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 39void 40Shader_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 60struct 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 70static const struct dx10_opcode_info 71opcode_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 188static void 189parse_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 219static void 220parse_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 249static void 250parse_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 272static void 273parse_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 284boolean 285Shader_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 595skip: 596 /* Advance to the next opcode. */ 597 parser->curr += length; 598 599 return TRUE; 600} 601 602void 603Shader_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