From 85f5cf3f66daebe93112e9b370062553170ccedf Mon Sep 17 00:00:00 2001 From: Jens Peters Date: Wed, 15 May 2024 21:23:26 +0200 Subject: [PATCH 1/2] sysinfo: Replace deprecated Vulkan macros Unfortunately we cannot just use the newer Vulkan macros since the major version for the NVIDIA driver needs 10 bits whereas the newer Vulkan macro for the major version returns only 7 bits. --- src/sysinfo/nvapi_adapter.cpp | 17 +++++++---------- src/util/util_version.h | 29 +++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 10 deletions(-) create mode 100644 src/util/util_version.h diff --git a/src/sysinfo/nvapi_adapter.cpp b/src/sysinfo/nvapi_adapter.cpp index 29d9ff06..922e23f9 100644 --- a/src/sysinfo/nvapi_adapter.cpp +++ b/src/sysinfo/nvapi_adapter.cpp @@ -3,6 +3,7 @@ #include "../util/util_string.h" #include "../util/util_env.h" #include "../util/util_log.h" +#include "../util/util_version.h" namespace dxvk { NvapiAdapter::NvapiAdapter(Vulkan& vulkan, Nvml& nvml) @@ -88,21 +89,17 @@ namespace dxvk { return false; // DXVK NVAPI-hack is enabled, skip this adapter if (HasNvProprietaryDriver()) - // Handle NVIDIA version notation - m_vkDriverVersion = VK_MAKE_VERSION( - VK_VERSION_MAJOR(m_vkProperties.driverVersion), - VK_VERSION_MINOR(m_vkProperties.driverVersion >> 0) >> 2, - VK_VERSION_PATCH(m_vkProperties.driverVersion >> 2) >> 4); + m_vkDriverVersion = m_vkProperties.driverVersion; else // Reporting e.g. Mesa driver versions turned out to be not very useful // since those will usually always fail driver version checks, // so just report a number that should be "useful" until the end of time - m_vkDriverVersion = VK_MAKE_VERSION(999, 99, 0); + m_vkDriverVersion = nvMakeVersion(999, 99, 0); log::write(str::format("NvAPI Device: ", m_vkProperties.deviceName, " (", - VK_VERSION_MAJOR(m_vkDriverVersion), ".", - VK_VERSION_MINOR(m_vkDriverVersion), ".", - VK_VERSION_PATCH(m_vkDriverVersion), ")")); + nvVersionMajor(m_vkDriverVersion), ".", + nvVersionMinor(m_vkDriverVersion), ".", + nvVersionPatch(m_vkDriverVersion), ")")); // Query all outputs from DXVK // Mosaic setup is not supported, thus one display output refers to one GPU @@ -154,7 +151,7 @@ namespace dxvk { // and does not have a patch number return m_driverVersionOverride > 0 ? m_driverVersionOverride - : VK_VERSION_MAJOR(m_vkDriverVersion) * 100 + std::min(VK_VERSION_MINOR(m_vkDriverVersion), 99U); + : nvVersionMajor(m_vkDriverVersion) * 100 + std::min((nvVersionMinor(m_vkDriverVersion)), 99U); } bool NvapiAdapter::HasNvProprietaryDriver() const { diff --git a/src/util/util_version.h b/src/util/util_version.h new file mode 100644 index 00000000..d62563d5 --- /dev/null +++ b/src/util/util_version.h @@ -0,0 +1,29 @@ +#pragma once + +#include "../nvapi_private.h" + +namespace dxvk { + + // The Vulkan version number packing used by NVIDIA is slightly different + // from the packing specified in the Vulkan specifications: + // - The major version is a 10-bit integer packed into bits 31-22 + // - The minor version is an 8-bit integer packed into bits 21-14 + // - The patch version is an 8-bit integer packed into bits 13-6 + // See https://registry.khronos.org/vulkan/specs/1.3/html/vkspec.html#extendingvulkan-coreversions-versionnumbers + + inline uint32_t nvMakeVersion(const uint32_t major, const uint32_t minor, const uint32_t patch) { + return (major << 22U) | (minor << 14U) | (patch << 6U); + } + + inline uint32_t nvVersionMajor(const uint32_t version) { + return (version >> 22U) & 0x3FFU; + } + + inline uint32_t nvVersionMinor(const uint32_t version) { + return (version >> 14U) & 0x0FFU; + } + + inline uint32_t nvVersionPatch(const uint32_t version) { + return (version >> 6U) & 0x0FFU; + } +} From aae4902b6ff7038fd1bd34d33f019397018f195c Mon Sep 17 00:00:00 2001 From: Jens Peters Date: Fri, 17 May 2024 16:14:57 +0200 Subject: [PATCH 2/2] tests: Add a few util tests --- tests/main.cpp | 4 ++-- tests/meson.build | 1 + tests/util.cpp | 45 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 48 insertions(+), 2 deletions(-) create mode 100644 tests/util.cpp diff --git a/tests/main.cpp b/tests/main.cpp index 4d43357c..103ad121 100644 --- a/tests/main.cpp +++ b/tests/main.cpp @@ -2,8 +2,8 @@ #include "../inc/catch_amalgamated.hpp" #include "section_listener.h" -CATCH_REGISTER_TAG_ALIAS("[@unit-tests]", "[d3d],[d3d11],[d3d12],[drs],[sysinfo],[sysinfo-topo],[sysinfo-nvml],[sysinfo-hdr]") +CATCH_REGISTER_TAG_ALIAS("[@unit-tests]", "[d3d],[d3d11],[d3d12],[drs],[sysinfo],[sysinfo-topo],[sysinfo-nvml],[sysinfo-hdr],[util]") CATCH_REGISTER_TAG_ALIAS("[@system]", "[system]") -CATCH_REGISTER_TAG_ALIAS("[@all]", "[d3d],[d3d11],[d3d12],[drs],[sysinfo],[sysinfo-topo],[sysinfo-nvml],[sysinfo-hdr],[system]") +CATCH_REGISTER_TAG_ALIAS("[@all]", "[d3d],[d3d11],[d3d12],[drs],[sysinfo],[sysinfo-topo],[sysinfo-nvml],[sysinfo-hdr],[util],[system]") CATCH_REGISTER_LISTENER(SectionListener) diff --git a/tests/meson.build b/tests/meson.build index f020c0f4..12f410c7 100644 --- a/tests/meson.build +++ b/tests/meson.build @@ -39,6 +39,7 @@ nvapi_tests_src = files([ 'nvapi_sysinfo_nvml.cpp', 'nvapi_sysinfo_hdr.cpp', 'nvapi_system.cpp', + 'util.cpp', ]) nvapi_exe = executable('nvapi'+target_suffix+'-tests', [ nvapi_src, catch2_src, nvapi_tests_src, dxvk_nvapi_version ], diff --git a/tests/util.cpp b/tests/util.cpp new file mode 100644 index 00000000..ced375e8 --- /dev/null +++ b/tests/util.cpp @@ -0,0 +1,45 @@ +#include "nvapi_tests_private.h" +#include "../src/util/util_string.h" +#include "../src/util/util_version.h" + +using namespace Catch::Matchers; + +TEST_CASE("String", "[.util]") { + SECTION("NVAPI Unicode-String") { + NvAPI_UnicodeString us = {'U', 'n', 'i', 'c', 'o', 'd', 'e'}; + REQUIRE(dxvk::str::fromnvus(us) == std::string("Unicode")); + } + + SECTION("NVAPI Short-String") { + NvAPI_ShortString ss{}; + + dxvk::str::tonvss(ss, std::string("Short-String")); + REQUIRE_THAT(ss, Equals("Short-String")); + + dxvk::str::tonvss(ss, std::string("Longer-Than-Short-String-Longer-Than-Short-String-Longer-Than-Short-String")); + REQUIRE_THAT(ss, SizeIs(64)); + } +} + +TEST_CASE("Version", "[.util]") { + SECTION("Vulkan version packing") { + struct Data { + uint32_t driverVersion; + uint32_t major; + uint32_t minor; + uint32_t patch; + }; + auto args = GENERATE( + Data{0x0, 0x0, 0x0, 0x0}, + Data{0xffffffff, 0x3ff, 0xff, 0xff}, + Data{0x85eac100, 535, 171, 04}); + + REQUIRE(dxvk::nvVersionMajor(args.driverVersion) == args.major); + REQUIRE(dxvk::nvVersionMinor(args.driverVersion) == args.minor); + REQUIRE(dxvk::nvVersionPatch(args.driverVersion) == args.patch); + } + + SECTION("Make Vulkan version") { + REQUIRE(dxvk::nvMakeVersion(0xffff, 0xffff, 0xffff) == 0xffffffc0); + } +}