Update how camera data is communicated to shader

This commit is contained in:
2023-08-31 21:16:11 +02:00
parent 93c75763c7
commit df4194be51
21 changed files with 265 additions and 177 deletions

View File

@@ -8,7 +8,7 @@
#include "Base/Logger.hpp"
#include <list>
#define RENDER_DOC
//#define RENDER_DOC
namespace openVulkanoCpp::Vulkan
{

View File

@@ -61,14 +61,14 @@ namespace openVulkanoCpp::Vulkan
// Color attachment
attachments.emplace_back(vk::AttachmentDescriptionFlags(), m_frameBuffer->GetColorFormat(), vk::SampleCountFlagBits::e1,
m_useClearColor ? vk::AttachmentLoadOp::eClear : vk::AttachmentLoadOp::eLoad, vk::AttachmentStoreOp::eStore, vk::AttachmentLoadOp::eLoad,
vk::AttachmentStoreOp::eStore, vk::ImageLayout::eUndefined, vk::ImageLayout::ePresentSrcKHR);
vk::AttachmentStoreOp::eStore, vk::ImageLayout::ePresentSrcKHR, vk::ImageLayout::ePresentSrcKHR);
vk::AttachmentReference* depthReference = nullptr;
if (m_frameBuffer->UseDepthBuffer())
{ // Depth attachment
attachments.emplace_back(vk::AttachmentDescriptionFlags(), m_frameBuffer->GetDepthFormat(), vk::SampleCountFlagBits::e1,
m_useClearDepth ? vk::AttachmentLoadOp::eClear : vk::AttachmentLoadOp::eLoad, vk::AttachmentStoreOp::eDontCare, m_useClearDepth ? vk::AttachmentLoadOp::eClear : vk::AttachmentLoadOp::eLoad,
vk::AttachmentStoreOp::eDontCare, vk::ImageLayout::eUndefined, vk::ImageLayout::eDepthStencilAttachmentOptimal);
vk::AttachmentStoreOp::eDontCare, vk::ImageLayout::eDepthStencilAttachmentOptimal, vk::ImageLayout::eDepthStencilAttachmentOptimal);
depthReference = new vk::AttachmentReference(1, vk::ImageLayout::eDepthStencilAttachmentOptimal);
}

View File

@@ -13,6 +13,7 @@
#include "Scene/VulkanShader.hpp"
#include "Base/UI/IVulkanWindow.hpp"
#include "Host/PlatformProducer.hpp"
#include "Vulkan/Scene/VulkanCamera.hpp"
#include <stdexcept>
namespace openVulkanoCpp::Vulkan
@@ -150,11 +151,15 @@ namespace openVulkanoCpp::Vulkan
Scene::Drawable** drawablePointer;
VulkanDrawContext drawContext { poolId, currentImageId, cmdHelper->cmdBuffer, this };
if (!scene->GetCamera()->renderCamera) resourceManager.PrepareCamera(scene->GetCamera());
while((drawablePointer = jobQueue->Pop()) != nullptr)
{
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());
static_cast<VulkanCamera*>(scene->GetCamera()->renderCamera)->Record(&drawContext);
//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();

View File

@@ -14,6 +14,7 @@
#include "Vulkan/Scene/VulkanNode.hpp"
#include "Vulkan/Scene/VulkanTexture.hpp"
#include "Vulkan/Image.hpp"
#include "Vulkan/Scene/VulkanCamera.hpp"
namespace openVulkanoCpp::Vulkan
{
@@ -165,12 +166,29 @@ namespace openVulkanoCpp::Vulkan
buffer = CreateDeviceOnlyBufferWithData(sizeof(Math::Matrix4f), vk::BufferUsageFlagBits::eUniformBuffer, &node->worldMat);
}
uBuffer->Init(buffer, frameSize, allocSize, GetDescriptorLayoutSet(NODE_LAYOUT_BINDING));
uBuffer->Init(buffer, frameSize, allocSize, GetDescriptorLayoutSet(NODE_LAYOUT_BINDING), NODE_LAYOUT_BINDING, 0);
vkNode->Init(node, uBuffer);
node->renderNode = vkNode;
}
}
void ResourceManager::PrepareCamera(Scene::Camera* camera)
{
const std::unique_lock lock(mutex);
if (!camera->renderCamera)
{
const vk::DeviceSize allocSize = Utils::Align(Scene::Camera::SIZE, uniformBufferAlignment);
const uint32_t imgs = context->swapChain.GetImageCount();
ManagedBuffer* buffer = CreateBuffer(imgs * allocSize, vk::BufferUsageFlagBits::eUniformBuffer, vk::MemoryPropertyFlagBits::eHostCoherent | vk::MemoryPropertyFlagBits::eHostVisible);
buffer->Map();
UniformBuffer* uBuffer = new UniformBuffer();
uBuffer->Init(buffer, allocSize, allocSize, GetDescriptorLayoutSet(CAM_LAYOUT_BINDING), CAM_LAYOUT_BINDING, 1);
VulkanCamera* vkCam = new VulkanCamera();
vkCam->Init(camera, uBuffer);
camera->renderCamera = vkCam;
}
}
vk::DescriptorSetLayout* ResourceManager::GetDescriptorLayoutSet(const DescriptorSetLayoutBinding& descriptorSetLayoutBinding)
{
auto& layout = descriptorSetLayoutCache[descriptorSetLayoutBinding];

View File

@@ -12,6 +12,7 @@
#include "ManagedResource.hpp"
#include "Vulkan/Image.hpp"
#include "Scene/Shader/DescriptorInputDescription.hpp"
#include "Scene/Camera.hpp"
#include <mutex>
#include <functional>
#include <map>
@@ -82,6 +83,8 @@ namespace openVulkanoCpp
VulkanTexture* PrepareTexture(Scene::Texture* texture);
void PrepareCamera(Scene::Camera* camera);
void RemoveShader(VulkanShader* shader) override;
void CopyDataToImage(vk::DeviceSize size, void* data, openVulkanoCpp::Vulkan::Image* image);

View File

@@ -19,6 +19,7 @@ namespace openVulkanoCpp::Vulkan
ManagedBuffer* m_buffer;
vk::DescriptorSet m_descriptorSet;
uint32_t m_frameOffset;
uint32_t m_setOffset, m_setCount = 1;
public:
~UniformBuffer() override
@@ -26,7 +27,7 @@ namespace openVulkanoCpp::Vulkan
if (m_buffer) Close();
}
void Init(ManagedBuffer* buffer, uint32_t frameOffset, uint32_t frameSize, vk::DescriptorSetLayout* descriptorSetLayout)
void Init(ManagedBuffer* buffer, uint32_t frameOffset, uint32_t frameSize, vk::DescriptorSetLayout* descriptorSetLayout, const DescriptorSetLayoutBinding& binding, uint32_t setId)
{
m_buffer = buffer;
m_frameOffset = frameOffset;
@@ -34,11 +35,11 @@ namespace openVulkanoCpp::Vulkan
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;
vk::WriteDescriptorSet writeDescriptorSet = { m_descriptorSet, binding.bindingId, 0, 1 };
writeDescriptorSet.descriptorType = static_cast<vk::DescriptorType>(binding.descriptorType);
writeDescriptorSet.pBufferInfo = &bufferInfo;
buffer->allocation->device.updateDescriptorSets(1, &writeDescriptorSet, 0, nullptr);
m_setOffset = setId;
}
void Close() override
@@ -50,8 +51,7 @@ namespace openVulkanoCpp::Vulkan
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);
drawContext->commandBuffer.bindDescriptorSets(vk::PipelineBindPoint::eGraphics, drawContext->GetShader()->pipelineLayout, m_setOffset, m_setCount, &m_descriptorSet, 1, &frameOffset);
}
void Update(void* data, uint32_t size, uint32_t bufferId) const

View File

@@ -0,0 +1,38 @@
/*
* 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 "Base/ICloseable.hpp"
#include "IRecordable.hpp"
#include "Vulkan/Resources/UniformBuffer.hpp"
namespace openVulkanoCpp::Vulkan
{
class VulkanCamera : public ICloseable, public IRecordable
{
Scene::Camera* camera = nullptr;
UniformBuffer* buffer = nullptr;
public:
void Init(Scene::Camera* camera, UniformBuffer* uniformBuffer)
{
this->camera = camera;
buffer = uniformBuffer;
}
void Record(VulkanDrawContext* context) override
{
buffer->Update(camera->GetData(), Scene::Camera::SIZE, context->currentImageId);
buffer->Record(context);
}
void Close() override
{
buffer->Close();
}
};
}

View File

@@ -23,7 +23,8 @@ namespace openVulkanoCpp::Vulkan
device.destroyShaderModule(shaderModule);
}
device.destroyPipelineLayout(pipelineLayout);
device.destroyDescriptorSetLayout(descriptorSetLayout);
for(auto& descriptorSetLayout : descriptorSetLayouts)
device.destroyDescriptorSetLayout(descriptorSetLayout);
}
void VulkanShader::Init(Context* context, Scene::Shader* shader, IShaderOwner* owner)
@@ -128,12 +129,15 @@ namespace openVulkanoCpp::Vulkan
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() };
//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> layoutBindings1 = { reinterpret_cast<const vk::DescriptorSetLayoutBinding&>(NODE_LAYOUT_BINDING) };
std::array<vk::DescriptorSetLayoutBinding, 1> layoutBindings2 = { reinterpret_cast<const vk::DescriptorSetLayoutBinding&>(CAM_LAYOUT_BINDING) };
vk::DescriptorSetLayoutCreateInfo dslci = { {}, layoutBindings1.size(), layoutBindings1.data() };
vk::DescriptorSetLayoutCreateInfo dslci2 = { {}, layoutBindings2.size(), layoutBindings2.data() };
descriptorSetLayouts.push_back(device.createDescriptorSetLayout(dslci));
descriptorSetLayouts.push_back(device.createDescriptorSetLayout(dslci2));
vk::PipelineLayoutCreateInfo plci = { {}, static_cast<uint32_t>(descriptorSetLayouts.size()), descriptorSetLayouts.data(), 0, nullptr };
pipelineLayout = this->device.createPipelineLayout(plci);
}
}

View File

@@ -30,7 +30,7 @@ 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;
std::vector<vk::DescriptorSetLayout> descriptorSetLayouts;
vk::PipelineLayout pipelineLayout;
IShaderOwner* owner = nullptr;
Context* context = nullptr;

View File

@@ -15,8 +15,8 @@ namespace openVulkanoCpp::Vulkan
VulkanShader* m_lastShader = nullptr;
public:
size_t encoderThreadId;
size_t currentImageId;
const size_t encoderThreadId;
const size_t currentImageId;
vk::CommandBuffer& commandBuffer;
Renderer* renderer;