Commit a5c9a144 by Jamie Madill

Fix uniform bug from duplicate D3D9 shader pointers.

In D3D9, sometimes the compiler would return the same shader pointer on different calls to compile, if the programs were similar. Work around this quirk by storing an applied serial for the program, so we know when to refresh uniform data. BUG=angle:661 Change-Id: I9750ee2298701dbe3f121dac6626198d24a2d1b2 Reviewed-on: https://chromium-review.googlesource.com/201562Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org> Tested-by: 's avatarJamie Madill <jmadill@chromium.org>
parent 673e680c
...@@ -132,6 +132,7 @@ Renderer9::Renderer9(egl::Display *display, HDC hDc) : Renderer(display), mDc(hD ...@@ -132,6 +132,7 @@ Renderer9::Renderer9(egl::Display *display, HDC hDc) : Renderer(display), mDc(hD
mAppliedVertexShader = NULL; mAppliedVertexShader = NULL;
mAppliedPixelShader = NULL; mAppliedPixelShader = NULL;
mAppliedProgramSerial = 0;
} }
Renderer9::~Renderer9() Renderer9::~Renderer9()
...@@ -1738,25 +1739,29 @@ void Renderer9::applyShaders(gl::ProgramBinary *programBinary, bool rasterizerDi ...@@ -1738,25 +1739,29 @@ void Renderer9::applyShaders(gl::ProgramBinary *programBinary, bool rasterizerDi
IDirect3DVertexShader9 *vertexShader = (vertexExe ? ShaderExecutable9::makeShaderExecutable9(vertexExe)->getVertexShader() : NULL); IDirect3DVertexShader9 *vertexShader = (vertexExe ? ShaderExecutable9::makeShaderExecutable9(vertexExe)->getVertexShader() : NULL);
IDirect3DPixelShader9 *pixelShader = (pixelExe ? ShaderExecutable9::makeShaderExecutable9(pixelExe)->getPixelShader() : NULL); IDirect3DPixelShader9 *pixelShader = (pixelExe ? ShaderExecutable9::makeShaderExecutable9(pixelExe)->getPixelShader() : NULL);
bool dirtyUniforms = false;
if (vertexShader != mAppliedVertexShader) if (vertexShader != mAppliedVertexShader)
{ {
mDevice->SetVertexShader(vertexShader); mDevice->SetVertexShader(vertexShader);
mAppliedVertexShader = vertexShader; mAppliedVertexShader = vertexShader;
dirtyUniforms = true;
} }
if (pixelShader != mAppliedPixelShader) if (pixelShader != mAppliedPixelShader)
{ {
mDevice->SetPixelShader(pixelShader); mDevice->SetPixelShader(pixelShader);
mAppliedPixelShader = pixelShader; mAppliedPixelShader = pixelShader;
dirtyUniforms = true;
} }
if (dirtyUniforms) // D3D9 has a quirk where creating multiple shaders with the same content
// can return the same shader pointer. Because GL programs store different data
// per-program, checking the program serial guarantees we upload fresh
// uniform data even if our shader pointers are the same.
// https://code.google.com/p/angleproject/issues/detail?id=661
unsigned int programSerial = programBinary->getSerial();
if (programSerial != mAppliedProgramSerial)
{ {
programBinary->dirtyAllUniforms(); programBinary->dirtyAllUniforms();
mDxUniformsDirty = true;
mAppliedProgramSerial = programSerial;
} }
} }
...@@ -2114,6 +2119,7 @@ void Renderer9::markAllStateDirty() ...@@ -2114,6 +2119,7 @@ void Renderer9::markAllStateDirty()
mAppliedIBSerial = 0; mAppliedIBSerial = 0;
mAppliedVertexShader = NULL; mAppliedVertexShader = NULL;
mAppliedPixelShader = NULL; mAppliedPixelShader = NULL;
mAppliedProgramSerial = 0;
mDxUniformsDirty = true; mDxUniformsDirty = true;
mVertexDeclarationCache.markStateDirty(); mVertexDeclarationCache.markStateDirty();
......
...@@ -378,7 +378,8 @@ class Renderer9 : public Renderer ...@@ -378,7 +378,8 @@ class Renderer9 : public Renderer
unsigned int mAppliedIBSerial; unsigned int mAppliedIBSerial;
IDirect3DVertexShader9 *mAppliedVertexShader; IDirect3DVertexShader9 *mAppliedVertexShader;
IDirect3DPixelShader9 *mAppliedPixelShader; IDirect3DPixelShader9 *mAppliedPixelShader;
unsigned int mAppliedProgramSerial;
rx::dx_VertexConstants mVertexConstants; rx::dx_VertexConstants mVertexConstants;
rx::dx_PixelConstants mPixelConstants; rx::dx_PixelConstants mPixelConstants;
bool mDxUniformsDirty; bool mDxUniformsDirty;
......
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