1 /**************************************************************************
2 *
3 * Copyright 2020 Red Hat.
4 * All Rights Reserved.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included
14 * in all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 * SOFTWARE.
23 *
24 **************************************************************************/
25 #include "draw_tess.h"
26 #if DRAW_LLVM_AVAILABLE
27 #include "draw_llvm.h"
28 #endif
29
30 #include "tessellator/p_tessellator.h"
31 #include "nir/nir_to_tgsi_info.h"
32 #include "util/u_prim.h"
33 #include "util/u_math.h"
34 #include "util/u_memory.h"
35 #include "util/ralloc.h"
36 #if DRAW_LLVM_AVAILABLE
37 static inline int
draw_tes_get_input_index(int semantic,int index,const struct tgsi_shader_info * input_info)38 draw_tes_get_input_index(int semantic, int index,
39 const struct tgsi_shader_info *input_info)
40 {
41 int i;
42 const uint8_t *input_semantic_names = input_info->output_semantic_name;
43 const uint8_t *input_semantic_indices = input_info->output_semantic_index;
44 for (i = 0; i < PIPE_MAX_SHADER_OUTPUTS; i++) {
45 if (input_semantic_names[i] == semantic &&
46 input_semantic_indices[i] == index)
47 return i;
48 }
49 return -1;
50 }
51
52 #define DEBUG_INPUTS 0
53 static void
llvm_fetch_tcs_input(struct draw_tess_ctrl_shader * shader,const struct draw_prim_info * input_prim_info,unsigned prim_id,unsigned num_vertices)54 llvm_fetch_tcs_input(struct draw_tess_ctrl_shader *shader,
55 const struct draw_prim_info *input_prim_info,
56 unsigned prim_id,
57 unsigned num_vertices)
58 {
59 const float (*input_ptr)[4];
60 float (*input_data)[32][NUM_TCS_INPUTS][TGSI_NUM_CHANNELS] = &shader->tcs_input->data;
61 unsigned slot, i;
62 int vs_slot;
63 unsigned input_vertex_stride = shader->input_vertex_stride;
64
65 input_ptr = shader->input;
66 for (i = 0; i < num_vertices; i++) {
67 const float (*input)[4];
68 int vertex_idx = prim_id * num_vertices + i;
69 if (input_prim_info->linear == false)
70 vertex_idx = input_prim_info->elts[vertex_idx];
71 #if DEBUG_INPUTS
72 debug_printf("%d) tcs vertex index = %d (prim idx = %d)\n",
73 i, prim_id, 0);
74 #endif
75 input = (const float (*)[4])((const char *)input_ptr + (vertex_idx * input_vertex_stride));
76 for (slot = 0, vs_slot = 0; slot < shader->info.num_inputs; ++slot) {
77 vs_slot = draw_tes_get_input_index(
78 shader->info.input_semantic_name[slot],
79 shader->info.input_semantic_index[slot],
80 shader->input_info);
81 if (vs_slot < 0) {
82 debug_printf("VS/TCS signature mismatch!\n");
83 (*input_data)[i][slot][0] = 0;
84 (*input_data)[i][slot][1] = 0;
85 (*input_data)[i][slot][2] = 0;
86 (*input_data)[i][slot][3] = 0;
87 } else {
88 (*input_data)[i][slot][0] = input[vs_slot][0];
89 (*input_data)[i][slot][1] = input[vs_slot][1];
90 (*input_data)[i][slot][2] = input[vs_slot][2];
91 (*input_data)[i][slot][3] = input[vs_slot][3];
92 #if DEBUG_INPUTS
93 debug_printf("\t\t%p = %f %f %f %f\n", &(*input_data)[i][slot][0],
94 (*input_data)[i][slot][0],
95 (*input_data)[i][slot][1],
96 (*input_data)[i][slot][2],
97 (*input_data)[i][slot][3]);
98 #endif
99 ++vs_slot;
100 }
101 }
102 }
103 }
104
105 #define DEBUG_OUTPUTS 0
106 static void
llvm_store_tcs_output(struct draw_tess_ctrl_shader * shader,unsigned prim_id,struct draw_vertex_info * output_verts,unsigned vert_start)107 llvm_store_tcs_output(struct draw_tess_ctrl_shader *shader,
108 unsigned prim_id,
109 struct draw_vertex_info *output_verts,
110 unsigned vert_start)
111 {
112 float (*output_ptr)[4];
113 float (*output_data)[32][PIPE_MAX_SHADER_INPUTS][TGSI_NUM_CHANNELS] = &shader->tcs_output->data;
114 unsigned slot, i;
115 unsigned num_vertices = shader->vertices_out;
116
117 char *output = (char *)output_verts->verts->data;
118 output += vert_start * output_verts->stride;
119
120 for (i = 0; i < num_vertices; i++) {
121
122 #if DEBUG_OUTPUTS
123 debug_printf("%d) tcs store vertex index = %d (prim idx = %d)\n",
124 i, prim_id, 0);
125 #endif
126 output_ptr = (float(*)[4])(output + (i * output_verts->stride));
127
128 for (slot = 0; slot < shader->info.num_outputs; ++slot) {
129 output_ptr[slot][0] = (*output_data)[i][slot][0];
130 output_ptr[slot][1] = (*output_data)[i][slot][1];
131 output_ptr[slot][2] = (*output_data)[i][slot][2];
132 output_ptr[slot][3] = (*output_data)[i][slot][3];
133 #if DEBUG_OUTPUTS
134 debug_printf("\t\t%p = %f %f %f %f\n",
135 &output_ptr[slot][0],
136 output_ptr[slot][0],
137 output_ptr[slot][1],
138 output_ptr[slot][2],
139 output_ptr[slot][3]);
140 #endif
141 }
142 }
143 }
144
145 static void
llvm_tcs_run(struct draw_tess_ctrl_shader * shader,uint32_t prim_id)146 llvm_tcs_run(struct draw_tess_ctrl_shader *shader, uint32_t prim_id)
147 {
148 shader->current_variant->jit_func(shader->jit_resources,
149 shader->tcs_input->data, shader->tcs_output->data, prim_id,
150 shader->draw->pt.vertices_per_patch, shader->draw->pt.user.viewid);
151 }
152 #endif
153
154 /**
155 * Execute tess ctrl shader.
156 */
draw_tess_ctrl_shader_run(struct draw_tess_ctrl_shader * shader,const struct draw_vertex_info * input_verts,const struct draw_prim_info * input_prim,const struct tgsi_shader_info * input_info,struct draw_vertex_info * output_verts,struct draw_prim_info * output_prims)157 int draw_tess_ctrl_shader_run(struct draw_tess_ctrl_shader *shader,
158 const struct draw_vertex_info *input_verts,
159 const struct draw_prim_info *input_prim,
160 const struct tgsi_shader_info *input_info,
161 struct draw_vertex_info *output_verts,
162 struct draw_prim_info *output_prims )
163 {
164 const float (*input)[4] = (const float (*)[4])input_verts->verts->data;
165 unsigned num_outputs = draw_total_tcs_outputs(shader->draw);
166 unsigned input_stride = input_verts->vertex_size;
167 unsigned vertex_size = sizeof(struct vertex_header) + num_outputs * 4 * sizeof(float);
168 unsigned num_patches = input_prim->count / shader->draw->pt.vertices_per_patch;
169
170 output_verts->vertex_size = vertex_size;
171 output_verts->stride = output_verts->vertex_size;
172 output_verts->verts = NULL;
173 output_verts->count = 0;
174 shader->input = input;
175 shader->input_vertex_stride = input_stride;
176 shader->input_info = input_info;
177
178 output_prims->linear = true;
179 output_prims->start = 0;
180 output_prims->elts = NULL;
181 output_prims->count = 0;
182 output_prims->prim = MESA_PRIM_PATCHES;
183 output_prims->flags = 0;
184 output_prims->primitive_lengths = NULL;
185 output_prims->primitive_count = 0;
186
187 if (shader->draw->collect_statistics) {
188 shader->draw->statistics.hs_invocations += num_patches;
189 }
190 #if DRAW_LLVM_AVAILABLE
191 unsigned first_patch = input_prim->start / shader->draw->pt.vertices_per_patch;
192 for (unsigned i = 0; i < num_patches; i++) {
193 uint32_t vert_start = output_verts->count;
194
195 output_verts->count += shader->vertices_out;
196
197 llvm_fetch_tcs_input(shader, input_prim, i, shader->draw->pt.vertices_per_patch);
198
199 llvm_tcs_run(shader, first_patch + i);
200
201 uint32_t old_verts = util_align_npot(vert_start, 16);
202 uint32_t new_verts = util_align_npot(output_verts->count, 16);
203 uint32_t old_size = output_verts->vertex_size * old_verts;
204 uint32_t new_size = output_verts->vertex_size * new_verts;
205 output_verts->verts = REALLOC(output_verts->verts, old_size, new_size);
206
207 llvm_store_tcs_output(shader, i, output_verts, vert_start);
208 }
209 #endif
210
211 output_prims->primitive_count = num_patches;
212 return 0;
213 }
214
215 #if DRAW_LLVM_AVAILABLE
216 #define DEBUG_INPUTS 0
217 static void
llvm_fetch_tes_input(struct draw_tess_eval_shader * shader,const struct draw_prim_info * input_prim_info,unsigned prim_id,unsigned num_vertices)218 llvm_fetch_tes_input(struct draw_tess_eval_shader *shader,
219 const struct draw_prim_info *input_prim_info,
220 unsigned prim_id,
221 unsigned num_vertices)
222 {
223 const float (*input_ptr)[4];
224 float (*input_data)[32][PIPE_MAX_SHADER_INPUTS][TGSI_NUM_CHANNELS] = &shader->tes_input->data;
225 unsigned slot, i;
226 int vs_slot;
227 unsigned input_vertex_stride = shader->input_vertex_stride;
228
229 input_ptr = shader->input;
230 for (i = 0; i < num_vertices; i++) {
231 const float (*input)[4];
232 int vertex_idx = prim_id * num_vertices + i;
233
234 if (input_prim_info->linear == false)
235 vertex_idx = input_prim_info->elts[vertex_idx];
236 #if DEBUG_INPUTS
237 debug_printf("%d) tes vertex index = %d (prim idx = %d)\n",
238 i, prim_id, 0);
239 #endif
240 input = (const float (*)[4])((const char *)input_ptr + (vertex_idx * input_vertex_stride));
241 for (slot = 0, vs_slot = 0; slot < shader->info.num_inputs; ++slot) {
242 vs_slot = draw_tes_get_input_index(
243 shader->info.input_semantic_name[slot],
244 shader->info.input_semantic_index[slot],
245 shader->input_info);
246 if (vs_slot < 0) {
247 debug_printf("TCS/TES signature mismatch!\n");
248 (*input_data)[i][slot][0] = 0;
249 (*input_data)[i][slot][1] = 0;
250 (*input_data)[i][slot][2] = 0;
251 (*input_data)[i][slot][3] = 0;
252 } else {
253 (*input_data)[i][slot][0] = input[vs_slot][0];
254 (*input_data)[i][slot][1] = input[vs_slot][1];
255 (*input_data)[i][slot][2] = input[vs_slot][2];
256 (*input_data)[i][slot][3] = input[vs_slot][3];
257 #if DEBUG_INPUTS
258 debug_printf("\t\t%p = %f %f %f %f\n",
259 &input[vs_slot][0],
260 (*input_data)[i][slot][0],
261 (*input_data)[i][slot][1],
262 (*input_data)[i][slot][2],
263 (*input_data)[i][slot][3]);
264 #endif
265 ++vs_slot;
266 }
267 }
268 }
269 }
270
271 static void
llvm_fetch_tess_factors(struct draw_tess_eval_shader * shader,unsigned patch_id,unsigned num_vertices,struct pipe_tessellation_factors * factors)272 llvm_fetch_tess_factors(struct draw_tess_eval_shader *shader,
273 unsigned patch_id,
274 unsigned num_vertices,
275 struct pipe_tessellation_factors *factors)
276 {
277 int outer_slot = draw_tes_get_input_index(
278 TGSI_SEMANTIC_TESSOUTER, 0, shader->input_info);
279 int inner_slot = draw_tes_get_input_index(
280 TGSI_SEMANTIC_TESSINNER, 0, shader->input_info);
281 const float (*input_ptr)[4];
282 const float (*input)[4];
283 input_ptr = shader->input;
284 input = (const float (*)[4])((const char *)input_ptr + ((patch_id * num_vertices) * shader->input_vertex_stride));
285
286 if (outer_slot != -1) {
287 for (unsigned i = 0; i < 4; i++)
288 factors->outer_tf[i] = input[outer_slot][i];
289 } else {
290 for (unsigned i = 0; i < 4; i++)
291 factors->outer_tf[i] = shader->draw->default_outer_tess_level[i];
292 }
293 if (inner_slot != -1) {
294 for (unsigned i = 0; i < 2; i++)
295 factors->inner_tf[i] = input[inner_slot][i];
296 } else {
297 for (unsigned i = 0; i < 2; i++)
298 factors->inner_tf[i] = shader->draw->default_inner_tess_level[i];
299 }
300 }
301
302 static void
llvm_tes_run(struct draw_tess_eval_shader * shader,uint32_t prim_id,uint32_t patch_vertices_in,struct pipe_tessellator_data * tess_data,struct pipe_tessellation_factors * tess_factors,struct vertex_header * output)303 llvm_tes_run(struct draw_tess_eval_shader *shader,
304 uint32_t prim_id,
305 uint32_t patch_vertices_in,
306 struct pipe_tessellator_data *tess_data,
307 struct pipe_tessellation_factors *tess_factors,
308 struct vertex_header *output)
309 {
310 shader->current_variant->jit_func(shader->jit_resources,
311 shader->tes_input->data, output, prim_id,
312 tess_data->num_domain_points, tess_data->domain_points_u, tess_data->domain_points_v,
313 tess_factors->outer_tf, tess_factors->inner_tf, patch_vertices_in,
314 shader->draw->pt.user.viewid);
315 }
316 #endif
317
318 /**
319 * Execute tess eval shader.
320 */
draw_tess_eval_shader_run(struct draw_tess_eval_shader * shader,unsigned num_input_vertices_per_patch,const struct draw_vertex_info * input_verts,const struct draw_prim_info * input_prim,const struct tgsi_shader_info * input_info,struct draw_vertex_info * output_verts,struct draw_prim_info * output_prims,uint16_t ** elts_out)321 int draw_tess_eval_shader_run(struct draw_tess_eval_shader *shader,
322 unsigned num_input_vertices_per_patch,
323 const struct draw_vertex_info *input_verts,
324 const struct draw_prim_info *input_prim,
325 const struct tgsi_shader_info *input_info,
326 struct draw_vertex_info *output_verts,
327 struct draw_prim_info *output_prims,
328 uint16_t **elts_out)
329 {
330 const float (*input)[4] = (const float (*)[4])input_verts->verts->data;
331 unsigned num_outputs = draw_total_tes_outputs(shader->draw);
332 unsigned input_stride = input_verts->vertex_size;
333 unsigned vertex_size = sizeof(struct vertex_header) + num_outputs * 4 * sizeof(float);
334 uint16_t *elts = NULL;
335 output_verts->vertex_size = vertex_size;
336 output_verts->stride = output_verts->vertex_size;
337 output_verts->count = 0;
338 output_verts->verts = NULL;
339
340 output_prims->linear = false;
341 output_prims->start = 0;
342 output_prims->elts = NULL;
343 output_prims->count = 0;
344 output_prims->prim = get_tes_output_prim(shader);
345 output_prims->flags = 0;
346 output_prims->primitive_lengths = NULL;
347 output_prims->primitive_count = 0;
348
349 shader->input = input;
350 shader->input_vertex_stride = input_stride;
351 shader->input_info = input_info;
352
353 #if DRAW_LLVM_AVAILABLE
354 struct pipe_tessellation_factors factors;
355 struct pipe_tessellator_data data = { 0 };
356 struct pipe_tessellator *ptess = p_tess_init(shader->prim_mode,
357 shader->spacing,
358 !shader->vertex_order_cw,
359 shader->point_mode);
360 for (unsigned i = 0; i < input_prim->primitive_count; i++) {
361 uint32_t vert_start = output_verts->count;
362 uint32_t prim_start = output_prims->primitive_count;
363 uint32_t elt_start = output_prims->count;
364
365 llvm_fetch_tess_factors(shader, i, num_input_vertices_per_patch, &factors);
366
367 /* tessellate with the factors for this primitive */
368 p_tessellate(ptess, &factors, &data);
369
370 if (data.num_domain_points == 0)
371 continue;
372
373 uint32_t old_verts = vert_start;
374 uint32_t new_verts = vert_start + util_align_npot(data.num_domain_points, 4);
375 uint32_t old_size = output_verts->vertex_size * old_verts;
376 uint32_t new_size = output_verts->vertex_size * new_verts;
377 output_verts->verts = REALLOC(output_verts->verts, old_size, new_size);
378
379 output_verts->count += data.num_domain_points;
380
381 output_prims->count += data.num_indices;
382 elts = REALLOC(elts, elt_start * sizeof(uint16_t),
383 output_prims->count * sizeof(uint16_t));
384
385 for (unsigned i = 0; i < data.num_indices; i++)
386 elts[elt_start + i] = vert_start + data.indices[i];
387
388 llvm_fetch_tes_input(shader, input_prim, i, num_input_vertices_per_patch);
389 /* run once per primitive? */
390 char *output = (char *)output_verts->verts;
391 output += vert_start * vertex_size;
392 llvm_tes_run(shader, i, num_input_vertices_per_patch, &data, &factors, (struct vertex_header *)output);
393
394 if (shader->draw->collect_statistics) {
395 shader->draw->statistics.ds_invocations += data.num_domain_points;
396 }
397
398 uint32_t prim_len = u_prim_vertex_count(output_prims->prim)->min;
399 output_prims->primitive_count += data.num_indices / prim_len;
400 output_prims->primitive_lengths = REALLOC(output_prims->primitive_lengths, prim_start * sizeof(uint32_t),
401 output_prims->primitive_count * sizeof(uint32_t));
402 for (unsigned i = prim_start; i < output_prims->primitive_count; i++) {
403 output_prims->primitive_lengths[i] = prim_len;
404 }
405 }
406 p_tess_destroy(ptess);
407 #endif
408
409 *elts_out = elts;
410 output_prims->elts = elts;
411 return 0;
412 }
413
414 struct draw_tess_ctrl_shader *
draw_create_tess_ctrl_shader(struct draw_context * draw,const struct pipe_shader_state * state)415 draw_create_tess_ctrl_shader(struct draw_context *draw,
416 const struct pipe_shader_state *state)
417 {
418 #if DRAW_LLVM_AVAILABLE
419 bool use_llvm = draw->llvm != NULL;
420 struct llvm_tess_ctrl_shader *llvm_tcs = NULL;
421 #endif
422 struct draw_tess_ctrl_shader *tcs;
423
424 #if DRAW_LLVM_AVAILABLE
425 if (use_llvm) {
426 llvm_tcs = CALLOC_STRUCT(llvm_tess_ctrl_shader);
427
428 if (!llvm_tcs)
429 return NULL;
430
431 tcs = &llvm_tcs->base;
432
433 list_inithead(&llvm_tcs->variants.list);
434 } else
435 #endif
436 {
437 tcs = CALLOC_STRUCT(draw_tess_ctrl_shader);
438 }
439
440 if (!tcs)
441 return NULL;
442
443 tcs->draw = draw;
444 tcs->state = *state;
445
446 nir_tgsi_scan_shader(state->ir.nir, &tcs->info, true);
447
448 tcs->vector_length = 4;
449 tcs->vertices_out = tcs->info.properties[TGSI_PROPERTY_TCS_VERTICES_OUT];
450 #if DRAW_LLVM_AVAILABLE
451 if (use_llvm) {
452
453 tcs->tcs_input = align_malloc(sizeof(struct draw_tcs_inputs), 16);
454 memset(tcs->tcs_input, 0, sizeof(struct draw_tcs_inputs));
455
456 tcs->tcs_output = align_malloc(sizeof(struct draw_tcs_outputs), 16);
457 memset(tcs->tcs_output, 0, sizeof(struct draw_tcs_outputs));
458
459 tcs->jit_resources = &draw->llvm->jit_resources[PIPE_SHADER_TESS_CTRL];
460 llvm_tcs->variant_key_size =
461 draw_tcs_llvm_variant_key_size(
462 tcs->info.file_max[TGSI_FILE_SAMPLER]+1,
463 tcs->info.file_max[TGSI_FILE_SAMPLER_VIEW]+1,
464 tcs->info.file_max[TGSI_FILE_IMAGE]+1);
465 }
466 #endif
467 return tcs;
468 }
469
draw_bind_tess_ctrl_shader(struct draw_context * draw,struct draw_tess_ctrl_shader * dtcs)470 void draw_bind_tess_ctrl_shader(struct draw_context *draw,
471 struct draw_tess_ctrl_shader *dtcs)
472 {
473 draw_do_flush(draw, DRAW_FLUSH_STATE_CHANGE);
474 if (dtcs) {
475 draw->tcs.tess_ctrl_shader = dtcs;
476 } else {
477 draw->tcs.tess_ctrl_shader = NULL;
478 }
479 }
480
draw_delete_tess_ctrl_shader(struct draw_context * draw,struct draw_tess_ctrl_shader * dtcs)481 void draw_delete_tess_ctrl_shader(struct draw_context *draw,
482 struct draw_tess_ctrl_shader *dtcs)
483 {
484 if (!dtcs)
485 return;
486
487 #if DRAW_LLVM_AVAILABLE
488 if (draw->llvm) {
489 struct llvm_tess_ctrl_shader *shader = llvm_tess_ctrl_shader(dtcs);
490
491 struct draw_tcs_llvm_variant_list_item *li, *next;
492
493 LIST_FOR_EACH_ENTRY_SAFE(li, next, &shader->variants.list, list) {
494 draw_tcs_llvm_destroy_variant(li->base);
495 }
496
497 assert(shader->variants_cached == 0);
498 align_free(dtcs->tcs_input);
499 align_free(dtcs->tcs_output);
500 }
501 #endif
502
503 if (dtcs->state.type == PIPE_SHADER_IR_NIR && dtcs->state.ir.nir)
504 ralloc_free(dtcs->state.ir.nir);
505 FREE(dtcs);
506 }
507
508 #if DRAW_LLVM_AVAILABLE
draw_tcs_set_current_variant(struct draw_tess_ctrl_shader * shader,struct draw_tcs_llvm_variant * variant)509 void draw_tcs_set_current_variant(struct draw_tess_ctrl_shader *shader,
510 struct draw_tcs_llvm_variant *variant)
511 {
512 shader->current_variant = variant;
513 }
514 #endif
515
516 struct draw_tess_eval_shader *
draw_create_tess_eval_shader(struct draw_context * draw,const struct pipe_shader_state * state)517 draw_create_tess_eval_shader(struct draw_context *draw,
518 const struct pipe_shader_state *state)
519 {
520 #if DRAW_LLVM_AVAILABLE
521 bool use_llvm = draw->llvm != NULL;
522 struct llvm_tess_eval_shader *llvm_tes = NULL;
523 #endif
524 struct draw_tess_eval_shader *tes;
525
526 #if DRAW_LLVM_AVAILABLE
527 if (use_llvm) {
528 llvm_tes = CALLOC_STRUCT(llvm_tess_eval_shader);
529
530 if (!llvm_tes)
531 return NULL;
532
533 tes = &llvm_tes->base;
534 list_inithead(&llvm_tes->variants.list);
535 } else
536 #endif
537 {
538 tes = CALLOC_STRUCT(draw_tess_eval_shader);
539 }
540
541 if (!tes)
542 return NULL;
543
544 tes->draw = draw;
545 tes->state = *state;
546
547 nir_tgsi_scan_shader(state->ir.nir, &tes->info, true);
548
549 tes->prim_mode = tes->info.properties[TGSI_PROPERTY_TES_PRIM_MODE];
550 tes->spacing = tes->info.properties[TGSI_PROPERTY_TES_SPACING];
551 tes->vertex_order_cw = tes->info.properties[TGSI_PROPERTY_TES_VERTEX_ORDER_CW];
552 tes->point_mode = tes->info.properties[TGSI_PROPERTY_TES_POINT_MODE];
553
554 tes->vector_length = 4;
555
556 tes->position_output = -1;
557 bool found_clipvertex = false;
558 for (unsigned i = 0; i < tes->info.num_outputs; i++) {
559 if (tes->info.output_semantic_name[i] == TGSI_SEMANTIC_POSITION &&
560 tes->info.output_semantic_index[i] == 0)
561 tes->position_output = i;
562 if (tes->info.output_semantic_name[i] == TGSI_SEMANTIC_VIEWPORT_INDEX)
563 tes->viewport_index_output = i;
564 if (tes->info.output_semantic_name[i] == TGSI_SEMANTIC_CLIPVERTEX &&
565 tes->info.output_semantic_index[i] == 0) {
566 found_clipvertex = true;
567 tes->clipvertex_output = i;
568 }
569 if (tes->info.output_semantic_name[i] == TGSI_SEMANTIC_CLIPDIST) {
570 assert(tes->info.output_semantic_index[i] <
571 PIPE_MAX_CLIP_OR_CULL_DISTANCE_ELEMENT_COUNT);
572 tes->ccdistance_output[tes->info.output_semantic_index[i]] = i;
573 }
574 }
575 if (!found_clipvertex)
576 tes->clipvertex_output = tes->position_output;
577
578 #if DRAW_LLVM_AVAILABLE
579 if (use_llvm) {
580
581 tes->tes_input = align_malloc(sizeof(struct draw_tes_inputs), 16);
582 memset(tes->tes_input, 0, sizeof(struct draw_tes_inputs));
583
584 tes->jit_resources = &draw->llvm->jit_resources[PIPE_SHADER_TESS_EVAL];
585 llvm_tes->variant_key_size =
586 draw_tes_llvm_variant_key_size(
587 tes->info.file_max[TGSI_FILE_SAMPLER]+1,
588 tes->info.file_max[TGSI_FILE_SAMPLER_VIEW]+1,
589 tes->info.file_max[TGSI_FILE_IMAGE]+1);
590 }
591 #endif
592 return tes;
593 }
594
draw_bind_tess_eval_shader(struct draw_context * draw,struct draw_tess_eval_shader * dtes)595 void draw_bind_tess_eval_shader(struct draw_context *draw,
596 struct draw_tess_eval_shader *dtes)
597 {
598 draw_do_flush(draw, DRAW_FLUSH_STATE_CHANGE);
599 if (dtes) {
600 draw->tes.tess_eval_shader = dtes;
601 draw->tes.num_tes_outputs = dtes->info.num_outputs;
602 draw->tes.position_output = dtes->position_output;
603 draw->tes.clipvertex_output = dtes->clipvertex_output;
604 } else {
605 draw->tes.tess_eval_shader = NULL;
606 }
607 }
608
draw_delete_tess_eval_shader(struct draw_context * draw,struct draw_tess_eval_shader * dtes)609 void draw_delete_tess_eval_shader(struct draw_context *draw,
610 struct draw_tess_eval_shader *dtes)
611 {
612 if (!dtes)
613 return;
614
615 #if DRAW_LLVM_AVAILABLE
616 if (draw->llvm) {
617 struct llvm_tess_eval_shader *shader = llvm_tess_eval_shader(dtes);
618 struct draw_tes_llvm_variant_list_item *li, *next;
619
620 LIST_FOR_EACH_ENTRY_SAFE(li, next, &shader->variants.list, list) {
621 draw_tes_llvm_destroy_variant(li->base);
622 }
623
624 assert(shader->variants_cached == 0);
625 align_free(dtes->tes_input);
626 }
627 #endif
628 if (dtes->state.type == PIPE_SHADER_IR_NIR && dtes->state.ir.nir)
629 ralloc_free(dtes->state.ir.nir);
630 FREE(dtes);
631 }
632
633 #if DRAW_LLVM_AVAILABLE
draw_tes_set_current_variant(struct draw_tess_eval_shader * shader,struct draw_tes_llvm_variant * variant)634 void draw_tes_set_current_variant(struct draw_tess_eval_shader *shader,
635 struct draw_tes_llvm_variant *variant)
636 {
637 shader->current_variant = variant;
638 }
639 #endif
640
get_tes_output_prim(struct draw_tess_eval_shader * shader)641 enum mesa_prim get_tes_output_prim(struct draw_tess_eval_shader *shader)
642 {
643 if (shader->point_mode)
644 return MESA_PRIM_POINTS;
645 else if (shader->prim_mode == MESA_PRIM_LINES)
646 return MESA_PRIM_LINES;
647 else
648 return MESA_PRIM_TRIANGLES;
649 }
650