Index: vulkan-game.cpp
===================================================================
--- vulkan-game.cpp	(revision c8c6da81cef243ff820763829abe316ce3d2e34a)
+++ vulkan-game.cpp	(revision e5d4acafffa467127203d6f24eff7cd0da816759)
@@ -332,17 +332,12 @@
          createRenderPass();
 
-         createDescriptorSetLayout(scenePipeline);
-         createGraphicsPipeline("shaders/vert.spv", "shaders/frag.spv", scenePipeline);
-
-         createDescriptorSetLayout(overlayPipeline);
-         createGraphicsPipeline("shaders/vert.spv", "shaders/frag.spv", overlayPipeline);
-
          createCommandPool();
-         createDepthResources();
-         createFramebuffers();
 
          createImageResources("textures/texture.jpg", textureImage, textureImageMemory, textureImageView);
          createImageResourcesFromSDLTexture(uiOverlay, sdlOverlayImage, sdlOverlayImageMemory, sdlOverlayImageView);
          createTextureSampler();
+
+         createSceneDescriptorSetLayout(scenePipeline);
+         createOverlayDescriptorSetLayout(overlayPipeline);
 
          createShaderBuffers(scenePipeline, {
@@ -357,36 +352,19 @@
             {{-0.5f,  0.5f,  0.0f}, {1.0f, 1.0f, 1.0f}, {0.0f, 0.0f}}
          }, {
-            0,  1,  2,  2,  3,  0,
-            4,  5,  6,  6,  7,  4
+            0, 1, 2, 2, 3, 0,
+            4, 5, 6, 6, 7, 4
          });
 
          createShaderBuffers(overlayPipeline, {
-            // Filler vertices to increase the overlay vertex indices to at least 8
-            {{-1.0f, -1.0f,  3.0f}, {1.0f, 1.0f, 1.0f}, {0.0f, 0.0f}},
-            {{-1.0f, -1.0f,  3.0f}, {1.0f, 1.0f, 1.0f}, {0.0f, 0.0f}},
-            {{-1.0f, -1.0f,  3.0f}, {1.0f, 1.0f, 1.0f}, {0.0f, 0.0f}},
-            {{-1.0f, -1.0f,  3.0f}, {1.0f, 1.0f, 1.0f}, {0.0f, 0.0f}},
-            {{-1.0f, -1.0f,  3.0f}, {1.0f, 1.0f, 1.0f}, {0.0f, 0.0f}},
-            {{-1.0f, -1.0f,  3.0f}, {1.0f, 1.0f, 1.0f}, {0.0f, 0.0f}},
-            {{-1.0f, -1.0f,  3.0f}, {1.0f, 1.0f, 1.0f}, {0.0f, 0.0f}},
-            {{-1.0f, -1.0f,  3.0f}, {1.0f, 1.0f, 1.0f}, {0.0f, 0.0f}},
-
-            {{-1.0f,  1.0f,  0.0f}, {1.0f, 0.0f, 0.0f}, {0.0f, 1.0f}},
-            {{ 1.0f,  1.0f,  0.0f}, {0.0f, 1.0f, 0.0f}, {1.0f, 1.0f}},
-            {{ 1.0f, -1.0f,  0.0f}, {0.0f, 0.0f, 1.0f}, {1.0f, 0.0f}},
-            {{-1.0f, -1.0f,  0.0f}, {1.0f, 1.0f, 1.0f}, {0.0f, 0.0f}}
+            {{-1.0f,  1.0f,  0.0f}, {0.0f, 0.0f, 0.0f}, {0.0f, 1.0f}},
+            {{ 1.0f,  1.0f,  0.0f}, {0.0f, 0.0f, 0.0f}, {1.0f, 1.0f}},
+            {{ 1.0f, -1.0f,  0.0f}, {0.0f, 0.0f, 0.0f}, {1.0f, 0.0f}},
+            {{-1.0f, -1.0f,  0.0f}, {0.0f, 0.0f, 0.0f}, {0.0f, 0.0f}}
          }, {
-            8,  9, 10, 10, 11,  8
+            0, 1, 2, 2,3, 0
          });
 
-         createUniformBuffers();
-
-         createDescriptorPool(scenePipeline);
-         createDescriptorSets(scenePipeline);
-
-         createDescriptorPool(overlayPipeline);
-         createDescriptorSets(overlayPipeline);
-
-         createCommandBuffers();
+         createBufferResources();
+
          createSyncObjects();
       }
@@ -794,5 +772,5 @@
       }
 
-      void createDescriptorSetLayout(GraphicsPipelineInfo& info) {
+      void createSceneDescriptorSetLayout(GraphicsPipelineInfo& info) {
          VkDescriptorSetLayoutBinding uboLayoutBinding = {};
          uboLayoutBinding.binding = 0;
@@ -817,4 +795,23 @@
 
          array<VkDescriptorSetLayoutBinding, 3> bindings = { uboLayoutBinding, samplerLayoutBinding, overlaySamplerLayoutBinding };
+         VkDescriptorSetLayoutCreateInfo layoutInfo = {};
+         layoutInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
+         layoutInfo.bindingCount = static_cast<uint32_t>(bindings.size());
+         layoutInfo.pBindings = bindings.data();
+
+         if (vkCreateDescriptorSetLayout(device, &layoutInfo, nullptr, &info.descriptorSetLayout) != VK_SUCCESS) {
+            throw runtime_error("failed to create descriptor set layout!");
+         }
+      }
+
+      void createOverlayDescriptorSetLayout(GraphicsPipelineInfo& info) {
+         VkDescriptorSetLayoutBinding samplerLayoutBinding = {};
+         samplerLayoutBinding.binding = 0;
+         samplerLayoutBinding.descriptorCount = 1;
+         samplerLayoutBinding.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
+         samplerLayoutBinding.pImmutableSamplers = nullptr;
+         samplerLayoutBinding.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
+
+         array<VkDescriptorSetLayoutBinding, 1> bindings = { samplerLayoutBinding };
          VkDescriptorSetLayoutCreateInfo layoutInfo = {};
          layoutInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
@@ -1512,5 +1509,5 @@
       }
 
-      void createDescriptorPool(GraphicsPipelineInfo& info) {
+      void createSceneDescriptorPool(GraphicsPipelineInfo& info) {
          array<VkDescriptorPoolSize, 3> poolSizes = {};
          poolSizes[0].type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
@@ -1532,5 +1529,5 @@
       }
 
-      void createDescriptorSets(GraphicsPipelineInfo& info) {
+      void createSceneDescriptorSets(GraphicsPipelineInfo& info) {
          vector<VkDescriptorSetLayout> layouts(swapChainImages.size(), info.descriptorSetLayout);
 
@@ -1593,4 +1590,56 @@
             descriptorWrites[2].pImageInfo = &overlayImageInfo;
             descriptorWrites[2].pTexelBufferView = nullptr;
+
+            vkUpdateDescriptorSets(device, static_cast<uint32_t>(descriptorWrites.size()), descriptorWrites.data(), 0, nullptr);
+         }
+      }
+
+      void createOverlayDescriptorPool(GraphicsPipelineInfo& info) {
+         array<VkDescriptorPoolSize, 1> poolSizes = {};
+         poolSizes[0].type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
+         poolSizes[0].descriptorCount = static_cast<uint32_t>(swapChainImages.size());
+
+         VkDescriptorPoolCreateInfo poolInfo = {};
+         poolInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
+         poolInfo.poolSizeCount = static_cast<uint32_t>(poolSizes.size());
+         poolInfo.pPoolSizes = poolSizes.data();
+         poolInfo.maxSets = static_cast<uint32_t>(swapChainImages.size());
+
+         if (vkCreateDescriptorPool(device, &poolInfo, nullptr, &info.descriptorPool) != VK_SUCCESS) {
+            throw runtime_error("failed to create descriptor pool!");
+         }
+      }
+
+      void createOverlayDescriptorSets(GraphicsPipelineInfo& info) {
+         vector<VkDescriptorSetLayout> layouts(swapChainImages.size(), info.descriptorSetLayout);
+
+         VkDescriptorSetAllocateInfo allocInfo = {};
+         allocInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
+         allocInfo.descriptorPool = info.descriptorPool;
+         allocInfo.descriptorSetCount = static_cast<uint32_t>(swapChainImages.size());
+         allocInfo.pSetLayouts = layouts.data();
+
+         info.descriptorSets.resize(swapChainImages.size());
+         if (vkAllocateDescriptorSets(device, &allocInfo, info.descriptorSets.data()) != VK_SUCCESS) {
+            throw runtime_error("failed to allocate descriptor sets!");
+         }
+
+         for (size_t i = 0; i < swapChainImages.size(); i++) {
+            VkDescriptorImageInfo imageInfo = {};
+            imageInfo.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
+            imageInfo.imageView = sdlOverlayImageView;
+            imageInfo.sampler = textureSampler;
+
+            array<VkWriteDescriptorSet, 1> descriptorWrites = {};
+
+            descriptorWrites[0].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
+            descriptorWrites[0].dstSet = info.descriptorSets[i];
+            descriptorWrites[0].dstBinding = 0;
+            descriptorWrites[0].dstArrayElement = 0;
+            descriptorWrites[0].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
+            descriptorWrites[0].descriptorCount = 1;
+            descriptorWrites[0].pBufferInfo = nullptr;
+            descriptorWrites[0].pImageInfo = &imageInfo;
+            descriptorWrites[0].pTexelBufferView = nullptr;
 
             vkUpdateDescriptorSets(device, static_cast<uint32_t>(descriptorWrites.size()), descriptorWrites.data(), 0, nullptr);
@@ -1845,16 +1894,19 @@
          createRenderPass();
 
-         createGraphicsPipeline("shaders/scene-vert.spv", "shaders/scene-frag.spv", scenePipeline);
-         createGraphicsPipeline("shaders/overlay-vert.spv", "shaders/overlay-frag.spv", overlayPipeline);
-
+         createBufferResources();
+      }
+
+      void createBufferResources() {
          createDepthResources();
          createFramebuffers();
          createUniformBuffers();
 
-         createDescriptorPool(scenePipeline);
-         createDescriptorSets(scenePipeline);
-
-         createDescriptorPool(overlayPipeline);
-         createDescriptorSets(overlayPipeline);
+         createGraphicsPipeline("shaders/scene-vert.spv", "shaders/scene-frag.spv", scenePipeline);
+         createSceneDescriptorPool(scenePipeline);
+         createSceneDescriptorSets(scenePipeline);
+
+         createGraphicsPipeline("shaders/overlay-vert.spv", "shaders/overlay-frag.spv", overlayPipeline);
+         createOverlayDescriptorPool(overlayPipeline);
+         createOverlayDescriptorSets(overlayPipeline);
 
          createCommandBuffers();
