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>
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)
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);
}
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" */
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
}
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}
%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
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
VkImage image{VK_NULL_HANDLE};
VkFence present_fence{VK_NULL_HANDLE};
+
+#ifdef USE_ICD_MALI_NIKEM
+ bool is_external{false};
+#endif
};
/**
* 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;
* @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 */
{
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;
};
{
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;
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)
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;
}
}
+#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
*/
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);