D3D11: Fix program binary crash with UBO bindings.
This crash could occur when saving and loading a program with UBO
bindings that was never used in a draw operation. The fix is to
ensure the D3DLinkedUniforms are properly initialized before we
save the program binary.
BUG=angleproject:1637
Change-Id: I9691e375d19dc628f34f351ae94b68bd0f2f76b8
Reviewed-on: https://chromium-review.googlesource.com/422665
Commit-Queue: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
diff --git a/src/libANGLE/renderer/d3d/ProgramD3D.cpp b/src/libANGLE/renderer/d3d/ProgramD3D.cpp
index b9f6c0a..fb224c8 100644
--- a/src/libANGLE/renderer/d3d/ProgramD3D.cpp
+++ b/src/libANGLE/renderer/d3d/ProgramD3D.cpp
@@ -1037,6 +1037,10 @@
stream->writeInt(uniform->registerElement);
}
+ // Ensure we init the uniform block structure data if we should.
+ // http://anglebug.com/1637
+ ensureUniformBlocksInitialized();
+
stream->writeInt(mD3DUniformBlocks.size());
for (const D3DUniformBlock &uniformBlock : mD3DUniformBlocks)
{
@@ -1131,7 +1135,7 @@
stream->writeBytes(geometryExe->getFunction(), geometryShaderSize);
}
- return gl::Error(GL_NO_ERROR);
+ return gl::NoError();
}
void ProgramD3D::setBinaryRetrievableHint(bool /* retrievable */)
@@ -1174,7 +1178,7 @@
if (mPixelExecutables[executableIndex]->matchesSignature(outputSignature))
{
*outExectuable = mPixelExecutables[executableIndex]->shaderExecutable();
- return gl::Error(GL_NO_ERROR);
+ return gl::NoError();
}
}
@@ -1218,7 +1222,7 @@
if (mVertexExecutables[executableIndex]->matchesSignature(mCachedVertexSignature))
{
*outExectuable = mVertexExecutables[executableIndex]->shaderExecutable();
- return gl::Error(GL_NO_ERROR);
+ return gl::NoError();
}
}
@@ -1266,7 +1270,7 @@
// Return a null shader if the current rendering doesn't use a geometry shader
if (!usesGeometryShader(drawMode))
{
- return gl::Error(GL_NO_ERROR);
+ return gl::NoError();
}
gl::PrimitiveType geometryShaderType = GetGeometryShaderTypeFromDrawMode(drawMode);
@@ -1277,7 +1281,7 @@
{
*outExecutable = mGeometryExecutables[geometryShaderType];
}
- return gl::Error(GL_NO_ERROR);
+ return gl::NoError();
}
std::string geometryHLSL = mDynamicHLSL->generateGeometryShaderHLSL(
@@ -1588,9 +1592,13 @@
}
}
-void ProgramD3D::assignUniformBlockRegisters()
+void ProgramD3D::ensureUniformBlocksInitialized()
{
- mD3DUniformBlocks.clear();
+ // Lazy init.
+ if (mState.getUniformBlocks().empty() || !mD3DUniformBlocks.empty())
+ {
+ return;
+ }
// Assign registers and update sizes.
const ShaderD3D *vertexShaderD3D = GetImplAs<ShaderD3D>(mState.getAttachedVertexShader());
@@ -1657,21 +1665,17 @@
d3dUniform->dirty = false;
}
- return gl::Error(GL_NO_ERROR);
+ return gl::NoError();
}
gl::Error ProgramD3D::applyUniformBuffers(const gl::ContextState &data)
{
if (mState.getUniformBlocks().empty())
{
- return gl::Error(GL_NO_ERROR);
+ return gl::NoError();
}
- // Lazy init.
- if (mD3DUniformBlocks.empty())
- {
- assignUniformBlockRegisters();
- }
+ ensureUniformBlocksInitialized();
mVertexUBOCache.clear();
mFragmentUBOCache.clear();