首页 > 解决方案 > 惰性初始化 VkObjects 的 Vulkan 用例

问题描述

当您围绕基本的 Vulkan 对象(如VkDevice,等)编写一些包装器时VkSemaphoreVkImage是否有一些典型的用例(如使用 OpenGL 时),您真的想使用延迟初始化并且不要直接在构造函数中调用vkCreateDevice, VkCreateSemaphore,但是VkCreateXyz稍后在某些创建/初始化方法中?

标签: c++vulkan

解决方案


延迟初始化通常用于“推迟”执行某些活动,直到它真正需要(可能永远不会)。对于创建方法,似乎没有什么好处——如果你创建了一些你通常想要的东西,或者如果有一些问题会立即失败(而不是稍后执行)。

但是,这种方法对于调用 Vulkan API 方法的访问器很有用,这些方法可能会或可能不会被应用程序使用,例如物理设备的属性:

private VkPhysicalDeviceFeatures features;

public VkPhysicalDeviceFeatures features() {
    if(features == null) {
        features = new VkPhysicalDeviceFeatures();
        vkGetPhysicalDeviceFeatures(handle, features);
    }
    return features;
}

这比作为构造函数的一部分“强制”从 Vulkan 检索特征要好,如果需要,可以缓存结果(如上),但会增加一点复杂性。

编辑:一个更好的例子可能是设备内存属性或类似的东西,这些功能通常会在创建逻辑设备时立即使用。

对于通过VkCreateXXX方法创建的对象,我建议使用构造函数静态工厂方法。单元测试将使用构造函数(通常会以某种方式受到保护),而应用程序将调用工厂。

例如(伪代码):

class LogicalDevice {
    public static LogicalDevice create(PhysicalDevice parent) {
        // populate VkDeviceCreateInfo with required extensions, layers, queues, etc
        vkCreateDevice(...);
        return new LogicalDevice(...);
    }

    LogicalDevice(Handle handle, PhysicalDevice parent, ...) {
    }
}

推荐阅读