mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-06 07:18:17 +02: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_private.h"
|
||||||
|
#include "radv_debug.h"
|
||||||
|
|
||||||
#include "vk_format.h"
|
#include "vk_format.h"
|
||||||
#include "sid.h"
|
#include "sid.h"
|
||||||
|
|
||||||
#include "vk_util.h"
|
#include "vk_util.h"
|
||||||
|
|
||||||
|
#include "drm-uapi/drm_fourcc.h"
|
||||||
#include "util/half_float.h"
|
#include "util/half_float.h"
|
||||||
#include "util/format_srgb.h"
|
#include "util/format_srgb.h"
|
||||||
#include "util/format_r11g11b10f.h"
|
#include "util/format_r11g11b10f.h"
|
||||||
#include "util/format_rgb9e5.h"
|
#include "util/format_rgb9e5.h"
|
||||||
|
#include "vulkan/util/vk_format.h"
|
||||||
|
|
||||||
uint32_t radv_translate_buffer_dataformat(const struct vk_format_description *desc,
|
uint32_t radv_translate_buffer_dataformat(const struct vk_format_description *desc,
|
||||||
int first_non_void)
|
int first_non_void)
|
||||||
|
|
@ -1119,6 +1122,167 @@ void radv_GetPhysicalDeviceFormatProperties(
|
||||||
pFormatProperties);
|
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(
|
void radv_GetPhysicalDeviceFormatProperties2(
|
||||||
VkPhysicalDevice physicalDevice,
|
VkPhysicalDevice physicalDevice,
|
||||||
VkFormat format,
|
VkFormat format,
|
||||||
|
|
@ -1129,6 +1293,8 @@ void radv_GetPhysicalDeviceFormatProperties2(
|
||||||
radv_physical_device_get_format_properties(physical_device,
|
radv_physical_device_get_format_properties(physical_device,
|
||||||
format,
|
format,
|
||||||
&pFormatProperties->formatProperties);
|
&pFormatProperties->formatProperties);
|
||||||
|
|
||||||
|
radv_list_drm_format_modifiers(physical_device, format, pFormatProperties);
|
||||||
}
|
}
|
||||||
|
|
||||||
static VkResult radv_get_image_format_properties(struct radv_physical_device *physical_device,
|
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;
|
VkSampleCountFlags sampleCounts = VK_SAMPLE_COUNT_1_BIT;
|
||||||
const struct vk_format_description *desc = vk_format_description(format);
|
const struct vk_format_description *desc = vk_format_description(format);
|
||||||
enum chip_class chip_class = physical_device->rad_info.chip_class;
|
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,
|
radv_physical_device_get_format_properties(physical_device, format,
|
||||||
&format_props);
|
&format_props);
|
||||||
if (info->tiling == VK_IMAGE_TILING_LINEAR) {
|
if (tiling == VK_IMAGE_TILING_LINEAR) {
|
||||||
format_feature_flags = format_props.linearTilingFeatures;
|
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;
|
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 {
|
} else {
|
||||||
unreachable("bad VkImageTiling");
|
unreachable("bad VkImageTiling");
|
||||||
}
|
}
|
||||||
|
|
@ -1200,7 +1379,7 @@ static VkResult radv_get_image_format_properties(struct radv_physical_device *ph
|
||||||
maxArraySize = 1;
|
maxArraySize = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (info->tiling == VK_IMAGE_TILING_OPTIMAL &&
|
if (tiling == VK_IMAGE_TILING_OPTIMAL &&
|
||||||
info->type == VK_IMAGE_TYPE_2D &&
|
info->type == VK_IMAGE_TYPE_2D &&
|
||||||
(format_feature_flags & (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT |
|
(format_feature_flags & (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT |
|
||||||
VK_FORMAT_FEATURE_DEPTH_STENCIL_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;
|
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_SFLOAT ||
|
||||||
format == VK_FORMAT_R32G32B32_SINT ||
|
format == VK_FORMAT_R32G32B32_SINT ||
|
||||||
format == VK_FORMAT_R32G32B32_UINT)) {
|
format == VK_FORMAT_R32G32B32_UINT)) {
|
||||||
|
|
@ -1306,6 +1485,14 @@ static VkResult radv_get_image_format_properties(struct radv_physical_device *ph
|
||||||
.maxResourceSize = UINT32_MAX,
|
.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;
|
return VK_SUCCESS;
|
||||||
unsupported:
|
unsupported:
|
||||||
*pImageFormatProperties = (VkImageFormatProperties) {
|
*pImageFormatProperties = (VkImageFormatProperties) {
|
||||||
|
|
@ -1316,7 +1503,7 @@ unsupported:
|
||||||
.maxResourceSize = 0,
|
.maxResourceSize = 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
return VK_ERROR_FORMAT_NOT_SUPPORTED;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
VkResult radv_GetPhysicalDeviceImageFormatProperties(
|
VkResult radv_GetPhysicalDeviceImageFormatProperties(
|
||||||
|
|
@ -1359,16 +1546,28 @@ get_external_image_format_properties(struct radv_physical_device *physical_devic
|
||||||
return;
|
return;
|
||||||
|
|
||||||
switch (handleType) {
|
switch (handleType) {
|
||||||
case VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT:
|
|
||||||
case VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT:
|
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;
|
||||||
|
|
||||||
|
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) {
|
switch (pImageFormatInfo->type) {
|
||||||
case VK_IMAGE_TYPE_2D:
|
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;
|
||||||
if (pImageFormatInfo->tiling != VK_IMAGE_TILING_LINEAR)
|
if (pImageFormatInfo->tiling != VK_IMAGE_TILING_LINEAR)
|
||||||
flags |= VK_EXTERNAL_MEMORY_FEATURE_DEDICATED_ONLY_BIT;
|
flags |= VK_EXTERNAL_MEMORY_FEATURE_DEDICATED_ONLY_BIT;
|
||||||
|
|
||||||
compat_flags = export_flags = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT |
|
compat_flags = export_flags = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT;
|
||||||
VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT;
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue