summaryrefslogtreecommitdiffstats
path: root/src/3rdparty/angle/src/libANGLE/Shader.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/3rdparty/angle/src/libANGLE/Shader.cpp')
-rw-r--r--src/3rdparty/angle/src/libANGLE/Shader.cpp373
1 files changed, 262 insertions, 111 deletions
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<int>(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<int>(mData.mSource.length()) + 1);
+ return mState.mSource.empty() ? 0 : (static_cast<int>(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<int>(mData.mTranslatedSource.length()) + 1);
+ return (static_cast<int>(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<int>(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<const char *> 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<const char *> 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<sh::Varying> &Shader::getVaryings() const
+int Shader::getShaderVersion(const Context *context)
{
- return mData.getVaryings();
+ resolveCompile(context);
+ return mState.mShaderVersion;
}
-const std::vector<sh::Uniform> &Shader::getUniforms() const
+const std::vector<sh::Varying> &Shader::getInputVaryings(const Context *context)
{
- return mData.getUniforms();
+ resolveCompile(context);
+ return mState.getInputVaryings();
}
-const std::vector<sh::InterfaceBlock> &Shader::getInterfaceBlocks() const
+const std::vector<sh::Varying> &Shader::getOutputVaryings(const Context *context)
{
- return mData.getInterfaceBlocks();
+ resolveCompile(context);
+ return mState.getOutputVaryings();
}
-const std::vector<sh::Attribute> &Shader::getActiveAttributes() const
+const std::vector<sh::Uniform> &Shader::getUniforms(const Context *context)
{
- return mData.getActiveAttributes();
+ resolveCompile(context);
+ return mState.getUniforms();
}
-const std::vector<sh::OutputVariable> &Shader::getActiveOutputVariables() const
+const std::vector<sh::InterfaceBlock> &Shader::getUniformBlocks(const Context *context)
{
- return mData.getActiveOutputVariables();
+ resolveCompile(context);
+ return mState.getUniformBlocks();
}
-int Shader::getSemanticIndex(const std::string &attributeName) const
+const std::vector<sh::InterfaceBlock> &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<sh::Attribute> &Shader::getActiveAttributes(const Context *context)
+{
+ resolveCompile(context);
+ return mState.getActiveAttributes();
+}
+
+const std::vector<sh::OutputVariable> &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