distribution/packages/graphics/vulkan/vkmark/patches/vkmark-999.01-PR47-drop-the-vkCreateDmaBufImageINTEL-extension.patch
2022-12-30 13:35:48 -08:00

542 lines
22 KiB
Diff
Executable file

From 51c7eb0c8c1cd4872eec176775276cca3565a0a6 Mon Sep 17 00:00:00 2001
From: Alexandros Frantzis <alexandros.frantzis@collabora.com>
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 <alexandros.frantzis@collabora.com>
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<vk::PhysicalDevice> 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<DeviceUUID>(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<vk::PhysicalDevice>& 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<DeviceUUID>(physical_device.getProperties().pipelineCacheUUID).representation().data()
);
}
@@ -213,7 +213,7 @@ vk::PhysicalDevice ChooseFirstSupportedStrategy::operator()(const std::vector<vk
vk::PhysicalDevice ChooseByUUIDStrategy::operator()(const std::vector<vk::PhysicalDevice>& 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<vk::Physic
}
// if device is not supported by wsi it would appear in list_all_devices but is not available here
- throw std::runtime_error(std::string("Device specified by uuid is not available!"));
+ throw std::runtime_error(std::string("Device specified by uuid is not available"));
}
From 6395c5621fb8d83d649a174f53cfdb1626959f0e Mon Sep 17 00:00:00 2001
From: Alexandros Frantzis <alexandros.frantzis@collabora.com>
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<char const*> enabled_extensions{vulkan_wsi.vulkan_extensions()};
+ std::vector<char const*> 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<char const*,1> enabled_extensions{
- {VK_KHR_SWAPCHAIN_EXTENSION_NAME}};
+ std::vector<char const*> 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<char const*> vulkan_extensions() = 0;
+ struct Extensions
+ {
+ std::vector<char const*> instance;
+ std::vector<char const*> device;
+ };
+
+ virtual Extensions required_extensions() = 0;
virtual bool is_physical_device_supported(vk::PhysicalDevice const& pd) = 0;
virtual std::vector<uint32_t> 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<char const*> 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<char const*> vulkan_extensions() override;
+ Extensions required_extensions() override;
bool is_physical_device_supported(vk::PhysicalDevice const& pd) override;
std::vector<uint32_t> 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<char const*> vulkan_extensions() = 0;
+ virtual std::vector<char const*> 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<vk::SwapchainKHR> SwapchainWindowSystem::create_vk_swapchain()
[this] (auto& s) { vulkan->device().destroySwapchainKHR(s); }};
}
-std::vector<char const*> 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<char const*> vulkan_extensions() override;
+ Extensions required_extensions() override;
bool is_physical_device_supported(vk::PhysicalDevice const& pd) override;
std::vector<uint32_t> 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<char const*> WaylandNativeSystem::vulkan_extensions()
+std::vector<char const*> 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<char const*> vulkan_extensions() override;
+ std::vector<char const*> 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<char const*> XcbNativeSystem::vulkan_extensions()
+std::vector<char const*> 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<char const*> vulkan_extensions() override;
+ std::vector<char const*> 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<char const*> vulkan_extensions() override { return {}; }
+ Extensions required_extensions() override { return {}; }
bool is_physical_device_supported(vk::PhysicalDevice const&) override { return true; }
std::vector<uint32_t> 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<char const*> 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 <alexandros.frantzis@collabora.com>
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 <jeffy.chen@rock-chips.com>
---
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 <xf86drm.h>
#include <drm_fourcc.h>
-#include <vulkan/vulkan_intel.h>
+#include <algorithm>
#include <system_error>
#include <fcntl.h>
#include <unistd.h>
@@ -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<PFN_vkCreateDmaBufImageINTEL>(
- 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<int>{gbm_bo_get_fd(gbm_bo), close};
- auto const stride = gbm_bo_get_stride(gbm_bo);
-
- VkDmaBufImageCreateInfo create_info{};
- create_info.sType = static_cast<VkStructureType>(VK_STRUCTURE_TYPE_DMA_BUF_IMAGE_CREATE_INFO_INTEL);
- create_info.fd = fd;
- create_info.format = static_cast<VkFormat>(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<vk::Result>(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<vk::Image>{
+ 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<vk::DeviceMemory>{
+ 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>{
- 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<uint32_t> KMSWindowSystem::physical_device_queue_family_indices(