Fix CTS Coredump issue of "image_swapchain_create_info" cases on NikeM: 67/269967/1
authorTianhao Ni <tianhao.ni@samsung.com>
Wed, 8 Sep 2021 02:21:44 +0000 (10:21 +0800)
committerTianhao Ni <tianhao.ni@samsung.com>
Mon, 24 Jan 2022 01:20:08 +0000 (09:20 +0800)
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 <tianhao.ni@samsung.com>
CMakeLists.txt
packaging/vulkan-wsi-layer.spec
wsi/swapchain_base_tizen.cpp
wsi/swapchain_base_tizen.hpp
wsi/tizen/swapchain.cpp
wsi/tizen/swapchain.hpp

index ef5fb5957dc77fd47f5c2c96da115478cc77c7fb..6b04161d7b17df877ad375c22839ca465699a3df 100644 (file)
@@ -164,6 +164,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)
index b525253080c1f3946f309a90d4328ddcd3ecfc4d..5c82e4bf199fa302dc207acbfa2170d533fdbc50 100644 (file)
@@ -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
index 1f81fa08ffcd2eb8092915b799565194238b4c30..c488a0a2127e556e7bdce68f8fc379a17e5f64c6 100644 (file)
@@ -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
index b020c805ac983d0346939f62bafe3a7a5e472a1d..63e97dd0c4ffc31378eae239d117cf3f61016da1 100644 (file)
@@ -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 */
index a6f28a5147cf361d1d35f51b1a90da29075416c1..6da418548a4c2851d89eb6a7ac028e0f10936a95 100644 (file)
@@ -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<uint32_t>(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<VkDeviceSize>(info.planes[0].stride);
+      image_data->offset = static_cast<VkDeviceSize>(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<void *>(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<tizen_image_data *>(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
index d2c277c70e6f068ecbcb23d8221f0f9572cb5b70..8714fd92f2b88eab0ba06315ece82173cac8eadf 100644 (file)
@@ -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);