OSDN Git Service

gl_VertexID implementation
[android-x86/external-swiftshader.git] / src / Shader / PixelShader.cpp
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(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 }