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