Commit 3e03ebd6 by Dian Xiang

Using dirty bits notification for D3D9 blend state

BUG=angleproject:1249 Dirty bit notifications are used in GL and D3D11 for state tracking. This is a continuation of D3D dirty bit refactor for D3D9 Change-Id: Ifaa1826a93cf36c83d68150107b164d1d269c2b0 Reviewed-on: https://chromium-review.googlesource.com/316475Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org> Tryjob-Request: Dian Xiang <dianx@google.com> Tested-by: 's avatarDian Xiang <dianx@google.com>
parent 792a41d1
...@@ -82,7 +82,6 @@ class Renderer : public ImplFactory ...@@ -82,7 +82,6 @@ class Renderer : public ImplFactory
virtual bool testDeviceLost() = 0; virtual bool testDeviceLost() = 0;
virtual bool testDeviceResettable() = 0; virtual bool testDeviceResettable() = 0;
virtual VendorID getVendorId() const = 0;
virtual std::string getVendorString() const = 0; virtual std::string getVendorString() const = 0;
virtual std::string getRendererDescription() const = 0; virtual std::string getRendererDescription() const = 0;
......
...@@ -2610,11 +2610,6 @@ bool Renderer11::resetDevice() ...@@ -2610,11 +2610,6 @@ bool Renderer11::resetDevice()
return true; return true;
} }
VendorID Renderer11::getVendorId() const
{
return static_cast<VendorID>(mAdapterDescription.VendorId);
}
std::string Renderer11::getRendererDescription() const std::string Renderer11::getRendererDescription() const
{ {
std::ostringstream rendererString; std::ostringstream rendererString;
......
...@@ -144,7 +144,6 @@ class Renderer11 : public RendererD3D ...@@ -144,7 +144,6 @@ class Renderer11 : public RendererD3D
bool testDeviceLost() override; bool testDeviceLost() override;
bool testDeviceResettable() override; bool testDeviceResettable() override;
VendorID getVendorId() const override;
std::string getRendererDescription() const override; std::string getRendererDescription() const override;
DeviceIdentifier getAdapterIdentifier() const override; DeviceIdentifier getAdapterIdentifier() const override;
......
...@@ -104,4 +104,4 @@ class StateManager11 final : angle::NonCopyable ...@@ -104,4 +104,4 @@ class StateManager11 final : angle::NonCopyable
}; };
} // namespace rx } // namespace rx
#endif // LIBANGLE_RENDERER_D3D11_STATEMANAGER11_H_ #endif // LIBANGLE_RENDERER_D3D11_STATEMANAGER11_H_
\ No newline at end of file
...@@ -76,8 +76,7 @@ enum ...@@ -76,8 +76,7 @@ enum
MAX_TEXTURE_IMAGE_UNITS_VTF_SM3 = 4 MAX_TEXTURE_IMAGE_UNITS_VTF_SM3 = 4
}; };
Renderer9::Renderer9(egl::Display *display) Renderer9::Renderer9(egl::Display *display) : RendererD3D(display), mStateManager(this)
: RendererD3D(display)
{ {
mD3d9Module = NULL; mD3d9Module = NULL;
...@@ -886,6 +885,11 @@ gl::Error Renderer9::setUniformBuffers(const gl::Data &/*data*/, ...@@ -886,6 +885,11 @@ gl::Error Renderer9::setUniformBuffers(const gl::Data &/*data*/,
return gl::Error(GL_NO_ERROR); return gl::Error(GL_NO_ERROR);
} }
void Renderer9::syncState(const gl::State &state, const gl::State::DirtyBits &bitmask)
{
mStateManager.syncState(state, bitmask);
}
gl::Error Renderer9::updateState(const gl::Data &data, GLenum drawMode) gl::Error Renderer9::updateState(const gl::Data &data, GLenum drawMode)
{ {
// Applies the render target surface, depth stencil surface, viewport rectangle and // Applies the render target surface, depth stencil surface, viewport rectangle and
...@@ -930,6 +934,9 @@ gl::Error Renderer9::updateState(const gl::Data &data, GLenum drawMode) ...@@ -930,6 +934,9 @@ gl::Error Renderer9::updateState(const gl::Data &data, GLenum drawMode)
// Setting depth stencil state // Setting depth stencil state
error = setDepthStencilState(*data.state); error = setDepthStencilState(*data.state);
mStateManager.resetDirtyBits();
return error; return error;
} }
...@@ -978,107 +985,7 @@ gl::Error Renderer9::setBlendState(const gl::Framebuffer *framebuffer, ...@@ -978,107 +985,7 @@ gl::Error Renderer9::setBlendState(const gl::Framebuffer *framebuffer,
const gl::ColorF &blendColor, const gl::ColorF &blendColor,
unsigned int sampleMask) unsigned int sampleMask)
{ {
bool blendStateChanged = mForceSetBlendState || memcmp(&blendState, &mCurBlendState, sizeof(gl::BlendState)) != 0; return mStateManager.setBlendState(framebuffer, blendState, blendColor, sampleMask);
bool blendColorChanged = mForceSetBlendState || memcmp(&blendColor, &mCurBlendColor, sizeof(gl::ColorF)) != 0;
bool sampleMaskChanged = mForceSetBlendState || sampleMask != mCurSampleMask;
if (blendStateChanged || blendColorChanged)
{
if (blendState.blend)
{
mDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
if (blendState.sourceBlendRGB != GL_CONSTANT_ALPHA && blendState.sourceBlendRGB != GL_ONE_MINUS_CONSTANT_ALPHA &&
blendState.destBlendRGB != GL_CONSTANT_ALPHA && blendState.destBlendRGB != GL_ONE_MINUS_CONSTANT_ALPHA)
{
mDevice->SetRenderState(D3DRS_BLENDFACTOR, gl_d3d9::ConvertColor(blendColor));
}
else
{
mDevice->SetRenderState(D3DRS_BLENDFACTOR, D3DCOLOR_RGBA(gl::unorm<8>(blendColor.alpha),
gl::unorm<8>(blendColor.alpha),
gl::unorm<8>(blendColor.alpha),
gl::unorm<8>(blendColor.alpha)));
}
mDevice->SetRenderState(D3DRS_SRCBLEND, gl_d3d9::ConvertBlendFunc(blendState.sourceBlendRGB));
mDevice->SetRenderState(D3DRS_DESTBLEND, gl_d3d9::ConvertBlendFunc(blendState.destBlendRGB));
mDevice->SetRenderState(D3DRS_BLENDOP, gl_d3d9::ConvertBlendOp(blendState.blendEquationRGB));
if (blendState.sourceBlendRGB != blendState.sourceBlendAlpha ||
blendState.destBlendRGB != blendState.destBlendAlpha ||
blendState.blendEquationRGB != blendState.blendEquationAlpha)
{
mDevice->SetRenderState(D3DRS_SEPARATEALPHABLENDENABLE, TRUE);
mDevice->SetRenderState(D3DRS_SRCBLENDALPHA, gl_d3d9::ConvertBlendFunc(blendState.sourceBlendAlpha));
mDevice->SetRenderState(D3DRS_DESTBLENDALPHA, gl_d3d9::ConvertBlendFunc(blendState.destBlendAlpha));
mDevice->SetRenderState(D3DRS_BLENDOPALPHA, gl_d3d9::ConvertBlendOp(blendState.blendEquationAlpha));
}
else
{
mDevice->SetRenderState(D3DRS_SEPARATEALPHABLENDENABLE, FALSE);
}
}
else
{
mDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
}
if (blendState.sampleAlphaToCoverage)
{
FIXME("Sample alpha to coverage is unimplemented.");
}
const gl::FramebufferAttachment *attachment = framebuffer->getFirstColorbuffer();
GLenum internalFormat = attachment ? attachment->getInternalFormat() : GL_NONE;
// Set the color mask
bool zeroColorMaskAllowed = getVendorId() != VENDOR_ID_AMD;
// 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
const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(internalFormat);
DWORD colorMask = gl_d3d9::ConvertColorMask(formatInfo.redBits > 0 && blendState.colorMaskRed,
formatInfo.greenBits > 0 && blendState.colorMaskGreen,
formatInfo.blueBits > 0 && blendState.colorMaskBlue,
formatInfo.alphaBits > 0 && blendState.colorMaskAlpha);
if (colorMask == 0 && !zeroColorMaskAllowed)
{
// Enable green channel, but set blending so nothing will be drawn.
mDevice->SetRenderState(D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_GREEN);
mDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
mDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ZERO);
mDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE);
mDevice->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_ADD);
}
else
{
mDevice->SetRenderState(D3DRS_COLORWRITEENABLE, colorMask);
}
mDevice->SetRenderState(D3DRS_DITHERENABLE, blendState.dither ? TRUE : FALSE);
mCurBlendState = blendState;
mCurBlendColor = blendColor;
}
if (sampleMaskChanged)
{
// Set the multisample mask
mDevice->SetRenderState(D3DRS_MULTISAMPLEANTIALIAS, TRUE);
mDevice->SetRenderState(D3DRS_MULTISAMPLEMASK, static_cast<DWORD>(sampleMask));
mCurSampleMask = sampleMask;
}
mForceSetBlendState = false;
return gl::Error(GL_NO_ERROR);
} }
gl::Error Renderer9::setDepthStencilState(const gl::State &glState) gl::Error Renderer9::setDepthStencilState(const gl::State &glState)
...@@ -1487,7 +1394,7 @@ gl::Error Renderer9::applyRenderTarget(const gl::FramebufferAttachment *colorAtt ...@@ -1487,7 +1394,7 @@ gl::Error Renderer9::applyRenderTarget(const gl::FramebufferAttachment *colorAtt
{ {
mForceSetScissor = true; mForceSetScissor = true;
mForceSetViewport = true; mForceSetViewport = true;
mForceSetBlendState = true; mStateManager.forceSetBlendState();
mRenderTargetDesc.width = renderTargetWidth; mRenderTargetDesc.width = renderTargetWidth;
mRenderTargetDesc.height = renderTargetHeight; mRenderTargetDesc.height = renderTargetHeight;
...@@ -2335,7 +2242,7 @@ void Renderer9::markAllStateDirty() ...@@ -2335,7 +2242,7 @@ void Renderer9::markAllStateDirty()
mForceSetRasterState = true; mForceSetRasterState = true;
mForceSetScissor = true; mForceSetScissor = true;
mForceSetViewport = true; mForceSetViewport = true;
mForceSetBlendState = true; mStateManager.forceSetBlendState();
ASSERT(mCurVertexSamplerStates.size() == mCurVertexTextures.size()); ASSERT(mCurVertexSamplerStates.size() == mCurVertexTextures.size());
for (unsigned int i = 0; i < mCurVertexTextures.size(); i++) for (unsigned int i = 0; i < mCurVertexTextures.size(); i++)
......
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
#include "libANGLE/renderer/d3d/d3d9/DebugAnnotator9.h" #include "libANGLE/renderer/d3d/d3d9/DebugAnnotator9.h"
#include "libANGLE/renderer/d3d/d3d9/ShaderCache.h" #include "libANGLE/renderer/d3d/d3d9/ShaderCache.h"
#include "libANGLE/renderer/d3d/d3d9/VertexDeclarationCache.h" #include "libANGLE/renderer/d3d/d3d9/VertexDeclarationCache.h"
#include "libANGLE/renderer/d3d/d3d9/StateManager9.h"
namespace gl namespace gl
{ {
...@@ -135,7 +136,7 @@ class Renderer9 : public RendererD3D ...@@ -135,7 +136,7 @@ class Renderer9 : public RendererD3D
bool testDeviceLost() override; bool testDeviceLost() override;
bool testDeviceResettable() override; bool testDeviceResettable() override;
VendorID getVendorId() const override; VendorID getVendorId() const;
std::string getRendererDescription() const override; std::string getRendererDescription() const override;
DeviceIdentifier getAdapterIdentifier() const override; DeviceIdentifier getAdapterIdentifier() const override;
...@@ -231,10 +232,7 @@ class Renderer9 : public RendererD3D ...@@ -231,10 +232,7 @@ class Renderer9 : public RendererD3D
virtual gl::Error fastCopyBufferToTexture(const gl::PixelUnpackState &unpack, unsigned int offset, RenderTargetD3D *destRenderTarget, virtual gl::Error fastCopyBufferToTexture(const gl::PixelUnpackState &unpack, unsigned int offset, RenderTargetD3D *destRenderTarget,
GLenum destinationFormat, GLenum sourcePixelsType, const gl::Box &destArea); GLenum destinationFormat, GLenum sourcePixelsType, const gl::Box &destArea);
void syncState(const gl::State & /*state*/, const gl::State::DirtyBits &bitmask) override void syncState(const gl::State &state, const gl::State::DirtyBits &bitmask) override;
{
// TODO(dianx) implement d3d9 dirty bits
}
// D3D9-renderer specific methods // D3D9-renderer specific methods
gl::Error boxFilter(IDirect3DSurface9 *source, IDirect3DSurface9 *dest); gl::Error boxFilter(IDirect3DSurface9 *source, IDirect3DSurface9 *dest);
...@@ -351,6 +349,8 @@ class Renderer9 : public RendererD3D ...@@ -351,6 +349,8 @@ class Renderer9 : public RendererD3D
IDirect3DStateBlock9 *mMaskedClearSavedState; IDirect3DStateBlock9 *mMaskedClearSavedState;
StateManager9 mStateManager;
// previously set render states // previously set render states
bool mForceSetDepthStencilState; bool mForceSetDepthStencilState;
gl::DepthStencilState mCurDepthStencilState; gl::DepthStencilState mCurDepthStencilState;
...@@ -371,11 +371,6 @@ class Renderer9 : public RendererD3D ...@@ -371,11 +371,6 @@ class Renderer9 : public RendererD3D
float mCurFar; float mCurFar;
float mCurDepthFront; float mCurDepthFront;
bool mForceSetBlendState;
gl::BlendState mCurBlendState;
gl::ColorF mCurBlendColor;
GLuint mCurSampleMask;
// Currently applied sampler states // Currently applied sampler states
struct CurSamplerState struct CurSamplerState
{ {
......
//
// Copyright (c) 2015 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// StateManager9.h: Defines a class for caching D3D9 state
#ifndef LIBANGLE_RENDERER_D3D9_STATEMANAGER9_H_
#define LIBANGLE_RENDERER_D3D9_STATEMANAGER9_H_
#include "libANGLE/angletypes.h"
#include "libANGLE/Data.h"
#include "libANGLE/State.h"
namespace rx
{
class Renderer9;
class StateManager9 final : angle::NonCopyable
{
public:
StateManager9(Renderer9 *renderer9);
~StateManager9();
void syncState(const gl::State &state, const gl::State::DirtyBits &dirtyBits);
gl::Error setBlendState(const gl::Framebuffer *framebuffer,
const gl::BlendState &blendState,
const gl::ColorF &blendColor,
unsigned int sampleMask);
void forceSetBlendState();
void resetDirtyBits() { mDirtyBits.reset(); }
VendorID getVendorId() const;
private:
void setBlendEnabled(bool enabled);
void setBlendColor(const gl::BlendState &blendState, const gl::ColorF &blendColor);
void setBlendFuncsEquations(const gl::BlendState &blendState);
void setColorMask(const gl::Framebuffer *framebuffer,
bool red,
bool blue,
bool green,
bool alpha);
void setSampleAlphaToCoverage(bool enabled);
void setDither(bool dither);
void setSampleMask(unsigned int sampleMask);
enum DirtyBitType
{
DIRTY_BIT_BLEND_ENABLED,
DIRTY_BIT_BLEND_COLOR,
DIRTY_BIT_BLEND_FUNCS_EQUATIONS,
DIRTY_BIT_SAMPLE_ALPHA_TO_COVERAGE,
DIRTY_BIT_COLOR_MASK,
DIRTY_BIT_DITHER,
DIRTY_BIT_SAMPLE_MASK,
DIRTY_BIT_MAX
};
typedef std::bitset<DIRTY_BIT_MAX> DirtyBits;
// Currently applied blend state
gl::BlendState mCurBlendState;
gl::ColorF mCurBlendColor;
unsigned int mCurSampleMask;
DirtyBits mBlendStateDirtyBits;
Renderer9 *mRenderer9;
DirtyBits mDirtyBits;
};
} // namespace rx
#endif // LIBANGLE_RENDERER_D3D9_STATEMANAGER9_H_
...@@ -363,12 +363,6 @@ bool RendererGL::testDeviceResettable() ...@@ -363,12 +363,6 @@ bool RendererGL::testDeviceResettable()
return bool(); return bool();
} }
VendorID RendererGL::getVendorId() const
{
UNIMPLEMENTED();
return VendorID();
}
std::string RendererGL::getVendorString() const std::string RendererGL::getVendorString() const
{ {
return std::string(reinterpret_cast<const char*>(mFunctions->getString(GL_VENDOR))); return std::string(reinterpret_cast<const char*>(mFunctions->getString(GL_VENDOR)));
......
...@@ -99,7 +99,6 @@ class RendererGL : public Renderer ...@@ -99,7 +99,6 @@ class RendererGL : public Renderer
bool testDeviceLost() override; bool testDeviceLost() override;
bool testDeviceResettable() override; bool testDeviceResettable() override;
VendorID getVendorId() const override;
std::string getVendorString() const override; std::string getVendorString() const override;
std::string getRendererDescription() const override; std::string getRendererDescription() const override;
......
...@@ -265,6 +265,8 @@ ...@@ -265,6 +265,8 @@
'libANGLE/renderer/d3d/d3d9/shaders/compiled/luminanceps.h', 'libANGLE/renderer/d3d/d3d9/shaders/compiled/luminanceps.h',
'libANGLE/renderer/d3d/d3d9/shaders/compiled/passthroughps.h', 'libANGLE/renderer/d3d/d3d9/shaders/compiled/passthroughps.h',
'libANGLE/renderer/d3d/d3d9/shaders/compiled/standardvs.h', 'libANGLE/renderer/d3d/d3d9/shaders/compiled/standardvs.h',
'libANGLE/renderer/d3d/d3d9/StateManager9.cpp',
'libANGLE/renderer/d3d/d3d9/StateManager9.h',
'libANGLE/renderer/d3d/d3d9/SwapChain9.cpp', 'libANGLE/renderer/d3d/d3d9/SwapChain9.cpp',
'libANGLE/renderer/d3d/d3d9/SwapChain9.h', 'libANGLE/renderer/d3d/d3d9/SwapChain9.h',
'libANGLE/renderer/d3d/d3d9/TextureStorage9.cpp', 'libANGLE/renderer/d3d/d3d9/TextureStorage9.cpp',
......
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