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