Allow clearing image arrays in ImageView
Allow an image of type VK_IMAGE_VIEW_TYPE_(?)D with multiple array
layers to count as VK_IMAGE_VIEW_TYPE_(X)D_ARRAY in ImageView.
Bug b/119620767
Change-Id: I2d6ba3d960c531949529d72f5347442bb53990d6
Reviewed-on: https://swiftshader-review.googlesource.com/c/23651
Tested-by: Alexis Hétu <sugoi@google.com>
Reviewed-by: Chris Forbes <chrisforbes@google.com>
diff --git a/src/Vulkan/VkImage.cpp b/src/Vulkan/VkImage.cpp
index 0310615..a25d2e4 100644
--- a/src/Vulkan/VkImage.cpp
+++ b/src/Vulkan/VkImage.cpp
@@ -279,7 +279,7 @@
// Depth and Stencil pitch should be computed separately
ASSERT((flags & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) !=
(VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT));
- return sw::Surface::pitchB(extent.width, getBorder(), getFormat(flags), false);
+ return sw::Surface::pitchB(extent.width, isCube() ? 1 : 0, getFormat(flags), false);
}
int Image::slicePitchBytes(const VkImageAspectFlags& flags) const
@@ -287,7 +287,7 @@
// Depth and Stencil slice should be computed separately
ASSERT((flags & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) !=
(VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT));
- return sw::Surface::sliceB(extent.width, extent.height, getBorder(), getFormat(flags), false);
+ return sw::Surface::sliceB(extent.width, extent.height, isCube() ? 1 : 0, getFormat(flags), false);
}
int Image::bytesPerTexel(const VkImageAspectFlags& flags) const
@@ -333,9 +333,9 @@
return format;
}
-int Image::getBorder() const
+bool Image::isCube() const
{
- return ((flags & VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT) && (imageType == VK_IMAGE_TYPE_2D)) ? 1 : 0;
+ return (flags & VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT) && (imageType == VK_IMAGE_TYPE_2D);
}
VkDeviceSize Image::getStorageSize(const VkImageAspectFlags& flags) const
diff --git a/src/Vulkan/VkImage.hpp b/src/Vulkan/VkImage.hpp
index cfcd379..9342554 100644
--- a/src/Vulkan/VkImage.hpp
+++ b/src/Vulkan/VkImage.hpp
@@ -47,6 +47,8 @@
VkImageType getImageType() const { return imageType; }
VkFormat getFormat() const { return format; }
+ uint32_t getArrayLayers() const { return arrayLayers; }
+ bool isCube() const;
private:
void copy(VkBuffer buffer, const VkBufferImageCopy& region, bool bufferIsSource);
@@ -58,7 +60,6 @@
int slicePitchBytes(const VkImageAspectFlags& flags) const;
int bytesPerTexel(const VkImageAspectFlags& flags) const;
VkFormat getFormat(const VkImageAspectFlags& flags) const;
- int getBorder() const;
sw::Surface* asSurface(const VkImageAspectFlags& flags) const;
DeviceMemory* deviceMemory = nullptr;
diff --git a/src/Vulkan/VkImageView.cpp b/src/Vulkan/VkImageView.cpp
index 746def5..e2c2113 100644
--- a/src/Vulkan/VkImageView.cpp
+++ b/src/Vulkan/VkImageView.cpp
@@ -19,7 +19,7 @@
{
ImageView::ImageView(const VkImageViewCreateInfo* pCreateInfo, void* mem) :
- image(pCreateInfo->image), viewType(pCreateInfo->viewType), format(pCreateInfo->format),
+ image(Cast(pCreateInfo->image)), viewType(pCreateInfo->viewType), format(pCreateInfo->format),
components(pCreateInfo->components), subresourceRange(pCreateInfo->subresourceRange)
{
}
@@ -33,23 +33,60 @@
{
}
+bool ImageView::imageTypesMatch(VkImageType imageType) const
+{
+ bool isCube = image->isCube();
+
+ switch(imageType)
+ {
+ case VK_IMAGE_TYPE_1D:
+ switch(viewType)
+ {
+ case VK_IMAGE_VIEW_TYPE_1D:
+ case VK_IMAGE_VIEW_TYPE_1D_ARRAY:
+ return true;
+ }
+ break;
+ case VK_IMAGE_TYPE_2D:
+ switch(viewType)
+ {
+ case VK_IMAGE_VIEW_TYPE_2D:
+ case VK_IMAGE_VIEW_TYPE_2D_ARRAY:
+ return !isCube;
+ case VK_IMAGE_VIEW_TYPE_CUBE:
+ case VK_IMAGE_VIEW_TYPE_CUBE_ARRAY:
+ return isCube;
+ }
+ break;
+ case VK_IMAGE_TYPE_3D:
+ switch(viewType)
+ {
+ case VK_IMAGE_VIEW_TYPE_3D:
+ return true;
+ }
+ break;
+ default:
+ break;
+ }
+
+ return false;
+}
+
void ImageView::clear(const VkClearValue& clearValue, const VkRect2D& renderArea)
{
// Note: clearing ignores swizzling, so components is ignored.
- auto imageObject = Cast(image);
-
- if(imageObject->getImageType() != viewType)
+ if(!imageTypesMatch(image->getImageType()))
{
UNIMPLEMENTED();
}
- if(imageObject->getFormat() != format)
+ if(image->getFormat() != format)
{
UNIMPLEMENTED();
}
- imageObject->clear(clearValue, renderArea, subresourceRange);
+ image->clear(clearValue, renderArea, subresourceRange);
}
}
\ No newline at end of file
diff --git a/src/Vulkan/VkImageView.hpp b/src/Vulkan/VkImageView.hpp
index 06da799..cdc3896 100644
--- a/src/Vulkan/VkImageView.hpp
+++ b/src/Vulkan/VkImageView.hpp
@@ -34,7 +34,9 @@
void clear(const VkClearValue& clearValues, const VkRect2D& renderArea);
private:
- VkImage image = VK_NULL_HANDLE;
+ bool imageTypesMatch(VkImageType imageType) const;
+
+ Image* image = nullptr;
VkImageViewType viewType = VK_IMAGE_VIEW_TYPE_2D;
VkFormat format = VK_FORMAT_UNDEFINED;
VkComponentMapping components = {};