Framebuffer clear assert fix
Respect loadOp when clearing attachments in beginRenderPass().
Bug b/119621736
Change-Id: Id9ad0f1ad9dc6116264782be3370c37c078d6846
Reviewed-on: https://swiftshader-review.googlesource.com/c/24050
Tested-by: Alexis Hétu <sugoi@google.com>
Reviewed-by: Chris Forbes <chrisforbes@google.com>
diff --git a/src/Vulkan/VkFramebuffer.cpp b/src/Vulkan/VkFramebuffer.cpp
index c7fd078..1adadce 100644
--- a/src/Vulkan/VkFramebuffer.cpp
+++ b/src/Vulkan/VkFramebuffer.cpp
@@ -15,6 +15,8 @@
#include "VkFramebuffer.hpp"
#include "VkImageView.hpp"
#include "VkRenderPass.hpp"
+#include "Device/Surface.hpp"
+#include <algorithm>
#include <memory.h>
namespace vk
@@ -38,11 +40,32 @@
void Framebuffer::clear(uint32_t clearValueCount, const VkClearValue* pClearValues, const VkRect2D& renderArea)
{
- ASSERT(clearValueCount >= attachmentCount);
+ ASSERT(attachmentCount == renderPass->getAttachmentCount());
- for(uint32_t i = 0; i < attachmentCount; i++)
+ const uint32_t count = std::min(clearValueCount, attachmentCount);
+ for(uint32_t i = 0; i < count; i++)
{
- attachments[i]->clear(pClearValues[i], renderArea);
+ const VkAttachmentDescription attachment = renderPass->getAttachment(i);
+ bool isDepth = sw::Surface::isDepth(attachment.format);
+ bool isStencil = sw::Surface::isStencil(attachment.format);
+
+ if(isDepth || isStencil)
+ {
+ bool clearDepth = (isDepth && (attachment.loadOp == VK_ATTACHMENT_LOAD_OP_CLEAR));
+ bool clearStencil = (isStencil && (attachment.stencilLoadOp == VK_ATTACHMENT_LOAD_OP_CLEAR));
+
+ if(clearDepth || clearStencil)
+ {
+ attachments[i]->clear(pClearValues[i],
+ (clearDepth ? VK_IMAGE_ASPECT_DEPTH_BIT : 0) |
+ (clearStencil ? VK_IMAGE_ASPECT_STENCIL_BIT : 0),
+ renderArea);
+ }
+ }
+ else if(attachment.loadOp == VK_ATTACHMENT_LOAD_OP_CLEAR)
+ {
+ attachments[i]->clear(pClearValues[i], VK_IMAGE_ASPECT_COLOR_BIT, renderArea);
+ }
}
}
diff --git a/src/Vulkan/VkImageView.cpp b/src/Vulkan/VkImageView.cpp
index 293c8d7..9dd1680 100644
--- a/src/Vulkan/VkImageView.cpp
+++ b/src/Vulkan/VkImageView.cpp
@@ -72,7 +72,7 @@
return false;
}
-void ImageView::clear(const VkClearValue& clearValue, const VkRect2D& renderArea)
+void ImageView::clear(const VkClearValue& clearValue, const VkImageAspectFlags aspectMask, const VkRect2D& renderArea)
{
// Note: clearing ignores swizzling, so components is ignored.
@@ -86,6 +86,8 @@
UNIMPLEMENTED();
}
+ VkImageSubresourceRange sr = subresourceRange;
+ sr.aspectMask = aspectMask;
image->clear(clearValue, renderArea, subresourceRange);
}
diff --git a/src/Vulkan/VkImageView.hpp b/src/Vulkan/VkImageView.hpp
index d2a0124..26be628 100644
--- a/src/Vulkan/VkImageView.hpp
+++ b/src/Vulkan/VkImageView.hpp
@@ -31,7 +31,7 @@
static size_t ComputeRequiredAllocationSize(const VkImageViewCreateInfo* pCreateInfo);
- void clear(const VkClearValue& clearValues, const VkRect2D& renderArea);
+ void clear(const VkClearValue& clearValues, const VkImageAspectFlags aspectMask, const VkRect2D& renderArea);
void clear(const VkClearValue& clearValue, const VkImageAspectFlags aspectMask, const VkClearRect& renderArea);
private: