From d33bc6c75e1172c7a9ad787564cd1b803bafaf57 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alejandro=20Pi=C3=B1eiro?= Date: Sat, 20 Jun 2020 00:08:13 +0200 Subject: [PATCH] shadowmappping: check if depth format supports LINEAR filtering The test uses the format VK_FORMAT_D16_UNORM for the shadow map, and it sets unconditionally VK_FILTER_LINEAR when using it. But by spec, it is not mandatory that format to support filtering. Explained here: https://www.khronos.org/registry/vulkan/specs/1.2/html/chap32.html table 51, VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT. This commit checks if that flag is present with that format to decide between LINEAR (the default value) or NEAREST (if LINEAR is not supported). Adds a auxiliar method on VulkanTools just in case it could be useful for other demos. This is not detected by the Validation Layers, but raise an assertion with one of the development tools we use to implement the Mesa v3dv driver (rpi4 vulkan driver). --- base/VulkanTools.cpp | 15 +++++++++++++++ base/VulkanTools.h | 3 +++ examples/shadowmapping/shadowmapping.cpp | 9 ++++++--- 3 files changed, 24 insertions(+), 3 deletions(-) diff --git a/base/VulkanTools.cpp b/base/VulkanTools.cpp index 947f56aa..7dd51621 100644 --- a/base/VulkanTools.cpp +++ b/base/VulkanTools.cpp @@ -100,6 +100,21 @@ namespace vks return false; } + // Returns if a given format support LINEAR filtering + VkBool32 formatIsFilterable(VkPhysicalDevice physicalDevice, VkFormat format, VkImageTiling tiling) + { + VkFormatProperties formatProps; + vkGetPhysicalDeviceFormatProperties(physicalDevice, format, &formatProps); + + if (tiling == VK_IMAGE_TILING_OPTIMAL) + return formatProps.optimalTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT; + + if (tiling == VK_IMAGE_TILING_LINEAR) + return formatProps.linearTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT; + + return false; + } + // Create an image memory barrier for changing the layout of // an image and put it into an active command buffer // See chapter 11.4 "Image Layout" for details diff --git a/base/VulkanTools.h b/base/VulkanTools.h index adccbf9f..fe75fe2f 100644 --- a/base/VulkanTools.h +++ b/base/VulkanTools.h @@ -78,6 +78,9 @@ namespace vks // Returns false if none of the depth formats in the list is supported by the device VkBool32 getSupportedDepthFormat(VkPhysicalDevice physicalDevice, VkFormat *depthFormat); + // Returns if a given format support LINEAR filtering + VkBool32 formatIsFilterable(VkPhysicalDevice physicalDevice, VkFormat format, VkImageTiling tiling); + // Put an image memory barrier for setting an image layout on the sub resource into the given command buffer void setImageLayout( VkCommandBuffer cmdbuffer, diff --git a/examples/shadowmapping/shadowmapping.cpp b/examples/shadowmapping/shadowmapping.cpp index ce15be5d..97ea579e 100644 --- a/examples/shadowmapping/shadowmapping.cpp +++ b/examples/shadowmapping/shadowmapping.cpp @@ -33,7 +33,7 @@ #else #define SHADOWMAP_DIM 2048 #endif -#define SHADOWMAP_FILTER VK_FILTER_LINEAR +#define DEFAULT_SHADOWMAP_FILTER VK_FILTER_LINEAR class VulkanExample : public VulkanExampleBase { @@ -275,9 +275,12 @@ public: // Create sampler to sample from to depth attachment // Used to sample in the fragment shader for shadowed rendering + VkFilter shadowmap_filter = vks::tools::formatIsFilterable(physicalDevice, DEPTH_FORMAT, VK_IMAGE_TILING_OPTIMAL) ? + DEFAULT_SHADOWMAP_FILTER : + VK_FILTER_NEAREST; VkSamplerCreateInfo sampler = vks::initializers::samplerCreateInfo(); - sampler.magFilter = SHADOWMAP_FILTER; - sampler.minFilter = SHADOWMAP_FILTER; + sampler.magFilter = shadowmap_filter; + sampler.minFilter = shadowmap_filter; sampler.mipmapMode = VK_SAMPLER_MIPMAP_MODE_LINEAR; sampler.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; sampler.addressModeV = sampler.addressModeU;