Commit 03208d5d by jbauman@chromium.org

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
parent 1179ecf4
#define MAJOR_VERSION 0
#define MINOR_VERSION 0
#define BUILD_VERSION 0
#define BUILD_REVISION 692
#define BUILD_REVISION 693
#define STRINGIFY(x) #x
#define MACRO_STRINGIFY(x) STRINGIFY(x)
......
......@@ -141,6 +141,8 @@ bool Display::initialize()
if (mDeviceCaps.PresentationIntervals & D3DPRESENT_INTERVAL_THREE) {mMinSwapInterval = std::min(mMinSwapInterval, 3); mMaxSwapInterval = std::max(mMaxSwapInterval, 3);}
if (mDeviceCaps.PresentationIntervals & D3DPRESENT_INTERVAL_FOUR) {mMinSwapInterval = std::min(mMinSwapInterval, 4); mMaxSwapInterval = std::max(mMaxSwapInterval, 4);}
mD3d9->GetAdapterIdentifier(mAdapter, 0, &mAdapterIdentifier);
const D3DFORMAT renderTargetFormats[] =
{
D3DFMT_A1R5G5B5,
......@@ -688,6 +690,11 @@ D3DCAPS9 Display::getDeviceCaps()
return mDeviceCaps;
}
D3DADAPTER_IDENTIFIER9 *Display::getAdapterIdentifier()
{
return &mAdapterIdentifier;
}
bool Display::isDeviceLost()
{
if (mDeviceEx)
......
......@@ -60,6 +60,7 @@ class Display
virtual IDirect3DDevice9 *getDevice();
virtual D3DCAPS9 getDeviceCaps();
virtual D3DADAPTER_IDENTIFIER9 *getAdapterIdentifier();
bool isDeviceLost();
virtual void getMultiSampleSupport(D3DFORMAT format, bool *multiSampleArray);
virtual bool getCompressedTextureSupport();
......@@ -91,6 +92,7 @@ class Display
IDirect3DDevice9 *mDevice;
IDirect3DDevice9Ex *mDeviceEx; // Might be null if D3D9Ex is not supported.
D3DCAPS9 mDeviceCaps;
D3DADAPTER_IDENTIFIER9 mAdapterIdentifier;
HWND mDeviceWindow;
bool mSceneStarted;
......
......@@ -1737,6 +1737,15 @@ void Context::applyState(GLenum drawMode)
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 @@ void Context::applyState(GLenum drawMode)
mDepthStateDirty = false;
}
if (!zeroColorMaskAllowed && (mMaskStateDirty || mBlendStateDirty))
{
mBlendStateDirty = true;
mMaskStateDirty = true;
}
if (mBlendStateDirty)
{
if (mState.blend)
......@@ -1874,8 +1889,22 @@ void Context::applyState(GLenum drawMode)
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;
......
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