@@ -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+
13731414angle::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+
14351507void 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
0 commit comments