summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--assets/shaders/present.frag10
-rw-r--r--src/window.cpp164
-rw-r--r--src/window.hpp2
3 files changed, 130 insertions, 46 deletions
diff --git a/assets/shaders/present.frag b/assets/shaders/present.frag
index 695f7bd..427468c 100644
--- a/assets/shaders/present.frag
+++ b/assets/shaders/present.frag
@@ -1,16 +1,10 @@
#version 450
-layout (binding = 0) uniform sampler2D samplerColor;
-
layout (location = 0) in vec2 inUV;
layout (location = 0) out vec4 outFragColor;
void main()
{
- vec4 color = texture(samplerColor, inUV);
- if (color.w == 0) {
- discard;
- }
- outFragColor = color;
-} \ No newline at end of file
+ outFragColor = vec4(0, 0, 0, 1);
+}
diff --git a/src/window.cpp b/src/window.cpp
index dda6efe..4d816ca 100644
--- a/src/window.cpp
+++ b/src/window.cpp
@@ -1,4 +1,3 @@
-#include <vulkan/vulkan_core.h>
#define GLFW_INCLUDE_NONE
#define GLFW_INCLUDE_VULKAN
@@ -33,6 +32,7 @@ unsigned int presentFamilyIndex;
/*
* Instantiation
*/
+bool shouldRecreateSwapchain = false;
unsigned int CURRENT_FRAME = 0;
unsigned int selectedSurfaceIndex = -1u;
unsigned int selectedPresentIndex = -1u;
@@ -43,16 +43,21 @@ VkPresentModeKHR vkPresentModeKHR;
VkExtent2D extent;
VkImage *swapchainImages = nullptr;
VkImageView *swapchainImageViews = nullptr;
+VkSampler presentSampler;
VkRenderPass renderPass;
VkDescriptorSetLayout vkDescriptorSetLayout;
+/*
+VkDescriptorPool presentDescriptorPool;
+VkDescriptorSet *presentDescriptorSets = nullptr;
+*/
VkPipelineLayout pipelineLayout;
VkPipeline graphicsPipeline;
VkFramebuffer *swapchainFramebuffers = nullptr;
VkCommandPool vkCommandPool;
-VkCommandBuffer commandBuffer;
-VkSemaphore imageAvailableSemaphore;
-VkSemaphore renderFinishedSemaphore;
-VkFence inFlightFence;
+VkCommandBuffer presentCommandBuffers[MAX_FRAMES_IN_FLIGHT];
+VkSemaphore presentImageAvailableSemaphores[MAX_FRAMES_IN_FLIGHT];
+VkSemaphore presentRenderFinishedSemaphores[MAX_FRAMES_IN_FLIGHT];
+VkFence presentInFlightFences[MAX_FRAMES_IN_FLIGHT];
const std::vector<const char *> REQUIRED_EXTENSIONS = std::vector<const char *> {
VK_KHR_SWAPCHAIN_EXTENSION_NAME
@@ -350,6 +355,28 @@ void InitVulkan() {
vkGetDeviceQueue(vkDevice, graphicsFamilyIndex, 0, &graphicsQueue);
vkGetDeviceQueue(vkDevice, presentFamilyIndex, 0, &presentQueue);
}
+
+ // generic present sampler
+ VkSamplerCreateInfo samplerCreateInfo{};
+ samplerCreateInfo.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
+ samplerCreateInfo.flags = 0U;
+ samplerCreateInfo.magFilter = VK_FILTER_NEAREST;
+ samplerCreateInfo.minFilter = VK_FILTER_NEAREST;
+ samplerCreateInfo.mipmapMode = VK_SAMPLER_MIPMAP_MODE_LINEAR;
+ samplerCreateInfo.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
+ samplerCreateInfo.addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
+ samplerCreateInfo.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
+ samplerCreateInfo.mipLodBias = 0.0f;
+ samplerCreateInfo.anisotropyEnable = VK_FALSE;
+ samplerCreateInfo.maxAnisotropy = 1.0f;
+ samplerCreateInfo.compareEnable = VK_FALSE;
+ samplerCreateInfo.compareOp = {};
+ samplerCreateInfo.minLod = 0.0f;
+ samplerCreateInfo.maxLod = 1.0f;
+ samplerCreateInfo.borderColor = VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE;
+ samplerCreateInfo.unnormalizedCoordinates = {};
+
+ vkCreateSampler(vkDevice, &samplerCreateInfo, vkAllocator, &presentSampler);
}
void CreateSwapchain() {
@@ -624,24 +651,55 @@ void CreateGraphicsPipeline() {
* PipelineLayout + DescriptorSets
*/
+ /*
VkDescriptorSetLayoutBinding imageSamplerLayoutBinding{};
imageSamplerLayoutBinding.binding = 0;
imageSamplerLayoutBinding.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
imageSamplerLayoutBinding.descriptorCount = 1;
imageSamplerLayoutBinding.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
imageSamplerLayoutBinding.pImmutableSamplers = nullptr;
+ */
VkDescriptorSetLayoutCreateInfo descriptorSetLayoutCreateInfo{};
descriptorSetLayoutCreateInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
descriptorSetLayoutCreateInfo.flags = 0;
+ descriptorSetLayoutCreateInfo.bindingCount = 0;
+ descriptorSetLayoutCreateInfo.pBindings = nullptr;
+ /*
descriptorSetLayoutCreateInfo.bindingCount = 1;
descriptorSetLayoutCreateInfo.pBindings = &imageSamplerLayoutBinding;
+ */
auto result = vkCreateDescriptorSetLayout(vkDevice, &descriptorSetLayoutCreateInfo, vkAllocator, &vkDescriptorSetLayout);
if (result != VK_SUCCESS) {
throw "failed to create descriptor set layout";
}
+ /*
+ VkDescriptorPoolSize vkDescriptorPoolSize{};
+ vkDescriptorPoolSize.descriptorCount = swapchainLength;
+ vkDescriptorPoolSize.type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
+
+ VkDescriptorPoolCreateInfo descriptorPoolCreateInfo{};
+ descriptorPoolCreateInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
+ descriptorPoolCreateInfo.flags = 0;
+ descriptorPoolCreateInfo.maxSets = 1;
+ descriptorPoolCreateInfo.poolSizeCount = 1;
+ descriptorPoolCreateInfo.pPoolSizes = &vkDescriptorPoolSize;
+ descriptorPoolCreateInfo.pNext = nullptr;
+
+ vkCreateDescriptorPool(vkDevice, &descriptorPoolCreateInfo, vkAllocator, &presentDescriptorPool);
+
+ VkDescriptorSetAllocateInfo allocInfo{};
+ allocInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
+ allocInfo.descriptorPool = presentDescriptorPool;
+ allocInfo.descriptorSetCount = 1;
+ allocInfo.pSetLayouts = &vkDescriptorSetLayout;
+ allocInfo.pNext = nullptr;
+
+ vkAllocateDescriptorSets(vkDevice, &allocInfo, presentDescriptorSets);
+ */
+
VkPipelineLayoutCreateInfo pipelineLayoutInfo{};
pipelineLayoutInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
pipelineLayoutInfo.setLayoutCount = 1;
@@ -680,9 +738,10 @@ void CreateGraphicsPipeline() {
throw "failed to create graphics pipeline.";
}
- VkWriteDescriptorSet writeDescriptorSets[2];
- VkDescriptorImageInfo descriptorImageInfo[2];
- for (long i = 0; i < 2; ++i) {
+ /*
+ VkWriteDescriptorSet writeDescriptorSets[3];
+ VkDescriptorImageInfo descriptorImageInfo[3];
+ for (long i = 0; i < 3; ++i) {
writeDescriptorSets[i].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
// writeDescriptorSets[i].dstSet = VK_NULL_HANDLE;
writeDescriptorSets[i].dstBinding = 0U;
@@ -697,15 +756,16 @@ void CreateGraphicsPipeline() {
descriptorImageInfo[i].imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
}
- for (long i = 0; i < 2; ++i) {
- descriptorImageInfo[i].sampler = nullptr; // TODO
+ for (long i = 0; i < 3; ++i) {
+ descriptorImageInfo[i].sampler = presentSampler;
descriptorImageInfo[i].imageView = swapchainImageViews[i];
writeDescriptorSets[i].pImageInfo = &descriptorImageInfo[i];
- writeDescriptorSets[i].dstSet = nullptr; // TODO
+ writeDescriptorSets[i].dstSet = presentDescriptorSets[i];
}
vkUpdateDescriptorSets(vkDevice, 2, writeDescriptorSets, 0, nullptr);
+ */
vkDestroyShaderModule(vkDevice, fragShader, vkAllocator);
vkDestroyShaderModule(vkDevice, vertShader, vkAllocator);
@@ -754,9 +814,9 @@ void CreateCommandBuffer() {
allocInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
allocInfo.commandPool = vkCommandPool;
allocInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
- allocInfo.commandBufferCount = 1;
+ allocInfo.commandBufferCount = MAX_FRAMES_IN_FLIGHT;
- auto result = vkAllocateCommandBuffers(vkDevice, &allocInfo, &commandBuffer);
+ auto result = vkAllocateCommandBuffers(vkDevice, &allocInfo, presentCommandBuffers);
if (result != VK_SUCCESS) {
throw "failed to allocate command buffer";
}
@@ -770,12 +830,14 @@ void CreateSyncObjects() {
fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
fenceInfo.flags = VK_FENCE_CREATE_SIGNALED_BIT;
- auto result1 = vkCreateSemaphore(vkDevice, &semaphoreInfo, vkAllocator, &imageAvailableSemaphore);
- auto result2 = vkCreateSemaphore(vkDevice, &semaphoreInfo, vkAllocator, &renderFinishedSemaphore);
- auto result3 = vkCreateFence(vkDevice, &fenceInfo, vkAllocator, &inFlightFence);
- auto result = result1 == result2 && result2 == result3 && result3 == VK_SUCCESS;
- if (!result) {
- throw "failed to create sync objects";
+ for (long i = 0; i < MAX_FRAMES_IN_FLIGHT; ++i) {
+ auto result1 = vkCreateSemaphore(vkDevice, &semaphoreInfo, vkAllocator, &presentImageAvailableSemaphores[i]);
+ auto result2 = vkCreateSemaphore(vkDevice, &semaphoreInfo, vkAllocator, &presentRenderFinishedSemaphores[i]);
+ auto result3 = vkCreateFence(vkDevice, &fenceInfo, vkAllocator, &presentInFlightFences[i]);
+ auto result = result1 == result2 && result2 == result3 && result3 == VK_SUCCESS;
+ if (!result) {
+ throw "failed to create sync objects";
+ }
}
}
@@ -850,15 +912,26 @@ void DestroySwapchain() {
swapchainFramebuffers = CAFE_BABE(VkFramebuffer);
}
+void RecreateSwapchain() {
+ int width, height = 0;
+ glfwGetFramebufferSize(window, &width, &height);
+ while (width == 0 || height == 0) {
+ glfwGetFramebufferSize(window, &width, &height);
+ glfwWaitEvents();
+ }
+ DestroySwapchain();
+ CreateSwapchain();
+ CreateFramebuffers();
+ shouldRecreateSwapchain = false;
+}
+
void FramebufferResizeCallback(GLFWwindow *window, int width, int height) {
if (extent.width == width && extent.height != height) {
return;
}
- DestroySwapchain();
extent.width = width;
extent.height = height;
- CreateSwapchain();
- CreateFramebuffers();
+ shouldRecreateSwapchain = true;
}
void CreateWindow(PKEWindowProperties *wp) {
@@ -880,16 +953,21 @@ void CreateWindow(PKEWindowProperties *wp) {
void DestroyWindow() {
if (vkInstance == nullptr) return;
DestroySwapchain();
- vkDestroySemaphore(vkDevice, imageAvailableSemaphore, vkAllocator);
- vkDestroySemaphore(vkDevice, renderFinishedSemaphore, vkAllocator);
- vkDestroyFence(vkDevice, inFlightFence, vkAllocator);
+ for (long i = 0; i < MAX_FRAMES_IN_FLIGHT; ++i) {
+ vkDestroySemaphore(vkDevice, presentImageAvailableSemaphores[i], vkAllocator);
+ vkDestroySemaphore(vkDevice, presentRenderFinishedSemaphores[i], vkAllocator);
+ vkDestroyFence(vkDevice, presentInFlightFences[i], vkAllocator);
+ }
vkDestroyCommandPool(vkDevice, vkCommandPool, vkAllocator);
vkDestroyPipeline(vkDevice, graphicsPipeline, vkAllocator);
vkDestroyPipelineLayout(vkDevice, pipelineLayout, vkAllocator);
+ /*
+ vkDestroyDescriptorPool(vkDevice, presentDescriptorPool, vkAllocator);
+ */
vkDestroyDescriptorSetLayout(vkDevice, vkDescriptorSetLayout, vkAllocator);
vkDestroyRenderPass(vkDevice, renderPass, vkAllocator);
- DestroySwapchain();
vkDestroySurfaceKHR(vkInstance, vkSurfaceKHR, vkAllocator);
+ vkDestroySampler(vkDevice, presentSampler, vkAllocator);
vkDestroyDevice(vkDevice, vkAllocator);
if (VULKAN_DEBUG_REPORT) {
auto vkDestroyDebugReportCallbackEXT = (PFN_vkDestroyDebugReportCallbackEXT)vkGetInstanceProcAddr(vkInstance, "vkDestroyDebugReportCallbackEXT");
@@ -918,18 +996,25 @@ VkShaderModule UploadShader(AssetHandle handle) {
void PreRender() {}
void Render() {
- vkWaitForFences(vkDevice, 1, &inFlightFence, VK_TRUE, UINT64_MAX);
+ vkWaitForFences(vkDevice, 1, &presentInFlightFences[CURRENT_FRAME], VK_TRUE, UINT64_MAX);
uint32_t imageIndex;
- vkAcquireNextImageKHR(vkDevice, vkSwapchainKHR, UINT64_MAX, imageAvailableSemaphore, VK_NULL_HANDLE, &imageIndex);
+ auto result = vkAcquireNextImageKHR(vkDevice, vkSwapchainKHR, UINT64_MAX, presentImageAvailableSemaphores[CURRENT_FRAME], VK_NULL_HANDLE, &imageIndex);
+
+ if (result == VK_ERROR_OUT_OF_DATE_KHR) {
+ RecreateSwapchain();
+ return;
+ } else if (result != VK_SUCCESS && result != VK_SUBOPTIMAL_KHR) {
+ throw "failed to acquire swapchain";
+ }
- vkResetFences(vkDevice, 1, &inFlightFence);
+ vkResetFences(vkDevice, 1, &presentInFlightFences[CURRENT_FRAME]);
- vkResetCommandBuffer(commandBuffer, 0);
- RecordCommandBuffer(commandBuffer, imageIndex);
+ vkResetCommandBuffer(presentCommandBuffers[CURRENT_FRAME], 0);
+ RecordCommandBuffer(presentCommandBuffers[CURRENT_FRAME], imageIndex);
- VkSemaphore waitSemaphores[] = {imageAvailableSemaphore};
- VkSemaphore signalSemaphores[] = {renderFinishedSemaphore};
+ VkSemaphore waitSemaphores[] = {presentImageAvailableSemaphores[CURRENT_FRAME]};
+ VkSemaphore signalSemaphores[] = {presentRenderFinishedSemaphores[CURRENT_FRAME]};
VkPipelineStageFlags waitStages[] = {VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT};
VkSubmitInfo submitInfo{};
@@ -938,11 +1023,11 @@ void Render() {
submitInfo.pWaitSemaphores = waitSemaphores;
submitInfo.pWaitDstStageMask = waitStages;
submitInfo.commandBufferCount = 1;
- submitInfo.pCommandBuffers = &commandBuffer;
+ submitInfo.pCommandBuffers = &presentCommandBuffers[CURRENT_FRAME];
submitInfo.signalSemaphoreCount = 1;
submitInfo.pSignalSemaphores = signalSemaphores;
- auto result = vkQueueSubmit(graphicsQueue, 1, &submitInfo, inFlightFence);
+ result = vkQueueSubmit(graphicsQueue, 1, &submitInfo, presentInFlightFences[CURRENT_FRAME]);
if (result != VK_SUCCESS) {
throw "failed to submit queue";
}
@@ -958,9 +1043,14 @@ void Render() {
presentInfo.pImageIndices = &imageIndex;
presentInfo.pResults = nullptr;
- vkQueuePresentKHR(presentQueue, &presentInfo);
+ result = vkQueuePresentKHR(presentQueue, &presentInfo);
+ if (result == VK_ERROR_OUT_OF_DATE_KHR || result == VK_SUBOPTIMAL_KHR || shouldRecreateSwapchain) {
+ RecreateSwapchain();
+ } else if (result != VK_SUCCESS) {
+ throw "failed to present swapchain image";
+ }
- CURRENT_FRAME = (CURRENT_FRAME + 1) % swapchainLength;
+ CURRENT_FRAME = (CURRENT_FRAME + 1) % MAX_FRAMES_IN_FLIGHT;
}
void PostRender() {}
diff --git a/src/window.hpp b/src/window.hpp
index b7a4e05..27f809c 100644
--- a/src/window.hpp
+++ b/src/window.hpp
@@ -7,7 +7,7 @@
#include <GLFW/glfw3.h>
#include <vulkan/vulkan.h>
-const unsigned int MAX_FRAMES_IN_FLIGHT = 3;
+const unsigned int MAX_FRAMES_IN_FLIGHT = 2;
extern GLFWwindow *window;
extern VkInstance vkInstance;