From 0a7aebadfbb3534284546aa3ca8612314c08f136 Mon Sep 17 00:00:00 2001 From: Miguel Costa Date: Tue, 26 Jun 2018 16:56:45 +0200 Subject: Update ANGLE to chromium/3280 Change-Id: I0802c0d7486f772d361f87a544d6c5af937f4ca1 Reviewed-by: Friedemann Kleint --- src/3rdparty/angle/src/libANGLE/Shader.cpp | 373 ++++++++++++++++++++--------- 1 file changed, 262 insertions(+), 111 deletions(-) (limited to 'src/3rdparty/angle/src/libANGLE/Shader.cpp') diff --git a/src/3rdparty/angle/src/libANGLE/Shader.cpp b/src/3rdparty/angle/src/libANGLE/Shader.cpp index bbe9077fc9..94c4f3c705 100644 --- a/src/3rdparty/angle/src/libANGLE/Shader.cpp +++ b/src/3rdparty/angle/src/libANGLE/Shader.cpp @@ -14,11 +14,13 @@ #include "common/utilities.h" #include "GLSLANG/ShaderLang.h" +#include "libANGLE/Caps.h" #include "libANGLE/Compiler.h" #include "libANGLE/Constants.h" -#include "libANGLE/renderer/Renderer.h" +#include "libANGLE/renderer/GLImplFactory.h" #include "libANGLE/renderer/ShaderImpl.h" #include "libANGLE/ResourceManager.h" +#include "libANGLE/Context.h" namespace gl { @@ -55,16 +57,16 @@ bool CompareShaderVar(const sh::ShaderVariable &x, const sh::ShaderVariable &y) { if (x.type == y.type) { - return x.arraySize > y.arraySize; + return x.getArraySizeProduct() > y.getArraySizeProduct(); } // Special case for handling structs: we sort these to the end of the list - if (x.type == GL_STRUCT_ANGLEX) + if (x.type == GL_NONE) { return false; } - if (y.type == GL_STRUCT_ANGLEX) + if (y.type == GL_NONE) { return true; } @@ -72,45 +74,61 @@ bool CompareShaderVar(const sh::ShaderVariable &x, const sh::ShaderVariable &y) return gl::VariableSortOrder(x.type) < gl::VariableSortOrder(y.type); } -Shader::Data::Data(GLenum shaderType) : mLabel(), mShaderType(shaderType), mShaderVersion(100) +ShaderState::ShaderState(GLenum shaderType) + : mLabel(), + mShaderType(shaderType), + mShaderVersion(100), + mNumViews(-1), + mGeometryShaderInputPrimitiveType(GL_INVALID_VALUE), + mGeometryShaderOutputPrimitiveType(GL_INVALID_VALUE), + mGeometryShaderInvocations(1), + mGeometryShaderMaxVertices(-1), + mCompileStatus(CompileStatus::NOT_COMPILED) { + mLocalSize.fill(-1); } -Shader::Data::~Data() +ShaderState::~ShaderState() { } -Shader::Shader(ResourceManager *manager, - rx::ImplFactory *implFactory, +Shader::Shader(ShaderProgramManager *manager, + rx::GLImplFactory *implFactory, const gl::Limitations &rendererLimitations, GLenum type, GLuint handle) - : mData(type), - mImplementation(implFactory->createShader(mData)), + : mState(type), + mImplementation(implFactory->createShader(mState)), mRendererLimitations(rendererLimitations), mHandle(handle), mType(type), mRefCount(0), mDeleteStatus(false), - mCompiled(false), mResourceManager(manager) { ASSERT(mImplementation); } +void Shader::onDestroy(const gl::Context *context) +{ + mBoundCompiler.set(context, nullptr); + mImplementation.reset(nullptr); + delete this; +} + Shader::~Shader() { - SafeDelete(mImplementation); + ASSERT(!mImplementation); } void Shader::setLabel(const std::string &label) { - mData.mLabel = label; + mState.mLabel = label; } const std::string &Shader::getLabel() const { - return mData.mLabel; + return mState.mLabel; } GLuint Shader::getHandle() const @@ -134,11 +152,12 @@ void Shader::setSource(GLsizei count, const char *const *string, const GLint *le } } - mData.mSource = stream.str(); + mState.mSource = stream.str(); } -int Shader::getInfoLogLength() const +int Shader::getInfoLogLength(const Context *context) { + resolveCompile(context); if (mInfoLog.empty()) { return 0; @@ -147,8 +166,10 @@ int Shader::getInfoLogLength() const return (static_cast(mInfoLog.length()) + 1); } -void Shader::getInfoLog(GLsizei bufSize, GLsizei *length, char *infoLog) const +void Shader::getInfoLog(const Context *context, GLsizei bufSize, GLsizei *length, char *infoLog) { + resolveCompile(context); + int index = 0; if (bufSize > 0) @@ -167,21 +188,25 @@ void Shader::getInfoLog(GLsizei bufSize, GLsizei *length, char *infoLog) const int Shader::getSourceLength() const { - return mData.mSource.empty() ? 0 : (static_cast(mData.mSource.length()) + 1); + return mState.mSource.empty() ? 0 : (static_cast(mState.mSource.length()) + 1); } -int Shader::getTranslatedSourceLength() const +int Shader::getTranslatedSourceLength(const Context *context) { - if (mData.mTranslatedSource.empty()) + resolveCompile(context); + + if (mState.mTranslatedSource.empty()) { return 0; } - return (static_cast(mData.mTranslatedSource.length()) + 1); + return (static_cast(mState.mTranslatedSource.length()) + 1); } -int Shader::getTranslatedSourceWithDebugInfoLength() const +int Shader::getTranslatedSourceWithDebugInfoLength(const Context *context) { + resolveCompile(context); + const std::string &debugInfo = mImplementation->getDebugInfo(); if (debugInfo.empty()) { @@ -191,7 +216,11 @@ int Shader::getTranslatedSourceWithDebugInfoLength() const return (static_cast(debugInfo.length()) + 1); } -void Shader::getSourceImpl(const std::string &source, GLsizei bufSize, GLsizei *length, char *buffer) +// static +void Shader::GetSourceImpl(const std::string &source, + GLsizei bufSize, + GLsizei *length, + char *buffer) { int index = 0; @@ -211,117 +240,186 @@ void Shader::getSourceImpl(const std::string &source, GLsizei bufSize, GLsizei * void Shader::getSource(GLsizei bufSize, GLsizei *length, char *buffer) const { - getSourceImpl(mData.mSource, bufSize, length, buffer); + GetSourceImpl(mState.mSource, bufSize, length, buffer); +} + +void Shader::getTranslatedSource(const Context *context, + GLsizei bufSize, + GLsizei *length, + char *buffer) +{ + GetSourceImpl(getTranslatedSource(context), bufSize, length, buffer); } -void Shader::getTranslatedSource(GLsizei bufSize, GLsizei *length, char *buffer) const +const std::string &Shader::getTranslatedSource(const Context *context) { - getSourceImpl(mData.mTranslatedSource, bufSize, length, buffer); + resolveCompile(context); + return mState.mTranslatedSource; } -void Shader::getTranslatedSourceWithDebugInfo(GLsizei bufSize, GLsizei *length, char *buffer) const +void Shader::getTranslatedSourceWithDebugInfo(const Context *context, + GLsizei bufSize, + GLsizei *length, + char *buffer) { + resolveCompile(context); const std::string &debugInfo = mImplementation->getDebugInfo(); - getSourceImpl(debugInfo, bufSize, length, buffer); + GetSourceImpl(debugInfo, bufSize, length, buffer); } -void Shader::compile(Compiler *compiler) +void Shader::compile(const Context *context) { - mData.mTranslatedSource.clear(); + mState.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); + mState.mShaderVersion = 100; + mState.mInputVaryings.clear(); + mState.mOutputVaryings.clear(); + mState.mUniforms.clear(); + mState.mUniformBlocks.clear(); + mState.mShaderStorageBlocks.clear(); + mState.mActiveAttributes.clear(); + mState.mActiveOutputVariables.clear(); + mState.mNumViews = -1; + mState.mGeometryShaderInputPrimitiveType = GL_INVALID_VALUE; + mState.mGeometryShaderOutputPrimitiveType = GL_INVALID_VALUE; + mState.mGeometryShaderInvocations = 1; + mState.mGeometryShaderMaxVertices = -1; + + mState.mCompileStatus = CompileStatus::COMPILE_REQUESTED; + mBoundCompiler.set(context, context->getCompiler()); + + // Cache the compile source and options for compilation. Must be done now, since the source + // can change before the link call or another call that resolves the compile. std::stringstream sourceStream; - std::string sourcePath; - int additionalOptions = - mImplementation->prepareSourceAndReturnOptions(&sourceStream, &sourcePath); - int compileOptions = (SH_OBJECT_CODE | SH_VARIABLES | additionalOptions); + mLastCompileOptions = + mImplementation->prepareSourceAndReturnOptions(&sourceStream, &mLastCompiledSourcePath); + mLastCompileOptions |= (SH_OBJECT_CODE | SH_VARIABLES); + mLastCompiledSource = sourceStream.str(); + + // Add default options to WebGL shaders to prevent unexpected behavior during compilation. + if (context->getExtensions().webglCompatibility) + { + mLastCompileOptions |= SH_INIT_GL_POSITION; + mLastCompileOptions |= SH_LIMIT_CALL_STACK_DEPTH; + mLastCompileOptions |= SH_LIMIT_EXPRESSION_COMPLEXITY; + mLastCompileOptions |= SH_ENFORCE_PACKING_RESTRICTIONS; + } // 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; + mLastCompileOptions |= SH_VALIDATE_LOOP_INDEXING; } +} - std::string sourceString = sourceStream.str(); - std::vector sourceCStrings; - - if (!sourcePath.empty()) +void Shader::resolveCompile(const Context *context) +{ + if (!mState.compilePending()) { - sourceCStrings.push_back(sourcePath.c_str()); + return; } - sourceCStrings.push_back(sourceString.c_str()); + ASSERT(mBoundCompiler.get()); + ShHandle compilerHandle = mBoundCompiler->getCompilerHandle(mState.mShaderType); + + std::vector srcStrings; + + if (!mLastCompiledSourcePath.empty()) + { + srcStrings.push_back(mLastCompiledSourcePath.c_str()); + } - bool result = - ShCompile(compilerHandle, &sourceCStrings[0], sourceCStrings.size(), compileOptions); + srcStrings.push_back(mLastCompiledSource.c_str()); - if (!result) + if (!sh::Compile(compilerHandle, &srcStrings[0], srcStrings.size(), mLastCompileOptions)) { - mInfoLog = ShGetInfoLog(compilerHandle); - TRACE("\n%s", mInfoLog.c_str()); - mCompiled = false; + mInfoLog = sh::GetInfoLog(compilerHandle); + WARN() << std::endl << mInfoLog; + mState.mCompileStatus = CompileStatus::NOT_COMPILED; return; } - mData.mTranslatedSource = ShGetObjectCode(compilerHandle); + mState.mTranslatedSource = sh::GetObjectCode(compilerHandle); -#ifndef NDEBUG +#if !defined(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) + std::istringstream inputSourceStream(mState.mSource); + std::string line; + while (std::getline(inputSourceStream, line)) { - 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); + // Remove null characters from the source line + line.erase(std::remove(line.begin(), line.end(), '\0'), line.end()); - curPos = (nextLine == std::string::npos) ? std::string::npos : (nextLine + 1); + shaderStream << "// " << line << std::endl; } shaderStream << "\n\n"; - shaderStream << mData.mTranslatedSource; - mData.mTranslatedSource = shaderStream.str(); -#endif + shaderStream << mState.mTranslatedSource; + mState.mTranslatedSource = shaderStream.str(); +#endif // !defined(NDEBUG) // Gather the shader information - mData.mShaderVersion = ShGetShaderVersion(compilerHandle); + mState.mShaderVersion = sh::GetShaderVersion(compilerHandle); - mData.mVaryings = GetShaderVariables(ShGetVaryings(compilerHandle)); - mData.mUniforms = GetShaderVariables(ShGetUniforms(compilerHandle)); - mData.mInterfaceBlocks = GetShaderVariables(ShGetInterfaceBlocks(compilerHandle)); + mState.mUniforms = GetShaderVariables(sh::GetUniforms(compilerHandle)); + mState.mUniformBlocks = GetShaderVariables(sh::GetUniformBlocks(compilerHandle)); + mState.mShaderStorageBlocks = GetShaderVariables(sh::GetShaderStorageBlocks(compilerHandle)); - if (mData.mShaderType == GL_VERTEX_SHADER) + switch (mState.mShaderType) { - 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)); + case GL_COMPUTE_SHADER: + { + mState.mLocalSize = sh::GetComputeShaderLocalGroupSize(compilerHandle); + break; + } + case GL_VERTEX_SHADER: + { + { + mState.mOutputVaryings = GetShaderVariables(sh::GetOutputVaryings(compilerHandle)); + mState.mActiveAttributes = + GetActiveShaderVariables(sh::GetAttributes(compilerHandle)); + mState.mNumViews = sh::GetVertexShaderNumViews(compilerHandle); + } + break; + } + case GL_FRAGMENT_SHADER: + { + mState.mInputVaryings = GetShaderVariables(sh::GetInputVaryings(compilerHandle)); + // TODO(jmadill): Figure out why we only sort in the FS, and if we need to. + std::sort(mState.mInputVaryings.begin(), mState.mInputVaryings.end(), CompareShaderVar); + mState.mActiveOutputVariables = + GetActiveShaderVariables(sh::GetOutputVariables(compilerHandle)); + break; + } + case GL_GEOMETRY_SHADER_EXT: + { + mState.mInputVaryings = GetShaderVariables(sh::GetInputVaryings(compilerHandle)); + mState.mOutputVaryings = GetShaderVariables(sh::GetOutputVaryings(compilerHandle)); + + mState.mGeometryShaderInputPrimitiveType = + sh::GetGeometryShaderInputPrimitiveType(compilerHandle); + mState.mGeometryShaderOutputPrimitiveType = + sh::GetGeometryShaderOutputPrimitiveType(compilerHandle); + mState.mGeometryShaderInvocations = sh::GetGeometryShaderInvocations(compilerHandle); + mState.mGeometryShaderMaxVertices = sh::GetGeometryShaderMaxVertices(compilerHandle); + break; + } + default: + UNREACHABLE(); } - ASSERT(!mData.mTranslatedSource.empty()); + ASSERT(!mState.mTranslatedSource.empty()); - mCompiled = mImplementation->postTranslateCompile(compiler, &mInfoLog); + bool success = mImplementation->postTranslateCompile(mBoundCompiler.get(), &mInfoLog); + mState.mCompileStatus = success ? CompileStatus::COMPILED : CompileStatus::NOT_COMPILED; } void Shader::addRef() @@ -329,13 +427,13 @@ void Shader::addRef() mRefCount++; } -void Shader::release() +void Shader::release(const Context *context) { mRefCount--; if (mRefCount == 0 && mDeleteStatus) { - mResourceManager->deleteShader(mHandle); + mResourceManager->deleteShader(context, mHandle); } } @@ -354,57 +452,110 @@ void Shader::flagForDeletion() mDeleteStatus = true; } -int Shader::getShaderVersion() const +bool Shader::isCompiled(const Context *context) { - return mData.mShaderVersion; + resolveCompile(context); + return mState.mCompileStatus == CompileStatus::COMPILED; } -const std::vector &Shader::getVaryings() const +int Shader::getShaderVersion(const Context *context) { - return mData.getVaryings(); + resolveCompile(context); + return mState.mShaderVersion; } -const std::vector &Shader::getUniforms() const +const std::vector &Shader::getInputVaryings(const Context *context) { - return mData.getUniforms(); + resolveCompile(context); + return mState.getInputVaryings(); } -const std::vector &Shader::getInterfaceBlocks() const +const std::vector &Shader::getOutputVaryings(const Context *context) { - return mData.getInterfaceBlocks(); + resolveCompile(context); + return mState.getOutputVaryings(); } -const std::vector &Shader::getActiveAttributes() const +const std::vector &Shader::getUniforms(const Context *context) { - return mData.getActiveAttributes(); + resolveCompile(context); + return mState.getUniforms(); } -const std::vector &Shader::getActiveOutputVariables() const +const std::vector &Shader::getUniformBlocks(const Context *context) { - return mData.getActiveOutputVariables(); + resolveCompile(context); + return mState.getUniformBlocks(); } -int Shader::getSemanticIndex(const std::string &attributeName) const +const std::vector &Shader::getShaderStorageBlocks(const Context *context) { - if (!attributeName.empty()) - { - const auto &activeAttributes = mData.getActiveAttributes(); + resolveCompile(context); + return mState.getShaderStorageBlocks(); +} - int semanticIndex = 0; - for (size_t attributeIndex = 0; attributeIndex < activeAttributes.size(); attributeIndex++) - { - const sh::ShaderVariable &attribute = activeAttributes[attributeIndex]; +const std::vector &Shader::getActiveAttributes(const Context *context) +{ + resolveCompile(context); + return mState.getActiveAttributes(); +} + +const std::vector &Shader::getActiveOutputVariables(const Context *context) +{ + resolveCompile(context); + return mState.getActiveOutputVariables(); +} - if (attribute.name == attributeName) +std::string Shader::getTransformFeedbackVaryingMappedName(const std::string &tfVaryingName, + const Context *context) +{ + // TODO(jiawei.shao@intel.com): support transform feedback on geometry shader. + ASSERT(mState.getShaderType() == GL_VERTEX_SHADER); + const auto &varyings = getOutputVaryings(context); + auto bracketPos = tfVaryingName.find("["); + if (bracketPos != std::string::npos) + { + auto tfVaryingBaseName = tfVaryingName.substr(0, bracketPos); + for (const auto &varying : varyings) + { + if (varying.name == tfVaryingBaseName) { - return semanticIndex; + std::string mappedNameWithArrayIndex = + varying.mappedName + tfVaryingName.substr(bracketPos); + return mappedNameWithArrayIndex; + } + } + } + else + { + for (const auto &varying : varyings) + { + if (varying.name == tfVaryingName) + { + return varying.mappedName; } - - semanticIndex += gl::VariableRegisterCount(attribute.type); } } + UNREACHABLE(); + return std::string(); +} - return -1; +const sh::WorkGroupSize &Shader::getWorkGroupSize(const Context *context) +{ + resolveCompile(context); + return mState.mLocalSize; } +int Shader::getNumViews(const Context *context) +{ + resolveCompile(context); + return mState.mNumViews; } + +const std::string &Shader::getCompilerResourcesString() const +{ + ASSERT(mBoundCompiler.get()); + return mBoundCompiler->getBuiltinResourcesString(mState.mShaderType); +} + +} // namespace gl -- cgit v1.2.3