diff --git a/docs/relnotes/new_features.txt b/docs/relnotes/new_features.txt index 442cb309fda..840409c0864 100644 --- a/docs/relnotes/new_features.txt +++ b/docs/relnotes/new_features.txt @@ -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. diff --git a/src/amd/vulkan/radv_android.c b/src/amd/vulkan/radv_android.c index c89719bb0b8..dcfdfe3b80c 100644 --- a/src/amd/vulkan/radv_android.c +++ b/src/amd/vulkan/radv_android.c @@ -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 buffer’s 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 diff --git a/src/amd/vulkan/radv_device.c b/src/amd/vulkan/radv_device.c index 7985cd93218..e30e308d3fc 100644 --- a/src/amd/vulkan/radv_device.c +++ b/src/amd/vulkan/radv_device.c @@ -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, diff --git a/src/amd/vulkan/radv_formats.c b/src/amd/vulkan/radv_formats.c index 429f462cfdd..6ec05aa17fd 100644 --- a/src/amd/vulkan/radv_formats.c +++ b/src/amd/vulkan/radv_formats.c @@ -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