Commit 27a60631 by Jamie Madill

Re-apply UBO binding workaround on program save.

The workaround which was previously defined to only apply on load also seems to affect save on some AMD drivers. BUG=angleproject:1637 BUG=angleproject:1897 Change-Id: Ia01a1420a484f3c2682ce97eaab18baccfb66a50 Reviewed-on: https://chromium-review.googlesource.com/558008Reviewed-by: 's avatarYuly Novikov <ynovikov@chromium.org> Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org>
parent b12040c4
......@@ -437,7 +437,7 @@ void MemoryProgramCache::Serialize(const Context *context,
stream.writeInt(imageBinding.elementCount);
}
program->getImplementation()->save(&stream);
program->getImplementation()->save(context, &stream);
ASSERT(binaryOut);
binaryOut->resize(stream.length());
......
......@@ -41,7 +41,7 @@ class ProgramImpl : angle::NonCopyable
virtual gl::LinkResult load(const gl::Context *context,
gl::InfoLog &infoLog,
gl::BinaryInputStream *stream) = 0;
virtual void save(gl::BinaryOutputStream *stream) = 0;
virtual void save(const gl::Context *context, gl::BinaryOutputStream *stream) = 0;
virtual void setBinaryRetrievableHint(bool retrievable) = 0;
virtual void setSeparable(bool separable) = 0;
......
......@@ -24,7 +24,7 @@ class MockProgramImpl : public rx::ProgramImpl
virtual ~MockProgramImpl() { destructor(); }
MOCK_METHOD3(load, gl::LinkResult(const gl::Context *, gl::InfoLog &, gl::BinaryInputStream *));
MOCK_METHOD1(save, void(gl::BinaryOutputStream *));
MOCK_METHOD2(save, void(const gl::Context *, gl::BinaryOutputStream *));
MOCK_METHOD1(setBinaryRetrievableHint, void(bool));
MOCK_METHOD1(setSeparable, void(bool));
......
......@@ -959,7 +959,7 @@ gl::LinkResult ProgramD3D::load(const gl::Context *context,
return true;
}
void ProgramD3D::save(gl::BinaryOutputStream *stream)
void ProgramD3D::save(const gl::Context *context, gl::BinaryOutputStream *stream)
{
// Output the DeviceIdentifier before we output any shader code
// When we load the binary again later, we can validate the device identifier before trying to
......
......@@ -161,7 +161,7 @@ class ProgramD3D : public ProgramImpl
gl::LinkResult load(const gl::Context *context,
gl::InfoLog &infoLog,
gl::BinaryInputStream *stream) override;
void save(gl::BinaryOutputStream *stream) override;
void save(const gl::Context *context, gl::BinaryOutputStream *stream) override;
void setBinaryRetrievableHint(bool retrievable) override;
void setSeparable(bool separable) override;
......
......@@ -71,22 +71,12 @@ gl::LinkResult ProgramGL::load(const gl::Context *context,
}
postLink();
// Re-apply UBO bindings to work around driver bugs.
const WorkaroundsGL &workaroundsGL = GetImplAs<ContextGL>(context)->getWorkaroundsGL();
if (workaroundsGL.reapplyUBOBindingsAfterLoadingBinaryProgram)
{
const auto &blocks = mState.getUniformBlocks();
for (size_t blockIndex : mState.getActiveUniformBlockBindingsMask())
{
setUniformBlockBinding(static_cast<GLuint>(blockIndex), blocks[blockIndex].binding);
}
}
reapplyUBOBindingsIfNeeded(context);
return true;
}
void ProgramGL::save(gl::BinaryOutputStream *stream)
void ProgramGL::save(const gl::Context *context, gl::BinaryOutputStream *stream)
{
GLint binaryLength = 0;
mFunctions->getProgramiv(mProgramID, GL_PROGRAM_BINARY_LENGTH, &binaryLength);
......@@ -99,6 +89,22 @@ void ProgramGL::save(gl::BinaryOutputStream *stream)
stream->writeInt(binaryFormat);
stream->writeInt(binaryLength);
stream->writeBytes(&binary[0], binaryLength);
reapplyUBOBindingsIfNeeded(context);
}
void ProgramGL::reapplyUBOBindingsIfNeeded(const gl::Context *context)
{
// Re-apply UBO bindings to work around driver bugs.
const WorkaroundsGL &workaroundsGL = GetImplAs<ContextGL>(context)->getWorkaroundsGL();
if (workaroundsGL.reapplyUBOBindingsAfterUsingBinaryProgram)
{
const auto &blocks = mState.getUniformBlocks();
for (size_t blockIndex : mState.getActiveUniformBlockBindingsMask())
{
setUniformBlockBinding(static_cast<GLuint>(blockIndex), blocks[blockIndex].binding);
}
}
}
void ProgramGL::setBinaryRetrievableHint(bool retrievable)
......
......@@ -34,7 +34,7 @@ class ProgramGL : public ProgramImpl
gl::LinkResult load(const gl::Context *contextImpl,
gl::InfoLog &infoLog,
gl::BinaryInputStream *stream) override;
void save(gl::BinaryOutputStream *stream) override;
void save(const gl::Context *context, gl::BinaryOutputStream *stream) override;
void setBinaryRetrievableHint(bool retrievable) override;
void setSeparable(bool separable) override;
......@@ -82,6 +82,7 @@ class ProgramGL : public ProgramImpl
void preLink();
bool checkLinkStatus(gl::InfoLog &infoLog);
void postLink();
void reapplyUBOBindingsIfNeeded(const gl::Context *context);
// Helper function, makes it simpler to type.
GLint uniLoc(GLint glLocation) const { return mUniformRealLocationMap[glLocation]; }
......
......@@ -114,11 +114,11 @@ struct WorkaroundsGL
// Tracking bug: http://crbug.com/672380
bool emulateAtan2Float = false;
// Some drivers seem to forget about UBO bindings when loading program binaries. Work around
// this by re-applying the bindings after the program binary is loaded.
// Some drivers seem to forget about UBO bindings when using program binaries. Work around
// this by re-applying the bindings after the program binary is loaded or saved.
// This only seems to affect AMD OpenGL drivers, and some Android devices.
// http://anglebug.com/1637
bool reapplyUBOBindingsAfterLoadingBinaryProgram = false;
bool reapplyUBOBindingsAfterUsingBinaryProgram = false;
// Some OpenGL drivers return 0 when we query MAX_VERTEX_ATTRIB_STRIDE in an OpenGL 4.4 or
// higher context.
......
......@@ -998,11 +998,11 @@ void GenerateWorkarounds(const FunctionsGL *functions, WorkaroundsGL *workaround
// 364 are known to be affected, at least up to 375.
workarounds->emulateAtan2Float = IsNvidia(vendor);
workarounds->reapplyUBOBindingsAfterLoadingBinaryProgram = IsAMD(vendor);
workarounds->reapplyUBOBindingsAfterUsingBinaryProgram = IsAMD(vendor);
#if defined(ANGLE_PLATFORM_ANDROID)
// TODO(jmadill): Narrow workaround range for specific devices.
workarounds->reapplyUBOBindingsAfterLoadingBinaryProgram = true;
workarounds->reapplyUBOBindingsAfterUsingBinaryProgram = true;
#endif
}
......
......@@ -29,7 +29,7 @@ gl::LinkResult ProgramNULL::load(const gl::Context *contextImpl,
return true;
}
void ProgramNULL::save(gl::BinaryOutputStream *stream)
void ProgramNULL::save(const gl::Context *context, gl::BinaryOutputStream *stream)
{
}
......
......@@ -24,7 +24,7 @@ class ProgramNULL : public ProgramImpl
gl::LinkResult load(const gl::Context *context,
gl::InfoLog &infoLog,
gl::BinaryInputStream *stream) override;
void save(gl::BinaryOutputStream *stream) override;
void save(const gl::Context *context, gl::BinaryOutputStream *stream) override;
void setBinaryRetrievableHint(bool retrievable) override;
void setSeparable(bool separable) override;
......
......@@ -43,7 +43,7 @@ gl::LinkResult ProgramVk::load(const gl::Context *contextImpl,
return gl::InternalError();
}
void ProgramVk::save(gl::BinaryOutputStream *stream)
void ProgramVk::save(const gl::Context *context, gl::BinaryOutputStream *stream)
{
UNIMPLEMENTED();
}
......
......@@ -26,7 +26,7 @@ class ProgramVk : public ProgramImpl
gl::LinkResult load(const gl::Context *context,
gl::InfoLog &infoLog,
gl::BinaryInputStream *stream) override;
void save(gl::BinaryOutputStream *stream) override;
void save(const gl::Context *context, gl::BinaryOutputStream *stream) override;
void setBinaryRetrievableHint(bool retrievable) override;
void setSeparable(bool separable) override;
......
......@@ -676,13 +676,6 @@ TEST_P(UniformBufferTest31, MaxUniformBufferBindingsExceeded)
// Test uniform block bindings specified by layout in shader work properly.
TEST_P(UniformBufferTest31, UniformBufferBindings)
{
// TODO(jmadill): Figure out why this fails on Linux AMD OpenGL
if (IsLinux() && IsAMD() && IsDesktopOpenGL())
{
std::cout << "Test skipped on Linux OpenGL on AMD." << std::endl;
return;
}
const std::string &vertexShaderSource =
"#version 310 es\n"
"in vec4 position;\n"
......@@ -748,13 +741,6 @@ TEST_P(UniformBufferTest31, UniformBufferBindings)
// Test uniform blocks used as instanced array take next binding point for each subsequent element.
TEST_P(UniformBufferTest31, ConsecutiveBindingsForBlockArray)
{
// TODO(jmadill): Figure out why this fails on Linux AMD OpenGL
if (IsLinux() && IsAMD() && IsDesktopOpenGL())
{
std::cout << "Test skipped on Linux OpenGL on AMD." << std::endl;
return;
}
const std::string &vertexShaderSource =
"#version 310 es\n"
"in vec4 position;\n"
......
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