17ec681f3Smrg/**************************************************************************
27ec681f3Smrg *
37ec681f3Smrg * Copyright 2020 Red Hat.
47ec681f3Smrg * All Rights Reserved.
57ec681f3Smrg *
67ec681f3Smrg * Permission is hereby granted, free of charge, to any person obtaining a
77ec681f3Smrg * copy of this software and associated documentation files (the "Software"),
87ec681f3Smrg * to deal in the Software without restriction, including without limitation
97ec681f3Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
107ec681f3Smrg * and/or sell copies of the Software, and to permit persons to whom the
117ec681f3Smrg * Software is furnished to do so, subject to the following conditions:
127ec681f3Smrg *
137ec681f3Smrg * The above copyright notice and this permission notice shall be included
147ec681f3Smrg * in all copies or substantial portions of the Software.
157ec681f3Smrg *
167ec681f3Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
177ec681f3Smrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
187ec681f3Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
197ec681f3Smrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
207ec681f3Smrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
217ec681f3Smrg * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
227ec681f3Smrg * SOFTWARE.
237ec681f3Smrg *
247ec681f3Smrg **************************************************************************/
257ec681f3Smrg#include "draw_tess.h"
267ec681f3Smrg#ifdef DRAW_LLVM_AVAILABLE
277ec681f3Smrg#include "draw_llvm.h"
287ec681f3Smrg#endif
297ec681f3Smrg
307ec681f3Smrg#include "tessellator/p_tessellator.h"
317ec681f3Smrg#include "nir/nir_to_tgsi_info.h"
327ec681f3Smrg#include "util/u_prim.h"
337ec681f3Smrg#include "util/u_math.h"
347ec681f3Smrg#include "util/u_memory.h"
357ec681f3Smrg#include "util/ralloc.h"
367ec681f3Smrg#ifdef DRAW_LLVM_AVAILABLE
377ec681f3Smrgstatic inline int
387ec681f3Smrgdraw_tes_get_input_index(int semantic, int index,
397ec681f3Smrg                         const struct tgsi_shader_info *input_info)
407ec681f3Smrg{
417ec681f3Smrg   int i;
427ec681f3Smrg   const ubyte *input_semantic_names = input_info->output_semantic_name;
437ec681f3Smrg   const ubyte *input_semantic_indices = input_info->output_semantic_index;
447ec681f3Smrg   for (i = 0; i < PIPE_MAX_SHADER_OUTPUTS; i++) {
457ec681f3Smrg      if (input_semantic_names[i] == semantic &&
467ec681f3Smrg          input_semantic_indices[i] == index)
477ec681f3Smrg         return i;
487ec681f3Smrg   }
497ec681f3Smrg   return -1;
507ec681f3Smrg}
517ec681f3Smrg
527ec681f3Smrg#define DEBUG_INPUTS 0
537ec681f3Smrgstatic void
547ec681f3Smrgllvm_fetch_tcs_input(struct draw_tess_ctrl_shader *shader,
557ec681f3Smrg                     const struct draw_prim_info *input_prim_info,
567ec681f3Smrg                     unsigned prim_id,
577ec681f3Smrg                     unsigned num_vertices)
587ec681f3Smrg{
597ec681f3Smrg   const float (*input_ptr)[4];
607ec681f3Smrg   float (*input_data)[32][NUM_TCS_INPUTS][TGSI_NUM_CHANNELS] = &shader->tcs_input->data;
617ec681f3Smrg   unsigned slot, i;
627ec681f3Smrg   int vs_slot;
637ec681f3Smrg   unsigned input_vertex_stride = shader->input_vertex_stride;
647ec681f3Smrg
657ec681f3Smrg   input_ptr = shader->input;
667ec681f3Smrg   for (i = 0; i < num_vertices; i++) {
677ec681f3Smrg      const float (*input)[4];
687ec681f3Smrg      int vertex_idx = prim_id * num_vertices + i;
697ec681f3Smrg      if (input_prim_info->linear == FALSE)
707ec681f3Smrg         vertex_idx = input_prim_info->elts[vertex_idx];
717ec681f3Smrg#if DEBUG_INPUTS
727ec681f3Smrg      debug_printf("%d) tcs vertex index = %d (prim idx = %d)\n",
737ec681f3Smrg                   i, prim_id, 0);
747ec681f3Smrg#endif
757ec681f3Smrg      input = (const float (*)[4])((const char *)input_ptr + (vertex_idx * input_vertex_stride));
767ec681f3Smrg      for (slot = 0, vs_slot = 0; slot < shader->info.num_inputs; ++slot) {
777ec681f3Smrg         vs_slot = draw_tes_get_input_index(
787ec681f3Smrg                                            shader->info.input_semantic_name[slot],
797ec681f3Smrg                                            shader->info.input_semantic_index[slot],
807ec681f3Smrg                                            shader->input_info);
817ec681f3Smrg         if (vs_slot < 0) {
827ec681f3Smrg            debug_printf("VS/TCS signature mismatch!\n");
837ec681f3Smrg            (*input_data)[i][slot][0] = 0;
847ec681f3Smrg            (*input_data)[i][slot][1] = 0;
857ec681f3Smrg            (*input_data)[i][slot][2] = 0;
867ec681f3Smrg            (*input_data)[i][slot][3] = 0;
877ec681f3Smrg         } else {
887ec681f3Smrg            (*input_data)[i][slot][0] = input[vs_slot][0];
897ec681f3Smrg            (*input_data)[i][slot][1] = input[vs_slot][1];
907ec681f3Smrg            (*input_data)[i][slot][2] = input[vs_slot][2];
917ec681f3Smrg            (*input_data)[i][slot][3] = input[vs_slot][3];
927ec681f3Smrg#if DEBUG_INPUTS
937ec681f3Smrg            debug_printf("\t\t%p = %f %f %f %f\n", &(*input_data)[i][slot][0],
947ec681f3Smrg                         (*input_data)[i][slot][0],
957ec681f3Smrg                         (*input_data)[i][slot][1],
967ec681f3Smrg                         (*input_data)[i][slot][2],
977ec681f3Smrg                         (*input_data)[i][slot][3]);
987ec681f3Smrg#endif
997ec681f3Smrg            ++vs_slot;
1007ec681f3Smrg         }
1017ec681f3Smrg      }
1027ec681f3Smrg   }
1037ec681f3Smrg}
1047ec681f3Smrg
1057ec681f3Smrg#define DEBUG_OUTPUTS 0
1067ec681f3Smrgstatic void
1077ec681f3Smrgllvm_store_tcs_output(struct draw_tess_ctrl_shader *shader,
1087ec681f3Smrg                      unsigned prim_id,
1097ec681f3Smrg                      struct draw_vertex_info *output_verts,
1107ec681f3Smrg                      unsigned vert_start)
1117ec681f3Smrg{
1127ec681f3Smrg   float (*output_ptr)[4];
1137ec681f3Smrg   float (*output_data)[32][PIPE_MAX_SHADER_INPUTS][TGSI_NUM_CHANNELS] = &shader->tcs_output->data;
1147ec681f3Smrg   unsigned slot, i;
1157ec681f3Smrg   unsigned num_vertices = shader->vertices_out;
1167ec681f3Smrg
1177ec681f3Smrg   char *output = (char *)output_verts->verts->data;
1187ec681f3Smrg   output += vert_start * output_verts->stride;
1197ec681f3Smrg
1207ec681f3Smrg   for (i = 0; i < num_vertices; i++) {
1217ec681f3Smrg
1227ec681f3Smrg#if DEBUG_OUTPUTS
1237ec681f3Smrg      debug_printf("%d) tcs store vertex index = %d (prim idx = %d)\n",
1247ec681f3Smrg                   i, prim_id, 0);
1257ec681f3Smrg#endif
1267ec681f3Smrg      output_ptr = (float(*)[4])(output + (i * output_verts->stride));
1277ec681f3Smrg
1287ec681f3Smrg      for (slot = 0; slot < shader->info.num_outputs; ++slot) {
1297ec681f3Smrg         output_ptr[slot][0] = (*output_data)[i][slot][0];
1307ec681f3Smrg         output_ptr[slot][1] = (*output_data)[i][slot][1];
1317ec681f3Smrg         output_ptr[slot][2] = (*output_data)[i][slot][2];
1327ec681f3Smrg         output_ptr[slot][3] = (*output_data)[i][slot][3];
1337ec681f3Smrg#if DEBUG_OUTPUTS
1347ec681f3Smrg         debug_printf("\t\t%p = %f %f %f %f\n",
1357ec681f3Smrg                      &output_ptr[slot][0],
1367ec681f3Smrg                      output_ptr[slot][0],
1377ec681f3Smrg                      output_ptr[slot][1],
1387ec681f3Smrg                      output_ptr[slot][2],
1397ec681f3Smrg                      output_ptr[slot][3]);
1407ec681f3Smrg#endif
1417ec681f3Smrg      }
1427ec681f3Smrg   }
1437ec681f3Smrg}
1447ec681f3Smrg
1457ec681f3Smrgstatic void
1467ec681f3Smrgllvm_tcs_run(struct draw_tess_ctrl_shader *shader, uint32_t prim_id)
1477ec681f3Smrg{
1487ec681f3Smrg   shader->current_variant->jit_func(shader->jit_context, shader->tcs_input->data, shader->tcs_output->data, prim_id,
1497ec681f3Smrg                                     shader->draw->pt.vertices_per_patch, shader->draw->pt.user.viewid);
1507ec681f3Smrg}
1517ec681f3Smrg#endif
1527ec681f3Smrg
1537ec681f3Smrg/**
1547ec681f3Smrg * Execute tess ctrl shader.
1557ec681f3Smrg */
1567ec681f3Smrgint draw_tess_ctrl_shader_run(struct draw_tess_ctrl_shader *shader,
1577ec681f3Smrg                              const void *constants[PIPE_MAX_CONSTANT_BUFFERS],
1587ec681f3Smrg                              const unsigned constants_size[PIPE_MAX_CONSTANT_BUFFERS],
1597ec681f3Smrg                              const struct draw_vertex_info *input_verts,
1607ec681f3Smrg                              const struct draw_prim_info *input_prim,
1617ec681f3Smrg                              const struct tgsi_shader_info *input_info,
1627ec681f3Smrg                              struct draw_vertex_info *output_verts,
1637ec681f3Smrg                              struct draw_prim_info *output_prims )
1647ec681f3Smrg{
1657ec681f3Smrg   const float (*input)[4] = (const float (*)[4])input_verts->verts->data;
1667ec681f3Smrg   unsigned num_outputs = draw_total_tcs_outputs(shader->draw);
1677ec681f3Smrg   unsigned input_stride = input_verts->vertex_size;
1687ec681f3Smrg   unsigned vertex_size = sizeof(struct vertex_header) + num_outputs * 4 * sizeof(float);
1697ec681f3Smrg   unsigned num_patches = input_prim->count / shader->draw->pt.vertices_per_patch;
1707ec681f3Smrg
1717ec681f3Smrg   output_verts->vertex_size = vertex_size;
1727ec681f3Smrg   output_verts->stride = output_verts->vertex_size;
1737ec681f3Smrg   output_verts->verts = NULL;
1747ec681f3Smrg   output_verts->count = 0;
1757ec681f3Smrg   shader->input = input;
1767ec681f3Smrg   shader->input_vertex_stride = input_stride;
1777ec681f3Smrg   shader->input_info = input_info;
1787ec681f3Smrg
1797ec681f3Smrg   output_prims->linear = TRUE;
1807ec681f3Smrg   output_prims->start = 0;
1817ec681f3Smrg   output_prims->elts = NULL;
1827ec681f3Smrg   output_prims->count = 0;
1837ec681f3Smrg   output_prims->prim = PIPE_PRIM_PATCHES;
1847ec681f3Smrg   output_prims->flags = 0;
1857ec681f3Smrg   output_prims->primitive_lengths = NULL;
1867ec681f3Smrg   output_prims->primitive_count = 0;
1877ec681f3Smrg
1887ec681f3Smrg   if (shader->draw->collect_statistics) {
1897ec681f3Smrg      shader->draw->statistics.hs_invocations += num_patches;
1907ec681f3Smrg   }
1917ec681f3Smrg#ifdef DRAW_LLVM_AVAILABLE
1927ec681f3Smrg   for (unsigned i = 0; i < num_patches; i++) {
1937ec681f3Smrg      uint32_t vert_start = output_verts->count;
1947ec681f3Smrg
1957ec681f3Smrg      output_verts->count += shader->vertices_out;
1967ec681f3Smrg
1977ec681f3Smrg      llvm_fetch_tcs_input(shader, input_prim, i, shader->draw->pt.vertices_per_patch);
1987ec681f3Smrg
1997ec681f3Smrg      llvm_tcs_run(shader, i);
2007ec681f3Smrg
2017ec681f3Smrg      uint32_t old_verts = util_align_npot(vert_start, 16);
2027ec681f3Smrg      uint32_t new_verts = util_align_npot(output_verts->count, 16);
2037ec681f3Smrg      uint32_t old_size = output_verts->vertex_size * old_verts;
2047ec681f3Smrg      uint32_t new_size = output_verts->vertex_size * new_verts;
2057ec681f3Smrg      output_verts->verts = REALLOC(output_verts->verts, old_size, new_size);
2067ec681f3Smrg
2077ec681f3Smrg      llvm_store_tcs_output(shader, i, output_verts, vert_start);
2087ec681f3Smrg   }
2097ec681f3Smrg#endif
2107ec681f3Smrg
2117ec681f3Smrg   output_prims->primitive_count = num_patches;
2127ec681f3Smrg   return 0;
2137ec681f3Smrg}
2147ec681f3Smrg
2157ec681f3Smrg#ifdef DRAW_LLVM_AVAILABLE
2167ec681f3Smrg#define DEBUG_INPUTS 0
2177ec681f3Smrgstatic void
2187ec681f3Smrgllvm_fetch_tes_input(struct draw_tess_eval_shader *shader,
2197ec681f3Smrg                     const struct draw_prim_info *input_prim_info,
2207ec681f3Smrg                     unsigned prim_id,
2217ec681f3Smrg                     unsigned num_vertices)
2227ec681f3Smrg{
2237ec681f3Smrg   const float (*input_ptr)[4];
2247ec681f3Smrg   float (*input_data)[32][PIPE_MAX_SHADER_INPUTS][TGSI_NUM_CHANNELS] = &shader->tes_input->data;
2257ec681f3Smrg   unsigned slot, i;
2267ec681f3Smrg   int vs_slot;
2277ec681f3Smrg   unsigned input_vertex_stride = shader->input_vertex_stride;
2287ec681f3Smrg
2297ec681f3Smrg   input_ptr = shader->input;
2307ec681f3Smrg   for (i = 0; i < num_vertices; i++) {
2317ec681f3Smrg      const float (*input)[4];
2327ec681f3Smrg      int vertex_idx = prim_id * num_vertices + i;
2337ec681f3Smrg
2347ec681f3Smrg      if (input_prim_info->linear == FALSE)
2357ec681f3Smrg         vertex_idx = input_prim_info->elts[vertex_idx];
2367ec681f3Smrg#if DEBUG_INPUTS
2377ec681f3Smrg      debug_printf("%d) tes vertex index = %d (prim idx = %d)\n",
2387ec681f3Smrg                   i, prim_id, 0);
2397ec681f3Smrg#endif
2407ec681f3Smrg      input = (const float (*)[4])((const char *)input_ptr + (vertex_idx * input_vertex_stride));
2417ec681f3Smrg      for (slot = 0, vs_slot = 0; slot < shader->info.num_inputs; ++slot) {
2427ec681f3Smrg         vs_slot = draw_tes_get_input_index(
2437ec681f3Smrg                                            shader->info.input_semantic_name[slot],
2447ec681f3Smrg                                            shader->info.input_semantic_index[slot],
2457ec681f3Smrg                                            shader->input_info);
2467ec681f3Smrg         if (vs_slot < 0) {
2477ec681f3Smrg            debug_printf("TCS/TES signature mismatch!\n");
2487ec681f3Smrg            (*input_data)[i][slot][0] = 0;
2497ec681f3Smrg            (*input_data)[i][slot][1] = 0;
2507ec681f3Smrg            (*input_data)[i][slot][2] = 0;
2517ec681f3Smrg            (*input_data)[i][slot][3] = 0;
2527ec681f3Smrg         } else {
2537ec681f3Smrg            (*input_data)[i][slot][0] = input[vs_slot][0];
2547ec681f3Smrg            (*input_data)[i][slot][1] = input[vs_slot][1];
2557ec681f3Smrg            (*input_data)[i][slot][2] = input[vs_slot][2];
2567ec681f3Smrg            (*input_data)[i][slot][3] = input[vs_slot][3];
2577ec681f3Smrg#if DEBUG_INPUTS
2587ec681f3Smrg            debug_printf("\t\t%p = %f %f %f %f\n",
2597ec681f3Smrg                         &input[vs_slot][0],
2607ec681f3Smrg                         (*input_data)[i][slot][0],
2617ec681f3Smrg                         (*input_data)[i][slot][1],
2627ec681f3Smrg                         (*input_data)[i][slot][2],
2637ec681f3Smrg                         (*input_data)[i][slot][3]);
2647ec681f3Smrg#endif
2657ec681f3Smrg            ++vs_slot;
2667ec681f3Smrg         }
2677ec681f3Smrg      }
2687ec681f3Smrg   }
2697ec681f3Smrg}
2707ec681f3Smrg
2717ec681f3Smrgstatic void
2727ec681f3Smrgllvm_fetch_tess_factors(struct draw_tess_eval_shader *shader,
2737ec681f3Smrg                        unsigned patch_id,
2747ec681f3Smrg                        unsigned num_vertices,
2757ec681f3Smrg                        struct pipe_tessellation_factors *factors)
2767ec681f3Smrg{
2777ec681f3Smrg   int outer_slot = draw_tes_get_input_index(
2787ec681f3Smrg      TGSI_SEMANTIC_TESSOUTER, 0, shader->input_info);
2797ec681f3Smrg   int inner_slot = draw_tes_get_input_index(
2807ec681f3Smrg      TGSI_SEMANTIC_TESSINNER, 0, shader->input_info);
2817ec681f3Smrg   const float (*input_ptr)[4];
2827ec681f3Smrg   const float (*input)[4];
2837ec681f3Smrg   input_ptr = shader->input;
2847ec681f3Smrg   input = (const float (*)[4])((const char *)input_ptr + ((patch_id * num_vertices) * shader->input_vertex_stride));
2857ec681f3Smrg
2867ec681f3Smrg   if (outer_slot != -1) {
2877ec681f3Smrg      for (unsigned i = 0; i < 4; i++)
2887ec681f3Smrg         factors->outer_tf[i] = input[outer_slot][i];
2897ec681f3Smrg   } else {
2907ec681f3Smrg      for (unsigned i = 0; i < 4; i++)
2917ec681f3Smrg         factors->outer_tf[i] = shader->draw->default_outer_tess_level[i];
2927ec681f3Smrg   }
2937ec681f3Smrg   if (inner_slot != -1) {
2947ec681f3Smrg      for (unsigned i = 0; i < 2; i++)
2957ec681f3Smrg         factors->inner_tf[i] = input[inner_slot][i];
2967ec681f3Smrg   } else {
2977ec681f3Smrg      for (unsigned i = 0; i < 2; i++)
2987ec681f3Smrg         factors->inner_tf[i] = shader->draw->default_inner_tess_level[i];
2997ec681f3Smrg   }
3007ec681f3Smrg}
3017ec681f3Smrg
3027ec681f3Smrgstatic void
3037ec681f3Smrgllvm_tes_run(struct draw_tess_eval_shader *shader,
3047ec681f3Smrg             uint32_t prim_id,
3057ec681f3Smrg             uint32_t patch_vertices_in,
3067ec681f3Smrg             struct pipe_tessellator_data *tess_data,
3077ec681f3Smrg             struct pipe_tessellation_factors *tess_factors,
3087ec681f3Smrg             struct vertex_header *output)
3097ec681f3Smrg{
3107ec681f3Smrg   shader->current_variant->jit_func(shader->jit_context, shader->tes_input->data, output, prim_id,
3117ec681f3Smrg                                     tess_data->num_domain_points, tess_data->domain_points_u, tess_data->domain_points_v,
3127ec681f3Smrg                                     tess_factors->outer_tf, tess_factors->inner_tf, patch_vertices_in,
3137ec681f3Smrg                                     shader->draw->pt.user.viewid);
3147ec681f3Smrg}
3157ec681f3Smrg#endif
3167ec681f3Smrg
3177ec681f3Smrg/**
3187ec681f3Smrg * Execute tess eval shader.
3197ec681f3Smrg */
3207ec681f3Smrgint draw_tess_eval_shader_run(struct draw_tess_eval_shader *shader,
3217ec681f3Smrg                              const void *constants[PIPE_MAX_CONSTANT_BUFFERS],
3227ec681f3Smrg                              const unsigned constants_size[PIPE_MAX_CONSTANT_BUFFERS],
3237ec681f3Smrg                              unsigned num_input_vertices_per_patch,
3247ec681f3Smrg                              const struct draw_vertex_info *input_verts,
3257ec681f3Smrg                              const struct draw_prim_info *input_prim,
3267ec681f3Smrg                              const struct tgsi_shader_info *input_info,
3277ec681f3Smrg                              struct draw_vertex_info *output_verts,
3287ec681f3Smrg                              struct draw_prim_info *output_prims,
3297ec681f3Smrg                              ushort **elts_out)
3307ec681f3Smrg{
3317ec681f3Smrg   const float (*input)[4] = (const float (*)[4])input_verts->verts->data;
3327ec681f3Smrg   unsigned num_outputs = draw_total_tes_outputs(shader->draw);
3337ec681f3Smrg   unsigned input_stride = input_verts->vertex_size;
3347ec681f3Smrg   unsigned vertex_size = sizeof(struct vertex_header) + num_outputs * 4 * sizeof(float);
3357ec681f3Smrg   ushort *elts = NULL;
3367ec681f3Smrg   output_verts->vertex_size = vertex_size;
3377ec681f3Smrg   output_verts->stride = output_verts->vertex_size;
3387ec681f3Smrg   output_verts->count = 0;
3397ec681f3Smrg   output_verts->verts = NULL;
3407ec681f3Smrg
3417ec681f3Smrg   output_prims->linear = FALSE;
3427ec681f3Smrg   output_prims->start = 0;
3437ec681f3Smrg   output_prims->elts = NULL;
3447ec681f3Smrg   output_prims->count = 0;
3457ec681f3Smrg   output_prims->prim = get_tes_output_prim(shader);
3467ec681f3Smrg   output_prims->flags = 0;
3477ec681f3Smrg   output_prims->primitive_lengths = NULL;
3487ec681f3Smrg   output_prims->primitive_count = 0;
3497ec681f3Smrg
3507ec681f3Smrg   shader->input = input;
3517ec681f3Smrg   shader->input_vertex_stride = input_stride;
3527ec681f3Smrg   shader->input_info = input_info;
3537ec681f3Smrg
3547ec681f3Smrg#ifdef DRAW_LLVM_AVAILABLE
3557ec681f3Smrg   struct pipe_tessellation_factors factors;
3567ec681f3Smrg   struct pipe_tessellator_data data = { 0 };
3577ec681f3Smrg   struct pipe_tessellator *ptess = p_tess_init(shader->prim_mode,
3587ec681f3Smrg                                                shader->spacing,
3597ec681f3Smrg                                                !shader->vertex_order_cw,
3607ec681f3Smrg                                                shader->point_mode);
3617ec681f3Smrg   for (unsigned i = 0; i < input_prim->primitive_count; i++) {
3627ec681f3Smrg      uint32_t vert_start = output_verts->count;
3637ec681f3Smrg      uint32_t prim_start = output_prims->primitive_count;
3647ec681f3Smrg      uint32_t elt_start = output_prims->count;
3657ec681f3Smrg
3667ec681f3Smrg      llvm_fetch_tess_factors(shader, i, num_input_vertices_per_patch, &factors);
3677ec681f3Smrg
3687ec681f3Smrg      /* tessellate with the factors for this primitive */
3697ec681f3Smrg      p_tessellate(ptess, &factors, &data);
3707ec681f3Smrg
3717ec681f3Smrg      if (data.num_domain_points == 0)
3727ec681f3Smrg         continue;
3737ec681f3Smrg
3747ec681f3Smrg      uint32_t old_verts = vert_start;
3757ec681f3Smrg      uint32_t new_verts = vert_start + util_align_npot(data.num_domain_points, 4);
3767ec681f3Smrg      uint32_t old_size = output_verts->vertex_size * old_verts;
3777ec681f3Smrg      uint32_t new_size = output_verts->vertex_size * new_verts;
3787ec681f3Smrg      output_verts->verts = REALLOC(output_verts->verts, old_size, new_size);
3797ec681f3Smrg
3807ec681f3Smrg      output_verts->count += data.num_domain_points;
3817ec681f3Smrg
3827ec681f3Smrg      output_prims->count += data.num_indices;
3837ec681f3Smrg      elts = REALLOC(elts, elt_start * sizeof(uint16_t),
3847ec681f3Smrg                     output_prims->count * sizeof(uint16_t));
3857ec681f3Smrg
3867ec681f3Smrg      for (unsigned i = 0; i < data.num_indices; i++)
3877ec681f3Smrg         elts[elt_start + i] = vert_start + data.indices[i];
3887ec681f3Smrg
3897ec681f3Smrg      llvm_fetch_tes_input(shader, input_prim, i, num_input_vertices_per_patch);
3907ec681f3Smrg      /* run once per primitive? */
3917ec681f3Smrg      char *output = (char *)output_verts->verts;
3927ec681f3Smrg      output += vert_start * vertex_size;
3937ec681f3Smrg      llvm_tes_run(shader, i, num_input_vertices_per_patch, &data, &factors, (struct vertex_header *)output);
3947ec681f3Smrg
3957ec681f3Smrg      if (shader->draw->collect_statistics) {
3967ec681f3Smrg         shader->draw->statistics.ds_invocations += data.num_domain_points;
3977ec681f3Smrg      }
3987ec681f3Smrg
3997ec681f3Smrg      uint32_t prim_len = u_prim_vertex_count(output_prims->prim)->min;
4007ec681f3Smrg      output_prims->primitive_count += data.num_indices / prim_len;
4017ec681f3Smrg      output_prims->primitive_lengths = REALLOC(output_prims->primitive_lengths, prim_start * sizeof(uint32_t),
4027ec681f3Smrg                                                output_prims->primitive_count * sizeof(uint32_t));
4037ec681f3Smrg      for (unsigned i = prim_start; i < output_prims->primitive_count; i++) {
4047ec681f3Smrg         output_prims->primitive_lengths[i] = prim_len;
4057ec681f3Smrg      }
4067ec681f3Smrg   }
4077ec681f3Smrg   p_tess_destroy(ptess);
4087ec681f3Smrg#endif
4097ec681f3Smrg
4107ec681f3Smrg   *elts_out = elts;
4117ec681f3Smrg   output_prims->elts = elts;
4127ec681f3Smrg   return 0;
4137ec681f3Smrg}
4147ec681f3Smrg
4157ec681f3Smrgstruct draw_tess_ctrl_shader *
4167ec681f3Smrgdraw_create_tess_ctrl_shader(struct draw_context *draw,
4177ec681f3Smrg                             const struct pipe_shader_state *state)
4187ec681f3Smrg{
4197ec681f3Smrg#ifdef DRAW_LLVM_AVAILABLE
4207ec681f3Smrg   boolean use_llvm = draw->llvm != NULL;
4217ec681f3Smrg   struct llvm_tess_ctrl_shader *llvm_tcs = NULL;
4227ec681f3Smrg#endif
4237ec681f3Smrg   struct draw_tess_ctrl_shader *tcs;
4247ec681f3Smrg
4257ec681f3Smrg#ifdef DRAW_LLVM_AVAILABLE
4267ec681f3Smrg   if (use_llvm) {
4277ec681f3Smrg      llvm_tcs = CALLOC_STRUCT(llvm_tess_ctrl_shader);
4287ec681f3Smrg
4297ec681f3Smrg      if (!llvm_tcs)
4307ec681f3Smrg         return NULL;
4317ec681f3Smrg
4327ec681f3Smrg      tcs = &llvm_tcs->base;
4337ec681f3Smrg
4347ec681f3Smrg      make_empty_list(&llvm_tcs->variants);
4357ec681f3Smrg   } else
4367ec681f3Smrg#endif
4377ec681f3Smrg   {
4387ec681f3Smrg      tcs = CALLOC_STRUCT(draw_tess_ctrl_shader);
4397ec681f3Smrg   }
4407ec681f3Smrg
4417ec681f3Smrg   if (!tcs)
4427ec681f3Smrg      return NULL;
4437ec681f3Smrg
4447ec681f3Smrg   tcs->draw = draw;
4457ec681f3Smrg   tcs->state = *state;
4467ec681f3Smrg
4477ec681f3Smrg   nir_tgsi_scan_shader(state->ir.nir, &tcs->info, true);
4487ec681f3Smrg
4497ec681f3Smrg   tcs->vector_length = 4;
4507ec681f3Smrg   tcs->vertices_out = tcs->info.properties[TGSI_PROPERTY_TCS_VERTICES_OUT];
4517ec681f3Smrg#ifdef DRAW_LLVM_AVAILABLE
4527ec681f3Smrg   if (use_llvm) {
4537ec681f3Smrg
4547ec681f3Smrg      tcs->tcs_input = align_malloc(sizeof(struct draw_tcs_inputs), 16);
4557ec681f3Smrg      memset(tcs->tcs_input, 0, sizeof(struct draw_tcs_inputs));
4567ec681f3Smrg
4577ec681f3Smrg      tcs->tcs_output = align_malloc(sizeof(struct draw_tcs_outputs), 16);
4587ec681f3Smrg      memset(tcs->tcs_output, 0, sizeof(struct draw_tcs_outputs));
4597ec681f3Smrg
4607ec681f3Smrg      tcs->jit_context = &draw->llvm->tcs_jit_context;
4617ec681f3Smrg      llvm_tcs->variant_key_size =
4627ec681f3Smrg         draw_tcs_llvm_variant_key_size(
4637ec681f3Smrg                                        MAX2(tcs->info.file_max[TGSI_FILE_SAMPLER]+1,
4647ec681f3Smrg                                             tcs->info.file_max[TGSI_FILE_SAMPLER_VIEW]+1),
4657ec681f3Smrg                                        tcs->info.file_max[TGSI_FILE_IMAGE]+1);
4667ec681f3Smrg   }
4677ec681f3Smrg#endif
4687ec681f3Smrg   return tcs;
4697ec681f3Smrg}
4707ec681f3Smrg
4717ec681f3Smrgvoid draw_bind_tess_ctrl_shader(struct draw_context *draw,
4727ec681f3Smrg                                struct draw_tess_ctrl_shader *dtcs)
4737ec681f3Smrg{
4747ec681f3Smrg   draw_do_flush(draw, DRAW_FLUSH_STATE_CHANGE);
4757ec681f3Smrg   if (dtcs) {
4767ec681f3Smrg      draw->tcs.tess_ctrl_shader = dtcs;
4777ec681f3Smrg   } else {
4787ec681f3Smrg      draw->tcs.tess_ctrl_shader = NULL;
4797ec681f3Smrg   }
4807ec681f3Smrg}
4817ec681f3Smrg
4827ec681f3Smrgvoid draw_delete_tess_ctrl_shader(struct draw_context *draw,
4837ec681f3Smrg                                  struct draw_tess_ctrl_shader *dtcs)
4847ec681f3Smrg{
4857ec681f3Smrg   if (!dtcs)
4867ec681f3Smrg      return;
4877ec681f3Smrg
4887ec681f3Smrg#ifdef DRAW_LLVM_AVAILABLE
4897ec681f3Smrg   if (draw->llvm) {
4907ec681f3Smrg      struct llvm_tess_ctrl_shader *shader = llvm_tess_ctrl_shader(dtcs);
4917ec681f3Smrg
4927ec681f3Smrg      struct draw_tcs_llvm_variant_list_item *li;
4937ec681f3Smrg
4947ec681f3Smrg      li = first_elem(&shader->variants);
4957ec681f3Smrg      while(!at_end(&shader->variants, li)) {
4967ec681f3Smrg         struct draw_tcs_llvm_variant_list_item *next = next_elem(li);
4977ec681f3Smrg         draw_tcs_llvm_destroy_variant(li->base);
4987ec681f3Smrg         li = next;
4997ec681f3Smrg      }
5007ec681f3Smrg
5017ec681f3Smrg      assert(shader->variants_cached == 0);
5027ec681f3Smrg      align_free(dtcs->tcs_input);
5037ec681f3Smrg      align_free(dtcs->tcs_output);
5047ec681f3Smrg   }
5057ec681f3Smrg#endif
5067ec681f3Smrg
5077ec681f3Smrg   if (dtcs->state.ir.nir)
5087ec681f3Smrg      ralloc_free(dtcs->state.ir.nir);
5097ec681f3Smrg   FREE(dtcs);
5107ec681f3Smrg}
5117ec681f3Smrg
5127ec681f3Smrg#ifdef DRAW_LLVM_AVAILABLE
5137ec681f3Smrgvoid draw_tcs_set_current_variant(struct draw_tess_ctrl_shader *shader,
5147ec681f3Smrg                                  struct draw_tcs_llvm_variant *variant)
5157ec681f3Smrg{
5167ec681f3Smrg   shader->current_variant = variant;
5177ec681f3Smrg}
5187ec681f3Smrg#endif
5197ec681f3Smrg
5207ec681f3Smrgstruct draw_tess_eval_shader *
5217ec681f3Smrgdraw_create_tess_eval_shader(struct draw_context *draw,
5227ec681f3Smrg                             const struct pipe_shader_state *state)
5237ec681f3Smrg{
5247ec681f3Smrg#ifdef DRAW_LLVM_AVAILABLE
5257ec681f3Smrg   boolean use_llvm = draw->llvm != NULL;
5267ec681f3Smrg   struct llvm_tess_eval_shader *llvm_tes = NULL;
5277ec681f3Smrg#endif
5287ec681f3Smrg   struct draw_tess_eval_shader *tes;
5297ec681f3Smrg
5307ec681f3Smrg#ifdef DRAW_LLVM_AVAILABLE
5317ec681f3Smrg   if (use_llvm) {
5327ec681f3Smrg      llvm_tes = CALLOC_STRUCT(llvm_tess_eval_shader);
5337ec681f3Smrg
5347ec681f3Smrg      if (!llvm_tes)
5357ec681f3Smrg         return NULL;
5367ec681f3Smrg
5377ec681f3Smrg      tes = &llvm_tes->base;
5387ec681f3Smrg      make_empty_list(&llvm_tes->variants);
5397ec681f3Smrg   } else
5407ec681f3Smrg#endif
5417ec681f3Smrg   {
5427ec681f3Smrg      tes = CALLOC_STRUCT(draw_tess_eval_shader);
5437ec681f3Smrg   }
5447ec681f3Smrg
5457ec681f3Smrg   if (!tes)
5467ec681f3Smrg      return NULL;
5477ec681f3Smrg
5487ec681f3Smrg   tes->draw = draw;
5497ec681f3Smrg   tes->state = *state;
5507ec681f3Smrg
5517ec681f3Smrg   nir_tgsi_scan_shader(state->ir.nir, &tes->info, true);
5527ec681f3Smrg
5537ec681f3Smrg   tes->prim_mode = tes->info.properties[TGSI_PROPERTY_TES_PRIM_MODE];
5547ec681f3Smrg   tes->spacing = tes->info.properties[TGSI_PROPERTY_TES_SPACING];
5557ec681f3Smrg   tes->vertex_order_cw = tes->info.properties[TGSI_PROPERTY_TES_VERTEX_ORDER_CW];
5567ec681f3Smrg   tes->point_mode = tes->info.properties[TGSI_PROPERTY_TES_POINT_MODE];
5577ec681f3Smrg
5587ec681f3Smrg   tes->vector_length = 4;
5597ec681f3Smrg
5607ec681f3Smrg   tes->position_output = -1;
5617ec681f3Smrg   bool found_clipvertex = false;
5627ec681f3Smrg   for (unsigned i = 0; i < tes->info.num_outputs; i++) {
5637ec681f3Smrg      if (tes->info.output_semantic_name[i] == TGSI_SEMANTIC_POSITION &&
5647ec681f3Smrg          tes->info.output_semantic_index[i] == 0)
5657ec681f3Smrg         tes->position_output = i;
5667ec681f3Smrg      if (tes->info.output_semantic_name[i] == TGSI_SEMANTIC_VIEWPORT_INDEX)
5677ec681f3Smrg         tes->viewport_index_output = i;
5687ec681f3Smrg      if (tes->info.output_semantic_name[i] == TGSI_SEMANTIC_CLIPVERTEX &&
5697ec681f3Smrg          tes->info.output_semantic_index[i] == 0) {
5707ec681f3Smrg         found_clipvertex = true;
5717ec681f3Smrg         tes->clipvertex_output = i;
5727ec681f3Smrg      }
5737ec681f3Smrg      if (tes->info.output_semantic_name[i] == TGSI_SEMANTIC_CLIPDIST) {
5747ec681f3Smrg         debug_assert(tes->info.output_semantic_index[i] <
5757ec681f3Smrg                      PIPE_MAX_CLIP_OR_CULL_DISTANCE_ELEMENT_COUNT);
5767ec681f3Smrg         tes->ccdistance_output[tes->info.output_semantic_index[i]] = i;
5777ec681f3Smrg      }
5787ec681f3Smrg   }
5797ec681f3Smrg   if (!found_clipvertex)
5807ec681f3Smrg      tes->clipvertex_output = tes->position_output;
5817ec681f3Smrg
5827ec681f3Smrg#ifdef DRAW_LLVM_AVAILABLE
5837ec681f3Smrg   if (use_llvm) {
5847ec681f3Smrg
5857ec681f3Smrg      tes->tes_input = align_malloc(sizeof(struct draw_tes_inputs), 16);
5867ec681f3Smrg      memset(tes->tes_input, 0, sizeof(struct draw_tes_inputs));
5877ec681f3Smrg
5887ec681f3Smrg      tes->jit_context = &draw->llvm->tes_jit_context;
5897ec681f3Smrg      llvm_tes->variant_key_size =
5907ec681f3Smrg         draw_tes_llvm_variant_key_size(
5917ec681f3Smrg                                        MAX2(tes->info.file_max[TGSI_FILE_SAMPLER]+1,
5927ec681f3Smrg                                             tes->info.file_max[TGSI_FILE_SAMPLER_VIEW]+1),
5937ec681f3Smrg                                        tes->info.file_max[TGSI_FILE_IMAGE]+1);
5947ec681f3Smrg   }
5957ec681f3Smrg#endif
5967ec681f3Smrg   return tes;
5977ec681f3Smrg}
5987ec681f3Smrg
5997ec681f3Smrgvoid draw_bind_tess_eval_shader(struct draw_context *draw,
6007ec681f3Smrg                                struct draw_tess_eval_shader *dtes)
6017ec681f3Smrg{
6027ec681f3Smrg   draw_do_flush(draw, DRAW_FLUSH_STATE_CHANGE);
6037ec681f3Smrg   if (dtes) {
6047ec681f3Smrg      draw->tes.tess_eval_shader = dtes;
6057ec681f3Smrg      draw->tes.position_output = dtes->position_output;
6067ec681f3Smrg      draw->tes.clipvertex_output = dtes->clipvertex_output;
6077ec681f3Smrg   } else {
6087ec681f3Smrg      draw->tes.tess_eval_shader = NULL;
6097ec681f3Smrg   }
6107ec681f3Smrg}
6117ec681f3Smrg
6127ec681f3Smrgvoid draw_delete_tess_eval_shader(struct draw_context *draw,
6137ec681f3Smrg                                  struct draw_tess_eval_shader *dtes)
6147ec681f3Smrg{
6157ec681f3Smrg   if (!dtes)
6167ec681f3Smrg      return;
6177ec681f3Smrg
6187ec681f3Smrg#ifdef DRAW_LLVM_AVAILABLE
6197ec681f3Smrg   if (draw->llvm) {
6207ec681f3Smrg      struct llvm_tess_eval_shader *shader = llvm_tess_eval_shader(dtes);
6217ec681f3Smrg      struct draw_tes_llvm_variant_list_item *li;
6227ec681f3Smrg
6237ec681f3Smrg      li = first_elem(&shader->variants);
6247ec681f3Smrg      while(!at_end(&shader->variants, li)) {
6257ec681f3Smrg         struct draw_tes_llvm_variant_list_item *next = next_elem(li);
6267ec681f3Smrg         draw_tes_llvm_destroy_variant(li->base);
6277ec681f3Smrg         li = next;
6287ec681f3Smrg      }
6297ec681f3Smrg
6307ec681f3Smrg      assert(shader->variants_cached == 0);
6317ec681f3Smrg      align_free(dtes->tes_input);
6327ec681f3Smrg   }
6337ec681f3Smrg#endif
6347ec681f3Smrg   if (dtes->state.ir.nir)
6357ec681f3Smrg      ralloc_free(dtes->state.ir.nir);
6367ec681f3Smrg   FREE(dtes);
6377ec681f3Smrg}
6387ec681f3Smrg
6397ec681f3Smrg#ifdef DRAW_LLVM_AVAILABLE
6407ec681f3Smrgvoid draw_tes_set_current_variant(struct draw_tess_eval_shader *shader,
6417ec681f3Smrg                                  struct draw_tes_llvm_variant *variant)
6427ec681f3Smrg{
6437ec681f3Smrg   shader->current_variant = variant;
6447ec681f3Smrg}
6457ec681f3Smrg#endif
6467ec681f3Smrg
6477ec681f3Smrgenum pipe_prim_type get_tes_output_prim(struct draw_tess_eval_shader *shader)
6487ec681f3Smrg{
6497ec681f3Smrg   if (shader->point_mode)
6507ec681f3Smrg      return PIPE_PRIM_POINTS;
6517ec681f3Smrg   else if (shader->prim_mode == PIPE_PRIM_LINES)
6527ec681f3Smrg      return PIPE_PRIM_LINES;
6537ec681f3Smrg   else
6547ec681f3Smrg      return PIPE_PRIM_TRIANGLES;
6557ec681f3Smrg}
656