odin 编程语言:vulkan.CreateDevice() 在执行时导致程序崩溃

问题描述 投票:0回答:1

我将 vulkan 与 odin 编程语言结合使用。我的程序在尝试调用过程 vulkan.CreateDevice() 后崩溃(仅供参考,过程只是 odin 中的函数)。 我创建设备的代码如下所示:

bonbug.actionStart("Creating Device");
    vulkan.load_proc_addresses(get_proc_address);
    queuePriority : f32 = 1.0;
    dQCreateInfo : []vulkan.DeviceQueueCreateInfo = {{
        sType = .DEVICE_QUEUE_CREATE_INFO,
        queueFamilyIndex = deviceIndex,
        queueCount = 1,
        pQueuePriorities = &queuePriority,
    }};
    deviceFeatures : vulkan.PhysicalDeviceFeatures;
    dCreateInfo : vulkan.DeviceCreateInfo = {
        sType = .DEVICE_CREATE_INFO,
        pQueueCreateInfos = raw_data(dQCreateInfo),
        queueCreateInfoCount = cast(u32)len(dQCreateInfo),
        pEnabledFeatures = &deviceFeatures,
        enabledExtensionCount = 0,
        enabledLayerCount = layerCount,
        ppEnabledLayerNames = cast([^]cstring)raw_data(requestedLayers),
    };

        fmt.printf("test");
    vulkan.CreateDevice(devices[deviceIndex], &dCreateInfo, nil, &device);
bonbug.actionEnd();

Bonbug 只是一个调试包。我的程序叫做 bonfire,所以这就是我想出的名字。 Vulkan 不显示任何错误消息。我知道程序在运行 vulkan.CreateDevice() 时崩溃,因为 printf("test") 通过了。 结果输出是这样的:

BONBUGGER: Creating Device... test

请注意,该行末尾没有“DONE”(这就是 bonbug.actionEnd() 所做的),这验证了程序已崩溃。 此行为之前在另一个 vulkan 过程中也发生过。我用这段代码修复了:

context.user_ptr = &instance;
get_proc_address :: proc(p: rawptr, name: cstring) 
{
    (cast(^rawptr)p)^ = glfw.GetInstanceProcAddress((^vulkan.Instance)(context.user_ptr)^, name);
}

vulkan.load_proc_addresses(get_proc_address);

这对于该程序有效;但是我尝试运行“vulkan.load_proc_addresses(get_proc_address);”在 CreateDevice() 过程之前再次执行此操作,但它不起作用。 请帮忙,因为我还没有找到 odin 的任何 vulkan 文档,但我对项目的了解太深,无法将其转换为 c++。

crash vulkan odin
1个回答
0
投票

不确定您是否仍在寻找这个问题的答案,但我一直在研究这个问题,并认为我会与其他人分享我的发现。

导入时的 Vulkan 库在某种意义上是“不完整的”。我们需要使用 Vulkan 的所有方法/函数都存在,但作为模板而不是真正的函数。为了使用这些函数,我们必须首先告诉库在哪里可以找到这些函数。

我们可以使用重载函数来做到这一点:

vulkan.load_proc_addresses()
。该函数重载了以下 5 个函数:

  1. load_proc_addresses_global(vk_get_instance_proc_addr: rawptr)
  2. load_proc_addresses_instance(instance: Instance)
  3. load_proc_addresses_device(device: Device)
  4. load_proc_addresses_device_vtable(device: Device, vtable: ^Device_VTable)
  5. load_proc_addresses_custom(set_proc_address: SetProcAddressType)

load_proc_addresses_global(vk_get_instance_proc_addr: rawptr)

此函数采用指向函数的指针作为参数,用于访问创建 Vulkan 实例所需的最基本的 Vulkan 函数。


load_proc_addresses_instance(instance: Instance)

通过将

vulkan.Instance
传递给此函数,我们可以访问创建物理和逻辑设备所需的下一级 Vulkan 功能。


load_proc_addresses_device(device: Device)

将 vulkan.Device 传递给该函数后,我们就完成了所有函数定义,可以使用完整的 Vulkan 功能。


用这个我们可以组合一个基本的 Vulkan 初始化方法:

import "vendor:glfw"
import vk "vendor:vulkan"

initVulkan :: proc() {
    // load_proc_addresses_global :: proc(vk_get_instance_proc_addr: rawptr)
    vk.load_proc_addresses((rawptr)(glfw.GetInstanceProcAddress));

    instance : vk.Instance = createVkInstance();
    
    // load_proc_addresses_instance :: proc(instance: Instance)
    vk.load_proc_addresses(instance)

    physicalDevice : vk.PhysicalDevice = pickPhysicalDevice()
    device : vk.Device = createLogicalDevice(physicalDevice)
    
    // load_proc_addresses_device :: proc(device: Device)
    vk.load_proc_addresses(device)
}

就是这样。这样(假设您正确创建了实例和设备),Vulkan 库就可以正常运行了。


但是我听到你问最后两个函数是什么:

  1. load_proc_addresses_device_vtable(device: Device, vtable: ^Device_VTable)
  2. load_proc_addresses_custom(set_proc_address: SetProcAddressType)

我们不需要它们。据我所知,仅当您计划同时使用多个设备时才使用

load_proc_addresses_device_vtable
。这是因为每个设备都有自己的关联功能位置,要求程序员为每个设备存储正确的功能位置。

另一方面,

load_proc_addresses_custom
接受一个函数指针并使用它映射所有 Vulkans 函数。我想不出您希望自己这样做的任何合理理由,所以不要接近这个,除非您真的知道自己在做什么。

© www.soinside.com 2019 - 2024. All rights reserved.