xref: /aosp_15_r20/external/mesa3d/src/microsoft/compiler/dxil_signature.c (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1*61046927SAndroid Build Coastguard Worker /*
2*61046927SAndroid Build Coastguard Worker  * Copyright © Microsoft Corporation
3*61046927SAndroid Build Coastguard Worker  *
4*61046927SAndroid Build Coastguard Worker  * Permission is hereby granted, free of charge, to any person obtaining a
5*61046927SAndroid Build Coastguard Worker  * copy of this software and associated documentation files (the "Software"),
6*61046927SAndroid Build Coastguard Worker  * to deal in the Software without restriction, including without limitation
7*61046927SAndroid Build Coastguard Worker  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8*61046927SAndroid Build Coastguard Worker  * and/or sell copies of the Software, and to permit persons to whom the
9*61046927SAndroid Build Coastguard Worker  * Software is furnished to do so, subject to the following conditions:
10*61046927SAndroid Build Coastguard Worker  *
11*61046927SAndroid Build Coastguard Worker  * The above copyright notice and this permission notice (including the next
12*61046927SAndroid Build Coastguard Worker  * paragraph) shall be included in all copies or substantial portions of the
13*61046927SAndroid Build Coastguard Worker  * Software.
14*61046927SAndroid Build Coastguard Worker  *
15*61046927SAndroid Build Coastguard Worker  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16*61046927SAndroid Build Coastguard Worker  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17*61046927SAndroid Build Coastguard Worker  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18*61046927SAndroid Build Coastguard Worker  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19*61046927SAndroid Build Coastguard Worker  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20*61046927SAndroid Build Coastguard Worker  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21*61046927SAndroid Build Coastguard Worker  * IN THE SOFTWARE.
22*61046927SAndroid Build Coastguard Worker  */
23*61046927SAndroid Build Coastguard Worker 
24*61046927SAndroid Build Coastguard Worker #include "dxil_signature.h"
25*61046927SAndroid Build Coastguard Worker #include "dxil_enums.h"
26*61046927SAndroid Build Coastguard Worker #include "dxil_module.h"
27*61046927SAndroid Build Coastguard Worker 
28*61046927SAndroid Build Coastguard Worker #include "glsl_types.h"
29*61046927SAndroid Build Coastguard Worker #include "nir_to_dxil.h"
30*61046927SAndroid Build Coastguard Worker #include "util/u_debug.h"
31*61046927SAndroid Build Coastguard Worker 
32*61046927SAndroid Build Coastguard Worker #include <string.h>
33*61046927SAndroid Build Coastguard Worker 
34*61046927SAndroid Build Coastguard Worker 
35*61046927SAndroid Build Coastguard Worker struct semantic_info {
36*61046927SAndroid Build Coastguard Worker    enum dxil_semantic_kind kind;
37*61046927SAndroid Build Coastguard Worker    char name[64];
38*61046927SAndroid Build Coastguard Worker    int index;
39*61046927SAndroid Build Coastguard Worker    enum dxil_prog_sig_comp_type comp_type;
40*61046927SAndroid Build Coastguard Worker    uint8_t sig_comp_type;
41*61046927SAndroid Build Coastguard Worker    int32_t start_row;
42*61046927SAndroid Build Coastguard Worker    int32_t rows;
43*61046927SAndroid Build Coastguard Worker    uint8_t start_col;
44*61046927SAndroid Build Coastguard Worker    uint8_t cols;
45*61046927SAndroid Build Coastguard Worker    uint8_t interpolation;
46*61046927SAndroid Build Coastguard Worker    uint8_t stream;
47*61046927SAndroid Build Coastguard Worker    const char *sysvalue_name;
48*61046927SAndroid Build Coastguard Worker };
49*61046927SAndroid Build Coastguard Worker 
50*61046927SAndroid Build Coastguard Worker 
51*61046927SAndroid Build Coastguard Worker static bool
is_depth_output(enum dxil_semantic_kind kind)52*61046927SAndroid Build Coastguard Worker is_depth_output(enum dxil_semantic_kind kind)
53*61046927SAndroid Build Coastguard Worker {
54*61046927SAndroid Build Coastguard Worker    return kind == DXIL_SEM_DEPTH || kind == DXIL_SEM_DEPTH_GE ||
55*61046927SAndroid Build Coastguard Worker           kind == DXIL_SEM_DEPTH_LE || kind == DXIL_SEM_STENCIL_REF;
56*61046927SAndroid Build Coastguard Worker }
57*61046927SAndroid Build Coastguard Worker 
58*61046927SAndroid Build Coastguard Worker static uint8_t
get_interpolation(nir_variable * var)59*61046927SAndroid Build Coastguard Worker get_interpolation(nir_variable *var)
60*61046927SAndroid Build Coastguard Worker {
61*61046927SAndroid Build Coastguard Worker    if (var->data.patch)
62*61046927SAndroid Build Coastguard Worker       return DXIL_INTERP_UNDEFINED;
63*61046927SAndroid Build Coastguard Worker 
64*61046927SAndroid Build Coastguard Worker    if (glsl_type_is_integer(glsl_without_array_or_matrix(var->type)) ||
65*61046927SAndroid Build Coastguard Worker        glsl_type_is_64bit(glsl_without_array_or_matrix(var->type)))
66*61046927SAndroid Build Coastguard Worker       return DXIL_INTERP_CONSTANT;
67*61046927SAndroid Build Coastguard Worker 
68*61046927SAndroid Build Coastguard Worker    if (var->data.sample) {
69*61046927SAndroid Build Coastguard Worker       if (var->data.location == VARYING_SLOT_POS)
70*61046927SAndroid Build Coastguard Worker          return DXIL_INTERP_LINEAR_NOPERSPECTIVE_SAMPLE;
71*61046927SAndroid Build Coastguard Worker       switch (var->data.interpolation) {
72*61046927SAndroid Build Coastguard Worker       case INTERP_MODE_NONE: return DXIL_INTERP_LINEAR_SAMPLE;
73*61046927SAndroid Build Coastguard Worker       case INTERP_MODE_FLAT: return DXIL_INTERP_CONSTANT;
74*61046927SAndroid Build Coastguard Worker       case INTERP_MODE_NOPERSPECTIVE: return DXIL_INTERP_LINEAR_NOPERSPECTIVE_SAMPLE;
75*61046927SAndroid Build Coastguard Worker       case INTERP_MODE_SMOOTH: return DXIL_INTERP_LINEAR_SAMPLE;
76*61046927SAndroid Build Coastguard Worker       }
77*61046927SAndroid Build Coastguard Worker    } else if (unlikely(var->data.centroid)) {
78*61046927SAndroid Build Coastguard Worker       if (var->data.location == VARYING_SLOT_POS)
79*61046927SAndroid Build Coastguard Worker          return DXIL_INTERP_LINEAR_NOPERSPECTIVE_CENTROID;
80*61046927SAndroid Build Coastguard Worker       switch (var->data.interpolation) {
81*61046927SAndroid Build Coastguard Worker       case INTERP_MODE_NONE: return DXIL_INTERP_LINEAR_CENTROID;
82*61046927SAndroid Build Coastguard Worker       case INTERP_MODE_FLAT: return DXIL_INTERP_CONSTANT;
83*61046927SAndroid Build Coastguard Worker       case INTERP_MODE_NOPERSPECTIVE: return DXIL_INTERP_LINEAR_NOPERSPECTIVE_CENTROID;
84*61046927SAndroid Build Coastguard Worker       case INTERP_MODE_SMOOTH: return DXIL_INTERP_LINEAR_CENTROID;
85*61046927SAndroid Build Coastguard Worker       }
86*61046927SAndroid Build Coastguard Worker    } else {
87*61046927SAndroid Build Coastguard Worker       if (var->data.location == VARYING_SLOT_POS)
88*61046927SAndroid Build Coastguard Worker          return DXIL_INTERP_LINEAR_NOPERSPECTIVE;
89*61046927SAndroid Build Coastguard Worker       switch (var->data.interpolation) {
90*61046927SAndroid Build Coastguard Worker       case INTERP_MODE_NONE: return DXIL_INTERP_LINEAR;
91*61046927SAndroid Build Coastguard Worker       case INTERP_MODE_FLAT: return DXIL_INTERP_CONSTANT;
92*61046927SAndroid Build Coastguard Worker       case INTERP_MODE_NOPERSPECTIVE: return DXIL_INTERP_LINEAR_NOPERSPECTIVE;
93*61046927SAndroid Build Coastguard Worker       case INTERP_MODE_SMOOTH: return DXIL_INTERP_LINEAR;
94*61046927SAndroid Build Coastguard Worker       }
95*61046927SAndroid Build Coastguard Worker    }
96*61046927SAndroid Build Coastguard Worker 
97*61046927SAndroid Build Coastguard Worker    return DXIL_INTERP_LINEAR;
98*61046927SAndroid Build Coastguard Worker }
99*61046927SAndroid Build Coastguard Worker 
100*61046927SAndroid Build Coastguard Worker static const char *
in_sysvalue_name(nir_variable * var)101*61046927SAndroid Build Coastguard Worker in_sysvalue_name(nir_variable *var)
102*61046927SAndroid Build Coastguard Worker {
103*61046927SAndroid Build Coastguard Worker    switch (var->data.location) {
104*61046927SAndroid Build Coastguard Worker    case VARYING_SLOT_POS:
105*61046927SAndroid Build Coastguard Worker       return "POS";
106*61046927SAndroid Build Coastguard Worker    case VARYING_SLOT_FACE:
107*61046927SAndroid Build Coastguard Worker       return "FACE";
108*61046927SAndroid Build Coastguard Worker    case VARYING_SLOT_LAYER:
109*61046927SAndroid Build Coastguard Worker       return "RTINDEX";
110*61046927SAndroid Build Coastguard Worker    default:
111*61046927SAndroid Build Coastguard Worker       return "NONE";
112*61046927SAndroid Build Coastguard Worker    }
113*61046927SAndroid Build Coastguard Worker }
114*61046927SAndroid Build Coastguard Worker 
115*61046927SAndroid Build Coastguard Worker /*
116*61046927SAndroid Build Coastguard Worker  * The signatures are written into the stream in two pieces:
117*61046927SAndroid Build Coastguard Worker  * DxilProgramSignatureElement is a fixes size structure that gets dumped
118*61046927SAndroid Build Coastguard Worker  * to the stream in order of the registers and each contains an offset
119*61046927SAndroid Build Coastguard Worker  * to the semantic name string. Then these strings are dumped into the stream.
120*61046927SAndroid Build Coastguard Worker  */
121*61046927SAndroid Build Coastguard Worker static unsigned
get_additional_semantic_info(nir_shader * s,nir_variable * var,struct semantic_info * info,unsigned next_row,unsigned clip_size)122*61046927SAndroid Build Coastguard Worker get_additional_semantic_info(nir_shader *s, nir_variable *var, struct semantic_info *info,
123*61046927SAndroid Build Coastguard Worker                              unsigned next_row, unsigned clip_size)
124*61046927SAndroid Build Coastguard Worker {
125*61046927SAndroid Build Coastguard Worker    const struct glsl_type *type = var->type;
126*61046927SAndroid Build Coastguard Worker    if (nir_is_arrayed_io(var, s->info.stage))
127*61046927SAndroid Build Coastguard Worker       type = glsl_get_array_element(type);
128*61046927SAndroid Build Coastguard Worker 
129*61046927SAndroid Build Coastguard Worker    info->comp_type = dxil_get_prog_sig_comp_type(type);
130*61046927SAndroid Build Coastguard Worker    info->sig_comp_type = dxil_get_comp_type_from_prog_sig_type(info->comp_type);
131*61046927SAndroid Build Coastguard Worker 
132*61046927SAndroid Build Coastguard Worker    bool is_depth = is_depth_output(info->kind);
133*61046927SAndroid Build Coastguard Worker 
134*61046927SAndroid Build Coastguard Worker    bool is_gs_input = s->info.stage == MESA_SHADER_GEOMETRY &&
135*61046927SAndroid Build Coastguard Worker       (var->data.mode & (nir_var_shader_in | nir_var_system_value));
136*61046927SAndroid Build Coastguard Worker 
137*61046927SAndroid Build Coastguard Worker    info->stream = var->data.stream;
138*61046927SAndroid Build Coastguard Worker    info->rows = 1;
139*61046927SAndroid Build Coastguard Worker    if (info->kind == DXIL_SEM_TARGET) {
140*61046927SAndroid Build Coastguard Worker       info->start_row = info->index;
141*61046927SAndroid Build Coastguard Worker       info->cols = 4;
142*61046927SAndroid Build Coastguard Worker    } else if (is_depth ||
143*61046927SAndroid Build Coastguard Worker               (info->kind == DXIL_SEM_PRIMITIVE_ID && is_gs_input) ||
144*61046927SAndroid Build Coastguard Worker               info->kind == DXIL_SEM_COVERAGE ||
145*61046927SAndroid Build Coastguard Worker               info->kind == DXIL_SEM_SAMPLE_INDEX) {
146*61046927SAndroid Build Coastguard Worker       // This turns into a 'N/A' mask in the disassembly
147*61046927SAndroid Build Coastguard Worker       info->start_row = -1;
148*61046927SAndroid Build Coastguard Worker       info->cols = 1;
149*61046927SAndroid Build Coastguard Worker    } else if (info->kind == DXIL_SEM_TESS_FACTOR ||
150*61046927SAndroid Build Coastguard Worker               info->kind == DXIL_SEM_INSIDE_TESS_FACTOR) {
151*61046927SAndroid Build Coastguard Worker       assert(var->data.compact);
152*61046927SAndroid Build Coastguard Worker       info->start_row = next_row;
153*61046927SAndroid Build Coastguard Worker       info->rows = glsl_get_aoa_size(type);
154*61046927SAndroid Build Coastguard Worker       info->cols = 1;
155*61046927SAndroid Build Coastguard Worker       next_row += info->rows;
156*61046927SAndroid Build Coastguard Worker    } else if (var->data.compact) {
157*61046927SAndroid Build Coastguard Worker       info->start_row = next_row;
158*61046927SAndroid Build Coastguard Worker       next_row++;
159*61046927SAndroid Build Coastguard Worker 
160*61046927SAndroid Build Coastguard Worker       assert(glsl_type_is_array(type) && info->kind == DXIL_SEM_CLIP_DISTANCE);
161*61046927SAndroid Build Coastguard Worker       unsigned num_floats = glsl_get_aoa_size(type);
162*61046927SAndroid Build Coastguard Worker       unsigned start_offset = (var->data.location - VARYING_SLOT_CLIP_DIST0) * 4 +
163*61046927SAndroid Build Coastguard Worker          var->data.location_frac;
164*61046927SAndroid Build Coastguard Worker 
165*61046927SAndroid Build Coastguard Worker       if (start_offset >= clip_size) {
166*61046927SAndroid Build Coastguard Worker          info->kind = DXIL_SEM_CULL_DISTANCE;
167*61046927SAndroid Build Coastguard Worker          snprintf(info->name, 64, "SV_CullDistance");
168*61046927SAndroid Build Coastguard Worker       }
169*61046927SAndroid Build Coastguard Worker       info->cols = num_floats;
170*61046927SAndroid Build Coastguard Worker       info->start_col = (uint8_t)var->data.location_frac;
171*61046927SAndroid Build Coastguard Worker    } else {
172*61046927SAndroid Build Coastguard Worker       info->start_row = next_row;
173*61046927SAndroid Build Coastguard Worker       info->rows = glsl_count_vec4_slots(type, false, false);
174*61046927SAndroid Build Coastguard Worker       if (glsl_type_is_array(type))
175*61046927SAndroid Build Coastguard Worker          type = glsl_get_array_element(type);
176*61046927SAndroid Build Coastguard Worker       next_row += info->rows;
177*61046927SAndroid Build Coastguard Worker       info->start_col = (uint8_t)var->data.location_frac;
178*61046927SAndroid Build Coastguard Worker       info->cols = MIN2(glsl_get_component_slots(type), 4);
179*61046927SAndroid Build Coastguard Worker    }
180*61046927SAndroid Build Coastguard Worker 
181*61046927SAndroid Build Coastguard Worker    return next_row;
182*61046927SAndroid Build Coastguard Worker }
183*61046927SAndroid Build Coastguard Worker 
184*61046927SAndroid Build Coastguard Worker typedef void (*semantic_info_proc)(nir_variable *var, struct semantic_info *info, gl_shader_stage stage);
185*61046927SAndroid Build Coastguard Worker 
186*61046927SAndroid Build Coastguard Worker static void
get_semantic_vs_in_name(nir_variable * var,struct semantic_info * info,gl_shader_stage stage)187*61046927SAndroid Build Coastguard Worker get_semantic_vs_in_name(nir_variable *var, struct semantic_info *info, gl_shader_stage stage)
188*61046927SAndroid Build Coastguard Worker {
189*61046927SAndroid Build Coastguard Worker    strcpy(info->name, "TEXCOORD");
190*61046927SAndroid Build Coastguard Worker    info->index = var->data.driver_location;
191*61046927SAndroid Build Coastguard Worker    info->kind = DXIL_SEM_ARBITRARY;
192*61046927SAndroid Build Coastguard Worker }
193*61046927SAndroid Build Coastguard Worker 
194*61046927SAndroid Build Coastguard Worker static void
get_semantic_sv_name(nir_variable * var,struct semantic_info * info,gl_shader_stage stage)195*61046927SAndroid Build Coastguard Worker get_semantic_sv_name(nir_variable *var, struct semantic_info *info, gl_shader_stage stage)
196*61046927SAndroid Build Coastguard Worker {
197*61046927SAndroid Build Coastguard Worker    if (stage != MESA_SHADER_VERTEX)
198*61046927SAndroid Build Coastguard Worker       info->interpolation = get_interpolation(var);
199*61046927SAndroid Build Coastguard Worker 
200*61046927SAndroid Build Coastguard Worker    switch (var->data.location) {
201*61046927SAndroid Build Coastguard Worker    case SYSTEM_VALUE_VERTEX_ID_ZERO_BASE:
202*61046927SAndroid Build Coastguard Worker       info->kind = DXIL_SEM_VERTEX_ID;
203*61046927SAndroid Build Coastguard Worker       break;
204*61046927SAndroid Build Coastguard Worker    case SYSTEM_VALUE_INSTANCE_ID:
205*61046927SAndroid Build Coastguard Worker       info->kind = DXIL_SEM_INSTANCE_ID;
206*61046927SAndroid Build Coastguard Worker       break;
207*61046927SAndroid Build Coastguard Worker    case SYSTEM_VALUE_PRIMITIVE_ID:
208*61046927SAndroid Build Coastguard Worker       info->kind = DXIL_SEM_PRIMITIVE_ID;
209*61046927SAndroid Build Coastguard Worker       break;
210*61046927SAndroid Build Coastguard Worker    case SYSTEM_VALUE_SAMPLE_ID:
211*61046927SAndroid Build Coastguard Worker       info->kind = DXIL_SEM_SAMPLE_INDEX;
212*61046927SAndroid Build Coastguard Worker       break;
213*61046927SAndroid Build Coastguard Worker    default:
214*61046927SAndroid Build Coastguard Worker       unreachable("unsupported system value");
215*61046927SAndroid Build Coastguard Worker    }
216*61046927SAndroid Build Coastguard Worker    strncpy(info->name, var->name, ARRAY_SIZE(info->name) - 1);
217*61046927SAndroid Build Coastguard Worker }
218*61046927SAndroid Build Coastguard Worker 
219*61046927SAndroid Build Coastguard Worker static void
get_semantic_ps_outname(nir_variable * var,struct semantic_info * info)220*61046927SAndroid Build Coastguard Worker get_semantic_ps_outname(nir_variable *var, struct semantic_info *info)
221*61046927SAndroid Build Coastguard Worker {
222*61046927SAndroid Build Coastguard Worker    info->kind = DXIL_SEM_INVALID;
223*61046927SAndroid Build Coastguard Worker    switch (var->data.location) {
224*61046927SAndroid Build Coastguard Worker    case FRAG_RESULT_COLOR:
225*61046927SAndroid Build Coastguard Worker       snprintf(info->name, 64, "%s", "SV_Target");
226*61046927SAndroid Build Coastguard Worker       info->index = var->data.index;
227*61046927SAndroid Build Coastguard Worker       info->kind = DXIL_SEM_TARGET;
228*61046927SAndroid Build Coastguard Worker       break;
229*61046927SAndroid Build Coastguard Worker    case FRAG_RESULT_DATA0:
230*61046927SAndroid Build Coastguard Worker    case FRAG_RESULT_DATA1:
231*61046927SAndroid Build Coastguard Worker    case FRAG_RESULT_DATA2:
232*61046927SAndroid Build Coastguard Worker    case FRAG_RESULT_DATA3:
233*61046927SAndroid Build Coastguard Worker    case FRAG_RESULT_DATA4:
234*61046927SAndroid Build Coastguard Worker    case FRAG_RESULT_DATA5:
235*61046927SAndroid Build Coastguard Worker    case FRAG_RESULT_DATA6:
236*61046927SAndroid Build Coastguard Worker    case FRAG_RESULT_DATA7:
237*61046927SAndroid Build Coastguard Worker       snprintf(info->name, 64, "%s", "SV_Target");
238*61046927SAndroid Build Coastguard Worker       info->index = var->data.location - FRAG_RESULT_DATA0;
239*61046927SAndroid Build Coastguard Worker       if (var->data.location == FRAG_RESULT_DATA0 &&
240*61046927SAndroid Build Coastguard Worker           var->data.index > 0)
241*61046927SAndroid Build Coastguard Worker          info->index = var->data.index;
242*61046927SAndroid Build Coastguard Worker       info->kind = DXIL_SEM_TARGET;
243*61046927SAndroid Build Coastguard Worker       break;
244*61046927SAndroid Build Coastguard Worker    case FRAG_RESULT_DEPTH:
245*61046927SAndroid Build Coastguard Worker       snprintf(info->name, 64, "%s", "SV_Depth");
246*61046927SAndroid Build Coastguard Worker       info->kind = DXIL_SEM_DEPTH;
247*61046927SAndroid Build Coastguard Worker       break;
248*61046927SAndroid Build Coastguard Worker    case FRAG_RESULT_STENCIL:
249*61046927SAndroid Build Coastguard Worker       snprintf(info->name, 64, "%s", "SV_StencilRef");
250*61046927SAndroid Build Coastguard Worker       info->kind = DXIL_SEM_STENCIL_REF; //??
251*61046927SAndroid Build Coastguard Worker       break;
252*61046927SAndroid Build Coastguard Worker    case FRAG_RESULT_SAMPLE_MASK:
253*61046927SAndroid Build Coastguard Worker       snprintf(info->name, 64, "%s", "SV_Coverage");
254*61046927SAndroid Build Coastguard Worker       info->kind = DXIL_SEM_COVERAGE; //??
255*61046927SAndroid Build Coastguard Worker       break;
256*61046927SAndroid Build Coastguard Worker    default:
257*61046927SAndroid Build Coastguard Worker       snprintf(info->name, 64, "%s", "UNDEFINED");
258*61046927SAndroid Build Coastguard Worker       break;
259*61046927SAndroid Build Coastguard Worker    }
260*61046927SAndroid Build Coastguard Worker }
261*61046927SAndroid Build Coastguard Worker 
262*61046927SAndroid Build Coastguard Worker static void
get_semantic_name(nir_variable * var,struct semantic_info * info,const struct glsl_type * type)263*61046927SAndroid Build Coastguard Worker get_semantic_name(nir_variable *var, struct semantic_info *info,
264*61046927SAndroid Build Coastguard Worker                   const struct glsl_type *type)
265*61046927SAndroid Build Coastguard Worker {
266*61046927SAndroid Build Coastguard Worker    info->kind = DXIL_SEM_INVALID;
267*61046927SAndroid Build Coastguard Worker    info->interpolation = get_interpolation(var);
268*61046927SAndroid Build Coastguard Worker    switch (var->data.location) {
269*61046927SAndroid Build Coastguard Worker 
270*61046927SAndroid Build Coastguard Worker    case VARYING_SLOT_POS:
271*61046927SAndroid Build Coastguard Worker       assert(glsl_get_components(type) == 4);
272*61046927SAndroid Build Coastguard Worker       snprintf(info->name, 64, "%s", "SV_Position");
273*61046927SAndroid Build Coastguard Worker       info->kind = DXIL_SEM_POSITION;
274*61046927SAndroid Build Coastguard Worker       break;
275*61046927SAndroid Build Coastguard Worker 
276*61046927SAndroid Build Coastguard Worker     case VARYING_SLOT_FACE:
277*61046927SAndroid Build Coastguard Worker       assert(glsl_get_components(type) == 1);
278*61046927SAndroid Build Coastguard Worker       snprintf(info->name, 64, "%s", "SV_IsFrontFace");
279*61046927SAndroid Build Coastguard Worker       info->kind = DXIL_SEM_IS_FRONT_FACE;
280*61046927SAndroid Build Coastguard Worker       break;
281*61046927SAndroid Build Coastguard Worker 
282*61046927SAndroid Build Coastguard Worker    case VARYING_SLOT_PRIMITIVE_ID:
283*61046927SAndroid Build Coastguard Worker      assert(glsl_get_components(type) == 1);
284*61046927SAndroid Build Coastguard Worker      snprintf(info->name, 64, "%s", "SV_PrimitiveID");
285*61046927SAndroid Build Coastguard Worker      info->kind = DXIL_SEM_PRIMITIVE_ID;
286*61046927SAndroid Build Coastguard Worker      break;
287*61046927SAndroid Build Coastguard Worker 
288*61046927SAndroid Build Coastguard Worker    case VARYING_SLOT_CLIP_DIST1:
289*61046927SAndroid Build Coastguard Worker       info->index = 1;
290*61046927SAndroid Build Coastguard Worker       FALLTHROUGH;
291*61046927SAndroid Build Coastguard Worker    case VARYING_SLOT_CLIP_DIST0:
292*61046927SAndroid Build Coastguard Worker       assert(var->data.location == VARYING_SLOT_CLIP_DIST1 || info->index == 0);
293*61046927SAndroid Build Coastguard Worker       snprintf(info->name, 64, "%s", "SV_ClipDistance");
294*61046927SAndroid Build Coastguard Worker       info->kind = DXIL_SEM_CLIP_DISTANCE;
295*61046927SAndroid Build Coastguard Worker       break;
296*61046927SAndroid Build Coastguard Worker 
297*61046927SAndroid Build Coastguard Worker    case VARYING_SLOT_TESS_LEVEL_INNER:
298*61046927SAndroid Build Coastguard Worker       assert(glsl_get_components(type) <= 2);
299*61046927SAndroid Build Coastguard Worker       snprintf(info->name, 64, "%s", "SV_InsideTessFactor");
300*61046927SAndroid Build Coastguard Worker       info->kind = DXIL_SEM_INSIDE_TESS_FACTOR;
301*61046927SAndroid Build Coastguard Worker       break;
302*61046927SAndroid Build Coastguard Worker 
303*61046927SAndroid Build Coastguard Worker    case VARYING_SLOT_TESS_LEVEL_OUTER:
304*61046927SAndroid Build Coastguard Worker       assert(glsl_get_components(type) <= 4);
305*61046927SAndroid Build Coastguard Worker       snprintf(info->name, 64, "%s", "SV_TessFactor");
306*61046927SAndroid Build Coastguard Worker       info->kind = DXIL_SEM_TESS_FACTOR;
307*61046927SAndroid Build Coastguard Worker       break;
308*61046927SAndroid Build Coastguard Worker 
309*61046927SAndroid Build Coastguard Worker    case VARYING_SLOT_VIEWPORT:
310*61046927SAndroid Build Coastguard Worker       assert(glsl_get_components(type) == 1);
311*61046927SAndroid Build Coastguard Worker       snprintf(info->name, 64, "%s", "SV_ViewportArrayIndex");
312*61046927SAndroid Build Coastguard Worker       info->kind = DXIL_SEM_VIEWPORT_ARRAY_INDEX;
313*61046927SAndroid Build Coastguard Worker       break;
314*61046927SAndroid Build Coastguard Worker 
315*61046927SAndroid Build Coastguard Worker    case VARYING_SLOT_LAYER:
316*61046927SAndroid Build Coastguard Worker       assert(glsl_get_components(type) == 1);
317*61046927SAndroid Build Coastguard Worker       snprintf(info->name, 64, "%s", "SV_RenderTargetArrayIndex");
318*61046927SAndroid Build Coastguard Worker       info->kind = DXIL_SEM_RENDERTARGET_ARRAY_INDEX;
319*61046927SAndroid Build Coastguard Worker       break;
320*61046927SAndroid Build Coastguard Worker 
321*61046927SAndroid Build Coastguard Worker    default: {
322*61046927SAndroid Build Coastguard Worker          info->index = var->data.driver_location;
323*61046927SAndroid Build Coastguard Worker          strcpy(info->name, "TEXCOORD");
324*61046927SAndroid Build Coastguard Worker          info->kind = DXIL_SEM_ARBITRARY;
325*61046927SAndroid Build Coastguard Worker       }
326*61046927SAndroid Build Coastguard Worker    }
327*61046927SAndroid Build Coastguard Worker }
328*61046927SAndroid Build Coastguard Worker 
329*61046927SAndroid Build Coastguard Worker static void
get_semantic_in_name(nir_variable * var,struct semantic_info * info,gl_shader_stage stage)330*61046927SAndroid Build Coastguard Worker get_semantic_in_name(nir_variable *var, struct semantic_info *info, gl_shader_stage stage)
331*61046927SAndroid Build Coastguard Worker {
332*61046927SAndroid Build Coastguard Worker    const struct glsl_type *type = var->type;
333*61046927SAndroid Build Coastguard Worker    if (nir_is_arrayed_io(var, stage) &&
334*61046927SAndroid Build Coastguard Worker        glsl_type_is_array(type))
335*61046927SAndroid Build Coastguard Worker       type = glsl_get_array_element(type);
336*61046927SAndroid Build Coastguard Worker 
337*61046927SAndroid Build Coastguard Worker    get_semantic_name(var, info, type);
338*61046927SAndroid Build Coastguard Worker    info->sysvalue_name = in_sysvalue_name(var);
339*61046927SAndroid Build Coastguard Worker }
340*61046927SAndroid Build Coastguard Worker 
341*61046927SAndroid Build Coastguard Worker 
342*61046927SAndroid Build Coastguard Worker static enum dxil_prog_sig_semantic
prog_semantic_from_kind(enum dxil_semantic_kind kind,unsigned num_vals,unsigned start_val)343*61046927SAndroid Build Coastguard Worker prog_semantic_from_kind(enum dxil_semantic_kind kind, unsigned num_vals, unsigned start_val)
344*61046927SAndroid Build Coastguard Worker {
345*61046927SAndroid Build Coastguard Worker    switch (kind) {
346*61046927SAndroid Build Coastguard Worker    case DXIL_SEM_ARBITRARY: return DXIL_PROG_SEM_UNDEFINED;
347*61046927SAndroid Build Coastguard Worker    case DXIL_SEM_VERTEX_ID: return DXIL_PROG_SEM_VERTEX_ID;
348*61046927SAndroid Build Coastguard Worker    case DXIL_SEM_INSTANCE_ID: return DXIL_PROG_SEM_INSTANCE_ID;
349*61046927SAndroid Build Coastguard Worker    case DXIL_SEM_POSITION: return DXIL_PROG_SEM_POSITION;
350*61046927SAndroid Build Coastguard Worker    case DXIL_SEM_COVERAGE: return DXIL_PROG_SEM_COVERAGE;
351*61046927SAndroid Build Coastguard Worker    case DXIL_SEM_INNER_COVERAGE: return DXIL_PROG_SEM_INNER_COVERAGE;
352*61046927SAndroid Build Coastguard Worker    case DXIL_SEM_PRIMITIVE_ID: return DXIL_PROG_SEM_PRIMITIVE_ID;
353*61046927SAndroid Build Coastguard Worker    case DXIL_SEM_SAMPLE_INDEX: return DXIL_PROG_SEM_SAMPLE_INDEX;
354*61046927SAndroid Build Coastguard Worker    case DXIL_SEM_IS_FRONT_FACE: return DXIL_PROG_SEM_IS_FRONTFACE;
355*61046927SAndroid Build Coastguard Worker    case DXIL_SEM_RENDERTARGET_ARRAY_INDEX: return DXIL_PROG_SEM_RENDERTARGET_ARRAY_INDEX;
356*61046927SAndroid Build Coastguard Worker    case DXIL_SEM_VIEWPORT_ARRAY_INDEX: return DXIL_PROG_SEM_VIEWPORT_ARRAY_INDEX;
357*61046927SAndroid Build Coastguard Worker    case DXIL_SEM_CLIP_DISTANCE: return DXIL_PROG_SEM_CLIP_DISTANCE;
358*61046927SAndroid Build Coastguard Worker    case DXIL_SEM_CULL_DISTANCE: return DXIL_PROG_SEM_CULL_DISTANCE;
359*61046927SAndroid Build Coastguard Worker    case DXIL_SEM_BARYCENTRICS: return DXIL_PROG_SEM_BARYCENTRICS;
360*61046927SAndroid Build Coastguard Worker    case DXIL_SEM_SHADING_RATE: return DXIL_PROG_SEM_SHADING_RATE;
361*61046927SAndroid Build Coastguard Worker    case DXIL_SEM_CULL_PRIMITIVE: return DXIL_PROG_SEM_CULL_PRIMITIVE;
362*61046927SAndroid Build Coastguard Worker    case DXIL_SEM_TARGET: return DXIL_PROG_SEM_TARGET;
363*61046927SAndroid Build Coastguard Worker    case DXIL_SEM_DEPTH: return DXIL_PROG_SEM_DEPTH;
364*61046927SAndroid Build Coastguard Worker    case DXIL_SEM_DEPTH_LE: return DXIL_PROG_SEM_DEPTH_LE;
365*61046927SAndroid Build Coastguard Worker    case DXIL_SEM_DEPTH_GE: return DXIL_PROG_SEM_DEPTH_GE;
366*61046927SAndroid Build Coastguard Worker    case DXIL_SEM_STENCIL_REF: return DXIL_PROG_SEM_STENCIL_REF;
367*61046927SAndroid Build Coastguard Worker    case DXIL_SEM_TESS_FACTOR:
368*61046927SAndroid Build Coastguard Worker       switch (num_vals) {
369*61046927SAndroid Build Coastguard Worker       case 4: return DXIL_PROG_SEM_FINAL_QUAD_EDGE_TESSFACTOR;
370*61046927SAndroid Build Coastguard Worker       case 3: return DXIL_PROG_SEM_FINAL_TRI_EDGE_TESSFACTOR;
371*61046927SAndroid Build Coastguard Worker       case 2: return start_val == 0 ?
372*61046927SAndroid Build Coastguard Worker          DXIL_PROG_SEM_FINAL_LINE_DENSITY_TESSFACTOR :
373*61046927SAndroid Build Coastguard Worker          DXIL_PROG_SEM_FINAL_LINE_DETAIL_TESSFACTOR;
374*61046927SAndroid Build Coastguard Worker       default:
375*61046927SAndroid Build Coastguard Worker          unreachable("Invalid row count for tess factor");
376*61046927SAndroid Build Coastguard Worker       }
377*61046927SAndroid Build Coastguard Worker    case DXIL_SEM_INSIDE_TESS_FACTOR:
378*61046927SAndroid Build Coastguard Worker       switch (num_vals) {
379*61046927SAndroid Build Coastguard Worker       case 2: return DXIL_PROG_SEM_FINAL_QUAD_INSIDE_EDGE_TESSFACTOR;
380*61046927SAndroid Build Coastguard Worker       case 1: return DXIL_PROG_SEM_FINAL_TRI_INSIDE_EDGE_TESSFACTOR;
381*61046927SAndroid Build Coastguard Worker       default:
382*61046927SAndroid Build Coastguard Worker          unreachable("Invalid row count for inner tess factor");
383*61046927SAndroid Build Coastguard Worker       }
384*61046927SAndroid Build Coastguard Worker    default:
385*61046927SAndroid Build Coastguard Worker        return DXIL_PROG_SEM_UNDEFINED;
386*61046927SAndroid Build Coastguard Worker    }
387*61046927SAndroid Build Coastguard Worker }
388*61046927SAndroid Build Coastguard Worker 
389*61046927SAndroid Build Coastguard Worker static
390*61046927SAndroid Build Coastguard Worker uint32_t
copy_semantic_name_to_string(struct _mesa_string_buffer * string_out,const char * name)391*61046927SAndroid Build Coastguard Worker copy_semantic_name_to_string(struct _mesa_string_buffer *string_out, const char *name)
392*61046927SAndroid Build Coastguard Worker {
393*61046927SAndroid Build Coastguard Worker    /*  copy the semantic name */
394*61046927SAndroid Build Coastguard Worker    uint32_t retval = string_out->length;
395*61046927SAndroid Build Coastguard Worker    size_t name_len = strlen(name) + 1;
396*61046927SAndroid Build Coastguard Worker    _mesa_string_buffer_append_len(string_out, name, name_len);
397*61046927SAndroid Build Coastguard Worker    return retval;
398*61046927SAndroid Build Coastguard Worker }
399*61046927SAndroid Build Coastguard Worker 
400*61046927SAndroid Build Coastguard Worker static
401*61046927SAndroid Build Coastguard Worker uint32_t
append_semantic_index_to_table(struct dxil_psv_sem_index_table * table,uint32_t index,uint32_t num_rows)402*61046927SAndroid Build Coastguard Worker append_semantic_index_to_table(struct dxil_psv_sem_index_table *table, uint32_t index,
403*61046927SAndroid Build Coastguard Worker                                uint32_t num_rows)
404*61046927SAndroid Build Coastguard Worker {
405*61046927SAndroid Build Coastguard Worker    for (unsigned i = 0; i < table->size; ++i) {
406*61046927SAndroid Build Coastguard Worker       unsigned j = 0;
407*61046927SAndroid Build Coastguard Worker       for (; j < num_rows && i + j < table->size; ++j)
408*61046927SAndroid Build Coastguard Worker          if (table->data[i + j] != index + j)
409*61046927SAndroid Build Coastguard Worker             break;
410*61046927SAndroid Build Coastguard Worker       if (j == num_rows)
411*61046927SAndroid Build Coastguard Worker          return i;
412*61046927SAndroid Build Coastguard Worker       else if (j > 0)
413*61046927SAndroid Build Coastguard Worker          i += j - 1;
414*61046927SAndroid Build Coastguard Worker    }
415*61046927SAndroid Build Coastguard Worker    uint32_t retval = table->size;
416*61046927SAndroid Build Coastguard Worker    assert(table->size + num_rows <= ARRAY_SIZE(table->data));
417*61046927SAndroid Build Coastguard Worker    for (unsigned i = 0; i < num_rows; ++i)
418*61046927SAndroid Build Coastguard Worker       table->data[table->size++] = index + i;
419*61046927SAndroid Build Coastguard Worker    return retval;
420*61046927SAndroid Build Coastguard Worker }
421*61046927SAndroid Build Coastguard Worker 
422*61046927SAndroid Build Coastguard Worker static const struct dxil_mdnode *
fill_SV_param_nodes(struct dxil_module * mod,unsigned record_id,const struct dxil_signature_record * rec,const struct dxil_psv_signature_element * psv,bool is_input)423*61046927SAndroid Build Coastguard Worker fill_SV_param_nodes(struct dxil_module *mod, unsigned record_id,
424*61046927SAndroid Build Coastguard Worker                     const struct dxil_signature_record *rec,
425*61046927SAndroid Build Coastguard Worker                     const struct dxil_psv_signature_element *psv,
426*61046927SAndroid Build Coastguard Worker                     bool is_input) {
427*61046927SAndroid Build Coastguard Worker 
428*61046927SAndroid Build Coastguard Worker    const struct dxil_mdnode *SV_params_nodes[11];
429*61046927SAndroid Build Coastguard Worker    /* For this to always work we should use vectorize_io, but for FS out and VS in
430*61046927SAndroid Build Coastguard Worker     * this is not implemented globally */
431*61046927SAndroid Build Coastguard Worker    const struct dxil_mdnode *flattened_semantics[256];
432*61046927SAndroid Build Coastguard Worker 
433*61046927SAndroid Build Coastguard Worker    for (unsigned i = 0; i < rec->num_elements; ++i)
434*61046927SAndroid Build Coastguard Worker       flattened_semantics[i] = dxil_get_metadata_int32(mod, rec->elements[i].semantic_index);
435*61046927SAndroid Build Coastguard Worker 
436*61046927SAndroid Build Coastguard Worker    SV_params_nodes[0] = dxil_get_metadata_int32(mod, (int)record_id); // Unique element ID
437*61046927SAndroid Build Coastguard Worker    SV_params_nodes[1] = dxil_get_metadata_string(mod, rec->name); // Element name
438*61046927SAndroid Build Coastguard Worker    SV_params_nodes[2] = dxil_get_metadata_int8(mod, rec->sig_comp_type); // Element type
439*61046927SAndroid Build Coastguard Worker    SV_params_nodes[3] = dxil_get_metadata_int8(mod, (int8_t)psv->semantic_kind); // Effective system value
440*61046927SAndroid Build Coastguard Worker    SV_params_nodes[4] = dxil_get_metadata_node(mod, flattened_semantics,
441*61046927SAndroid Build Coastguard Worker                                                rec->num_elements); // Semantic index vector
442*61046927SAndroid Build Coastguard Worker    SV_params_nodes[5] = dxil_get_metadata_int8(mod, psv->interpolation_mode); // Interpolation mode
443*61046927SAndroid Build Coastguard Worker    SV_params_nodes[6] = dxil_get_metadata_int32(mod, psv->rows); // Number of rows
444*61046927SAndroid Build Coastguard Worker    SV_params_nodes[7] = dxil_get_metadata_int8(mod, psv->cols_and_start & 0xf); // Number of columns
445*61046927SAndroid Build Coastguard Worker    SV_params_nodes[8] = dxil_get_metadata_int32(mod, rec->elements[0].reg); // Element packing start row
446*61046927SAndroid Build Coastguard Worker    SV_params_nodes[9] = dxil_get_metadata_int8(mod, (psv->cols_and_start >> 4) & 0x3); // Element packing start column
447*61046927SAndroid Build Coastguard Worker 
448*61046927SAndroid Build Coastguard Worker    const struct dxil_mdnode *SV_metadata[6];
449*61046927SAndroid Build Coastguard Worker    unsigned num_metadata_nodes = 0;
450*61046927SAndroid Build Coastguard Worker    if (rec->elements[0].stream != 0) {
451*61046927SAndroid Build Coastguard Worker       SV_metadata[num_metadata_nodes++] = dxil_get_metadata_int32(mod, DXIL_SIGNATURE_ELEMENT_OUTPUT_STREAM);
452*61046927SAndroid Build Coastguard Worker       SV_metadata[num_metadata_nodes++] = dxil_get_metadata_int32(mod, rec->elements[0].stream);
453*61046927SAndroid Build Coastguard Worker    }
454*61046927SAndroid Build Coastguard Worker    uint8_t usage_mask = rec->elements[0].always_reads_mask;
455*61046927SAndroid Build Coastguard Worker    if (!is_input)
456*61046927SAndroid Build Coastguard Worker       usage_mask = 0xf & ~rec->elements[0].never_writes_mask;
457*61046927SAndroid Build Coastguard Worker    if (usage_mask && mod->minor_validator >= 5) {
458*61046927SAndroid Build Coastguard Worker       usage_mask >>= (psv->cols_and_start >> 4) & 0x3;
459*61046927SAndroid Build Coastguard Worker       SV_metadata[num_metadata_nodes++] = dxil_get_metadata_int32(mod, DXIL_SIGNATURE_ELEMENT_USAGE_COMPONENT_MASK);
460*61046927SAndroid Build Coastguard Worker       SV_metadata[num_metadata_nodes++] = dxil_get_metadata_int8(mod, usage_mask);
461*61046927SAndroid Build Coastguard Worker    }
462*61046927SAndroid Build Coastguard Worker 
463*61046927SAndroid Build Coastguard Worker    uint8_t dynamic_index_mask = psv->dynamic_mask_and_stream & 0xf;
464*61046927SAndroid Build Coastguard Worker    if (dynamic_index_mask) {
465*61046927SAndroid Build Coastguard Worker       SV_metadata[num_metadata_nodes++] = dxil_get_metadata_int32(mod, DXIL_SIGNATURE_ELEMENT_DYNAMIC_INDEX_COMPONENT_MASK);
466*61046927SAndroid Build Coastguard Worker       SV_metadata[num_metadata_nodes++] = dxil_get_metadata_int8(mod, dynamic_index_mask);
467*61046927SAndroid Build Coastguard Worker    }
468*61046927SAndroid Build Coastguard Worker 
469*61046927SAndroid Build Coastguard Worker    SV_params_nodes[10] = num_metadata_nodes ? dxil_get_metadata_node(mod, SV_metadata, num_metadata_nodes) : NULL;
470*61046927SAndroid Build Coastguard Worker 
471*61046927SAndroid Build Coastguard Worker    return dxil_get_metadata_node(mod, SV_params_nodes, ARRAY_SIZE(SV_params_nodes));
472*61046927SAndroid Build Coastguard Worker }
473*61046927SAndroid Build Coastguard Worker 
474*61046927SAndroid Build Coastguard Worker static void
fill_signature_element(struct dxil_signature_element * elm,struct semantic_info * semantic,unsigned row)475*61046927SAndroid Build Coastguard Worker fill_signature_element(struct dxil_signature_element *elm,
476*61046927SAndroid Build Coastguard Worker                        struct semantic_info *semantic,
477*61046927SAndroid Build Coastguard Worker                        unsigned row)
478*61046927SAndroid Build Coastguard Worker {
479*61046927SAndroid Build Coastguard Worker    memset(elm, 0, sizeof(struct dxil_signature_element));
480*61046927SAndroid Build Coastguard Worker    elm->stream = semantic->stream;
481*61046927SAndroid Build Coastguard Worker    // elm->semantic_name_offset = 0;  // Offset needs to be filled out when writing
482*61046927SAndroid Build Coastguard Worker    elm->semantic_index = semantic->index + row;
483*61046927SAndroid Build Coastguard Worker    elm->system_value = (uint32_t) prog_semantic_from_kind(semantic->kind, semantic->rows, row);
484*61046927SAndroid Build Coastguard Worker    elm->comp_type = (uint32_t) semantic->comp_type;
485*61046927SAndroid Build Coastguard Worker    elm->reg = semantic->start_row + row;
486*61046927SAndroid Build Coastguard Worker 
487*61046927SAndroid Build Coastguard Worker    assert(semantic->cols + semantic->start_col <= 4);
488*61046927SAndroid Build Coastguard Worker    elm->mask = (uint8_t) (((1 << semantic->cols) - 1) << semantic->start_col);
489*61046927SAndroid Build Coastguard Worker    elm->min_precision = DXIL_MIN_PREC_DEFAULT;
490*61046927SAndroid Build Coastguard Worker }
491*61046927SAndroid Build Coastguard Worker 
492*61046927SAndroid Build Coastguard Worker static bool
fill_psv_signature_element(struct dxil_psv_signature_element * psv_elm,struct semantic_info * semantic,struct dxil_module * mod)493*61046927SAndroid Build Coastguard Worker fill_psv_signature_element(struct dxil_psv_signature_element *psv_elm,
494*61046927SAndroid Build Coastguard Worker                            struct semantic_info *semantic, struct dxil_module *mod)
495*61046927SAndroid Build Coastguard Worker {
496*61046927SAndroid Build Coastguard Worker    memset(psv_elm, 0, sizeof(struct dxil_psv_signature_element));
497*61046927SAndroid Build Coastguard Worker    psv_elm->rows = semantic->rows;
498*61046927SAndroid Build Coastguard Worker    if (semantic->start_row >= 0) {
499*61046927SAndroid Build Coastguard Worker       assert(semantic->start_row < 256);
500*61046927SAndroid Build Coastguard Worker       psv_elm->start_row = semantic->start_row;
501*61046927SAndroid Build Coastguard Worker       psv_elm->cols_and_start = (1u << 6) | (semantic->start_col << 4) | semantic->cols;
502*61046927SAndroid Build Coastguard Worker    } else {
503*61046927SAndroid Build Coastguard Worker       /* The validation expects that the the start row is not egative
504*61046927SAndroid Build Coastguard Worker        * and apparently the extra bit in the cols_and_start indicates that the
505*61046927SAndroid Build Coastguard Worker        * row is meant literally, so don't set it in this case.
506*61046927SAndroid Build Coastguard Worker        * (Source of information: Comparing with the validation structures
507*61046927SAndroid Build Coastguard Worker        * created by dxcompiler)
508*61046927SAndroid Build Coastguard Worker        */
509*61046927SAndroid Build Coastguard Worker       psv_elm->start_row = 0;
510*61046927SAndroid Build Coastguard Worker       psv_elm->cols_and_start = (semantic->start_col << 4) | semantic->cols;
511*61046927SAndroid Build Coastguard Worker    }
512*61046927SAndroid Build Coastguard Worker    psv_elm->semantic_kind = (uint8_t)semantic->kind;
513*61046927SAndroid Build Coastguard Worker    psv_elm->component_type = semantic->comp_type;
514*61046927SAndroid Build Coastguard Worker    psv_elm->interpolation_mode = semantic->interpolation;
515*61046927SAndroid Build Coastguard Worker    psv_elm->dynamic_mask_and_stream = (semantic->stream) << 4;
516*61046927SAndroid Build Coastguard Worker    if (semantic->kind == DXIL_SEM_ARBITRARY && strlen(semantic->name)) {
517*61046927SAndroid Build Coastguard Worker       psv_elm->semantic_name_offset =
518*61046927SAndroid Build Coastguard Worker             copy_semantic_name_to_string(mod->sem_string_table, semantic->name);
519*61046927SAndroid Build Coastguard Worker 
520*61046927SAndroid Build Coastguard Worker       /* TODO: clean up memory */
521*61046927SAndroid Build Coastguard Worker       if (psv_elm->semantic_name_offset == (uint32_t)-1)
522*61046927SAndroid Build Coastguard Worker          return false;
523*61046927SAndroid Build Coastguard Worker    }
524*61046927SAndroid Build Coastguard Worker 
525*61046927SAndroid Build Coastguard Worker    psv_elm->semantic_indexes_offset =
526*61046927SAndroid Build Coastguard Worker          append_semantic_index_to_table(&mod->sem_index_table, semantic->index, semantic->rows);
527*61046927SAndroid Build Coastguard Worker 
528*61046927SAndroid Build Coastguard Worker    return true;
529*61046927SAndroid Build Coastguard Worker }
530*61046927SAndroid Build Coastguard Worker 
531*61046927SAndroid Build Coastguard Worker static bool
fill_io_signature(struct dxil_module * mod,int id,struct semantic_info * semantic,struct dxil_signature_record * rec,struct dxil_psv_signature_element * psv_elm)532*61046927SAndroid Build Coastguard Worker fill_io_signature(struct dxil_module *mod, int id,
533*61046927SAndroid Build Coastguard Worker                   struct semantic_info *semantic,
534*61046927SAndroid Build Coastguard Worker                   struct dxil_signature_record *rec,
535*61046927SAndroid Build Coastguard Worker                   struct dxil_psv_signature_element *psv_elm)
536*61046927SAndroid Build Coastguard Worker {
537*61046927SAndroid Build Coastguard Worker    rec->name = ralloc_strdup(mod->ralloc_ctx, semantic->name);
538*61046927SAndroid Build Coastguard Worker    rec->num_elements = semantic->rows;
539*61046927SAndroid Build Coastguard Worker    rec->sig_comp_type = semantic->sig_comp_type;
540*61046927SAndroid Build Coastguard Worker 
541*61046927SAndroid Build Coastguard Worker    for (unsigned i = 0; i < semantic->rows; ++i)
542*61046927SAndroid Build Coastguard Worker       fill_signature_element(&rec->elements[i], semantic, i);
543*61046927SAndroid Build Coastguard Worker    return fill_psv_signature_element(psv_elm, semantic, mod);
544*61046927SAndroid Build Coastguard Worker }
545*61046927SAndroid Build Coastguard Worker 
546*61046927SAndroid Build Coastguard Worker static unsigned
get_input_signature_group(struct dxil_module * mod,unsigned num_inputs,nir_shader * s,nir_variable_mode modes,semantic_info_proc get_semantics,unsigned * row_iter,unsigned input_clip_size)547*61046927SAndroid Build Coastguard Worker get_input_signature_group(struct dxil_module *mod,
548*61046927SAndroid Build Coastguard Worker                           unsigned num_inputs,
549*61046927SAndroid Build Coastguard Worker                           nir_shader *s, nir_variable_mode modes,
550*61046927SAndroid Build Coastguard Worker                           semantic_info_proc get_semantics, unsigned *row_iter,
551*61046927SAndroid Build Coastguard Worker                           unsigned input_clip_size)
552*61046927SAndroid Build Coastguard Worker {
553*61046927SAndroid Build Coastguard Worker    nir_foreach_variable_with_modes(var, s, modes) {
554*61046927SAndroid Build Coastguard Worker       if (var->data.patch)
555*61046927SAndroid Build Coastguard Worker          continue;
556*61046927SAndroid Build Coastguard Worker 
557*61046927SAndroid Build Coastguard Worker       struct semantic_info semantic = {0};
558*61046927SAndroid Build Coastguard Worker       get_semantics(var, &semantic, s->info.stage);
559*61046927SAndroid Build Coastguard Worker       mod->inputs[num_inputs].sysvalue = semantic.sysvalue_name;
560*61046927SAndroid Build Coastguard Worker       nir_variable *base_var = var;
561*61046927SAndroid Build Coastguard Worker       if (var->data.location_frac) {
562*61046927SAndroid Build Coastguard Worker          /* Note: Specifically search for a variable that has space for these additional components */
563*61046927SAndroid Build Coastguard Worker          nir_foreach_variable_with_modes(test_var, s, modes) {
564*61046927SAndroid Build Coastguard Worker             if (var->data.location == test_var->data.location) {
565*61046927SAndroid Build Coastguard Worker                /* Variables should be sorted such that we're only looking for an already-emitted variable */
566*61046927SAndroid Build Coastguard Worker                if (test_var == var)
567*61046927SAndroid Build Coastguard Worker                   break;
568*61046927SAndroid Build Coastguard Worker                base_var = test_var;
569*61046927SAndroid Build Coastguard Worker                if (test_var->data.location_frac == 0 &&
570*61046927SAndroid Build Coastguard Worker                    glsl_get_component_slots(
571*61046927SAndroid Build Coastguard Worker                       nir_is_arrayed_io(test_var, s->info.stage) ?
572*61046927SAndroid Build Coastguard Worker                       glsl_get_array_element(test_var->type) : test_var->type) <= var->data.location_frac)
573*61046927SAndroid Build Coastguard Worker                   break;
574*61046927SAndroid Build Coastguard Worker             }
575*61046927SAndroid Build Coastguard Worker          }
576*61046927SAndroid Build Coastguard Worker       }
577*61046927SAndroid Build Coastguard Worker       if (base_var != var)
578*61046927SAndroid Build Coastguard Worker          /* Combine fractional vars into any already existing row */
579*61046927SAndroid Build Coastguard Worker          get_additional_semantic_info(s, var, &semantic,
580*61046927SAndroid Build Coastguard Worker                                       mod->psv_inputs[mod->input_mappings[base_var->data.driver_location]].start_row,
581*61046927SAndroid Build Coastguard Worker                                       input_clip_size);
582*61046927SAndroid Build Coastguard Worker       else
583*61046927SAndroid Build Coastguard Worker          *row_iter = get_additional_semantic_info(s, var, &semantic, *row_iter, input_clip_size);
584*61046927SAndroid Build Coastguard Worker 
585*61046927SAndroid Build Coastguard Worker       mod->input_mappings[var->data.driver_location] = num_inputs;
586*61046927SAndroid Build Coastguard Worker       struct dxil_psv_signature_element *psv_elm = &mod->psv_inputs[num_inputs];
587*61046927SAndroid Build Coastguard Worker 
588*61046927SAndroid Build Coastguard Worker       if (!fill_io_signature(mod, num_inputs, &semantic,
589*61046927SAndroid Build Coastguard Worker                              &mod->inputs[num_inputs], psv_elm))
590*61046927SAndroid Build Coastguard Worker          return 0;
591*61046927SAndroid Build Coastguard Worker 
592*61046927SAndroid Build Coastguard Worker       mod->num_psv_inputs = MAX2(mod->num_psv_inputs,
593*61046927SAndroid Build Coastguard Worker                                  semantic.start_row + semantic.rows);
594*61046927SAndroid Build Coastguard Worker 
595*61046927SAndroid Build Coastguard Worker       ++num_inputs;
596*61046927SAndroid Build Coastguard Worker       assert(num_inputs < VARYING_SLOT_MAX * 4);
597*61046927SAndroid Build Coastguard Worker    }
598*61046927SAndroid Build Coastguard Worker    return num_inputs;
599*61046927SAndroid Build Coastguard Worker }
600*61046927SAndroid Build Coastguard Worker 
601*61046927SAndroid Build Coastguard Worker static void
process_input_signature(struct dxil_module * mod,nir_shader * s,unsigned input_clip_size)602*61046927SAndroid Build Coastguard Worker process_input_signature(struct dxil_module *mod, nir_shader *s, unsigned input_clip_size)
603*61046927SAndroid Build Coastguard Worker {
604*61046927SAndroid Build Coastguard Worker    if (s->info.stage == MESA_SHADER_KERNEL)
605*61046927SAndroid Build Coastguard Worker       return;
606*61046927SAndroid Build Coastguard Worker    unsigned next_row = 0;
607*61046927SAndroid Build Coastguard Worker 
608*61046927SAndroid Build Coastguard Worker    mod->num_sig_inputs = get_input_signature_group(mod, 0,
609*61046927SAndroid Build Coastguard Worker                                                    s, nir_var_shader_in,
610*61046927SAndroid Build Coastguard Worker                                                    s->info.stage == MESA_SHADER_VERTEX ?
611*61046927SAndroid Build Coastguard Worker                                                       get_semantic_vs_in_name : get_semantic_in_name,
612*61046927SAndroid Build Coastguard Worker                                                    &next_row, input_clip_size);
613*61046927SAndroid Build Coastguard Worker 
614*61046927SAndroid Build Coastguard Worker    mod->num_sig_inputs = get_input_signature_group(mod, mod->num_sig_inputs,
615*61046927SAndroid Build Coastguard Worker                                                    s, nir_var_system_value,
616*61046927SAndroid Build Coastguard Worker                                                    get_semantic_sv_name,
617*61046927SAndroid Build Coastguard Worker                                                    &next_row, input_clip_size);
618*61046927SAndroid Build Coastguard Worker 
619*61046927SAndroid Build Coastguard Worker }
620*61046927SAndroid Build Coastguard Worker 
out_sysvalue_name(nir_variable * var)621*61046927SAndroid Build Coastguard Worker static const char *out_sysvalue_name(nir_variable *var)
622*61046927SAndroid Build Coastguard Worker {
623*61046927SAndroid Build Coastguard Worker    switch (var->data.location) {
624*61046927SAndroid Build Coastguard Worker    case VARYING_SLOT_FACE:
625*61046927SAndroid Build Coastguard Worker       return "FACE";
626*61046927SAndroid Build Coastguard Worker    case VARYING_SLOT_POS:
627*61046927SAndroid Build Coastguard Worker       return "POS";
628*61046927SAndroid Build Coastguard Worker    case VARYING_SLOT_CLIP_DIST0:
629*61046927SAndroid Build Coastguard Worker    case VARYING_SLOT_CLIP_DIST1:
630*61046927SAndroid Build Coastguard Worker       return "CLIPDST";
631*61046927SAndroid Build Coastguard Worker    case VARYING_SLOT_PRIMITIVE_ID:
632*61046927SAndroid Build Coastguard Worker       return "PRIMID";
633*61046927SAndroid Build Coastguard Worker    default:
634*61046927SAndroid Build Coastguard Worker       return "NO";
635*61046927SAndroid Build Coastguard Worker    }
636*61046927SAndroid Build Coastguard Worker }
637*61046927SAndroid Build Coastguard Worker 
638*61046927SAndroid Build Coastguard Worker static void
process_output_signature(struct dxil_module * mod,nir_shader * s)639*61046927SAndroid Build Coastguard Worker process_output_signature(struct dxil_module *mod, nir_shader *s)
640*61046927SAndroid Build Coastguard Worker {
641*61046927SAndroid Build Coastguard Worker    unsigned num_outputs = 0;
642*61046927SAndroid Build Coastguard Worker    unsigned next_row = 0;
643*61046927SAndroid Build Coastguard Worker    nir_foreach_variable_with_modes(var, s, nir_var_shader_out) {
644*61046927SAndroid Build Coastguard Worker       struct semantic_info semantic = {0};
645*61046927SAndroid Build Coastguard Worker       if (var->data.patch)
646*61046927SAndroid Build Coastguard Worker          continue;
647*61046927SAndroid Build Coastguard Worker 
648*61046927SAndroid Build Coastguard Worker       if (s->info.stage == MESA_SHADER_FRAGMENT) {
649*61046927SAndroid Build Coastguard Worker          get_semantic_ps_outname(var, &semantic);
650*61046927SAndroid Build Coastguard Worker          mod->outputs[num_outputs].sysvalue = "TARGET";
651*61046927SAndroid Build Coastguard Worker       } else {
652*61046927SAndroid Build Coastguard Worker          const struct glsl_type *type = var->type;
653*61046927SAndroid Build Coastguard Worker          if (nir_is_arrayed_io(var, s->info.stage))
654*61046927SAndroid Build Coastguard Worker             type = glsl_get_array_element(type);
655*61046927SAndroid Build Coastguard Worker          get_semantic_name(var, &semantic, type);
656*61046927SAndroid Build Coastguard Worker          mod->outputs[num_outputs].sysvalue = out_sysvalue_name(var);
657*61046927SAndroid Build Coastguard Worker       }
658*61046927SAndroid Build Coastguard Worker       nir_variable *base_var = var;
659*61046927SAndroid Build Coastguard Worker       if (var->data.location_frac) {
660*61046927SAndroid Build Coastguard Worker          if (s->info.stage == MESA_SHADER_FRAGMENT) {
661*61046927SAndroid Build Coastguard Worker             /* Fragment shader outputs are all either scalars, or must be declared as a single 4-component vector.
662*61046927SAndroid Build Coastguard Worker              * Any attempt to declare partial vectors split across multiple variables is ignored.
663*61046927SAndroid Build Coastguard Worker              */
664*61046927SAndroid Build Coastguard Worker             continue;
665*61046927SAndroid Build Coastguard Worker          }
666*61046927SAndroid Build Coastguard Worker          base_var = nir_find_variable_with_location(s, nir_var_shader_out, var->data.location);
667*61046927SAndroid Build Coastguard Worker       }
668*61046927SAndroid Build Coastguard Worker       if (base_var != var &&
669*61046927SAndroid Build Coastguard Worker           base_var->data.stream == var->data.stream)
670*61046927SAndroid Build Coastguard Worker          /* Combine fractional vars into any already existing row */
671*61046927SAndroid Build Coastguard Worker          get_additional_semantic_info(s, var, &semantic,
672*61046927SAndroid Build Coastguard Worker                                       mod->psv_outputs[base_var->data.driver_location].start_row,
673*61046927SAndroid Build Coastguard Worker                                       s->info.clip_distance_array_size);
674*61046927SAndroid Build Coastguard Worker       else
675*61046927SAndroid Build Coastguard Worker          next_row = get_additional_semantic_info(s, var, &semantic, next_row, s->info.clip_distance_array_size);
676*61046927SAndroid Build Coastguard Worker 
677*61046927SAndroid Build Coastguard Worker       mod->info.has_out_position |= semantic.kind== DXIL_SEM_POSITION;
678*61046927SAndroid Build Coastguard Worker       mod->info.has_out_depth |= semantic.kind == DXIL_SEM_DEPTH;
679*61046927SAndroid Build Coastguard Worker 
680*61046927SAndroid Build Coastguard Worker       struct dxil_psv_signature_element *psv_elm = &mod->psv_outputs[num_outputs];
681*61046927SAndroid Build Coastguard Worker 
682*61046927SAndroid Build Coastguard Worker       if (!fill_io_signature(mod, num_outputs, &semantic,
683*61046927SAndroid Build Coastguard Worker                              &mod->outputs[num_outputs], psv_elm))
684*61046927SAndroid Build Coastguard Worker          return;
685*61046927SAndroid Build Coastguard Worker 
686*61046927SAndroid Build Coastguard Worker       for (unsigned i = 0; i < mod->outputs[num_outputs].num_elements; ++i) {
687*61046927SAndroid Build Coastguard Worker          struct dxil_signature_element *elm = &mod->outputs[num_outputs].elements[i];
688*61046927SAndroid Build Coastguard Worker          if (mod->minor_validator <= 4)
689*61046927SAndroid Build Coastguard Worker             elm->never_writes_mask = 0xff & ~elm->mask;
690*61046927SAndroid Build Coastguard Worker          else
691*61046927SAndroid Build Coastguard Worker             /* This will be updated by the module processing */
692*61046927SAndroid Build Coastguard Worker             elm->never_writes_mask = 0xf & ~elm->mask;
693*61046927SAndroid Build Coastguard Worker       }
694*61046927SAndroid Build Coastguard Worker 
695*61046927SAndroid Build Coastguard Worker       ++num_outputs;
696*61046927SAndroid Build Coastguard Worker 
697*61046927SAndroid Build Coastguard Worker       mod->num_psv_outputs[semantic.stream] = MAX2(mod->num_psv_outputs[semantic.stream],
698*61046927SAndroid Build Coastguard Worker                                                    semantic.start_row + semantic.rows);
699*61046927SAndroid Build Coastguard Worker    }
700*61046927SAndroid Build Coastguard Worker    mod->num_sig_outputs = num_outputs;
701*61046927SAndroid Build Coastguard Worker }
702*61046927SAndroid Build Coastguard Worker 
703*61046927SAndroid Build Coastguard Worker static const char *
patch_sysvalue_name(nir_variable * var)704*61046927SAndroid Build Coastguard Worker patch_sysvalue_name(nir_variable *var)
705*61046927SAndroid Build Coastguard Worker {
706*61046927SAndroid Build Coastguard Worker    switch (var->data.location) {
707*61046927SAndroid Build Coastguard Worker    case VARYING_SLOT_TESS_LEVEL_OUTER:
708*61046927SAndroid Build Coastguard Worker       switch (glsl_get_aoa_size(var->type)) {
709*61046927SAndroid Build Coastguard Worker       case 4:
710*61046927SAndroid Build Coastguard Worker          return "QUADEDGE";
711*61046927SAndroid Build Coastguard Worker       case 3:
712*61046927SAndroid Build Coastguard Worker          return "TRIEDGE";
713*61046927SAndroid Build Coastguard Worker       case 2:
714*61046927SAndroid Build Coastguard Worker          return var->data.location_frac == 0 ?
715*61046927SAndroid Build Coastguard Worker             "LINEDET" : "LINEDEN";
716*61046927SAndroid Build Coastguard Worker       default:
717*61046927SAndroid Build Coastguard Worker          unreachable("Unexpected outer tess factor array size");
718*61046927SAndroid Build Coastguard Worker       }
719*61046927SAndroid Build Coastguard Worker       break;
720*61046927SAndroid Build Coastguard Worker    case VARYING_SLOT_TESS_LEVEL_INNER:
721*61046927SAndroid Build Coastguard Worker       switch (glsl_get_aoa_size(var->type)) {
722*61046927SAndroid Build Coastguard Worker       case 2:
723*61046927SAndroid Build Coastguard Worker          return "QUADINT";
724*61046927SAndroid Build Coastguard Worker       case 1:
725*61046927SAndroid Build Coastguard Worker          return "TRIINT";
726*61046927SAndroid Build Coastguard Worker       default:
727*61046927SAndroid Build Coastguard Worker          unreachable("Unexpected inner tess factory array size");
728*61046927SAndroid Build Coastguard Worker       }
729*61046927SAndroid Build Coastguard Worker       break;
730*61046927SAndroid Build Coastguard Worker    default:
731*61046927SAndroid Build Coastguard Worker       return "NO";
732*61046927SAndroid Build Coastguard Worker    }
733*61046927SAndroid Build Coastguard Worker }
734*61046927SAndroid Build Coastguard Worker 
735*61046927SAndroid Build Coastguard Worker static void
process_patch_const_signature(struct dxil_module * mod,nir_shader * s)736*61046927SAndroid Build Coastguard Worker process_patch_const_signature(struct dxil_module *mod, nir_shader *s)
737*61046927SAndroid Build Coastguard Worker {
738*61046927SAndroid Build Coastguard Worker    if (s->info.stage != MESA_SHADER_TESS_CTRL &&
739*61046927SAndroid Build Coastguard Worker        s->info.stage != MESA_SHADER_TESS_EVAL)
740*61046927SAndroid Build Coastguard Worker       return;
741*61046927SAndroid Build Coastguard Worker 
742*61046927SAndroid Build Coastguard Worker    nir_variable_mode mode = s->info.stage == MESA_SHADER_TESS_CTRL ?
743*61046927SAndroid Build Coastguard Worker       nir_var_shader_out : nir_var_shader_in;
744*61046927SAndroid Build Coastguard Worker    unsigned num_consts = 0;
745*61046927SAndroid Build Coastguard Worker    unsigned next_row = 0;
746*61046927SAndroid Build Coastguard Worker    nir_foreach_variable_with_modes(var, s, mode) {
747*61046927SAndroid Build Coastguard Worker       struct semantic_info semantic = {0};
748*61046927SAndroid Build Coastguard Worker       if (!var->data.patch)
749*61046927SAndroid Build Coastguard Worker          continue;
750*61046927SAndroid Build Coastguard Worker 
751*61046927SAndroid Build Coastguard Worker       const struct glsl_type *type = var->type;
752*61046927SAndroid Build Coastguard Worker       get_semantic_name(var, &semantic, type);
753*61046927SAndroid Build Coastguard Worker 
754*61046927SAndroid Build Coastguard Worker       mod->patch_consts[num_consts].sysvalue = patch_sysvalue_name(var);
755*61046927SAndroid Build Coastguard Worker       next_row = get_additional_semantic_info(s, var, &semantic, next_row, 0);
756*61046927SAndroid Build Coastguard Worker 
757*61046927SAndroid Build Coastguard Worker       struct dxil_psv_signature_element *psv_elm = &mod->psv_patch_consts[num_consts];
758*61046927SAndroid Build Coastguard Worker 
759*61046927SAndroid Build Coastguard Worker       if (!fill_io_signature(mod, num_consts, &semantic,
760*61046927SAndroid Build Coastguard Worker                              &mod->patch_consts[num_consts], psv_elm))
761*61046927SAndroid Build Coastguard Worker          return;
762*61046927SAndroid Build Coastguard Worker 
763*61046927SAndroid Build Coastguard Worker       if (mode == nir_var_shader_out) {
764*61046927SAndroid Build Coastguard Worker          for (unsigned i = 0; i < mod->patch_consts[num_consts].num_elements; ++i) {
765*61046927SAndroid Build Coastguard Worker             struct dxil_signature_element *elm = &mod->patch_consts[num_consts].elements[i];
766*61046927SAndroid Build Coastguard Worker             if (mod->minor_validator <= 4)
767*61046927SAndroid Build Coastguard Worker                elm->never_writes_mask = 0xff & ~elm->mask;
768*61046927SAndroid Build Coastguard Worker             else
769*61046927SAndroid Build Coastguard Worker                /* This will be updated by the module processing */
770*61046927SAndroid Build Coastguard Worker                elm->never_writes_mask = 0xf & ~elm->mask;
771*61046927SAndroid Build Coastguard Worker          }
772*61046927SAndroid Build Coastguard Worker       }
773*61046927SAndroid Build Coastguard Worker 
774*61046927SAndroid Build Coastguard Worker       ++num_consts;
775*61046927SAndroid Build Coastguard Worker 
776*61046927SAndroid Build Coastguard Worker       mod->num_psv_patch_consts = MAX2(mod->num_psv_patch_consts,
777*61046927SAndroid Build Coastguard Worker                                        semantic.start_row + semantic.rows);
778*61046927SAndroid Build Coastguard Worker    }
779*61046927SAndroid Build Coastguard Worker    mod->num_sig_patch_consts = num_consts;
780*61046927SAndroid Build Coastguard Worker }
781*61046927SAndroid Build Coastguard Worker 
782*61046927SAndroid Build Coastguard Worker static void
prepare_dependency_tables(struct dxil_module * mod,nir_shader * s)783*61046927SAndroid Build Coastguard Worker prepare_dependency_tables(struct dxil_module *mod, nir_shader *s)
784*61046927SAndroid Build Coastguard Worker {
785*61046927SAndroid Build Coastguard Worker    bool uses_view_id = BITSET_TEST(s->info.system_values_read, SYSTEM_VALUE_VIEW_INDEX);
786*61046927SAndroid Build Coastguard Worker    uint32_t num_output_streams = s->info.stage == MESA_SHADER_GEOMETRY ? 4 : 1;
787*61046927SAndroid Build Coastguard Worker    uint32_t num_tables = s->info.stage == MESA_SHADER_TESS_CTRL || s->info.stage == MESA_SHADER_TESS_EVAL ? 2 : num_output_streams;
788*61046927SAndroid Build Coastguard Worker 
789*61046927SAndroid Build Coastguard Worker    const uint32_t output_vecs_per_dword = 32 /* bits per dword */ / 4 /* components per vec */;
790*61046927SAndroid Build Coastguard Worker    const uint32_t masks_per_input_vec = 4 /* components per vec */;
791*61046927SAndroid Build Coastguard Worker 
792*61046927SAndroid Build Coastguard Worker    for (uint32_t i = 0; i < num_output_streams; ++i)
793*61046927SAndroid Build Coastguard Worker       mod->dependency_table_dwords_per_input[i] = DIV_ROUND_UP(mod->num_psv_outputs[i], output_vecs_per_dword);
794*61046927SAndroid Build Coastguard Worker    if (s->info.stage == MESA_SHADER_TESS_CTRL)
795*61046927SAndroid Build Coastguard Worker       mod->dependency_table_dwords_per_input[1] = DIV_ROUND_UP(mod->num_psv_patch_consts, output_vecs_per_dword);
796*61046927SAndroid Build Coastguard Worker 
797*61046927SAndroid Build Coastguard Worker    uint32_t view_id_table_sizes[4] = { 0 };
798*61046927SAndroid Build Coastguard Worker    if (uses_view_id) {
799*61046927SAndroid Build Coastguard Worker       for (uint32_t i = 0; i < 4; ++i)
800*61046927SAndroid Build Coastguard Worker          view_id_table_sizes[i] = mod->dependency_table_dwords_per_input[i];
801*61046927SAndroid Build Coastguard Worker    }
802*61046927SAndroid Build Coastguard Worker 
803*61046927SAndroid Build Coastguard Worker    for (uint32_t i = 0; i < num_output_streams; ++i)
804*61046927SAndroid Build Coastguard Worker       mod->io_dependency_table_size[i] = mod->dependency_table_dwords_per_input[i] * mod->num_psv_inputs * masks_per_input_vec;
805*61046927SAndroid Build Coastguard Worker    if (s->info.stage == MESA_SHADER_TESS_CTRL)
806*61046927SAndroid Build Coastguard Worker       mod->io_dependency_table_size[1] = mod->dependency_table_dwords_per_input[1] * mod->num_psv_inputs * masks_per_input_vec;
807*61046927SAndroid Build Coastguard Worker    else if (s->info.stage == MESA_SHADER_TESS_EVAL)
808*61046927SAndroid Build Coastguard Worker       mod->io_dependency_table_size[1] = mod->dependency_table_dwords_per_input[0] * mod->num_psv_patch_consts * masks_per_input_vec;
809*61046927SAndroid Build Coastguard Worker 
810*61046927SAndroid Build Coastguard Worker    mod->serialized_dependency_table_size = num_tables + 1;
811*61046927SAndroid Build Coastguard Worker    for (uint32_t i = 0; i < num_tables; ++i) {
812*61046927SAndroid Build Coastguard Worker       mod->serialized_dependency_table_size += view_id_table_sizes[i] + mod->io_dependency_table_size[i];
813*61046927SAndroid Build Coastguard Worker    }
814*61046927SAndroid Build Coastguard Worker 
815*61046927SAndroid Build Coastguard Worker    uint32_t *table = calloc(mod->serialized_dependency_table_size, sizeof(uint32_t));
816*61046927SAndroid Build Coastguard Worker    mod->serialized_dependency_table = table;
817*61046927SAndroid Build Coastguard Worker 
818*61046927SAndroid Build Coastguard Worker    *(table++) = mod->num_psv_inputs * 4;
819*61046927SAndroid Build Coastguard Worker    for (uint32_t i = 0; i < num_output_streams; ++i) {
820*61046927SAndroid Build Coastguard Worker       *(table++) = mod->num_psv_outputs[i] * 4;
821*61046927SAndroid Build Coastguard Worker       mod->viewid_dependency_table[i] = table;
822*61046927SAndroid Build Coastguard Worker       table += view_id_table_sizes[i];
823*61046927SAndroid Build Coastguard Worker       mod->io_dependency_table[i] = table;
824*61046927SAndroid Build Coastguard Worker       table += mod->io_dependency_table_size[i];
825*61046927SAndroid Build Coastguard Worker    }
826*61046927SAndroid Build Coastguard Worker    if (s->info.stage == MESA_SHADER_TESS_CTRL || s->info.stage == MESA_SHADER_TESS_EVAL) {
827*61046927SAndroid Build Coastguard Worker       *(table++) = mod->num_psv_patch_consts * 4;
828*61046927SAndroid Build Coastguard Worker       if (s->info.stage == MESA_SHADER_TESS_CTRL) {
829*61046927SAndroid Build Coastguard Worker          mod->viewid_dependency_table[1] = table;
830*61046927SAndroid Build Coastguard Worker          table += view_id_table_sizes[1];
831*61046927SAndroid Build Coastguard Worker       }
832*61046927SAndroid Build Coastguard Worker       mod->io_dependency_table[1] = table;
833*61046927SAndroid Build Coastguard Worker       table += mod->io_dependency_table_size[1];
834*61046927SAndroid Build Coastguard Worker    }
835*61046927SAndroid Build Coastguard Worker }
836*61046927SAndroid Build Coastguard Worker 
837*61046927SAndroid Build Coastguard Worker void
preprocess_signatures(struct dxil_module * mod,nir_shader * s,unsigned input_clip_size)838*61046927SAndroid Build Coastguard Worker preprocess_signatures(struct dxil_module *mod, nir_shader *s, unsigned input_clip_size)
839*61046927SAndroid Build Coastguard Worker {
840*61046927SAndroid Build Coastguard Worker    /* DXC does the same: Add an empty string before everything else */
841*61046927SAndroid Build Coastguard Worker    mod->sem_string_table = _mesa_string_buffer_create(mod->ralloc_ctx, 1024);
842*61046927SAndroid Build Coastguard Worker    copy_semantic_name_to_string(mod->sem_string_table, "");
843*61046927SAndroid Build Coastguard Worker 
844*61046927SAndroid Build Coastguard Worker    process_input_signature(mod, s, input_clip_size);
845*61046927SAndroid Build Coastguard Worker    process_output_signature(mod, s);
846*61046927SAndroid Build Coastguard Worker    process_patch_const_signature(mod, s);
847*61046927SAndroid Build Coastguard Worker 
848*61046927SAndroid Build Coastguard Worker    prepare_dependency_tables(mod, s);
849*61046927SAndroid Build Coastguard Worker }
850*61046927SAndroid Build Coastguard Worker 
851*61046927SAndroid Build Coastguard Worker static const struct dxil_mdnode *
get_signature_metadata(struct dxil_module * mod,const struct dxil_signature_record * recs,const struct dxil_psv_signature_element * psvs,unsigned num_elements,bool is_input)852*61046927SAndroid Build Coastguard Worker get_signature_metadata(struct dxil_module *mod,
853*61046927SAndroid Build Coastguard Worker                        const struct dxil_signature_record *recs,
854*61046927SAndroid Build Coastguard Worker                        const struct dxil_psv_signature_element *psvs,
855*61046927SAndroid Build Coastguard Worker                        unsigned num_elements,
856*61046927SAndroid Build Coastguard Worker                        bool is_input)
857*61046927SAndroid Build Coastguard Worker {
858*61046927SAndroid Build Coastguard Worker    if (num_elements == 0)
859*61046927SAndroid Build Coastguard Worker       return NULL;
860*61046927SAndroid Build Coastguard Worker 
861*61046927SAndroid Build Coastguard Worker    const struct dxil_mdnode *nodes[VARYING_SLOT_MAX * 4];
862*61046927SAndroid Build Coastguard Worker    for (unsigned i = 0; i < num_elements; ++i) {
863*61046927SAndroid Build Coastguard Worker       nodes[i] = fill_SV_param_nodes(mod, i, &recs[i], &psvs[i], is_input);
864*61046927SAndroid Build Coastguard Worker    }
865*61046927SAndroid Build Coastguard Worker 
866*61046927SAndroid Build Coastguard Worker    return dxil_get_metadata_node(mod, nodes, num_elements);
867*61046927SAndroid Build Coastguard Worker }
868*61046927SAndroid Build Coastguard Worker 
869*61046927SAndroid Build Coastguard Worker const struct dxil_mdnode *
get_signatures(struct dxil_module * mod)870*61046927SAndroid Build Coastguard Worker get_signatures(struct dxil_module *mod)
871*61046927SAndroid Build Coastguard Worker {
872*61046927SAndroid Build Coastguard Worker    const struct dxil_mdnode *input_signature = get_signature_metadata(mod, mod->inputs, mod->psv_inputs, mod->num_sig_inputs, true);
873*61046927SAndroid Build Coastguard Worker    const struct dxil_mdnode *output_signature = get_signature_metadata(mod, mod->outputs, mod->psv_outputs, mod->num_sig_outputs, false);
874*61046927SAndroid Build Coastguard Worker    const struct dxil_mdnode *patch_const_signature = get_signature_metadata(mod, mod->patch_consts, mod->psv_patch_consts, mod->num_sig_patch_consts,
875*61046927SAndroid Build Coastguard Worker       mod->shader_kind == DXIL_DOMAIN_SHADER);
876*61046927SAndroid Build Coastguard Worker 
877*61046927SAndroid Build Coastguard Worker    const struct dxil_mdnode *SV_nodes[3] = {
878*61046927SAndroid Build Coastguard Worker       input_signature,
879*61046927SAndroid Build Coastguard Worker       output_signature,
880*61046927SAndroid Build Coastguard Worker       patch_const_signature
881*61046927SAndroid Build Coastguard Worker    };
882*61046927SAndroid Build Coastguard Worker    if (output_signature || input_signature || patch_const_signature)
883*61046927SAndroid Build Coastguard Worker       return dxil_get_metadata_node(mod, SV_nodes, ARRAY_SIZE(SV_nodes));
884*61046927SAndroid Build Coastguard Worker    else
885*61046927SAndroid Build Coastguard Worker       return NULL;
886*61046927SAndroid Build Coastguard Worker }
887