Attempt to ensure pipeline flush on rendertarget change
Some ATI cards appear not to flush the pipeline correctly, causing textures not to pick up newly-drawn contexts, so do an extra no-op draw when necessary.
BUG=169
TEST=chromium on hulu.com
Review URL: http://codereview.appspot.com/4576051
git-svn-id: https://angleproject.googlecode.com/svn/trunk@693 736b8ea6-26fd-11df-bfd4-992fa37f6226
diff --git a/src/libGLESv2/Context.cpp b/src/libGLESv2/Context.cpp
index 1c66450..6c973ea 100644
--- a/src/libGLESv2/Context.cpp
+++ b/src/libGLESv2/Context.cpp
@@ -1737,6 +1737,15 @@
GLint alwaysFront = !isTriangleMode(drawMode);
programObject->setUniform1iv(pointsOrLines, 1, &alwaysFront);
+ egl::Display *display = getDisplay();
+ D3DADAPTER_IDENTIFIER9 *identifier = display->getAdapterIdentifier();
+ bool zeroColorMaskAllowed = identifier->VendorId != 0x1002;
+ // Apparently some ATI cards have a bug where a draw with a zero color
+ // write mask can cause later draws to have incorrect results. Instead,
+ // set a nonzero color write mask but modify the blend state so that no
+ // drawing is done.
+ // http://code.google.com/p/angleproject/issues/detail?id=169
+
if (mCullStateDirty || mFrontFaceDirty)
{
if (mState.cullFace)
@@ -1766,6 +1775,12 @@
mDepthStateDirty = false;
}
+ if (!zeroColorMaskAllowed && (mMaskStateDirty || mBlendStateDirty))
+ {
+ mBlendStateDirty = true;
+ mMaskStateDirty = true;
+ }
+
if (mBlendStateDirty)
{
if (mState.blend)
@@ -1874,8 +1889,22 @@
if (mMaskStateDirty)
{
- device->SetRenderState(D3DRS_COLORWRITEENABLE, es2dx::ConvertColorMask(mState.colorMaskRed, mState.colorMaskGreen,
- mState.colorMaskBlue, mState.colorMaskAlpha));
+ int colorMask = es2dx::ConvertColorMask(mState.colorMaskRed, mState.colorMaskGreen,
+ mState.colorMaskBlue, mState.colorMaskAlpha);
+ if (colorMask == 0 && !zeroColorMaskAllowed)
+ {
+ // Enable green channel, but set blending so nothing will be drawn.
+ device->SetRenderState(D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_GREEN);
+ device->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
+
+ device->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ZERO);
+ device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE);
+ device->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_ADD);
+ }
+ else
+ {
+ device->SetRenderState(D3DRS_COLORWRITEENABLE, colorMask);
+ }
device->SetRenderState(D3DRS_ZWRITEENABLE, mState.depthMask ? TRUE : FALSE);
mMaskStateDirty = false;