diff options
Diffstat (limited to 'src/3rdparty/angle/src/libGLESv2/Shader.cpp')
-rw-r--r-- | src/3rdparty/angle/src/libGLESv2/Shader.cpp | 476 |
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(); } } |