vkCreateSwapchainKHR():未为此物理设备检索表面功能
vkCreateSwapchainKHR(): surface capabilities not retrieved for this physical device
我正在尝试在表面创建后创建交换链。目前我的 window 正在使用 GLFW 创建,如下所示:
glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
GLFWWindow = glfwCreateWindow(Extent.Width, Extent.Height, _Name.c_str(), NULL, NULL);
我这样创建 VkInstance
:
VkApplicationInfo AppInfo = { VK_STRUCTURE_TYPE_APPLICATION_INFO };
AppInfo.apiVersion = VK_API_VERSION_1_1; //Should check if version is available vi vkEnumerateInstanceVersion().
AppInfo.applicationVersion = VK_MAKE_VERSION(1, 0, 0);
AppInfo.engineVersion = VK_MAKE_VERSION(1, 0, 0);
AppInfo.pApplicationName = _AppName;
AppInfo.pEngineName = "Game Studio";
#ifdef GS_DEBUG
const char* InstanceLayers[] = { "VK_LAYER_LUNARG_standard_validation" };
#else
const char* InstanceLayers[] = nullptr;
#endif // GS_DEBUG
const char* Extensions[] = { VK_KHR_SURFACE_EXTENSION_NAME, VK_KHR_WIN32_SURFACE_EXTENSION_NAME };
VkInstanceCreateInfo InstanceCreateInfo = { VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO };
InstanceCreateInfo.pApplicationInfo = &AppInfo;
InstanceCreateInfo.enabledLayerCount = 1;
InstanceCreateInfo.ppEnabledLayerNames = InstanceLayers;
InstanceCreateInfo.enabledExtensionCount = 2;
InstanceCreateInfo.ppEnabledExtensionNames = Extensions;
GS_VK_CHECK(vkCreateInstance(&InstanceCreateInfo, ALLOCATOR, &Instance), "Failed to create Instance!")
我的VkDevice
是这样的:
VkPhysicalDeviceFeatures deviceFeatures = {}; //COME BACK TO
const char* DeviceExtensions[] = { VK_KHR_SWAPCHAIN_EXTENSION_NAME };
PhysicalDevice = CreatePhysicalDevice(_Instance);
QueueInfo GraphicsQueueInfo;
QueueInfo ComputeQueueInfo;
QueueInfo TransferQueueInfo;
GraphicsQueueInfo.QueueFlag = VK_QUEUE_GRAPHICS_BIT;
GraphicsQueueInfo.QueuePriority = 1.0f;
ComputeQueueInfo.QueueFlag = VK_QUEUE_COMPUTE_BIT;
ComputeQueueInfo.QueuePriority = 1.0f;
TransferQueueInfo.QueueFlag = VK_QUEUE_TRANSFER_BIT;
TransferQueueInfo.QueuePriority = 1.0f;
QueueInfo QueueInfos[] = { GraphicsQueueInfo, ComputeQueueInfo, TransferQueueInfo };
FVector<VkDeviceQueueCreateInfo> QueueCreateInfos = CreateQueueInfos(QueueInfos, 3, PhysicalDevice);
VkDeviceCreateInfo DeviceCreateInfo = { VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO };
DeviceCreateInfo.queueCreateInfoCount = QueueCreateInfos.length();
DeviceCreateInfo.pQueueCreateInfos = QueueCreateInfos.data();
DeviceCreateInfo.enabledExtensionCount = 1;
DeviceCreateInfo.pEnabledFeatures = &deviceFeatures;
DeviceCreateInfo.ppEnabledExtensionNames = DeviceExtensions;
auto ff = vkCreateDevice(PhysicalDevice, &DeviceCreateInfo, ALLOCATOR, &Device);
Vk_Queue* Queues[] = { &GraphicsQueue, &ComputeQueue, &TransferQueue };
SetVk_Queues(Queues, QueueCreateInfos);
vkGetPhysicalDeviceMemoryProperties(PhysicalDevice, &MemoryProperties);
然后我将 HWND
和 hInstance
传递给表面:
VkWin32SurfaceCreateInfoKHR WCreateInfo = { VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR };
WCreateInfo.hwnd = SCAST(WindowsWindow*, _Window)->GetWindowObject();
WCreateInfo.hinstance = SCAST(WindowsWindow*, _Window)->GetHInstance();
GS_VK_CHECK(vkCreateWin32SurfaceKHR(m_Instance, &WCreateInfo, ALLOCATOR, &Surface), "Failed to create Windows Surface!")
之后,根据验证层的要求,我查询支持和功能:
VkSurfaceCapabilitiesKHR Capabilities;
auto CapResult = vkGetPhysicalDeviceSurfaceCapabilitiesKHR(_PD, Surface, &Capabilities);
VkBool32 Supports = 0;
auto SupResult = vkGetPhysicalDeviceSurfaceSupportKHR(_PD, _Device.GetGraphicsQueue().GetQueueIndex(), Surface, &Supports);
vkGetPhysicalDeviceSurfaceSupportKHR()
returnsVK_SUCCESS
而且表面是支持的,但是vkGetPhysicalDeviceSurfaceCapabilitiesKHR()
returnsVK_ERROR_SURFACE_LOST_KHR
。我试着调换这两个函数的顺序,还是一样。
最后,当我尝试创建交换链时:
VkSwapchainCreateInfoKHR SwapchainCreateInfo = { VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR };
SwapchainCreateInfo.surface = _Surface;
SwapchainCreateInfo.minImageCount = 3;
SwapchainCreateInfo.imageFormat = _SurfaceFormat;
SwapchainCreateInfo.imageColorSpace = _SurfaceColorSpace;
SwapchainCreateInfo.imageExtent = _SurfaceExtent;
SwapchainCreateInfo.imageArrayLayers = 1;
SwapchainCreateInfo.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
SwapchainCreateInfo.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE;
SwapchainCreateInfo.queueFamilyIndexCount = 1; // Optional
SwapchainCreateInfo.pQueueFamilyIndices = nullptr;
SwapchainCreateInfo.preTransform = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR;
SwapchainCreateInfo.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;
SwapchainCreateInfo.presentMode = _PresentMode;
SwapchainCreateInfo.clipped = VK_TRUE;
SwapchainCreateInfo.oldSwapchain = _OldSwapchain;
失败并显示此 VK_RESULT
:VK_ERROR_INITIALIZATION_FAILED
,并且验证层抛出此警告:
UNASSIGNED-CoreValidation-DrawState-SwapchainCreateBeforeQuery(ERROR / SPEC): msgNum: 0 - vkCreateSwapchainKHR(): surface capabilities not retrieved for this physical device
Objects: 1
[0] 0x1fddb809470, type: 2, name: NULL
即使我相信我已经检查了功能。
我的实例启用了此扩展,这是 GLFW 运行所需的全部:
const char* Extensions[] = { VK_KHR_SURFACE_EXTENSION_NAME, VK_KHR_WIN32_SURFACE_EXTENSION_NAME };
我的想法是 Vulkan 有问题,因为我看不出哪里会出错。我正在考虑创建一个问题,但我想先和你们确认一下。
您展示了 window 创建和表面创建,但不包括实例创建代码。创建实例时,您是否确保请求了 glfwGetRequiredInstanceExtensions
返回的扩展?请求的确切扩展集是什么?
如果您没有请求任何延期,特别是如果您缺少 VK_KHR_surface
和 VK_KHR_win32_surface
,那么预计部分或所有表面操作可能会失败。
此外,您如何填充 _SurfaceFormat
?
最后,这看起来不对:
SwapchainCreateInfo.queueFamilyIndexCount = 1; // Optional
SwapchainCreateInfo.pQueueFamilyIndices = nullptr;
如果 pQueueFamilyIndices
为空,则 queueFamilyIndexCount
应为零。
原来我没有正确设置 HWND 和 HInstance 变量,但是表面创建并没有抱怨它,验证层也没有。由于某种原因,其中一个查询功能函数没有失败,而另一个失败了。
我正在尝试在表面创建后创建交换链。目前我的 window 正在使用 GLFW 创建,如下所示:
glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
GLFWWindow = glfwCreateWindow(Extent.Width, Extent.Height, _Name.c_str(), NULL, NULL);
我这样创建 VkInstance
:
VkApplicationInfo AppInfo = { VK_STRUCTURE_TYPE_APPLICATION_INFO };
AppInfo.apiVersion = VK_API_VERSION_1_1; //Should check if version is available vi vkEnumerateInstanceVersion().
AppInfo.applicationVersion = VK_MAKE_VERSION(1, 0, 0);
AppInfo.engineVersion = VK_MAKE_VERSION(1, 0, 0);
AppInfo.pApplicationName = _AppName;
AppInfo.pEngineName = "Game Studio";
#ifdef GS_DEBUG
const char* InstanceLayers[] = { "VK_LAYER_LUNARG_standard_validation" };
#else
const char* InstanceLayers[] = nullptr;
#endif // GS_DEBUG
const char* Extensions[] = { VK_KHR_SURFACE_EXTENSION_NAME, VK_KHR_WIN32_SURFACE_EXTENSION_NAME };
VkInstanceCreateInfo InstanceCreateInfo = { VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO };
InstanceCreateInfo.pApplicationInfo = &AppInfo;
InstanceCreateInfo.enabledLayerCount = 1;
InstanceCreateInfo.ppEnabledLayerNames = InstanceLayers;
InstanceCreateInfo.enabledExtensionCount = 2;
InstanceCreateInfo.ppEnabledExtensionNames = Extensions;
GS_VK_CHECK(vkCreateInstance(&InstanceCreateInfo, ALLOCATOR, &Instance), "Failed to create Instance!")
我的VkDevice
是这样的:
VkPhysicalDeviceFeatures deviceFeatures = {}; //COME BACK TO
const char* DeviceExtensions[] = { VK_KHR_SWAPCHAIN_EXTENSION_NAME };
PhysicalDevice = CreatePhysicalDevice(_Instance);
QueueInfo GraphicsQueueInfo;
QueueInfo ComputeQueueInfo;
QueueInfo TransferQueueInfo;
GraphicsQueueInfo.QueueFlag = VK_QUEUE_GRAPHICS_BIT;
GraphicsQueueInfo.QueuePriority = 1.0f;
ComputeQueueInfo.QueueFlag = VK_QUEUE_COMPUTE_BIT;
ComputeQueueInfo.QueuePriority = 1.0f;
TransferQueueInfo.QueueFlag = VK_QUEUE_TRANSFER_BIT;
TransferQueueInfo.QueuePriority = 1.0f;
QueueInfo QueueInfos[] = { GraphicsQueueInfo, ComputeQueueInfo, TransferQueueInfo };
FVector<VkDeviceQueueCreateInfo> QueueCreateInfos = CreateQueueInfos(QueueInfos, 3, PhysicalDevice);
VkDeviceCreateInfo DeviceCreateInfo = { VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO };
DeviceCreateInfo.queueCreateInfoCount = QueueCreateInfos.length();
DeviceCreateInfo.pQueueCreateInfos = QueueCreateInfos.data();
DeviceCreateInfo.enabledExtensionCount = 1;
DeviceCreateInfo.pEnabledFeatures = &deviceFeatures;
DeviceCreateInfo.ppEnabledExtensionNames = DeviceExtensions;
auto ff = vkCreateDevice(PhysicalDevice, &DeviceCreateInfo, ALLOCATOR, &Device);
Vk_Queue* Queues[] = { &GraphicsQueue, &ComputeQueue, &TransferQueue };
SetVk_Queues(Queues, QueueCreateInfos);
vkGetPhysicalDeviceMemoryProperties(PhysicalDevice, &MemoryProperties);
然后我将 HWND
和 hInstance
传递给表面:
VkWin32SurfaceCreateInfoKHR WCreateInfo = { VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR };
WCreateInfo.hwnd = SCAST(WindowsWindow*, _Window)->GetWindowObject();
WCreateInfo.hinstance = SCAST(WindowsWindow*, _Window)->GetHInstance();
GS_VK_CHECK(vkCreateWin32SurfaceKHR(m_Instance, &WCreateInfo, ALLOCATOR, &Surface), "Failed to create Windows Surface!")
之后,根据验证层的要求,我查询支持和功能:
VkSurfaceCapabilitiesKHR Capabilities;
auto CapResult = vkGetPhysicalDeviceSurfaceCapabilitiesKHR(_PD, Surface, &Capabilities);
VkBool32 Supports = 0;
auto SupResult = vkGetPhysicalDeviceSurfaceSupportKHR(_PD, _Device.GetGraphicsQueue().GetQueueIndex(), Surface, &Supports);
vkGetPhysicalDeviceSurfaceSupportKHR()
returnsVK_SUCCESS
而且表面是支持的,但是vkGetPhysicalDeviceSurfaceCapabilitiesKHR()
returnsVK_ERROR_SURFACE_LOST_KHR
。我试着调换这两个函数的顺序,还是一样。
最后,当我尝试创建交换链时:
VkSwapchainCreateInfoKHR SwapchainCreateInfo = { VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR };
SwapchainCreateInfo.surface = _Surface;
SwapchainCreateInfo.minImageCount = 3;
SwapchainCreateInfo.imageFormat = _SurfaceFormat;
SwapchainCreateInfo.imageColorSpace = _SurfaceColorSpace;
SwapchainCreateInfo.imageExtent = _SurfaceExtent;
SwapchainCreateInfo.imageArrayLayers = 1;
SwapchainCreateInfo.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
SwapchainCreateInfo.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE;
SwapchainCreateInfo.queueFamilyIndexCount = 1; // Optional
SwapchainCreateInfo.pQueueFamilyIndices = nullptr;
SwapchainCreateInfo.preTransform = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR;
SwapchainCreateInfo.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;
SwapchainCreateInfo.presentMode = _PresentMode;
SwapchainCreateInfo.clipped = VK_TRUE;
SwapchainCreateInfo.oldSwapchain = _OldSwapchain;
失败并显示此 VK_RESULT
:VK_ERROR_INITIALIZATION_FAILED
,并且验证层抛出此警告:
UNASSIGNED-CoreValidation-DrawState-SwapchainCreateBeforeQuery(ERROR / SPEC): msgNum: 0 - vkCreateSwapchainKHR(): surface capabilities not retrieved for this physical device
Objects: 1
[0] 0x1fddb809470, type: 2, name: NULL
即使我相信我已经检查了功能。
我的实例启用了此扩展,这是 GLFW 运行所需的全部:
const char* Extensions[] = { VK_KHR_SURFACE_EXTENSION_NAME, VK_KHR_WIN32_SURFACE_EXTENSION_NAME };
我的想法是 Vulkan 有问题,因为我看不出哪里会出错。我正在考虑创建一个问题,但我想先和你们确认一下。
您展示了 window 创建和表面创建,但不包括实例创建代码。创建实例时,您是否确保请求了 glfwGetRequiredInstanceExtensions
返回的扩展?请求的确切扩展集是什么?
如果您没有请求任何延期,特别是如果您缺少 VK_KHR_surface
和 VK_KHR_win32_surface
,那么预计部分或所有表面操作可能会失败。
此外,您如何填充 _SurfaceFormat
?
最后,这看起来不对:
SwapchainCreateInfo.queueFamilyIndexCount = 1; // Optional
SwapchainCreateInfo.pQueueFamilyIndices = nullptr;
如果 pQueueFamilyIndices
为空,则 queueFamilyIndexCount
应为零。
原来我没有正确设置 HWND 和 HInstance 变量,但是表面创建并没有抱怨它,验证层也没有。由于某种原因,其中一个查询功能函数没有失败,而另一个失败了。