summaryrefslogtreecommitdiffstats
path: root/gfx/angle/src/libANGLE/renderer/d3d/d3d11/Clear11.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'gfx/angle/src/libANGLE/renderer/d3d/d3d11/Clear11.cpp')
-rwxr-xr-xgfx/angle/src/libANGLE/renderer/d3d/d3d11/Clear11.cpp537
1 files changed, 258 insertions, 279 deletions
diff --git a/gfx/angle/src/libANGLE/renderer/d3d/d3d11/Clear11.cpp b/gfx/angle/src/libANGLE/renderer/d3d/d3d11/Clear11.cpp
index f42a59ced..d2d813895 100755
--- a/gfx/angle/src/libANGLE/renderer/d3d/d3d11/Clear11.cpp
+++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d11/Clear11.cpp
@@ -34,40 +34,29 @@ namespace rx
{
template <typename T>
-static void ApplyVertices(const gl::Extents &framebufferSize,
- const gl::Rectangle *scissor,
- const gl::Color<T> &color,
- float depth,
- void *buffer)
+static void ApplyVertices(const gl::Extents &framebufferSize, const gl::Rectangle *scissor, const gl::Color<T> &color, float depth, void *buffer)
{
- d3d11::PositionDepthColorVertex<T> *vertices =
- reinterpret_cast<d3d11::PositionDepthColorVertex<T> *>(buffer);
+ d3d11::PositionDepthColorVertex<T> *vertices = reinterpret_cast<d3d11::PositionDepthColorVertex<T>*>(buffer);
float depthClear = gl::clamp01(depth);
- float left = -1.0f;
- float right = 1.0f;
- float top = -1.0f;
- float bottom = 1.0f;
+ float left = -1.0f;
+ float right = 1.0f;
+ float top = -1.0f;
+ float bottom = 1.0f;
// Clip the quad coordinates to the scissor if needed
if (scissor != nullptr)
{
- left = std::max(left, (scissor->x / float(framebufferSize.width)) * 2.0f - 1.0f);
- right = std::min(
- right, ((scissor->x + scissor->width) / float(framebufferSize.width)) * 2.0f - 1.0f);
- top = std::max(top, ((framebufferSize.height - scissor->y - scissor->height) /
- float(framebufferSize.height)) *
- 2.0f -
- 1.0f);
- bottom = std::min(
- bottom,
- ((framebufferSize.height - scissor->y) / float(framebufferSize.height)) * 2.0f - 1.0f);
+ left = std::max(left, (scissor->x / float(framebufferSize.width)) * 2.0f - 1.0f);
+ right = std::min(right, ((scissor->x + scissor->width) / float(framebufferSize.width)) * 2.0f - 1.0f);
+ top = std::max(top, ((framebufferSize.height - scissor->y - scissor->height) / float(framebufferSize.height)) * 2.0f - 1.0f);
+ bottom = std::min(bottom, ((framebufferSize.height - scissor->y) / float(framebufferSize.height)) * 2.0f - 1.0f);
}
- d3d11::SetPositionDepthColorVertex<T>(vertices + 0, left, bottom, depthClear, color);
- d3d11::SetPositionDepthColorVertex<T>(vertices + 1, left, top, depthClear, color);
+ d3d11::SetPositionDepthColorVertex<T>(vertices + 0, left, bottom, depthClear, color);
+ d3d11::SetPositionDepthColorVertex<T>(vertices + 1, left, top, depthClear, color);
d3d11::SetPositionDepthColorVertex<T>(vertices + 2, right, bottom, depthClear, color);
- d3d11::SetPositionDepthColorVertex<T>(vertices + 3, right, top, depthClear, color);
+ d3d11::SetPositionDepthColorVertex<T>(vertices + 3, right, top, depthClear, color);
}
Clear11::ClearShader::ClearShader(DXGI_FORMAT colorType,
@@ -82,9 +71,10 @@ Clear11::ClearShader::ClearShader(DXGI_FORMAT colorType,
vertexShader(vsByteCode, vsSize, vsDebugName),
pixelShader(psByteCode, psSize, psDebugName)
{
- D3D11_INPUT_ELEMENT_DESC quadLayout[] = {
- {"POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0},
- {"COLOR", 0, colorType, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0},
+ D3D11_INPUT_ELEMENT_DESC quadLayout[] =
+ {
+ { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
+ { "COLOR", 0, colorType, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 },
};
inputLayout = new d3d11::LazyInputLayout(quadLayout, 2, vsByteCode, vsSize, inputLayoutName);
@@ -113,11 +103,11 @@ Clear11::Clear11(Renderer11 *renderer)
ID3D11Device *device = renderer->getDevice();
D3D11_BUFFER_DESC vbDesc;
- vbDesc.ByteWidth = sizeof(d3d11::PositionDepthColorVertex<float>) * 4;
- vbDesc.Usage = D3D11_USAGE_DYNAMIC;
- vbDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
- vbDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
- vbDesc.MiscFlags = 0;
+ vbDesc.ByteWidth = sizeof(d3d11::PositionDepthColorVertex<float>) * 4;
+ vbDesc.Usage = D3D11_USAGE_DYNAMIC;
+ vbDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
+ vbDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
+ vbDesc.MiscFlags = 0;
vbDesc.StructureByteStride = 0;
result = device->CreateBuffer(&vbDesc, nullptr, &mVertexBuffer);
@@ -125,15 +115,15 @@ Clear11::Clear11(Renderer11 *renderer)
d3d11::SetDebugName(mVertexBuffer, "Clear11 masked clear vertex buffer");
D3D11_RASTERIZER_DESC rsDesc;
- rsDesc.FillMode = D3D11_FILL_SOLID;
- rsDesc.CullMode = D3D11_CULL_NONE;
+ rsDesc.FillMode = D3D11_FILL_SOLID;
+ rsDesc.CullMode = D3D11_CULL_NONE;
rsDesc.FrontCounterClockwise = FALSE;
- rsDesc.DepthBias = 0;
- rsDesc.DepthBiasClamp = 0.0f;
- rsDesc.SlopeScaledDepthBias = 0.0f;
- rsDesc.DepthClipEnable = TRUE;
- rsDesc.ScissorEnable = FALSE;
- rsDesc.MultisampleEnable = FALSE;
+ rsDesc.DepthBias = 0;
+ rsDesc.DepthBiasClamp = 0.0f;
+ rsDesc.SlopeScaledDepthBias = 0.0f;
+ rsDesc.DepthClipEnable = TRUE;
+ rsDesc.ScissorEnable = FALSE;
+ rsDesc.MultisampleEnable = FALSE;
rsDesc.AntialiasedLineEnable = FALSE;
result = device->CreateRasterizerState(&rsDesc, &mRasterizerState);
@@ -142,36 +132,51 @@ Clear11::Clear11(Renderer11 *renderer)
if (mRenderer->getRenderer11DeviceCaps().featureLevel <= D3D_FEATURE_LEVEL_9_3)
{
- mFloatClearShader =
- new ClearShader(DXGI_FORMAT_R32G32B32A32_FLOAT, "Clear11 Float IL", g_VS_ClearFloat,
- ArraySize(g_VS_ClearFloat), "Clear11 Float VS", g_PS_ClearFloat_FL9,
- ArraySize(g_PS_ClearFloat_FL9), "Clear11 Float PS");
+ mFloatClearShader = new ClearShader(DXGI_FORMAT_R32G32B32A32_FLOAT,
+ "Clear11 Float IL",
+ g_VS_ClearFloat,
+ ArraySize(g_VS_ClearFloat),
+ "Clear11 Float VS",
+ g_PS_ClearFloat_FL9,
+ ArraySize(g_PS_ClearFloat_FL9),
+ "Clear11 Float PS");
}
else
{
- mFloatClearShader =
- new ClearShader(DXGI_FORMAT_R32G32B32A32_FLOAT, "Clear11 Float IL", g_VS_ClearFloat,
- ArraySize(g_VS_ClearFloat), "Clear11 Float VS", g_PS_ClearFloat,
- ArraySize(g_PS_ClearFloat), "Clear11 Float PS");
+ mFloatClearShader = new ClearShader(DXGI_FORMAT_R32G32B32A32_FLOAT,
+ "Clear11 Float IL",
+ g_VS_ClearFloat,
+ ArraySize(g_VS_ClearFloat),
+ "Clear11 Float VS",
+ g_PS_ClearFloat,
+ ArraySize(g_PS_ClearFloat),
+ "Clear11 Float PS");
}
if (renderer->isES3Capable())
{
- mUintClearShader =
- new ClearShader(DXGI_FORMAT_R32G32B32A32_UINT, "Clear11 UINT IL", g_VS_ClearUint,
- ArraySize(g_VS_ClearUint), "Clear11 UINT VS", g_PS_ClearUint,
- ArraySize(g_PS_ClearUint), "Clear11 UINT PS");
- mIntClearShader =
- new ClearShader(DXGI_FORMAT_R32G32B32A32_UINT, "Clear11 SINT IL", g_VS_ClearSint,
- ArraySize(g_VS_ClearSint), "Clear11 SINT VS", g_PS_ClearSint,
- ArraySize(g_PS_ClearSint), "Clear11 SINT PS");
+ mUintClearShader = new ClearShader(DXGI_FORMAT_R32G32B32A32_UINT,
+ "Clear11 UINT IL",
+ g_VS_ClearUint,
+ ArraySize(g_VS_ClearUint),
+ "Clear11 UINT VS",
+ g_PS_ClearUint,
+ ArraySize(g_PS_ClearUint),
+ "Clear11 UINT PS");
+ mIntClearShader = new ClearShader(DXGI_FORMAT_R32G32B32A32_UINT,
+ "Clear11 SINT IL",
+ g_VS_ClearSint,
+ ArraySize(g_VS_ClearSint),
+ "Clear11 SINT VS",
+ g_PS_ClearSint,
+ ArraySize(g_PS_ClearSint),
+ "Clear11 SINT PS");
}
}
Clear11::~Clear11()
{
- for (ClearBlendStateMap::iterator i = mClearBlendStates.begin(); i != mClearBlendStates.end();
- i++)
+ for (ClearBlendStateMap::iterator i = mClearBlendStates.begin(); i != mClearBlendStates.end(); i++)
{
SafeRelease(i->second);
}
@@ -181,8 +186,7 @@ Clear11::~Clear11()
SafeDelete(mUintClearShader);
SafeDelete(mIntClearShader);
- for (ClearDepthStencilStateMap::iterator i = mClearDepthStencilStates.begin();
- i != mClearDepthStencilStates.end(); i++)
+ for (ClearDepthStencilStateMap::iterator i = mClearDepthStencilStates.begin(); i != mClearDepthStencilStates.end(); i++)
{
SafeRelease(i->second);
}
@@ -195,9 +199,9 @@ Clear11::~Clear11()
gl::Error Clear11::clearFramebuffer(const ClearParameters &clearParams,
const gl::FramebufferState &fboData)
{
- const auto &colorAttachments = fboData.getColorAttachments();
- const auto &drawBufferStates = fboData.getDrawBufferStates();
- const auto *depthAttachment = fboData.getDepthAttachment();
+ const auto &colorAttachments = fboData.getColorAttachments();
+ const auto &drawBufferStates = fboData.getDrawBufferStates();
+ const auto *depthAttachment = fboData.getDepthAttachment();
const auto *stencilAttachment = fboData.getStencilAttachment();
ASSERT(colorAttachments.size() == drawBufferStates.size());
@@ -205,24 +209,20 @@ gl::Error Clear11::clearFramebuffer(const ClearParameters &clearParams,
// Iterate over the color buffers which require clearing and determine if they can be
// cleared with ID3D11DeviceContext::ClearRenderTargetView or ID3D11DeviceContext1::ClearView.
// This requires:
- // 1) The render target is being cleared to a float value (will be cast to integer when clearing
- // integer
+ // 1) The render target is being cleared to a float value (will be cast to integer when clearing integer
// render targets as expected but does not work the other way around)
// 2) The format of the render target has no color channels that are currently masked out.
- // Clear the easy-to-clear buffers on the spot and accumulate the ones that require special
- // work.
+ // Clear the easy-to-clear buffers on the spot and accumulate the ones that require special work.
//
// If these conditions are met, and:
// - No scissored clear is needed, then clear using ID3D11DeviceContext::ClearRenderTargetView.
// - A scissored clear is needed then clear using ID3D11DeviceContext1::ClearView if available.
// Otherwise draw a quad.
//
- // Also determine if the depth stencil can be cleared with
- // ID3D11DeviceContext::ClearDepthStencilView
+ // Also determine if the depth stencil can be cleared with ID3D11DeviceContext::ClearDepthStencilView
// by checking if the stencil write mask covers the entire stencil.
//
- // To clear the remaining buffers, quads must be drawn containing an int, uint or float vertex
- // color
+ // To clear the remaining buffers, quads must be drawn containing an int, uint or float vertex color
// attribute.
gl::Extents framebufferSize;
@@ -246,7 +246,7 @@ gl::Error Clear11::clearFramebuffer(const ClearParameters &clearParams,
return gl::Error(GL_INVALID_OPERATION);
}
- if (clearParams.scissorEnabled && (clearParams.scissor.x >= framebufferSize.width ||
+ if (clearParams.scissorEnabled && (clearParams.scissor.x >= framebufferSize.width ||
clearParams.scissor.y >= framebufferSize.height ||
clearParams.scissor.x + clearParams.scissor.width <= 0 ||
clearParams.scissor.y + clearParams.scissor.height <= 0))
@@ -255,18 +255,16 @@ gl::Error Clear11::clearFramebuffer(const ClearParameters &clearParams,
return gl::Error(GL_NO_ERROR);
}
- bool needScissoredClear =
- clearParams.scissorEnabled &&
- (clearParams.scissor.x > 0 || clearParams.scissor.y > 0 ||
- clearParams.scissor.x + clearParams.scissor.width < framebufferSize.width ||
- clearParams.scissor.y + clearParams.scissor.height < framebufferSize.height);
+ bool needScissoredClear = clearParams.scissorEnabled && (clearParams.scissor.x > 0 || clearParams.scissor.y > 0 ||
+ clearParams.scissor.x + clearParams.scissor.width < framebufferSize.width ||
+ clearParams.scissor.y + clearParams.scissor.height < framebufferSize.height);
std::vector<MaskedRenderTarget> maskedClearRenderTargets;
- RenderTarget11 *maskedClearDepthStencil = nullptr;
+ RenderTarget11* maskedClearDepthStencil = nullptr;
- ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
+ ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
ID3D11DeviceContext1 *deviceContext1 = mRenderer->getDeviceContext1IfSupported();
- ID3D11Device *device = mRenderer->getDevice();
+ ID3D11Device *device = mRenderer->getDevice();
for (size_t colorAttachmentIndex = 0; colorAttachmentIndex < colorAttachments.size();
colorAttachmentIndex++)
@@ -277,7 +275,11 @@ gl::Error Clear11::clearFramebuffer(const ClearParameters &clearParams,
drawBufferStates[colorAttachmentIndex] != GL_NONE)
{
RenderTarget11 *renderTarget = nullptr;
- ANGLE_TRY(attachment.getRenderTarget(&renderTarget));
+ gl::Error error = attachment.getRenderTarget(&renderTarget);
+ if (error.isError())
+ {
+ return error;
+ }
const gl::InternalFormat &formatInfo = *attachment.getFormat().info;
@@ -309,8 +311,7 @@ gl::Error Clear11::clearFramebuffer(const ClearParameters &clearParams,
(formatInfo.blueBits > 0 && !clearParams.colorMaskBlue) ||
(formatInfo.alphaBits > 0 && !clearParams.colorMaskAlpha))
{
- // A masked clear is required, or a scissored clear is required and
- // ID3D11DeviceContext1::ClearView is unavailable
+ // A masked clear is required, or a scissored clear is required and ID3D11DeviceContext1::ClearView is unavailable
MaskedRenderTarget maskAndRt;
bool clearColor = clearParams.clearColor[colorAttachmentIndex];
maskAndRt.colorMask[0] = (clearColor && clearParams.colorMaskRed);
@@ -322,40 +323,39 @@ gl::Error Clear11::clearFramebuffer(const ClearParameters &clearParams,
}
else
{
- // ID3D11DeviceContext::ClearRenderTargetView or ID3D11DeviceContext1::ClearView is
- // possible
+ // ID3D11DeviceContext::ClearRenderTargetView or ID3D11DeviceContext1::ClearView is possible
ID3D11RenderTargetView *framebufferRTV = renderTarget->getRenderTargetView();
if (!framebufferRTV)
{
- return gl::Error(GL_OUT_OF_MEMORY,
- "Internal render target view pointer unexpectedly null.");
+ return gl::Error(GL_OUT_OF_MEMORY, "Internal render target view pointer unexpectedly null.");
}
- const auto &nativeFormat = renderTarget->getFormatSet().format();
+ const auto &dxgiFormatInfo =
+ d3d11::GetDXGIFormatInfo(renderTarget->getFormatSet().rtvFormat);
- // Check if the actual format has a channel that the internal format does not and
- // set them to the default values
+ // Check if the actual format has a channel that the internal format does not and set them to the
+ // default values
float clearValues[4] = {
- ((formatInfo.redBits == 0 && nativeFormat.redBits > 0)
+ ((formatInfo.redBits == 0 && dxgiFormatInfo.redBits > 0)
? 0.0f
: clearParams.colorFClearValue.red),
- ((formatInfo.greenBits == 0 && nativeFormat.greenBits > 0)
+ ((formatInfo.greenBits == 0 && dxgiFormatInfo.greenBits > 0)
? 0.0f
: clearParams.colorFClearValue.green),
- ((formatInfo.blueBits == 0 && nativeFormat.blueBits > 0)
+ ((formatInfo.blueBits == 0 && dxgiFormatInfo.blueBits > 0)
? 0.0f
: clearParams.colorFClearValue.blue),
- ((formatInfo.alphaBits == 0 && nativeFormat.alphaBits > 0)
+ ((formatInfo.alphaBits == 0 && dxgiFormatInfo.alphaBits > 0)
? 1.0f
: clearParams.colorFClearValue.alpha),
};
- if (formatInfo.alphaBits == 1)
+ if (dxgiFormatInfo.alphaBits == 1)
{
- // Some drivers do not correctly handle calling Clear() on a format with 1-bit
- // alpha. They can incorrectly round all non-zero values up to 1.0f. Note that
- // WARP does not do this. We should handle the rounding for them instead.
+ // Some drivers do not correctly handle calling Clear() on a format with 1-bit alpha.
+ // They can incorrectly round all non-zero values up to 1.0f. Note that WARP does not do this.
+ // We should handle the rounding for them instead.
clearValues[3] = (clearParams.colorFClearValue.alpha >= 0.5f) ? 1.0f : 0.0f;
}
@@ -365,26 +365,16 @@ gl::Error Clear11::clearFramebuffer(const ClearParameters &clearParams,
ASSERT(deviceContext1);
D3D11_RECT rect;
- rect.left = clearParams.scissor.x;
- rect.right = clearParams.scissor.x + clearParams.scissor.width;
- rect.top = clearParams.scissor.y;
+ rect.left = clearParams.scissor.x;
+ rect.right = clearParams.scissor.x + clearParams.scissor.width;
+ rect.top = clearParams.scissor.y;
rect.bottom = clearParams.scissor.y + clearParams.scissor.height;
deviceContext1->ClearView(framebufferRTV, clearValues, &rect, 1);
-
- if (mRenderer->getWorkarounds().callClearTwice)
- {
- deviceContext1->ClearView(framebufferRTV, clearValues, &rect, 1);
- }
}
else
{
deviceContext->ClearRenderTargetView(framebufferRTV, clearValues);
-
- if (mRenderer->getWorkarounds().callClearTwice)
- {
- deviceContext->ClearRenderTargetView(framebufferRTV, clearValues);
- }
}
}
}
@@ -392,20 +382,21 @@ gl::Error Clear11::clearFramebuffer(const ClearParameters &clearParams,
if (clearParams.clearDepth || clearParams.clearStencil)
{
- const gl::FramebufferAttachment *attachment =
- (depthAttachment != nullptr) ? depthAttachment : stencilAttachment;
+ const gl::FramebufferAttachment *attachment = (depthAttachment != nullptr) ? depthAttachment : stencilAttachment;
ASSERT(attachment != nullptr);
RenderTarget11 *renderTarget = nullptr;
- ANGLE_TRY(attachment->getRenderTarget(&renderTarget));
+ gl::Error error = attachment->getRenderTarget(&renderTarget);
+ if (error.isError())
+ {
+ return error;
+ }
- const auto &nativeFormat = renderTarget->getFormatSet().format();
+ const auto &dxgiFormatInfo =
+ d3d11::GetDXGIFormatInfo(renderTarget->getFormatSet().dsvFormat);
- unsigned int stencilUnmasked =
- (stencilAttachment != nullptr) ? (1 << nativeFormat.stencilBits) - 1 : 0;
- bool needMaskedStencilClear =
- clearParams.clearStencil &&
- (clearParams.stencilWriteMask & stencilUnmasked) != stencilUnmasked;
+ unsigned int stencilUnmasked = (stencilAttachment != nullptr) ? (1 << dxgiFormatInfo.stencilBits) - 1 : 0;
+ bool needMaskedStencilClear = clearParams.clearStencil && (clearParams.stencilWriteMask & stencilUnmasked) != stencilUnmasked;
if (needScissoredClear || needMaskedStencilClear)
{
@@ -416,156 +407,144 @@ gl::Error Clear11::clearFramebuffer(const ClearParameters &clearParams,
ID3D11DepthStencilView *framebufferDSV = renderTarget->getDepthStencilView();
if (!framebufferDSV)
{
- return gl::Error(GL_OUT_OF_MEMORY,
- "Internal depth stencil view pointer unexpectedly null.");
+ return gl::Error(GL_OUT_OF_MEMORY, "Internal depth stencil view pointer unexpectedly null.");
}
- UINT clearFlags = (clearParams.clearDepth ? D3D11_CLEAR_DEPTH : 0) |
- (clearParams.clearStencil ? D3D11_CLEAR_STENCIL : 0);
- FLOAT depthClear = gl::clamp01(clearParams.depthClearValue);
+ UINT clearFlags = (clearParams.clearDepth ? D3D11_CLEAR_DEPTH : 0) |
+ (clearParams.clearStencil ? D3D11_CLEAR_STENCIL : 0);
+ FLOAT depthClear = gl::clamp01(clearParams.depthClearValue);
UINT8 stencilClear = clearParams.stencilClearValue & 0xFF;
- deviceContext->ClearDepthStencilView(framebufferDSV, clearFlags, depthClear,
- stencilClear);
+ deviceContext->ClearDepthStencilView(framebufferDSV, clearFlags, depthClear, stencilClear);
}
}
- if (maskedClearRenderTargets.empty() && !maskedClearDepthStencil)
+ if (maskedClearRenderTargets.size() > 0 || maskedClearDepthStencil)
{
- return gl::NoError();
- }
+ // To clear the render targets and depth stencil in one pass:
+ //
+ // Render a quad clipped to the scissor rectangle which draws the clear color and a blend
+ // state that will perform the required color masking.
+ //
+ // The quad's depth is equal to the depth clear value with a depth stencil state that
+ // will enable or disable depth test/writes if the depth buffer should be cleared or not.
+ //
+ // The rasterizer state's stencil is set to always pass or fail based on if the stencil
+ // should be cleared or not with a stencil write mask of the stencil clear value.
+ //
+ // ======================================================================================
+ //
+ // Luckily, the gl spec (ES 3.0.2 pg 183) states that the results of clearing a render-
+ // buffer that is not normalized fixed point or floating point with floating point values
+ // are undefined so we can just write floats to them and D3D11 will bit cast them to
+ // integers.
+ //
+ // Also, we don't have to worry about attempting to clear a normalized fixed/floating point
+ // buffer with integer values because there is no gl API call which would allow it,
+ // glClearBuffer* calls only clear a single renderbuffer at a time which is verified to
+ // be a compatible clear type.
+
+ // Bind all the render targets which need clearing
+ ASSERT(maskedClearRenderTargets.size() <= mRenderer->getNativeCaps().maxDrawBuffers);
+ std::vector<ID3D11RenderTargetView*> rtvs(maskedClearRenderTargets.size());
+ for (unsigned int i = 0; i < maskedClearRenderTargets.size(); i++)
+ {
+ RenderTarget11 *renderTarget = maskedClearRenderTargets[i].renderTarget;
+ ID3D11RenderTargetView *rtv = renderTarget->getRenderTargetView();
+ if (!rtv)
+ {
+ return gl::Error(GL_OUT_OF_MEMORY, "Internal render target view pointer unexpectedly null.");
+ }
- // To clear the render targets and depth stencil in one pass:
- //
- // Render a quad clipped to the scissor rectangle which draws the clear color and a blend
- // state that will perform the required color masking.
- //
- // The quad's depth is equal to the depth clear value with a depth stencil state that
- // will enable or disable depth test/writes if the depth buffer should be cleared or not.
- //
- // The rasterizer state's stencil is set to always pass or fail based on if the stencil
- // should be cleared or not with a stencil write mask of the stencil clear value.
- //
- // ======================================================================================
- //
- // Luckily, the gl spec (ES 3.0.2 pg 183) states that the results of clearing a render-
- // buffer that is not normalized fixed point or floating point with floating point values
- // are undefined so we can just write floats to them and D3D11 will bit cast them to
- // integers.
- //
- // Also, we don't have to worry about attempting to clear a normalized fixed/floating point
- // buffer with integer values because there is no gl API call which would allow it,
- // glClearBuffer* calls only clear a single renderbuffer at a time which is verified to
- // be a compatible clear type.
-
- // Bind all the render targets which need clearing
- ASSERT(maskedClearRenderTargets.size() <= mRenderer->getNativeCaps().maxDrawBuffers);
- std::vector<ID3D11RenderTargetView *> rtvs(maskedClearRenderTargets.size());
- for (unsigned int i = 0; i < maskedClearRenderTargets.size(); i++)
- {
- RenderTarget11 *renderTarget = maskedClearRenderTargets[i].renderTarget;
- ID3D11RenderTargetView *rtv = renderTarget->getRenderTargetView();
- if (!rtv)
+ rtvs[i] = rtv;
+ }
+ ID3D11DepthStencilView *dsv = maskedClearDepthStencil ? maskedClearDepthStencil->getDepthStencilView() : nullptr;
+
+ ID3D11BlendState *blendState = getBlendState(maskedClearRenderTargets);
+ const FLOAT blendFactors[4] = { 1.0f, 1.0f, 1.0f, 1.0f };
+ const UINT sampleMask = 0xFFFFFFFF;
+
+ ID3D11DepthStencilState *dsState = getDepthStencilState(clearParams);
+ const UINT stencilClear = clearParams.stencilClearValue & 0xFF;
+
+ // Set the vertices
+ UINT vertexStride = 0;
+ const UINT startIdx = 0;
+ ClearShader *shader = nullptr;
+ D3D11_MAPPED_SUBRESOURCE mappedResource;
+ HRESULT result = deviceContext->Map(mVertexBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);
+ if (FAILED(result))
{
- return gl::Error(GL_OUT_OF_MEMORY,
- "Internal render target view pointer unexpectedly null.");
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to map internal masked clear vertex buffer, HRESULT: 0x%X.", result);
}
- rtvs[i] = rtv;
- }
- ID3D11DepthStencilView *dsv =
- maskedClearDepthStencil ? maskedClearDepthStencil->getDepthStencilView() : nullptr;
-
- ID3D11BlendState *blendState = getBlendState(maskedClearRenderTargets);
- const FLOAT blendFactors[4] = {1.0f, 1.0f, 1.0f, 1.0f};
- const UINT sampleMask = 0xFFFFFFFF;
-
- ID3D11DepthStencilState *dsState = getDepthStencilState(clearParams);
- const UINT stencilClear = clearParams.stencilClearValue & 0xFF;
-
- // Set the vertices
- UINT vertexStride = 0;
- const UINT startIdx = 0;
- ClearShader *shader = nullptr;
- D3D11_MAPPED_SUBRESOURCE mappedResource;
- HRESULT result =
- deviceContext->Map(mVertexBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);
- if (FAILED(result))
- {
- return gl::Error(GL_OUT_OF_MEMORY,
- "Failed to map internal masked clear vertex buffer, HRESULT: 0x%X.",
- result);
- }
-
- const gl::Rectangle *scissorPtr = clearParams.scissorEnabled ? &clearParams.scissor : nullptr;
- switch (clearParams.colorClearType)
- {
- case GL_FLOAT:
- ApplyVertices(framebufferSize, scissorPtr, clearParams.colorFClearValue,
- clearParams.depthClearValue, mappedResource.pData);
+ const gl::Rectangle *scissorPtr = clearParams.scissorEnabled ? &clearParams.scissor : nullptr;
+ switch (clearParams.colorClearType)
+ {
+ case GL_FLOAT:
+ ApplyVertices(framebufferSize, scissorPtr, clearParams.colorFClearValue, clearParams.depthClearValue, mappedResource.pData);
vertexStride = sizeof(d3d11::PositionDepthColorVertex<float>);
- shader = mFloatClearShader;
+ shader = mFloatClearShader;
break;
- case GL_UNSIGNED_INT:
- ApplyVertices(framebufferSize, scissorPtr, clearParams.colorUIClearValue,
- clearParams.depthClearValue, mappedResource.pData);
+ case GL_UNSIGNED_INT:
+ ApplyVertices(framebufferSize, scissorPtr, clearParams.colorUIClearValue, clearParams.depthClearValue, mappedResource.pData);
vertexStride = sizeof(d3d11::PositionDepthColorVertex<unsigned int>);
- shader = mUintClearShader;
+ shader = mUintClearShader;
break;
- case GL_INT:
- ApplyVertices(framebufferSize, scissorPtr, clearParams.colorIClearValue,
- clearParams.depthClearValue, mappedResource.pData);
+ case GL_INT:
+ ApplyVertices(framebufferSize, scissorPtr, clearParams.colorIClearValue, clearParams.depthClearValue, mappedResource.pData);
vertexStride = sizeof(d3d11::PositionDepthColorVertex<int>);
- shader = mIntClearShader;
+ shader = mIntClearShader;
break;
- default:
+ default:
UNREACHABLE();
break;
- }
-
- deviceContext->Unmap(mVertexBuffer, 0);
-
- // Set the viewport to be the same size as the framebuffer
- D3D11_VIEWPORT viewport;
- viewport.TopLeftX = 0;
- viewport.TopLeftY = 0;
- viewport.Width = static_cast<FLOAT>(framebufferSize.width);
- viewport.Height = static_cast<FLOAT>(framebufferSize.height);
- viewport.MinDepth = 0;
- viewport.MaxDepth = 1;
- deviceContext->RSSetViewports(1, &viewport);
-
- // Apply state
- deviceContext->OMSetBlendState(blendState, blendFactors, sampleMask);
- deviceContext->OMSetDepthStencilState(dsState, stencilClear);
- deviceContext->RSSetState(mRasterizerState);
-
- // Apply shaders
- deviceContext->IASetInputLayout(shader->inputLayout->resolve(device));
- deviceContext->VSSetShader(shader->vertexShader.resolve(device), nullptr, 0);
- deviceContext->PSSetShader(shader->pixelShader.resolve(device), nullptr, 0);
- deviceContext->GSSetShader(nullptr, nullptr, 0);
-
- // Apply vertex buffer
- deviceContext->IASetVertexBuffers(0, 1, &mVertexBuffer, &vertexStride, &startIdx);
- deviceContext->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
-
- // Apply render targets
- mRenderer->getStateManager()->setOneTimeRenderTargets(rtvs, dsv);
-
- // Draw the clear quad
- deviceContext->Draw(4, 0);
+ }
- // Clean up
- mRenderer->markAllStateDirty();
+ deviceContext->Unmap(mVertexBuffer, 0);
+
+ // Set the viewport to be the same size as the framebuffer
+ D3D11_VIEWPORT viewport;
+ viewport.TopLeftX = 0;
+ viewport.TopLeftY = 0;
+ viewport.Width = static_cast<FLOAT>(framebufferSize.width);
+ viewport.Height = static_cast<FLOAT>(framebufferSize.height);
+ viewport.MinDepth = 0;
+ viewport.MaxDepth = 1;
+ deviceContext->RSSetViewports(1, &viewport);
+
+ // Apply state
+ deviceContext->OMSetBlendState(blendState, blendFactors, sampleMask);
+ deviceContext->OMSetDepthStencilState(dsState, stencilClear);
+ deviceContext->RSSetState(mRasterizerState);
+
+ // Apply shaders
+ deviceContext->IASetInputLayout(shader->inputLayout->resolve(device));
+ deviceContext->VSSetShader(shader->vertexShader.resolve(device), nullptr, 0);
+ deviceContext->PSSetShader(shader->pixelShader.resolve(device), nullptr, 0);
+ deviceContext->GSSetShader(nullptr, nullptr, 0);
+
+ // Apply vertex buffer
+ deviceContext->IASetVertexBuffers(0, 1, &mVertexBuffer, &vertexStride, &startIdx);
+ deviceContext->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
+
+ // Apply render targets
+ mRenderer->getStateManager()->setOneTimeRenderTargets(rtvs, dsv);
+
+ // Draw the clear quad
+ deviceContext->Draw(4, 0);
+
+ // Clean up
+ mRenderer->markAllStateDirty();
+ }
- return gl::NoError();
+ return gl::Error(GL_NO_ERROR);
}
-ID3D11BlendState *Clear11::getBlendState(const std::vector<MaskedRenderTarget> &rts)
+ID3D11BlendState *Clear11::getBlendState(const std::vector<MaskedRenderTarget>& rts)
{
ClearBlendInfo blendKey = {};
for (unsigned int i = 0; i < D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; i++)
@@ -573,12 +552,11 @@ ID3D11BlendState *Clear11::getBlendState(const std::vector<MaskedRenderTarget> &
if (i < rts.size())
{
RenderTarget11 *rt = rts[i].renderTarget;
- const gl::InternalFormat &formatInfo =
- gl::GetInternalFormatInfo(rt->getInternalFormat());
+ const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(rt->getInternalFormat());
- blendKey.maskChannels[i][0] = (rts[i].colorMask[0] && formatInfo.redBits > 0);
+ blendKey.maskChannels[i][0] = (rts[i].colorMask[0] && formatInfo.redBits > 0);
blendKey.maskChannels[i][1] = (rts[i].colorMask[1] && formatInfo.greenBits > 0);
- blendKey.maskChannels[i][2] = (rts[i].colorMask[2] && formatInfo.blueBits > 0);
+ blendKey.maskChannels[i][2] = (rts[i].colorMask[2] && formatInfo.blueBits > 0);
blendKey.maskChannels[i][3] = (rts[i].colorMask[3] && formatInfo.alphaBits > 0);
}
else
@@ -597,21 +575,22 @@ ID3D11BlendState *Clear11::getBlendState(const std::vector<MaskedRenderTarget> &
}
else
{
- D3D11_BLEND_DESC blendDesc = {0};
- blendDesc.AlphaToCoverageEnable = FALSE;
+ D3D11_BLEND_DESC blendDesc = { 0 };
+ blendDesc.AlphaToCoverageEnable = FALSE;
blendDesc.IndependentBlendEnable = (rts.size() > 1) ? TRUE : FALSE;
for (unsigned int j = 0; j < D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; j++)
{
- blendDesc.RenderTarget[j].BlendEnable = FALSE;
- blendDesc.RenderTarget[j].RenderTargetWriteMask = gl_d3d11::ConvertColorMask(
- blendKey.maskChannels[j][0], blendKey.maskChannels[j][1],
- blendKey.maskChannels[j][2], blendKey.maskChannels[j][3]);
+ blendDesc.RenderTarget[j].BlendEnable = FALSE;
+ blendDesc.RenderTarget[j].RenderTargetWriteMask = gl_d3d11::ConvertColorMask(blendKey.maskChannels[j][0],
+ blendKey.maskChannels[j][1],
+ blendKey.maskChannels[j][2],
+ blendKey.maskChannels[j][3]);
}
- ID3D11Device *device = mRenderer->getDevice();
- ID3D11BlendState *blendState = nullptr;
- HRESULT result = device->CreateBlendState(&blendDesc, &blendState);
+ ID3D11Device *device = mRenderer->getDevice();
+ ID3D11BlendState* blendState = nullptr;
+ HRESULT result = device->CreateBlendState(&blendDesc, &blendState);
if (FAILED(result) || !blendState)
{
ERR("Unable to create a ID3D11BlendState, HRESULT: 0x%X.", result);
@@ -626,10 +605,10 @@ ID3D11BlendState *Clear11::getBlendState(const std::vector<MaskedRenderTarget> &
ID3D11DepthStencilState *Clear11::getDepthStencilState(const ClearParameters &clearParams)
{
- ClearDepthStencilInfo dsKey = {0};
- dsKey.clearDepth = clearParams.clearDepth;
- dsKey.clearStencil = clearParams.clearStencil;
- dsKey.stencilWriteMask = clearParams.stencilWriteMask & 0xFF;
+ ClearDepthStencilInfo dsKey = { 0 };
+ dsKey.clearDepth = clearParams.clearDepth;
+ dsKey.clearStencil = clearParams.clearStencil;
+ dsKey.stencilWriteMask = clearParams.stencilWriteMask & 0xFF;
ClearDepthStencilStateMap::const_iterator i = mClearDepthStencilStates.find(dsKey);
if (i != mClearDepthStencilStates.end())
@@ -638,26 +617,25 @@ ID3D11DepthStencilState *Clear11::getDepthStencilState(const ClearParameters &cl
}
else
{
- D3D11_DEPTH_STENCIL_DESC dsDesc = {0};
- dsDesc.DepthEnable = dsKey.clearDepth ? TRUE : FALSE;
- dsDesc.DepthWriteMask =
- dsKey.clearDepth ? D3D11_DEPTH_WRITE_MASK_ALL : D3D11_DEPTH_WRITE_MASK_ZERO;
- dsDesc.DepthFunc = D3D11_COMPARISON_ALWAYS;
- dsDesc.StencilEnable = dsKey.clearStencil ? TRUE : FALSE;
- dsDesc.StencilReadMask = 0;
- dsDesc.StencilWriteMask = dsKey.stencilWriteMask;
- dsDesc.FrontFace.StencilFailOp = D3D11_STENCIL_OP_REPLACE;
+ D3D11_DEPTH_STENCIL_DESC dsDesc = { 0 };
+ dsDesc.DepthEnable = dsKey.clearDepth ? TRUE : FALSE;
+ dsDesc.DepthWriteMask = dsKey.clearDepth ? D3D11_DEPTH_WRITE_MASK_ALL : D3D11_DEPTH_WRITE_MASK_ZERO;
+ dsDesc.DepthFunc = D3D11_COMPARISON_ALWAYS;
+ dsDesc.StencilEnable = dsKey.clearStencil ? TRUE : FALSE;
+ dsDesc.StencilReadMask = 0;
+ dsDesc.StencilWriteMask = dsKey.stencilWriteMask;
+ dsDesc.FrontFace.StencilFailOp = D3D11_STENCIL_OP_REPLACE;
dsDesc.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_REPLACE;
- dsDesc.FrontFace.StencilPassOp = D3D11_STENCIL_OP_REPLACE;
- dsDesc.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS;
- dsDesc.BackFace.StencilFailOp = D3D11_STENCIL_OP_REPLACE;
- dsDesc.BackFace.StencilDepthFailOp = D3D11_STENCIL_OP_REPLACE;
- dsDesc.BackFace.StencilPassOp = D3D11_STENCIL_OP_REPLACE;
- dsDesc.BackFace.StencilFunc = D3D11_COMPARISON_ALWAYS;
-
- ID3D11Device *device = mRenderer->getDevice();
- ID3D11DepthStencilState *dsState = nullptr;
- HRESULT result = device->CreateDepthStencilState(&dsDesc, &dsState);
+ dsDesc.FrontFace.StencilPassOp = D3D11_STENCIL_OP_REPLACE;
+ dsDesc.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS;
+ dsDesc.BackFace.StencilFailOp = D3D11_STENCIL_OP_REPLACE;
+ dsDesc.BackFace.StencilDepthFailOp = D3D11_STENCIL_OP_REPLACE;
+ dsDesc.BackFace.StencilPassOp = D3D11_STENCIL_OP_REPLACE;
+ dsDesc.BackFace.StencilFunc = D3D11_COMPARISON_ALWAYS;
+
+ ID3D11Device *device = mRenderer->getDevice();
+ ID3D11DepthStencilState* dsState = nullptr;
+ HRESULT result = device->CreateDepthStencilState(&dsDesc, &dsState);
if (FAILED(result) || !dsState)
{
ERR("Unable to create a ID3D11DepthStencilState, HRESULT: 0x%X.", result);
@@ -669,4 +647,5 @@ ID3D11DepthStencilState *Clear11::getDepthStencilState(const ClearParameters &cl
return dsState;
}
}
+
}