Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package vkmark for openSUSE:Factory checked in at 2021-03-05 13:47:22 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/vkmark (Old) and /work/SRC/openSUSE:Factory/.vkmark.new.2378 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "vkmark" Fri Mar 5 13:47:22 2021 rev:6 rq:876687 version:2017.08+git.20210301 Changes: -------- --- /work/SRC/openSUSE:Factory/vkmark/vkmark.changes 2020-06-11 14:54:57.827326747 +0200 +++ /work/SRC/openSUSE:Factory/.vkmark.new.2378/vkmark.changes 2021-03-05 13:49:47.679868628 +0100 @@ -1,0 +2,7 @@ +Thu Mar 4 08:14:49 UTC 2021 - Martin Pluskal <mplus...@suse.com> + +- Update to version 2017.08+git.20210301: + * doc: Document new Vulkan device related flags in man page + * core: Allow selecting the Vulkan device to run on + +------------------------------------------------------------------- Old: ---- vkmark-2017.08+git.20200521.obscpio New: ---- vkmark-2017.08+git.20210301.obscpio ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ vkmark.spec ++++++ --- /var/tmp/diff_new_pack.cj2qdo/_old 2021-03-05 13:49:48.299869191 +0100 +++ /var/tmp/diff_new_pack.cj2qdo/_new 2021-03-05 13:49:48.303869195 +0100 @@ -1,7 +1,7 @@ # # spec file for package vkmark # -# Copyright (c) 2020 SUSE LLC +# Copyright (c) 2021 SUSE LLC # Copyright (c) 2018-2019 Malcolm J Lewis <malcolmle...@opensuse.org> # # All modifications and additions to the file contributed by third parties @@ -18,7 +18,7 @@ Name: vkmark -Version: 2017.08+git.20200521 +Version: 2017.08+git.20210301 Release: 0 Summary: Vulkan benchmark utility License: LGPL-2.1-or-later ++++++ _servicedata ++++++ --- /var/tmp/diff_new_pack.cj2qdo/_old 2021-03-05 13:49:48.335869224 +0100 +++ /var/tmp/diff_new_pack.cj2qdo/_new 2021-03-05 13:49:48.335869224 +0100 @@ -1,4 +1,4 @@ <servicedata> <service name="tar_scm"> <param name="url">git://github.com/vkmark/vkmark</param> - <param name="changesrevision">e8c0720f3251e50aa8e777f44e3c2406dceb919c</param></service></servicedata> \ No newline at end of file + <param name="changesrevision">6aad03d6d55dfd3fc64c2d78585c981898f9dac4</param></service></servicedata> \ No newline at end of file ++++++ vkmark-2017.08+git.20200521.obscpio -> vkmark-2017.08+git.20210301.obscpio ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vkmark-2017.08+git.20200521/doc/vkmark.1 new/vkmark-2017.08+git.20210301/doc/vkmark.1 --- old/vkmark-2017.08+git.20200521/doc/vkmark.1 2020-05-21 12:17:11.000000000 +0200 +++ new/vkmark-2017.08+git.20210301/doc/vkmark.1 2021-03-01 11:45:55.000000000 +0100 @@ -53,6 +53,12 @@ \fB\-d\fR, \fB\-\-debug\fR Display debug messages .TP +\fB\-D\fR, \fB\-\-use-device\fR +Use Vulkan device with specified UUID +.TP +\fB\-L\fR, \fB\-\-list-devices\fR +List Vulkan devices +.TP \fB\-h\fR, \fB\-\-help\fR Display help .SH BENCHMARKS diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vkmark-2017.08+git.20200521/src/device_uuid.cpp new/vkmark-2017.08+git.20210301/src/device_uuid.cpp --- old/vkmark-2017.08+git.20200521/src/device_uuid.cpp 1970-01-01 01:00:00.000000000 +0100 +++ new/vkmark-2017.08+git.20210301/src/device_uuid.cpp 2021-03-01 11:45:55.000000000 +0100 @@ -0,0 +1,79 @@ +/* + * Copyright ?? 2021 vkmark developers + * + * This file is part of vkmark. + * + * vkmark is free software: you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, either + * version 2.1 of the License, or (at your option) any later version. + * + * vkmark is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with vkmark. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "device_uuid.h" +#include <stdexcept> + +static std::array<char, 2 * VK_UUID_SIZE> decode_UUID(const std::array<uint8_t, VK_UUID_SIZE>& bytes) +{ + std::array<char, 2 * VK_UUID_SIZE> representation{}; + constexpr char characters[16] = + { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' }; + + for (std::size_t i = 0; i < bytes.size(); ++i) + { + auto& byte = bytes[i]; + + representation[2 * i] = characters[byte / 16]; + representation[2 * i + 1] = characters[byte % 16]; + } + + return representation; +} + +static std::array<uint8_t, VK_UUID_SIZE> encode_UUID(const std::array<char, 2 * VK_UUID_SIZE>& representation) +{ + std::array<uint8_t, VK_UUID_SIZE> bytes{}; + + auto&& decode_character = [](const char ch) { + if (ch >= '0' && ch <= '9') + return ch - '0'; + else if (ch >= 'a' && ch <= 'f') + return ch - 'a' + 10; + throw std::invalid_argument( + std::string{ch} + "character found while parsing hexadecimal string!"); + }; + + for (std::size_t i = 0; i < bytes.size(); ++i) + { + bytes[i] = decode_character(representation[2 * i]) * 16 + + decode_character(representation[2 * i + 1]); + } + + return bytes; +} + +DeviceUUID::DeviceUUID(std::string const& representation) +{ + std::array<char, 2 * VK_UUID_SIZE> chars{}; + if (representation.size() != chars.size()) + throw std::invalid_argument("given UUID representation has wrong size!"); + + std::copy(representation.begin(), representation.end(), chars.begin()); + raw = encode_UUID(chars); +} + +std::array<char, 2 * VK_UUID_SIZE + 1> DeviceUUID::representation() const +{ + std::array<char, 2 * VK_UUID_SIZE + 1> c_str{}; + auto&& chars = decode_UUID(raw); + std::copy(chars.begin(), chars.end(), c_str.begin()); + + return c_str; +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vkmark-2017.08+git.20200521/src/device_uuid.h new/vkmark-2017.08+git.20210301/src/device_uuid.h --- old/vkmark-2017.08+git.20200521/src/device_uuid.h 1970-01-01 01:00:00.000000000 +0100 +++ new/vkmark-2017.08+git.20210301/src/device_uuid.h 2021-03-01 11:45:55.000000000 +0100 @@ -0,0 +1,54 @@ +/* + * Copyright ?? 2021 vkmark developers + * + * This file is part of vkmark. + * + * vkmark is free software: you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, either + * version 2.1 of the License, or (at your option) any later version. + * + * vkmark is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with vkmark. If not, see <http://www.gnu.org/licenses/>. + */ + +#pragma once + +#include <array> +#include <cstdint> +#include <string> +#include <vulkan/vulkan.hpp> + +struct DeviceUUID +{ + std::array<uint8_t, VK_UUID_SIZE> raw{}; + + DeviceUUID() = default; + DeviceUUID(std::array<uint8_t, VK_UUID_SIZE> const& bytes) + : raw(bytes) + {} + + DeviceUUID(std::string const& representation); + + DeviceUUID(const uint8_t bytes[]) // TODO: only used for githubs CI. delete when not needed anymore + { + std::copy(bytes, bytes + VK_UUID_SIZE, raw.data()); + } + + operator std::array<uint8_t, VK_UUID_SIZE> () const + { + return raw; + } + + bool operator==(const DeviceUUID& other) const + { + return raw == other.raw; + } + + std::array<char, 2 * VK_UUID_SIZE + 1> representation() const; +}; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vkmark-2017.08+git.20200521/src/main.cpp new/vkmark-2017.08+git.20210301/src/main.cpp --- old/vkmark-2017.08+git.20200521/src/main.cpp 2020-05-21 12:17:11.000000000 +0200 +++ new/vkmark-2017.08+git.20210301/src/main.cpp 2021-03-01 11:45:55.000000000 +0100 @@ -23,6 +23,7 @@ #include "window_system.h" #include "window_system_loader.h" #include "vulkan_state.h" +#include "device_uuid.h" #include "scene.h" #include "scene_collection.h" #include "benchmark_collection.h" @@ -114,7 +115,17 @@ } auto& ws = ws_loader.load_window_system(); - VulkanState vulkan{ws.vulkan_wsi()}; + + auto&& device_strategy = options.use_device_with_uuid.second ? + VulkanState::ChoosePhysicalDeviceStrategy{ChooseByUUIDStrategy{options.use_device_with_uuid.first}} : + VulkanState::ChoosePhysicalDeviceStrategy{ChooseFirstSupportedStrategy{}}; + VulkanState vulkan{ws.vulkan_wsi(), device_strategy}; + + if (options.list_devices) + { + vulkan.log_all_devices(); + return 0; + } auto const ws_vulkan_deinit = Util::on_scope_exit([&] { ws.deinit_vulkan(); }); ws.init_vulkan(vulkan); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vkmark-2017.08+git.20200521/src/meson.build new/vkmark-2017.08+git.20210301/src/meson.build --- old/vkmark-2017.08+git.20200521/src/meson.build 2020-05-21 12:17:11.000000000 +0200 +++ new/vkmark-2017.08+git.20210301/src/meson.build 2021-03-01 11:45:55.000000000 +0100 @@ -17,6 +17,7 @@ 'benchmark.cpp', 'benchmark_collection.cpp', 'default_benchmarks.cpp', + 'device_uuid.cpp', 'log.cpp', 'main_loop.cpp', 'mesh.cpp', diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vkmark-2017.08+git.20200521/src/options.cpp new/vkmark-2017.08+git.20210301/src/options.cpp --- old/vkmark-2017.08+git.20200521/src/options.cpp 2020-05-21 12:17:11.000000000 +0200 +++ new/vkmark-2017.08+git.20210301/src/options.cpp 2021-03-01 11:45:55.000000000 +0100 @@ -24,6 +24,8 @@ #include <getopt.h> #include <algorithm> #include <cctype> +#include <string> +#include <utility> #include "options.h" #include "util.h" @@ -36,6 +38,7 @@ struct option long_options[] = { {"benchmark", 1, 0, 0}, {"size", 1, 0, 0}, + {"use-device", 1, 0, 0}, {"fullscreen", 0, 0, 0}, {"present-mode", 1, 0, 0}, {"pixel-format", 1, 0, 0}, @@ -45,6 +48,7 @@ {"data-dir", 1, 0, 0}, {"winsys", 1, 0, 0}, {"winsys-options", 1, 0, 0}, + {"list-devices", 0, 0, 0}, {"run-forever", 0, 0, 0}, {"debug", 0, 0, 0}, {"help", 0, 0, 0}, @@ -133,7 +137,9 @@ data_dir{VKMARK_DATA_DIR}, run_forever{false}, show_debug{false}, - show_help{false} + show_help{false}, + list_devices{false}, + use_device_with_uuid{} { } @@ -162,6 +168,8 @@ " --run-forever Run indefinitely, looping from the last benchmark\n" " back to the first\n" " -d, --debug Display debug messages\n" + " -D --use-device Use Vulkan device with specified UUID\n" + " -L --list-devices List Vulkan devices\n" " -h, --help Display help\n"; for (auto const& wsh : window_system_help) @@ -181,7 +189,7 @@ int c; std::string optname; - c = getopt_long(argc, argv, "b:s:p:ldh", + c = getopt_long(argc, argv, "b:s:p:ldhD:L", long_options, &option_index); if (c == -1) break; @@ -219,6 +227,10 @@ show_debug = true; else if (c == 'h' || optname == "help") show_help = true; + else if (c == 'L' || optname == "list-devices") + list_devices = true; + else if (c == 'D' || optname == "use-device") + use_device_with_uuid = std::make_pair(DeviceUUID{std::string {optarg}}, true); } return true; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vkmark-2017.08+git.20200521/src/options.h new/vkmark-2017.08+git.20210301/src/options.h --- old/vkmark-2017.08+git.20200521/src/options.h 2020-05-21 12:17:11.000000000 +0200 +++ new/vkmark-2017.08+git.20210301/src/options.h 2021-03-01 11:45:55.000000000 +0100 @@ -28,6 +28,8 @@ #include <vulkan/vulkan.hpp> +#include "device_uuid.h" + struct Options { struct WindowSystemOption @@ -55,6 +57,8 @@ bool run_forever; bool show_debug; bool show_help; + bool list_devices; + std::pair<DeviceUUID, bool> use_device_with_uuid; // pseudo-optional private: std::vector<std::string> window_system_help; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vkmark-2017.08+git.20200521/src/vulkan_state.cpp new/vkmark-2017.08+git.20210301/src/vulkan_state.cpp --- old/vkmark-2017.08+git.20200521/src/vulkan_state.cpp 2020-05-21 12:17:11.000000000 +0200 +++ new/vkmark-2017.08+git.20210301/src/vulkan_state.cpp 2021-03-01 11:45:55.000000000 +0100 @@ -21,29 +21,65 @@ */ #include "vulkan_state.h" -#include "vulkan_wsi.h" - +#include "device_uuid.h" #include "log.h" +#include <array> #include <vector> -#include <algorithm> +#include <vulkan/vulkan.hpp> + -VulkanState::VulkanState(VulkanWSI& vulkan_wsi) +VulkanState::VulkanState(VulkanWSI& vulkan_wsi, ChoosePhysicalDeviceStrategy const& pd_strategy) { create_instance(vulkan_wsi); - choose_physical_device(vulkan_wsi); - create_device(vulkan_wsi); + create_physical_device(vulkan_wsi, pd_strategy); + create_logical_device(vulkan_wsi); create_command_pool(); } -void VulkanState::log_info() +std::vector<vk::PhysicalDevice> VulkanState::available_devices(VulkanWSI& vulkan_wsi) const +{ + auto available_devices = instance().enumeratePhysicalDevices(); + for (auto it_device = available_devices.begin(); it_device != available_devices.end();) + { + if (!vulkan_wsi.is_physical_device_supported(*it_device)) + { + Log::debug("device with uuid %s is not supported by window system integration layer", + static_cast<DeviceUUID>(it_device->getProperties().pipelineCacheUUID).representation().data()); + it_device = available_devices.erase(it_device); + } + else + ++it_device; + } + + return available_devices; +} + +static void log_device_info(vk::PhysicalDevice const& device) { - auto const props = physical_device().getProperties(); + auto const props = device.getProperties(); Log::info(" Vendor ID: 0x%X\n", props.vendorID); Log::info(" Device ID: 0x%X\n", props.deviceID); Log::info(" Device Name: %s\n", static_cast<char const*>(props.deviceName)); Log::info(" Driver Version: %u\n", props.driverVersion); + Log::info(" Device UUID: %s\n", static_cast<DeviceUUID>(props.pipelineCacheUUID).representation().data()); +} + +void VulkanState::log_info() const +{ + log_device_info(physical_device()); +} + +void VulkanState::log_all_devices() const +{ + std::vector<vk::PhysicalDevice> const& physical_devices = instance().enumeratePhysicalDevices(); + + for (size_t i = 0; i < physical_devices.size(); ++i) + { + Log::info("=== Physical Device %d ===\n", i); + log_device_info(physical_devices[i]); + } } void VulkanState::create_instance(VulkanWSI& vulkan_wsi) @@ -64,40 +100,34 @@ [] (auto& i) { i.destroy(); }}; } -void VulkanState::choose_physical_device(VulkanWSI& vulkan_wsi) +void VulkanState::create_physical_device(VulkanWSI& vulkan_wsi, ChoosePhysicalDeviceStrategy const& pd_strategy) { - auto const physical_devices = instance().enumeratePhysicalDevices(); - - for (auto const& pd : physical_devices) - { - if (!vulkan_wsi.is_physical_device_supported(pd)) - continue; + vk_physical_device = pd_strategy(available_devices(vulkan_wsi)); +} - auto const queue_families = pd.getQueueFamilyProperties(); - int queue_index = 0; - for (auto const& queue_family : queue_families) - { - if (queue_family.queueCount > 0 && - (queue_family.queueFlags & vk::QueueFlagBits::eGraphics)) - { - vk_physical_device = pd; - vk_graphics_queue_family_index = queue_index; - - break; - } - ++queue_index; - } +// pseudo-optional +static std::pair<uint32_t, bool> find_queue_family_index(vk::PhysicalDevice pd, vk::QueueFlagBits queue_family_type) +{ + auto const queue_families = pd.getQueueFamilyProperties(); - if (vk_physical_device) - break; + for (uint32_t queue_index = 0; queue_index < queue_families.size(); ++queue_index) + { + // each queue family must support at least one queue + if (queue_families[queue_index].queueFlags & queue_family_type) + return std::make_pair(queue_index, true); } - if (!vk_physical_device) - throw std::runtime_error("No suitable Vulkan physical devices found"); + return std::make_pair(0, false); } -void VulkanState::create_device(VulkanWSI& vulkan_wsi) +void VulkanState::create_logical_device(VulkanWSI& vulkan_wsi) { + // it would be really nice to support c++17 + auto pair = find_queue_family_index(physical_device(), vk::QueueFlagBits::eGraphics); + if (!pair.second) + throw std::runtime_error("selected physical device does not provide graphics queue"); + vk_graphics_queue_family_index = pair.first; + auto const priority = 1.0f; auto queue_family_indices = @@ -159,3 +189,43 @@ device().createCommandPool(command_pool_create_info), [this] (auto& cp) { this->device().destroyCommandPool(cp); }}; } + + +vk::PhysicalDevice ChooseFirstSupportedStrategy::operator()(const std::vector<vk::PhysicalDevice>& available_devices) +{ + 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"); + return physical_device; + } + + Log::debug("device with uuid %s skipped!\n", + static_cast<DeviceUUID>(physical_device.getProperties().pipelineCacheUUID).representation().data() + ); + } + + throw std::runtime_error("No suitable Vulkan physical devices found"); +} + +vk::PhysicalDevice ChooseByUUIDStrategy::operator()(const std::vector<vk::PhysicalDevice>& available_devices) +{ + Log::debug("Trying to use device with specified UUID %s.\n", + m_selected_device_uuid.representation().data()); + + for (auto const& physical_device: available_devices) + { + auto&& uuid = static_cast<DeviceUUID>(physical_device.getProperties().pipelineCacheUUID); + if (uuid == m_selected_device_uuid) + { + Log::debug("Device found by UUID\n"); + return physical_device; + } + } + + // 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!")); +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vkmark-2017.08+git.20200521/src/vulkan_state.h new/vkmark-2017.08+git.20210301/src/vulkan_state.h --- old/vkmark-2017.08+git.20200521/src/vulkan_state.h 2020-05-21 12:17:11.000000000 +0200 +++ new/vkmark-2017.08+git.20210301/src/vulkan_state.h 2021-03-01 11:45:55.000000000 +0100 @@ -22,18 +22,21 @@ #pragma once +#include <functional> #include <vulkan/vulkan.hpp> #include "managed_resource.h" +#include "vulkan_wsi.h" +#include "device_uuid.h" -class VulkanWSI; class VulkanState { public: - VulkanState(VulkanWSI& vulkan_wsi); + using ChoosePhysicalDeviceStrategy = + std::function<vk::PhysicalDevice (std::vector<vk::PhysicalDevice> const&)>; - void log_info(); + VulkanState(VulkanWSI& vulkan_wsi, ChoosePhysicalDeviceStrategy const& pd_strategy); vk::Instance const& instance() const { @@ -65,16 +68,40 @@ return vk_command_pool; } + void log_info() const; + void log_all_devices() const; + private: + void create_instance(VulkanWSI& vulkan_wsi); - void choose_physical_device(VulkanWSI& vulkan_wsi); - void create_device(VulkanWSI& vulkan_wsi); + void create_physical_device(VulkanWSI& vulkan_wsi, ChoosePhysicalDeviceStrategy const& pd_strategy); + void create_logical_device(VulkanWSI& vulkan_wsi); void create_command_pool(); + std::vector<vk::PhysicalDevice> available_devices(VulkanWSI& vulkan_wsi) const; ManagedResource<vk::Instance> vk_instance; - vk::PhysicalDevice vk_physical_device; - uint32_t vk_graphics_queue_family_index; ManagedResource<vk::Device> vk_device; - vk::Queue vk_graphics_queue; ManagedResource<vk::CommandPool> vk_command_pool; + vk::Queue vk_graphics_queue; + vk::PhysicalDevice vk_physical_device; + uint32_t vk_graphics_queue_family_index; +}; + +class ChooseFirstSupportedStrategy +{ +public: + vk::PhysicalDevice operator()(const std::vector<vk::PhysicalDevice>& available_devices); +}; + +class ChooseByUUIDStrategy +{ +public: + ChooseByUUIDStrategy(const DeviceUUID& uuid) + : m_selected_device_uuid(uuid) + {} + + vk::PhysicalDevice operator()(const std::vector<vk::PhysicalDevice>& available_devices); + +private: + DeviceUUID m_selected_device_uuid; }; ++++++ vkmark.obsinfo ++++++ --- /var/tmp/diff_new_pack.cj2qdo/_old 2021-03-05 13:49:48.499869373 +0100 +++ /var/tmp/diff_new_pack.cj2qdo/_new 2021-03-05 13:49:48.499869373 +0100 @@ -1,5 +1,5 @@ name: vkmark -version: 2017.08+git.20200521 -mtime: 1590056231 -commit: e8c0720f3251e50aa8e777f44e3c2406dceb919c +version: 2017.08+git.20210301 +mtime: 1614595555 +commit: 6aad03d6d55dfd3fc64c2d78585c981898f9dac4