From b6438c67792a268b2307b4d0ae7a5c278e7b6152 Mon Sep 17 00:00:00 2001 From: tylermurphy534 Date: Tue, 20 Sep 2022 23:04:33 -0400 Subject: [PATCH] recreate descriptors --- engine/xe_image.cpp | 133 ++++++++++++++++++++---------------- engine/xe_image.hpp | 2 + engine/xe_render_system.cpp | 52 ++++++-------- engine/xe_render_system.hpp | 6 +- engine/xe_swap_chain.hpp | 2 +- src/simple_renderer.cpp | 3 +- 6 files changed, 103 insertions(+), 95 deletions(-) diff --git a/engine/xe_image.cpp b/engine/xe_image.cpp index c7b1488..26e35f2 100644 --- a/engine/xe_image.cpp +++ b/engine/xe_image.cpp @@ -12,11 +12,13 @@ namespace xe { XeImage::XeImage(XeDevice &xeDevice, const std::string &filename) : xeDevice{xeDevice} { createTextureImage(filename); + createTextureImageView(); } XeImage::~XeImage() { vkDestroyImage(xeDevice.device(), textureImage, nullptr); vkFreeMemory(xeDevice.device(), textureImageMemory, nullptr); + vkDestroyImageView(xeDevice.device(), textureImageView, nullptr); } void XeImage::createTextureImage(const std::string &filename) { @@ -94,73 +96,90 @@ void XeImage::createImage(uint32_t width, uint32_t height, VkFormat format, VkIm } void XeImage::transitionImageLayout(VkImage image, VkFormat format, VkImageLayout oldLayout, VkImageLayout newLayout) { - VkCommandBuffer commandBuffer = xeDevice.beginSingleTimeCommands(); + VkCommandBuffer commandBuffer = xeDevice.beginSingleTimeCommands(); - VkImageMemoryBarrier barrier{}; - barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; - barrier.oldLayout = oldLayout; - barrier.newLayout = newLayout; - barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; - barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; - barrier.image = image; - barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; - barrier.subresourceRange.baseMipLevel = 0; - barrier.subresourceRange.levelCount = 1; - barrier.subresourceRange.baseArrayLayer = 0; - barrier.subresourceRange.layerCount = 1; + VkImageMemoryBarrier barrier{}; + barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; + barrier.oldLayout = oldLayout; + barrier.newLayout = newLayout; + barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; + barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; + barrier.image = image; + barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; + barrier.subresourceRange.baseMipLevel = 0; + barrier.subresourceRange.levelCount = 1; + barrier.subresourceRange.baseArrayLayer = 0; + barrier.subresourceRange.layerCount = 1; - VkPipelineStageFlags sourceStage; - VkPipelineStageFlags destinationStage; + VkPipelineStageFlags sourceStage; + VkPipelineStageFlags destinationStage; - if (oldLayout == VK_IMAGE_LAYOUT_UNDEFINED && newLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL) { - barrier.srcAccessMask = 0; - barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; + if (oldLayout == VK_IMAGE_LAYOUT_UNDEFINED && newLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL) { + barrier.srcAccessMask = 0; + barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; - sourceStage = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT; - destinationStage = VK_PIPELINE_STAGE_TRANSFER_BIT; - } else if (oldLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL && newLayout == VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL) { - barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; - barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT; + sourceStage = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT; + destinationStage = VK_PIPELINE_STAGE_TRANSFER_BIT; + } else if (oldLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL && newLayout == VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL) { + barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; + barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT; - sourceStage = VK_PIPELINE_STAGE_TRANSFER_BIT; - destinationStage = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT; - } else { - throw std::invalid_argument("unsupported layout transition!"); - } - - vkCmdPipelineBarrier( - commandBuffer, - sourceStage, destinationStage, - 0, - 0, nullptr, - 0, nullptr, - 1, &barrier - ); - - xeDevice.endSingleTimeCommands(commandBuffer); + sourceStage = VK_PIPELINE_STAGE_TRANSFER_BIT; + destinationStage = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT; + } else { + throw std::invalid_argument("unsupported layout transition!"); } - void XeImage::copyBufferToImage(VkBuffer buffer, VkImage image, uint32_t width, uint32_t height) { - VkCommandBuffer commandBuffer = xeDevice.beginSingleTimeCommands(); + vkCmdPipelineBarrier( + commandBuffer, + sourceStage, destinationStage, + 0, + 0, nullptr, + 0, nullptr, + 1, &barrier + ); - VkBufferImageCopy region{}; - region.bufferOffset = 0; - region.bufferRowLength = 0; - region.bufferImageHeight = 0; - region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; - region.imageSubresource.mipLevel = 0; - region.imageSubresource.baseArrayLayer = 0; - region.imageSubresource.layerCount = 1; - region.imageOffset = {0, 0, 0}; - region.imageExtent = { - width, - height, - 1 - }; + xeDevice.endSingleTimeCommands(commandBuffer); +} - vkCmdCopyBufferToImage(commandBuffer, buffer, image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ®ion); +void XeImage::copyBufferToImage(VkBuffer buffer, VkImage image, uint32_t width, uint32_t height) { + VkCommandBuffer commandBuffer = xeDevice.beginSingleTimeCommands(); + + VkBufferImageCopy region{}; + region.bufferOffset = 0; + region.bufferRowLength = 0; + region.bufferImageHeight = 0; + region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; + region.imageSubresource.mipLevel = 0; + region.imageSubresource.baseArrayLayer = 0; + region.imageSubresource.layerCount = 1; + region.imageOffset = {0, 0, 0}; + region.imageExtent = { + width, + height, + 1 + }; - xeDevice.endSingleTimeCommands(commandBuffer); + vkCmdCopyBufferToImage(commandBuffer, buffer, image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ®ion); + + xeDevice.endSingleTimeCommands(commandBuffer); +} + +void XeImage::createTextureImageView() { + VkImageViewCreateInfo viewInfo{}; + viewInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; + viewInfo.image = textureImage; + viewInfo.viewType = VK_IMAGE_VIEW_TYPE_2D; + viewInfo.format = VK_FORMAT_R8G8B8A8_SRGB; + viewInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; + viewInfo.subresourceRange.baseMipLevel = 0; + viewInfo.subresourceRange.levelCount = 1; + viewInfo.subresourceRange.baseArrayLayer = 0; + viewInfo.subresourceRange.layerCount = 1; + + if (vkCreateImageView(xeDevice.device(), &viewInfo, nullptr, &textureImageView) != VK_SUCCESS) { + throw std::runtime_error("failed to create texture image view!"); } +} } \ No newline at end of file diff --git a/engine/xe_image.hpp b/engine/xe_image.hpp index c3ffe4f..7d514d9 100644 --- a/engine/xe_image.hpp +++ b/engine/xe_image.hpp @@ -22,10 +22,12 @@ class XeImage { void createImage(uint32_t width, uint32_t height, VkFormat format, VkImageTiling tiling, VkImageUsageFlags usage, VkMemoryPropertyFlags properties, VkImage& image, VkDeviceMemory& imageMemory); void transitionImageLayout(VkImage image, VkFormat format, VkImageLayout oldLayout, VkImageLayout newLayout); void copyBufferToImage(VkBuffer buffer, VkImage image, uint32_t width, uint32_t height); + void createTextureImageView(); XeDevice &xeDevice; VkImage textureImage; + VkImageView textureImageView; VkDeviceMemory textureImageMemory; friend class XeRenderSystem; diff --git a/engine/xe_render_system.cpp b/engine/xe_render_system.cpp index 80f76af..6cfb183 100644 --- a/engine/xe_render_system.cpp +++ b/engine/xe_render_system.cpp @@ -25,13 +25,13 @@ XeRenderSystem::XeRenderSystem( XeImage *image ) : xeDevice{xeEngine.xeDevice}, xeRenderer{xeEngine.xeRenderer}, + xeDescriptorPool{xeEngine.xeDescriptorPool}, pushCunstantDataSize{pushCunstantDataSize}, uniformBufferDataSize{uniformBufferDataSize}, textureSamplerBinding{image != nullptr} { createDescriptorSetLayout(); createUniformBuffers(); - createTextureImageView(image); - createDescriptorSets(*xeEngine.xeDescriptorPool); + createDescriptorSets(image); createPipelineLayout(); createPipeline(xeRenderer.getSwapChainRenderPass(), vert, frag); } @@ -41,7 +41,6 @@ XeRenderSystem::~XeRenderSystem() { vkDestroyPipelineLayout(xeDevice.device(), pipelineLayout, nullptr); if ( textureSamplerBinding ) { vkDestroySampler(xeDevice.device(), textureSampler, nullptr); - vkDestroyImageView(xeDevice.device(), textureImageView, nullptr); } }; @@ -100,34 +99,18 @@ void XeRenderSystem::createUniformBuffers() { } -void XeRenderSystem::createTextureImageView(XeImage *image) { - - if (!textureSamplerBinding) { - return; - } - - VkImageViewCreateInfo viewInfo{}; - viewInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; - viewInfo.image = image->textureImage; - viewInfo.viewType = VK_IMAGE_VIEW_TYPE_2D; - viewInfo.format = VK_FORMAT_R8G8B8A8_SRGB; - viewInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; - viewInfo.subresourceRange.baseMipLevel = 0; - viewInfo.subresourceRange.levelCount = 1; - viewInfo.subresourceRange.baseArrayLayer = 0; - viewInfo.subresourceRange.layerCount = 1; - - if (vkCreateImageView(xeDevice.device(), &viewInfo, nullptr, &textureImageView) != VK_SUCCESS) { - throw std::runtime_error("failed to create texture image view!"); - } -} - -void XeRenderSystem::createDescriptorSets(XeDescriptorPool &xeDescriptorPool) { +void XeRenderSystem::createDescriptorSets(XeImage *image) { descriptorSets = std::vector(XeSwapChain::MAX_FRAMES_IN_FLIGHT); for (int i = 0; i < descriptorSets.size(); i++) { - auto bufferInfo = uboBuffers[i]->descriptorInfo(); - XeDescriptorWriter writer{*xeDescriptorSetLayout, xeDescriptorPool}; + updateDescriptorSet(image, i, true); + } + +} + +void XeRenderSystem::updateDescriptorSet(XeImage *image, int frameIndex, bool allocate) { + auto bufferInfo = uboBuffers[frameIndex]->descriptorInfo(); + XeDescriptorWriter writer{*xeDescriptorSetLayout, *xeDescriptorPool}; int binding = 0; @@ -139,14 +122,17 @@ void XeRenderSystem::createDescriptorSets(XeDescriptorPool &xeDescriptorPool) { if (textureSamplerBinding) { VkDescriptorImageInfo imageInfo{}; imageInfo.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; - imageInfo.imageView = textureImageView; + imageInfo.imageView = image->textureImageView; imageInfo.sampler = textureSampler; writer.writeImage(binding, &imageInfo); binding += 1; } - writer.build(descriptorSets[i]); - } - + if (allocate) { + writer.build(descriptorSets[frameIndex]); + } else { + writer.overwrite(descriptorSets[frameIndex]); + } + } @@ -234,7 +220,7 @@ void XeRenderSystem::loadUniformObject(void *uniformBufferData) { } void XeRenderSystem::loadTexture(XeImage *image) { - // createTextureImageView(image); + updateDescriptorSet(image, xeRenderer.getFrameIndex(), false); } void XeRenderSystem::render(XeGameObject &gameObject) { diff --git a/engine/xe_render_system.hpp b/engine/xe_render_system.hpp index fbf10fc..d6b24b5 100644 --- a/engine/xe_render_system.hpp +++ b/engine/xe_render_system.hpp @@ -41,8 +41,8 @@ class XeRenderSystem { void createDescriptorSetLayout(); void createUniformBuffers(); - void createTextureImageView(XeImage *image); - void createDescriptorSets(XeDescriptorPool &xeDescriptorPool); + void createDescriptorSets(XeImage *image); + void updateDescriptorSet(XeImage *image, int frameIndex, bool allocate); void createPipelineLayout(); void createPipeline(VkRenderPass renderPass, std::string vert, std::string frag); @@ -61,9 +61,9 @@ class XeRenderSystem { std::vector descriptorSets; VkSampler textureSampler; - VkImageView textureImageView; VkPipelineLayout pipelineLayout; + std::unique_ptr &xeDescriptorPool; std::unique_ptr xeDescriptorSetLayout; }; diff --git a/engine/xe_swap_chain.hpp b/engine/xe_swap_chain.hpp index c0299a3..50aa03f 100755 --- a/engine/xe_swap_chain.hpp +++ b/engine/xe_swap_chain.hpp @@ -13,7 +13,7 @@ namespace xe { class XeSwapChain { public: - static constexpr int MAX_FRAMES_IN_FLIGHT = 3; + static constexpr int MAX_FRAMES_IN_FLIGHT = 2; XeSwapChain(XeDevice &deviceRef, VkExtent2D windowExtent); XeSwapChain(XeDevice &deviceRef, VkExtent2D windowExtent, std::shared_ptr previous); diff --git a/src/simple_renderer.cpp b/src/simple_renderer.cpp index 548b77d..a7016f9 100644 --- a/src/simple_renderer.cpp +++ b/src/simple_renderer.cpp @@ -7,12 +7,13 @@ SimpleRenderer::SimpleRenderer(xe::XeEngine &xeEngine, xe::XeImage *xeImage) void SimpleRenderer::render(std::vector &gameObjects, xe::XeCamera &xeCamera, xe::XeImage *xeImage) { + xeRenderSystem.loadTexture(xeImage); + xeRenderSystem.start(); UniformBuffer ubo{}; ubo.projectionView = xeCamera.getProjection() * xeCamera.getView(); xeRenderSystem.loadUniformObject(&ubo); - xeRenderSystem.loadTexture(xeImage); for(auto &obj : gameObjects) { PushConstant pc{};