Fix CTS Coredump issue of "image_swapchain_create_info" cases on NikeM: 72/263672/3 new_wsi_layer
authorTianhao Ni <tianhao.ni@samsung.com>
Wed, 8 Sep 2021 02:21:44 +0000 (10:21 +0800)
committerTianhao Ni <tianhao.ni@samsung.com>
Wed, 8 Sep 2021 03:07:48 +0000 (11:07 +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
layer/layer.cpp
layer/swapchain_api.cpp
layer/swapchain_api.hpp
packaging/vulkan-wsi-layer.spec
wsi/swapchain_base_tizen.cpp
wsi/swapchain_base_tizen.hpp
wsi/tizen/swapchain.cpp
wsi/tizen/swapchain.hpp

index 0f022de284fc948c150b7bf8604a12863b751113..1642878a5fd5b831017ea7c37d315a95ae4e40ed 100644 (file)
@@ -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)
index 82a1cdeedb8b24e4b4110f9d049f1e03db544536..71c9f2d6c269493520d7628979fc1963cb5164ea 100644 (file)
@@ -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);
 }
index dd0e3e6a211061d42a4ff816b6c629caa2d0459a..3c7dc4e6705d2260c2a188665de36a93be2de094 100644 (file)
@@ -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<wsi::swapchain_base *>(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" */
index d1476f919e88a221e01128e5a1991e0795c7ec84..3a1fac9eec955f6f592fb9d4eb64ee51ed54582c 100644 (file)
@@ -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
 }
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);