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
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;
ClearBlendStateMap mClearBlendStates;
// Cached cache Keys
gl::DepthStencilState mDepthStencilStateKey;
d3d11::BlendStateKey mBlendStateKey;
ClearShader *mFloatClearShader;
ClearShader *mUintClearShader;
ClearShader *mIntClearShader;
ClearDepthStencilStateMap mClearDepthStencilStates;
ID3D11Buffer *mVertexBuffer;
ID3D11RasterizerState *mRasterizerState;
};
......
......@@ -13,6 +13,7 @@
#include "libANGLE/angletypes.h"
#include "libANGLE/Error.h"
#include "common/angleutils.h"
#include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h"
#include <unordered_map>
......@@ -34,11 +35,11 @@ class RenderStateCache : angle::NonCopyable
void initialize(ID3D11Device *device);
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 getDepthStencilState(const gl::DepthStencilState &dsState,
bool disableDepth,
bool disableStencil,
ID3D11DepthStencilState **outDSState);
gl::Error getSamplerState(const gl::SamplerState &samplerState, ID3D11SamplerState **outSamplerState);
......@@ -47,19 +48,19 @@ class RenderStateCache : angle::NonCopyable
unsigned long long mCounter;
// Blend state cache
struct BlendStateKey
{
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 std::size_t HashBlendState(const d3d11::BlendStateKey &blendState);
static bool CompareBlendStates(const d3d11::BlendStateKey &a, const d3d11::BlendStateKey &b);
static const unsigned int kMaxBlendStates;
typedef std::size_t (*BlendStateHashFunction)(const BlendStateKey &);
typedef bool (*BlendStateEqualityFunction)(const BlendStateKey &, const BlendStateKey &);
typedef std::size_t (*BlendStateHashFunction)(const d3d11::BlendStateKey &);
typedef bool (*BlendStateEqualityFunction)(const d3d11::BlendStateKey &,
const d3d11::BlendStateKey &);
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;
// Rasterizer state cache
......@@ -68,8 +69,8 @@ class RenderStateCache : angle::NonCopyable
gl::RasterizerState rasterizerState;
bool scissorEnabled;
};
static std::size_t hashRasterizerState(const RasterizerStateKey &rasterState);
static bool compareRasterizerStates(const RasterizerStateKey &a, const RasterizerStateKey &b);
static std::size_t HashRasterizerState(const RasterizerStateKey &rasterState);
static bool CompareRasterizerStates(const RasterizerStateKey &a, const RasterizerStateKey &b);
static const unsigned int kMaxRasterizerStates;
typedef std::size_t (*RasterizerStateHashFunction)(const RasterizerStateKey &);
......@@ -79,8 +80,8 @@ class RenderStateCache : angle::NonCopyable
RasterizerStateMap mRasterizerStateCache;
// Depth stencil state cache
static std::size_t hashDepthStencilState(const gl::DepthStencilState &dsState);
static bool compareDepthStencilStates(const gl::DepthStencilState &a, const gl::DepthStencilState &b);
static std::size_t HashDepthStencilState(const gl::DepthStencilState &dsState);
static bool CompareDepthStencilStates(const gl::DepthStencilState &a, const gl::DepthStencilState &b);
static const unsigned int kMaxDepthStencilStates;
typedef std::size_t (*DepthStencilStateHashFunction)(const gl::DepthStencilState &);
......@@ -93,8 +94,8 @@ class RenderStateCache : angle::NonCopyable
DepthStencilStateMap mDepthStencilStateCache;
// Sample state cache
static std::size_t hashSamplerState(const gl::SamplerState &samplerState);
static bool compareSamplerStates(const gl::SamplerState &a, const gl::SamplerState &b);
static std::size_t HashSamplerState(const gl::SamplerState &samplerState);
static bool CompareSamplerStates(const gl::SamplerState &a, const gl::SamplerState &b);
static const unsigned int kMaxSamplerStates;
typedef std::size_t (*SamplerStateHashFunction)(const gl::SamplerState &);
......
......@@ -496,7 +496,9 @@ gl::Error StateManager11::setBlendState(const gl::Framebuffer *framebuffer,
}
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);
......@@ -550,25 +552,41 @@ gl::Error StateManager11::setDepthStencilState(const gl::State &glState)
return gl::NoError();
}
const auto &depthStencilState = glState.getDepthStencilState();
int stencilRef = glState.getStencilRef();
int stencilBackRef = glState.getStencilBackRef();
mCurDepthStencilState = glState.getDepthStencilState();
mCurStencilRef = glState.getStencilRef();
mCurStencilBackRef = glState.getStencilBackRef();
mCurDisableDepth = disableDepth;
mCurDisableStencil = disableStencil;
// get the maximum size of the stencil ref
unsigned int maxStencil = 0;
if (depthStencilState.stencilTest && mCurStencilSize > 0)
if (mCurDepthStencilState.stencilTest && mCurStencilSize > 0)
{
maxStencil = (1 << mCurStencilSize) - 1;
}
ASSERT((depthStencilState.stencilWritemask & maxStencil) ==
(depthStencilState.stencilBackWritemask & maxStencil));
ASSERT(stencilRef == stencilBackRef);
ASSERT((depthStencilState.stencilMask & maxStencil) ==
(depthStencilState.stencilBackMask & maxStencil));
ASSERT((mCurDepthStencilState.stencilWritemask & maxStencil) ==
(mCurDepthStencilState.stencilBackWritemask & maxStencil));
ASSERT(mCurStencilRef == mCurStencilBackRef);
ASSERT((mCurDepthStencilState.stencilMask & maxStencil) ==
(mCurDepthStencilState.stencilBackMask & maxStencil));
ID3D11DepthStencilState *dxDepthStencilState = NULL;
ANGLE_TRY(mRenderer->getStateCache().getDepthStencilState(
depthStencilState, disableDepth, disableStencil, &dxDepthStencilState));
gl::DepthStencilState dsStateKey = glState.getDepthStencilState();
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);
......@@ -580,16 +598,10 @@ gl::Error StateManager11::setDepthStencilState(const gl::State &glState)
"Unexpected value of D3D11_DEFAULT_STENCIL_READ_MASK");
static_assert(D3D11_DEFAULT_STENCIL_WRITE_MASK == 0xFF,
"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);
mCurDepthStencilState = depthStencilState;
mCurStencilRef = stencilRef;
mCurStencilBackRef = stencilBackRef;
mCurDisableDepth = disableDepth;
mCurDisableStencil = disableStencil;
mDepthStencilStateIsDirty = false;
return gl::NoError();
......@@ -803,21 +815,18 @@ void StateManager11::invalidateEverything()
invalidateBoundViews();
}
void StateManager11::setOneTimeRenderTarget(ID3D11RenderTargetView *renderTarget,
ID3D11DepthStencilView *depthStencil)
void StateManager11::setOneTimeRenderTarget(ID3D11RenderTargetView *rtv,
ID3D11DepthStencilView *dsv)
{
mRenderer->getDeviceContext()->OMSetRenderTargets(1, &renderTarget, depthStencil);
mRenderer->getDeviceContext()->OMSetRenderTargets(1, &rtv, dsv);
mRenderTargetIsDirty = true;
}
void StateManager11::setOneTimeRenderTargets(
const std::vector<ID3D11RenderTargetView *> &renderTargets,
ID3D11DepthStencilView *depthStencil)
void StateManager11::setOneTimeRenderTargets(ID3D11RenderTargetView **rtvs,
UINT numRtvs,
ID3D11DepthStencilView *dsv)
{
UINT count = static_cast<UINT>(renderTargets.size());
auto renderTargetPointer = (!renderTargets.empty() ? renderTargets.data() : nullptr);
mRenderer->getDeviceContext()->OMSetRenderTargets(count, renderTargetPointer, depthStencil);
mRenderer->getDeviceContext()->OMSetRenderTargets(numRtvs, (numRtvs > 0) ? rtvs : nullptr, dsv);
mRenderTargetIsDirty = true;
}
......
......@@ -83,10 +83,10 @@ class StateManager11 final : angle::NonCopyable
void invalidateBoundViews();
void invalidateEverything();
void setOneTimeRenderTarget(ID3D11RenderTargetView *renderTarget,
ID3D11DepthStencilView *depthStencil);
void setOneTimeRenderTargets(const std::vector<ID3D11RenderTargetView *> &renderTargets,
ID3D11DepthStencilView *depthStencil);
void setOneTimeRenderTarget(ID3D11RenderTargetView *rtv, ID3D11DepthStencilView *dsv);
void setOneTimeRenderTargets(ID3D11RenderTargetView **rtvs,
UINT numRtvs,
ID3D11DepthStencilView *dsv);
void onBeginQuery(Query11 *query);
void onDeleteQueryObject(Query11 *query);
......
......@@ -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 d3d11
......
......@@ -55,6 +55,8 @@ UINT ConvertMaxAnisotropy(float maxAnisotropy, D3D_FEATURE_LEVEL featureLevel);
D3D11_QUERY ConvertQueryType(GLenum queryType);
UINT8 GetColorMask(const gl::InternalFormat *formatInfo);
} // namespace gl_d3d11
namespace d3d11_gl
......@@ -132,6 +134,13 @@ void SetPositionDepthColorVertex(PositionDepthColorVertex<T>* vertex, float x, f
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);
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