1 // Copyright 2016 The SwiftShader Authors. All Rights Reserved.
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
7 // http://www.apache.org/licenses/LICENSE-2.0
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
15 #include "VertexShader.hpp"
24 VertexShader::VertexShader(const VertexShader *vs) : Shader()
27 positionRegister = Pos;
28 pointSizeRegister = Unused;
29 instanceIdDeclared = false;
30 vertexIdDeclared = false;
31 textureSampling = false;
33 for(int i = 0; i < MAX_VERTEX_INPUTS; i++)
35 input[i] = Semantic();
36 attribType[i] = ATTRIBTYPE_FLOAT;
41 for(size_t i = 0; i < vs->getLength(); i++)
43 append(new sw::Shader::Instruction(*vs->getInstruction(i)));
46 memcpy(output, vs->output, sizeof(output));
47 memcpy(input, vs->input, sizeof(input));
48 memcpy(attribType, vs->attribType, sizeof(attribType));
49 positionRegister = vs->positionRegister;
50 pointSizeRegister = vs->pointSizeRegister;
51 instanceIdDeclared = vs->instanceIdDeclared;
52 vertexIdDeclared = vs->vertexIdDeclared;
53 usedSamplers = vs->usedSamplers;
60 VertexShader::VertexShader(const unsigned long *token) : Shader()
64 positionRegister = Pos;
65 pointSizeRegister = Unused;
66 instanceIdDeclared = false;
67 vertexIdDeclared = false;
68 textureSampling = false;
70 for(int i = 0; i < MAX_VERTEX_INPUTS; i++)
72 input[i] = Semantic();
73 attribType[i] = ATTRIBTYPE_FLOAT;
80 VertexShader::~VertexShader()
84 int VertexShader::validate(const unsigned long *const token)
91 unsigned short version = (unsigned short)(token[0] & 0x0000FFFF);
92 unsigned char majorVersion = (unsigned char)((token[0] & 0x0000FF00) >> 8);
93 ShaderType shaderType = (ShaderType)((token[0] & 0xFFFF0000) >> 16);
95 if(shaderType != SHADER_VERTEX || majorVersion > 3)
100 int instructionCount = 1;
102 for(int i = 0; token[i] != 0x0000FFFF; i++)
104 if((token[i] & 0x0000FFFF) == 0x0000FFFE) // Comment token
106 int length = (token[i] & 0x7FFF0000) >> 16;
112 Shader::Opcode opcode = (Shader::Opcode)(token[i] & 0x0000FFFF);
116 case Shader::OPCODE_TEXCOORD:
117 case Shader::OPCODE_TEXKILL:
118 case Shader::OPCODE_TEX:
119 case Shader::OPCODE_TEXBEM:
120 case Shader::OPCODE_TEXBEML:
121 case Shader::OPCODE_TEXREG2AR:
122 case Shader::OPCODE_TEXREG2GB:
123 case Shader::OPCODE_TEXM3X2PAD:
124 case Shader::OPCODE_TEXM3X2TEX:
125 case Shader::OPCODE_TEXM3X3PAD:
126 case Shader::OPCODE_TEXM3X3TEX:
127 case Shader::OPCODE_RESERVED0:
128 case Shader::OPCODE_TEXM3X3SPEC:
129 case Shader::OPCODE_TEXM3X3VSPEC:
130 case Shader::OPCODE_TEXREG2RGB:
131 case Shader::OPCODE_TEXDP3TEX:
132 case Shader::OPCODE_TEXM3X2DEPTH:
133 case Shader::OPCODE_TEXDP3:
134 case Shader::OPCODE_TEXM3X3:
135 case Shader::OPCODE_TEXDEPTH:
136 case Shader::OPCODE_CMP0:
137 case Shader::OPCODE_BEM:
138 case Shader::OPCODE_DP2ADD:
139 case Shader::OPCODE_DFDX:
140 case Shader::OPCODE_DFDY:
141 case Shader::OPCODE_TEXLDD:
142 return 0; // Unsupported operation
148 i += size(token[i], version);
152 return instructionCount;
155 bool VertexShader::containsTextureSampling() const
157 return textureSampling;
160 void VertexShader::setInput(int inputIdx, const sw::Shader::Semantic& semantic, AttribType aType)
162 input[inputIdx] = semantic;
163 attribType[inputIdx] = aType;
166 void VertexShader::setOutput(int outputIdx, int nbComponents, const sw::Shader::Semantic& semantic)
168 for(int i = 0; i < nbComponents; ++i)
170 output[outputIdx][i] = semantic;
174 void VertexShader::setPositionRegister(int posReg)
176 setOutput(posReg, 4, sw::Shader::Semantic(sw::Shader::USAGE_POSITION, 0));
177 positionRegister = posReg;
180 void VertexShader::setPointSizeRegister(int ptSizeReg)
182 setOutput(ptSizeReg, 4, sw::Shader::Semantic(sw::Shader::USAGE_PSIZE, 0));
183 pointSizeRegister = ptSizeReg;
186 const sw::Shader::Semantic& VertexShader::getInput(int inputIdx) const
188 return input[inputIdx];
191 VertexShader::AttribType VertexShader::getAttribType(int inputIdx) const
193 return attribType[inputIdx];
196 const sw::Shader::Semantic& VertexShader::getOutput(int outputIdx, int component) const
198 return output[outputIdx][component];
201 void VertexShader::analyze()
205 analyzeDirtyConstants();
206 analyzeTextureSampling();
207 analyzeDynamicBranching();
210 analyzeDynamicIndexing();
213 void VertexShader::analyzeInput()
215 for(unsigned int i = 0; i < instruction.size(); i++)
217 if(instruction[i]->opcode == Shader::OPCODE_DCL &&
218 instruction[i]->dst.type == Shader::PARAMETER_INPUT)
220 int index = instruction[i]->dst.index;
222 input[index] = Semantic(instruction[i]->usage, instruction[i]->usageIndex);
227 void VertexShader::analyzeOutput()
231 output[Pos][0] = Semantic(Shader::USAGE_POSITION, 0);
232 output[Pos][1] = Semantic(Shader::USAGE_POSITION, 0);
233 output[Pos][2] = Semantic(Shader::USAGE_POSITION, 0);
234 output[Pos][3] = Semantic(Shader::USAGE_POSITION, 0);
236 for(unsigned int i = 0; i < instruction.size(); i++)
238 const DestinationParameter &dst = instruction[i]->dst;
242 case Shader::PARAMETER_RASTOUT:
246 // Position already assumed written
249 output[Fog][0] = Semantic(Shader::USAGE_FOG, 0);
252 output[Pts][1] = Semantic(Shader::USAGE_PSIZE, 0);
253 pointSizeRegister = Pts;
255 default: ASSERT(false);
258 case Shader::PARAMETER_ATTROUT:
261 if(dst.x) output[C0][0] = Semantic(Shader::USAGE_COLOR, 0);
262 if(dst.y) output[C0][1] = Semantic(Shader::USAGE_COLOR, 0);
263 if(dst.z) output[C0][2] = Semantic(Shader::USAGE_COLOR, 0);
264 if(dst.w) output[C0][3] = Semantic(Shader::USAGE_COLOR, 0);
266 else if(dst.index == 1)
268 if(dst.x) output[C1][0] = Semantic(Shader::USAGE_COLOR, 1);
269 if(dst.y) output[C1][1] = Semantic(Shader::USAGE_COLOR, 1);
270 if(dst.z) output[C1][2] = Semantic(Shader::USAGE_COLOR, 1);
271 if(dst.w) output[C1][3] = Semantic(Shader::USAGE_COLOR, 1);
275 case Shader::PARAMETER_TEXCRDOUT:
276 if(dst.x) output[T0 + dst.index][0] = Semantic(Shader::USAGE_TEXCOORD, dst.index);
277 if(dst.y) output[T0 + dst.index][1] = Semantic(Shader::USAGE_TEXCOORD, dst.index);
278 if(dst.z) output[T0 + dst.index][2] = Semantic(Shader::USAGE_TEXCOORD, dst.index);
279 if(dst.w) output[T0 + dst.index][3] = Semantic(Shader::USAGE_TEXCOORD, dst.index);
286 else // Shader Model 3.0 input declaration
288 for(unsigned int i = 0; i < instruction.size(); i++)
290 if(instruction[i]->opcode == Shader::OPCODE_DCL &&
291 instruction[i]->dst.type == Shader::PARAMETER_OUTPUT)
293 unsigned char usage = instruction[i]->usage;
294 unsigned char usageIndex = instruction[i]->usageIndex;
296 const DestinationParameter &dst = instruction[i]->dst;
298 if(dst.x) output[dst.index][0] = Semantic(usage, usageIndex);
299 if(dst.y) output[dst.index][1] = Semantic(usage, usageIndex);
300 if(dst.z) output[dst.index][2] = Semantic(usage, usageIndex);
301 if(dst.w) output[dst.index][3] = Semantic(usage, usageIndex);
303 if(usage == Shader::USAGE_POSITION && usageIndex == 0)
305 positionRegister = dst.index;
308 if(usage == Shader::USAGE_PSIZE && usageIndex == 0)
310 pointSizeRegister = dst.index;
317 void VertexShader::analyzeTextureSampling()
319 textureSampling = false;
321 for(unsigned int i = 0; i < instruction.size() && !textureSampling; i++)
323 if(instruction[i]->src[1].type == PARAMETER_SAMPLER)
325 textureSampling = true;