gpt4 book ai didi

c++ - 覆盖 VK_USE_64_BIT_PTR_DEFINES

转载 作者:行者123 更新时间:2023-12-05 04:19:30 31 4
gpt4 key购买 nike

Vulkan 句柄是指向 struct 的不透明指针,或者只是无符号的 64 位整数,具体取决于 VK_USE_64_BIT_PTR_DEFINES 的值:

    #if (VK_USE_64_BIT_PTR_DEFINES==1)
#define VK_DEFINE_NON_DISPATCHABLE_HANDLE(object) typedef struct object##_T *object;
#else
#define VK_DEFINE_NON_DISPATCHABLE_HANDLE(object) typedef uint64_t object;
#endif

VK_USE_64_BIT_PTR_DEFINESvulkan_core.h 中尚未define时设置为以下值,具体取决于平台(至少在我的标题版本):

#ifndef VK_USE_64_BIT_PTR_DEFINES
#if defined(__LP64__) || defined(_WIN64) || (defined(__x86_64__) && !defined(__ILP32__) ) || defined(_M_X64) || defined(__ia64) || defined (_M_IA64) || defined(__aarch64__) || defined(__powerpc64__)
#define VK_USE_64_BIT_PTR_DEFINES 1
#else
#define VK_USE_64_BIT_PTR_DEFINES 0
#endif
#endif

documentation for that preprocessor #define陈述如下:

The vulkan_core.h header allows the VK_USE_64_BIT_PTR_DEFINES definition to be overridden by the application. This allows the application to select either a 64-bit pointer type or a 64-bit unsigned integer type for non-dispatchable handles in the case where the predefined preprocessor check does not identify the desired configuration.

我将此声明解释为:

It's okay to force VK_USE_64_BIT_PTR_DEFINES's value at build time so that I can use either of the definitions.

但是,据我所知,更改 header 端的定义仅...对编译为 .dll/.so 的共享库的影响,显然包括 LunarG's Vulkan SDK 的那些我正在使用(我们不仅改变了类型,我们还改变了函数签名)。

在 Linux 或带有 MinGW 的 Windows 上,VK_USE_64_BIT_PTR_DEFINES 默认为 1。在使用 MSVC 的 Windows 上,它默认为 0。所以我尝试将其更改为 1,正如预期的那样,它会生成以下链接器错误(MRE 用于下面的测试)。

main.cpp.obj : error LNK2019: unresolved external symbol _vkCmdBindIndexBuffer@20 referenced in function "void __cdecl foo(void)" (?foo@@YAXXZ)vk_test.exe : fatal error LNK1120: 1 unresolved externals

编辑 - 评论后澄清:vulkan_core.h 中的所有内容都是 extern "C"{}


我非常、非常怀疑 Vulkan 文档是错误的,所以我认为我一定遗漏了一些非常明显的东西。我怀疑答案是:

  • “只是您在覆盖该值后没有链接到正确的目标”
  • “您误解了文档所说的内容。这里的‘应用程序’并不是指您认为它所做的事情”

但我真的不知道如何证实我的猜想。


MRE:

CMakeLists.txt

cmake_minimum_required(VERSION 3.23)

project(vk_test LANGUAGES CXX)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

find_package(Vulkan REQUIRED)

add_executable(vk_test main.cpp)

# No effect for GCC / MinGW
# On MSVC on the other hand, the value is set to 0 when not defined by user
# Comment that line to build with MSVC
add_compile_definitions(VK_USE_64_BIT_PTR_DEFINES=1)

target_link_libraries(vk_test PUBLIC ${Vulkan_LIBRARY})
target_include_directories(vk_test SYSTEM PUBLIC ${Vulkan_INCLUDE_DIRS})

main.cpp:

#include <cassert>

#include <vulkan/vulkan_core.h>

void foo()
{
assert(false); // The following call has invalid parameters, so no point letting execution reach that point
vkCmdBindIndexBuffer(VK_NULL_HANDLE, VK_NULL_HANDLE, 0, VkIndexType{});
}

int main()
{
return 0;
}

系统:

  • Windows 10。
  • MSVC:版本。 19 ~ 14.34(希望他们的编号正确)
  • Vulkan SDK 版本。 1.3.216.0

最佳答案

好吧,再多做一点研究就可以让我把事情弄清楚。

TL;DR:它不应该像那样使用(所以我的想法部分是对的,耶!)。覆盖 VK_USE_64_BIT_PTR_DEFINES 使您无法使用您正在链接的库的“原始”定义,这就是我在帖子中担心的原因。相反,您首先创建一个 VkInstance,然后 使用 vkGetInstanceProcAddr 获取函数指针(分别使用 VkDevicevkGetDeviceProcAddr 用于设备功能)。获取相关函数指针所需的所有函数都可以从库中访问。


覆盖 VK_USE_64_BIT_PTR_DEFINES 时期望您做什么的简单演示

cmake_minimum_required(VERSION 3.23)

project(vk_test LANGUAGES CXX)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

find_package(Vulkan REQUIRED)

add_executable(vk_test main.cpp)

# No effect for GCC / MinGW
# On MSVC on the other hand, the value is set to 0 when not defined by user
add_compile_definitions(VK_USE_64_BIT_PTR_DEFINES=1)

target_link_libraries(vk_test PUBLIC ${Vulkan_LIBRARY})
target_include_directories(vk_test SYSTEM PUBLIC ${Vulkan_INCLUDE_DIRS})
#include <iostream>

#include <vulkan/vulkan_core.h>

void foo()
{
const VkInstanceCreateInfo instance_info
{
/*.sType = */VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,
/*.pNext = */nullptr,
/*.flags = */0,
/*.pApplicationInfo = */nullptr,
/*.enabledLayerCount = */0,
/*.ppEnabledLayerNames = */nullptr,
/*.enabledExtensionCount = */0,
/*.ppEnabledExtensionNames = */nullptr
};

VkInstance instance = VK_NULL_HANDLE;

if(vkCreateInstance(&instance_info, nullptr, &instance) != VK_SUCCESS)
{
std::cout << ":(" << std::endl;
return;
}

const auto f = reinterpret_cast<PFN_vkCmdBindIndexBuffer>(vkGetInstanceProcAddr(instance, "vkCmdBindIndexBuffer"));
std::cout << (f != nullptr) << std::endl; // Prints '1' (hopefully for you too)

vkDestroyInstance(instance, nullptr);
}

int main()
{
foo();

return 0;
}

避免自己编写此类代码的替代方法/工具

  • vulkan.hpp 中生成了所有必需调用的列表,希望它可以比手工编写更轻松地集成到您的应用程序中。

  • Vulkan-Loader (VOLK)是 Khronos 为该目的开发的库。它还有一个 list可以以纯文本形式存储的方式加载的符号,也可以用于生成适当的代码。

关于c++ - 覆盖 VK_USE_64_BIT_PTR_DEFINES,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74791051/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com