mirror of https://gitlab.freedesktop.org/mesa/mesa
nvk: Implement DRM format modifier queries
Reviewed-by: Dave Airlie <airlied@redhat.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/24795>
This commit is contained in:
parent
4ad79bfef4
commit
224d9a514a
|
@ -161,9 +161,9 @@ nvk_GetPhysicalDeviceFormatProperties2(VkPhysicalDevice physicalDevice,
|
|||
|
||||
VkFormatFeatureFlags2 linear2, optimal2, buffer2;
|
||||
linear2 = nvk_get_image_format_features(pdevice, format,
|
||||
VK_IMAGE_TILING_LINEAR);
|
||||
VK_IMAGE_TILING_LINEAR, 0);
|
||||
optimal2 = nvk_get_image_format_features(pdevice, format,
|
||||
VK_IMAGE_TILING_OPTIMAL);
|
||||
VK_IMAGE_TILING_OPTIMAL, 0);
|
||||
buffer2 = nvk_get_buffer_format_features(pdevice, format);
|
||||
|
||||
pFormatProperties->formatProperties = (VkFormatProperties) {
|
||||
|
@ -182,6 +182,11 @@ nvk_GetPhysicalDeviceFormatProperties2(VkPhysicalDevice physicalDevice,
|
|||
break;
|
||||
}
|
||||
|
||||
case VK_STRUCTURE_TYPE_DRM_FORMAT_MODIFIER_PROPERTIES_LIST_EXT:
|
||||
case VK_STRUCTURE_TYPE_DRM_FORMAT_MODIFIER_PROPERTIES_LIST_2_EXT:
|
||||
nvk_get_drm_format_modifier_properties_list(pdevice, format, ext);
|
||||
break;
|
||||
|
||||
default:
|
||||
vk_debug_ignored_stype(ext->sType);
|
||||
break;
|
||||
|
|
|
@ -12,6 +12,9 @@
|
|||
|
||||
#include "vk_enum_to_str.h"
|
||||
#include "vk_format.h"
|
||||
#include "nil.h"
|
||||
#include "vk_enum_defines.h"
|
||||
#include "vk_format.h"
|
||||
|
||||
#include "clb097.h"
|
||||
#include "clb197.h"
|
||||
|
@ -19,10 +22,16 @@
|
|||
|
||||
static VkFormatFeatureFlags2
|
||||
nvk_get_image_plane_format_features(struct nvk_physical_device *pdev,
|
||||
VkFormat vk_format, VkImageTiling tiling)
|
||||
VkFormat vk_format, VkImageTiling tiling,
|
||||
uint64_t drm_format_mod)
|
||||
{
|
||||
VkFormatFeatureFlags2 features = 0;
|
||||
|
||||
if (tiling == VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT &&
|
||||
drm_format_mod != DRM_FORMAT_MOD_LINEAR &&
|
||||
!fourcc_mod_is_vendor(drm_format_mod, NVIDIA))
|
||||
return 0;
|
||||
|
||||
enum pipe_format p_format = vk_format_to_pipe_format(vk_format);
|
||||
if (p_format == PIPE_FORMAT_NONE)
|
||||
return 0;
|
||||
|
@ -84,12 +93,15 @@ nvk_get_image_plane_format_features(struct nvk_physical_device *pdev,
|
|||
|
||||
VkFormatFeatureFlags2
|
||||
nvk_get_image_format_features(struct nvk_physical_device *pdev,
|
||||
VkFormat vk_format, VkImageTiling tiling)
|
||||
VkFormat vk_format, VkImageTiling tiling,
|
||||
uint64_t drm_format_mod)
|
||||
{
|
||||
const struct vk_format_ycbcr_info *ycbcr_info =
|
||||
vk_format_get_ycbcr_info(vk_format);
|
||||
if (ycbcr_info == NULL)
|
||||
return nvk_get_image_plane_format_features(pdev, vk_format, tiling);
|
||||
if (ycbcr_info == NULL) {
|
||||
return nvk_get_image_plane_format_features(pdev, vk_format, tiling,
|
||||
drm_format_mod);
|
||||
}
|
||||
|
||||
/* For multi-plane, we get the feature flags of each plane separately,
|
||||
* then take their intersection as the overall format feature flags
|
||||
|
@ -99,7 +111,7 @@ nvk_get_image_format_features(struct nvk_physical_device *pdev,
|
|||
for (uint8_t plane = 0; plane < ycbcr_info->n_planes; plane++) {
|
||||
const struct vk_format_ycbcr_plane *plane_info = &ycbcr_info->planes[plane];
|
||||
features &= nvk_get_image_plane_format_features(pdev, plane_info->format,
|
||||
tiling);
|
||||
tiling, drm_format_mod);
|
||||
if (plane_info->denominator_scales[0] > 1 ||
|
||||
plane_info->denominator_scales[1] > 1)
|
||||
cosited_chroma = true;
|
||||
|
@ -143,6 +155,98 @@ nvk_get_image_format_features(struct nvk_physical_device *pdev,
|
|||
return features;
|
||||
}
|
||||
|
||||
void
|
||||
nvk_get_drm_format_modifier_properties_list(struct nvk_physical_device *pdev,
|
||||
VkFormat vk_format,
|
||||
VkBaseOutStructure *ext)
|
||||
{
|
||||
assert(ext->sType == VK_STRUCTURE_TYPE_DRM_FORMAT_MODIFIER_PROPERTIES_LIST_EXT ||
|
||||
ext->sType == VK_STRUCTURE_TYPE_DRM_FORMAT_MODIFIER_PROPERTIES_LIST_2_EXT);
|
||||
|
||||
/* The two top-level data structures are the same. It's only when
|
||||
* you get to walking the actual list of modifier properties that
|
||||
* they differ.
|
||||
*/
|
||||
VkDrmFormatModifierPropertiesListEXT *p = (void *)ext;
|
||||
|
||||
/* We don't support modifiers for YCbCr images */
|
||||
if (vk_format_get_ycbcr_info(vk_format) != NULL) {
|
||||
p->drmFormatModifierCount = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Check that we actually support the format so we don't try to query
|
||||
* modifiers for formats NIL doesn't support.
|
||||
*/
|
||||
const VkFormatFeatureFlags2 tiled_features =
|
||||
nvk_get_image_plane_format_features(pdev, vk_format,
|
||||
VK_IMAGE_TILING_OPTIMAL,
|
||||
DRM_FORMAT_MOD_INVALID);
|
||||
if (tiled_features == 0) {
|
||||
p->drmFormatModifierCount = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
uint64_t mods[NIL_MAX_DRM_FORMAT_MODS];
|
||||
size_t mod_count = NIL_MAX_DRM_FORMAT_MODS;
|
||||
enum pipe_format p_format = vk_format_to_pipe_format(vk_format);
|
||||
nil_drm_format_mods_for_format(&pdev->info, nil_format(p_format),
|
||||
&mod_count, &mods);
|
||||
if (mod_count == 0) {
|
||||
p->drmFormatModifierCount = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
switch (ext->sType) {
|
||||
case VK_STRUCTURE_TYPE_DRM_FORMAT_MODIFIER_PROPERTIES_LIST_EXT: {
|
||||
VK_OUTARRAY_MAKE_TYPED(VkDrmFormatModifierPropertiesEXT, out,
|
||||
p->pDrmFormatModifierProperties,
|
||||
&p->drmFormatModifierCount);
|
||||
|
||||
for (uint32_t i = 0; i < mod_count; i++) {
|
||||
const VkFormatFeatureFlags2 features2 =
|
||||
nvk_get_image_format_features(pdev, vk_format,
|
||||
VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT,
|
||||
mods[i]);
|
||||
if (features2 != 0) {
|
||||
vk_outarray_append_typed(VkDrmFormatModifierPropertiesEXT, &out, mp) {
|
||||
mp->drmFormatModifier = mods[i];
|
||||
mp->drmFormatModifierPlaneCount = 1;
|
||||
mp->drmFormatModifierTilingFeatures =
|
||||
vk_format_features2_to_features(features2);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case VK_STRUCTURE_TYPE_DRM_FORMAT_MODIFIER_PROPERTIES_LIST_2_EXT: {
|
||||
VkDrmFormatModifierPropertiesList2EXT *p2 = (void *)p;
|
||||
VK_OUTARRAY_MAKE_TYPED(VkDrmFormatModifierProperties2EXT, out,
|
||||
p2->pDrmFormatModifierProperties,
|
||||
&p2->drmFormatModifierCount);
|
||||
|
||||
for (uint32_t i = 0; i < mod_count; i++) {
|
||||
const VkFormatFeatureFlags2 features2 =
|
||||
nvk_get_image_format_features(pdev, vk_format,
|
||||
VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT,
|
||||
mods[i]);
|
||||
if (features2 != 0) {
|
||||
vk_outarray_append_typed(VkDrmFormatModifierProperties2EXT, &out, mp) {
|
||||
mp->drmFormatModifier = mods[i];
|
||||
mp->drmFormatModifierPlaneCount = 1;
|
||||
mp->drmFormatModifierTilingFeatures = features2;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
unreachable("Invalid structure type");
|
||||
}
|
||||
}
|
||||
|
||||
static VkFormatFeatureFlags2
|
||||
vk_image_usage_to_format_features(VkImageUsageFlagBits usage_flag)
|
||||
{
|
||||
|
@ -182,6 +286,18 @@ nvk_image_max_dimension(const struct nv_device_info *info,
|
|||
}
|
||||
}
|
||||
|
||||
static uint64_t
|
||||
get_explicit_drm_format_mod(const void *pNext)
|
||||
{
|
||||
const VkPhysicalDeviceImageDrmFormatModifierInfoEXT *drm_format_mod_info =
|
||||
vk_find_struct_const(pNext,
|
||||
PHYSICAL_DEVICE_IMAGE_DRM_FORMAT_MODIFIER_INFO_EXT);
|
||||
if (drm_format_mod_info)
|
||||
return drm_format_mod_info->drmFormatModifier;
|
||||
else
|
||||
return DRM_FORMAT_MOD_INVALID;
|
||||
}
|
||||
|
||||
VKAPI_ATTR VkResult VKAPI_CALL
|
||||
nvk_GetPhysicalDeviceImageFormatProperties2(
|
||||
VkPhysicalDevice physicalDevice,
|
||||
|
@ -198,6 +314,8 @@ nvk_GetPhysicalDeviceImageFormatProperties2(
|
|||
memset(&pImageFormatProperties->imageFormatProperties, 0,
|
||||
sizeof(pImageFormatProperties->imageFormatProperties));
|
||||
|
||||
uint64_t drm_format_mod =
|
||||
get_explicit_drm_format_mod(pImageFormatInfo->pNext);
|
||||
const struct vk_format_ycbcr_info *ycbcr_info =
|
||||
vk_format_get_ycbcr_info(pImageFormatInfo->format);
|
||||
|
||||
|
@ -208,16 +326,18 @@ nvk_GetPhysicalDeviceImageFormatProperties2(
|
|||
VkFormatFeatureFlags2 features;
|
||||
if (ycbcr_info == NULL) {
|
||||
features = nvk_get_image_plane_format_features(
|
||||
pdev, pImageFormatInfo->format, pImageFormatInfo->tiling);
|
||||
pdev, pImageFormatInfo->format, pImageFormatInfo->tiling,
|
||||
drm_format_mod);
|
||||
} else {
|
||||
features = ~0ull;
|
||||
assert(ycbcr_info->n_planes > 0);
|
||||
for (uint8_t plane = 0; plane < ycbcr_info->n_planes; plane++) {
|
||||
const VkFormat plane_format = ycbcr_info->planes[plane].format;
|
||||
features &= nvk_get_image_plane_format_features(
|
||||
pdev, plane_format, pImageFormatInfo->tiling);
|
||||
pdev, plane_format, pImageFormatInfo->tiling, drm_format_mod);
|
||||
}
|
||||
}
|
||||
|
||||
if (features == 0)
|
||||
return VK_ERROR_FORMAT_NOT_SUPPORTED;
|
||||
|
||||
|
@ -624,7 +744,7 @@ nvk_image_init(struct nvk_device *dev,
|
|||
struct nil_image_init_info nil_info = {
|
||||
.dim = vk_image_type_to_nil_dim(pCreateInfo->imageType),
|
||||
.format = nil_format(vk_format_to_pipe_format(format)),
|
||||
.modifier = DRM_FORMAT_MOD_INVALID,
|
||||
.modifier = image->vk.drm_format_mod,
|
||||
.extent_px = {
|
||||
.width = pCreateInfo->extent.width / width_scale,
|
||||
.height = pCreateInfo->extent.height / height_scale,
|
||||
|
|
|
@ -37,13 +37,15 @@
|
|||
struct nvk_device_memory;
|
||||
struct nvk_physical_device;
|
||||
|
||||
static VkFormatFeatureFlags2
|
||||
nvk_get_image_plane_format_features(struct nvk_physical_device *pdev,
|
||||
VkFormat vk_format, VkImageTiling tiling);
|
||||
|
||||
VkFormatFeatureFlags2
|
||||
nvk_get_image_format_features(struct nvk_physical_device *pdevice,
|
||||
VkFormat format, VkImageTiling tiling);
|
||||
VkFormat format, VkImageTiling tiling,
|
||||
uint64_t drm_format_mod);
|
||||
|
||||
void
|
||||
nvk_get_drm_format_modifier_properties_list(struct nvk_physical_device *pdev,
|
||||
VkFormat vk_format,
|
||||
VkBaseOutStructure *ext);
|
||||
|
||||
uint32_t
|
||||
nvk_image_max_dimension(const struct nv_device_info *info,
|
||||
|
|
Loading…
Reference in New Issue