mirror of
https://gitlab.freedesktop.org/monado/monado.git
synced 2025-01-14 02:45:24 +00:00
aux/vk: handle extFormatResolve in create_image
Part-of: <https://gitlab.freedesktop.org/monado/monado/-/merge_requests/2316>
This commit is contained in:
parent
8c272d1d96
commit
08f3965ad0
|
@ -804,28 +804,15 @@ vk_get_memory_type(struct vk_bundle *vk, uint32_t type_bits, VkMemoryPropertyFla
|
|||
XRT_CHECK_RESULT VkResult
|
||||
vk_alloc_and_bind_image_memory(struct vk_bundle *vk,
|
||||
VkImage image,
|
||||
size_t max_size,
|
||||
const VkMemoryRequirements *requirements,
|
||||
const void *pNext_for_allocate,
|
||||
const char *caller_name,
|
||||
VkDeviceMemory *out_mem,
|
||||
VkDeviceSize *out_size)
|
||||
VkDeviceMemory *out_mem)
|
||||
{
|
||||
VkMemoryRequirements memory_requirements;
|
||||
vk->vkGetImageMemoryRequirements(vk->device, image, &memory_requirements);
|
||||
|
||||
if (max_size > 0 && memory_requirements.size > max_size) {
|
||||
VK_ERROR(vk, "(%s) vkGetImageMemoryRequirements: Requested more memory (%u) then given (%u)\n",
|
||||
caller_name, (uint32_t)memory_requirements.size, (uint32_t)max_size);
|
||||
return VK_ERROR_OUT_OF_DEVICE_MEMORY;
|
||||
}
|
||||
if (out_size != NULL) {
|
||||
*out_size = memory_requirements.size;
|
||||
}
|
||||
|
||||
uint32_t memory_type_index = UINT32_MAX;
|
||||
bool bret = vk_get_memory_type( //
|
||||
vk, // vk_bundle
|
||||
memory_requirements.memoryTypeBits, // type_bits
|
||||
requirements->memoryTypeBits, // type_bits
|
||||
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, // memory_props
|
||||
&memory_type_index); // out_type_id
|
||||
if (!bret) {
|
||||
|
@ -836,7 +823,7 @@ vk_alloc_and_bind_image_memory(struct vk_bundle *vk,
|
|||
VkMemoryAllocateInfo alloc_info = {
|
||||
.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
|
||||
.pNext = pNext_for_allocate,
|
||||
.allocationSize = memory_requirements.size,
|
||||
.allocationSize = requirements->size,
|
||||
.memoryTypeIndex = memory_type_index,
|
||||
};
|
||||
|
||||
|
@ -901,14 +888,16 @@ create_image_simple(struct vk_bundle *vk,
|
|||
return ret;
|
||||
}
|
||||
|
||||
VkMemoryRequirements requirements = {0};
|
||||
vk->vkGetImageMemoryRequirements(vk->device, image, &requirements);
|
||||
|
||||
ret = vk_alloc_and_bind_image_memory( //
|
||||
vk, // vk_bundle
|
||||
image, // image
|
||||
SIZE_MAX, // max_size
|
||||
&requirements, // max_size
|
||||
NULL, // pNext_for_allocate
|
||||
__func__, // caller_name
|
||||
out_mem, // out_mem
|
||||
NULL); // out_size
|
||||
out_mem); // out_mem
|
||||
if (ret != VK_SUCCESS) {
|
||||
// Clean up image
|
||||
vk->vkDestroyImage(vk->device, image, NULL);
|
||||
|
@ -1154,18 +1143,37 @@ vk_create_image_from_native(struct vk_bundle *vk,
|
|||
// Nothing to cleanup
|
||||
return ret;
|
||||
}
|
||||
|
||||
VkMemoryRequirements requirements = {0};
|
||||
vk->vkGetImageMemoryRequirements(vk->device, image, &requirements);
|
||||
|
||||
#if defined(XRT_GRAPHICS_BUFFER_HANDLE_IS_FD)
|
||||
VkImportMemoryFdInfoKHR import_memory_info = {
|
||||
.sType = VK_STRUCTURE_TYPE_IMPORT_MEMORY_FD_INFO_KHR,
|
||||
.handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHR,
|
||||
.fd = image_native->handle,
|
||||
};
|
||||
|
||||
// TODO memoryTypeBits from VkMemoryFdPropertiesKHR
|
||||
#elif defined(XRT_GRAPHICS_BUFFER_HANDLE_IS_AHARDWAREBUFFER)
|
||||
VkImportAndroidHardwareBufferInfoANDROID import_memory_info = {
|
||||
.sType = VK_STRUCTURE_TYPE_IMPORT_ANDROID_HARDWARE_BUFFER_INFO_ANDROID,
|
||||
.pNext = NULL,
|
||||
.buffer = image_native->handle,
|
||||
};
|
||||
|
||||
VkAndroidHardwareBufferPropertiesANDROID ahb_props = {
|
||||
.sType = VK_STRUCTURE_TYPE_ANDROID_HARDWARE_BUFFER_PROPERTIES_ANDROID,
|
||||
};
|
||||
|
||||
ret = vk->vkGetAndroidHardwareBufferPropertiesANDROID(vk->device, image_native->handle, &ahb_props);
|
||||
if (ret != VK_SUCCESS) {
|
||||
VK_ERROR(vk, "vkGetAndroidHardwareBufferPropertiesANDROID: %s", vk_result_string(ret));
|
||||
return ret;
|
||||
}
|
||||
|
||||
requirements.size = ahb_props.allocationSize;
|
||||
requirements.memoryTypeBits = ahb_props.memoryTypeBits;
|
||||
#elif defined(XRT_GRAPHICS_BUFFER_HANDLE_IS_WIN32_HANDLE)
|
||||
VkImportMemoryWin32HandleInfoKHR import_memory_info = {
|
||||
.sType = VK_STRUCTURE_TYPE_IMPORT_MEMORY_WIN32_HANDLE_INFO_KHR,
|
||||
|
@ -1173,9 +1181,20 @@ vk_create_image_from_native(struct vk_bundle *vk,
|
|||
.handleType = handle_type,
|
||||
.handle = image_native->handle,
|
||||
};
|
||||
|
||||
// TODO memoryTypeBits from VkMemoryWin32HandlePropertiesKHR
|
||||
#else
|
||||
#error "need port"
|
||||
#endif
|
||||
if (requirements.size > image_native->size) {
|
||||
VK_ERROR(vk, "size mismatch, exported %" PRIu64 " but requires %" PRIu64, image_native->size,
|
||||
requirements.size);
|
||||
return VK_ERROR_OUT_OF_DEVICE_MEMORY;
|
||||
} else if (requirements.size < image_native->size) {
|
||||
VK_WARN(vk, "size mismatch, exported %" PRIu64 " but requires %" PRIu64, image_native->size,
|
||||
requirements.size);
|
||||
}
|
||||
|
||||
VkMemoryDedicatedAllocateInfoKHR dedicated_memory_info = {
|
||||
.sType = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO_KHR,
|
||||
.pNext = &import_memory_info,
|
||||
|
@ -1186,11 +1205,10 @@ vk_create_image_from_native(struct vk_bundle *vk,
|
|||
ret = vk_alloc_and_bind_image_memory( //
|
||||
vk, // vk_bundle
|
||||
image, // image
|
||||
image_native->size, // max_size
|
||||
&requirements, // requirements
|
||||
&dedicated_memory_info, // pNext_for_allocate
|
||||
__func__, // caller_name
|
||||
out_mem, // out_mem
|
||||
NULL); // out_size
|
||||
out_mem); // out_mem
|
||||
|
||||
#if defined(XRT_GRAPHICS_BUFFER_HANDLE_CONSUMED_BY_VULKAN_IMPORT)
|
||||
// We have consumed this fd now, make sure it's not freed again.
|
||||
|
|
|
@ -1082,9 +1082,7 @@ vk_get_memory_type(struct vk_bundle *vk, uint32_t type_bits, VkMemoryPropertyFla
|
|||
*
|
||||
* @param vk Vulkan bundle
|
||||
* @param image The VkImage to allocate for and bind.
|
||||
* @param max_size The maximum value you'll allow for
|
||||
* VkMemoryRequirements::size. Pass SIZE_MAX if you will accept any size
|
||||
* that works.
|
||||
* @param requirements Memory requirements used for finding the memory type and the size.
|
||||
* @param pNext_for_allocate (Optional) a pointer to use in the pNext chain of
|
||||
* VkMemoryAllocateInfo.
|
||||
* @param caller_name Used for error printing, this function is called from
|
||||
|
@ -1104,11 +1102,10 @@ vk_get_memory_type(struct vk_bundle *vk, uint32_t type_bits, VkMemoryPropertyFla
|
|||
XRT_CHECK_RESULT VkResult
|
||||
vk_alloc_and_bind_image_memory(struct vk_bundle *vk,
|
||||
VkImage image,
|
||||
size_t max_size,
|
||||
const VkMemoryRequirements *requirements,
|
||||
const void *pNext_for_allocate,
|
||||
const char *caller_name,
|
||||
VkDeviceMemory *out_mem,
|
||||
VkDeviceSize *out_size);
|
||||
VkDeviceMemory *out_mem);
|
||||
|
||||
/*!
|
||||
*
|
||||
|
@ -1564,9 +1561,7 @@ vk_csci_get_image_external_support(struct vk_bundle *vk,
|
|||
* CSCI = Compositor SwapChain Images.
|
||||
*/
|
||||
bool
|
||||
vk_csci_is_format_supported(struct vk_bundle *vk,
|
||||
VkFormat format,
|
||||
enum xrt_swapchain_usage_bits xbits);
|
||||
vk_csci_is_format_supported(struct vk_bundle *vk, VkFormat format, enum xrt_swapchain_usage_bits xbits);
|
||||
|
||||
/*
|
||||
*
|
||||
|
|
|
@ -108,7 +108,6 @@ create_image(struct vk_bundle *vk, const struct xrt_swapchain_create_info *info,
|
|||
VkDeviceMemory device_memory = VK_NULL_HANDLE;
|
||||
VkImage image = VK_NULL_HANDLE;
|
||||
VkResult ret = VK_SUCCESS;
|
||||
VkDeviceSize size;
|
||||
|
||||
#if defined(XRT_GRAPHICS_BUFFER_HANDLE_IS_AHARDWAREBUFFER)
|
||||
/*
|
||||
|
@ -187,9 +186,8 @@ create_image(struct vk_bundle *vk, const struct xrt_swapchain_create_info *info,
|
|||
};
|
||||
CHAIN(format_android);
|
||||
|
||||
// Android can't allocate native sRGB.
|
||||
// Use UNORM and correct gamma later.
|
||||
if (image_format == VK_FORMAT_R8G8B8A8_SRGB) {
|
||||
// Some versions of Android can't allocate native sRGB, use UNORM and correct gamma later.
|
||||
image_format = VK_FORMAT_R8G8B8A8_UNORM;
|
||||
|
||||
// https://www.khronos.org/registry/vulkan/specs/1.0/html/vkspec.html#VUID-VkImageViewCreateInfo-image-01019
|
||||
|
@ -203,6 +201,20 @@ create_image(struct vk_bundle *vk, const struct xrt_swapchain_create_info *info,
|
|||
add_format_non_dup(&flh, VK_FORMAT_R8G8B8A8_UNORM);
|
||||
add_format_non_dup(&flh, VK_FORMAT_R8G8B8A8_SRGB);
|
||||
}
|
||||
|
||||
if (vk_csci_is_format_supported(vk, image_format, info->bits)) {
|
||||
// Format is supported, no need for VkExternalFormatANDROID
|
||||
format_android.externalFormat = 0;
|
||||
assert(a_buffer_format_props.format != VK_FORMAT_UNDEFINED); // Make sure there is a Vulkan format.
|
||||
} else if (image_usage != VK_IMAGE_USAGE_SAMPLED_BIT && !vk->has_ANDROID_external_format_resolve) {
|
||||
// VUID-VkImageCreateInfo-pNext-09457
|
||||
VK_ERROR(
|
||||
vk, "VK_ANDROID_external_format_resolve not supported, only VK_IMAGE_USAGE_SAMPLED_BIT is allowed");
|
||||
return VK_ERROR_FORMAT_NOT_SUPPORTED;
|
||||
} else {
|
||||
VK_ERROR(vk, "Format not supported");
|
||||
return VK_ERROR_FORMAT_NOT_SUPPORTED;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef VK_KHR_image_format_list
|
||||
|
@ -270,7 +282,20 @@ create_image(struct vk_bundle *vk, const struct xrt_swapchain_create_info *info,
|
|||
.pNext = &memory_dedicated_requirements,
|
||||
};
|
||||
|
||||
VkMemoryRequirements *requirements;
|
||||
#if defined(XRT_GRAPHICS_BUFFER_HANDLE_IS_AHARDWAREBUFFER)
|
||||
// VUID-VkImageMemoryRequirementsInfo2-image-01897
|
||||
// VUID-VkMemoryAllocateInfo-pNext-01874
|
||||
// Use the requirements from the VkAndroidHardwareBufferPropertiesANDROID instead of querying them
|
||||
VkMemoryRequirements android_memory_requirements = {
|
||||
.size = a_buffer_props.allocationSize,
|
||||
.memoryTypeBits = a_buffer_props.memoryTypeBits,
|
||||
};
|
||||
requirements = &android_memory_requirements;
|
||||
#else
|
||||
vk->vkGetImageMemoryRequirements2(vk->device, &memory_requirements_info, &memory_requirements);
|
||||
requirements = &memory_requirements.memoryRequirements;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* On tegra we must not use dedicated allocation when it is only preferred to avoid black textures and driver
|
||||
|
@ -312,11 +337,10 @@ create_image(struct vk_bundle *vk, const struct xrt_swapchain_create_info *info,
|
|||
ret = vk_alloc_and_bind_image_memory( //
|
||||
vk, // vk_bundle
|
||||
image, // image
|
||||
SIZE_MAX, // max_size
|
||||
requirements, // requirements
|
||||
&export_alloc_info, // pNext_for_allocate
|
||||
"vk_image_allocator::create_image", // caller_name
|
||||
&device_memory, // out_mem
|
||||
&size); // out_size
|
||||
&device_memory); // out_mem
|
||||
if (ret != VK_SUCCESS) {
|
||||
vk->vkDestroyImage(vk->device, image, NULL);
|
||||
return ret;
|
||||
|
@ -324,7 +348,7 @@ create_image(struct vk_bundle *vk, const struct xrt_swapchain_create_info *info,
|
|||
|
||||
out_image->handle = image;
|
||||
out_image->memory = device_memory;
|
||||
out_image->size = size;
|
||||
out_image->size = memory_requirements.memoryRequirements.size;
|
||||
out_image->use_dedicated_allocation = use_dedicated_allocation;
|
||||
|
||||
return ret;
|
||||
|
|
Loading…
Reference in a new issue