Implementation of partial clear
Implemented subregion clears.
The quad layout had to be disabled to depth/stencil textures,
as it was not expected by dEQP.
Passes all tests in api.image_clearing.dedicated_allocation.
- partial_clear_color_attachment.*
- partial_clear_depth_stencil_attachment.*
Bug b/119621736
Change-Id: I9e854eceeef4a72b2ae507d62dbdbfa0b56c96f3
Reviewed-on: https://swiftshader-review.googlesource.com/c/23829
Tested-by: Alexis Hétu <sugoi@google.com>
Reviewed-by: Chris Forbes <chrisforbes@google.com>
Reviewed-by: Corentin Wallez <cwallez@google.com>
diff --git a/src/Device/Surface.cpp b/src/Device/Surface.cpp
index 0da1282..b367ec5 100644
--- a/src/Device/Surface.cpp
+++ b/src/Device/Surface.cpp
@@ -1995,20 +1995,6 @@
bool Surface::hasQuadLayout(VkFormat format)
{
- switch(format)
- {
- case VK_FORMAT_D16_UNORM:
- case VK_FORMAT_X8_D24_UNORM_PACK32:
- case VK_FORMAT_D32_SFLOAT:
- case VK_FORMAT_S8_UINT:
- case VK_FORMAT_D16_UNORM_S8_UINT:
- case VK_FORMAT_D24_UNORM_S8_UINT:
- case VK_FORMAT_D32_SFLOAT_S8_UINT:
- return true;
- default:
- break;
- }
-
return false;
}
diff --git a/src/Vulkan/VkImage.cpp b/src/Vulkan/VkImage.cpp
index 89887a4..9278161 100644
--- a/src/Vulkan/VkImage.cpp
+++ b/src/Vulkan/VkImage.cpp
@@ -532,6 +532,32 @@
}
}
+void Image::clear(void* pixelData, VkFormat format, const VkRect2D& renderArea, const VkImageSubresourceRange& subresourceRange, VkImageAspectFlags aspectMask)
+{
+ if((subresourceRange.baseMipLevel != 0) ||
+ (subresourceRange.levelCount != 1))
+ {
+ UNIMPLEMENTED();
+ }
+
+ sw::SliceRect dRect(renderArea.offset.x, renderArea.offset.y,
+ renderArea.offset.x + renderArea.extent.width,
+ renderArea.offset.y + renderArea.extent.height, 0);
+
+ uint32_t firstLayer = subresourceRange.baseArrayLayer;
+ uint32_t lastLayer = getLastLayerIndex(subresourceRange);
+ for(uint32_t layer = firstLayer; layer <= lastLayer; ++layer)
+ {
+ for(uint32_t s = 0; s < extent.depth; ++s)
+ {
+ dRect.slice = s;
+ sw::Surface* surface = asSurface(aspectMask, 0, layer);
+ blitter->clear(pixelData, format, surface, dRect, 0xF);
+ delete surface;
+ }
+ }
+}
+
void Image::clear(const VkClearColorValue& color, const VkImageSubresourceRange& subresourceRange)
{
if(!(subresourceRange.aspectMask == VK_IMAGE_ASPECT_COLOR_BIT))
@@ -567,22 +593,26 @@
(subresourceRange.aspectMask & (VK_IMAGE_ASPECT_DEPTH_BIT |
VK_IMAGE_ASPECT_STENCIL_BIT))) ||
(subresourceRange.baseMipLevel != 0) ||
- (subresourceRange.levelCount != 1) ||
- (renderArea.offset.x != 0) ||
- (renderArea.offset.y != 0) ||
- (renderArea.extent.width != extent.width) ||
- (renderArea.extent.height != extent.height))
+ (subresourceRange.levelCount != 1))
{
UNIMPLEMENTED();
}
if(subresourceRange.aspectMask == VK_IMAGE_ASPECT_COLOR_BIT)
{
- clear(clearValue.color, subresourceRange);
+ clear((void*)(clearValue.color.float32), getClearFormat(), renderArea, subresourceRange, VK_IMAGE_ASPECT_COLOR_BIT);
}
else
{
- clear(clearValue.depthStencil, subresourceRange);
+ if(subresourceRange.aspectMask & VK_IMAGE_ASPECT_DEPTH_BIT)
+ {
+ clear((void*)(&clearValue.depthStencil.depth), VK_FORMAT_D32_SFLOAT, renderArea, subresourceRange, VK_IMAGE_ASPECT_DEPTH_BIT);
+ }
+
+ if(subresourceRange.aspectMask & VK_IMAGE_ASPECT_STENCIL_BIT)
+ {
+ clear((void*)(&clearValue.depthStencil.stencil), VK_FORMAT_S8_UINT, renderArea, subresourceRange, VK_IMAGE_ASPECT_STENCIL_BIT);
+ }
}
}
diff --git a/src/Vulkan/VkImage.hpp b/src/Vulkan/VkImage.hpp
index badca58..eb8cc94 100644
--- a/src/Vulkan/VkImage.hpp
+++ b/src/Vulkan/VkImage.hpp
@@ -73,6 +73,7 @@
uint32_t getLastMipLevel(const VkImageSubresourceRange& subresourceRange) const;
VkFormat getClearFormat() const;
void clear(void* pixelData, VkFormat format, const VkImageSubresourceRange& subresourceRange, VkImageAspectFlags aspectMask);
+ void clear(void* pixelData, VkFormat format, const VkRect2D& renderArea, const VkImageSubresourceRange& subresourceRange, VkImageAspectFlags aspectMask);
sw::Surface* asSurface(const VkImageAspectFlags& flags, uint32_t mipLevel, uint32_t layer) const;
DeviceMemory* deviceMemory = nullptr;