mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-20 05:10:11 +01:00
Merge branch 'pvr-mod-basic' into 'main'
Draft: pvr: preliminary EXT_image_drm_format_modifier support See merge request mesa/mesa!38991
This commit is contained in:
commit
28d85aab39
4 changed files with 162 additions and 8 deletions
|
|
@ -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"
|
||||
|
|
@ -437,6 +438,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,
|
||||
|
|
@ -466,6 +523,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;
|
||||
|
|
@ -492,6 +553,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) {
|
||||
|
|
@ -504,8 +566,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;
|
||||
|
|
@ -535,7 +611,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;
|
||||
}
|
||||
|
|
@ -566,7 +642,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;
|
||||
|
|
@ -620,7 +696,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,
|
||||
|
|
@ -686,6 +762,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_PER_ARCH(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"
|
||||
|
|
@ -61,10 +62,16 @@ 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_init_physical_extent(struct pvr_image *image,
|
||||
const VkImageCreateInfo *pCreateInfo,
|
||||
unsigned pbe_stride_align)
|
||||
{
|
||||
assert(image->memlayout != PVR_MEMLAYOUT_UNDEFINED);
|
||||
|
|
@ -92,6 +99,19 @@ static void pvr_image_init_physical_extent(struct pvr_image *image,
|
|||
image->physical_extent.width =
|
||||
align(image->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);
|
||||
image->physical_extent.width =
|
||||
explicit_mod->pPlaneLayouts[0].rowPitch / bpp;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -154,6 +174,47 @@ 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 (!util_is_aligned(explicit_mod->pPlaneLayouts[0].rowPitch,
|
||||
bpp * pbe_stride_align))
|
||||
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,
|
||||
|
|
@ -161,6 +222,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,
|
||||
|
|
@ -168,21 +233,32 @@ 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.
|
||||
*/
|
||||
image->alignment = 4096U;
|
||||
|
||||
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);
|
||||
|
|
|
|||
|
|
@ -175,6 +175,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,
|
||||
|
|
|
|||
|
|
@ -75,7 +75,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