I'm trying to create a swapchain after surface creation. Currently my window is being created with GLFW like this:
glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
GLFWWindow = glfwCreateWindow(Extent.Width, Extent.Height, _Name.c_str(), NULL, NULL);
I create my VkInstance
like this:
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!")
My VkDevice
like this:
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);
Then I'm giving the HWND
and hInstance
to the surface through:
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!")
After that as required by the validation layers I query for support and capabilities:
VkSurfaceCapabilitiesKHR Capabilities;
auto CapResult = vkGetPhysicalDeviceSurfaceCapabilitiesKHR(_PD, Surface, &Capabilities);
VkBool32 Supports = 0;
auto SupResult = vkGetPhysicalDeviceSurfaceSupportKHR(_PD, _Device.GetGraphicsQueue().GetQueueIndex(), Surface, &Supports);
vkGetPhysicalDeviceSurfaceSupportKHR()
returns VK_SUCCESS
and that the surface is supported, but vkGetPhysicalDeviceSurfaceCapabilitiesKHR()
returns VK_ERROR_SURFACE_LOST_KHR
. I tried switching the order of these two functions and still the same happens.
Finally when I try to create a swapchain:
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;
It fails with this VK_RESULT
: VK_ERROR_INITIALIZATION_FAILED
, and the validation layers throw this warning:
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
Even though I believe I have checked for capabilities.
My Instance has this extensions enabled which are all that are required for GLFW to function:
const char* Extensions[] = { VK_KHR_SURFACE_EXTENSION_NAME, VK_KHR_WIN32_SURFACE_EXTENSION_NAME };
My thought is that there is something wrong with Vulkan, since I can not see where this could go wrong. I was thinking of creating an issue but I wanted to check with you guys first.
Turns out I wasn't setting the HWND and HInstance variables properly but the surface creation didn't complain about it, neither did the validation layers. And for some reason one of the query capabilities function didn't fail while the other did.