1 /**************************************************************************
2 *
3 * Copyright 2012-2021 VMware, Inc.
4 * All Rights Reserved.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sub license, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
18 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
19 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
20 * USE OR OTHER DEALINGS IN THE SOFTWARE.
21 *
22 * The above copyright notice and this permission notice (including the
23 * next paragraph) shall be included in all copies or substantial portions
24 * of the Software.
25 *
26 **************************************************************************/
27
28 /*
29 * ShaderParse.c --
30 * Functions for parsing shader tokens.
31 */
32
33 #include "Debug.h"
34 #include "ShaderParse.h"
35
36 #include "util/u_memory.h"
37
38
39 void
Shader_parse_init(struct Shader_parser * parser,const unsigned * code)40 Shader_parse_init(struct Shader_parser *parser,
41 const unsigned *code)
42 {
43 parser->curr = parser->code = code;
44
45 parser->header.type = DECODE_D3D10_SB_TOKENIZED_PROGRAM_TYPE(*parser->curr);
46 parser->header.major_version = DECODE_D3D10_SB_TOKENIZED_PROGRAM_MAJOR_VERSION(*parser->curr);
47 parser->header.minor_version = DECODE_D3D10_SB_TOKENIZED_PROGRAM_MINOR_VERSION(*parser->curr);
48 parser->curr++;
49
50 parser->header.size = DECODE_D3D10_SB_TOKENIZED_PROGRAM_LENGTH(*parser->curr);
51 parser->curr++;
52 }
53
54 #define OP_NOT_DONE (1 << 0) /* not implemented yet */
55 #define OP_SATURATE (1 << 1) /* saturate in opcode specific control */
56 #define OP_TEST_BOOLEAN (1 << 2) /* test boolean in opcode specific control */
57 #define OP_DCL (1 << 3) /* custom opcode specific control */
58 #define OP_RESINFO_RET_TYPE (1 << 4) /* return type for resinfo */
59
60 struct dx10_opcode_info {
61 D3D10_SB_OPCODE_TYPE type;
62 const char *name;
63 unsigned num_dst;
64 unsigned num_src;
65 unsigned flags;
66 };
67
68 #define _(_opcode) _opcode, #_opcode
69
70 static const struct dx10_opcode_info
71 opcode_info[D3D10_SB_NUM_OPCODES] = {
72 {_(D3D10_SB_OPCODE_ADD), 1, 2, OP_SATURATE},
73 {_(D3D10_SB_OPCODE_AND), 1, 2, 0},
74 {_(D3D10_SB_OPCODE_BREAK), 0, 0, 0},
75 {_(D3D10_SB_OPCODE_BREAKC), 0, 1, OP_TEST_BOOLEAN},
76 {_(D3D10_SB_OPCODE_CALL), 0, 1, 0},
77 {_(D3D10_SB_OPCODE_CALLC), 0, 2, OP_TEST_BOOLEAN},
78 {_(D3D10_SB_OPCODE_CASE), 0, 1, 0},
79 {_(D3D10_SB_OPCODE_CONTINUE), 0, 0, 0},
80 {_(D3D10_SB_OPCODE_CONTINUEC), 0, 1, OP_TEST_BOOLEAN},
81 {_(D3D10_SB_OPCODE_CUT), 0, 0, 0},
82 {_(D3D10_SB_OPCODE_DEFAULT), 0, 0, 0},
83 {_(D3D10_SB_OPCODE_DERIV_RTX), 1, 1, OP_SATURATE},
84 {_(D3D10_SB_OPCODE_DERIV_RTY), 1, 1, OP_SATURATE},
85 {_(D3D10_SB_OPCODE_DISCARD), 0, 1, OP_TEST_BOOLEAN},
86 {_(D3D10_SB_OPCODE_DIV), 1, 2, OP_SATURATE},
87 {_(D3D10_SB_OPCODE_DP2), 1, 2, OP_SATURATE},
88 {_(D3D10_SB_OPCODE_DP3), 1, 2, OP_SATURATE},
89 {_(D3D10_SB_OPCODE_DP4), 1, 2, OP_SATURATE},
90 {_(D3D10_SB_OPCODE_ELSE), 0, 0, 0},
91 {_(D3D10_SB_OPCODE_EMIT), 0, 0, 0},
92 {_(D3D10_SB_OPCODE_EMITTHENCUT), 0, 0, 0},
93 {_(D3D10_SB_OPCODE_ENDIF), 0, 0, 0},
94 {_(D3D10_SB_OPCODE_ENDLOOP), 0, 0, 0},
95 {_(D3D10_SB_OPCODE_ENDSWITCH), 0, 0, 0},
96 {_(D3D10_SB_OPCODE_EQ), 1, 2, 0},
97 {_(D3D10_SB_OPCODE_EXP), 1, 1, OP_SATURATE},
98 {_(D3D10_SB_OPCODE_FRC), 1, 1, OP_SATURATE},
99 {_(D3D10_SB_OPCODE_FTOI), 1, 1, 0},
100 {_(D3D10_SB_OPCODE_FTOU), 1, 1, 0},
101 {_(D3D10_SB_OPCODE_GE), 1, 2, 0},
102 {_(D3D10_SB_OPCODE_IADD), 1, 2, 0},
103 {_(D3D10_SB_OPCODE_IF), 0, 1, OP_TEST_BOOLEAN},
104 {_(D3D10_SB_OPCODE_IEQ), 1, 2, 0},
105 {_(D3D10_SB_OPCODE_IGE), 1, 2, 0},
106 {_(D3D10_SB_OPCODE_ILT), 1, 2, 0},
107 {_(D3D10_SB_OPCODE_IMAD), 1, 3, 0},
108 {_(D3D10_SB_OPCODE_IMAX), 1, 2, 0},
109 {_(D3D10_SB_OPCODE_IMIN), 1, 2, 0},
110 {_(D3D10_SB_OPCODE_IMUL), 2, 2, 0},
111 {_(D3D10_SB_OPCODE_INE), 1, 2, 0},
112 {_(D3D10_SB_OPCODE_INEG), 1, 1, 0},
113 {_(D3D10_SB_OPCODE_ISHL), 1, 2, 0},
114 {_(D3D10_SB_OPCODE_ISHR), 1, 2, 0},
115 {_(D3D10_SB_OPCODE_ITOF), 1, 1, 0},
116 {_(D3D10_SB_OPCODE_LABEL), 0, 1, 0},
117 {_(D3D10_SB_OPCODE_LD), 1, 2, 0},
118 {_(D3D10_SB_OPCODE_LD_MS), 1, 3, 0},
119 {_(D3D10_SB_OPCODE_LOG), 1, 1, OP_SATURATE},
120 {_(D3D10_SB_OPCODE_LOOP), 0, 0, 0},
121 {_(D3D10_SB_OPCODE_LT), 1, 2, 0},
122 {_(D3D10_SB_OPCODE_MAD), 1, 3, OP_SATURATE},
123 {_(D3D10_SB_OPCODE_MIN), 1, 2, OP_SATURATE},
124 {_(D3D10_SB_OPCODE_MAX), 1, 2, OP_SATURATE},
125 {_(D3D10_SB_OPCODE_CUSTOMDATA), 0, 0, 0},
126 {_(D3D10_SB_OPCODE_MOV), 1, 1, OP_SATURATE},
127 {_(D3D10_SB_OPCODE_MOVC), 1, 3, OP_SATURATE},
128 {_(D3D10_SB_OPCODE_MUL), 1, 2, OP_SATURATE},
129 {_(D3D10_SB_OPCODE_NE), 1, 2, 0},
130 {_(D3D10_SB_OPCODE_NOP), 0, 0, 0},
131 {_(D3D10_SB_OPCODE_NOT), 1, 1, 0},
132 {_(D3D10_SB_OPCODE_OR), 1, 2, 0},
133 {_(D3D10_SB_OPCODE_RESINFO), 1, 2, OP_RESINFO_RET_TYPE},
134 {_(D3D10_SB_OPCODE_RET), 0, 0, 0},
135 {_(D3D10_SB_OPCODE_RETC), 0, 1, OP_TEST_BOOLEAN},
136 {_(D3D10_SB_OPCODE_ROUND_NE), 1, 1, OP_SATURATE},
137 {_(D3D10_SB_OPCODE_ROUND_NI), 1, 1, OP_SATURATE},
138 {_(D3D10_SB_OPCODE_ROUND_PI), 1, 1, OP_SATURATE},
139 {_(D3D10_SB_OPCODE_ROUND_Z), 1, 1, OP_SATURATE},
140 {_(D3D10_SB_OPCODE_RSQ), 1, 1, OP_SATURATE},
141 {_(D3D10_SB_OPCODE_SAMPLE), 1, 3, 0},
142 {_(D3D10_SB_OPCODE_SAMPLE_C), 1, 4, 0},
143 {_(D3D10_SB_OPCODE_SAMPLE_C_LZ), 1, 4, 0},
144 {_(D3D10_SB_OPCODE_SAMPLE_L), 1, 4, 0},
145 {_(D3D10_SB_OPCODE_SAMPLE_D), 1, 5, 0},
146 {_(D3D10_SB_OPCODE_SAMPLE_B), 1, 4, 0},
147 {_(D3D10_SB_OPCODE_SQRT), 1, 1, OP_SATURATE},
148 {_(D3D10_SB_OPCODE_SWITCH), 0, 1, 0},
149 {_(D3D10_SB_OPCODE_SINCOS), 2, 1, OP_SATURATE},
150 {_(D3D10_SB_OPCODE_UDIV), 2, 2, 0},
151 {_(D3D10_SB_OPCODE_ULT), 1, 2, 0},
152 {_(D3D10_SB_OPCODE_UGE), 1, 2, 0},
153 {_(D3D10_SB_OPCODE_UMUL), 2, 2, 0},
154 {_(D3D10_SB_OPCODE_UMAD), 1, 3, 0},
155 {_(D3D10_SB_OPCODE_UMAX), 1, 2, 0},
156 {_(D3D10_SB_OPCODE_UMIN), 1, 2, 0},
157 {_(D3D10_SB_OPCODE_USHR), 1, 2, 0},
158 {_(D3D10_SB_OPCODE_UTOF), 1, 1, 0},
159 {_(D3D10_SB_OPCODE_XOR), 1, 2, 0},
160 {_(D3D10_SB_OPCODE_DCL_RESOURCE), 1, 0, OP_DCL},
161 {_(D3D10_SB_OPCODE_DCL_CONSTANT_BUFFER), 0, 1, OP_DCL},
162 {_(D3D10_SB_OPCODE_DCL_SAMPLER), 1, 0, OP_DCL},
163 {_(D3D10_SB_OPCODE_DCL_INDEX_RANGE), 1, 0, OP_DCL},
164 {_(D3D10_SB_OPCODE_DCL_GS_OUTPUT_PRIMITIVE_TOPOLOGY), 0, 0, OP_DCL},
165 {_(D3D10_SB_OPCODE_DCL_GS_INPUT_PRIMITIVE), 0, 0, OP_DCL},
166 {_(D3D10_SB_OPCODE_DCL_MAX_OUTPUT_VERTEX_COUNT), 0, 0, OP_DCL},
167 {_(D3D10_SB_OPCODE_DCL_INPUT), 1, 0, OP_DCL},
168 {_(D3D10_SB_OPCODE_DCL_INPUT_SGV), 1, 0, OP_DCL},
169 {_(D3D10_SB_OPCODE_DCL_INPUT_SIV), 1, 0, OP_DCL},
170 {_(D3D10_SB_OPCODE_DCL_INPUT_PS), 1, 0, OP_DCL},
171 {_(D3D10_SB_OPCODE_DCL_INPUT_PS_SGV), 1, 0, OP_DCL},
172 {_(D3D10_SB_OPCODE_DCL_INPUT_PS_SIV), 1, 0, OP_DCL},
173 {_(D3D10_SB_OPCODE_DCL_OUTPUT), 1, 0, OP_DCL},
174 {_(D3D10_SB_OPCODE_DCL_OUTPUT_SGV), 1, 0, OP_DCL},
175 {_(D3D10_SB_OPCODE_DCL_OUTPUT_SIV), 1, 0, OP_DCL},
176 {_(D3D10_SB_OPCODE_DCL_TEMPS), 0, 0, OP_DCL},
177 {_(D3D10_SB_OPCODE_DCL_INDEXABLE_TEMP), 0, 0, OP_DCL},
178 {_(D3D10_SB_OPCODE_DCL_GLOBAL_FLAGS), 0, 0, OP_DCL},
179 {_(D3D10_SB_OPCODE_RESERVED0), 0, 0, OP_NOT_DONE},
180 {_(D3D10_1_SB_OPCODE_LOD), 0, 0, OP_NOT_DONE},
181 {_(D3D10_1_SB_OPCODE_GATHER4), 0, 0, OP_NOT_DONE},
182 {_(D3D10_1_SB_OPCODE_SAMPLE_POS), 0, 0, OP_NOT_DONE},
183 {_(D3D10_1_SB_OPCODE_SAMPLE_INFO), 0, 0, OP_NOT_DONE}
184 };
185
186 #undef _
187
188 static void
parse_operand(const unsigned ** curr,struct Shader_operand * operand)189 parse_operand(const unsigned **curr,
190 struct Shader_operand *operand)
191 {
192 operand->type = DECODE_D3D10_SB_OPERAND_TYPE(**curr);
193
194 /* Index dimension. */
195 switch (DECODE_D3D10_SB_OPERAND_INDEX_DIMENSION(**curr)) {
196 case D3D10_SB_OPERAND_INDEX_0D:
197 operand->index_dim = 0;
198 break;
199 case D3D10_SB_OPERAND_INDEX_1D:
200 operand->index_dim = 1;
201 break;
202 case D3D10_SB_OPERAND_INDEX_2D:
203 operand->index_dim = 2;
204 break;
205 default:
206 assert(0);
207 }
208
209 if (operand->index_dim >= 1) {
210 operand->index[0].index_rep = DECODE_D3D10_SB_OPERAND_INDEX_REPRESENTATION(0, **curr);
211 if (operand->index_dim >= 2) {
212 operand->index[1].index_rep = DECODE_D3D10_SB_OPERAND_INDEX_REPRESENTATION(1, **curr);
213 }
214 }
215
216 (*curr)++;
217 }
218
219 static void
parse_relative_operand(const unsigned ** curr,struct Shader_relative_operand * operand)220 parse_relative_operand(const unsigned **curr,
221 struct Shader_relative_operand *operand)
222 {
223 assert(!DECODE_IS_D3D10_SB_OPERAND_EXTENDED(**curr));
224 assert(DECODE_D3D10_SB_OPERAND_NUM_COMPONENTS(**curr) == D3D10_SB_OPERAND_4_COMPONENT);
225 assert(DECODE_D3D10_SB_OPERAND_4_COMPONENT_SELECTION_MODE(**curr) == D3D10_SB_OPERAND_4_COMPONENT_SELECT_1_MODE);
226
227 operand->comp = DECODE_D3D10_SB_OPERAND_4_COMPONENT_SELECT_1(**curr);
228
229 operand->type = DECODE_D3D10_SB_OPERAND_TYPE(**curr);
230 assert(operand->type != D3D10_SB_OPERAND_TYPE_IMMEDIATE32);
231
232 /* Index dimension. */
233 assert(DECODE_D3D10_SB_OPERAND_INDEX_REPRESENTATION(0, **curr) == D3D10_SB_OPERAND_INDEX_IMMEDIATE32);
234
235 if (DECODE_D3D10_SB_OPERAND_INDEX_DIMENSION(**curr) == D3D10_SB_OPERAND_INDEX_1D) {
236 (*curr)++;
237 operand->index[0].imm = **curr;
238 } else {
239 assert(DECODE_D3D10_SB_OPERAND_INDEX_DIMENSION(**curr) == D3D10_SB_OPERAND_INDEX_2D);
240 (*curr)++;
241 operand->index[0].imm = **curr;
242 (*curr)++;
243 operand->index[1].imm = **curr;
244
245 }
246 (*curr)++;
247 }
248
249 static void
parse_index(const unsigned ** curr,struct Shader_index * index)250 parse_index(const unsigned **curr,
251 struct Shader_index *index)
252 {
253 switch (index->index_rep) {
254 case D3D10_SB_OPERAND_INDEX_IMMEDIATE32:
255 index->imm = *(*curr)++;
256 break;
257 case D3D10_SB_OPERAND_INDEX_RELATIVE:
258 index->imm = 0;
259 parse_relative_operand(curr, &index->rel);
260 break;
261 case D3D10_SB_OPERAND_INDEX_IMMEDIATE32_PLUS_RELATIVE:
262 index->imm = *(*curr)++;
263 parse_relative_operand(curr, &index->rel);
264 break;
265 default:
266 /* XXX: Support other index representations.
267 */
268 assert(0);
269 }
270 }
271
272 static void
parse_operand_index(const unsigned ** curr,struct Shader_operand * operand)273 parse_operand_index(const unsigned **curr,
274 struct Shader_operand *operand)
275 {
276 if (operand->index_dim >= 1) {
277 parse_index(curr, &operand->index[0]);
278 if (operand->index_dim >= 2) {
279 parse_index(curr, &operand->index[1]);
280 }
281 }
282 }
283
284 boolean
Shader_parse_opcode(struct Shader_parser * parser,struct Shader_opcode * opcode)285 Shader_parse_opcode(struct Shader_parser *parser,
286 struct Shader_opcode *opcode)
287 {
288 const unsigned *curr = parser->curr;
289 const struct dx10_opcode_info *info;
290 unsigned length;
291 boolean opcode_is_extended;
292 unsigned i;
293
294 if (curr >= parser->code + parser->header.size) {
295 return FALSE;
296 }
297
298 memset(opcode, 0, sizeof *opcode);
299
300 /* Opcode type. */
301 opcode->type = DECODE_D3D10_SB_OPCODE_TYPE(*curr);
302
303 if (opcode->type == D3D10_SB_OPCODE_CUSTOMDATA) {
304 opcode->customdata._class = DECODE_D3D10_SB_CUSTOMDATA_CLASS(*curr);
305 curr++;
306
307 assert(opcode->customdata._class == D3D10_SB_CUSTOMDATA_DCL_IMMEDIATE_CONSTANT_BUFFER);
308
309 opcode->customdata.u.constbuf.count = *curr - 2;
310 curr++;
311
312 opcode->customdata.u.constbuf.data = MALLOC(opcode->customdata.u.constbuf.count * sizeof(unsigned));
313 assert(opcode->customdata.u.constbuf.data);
314
315 memcpy(opcode->customdata.u.constbuf.data,
316 curr,
317 opcode->customdata.u.constbuf.count * sizeof(unsigned));
318 curr += opcode->customdata.u.constbuf.count;
319
320 parser->curr = curr;
321 return TRUE;
322 }
323
324 opcode->dcl_siv_name = D3D10_SB_NAME_UNDEFINED;
325
326 /* Lookup extra information based on opcode type. */
327 assert(opcode->type < D3D10_SB_NUM_OPCODES);
328 info = &opcode_info[opcode->type];
329
330 /* Opcode specific. */
331 switch (opcode->type) {
332 case D3D10_SB_OPCODE_DCL_RESOURCE:
333 opcode->specific.dcl_resource_dimension = DECODE_D3D10_SB_RESOURCE_DIMENSION(*curr);
334 break;
335 case D3D10_SB_OPCODE_DCL_SAMPLER:
336 opcode->specific.dcl_sampler_mode = DECODE_D3D10_SB_SAMPLER_MODE(*curr);
337 break;
338 case D3D10_SB_OPCODE_DCL_GS_OUTPUT_PRIMITIVE_TOPOLOGY:
339 opcode->specific.dcl_gs_output_primitive_topology = DECODE_D3D10_SB_GS_OUTPUT_PRIMITIVE_TOPOLOGY(*curr);
340 break;
341 case D3D10_SB_OPCODE_DCL_GS_INPUT_PRIMITIVE:
342 opcode->specific.dcl_gs_input_primitive = DECODE_D3D10_SB_GS_INPUT_PRIMITIVE(*curr);
343 break;
344 case D3D10_SB_OPCODE_DCL_INPUT_PS:
345 case D3D10_SB_OPCODE_DCL_INPUT_PS_SIV:
346 opcode->specific.dcl_in_ps_interp = DECODE_D3D10_SB_INPUT_INTERPOLATION_MODE(*curr);
347 break;
348 case D3D10_SB_OPCODE_DCL_GLOBAL_FLAGS:
349 opcode->specific.global_flags.refactoring_allowed = DECODE_D3D10_SB_GLOBAL_FLAGS(*curr) ? 1 : 0;
350 break;
351 default:
352 /* Parse opcode-specific control bits */
353 if (info->flags & OP_DCL) {
354 /* no-op */
355 } else if (info->flags & OP_SATURATE) {
356 opcode->saturate =
357 !!DECODE_IS_D3D10_SB_INSTRUCTION_SATURATE_ENABLED(*curr);
358 } else if (info->flags & OP_TEST_BOOLEAN) {
359 opcode->specific.test_boolean =
360 DECODE_D3D10_SB_INSTRUCTION_TEST_BOOLEAN(*curr);
361 } else if (info->flags & OP_RESINFO_RET_TYPE) {
362 opcode->specific.resinfo_ret_type =
363 DECODE_D3D10_SB_RESINFO_INSTRUCTION_RETURN_TYPE(*curr);
364 } else {
365 /* Warn if there are bits set in the opcode-specific controls (bits 23:11 inclusive)*/
366 if (*curr & ((1 << 24) - (1 << 11))) {
367 debug_printf("warning: unexpected opcode-specific control in opcode %s\n",
368 info->name);
369 }
370 }
371 break;
372 }
373
374 /* Opcode length in DWORDs. */
375 length = DECODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(*curr);
376 assert(curr + length <= parser->code + parser->header.size);
377
378 /* Opcode specific fields in token0. */
379 switch (opcode->type) {
380 case D3D10_SB_OPCODE_DCL_CONSTANT_BUFFER:
381 opcode->specific.dcl_cb_access_pattern =
382 DECODE_D3D10_SB_CONSTANT_BUFFER_ACCESS_PATTERN(*curr);
383 break;
384 default:
385 break;
386 }
387
388 opcode_is_extended = DECODE_IS_D3D10_SB_OPCODE_EXTENDED(*curr);
389
390 curr++;
391
392 if (opcode_is_extended) {
393 /* NOTE: DECODE_IS_D3D10_SB_OPCODE_DOUBLE_EXTENDED is broken.
394 */
395 assert(!((*curr & D3D10_SB_OPERAND_DOUBLE_EXTENDED_MASK) >> D3D10_SB_OPERAND_DOUBLE_EXTENDED_SHIFT));
396
397 switch (DECODE_D3D10_SB_EXTENDED_OPCODE_TYPE(*curr)) {
398 case D3D10_SB_EXTENDED_OPCODE_EMPTY:
399 break;
400 case D3D10_SB_EXTENDED_OPCODE_SAMPLE_CONTROLS:
401 opcode->imm_texel_offset.u = DECODE_IMMEDIATE_D3D10_SB_ADDRESS_OFFSET(D3D10_SB_IMMEDIATE_ADDRESS_OFFSET_U, *curr);
402 opcode->imm_texel_offset.v = DECODE_IMMEDIATE_D3D10_SB_ADDRESS_OFFSET(D3D10_SB_IMMEDIATE_ADDRESS_OFFSET_V, *curr);
403 opcode->imm_texel_offset.w = DECODE_IMMEDIATE_D3D10_SB_ADDRESS_OFFSET(D3D10_SB_IMMEDIATE_ADDRESS_OFFSET_W, *curr);
404 break;
405 default:
406 assert(0);
407 }
408
409 curr++;
410 }
411
412 if (info->flags & OP_NOT_DONE) {
413 /* XXX: Need to figure out the number of operands for this opcode.
414 * Should be okay to continue execution -- we have enough info
415 * to skip to the next instruction.
416 */
417 LOG_UNSUPPORTED(TRUE);
418 opcode->num_dst = 0;
419 opcode->num_src = 0;
420 goto skip;
421 }
422
423 opcode->num_dst = info->num_dst;
424 opcode->num_src = info->num_src;
425
426 /* Destination operands. */
427 for (i = 0; i < info->num_dst; i++) {
428 D3D10_SB_OPERAND_NUM_COMPONENTS num_components;
429
430 assert(!DECODE_IS_D3D10_SB_OPERAND_EXTENDED(*curr));
431
432 num_components = DECODE_D3D10_SB_OPERAND_NUM_COMPONENTS(*curr);
433 if (num_components == D3D10_SB_OPERAND_4_COMPONENT) {
434 D3D10_SB_OPERAND_4_COMPONENT_SELECTION_MODE selection_mode;
435
436 selection_mode = DECODE_D3D10_SB_OPERAND_4_COMPONENT_SELECTION_MODE(*curr);
437 assert(selection_mode == D3D10_SB_OPERAND_4_COMPONENT_MASK_MODE);
438
439 opcode->dst[i].mask = DECODE_D3D10_SB_OPERAND_4_COMPONENT_MASK(*curr);
440 } else {
441 assert(num_components == D3D10_SB_OPERAND_0_COMPONENT ||
442 num_components == D3D10_SB_OPERAND_1_COMPONENT);
443
444 opcode->dst[i].mask = D3D10_SB_OPERAND_4_COMPONENT_MASK_X;
445 }
446
447 parse_operand(&curr, &opcode->dst[i].base);
448 parse_operand_index(&curr, &opcode->dst[i].base);
449 }
450
451 /* Source operands. */
452 for (i = 0; i < info->num_src; i++) {
453 boolean extended;
454 D3D10_SB_OPERAND_NUM_COMPONENTS num_components;
455
456 extended = DECODE_IS_D3D10_SB_OPERAND_EXTENDED(*curr);
457
458 num_components = DECODE_D3D10_SB_OPERAND_NUM_COMPONENTS(*curr);
459 if (num_components == D3D10_SB_OPERAND_4_COMPONENT) {
460 D3D10_SB_OPERAND_4_COMPONENT_SELECTION_MODE selection_mode;
461
462 selection_mode = DECODE_D3D10_SB_OPERAND_4_COMPONENT_SELECTION_MODE(*curr);
463
464 if (selection_mode == D3D10_SB_OPERAND_4_COMPONENT_SWIZZLE_MODE) {
465 opcode->src[i].swizzle[0] = DECODE_D3D10_SB_OPERAND_4_COMPONENT_SWIZZLE_SOURCE(*curr, 0);
466 opcode->src[i].swizzle[1] = DECODE_D3D10_SB_OPERAND_4_COMPONENT_SWIZZLE_SOURCE(*curr, 1);
467 opcode->src[i].swizzle[2] = DECODE_D3D10_SB_OPERAND_4_COMPONENT_SWIZZLE_SOURCE(*curr, 2);
468 opcode->src[i].swizzle[3] = DECODE_D3D10_SB_OPERAND_4_COMPONENT_SWIZZLE_SOURCE(*curr, 3);
469 } else if (selection_mode == D3D10_SB_OPERAND_4_COMPONENT_SELECT_1_MODE) {
470 opcode->src[i].swizzle[0] =
471 opcode->src[i].swizzle[1] =
472 opcode->src[i].swizzle[2] =
473 opcode->src[i].swizzle[3] = DECODE_D3D10_SB_OPERAND_4_COMPONENT_SELECT_1(*curr);
474 } else {
475 /* This case apparently happens only for 4-component 32-bit
476 * immediate operands.
477 */
478 assert(selection_mode == D3D10_SB_OPERAND_4_COMPONENT_MASK_MODE);
479 assert(DECODE_D3D10_SB_OPERAND_4_COMPONENT_MASK(*curr) == 0);
480 assert(DECODE_D3D10_SB_OPERAND_TYPE(*curr) == D3D10_SB_OPERAND_TYPE_IMMEDIATE32);
481
482
483 opcode->src[i].swizzle[0] = D3D10_SB_4_COMPONENT_X;
484 opcode->src[i].swizzle[1] = D3D10_SB_4_COMPONENT_Y;
485 opcode->src[i].swizzle[2] = D3D10_SB_4_COMPONENT_Z;
486 opcode->src[i].swizzle[3] = D3D10_SB_4_COMPONENT_W;
487 }
488 } else if (num_components == D3D10_SB_OPERAND_1_COMPONENT) {
489 opcode->src[i].swizzle[0] =
490 opcode->src[i].swizzle[1] =
491 opcode->src[i].swizzle[2] =
492 opcode->src[i].swizzle[3] = D3D10_SB_4_COMPONENT_X;
493 } else {
494 /* Samplers only?
495 */
496 assert(num_components == D3D10_SB_OPERAND_0_COMPONENT);
497 assert(DECODE_D3D10_SB_OPERAND_TYPE(*curr) == D3D10_SB_OPERAND_TYPE_SAMPLER ||
498 DECODE_D3D10_SB_OPERAND_TYPE(*curr) == D3D10_SB_OPERAND_TYPE_LABEL);
499
500 opcode->src[i].swizzle[0] = D3D10_SB_4_COMPONENT_X;
501 opcode->src[i].swizzle[1] = D3D10_SB_4_COMPONENT_Y;
502 opcode->src[i].swizzle[2] = D3D10_SB_4_COMPONENT_Z;
503 opcode->src[i].swizzle[3] = D3D10_SB_4_COMPONENT_W;
504 }
505
506 parse_operand(&curr, &opcode->src[i].base);
507
508 opcode->src[i].modifier = D3D10_SB_OPERAND_MODIFIER_NONE;
509 if (extended) {
510 /* NOTE: DECODE_IS_D3D10_SB_OPERAND_DOUBLE_EXTENDED is broken.
511 */
512 assert(!((*curr & D3D10_SB_OPERAND_DOUBLE_EXTENDED_MASK) >> D3D10_SB_OPERAND_DOUBLE_EXTENDED_SHIFT));
513
514 switch (DECODE_D3D10_SB_EXTENDED_OPERAND_TYPE(*curr)) {
515 case D3D10_SB_EXTENDED_OPERAND_EMPTY:
516 break;
517
518 case D3D10_SB_EXTENDED_OPERAND_MODIFIER:
519 opcode->src[i].modifier = DECODE_D3D10_SB_OPERAND_MODIFIER(*curr);
520 break;
521
522 default:
523 assert(0);
524 }
525
526 curr++;
527 }
528
529 parse_operand_index(&curr, &opcode->src[i].base);
530
531 if (opcode->src[i].base.type == D3D10_SB_OPERAND_TYPE_IMMEDIATE32) {
532 switch (num_components) {
533 case D3D10_SB_OPERAND_1_COMPONENT:
534 opcode->src[i].imm[0].u32 =
535 opcode->src[i].imm[1].u32 =
536 opcode->src[i].imm[2].u32 =
537 opcode->src[i].imm[3].u32 = *curr++;
538 break;
539
540 case D3D10_SB_OPERAND_4_COMPONENT:
541 opcode->src[i].imm[0].u32 = *curr++;
542 opcode->src[i].imm[1].u32 = *curr++;
543 opcode->src[i].imm[2].u32 = *curr++;
544 opcode->src[i].imm[3].u32 = *curr++;
545 break;
546
547 default:
548 /* XXX: Support other component sizes.
549 */
550 assert(0);
551 }
552 }
553 }
554
555 /* Opcode specific trailing operands. */
556 switch (opcode->type) {
557 case D3D10_SB_OPCODE_DCL_RESOURCE:
558 opcode->dcl_resource_ret_type[0] = DECODE_D3D10_SB_RESOURCE_RETURN_TYPE(*curr, 0);
559 opcode->dcl_resource_ret_type[1] = DECODE_D3D10_SB_RESOURCE_RETURN_TYPE(*curr, 1);
560 opcode->dcl_resource_ret_type[2] = DECODE_D3D10_SB_RESOURCE_RETURN_TYPE(*curr, 2);
561 opcode->dcl_resource_ret_type[3] = DECODE_D3D10_SB_RESOURCE_RETURN_TYPE(*curr, 3);
562 curr++;
563 break;
564 case D3D10_SB_OPCODE_DCL_MAX_OUTPUT_VERTEX_COUNT:
565 opcode->specific.dcl_max_output_vertex_count = *curr;
566 curr++;
567 break;
568 case D3D10_SB_OPCODE_DCL_INPUT_SGV:
569 case D3D10_SB_OPCODE_DCL_INPUT_SIV:
570 case D3D10_SB_OPCODE_DCL_INPUT_PS_SGV:
571 case D3D10_SB_OPCODE_DCL_INPUT_PS_SIV:
572 case D3D10_SB_OPCODE_DCL_OUTPUT_SIV:
573 case D3D10_SB_OPCODE_DCL_OUTPUT_SGV:
574 opcode->dcl_siv_name = DECODE_D3D10_SB_NAME(*curr);
575 curr++;
576 break;
577 case D3D10_SB_OPCODE_DCL_TEMPS:
578 opcode->specific.dcl_num_temps = *curr;
579 curr++;
580 break;
581 case D3D10_SB_OPCODE_DCL_INDEXABLE_TEMP:
582 opcode->specific.dcl_indexable_temp.index = *curr++;
583 opcode->specific.dcl_indexable_temp.count = *curr++;
584 opcode->specific.dcl_indexable_temp.components = *curr++;
585 break;
586 case D3D10_SB_OPCODE_DCL_INDEX_RANGE:
587 opcode->specific.index_range_count = *curr++;
588 break;
589 default:
590 break;
591 }
592
593 assert(curr == parser->curr + length);
594
595 skip:
596 /* Advance to the next opcode. */
597 parser->curr += length;
598
599 return TRUE;
600 }
601
602 void
Shader_opcode_free(struct Shader_opcode * opcode)603 Shader_opcode_free(struct Shader_opcode *opcode)
604 {
605 if (opcode->type == D3D10_SB_OPCODE_CUSTOMDATA) {
606 if (opcode->customdata._class == D3D10_SB_CUSTOMDATA_DCL_IMMEDIATE_CONSTANT_BUFFER) {
607 FREE(opcode->customdata.u.constbuf.data);
608 }
609 }
610 }
611