Implement VK_EXT_separate_stencil_usage
This extension allows users to query and specify different usages for
the main image and the stencil. SwiftShader does not use an image's
usage for non-debug purposes outside of
vkGetPhysicalDeviceImageFormatProperties2. This applies to separate
stencil usage as well.
Bug: b/176098507
Tests: dEQP-VK.pipeline.sampler.separate_stencil_usage.*
Tests: dEQP-VK.renderpass.suballocation.multisample.separate_stencil_usage.*
Tests: dEQP-VK.renderpass2.suballocation.multisample.separate_stencil_usage.*
Change-Id: Iea74a9fa0de8cdcc51bdc613cdc0754e0f327fd5
Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/51368
Tested-by: Sean Risser <srisser@google.com>
Commit-Queue: Sean Risser <srisser@google.com>
Kokoro-Result: kokoro <noreply+kokoro@google.com>
Reviewed-by: Nicolas Capens <nicolascapens@google.com>
diff --git a/src/Vulkan/libVulkan.cpp b/src/Vulkan/libVulkan.cpp
index ba5981d..4fbbea1 100644
--- a/src/Vulkan/libVulkan.cpp
+++ b/src/Vulkan/libVulkan.cpp
@@ -404,6 +404,7 @@
#endif // SWIFTSHADER_DEVICE_MEMORY_REPORT
// Vulkan 1.2 promoted extensions
{ VK_EXT_SCALAR_BLOCK_LAYOUT_EXTENSION_NAME, VK_EXT_SCALAR_BLOCK_LAYOUT_SPEC_VERSION },
+ { VK_EXT_SEPARATE_STENCIL_USAGE_EXTENSION_NAME, VK_EXT_SEPARATE_STENCIL_USAGE_SPEC_VERSION },
{ VK_KHR_IMAGE_FORMAT_LIST_EXTENSION_NAME, VK_KHR_IMAGE_FORMAT_LIST_SPEC_VERSION },
{ VK_KHR_IMAGELESS_FRAMEBUFFER_EXTENSION_NAME, VK_KHR_IMAGELESS_FRAMEBUFFER_SPEC_VERSION },
{ VK_KHR_SHADER_FLOAT_CONTROLS_EXTENSION_NAME, VK_KHR_SHADER_FLOAT_CONTROLS_SPEC_VERSION },
@@ -1636,6 +1637,14 @@
// by the application. Swiftshader is not impacted from lacking this information,
// so we don't need to track the format list.
break;
+ case VK_STRUCTURE_TYPE_IMAGE_STENCIL_USAGE_CREATE_INFO:
+ {
+ // SwiftShader does not use an image's usage info for non-debug purposes outside of
+ // vkGetPhysicalDeviceImageFormatProperties2. This also applies to separate stencil usage.
+ const VkImageStencilUsageCreateInfo *stencilUsageInfo = reinterpret_cast<const VkImageStencilUsageCreateInfo *>(extensionCreateInfo);
+ (void)stencilUsageInfo->stencilUsage;
+ }
+ break;
default:
// "the [driver] must skip over, without processing (other than reading the sType and pNext members) any structures in the chain with sType values not defined by [supported extenions]"
LOG_TRAP("pCreateInfo->pNext sType = %s", vk::Stringify(extensionCreateInfo->sType).c_str());
@@ -3028,6 +3037,47 @@
vkGetPhysicalDeviceFormatProperties(physicalDevice, format, &(pFormatProperties->formatProperties));
}
+static bool checkFormatUsage(VkImageUsageFlags usage, VkFormatFeatureFlags features)
+{
+ // Check for usage conflict with features
+ if((usage & VK_IMAGE_USAGE_SAMPLED_BIT) && !(features & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT))
+ {
+ return false;
+ }
+
+ if((usage & VK_IMAGE_USAGE_STORAGE_BIT) && !(features & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT))
+ {
+ return false;
+ }
+
+ if((usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) && !(features & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT))
+ {
+ return false;
+ }
+
+ if((usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) && !(features & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT))
+ {
+ return false;
+ }
+
+ if((usage & VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT) && !(features & (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT)))
+ {
+ return false;
+ }
+
+ if((usage & VK_IMAGE_USAGE_TRANSFER_SRC_BIT) && !(features & VK_FORMAT_FEATURE_TRANSFER_SRC_BIT))
+ {
+ return false;
+ }
+
+ if((usage & VK_IMAGE_USAGE_TRANSFER_DST_BIT) && !(features & VK_FORMAT_FEATURE_TRANSFER_DST_BIT))
+ {
+ return false;
+ }
+
+ return true;
+}
+
VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceImageFormatProperties2(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceImageFormatInfo2 *pImageFormatInfo, VkImageFormatProperties2 *pImageFormatProperties)
{
TRACE("(VkPhysicalDevice physicalDevice = %p, const VkPhysicalDeviceImageFormatInfo2* pImageFormatInfo = %p, VkImageFormatProperties2* pImageFormatProperties = %p)",
@@ -3040,6 +3090,7 @@
const VkBaseInStructure *extensionFormatInfo = reinterpret_cast<const VkBaseInStructure *>(pImageFormatInfo->pNext);
const VkExternalMemoryHandleTypeFlagBits *handleType = nullptr;
+ VkImageUsageFlags stencilUsage = 0;
while(extensionFormatInfo)
{
switch(extensionFormatInfo->sType)
@@ -3050,10 +3101,10 @@
ASSERT(!hasDeviceExtension(VK_KHR_IMAGE_FORMAT_LIST_EXTENSION_NAME));
}
break;
- case VK_STRUCTURE_TYPE_IMAGE_STENCIL_USAGE_CREATE_INFO_EXT:
+ case VK_STRUCTURE_TYPE_IMAGE_STENCIL_USAGE_CREATE_INFO:
{
- // Explicitly ignored, since VK_EXT_separate_stencil_usage is not supported
- ASSERT(!hasDeviceExtension(VK_EXT_SEPARATE_STENCIL_USAGE_EXTENSION_NAME));
+ const VkImageStencilUsageCreateInfo *stencilUsageInfo = reinterpret_cast<const VkImageStencilUsageCreateInfo *>(extensionFormatInfo);
+ stencilUsage = stencilUsageInfo->stencilUsage;
}
break;
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO:
@@ -3151,38 +3202,14 @@
return VK_ERROR_FORMAT_NOT_SUPPORTED;
}
- // Check for usage conflict with features
- if((usage & VK_IMAGE_USAGE_SAMPLED_BIT) && !(features & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT))
+ // Reject any usage or separate stencil usage that is not compatible with the specified format.
+ if(!checkFormatUsage(usage, features))
{
return VK_ERROR_FORMAT_NOT_SUPPORTED;
}
-
- if((usage & VK_IMAGE_USAGE_STORAGE_BIT) && !(features & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT))
- {
- return VK_ERROR_FORMAT_NOT_SUPPORTED;
- }
-
- if((usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) && !(features & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT))
- {
- return VK_ERROR_FORMAT_NOT_SUPPORTED;
- }
-
- if((usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) && !(features & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT))
- {
- return VK_ERROR_FORMAT_NOT_SUPPORTED;
- }
-
- if((usage & VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT) && !(features & (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT)))
- {
- return VK_ERROR_FORMAT_NOT_SUPPORTED;
- }
-
- if((usage & VK_IMAGE_USAGE_TRANSFER_SRC_BIT) && !(features & VK_FORMAT_FEATURE_TRANSFER_SRC_BIT))
- {
- return VK_ERROR_FORMAT_NOT_SUPPORTED;
- }
-
- if((usage & VK_IMAGE_USAGE_TRANSFER_DST_BIT) && !(features & VK_FORMAT_FEATURE_TRANSFER_DST_BIT))
+ // If stencilUsage is 0 then no separate usage was provided and it takes on the same value as usage,
+ // which has already been checked. So only check non-zero stencilUsage.
+ if(stencilUsage != 0 && !checkFormatUsage(stencilUsage, features))
{
return VK_ERROR_FORMAT_NOT_SUPPORTED;
}