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