Changeset bfd620e in opengl-game


Ignore:
Timestamp:
Jul 12, 2019, 5:23:57 PM (5 years ago)
Author:
Dmitry Portnoy <dmitry.portnoy@…>
Branches:
feature/imgui-sdl, master, points-test
Children:
4befb76
Parents:
321272c
Message:

Create the swap chain

File:
1 edited

Legend:

Unmodified
Added
Removed
  • vulkan-game.cpp

    r321272c rbfd620e  
    1717#include <cstdlib>
    1818#include <optional>
     19#include <algorithm>
    1920
    2021#include "game-gui-sdl.hpp"
    2122
    2223using namespace std;
    23 using namespace glm;
     24//using namespace glm;
    2425
    2526const int SCREEN_WIDTH = 800;
    2627const int SCREEN_HEIGHT = 600;
    27 
    28 const vector<const char*> validationLayers = {
    29     "VK_LAYER_KHRONOS_validation"
    30 };
    3128
    3229#ifdef NDEBUG
     
    3633#endif
    3734
     35const vector<const char*> validationLayers = {
     36   "VK_LAYER_KHRONOS_validation"
     37};
     38
     39const vector<const char*> deviceExtensions = {
     40   VK_KHR_SWAPCHAIN_EXTENSION_NAME
     41};
     42
    3843struct QueueFamilyIndices {
    3944    optional<uint32_t> graphicsFamily;
     
    4348        return graphicsFamily.has_value() && presentFamily.has_value();
    4449    }
     50};
     51
     52struct SwapChainSupportDetails {
     53    VkSurfaceCapabilitiesKHR capabilities;
     54    vector<VkSurfaceFormatKHR> formats;
     55    vector<VkPresentModeKHR> presentModes;
    4556};
    4657
     
    104115      VkQueue graphicsQueue;
    105116      VkQueue presentQueue;
     117
     118      VkSwapchainKHR swapChain;
     119      vector<VkImage> swapChainImages;
     120      VkFormat swapChainImageFormat;
     121      VkExtent2D swapChainExtent;
     122
     123      vector<VkImageView> swapChainImageViews;
    106124
    107125      // both SDL and GLFW create window functions return NULL on failure
     
    135153         pickPhysicalDevice();
    136154         createLogicalDevice();
     155         createSwapChain();
     156         createImageViews();
    137157      }
    138158
     
    247267         QueueFamilyIndices indices = findQueueFamilies(device);
    248268
    249          return indices.isComplete();
     269         bool extensionsSupported = checkDeviceExtensionSupport(device);
     270
     271         bool swapChainAdequate = false;
     272
     273         if (extensionsSupported) {
     274            SwapChainSupportDetails swapChainSupport = querySwapChainSupport(device);
     275            swapChainAdequate = !swapChainSupport.formats.empty() && !swapChainSupport.presentModes.empty();
     276         }
     277
     278         return indices.isComplete() && extensionsSupported && swapChainAdequate;
     279      }
     280
     281      bool checkDeviceExtensionSupport(VkPhysicalDevice device) {
     282         uint32_t extensionCount;
     283         vkEnumerateDeviceExtensionProperties(device, nullptr, &extensionCount, nullptr);
     284
     285         vector<VkExtensionProperties> availableExtensions(extensionCount);
     286         vkEnumerateDeviceExtensionProperties(device, nullptr, &extensionCount, availableExtensions.data());
     287
     288         set<string> requiredExtensions(deviceExtensions.begin(), deviceExtensions.end());
     289
     290         for (const auto& extension : availableExtensions) {
     291            requiredExtensions.erase(extension.extensionName);
     292         }
     293
     294         return requiredExtensions.empty();
    250295      }
    251296
     
    278323         createInfo.pEnabledFeatures = &deviceFeatures;
    279324
    280          createInfo.enabledExtensionCount = 0;
     325         createInfo.enabledExtensionCount = static_cast<uint32_t>(deviceExtensions.size());
     326         createInfo.ppEnabledExtensionNames = deviceExtensions.data();
    281327
    282328         // These fields are ignored  by up-to-date Vulkan implementations,
     
    354400      }
    355401
     402      SwapChainSupportDetails querySwapChainSupport(VkPhysicalDevice device) {
     403         SwapChainSupportDetails details;
     404
     405         vkGetPhysicalDeviceSurfaceCapabilitiesKHR(device, surface, &details.capabilities);
     406
     407         uint32_t formatCount;
     408         vkGetPhysicalDeviceSurfaceFormatsKHR(device, surface, &formatCount, nullptr);
     409
     410         if (formatCount != 0) {
     411            details.formats.resize(formatCount);
     412            vkGetPhysicalDeviceSurfaceFormatsKHR(device, surface, &formatCount, details.formats.data());
     413         }
     414
     415         uint32_t presentModeCount;
     416         vkGetPhysicalDeviceSurfacePresentModesKHR(device, surface, &presentModeCount, nullptr);
     417
     418         if (presentModeCount != 0) {
     419            details.presentModes.resize(presentModeCount);
     420            vkGetPhysicalDeviceSurfacePresentModesKHR(device, surface, &presentModeCount, details.presentModes.data());
     421         }
     422
     423         return details;
     424      }
     425
     426      VkSurfaceFormatKHR chooseSwapSurfaceFormat(const vector<VkSurfaceFormatKHR>& availableFormats) {
     427         for (const auto& availableFormat : availableFormats) {
     428            if (availableFormat.format == VK_FORMAT_B8G8R8A8_UNORM && availableFormat.colorSpace == VK_COLOR_SPACE_SRGB_NONLINEAR_KHR) {
     429               return availableFormat;
     430            }
     431         }
     432
     433         return availableFormats[0];
     434      }
     435
     436      VkPresentModeKHR chooseSwapPresentMode(const vector<VkPresentModeKHR>& availablePresentModes) {
     437         VkPresentModeKHR bestMode = VK_PRESENT_MODE_FIFO_KHR;
     438
     439         for (const auto& availablePresentMode : availablePresentModes) {
     440            if (availablePresentMode == VK_PRESENT_MODE_MAILBOX_KHR) {
     441               return availablePresentMode;
     442            } else if (availablePresentMode == VK_PRESENT_MODE_IMMEDIATE_KHR) {
     443               bestMode = availablePresentMode;
     444            }
     445         }
     446
     447         return bestMode;
     448      }
     449
     450      VkExtent2D chooseSwapExtent(const VkSurfaceCapabilitiesKHR& capabilities) {
     451         if (capabilities.currentExtent.width != numeric_limits<uint32_t>::max()) {
     452            return capabilities.currentExtent;
     453         } else {
     454            VkExtent2D actualExtent = { SCREEN_WIDTH, SCREEN_HEIGHT };
     455
     456            actualExtent.width = max(capabilities.minImageExtent.width, min(capabilities.maxImageExtent.width, actualExtent.width));
     457            actualExtent.height = max(capabilities.minImageExtent.height, min(capabilities.maxImageExtent.height, actualExtent.height));
     458
     459            return actualExtent;
     460         }
     461      }
     462
    356463      void populateDebugMessengerCreateInfo(VkDebugUtilsMessengerCreateInfoEXT& createInfo) {
    357464         createInfo = {};
     
    374481
    375482         return extensions;
     483      }
     484
     485      void createSwapChain() {
     486         SwapChainSupportDetails swapChainSupport = querySwapChainSupport(physicalDevice);
     487
     488         VkSurfaceFormatKHR surfaceFormat = chooseSwapSurfaceFormat(swapChainSupport.formats);
     489         VkPresentModeKHR presentMode = chooseSwapPresentMode(swapChainSupport.presentModes);
     490         VkExtent2D extent = chooseSwapExtent(swapChainSupport.capabilities);
     491
     492         uint32_t imageCount = swapChainSupport.capabilities.minImageCount + 1;
     493         if (swapChainSupport.capabilities.maxImageCount > 0 &&
     494               imageCount > swapChainSupport.capabilities.maxImageCount) {
     495            imageCount = swapChainSupport.capabilities.maxImageCount;
     496         }
     497
     498         VkSwapchainCreateInfoKHR createInfo = {};
     499
     500         createInfo.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
     501         createInfo.surface = surface;
     502         createInfo.minImageCount = imageCount;
     503         createInfo.imageFormat = surfaceFormat.format;
     504         createInfo.imageColorSpace = surfaceFormat.colorSpace;
     505         createInfo.imageExtent = extent;
     506         createInfo.imageArrayLayers = 1;
     507         createInfo.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
     508
     509         QueueFamilyIndices indices = findQueueFamilies(physicalDevice);
     510         uint32_t queueFamilyIndices[] = {indices.graphicsFamily.value(), indices.presentFamily.value()};
     511
     512         if (indices.graphicsFamily != indices.presentFamily) {
     513            createInfo.imageSharingMode = VK_SHARING_MODE_CONCURRENT;
     514            createInfo.queueFamilyIndexCount = 2;
     515            createInfo.pQueueFamilyIndices = queueFamilyIndices;
     516         } else {
     517            createInfo.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE;
     518            createInfo.queueFamilyIndexCount = 0; // Optional
     519            createInfo.pQueueFamilyIndices = nullptr;
     520         }
     521
     522         createInfo.preTransform = swapChainSupport.capabilities.currentTransform;
     523         createInfo.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;
     524         createInfo.presentMode = presentMode;
     525         createInfo.clipped = VK_TRUE;
     526         createInfo.oldSwapchain = VK_NULL_HANDLE;
     527
     528         if (vkCreateSwapchainKHR(device, &createInfo, nullptr, &swapChain) != VK_SUCCESS) {
     529            throw runtime_error("failed to create swap chain!");
     530         }
     531
     532         vkGetSwapchainImagesKHR(device, swapChain, &imageCount, nullptr);
     533         swapChainImages.resize(imageCount);
     534         vkGetSwapchainImagesKHR(device, swapChain, &imageCount, swapChainImages.data());
     535
     536         swapChainImageFormat = surfaceFormat.format;
     537         swapChainExtent = extent;
     538      }
     539
     540      void createImageViews() {
     541         swapChainImageViews.resize(swapChainImages.size());
     542
     543         for (size_t i=0; i<swapChainImages.size(); i++) {
     544            VkImageViewCreateInfo createInfo = {};
     545            createInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
     546            createInfo.image = swapChainImages[i];
     547
     548            createInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
     549            createInfo.format = swapChainImageFormat;
     550
     551            createInfo.components.r = VK_COMPONENT_SWIZZLE_IDENTITY;
     552            createInfo.components.g = VK_COMPONENT_SWIZZLE_IDENTITY;
     553            createInfo.components.b = VK_COMPONENT_SWIZZLE_IDENTITY;
     554            createInfo.components.a = VK_COMPONENT_SWIZZLE_IDENTITY;
     555
     556            createInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
     557            createInfo.subresourceRange.baseMipLevel = 0;
     558            createInfo.subresourceRange.levelCount = 1;
     559            createInfo.subresourceRange.baseArrayLayer = 0;
     560            createInfo.subresourceRange.layerCount = 1;
     561
     562            if (vkCreateImageView(device, &createInfo, nullptr, &swapChainImageViews[i]) != VK_SUCCESS) {
     563               throw runtime_error("failed to create image views!");
     564            }
     565         }
    376566      }
    377567
     
    392582                  quit = true;
    393583               }
    394             }
    395          }
    396 
    397          SDL_FillRect(sdlSurface, nullptr, SDL_MapRGB(sdlSurface->format, 0xFF, 0xFF, 0xFF));
    398 
    399          SDL_UpdateWindowSurface(window);
     584
     585               /*
     586               SDL_FillRect(sdlSurface, nullptr, SDL_MapRGB(sdlSurface->format, 0xFF, 0xFF, 0xFF));
     587
     588               SDL_UpdateWindowSurface(window);
     589               */
     590            }
     591         }
    400592      }
    401593
    402594      void cleanup() {
     595         for (auto imageView : swapChainImageViews) {
     596            vkDestroyImageView(device, imageView, nullptr);
     597         }
     598
     599         vkDestroySwapchainKHR(device, swapChain, nullptr);
    403600         vkDestroyDevice(device, nullptr);
    404601
     
    426623#endif
    427624
    428    mat4 matrix;
    429    vec4 vec;
    430    vec4 test = matrix * vec;
     625   glm::mat4 matrix;
     626   glm::vec4 vec;
     627   glm::vec4 test = matrix * vec;
    431628
    432629   cout << "Starting Vulkan game..." << endl;
Note: See TracChangeset for help on using the changeset viewer.