From 93c75763c7472db8e9fa610becf0ad155a90cf20 Mon Sep 17 00:00:00 2001 From: GeorgH93 Date: Wed, 30 Aug 2023 23:11:11 +0200 Subject: [PATCH] [WIP] Refactor creation of descriptorsets --- .../Shader/DescriptorInputDescription.hpp | 21 +++-- .../Scene/Shader/ShaderProgramType.hpp | 1 + openVulkanoCpp/Vulkan/Context.cpp | 3 - openVulkanoCpp/Vulkan/Context.hpp | 2 - openVulkanoCpp/Vulkan/Pipeline.hpp | 48 ----------- openVulkanoCpp/Vulkan/Renderer.cpp | 2 +- openVulkanoCpp/Vulkan/Renderer.hpp | 1 + .../Vulkan/Resources/IShaderOwner.hpp | 23 ++--- .../Vulkan/Resources/ResourceManager.cpp | 35 +++++++- .../Vulkan/Resources/ResourceManager.hpp | 11 +++ .../Vulkan/Resources/UniformBuffer.hpp | 85 ++++++++++--------- openVulkanoCpp/Vulkan/Scene/IRecordable.hpp | 16 ++-- .../Scene/SimpleDrawableVulkanEncoder.cpp | 2 +- openVulkanoCpp/Vulkan/Scene/VulkanNode.hpp | 71 ++++++++-------- openVulkanoCpp/Vulkan/Scene/VulkanShader.cpp | 24 +++++- openVulkanoCpp/Vulkan/Scene/VulkanShader.hpp | 6 +- openVulkanoCpp/Vulkan/Scene/VulkanTexture.hpp | 8 +- openVulkanoCpp/Vulkan/VulkanDrawContext.cpp | 9 +- openVulkanoCpp/Vulkan/VulkanDrawContext.hpp | 6 ++ 19 files changed, 201 insertions(+), 173 deletions(-) delete mode 100644 openVulkanoCpp/Vulkan/Pipeline.hpp diff --git a/openVulkanoCpp/Scene/Shader/DescriptorInputDescription.hpp b/openVulkanoCpp/Scene/Shader/DescriptorInputDescription.hpp index 9564fdb..d008182 100644 --- a/openVulkanoCpp/Scene/Shader/DescriptorInputDescription.hpp +++ b/openVulkanoCpp/Scene/Shader/DescriptorInputDescription.hpp @@ -38,20 +38,31 @@ namespace openVulkanoCpp ShaderProgramType::Type stageFlags; void* immutableSamplers; - DescriptorSetLayoutBinding() - : DescriptorSetLayoutBinding(Type::TYPE_UNIFORM_BUFFER_DYNAMIC, 1, ShaderProgramType::Type::VERTEX) + constexpr DescriptorSetLayoutBinding() + : DescriptorSetLayoutBinding(0, Type::TYPE_UNIFORM_BUFFER_DYNAMIC, 1, ShaderProgramType::Type::VERTEX) {} - DescriptorSetLayoutBinding(Type descriptorType, uint32_t descriptorCount, + constexpr DescriptorSetLayoutBinding(uint32_t bindingId, Type descriptorType, uint32_t descriptorCount, ShaderProgramType::Type stageFlags, void* immutableSamplers = nullptr) - : bindingId(0), descriptorType(descriptorType) + : bindingId(bindingId), descriptorType(descriptorType) , descriptorCount(descriptorCount), stageFlags(stageFlags) , immutableSamplers(immutableSamplers) {} - DescriptorSetLayoutBinding(uint32_t id, const DescriptorSetLayoutBinding& layout) + constexpr DescriptorSetLayoutBinding(uint32_t id, const DescriptorSetLayoutBinding& layout) : bindingId(id), descriptorType(layout.descriptorType), descriptorCount(layout.descriptorCount) , stageFlags(layout.stageFlags), immutableSamplers(layout.immutableSamplers) {} + + constexpr bool operator <(const DescriptorSetLayoutBinding& rhs) const + { + return bindingId < rhs.bindingId && + descriptorType < rhs.descriptorType && + descriptorCount < rhs.descriptorCount && + stageFlags < rhs.stageFlags && + immutableSamplers < rhs.immutableSamplers; + } }; + + static constexpr inline DescriptorSetLayoutBinding NODE_LAYOUT_BINDING = {0, DescriptorSetLayoutBinding::Type::TYPE_UNIFORM_BUFFER_DYNAMIC, 1, ShaderProgramType::ALL_GRAPHICS}; } \ No newline at end of file diff --git a/openVulkanoCpp/Scene/Shader/ShaderProgramType.hpp b/openVulkanoCpp/Scene/Shader/ShaderProgramType.hpp index eb1c461..89adbd7 100644 --- a/openVulkanoCpp/Scene/Shader/ShaderProgramType.hpp +++ b/openVulkanoCpp/Scene/Shader/ShaderProgramType.hpp @@ -6,6 +6,7 @@ #pragma once +#include "Base/Utils.hpp" #include #include diff --git a/openVulkanoCpp/Vulkan/Context.cpp b/openVulkanoCpp/Vulkan/Context.cpp index 8853368..6bf42b3 100644 --- a/openVulkanoCpp/Vulkan/Context.cpp +++ b/openVulkanoCpp/Vulkan/Context.cpp @@ -32,8 +32,6 @@ namespace openVulkanoCpp::Vulkan swapChain.Init(device.get(), surface, window); swapChainRenderPass.Init(device.get(), &swapChain, true, true); - pipeline.Init(device->device); - initialized = true; } @@ -42,7 +40,6 @@ namespace openVulkanoCpp::Vulkan if (!initialized) return; device->WaitIdle(); - pipeline.Close(); swapChainRenderPass.Close(); swapChain.Close(); deviceManager.Close(); diff --git a/openVulkanoCpp/Vulkan/Context.hpp b/openVulkanoCpp/Vulkan/Context.hpp index 22dfc3b..f9181be 100644 --- a/openVulkanoCpp/Vulkan/Context.hpp +++ b/openVulkanoCpp/Vulkan/Context.hpp @@ -10,7 +10,6 @@ #include "DeviceManager.hpp" #include "SwapChain.hpp" #include "RenderPass.hpp" -#include "Pipeline.hpp" namespace openVulkanoCpp { @@ -35,7 +34,6 @@ namespace openVulkanoCpp RenderPass swapChainRenderPass; IVulkanWindow* window = nullptr; IGraphicsAppManager* graphicsAppManager = nullptr; - Pipeline pipeline; Context() : initialized(false) { diff --git a/openVulkanoCpp/Vulkan/Pipeline.hpp b/openVulkanoCpp/Vulkan/Pipeline.hpp deleted file mode 100644 index 77f3ea3..0000000 --- a/openVulkanoCpp/Vulkan/Pipeline.hpp +++ /dev/null @@ -1,48 +0,0 @@ -/* - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at https://mozilla.org/MPL/2.0/. - */ - -#pragma once - -#include -#include "Base/ICloseable.hpp" - -namespace openVulkanoCpp::Vulkan -{ - struct Pipeline : virtual ICloseable - { - vk::Device device; - vk::DescriptorSetLayout descriptorSetLayout; - vk::PipelineLayout pipelineLayout; - vk::DescriptorPool descriptorPool; - - void Init(const vk::Device& device) - { - this->device = device; - - CreatePipelineLayout(); - } - - void Close() override - { - device.destroyPipelineLayout(pipelineLayout); - device.destroyDescriptorSetLayout(descriptorSetLayout); - } - - private: - void CreatePipelineLayout() - { - vk::PushConstantRange camPushConstantDesc = { vk::ShaderStageFlagBits::eVertex | vk::ShaderStageFlagBits::eFragment, 0, 3 * sizeof(Math::Matrix4f) + sizeof(Math::Vector4f) + 8 * sizeof(float) }; - std::array camPushConstantDescs = { camPushConstantDesc }; - vk::DescriptorSetLayoutBinding nodeLayoutBinding = { 0, vk::DescriptorType::eUniformBufferDynamic, 1, vk::ShaderStageFlagBits::eVertex }; - //vk::DescriptorSetLayoutBinding textureLayoutBinding = { 0, vk::DescriptorType::image }; - std::array layoutBindings = { nodeLayoutBinding }; - vk::DescriptorSetLayoutCreateInfo dslci = { {}, layoutBindings.size(), layoutBindings.data() }; - descriptorSetLayout = device.createDescriptorSetLayout(dslci); - vk::PipelineLayoutCreateInfo plci = { {}, 1, &descriptorSetLayout, camPushConstantDescs.size(), camPushConstantDescs.data() }; - pipelineLayout = this->device.createPipelineLayout(plci); - } - }; -} diff --git a/openVulkanoCpp/Vulkan/Renderer.cpp b/openVulkanoCpp/Vulkan/Renderer.cpp index c705be2..15daf2f 100644 --- a/openVulkanoCpp/Vulkan/Renderer.cpp +++ b/openVulkanoCpp/Vulkan/Renderer.cpp @@ -147,7 +147,6 @@ namespace openVulkanoCpp::Vulkan cmdHelper->Reset(); vk::CommandBufferInheritanceInfo inheritance = { context.swapChainRenderPass.renderPass, 0, context.swapChainRenderPass.GetFrameBuffer()->GetCurrentFrameBuffer() }; cmdHelper->cmdBuffer.begin(vk::CommandBufferBeginInfo{ vk::CommandBufferUsageFlagBits::eOneTimeSubmit | vk::CommandBufferUsageFlagBits::eRenderPassContinue, &inheritance }); - cmdHelper->cmdBuffer.pushConstants(context.pipeline.pipelineLayout, vk::ShaderStageFlagBits::eVertex | vk::ShaderStageFlagBits::eFragment, 0, 3 * sizeof(Math::Matrix4f) + sizeof(Math::Vector4f) + 8 * sizeof(float), &scene->GetCamera()->GetViewProjectionMatrix()); Scene::Drawable** drawablePointer; VulkanDrawContext drawContext { poolId, currentImageId, cmdHelper->cmdBuffer, this }; @@ -155,6 +154,7 @@ namespace openVulkanoCpp::Vulkan { Scene::Drawable* drawable = *drawablePointer; drawContext.EncodeShader(drawable->GetShader()); + cmdHelper->cmdBuffer.pushConstants(drawContext.GetShader()->pipelineLayout, vk::ShaderStageFlagBits::eVertex | vk::ShaderStageFlagBits::eFragment, 0, 3 * sizeof(Math::Matrix4f) + sizeof(Math::Vector4f) + 8 * sizeof(float), &scene->GetCamera()->GetViewProjectionMatrix()); drawable->GetEncoder().vulkan(drawable, &drawContext); } cmdHelper->cmdBuffer.end(); diff --git a/openVulkanoCpp/Vulkan/Renderer.hpp b/openVulkanoCpp/Vulkan/Renderer.hpp index c9891e0..df5cfc8 100644 --- a/openVulkanoCpp/Vulkan/Renderer.hpp +++ b/openVulkanoCpp/Vulkan/Renderer.hpp @@ -15,6 +15,7 @@ #include "Data/ReadOnlyAtomicArrayQueue.hpp" #include "CommandHelper.hpp" #include "Base/EngineConfiguration.hpp" +#include "Resources/ResourceManager.hpp" #include #include diff --git a/openVulkanoCpp/Vulkan/Resources/IShaderOwner.hpp b/openVulkanoCpp/Vulkan/Resources/IShaderOwner.hpp index 434f043..0ebe2ed 100644 --- a/openVulkanoCpp/Vulkan/Resources/IShaderOwner.hpp +++ b/openVulkanoCpp/Vulkan/Resources/IShaderOwner.hpp @@ -6,20 +6,15 @@ #pragma once -#include "Vulkan/Scene/VulkanShader.hpp" - -namespace openVulkanoCpp +namespace openVulkanoCpp::Vulkan { - namespace Vulkan + struct VulkanShader; + + class IShaderOwner { - struct VulkanShader; + public: + virtual ~IShaderOwner() = default; - class IShaderOwner - { - public: - virtual ~IShaderOwner() = default; - - virtual void RemoveShader(VulkanShader* shader) = 0; - }; - } -} + virtual void RemoveShader(VulkanShader* shader) = 0; + }; +} \ No newline at end of file diff --git a/openVulkanoCpp/Vulkan/Resources/ResourceManager.cpp b/openVulkanoCpp/Vulkan/Resources/ResourceManager.cpp index 65bca69..e86ba37 100644 --- a/openVulkanoCpp/Vulkan/Resources/ResourceManager.cpp +++ b/openVulkanoCpp/Vulkan/Resources/ResourceManager.cpp @@ -21,6 +21,7 @@ namespace openVulkanoCpp::Vulkan ResourceManager::ResourceManager() { + static_assert(sizeof(DescriptorSetLayoutBinding) == sizeof(vk::DescriptorSetLayoutBinding)); freeFunction = [this](ManagedBuffer* buffer) { this->FreeBuffer(buffer); }; } @@ -50,6 +51,23 @@ namespace openVulkanoCpp::Vulkan transferQueue = this->device.getQueue(context->device->queueIndices.transfer, 0); + // Setup descriptor pool + constexpr vk::DescriptorPoolSize sizeInfo[] = { + { vk::DescriptorType::eSampler, 100000 }, + { vk::DescriptorType::eCombinedImageSampler, 100000 }, + { vk::DescriptorType::eSampledImage, 100000 }, + { vk::DescriptorType::eStorageImage, 100000 }, + { vk::DescriptorType::eUniformTexelBuffer, 100000 }, + { vk::DescriptorType::eStorageTexelBuffer, 100000 }, + { vk::DescriptorType::eUniformBuffer, 100000 }, + { vk::DescriptorType::eStorageBuffer, 100000 }, + { vk::DescriptorType::eUniformBufferDynamic, 100000 }, + { vk::DescriptorType::eStorageBufferDynamic, 100000 }, + { vk::DescriptorType::eInputAttachment, 100000 } + }; + const vk::DescriptorPoolCreateInfo poolCreateInfo(vk::DescriptorPoolCreateFlagBits::eFreeDescriptorSet, 100000, std::size(sizeInfo), sizeInfo); + descriptorPool = device.createDescriptorPool(poolCreateInfo); + INSTANCE = this; } @@ -61,6 +79,7 @@ namespace openVulkanoCpp::Vulkan device.freeCommandBuffers(cmdPools[i], 1, &cmdBuffers[i]); device.destroyCommandPool(cmdPools[i]); } + device.destroyDescriptorPool(descriptorPool); shaders.clear(); cmdBuffers = nullptr; cmdPools = nullptr; @@ -131,8 +150,10 @@ namespace openVulkanoCpp::Vulkan ManagedBuffer* buffer; VulkanNode* vkNode; const vk::DeviceSize allocSize = Utils::Align(sizeof(Math::Matrix4f), uniformBufferAlignment); + vk::DeviceSize frameSize = 0; if (node->GetUpdateFrequency() != Scene::UpdateFrequency::Never) { + frameSize = allocSize; vkNode = new VulkanNodeDynamic(); const uint32_t imgs = context->swapChain.GetImageCount(); buffer = CreateBuffer(imgs * allocSize, vk::BufferUsageFlagBits::eUniformBuffer, vk::MemoryPropertyFlagBits::eHostCoherent | vk::MemoryPropertyFlagBits::eHostVisible); @@ -143,12 +164,24 @@ namespace openVulkanoCpp::Vulkan vkNode = new VulkanNode(); buffer = CreateDeviceOnlyBufferWithData(sizeof(Math::Matrix4f), vk::BufferUsageFlagBits::eUniformBuffer, &node->worldMat); } - uBuffer->Init(buffer, allocSize, &context->pipeline.descriptorSetLayout, context->pipeline.pipelineLayout); + + uBuffer->Init(buffer, frameSize, allocSize, GetDescriptorLayoutSet(NODE_LAYOUT_BINDING)); vkNode->Init(node, uBuffer); node->renderNode = vkNode; } } + vk::DescriptorSetLayout* ResourceManager::GetDescriptorLayoutSet(const DescriptorSetLayoutBinding& descriptorSetLayoutBinding) + { + auto& layout = descriptorSetLayoutCache[descriptorSetLayoutBinding]; + if (!layout) + { + vk::DescriptorSetLayoutCreateInfo createInfo({}, 1, &reinterpret_cast(descriptorSetLayoutBinding)); + layout = device.createDescriptorSetLayout(createInfo); + } + return &layout; + } + ManagedBuffer* ResourceManager::CreateSharedMemoryBuffer(const size_t size) { const std::unique_lock lock(mutex); diff --git a/openVulkanoCpp/Vulkan/Resources/ResourceManager.hpp b/openVulkanoCpp/Vulkan/Resources/ResourceManager.hpp index 848d317..9911134 100644 --- a/openVulkanoCpp/Vulkan/Resources/ResourceManager.hpp +++ b/openVulkanoCpp/Vulkan/Resources/ResourceManager.hpp @@ -11,8 +11,10 @@ #include "IShaderOwner.hpp" #include "ManagedResource.hpp" #include "Vulkan/Image.hpp" +#include "Scene/Shader/DescriptorInputDescription.hpp" #include #include +#include namespace openVulkanoCpp { @@ -22,15 +24,20 @@ namespace openVulkanoCpp class Geometry; class Material; class Texture; + class Shader; } namespace Vulkan { + class Context; class VulkanGeometry; class VulkanTexture; + class UniformBuffer; class ResourceManager : public ICloseable, public IShaderOwner { + friend UniformBuffer; + Context* context; vk::Device device = nullptr; vk::Queue transferQueue = nullptr; @@ -45,6 +52,8 @@ namespace openVulkanoCpp std::vector> toFree; std::vector recycleBuffers; std::function freeFunction; + vk::DescriptorPool descriptorPool; + std::map descriptorSetLayoutCache; int buffers = -1, currentBuffer = -1; @@ -104,6 +113,8 @@ namespace openVulkanoCpp MemoryAllocation* GetFreeMemoryAllocation(size_t size, uint32_t type, bool createIfAllFull = true); + vk::DescriptorSetLayout* GetDescriptorLayoutSet(const DescriptorSetLayoutBinding& descriptorSetLayoutBinding); + public: VulkanShader* CreateShader(Scene::Shader* shader); }; diff --git a/openVulkanoCpp/Vulkan/Resources/UniformBuffer.hpp b/openVulkanoCpp/Vulkan/Resources/UniformBuffer.hpp index 3d2b6b5..f0b80b0 100644 --- a/openVulkanoCpp/Vulkan/Resources/UniformBuffer.hpp +++ b/openVulkanoCpp/Vulkan/Resources/UniformBuffer.hpp @@ -7,55 +7,56 @@ #pragma once #include "Base/ICloseable.hpp" -#include "Vulkan/Scene/IRecordable.hpp" #include "ManagedResource.hpp" +#include "Vulkan/Scene/IRecordable.hpp" +#include "Vulkan/Scene/VulkanShader.hpp" +#include "Vulkan/VulkanDrawContext.hpp" -namespace openVulkanoCpp +namespace openVulkanoCpp::Vulkan { - namespace Vulkan + class UniformBuffer final : IRecordable, ICloseable { - struct UniformBuffer : virtual ICloseable, virtual IRecordable + ManagedBuffer* m_buffer; + vk::DescriptorSet m_descriptorSet; + uint32_t m_frameOffset; + + public: + ~UniformBuffer() override { - ManagedBuffer* buffer; - vk::DescriptorPool descPool; - vk::DescriptorSet descSet; - vk::PipelineLayout layout; - uint32_t allocSizeFrame; + if (m_buffer) Close(); + } - void Init(ManagedBuffer* buffer, uint32_t allocSizeFrame, vk::DescriptorSetLayout* descriptorSetLayout, vk::PipelineLayout layout) - { - this->buffer = buffer; - this->layout = layout; - this->allocSizeFrame = allocSizeFrame; - vk::DescriptorPoolSize poolSize = { vk::DescriptorType::eUniformBufferDynamic, 1 }; - const vk::DescriptorPoolCreateInfo poolCreateInfo = { {}, 1, 1, &poolSize }; - descPool = buffer->allocation->device.createDescriptorPool(poolCreateInfo); - const vk::DescriptorSetAllocateInfo descSetAllocInfo = { descPool, 1, descriptorSetLayout }; - descSet = buffer->allocation->device.allocateDescriptorSets(descSetAllocInfo)[0]; - vk::DescriptorBufferInfo bufferInfo = { buffer->buffer, 0, allocSizeFrame }; - vk::WriteDescriptorSet writeDescriptorSet = { descSet }; - writeDescriptorSet.descriptorCount = 1; - writeDescriptorSet.descriptorType = vk::DescriptorType::eUniformBufferDynamic; - writeDescriptorSet.pBufferInfo = &bufferInfo; - buffer->allocation->device.updateDescriptorSets(1, &writeDescriptorSet, 0, nullptr); - } + void Init(ManagedBuffer* buffer, uint32_t frameOffset, uint32_t frameSize, vk::DescriptorSetLayout* descriptorSetLayout) + { + m_buffer = buffer; + m_frameOffset = frameOffset; - void Record(vk::CommandBuffer& cmdBuffer, uint32_t bufferId) override - { - uint32_t frameOffset = allocSizeFrame * bufferId; - cmdBuffer.bindDescriptorSets(vk::PipelineBindPoint::eGraphics, layout, 0, 1, - &descSet, 1, &frameOffset); - } + const vk::DescriptorSetAllocateInfo descSetAllocInfo = { ResourceManager::INSTANCE->descriptorPool, 1, descriptorSetLayout }; + m_descriptorSet = buffer->allocation->device.allocateDescriptorSets(descSetAllocInfo)[0]; + vk::DescriptorBufferInfo bufferInfo = { buffer->buffer, 0, frameSize }; + vk::WriteDescriptorSet writeDescriptorSet = { m_descriptorSet }; + writeDescriptorSet.descriptorCount = 1; + writeDescriptorSet.descriptorType = vk::DescriptorType::eUniformBufferDynamic; + writeDescriptorSet.pBufferInfo = &bufferInfo; + buffer->allocation->device.updateDescriptorSets(1, &writeDescriptorSet, 0, nullptr); + } - void Update(void* data, uint32_t size, uint32_t bufferId) const - { - buffer->Copy(data, size, allocSizeFrame * bufferId); - } + void Close() override + { //TODO handle this better + m_buffer->allocation->device.freeDescriptorSets(ResourceManager::INSTANCE->descriptorPool, 1, &m_descriptorSet); + m_buffer = nullptr; + } - void Close() override - { - buffer->allocation->device.destroyDescriptorPool(descPool); - } - }; - } + void Record(VulkanDrawContext* drawContext) override + { + uint32_t frameOffset = m_frameOffset * drawContext->currentImageId; + drawContext->commandBuffer.bindDescriptorSets(vk::PipelineBindPoint::eGraphics, drawContext->GetShader()->pipelineLayout, 0, 1, + &m_descriptorSet, 1, &frameOffset); + } + + void Update(void* data, uint32_t size, uint32_t bufferId) const + { + m_buffer->Copy(data, size, m_frameOffset * bufferId); + } + }; } diff --git a/openVulkanoCpp/Vulkan/Scene/IRecordable.hpp b/openVulkanoCpp/Vulkan/Scene/IRecordable.hpp index 1c27b29..1727021 100644 --- a/openVulkanoCpp/Vulkan/Scene/IRecordable.hpp +++ b/openVulkanoCpp/Vulkan/Scene/IRecordable.hpp @@ -6,17 +6,15 @@ #pragma once +#include "Vulkan/VulkanDrawContext.hpp" #include -namespace openVulkanoCpp +namespace openVulkanoCpp::Vulkan { - namespace Vulkan + class IRecordable { - class IRecordable - { - public: - virtual ~IRecordable() = default; - virtual void Record(vk::CommandBuffer& cmdBuffer, uint32_t bufferId) = 0; - }; - } + public: + virtual ~IRecordable() = default; + virtual void Record(VulkanDrawContext* context) = 0; + }; } diff --git a/openVulkanoCpp/Vulkan/Scene/SimpleDrawableVulkanEncoder.cpp b/openVulkanoCpp/Vulkan/Scene/SimpleDrawableVulkanEncoder.cpp index d68ec4b..e1d3029 100644 --- a/openVulkanoCpp/Vulkan/Scene/SimpleDrawableVulkanEncoder.cpp +++ b/openVulkanoCpp/Vulkan/Scene/SimpleDrawableVulkanEncoder.cpp @@ -22,7 +22,7 @@ namespace openVulkanoCpp::Vulkan for(Node* node : instance->GetNodes()) { if (!node->renderNode) drawContext->renderer->GetResourceManager().PrepareNode(node); - static_cast(node->renderNode)->Record(drawContext->commandBuffer, drawContext->currentImageId); + static_cast(node->renderNode)->Record(drawContext); renderGeo->RecordDraw(drawContext->commandBuffer); } } diff --git a/openVulkanoCpp/Vulkan/Scene/VulkanNode.hpp b/openVulkanoCpp/Vulkan/Scene/VulkanNode.hpp index eb9af89..1f0546e 100644 --- a/openVulkanoCpp/Vulkan/Scene/VulkanNode.hpp +++ b/openVulkanoCpp/Vulkan/Scene/VulkanNode.hpp @@ -11,50 +11,47 @@ #include "Scene/Camera.hpp" #include "Vulkan/Resources/UniformBuffer.hpp" -namespace openVulkanoCpp +namespace openVulkanoCpp::Vulkan { - namespace Vulkan + struct VulkanNode : IRecordable, ICloseable { - struct VulkanNode : IRecordable, ICloseable + Scene::Node* node = nullptr; + UniformBuffer* buffer = nullptr; + + virtual void Init(Scene::Node* node, UniformBuffer* uniformBuffer) { - Scene::Node* node = nullptr; - UniformBuffer* buffer = nullptr; + this->node = node; + this->buffer = uniformBuffer; + } - virtual void Init(Scene::Node* node, UniformBuffer* uniformBuffer) - { - this->node = node; - this->buffer = uniformBuffer; - } - - void Record(vk::CommandBuffer& cmdBuffer, uint32_t bufferId) override - { - buffer->Record(cmdBuffer, 0); - } - - void Close() override {} - }; - - struct VulkanNodeDynamic : VulkanNode + void Record(VulkanDrawContext* context) override { - uint32_t lastUpdate = -1; + buffer->Record(context); + } - void Init(Scene::Node* node, UniformBuffer* uniformBuffer) override + void Close() override {} + }; + + struct VulkanNodeDynamic : VulkanNode + { + uint32_t lastUpdate = -1; + + void Init(Scene::Node* node, UniformBuffer* uniformBuffer) override + { + VulkanNode::Init(node, uniformBuffer); + lastUpdate = -1; + } + + void Record(VulkanDrawContext* context) override + { + //if(context->currentImageId != lastUpdate) //TODO fix { - VulkanNode::Init(node, uniformBuffer); - lastUpdate = -1; + //lastUpdate = bufferId; + buffer->Update(&node->worldMat, sizeof(Math::Matrix4f), context->currentImageId); } + buffer->Record(context); + } - void Record(vk::CommandBuffer& cmdBuffer, uint32_t bufferId) override - { - if(bufferId != lastUpdate) - { - lastUpdate = bufferId; - buffer->Update(&node->worldMat, sizeof(Math::Matrix4f), bufferId); - } - buffer->Record(cmdBuffer, bufferId); - } - - void Close() override{} - }; - } + void Close() override{} + }; } diff --git a/openVulkanoCpp/Vulkan/Scene/VulkanShader.cpp b/openVulkanoCpp/Vulkan/Scene/VulkanShader.cpp index 012cf32..28c096b 100644 --- a/openVulkanoCpp/Vulkan/Scene/VulkanShader.cpp +++ b/openVulkanoCpp/Vulkan/Scene/VulkanShader.cpp @@ -8,9 +8,12 @@ #include "Vulkan/Context.hpp" #include "Scene/Shader/Shader.hpp" #include "Vulkan/Resources/IShaderOwner.hpp" +#include "Scene/Shader/DescriptorInputDescription.hpp" namespace openVulkanoCpp::Vulkan { + static_assert(sizeof(vk::DescriptorSetLayoutBinding) == sizeof(DescriptorSetLayoutBinding)); + VulkanShader::~VulkanShader() { if (!shader) return; @@ -19,6 +22,8 @@ namespace openVulkanoCpp::Vulkan { device.destroyShaderModule(shaderModule); } + device.destroyPipelineLayout(pipelineLayout); + device.destroyDescriptorSetLayout(descriptorSetLayout); } void VulkanShader::Init(Context* context, Scene::Shader* shader, IShaderOwner* owner) @@ -98,10 +103,10 @@ namespace openVulkanoCpp::Vulkan colorInfo.attachmentCount = 1; colorInfo.pAttachments = &colorBlendAttachment; - + CreatePipelineLayout(); vk::GraphicsPipelineCreateInfo pipelineCreateInfo = { {}, static_cast(shaderStageCreateInfo.size()), shaderStageCreateInfo.data(), &pipelineVertexInputStateCreateInfo, &inputAssembly, - nullptr, &viewportStateCreateInfo, &rasterizer, &msaa, &depth, &colorInfo, nullptr, context->pipeline.pipelineLayout, context->swapChainRenderPass.renderPass }; + nullptr, &viewportStateCreateInfo, &rasterizer, &msaa, &depth, &colorInfo, nullptr, pipelineLayout, context->swapChainRenderPass.renderPass }; pipeline = this->device.createGraphicsPipeline({}, pipelineCreateInfo).value; } @@ -111,13 +116,24 @@ namespace openVulkanoCpp::Vulkan BuildPipeline(); } - void VulkanShader::Record(vk::CommandBuffer& cmdBuffer, uint32_t bufferId) + void VulkanShader::Record(VulkanDrawContext* context) { - cmdBuffer.bindPipeline(vk::PipelineBindPoint::eGraphics, pipeline); + context->commandBuffer.bindPipeline(vk::PipelineBindPoint::eGraphics, pipeline); } void VulkanShader::Close() { owner->RemoveShader(this); } + + void VulkanShader::CreatePipelineLayout() + { + vk::PushConstantRange camPushConstantDesc = { vk::ShaderStageFlagBits::eVertex | vk::ShaderStageFlagBits::eFragment, 0, 3 * sizeof(Math::Matrix4f) + sizeof(Math::Vector4f) + 8 * sizeof(float) }; + std::array camPushConstantDescs = { camPushConstantDesc }; + std::array layoutBindings = { reinterpret_cast(NODE_LAYOUT_BINDING) }; + vk::DescriptorSetLayoutCreateInfo dslci = { {}, layoutBindings.size(), layoutBindings.data() }; + descriptorSetLayout = device.createDescriptorSetLayout(dslci); + vk::PipelineLayoutCreateInfo plci = { {}, 1, &descriptorSetLayout, camPushConstantDescs.size(), camPushConstantDescs.data() }; + pipelineLayout = this->device.createPipelineLayout(plci); + } } \ No newline at end of file diff --git a/openVulkanoCpp/Vulkan/Scene/VulkanShader.hpp b/openVulkanoCpp/Vulkan/Scene/VulkanShader.hpp index 92f0efe..e8b4127 100644 --- a/openVulkanoCpp/Vulkan/Scene/VulkanShader.hpp +++ b/openVulkanoCpp/Vulkan/Scene/VulkanShader.hpp @@ -30,6 +30,8 @@ namespace openVulkanoCpp std::vector shaderModules; // TODO manage live time somewhere else to allow sharing of shader programs std::vector shaderStageCreateInfo; vk::Pipeline pipeline; // TODO pipeline and shader config should be split + vk::DescriptorSetLayout descriptorSetLayout; + vk::PipelineLayout pipelineLayout; IShaderOwner* owner = nullptr; Context* context = nullptr; @@ -41,12 +43,14 @@ namespace openVulkanoCpp void Resize(); - void Record(vk::CommandBuffer& cmdBuffer, uint32_t bufferId) override; + void Record(VulkanDrawContext* context) override; void Close() override; private: void BuildPipeline(); + + void CreatePipelineLayout(); }; } } \ No newline at end of file diff --git a/openVulkanoCpp/Vulkan/Scene/VulkanTexture.hpp b/openVulkanoCpp/Vulkan/Scene/VulkanTexture.hpp index 860e3be..26468df 100644 --- a/openVulkanoCpp/Vulkan/Scene/VulkanTexture.hpp +++ b/openVulkanoCpp/Vulkan/Scene/VulkanTexture.hpp @@ -24,7 +24,7 @@ namespace openVulkanoCpp::Vulkan texture->updated = false; } - void Record(vk::CommandBuffer& cmdBuffer, uint32_t bufferId) override + void Record(VulkanDrawContext* context) override { //cmdBuffer.bindDescriptorSets(vk::PipelineBindPoint::eGraphics, ) } @@ -42,15 +42,15 @@ namespace openVulkanoCpp::Vulkan lastUpdate = -1; } - void Record(vk::CommandBuffer& cmdBuffer, uint32_t bufferId) override + void Record(VulkanDrawContext* context) override { - if(bufferId != lastUpdate && m_texture->updated) + /*if(bufferId != lastUpdate && m_texture->updated) { lastUpdate = bufferId; resourceManager->CopyDataToImage(m_texture->size, m_texture->textureBuffer, this); m_texture->updated = false; } - VulkanTexture::Record(cmdBuffer, bufferId); + VulkanTexture::Record(cmdBuffer, bufferId);*/ } }; } \ No newline at end of file diff --git a/openVulkanoCpp/Vulkan/VulkanDrawContext.cpp b/openVulkanoCpp/Vulkan/VulkanDrawContext.cpp index 56f4ce5..f01d795 100644 --- a/openVulkanoCpp/Vulkan/VulkanDrawContext.cpp +++ b/openVulkanoCpp/Vulkan/VulkanDrawContext.cpp @@ -18,7 +18,14 @@ namespace openVulkanoCpp::Vulkan vkShader = renderer->GetResourceManager().CreateShader(shader); } else if (m_lastShader == vkShader) return; // Skip it if shader is already bound - vkShader->Record(commandBuffer, currentImageId); + vkShader->Record(this); + m_lastShader = vkShader; + } + + void VulkanDrawContext::EncodeShader(VulkanShader* vkShader) + { + if (m_lastShader == vkShader) return; // Skip it if shader is already bound + vkShader->Record(this); m_lastShader = vkShader; } } \ No newline at end of file diff --git a/openVulkanoCpp/Vulkan/VulkanDrawContext.hpp b/openVulkanoCpp/Vulkan/VulkanDrawContext.hpp index e776193..464b3b0 100644 --- a/openVulkanoCpp/Vulkan/VulkanDrawContext.hpp +++ b/openVulkanoCpp/Vulkan/VulkanDrawContext.hpp @@ -4,6 +4,8 @@ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ +#pragma once + #include "Renderer.hpp" namespace openVulkanoCpp::Vulkan @@ -23,5 +25,9 @@ namespace openVulkanoCpp::Vulkan {} void EncodeShader(Scene::Shader* shader); + + void EncodeShader(VulkanShader* shader); + + VulkanShader* GetShader() const { return m_lastShader; } }; }