diff options
Diffstat (limited to 'src/3rdparty/angle/src/libANGLE/Shader.cpp')
-rw-r--r-- | src/3rdparty/angle/src/libANGLE/Shader.cpp | 279 |
1 files changed, 223 insertions, 56 deletions
diff --git a/src/3rdparty/angle/src/libANGLE/Shader.cpp b/src/3rdparty/angle/src/libANGLE/Shader.cpp index 7af4ff358d..bbe9077fc9 100644 --- a/src/3rdparty/angle/src/libANGLE/Shader.cpp +++ b/src/3rdparty/angle/src/libANGLE/Shader.cpp @@ -9,35 +9,108 @@ // functionality. [OpenGL ES 2.0.24] section 2.10 page 24 and section 3.8 page 84. #include "libANGLE/Shader.h" + +#include <sstream> + +#include "common/utilities.h" +#include "GLSLANG/ShaderLang.h" +#include "libANGLE/Compiler.h" +#include "libANGLE/Constants.h" #include "libANGLE/renderer/Renderer.h" #include "libANGLE/renderer/ShaderImpl.h" -#include "libANGLE/Constants.h" #include "libANGLE/ResourceManager.h" -#include "common/utilities.h" +namespace gl +{ -#include "GLSLANG/ShaderLang.h" +namespace +{ +template <typename VarT> +std::vector<VarT> GetActiveShaderVariables(const std::vector<VarT> *variableList) +{ + ASSERT(variableList); + std::vector<VarT> result; + for (size_t varIndex = 0; varIndex < variableList->size(); varIndex++) + { + const VarT &var = variableList->at(varIndex); + if (var.staticUse) + { + result.push_back(var); + } + } + return result; +} -#include <sstream> +template <typename VarT> +const std::vector<VarT> &GetShaderVariables(const std::vector<VarT> *variableList) +{ + ASSERT(variableList); + return *variableList; +} -namespace gl +} // anonymous namespace + +// true if varying x has a higher priority in packing than y +bool CompareShaderVar(const sh::ShaderVariable &x, const sh::ShaderVariable &y) { + if (x.type == y.type) + { + return x.arraySize > y.arraySize; + } -Shader::Shader(ResourceManager *manager, rx::ShaderImpl *impl, GLenum type, GLuint handle) - : mShader(impl), - mType(type), + // 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); +} + +Shader::Data::Data(GLenum shaderType) : mLabel(), mShaderType(shaderType), mShaderVersion(100) +{ +} + +Shader::Data::~Data() +{ +} + +Shader::Shader(ResourceManager *manager, + rx::ImplFactory *implFactory, + const gl::Limitations &rendererLimitations, + GLenum type, + GLuint handle) + : mData(type), + mImplementation(implFactory->createShader(mData)), + mRendererLimitations(rendererLimitations), mHandle(handle), - mResourceManager(manager), + mType(type), mRefCount(0), mDeleteStatus(false), - mCompiled(false) + mCompiled(false), + mResourceManager(manager) { - ASSERT(impl); + ASSERT(mImplementation); } Shader::~Shader() { - SafeDelete(mShader); + SafeDelete(mImplementation); +} + +void Shader::setLabel(const std::string &label) +{ + mData.mLabel = label; +} + +const std::string &Shader::getLabel() const +{ + return mData.mLabel; } GLuint Shader::getHandle() const @@ -61,12 +134,17 @@ void Shader::setSource(GLsizei count, const char *const *string, const GLint *le } } - mSource = stream.str(); + mData.mSource = stream.str(); } int Shader::getInfoLogLength() const { - return mShader->getInfoLog().empty() ? 0 : (mShader->getInfoLog().length() + 1); + if (mInfoLog.empty()) + { + return 0; + } + + return (static_cast<int>(mInfoLog.length()) + 1); } void Shader::getInfoLog(GLsizei bufSize, GLsizei *length, char *infoLog) const @@ -75,8 +153,8 @@ void Shader::getInfoLog(GLsizei bufSize, GLsizei *length, char *infoLog) const if (bufSize > 0) { - index = std::min(bufSize - 1, static_cast<GLsizei>(mShader->getInfoLog().length())); - memcpy(infoLog, mShader->getInfoLog().c_str(), index); + index = std::min(bufSize - 1, static_cast<GLsizei>(mInfoLog.length())); + memcpy(infoLog, mInfoLog.c_str(), index); infoLog[index] = '\0'; } @@ -89,12 +167,28 @@ void Shader::getInfoLog(GLsizei bufSize, GLsizei *length, char *infoLog) const int Shader::getSourceLength() const { - return mSource.empty() ? 0 : (mSource.length() + 1); + return mData.mSource.empty() ? 0 : (static_cast<int>(mData.mSource.length()) + 1); } int Shader::getTranslatedSourceLength() const { - return mShader->getTranslatedSource().empty() ? 0 : (mShader->getTranslatedSource().length() + 1); + if (mData.mTranslatedSource.empty()) + { + return 0; + } + + return (static_cast<int>(mData.mTranslatedSource.length()) + 1); +} + +int Shader::getTranslatedSourceWithDebugInfoLength() const +{ + const std::string &debugInfo = mImplementation->getDebugInfo(); + if (debugInfo.empty()) + { + return 0; + } + + return (static_cast<int>(debugInfo.length()) + 1); } void Shader::getSourceImpl(const std::string &source, GLsizei bufSize, GLsizei *length, char *buffer) @@ -117,23 +211,117 @@ void Shader::getSourceImpl(const std::string &source, GLsizei bufSize, GLsizei * void Shader::getSource(GLsizei bufSize, GLsizei *length, char *buffer) const { - getSourceImpl(mSource, bufSize, length, buffer); + getSourceImpl(mData.mSource, bufSize, length, buffer); } void Shader::getTranslatedSource(GLsizei bufSize, GLsizei *length, char *buffer) const { - getSourceImpl(mShader->getTranslatedSource(), bufSize, length, buffer); + getSourceImpl(mData.mTranslatedSource, bufSize, length, buffer); } void Shader::getTranslatedSourceWithDebugInfo(GLsizei bufSize, GLsizei *length, char *buffer) const { - std::string debugInfo(mShader->getDebugInfo()); + const std::string &debugInfo = mImplementation->getDebugInfo(); getSourceImpl(debugInfo, bufSize, length, buffer); } void Shader::compile(Compiler *compiler) { - mCompiled = mShader->compile(compiler, mSource); + mData.mTranslatedSource.clear(); + mInfoLog.clear(); + mData.mShaderVersion = 100; + mData.mVaryings.clear(); + mData.mUniforms.clear(); + mData.mInterfaceBlocks.clear(); + mData.mActiveAttributes.clear(); + mData.mActiveOutputVariables.clear(); + + ShHandle compilerHandle = compiler->getCompilerHandle(mData.mShaderType); + + std::stringstream sourceStream; + + std::string sourcePath; + int additionalOptions = + mImplementation->prepareSourceAndReturnOptions(&sourceStream, &sourcePath); + int compileOptions = (SH_OBJECT_CODE | SH_VARIABLES | additionalOptions); + + // Some targets (eg D3D11 Feature Level 9_3 and below) do not support non-constant loop indexes + // in fragment shaders. Shader compilation will fail. To provide a better error message we can + // instruct the compiler to pre-validate. + if (mRendererLimitations.shadersRequireIndexedLoopValidation) + { + compileOptions |= SH_VALIDATE_LOOP_INDEXING; + } + + std::string sourceString = sourceStream.str(); + std::vector<const char *> sourceCStrings; + + if (!sourcePath.empty()) + { + sourceCStrings.push_back(sourcePath.c_str()); + } + + sourceCStrings.push_back(sourceString.c_str()); + + bool result = + ShCompile(compilerHandle, &sourceCStrings[0], sourceCStrings.size(), compileOptions); + + if (!result) + { + mInfoLog = ShGetInfoLog(compilerHandle); + TRACE("\n%s", mInfoLog.c_str()); + mCompiled = false; + return; + } + + mData.mTranslatedSource = ShGetObjectCode(compilerHandle); + +#ifndef NDEBUG + // Prefix translated shader with commented out un-translated shader. + // Useful in diagnostics tools which capture the shader source. + std::ostringstream shaderStream; + shaderStream << "// GLSL\n"; + shaderStream << "//\n"; + + size_t curPos = 0; + while (curPos != std::string::npos) + { + size_t nextLine = mData.mSource.find("\n", curPos); + size_t len = (nextLine == std::string::npos) ? std::string::npos : (nextLine - curPos + 1); + + shaderStream << "// " << mData.mSource.substr(curPos, len); + + curPos = (nextLine == std::string::npos) ? std::string::npos : (nextLine + 1); + } + shaderStream << "\n\n"; + shaderStream << mData.mTranslatedSource; + mData.mTranslatedSource = shaderStream.str(); +#endif + + // Gather the shader information + mData.mShaderVersion = ShGetShaderVersion(compilerHandle); + + mData.mVaryings = GetShaderVariables(ShGetVaryings(compilerHandle)); + mData.mUniforms = GetShaderVariables(ShGetUniforms(compilerHandle)); + mData.mInterfaceBlocks = GetShaderVariables(ShGetInterfaceBlocks(compilerHandle)); + + if (mData.mShaderType == GL_VERTEX_SHADER) + { + mData.mActiveAttributes = GetActiveShaderVariables(ShGetAttributes(compilerHandle)); + } + else + { + ASSERT(mData.mShaderType == GL_FRAGMENT_SHADER); + + // TODO(jmadill): Figure out why we only sort in the FS, and if we need to. + std::sort(mData.mVaryings.begin(), mData.mVaryings.end(), CompareShaderVar); + mData.mActiveOutputVariables = + GetActiveShaderVariables(ShGetOutputVariables(compilerHandle)); + } + + ASSERT(!mData.mTranslatedSource.empty()); + + mCompiled = mImplementation->postTranslateCompile(compiler, &mInfoLog); } void Shader::addRef() @@ -166,62 +354,41 @@ void Shader::flagForDeletion() mDeleteStatus = true; } -const std::vector<gl::PackedVarying> &Shader::getVaryings() const -{ - return mShader->getVaryings(); -} - -const std::vector<sh::Uniform> &Shader::getUniforms() const -{ - return mShader->getUniforms(); -} - -const std::vector<sh::InterfaceBlock> &Shader::getInterfaceBlocks() const +int Shader::getShaderVersion() const { - return mShader->getInterfaceBlocks(); + return mData.mShaderVersion; } -const std::vector<sh::Attribute> &Shader::getActiveAttributes() const +const std::vector<sh::Varying> &Shader::getVaryings() const { - return mShader->getActiveAttributes(); + return mData.getVaryings(); } -const std::vector<sh::Attribute> &Shader::getActiveOutputVariables() const -{ - return mShader->getActiveOutputVariables(); -} - -std::vector<gl::PackedVarying> &Shader::getVaryings() -{ - return mShader->getVaryings(); -} - -std::vector<sh::Uniform> &Shader::getUniforms() +const std::vector<sh::Uniform> &Shader::getUniforms() const { - return mShader->getUniforms(); + return mData.getUniforms(); } -std::vector<sh::InterfaceBlock> &Shader::getInterfaceBlocks() +const std::vector<sh::InterfaceBlock> &Shader::getInterfaceBlocks() const { - return mShader->getInterfaceBlocks(); + return mData.getInterfaceBlocks(); } -std::vector<sh::Attribute> &Shader::getActiveAttributes() +const std::vector<sh::Attribute> &Shader::getActiveAttributes() const { - return mShader->getActiveAttributes(); + return mData.getActiveAttributes(); } -std::vector<sh::Attribute> &Shader::getActiveOutputVariables() +const std::vector<sh::OutputVariable> &Shader::getActiveOutputVariables() const { - return mShader->getActiveOutputVariables(); + return mData.getActiveOutputVariables(); } - int Shader::getSemanticIndex(const std::string &attributeName) const { if (!attributeName.empty()) { - const auto &activeAttributes = mShader->getActiveAttributes(); + const auto &activeAttributes = mData.getActiveAttributes(); int semanticIndex = 0; for (size_t attributeIndex = 0; attributeIndex < activeAttributes.size(); attributeIndex++) |