Vulkan instance missing VK_KHR_win32_surface extension

Started by Manhattan, April 22, 2022, 02:21:55

Previous topic - Next topic

Manhattan

Hello. I'm new to Vulkan and trying to set it up using LWJGL 3.3.1 on Windows 11 x64 using an "Nvidia RTX 2070 Super with MaxQ Design" updated to the latest version (512.15).
When I try to use glfwCreateWindowSurface, it throws me the error "Win32: Vulkan instance missing VK_KHR_win32_surface extension" with an error code of: 65542
When I try to use vkCreateWin32SurfaceKHR instead, it throws me a NullPointerException.
I've made sure the extension is there during the instance creation.
I've used vkGetInstanceProcAddr on both functions only to get a null pointer, while at the same time functions like vkCreateInstance and vkEnumerateInstanceExtensionProperties return a valid pointer.

Please, take a look at my code:
public class GLFWHandler {
	public static final void init() {
		// Set GLFW error callback
		GLFW.glfwSetErrorCallback(new GLFWErrorCallbackI() {
			@Override
			public void invoke(int code, long message) { ExceptionHandler.error(GLFWErrorCallback.getDescription(message), code); }
		});
		// In failure to initialize GLFW, throw an error
		if(!GLFW.glfwInit()) ExceptionHandler.error("Failed to initialize GLFW.", 1); // ERROR CODE: 1
	}
}


public class VulkanInstance {
	public static final VkInstance vulkanInstance;
	
	static {
		if (!GLFWVulkan.glfwVulkanSupported()) ExceptionHandler.error("Vulkan is not supported.", 3); // ERROR CODE: 3
		try(final MemoryStack stack = MemoryStack.stackPush()) {
			final ByteBuffer appShortName = MemoryStack.stackUTF8(Info.APP_SHORTNAME != null ? Info.APP_SHORTNAME : "App", true);
			final ByteBuffer engineName = MemoryStack.stackASCII("Engine", true);
			final VkApplicationInfo appInfo = VkApplicationInfo.calloc(stack)
							  .sType(VK10.VK_STRUCTURE_TYPE_APPLICATION_INFO)
							  .pApplicationName(appShortName)
							  .applicationVersion(1)
							  .pEngineName(engineName)
							  .engineVersion(1)
							  .apiVersion(VK10.VK_API_VERSION_1_0);
			final PointerBuffer glfwExtensions = GLFWVulkan.glfwGetRequiredInstanceExtensions();
			final PointerBuffer requiredExtensions = stack.mallocPointer(glfwExtensions.limit() + 1);
			ByteBuffer win32SurfaceExtension = stack.UTF8(KHRWin32Surface.VK_KHR_WIN32_SURFACE_EXTENSION_NAME);
			requiredExtensions.put(glfwExtensions).put(win32SurfaceExtension);
			final VkInstanceCreateInfo instanceInfo = VkInstanceCreateInfo.calloc(stack)
								  .sType(VK10.VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO)
								  .pNext(MemoryUtil.NULL)
								  .pApplicationInfo(appInfo)
								  .ppEnabledLayerNames(null)
								  .ppEnabledExtensionNames(requiredExtensions);
			final PointerBuffer instancePointer = stack.mallocPointer(1);
			VK10.vkCreateInstance(instanceInfo, null, instancePointer)
			vulkanInstance = new VkInstance(instancePointer.get(0), instanceInfo);
               }
       }
}


public class Surface {
	public static final long surface;
	
	static {
        	try (final MemoryStack stack = MemoryStack.stackPush()) {
			final LongBuffer pSurface = stack.mallocLong(1);
			if(GLFWVulkan.glfwCreateWindowSurface(VulkanInstance.vulkanInstance, Display.window, null, pSurface) != VK10.VK_SUCCESS) ExceptionHandler.error("Failed to create a window surface.", 19);
			surface = pSurface.get(0);
		}
        }
}


Please let me know if I'm doing something wrong here.
Thank you very much in advance.

KaiHH

Two things:
1.: the extensions "VK_KHR_surface" and "VK_KHR_win32_surface" will already be included in the result of `glfwGetRequiredInstanceExtensions()`, so there is no need to _additionally_ manually add it
2.: you call the relative put() methods `requiredExtensions.put(glfwExtensions).put(win32SurfaceExtension);` without resetting the position of the NIO Buffer afterwards. This results in the requiredExtensions buffer effectively being empty as LWJGL sees it, since its remaining() will be 0. So, either rewind(), flip() or position(0) that buffer.

Manhattan

Quote from: KaiHH on April 22, 2022, 07:13:59
Two things:
1.: the extensions "VK_KHR_surface" and "VK_KHR_win32_surface" will already be included in the result of `glfwGetRequiredInstanceExtensions()`, so there is no need to _additionally_ manually add it
2.: you call the relative put() methods `requiredExtensions.put(glfwExtensions).put(win32SurfaceExtension);` without resetting the position of the NIO Buffer afterwards. This results in the requiredExtensions buffer effectively being empty as LWJGL sees it, since its remaining() will be 0. So, either rewind(), flip() or position(0) that buffer.

You, good sir, are a godsent.
It's laughable what kind of topics I had to research in order to find a solution to my now-fixed problem when all I had to do is to reset the buffer position.
Thank you very much for helping me, KaiHH.