mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-29 18:50:10 +01:00
radv: Add format modifier format queries.
Reviewed-By: Chad Versace <chad@kiwitree.net> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/7667>
This commit is contained in:
parent
4dbbd59a01
commit
6c83e3ea98
1 changed files with 208 additions and 9 deletions
|
|
@ -23,16 +23,19 @@
|
|||
*/
|
||||
|
||||
#include "radv_private.h"
|
||||
#include "radv_debug.h"
|
||||
|
||||
#include "vk_format.h"
|
||||
#include "sid.h"
|
||||
|
||||
#include "vk_util.h"
|
||||
|
||||
#include "drm-uapi/drm_fourcc.h"
|
||||
#include "util/half_float.h"
|
||||
#include "util/format_srgb.h"
|
||||
#include "util/format_r11g11b10f.h"
|
||||
#include "util/format_rgb9e5.h"
|
||||
#include "vulkan/util/vk_format.h"
|
||||
|
||||
uint32_t radv_translate_buffer_dataformat(const struct vk_format_description *desc,
|
||||
int first_non_void)
|
||||
|
|
@ -1119,6 +1122,167 @@ void radv_GetPhysicalDeviceFormatProperties(
|
|||
pFormatProperties);
|
||||
}
|
||||
|
||||
static const struct ac_modifier_options radv_modifier_options = {
|
||||
.dcc = false,
|
||||
.dcc_retile = false,
|
||||
};
|
||||
|
||||
static VkFormatFeatureFlags
|
||||
radv_get_modifier_flags(struct radv_physical_device *dev,
|
||||
VkFormat format, uint64_t modifier,
|
||||
const VkFormatProperties *props)
|
||||
{
|
||||
VkFormatFeatureFlags features;
|
||||
|
||||
if (vk_format_is_compressed(format) || vk_format_is_depth_or_stencil(format))
|
||||
return 0;
|
||||
|
||||
if (modifier == DRM_FORMAT_MOD_LINEAR)
|
||||
features = props->linearTilingFeatures;
|
||||
else
|
||||
features = props->optimalTilingFeatures;
|
||||
|
||||
if (modifier != DRM_FORMAT_MOD_LINEAR && vk_format_get_plane_count(format) > 1)
|
||||
return 0;
|
||||
|
||||
if (ac_modifier_has_dcc(modifier)) {
|
||||
features &= ~VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT;
|
||||
|
||||
if (dev->instance->debug_flags & RADV_DEBUG_NO_DCC)
|
||||
return 0;
|
||||
}
|
||||
|
||||
return features;
|
||||
}
|
||||
|
||||
static void radv_list_drm_format_modifiers(struct radv_physical_device *dev,
|
||||
VkFormat format,
|
||||
VkFormatProperties2 *pFormatProperties)
|
||||
{
|
||||
VkDrmFormatModifierPropertiesListEXT *mod_list =
|
||||
vk_find_struct(pFormatProperties, DRM_FORMAT_MODIFIER_PROPERTIES_LIST_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) {
|
||||
VkFormatFeatureFlags features =
|
||||
radv_get_modifier_flags(dev, format, mods[i], &pFormatProperties->formatProperties);
|
||||
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;
|
||||
}
|
||||
|
||||
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,
|
||||
VkImageFormatProperties *props,
|
||||
VkFormat format,
|
||||
uint64_t modifier)
|
||||
{
|
||||
if (info->type != VK_IMAGE_TYPE_2D)
|
||||
return VK_ERROR_FORMAT_NOT_SUPPORTED;
|
||||
|
||||
/* We did not add modifiers for sparse textures. */
|
||||
if (info->flags & (VK_IMAGE_CREATE_SPARSE_BINDING_BIT |
|
||||
VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT |
|
||||
VK_IMAGE_CREATE_SPARSE_ALIASED_BIT))
|
||||
return VK_ERROR_FORMAT_NOT_SUPPORTED;
|
||||
|
||||
/*
|
||||
* Need to check the modifier is supported in general:
|
||||
* "If the drmFormatModifier is incompatible with the parameters specified
|
||||
* in VkPhysicalDeviceImageFormatInfo2 and its pNext chain, then
|
||||
* vkGetPhysicalDeviceImageFormatProperties2 returns VK_ERROR_FORMAT_NOT_SUPPORTED.
|
||||
* The implementation must support the query of any drmFormatModifier,
|
||||
* including unknown and invalid modifier values."
|
||||
*/
|
||||
VkDrmFormatModifierPropertiesListEXT mod_list = {
|
||||
.sType = VK_STRUCTURE_TYPE_DRM_FORMAT_MODIFIER_PROPERTIES_LIST_EXT,
|
||||
};
|
||||
|
||||
VkFormatProperties2 format_props2 = {
|
||||
.sType = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2,
|
||||
.pNext = &mod_list
|
||||
};
|
||||
|
||||
radv_GetPhysicalDeviceFormatProperties2(radv_physical_device_to_handle(dev), format, &format_props2);
|
||||
|
||||
if (!mod_list.drmFormatModifierCount)
|
||||
return VK_ERROR_FORMAT_NOT_SUPPORTED;
|
||||
|
||||
mod_list.pDrmFormatModifierProperties = calloc(mod_list.drmFormatModifierCount, sizeof(*mod_list.pDrmFormatModifierProperties));
|
||||
if (!mod_list.pDrmFormatModifierProperties)
|
||||
return VK_ERROR_OUT_OF_HOST_MEMORY;
|
||||
|
||||
radv_GetPhysicalDeviceFormatProperties2(radv_physical_device_to_handle(dev), format, &format_props2);
|
||||
|
||||
bool found = false;
|
||||
for (uint32_t i = 0; i < mod_list.drmFormatModifierCount && !found; ++i)
|
||||
if (mod_list.pDrmFormatModifierProperties[i].drmFormatModifier == modifier)
|
||||
found = true;
|
||||
|
||||
free(mod_list.pDrmFormatModifierProperties);
|
||||
|
||||
if (!found)
|
||||
return VK_ERROR_FORMAT_NOT_SUPPORTED;
|
||||
|
||||
if (ac_modifier_has_dcc(modifier) &&
|
||||
!radv_are_formats_dcc_compatible(dev, info->pNext, format, info->flags))
|
||||
return VK_ERROR_FORMAT_NOT_SUPPORTED;
|
||||
|
||||
/* We can expand this as needed and implemented but there is not much demand
|
||||
* for more. */
|
||||
if (ac_modifier_has_dcc(modifier)) {
|
||||
props->maxMipLevels = 1;
|
||||
props->maxArrayLayers = 1;
|
||||
}
|
||||
/* We don't support MSAA for modifiers */
|
||||
props->sampleCounts &= VK_SAMPLE_COUNT_1_BIT;
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
void radv_GetPhysicalDeviceFormatProperties2(
|
||||
VkPhysicalDevice physicalDevice,
|
||||
VkFormat format,
|
||||
|
|
@ -1129,6 +1293,8 @@ void radv_GetPhysicalDeviceFormatProperties2(
|
|||
radv_physical_device_get_format_properties(physical_device,
|
||||
format,
|
||||
&pFormatProperties->formatProperties);
|
||||
|
||||
radv_list_drm_format_modifiers(physical_device, format, pFormatProperties);
|
||||
}
|
||||
|
||||
static VkResult radv_get_image_format_properties(struct radv_physical_device *physical_device,
|
||||
|
|
@ -1145,13 +1311,26 @@ static VkResult radv_get_image_format_properties(struct radv_physical_device *ph
|
|||
VkSampleCountFlags sampleCounts = VK_SAMPLE_COUNT_1_BIT;
|
||||
const struct vk_format_description *desc = vk_format_description(format);
|
||||
enum chip_class chip_class = physical_device->rad_info.chip_class;
|
||||
VkImageTiling tiling = info->tiling;
|
||||
const VkPhysicalDeviceImageDrmFormatModifierInfoEXT *mod_info =
|
||||
vk_find_struct_const(info->pNext, PHYSICAL_DEVICE_IMAGE_DRM_FORMAT_MODIFIER_INFO_EXT);
|
||||
VkResult result = VK_ERROR_FORMAT_NOT_SUPPORTED;
|
||||
|
||||
if (mod_info) {
|
||||
tiling = mod_info->drmFormatModifier == DRM_FORMAT_MOD_LINEAR ?
|
||||
VK_IMAGE_TILING_LINEAR : VK_IMAGE_TILING_OPTIMAL;
|
||||
}
|
||||
|
||||
radv_physical_device_get_format_properties(physical_device, format,
|
||||
&format_props);
|
||||
if (info->tiling == VK_IMAGE_TILING_LINEAR) {
|
||||
if (tiling == VK_IMAGE_TILING_LINEAR) {
|
||||
format_feature_flags = format_props.linearTilingFeatures;
|
||||
} else if (info->tiling == VK_IMAGE_TILING_OPTIMAL) {
|
||||
} else if (tiling == VK_IMAGE_TILING_OPTIMAL) {
|
||||
format_feature_flags = format_props.optimalTilingFeatures;
|
||||
} else if (tiling == VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT) {
|
||||
format_feature_flags = radv_get_modifier_flags(physical_device, format,
|
||||
mod_info->drmFormatModifier,
|
||||
&format_props);
|
||||
} else {
|
||||
unreachable("bad VkImageTiling");
|
||||
}
|
||||
|
|
@ -1200,7 +1379,7 @@ static VkResult radv_get_image_format_properties(struct radv_physical_device *ph
|
|||
maxArraySize = 1;
|
||||
}
|
||||
|
||||
if (info->tiling == VK_IMAGE_TILING_OPTIMAL &&
|
||||
if (tiling == VK_IMAGE_TILING_OPTIMAL &&
|
||||
info->type == VK_IMAGE_TYPE_2D &&
|
||||
(format_feature_flags & (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT |
|
||||
VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT)) &&
|
||||
|
|
@ -1208,7 +1387,7 @@ static VkResult radv_get_image_format_properties(struct radv_physical_device *ph
|
|||
sampleCounts |= VK_SAMPLE_COUNT_2_BIT | VK_SAMPLE_COUNT_4_BIT | VK_SAMPLE_COUNT_8_BIT;
|
||||
}
|
||||
|
||||
if (info->tiling == VK_IMAGE_TILING_LINEAR &&
|
||||
if (tiling == VK_IMAGE_TILING_LINEAR &&
|
||||
(format == VK_FORMAT_R32G32B32_SFLOAT ||
|
||||
format == VK_FORMAT_R32G32B32_SINT ||
|
||||
format == VK_FORMAT_R32G32B32_UINT)) {
|
||||
|
|
@ -1306,6 +1485,14 @@ static VkResult radv_get_image_format_properties(struct radv_physical_device *ph
|
|||
.maxResourceSize = UINT32_MAX,
|
||||
};
|
||||
|
||||
if (mod_info) {
|
||||
result = radv_check_modifier_support(physical_device, info,
|
||||
pImageFormatProperties,
|
||||
format, mod_info->drmFormatModifier);
|
||||
if (result != VK_SUCCESS)
|
||||
goto unsupported;
|
||||
}
|
||||
|
||||
return VK_SUCCESS;
|
||||
unsupported:
|
||||
*pImageFormatProperties = (VkImageFormatProperties) {
|
||||
|
|
@ -1316,7 +1503,7 @@ unsupported:
|
|||
.maxResourceSize = 0,
|
||||
};
|
||||
|
||||
return VK_ERROR_FORMAT_NOT_SUPPORTED;
|
||||
return result;
|
||||
}
|
||||
|
||||
VkResult radv_GetPhysicalDeviceImageFormatProperties(
|
||||
|
|
@ -1359,16 +1546,28 @@ get_external_image_format_properties(struct radv_physical_device *physical_devic
|
|||
return;
|
||||
|
||||
switch (handleType) {
|
||||
case VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT:
|
||||
case VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT:
|
||||
if (pImageFormatInfo->tiling != VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT)
|
||||
break;
|
||||
|
||||
switch (pImageFormatInfo->type) {
|
||||
case VK_IMAGE_TYPE_2D:
|
||||
flags = VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT|VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT;
|
||||
flags = VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT |VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT;
|
||||
|
||||
compat_flags = export_flags = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT:
|
||||
switch (pImageFormatInfo->type) {
|
||||
case VK_IMAGE_TYPE_2D:
|
||||
flags = VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT |VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT;
|
||||
if (pImageFormatInfo->tiling != VK_IMAGE_TILING_LINEAR)
|
||||
flags |= VK_EXTERNAL_MEMORY_FEATURE_DEDICATED_ONLY_BIT;
|
||||
|
||||
compat_flags = export_flags = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT |
|
||||
VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT;
|
||||
compat_flags = export_flags = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue