Commit 7e01e4e0 by Nicolas Capens Committed by Nicolas Capens

Support images with linear tiling for transfers

The Vulkan 1.1 spec on vkCreateImage states that "Creation of images with tiling VK_IMAGE_TILING_LINEAR may not be supported unless other parameters meet all of the constraints: * imageType is VK_IMAGE_TYPE_2D * format is not a depth/stencil format * mipLevels is 1 * arrayLayers is 1 * samples is VK_SAMPLE_COUNT_1_BIT * usage only includes VK_IMAGE_USAGE_TRANSFER_SRC_BIT and/or VK_IMAGE_USAGE_TRANSFER_DST_BIT" Also restrict YCbCr image creation in accordance with: "Creation of images with a format requiring Y’CBCR conversion may not be supported unless other parameters meet all of the constraints: * imageType is VK_IMAGE_TYPE_2D * mipLevels is 1 * arrayLayers is 1 * samples is VK_SAMPLE_COUNT_1_BIT" Bug: b/119620767 Bug: b/132437008 Tests: dEQP-VK.*ycbcr* Change-Id: I909fda2a154e69fbd4afb862cf4cc14c244005bf Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/31788Tested-by: 's avatarNicolas Capens <nicolascapens@google.com> Kokoro-Presubmit: kokoro <noreply+kokoro@google.com> Reviewed-by: 's avatarChris Forbes <chrisforbes@google.com> Reviewed-by: 's avatarAlexis Hétu <sugoi@google.com>
parent 51e9e565
......@@ -111,11 +111,15 @@ void Image::getSubresourceLayout(const VkImageSubresource* pSubresource, VkSubre
{
// By spec, aspectMask has a single bit set.
if (!((pSubresource->aspectMask == VK_IMAGE_ASPECT_COLOR_BIT) ||
(pSubresource->aspectMask == VK_IMAGE_ASPECT_DEPTH_BIT) ||
(pSubresource->aspectMask == VK_IMAGE_ASPECT_STENCIL_BIT)))
(pSubresource->aspectMask == VK_IMAGE_ASPECT_DEPTH_BIT) ||
(pSubresource->aspectMask == VK_IMAGE_ASPECT_STENCIL_BIT) ||
(pSubresource->aspectMask == VK_IMAGE_ASPECT_PLANE_0_BIT) ||
(pSubresource->aspectMask == VK_IMAGE_ASPECT_PLANE_1_BIT) ||
(pSubresource->aspectMask == VK_IMAGE_ASPECT_PLANE_2_BIT)))
{
UNIMPLEMENTED("aspectMask");
UNSUPPORTED("aspectMask %X", pSubresource->aspectMask);
}
auto aspect = static_cast<VkImageAspectFlagBits>(pSubresource->aspectMask);
pLayout->offset = getMemoryOffset(aspect, pSubresource->mipLevel, pSubresource->arrayLayer);
pLayout->size = getMultiSampledLevelSize(aspect, pSubresource->mipLevel);
......@@ -130,18 +134,24 @@ void Image::copyTo(VkImage dstImage, const VkImageCopy& pRegion)
// an image to another image that has the same number of bytes per pixel.
Image* dst = Cast(dstImage);
if(!((pRegion.srcSubresource.aspectMask == VK_IMAGE_ASPECT_COLOR_BIT) ||
(pRegion.srcSubresource.aspectMask == VK_IMAGE_ASPECT_DEPTH_BIT) ||
(pRegion.srcSubresource.aspectMask == VK_IMAGE_ASPECT_STENCIL_BIT)))
if (!((pRegion.srcSubresource.aspectMask == VK_IMAGE_ASPECT_COLOR_BIT) ||
(pRegion.srcSubresource.aspectMask == VK_IMAGE_ASPECT_DEPTH_BIT) ||
(pRegion.srcSubresource.aspectMask == VK_IMAGE_ASPECT_STENCIL_BIT) ||
(pRegion.srcSubresource.aspectMask == VK_IMAGE_ASPECT_PLANE_0_BIT) ||
(pRegion.srcSubresource.aspectMask == VK_IMAGE_ASPECT_PLANE_1_BIT) ||
(pRegion.srcSubresource.aspectMask == VK_IMAGE_ASPECT_PLANE_2_BIT)))
{
UNIMPLEMENTED("srcSubresource");
UNSUPPORTED("srcSubresource.aspectMask %X", pRegion.srcSubresource.aspectMask);
}
if(!((pRegion.dstSubresource.aspectMask == VK_IMAGE_ASPECT_COLOR_BIT) ||
(pRegion.dstSubresource.aspectMask == VK_IMAGE_ASPECT_DEPTH_BIT) ||
(pRegion.dstSubresource.aspectMask == VK_IMAGE_ASPECT_STENCIL_BIT)))
if (!((pRegion.dstSubresource.aspectMask == VK_IMAGE_ASPECT_COLOR_BIT) ||
(pRegion.dstSubresource.aspectMask == VK_IMAGE_ASPECT_DEPTH_BIT) ||
(pRegion.dstSubresource.aspectMask == VK_IMAGE_ASPECT_STENCIL_BIT) ||
(pRegion.dstSubresource.aspectMask == VK_IMAGE_ASPECT_PLANE_0_BIT) ||
(pRegion.dstSubresource.aspectMask == VK_IMAGE_ASPECT_PLANE_1_BIT) ||
(pRegion.dstSubresource.aspectMask == VK_IMAGE_ASPECT_PLANE_2_BIT)))
{
UNIMPLEMENTED("dstSubresource");
UNSUPPORTED("dstSubresource.aspectMask %X", pRegion.dstSubresource.aspectMask);
}
VkImageAspectFlagBits srcAspect = static_cast<VkImageAspectFlagBits>(pRegion.srcSubresource.aspectMask);
......@@ -510,9 +520,9 @@ VkExtent3D Image::getMipLevelExtent(VkImageAspectFlagBits aspect, uint32_t mipLe
mipLevelExtent.height = extent.height >> mipLevel;
mipLevelExtent.depth = extent.depth >> mipLevel;
if(mipLevelExtent.width == 0) mipLevelExtent.width = 1;
if(mipLevelExtent.height == 0) mipLevelExtent.height = 1;
if(mipLevelExtent.depth == 0) mipLevelExtent.depth = 1;
if(mipLevelExtent.width == 0) { mipLevelExtent.width = 1; }
if(mipLevelExtent.height == 0) { mipLevelExtent.height = 1; }
if(mipLevelExtent.depth == 0) { mipLevelExtent.depth = 1; }
switch(aspect)
{
......
......@@ -375,7 +375,7 @@ bool PhysicalDevice::hasFeatures(const VkPhysicalDeviceFeatures& requestedFeatur
return true;
}
void PhysicalDevice::getFormatProperties(VkFormat format, VkFormatProperties* pFormatProperties) const
void PhysicalDevice::getFormatProperties(Format format, VkFormatProperties* pFormatProperties) const
{
pFormatProperties->linearTilingFeatures = 0; // Unsupported format
pFormatProperties->optimalTilingFeatures = 0; // Unsupported format
......@@ -660,11 +660,17 @@ void PhysicalDevice::getFormatProperties(VkFormat format, VkFormatProperties* pF
default:
break;
}
if(pFormatProperties->optimalTilingFeatures)
{
pFormatProperties->linearTilingFeatures = VK_FORMAT_FEATURE_TRANSFER_SRC_BIT |
VK_FORMAT_FEATURE_TRANSFER_DST_BIT;
}
}
void PhysicalDevice::getImageFormatProperties(VkFormat format, VkImageType type, VkImageTiling tiling,
void PhysicalDevice::getImageFormatProperties(Format format, VkImageType type, VkImageTiling tiling,
VkImageUsageFlags usage, VkImageCreateFlags flags,
VkImageFormatProperties* pImageFormatProperties) const
VkImageFormatProperties* pImageFormatProperties) const
{
pImageFormatProperties->sampleCounts = VK_SAMPLE_COUNT_1_BIT;
pImageFormatProperties->maxArrayLayers = vk::MAX_IMAGE_ARRAY_LAYERS;
......@@ -713,6 +719,24 @@ void PhysicalDevice::getImageFormatProperties(VkFormat format, VkImageType type,
}
pImageFormatProperties->maxResourceSize = 1 << 31; // Minimum value for maxResourceSize
// "Images created with tiling equal to VK_IMAGE_TILING_LINEAR have further restrictions on their limits and capabilities
// compared to images created with tiling equal to VK_IMAGE_TILING_OPTIMAL."
if(tiling == VK_IMAGE_TILING_LINEAR)
{
pImageFormatProperties->maxMipLevels = 1;
pImageFormatProperties->maxArrayLayers = 1;
pImageFormatProperties->sampleCounts = VK_SAMPLE_COUNT_1_BIT;
}
// "Images created with a format from one of those listed in Formats requiring sampler YCBCR conversion for VK_IMAGE_ASPECT_COLOR_BIT image views
// have further restrictions on their limits and capabilities compared to images created with other formats."
if(format.isYcbcrFormat())
{
pImageFormatProperties->maxMipLevels = 1;
pImageFormatProperties->maxArrayLayers = 1;
pImageFormatProperties->sampleCounts = VK_SAMPLE_COUNT_1_BIT;
}
}
uint32_t PhysicalDevice::getQueueFamilyPropertyCount() const
......
......@@ -16,6 +16,7 @@
#define VK_PHYSICAL_DEVICE_HPP_
#include "VkObject.hpp"
#include "VkFormat.h"
#ifdef VK_USE_PLATFORM_ANDROID_KHR
#include <vulkan/vk_android_native_buffer.h>
......@@ -60,8 +61,8 @@ public:
void getProperties(const VkPhysicalDeviceExternalFenceInfo* pExternalFenceInfo, VkExternalFenceProperties* pExternalFenceProperties) const;
void getProperties(const VkPhysicalDeviceExternalSemaphoreInfo* pExternalSemaphoreInfo, VkExternalSemaphoreProperties* pExternalSemaphoreProperties) const;
void getFormatProperties(VkFormat format, VkFormatProperties* pFormatProperties) const;
void getImageFormatProperties(VkFormat format, VkImageType type, VkImageTiling tiling,
void getFormatProperties(Format format, VkFormatProperties* pFormatProperties) const;
void getImageFormatProperties(Format format, VkImageType type, VkImageTiling tiling,
VkImageUsageFlags usage, VkImageCreateFlags flags,
VkImageFormatProperties* pImageFormatProperties) const;
uint32_t getQueueFamilyPropertyCount() const;
......
......@@ -232,6 +232,10 @@ VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceImageFormatProperties(VkPhysic
TRACE("(VkPhysicalDevice physicalDevice = %p, VkFormat format = %d, VkImageType type = %d, VkImageTiling tiling = %d, VkImageUsageFlags usage = %d, VkImageCreateFlags flags = %d, VkImageFormatProperties* pImageFormatProperties = %p)",
physicalDevice, (int)format, (int)type, (int)tiling, usage, flags, pImageFormatProperties);
// "If the combination of parameters to vkGetPhysicalDeviceImageFormatProperties is not supported by the implementation
// for use in vkCreateImage, then all members of VkImageFormatProperties will be filled with zero."
memset(pImageFormatProperties, 0, sizeof(VkImageFormatProperties));
VkFormatProperties properties;
vk::Cast(physicalDevice)->getFormatProperties(format, &properties);
......@@ -302,6 +306,31 @@ VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceImageFormatProperties(VkPhysic
VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT;
ASSERT(!(usage & ~(allRecognizedUsageBits)));
// "Images created with tiling equal to VK_IMAGE_TILING_LINEAR have further restrictions on their limits and capabilities
// compared to images created with tiling equal to VK_IMAGE_TILING_OPTIMAL."
if(tiling == VK_IMAGE_TILING_LINEAR)
{
if(type != VK_IMAGE_TYPE_2D)
{
return VK_ERROR_FORMAT_NOT_SUPPORTED;
}
if(vk::Format(format).isDepth() || vk::Format(format).isStencil())
{
return VK_ERROR_FORMAT_NOT_SUPPORTED;
}
}
// "Images created with a format from one of those listed in Formats requiring sampler YCBCR conversion for VK_IMAGE_ASPECT_COLOR_BIT image views
// have further restrictions on their limits and capabilities compared to images created with other formats."
if(vk::Format(format).isYcbcrFormat())
{
if(type != VK_IMAGE_TYPE_2D)
{
return VK_ERROR_FORMAT_NOT_SUPPORTED;
}
}
vk::Cast(physicalDevice)->getImageFormatProperties(format, type, tiling, usage, flags, pImageFormatProperties);
return VK_SUCCESS;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment