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