我正在使用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
或简单地比较无效终端的字符串,然后在比较后记住将其添加。。