From 96ea71852f4136c533f692cf89d9baad77df661c Mon Sep 17 00:00:00 2001 From: kearwood Date: Wed, 21 Sep 2022 00:11:48 -0700 Subject: [PATCH] Implemented logic in KRPipeline to update descriptor sets. Implemented KRTexture::getFullImageView Implemented KRTexture::getImage Create stub function, KRUniformBuffer::getBuffer --- kraken/KRPipeline.cpp | 86 +++++++++++++++++++++++++++++++++----- kraken/KRPipeline.h | 3 +- kraken/KRTexture.cpp | 20 +++++++++ kraken/KRTexture.h | 3 ++ kraken/KRUniformBuffer.cpp | 8 +++- kraken/KRUniformBuffer.h | 1 + 6 files changed, 109 insertions(+), 12 deletions(-) diff --git a/kraken/KRPipeline.cpp b/kraken/KRPipeline.cpp index d7a7cf2..befe617 100644 --- a/kraken/KRPipeline.cpp +++ b/kraken/KRPipeline.cpp @@ -844,17 +844,81 @@ void KRPipeline::updateDescriptorSets() // There are no descriptors return; } - if (m_descriptorSets.size()) { - // TODO - We should detect changes to descriptor sets and update them - return; - } std::unique_ptr& device = getContext().getDeviceManager()->getDevice(m_deviceHandle); - // TODO - Handle device context loss - m_descriptorSets.resize(KRENGINE_MAX_FRAMES_IN_FLIGHT, VK_NULL_HANDLE); - std::vector layouts(KRENGINE_MAX_FRAMES_IN_FLIGHT, m_descriptorSetLayout); - device->createDescriptorSets(layouts, m_descriptorSets); + // If the descriptor sets are not yet allocted, create them + if (m_descriptorSets.size() == 0) { + int descriptorSetCount = 0; + for (int stage = 0; stage < static_cast(ShaderStage::ShaderStageCount); stage++) { + const StageInfo& stageInfo = m_stages[stage]; + descriptorSetCount += stageInfo.descriptorSets.size(); + } + m_descriptorSets.resize(KRENGINE_MAX_FRAMES_IN_FLIGHT * descriptorSetCount, VK_NULL_HANDLE); + std::vector layouts(KRENGINE_MAX_FRAMES_IN_FLIGHT, m_descriptorSetLayout); + device->createDescriptorSets(layouts, m_descriptorSets); + } + + // Update the descriptor sets + // TODO - We should only do this when the descriptors have changed + + int descriptorSetCount = m_descriptorSets.size() / KRENGINE_MAX_FRAMES_IN_FLIGHT; + int descriptorSetStart = (getContext().getCurrentFrame() % KRENGINE_MAX_FRAMES_IN_FLIGHT) * descriptorSetCount; + int descriptorSetIndex = descriptorSetStart; + + std::vector descriptorWrites; + std::vector buffers; + std::vector images; + + for (int stage = 0; stage < static_cast(ShaderStage::ShaderStageCount); stage++) { + StageInfo& stageInfo = m_stages[stage]; + for (DescriptorSetInfo& descriptorSetInfo : stageInfo.descriptorSets) { + VkDescriptorSet descriptorSet = m_descriptorSets[descriptorSetIndex++]; + + int bindingIndex = 0; + for (DescriptorBinding& binding : descriptorSetInfo.bindings) { + UniformBufferDescriptorInfo* buffer = std::get_if(&binding); + ImageDescriptorInfo* image = std::get_if(&binding); + if (buffer) { + VkDescriptorBufferInfo& bufferInfo = buffers.emplace_back(VkDescriptorBufferInfo{}); + bufferInfo.buffer = buffer->buffer->getBuffer(); + bufferInfo.offset = 0; + bufferInfo.range = VK_WHOLE_SIZE; + + VkWriteDescriptorSet& descriptorWrite = descriptorWrites.emplace_back(VkWriteDescriptorSet{}); + descriptorWrite.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; + descriptorWrite.dstSet = descriptorSet; + descriptorWrite.dstBinding = bindingIndex; + descriptorWrite.dstArrayElement = 0; + descriptorWrite.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; + descriptorWrite.descriptorCount = 1; + descriptorWrite.pBufferInfo = &bufferInfo; + } else if (image) { + VkDescriptorImageInfo& imageInfo = images.emplace_back(VkDescriptorImageInfo{}); + imageInfo.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; + imageInfo.imageView = image->texture->getFullImageView(m_deviceHandle); + imageInfo.sampler = image->sampler->getSampler(m_deviceHandle); + + VkWriteDescriptorSet& descriptorWrite = descriptorWrites.emplace_back(VkWriteDescriptorSet{}); + descriptorWrite.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; + descriptorWrite.dstSet = descriptorSet; + descriptorWrite.dstBinding = bindingIndex++; + descriptorWrite.dstArrayElement = 0; + descriptorWrite.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; + descriptorWrite.descriptorCount = 1; + descriptorWrite.pImageInfo = &imageInfo; + } else { + // TODO - Error Handling + assert(false); + } + bindingIndex++; + } + } + } + + if (!descriptorWrites.empty()) { + vkUpdateDescriptorSets(device->m_logicalDevice, static_cast(descriptorWrites.size()), descriptorWrites.data(), 0, nullptr); + } } void KRPipeline::bindDescriptorSets(VkCommandBuffer& commandBuffer) @@ -862,12 +926,14 @@ void KRPipeline::bindDescriptorSets(VkCommandBuffer& commandBuffer) if (m_descriptorSets.empty()) { return; } - VkDescriptorSet descriptorSet = m_descriptorSets[getContext().getCurrentFrame() % m_descriptorSets.size()]; + int descriptorSetCount = m_descriptorSets.size() / KRENGINE_MAX_FRAMES_IN_FLIGHT; + int startDescriptorSet = (getContext().getCurrentFrame() % KRENGINE_MAX_FRAMES_IN_FLIGHT) * descriptorSetCount; + VkDescriptorSet descriptorSet = m_descriptorSets[startDescriptorSet]; if (descriptorSet == VK_NULL_HANDLE) { return; } // TODO - Vulkan Refactoring - Support multiple descriptor set binding - vkCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, m_pipelineLayout, 0, 1, &descriptorSet, 0, nullptr); + vkCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, m_pipelineLayout, 0, descriptorSetCount, &descriptorSet, 0, nullptr); } const char* KRPipeline::getKey() const diff --git a/kraken/KRPipeline.h b/kraken/KRPipeline.h index 77a2ff9..65edd6c 100644 --- a/kraken/KRPipeline.h +++ b/kraken/KRPipeline.h @@ -335,7 +335,8 @@ private: }; typedef std::vector> DescriptorSetQuery; - typedef std::vector> DescriptorSetBinding; + typedef std::variant DescriptorBinding; + typedef std::vector DescriptorSetBinding; struct DescriptorSetInfo { diff --git a/kraken/KRTexture.cpp b/kraken/KRTexture.cpp index 5498702..78ce0d2 100755 --- a/kraken/KRTexture.cpp +++ b/kraken/KRTexture.cpp @@ -267,3 +267,23 @@ void KRTexture::_swapHandles() } } +VkImageView KRTexture::getFullImageView(KrDeviceHandle device) +{ + for (TextureHandle& handle : m_handles) { + if (handle.device == device) { + return handle.fullImageView; + } + } + return VK_NULL_HANDLE; +} + +VkImage KRTexture::getImage(KrDeviceHandle device) +{ + for (TextureHandle& handle : m_handles) { + if (handle.device == device) { + return handle.image; + } + } + return VK_NULL_HANDLE; +} + diff --git a/kraken/KRTexture.h b/kraken/KRTexture.h index 68aede2..cbebfaf 100755 --- a/kraken/KRTexture.h +++ b/kraken/KRTexture.h @@ -89,6 +89,9 @@ public: void _swapHandles(); + VkImageView getFullImageView(KrDeviceHandle device); + VkImage getImage(KrDeviceHandle device); + protected: virtual bool createGPUTexture(int lod_max_dim) = 0; GLuint getHandle(); diff --git a/kraken/KRUniformBuffer.cpp b/kraken/KRUniformBuffer.cpp index 8c72846..b543de6 100644 --- a/kraken/KRUniformBuffer.cpp +++ b/kraken/KRUniformBuffer.cpp @@ -40,4 +40,10 @@ KRUniformBuffer::KRUniformBuffer(KRContext& context) KRUniformBuffer::~KRUniformBuffer() { -} \ No newline at end of file +} + +VkBuffer KRUniformBuffer::getBuffer() +{ + // TODO - Vulkan Refactoring, Implement + return VK_NULL_HANDLE; +} diff --git a/kraken/KRUniformBuffer.h b/kraken/KRUniformBuffer.h index d55ab52..600d914 100644 --- a/kraken/KRUniformBuffer.h +++ b/kraken/KRUniformBuffer.h @@ -41,6 +41,7 @@ public: KRUniformBuffer(KRContext& context); virtual ~KRUniformBuffer(); + VkBuffer getBuffer(); private: };