venus: implement VK_ANDROID_native_buffer v7
1. Android native buffer import 2. vkGetSwapchainGrallocUsage2ANDROID 3. vkAcquireImageANDROID 4. vkQueueSignalReleaseImageANDROID 5. not advertise shared presentable image support Signed-off-by: Yiwei Zhang <zzyiwei@chromium.org> Reviewed-by: Chia-I Wu <olvaffe@gmail.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/10259>
This commit is contained in:
@@ -86,6 +86,8 @@ endif
|
|||||||
|
|
||||||
if with_platform_android
|
if with_platform_android
|
||||||
libvn_files += files('vn_android.c')
|
libvn_files += files('vn_android.c')
|
||||||
|
vn_deps += dep_android
|
||||||
|
vn_flags += '-DVK_USE_PLATFORM_ANDROID_KHR'
|
||||||
endif
|
endif
|
||||||
|
|
||||||
libvulkan_virtio = shared_library(
|
libvulkan_virtio = shared_library(
|
||||||
|
@@ -1,13 +1,27 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2021 Google LLC
|
* Copyright 2021 Google LLC
|
||||||
* SPDX-License-Identifier: MIT
|
* SPDX-License-Identifier: MIT
|
||||||
|
*
|
||||||
|
* based in part on anv and radv which are:
|
||||||
|
* Copyright © 2015 Intel Corporation
|
||||||
|
* Copyright © 2016 Red Hat
|
||||||
|
* Copyright © 2016 Bas Nieuwenhuizen
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "vn_android.h"
|
||||||
#include "vn_common.h"
|
#include "vn_common.h"
|
||||||
|
|
||||||
#include <hardware/hwvulkan.h>
|
#include <hardware/hwvulkan.h>
|
||||||
|
#include <vndk/hardware_buffer.h>
|
||||||
#include <vulkan/vk_icd.h>
|
#include <vulkan/vk_icd.h>
|
||||||
|
|
||||||
|
#include "util/libsync.h"
|
||||||
|
#include "util/os_file.h"
|
||||||
|
|
||||||
|
#include "vn_device.h"
|
||||||
|
#include "vn_image.h"
|
||||||
|
#include "vn_queue.h"
|
||||||
|
|
||||||
static int
|
static int
|
||||||
vn_hal_open(const struct hw_module_t *mod,
|
vn_hal_open(const struct hw_module_t *mod,
|
||||||
const char *id,
|
const char *id,
|
||||||
@@ -62,3 +76,250 @@ vn_hal_open(const struct hw_module_t *mod,
|
|||||||
*dev = &vn_hal_dev.common;
|
*dev = &vn_hal_dev.common;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VkResult
|
||||||
|
vn_GetSwapchainGrallocUsage2ANDROID(
|
||||||
|
VkDevice device,
|
||||||
|
VkFormat format,
|
||||||
|
VkImageUsageFlags imageUsage,
|
||||||
|
VkSwapchainImageUsageFlagsANDROID swapchainImageUsage,
|
||||||
|
uint64_t *grallocConsumerUsage,
|
||||||
|
uint64_t *grallocProducerUsage)
|
||||||
|
{
|
||||||
|
struct vn_device *dev = vn_device_from_handle(device);
|
||||||
|
*grallocConsumerUsage = 0;
|
||||||
|
*grallocProducerUsage = 0;
|
||||||
|
|
||||||
|
if (swapchainImageUsage & VK_SWAPCHAIN_IMAGE_USAGE_SHARED_BIT_ANDROID)
|
||||||
|
return vn_error(dev->instance, VK_ERROR_INITIALIZATION_FAILED);
|
||||||
|
|
||||||
|
if (VN_DEBUG(WSI))
|
||||||
|
vn_log(dev->instance, "format=%d, imageUsage=0x%x", format, imageUsage);
|
||||||
|
|
||||||
|
if (imageUsage & (VK_IMAGE_USAGE_TRANSFER_DST_BIT |
|
||||||
|
VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT))
|
||||||
|
*grallocProducerUsage |= AHARDWAREBUFFER_USAGE_GPU_FRAMEBUFFER;
|
||||||
|
|
||||||
|
if (imageUsage &
|
||||||
|
(VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_SAMPLED_BIT |
|
||||||
|
VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT))
|
||||||
|
*grallocConsumerUsage |= AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE;
|
||||||
|
|
||||||
|
return VK_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
VkResult
|
||||||
|
vn_image_from_anb(struct vn_device *dev,
|
||||||
|
const VkImageCreateInfo *image_info,
|
||||||
|
const VkNativeBufferANDROID *anb_info,
|
||||||
|
const VkAllocationCallbacks *alloc,
|
||||||
|
struct vn_image **out_img)
|
||||||
|
{
|
||||||
|
/* If anb_info->handle points to a classic resouce created from
|
||||||
|
* virtio_gpu_cmd_resource_create_3d, anb_info->stride is the stride of the
|
||||||
|
* guest shadow storage other than the host gpu storage.
|
||||||
|
*
|
||||||
|
* We also need to pass the correct stride to vn_CreateImage, which will be
|
||||||
|
* done via VkImageDrmFormatModifierExplicitCreateInfoEXT and will require
|
||||||
|
* VK_EXT_image_drm_format_modifier support in the host driver. The struct
|
||||||
|
* also needs a modifier, which can only be encoded in anb_info->handle.
|
||||||
|
*
|
||||||
|
* Given above, until gralloc gets fixed to set stride correctly and to
|
||||||
|
* encode modifier in the native handle, we will have to make assumptions.
|
||||||
|
* (e.g. In CrOS, there's a VIRTGPU_RESOURCE_INFO_TYPE_EXTENDED kernel hack
|
||||||
|
* for that)
|
||||||
|
*/
|
||||||
|
VkResult result = VK_SUCCESS;
|
||||||
|
VkDevice device = vn_device_to_handle(dev);
|
||||||
|
VkDeviceMemory memory = VK_NULL_HANDLE;
|
||||||
|
VkImage image = VK_NULL_HANDLE;
|
||||||
|
struct vn_image *img = NULL;
|
||||||
|
uint32_t mem_type_bits = 0;
|
||||||
|
int dma_buf_fd = -1;
|
||||||
|
int dup_fd = -1;
|
||||||
|
|
||||||
|
/* encoder will strip the Android specific pNext structs */
|
||||||
|
result = vn_image_create(dev, image_info, alloc, &img);
|
||||||
|
if (result != VK_SUCCESS)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
image = vn_image_to_handle(img);
|
||||||
|
VkMemoryRequirements mem_req;
|
||||||
|
vn_GetImageMemoryRequirements(device, image, &mem_req);
|
||||||
|
if (!mem_req.memoryTypeBits) {
|
||||||
|
result = VK_ERROR_INVALID_EXTERNAL_HANDLE;
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (anb_info->handle->numFds != 1) {
|
||||||
|
if (VN_DEBUG(WSI))
|
||||||
|
vn_log(dev->instance, "handle->numFds is %d, expected 1",
|
||||||
|
anb_info->handle->numFds);
|
||||||
|
result = VK_ERROR_INVALID_EXTERNAL_HANDLE;
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
dma_buf_fd = anb_info->handle->data[0];
|
||||||
|
if (dma_buf_fd < 0) {
|
||||||
|
result = VK_ERROR_INVALID_EXTERNAL_HANDLE;
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
VkMemoryFdPropertiesKHR fd_prop = {
|
||||||
|
.sType = VK_STRUCTURE_TYPE_MEMORY_FD_PROPERTIES_KHR,
|
||||||
|
.pNext = NULL,
|
||||||
|
.memoryTypeBits = 0,
|
||||||
|
};
|
||||||
|
result = vn_GetMemoryFdPropertiesKHR(
|
||||||
|
device, VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT, dma_buf_fd,
|
||||||
|
&fd_prop);
|
||||||
|
if (result != VK_SUCCESS)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
if (!fd_prop.memoryTypeBits) {
|
||||||
|
result = VK_ERROR_INVALID_EXTERNAL_HANDLE;
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (VN_DEBUG(WSI))
|
||||||
|
vn_log(dev->instance, "memoryTypeBits = img(0x%X) & fd(0x%X)",
|
||||||
|
mem_req.memoryTypeBits, fd_prop.memoryTypeBits);
|
||||||
|
|
||||||
|
mem_type_bits = mem_req.memoryTypeBits & fd_prop.memoryTypeBits;
|
||||||
|
if (!mem_type_bits) {
|
||||||
|
result = VK_ERROR_INVALID_EXTERNAL_HANDLE;
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
dup_fd = os_dupfd_cloexec(dma_buf_fd);
|
||||||
|
if (dup_fd < 0) {
|
||||||
|
result = (errno == EMFILE) ? VK_ERROR_TOO_MANY_OBJECTS
|
||||||
|
: VK_ERROR_OUT_OF_HOST_MEMORY;
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
const VkImportMemoryFdInfoKHR import_fd_info = {
|
||||||
|
.sType = VK_STRUCTURE_TYPE_IMPORT_MEMORY_FD_INFO_KHR,
|
||||||
|
.pNext = NULL,
|
||||||
|
.handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT,
|
||||||
|
.fd = dup_fd,
|
||||||
|
};
|
||||||
|
const VkMemoryAllocateInfo memory_info = {
|
||||||
|
.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
|
||||||
|
.pNext = &import_fd_info,
|
||||||
|
.allocationSize = mem_req.size,
|
||||||
|
.memoryTypeIndex = ffs(mem_type_bits) - 1,
|
||||||
|
};
|
||||||
|
result = vn_AllocateMemory(device, &memory_info, alloc, &memory);
|
||||||
|
if (result != VK_SUCCESS) {
|
||||||
|
/* only need to close the dup_fd on import failure */
|
||||||
|
close(dup_fd);
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
result = vn_BindImageMemory(device, image, memory, 0);
|
||||||
|
if (result != VK_SUCCESS)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
/* Android WSI image owns the memory */
|
||||||
|
img->private_memory = memory;
|
||||||
|
*out_img = img;
|
||||||
|
|
||||||
|
return VK_SUCCESS;
|
||||||
|
|
||||||
|
fail:
|
||||||
|
if (image != VK_NULL_HANDLE)
|
||||||
|
vn_DestroyImage(device, image, alloc);
|
||||||
|
if (memory != VK_NULL_HANDLE)
|
||||||
|
vn_FreeMemory(device, memory, alloc);
|
||||||
|
return vn_error(dev->instance, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
VkResult
|
||||||
|
vn_AcquireImageANDROID(VkDevice device,
|
||||||
|
UNUSED VkImage image,
|
||||||
|
int nativeFenceFd,
|
||||||
|
VkSemaphore semaphore,
|
||||||
|
VkFence fence)
|
||||||
|
{
|
||||||
|
/* At this moment, out semaphore and fence are filled with already signaled
|
||||||
|
* payloads, and the native fence fd is waited inside until signaled.
|
||||||
|
*/
|
||||||
|
struct vn_device *dev = vn_device_from_handle(device);
|
||||||
|
struct vn_semaphore *sem = vn_semaphore_from_handle(semaphore);
|
||||||
|
struct vn_fence *fen = vn_fence_from_handle(fence);
|
||||||
|
|
||||||
|
if (nativeFenceFd >= 0) {
|
||||||
|
int ret = sync_wait(nativeFenceFd, INT32_MAX);
|
||||||
|
/* Android loader expects the ICD to always close the fd */
|
||||||
|
close(nativeFenceFd);
|
||||||
|
if (ret)
|
||||||
|
return vn_error(dev->instance, VK_ERROR_SURFACE_LOST_KHR);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sem)
|
||||||
|
vn_semaphore_signal_wsi(dev, sem);
|
||||||
|
|
||||||
|
if (fen)
|
||||||
|
vn_fence_signal_wsi(dev, fen);
|
||||||
|
|
||||||
|
return VK_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
VkResult
|
||||||
|
vn_QueueSignalReleaseImageANDROID(VkQueue queue,
|
||||||
|
uint32_t waitSemaphoreCount,
|
||||||
|
const VkSemaphore *pWaitSemaphores,
|
||||||
|
VkImage image,
|
||||||
|
int *pNativeFenceFd)
|
||||||
|
{
|
||||||
|
/* At this moment, the wait semaphores are converted to a VkFence via an
|
||||||
|
* empty submit. The VkFence is then waited inside until signaled, and the
|
||||||
|
* out native fence fd is set to -1.
|
||||||
|
*/
|
||||||
|
VkResult result = VK_SUCCESS;
|
||||||
|
struct vn_queue *que = vn_queue_from_handle(queue);
|
||||||
|
const VkAllocationCallbacks *alloc = &que->device->base.base.alloc;
|
||||||
|
VkDevice device = vn_device_to_handle(que->device);
|
||||||
|
VkPipelineStageFlags local_stage_masks[8];
|
||||||
|
VkPipelineStageFlags *stage_masks = local_stage_masks;
|
||||||
|
|
||||||
|
if (waitSemaphoreCount == 0)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
if (waitSemaphoreCount > ARRAY_SIZE(local_stage_masks)) {
|
||||||
|
stage_masks =
|
||||||
|
vk_alloc(alloc, sizeof(VkPipelineStageFlags) * waitSemaphoreCount,
|
||||||
|
VN_DEFAULT_ALIGN, VK_SYSTEM_ALLOCATION_SCOPE_COMMAND);
|
||||||
|
if (!stage_masks) {
|
||||||
|
result = VK_ERROR_OUT_OF_HOST_MEMORY;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (uint32_t i = 0; i < waitSemaphoreCount; i++)
|
||||||
|
stage_masks[i] = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
|
||||||
|
|
||||||
|
const VkSubmitInfo submit_info = {
|
||||||
|
.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO,
|
||||||
|
.pNext = NULL,
|
||||||
|
.waitSemaphoreCount = waitSemaphoreCount,
|
||||||
|
.pWaitSemaphores = pWaitSemaphores,
|
||||||
|
.pWaitDstStageMask = stage_masks,
|
||||||
|
.commandBufferCount = 0,
|
||||||
|
.pCommandBuffers = NULL,
|
||||||
|
.signalSemaphoreCount = 0,
|
||||||
|
.pSignalSemaphores = NULL,
|
||||||
|
};
|
||||||
|
result = vn_QueueSubmit(queue, 1, &submit_info, que->wait_fence);
|
||||||
|
if (result != VK_SUCCESS)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
result =
|
||||||
|
vn_WaitForFences(device, 1, &que->wait_fence, VK_TRUE, UINT64_MAX);
|
||||||
|
vn_ResetFences(device, 1, &que->wait_fence);
|
||||||
|
|
||||||
|
out:
|
||||||
|
*pNativeFenceFd = -1;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
30
src/virtio/vulkan/vn_android.h
Normal file
30
src/virtio/vulkan/vn_android.h
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2021 Google LLC
|
||||||
|
* SPDX-License-Identifier: MIT
|
||||||
|
*
|
||||||
|
* based in part on anv and radv which are:
|
||||||
|
* Copyright © 2015 Intel Corporation
|
||||||
|
* Copyright © 2016 Red Hat
|
||||||
|
* Copyright © 2016 Bas Nieuwenhuizen
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef VN_ANDROID_H
|
||||||
|
#define VN_ANDROID_H
|
||||||
|
|
||||||
|
#include <vulkan/vk_android_native_buffer.h>
|
||||||
|
#include <vulkan/vulkan.h>
|
||||||
|
|
||||||
|
/* venus implements VK_ANDROID_native_buffer up to spec version 7 */
|
||||||
|
#define VN_ANDROID_NATIVE_BUFFER_SPEC_VERSION 7
|
||||||
|
|
||||||
|
struct vn_device;
|
||||||
|
struct vn_image;
|
||||||
|
|
||||||
|
VkResult
|
||||||
|
vn_image_from_anb(struct vn_device *dev,
|
||||||
|
const VkImageCreateInfo *image_info,
|
||||||
|
const VkNativeBufferANDROID *anb_info,
|
||||||
|
const VkAllocationCallbacks *alloc,
|
||||||
|
struct vn_image **out_img);
|
||||||
|
|
||||||
|
#endif /* VN_ANDROID_H */
|
@@ -20,6 +20,7 @@
|
|||||||
#include "venus-protocol/vn_protocol_driver_instance.h"
|
#include "venus-protocol/vn_protocol_driver_instance.h"
|
||||||
#include "venus-protocol/vn_protocol_driver_transport.h"
|
#include "venus-protocol/vn_protocol_driver_transport.h"
|
||||||
|
|
||||||
|
#include "vn_android.h"
|
||||||
#include "vn_device_memory.h"
|
#include "vn_device_memory.h"
|
||||||
#include "vn_icd.h"
|
#include "vn_icd.h"
|
||||||
#include "vn_queue.h"
|
#include "vn_queue.h"
|
||||||
@@ -1413,6 +1414,9 @@ vn_physical_device_get_supported_extensions(
|
|||||||
.KHR_incremental_present = true,
|
.KHR_incremental_present = true,
|
||||||
.KHR_swapchain = true,
|
.KHR_swapchain = true,
|
||||||
.KHR_swapchain_mutable_format = true,
|
.KHR_swapchain_mutable_format = true,
|
||||||
|
#endif
|
||||||
|
#ifdef ANDROID
|
||||||
|
.ANDROID_native_buffer = true,
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -1535,6 +1539,13 @@ vn_physical_device_init_extensions(struct vn_physical_device *physical_dev)
|
|||||||
if (supported.extensions[i]) {
|
if (supported.extensions[i]) {
|
||||||
physical_dev->base.base.supported_extensions.extensions[i] = true;
|
physical_dev->base.base.supported_extensions.extensions[i] = true;
|
||||||
physical_dev->extension_spec_versions[i] = props->specVersion;
|
physical_dev->extension_spec_versions[i] = props->specVersion;
|
||||||
|
#ifdef ANDROID
|
||||||
|
/* override VK_ANDROID_native_buffer spec version */
|
||||||
|
if (!strcmp(props->extensionName,
|
||||||
|
VK_ANDROID_NATIVE_BUFFER_EXTENSION_NAME))
|
||||||
|
physical_dev->extension_spec_versions[i] =
|
||||||
|
VN_ANDROID_NATIVE_BUFFER_SPEC_VERSION;
|
||||||
|
#endif
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2380,12 +2391,13 @@ vn_GetPhysicalDeviceProperties2(VkPhysicalDevice physicalDevice,
|
|||||||
|
|
||||||
VkPhysicalDevicePCIBusInfoPropertiesEXT *pci_bus_info;
|
VkPhysicalDevicePCIBusInfoPropertiesEXT *pci_bus_info;
|
||||||
VkPhysicalDeviceTransformFeedbackPropertiesEXT *transform_feedback;
|
VkPhysicalDeviceTransformFeedbackPropertiesEXT *transform_feedback;
|
||||||
|
VkPhysicalDevicePresentationPropertiesANDROID *presentation_properties;
|
||||||
} u;
|
} u;
|
||||||
|
|
||||||
u.pnext = (VkBaseOutStructure *)pProperties;
|
u.pnext = (VkBaseOutStructure *)pProperties;
|
||||||
while (u.pnext) {
|
while (u.pnext) {
|
||||||
void *saved = u.pnext->pNext;
|
void *saved = u.pnext->pNext;
|
||||||
switch (u.pnext->sType) {
|
switch ((int32_t)u.pnext->sType) {
|
||||||
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2:
|
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2:
|
||||||
memcpy(u.pnext, &physical_dev->properties,
|
memcpy(u.pnext, &physical_dev->properties,
|
||||||
sizeof(physical_dev->properties));
|
sizeof(physical_dev->properties));
|
||||||
@@ -2576,6 +2588,9 @@ vn_GetPhysicalDeviceProperties2(VkPhysicalDevice physicalDevice,
|
|||||||
&physical_dev->transform_feedback_properties,
|
&physical_dev->transform_feedback_properties,
|
||||||
sizeof(physical_dev->transform_feedback_properties));
|
sizeof(physical_dev->transform_feedback_properties));
|
||||||
break;
|
break;
|
||||||
|
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRESENTATION_PROPERTIES_ANDROID:
|
||||||
|
u.presentation_properties->sharedImage = VK_FALSE;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -2908,52 +2923,65 @@ find_extension_names(const char *const *exts,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char **
|
static bool
|
||||||
merge_extension_names(const char *const *exts,
|
merge_extension_names(const char *const *exts,
|
||||||
uint32_t ext_count,
|
uint32_t ext_count,
|
||||||
const char *const *extra_exts,
|
const char *const *extra_exts,
|
||||||
uint32_t extra_count,
|
uint32_t extra_count,
|
||||||
|
const char *const *block_exts,
|
||||||
|
uint32_t block_count,
|
||||||
const VkAllocationCallbacks *alloc,
|
const VkAllocationCallbacks *alloc,
|
||||||
uint32_t *merged_count)
|
const char *const **out_exts,
|
||||||
|
uint32_t *out_count)
|
||||||
{
|
{
|
||||||
const char **merged =
|
const char **merged =
|
||||||
vk_alloc(alloc, sizeof(*merged) * (ext_count + extra_count),
|
vk_alloc(alloc, sizeof(*merged) * (ext_count + extra_count),
|
||||||
VN_DEFAULT_ALIGN, VK_SYSTEM_ALLOCATION_SCOPE_COMMAND);
|
VN_DEFAULT_ALIGN, VK_SYSTEM_ALLOCATION_SCOPE_COMMAND);
|
||||||
if (!merged)
|
if (!merged)
|
||||||
return NULL;
|
return false;
|
||||||
|
|
||||||
memcpy(merged, exts, sizeof(*exts) * ext_count);
|
uint32_t count = 0;
|
||||||
|
for (uint32_t i = 0; i < ext_count; i++) {
|
||||||
uint32_t count = ext_count;
|
if (!find_extension_names(block_exts, block_count, exts[i]))
|
||||||
|
merged[count++] = exts[i];
|
||||||
|
}
|
||||||
for (uint32_t i = 0; i < extra_count; i++) {
|
for (uint32_t i = 0; i < extra_count; i++) {
|
||||||
if (!find_extension_names(exts, ext_count, extra_exts[i]))
|
if (!find_extension_names(exts, ext_count, extra_exts[i]))
|
||||||
merged[count++] = extra_exts[i];
|
merged[count++] = extra_exts[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
*merged_count = count;
|
*out_exts = merged;
|
||||||
return merged;
|
*out_count = count;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const VkDeviceCreateInfo *
|
static const VkDeviceCreateInfo *
|
||||||
vn_device_fix_create_info(const struct vn_physical_device *physical_dev,
|
vn_device_fix_create_info(const struct vn_device *dev,
|
||||||
const VkDeviceCreateInfo *dev_info,
|
const VkDeviceCreateInfo *dev_info,
|
||||||
const VkAllocationCallbacks *alloc,
|
const VkAllocationCallbacks *alloc,
|
||||||
VkDeviceCreateInfo *local_info)
|
VkDeviceCreateInfo *local_info)
|
||||||
{
|
{
|
||||||
|
/* extra_exts and block_exts must not overlap */
|
||||||
const char *extra_exts[8];
|
const char *extra_exts[8];
|
||||||
|
const char *block_exts[8];
|
||||||
uint32_t extra_count = 0;
|
uint32_t extra_count = 0;
|
||||||
|
uint32_t block_count = 0;
|
||||||
|
|
||||||
if (physical_dev->wsi_device.supports_modifiers)
|
if (dev->physical_device->wsi_device.supports_modifiers)
|
||||||
extra_exts[extra_count++] = "VK_EXT_image_drm_format_modifier";
|
extra_exts[extra_count++] = "VK_EXT_image_drm_format_modifier";
|
||||||
|
|
||||||
if (!extra_count)
|
if (dev->base.base.enabled_extensions.ANDROID_native_buffer)
|
||||||
|
block_exts[block_count++] = VK_ANDROID_NATIVE_BUFFER_EXTENSION_NAME;
|
||||||
|
|
||||||
|
if (!extra_count && (!block_count || !dev_info->enabledExtensionCount))
|
||||||
return dev_info;
|
return dev_info;
|
||||||
|
|
||||||
*local_info = *dev_info;
|
*local_info = *dev_info;
|
||||||
local_info->ppEnabledExtensionNames = merge_extension_names(
|
if (!merge_extension_names(dev_info->ppEnabledExtensionNames,
|
||||||
dev_info->ppEnabledExtensionNames, dev_info->enabledExtensionCount,
|
dev_info->enabledExtensionCount, extra_exts,
|
||||||
extra_exts, extra_count, alloc, &local_info->enabledExtensionCount);
|
extra_count, block_exts, block_count, alloc,
|
||||||
if (!local_info->ppEnabledExtensionNames)
|
&local_info->ppEnabledExtensionNames,
|
||||||
|
&local_info->enabledExtensionCount))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
return local_info;
|
return local_info;
|
||||||
@@ -2992,8 +3020,8 @@ vn_CreateDevice(VkPhysicalDevice physicalDevice,
|
|||||||
dev->physical_device = physical_dev;
|
dev->physical_device = physical_dev;
|
||||||
|
|
||||||
VkDeviceCreateInfo local_create_info;
|
VkDeviceCreateInfo local_create_info;
|
||||||
pCreateInfo = vn_device_fix_create_info(physical_dev, pCreateInfo, alloc,
|
pCreateInfo =
|
||||||
&local_create_info);
|
vn_device_fix_create_info(dev, pCreateInfo, alloc, &local_create_info);
|
||||||
if (!pCreateInfo) {
|
if (!pCreateInfo) {
|
||||||
result = VK_ERROR_OUT_OF_HOST_MEMORY;
|
result = VK_ERROR_OUT_OF_HOST_MEMORY;
|
||||||
goto fail;
|
goto fail;
|
||||||
|
@@ -15,6 +15,7 @@
|
|||||||
#include "venus-protocol/vn_protocol_driver_sampler.h"
|
#include "venus-protocol/vn_protocol_driver_sampler.h"
|
||||||
#include "venus-protocol/vn_protocol_driver_sampler_ycbcr_conversion.h"
|
#include "venus-protocol/vn_protocol_driver_sampler_ycbcr_conversion.h"
|
||||||
|
|
||||||
|
#include "vn_android.h"
|
||||||
#include "vn_device.h"
|
#include "vn_device.h"
|
||||||
#include "vn_device_memory.h"
|
#include "vn_device_memory.h"
|
||||||
|
|
||||||
@@ -153,6 +154,15 @@ vn_CreateImage(VkDevice device,
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef ANDROID
|
||||||
|
const VkNativeBufferANDROID *anb_info =
|
||||||
|
vk_find_struct_const(pCreateInfo->pNext, NATIVE_BUFFER_ANDROID);
|
||||||
|
if (anb_info) {
|
||||||
|
result = vn_image_from_anb(dev, pCreateInfo, anb_info, alloc, &img);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
result = vn_image_create(dev, pCreateInfo, alloc, &img);
|
result = vn_image_create(dev, pCreateInfo, alloc, &img);
|
||||||
|
|
||||||
out:
|
out:
|
||||||
@@ -176,6 +186,9 @@ vn_DestroyImage(VkDevice device,
|
|||||||
if (!img)
|
if (!img)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (img->private_memory != VK_NULL_HANDLE)
|
||||||
|
vn_FreeMemory(device, img->private_memory, pAllocator);
|
||||||
|
|
||||||
vn_async_vkDestroyImage(dev->instance, device, image, NULL);
|
vn_async_vkDestroyImage(dev->instance, device, image, NULL);
|
||||||
|
|
||||||
vn_object_base_fini(&img->base);
|
vn_object_base_fini(&img->base);
|
||||||
|
@@ -18,6 +18,8 @@ struct vn_image {
|
|||||||
|
|
||||||
VkMemoryRequirements2 memory_requirements[4];
|
VkMemoryRequirements2 memory_requirements[4];
|
||||||
VkMemoryDedicatedRequirements dedicated_requirements[4];
|
VkMemoryDedicatedRequirements dedicated_requirements[4];
|
||||||
|
/* For VK_ANDROID_native_buffer, the WSI image owns the memory, */
|
||||||
|
VkDeviceMemory private_memory;
|
||||||
};
|
};
|
||||||
VK_DEFINE_NONDISP_HANDLE_CASTS(vn_image,
|
VK_DEFINE_NONDISP_HANDLE_CASTS(vn_image,
|
||||||
base.base,
|
base.base,
|
||||||
|
Reference in New Issue
Block a user