From: Tianhao Ni Date: Wed, 8 Sep 2021 02:21:44 +0000 (+0800) Subject: Fix CTS Coredump issue of "image_swapchain_create_info" cases on NikeM: X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=refs%2Fheads%2Fnew_wsi_layer;p=platform%2Fcore%2Fuifw%2Fvulkan-wsi-tizen.git Fix CTS Coredump issue of "image_swapchain_create_info" cases on NikeM: Wsi layer and Mali has different swapchain defination, if we pass VkImageSwapchainCreateInfoKHR to Mali, Mali will handle swapchain object of wsi layer, which will cause SegmentFault issue. - Handle VkImageSwapchainCreateInfoKHR of vkCreateImage in wsi layer instead of Mali - Handle VkBindImageMemorySwapchainInfoKHR of vkBindImageMemory2 in wsi layer instead of Mali Change-Id: I85459c0d99409e34657673a64ae29985090bd20c Signed-off-by: Tianhao Ni --- diff --git a/CMakeLists.txt b/CMakeLists.txt index 0f022de..1642878 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -140,6 +140,9 @@ if(BUILD_WSI_WAYLAND) list(APPEND LINK_WSI_LIBS wayland_wsi) elseif(BUILD_WSI_TIZEN) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DVK_USE_PLATFORM_WAYLAND_KHR") + if(USE_ICD_MALI_NIKEM) + add_definitions(-DUSE_ICD_MALI_NIKEM) + endif() add_library(tizen_wsi STATIC wsi/tizen/surface_properties.cpp wsi/tizen/swapchain.cpp) diff --git a/layer/layer.cpp b/layer/layer.cpp index 82a1cde..71c9f2d 100644 --- a/layer/layer.cpp +++ b/layer/layer.cpp @@ -411,6 +411,10 @@ VK_LAYER_EXPORT PFN_vkVoidFunction VKAPI_CALL wsi_layer_vkGetDeviceProcAddr(VkDe GET_PROC_ADDR(vkAcquireNextImageKHR); GET_PROC_ADDR(vkQueuePresentKHR); GET_PROC_ADDR(vkAcquireNextImage2KHR); +#ifdef USE_ICD_MALI_NIKEM + GET_PROC_ADDR(vkCreateImage); + GET_PROC_ADDR(vkBindImageMemory2); +#endif return layer::device_private_data::get(device).disp.GetDeviceProcAddr(device, funcName); } diff --git a/layer/swapchain_api.cpp b/layer/swapchain_api.cpp index dd0e3e6..3c7dc4e 100644 --- a/layer/swapchain_api.cpp +++ b/layer/swapchain_api.cpp @@ -207,4 +207,69 @@ VKAPI_ATTR VkResult wsi_layer_vkAcquireNextImage2KHR(VkDevice device, return sc->acquire_next_image(pAcquireInfo->timeout, pAcquireInfo->semaphore, pAcquireInfo->fence, pImageIndex); } +#ifdef USE_ICD_MALI_NIKEM +VKAPI_ATTR VkResult wsi_layer_vkCreateImage(VkDevice device, const VkImageCreateInfo* pCreateInfo, + const VkAllocationCallbacks* pAllocator, VkImage* pImage) +{ + layer::device_private_data &device_data = layer::device_private_data::get(device); + bool is_swapchain_image = false; + wsi::swapchain_base *sc = nullptr; + VkImageCreateInfo create_info = *pCreateInfo; + + for (VkBaseOutStructure *s = (VkBaseOutStructure *)(create_info.pNext); s != nullptr; s = s->pNext) { + if (s->sType == VK_STRUCTURE_TYPE_IMAGE_SWAPCHAIN_CREATE_INFO_KHR) { + VkImageSwapchainCreateInfoKHR *pImageSwapchainCreateInfo = (VkImageSwapchainCreateInfoKHR *)(s); + if (!device_data.layer_owns_swapchain(pImageSwapchainCreateInfo->swapchain)) + wsi_error("Swapchain not created by layer"); + else { + is_swapchain_image = true; + sc = reinterpret_cast(pImageSwapchainCreateInfo->swapchain); + } + break; + } + } + + if (is_swapchain_image) { + wsi_info("Create image for swapchain[%p]", sc); + return sc->create_swapchain_images(&create_info, pAllocator, pImage); + } + + return device_data.disp.CreateImage(device, pCreateInfo, pAllocator, pImage); +} + +VKAPI_ATTR VkResult wsi_layer_vkBindImageMemory2(VkDevice device, uint32_t bindInfoCount, + const VkBindImageMemoryInfo *pBindInfos) +{ + VkResult result = VK_SUCCESS; + layer::device_private_data &device_data = layer::device_private_data::get(device); + wsi::swapchain_base *sc = nullptr; + + for (uint32_t i = 0; i < bindInfoCount; i++) { + VkBaseOutStructure *s = (VkBaseOutStructure *)(&pBindInfos[i]); + bool is_swapchain_image = false; + + for (s = s->pNext; s != nullptr; s = s->pNext) { + if (s->sType == VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_SWAPCHAIN_INFO_KHR) { + is_swapchain_image = true; + VkBindImageMemorySwapchainInfoKHR *pBindImageMemorySwapchainInfo = (VkBindImageMemorySwapchainInfoKHR *)(s); + uint32_t image_index = pBindImageMemorySwapchainInfo->imageIndex; + sc = (wsi::swapchain_base *)(pBindImageMemorySwapchainInfo->swapchain); + if (sc) { + result = sc->bind_swapchain_images(image_index, pBindInfos[i].image); + if (result != VK_SUCCESS) + return result; + } + break; + } + } + if (!is_swapchain_image) { + result = device_data.disp.BindImageMemory(device, pBindInfos[i].image, pBindInfos[i].memory, pBindInfos[i].memoryOffset); + if (result != VK_SUCCESS) + return result; + } + } + + return VK_SUCCESS; +} +#endif } /* extern "C" */ diff --git a/layer/swapchain_api.hpp b/layer/swapchain_api.hpp index d1476f9..3a1fac9 100644 --- a/layer/swapchain_api.hpp +++ b/layer/swapchain_api.hpp @@ -50,5 +50,10 @@ extern "C" VKAPI_ATTR VkResult wsi_layer_vkQueuePresentKHR(VkQueue queue, const VkPresentInfoKHR *pPresentInfo); VKAPI_ATTR VkResult wsi_layer_vkAcquireNextImage2KHR(VkDevice device, const VkAcquireNextImageInfoKHR *pAcquireInfo, uint32_t *pImageIndex); - +#ifdef USE_ICD_MALI_NIKEM + VKAPI_ATTR VkResult wsi_layer_vkCreateImage(VkDevice device, const VkImageCreateInfo* pCreateInfo, + const VkAllocationCallbacks* pAllocator, VkImage* pImage); + VKAPI_ATTR VkResult wsi_layer_vkBindImageMemory2(VkDevice device, uint32_t bindInfoCount, + const VkBindImageMemoryInfo *pBindInfos); +#endif } diff --git a/packaging/vulkan-wsi-layer.spec b/packaging/vulkan-wsi-layer.spec index b525253..5c82e4b 100644 --- a/packaging/vulkan-wsi-layer.spec +++ b/packaging/vulkan-wsi-layer.spec @@ -24,6 +24,8 @@ BuildRequires: pkgconfig(libdrm) BuildRequires: pkgconfig(dlog) BuildRequires: vulkan-headers +#%define VULKAN_ICD mali_nikem + #%define _unpackaged_files_terminate_build 0 %global TZ_SYS_RO_SHARE %{?TZ_SYS_RO_SHARE:%TZ_SYS_RO_SHARE}%{!?TZ_SYS_RO_SHARE:/usr/share} @@ -35,7 +37,12 @@ Vulkan WSI (Window System Integration) Layer for Tizen %setup -q %build -cmake . -Bbuild -DCMAKE_INSTALL_PREFIX=/usr -DBUILD_WSI_TIZEN=ON +cmake . -Bbuild \ + -DCMAKE_INSTALL_PREFIX=/usr \ + -DBUILD_WSI_TIZEN=ON \ +%if "%{VULKAN_ICD}" == "mali_nikem" + -DUSE_ICD_MALI_NIKEM=ON +%endif make -C build %install diff --git a/wsi/swapchain_base_tizen.cpp b/wsi/swapchain_base_tizen.cpp index 1f81fa0..c488a0a 100644 --- a/wsi/swapchain_base_tizen.cpp +++ b/wsi/swapchain_base_tizen.cpp @@ -203,6 +203,20 @@ VkResult swapchain_base::queue_present(VkQueue queue, const VkPresentInfoKHR *pr return VK_SUCCESS; } +#ifdef USE_ICD_MALI_NIKEM +VkResult swapchain_base::create_swapchain_images(VkImageCreateInfo* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkImage* pImage) +{ + return create_external_image(pCreateInfo, pAllocator, pImage); +} + +VkResult swapchain_base::bind_swapchain_images(const uint32_t image_index, VkImage image) +{ + return bind_external_image(image_index, image); +} +#endif + void swapchain_base::deprecate(VkSwapchainKHR descendant) { // TO BE DONE - release old swapchain resources diff --git a/wsi/swapchain_base_tizen.hpp b/wsi/swapchain_base_tizen.hpp index b020c80..63e97dd 100644 --- a/wsi/swapchain_base_tizen.hpp +++ b/wsi/swapchain_base_tizen.hpp @@ -16,6 +16,10 @@ struct swapchain_image VkImage image{VK_NULL_HANDLE}; VkFence present_fence{VK_NULL_HANDLE}; + +#ifdef USE_ICD_MALI_NIKEM + bool is_external{false}; +#endif }; /** @@ -89,7 +93,13 @@ public: * otherwise returns VK_SUCCESS. */ VkResult queue_present(VkQueue queue, const VkPresentInfoKHR *present_info, const uint32_t image_index, const VkPresentRegionKHR *region); +#ifdef USE_ICD_MALI_NIKEM + VkResult create_swapchain_images(VkImageCreateInfo* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkImage* pImage); + VkResult bind_swapchain_images(const uint32_t image_index, VkImage image); +#endif protected: layer::device_private_data &m_device_data; @@ -230,6 +240,11 @@ protected: * @param image Handle to the image about to be released. */ virtual void destroy_image(void){}; +#ifdef USE_ICD_MALI_NIKEM + virtual VkResult create_external_image(VkImageCreateInfo* pCreateInfo, + const VkAllocationCallbacks* pAllocator, VkImage* pImage) = 0; + virtual VkResult bind_external_image(const uint32_t image_index, VkImage image) = 0; +#endif }; } /* namespace wsi */ diff --git a/wsi/tizen/swapchain.cpp b/wsi/tizen/swapchain.cpp index a6f28a5..6da4185 100644 --- a/wsi/tizen/swapchain.cpp +++ b/wsi/tizen/swapchain.cpp @@ -41,10 +41,10 @@ struct swapchain::tizen_image_data { int buffer_fd; tbm_surface_h tbm_buffer; - - int stride; - uint32_t offset; - +#ifndef USE_ICD_MALI_NIKEM + VkDeviceSize stride; // rowPitch + VkDeviceSize offset; +#endif VkDeviceMemory memory; }; @@ -193,19 +193,26 @@ VkResult swapchain::allocate_image(const VkImageCreateInfo &image_create_info, t { VkResult result = VK_SUCCESS; +#ifndef USE_ICD_MALI_NIKEM assert(image_data->stride >= 0); VkSubresourceLayout image_layout = {}; image_layout.offset = image_data->offset; - image_layout.rowPitch = static_cast(image_data->stride); + image_layout.rowPitch = image_data->stride; VkImageDrmFormatModifierExplicitCreateInfoEXT drm_mod_info = {}; drm_mod_info.sType = VK_STRUCTURE_TYPE_IMAGE_DRM_FORMAT_MODIFIER_EXPLICIT_CREATE_INFO_EXT; drm_mod_info.pNext = image_create_info.pNext; drm_mod_info.drmFormatModifier = DRM_FORMAT_MOD_LINEAR; drm_mod_info.drmFormatModifierPlaneCount = 1; drm_mod_info.pPlaneLayouts = &image_layout; +#endif + VkExternalMemoryImageCreateInfoKHR external_info = {}; external_info.sType = VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO_KHR; +#ifndef USE_ICD_MALI_NIKEM external_info.pNext = &drm_mod_info; +#else + external_info.pNext = image_create_info.pNext; +#endif external_info.handleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT; VkImageCreateInfo image_info = image_create_info; @@ -317,20 +324,25 @@ VkResult swapchain::create_image(const VkImageCreateInfo &image_create_info) goto out; } - tbm_surface_info_s info; tbm_bo bo = tbm_surface_internal_get_bo(buffers[i], 0); tbm_bo_handle bo_handle = tbm_bo_get_handle(bo, TBM_DEVICE_3D); - tbm_surface_get_info(buffers[i], &info); - image_data->tbm_buffer = buffers[i]; image_data->buffer_fd = bo_handle.u32;//tbm_bo_export_fd(bo); - image_data->stride = info.planes[0].stride; - image_data->offset = info.planes[0].offset; image_data->memory = VK_NULL_HANDLE; +#ifndef USE_ICD_MALI_NIKEM + tbm_surface_info_s info; + tbm_surface_get_info(buffers[i], &info); + image_data->stride = static_cast(info.planes[0].stride); + image_data->offset = static_cast(info.planes[0].offset); +#endif + wsi_info("New image[%d] - tbm_buffer [%p], buffer fd [%d]", i, image_data->tbm_buffer, image_data->buffer_fd); image.data = static_cast(image_data); +#ifdef USE_ICD_MALI_NIKEM + image.is_external = false; +#endif result = allocate_image(image_create_info, image_data, &image.image); if (result != VK_SUCCESS) @@ -409,7 +421,11 @@ void swapchain::destroy_image(void) m_device_data.disp.DestroyFence(m_device, image.present_fence, get_allocation_callbacks()); image.present_fence = VK_NULL_HANDLE; } +#ifdef USE_ICD_MALI_NIKEM + if (image.image != VK_NULL_HANDLE && !image.is_external) +#else if (image.image != VK_NULL_HANDLE) +#endif { m_device_data.disp.DestroyImage(m_device, image.image, get_allocation_callbacks()); image.image = VK_NULL_HANDLE; @@ -438,5 +454,55 @@ void swapchain::destroy_image(void) } } +#ifdef USE_ICD_MALI_NIKEM +VkResult swapchain::create_external_image(VkImageCreateInfo* pCreateInfo, + const VkAllocationCallbacks* pAllocator, VkImage* pImage) +{ + VkResult result = VK_SUCCESS; + + VkExternalMemoryImageCreateInfoKHR external_info = {}; + external_info.sType = VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO_KHR; + external_info.pNext = pCreateInfo->pNext; + external_info.handleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT; + + pCreateInfo->pNext = &external_info; + pCreateInfo->tiling = VK_IMAGE_TILING_LINEAR; + + for (VkBaseOutStructure *s = (VkBaseOutStructure *)(pCreateInfo); s != nullptr; s = s->pNext) { + if (((VkBaseOutStructure *)(s->pNext))->sType == VK_STRUCTURE_TYPE_IMAGE_SWAPCHAIN_CREATE_INFO_KHR) { + s->pNext = ((VkBaseOutStructure *)(s->pNext))->pNext; + } + } + + result = m_device_data.disp.CreateImage(m_device, pCreateInfo, get_allocation_callbacks(), pImage); + if (result != VK_SUCCESS) { + wsi_error("Image creation failed.\n"); + } + + return result; +} + +VkResult swapchain::bind_external_image(const uint32_t image_index, VkImage image) +{ + VkResult result = VK_SUCCESS; + tizen_image_data *image_data = reinterpret_cast(m_swapchain_images[image_index].data); + + assert(image_data != nullptr); + assert(image_data->memory != VK_NULL_HANDLE); + + if (m_swapchain_images[image_index].image != VK_NULL_HANDLE) + m_device_data.disp.DestroyImage(m_device, m_swapchain_images[image_index].image, get_allocation_callbacks()); + + m_swapchain_images[image_index].image = image; + + result = m_device_data.disp.BindImageMemory(m_device, image, image_data->memory, 0); + if (result == VK_SUCCESS) { + m_swapchain_images[image_index].is_external = true; + } + + return result; +} +#endif + } // namespace wayland } // namespace wsi diff --git a/wsi/tizen/swapchain.hpp b/wsi/tizen/swapchain.hpp index d2c277c..8714fd9 100644 --- a/wsi/tizen/swapchain.hpp +++ b/wsi/tizen/swapchain.hpp @@ -79,6 +79,12 @@ protected: */ void destroy_image(void) override; +#ifdef USE_ICD_MALI_NIKEM + virtual VkResult create_external_image(VkImageCreateInfo* pCreateInfo, + const VkAllocationCallbacks* pAllocator, VkImage* pImage) override; + virtual VkResult bind_external_image(const uint32_t image_index, VkImage image) override; +#endif + private: struct tizen_image_data; VkResult allocate_image(const VkImageCreateInfo &image_create_info, tizen_image_data *image_data, VkImage *image);