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.cpp279
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++)