vulkan实例层返回vk_error_layer_not_present,尽管在枚举图层属性时出现



我正在使用Vulkan-Go绑定与Vulkan合作。我通过验证层成功枚举,并确认vk_layer_khronos_validation在该列表中。然后,我将其作为验证层(和唯一的验证层(传递给我的创建实例调用。它返回vk_error_layer_not_present。

我已经验证了我的注册表是正确的,并且所有层都有正确的条目。我已经验证了条目中存在的文件我在写作时使用了Lunarg的最新SDK(1.1.114.0(我正在使用Vulkan-Go的GO绑定,但这似乎不是问题,因为返回错误的呼叫是C的呼叫,并且错误是Vulkan响应代码。也发生在枚举层属性中返回的任何其他层扩展工作正常,使用相同的枚举策略等

枚举(输出12层,包括问题中提到的一层(:

// FindAvailableInstanceValidationLayers returns a list of available validation layers on your device
func (vkctx *VulkanContext) FindAvailableInstanceValidationLayers() ([]string, error) {
    var count uint32
    if res := vk.EnumerateInstanceLayerProperties(&count, nil); res != vk.Success {
        dbg.Error("Failed to get instance validation layer count!")
        return nil, errors.New("failed to get instance validation layer count")
    }
    properties := make([]vk.LayerProperties, count, count)
    if res := vk.EnumerateInstanceLayerProperties(&count, properties); res != vk.Success {
        dbg.Error("Failed to enumerate instance validation layers!")
        return nil, errors.New("failed to get instance validation layer count")
    }
    var layers []string
    for _, prop := range properties {
        prop.Deref()
        name := string(bytes.Trim(prop.LayerName[:], "x00"))
        layers = append(layers, name)
    }
    return layers, nil
}
// returns => [VK_LAYER_NV_optimus VK_LAYER_VALVE_steam_overlay VK_LAYER_VALVE_steam_fossilize VK_LAYER_LUNARG_api_dump VK_LAYER_LUNARG_assistant_layer VK_LAYER_LUNARG_core_validation VK_LAYER_LUNARG_device_simulation VK_LAYER_KHRONOS_validation VK_LAYER_LUNARG_monitor VK_LAYER_LUNARG_object_tracker VK_LAYER_LUNARG_screenshot VK_LAYER_LUNARG_standard_validation VK_LAYER_LUNARG_parameter_validation VK_LAYER_GOOGLE_threading VK_LAYER_GOOGLE_unique_objects VK_LAYER_LUNARG_vktrace]

创建实例调用:

// declare app info
    appinfo := &vk.ApplicationInfo{
        SType:              vk.StructureTypeApplicationInfo,
        PApplicationName:   "Stack Overflow Example",
        ApplicationVersion: vk.MakeVersion(1, 0, 0),
        PEngineName:        "no engine",
        EngineVersion:      vk.MakeVersion(1, 0, 0),
        ApiVersion:         vk.ApiVersion11,
    }
    // declare create info (supported layers contains correct string)
    createinfo := &vk.InstanceCreateInfo{
        SType:                   vk.StructureTypeInstanceCreateInfo,
        PApplicationInfo:        appinfo,
        EnabledExtensionCount:   uint32(2),
        PpEnabledExtensionNames: []string{ "VK_KHR_surface", "VK_KHR_win32_surface" },
        EnabledLayerCount:       uint32(1),
        PpEnabledLayerNames:     []string{ "VK_LAYER_KHRONOS_validation" },
    }

    // create the instance
    inst := new(vk.Instance)
    if result := vk.CreateInstance(createinfo, nil, inst); result != vk.Success {
        // result => vk.ErrorLayerNotPresent
        dbg.Error("Failed to create vulkan instance!")
        return nil, errors.New("vulkan instance creation failed")
    }

我期望CreateInstance通过(或出于其他原因失败(,而是进入IF语句,"结果"变量设置为vk_error_layer_not_present。它使用了该可用层列表中的相同字符串,因此毫无疑问是相同的。这是唯一的一层。如果我使用任何其他图层(例如vk_layer_lunarg_core_validation(,则它将具有相同的结果。无论枚举中列出的层。

我本人遇到了同样的问题,由于这是Google这个问题的最佳结果,但没有提供任何答案,我将分享我的发现。

vulkan期望在ppenabledlayernames和ppenabledextensionnames(以及通常(中提供的字符串是无效的,目前必须在使用vulkan-go时手动进行。

在您的代码示例中,您已经通过修剪来自Vulkan提供的字符串的所有null字节来隐藏问题。

    name := string(bytes.Trim(prop.LayerName[:], "x00"))

值得一提的是,Vulkan-Go提供了执行上述转换((的功能,但它也有相同的问题。如果要在使用CreateInstance或类似的情况下测试字符串,则必须保留至少一个null字节:

terminus := bytes.IndexByte(prop.LayerName[:], 0)  // Find null terminator
name := string(prop.LayerName[:terminus+1]) // Include single NULL byte

或简单地比较无效终端的字符串,然后在比较后记住将其添加。。

最新更新