- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
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_DEFINES
在 vulkan_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 theVK_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 文档是错误的,所以我认为我一定遗漏了一些非常明显的东西。我怀疑答案是:
但我真的不知道如何证实我的猜想。
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;
}
系统:
14.34
(希望他们的编号正确)1.3.216.0
。最佳答案
好吧,再多做一点研究就可以让我把事情弄清楚。
TL;DR:它不应该像那样使用(所以我的想法部分是对的,耶!)。覆盖 VK_USE_64_BIT_PTR_DEFINES
使您无法使用您正在链接的库的“原始”定义,这就是我在帖子中担心的原因。相反,您首先创建一个 VkInstance
,然后 使用 vkGetInstanceProcAddr
获取函数指针(分别使用 VkDevice
和 vkGetDeviceProcAddr
用于设备功能)。获取相关函数指针所需的所有函数都可以从库中访问。
覆盖 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/
我是一名优秀的程序员,十分优秀!