Commit ea918db9 by Jamie Madill

Clean up Program::linkUniforms.

This method previously relied on output from the D3D back-end from ProgramImpl::link. Split the D3D-specific code into its own method, and do the linking validation before we call link. BUG=angleproject:1123 Change-Id: I582671e21af605af9f4451b02fc96ad29c923048 Reviewed-on: https://chromium-review.googlesource.com/293762Reviewed-by: 's avatarCorentin Wallez <cwallez@chromium.org> Tested-by: 's avatarJamie Madill <jmadill@chromium.org>
parent 70022972
......@@ -295,6 +295,11 @@ Error Program::link(const gl::Data &data)
return Error(GL_NO_ERROR);
}
if (!linkUniforms(mInfoLog, *data.caps))
{
return Error(GL_NO_ERROR);
}
int registers;
std::vector<LinkedVarying> linkedVaryings;
rx::LinkResult result =
......@@ -305,12 +310,6 @@ Error Program::link(const gl::Data &data)
return result.error;
}
if (!mProgram->linkUniforms(mInfoLog, *mData.mAttachedVertexShader,
*mData.mAttachedFragmentShader, *data.caps))
{
return Error(GL_NO_ERROR);
}
if (!linkUniformBlocks(mInfoLog, *mData.mAttachedVertexShader, *mData.mAttachedFragmentShader,
*data.caps))
{
......@@ -1290,6 +1289,37 @@ bool Program::linkVaryings(InfoLog &infoLog,
return true;
}
bool Program::linkUniforms(gl::InfoLog &infoLog, const gl::Caps & /*caps*/) const
{
const std::vector<sh::Uniform> &vertexUniforms = mData.mAttachedVertexShader->getUniforms();
const std::vector<sh::Uniform> &fragmentUniforms = mData.mAttachedFragmentShader->getUniforms();
// Check that uniforms defined in the vertex and fragment shaders are identical
std::map<std::string, const sh::Uniform *> linkedUniforms;
for (const sh::Uniform &vertexUniform : vertexUniforms)
{
linkedUniforms[vertexUniform.name] = &vertexUniform;
}
for (const sh::Uniform &fragmentUniform : fragmentUniforms)
{
auto entry = linkedUniforms.find(fragmentUniform.name);
if (entry != linkedUniforms.end())
{
const sh::Uniform &vertexUniform = *entry->second;
const std::string &uniformName = "uniform '" + vertexUniform.name + "'";
if (!linkValidateUniforms(infoLog, uniformName, vertexUniform, fragmentUniform))
{
return false;
}
}
}
// TODO(jmadill): check sampler uniforms with caps
return true;
}
bool Program::linkValidateInterfaceBlockFields(InfoLog &infoLog, const std::string &uniformName, const sh::InterfaceBlockField &vertexUniform, const sh::InterfaceBlockField &fragmentUniform)
{
if (!linkValidateVariablesBase(infoLog, uniformName, vertexUniform, fragmentUniform, true))
......
......@@ -312,6 +312,7 @@ class Program : angle::NonCopyable
static bool linkVaryings(InfoLog &infoLog,
const Shader *vertexShader,
const Shader *fragmentShader);
bool linkUniforms(gl::InfoLog &infoLog, const gl::Caps &caps) const;
bool areMatchingInterfaceBlocks(gl::InfoLog &infoLog, const sh::InterfaceBlock &vertexInterfaceBlock,
const sh::InterfaceBlock &fragmentInterfaceBlock);
......
......@@ -86,8 +86,6 @@ class ProgramImpl : angle::NonCopyable
virtual LinkResult compileProgramExecutables(gl::InfoLog &infoLog, int registers) = 0;
virtual bool linkUniforms(gl::InfoLog &infoLog, const gl::Shader &vertexShader, const gl::Shader &fragmentShader,
const gl::Caps &caps) = 0;
virtual bool defineUniformBlock(gl::InfoLog &infoLog, const gl::Shader &shader, const sh::InterfaceBlock &interfaceBlock,
const gl::Caps &caps) = 0;
......
......@@ -1147,6 +1147,11 @@ LinkResult ProgramD3D::link(const gl::Data &data, gl::InfoLog &infoLog,
initAttributesByLayout();
if (!defineUniforms(infoLog, *data.caps))
{
return LinkResult(false, gl::Error(GL_NO_ERROR));
}
return LinkResult(true, gl::Error(GL_NO_ERROR));
}
......@@ -1406,44 +1411,14 @@ void ProgramD3D::getUniformuiv(GLint location, GLuint *params)
getUniformv(location, params, GL_UNSIGNED_INT);
}
bool ProgramD3D::linkUniforms(gl::InfoLog &infoLog, const gl::Shader &vertexShader, const gl::Shader &fragmentShader,
const gl::Caps &caps)
bool ProgramD3D::defineUniforms(gl::InfoLog &infoLog, const gl::Caps &caps)
{
const ShaderD3D *vertexShaderD3D = GetImplAs<ShaderD3D>(&vertexShader);
const ShaderD3D *fragmentShaderD3D = GetImplAs<ShaderD3D>(&fragmentShader);
const std::vector<sh::Uniform> &vertexUniforms = vertexShader.getUniforms();
const std::vector<sh::Uniform> &fragmentUniforms = fragmentShader.getUniforms();
// Check that uniforms defined in the vertex and fragment shaders are identical
typedef std::map<std::string, const sh::Uniform*> UniformMap;
UniformMap linkedUniforms;
for (unsigned int vertexUniformIndex = 0; vertexUniformIndex < vertexUniforms.size(); vertexUniformIndex++)
{
const sh::Uniform &vertexUniform = vertexUniforms[vertexUniformIndex];
linkedUniforms[vertexUniform.name] = &vertexUniform;
}
for (unsigned int fragmentUniformIndex = 0; fragmentUniformIndex < fragmentUniforms.size(); fragmentUniformIndex++)
{
const sh::Uniform &fragmentUniform = fragmentUniforms[fragmentUniformIndex];
UniformMap::const_iterator entry = linkedUniforms.find(fragmentUniform.name);
if (entry != linkedUniforms.end())
{
const sh::Uniform &vertexUniform = *entry->second;
const std::string &uniformName = "uniform '" + vertexUniform.name + "'";
if (!gl::Program::linkValidateUniforms(infoLog, uniformName, vertexUniform, fragmentUniform))
{
return false;
}
}
}
const gl::Shader *vertexShader = mData.getAttachedVertexShader();
const std::vector<sh::Uniform> &vertexUniforms = vertexShader->getUniforms();
const ShaderD3D *vertexShaderD3D = GetImplAs<ShaderD3D>(vertexShader);
for (unsigned int uniformIndex = 0; uniformIndex < vertexUniforms.size(); uniformIndex++)
for (const sh::Uniform &uniform : vertexUniforms)
{
const sh::Uniform &uniform = vertexUniforms[uniformIndex];
if (uniform.staticUse)
{
unsigned int registerBase = uniform.isBuiltIn() ? GL_INVALID_INDEX :
......@@ -1452,10 +1427,12 @@ bool ProgramD3D::linkUniforms(gl::InfoLog &infoLog, const gl::Shader &vertexShad
}
}
for (unsigned int uniformIndex = 0; uniformIndex < fragmentUniforms.size(); uniformIndex++)
{
const sh::Uniform &uniform = fragmentUniforms[uniformIndex];
const gl::Shader *fragmentShader = mData.getAttachedFragmentShader();
const std::vector<sh::Uniform> &fragmentUniforms = fragmentShader->getUniforms();
const ShaderD3D *fragmentShaderD3D = GetImplAs<ShaderD3D>(fragmentShader);
for (const sh::Uniform &uniform : fragmentUniforms)
{
if (uniform.staticUse)
{
unsigned int registerBase = uniform.isBuiltIn() ? GL_INVALID_INDEX :
......@@ -1464,6 +1441,7 @@ bool ProgramD3D::linkUniforms(gl::InfoLog &infoLog, const gl::Shader &vertexShad
}
}
// TODO(jmadill): move the validation part to gl::Program
if (!indexUniforms(infoLog, caps))
{
return false;
......
......@@ -113,8 +113,6 @@ class ProgramD3D : public ProgramImpl
const UniformStorageD3D &getVertexUniformStorage() const { return *mVertexUniformStorage; }
const UniformStorageD3D &getFragmentUniformStorage() const { return *mFragmentUniformStorage; }
bool linkUniforms(gl::InfoLog &infoLog, const gl::Shader &vertexShader, const gl::Shader &fragmentShader,
const gl::Caps &caps);
bool defineUniformBlock(gl::InfoLog &infoLog, const gl::Shader &shader, const sh::InterfaceBlock &interfaceBlock, const gl::Caps &caps);
void reset();
......@@ -180,6 +178,7 @@ class ProgramD3D : public ProgramImpl
GLenum textureType;
};
bool defineUniforms(gl::InfoLog &infoLog, const gl::Caps &caps);
void defineUniformBase(const ShaderD3D *shader, const sh::Uniform &uniform, unsigned int uniformRegister);
void defineUniform(const ShaderD3D *shader, const sh::ShaderVariable &uniform, const std::string &fullName,
sh::HLSLBlockEncoder *encoder);
......
......@@ -395,13 +395,6 @@ LinkResult ProgramGL::compileProgramExecutables(gl::InfoLog &infoLog, int regist
return LinkResult(true, gl::Error(GL_NO_ERROR));
}
bool ProgramGL::linkUniforms(gl::InfoLog &infoLog, const gl::Shader &vertexShader, const gl::Shader &fragmentShader,
const gl::Caps &caps)
{
//UNIMPLEMENTED();
return true;
}
bool ProgramGL::defineUniformBlock(gl::InfoLog &infoLog, const gl::Shader &shader, const sh::InterfaceBlock &interfaceBlock,
const gl::Caps &caps)
{
......
......@@ -79,8 +79,6 @@ class ProgramGL : public ProgramImpl
LinkResult compileProgramExecutables(gl::InfoLog &infoLog, int registers) override;
bool linkUniforms(gl::InfoLog &infoLog, const gl::Shader &vertexShader, const gl::Shader &fragmentShader,
const gl::Caps &caps) override;
bool defineUniformBlock(gl::InfoLog &infoLog, const gl::Shader &shader, const sh::InterfaceBlock &interfaceBlock,
const gl::Caps &caps) override;
......
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