我目前正在学习Vulkan。在学习几个教程时,重复出现大致相同的代码:
VkInstance g_instance;
void SetupVulkan(){
VkApplicationInfo appInfo = {};
//Set appInfo attributes
VkInstanceCreateInfo instanceInfo = {};
instanceInfo.pApplicationInfo = &appInfo;
//Set ICI attributes
VkResult result = vkCreateInstance(&instanceInfo, NULL, &g_instance);
//Error handling
}
这会在堆栈上创建VkApplicationInfo
和VkInstanceCreateInfo
。离开功能并使用g_instance
时,这是否会导致一些问题? vkCreateInstance
是否正在复制VkApplicationInfo
和VkInstanceCreateInfo
的所有数据?如果是这样,那么为什么官方手册没有告诉我这种行为? https://www.khronos.org/registry/vulkan/specs/1.0/man/html/vkCreateInstance.html
整个API都重复相同的模式。我怎样才能知道堆栈上的分配在哪些情况下是正常的,在哪些情况下应该更喜欢像堆或全局内存那样的更持久的方式?
答案 0 :(得分:7)
重要的是要记住哪些对象代表您向Vulkan提供数据,哪些对象代表Vulkan对象或Vulkan向您提供数据。
VkInstance
是一个Vulkan句柄。这意味着它实际上是一个指针或64位整数或某些。您将它用作指向对象的指针,而不是像对象本身。所以它在功能上与此无异:
Type *p
auto error_code = getPtr(&p);
return p;
Vulkan创建的所有对象(即:vkCreate
或vkAllocate
调用的结果)都是句柄。它们都像指针/引用一样,所以你可以自由地传递它们而不用担心。
实际的Vulkan结构(如各种Info
对象)用于输入Vulkan或输出Vulkan。但不管怎样,Vulkan只会在函数调用期间使用它们。那么你之后用它们做什么完全取决于你。
甚至像VkPhysicalDeviceFeatures
这样的输出数据结构仍然只是C ++结构。并且您以C ++允许的任何方式使用它们。其中的数据没有额外的引用或指向Vulkan拥有的内存;他们只是一堆价值观。
如果您使用VkAllocationCallbacks
,则必须小心谨慎。该实现将在内部存储存储在此结构中的指针。因此,在销毁关联对象之前,它们必须保持有效。但结构本身不会存储超出您提供的Vulkan调用的持续时间。
如果是这样,为什么官方手册没有告诉我这种行为?
确实如第2.3.1节所述。这适用于Vulkan规范中的每个函数,因此不会在每个函数中单独列出:
应用程序拥有的内存会立即被传入的任何Vulkan命令使用。一旦消耗它的命令返回,应用程序就可以更改或释放此内存。