Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit d705f18

Browse files
null77Commit Bot
authored andcommitted
Vulkan: Add immediate scissored clears.
This allows us to avoid using draw commands with pipelines for scissored clears. This prevents some tests from generating large numbers of VkPipelines. Bug: angleproject:4517 Bug: angleproject:4617 Change-Id: Id4a44000078098a60aa89233cfef30b75727d108 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2194473 Commit-Queue: Jamie Madill <[email protected]> Reviewed-by: Tim Van Patten <[email protected]>
1 parent 69e4694 commit d705f18

File tree

3 files changed

+95
-35
lines changed

3 files changed

+95
-35
lines changed

src/libANGLE/renderer/vulkan/FramebufferVk.cpp

Lines changed: 80 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -275,7 +275,7 @@ angle::Result FramebufferVk::clearImpl(const gl::Context *context,
275275
// there's a depth mask, depth clearing is already disabled.
276276
bool maskedClearColor =
277277
clearColor && (mActiveColorComponents & colorMaskFlags) != mActiveColorComponents;
278-
bool maskedClearStencil = stencilMask != 0xFF;
278+
bool maskedClearStencil = clearStencil && stencilMask != 0xFF;
279279

280280
bool clearColorWithRenderPassLoadOp = clearColor && !maskedClearColor && !scissoredClear;
281281
bool clearDepthWithRenderPassLoadOp = clearDepth && !scissoredClear;
@@ -325,6 +325,13 @@ angle::Result FramebufferVk::clearImpl(const gl::Context *context,
325325
}
326326
}
327327

328+
if (scissoredClear && !maskedClearColor && !maskedClearStencil)
329+
{
330+
return clearImmediatelyWithRenderPassOp(contextVk, scissoredRenderArea, clearColorBuffers,
331+
clearDepth, clearStencil, clearColorValue,
332+
clearDepthStencilValue);
333+
}
334+
328335
// The most costly clear mode is when we need to mask out specific color channels or stencil
329336
// bits. This can only be done with a draw call.
330337
return clearWithDraw(contextVk, scissoredRenderArea, clearColorBuffers, clearDepth,
@@ -1370,6 +1377,40 @@ angle::Result FramebufferVk::getFramebuffer(ContextVk *contextVk, vk::Framebuffe
13701377
return angle::Result::Continue;
13711378
}
13721379

1380+
angle::Result FramebufferVk::clearImmediatelyWithRenderPassOp(
1381+
ContextVk *contextVk,
1382+
const gl::Rectangle &clearArea,
1383+
gl::DrawBufferMask clearColorBuffers,
1384+
bool clearDepth,
1385+
bool clearStencil,
1386+
const VkClearColorValue &clearColorValue,
1387+
const VkClearDepthStencilValue &clearDepthStencilValue)
1388+
{
1389+
for (size_t colorIndexGL : clearColorBuffers)
1390+
{
1391+
VkClearValue clearValue = getCorrectedColorClearValue(colorIndexGL, clearColorValue);
1392+
mDeferredClears.store(static_cast<uint32_t>(colorIndexGL), VK_IMAGE_ASPECT_COLOR_BIT,
1393+
clearValue);
1394+
}
1395+
1396+
if (clearDepth)
1397+
{
1398+
VkClearValue clearValue;
1399+
clearValue.depthStencil = clearDepthStencilValue;
1400+
mDeferredClears.store(vk::kClearValueDepthIndex, VK_IMAGE_ASPECT_DEPTH_BIT, clearValue);
1401+
}
1402+
1403+
if (clearStencil)
1404+
{
1405+
VkClearValue clearValue;
1406+
clearValue.depthStencil = clearDepthStencilValue;
1407+
mDeferredClears.store(vk::kClearValueStencilIndex, VK_IMAGE_ASPECT_STENCIL_BIT, clearValue);
1408+
}
1409+
1410+
// Ensure the clear happens immediately.
1411+
return flushDeferredClears(contextVk, clearArea);
1412+
}
1413+
13731414
angle::Result FramebufferVk::clearWithDraw(ContextVk *contextVk,
13741415
const gl::Rectangle &clearArea,
13751416
gl::DrawBufferMask clearColorBuffers,
@@ -1386,11 +1427,8 @@ angle::Result FramebufferVk::clearWithDraw(ContextVk *contextVk,
13861427
clearValue.depthStencil = clearDepthStencilValue;
13871428
mDeferredClears.store(vk::kClearValueDepthIndex, VK_IMAGE_ASPECT_DEPTH_BIT, clearValue);
13881429

1389-
// Ensure the clear happens immediately.
1390-
if (clearColorBuffers.none() && !clearStencil)
1391-
{
1392-
return flushDeferredClears(contextVk, clearArea);
1393-
}
1430+
// Scissored-only clears are handled in clearImmediatelyWithRenderPassOp.
1431+
ASSERT(clearColorBuffers.any() || clearStencil);
13941432
}
13951433

13961434
UtilsVk::ClearFramebufferParameters params = {};
@@ -1432,6 +1470,40 @@ angle::Result FramebufferVk::clearWithDraw(ContextVk *contextVk,
14321470
return angle::Result::Continue;
14331471
}
14341472

1473+
VkClearValue FramebufferVk::getCorrectedColorClearValue(size_t colorIndexGL,
1474+
const VkClearColorValue &clearColor) const
1475+
{
1476+
VkClearValue clearValue;
1477+
clearValue.color = clearColor;
1478+
1479+
if (!mEmulatedAlphaAttachmentMask[colorIndexGL])
1480+
{
1481+
return clearValue;
1482+
}
1483+
1484+
// If the render target doesn't have alpha, but its emulated format has it, clear the alpha
1485+
// to 1.
1486+
RenderTargetVk *renderTarget = getColorDrawRenderTarget(colorIndexGL);
1487+
const vk::Format &format = renderTarget->getImageFormat();
1488+
if (format.vkFormatIsInt)
1489+
{
1490+
if (format.vkFormatIsUnsigned)
1491+
{
1492+
clearValue.color.uint32[3] = kEmulatedAlphaValue;
1493+
}
1494+
else
1495+
{
1496+
clearValue.color.int32[3] = kEmulatedAlphaValue;
1497+
}
1498+
}
1499+
else
1500+
{
1501+
clearValue.color.float32[3] = kEmulatedAlphaValue;
1502+
}
1503+
1504+
return clearValue;
1505+
}
1506+
14351507
void FramebufferVk::clearWithRenderPassOp(gl::DrawBufferMask clearColorBuffers,
14361508
bool clearDepth,
14371509
bool clearStencil,
@@ -1443,33 +1515,8 @@ void FramebufferVk::clearWithRenderPassOp(gl::DrawBufferMask clearColorBuffers,
14431515
{
14441516
ASSERT(mState.getEnabledDrawBuffers().test(colorIndexGL));
14451517
RenderTargetVk *renderTarget = getColorDrawRenderTarget(colorIndexGL);
1446-
1447-
VkClearValue clearValue;
1448-
clearValue.color = clearColorValue;
1449-
1450-
// If the render target doesn't have alpha, but its emulated format has it, clear the
1451-
// alpha to 1.
1452-
if (mEmulatedAlphaAttachmentMask[colorIndexGL])
1453-
{
1454-
const vk::Format &format = renderTarget->getImageFormat();
1455-
if (format.vkFormatIsInt)
1456-
{
1457-
if (format.vkFormatIsUnsigned)
1458-
{
1459-
clearValue.color.uint32[3] = kEmulatedAlphaValue;
1460-
}
1461-
else
1462-
{
1463-
clearValue.color.int32[3] = kEmulatedAlphaValue;
1464-
}
1465-
}
1466-
else
1467-
{
1468-
clearValue.color.float32[3] = kEmulatedAlphaValue;
1469-
}
1470-
}
1471-
1472-
gl::ImageIndex imageIndex = renderTarget->getImageIndex();
1518+
VkClearValue clearValue = getCorrectedColorClearValue(colorIndexGL, clearColorValue);
1519+
gl::ImageIndex imageIndex = renderTarget->getImageIndex();
14731520
renderTarget->getImage().stageClear(imageIndex, VK_IMAGE_ASPECT_COLOR_BIT, clearValue);
14741521
}
14751522

src/libANGLE/renderer/vulkan/FramebufferVk.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,16 @@ class FramebufferVk : public FramebufferImpl
157157
bool clearStencil,
158158
const VkClearColorValue &clearColorValue,
159159
const VkClearDepthStencilValue &clearDepthStencilValue);
160+
161+
angle::Result clearImmediatelyWithRenderPassOp(
162+
ContextVk *contextVk,
163+
const gl::Rectangle &clearArea,
164+
gl::DrawBufferMask clearColorBuffers,
165+
bool clearDepth,
166+
bool clearStencil,
167+
const VkClearColorValue &clearColorValue,
168+
const VkClearDepthStencilValue &clearDepthStencilValue);
169+
160170
angle::Result clearWithDraw(ContextVk *contextVk,
161171
const gl::Rectangle &clearArea,
162172
gl::DrawBufferMask clearColorBuffers,
@@ -186,6 +196,8 @@ class FramebufferVk : public FramebufferImpl
186196
VkImageAspectFlagBits getReadPixelsAspectFlags(GLenum format) const;
187197

188198
angle::Result flushDeferredClears(ContextVk *contextVk, const gl::Rectangle &renderArea);
199+
VkClearValue getCorrectedColorClearValue(size_t colorIndexGL,
200+
const VkClearColorValue &clearColor) const;
189201

190202
WindowSurfaceVk *mBackbuffer;
191203

src/libANGLE/renderer/vulkan/vk_utils.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -701,8 +701,9 @@ void ClearValuesArray::store(uint32_t index,
701701
// We do this double if to handle the packed depth-stencil case.
702702
if ((aspectFlags & VK_IMAGE_ASPECT_STENCIL_BIT) != 0)
703703
{
704-
// Special case for stencil.
705-
ASSERT(index == kClearValueDepthIndex);
704+
// Ensure for packed DS we're writing to the depth index.
705+
ASSERT(index == kClearValueDepthIndex ||
706+
(index == kClearValueStencilIndex && aspectFlags == VK_IMAGE_ASPECT_STENCIL_BIT));
706707
mValues[kClearValueStencilIndex] = clearValue;
707708
mEnabled.set(kClearValueStencilIndex);
708709
}

0 commit comments

Comments
 (0)