From 9738de012a5c002d864dc66fac91d357a0640c9c Mon Sep 17 00:00:00 2001 From: Grayson Riffe Date: Thu, 20 Feb 2025 02:50:15 -0600 Subject: [PATCH] Add uniform buffer / resource descriptor set --- NothinFancy/res/shaders/output.vert.glsl | 7 +- NothinFancy/src/client/render/Buffer.cpp | 16 +- NothinFancy/src/client/render/Buffer.h | 8 +- .../src/client/render/RenderEngine.cpp | 170 ++++++++++++------ NothinFancy/src/client/render/RenderEngine.h | 24 +-- NothinFancy/src/pch.h | 1 + 6 files changed, 155 insertions(+), 71 deletions(-) diff --git a/NothinFancy/res/shaders/output.vert.glsl b/NothinFancy/res/shaders/output.vert.glsl index 357b4f9..6986a2a 100644 --- a/NothinFancy/res/shaders/output.vert.glsl +++ b/NothinFancy/res/shaders/output.vert.glsl @@ -7,7 +7,12 @@ layout(location = 1) in vec3 inColor; // Outputs layout(location = 0) out vec3 fragColor; +// Uniforms +layout(binding = 0) uniform MVPMatrixUniformBufferObject { + mat4 mvp; +} mvpUBO; + void main() { fragColor = inColor; - gl_Position = vec4(inPosition, 0.0, 1.0); + gl_Position = mvpUBO.mvp * vec4(inPosition, 0.0, 1.0); } diff --git a/NothinFancy/src/client/render/Buffer.cpp b/NothinFancy/src/client/render/Buffer.cpp index 0728c36..31ad4b4 100644 --- a/NothinFancy/src/client/render/Buffer.cpp +++ b/NothinFancy/src/client/render/Buffer.cpp @@ -7,11 +7,21 @@ namespace nf::client::render { Buffer::Buffer(BufferType type, const VkDevice& device, VideoMemoryAllocator& allocator, const VkCommandPool& commandPool, const VkQueue& queue, void* bufferData, size_t bufferSize) : Resource(device) + , m_allocator(allocator) , m_handle() , m_memory() , m_offset() - , m_allocator(allocator) + , m_pointer() { + if (type == BufferType::Uniform) { + createBuffer(bufferSize, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, m_handle); + m_allocator.allocateForBuffer(m_handle, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, m_memory, m_offset); + vkBindBufferMemory(m_device, m_handle, m_memory, m_offset); + + vkMapMemory(m_device, m_memory, m_offset, bufferSize, 0, &m_pointer); + return; + } + VkBuffer stagingBuffer = nullptr; createBuffer(bufferSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, stagingBuffer); @@ -50,6 +60,10 @@ namespace nf::client::render { return m_handle; } + void* Buffer::getPointer() const { + return m_pointer; + } + void Buffer::createBuffer(VkDeviceSize size, VkBufferUsageFlags usage, VkBuffer& buffer) { VkBufferCreateInfo bufferCI = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO }; bufferCI.size = size; diff --git a/NothinFancy/src/client/render/Buffer.h b/NothinFancy/src/client/render/Buffer.h index eea3eab..adeda04 100644 --- a/NothinFancy/src/client/render/Buffer.h +++ b/NothinFancy/src/client/render/Buffer.h @@ -7,7 +7,8 @@ namespace nf::client::render { enum class BufferType { Vertex, - Index + Index, + Uniform }; class Buffer : Resource { @@ -15,6 +16,7 @@ namespace nf::client::render { Buffer(BufferType type, const VkDevice& device, VideoMemoryAllocator& allocator, const VkCommandPool& commandPool, const VkQueue& queue, void* bufferData, size_t bufferSize); const VkBuffer& getHandle() const; + void* getPointer() const; ~Buffer(); private: @@ -23,11 +25,11 @@ namespace nf::client::render { void destroyBuffer(VkBuffer buffer, VkDeviceMemory bufferMemory, VkDeviceSize offset); + VideoMemoryAllocator& m_allocator; VkBuffer m_handle; VkDeviceMemory m_memory; VkDeviceSize m_offset; - - VideoMemoryAllocator& m_allocator; + void* m_pointer; }; } diff --git a/NothinFancy/src/client/render/RenderEngine.cpp b/NothinFancy/src/client/render/RenderEngine.cpp index 14c0567..da5aa06 100644 --- a/NothinFancy/src/client/render/RenderEngine.cpp +++ b/NothinFancy/src/client/render/RenderEngine.cpp @@ -30,12 +30,16 @@ namespace nf::client::render { , m_swapchainImages() , m_swapchainImageViews() , m_swapchainFramebuffers() - , m_pipelineLayoutOutput() + , m_pipelineOutputDescriptorSetLayout() + , m_pipelineOutputLayout() + , m_pipelineOutputDescriptorPool() + , m_pipelineOutputDescriptorSet() , m_pipelineOutput() , m_commandPool() - , m_numFramesInFlight(2) - , m_frameExecutors() - , m_currentFrameExecutor() + , m_commandBuffer() + , m_semaphoreImageAvailable() + , m_semaphoreRenderingDone() + , m_fenceFrameInFlight() , m_allocator() , m_bufferVertex() , m_bufferIndex() @@ -51,7 +55,7 @@ namespace nf::client::render { createOutputRenderPass(); createSwapchainFramebuffers(); createOutputPipeline(); - createFrameExecutors(); + createExecutionObjects(); m_allocator = std::make_unique(m_device, m_physicalDevice); createBuffers(); @@ -379,7 +383,7 @@ namespace nf::client::render { VkPipelineRasterizationStateCreateInfo rasterizationCI = { VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO }; rasterizationCI.lineWidth = 1.0; rasterizationCI.cullMode = VK_CULL_MODE_BACK_BIT; - rasterizationCI.frontFace = VK_FRONT_FACE_CLOCKWISE; + rasterizationCI.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE; // Specify multisample state VkPipelineMultisampleStateCreateInfo multisampleStateCI = { VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO }; @@ -392,12 +396,48 @@ namespace nf::client::render { colorBlendStateCI.attachmentCount = 1; colorBlendStateCI.pAttachments = &colorBlendAttachmentState; + // Create descriptor set layout + VkDescriptorSetLayoutCreateInfo descriptorSetLayoutCI = { VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO }; + VkDescriptorSetLayoutBinding mvpLayoutBinding = {}; + mvpLayoutBinding.binding = 0; + mvpLayoutBinding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; + mvpLayoutBinding.descriptorCount = 1; + mvpLayoutBinding.stageFlags = VK_SHADER_STAGE_VERTEX_BIT; + descriptorSetLayoutCI.bindingCount = 1; + descriptorSetLayoutCI.pBindings = &mvpLayoutBinding; + + if (vkCreateDescriptorSetLayout(m_device, &descriptorSetLayoutCI, nullptr, &m_pipelineOutputDescriptorSetLayout) != VK_SUCCESS) + NFError("Could not create descriptor set layout."); + // Create pipeline layout VkPipelineLayoutCreateInfo layoutCI = { VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO }; + layoutCI.setLayoutCount = 1; + layoutCI.pSetLayouts = &m_pipelineOutputDescriptorSetLayout; - if (vkCreatePipelineLayout(m_device, &layoutCI, nullptr, &m_pipelineLayoutOutput) != VK_SUCCESS) + if (vkCreatePipelineLayout(m_device, &layoutCI, nullptr, &m_pipelineOutputLayout) != VK_SUCCESS) NFError("Could not create pipeline layout."); + // Create descriptor pool + VkDescriptorPoolCreateInfo descriptorPoolCI = { VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO }; + VkDescriptorPoolSize descriptorPoolSize = {}; + descriptorPoolSize.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; + descriptorPoolSize.descriptorCount = 1; + descriptorPoolCI.poolSizeCount = 1; + descriptorPoolCI.pPoolSizes = &descriptorPoolSize; + descriptorPoolCI.maxSets = 1; + + if (vkCreateDescriptorPool(m_device, &descriptorPoolCI, nullptr, &m_pipelineOutputDescriptorPool) != VK_SUCCESS) + NFError("Could not create descriptor pool."); + + // Allocate descriptor set + VkDescriptorSetAllocateInfo descriptorSetAI = { VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO }; + descriptorSetAI.descriptorPool = m_pipelineOutputDescriptorPool; + descriptorSetAI.descriptorSetCount = 1; + descriptorSetAI.pSetLayouts = &m_pipelineOutputDescriptorSetLayout; + + if (vkAllocateDescriptorSets(m_device, &descriptorSetAI, &m_pipelineOutputDescriptorSet) != VK_SUCCESS) + NFError("Could not allocate descriptor set."); + // And finally put it all together VkGraphicsPipelineCreateInfo pipelineCI = { VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO }; pipelineCI.stageCount = 2; @@ -409,14 +449,14 @@ namespace nf::client::render { pipelineCI.pMultisampleState = &multisampleStateCI; pipelineCI.pColorBlendState = &colorBlendStateCI; pipelineCI.pDynamicState = &dynamicStateCI; - pipelineCI.layout = m_pipelineLayoutOutput; + pipelineCI.layout = m_pipelineOutputLayout; pipelineCI.renderPass = m_renderPassOutput; if (vkCreateGraphicsPipelines(m_device, nullptr, 1, &pipelineCI, nullptr, &m_pipelineOutput) != VK_SUCCESS) NFError("Could not create graphics pipeline."); } - void RenderEngine::createFrameExecutors() { + void RenderEngine::createExecutionObjects() { VkCommandPoolCreateInfo commandPoolCI = { VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO }; commandPoolCI.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT; commandPoolCI.queueFamilyIndex = m_queueFIGraphics; @@ -424,25 +464,22 @@ namespace nf::client::render { if (vkCreateCommandPool(m_device, &commandPoolCI, nullptr, &m_commandPool) != VK_SUCCESS) NFError("Could not create command pool."); - m_frameExecutors.resize(m_numFramesInFlight); - for (int i = 0; i < m_frameExecutors.size(); i++) { - VkCommandBufferAllocateInfo commandBufferAI = { VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO }; - commandBufferAI.commandPool = m_commandPool; - commandBufferAI.commandBufferCount = 1; + VkCommandBufferAllocateInfo commandBufferAI = { VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO }; + commandBufferAI.commandPool = m_commandPool; + commandBufferAI.commandBufferCount = 1; - if (vkAllocateCommandBuffers(m_device, &commandBufferAI, &m_frameExecutors[i].commandBuffer) != VK_SUCCESS) - NFError("Could not create command buffer."); + if (vkAllocateCommandBuffers(m_device, &commandBufferAI, &m_commandBuffer) != VK_SUCCESS) + NFError("Could not create command buffer."); - VkSemaphoreCreateInfo semaphoreCI = { VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO }; - if (vkCreateSemaphore(m_device, &semaphoreCI, nullptr, &m_frameExecutors[i].semaphoreImageAvailable) != VK_SUCCESS || - vkCreateSemaphore(m_device, &semaphoreCI, nullptr, &m_frameExecutors[i].semaphoreRenderFinished) != VK_SUCCESS) - NFError("Could not create semaphore."); + VkSemaphoreCreateInfo semaphoreCI = { VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO }; + if (vkCreateSemaphore(m_device, &semaphoreCI, nullptr, &m_semaphoreImageAvailable) != VK_SUCCESS || + vkCreateSemaphore(m_device, &semaphoreCI, nullptr, &m_semaphoreRenderingDone) != VK_SUCCESS) + NFError("Could not create semaphore."); - VkFenceCreateInfo fenceCI = { VK_STRUCTURE_TYPE_FENCE_CREATE_INFO }; - fenceCI.flags = VK_FENCE_CREATE_SIGNALED_BIT; - if (vkCreateFence(m_device, &fenceCI, nullptr, &m_frameExecutors[i].fenceFrameInFlight) != VK_SUCCESS) - NFError("Could not create fence."); - } + VkFenceCreateInfo fenceCI = { VK_STRUCTURE_TYPE_FENCE_CREATE_INFO }; + fenceCI.flags = VK_FENCE_CREATE_SIGNALED_BIT; + if (vkCreateFence(m_device, &fenceCI, nullptr, &m_fenceFrameInFlight) != VK_SUCCESS) + NFError("Could not create fence."); } void RenderEngine::createBuffers() { @@ -462,18 +499,30 @@ namespace nf::client::render { size_t triangleIndicesSize = sizeof(triangleIndices[0]) * triangleIndices.size(); m_bufferIndex = std::make_unique(BufferType::Index, m_device, *m_allocator, m_commandPool, m_queueGraphics, triangleIndices.data(), triangleIndicesSize); + + size_t mvpUniformBufferSize = sizeof(glm::mat4); + m_bufferUniformMVP = std::make_unique(BufferType::Uniform, m_device, *m_allocator, nullptr, nullptr, nullptr, mvpUniformBufferSize); + + // Add uniform buffer to descriptor set + VkWriteDescriptorSet descriptorSetWrite = { VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET }; + VkDescriptorBufferInfo uniformDescriptorBI = {}; + uniformDescriptorBI.buffer = m_bufferUniformMVP->getHandle(); + uniformDescriptorBI.range = VK_WHOLE_SIZE; + descriptorSetWrite.dstSet = m_pipelineOutputDescriptorSet; + descriptorSetWrite.dstBinding = 0; + descriptorSetWrite.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; + descriptorSetWrite.descriptorCount = 1; + descriptorSetWrite.pBufferInfo = &uniformDescriptorBI; + vkUpdateDescriptorSets(m_device, 1, &descriptorSetWrite, 0, nullptr); } void RenderEngine::doFrame() { - // Get current frame executor - auto& [commandBuffer, semaphoreImageAvailable, semaphoreRenderFinished, fenceFrameInFlight] = m_frameExecutors[m_currentFrameExecutor]; - // First, wait for previous frame to complete - vkWaitForFences(m_device, 1, &fenceFrameInFlight, VK_TRUE, UINT64_MAX); + vkWaitForFences(m_device, 1, &m_fenceFrameInFlight, VK_TRUE, UINT64_MAX); // Get next swapchain image and recreate if necessary uint32_t nextImageIndex = 0; - VkResult result = vkAcquireNextImageKHR(m_device, m_swapchain, UINT64_MAX, semaphoreImageAvailable, nullptr, &nextImageIndex); + VkResult result = vkAcquireNextImageKHR(m_device, m_swapchain, UINT64_MAX, m_semaphoreImageAvailable, nullptr, &nextImageIndex); if (result == VK_ERROR_OUT_OF_DATE_KHR) { recreateSwapchain(); return; @@ -482,12 +531,12 @@ namespace nf::client::render { NFError("Could not aquire next swapchain image."); // Reset fence for this frame - vkResetFences(m_device, 1, &fenceFrameInFlight); + vkResetFences(m_device, 1, &m_fenceFrameInFlight); // Begin recording VkCommandBufferBeginInfo commandBufferBI = { VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO }; - if (vkBeginCommandBuffer(commandBuffer, &commandBufferBI) != VK_SUCCESS) + if (vkBeginCommandBuffer(m_commandBuffer, &commandBufferBI) != VK_SUCCESS) NFError("Could not begin recording command buffer."); // Start the render pass @@ -498,52 +547,65 @@ namespace nf::client::render { renderPassBI.renderArea.extent = m_swapchainExtent; renderPassBI.clearValueCount = 1; renderPassBI.pClearValues = &black; - vkCmdBeginRenderPass(commandBuffer, &renderPassBI, VK_SUBPASS_CONTENTS_INLINE); + vkCmdBeginRenderPass(m_commandBuffer, &renderPassBI, VK_SUBPASS_CONTENTS_INLINE); // Bind output pipeline - vkCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, m_pipelineOutput); + vkCmdBindPipeline(m_commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, m_pipelineOutput); // Set viewport and scissor VkViewport viewport = {}; viewport.width = static_cast(m_swapchainExtent.width), viewport.height = static_cast(m_swapchainExtent.height); viewport.maxDepth = 1.0; - vkCmdSetViewport(commandBuffer, 0, 1, &viewport); + vkCmdSetViewport(m_commandBuffer, 0, 1, &viewport); VkRect2D scissor = { {}, m_swapchainExtent }; - vkCmdSetScissor(commandBuffer, 0, 1, &scissor); + vkCmdSetScissor(m_commandBuffer, 0, 1, &scissor); // Bind buffers VkDeviceSize bufferOffset = 0; - vkCmdBindVertexBuffers(commandBuffer, 0, 1, &m_bufferVertex->getHandle(), &bufferOffset); - vkCmdBindIndexBuffer(commandBuffer, m_bufferIndex->getHandle(), 0, VK_INDEX_TYPE_UINT32); + vkCmdBindVertexBuffers(m_commandBuffer, 0, 1, &m_bufferVertex->getHandle(), &bufferOffset); + vkCmdBindIndexBuffer(m_commandBuffer, m_bufferIndex->getHandle(), 0, VK_INDEX_TYPE_UINT32); + + // Update uniform buffer + static auto startTime = std::chrono::high_resolution_clock::now(); + auto currentTime = std::chrono::high_resolution_clock::now(); + float time = std::chrono::duration(currentTime - startTime).count(); + glm::mat4 modelMatrix = glm::rotate(glm::mat4(1.0), time * glm::radians(20.0f), glm::vec3(0.0, 0.0, 1.0)), + viewMatrix = glm::lookAt(glm::vec3(1.0, 1.0, 2.0), glm::vec3(0.0), glm::vec3(0.0, 1.0, 0.0)), + projectionMatrix = glm::perspective(glm::radians(45.0f), static_cast(m_swapchainExtent.width) / m_swapchainExtent.height, 0.1f, 10.0f); + + projectionMatrix[1][1] *= -1; + glm::mat4 mvpMatrix = projectionMatrix * viewMatrix * modelMatrix; + memcpy(m_bufferUniformMVP->getPointer(), &mvpMatrix, sizeof(mvpMatrix)); + vkCmdBindDescriptorSets(m_commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, m_pipelineOutputLayout, 0, 1, &m_pipelineOutputDescriptorSet, 0, nullptr); // Draw - vkCmdDrawIndexed(commandBuffer, 6, 1, 0, 0, 0); + vkCmdDrawIndexed(m_commandBuffer, 6, 1, 0, 0, 0); // End the render pass - vkCmdEndRenderPass(commandBuffer); + vkCmdEndRenderPass(m_commandBuffer); // Finish recording - if (vkEndCommandBuffer(commandBuffer) != VK_SUCCESS) + if (vkEndCommandBuffer(m_commandBuffer) != VK_SUCCESS) NFError("Could not end command buffer."); // Submit to graphics queue VkPipelineStageFlags waitStage = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; VkSubmitInfo submitInfo = { VK_STRUCTURE_TYPE_SUBMIT_INFO }; submitInfo.waitSemaphoreCount = 1; - submitInfo.pWaitSemaphores = &semaphoreImageAvailable; + submitInfo.pWaitSemaphores = &m_semaphoreImageAvailable; submitInfo.pWaitDstStageMask = &waitStage; submitInfo.commandBufferCount = 1; - submitInfo.pCommandBuffers = &commandBuffer; + submitInfo.pCommandBuffers = &m_commandBuffer; submitInfo.signalSemaphoreCount = 1; - submitInfo.pSignalSemaphores = &semaphoreRenderFinished; + submitInfo.pSignalSemaphores = &m_semaphoreRenderingDone; - if (vkQueueSubmit(m_queueGraphics, 1, &submitInfo, fenceFrameInFlight) != VK_SUCCESS) + if (vkQueueSubmit(m_queueGraphics, 1, &submitInfo, m_fenceFrameInFlight) != VK_SUCCESS) NFError("Could not submit to Vulkan queue."); // And present! VkPresentInfoKHR presentInfo = { VK_STRUCTURE_TYPE_PRESENT_INFO_KHR }; presentInfo.waitSemaphoreCount = 1; - presentInfo.pWaitSemaphores = &semaphoreRenderFinished; + presentInfo.pWaitSemaphores = &m_semaphoreRenderingDone; presentInfo.swapchainCount = 1; presentInfo.pSwapchains = &m_swapchain; presentInfo.pImageIndices = &nextImageIndex; @@ -553,9 +615,6 @@ namespace nf::client::render { recreateSwapchain(); else if (result != VK_SUCCESS) NFError("Could not present image."); - - // Advance to next frame executor - m_currentFrameExecutor = (m_currentFrameExecutor + 1) % m_numFramesInFlight; } void RenderEngine::setDisplay(DisplayConfig config) { @@ -593,19 +652,20 @@ namespace nf::client::render { RenderEngine::~RenderEngine() { waitIdle(); + m_bufferUniformMVP.reset(); m_bufferIndex.reset(); m_bufferVertex.reset(); - for (int i = 0; i < m_frameExecutors.size(); i++) { - vkDestroyFence(m_device, m_frameExecutors[i].fenceFrameInFlight, nullptr); - vkDestroySemaphore(m_device, m_frameExecutors[i].semaphoreRenderFinished, nullptr); - vkDestroySemaphore(m_device, m_frameExecutors[i].semaphoreImageAvailable, nullptr); - } + vkDestroyFence(m_device, m_fenceFrameInFlight, nullptr); + vkDestroySemaphore(m_device, m_semaphoreRenderingDone, nullptr); + vkDestroySemaphore(m_device, m_semaphoreImageAvailable, nullptr); destroySwapchain(); vkDestroyCommandPool(m_device, m_commandPool, nullptr); vkDestroyPipeline(m_device, m_pipelineOutput, nullptr); - vkDestroyPipelineLayout(m_device, m_pipelineLayoutOutput, nullptr); + vkDestroyDescriptorPool(m_device, m_pipelineOutputDescriptorPool, nullptr); + vkDestroyPipelineLayout(m_device, m_pipelineOutputLayout, nullptr); + vkDestroyDescriptorSetLayout(m_device, m_pipelineOutputDescriptorSetLayout, nullptr); vkDestroyRenderPass(m_device, m_renderPassOutput, nullptr); vkDestroyDevice(m_device, nullptr); vkDestroySurfaceKHR(m_instance, m_surface, nullptr); diff --git a/NothinFancy/src/client/render/RenderEngine.h b/NothinFancy/src/client/render/RenderEngine.h index 4805573..5fc23b3 100644 --- a/NothinFancy/src/client/render/RenderEngine.h +++ b/NothinFancy/src/client/render/RenderEngine.h @@ -7,12 +7,6 @@ #include "Buffer.h" namespace nf::client::render { - struct FrameExecutor { - VkCommandBuffer commandBuffer; - VkSemaphore semaphoreImageAvailable, semaphoreRenderFinished; - VkFence fenceFrameInFlight; - }; - class RenderEngine { public: RenderEngine(std::shared_ptr window, DisplayConfig display); @@ -26,11 +20,12 @@ namespace nf::client::render { void createSurface(); void pickPhysicalDevice(); void createDevice(); + void createSwapchain(); void createOutputRenderPass(); void createSwapchainFramebuffers(); void createOutputPipeline(); - void createFrameExecutors(); + void createExecutionObjects(); void createBuffers(); @@ -49,6 +44,7 @@ namespace nf::client::render { uint32_t m_queueFIGraphics, m_queueFIPresent; VkDevice m_device; VkQueue m_queueGraphics, m_queuePresent; + VkRenderPass m_renderPassOutput; // Swapchain @@ -60,17 +56,23 @@ namespace nf::client::render { std::vector m_swapchainFramebuffers; // Pipelines - VkPipelineLayout m_pipelineLayoutOutput; + VkDescriptorSetLayout m_pipelineOutputDescriptorSetLayout; + VkPipelineLayout m_pipelineOutputLayout; + VkDescriptorPool m_pipelineOutputDescriptorPool; + VkDescriptorSet m_pipelineOutputDescriptorSet; VkPipeline m_pipelineOutput; // Execution objects VkCommandPool m_commandPool; - const uint32_t m_numFramesInFlight; - std::vector m_frameExecutors; - uint32_t m_currentFrameExecutor; + VkCommandBuffer m_commandBuffer; + VkSemaphore m_semaphoreImageAvailable; + VkSemaphore m_semaphoreRenderingDone; + VkFence m_fenceFrameInFlight; + // Temporary objects std::unique_ptr m_allocator; std::unique_ptr m_bufferVertex; std::unique_ptr m_bufferIndex; + std::unique_ptr m_bufferUniformMVP; }; } diff --git a/NothinFancy/src/pch.h b/NothinFancy/src/pch.h index 723622e..6a33947 100644 --- a/NothinFancy/src/pch.h +++ b/NothinFancy/src/pch.h @@ -45,3 +45,4 @@ // GLM #include +#include