1 // SwiftShader Software Renderer
3 // Copyright(c) 2005-2013 TransGaming Inc.
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.
12 // Shader.cpp: Implements the Shader class and its derived classes
13 // VertexShader and FragmentShader. Implements GL shader objects and related
14 // functionality. [OpenGL ES 2.0.24] section 2.10 page 24 and section 3.8 page 84.
19 #include "utilities.h"
21 #include "GLSLANG/ShaderLang.h"
27 bool Shader::compilerInitialized = false;
29 Shader::Shader(ResourceManager *manager, GLuint handle) : mHandle(handle), mResourceManager(manager)
37 mDeleteStatus = false;
46 GLuint Shader::getHandle() 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 int Shader::getInfoLogLength() const
99 return strlen(mInfoLog) + 1;
103 void Shader::getInfoLog(GLsizei bufSize, GLsizei *length, char *infoLog)
111 index = std::min(bufSize - 1, (int)strlen(mInfoLog));
112 memcpy(infoLog, mInfoLog, index);
115 infoLog[index] = '\0';
124 int 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(ShShaderType type)
159 if(!compilerInitialized)
162 compilerInitialized = true;
165 TranslatorASM *assembler = new TranslatorASM(this, type, SH_GLES2_SPEC);
167 ShBuiltInResources resources;
168 ShInitBuiltInResources(&resources);
169 resources.MaxVertexAttribs = MAX_VERTEX_ATTRIBS;
170 resources.MaxVertexUniformVectors = MAX_VERTEX_UNIFORM_VECTORS;
171 resources.MaxVaryingVectors = MAX_VARYING_VECTORS;
172 resources.MaxVertexTextureImageUnits = MAX_VERTEX_TEXTURE_IMAGE_UNITS;
173 resources.MaxCombinedTextureImageUnits = MAX_COMBINED_TEXTURE_IMAGE_UNITS;
174 resources.MaxTextureImageUnits = MAX_TEXTURE_IMAGE_UNITS;
175 resources.MaxFragmentUniformVectors = MAX_FRAGMENT_UNIFORM_VECTORS;
176 resources.MaxDrawBuffers = MAX_DRAW_BUFFERS;
177 resources.OES_standard_derivatives = 1;
178 resources.OES_fragment_precision_high = 1;
179 resources.MaxCallStackDepth = 16;
180 assembler->Init(resources);
191 activeUniforms.clear();
192 activeAttributes.clear();
195 bool Shader::isCompiled()
197 return getShader() != 0;
200 sw::PixelShader *Shader::getPixelShader() const
205 sw::VertexShader *Shader::getVertexShader() const
210 void Shader::addRef()
215 void Shader::release()
219 if(mRefCount == 0 && mDeleteStatus)
221 mResourceManager->deleteShader(mHandle);
225 unsigned int Shader::getRefCount() const
230 bool Shader::isFlaggedForDeletion() const
232 return mDeleteStatus;
235 void Shader::flagForDeletion()
237 mDeleteStatus = true;
240 void Shader::releaseCompiler()
243 compilerInitialized = false;
246 GLenum Shader::parseType(const std::string &type)
252 else if(type == "float2")
254 return GL_FLOAT_VEC2;
256 else if(type == "float3")
258 return GL_FLOAT_VEC3;
260 else if(type == "float4")
262 return GL_FLOAT_VEC4;
264 else if(type == "float2x2")
266 return GL_FLOAT_MAT2;
268 else if(type == "float3x3")
270 return GL_FLOAT_MAT3;
272 else if(type == "float4x4")
274 return GL_FLOAT_MAT4;
281 // true if varying x has a higher priority in packing than y
282 bool Shader::compareVarying(const Varying &x, const Varying &y)
286 return x.size() > y.size();
291 case GL_FLOAT_MAT4: return true;
295 case GL_FLOAT_MAT4: return false;
296 case GL_FLOAT_MAT2: return true;
297 case GL_FLOAT_VEC4: return true;
298 case GL_FLOAT_MAT3: return true;
299 case GL_FLOAT_VEC3: return true;
300 case GL_FLOAT_VEC2: return true;
301 case GL_FLOAT: return true;
302 default: UNREACHABLE();
308 case GL_FLOAT_MAT4: return false;
309 case GL_FLOAT_MAT2: return false;
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();
321 case GL_FLOAT_MAT4: return false;
322 case GL_FLOAT_MAT2: return false;
323 case GL_FLOAT_VEC4: return false;
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();
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 false;
338 case GL_FLOAT_VEC3: return true;
339 case GL_FLOAT_VEC2: return true;
340 case GL_FLOAT: return true;
341 default: UNREACHABLE();
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 false;
352 case GL_FLOAT_VEC2: return true;
353 case GL_FLOAT: return true;
354 default: UNREACHABLE();
357 case GL_FLOAT: return false;
358 default: UNREACHABLE();
364 VertexShader::VertexShader(ResourceManager *manager, GLuint handle) : Shader(manager, handle)
369 VertexShader::~VertexShader()
374 GLenum VertexShader::getType()
376 return GL_VERTEX_SHADER;
379 void VertexShader::compile()
384 vertexShader = new sw::VertexShader();
386 TranslatorASM *compiler = createCompiler(SH_VERTEX_SHADER);
388 // Ensure we don't pass a NULL source to the compiler
395 int success = ShCompile(compiler, &source, 1, SH_OBJECT_CODE);
399 static int serial = 1;
401 sprintf(buffer, "vertex-input-%d-%d.txt", getHandle(), serial);
402 FILE *file = fopen(buffer, "wt");
403 fprintf(file, mSource);
405 vertexShader->print("vertex-output-%d-%d.txt", getHandle(), serial);
415 ShGetInfo(compiler, SH_INFO_LOG_LENGTH, &infoLogLen);
416 mInfoLog = new char[infoLogLen];
417 ShGetInfoLog(compiler, mInfoLog);
418 TRACE("\n%s", mInfoLog);
424 int VertexShader::getSemanticIndex(const std::string &attributeName)
426 if(!attributeName.empty())
428 for(sh::ActiveAttributes::iterator attribute = activeAttributes.begin(); attribute != activeAttributes.end(); attribute++)
430 if(attribute->name == attributeName)
432 return attribute->registerIndex;
440 sw::Shader *VertexShader::getShader() const
445 sw::VertexShader *VertexShader::getVertexShader() const
450 FragmentShader::FragmentShader(ResourceManager *manager, GLuint handle) : Shader(manager, handle)
455 FragmentShader::~FragmentShader()
460 GLenum FragmentShader::getType()
462 return GL_FRAGMENT_SHADER;
465 void FragmentShader::compile()
470 pixelShader = new sw::PixelShader();
472 TranslatorASM *compiler = createCompiler(SH_FRAGMENT_SHADER);
474 // Ensure we don't pass a NULL source to the compiler
481 int success = ShCompile(compiler, &source, 1, SH_OBJECT_CODE);
485 static int serial = 1;
487 sprintf(buffer, "pixel-input-%d-%d.txt", getHandle(), serial);
488 FILE *file = fopen(buffer, "wt");
489 fprintf(file, mSource);
491 pixelShader->print("pixel-output-%d-%d.txt", getHandle(), serial);
501 ShGetInfo(compiler, SH_INFO_LOG_LENGTH, &infoLogLen);
502 mInfoLog = new char[infoLogLen];
503 ShGetInfoLog(compiler, mInfoLog);
504 TRACE("\n%s", mInfoLog);
510 sw::Shader *FragmentShader::getShader() const
515 sw::PixelShader *FragmentShader::getPixelShader() const