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, ...@@ -288,6 +288,13 @@ void BlendStateExt::setColorMask(const bool red,
mColorMask = expandColorMaskValue(red, green, blue, alpha); 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, void BlendStateExt::setColorMaskIndexed(const size_t index,
const bool red, const bool red,
const bool green, const bool green,
...@@ -298,6 +305,12 @@ void BlendStateExt::setColorMaskIndexed(const size_t index, ...@@ -298,6 +305,12 @@ void BlendStateExt::setColorMaskIndexed(const size_t index,
ColorMaskStorage::SetValueIndexed(index, PackColorMask(red, green, blue, alpha), &mColorMask); 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, void BlendStateExt::getColorMaskIndexed(const size_t index,
bool *red, bool *red,
bool *green, bool *green,
...@@ -350,6 +363,20 @@ void BlendStateExt::setEquationsIndexed(const size_t index, ...@@ -350,6 +363,20 @@ void BlendStateExt::setEquationsIndexed(const size_t index,
&mEquationAlpha); &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 GLenum BlendStateExt::getEquationColorIndexed(size_t index) const
{ {
ASSERT(index < mMaxDrawBuffers); ASSERT(index < mMaxDrawBuffers);
...@@ -426,6 +453,22 @@ void BlendStateExt::setFactorsIndexed(const size_t index, ...@@ -426,6 +453,22 @@ void BlendStateExt::setFactorsIndexed(const size_t index,
FactorStorage::SetValueIndexed(index, FromGLenum<BlendFactorType>(dstAlpha), &mDstAlpha); 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 GLenum BlendStateExt::getSrcColorIndexed(size_t index) const
{ {
ASSERT(index < mMaxDrawBuffers); ASSERT(index < mMaxDrawBuffers);
......
...@@ -554,11 +554,13 @@ class BlendStateExt final ...@@ -554,11 +554,13 @@ class BlendStateExt final
const bool alpha) const; const bool alpha) const;
ColorMaskStorage::Type expandColorMaskIndexed(const size_t index) const; ColorMaskStorage::Type expandColorMaskIndexed(const size_t index) const;
void setColorMask(const bool red, const bool green, const bool blue, const bool alpha); 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, void setColorMaskIndexed(const size_t index,
const bool red, const bool red,
const bool green, const bool green,
const bool blue, const bool blue,
const bool alpha); const bool alpha);
uint8_t getColorMaskIndexed(const size_t index) const;
void getColorMaskIndexed(const size_t index, void getColorMaskIndexed(const size_t index,
bool *red, bool *red,
bool *green, bool *green,
...@@ -573,6 +575,9 @@ class BlendStateExt final ...@@ -573,6 +575,9 @@ class BlendStateExt final
EquationStorage::Type expandEquationAlphaIndexed(const size_t index) const; EquationStorage::Type expandEquationAlphaIndexed(const size_t index) const;
void setEquations(const GLenum modeColor, const GLenum modeAlpha); 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 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 getEquationColorIndexed(size_t index) const;
GLenum getEquationAlphaIndexed(size_t index) const; GLenum getEquationAlphaIndexed(size_t index) const;
DrawBufferMask compareEquations(const EquationStorage::Type color, DrawBufferMask compareEquations(const EquationStorage::Type color,
...@@ -594,6 +599,7 @@ class BlendStateExt final ...@@ -594,6 +599,7 @@ class BlendStateExt final
const GLenum dstColor, const GLenum dstColor,
const GLenum srcAlpha, const GLenum srcAlpha,
const GLenum dstAlpha); const GLenum dstAlpha);
void setFactorsIndexed(const size_t index, const size_t otherIndex, const BlendStateExt &other);
GLenum getSrcColorIndexed(size_t index) const; GLenum getSrcColorIndexed(size_t index) const;
GLenum getDstColorIndexed(size_t index) const; GLenum getDstColorIndexed(size_t index) const;
GLenum getSrcAlphaIndexed(size_t index) const; GLenum getSrcAlphaIndexed(size_t index) const;
......
...@@ -99,6 +99,12 @@ TEST(BlendStateExt, ColorMask) ...@@ -99,6 +99,12 @@ TEST(BlendStateExt, ColorMask)
blendStateExt.setColorMaskIndexed(3, false, true, false, true); blendStateExt.setColorMaskIndexed(3, false, true, false, true);
ASSERT_EQ(blendStateExt.mColorMask, is64Bit ? 0x050A050505u : 0x5A555u); 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; bool r, g, b, a;
blendStateExt.getColorMaskIndexed(3, &r, &g, &b, &a); blendStateExt.getColorMaskIndexed(3, &r, &g, &b, &a);
ASSERT_FALSE(r); ASSERT_FALSE(r);
...@@ -141,6 +147,16 @@ TEST(BlendStateExt, BlendEquations) ...@@ -141,6 +147,16 @@ TEST(BlendStateExt, BlendEquations)
const gl::DrawBufferMask diff = const gl::DrawBufferMask diff =
blendStateExt.compareEquations(otherEquationColor, otherEquationAlpha); blendStateExt.compareEquations(otherEquationColor, otherEquationAlpha);
ASSERT_EQ(diff.to_ulong(), 40u); 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 // Test blend factors manipulations
...@@ -181,6 +197,34 @@ TEST(BlendStateExt, BlendFactors) ...@@ -181,6 +197,34 @@ TEST(BlendStateExt, BlendFactors)
const gl::DrawBufferMask diff = const gl::DrawBufferMask diff =
blendStateExt.compareFactors(otherSrcColor, otherDstColor, otherSrcAlpha, otherDstAlpha); blendStateExt.compareFactors(otherSrcColor, otherDstColor, otherSrcAlpha, otherDstAlpha);
ASSERT_EQ(diff.to_ulong(), 169u); 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 } // namespace angle
...@@ -34,8 +34,6 @@ ClearParameters GetClearParameters(const gl::State &state, GLbitfield mask) ...@@ -34,8 +34,6 @@ ClearParameters GetClearParameters(const gl::State &state, GLbitfield mask)
ClearParameters clearParams; ClearParameters clearParams;
memset(&clearParams, 0, sizeof(ClearParameters)); memset(&clearParams, 0, sizeof(ClearParameters));
const auto &blendStateArray = state.getBlendStateArray();
clearParams.colorF = state.getColorClearValue(); clearParams.colorF = state.getColorClearValue();
clearParams.colorType = GL_FLOAT; clearParams.colorType = GL_FLOAT;
clearParams.clearDepth = false; clearParams.clearDepth = false;
...@@ -49,15 +47,15 @@ ClearParameters GetClearParameters(const gl::State &state, GLbitfield mask) ...@@ -49,15 +47,15 @@ ClearParameters GetClearParameters(const gl::State &state, GLbitfield mask)
const gl::Framebuffer *framebufferObject = state.getDrawFramebuffer(); const gl::Framebuffer *framebufferObject = state.getDrawFramebuffer();
const bool clearColor = const bool clearColor =
(mask & GL_COLOR_BUFFER_BIT) && framebufferObject->hasEnabledDrawBuffer(); (mask & GL_COLOR_BUFFER_BIT) && framebufferObject->hasEnabledDrawBuffer();
ASSERT(blendStateArray.size() == gl::IMPLEMENTATION_MAX_DRAW_BUFFERS); if (clearColor)
for (size_t i = 0; i < blendStateArray.size(); i++) {
clearParams.clearColor.set();
}
else
{ {
clearParams.clearColor[i] = clearColor; clearParams.clearColor.reset();
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.colorMask = state.getBlendStateExt().mColorMask;
if (mask & GL_DEPTH_BUFFER_BIT) if (mask & GL_DEPTH_BUFFER_BIT)
{ {
......
...@@ -40,10 +40,7 @@ struct ClearParameters ...@@ -40,10 +40,7 @@ struct ClearParameters
gl::ColorI colorI; gl::ColorI colorI;
gl::ColorUI colorUI; gl::ColorUI colorUI;
GLenum colorType; GLenum colorType;
gl::DrawBufferMask colorMaskRed; gl::BlendStateExt::ColorMaskStorage::Type colorMask;
gl::DrawBufferMask colorMaskGreen;
gl::DrawBufferMask colorMaskBlue;
gl::DrawBufferMask colorMaskAlpha;
bool clearDepth; bool clearDepth;
float depthValue; float depthValue;
......
...@@ -287,16 +287,7 @@ angle::Result Clear11::ensureResourcesInitialized(const gl::Context *context) ...@@ -287,16 +287,7 @@ angle::Result Clear11::ensureResourcesInitialized(const gl::Context *context)
mDepthStencilStateKey.stencilBackFunc = GL_ALWAYS; mDepthStencilStateKey.stencilBackFunc = GL_ALWAYS;
// Initialize BlendStateKey with defaults // Initialize BlendStateKey with defaults
for (gl::BlendState &blendState : mBlendStateKey.blendStateArray) mBlendStateKey.blendStateExt = gl::BlendStateExt(mRenderer->getNativeCaps().maxDrawBuffers);
{
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;
}
mResourcesInitialized = true; mResourcesInitialized = true;
return angle::Result::Continue; return angle::Result::Continue;
...@@ -468,11 +459,8 @@ angle::Result Clear11::clearFramebuffer(const gl::Context *context, ...@@ -468,11 +459,8 @@ angle::Result Clear11::clearFramebuffer(const gl::Context *context,
const auto &colorAttachments = fboData.getColorAttachments(); const auto &colorAttachments = fboData.getColorAttachments();
for (auto colorAttachmentIndex : fboData.getEnabledDrawBuffers()) for (auto colorAttachmentIndex : fboData.getEnabledDrawBuffers())
{ {
const uint8_t colorMask = const uint8_t colorMask = gl::BlendStateExt::ColorMaskStorage::GetValueIndexed(
gl_d3d11::ConvertColorMask(clearParams.colorMaskRed[colorAttachmentIndex], colorAttachmentIndex, clearParams.colorMask);
clearParams.colorMaskGreen[colorAttachmentIndex],
clearParams.colorMaskBlue[colorAttachmentIndex],
clearParams.colorMaskAlpha[colorAttachmentIndex]);
commonColorMask |= colorMask; commonColorMask |= colorMask;
...@@ -501,10 +489,10 @@ angle::Result Clear11::clearFramebuffer(const gl::Context *context, ...@@ -501,10 +489,10 @@ angle::Result Clear11::clearFramebuffer(const gl::Context *context,
<< ")."; << ").";
} }
if ((formatInfo.redBits == 0 || !clearParams.colorMaskRed[colorAttachmentIndex]) && bool r, g, b, a;
(formatInfo.greenBits == 0 || !clearParams.colorMaskGreen[colorAttachmentIndex]) && gl::BlendStateExt::UnpackColorMask(colorMask, &r, &g, &b, &a);
(formatInfo.blueBits == 0 || !clearParams.colorMaskBlue[colorAttachmentIndex]) && if ((formatInfo.redBits == 0 || !r) && (formatInfo.greenBits == 0 || !g) &&
(formatInfo.alphaBits == 0 || !clearParams.colorMaskAlpha[colorAttachmentIndex])) (formatInfo.blueBits == 0 || !b) && (formatInfo.alphaBits == 0 || !a))
{ {
// Every channel either does not exist in the render target or is masked out // Every channel either does not exist in the render target or is masked out
continue; continue;
...@@ -514,11 +502,9 @@ angle::Result Clear11::clearFramebuffer(const gl::Context *context, ...@@ -514,11 +502,9 @@ angle::Result Clear11::clearFramebuffer(const gl::Context *context,
ASSERT(framebufferRTV.valid()); ASSERT(framebufferRTV.valid());
if ((!(mRenderer->getRenderer11DeviceCaps().supportsClearView) && needScissoredClear) || if ((!(mRenderer->getRenderer11DeviceCaps().supportsClearView) && needScissoredClear) ||
clearParams.colorType != GL_FLOAT || clearParams.colorType != GL_FLOAT || (formatInfo.redBits > 0 && !r) ||
(formatInfo.redBits > 0 && !clearParams.colorMaskRed[colorAttachmentIndex]) || (formatInfo.greenBits > 0 && !g) || (formatInfo.blueBits > 0 && !b) ||
(formatInfo.greenBits > 0 && !clearParams.colorMaskGreen[colorAttachmentIndex]) || (formatInfo.alphaBits > 0 && !a))
(formatInfo.blueBits > 0 && !clearParams.colorMaskBlue[colorAttachmentIndex]) ||
(formatInfo.alphaBits > 0 && !clearParams.colorMaskAlpha[colorAttachmentIndex]))
{ {
rtvs[numRtvs] = framebufferRTV.get(); rtvs[numRtvs] = framebufferRTV.get();
rtvMasks[numRtvs] = gl_d3d11::GetColorMask(formatInfo) & colorMask; rtvMasks[numRtvs] = gl_d3d11::GetColorMask(formatInfo) & colorMask;
...@@ -650,17 +636,13 @@ angle::Result Clear11::clearFramebuffer(const gl::Context *context, ...@@ -650,17 +636,13 @@ angle::Result Clear11::clearFramebuffer(const gl::Context *context,
ASSERT(numRtvs <= static_cast<uint32_t>(mRenderer->getNativeCaps().maxDrawBuffers)); ASSERT(numRtvs <= static_cast<uint32_t>(mRenderer->getNativeCaps().maxDrawBuffers));
// Setup BlendStateKey parameters // 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]; mBlendStateKey.blendStateExt.setColorMaskIndexed(i, rtvMasks[i]);
blendState.colorMaskRed = clearParams.colorMaskRed[i];
blendState.colorMaskGreen = clearParams.colorMaskGreen[i];
blendState.colorMaskBlue = clearParams.colorMaskBlue[i];
blendState.colorMaskAlpha = clearParams.colorMaskAlpha[i];
} }
mBlendStateKey.rtvMax = static_cast<uint16_t>(numRtvs); mBlendStateKey.rtvMax = static_cast<uint16_t>(numRtvs);
memcpy(mBlendStateKey.rtvMasks, &rtvMasks[0], sizeof(mBlendStateKey.rtvMasks));
// Get BlendState // Get BlendState
const d3d11::BlendState *blendState = nullptr; const d3d11::BlendState *blendState = nullptr;
......
...@@ -45,31 +45,28 @@ void RenderStateCache::clear() ...@@ -45,31 +45,28 @@ void RenderStateCache::clear()
// static // static
d3d11::BlendStateKey RenderStateCache::GetBlendStateKey(const gl::Context *context, d3d11::BlendStateKey RenderStateCache::GetBlendStateKey(const gl::Context *context,
Framebuffer11 *framebuffer11, Framebuffer11 *framebuffer11,
const gl::BlendStateArray &blendStateArray, const gl::BlendStateExt &blendStateExt,
bool sampleAlphaToCoverage) bool sampleAlphaToCoverage)
{ {
d3d11::BlendStateKey key; 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 // work correctly. Due to mrt_perf_workaround, the actual indices of active draw buffers may be
// different, so both arrays should be tracked. // different, so both arrays should be tracked.
key.blendStateExt = gl::BlendStateExt(blendStateExt.mMaxDrawBuffers);
const gl::AttachmentList &colorbuffers = framebuffer11->getColorAttachmentsForRender(context); const gl::AttachmentList &colorbuffers = framebuffer11->getColorAttachmentsForRender(context);
const gl::DrawBufferMask colorAttachmentsForRenderMask = const gl::DrawBufferMask colorAttachmentsForRenderMask =
framebuffer11->getLastColorAttachmentsForRenderMask(); framebuffer11->getLastColorAttachmentsForRenderMask();
ASSERT(blendStateArray.size() == colorAttachmentsForRenderMask.size()); ASSERT(blendStateExt.mMaxDrawBuffers <= colorAttachmentsForRenderMask.size());
ASSERT(colorbuffers.size() == colorAttachmentsForRenderMask.count()); ASSERT(colorbuffers.size() == colorAttachmentsForRenderMask.count());
size_t keyBlendIndex = 0; 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) 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()); ASSERT(keyBlendIndex < colorbuffers.size());
const gl::FramebufferAttachment *attachment = colorbuffers[keyBlendIndex]; const gl::FramebufferAttachment *attachment = colorbuffers[keyBlendIndex];
...@@ -81,44 +78,26 @@ d3d11::BlendStateKey RenderStateCache::GetBlendStateKey(const gl::Context *conte ...@@ -81,44 +78,26 @@ d3d11::BlendStateKey RenderStateCache::GetBlendStateKey(const gl::Context *conte
continue; continue;
} }
// These values are used only for caching (hash calculation) purposes. const uint8_t colorMask = blendStateExt.getColorMaskIndexed(sourceIndex);
// 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 gl::InternalFormat &internalFormat = *attachment->getFormat().info; 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.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 // 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, // 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. // 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; key.blendStateExt.setEnabledIndexed(keyBlendIndex, true);
keyBlendState.sourceBlendRGB = blendState.sourceBlendRGB; key.blendStateExt.setEquationsIndexed(keyBlendIndex, sourceIndex, blendStateExt);
keyBlendState.sourceBlendAlpha = blendState.sourceBlendAlpha; key.blendStateExt.setFactorsIndexed(keyBlendIndex, sourceIndex, blendStateExt);
keyBlendState.destBlendRGB = blendState.destBlendRGB;
keyBlendState.destBlendAlpha = blendState.destBlendAlpha;
keyBlendState.blendEquationRGB = blendState.blendEquationRGB;
keyBlendState.blendEquationAlpha = blendState.blendEquationAlpha;
} }
keyBlendIndex++; 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; key.sampleAlphaToCoverage = sampleAlphaToCoverage ? 1 : 0;
return key; return key;
} }
...@@ -138,8 +117,8 @@ angle::Result RenderStateCache::getBlendState(const gl::Context *context, ...@@ -138,8 +117,8 @@ angle::Result RenderStateCache::getBlendState(const gl::Context *context,
TrimCache(kMaxStates, kGCLimit, "blend state", &mBlendStateCache); TrimCache(kMaxStates, kGCLimit, "blend state", &mBlendStateCache);
// 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; D3D11_BLEND_DESC blendDesc = {}; // avoid undefined fields
const gl::BlendStateArray &blendStateArray = key.blendStateArray; const gl::BlendStateExt &blendStateExt = key.blendStateExt;
blendDesc.AlphaToCoverageEnable = key.sampleAlphaToCoverage != 0 ? TRUE : FALSE; blendDesc.AlphaToCoverageEnable = key.sampleAlphaToCoverage != 0 ? TRUE : FALSE;
blendDesc.IndependentBlendEnable = key.rtvMax > 1 ? TRUE : FALSE; blendDesc.IndependentBlendEnable = key.rtvMax > 1 ? TRUE : FALSE;
...@@ -148,26 +127,29 @@ angle::Result RenderStateCache::getBlendState(const gl::Context *context, ...@@ -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 // 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. // 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 < blendStateExt.mMaxDrawBuffers; i++)
for (size_t i = 0; i < D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; i++)
{ {
D3D11_RENDER_TARGET_BLEND_DESC &rtDesc = blendDesc.RenderTarget[i]; D3D11_RENDER_TARGET_BLEND_DESC &rtDesc = blendDesc.RenderTarget[i];
rtDesc = {}; // otherwise its content may be undefined if (blendStateExt.mEnabledMask.test(i))
const gl::BlendState &blendState = blendStateArray[i];
if (blendState.blend)
{ {
rtDesc.BlendEnable = true; rtDesc.BlendEnable = true;
rtDesc.SrcBlend = gl_d3d11::ConvertBlendFunc(blendState.sourceBlendRGB, false); rtDesc.SrcBlend =
rtDesc.DestBlend = gl_d3d11::ConvertBlendFunc(blendState.destBlendRGB, false); gl_d3d11::ConvertBlendFunc(blendStateExt.getSrcColorIndexed(i), false);
rtDesc.BlendOp = gl_d3d11::ConvertBlendOp(blendState.blendEquationRGB); rtDesc.DestBlend =
rtDesc.SrcBlendAlpha = gl_d3d11::ConvertBlendFunc(blendState.sourceBlendAlpha, true); gl_d3d11::ConvertBlendFunc(blendStateExt.getDstColorIndexed(i), false);
rtDesc.DestBlendAlpha = gl_d3d11::ConvertBlendFunc(blendState.destBlendAlpha, true); rtDesc.BlendOp = gl_d3d11::ConvertBlendOp(blendStateExt.getEquationColorIndexed(i));
rtDesc.BlendOpAlpha = gl_d3d11::ConvertBlendOp(blendState.blendEquationAlpha); 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; d3d11::BlendState d3dBlendState;
......
...@@ -69,7 +69,7 @@ class RenderStateCache : angle::NonCopyable ...@@ -69,7 +69,7 @@ class RenderStateCache : angle::NonCopyable
static d3d11::BlendStateKey GetBlendStateKey(const gl::Context *context, static d3d11::BlendStateKey GetBlendStateKey(const gl::Context *context,
Framebuffer11 *framebuffer11, Framebuffer11 *framebuffer11,
const gl::BlendStateArray &blendStateArray, const gl::BlendStateExt &blendStateExt,
bool sampleAlphaToCoverage); bool sampleAlphaToCoverage);
angle::Result getBlendState(const gl::Context *context, angle::Result getBlendState(const gl::Context *context,
Renderer11 *renderer, Renderer11 *renderer,
......
...@@ -668,7 +668,7 @@ StateManager11::StateManager11(Renderer11 *renderer) ...@@ -668,7 +668,7 @@ StateManager11::StateManager11(Renderer11 *renderer)
: mRenderer(renderer), : mRenderer(renderer),
mInternalDirtyBits(), mInternalDirtyBits(),
mCurSampleAlphaToCoverage(false), mCurSampleAlphaToCoverage(false),
mCurBlendStateArray(), mCurBlendStateExt(),
mCurBlendColor(0, 0, 0, 0), mCurBlendColor(0, 0, 0, 0),
mCurSampleMask(0), mCurSampleMask(0),
mCurStencilRef(0), mCurStencilRef(0),
...@@ -951,63 +951,40 @@ void StateManager11::syncState(const gl::Context *context, const gl::State::Dirt ...@@ -951,63 +951,40 @@ void StateManager11::syncState(const gl::Context *context, const gl::State::Dirt
{ {
case gl::State::DIRTY_BIT_BLEND_EQUATIONS: case gl::State::DIRTY_BIT_BLEND_EQUATIONS:
{ {
const gl::BlendStateArray &blendStateArray = state.getBlendStateArray(); const gl::BlendStateExt &blendStateExt = state.getBlendStateExt();
const size_t statesCount = mIndependentBlendStates ? blendStateArray.size() : 1; ASSERT(mCurBlendStateExt.mMaxDrawBuffers == blendStateExt.mMaxDrawBuffers);
for (size_t i = 0; i < statesCount; i++) // 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]; mInternalDirtyBits.set(DIRTY_BIT_BLEND_STATE);
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;
}
} }
break; break;
} }
case gl::State::DIRTY_BIT_BLEND_FUNCS: case gl::State::DIRTY_BIT_BLEND_FUNCS:
{ {
const gl::BlendStateArray &blendStateArray = state.getBlendStateArray(); const gl::BlendStateExt &blendStateExt = state.getBlendStateExt();
const size_t statesCount = mIndependentBlendStates ? blendStateArray.size() : 1; ASSERT(mCurBlendStateExt.mMaxDrawBuffers == blendStateExt.mMaxDrawBuffers);
for (size_t i = 0; i < statesCount; i++) // 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]; mInternalDirtyBits.set(DIRTY_BIT_BLEND_STATE);
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;
}
} }
break; break;
} }
case gl::State::DIRTY_BIT_BLEND_ENABLED: case gl::State::DIRTY_BIT_BLEND_ENABLED:
{ {
const gl::BlendStateArray &blendStateArray = state.getBlendStateArray(); if (state.getBlendStateExt().mEnabledMask != mCurBlendStateExt.mEnabledMask)
const size_t statesCount = mIndependentBlendStates ? blendStateArray.size() : 1;
for (size_t i = 0; i < statesCount; i++)
{ {
if (blendStateArray[i].blend != mCurBlendStateArray[i].blend) mInternalDirtyBits.set(DIRTY_BIT_BLEND_STATE);
{
mInternalDirtyBits.set(DIRTY_BIT_BLEND_STATE);
break;
}
} }
break; break;
} }
...@@ -1025,20 +1002,9 @@ void StateManager11::syncState(const gl::Context *context, const gl::State::Dirt ...@@ -1025,20 +1002,9 @@ void StateManager11::syncState(const gl::Context *context, const gl::State::Dirt
break; break;
case gl::State::DIRTY_BIT_COLOR_MASK: case gl::State::DIRTY_BIT_COLOR_MASK:
{ {
const gl::BlendStateArray &blendStateArray = state.getBlendStateArray(); if (state.getBlendStateExt().mColorMask != mCurBlendStateExt.mColorMask)
const size_t statesCount = mIndependentBlendStates ? blendStateArray.size() : 1;
for (size_t i = 0; i < statesCount; i++)
{ {
const gl::BlendState &blendState = blendStateArray[i]; mInternalDirtyBits.set(DIRTY_BIT_BLEND_STATE);
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;
}
} }
break; break;
} }
...@@ -1262,7 +1228,7 @@ void StateManager11::handleMultiviewDrawFramebufferChange(const gl::Context *con ...@@ -1262,7 +1228,7 @@ void StateManager11::handleMultiviewDrawFramebufferChange(const gl::Context *con
} }
angle::Result StateManager11::syncBlendState(const gl::Context *context, angle::Result StateManager11::syncBlendState(const gl::Context *context,
const gl::BlendStateArray &blendStateArray, const gl::BlendStateExt &blendStateExt,
const gl::ColorF &blendColor, const gl::ColorF &blendColor,
unsigned int sampleMask, unsigned int sampleMask,
bool sampleAlphaToCoverage, bool sampleAlphaToCoverage,
...@@ -1270,7 +1236,7 @@ angle::Result StateManager11::syncBlendState(const gl::Context *context, ...@@ -1270,7 +1236,7 @@ angle::Result StateManager11::syncBlendState(const gl::Context *context,
{ {
const d3d11::BlendState *dxBlendState = nullptr; const d3d11::BlendState *dxBlendState = nullptr;
const d3d11::BlendStateKey &key = RenderStateCache::GetBlendStateKey( const d3d11::BlendStateKey &key = RenderStateCache::GetBlendStateKey(
context, mFramebuffer11, blendStateArray, sampleAlphaToCoverage); context, mFramebuffer11, blendStateExt, sampleAlphaToCoverage);
ANGLE_TRY(mRenderer->getBlendState(context, key, &dxBlendState)); ANGLE_TRY(mRenderer->getBlendState(context, key, &dxBlendState));
...@@ -1288,7 +1254,7 @@ angle::Result StateManager11::syncBlendState(const gl::Context *context, ...@@ -1288,7 +1254,7 @@ angle::Result StateManager11::syncBlendState(const gl::Context *context,
mRenderer->getDeviceContext()->OMSetBlendState(dxBlendState->get(), blendColors, sampleMask); mRenderer->getDeviceContext()->OMSetBlendState(dxBlendState->get(), blendColors, sampleMask);
mCurBlendStateArray = blendStateArray; mCurBlendStateExt = blendStateExt;
mCurBlendColor = blendColor; mCurBlendColor = blendColor;
mCurSampleMask = sampleMask; mCurSampleMask = sampleMask;
mCurSampleAlphaToCoverage = sampleAlphaToCoverage; mCurSampleAlphaToCoverage = sampleAlphaToCoverage;
...@@ -1960,6 +1926,10 @@ angle::Result StateManager11::ensureInitialized(const gl::Context *context) ...@@ -1960,6 +1926,10 @@ angle::Result StateManager11::ensureInitialized(const gl::Context *context)
mIndependentBlendStates = extensions.drawBuffersIndexedAny(); // requires FL10_1 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)); ANGLE_TRY(mVertexDataManager.initialize(context));
mCurrentAttributes.reserve(gl::MAX_VERTEX_ATTRIBS); mCurrentAttributes.reserve(gl::MAX_VERTEX_ATTRIBS);
...@@ -2300,7 +2270,7 @@ angle::Result StateManager11::updateState(const gl::Context *context, ...@@ -2300,7 +2270,7 @@ angle::Result StateManager11::updateState(const gl::Context *context,
break; break;
case DIRTY_BIT_BLEND_STATE: case DIRTY_BIT_BLEND_STATE:
ANGLE_TRY(syncBlendState( ANGLE_TRY(syncBlendState(
context, glState.getBlendStateArray(), glState.getBlendColor(), sampleMask, context, glState.getBlendStateExt(), glState.getBlendColor(), sampleMask,
glState.isSampleAlphaToCoverageEnabled(), glState.hasConstantAlphaBlendFunc())); glState.isSampleAlphaToCoverageEnabled(), glState.hasConstantAlphaBlendFunc()));
break; break;
case DIRTY_BIT_DEPTH_STENCIL_STATE: case DIRTY_BIT_DEPTH_STENCIL_STATE:
......
...@@ -313,7 +313,7 @@ class StateManager11 final : angle::NonCopyable ...@@ -313,7 +313,7 @@ class StateManager11 final : angle::NonCopyable
ID3D11Resource *resource); ID3D11Resource *resource);
angle::Result syncBlendState(const gl::Context *context, angle::Result syncBlendState(const gl::Context *context,
const gl::BlendStateArray &blendStateArray, const gl::BlendStateExt &blendStateExt,
const gl::ColorF &blendColor, const gl::ColorF &blendColor,
unsigned int sampleMask, unsigned int sampleMask,
bool sampleAlphaToCoverage, bool sampleAlphaToCoverage,
...@@ -466,7 +466,7 @@ class StateManager11 final : angle::NonCopyable ...@@ -466,7 +466,7 @@ class StateManager11 final : angle::NonCopyable
bool mCurSampleAlphaToCoverage; bool mCurSampleAlphaToCoverage;
// Blend State // Blend State
gl::BlendStateArray mCurBlendStateArray; gl::BlendStateExt mCurBlendStateExt;
gl::ColorF mCurBlendColor; gl::ColorF mCurBlendColor;
unsigned int mCurSampleMask; unsigned int mCurSampleMask;
......
...@@ -2223,6 +2223,7 @@ void SetPositionLayerTexCoord3DVertex(PositionLayerTexCoord3DVertex *vertex, ...@@ -2223,6 +2223,7 @@ void SetPositionLayerTexCoord3DVertex(PositionLayerTexCoord3DVertex *vertex,
BlendStateKey::BlendStateKey() BlendStateKey::BlendStateKey()
{ {
memset(this, 0, sizeof(BlendStateKey)); memset(this, 0, sizeof(BlendStateKey));
blendStateExt = gl::BlendStateExt();
} }
BlendStateKey::BlendStateKey(const BlendStateKey &other) BlendStateKey::BlendStateKey(const BlendStateKey &other)
......
...@@ -148,9 +148,7 @@ struct BlendStateKey final ...@@ -148,9 +148,7 @@ struct BlendStateKey final
BlendStateKey(); BlendStateKey();
BlendStateKey(const BlendStateKey &other); BlendStateKey(const BlendStateKey &other);
gl::BlendStateArray blendStateArray; gl::BlendStateExt blendStateExt;
uint8_t rtvMasks[D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT];
// Use two 16-bit ints to round the struct nicely. // Use two 16-bit ints to round the struct nicely.
uint16_t rtvMax; uint16_t rtvMax;
......
...@@ -1949,10 +1949,12 @@ void Renderer9::clear(const ClearParameters &clearParams, ...@@ -1949,10 +1949,12 @@ void Renderer9::clear(const ClearParameters &clearParams,
? 0.0f ? 0.0f
: clearParams.colorF.blue)); : clearParams.colorF.blue));
if ((formatInfo.redBits > 0 && !clearParams.colorMaskRed[0]) || const uint8_t colorMask =
(formatInfo.greenBits > 0 && !clearParams.colorMaskGreen[0]) || gl::BlendStateExt::ColorMaskStorage::GetValueIndexed(0, clearParams.colorMask);
(formatInfo.blueBits > 0 && !clearParams.colorMaskBlue[0]) || bool r, g, b, a;
(formatInfo.alphaBits > 0 && !clearParams.colorMaskAlpha[0])) 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; needMaskedColorClear = true;
} }
...@@ -2019,11 +2021,11 @@ void Renderer9::clear(const ClearParameters &clearParams, ...@@ -2019,11 +2021,11 @@ void Renderer9::clear(const ClearParameters &clearParams,
if (clearColor) if (clearColor)
{ {
mDevice->SetRenderState(D3DRS_COLORWRITEENABLE, // clearParams.colorMask follows the same packing scheme as
gl_d3d9::ConvertColorMask(clearParams.colorMaskRed[0], // D3DCOLORWRITEENABLE_RED/GREEN/BLUE/ALPHA
clearParams.colorMaskGreen[0], mDevice->SetRenderState(
clearParams.colorMaskBlue[0], D3DRS_COLORWRITEENABLE,
clearParams.colorMaskAlpha[0])); gl::BlendStateExt::ColorMaskStorage::GetValueIndexed(0, clearParams.colorMask));
} }
else 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