1 // Copyright 2016 The SwiftShader Authors. All Rights Reserved.
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
7 // http://www.apache.org/licenses/LICENSE-2.0
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.
15 #include "PixelShader.hpp"
23 PixelShader::PixelShader(const PixelShader *ps) : Shader()
27 vFaceDeclared = false;
32 for(size_t i = 0; i < ps->getLength(); i++)
34 append(new sw::Shader::Instruction(*ps->getInstruction(i)));
37 memcpy(input, ps->input, sizeof(input));
38 vPosDeclared = ps->vPosDeclared;
39 vFaceDeclared = ps->vFaceDeclared;
40 usedSamplers = ps->usedSamplers;
47 PixelShader::PixelShader(const unsigned long *token) : Shader()
52 vFaceDeclared = false;
59 PixelShader::~PixelShader()
63 int PixelShader::validate(const unsigned long *const token)
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);
75 if(shaderType != SHADER_PIXEL || majorVersion > 3)
80 int instructionCount = 1;
82 for(int i = 0; token[i] != 0x0000FFFF; i++)
84 if((token[i] & 0x0000FFFF) == 0x0000FFFE) // Comment token
86 int length = (token[i] & 0x7FFF0000) >> 16;
92 Shader::Opcode opcode = (Shader::Opcode)(token[i] & 0x0000FFFF);
96 case Shader::OPCODE_RESERVED0:
97 case Shader::OPCODE_MOVA:
98 return 0; // Unsupported operation
104 i += size(token[i], version);
108 return instructionCount;
111 bool PixelShader::depthOverride() const
116 bool PixelShader::containsKill() const
121 bool PixelShader::containsCentroid() const
126 bool PixelShader::usesDiffuse(int component) const
128 return input[0][component].active();
131 bool PixelShader::usesSpecular(int component) const
133 return input[1][component].active();
136 bool PixelShader::usesTexture(int coordinate, int component) const
138 return input[2 + coordinate][component].active();
141 void PixelShader::setInput(int inputIdx, int nbComponents, const sw::Shader::Semantic& semantic)
143 for(int i = 0; i < nbComponents; ++i)
145 input[inputIdx][i] = semantic;
149 const sw::Shader::Semantic& PixelShader::getInput(int inputIdx, int component) const
151 return input[inputIdx][component];
154 void PixelShader::analyze()
158 analyzeInterpolants();
159 analyzeDirtyConstants();
160 analyzeDynamicBranching();
163 analyzeDynamicIndexing();
166 void PixelShader::analyzeZOverride()
170 for(unsigned int i = 0; i < instruction.size(); i++)
172 if(instruction[i]->opcode == Shader::OPCODE_TEXM3X2DEPTH ||
173 instruction[i]->opcode == Shader::OPCODE_TEXDEPTH ||
174 instruction[i]->dst.type == Shader::PARAMETER_DEPTHOUT)
183 void PixelShader::analyzeKill()
187 for(unsigned int i = 0; i < instruction.size(); i++)
189 if(instruction[i]->opcode == Shader::OPCODE_TEXKILL ||
190 instruction[i]->opcode == Shader::OPCODE_DISCARD)
199 void PixelShader::analyzeInterpolants()
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);
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);
214 for(int i = 0; i < 8; i++)
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);
222 Shader::SamplerType samplerType[16];
224 for(int i = 0; i < 16; i++)
226 samplerType[i] = Shader::SAMPLER_UNKNOWN;
229 for(unsigned int i = 0; i < instruction.size(); i++)
231 if(instruction[i]->dst.type == Shader::PARAMETER_SAMPLER)
233 int sampler = instruction[i]->dst.index;
235 samplerType[sampler] = instruction[i]->samplerType;
239 bool interpolant[MAX_FRAGMENT_INPUTS][4] = {{false}}; // Interpolants in use
241 for(unsigned int i = 0; i < instruction.size(); i++)
243 if(instruction[i]->dst.type == Shader::PARAMETER_TEXTURE)
245 int index = instruction[i]->dst.index + 2;
247 switch(instruction[i]->opcode)
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;
265 case Shader::OPCODE_TEXKILL:
268 interpolant[index][0] = true;
269 interpolant[index][1] = true;
270 interpolant[index][2] = true;
274 interpolant[index][0] = true;
275 interpolant[index][1] = true;
276 interpolant[index][2] = true;
277 interpolant[index][3] = true;
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;
288 case Shader::OPCODE_DCL:
290 default: // Arithmetic instruction
291 if(version >= 0x0104)
298 for(int argument = 0; argument < 4; argument++)
300 if(instruction[i]->src[argument].type == Shader::PARAMETER_INPUT ||
301 instruction[i]->src[argument].type == Shader::PARAMETER_TEXTURE)
303 int index = instruction[i]->src[argument].index;
304 int swizzle = instruction[i]->src[argument].swizzle;
305 int mask = instruction[i]->dst.mask;
307 if(instruction[i]->src[argument].type == Shader::PARAMETER_TEXTURE)
312 switch(instruction[i]->opcode)
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:
324 int sampler = instruction[i]->src[1].index;
326 switch(samplerType[sampler])
328 case Shader::SAMPLER_UNKNOWN:
329 if(version == 0x0104)
331 if((instruction[i]->src[0].swizzle & 0x30) == 0x20) // .xyz
333 interpolant[index][0] = true;
334 interpolant[index][1] = true;
335 interpolant[index][2] = true;
339 interpolant[index][0] = true;
340 interpolant[index][1] = true;
341 interpolant[index][3] = true;
349 case Shader::SAMPLER_1D:
350 interpolant[index][0] = true;
352 case Shader::SAMPLER_2D:
353 interpolant[index][0] = true;
354 interpolant[index][1] = true;
356 case Shader::SAMPLER_CUBE:
357 interpolant[index][0] = true;
358 interpolant[index][1] = true;
359 interpolant[index][2] = true;
361 case Shader::SAMPLER_VOLUME:
362 interpolant[index][0] = true;
363 interpolant[index][1] = true;
364 interpolant[index][2] = true;
370 if(instruction[i]->bias)
372 interpolant[index][3] = true;
375 if(instruction[i]->project)
377 interpolant[index][3] = true;
380 if(version == 0x0104 && instruction[i]->opcode == Shader::OPCODE_TEX)
382 if(instruction[i]->src[0].modifier == Shader::MODIFIER_DZ)
384 interpolant[index][2] = true;
387 if(instruction[i]->src[0].modifier == Shader::MODIFIER_DW)
389 interpolant[index][3] = true;
394 case Shader::OPCODE_M3X2:
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);
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);
414 case Shader::OPCODE_M3X3:
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);
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);
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);
442 case Shader::OPCODE_M3X4:
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);
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);
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);
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);
478 case Shader::OPCODE_M4X3:
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);
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);
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);
506 case Shader::OPCODE_M4X4:
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);
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);
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);
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);
542 case Shader::OPCODE_CRS:
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);
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);
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);
567 case Shader::OPCODE_DP2ADD:
568 if(argument == 0 || argument == 1)
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);
575 else // argument == 2
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);
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);
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);
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);
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);
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);
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;
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;
655 case Shader::OPCODE_TEXREG2AR:
656 case Shader::OPCODE_TEXREG2GB:
657 case Shader::OPCODE_TEXREG2RGB:
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;
670 for(int index = 0; index < MAX_FRAGMENT_INPUTS; index++)
672 for(int component = 0; component < 4; component++)
674 if(!interpolant[index][component])
676 input[index][component] = Semantic();
681 else // Shader Model 3.0 input declaration; v# indexable
683 for(unsigned int i = 0; i < instruction.size(); i++)
685 if(instruction[i]->opcode == Shader::OPCODE_DCL)
687 if(instruction[i]->dst.type == Shader::PARAMETER_INPUT)
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;
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);
699 else if(instruction[i]->dst.type == Shader::PARAMETER_MISCTYPE)
701 unsigned char index = instruction[i]->dst.index;
703 if(index == Shader::VPosIndex)
707 else if(index == Shader::VFaceIndex)
709 vFaceDeclared = true;
717 if(version >= 0x0200)
719 for(unsigned int i = 0; i < instruction.size(); i++)
721 if(instruction[i]->opcode == Shader::OPCODE_DCL)
723 bool centroid = instruction[i]->dst.centroid;
724 unsigned char reg = instruction[i]->dst.index;
726 switch(instruction[i]->dst.type)
728 case Shader::PARAMETER_INPUT:
729 input[reg][0].centroid = centroid;
731 case Shader::PARAMETER_TEXTURE:
732 input[2 + reg][0].centroid = centroid;
738 this->centroid = this->centroid || centroid;