From 5a331578b5f1022248d160548cf618f374cf59fc Mon Sep 17 00:00:00 2001 From: Hane Date: Wed, 30 Oct 2024 18:27:16 +0100 Subject: [PATCH 1/2] swp/sur extensions + surface --- src/main.cpp | 56 +++++++++++++++++++++++++++++----------------------- 1 file changed, 31 insertions(+), 25 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index d5a2b2e..f6f6660 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,6 +1,12 @@ #define WIN32_LEAN_AND_MEAN #define UNICODE +#ifdef _WIN32 + #define VK_USE_PLATFORM_WIN32_KHR +#elif defined(VK_USE_PLATFORM_WAYLAND_KHR) + #define VK_USE_PLATFORM_WAYLAND_KHR +#endif + #include #include #include @@ -110,23 +116,23 @@ int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int n app_info.engineVersion = 1; app_info.apiVersion = VK_API_VERSION_1_0; + // initialize the VkInstanceCreateInfo structure with appropiate SURFACE extensions std::vector instanceExtensionNames; instanceExtensionNames.push_back(VK_KHR_SURFACE_EXTENSION_NAME); - /* - * #ifdef _WIN32 - * instanceExtensionNames.push_back(VK_KHR_WIN32_SURFACE_EXTENSION_NAME); - * #elif defined(VK_USE_PLATFORM_WAYLAND_KHR) - * instanceExtensionNames.push_back(VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME); - * #endif - */ + + #ifdef _WIN32 + instanceExtensionNames.push_back(VK_KHR_WIN32_SURFACE_EXTENSION_NAME); + #elif defined(VK_USE_PLATFORM_WAYLAND_KHR) + instanceExtensionNames.push_back(VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME); + #endif VkInstanceCreateInfo inst_info = {}; inst_info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO; inst_info.pNext = NULL; inst_info.flags = 0; inst_info.pApplicationInfo = &app_info; - inst_info.enabledExtensionCount = 0;//2; - inst_info.ppEnabledExtensionNames = NULL;//instanceExtensionName.data(); + inst_info.enabledExtensionCount = 2; + inst_info.ppEnabledExtensionNames = instanceExtensionNames.data(); inst_info.enabledLayerCount = 0; inst_info.ppEnabledLayerNames = NULL; @@ -187,8 +193,8 @@ int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int n deviceInfo.pNext = NULL; deviceInfo.queueCreateInfoCount = 1; deviceInfo.pQueueCreateInfos = &queueInfo; - deviceInfo.enabledExtensionCount = 0;//1; - deviceInfo.ppEnabledExtensionNames = NULL;//deviceExtensionNames.data(); + deviceInfo.enabledExtensionCount = 1; + deviceInfo.ppEnabledExtensionNames = deviceExtensionNames.data(); deviceInfo.enabledLayerCount = 0; deviceInfo.ppEnabledLayerNames = NULL; deviceInfo.pEnabledFeatures = NULL; @@ -220,16 +226,16 @@ int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int n assert(result == VK_SUCCESS); //Swapchain setup (requires Instance SURFACEs and Device SWAPCHAIN extensions) - /* - * VkSurfaceKHR surface; - * #ifdef _WIN32 - * VkWin32SurfaceCreateInfoKHR createInfo = {}; - * createInfo.sType = VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR; - * createInfo.pNext = NULL; - * createInfo.hinstance = hInstance; - * createInfo.hwnd = hwnd; - * result = vkCreateWin32SurfaceKHR(inst, &createInfo, NULL, &surface); - */ + + VkSurfaceKHR surface; + #ifdef _WIN32 + VkWin32SurfaceCreateInfoKHR createInfo = {}; + createInfo.sType = VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR; + createInfo.pNext = NULL; + createInfo.hinstance = hInstance; + createInfo.hwnd = hwnd; + result = vkCreateWin32SurfaceKHR(inst, &createInfo, NULL, &surface); + /* * #elif defined(VK_USE_PLATFORM_WAYLAND_KHR) * VkWaylandSurfaceCreateInfoKHR createInfo = {}; @@ -238,11 +244,11 @@ int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int n * createInfo.display = info.display; * createInfo.surface = info.window; * res = vkCreateWaylandSurfaceKHR(inst, &createInfo, NULL, &surface); - * - * #endif - * assert(result == VK_SUCCESS); */ - // + #endif + assert(result == VK_SUCCESS); + + //Window show and event loop From a18d2196c1edd70788a97239d2466acd88e303d9 Mon Sep 17 00:00:00 2001 From: Hane Date: Fri, 1 Nov 2024 16:22:33 +0100 Subject: [PATCH 2/2] lunarg 5 --- src/main.cpp | 273 ++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 238 insertions(+), 35 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index f6f6660..099d1d1 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -157,7 +157,32 @@ int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int n result = vkEnumeratePhysicalDevices(inst, &gpuCount, gpus.data()); assert(!result && gpuCount >= 1); - /* Creating logical device(with SWAPCHAIN extension) + queues (todo insspect all gpus, not assuume 1st) */ + //Surface setup (requires Instance SURFACEs) + VkSurfaceKHR surface; + #ifdef _WIN32 + VkWin32SurfaceCreateInfoKHR createInfo = {}; + createInfo.sType = VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR; + createInfo.pNext = NULL; + createInfo.hinstance = hInstance; + createInfo.hwnd = hwnd; + result = vkCreateWin32SurfaceKHR(inst, &createInfo, NULL, &surface); + +/* + * #elif defined(VK_USE_PLATFORM_WAYLAND_KHR) + * VkWaylandSurfaceCreateInfoKHR createInfo = {}; + * createInfo.sType = VK_STRUCTURE_TYPE_WAYLAND_SURFACE_CREATE_INFO_KHR; + * createInfo.pNext = NULL; + * createInfo.display = info.display; + * createInfo.surface = info.window; + * result= vkCreateWaylandSurfaceKHR(inst, &createInfo, NULL, &surface); + */ + #endif + assert(result == VK_SUCCESS); + + + + + /* Creating logical device(with SWAPCHAIN extension) + queues (todo insspect all gpus, not assume 1st) */ VkDeviceQueueCreateInfo queueInfo = {}; uint32_t queueFamilyCount = 0; @@ -169,16 +194,53 @@ int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int n vkGetPhysicalDeviceQueueFamilyProperties(gpus[0], &queueFamilyCount, queueProperties.data()); assert(queueFamilyCount >= 1); - bool found = false; //U_ASSERT_ONLY - for (unsigned int i = 0; i < queueFamilyCount; i++) { - if (queueProperties[i].queueFlags & VK_QUEUE_GRAPHICS_BIT) { - queueInfo.queueFamilyIndex = i; - found = true; - break; - } - } - assert(found); - assert(queueFamilyCount >= 1); + // Iterate over each queue to learn whether it supports Presenting + VkBool32 *pSupportsPresent = (VkBool32 *) malloc(queueFamilyCount * sizeof(VkBool32)); + for (uint32_t i = 0; i < queueFamilyCount; i++) { + vkGetPhysicalDeviceSurfaceSupportKHR(gpus[0], i, surface, &pSupportsPresent[i]); + } + + //Look for graphics & present support in queue families. Also store graphics queue family to create queue + /* + * bool found = false; //U_ASSERT_ONLY + * for (unsigned int i = 0; i < queueFamilyCount; i++) { + * if (queueProperties[i].queueFlags & VK_QUEUE_GRAPHICS_BIT) { + * queuequeueFamilyIndex = i; + * found = true; + * break; + * } + * } + * assert(found); + */ + + uint32_t graphicsQueueFamilyIndex = UINT32_MAX; + uint32_t presentQueueFamilyIndex = UINT32_MAX; + for (uint32_t i = 0; i < queueFamilyCount; ++i) { + if (queueProperties[i].queueFlags & VK_QUEUE_GRAPHICS_BIT) { + if (graphicsQueueFamilyIndex == UINT32_MAX) + graphicsQueueFamilyIndex = i; + + if (pSupportsPresent[i] == VK_TRUE) { + graphicsQueueFamilyIndex = i; + presentQueueFamilyIndex = i; + break; + } + } + } + + if (presentQueueFamilyIndex == UINT32_MAX) { + // If didn't find a queue that supports both graphics and present, then + // find a separate present queue. + for (size_t i = 0; i < queueFamilyCount; ++i) + if (pSupportsPresent[i] == VK_TRUE) { + presentQueueFamilyIndex = i; + break; + } + } + + free(pSupportsPresent); + assert(queueFamilyCount >= 1 && presentQueueFamilyIndex != UINT32_MAX && + graphicsQueueFamilyIndex != UINT32_MAX); float queuePriorities[1] = {0.0}; queueInfo.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO; @@ -208,7 +270,7 @@ int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int n VkCommandPoolCreateInfo cmdPoolInfo = {}; cmdPoolInfo.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO; cmdPoolInfo.pNext = NULL; - cmdPoolInfo.queueFamilyIndex = queueInfo.queueFamilyIndex; //u sure bro???? + cmdPoolInfo.queueFamilyIndex = graphicsQueueFamilyIndex; cmdPoolInfo.flags = 0; result = vkCreateCommandPool(device, &cmdPoolInfo, NULL, &cmdPool); @@ -216,8 +278,8 @@ int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int n VkCommandBuffer cmd; VkCommandBufferAllocateInfo cmdInfo = {}; - cmdInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO; cmdInfo.pNext = NULL; + cmdInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;; cmdInfo.commandPool = cmdPool; cmdInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; cmdInfo.commandBufferCount = 1; @@ -225,31 +287,172 @@ int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int n result = vkAllocateCommandBuffers(device, &cmdInfo, &cmd); assert(result == VK_SUCCESS); - //Swapchain setup (requires Instance SURFACEs and Device SWAPCHAIN extensions) + + // Setting surface format + VkFormat format; + // Get the list of VkFormats that are supported: + uint32_t formatCount; + result = vkGetPhysicalDeviceSurfaceFormatsKHR(gpus[0], surface, &formatCount, NULL); + assert(result == VK_SUCCESS); + VkSurfaceFormatKHR *surfFormats = (VkSurfaceFormatKHR *)malloc(formatCount * sizeof(VkSurfaceFormatKHR)); + result = vkGetPhysicalDeviceSurfaceFormatsKHR(gpus[0], surface, &formatCount, surfFormats); + assert(result == VK_SUCCESS); + // If the format list includes just one entry of VK_FORMAT_UNDEFINED, + // the surface has no preferred format. Otherwise, at least one + // supported format will be returned. + if (formatCount == 1 && surfFormats[0].format == VK_FORMAT_UNDEFINED) { + format = VK_FORMAT_B8G8R8A8_UNORM; + } else { + assert(formatCount >= 1); + format = surfFormats[0].format; + } + free(surfFormats); + + //Surface capabilities and present modes + + uint32_t presentModeCount; + result = vkGetPhysicalDeviceSurfacePresentModesKHR(gpus[0], surface, &presentModeCount, NULL); + assert(result == VK_SUCCESS); //free? + VkPresentModeKHR *presentModes = (VkPresentModeKHR *)malloc(presentModeCount * sizeof(VkPresentModeKHR)); + result = vkGetPhysicalDeviceSurfacePresentModesKHR(gpus[0], surface, &presentModeCount, presentModes); + assert(result == VK_SUCCESS); + // The FIFO present mode is guaranteed by the spec to be supported, so it is hardcoded + VkPresentModeKHR swapchainPresentMode = VK_PRESENT_MODE_FIFO_KHR; + + VkSurfaceCapabilitiesKHR surfCapabilities; + result = vkGetPhysicalDeviceSurfaceCapabilitiesKHR(gpus[0], surface, &surfCapabilities); + assert(result == VK_SUCCESS); + VkExtent2D swapchainExtent; + // width and height are either both 0xFFFFFFFF, or both not 0xFFFFFFFF. + if (surfCapabilities.currentExtent.width == 0xFFFFFFFF) { + // If the surface size is undefined, the size is set to + // the size of the images requested. + swapchainExtent.width = 100; + swapchainExtent.height = 100; + if (swapchainExtent.width < surfCapabilities.minImageExtent.width) { + swapchainExtent.width = surfCapabilities.minImageExtent.width; + } else if (swapchainExtent.width > surfCapabilities.maxImageExtent.width) { + swapchainExtent.width = surfCapabilities.maxImageExtent.width; + } - VkSurfaceKHR surface; - #ifdef _WIN32 - VkWin32SurfaceCreateInfoKHR createInfo = {}; - createInfo.sType = VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR; - createInfo.pNext = NULL; - createInfo.hinstance = hInstance; - createInfo.hwnd = hwnd; - result = vkCreateWin32SurfaceKHR(inst, &createInfo, NULL, &surface); - -/* - * #elif defined(VK_USE_PLATFORM_WAYLAND_KHR) - * VkWaylandSurfaceCreateInfoKHR createInfo = {}; - * createInfo.sType = VK_STRUCTURE_TYPE_WAYLAND_SURFACE_CREATE_INFO_KHR; - * createInfo.pNext = NULL; - * createInfo.display = info.display; - * createInfo.surface = info.window; - * res = vkCreateWaylandSurfaceKHR(inst, &createInfo, NULL, &surface); - */ - #endif - assert(result == VK_SUCCESS); - + if (swapchainExtent.height < surfCapabilities.minImageExtent.height) { + swapchainExtent.height = surfCapabilities.minImageExtent.height; + } else if (swapchainExtent.height > surfCapabilities.maxImageExtent.height) { + swapchainExtent.height = surfCapabilities.maxImageExtent.height; + } + } else { + // If the surface size is defined, the swap chain size must match + swapchainExtent = surfCapabilities.currentExtent; + } + // Determine the number of VkImage's to use in the swap chain. + // We need to acquire only 1 presentable image at at time. + // Asking for minImageCount images ensures that we can acquire + // 1 presentable image as long as we present it before attempting + // to acquire another. + uint32_t desiredNumberOfSwapChainImages = surfCapabilities.minImageCount; + + VkSurfaceTransformFlagBitsKHR preTransform; + if (surfCapabilities.supportedTransforms & VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR) { + preTransform = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR; + } else { + preTransform = surfCapabilities.currentTransform; + } + + // Find a supported composite alpha mode - one of these is guaranteed to be set + VkCompositeAlphaFlagBitsKHR compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR; + VkCompositeAlphaFlagBitsKHR compositeAlphaFlags[4] = { + VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR, + VK_COMPOSITE_ALPHA_PRE_MULTIPLIED_BIT_KHR, + VK_COMPOSITE_ALPHA_POST_MULTIPLIED_BIT_KHR, + VK_COMPOSITE_ALPHA_INHERIT_BIT_KHR, + }; + for (uint32_t i = 0; i < sizeof(compositeAlphaFlags) / sizeof(compositeAlphaFlags[0]); i++) { + if (surfCapabilities.supportedCompositeAlpha & compositeAlphaFlags[i]) { + compositeAlpha = compositeAlphaFlags[i]; + break; + } + } + + VkSwapchainKHR swapchain; + VkSwapchainCreateInfoKHR swapchainCreateInfo = {}; + swapchainCreateInfo.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR; + swapchainCreateInfo.pNext = NULL; + swapchainCreateInfo.surface = surface; + swapchainCreateInfo.minImageCount = desiredNumberOfSwapChainImages; + swapchainCreateInfo.imageFormat = format; + swapchainCreateInfo.imageExtent.width = swapchainExtent.width; + swapchainCreateInfo.imageExtent.height = swapchainExtent.height; + swapchainCreateInfo.preTransform = preTransform; + swapchainCreateInfo.compositeAlpha = compositeAlpha; + swapchainCreateInfo.imageArrayLayers = 1; + swapchainCreateInfo.presentMode = swapchainPresentMode; + swapchainCreateInfo.oldSwapchain = VK_NULL_HANDLE; + swapchainCreateInfo.clipped = true; + swapchainCreateInfo.imageColorSpace = VK_COLORSPACE_SRGB_NONLINEAR_KHR; + swapchainCreateInfo.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; + swapchainCreateInfo.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE; + swapchainCreateInfo.queueFamilyIndexCount = 0; + swapchainCreateInfo.pQueueFamilyIndices = NULL; + uint32_t queueFamilyIndices[2] = {(uint32_t)graphicsQueueFamilyIndex, (uint32_t)presentQueueFamilyIndex}; + if (graphicsQueueFamilyIndex != presentQueueFamilyIndex) { + // If the graphics and present queues are from different queue families, + // we either have to explicitly transfer ownership of images between + // the queues, or we have to create the swapchain with imageSharingMode + // as VK_SHARING_MODE_CONCURRENT + swapchainCreateInfo.imageSharingMode = VK_SHARING_MODE_CONCURRENT; + swapchainCreateInfo.queueFamilyIndexCount = 2; + swapchainCreateInfo.pQueueFamilyIndices = queueFamilyIndices; + } + + result = vkCreateSwapchainKHR(device, &swapchainCreateInfo, NULL, &swapchain); + assert(result == VK_SUCCESS); + + uint32_t swapchainImageCount; + result = vkGetSwapchainImagesKHR(device, swapchain, &swapchainImageCount, NULL); + assert(result == VK_SUCCESS); + + VkImage *swapchainImages = (VkImage *)malloc(swapchainImageCount * sizeof(VkImage)); + assert(swapchainImages); + result = vkGetSwapchainImagesKHR(device, swapchain, &swapchainImageCount, swapchainImages); + assert(result == VK_SUCCESS); + + typedef struct _swap_chain_buffers { + VkImage image; + VkImageView view; + } swap_chain_buffer; + + std::vector buffers; + buffers.resize(swapchainImageCount); + for (uint32_t i = 0; i < swapchainImageCount; i++) { + buffers[i].image = swapchainImages[i]; + } + free(swapchainImages); + + for (uint32_t i = 0; i < swapchainImageCount; i++) { + VkImageViewCreateInfo color_image_view = {}; + color_image_view.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; + color_image_view.pNext = NULL; + color_image_view.flags = 0; + color_image_view.image = buffers[i].image; + color_image_view.viewType = VK_IMAGE_VIEW_TYPE_2D; + color_image_view.format = format; + color_image_view.components.r = VK_COMPONENT_SWIZZLE_R; + color_image_view.components.g = VK_COMPONENT_SWIZZLE_G; + color_image_view.components.b = VK_COMPONENT_SWIZZLE_B; + color_image_view.components.a = VK_COMPONENT_SWIZZLE_A; + color_image_view.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; + color_image_view.subresourceRange.baseMipLevel = 0; + color_image_view.subresourceRange.levelCount = 1; + color_image_view.subresourceRange.baseArrayLayer = 0; + color_image_view.subresourceRange.layerCount = 1; + + result = vkCreateImageView(device, &color_image_view, NULL, &buffers[i].view); + assert(result == VK_SUCCESS); + } + + //Window show and event loop