Commit c142e9da by Geoff Lang

Renderer classes now set their blend states to mask out channels that do not…

Renderer classes now set their blend states to mask out channels that do not exist in the render target. Change-Id: Ia49bf8de07bbdfa31275ec9835de28adc3717485 Reviewed-on: https://chromium-review.googlesource.com/176855Reviewed-by: 's avatarShannon Woods <shannonwoods@chromium.org> Commit-Queue: Shannon Woods <shannonwoods@chromium.org> Tested-by: 's avatarShannon Woods <shannonwoods@chromium.org>
parent 5cd4761f
...@@ -2340,7 +2340,7 @@ void Context::applyState(GLenum drawMode) ...@@ -2340,7 +2340,7 @@ void Context::applyState(GLenum drawMode)
{ {
mask = 0xFFFFFFFF; mask = 0xFFFFFFFF;
} }
mRenderer->setBlendState(mState.blend, mState.blendColor, mask); mRenderer->setBlendState(framebufferObject, mState.blend, mState.blendColor, mask);
mRenderer->setDepthStencilState(mState.depthStencil, mState.stencilRef, mState.stencilBackRef, mRenderer->setDepthStencilState(mState.depthStencil, mState.stencilRef, mState.stencilBackRef,
mState.rasterizer.frontFace == GL_CCW); mState.rasterizer.frontFace == GL_CCW);
......
...@@ -125,7 +125,7 @@ class Renderer ...@@ -125,7 +125,7 @@ class Renderer
virtual bool setUniformBuffers(const gl::Buffer *vertexUniformBuffers[], const gl::Buffer *fragmentUniformBuffers[]) = 0; virtual bool setUniformBuffers(const gl::Buffer *vertexUniformBuffers[], const gl::Buffer *fragmentUniformBuffers[]) = 0;
virtual void setRasterizerState(const gl::RasterizerState &rasterState) = 0; virtual void setRasterizerState(const gl::RasterizerState &rasterState) = 0;
virtual void setBlendState(const gl::BlendState &blendState, const gl::ColorF &blendColor, virtual void setBlendState(gl::Framebuffer *framebuffer, const gl::BlendState &blendState, const gl::ColorF &blendColor,
unsigned int sampleMask) = 0; unsigned int sampleMask) = 0;
virtual void setDepthStencilState(const gl::DepthStencilState &depthStencilState, int stencilRef, virtual void setDepthStencilState(const gl::DepthStencilState &depthStencilState, int stencilRef,
int stencilBackRef, bool frontFaceCCW) = 0; int stencilBackRef, bool frontFaceCCW) = 0;
......
...@@ -10,6 +10,9 @@ ...@@ -10,6 +10,9 @@
#include "libGLESv2/renderer/d3d11/RenderStateCache.h" #include "libGLESv2/renderer/d3d11/RenderStateCache.h"
#include "libGLESv2/renderer/d3d11/renderer11_utils.h" #include "libGLESv2/renderer/d3d11/renderer11_utils.h"
#include "libGLESv2/renderer/Renderer.h"
#include "libGLESv2/Framebuffer.h"
#include "libGLESv2/Renderbuffer.h"
#include "common/debug.h" #include "common/debug.h"
#include "third_party/murmurhash/MurmurHash3.h" #include "third_party/murmurhash/MurmurHash3.h"
...@@ -62,7 +65,7 @@ void RenderStateCache::clear() ...@@ -62,7 +65,7 @@ void RenderStateCache::clear()
ClearStateMap(mSamplerStateCache); ClearStateMap(mSamplerStateCache);
} }
std::size_t RenderStateCache::hashBlendState(const gl::BlendState &blendState) std::size_t RenderStateCache::hashBlendState(const BlendStateKey &blendState)
{ {
static const unsigned int seed = 0xABCDEF98; static const unsigned int seed = 0xABCDEF98;
...@@ -71,12 +74,12 @@ std::size_t RenderStateCache::hashBlendState(const gl::BlendState &blendState) ...@@ -71,12 +74,12 @@ std::size_t RenderStateCache::hashBlendState(const gl::BlendState &blendState)
return hash; return hash;
} }
bool RenderStateCache::compareBlendStates(const gl::BlendState &a, const gl::BlendState &b) bool RenderStateCache::compareBlendStates(const BlendStateKey &a, const BlendStateKey &b)
{ {
return memcmp(&a, &b, sizeof(gl::BlendState)) == 0; return memcmp(&a, &b, sizeof(gl::BlendState)) == 0;
} }
ID3D11BlendState *RenderStateCache::getBlendState(const gl::BlendState &blendState) ID3D11BlendState *RenderStateCache::getBlendState(const gl::Framebuffer *framebuffer, const gl::BlendState &blendState)
{ {
if (!mDevice) if (!mDevice)
{ {
...@@ -84,7 +87,35 @@ ID3D11BlendState *RenderStateCache::getBlendState(const gl::BlendState &blendSta ...@@ -84,7 +87,35 @@ ID3D11BlendState *RenderStateCache::getBlendState(const gl::BlendState &blendSta
return NULL; return NULL;
} }
BlendStateMap::iterator i = mBlendStateCache.find(blendState); bool mrt = false;
BlendStateKey key = { 0 };
key.blendState = blendState;
for (unsigned int i = 0; i < D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; i++)
{
gl::Renderbuffer *renderBuffer = framebuffer->getColorbuffer(i);
if (renderBuffer)
{
if (i > 0)
{
mrt = true;
}
key.rtChannels[i][0] = renderBuffer->getRedSize() > 0;
key.rtChannels[i][1] = renderBuffer->getGreenSize() > 0;
key.rtChannels[i][2] = renderBuffer->getBlueSize() > 0;
key.rtChannels[i][3] = renderBuffer->getAlphaSize() > 0;
}
else
{
key.rtChannels[i][0] = false;
key.rtChannels[i][1] = false;
key.rtChannels[i][2] = false;
key.rtChannels[i][3] = false;
}
}
BlendStateMap::iterator i = mBlendStateCache.find(key);
if (i != mBlendStateCache.end()) if (i != mBlendStateCache.end())
{ {
BlendStateCounterPair &state = i->second; BlendStateCounterPair &state = i->second;
...@@ -113,7 +144,7 @@ ID3D11BlendState *RenderStateCache::getBlendState(const gl::BlendState &blendSta ...@@ -113,7 +144,7 @@ ID3D11BlendState *RenderStateCache::getBlendState(const gl::BlendState &blendSta
// Create a new blend state and insert it into the cache // Create a new blend state and insert it into the cache
D3D11_BLEND_DESC blendDesc = { 0 }; D3D11_BLEND_DESC blendDesc = { 0 };
blendDesc.AlphaToCoverageEnable = blendState.sampleAlphaToCoverage; blendDesc.AlphaToCoverageEnable = blendState.sampleAlphaToCoverage;
blendDesc.IndependentBlendEnable = FALSE; blendDesc.IndependentBlendEnable = mrt ? TRUE : FALSE;
for (unsigned int i = 0; i < D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; i++) for (unsigned int i = 0; i < D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; i++)
{ {
...@@ -131,10 +162,10 @@ ID3D11BlendState *RenderStateCache::getBlendState(const gl::BlendState &blendSta ...@@ -131,10 +162,10 @@ ID3D11BlendState *RenderStateCache::getBlendState(const gl::BlendState &blendSta
rtBlend.BlendOpAlpha = gl_d3d11::ConvertBlendOp(blendState.blendEquationAlpha); rtBlend.BlendOpAlpha = gl_d3d11::ConvertBlendOp(blendState.blendEquationAlpha);
} }
rtBlend.RenderTargetWriteMask = gl_d3d11::ConvertColorMask(blendState.colorMaskRed, rtBlend.RenderTargetWriteMask = gl_d3d11::ConvertColorMask(key.rtChannels[i][0] && blendState.colorMaskRed,
blendState.colorMaskGreen, key.rtChannels[i][1] && blendState.colorMaskGreen,
blendState.colorMaskBlue, key.rtChannels[i][2] && blendState.colorMaskBlue,
blendState.colorMaskAlpha); key.rtChannels[i][3] && blendState.colorMaskAlpha);
} }
ID3D11BlendState *dx11BlendState = NULL; ID3D11BlendState *dx11BlendState = NULL;
...@@ -145,7 +176,7 @@ ID3D11BlendState *RenderStateCache::getBlendState(const gl::BlendState &blendSta ...@@ -145,7 +176,7 @@ ID3D11BlendState *RenderStateCache::getBlendState(const gl::BlendState &blendSta
return NULL; return NULL;
} }
mBlendStateCache.insert(std::make_pair(blendState, std::make_pair(dx11BlendState, mCounter++))); mBlendStateCache.insert(std::make_pair(key, std::make_pair(dx11BlendState, mCounter++)));
return dx11BlendState; return dx11BlendState;
} }
...@@ -174,7 +205,7 @@ ID3D11RasterizerState *RenderStateCache::getRasterizerState(const gl::Rasterizer ...@@ -174,7 +205,7 @@ ID3D11RasterizerState *RenderStateCache::getRasterizerState(const gl::Rasterizer
return NULL; return NULL;
} }
RasterizerStateKey key; RasterizerStateKey key = { 0 };
key.rasterizerState = rasterState; key.rasterizerState = rasterState;
key.scissorEnabled = scissorEnabled; key.scissorEnabled = scissorEnabled;
key.depthSize = depthSize; key.depthSize = depthSize;
......
...@@ -13,6 +13,11 @@ ...@@ -13,6 +13,11 @@
#include "libGLESv2/angletypes.h" #include "libGLESv2/angletypes.h"
#include "common/angleutils.h" #include "common/angleutils.h"
namespace gl
{
class Framebuffer;
}
namespace rx namespace rx
{ {
...@@ -25,8 +30,7 @@ class RenderStateCache ...@@ -25,8 +30,7 @@ class RenderStateCache
void initialize(ID3D11Device *device); void initialize(ID3D11Device *device);
void clear(); void clear();
// Increments refcount on the returned blend state, Release() must be called. ID3D11BlendState *getBlendState(const gl::Framebuffer *framebuffer, const gl::BlendState &blendState);
ID3D11BlendState *getBlendState(const gl::BlendState &blendState);
ID3D11RasterizerState *getRasterizerState(const gl::RasterizerState &rasterState, ID3D11RasterizerState *getRasterizerState(const gl::RasterizerState &rasterState,
bool scissorEnabled, unsigned int depthSize); bool scissorEnabled, unsigned int depthSize);
ID3D11DepthStencilState *getDepthStencilState(const gl::DepthStencilState &dsState); ID3D11DepthStencilState *getDepthStencilState(const gl::DepthStencilState &dsState);
...@@ -38,14 +42,19 @@ class RenderStateCache ...@@ -38,14 +42,19 @@ class RenderStateCache
unsigned long long mCounter; unsigned long long mCounter;
// Blend state cache // Blend state cache
static std::size_t hashBlendState(const gl::BlendState &blendState); struct BlendStateKey
static bool compareBlendStates(const gl::BlendState &a, const gl::BlendState &b); {
gl::BlendState blendState;
bool rtChannels[D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT][4];
};
static std::size_t hashBlendState(const BlendStateKey &blendState);
static bool compareBlendStates(const BlendStateKey &a, const BlendStateKey &b);
static const unsigned int kMaxBlendStates; static const unsigned int kMaxBlendStates;
typedef std::size_t (*BlendStateHashFunction)(const gl::BlendState &); typedef std::size_t (*BlendStateHashFunction)(const BlendStateKey &);
typedef bool (*BlendStateEqualityFunction)(const gl::BlendState &, const gl::BlendState &); typedef bool (*BlendStateEqualityFunction)(const BlendStateKey &, const BlendStateKey &);
typedef std::pair<ID3D11BlendState*, unsigned long long> BlendStateCounterPair; typedef std::pair<ID3D11BlendState*, unsigned long long> BlendStateCounterPair;
typedef std::unordered_map<gl::BlendState, BlendStateCounterPair, BlendStateHashFunction, BlendStateEqualityFunction> BlendStateMap; typedef std::unordered_map<BlendStateKey, BlendStateCounterPair, BlendStateHashFunction, BlendStateEqualityFunction> BlendStateMap;
BlendStateMap mBlendStateCache; BlendStateMap mBlendStateCache;
// Rasterizer state cache // Rasterizer state cache
......
...@@ -723,7 +723,7 @@ void Renderer11::setRasterizerState(const gl::RasterizerState &rasterState) ...@@ -723,7 +723,7 @@ void Renderer11::setRasterizerState(const gl::RasterizerState &rasterState)
mForceSetRasterState = false; mForceSetRasterState = false;
} }
void Renderer11::setBlendState(const gl::BlendState &blendState, const gl::ColorF &blendColor, void Renderer11::setBlendState(gl::Framebuffer *framebuffer, const gl::BlendState &blendState, const gl::ColorF &blendColor,
unsigned int sampleMask) unsigned int sampleMask)
{ {
if (mForceSetBlendState || if (mForceSetBlendState ||
...@@ -731,7 +731,7 @@ void Renderer11::setBlendState(const gl::BlendState &blendState, const gl::Color ...@@ -731,7 +731,7 @@ void Renderer11::setBlendState(const gl::BlendState &blendState, const gl::Color
memcmp(&blendColor, &mCurBlendColor, sizeof(gl::ColorF)) != 0 || memcmp(&blendColor, &mCurBlendColor, sizeof(gl::ColorF)) != 0 ||
sampleMask != mCurSampleMask) sampleMask != mCurSampleMask)
{ {
ID3D11BlendState *dxBlendState = mStateCache.getBlendState(blendState); ID3D11BlendState *dxBlendState = mStateCache.getBlendState(framebuffer, blendState);
if (!dxBlendState) if (!dxBlendState)
{ {
ERR("NULL blend state returned by RenderStateCache::getBlendState, setting the default " ERR("NULL blend state returned by RenderStateCache::getBlendState, setting the default "
...@@ -1081,6 +1081,7 @@ bool Renderer11::applyRenderTarget(gl::Framebuffer *framebuffer) ...@@ -1081,6 +1081,7 @@ bool Renderer11::applyRenderTarget(gl::Framebuffer *framebuffer)
mRenderTargetDesc.format = renderTargetFormat; mRenderTargetDesc.format = renderTargetFormat;
mForceSetViewport = true; mForceSetViewport = true;
mForceSetScissor = true; mForceSetScissor = true;
mForceSetBlendState = true;
if (!mDepthStencilInitialized || depthSize != mCurDepthSize) if (!mDepthStencilInitialized || depthSize != mCurDepthSize)
{ {
......
...@@ -64,7 +64,7 @@ class Renderer11 : public Renderer ...@@ -64,7 +64,7 @@ class Renderer11 : public Renderer
virtual bool setUniformBuffers(const gl::Buffer *vertexUniformBuffers[], const gl::Buffer *fragmentUniformBuffers[]); virtual bool setUniformBuffers(const gl::Buffer *vertexUniformBuffers[], const gl::Buffer *fragmentUniformBuffers[]);
virtual void setRasterizerState(const gl::RasterizerState &rasterState); virtual void setRasterizerState(const gl::RasterizerState &rasterState);
virtual void setBlendState(const gl::BlendState &blendState, const gl::ColorF &blendColor, virtual void setBlendState(gl::Framebuffer *framebuffer, const gl::BlendState &blendState, const gl::ColorF &blendColor,
unsigned int sampleMask); unsigned int sampleMask);
virtual void setDepthStencilState(const gl::DepthStencilState &depthStencilState, int stencilRef, virtual void setDepthStencilState(const gl::DepthStencilState &depthStencilState, int stencilRef,
int stencilBackRef, bool frontFaceCCW); int stencilBackRef, bool frontFaceCCW);
......
...@@ -872,7 +872,8 @@ void Renderer9::setRasterizerState(const gl::RasterizerState &rasterState) ...@@ -872,7 +872,8 @@ void Renderer9::setRasterizerState(const gl::RasterizerState &rasterState)
mForceSetRasterState = false; mForceSetRasterState = false;
} }
void Renderer9::setBlendState(const gl::BlendState &blendState, const gl::ColorF &blendColor, unsigned int sampleMask) void Renderer9::setBlendState(gl::Framebuffer *framebuffer, const gl::BlendState &blendState, const gl::ColorF &blendColor,
unsigned int sampleMask)
{ {
bool blendStateChanged = mForceSetBlendState || memcmp(&blendState, &mCurBlendState, sizeof(gl::BlendState)) != 0; bool blendStateChanged = mForceSetBlendState || memcmp(&blendState, &mCurBlendState, sizeof(gl::BlendState)) != 0;
bool blendColorChanged = mForceSetBlendState || memcmp(&blendColor, &mCurBlendColor, sizeof(gl::ColorF)) != 0; bool blendColorChanged = mForceSetBlendState || memcmp(&blendColor, &mCurBlendColor, sizeof(gl::ColorF)) != 0;
...@@ -926,6 +927,10 @@ void Renderer9::setBlendState(const gl::BlendState &blendState, const gl::ColorF ...@@ -926,6 +927,10 @@ void Renderer9::setBlendState(const gl::BlendState &blendState, const gl::ColorF
FIXME("Sample alpha to coverage is unimplemented."); FIXME("Sample alpha to coverage is unimplemented.");
} }
gl::Renderbuffer *renderBuffer = framebuffer->getFirstColorbuffer();
GLenum internalFormat = renderBuffer ? renderBuffer->getInternalFormat() : GL_NONE;
GLuint clientVersion = getCurrentClientVersion();
// Set the color mask // Set the color mask
bool zeroColorMaskAllowed = getAdapterVendor() != VENDOR_ID_AMD; bool zeroColorMaskAllowed = getAdapterVendor() != VENDOR_ID_AMD;
// Apparently some ATI cards have a bug where a draw with a zero color // Apparently some ATI cards have a bug where a draw with a zero color
...@@ -934,8 +939,10 @@ void Renderer9::setBlendState(const gl::BlendState &blendState, const gl::ColorF ...@@ -934,8 +939,10 @@ void Renderer9::setBlendState(const gl::BlendState &blendState, const gl::ColorF
// drawing is done. // drawing is done.
// http://code.google.com/p/angleproject/issues/detail?id=169 // http://code.google.com/p/angleproject/issues/detail?id=169
DWORD colorMask = gl_d3d9::ConvertColorMask(blendState.colorMaskRed, blendState.colorMaskGreen, DWORD colorMask = gl_d3d9::ConvertColorMask(gl::GetRedBits(internalFormat, clientVersion) > 0 && blendState.colorMaskRed,
blendState.colorMaskBlue, blendState.colorMaskAlpha); gl::GetGreenBits(internalFormat, clientVersion) > 0 && blendState.colorMaskGreen,
gl::GetBlueBits(internalFormat, clientVersion) > 0 && blendState.colorMaskBlue,
gl::GetAlphaBits(internalFormat, clientVersion) > 0 && blendState.colorMaskAlpha);
if (colorMask == 0 && !zeroColorMaskAllowed) if (colorMask == 0 && !zeroColorMaskAllowed)
{ {
// Enable green channel, but set blending so nothing will be drawn. // Enable green channel, but set blending so nothing will be drawn.
...@@ -1386,6 +1393,7 @@ bool Renderer9::applyRenderTarget(gl::Framebuffer *framebuffer) ...@@ -1386,6 +1393,7 @@ bool Renderer9::applyRenderTarget(gl::Framebuffer *framebuffer)
{ {
mForceSetScissor = true; mForceSetScissor = true;
mForceSetViewport = true; mForceSetViewport = true;
mForceSetBlendState = true;
mRenderTargetDesc.width = renderbufferObject->getWidth(); mRenderTargetDesc.width = renderbufferObject->getWidth();
mRenderTargetDesc.height = renderbufferObject->getHeight(); mRenderTargetDesc.height = renderbufferObject->getHeight();
......
...@@ -76,7 +76,7 @@ class Renderer9 : public Renderer ...@@ -76,7 +76,7 @@ class Renderer9 : public Renderer
virtual bool setUniformBuffers(const gl::Buffer *vertexUniformBuffers[], const gl::Buffer *fragmentUniformBuffers[]); virtual bool setUniformBuffers(const gl::Buffer *vertexUniformBuffers[], const gl::Buffer *fragmentUniformBuffers[]);
virtual void setRasterizerState(const gl::RasterizerState &rasterState); virtual void setRasterizerState(const gl::RasterizerState &rasterState);
virtual void setBlendState(const gl::BlendState &blendState, const gl::ColorF &blendColor, virtual void setBlendState(gl::Framebuffer *framebuffer, const gl::BlendState &blendState, const gl::ColorF &blendColor,
unsigned int sampleMask); unsigned int sampleMask);
virtual void setDepthStencilState(const gl::DepthStencilState &depthStencilState, int stencilRef, virtual void setDepthStencilState(const gl::DepthStencilState &depthStencilState, int stencilRef,
int stencilBackRef, bool frontFaceCCW); int stencilBackRef, bool frontFaceCCW);
......
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