1 // Copyright 2016 The SwiftShader Authors. All Rights Reserved. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 #include "PixelShader.hpp" 16 17 #include "Debug.hpp" 18 19 #include <string.h> 20 21 namespace sw 22 { 23 PixelShader::PixelShader(const PixelShader *ps) : Shader() 24 { 25 version = 0x0300; 26 vPosDeclared = false; 27 vFaceDeclared = false; 28 centroid = false; 29 30 if(ps) // Make a copy 31 { 32 for(size_t i = 0; i < ps->getLength(); i++) 33 { 34 append(new sw::Shader::Instruction(*ps->getInstruction(i))); 35 } 36 37 memcpy(semantic, ps->semantic, sizeof(semantic)); 38 vPosDeclared = ps->vPosDeclared; 39 vFaceDeclared = ps->vFaceDeclared; 40 usedSamplers = ps->usedSamplers; 41 42 optimize(); 43 analyze(); 44 } 45 } 46 47 PixelShader::PixelShader(const unsigned long *token) : Shader() 48 { 49 parse(token); 50 51 vPosDeclared = false; 52 vFaceDeclared = false; 53 centroid = false; 54 55 optimize(); 56 analyze(); 57 } 58 59 PixelShader::~PixelShader() 60 { 61 } 62 63 int PixelShader::validate(const unsigned long *const token) 64 { 65 if(!token) 66 { 67 return 0; 68 } 69 70 unsigned short version = (unsigned short)(token[0] & 0x0000FFFF); 71 unsigned char minorVersion = (unsigned char)(token[0] & 0x000000FF); 72 unsigned char majorVersion = (unsigned char)((token[0] & 0x0000FF00) >> 8); 73 ShaderType shaderType = (ShaderType)((token[0] & 0xFFFF0000) >> 16); 74 75 if(shaderType != SHADER_PIXEL || majorVersion > 3) 76 { 77 return 0; 78 } 79 80 int instructionCount = 1; 81 82 for(int i = 0; token[i] != 0x0000FFFF; i++) 83 { 84 if((token[i] & 0x0000FFFF) == 0x0000FFFE) // Comment token 85 { 86 int length = (token[i] & 0x7FFF0000) >> 16; 87 88 i += length; 89 } 90 else 91 { 92 Shader::Opcode opcode = (Shader::Opcode)(token[i] & 0x0000FFFF); 93 94 switch(opcode) 95 { 96 case Shader::OPCODE_RESERVED0: 97 case Shader::OPCODE_MOVA: 98 return 0; // Unsupported operation 99 default: 100 instructionCount++; 101 break; 102 } 103 104 i += size(token[i], version); 105 } 106 } 107 108 return instructionCount; 109 } 110 111 bool PixelShader::depthOverride() const 112 { 113 return zOverride; 114 } 115 116 bool PixelShader::containsKill() const 117 { 118 return kill; 119 } 120 121 bool PixelShader::containsCentroid() const 122 { 123 return centroid; 124 } 125 126 bool PixelShader::usesDiffuse(int component) const 127 { 128 return semantic[0][component].active(); 129 } 130 131 bool PixelShader::usesSpecular(int component) const 132 { 133 return semantic[1][component].active(); 134 } 135 136 bool PixelShader::usesTexture(int coordinate, int component) const 137 { 138 return semantic[2 + coordinate][component].active(); 139 } 140 141 void PixelShader::analyze() 142 { 143 analyzeZOverride(); 144 analyzeKill(); 145 analyzeInterpolants(); 146 analyzeDirtyConstants(); 147 analyzeDynamicBranching(); 148 analyzeSamplers(); 149 analyzeCallSites(); 150 analyzeDynamicIndexing(); 151 } 152 153 void PixelShader::analyzeZOverride() 154 { 155 zOverride = false; 156 157 for(unsigned int i = 0; i < instruction.size(); i++) 158 { 159 if(instruction[i]->opcode == Shader::OPCODE_TEXM3X2DEPTH || 160 instruction[i]->opcode == Shader::OPCODE_TEXDEPTH || 161 instruction[i]->dst.type == Shader::PARAMETER_DEPTHOUT) 162 { 163 zOverride = true; 164 165 break; 166 } 167 } 168 } 169 170 void PixelShader::analyzeKill() 171 { 172 kill = false; 173 174 for(unsigned int i = 0; i < instruction.size(); i++) 175 { 176 if(instruction[i]->opcode == Shader::OPCODE_TEXKILL || 177 instruction[i]->opcode == Shader::OPCODE_DISCARD) 178 { 179 kill = true; 180 181 break; 182 } 183 } 184 } 185 186 void PixelShader::analyzeInterpolants() 187 { 188 if(version < 0x0300) 189 { 190 // Set default mapping; disable unused interpolants below 191 semantic[0][0] = Semantic(Shader::USAGE_COLOR, 0); 192 semantic[0][1] = Semantic(Shader::USAGE_COLOR, 0); 193 semantic[0][2] = Semantic(Shader::USAGE_COLOR, 0); 194 semantic[0][3] = Semantic(Shader::USAGE_COLOR, 0); 195 196 semantic[1][0] = Semantic(Shader::USAGE_COLOR, 1); 197 semantic[1][1] = Semantic(Shader::USAGE_COLOR, 1); 198 semantic[1][2] = Semantic(Shader::USAGE_COLOR, 1); 199 semantic[1][3] = Semantic(Shader::USAGE_COLOR, 1); 200 201 for(int i = 0; i < 8; i++) 202 { 203 semantic[2 + i][0] = Semantic(Shader::USAGE_TEXCOORD, i); 204 semantic[2 + i][1] = Semantic(Shader::USAGE_TEXCOORD, i); 205 semantic[2 + i][2] = Semantic(Shader::USAGE_TEXCOORD, i); 206 semantic[2 + i][3] = Semantic(Shader::USAGE_TEXCOORD, i); 207 } 208 209 Shader::SamplerType samplerType[16]; 210 211 for(int i = 0; i < 16; i++) 212 { 213 samplerType[i] = Shader::SAMPLER_UNKNOWN; 214 } 215 216 for(unsigned int i = 0; i < instruction.size(); i++) 217 { 218 if(instruction[i]->dst.type == Shader::PARAMETER_SAMPLER) 219 { 220 int sampler = instruction[i]->dst.index; 221 222 samplerType[sampler] = instruction[i]->samplerType; 223 } 224 } 225 226 bool interpolant[MAX_FRAGMENT_INPUTS][4] = {{false}}; // Interpolants in use 227 228 for(unsigned int i = 0; i < instruction.size(); i++) 229 { 230 if(instruction[i]->dst.type == Shader::PARAMETER_TEXTURE) 231 { 232 int index = instruction[i]->dst.index + 2; 233 int mask = instruction[i]->dst.mask; 234 235 switch(instruction[i]->opcode) 236 { 237 case Shader::OPCODE_TEX: 238 case Shader::OPCODE_TEXBEM: 239 case Shader::OPCODE_TEXBEML: 240 case Shader::OPCODE_TEXCOORD: 241 case Shader::OPCODE_TEXDP3: 242 case Shader::OPCODE_TEXDP3TEX: 243 case Shader::OPCODE_TEXM3X2DEPTH: 244 case Shader::OPCODE_TEXM3X2PAD: 245 case Shader::OPCODE_TEXM3X2TEX: 246 case Shader::OPCODE_TEXM3X3: 247 case Shader::OPCODE_TEXM3X3PAD: 248 case Shader::OPCODE_TEXM3X3TEX: 249 interpolant[index][0] = true; 250 interpolant[index][1] = true; 251 interpolant[index][2] = true; 252 break; 253 case Shader::OPCODE_TEXKILL: 254 if(majorVersion < 2) 255 { 256 interpolant[index][0] = true; 257 interpolant[index][1] = true; 258 interpolant[index][2] = true; 259 } 260 else 261 { 262 interpolant[index][0] = true; 263 interpolant[index][1] = true; 264 interpolant[index][2] = true; 265 interpolant[index][3] = true; 266 } 267 break; 268 case Shader::OPCODE_TEXM3X3VSPEC: 269 interpolant[index][0] = true; 270 interpolant[index][1] = true; 271 interpolant[index][2] = true; 272 interpolant[index - 2][3] = true; 273 interpolant[index - 1][3] = true; 274 interpolant[index - 0][3] = true; 275 break; 276 case Shader::OPCODE_DCL: 277 break; // Ignore 278 default: // Arithmetic instruction 279 if(version >= 0x0104) 280 { 281 ASSERT(false); 282 } 283 } 284 } 285 286 for(int argument = 0; argument < 4; argument++) 287 { 288 if(instruction[i]->src[argument].type == Shader::PARAMETER_INPUT || 289 instruction[i]->src[argument].type == Shader::PARAMETER_TEXTURE) 290 { 291 int index = instruction[i]->src[argument].index; 292 int swizzle = instruction[i]->src[argument].swizzle; 293 int mask = instruction[i]->dst.mask; 294 295 if(instruction[i]->src[argument].type == Shader::PARAMETER_TEXTURE) 296 { 297 index += 2; 298 } 299 300 switch(instruction[i]->opcode) 301 { 302 case Shader::OPCODE_TEX: 303 case Shader::OPCODE_TEXLDD: 304 case Shader::OPCODE_TEXLDL: 305 case Shader::OPCODE_TEXOFFSET: 306 case Shader::OPCODE_TEXLDLOFFSET: 307 case Shader::OPCODE_TEXELFETCH: 308 case Shader::OPCODE_TEXELFETCHOFFSET: 309 case Shader::OPCODE_TEXGRAD: 310 case Shader::OPCODE_TEXGRADOFFSET: 311 { 312 int sampler = instruction[i]->src[1].index; 313 314 switch(samplerType[sampler]) 315 { 316 case Shader::SAMPLER_UNKNOWN: 317 if(version == 0x0104) 318 { 319 if((instruction[i]->src[0].swizzle & 0x30) == 0x20) // .xyz 320 { 321 interpolant[index][0] = true; 322 interpolant[index][1] = true; 323 interpolant[index][2] = true; 324 } 325 else // .xyw 326 { 327 interpolant[index][0] = true; 328 interpolant[index][1] = true; 329 interpolant[index][3] = true; 330 } 331 } 332 else 333 { 334 ASSERT(false); 335 } 336 break; 337 case Shader::SAMPLER_1D: 338 interpolant[index][0] = true; 339 break; 340 case Shader::SAMPLER_2D: 341 interpolant[index][0] = true; 342 interpolant[index][1] = true; 343 break; 344 case Shader::SAMPLER_CUBE: 345 interpolant[index][0] = true; 346 interpolant[index][1] = true; 347 interpolant[index][2] = true; 348 break; 349 case Shader::SAMPLER_VOLUME: 350 interpolant[index][0] = true; 351 interpolant[index][1] = true; 352 interpolant[index][2] = true; 353 break; 354 default: 355 ASSERT(false); 356 } 357 358 if(instruction[i]->bias) 359 { 360 interpolant[index][3] = true; 361 } 362 363 if(instruction[i]->project) 364 { 365 interpolant[index][3] = true; 366 } 367 368 if(version == 0x0104 && instruction[i]->opcode == Shader::OPCODE_TEX) 369 { 370 if(instruction[i]->src[0].modifier == Shader::MODIFIER_DZ) 371 { 372 interpolant[index][2] = true; 373 } 374 375 if(instruction[i]->src[0].modifier == Shader::MODIFIER_DW) 376 { 377 interpolant[index][3] = true; 378 } 379 } 380 } 381 break; 382 case Shader::OPCODE_M3X2: 383 if(mask & 0x1) 384 { 385 interpolant[index][0] |= swizzleContainsComponentMasked(swizzle, 0, 0x7); 386 interpolant[index][1] |= swizzleContainsComponentMasked(swizzle, 1, 0x7); 387 interpolant[index][2] |= swizzleContainsComponentMasked(swizzle, 2, 0x7); 388 interpolant[index][3] |= swizzleContainsComponentMasked(swizzle, 3, 0x7); 389 } 390 391 if(argument == 1) 392 { 393 if(mask & 0x2) 394 { 395 interpolant[index + 1][0] |= swizzleContainsComponentMasked(swizzle, 0, 0x7); 396 interpolant[index + 1][1] |= swizzleContainsComponentMasked(swizzle, 1, 0x7); 397 interpolant[index + 1][2] |= swizzleContainsComponentMasked(swizzle, 2, 0x7); 398 interpolant[index + 1][3] |= swizzleContainsComponentMasked(swizzle, 3, 0x7); 399 } 400 } 401 break; 402 case Shader::OPCODE_M3X3: 403 if(mask & 0x1) 404 { 405 interpolant[index][0] |= swizzleContainsComponentMasked(swizzle, 0, 0x7); 406 interpolant[index][1] |= swizzleContainsComponentMasked(swizzle, 1, 0x7); 407 interpolant[index][2] |= swizzleContainsComponentMasked(swizzle, 2, 0x7); 408 interpolant[index][3] |= swizzleContainsComponentMasked(swizzle, 3, 0x7); 409 } 410 411 if(argument == 1) 412 { 413 if(mask & 0x2) 414 { 415 interpolant[index + 1][0] |= swizzleContainsComponentMasked(swizzle, 0, 0x7); 416 interpolant[index + 1][1] |= swizzleContainsComponentMasked(swizzle, 1, 0x7); 417 interpolant[index + 1][2] |= swizzleContainsComponentMasked(swizzle, 2, 0x7); 418 interpolant[index + 1][3] |= swizzleContainsComponentMasked(swizzle, 3, 0x7); 419 } 420 421 if(mask & 0x4) 422 { 423 interpolant[index + 2][0] |= swizzleContainsComponentMasked(swizzle, 0, 0x7); 424 interpolant[index + 2][1] |= swizzleContainsComponentMasked(swizzle, 1, 0x7); 425 interpolant[index + 2][2] |= swizzleContainsComponentMasked(swizzle, 2, 0x7); 426 interpolant[index + 2][3] |= swizzleContainsComponentMasked(swizzle, 3, 0x7); 427 } 428 } 429 break; 430 case Shader::OPCODE_M3X4: 431 if(mask & 0x1) 432 { 433 interpolant[index][0] |= swizzleContainsComponentMasked(swizzle, 0, 0x7); 434 interpolant[index][1] |= swizzleContainsComponentMasked(swizzle, 1, 0x7); 435 interpolant[index][2] |= swizzleContainsComponentMasked(swizzle, 2, 0x7); 436 interpolant[index][3] |= swizzleContainsComponentMasked(swizzle, 3, 0x7); 437 } 438 439 if(argument == 1) 440 { 441 if(mask & 0x2) 442 { 443 interpolant[index + 1][0] |= swizzleContainsComponentMasked(swizzle, 0, 0x7); 444 interpolant[index + 1][1] |= swizzleContainsComponentMasked(swizzle, 1, 0x7); 445 interpolant[index + 1][2] |= swizzleContainsComponentMasked(swizzle, 2, 0x7); 446 interpolant[index + 1][3] |= swizzleContainsComponentMasked(swizzle, 3, 0x7); 447 } 448 449 if(mask & 0x4) 450 { 451 interpolant[index + 2][0] |= swizzleContainsComponentMasked(swizzle, 0, 0x7); 452 interpolant[index + 2][1] |= swizzleContainsComponentMasked(swizzle, 1, 0x7); 453 interpolant[index + 2][2] |= swizzleContainsComponentMasked(swizzle, 2, 0x7); 454 interpolant[index + 2][3] |= swizzleContainsComponentMasked(swizzle, 3, 0x7); 455 } 456 457 if(mask & 0x8) 458 { 459 interpolant[index + 3][0] |= swizzleContainsComponentMasked(swizzle, 0, 0x7); 460 interpolant[index + 3][1] |= swizzleContainsComponentMasked(swizzle, 1, 0x7); 461 interpolant[index + 3][2] |= swizzleContainsComponentMasked(swizzle, 2, 0x7); 462 interpolant[index + 3][3] |= swizzleContainsComponentMasked(swizzle, 3, 0x7); 463 } 464 } 465 break; 466 case Shader::OPCODE_M4X3: 467 if(mask & 0x1) 468 { 469 interpolant[index][0] |= swizzleContainsComponent(swizzle, 0); 470 interpolant[index][1] |= swizzleContainsComponent(swizzle, 1); 471 interpolant[index][2] |= swizzleContainsComponent(swizzle, 2); 472 interpolant[index][3] |= swizzleContainsComponent(swizzle, 3); 473 } 474 475 if(argument == 1) 476 { 477 if(mask & 0x2) 478 { 479 interpolant[index + 1][0] |= swizzleContainsComponent(swizzle, 0); 480 interpolant[index + 1][1] |= swizzleContainsComponent(swizzle, 1); 481 interpolant[index + 1][2] |= swizzleContainsComponent(swizzle, 2); 482 interpolant[index + 1][3] |= swizzleContainsComponent(swizzle, 3); 483 } 484 485 if(mask & 0x4) 486 { 487 interpolant[index + 2][0] |= swizzleContainsComponent(swizzle, 0); 488 interpolant[index + 2][1] |= swizzleContainsComponent(swizzle, 1); 489 interpolant[index + 2][2] |= swizzleContainsComponent(swizzle, 2); 490 interpolant[index + 2][3] |= swizzleContainsComponent(swizzle, 3); 491 } 492 } 493 break; 494 case Shader::OPCODE_M4X4: 495 if(mask & 0x1) 496 { 497 interpolant[index][0] |= swizzleContainsComponent(swizzle, 0); 498 interpolant[index][1] |= swizzleContainsComponent(swizzle, 1); 499 interpolant[index][2] |= swizzleContainsComponent(swizzle, 2); 500 interpolant[index][3] |= swizzleContainsComponent(swizzle, 3); 501 } 502 503 if(argument == 1) 504 { 505 if(mask & 0x2) 506 { 507 interpolant[index + 1][0] |= swizzleContainsComponent(swizzle, 0); 508 interpolant[index + 1][1] |= swizzleContainsComponent(swizzle, 1); 509 interpolant[index + 1][2] |= swizzleContainsComponent(swizzle, 2); 510 interpolant[index + 1][3] |= swizzleContainsComponent(swizzle, 3); 511 } 512 513 if(mask & 0x4) 514 { 515 interpolant[index + 2][0] |= swizzleContainsComponent(swizzle, 0); 516 interpolant[index + 2][1] |= swizzleContainsComponent(swizzle, 1); 517 interpolant[index + 2][2] |= swizzleContainsComponent(swizzle, 2); 518 interpolant[index + 2][3] |= swizzleContainsComponent(swizzle, 3); 519 } 520 521 if(mask & 0x8) 522 { 523 interpolant[index + 3][0] |= swizzleContainsComponent(swizzle, 0); 524 interpolant[index + 3][1] |= swizzleContainsComponent(swizzle, 1); 525 interpolant[index + 3][2] |= swizzleContainsComponent(swizzle, 2); 526 interpolant[index + 3][3] |= swizzleContainsComponent(swizzle, 3); 527 } 528 } 529 break; 530 case Shader::OPCODE_CRS: 531 if(mask & 0x1) 532 { 533 interpolant[index][0] |= swizzleContainsComponentMasked(swizzle, 0, 0x6); 534 interpolant[index][1] |= swizzleContainsComponentMasked(swizzle, 1, 0x6); 535 interpolant[index][2] |= swizzleContainsComponentMasked(swizzle, 2, 0x6); 536 interpolant[index][3] |= swizzleContainsComponentMasked(swizzle, 3, 0x6); 537 } 538 539 if(mask & 0x2) 540 { 541 interpolant[index][0] |= swizzleContainsComponentMasked(swizzle, 0, 0x5); 542 interpolant[index][1] |= swizzleContainsComponentMasked(swizzle, 1, 0x5); 543 interpolant[index][2] |= swizzleContainsComponentMasked(swizzle, 2, 0x5); 544 interpolant[index][3] |= swizzleContainsComponentMasked(swizzle, 3, 0x5); 545 } 546 547 if(mask & 0x4) 548 { 549 interpolant[index][0] |= swizzleContainsComponentMasked(swizzle, 0, 0x3); 550 interpolant[index][1] |= swizzleContainsComponentMasked(swizzle, 1, 0x3); 551 interpolant[index][2] |= swizzleContainsComponentMasked(swizzle, 2, 0x3); 552 interpolant[index][3] |= swizzleContainsComponentMasked(swizzle, 3, 0x3); 553 } 554 break; 555 case Shader::OPCODE_DP2ADD: 556 if(argument == 0 || argument == 1) 557 { 558 interpolant[index][0] |= swizzleContainsComponentMasked(swizzle, 0, 0x3); 559 interpolant[index][1] |= swizzleContainsComponentMasked(swizzle, 1, 0x3); 560 interpolant[index][2] |= swizzleContainsComponentMasked(swizzle, 2, 0x3); 561 interpolant[index][3] |= swizzleContainsComponentMasked(swizzle, 3, 0x3); 562 } 563 else // argument == 2 564 { 565 interpolant[index][0] |= swizzleContainsComponent(swizzle, 0); 566 interpolant[index][1] |= swizzleContainsComponent(swizzle, 1); 567 interpolant[index][2] |= swizzleContainsComponent(swizzle, 2); 568 interpolant[index][3] |= swizzleContainsComponent(swizzle, 3); 569 } 570 break; 571 case Shader::OPCODE_DP3: 572 interpolant[index][0] |= swizzleContainsComponentMasked(swizzle, 0, 0x7); 573 interpolant[index][1] |= swizzleContainsComponentMasked(swizzle, 1, 0x7); 574 interpolant[index][2] |= swizzleContainsComponentMasked(swizzle, 2, 0x7); 575 interpolant[index][3] |= swizzleContainsComponentMasked(swizzle, 3, 0x7); 576 break; 577 case Shader::OPCODE_DP4: 578 interpolant[index][0] |= swizzleContainsComponent(swizzle, 0); 579 interpolant[index][1] |= swizzleContainsComponent(swizzle, 1); 580 interpolant[index][2] |= swizzleContainsComponent(swizzle, 2); 581 interpolant[index][3] |= swizzleContainsComponent(swizzle, 3); 582 break; 583 case Shader::OPCODE_SINCOS: 584 case Shader::OPCODE_EXP2X: 585 case Shader::OPCODE_LOG2X: 586 case Shader::OPCODE_POWX: 587 case Shader::OPCODE_RCPX: 588 case Shader::OPCODE_RSQX: 589 interpolant[index][0] |= swizzleContainsComponent(swizzle, 0); 590 interpolant[index][1] |= swizzleContainsComponent(swizzle, 1); 591 interpolant[index][2] |= swizzleContainsComponent(swizzle, 2); 592 interpolant[index][3] |= swizzleContainsComponent(swizzle, 3); 593 break; 594 case Shader::OPCODE_NRM3: 595 interpolant[index][0] |= swizzleContainsComponentMasked(swizzle, 0, 0x7 | mask); 596 interpolant[index][1] |= swizzleContainsComponentMasked(swizzle, 1, 0x7 | mask); 597 interpolant[index][2] |= swizzleContainsComponentMasked(swizzle, 2, 0x7 | mask); 598 interpolant[index][3] |= swizzleContainsComponentMasked(swizzle, 3, 0x7 | mask); 599 break; 600 case Shader::OPCODE_MOV: 601 case Shader::OPCODE_ADD: 602 case Shader::OPCODE_SUB: 603 case Shader::OPCODE_MUL: 604 case Shader::OPCODE_MAD: 605 case Shader::OPCODE_ABS: 606 case Shader::OPCODE_CMP0: 607 case Shader::OPCODE_CND: 608 case Shader::OPCODE_FRC: 609 case Shader::OPCODE_LRP: 610 case Shader::OPCODE_MAX: 611 case Shader::OPCODE_MIN: 612 case Shader::OPCODE_CMP: 613 case Shader::OPCODE_BREAKC: 614 case Shader::OPCODE_DFDX: 615 case Shader::OPCODE_DFDY: 616 interpolant[index][0] |= swizzleContainsComponentMasked(swizzle, 0, mask); 617 interpolant[index][1] |= swizzleContainsComponentMasked(swizzle, 1, mask); 618 interpolant[index][2] |= swizzleContainsComponentMasked(swizzle, 2, mask); 619 interpolant[index][3] |= swizzleContainsComponentMasked(swizzle, 3, mask); 620 break; 621 case Shader::OPCODE_TEXCOORD: 622 interpolant[index][0] = true; 623 interpolant[index][1] = true; 624 interpolant[index][2] = true; 625 interpolant[index][3] = true; 626 break; 627 case Shader::OPCODE_TEXDP3: 628 case Shader::OPCODE_TEXDP3TEX: 629 case Shader::OPCODE_TEXM3X2PAD: 630 case Shader::OPCODE_TEXM3X3PAD: 631 case Shader::OPCODE_TEXM3X2TEX: 632 case Shader::OPCODE_TEXM3X3SPEC: 633 case Shader::OPCODE_TEXM3X3VSPEC: 634 case Shader::OPCODE_TEXBEM: 635 case Shader::OPCODE_TEXBEML: 636 case Shader::OPCODE_TEXM3X2DEPTH: 637 case Shader::OPCODE_TEXM3X3: 638 case Shader::OPCODE_TEXM3X3TEX: 639 interpolant[index][0] = true; 640 interpolant[index][1] = true; 641 interpolant[index][2] = true; 642 break; 643 case Shader::OPCODE_TEXREG2AR: 644 case Shader::OPCODE_TEXREG2GB: 645 case Shader::OPCODE_TEXREG2RGB: 646 break; 647 default: 648 // ASSERT(false); // Refine component usage 649 interpolant[index][0] = true; 650 interpolant[index][1] = true; 651 interpolant[index][2] = true; 652 interpolant[index][3] = true; 653 } 654 } 655 } 656 } 657 658 for(int index = 0; index < MAX_FRAGMENT_INPUTS; index++) 659 { 660 for(int component = 0; component < 4; component++) 661 { 662 if(!interpolant[index][component]) 663 { 664 semantic[index][component] = Semantic(); 665 } 666 } 667 } 668 } 669 else // Shader Model 3.0 input declaration; v# indexable 670 { 671 for(unsigned int i = 0; i < instruction.size(); i++) 672 { 673 if(instruction[i]->opcode == Shader::OPCODE_DCL) 674 { 675 if(instruction[i]->dst.type == Shader::PARAMETER_INPUT) 676 { 677 unsigned char usage = instruction[i]->usage; 678 unsigned char index = instruction[i]->usageIndex; 679 unsigned char mask = instruction[i]->dst.mask; 680 unsigned char reg = instruction[i]->dst.index; 681 682 if(mask & 0x01) semantic[reg][0] = Semantic(usage, index); 683 if(mask & 0x02) semantic[reg][1] = Semantic(usage, index); 684 if(mask & 0x04) semantic[reg][2] = Semantic(usage, index); 685 if(mask & 0x08) semantic[reg][3] = Semantic(usage, index); 686 } 687 else if(instruction[i]->dst.type == Shader::PARAMETER_MISCTYPE) 688 { 689 unsigned char index = instruction[i]->dst.index; 690 691 if(index == 0) 692 { 693 vPosDeclared = true; 694 } 695 else if(index == 1) 696 { 697 vFaceDeclared = true; 698 } 699 else ASSERT(false); 700 } 701 } 702 } 703 } 704 705 if(version >= 0x0200) 706 { 707 for(unsigned int i = 0; i < instruction.size(); i++) 708 { 709 if(instruction[i]->opcode == Shader::OPCODE_DCL) 710 { 711 bool centroid = instruction[i]->dst.centroid; 712 unsigned char reg = instruction[i]->dst.index; 713 714 switch(instruction[i]->dst.type) 715 { 716 case Shader::PARAMETER_INPUT: 717 semantic[reg][0].centroid = centroid; 718 break; 719 case Shader::PARAMETER_TEXTURE: 720 semantic[2 + reg][0].centroid = centroid; 721 break; 722 default: 723 break; 724 } 725 726 this->centroid = this->centroid || centroid; 727 } 728 } 729 } 730 } 731 } 732