mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-20 11:40:10 +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 <stdint.h>
|
||||||
#include <vulkan/vulkan.h>
|
#include <vulkan/vulkan.h>
|
||||||
|
|
||||||
|
#include "drm-uapi/drm_fourcc.h"
|
||||||
#include "hwdef/rogue_hw_utils.h"
|
#include "hwdef/rogue_hw_utils.h"
|
||||||
|
|
||||||
#include "pvr_common.h"
|
#include "pvr_common.h"
|
||||||
|
|
@ -437,6 +438,62 @@ pvr_get_buffer_format_features2(struct pvr_physical_device *pdevice,
|
||||||
return flags;
|
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(
|
void pvr_GetPhysicalDeviceFormatProperties2(
|
||||||
VkPhysicalDevice physicalDevice,
|
VkPhysicalDevice physicalDevice,
|
||||||
VkFormat format,
|
VkFormat format,
|
||||||
|
|
@ -466,6 +523,10 @@ void pvr_GetPhysicalDeviceFormatProperties2(
|
||||||
pFormatProperties3->bufferFeatures = buffer2;
|
pFormatProperties3->bufferFeatures = buffer2;
|
||||||
break;
|
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:
|
default:
|
||||||
vk_debug_ignored_stype(ext->sType);
|
vk_debug_ignored_stype(ext->sType);
|
||||||
break;
|
break;
|
||||||
|
|
@ -492,6 +553,7 @@ pvr_get_image_format_properties(struct pvr_physical_device *pdevice,
|
||||||
VkFormatFeatureFlags2 tiling_features2;
|
VkFormatFeatureFlags2 tiling_features2;
|
||||||
VkImageUsageFlags usage =
|
VkImageUsageFlags usage =
|
||||||
info->usage | (stencil_usage_info ? stencil_usage_info->stencilUsage : 0);
|
info->usage | (stencil_usage_info ? stencil_usage_info->stencilUsage : 0);
|
||||||
|
VkImageTiling tiling = info->tiling;
|
||||||
VkResult result;
|
VkResult result;
|
||||||
|
|
||||||
if (!pvr_format) {
|
if (!pvr_format) {
|
||||||
|
|
@ -504,8 +566,22 @@ pvr_get_image_format_properties(struct pvr_physical_device *pdevice,
|
||||||
goto err_unsupported_format;
|
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 =
|
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) {
|
if (tiling_features2 == 0) {
|
||||||
result = vk_error(pdevice, VK_ERROR_FORMAT_NOT_SUPPORTED);
|
result = vk_error(pdevice, VK_ERROR_FORMAT_NOT_SUPPORTED);
|
||||||
goto err_unsupported_format;
|
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
|
/* Linear tiled 3D images may only be used for transfer or blit
|
||||||
* operations.
|
* 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);
|
result = vk_error(pdevice, VK_ERROR_FORMAT_NOT_SUPPORTED);
|
||||||
goto err_unsupported_format;
|
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;
|
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->maxExtent.depth = 1;
|
||||||
pImageFormatProperties->maxArrayLayers = 1;
|
pImageFormatProperties->maxArrayLayers = 1;
|
||||||
pImageFormatProperties->sampleCounts = VK_SAMPLE_COUNT_1_BIT;
|
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
|
* or VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT, so for simplicity don't
|
||||||
* support miplevels for these tilings.
|
* support miplevels for these tilings.
|
||||||
*/
|
*/
|
||||||
if (info->tiling == VK_IMAGE_TILING_LINEAR) {
|
if (tiling == VK_IMAGE_TILING_LINEAR) {
|
||||||
pImageFormatProperties->maxMipLevels = 1;
|
pImageFormatProperties->maxMipLevels = 1;
|
||||||
} else {
|
} else {
|
||||||
const uint32_t max_size = MAX3(pImageFormatProperties->maxExtent.width,
|
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:
|
case VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO:
|
||||||
break;
|
break;
|
||||||
case VK_STRUCTURE_TYPE_IMAGE_STENCIL_USAGE_CREATE_INFO:
|
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
|
/* Nothing to do here, it's handled in
|
||||||
* PVR_PER_ARCH(get_image_format_properties)
|
* PVR_PER_ARCH(get_image_format_properties)
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,7 @@
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "drm-uapi/drm_fourcc.h"
|
||||||
#include "pvr_buffer.h"
|
#include "pvr_buffer.h"
|
||||||
#include "pvr_device.h"
|
#include "pvr_device.h"
|
||||||
#include "pvr_device_info.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:
|
case VK_IMAGE_TILING_LINEAR:
|
||||||
image->memlayout = PVR_MEMLAYOUT_LINEAR;
|
image->memlayout = PVR_MEMLAYOUT_LINEAR;
|
||||||
break;
|
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,
|
static void pvr_image_init_physical_extent(struct pvr_image *image,
|
||||||
|
const VkImageCreateInfo *pCreateInfo,
|
||||||
unsigned pbe_stride_align)
|
unsigned pbe_stride_align)
|
||||||
{
|
{
|
||||||
assert(image->memlayout != PVR_MEMLAYOUT_UNDEFINED);
|
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 =
|
image->physical_extent.width =
|
||||||
align(image->physical_extent.width, pbe_stride_align);
|
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 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,
|
VkResult pvr_CreateImage(VkDevice _device,
|
||||||
const VkImageCreateInfo *pCreateInfo,
|
const VkImageCreateInfo *pCreateInfo,
|
||||||
const VkAllocationCallbacks *pAllocator,
|
const VkAllocationCallbacks *pAllocator,
|
||||||
|
|
@ -161,6 +222,10 @@ VkResult pvr_CreateImage(VkDevice _device,
|
||||||
{
|
{
|
||||||
VK_FROM_HANDLE(pvr_device, device, _device);
|
VK_FROM_HANDLE(pvr_device, device, _device);
|
||||||
struct pvr_image *image;
|
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)) {
|
if (wsi_common_is_swapchain_image(pCreateInfo)) {
|
||||||
return wsi_common_create_swapchain_image(&device->pdevice->wsi_device,
|
return wsi_common_create_swapchain_image(&device->pdevice->wsi_device,
|
||||||
|
|
@ -168,21 +233,32 @@ VkResult pvr_CreateImage(VkDevice _device,
|
||||||
pImage);
|
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 =
|
image =
|
||||||
vk_image_create(&device->vk, pCreateInfo, pAllocator, sizeof(*image));
|
vk_image_create(&device->vk, pCreateInfo, pAllocator, sizeof(*image));
|
||||||
if (!image)
|
if (!image)
|
||||||
return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
|
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.
|
/* All images aligned to 4k, in case of arrays/CEM.
|
||||||
* Refer: pvr_GetImageMemoryRequirements for further details.
|
* Refer: pvr_GetImageMemoryRequirements for further details.
|
||||||
*/
|
*/
|
||||||
image->alignment = 4096U;
|
image->alignment = 4096U;
|
||||||
|
|
||||||
unsigned pbe_stride_align = get_pbe_stride_align(&device->pdevice->dev_info);
|
|
||||||
|
|
||||||
/* Initialize the image using the saved information from pCreateInfo */
|
/* Initialize the image using the saved information from pCreateInfo */
|
||||||
pvr_image_init_memlayout(image);
|
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);
|
pvr_image_setup_mip_levels(image);
|
||||||
|
|
||||||
*pImage = pvr_image_to_handle(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_custom_border_color = true,
|
||||||
.EXT_depth_clamp_zero_one = true,
|
.EXT_depth_clamp_zero_one = true,
|
||||||
.EXT_depth_clip_enable = true,
|
.EXT_depth_clip_enable = true,
|
||||||
|
.EXT_image_drm_format_modifier = true,
|
||||||
.EXT_extended_dynamic_state = true,
|
.EXT_extended_dynamic_state = true,
|
||||||
.EXT_extended_dynamic_state2 = true,
|
.EXT_extended_dynamic_state2 = true,
|
||||||
.EXT_extended_dynamic_state3 = true,
|
.EXT_extended_dynamic_state3 = true,
|
||||||
|
|
|
||||||
|
|
@ -75,7 +75,7 @@ VkResult pvr_wsi_init(struct pvr_physical_device *pdevice)
|
||||||
if (result != VK_SUCCESS)
|
if (result != VK_SUCCESS)
|
||||||
return result;
|
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->wsi_device.can_present_on_device = pvr_can_present_on_device;
|
||||||
pdevice->vk.wsi_device = &pdevice->wsi_device;
|
pdevice->vk.wsi_device = &pdevice->wsi_device;
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue