Changeset b794178 in opengl-game for vulkan-game.cpp


Ignore:
Timestamp:
Oct 17, 2019, 9:30:18 PM (5 years ago)
Author:
Dmitry Portnoy <dmitry.portnoy@…>
Branches:
feature/imgui-sdl, master, points-test
Children:
e83b155
Parents:
771b33a
Message:

In vulkangame, add the ability to create vulkan resoirces and descriptor sets for shader uniforms (images and ubos)

File:
1 edited

Legend:

Unmodified
Added
Removed
  • vulkan-game.cpp

    r771b33a rb794178  
    99
    1010#include "utils.hpp"
    11 #include "vulkan-utils.hpp"
    1211
    1312using namespace std;
     13
     14struct UniformBufferObject {
     15   alignas(16) mat4 model;
     16   alignas(16) mat4 view;
     17   alignas(16) mat4 proj;
     18};
    1419
    1520VulkanGame::VulkanGame() {
     
    8489      cout << gui->getError() << endl;
    8590      return RTWO_ERROR;
     91   }
     92
     93   SDL_VERSION(&sdlVersion);
     94
     95   // In SDL 2.0.10 (currently, the latest), SDL_TEXTUREACCESS_TARGET is required to get a transparent overlay working
     96   // However, the latest SDL version available through homebrew on Mac is 2.0.9, which requires SDL_TEXTUREACCESS_STREAMING
     97   // I tried building sdl 2.0.10 (and sdl_image and sdl_ttf) from source on Mac, but had some issues, so this is easier
     98   // until the homebrew recipe is updated
     99   if (sdlVersion.major == 2 && sdlVersion.minor == 0 && sdlVersion.patch == 9) {
     100      uiOverlay = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_STREAMING,
     101         gui->getWindowWidth(), gui->getWindowHeight());
     102   } else {
     103      uiOverlay = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET,
     104         gui->getWindowWidth(), gui->getWindowHeight());
     105   }
     106
     107   if (uiOverlay == nullptr) {
     108      cout << "Unable to create blank texture! SDL Error: " << SDL_GetError() << endl;
     109   }
     110   if (SDL_SetTextureBlendMode(uiOverlay, SDL_BLENDMODE_BLEND) != 0) {
     111      cout << "Unable to set texture blend mode! SDL Error: " << SDL_GetError() << endl;
    86112   }
    87113
     
    107133   createCommandPool();
    108134
    109    graphicsPipelines.push_back(GraphicsPipeline_Vulkan(device, viewport, sizeof(Vertex)));
     135   createVulkanResources();
     136
     137   graphicsPipelines.push_back(GraphicsPipeline_Vulkan(device, renderPass, viewport, sizeof(Vertex)));
    110138
    111139   graphicsPipelines.back().addAttribute(VK_FORMAT_R32G32B32_SFLOAT, offset_of(&Vertex::pos));
     
    113141   graphicsPipelines.back().addAttribute(VK_FORMAT_R32G32_SFLOAT, offset_of(&Vertex::texCoord));
    114142
     143   graphicsPipelines.back().addDescriptorInfo(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
     144      VK_SHADER_STAGE_VERTEX_BIT, &uniformBufferInfoList);
     145   graphicsPipelines.back().addDescriptorInfo(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
     146      VK_SHADER_STAGE_FRAGMENT_BIT, &floorTextureImageDescriptor);
     147
     148   graphicsPipelines.back().createDescriptorSetLayout();
    115149   graphicsPipelines.back().createPipeline("shaders/scene-vert.spv", "shaders/scene-frag.spv");
    116 
    117    graphicsPipelines.push_back(GraphicsPipeline_Vulkan(device, viewport, sizeof(OverlayVertex)));
     150   graphicsPipelines.back().createDescriptorPool(swapChainImages);
     151   graphicsPipelines.back().createDescriptorSets(swapChainImages);
     152
     153   graphicsPipelines.push_back(GraphicsPipeline_Vulkan(device, renderPass, viewport, sizeof(OverlayVertex)));
    118154
    119155   graphicsPipelines.back().addAttribute(VK_FORMAT_R32G32B32_SFLOAT, offset_of(&OverlayVertex::pos));
    120156   graphicsPipelines.back().addAttribute(VK_FORMAT_R32G32_SFLOAT, offset_of(&OverlayVertex::texCoord));
    121157
     158   graphicsPipelines.back().addDescriptorInfo(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
     159      VK_SHADER_STAGE_FRAGMENT_BIT, &sdlOverlayImageDescriptor);
     160
     161   graphicsPipelines.back().createDescriptorSetLayout();
    122162   graphicsPipelines.back().createPipeline("shaders/overlay-vert.spv", "shaders/overlay-frag.spv");
     163   graphicsPipelines.back().createDescriptorPool(swapChainImages);
     164   graphicsPipelines.back().createDescriptorSets(swapChainImages);
    123165
    124166   cout << "Created " << graphicsPipelines.size() << " graphics pipelines" << endl;
     
    189231   cleanupSwapChain();
    190232
     233   for (GraphicsPipeline_Vulkan pipeline : graphicsPipelines) {
     234      pipeline.cleanupBuffers();
     235   }
     236
    191237   vkDestroyCommandPool(device, commandPool, nullptr);
    192238   vkDestroyDevice(device, nullptr);
     
    198244
    199245   vkDestroyInstance(instance, nullptr);
     246
     247   // TODO: Check if any of these functions accept null parameters
     248   // If they do, I don't need to check for that
     249
     250   if (uiOverlay != nullptr) {
     251      SDL_DestroyTexture(uiOverlay);
     252      uiOverlay = nullptr;
     253   }
    200254
    201255   SDL_DestroyRenderer(renderer);
     
    343397   QueueFamilyIndices indices = VulkanUtils::findQueueFamilies(physicalDevice, surface);
    344398
    345    vector<VkDeviceQueueCreateInfo> queueCreateInfos;
     399   vector<VkDeviceQueueCreateInfo> queueCreateInfoList;
    346400   set<uint32_t> uniqueQueueFamilies = { indices.graphicsFamily.value(), indices.presentFamily.value() };
    347401
     
    354408      queueCreateInfo.pQueuePriorities = &queuePriority;
    355409
    356       queueCreateInfos.push_back(queueCreateInfo);
     410      queueCreateInfoList.push_back(queueCreateInfo);
    357411   }
    358412
     
    362416   VkDeviceCreateInfo createInfo = {};
    363417   createInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
    364    createInfo.queueCreateInfoCount = static_cast<uint32_t>(queueCreateInfos.size());
    365    createInfo.pQueueCreateInfos = queueCreateInfos.data();
     418   createInfo.queueCreateInfoCount = static_cast<uint32_t>(queueCreateInfoList.size());
     419   createInfo.pQueueCreateInfos = queueCreateInfoList.data();
    366420
    367421   createInfo.pEnabledFeatures = &deviceFeatures;
     
    529583}
    530584
     585void VulkanGame::createVulkanResources() {
     586   createTextureSampler();
     587   createUniformBuffers();
     588
     589   // TODO: Make sure that Vulkan complains about these images not being destroyed and then destroy them
     590
     591   VulkanUtils::createVulkanImageFromFile(device, physicalDevice, commandPool, "textures/texture.jpg",
     592      floorTextureImage, graphicsQueue);
     593   VulkanUtils::createVulkanImageFromSDLTexture(device, physicalDevice, uiOverlay, sdlOverlayImage);
     594
     595   floorTextureImageDescriptor = {};
     596   floorTextureImageDescriptor.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
     597   floorTextureImageDescriptor.imageView = floorTextureImage.imageView;
     598   floorTextureImageDescriptor.sampler = textureSampler;
     599
     600   sdlOverlayImageDescriptor = {};
     601   sdlOverlayImageDescriptor.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
     602   sdlOverlayImageDescriptor.imageView = sdlOverlayImage.imageView;
     603   sdlOverlayImageDescriptor.sampler = textureSampler;
     604}
     605
     606void VulkanGame::createTextureSampler() {
     607   VkSamplerCreateInfo samplerInfo = {};
     608   samplerInfo.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
     609   samplerInfo.magFilter = VK_FILTER_LINEAR;
     610   samplerInfo.minFilter = VK_FILTER_LINEAR;
     611
     612   samplerInfo.addressModeU = VK_SAMPLER_ADDRESS_MODE_REPEAT;
     613   samplerInfo.addressModeV = VK_SAMPLER_ADDRESS_MODE_REPEAT;
     614   samplerInfo.addressModeW = VK_SAMPLER_ADDRESS_MODE_REPEAT;
     615
     616   samplerInfo.anisotropyEnable = VK_TRUE;
     617   samplerInfo.maxAnisotropy = 16;
     618   samplerInfo.borderColor = VK_BORDER_COLOR_INT_OPAQUE_BLACK;
     619   samplerInfo.unnormalizedCoordinates = VK_FALSE;
     620   samplerInfo.compareEnable = VK_FALSE;
     621   samplerInfo.compareOp = VK_COMPARE_OP_ALWAYS;
     622   samplerInfo.mipmapMode = VK_SAMPLER_MIPMAP_MODE_LINEAR;
     623   samplerInfo.mipLodBias = 0.0f;
     624   samplerInfo.minLod = 0.0f;
     625   samplerInfo.maxLod = 0.0f;
     626
     627   if (vkCreateSampler(device, &samplerInfo, nullptr, &textureSampler) != VK_SUCCESS) {
     628      throw runtime_error("failed to create texture sampler!");
     629   }
     630}
     631
     632void VulkanGame::createUniformBuffers() {
     633   VkDeviceSize bufferSize = sizeof(UniformBufferObject);
     634
     635   uniformBuffers.resize(swapChainImages.size());
     636   uniformBuffersMemory.resize(swapChainImages.size());
     637   uniformBufferInfoList.resize(swapChainImages.size());
     638
     639   for (size_t i = 0; i < swapChainImages.size(); i++) {
     640      VulkanUtils::createBuffer(device, physicalDevice, bufferSize, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,
     641         VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
     642         uniformBuffers[i], uniformBuffersMemory[i]);
     643
     644      uniformBufferInfoList[i].buffer = uniformBuffers[i];
     645      uniformBufferInfoList[i].offset = 0;
     646      uniformBufferInfoList[i].range = sizeof(UniformBufferObject);
     647   }
     648}
     649
    531650void VulkanGame::cleanupSwapChain() {
     651   for (GraphicsPipeline_Vulkan pipeline : graphicsPipelines) {
     652      pipeline.cleanup();
     653   }
     654
    532655   vkDestroyRenderPass(device, renderPass, nullptr);
    533656
    534    for (auto imageView : swapChainImageViews) {
     657   for (VkImageView imageView : swapChainImageViews) {
    535658      vkDestroyImageView(device, imageView, nullptr);
    536659   }
Note: See TracChangeset for help on using the changeset viewer.