v3dv/format: Add support for VK_KHR_format_feature_flags2

VK_KHR_format_feature_flags2 is mostly about define a new 64-bit
VkFormatFeatureFlagBits2KHR format feature flag type, as 29 bits of
the 32-bit VkFormatFeatureFlagBits are already in use.

So all the bits from VkFormatFeatureFlagBits are being replicated, and
most of the work here consist on switch to the new flags.

From the new (not replicated from VkFormatFeatureFlagBits) flag bits,
we don't support
VK_FORMAT_FEATURE_2_STORAGE_READ_WITHOUT_FORMAT_BIT_KHR or
VK_FORMAT_FEATURE_2_STORAGE_WRITE_WITHOUT_FORMAT_BIT_KHR, as right now
we require the format on the shader for doing the read and stores.

We use now VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_DEPTH_COMPARISON_BIT_KHR,
but only applying it for depth formats.

Reviewed-by: Iago Toral Quiroga <itoral@igalia.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/16718>
This commit is contained in:
Alejandro Piñeiro
2022-05-10 22:01:51 +02:00
committed by Marge Bot
parent 11a0ea76a2
commit 746287d221
5 changed files with 73 additions and 46 deletions

View File

@@ -474,7 +474,7 @@ Vulkan 1.3 -- all DONE: anv, radv, lvp
VK_KHR_copy_commands2 DONE (anv, lvp, radv, tu, v3dv)
VK_KHR_dynamic_rendering DONE (anv, lvp, radv)
VK_KHR_format_feature_flags2 DONE (anv, radv, tu)
VK_KHR_format_feature_flags2 DONE (anv, radv, tu, v3dv)
VK_KHR_maintenance4 DONE (anv, radv, tu)
VK_KHR_shader_non_semantic_info DONE (anv, radv, tu, v3dv)
VK_KHR_shader_terminate_invocation DONE (anv, radv, tu)

View File

@@ -129,6 +129,7 @@ get_device_extensions(const struct v3dv_physical_device *device,
.KHR_external_memory_fd = true,
.KHR_external_semaphore = true,
.KHR_external_semaphore_fd = true,
.KHR_format_feature_flags2 = true,
.KHR_get_memory_requirements2 = true,
.KHR_image_format_list = true,
.KHR_imageless_framebuffer = true,

View File

@@ -23,6 +23,7 @@
#include "v3dv_private.h"
#include "vk_util.h"
#include "vk_enum_defines.h"
#include "drm-uapi/drm_fourcc.h"
#include "util/format/u_format.h"
@@ -122,7 +123,7 @@ v3dv_get_compatible_tfu_format(struct v3dv_device *device,
return format;
}
static VkFormatFeatureFlags
static VkFormatFeatureFlags2KHR
image_format_features(struct v3dv_physical_device *pdevice,
VkFormat vk_format,
const struct v3dv_format *v3dv_format,
@@ -149,7 +150,7 @@ image_format_features(struct v3dv_physical_device *pdevice,
return 0;
}
VkFormatFeatureFlags flags = 0;
VkFormatFeatureFlags2KHR flags = 0;
/* Raster format is only supported for 1D textures, so let's just
* always require optimal tiling for anything that requires sampling.
@@ -158,22 +159,22 @@ image_format_features(struct v3dv_physical_device *pdevice,
*/
if (v3dv_format->tex_type != TEXTURE_DATA_FORMAT_NO &&
tiling == VK_IMAGE_TILING_OPTIMAL) {
flags |= VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT |
VK_FORMAT_FEATURE_BLIT_SRC_BIT;
flags |= VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_BIT |
VK_FORMAT_FEATURE_2_BLIT_SRC_BIT;
if (v3dv_format->supports_filtering)
flags |= VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT;
flags |= VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_FILTER_LINEAR_BIT;
}
if (v3dv_format->rt_type != V3D_OUTPUT_IMAGE_FORMAT_NO) {
if (aspects & VK_IMAGE_ASPECT_COLOR_BIT) {
flags |= VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT |
VK_FORMAT_FEATURE_BLIT_DST_BIT;
flags |= VK_FORMAT_FEATURE_2_COLOR_ATTACHMENT_BIT |
VK_FORMAT_FEATURE_2_BLIT_DST_BIT;
if (v3dv_X(pdevice, format_supports_blending)(v3dv_format))
flags |= VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT;
flags |= VK_FORMAT_FEATURE_2_COLOR_ATTACHMENT_BLEND_BIT;
} else if (aspects & zs_aspects) {
flags |= VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT |
VK_FORMAT_FEATURE_BLIT_DST_BIT;
flags |= VK_FORMAT_FEATURE_2_DEPTH_STENCIL_ATTACHMENT_BIT |
VK_FORMAT_FEATURE_2_BLIT_DST_BIT;
}
}
@@ -183,26 +184,32 @@ image_format_features(struct v3dv_physical_device *pdevice,
if (tiling != VK_IMAGE_TILING_LINEAR) {
if (desc->layout == UTIL_FORMAT_LAYOUT_PLAIN && desc->is_array) {
flags |= VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT;
flags |= VK_FORMAT_FEATURE_2_STORAGE_IMAGE_BIT;
if (desc->nr_channels == 1 && vk_format_is_int(vk_format))
flags |= VK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT;
flags |= VK_FORMAT_FEATURE_2_STORAGE_IMAGE_ATOMIC_BIT;
} else if (vk_format == VK_FORMAT_A2B10G10R10_UNORM_PACK32 ||
vk_format == VK_FORMAT_A2B10G10R10_UINT_PACK32 ||
vk_format == VK_FORMAT_B10G11R11_UFLOAT_PACK32) {
/* To comply with shaderStorageImageExtendedFormats */
flags |= VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT;
flags |= VK_FORMAT_FEATURE_2_STORAGE_IMAGE_BIT;
}
}
/* All our depth formats support shadow comparisons. */
if (vk_format_has_depth(vk_format) &&
(flags & VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_BIT)) {
flags |= VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_DEPTH_COMPARISON_BIT;
}
if (flags) {
flags |= VK_FORMAT_FEATURE_TRANSFER_SRC_BIT |
VK_FORMAT_FEATURE_TRANSFER_DST_BIT;
flags |= VK_FORMAT_FEATURE_2_TRANSFER_SRC_BIT |
VK_FORMAT_FEATURE_2_TRANSFER_DST_BIT;
}
return flags;
}
static VkFormatFeatureFlags
static VkFormatFeatureFlags2KHR
buffer_format_features(VkFormat vk_format, const struct v3dv_format *v3dv_format)
{
if (!v3dv_format || !v3dv_format->supported)
@@ -221,30 +228,30 @@ buffer_format_features(VkFormat vk_format, const struct v3dv_format *v3dv_format
vk_format_description(vk_format);
assert(desc);
VkFormatFeatureFlags flags = 0;
VkFormatFeatureFlags2KHR flags = 0;
if (desc->layout == UTIL_FORMAT_LAYOUT_PLAIN &&
desc->colorspace == UTIL_FORMAT_COLORSPACE_RGB &&
desc->is_array) {
flags |= VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT;
flags |= VK_FORMAT_FEATURE_2_VERTEX_BUFFER_BIT;
if (v3dv_format->tex_type != TEXTURE_DATA_FORMAT_NO) {
flags |= VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT |
VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT;
flags |= VK_FORMAT_FEATURE_2_UNIFORM_TEXEL_BUFFER_BIT |
VK_FORMAT_FEATURE_2_STORAGE_TEXEL_BUFFER_BIT;
}
} else if (vk_format == VK_FORMAT_A2B10G10R10_UNORM_PACK32) {
flags |= VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT |
VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT |
VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT;
flags |= VK_FORMAT_FEATURE_2_VERTEX_BUFFER_BIT |
VK_FORMAT_FEATURE_2_UNIFORM_TEXEL_BUFFER_BIT |
VK_FORMAT_FEATURE_2_STORAGE_TEXEL_BUFFER_BIT;
} else if (vk_format == VK_FORMAT_A2B10G10R10_UINT_PACK32 ||
vk_format == VK_FORMAT_B10G11R11_UFLOAT_PACK32) {
flags |= VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT |
VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT;
flags |= VK_FORMAT_FEATURE_2_UNIFORM_TEXEL_BUFFER_BIT |
VK_FORMAT_FEATURE_2_STORAGE_TEXEL_BUFFER_BIT;
}
if (desc->layout == UTIL_FORMAT_LAYOUT_PLAIN &&
desc->is_array &&
desc->nr_channels == 1 &&
vk_format_is_int(vk_format)) {
flags |= VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_ATOMIC_BIT;
flags |= VK_FORMAT_FEATURE_2_STORAGE_TEXEL_BUFFER_ATOMIC_BIT;
}
return flags;
@@ -253,14 +260,23 @@ buffer_format_features(VkFormat vk_format, const struct v3dv_format *v3dv_format
bool
v3dv_buffer_format_supports_features(struct v3dv_device *device,
VkFormat vk_format,
VkFormatFeatureFlags features)
VkFormatFeatureFlags2KHR features)
{
const struct v3dv_format *v3dv_format = v3dv_X(device, get_format)(vk_format);
const VkFormatFeatureFlags supported =
const VkFormatFeatureFlags2KHR supported =
buffer_format_features(vk_format, v3dv_format);
return (supported & features) == features;
}
/* FIXME: this helper now on anv, radv, lvp, and v3dv. Perhaps common
* place?
*/
static inline VkFormatFeatureFlags
features2_to_features(VkFormatFeatureFlags2KHR features2)
{
return features2 & VK_ALL_FORMAT_FEATURE_FLAG_BITS;
}
VKAPI_ATTR void VKAPI_CALL
v3dv_GetPhysicalDeviceFormatProperties2(VkPhysicalDevice physicalDevice,
VkFormat format,
@@ -269,13 +285,16 @@ v3dv_GetPhysicalDeviceFormatProperties2(VkPhysicalDevice physicalDevice,
V3DV_FROM_HANDLE(v3dv_physical_device, pdevice, physicalDevice);
const struct v3dv_format *v3dv_format = v3dv_X(pdevice, get_format)(format);
VkFormatFeatureFlags2KHR linear2, optimal2, buffer2;
linear2 = image_format_features(pdevice, format, v3dv_format,
VK_IMAGE_TILING_LINEAR);
optimal2 = image_format_features(pdevice, format, v3dv_format,
VK_IMAGE_TILING_OPTIMAL);
buffer2 = buffer_format_features(format, v3dv_format);
pFormatProperties->formatProperties = (VkFormatProperties) {
.linearTilingFeatures =
image_format_features(pdevice, format, v3dv_format, VK_IMAGE_TILING_LINEAR),
.optimalTilingFeatures =
image_format_features(pdevice, format, v3dv_format, VK_IMAGE_TILING_OPTIMAL),
.bufferFeatures =
buffer_format_features(format, v3dv_format),
.linearTilingFeatures = features2_to_features(linear2),
.optimalTilingFeatures = features2_to_features(optimal2),
.bufferFeatures = features2_to_features(buffer2),
};
vk_foreach_struct(ext, pFormatProperties->pNext) {
@@ -305,6 +324,13 @@ v3dv_GetPhysicalDeviceFormatProperties2(VkPhysicalDevice physicalDevice,
}
break;
}
case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_3_KHR: {
VkFormatProperties3KHR *props = (VkFormatProperties3KHR *)ext;
props->linearTilingFeatures = linear2;
props->optimalTilingFeatures = optimal2;
props->bufferFeatures = buffer2;
break;
}
default:
v3dv_debug_ignored_stype(ext->sType);
break;
@@ -321,7 +347,7 @@ get_image_format_properties(
VkSamplerYcbcrConversionImageFormatProperties *pYcbcrImageFormatProperties)
{
const struct v3dv_format *v3dv_format = v3dv_X(physical_device, get_format)(info->format);
VkFormatFeatureFlags format_feature_flags =
VkFormatFeatureFlags2KHR format_feature_flags =
image_format_features(physical_device, info->format, v3dv_format, tiling);
if (!format_feature_flags)
goto unsupported;
@@ -355,7 +381,7 @@ get_image_format_properties(
info->flags & VK_IMAGE_CREATE_EXTENDED_USAGE_BIT ? 0 : image_usage;
if (image_usage & VK_IMAGE_USAGE_TRANSFER_SRC_BIT) {
if (!(format_feature_flags & VK_FORMAT_FEATURE_TRANSFER_SRC_BIT)) {
if (!(format_feature_flags & VK_FORMAT_FEATURE_2_TRANSFER_SRC_BIT)) {
goto unsupported;
}
@@ -371,14 +397,14 @@ get_image_format_properties(
}
if (image_usage & VK_IMAGE_USAGE_TRANSFER_DST_BIT) {
if (!(format_feature_flags & VK_FORMAT_FEATURE_TRANSFER_DST_BIT)) {
if (!(format_feature_flags & VK_FORMAT_FEATURE_2_TRANSFER_DST_BIT)) {
goto unsupported;
}
}
if (view_usage & (VK_IMAGE_USAGE_SAMPLED_BIT |
VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT)) {
if (!(format_feature_flags & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT)) {
if (!(format_feature_flags & VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_BIT)) {
goto unsupported;
}
@@ -393,20 +419,20 @@ get_image_format_properties(
}
if (view_usage & VK_IMAGE_USAGE_STORAGE_BIT) {
if (!(format_feature_flags & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT)) {
if (!(format_feature_flags & VK_FORMAT_FEATURE_2_STORAGE_IMAGE_BIT)) {
goto unsupported;
}
}
if (view_usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) {
if (!(format_feature_flags & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT)) {
if (!(format_feature_flags & VK_FORMAT_FEATURE_2_COLOR_ATTACHMENT_BIT)) {
goto unsupported;
}
}
if (view_usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) {
if (!(format_feature_flags &
VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT)) {
VK_FORMAT_FEATURE_2_DEPTH_STENCIL_ATTACHMENT_BIT)) {
goto unsupported;
}
}
@@ -464,8 +490,8 @@ get_image_format_properties(
if (tiling != VK_IMAGE_TILING_LINEAR &&
info->type == VK_IMAGE_TYPE_2D &&
!(info->flags & VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT) &&
(format_feature_flags & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT ||
format_feature_flags & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT)) {
(format_feature_flags & VK_FORMAT_FEATURE_2_COLOR_ATTACHMENT_BIT ||
format_feature_flags & VK_FORMAT_FEATURE_2_DEPTH_STENCIL_ATTACHMENT_BIT)) {
pImageFormatProperties->sampleCounts |= VK_SAMPLE_COUNT_4_BIT;
}

View File

@@ -1989,7 +1989,7 @@ texel_buffer_shader_copy(struct v3dv_cmd_buffer *cmd_buffer,
if (!(buffer->usage & VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT)) {
if (v3dv_buffer_format_supports_features(
cmd_buffer->device, src_format,
VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT)) {
VK_FORMAT_FEATURE_2_UNIFORM_TEXEL_BUFFER_BIT)) {
buffer->usage |= VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT;
} else {
return handled;

View File

@@ -2001,7 +2001,7 @@ v3dv_get_compatible_tfu_format(struct v3dv_device *device,
uint32_t bpp, VkFormat *out_vk_format);
bool v3dv_buffer_format_supports_features(struct v3dv_device *device,
VkFormat vk_format,
VkFormatFeatureFlags features);
VkFormatFeatureFlags2KHR features);
struct v3dv_cl_reloc v3dv_write_uniforms(struct v3dv_cmd_buffer *cmd_buffer,
struct v3dv_pipeline *pipeline,