Commit b5e884a4 by Shahmeer Esmail Committed by Commit Bot

Clear11 VerticesTransform, RasterizerStates, ScissorRect

- Skip clears if an empty scissor rect is set - Use rastStates to apply scissoring instead of recomputing the scissored positions and updating the VB and updating the VB for every clear - Use ComPtrs for VB and RasterizerStates BUG=angleproject:1934 Change-Id: Ib4448d8568b465df5de57607be4985095f6bd014 Reviewed-on: https://chromium-review.googlesource.com/453881 Commit-Queue: Jamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org>
parent 420ba154
...@@ -33,41 +33,24 @@ ...@@ -33,41 +33,24 @@
namespace rx namespace rx
{ {
static constexpr uint32_t g_VertexSize = sizeof(d3d11::PositionDepthColorVertex<float>);
template <typename T> template <typename T>
static void ApplyVertices(const gl::Extents &framebufferSize, static void ApplyVertices(const gl::Color<T> &color, const float depth, void *buffer)
const gl::Rectangle *scissor,
const gl::Color<T> &color,
float depth,
void *buffer)
{ {
d3d11::PositionDepthColorVertex<T> *vertices = d3d11::PositionDepthColorVertex<T> *vertices =
reinterpret_cast<d3d11::PositionDepthColorVertex<T> *>(buffer); reinterpret_cast<d3d11::PositionDepthColorVertex<T> *>(buffer);
float depthClear = gl::clamp01(depth); const float z = gl::clamp01(depth);
float left = -1.0f; const float left = -1.0f;
float right = 1.0f; const float right = 1.0f;
float top = -1.0f; const float top = -1.0f;
float bottom = 1.0f; const float bottom = 1.0f;
// Clip the quad coordinates to the scissor if needed d3d11::SetPositionDepthColorVertex<T>(vertices + 0, left, bottom, z, color);
if (scissor != nullptr) d3d11::SetPositionDepthColorVertex<T>(vertices + 1, left, top, z, color);
{ d3d11::SetPositionDepthColorVertex<T>(vertices + 2, right, bottom, z, color);
left = std::max(left, (scissor->x / float(framebufferSize.width)) * 2.0f - 1.0f); d3d11::SetPositionDepthColorVertex<T>(vertices + 3, right, top, z, color);
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 + 2, right, bottom, depthClear, color);
d3d11::SetPositionDepthColorVertex<T>(vertices + 3, right, top, depthClear, color);
} }
Clear11::ClearShader::ClearShader(DXGI_FORMAT colorType, Clear11::ClearShader::ClearShader(DXGI_FORMAT colorType,
...@@ -101,9 +84,7 @@ Clear11::Clear11(Renderer11 *renderer) ...@@ -101,9 +84,7 @@ Clear11::Clear11(Renderer11 *renderer)
: mRenderer(renderer), : mRenderer(renderer),
mFloatClearShader(nullptr), mFloatClearShader(nullptr),
mUintClearShader(nullptr), mUintClearShader(nullptr),
mIntClearShader(nullptr), mIntClearShader(nullptr)
mVertexBuffer(nullptr),
mRasterizerState(nullptr)
{ {
TRACE_EVENT0("gpu.angle", "Clear11::Clear11"); TRACE_EVENT0("gpu.angle", "Clear11::Clear11");
...@@ -111,14 +92,14 @@ Clear11::Clear11(Renderer11 *renderer) ...@@ -111,14 +92,14 @@ Clear11::Clear11(Renderer11 *renderer)
ID3D11Device *device = renderer->getDevice(); ID3D11Device *device = renderer->getDevice();
D3D11_BUFFER_DESC vbDesc; D3D11_BUFFER_DESC vbDesc;
vbDesc.ByteWidth = sizeof(d3d11::PositionDepthColorVertex<float>) * 4; vbDesc.ByteWidth = g_VertexSize * 4;
vbDesc.Usage = D3D11_USAGE_DYNAMIC; vbDesc.Usage = D3D11_USAGE_DYNAMIC;
vbDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER; vbDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
vbDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; vbDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
vbDesc.MiscFlags = 0; vbDesc.MiscFlags = 0;
vbDesc.StructureByteStride = 0; vbDesc.StructureByteStride = 0;
result = device->CreateBuffer(&vbDesc, nullptr, &mVertexBuffer); result = device->CreateBuffer(&vbDesc, nullptr, mVertexBuffer.GetAddressOf());
ASSERT(SUCCEEDED(result)); ASSERT(SUCCEEDED(result));
d3d11::SetDebugName(mVertexBuffer, "Clear11 masked clear vertex buffer"); d3d11::SetDebugName(mVertexBuffer, "Clear11 masked clear vertex buffer");
...@@ -134,9 +115,16 @@ Clear11::Clear11(Renderer11 *renderer) ...@@ -134,9 +115,16 @@ Clear11::Clear11(Renderer11 *renderer)
rsDesc.MultisampleEnable = FALSE; rsDesc.MultisampleEnable = FALSE;
rsDesc.AntialiasedLineEnable = FALSE; rsDesc.AntialiasedLineEnable = FALSE;
result = device->CreateRasterizerState(&rsDesc, &mRasterizerState); result = device->CreateRasterizerState(&rsDesc, mScissorDisabledRasterizerState.GetAddressOf());
ASSERT(SUCCEEDED(result));
d3d11::SetDebugName(mScissorDisabledRasterizerState,
"Clear11 Rasterizer State with scissor disabled");
rsDesc.ScissorEnable = TRUE;
result = device->CreateRasterizerState(&rsDesc, mScissorEnabledRasterizerState.GetAddressOf());
ASSERT(SUCCEEDED(result)); ASSERT(SUCCEEDED(result));
d3d11::SetDebugName(mRasterizerState, "Clear11 masked clear rasterizer state"); d3d11::SetDebugName(mScissorEnabledRasterizerState,
"Clear11 Rasterizer State with scissor enabled");
if (mRenderer->getRenderer11DeviceCaps().featureLevel <= D3D_FEATURE_LEVEL_9_3) if (mRenderer->getRenderer11DeviceCaps().featureLevel <= D3D_FEATURE_LEVEL_9_3)
{ {
...@@ -202,8 +190,6 @@ Clear11::~Clear11() ...@@ -202,8 +190,6 @@ Clear11::~Clear11()
SafeDelete(mFloatClearShader); SafeDelete(mFloatClearShader);
SafeDelete(mUintClearShader); SafeDelete(mUintClearShader);
SafeDelete(mIntClearShader); SafeDelete(mIntClearShader);
SafeRelease(mVertexBuffer);
SafeRelease(mRasterizerState);
} }
gl::Error Clear11::clearFramebuffer(const ClearParameters &clearParams, gl::Error Clear11::clearFramebuffer(const ClearParameters &clearParams,
...@@ -211,11 +197,17 @@ gl::Error Clear11::clearFramebuffer(const ClearParameters &clearParams, ...@@ -211,11 +197,17 @@ gl::Error Clear11::clearFramebuffer(const ClearParameters &clearParams,
{ {
const auto &colorAttachments = fboData.getColorAttachments(); const auto &colorAttachments = fboData.getColorAttachments();
const auto &drawBufferStates = fboData.getDrawBufferStates(); const auto &drawBufferStates = fboData.getDrawBufferStates();
const auto *depthAttachment = fboData.getDepthAttachment(); const gl::FramebufferAttachment *depthStencilAttachment = fboData.getDepthOrStencilAttachment();
const auto *stencilAttachment = fboData.getStencilAttachment(); RenderTarget11 *depthStencilRenderTarget = nullptr;
ASSERT(colorAttachments.size() <= drawBufferStates.size()); ASSERT(colorAttachments.size() <= drawBufferStates.size());
if (clearParams.clearDepth || clearParams.clearStencil)
{
ASSERT(depthStencilAttachment != nullptr);
ANGLE_TRY(depthStencilAttachment->getRenderTarget(&depthStencilRenderTarget));
}
// Iterate over the color buffers which require clearing and determine if they can be // Iterate over the color buffers which require clearing and determine if they can be
// cleared with ID3D11DeviceContext::ClearRenderTargetView or ID3D11DeviceContext1::ClearView. // cleared with ID3D11DeviceContext::ClearRenderTargetView or ID3D11DeviceContext1::ClearView.
// This requires: // This requires:
...@@ -240,43 +232,45 @@ gl::Error Clear11::clearFramebuffer(const ClearParameters &clearParams, ...@@ -240,43 +232,45 @@ gl::Error Clear11::clearFramebuffer(const ClearParameters &clearParams,
gl::Extents framebufferSize; gl::Extents framebufferSize;
const gl::FramebufferAttachment *colorAttachment = fboData.getFirstColorAttachment(); if (depthStencilRenderTarget != nullptr)
if (colorAttachment != nullptr)
{
framebufferSize = colorAttachment->getSize();
}
else if (depthAttachment != nullptr)
{ {
framebufferSize = depthAttachment->getSize(); framebufferSize = depthStencilRenderTarget->getExtents();
}
else if (stencilAttachment != nullptr)
{
framebufferSize = stencilAttachment->getSize();
} }
else else
{ {
const auto colorAttachment = fboData.getFirstColorAttachment();
if (!colorAttachment)
{
UNREACHABLE(); UNREACHABLE();
return gl::Error(GL_INVALID_OPERATION); return gl::InternalError();
} }
if (clearParams.scissorEnabled && (clearParams.scissor.x >= framebufferSize.width || framebufferSize = colorAttachment->getSize();
}
bool needScissoredClear = false;
if (clearParams.scissorEnabled)
{
if (clearParams.scissor.x >= framebufferSize.width ||
clearParams.scissor.y >= framebufferSize.height || clearParams.scissor.y >= framebufferSize.height ||
clearParams.scissor.x + clearParams.scissor.width <= 0 || clearParams.scissor.x + clearParams.scissor.width <= 0 ||
clearParams.scissor.y + clearParams.scissor.height <= 0)) clearParams.scissor.y + clearParams.scissor.height <= 0 ||
clearParams.scissor.width == 0 || clearParams.scissor.height == 0)
{ {
// Scissor is enabled and the scissor rectangle is outside the renderbuffer // Scissor rect is outside the renderbuffer or is an empty rect
return gl::NoError(); return gl::NoError();
} }
bool needScissoredClear = needScissoredClear =
clearParams.scissorEnabled && clearParams.scissor.x > 0 || clearParams.scissor.y > 0 ||
(clearParams.scissor.x > 0 || clearParams.scissor.y > 0 ||
clearParams.scissor.x + clearParams.scissor.width < framebufferSize.width || clearParams.scissor.x + clearParams.scissor.width < framebufferSize.width ||
clearParams.scissor.y + clearParams.scissor.height < framebufferSize.height); clearParams.scissor.y + clearParams.scissor.height < framebufferSize.height;
}
ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext(); ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
ID3D11DeviceContext1 *deviceContext1 = mRenderer->getDeviceContext1IfSupported(); ID3D11DeviceContext1 *deviceContext1 = mRenderer->getDeviceContext1IfSupported();
ID3D11Device *device = mRenderer->getDevice();
std::array<ID3D11RenderTargetView *, D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT> rtvs; std::array<ID3D11RenderTargetView *, D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT> rtvs;
std::array<uint8_t, D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT> rtvMasks; std::array<uint8_t, D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT> rtvMasks;
...@@ -405,36 +399,30 @@ gl::Error Clear11::clearFramebuffer(const ClearParameters &clearParams, ...@@ -405,36 +399,30 @@ gl::Error Clear11::clearFramebuffer(const ClearParameters &clearParams,
} }
} }
if (clearParams.clearDepth || clearParams.clearStencil) if (depthStencilRenderTarget)
{ {
const gl::FramebufferAttachment *attachment = dsv = depthStencilRenderTarget->getDepthStencilView();
(depthAttachment != nullptr) ? depthAttachment : stencilAttachment;
ASSERT(attachment != nullptr);
RenderTarget11 *renderTarget = nullptr; if (!dsv)
ANGLE_TRY(attachment->getRenderTarget(&renderTarget)); {
return gl::OutOfMemory() << "Clear11: Depth stencil view pointer unexpectedly null.";
}
const auto &nativeFormat = renderTarget->getFormatSet().format(); const auto &nativeFormat = depthStencilRenderTarget->getFormatSet().format();
const gl::FramebufferAttachment *stencilAttachment = fboData.getStencilAttachment();
unsigned int stencilUnmasked = uint32_t stencilUnmasked =
(stencilAttachment != nullptr) ? (1 << nativeFormat.stencilBits) - 1 : 0; (stencilAttachment != nullptr) ? (1 << nativeFormat.stencilBits) - 1 : 0;
bool needMaskedStencilClear = bool needMaskedStencilClear =
clearParams.clearStencil && clearParams.clearStencil &&
(clearParams.stencilWriteMask & stencilUnmasked) != stencilUnmasked; (clearParams.stencilWriteMask & stencilUnmasked) != stencilUnmasked;
dsv = renderTarget->getDepthStencilView();
if (!dsv)
{
return gl::OutOfMemory() << "Clear11: Depth stencil view pointer unexpectedly null.";
}
if (!needScissoredClear && !needMaskedStencilClear) if (!needScissoredClear && !needMaskedStencilClear)
{ {
UINT clearFlags = (clearParams.clearDepth ? D3D11_CLEAR_DEPTH : 0) | const UINT clearFlags = (clearParams.clearDepth ? D3D11_CLEAR_DEPTH : 0) |
(clearParams.clearStencil ? D3D11_CLEAR_STENCIL : 0); (clearParams.clearStencil ? D3D11_CLEAR_STENCIL : 0);
FLOAT depthClear = gl::clamp01(clearParams.depthClearValue); const FLOAT depthClear = gl::clamp01(clearParams.depthClearValue);
UINT8 stencilClear = clearParams.stencilClearValue & 0xFF; const UINT8 stencilClear = clearParams.stencilClearValue & 0xFF;
deviceContext->ClearDepthStencilView(dsv, clearFlags, depthClear, stencilClear); deviceContext->ClearDepthStencilView(dsv, clearFlags, depthClear, stencilClear);
...@@ -473,7 +461,6 @@ gl::Error Clear11::clearFramebuffer(const ClearParameters &clearParams, ...@@ -473,7 +461,6 @@ gl::Error Clear11::clearFramebuffer(const ClearParameters &clearParams,
ASSERT(numRtvs <= mRenderer->getNativeCaps().maxDrawBuffers); ASSERT(numRtvs <= mRenderer->getNativeCaps().maxDrawBuffers);
const UINT sampleMask = 0xFFFFFFFF; const UINT sampleMask = 0xFFFFFFFF;
const float blendFactors[4] = {1.0f, 1.0f, 1.0f, 1.0f};
ID3D11BlendState *blendState = nullptr; ID3D11BlendState *blendState = nullptr;
if (numRtvs > 0) if (numRtvs > 0)
...@@ -508,38 +495,32 @@ gl::Error Clear11::clearFramebuffer(const ClearParameters &clearParams, ...@@ -508,38 +495,32 @@ gl::Error Clear11::clearFramebuffer(const ClearParameters &clearParams,
} }
// Set the vertices // Set the vertices
UINT vertexStride = 0;
const UINT startIdx = 0;
ClearShader *shader = nullptr; ClearShader *shader = nullptr;
D3D11_MAPPED_SUBRESOURCE mappedResource; D3D11_MAPPED_SUBRESOURCE mappedResource;
HRESULT result = HRESULT result =
deviceContext->Map(mVertexBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource); deviceContext->Map(mVertexBuffer.Get(), 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);
if (FAILED(result)) if (FAILED(result))
{ {
return gl::OutOfMemory() << "Clear11: Failed to map internal VB, " << result; return gl::OutOfMemory() << "Clear11: Failed to map internal VB, " << result;
} }
const gl::Rectangle *scissorPtr = clearParams.scissorEnabled ? &clearParams.scissor : nullptr;
switch (clearParams.colorClearType) switch (clearParams.colorClearType)
{ {
case GL_FLOAT: case GL_FLOAT:
ApplyVertices(framebufferSize, scissorPtr, clearParams.colorFClearValue, ApplyVertices(clearParams.colorFClearValue, clearParams.depthClearValue,
clearParams.depthClearValue, mappedResource.pData); mappedResource.pData);
vertexStride = sizeof(d3d11::PositionDepthColorVertex<float>);
shader = mFloatClearShader; shader = mFloatClearShader;
break; break;
case GL_UNSIGNED_INT: case GL_UNSIGNED_INT:
ApplyVertices(framebufferSize, scissorPtr, clearParams.colorUIClearValue, ApplyVertices(clearParams.colorUIClearValue, clearParams.depthClearValue,
clearParams.depthClearValue, mappedResource.pData); mappedResource.pData);
vertexStride = sizeof(d3d11::PositionDepthColorVertex<unsigned int>);
shader = mUintClearShader; shader = mUintClearShader;
break; break;
case GL_INT: case GL_INT:
ApplyVertices(framebufferSize, scissorPtr, clearParams.colorIClearValue, ApplyVertices(clearParams.colorIClearValue, clearParams.depthClearValue,
clearParams.depthClearValue, mappedResource.pData); mappedResource.pData);
vertexStride = sizeof(d3d11::PositionDepthColorVertex<int>);
shader = mIntClearShader; shader = mIntClearShader;
break; break;
...@@ -548,7 +529,7 @@ gl::Error Clear11::clearFramebuffer(const ClearParameters &clearParams, ...@@ -548,7 +529,7 @@ gl::Error Clear11::clearFramebuffer(const ClearParameters &clearParams,
break; break;
} }
deviceContext->Unmap(mVertexBuffer, 0); deviceContext->Unmap(mVertexBuffer.Get(), 0);
// Set the viewport to be the same size as the framebuffer // Set the viewport to be the same size as the framebuffer
D3D11_VIEWPORT viewport; D3D11_VIEWPORT viewport;
...@@ -561,18 +542,31 @@ gl::Error Clear11::clearFramebuffer(const ClearParameters &clearParams, ...@@ -561,18 +542,31 @@ gl::Error Clear11::clearFramebuffer(const ClearParameters &clearParams,
deviceContext->RSSetViewports(1, &viewport); deviceContext->RSSetViewports(1, &viewport);
// Apply state // Apply state
deviceContext->RSSetState(mRasterizerState); deviceContext->OMSetBlendState(blendState, nullptr, sampleMask);
deviceContext->OMSetBlendState(blendState, blendFactors, sampleMask);
deviceContext->OMSetDepthStencilState(dsState, stencilValue); deviceContext->OMSetDepthStencilState(dsState, stencilValue);
if (needScissoredClear)
{
const D3D11_RECT scissorRect = {clearParams.scissor.x, clearParams.scissor.y,
clearParams.scissor.x1(), clearParams.scissor.y1()};
deviceContext->RSSetScissorRects(1, &scissorRect);
deviceContext->RSSetState(mScissorEnabledRasterizerState.Get());
}
else
{
deviceContext->RSSetState(mScissorDisabledRasterizerState.Get());
}
// Apply shaders // Apply shaders
ID3D11Device *device = mRenderer->getDevice();
deviceContext->IASetInputLayout(shader->inputLayout->resolve(device)); deviceContext->IASetInputLayout(shader->inputLayout->resolve(device));
deviceContext->VSSetShader(shader->vertexShader.resolve(device), nullptr, 0); deviceContext->VSSetShader(shader->vertexShader.resolve(device), nullptr, 0);
deviceContext->PSSetShader(shader->pixelShader.resolve(device), nullptr, 0); deviceContext->PSSetShader(shader->pixelShader.resolve(device), nullptr, 0);
deviceContext->GSSetShader(nullptr, nullptr, 0); deviceContext->GSSetShader(nullptr, nullptr, 0);
// Apply vertex buffer // Apply vertex buffer
deviceContext->IASetVertexBuffers(0, 1, &mVertexBuffer, &vertexStride, &startIdx); const UINT offset = 0;
deviceContext->IASetVertexBuffers(0, 1, mVertexBuffer.GetAddressOf(), &g_VertexSize, &offset);
deviceContext->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP); deviceContext->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
// Apply render targets // Apply render targets
......
...@@ -63,16 +63,17 @@ class Clear11 : angle::NonCopyable ...@@ -63,16 +63,17 @@ class Clear11 : angle::NonCopyable
Renderer11 *mRenderer; Renderer11 *mRenderer;
// Cached cache Keys // States
angle::ComPtr<ID3D11RasterizerState> mScissorEnabledRasterizerState;
angle::ComPtr<ID3D11RasterizerState> mScissorDisabledRasterizerState;
gl::DepthStencilState mDepthStencilStateKey; gl::DepthStencilState mDepthStencilStateKey;
d3d11::BlendStateKey mBlendStateKey; d3d11::BlendStateKey mBlendStateKey;
// Shaders and Shader Resources
ClearShader *mFloatClearShader; ClearShader *mFloatClearShader;
ClearShader *mUintClearShader; ClearShader *mUintClearShader;
ClearShader *mIntClearShader; ClearShader *mIntClearShader;
angle::ComPtr<ID3D11Buffer> mVertexBuffer;
ID3D11Buffer *mVertexBuffer;
ID3D11RasterizerState *mRasterizerState;
}; };
} }
......
...@@ -170,11 +170,13 @@ gl::Error RenderStateCache::getBlendState(const d3d11::BlendStateKey &key, ...@@ -170,11 +170,13 @@ gl::Error RenderStateCache::getBlendState(const d3d11::BlendStateKey &key,
// 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;
D3D11_RENDER_TARGET_BLEND_DESC &rtDesc0 = blendDesc.RenderTarget[0]; D3D11_RENDER_TARGET_BLEND_DESC &rtDesc0 = blendDesc.RenderTarget[0];
rtDesc0 = {};
const gl::BlendState &blendState = key.blendState; const gl::BlendState &blendState = key.blendState;
blendDesc.AlphaToCoverageEnable = blendState.sampleAlphaToCoverage; blendDesc.AlphaToCoverageEnable = blendState.sampleAlphaToCoverage;
blendDesc.IndependentBlendEnable = key.mrt ? TRUE : FALSE; blendDesc.IndependentBlendEnable = key.mrt ? TRUE : FALSE;
rtDesc0 = {};
if (blendState.blend) if (blendState.blend)
{ {
rtDesc0.BlendEnable = true; rtDesc0.BlendEnable = true;
......
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