Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mesa
Path: blob/21.2-virgl/src/gallium/frontends/d3d10umd/ShaderParse.c
4565 views
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
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
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
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
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
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
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_OPCODE_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
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
612