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