Remove rx::ShaderSh and move the shared code to the GL.
The GL layer can interact with the translator directly, to query all
the active shader variables and call ShCompile.
BUG=angleproject:1159
Change-Id: I334a9bef28f93cf85dd8cac0fb8542ac567cc3ec
Reviewed-on: https://chromium-review.googlesource.com/299877
Reviewed-by: Geoff Lang <geofflang@chromium.org>
Tryjob-Request: Jamie Madill <jmadill@chromium.org>
Tested-by: Jamie Madill <jmadill@chromium.org>
diff --git a/src/libANGLE/Shader.cpp b/src/libANGLE/Shader.cpp
index d0255a4..98fcdca 100644
--- a/src/libANGLE/Shader.cpp
+++ b/src/libANGLE/Shader.cpp
@@ -14,6 +14,7 @@
#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"
@@ -22,6 +23,55 @@
namespace gl
{
+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;
+}
+
+template <typename VarT>
+const std::vector<VarT> &GetShaderVariables(const std::vector<VarT> *variableList)
+{
+ ASSERT(variableList);
+ return *variableList;
+}
+
+// true if varying x has a higher priority in packing than y
+bool CompareVarying(const sh::Varying &x, const sh::Varying &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);
+}
+
+} // anonymous namespace
+
Shader::Data::Data(GLenum shaderType) : mShaderType(shaderType), mShaderVersion(100)
{
}
@@ -30,9 +80,14 @@
{
}
-Shader::Shader(ResourceManager *manager, rx::ImplFactory *implFactory, GLenum type, GLuint handle)
+Shader::Shader(ResourceManager *manager,
+ rx::ImplFactory *implFactory,
+ const gl::Limitations &rendererLimitations,
+ GLenum type,
+ GLuint handle)
: mData(type),
- mImplementation(implFactory->createShader(&mData)),
+ mImplementation(implFactory->createShader(mData)),
+ mRendererLimitations(rendererLimitations),
mHandle(handle),
mType(type),
mRefCount(0),
@@ -69,17 +124,17 @@
}
}
- mSource = stream.str();
+ mData.mSource = stream.str();
}
int Shader::getInfoLogLength() const
{
- if (mData.mInfoLog.empty())
+ if (mInfoLog.empty())
{
return 0;
}
- return (static_cast<int>(mData.mInfoLog.length()) + 1);
+ return (static_cast<int>(mInfoLog.length()) + 1);
}
void Shader::getInfoLog(GLsizei bufSize, GLsizei *length, char *infoLog) const
@@ -88,8 +143,8 @@
if (bufSize > 0)
{
- index = std::min(bufSize - 1, static_cast<GLsizei>(mData.mInfoLog.length()));
- memcpy(infoLog, mData.mInfoLog.c_str(), index);
+ index = std::min(bufSize - 1, static_cast<GLsizei>(mInfoLog.length()));
+ memcpy(infoLog, mInfoLog.c_str(), index);
infoLog[index] = '\0';
}
@@ -102,7 +157,7 @@
int Shader::getSourceLength() const
{
- return mSource.empty() ? 0 : (static_cast<int>(mSource.length()) + 1);
+ return mData.mSource.empty() ? 0 : (static_cast<int>(mData.mSource.length()) + 1);
}
int Shader::getTranslatedSourceLength() const
@@ -135,7 +190,7 @@
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
@@ -152,7 +207,7 @@
void Shader::compile(Compiler *compiler)
{
mData.mTranslatedSource.clear();
- mData.mInfoLog.clear();
+ mInfoLog.clear();
mData.mShaderVersion = 100;
mData.mVaryings.clear();
mData.mUniforms.clear();
@@ -160,7 +215,81 @@
mData.mActiveAttributes.clear();
mData.mActiveOutputVariables.clear();
- mCompiled = mImplementation->compile(compiler, mSource, 0);
+ ShHandle compilerHandle = compiler->getCompilerHandle(mData.mShaderType);
+
+ std::stringstream sourceStream;
+
+ int additionalOptions = mImplementation->prepareSourceAndReturnOptions(&sourceStream);
+ 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();
+ const char *sourceCString = sourceString.c_str();
+ bool result = ShCompile(compilerHandle, &sourceCString, 1, 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(), CompareVarying);
+ mData.mActiveOutputVariables =
+ GetActiveShaderVariables(ShGetOutputVariables(compilerHandle));
+ }
+
+ ASSERT(!mData.mTranslatedSource.empty());
+
+ mCompiled = mImplementation->postTranslateCompile(compiler, &mInfoLog);
}
void Shader::addRef()