From: Alexis Hetu Date: Wed, 16 Jan 2019 20:47:19 +0000 (-0500) Subject: Allow clearing image arrays in ImageView X-Git-Tag: android-x86-9.0-r1~437 X-Git-Url: http://git.osdn.net/view?a=commitdiff_plain;h=ed30373d288595486116e9fa65dbffa4a0813bde;p=android-x86%2Fexternal-swiftshader.git 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 Reviewed-by: Chris Forbes --- diff --git a/src/Vulkan/VkImage.cpp b/src/Vulkan/VkImage.cpp index 03106158c..a25d2e4be 100644 --- a/src/Vulkan/VkImage.cpp +++ b/src/Vulkan/VkImage.cpp @@ -279,7 +279,7 @@ int Image::rowPitchBytes(const VkImageAspectFlags& flags) const // 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 @@ int Image::slicePitchBytes(const VkImageAspectFlags& flags) const // 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 @@ VkFormat Image::getFormat(const VkImageAspectFlags& flags) const 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 cfcd379de..93425542d 100644 --- a/src/Vulkan/VkImage.hpp +++ b/src/Vulkan/VkImage.hpp @@ -47,6 +47,8 @@ public: 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 @@ private: 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 746def5f6..e2c211366 100644 --- a/src/Vulkan/VkImageView.cpp +++ b/src/Vulkan/VkImageView.cpp @@ -19,7 +19,7 @@ namespace vk { 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 @@ void ImageView::destroy(const VkAllocationCallbacks* pAllocator) { } +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 06da79943..cdc3896f9 100644 --- a/src/Vulkan/VkImageView.hpp +++ b/src/Vulkan/VkImageView.hpp @@ -34,7 +34,9 @@ public: 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 = {};