Commit 95f6cedd by Shahmeer Esmail Committed by Commit Bot

RenderstateCache and Clear11 Optimizations

- Unify DepthStencilState and BlendState caches in RenderStateCache with those in Clear11. This will increase cache hit rate and reduce memory usage. - Apply DepthStencilState and BlendState only when required to reduce state sets. BUG=angleproject:1632 Change-Id: I244e3ba189f82814638fa90e2617aa5441024d0f Reviewed-on: https://chromium-review.googlesource.com/453888 Commit-Queue: Jamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org>
parent d0fcb90d
...@@ -60,35 +60,17 @@ class Clear11 : angle::NonCopyable ...@@ -60,35 +60,17 @@ class Clear11 : angle::NonCopyable
d3d11::LazyShader<ID3D11PixelShader> pixelShader; d3d11::LazyShader<ID3D11PixelShader> pixelShader;
}; };
template <unsigned int vsSize, unsigned int psSize>
static ClearShader CreateClearShader(ID3D11Device *device, DXGI_FORMAT colorType, const BYTE(&vsByteCode)[vsSize], const BYTE(&psByteCode)[psSize]);
struct ClearBlendInfo
{
bool maskChannels[D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT][4];
};
typedef bool(*ClearBlendInfoComparisonFunction)(const ClearBlendInfo&, const ClearBlendInfo &);
typedef std::map<ClearBlendInfo, ID3D11BlendState*, ClearBlendInfoComparisonFunction> ClearBlendStateMap;
struct ClearDepthStencilInfo
{
bool clearDepth;
bool clearStencil;
UINT8 stencilWriteMask;
};
typedef bool(*ClearDepthStencilInfoComparisonFunction)(const ClearDepthStencilInfo&, const ClearDepthStencilInfo &);
typedef std::map<ClearDepthStencilInfo, ID3D11DepthStencilState*, ClearDepthStencilInfoComparisonFunction> ClearDepthStencilStateMap;
Renderer11 *mRenderer; Renderer11 *mRenderer;
ClearBlendStateMap mClearBlendStates; // Cached cache Keys
gl::DepthStencilState mDepthStencilStateKey;
d3d11::BlendStateKey mBlendStateKey;
ClearShader *mFloatClearShader; ClearShader *mFloatClearShader;
ClearShader *mUintClearShader; ClearShader *mUintClearShader;
ClearShader *mIntClearShader; ClearShader *mIntClearShader;
ClearDepthStencilStateMap mClearDepthStencilStates;
ID3D11Buffer *mVertexBuffer; ID3D11Buffer *mVertexBuffer;
ID3D11RasterizerState *mRasterizerState; ID3D11RasterizerState *mRasterizerState;
}; };
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
#include "libANGLE/angletypes.h" #include "libANGLE/angletypes.h"
#include "libANGLE/Error.h" #include "libANGLE/Error.h"
#include "common/angleutils.h" #include "common/angleutils.h"
#include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h"
#include <unordered_map> #include <unordered_map>
...@@ -34,11 +35,11 @@ class RenderStateCache : angle::NonCopyable ...@@ -34,11 +35,11 @@ class RenderStateCache : angle::NonCopyable
void initialize(ID3D11Device *device); void initialize(ID3D11Device *device);
void clear(); void clear();
gl::Error getBlendState(const gl::Framebuffer *framebuffer, const gl::BlendState &blendState, ID3D11BlendState **outBlendState); static d3d11::BlendStateKey GetBlendStateKey(const gl::Framebuffer *framebuffer,
const gl::BlendState &blendState);
gl::Error getBlendState(const d3d11::BlendStateKey &key, ID3D11BlendState **outBlendState);
gl::Error getRasterizerState(const gl::RasterizerState &rasterState, bool scissorEnabled, ID3D11RasterizerState **outRasterizerState); gl::Error getRasterizerState(const gl::RasterizerState &rasterState, bool scissorEnabled, ID3D11RasterizerState **outRasterizerState);
gl::Error getDepthStencilState(const gl::DepthStencilState &dsState, gl::Error getDepthStencilState(const gl::DepthStencilState &dsState,
bool disableDepth,
bool disableStencil,
ID3D11DepthStencilState **outDSState); ID3D11DepthStencilState **outDSState);
gl::Error getSamplerState(const gl::SamplerState &samplerState, ID3D11SamplerState **outSamplerState); gl::Error getSamplerState(const gl::SamplerState &samplerState, ID3D11SamplerState **outSamplerState);
...@@ -47,19 +48,19 @@ class RenderStateCache : angle::NonCopyable ...@@ -47,19 +48,19 @@ class RenderStateCache : angle::NonCopyable
unsigned long long mCounter; unsigned long long mCounter;
// Blend state cache // Blend state cache
struct BlendStateKey static std::size_t HashBlendState(const d3d11::BlendStateKey &blendState);
{ static bool CompareBlendStates(const d3d11::BlendStateKey &a, const d3d11::BlendStateKey &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 BlendStateKey &); typedef std::size_t (*BlendStateHashFunction)(const d3d11::BlendStateKey &);
typedef bool (*BlendStateEqualityFunction)(const BlendStateKey &, const BlendStateKey &); typedef bool (*BlendStateEqualityFunction)(const d3d11::BlendStateKey &,
const d3d11::BlendStateKey &);
typedef std::pair<ID3D11BlendState*, unsigned long long> BlendStateCounterPair; typedef std::pair<ID3D11BlendState*, unsigned long long> BlendStateCounterPair;
typedef std::unordered_map<BlendStateKey, BlendStateCounterPair, BlendStateHashFunction, BlendStateEqualityFunction> BlendStateMap; typedef std::unordered_map<d3d11::BlendStateKey,
BlendStateCounterPair,
BlendStateHashFunction,
BlendStateEqualityFunction>
BlendStateMap;
BlendStateMap mBlendStateCache; BlendStateMap mBlendStateCache;
// Rasterizer state cache // Rasterizer state cache
...@@ -68,8 +69,8 @@ class RenderStateCache : angle::NonCopyable ...@@ -68,8 +69,8 @@ class RenderStateCache : angle::NonCopyable
gl::RasterizerState rasterizerState; gl::RasterizerState rasterizerState;
bool scissorEnabled; bool scissorEnabled;
}; };
static std::size_t hashRasterizerState(const RasterizerStateKey &rasterState); static std::size_t HashRasterizerState(const RasterizerStateKey &rasterState);
static bool compareRasterizerStates(const RasterizerStateKey &a, const RasterizerStateKey &b); static bool CompareRasterizerStates(const RasterizerStateKey &a, const RasterizerStateKey &b);
static const unsigned int kMaxRasterizerStates; static const unsigned int kMaxRasterizerStates;
typedef std::size_t (*RasterizerStateHashFunction)(const RasterizerStateKey &); typedef std::size_t (*RasterizerStateHashFunction)(const RasterizerStateKey &);
...@@ -79,8 +80,8 @@ class RenderStateCache : angle::NonCopyable ...@@ -79,8 +80,8 @@ class RenderStateCache : angle::NonCopyable
RasterizerStateMap mRasterizerStateCache; RasterizerStateMap mRasterizerStateCache;
// Depth stencil state cache // Depth stencil state cache
static std::size_t hashDepthStencilState(const gl::DepthStencilState &dsState); static std::size_t HashDepthStencilState(const gl::DepthStencilState &dsState);
static bool compareDepthStencilStates(const gl::DepthStencilState &a, const gl::DepthStencilState &b); static bool CompareDepthStencilStates(const gl::DepthStencilState &a, const gl::DepthStencilState &b);
static const unsigned int kMaxDepthStencilStates; static const unsigned int kMaxDepthStencilStates;
typedef std::size_t (*DepthStencilStateHashFunction)(const gl::DepthStencilState &); typedef std::size_t (*DepthStencilStateHashFunction)(const gl::DepthStencilState &);
...@@ -93,8 +94,8 @@ class RenderStateCache : angle::NonCopyable ...@@ -93,8 +94,8 @@ class RenderStateCache : angle::NonCopyable
DepthStencilStateMap mDepthStencilStateCache; DepthStencilStateMap mDepthStencilStateCache;
// Sample state cache // Sample state cache
static std::size_t hashSamplerState(const gl::SamplerState &samplerState); static std::size_t HashSamplerState(const gl::SamplerState &samplerState);
static bool compareSamplerStates(const gl::SamplerState &a, const gl::SamplerState &b); static bool CompareSamplerStates(const gl::SamplerState &a, const gl::SamplerState &b);
static const unsigned int kMaxSamplerStates; static const unsigned int kMaxSamplerStates;
typedef std::size_t (*SamplerStateHashFunction)(const gl::SamplerState &); typedef std::size_t (*SamplerStateHashFunction)(const gl::SamplerState &);
......
...@@ -496,7 +496,9 @@ gl::Error StateManager11::setBlendState(const gl::Framebuffer *framebuffer, ...@@ -496,7 +496,9 @@ gl::Error StateManager11::setBlendState(const gl::Framebuffer *framebuffer,
} }
ID3D11BlendState *dxBlendState = nullptr; ID3D11BlendState *dxBlendState = nullptr;
ANGLE_TRY(mRenderer->getStateCache().getBlendState(framebuffer, blendState, &dxBlendState)); const d3d11::BlendStateKey &key = RenderStateCache::GetBlendStateKey(framebuffer, blendState);
ANGLE_TRY(mRenderer->getStateCache().getBlendState(key, &dxBlendState));
ASSERT(dxBlendState != nullptr); ASSERT(dxBlendState != nullptr);
...@@ -550,25 +552,41 @@ gl::Error StateManager11::setDepthStencilState(const gl::State &glState) ...@@ -550,25 +552,41 @@ gl::Error StateManager11::setDepthStencilState(const gl::State &glState)
return gl::NoError(); return gl::NoError();
} }
const auto &depthStencilState = glState.getDepthStencilState(); mCurDepthStencilState = glState.getDepthStencilState();
int stencilRef = glState.getStencilRef(); mCurStencilRef = glState.getStencilRef();
int stencilBackRef = glState.getStencilBackRef(); mCurStencilBackRef = glState.getStencilBackRef();
mCurDisableDepth = disableDepth;
mCurDisableStencil = disableStencil;
// get the maximum size of the stencil ref // get the maximum size of the stencil ref
unsigned int maxStencil = 0; unsigned int maxStencil = 0;
if (depthStencilState.stencilTest && mCurStencilSize > 0) if (mCurDepthStencilState.stencilTest && mCurStencilSize > 0)
{ {
maxStencil = (1 << mCurStencilSize) - 1; maxStencil = (1 << mCurStencilSize) - 1;
} }
ASSERT((depthStencilState.stencilWritemask & maxStencil) == ASSERT((mCurDepthStencilState.stencilWritemask & maxStencil) ==
(depthStencilState.stencilBackWritemask & maxStencil)); (mCurDepthStencilState.stencilBackWritemask & maxStencil));
ASSERT(stencilRef == stencilBackRef); ASSERT(mCurStencilRef == mCurStencilBackRef);
ASSERT((depthStencilState.stencilMask & maxStencil) == ASSERT((mCurDepthStencilState.stencilMask & maxStencil) ==
(depthStencilState.stencilBackMask & maxStencil)); (mCurDepthStencilState.stencilBackMask & maxStencil));
ID3D11DepthStencilState *dxDepthStencilState = NULL; ID3D11DepthStencilState *dxDepthStencilState = NULL;
ANGLE_TRY(mRenderer->getStateCache().getDepthStencilState( gl::DepthStencilState dsStateKey = glState.getDepthStencilState();
depthStencilState, disableDepth, disableStencil, &dxDepthStencilState));
if (disableDepth)
{
dsStateKey.depthTest = false;
dsStateKey.depthMask = false;
}
if (disableStencil)
{
dsStateKey.stencilWritemask = 0;
dsStateKey.stencilBackWritemask = 0;
dsStateKey.stencilTest = false;
}
ANGLE_TRY(mRenderer->getStateCache().getDepthStencilState(dsStateKey, &dxDepthStencilState));
ASSERT(dxDepthStencilState); ASSERT(dxDepthStencilState);
...@@ -580,16 +598,10 @@ gl::Error StateManager11::setDepthStencilState(const gl::State &glState) ...@@ -580,16 +598,10 @@ gl::Error StateManager11::setDepthStencilState(const gl::State &glState)
"Unexpected value of D3D11_DEFAULT_STENCIL_READ_MASK"); "Unexpected value of D3D11_DEFAULT_STENCIL_READ_MASK");
static_assert(D3D11_DEFAULT_STENCIL_WRITE_MASK == 0xFF, static_assert(D3D11_DEFAULT_STENCIL_WRITE_MASK == 0xFF,
"Unexpected value of D3D11_DEFAULT_STENCIL_WRITE_MASK"); "Unexpected value of D3D11_DEFAULT_STENCIL_WRITE_MASK");
UINT dxStencilRef = std::min<UINT>(stencilRef, 0xFFu); UINT dxStencilRef = std::min<UINT>(mCurStencilRef, 0xFFu);
mRenderer->getDeviceContext()->OMSetDepthStencilState(dxDepthStencilState, dxStencilRef); mRenderer->getDeviceContext()->OMSetDepthStencilState(dxDepthStencilState, dxStencilRef);
mCurDepthStencilState = depthStencilState;
mCurStencilRef = stencilRef;
mCurStencilBackRef = stencilBackRef;
mCurDisableDepth = disableDepth;
mCurDisableStencil = disableStencil;
mDepthStencilStateIsDirty = false; mDepthStencilStateIsDirty = false;
return gl::NoError(); return gl::NoError();
...@@ -803,21 +815,18 @@ void StateManager11::invalidateEverything() ...@@ -803,21 +815,18 @@ void StateManager11::invalidateEverything()
invalidateBoundViews(); invalidateBoundViews();
} }
void StateManager11::setOneTimeRenderTarget(ID3D11RenderTargetView *renderTarget, void StateManager11::setOneTimeRenderTarget(ID3D11RenderTargetView *rtv,
ID3D11DepthStencilView *depthStencil) ID3D11DepthStencilView *dsv)
{ {
mRenderer->getDeviceContext()->OMSetRenderTargets(1, &renderTarget, depthStencil); mRenderer->getDeviceContext()->OMSetRenderTargets(1, &rtv, dsv);
mRenderTargetIsDirty = true; mRenderTargetIsDirty = true;
} }
void StateManager11::setOneTimeRenderTargets( void StateManager11::setOneTimeRenderTargets(ID3D11RenderTargetView **rtvs,
const std::vector<ID3D11RenderTargetView *> &renderTargets, UINT numRtvs,
ID3D11DepthStencilView *depthStencil) ID3D11DepthStencilView *dsv)
{ {
UINT count = static_cast<UINT>(renderTargets.size()); mRenderer->getDeviceContext()->OMSetRenderTargets(numRtvs, (numRtvs > 0) ? rtvs : nullptr, dsv);
auto renderTargetPointer = (!renderTargets.empty() ? renderTargets.data() : nullptr);
mRenderer->getDeviceContext()->OMSetRenderTargets(count, renderTargetPointer, depthStencil);
mRenderTargetIsDirty = true; mRenderTargetIsDirty = true;
} }
......
...@@ -83,10 +83,10 @@ class StateManager11 final : angle::NonCopyable ...@@ -83,10 +83,10 @@ class StateManager11 final : angle::NonCopyable
void invalidateBoundViews(); void invalidateBoundViews();
void invalidateEverything(); void invalidateEverything();
void setOneTimeRenderTarget(ID3D11RenderTargetView *renderTarget, void setOneTimeRenderTarget(ID3D11RenderTargetView *rtv, ID3D11DepthStencilView *dsv);
ID3D11DepthStencilView *depthStencil); void setOneTimeRenderTargets(ID3D11RenderTargetView **rtvs,
void setOneTimeRenderTargets(const std::vector<ID3D11RenderTargetView *> &renderTargets, UINT numRtvs,
ID3D11DepthStencilView *depthStencil); ID3D11DepthStencilView *dsv);
void onBeginQuery(Query11 *query); void onBeginQuery(Query11 *query);
void onDeleteQueryObject(Query11 *query); void onDeleteQueryObject(Query11 *query);
......
...@@ -1697,6 +1697,29 @@ D3D11_QUERY ConvertQueryType(GLenum queryType) ...@@ -1697,6 +1697,29 @@ D3D11_QUERY ConvertQueryType(GLenum queryType)
} }
} }
// Get the D3D11 write mask covering all color channels of a given format
UINT8 GetColorMask(const gl::InternalFormat *formatInfo)
{
UINT8 mask = 0;
if (formatInfo->redBits > 0)
{
mask |= D3D11_COLOR_WRITE_ENABLE_RED;
}
if (formatInfo->greenBits > 0)
{
mask |= D3D11_COLOR_WRITE_ENABLE_GREEN;
}
if (formatInfo->blueBits > 0)
{
mask |= D3D11_COLOR_WRITE_ENABLE_BLUE;
}
if (formatInfo->alphaBits > 0)
{
mask |= D3D11_COLOR_WRITE_ENABLE_ALPHA;
}
return mask;
}
} // namespace gl_d3d11 } // namespace gl_d3d11
namespace d3d11 namespace d3d11
......
...@@ -55,6 +55,8 @@ UINT ConvertMaxAnisotropy(float maxAnisotropy, D3D_FEATURE_LEVEL featureLevel); ...@@ -55,6 +55,8 @@ UINT ConvertMaxAnisotropy(float maxAnisotropy, D3D_FEATURE_LEVEL featureLevel);
D3D11_QUERY ConvertQueryType(GLenum queryType); D3D11_QUERY ConvertQueryType(GLenum queryType);
UINT8 GetColorMask(const gl::InternalFormat *formatInfo);
} // namespace gl_d3d11 } // namespace gl_d3d11
namespace d3d11_gl namespace d3d11_gl
...@@ -132,6 +134,13 @@ void SetPositionDepthColorVertex(PositionDepthColorVertex<T>* vertex, float x, f ...@@ -132,6 +134,13 @@ void SetPositionDepthColorVertex(PositionDepthColorVertex<T>* vertex, float x, f
vertex->a = color.alpha; vertex->a = color.alpha;
} }
struct BlendStateKey
{
gl::BlendState blendState;
bool mrt;
uint8_t rtvMasks[D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT];
};
HRESULT SetDebugName(ID3D11DeviceChild *resource, const char *name); HRESULT SetDebugName(ID3D11DeviceChild *resource, const char *name);
template <typename T> template <typename T>
......
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