summaryrefslogtreecommitdiff
path: root/src/amd/vulkan/radv_android.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/amd/vulkan/radv_android.c')
-rw-r--r--src/amd/vulkan/radv_android.c504
1 files changed, 172 insertions, 332 deletions
diff --git a/src/amd/vulkan/radv_android.c b/src/amd/vulkan/radv_android.c
index 066cae971e6..e9505378737 100644
--- a/src/amd/vulkan/radv_android.c
+++ b/src/amd/vulkan/radv_android.c
@@ -1,27 +1,18 @@
/*
* Copyright © 2017, Google Inc.
*
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
+ * SPDX-License-Identifier: MIT
*/
-#ifdef ANDROID
+#include "radv_android.h"
+#include "radv_buffer.h"
+#include "radv_device.h"
+#include "radv_device_memory.h"
+#include "radv_entrypoints.h"
+#include "radv_image.h"
+#include "radv_physical_device.h"
+
+#if DETECT_OS_ANDROID
#include <libsync.h>
#include <hardware/gralloc.h>
#include <hardware/hardware.h>
@@ -32,23 +23,20 @@
#if ANDROID_API_LEVEL >= 26
#include <hardware/gralloc1.h>
#endif
-#endif
+#endif /* DETECT_OS_ANDROID */
#include "util/os_file.h"
-#include "radv_private.h"
+#include "vk_android.h"
+#include "vk_log.h"
#include "vk_util.h"
-#ifdef ANDROID
+#if DETECT_OS_ANDROID
static int radv_hal_open(const struct hw_module_t *mod, const char *id, struct hw_device_t **dev);
static int radv_hal_close(struct hw_device_t *dev);
-static void UNUSED
-static_asserts(void)
-{
- STATIC_ASSERT(HWVULKAN_DISPATCH_MAGIC == ICD_LOADER_MAGIC);
-}
+static_assert(HWVULKAN_DISPATCH_MAGIC == ICD_LOADER_MAGIC, "");
PUBLIC struct hwvulkan_module_t HAL_MODULE_INFO_SYM = {
.common =
@@ -111,17 +99,18 @@ radv_hal_close(struct hw_device_t *dev)
VkResult
radv_image_from_gralloc(VkDevice device_h, const VkImageCreateInfo *base_info,
- const VkNativeBufferANDROID *gralloc_info,
- const VkAllocationCallbacks *alloc, VkImage *out_image_h)
+ const VkNativeBufferANDROID *gralloc_info, const VkAllocationCallbacks *alloc,
+ VkImage *out_image_h)
{
- RADV_FROM_HANDLE(radv_device, device, device_h);
+ VK_FROM_HANDLE(radv_device, device, device_h);
+ const struct radv_physical_device *pdev = radv_device_physical(device);
VkImage image_h = VK_NULL_HANDLE;
struct radv_image *image = NULL;
VkResult result;
if (gralloc_info->handle->numFds != 1) {
- return vk_errorf(device->instance, VK_ERROR_INVALID_EXTERNAL_HANDLE,
+ return vk_errorf(device, VK_ERROR_INVALID_EXTERNAL_HANDLE,
"VkNativeBufferANDROID::handle::numFds is %d, "
"expected 1",
gralloc_info->handle->numFds);
@@ -143,10 +132,10 @@ radv_image_from_gralloc(VkDevice device_h, const VkImageCreateInfo *base_info,
/* Find the first VRAM memory type, or GART for PRIME images. */
int memory_type_index = -1;
- for (int i = 0; i < device->physical_device->memory_properties.memoryTypeCount; ++i) {
- bool is_local = !!(device->physical_device->memory_properties.memoryTypes[i].propertyFlags &
- VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
- if (is_local) {
+ for (int i = 0; i < pdev->memory_properties.memoryTypeCount; ++i) {
+ bool is_local = !!(pdev->memory_properties.memoryTypes[i].propertyFlags & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
+ bool is_32bit = !!(pdev->memory_types_32bit & (1u << i));
+ if (is_local && !is_32bit) {
memory_type_index = i;
break;
}
@@ -187,7 +176,7 @@ radv_image_from_gralloc(VkDevice device_h, const VkImageCreateInfo *base_info,
.no_metadata_planes = true,
.bo_metadata = &md,
},
- alloc, &image_h);
+ alloc, &image_h, false);
if (result != VK_SUCCESS)
goto fail_create_image;
@@ -196,7 +185,11 @@ radv_image_from_gralloc(VkDevice device_h, const VkImageCreateInfo *base_info,
radv_image_override_offset_stride(device, image, 0, gralloc_info->stride);
- radv_BindImageMemory(device_h, image_h, memory_h, 0);
+ VkBindImageMemoryInfo bind_info = {.sType = VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_INFO,
+ .image = image_h,
+ .memory = memory_h,
+ .memoryOffset = 0};
+ radv_BindImageMemory2(device_h, 1, &bind_info);
image->owned_memory = memory_h;
/* Don't clobber the out-parameter until success is certain. */
@@ -210,12 +203,12 @@ fail_create_image:
}
VkResult
-radv_GetSwapchainGrallocUsageANDROID(VkDevice device_h, VkFormat format,
- VkImageUsageFlags imageUsage, int *grallocUsage)
+radv_GetSwapchainGrallocUsageANDROID(VkDevice device_h, VkFormat format, VkImageUsageFlags imageUsage,
+ int *grallocUsage)
{
- RADV_FROM_HANDLE(radv_device, device, device_h);
- struct radv_physical_device *phys_dev = device->physical_device;
- VkPhysicalDevice phys_dev_h = radv_physical_device_to_handle(phys_dev);
+ VK_FROM_HANDLE(radv_device, device, device_h);
+ struct radv_physical_device *pdev = radv_device_physical(device);
+ VkPhysicalDevice pdev_h = radv_physical_device_to_handle(pdev);
VkResult result;
*grallocUsage = 0;
@@ -246,10 +239,9 @@ radv_GetSwapchainGrallocUsageANDROID(VkDevice device_h, VkFormat format,
};
/* Check that requested format and usage are supported. */
- result = radv_GetPhysicalDeviceImageFormatProperties2(phys_dev_h, &image_format_info,
- &image_format_props);
+ result = radv_GetPhysicalDeviceImageFormatProperties2(pdev_h, &image_format_info, &image_format_props);
if (result != VK_SUCCESS) {
- return vk_errorf(device->instance, result,
+ return vk_errorf(device, result,
"radv_GetPhysicalDeviceImageFormatProperties2 failed "
"inside %s",
__func__);
@@ -258,15 +250,15 @@ radv_GetSwapchainGrallocUsageANDROID(VkDevice device_h, VkFormat format,
if (unmask32(&imageUsage, VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT))
*grallocUsage |= GRALLOC_USAGE_HW_RENDER;
- if (unmask32(&imageUsage, VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_SAMPLED_BIT |
- VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT))
+ if (unmask32(&imageUsage, VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_STORAGE_BIT |
+ VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT))
*grallocUsage |= GRALLOC_USAGE_HW_TEXTURE;
/* All VkImageUsageFlags not explicitly checked here are unsupported for
* gralloc swapchains.
*/
if (imageUsage != 0) {
- return vk_errorf(device->instance, VK_ERROR_FORMAT_NOT_SUPPORTED,
+ return vk_errorf(device, VK_ERROR_FORMAT_NOT_SUPPORTED,
"unsupported VkImageUsageFlags(0x%x) for gralloc "
"swapchain",
imageUsage);
@@ -278,8 +270,7 @@ radv_GetSwapchainGrallocUsageANDROID(VkDevice device_h, VkFormat format,
* what we need for 30-bit colors.
*/
if (format == VK_FORMAT_B8G8R8A8_UNORM || format == VK_FORMAT_B5G6R5_UNORM_PACK16) {
- *grallocUsage |=
- GRALLOC_USAGE_HW_FB | GRALLOC_USAGE_HW_COMPOSER | GRALLOC_USAGE_EXTERNAL_DISP;
+ *grallocUsage |= GRALLOC_USAGE_HW_FB | GRALLOC_USAGE_HW_COMPOSER | GRALLOC_USAGE_EXTERNAL_DISP;
}
if (*grallocUsage == 0)
@@ -289,25 +280,23 @@ radv_GetSwapchainGrallocUsageANDROID(VkDevice device_h, VkFormat format,
}
VkResult
-radv_GetSwapchainGrallocUsage2ANDROID(VkDevice device_h, VkFormat format,
- VkImageUsageFlags imageUsage,
+radv_GetSwapchainGrallocUsage2ANDROID(VkDevice device_h, VkFormat format, VkImageUsageFlags imageUsage,
VkSwapchainImageUsageFlagsANDROID swapchainImageUsage,
- uint64_t *grallocConsumerUsage,
- uint64_t *grallocProducerUsage)
+ uint64_t *grallocConsumerUsage, uint64_t *grallocProducerUsage)
{
/* Before level 26 (Android 8.0/Oreo) the loader uses
* vkGetSwapchainGrallocUsageANDROID. */
#if ANDROID_API_LEVEL >= 26
- RADV_FROM_HANDLE(radv_device, device, device_h);
- struct radv_physical_device *phys_dev = device->physical_device;
- VkPhysicalDevice phys_dev_h = radv_physical_device_to_handle(phys_dev);
+ VK_FROM_HANDLE(radv_device, device, device_h);
+ struct radv_physical_device *pdev = radv_device_physical(device);
+ VkPhysicalDevice pdev_h = radv_physical_device_to_handle(pdev);
VkResult result;
*grallocConsumerUsage = 0;
*grallocProducerUsage = 0;
if (swapchainImageUsage & VK_SWAPCHAIN_IMAGE_USAGE_SHARED_BIT_ANDROID)
- return vk_errorf(device->instance, VK_ERROR_FORMAT_NOT_SUPPORTED,
+ return vk_errorf(device, VK_ERROR_FORMAT_NOT_SUPPORTED,
"The Vulkan loader tried to query shared presentable image support");
const VkPhysicalDeviceImageFormatInfo2 image_format_info = {
@@ -323,28 +312,26 @@ radv_GetSwapchainGrallocUsage2ANDROID(VkDevice device_h, VkFormat format,
};
/* Check that requested format and usage are supported. */
- result = radv_GetPhysicalDeviceImageFormatProperties2(phys_dev_h, &image_format_info,
- &image_format_props);
+ result = radv_GetPhysicalDeviceImageFormatProperties2(pdev_h, &image_format_info, &image_format_props);
if (result != VK_SUCCESS) {
- return vk_errorf(device->instance, result,
+ return vk_errorf(device, result,
"radv_GetPhysicalDeviceImageFormatProperties2 failed "
"inside %s",
__func__);
}
- if (unmask32(&imageUsage,
- VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT)) {
+ if (unmask32(&imageUsage, VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT)) {
*grallocProducerUsage |= GRALLOC1_PRODUCER_USAGE_GPU_RENDER_TARGET;
*grallocConsumerUsage |= GRALLOC1_CONSUMER_USAGE_CLIENT_TARGET;
}
- if (unmask32(&imageUsage, VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_SAMPLED_BIT |
- VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT)) {
+ if (unmask32(&imageUsage, VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_STORAGE_BIT |
+ VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT)) {
*grallocConsumerUsage |= GRALLOC1_CONSUMER_USAGE_GPU_TEXTURE;
}
if (imageUsage != 0) {
- return vk_errorf(device->instance, VK_ERROR_FORMAT_NOT_SUPPORTED,
+ return vk_errorf(device, VK_ERROR_FORMAT_NOT_SUPPORTED,
"unsupported VkImageUsageFlags(0x%x) for gralloc "
"swapchain",
imageUsage);
@@ -370,227 +357,55 @@ radv_GetSwapchainGrallocUsage2ANDROID(VkDevice device_h, VkFormat format,
return VK_ERROR_FORMAT_NOT_SUPPORTED;
#endif
}
-
-VkResult
-radv_AcquireImageANDROID(VkDevice device_h, VkImage image_h, int nativeFenceFd, VkSemaphore semaphore,
- VkFence fence)
-{
- RADV_FROM_HANDLE(radv_device, device, device_h);
- VkResult result = VK_SUCCESS;
-
- /* From https://source.android.com/devices/graphics/implement-vulkan :
- *
- * "The driver takes ownership of the fence file descriptor and closes
- * the fence file descriptor when no longer needed. The driver must do
- * so even if neither a semaphore or fence object is provided, or even
- * if vkAcquireImageANDROID fails and returns an error."
- *
- * The Vulkan spec for VkImportFence/SemaphoreFdKHR(), however, requires
- * the file descriptor to be left alone on failure.
- */
- int semaphore_fd = -1, fence_fd = -1;
- if (nativeFenceFd >= 0) {
- if (semaphore != VK_NULL_HANDLE && fence != VK_NULL_HANDLE) {
- /* We have both so we have to import the sync file twice. One of
- * them needs to be a dup.
- */
- semaphore_fd = nativeFenceFd;
- fence_fd = dup(nativeFenceFd);
- if (fence_fd < 0) {
- VkResult err = (errno == EMFILE) ? VK_ERROR_TOO_MANY_OBJECTS :
- VK_ERROR_OUT_OF_HOST_MEMORY;
- close(nativeFenceFd);
- return vk_error(device->instance, err);
- }
- } else if (semaphore != VK_NULL_HANDLE) {
- semaphore_fd = nativeFenceFd;
- } else if (fence != VK_NULL_HANDLE) {
- fence_fd = nativeFenceFd;
- } else {
- /* Nothing to import into so we have to close the file */
- close(nativeFenceFd);
- }
- }
-
- if (semaphore != VK_NULL_HANDLE) {
- const VkImportSemaphoreFdInfoKHR info = {
- .sType = VK_STRUCTURE_TYPE_IMPORT_SEMAPHORE_FD_INFO_KHR,
- .semaphore = semaphore,
- .flags = VK_SEMAPHORE_IMPORT_TEMPORARY_BIT,
- .handleType = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT,
- .fd = semaphore_fd,
- };
- result = radv_ImportSemaphoreFdKHR(device_h, &info);
- if (result == VK_SUCCESS)
- semaphore_fd = -1; /* RADV took ownership */
- }
-
- if (result == VK_SUCCESS && fence != VK_NULL_HANDLE) {
- const VkImportFenceFdInfoKHR info = {
- .sType = VK_STRUCTURE_TYPE_IMPORT_FENCE_FD_INFO_KHR,
- .fence = fence,
- .flags = VK_FENCE_IMPORT_TEMPORARY_BIT,
- .handleType = VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT,
- .fd = fence_fd,
- };
- result = radv_ImportFenceFdKHR(device_h, &info);
- if (result == VK_SUCCESS)
- fence_fd = -1; /* RADV took ownership */
- }
-
- if (semaphore_fd >= 0)
- close(semaphore_fd);
- if (fence_fd >= 0)
- close(fence_fd);
-
- return result;
-}
-
-VkResult
-radv_QueueSignalReleaseImageANDROID(VkQueue _queue, uint32_t waitSemaphoreCount,
- const VkSemaphore *pWaitSemaphores, VkImage image,
- int *pNativeFenceFd)
-{
- RADV_FROM_HANDLE(radv_queue, queue, _queue);
- VkResult result = VK_SUCCESS;
-
- if (waitSemaphoreCount == 0) {
- if (pNativeFenceFd)
- *pNativeFenceFd = -1;
- return VK_SUCCESS;
- }
-
- int fd = -1;
-
- for (uint32_t i = 0; i < waitSemaphoreCount; ++i) {
- int tmp_fd;
- result =
- radv_GetSemaphoreFdKHR(radv_device_to_handle(queue->device),
- &(VkSemaphoreGetFdInfoKHR){
- .sType = VK_STRUCTURE_TYPE_SEMAPHORE_GET_FD_INFO_KHR,
- .handleType = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT,
- .semaphore = pWaitSemaphores[i],
- },
- &tmp_fd);
- if (result != VK_SUCCESS) {
- if (fd >= 0)
- close(fd);
- return result;
- }
-
- if (fd < 0)
- fd = tmp_fd;
- else if (tmp_fd >= 0) {
- sync_accumulate("radv", &fd, tmp_fd);
- close(tmp_fd);
- }
- }
-
- if (pNativeFenceFd) {
- *pNativeFenceFd = fd;
- } else if (fd >= 0) {
- close(fd);
- /* We still need to do the exports, to reset the semaphores, but
- * otherwise we don't wait on them. */
- }
- return VK_SUCCESS;
-}
-#endif
+#endif /* DETECT_OS_ANDROID */
#if RADV_SUPPORT_ANDROID_HARDWARE_BUFFER
enum {
/* Usage bit equal to GRALLOC_USAGE_HW_CAMERA_MASK */
- AHARDWAREBUFFER_USAGE_CAMERA_MASK = 0x00060000U,
+ BUFFER_USAGE_CAMERA_MASK = 0x00060000U,
};
static inline VkFormat
vk_format_from_android(unsigned android_format, unsigned android_usage)
{
switch (android_format) {
- case AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM:
- case AHARDWAREBUFFER_FORMAT_R8G8B8X8_UNORM:
- return VK_FORMAT_R8G8B8A8_UNORM;
- case AHARDWAREBUFFER_FORMAT_R8G8B8_UNORM:
- return VK_FORMAT_R8G8B8_UNORM;
- case AHARDWAREBUFFER_FORMAT_R5G6B5_UNORM:
- return VK_FORMAT_R5G6B5_UNORM_PACK16;
- case AHARDWAREBUFFER_FORMAT_R16G16B16A16_FLOAT:
- return VK_FORMAT_R16G16B16A16_SFLOAT;
- case AHARDWAREBUFFER_FORMAT_R10G10B10A2_UNORM:
- return VK_FORMAT_A2B10G10R10_UNORM_PACK32;
case AHARDWAREBUFFER_FORMAT_Y8Cb8Cr8_420:
return VK_FORMAT_G8_B8R8_2PLANE_420_UNORM;
case AHARDWAREBUFFER_FORMAT_IMPLEMENTATION_DEFINED:
- if (android_usage & AHARDWAREBUFFER_USAGE_CAMERA_MASK)
+ if (android_usage & BUFFER_USAGE_CAMERA_MASK)
return VK_FORMAT_G8_B8R8_2PLANE_420_UNORM;
else
return VK_FORMAT_R8G8B8_UNORM;
- case AHARDWAREBUFFER_FORMAT_BLOB:
default:
- return VK_FORMAT_UNDEFINED;
+ return vk_ahb_format_to_image_format(android_format);
}
}
-static inline unsigned
-android_format_from_vk(unsigned vk_format)
+unsigned
+radv_ahb_format_for_vk_format(VkFormat vk_format)
{
switch (vk_format) {
- case VK_FORMAT_R8G8B8A8_UNORM:
- return AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM;
- case VK_FORMAT_R8G8B8_UNORM:
- return AHARDWAREBUFFER_FORMAT_R8G8B8_UNORM;
- case VK_FORMAT_R5G6B5_UNORM_PACK16:
- return AHARDWAREBUFFER_FORMAT_R5G6B5_UNORM;
- case VK_FORMAT_R16G16B16A16_SFLOAT:
- return AHARDWAREBUFFER_FORMAT_R16G16B16A16_FLOAT;
- case VK_FORMAT_A2B10G10R10_UNORM_PACK32:
- return AHARDWAREBUFFER_FORMAT_R10G10B10A2_UNORM;
case VK_FORMAT_G8_B8R8_2PLANE_420_UNORM:
return AHARDWAREBUFFER_FORMAT_Y8Cb8Cr8_420;
default:
- return AHARDWAREBUFFER_FORMAT_BLOB;
+ return vk_image_format_to_ahb_format(vk_format);
}
}
-uint64_t
-radv_ahb_usage_from_vk_usage(const VkImageCreateFlags vk_create, const VkImageUsageFlags vk_usage)
-{
- uint64_t ahb_usage = 0;
- if (vk_usage & VK_IMAGE_USAGE_SAMPLED_BIT)
- ahb_usage |= AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE;
-
- if (vk_usage & VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT)
- ahb_usage |= AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE;
-
- if (vk_usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT)
- ahb_usage |= AHARDWAREBUFFER_USAGE_GPU_COLOR_OUTPUT;
-
- if (vk_create & VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT)
- ahb_usage |= AHARDWAREBUFFER_USAGE_GPU_CUBE_MAP;
-
- if (vk_create & VK_IMAGE_CREATE_PROTECTED_BIT)
- ahb_usage |= AHARDWAREBUFFER_USAGE_PROTECTED_CONTENT;
-
- /* No usage bits set - set at least one GPU usage. */
- if (ahb_usage == 0)
- ahb_usage = AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE;
- return ahb_usage;
-}
-
static VkResult
get_ahb_buffer_format_properties(VkDevice device_h, const struct AHardwareBuffer *buffer,
VkAndroidHardwareBufferFormatPropertiesANDROID *pProperties)
{
- RADV_FROM_HANDLE(radv_device, device, device_h);
+ VK_FROM_HANDLE(radv_device, device, device_h);
+ struct radv_physical_device *pdev = radv_device_physical(device);
/* Get a description of buffer contents . */
AHardwareBuffer_Desc desc;
AHardwareBuffer_describe(buffer, &desc);
/* Verify description. */
- const uint64_t gpu_usage = AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE |
- AHARDWAREBUFFER_USAGE_GPU_COLOR_OUTPUT |
+ const uint64_t gpu_usage = AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE | AHARDWAREBUFFER_USAGE_GPU_COLOR_OUTPUT |
AHARDWAREBUFFER_USAGE_GPU_DATA_BUFFER;
/* "Buffer must be a valid Android hardware buffer object with at least
@@ -605,14 +420,14 @@ get_ahb_buffer_format_properties(VkDevice device_h, const struct AHardwareBuffer
p->format = vk_format_from_android(desc.format, desc.usage);
p->externalFormat = (uint64_t)(uintptr_t)p->format;
- VkFormatProperties format_properties;
- radv_GetPhysicalDeviceFormatProperties(radv_physical_device_to_handle(device->physical_device),
- p->format, &format_properties);
+ VkFormatProperties2 format_properties = {.sType = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2};
+
+ radv_GetPhysicalDeviceFormatProperties2(radv_physical_device_to_handle(pdev), p->format, &format_properties);
if (desc.usage & AHARDWAREBUFFER_USAGE_GPU_DATA_BUFFER)
- p->formatFeatures = format_properties.linearTilingFeatures;
+ p->formatFeatures = format_properties.formatProperties.linearTilingFeatures;
else
- p->formatFeatures = format_properties.optimalTilingFeatures;
+ p->formatFeatures = format_properties.formatProperties.optimalTilingFeatures;
/* "Images can be created with an external format even if the Android hardware
* buffer has a format which has an equivalent Vulkan format to enable
@@ -651,13 +466,85 @@ get_ahb_buffer_format_properties(VkDevice device_h, const struct AHardwareBuffer
return VK_SUCCESS;
}
+static VkResult
+get_ahb_buffer_format_properties2(VkDevice device_h, const struct AHardwareBuffer *buffer,
+ VkAndroidHardwareBufferFormatProperties2ANDROID *pProperties)
+{
+ VK_FROM_HANDLE(radv_device, device, device_h);
+ struct radv_physical_device *pdev = radv_device_physical(device);
+
+ /* Get a description of buffer contents . */
+ AHardwareBuffer_Desc desc;
+ AHardwareBuffer_describe(buffer, &desc);
+
+ /* Verify description. */
+ const uint64_t gpu_usage = AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE | AHARDWAREBUFFER_USAGE_GPU_COLOR_OUTPUT |
+ AHARDWAREBUFFER_USAGE_GPU_DATA_BUFFER;
+
+ /* "Buffer must be a valid Android hardware buffer object with at least
+ * one of the AHARDWAREBUFFER_USAGE_GPU_* usage flags."
+ */
+ if (!(desc.usage & (gpu_usage)))
+ return VK_ERROR_INVALID_EXTERNAL_HANDLE;
+
+ /* Fill properties fields based on description. */
+ VkAndroidHardwareBufferFormatProperties2ANDROID *p = pProperties;
+
+ p->format = vk_format_from_android(desc.format, desc.usage);
+ p->externalFormat = (uint64_t)(uintptr_t)p->format;
+
+ VkFormatProperties2 format_properties = {.sType = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2};
+
+ radv_GetPhysicalDeviceFormatProperties2(radv_physical_device_to_handle(pdev), p->format, &format_properties);
+
+ if (desc.usage & AHARDWAREBUFFER_USAGE_GPU_DATA_BUFFER)
+ p->formatFeatures = format_properties.formatProperties.linearTilingFeatures;
+ else
+ p->formatFeatures = format_properties.formatProperties.optimalTilingFeatures;
+
+ /* "Images can be created with an external format even if the Android hardware
+ * buffer has a format which has an equivalent Vulkan format to enable
+ * consistent handling of images from sources that might use either category
+ * of format. However, all images created with an external format are subject
+ * to the valid usage requirements associated with external formats, even if
+ * the Android hardware buffer’s format has a Vulkan equivalent."
+ *
+ * "The formatFeatures member *must* include
+ * VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_BIT and at least one of
+ * VK_FORMAT_FEATURE_2_MIDPOINT_CHROMA_SAMPLES_BIT or
+ * VK_FORMAT_FEATURE_2_COSITED_CHROMA_SAMPLES_BIT"
+ */
+ assert(p->formatFeatures & VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_BIT);
+
+ p->formatFeatures |= VK_FORMAT_FEATURE_2_MIDPOINT_CHROMA_SAMPLES_BIT;
+
+ /* "Implementations may not always be able to determine the color model,
+ * numerical range, or chroma offsets of the image contents, so the values
+ * in VkAndroidHardwareBufferFormatPropertiesANDROID are only suggestions.
+ * Applications should treat these values as sensible defaults to use in
+ * the absence of more reliable information obtained through some other
+ * means."
+ */
+ p->samplerYcbcrConversionComponents.r = VK_COMPONENT_SWIZZLE_IDENTITY;
+ p->samplerYcbcrConversionComponents.g = VK_COMPONENT_SWIZZLE_IDENTITY;
+ p->samplerYcbcrConversionComponents.b = VK_COMPONENT_SWIZZLE_IDENTITY;
+ p->samplerYcbcrConversionComponents.a = VK_COMPONENT_SWIZZLE_IDENTITY;
+
+ p->suggestedYcbcrModel = VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_601;
+ p->suggestedYcbcrRange = VK_SAMPLER_YCBCR_RANGE_ITU_FULL;
+
+ p->suggestedXChromaOffset = VK_CHROMA_LOCATION_MIDPOINT;
+ p->suggestedYChromaOffset = VK_CHROMA_LOCATION_MIDPOINT;
+
+ return VK_SUCCESS;
+}
+
VkResult
-radv_GetAndroidHardwareBufferPropertiesANDROID(VkDevice device_h,
- const struct AHardwareBuffer *buffer,
+radv_GetAndroidHardwareBufferPropertiesANDROID(VkDevice device_h, const struct AHardwareBuffer *buffer,
VkAndroidHardwareBufferPropertiesANDROID *pProperties)
{
- RADV_FROM_HANDLE(radv_device, dev, device_h);
- struct radv_physical_device *pdevice = dev->physical_device;
+ VK_FROM_HANDLE(radv_device, dev, device_h);
+ struct radv_physical_device *pdev = radv_device_physical(dev);
VkAndroidHardwareBufferFormatPropertiesANDROID *format_prop =
vk_find_struct(pProperties->pNext, ANDROID_HARDWARE_BUFFER_FORMAT_PROPERTIES_ANDROID);
@@ -666,6 +553,11 @@ radv_GetAndroidHardwareBufferPropertiesANDROID(VkDevice device_h,
if (format_prop)
get_ahb_buffer_format_properties(device_h, buffer, format_prop);
+ VkAndroidHardwareBufferFormatProperties2ANDROID *format_prop2 =
+ vk_find_struct(pProperties->pNext, ANDROID_HARDWARE_BUFFER_FORMAT_PROPERTIES_2_ANDROID);
+ if (format_prop2)
+ get_ahb_buffer_format_properties2(device_h, buffer, format_prop2);
+
/* NOTE - We support buffers with only one handle but do not error on
* multiple handle case. Reason is that we want to support YUV formats
* where we have many logical planes but they all point to the same
@@ -677,20 +569,19 @@ radv_GetAndroidHardwareBufferPropertiesANDROID(VkDevice device_h,
return VK_ERROR_INVALID_EXTERNAL_HANDLE;
/* All memory types. */
- uint32_t memory_types = (1u << pdevice->memory_properties.memoryTypeCount) - 1;
+ uint32_t memory_types = (1u << pdev->memory_properties.memoryTypeCount) - 1;
pProperties->allocationSize = lseek(dma_buf, 0, SEEK_END);
- pProperties->memoryTypeBits = memory_types;
+ pProperties->memoryTypeBits = memory_types & ~pdev->memory_types_32bit;
return VK_SUCCESS;
}
VkResult
-radv_GetMemoryAndroidHardwareBufferANDROID(VkDevice device_h,
- const VkMemoryGetAndroidHardwareBufferInfoANDROID *pInfo,
+radv_GetMemoryAndroidHardwareBufferANDROID(VkDevice device_h, const VkMemoryGetAndroidHardwareBufferInfoANDROID *pInfo,
struct AHardwareBuffer **pBuffer)
{
- RADV_FROM_HANDLE(radv_device_memory, mem, pInfo->memory);
+ VK_FROM_HANDLE(radv_device_memory, mem, pInfo->memory);
/* This should always be set due to the export handle types being set on
* allocation. */
@@ -718,8 +609,7 @@ VkFormat
radv_select_android_external_format(const void *next, VkFormat default_format)
{
#if RADV_SUPPORT_ANDROID_HARDWARE_BUFFER
- const VkExternalFormatANDROID *android_format =
- vk_find_struct_const(next, EXTERNAL_FORMAT_ANDROID);
+ const VkExternalFormatANDROID *android_format = vk_find_struct_const(next, EXTERNAL_FORMAT_ANDROID);
if (android_format && android_format->externalFormat) {
return (VkFormat)android_format->externalFormat;
@@ -730,8 +620,8 @@ radv_select_android_external_format(const void *next, VkFormat default_format)
}
VkResult
-radv_import_ahb_memory(struct radv_device *device, struct radv_device_memory *mem,
- unsigned priority, const VkImportAndroidHardwareBufferInfoANDROID *info)
+radv_import_ahb_memory(struct radv_device *device, struct radv_device_memory *mem, unsigned priority,
+ const VkImportAndroidHardwareBufferInfoANDROID *info)
{
#if RADV_SUPPORT_ANDROID_HARDWARE_BUFFER
/* Import from AHardwareBuffer to radv_device_memory. */
@@ -747,8 +637,7 @@ radv_import_ahb_memory(struct radv_device *device, struct radv_device_memory *me
return VK_ERROR_INVALID_EXTERNAL_HANDLE;
uint64_t alloc_size = 0;
- VkResult result =
- device->ws->buffer_from_fd(device->ws, dma_buf, priority, &mem->bo, &alloc_size);
+ VkResult result = device->ws->buffer_from_fd(device->ws, dma_buf, priority, &mem->bo, &alloc_size);
if (result != VK_SUCCESS)
return result;
@@ -756,24 +645,23 @@ radv_import_ahb_memory(struct radv_device *device, struct radv_device_memory *me
struct radeon_bo_metadata metadata;
device->ws->buffer_get_metadata(device->ws, mem->bo, &metadata);
- struct radv_image_create_info create_info = {.no_metadata_planes = true,
- .bo_metadata = &metadata};
+ struct radv_image_create_info create_info = {.no_metadata_planes = true, .bo_metadata = &metadata};
- VkResult result = radv_image_create_layout(device, create_info, NULL, mem->image);
+ result = radv_image_create_layout(device, create_info, NULL, NULL, mem->image);
if (result != VK_SUCCESS) {
- device->ws->buffer_destroy(device->ws, mem->bo);
+ radv_bo_destroy(device, NULL, mem->bo);
mem->bo = NULL;
return result;
}
if (alloc_size < mem->image->size) {
- device->ws->buffer_destroy(device->ws, mem->bo);
+ radv_bo_destroy(device, NULL, mem->bo);
mem->bo = NULL;
return VK_ERROR_INVALID_EXTERNAL_HANDLE;
}
} else if (mem->buffer) {
- if (alloc_size < mem->buffer->size) {
- device->ws->buffer_destroy(device->ws, mem->bo);
+ if (alloc_size < mem->buffer->vk.size) {
+ radv_bo_destroy(device, NULL, mem->bo);
mem->bo = NULL;
return VK_ERROR_INVALID_EXTERNAL_HANDLE;
}
@@ -794,52 +682,14 @@ radv_import_ahb_memory(struct radv_device *device, struct radv_device_memory *me
}
VkResult
-radv_create_ahb_memory(struct radv_device *device, struct radv_device_memory *mem,
- unsigned priority, const VkMemoryAllocateInfo *pAllocateInfo)
+radv_create_ahb_memory(struct radv_device *device, struct radv_device_memory *mem, unsigned priority,
+ const VkMemoryAllocateInfo *pAllocateInfo)
{
#if RADV_SUPPORT_ANDROID_HARDWARE_BUFFER
- const VkMemoryDedicatedAllocateInfo *dedicated_info =
- vk_find_struct_const(pAllocateInfo->pNext, MEMORY_DEDICATED_ALLOCATE_INFO);
-
- uint32_t w = 0;
- uint32_t h = 1;
- uint32_t layers = 1;
- uint32_t format = 0;
- uint64_t usage = 0;
-
- /* If caller passed dedicated information. */
- if (dedicated_info && dedicated_info->image) {
- RADV_FROM_HANDLE(radv_image, image, dedicated_info->image);
- w = image->info.width;
- h = image->info.height;
- layers = image->info.array_size;
- format = android_format_from_vk(image->vk_format);
- usage = radv_ahb_usage_from_vk_usage(image->flags, image->usage);
- } else if (dedicated_info && dedicated_info->buffer) {
- RADV_FROM_HANDLE(radv_buffer, buffer, dedicated_info->buffer);
- w = buffer->size;
- format = AHARDWAREBUFFER_FORMAT_BLOB;
- usage = AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN | AHARDWAREBUFFER_USAGE_CPU_WRITE_OFTEN;
- } else {
- w = pAllocateInfo->allocationSize;
- format = AHARDWAREBUFFER_FORMAT_BLOB;
- usage = AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN | AHARDWAREBUFFER_USAGE_CPU_WRITE_OFTEN;
- }
-
- struct AHardwareBuffer *android_hardware_buffer = NULL;
- struct AHardwareBuffer_Desc desc = {
- .width = w,
- .height = h,
- .layers = layers,
- .format = format,
- .usage = usage,
- };
-
- if (AHardwareBuffer_allocate(&desc, &android_hardware_buffer) != 0)
+ mem->android_hardware_buffer = vk_alloc_ahardware_buffer(pAllocateInfo);
+ if (mem->android_hardware_buffer == NULL)
return VK_ERROR_OUT_OF_HOST_MEMORY;
- mem->android_hardware_buffer = android_hardware_buffer;
-
const struct VkImportAndroidHardwareBufferInfoANDROID import_info = {
.buffer = mem->android_hardware_buffer,
};
@@ -859,21 +709,11 @@ bool
radv_android_gralloc_supports_format(VkFormat format, VkImageUsageFlagBits usage)
{
#if RADV_SUPPORT_ANDROID_HARDWARE_BUFFER
- /* Ideally we check Gralloc for what it supports and then merge that with the radv
- format support, but there is no easy gralloc query besides just creating an image.
- That seems a bit on the expensive side, so just hardcode for now. */
- /* TODO: Add multi-plane formats after confirming everything works between radeonsi
- and radv. */
- switch (format) {
- case VK_FORMAT_R8G8B8A8_UNORM:
- case VK_FORMAT_R5G6B5_UNORM_PACK16:
- return true;
- case VK_FORMAT_R8_UNORM:
- case VK_FORMAT_R8G8_UNORM:
- return !(usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT);
- default:
- return false;
- }
+ /* Ideally we check AHardwareBuffer_isSupported. But that test-allocates on most platforms and
+ * seems a bit on the expensive side. Return true as long as it is a format we understand.
+ */
+ (void)usage;
+ return radv_ahb_format_for_vk_format(format);
#else
(void)format;
(void)usage;