尽管在枚举图层属性时出现,Vulkan 实例图层仍返回 VK_ERROR_LAYER_NOT_PRESENT?

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

我正在使用 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 语句,并且“result”变量设置为 VK_ERROR_LAYER_NOT_PRESENT。它使用可用层列表中的相同字符串,因此毫无疑问它是相同的。这是唯一的一层。如果我使用任何其他层(例如 VK_LAYER_LUNARG_core_validation),那么它将具有相同的结果。无论枚举中列出的是哪一层。

go layer vulkan
2个回答
1
投票

我今天自己也遇到了同样的问题,由于这是 Google 中此问题的最高结果,但没有提供答案,所以我将分享我发现的内容。

Vulkan 期望 ppEnabledLayerNames 和 ppEnabledExtensionNames(以及一般情况)中提供的字符串以 null 结尾,目前在使用 vulkan-go 时必须手动完成。

在您的代码示例中,您通过从 Vulkan 提供的字符串中修剪所有 NULL 字节来隐藏问题

name := string(bytes.Trim(prop.LayerName[:], "\x00"))
值得一提的是,vulkan-go 提供了一个函数来进行上述转换,

ToString(),但它也有同样的问题。如果您想在使用 CreateInstance 或类似工具之前测试字符串,则必须保留至少一个 NULL 字节:

terminus := bytes.IndexByte(prop.LayerName[:], 0) // Find null terminator name := string(prop.LayerName[:terminus+1]) // Include single NULL byte
或者简单地比较不带空终止符的字符串,然后记住在比较后添加它。 .


0
投票
我刚刚在 Linux 上遇到了这个奇怪的错误(我的应用程序是用 C++ 编写的),带有层

1.3.261.1

问题是 dlopen 无法加载

libVkLayer_khronos_validation.so

,因为 
pthread_create
 未定义。

解决方案很简单:

// Validation layer needs this. void *libHandle = dlopen( "libpthread.so.0", RTLD_GLOBAL | RTLD_LAZY ); if(!libHandle) { fprintf(stderr, "dlopen failed: %s\n", dlerror()); }
这解决了它。

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