• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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