From 0f475223dd715a0b51be27899d3c160a1392b338 Mon Sep 17 00:00:00 2001 From: Yiwei Zhang Date: Thu, 11 Apr 2019 19:38:00 -0700 Subject: libvulkan: correctly handle VkBindImageMemorySwapchainInfoKHR This change checks if VkBindImageMemorySwapchainInfoKHR is chained in any VkBindImageMemoryInfo struct. If existed, a VkNativeBufferANDROID struct is properly constructed and additionally chained to the original VkBindImageMemoryInfo struct. Bug: 130182551 Test: CtsDeqpTestCases Change-Id: I1a9e35dbd228060fcfade11be6e7d1b47dad474f --- vulkan/libvulkan/swapchain.cpp | 101 +++++++++++++++++++++++++++++++++++++---- 1 file changed, 92 insertions(+), 9 deletions(-) (limited to 'vulkan/libvulkan/swapchain.cpp') diff --git a/vulkan/libvulkan/swapchain.cpp b/vulkan/libvulkan/swapchain.cpp index 611bb002cb..bc00190779 100644 --- a/vulkan/libvulkan/swapchain.cpp +++ b/vulkan/libvulkan/swapchain.cpp @@ -16,17 +16,19 @@ #define ATRACE_TAG ATRACE_TAG_GRAPHICS -#include - +#include #include #include -#include #include +#include +#include #include #include #include -#include -#include + +#include +#include +#include #include "driver.h" @@ -1818,14 +1820,90 @@ VKAPI_ATTR void SetHdrMetadataEXT( return; } +static void InterceptBindImageMemory2( + uint32_t bind_info_count, + const VkBindImageMemoryInfo* bind_infos, + std::vector* out_native_buffers, + std::vector* out_bind_infos) { + out_native_buffers->clear(); + out_bind_infos->clear(); + + if (!bind_info_count) + return; + + std::unordered_set intercepted_indexes; + + for (uint32_t idx = 0; idx < bind_info_count; idx++) { + auto info = reinterpret_cast( + bind_infos[idx].pNext); + while (info && + info->sType != + VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_SWAPCHAIN_INFO_KHR) { + info = reinterpret_cast( + info->pNext); + } + + if (!info) + continue; + + ALOG_ASSERT(info->swapchain != VK_NULL_HANDLE, + "swapchain handle must not be NULL"); + const Swapchain* swapchain = SwapchainFromHandle(info->swapchain); + ALOG_ASSERT( + info->imageIndex < swapchain->num_images, + "imageIndex must be less than the number of images in swapchain"); + + ANativeWindowBuffer* buffer = + swapchain->images[info->imageIndex].buffer.get(); + VkNativeBufferANDROID native_buffer = { +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wold-style-cast" + .sType = VK_STRUCTURE_TYPE_NATIVE_BUFFER_ANDROID, +#pragma clang diagnostic pop + .pNext = bind_infos[idx].pNext, + .handle = buffer->handle, + .stride = buffer->stride, + .format = buffer->format, + .usage = int(buffer->usage), + }; + // Reserve enough space to avoid letting re-allocation invalidate the + // addresses of the elements inside. + out_native_buffers->reserve(bind_info_count); + out_native_buffers->emplace_back(native_buffer); + + // Reserve the space now since we know how much is needed now. + out_bind_infos->reserve(bind_info_count); + out_bind_infos->emplace_back(bind_infos[idx]); + out_bind_infos->back().pNext = &out_native_buffers->back(); + + intercepted_indexes.insert(idx); + } + + if (intercepted_indexes.empty()) + return; + + for (uint32_t idx = 0; idx < bind_info_count; idx++) { + if (intercepted_indexes.count(idx)) + continue; + out_bind_infos->emplace_back(bind_infos[idx]); + } +} + VKAPI_ATTR VkResult BindImageMemory2(VkDevice device, uint32_t bindInfoCount, const VkBindImageMemoryInfo* pBindInfos) { ATRACE_CALL(); - return GetData(device).driver.BindImageMemory2(device, bindInfoCount, - pBindInfos); + // out_native_buffers is for maintaining the lifecycle of the constructed + // VkNativeBufferANDROID objects inside InterceptBindImageMemory2. + std::vector out_native_buffers; + std::vector out_bind_infos; + InterceptBindImageMemory2(bindInfoCount, pBindInfos, &out_native_buffers, + &out_bind_infos); + return GetData(device).driver.BindImageMemory2( + device, bindInfoCount, + out_bind_infos.empty() ? pBindInfos : out_bind_infos.data()); } VKAPI_ATTR @@ -1834,8 +1912,13 @@ VkResult BindImageMemory2KHR(VkDevice device, const VkBindImageMemoryInfo* pBindInfos) { ATRACE_CALL(); - return GetData(device).driver.BindImageMemory2KHR(device, bindInfoCount, - pBindInfos); + std::vector out_native_buffers; + std::vector out_bind_infos; + InterceptBindImageMemory2(bindInfoCount, pBindInfos, &out_native_buffers, + &out_bind_infos); + return GetData(device).driver.BindImageMemory2KHR( + device, bindInfoCount, + out_bind_infos.empty() ? pBindInfos : out_bind_infos.data()); } } // namespace driver -- cgit v1.2.3-59-g8ed1b