[WIP] Refactor creation of descriptorsets
This commit is contained in:
@@ -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};
|
||||
}
|
||||
@@ -6,6 +6,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Base/Utils.hpp"
|
||||
#include <string_view>
|
||||
#include <cinttypes>
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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 <vulkan/vulkan.hpp>
|
||||
#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<vk::PushConstantRange, 1> camPushConstantDescs = { camPushConstantDesc };
|
||||
vk::DescriptorSetLayoutBinding nodeLayoutBinding = { 0, vk::DescriptorType::eUniformBufferDynamic, 1, vk::ShaderStageFlagBits::eVertex };
|
||||
//vk::DescriptorSetLayoutBinding textureLayoutBinding = { 0, vk::DescriptorType::image };
|
||||
std::array<vk::DescriptorSetLayoutBinding, 1> 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);
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -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();
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
#include "Data/ReadOnlyAtomicArrayQueue.hpp"
|
||||
#include "CommandHelper.hpp"
|
||||
#include "Base/EngineConfiguration.hpp"
|
||||
#include "Resources/ResourceManager.hpp"
|
||||
#include <vector>
|
||||
#include <thread>
|
||||
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
}
|
||||
@@ -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<const vk::DescriptorSetLayoutBinding&>(descriptorSetLayoutBinding));
|
||||
layout = device.createDescriptorSetLayout(createInfo);
|
||||
}
|
||||
return &layout;
|
||||
}
|
||||
|
||||
ManagedBuffer* ResourceManager::CreateSharedMemoryBuffer(const size_t size)
|
||||
{
|
||||
const std::unique_lock lock(mutex);
|
||||
|
||||
@@ -11,8 +11,10 @@
|
||||
#include "IShaderOwner.hpp"
|
||||
#include "ManagedResource.hpp"
|
||||
#include "Vulkan/Image.hpp"
|
||||
#include "Scene/Shader/DescriptorInputDescription.hpp"
|
||||
#include <mutex>
|
||||
#include <functional>
|
||||
#include <map>
|
||||
|
||||
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<std::vector<ManagedBuffer*>> toFree;
|
||||
std::vector<ManagedBuffer*> recycleBuffers;
|
||||
std::function<void(ManagedBuffer*)> freeFunction;
|
||||
vk::DescriptorPool descriptorPool;
|
||||
std::map<DescriptorSetLayoutBinding, vk::DescriptorSetLayout> 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);
|
||||
};
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -6,17 +6,15 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Vulkan/VulkanDrawContext.hpp"
|
||||
#include <vulkan/vulkan.hpp>
|
||||
|
||||
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;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ namespace openVulkanoCpp::Vulkan
|
||||
for(Node* node : instance->GetNodes())
|
||||
{
|
||||
if (!node->renderNode) drawContext->renderer->GetResourceManager().PrepareNode(node);
|
||||
static_cast<VulkanNode*>(node->renderNode)->Record(drawContext->commandBuffer, drawContext->currentImageId);
|
||||
static_cast<VulkanNode*>(node->renderNode)->Record(drawContext);
|
||||
renderGeo->RecordDraw(drawContext->commandBuffer);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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{}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -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<uint32_t>(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<vk::PushConstantRange, 1> camPushConstantDescs = { camPushConstantDesc };
|
||||
std::array<vk::DescriptorSetLayoutBinding, 1> layoutBindings = { reinterpret_cast<const vk::DescriptorSetLayoutBinding&>(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);
|
||||
}
|
||||
}
|
||||
@@ -30,6 +30,8 @@ namespace openVulkanoCpp
|
||||
std::vector<vk::ShaderModule> shaderModules; // TODO manage live time somewhere else to allow sharing of shader programs
|
||||
std::vector<vk::PipelineShaderStageCreateInfo> 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();
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -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);*/
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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; }
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user