Commit 4091119b by Philippe Hamel Committed by Corentin Wallez

Add workaround to always call useProgram after a successful link.

This workaround is meant to reproduce the behavior of the use_current_program_after_successful_link workaround in Chromium (http://crbug.com/110263) The workaround was shown to be unnecessary for MacOSX 10.9 and higher (http://crrev.com/39eb535b). BUG=349137 Change-Id: I3023f053aa1593ba7044a889dd47746b8f7e0581 Reviewed-on: https://chromium-review.googlesource.com/337780Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org> Commit-Queue: Jamie Madill <jmadill@chromium.org> Commit-Queue: Geoff Lang <geofflang@chromium.org>
parent 53a36004
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
#include "libANGLE/renderer/gl/FunctionsGL.h" #include "libANGLE/renderer/gl/FunctionsGL.h"
#include "libANGLE/renderer/gl/ShaderGL.h" #include "libANGLE/renderer/gl/ShaderGL.h"
#include "libANGLE/renderer/gl/StateManagerGL.h" #include "libANGLE/renderer/gl/StateManagerGL.h"
#include "libANGLE/renderer/gl/WorkaroundsGL.h"
#include "platform/Platform.h" #include "platform/Platform.h"
namespace rx namespace rx
...@@ -20,8 +21,13 @@ namespace rx ...@@ -20,8 +21,13 @@ namespace rx
ProgramGL::ProgramGL(const gl::Program::Data &data, ProgramGL::ProgramGL(const gl::Program::Data &data,
const FunctionsGL *functions, const FunctionsGL *functions,
const WorkaroundsGL &workarounds,
StateManagerGL *stateManager) StateManagerGL *stateManager)
: ProgramImpl(data), mFunctions(functions), mStateManager(stateManager), mProgramID(0) : ProgramImpl(data),
mFunctions(functions),
mWorkarounds(workarounds),
mStateManager(stateManager),
mProgramID(0)
{ {
ASSERT(mFunctions); ASSERT(mFunctions);
ASSERT(mStateManager); ASSERT(mStateManager);
...@@ -144,6 +150,11 @@ LinkResult ProgramGL::link(const gl::Data &data, gl::InfoLog &infoLog) ...@@ -144,6 +150,11 @@ LinkResult ProgramGL::link(const gl::Data &data, gl::InfoLog &infoLog)
return LinkResult(false, gl::Error(GL_NO_ERROR)); return LinkResult(false, gl::Error(GL_NO_ERROR));
} }
if (mWorkarounds.alwaysCallUseProgramAfterLink)
{
mStateManager->forceUseProgram(mProgramID);
}
// Query the uniform information // Query the uniform information
ASSERT(mUniformRealLocationMap.empty()); ASSERT(mUniformRealLocationMap.empty());
const auto &uniforms = mData.getUniforms(); const auto &uniforms = mData.getUniforms();
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#ifndef LIBANGLE_RENDERER_GL_PROGRAMGL_H_ #ifndef LIBANGLE_RENDERER_GL_PROGRAMGL_H_
#define LIBANGLE_RENDERER_GL_PROGRAMGL_H_ #define LIBANGLE_RENDERER_GL_PROGRAMGL_H_
#include "libANGLE/renderer/gl/WorkaroundsGL.h"
#include "libANGLE/renderer/ProgramImpl.h" #include "libANGLE/renderer/ProgramImpl.h"
namespace rx namespace rx
...@@ -28,6 +29,7 @@ class ProgramGL : public ProgramImpl ...@@ -28,6 +29,7 @@ class ProgramGL : public ProgramImpl
public: public:
ProgramGL(const gl::Program::Data &data, ProgramGL(const gl::Program::Data &data,
const FunctionsGL *functions, const FunctionsGL *functions,
const WorkaroundsGL &workarounds,
StateManagerGL *stateManager); StateManagerGL *stateManager);
~ProgramGL() override; ~ProgramGL() override;
...@@ -76,6 +78,7 @@ class ProgramGL : public ProgramImpl ...@@ -76,6 +78,7 @@ class ProgramGL : public ProgramImpl
GLint uniLoc(GLint glLocation) const { return mUniformRealLocationMap[glLocation]; } GLint uniLoc(GLint glLocation) const { return mUniformRealLocationMap[glLocation]; }
const FunctionsGL *mFunctions; const FunctionsGL *mFunctions;
const WorkaroundsGL &mWorkarounds;
StateManagerGL *mStateManager; StateManagerGL *mStateManager;
std::vector<GLint> mUniformRealLocationMap; std::vector<GLint> mUniformRealLocationMap;
......
...@@ -271,7 +271,7 @@ ShaderImpl *RendererGL::createShader(const gl::Shader::Data &data) ...@@ -271,7 +271,7 @@ ShaderImpl *RendererGL::createShader(const gl::Shader::Data &data)
ProgramImpl *RendererGL::createProgram(const gl::Program::Data &data) ProgramImpl *RendererGL::createProgram(const gl::Program::Data &data)
{ {
return new ProgramGL(data, mFunctions, mStateManager); return new ProgramGL(data, mFunctions, mWorkarounds, mStateManager);
} }
FramebufferImpl *RendererGL::createFramebuffer(const gl::Framebuffer::Data &data) FramebufferImpl *RendererGL::createFramebuffer(const gl::Framebuffer::Data &data)
......
...@@ -302,11 +302,16 @@ void StateManagerGL::useProgram(GLuint program) ...@@ -302,11 +302,16 @@ void StateManagerGL::useProgram(GLuint program)
{ {
if (mProgram != program) if (mProgram != program)
{ {
mProgram = program; forceUseProgram(program);
mFunctions->useProgram(mProgram);
} }
} }
void StateManagerGL::forceUseProgram(GLuint program)
{
mProgram = program;
mFunctions->useProgram(mProgram);
}
void StateManagerGL::bindVertexArray(GLuint vao, GLuint elementArrayBuffer) void StateManagerGL::bindVertexArray(GLuint vao, GLuint elementArrayBuffer)
{ {
if (mVAO != vao) if (mVAO != vao)
......
...@@ -47,6 +47,7 @@ class StateManagerGL final : angle::NonCopyable ...@@ -47,6 +47,7 @@ class StateManagerGL final : angle::NonCopyable
void deleteQuery(GLuint query); void deleteQuery(GLuint query);
void useProgram(GLuint program); void useProgram(GLuint program);
void forceUseProgram(GLuint program);
void bindVertexArray(GLuint vao, GLuint elementArrayBuffer); void bindVertexArray(GLuint vao, GLuint elementArrayBuffer);
void bindBuffer(GLenum type, GLuint buffer); void bindBuffer(GLenum type, GLuint buffer);
void bindBufferBase(GLenum type, size_t index, GLuint buffer); void bindBufferBase(GLenum type, size_t index, GLuint buffer);
......
...@@ -19,7 +19,8 @@ struct WorkaroundsGL ...@@ -19,7 +19,8 @@ struct WorkaroundsGL
rgba4IsNotSupportedForColorRendering(false), rgba4IsNotSupportedForColorRendering(false),
doesSRGBClearsOnLinearFramebufferAttachments(false), doesSRGBClearsOnLinearFramebufferAttachments(false),
doWhileGLSLCausesGPUHang(false), doWhileGLSLCausesGPUHang(false),
finishDoesNotCauseQueriesToBeAvailable(false) finishDoesNotCauseQueriesToBeAvailable(false),
alwaysCallUseProgramAfterLink(false)
{ {
} }
...@@ -56,6 +57,12 @@ struct WorkaroundsGL ...@@ -56,6 +57,12 @@ struct WorkaroundsGL
// (NVIDIA) drivers. It was found that enabling GL_DEBUG_OUTPUT_SYNCHRONOUS before the finish // (NVIDIA) drivers. It was found that enabling GL_DEBUG_OUTPUT_SYNCHRONOUS before the finish
// causes it to fully finish. // causes it to fully finish.
bool finishDoesNotCauseQueriesToBeAvailable; bool finishDoesNotCauseQueriesToBeAvailable;
// Always call useProgram after a successful link to avoid a driver bug.
// This workaround is meant to reproduce the use_current_program_after_successful_link
// workaround in Chromium (http://crbug.com/110263). It has been shown that this workaround is
// not necessary for MacOSX 10.9 and higher (http://crrev.com/39eb535b).
bool alwaysCallUseProgramAfterLink;
}; };
} }
......
...@@ -666,6 +666,9 @@ void GenerateWorkarounds(const FunctionsGL *functions, WorkaroundsGL *workaround ...@@ -666,6 +666,9 @@ void GenerateWorkarounds(const FunctionsGL *functions, WorkaroundsGL *workaround
workarounds->finishDoesNotCauseQueriesToBeAvailable = workarounds->finishDoesNotCauseQueriesToBeAvailable =
functions->standard == STANDARD_GL_DESKTOP && vendor == VENDOR_ID_NVIDIA; functions->standard == STANDARD_GL_DESKTOP && vendor == VENDOR_ID_NVIDIA;
// TODO(cwallez): Disable this workaround for MacOSX versions 10.9 or later.
workarounds->alwaysCallUseProgramAfterLink = true;
} }
} }
......
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