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 "Common/Debug.hpp" 18 19 #include <string.h> 20 21 namespace sw 22 { PixelShader(const PixelShader * ps)23 PixelShader::PixelShader(const PixelShader *ps) : Shader() 24 { 25 shaderModel = 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(input, ps->input, sizeof(input)); 38 vPosDeclared = ps->vPosDeclared; 39 vFaceDeclared = ps->vFaceDeclared; 40 usedSamplers = ps->usedSamplers; 41 42 optimize(); 43 analyze(); 44 } 45 } 46 PixelShader(const unsigned long * token)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 ~PixelShader()59 PixelShader::~PixelShader() 60 { 61 } 62 validate(const unsigned long * const token)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 depthOverride() const111 bool PixelShader::depthOverride() const 112 { 113 return zOverride; 114 } 115 containsKill() const116 bool PixelShader::containsKill() const 117 { 118 return kill; 119 } 120 containsCentroid() const121 bool PixelShader::containsCentroid() const 122 { 123 return centroid; 124 } 125 usesDiffuse(int component) const126 bool PixelShader::usesDiffuse(int component) const 127 { 128 return input[0][component].active(); 129 } 130 usesSpecular(int component) const131 bool PixelShader::usesSpecular(int component) const 132 { 133 return input[1][component].active(); 134 } 135 usesTexture(int coordinate,int component) const136 bool PixelShader::usesTexture(int coordinate, int component) const 137 { 138 return input[2 + coordinate][component].active(); 139 } 140 setInput(int inputIdx,int nbComponents,const sw::Shader::Semantic & semantic)141 void PixelShader::setInput(int inputIdx, int nbComponents, const sw::Shader::Semantic& semantic) 142 { 143 for(int i = 0; i < nbComponents; ++i) 144 { 145 input[inputIdx][i] = semantic; 146 } 147 } 148 getInput(int inputIdx,int component) const149 const sw::Shader::Semantic& PixelShader::getInput(int inputIdx, int component) const 150 { 151 return input[inputIdx][component]; 152 } 153 analyze()154 void PixelShader::analyze() 155 { 156 analyzeZOverride(); 157 analyzeKill(); 158 analyzeInterpolants(); 159 analyzeDirtyConstants(); 160 analyzeDynamicBranching(); 161 analyzeSamplers(); 162 analyzeCallSites(); 163 analyzeIndirectAddressing(); 164 analyzeLimits(); 165 } 166 analyzeZOverride()167 void PixelShader::analyzeZOverride() 168 { 169 zOverride = false; 170 171 for(const auto &inst : instruction) 172 { 173 if(inst->opcode == Shader::OPCODE_TEXM3X2DEPTH || 174 inst->opcode == Shader::OPCODE_TEXDEPTH || 175 inst->dst.type == Shader::PARAMETER_DEPTHOUT) 176 { 177 zOverride = true; 178 179 break; 180 } 181 } 182 } 183 analyzeKill()184 void PixelShader::analyzeKill() 185 { 186 kill = false; 187 188 for(const auto &inst : instruction) 189 { 190 if(inst->opcode == Shader::OPCODE_TEXKILL || 191 inst->opcode == Shader::OPCODE_DISCARD) 192 { 193 kill = true; 194 195 break; 196 } 197 } 198 } 199 analyzeInterpolants()200 void PixelShader::analyzeInterpolants() 201 { 202 if(shaderModel < 0x0300) 203 { 204 // Set default mapping; disable unused interpolants below 205 input[0][0] = Semantic(Shader::USAGE_COLOR, 0); 206 input[0][1] = Semantic(Shader::USAGE_COLOR, 0); 207 input[0][2] = Semantic(Shader::USAGE_COLOR, 0); 208 input[0][3] = Semantic(Shader::USAGE_COLOR, 0); 209 210 input[1][0] = Semantic(Shader::USAGE_COLOR, 1); 211 input[1][1] = Semantic(Shader::USAGE_COLOR, 1); 212 input[1][2] = Semantic(Shader::USAGE_COLOR, 1); 213 input[1][3] = Semantic(Shader::USAGE_COLOR, 1); 214 215 for(int i = 0; i < 8; i++) 216 { 217 input[2 + i][0] = Semantic(Shader::USAGE_TEXCOORD, i); 218 input[2 + i][1] = Semantic(Shader::USAGE_TEXCOORD, i); 219 input[2 + i][2] = Semantic(Shader::USAGE_TEXCOORD, i); 220 input[2 + i][3] = Semantic(Shader::USAGE_TEXCOORD, i); 221 } 222 223 Shader::SamplerType samplerType[16]; 224 225 for(int i = 0; i < 16; i++) 226 { 227 samplerType[i] = Shader::SAMPLER_UNKNOWN; 228 } 229 230 for(const auto &inst : instruction) 231 { 232 if(inst->dst.type == Shader::PARAMETER_SAMPLER) 233 { 234 int sampler = inst->dst.index; 235 236 samplerType[sampler] = inst->samplerType; 237 } 238 } 239 240 bool interpolant[MAX_FRAGMENT_INPUTS][4] = {{false}}; // Interpolants in use 241 242 for(const auto &inst : instruction) 243 { 244 if(inst->dst.type == Shader::PARAMETER_TEXTURE) 245 { 246 int index = inst->dst.index + 2; 247 248 switch(inst->opcode) 249 { 250 case Shader::OPCODE_TEX: 251 case Shader::OPCODE_TEXBEM: 252 case Shader::OPCODE_TEXBEML: 253 case Shader::OPCODE_TEXCOORD: 254 case Shader::OPCODE_TEXDP3: 255 case Shader::OPCODE_TEXDP3TEX: 256 case Shader::OPCODE_TEXM3X2DEPTH: 257 case Shader::OPCODE_TEXM3X2PAD: 258 case Shader::OPCODE_TEXM3X2TEX: 259 case Shader::OPCODE_TEXM3X3: 260 case Shader::OPCODE_TEXM3X3PAD: 261 case Shader::OPCODE_TEXM3X3TEX: 262 interpolant[index][0] = true; 263 interpolant[index][1] = true; 264 interpolant[index][2] = true; 265 break; 266 case Shader::OPCODE_TEXKILL: 267 if(majorVersion < 2) 268 { 269 interpolant[index][0] = true; 270 interpolant[index][1] = true; 271 interpolant[index][2] = true; 272 } 273 else 274 { 275 interpolant[index][0] = true; 276 interpolant[index][1] = true; 277 interpolant[index][2] = true; 278 interpolant[index][3] = true; 279 } 280 break; 281 case Shader::OPCODE_TEXM3X3VSPEC: 282 interpolant[index][0] = true; 283 interpolant[index][1] = true; 284 interpolant[index][2] = true; 285 interpolant[index - 2][3] = true; 286 interpolant[index - 1][3] = true; 287 interpolant[index - 0][3] = true; 288 break; 289 case Shader::OPCODE_DCL: 290 break; // Ignore 291 default: // Arithmetic instruction 292 if(shaderModel >= 0x0104) 293 { 294 ASSERT(false); 295 } 296 } 297 } 298 299 for(int argument = 0; argument < 4; argument++) 300 { 301 if(inst->src[argument].type == Shader::PARAMETER_INPUT || 302 inst->src[argument].type == Shader::PARAMETER_TEXTURE) 303 { 304 int index = inst->src[argument].index; 305 int swizzle = inst->src[argument].swizzle; 306 int mask = inst->dst.mask; 307 308 if(inst->src[argument].type == Shader::PARAMETER_TEXTURE) 309 { 310 index += 2; 311 } 312 313 switch(inst->opcode) 314 { 315 case Shader::OPCODE_TEX: 316 case Shader::OPCODE_TEXLDD: 317 case Shader::OPCODE_TEXLDL: 318 case Shader::OPCODE_TEXLOD: 319 case Shader::OPCODE_TEXBIAS: 320 case Shader::OPCODE_TEXOFFSET: 321 case Shader::OPCODE_TEXOFFSETBIAS: 322 case Shader::OPCODE_TEXLODOFFSET: 323 case Shader::OPCODE_TEXELFETCH: 324 case Shader::OPCODE_TEXELFETCHOFFSET: 325 case Shader::OPCODE_TEXGRAD: 326 case Shader::OPCODE_TEXGRADOFFSET: 327 { 328 int sampler = inst->src[1].index; 329 330 switch(samplerType[sampler]) 331 { 332 case Shader::SAMPLER_UNKNOWN: 333 if(shaderModel == 0x0104) 334 { 335 if((inst->src[0].swizzle & 0x30) == 0x20) // .xyz 336 { 337 interpolant[index][0] = true; 338 interpolant[index][1] = true; 339 interpolant[index][2] = true; 340 } 341 else // .xyw 342 { 343 interpolant[index][0] = true; 344 interpolant[index][1] = true; 345 interpolant[index][3] = true; 346 } 347 } 348 else 349 { 350 ASSERT(false); 351 } 352 break; 353 case Shader::SAMPLER_1D: 354 interpolant[index][0] = true; 355 break; 356 case Shader::SAMPLER_2D: 357 interpolant[index][0] = true; 358 interpolant[index][1] = true; 359 break; 360 case Shader::SAMPLER_CUBE: 361 interpolant[index][0] = true; 362 interpolant[index][1] = true; 363 interpolant[index][2] = true; 364 break; 365 case Shader::SAMPLER_VOLUME: 366 interpolant[index][0] = true; 367 interpolant[index][1] = true; 368 interpolant[index][2] = true; 369 break; 370 default: 371 ASSERT(false); 372 } 373 374 if(inst->bias) 375 { 376 interpolant[index][3] = true; 377 } 378 379 if(inst->project) 380 { 381 interpolant[index][3] = true; 382 } 383 384 if(shaderModel == 0x0104 && inst->opcode == Shader::OPCODE_TEX) 385 { 386 if(inst->src[0].modifier == Shader::MODIFIER_DZ) 387 { 388 interpolant[index][2] = true; 389 } 390 391 if(inst->src[0].modifier == Shader::MODIFIER_DW) 392 { 393 interpolant[index][3] = true; 394 } 395 } 396 } 397 break; 398 case Shader::OPCODE_M3X2: 399 if(mask & 0x1) 400 { 401 interpolant[index][0] |= swizzleContainsComponentMasked(swizzle, 0, 0x7); 402 interpolant[index][1] |= swizzleContainsComponentMasked(swizzle, 1, 0x7); 403 interpolant[index][2] |= swizzleContainsComponentMasked(swizzle, 2, 0x7); 404 interpolant[index][3] |= swizzleContainsComponentMasked(swizzle, 3, 0x7); 405 } 406 407 if(argument == 1) 408 { 409 if(mask & 0x2) 410 { 411 interpolant[index + 1][0] |= swizzleContainsComponentMasked(swizzle, 0, 0x7); 412 interpolant[index + 1][1] |= swizzleContainsComponentMasked(swizzle, 1, 0x7); 413 interpolant[index + 1][2] |= swizzleContainsComponentMasked(swizzle, 2, 0x7); 414 interpolant[index + 1][3] |= swizzleContainsComponentMasked(swizzle, 3, 0x7); 415 } 416 } 417 break; 418 case Shader::OPCODE_M3X3: 419 if(mask & 0x1) 420 { 421 interpolant[index][0] |= swizzleContainsComponentMasked(swizzle, 0, 0x7); 422 interpolant[index][1] |= swizzleContainsComponentMasked(swizzle, 1, 0x7); 423 interpolant[index][2] |= swizzleContainsComponentMasked(swizzle, 2, 0x7); 424 interpolant[index][3] |= swizzleContainsComponentMasked(swizzle, 3, 0x7); 425 } 426 427 if(argument == 1) 428 { 429 if(mask & 0x2) 430 { 431 interpolant[index + 1][0] |= swizzleContainsComponentMasked(swizzle, 0, 0x7); 432 interpolant[index + 1][1] |= swizzleContainsComponentMasked(swizzle, 1, 0x7); 433 interpolant[index + 1][2] |= swizzleContainsComponentMasked(swizzle, 2, 0x7); 434 interpolant[index + 1][3] |= swizzleContainsComponentMasked(swizzle, 3, 0x7); 435 } 436 437 if(mask & 0x4) 438 { 439 interpolant[index + 2][0] |= swizzleContainsComponentMasked(swizzle, 0, 0x7); 440 interpolant[index + 2][1] |= swizzleContainsComponentMasked(swizzle, 1, 0x7); 441 interpolant[index + 2][2] |= swizzleContainsComponentMasked(swizzle, 2, 0x7); 442 interpolant[index + 2][3] |= swizzleContainsComponentMasked(swizzle, 3, 0x7); 443 } 444 } 445 break; 446 case Shader::OPCODE_M3X4: 447 if(mask & 0x1) 448 { 449 interpolant[index][0] |= swizzleContainsComponentMasked(swizzle, 0, 0x7); 450 interpolant[index][1] |= swizzleContainsComponentMasked(swizzle, 1, 0x7); 451 interpolant[index][2] |= swizzleContainsComponentMasked(swizzle, 2, 0x7); 452 interpolant[index][3] |= swizzleContainsComponentMasked(swizzle, 3, 0x7); 453 } 454 455 if(argument == 1) 456 { 457 if(mask & 0x2) 458 { 459 interpolant[index + 1][0] |= swizzleContainsComponentMasked(swizzle, 0, 0x7); 460 interpolant[index + 1][1] |= swizzleContainsComponentMasked(swizzle, 1, 0x7); 461 interpolant[index + 1][2] |= swizzleContainsComponentMasked(swizzle, 2, 0x7); 462 interpolant[index + 1][3] |= swizzleContainsComponentMasked(swizzle, 3, 0x7); 463 } 464 465 if(mask & 0x4) 466 { 467 interpolant[index + 2][0] |= swizzleContainsComponentMasked(swizzle, 0, 0x7); 468 interpolant[index + 2][1] |= swizzleContainsComponentMasked(swizzle, 1, 0x7); 469 interpolant[index + 2][2] |= swizzleContainsComponentMasked(swizzle, 2, 0x7); 470 interpolant[index + 2][3] |= swizzleContainsComponentMasked(swizzle, 3, 0x7); 471 } 472 473 if(mask & 0x8) 474 { 475 interpolant[index + 3][0] |= swizzleContainsComponentMasked(swizzle, 0, 0x7); 476 interpolant[index + 3][1] |= swizzleContainsComponentMasked(swizzle, 1, 0x7); 477 interpolant[index + 3][2] |= swizzleContainsComponentMasked(swizzle, 2, 0x7); 478 interpolant[index + 3][3] |= swizzleContainsComponentMasked(swizzle, 3, 0x7); 479 } 480 } 481 break; 482 case Shader::OPCODE_M4X3: 483 if(mask & 0x1) 484 { 485 interpolant[index][0] |= swizzleContainsComponent(swizzle, 0); 486 interpolant[index][1] |= swizzleContainsComponent(swizzle, 1); 487 interpolant[index][2] |= swizzleContainsComponent(swizzle, 2); 488 interpolant[index][3] |= swizzleContainsComponent(swizzle, 3); 489 } 490 491 if(argument == 1) 492 { 493 if(mask & 0x2) 494 { 495 interpolant[index + 1][0] |= swizzleContainsComponent(swizzle, 0); 496 interpolant[index + 1][1] |= swizzleContainsComponent(swizzle, 1); 497 interpolant[index + 1][2] |= swizzleContainsComponent(swizzle, 2); 498 interpolant[index + 1][3] |= swizzleContainsComponent(swizzle, 3); 499 } 500 501 if(mask & 0x4) 502 { 503 interpolant[index + 2][0] |= swizzleContainsComponent(swizzle, 0); 504 interpolant[index + 2][1] |= swizzleContainsComponent(swizzle, 1); 505 interpolant[index + 2][2] |= swizzleContainsComponent(swizzle, 2); 506 interpolant[index + 2][3] |= swizzleContainsComponent(swizzle, 3); 507 } 508 } 509 break; 510 case Shader::OPCODE_M4X4: 511 if(mask & 0x1) 512 { 513 interpolant[index][0] |= swizzleContainsComponent(swizzle, 0); 514 interpolant[index][1] |= swizzleContainsComponent(swizzle, 1); 515 interpolant[index][2] |= swizzleContainsComponent(swizzle, 2); 516 interpolant[index][3] |= swizzleContainsComponent(swizzle, 3); 517 } 518 519 if(argument == 1) 520 { 521 if(mask & 0x2) 522 { 523 interpolant[index + 1][0] |= swizzleContainsComponent(swizzle, 0); 524 interpolant[index + 1][1] |= swizzleContainsComponent(swizzle, 1); 525 interpolant[index + 1][2] |= swizzleContainsComponent(swizzle, 2); 526 interpolant[index + 1][3] |= swizzleContainsComponent(swizzle, 3); 527 } 528 529 if(mask & 0x4) 530 { 531 interpolant[index + 2][0] |= swizzleContainsComponent(swizzle, 0); 532 interpolant[index + 2][1] |= swizzleContainsComponent(swizzle, 1); 533 interpolant[index + 2][2] |= swizzleContainsComponent(swizzle, 2); 534 interpolant[index + 2][3] |= swizzleContainsComponent(swizzle, 3); 535 } 536 537 if(mask & 0x8) 538 { 539 interpolant[index + 3][0] |= swizzleContainsComponent(swizzle, 0); 540 interpolant[index + 3][1] |= swizzleContainsComponent(swizzle, 1); 541 interpolant[index + 3][2] |= swizzleContainsComponent(swizzle, 2); 542 interpolant[index + 3][3] |= swizzleContainsComponent(swizzle, 3); 543 } 544 } 545 break; 546 case Shader::OPCODE_CRS: 547 if(mask & 0x1) 548 { 549 interpolant[index][0] |= swizzleContainsComponentMasked(swizzle, 0, 0x6); 550 interpolant[index][1] |= swizzleContainsComponentMasked(swizzle, 1, 0x6); 551 interpolant[index][2] |= swizzleContainsComponentMasked(swizzle, 2, 0x6); 552 interpolant[index][3] |= swizzleContainsComponentMasked(swizzle, 3, 0x6); 553 } 554 555 if(mask & 0x2) 556 { 557 interpolant[index][0] |= swizzleContainsComponentMasked(swizzle, 0, 0x5); 558 interpolant[index][1] |= swizzleContainsComponentMasked(swizzle, 1, 0x5); 559 interpolant[index][2] |= swizzleContainsComponentMasked(swizzle, 2, 0x5); 560 interpolant[index][3] |= swizzleContainsComponentMasked(swizzle, 3, 0x5); 561 } 562 563 if(mask & 0x4) 564 { 565 interpolant[index][0] |= swizzleContainsComponentMasked(swizzle, 0, 0x3); 566 interpolant[index][1] |= swizzleContainsComponentMasked(swizzle, 1, 0x3); 567 interpolant[index][2] |= swizzleContainsComponentMasked(swizzle, 2, 0x3); 568 interpolant[index][3] |= swizzleContainsComponentMasked(swizzle, 3, 0x3); 569 } 570 break; 571 case Shader::OPCODE_DP2ADD: 572 if(argument == 0 || argument == 1) 573 { 574 interpolant[index][0] |= swizzleContainsComponentMasked(swizzle, 0, 0x3); 575 interpolant[index][1] |= swizzleContainsComponentMasked(swizzle, 1, 0x3); 576 interpolant[index][2] |= swizzleContainsComponentMasked(swizzle, 2, 0x3); 577 interpolant[index][3] |= swizzleContainsComponentMasked(swizzle, 3, 0x3); 578 } 579 else // argument == 2 580 { 581 interpolant[index][0] |= swizzleContainsComponent(swizzle, 0); 582 interpolant[index][1] |= swizzleContainsComponent(swizzle, 1); 583 interpolant[index][2] |= swizzleContainsComponent(swizzle, 2); 584 interpolant[index][3] |= swizzleContainsComponent(swizzle, 3); 585 } 586 break; 587 case Shader::OPCODE_DP3: 588 interpolant[index][0] |= swizzleContainsComponentMasked(swizzle, 0, 0x7); 589 interpolant[index][1] |= swizzleContainsComponentMasked(swizzle, 1, 0x7); 590 interpolant[index][2] |= swizzleContainsComponentMasked(swizzle, 2, 0x7); 591 interpolant[index][3] |= swizzleContainsComponentMasked(swizzle, 3, 0x7); 592 break; 593 case Shader::OPCODE_DP4: 594 interpolant[index][0] |= swizzleContainsComponent(swizzle, 0); 595 interpolant[index][1] |= swizzleContainsComponent(swizzle, 1); 596 interpolant[index][2] |= swizzleContainsComponent(swizzle, 2); 597 interpolant[index][3] |= swizzleContainsComponent(swizzle, 3); 598 break; 599 case Shader::OPCODE_SINCOS: 600 case Shader::OPCODE_EXP2X: 601 case Shader::OPCODE_LOG2X: 602 case Shader::OPCODE_POWX: 603 case Shader::OPCODE_RCPX: 604 case Shader::OPCODE_RSQX: 605 interpolant[index][0] |= swizzleContainsComponent(swizzle, 0); 606 interpolant[index][1] |= swizzleContainsComponent(swizzle, 1); 607 interpolant[index][2] |= swizzleContainsComponent(swizzle, 2); 608 interpolant[index][3] |= swizzleContainsComponent(swizzle, 3); 609 break; 610 case Shader::OPCODE_NRM3: 611 interpolant[index][0] |= swizzleContainsComponentMasked(swizzle, 0, 0x7 | mask); 612 interpolant[index][1] |= swizzleContainsComponentMasked(swizzle, 1, 0x7 | mask); 613 interpolant[index][2] |= swizzleContainsComponentMasked(swizzle, 2, 0x7 | mask); 614 interpolant[index][3] |= swizzleContainsComponentMasked(swizzle, 3, 0x7 | mask); 615 break; 616 case Shader::OPCODE_MOV: 617 case Shader::OPCODE_ADD: 618 case Shader::OPCODE_SUB: 619 case Shader::OPCODE_MUL: 620 case Shader::OPCODE_MAD: 621 case Shader::OPCODE_ABS: 622 case Shader::OPCODE_CMP0: 623 case Shader::OPCODE_CND: 624 case Shader::OPCODE_FRC: 625 case Shader::OPCODE_LRP: 626 case Shader::OPCODE_MAX: 627 case Shader::OPCODE_MIN: 628 case Shader::OPCODE_CMP: 629 case Shader::OPCODE_BREAKC: 630 case Shader::OPCODE_DFDX: 631 case Shader::OPCODE_DFDY: 632 interpolant[index][0] |= swizzleContainsComponentMasked(swizzle, 0, mask); 633 interpolant[index][1] |= swizzleContainsComponentMasked(swizzle, 1, mask); 634 interpolant[index][2] |= swizzleContainsComponentMasked(swizzle, 2, mask); 635 interpolant[index][3] |= swizzleContainsComponentMasked(swizzle, 3, mask); 636 break; 637 case Shader::OPCODE_TEXCOORD: 638 interpolant[index][0] = true; 639 interpolant[index][1] = true; 640 interpolant[index][2] = true; 641 interpolant[index][3] = true; 642 break; 643 case Shader::OPCODE_TEXDP3: 644 case Shader::OPCODE_TEXDP3TEX: 645 case Shader::OPCODE_TEXM3X2PAD: 646 case Shader::OPCODE_TEXM3X3PAD: 647 case Shader::OPCODE_TEXM3X2TEX: 648 case Shader::OPCODE_TEXM3X3SPEC: 649 case Shader::OPCODE_TEXM3X3VSPEC: 650 case Shader::OPCODE_TEXBEM: 651 case Shader::OPCODE_TEXBEML: 652 case Shader::OPCODE_TEXM3X2DEPTH: 653 case Shader::OPCODE_TEXM3X3: 654 case Shader::OPCODE_TEXM3X3TEX: 655 interpolant[index][0] = true; 656 interpolant[index][1] = true; 657 interpolant[index][2] = true; 658 break; 659 case Shader::OPCODE_TEXREG2AR: 660 case Shader::OPCODE_TEXREG2GB: 661 case Shader::OPCODE_TEXREG2RGB: 662 break; 663 default: 664 // ASSERT(false); // Refine component usage 665 interpolant[index][0] = true; 666 interpolant[index][1] = true; 667 interpolant[index][2] = true; 668 interpolant[index][3] = true; 669 } 670 } 671 } 672 } 673 674 for(int index = 0; index < MAX_FRAGMENT_INPUTS; index++) 675 { 676 for(int component = 0; component < 4; component++) 677 { 678 if(!interpolant[index][component]) 679 { 680 input[index][component] = Semantic(); 681 } 682 } 683 } 684 } 685 else // Shader Model 3.0 input declaration; v# indexable 686 { 687 for(const auto &inst : instruction) 688 { 689 if(inst->opcode == Shader::OPCODE_DCL) 690 { 691 if(inst->dst.type == Shader::PARAMETER_INPUT) 692 { 693 unsigned char usage = inst->usage; 694 unsigned char index = inst->usageIndex; 695 unsigned char mask = inst->dst.mask; 696 unsigned char reg = inst->dst.index; 697 698 if(mask & 0x01) input[reg][0] = Semantic(usage, index); 699 if(mask & 0x02) input[reg][1] = Semantic(usage, index); 700 if(mask & 0x04) input[reg][2] = Semantic(usage, index); 701 if(mask & 0x08) input[reg][3] = Semantic(usage, index); 702 } 703 else if(inst->dst.type == Shader::PARAMETER_MISCTYPE) 704 { 705 unsigned char index = inst->dst.index; 706 707 if(index == Shader::VPosIndex) 708 { 709 vPosDeclared = true; 710 } 711 else if(index == Shader::VFaceIndex) 712 { 713 vFaceDeclared = true; 714 } 715 else ASSERT(false); 716 } 717 } 718 } 719 } 720 721 if(shaderModel >= 0x0200) 722 { 723 for(const auto &inst : instruction) 724 { 725 if(inst->opcode == Shader::OPCODE_DCL) 726 { 727 bool centroid = inst->dst.centroid; 728 unsigned char reg = inst->dst.index; 729 730 switch(inst->dst.type) 731 { 732 case Shader::PARAMETER_INPUT: 733 input[reg][0].centroid = centroid; 734 break; 735 case Shader::PARAMETER_TEXTURE: 736 input[2 + reg][0].centroid = centroid; 737 break; 738 default: 739 break; 740 } 741 742 this->centroid = this->centroid || centroid; 743 } 744 } 745 } 746 } 747 } 748