summaryrefslogtreecommitdiffstats
path: root/src/3rdparty/angle/src/libGLESv2/Shader.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/3rdparty/angle/src/libGLESv2/Shader.cpp')
-rw-r--r--src/3rdparty/angle/src/libGLESv2/Shader.cpp476
1 files changed, 44 insertions, 432 deletions
diff --git a/src/3rdparty/angle/src/libGLESv2/Shader.cpp b/src/3rdparty/angle/src/libGLESv2/Shader.cpp
index eda0298e87..e3da2b1a9e 100644
--- a/src/3rdparty/angle/src/libGLESv2/Shader.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/Shader.cpp
@@ -1,4 +1,3 @@
-#include "precompiled.h"
//
// Copyright (c) 2002-2014 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
@@ -10,27 +9,30 @@
// functionality. [OpenGL ES 2.0.24] section 2.10 page 24 and section 3.8 page 84.
#include "libGLESv2/Shader.h"
-
-#include "GLSLANG/ShaderLang.h"
-#include "common/utilities.h"
#include "libGLESv2/renderer/Renderer.h"
+#include "libGLESv2/renderer/ShaderImpl.h"
#include "libGLESv2/Constants.h"
#include "libGLESv2/ResourceManager.h"
+#include "common/utilities.h"
+
+#include "GLSLANG/ShaderLang.h"
+
+#include <sstream>
+
namespace gl
{
-void *Shader::mFragmentCompiler = NULL;
-void *Shader::mVertexCompiler = NULL;
-Shader::Shader(ResourceManager *manager, const rx::Renderer *renderer, GLuint handle)
- : mHandle(handle), mRenderer(renderer), mResourceManager(manager)
+Shader::Shader(ResourceManager *manager, rx::ShaderImpl *impl, GLenum type, GLuint handle)
+ : mShader(impl),
+ mType(type),
+ mHandle(handle),
+ mResourceManager(manager),
+ mRefCount(0),
+ mDeleteStatus(false),
+ mCompiled(false)
{
- uncompile();
- initializeCompiler();
-
- mRefCount = 0;
- mDeleteStatus = false;
- mShaderVersion = 100;
+ ASSERT(impl);
}
Shader::~Shader()
@@ -56,7 +58,7 @@ void Shader::setSource(GLsizei count, const char *const *string, const GLint *le
int Shader::getInfoLogLength() const
{
- return mInfoLog.empty() ? 0 : (mInfoLog.length() + 1);
+ return mShader->getInfoLog().empty() ? 0 : (mShader->getInfoLog().length() + 1);
}
void Shader::getInfoLog(GLsizei bufSize, GLsizei *length, char *infoLog) const
@@ -65,8 +67,8 @@ void Shader::getInfoLog(GLsizei bufSize, GLsizei *length, char *infoLog) const
if (bufSize > 0)
{
- index = std::min(bufSize - 1, static_cast<GLsizei>(mInfoLog.length()));
- memcpy(infoLog, mInfoLog.c_str(), index);
+ index = std::min(bufSize - 1, static_cast<GLsizei>(mShader->getInfoLog().length()));
+ memcpy(infoLog, mShader->getInfoLog().c_str(), index);
infoLog[index] = '\0';
}
@@ -84,10 +86,10 @@ int Shader::getSourceLength() const
int Shader::getTranslatedSourceLength() const
{
- return mHlsl.empty() ? 0 : (mHlsl.length() + 1);
+ return mShader->getTranslatedSource().empty() ? 0 : (mShader->getTranslatedSource().length() + 1);
}
-void Shader::getSourceImpl(const std::string &source, GLsizei bufSize, GLsizei *length, char *buffer) const
+void Shader::getSourceImpl(const std::string &source, GLsizei bufSize, GLsizei *length, char *buffer)
{
int index = 0;
@@ -112,44 +114,12 @@ void Shader::getSource(GLsizei bufSize, GLsizei *length, char *buffer) const
void Shader::getTranslatedSource(GLsizei bufSize, GLsizei *length, char *buffer) const
{
- getSourceImpl(mHlsl, bufSize, length, buffer);
+ getSourceImpl(mShader->getTranslatedSource(), bufSize, length, buffer);
}
-unsigned int Shader::getUniformRegister(const std::string &uniformName) const
+void Shader::compile()
{
- ASSERT(mUniformRegisterMap.count(uniformName) > 0);
- return mUniformRegisterMap.find(uniformName)->second;
-}
-
-unsigned int Shader::getInterfaceBlockRegister(const std::string &blockName) const
-{
- ASSERT(mInterfaceBlockRegisterMap.count(blockName) > 0);
- return mInterfaceBlockRegisterMap.find(blockName)->second;
-}
-
-const std::vector<sh::Uniform> &Shader::getUniforms() const
-{
- return mActiveUniforms;
-}
-
-const std::vector<sh::InterfaceBlock> &Shader::getInterfaceBlocks() const
-{
- return mActiveInterfaceBlocks;
-}
-
-std::vector<PackedVarying> &Shader::getVaryings()
-{
- return mVaryings;
-}
-
-bool Shader::isCompiled() const
-{
- return !mHlsl.empty();
-}
-
-const std::string &Shader::getHLSL() const
-{
- return mHlsl;
+ mCompiled = mShader->compile(mSource);
}
void Shader::addRef()
@@ -182,412 +152,54 @@ void Shader::flagForDeletion()
mDeleteStatus = true;
}
-// Perform a one-time initialization of the shader compiler (or after being destructed by releaseCompiler)
-void Shader::initializeCompiler()
-{
- if (!mFragmentCompiler)
- {
- int result = ShInitialize();
-
- if (result)
- {
- ShShaderOutput hlslVersion = (mRenderer->getMajorShaderModel() >= 4) ? SH_HLSL11_OUTPUT : SH_HLSL9_OUTPUT;
-
- ShBuiltInResources resources;
- ShInitBuiltInResources(&resources);
-
- // TODO(geofflang): use context's caps
- const gl::Caps &caps = mRenderer->getRendererCaps();
- const gl::Extensions &extensions = mRenderer->getRendererExtensions();
-
- resources.MaxVertexAttribs = MAX_VERTEX_ATTRIBS;
- resources.MaxVertexUniformVectors = mRenderer->getMaxVertexUniformVectors();
- resources.MaxVaryingVectors = mRenderer->getMaxVaryingVectors();
- resources.MaxVertexTextureImageUnits = mRenderer->getMaxVertexTextureImageUnits();
- resources.MaxCombinedTextureImageUnits = mRenderer->getMaxCombinedTextureImageUnits();
- resources.MaxTextureImageUnits = MAX_TEXTURE_IMAGE_UNITS;
- resources.MaxFragmentUniformVectors = mRenderer->getMaxFragmentUniformVectors();
- resources.MaxDrawBuffers = caps.maxDrawBuffers;
- resources.OES_standard_derivatives = extensions.standardDerivatives;
- resources.EXT_draw_buffers = extensions.drawBuffers;
- resources.EXT_shader_texture_lod = 1;
- // resources.OES_EGL_image_external = mRenderer->getShareHandleSupport() ? 1 : 0; // TODO: commented out until the extension is actually supported.
- resources.FragmentPrecisionHigh = 1; // Shader Model 2+ always supports FP24 (s16e7) which corresponds to highp
- resources.EXT_frag_depth = 1; // Shader Model 2+ always supports explicit depth output
- // GLSL ES 3.0 constants
- resources.MaxVertexOutputVectors = mRenderer->getMaxVaryingVectors();
- resources.MaxFragmentInputVectors = mRenderer->getMaxVaryingVectors();
- resources.MinProgramTexelOffset = -8; // D3D10_COMMONSHADER_TEXEL_OFFSET_MAX_NEGATIVE
- resources.MaxProgramTexelOffset = 7; // D3D10_COMMONSHADER_TEXEL_OFFSET_MAX_POSITIVE
-
- mFragmentCompiler = ShConstructCompiler(GL_FRAGMENT_SHADER, SH_GLES2_SPEC, hlslVersion, &resources);
- mVertexCompiler = ShConstructCompiler(GL_VERTEX_SHADER, SH_GLES2_SPEC, hlslVersion, &resources);
- }
- }
-}
-
-void Shader::releaseCompiler()
+const std::vector<gl::PackedVarying> &Shader::getVaryings() const
{
- ShDestruct(mFragmentCompiler);
- ShDestruct(mVertexCompiler);
-
- mFragmentCompiler = NULL;
- mVertexCompiler = NULL;
-
- ShFinalize();
+ return mShader->getVaryings();
}
-void Shader::parseVaryings(void *compiler)
-{
- if (!mHlsl.empty())
- {
- std::vector<sh::Varying> *activeVaryings;
- ShGetInfoPointer(compiler, SH_ACTIVE_VARYINGS_ARRAY, reinterpret_cast<void**>(&activeVaryings));
-
- for (size_t varyingIndex = 0; varyingIndex < activeVaryings->size(); varyingIndex++)
- {
- mVaryings.push_back(PackedVarying((*activeVaryings)[varyingIndex]));
- }
-
- mUsesMultipleRenderTargets = mHlsl.find("GL_USES_MRT") != std::string::npos;
- mUsesFragColor = mHlsl.find("GL_USES_FRAG_COLOR") != std::string::npos;
- mUsesFragData = mHlsl.find("GL_USES_FRAG_DATA") != std::string::npos;
- mUsesFragCoord = mHlsl.find("GL_USES_FRAG_COORD") != std::string::npos;
- mUsesFrontFacing = mHlsl.find("GL_USES_FRONT_FACING") != std::string::npos;
- mUsesPointSize = mHlsl.find("GL_USES_POINT_SIZE") != std::string::npos;
- mUsesPointCoord = mHlsl.find("GL_USES_POINT_COORD") != std::string::npos;
- mUsesDepthRange = mHlsl.find("GL_USES_DEPTH_RANGE") != std::string::npos;
- mUsesFragDepth = mHlsl.find("GL_USES_FRAG_DEPTH") != std::string::npos;
- mUsesDiscardRewriting = mHlsl.find("ANGLE_USES_DISCARD_REWRITING") != std::string::npos;
- mUsesNestedBreak = mHlsl.find("ANGLE_USES_NESTED_BREAK") != std::string::npos;
- }
-}
-
-void Shader::resetVaryingsRegisterAssignment()
-{
- for (unsigned int varyingIndex = 0; varyingIndex < mVaryings.size(); varyingIndex++)
- {
- mVaryings[varyingIndex].resetRegisterAssignment();
- }
-}
-
-// initialize/clean up previous state
-void Shader::uncompile()
-{
- // set by compileToHLSL
- mHlsl.clear();
- mInfoLog.clear();
-
- // set by parseVaryings
- mVaryings.clear();
-
- mUsesMultipleRenderTargets = false;
- mUsesFragColor = false;
- mUsesFragData = false;
- mUsesFragCoord = false;
- mUsesFrontFacing = false;
- mUsesPointSize = false;
- mUsesPointCoord = false;
- mUsesDepthRange = false;
- mUsesFragDepth = false;
- mShaderVersion = 100;
- mUsesDiscardRewriting = false;
- mUsesNestedBreak = false;
-
- mActiveUniforms.clear();
- mActiveInterfaceBlocks.clear();
-}
-
-void Shader::compileToHLSL(void *compiler)
-{
- // ensure the compiler is loaded
- initializeCompiler();
-
- int compileOptions = SH_OBJECT_CODE;
- std::string sourcePath;
- if (perfActive())
- {
- sourcePath = getTempPath();
- writeFile(sourcePath.c_str(), mSource.c_str(), mSource.length());
- compileOptions |= SH_LINE_DIRECTIVES;
- }
-
- int result;
- if (sourcePath.empty())
- {
- const char* sourceStrings[] =
- {
- mSource.c_str(),
- };
-
- result = ShCompile(compiler, sourceStrings, ArraySize(sourceStrings), compileOptions);
- }
- else
- {
- const char* sourceStrings[] =
- {
- sourcePath.c_str(),
- mSource.c_str(),
- };
-
- result = ShCompile(compiler, sourceStrings, ArraySize(sourceStrings), compileOptions | SH_SOURCE_PATH);
- }
-
- size_t shaderVersion = 100;
- ShGetInfo(compiler, SH_SHADER_VERSION, &shaderVersion);
-
- mShaderVersion = static_cast<int>(shaderVersion);
-
- if (shaderVersion == 300 && mRenderer->getCurrentClientVersion() < 3)
- {
- mInfoLog = "GLSL ES 3.00 is not supported by OpenGL ES 2.0 contexts";
- TRACE("\n%s", mInfoLog.c_str());
- }
- else if (result)
- {
- size_t objCodeLen = 0;
- ShGetInfo(compiler, SH_OBJECT_CODE_LENGTH, &objCodeLen);
-
- char* outputHLSL = new char[objCodeLen];
- ShGetObjectCode(compiler, outputHLSL);
-
-#ifdef _DEBUG
- std::ostringstream hlslStream;
- hlslStream << "// GLSL\n";
- hlslStream << "//\n";
-
- size_t curPos = 0;
- while (curPos != std::string::npos)
- {
- size_t nextLine = mSource.find("\n", curPos);
- size_t len = (nextLine == std::string::npos) ? std::string::npos : (nextLine - curPos + 1);
-
- hlslStream << "// " << mSource.substr(curPos, len);
-
- curPos = (nextLine == std::string::npos) ? std::string::npos : (nextLine + 1);
- }
- hlslStream << "\n\n";
- hlslStream << outputHLSL;
- mHlsl = hlslStream.str();
-#else
- mHlsl = outputHLSL;
-#endif
-
- delete[] outputHLSL;
-
- void *activeUniforms;
- ShGetInfoPointer(compiler, SH_ACTIVE_UNIFORMS_ARRAY, &activeUniforms);
- mActiveUniforms = *(std::vector<sh::Uniform>*)activeUniforms;
-
- for (size_t uniformIndex = 0; uniformIndex < mActiveUniforms.size(); uniformIndex++)
- {
- const sh::Uniform &uniform = mActiveUniforms[uniformIndex];
-
- unsigned int index = -1;
- bool result = ShGetUniformRegister(compiler, uniform.name.c_str(), &index);
- UNUSED_ASSERTION_VARIABLE(result);
- ASSERT(result);
-
- mUniformRegisterMap[uniform.name] = index;
- }
-
- void *activeInterfaceBlocks;
- ShGetInfoPointer(compiler, SH_ACTIVE_INTERFACE_BLOCKS_ARRAY, &activeInterfaceBlocks);
- mActiveInterfaceBlocks = *(std::vector<sh::InterfaceBlock>*)activeInterfaceBlocks;
-
- for (size_t blockIndex = 0; blockIndex < mActiveInterfaceBlocks.size(); blockIndex++)
- {
- const sh::InterfaceBlock &interfaceBlock = mActiveInterfaceBlocks[blockIndex];
-
- unsigned int index = -1;
- bool result = ShGetInterfaceBlockRegister(compiler, interfaceBlock.name.c_str(), &index);
- UNUSED_ASSERTION_VARIABLE(result);
- ASSERT(result);
-
- mInterfaceBlockRegisterMap[interfaceBlock.name] = index;
- }
- }
- else
- {
- size_t infoLogLen = 0;
- ShGetInfo(compiler, SH_INFO_LOG_LENGTH, &infoLogLen);
-
- char* infoLog = new char[infoLogLen];
- ShGetInfoLog(compiler, infoLog);
- mInfoLog = infoLog;
-
- TRACE("\n%s", mInfoLog.c_str());
- }
-}
-
-rx::D3DWorkaroundType Shader::getD3DWorkarounds() const
-{
- if (mUsesDiscardRewriting)
- {
- // ANGLE issue 486:
- // Work-around a D3D9 compiler bug that presents itself when using conditional discard, by disabling optimization
- return rx::ANGLE_D3D_WORKAROUND_SKIP_OPTIMIZATION;
- }
-
- if (mUsesNestedBreak)
- {
- // ANGLE issue 603:
- // Work-around a D3D9 compiler bug that presents itself when using break in a nested loop, by maximizing optimization
- // We want to keep the use of ANGLE_D3D_WORKAROUND_MAX_OPTIMIZATION minimal to prevent hangs, so usesDiscard takes precedence
- return rx::ANGLE_D3D_WORKAROUND_MAX_OPTIMIZATION;
- }
-
- return rx::ANGLE_D3D_WORKAROUND_NONE;
-}
-
-// true if varying x has a higher priority in packing than y
-bool Shader::compareVarying(const PackedVarying &x, const PackedVarying &y)
-{
- if (x.type == y.type)
- {
- return x.arraySize > y.arraySize;
- }
-
- // Special case for handling structs: we sort these to the end of the list
- if (x.type == GL_STRUCT_ANGLEX)
- {
- return false;
- }
-
- if (y.type == GL_STRUCT_ANGLEX)
- {
- return true;
- }
-
- return gl::VariableSortOrder(x.type) <= gl::VariableSortOrder(y.type);
-}
-
-int Shader::getShaderVersion() const
-{
- return mShaderVersion;
-}
-
-VertexShader::VertexShader(ResourceManager *manager, const rx::Renderer *renderer, GLuint handle)
- : Shader(manager, renderer, handle)
-{
-}
-
-VertexShader::~VertexShader()
-{
-}
-
-GLenum VertexShader::getType() const
-{
- return GL_VERTEX_SHADER;
-}
-
-void VertexShader::uncompile()
-{
- Shader::uncompile();
-
- // set by ParseAttributes
- mActiveAttributes.clear();
-}
-
-void VertexShader::compile()
-{
- uncompile();
-
- compileToHLSL(mVertexCompiler);
- parseAttributes();
- parseVaryings(mVertexCompiler);
-}
-
-int VertexShader::getSemanticIndex(const std::string &attributeName)
+const std::vector<sh::Uniform> &Shader::getUniforms() const
{
- if (!attributeName.empty())
- {
- int semanticIndex = 0;
- for (unsigned int attributeIndex = 0; attributeIndex < mActiveAttributes.size(); attributeIndex++)
- {
- const sh::ShaderVariable &attribute = mActiveAttributes[attributeIndex];
-
- if (attribute.name == attributeName)
- {
- return semanticIndex;
- }
-
- semanticIndex += VariableRegisterCount(attribute.type);
- }
- }
-
- return -1;
+ return mShader->getUniforms();
}
-void VertexShader::parseAttributes()
+const std::vector<sh::InterfaceBlock> &Shader::getInterfaceBlocks() const
{
- const std::string &hlsl = getHLSL();
- if (!hlsl.empty())
- {
- void *activeAttributes;
- ShGetInfoPointer(mVertexCompiler, SH_ACTIVE_ATTRIBUTES_ARRAY, &activeAttributes);
- mActiveAttributes = *(std::vector<sh::Attribute>*)activeAttributes;
- }
+ return mShader->getInterfaceBlocks();
}
-FragmentShader::FragmentShader(ResourceManager *manager, const rx::Renderer *renderer, GLuint handle)
- : Shader(manager, renderer, handle)
+const std::vector<sh::Attribute> &Shader::getActiveAttributes() const
{
+ return mShader->getActiveAttributes();
}
-FragmentShader::~FragmentShader()
+const std::vector<sh::Attribute> &Shader::getActiveOutputVariables() const
{
+ return mShader->getActiveOutputVariables();
}
-GLenum FragmentShader::getType() const
+std::vector<gl::PackedVarying> &Shader::getVaryings()
{
- return GL_FRAGMENT_SHADER;
+ return mShader->getVaryings();
}
-void FragmentShader::compile()
+std::vector<sh::Uniform> &Shader::getUniforms()
{
- uncompile();
-
- compileToHLSL(mFragmentCompiler);
- parseVaryings(mFragmentCompiler);
- std::sort(mVaryings.begin(), mVaryings.end(), compareVarying);
-
- const std::string &hlsl = getHLSL();
- if (!hlsl.empty())
- {
- void *activeOutputVariables;
- ShGetInfoPointer(mFragmentCompiler, SH_ACTIVE_OUTPUT_VARIABLES_ARRAY, &activeOutputVariables);
- mActiveOutputVariables = *(std::vector<sh::Attribute>*)activeOutputVariables;
- }
+ return mShader->getUniforms();
}
-void FragmentShader::uncompile()
+std::vector<sh::InterfaceBlock> &Shader::getInterfaceBlocks()
{
- Shader::uncompile();
-
- mActiveOutputVariables.clear();
+ return mShader->getInterfaceBlocks();
}
-const std::vector<sh::Attribute> &FragmentShader::getOutputVariables() const
+std::vector<sh::Attribute> &Shader::getActiveAttributes()
{
- return mActiveOutputVariables;
+ return mShader->getActiveAttributes();
}
-ShShaderOutput Shader::getCompilerOutputType(GLenum shader)
+std::vector<sh::Attribute> &Shader::getActiveOutputVariables()
{
- void *compiler = NULL;
-
- switch (shader)
- {
- case GL_VERTEX_SHADER: compiler = mVertexCompiler; break;
- case GL_FRAGMENT_SHADER: compiler = mFragmentCompiler; break;
- default: UNREACHABLE(); return SH_HLSL9_OUTPUT;
- }
-
- size_t outputType = 0;
- ShGetInfo(compiler, SH_OUTPUT_TYPE, &outputType);
-
- return static_cast<ShShaderOutput>(outputType);
+ return mShader->getActiveOutputVariables();
}
}