Commit bd044ed8 by Jamie Madill Committed by Commit Bot

Defer shader compiles when possible.

When using the program binary memory cache inside ANGLE, this will give a potential fast path. If the user doesn't query the shader compile status or info log before calling LinkProgram, then we can check the program cache before translating the program, and if it finds a hit, we don't even need to call the translator. To preserve the shader settings at compile time, a reference to the current shader translator is kept in a binding pointer on the call to compile. This mirrors a similar implementation in Chromium's command buffer. Also the compile options and source are cached at compile to preserve the correct shader state. BUG=angleproject:1897 Change-Id: I3c046d7ac8c3b5c8cc169c4802ffe47f95537212 Reviewed-on: https://chromium-review.googlesource.com/517379Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org> Reviewed-by: 's avatarCorentin Wallez <cwallez@chromium.org> Commit-Queue: Jamie Madill <jmadill@chromium.org>
parent dc0fa46a
...@@ -2136,7 +2136,7 @@ void Context::programPathFragmentInputGen(GLuint program, ...@@ -2136,7 +2136,7 @@ void Context::programPathFragmentInputGen(GLuint program,
{ {
auto *programObject = getProgram(program); auto *programObject = getProgram(program);
programObject->pathFragmentInputGen(location, genMode, components, coeffs); programObject->pathFragmentInputGen(this, location, genMode, components, coeffs);
} }
GLuint Context::getProgramResourceIndex(GLuint program, GLenum programInterface, const GLchar *name) GLuint Context::getProgramResourceIndex(GLuint program, GLenum programInterface, const GLchar *name)
...@@ -4319,14 +4319,14 @@ void Context::getShaderiv(GLuint shader, GLenum pname, GLint *params) ...@@ -4319,14 +4319,14 @@ void Context::getShaderiv(GLuint shader, GLenum pname, GLint *params)
{ {
Shader *shaderObject = getShader(shader); Shader *shaderObject = getShader(shader);
ASSERT(shaderObject); ASSERT(shaderObject);
QueryShaderiv(shaderObject, pname, params); QueryShaderiv(this, shaderObject, pname, params);
} }
void Context::getShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei *length, GLchar *infolog) void Context::getShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei *length, GLchar *infolog)
{ {
Shader *shaderObject = getShader(shader); Shader *shaderObject = getShader(shader);
ASSERT(shaderObject); ASSERT(shaderObject);
shaderObject->getInfoLog(bufsize, length, infolog); shaderObject->getInfoLog(this, bufsize, length, infolog);
} }
void Context::getShaderPrecisionFormat(GLenum shadertype, void Context::getShaderPrecisionFormat(GLenum shadertype,
......
...@@ -542,17 +542,17 @@ void Program::bindFragmentInputLocation(GLint index, const char *name) ...@@ -542,17 +542,17 @@ void Program::bindFragmentInputLocation(GLint index, const char *name)
mFragmentInputBindings.bindLocation(index, name); mFragmentInputBindings.bindLocation(index, name);
} }
BindingInfo Program::getFragmentInputBindingInfo(GLint index) const BindingInfo Program::getFragmentInputBindingInfo(const Context *context, GLint index) const
{ {
BindingInfo ret; BindingInfo ret;
ret.type = GL_NONE; ret.type = GL_NONE;
ret.valid = false; ret.valid = false;
const Shader *fragmentShader = mState.getAttachedFragmentShader(); Shader *fragmentShader = mState.getAttachedFragmentShader();
ASSERT(fragmentShader); ASSERT(fragmentShader);
// Find the actual fragment shader varying we're interested in // Find the actual fragment shader varying we're interested in
const std::vector<sh::Varying> &inputs = fragmentShader->getVaryings(); const std::vector<sh::Varying> &inputs = fragmentShader->getVaryings(context);
for (const auto &binding : mFragmentInputBindings) for (const auto &binding : mFragmentInputBindings)
{ {
...@@ -593,7 +593,8 @@ BindingInfo Program::getFragmentInputBindingInfo(GLint index) const ...@@ -593,7 +593,8 @@ BindingInfo Program::getFragmentInputBindingInfo(GLint index) const
return ret; return ret;
} }
void Program::pathFragmentInputGen(GLint index, void Program::pathFragmentInputGen(const Context *context,
GLint index,
GLenum genMode, GLenum genMode,
GLint components, GLint components,
const GLfloat *coeffs) const GLfloat *coeffs)
...@@ -602,7 +603,7 @@ void Program::pathFragmentInputGen(GLint index, ...@@ -602,7 +603,7 @@ void Program::pathFragmentInputGen(GLint index,
if (index == -1) if (index == -1)
return; return;
const auto &binding = getFragmentInputBindingInfo(index); const auto &binding = getFragmentInputBindingInfo(context, index);
// If the input doesn't exist then then the command is silently ignored // If the input doesn't exist then then the command is silently ignored
// This could happen through optimization for example, the shader translator // This could happen through optimization for example, the shader translator
...@@ -644,14 +645,14 @@ Error Program::link(const gl::Context *context) ...@@ -644,14 +645,14 @@ Error Program::link(const gl::Context *context)
if (computeShader) if (computeShader)
{ {
if (!computeShader->isCompiled()) if (!computeShader->isCompiled(context))
{ {
mInfoLog << "Attached compute shader is not compiled."; mInfoLog << "Attached compute shader is not compiled.";
return NoError(); return NoError();
} }
ASSERT(computeShader->getType() == GL_COMPUTE_SHADER); ASSERT(computeShader->getType() == GL_COMPUTE_SHADER);
mState.mComputeShaderLocalSize = computeShader->getWorkGroupSize(); mState.mComputeShaderLocalSize = computeShader->getWorkGroupSize(context);
// GLSL ES 3.10, 4.4.1.1 Compute Shader Inputs // GLSL ES 3.10, 4.4.1.1 Compute Shader Inputs
// If the work group size is not specified, a link time error should occur. // If the work group size is not specified, a link time error should occur.
...@@ -661,12 +662,12 @@ Error Program::link(const gl::Context *context) ...@@ -661,12 +662,12 @@ Error Program::link(const gl::Context *context)
return NoError(); return NoError();
} }
if (!linkUniforms(mInfoLog, caps, mUniformLocationBindings)) if (!linkUniforms(context, mInfoLog, mUniformLocationBindings))
{ {
return NoError(); return NoError();
} }
if (!linkUniformBlocks(mInfoLog, caps, context->getExtensions().webglCompatibility)) if (!linkUniformBlocks(context, mInfoLog))
{ {
return NoError(); return NoError();
} }
...@@ -680,52 +681,52 @@ Error Program::link(const gl::Context *context) ...@@ -680,52 +681,52 @@ Error Program::link(const gl::Context *context)
} }
else else
{ {
if (!fragmentShader || !fragmentShader->isCompiled()) if (!fragmentShader || !fragmentShader->isCompiled(context))
{ {
return NoError(); return NoError();
} }
ASSERT(fragmentShader->getType() == GL_FRAGMENT_SHADER); ASSERT(fragmentShader->getType() == GL_FRAGMENT_SHADER);
if (!vertexShader || !vertexShader->isCompiled()) if (!vertexShader || !vertexShader->isCompiled(context))
{ {
return NoError(); return NoError();
} }
ASSERT(vertexShader->getType() == GL_VERTEX_SHADER); ASSERT(vertexShader->getType() == GL_VERTEX_SHADER);
if (fragmentShader->getShaderVersion() != vertexShader->getShaderVersion()) if (fragmentShader->getShaderVersion(context) != vertexShader->getShaderVersion(context))
{ {
mInfoLog << "Fragment shader version does not match vertex shader version."; mInfoLog << "Fragment shader version does not match vertex shader version.";
return NoError(); return NoError();
} }
if (!linkAttributes(data, mInfoLog)) if (!linkAttributes(context, mInfoLog))
{ {
return NoError(); return NoError();
} }
if (!linkVaryings(mInfoLog)) if (!linkVaryings(context, mInfoLog))
{ {
return NoError(); return NoError();
} }
if (!linkUniforms(mInfoLog, caps, mUniformLocationBindings)) if (!linkUniforms(context, mInfoLog, mUniformLocationBindings))
{ {
return NoError(); return NoError();
} }
if (!linkUniformBlocks(mInfoLog, caps, context->getExtensions().webglCompatibility)) if (!linkUniformBlocks(context, mInfoLog))
{ {
return NoError(); return NoError();
} }
const auto &mergedVaryings = getMergedVaryings(); const auto &mergedVaryings = getMergedVaryings(context);
if (!linkValidateTransformFeedback(context, mInfoLog, mergedVaryings, caps)) if (!linkValidateTransformFeedback(context, mInfoLog, mergedVaryings, caps))
{ {
return NoError(); return NoError();
} }
linkOutputVariables(); linkOutputVariables(context);
// Validate we can pack the varyings. // Validate we can pack the varyings.
std::vector<PackedVarying> packedVaryings = getPackedVaryings(mergedVaryings); std::vector<PackedVarying> packedVaryings = getPackedVaryings(mergedVaryings);
...@@ -752,7 +753,7 @@ Error Program::link(const gl::Context *context) ...@@ -752,7 +753,7 @@ Error Program::link(const gl::Context *context)
setUniformValuesFromBindingQualifiers(); setUniformValuesFromBindingQualifiers();
gatherInterfaceBlockInfo(); gatherInterfaceBlockInfo(context);
return NoError(); return NoError();
} }
...@@ -1949,15 +1950,15 @@ GLenum Program::getTransformFeedbackBufferMode() const ...@@ -1949,15 +1950,15 @@ GLenum Program::getTransformFeedbackBufferMode() const
return mState.mTransformFeedbackBufferMode; return mState.mTransformFeedbackBufferMode;
} }
bool Program::linkVaryings(InfoLog &infoLog) const bool Program::linkVaryings(const Context *context, InfoLog &infoLog) const
{ {
const Shader *vertexShader = mState.mAttachedVertexShader; Shader *vertexShader = mState.mAttachedVertexShader;
const Shader *fragmentShader = mState.mAttachedFragmentShader; Shader *fragmentShader = mState.mAttachedFragmentShader;
ASSERT(vertexShader->getShaderVersion() == fragmentShader->getShaderVersion()); ASSERT(vertexShader->getShaderVersion(context) == fragmentShader->getShaderVersion(context));
const std::vector<sh::Varying> &vertexVaryings = vertexShader->getVaryings(); const std::vector<sh::Varying> &vertexVaryings = vertexShader->getVaryings(context);
const std::vector<sh::Varying> &fragmentVaryings = fragmentShader->getVaryings(); const std::vector<sh::Varying> &fragmentVaryings = fragmentShader->getVaryings(context);
std::map<GLuint, std::string> staticFragmentInputLocations; std::map<GLuint, std::string> staticFragmentInputLocations;
...@@ -1977,7 +1978,7 @@ bool Program::linkVaryings(InfoLog &infoLog) const ...@@ -1977,7 +1978,7 @@ bool Program::linkVaryings(InfoLog &infoLog) const
{ {
ASSERT(!input.isBuiltIn()); ASSERT(!input.isBuiltIn());
if (!linkValidateVaryings(infoLog, output.name, input, output, if (!linkValidateVaryings(infoLog, output.name, input, output,
vertexShader->getShaderVersion())) vertexShader->getShaderVersion(context)))
{ {
return false; return false;
} }
...@@ -2018,7 +2019,7 @@ bool Program::linkVaryings(InfoLog &infoLog) const ...@@ -2018,7 +2019,7 @@ bool Program::linkVaryings(InfoLog &infoLog) const
} }
} }
if (!linkValidateBuiltInVaryings(infoLog)) if (!linkValidateBuiltInVaryings(context, infoLog))
{ {
return false; return false;
} }
...@@ -2028,12 +2029,12 @@ bool Program::linkVaryings(InfoLog &infoLog) const ...@@ -2028,12 +2029,12 @@ bool Program::linkVaryings(InfoLog &infoLog) const
return true; return true;
} }
bool Program::linkUniforms(InfoLog &infoLog, bool Program::linkUniforms(const Context *context,
const Caps &caps, InfoLog &infoLog,
const Bindings &uniformLocationBindings) const Bindings &uniformLocationBindings)
{ {
UniformLinker linker(mState); UniformLinker linker(mState);
if (!linker.link(infoLog, caps, uniformLocationBindings)) if (!linker.link(context, infoLog, uniformLocationBindings))
{ {
return false; return false;
} }
...@@ -2089,12 +2090,13 @@ bool Program::linkValidateInterfaceBlockFields(InfoLog &infoLog, ...@@ -2089,12 +2090,13 @@ bool Program::linkValidateInterfaceBlockFields(InfoLog &infoLog,
} }
// Assigns locations to all attributes from the bindings and program locations. // Assigns locations to all attributes from the bindings and program locations.
bool Program::linkAttributes(const ContextState &data, InfoLog &infoLog) bool Program::linkAttributes(const Context *context, InfoLog &infoLog)
{ {
const auto *vertexShader = mState.getAttachedVertexShader(); const ContextState &data = context->getContextState();
auto *vertexShader = mState.getAttachedVertexShader();
unsigned int usedLocations = 0; unsigned int usedLocations = 0;
mState.mAttributes = vertexShader->getActiveAttributes(); mState.mAttributes = vertexShader->getActiveAttributes(context);
GLuint maxAttribs = data.getCaps().maxVertexAttributes; GLuint maxAttribs = data.getCaps().maxVertexAttributes;
// TODO(jmadill): handle aliasing robustly // TODO(jmadill): handle aliasing robustly
...@@ -2239,12 +2241,14 @@ bool Program::validateVertexAndFragmentInterfaceBlocks( ...@@ -2239,12 +2241,14 @@ bool Program::validateVertexAndFragmentInterfaceBlocks(
return true; return true;
} }
bool Program::linkUniformBlocks(InfoLog &infoLog, const Caps &caps, bool webglCompatibility) bool Program::linkUniformBlocks(const Context *context, InfoLog &infoLog)
{ {
const auto &caps = context->getCaps();
if (mState.mAttachedComputeShader) if (mState.mAttachedComputeShader)
{ {
const Shader &computeShader = *mState.mAttachedComputeShader; Shader &computeShader = *mState.mAttachedComputeShader;
const auto &computeInterfaceBlocks = computeShader.getInterfaceBlocks(); const auto &computeInterfaceBlocks = computeShader.getInterfaceBlocks(context);
if (!validateUniformBlocksCount( if (!validateUniformBlocksCount(
caps.maxComputeUniformBlocks, computeInterfaceBlocks, caps.maxComputeUniformBlocks, computeInterfaceBlocks,
...@@ -2256,11 +2260,11 @@ bool Program::linkUniformBlocks(InfoLog &infoLog, const Caps &caps, bool webglCo ...@@ -2256,11 +2260,11 @@ bool Program::linkUniformBlocks(InfoLog &infoLog, const Caps &caps, bool webglCo
return true; return true;
} }
const Shader &vertexShader = *mState.mAttachedVertexShader; Shader &vertexShader = *mState.mAttachedVertexShader;
const Shader &fragmentShader = *mState.mAttachedFragmentShader; Shader &fragmentShader = *mState.mAttachedFragmentShader;
const auto &vertexInterfaceBlocks = vertexShader.getInterfaceBlocks(); const auto &vertexInterfaceBlocks = vertexShader.getInterfaceBlocks(context);
const auto &fragmentInterfaceBlocks = fragmentShader.getInterfaceBlocks(); const auto &fragmentInterfaceBlocks = fragmentShader.getInterfaceBlocks(context);
if (!validateUniformBlocksCount( if (!validateUniformBlocksCount(
caps.maxVertexUniformBlocks, vertexInterfaceBlocks, caps.maxVertexUniformBlocks, vertexInterfaceBlocks,
...@@ -2276,6 +2280,8 @@ bool Program::linkUniformBlocks(InfoLog &infoLog, const Caps &caps, bool webglCo ...@@ -2276,6 +2280,8 @@ bool Program::linkUniformBlocks(InfoLog &infoLog, const Caps &caps, bool webglCo
return false; return false;
} }
bool webglCompatibility = context->getExtensions().webglCompatibility;
if (!validateVertexAndFragmentInterfaceBlocks(vertexInterfaceBlocks, fragmentInterfaceBlocks, if (!validateVertexAndFragmentInterfaceBlocks(vertexInterfaceBlocks, fragmentInterfaceBlocks,
infoLog, webglCompatibility)) infoLog, webglCompatibility))
{ {
...@@ -2415,13 +2421,13 @@ bool Program::linkValidateVaryings(InfoLog &infoLog, ...@@ -2415,13 +2421,13 @@ bool Program::linkValidateVaryings(InfoLog &infoLog,
return true; return true;
} }
bool Program::linkValidateBuiltInVaryings(InfoLog &infoLog) const bool Program::linkValidateBuiltInVaryings(const Context *context, InfoLog &infoLog) const
{ {
const Shader *vertexShader = mState.mAttachedVertexShader; Shader *vertexShader = mState.mAttachedVertexShader;
const Shader *fragmentShader = mState.mAttachedFragmentShader; Shader *fragmentShader = mState.mAttachedFragmentShader;
const std::vector<sh::Varying> &vertexVaryings = vertexShader->getVaryings(); const auto &vertexVaryings = vertexShader->getVaryings(context);
const std::vector<sh::Varying> &fragmentVaryings = fragmentShader->getVaryings(); const auto &fragmentVaryings = fragmentShader->getVaryings(context);
int shaderVersion = vertexShader->getShaderVersion(); int shaderVersion = vertexShader->getShaderVersion(context);
if (shaderVersion != 100) if (shaderVersion != 100)
{ {
...@@ -2593,16 +2599,16 @@ void Program::gatherTransformFeedbackVaryings(const Program::MergedVaryings &var ...@@ -2593,16 +2599,16 @@ void Program::gatherTransformFeedbackVaryings(const Program::MergedVaryings &var
} }
} }
Program::MergedVaryings Program::getMergedVaryings() const Program::MergedVaryings Program::getMergedVaryings(const Context *context) const
{ {
MergedVaryings merged; MergedVaryings merged;
for (const sh::Varying &varying : mState.mAttachedVertexShader->getVaryings()) for (const sh::Varying &varying : mState.mAttachedVertexShader->getVaryings(context))
{ {
merged[varying.name].vertex = &varying; merged[varying.name].vertex = &varying;
} }
for (const sh::Varying &varying : mState.mAttachedFragmentShader->getVaryings()) for (const sh::Varying &varying : mState.mAttachedFragmentShader->getVaryings(context))
{ {
merged[varying.name].fragment = &varying; merged[varying.name].fragment = &varying;
} }
...@@ -2684,16 +2690,16 @@ std::vector<PackedVarying> Program::getPackedVaryings( ...@@ -2684,16 +2690,16 @@ std::vector<PackedVarying> Program::getPackedVaryings(
return packedVaryings; return packedVaryings;
} }
void Program::linkOutputVariables() void Program::linkOutputVariables(const Context *context)
{ {
const Shader *fragmentShader = mState.mAttachedFragmentShader; Shader *fragmentShader = mState.mAttachedFragmentShader;
ASSERT(fragmentShader != nullptr); ASSERT(fragmentShader != nullptr);
ASSERT(mState.mOutputVariableTypes.empty()); ASSERT(mState.mOutputVariableTypes.empty());
ASSERT(mState.mActiveOutputVariables.none()); ASSERT(mState.mActiveOutputVariables.none());
// Gather output variable types // Gather output variable types
for (const auto &outputVariable : fragmentShader->getActiveOutputVariables()) for (const auto &outputVariable : fragmentShader->getActiveOutputVariables(context))
{ {
if (outputVariable.isBuiltIn() && outputVariable.name != "gl_FragColor" && if (outputVariable.isBuiltIn() && outputVariable.name != "gl_FragColor" &&
outputVariable.name != "gl_FragData") outputVariable.name != "gl_FragData")
...@@ -2719,10 +2725,10 @@ void Program::linkOutputVariables() ...@@ -2719,10 +2725,10 @@ void Program::linkOutputVariables()
} }
// Skip this step for GLES2 shaders. // Skip this step for GLES2 shaders.
if (fragmentShader->getShaderVersion() == 100) if (fragmentShader->getShaderVersion(context) == 100)
return; return;
mState.mOutputVariables = fragmentShader->getActiveOutputVariables(); mState.mOutputVariables = fragmentShader->getActiveOutputVariables(context);
// TODO(jmadill): any caps validation here? // TODO(jmadill): any caps validation here?
for (unsigned int outputVariableIndex = 0; outputVariableIndex < mState.mOutputVariables.size(); for (unsigned int outputVariableIndex = 0; outputVariableIndex < mState.mOutputVariables.size();
...@@ -2771,15 +2777,15 @@ void Program::setUniformValuesFromBindingQualifiers() ...@@ -2771,15 +2777,15 @@ void Program::setUniformValuesFromBindingQualifiers()
} }
} }
void Program::gatherInterfaceBlockInfo() void Program::gatherInterfaceBlockInfo(const Context *context)
{ {
ASSERT(mState.mUniformBlocks.empty()); ASSERT(mState.mUniformBlocks.empty());
if (mState.mAttachedComputeShader) if (mState.mAttachedComputeShader)
{ {
const Shader *computeShader = mState.getAttachedComputeShader(); Shader *computeShader = mState.getAttachedComputeShader();
for (const sh::InterfaceBlock &computeBlock : computeShader->getInterfaceBlocks()) for (const sh::InterfaceBlock &computeBlock : computeShader->getInterfaceBlocks(context))
{ {
// Only 'packed' blocks are allowed to be considered inactive. // Only 'packed' blocks are allowed to be considered inactive.
...@@ -2801,9 +2807,9 @@ void Program::gatherInterfaceBlockInfo() ...@@ -2801,9 +2807,9 @@ void Program::gatherInterfaceBlockInfo()
std::set<std::string> visitedList; std::set<std::string> visitedList;
const Shader *vertexShader = mState.getAttachedVertexShader(); Shader *vertexShader = mState.getAttachedVertexShader();
for (const sh::InterfaceBlock &vertexBlock : vertexShader->getInterfaceBlocks()) for (const sh::InterfaceBlock &vertexBlock : vertexShader->getInterfaceBlocks(context))
{ {
// Only 'packed' blocks are allowed to be considered inactive. // Only 'packed' blocks are allowed to be considered inactive.
if (!vertexBlock.staticUse && vertexBlock.layout == sh::BLOCKLAYOUT_PACKED) if (!vertexBlock.staticUse && vertexBlock.layout == sh::BLOCKLAYOUT_PACKED)
...@@ -2816,9 +2822,9 @@ void Program::gatherInterfaceBlockInfo() ...@@ -2816,9 +2822,9 @@ void Program::gatherInterfaceBlockInfo()
visitedList.insert(vertexBlock.name); visitedList.insert(vertexBlock.name);
} }
const Shader *fragmentShader = mState.getAttachedFragmentShader(); Shader *fragmentShader = mState.getAttachedFragmentShader();
for (const sh::InterfaceBlock &fragmentBlock : fragmentShader->getInterfaceBlocks()) for (const sh::InterfaceBlock &fragmentBlock : fragmentShader->getInterfaceBlocks(context))
{ {
// Only 'packed' blocks are allowed to be considered inactive. // Only 'packed' blocks are allowed to be considered inactive.
if (!fragmentBlock.staticUse && fragmentBlock.layout == sh::BLOCKLAYOUT_PACKED) if (!fragmentBlock.staticUse && fragmentBlock.layout == sh::BLOCKLAYOUT_PACKED)
......
...@@ -206,9 +206,9 @@ class ProgramState final : angle::NonCopyable ...@@ -206,9 +206,9 @@ class ProgramState final : angle::NonCopyable
const std::string &getLabel(); const std::string &getLabel();
const Shader *getAttachedVertexShader() const { return mAttachedVertexShader; } Shader *getAttachedVertexShader() const { return mAttachedVertexShader; }
const Shader *getAttachedFragmentShader() const { return mAttachedFragmentShader; } Shader *getAttachedFragmentShader() const { return mAttachedFragmentShader; }
const Shader *getAttachedComputeShader() const { return mAttachedComputeShader; } Shader *getAttachedComputeShader() const { return mAttachedComputeShader; }
const std::vector<std::string> &getTransformFeedbackVaryingNames() const const std::vector<std::string> &getTransformFeedbackVaryingNames() const
{ {
return mTransformFeedbackVaryingNames; return mTransformFeedbackVaryingNames;
...@@ -314,9 +314,10 @@ class Program final : angle::NonCopyable, public LabeledObject ...@@ -314,9 +314,10 @@ class Program final : angle::NonCopyable, public LabeledObject
void bindUniformLocation(GLuint index, const char *name); void bindUniformLocation(GLuint index, const char *name);
// CHROMIUM_path_rendering // CHROMIUM_path_rendering
BindingInfo getFragmentInputBindingInfo(GLint index) const; BindingInfo getFragmentInputBindingInfo(const Context *context, GLint index) const;
void bindFragmentInputLocation(GLint index, const char *name); void bindFragmentInputLocation(GLint index, const char *name);
void pathFragmentInputGen(GLint index, void pathFragmentInputGen(const Context *context,
GLint index,
GLenum genMode, GLenum genMode,
GLint components, GLint components,
const GLfloat *coeffs); const GLfloat *coeffs);
...@@ -491,7 +492,7 @@ class Program final : angle::NonCopyable, public LabeledObject ...@@ -491,7 +492,7 @@ class Program final : angle::NonCopyable, public LabeledObject
void unlink(); void unlink();
void resetUniformBlockBindings(); void resetUniformBlockBindings();
bool linkAttributes(const ContextState &data, InfoLog &infoLog); bool linkAttributes(const Context *context, InfoLog &infoLog);
bool validateUniformBlocksCount(GLuint maxUniformBlocks, bool validateUniformBlocksCount(GLuint maxUniformBlocks,
const std::vector<sh::InterfaceBlock> &block, const std::vector<sh::InterfaceBlock> &block,
const std::string &errorMessage, const std::string &errorMessage,
...@@ -501,10 +502,12 @@ class Program final : angle::NonCopyable, public LabeledObject ...@@ -501,10 +502,12 @@ class Program final : angle::NonCopyable, public LabeledObject
const std::vector<sh::InterfaceBlock> &fragmentInterfaceBlocks, const std::vector<sh::InterfaceBlock> &fragmentInterfaceBlocks,
InfoLog &infoLog, InfoLog &infoLog,
bool webglCompatibility) const; bool webglCompatibility) const;
bool linkUniformBlocks(InfoLog &infoLog, const Caps &caps, bool webglCompatibility); bool linkUniformBlocks(const Context *context, InfoLog &infoLog);
bool linkVaryings(InfoLog &infoLog) const; bool linkVaryings(const Context *context, InfoLog &infoLog) const;
bool linkUniforms(InfoLog &infoLog, const Caps &caps, const Bindings &uniformLocationBindings); bool linkUniforms(const Context *context,
InfoLog &infoLog,
const Bindings &uniformLocationBindings);
void linkSamplerBindings(); void linkSamplerBindings();
bool areMatchingInterfaceBlocks(InfoLog &infoLog, bool areMatchingInterfaceBlocks(InfoLog &infoLog,
...@@ -517,7 +520,7 @@ class Program final : angle::NonCopyable, public LabeledObject ...@@ -517,7 +520,7 @@ class Program final : angle::NonCopyable, public LabeledObject
const sh::Varying &vertexVarying, const sh::Varying &vertexVarying,
const sh::Varying &fragmentVarying, const sh::Varying &fragmentVarying,
int shaderVersion); int shaderVersion);
bool linkValidateBuiltInVaryings(InfoLog &infoLog) const; bool linkValidateBuiltInVaryings(const Context *context, InfoLog &infoLog) const;
bool linkValidateTransformFeedback(const gl::Context *context, bool linkValidateTransformFeedback(const gl::Context *context,
InfoLog &infoLog, InfoLog &infoLog,
const MergedVaryings &linkedVaryings, const MergedVaryings &linkedVaryings,
...@@ -525,13 +528,13 @@ class Program final : angle::NonCopyable, public LabeledObject ...@@ -525,13 +528,13 @@ class Program final : angle::NonCopyable, public LabeledObject
void gatherTransformFeedbackVaryings(const MergedVaryings &varyings); void gatherTransformFeedbackVaryings(const MergedVaryings &varyings);
MergedVaryings getMergedVaryings() const; MergedVaryings getMergedVaryings(const Context *context) const;
std::vector<PackedVarying> getPackedVaryings(const MergedVaryings &mergedVaryings) const; std::vector<PackedVarying> getPackedVaryings(const MergedVaryings &mergedVaryings) const;
void linkOutputVariables(); void linkOutputVariables(const Context *context);
void setUniformValuesFromBindingQualifiers(); void setUniformValuesFromBindingQualifiers();
void gatherInterfaceBlockInfo(); void gatherInterfaceBlockInfo(const Context *context);
template <typename VarT> template <typename VarT>
void defineUniformBlockMembers(const std::vector<VarT> &fields, void defineUniformBlockMembers(const std::vector<VarT> &fields,
const std::string &prefix, const std::string &prefix,
......
...@@ -95,7 +95,7 @@ Shader::Shader(ShaderProgramManager *manager, ...@@ -95,7 +95,7 @@ Shader::Shader(ShaderProgramManager *manager,
mType(type), mType(type),
mRefCount(0), mRefCount(0),
mDeleteStatus(false), mDeleteStatus(false),
mCompiled(false), mStatus(CompileStatus::NOT_COMPILED),
mResourceManager(manager) mResourceManager(manager)
{ {
ASSERT(mImplementation); ASSERT(mImplementation);
...@@ -103,7 +103,7 @@ Shader::Shader(ShaderProgramManager *manager, ...@@ -103,7 +103,7 @@ Shader::Shader(ShaderProgramManager *manager,
Shader::~Shader() Shader::~Shader()
{ {
SafeDelete(mImplementation); mBoundCompiler.set(nullptr);
} }
void Shader::setLabel(const std::string &label) void Shader::setLabel(const std::string &label)
...@@ -140,8 +140,9 @@ void Shader::setSource(GLsizei count, const char *const *string, const GLint *le ...@@ -140,8 +140,9 @@ void Shader::setSource(GLsizei count, const char *const *string, const GLint *le
mState.mSource = stream.str(); mState.mSource = stream.str();
} }
int Shader::getInfoLogLength() const int Shader::getInfoLogLength(const Context *context)
{ {
resolveCompile(context);
if (mInfoLog.empty()) if (mInfoLog.empty())
{ {
return 0; return 0;
...@@ -150,8 +151,10 @@ int Shader::getInfoLogLength() const ...@@ -150,8 +151,10 @@ int Shader::getInfoLogLength() const
return (static_cast<int>(mInfoLog.length()) + 1); 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; int index = 0;
if (bufSize > 0) if (bufSize > 0)
...@@ -173,8 +176,10 @@ int Shader::getSourceLength() const ...@@ -173,8 +176,10 @@ int Shader::getSourceLength() const
return mState.mSource.empty() ? 0 : (static_cast<int>(mState.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)
{ {
resolveCompile(context);
if (mState.mTranslatedSource.empty()) if (mState.mTranslatedSource.empty())
{ {
return 0; return 0;
...@@ -183,8 +188,10 @@ int Shader::getTranslatedSourceLength() const ...@@ -183,8 +188,10 @@ int Shader::getTranslatedSourceLength() const
return (static_cast<int>(mState.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(); const std::string &debugInfo = mImplementation->getDebugInfo();
if (debugInfo.empty()) if (debugInfo.empty())
{ {
...@@ -194,7 +201,11 @@ int Shader::getTranslatedSourceWithDebugInfoLength() const ...@@ -194,7 +201,11 @@ int Shader::getTranslatedSourceWithDebugInfoLength() const
return (static_cast<int>(debugInfo.length()) + 1); 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; int index = 0;
...@@ -214,18 +225,31 @@ void Shader::getSourceImpl(const std::string &source, GLsizei bufSize, GLsizei * ...@@ -214,18 +225,31 @@ void Shader::getSourceImpl(const std::string &source, GLsizei bufSize, GLsizei *
void Shader::getSource(GLsizei bufSize, GLsizei *length, char *buffer) const void Shader::getSource(GLsizei bufSize, GLsizei *length, char *buffer) const
{ {
getSourceImpl(mState.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(mState.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(); const std::string &debugInfo = mImplementation->getDebugInfo();
getSourceImpl(debugInfo, bufSize, length, buffer); GetSourceImpl(debugInfo, bufSize, length, buffer);
} }
void Shader::compile(const Context *context) void Shader::compile(const Context *context)
...@@ -239,23 +263,26 @@ void Shader::compile(const Context *context) ...@@ -239,23 +263,26 @@ void Shader::compile(const Context *context)
mState.mActiveAttributes.clear(); mState.mActiveAttributes.clear();
mState.mActiveOutputVariables.clear(); mState.mActiveOutputVariables.clear();
Compiler *compiler = context->getCompiler(); mStatus = CompileStatus::COMPILE_REQUESTED;
ShHandle compilerHandle = compiler->getCompilerHandle(mState.mShaderType); mBoundCompiler.set(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::stringstream sourceStream;
std::string sourcePath; mLastCompileOptions =
ShCompileOptions additionalOptions = mImplementation->prepareSourceAndReturnOptions(&sourceStream, &mLastCompiledSourcePath);
mImplementation->prepareSourceAndReturnOptions(&sourceStream, &sourcePath); mLastCompileOptions |= (SH_OBJECT_CODE | SH_VARIABLES);
ShCompileOptions compileOptions = (SH_OBJECT_CODE | SH_VARIABLES | additionalOptions); mLastCompiledSource = sourceStream.str();
// Add default options to WebGL shaders to prevent unexpected behavior during compilation. // Add default options to WebGL shaders to prevent unexpected behavior during compilation.
if (context->getExtensions().webglCompatibility) if (context->getExtensions().webglCompatibility)
{ {
compileOptions |= SH_INIT_GL_POSITION; mLastCompileOptions |= SH_INIT_GL_POSITION;
compileOptions |= SH_LIMIT_CALL_STACK_DEPTH; mLastCompileOptions |= SH_LIMIT_CALL_STACK_DEPTH;
compileOptions |= SH_LIMIT_EXPRESSION_COMPLEXITY; mLastCompileOptions |= SH_LIMIT_EXPRESSION_COMPLEXITY;
compileOptions |= SH_ENFORCE_PACKING_RESTRICTIONS; mLastCompileOptions |= SH_ENFORCE_PACKING_RESTRICTIONS;
} }
// Some targets (eg D3D11 Feature Level 9_3 and below) do not support non-constant loop indexes // Some targets (eg D3D11 Feature Level 9_3 and below) do not support non-constant loop indexes
...@@ -263,33 +290,40 @@ void Shader::compile(const Context *context) ...@@ -263,33 +290,40 @@ void Shader::compile(const Context *context)
// instruct the compiler to pre-validate. // instruct the compiler to pre-validate.
if (mRendererLimitations.shadersRequireIndexedLoopValidation) if (mRendererLimitations.shadersRequireIndexedLoopValidation)
{ {
compileOptions |= SH_VALIDATE_LOOP_INDEXING; mLastCompileOptions |= SH_VALIDATE_LOOP_INDEXING;
} }
}
std::string sourceString = sourceStream.str(); void Shader::resolveCompile(const Context *context)
std::vector<const char *> sourceCStrings; {
if (mStatus != CompileStatus::COMPILE_REQUESTED)
if (!sourcePath.empty())
{ {
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 = srcStrings.push_back(mLastCompiledSource.c_str());
sh::Compile(compilerHandle, &sourceCStrings[0], sourceCStrings.size(), compileOptions);
if (!result) if (!sh::Compile(compilerHandle, &srcStrings[0], srcStrings.size(), mLastCompileOptions))
{ {
mInfoLog = sh::GetInfoLog(compilerHandle); mInfoLog = sh::GetInfoLog(compilerHandle);
WARN() << std::endl << mInfoLog; WARN() << std::endl << mInfoLog;
mCompiled = false; mStatus = CompileStatus::NOT_COMPILED;
return; return;
} }
mState.mTranslatedSource = sh::GetObjectCode(compilerHandle); mState.mTranslatedSource = sh::GetObjectCode(compilerHandle);
#ifndef NDEBUG #if !defined(NDEBUG)
// Prefix translated shader with commented out un-translated shader. // Prefix translated shader with commented out un-translated shader.
// Useful in diagnostics tools which capture the shader source. // Useful in diagnostics tools which capture the shader source.
std::ostringstream shaderStream; std::ostringstream shaderStream;
...@@ -308,7 +342,7 @@ void Shader::compile(const Context *context) ...@@ -308,7 +342,7 @@ void Shader::compile(const Context *context)
shaderStream << "\n\n"; shaderStream << "\n\n";
shaderStream << mState.mTranslatedSource; shaderStream << mState.mTranslatedSource;
mState.mTranslatedSource = shaderStream.str(); mState.mTranslatedSource = shaderStream.str();
#endif #endif // !defined(NDEBUG)
// Gather the shader information // Gather the shader information
mState.mShaderVersion = sh::GetShaderVersion(compilerHandle); mState.mShaderVersion = sh::GetShaderVersion(compilerHandle);
...@@ -343,7 +377,8 @@ void Shader::compile(const Context *context) ...@@ -343,7 +377,8 @@ void Shader::compile(const Context *context)
ASSERT(!mState.mTranslatedSource.empty()); ASSERT(!mState.mTranslatedSource.empty());
mCompiled = mImplementation->postTranslateCompile(compiler, &mInfoLog); bool success = mImplementation->postTranslateCompile(mBoundCompiler.get(), &mInfoLog);
mStatus = success ? CompileStatus::COMPILED : CompileStatus::NOT_COMPILED;
} }
void Shader::addRef() void Shader::addRef()
...@@ -376,38 +411,51 @@ void Shader::flagForDeletion() ...@@ -376,38 +411,51 @@ void Shader::flagForDeletion()
mDeleteStatus = true; mDeleteStatus = true;
} }
int Shader::getShaderVersion() const bool Shader::isCompiled(const Context *context)
{ {
resolveCompile(context);
return mStatus == CompileStatus::COMPILED;
}
int Shader::getShaderVersion(const Context *context)
{
resolveCompile(context);
return mState.mShaderVersion; return mState.mShaderVersion;
} }
const std::vector<sh::Varying> &Shader::getVaryings() const const std::vector<sh::Varying> &Shader::getVaryings(const Context *context)
{ {
resolveCompile(context);
return mState.getVaryings(); return mState.getVaryings();
} }
const std::vector<sh::Uniform> &Shader::getUniforms() const const std::vector<sh::Uniform> &Shader::getUniforms(const Context *context)
{ {
resolveCompile(context);
return mState.getUniforms(); return mState.getUniforms();
} }
const std::vector<sh::InterfaceBlock> &Shader::getInterfaceBlocks() const const std::vector<sh::InterfaceBlock> &Shader::getInterfaceBlocks(const Context *context)
{ {
resolveCompile(context);
return mState.getInterfaceBlocks(); return mState.getInterfaceBlocks();
} }
const std::vector<sh::Attribute> &Shader::getActiveAttributes() const const std::vector<sh::Attribute> &Shader::getActiveAttributes(const Context *context)
{ {
resolveCompile(context);
return mState.getActiveAttributes(); return mState.getActiveAttributes();
} }
const std::vector<sh::OutputVariable> &Shader::getActiveOutputVariables() const const std::vector<sh::OutputVariable> &Shader::getActiveOutputVariables(const Context *context)
{ {
resolveCompile(context);
return mState.getActiveOutputVariables(); return mState.getActiveOutputVariables();
} }
int Shader::getSemanticIndex(const std::string &attributeName) const int Shader::getSemanticIndex(const Context *context, const std::string &attributeName)
{ {
resolveCompile(context);
if (!attributeName.empty()) if (!attributeName.empty())
{ {
const auto &activeAttributes = mState.getActiveAttributes(); const auto &activeAttributes = mState.getActiveAttributes();
...@@ -429,4 +477,10 @@ int Shader::getSemanticIndex(const std::string &attributeName) const ...@@ -429,4 +477,10 @@ int Shader::getSemanticIndex(const std::string &attributeName) const
return -1; return -1;
} }
const sh::WorkGroupSize &Shader::getWorkGroupSize(const Context *context)
{
resolveCompile(context);
return mState.mLocalSize;
} }
} // namespace gl
...@@ -12,16 +12,18 @@ ...@@ -12,16 +12,18 @@
#ifndef LIBANGLE_SHADER_H_ #ifndef LIBANGLE_SHADER_H_
#define LIBANGLE_SHADER_H_ #define LIBANGLE_SHADER_H_
#include <string>
#include <list> #include <list>
#include <memory>
#include <string>
#include <vector> #include <vector>
#include "angle_gl.h" #include "angle_gl.h"
#include <GLSLANG/ShaderLang.h> #include <GLSLANG/ShaderLang.h>
#include "common/Optional.h"
#include "common/angleutils.h" #include "common/angleutils.h"
#include "libANGLE/angletypes.h"
#include "libANGLE/Debug.h" #include "libANGLE/Debug.h"
#include "libANGLE/angletypes.h"
namespace rx namespace rx
{ {
...@@ -98,22 +100,27 @@ class Shader final : angle::NonCopyable, public LabeledObject ...@@ -98,22 +100,27 @@ class Shader final : angle::NonCopyable, public LabeledObject
GLenum getType() const { return mType; } GLenum getType() const { return mType; }
GLuint getHandle() const; GLuint getHandle() const;
rx::ShaderImpl *getImplementation() const { return mImplementation; } rx::ShaderImpl *getImplementation() const { return mImplementation.get(); }
void deleteSource();
void setSource(GLsizei count, const char *const *string, const GLint *length); void setSource(GLsizei count, const char *const *string, const GLint *length);
int getInfoLogLength() const; int getInfoLogLength(const Context *context);
void getInfoLog(GLsizei bufSize, GLsizei *length, char *infoLog) const; void getInfoLog(const Context *context, GLsizei bufSize, GLsizei *length, char *infoLog);
int getSourceLength() const; int getSourceLength() const;
void getSource(GLsizei bufSize, GLsizei *length, char *buffer) const; void getSource(GLsizei bufSize, GLsizei *length, char *buffer) const;
int getTranslatedSourceLength() const; int getTranslatedSourceLength(const Context *context);
int getTranslatedSourceWithDebugInfoLength() const; int getTranslatedSourceWithDebugInfoLength(const Context *context);
const std::string &getTranslatedSource() const { return mState.getTranslatedSource(); } const std::string &getTranslatedSource(const Context *context);
void getTranslatedSource(GLsizei bufSize, GLsizei *length, char *buffer) const; void getTranslatedSource(const Context *context,
void getTranslatedSourceWithDebugInfo(GLsizei bufSize, GLsizei *length, char *buffer) const; GLsizei bufSize,
GLsizei *length,
char *buffer);
void getTranslatedSourceWithDebugInfo(const Context *context,
GLsizei bufSize,
GLsizei *length,
char *buffer);
void compile(const Context *context); void compile(const Context *context);
bool isCompiled() const { return mCompiled; } bool isCompiled(const Context *context);
void addRef(); void addRef();
void release(const Context *context); void release(const Context *context);
...@@ -121,31 +128,50 @@ class Shader final : angle::NonCopyable, public LabeledObject ...@@ -121,31 +128,50 @@ class Shader final : angle::NonCopyable, public LabeledObject
bool isFlaggedForDeletion() const; bool isFlaggedForDeletion() const;
void flagForDeletion(); void flagForDeletion();
int getShaderVersion() const; int getShaderVersion(const Context *context);
const std::vector<sh::Varying> &getVaryings() const; const std::vector<sh::Varying> &getVaryings(const Context *context);
const std::vector<sh::Uniform> &getUniforms() const; const std::vector<sh::Uniform> &getUniforms(const Context *context);
const std::vector<sh::InterfaceBlock> &getInterfaceBlocks() const; const std::vector<sh::InterfaceBlock> &getInterfaceBlocks(const Context *context);
const std::vector<sh::Attribute> &getActiveAttributes() const; const std::vector<sh::Attribute> &getActiveAttributes(const Context *context);
const std::vector<sh::OutputVariable> &getActiveOutputVariables() const; const std::vector<sh::OutputVariable> &getActiveOutputVariables(const Context *context);
int getSemanticIndex(const std::string &attributeName) const; int getSemanticIndex(const Context *context, const std::string &attributeName);
const sh::WorkGroupSize &getWorkGroupSize() const { return mState.mLocalSize; } const sh::WorkGroupSize &getWorkGroupSize(const Context *context);
private: private:
static void getSourceImpl(const std::string &source, GLsizei bufSize, GLsizei *length, char *buffer); static void GetSourceImpl(const std::string &source,
GLsizei bufSize,
GLsizei *length,
char *buffer);
void resolveCompile(const Context *context);
// We defer the compile until link time, or until properties are queried.
enum class CompileStatus
{
NOT_COMPILED,
COMPILE_REQUESTED,
COMPILED,
};
ShaderState mState; ShaderState mState;
rx::ShaderImpl *mImplementation; std::string mLastCompiledSource;
std::string mLastCompiledSourcePath;
ShCompileOptions mLastCompileOptions;
std::unique_ptr<rx::ShaderImpl> mImplementation;
const gl::Limitations &mRendererLimitations; const gl::Limitations &mRendererLimitations;
const GLuint mHandle; const GLuint mHandle;
const GLenum mType; const GLenum mType;
unsigned int mRefCount; // Number of program objects this shader is attached to unsigned int mRefCount; // Number of program objects this shader is attached to
bool mDeleteStatus; // Flag to indicate that the shader can be deleted when no longer in use bool mDeleteStatus; // Flag to indicate that the shader can be deleted when no longer in use
bool mCompiled; // Indicates if this shader has been successfully compiled CompileStatus mStatus; // Indicates if this shader has been successfully compiled
std::string mInfoLog; std::string mInfoLog;
// We keep a reference to the translator in order to defer compiles while preserving settings.
BindingPointer<Compiler> mBoundCompiler;
ShaderProgramManager *mResourceManager; ShaderProgramManager *mResourceManager;
}; };
......
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
#include "common/utilities.h" #include "common/utilities.h"
#include "libANGLE/Caps.h" #include "libANGLE/Caps.h"
#include "libANGLE/Context.h"
#include "libANGLE/Shader.h" #include "libANGLE/Shader.h"
#include "libANGLE/features.h" #include "libANGLE/features.h"
...@@ -45,14 +46,14 @@ void UniformLinker::getResults(std::vector<LinkedUniform> *uniforms, ...@@ -45,14 +46,14 @@ void UniformLinker::getResults(std::vector<LinkedUniform> *uniforms,
uniformLocations->swap(mUniformLocations); uniformLocations->swap(mUniformLocations);
} }
bool UniformLinker::link(InfoLog &infoLog, bool UniformLinker::link(const Context *context,
const Caps &caps, InfoLog &infoLog,
const Program::Bindings &uniformLocationBindings) const Program::Bindings &uniformLocationBindings)
{ {
if (mState.getAttachedVertexShader() && mState.getAttachedFragmentShader()) if (mState.getAttachedVertexShader() && mState.getAttachedFragmentShader())
{ {
ASSERT(mState.getAttachedComputeShader() == nullptr); ASSERT(mState.getAttachedComputeShader() == nullptr);
if (!validateVertexAndFragmentUniforms(infoLog)) if (!validateVertexAndFragmentUniforms(context, infoLog))
{ {
return false; return false;
} }
...@@ -60,7 +61,7 @@ bool UniformLinker::link(InfoLog &infoLog, ...@@ -60,7 +61,7 @@ bool UniformLinker::link(InfoLog &infoLog,
// Flatten the uniforms list (nested fields) into a simple list (no nesting). // Flatten the uniforms list (nested fields) into a simple list (no nesting).
// Also check the maximum uniform vector and sampler counts. // Also check the maximum uniform vector and sampler counts.
if (!flattenUniformsAndCheckCaps(caps, infoLog)) if (!flattenUniformsAndCheckCaps(context, infoLog))
{ {
return false; return false;
} }
...@@ -73,14 +74,15 @@ bool UniformLinker::link(InfoLog &infoLog, ...@@ -73,14 +74,15 @@ bool UniformLinker::link(InfoLog &infoLog,
return true; return true;
} }
bool UniformLinker::validateVertexAndFragmentUniforms(InfoLog &infoLog) const bool UniformLinker::validateVertexAndFragmentUniforms(const Context *context,
InfoLog &infoLog) const
{ {
// Check that uniforms defined in the vertex and fragment shaders are identical // Check that uniforms defined in the vertex and fragment shaders are identical
std::map<std::string, LinkedUniform> linkedUniforms; std::map<std::string, LinkedUniform> linkedUniforms;
const std::vector<sh::Uniform> &vertexUniforms = const std::vector<sh::Uniform> &vertexUniforms =
mState.getAttachedVertexShader()->getUniforms(); mState.getAttachedVertexShader()->getUniforms(context);
const std::vector<sh::Uniform> &fragmentUniforms = const std::vector<sh::Uniform> &fragmentUniforms =
mState.getAttachedFragmentShader()->getUniforms(); mState.getAttachedFragmentShader()->getUniforms(context);
for (const sh::Uniform &vertexUniform : vertexUniforms) for (const sh::Uniform &vertexUniform : vertexUniforms)
{ {
...@@ -319,7 +321,8 @@ void UniformLinker::pruneUnusedUniforms() ...@@ -319,7 +321,8 @@ void UniformLinker::pruneUnusedUniforms()
} }
bool UniformLinker::flattenUniformsAndCheckCapsForShader( bool UniformLinker::flattenUniformsAndCheckCapsForShader(
const Shader &shader, const Context *context,
Shader *shader,
GLuint maxUniformComponents, GLuint maxUniformComponents,
GLuint maxTextureImageUnits, GLuint maxTextureImageUnits,
const std::string &componentsErrorMessage, const std::string &componentsErrorMessage,
...@@ -328,7 +331,7 @@ bool UniformLinker::flattenUniformsAndCheckCapsForShader( ...@@ -328,7 +331,7 @@ bool UniformLinker::flattenUniformsAndCheckCapsForShader(
InfoLog &infoLog) InfoLog &infoLog)
{ {
VectorAndSamplerCount vasCount; VectorAndSamplerCount vasCount;
for (const sh::Uniform &uniform : shader.getUniforms()) for (const sh::Uniform &uniform : shader->getUniforms(context))
{ {
vasCount += flattenUniform(uniform, &samplerUniforms); vasCount += flattenUniform(uniform, &samplerUniforms);
} }
...@@ -348,17 +351,19 @@ bool UniformLinker::flattenUniformsAndCheckCapsForShader( ...@@ -348,17 +351,19 @@ bool UniformLinker::flattenUniformsAndCheckCapsForShader(
return true; return true;
} }
bool UniformLinker::flattenUniformsAndCheckCaps(const Caps &caps, InfoLog &infoLog) bool UniformLinker::flattenUniformsAndCheckCaps(const Context *context, InfoLog &infoLog)
{ {
std::vector<LinkedUniform> samplerUniforms; std::vector<LinkedUniform> samplerUniforms;
const Caps &caps = context->getCaps();
if (mState.getAttachedComputeShader()) if (mState.getAttachedComputeShader())
{ {
const Shader *computeShader = mState.getAttachedComputeShader(); Shader *computeShader = mState.getAttachedComputeShader();
// TODO (mradev): check whether we need finer-grained component counting // TODO (mradev): check whether we need finer-grained component counting
if (!flattenUniformsAndCheckCapsForShader( if (!flattenUniformsAndCheckCapsForShader(
*computeShader, caps.maxComputeUniformComponents / 4, context, computeShader, caps.maxComputeUniformComponents / 4,
caps.maxComputeTextureImageUnits, caps.maxComputeTextureImageUnits,
"Compute shader active uniforms exceed MAX_COMPUTE_UNIFORM_COMPONENTS (", "Compute shader active uniforms exceed MAX_COMPUTE_UNIFORM_COMPONENTS (",
"Compute shader sampler count exceeds MAX_COMPUTE_TEXTURE_IMAGE_UNITS (", "Compute shader sampler count exceeds MAX_COMPUTE_TEXTURE_IMAGE_UNITS (",
...@@ -369,20 +374,22 @@ bool UniformLinker::flattenUniformsAndCheckCaps(const Caps &caps, InfoLog &infoL ...@@ -369,20 +374,22 @@ bool UniformLinker::flattenUniformsAndCheckCaps(const Caps &caps, InfoLog &infoL
} }
else else
{ {
const Shader *vertexShader = mState.getAttachedVertexShader(); Shader *vertexShader = mState.getAttachedVertexShader();
if (!flattenUniformsAndCheckCapsForShader( if (!flattenUniformsAndCheckCapsForShader(
*vertexShader, caps.maxVertexUniformVectors, caps.maxVertexTextureImageUnits, context, vertexShader, caps.maxVertexUniformVectors,
caps.maxVertexTextureImageUnits,
"Vertex shader active uniforms exceed MAX_VERTEX_UNIFORM_VECTORS (", "Vertex shader active uniforms exceed MAX_VERTEX_UNIFORM_VECTORS (",
"Vertex shader sampler count exceeds MAX_VERTEX_TEXTURE_IMAGE_UNITS (", "Vertex shader sampler count exceeds MAX_VERTEX_TEXTURE_IMAGE_UNITS (",
samplerUniforms, infoLog)) samplerUniforms, infoLog))
{ {
return false; return false;
} }
const Shader *fragmentShader = mState.getAttachedFragmentShader();
Shader *fragmentShader = mState.getAttachedFragmentShader();
if (!flattenUniformsAndCheckCapsForShader( if (!flattenUniformsAndCheckCapsForShader(
*fragmentShader, caps.maxFragmentUniformVectors, caps.maxTextureImageUnits, context, fragmentShader, caps.maxFragmentUniformVectors, caps.maxTextureImageUnits,
"Fragment shader active uniforms exceed MAX_FRAGMENT_UNIFORM_VECTORS (", "Fragment shader active uniforms exceed MAX_FRAGMENT_UNIFORM_VECTORS (",
"Fragment shader sampler count exceeds MAX_TEXTURE_IMAGE_UNITS (", samplerUniforms, "Fragment shader sampler count exceeds MAX_TEXTURE_IMAGE_UNITS (", samplerUniforms,
infoLog)) infoLog))
......
...@@ -22,7 +22,9 @@ class UniformLinker ...@@ -22,7 +22,9 @@ class UniformLinker
public: public:
UniformLinker(const ProgramState &state); UniformLinker(const ProgramState &state);
bool link(InfoLog &infoLog, const Caps &caps, const Program::Bindings &uniformLocationBindings); bool link(const Context *context,
InfoLog &infoLog,
const Program::Bindings &uniformLocationBindings);
void getResults(std::vector<LinkedUniform> *uniforms, void getResults(std::vector<LinkedUniform> *uniforms,
std::vector<VariableLocation> *uniformLocations); std::vector<VariableLocation> *uniformLocations);
...@@ -45,21 +47,22 @@ class UniformLinker ...@@ -45,21 +47,22 @@ class UniformLinker
unsigned int samplerCount; unsigned int samplerCount;
}; };
bool validateVertexAndFragmentUniforms(InfoLog &infoLog) const; bool validateVertexAndFragmentUniforms(const Context *context, InfoLog &infoLog) const;
static bool linkValidateUniforms(InfoLog &infoLog, static bool linkValidateUniforms(InfoLog &infoLog,
const std::string &uniformName, const std::string &uniformName,
const sh::Uniform &vertexUniform, const sh::Uniform &vertexUniform,
const sh::Uniform &fragmentUniform); const sh::Uniform &fragmentUniform);
bool flattenUniformsAndCheckCapsForShader(const Shader &shader, bool flattenUniformsAndCheckCapsForShader(const Context *context,
Shader *shader,
GLuint maxUniformComponents, GLuint maxUniformComponents,
GLuint maxTextureImageUnits, GLuint maxTextureImageUnits,
const std::string &componentsErrorMessage, const std::string &componentsErrorMessage,
const std::string &samplerErrorMessage, const std::string &samplerErrorMessage,
std::vector<LinkedUniform> &samplerUniforms, std::vector<LinkedUniform> &samplerUniforms,
InfoLog &infoLog); InfoLog &infoLog);
bool flattenUniformsAndCheckCaps(const Caps &caps, InfoLog &infoLog); bool flattenUniformsAndCheckCaps(const Context *context, InfoLog &infoLog);
VectorAndSamplerCount flattenUniform(const sh::Uniform &uniform, VectorAndSamplerCount flattenUniform(const sh::Uniform &uniform,
std::vector<LinkedUniform> *samplerUniforms); std::vector<LinkedUniform> *samplerUniforms);
......
...@@ -678,7 +678,7 @@ void QueryRenderbufferiv(const Context *context, ...@@ -678,7 +678,7 @@ void QueryRenderbufferiv(const Context *context,
} }
} }
void QueryShaderiv(const Shader *shader, GLenum pname, GLint *params) void QueryShaderiv(const Context *context, Shader *shader, GLenum pname, GLint *params)
{ {
ASSERT(shader != nullptr); ASSERT(shader != nullptr);
...@@ -691,16 +691,16 @@ void QueryShaderiv(const Shader *shader, GLenum pname, GLint *params) ...@@ -691,16 +691,16 @@ void QueryShaderiv(const Shader *shader, GLenum pname, GLint *params)
*params = shader->isFlaggedForDeletion(); *params = shader->isFlaggedForDeletion();
return; return;
case GL_COMPILE_STATUS: case GL_COMPILE_STATUS:
*params = shader->isCompiled() ? GL_TRUE : GL_FALSE; *params = shader->isCompiled(context) ? GL_TRUE : GL_FALSE;
return; return;
case GL_INFO_LOG_LENGTH: case GL_INFO_LOG_LENGTH:
*params = shader->getInfoLogLength(); *params = shader->getInfoLogLength(context);
return; return;
case GL_SHADER_SOURCE_LENGTH: case GL_SHADER_SOURCE_LENGTH:
*params = shader->getSourceLength(); *params = shader->getSourceLength();
return; return;
case GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE: case GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE:
*params = shader->getTranslatedSourceWithDebugInfoLength(); *params = shader->getTranslatedSourceWithDebugInfoLength(context);
return; return;
default: default:
UNREACHABLE(); UNREACHABLE();
......
...@@ -44,7 +44,7 @@ void QueryRenderbufferiv(const Context *context, ...@@ -44,7 +44,7 @@ void QueryRenderbufferiv(const Context *context,
const Renderbuffer *renderbuffer, const Renderbuffer *renderbuffer,
GLenum pname, GLenum pname,
GLint *params); GLint *params);
void QueryShaderiv(const Shader *shader, GLenum pname, GLint *params); void QueryShaderiv(const Context *context, Shader *shader, GLenum pname, GLint *params);
void QueryTexLevelParameterfv(const Texture *texture, void QueryTexLevelParameterfv(const Texture *texture,
GLenum target, GLenum target,
GLint level, GLint level,
......
...@@ -10,13 +10,14 @@ ...@@ -10,13 +10,14 @@
#include "common/utilities.h" #include "common/utilities.h"
#include "compiler/translator/blocklayoutHLSL.h" #include "compiler/translator/blocklayoutHLSL.h"
#include "libANGLE/Context.h"
#include "libANGLE/Program.h" #include "libANGLE/Program.h"
#include "libANGLE/Shader.h" #include "libANGLE/Shader.h"
#include "libANGLE/VaryingPacking.h"
#include "libANGLE/formatutils.h" #include "libANGLE/formatutils.h"
#include "libANGLE/renderer/d3d/ProgramD3D.h" #include "libANGLE/renderer/d3d/ProgramD3D.h"
#include "libANGLE/renderer/d3d/RendererD3D.h" #include "libANGLE/renderer/d3d/RendererD3D.h"
#include "libANGLE/renderer/d3d/ShaderD3D.h" #include "libANGLE/renderer/d3d/ShaderD3D.h"
#include "libANGLE/VaryingPacking.h"
using namespace gl; using namespace gl;
...@@ -392,7 +393,7 @@ void DynamicHLSL::generateVaryingLinkHLSL(const VaryingPacking &varyingPacking, ...@@ -392,7 +393,7 @@ void DynamicHLSL::generateVaryingLinkHLSL(const VaryingPacking &varyingPacking,
hlslStream << "};\n"; hlslStream << "};\n";
} }
void DynamicHLSL::generateShaderLinkHLSL(const gl::ContextState &data, void DynamicHLSL::generateShaderLinkHLSL(const gl::Context *context,
const gl::ProgramState &programData, const gl::ProgramState &programData,
const ProgramD3DMetadata &programMetadata, const ProgramD3DMetadata &programMetadata,
const VaryingPacking &varyingPacking, const VaryingPacking &varyingPacking,
...@@ -402,8 +403,9 @@ void DynamicHLSL::generateShaderLinkHLSL(const gl::ContextState &data, ...@@ -402,8 +403,9 @@ void DynamicHLSL::generateShaderLinkHLSL(const gl::ContextState &data,
{ {
ASSERT(pixelHLSL->empty() && vertexHLSL->empty()); ASSERT(pixelHLSL->empty() && vertexHLSL->empty());
const gl::Shader *vertexShaderGL = programData.getAttachedVertexShader(); const auto &data = context->getContextState();
const gl::Shader *fragmentShaderGL = programData.getAttachedFragmentShader(); gl::Shader *vertexShaderGL = programData.getAttachedVertexShader();
gl::Shader *fragmentShaderGL = programData.getAttachedFragmentShader();
const ShaderD3D *fragmentShader = GetImplAs<ShaderD3D>(fragmentShaderGL); const ShaderD3D *fragmentShader = GetImplAs<ShaderD3D>(fragmentShaderGL);
const int shaderModel = mRenderer->getMajorShaderModel(); const int shaderModel = mRenderer->getMajorShaderModel();
...@@ -418,7 +420,7 @@ void DynamicHLSL::generateShaderLinkHLSL(const gl::ContextState &data, ...@@ -418,7 +420,7 @@ void DynamicHLSL::generateShaderLinkHLSL(const gl::ContextState &data,
ASSERT(!fragmentShader->usesFragColor() || !fragmentShader->usesFragData()); ASSERT(!fragmentShader->usesFragColor() || !fragmentShader->usesFragData());
std::stringstream vertexStream; std::stringstream vertexStream;
vertexStream << vertexShaderGL->getTranslatedSource(); vertexStream << vertexShaderGL->getTranslatedSource(context);
// Instanced PointSprite emulation requires additional entries originally generated in the // Instanced PointSprite emulation requires additional entries originally generated in the
// GeometryShader HLSL. These include pointsize clamp values. // GeometryShader HLSL. These include pointsize clamp values.
...@@ -586,7 +588,7 @@ void DynamicHLSL::generateShaderLinkHLSL(const gl::ContextState &data, ...@@ -586,7 +588,7 @@ void DynamicHLSL::generateShaderLinkHLSL(const gl::ContextState &data,
const auto &pixelBuiltins = builtinsD3D[SHADER_PIXEL]; const auto &pixelBuiltins = builtinsD3D[SHADER_PIXEL];
std::stringstream pixelStream; std::stringstream pixelStream;
pixelStream << fragmentShaderGL->getTranslatedSource(); pixelStream << fragmentShaderGL->getTranslatedSource(context);
pixelStream << "struct PS_INPUT\n"; pixelStream << "struct PS_INPUT\n";
generateVaryingLinkHLSL(varyingPacking, pixelBuiltins, builtinsD3D.usesPointSize(), generateVaryingLinkHLSL(varyingPacking, pixelBuiltins, builtinsD3D.usesPointSize(),
pixelStream); pixelStream);
...@@ -769,11 +771,12 @@ void DynamicHLSL::generateShaderLinkHLSL(const gl::ContextState &data, ...@@ -769,11 +771,12 @@ void DynamicHLSL::generateShaderLinkHLSL(const gl::ContextState &data,
*pixelHLSL = pixelStream.str(); *pixelHLSL = pixelStream.str();
} }
std::string DynamicHLSL::generateComputeShaderLinkHLSL(const gl::ProgramState &programData) const std::string DynamicHLSL::generateComputeShaderLinkHLSL(const gl::Context *context,
const gl::ProgramState &programData) const
{ {
const gl::Shader *computeShaderGL = programData.getAttachedComputeShader(); gl::Shader *computeShaderGL = programData.getAttachedComputeShader();
std::stringstream computeStream; std::stringstream computeStream;
std::string translatedSource = computeShaderGL->getTranslatedSource(); std::string translatedSource = computeShaderGL->getTranslatedSource(context);
computeStream << translatedSource; computeStream << translatedSource;
bool usesWorkGroupID = translatedSource.find("GL_USES_WORK_GROUP_ID") != std::string::npos; bool usesWorkGroupID = translatedSource.find("GL_USES_WORK_GROUP_ID") != std::string::npos;
...@@ -811,7 +814,7 @@ std::string DynamicHLSL::generateComputeShaderLinkHLSL(const gl::ProgramState &p ...@@ -811,7 +814,7 @@ std::string DynamicHLSL::generateComputeShaderLinkHLSL(const gl::ProgramState &p
computeStream << "};\n\n"; computeStream << "};\n\n";
const sh::WorkGroupSize &localSize = computeShaderGL->getWorkGroupSize(); const sh::WorkGroupSize &localSize = computeShaderGL->getWorkGroupSize(context);
computeStream << "[numthreads(" << localSize[0] << ", " << localSize[1] << ", " << localSize[2] computeStream << "[numthreads(" << localSize[0] << ", " << localSize[1] << ", " << localSize[2]
<< ")]\n"; << ")]\n";
......
...@@ -117,14 +117,15 @@ class DynamicHLSL : angle::NonCopyable ...@@ -117,14 +117,15 @@ class DynamicHLSL : angle::NonCopyable
const std::vector<PixelShaderOutputVariable> &outputVariables, const std::vector<PixelShaderOutputVariable> &outputVariables,
bool usesFragDepth, bool usesFragDepth,
const std::vector<GLenum> &outputLayout) const; const std::vector<GLenum> &outputLayout) const;
void generateShaderLinkHLSL(const gl::ContextState &data, void generateShaderLinkHLSL(const gl::Context *context,
const gl::ProgramState &programData, const gl::ProgramState &programData,
const ProgramD3DMetadata &programMetadata, const ProgramD3DMetadata &programMetadata,
const gl::VaryingPacking &varyingPacking, const gl::VaryingPacking &varyingPacking,
const BuiltinVaryingsD3D &builtinsD3D, const BuiltinVaryingsD3D &builtinsD3D,
std::string *pixelHLSL, std::string *pixelHLSL,
std::string *vertexHLSL) const; std::string *vertexHLSL) const;
std::string generateComputeShaderLinkHLSL(const gl::ProgramState &programData) const; std::string generateComputeShaderLinkHLSL(const gl::Context *context,
const gl::ProgramState &programData) const;
std::string generateGeometryShaderPreamble(const gl::VaryingPacking &varyingPacking, std::string generateGeometryShaderPreamble(const gl::VaryingPacking &varyingPacking,
const BuiltinVaryingsD3D &builtinsD3D) const; const BuiltinVaryingsD3D &builtinsD3D) const;
......
...@@ -34,10 +34,11 @@ namespace rx ...@@ -34,10 +34,11 @@ namespace rx
namespace namespace
{ {
gl::InputLayout GetDefaultInputLayoutFromShader(const gl::Shader *vertexShader) gl::InputLayout GetDefaultInputLayoutFromShader(const gl::Context *context,
gl::Shader *vertexShader)
{ {
gl::InputLayout defaultLayout; gl::InputLayout defaultLayout;
for (const sh::Attribute &shaderAttr : vertexShader->getActiveAttributes()) for (const sh::Attribute &shaderAttr : vertexShader->getActiveAttributes(context))
{ {
if (shaderAttr.type != GL_NONE) if (shaderAttr.type != GL_NONE)
{ {
...@@ -1331,17 +1332,23 @@ class ProgramD3D::GetExecutableTask : public Closure ...@@ -1331,17 +1332,23 @@ class ProgramD3D::GetExecutableTask : public Closure
class ProgramD3D::GetVertexExecutableTask : public ProgramD3D::GetExecutableTask class ProgramD3D::GetVertexExecutableTask : public ProgramD3D::GetExecutableTask
{ {
public: public:
GetVertexExecutableTask(ProgramD3D *program) : GetExecutableTask(program) {} GetVertexExecutableTask(ProgramD3D *program, const gl::Context *context)
: GetExecutableTask(program), mContext(context)
{
}
gl::Error run() override gl::Error run() override
{ {
const auto &defaultInputLayout = const auto &defaultInputLayout =
GetDefaultInputLayoutFromShader(mProgram->mState.getAttachedVertexShader()); GetDefaultInputLayoutFromShader(mContext, mProgram->mState.getAttachedVertexShader());
ANGLE_TRY( ANGLE_TRY(
mProgram->getVertexExecutableForInputLayout(defaultInputLayout, &mResult, &mInfoLog)); mProgram->getVertexExecutableForInputLayout(defaultInputLayout, &mResult, &mInfoLog));
return gl::NoError(); return gl::NoError();
} }
private:
const gl::Context *mContext;
}; };
class ProgramD3D::GetPixelExecutableTask : public ProgramD3D::GetExecutableTask class ProgramD3D::GetPixelExecutableTask : public ProgramD3D::GetExecutableTask
...@@ -1395,17 +1402,16 @@ gl::Error ProgramD3D::getComputeExecutable(ShaderExecutableD3D **outExecutable) ...@@ -1395,17 +1402,16 @@ gl::Error ProgramD3D::getComputeExecutable(ShaderExecutableD3D **outExecutable)
return gl::NoError(); return gl::NoError();
} }
LinkResult ProgramD3D::compileProgramExecutables(const gl::ContextState &contextState, LinkResult ProgramD3D::compileProgramExecutables(const gl::Context *context, gl::InfoLog &infoLog)
gl::InfoLog &infoLog)
{ {
// Ensure the compiler is initialized to avoid race conditions. // Ensure the compiler is initialized to avoid race conditions.
ANGLE_TRY(mRenderer->ensureHLSLCompilerInitialized()); ANGLE_TRY(mRenderer->ensureHLSLCompilerInitialized());
WorkerThreadPool *workerPool = mRenderer->getWorkerThreadPool(); WorkerThreadPool *workerPool = mRenderer->getWorkerThreadPool();
GetVertexExecutableTask vertexTask(this); GetVertexExecutableTask vertexTask(this, context);
GetPixelExecutableTask pixelTask(this); GetPixelExecutableTask pixelTask(this);
GetGeometryExecutableTask geometryTask(this, contextState); GetGeometryExecutableTask geometryTask(this, context->getContextState());
std::array<WaitableEvent, 3> waitEvents = {{workerPool->postWorkerTask(&vertexTask), std::array<WaitableEvent, 3> waitEvents = {{workerPool->postWorkerTask(&vertexTask),
workerPool->postWorkerTask(&pixelTask), workerPool->postWorkerTask(&pixelTask),
...@@ -1453,12 +1459,12 @@ LinkResult ProgramD3D::compileProgramExecutables(const gl::ContextState &context ...@@ -1453,12 +1459,12 @@ LinkResult ProgramD3D::compileProgramExecutables(const gl::ContextState &context
(!usesGeometryShader(GL_POINTS) || pointGS)); (!usesGeometryShader(GL_POINTS) || pointGS));
} }
LinkResult ProgramD3D::compileComputeExecutable(gl::InfoLog &infoLog) LinkResult ProgramD3D::compileComputeExecutable(const gl::Context *context, gl::InfoLog &infoLog)
{ {
// Ensure the compiler is initialized to avoid race conditions. // Ensure the compiler is initialized to avoid race conditions.
ANGLE_TRY(mRenderer->ensureHLSLCompilerInitialized()); ANGLE_TRY(mRenderer->ensureHLSLCompilerInitialized());
std::string computeShader = mDynamicHLSL->generateComputeShaderLinkHLSL(mState); std::string computeShader = mDynamicHLSL->generateComputeShaderLinkHLSL(context, mState);
ShaderExecutableD3D *computeExecutable = nullptr; ShaderExecutableD3D *computeExecutable = nullptr;
ANGLE_TRY(mRenderer->compileToExecutable(infoLog, computeShader, SHADER_COMPUTE, ANGLE_TRY(mRenderer->compileToExecutable(infoLog, computeShader, SHADER_COMPUTE,
...@@ -1488,14 +1494,14 @@ LinkResult ProgramD3D::link(const gl::Context *context, ...@@ -1488,14 +1494,14 @@ LinkResult ProgramD3D::link(const gl::Context *context,
reset(); reset();
const gl::Shader *computeShader = mState.getAttachedComputeShader(); gl::Shader *computeShader = mState.getAttachedComputeShader();
if (computeShader) if (computeShader)
{ {
mSamplersCS.resize(data.getCaps().maxComputeTextureImageUnits); mSamplersCS.resize(data.getCaps().maxComputeTextureImageUnits);
defineUniformsAndAssignRegisters(); defineUniformsAndAssignRegisters(context);
LinkResult result = compileComputeExecutable(infoLog); LinkResult result = compileComputeExecutable(context, infoLog);
if (result.isError()) if (result.isError())
{ {
infoLog << result.getError().getMessage(); infoLog << result.getError().getMessage();
...@@ -1507,12 +1513,12 @@ LinkResult ProgramD3D::link(const gl::Context *context, ...@@ -1507,12 +1513,12 @@ LinkResult ProgramD3D::link(const gl::Context *context,
return result; return result;
} }
initUniformBlockInfo(computeShader); initUniformBlockInfo(context, computeShader);
} }
else else
{ {
const gl::Shader *vertexShader = mState.getAttachedVertexShader(); gl::Shader *vertexShader = mState.getAttachedVertexShader();
const gl::Shader *fragmentShader = mState.getAttachedFragmentShader(); gl::Shader *fragmentShader = mState.getAttachedFragmentShader();
const ShaderD3D *vertexShaderD3D = GetImplAs<ShaderD3D>(vertexShader); const ShaderD3D *vertexShaderD3D = GetImplAs<ShaderD3D>(vertexShader);
const ShaderD3D *fragmentShaderD3D = GetImplAs<ShaderD3D>(fragmentShader); const ShaderD3D *fragmentShaderD3D = GetImplAs<ShaderD3D>(fragmentShader);
...@@ -1545,16 +1551,17 @@ LinkResult ProgramD3D::link(const gl::Context *context, ...@@ -1545,16 +1551,17 @@ LinkResult ProgramD3D::link(const gl::Context *context,
ProgramD3DMetadata metadata(mRenderer, vertexShaderD3D, fragmentShaderD3D); ProgramD3DMetadata metadata(mRenderer, vertexShaderD3D, fragmentShaderD3D);
BuiltinVaryingsD3D builtins(metadata, packing); BuiltinVaryingsD3D builtins(metadata, packing);
mDynamicHLSL->generateShaderLinkHLSL(data, mState, metadata, packing, builtins, &mPixelHLSL, mDynamicHLSL->generateShaderLinkHLSL(context, mState, metadata, packing, builtins,
&mVertexHLSL); &mPixelHLSL, &mVertexHLSL);
mUsesPointSize = vertexShaderD3D->usesPointSize(); mUsesPointSize = vertexShaderD3D->usesPointSize();
mDynamicHLSL->getPixelShaderOutputKey(data, mState, metadata, &mPixelShaderKey); mDynamicHLSL->getPixelShaderOutputKey(data, mState, metadata, &mPixelShaderKey);
mUsesFragDepth = metadata.usesFragDepth(); mUsesFragDepth = metadata.usesFragDepth();
// Cache if we use flat shading // Cache if we use flat shading
mUsesFlatInterpolation = (FindFlatInterpolationVarying(fragmentShader->getVaryings()) || mUsesFlatInterpolation =
FindFlatInterpolationVarying(vertexShader->getVaryings())); (FindFlatInterpolationVarying(fragmentShader->getVaryings(context)) ||
FindFlatInterpolationVarying(vertexShader->getVaryings(context)));
if (mRenderer->getMajorShaderModel() >= 4) if (mRenderer->getMajorShaderModel() >= 4)
{ {
...@@ -1562,13 +1569,13 @@ LinkResult ProgramD3D::link(const gl::Context *context, ...@@ -1562,13 +1569,13 @@ LinkResult ProgramD3D::link(const gl::Context *context,
mDynamicHLSL->generateGeometryShaderPreamble(packing, builtins); mDynamicHLSL->generateGeometryShaderPreamble(packing, builtins);
} }
initAttribLocationsToD3DSemantic(); initAttribLocationsToD3DSemantic(context);
defineUniformsAndAssignRegisters(); defineUniformsAndAssignRegisters(context);
gatherTransformFeedbackVaryings(packing, builtins[SHADER_VERTEX]); gatherTransformFeedbackVaryings(packing, builtins[SHADER_VERTEX]);
LinkResult result = compileProgramExecutables(data, infoLog); LinkResult result = compileProgramExecutables(context, infoLog);
if (result.isError()) if (result.isError())
{ {
infoLog << result.getError().getMessage(); infoLog << result.getError().getMessage();
...@@ -1580,8 +1587,8 @@ LinkResult ProgramD3D::link(const gl::Context *context, ...@@ -1580,8 +1587,8 @@ LinkResult ProgramD3D::link(const gl::Context *context,
return result; return result;
} }
initUniformBlockInfo(vertexShader); initUniformBlockInfo(context, vertexShader);
initUniformBlockInfo(fragmentShader); initUniformBlockInfo(context, fragmentShader);
} }
return true; return true;
...@@ -1593,9 +1600,9 @@ GLboolean ProgramD3D::validate(const gl::Caps & /*caps*/, gl::InfoLog * /*infoLo ...@@ -1593,9 +1600,9 @@ GLboolean ProgramD3D::validate(const gl::Caps & /*caps*/, gl::InfoLog * /*infoLo
return GL_TRUE; return GL_TRUE;
} }
void ProgramD3D::initUniformBlockInfo(const gl::Shader *shader) void ProgramD3D::initUniformBlockInfo(const gl::Context *context, gl::Shader *shader)
{ {
for (const sh::InterfaceBlock &interfaceBlock : shader->getInterfaceBlocks()) for (const sh::InterfaceBlock &interfaceBlock : shader->getInterfaceBlocks(context))
{ {
if (!interfaceBlock.staticUse && interfaceBlock.layout == sh::BLOCKLAYOUT_PACKED) if (!interfaceBlock.staticUse && interfaceBlock.layout == sh::BLOCKLAYOUT_PACKED)
continue; continue;
...@@ -1923,13 +1930,13 @@ void ProgramD3D::setUniformBlockBinding(GLuint /*uniformBlockIndex*/, ...@@ -1923,13 +1930,13 @@ void ProgramD3D::setUniformBlockBinding(GLuint /*uniformBlockIndex*/,
{ {
} }
void ProgramD3D::defineUniformsAndAssignRegisters() void ProgramD3D::defineUniformsAndAssignRegisters(const gl::Context *context)
{ {
D3DUniformMap uniformMap; D3DUniformMap uniformMap;
const gl::Shader *computeShader = mState.getAttachedComputeShader(); gl::Shader *computeShader = mState.getAttachedComputeShader();
if (computeShader) if (computeShader)
{ {
for (const sh::Uniform &computeUniform : computeShader->getUniforms()) for (const sh::Uniform &computeUniform : computeShader->getUniforms(context))
{ {
if (computeUniform.staticUse) if (computeUniform.staticUse)
{ {
...@@ -1939,8 +1946,8 @@ void ProgramD3D::defineUniformsAndAssignRegisters() ...@@ -1939,8 +1946,8 @@ void ProgramD3D::defineUniformsAndAssignRegisters()
} }
else else
{ {
const gl::Shader *vertexShader = mState.getAttachedVertexShader(); gl::Shader *vertexShader = mState.getAttachedVertexShader();
for (const sh::Uniform &vertexUniform : vertexShader->getUniforms()) for (const sh::Uniform &vertexUniform : vertexShader->getUniforms(context))
{ {
if (vertexUniform.staticUse) if (vertexUniform.staticUse)
{ {
...@@ -1948,8 +1955,8 @@ void ProgramD3D::defineUniformsAndAssignRegisters() ...@@ -1948,8 +1955,8 @@ void ProgramD3D::defineUniformsAndAssignRegisters()
} }
} }
const gl::Shader *fragmentShader = mState.getAttachedFragmentShader(); gl::Shader *fragmentShader = mState.getAttachedFragmentShader();
for (const sh::Uniform &fragmentUniform : fragmentShader->getUniforms()) for (const sh::Uniform &fragmentUniform : fragmentShader->getUniforms(context))
{ {
if (fragmentUniform.staticUse) if (fragmentUniform.staticUse)
{ {
...@@ -2360,15 +2367,15 @@ unsigned int ProgramD3D::issueSerial() ...@@ -2360,15 +2367,15 @@ unsigned int ProgramD3D::issueSerial()
return mCurrentSerial++; return mCurrentSerial++;
} }
void ProgramD3D::initAttribLocationsToD3DSemantic() void ProgramD3D::initAttribLocationsToD3DSemantic(const gl::Context *context)
{ {
const gl::Shader *vertexShader = mState.getAttachedVertexShader(); gl::Shader *vertexShader = mState.getAttachedVertexShader();
ASSERT(vertexShader != nullptr); ASSERT(vertexShader != nullptr);
// Init semantic index // Init semantic index
for (const sh::Attribute &attribute : mState.getAttributes()) for (const sh::Attribute &attribute : mState.getAttributes())
{ {
int d3dSemantic = vertexShader->getSemanticIndex(attribute.name); int d3dSemantic = vertexShader->getSemanticIndex(context, attribute.name);
int regCount = gl::VariableRegisterCount(attribute.type); int regCount = gl::VariableRegisterCount(attribute.type);
for (int reg = 0; reg < regCount; ++reg) for (int reg = 0; reg < regCount; ++reg)
......
...@@ -336,7 +336,7 @@ class ProgramD3D : public ProgramImpl ...@@ -336,7 +336,7 @@ class ProgramD3D : public ProgramImpl
typedef std::map<std::string, D3DUniform *> D3DUniformMap; typedef std::map<std::string, D3DUniform *> D3DUniformMap;
void defineUniformsAndAssignRegisters(); void defineUniformsAndAssignRegisters(const gl::Context *context);
void defineUniformBase(const gl::Shader *shader, void defineUniformBase(const gl::Shader *shader,
const sh::Uniform &uniform, const sh::Uniform &uniform,
D3DUniformMap *uniformMap); D3DUniformMap *uniformMap);
...@@ -364,20 +364,20 @@ class ProgramD3D : public ProgramImpl ...@@ -364,20 +364,20 @@ class ProgramD3D : public ProgramImpl
const GLfloat *value, const GLfloat *value,
GLenum targetUniformType); GLenum targetUniformType);
LinkResult compileProgramExecutables(const gl::ContextState &data, gl::InfoLog &infoLog); LinkResult compileProgramExecutables(const gl::Context *context, gl::InfoLog &infoLog);
LinkResult compileComputeExecutable(gl::InfoLog &infoLog); LinkResult compileComputeExecutable(const gl::Context *context, gl::InfoLog &infoLog);
void gatherTransformFeedbackVaryings(const gl::VaryingPacking &varyings, void gatherTransformFeedbackVaryings(const gl::VaryingPacking &varyings,
const BuiltinInfo &builtins); const BuiltinInfo &builtins);
D3DUniform *getD3DUniformByName(const std::string &name); D3DUniform *getD3DUniformByName(const std::string &name);
D3DUniform *getD3DUniformFromLocation(GLint location); D3DUniform *getD3DUniformFromLocation(GLint location);
void initAttribLocationsToD3DSemantic(); void initAttribLocationsToD3DSemantic(const gl::Context *context);
void reset(); void reset();
void ensureUniformBlocksInitialized(); void ensureUniformBlocksInitialized();
void initUniformBlockInfo(const gl::Shader *shader); void initUniformBlockInfo(const gl::Context *context, gl::Shader *shader);
size_t getUniformBlockInfo(const sh::InterfaceBlock &interfaceBlock); size_t getUniformBlockInfo(const sh::InterfaceBlock &interfaceBlock);
RendererD3D *mRenderer; RendererD3D *mRenderer;
......
...@@ -67,8 +67,10 @@ LinkResult ProgramVk::link(const gl::Context *glContext, ...@@ -67,8 +67,10 @@ LinkResult ProgramVk::link(const gl::Context *glContext,
RendererVk *renderer = context->getRenderer(); RendererVk *renderer = context->getRenderer();
GlslangWrapper *glslangWrapper = renderer->getGlslangWrapper(); GlslangWrapper *glslangWrapper = renderer->getGlslangWrapper();
const std::string &vertexSource = mState.getAttachedVertexShader()->getTranslatedSource(); const std::string &vertexSource =
const std::string &fragmentSource = mState.getAttachedFragmentShader()->getTranslatedSource(); mState.getAttachedVertexShader()->getTranslatedSource(glContext);
const std::string &fragmentSource =
mState.getAttachedFragmentShader()->getTranslatedSource(glContext);
std::vector<uint32_t> vertexCode; std::vector<uint32_t> vertexCode;
std::vector<uint32_t> fragmentCode; std::vector<uint32_t> fragmentCode;
......
...@@ -3527,7 +3527,7 @@ bool ValidateProgramPathFragmentInputGen(Context *context, ...@@ -3527,7 +3527,7 @@ bool ValidateProgramPathFragmentInputGen(Context *context,
if (location == -1) if (location == -1)
return true; return true;
const auto &binding = programObject->getFragmentInputBindingInfo(location); const auto &binding = programObject->getFragmentInputBindingInfo(context, location);
if (!binding.valid) if (!binding.valid)
{ {
......
...@@ -452,7 +452,7 @@ void GL_APIENTRY GetTranslatedShaderSourceANGLE(GLuint shader, ...@@ -452,7 +452,7 @@ void GL_APIENTRY GetTranslatedShaderSourceANGLE(GLuint shader,
return; return;
} }
shaderObject->getTranslatedSourceWithDebugInfo(bufsize, length, source); shaderObject->getTranslatedSourceWithDebugInfo(context, bufsize, length, source);
} }
} }
...@@ -2230,7 +2230,7 @@ GetShaderivRobustANGLE(GLuint shader, GLenum pname, GLsizei bufSize, GLsizei *le ...@@ -2230,7 +2230,7 @@ GetShaderivRobustANGLE(GLuint shader, GLenum pname, GLsizei bufSize, GLsizei *le
} }
Shader *shaderObject = context->getShader(shader); Shader *shaderObject = context->getShader(shader);
QueryShaderiv(shaderObject, pname, params); QueryShaderiv(context, shaderObject, pname, params);
SetRobustLengthParam(length, numParams); SetRobustLengthParam(length, numParams);
} }
} }
......
...@@ -506,7 +506,7 @@ GLuint ANGLETest::compileShader(GLenum type, const std::string &source) ...@@ -506,7 +506,7 @@ GLuint ANGLETest::compileShader(GLenum type, const std::string &source)
std::vector<GLchar> infoLog(infoLogLength); std::vector<GLchar> infoLog(infoLogLength);
glGetShaderInfoLog(shader, static_cast<GLsizei>(infoLog.size()), nullptr, &infoLog[0]); glGetShaderInfoLog(shader, static_cast<GLsizei>(infoLog.size()), nullptr, &infoLog[0]);
std::cerr << "shader compilation failed: " << &infoLog[0]; std::cerr << "shader compilation failed: " << &infoLog[0] << std::endl;
} }
glDeleteShader(shader); glDeleteShader(shader);
......
...@@ -59,6 +59,8 @@ GLuint CompileShader(GLenum type, const std::string &source) ...@@ -59,6 +59,8 @@ GLuint CompileShader(GLenum type, const std::string &source)
std::cerr << "shader compilation failed. <Empty log message>"; std::cerr << "shader compilation failed. <Empty log message>";
} }
std::cerr << std::endl;
glDeleteShader(shader); glDeleteShader(shader);
shader = 0; shader = 0;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment