• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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,uint32_t ** patch_lengths,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                               uint32_t **patch_lengths,
329                               uint16_t **elts_out)
330 {
331    const float (*input)[4] = (const float (*)[4])input_verts->verts->data;
332    unsigned num_outputs = draw_total_tes_outputs(shader->draw);
333    unsigned input_stride = input_verts->vertex_size;
334    unsigned vertex_size = sizeof(struct vertex_header) + num_outputs * 4 * sizeof(float);
335    uint16_t *elts = NULL;
336    output_verts->vertex_size = vertex_size;
337    output_verts->stride = output_verts->vertex_size;
338    output_verts->count = 0;
339    output_verts->verts = NULL;
340 
341    output_prims->linear = false;
342    output_prims->start = 0;
343    output_prims->elts = NULL;
344    output_prims->count = 0;
345    output_prims->prim = get_tes_output_prim(shader);
346    output_prims->flags = 0;
347    output_prims->primitive_lengths = NULL;
348    output_prims->primitive_count = 0;
349 
350    if (patch_lengths) {
351       *patch_lengths = MALLOC(input_prim->primitive_count * sizeof(uint32_t));
352    }
353 
354    shader->input = input;
355    shader->input_vertex_stride = input_stride;
356    shader->input_info = input_info;
357 
358 #if DRAW_LLVM_AVAILABLE
359    struct pipe_tessellation_factors factors;
360    struct pipe_tessellator_data data = { 0 };
361    struct pipe_tessellator *ptess = p_tess_init(shader->prim_mode,
362                                                 shader->spacing,
363                                                 !shader->vertex_order_cw,
364                                                 shader->point_mode);
365    for (unsigned i = 0; i < input_prim->primitive_count; i++) {
366       uint32_t vert_start = output_verts->count;
367       uint32_t prim_start = output_prims->primitive_count;
368       uint32_t elt_start = output_prims->count;
369 
370       llvm_fetch_tess_factors(shader, i, num_input_vertices_per_patch, &factors);
371 
372       /* tessellate with the factors for this primitive */
373       p_tessellate(ptess, &factors, &data);
374 
375       if (data.num_domain_points == 0)
376          continue;
377 
378       uint32_t old_verts = vert_start;
379       uint32_t new_verts = vert_start + util_align_npot(data.num_domain_points, 4);
380       uint32_t old_size = output_verts->vertex_size * old_verts;
381       uint32_t new_size = output_verts->vertex_size * new_verts;
382       output_verts->verts = REALLOC(output_verts->verts, old_size, new_size);
383 
384       output_verts->count += data.num_domain_points;
385 
386       output_prims->count += data.num_indices;
387       elts = REALLOC(elts, elt_start * sizeof(uint16_t),
388                      output_prims->count * sizeof(uint16_t));
389 
390       for (uint32_t i = 0; i < data.num_indices; i++)
391          elts[elt_start + i] = vert_start + data.indices[i];
392 
393       llvm_fetch_tes_input(shader, input_prim, i, num_input_vertices_per_patch);
394       /* run once per primitive? */
395       char *output = (char *)output_verts->verts;
396       output += vert_start * vertex_size;
397       llvm_tes_run(shader, i, num_input_vertices_per_patch, &data, &factors, (struct vertex_header *)output);
398 
399       if (shader->draw->collect_statistics) {
400          shader->draw->statistics.ds_invocations += data.num_domain_points;
401       }
402 
403       uint32_t prim_len = u_prim_vertex_count(output_prims->prim)->min;
404       uint32_t prims_per_patch = data.num_indices / prim_len;
405       output_prims->primitive_count += prims_per_patch;
406       if (patch_lengths) {
407          (*patch_lengths)[i] = prims_per_patch;
408       }
409 
410       output_prims->primitive_lengths = REALLOC(output_prims->primitive_lengths, prim_start * sizeof(uint32_t),
411                                                 output_prims->primitive_count * sizeof(uint32_t));
412       for (uint32_t i = prim_start; i < output_prims->primitive_count; i++) {
413          output_prims->primitive_lengths[i] = prim_len;
414       }
415    }
416    p_tess_destroy(ptess);
417 #endif
418 
419    *elts_out = elts;
420    output_prims->elts = elts;
421    return 0;
422 }
423 
424 struct draw_tess_ctrl_shader *
draw_create_tess_ctrl_shader(struct draw_context * draw,const struct pipe_shader_state * state)425 draw_create_tess_ctrl_shader(struct draw_context *draw,
426                              const struct pipe_shader_state *state)
427 {
428 #if DRAW_LLVM_AVAILABLE
429    bool use_llvm = draw->llvm != NULL;
430    struct llvm_tess_ctrl_shader *llvm_tcs = NULL;
431 #endif
432    struct draw_tess_ctrl_shader *tcs;
433 
434 #if DRAW_LLVM_AVAILABLE
435    if (use_llvm) {
436       llvm_tcs = CALLOC_STRUCT(llvm_tess_ctrl_shader);
437 
438       if (!llvm_tcs)
439          return NULL;
440 
441       tcs = &llvm_tcs->base;
442 
443       list_inithead(&llvm_tcs->variants.list);
444    } else
445 #endif
446    {
447       tcs = CALLOC_STRUCT(draw_tess_ctrl_shader);
448    }
449 
450    if (!tcs)
451       return NULL;
452 
453    tcs->draw = draw;
454    tcs->state = *state;
455 
456    nir_tgsi_scan_shader(state->ir.nir, &tcs->info, true);
457 
458    tcs->vector_length = 4;
459    tcs->vertices_out = tcs->info.properties[TGSI_PROPERTY_TCS_VERTICES_OUT];
460 #if DRAW_LLVM_AVAILABLE
461    if (use_llvm) {
462 
463       tcs->tcs_input = align_malloc(sizeof(struct draw_tcs_inputs), 16);
464       memset(tcs->tcs_input, 0, sizeof(struct draw_tcs_inputs));
465 
466       tcs->tcs_output = align_malloc(sizeof(struct draw_tcs_outputs), 16);
467       memset(tcs->tcs_output, 0, sizeof(struct draw_tcs_outputs));
468 
469       tcs->jit_resources = &draw->llvm->jit_resources[PIPE_SHADER_TESS_CTRL];
470       llvm_tcs->variant_key_size =
471          draw_tcs_llvm_variant_key_size(
472                                         tcs->info.file_max[TGSI_FILE_SAMPLER]+1,
473                                         tcs->info.file_max[TGSI_FILE_SAMPLER_VIEW]+1,
474                                         tcs->info.file_max[TGSI_FILE_IMAGE]+1);
475    }
476 #endif
477    return tcs;
478 }
479 
draw_bind_tess_ctrl_shader(struct draw_context * draw,struct draw_tess_ctrl_shader * dtcs)480 void draw_bind_tess_ctrl_shader(struct draw_context *draw,
481                                 struct draw_tess_ctrl_shader *dtcs)
482 {
483    draw_do_flush(draw, DRAW_FLUSH_STATE_CHANGE);
484    if (dtcs) {
485       draw->tcs.tess_ctrl_shader = dtcs;
486    } else {
487       draw->tcs.tess_ctrl_shader = NULL;
488    }
489 }
490 
draw_delete_tess_ctrl_shader(struct draw_context * draw,struct draw_tess_ctrl_shader * dtcs)491 void draw_delete_tess_ctrl_shader(struct draw_context *draw,
492                                   struct draw_tess_ctrl_shader *dtcs)
493 {
494    if (!dtcs)
495       return;
496 
497 #if DRAW_LLVM_AVAILABLE
498    if (draw->llvm) {
499       struct llvm_tess_ctrl_shader *shader = llvm_tess_ctrl_shader(dtcs);
500 
501       struct draw_tcs_llvm_variant_list_item *li, *next;
502 
503       LIST_FOR_EACH_ENTRY_SAFE(li, next, &shader->variants.list, list) {
504          draw_tcs_llvm_destroy_variant(li->base);
505       }
506 
507       assert(shader->variants_cached == 0);
508       align_free(dtcs->tcs_input);
509       align_free(dtcs->tcs_output);
510    }
511 #endif
512 
513    if (dtcs->state.type == PIPE_SHADER_IR_NIR && dtcs->state.ir.nir)
514       ralloc_free(dtcs->state.ir.nir);
515    FREE(dtcs);
516 }
517 
518 #if DRAW_LLVM_AVAILABLE
draw_tcs_set_current_variant(struct draw_tess_ctrl_shader * shader,struct draw_tcs_llvm_variant * variant)519 void draw_tcs_set_current_variant(struct draw_tess_ctrl_shader *shader,
520                                   struct draw_tcs_llvm_variant *variant)
521 {
522    shader->current_variant = variant;
523 }
524 #endif
525 
526 struct draw_tess_eval_shader *
draw_create_tess_eval_shader(struct draw_context * draw,const struct pipe_shader_state * state)527 draw_create_tess_eval_shader(struct draw_context *draw,
528                              const struct pipe_shader_state *state)
529 {
530 #if DRAW_LLVM_AVAILABLE
531    bool use_llvm = draw->llvm != NULL;
532    struct llvm_tess_eval_shader *llvm_tes = NULL;
533 #endif
534    struct draw_tess_eval_shader *tes;
535 
536 #if DRAW_LLVM_AVAILABLE
537    if (use_llvm) {
538       llvm_tes = CALLOC_STRUCT(llvm_tess_eval_shader);
539 
540       if (!llvm_tes)
541          return NULL;
542 
543       tes = &llvm_tes->base;
544       list_inithead(&llvm_tes->variants.list);
545    } else
546 #endif
547    {
548       tes = CALLOC_STRUCT(draw_tess_eval_shader);
549    }
550 
551    if (!tes)
552       return NULL;
553 
554    tes->draw = draw;
555    tes->state = *state;
556 
557    nir_tgsi_scan_shader(state->ir.nir, &tes->info, true);
558 
559    tes->prim_mode = tes->info.properties[TGSI_PROPERTY_TES_PRIM_MODE];
560    tes->spacing = tes->info.properties[TGSI_PROPERTY_TES_SPACING];
561    tes->vertex_order_cw = tes->info.properties[TGSI_PROPERTY_TES_VERTEX_ORDER_CW];
562    tes->point_mode = tes->info.properties[TGSI_PROPERTY_TES_POINT_MODE];
563 
564    tes->vector_length = 4;
565 
566    tes->position_output = -1;
567    bool found_clipvertex = false;
568    for (unsigned i = 0; i < tes->info.num_outputs; i++) {
569       if (tes->info.output_semantic_name[i] == TGSI_SEMANTIC_POSITION &&
570           tes->info.output_semantic_index[i] == 0)
571          tes->position_output = i;
572       if (tes->info.output_semantic_name[i] == TGSI_SEMANTIC_VIEWPORT_INDEX)
573          tes->viewport_index_output = i;
574       if (tes->info.output_semantic_name[i] == TGSI_SEMANTIC_CLIPVERTEX &&
575           tes->info.output_semantic_index[i] == 0) {
576          found_clipvertex = true;
577          tes->clipvertex_output = i;
578       }
579       if (tes->info.output_semantic_name[i] == TGSI_SEMANTIC_CLIPDIST) {
580          assert(tes->info.output_semantic_index[i] <
581                       PIPE_MAX_CLIP_OR_CULL_DISTANCE_ELEMENT_COUNT);
582          tes->ccdistance_output[tes->info.output_semantic_index[i]] = i;
583       }
584    }
585    if (!found_clipvertex)
586       tes->clipvertex_output = tes->position_output;
587 
588 #if DRAW_LLVM_AVAILABLE
589    if (use_llvm) {
590 
591       tes->tes_input = align_malloc(sizeof(struct draw_tes_inputs), 16);
592       memset(tes->tes_input, 0, sizeof(struct draw_tes_inputs));
593 
594       tes->jit_resources = &draw->llvm->jit_resources[PIPE_SHADER_TESS_EVAL];
595       llvm_tes->variant_key_size =
596          draw_tes_llvm_variant_key_size(
597                                         tes->info.file_max[TGSI_FILE_SAMPLER]+1,
598                                         tes->info.file_max[TGSI_FILE_SAMPLER_VIEW]+1,
599                                         tes->info.file_max[TGSI_FILE_IMAGE]+1);
600    }
601 #endif
602    return tes;
603 }
604 
draw_bind_tess_eval_shader(struct draw_context * draw,struct draw_tess_eval_shader * dtes)605 void draw_bind_tess_eval_shader(struct draw_context *draw,
606                                 struct draw_tess_eval_shader *dtes)
607 {
608    draw_do_flush(draw, DRAW_FLUSH_STATE_CHANGE);
609    if (dtes) {
610       draw->tes.tess_eval_shader = dtes;
611       draw->tes.num_tes_outputs = dtes->info.num_outputs;
612       draw->tes.position_output = dtes->position_output;
613       draw->tes.clipvertex_output = dtes->clipvertex_output;
614    } else {
615       draw->tes.tess_eval_shader = NULL;
616    }
617 }
618 
draw_delete_tess_eval_shader(struct draw_context * draw,struct draw_tess_eval_shader * dtes)619 void draw_delete_tess_eval_shader(struct draw_context *draw,
620                                   struct draw_tess_eval_shader *dtes)
621 {
622    if (!dtes)
623       return;
624 
625 #if DRAW_LLVM_AVAILABLE
626    if (draw->llvm) {
627       struct llvm_tess_eval_shader *shader = llvm_tess_eval_shader(dtes);
628       struct draw_tes_llvm_variant_list_item *li, *next;
629 
630       LIST_FOR_EACH_ENTRY_SAFE(li, next, &shader->variants.list, list) {
631          draw_tes_llvm_destroy_variant(li->base);
632       }
633 
634       assert(shader->variants_cached == 0);
635       align_free(dtes->tes_input);
636    }
637 #endif
638    if (dtes->state.type == PIPE_SHADER_IR_NIR && dtes->state.ir.nir)
639       ralloc_free(dtes->state.ir.nir);
640    FREE(dtes);
641 }
642 
643 #if DRAW_LLVM_AVAILABLE
draw_tes_set_current_variant(struct draw_tess_eval_shader * shader,struct draw_tes_llvm_variant * variant)644 void draw_tes_set_current_variant(struct draw_tess_eval_shader *shader,
645                                   struct draw_tes_llvm_variant *variant)
646 {
647    shader->current_variant = variant;
648 }
649 #endif
650 
get_tes_output_prim(struct draw_tess_eval_shader * shader)651 enum mesa_prim get_tes_output_prim(struct draw_tess_eval_shader *shader)
652 {
653    if (shader->point_mode)
654       return MESA_PRIM_POINTS;
655    else if (shader->prim_mode == MESA_PRIM_LINES)
656       return MESA_PRIM_LINES;
657    else
658       return MESA_PRIM_TRIANGLES;
659 }
660