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).
This commit is contained in:
Alejandro Piñeiro 2020-06-20 00:08:13 +02:00
parent 55d7125e7c
commit d33bc6c75e
3 changed files with 24 additions and 3 deletions

View file

@ -100,6 +100,21 @@ namespace vks
return false; 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 // Create an image memory barrier for changing the layout of
// an image and put it into an active command buffer // an image and put it into an active command buffer
// See chapter 11.4 "Image Layout" for details // See chapter 11.4 "Image Layout" for details

View file

@ -78,6 +78,9 @@ namespace vks
// Returns false if none of the depth formats in the list is supported by the device // Returns false if none of the depth formats in the list is supported by the device
VkBool32 getSupportedDepthFormat(VkPhysicalDevice physicalDevice, VkFormat *depthFormat); 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 // Put an image memory barrier for setting an image layout on the sub resource into the given command buffer
void setImageLayout( void setImageLayout(
VkCommandBuffer cmdbuffer, VkCommandBuffer cmdbuffer,

View file

@ -33,7 +33,7 @@
#else #else
#define SHADOWMAP_DIM 2048 #define SHADOWMAP_DIM 2048
#endif #endif
#define SHADOWMAP_FILTER VK_FILTER_LINEAR #define DEFAULT_SHADOWMAP_FILTER VK_FILTER_LINEAR
class VulkanExample : public VulkanExampleBase class VulkanExample : public VulkanExampleBase
{ {
@ -275,9 +275,12 @@ public:
// Create sampler to sample from to depth attachment // Create sampler to sample from to depth attachment
// Used to sample in the fragment shader for shadowed rendering // 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(); VkSamplerCreateInfo sampler = vks::initializers::samplerCreateInfo();
sampler.magFilter = SHADOWMAP_FILTER; sampler.magFilter = shadowmap_filter;
sampler.minFilter = SHADOWMAP_FILTER; sampler.minFilter = shadowmap_filter;
sampler.mipmapMode = VK_SAMPLER_MIPMAP_MODE_LINEAR; sampler.mipmapMode = VK_SAMPLER_MIPMAP_MODE_LINEAR;
sampler.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; sampler.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
sampler.addressModeV = sampler.addressModeU; sampler.addressModeV = sampler.addressModeU;