blob: f569342a54ef5b3d9272cbfcd5d62df4fb180283 [file] [log] [blame]
John Bauman89401822014-05-06 15:04:28 -04001// SwiftShader Software Renderer
2//
John Bauman66b8ab22014-05-06 15:57:45 -04003// Copyright(c) 2005-2013 TransGaming Inc.
John Bauman89401822014-05-06 15:04:28 -04004//
5// All rights reserved. No part of this software may be copied, distributed, transmitted,
6// transcribed, stored in a retrieval system, translated into any human or computer
7// language by any means, or disclosed to third parties without the explicit written
8// agreement of TransGaming Inc. Without such an agreement, no rights or licenses, express
9// or implied, including but not limited to any patent rights, are granted to you.
10//
11
12#include "PixelShader.hpp"
13
14#include "Debug.hpp"
15
John Bauman66b8ab22014-05-06 15:57:45 -040016#include <string.h>
17
John Bauman89401822014-05-06 15:04:28 -040018namespace sw
19{
John Bauman19bac1e2014-05-06 15:23:49 -040020 PixelShader::PixelShader(const PixelShader *ps) : Shader()
21 {
22 version = 0x0300;
23 vPosDeclared = false;
24 vFaceDeclared = false;
25 centroid = false;
26
27 if(ps) // Make a copy
28 {
Alexis Hetu903e0252014-11-25 14:25:32 -050029 for(size_t i = 0; i < ps->getLength(); i++)
John Bauman19bac1e2014-05-06 15:23:49 -040030 {
31 append(new sw::Shader::Instruction(*ps->getInstruction(i)));
32 }
33
34 memcpy(semantic, ps->semantic, sizeof(semantic));
35 vPosDeclared = ps->vPosDeclared;
36 vFaceDeclared = ps->vFaceDeclared;
37 usedSamplers = ps->usedSamplers;
38
John Baumand4ae8632014-05-06 16:18:33 -040039 optimize();
John Bauman19bac1e2014-05-06 15:23:49 -040040 analyze();
41 }
42 }
43
44 PixelShader::PixelShader(const unsigned long *token) : Shader()
John Bauman89401822014-05-06 15:04:28 -040045 {
46 parse(token);
John Bauman19bac1e2014-05-06 15:23:49 -040047
48 vPosDeclared = false;
49 vFaceDeclared = false;
50 centroid = false;
51
John Baumand4ae8632014-05-06 16:18:33 -040052 optimize();
John Bauman19bac1e2014-05-06 15:23:49 -040053 analyze();
John Bauman89401822014-05-06 15:04:28 -040054 }
55
56 PixelShader::~PixelShader()
57 {
58 }
59
John Bauman89401822014-05-06 15:04:28 -040060 int PixelShader::validate(const unsigned long *const token)
61 {
62 if(!token)
63 {
64 return 0;
65 }
66
67 unsigned short version = (unsigned short)(token[0] & 0x0000FFFF);
68 unsigned char minorVersion = (unsigned char)(token[0] & 0x000000FF);
69 unsigned char majorVersion = (unsigned char)((token[0] & 0x0000FF00) >> 8);
70 ShaderType shaderType = (ShaderType)((token[0] & 0xFFFF0000) >> 16);
71
72 if(shaderType != SHADER_PIXEL || majorVersion > 3)
73 {
74 return 0;
75 }
76
77 int instructionCount = 1;
78
79 for(int i = 0; token[i] != 0x0000FFFF; i++)
80 {
81 if((token[i] & 0x0000FFFF) == 0x0000FFFE) // Comment token
82 {
83 int length = (token[i] & 0x7FFF0000) >> 16;
84
85 i += length;
86 }
87 else
88 {
John Bauman19bac1e2014-05-06 15:23:49 -040089 Shader::Opcode opcode = (Shader::Opcode)(token[i] & 0x0000FFFF);
John Bauman89401822014-05-06 15:04:28 -040090
91 switch(opcode)
92 {
John Bauman19bac1e2014-05-06 15:23:49 -040093 case Shader::OPCODE_RESERVED0:
94 case Shader::OPCODE_MOVA:
John Bauman89401822014-05-06 15:04:28 -040095 return 0; // Unsupported operation
96 default:
97 instructionCount++;
98 break;
99 }
100
101 i += size(token[i], version);
102 }
103 }
104
105 return instructionCount;
106 }
107
108 bool PixelShader::depthOverride() const
109 {
110 return zOverride;
111 }
112
John Bauman19bac1e2014-05-06 15:23:49 -0400113 bool PixelShader::containsKill() const
John Bauman89401822014-05-06 15:04:28 -0400114 {
John Bauman19bac1e2014-05-06 15:23:49 -0400115 return kill;
John Bauman89401822014-05-06 15:04:28 -0400116 }
117
118 bool PixelShader::containsCentroid() const
119 {
120 return centroid;
121 }
122
123 bool PixelShader::usesDiffuse(int component) const
124 {
125 return semantic[0][component].active();
126 }
127
128 bool PixelShader::usesSpecular(int component) const
129 {
130 return semantic[1][component].active();
131 }
132
133 bool PixelShader::usesTexture(int coordinate, int component) const
134 {
135 return semantic[2 + coordinate][component].active();
136 }
137
John Bauman19bac1e2014-05-06 15:23:49 -0400138 void PixelShader::analyze()
139 {
140 analyzeZOverride();
141 analyzeKill();
142 analyzeInterpolants();
143 analyzeDirtyConstants();
144 analyzeDynamicBranching();
145 analyzeSamplers();
146 analyzeCallSites();
147 analyzeDynamicIndexing();
148 }
149
John Bauman89401822014-05-06 15:04:28 -0400150 void PixelShader::analyzeZOverride()
151 {
152 zOverride = false;
153
John Bauman19bac1e2014-05-06 15:23:49 -0400154 for(unsigned int i = 0; i < instruction.size(); i++)
John Bauman89401822014-05-06 15:04:28 -0400155 {
John Bauman19bac1e2014-05-06 15:23:49 -0400156 if(instruction[i]->opcode == Shader::OPCODE_TEXM3X2DEPTH ||
157 instruction[i]->opcode == Shader::OPCODE_TEXDEPTH ||
158 instruction[i]->dst.type == Shader::PARAMETER_DEPTHOUT)
John Bauman89401822014-05-06 15:04:28 -0400159 {
160 zOverride = true;
161
162 break;
163 }
164 }
165 }
166
John Bauman19bac1e2014-05-06 15:23:49 -0400167 void PixelShader::analyzeKill()
John Bauman89401822014-05-06 15:04:28 -0400168 {
John Bauman19bac1e2014-05-06 15:23:49 -0400169 kill = false;
John Bauman89401822014-05-06 15:04:28 -0400170
John Bauman19bac1e2014-05-06 15:23:49 -0400171 for(unsigned int i = 0; i < instruction.size(); i++)
John Bauman89401822014-05-06 15:04:28 -0400172 {
John Bauman19bac1e2014-05-06 15:23:49 -0400173 if(instruction[i]->opcode == Shader::OPCODE_TEXKILL ||
174 instruction[i]->opcode == Shader::OPCODE_DISCARD)
John Bauman89401822014-05-06 15:04:28 -0400175 {
John Bauman19bac1e2014-05-06 15:23:49 -0400176 kill = true;
John Bauman89401822014-05-06 15:04:28 -0400177
178 break;
179 }
180 }
181 }
182
183 void PixelShader::analyzeInterpolants()
184 {
John Bauman89401822014-05-06 15:04:28 -0400185 if(version < 0x0300)
186 {
187 // Set default mapping; disable unused interpolants below
John Bauman19bac1e2014-05-06 15:23:49 -0400188 semantic[0][0] = Semantic(Shader::USAGE_COLOR, 0);
189 semantic[0][1] = Semantic(Shader::USAGE_COLOR, 0);
190 semantic[0][2] = Semantic(Shader::USAGE_COLOR, 0);
191 semantic[0][3] = Semantic(Shader::USAGE_COLOR, 0);
John Bauman89401822014-05-06 15:04:28 -0400192
John Bauman19bac1e2014-05-06 15:23:49 -0400193 semantic[1][0] = Semantic(Shader::USAGE_COLOR, 1);
194 semantic[1][1] = Semantic(Shader::USAGE_COLOR, 1);
195 semantic[1][2] = Semantic(Shader::USAGE_COLOR, 1);
196 semantic[1][3] = Semantic(Shader::USAGE_COLOR, 1);
John Bauman89401822014-05-06 15:04:28 -0400197
198 for(int i = 0; i < 8; i++)
199 {
John Bauman19bac1e2014-05-06 15:23:49 -0400200 semantic[2 + i][0] = Semantic(Shader::USAGE_TEXCOORD, i);
201 semantic[2 + i][1] = Semantic(Shader::USAGE_TEXCOORD, i);
202 semantic[2 + i][2] = Semantic(Shader::USAGE_TEXCOORD, i);
203 semantic[2 + i][3] = Semantic(Shader::USAGE_TEXCOORD, i);
John Bauman89401822014-05-06 15:04:28 -0400204 }
205
John Bauman19bac1e2014-05-06 15:23:49 -0400206 Shader::SamplerType samplerType[16];
John Bauman89401822014-05-06 15:04:28 -0400207
208 for(int i = 0; i < 16; i++)
209 {
John Bauman19bac1e2014-05-06 15:23:49 -0400210 samplerType[i] = Shader::SAMPLER_UNKNOWN;
John Bauman89401822014-05-06 15:04:28 -0400211 }
212
John Bauman19bac1e2014-05-06 15:23:49 -0400213 for(unsigned int i = 0; i < instruction.size(); i++)
John Bauman89401822014-05-06 15:04:28 -0400214 {
John Bauman19bac1e2014-05-06 15:23:49 -0400215 if(instruction[i]->dst.type == Shader::PARAMETER_SAMPLER)
John Bauman89401822014-05-06 15:04:28 -0400216 {
John Bauman19bac1e2014-05-06 15:23:49 -0400217 int sampler = instruction[i]->dst.index;
John Bauman89401822014-05-06 15:04:28 -0400218
John Bauman19bac1e2014-05-06 15:23:49 -0400219 samplerType[sampler] = instruction[i]->samplerType;
John Bauman89401822014-05-06 15:04:28 -0400220 }
221 }
222
Nicolas Capens91859812016-01-02 00:00:35 -0500223 bool interpolant[MAX_INPUT_VARYINGS][4] = {{false}}; // Interpolants in use
John Bauman89401822014-05-06 15:04:28 -0400224
John Bauman19bac1e2014-05-06 15:23:49 -0400225 for(unsigned int i = 0; i < instruction.size(); i++)
John Bauman89401822014-05-06 15:04:28 -0400226 {
John Bauman19bac1e2014-05-06 15:23:49 -0400227 if(instruction[i]->dst.type == Shader::PARAMETER_TEXTURE)
John Bauman89401822014-05-06 15:04:28 -0400228 {
John Bauman19bac1e2014-05-06 15:23:49 -0400229 int index = instruction[i]->dst.index + 2;
230 int mask = instruction[i]->dst.mask;
John Bauman89401822014-05-06 15:04:28 -0400231
John Bauman19bac1e2014-05-06 15:23:49 -0400232 switch(instruction[i]->opcode)
John Bauman89401822014-05-06 15:04:28 -0400233 {
John Bauman19bac1e2014-05-06 15:23:49 -0400234 case Shader::OPCODE_TEX:
235 case Shader::OPCODE_TEXBEM:
236 case Shader::OPCODE_TEXBEML:
237 case Shader::OPCODE_TEXCOORD:
238 case Shader::OPCODE_TEXDP3:
239 case Shader::OPCODE_TEXDP3TEX:
240 case Shader::OPCODE_TEXM3X2DEPTH:
241 case Shader::OPCODE_TEXM3X2PAD:
242 case Shader::OPCODE_TEXM3X2TEX:
243 case Shader::OPCODE_TEXM3X3:
244 case Shader::OPCODE_TEXM3X3PAD:
245 case Shader::OPCODE_TEXM3X3TEX:
John Bauman89401822014-05-06 15:04:28 -0400246 interpolant[index][0] = true;
247 interpolant[index][1] = true;
248 interpolant[index][2] = true;
249 break;
John Bauman19bac1e2014-05-06 15:23:49 -0400250 case Shader::OPCODE_TEXKILL:
John Bauman89401822014-05-06 15:04:28 -0400251 if(majorVersion < 2)
252 {
253 interpolant[index][0] = true;
254 interpolant[index][1] = true;
255 interpolant[index][2] = true;
256 }
257 else
258 {
259 interpolant[index][0] = true;
260 interpolant[index][1] = true;
261 interpolant[index][2] = true;
262 interpolant[index][3] = true;
263 }
264 break;
John Bauman19bac1e2014-05-06 15:23:49 -0400265 case Shader::OPCODE_TEXM3X3VSPEC:
John Bauman89401822014-05-06 15:04:28 -0400266 interpolant[index][0] = true;
267 interpolant[index][1] = true;
268 interpolant[index][2] = true;
269 interpolant[index - 2][3] = true;
270 interpolant[index - 1][3] = true;
271 interpolant[index - 0][3] = true;
272 break;
John Bauman19bac1e2014-05-06 15:23:49 -0400273 case Shader::OPCODE_DCL:
John Bauman89401822014-05-06 15:04:28 -0400274 break; // Ignore
275 default: // Arithmetic instruction
276 if(version >= 0x0104)
277 {
278 ASSERT(false);
279 }
280 }
281 }
282
283 for(int argument = 0; argument < 4; argument++)
284 {
John Bauman19bac1e2014-05-06 15:23:49 -0400285 if(instruction[i]->src[argument].type == Shader::PARAMETER_INPUT ||
286 instruction[i]->src[argument].type == Shader::PARAMETER_TEXTURE)
John Bauman89401822014-05-06 15:04:28 -0400287 {
John Bauman19bac1e2014-05-06 15:23:49 -0400288 int index = instruction[i]->src[argument].index;
289 int swizzle = instruction[i]->src[argument].swizzle;
290 int mask = instruction[i]->dst.mask;
John Bauman89401822014-05-06 15:04:28 -0400291
John Bauman19bac1e2014-05-06 15:23:49 -0400292 if(instruction[i]->src[argument].type == Shader::PARAMETER_TEXTURE)
John Bauman89401822014-05-06 15:04:28 -0400293 {
294 index += 2;
295 }
296
John Bauman19bac1e2014-05-06 15:23:49 -0400297 switch(instruction[i]->opcode)
John Bauman89401822014-05-06 15:04:28 -0400298 {
John Bauman19bac1e2014-05-06 15:23:49 -0400299 case Shader::OPCODE_TEX:
300 case Shader::OPCODE_TEXLDD:
301 case Shader::OPCODE_TEXLDL:
Alexis Hetu25d47fc2015-10-22 13:58:32 -0400302 case Shader::OPCODE_TEXOFFSET:
303 case Shader::OPCODE_TEXLDLOFFSET:
304 case Shader::OPCODE_TEXELFETCH:
305 case Shader::OPCODE_TEXELFETCHOFFSET:
306 case Shader::OPCODE_TEXGRAD:
307 case Shader::OPCODE_TEXGRADOFFSET:
John Bauman89401822014-05-06 15:04:28 -0400308 {
John Bauman19bac1e2014-05-06 15:23:49 -0400309 int sampler = instruction[i]->src[1].index;
John Bauman89401822014-05-06 15:04:28 -0400310
311 switch(samplerType[sampler])
312 {
John Bauman19bac1e2014-05-06 15:23:49 -0400313 case Shader::SAMPLER_UNKNOWN:
John Bauman89401822014-05-06 15:04:28 -0400314 if(version == 0x0104)
315 {
John Bauman19bac1e2014-05-06 15:23:49 -0400316 if((instruction[i]->src[0].swizzle & 0x30) == 0x20) // .xyz
John Bauman89401822014-05-06 15:04:28 -0400317 {
318 interpolant[index][0] = true;
319 interpolant[index][1] = true;
320 interpolant[index][2] = true;
321 }
322 else // .xyw
323 {
324 interpolant[index][0] = true;
325 interpolant[index][1] = true;
326 interpolant[index][3] = true;
327 }
328 }
329 else
330 {
331 ASSERT(false);
332 }
333 break;
John Bauman19bac1e2014-05-06 15:23:49 -0400334 case Shader::SAMPLER_1D:
John Bauman89401822014-05-06 15:04:28 -0400335 interpolant[index][0] = true;
336 break;
John Bauman19bac1e2014-05-06 15:23:49 -0400337 case Shader::SAMPLER_2D:
John Bauman89401822014-05-06 15:04:28 -0400338 interpolant[index][0] = true;
339 interpolant[index][1] = true;
340 break;
John Bauman19bac1e2014-05-06 15:23:49 -0400341 case Shader::SAMPLER_CUBE:
John Bauman89401822014-05-06 15:04:28 -0400342 interpolant[index][0] = true;
343 interpolant[index][1] = true;
344 interpolant[index][2] = true;
345 break;
John Bauman19bac1e2014-05-06 15:23:49 -0400346 case Shader::SAMPLER_VOLUME:
John Bauman89401822014-05-06 15:04:28 -0400347 interpolant[index][0] = true;
348 interpolant[index][1] = true;
349 interpolant[index][2] = true;
350 break;
351 default:
352 ASSERT(false);
353 }
354
John Bauman19bac1e2014-05-06 15:23:49 -0400355 if(instruction[i]->bias)
John Bauman89401822014-05-06 15:04:28 -0400356 {
357 interpolant[index][3] = true;
358 }
359
John Bauman19bac1e2014-05-06 15:23:49 -0400360 if(instruction[i]->project)
John Bauman89401822014-05-06 15:04:28 -0400361 {
362 interpolant[index][3] = true;
363 }
364
John Bauman19bac1e2014-05-06 15:23:49 -0400365 if(version == 0x0104 && instruction[i]->opcode == Shader::OPCODE_TEX)
John Bauman89401822014-05-06 15:04:28 -0400366 {
John Bauman19bac1e2014-05-06 15:23:49 -0400367 if(instruction[i]->src[0].modifier == Shader::MODIFIER_DZ)
John Bauman89401822014-05-06 15:04:28 -0400368 {
369 interpolant[index][2] = true;
370 }
371
John Bauman19bac1e2014-05-06 15:23:49 -0400372 if(instruction[i]->src[0].modifier == Shader::MODIFIER_DW)
John Bauman89401822014-05-06 15:04:28 -0400373 {
374 interpolant[index][3] = true;
375 }
376 }
377 }
378 break;
John Bauman19bac1e2014-05-06 15:23:49 -0400379 case Shader::OPCODE_M3X2:
John Bauman89401822014-05-06 15:04:28 -0400380 if(mask & 0x1)
381 {
382 interpolant[index][0] |= swizzleContainsComponentMasked(swizzle, 0, 0x7);
383 interpolant[index][1] |= swizzleContainsComponentMasked(swizzle, 1, 0x7);
384 interpolant[index][2] |= swizzleContainsComponentMasked(swizzle, 2, 0x7);
385 interpolant[index][3] |= swizzleContainsComponentMasked(swizzle, 3, 0x7);
386 }
387
388 if(argument == 1)
389 {
390 if(mask & 0x2)
391 {
392 interpolant[index + 1][0] |= swizzleContainsComponentMasked(swizzle, 0, 0x7);
393 interpolant[index + 1][1] |= swizzleContainsComponentMasked(swizzle, 1, 0x7);
394 interpolant[index + 1][2] |= swizzleContainsComponentMasked(swizzle, 2, 0x7);
395 interpolant[index + 1][3] |= swizzleContainsComponentMasked(swizzle, 3, 0x7);
396 }
397 }
398 break;
John Bauman19bac1e2014-05-06 15:23:49 -0400399 case Shader::OPCODE_M3X3:
John Bauman89401822014-05-06 15:04:28 -0400400 if(mask & 0x1)
401 {
402 interpolant[index][0] |= swizzleContainsComponentMasked(swizzle, 0, 0x7);
403 interpolant[index][1] |= swizzleContainsComponentMasked(swizzle, 1, 0x7);
404 interpolant[index][2] |= swizzleContainsComponentMasked(swizzle, 2, 0x7);
405 interpolant[index][3] |= swizzleContainsComponentMasked(swizzle, 3, 0x7);
406 }
407
408 if(argument == 1)
409 {
410 if(mask & 0x2)
411 {
412 interpolant[index + 1][0] |= swizzleContainsComponentMasked(swizzle, 0, 0x7);
413 interpolant[index + 1][1] |= swizzleContainsComponentMasked(swizzle, 1, 0x7);
414 interpolant[index + 1][2] |= swizzleContainsComponentMasked(swizzle, 2, 0x7);
415 interpolant[index + 1][3] |= swizzleContainsComponentMasked(swizzle, 3, 0x7);
416 }
417
418 if(mask & 0x4)
419 {
420 interpolant[index + 2][0] |= swizzleContainsComponentMasked(swizzle, 0, 0x7);
421 interpolant[index + 2][1] |= swizzleContainsComponentMasked(swizzle, 1, 0x7);
422 interpolant[index + 2][2] |= swizzleContainsComponentMasked(swizzle, 2, 0x7);
423 interpolant[index + 2][3] |= swizzleContainsComponentMasked(swizzle, 3, 0x7);
424 }
425 }
426 break;
John Bauman19bac1e2014-05-06 15:23:49 -0400427 case Shader::OPCODE_M3X4:
John Bauman89401822014-05-06 15:04:28 -0400428 if(mask & 0x1)
429 {
430 interpolant[index][0] |= swizzleContainsComponentMasked(swizzle, 0, 0x7);
431 interpolant[index][1] |= swizzleContainsComponentMasked(swizzle, 1, 0x7);
432 interpolant[index][2] |= swizzleContainsComponentMasked(swizzle, 2, 0x7);
433 interpolant[index][3] |= swizzleContainsComponentMasked(swizzle, 3, 0x7);
434 }
435
436 if(argument == 1)
437 {
438 if(mask & 0x2)
439 {
440 interpolant[index + 1][0] |= swizzleContainsComponentMasked(swizzle, 0, 0x7);
441 interpolant[index + 1][1] |= swizzleContainsComponentMasked(swizzle, 1, 0x7);
442 interpolant[index + 1][2] |= swizzleContainsComponentMasked(swizzle, 2, 0x7);
443 interpolant[index + 1][3] |= swizzleContainsComponentMasked(swizzle, 3, 0x7);
444 }
445
446 if(mask & 0x4)
447 {
448 interpolant[index + 2][0] |= swizzleContainsComponentMasked(swizzle, 0, 0x7);
449 interpolant[index + 2][1] |= swizzleContainsComponentMasked(swizzle, 1, 0x7);
450 interpolant[index + 2][2] |= swizzleContainsComponentMasked(swizzle, 2, 0x7);
451 interpolant[index + 2][3] |= swizzleContainsComponentMasked(swizzle, 3, 0x7);
452 }
453
454 if(mask & 0x8)
455 {
456 interpolant[index + 3][0] |= swizzleContainsComponentMasked(swizzle, 0, 0x7);
457 interpolant[index + 3][1] |= swizzleContainsComponentMasked(swizzle, 1, 0x7);
458 interpolant[index + 3][2] |= swizzleContainsComponentMasked(swizzle, 2, 0x7);
459 interpolant[index + 3][3] |= swizzleContainsComponentMasked(swizzle, 3, 0x7);
460 }
461 }
462 break;
John Bauman19bac1e2014-05-06 15:23:49 -0400463 case Shader::OPCODE_M4X3:
John Bauman89401822014-05-06 15:04:28 -0400464 if(mask & 0x1)
465 {
466 interpolant[index][0] |= swizzleContainsComponent(swizzle, 0);
467 interpolant[index][1] |= swizzleContainsComponent(swizzle, 1);
468 interpolant[index][2] |= swizzleContainsComponent(swizzle, 2);
469 interpolant[index][3] |= swizzleContainsComponent(swizzle, 3);
470 }
471
472 if(argument == 1)
473 {
474 if(mask & 0x2)
475 {
476 interpolant[index + 1][0] |= swizzleContainsComponent(swizzle, 0);
477 interpolant[index + 1][1] |= swizzleContainsComponent(swizzle, 1);
478 interpolant[index + 1][2] |= swizzleContainsComponent(swizzle, 2);
479 interpolant[index + 1][3] |= swizzleContainsComponent(swizzle, 3);
480 }
481
482 if(mask & 0x4)
483 {
484 interpolant[index + 2][0] |= swizzleContainsComponent(swizzle, 0);
485 interpolant[index + 2][1] |= swizzleContainsComponent(swizzle, 1);
486 interpolant[index + 2][2] |= swizzleContainsComponent(swizzle, 2);
487 interpolant[index + 2][3] |= swizzleContainsComponent(swizzle, 3);
488 }
489 }
490 break;
John Bauman19bac1e2014-05-06 15:23:49 -0400491 case Shader::OPCODE_M4X4:
John Bauman89401822014-05-06 15:04:28 -0400492 if(mask & 0x1)
493 {
494 interpolant[index][0] |= swizzleContainsComponent(swizzle, 0);
495 interpolant[index][1] |= swizzleContainsComponent(swizzle, 1);
496 interpolant[index][2] |= swizzleContainsComponent(swizzle, 2);
497 interpolant[index][3] |= swizzleContainsComponent(swizzle, 3);
498 }
499
500 if(argument == 1)
501 {
502 if(mask & 0x2)
503 {
504 interpolant[index + 1][0] |= swizzleContainsComponent(swizzle, 0);
505 interpolant[index + 1][1] |= swizzleContainsComponent(swizzle, 1);
506 interpolant[index + 1][2] |= swizzleContainsComponent(swizzle, 2);
507 interpolant[index + 1][3] |= swizzleContainsComponent(swizzle, 3);
508 }
509
510 if(mask & 0x4)
511 {
512 interpolant[index + 2][0] |= swizzleContainsComponent(swizzle, 0);
513 interpolant[index + 2][1] |= swizzleContainsComponent(swizzle, 1);
514 interpolant[index + 2][2] |= swizzleContainsComponent(swizzle, 2);
515 interpolant[index + 2][3] |= swizzleContainsComponent(swizzle, 3);
516 }
517
518 if(mask & 0x8)
519 {
520 interpolant[index + 3][0] |= swizzleContainsComponent(swizzle, 0);
521 interpolant[index + 3][1] |= swizzleContainsComponent(swizzle, 1);
522 interpolant[index + 3][2] |= swizzleContainsComponent(swizzle, 2);
523 interpolant[index + 3][3] |= swizzleContainsComponent(swizzle, 3);
524 }
525 }
526 break;
John Bauman19bac1e2014-05-06 15:23:49 -0400527 case Shader::OPCODE_CRS:
John Bauman89401822014-05-06 15:04:28 -0400528 if(mask & 0x1)
529 {
530 interpolant[index][0] |= swizzleContainsComponentMasked(swizzle, 0, 0x6);
531 interpolant[index][1] |= swizzleContainsComponentMasked(swizzle, 1, 0x6);
532 interpolant[index][2] |= swizzleContainsComponentMasked(swizzle, 2, 0x6);
533 interpolant[index][3] |= swizzleContainsComponentMasked(swizzle, 3, 0x6);
534 }
535
536 if(mask & 0x2)
537 {
538 interpolant[index][0] |= swizzleContainsComponentMasked(swizzle, 0, 0x5);
539 interpolant[index][1] |= swizzleContainsComponentMasked(swizzle, 1, 0x5);
540 interpolant[index][2] |= swizzleContainsComponentMasked(swizzle, 2, 0x5);
541 interpolant[index][3] |= swizzleContainsComponentMasked(swizzle, 3, 0x5);
542 }
543
544 if(mask & 0x4)
545 {
546 interpolant[index][0] |= swizzleContainsComponentMasked(swizzle, 0, 0x3);
547 interpolant[index][1] |= swizzleContainsComponentMasked(swizzle, 1, 0x3);
548 interpolant[index][2] |= swizzleContainsComponentMasked(swizzle, 2, 0x3);
549 interpolant[index][3] |= swizzleContainsComponentMasked(swizzle, 3, 0x3);
550 }
551 break;
John Bauman19bac1e2014-05-06 15:23:49 -0400552 case Shader::OPCODE_DP2ADD:
John Bauman89401822014-05-06 15:04:28 -0400553 if(argument == 0 || argument == 1)
554 {
555 interpolant[index][0] |= swizzleContainsComponentMasked(swizzle, 0, 0x3);
556 interpolant[index][1] |= swizzleContainsComponentMasked(swizzle, 1, 0x3);
557 interpolant[index][2] |= swizzleContainsComponentMasked(swizzle, 2, 0x3);
558 interpolant[index][3] |= swizzleContainsComponentMasked(swizzle, 3, 0x3);
559 }
560 else // argument == 2
561 {
562 interpolant[index][0] |= swizzleContainsComponent(swizzle, 0);
563 interpolant[index][1] |= swizzleContainsComponent(swizzle, 1);
564 interpolant[index][2] |= swizzleContainsComponent(swizzle, 2);
565 interpolant[index][3] |= swizzleContainsComponent(swizzle, 3);
566 }
567 break;
John Bauman19bac1e2014-05-06 15:23:49 -0400568 case Shader::OPCODE_DP3:
John Bauman89401822014-05-06 15:04:28 -0400569 interpolant[index][0] |= swizzleContainsComponentMasked(swizzle, 0, 0x7);
570 interpolant[index][1] |= swizzleContainsComponentMasked(swizzle, 1, 0x7);
571 interpolant[index][2] |= swizzleContainsComponentMasked(swizzle, 2, 0x7);
572 interpolant[index][3] |= swizzleContainsComponentMasked(swizzle, 3, 0x7);
573 break;
John Bauman19bac1e2014-05-06 15:23:49 -0400574 case Shader::OPCODE_DP4:
John Bauman89401822014-05-06 15:04:28 -0400575 interpolant[index][0] |= swizzleContainsComponent(swizzle, 0);
576 interpolant[index][1] |= swizzleContainsComponent(swizzle, 1);
577 interpolant[index][2] |= swizzleContainsComponent(swizzle, 2);
578 interpolant[index][3] |= swizzleContainsComponent(swizzle, 3);
579 break;
John Bauman19bac1e2014-05-06 15:23:49 -0400580 case Shader::OPCODE_SINCOS:
581 case Shader::OPCODE_EXP2X:
582 case Shader::OPCODE_LOG2X:
583 case Shader::OPCODE_POWX:
584 case Shader::OPCODE_RCPX:
585 case Shader::OPCODE_RSQX:
John Bauman89401822014-05-06 15:04:28 -0400586 interpolant[index][0] |= swizzleContainsComponent(swizzle, 0);
587 interpolant[index][1] |= swizzleContainsComponent(swizzle, 1);
588 interpolant[index][2] |= swizzleContainsComponent(swizzle, 2);
589 interpolant[index][3] |= swizzleContainsComponent(swizzle, 3);
590 break;
John Bauman19bac1e2014-05-06 15:23:49 -0400591 case Shader::OPCODE_NRM3:
John Bauman89401822014-05-06 15:04:28 -0400592 interpolant[index][0] |= swizzleContainsComponentMasked(swizzle, 0, 0x7 | mask);
593 interpolant[index][1] |= swizzleContainsComponentMasked(swizzle, 1, 0x7 | mask);
594 interpolant[index][2] |= swizzleContainsComponentMasked(swizzle, 2, 0x7 | mask);
595 interpolant[index][3] |= swizzleContainsComponentMasked(swizzle, 3, 0x7 | mask);
596 break;
John Bauman19bac1e2014-05-06 15:23:49 -0400597 case Shader::OPCODE_MOV:
598 case Shader::OPCODE_ADD:
599 case Shader::OPCODE_SUB:
600 case Shader::OPCODE_MUL:
601 case Shader::OPCODE_MAD:
602 case Shader::OPCODE_ABS:
603 case Shader::OPCODE_CMP0:
604 case Shader::OPCODE_CND:
605 case Shader::OPCODE_FRC:
606 case Shader::OPCODE_LRP:
607 case Shader::OPCODE_MAX:
608 case Shader::OPCODE_MIN:
609 case Shader::OPCODE_CMP:
610 case Shader::OPCODE_BREAKC:
611 case Shader::OPCODE_DFDX:
612 case Shader::OPCODE_DFDY:
John Bauman89401822014-05-06 15:04:28 -0400613 interpolant[index][0] |= swizzleContainsComponentMasked(swizzle, 0, mask);
614 interpolant[index][1] |= swizzleContainsComponentMasked(swizzle, 1, mask);
615 interpolant[index][2] |= swizzleContainsComponentMasked(swizzle, 2, mask);
616 interpolant[index][3] |= swizzleContainsComponentMasked(swizzle, 3, mask);
617 break;
John Bauman19bac1e2014-05-06 15:23:49 -0400618 case Shader::OPCODE_TEXCOORD:
John Bauman89401822014-05-06 15:04:28 -0400619 interpolant[index][0] = true;
620 interpolant[index][1] = true;
621 interpolant[index][2] = true;
622 interpolant[index][3] = true;
623 break;
John Bauman19bac1e2014-05-06 15:23:49 -0400624 case Shader::OPCODE_TEXDP3:
625 case Shader::OPCODE_TEXDP3TEX:
626 case Shader::OPCODE_TEXM3X2PAD:
627 case Shader::OPCODE_TEXM3X3PAD:
628 case Shader::OPCODE_TEXM3X2TEX:
629 case Shader::OPCODE_TEXM3X3SPEC:
630 case Shader::OPCODE_TEXM3X3VSPEC:
631 case Shader::OPCODE_TEXBEM:
632 case Shader::OPCODE_TEXBEML:
633 case Shader::OPCODE_TEXM3X2DEPTH:
634 case Shader::OPCODE_TEXM3X3:
635 case Shader::OPCODE_TEXM3X3TEX:
John Bauman89401822014-05-06 15:04:28 -0400636 interpolant[index][0] = true;
637 interpolant[index][1] = true;
638 interpolant[index][2] = true;
639 break;
John Bauman19bac1e2014-05-06 15:23:49 -0400640 case Shader::OPCODE_TEXREG2AR:
641 case Shader::OPCODE_TEXREG2GB:
642 case Shader::OPCODE_TEXREG2RGB:
John Bauman89401822014-05-06 15:04:28 -0400643 break;
644 default:
645 // ASSERT(false); // Refine component usage
646 interpolant[index][0] = true;
647 interpolant[index][1] = true;
648 interpolant[index][2] = true;
649 interpolant[index][3] = true;
650 }
651 }
652 }
653 }
654
John Bauman66b8ab22014-05-06 15:57:45 -0400655 for(int index = 0; index < MAX_INPUT_VARYINGS; index++)
John Bauman89401822014-05-06 15:04:28 -0400656 {
657 for(int component = 0; component < 4; component++)
658 {
659 if(!interpolant[index][component])
660 {
661 semantic[index][component] = Semantic();
662 }
663 }
664 }
665 }
666 else // Shader Model 3.0 input declaration; v# indexable
667 {
John Bauman19bac1e2014-05-06 15:23:49 -0400668 for(unsigned int i = 0; i < instruction.size(); i++)
John Bauman89401822014-05-06 15:04:28 -0400669 {
John Bauman19bac1e2014-05-06 15:23:49 -0400670 if(instruction[i]->opcode == Shader::OPCODE_DCL)
John Bauman89401822014-05-06 15:04:28 -0400671 {
John Bauman19bac1e2014-05-06 15:23:49 -0400672 if(instruction[i]->dst.type == Shader::PARAMETER_INPUT)
John Bauman89401822014-05-06 15:04:28 -0400673 {
John Bauman19bac1e2014-05-06 15:23:49 -0400674 unsigned char usage = instruction[i]->usage;
675 unsigned char index = instruction[i]->usageIndex;
676 unsigned char mask = instruction[i]->dst.mask;
677 unsigned char reg = instruction[i]->dst.index;
John Bauman89401822014-05-06 15:04:28 -0400678
John Bauman19bac1e2014-05-06 15:23:49 -0400679 if(mask & 0x01) semantic[reg][0] = Semantic(usage, index);
680 if(mask & 0x02) semantic[reg][1] = Semantic(usage, index);
681 if(mask & 0x04) semantic[reg][2] = Semantic(usage, index);
682 if(mask & 0x08) semantic[reg][3] = Semantic(usage, index);
John Bauman89401822014-05-06 15:04:28 -0400683 }
John Bauman19bac1e2014-05-06 15:23:49 -0400684 else if(instruction[i]->dst.type == Shader::PARAMETER_MISCTYPE)
John Bauman89401822014-05-06 15:04:28 -0400685 {
John Bauman19bac1e2014-05-06 15:23:49 -0400686 unsigned char index = instruction[i]->dst.index;
John Bauman89401822014-05-06 15:04:28 -0400687
688 if(index == 0)
689 {
690 vPosDeclared = true;
691 }
692 else if(index == 1)
693 {
694 vFaceDeclared = true;
695 }
696 else ASSERT(false);
697 }
698 }
699 }
700 }
701
702 if(version >= 0x0200)
703 {
John Bauman19bac1e2014-05-06 15:23:49 -0400704 for(unsigned int i = 0; i < instruction.size(); i++)
John Bauman89401822014-05-06 15:04:28 -0400705 {
John Bauman19bac1e2014-05-06 15:23:49 -0400706 if(instruction[i]->opcode == Shader::OPCODE_DCL)
John Bauman89401822014-05-06 15:04:28 -0400707 {
John Bauman19bac1e2014-05-06 15:23:49 -0400708 bool centroid = instruction[i]->dst.centroid;
709 unsigned char reg = instruction[i]->dst.index;
John Bauman89401822014-05-06 15:04:28 -0400710
John Bauman19bac1e2014-05-06 15:23:49 -0400711 switch(instruction[i]->dst.type)
John Bauman89401822014-05-06 15:04:28 -0400712 {
John Bauman19bac1e2014-05-06 15:23:49 -0400713 case Shader::PARAMETER_INPUT:
John Bauman89401822014-05-06 15:04:28 -0400714 semantic[reg][0].centroid = centroid;
715 break;
John Bauman19bac1e2014-05-06 15:23:49 -0400716 case Shader::PARAMETER_TEXTURE:
John Bauman89401822014-05-06 15:04:28 -0400717 semantic[2 + reg][0].centroid = centroid;
718 break;
Nicolas Capensb69aa272016-01-02 00:06:41 -0500719 default:
720 break;
John Bauman89401822014-05-06 15:04:28 -0400721 }
722
723 this->centroid = this->centroid || centroid;
724 }
725 }
726 }
727 }
728}