diff --git a/packages/graphics/vulkan/vkmark/package.mk b/packages/graphics/vulkan/vkmark/package.mk index b744de8ee2..884a9d8ede 100644 --- a/packages/graphics/vulkan/vkmark/package.mk +++ b/packages/graphics/vulkan/vkmark/package.mk @@ -2,8 +2,8 @@ # Copyright (C) 2022-present Team LibreELEC (https://libreelec.tv) PKG_NAME="vkmark" -PKG_VERSION="d872846e2e7c47010c11227eb713d00ccfdd35c6" -PKG_SHA256="3b03785c9952d5f1ebad6c08349d8697814ad6724f81c05891afabb59f54bf22" +PKG_VERSION="30d2cd37f0566589d90914501fc7c51a4e51f559" +PKG_SHA256="6a2ab6a9c58b4bd11eb0235a8e31b10b3d0cbcd5c64b799d342572936a717745" PKG_LICENSE="LGPL-2.1-or-later" PKG_SITE="https://github.com/vkmark/vkmark" PKG_URL="https://github.com/vkmark/vkmark/archive/${PKG_VERSION}.tar.gz" diff --git a/packages/graphics/vulkan/vkmark/patches/vkmark-999.01-PR47-drop-the-vkCreateDmaBufImageINTEL-extension.patch b/packages/graphics/vulkan/vkmark/patches/vkmark-999.01-PR47-drop-the-vkCreateDmaBufImageINTEL-extension.patch new file mode 100644 index 0000000000..ab1f789063 --- /dev/null +++ b/packages/graphics/vulkan/vkmark/patches/vkmark-999.01-PR47-drop-the-vkCreateDmaBufImageINTEL-extension.patch @@ -0,0 +1,542 @@ +From 51c7eb0c8c1cd4872eec176775276cca3565a0a6 Mon Sep 17 00:00:00 2001 +From: Alexandros Frantzis +Date: Fri, 9 Sep 2022 18:32:03 +0300 +Subject: [PATCH 1/4] github: Build with both ubuntu-20.04 and ubuntu-22.04 in + CI + +--- + .github/workflows/build.yml | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml +index fbb5682..b60ad80 100644 +--- a/.github/workflows/build.yml ++++ b/.github/workflows/build.yml +@@ -10,7 +10,10 @@ on: + + jobs: + build: +- runs-on: ubuntu-latest ++ strategy: ++ matrix: ++ os: [ubuntu-20.04, ubuntu-22.04] ++ runs-on: ${{ matrix.os }} + steps: + - uses: actions/checkout@v1 + - name: Install dependencies + +From 7bbe275e49045237f2cdbc2f441a394b562b0aa5 Mon Sep 17 00:00:00 2001 +From: Alexandros Frantzis +Date: Fri, 9 Sep 2022 18:08:12 +0300 +Subject: [PATCH 2/4] core: Improve log message consistency + +--- + src/vulkan_state.cpp | 12 ++++++------ + 1 file changed, 6 insertions(+), 6 deletions(-) + +diff --git a/src/vulkan_state.cpp b/src/vulkan_state.cpp +index 6f50673..fbd789c 100644 +--- a/src/vulkan_state.cpp ++++ b/src/vulkan_state.cpp +@@ -44,7 +44,7 @@ std::vector VulkanState::available_devices(VulkanWSI& vulkan + { + if (!vulkan_wsi.is_physical_device_supported(*it_device)) + { +- Log::debug("device with uuid %s is not supported by window system integration layer", ++ Log::debug("Device with uuid %s is not supported by window system integration layer\n", + static_cast(it_device->getProperties().pipelineCacheUUID).representation().data()); + it_device = available_devices.erase(it_device); + } +@@ -193,17 +193,17 @@ void VulkanState::create_command_pool() + + vk::PhysicalDevice ChooseFirstSupportedStrategy::operator()(const std::vector& available_devices) + { +- Log::debug("Trying to use first supported device.\n"); ++ Log::debug("Trying to use first supported device\n"); + + for (auto const& physical_device : available_devices) + { + if (find_queue_family_index(physical_device, vk::QueueFlagBits::eGraphics).second) + { +- Log::debug("First supported device choosen!\n"); ++ Log::debug("First supported device chosen\n"); + return physical_device; + } + +- Log::debug("device with uuid %s skipped!\n", ++ Log::debug("Device with uuid %s skipped\n", + static_cast(physical_device.getProperties().pipelineCacheUUID).representation().data() + ); + } +@@ -213,7 +213,7 @@ vk::PhysicalDevice ChooseFirstSupportedStrategy::operator()(const std::vector& available_devices) + { +- Log::debug("Trying to use device with specified UUID %s.\n", ++ Log::debug("Trying to use device with specified UUID %s\n", + m_selected_device_uuid.representation().data()); + + for (auto const& physical_device: available_devices) +@@ -227,5 +227,5 @@ vk::PhysicalDevice ChooseByUUIDStrategy::operator()(const std::vector +Date: Fri, 9 Sep 2022 17:48:44 +0300 +Subject: [PATCH 3/4] core,ws: Allow WSI backends to request device extensions + +The backends were able to request instance extensions, support +requesting device extensions, too. +--- + src/vulkan_state.cpp | 5 ++--- + src/vulkan_wsi.h | 8 +++++++- + src/ws/kms_window_system.cpp | 2 +- + src/ws/kms_window_system.h | 2 +- + src/ws/native_system.h | 2 +- + src/ws/swapchain_window_system.cpp | 4 ++-- + src/ws/swapchain_window_system.h | 2 +- + src/ws/wayland_native_system.cpp | 2 +- + src/ws/wayland_native_system.h | 2 +- + src/ws/xcb_native_system.cpp | 2 +- + src/ws/xcb_native_system.h | 2 +- + tests/null_window_system.h | 2 +- + tests/test_window_system_plugin.cpp | 2 +- + tests/window_system_loader_test.cpp | 2 +- + 14 files changed, 22 insertions(+), 17 deletions(-) + +diff --git a/src/vulkan_state.cpp b/src/vulkan_state.cpp +index fbd789c..b1973ed 100644 +--- a/src/vulkan_state.cpp ++++ b/src/vulkan_state.cpp +@@ -87,7 +87,7 @@ void VulkanState::create_instance(VulkanWSI& vulkan_wsi) + auto const app_info = vk::ApplicationInfo{} + .setPApplicationName("vkmark"); + +- std::vector enabled_extensions{vulkan_wsi.vulkan_extensions()}; ++ std::vector enabled_extensions{vulkan_wsi.required_extensions().instance}; + enabled_extensions.push_back(VK_KHR_SURFACE_EXTENSION_NAME); + + auto const create_info = vk::InstanceCreateInfo{} +@@ -159,8 +159,7 @@ void VulkanState::create_logical_device(VulkanWSI& vulkan_wsi) + Log::debug("VulkanState: Using queue family index %d for rendering\n", + graphics_queue_family_index()); + +- std::array enabled_extensions{ +- {VK_KHR_SWAPCHAIN_EXTENSION_NAME}}; ++ std::vector enabled_extensions{vulkan_wsi.required_extensions().device}; + + auto const device_features = vk::PhysicalDeviceFeatures{} + .setSamplerAnisotropy(true); +diff --git a/src/vulkan_wsi.h b/src/vulkan_wsi.h +index f8c50eb..22e87f1 100644 +--- a/src/vulkan_wsi.h ++++ b/src/vulkan_wsi.h +@@ -32,7 +32,13 @@ class VulkanWSI + public: + virtual ~VulkanWSI() = default; + +- virtual std::vector vulkan_extensions() = 0; ++ struct Extensions ++ { ++ std::vector instance; ++ std::vector device; ++ }; ++ ++ virtual Extensions required_extensions() = 0; + virtual bool is_physical_device_supported(vk::PhysicalDevice const& pd) = 0; + virtual std::vector physical_device_queue_family_indices( + vk::PhysicalDevice const& pd) = 0; +diff --git a/src/ws/kms_window_system.cpp b/src/ws/kms_window_system.cpp +index ca8220f..6132e64 100644 +--- a/src/ws/kms_window_system.cpp ++++ b/src/ws/kms_window_system.cpp +@@ -533,7 +533,7 @@ void KMSWindowSystem::wait_for_drm_page_flip_event() + } + } + +-std::vector KMSWindowSystem::vulkan_extensions() ++VulkanWSI::Extensions KMSWindowSystem::required_extensions() + { + return {}; + } +diff --git a/src/ws/kms_window_system.h b/src/ws/kms_window_system.h +index 4389ef7..20a067f 100644 +--- a/src/ws/kms_window_system.h ++++ b/src/ws/kms_window_system.h +@@ -61,7 +61,7 @@ class KMSWindowSystem : public WindowSystem, public VulkanWSI + bool should_quit() override; + + // VulkanWSI +- std::vector vulkan_extensions() override; ++ Extensions required_extensions() override; + bool is_physical_device_supported(vk::PhysicalDevice const& pd) override; + std::vector physical_device_queue_family_indices( + vk::PhysicalDevice const& pd) override; +diff --git a/src/ws/native_system.h b/src/ws/native_system.h +index 076948e..cbe073a 100644 +--- a/src/ws/native_system.h ++++ b/src/ws/native_system.h +@@ -34,7 +34,7 @@ class NativeSystem + public: + virtual ~NativeSystem() = default; + +- virtual std::vector vulkan_extensions() = 0; ++ virtual std::vector instance_extensions() = 0; + virtual uint32_t get_presentation_queue_family_index(vk::PhysicalDevice const& pd) = 0; + virtual bool should_quit() = 0; + virtual vk::Extent2D get_vk_extent() = 0; +diff --git a/src/ws/swapchain_window_system.cpp b/src/ws/swapchain_window_system.cpp +index d38fa6b..9f9fba3 100644 +--- a/src/ws/swapchain_window_system.cpp ++++ b/src/ws/swapchain_window_system.cpp +@@ -251,9 +251,9 @@ ManagedResource SwapchainWindowSystem::create_vk_swapchain() + [this] (auto& s) { vulkan->device().destroySwapchainKHR(s); }}; + } + +-std::vector SwapchainWindowSystem::vulkan_extensions() ++VulkanWSI::Extensions SwapchainWindowSystem::required_extensions() + { +- return native->vulkan_extensions(); ++ return {native->instance_extensions(), {VK_KHR_SWAPCHAIN_EXTENSION_NAME}}; + } + + bool SwapchainWindowSystem::is_physical_device_supported(vk::PhysicalDevice const& pd) +diff --git a/src/ws/swapchain_window_system.h b/src/ws/swapchain_window_system.h +index c3b2780..412b924 100644 +--- a/src/ws/swapchain_window_system.h ++++ b/src/ws/swapchain_window_system.h +@@ -51,7 +51,7 @@ class SwapchainWindowSystem : public WindowSystem, public VulkanWSI + bool should_quit() override; + + // VulkanWSI +- std::vector vulkan_extensions() override; ++ Extensions required_extensions() override; + bool is_physical_device_supported(vk::PhysicalDevice const& pd) override; + std::vector physical_device_queue_family_indices( + vk::PhysicalDevice const& pd) override; +diff --git a/src/ws/wayland_native_system.cpp b/src/ws/wayland_native_system.cpp +index 642d8fe..816a7b9 100644 +--- a/src/ws/wayland_native_system.cpp ++++ b/src/ws/wayland_native_system.cpp +@@ -145,7 +145,7 @@ WaylandNativeSystem::WaylandNativeSystem(int width, int height) + create_native_window(); + } + +-std::vector WaylandNativeSystem::vulkan_extensions() ++std::vector WaylandNativeSystem::instance_extensions() + { + return {VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME}; + } +diff --git a/src/ws/wayland_native_system.h b/src/ws/wayland_native_system.h +index 400c358..01cdbaa 100644 +--- a/src/ws/wayland_native_system.h ++++ b/src/ws/wayland_native_system.h +@@ -35,7 +35,7 @@ class WaylandNativeSystem : public NativeSystem + public: + WaylandNativeSystem(int width, int height); + +- std::vector vulkan_extensions() override; ++ std::vector instance_extensions() override; + uint32_t get_presentation_queue_family_index(vk::PhysicalDevice const& pd) override; + bool should_quit() override; + vk::Extent2D get_vk_extent() override; +diff --git a/src/ws/xcb_native_system.cpp b/src/ws/xcb_native_system.cpp +index 59c84f0..b683772 100644 +--- a/src/ws/xcb_native_system.cpp ++++ b/src/ws/xcb_native_system.cpp +@@ -47,7 +47,7 @@ XcbNativeSystem::~XcbNativeSystem() + xcb_disconnect(connection); + } + +-std::vector XcbNativeSystem::vulkan_extensions() ++std::vector XcbNativeSystem::instance_extensions() + { + return {VK_KHR_XCB_SURFACE_EXTENSION_NAME}; + } +diff --git a/src/ws/xcb_native_system.h b/src/ws/xcb_native_system.h +index 7fcc44a..dadc32f 100644 +--- a/src/ws/xcb_native_system.h ++++ b/src/ws/xcb_native_system.h +@@ -35,7 +35,7 @@ class XcbNativeSystem : public NativeSystem + XcbNativeSystem(int width, int height, xcb_visualid_t visual_id); + ~XcbNativeSystem(); + +- std::vector vulkan_extensions() override; ++ std::vector instance_extensions() override; + uint32_t get_presentation_queue_family_index(vk::PhysicalDevice const& pd) override; + bool should_quit() override; + vk::Extent2D get_vk_extent() override; +diff --git a/tests/null_window_system.h b/tests/null_window_system.h +index bc01276..b7cc9ba 100644 +--- a/tests/null_window_system.h ++++ b/tests/null_window_system.h +@@ -39,7 +39,7 @@ class NullWindowSystem : public WindowSystem, public VulkanWSI + + bool should_quit() override { return false; } + +- std::vector vulkan_extensions() override { return {}; } ++ Extensions required_extensions() override { return {}; } + bool is_physical_device_supported(vk::PhysicalDevice const&) override { return true; } + std::vector physical_device_queue_family_indices( + vk::PhysicalDevice const&) override +diff --git a/tests/test_window_system_plugin.cpp b/tests/test_window_system_plugin.cpp +index 7877c8e..a562958 100644 +--- a/tests/test_window_system_plugin.cpp ++++ b/tests/test_window_system_plugin.cpp +@@ -32,7 +32,7 @@ class TestWindowSystem : public NullWindowSystem + { + public: + TestWindowSystem(std::string const& id) : id{id} {} +- std::vector vulkan_extensions() override { return {id.c_str()}; } ++ Extensions required_extensions() override { return {{id.c_str()}, {}}; } + + private: + std::string const id; +diff --git a/tests/window_system_loader_test.cpp b/tests/window_system_loader_test.cpp +index 8aed335..c458e61 100644 +--- a/tests/window_system_loader_test.cpp ++++ b/tests/window_system_loader_test.cpp +@@ -84,7 +84,7 @@ class TestWindowSystems + + int window_system_id(WindowSystem& ws) + { +- return std::stoi(ws.vulkan_wsi().vulkan_extensions()[0]); ++ return std::stoi(ws.vulkan_wsi().required_extensions().instance[0]); + } + + } + +From dd75130a7ddf747eb7fd755946e84baf98a6e05f Mon Sep 17 00:00:00 2001 +From: Alexandros Frantzis +Date: Fri, 9 Sep 2022 16:23:40 +0300 +Subject: [PATCH 4/4] kms: Use VK_EXT_external_memory_dmabuf to create + dmabuf-backed Vulkan images + +Drop the vkCreateDmaBufImageINTEL extension function and use the +functionality provided by the official VK_EXT_external_memory_dmabuf +extension to create dmabuf-backed Vulkan images. + +Fixes #33 + +Co-authored-by: Jeffy Chen +--- + meson.build | 7 +- + src/ws/kms_window_system.cpp | 132 +++++++++++++++++++++++------------ + 2 files changed, 89 insertions(+), 50 deletions(-) + +diff --git a/meson.build b/meson.build +index 7d305dc..0d83918 100644 +--- a/meson.build ++++ b/meson.build +@@ -32,16 +32,11 @@ wayland_protocols_dep = dependency('wayland-protocols', version : '>= 1.12', + wayland_scanner_dep = dependency('wayland-scanner', required : get_option('wayland') == 'true') + libdrm_dep = dependency('libdrm', required : get_option('kms') == 'true') + gbm_dep = dependency('gbm', required : get_option('kms') == 'true') +-has_vulkan_intel_header = cpp.has_header('vulkan/vulkan_intel.h', dependencies: vulkan_dep) +- +-if get_option('kms') == 'true' and not has_vulkan_intel_header +- error('KMS plugin needs the vulkan_intel.h header, but it couldn\'t be found') +-endif + + build_xcb_ws = xcb_dep.found() and xcb_icccm_dep.found() and get_option('xcb') != 'false' + build_wayland_ws = (wayland_client_dep.found() and wayland_protocols_dep.found() and + wayland_scanner_dep.found() and get_option('wayland') != 'false') +-build_kms_ws = libdrm_dep.found() and gbm_dep.found() and has_vulkan_intel_header and get_option('kms') != 'false' ++build_kms_ws = libdrm_dep.found() and gbm_dep.found() and get_option('kms') != 'false' + + if not build_xcb_ws and not build_wayland_ws and not build_kms_ws + error('vkmark needs at least one winsys to work - xcb, wayland or kms') +diff --git a/src/ws/kms_window_system.cpp b/src/ws/kms_window_system.cpp +index 6132e64..fc02eae 100644 +--- a/src/ws/kms_window_system.cpp ++++ b/src/ws/kms_window_system.cpp +@@ -29,8 +29,8 @@ + + #include + #include +-#include + ++#include + #include + #include + #include +@@ -270,6 +270,24 @@ void restore_vt(int) + global_vt_state->restore(); + } + ++uint32_t find_memory_type_index(vk::PhysicalDevice const& physical_device, ++ vk::MemoryRequirements const& requirements, ++ vk::MemoryPropertyFlags flags) ++{ ++ auto const properties = physical_device.getMemoryProperties(); ++ ++ for (uint32_t i = 0; i < properties.memoryTypeCount; i++) ++ { ++ if ((requirements.memoryTypeBits & (1 << i)) && ++ (properties.memoryTypes[i].propertyFlags & flags) == flags) ++ { ++ return i; ++ } ++ } ++ ++ throw std::runtime_error{"Coudn't find matching memory type"}; ++} ++ + } + + VTState::VTState() +@@ -433,14 +451,20 @@ void KMSWindowSystem::create_drm_fbs() + for (auto const& gbm_bo : gbm_bos) + { + uint32_t fb = 0; ++ uint32_t handles[4] = {0}; ++ uint32_t strides[4] = {0}; ++ uint32_t offsets[4] = {0}; + +- uint32_t handles[4] = {gbm_bo_get_handle(gbm_bo).u32, 0, 0, 0}; +- uint32_t strides[4] = {gbm_bo_get_stride(gbm_bo), 0, 0, 0}; +- uint32_t offsets[4] = {0, 0, 0, 0}; ++ for (auto i = 0; i < gbm_bo_get_plane_count(gbm_bo); i++) ++ { ++ handles[i] = gbm_bo_get_handle_for_plane(gbm_bo, i).u32; ++ offsets[i] = gbm_bo_get_offset(gbm_bo, i); ++ strides[i] = gbm_bo_get_stride_for_plane(gbm_bo, i); ++ } + + auto const ret = drmModeAddFB2( + drm_fd, vk_extent.width, vk_extent.height, +- DRM_FORMAT_XRGB8888, ++ gbm_bo_get_format(gbm_bo), + handles, strides, offsets, &fb, 0); + + if (ret < 0) +@@ -453,52 +477,65 @@ void KMSWindowSystem::create_drm_fbs() + } + } + +-// TODO: Use an official extension to create the VkImages when it becomes +-// available (e.g. VK_MESAX_external_image_dma_buf) + void KMSWindowSystem::create_vk_images() + { +- auto const create_dma_buf_image = +- reinterpret_cast( +- vulkan->device().getProcAddr("vkCreateDmaBufImageINTEL")); +- +- if (!create_dma_buf_image) +- throw std::runtime_error{"Failed to get vkCreateDmaBufImageINTEL function pointer"}; +- + for (auto const& gbm_bo : gbm_bos) + { + auto const fd = ManagedResource{gbm_bo_get_fd(gbm_bo), close}; +- auto const stride = gbm_bo_get_stride(gbm_bo); +- +- VkDmaBufImageCreateInfo create_info{}; +- create_info.sType = static_cast(VK_STRUCTURE_TYPE_DMA_BUF_IMAGE_CREATE_INFO_INTEL); +- create_info.fd = fd; +- create_info.format = static_cast(vk_image_format); +- create_info.extent = {vk_extent.width, vk_extent.height, 1}; +- create_info.strideInBytes = stride; +- +- VkImage image; +- VkDeviceMemory device_memory; +- +- VkResult result = create_dma_buf_image( +- vulkan->device(), +- &create_info, +- nullptr, +- &device_memory, +- &image); +- +- if (result != VK_SUCCESS) +- { +- vk::throwResultException(static_cast(result), +- "vkCreateDmbBufImageINTEL"); +- } ++ uint64_t modifier = gbm_bo_get_modifier(gbm_bo); ++ ++ auto const modifier_info = vk::ImageDrmFormatModifierListCreateInfoEXT{} ++ .setDrmFormatModifierCount(1) ++ .setPDrmFormatModifiers(&modifier); ++ auto const external_memory_create_info = vk::ExternalMemoryImageCreateInfoKHR{} ++ .setHandleTypes(vk::ExternalMemoryHandleTypeFlagBitsKHR::eDmaBufEXT) ++ .setPNext(&modifier_info); ++ auto const image_create_info = vk::ImageCreateInfo{} ++ .setPNext(&external_memory_create_info) ++ .setImageType(vk::ImageType::e2D) ++ .setFormat(vk_image_format) ++ .setExtent({vk_extent.width, vk_extent.height, 1}) ++ .setMipLevels(1) ++ .setArrayLayers(1) ++ .setSamples(vk::SampleCountFlagBits::e1) ++ .setTiling(vk::ImageTiling::eDrmFormatModifierEXT) ++ .setUsage(vk::ImageUsageFlagBits::eColorAttachment) ++ .setSharingMode(vk::SharingMode::eExclusive) ++ .setInitialLayout(vk::ImageLayout::eUndefined); ++ ++ auto vk_image = ManagedResource{ ++ vulkan->device().createImage(image_create_info), ++ [vptr=vulkan] (auto const& i) { vptr->device().destroyImage(i); }}; ++ ++ auto const requirements = vulkan->device().getImageMemoryRequirements(vk_image); ++ uint32_t index = find_memory_type_index(vulkan->physical_device(), ++ requirements, ++ vk::MemoryPropertyFlagBits::eDeviceLocal); ++ ++ auto const import_memory_fd_info = vk::ImportMemoryFdInfoKHR{} ++ .setHandleType(vk::ExternalMemoryHandleTypeFlagBitsKHR::eDmaBufEXT) ++ .setFd(fd); ++ auto const dedicated_allocate_info = vk::MemoryDedicatedAllocateInfoKHR{} ++ .setPNext(&import_memory_fd_info) ++ .setImage(vk_image); ++ auto const memory_allocate_info = vk::MemoryAllocateInfo{} ++ .setPNext(&dedicated_allocate_info) ++ .setAllocationSize(requirements.size) ++ .setMemoryTypeIndex((uint32_t)index); ++ ++ auto device_memory = ManagedResource{ ++ vulkan->device().allocateMemory(memory_allocate_info), ++ [vptr=vulkan] (auto const& m) { vptr->device().freeMemory(m); }}; ++ ++ vulkan->device().bindImageMemory(vk_image, device_memory, 0); + + vk_images.push_back( + ManagedResource{ +- vk::Image{image}, +- [vptr=vulkan, device_memory] (auto& image) ++ vk_image.steal(), ++ [vptr=vulkan, mem=device_memory.steal()] (auto const& image) + { + vptr->device().destroyImage(image); +- vptr->device().freeMemory(device_memory); ++ vptr->device().freeMemory(mem); + }}); + } + } +@@ -535,12 +572,19 @@ void KMSWindowSystem::wait_for_drm_page_flip_event() + + VulkanWSI::Extensions KMSWindowSystem::required_extensions() + { +- return {}; ++ return {{}, {VK_EXT_EXTERNAL_MEMORY_DMA_BUF_EXTENSION_NAME}}; + } + +-bool KMSWindowSystem::is_physical_device_supported(vk::PhysicalDevice const&) ++bool KMSWindowSystem::is_physical_device_supported(vk::PhysicalDevice const& physdev) + { +- return true; ++ auto const props = physdev.enumerateDeviceExtensionProperties(); ++ auto const iter = std::find_if( ++ props.begin(), props.end(), ++ [](vk::ExtensionProperties prop) ++ { ++ return std::string{VK_EXT_EXTERNAL_MEMORY_DMA_BUF_EXTENSION_NAME} == prop.extensionName; ++ }); ++ return iter != props.end(); + } + + std::vector KMSWindowSystem::physical_device_queue_family_indices( diff --git a/packages/graphics/vulkan/vkmark/patches/vkmark-999.01-drop-dependency-on-vkCreateDmaBufImageINTEL.patch b/packages/graphics/vulkan/vkmark/patches/vkmark-999.01-drop-dependency-on-vkCreateDmaBufImageINTEL.patch deleted file mode 100644 index a0c5ac5fb9..0000000000 --- a/packages/graphics/vulkan/vkmark/patches/vkmark-999.01-drop-dependency-on-vkCreateDmaBufImageINTEL.patch +++ /dev/null @@ -1,273 +0,0 @@ -From 0dd62e9adff82d51ed67c625a4f456a8e5f1a2e2 Mon Sep 17 00:00:00 2001 -From: Jeffy Chen -Date: Mon, 23 May 2022 10:57:27 +0800 -Subject: [PATCH] kms: Drop dependency on vkCreateDmaBufImageINTEL - -Based on chromium's gpu/vulkan/vulkan_image{_linux,}.cc - -Signed-off-by: Jeffy Chen ---- - meson.build | 7 +- - src/ws/kms_window_system.cpp | 172 ++++++++++++++++++++++++++--------- - src/ws/kms_window_system.h | 1 - - 3 files changed, 130 insertions(+), 50 deletions(-) - -diff --git a/meson.build b/meson.build -index 7d305dc..0d83918 100644 ---- a/meson.build -+++ b/meson.build -@@ -32,16 +32,11 @@ wayland_protocols_dep = dependency('wayland-protocols', version : '>= 1.12', - wayland_scanner_dep = dependency('wayland-scanner', required : get_option('wayland') == 'true') - libdrm_dep = dependency('libdrm', required : get_option('kms') == 'true') - gbm_dep = dependency('gbm', required : get_option('kms') == 'true') --has_vulkan_intel_header = cpp.has_header('vulkan/vulkan_intel.h', dependencies: vulkan_dep) -- --if get_option('kms') == 'true' and not has_vulkan_intel_header -- error('KMS plugin needs the vulkan_intel.h header, but it couldn\'t be found') --endif - - build_xcb_ws = xcb_dep.found() and xcb_icccm_dep.found() and get_option('xcb') != 'false' - build_wayland_ws = (wayland_client_dep.found() and wayland_protocols_dep.found() and - wayland_scanner_dep.found() and get_option('wayland') != 'false') --build_kms_ws = libdrm_dep.found() and gbm_dep.found() and has_vulkan_intel_header and get_option('kms') != 'false' -+build_kms_ws = libdrm_dep.found() and gbm_dep.found() and get_option('kms') != 'false' - - if not build_xcb_ws and not build_wayland_ws and not build_kms_ws - error('vkmark needs at least one winsys to work - xcb, wayland or kms') -diff --git a/src/ws/kms_window_system.cpp b/src/ws/kms_window_system.cpp -index ca8220f..18c5384 100644 ---- a/src/ws/kms_window_system.cpp -+++ b/src/ws/kms_window_system.cpp -@@ -29,7 +29,6 @@ - - #include - #include --#include - - #include - #include -@@ -352,7 +351,6 @@ void KMSWindowSystem::init_vulkan(VulkanState& vulkan_) - - vk_image_format = vk::Format::eB8G8R8A8Srgb; - create_gbm_bos(); -- create_drm_fbs(); - create_vk_images(); - } - -@@ -428,68 +426,122 @@ void KMSWindowSystem::create_gbm_bos() - } - } - --void KMSWindowSystem::create_drm_fbs() --{ -- for (auto const& gbm_bo : gbm_bos) -- { -- uint32_t fb = 0; -- -- uint32_t handles[4] = {gbm_bo_get_handle(gbm_bo).u32, 0, 0, 0}; -- uint32_t strides[4] = {gbm_bo_get_stride(gbm_bo), 0, 0, 0}; -- uint32_t offsets[4] = {0, 0, 0, 0}; -- -- auto const ret = drmModeAddFB2( -- drm_fd, vk_extent.width, vk_extent.height, -- DRM_FORMAT_XRGB8888, -- handles, strides, offsets, &fb, 0); -- -- if (ret < 0) -- throw std::system_error{-ret, std::system_category(), "Failed to add drm fb"}; -+// TODO: Use an official extension to create the VkImages when it becomes -+// available (e.g. VK_MESAX_external_image_dma_buf) - -- drm_fbs.push_back( -- ManagedResource{ -- std::move(fb), -- [this] (auto& fb) { drmModeRmFB(drm_fd, fb); }}); -+static int find_memory_type_index(VkPhysicalDevice physical_device, -+ const VkMemoryRequirements* requirements, -+ VkMemoryPropertyFlags flags) { -+ VkPhysicalDeviceMemoryProperties properties; -+ vkGetPhysicalDeviceMemoryProperties(physical_device, &properties); -+ for (int i = 0; i <= 31; i++) { -+ if (((1u << i) & requirements->memoryTypeBits) == 0) -+ continue; -+ if ((properties.memoryTypes[i].propertyFlags & flags) != flags) -+ continue; -+ return i; - } -+ return -1; - } - --// TODO: Use an official extension to create the VkImages when it becomes --// available (e.g. VK_MESAX_external_image_dma_buf) - void KMSWindowSystem::create_vk_images() - { -- auto const create_dma_buf_image = -- reinterpret_cast( -- vulkan->device().getProcAddr("vkCreateDmaBufImageINTEL")); -- -- if (!create_dma_buf_image) -- throw std::runtime_error{"Failed to get vkCreateDmaBufImageINTEL function pointer"}; -- - for (auto const& gbm_bo : gbm_bos) - { - auto const fd = ManagedResource{gbm_bo_get_fd(gbm_bo), close}; -- auto const stride = gbm_bo_get_stride(gbm_bo); - -- VkDmaBufImageCreateInfo create_info{}; -- create_info.sType = static_cast(VK_STRUCTURE_TYPE_DMA_BUF_IMAGE_CREATE_INFO_INTEL); -- create_info.fd = fd; -- create_info.format = static_cast(vk_image_format); -- create_info.extent = {vk_extent.width, vk_extent.height, 1}; -- create_info.strideInBytes = stride; -+ VkExternalMemoryImageCreateInfoKHR external_image_create_info = { -+ .sType = VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO_KHR, -+ .handleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT, -+ }; -+ -+ uint64_t modifier = DRM_FORMAT_MOD_LINEAR; -+ VkImageDrmFormatModifierListCreateInfoEXT modifier_info = { -+ .sType = VK_STRUCTURE_TYPE_IMAGE_DRM_FORMAT_MODIFIER_LIST_CREATE_INFO_EXT, -+ .drmFormatModifierCount = 1, -+ .pDrmFormatModifiers = &modifier, -+ }; -+ external_image_create_info.pNext = &modifier_info; -+ -+ VkImportMemoryFdInfoKHR import_memory_fd_info = { -+ .sType = VK_STRUCTURE_TYPE_IMPORT_MEMORY_FD_INFO_KHR, -+ .handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT, -+ .fd = fd, -+ }; -+ -+ VkImageCreateInfo create_info{}; -+ create_info = { -+ .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, -+ .pNext = &external_image_create_info, -+ .flags = 0, -+ .imageType = VK_IMAGE_TYPE_2D, -+ .format = static_cast(vk_image_format), -+ .extent = {vk_extent.width, vk_extent.height, 1}, -+ .mipLevels = 1, -+ .arrayLayers = 1, -+ .samples = VK_SAMPLE_COUNT_1_BIT, -+ .tiling = VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT, -+ .usage = 0, -+ .sharingMode = VK_SHARING_MODE_EXCLUSIVE, -+ .queueFamilyIndexCount = 0, -+ .pQueueFamilyIndices = nullptr, -+ .initialLayout = VK_IMAGE_LAYOUT_UNDEFINED, -+ }; - - VkImage image; -- VkDeviceMemory device_memory; - -- VkResult result = create_dma_buf_image( -+ VkResult result = vkCreateImage( - vulkan->device(), - &create_info, - nullptr, -- &device_memory, - &image); -+ if (result != VK_SUCCESS) -+ { -+ vk::throwResultException(static_cast(result), -+ "vkCreateImage"); -+ } -+ -+ VkMemoryDedicatedAllocateInfoKHR dedicated_memory_info = { -+ .sType = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO_KHR, -+ .pNext = &import_memory_fd_info, -+ .image = image, -+ }; -+ -+ VkMemoryRequirements requirements; -+ vkGetImageMemoryRequirements(vulkan->device(), image, &requirements); -+ if (!requirements.memoryTypeBits) { -+ throw std::runtime_error{"Failed in vkGetImageMemoryRequirements"}; -+ } -+ -+ int index = find_memory_type_index(vulkan->physical_device(), -+ &requirements, -+ VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); -+ if (index < 0) { -+ throw std::runtime_error{"Failed to get memoryTypeIndex"}; -+ } -+ -+ VkMemoryAllocateInfo memory_allocate_info = { -+ .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, -+ .pNext = &dedicated_memory_info, -+ .allocationSize = requirements.size, -+ .memoryTypeIndex = (uint32_t)index, -+ }; -+ -+ VkDeviceMemory device_memory = VK_NULL_HANDLE; -+ result = vkAllocateMemory(vulkan->device(), &memory_allocate_info, -+ nullptr /* pAllocator */, &device_memory); - - if (result != VK_SUCCESS) - { - vk::throwResultException(static_cast(result), -- "vkCreateDmbBufImageINTEL"); -+ "vkAllocateMemory"); -+ } -+ -+ result = vkBindImageMemory(vulkan->device(), image, device_memory, -+ 0 /* memoryOffset */); -+ if (result != VK_SUCCESS) { -+ vk::throwResultException(static_cast(result), -+ "vkBindImageMemory"); - } - - vk_images.push_back( -@@ -500,6 +552,40 @@ void KMSWindowSystem::create_vk_images() - vptr->device().destroyImage(image); - vptr->device().freeMemory(device_memory); - }}); -+ -+ std::array layouts = {}; -+ const VkImageSubresource image_subresource = { -+ .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, -+ .mipLevel = 0, -+ .arrayLayer = 0, -+ }; -+ vkGetImageSubresourceLayout(vulkan->device(), image, -+ &image_subresource, &layouts[0]); -+ -+ uint32_t fb = 0; -+ -+ uint32_t handles[4] = {0,}; -+ uint32_t strides[4] = {0,}; -+ uint32_t offsets[4] = {0,}; -+ -+ for (auto i = 0; i < gbm_bo_get_plane_count(gbm_bo); i++) { -+ handles[i] = gbm_bo_get_handle(gbm_bo).u32; -+ offsets[i] = layouts[i].offset; -+ strides[i] = layouts[i].rowPitch; -+ } -+ -+ auto const ret = drmModeAddFB2( -+ drm_fd, vk_extent.width, vk_extent.height, -+ DRM_FORMAT_XRGB8888, -+ handles, strides, offsets, &fb, 0); -+ -+ if (ret < 0) -+ throw std::system_error{-ret, std::system_category(), "Failed to add drm fb"}; -+ -+ drm_fbs.push_back( -+ ManagedResource{ -+ std::move(fb), -+ [this] (auto& fb) { drmModeRmFB(drm_fd, fb); }}); - } - } - -diff --git a/src/ws/kms_window_system.h b/src/ws/kms_window_system.h -index 4389ef7..ca304c0 100644 ---- a/src/ws/kms_window_system.h -+++ b/src/ws/kms_window_system.h -@@ -68,7 +68,6 @@ class KMSWindowSystem : public WindowSystem, public VulkanWSI - - protected: - void create_gbm_bos(); -- void create_drm_fbs(); - void create_vk_images(); - void wait_for_drm_page_flip_event(); -