diff options
-rw-r--r-- | vulkan/include/vulkan/vk_android_native_buffer.h | 15 | ||||
-rw-r--r-- | vulkan/libvulkan/driver.cpp | 1 | ||||
-rw-r--r-- | vulkan/libvulkan/driver.h | 1 | ||||
-rw-r--r-- | vulkan/libvulkan/swapchain.cpp | 324 |
4 files changed, 232 insertions, 109 deletions
diff --git a/vulkan/include/vulkan/vk_android_native_buffer.h b/vulkan/include/vulkan/vk_android_native_buffer.h index e78f47003b..7c8e695d67 100644 --- a/vulkan/include/vulkan/vk_android_native_buffer.h +++ b/vulkan/include/vulkan/vk_android_native_buffer.h @@ -60,7 +60,12 @@ extern "C" { * * This version of the extension cleans up a bug introduced in version 9 */ -#define VK_ANDROID_NATIVE_BUFFER_SPEC_VERSION 10 +/* + * NOTE ON VK_ANDROID_NATIVE_BUFFER_SPEC_VERSION 11 + * + * This version of the extension deprecates the last of grallocusage + */ +#define VK_ANDROID_NATIVE_BUFFER_SPEC_VERSION 11 #define VK_ANDROID_NATIVE_BUFFER_EXTENSION_NAME "VK_ANDROID_native_buffer" #define VK_ANDROID_NATIVE_BUFFER_ENUM(type, id) \ @@ -151,6 +156,8 @@ typedef struct { * pNext: NULL or a pointer to a structure extending this structure * format: value specifying the format the image will be created with * imageUsage: bitmask of VkImageUsageFlagBits describing intended usage + * + * DEPRECATED in SPEC_VERSION 10 */ typedef struct { VkStructureType sType; @@ -167,6 +174,8 @@ typedef struct { * format: value specifying the format the image will be created with * imageUsage: bitmask of VkImageUsageFlagBits describing intended usage * swapchainImageUsage: is a bitmask of VkSwapchainImageUsageFlagsANDROID + * + * DEPRECATED in SPEC_VERSION 11 */ typedef struct { VkStructureType sType; @@ -198,7 +207,7 @@ typedef VkResult (VKAPI_PTR *PFN_vkGetSwapchainGrallocUsage3ANDROID)( const VkGrallocUsageInfoANDROID* grallocUsageInfo, uint64_t* grallocUsage); -/* ADDED in SPEC_VERSION 10 */ +/* DEPRECATED in SPEC_VERSION 11 */ typedef VkResult (VKAPI_PTR *PFN_vkGetSwapchainGrallocUsage4ANDROID)( VkDevice device, const VkGrallocUsageInfo2ANDROID* grallocUsageInfo, @@ -245,7 +254,7 @@ VKAPI_ATTR VkResult VKAPI_CALL vkGetSwapchainGrallocUsage3ANDROID( uint64_t* grallocUsage ); -/* ADDED in SPEC_VERSION 10 */ +/* DEPRECATED in SPEC_VERSION 11 */ VKAPI_ATTR VkResult VKAPI_CALL vkGetSwapchainGrallocUsage4ANDROID( VkDevice device, const VkGrallocUsageInfo2ANDROID* grallocUsageInfo, diff --git a/vulkan/libvulkan/driver.cpp b/vulkan/libvulkan/driver.cpp index bdba27e6a1..5d7a4aa170 100644 --- a/vulkan/libvulkan/driver.cpp +++ b/vulkan/libvulkan/driver.cpp @@ -1456,6 +1456,7 @@ VkResult CreateDevice(VkPhysicalDevice physicalDevice, } data->driver_device = dev; + data->driver_physical_device = physicalDevice; *pDevice = dev; diff --git a/vulkan/libvulkan/driver.h b/vulkan/libvulkan/driver.h index 4d2bbd69e3..4b855e5999 100644 --- a/vulkan/libvulkan/driver.h +++ b/vulkan/libvulkan/driver.h @@ -98,6 +98,7 @@ struct DeviceData { VkDevice driver_device; DeviceDriverTable driver; + VkPhysicalDevice driver_physical_device; }; bool OpenHAL(); diff --git a/vulkan/libvulkan/swapchain.cpp b/vulkan/libvulkan/swapchain.cpp index dcef54dc38..9b69438276 100644 --- a/vulkan/libvulkan/swapchain.cpp +++ b/vulkan/libvulkan/swapchain.cpp @@ -18,6 +18,7 @@ #include <aidl/android/hardware/graphics/common/PixelFormat.h> #include <android/hardware/graphics/common/1.0/types.h> +#include <android/hardware_buffer.h> #include <grallocusage/GrallocUsageConversion.h> #include <graphicsenv/GraphicsEnv.h> #include <hardware/gralloc.h> @@ -1367,6 +1368,187 @@ static void DestroySwapchainInternal(VkDevice device, allocator->pfnFree(allocator->pUserData, swapchain); } +static VkResult getProducerUsage(const VkDevice& device, + const VkSwapchainCreateInfoKHR* create_info, + const VkSwapchainImageUsageFlagsANDROID swapchain_image_usage, + bool create_protected_swapchain, + uint64_t* producer_usage) { + // Get the physical device to query the appropriate producer usage + const VkPhysicalDevice& pdev = GetData(device).driver_physical_device; + const InstanceData& instance_data = GetData(pdev); + const InstanceDriverTable& instance_dispatch = instance_data.driver; + if (!instance_dispatch.GetPhysicalDeviceImageFormatProperties2 && + !instance_dispatch.GetPhysicalDeviceImageFormatProperties2KHR) { + uint64_t native_usage = 0; + void* usage_info_pNext = nullptr; + VkResult result; + VkImageCompressionControlEXT image_compression = {}; + const auto& dispatch = GetData(device).driver; + if (dispatch.GetSwapchainGrallocUsage4ANDROID) { + ATRACE_BEGIN("GetSwapchainGrallocUsage4ANDROID"); + VkGrallocUsageInfo2ANDROID gralloc_usage_info = {}; + gralloc_usage_info.sType = + VK_STRUCTURE_TYPE_GRALLOC_USAGE_INFO_2_ANDROID; + gralloc_usage_info.format = create_info->imageFormat; + gralloc_usage_info.imageUsage = create_info->imageUsage; + gralloc_usage_info.swapchainImageUsage = swapchain_image_usage; + + // Look through the pNext chain for an image compression control struct + // if one is found AND the appropriate extensions are enabled, + // append it to be the gralloc usage pNext chain + const VkSwapchainCreateInfoKHR* create_infos = create_info; + while (create_infos->pNext) { + create_infos = reinterpret_cast<const VkSwapchainCreateInfoKHR*>( + create_infos->pNext); + switch (create_infos->sType) { + case VK_STRUCTURE_TYPE_IMAGE_COMPRESSION_CONTROL_EXT: { + const VkImageCompressionControlEXT* compression_infos = + reinterpret_cast<const VkImageCompressionControlEXT*>( + create_infos); + image_compression = *compression_infos; + image_compression.pNext = nullptr; + usage_info_pNext = &image_compression; + } break; + + default: + // Ignore all other info structs + break; + } + } + gralloc_usage_info.pNext = usage_info_pNext; + + result = dispatch.GetSwapchainGrallocUsage4ANDROID( + device, &gralloc_usage_info, &native_usage); + ATRACE_END(); + if (result != VK_SUCCESS) { + ALOGE("vkGetSwapchainGrallocUsage4ANDROID failed: %d", result); + return VK_ERROR_SURFACE_LOST_KHR; + } + } else if (dispatch.GetSwapchainGrallocUsage3ANDROID) { + ATRACE_BEGIN("GetSwapchainGrallocUsage3ANDROID"); + VkGrallocUsageInfoANDROID gralloc_usage_info = {}; + gralloc_usage_info.sType = VK_STRUCTURE_TYPE_GRALLOC_USAGE_INFO_ANDROID; + gralloc_usage_info.format = create_info->imageFormat; + gralloc_usage_info.imageUsage = create_info->imageUsage; + + // Look through the pNext chain for an image compression control struct + // if one is found AND the appropriate extensions are enabled, + // append it to be the gralloc usage pNext chain + const VkSwapchainCreateInfoKHR* create_infos = create_info; + while (create_infos->pNext) { + create_infos = reinterpret_cast<const VkSwapchainCreateInfoKHR*>( + create_infos->pNext); + switch (create_infos->sType) { + case VK_STRUCTURE_TYPE_IMAGE_COMPRESSION_CONTROL_EXT: { + const VkImageCompressionControlEXT* compression_infos = + reinterpret_cast<const VkImageCompressionControlEXT*>( + create_infos); + image_compression = *compression_infos; + image_compression.pNext = nullptr; + usage_info_pNext = &image_compression; + } break; + + default: + // Ignore all other info structs + break; + } + } + gralloc_usage_info.pNext = usage_info_pNext; + + result = dispatch.GetSwapchainGrallocUsage3ANDROID( + device, &gralloc_usage_info, &native_usage); + ATRACE_END(); + if (result != VK_SUCCESS) { + ALOGE("vkGetSwapchainGrallocUsage3ANDROID failed: %d", result); + return VK_ERROR_SURFACE_LOST_KHR; + } + } else if (dispatch.GetSwapchainGrallocUsage2ANDROID) { + uint64_t consumer_usage, producer_usage; + ATRACE_BEGIN("GetSwapchainGrallocUsage2ANDROID"); + result = dispatch.GetSwapchainGrallocUsage2ANDROID( + device, create_info->imageFormat, create_info->imageUsage, + swapchain_image_usage, &consumer_usage, &producer_usage); + ATRACE_END(); + if (result != VK_SUCCESS) { + ALOGE("vkGetSwapchainGrallocUsage2ANDROID failed: %d", result); + return VK_ERROR_SURFACE_LOST_KHR; + } + native_usage = + convertGralloc1ToBufferUsage(producer_usage, consumer_usage); + } else if (dispatch.GetSwapchainGrallocUsageANDROID) { + ATRACE_BEGIN("GetSwapchainGrallocUsageANDROID"); + int32_t legacy_usage = 0; + result = dispatch.GetSwapchainGrallocUsageANDROID( + device, create_info->imageFormat, create_info->imageUsage, + &legacy_usage); + ATRACE_END(); + if (result != VK_SUCCESS) { + ALOGE("vkGetSwapchainGrallocUsageANDROID failed: %d", result); + return VK_ERROR_SURFACE_LOST_KHR; + } + native_usage = static_cast<uint64_t>(legacy_usage); + } + *producer_usage = native_usage; + + return VK_SUCCESS; + } + + // call GetPhysicalDeviceImageFormatProperties2KHR + VkPhysicalDeviceExternalImageFormatInfo external_image_format_info = { + .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO, + .pNext = nullptr, + .handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID, + }; + + // AHB does not have an sRGB format so we can't pass it to GPDIFP + // We need to convert the format to unorm if it is srgb + VkFormat format = create_info->imageFormat; + if (format == VK_FORMAT_R8G8B8A8_SRGB) { + format = VK_FORMAT_R8G8B8A8_UNORM; + } + + VkPhysicalDeviceImageFormatInfo2 image_format_info = { + .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2, + .pNext = &external_image_format_info, + .format = format, + .type = VK_IMAGE_TYPE_2D, + .tiling = VK_IMAGE_TILING_OPTIMAL, + .usage = create_info->imageUsage, + .flags = create_protected_swapchain ? VK_IMAGE_CREATE_PROTECTED_BIT : 0u, + }; + + VkAndroidHardwareBufferUsageANDROID ahb_usage; + ahb_usage.sType = VK_STRUCTURE_TYPE_ANDROID_HARDWARE_BUFFER_USAGE_ANDROID; + ahb_usage.pNext = nullptr; + + VkImageFormatProperties2 image_format_properties; + image_format_properties.sType = VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2; + image_format_properties.pNext = &ahb_usage; + + if (instance_dispatch.GetPhysicalDeviceImageFormatProperties2) { + VkResult result = instance_dispatch.GetPhysicalDeviceImageFormatProperties2( + pdev, &image_format_info, &image_format_properties); + if (result != VK_SUCCESS) { + ALOGE("VkGetPhysicalDeviceImageFormatProperties2 for AHB usage failed: %d", result); + return VK_ERROR_SURFACE_LOST_KHR; + } + } + else { + VkResult result = instance_dispatch.GetPhysicalDeviceImageFormatProperties2KHR( + pdev, &image_format_info, + &image_format_properties); + if (result != VK_SUCCESS) { + ALOGE("VkGetPhysicalDeviceImageFormatProperties2KHR for AHB usage failed: %d", + result); + return VK_ERROR_SURFACE_LOST_KHR; + } + } + + *producer_usage = ahb_usage.androidHardwareBufferUsage; + + return VK_SUCCESS; +} + VKAPI_ATTR VkResult CreateSwapchainKHR(VkDevice device, const VkSwapchainCreateInfoKHR* create_info, @@ -1601,120 +1783,48 @@ VkResult CreateSwapchainKHR(VkDevice device, num_images = 1; } + // Look through the create_info pNext chain passed to createSwapchainKHR + // for an image compression control struct. + // if one is found AND the appropriate extensions are enabled, create a + // VkImageCompressionControlEXT structure to pass on to VkImageCreateInfo + // TODO check for imageCompressionControlSwapchain feature is enabled void* usage_info_pNext = nullptr; VkImageCompressionControlEXT image_compression = {}; - uint64_t native_usage = 0; - if (dispatch.GetSwapchainGrallocUsage4ANDROID) { - ATRACE_BEGIN("GetSwapchainGrallocUsage4ANDROID"); - VkGrallocUsageInfo2ANDROID gralloc_usage_info = {}; - gralloc_usage_info.sType = - VK_STRUCTURE_TYPE_GRALLOC_USAGE_INFO_2_ANDROID; - gralloc_usage_info.format = create_info->imageFormat; - gralloc_usage_info.imageUsage = create_info->imageUsage; - gralloc_usage_info.swapchainImageUsage = swapchain_image_usage; - - // Look through the pNext chain for an image compression control struct - // if one is found AND the appropriate extensions are enabled, - // append it to be the gralloc usage pNext chain - const VkSwapchainCreateInfoKHR* create_infos = create_info; - while (create_infos->pNext) { - create_infos = reinterpret_cast<const VkSwapchainCreateInfoKHR*>( - create_infos->pNext); - switch (create_infos->sType) { - case VK_STRUCTURE_TYPE_IMAGE_COMPRESSION_CONTROL_EXT: { - const VkImageCompressionControlEXT* compression_infos = - reinterpret_cast<const VkImageCompressionControlEXT*>( - create_infos); - image_compression = *compression_infos; - image_compression.pNext = nullptr; - usage_info_pNext = &image_compression; - } break; - - default: - // Ignore all other info structs - break; - } - } - gralloc_usage_info.pNext = usage_info_pNext; - - result = dispatch.GetSwapchainGrallocUsage4ANDROID( - device, &gralloc_usage_info, &native_usage); - ATRACE_END(); - if (result != VK_SUCCESS) { - ALOGE("vkGetSwapchainGrallocUsage4ANDROID failed: %d", result); - return VK_ERROR_SURFACE_LOST_KHR; - } - } else if (dispatch.GetSwapchainGrallocUsage3ANDROID) { - ATRACE_BEGIN("GetSwapchainGrallocUsage3ANDROID"); - VkGrallocUsageInfoANDROID gralloc_usage_info = {}; - gralloc_usage_info.sType = VK_STRUCTURE_TYPE_GRALLOC_USAGE_INFO_ANDROID; - gralloc_usage_info.format = create_info->imageFormat; - gralloc_usage_info.imageUsage = create_info->imageUsage; - - // Look through the pNext chain for an image compression control struct - // if one is found AND the appropriate extensions are enabled, - // append it to be the gralloc usage pNext chain - const VkSwapchainCreateInfoKHR* create_infos = create_info; - while (create_infos->pNext) { - create_infos = reinterpret_cast<const VkSwapchainCreateInfoKHR*>( - create_infos->pNext); - switch (create_infos->sType) { - case VK_STRUCTURE_TYPE_IMAGE_COMPRESSION_CONTROL_EXT: { - const VkImageCompressionControlEXT* compression_infos = - reinterpret_cast<const VkImageCompressionControlEXT*>( - create_infos); - image_compression = *compression_infos; - image_compression.pNext = nullptr; - usage_info_pNext = &image_compression; - } break; - - default: - // Ignore all other info structs - break; - } - } - gralloc_usage_info.pNext = usage_info_pNext; + const VkSwapchainCreateInfoKHR* create_infos = create_info; + while (create_infos->pNext) { + create_infos = reinterpret_cast<const VkSwapchainCreateInfoKHR*>(create_infos->pNext); + switch (create_infos->sType) { + case VK_STRUCTURE_TYPE_IMAGE_COMPRESSION_CONTROL_EXT: { + const VkImageCompressionControlEXT* compression_infos = + reinterpret_cast<const VkImageCompressionControlEXT*>(create_infos); + image_compression = *compression_infos; + image_compression.pNext = nullptr; + usage_info_pNext = &image_compression; + } break; - result = dispatch.GetSwapchainGrallocUsage3ANDROID( - device, &gralloc_usage_info, &native_usage); - ATRACE_END(); - if (result != VK_SUCCESS) { - ALOGE("vkGetSwapchainGrallocUsage3ANDROID failed: %d", result); - return VK_ERROR_SURFACE_LOST_KHR; - } - } else if (dispatch.GetSwapchainGrallocUsage2ANDROID) { - uint64_t consumer_usage, producer_usage; - ATRACE_BEGIN("GetSwapchainGrallocUsage2ANDROID"); - result = dispatch.GetSwapchainGrallocUsage2ANDROID( - device, create_info->imageFormat, create_info->imageUsage, - swapchain_image_usage, &consumer_usage, &producer_usage); - ATRACE_END(); - if (result != VK_SUCCESS) { - ALOGE("vkGetSwapchainGrallocUsage2ANDROID failed: %d", result); - return VK_ERROR_SURFACE_LOST_KHR; - } - native_usage = - convertGralloc1ToBufferUsage(producer_usage, consumer_usage); - } else if (dispatch.GetSwapchainGrallocUsageANDROID) { - ATRACE_BEGIN("GetSwapchainGrallocUsageANDROID"); - int32_t legacy_usage = 0; - result = dispatch.GetSwapchainGrallocUsageANDROID( - device, create_info->imageFormat, create_info->imageUsage, - &legacy_usage); - ATRACE_END(); - if (result != VK_SUCCESS) { - ALOGE("vkGetSwapchainGrallocUsageANDROID failed: %d", result); - return VK_ERROR_SURFACE_LOST_KHR; + default: + // Ignore all other info structs + break; } - native_usage = static_cast<uint64_t>(legacy_usage); } - native_usage |= surface.consumer_usage; - bool createProtectedSwapchain = false; + // Get the appropriate native_usage for the images + // Get the consumer usage + uint64_t native_usage = surface.consumer_usage; + // Determine if the swapchain is protected + bool create_protected_swapchain = false; if (create_info->flags & VK_SWAPCHAIN_CREATE_PROTECTED_BIT_KHR) { - createProtectedSwapchain = true; + create_protected_swapchain = true; native_usage |= BufferUsage::PROTECTED; } + // Get the producer usage + uint64_t producer_usage; + result = getProducerUsage(device, create_info, swapchain_image_usage, create_protected_swapchain, &producer_usage); + if (result != VK_SUCCESS) { + return result; + } + native_usage |= producer_usage; + err = native_window_set_usage(window, native_usage); if (err != android::OK) { ALOGE("native_window_set_usage failed: %s (%d)", strerror(-err), err); @@ -1742,8 +1852,10 @@ VkResult CreateSwapchainKHR(VkDevice device, void* mem = allocator->pfnAllocation(allocator->pUserData, sizeof(Swapchain), alignof(Swapchain), VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); + if (!mem) return VK_ERROR_OUT_OF_HOST_MEMORY; + Swapchain* swapchain = new (mem) Swapchain(surface, num_images, create_info->presentMode, TranslateVulkanToNativeTransform(create_info->preTransform), @@ -1767,7 +1879,7 @@ VkResult CreateSwapchainKHR(VkDevice device, VkImageCreateInfo image_create = { .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, .pNext = nullptr, - .flags = createProtectedSwapchain ? VK_IMAGE_CREATE_PROTECTED_BIT : 0u, + .flags = create_protected_swapchain ? VK_IMAGE_CREATE_PROTECTED_BIT : 0u, .imageType = VK_IMAGE_TYPE_2D, .format = create_info->imageFormat, .extent = { |