mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-04-25 04:50:38 +02:00
pvr: preliminary EXT_image_drm_format_modifier support
Adds a trivial EXT_image_drm_format_modifier support that only handles LINEAR modifier. Signed-off-by: Icenowy Zheng <uwu@icenowy.me> Acked-by: Luigi Santivetti <luigi.santivetti@imgtec.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/38991>
This commit is contained in:
parent
cf68dc570b
commit
bed1576b14
6 changed files with 169 additions and 9 deletions
|
|
@ -639,7 +639,7 @@ Khronos extensions that are not part of any Vulkan version:
|
|||
VK_EXT_headless_surface DONE (anv, dzn, hasvk, hk, lvp, nvk, panvk, pvr, radv, tu, v3dv, vn)
|
||||
VK_EXT_image_2d_view_of_3d DONE (anv, hasvk, hk, lvp, nvk, panvk, pvr, radv, tu, vn)
|
||||
VK_EXT_image_compression_control DONE (anv/gfx12-, radv)
|
||||
VK_EXT_image_drm_format_modifier DONE (anv, hasvk, hk, lvp, nvk, panvk, radv/gfx9+, tu, v3dv, vn)
|
||||
VK_EXT_image_drm_format_modifier DONE (anv, hasvk, hk, lvp, nvk, panvk, pvr, radv/gfx9+, tu, v3dv, vn)
|
||||
VK_EXT_image_sliced_view_of_3d DONE (anv, hk, lvp, nvk, radv/gfx10+, vn)
|
||||
VK_EXT_image_view_min_lod DONE (anv, hasvk, hk, nvk, radv, tu, vn)
|
||||
VK_EXT_index_type_uint8 DONE (anv, hasvk, hk, nvk, lvp, panvk, pvr, radv/gfx8+, tu, v3dv, vn)
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
VK_QCOM_image_processing on Turnip
|
||||
VK_EXT_present_timing on RADV, NVK, Turnip, ANV, Honeykrisp, panvk
|
||||
VK_KHR_sampler_ycbcr_conversion on pvr
|
||||
VK_EXT_image_drm_format_modifier on pvr
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@
|
|||
#include <stdint.h>
|
||||
#include <vulkan/vulkan.h>
|
||||
|
||||
#include "drm-uapi/drm_fourcc.h"
|
||||
#include "hwdef/rogue_hw_utils.h"
|
||||
|
||||
#include "pvr_common.h"
|
||||
|
|
@ -452,6 +453,62 @@ pvr_get_buffer_format_features2(struct pvr_physical_device *pdevice,
|
|||
return flags;
|
||||
}
|
||||
|
||||
static void pvr_get_drm_format_modifier_properties_list(
|
||||
struct pvr_physical_device *pdevice,
|
||||
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;
|
||||
const VkFormatFeatureFlags2 linear_features =
|
||||
pvr_get_image_format_features2(pdevice, vk_format, VK_IMAGE_TILING_LINEAR);
|
||||
|
||||
/* We support LINEAR only yet */
|
||||
if (!linear_features) {
|
||||
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);
|
||||
|
||||
vk_outarray_append_typed(VkDrmFormatModifierPropertiesEXT, &out, mp) {
|
||||
mp->drmFormatModifier = DRM_FORMAT_MOD_LINEAR;
|
||||
mp->drmFormatModifierPlaneCount = 1;
|
||||
mp->drmFormatModifierTilingFeatures =
|
||||
vk_format_features2_to_features(linear_features);
|
||||
}
|
||||
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);
|
||||
|
||||
vk_outarray_append_typed(VkDrmFormatModifierProperties2EXT, &out, mp) {
|
||||
mp->drmFormatModifier = DRM_FORMAT_MOD_LINEAR;
|
||||
mp->drmFormatModifierPlaneCount = 1;
|
||||
mp->drmFormatModifierTilingFeatures = linear_features;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
UNREACHABLE("Invalid structure type for modifier properties");
|
||||
}
|
||||
}
|
||||
|
||||
void pvr_GetPhysicalDeviceFormatProperties2(
|
||||
VkPhysicalDevice physicalDevice,
|
||||
VkFormat format,
|
||||
|
|
@ -481,6 +538,10 @@ void pvr_GetPhysicalDeviceFormatProperties2(
|
|||
pFormatProperties3->bufferFeatures = buffer2;
|
||||
break;
|
||||
}
|
||||
case VK_STRUCTURE_TYPE_DRM_FORMAT_MODIFIER_PROPERTIES_LIST_EXT:
|
||||
case VK_STRUCTURE_TYPE_DRM_FORMAT_MODIFIER_PROPERTIES_LIST_2_EXT:
|
||||
pvr_get_drm_format_modifier_properties_list(pdevice, format, ext);
|
||||
break;
|
||||
default:
|
||||
vk_debug_ignored_stype(ext->sType);
|
||||
break;
|
||||
|
|
@ -534,6 +595,7 @@ pvr_get_image_format_properties(struct pvr_physical_device *pdevice,
|
|||
VkFormatFeatureFlags2 tiling_features2;
|
||||
VkImageUsageFlags usage =
|
||||
info->usage | (stencil_usage_info ? stencil_usage_info->stencilUsage : 0);
|
||||
VkImageTiling tiling = info->tiling;
|
||||
VkResult result;
|
||||
|
||||
if (!pvr_format) {
|
||||
|
|
@ -546,8 +608,22 @@ pvr_get_image_format_properties(struct pvr_physical_device *pdevice,
|
|||
goto err_unsupported_format;
|
||||
}
|
||||
|
||||
if (tiling == VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT) {
|
||||
const VkPhysicalDeviceImageDrmFormatModifierInfoEXT *drm_format_mod_info =
|
||||
vk_find_struct_const(info->pNext,
|
||||
PHYSICAL_DEVICE_IMAGE_DRM_FORMAT_MODIFIER_INFO_EXT);
|
||||
|
||||
if (drm_format_mod_info &&
|
||||
drm_format_mod_info->drmFormatModifier == DRM_FORMAT_MOD_LINEAR) {
|
||||
tiling = VK_IMAGE_TILING_LINEAR;
|
||||
} else {
|
||||
result = vk_error(pdevice, VK_ERROR_FORMAT_NOT_SUPPORTED);
|
||||
goto err_unsupported_format;
|
||||
}
|
||||
}
|
||||
|
||||
tiling_features2 =
|
||||
pvr_get_image_format_features2(pdevice, info->format, info->tiling);
|
||||
pvr_get_image_format_features2(pdevice, info->format, tiling);
|
||||
if (tiling_features2 == 0) {
|
||||
result = vk_error(pdevice, VK_ERROR_FORMAT_NOT_SUPPORTED);
|
||||
goto err_unsupported_format;
|
||||
|
|
@ -587,7 +663,7 @@ pvr_get_image_format_properties(struct pvr_physical_device *pdevice,
|
|||
/* Linear tiled 3D images may only be used for transfer or blit
|
||||
* operations.
|
||||
*/
|
||||
if (info->tiling == VK_IMAGE_TILING_LINEAR && usage & ~transfer_usage) {
|
||||
if (tiling == VK_IMAGE_TILING_LINEAR && usage & ~transfer_usage) {
|
||||
result = vk_error(pdevice, VK_ERROR_FORMAT_NOT_SUPPORTED);
|
||||
goto err_unsupported_format;
|
||||
}
|
||||
|
|
@ -618,7 +694,7 @@ pvr_get_image_format_properties(struct pvr_physical_device *pdevice,
|
|||
pImageFormatProperties->maxExtent.depth = max_render_size_z;
|
||||
}
|
||||
|
||||
if (info->tiling == VK_IMAGE_TILING_LINEAR) {
|
||||
if (tiling == VK_IMAGE_TILING_LINEAR) {
|
||||
pImageFormatProperties->maxExtent.depth = 1;
|
||||
pImageFormatProperties->maxArrayLayers = 1;
|
||||
pImageFormatProperties->sampleCounts = VK_SAMPLE_COUNT_1_BIT;
|
||||
|
|
@ -672,7 +748,7 @@ pvr_get_image_format_properties(struct pvr_physical_device *pdevice,
|
|||
* or VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT, so for simplicity don't
|
||||
* support miplevels for these tilings.
|
||||
*/
|
||||
if (info->tiling == VK_IMAGE_TILING_LINEAR) {
|
||||
if (tiling == VK_IMAGE_TILING_LINEAR) {
|
||||
pImageFormatProperties->maxMipLevels = 1;
|
||||
} else {
|
||||
const uint32_t max_size = MAX3(pImageFormatProperties->maxExtent.width,
|
||||
|
|
@ -738,6 +814,7 @@ VkResult pvr_GetPhysicalDeviceImageFormatProperties2(
|
|||
case VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO:
|
||||
break;
|
||||
case VK_STRUCTURE_TYPE_IMAGE_STENCIL_USAGE_CREATE_INFO:
|
||||
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_DRM_FORMAT_MODIFIER_INFO_EXT:
|
||||
/* Nothing to do here, it's handled in
|
||||
* pvr_get_image_format_properties)
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@
|
|||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "drm-uapi/drm_fourcc.h"
|
||||
#include "pvr_buffer.h"
|
||||
#include "pvr_device.h"
|
||||
#include "pvr_device_info.h"
|
||||
|
|
@ -62,11 +63,17 @@ static void pvr_image_init_memlayout(struct pvr_image *image)
|
|||
case VK_IMAGE_TILING_LINEAR:
|
||||
image->memlayout = PVR_MEMLAYOUT_LINEAR;
|
||||
break;
|
||||
case VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT:
|
||||
/* Support only LINEAR now */
|
||||
assert(image->vk.drm_format_mod == DRM_FORMAT_MOD_LINEAR);
|
||||
image->memlayout = PVR_MEMLAYOUT_LINEAR;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void pvr_image_plane_init_physical_extent(
|
||||
struct pvr_image *image,
|
||||
const VkImageCreateInfo *pCreateInfo,
|
||||
unsigned pbe_stride_align,
|
||||
const struct vk_format_ycbcr_info *ycbcr_info,
|
||||
uint8_t i)
|
||||
|
|
@ -95,6 +102,19 @@ static void pvr_image_plane_init_physical_extent(
|
|||
plane->physical_extent.width =
|
||||
align(plane->physical_extent.width, pbe_stride_align);
|
||||
}
|
||||
|
||||
if (image->vk.tiling == VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT) {
|
||||
const VkImageDrmFormatModifierExplicitCreateInfoEXT *explicit_mod =
|
||||
vk_find_struct_const(
|
||||
pCreateInfo->pNext,
|
||||
IMAGE_DRM_FORMAT_MODIFIER_EXPLICIT_CREATE_INFO_EXT);
|
||||
if (explicit_mod) {
|
||||
const uint32_t bpp =
|
||||
vk_format_get_blocksize(image->vk.format);
|
||||
plane->physical_extent.width =
|
||||
explicit_mod->pPlaneLayouts[i].rowPitch / bpp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ycbcr_info) {
|
||||
|
|
@ -106,6 +126,7 @@ static void pvr_image_plane_init_physical_extent(
|
|||
}
|
||||
|
||||
static void pvr_image_init_physical_extent(struct pvr_image *image,
|
||||
const VkImageCreateInfo *pCreateInfo,
|
||||
unsigned pbe_stride_align)
|
||||
{
|
||||
assert(image->memlayout != PVR_MEMLAYOUT_UNDEFINED);
|
||||
|
|
@ -115,6 +136,7 @@ static void pvr_image_init_physical_extent(struct pvr_image *image,
|
|||
|
||||
for (uint8_t plane = 0; plane < image->plane_count; plane++) {
|
||||
pvr_image_plane_init_physical_extent(image,
|
||||
pCreateInfo,
|
||||
pbe_stride_align,
|
||||
ycbcr_info,
|
||||
plane);
|
||||
|
|
@ -197,6 +219,50 @@ static void pvr_image_setup_mip_levels(struct pvr_image *image)
|
|||
|
||||
static unsigned get_pbe_stride_align(const struct pvr_device_info *dev_info);
|
||||
|
||||
static VkResult pvr_pick_modifier(const VkImageCreateInfo *pCreateInfo,
|
||||
unsigned pbe_stride_align,
|
||||
uint64_t *modifier)
|
||||
{
|
||||
const VkImageDrmFormatModifierListCreateInfoEXT *mod_list =
|
||||
vk_find_struct_const(pCreateInfo->pNext,
|
||||
IMAGE_DRM_FORMAT_MODIFIER_LIST_CREATE_INFO_EXT);
|
||||
|
||||
const VkImageDrmFormatModifierExplicitCreateInfoEXT *explicit_mod =
|
||||
vk_find_struct_const(
|
||||
pCreateInfo->pNext,
|
||||
IMAGE_DRM_FORMAT_MODIFIER_EXPLICIT_CREATE_INFO_EXT);
|
||||
|
||||
/* Only support LINEAR now */
|
||||
*modifier = DRM_FORMAT_MOD_INVALID;
|
||||
|
||||
if (mod_list)
|
||||
for (unsigned i = 0; i < mod_list->drmFormatModifierCount; i++)
|
||||
if (mod_list->pDrmFormatModifiers[i] == DRM_FORMAT_MOD_LINEAR)
|
||||
*modifier = DRM_FORMAT_MOD_LINEAR;
|
||||
|
||||
if (explicit_mod) {
|
||||
const uint32_t bpp = vk_format_get_blocksize(pCreateInfo->format);
|
||||
assert(explicit_mod->drmFormatModifier == DRM_FORMAT_MOD_LINEAR &&
|
||||
explicit_mod->drmFormatModifierPlaneCount == 1);
|
||||
*modifier = explicit_mod->drmFormatModifier;
|
||||
|
||||
if (explicit_mod->pPlaneLayouts[0].offset != 0)
|
||||
return VK_ERROR_INVALID_DRM_FORMAT_MODIFIER_PLANE_LAYOUT_EXT;
|
||||
|
||||
if (explicit_mod->pPlaneLayouts[0].rowPitch %
|
||||
(bpp * pbe_stride_align) != 0) {
|
||||
return VK_ERROR_INVALID_DRM_FORMAT_MODIFIER_PLANE_LAYOUT_EXT;
|
||||
}
|
||||
|
||||
if (explicit_mod->pPlaneLayouts[0].rowPitch <
|
||||
pCreateInfo->extent.width * bpp) {
|
||||
return VK_ERROR_INVALID_DRM_FORMAT_MODIFIER_PLANE_LAYOUT_EXT;
|
||||
}
|
||||
}
|
||||
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
VkResult pvr_CreateImage(VkDevice _device,
|
||||
const VkImageCreateInfo *pCreateInfo,
|
||||
const VkAllocationCallbacks *pAllocator,
|
||||
|
|
@ -204,6 +270,10 @@ VkResult pvr_CreateImage(VkDevice _device,
|
|||
{
|
||||
VK_FROM_HANDLE(pvr_device, device, _device);
|
||||
struct pvr_image *image;
|
||||
uint64_t modifier = DRM_FORMAT_MOD_INVALID;
|
||||
VkResult res;
|
||||
|
||||
unsigned pbe_stride_align = get_pbe_stride_align(&device->pdevice->dev_info);
|
||||
|
||||
if (wsi_common_is_swapchain_image(pCreateInfo)) {
|
||||
return wsi_common_create_swapchain_image(&device->pdevice->wsi_device,
|
||||
|
|
@ -211,11 +281,24 @@ VkResult pvr_CreateImage(VkDevice _device,
|
|||
pImage);
|
||||
}
|
||||
|
||||
if (pCreateInfo->tiling == VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT) {
|
||||
res = pvr_pick_modifier(pCreateInfo, pbe_stride_align,
|
||||
&modifier);
|
||||
if (res != VK_SUCCESS)
|
||||
return vk_error(device, res);
|
||||
|
||||
assert(modifier == DRM_FORMAT_MOD_LINEAR);
|
||||
}
|
||||
|
||||
image =
|
||||
vk_image_create(&device->vk, pCreateInfo, pAllocator, sizeof(*image));
|
||||
if (!image)
|
||||
return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
|
||||
|
||||
if (image->vk.tiling == VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT) {
|
||||
image->vk.drm_format_mod = modifier;
|
||||
}
|
||||
|
||||
/* All images aligned to 4k, in case of arrays/CEM.
|
||||
* Refer: pvr_GetImageMemoryRequirements for further details.
|
||||
*/
|
||||
|
|
@ -223,11 +306,9 @@ VkResult pvr_CreateImage(VkDevice _device,
|
|||
|
||||
image->plane_count = vk_format_get_plane_count(image->vk.format);
|
||||
|
||||
unsigned pbe_stride_align = get_pbe_stride_align(&device->pdevice->dev_info);
|
||||
|
||||
/* Initialize the image using the saved information from pCreateInfo */
|
||||
pvr_image_init_memlayout(image);
|
||||
pvr_image_init_physical_extent(image, pbe_stride_align);
|
||||
pvr_image_init_physical_extent(image, pCreateInfo, pbe_stride_align);
|
||||
pvr_image_setup_mip_levels(image);
|
||||
|
||||
*pImage = pvr_image_to_handle(image);
|
||||
|
|
|
|||
|
|
@ -177,6 +177,7 @@ static void pvr_physical_device_get_supported_extensions(
|
|||
.EXT_custom_border_color = true,
|
||||
.EXT_depth_clamp_zero_one = true,
|
||||
.EXT_depth_clip_enable = true,
|
||||
.EXT_image_drm_format_modifier = true,
|
||||
.EXT_extended_dynamic_state = true,
|
||||
.EXT_extended_dynamic_state2 = true,
|
||||
.EXT_extended_dynamic_state3 = true,
|
||||
|
|
|
|||
|
|
@ -79,7 +79,7 @@ VkResult pvr_wsi_init(struct pvr_physical_device *pdevice)
|
|||
if (result != VK_SUCCESS)
|
||||
return result;
|
||||
|
||||
pdevice->wsi_device.supports_modifiers = false;
|
||||
pdevice->wsi_device.supports_modifiers = true;
|
||||
pdevice->wsi_device.can_present_on_device = pvr_can_present_on_device;
|
||||
pdevice->vk.wsi_device = &pdevice->wsi_device;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue