tu: Implement GetDevice*MemoryRequirements()

Based mostly on anv, which is a bit more optimized than radv - we at
allocate the image on the stack.

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/15488>
This commit is contained in:
Connor Abbott 2022-03-18 14:13:47 +01:00 committed by Marge Bot
parent c42da6dd60
commit d1762b7df0
2 changed files with 159 additions and 98 deletions

View File

@ -2270,18 +2270,14 @@ tu_InvalidateMappedMemoryRanges(VkDevice _device,
return VK_SUCCESS;
}
VKAPI_ATTR void VKAPI_CALL
tu_GetBufferMemoryRequirements2(
VkDevice device,
const VkBufferMemoryRequirementsInfo2 *pInfo,
VkMemoryRequirements2 *pMemoryRequirements)
static void
tu_get_buffer_memory_requirements(uint64_t size,
VkMemoryRequirements2 *pMemoryRequirements)
{
TU_FROM_HANDLE(tu_buffer, buffer, pInfo->buffer);
pMemoryRequirements->memoryRequirements = (VkMemoryRequirements) {
.memoryTypeBits = 1,
.alignment = 64,
.size = MAX2(align64(buffer->size, 64), buffer->size),
.size = MAX2(align64(size, 64), size),
};
vk_foreach_struct(ext, pMemoryRequirements->pNext) {
@ -2300,41 +2296,23 @@ tu_GetBufferMemoryRequirements2(
}
VKAPI_ATTR void VKAPI_CALL
tu_GetImageMemoryRequirements2(VkDevice device,
const VkImageMemoryRequirementsInfo2 *pInfo,
VkMemoryRequirements2 *pMemoryRequirements)
tu_GetBufferMemoryRequirements2(
VkDevice device,
const VkBufferMemoryRequirementsInfo2 *pInfo,
VkMemoryRequirements2 *pMemoryRequirements)
{
TU_FROM_HANDLE(tu_image, image, pInfo->image);
TU_FROM_HANDLE(tu_buffer, buffer, pInfo->buffer);
pMemoryRequirements->memoryRequirements = (VkMemoryRequirements) {
.memoryTypeBits = 1,
.alignment = image->layout[0].base_align,
.size = image->total_size
};
vk_foreach_struct(ext, pMemoryRequirements->pNext) {
switch (ext->sType) {
case VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS: {
VkMemoryDedicatedRequirements *req =
(VkMemoryDedicatedRequirements *) ext;
req->requiresDedicatedAllocation = image->shareable;
req->prefersDedicatedAllocation = req->requiresDedicatedAllocation;
break;
}
default:
break;
}
}
tu_get_buffer_memory_requirements(buffer->size, pMemoryRequirements);
}
VKAPI_ATTR void VKAPI_CALL
tu_GetImageSparseMemoryRequirements2(
tu_GetDeviceBufferMemoryRequirements(
VkDevice device,
const VkImageSparseMemoryRequirementsInfo2 *pInfo,
uint32_t *pSparseMemoryRequirementCount,
VkSparseImageMemoryRequirements2 *pSparseMemoryRequirements)
const VkDeviceBufferMemoryRequirements *pInfo,
VkMemoryRequirements2 *pMemoryRequirements)
{
tu_stub();
tu_get_buffer_memory_requirements(pInfo->pCreateInfo->size, pMemoryRequirements);
}
VKAPI_ATTR void VKAPI_CALL

View File

@ -322,62 +322,11 @@ ubwc_possible(VkFormat format, VkImageType type, VkImageUsageFlags usage,
return true;
}
VKAPI_ATTR VkResult VKAPI_CALL
tu_CreateImage(VkDevice _device,
const VkImageCreateInfo *pCreateInfo,
const VkAllocationCallbacks *alloc,
VkImage *pImage)
static VkResult
tu_image_init(struct tu_device *device, struct tu_image *image,
const VkImageCreateInfo *pCreateInfo, uint64_t modifier,
const VkSubresourceLayout *plane_layouts)
{
TU_FROM_HANDLE(tu_device, device, _device);
uint64_t modifier = DRM_FORMAT_MOD_INVALID;
const VkSubresourceLayout *plane_layouts = NULL;
struct tu_image *image;
if (pCreateInfo->tiling == VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT) {
const VkImageDrmFormatModifierListCreateInfoEXT *mod_info =
vk_find_struct_const(pCreateInfo->pNext,
IMAGE_DRM_FORMAT_MODIFIER_LIST_CREATE_INFO_EXT);
const VkImageDrmFormatModifierExplicitCreateInfoEXT *drm_explicit_info =
vk_find_struct_const(pCreateInfo->pNext,
IMAGE_DRM_FORMAT_MODIFIER_EXPLICIT_CREATE_INFO_EXT);
assert(mod_info || drm_explicit_info);
if (mod_info) {
modifier = DRM_FORMAT_MOD_LINEAR;
for (unsigned i = 0; i < mod_info->drmFormatModifierCount; i++) {
if (mod_info->pDrmFormatModifiers[i] == DRM_FORMAT_MOD_QCOM_COMPRESSED)
modifier = DRM_FORMAT_MOD_QCOM_COMPRESSED;
}
} else {
modifier = drm_explicit_info->drmFormatModifier;
assert(modifier == DRM_FORMAT_MOD_LINEAR ||
modifier == DRM_FORMAT_MOD_QCOM_COMPRESSED);
plane_layouts = drm_explicit_info->pPlaneLayouts;
}
} else {
const struct wsi_image_create_info *wsi_info =
vk_find_struct_const(pCreateInfo->pNext, WSI_IMAGE_CREATE_INFO_MESA);
if (wsi_info && wsi_info->scanout)
modifier = DRM_FORMAT_MOD_LINEAR;
}
#ifdef ANDROID
const VkNativeBufferANDROID *gralloc_info =
vk_find_struct_const(pCreateInfo->pNext, NATIVE_BUFFER_ANDROID);
int dma_buf;
if (gralloc_info) {
VkResult result = tu_gralloc_info(device, gralloc_info, &dma_buf, &modifier);
if (result != VK_SUCCESS)
return result;
}
#endif
image = vk_object_zalloc(&device->vk, alloc, sizeof(*image),
VK_OBJECT_TYPE_IMAGE);
if (!image)
return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
const VkExternalMemoryImageCreateInfo *external_info =
vk_find_struct_const(pCreateInfo->pNext, EXTERNAL_MEMORY_IMAGE_CREATE_INFO);
image->shareable = external_info != NULL;
@ -521,7 +470,7 @@ tu_CreateImage(VkDevice _device,
if (pCreateInfo->mipLevels != 1 ||
pCreateInfo->arrayLayers != 1 ||
pCreateInfo->extent.depth != 1)
goto invalid_layout;
return vk_error(device, VK_ERROR_INVALID_DRM_FORMAT_MODIFIER_PLANE_LAYOUT_EXT);
plane_layout.offset = plane_layouts[i].offset;
plane_layout.pitch = plane_layouts[i].rowPitch;
@ -540,7 +489,7 @@ tu_CreateImage(VkDevice _device,
pCreateInfo->imageType == VK_IMAGE_TYPE_3D,
plane_layouts ? &plane_layout : NULL)) {
assert(plane_layouts); /* can only fail with explicit layout */
goto invalid_layout;
return vk_error(device, VK_ERROR_INVALID_DRM_FORMAT_MODIFIER_PLANE_LAYOUT_EXT);
}
/* fdl6_layout can't take explicit offset without explicit pitch
@ -588,17 +537,80 @@ tu_CreateImage(VkDevice _device,
image->total_size += lrz_size;
}
return VK_SUCCESS;
}
VKAPI_ATTR VkResult VKAPI_CALL
tu_CreateImage(VkDevice _device,
const VkImageCreateInfo *pCreateInfo,
const VkAllocationCallbacks *alloc,
VkImage *pImage)
{
uint64_t modifier = DRM_FORMAT_MOD_INVALID;
const VkSubresourceLayout *plane_layouts = NULL;
TU_FROM_HANDLE(tu_device, device, _device);
struct tu_image *image =
vk_object_zalloc(&device->vk, alloc, sizeof(*image), VK_OBJECT_TYPE_IMAGE);
if (!image)
return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
if (pCreateInfo->tiling == VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT) {
const VkImageDrmFormatModifierListCreateInfoEXT *mod_info =
vk_find_struct_const(pCreateInfo->pNext,
IMAGE_DRM_FORMAT_MODIFIER_LIST_CREATE_INFO_EXT);
const VkImageDrmFormatModifierExplicitCreateInfoEXT *drm_explicit_info =
vk_find_struct_const(pCreateInfo->pNext,
IMAGE_DRM_FORMAT_MODIFIER_EXPLICIT_CREATE_INFO_EXT);
assert(mod_info || drm_explicit_info);
if (mod_info) {
modifier = DRM_FORMAT_MOD_LINEAR;
for (unsigned i = 0; i < mod_info->drmFormatModifierCount; i++) {
if (mod_info->pDrmFormatModifiers[i] == DRM_FORMAT_MOD_QCOM_COMPRESSED)
modifier = DRM_FORMAT_MOD_QCOM_COMPRESSED;
}
} else {
modifier = drm_explicit_info->drmFormatModifier;
assert(modifier == DRM_FORMAT_MOD_LINEAR ||
modifier == DRM_FORMAT_MOD_QCOM_COMPRESSED);
plane_layouts = drm_explicit_info->pPlaneLayouts;
}
} else {
const struct wsi_image_create_info *wsi_info =
vk_find_struct_const(pCreateInfo->pNext, WSI_IMAGE_CREATE_INFO_MESA);
if (wsi_info && wsi_info->scanout)
modifier = DRM_FORMAT_MOD_LINEAR;
}
#ifdef ANDROID
const VkNativeBufferANDROID *gralloc_info =
vk_find_struct_const(pCreateInfo->pNext, NATIVE_BUFFER_ANDROID);
int dma_buf;
if (gralloc_info) {
VkResult result = tu_gralloc_info(device, gralloc_info, &dma_buf, &modifier);
if (result != VK_SUCCESS)
return result;
}
#endif
VkResult result = tu_image_init(device, image, pCreateInfo, modifier,
plane_layouts);
if (result != VK_SUCCESS) {
vk_object_free(&device->vk, alloc, image);
return result;
}
*pImage = tu_image_to_handle(image);
#ifdef ANDROID
if (gralloc_info)
return tu_import_memory_from_gralloc_handle(_device, dma_buf, alloc, *pImage);
return tu_import_memory_from_gralloc_handle(_device, dma_buf, alloc,
*pImage);
#endif
return VK_SUCCESS;
invalid_layout:
vk_object_free(&device->vk, alloc, image);
return vk_error(device, VK_ERROR_INVALID_DRM_FORMAT_MODIFIER_PLANE_LAYOUT_EXT);
}
VKAPI_ATTR void VKAPI_CALL
@ -620,6 +632,77 @@ tu_DestroyImage(VkDevice _device,
vk_object_free(&device->vk, pAllocator, image);
}
static void
tu_get_image_memory_requirements(struct tu_image *image,
VkMemoryRequirements2 *pMemoryRequirements)
{
pMemoryRequirements->memoryRequirements = (VkMemoryRequirements) {
.memoryTypeBits = 1,
.alignment = image->layout[0].base_align,
.size = image->total_size
};
vk_foreach_struct(ext, pMemoryRequirements->pNext) {
switch (ext->sType) {
case VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS: {
VkMemoryDedicatedRequirements *req =
(VkMemoryDedicatedRequirements *) ext;
req->requiresDedicatedAllocation = image->shareable;
req->prefersDedicatedAllocation = req->requiresDedicatedAllocation;
break;
}
default:
break;
}
}
}
VKAPI_ATTR void VKAPI_CALL
tu_GetImageMemoryRequirements2(VkDevice device,
const VkImageMemoryRequirementsInfo2 *pInfo,
VkMemoryRequirements2 *pMemoryRequirements)
{
TU_FROM_HANDLE(tu_image, image, pInfo->image);
tu_get_image_memory_requirements(image, pMemoryRequirements);
}
VKAPI_ATTR void VKAPI_CALL
tu_GetImageSparseMemoryRequirements2(
VkDevice device,
const VkImageSparseMemoryRequirementsInfo2 *pInfo,
uint32_t *pSparseMemoryRequirementCount,
VkSparseImageMemoryRequirements2 *pSparseMemoryRequirements)
{
tu_stub();
}
VKAPI_ATTR void VKAPI_CALL
tu_GetDeviceImageMemoryRequirements(
VkDevice _device,
const VkDeviceImageMemoryRequirements *pInfo,
VkMemoryRequirements2 *pMemoryRequirements)
{
TU_FROM_HANDLE(tu_device, device, _device);
struct tu_image image = {0};
tu_image_init(device, &image, pInfo->pCreateInfo, DRM_FORMAT_MOD_INVALID,
NULL);
tu_get_image_memory_requirements(&image, pMemoryRequirements);
}
VKAPI_ATTR void VKAPI_CALL
tu_GetDeviceImageSparseMemoryRequirements(
VkDevice device,
const VkDeviceImageMemoryRequirements *pInfo,
uint32_t *pSparseMemoryRequirementCount,
VkSparseImageMemoryRequirements2 *pSparseMemoryRequirements)
{
tu_stub();
}
VKAPI_ATTR void VKAPI_CALL
tu_GetImageSubresourceLayout(VkDevice _device,
VkImage _image,