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 // Shader.cpp: Implements the Shader class and its derived classes
16 // VertexShader and FragmentShader. Implements GL shader objects and related
17 // functionality. [OpenGL ES 2.0.24] section 2.10 page 24 and section 3.8 page 84.
22 #include "utilities.h"
29 bool Shader::compilerInitialized = false;
31 Shader::Shader(ResourceManager *manager, GLuint handle) : mHandle(handle), mResourceManager(manager)
38 mDeleteStatus = false;
46 GLuint Shader::getName() const
51 void Shader::setSource(GLsizei count, const char *const *string, const GLint *length)
56 for(int i = 0; i < count; i++)
58 if(length && length[i] >= 0)
60 totalLength += length[i];
64 totalLength += (int)strlen(string[i]);
68 mSource = new char[totalLength + 1];
71 for(int i = 0; i < count; i++)
75 if(length && length[i] >= 0)
77 stringLength = length[i];
81 stringLength = (int)strlen(string[i]);
84 strncpy(code, string[i], stringLength);
88 mSource[totalLength] = '\0';
91 size_t Shader::getInfoLogLength() const
99 return infoLog.size() + 1;
103 void Shader::getInfoLog(GLsizei bufSize, GLsizei *length, char *infoLogOut)
111 index = std::min(bufSize - 1, (GLsizei)infoLog.size());
112 memcpy(infoLogOut, infoLog.c_str(), index);
115 infoLogOut[index] = '\0';
124 size_t Shader::getSourceLength() const
132 return strlen(mSource) + 1;
136 void Shader::getSource(GLsizei bufSize, GLsizei *length, char *source)
144 index = std::min(bufSize - 1, (int)strlen(mSource));
145 memcpy(source, mSource, index);
148 source[index] = '\0';
157 TranslatorASM *Shader::createCompiler(GLenum shaderType)
159 if(!compilerInitialized)
161 InitCompilerGlobals();
162 compilerInitialized = true;
165 TranslatorASM *assembler = new TranslatorASM(this, shaderType);
167 ShBuiltInResources resources;
168 resources.MaxVertexAttribs = MAX_VERTEX_ATTRIBS;
169 resources.MaxVertexUniformVectors = MAX_VERTEX_UNIFORM_VECTORS;
170 resources.MaxVaryingVectors = MAX_VARYING_VECTORS;
171 resources.MaxVertexTextureImageUnits = MAX_VERTEX_TEXTURE_IMAGE_UNITS;
172 resources.MaxCombinedTextureImageUnits = MAX_COMBINED_TEXTURE_IMAGE_UNITS;
173 resources.MaxTextureImageUnits = MAX_TEXTURE_IMAGE_UNITS;
174 resources.MaxFragmentUniformVectors = MAX_FRAGMENT_UNIFORM_VECTORS;
175 resources.MaxDrawBuffers = MAX_DRAW_BUFFERS;
176 resources.MaxVertexOutputVectors = MAX_VERTEX_OUTPUT_VECTORS;
177 resources.MaxFragmentInputVectors = MAX_FRAGMENT_INPUT_VECTORS;
178 resources.MinProgramTexelOffset = MIN_PROGRAM_TEXEL_OFFSET;
179 resources.MaxProgramTexelOffset = MAX_PROGRAM_TEXEL_OFFSET;
180 resources.OES_standard_derivatives = 1;
181 resources.OES_fragment_precision_high = 1;
182 resources.OES_EGL_image_external = 1;
183 resources.EXT_draw_buffers = 1;
184 resources.MaxCallStackDepth = 16;
185 assembler->Init(resources);
195 activeUniforms.clear();
196 activeAttributes.clear();
199 void Shader::compile()
204 TranslatorASM *compiler = createCompiler(getType());
206 // Ensure we don't pass a nullptr source to the compiler
207 const char *source = "\0";
213 bool success = compiler->compile(&source, 1, SH_OBJECT_CODE);
217 static int serial = 1;
222 sprintf(buffer, "shader-input-%d-%d.txt", getName(), serial);
223 FILE *file = fopen(buffer, "wt");
224 fprintf(file, "%s", mSource);
228 getShader()->print("shader-output-%d-%d.txt", getName(), serial);
233 int shaderVersion = compiler->getShaderVersion();
234 int clientVersion = es2::getContext()->getClientVersion();
236 if(shaderVersion >= 300 && clientVersion < 3)
238 infoLog = "GLSL ES 3.00 is not supported by OpenGL ES 2.0 contexts";
246 infoLog += compiler->getInfoSink().info.c_str();
247 TRACE("\n%s", infoLog.c_str());
253 bool Shader::isCompiled()
255 return getShader() != 0;
258 void Shader::addRef()
263 void Shader::release()
267 if(mRefCount == 0 && mDeleteStatus)
269 mResourceManager->deleteShader(mHandle);
273 unsigned int Shader::getRefCount() const
278 bool Shader::isFlaggedForDeletion() const
280 return mDeleteStatus;
283 void Shader::flagForDeletion()
285 mDeleteStatus = true;
288 void Shader::releaseCompiler()
290 FreeCompilerGlobals();
291 compilerInitialized = false;
294 // true if varying x has a higher priority in packing than y
295 bool Shader::compareVarying(const glsl::Varying &x, const glsl::Varying &y)
299 return x.size() > y.size();
304 case GL_FLOAT_MAT4: return true;
308 case GL_FLOAT_MAT4: return false;
309 case GL_FLOAT_MAT2: return true;
310 case GL_FLOAT_VEC4: return true;
311 case GL_FLOAT_MAT3: return true;
312 case GL_FLOAT_VEC3: return true;
313 case GL_FLOAT_VEC2: return true;
314 case GL_FLOAT: return true;
315 default: UNREACHABLE(y.type);
321 case GL_FLOAT_MAT4: return false;
322 case GL_FLOAT_MAT2: return false;
323 case GL_FLOAT_VEC4: return true;
324 case GL_FLOAT_MAT3: return true;
325 case GL_FLOAT_VEC3: return true;
326 case GL_FLOAT_VEC2: return true;
327 case GL_FLOAT: return true;
328 default: UNREACHABLE(y.type);
334 case GL_FLOAT_MAT4: return false;
335 case GL_FLOAT_MAT2: return false;
336 case GL_FLOAT_VEC4: return false;
337 case GL_FLOAT_MAT3: return true;
338 case GL_FLOAT_VEC3: return true;
339 case GL_FLOAT_VEC2: return true;
340 case GL_FLOAT: return true;
341 default: UNREACHABLE(y.type);
347 case GL_FLOAT_MAT4: return false;
348 case GL_FLOAT_MAT2: return false;
349 case GL_FLOAT_VEC4: return false;
350 case GL_FLOAT_MAT3: return false;
351 case GL_FLOAT_VEC3: return true;
352 case GL_FLOAT_VEC2: return true;
353 case GL_FLOAT: return true;
354 default: UNREACHABLE(y.type);
360 case GL_FLOAT_MAT4: return false;
361 case GL_FLOAT_MAT2: return false;
362 case GL_FLOAT_VEC4: return false;
363 case GL_FLOAT_MAT3: return false;
364 case GL_FLOAT_VEC3: return false;
365 case GL_FLOAT_VEC2: return true;
366 case GL_FLOAT: return true;
367 default: UNREACHABLE(y.type);
370 case GL_FLOAT: return false;
371 default: UNREACHABLE(x.type);
377 VertexShader::VertexShader(ResourceManager *manager, GLuint handle) : Shader(manager, handle)
382 VertexShader::~VertexShader()
387 GLenum VertexShader::getType() const
389 return GL_VERTEX_SHADER;
392 int VertexShader::getSemanticIndex(const std::string &attributeName)
394 if(!attributeName.empty())
396 for(glsl::ActiveAttributes::iterator attribute = activeAttributes.begin(); attribute != activeAttributes.end(); attribute++)
398 if(attribute->name == attributeName)
400 return attribute->registerIndex;
408 sw::Shader *VertexShader::getShader() const
413 sw::VertexShader *VertexShader::getVertexShader() const
418 void VertexShader::createShader()
421 vertexShader = new sw::VertexShader();
424 void VertexShader::deleteShader()
427 vertexShader = nullptr;
430 FragmentShader::FragmentShader(ResourceManager *manager, GLuint handle) : Shader(manager, handle)
435 FragmentShader::~FragmentShader()
440 GLenum FragmentShader::getType() const
442 return GL_FRAGMENT_SHADER;
445 sw::Shader *FragmentShader::getShader() const
450 sw::PixelShader *FragmentShader::getPixelShader() const
455 void FragmentShader::createShader()
458 pixelShader = new sw::PixelShader();
461 void FragmentShader::deleteShader()
464 pixelShader = nullptr;