Commit 779a25a8 by Alexey Knyazev Committed by Commit Bot

D3D11: Migrate to the new blend state tracking

Migrate D3D ClearParameters struct to the new color mask storage Bug: angleproject:4394 Change-Id: Ibeb64e4bbb2758b9c8271fc3c59d2d675850b0a8 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2165886 Commit-Queue: Kenneth Russell <kbr@chromium.org> Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org>
parent 78ef4133
......@@ -288,6 +288,13 @@ void BlendStateExt::setColorMask(const bool red,
mColorMask = expandColorMaskValue(red, green, blue, alpha);
}
void BlendStateExt::setColorMaskIndexed(const size_t index, const uint8_t value)
{
ASSERT(index < mMaxDrawBuffers);
ASSERT(value <= 0xF);
ColorMaskStorage::SetValueIndexed(index, value, &mColorMask);
}
void BlendStateExt::setColorMaskIndexed(const size_t index,
const bool red,
const bool green,
......@@ -298,6 +305,12 @@ void BlendStateExt::setColorMaskIndexed(const size_t index,
ColorMaskStorage::SetValueIndexed(index, PackColorMask(red, green, blue, alpha), &mColorMask);
}
uint8_t BlendStateExt::getColorMaskIndexed(const size_t index) const
{
ASSERT(index < mMaxDrawBuffers);
return ColorMaskStorage::GetValueIndexed(index, mColorMask);
}
void BlendStateExt::getColorMaskIndexed(const size_t index,
bool *red,
bool *green,
......@@ -350,6 +363,20 @@ void BlendStateExt::setEquationsIndexed(const size_t index,
&mEquationAlpha);
}
void BlendStateExt::setEquationsIndexed(const size_t index,
const size_t sourceIndex,
const BlendStateExt &source)
{
ASSERT(index < mMaxDrawBuffers);
ASSERT(sourceIndex < source.mMaxDrawBuffers);
EquationStorage::SetValueIndexed(
index, EquationStorage::GetValueIndexed(sourceIndex, source.mEquationColor),
&mEquationColor);
EquationStorage::SetValueIndexed(
index, EquationStorage::GetValueIndexed(sourceIndex, source.mEquationAlpha),
&mEquationAlpha);
}
GLenum BlendStateExt::getEquationColorIndexed(size_t index) const
{
ASSERT(index < mMaxDrawBuffers);
......@@ -426,6 +453,22 @@ void BlendStateExt::setFactorsIndexed(const size_t index,
FactorStorage::SetValueIndexed(index, FromGLenum<BlendFactorType>(dstAlpha), &mDstAlpha);
}
void BlendStateExt::setFactorsIndexed(const size_t index,
const size_t sourceIndex,
const BlendStateExt &source)
{
ASSERT(index < mMaxDrawBuffers);
ASSERT(sourceIndex < source.mMaxDrawBuffers);
FactorStorage::SetValueIndexed(
index, FactorStorage::GetValueIndexed(sourceIndex, source.mSrcColor), &mSrcColor);
FactorStorage::SetValueIndexed(
index, FactorStorage::GetValueIndexed(sourceIndex, source.mDstColor), &mDstColor);
FactorStorage::SetValueIndexed(
index, FactorStorage::GetValueIndexed(sourceIndex, source.mSrcAlpha), &mSrcAlpha);
FactorStorage::SetValueIndexed(
index, FactorStorage::GetValueIndexed(sourceIndex, source.mDstAlpha), &mDstAlpha);
}
GLenum BlendStateExt::getSrcColorIndexed(size_t index) const
{
ASSERT(index < mMaxDrawBuffers);
......
......@@ -554,11 +554,13 @@ class BlendStateExt final
const bool alpha) const;
ColorMaskStorage::Type expandColorMaskIndexed(const size_t index) const;
void setColorMask(const bool red, const bool green, const bool blue, const bool alpha);
void setColorMaskIndexed(const size_t index, const uint8_t value);
void setColorMaskIndexed(const size_t index,
const bool red,
const bool green,
const bool blue,
const bool alpha);
uint8_t getColorMaskIndexed(const size_t index) const;
void getColorMaskIndexed(const size_t index,
bool *red,
bool *green,
......@@ -573,6 +575,9 @@ class BlendStateExt final
EquationStorage::Type expandEquationAlphaIndexed(const size_t index) const;
void setEquations(const GLenum modeColor, const GLenum modeAlpha);
void setEquationsIndexed(const size_t index, const GLenum modeColor, const GLenum modeAlpha);
void setEquationsIndexed(const size_t index,
const size_t otherIndex,
const BlendStateExt &other);
GLenum getEquationColorIndexed(size_t index) const;
GLenum getEquationAlphaIndexed(size_t index) const;
DrawBufferMask compareEquations(const EquationStorage::Type color,
......@@ -594,6 +599,7 @@ class BlendStateExt final
const GLenum dstColor,
const GLenum srcAlpha,
const GLenum dstAlpha);
void setFactorsIndexed(const size_t index, const size_t otherIndex, const BlendStateExt &other);
GLenum getSrcColorIndexed(size_t index) const;
GLenum getDstColorIndexed(size_t index) const;
GLenum getSrcAlphaIndexed(size_t index) const;
......
......@@ -99,6 +99,12 @@ TEST(BlendStateExt, ColorMask)
blendStateExt.setColorMaskIndexed(3, false, true, false, true);
ASSERT_EQ(blendStateExt.mColorMask, is64Bit ? 0x050A050505u : 0x5A555u);
blendStateExt.setColorMaskIndexed(3, 0xF);
ASSERT_EQ(blendStateExt.getColorMaskIndexed(3), 0xF);
blendStateExt.setColorMaskIndexed(3, 0xA);
ASSERT_EQ(blendStateExt.getColorMaskIndexed(3), 0xA);
bool r, g, b, a;
blendStateExt.getColorMaskIndexed(3, &r, &g, &b, &a);
ASSERT_FALSE(r);
......@@ -141,6 +147,16 @@ TEST(BlendStateExt, BlendEquations)
const gl::DrawBufferMask diff =
blendStateExt.compareEquations(otherEquationColor, otherEquationAlpha);
ASSERT_EQ(diff.to_ulong(), 40u);
// Copy buffer 3 to buffer 0
blendStateExt.setEquationsIndexed(0, 3, blendStateExt);
ASSERT_EQ(blendStateExt.getEquationColorIndexed(0), static_cast<GLenum>(GL_MAX));
ASSERT_EQ(blendStateExt.getEquationAlphaIndexed(0), static_cast<GLenum>(GL_FUNC_SUBTRACT));
// Copy buffer 5 to buffer 0
blendStateExt.setEquationsIndexed(0, 5, blendStateExt);
ASSERT_EQ(blendStateExt.getEquationColorIndexed(0), static_cast<GLenum>(GL_MIN));
ASSERT_EQ(blendStateExt.getEquationAlphaIndexed(0), static_cast<GLenum>(GL_FUNC_ADD));
}
// Test blend factors manipulations
......@@ -181,6 +197,34 @@ TEST(BlendStateExt, BlendFactors)
const gl::DrawBufferMask diff =
blendStateExt.compareFactors(otherSrcColor, otherDstColor, otherSrcAlpha, otherDstAlpha);
ASSERT_EQ(diff.to_ulong(), 169u);
// Copy buffer 0 to buffer 1
blendStateExt.setFactorsIndexed(1, 0, blendStateExt);
ASSERT_EQ(blendStateExt.getSrcColorIndexed(1), static_cast<GLenum>(GL_ONE));
ASSERT_EQ(blendStateExt.getDstColorIndexed(1), static_cast<GLenum>(GL_DST_COLOR));
ASSERT_EQ(blendStateExt.getSrcAlphaIndexed(1), static_cast<GLenum>(GL_SRC_ALPHA));
ASSERT_EQ(blendStateExt.getDstAlphaIndexed(1), static_cast<GLenum>(GL_DST_ALPHA));
// Copy buffer 3 to buffer 1
blendStateExt.setFactorsIndexed(1, 3, blendStateExt);
ASSERT_EQ(blendStateExt.getSrcColorIndexed(1), static_cast<GLenum>(GL_SRC_COLOR));
ASSERT_EQ(blendStateExt.getDstColorIndexed(1), static_cast<GLenum>(GL_ONE));
ASSERT_EQ(blendStateExt.getSrcAlphaIndexed(1), static_cast<GLenum>(GL_SRC_ALPHA));
ASSERT_EQ(blendStateExt.getDstAlphaIndexed(1), static_cast<GLenum>(GL_DST_ALPHA));
// Copy buffer 5 to buffer 1
blendStateExt.setFactorsIndexed(1, 5, blendStateExt);
ASSERT_EQ(blendStateExt.getSrcColorIndexed(1), static_cast<GLenum>(GL_SRC_COLOR));
ASSERT_EQ(blendStateExt.getDstColorIndexed(1), static_cast<GLenum>(GL_DST_COLOR));
ASSERT_EQ(blendStateExt.getSrcAlphaIndexed(1), static_cast<GLenum>(GL_ONE));
ASSERT_EQ(blendStateExt.getDstAlphaIndexed(1), static_cast<GLenum>(GL_DST_ALPHA));
// Copy buffer 7 to buffer 1
blendStateExt.setFactorsIndexed(1, 7, blendStateExt);
ASSERT_EQ(blendStateExt.getSrcColorIndexed(1), static_cast<GLenum>(GL_SRC_COLOR));
ASSERT_EQ(blendStateExt.getDstColorIndexed(1), static_cast<GLenum>(GL_DST_COLOR));
ASSERT_EQ(blendStateExt.getSrcAlphaIndexed(1), static_cast<GLenum>(GL_SRC_ALPHA));
ASSERT_EQ(blendStateExt.getDstAlphaIndexed(1), static_cast<GLenum>(GL_ONE));
}
} // namespace angle
......@@ -34,8 +34,6 @@ ClearParameters GetClearParameters(const gl::State &state, GLbitfield mask)
ClearParameters clearParams;
memset(&clearParams, 0, sizeof(ClearParameters));
const auto &blendStateArray = state.getBlendStateArray();
clearParams.colorF = state.getColorClearValue();
clearParams.colorType = GL_FLOAT;
clearParams.clearDepth = false;
......@@ -49,15 +47,15 @@ ClearParameters GetClearParameters(const gl::State &state, GLbitfield mask)
const gl::Framebuffer *framebufferObject = state.getDrawFramebuffer();
const bool clearColor =
(mask & GL_COLOR_BUFFER_BIT) && framebufferObject->hasEnabledDrawBuffer();
ASSERT(blendStateArray.size() == gl::IMPLEMENTATION_MAX_DRAW_BUFFERS);
for (size_t i = 0; i < blendStateArray.size(); i++)
if (clearColor)
{
clearParams.clearColor.set();
}
else
{
clearParams.clearColor[i] = clearColor;
clearParams.colorMaskRed[i] = blendStateArray[i].colorMaskRed;
clearParams.colorMaskGreen[i] = blendStateArray[i].colorMaskGreen;
clearParams.colorMaskBlue[i] = blendStateArray[i].colorMaskBlue;
clearParams.colorMaskAlpha[i] = blendStateArray[i].colorMaskAlpha;
clearParams.clearColor.reset();
}
clearParams.colorMask = state.getBlendStateExt().mColorMask;
if (mask & GL_DEPTH_BUFFER_BIT)
{
......
......@@ -40,10 +40,7 @@ struct ClearParameters
gl::ColorI colorI;
gl::ColorUI colorUI;
GLenum colorType;
gl::DrawBufferMask colorMaskRed;
gl::DrawBufferMask colorMaskGreen;
gl::DrawBufferMask colorMaskBlue;
gl::DrawBufferMask colorMaskAlpha;
gl::BlendStateExt::ColorMaskStorage::Type colorMask;
bool clearDepth;
float depthValue;
......
......@@ -287,16 +287,7 @@ angle::Result Clear11::ensureResourcesInitialized(const gl::Context *context)
mDepthStencilStateKey.stencilBackFunc = GL_ALWAYS;
// Initialize BlendStateKey with defaults
for (gl::BlendState &blendState : mBlendStateKey.blendStateArray)
{
blendState.blend = false;
blendState.sourceBlendRGB = GL_ONE;
blendState.sourceBlendAlpha = GL_ONE;
blendState.destBlendRGB = GL_ZERO;
blendState.destBlendAlpha = GL_ZERO;
blendState.blendEquationRGB = GL_FUNC_ADD;
blendState.blendEquationAlpha = GL_FUNC_ADD;
}
mBlendStateKey.blendStateExt = gl::BlendStateExt(mRenderer->getNativeCaps().maxDrawBuffers);
mResourcesInitialized = true;
return angle::Result::Continue;
......@@ -468,11 +459,8 @@ angle::Result Clear11::clearFramebuffer(const gl::Context *context,
const auto &colorAttachments = fboData.getColorAttachments();
for (auto colorAttachmentIndex : fboData.getEnabledDrawBuffers())
{
const uint8_t colorMask =
gl_d3d11::ConvertColorMask(clearParams.colorMaskRed[colorAttachmentIndex],
clearParams.colorMaskGreen[colorAttachmentIndex],
clearParams.colorMaskBlue[colorAttachmentIndex],
clearParams.colorMaskAlpha[colorAttachmentIndex]);
const uint8_t colorMask = gl::BlendStateExt::ColorMaskStorage::GetValueIndexed(
colorAttachmentIndex, clearParams.colorMask);
commonColorMask |= colorMask;
......@@ -501,10 +489,10 @@ angle::Result Clear11::clearFramebuffer(const gl::Context *context,
<< ").";
}
if ((formatInfo.redBits == 0 || !clearParams.colorMaskRed[colorAttachmentIndex]) &&
(formatInfo.greenBits == 0 || !clearParams.colorMaskGreen[colorAttachmentIndex]) &&
(formatInfo.blueBits == 0 || !clearParams.colorMaskBlue[colorAttachmentIndex]) &&
(formatInfo.alphaBits == 0 || !clearParams.colorMaskAlpha[colorAttachmentIndex]))
bool r, g, b, a;
gl::BlendStateExt::UnpackColorMask(colorMask, &r, &g, &b, &a);
if ((formatInfo.redBits == 0 || !r) && (formatInfo.greenBits == 0 || !g) &&
(formatInfo.blueBits == 0 || !b) && (formatInfo.alphaBits == 0 || !a))
{
// Every channel either does not exist in the render target or is masked out
continue;
......@@ -514,11 +502,9 @@ angle::Result Clear11::clearFramebuffer(const gl::Context *context,
ASSERT(framebufferRTV.valid());
if ((!(mRenderer->getRenderer11DeviceCaps().supportsClearView) && needScissoredClear) ||
clearParams.colorType != GL_FLOAT ||
(formatInfo.redBits > 0 && !clearParams.colorMaskRed[colorAttachmentIndex]) ||
(formatInfo.greenBits > 0 && !clearParams.colorMaskGreen[colorAttachmentIndex]) ||
(formatInfo.blueBits > 0 && !clearParams.colorMaskBlue[colorAttachmentIndex]) ||
(formatInfo.alphaBits > 0 && !clearParams.colorMaskAlpha[colorAttachmentIndex]))
clearParams.colorType != GL_FLOAT || (formatInfo.redBits > 0 && !r) ||
(formatInfo.greenBits > 0 && !g) || (formatInfo.blueBits > 0 && !b) ||
(formatInfo.alphaBits > 0 && !a))
{
rtvs[numRtvs] = framebufferRTV.get();
rtvMasks[numRtvs] = gl_d3d11::GetColorMask(formatInfo) & colorMask;
......@@ -650,17 +636,13 @@ angle::Result Clear11::clearFramebuffer(const gl::Context *context,
ASSERT(numRtvs <= static_cast<uint32_t>(mRenderer->getNativeCaps().maxDrawBuffers));
// Setup BlendStateKey parameters
for (size_t i = 0; i < mBlendStateKey.blendStateArray.size(); i++)
mBlendStateKey.blendStateExt.setColorMask(false, false, false, false);
for (size_t i = 0; i < numRtvs; i++)
{
gl::BlendState &blendState = mBlendStateKey.blendStateArray[i];
blendState.colorMaskRed = clearParams.colorMaskRed[i];
blendState.colorMaskGreen = clearParams.colorMaskGreen[i];
blendState.colorMaskBlue = clearParams.colorMaskBlue[i];
blendState.colorMaskAlpha = clearParams.colorMaskAlpha[i];
mBlendStateKey.blendStateExt.setColorMaskIndexed(i, rtvMasks[i]);
}
mBlendStateKey.rtvMax = static_cast<uint16_t>(numRtvs);
memcpy(mBlendStateKey.rtvMasks, &rtvMasks[0], sizeof(mBlendStateKey.rtvMasks));
// Get BlendState
const d3d11::BlendState *blendState = nullptr;
......
......@@ -45,31 +45,28 @@ void RenderStateCache::clear()
// static
d3d11::BlendStateKey RenderStateCache::GetBlendStateKey(const gl::Context *context,
Framebuffer11 *framebuffer11,
const gl::BlendStateArray &blendStateArray,
const gl::BlendStateExt &blendStateExt,
bool sampleAlphaToCoverage)
{
d3d11::BlendStateKey key;
// All elements of the BlendStateArray inside the key should be initialized for the caching to
// All fields of the BlendStateExt inside the key should be initialized for the caching to
// work correctly. Due to mrt_perf_workaround, the actual indices of active draw buffers may be
// different, so both arrays should be tracked.
key.blendStateExt = gl::BlendStateExt(blendStateExt.mMaxDrawBuffers);
const gl::AttachmentList &colorbuffers = framebuffer11->getColorAttachmentsForRender(context);
const gl::DrawBufferMask colorAttachmentsForRenderMask =
framebuffer11->getLastColorAttachmentsForRenderMask();
ASSERT(blendStateArray.size() == colorAttachmentsForRenderMask.size());
ASSERT(blendStateExt.mMaxDrawBuffers <= colorAttachmentsForRenderMask.size());
ASSERT(colorbuffers.size() == colorAttachmentsForRenderMask.count());
size_t keyBlendIndex = 0;
// With blending disabled, factors and equations are ignored when building
// D3D11_RENDER_TARGET_BLEND_DESC, so we can reduce the amount of unique keys by
// enforcing default values.
for (size_t sourceIndex : colorAttachmentsForRenderMask)
{
const gl::BlendState &blendState = blendStateArray[sourceIndex];
gl::BlendState &keyBlendState = key.blendStateArray[keyBlendIndex];
// With blending disabled, factors and equations are ignored when building
// D3D11_RENDER_TARGET_BLEND_DESC, so we can reduce the amount of unique keys by
// enforcing default values.
keyBlendState = gl::BlendState();
ASSERT(keyBlendIndex < colorbuffers.size());
const gl::FramebufferAttachment *attachment = colorbuffers[keyBlendIndex];
......@@ -81,44 +78,26 @@ d3d11::BlendStateKey RenderStateCache::GetBlendStateKey(const gl::Context *conte
continue;
}
// These values are used only for caching (hash calculation) purposes.
// Actual write color mask value is derived below.
keyBlendState.colorMaskRed = blendState.colorMaskRed;
keyBlendState.colorMaskGreen = blendState.colorMaskGreen;
keyBlendState.colorMaskBlue = blendState.colorMaskBlue;
keyBlendState.colorMaskAlpha = blendState.colorMaskAlpha;
const uint8_t colorMask = blendStateExt.getColorMaskIndexed(sourceIndex);
const gl::InternalFormat &internalFormat = *attachment->getFormat().info;
key.blendStateExt.setColorMaskIndexed(keyBlendIndex,
gl_d3d11::GetColorMask(internalFormat) & colorMask);
key.rtvMax = static_cast<uint16_t>(keyBlendIndex) + 1;
key.rtvMasks[keyBlendIndex] =
gl_d3d11::GetColorMask(internalFormat) &
gl_d3d11::ConvertColorMask(blendState.colorMaskRed, blendState.colorMaskGreen,
blendState.colorMaskBlue, blendState.colorMaskAlpha);
// Some D3D11 drivers produce unexpected results when blending is enabled for integer
// attachments. Per OpenGL ES spec, it must be ignored anyway. When blending is disabled,
// the state remains default to reduce the number of unique keys.
if (blendState.blend && !internalFormat.isInt())
if (blendStateExt.mEnabledMask.test(sourceIndex) && !internalFormat.isInt())
{
keyBlendState.blend = true;
keyBlendState.sourceBlendRGB = blendState.sourceBlendRGB;
keyBlendState.sourceBlendAlpha = blendState.sourceBlendAlpha;
keyBlendState.destBlendRGB = blendState.destBlendRGB;
keyBlendState.destBlendAlpha = blendState.destBlendAlpha;
keyBlendState.blendEquationRGB = blendState.blendEquationRGB;
keyBlendState.blendEquationAlpha = blendState.blendEquationAlpha;
key.blendStateExt.setEnabledIndexed(keyBlendIndex, true);
key.blendStateExt.setEquationsIndexed(keyBlendIndex, sourceIndex, blendStateExt);
key.blendStateExt.setFactorsIndexed(keyBlendIndex, sourceIndex, blendStateExt);
}
keyBlendIndex++;
}
// Initialize remaining slots in key.blendStateArray
if (keyBlendIndex < key.blendStateArray.size())
{
std::fill(key.blendStateArray.begin() + keyBlendIndex, key.blendStateArray.end(),
gl::BlendState());
}
key.sampleAlphaToCoverage = sampleAlphaToCoverage ? 1 : 0;
return key;
}
......@@ -138,8 +117,8 @@ angle::Result RenderStateCache::getBlendState(const gl::Context *context,
TrimCache(kMaxStates, kGCLimit, "blend state", &mBlendStateCache);
// Create a new blend state and insert it into the cache
D3D11_BLEND_DESC blendDesc;
const gl::BlendStateArray &blendStateArray = key.blendStateArray;
D3D11_BLEND_DESC blendDesc = {}; // avoid undefined fields
const gl::BlendStateExt &blendStateExt = key.blendStateExt;
blendDesc.AlphaToCoverageEnable = key.sampleAlphaToCoverage != 0 ? TRUE : FALSE;
blendDesc.IndependentBlendEnable = key.rtvMax > 1 ? TRUE : FALSE;
......@@ -148,26 +127,29 @@ angle::Result RenderStateCache::getBlendState(const gl::Context *context,
// feature level. Given that we do not expose GL entrypoints that set per-buffer blend states on
// systems lower than FL10_1, this array will be always valid.
ASSERT(blendStateArray.size() >= D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT);
for (size_t i = 0; i < D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; i++)
for (size_t i = 0; i < blendStateExt.mMaxDrawBuffers; i++)
{
D3D11_RENDER_TARGET_BLEND_DESC &rtDesc = blendDesc.RenderTarget[i];
rtDesc = {}; // otherwise its content may be undefined
const gl::BlendState &blendState = blendStateArray[i];
if (blendState.blend)
if (blendStateExt.mEnabledMask.test(i))
{
rtDesc.BlendEnable = true;
rtDesc.SrcBlend = gl_d3d11::ConvertBlendFunc(blendState.sourceBlendRGB, false);
rtDesc.DestBlend = gl_d3d11::ConvertBlendFunc(blendState.destBlendRGB, false);
rtDesc.BlendOp = gl_d3d11::ConvertBlendOp(blendState.blendEquationRGB);
rtDesc.SrcBlendAlpha = gl_d3d11::ConvertBlendFunc(blendState.sourceBlendAlpha, true);
rtDesc.DestBlendAlpha = gl_d3d11::ConvertBlendFunc(blendState.destBlendAlpha, true);
rtDesc.BlendOpAlpha = gl_d3d11::ConvertBlendOp(blendState.blendEquationAlpha);
rtDesc.BlendEnable = true;
rtDesc.SrcBlend =
gl_d3d11::ConvertBlendFunc(blendStateExt.getSrcColorIndexed(i), false);
rtDesc.DestBlend =
gl_d3d11::ConvertBlendFunc(blendStateExt.getDstColorIndexed(i), false);
rtDesc.BlendOp = gl_d3d11::ConvertBlendOp(blendStateExt.getEquationColorIndexed(i));
rtDesc.SrcBlendAlpha =
gl_d3d11::ConvertBlendFunc(blendStateExt.getSrcAlphaIndexed(i), true);
rtDesc.DestBlendAlpha =
gl_d3d11::ConvertBlendFunc(blendStateExt.getDstAlphaIndexed(i), true);
rtDesc.BlendOpAlpha =
gl_d3d11::ConvertBlendOp(blendStateExt.getEquationAlphaIndexed(i));
}
rtDesc.RenderTargetWriteMask = key.rtvMasks[i];
// blendStateExt.colorMask follows the same packing scheme as
// D3D11_RENDER_TARGET_BLEND_DESC.RenderTargetWriteMask
rtDesc.RenderTargetWriteMask = blendStateExt.getColorMaskIndexed(i);
}
d3d11::BlendState d3dBlendState;
......
......@@ -69,7 +69,7 @@ class RenderStateCache : angle::NonCopyable
static d3d11::BlendStateKey GetBlendStateKey(const gl::Context *context,
Framebuffer11 *framebuffer11,
const gl::BlendStateArray &blendStateArray,
const gl::BlendStateExt &blendStateExt,
bool sampleAlphaToCoverage);
angle::Result getBlendState(const gl::Context *context,
Renderer11 *renderer,
......
......@@ -668,7 +668,7 @@ StateManager11::StateManager11(Renderer11 *renderer)
: mRenderer(renderer),
mInternalDirtyBits(),
mCurSampleAlphaToCoverage(false),
mCurBlendStateArray(),
mCurBlendStateExt(),
mCurBlendColor(0, 0, 0, 0),
mCurSampleMask(0),
mCurStencilRef(0),
......@@ -951,63 +951,40 @@ void StateManager11::syncState(const gl::Context *context, const gl::State::Dirt
{
case gl::State::DIRTY_BIT_BLEND_EQUATIONS:
{
const gl::BlendStateArray &blendStateArray = state.getBlendStateArray();
const size_t statesCount = mIndependentBlendStates ? blendStateArray.size() : 1;
for (size_t i = 0; i < statesCount; i++)
const gl::BlendStateExt &blendStateExt = state.getBlendStateExt();
ASSERT(mCurBlendStateExt.mMaxDrawBuffers == blendStateExt.mMaxDrawBuffers);
// Compare blend equations only for buffers with blending enabled because
// subsequent sync stages enforce default values for buffers with blending disabled.
if ((blendStateExt.mEnabledMask &
mCurBlendStateExt.compareEquations(blendStateExt.mEquationColor,
blendStateExt.mEquationAlpha))
.any())
{
const gl::BlendState &blendState = blendStateArray[i];
if (!blendState.blend)
{
// Subsequent sync stages enforce default values for buffers with disabled
// blending anyway, no need to touch internal dirty bits.
continue;
}
const gl::BlendState &curBlendState = mCurBlendStateArray[i];
if (blendState.blendEquationRGB != curBlendState.blendEquationRGB ||
blendState.blendEquationAlpha != curBlendState.blendEquationAlpha)
{
mInternalDirtyBits.set(DIRTY_BIT_BLEND_STATE);
break;
}
mInternalDirtyBits.set(DIRTY_BIT_BLEND_STATE);
}
break;
}
case gl::State::DIRTY_BIT_BLEND_FUNCS:
{
const gl::BlendStateArray &blendStateArray = state.getBlendStateArray();
const size_t statesCount = mIndependentBlendStates ? blendStateArray.size() : 1;
for (size_t i = 0; i < statesCount; i++)
const gl::BlendStateExt &blendStateExt = state.getBlendStateExt();
ASSERT(mCurBlendStateExt.mMaxDrawBuffers == blendStateExt.mMaxDrawBuffers);
// Compare blend factors only for buffers with blending enabled because
// subsequent sync stages enforce default values for buffers with blending disabled.
if ((blendStateExt.mEnabledMask &
mCurBlendStateExt.compareFactors(
blendStateExt.mSrcColor, blendStateExt.mDstColor, blendStateExt.mSrcAlpha,
blendStateExt.mDstAlpha))
.any())
{
const gl::BlendState &blendState = blendStateArray[i];
if (!blendState.blend)
{
// Subsequent sync stages enforce default values for buffers with disabled
// blending anyway, no need to touch internal dirty bits.
continue;
}
const gl::BlendState &curBlendState = mCurBlendStateArray[i];
if (blendState.sourceBlendRGB != curBlendState.sourceBlendRGB ||
blendState.destBlendRGB != curBlendState.destBlendRGB ||
blendState.sourceBlendAlpha != curBlendState.sourceBlendAlpha ||
blendState.destBlendAlpha != curBlendState.destBlendAlpha)
{
mInternalDirtyBits.set(DIRTY_BIT_BLEND_STATE);
break;
}
mInternalDirtyBits.set(DIRTY_BIT_BLEND_STATE);
}
break;
}
case gl::State::DIRTY_BIT_BLEND_ENABLED:
{
const gl::BlendStateArray &blendStateArray = state.getBlendStateArray();
const size_t statesCount = mIndependentBlendStates ? blendStateArray.size() : 1;
for (size_t i = 0; i < statesCount; i++)
if (state.getBlendStateExt().mEnabledMask != mCurBlendStateExt.mEnabledMask)
{
if (blendStateArray[i].blend != mCurBlendStateArray[i].blend)
{
mInternalDirtyBits.set(DIRTY_BIT_BLEND_STATE);
break;
}
mInternalDirtyBits.set(DIRTY_BIT_BLEND_STATE);
}
break;
}
......@@ -1025,20 +1002,9 @@ void StateManager11::syncState(const gl::Context *context, const gl::State::Dirt
break;
case gl::State::DIRTY_BIT_COLOR_MASK:
{
const gl::BlendStateArray &blendStateArray = state.getBlendStateArray();
const size_t statesCount = mIndependentBlendStates ? blendStateArray.size() : 1;
for (size_t i = 0; i < statesCount; i++)
if (state.getBlendStateExt().mColorMask != mCurBlendStateExt.mColorMask)
{
const gl::BlendState &blendState = blendStateArray[i];
const gl::BlendState &curBlendState = mCurBlendStateArray[i];
if (blendState.colorMaskRed != curBlendState.colorMaskRed ||
blendState.colorMaskGreen != curBlendState.colorMaskGreen ||
blendState.colorMaskBlue != curBlendState.colorMaskBlue ||
blendState.colorMaskAlpha != curBlendState.colorMaskAlpha)
{
mInternalDirtyBits.set(DIRTY_BIT_BLEND_STATE);
break;
}
mInternalDirtyBits.set(DIRTY_BIT_BLEND_STATE);
}
break;
}
......@@ -1262,7 +1228,7 @@ void StateManager11::handleMultiviewDrawFramebufferChange(const gl::Context *con
}
angle::Result StateManager11::syncBlendState(const gl::Context *context,
const gl::BlendStateArray &blendStateArray,
const gl::BlendStateExt &blendStateExt,
const gl::ColorF &blendColor,
unsigned int sampleMask,
bool sampleAlphaToCoverage,
......@@ -1270,7 +1236,7 @@ angle::Result StateManager11::syncBlendState(const gl::Context *context,
{
const d3d11::BlendState *dxBlendState = nullptr;
const d3d11::BlendStateKey &key = RenderStateCache::GetBlendStateKey(
context, mFramebuffer11, blendStateArray, sampleAlphaToCoverage);
context, mFramebuffer11, blendStateExt, sampleAlphaToCoverage);
ANGLE_TRY(mRenderer->getBlendState(context, key, &dxBlendState));
......@@ -1288,7 +1254,7 @@ angle::Result StateManager11::syncBlendState(const gl::Context *context,
mRenderer->getDeviceContext()->OMSetBlendState(dxBlendState->get(), blendColors, sampleMask);
mCurBlendStateArray = blendStateArray;
mCurBlendStateExt = blendStateExt;
mCurBlendColor = blendColor;
mCurSampleMask = sampleMask;
mCurSampleAlphaToCoverage = sampleAlphaToCoverage;
......@@ -1960,6 +1926,10 @@ angle::Result StateManager11::ensureInitialized(const gl::Context *context)
mIndependentBlendStates = extensions.drawBuffersIndexedAny(); // requires FL10_1
// FL9_3 is limited to 4; ES3.1 context on FL11_0 is limited to 7
mCurBlendStateExt =
gl::BlendStateExt(GetImplAs<Context11>(context)->getNativeCaps().maxDrawBuffers);
ANGLE_TRY(mVertexDataManager.initialize(context));
mCurrentAttributes.reserve(gl::MAX_VERTEX_ATTRIBS);
......@@ -2300,7 +2270,7 @@ angle::Result StateManager11::updateState(const gl::Context *context,
break;
case DIRTY_BIT_BLEND_STATE:
ANGLE_TRY(syncBlendState(
context, glState.getBlendStateArray(), glState.getBlendColor(), sampleMask,
context, glState.getBlendStateExt(), glState.getBlendColor(), sampleMask,
glState.isSampleAlphaToCoverageEnabled(), glState.hasConstantAlphaBlendFunc()));
break;
case DIRTY_BIT_DEPTH_STENCIL_STATE:
......
......@@ -313,7 +313,7 @@ class StateManager11 final : angle::NonCopyable
ID3D11Resource *resource);
angle::Result syncBlendState(const gl::Context *context,
const gl::BlendStateArray &blendStateArray,
const gl::BlendStateExt &blendStateExt,
const gl::ColorF &blendColor,
unsigned int sampleMask,
bool sampleAlphaToCoverage,
......@@ -466,7 +466,7 @@ class StateManager11 final : angle::NonCopyable
bool mCurSampleAlphaToCoverage;
// Blend State
gl::BlendStateArray mCurBlendStateArray;
gl::BlendStateExt mCurBlendStateExt;
gl::ColorF mCurBlendColor;
unsigned int mCurSampleMask;
......
......@@ -2223,6 +2223,7 @@ void SetPositionLayerTexCoord3DVertex(PositionLayerTexCoord3DVertex *vertex,
BlendStateKey::BlendStateKey()
{
memset(this, 0, sizeof(BlendStateKey));
blendStateExt = gl::BlendStateExt();
}
BlendStateKey::BlendStateKey(const BlendStateKey &other)
......
......@@ -148,9 +148,7 @@ struct BlendStateKey final
BlendStateKey();
BlendStateKey(const BlendStateKey &other);
gl::BlendStateArray blendStateArray;
uint8_t rtvMasks[D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT];
gl::BlendStateExt blendStateExt;
// Use two 16-bit ints to round the struct nicely.
uint16_t rtvMax;
......
......@@ -1949,10 +1949,12 @@ void Renderer9::clear(const ClearParameters &clearParams,
? 0.0f
: clearParams.colorF.blue));
if ((formatInfo.redBits > 0 && !clearParams.colorMaskRed[0]) ||
(formatInfo.greenBits > 0 && !clearParams.colorMaskGreen[0]) ||
(formatInfo.blueBits > 0 && !clearParams.colorMaskBlue[0]) ||
(formatInfo.alphaBits > 0 && !clearParams.colorMaskAlpha[0]))
const uint8_t colorMask =
gl::BlendStateExt::ColorMaskStorage::GetValueIndexed(0, clearParams.colorMask);
bool r, g, b, a;
gl::BlendStateExt::UnpackColorMask(colorMask, &r, &g, &b, &a);
if ((formatInfo.redBits > 0 && !r) || (formatInfo.greenBits > 0 && !g) ||
(formatInfo.blueBits > 0 && !b) || (formatInfo.alphaBits > 0 && !a))
{
needMaskedColorClear = true;
}
......@@ -2019,11 +2021,11 @@ void Renderer9::clear(const ClearParameters &clearParams,
if (clearColor)
{
mDevice->SetRenderState(D3DRS_COLORWRITEENABLE,
gl_d3d9::ConvertColorMask(clearParams.colorMaskRed[0],
clearParams.colorMaskGreen[0],
clearParams.colorMaskBlue[0],
clearParams.colorMaskAlpha[0]));
// clearParams.colorMask follows the same packing scheme as
// D3DCOLORWRITEENABLE_RED/GREEN/BLUE/ALPHA
mDevice->SetRenderState(
D3DRS_COLORWRITEENABLE,
gl::BlendStateExt::ColorMaskStorage::GetValueIndexed(0, clearParams.colorMask));
}
else
{
......
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