1/********************************************************** 2 * Copyright 2018-2022 VMware, Inc. All rights reserved. 3 * 4 * Permission is hereby granted, free of charge, to any person 5 * obtaining a copy of this software and associated documentation 6 * files (the "Software"), to deal in the Software without 7 * restriction, including without limitation the rights to use, copy, 8 * modify, merge, publish, distribute, sublicense, and/or sell copies 9 * of the Software, and to permit persons to whom the Software is 10 * furnished to do so, subject to the following conditions: 11 * 12 * The above copyright notice and this permission notice shall be 13 * included in all copies or substantial portions of the Software. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 19 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 20 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 * SOFTWARE. 23 * 24 **********************************************************/ 25 26#include "util/u_inlines.h" 27#include "util/u_memory.h" 28#include "util/u_simple_shaders.h" 29 30#include "svga_context.h" 31#include "svga_cmd.h" 32#include "svga_tgsi.h" 33#include "svga_shader.h" 34 35 36static void 37make_tcs_key(struct svga_context *svga, struct svga_compile_key *key) 38{ 39 struct svga_tcs_shader *tcs = svga->curr.tcs; 40 41 memset(key, 0, sizeof *key); 42 43 /* 44 * SVGA_NEW_TEXTURE_BINDING | SVGA_NEW_SAMPLER 45 */ 46 svga_init_shader_key_common(svga, PIPE_SHADER_TESS_CTRL, &tcs->base, key); 47 48 /* SVGA_NEW_TCS_PARAM */ 49 key->tcs.vertices_per_patch = svga->curr.vertices_per_patch; 50 51 /* The tessellator parameters come from the layout section in the 52 * tessellation evaluation shader. Get these parameters from the 53 * current tessellation evaluation shader variant. 54 * Note: this requires the tessellation evaluation shader to be 55 * compiled first. 56 */ 57 struct svga_tes_variant *tes = svga_tes_variant(svga->state.hw_draw.tes); 58 key->tcs.prim_mode = tes->prim_mode; 59 key->tcs.spacing = tes->spacing; 60 key->tcs.vertices_order_cw = tes->vertices_order_cw; 61 key->tcs.point_mode = tes->point_mode; 62 63 /* The number of control point output from tcs is determined by the 64 * number of control point input expected in tes. If tes does not expect 65 * any control point input, then vertices_per_patch in the tes key will 66 * be 0, otherwise it will contain the number of vertices out as specified 67 * in the tcs property. 68 */ 69 key->tcs.vertices_out = tes->base.key.tes.vertices_per_patch; 70 71 if (svga->tcs.passthrough) 72 key->tcs.passthrough = 1; 73 74 key->clip_plane_enable = svga->curr.rast->templ.clip_plane_enable; 75 76 /* tcs is always followed by tes */ 77 key->last_vertex_stage = 0; 78} 79 80 81static enum pipe_error 82emit_hw_tcs(struct svga_context *svga, uint64_t dirty) 83{ 84 struct svga_shader_variant *variant; 85 struct svga_tcs_shader *tcs = svga->curr.tcs; 86 enum pipe_error ret = PIPE_OK; 87 struct svga_compile_key key; 88 89 assert(svga_have_sm5(svga)); 90 91 SVGA_STATS_TIME_PUSH(svga_sws(svga), SVGA_STATS_TIME_EMITTCS); 92 93 if (!tcs) { 94 /* If there is no active tcs, then there should not be 95 * active tes either 96 */ 97 assert(!svga->curr.tes); 98 if (svga->state.hw_draw.tcs != NULL) { 99 100 /** The previous tessellation control shader is made inactive. 101 * Needs to unbind the tessellation control shader. 102 */ 103 ret = svga_set_shader(svga, SVGA3D_SHADERTYPE_HS, NULL); 104 if (ret != PIPE_OK) 105 goto done; 106 svga->state.hw_draw.tcs = NULL; 107 } 108 goto done; 109 } 110 111 make_tcs_key(svga, &key); 112 113 /* See if we already have a TCS variant that matches the key */ 114 variant = svga_search_shader_key(&tcs->base, &key); 115 116 if (!variant) { 117 ret = svga_compile_shader(svga, &tcs->base, &key, &variant); 118 if (ret != PIPE_OK) 119 goto done; 120 } 121 122 if (variant != svga->state.hw_draw.tcs) { 123 /* Bind the new variant */ 124 ret = svga_set_shader(svga, SVGA3D_SHADERTYPE_HS, variant); 125 if (ret != PIPE_OK) 126 goto done; 127 128 svga->rebind.flags.tcs = FALSE; 129 svga->dirty |= SVGA_NEW_TCS_VARIANT; 130 svga->state.hw_draw.tcs = variant; 131 } 132 133done: 134 SVGA_STATS_TIME_POP(svga_sws(svga)); 135 return ret; 136} 137 138 139struct svga_tracked_state svga_hw_tcs = 140{ 141 "tessellation control shader (hwtnl)", 142 (SVGA_NEW_VS | 143 SVGA_NEW_TCS | 144 SVGA_NEW_TES | 145 SVGA_NEW_TEXTURE_BINDING | 146 SVGA_NEW_SAMPLER | 147 SVGA_NEW_RAST | 148 SVGA_NEW_TCS_RAW_BUFFER), 149 emit_hw_tcs 150}; 151 152 153static void 154make_tes_key(struct svga_context *svga, struct svga_compile_key *key) 155{ 156 struct svga_tes_shader *tes = svga->curr.tes; 157 158 memset(key, 0, sizeof *key); 159 160 /* 161 * SVGA_NEW_TEXTURE_BINDING | SVGA_NEW_SAMPLER 162 */ 163 svga_init_shader_key_common(svga, PIPE_SHADER_TESS_EVAL, &tes->base, key); 164 165 assert(svga->curr.tcs); 166 167 key->tes.vertices_per_patch = tes->base.info.tes.reads_control_point ? 168 svga->curr.tcs->base.info.tcs.vertices_out : 0; 169 170 key->tes.need_prescale = svga->state.hw_clear.prescale[0].enabled && 171 (svga->curr.gs == NULL); 172 173 /* tcs emits tessellation factors as extra outputs. 174 * Since tes depends on them, save the tessFactor output index 175 * from tcs in the tes compile key, so that if a different 176 * tcs is bound and if the tessFactor index is different, 177 * a different tes variant will be generated. 178 */ 179 key->tes.tessfactor_index = svga->curr.tcs->base.info.num_outputs; 180 181 key->clip_plane_enable = svga->curr.rast->templ.clip_plane_enable; 182 183 /* This is the last vertex stage if there is no geometry shader. */ 184 key->last_vertex_stage = !svga->curr.gs; 185 186 key->tes.need_tessinner = svga->curr.tcs->base.info.tcs.writes_tess_factor; 187 key->tes.need_tessouter = svga->curr.tcs->base.info.tcs.writes_tess_factor; 188} 189 190 191static void 192get_passthrough_tcs(struct svga_context *svga) 193{ 194 if (svga->tcs.passthrough_tcs && 195 svga->tcs.vs == svga->curr.vs && 196 svga->tcs.tes == svga->curr.tes && 197 svga->tcs.vertices_per_patch == svga->curr.vertices_per_patch) { 198 svga->pipe.bind_tcs_state(&svga->pipe, 199 svga->tcs.passthrough_tcs); 200 } 201 else { 202 struct svga_tcs_shader *new_tcs; 203 204 /* delete older passthrough shader*/ 205 if (svga->tcs.passthrough_tcs) { 206 svga->pipe.delete_tcs_state(&svga->pipe, 207 svga->tcs.passthrough_tcs); 208 } 209 210 new_tcs = (struct svga_tcs_shader *) 211 util_make_tess_ctrl_passthrough_shader(&svga->pipe, 212 svga->curr.vs->base.tgsi_info.num_outputs, 213 svga->curr.tes->base.tgsi_info.num_inputs, 214 svga->curr.vs->base.tgsi_info.output_semantic_name, 215 svga->curr.vs->base.tgsi_info.output_semantic_index, 216 svga->curr.tes->base.tgsi_info.input_semantic_name, 217 svga->curr.tes->base.tgsi_info.input_semantic_index, 218 svga->curr.vertices_per_patch); 219 svga->pipe.bind_tcs_state(&svga->pipe, new_tcs); 220 svga->tcs.passthrough_tcs = new_tcs; 221 svga->tcs.vs = svga->curr.vs; 222 svga->tcs.tes = svga->curr.tes; 223 svga->tcs.vertices_per_patch = svga->curr.vertices_per_patch; 224 } 225 226 struct pipe_constant_buffer cb; 227 228 cb.buffer = NULL; 229 cb.user_buffer = (void *) svga->curr.default_tesslevels; 230 cb.buffer_offset = 0; 231 cb.buffer_size = 2 * 4 * sizeof(float); 232 svga->pipe.set_constant_buffer(&svga->pipe, PIPE_SHADER_TESS_CTRL, 0, false, &cb); 233} 234 235 236static enum pipe_error 237emit_hw_tes(struct svga_context *svga, uint64_t dirty) 238{ 239 struct svga_shader_variant *variant; 240 struct svga_tes_shader *tes = svga->curr.tes; 241 enum pipe_error ret = PIPE_OK; 242 struct svga_compile_key key; 243 244 assert(svga_have_sm5(svga)); 245 246 SVGA_STATS_TIME_PUSH(svga_sws(svga), SVGA_STATS_TIME_EMITTES); 247 248 if (!tes) { 249 /* The GL spec implies that TES is optional when there's a TCS, 250 * but that's apparently a spec error. Assert if we have a TCS 251 * but no TES. 252 */ 253 assert(!svga->curr.tcs); 254 if (svga->state.hw_draw.tes != NULL) { 255 256 /** The previous tessellation evaluation shader is made inactive. 257 * Needs to unbind the tessellation evaluation shader. 258 */ 259 ret = svga_set_shader(svga, SVGA3D_SHADERTYPE_DS, NULL); 260 if (ret != PIPE_OK) 261 goto done; 262 svga->state.hw_draw.tes = NULL; 263 } 264 goto done; 265 } 266 267 if (!svga->curr.tcs) { 268 /* TES state is processed before the TCS 269 * shader and that's why we're checking for and creating the 270 * passthough TCS in the emit_hw_tes() function. 271 */ 272 get_passthrough_tcs(svga); 273 svga->tcs.passthrough = TRUE; 274 } 275 else { 276 svga->tcs.passthrough = FALSE; 277 } 278 279 make_tes_key(svga, &key); 280 281 /* See if we already have a TES variant that matches the key */ 282 variant = svga_search_shader_key(&tes->base, &key); 283 284 if (!variant) { 285 ret = svga_compile_shader(svga, &tes->base, &key, &variant); 286 if (ret != PIPE_OK) 287 goto done; 288 } 289 290 if (variant != svga->state.hw_draw.tes) { 291 /* Bind the new variant */ 292 ret = svga_set_shader(svga, SVGA3D_SHADERTYPE_DS, variant); 293 if (ret != PIPE_OK) 294 goto done; 295 296 svga->rebind.flags.tes = FALSE; 297 svga->dirty |= SVGA_NEW_TES_VARIANT; 298 svga->state.hw_draw.tes = variant; 299 } 300 301done: 302 SVGA_STATS_TIME_POP(svga_sws(svga)); 303 return ret; 304} 305 306 307struct svga_tracked_state svga_hw_tes = 308{ 309 "tessellation evaluation shader (hwtnl)", 310 /* TBD SVGA_NEW_VS/SVGA_NEW_FS/SVGA_NEW_GS are required or not*/ 311 (SVGA_NEW_VS | 312 SVGA_NEW_FS | 313 SVGA_NEW_GS | 314 SVGA_NEW_TCS | 315 SVGA_NEW_TES | 316 SVGA_NEW_TEXTURE_BINDING | 317 SVGA_NEW_SAMPLER | 318 SVGA_NEW_RAST | 319 SVGA_NEW_TES_RAW_BUFFER), 320 emit_hw_tes 321}; 322