vkd3d-shader/d3d-asm: Pass a prefix and suffix to shader_dump_decl_usage().
[vkd3d.git] / libs / vkd3d-shader / d3d_asm.c
blobdbc42b91ab5d609e7aff4d4c29f93712909cde05
1 /*
2 * Copyright 2002-2003 Jason Edmeades
3 * Copyright 2002-2003 Raphael Junqueira
4 * Copyright 2004 Christian Costa
5 * Copyright 2005 Oliver Stieber
6 * Copyright 2006 Ivan Gyurdiev
7 * Copyright 2007-2008, 2013 Stefan Dösinger for CodeWeavers
8 * Copyright 2009-2011 Henri Verbeet for CodeWeavers
10 * This library is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU Lesser General Public
12 * License as published by the Free Software Foundation; either
13 * version 2.1 of the License, or (at your option) any later version.
15 * This library is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * Lesser General Public License for more details.
20 * You should have received a copy of the GNU Lesser General Public
21 * License along with this library; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
25 #include "vkd3d_shader_private.h"
27 #include <stdio.h>
28 #include <math.h>
30 static const char * const shader_opcode_names[] =
32 [VKD3DSIH_ABS ] = "abs",
33 [VKD3DSIH_ACOS ] = "acos",
34 [VKD3DSIH_ADD ] = "add",
35 [VKD3DSIH_AND ] = "and",
36 [VKD3DSIH_ASIN ] = "asin",
37 [VKD3DSIH_ATAN ] = "atan",
38 [VKD3DSIH_ATOMIC_AND ] = "atomic_and",
39 [VKD3DSIH_ATOMIC_CMP_STORE ] = "atomic_cmp_store",
40 [VKD3DSIH_ATOMIC_IADD ] = "atomic_iadd",
41 [VKD3DSIH_ATOMIC_IMAX ] = "atomic_imax",
42 [VKD3DSIH_ATOMIC_IMIN ] = "atomic_imin",
43 [VKD3DSIH_ATOMIC_OR ] = "atomic_or",
44 [VKD3DSIH_ATOMIC_UMAX ] = "atomic_umax",
45 [VKD3DSIH_ATOMIC_UMIN ] = "atomic_umin",
46 [VKD3DSIH_ATOMIC_XOR ] = "atomic_xor",
47 [VKD3DSIH_BEM ] = "bem",
48 [VKD3DSIH_BFI ] = "bfi",
49 [VKD3DSIH_BFREV ] = "bfrev",
50 [VKD3DSIH_BRANCH ] = "branch",
51 [VKD3DSIH_BREAK ] = "break",
52 [VKD3DSIH_BREAKC ] = "breakc",
53 [VKD3DSIH_BREAKP ] = "breakp",
54 [VKD3DSIH_BUFINFO ] = "bufinfo",
55 [VKD3DSIH_CALL ] = "call",
56 [VKD3DSIH_CALLNZ ] = "callnz",
57 [VKD3DSIH_CASE ] = "case",
58 [VKD3DSIH_CHECK_ACCESS_FULLY_MAPPED ] = "check_access_fully_mapped",
59 [VKD3DSIH_CMP ] = "cmp",
60 [VKD3DSIH_CND ] = "cnd",
61 [VKD3DSIH_CONTINUE ] = "continue",
62 [VKD3DSIH_CONTINUEP ] = "continuec",
63 [VKD3DSIH_COUNTBITS ] = "countbits",
64 [VKD3DSIH_CRS ] = "crs",
65 [VKD3DSIH_CUT ] = "cut",
66 [VKD3DSIH_CUT_STREAM ] = "cut_stream",
67 [VKD3DSIH_DADD ] = "dadd",
68 [VKD3DSIH_DCL ] = "dcl",
69 [VKD3DSIH_DCL_CONSTANT_BUFFER ] = "dcl_constantBuffer",
70 [VKD3DSIH_DCL_FUNCTION_BODY ] = "dcl_function_body",
71 [VKD3DSIH_DCL_FUNCTION_TABLE ] = "dcl_function_table",
72 [VKD3DSIH_DCL_GLOBAL_FLAGS ] = "dcl_globalFlags",
73 [VKD3DSIH_DCL_GS_INSTANCES ] = "dcl_gs_instances",
74 [VKD3DSIH_DCL_HS_FORK_PHASE_INSTANCE_COUNT] = "dcl_hs_fork_phase_instance_count",
75 [VKD3DSIH_DCL_HS_JOIN_PHASE_INSTANCE_COUNT] = "dcl_hs_join_phase_instance_count",
76 [VKD3DSIH_DCL_HS_MAX_TESSFACTOR ] = "dcl_hs_max_tessfactor",
77 [VKD3DSIH_DCL_IMMEDIATE_CONSTANT_BUFFER ] = "dcl_immediateConstantBuffer",
78 [VKD3DSIH_DCL_INDEX_RANGE ] = "dcl_index_range",
79 [VKD3DSIH_DCL_INDEXABLE_TEMP ] = "dcl_indexableTemp",
80 [VKD3DSIH_DCL_INPUT ] = "dcl_input",
81 [VKD3DSIH_DCL_INPUT_CONTROL_POINT_COUNT ] = "dcl_input_control_point_count",
82 [VKD3DSIH_DCL_INPUT_PRIMITIVE ] = "dcl_inputPrimitive",
83 [VKD3DSIH_DCL_INPUT_PS ] = "dcl_input_ps",
84 [VKD3DSIH_DCL_INPUT_PS_SGV ] = "dcl_input_ps_sgv",
85 [VKD3DSIH_DCL_INPUT_PS_SIV ] = "dcl_input_ps_siv",
86 [VKD3DSIH_DCL_INPUT_SGV ] = "dcl_input_sgv",
87 [VKD3DSIH_DCL_INPUT_SIV ] = "dcl_input_siv",
88 [VKD3DSIH_DCL_INTERFACE ] = "dcl_interface",
89 [VKD3DSIH_DCL_OUTPUT ] = "dcl_output",
90 [VKD3DSIH_DCL_OUTPUT_CONTROL_POINT_COUNT ] = "dcl_output_control_point_count",
91 [VKD3DSIH_DCL_OUTPUT_SIV ] = "dcl_output_siv",
92 [VKD3DSIH_DCL_OUTPUT_TOPOLOGY ] = "dcl_outputTopology",
93 [VKD3DSIH_DCL_RESOURCE_RAW ] = "dcl_resource_raw",
94 [VKD3DSIH_DCL_RESOURCE_STRUCTURED ] = "dcl_resource_structured",
95 [VKD3DSIH_DCL_SAMPLER ] = "dcl_sampler",
96 [VKD3DSIH_DCL_STREAM ] = "dcl_stream",
97 [VKD3DSIH_DCL_TEMPS ] = "dcl_temps",
98 [VKD3DSIH_DCL_TESSELLATOR_DOMAIN ] = "dcl_tessellator_domain",
99 [VKD3DSIH_DCL_TESSELLATOR_OUTPUT_PRIMITIVE] = "dcl_tessellator_output_primitive",
100 [VKD3DSIH_DCL_TESSELLATOR_PARTITIONING ] = "dcl_tessellator_partitioning",
101 [VKD3DSIH_DCL_TGSM_RAW ] = "dcl_tgsm_raw",
102 [VKD3DSIH_DCL_TGSM_STRUCTURED ] = "dcl_tgsm_structured",
103 [VKD3DSIH_DCL_THREAD_GROUP ] = "dcl_thread_group",
104 [VKD3DSIH_DCL_UAV_RAW ] = "dcl_uav_raw",
105 [VKD3DSIH_DCL_UAV_STRUCTURED ] = "dcl_uav_structured",
106 [VKD3DSIH_DCL_UAV_TYPED ] = "dcl_uav_typed",
107 [VKD3DSIH_DCL_VERTICES_OUT ] = "dcl_maxOutputVertexCount",
108 [VKD3DSIH_DDIV ] = "ddiv",
109 [VKD3DSIH_DEF ] = "def",
110 [VKD3DSIH_DEFAULT ] = "default",
111 [VKD3DSIH_DEFB ] = "defb",
112 [VKD3DSIH_DEFI ] = "defi",
113 [VKD3DSIH_DEQO ] = "deq",
114 [VKD3DSIH_DFMA ] = "dfma",
115 [VKD3DSIH_DGEO ] = "dge",
116 [VKD3DSIH_DISCARD ] = "discard",
117 [VKD3DSIH_DIV ] = "div",
118 [VKD3DSIH_DLT ] = "dlt",
119 [VKD3DSIH_DMAX ] = "dmax",
120 [VKD3DSIH_DMIN ] = "dmin",
121 [VKD3DSIH_DMOV ] = "dmov",
122 [VKD3DSIH_DMOVC ] = "dmovc",
123 [VKD3DSIH_DMUL ] = "dmul",
124 [VKD3DSIH_DNE ] = "dne",
125 [VKD3DSIH_DP2 ] = "dp2",
126 [VKD3DSIH_DP2ADD ] = "dp2add",
127 [VKD3DSIH_DP3 ] = "dp3",
128 [VKD3DSIH_DP4 ] = "dp4",
129 [VKD3DSIH_DRCP ] = "drcp",
130 [VKD3DSIH_DST ] = "dst",
131 [VKD3DSIH_DSX ] = "dsx",
132 [VKD3DSIH_DSX_COARSE ] = "deriv_rtx_coarse",
133 [VKD3DSIH_DSX_FINE ] = "deriv_rtx_fine",
134 [VKD3DSIH_DSY ] = "dsy",
135 [VKD3DSIH_DSY_COARSE ] = "deriv_rty_coarse",
136 [VKD3DSIH_DSY_FINE ] = "deriv_rty_fine",
137 [VKD3DSIH_DTOF ] = "dtof",
138 [VKD3DSIH_DTOI ] = "dtoi",
139 [VKD3DSIH_DTOU ] = "dtou",
140 [VKD3DSIH_ELSE ] = "else",
141 [VKD3DSIH_EMIT ] = "emit",
142 [VKD3DSIH_EMIT_STREAM ] = "emit_stream",
143 [VKD3DSIH_ENDIF ] = "endif",
144 [VKD3DSIH_ENDLOOP ] = "endloop",
145 [VKD3DSIH_ENDREP ] = "endrep",
146 [VKD3DSIH_ENDSWITCH ] = "endswitch",
147 [VKD3DSIH_EQO ] = "eq",
148 [VKD3DSIH_EQU ] = "eq_unord",
149 [VKD3DSIH_EVAL_CENTROID ] = "eval_centroid",
150 [VKD3DSIH_EVAL_SAMPLE_INDEX ] = "eval_sample_index",
151 [VKD3DSIH_EXP ] = "exp",
152 [VKD3DSIH_EXPP ] = "expp",
153 [VKD3DSIH_F16TOF32 ] = "f16tof32",
154 [VKD3DSIH_F32TOF16 ] = "f32tof16",
155 [VKD3DSIH_FCALL ] = "fcall",
156 [VKD3DSIH_FIRSTBIT_HI ] = "firstbit_hi",
157 [VKD3DSIH_FIRSTBIT_LO ] = "firstbit_lo",
158 [VKD3DSIH_FIRSTBIT_SHI ] = "firstbit_shi",
159 [VKD3DSIH_FRC ] = "frc",
160 [VKD3DSIH_FREM ] = "frem",
161 [VKD3DSIH_FTOD ] = "ftod",
162 [VKD3DSIH_FTOI ] = "ftoi",
163 [VKD3DSIH_FTOU ] = "ftou",
164 [VKD3DSIH_GATHER4 ] = "gather4",
165 [VKD3DSIH_GATHER4_C ] = "gather4_c",
166 [VKD3DSIH_GATHER4_C_S ] = "gather4_c_s",
167 [VKD3DSIH_GATHER4_PO ] = "gather4_po",
168 [VKD3DSIH_GATHER4_PO_C ] = "gather4_po_c",
169 [VKD3DSIH_GATHER4_PO_C_S ] = "gather4_po_c_s",
170 [VKD3DSIH_GATHER4_PO_S ] = "gather4_po_s",
171 [VKD3DSIH_GATHER4_S ] = "gather4_s",
172 [VKD3DSIH_GEO ] = "ge",
173 [VKD3DSIH_GEU ] = "ge_unord",
174 [VKD3DSIH_HCOS ] = "hcos",
175 [VKD3DSIH_HS_CONTROL_POINT_PHASE ] = "hs_control_point_phase",
176 [VKD3DSIH_HS_DECLS ] = "hs_decls",
177 [VKD3DSIH_HS_FORK_PHASE ] = "hs_fork_phase",
178 [VKD3DSIH_HS_JOIN_PHASE ] = "hs_join_phase",
179 [VKD3DSIH_HSIN ] = "hsin",
180 [VKD3DSIH_HTAN ] = "htan",
181 [VKD3DSIH_IADD ] = "iadd",
182 [VKD3DSIH_IBFE ] = "ibfe",
183 [VKD3DSIH_IDIV ] = "idiv",
184 [VKD3DSIH_IEQ ] = "ieq",
185 [VKD3DSIH_IF ] = "if",
186 [VKD3DSIH_IFC ] = "ifc",
187 [VKD3DSIH_IGE ] = "ige",
188 [VKD3DSIH_ILT ] = "ilt",
189 [VKD3DSIH_IMAD ] = "imad",
190 [VKD3DSIH_IMAX ] = "imax",
191 [VKD3DSIH_IMIN ] = "imin",
192 [VKD3DSIH_IMM_ATOMIC_ALLOC ] = "imm_atomic_alloc",
193 [VKD3DSIH_IMM_ATOMIC_AND ] = "imm_atomic_and",
194 [VKD3DSIH_IMM_ATOMIC_CMP_EXCH ] = "imm_atomic_cmp_exch",
195 [VKD3DSIH_IMM_ATOMIC_CONSUME ] = "imm_atomic_consume",
196 [VKD3DSIH_IMM_ATOMIC_EXCH ] = "imm_atomic_exch",
197 [VKD3DSIH_IMM_ATOMIC_IADD ] = "imm_atomic_iadd",
198 [VKD3DSIH_IMM_ATOMIC_IMAX ] = "imm_atomic_imax",
199 [VKD3DSIH_IMM_ATOMIC_IMIN ] = "imm_atomic_imin",
200 [VKD3DSIH_IMM_ATOMIC_OR ] = "imm_atomic_or",
201 [VKD3DSIH_IMM_ATOMIC_UMAX ] = "imm_atomic_umax",
202 [VKD3DSIH_IMM_ATOMIC_UMIN ] = "imm_atomic_umin",
203 [VKD3DSIH_IMM_ATOMIC_XOR ] = "imm_atomic_xor",
204 [VKD3DSIH_IMUL ] = "imul",
205 [VKD3DSIH_INE ] = "ine",
206 [VKD3DSIH_INEG ] = "ineg",
207 [VKD3DSIH_ISFINITE ] = "isfinite",
208 [VKD3DSIH_ISHL ] = "ishl",
209 [VKD3DSIH_ISHR ] = "ishr",
210 [VKD3DSIH_ISINF ] = "isinf",
211 [VKD3DSIH_ISNAN ] = "isnan",
212 [VKD3DSIH_ITOD ] = "itod",
213 [VKD3DSIH_ITOF ] = "itof",
214 [VKD3DSIH_ITOI ] = "itoi",
215 [VKD3DSIH_LABEL ] = "label",
216 [VKD3DSIH_LD ] = "ld",
217 [VKD3DSIH_LD2DMS ] = "ld2dms",
218 [VKD3DSIH_LD2DMS_S ] = "ld2dms_s",
219 [VKD3DSIH_LD_RAW ] = "ld_raw",
220 [VKD3DSIH_LD_RAW_S ] = "ld_raw_s",
221 [VKD3DSIH_LD_S ] = "ld_s",
222 [VKD3DSIH_LD_STRUCTURED ] = "ld_structured",
223 [VKD3DSIH_LD_STRUCTURED_S ] = "ld_structured_s",
224 [VKD3DSIH_LD_UAV_TYPED ] = "ld_uav_typed",
225 [VKD3DSIH_LD_UAV_TYPED_S ] = "ld_uav_typed_s",
226 [VKD3DSIH_LIT ] = "lit",
227 [VKD3DSIH_LOD ] = "lod",
228 [VKD3DSIH_LOG ] = "log",
229 [VKD3DSIH_LOGP ] = "logp",
230 [VKD3DSIH_LOOP ] = "loop",
231 [VKD3DSIH_LRP ] = "lrp",
232 [VKD3DSIH_LTO ] = "lt",
233 [VKD3DSIH_LTU ] = "lt_unord",
234 [VKD3DSIH_M3x2 ] = "m3x2",
235 [VKD3DSIH_M3x3 ] = "m3x3",
236 [VKD3DSIH_M3x4 ] = "m3x4",
237 [VKD3DSIH_M4x3 ] = "m4x3",
238 [VKD3DSIH_M4x4 ] = "m4x4",
239 [VKD3DSIH_MAD ] = "mad",
240 [VKD3DSIH_MAX ] = "max",
241 [VKD3DSIH_MIN ] = "min",
242 [VKD3DSIH_MOV ] = "mov",
243 [VKD3DSIH_MOVA ] = "mova",
244 [VKD3DSIH_MOVC ] = "movc",
245 [VKD3DSIH_MSAD ] = "msad",
246 [VKD3DSIH_MUL ] = "mul",
247 [VKD3DSIH_NEO ] = "ne_ord",
248 [VKD3DSIH_NEU ] = "ne",
249 [VKD3DSIH_NOP ] = "nop",
250 [VKD3DSIH_NOT ] = "not",
251 [VKD3DSIH_NRM ] = "nrm",
252 [VKD3DSIH_OR ] = "or",
253 [VKD3DSIH_ORD ] = "ord",
254 [VKD3DSIH_PHASE ] = "phase",
255 [VKD3DSIH_PHI ] = "phi",
256 [VKD3DSIH_POW ] = "pow",
257 [VKD3DSIH_RCP ] = "rcp",
258 [VKD3DSIH_REP ] = "rep",
259 [VKD3DSIH_RESINFO ] = "resinfo",
260 [VKD3DSIH_RET ] = "ret",
261 [VKD3DSIH_RETP ] = "retp",
262 [VKD3DSIH_ROUND_NE ] = "round_ne",
263 [VKD3DSIH_ROUND_NI ] = "round_ni",
264 [VKD3DSIH_ROUND_PI ] = "round_pi",
265 [VKD3DSIH_ROUND_Z ] = "round_z",
266 [VKD3DSIH_RSQ ] = "rsq",
267 [VKD3DSIH_SAMPLE ] = "sample",
268 [VKD3DSIH_SAMPLE_B ] = "sample_b",
269 [VKD3DSIH_SAMPLE_B_CL_S ] = "sample_b_cl_s",
270 [VKD3DSIH_SAMPLE_C ] = "sample_c",
271 [VKD3DSIH_SAMPLE_C_CL_S ] = "sample_c_cl_s",
272 [VKD3DSIH_SAMPLE_C_LZ ] = "sample_c_lz",
273 [VKD3DSIH_SAMPLE_C_LZ_S ] = "sample_c_lz_s",
274 [VKD3DSIH_SAMPLE_CL_S ] = "sample_cl_s",
275 [VKD3DSIH_SAMPLE_GRAD ] = "sample_d",
276 [VKD3DSIH_SAMPLE_GRAD_CL_S ] = "sample_d_cl_s",
277 [VKD3DSIH_SAMPLE_INFO ] = "sample_info",
278 [VKD3DSIH_SAMPLE_LOD ] = "sample_l",
279 [VKD3DSIH_SAMPLE_LOD_S ] = "sample_l_s",
280 [VKD3DSIH_SAMPLE_POS ] = "sample_pos",
281 [VKD3DSIH_SETP ] = "setp",
282 [VKD3DSIH_SGE ] = "sge",
283 [VKD3DSIH_SGN ] = "sgn",
284 [VKD3DSIH_SINCOS ] = "sincos",
285 [VKD3DSIH_SLT ] = "slt",
286 [VKD3DSIH_SQRT ] = "sqrt",
287 [VKD3DSIH_STORE_RAW ] = "store_raw",
288 [VKD3DSIH_STORE_STRUCTURED ] = "store_structured",
289 [VKD3DSIH_STORE_UAV_TYPED ] = "store_uav_typed",
290 [VKD3DSIH_SUB ] = "sub",
291 [VKD3DSIH_SWAPC ] = "swapc",
292 [VKD3DSIH_SWITCH ] = "switch",
293 [VKD3DSIH_SWITCH_MONOLITHIC ] = "switch",
294 [VKD3DSIH_SYNC ] = "sync",
295 [VKD3DSIH_TAN ] = "tan",
296 [VKD3DSIH_TEX ] = "texld",
297 [VKD3DSIH_TEXBEM ] = "texbem",
298 [VKD3DSIH_TEXBEML ] = "texbeml",
299 [VKD3DSIH_TEXCOORD ] = "texcrd",
300 [VKD3DSIH_TEXDEPTH ] = "texdepth",
301 [VKD3DSIH_TEXDP3 ] = "texdp3",
302 [VKD3DSIH_TEXDP3TEX ] = "texdp3tex",
303 [VKD3DSIH_TEXKILL ] = "texkill",
304 [VKD3DSIH_TEXLDD ] = "texldd",
305 [VKD3DSIH_TEXLDL ] = "texldl",
306 [VKD3DSIH_TEXM3x2DEPTH ] = "texm3x2depth",
307 [VKD3DSIH_TEXM3x2PAD ] = "texm3x2pad",
308 [VKD3DSIH_TEXM3x2TEX ] = "texm3x2tex",
309 [VKD3DSIH_TEXM3x3 ] = "texm3x3",
310 [VKD3DSIH_TEXM3x3DIFF ] = "texm3x3diff",
311 [VKD3DSIH_TEXM3x3PAD ] = "texm3x3pad",
312 [VKD3DSIH_TEXM3x3SPEC ] = "texm3x3spec",
313 [VKD3DSIH_TEXM3x3TEX ] = "texm3x3tex",
314 [VKD3DSIH_TEXM3x3VSPEC ] = "texm3x3vspec",
315 [VKD3DSIH_TEXREG2AR ] = "texreg2ar",
316 [VKD3DSIH_TEXREG2GB ] = "texreg2gb",
317 [VKD3DSIH_TEXREG2RGB ] = "texreg2rgb",
318 [VKD3DSIH_UBFE ] = "ubfe",
319 [VKD3DSIH_UDIV ] = "udiv",
320 [VKD3DSIH_UGE ] = "uge",
321 [VKD3DSIH_ULT ] = "ult",
322 [VKD3DSIH_UMAX ] = "umax",
323 [VKD3DSIH_UMIN ] = "umin",
324 [VKD3DSIH_UMUL ] = "umul",
325 [VKD3DSIH_UNO ] = "uno",
326 [VKD3DSIH_USHR ] = "ushr",
327 [VKD3DSIH_UTOD ] = "utod",
328 [VKD3DSIH_UTOF ] = "utof",
329 [VKD3DSIH_UTOU ] = "utou",
330 [VKD3DSIH_XOR ] = "xor",
333 struct vkd3d_d3d_asm_colours
335 const char *reset;
336 const char *error;
337 const char *literal;
338 const char *modifier;
339 const char *opcode;
340 const char *reg;
341 const char *swizzle;
342 const char *version;
343 const char *write_mask;
344 const char *label;
347 struct vkd3d_d3d_asm_compiler
349 struct vkd3d_string_buffer buffer;
350 struct vkd3d_shader_version shader_version;
351 struct vkd3d_d3d_asm_colours colours;
352 enum vsir_asm_flags flags;
353 const struct vkd3d_shader_instruction *current;
356 static int VKD3D_PRINTF_FUNC(2, 3) shader_addline(struct vkd3d_string_buffer *buffer, const char *format, ...)
358 va_list args;
359 int ret;
361 va_start(args, format);
362 ret = vkd3d_string_buffer_vprintf(buffer, format, args);
363 va_end(args);
365 return ret;
368 /* Convert floating point offset relative to a register file to an absolute
369 * offset for float constants. */
370 static unsigned int shader_get_float_offset(enum vkd3d_shader_register_type register_type, UINT register_idx)
372 switch (register_type)
374 case VKD3DSPR_CONST: return register_idx;
375 case VKD3DSPR_CONST2: return 2048 + register_idx;
376 case VKD3DSPR_CONST3: return 4096 + register_idx;
377 case VKD3DSPR_CONST4: return 6144 + register_idx;
378 default:
379 FIXME("Unsupported register type: %u.\n", register_type);
380 return register_idx;
384 static void shader_dump_global_flags(struct vkd3d_d3d_asm_compiler *compiler,
385 enum vkd3d_shader_global_flags global_flags)
387 unsigned int i;
389 static const struct
391 enum vkd3d_shader_global_flags flag;
392 const char *name;
394 global_flag_info[] =
396 {VKD3DSGF_REFACTORING_ALLOWED, "refactoringAllowed"},
397 {VKD3DSGF_FORCE_EARLY_DEPTH_STENCIL, "forceEarlyDepthStencil"},
398 {VKD3DSGF_ENABLE_RAW_AND_STRUCTURED_BUFFERS, "enableRawAndStructuredBuffers"},
399 {VKD3DSGF_ENABLE_MINIMUM_PRECISION, "enableMinimumPrecision"},
400 {VKD3DSGF_SKIP_OPTIMIZATION, "skipOptimization"},
401 {VKD3DSGF_ENABLE_DOUBLE_PRECISION_FLOAT_OPS, "enableDoublePrecisionFloatOps"},
402 {VKD3DSGF_ENABLE_11_1_DOUBLE_EXTENSIONS, "enable11_1DoubleExtensions"},
405 for (i = 0; i < ARRAY_SIZE(global_flag_info); ++i)
407 if (global_flags & global_flag_info[i].flag)
409 vkd3d_string_buffer_printf(&compiler->buffer, "%s", global_flag_info[i].name);
410 global_flags &= ~global_flag_info[i].flag;
411 if (global_flags)
412 vkd3d_string_buffer_printf(&compiler->buffer, " | ");
416 if (global_flags)
417 vkd3d_string_buffer_printf(&compiler->buffer, "unknown_flags(%#"PRIx64")", (uint64_t)global_flags);
420 static void shader_dump_atomic_op_flags(struct vkd3d_d3d_asm_compiler *compiler, uint32_t atomic_flags)
422 if (atomic_flags & VKD3DARF_SEQ_CST)
424 vkd3d_string_buffer_printf(&compiler->buffer, "_seqCst");
425 atomic_flags &= ~VKD3DARF_SEQ_CST;
427 if (atomic_flags & VKD3DARF_VOLATILE)
429 vkd3d_string_buffer_printf(&compiler->buffer, "_volatile");
430 atomic_flags &= ~VKD3DARF_VOLATILE;
433 if (atomic_flags)
434 vkd3d_string_buffer_printf(&compiler->buffer, "_unknown_flags(%#x)", atomic_flags);
437 static void shader_dump_sync_flags(struct vkd3d_d3d_asm_compiler *compiler, uint32_t sync_flags)
439 if (sync_flags & VKD3DSSF_GLOBAL_UAV)
441 vkd3d_string_buffer_printf(&compiler->buffer, "_uglobal");
442 sync_flags &= ~VKD3DSSF_GLOBAL_UAV;
444 if (sync_flags & VKD3DSSF_THREAD_GROUP_UAV)
446 vkd3d_string_buffer_printf(&compiler->buffer, "_ugroup");
447 sync_flags &= ~VKD3DSSF_THREAD_GROUP_UAV;
449 if (sync_flags & VKD3DSSF_GROUP_SHARED_MEMORY)
451 vkd3d_string_buffer_printf(&compiler->buffer, "_g");
452 sync_flags &= ~VKD3DSSF_GROUP_SHARED_MEMORY;
454 if (sync_flags & VKD3DSSF_THREAD_GROUP)
456 vkd3d_string_buffer_printf(&compiler->buffer, "_t");
457 sync_flags &= ~VKD3DSSF_THREAD_GROUP;
460 if (sync_flags)
461 vkd3d_string_buffer_printf(&compiler->buffer, "_unknown_flags(%#x)", sync_flags);
464 static void shader_dump_precise_flags(struct vkd3d_d3d_asm_compiler *compiler, uint32_t flags)
466 if (!(flags & VKD3DSI_PRECISE_XYZW))
467 return;
469 vkd3d_string_buffer_printf(&compiler->buffer, " [precise");
470 if (flags != VKD3DSI_PRECISE_XYZW)
472 vkd3d_string_buffer_printf(&compiler->buffer, "(%s%s%s%s)",
473 flags & VKD3DSI_PRECISE_X ? "x" : "",
474 flags & VKD3DSI_PRECISE_Y ? "y" : "",
475 flags & VKD3DSI_PRECISE_Z ? "z" : "",
476 flags & VKD3DSI_PRECISE_W ? "w" : "");
478 vkd3d_string_buffer_printf(&compiler->buffer, "]");
481 static void shader_dump_uav_flags(struct vkd3d_d3d_asm_compiler *compiler, uint32_t uav_flags)
483 if (uav_flags & VKD3DSUF_GLOBALLY_COHERENT)
485 vkd3d_string_buffer_printf(&compiler->buffer, "_glc");
486 uav_flags &= ~VKD3DSUF_GLOBALLY_COHERENT;
488 if (uav_flags & VKD3DSUF_ORDER_PRESERVING_COUNTER)
490 vkd3d_string_buffer_printf(&compiler->buffer, "_opc");
491 uav_flags &= ~VKD3DSUF_ORDER_PRESERVING_COUNTER;
493 if (uav_flags & VKD3DSUF_RASTERISER_ORDERED_VIEW)
495 vkd3d_string_buffer_printf(&compiler->buffer, "_rov");
496 uav_flags &= ~VKD3DSUF_RASTERISER_ORDERED_VIEW;
499 if (uav_flags)
500 vkd3d_string_buffer_printf(&compiler->buffer, "_unknown_flags(%#x)", uav_flags);
503 static void shader_print_tessellator_domain(struct vkd3d_d3d_asm_compiler *compiler,
504 const char *prefix, enum vkd3d_tessellator_domain d, const char *suffix)
506 struct vkd3d_string_buffer *buffer = &compiler->buffer;
507 const char *domain;
509 switch (d)
511 case VKD3D_TESSELLATOR_DOMAIN_LINE:
512 domain = "domain_isoline";
513 break;
514 case VKD3D_TESSELLATOR_DOMAIN_TRIANGLE:
515 domain = "domain_tri";
516 break;
517 case VKD3D_TESSELLATOR_DOMAIN_QUAD:
518 domain = "domain_quad";
519 break;
520 default:
521 vkd3d_string_buffer_printf(buffer, "%s%s<unhandled tessellator domain %#x>%s%s",
522 prefix, compiler->colours.error, d, compiler->colours.reset, suffix);
523 return;
526 vkd3d_string_buffer_printf(buffer, "%s%s%s", prefix, domain, suffix);
529 static void shader_print_tessellator_output_primitive(struct vkd3d_d3d_asm_compiler *compiler,
530 const char *prefix, enum vkd3d_shader_tessellator_output_primitive p, const char *suffix)
532 struct vkd3d_string_buffer *buffer = &compiler->buffer;
533 const char *primitive;
535 switch (p)
537 case VKD3D_SHADER_TESSELLATOR_OUTPUT_POINT:
538 primitive = "output_point";
539 break;
540 case VKD3D_SHADER_TESSELLATOR_OUTPUT_LINE:
541 primitive = "output_line";
542 break;
543 case VKD3D_SHADER_TESSELLATOR_OUTPUT_TRIANGLE_CW:
544 primitive = "output_triangle_cw";
545 break;
546 case VKD3D_SHADER_TESSELLATOR_OUTPUT_TRIANGLE_CCW:
547 primitive = "output_triangle_ccw";
548 break;
549 default:
550 vkd3d_string_buffer_printf(buffer, "%s%s<unhandled tessellator output primitive %#x>%s%s",
551 prefix, compiler->colours.error, p, compiler->colours.reset, suffix);
552 return;
555 vkd3d_string_buffer_printf(buffer, "%s%s%s", prefix, primitive, suffix);
558 static void shader_print_tessellator_partitioning(struct vkd3d_d3d_asm_compiler *compiler,
559 const char *prefix, enum vkd3d_shader_tessellator_partitioning p, const char *suffix)
561 struct vkd3d_string_buffer *buffer = &compiler->buffer;
562 const char *partitioning;
564 switch (p)
566 case VKD3D_SHADER_TESSELLATOR_PARTITIONING_INTEGER:
567 partitioning = "partitioning_integer";
568 break;
569 case VKD3D_SHADER_TESSELLATOR_PARTITIONING_POW2:
570 partitioning = "partitioning_pow2";
571 break;
572 case VKD3D_SHADER_TESSELLATOR_PARTITIONING_FRACTIONAL_ODD:
573 partitioning = "partitioning_fractional_odd";
574 break;
575 case VKD3D_SHADER_TESSELLATOR_PARTITIONING_FRACTIONAL_EVEN:
576 partitioning = "partitioning_fractional_even";
577 break;
578 default:
579 vkd3d_string_buffer_printf(buffer, "%s%s<unhandled tessellator partitioning %#x>%s%s",
580 prefix, compiler->colours.error, p, compiler->colours.reset, suffix);
581 return;
584 vkd3d_string_buffer_printf(buffer, "%s%s%s", prefix, partitioning, suffix);
587 static void shader_print_input_sysval_semantic(struct vkd3d_d3d_asm_compiler *compiler,
588 const char *prefix, enum vkd3d_shader_input_sysval_semantic semantic, const char *suffix)
590 unsigned int i;
592 static const struct
594 enum vkd3d_shader_input_sysval_semantic sysval_semantic;
595 const char *sysval_name;
597 shader_input_sysval_semantic_names[] =
599 {VKD3D_SIV_POSITION, "position"},
600 {VKD3D_SIV_CLIP_DISTANCE, "clip_distance"},
601 {VKD3D_SIV_CULL_DISTANCE, "cull_distance"},
602 {VKD3D_SIV_RENDER_TARGET_ARRAY_INDEX, "render_target_array_index"},
603 {VKD3D_SIV_VIEWPORT_ARRAY_INDEX, "viewport_array_index"},
604 {VKD3D_SIV_VERTEX_ID, "vertex_id"},
605 {VKD3D_SIV_INSTANCE_ID, "instance_id"},
606 {VKD3D_SIV_PRIMITIVE_ID, "primitive_id"},
607 {VKD3D_SIV_IS_FRONT_FACE, "is_front_face"},
608 {VKD3D_SIV_SAMPLE_INDEX, "sample_index"},
609 {VKD3D_SIV_QUAD_U0_TESS_FACTOR, "finalQuadUeq0EdgeTessFactor"},
610 {VKD3D_SIV_QUAD_V0_TESS_FACTOR, "finalQuadVeq0EdgeTessFactor"},
611 {VKD3D_SIV_QUAD_U1_TESS_FACTOR, "finalQuadUeq1EdgeTessFactor"},
612 {VKD3D_SIV_QUAD_V1_TESS_FACTOR, "finalQuadVeq1EdgeTessFactor"},
613 {VKD3D_SIV_QUAD_U_INNER_TESS_FACTOR, "finalQuadUInsideTessFactor"},
614 {VKD3D_SIV_QUAD_V_INNER_TESS_FACTOR, "finalQuadVInsideTessFactor"},
615 {VKD3D_SIV_TRIANGLE_U_TESS_FACTOR, "finalTriUeq0EdgeTessFactor"},
616 {VKD3D_SIV_TRIANGLE_V_TESS_FACTOR, "finalTriVeq0EdgeTessFactor"},
617 {VKD3D_SIV_TRIANGLE_W_TESS_FACTOR, "finalTriWeq0EdgeTessFactor"},
618 {VKD3D_SIV_TRIANGLE_INNER_TESS_FACTOR, "finalTriInsideTessFactor"},
619 {VKD3D_SIV_LINE_DETAIL_TESS_FACTOR, "finalLineDetailTessFactor"},
620 {VKD3D_SIV_LINE_DENSITY_TESS_FACTOR, "finalLineDensityTessFactor"},
623 for (i = 0; i < ARRAY_SIZE(shader_input_sysval_semantic_names); ++i)
625 if (shader_input_sysval_semantic_names[i].sysval_semantic != semantic)
626 continue;
628 vkd3d_string_buffer_printf(&compiler->buffer, "%s%s%s",
629 prefix, shader_input_sysval_semantic_names[i].sysval_name, suffix);
630 return;
633 vkd3d_string_buffer_printf(&compiler->buffer, "%s%s<unhandled input sysval semantic %#x>%s%s",
634 prefix, compiler->colours.error, semantic, compiler->colours.reset, suffix);
637 static void shader_dump_resource_type(struct vkd3d_d3d_asm_compiler *compiler, enum vkd3d_shader_resource_type type)
639 static const char *const resource_type_names[] =
641 [VKD3D_SHADER_RESOURCE_NONE ] = "none",
642 [VKD3D_SHADER_RESOURCE_BUFFER ] = "buffer",
643 [VKD3D_SHADER_RESOURCE_TEXTURE_1D ] = "texture1d",
644 [VKD3D_SHADER_RESOURCE_TEXTURE_2D ] = "texture2d",
645 [VKD3D_SHADER_RESOURCE_TEXTURE_2DMS ] = "texture2dms",
646 [VKD3D_SHADER_RESOURCE_TEXTURE_3D ] = "texture3d",
647 [VKD3D_SHADER_RESOURCE_TEXTURE_CUBE ] = "texturecube",
648 [VKD3D_SHADER_RESOURCE_TEXTURE_1DARRAY ] = "texture1darray",
649 [VKD3D_SHADER_RESOURCE_TEXTURE_2DARRAY ] = "texture2darray",
650 [VKD3D_SHADER_RESOURCE_TEXTURE_2DMSARRAY] = "texture2dmsarray",
651 [VKD3D_SHADER_RESOURCE_TEXTURE_CUBEARRAY] = "texturecubearray",
654 if (type < ARRAY_SIZE(resource_type_names))
655 vkd3d_string_buffer_printf(&compiler->buffer, "%s", resource_type_names[type]);
656 else
657 vkd3d_string_buffer_printf(&compiler->buffer, "unknown");
660 static void shader_dump_data_type(struct vkd3d_d3d_asm_compiler *compiler, enum vkd3d_data_type type)
662 static const char *const data_type_names[] =
664 [VKD3D_DATA_FLOAT ] = "float",
665 [VKD3D_DATA_INT ] = "int",
666 [VKD3D_DATA_RESOURCE ] = "resource",
667 [VKD3D_DATA_SAMPLER ] = "sampler",
668 [VKD3D_DATA_UAV ] = "uav",
669 [VKD3D_DATA_UINT ] = "uint",
670 [VKD3D_DATA_UNORM ] = "unorm",
671 [VKD3D_DATA_SNORM ] = "snorm",
672 [VKD3D_DATA_OPAQUE ] = "opaque",
673 [VKD3D_DATA_MIXED ] = "mixed",
674 [VKD3D_DATA_DOUBLE ] = "double",
675 [VKD3D_DATA_CONTINUED] = "<continued>",
676 [VKD3D_DATA_UNUSED ] = "<unused>",
677 [VKD3D_DATA_UINT8 ] = "uint8",
678 [VKD3D_DATA_UINT64 ] = "uint64",
679 [VKD3D_DATA_BOOL ] = "bool",
680 [VKD3D_DATA_UINT16 ] = "uint16",
681 [VKD3D_DATA_HALF ] = "half",
684 const char *name;
686 if (type < ARRAY_SIZE(data_type_names))
687 name = data_type_names[type];
688 else
689 name = "<unknown>";
691 vkd3d_string_buffer_printf(&compiler->buffer, "%s", name);
694 static void shader_dump_resource_data_type(struct vkd3d_d3d_asm_compiler *compiler, const enum vkd3d_data_type *type)
696 int i;
698 vkd3d_string_buffer_printf(&compiler->buffer, "(");
700 for (i = 0; i < 4; i++)
702 vkd3d_string_buffer_printf(&compiler->buffer, "%s", i == 0 ? "" : ",");
703 shader_dump_data_type(compiler, type[i]);
706 vkd3d_string_buffer_printf(&compiler->buffer, ")");
709 static void shader_print_dcl_usage(struct vkd3d_d3d_asm_compiler *compiler,
710 const char *prefix, const struct vkd3d_shader_semantic *semantic, uint32_t flags, const char *suffix)
712 struct vkd3d_string_buffer *buffer = &compiler->buffer;
713 unsigned int usage_idx;
714 const char *usage;
715 bool indexed;
717 if (semantic->resource.reg.reg.type == VKD3DSPR_COMBINED_SAMPLER)
719 switch (semantic->resource_type)
721 case VKD3D_SHADER_RESOURCE_TEXTURE_2D:
722 usage = "2d";
723 break;
724 case VKD3D_SHADER_RESOURCE_TEXTURE_3D:
725 usage = "volume";
726 break;
727 case VKD3D_SHADER_RESOURCE_TEXTURE_CUBE:
728 usage = "cube";
729 break;
730 default:
731 vkd3d_string_buffer_printf(buffer, "%s%s<unhandled resource type %#x>%s%s",
732 prefix, compiler->colours.error, semantic->resource_type, compiler->colours.reset, suffix);
733 return;
736 vkd3d_string_buffer_printf(buffer, "%s%s%s", prefix, usage, suffix);
737 return;
740 if (semantic->resource.reg.reg.type == VKD3DSPR_RESOURCE || semantic->resource.reg.reg.type == VKD3DSPR_UAV)
742 vkd3d_string_buffer_printf(buffer, "%s", prefix);
743 if (semantic->resource.reg.reg.type == VKD3DSPR_RESOURCE)
744 vkd3d_string_buffer_printf(buffer, "resource_");
746 shader_dump_resource_type(compiler, semantic->resource_type);
747 if (semantic->resource_type == VKD3D_SHADER_RESOURCE_TEXTURE_2DMS
748 || semantic->resource_type == VKD3D_SHADER_RESOURCE_TEXTURE_2DMSARRAY)
750 vkd3d_string_buffer_printf(buffer, "(%u)", semantic->sample_count);
752 if (semantic->resource.reg.reg.type == VKD3DSPR_UAV)
753 shader_dump_uav_flags(compiler, flags);
754 vkd3d_string_buffer_printf(buffer, " ");
755 shader_dump_resource_data_type(compiler, semantic->resource_data_type);
756 vkd3d_string_buffer_printf(buffer, "%s", suffix);
757 return;
760 /* Pixel shaders 3.0 don't have usage semantics. */
761 if (!vkd3d_shader_ver_ge(&compiler->shader_version, 3, 0)
762 && compiler->shader_version.type == VKD3D_SHADER_TYPE_PIXEL)
763 return;
765 indexed = false;
766 usage_idx = semantic->usage_idx;
767 switch (semantic->usage)
769 case VKD3D_DECL_USAGE_POSITION:
770 usage = "position";
771 indexed = true;
772 break;
773 case VKD3D_DECL_USAGE_BLEND_INDICES:
774 usage = "blend";
775 break;
776 case VKD3D_DECL_USAGE_BLEND_WEIGHT:
777 usage = "weight";
778 break;
779 case VKD3D_DECL_USAGE_NORMAL:
780 usage = "normal";
781 indexed = true;
782 break;
783 case VKD3D_DECL_USAGE_PSIZE:
784 usage = "psize";
785 break;
786 case VKD3D_DECL_USAGE_COLOR:
787 if (semantic->usage_idx)
789 usage = "specular";
790 indexed = true;
791 --usage_idx;
792 break;
794 usage = "color";
795 break;
796 case VKD3D_DECL_USAGE_TEXCOORD:
797 usage = "texcoord";
798 indexed = true;
799 break;
800 case VKD3D_DECL_USAGE_TANGENT:
801 usage = "tangent";
802 break;
803 case VKD3D_DECL_USAGE_BINORMAL:
804 usage = "binormal";
805 break;
806 case VKD3D_DECL_USAGE_TESS_FACTOR:
807 usage = "tessfactor";
808 break;
809 case VKD3D_DECL_USAGE_POSITIONT:
810 usage = "positionT";
811 indexed = true;
812 break;
813 case VKD3D_DECL_USAGE_FOG:
814 usage = "fog";
815 break;
816 case VKD3D_DECL_USAGE_DEPTH:
817 usage = "depth";
818 break;
819 case VKD3D_DECL_USAGE_SAMPLE:
820 usage = "sample";
821 break;
822 default:
823 vkd3d_string_buffer_printf(buffer, "%s%s<unhandled usage %#x, index %u>%s%s",
824 prefix, compiler->colours.error, semantic->usage, usage_idx, compiler->colours.reset, suffix);
825 return;
828 if (indexed)
829 vkd3d_string_buffer_printf(buffer, "%s%s%u%s", prefix, usage, usage_idx, suffix);
830 else
831 vkd3d_string_buffer_printf(buffer, "%s%s%s", prefix, usage, suffix);
834 static void shader_print_src_param(struct vkd3d_d3d_asm_compiler *compiler,
835 const char *prefix, const struct vkd3d_shader_src_param *param, const char *suffix);
837 static void shader_print_float_literal(struct vkd3d_d3d_asm_compiler *compiler,
838 const char *prefix, float f, const char *suffix)
840 const char *sign = "";
842 if (isfinite(f) && signbit(f))
844 sign = "-";
845 f = -f;
848 vkd3d_string_buffer_printf(&compiler->buffer, "%s%s%s", prefix, sign, compiler->colours.literal);
849 vkd3d_string_buffer_print_f32(&compiler->buffer, f);
850 vkd3d_string_buffer_printf(&compiler->buffer, "%s%s", compiler->colours.reset, suffix);
853 static void shader_print_double_literal(struct vkd3d_d3d_asm_compiler *compiler,
854 const char *prefix, double d, const char *suffix)
856 const char *sign = "";
858 if (isfinite(d) && signbit(d))
860 sign = "-";
861 d = -d;
864 vkd3d_string_buffer_printf(&compiler->buffer, "%s%s%s", prefix, sign, compiler->colours.literal);
865 vkd3d_string_buffer_print_f64(&compiler->buffer, d);
866 vkd3d_string_buffer_printf(&compiler->buffer, "l%s%s", compiler->colours.reset, suffix);
869 static void shader_print_int_literal(struct vkd3d_d3d_asm_compiler *compiler,
870 const char *prefix, int i, const char *suffix)
872 if (i < 0)
873 vkd3d_string_buffer_printf(&compiler->buffer, "%s-%s%d%s%s",
874 prefix, compiler->colours.literal, -i, compiler->colours.reset, suffix);
875 else
876 vkd3d_string_buffer_printf(&compiler->buffer, "%s%s%d%s%s",
877 prefix, compiler->colours.literal, i, compiler->colours.reset, suffix);
880 static void shader_print_uint_literal(struct vkd3d_d3d_asm_compiler *compiler,
881 const char *prefix, unsigned int i, const char *suffix)
883 vkd3d_string_buffer_printf(&compiler->buffer, "%s%s%u%s%s",
884 prefix, compiler->colours.literal, i, compiler->colours.reset, suffix);
887 static void shader_print_uint64_literal(struct vkd3d_d3d_asm_compiler *compiler,
888 const char *prefix, uint64_t i, const char *suffix)
890 vkd3d_string_buffer_printf(&compiler->buffer, "%s%s%"PRIu64"%s%s",
891 prefix, compiler->colours.literal, i, compiler->colours.reset, suffix);
894 static void shader_print_hex_literal(struct vkd3d_d3d_asm_compiler *compiler,
895 const char *prefix, unsigned int i, const char *suffix)
897 vkd3d_string_buffer_printf(&compiler->buffer, "%s%s0x%08x%s%s",
898 prefix, compiler->colours.literal, i, compiler->colours.reset, suffix);
901 static void shader_print_bool_literal(struct vkd3d_d3d_asm_compiler *compiler,
902 const char *prefix, unsigned int b, const char *suffix)
904 vkd3d_string_buffer_printf(&compiler->buffer, "%s%s%s%s%s", prefix,
905 compiler->colours.literal, b ? "true" : "false", compiler->colours.reset, suffix);
908 static void shader_print_untyped_literal(struct vkd3d_d3d_asm_compiler *compiler,
909 const char *prefix, uint32_t u, const char *suffix)
911 union
913 uint32_t u;
914 float f;
915 } value;
916 unsigned int exponent = (u >> 23) & 0xff;
918 value.u = u;
920 if (exponent != 0 && exponent != 0xff)
921 return shader_print_float_literal(compiler, prefix, value.f, suffix);
923 if (u <= 10000)
924 return shader_print_uint_literal(compiler, prefix, value.u, suffix);
926 return shader_print_hex_literal(compiler, prefix, value.u, suffix);
929 static void shader_print_subscript(struct vkd3d_d3d_asm_compiler *compiler,
930 unsigned int offset, const struct vkd3d_shader_src_param *rel_addr)
932 if (rel_addr)
933 shader_print_src_param(compiler, "[", rel_addr, " + ");
934 shader_print_uint_literal(compiler, rel_addr ? "" : "[", offset, "]");
937 static void shader_print_subscript_range(struct vkd3d_d3d_asm_compiler *compiler,
938 unsigned int offset_first, unsigned int offset_last)
940 shader_print_uint_literal(compiler, "[", offset_first, ":");
941 if (offset_last != ~0u)
942 shader_print_uint_literal(compiler, "", offset_last, "]");
943 else
944 vkd3d_string_buffer_printf(&compiler->buffer, "*]");
947 static void shader_print_register(struct vkd3d_d3d_asm_compiler *compiler, const char *prefix,
948 const struct vkd3d_shader_register *reg, bool is_declaration, const char *suffix)
950 struct vkd3d_string_buffer *buffer = &compiler->buffer;
951 unsigned int offset = reg->idx[0].offset;
952 bool is_descriptor = false;
954 static const char * const rastout_reg_names[] = {"oPos", "oFog", "oPts"};
955 static const char * const misctype_reg_names[] = {"vPos", "vFace"};
957 vkd3d_string_buffer_printf(buffer, "%s%s", prefix,
958 reg->type == VKD3DSPR_LABEL ? compiler->colours.label : compiler->colours.reg);
959 switch (reg->type)
961 case VKD3DSPR_TEMP:
962 vkd3d_string_buffer_printf(buffer, "r");
963 break;
965 case VKD3DSPR_INPUT:
966 vkd3d_string_buffer_printf(buffer, "v");
967 break;
969 case VKD3DSPR_CONST:
970 case VKD3DSPR_CONST2:
971 case VKD3DSPR_CONST3:
972 case VKD3DSPR_CONST4:
973 vkd3d_string_buffer_printf(buffer, "c");
974 offset = shader_get_float_offset(reg->type, offset);
975 break;
977 case VKD3DSPR_TEXTURE: /* vs: case VKD3DSPR_ADDR */
978 vkd3d_string_buffer_printf(buffer, "%c",
979 compiler->shader_version.type == VKD3D_SHADER_TYPE_PIXEL ? 't' : 'a');
980 break;
982 case VKD3DSPR_RASTOUT:
983 vkd3d_string_buffer_printf(buffer, "%s", rastout_reg_names[offset]);
984 break;
986 case VKD3DSPR_COLOROUT:
987 vkd3d_string_buffer_printf(buffer, "oC");
988 break;
990 case VKD3DSPR_DEPTHOUT:
991 vkd3d_string_buffer_printf(buffer, "oDepth");
992 break;
994 case VKD3DSPR_DEPTHOUTGE:
995 vkd3d_string_buffer_printf(buffer, "oDepthGE");
996 break;
998 case VKD3DSPR_DEPTHOUTLE:
999 vkd3d_string_buffer_printf(buffer, "oDepthLE");
1000 break;
1002 case VKD3DSPR_ATTROUT:
1003 vkd3d_string_buffer_printf(buffer, "oD");
1004 break;
1006 case VKD3DSPR_TEXCRDOUT:
1007 /* Vertex shaders >= 3.0 use general purpose output registers
1008 * (VKD3DSPR_OUTPUT), which can include an address token. */
1009 if (vkd3d_shader_ver_ge(&compiler->shader_version, 3, 0))
1010 vkd3d_string_buffer_printf(buffer, "o");
1011 else
1012 vkd3d_string_buffer_printf(buffer, "oT");
1013 break;
1015 case VKD3DSPR_CONSTINT:
1016 vkd3d_string_buffer_printf(buffer, "i");
1017 break;
1019 case VKD3DSPR_CONSTBOOL:
1020 vkd3d_string_buffer_printf(buffer, "b");
1021 break;
1023 case VKD3DSPR_LABEL:
1024 vkd3d_string_buffer_printf(buffer, "l");
1025 break;
1027 case VKD3DSPR_LOOP:
1028 vkd3d_string_buffer_printf(buffer, "aL");
1029 break;
1031 case VKD3DSPR_COMBINED_SAMPLER:
1032 case VKD3DSPR_SAMPLER:
1033 vkd3d_string_buffer_printf(buffer, "s");
1034 is_descriptor = true;
1035 break;
1037 case VKD3DSPR_MISCTYPE:
1038 if (offset > 1)
1039 vkd3d_string_buffer_printf(buffer, "%s<unhandled misctype %#x>%s",
1040 compiler->colours.error, offset, compiler->colours.reset);
1041 else
1042 vkd3d_string_buffer_printf(buffer, "%s", misctype_reg_names[offset]);
1043 break;
1045 case VKD3DSPR_PREDICATE:
1046 vkd3d_string_buffer_printf(buffer, "p");
1047 break;
1049 case VKD3DSPR_IMMCONST:
1050 vkd3d_string_buffer_printf(buffer, "l");
1051 break;
1053 case VKD3DSPR_IMMCONST64:
1054 vkd3d_string_buffer_printf(buffer, "d");
1055 break;
1057 case VKD3DSPR_CONSTBUFFER:
1058 vkd3d_string_buffer_printf(buffer, "cb");
1059 is_descriptor = true;
1060 break;
1062 case VKD3DSPR_IMMCONSTBUFFER:
1063 vkd3d_string_buffer_printf(buffer, "icb");
1064 break;
1066 case VKD3DSPR_PRIMID:
1067 vkd3d_string_buffer_printf(buffer, "primID");
1068 break;
1070 case VKD3DSPR_NULL:
1071 vkd3d_string_buffer_printf(buffer, "null");
1072 break;
1074 case VKD3DSPR_RASTERIZER:
1075 vkd3d_string_buffer_printf(buffer, "rasterizer");
1076 break;
1078 case VKD3DSPR_RESOURCE:
1079 vkd3d_string_buffer_printf(buffer, "t");
1080 is_descriptor = true;
1081 break;
1083 case VKD3DSPR_UAV:
1084 vkd3d_string_buffer_printf(buffer, "u");
1085 is_descriptor = true;
1086 break;
1088 case VKD3DSPR_OUTPOINTID:
1089 vkd3d_string_buffer_printf(buffer, "vOutputControlPointID");
1090 break;
1092 case VKD3DSPR_FORKINSTID:
1093 vkd3d_string_buffer_printf(buffer, "vForkInstanceId");
1094 break;
1096 case VKD3DSPR_JOININSTID:
1097 vkd3d_string_buffer_printf(buffer, "vJoinInstanceId");
1098 break;
1100 case VKD3DSPR_INCONTROLPOINT:
1101 vkd3d_string_buffer_printf(buffer, "vicp");
1102 break;
1104 case VKD3DSPR_OUTCONTROLPOINT:
1105 vkd3d_string_buffer_printf(buffer, "vocp");
1106 break;
1108 case VKD3DSPR_PATCHCONST:
1109 vkd3d_string_buffer_printf(buffer, "vpc");
1110 break;
1112 case VKD3DSPR_TESSCOORD:
1113 vkd3d_string_buffer_printf(buffer, "vDomainLocation");
1114 break;
1116 case VKD3DSPR_GROUPSHAREDMEM:
1117 vkd3d_string_buffer_printf(buffer, "g");
1118 break;
1120 case VKD3DSPR_THREADID:
1121 vkd3d_string_buffer_printf(buffer, "vThreadID");
1122 break;
1124 case VKD3DSPR_THREADGROUPID:
1125 vkd3d_string_buffer_printf(buffer, "vThreadGroupID");
1126 break;
1128 case VKD3DSPR_LOCALTHREADID:
1129 vkd3d_string_buffer_printf(buffer, "vThreadIDInGroup");
1130 break;
1132 case VKD3DSPR_LOCALTHREADINDEX:
1133 vkd3d_string_buffer_printf(buffer, "vThreadIDInGroupFlattened");
1134 break;
1136 case VKD3DSPR_IDXTEMP:
1137 vkd3d_string_buffer_printf(buffer, "x");
1138 break;
1140 case VKD3DSPR_STREAM:
1141 vkd3d_string_buffer_printf(buffer, "m");
1142 break;
1144 case VKD3DSPR_FUNCTIONBODY:
1145 vkd3d_string_buffer_printf(buffer, "fb");
1146 break;
1148 case VKD3DSPR_FUNCTIONPOINTER:
1149 vkd3d_string_buffer_printf(buffer, "fp");
1150 break;
1152 case VKD3DSPR_COVERAGE:
1153 vkd3d_string_buffer_printf(buffer, "vCoverage");
1154 break;
1156 case VKD3DSPR_SAMPLEMASK:
1157 vkd3d_string_buffer_printf(buffer, "oMask");
1158 break;
1160 case VKD3DSPR_GSINSTID:
1161 vkd3d_string_buffer_printf(buffer, "vGSInstanceID");
1162 break;
1164 case VKD3DSPR_OUTSTENCILREF:
1165 vkd3d_string_buffer_printf(buffer, "oStencilRef");
1166 break;
1168 case VKD3DSPR_UNDEF:
1169 vkd3d_string_buffer_printf(buffer, "undef");
1170 break;
1172 case VKD3DSPR_SSA:
1173 vkd3d_string_buffer_printf(buffer, "sr");
1174 break;
1176 default:
1177 vkd3d_string_buffer_printf(buffer, "%s<unhandled register type %#x>%s",
1178 compiler->colours.error, reg->type, compiler->colours.reset);
1179 break;
1182 if (reg->type == VKD3DSPR_IMMCONST)
1184 bool untyped = false;
1186 switch (compiler->current->handler_idx)
1188 case VKD3DSIH_MOV:
1189 case VKD3DSIH_MOVC:
1190 untyped = true;
1191 break;
1193 default:
1194 break;
1197 vkd3d_string_buffer_printf(buffer, "%s(", compiler->colours.reset);
1198 switch (reg->dimension)
1200 case VSIR_DIMENSION_SCALAR:
1201 switch (reg->data_type)
1203 case VKD3D_DATA_FLOAT:
1204 if (untyped)
1205 shader_print_untyped_literal(compiler, "", reg->u.immconst_u32[0], "");
1206 else
1207 shader_print_float_literal(compiler, "", reg->u.immconst_f32[0], "");
1208 break;
1209 case VKD3D_DATA_INT:
1210 shader_print_int_literal(compiler, "", reg->u.immconst_u32[0], "");
1211 break;
1212 case VKD3D_DATA_RESOURCE:
1213 case VKD3D_DATA_SAMPLER:
1214 case VKD3D_DATA_UINT:
1215 shader_print_uint_literal(compiler, "", reg->u.immconst_u32[0], "");
1216 break;
1217 default:
1218 vkd3d_string_buffer_printf(buffer, "%s<unhandled data type %#x>%s",
1219 compiler->colours.error, reg->data_type, compiler->colours.reset);
1220 break;
1222 break;
1224 case VSIR_DIMENSION_VEC4:
1225 switch (reg->data_type)
1227 case VKD3D_DATA_FLOAT:
1228 if (untyped)
1230 shader_print_untyped_literal(compiler, "", reg->u.immconst_u32[0], "");
1231 shader_print_untyped_literal(compiler, ", ", reg->u.immconst_u32[1], "");
1232 shader_print_untyped_literal(compiler, ", ", reg->u.immconst_u32[2], "");
1233 shader_print_untyped_literal(compiler, ", ", reg->u.immconst_u32[3], "");
1235 else
1237 shader_print_float_literal(compiler, "", reg->u.immconst_f32[0], "");
1238 shader_print_float_literal(compiler, ", ", reg->u.immconst_f32[1], "");
1239 shader_print_float_literal(compiler, ", ", reg->u.immconst_f32[2], "");
1240 shader_print_float_literal(compiler, ", ", reg->u.immconst_f32[3], "");
1242 break;
1243 case VKD3D_DATA_INT:
1244 shader_print_int_literal(compiler, "", reg->u.immconst_u32[0], "");
1245 shader_print_int_literal(compiler, ", ", reg->u.immconst_u32[1], "");
1246 shader_print_int_literal(compiler, ", ", reg->u.immconst_u32[2], "");
1247 shader_print_int_literal(compiler, ", ", reg->u.immconst_u32[3], "");
1248 break;
1249 case VKD3D_DATA_RESOURCE:
1250 case VKD3D_DATA_SAMPLER:
1251 case VKD3D_DATA_UINT:
1252 shader_print_uint_literal(compiler, "", reg->u.immconst_u32[0], "");
1253 shader_print_uint_literal(compiler, ", ", reg->u.immconst_u32[1], "");
1254 shader_print_uint_literal(compiler, ", ", reg->u.immconst_u32[2], "");
1255 shader_print_uint_literal(compiler, ", ", reg->u.immconst_u32[3], "");
1256 break;
1257 default:
1258 vkd3d_string_buffer_printf(buffer, "%s<unhandled data type %#x>%s",
1259 compiler->colours.error, reg->data_type, compiler->colours.reset);
1260 break;
1262 break;
1264 default:
1265 vkd3d_string_buffer_printf(buffer, "%s<unhandled immconst dimension %#x>%s",
1266 compiler->colours.error, reg->dimension, compiler->colours.reset);
1267 break;
1269 vkd3d_string_buffer_printf(buffer, ")");
1271 else if (reg->type == VKD3DSPR_IMMCONST64)
1273 vkd3d_string_buffer_printf(buffer, "%s(", compiler->colours.reset);
1274 /* A double2 vector is treated as a float4 vector in enum vsir_dimension. */
1275 if (reg->dimension == VSIR_DIMENSION_SCALAR || reg->dimension == VSIR_DIMENSION_VEC4)
1277 if (reg->data_type == VKD3D_DATA_DOUBLE)
1279 shader_print_double_literal(compiler, "", reg->u.immconst_f64[0], "");
1280 if (reg->dimension == VSIR_DIMENSION_VEC4)
1281 shader_print_double_literal(compiler, ", ", reg->u.immconst_f64[1], "");
1283 else if (reg->data_type == VKD3D_DATA_UINT64)
1285 shader_print_uint64_literal(compiler, "", reg->u.immconst_u64[0], "");
1286 if (reg->dimension == VSIR_DIMENSION_VEC4)
1287 shader_print_uint64_literal(compiler, "", reg->u.immconst_u64[1], "");
1289 else
1291 vkd3d_string_buffer_printf(buffer, "%s<unhandled data type %#x>%s",
1292 compiler->colours.error, reg->data_type, compiler->colours.reset);
1295 else
1297 vkd3d_string_buffer_printf(buffer, "%s<unhandled immconst64 dimension %#x>%s",
1298 compiler->colours.error, reg->dimension, compiler->colours.reset);
1300 vkd3d_string_buffer_printf(buffer, ")");
1302 else if (reg->type != VKD3DSPR_RASTOUT
1303 && reg->type != VKD3DSPR_MISCTYPE
1304 && reg->type != VKD3DSPR_NULL
1305 && reg->type != VKD3DSPR_DEPTHOUT)
1307 if (offset != ~0u)
1309 bool is_sm_5_1 = vkd3d_shader_ver_ge(&compiler->shader_version, 5, 1);
1311 if (reg->idx[0].rel_addr || reg->type == VKD3DSPR_IMMCONSTBUFFER
1312 || reg->type == VKD3DSPR_INCONTROLPOINT || (reg->type == VKD3DSPR_INPUT
1313 && (compiler->shader_version.type == VKD3D_SHADER_TYPE_GEOMETRY
1314 || compiler->shader_version.type == VKD3D_SHADER_TYPE_HULL)))
1316 vkd3d_string_buffer_printf(buffer, "%s", compiler->colours.reset);
1317 shader_print_subscript(compiler, offset, reg->idx[0].rel_addr);
1319 else
1321 vkd3d_string_buffer_printf(buffer, "%u%s", offset, compiler->colours.reset);
1324 /* For sm 5.1 descriptor declarations we need to print the register range instead of
1325 * a single register index. */
1326 if (is_descriptor && is_declaration && is_sm_5_1)
1328 shader_print_subscript_range(compiler, reg->idx[1].offset, reg->idx[2].offset);
1330 else if (reg->type != VKD3DSPR_SSA)
1332 /* For descriptors in sm < 5.1 we move the reg->idx values up one slot
1333 * to normalise with 5.1.
1334 * Here we should ignore it if it's a descriptor in sm < 5.1. */
1335 if (reg->idx[1].offset != ~0u && (!is_descriptor || is_sm_5_1))
1336 shader_print_subscript(compiler, reg->idx[1].offset, reg->idx[1].rel_addr);
1338 if (reg->idx[2].offset != ~0u)
1339 shader_print_subscript(compiler, reg->idx[2].offset, reg->idx[2].rel_addr);
1342 else
1344 vkd3d_string_buffer_printf(buffer, "%s", compiler->colours.reset);
1347 if (reg->type == VKD3DSPR_FUNCTIONPOINTER)
1348 shader_print_subscript(compiler, reg->u.fp_body_idx, NULL);
1350 else
1352 vkd3d_string_buffer_printf(buffer, "%s", compiler->colours.reset);
1354 vkd3d_string_buffer_printf(buffer, "%s", suffix);
1357 static void shader_print_precision(struct vkd3d_d3d_asm_compiler *compiler, const struct vkd3d_shader_register *reg)
1359 struct vkd3d_string_buffer *buffer = &compiler->buffer;
1360 const char *precision;
1362 if (reg->precision == VKD3D_SHADER_REGISTER_PRECISION_DEFAULT)
1363 return;
1365 switch (reg->precision)
1367 case VKD3D_SHADER_REGISTER_PRECISION_MIN_FLOAT_16:
1368 precision = "min16f";
1369 break;
1371 case VKD3D_SHADER_REGISTER_PRECISION_MIN_FLOAT_10:
1372 precision = "min2_8f";
1373 break;
1375 case VKD3D_SHADER_REGISTER_PRECISION_MIN_INT_16:
1376 precision = "min16i";
1377 break;
1379 case VKD3D_SHADER_REGISTER_PRECISION_MIN_UINT_16:
1380 precision = "min16u";
1381 break;
1383 default:
1384 vkd3d_string_buffer_printf(buffer, " {%s<unhandled precision %#x>%s}",
1385 compiler->colours.error, reg->precision, compiler->colours.reset);
1386 return;
1388 vkd3d_string_buffer_printf(buffer, " {%s%s%s}", compiler->colours.modifier, precision, compiler->colours.reset);
1391 static void shader_print_non_uniform(struct vkd3d_d3d_asm_compiler *compiler, const struct vkd3d_shader_register *reg)
1393 if (reg->non_uniform)
1394 vkd3d_string_buffer_printf(&compiler->buffer, " {%snonuniform%s}",
1395 compiler->colours.modifier, compiler->colours.reset);
1398 static void shader_print_reg_type(struct vkd3d_d3d_asm_compiler *compiler,
1399 const char *prefix, const struct vkd3d_shader_register *reg, const char *suffix)
1401 static const char *dimensions[] =
1403 [VSIR_DIMENSION_NONE] = "",
1404 [VSIR_DIMENSION_SCALAR] = "s:",
1405 [VSIR_DIMENSION_VEC4] = "v4:",
1408 struct vkd3d_string_buffer *buffer = &compiler->buffer;
1409 const char *dimension;
1411 if (!(compiler->flags & VSIR_ASM_FLAG_DUMP_TYPES))
1413 vkd3d_string_buffer_printf(buffer, "%s%s", prefix, suffix);
1414 return;
1417 if (reg->data_type == VKD3D_DATA_UNUSED)
1418 return;
1420 if (reg->dimension < ARRAY_SIZE(dimensions))
1421 dimension = dimensions[reg->dimension];
1422 else
1423 dimension = "??";
1425 vkd3d_string_buffer_printf(buffer, "%s <%s", prefix, dimension);
1426 shader_dump_data_type(compiler, reg->data_type);
1427 vkd3d_string_buffer_printf(buffer, ">%s", suffix);
1430 static void shader_print_write_mask(struct vkd3d_d3d_asm_compiler *compiler,
1431 const char *prefix, uint32_t mask, const char *suffix)
1433 unsigned int i = 0;
1434 char buffer[5];
1436 if (mask == 0)
1438 vkd3d_string_buffer_printf(&compiler->buffer, "%s%s", prefix, suffix);
1439 return;
1442 if (mask & VKD3DSP_WRITEMASK_0)
1443 buffer[i++] = 'x';
1444 if (mask & VKD3DSP_WRITEMASK_1)
1445 buffer[i++] = 'y';
1446 if (mask & VKD3DSP_WRITEMASK_2)
1447 buffer[i++] = 'z';
1448 if (mask & VKD3DSP_WRITEMASK_3)
1449 buffer[i++] = 'w';
1450 buffer[i++] = '\0';
1452 vkd3d_string_buffer_printf(&compiler->buffer, "%s.%s%s%s%s", prefix,
1453 compiler->colours.write_mask, buffer, compiler->colours.reset, suffix);
1456 static void shader_print_dst_param(struct vkd3d_d3d_asm_compiler *compiler,
1457 const char *prefix, const struct vkd3d_shader_dst_param *param, bool is_declaration, const char *suffix)
1459 uint32_t write_mask = param->write_mask;
1461 shader_print_register(compiler, prefix, &param->reg, is_declaration, "");
1463 if (write_mask && param->reg.dimension == VSIR_DIMENSION_VEC4)
1465 if (data_type_is_64_bit(param->reg.data_type))
1466 write_mask = vsir_write_mask_32_from_64(write_mask);
1468 shader_print_write_mask(compiler, "", write_mask, "");
1471 shader_print_precision(compiler, &param->reg);
1472 shader_print_non_uniform(compiler, &param->reg);
1473 shader_print_reg_type(compiler, "", &param->reg, suffix);
1476 static void shader_print_src_param(struct vkd3d_d3d_asm_compiler *compiler,
1477 const char *prefix, const struct vkd3d_shader_src_param *param, const char *suffix)
1479 enum vkd3d_shader_src_modifier src_modifier = param->modifiers;
1480 struct vkd3d_string_buffer *buffer = &compiler->buffer;
1481 uint32_t swizzle = param->swizzle;
1482 const char *modifier = "";
1483 bool is_abs = false;
1485 if (src_modifier == VKD3DSPSM_NEG
1486 || src_modifier == VKD3DSPSM_BIASNEG
1487 || src_modifier == VKD3DSPSM_SIGNNEG
1488 || src_modifier == VKD3DSPSM_X2NEG
1489 || src_modifier == VKD3DSPSM_ABSNEG)
1490 modifier = "-";
1491 else if (src_modifier == VKD3DSPSM_COMP)
1492 modifier = "1-";
1493 else if (src_modifier == VKD3DSPSM_NOT)
1494 modifier = "!";
1495 vkd3d_string_buffer_printf(buffer, "%s%s", prefix, modifier);
1497 if (src_modifier == VKD3DSPSM_ABS || src_modifier == VKD3DSPSM_ABSNEG)
1498 is_abs = true;
1500 shader_print_register(compiler, is_abs ? "|" : "", &param->reg, false, "");
1502 switch (src_modifier)
1504 case VKD3DSPSM_NONE:
1505 case VKD3DSPSM_NEG:
1506 case VKD3DSPSM_COMP:
1507 case VKD3DSPSM_ABS:
1508 case VKD3DSPSM_ABSNEG:
1509 case VKD3DSPSM_NOT:
1510 break;
1511 case VKD3DSPSM_BIAS:
1512 case VKD3DSPSM_BIASNEG:
1513 vkd3d_string_buffer_printf(buffer, "_bias");
1514 break;
1515 case VKD3DSPSM_SIGN:
1516 case VKD3DSPSM_SIGNNEG:
1517 vkd3d_string_buffer_printf(buffer, "_bx2");
1518 break;
1519 case VKD3DSPSM_X2:
1520 case VKD3DSPSM_X2NEG:
1521 vkd3d_string_buffer_printf(buffer, "_x2");
1522 break;
1523 case VKD3DSPSM_DZ:
1524 vkd3d_string_buffer_printf(buffer, "_dz");
1525 break;
1526 case VKD3DSPSM_DW:
1527 vkd3d_string_buffer_printf(buffer, "_dw");
1528 break;
1529 default:
1530 vkd3d_string_buffer_printf(buffer, "_%s<unhandled modifier %#x>%s",
1531 compiler->colours.error, src_modifier, compiler->colours.reset);
1532 break;
1535 if (param->reg.type != VKD3DSPR_IMMCONST && param->reg.type != VKD3DSPR_IMMCONST64
1536 && param->reg.dimension == VSIR_DIMENSION_VEC4)
1538 static const char swizzle_chars[] = "xyzw";
1540 unsigned int swizzle_x, swizzle_y, swizzle_z, swizzle_w;
1542 if (data_type_is_64_bit(param->reg.data_type))
1543 swizzle = vsir_swizzle_32_from_64(swizzle);
1545 swizzle_x = vsir_swizzle_get_component(swizzle, 0);
1546 swizzle_y = vsir_swizzle_get_component(swizzle, 1);
1547 swizzle_z = vsir_swizzle_get_component(swizzle, 2);
1548 swizzle_w = vsir_swizzle_get_component(swizzle, 3);
1550 if (swizzle_x == swizzle_y && swizzle_x == swizzle_z && swizzle_x == swizzle_w)
1551 vkd3d_string_buffer_printf(buffer, ".%s%c%s", compiler->colours.swizzle,
1552 swizzle_chars[swizzle_x], compiler->colours.reset);
1553 else
1554 vkd3d_string_buffer_printf(buffer, ".%s%c%c%c%c%s", compiler->colours.swizzle,
1555 swizzle_chars[swizzle_x], swizzle_chars[swizzle_y],
1556 swizzle_chars[swizzle_z], swizzle_chars[swizzle_w], compiler->colours.reset);
1559 if (is_abs)
1560 vkd3d_string_buffer_printf(buffer, "|");
1562 shader_print_precision(compiler, &param->reg);
1563 shader_print_non_uniform(compiler, &param->reg);
1564 shader_print_reg_type(compiler, "", &param->reg, suffix);
1567 static void shader_dump_ins_modifiers(struct vkd3d_d3d_asm_compiler *compiler,
1568 const struct vkd3d_shader_dst_param *dst)
1570 struct vkd3d_string_buffer *buffer = &compiler->buffer;
1571 uint32_t mmask = dst->modifiers;
1573 switch (dst->shift)
1575 case 0: break;
1576 case 13: shader_addline(buffer, "_d8"); break;
1577 case 14: shader_addline(buffer, "_d4"); break;
1578 case 15: shader_addline(buffer, "_d2"); break;
1579 case 1: shader_addline(buffer, "_x2"); break;
1580 case 2: shader_addline(buffer, "_x4"); break;
1581 case 3: shader_addline(buffer, "_x8"); break;
1582 default: shader_addline(buffer, "_unhandled_shift(%d)", dst->shift); break;
1585 if (mmask & VKD3DSPDM_SATURATE) shader_addline(buffer, "_sat");
1586 if (mmask & VKD3DSPDM_PARTIALPRECISION) shader_addline(buffer, "_pp");
1587 if (mmask & VKD3DSPDM_MSAMPCENTROID) shader_addline(buffer, "_centroid");
1589 mmask &= ~VKD3DSPDM_MASK;
1590 if (mmask) FIXME("Unrecognised modifier %#x.\n", mmask);
1593 static void shader_dump_primitive_type(struct vkd3d_d3d_asm_compiler *compiler,
1594 const struct vkd3d_shader_primitive_type *primitive_type)
1596 struct vkd3d_string_buffer *buffer = &compiler->buffer;
1598 switch (primitive_type->type)
1600 case VKD3D_PT_UNDEFINED:
1601 shader_addline(buffer, "undefined");
1602 break;
1603 case VKD3D_PT_POINTLIST:
1604 shader_addline(buffer, "pointlist");
1605 break;
1606 case VKD3D_PT_LINELIST:
1607 shader_addline(buffer, "linelist");
1608 break;
1609 case VKD3D_PT_LINESTRIP:
1610 shader_addline(buffer, "linestrip");
1611 break;
1612 case VKD3D_PT_TRIANGLELIST:
1613 shader_addline(buffer, "trianglelist");
1614 break;
1615 case VKD3D_PT_TRIANGLESTRIP:
1616 shader_addline(buffer, "trianglestrip");
1617 break;
1618 case VKD3D_PT_TRIANGLEFAN:
1619 shader_addline(buffer, "trianglefan");
1620 break;
1621 case VKD3D_PT_LINELIST_ADJ:
1622 shader_addline(buffer, "linelist_adj");
1623 break;
1624 case VKD3D_PT_LINESTRIP_ADJ:
1625 shader_addline(buffer, "linestrip_adj");
1626 break;
1627 case VKD3D_PT_TRIANGLELIST_ADJ:
1628 shader_addline(buffer, "trianglelist_adj");
1629 break;
1630 case VKD3D_PT_TRIANGLESTRIP_ADJ:
1631 shader_addline(buffer, "trianglestrip_adj");
1632 break;
1633 case VKD3D_PT_PATCH:
1634 shader_addline(buffer, "patch%u", primitive_type->patch_vertex_count);
1635 break;
1636 default:
1637 shader_addline(buffer, "<unrecognized_primitive_type %#x>", primitive_type->type);
1638 break;
1642 static void shader_dump_interpolation_mode(struct vkd3d_d3d_asm_compiler *compiler,
1643 enum vkd3d_shader_interpolation_mode interpolation_mode)
1645 struct vkd3d_string_buffer *buffer = &compiler->buffer;
1647 switch (interpolation_mode)
1649 case VKD3DSIM_CONSTANT:
1650 shader_addline(buffer, "constant");
1651 break;
1652 case VKD3DSIM_LINEAR:
1653 shader_addline(buffer, "linear");
1654 break;
1655 case VKD3DSIM_LINEAR_CENTROID:
1656 shader_addline(buffer, "linear centroid");
1657 break;
1658 case VKD3DSIM_LINEAR_NOPERSPECTIVE:
1659 shader_addline(buffer, "linear noperspective");
1660 break;
1661 case VKD3DSIM_LINEAR_SAMPLE:
1662 shader_addline(buffer, "linear sample");
1663 break;
1664 case VKD3DSIM_LINEAR_NOPERSPECTIVE_CENTROID:
1665 shader_addline(buffer, "linear noperspective centroid");
1666 break;
1667 case VKD3DSIM_LINEAR_NOPERSPECTIVE_SAMPLE:
1668 shader_addline(buffer, "linear noperspective sample");
1669 break;
1670 default:
1671 shader_addline(buffer, "<unrecognized_interpolation_mode %#x>", interpolation_mode);
1672 break;
1676 const char *shader_get_type_prefix(enum vkd3d_shader_type type)
1678 switch (type)
1680 case VKD3D_SHADER_TYPE_VERTEX:
1681 return "vs";
1683 case VKD3D_SHADER_TYPE_HULL:
1684 return "hs";
1686 case VKD3D_SHADER_TYPE_DOMAIN:
1687 return "ds";
1689 case VKD3D_SHADER_TYPE_GEOMETRY:
1690 return "gs";
1692 case VKD3D_SHADER_TYPE_PIXEL:
1693 return "ps";
1695 case VKD3D_SHADER_TYPE_COMPUTE:
1696 return "cs";
1698 case VKD3D_SHADER_TYPE_EFFECT:
1699 return "fx";
1701 case VKD3D_SHADER_TYPE_TEXTURE:
1702 return "tx";
1704 case VKD3D_SHADER_TYPE_LIBRARY:
1705 return "lib";
1707 default:
1708 FIXME("Unhandled shader type %#x.\n", type);
1709 return "unknown";
1713 static void shader_dump_instruction_flags(struct vkd3d_d3d_asm_compiler *compiler,
1714 const struct vkd3d_shader_instruction *ins)
1716 struct vkd3d_string_buffer *buffer = &compiler->buffer;
1718 switch (ins->handler_idx)
1720 case VKD3DSIH_BREAKP:
1721 case VKD3DSIH_CONTINUEP:
1722 case VKD3DSIH_DISCARD:
1723 case VKD3DSIH_IF:
1724 case VKD3DSIH_RETP:
1725 switch (ins->flags)
1727 case VKD3D_SHADER_CONDITIONAL_OP_NZ: shader_addline(buffer, "_nz"); break;
1728 case VKD3D_SHADER_CONDITIONAL_OP_Z: shader_addline(buffer, "_z"); break;
1729 default: shader_addline(buffer, "_unrecognized(%#x)", ins->flags); break;
1731 break;
1733 case VKD3DSIH_IFC:
1734 case VKD3DSIH_BREAKC:
1735 switch (ins->flags)
1737 case VKD3D_SHADER_REL_OP_GT: shader_addline(buffer, "_gt"); break;
1738 case VKD3D_SHADER_REL_OP_EQ: shader_addline(buffer, "_eq"); break;
1739 case VKD3D_SHADER_REL_OP_GE: shader_addline(buffer, "_ge"); break;
1740 case VKD3D_SHADER_REL_OP_LT: shader_addline(buffer, "_lt"); break;
1741 case VKD3D_SHADER_REL_OP_NE: shader_addline(buffer, "_ne"); break;
1742 case VKD3D_SHADER_REL_OP_LE: shader_addline(buffer, "_le"); break;
1743 default: shader_addline(buffer, "_(%u)", ins->flags);
1745 break;
1747 case VKD3DSIH_RESINFO:
1748 switch (ins->flags)
1750 case VKD3DSI_NONE: break;
1751 case VKD3DSI_RESINFO_RCP_FLOAT: shader_addline(buffer, "_rcpFloat"); break;
1752 case VKD3DSI_RESINFO_UINT: shader_addline(buffer, "_uint"); break;
1753 default: shader_addline(buffer, "_unrecognized(%#x)", ins->flags);
1755 break;
1757 case VKD3DSIH_SAMPLE_INFO:
1758 switch (ins->flags)
1760 case VKD3DSI_NONE: break;
1761 case VKD3DSI_SAMPLE_INFO_UINT: shader_addline(buffer, "_uint"); break;
1762 default: shader_addline(buffer, "_unrecognized(%#x)", ins->flags);
1764 break;
1766 case VKD3DSIH_IMM_ATOMIC_CMP_EXCH:
1767 case VKD3DSIH_IMM_ATOMIC_IADD:
1768 case VKD3DSIH_IMM_ATOMIC_AND:
1769 case VKD3DSIH_IMM_ATOMIC_IMAX:
1770 case VKD3DSIH_IMM_ATOMIC_IMIN:
1771 case VKD3DSIH_IMM_ATOMIC_OR:
1772 case VKD3DSIH_IMM_ATOMIC_UMAX:
1773 case VKD3DSIH_IMM_ATOMIC_UMIN:
1774 case VKD3DSIH_IMM_ATOMIC_EXCH:
1775 case VKD3DSIH_IMM_ATOMIC_XOR:
1776 shader_dump_atomic_op_flags(compiler, ins->flags);
1777 break;
1779 case VKD3DSIH_SYNC:
1780 shader_dump_sync_flags(compiler, ins->flags);
1781 break;
1783 case VKD3DSIH_TEX:
1784 if (vkd3d_shader_ver_ge(&compiler->shader_version, 2, 0) && (ins->flags & VKD3DSI_TEXLD_PROJECT))
1785 shader_addline(buffer, "p");
1786 break;
1788 case VKD3DSIH_ISHL:
1789 case VKD3DSIH_ISHR:
1790 case VKD3DSIH_USHR:
1791 if (ins->flags & VKD3DSI_SHIFT_UNMASKED)
1792 shader_addline(buffer, "_unmasked");
1793 /* fall through */
1794 default:
1795 shader_dump_precise_flags(compiler, ins->flags);
1796 break;
1800 static void shader_dump_register_space(struct vkd3d_d3d_asm_compiler *compiler, unsigned int register_space)
1802 if (vkd3d_shader_ver_ge(&compiler->shader_version, 5, 1))
1803 shader_print_uint_literal(compiler, ", space=", register_space, "");
1806 static void shader_print_opcode(struct vkd3d_d3d_asm_compiler *compiler, enum vkd3d_shader_opcode opcode)
1808 vkd3d_string_buffer_printf(&compiler->buffer, "%s%s%s", compiler->colours.opcode,
1809 shader_opcode_names[opcode], compiler->colours.reset);
1812 static void shader_dump_icb(struct vkd3d_d3d_asm_compiler *compiler,
1813 const struct vkd3d_shader_immediate_constant_buffer *icb)
1815 struct vkd3d_string_buffer *buffer = &compiler->buffer;
1816 unsigned int i, j;
1818 vkd3d_string_buffer_printf(buffer, " {\n");
1819 if (icb->component_count == 1)
1821 for (i = 0; i < icb->element_count; )
1823 for (j = 0; i < icb->element_count && j < 4; ++i, ++j)
1824 shader_print_hex_literal(compiler, !j ? " " : ", ", icb->data[i], "");
1825 vkd3d_string_buffer_printf(buffer, "\n");
1828 else
1830 assert(icb->component_count == VKD3D_VEC4_SIZE);
1831 for (i = 0; i < icb->element_count; ++i)
1833 shader_print_hex_literal(compiler, " {", icb->data[4 * i + 0], "");
1834 shader_print_hex_literal(compiler, ", ", icb->data[4 * i + 1], "");
1835 shader_print_hex_literal(compiler, ", ", icb->data[4 * i + 2], "");
1836 shader_print_hex_literal(compiler, ", ", icb->data[4 * i + 3], "},\n");
1839 shader_addline(buffer, "}");
1842 static void shader_dump_instruction(struct vkd3d_d3d_asm_compiler *compiler,
1843 const struct vkd3d_shader_instruction *ins)
1845 struct vkd3d_string_buffer *buffer = &compiler->buffer;
1846 unsigned int i;
1848 compiler->current = ins;
1850 if (ins->predicate)
1851 shader_print_src_param(compiler, "(", ins->predicate, ") ");
1853 /* PixWin marks instructions with the coissue flag with a '+' */
1854 if (ins->coissue)
1855 vkd3d_string_buffer_printf(buffer, "+");
1857 shader_print_opcode(compiler, ins->handler_idx);
1859 switch (ins->handler_idx)
1861 case VKD3DSIH_DCL:
1862 case VKD3DSIH_DCL_UAV_TYPED:
1863 vkd3d_string_buffer_printf(buffer, "%s", compiler->colours.opcode);
1864 shader_print_dcl_usage(compiler, "_", &ins->declaration.semantic, ins->flags, "");
1865 shader_dump_ins_modifiers(compiler, &ins->declaration.semantic.resource.reg);
1866 vkd3d_string_buffer_printf(buffer, "%s", compiler->colours.reset);
1867 shader_print_register(compiler, " ", &ins->declaration.semantic.resource.reg.reg, true, "");
1868 shader_dump_register_space(compiler, ins->declaration.semantic.resource.range.space);
1869 break;
1871 case VKD3DSIH_DCL_CONSTANT_BUFFER:
1872 shader_print_register(compiler, " ", &ins->declaration.cb.src.reg, true, "");
1873 if (vkd3d_shader_ver_ge(&compiler->shader_version, 6, 0))
1874 shader_print_subscript(compiler, ins->declaration.cb.size, NULL);
1875 else if (vkd3d_shader_ver_ge(&compiler->shader_version, 5, 1))
1876 shader_print_subscript(compiler, ins->declaration.cb.size / VKD3D_VEC4_SIZE / sizeof(float), NULL);
1877 shader_addline(buffer, ", %s",
1878 ins->flags & VKD3DSI_INDEXED_DYNAMIC ? "dynamicIndexed" : "immediateIndexed");
1879 shader_dump_register_space(compiler, ins->declaration.cb.range.space);
1880 break;
1882 case VKD3DSIH_DCL_FUNCTION_BODY:
1883 vkd3d_string_buffer_printf(buffer, " fb%u", ins->declaration.index);
1884 break;
1886 case VKD3DSIH_DCL_FUNCTION_TABLE:
1887 vkd3d_string_buffer_printf(buffer, " ft%u = {...}", ins->declaration.index);
1888 break;
1890 case VKD3DSIH_DCL_GLOBAL_FLAGS:
1891 vkd3d_string_buffer_printf(buffer, " ");
1892 shader_dump_global_flags(compiler, ins->declaration.global_flags);
1893 break;
1895 case VKD3DSIH_DCL_HS_MAX_TESSFACTOR:
1896 shader_print_float_literal(compiler, " ", ins->declaration.max_tessellation_factor, "");
1897 break;
1899 case VKD3DSIH_DCL_IMMEDIATE_CONSTANT_BUFFER:
1900 shader_dump_icb(compiler, ins->declaration.icb);
1901 break;
1903 case VKD3DSIH_DCL_INDEX_RANGE:
1904 shader_print_dst_param(compiler, " ", &ins->declaration.index_range.dst, true, "");
1905 shader_print_uint_literal(compiler, " ", ins->declaration.index_range.register_count, "");
1906 break;
1908 case VKD3DSIH_DCL_INDEXABLE_TEMP:
1909 vkd3d_string_buffer_printf(buffer, " %sx%u%s", compiler->colours.reg,
1910 ins->declaration.indexable_temp.register_idx, compiler->colours.reset);
1911 shader_print_subscript(compiler, ins->declaration.indexable_temp.register_size, NULL);
1912 shader_print_uint_literal(compiler, ", ", ins->declaration.indexable_temp.component_count, "");
1913 if (ins->declaration.indexable_temp.alignment)
1914 shader_print_uint_literal(compiler, ", align ", ins->declaration.indexable_temp.alignment, "");
1915 if (ins->declaration.indexable_temp.initialiser)
1916 shader_dump_icb(compiler, ins->declaration.indexable_temp.initialiser);
1917 break;
1919 case VKD3DSIH_DCL_INPUT_PS:
1920 vkd3d_string_buffer_printf(buffer, " ");
1921 shader_dump_interpolation_mode(compiler, ins->flags);
1922 shader_print_dst_param(compiler, " ", &ins->declaration.dst, true, "");
1923 break;
1925 case VKD3DSIH_DCL_INPUT_PS_SGV:
1926 case VKD3DSIH_DCL_INPUT_SGV:
1927 case VKD3DSIH_DCL_INPUT_SIV:
1928 case VKD3DSIH_DCL_OUTPUT_SIV:
1929 shader_print_dst_param(compiler, " ", &ins->declaration.register_semantic.reg, true, "");
1930 shader_print_input_sysval_semantic(compiler, ", ", ins->declaration.register_semantic.sysval_semantic, "");
1931 break;
1933 case VKD3DSIH_DCL_INPUT_PS_SIV:
1934 vkd3d_string_buffer_printf(buffer, " ");
1935 shader_dump_interpolation_mode(compiler, ins->flags);
1936 shader_print_dst_param(compiler, " ", &ins->declaration.register_semantic.reg, true, "");
1937 shader_print_input_sysval_semantic(compiler, ", ", ins->declaration.register_semantic.sysval_semantic, "");
1938 break;
1940 case VKD3DSIH_DCL_INPUT:
1941 case VKD3DSIH_DCL_OUTPUT:
1942 shader_print_dst_param(compiler, " ", &ins->declaration.dst, true, "");
1943 break;
1945 case VKD3DSIH_DCL_INPUT_PRIMITIVE:
1946 case VKD3DSIH_DCL_OUTPUT_TOPOLOGY:
1947 vkd3d_string_buffer_printf(buffer, " ");
1948 shader_dump_primitive_type(compiler, &ins->declaration.primitive_type);
1949 break;
1951 case VKD3DSIH_DCL_INTERFACE:
1952 vkd3d_string_buffer_printf(buffer, " fp%u", ins->declaration.fp.index);
1953 shader_print_subscript(compiler, ins->declaration.fp.array_size, NULL);
1954 shader_print_subscript(compiler, ins->declaration.fp.body_count, NULL);
1955 vkd3d_string_buffer_printf(buffer, " = {...}");
1956 break;
1958 case VKD3DSIH_DCL_RESOURCE_RAW:
1959 shader_print_dst_param(compiler, " ", &ins->declaration.raw_resource.resource.reg, true, "");
1960 shader_dump_register_space(compiler, ins->declaration.raw_resource.resource.range.space);
1961 break;
1963 case VKD3DSIH_DCL_RESOURCE_STRUCTURED:
1964 shader_print_dst_param(compiler, " ", &ins->declaration.structured_resource.resource.reg, true, "");
1965 shader_print_uint_literal(compiler, ", ", ins->declaration.structured_resource.byte_stride, "");
1966 shader_dump_register_space(compiler, ins->declaration.structured_resource.resource.range.space);
1967 break;
1969 case VKD3DSIH_DCL_SAMPLER:
1970 shader_print_register(compiler, " ", &ins->declaration.sampler.src.reg, true,
1971 ins->flags == VKD3DSI_SAMPLER_COMPARISON_MODE ? ", comparisonMode" : "");
1972 shader_dump_register_space(compiler, ins->declaration.sampler.range.space);
1973 break;
1975 case VKD3DSIH_DCL_TEMPS:
1976 case VKD3DSIH_DCL_GS_INSTANCES:
1977 case VKD3DSIH_DCL_HS_FORK_PHASE_INSTANCE_COUNT:
1978 case VKD3DSIH_DCL_HS_JOIN_PHASE_INSTANCE_COUNT:
1979 case VKD3DSIH_DCL_INPUT_CONTROL_POINT_COUNT:
1980 case VKD3DSIH_DCL_OUTPUT_CONTROL_POINT_COUNT:
1981 case VKD3DSIH_DCL_VERTICES_OUT:
1982 shader_print_uint_literal(compiler, " ", ins->declaration.count, "");
1983 break;
1985 case VKD3DSIH_DCL_TESSELLATOR_DOMAIN:
1986 shader_print_tessellator_domain(compiler, " ", ins->declaration.tessellator_domain, "");
1987 break;
1989 case VKD3DSIH_DCL_TESSELLATOR_OUTPUT_PRIMITIVE:
1990 shader_print_tessellator_output_primitive(compiler, " ", ins->declaration.tessellator_output_primitive, "");
1991 break;
1993 case VKD3DSIH_DCL_TESSELLATOR_PARTITIONING:
1994 shader_print_tessellator_partitioning(compiler, " ", ins->declaration.tessellator_partitioning, "");
1995 break;
1997 case VKD3DSIH_DCL_TGSM_RAW:
1998 shader_print_dst_param(compiler, " ", &ins->declaration.tgsm_raw.reg, true, "");
1999 shader_print_uint_literal(compiler, ", ", ins->declaration.tgsm_raw.byte_count, "");
2000 break;
2002 case VKD3DSIH_DCL_TGSM_STRUCTURED:
2003 shader_print_dst_param(compiler, " ", &ins->declaration.tgsm_structured.reg, true, "");
2004 shader_print_uint_literal(compiler, ", ", ins->declaration.tgsm_structured.byte_stride, "");
2005 shader_print_uint_literal(compiler, ", ", ins->declaration.tgsm_structured.structure_count, "");
2006 break;
2008 case VKD3DSIH_DCL_THREAD_GROUP:
2009 shader_print_uint_literal(compiler, " ", ins->declaration.thread_group_size.x, "");
2010 shader_print_uint_literal(compiler, ", ", ins->declaration.thread_group_size.y, "");
2011 shader_print_uint_literal(compiler, ", ", ins->declaration.thread_group_size.z, "");
2012 break;
2014 case VKD3DSIH_DCL_UAV_RAW:
2015 shader_dump_uav_flags(compiler, ins->flags);
2016 shader_print_dst_param(compiler, " ", &ins->declaration.raw_resource.resource.reg, true, "");
2017 shader_dump_register_space(compiler, ins->declaration.raw_resource.resource.range.space);
2018 break;
2020 case VKD3DSIH_DCL_UAV_STRUCTURED:
2021 shader_dump_uav_flags(compiler, ins->flags);
2022 shader_print_dst_param(compiler, " ", &ins->declaration.structured_resource.resource.reg, true, "");
2023 shader_print_uint_literal(compiler, ", ", ins->declaration.structured_resource.byte_stride, "");
2024 shader_dump_register_space(compiler, ins->declaration.structured_resource.resource.range.space);
2025 break;
2027 case VKD3DSIH_DEF:
2028 vkd3d_string_buffer_printf(buffer, " %sc%u%s", compiler->colours.reg,
2029 shader_get_float_offset(ins->dst[0].reg.type, ins->dst[0].reg.idx[0].offset),
2030 compiler->colours.reset);
2031 shader_print_float_literal(compiler, " = ", ins->src[0].reg.u.immconst_f32[0], "");
2032 shader_print_float_literal(compiler, ", ", ins->src[0].reg.u.immconst_f32[1], "");
2033 shader_print_float_literal(compiler, ", ", ins->src[0].reg.u.immconst_f32[2], "");
2034 shader_print_float_literal(compiler, ", ", ins->src[0].reg.u.immconst_f32[3], "");
2035 break;
2037 case VKD3DSIH_DEFI:
2038 vkd3d_string_buffer_printf(buffer, " %si%u%s", compiler->colours.reg,
2039 ins->dst[0].reg.idx[0].offset, compiler->colours.reset);
2040 shader_print_int_literal(compiler, " = ", ins->src[0].reg.u.immconst_u32[0], "");
2041 shader_print_int_literal(compiler, ", ", ins->src[0].reg.u.immconst_u32[1], "");
2042 shader_print_int_literal(compiler, ", ", ins->src[0].reg.u.immconst_u32[2], "");
2043 shader_print_int_literal(compiler, ", ", ins->src[0].reg.u.immconst_u32[3], "");
2044 break;
2046 case VKD3DSIH_DEFB:
2047 vkd3d_string_buffer_printf(buffer, " %sb%u%s", compiler->colours.reg,
2048 ins->dst[0].reg.idx[0].offset, compiler->colours.reset);
2049 shader_print_bool_literal(compiler, " = ", ins->src[0].reg.u.immconst_u32[0], "");
2050 break;
2052 default:
2053 shader_dump_instruction_flags(compiler, ins);
2055 if (ins->resource_type != VKD3D_SHADER_RESOURCE_NONE)
2057 shader_addline(buffer, "_indexable(");
2058 if (ins->raw)
2059 vkd3d_string_buffer_printf(buffer, "raw_");
2060 if (ins->structured)
2061 vkd3d_string_buffer_printf(buffer, "structured_");
2062 shader_dump_resource_type(compiler, ins->resource_type);
2063 if (ins->resource_stride)
2064 shader_print_uint_literal(compiler, ", stride=", ins->resource_stride, "");
2065 shader_addline(buffer, ")");
2068 if (vkd3d_shader_instruction_has_texel_offset(ins))
2070 shader_print_int_literal(compiler, "(", ins->texel_offset.u, "");
2071 shader_print_int_literal(compiler, ",", ins->texel_offset.v, "");
2072 shader_print_int_literal(compiler, ",", ins->texel_offset.w, ")");
2075 if (ins->resource_data_type[0] != VKD3D_DATA_FLOAT
2076 || ins->resource_data_type[1] != VKD3D_DATA_FLOAT
2077 || ins->resource_data_type[2] != VKD3D_DATA_FLOAT
2078 || ins->resource_data_type[3] != VKD3D_DATA_FLOAT)
2079 shader_dump_resource_data_type(compiler, ins->resource_data_type);
2081 for (i = 0; i < ins->dst_count; ++i)
2083 shader_dump_ins_modifiers(compiler, &ins->dst[i]);
2084 shader_print_dst_param(compiler, !i ? " " : ", ", &ins->dst[i], false, "");
2087 /* Other source tokens */
2088 for (i = ins->dst_count; i < (ins->dst_count + ins->src_count); ++i)
2090 shader_print_src_param(compiler, !i ? " " : ", ", &ins->src[i - ins->dst_count], "");
2092 break;
2095 shader_addline(buffer, "\n");
2098 static const char *get_sysval_semantic_name(enum vkd3d_shader_sysval_semantic semantic)
2100 switch (semantic)
2102 case VKD3D_SHADER_SV_NONE: return "NONE";
2103 case VKD3D_SHADER_SV_POSITION: return "POS";
2104 case VKD3D_SHADER_SV_CLIP_DISTANCE: return "CLIPDST";
2105 case VKD3D_SHADER_SV_CULL_DISTANCE: return "CULLDST";
2106 case VKD3D_SHADER_SV_RENDER_TARGET_ARRAY_INDEX: return "RTINDEX";
2107 case VKD3D_SHADER_SV_VIEWPORT_ARRAY_INDEX: return "VPINDEX";
2108 case VKD3D_SHADER_SV_VERTEX_ID: return "VERTID";
2109 case VKD3D_SHADER_SV_PRIMITIVE_ID: return "PRIMID";
2110 case VKD3D_SHADER_SV_INSTANCE_ID: return "INSTID";
2111 case VKD3D_SHADER_SV_IS_FRONT_FACE: return "FFACE";
2112 case VKD3D_SHADER_SV_SAMPLE_INDEX: return "SAMPLE";
2113 case VKD3D_SHADER_SV_TESS_FACTOR_QUADEDGE: return "QUADEDGE";
2114 case VKD3D_SHADER_SV_TESS_FACTOR_QUADINT: return "QUADINT";
2115 case VKD3D_SHADER_SV_TESS_FACTOR_TRIEDGE: return "TRIEDGE";
2116 case VKD3D_SHADER_SV_TESS_FACTOR_TRIINT: return "TRIINT";
2117 case VKD3D_SHADER_SV_TESS_FACTOR_LINEDET: return "LINEDET";
2118 case VKD3D_SHADER_SV_TESS_FACTOR_LINEDEN: return "LINEDEN";
2119 case VKD3D_SHADER_SV_TARGET: return "TARGET";
2120 case VKD3D_SHADER_SV_DEPTH: return "DEPTH";
2121 case VKD3D_SHADER_SV_COVERAGE: return "COVERAGE";
2122 case VKD3D_SHADER_SV_DEPTH_GREATER_EQUAL: return "DEPTHGE";
2123 case VKD3D_SHADER_SV_DEPTH_LESS_EQUAL: return "DEPTHLE";
2124 case VKD3D_SHADER_SV_STENCIL_REF: return "STENCILREF";
2125 default: return "??";
2129 static const char *get_component_type_name(enum vkd3d_shader_component_type type)
2131 switch (type)
2133 case VKD3D_SHADER_COMPONENT_VOID: return "void";
2134 case VKD3D_SHADER_COMPONENT_UINT: return "uint";
2135 case VKD3D_SHADER_COMPONENT_INT: return "int";
2136 case VKD3D_SHADER_COMPONENT_FLOAT: return "float";
2137 case VKD3D_SHADER_COMPONENT_BOOL: return "bool";
2138 case VKD3D_SHADER_COMPONENT_DOUBLE: return "double";
2139 case VKD3D_SHADER_COMPONENT_UINT64: return "uint64";
2140 default: return "??";
2144 static const char *get_minimum_precision_name(enum vkd3d_shader_minimum_precision prec)
2146 switch (prec)
2148 case VKD3D_SHADER_MINIMUM_PRECISION_NONE: return "NONE";
2149 case VKD3D_SHADER_MINIMUM_PRECISION_FLOAT_16: return "FLOAT_16";
2150 case VKD3D_SHADER_MINIMUM_PRECISION_FIXED_8_2: return "FIXED_8_2";
2151 case VKD3D_SHADER_MINIMUM_PRECISION_INT_16: return "INT_16";
2152 case VKD3D_SHADER_MINIMUM_PRECISION_UINT_16: return "UINT_16";
2153 default: return "??";
2157 static const char *get_semantic_register_name(enum vkd3d_shader_sysval_semantic semantic)
2159 switch (semantic)
2161 case VKD3D_SHADER_SV_DEPTH: return "oDepth";
2162 case VKD3D_SHADER_SV_DEPTH_GREATER_EQUAL: return "oDepthGE";
2163 case VKD3D_SHADER_SV_DEPTH_LESS_EQUAL: return "oDepthLE";
2164 /* SV_Coverage has name vCoverage when used as an input,
2165 * but it doens't appear in the signature in that case. */
2166 case VKD3D_SHADER_SV_COVERAGE: return "oMask";
2167 case VKD3D_SHADER_SV_STENCIL_REF: return "oStencilRef";
2168 default: return "??";
2172 static enum vkd3d_result dump_signature(struct vkd3d_d3d_asm_compiler *compiler,
2173 const char *name, const char *register_name, const struct shader_signature *signature)
2175 struct vkd3d_string_buffer *buffer = &compiler->buffer;
2176 unsigned int i;
2178 if (signature->element_count == 0)
2179 return VKD3D_OK;
2181 vkd3d_string_buffer_printf(buffer, "%s%s%s\n",
2182 compiler->colours.opcode, name, compiler->colours.reset);
2184 for (i = 0; i < signature->element_count; ++i)
2186 struct signature_element *element = &signature->elements[i];
2188 vkd3d_string_buffer_printf(buffer, "%s.param%s %s", compiler->colours.opcode,
2189 compiler->colours.reset, element->semantic_name);
2191 if (element->semantic_index != 0)
2192 vkd3d_string_buffer_printf(buffer, "%u", element->semantic_index);
2194 if (element->register_index != -1)
2196 shader_print_write_mask(compiler, "", element->mask, "");
2197 vkd3d_string_buffer_printf(buffer, ", %s%s%d%s", compiler->colours.reg,
2198 register_name, element->register_index, compiler->colours.reset);
2199 shader_print_write_mask(compiler, "", element->used_mask, "");
2201 else
2203 vkd3d_string_buffer_printf(buffer, ", %s%s%s", compiler->colours.reg,
2204 get_semantic_register_name(element->sysval_semantic), compiler->colours.reset);
2207 if (!element->component_type && !element->sysval_semantic
2208 && !element->min_precision && !element->stream_index)
2209 goto done;
2211 vkd3d_string_buffer_printf(buffer, ", %s",
2212 get_component_type_name(element->component_type));
2214 if (!element->sysval_semantic && !element->min_precision && !element->stream_index)
2215 goto done;
2217 vkd3d_string_buffer_printf(buffer, ", %s",
2218 get_sysval_semantic_name(element->sysval_semantic));
2220 if (!element->min_precision && !element->stream_index)
2221 goto done;
2223 vkd3d_string_buffer_printf(buffer, ", %s",
2224 get_minimum_precision_name(element->min_precision));
2226 if (!element->stream_index)
2227 goto done;
2229 vkd3d_string_buffer_printf(buffer, ", m%u",
2230 element->stream_index);
2232 done:
2233 vkd3d_string_buffer_printf(buffer, "\n");
2236 return VKD3D_OK;
2239 static enum vkd3d_result dump_signatures(struct vkd3d_d3d_asm_compiler *compiler,
2240 const struct vsir_program *program)
2242 enum vkd3d_result ret;
2244 if ((ret = dump_signature(compiler, ".input",
2245 program->shader_version.type == VKD3D_SHADER_TYPE_DOMAIN ? "vicp" : "v",
2246 &program->input_signature)) < 0)
2247 return ret;
2249 if ((ret = dump_signature(compiler, ".output", "o",
2250 &program->output_signature)) < 0)
2251 return ret;
2253 if ((ret = dump_signature(compiler, ".patch_constant",
2254 program->shader_version.type == VKD3D_SHADER_TYPE_DOMAIN ? "vpc" : "o",
2255 &program->patch_constant_signature)) < 0)
2256 return ret;
2258 vkd3d_string_buffer_printf(&compiler->buffer, "%s.text%s\n",
2259 compiler->colours.opcode, compiler->colours.reset);
2261 return VKD3D_OK;
2264 enum vkd3d_result d3d_asm_compile(const struct vsir_program *program,
2265 const struct vkd3d_shader_compile_info *compile_info,
2266 struct vkd3d_shader_code *out, enum vsir_asm_flags flags)
2268 const struct vkd3d_shader_version *shader_version = &program->shader_version;
2269 enum vkd3d_shader_compile_option_formatting_flags formatting;
2270 struct vkd3d_d3d_asm_compiler compiler =
2272 .flags = flags,
2274 enum vkd3d_result result = VKD3D_OK;
2275 struct vkd3d_string_buffer *buffer;
2276 unsigned int indent, i, j;
2277 const char *indent_str;
2279 static const struct vkd3d_d3d_asm_colours no_colours =
2281 .reset = "",
2282 .error = "",
2283 .literal = "",
2284 .modifier = "",
2285 .opcode = "",
2286 .reg = "",
2287 .swizzle = "",
2288 .version = "",
2289 .write_mask = "",
2290 .label = "",
2292 static const struct vkd3d_d3d_asm_colours colours =
2294 .reset = "\x1b[m",
2295 .error = "\x1b[97;41m",
2296 .literal = "\x1b[95m",
2297 .modifier = "\x1b[36m",
2298 .opcode = "\x1b[96;1m",
2299 .reg = "\x1b[96m",
2300 .swizzle = "\x1b[93m",
2301 .version = "\x1b[36m",
2302 .write_mask = "\x1b[93m",
2303 .label = "\x1b[91m",
2306 formatting = VKD3D_SHADER_COMPILE_OPTION_FORMATTING_INDENT
2307 | VKD3D_SHADER_COMPILE_OPTION_FORMATTING_HEADER;
2308 if (compile_info)
2310 for (i = 0; i < compile_info->option_count; ++i)
2312 const struct vkd3d_shader_compile_option *option = &compile_info->options[i];
2314 if (option->name == VKD3D_SHADER_COMPILE_OPTION_FORMATTING)
2315 formatting = option->value;
2319 if (formatting & VKD3D_SHADER_COMPILE_OPTION_FORMATTING_COLOUR)
2320 compiler.colours = colours;
2321 else
2322 compiler.colours = no_colours;
2323 if (formatting & VKD3D_SHADER_COMPILE_OPTION_FORMATTING_INDENT)
2324 indent_str = " ";
2325 else
2326 indent_str = "";
2328 buffer = &compiler.buffer;
2329 vkd3d_string_buffer_init(buffer);
2331 compiler.shader_version = *shader_version;
2332 shader_version = &compiler.shader_version;
2333 vkd3d_string_buffer_printf(buffer, "%s%s_%u_%u%s\n", compiler.colours.version,
2334 shader_get_type_prefix(shader_version->type), shader_version->major,
2335 shader_version->minor, compiler.colours.reset);
2337 /* The signatures we emit only make sense for DXBC shaders. D3DBC
2338 * doesn't even have an explicit concept of signature. */
2339 if (formatting & VKD3D_SHADER_COMPILE_OPTION_FORMATTING_IO_SIGNATURES && shader_version->major >= 4)
2341 if ((result = dump_signatures(&compiler, program)) < 0)
2343 vkd3d_string_buffer_cleanup(buffer);
2344 return result;
2348 indent = 0;
2349 for (i = 0; i < program->instructions.count; ++i)
2351 struct vkd3d_shader_instruction *ins = &program->instructions.elements[i];
2353 switch (ins->handler_idx)
2355 case VKD3DSIH_ELSE:
2356 case VKD3DSIH_ENDIF:
2357 case VKD3DSIH_ENDLOOP:
2358 case VKD3DSIH_ENDSWITCH:
2359 if (indent)
2360 --indent;
2361 break;
2363 case VKD3DSIH_LABEL:
2364 case VKD3DSIH_HS_DECLS:
2365 case VKD3DSIH_HS_CONTROL_POINT_PHASE:
2366 case VKD3DSIH_HS_FORK_PHASE:
2367 case VKD3DSIH_HS_JOIN_PHASE:
2368 indent = 0;
2369 break;
2371 default:
2372 break;
2375 for (j = 0; j < indent; ++j)
2377 vkd3d_string_buffer_printf(buffer, "%s", indent_str);
2380 shader_dump_instruction(&compiler, ins);
2382 switch (ins->handler_idx)
2384 case VKD3DSIH_ELSE:
2385 case VKD3DSIH_IF:
2386 case VKD3DSIH_IFC:
2387 case VKD3DSIH_LOOP:
2388 case VKD3DSIH_SWITCH:
2389 case VKD3DSIH_LABEL:
2390 ++indent;
2391 break;
2393 default:
2394 break;
2398 vkd3d_shader_code_from_string_buffer(out, buffer);
2400 return result;
2403 void vkd3d_shader_trace(const struct vsir_program *program)
2405 const char *p, *q, *end;
2406 struct vkd3d_shader_code code;
2408 if (d3d_asm_compile(program, NULL, &code, VSIR_ASM_FLAG_DUMP_TYPES) != VKD3D_OK)
2409 return;
2411 end = (const char *)code.code + code.size;
2412 for (p = code.code; p < end; p = q)
2414 if (!(q = memchr(p, '\n', end - p)))
2415 q = end;
2416 else
2417 ++q;
2418 TRACE(" %.*s", (int)(q - p), p);
2421 vkd3d_shader_free_shader_code(&code);