blob: 1af50d82b3fbf196ca7c488db2e4504c4d66f887 [file] [log] [blame]
Nicolas Capens0bac2852016-05-07 06:09:58 -04001// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
John Bauman89401822014-05-06 15:04:28 -04002//
Nicolas Capens0bac2852016-05-07 06:09:58 -04003// 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
John Bauman89401822014-05-06 15:04:28 -04006//
Nicolas Capens0bac2852016-05-07 06:09:58 -04007// http://www.apache.org/licenses/LICENSE-2.0
John Bauman89401822014-05-06 15:04:28 -04008//
Nicolas Capens0bac2852016-05-07 06:09:58 -04009// 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.
John Bauman89401822014-05-06 15:04:28 -040014
15#include "PixelShader.hpp"
16
Nicolas Capens708c24b2017-10-26 13:07:10 -040017#include "Common/Debug.hpp"
John Bauman89401822014-05-06 15:04:28 -040018
John Bauman66b8ab22014-05-06 15:57:45 -040019#include <string.h>
20
John Bauman89401822014-05-06 15:04:28 -040021namespace sw
22{
John Bauman19bac1e2014-05-06 15:23:49 -040023 PixelShader::PixelShader(const PixelShader *ps) : Shader()
24 {
Alexis Hetu53ad4af2017-12-06 14:49:07 -050025 shaderModel = 0x0300;
John Bauman19bac1e2014-05-06 15:23:49 -040026 vPosDeclared = false;
27 vFaceDeclared = false;
28 centroid = false;
29
30 if(ps) // Make a copy
31 {
Alexis Hetu903e0252014-11-25 14:25:32 -050032 for(size_t i = 0; i < ps->getLength(); i++)
John Bauman19bac1e2014-05-06 15:23:49 -040033 {
34 append(new sw::Shader::Instruction(*ps->getInstruction(i)));
35 }
36
Alexis Hetu02ad0aa2016-08-02 11:18:14 -040037 memcpy(input, ps->input, sizeof(input));
John Bauman19bac1e2014-05-06 15:23:49 -040038 vPosDeclared = ps->vPosDeclared;
39 vFaceDeclared = ps->vFaceDeclared;
40 usedSamplers = ps->usedSamplers;
41
John Baumand4ae8632014-05-06 16:18:33 -040042 optimize();
John Bauman19bac1e2014-05-06 15:23:49 -040043 analyze();
44 }
45 }
46
47 PixelShader::PixelShader(const unsigned long *token) : Shader()
John Bauman89401822014-05-06 15:04:28 -040048 {
49 parse(token);
John Bauman19bac1e2014-05-06 15:23:49 -040050
51 vPosDeclared = false;
52 vFaceDeclared = false;
53 centroid = false;
54
John Baumand4ae8632014-05-06 16:18:33 -040055 optimize();
John Bauman19bac1e2014-05-06 15:23:49 -040056 analyze();
John Bauman89401822014-05-06 15:04:28 -040057 }
58
59 PixelShader::~PixelShader()
60 {
61 }
62
John Bauman89401822014-05-06 15:04:28 -040063 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);
Alexis Hetu7208e932016-06-02 11:19:24 -040071 // unsigned char minorVersion = (unsigned char)(token[0] & 0x000000FF);
John Bauman89401822014-05-06 15:04:28 -040072 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 {
John Bauman19bac1e2014-05-06 15:23:49 -040092 Shader::Opcode opcode = (Shader::Opcode)(token[i] & 0x0000FFFF);
John Bauman89401822014-05-06 15:04:28 -040093
94 switch(opcode)
95 {
John Bauman19bac1e2014-05-06 15:23:49 -040096 case Shader::OPCODE_RESERVED0:
97 case Shader::OPCODE_MOVA:
John Bauman89401822014-05-06 15:04:28 -040098 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
John Bauman19bac1e2014-05-06 15:23:49 -0400116 bool PixelShader::containsKill() const
John Bauman89401822014-05-06 15:04:28 -0400117 {
John Bauman19bac1e2014-05-06 15:23:49 -0400118 return kill;
John Bauman89401822014-05-06 15:04:28 -0400119 }
120
121 bool PixelShader::containsCentroid() const
122 {
123 return centroid;
124 }
125
126 bool PixelShader::usesDiffuse(int component) const
127 {
Alexis Hetu02ad0aa2016-08-02 11:18:14 -0400128 return input[0][component].active();
John Bauman89401822014-05-06 15:04:28 -0400129 }
130
131 bool PixelShader::usesSpecular(int component) const
132 {
Alexis Hetu02ad0aa2016-08-02 11:18:14 -0400133 return input[1][component].active();
John Bauman89401822014-05-06 15:04:28 -0400134 }
135
136 bool PixelShader::usesTexture(int coordinate, int component) const
137 {
Alexis Hetu02ad0aa2016-08-02 11:18:14 -0400138 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];
John Bauman89401822014-05-06 15:04:28 -0400152 }
153
John Bauman19bac1e2014-05-06 15:23:49 -0400154 void PixelShader::analyze()
155 {
156 analyzeZOverride();
157 analyzeKill();
158 analyzeInterpolants();
159 analyzeDirtyConstants();
160 analyzeDynamicBranching();
161 analyzeSamplers();
162 analyzeCallSites();
Nicolas Capens5bff4052018-05-28 13:18:59 -0400163 analyzeIndirectAddressing();
Ben Claytond951f192019-02-11 20:59:19 +0000164 analyzeLimits();
John Bauman19bac1e2014-05-06 15:23:49 -0400165 }
166
John Bauman89401822014-05-06 15:04:28 -0400167 void PixelShader::analyzeZOverride()
168 {
169 zOverride = false;
170
Alexis Hetubf3fc252017-12-06 14:22:10 -0500171 for(const auto &inst : instruction)
John Bauman89401822014-05-06 15:04:28 -0400172 {
Alexis Hetubf3fc252017-12-06 14:22:10 -0500173 if(inst->opcode == Shader::OPCODE_TEXM3X2DEPTH ||
174 inst->opcode == Shader::OPCODE_TEXDEPTH ||
175 inst->dst.type == Shader::PARAMETER_DEPTHOUT)
John Bauman89401822014-05-06 15:04:28 -0400176 {
177 zOverride = true;
178
179 break;
180 }
181 }
182 }
183
John Bauman19bac1e2014-05-06 15:23:49 -0400184 void PixelShader::analyzeKill()
John Bauman89401822014-05-06 15:04:28 -0400185 {
John Bauman19bac1e2014-05-06 15:23:49 -0400186 kill = false;
John Bauman89401822014-05-06 15:04:28 -0400187
Alexis Hetubf3fc252017-12-06 14:22:10 -0500188 for(const auto &inst : instruction)
John Bauman89401822014-05-06 15:04:28 -0400189 {
Alexis Hetubf3fc252017-12-06 14:22:10 -0500190 if(inst->opcode == Shader::OPCODE_TEXKILL ||
191 inst->opcode == Shader::OPCODE_DISCARD)
John Bauman89401822014-05-06 15:04:28 -0400192 {
John Bauman19bac1e2014-05-06 15:23:49 -0400193 kill = true;
John Bauman89401822014-05-06 15:04:28 -0400194
195 break;
196 }
197 }
198 }
199
200 void PixelShader::analyzeInterpolants()
201 {
Alexis Hetu53ad4af2017-12-06 14:49:07 -0500202 if(shaderModel < 0x0300)
John Bauman89401822014-05-06 15:04:28 -0400203 {
204 // Set default mapping; disable unused interpolants below
Alexis Hetu02ad0aa2016-08-02 11:18:14 -0400205 input[0][0] = Semantic(Shader::USAGE_COLOR, 0);
206 input[0][1] = Semantic(Shader::USAGE_COLOR, 0);
207 input[0][2] = Semantic(Shader::USAGE_COLOR, 0);
208 input[0][3] = Semantic(Shader::USAGE_COLOR, 0);
John Bauman89401822014-05-06 15:04:28 -0400209
Alexis Hetu02ad0aa2016-08-02 11:18:14 -0400210 input[1][0] = Semantic(Shader::USAGE_COLOR, 1);
211 input[1][1] = Semantic(Shader::USAGE_COLOR, 1);
212 input[1][2] = Semantic(Shader::USAGE_COLOR, 1);
213 input[1][3] = Semantic(Shader::USAGE_COLOR, 1);
John Bauman89401822014-05-06 15:04:28 -0400214
215 for(int i = 0; i < 8; i++)
216 {
Alexis Hetu02ad0aa2016-08-02 11:18:14 -0400217 input[2 + i][0] = Semantic(Shader::USAGE_TEXCOORD, i);
218 input[2 + i][1] = Semantic(Shader::USAGE_TEXCOORD, i);
219 input[2 + i][2] = Semantic(Shader::USAGE_TEXCOORD, i);
220 input[2 + i][3] = Semantic(Shader::USAGE_TEXCOORD, i);
John Bauman89401822014-05-06 15:04:28 -0400221 }
222
John Bauman19bac1e2014-05-06 15:23:49 -0400223 Shader::SamplerType samplerType[16];
John Bauman89401822014-05-06 15:04:28 -0400224
225 for(int i = 0; i < 16; i++)
226 {
John Bauman19bac1e2014-05-06 15:23:49 -0400227 samplerType[i] = Shader::SAMPLER_UNKNOWN;
John Bauman89401822014-05-06 15:04:28 -0400228 }
229
Alexis Hetubf3fc252017-12-06 14:22:10 -0500230 for(const auto &inst : instruction)
John Bauman89401822014-05-06 15:04:28 -0400231 {
Alexis Hetubf3fc252017-12-06 14:22:10 -0500232 if(inst->dst.type == Shader::PARAMETER_SAMPLER)
John Bauman89401822014-05-06 15:04:28 -0400233 {
Alexis Hetubf3fc252017-12-06 14:22:10 -0500234 int sampler = inst->dst.index;
John Bauman89401822014-05-06 15:04:28 -0400235
Alexis Hetubf3fc252017-12-06 14:22:10 -0500236 samplerType[sampler] = inst->samplerType;
John Bauman89401822014-05-06 15:04:28 -0400237 }
238 }
239
Nicolas Capens3b4c93f2016-05-18 12:51:37 -0400240 bool interpolant[MAX_FRAGMENT_INPUTS][4] = {{false}}; // Interpolants in use
John Bauman89401822014-05-06 15:04:28 -0400241
Alexis Hetubf3fc252017-12-06 14:22:10 -0500242 for(const auto &inst : instruction)
John Bauman89401822014-05-06 15:04:28 -0400243 {
Alexis Hetubf3fc252017-12-06 14:22:10 -0500244 if(inst->dst.type == Shader::PARAMETER_TEXTURE)
Nicolas Capens6abe1cb2016-01-15 23:30:50 -0500245 {
Alexis Hetubf3fc252017-12-06 14:22:10 -0500246 int index = inst->dst.index + 2;
John Bauman89401822014-05-06 15:04:28 -0400247
Alexis Hetubf3fc252017-12-06 14:22:10 -0500248 switch(inst->opcode)
John Bauman89401822014-05-06 15:04:28 -0400249 {
John Bauman19bac1e2014-05-06 15:23:49 -0400250 case Shader::OPCODE_TEX:
251 case Shader::OPCODE_TEXBEM:
252 case Shader::OPCODE_TEXBEML:
253 case Shader::OPCODE_TEXCOORD:
254 case Shader::OPCODE_TEXDP3:
255 case Shader::OPCODE_TEXDP3TEX:
256 case Shader::OPCODE_TEXM3X2DEPTH:
257 case Shader::OPCODE_TEXM3X2PAD:
258 case Shader::OPCODE_TEXM3X2TEX:
259 case Shader::OPCODE_TEXM3X3:
260 case Shader::OPCODE_TEXM3X3PAD:
261 case Shader::OPCODE_TEXM3X3TEX:
John Bauman89401822014-05-06 15:04:28 -0400262 interpolant[index][0] = true;
263 interpolant[index][1] = true;
264 interpolant[index][2] = true;
265 break;
John Bauman19bac1e2014-05-06 15:23:49 -0400266 case Shader::OPCODE_TEXKILL:
John Bauman89401822014-05-06 15:04:28 -0400267 if(majorVersion < 2)
268 {
269 interpolant[index][0] = true;
270 interpolant[index][1] = true;
271 interpolant[index][2] = true;
272 }
273 else
274 {
275 interpolant[index][0] = true;
276 interpolant[index][1] = true;
277 interpolant[index][2] = true;
278 interpolant[index][3] = true;
279 }
280 break;
John Bauman19bac1e2014-05-06 15:23:49 -0400281 case Shader::OPCODE_TEXM3X3VSPEC:
John Bauman89401822014-05-06 15:04:28 -0400282 interpolant[index][0] = true;
283 interpolant[index][1] = true;
284 interpolant[index][2] = true;
285 interpolant[index - 2][3] = true;
286 interpolant[index - 1][3] = true;
287 interpolant[index - 0][3] = true;
288 break;
John Bauman19bac1e2014-05-06 15:23:49 -0400289 case Shader::OPCODE_DCL:
John Bauman89401822014-05-06 15:04:28 -0400290 break; // Ignore
291 default: // Arithmetic instruction
Alexis Hetu53ad4af2017-12-06 14:49:07 -0500292 if(shaderModel >= 0x0104)
John Bauman89401822014-05-06 15:04:28 -0400293 {
294 ASSERT(false);
295 }
296 }
297 }
298
299 for(int argument = 0; argument < 4; argument++)
300 {
Alexis Hetubf3fc252017-12-06 14:22:10 -0500301 if(inst->src[argument].type == Shader::PARAMETER_INPUT ||
302 inst->src[argument].type == Shader::PARAMETER_TEXTURE)
John Bauman89401822014-05-06 15:04:28 -0400303 {
Alexis Hetubf3fc252017-12-06 14:22:10 -0500304 int index = inst->src[argument].index;
305 int swizzle = inst->src[argument].swizzle;
306 int mask = inst->dst.mask;
Nicolas Capens6abe1cb2016-01-15 23:30:50 -0500307
Alexis Hetubf3fc252017-12-06 14:22:10 -0500308 if(inst->src[argument].type == Shader::PARAMETER_TEXTURE)
John Bauman89401822014-05-06 15:04:28 -0400309 {
310 index += 2;
311 }
312
Alexis Hetubf3fc252017-12-06 14:22:10 -0500313 switch(inst->opcode)
John Bauman89401822014-05-06 15:04:28 -0400314 {
John Bauman19bac1e2014-05-06 15:23:49 -0400315 case Shader::OPCODE_TEX:
316 case Shader::OPCODE_TEXLDD:
317 case Shader::OPCODE_TEXLDL:
Nicolas Capensa0b57832017-11-07 13:07:53 -0500318 case Shader::OPCODE_TEXLOD:
319 case Shader::OPCODE_TEXBIAS:
Alexis Hetu25d47fc2015-10-22 13:58:32 -0400320 case Shader::OPCODE_TEXOFFSET:
Nicolas Capensa0b57832017-11-07 13:07:53 -0500321 case Shader::OPCODE_TEXOFFSETBIAS:
322 case Shader::OPCODE_TEXLODOFFSET:
Alexis Hetu25d47fc2015-10-22 13:58:32 -0400323 case Shader::OPCODE_TEXELFETCH:
324 case Shader::OPCODE_TEXELFETCHOFFSET:
325 case Shader::OPCODE_TEXGRAD:
326 case Shader::OPCODE_TEXGRADOFFSET:
John Bauman89401822014-05-06 15:04:28 -0400327 {
Alexis Hetubf3fc252017-12-06 14:22:10 -0500328 int sampler = inst->src[1].index;
John Bauman89401822014-05-06 15:04:28 -0400329
330 switch(samplerType[sampler])
331 {
John Bauman19bac1e2014-05-06 15:23:49 -0400332 case Shader::SAMPLER_UNKNOWN:
Alexis Hetu53ad4af2017-12-06 14:49:07 -0500333 if(shaderModel == 0x0104)
John Bauman89401822014-05-06 15:04:28 -0400334 {
Alexis Hetubf3fc252017-12-06 14:22:10 -0500335 if((inst->src[0].swizzle & 0x30) == 0x20) // .xyz
John Bauman89401822014-05-06 15:04:28 -0400336 {
337 interpolant[index][0] = true;
338 interpolant[index][1] = true;
339 interpolant[index][2] = true;
340 }
341 else // .xyw
342 {
343 interpolant[index][0] = true;
344 interpolant[index][1] = true;
345 interpolant[index][3] = true;
346 }
347 }
348 else
349 {
350 ASSERT(false);
351 }
352 break;
John Bauman19bac1e2014-05-06 15:23:49 -0400353 case Shader::SAMPLER_1D:
John Bauman89401822014-05-06 15:04:28 -0400354 interpolant[index][0] = true;
355 break;
John Bauman19bac1e2014-05-06 15:23:49 -0400356 case Shader::SAMPLER_2D:
John Bauman89401822014-05-06 15:04:28 -0400357 interpolant[index][0] = true;
358 interpolant[index][1] = true;
359 break;
John Bauman19bac1e2014-05-06 15:23:49 -0400360 case Shader::SAMPLER_CUBE:
John Bauman89401822014-05-06 15:04:28 -0400361 interpolant[index][0] = true;
362 interpolant[index][1] = true;
363 interpolant[index][2] = true;
364 break;
John Bauman19bac1e2014-05-06 15:23:49 -0400365 case Shader::SAMPLER_VOLUME:
John Bauman89401822014-05-06 15:04:28 -0400366 interpolant[index][0] = true;
367 interpolant[index][1] = true;
368 interpolant[index][2] = true;
369 break;
370 default:
371 ASSERT(false);
372 }
373
Alexis Hetubf3fc252017-12-06 14:22:10 -0500374 if(inst->bias)
John Bauman89401822014-05-06 15:04:28 -0400375 {
376 interpolant[index][3] = true;
377 }
378
Alexis Hetubf3fc252017-12-06 14:22:10 -0500379 if(inst->project)
John Bauman89401822014-05-06 15:04:28 -0400380 {
381 interpolant[index][3] = true;
382 }
383
Alexis Hetu53ad4af2017-12-06 14:49:07 -0500384 if(shaderModel == 0x0104 && inst->opcode == Shader::OPCODE_TEX)
John Bauman89401822014-05-06 15:04:28 -0400385 {
Alexis Hetubf3fc252017-12-06 14:22:10 -0500386 if(inst->src[0].modifier == Shader::MODIFIER_DZ)
John Bauman89401822014-05-06 15:04:28 -0400387 {
388 interpolant[index][2] = true;
389 }
390
Alexis Hetubf3fc252017-12-06 14:22:10 -0500391 if(inst->src[0].modifier == Shader::MODIFIER_DW)
John Bauman89401822014-05-06 15:04:28 -0400392 {
393 interpolant[index][3] = true;
394 }
395 }
396 }
397 break;
John Bauman19bac1e2014-05-06 15:23:49 -0400398 case Shader::OPCODE_M3X2:
John Bauman89401822014-05-06 15:04:28 -0400399 if(mask & 0x1)
400 {
401 interpolant[index][0] |= swizzleContainsComponentMasked(swizzle, 0, 0x7);
402 interpolant[index][1] |= swizzleContainsComponentMasked(swizzle, 1, 0x7);
403 interpolant[index][2] |= swizzleContainsComponentMasked(swizzle, 2, 0x7);
404 interpolant[index][3] |= swizzleContainsComponentMasked(swizzle, 3, 0x7);
405 }
406
407 if(argument == 1)
408 {
409 if(mask & 0x2)
410 {
411 interpolant[index + 1][0] |= swizzleContainsComponentMasked(swizzle, 0, 0x7);
412 interpolant[index + 1][1] |= swizzleContainsComponentMasked(swizzle, 1, 0x7);
413 interpolant[index + 1][2] |= swizzleContainsComponentMasked(swizzle, 2, 0x7);
414 interpolant[index + 1][3] |= swizzleContainsComponentMasked(swizzle, 3, 0x7);
415 }
416 }
417 break;
John Bauman19bac1e2014-05-06 15:23:49 -0400418 case Shader::OPCODE_M3X3:
John Bauman89401822014-05-06 15:04:28 -0400419 if(mask & 0x1)
420 {
421 interpolant[index][0] |= swizzleContainsComponentMasked(swizzle, 0, 0x7);
422 interpolant[index][1] |= swizzleContainsComponentMasked(swizzle, 1, 0x7);
423 interpolant[index][2] |= swizzleContainsComponentMasked(swizzle, 2, 0x7);
424 interpolant[index][3] |= swizzleContainsComponentMasked(swizzle, 3, 0x7);
425 }
426
427 if(argument == 1)
428 {
429 if(mask & 0x2)
430 {
431 interpolant[index + 1][0] |= swizzleContainsComponentMasked(swizzle, 0, 0x7);
432 interpolant[index + 1][1] |= swizzleContainsComponentMasked(swizzle, 1, 0x7);
433 interpolant[index + 1][2] |= swizzleContainsComponentMasked(swizzle, 2, 0x7);
434 interpolant[index + 1][3] |= swizzleContainsComponentMasked(swizzle, 3, 0x7);
435 }
436
437 if(mask & 0x4)
438 {
439 interpolant[index + 2][0] |= swizzleContainsComponentMasked(swizzle, 0, 0x7);
440 interpolant[index + 2][1] |= swizzleContainsComponentMasked(swizzle, 1, 0x7);
441 interpolant[index + 2][2] |= swizzleContainsComponentMasked(swizzle, 2, 0x7);
442 interpolant[index + 2][3] |= swizzleContainsComponentMasked(swizzle, 3, 0x7);
443 }
444 }
445 break;
John Bauman19bac1e2014-05-06 15:23:49 -0400446 case Shader::OPCODE_M3X4:
John Bauman89401822014-05-06 15:04:28 -0400447 if(mask & 0x1)
448 {
449 interpolant[index][0] |= swizzleContainsComponentMasked(swizzle, 0, 0x7);
450 interpolant[index][1] |= swizzleContainsComponentMasked(swizzle, 1, 0x7);
451 interpolant[index][2] |= swizzleContainsComponentMasked(swizzle, 2, 0x7);
452 interpolant[index][3] |= swizzleContainsComponentMasked(swizzle, 3, 0x7);
453 }
454
455 if(argument == 1)
456 {
457 if(mask & 0x2)
458 {
459 interpolant[index + 1][0] |= swizzleContainsComponentMasked(swizzle, 0, 0x7);
460 interpolant[index + 1][1] |= swizzleContainsComponentMasked(swizzle, 1, 0x7);
461 interpolant[index + 1][2] |= swizzleContainsComponentMasked(swizzle, 2, 0x7);
462 interpolant[index + 1][3] |= swizzleContainsComponentMasked(swizzle, 3, 0x7);
463 }
464
465 if(mask & 0x4)
466 {
467 interpolant[index + 2][0] |= swizzleContainsComponentMasked(swizzle, 0, 0x7);
468 interpolant[index + 2][1] |= swizzleContainsComponentMasked(swizzle, 1, 0x7);
469 interpolant[index + 2][2] |= swizzleContainsComponentMasked(swizzle, 2, 0x7);
470 interpolant[index + 2][3] |= swizzleContainsComponentMasked(swizzle, 3, 0x7);
471 }
472
473 if(mask & 0x8)
474 {
475 interpolant[index + 3][0] |= swizzleContainsComponentMasked(swizzle, 0, 0x7);
476 interpolant[index + 3][1] |= swizzleContainsComponentMasked(swizzle, 1, 0x7);
477 interpolant[index + 3][2] |= swizzleContainsComponentMasked(swizzle, 2, 0x7);
478 interpolant[index + 3][3] |= swizzleContainsComponentMasked(swizzle, 3, 0x7);
479 }
480 }
481 break;
John Bauman19bac1e2014-05-06 15:23:49 -0400482 case Shader::OPCODE_M4X3:
John Bauman89401822014-05-06 15:04:28 -0400483 if(mask & 0x1)
484 {
485 interpolant[index][0] |= swizzleContainsComponent(swizzle, 0);
486 interpolant[index][1] |= swizzleContainsComponent(swizzle, 1);
487 interpolant[index][2] |= swizzleContainsComponent(swizzle, 2);
488 interpolant[index][3] |= swizzleContainsComponent(swizzle, 3);
489 }
490
491 if(argument == 1)
492 {
493 if(mask & 0x2)
494 {
495 interpolant[index + 1][0] |= swizzleContainsComponent(swizzle, 0);
496 interpolant[index + 1][1] |= swizzleContainsComponent(swizzle, 1);
497 interpolant[index + 1][2] |= swizzleContainsComponent(swizzle, 2);
498 interpolant[index + 1][3] |= swizzleContainsComponent(swizzle, 3);
499 }
500
501 if(mask & 0x4)
502 {
503 interpolant[index + 2][0] |= swizzleContainsComponent(swizzle, 0);
504 interpolant[index + 2][1] |= swizzleContainsComponent(swizzle, 1);
505 interpolant[index + 2][2] |= swizzleContainsComponent(swizzle, 2);
506 interpolant[index + 2][3] |= swizzleContainsComponent(swizzle, 3);
507 }
508 }
509 break;
John Bauman19bac1e2014-05-06 15:23:49 -0400510 case Shader::OPCODE_M4X4:
John Bauman89401822014-05-06 15:04:28 -0400511 if(mask & 0x1)
512 {
513 interpolant[index][0] |= swizzleContainsComponent(swizzle, 0);
514 interpolant[index][1] |= swizzleContainsComponent(swizzle, 1);
515 interpolant[index][2] |= swizzleContainsComponent(swizzle, 2);
516 interpolant[index][3] |= swizzleContainsComponent(swizzle, 3);
517 }
518
519 if(argument == 1)
520 {
521 if(mask & 0x2)
522 {
523 interpolant[index + 1][0] |= swizzleContainsComponent(swizzle, 0);
524 interpolant[index + 1][1] |= swizzleContainsComponent(swizzle, 1);
525 interpolant[index + 1][2] |= swizzleContainsComponent(swizzle, 2);
526 interpolant[index + 1][3] |= swizzleContainsComponent(swizzle, 3);
527 }
528
529 if(mask & 0x4)
530 {
531 interpolant[index + 2][0] |= swizzleContainsComponent(swizzle, 0);
532 interpolant[index + 2][1] |= swizzleContainsComponent(swizzle, 1);
533 interpolant[index + 2][2] |= swizzleContainsComponent(swizzle, 2);
534 interpolant[index + 2][3] |= swizzleContainsComponent(swizzle, 3);
535 }
536
537 if(mask & 0x8)
538 {
539 interpolant[index + 3][0] |= swizzleContainsComponent(swizzle, 0);
540 interpolant[index + 3][1] |= swizzleContainsComponent(swizzle, 1);
541 interpolant[index + 3][2] |= swizzleContainsComponent(swizzle, 2);
542 interpolant[index + 3][3] |= swizzleContainsComponent(swizzle, 3);
543 }
544 }
545 break;
John Bauman19bac1e2014-05-06 15:23:49 -0400546 case Shader::OPCODE_CRS:
John Bauman89401822014-05-06 15:04:28 -0400547 if(mask & 0x1)
548 {
549 interpolant[index][0] |= swizzleContainsComponentMasked(swizzle, 0, 0x6);
550 interpolant[index][1] |= swizzleContainsComponentMasked(swizzle, 1, 0x6);
551 interpolant[index][2] |= swizzleContainsComponentMasked(swizzle, 2, 0x6);
552 interpolant[index][3] |= swizzleContainsComponentMasked(swizzle, 3, 0x6);
553 }
554
555 if(mask & 0x2)
556 {
557 interpolant[index][0] |= swizzleContainsComponentMasked(swizzle, 0, 0x5);
558 interpolant[index][1] |= swizzleContainsComponentMasked(swizzle, 1, 0x5);
559 interpolant[index][2] |= swizzleContainsComponentMasked(swizzle, 2, 0x5);
560 interpolant[index][3] |= swizzleContainsComponentMasked(swizzle, 3, 0x5);
561 }
562
563 if(mask & 0x4)
564 {
565 interpolant[index][0] |= swizzleContainsComponentMasked(swizzle, 0, 0x3);
566 interpolant[index][1] |= swizzleContainsComponentMasked(swizzle, 1, 0x3);
567 interpolant[index][2] |= swizzleContainsComponentMasked(swizzle, 2, 0x3);
568 interpolant[index][3] |= swizzleContainsComponentMasked(swizzle, 3, 0x3);
569 }
570 break;
John Bauman19bac1e2014-05-06 15:23:49 -0400571 case Shader::OPCODE_DP2ADD:
John Bauman89401822014-05-06 15:04:28 -0400572 if(argument == 0 || argument == 1)
573 {
574 interpolant[index][0] |= swizzleContainsComponentMasked(swizzle, 0, 0x3);
575 interpolant[index][1] |= swizzleContainsComponentMasked(swizzle, 1, 0x3);
576 interpolant[index][2] |= swizzleContainsComponentMasked(swizzle, 2, 0x3);
577 interpolant[index][3] |= swizzleContainsComponentMasked(swizzle, 3, 0x3);
578 }
579 else // argument == 2
580 {
581 interpolant[index][0] |= swizzleContainsComponent(swizzle, 0);
582 interpolant[index][1] |= swizzleContainsComponent(swizzle, 1);
583 interpolant[index][2] |= swizzleContainsComponent(swizzle, 2);
584 interpolant[index][3] |= swizzleContainsComponent(swizzle, 3);
585 }
586 break;
John Bauman19bac1e2014-05-06 15:23:49 -0400587 case Shader::OPCODE_DP3:
John Bauman89401822014-05-06 15:04:28 -0400588 interpolant[index][0] |= swizzleContainsComponentMasked(swizzle, 0, 0x7);
589 interpolant[index][1] |= swizzleContainsComponentMasked(swizzle, 1, 0x7);
590 interpolant[index][2] |= swizzleContainsComponentMasked(swizzle, 2, 0x7);
591 interpolant[index][3] |= swizzleContainsComponentMasked(swizzle, 3, 0x7);
592 break;
John Bauman19bac1e2014-05-06 15:23:49 -0400593 case Shader::OPCODE_DP4:
John Bauman89401822014-05-06 15:04:28 -0400594 interpolant[index][0] |= swizzleContainsComponent(swizzle, 0);
595 interpolant[index][1] |= swizzleContainsComponent(swizzle, 1);
596 interpolant[index][2] |= swizzleContainsComponent(swizzle, 2);
597 interpolant[index][3] |= swizzleContainsComponent(swizzle, 3);
598 break;
John Bauman19bac1e2014-05-06 15:23:49 -0400599 case Shader::OPCODE_SINCOS:
600 case Shader::OPCODE_EXP2X:
601 case Shader::OPCODE_LOG2X:
602 case Shader::OPCODE_POWX:
603 case Shader::OPCODE_RCPX:
604 case Shader::OPCODE_RSQX:
John Bauman89401822014-05-06 15:04:28 -0400605 interpolant[index][0] |= swizzleContainsComponent(swizzle, 0);
606 interpolant[index][1] |= swizzleContainsComponent(swizzle, 1);
607 interpolant[index][2] |= swizzleContainsComponent(swizzle, 2);
608 interpolant[index][3] |= swizzleContainsComponent(swizzle, 3);
609 break;
John Bauman19bac1e2014-05-06 15:23:49 -0400610 case Shader::OPCODE_NRM3:
John Bauman89401822014-05-06 15:04:28 -0400611 interpolant[index][0] |= swizzleContainsComponentMasked(swizzle, 0, 0x7 | mask);
612 interpolant[index][1] |= swizzleContainsComponentMasked(swizzle, 1, 0x7 | mask);
613 interpolant[index][2] |= swizzleContainsComponentMasked(swizzle, 2, 0x7 | mask);
614 interpolant[index][3] |= swizzleContainsComponentMasked(swizzle, 3, 0x7 | mask);
615 break;
John Bauman19bac1e2014-05-06 15:23:49 -0400616 case Shader::OPCODE_MOV:
617 case Shader::OPCODE_ADD:
618 case Shader::OPCODE_SUB:
619 case Shader::OPCODE_MUL:
620 case Shader::OPCODE_MAD:
621 case Shader::OPCODE_ABS:
622 case Shader::OPCODE_CMP0:
623 case Shader::OPCODE_CND:
624 case Shader::OPCODE_FRC:
625 case Shader::OPCODE_LRP:
626 case Shader::OPCODE_MAX:
627 case Shader::OPCODE_MIN:
628 case Shader::OPCODE_CMP:
629 case Shader::OPCODE_BREAKC:
630 case Shader::OPCODE_DFDX:
631 case Shader::OPCODE_DFDY:
John Bauman89401822014-05-06 15:04:28 -0400632 interpolant[index][0] |= swizzleContainsComponentMasked(swizzle, 0, mask);
633 interpolant[index][1] |= swizzleContainsComponentMasked(swizzle, 1, mask);
634 interpolant[index][2] |= swizzleContainsComponentMasked(swizzle, 2, mask);
635 interpolant[index][3] |= swizzleContainsComponentMasked(swizzle, 3, mask);
636 break;
John Bauman19bac1e2014-05-06 15:23:49 -0400637 case Shader::OPCODE_TEXCOORD:
John Bauman89401822014-05-06 15:04:28 -0400638 interpolant[index][0] = true;
639 interpolant[index][1] = true;
640 interpolant[index][2] = true;
641 interpolant[index][3] = true;
642 break;
John Bauman19bac1e2014-05-06 15:23:49 -0400643 case Shader::OPCODE_TEXDP3:
644 case Shader::OPCODE_TEXDP3TEX:
645 case Shader::OPCODE_TEXM3X2PAD:
646 case Shader::OPCODE_TEXM3X3PAD:
647 case Shader::OPCODE_TEXM3X2TEX:
648 case Shader::OPCODE_TEXM3X3SPEC:
649 case Shader::OPCODE_TEXM3X3VSPEC:
650 case Shader::OPCODE_TEXBEM:
651 case Shader::OPCODE_TEXBEML:
652 case Shader::OPCODE_TEXM3X2DEPTH:
653 case Shader::OPCODE_TEXM3X3:
654 case Shader::OPCODE_TEXM3X3TEX:
John Bauman89401822014-05-06 15:04:28 -0400655 interpolant[index][0] = true;
656 interpolant[index][1] = true;
657 interpolant[index][2] = true;
658 break;
John Bauman19bac1e2014-05-06 15:23:49 -0400659 case Shader::OPCODE_TEXREG2AR:
660 case Shader::OPCODE_TEXREG2GB:
661 case Shader::OPCODE_TEXREG2RGB:
John Bauman89401822014-05-06 15:04:28 -0400662 break;
663 default:
664 // ASSERT(false); // Refine component usage
665 interpolant[index][0] = true;
666 interpolant[index][1] = true;
667 interpolant[index][2] = true;
668 interpolant[index][3] = true;
669 }
670 }
671 }
672 }
673
Nicolas Capens3b4c93f2016-05-18 12:51:37 -0400674 for(int index = 0; index < MAX_FRAGMENT_INPUTS; index++)
John Bauman89401822014-05-06 15:04:28 -0400675 {
676 for(int component = 0; component < 4; component++)
677 {
678 if(!interpolant[index][component])
679 {
Alexis Hetu02ad0aa2016-08-02 11:18:14 -0400680 input[index][component] = Semantic();
John Bauman89401822014-05-06 15:04:28 -0400681 }
682 }
683 }
684 }
685 else // Shader Model 3.0 input declaration; v# indexable
686 {
Alexis Hetubf3fc252017-12-06 14:22:10 -0500687 for(const auto &inst : instruction)
John Bauman89401822014-05-06 15:04:28 -0400688 {
Alexis Hetubf3fc252017-12-06 14:22:10 -0500689 if(inst->opcode == Shader::OPCODE_DCL)
John Bauman89401822014-05-06 15:04:28 -0400690 {
Alexis Hetubf3fc252017-12-06 14:22:10 -0500691 if(inst->dst.type == Shader::PARAMETER_INPUT)
John Bauman89401822014-05-06 15:04:28 -0400692 {
Alexis Hetubf3fc252017-12-06 14:22:10 -0500693 unsigned char usage = inst->usage;
694 unsigned char index = inst->usageIndex;
695 unsigned char mask = inst->dst.mask;
696 unsigned char reg = inst->dst.index;
John Bauman89401822014-05-06 15:04:28 -0400697
Nicolas Capens8af24c52017-12-11 14:45:01 -0500698 if(mask & 0x01) input[reg][0] = Semantic(usage, index);
Alexis Hetu02ad0aa2016-08-02 11:18:14 -0400699 if(mask & 0x02) input[reg][1] = Semantic(usage, index);
700 if(mask & 0x04) input[reg][2] = Semantic(usage, index);
Nicolas Capens8af24c52017-12-11 14:45:01 -0500701 if(mask & 0x08) input[reg][3] = Semantic(usage, index);
John Bauman89401822014-05-06 15:04:28 -0400702 }
Alexis Hetubf3fc252017-12-06 14:22:10 -0500703 else if(inst->dst.type == Shader::PARAMETER_MISCTYPE)
John Bauman89401822014-05-06 15:04:28 -0400704 {
Alexis Hetubf3fc252017-12-06 14:22:10 -0500705 unsigned char index = inst->dst.index;
John Bauman89401822014-05-06 15:04:28 -0400706
Alexis Hetu877ddfc2017-07-25 17:48:00 -0400707 if(index == Shader::VPosIndex)
John Bauman89401822014-05-06 15:04:28 -0400708 {
709 vPosDeclared = true;
710 }
Alexis Hetu877ddfc2017-07-25 17:48:00 -0400711 else if(index == Shader::VFaceIndex)
John Bauman89401822014-05-06 15:04:28 -0400712 {
713 vFaceDeclared = true;
714 }
715 else ASSERT(false);
716 }
717 }
718 }
719 }
720
Alexis Hetu53ad4af2017-12-06 14:49:07 -0500721 if(shaderModel >= 0x0200)
John Bauman89401822014-05-06 15:04:28 -0400722 {
Alexis Hetubf3fc252017-12-06 14:22:10 -0500723 for(const auto &inst : instruction)
John Bauman89401822014-05-06 15:04:28 -0400724 {
Alexis Hetubf3fc252017-12-06 14:22:10 -0500725 if(inst->opcode == Shader::OPCODE_DCL)
John Bauman89401822014-05-06 15:04:28 -0400726 {
Alexis Hetubf3fc252017-12-06 14:22:10 -0500727 bool centroid = inst->dst.centroid;
728 unsigned char reg = inst->dst.index;
John Bauman89401822014-05-06 15:04:28 -0400729
Alexis Hetubf3fc252017-12-06 14:22:10 -0500730 switch(inst->dst.type)
John Bauman89401822014-05-06 15:04:28 -0400731 {
John Bauman19bac1e2014-05-06 15:23:49 -0400732 case Shader::PARAMETER_INPUT:
Alexis Hetu02ad0aa2016-08-02 11:18:14 -0400733 input[reg][0].centroid = centroid;
John Bauman89401822014-05-06 15:04:28 -0400734 break;
John Bauman19bac1e2014-05-06 15:23:49 -0400735 case Shader::PARAMETER_TEXTURE:
Alexis Hetu02ad0aa2016-08-02 11:18:14 -0400736 input[2 + reg][0].centroid = centroid;
John Bauman89401822014-05-06 15:04:28 -0400737 break;
Nicolas Capensb69aa272016-01-02 00:06:41 -0500738 default:
739 break;
John Bauman89401822014-05-06 15:04:28 -0400740 }
741
742 this->centroid = this->centroid || centroid;
743 }
744 }
745 }
746 }
747}