radv: implement VK_KHR_format_feature_flags2

Signed-off-by: Samuel Pitoiset <samuel.pitoiset@gmail.com>
Reviewed-by: Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/13194>
This commit is contained in:
Samuel Pitoiset 2021-08-17 09:05:09 +02:00 committed by Marge Bot
parent 5dee0d9da9
commit 49c3a88fad
4 changed files with 169 additions and 4 deletions

View File

@ -18,3 +18,4 @@ Experimental raytracing support on RADV
VK_KHR_synchronization2 on Intel
NGG shader based culling is now enabled by default on GFX10.3 on RADV.
VK_KHR_maintenance4 on RADV
VK_KHR_format_feature_flags2 on RADV.

View File

@ -660,6 +660,82 @@ get_ahb_buffer_format_properties(VkDevice device_h, const struct AHardwareBuffer
return VK_SUCCESS;
}
static VkResult
get_ahb_buffer_format_properties2(VkDevice device_h, const struct AHardwareBuffer *buffer,
VkAndroidHardwareBufferFormatPropertiesANDROID2 *pProperties)
{
RADV_FROM_HANDLE(radv_device, device, device_h);
/* Get a description of buffer contents . */
AHardwareBuffer_Desc desc;
AHardwareBuffer_describe(buffer, &desc);
/* Verify description. */
const uint64_t gpu_usage = AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE |
AHARDWAREBUFFER_USAGE_GPU_COLOR_OUTPUT |
AHARDWAREBUFFER_USAGE_GPU_DATA_BUFFER;
/* "Buffer must be a valid Android hardware buffer object with at least
* one of the AHARDWAREBUFFER_USAGE_GPU_* usage flags."
*/
if (!(desc.usage & (gpu_usage)))
return VK_ERROR_INVALID_EXTERNAL_HANDLE;
/* Fill properties fields based on description. */
VkAndroidHardwareBufferFormatPropertiesANDROID *p = pProperties;
p->format = vk_format_from_android(desc.format, desc.usage);
p->externalFormat = (uint64_t)(uintptr_t)p->format;
VkFormatProperties2 format_properties = {
.sType = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2
};
radv_GetPhysicalDeviceFormatProperties2(radv_physical_device_to_handle(device->physical_device),
p->format, &format_properties);
if (desc.usage & AHARDWAREBUFFER_USAGE_GPU_DATA_BUFFER)
p->formatFeatures = format_properties.formatProperties.linearTilingFeatures;
else
p->formatFeatures = format_properties.formatProperties.optimalTilingFeatures;
/* "Images can be created with an external format even if the Android hardware
* buffer has a format which has an equivalent Vulkan format to enable
* consistent handling of images from sources that might use either category
* of format. However, all images created with an external format are subject
* to the valid usage requirements associated with external formats, even if
* the Android hardware buffers format has a Vulkan equivalent."
*
* "The formatFeatures member *must* include
* VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_BIT_KHR and at least one of
* VK_FORMAT_FEATURE_2_MIDPOINT_CHROMA_SAMPLES_BIT_KHR or
* VK_FORMAT_FEATURE_2_COSITED_CHROMA_SAMPLES_BIT_KHR"
*/
assert(p->formatFeatures & VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_BIT_KHR);
p->formatFeatures |= VK_FORMAT_FEATURE_2_MIDPOINT_CHROMA_SAMPLES_BIT_KHR;
/* "Implementations may not always be able to determine the color model,
* numerical range, or chroma offsets of the image contents, so the values
* in VkAndroidHardwareBufferFormatPropertiesANDROID are only suggestions.
* Applications should treat these values as sensible defaults to use in
* the absence of more reliable information obtained through some other
* means."
*/
p->samplerYcbcrConversionComponents.r = VK_COMPONENT_SWIZZLE_IDENTITY;
p->samplerYcbcrConversionComponents.g = VK_COMPONENT_SWIZZLE_IDENTITY;
p->samplerYcbcrConversionComponents.b = VK_COMPONENT_SWIZZLE_IDENTITY;
p->samplerYcbcrConversionComponents.a = VK_COMPONENT_SWIZZLE_IDENTITY;
p->suggestedYcbcrModel = VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_601;
p->suggestedYcbcrRange = VK_SAMPLER_YCBCR_RANGE_ITU_FULL;
p->suggestedXChromaOffset = VK_CHROMA_LOCATION_MIDPOINT;
p->suggestedYChromaOffset = VK_CHROMA_LOCATION_MIDPOINT;
return VK_SUCCESS;
}
VkResult
radv_GetAndroidHardwareBufferPropertiesANDROID(VkDevice device_h,
const struct AHardwareBuffer *buffer,
@ -675,6 +751,11 @@ radv_GetAndroidHardwareBufferPropertiesANDROID(VkDevice device_h,
if (format_prop)
get_ahb_buffer_format_properties(device_h, buffer, format_prop);
VkAndroidHardwareBufferFormatProperties2ANDROID *format_prop2 =
vk_find_struct(pProperties->pNext, ANDROID_HARDWARE_BUFFER_FORMAT_PROPERTIES_2_ANDROID);
if (format_prop2)
get_ahb_buffer_format_properties2(device_h, buffer, format_prop2);
/* NOTE - We support buffers with only one handle but do not error on
* multiple handle case. Reason is that we want to support YUV formats
* where we have many logical planes but they all point to the same

View File

@ -424,6 +424,7 @@ radv_physical_device_get_supported_extensions(const struct radv_physical_device
.KHR_external_memory_fd = true,
.KHR_external_semaphore = true,
.KHR_external_semaphore_fd = true,
.KHR_format_feature_flags2 = true,
.KHR_fragment_shading_rate = device->rad_info.chip_class >= GFX10_3,
.KHR_get_memory_requirements2 = true,
.KHR_image_format_list = true,

View File

@ -684,8 +684,12 @@ radv_physical_device_get_format_properties(struct radv_physical_device *physical
}
if (radv_is_storage_image_format_supported(physical_device, format)) {
tiled |= VK_FORMAT_FEATURE_2_STORAGE_IMAGE_BIT_KHR;
linear |= VK_FORMAT_FEATURE_2_STORAGE_IMAGE_BIT_KHR;
tiled |= VK_FORMAT_FEATURE_2_STORAGE_IMAGE_BIT_KHR |
VK_FORMAT_FEATURE_2_STORAGE_READ_WITHOUT_FORMAT_BIT_KHR |
VK_FORMAT_FEATURE_2_STORAGE_WRITE_WITHOUT_FORMAT_BIT_KHR;
linear |= VK_FORMAT_FEATURE_2_STORAGE_IMAGE_BIT_KHR |
VK_FORMAT_FEATURE_2_STORAGE_READ_WITHOUT_FORMAT_BIT_KHR |
VK_FORMAT_FEATURE_2_STORAGE_WRITE_WITHOUT_FORMAT_BIT_KHR;
}
if (radv_is_buffer_format_supported(format, &scaled)) {
@ -707,8 +711,10 @@ radv_physical_device_get_format_properties(struct radv_physical_device *physical
if (radv_is_filter_minmax_format_supported(format))
tiled |= VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_FILTER_MINMAX_BIT_KHR;
if (vk_format_has_depth(format))
tiled |= VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_FILTER_LINEAR_BIT_KHR;
if (vk_format_has_depth(format)) {
tiled |= VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_FILTER_LINEAR_BIT_KHR |
VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_DEPTH_COMPARISON_BIT_KHR;
}
/* Don't support blitting surfaces with depth/stencil. */
if (vk_format_has_depth(format) && vk_format_has_stencil(format))
@ -1229,6 +1235,73 @@ radv_list_drm_format_modifiers(struct radv_physical_device *dev, VkFormat format
free(mods);
}
static void
radv_list_drm_format_modifiers_2(struct radv_physical_device *dev, VkFormat format,
VkFormatProperties2 *pFormatProperties)
{
VkDrmFormatModifierPropertiesList2EXT *mod_list =
vk_find_struct(pFormatProperties, DRM_FORMAT_MODIFIER_PROPERTIES_LIST_2_EXT);
unsigned mod_count;
if (!mod_list)
return;
if (vk_format_is_compressed(format) || vk_format_is_depth_or_stencil(format)) {
mod_list->drmFormatModifierCount = 0;
return;
}
ac_get_supported_modifiers(&dev->rad_info, &radv_modifier_options,
vk_format_to_pipe_format(format), &mod_count, NULL);
if (!mod_list->pDrmFormatModifierProperties) {
mod_list->drmFormatModifierCount = mod_count;
return;
}
mod_count = MIN2(mod_count, mod_list->drmFormatModifierCount);
uint64_t *mods = malloc(mod_count * sizeof(uint64_t));
if (!mods) {
/* We can't return an error here ... */
mod_list->drmFormatModifierCount = 0;
return;
}
ac_get_supported_modifiers(&dev->rad_info, &radv_modifier_options,
vk_format_to_pipe_format(format), &mod_count, mods);
mod_list->drmFormatModifierCount = 0;
for (unsigned i = 0; i < mod_count; ++i) {
VkFormatProperties3KHR format_props;
VkFormatFeatureFlags2KHR features =
radv_get_modifier_flags(dev, format, mods[i], &format_props);
unsigned planes = vk_format_get_plane_count(format);
if (planes == 1) {
if (ac_modifier_has_dcc_retile(mods[i]))
planes = 3;
else if (ac_modifier_has_dcc(mods[i]))
planes = 2;
}
pFormatProperties->formatProperties.linearTilingFeatures = format_props.linearTilingFeatures;
pFormatProperties->formatProperties.optimalTilingFeatures = format_props.optimalTilingFeatures;
pFormatProperties->formatProperties.bufferFeatures = format_props.bufferFeatures;
if (!features)
continue;
mod_list->pDrmFormatModifierProperties[mod_list->drmFormatModifierCount].drmFormatModifier =
mods[i];
mod_list->pDrmFormatModifierProperties[mod_list->drmFormatModifierCount]
.drmFormatModifierPlaneCount = planes;
mod_list->pDrmFormatModifierProperties[mod_list->drmFormatModifierCount]
.drmFormatModifierTilingFeatures = features;
++mod_list->drmFormatModifierCount;
}
free(mods);
}
static VkResult
radv_check_modifier_support(struct radv_physical_device *dev,
const VkPhysicalDeviceImageFormatInfo2 *info,
@ -1322,7 +1395,16 @@ radv_GetPhysicalDeviceFormatProperties2(VkPhysicalDevice physicalDevice, VkForma
pFormatProperties->formatProperties.bufferFeatures =
features2_to_features(format_props.bufferFeatures);
VkFormatProperties3KHR *format_props_extended =
vk_find_struct(pFormatProperties, FORMAT_PROPERTIES_3_KHR);
if (format_props_extended) {
format_props_extended->linearTilingFeatures = format_props.linearTilingFeatures;
format_props_extended->optimalTilingFeatures = format_props.optimalTilingFeatures;
format_props_extended->bufferFeatures = format_props.bufferFeatures;
}
radv_list_drm_format_modifiers(physical_device, format, pFormatProperties);
radv_list_drm_format_modifiers_2(physical_device, format, pFormatProperties);
}
static VkResult