From e501a69b36569560bcd1258e5badeb962c351a5e Mon Sep 17 00:00:00 2001 From: Dynamitos Date: Tue, 18 Jun 2024 23:33:03 +0200 Subject: [PATCH] Fixing initial frames --- src/Engine/Graphics/Buffer.h | 2 +- src/Engine/Graphics/RayTracing.cpp | 7 + src/Engine/Graphics/RayTracing.h | 8 +- .../Graphics/RenderPass/LightCullingPass.cpp | 5 +- .../Graphics/RenderPass/VisibilityPass.cpp | 2 +- src/Engine/Graphics/Vulkan/Buffer.cpp | 11 +- src/Engine/Graphics/Vulkan/Buffer.h | 4 +- src/Engine/Graphics/Vulkan/Graphics.cpp | 9 + src/Engine/Graphics/Vulkan/PipelineCache.cpp | 155 +++++++++++++++++- src/Engine/Graphics/Vulkan/PipelineCache.h | 1 + src/Engine/Graphics/Vulkan/RayTracing.cpp | 16 +- src/Engine/Graphics/Vulkan/RayTracing.h | 5 + 12 files changed, 207 insertions(+), 18 deletions(-) diff --git a/src/Engine/Graphics/Buffer.h b/src/Engine/Graphics/Buffer.h index 7d4d340..b2d9631 100644 --- a/src/Engine/Graphics/Buffer.h +++ b/src/Engine/Graphics/Buffer.h @@ -76,7 +76,7 @@ class ShaderBuffer : public Buffer { public: ShaderBuffer(QueueFamilyMapping mapping, const ShaderBufferCreateInfo& createInfo); virtual ~ShaderBuffer(); - virtual void rotateBuffer(uint64 size, bool preserveContents = false) = 0; + virtual void rotateBuffer(uint64 size, bool preserveContents = false, uint32 fillValue = 0) = 0; virtual void updateContents(const ShaderBufferCreateInfo& sourceData) = 0; constexpr uint32 getNumElements() const { return numElements; } diff --git a/src/Engine/Graphics/RayTracing.cpp b/src/Engine/Graphics/RayTracing.cpp index ac5edf9..1d4120f 100644 --- a/src/Engine/Graphics/RayTracing.cpp +++ b/src/Engine/Graphics/RayTracing.cpp @@ -1,7 +1,14 @@ #include "RayTracing.h" +#include "RayTracing.h" using namespace Seele::Gfx; +RayTracingPipeline::RayTracingPipeline(Gfx::PPipelineLayout layout) {} + +RayTracingPipeline::~RayTracingPipeline() {} + +PPipelineLayout RayTracingPipeline::getPipelineLayout() const { return layout; } + BottomLevelAS::BottomLevelAS() {} BottomLevelAS::~BottomLevelAS() {} diff --git a/src/Engine/Graphics/RayTracing.h b/src/Engine/Graphics/RayTracing.h index f5b7978..740da1f 100644 --- a/src/Engine/Graphics/RayTracing.h +++ b/src/Engine/Graphics/RayTracing.h @@ -3,10 +3,16 @@ namespace Seele { namespace Gfx { +DECLARE_REF(PipelineLayout) class RayTracingPipeline { public: - private: + RayTracingPipeline(PPipelineLayout layout); + virtual ~RayTracingPipeline(); + PPipelineLayout getPipelineLayout() const; + + protected: + PPipelineLayout layout; }; DEFINE_REF(RayTracingPipeline) class BottomLevelAS { diff --git a/src/Engine/Graphics/RenderPass/LightCullingPass.cpp b/src/Engine/Graphics/RenderPass/LightCullingPass.cpp index 0581030..c819790 100644 --- a/src/Engine/Graphics/RenderPass/LightCullingPass.cpp +++ b/src/Engine/Graphics/RenderPass/LightCullingPass.cpp @@ -270,7 +270,8 @@ void LightCullingPass::setupFrustums() { .dynamic = false, .name = "FrustumDispatch", }); - + frustumDispatchParamsBuffer->pipelineBarrier(Gfx::SE_ACCESS_TRANSFER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_TRANSFER_BIT, + Gfx::SE_ACCESS_UNIFORM_READ_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT); frustumBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{ .sourceData = { @@ -282,6 +283,8 @@ void LightCullingPass::setupFrustums() { .dynamic = false, .name = "FrustumBuffer", }); + frustumBuffer->pipelineBarrier(Gfx::SE_ACCESS_TRANSFER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_TRANSFER_BIT, Gfx::SE_ACCESS_SHADER_WRITE_BIT, + Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT); Gfx::PDescriptorSet dispatchParamsSet = dispatchParamsLayout->allocateDescriptorSet(); dispatchParamsSet->updateBuffer(0, frustumDispatchParamsBuffer); diff --git a/src/Engine/Graphics/RenderPass/VisibilityPass.cpp b/src/Engine/Graphics/RenderPass/VisibilityPass.cpp index a777091..b678ae6 100644 --- a/src/Engine/Graphics/RenderPass/VisibilityPass.cpp +++ b/src/Engine/Graphics/RenderPass/VisibilityPass.cpp @@ -11,7 +11,7 @@ VisibilityPass::~VisibilityPass() {} void VisibilityPass::beginFrame(const Component::Camera& cam) { RenderPass::beginFrame(cam); - cullingBuffer->rotateBuffer(VertexData::getMeshletCount() * sizeof(VertexData::MeshletCullingInfo), true); + cullingBuffer->rotateBuffer(VertexData::getMeshletCount() * sizeof(VertexData::MeshletCullingInfo), true, 0xffffffff); } void VisibilityPass::render() { diff --git a/src/Engine/Graphics/Vulkan/Buffer.cpp b/src/Engine/Graphics/Vulkan/Buffer.cpp index 2292252..6f5e3c8 100644 --- a/src/Engine/Graphics/Vulkan/Buffer.cpp +++ b/src/Engine/Graphics/Vulkan/Buffer.cpp @@ -187,7 +187,7 @@ void Buffer::readContents(uint64 regionOffset, uint64 regionSize, void* buffer) getAlloc()->readContents(regionOffset, regionSize, buffer); } -void Buffer::rotateBuffer(uint64 size, bool preserveContents) { +void Buffer::rotateBuffer(uint64 size, bool preserveContents, uint32 fillValue) { assert(dynamic); if (buffers.size() > 0) { size = std::max(getSize(), size); @@ -216,6 +216,11 @@ void Buffer::rotateBuffer(uint64 size, bool preserveContents) { } if (preserveContents) { copyBuffer(currentBuffer, i); + if (buffers[i]->size > buffers[currentBuffer]->size) { + PCommand command = graphics->getQueueCommands(getAlloc()->owner)->getCommands(); + vkCmdFillBuffer(command->getHandle(), buffers[i]->buffer, buffers[currentBuffer]->size, + buffers[i]->size - buffers[currentBuffer]->size, fillValue); + } } currentBuffer = i; return; @@ -344,9 +349,9 @@ void ShaderBuffer::updateContents(const ShaderBufferCreateInfo& createInfo) { } } -void ShaderBuffer::rotateBuffer(uint64 size, bool preserveContents) { +void ShaderBuffer::rotateBuffer(uint64 size, bool preserveContents, uint32 fillValue) { assert(dynamic); - Vulkan::Buffer::rotateBuffer(size, preserveContents); + Vulkan::Buffer::rotateBuffer(size, preserveContents, fillValue); } void ShaderBuffer::clear() { diff --git a/src/Engine/Graphics/Vulkan/Buffer.h b/src/Engine/Graphics/Vulkan/Buffer.h index 18225dc..e8f6840 100644 --- a/src/Engine/Graphics/Vulkan/Buffer.h +++ b/src/Engine/Graphics/Vulkan/Buffer.h @@ -45,7 +45,7 @@ class Buffer { VkBufferUsageFlags usage; bool dynamic; std::string name; - void rotateBuffer(uint64 size, bool preserveContents = false); + void rotateBuffer(uint64 size, bool preserveContents = false, uint32 fillValue = 0); void createBuffer(uint64 size); void copyBuffer(uint64 src, uint64 dest); @@ -107,7 +107,7 @@ class ShaderBuffer : public Gfx::ShaderBuffer, public Buffer { ShaderBuffer(PGraphics graphics, const ShaderBufferCreateInfo& sourceData); virtual ~ShaderBuffer(); virtual void updateContents(const ShaderBufferCreateInfo& createInfo) override; - virtual void rotateBuffer(uint64 size, bool preserveContents = false) override; + virtual void rotateBuffer(uint64 size, bool preserveContents = false, uint32 fillValue = 0) override; virtual void clear() override; diff --git a/src/Engine/Graphics/Vulkan/Graphics.cpp b/src/Engine/Graphics/Vulkan/Graphics.cpp index 8a29dd6..e2d19e1 100644 --- a/src/Engine/Graphics/Vulkan/Graphics.cpp +++ b/src/Engine/Graphics/Vulkan/Graphics.cpp @@ -34,6 +34,7 @@ PFN_vkSetDebugUtilsObjectNameEXT setDebugUtilsObjectName; PFN_vkCreateAccelerationStructureKHR createAccelerationStructure; PFN_vkCmdBuildAccelerationStructuresKHR cmdBuildAccelerationStructures; PFN_vkGetAccelerationStructureBuildSizesKHR getAccelerationStructureBuildSize; +PFN_vkCreateRayTracingPipelinesKHR createRayTracingPipelines; void vkCmdDrawMeshTasksEXT(VkCommandBuffer command, uint32 groupX, uint32 groupY, uint32 groupZ) { cmdDrawMeshTasks(command, groupX, groupY, groupZ); @@ -64,6 +65,13 @@ void vkGetAccelerationStructureBuildSizesKHR(VkDevice device, VkAccelerationStru getAccelerationStructureBuildSize(device, buildType, pBuildInfo, pMaxPrimitiveCounts, pSizeInfo); } +VkResult vkCreateRayTracingPipelinesKHR(VkDevice device, VkDeferredOperationKHR deferredOperation, VkPipelineCache pipelineCache, + uint32_t createInfoCount, const VkRayTracingPipelineCreateInfoKHR* pCreateInfos, + const VkAllocationCallbacks* pAllocator, VkPipeline* pPipelines) +{ + return createRayTracingPipelines(device, deferredOperation, pipelineCache, createInfoCount, pCreateInfos, pAllocator, pPipelines); +} + Graphics::Graphics() : instance(VK_NULL_HANDLE), handle(VK_NULL_HANDLE), physicalDevice(VK_NULL_HANDLE), callback(VK_NULL_HANDLE) {} Graphics::~Graphics() { @@ -684,4 +692,5 @@ void Graphics::createDevice(GraphicsInitializer initializer) { (PFN_vkCmdBuildAccelerationStructuresKHR)vkGetDeviceProcAddr(handle, "vkCmdBuildAccelerationStructuresKHR"); getAccelerationStructureBuildSize = (PFN_vkGetAccelerationStructureBuildSizesKHR)vkGetDeviceProcAddr(handle, "vkGetAccelerationStructureBuildSizesKHR"); + createRayTracingPipelines = (PFN_vkCreateRayTracingPipelinesKHR)vkGetDeviceProcAddr(handle, "vkCreateRayTracingPipelinesKHR"); } diff --git a/src/Engine/Graphics/Vulkan/PipelineCache.cpp b/src/Engine/Graphics/Vulkan/PipelineCache.cpp index fe4d641..7780e11 100644 --- a/src/Engine/Graphics/Vulkan/PipelineCache.cpp +++ b/src/Engine/Graphics/Vulkan/PipelineCache.cpp @@ -6,7 +6,6 @@ #include "Shader.h" #include - using namespace Seele; using namespace Seele::Vulkan; @@ -466,4 +465,156 @@ PComputePipeline PipelineCache::createPipeline(Gfx::ComputePipelineCreateInfo co return result; } -PRayTracingPipeline PipelineCache::createPipeline(Gfx::RayTracingPipelineCreateInfo createInfo) { return nullptr; } +PRayTracingPipeline PipelineCache::createPipeline(Gfx::RayTracingPipelineCreateInfo createInfo) { + Array shaderStages; + Array shaderGroups; + { + auto rayGen = createInfo.rayGenShader.cast(); + shaderStages.add(VkPipelineShaderStageCreateInfo{ + .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, + .pNext = nullptr, + .flags = 0, + .stage = VK_SHADER_STAGE_RAYGEN_BIT_KHR, + .module = rayGen->getModuleHandle(), + .pName = rayGen->getEntryPointName(), + }); + shaderGroups.add(VkRayTracingShaderGroupCreateInfoKHR{ + .sType = VK_STRUCTURE_TYPE_RAY_TRACING_SHADER_GROUP_CREATE_INFO_KHR, + .pNext = nullptr, + .type = VK_RAY_TRACING_SHADER_GROUP_TYPE_GENERAL_KHR, + .generalShader = static_cast(shaderStages.size() - 1), + .closestHitShader = VK_SHADER_UNUSED_KHR, + .anyHitShader = VK_SHADER_UNUSED_KHR, + .intersectionShader = VK_SHADER_UNUSED_KHR, + }); + } + { + for (auto gfxHit : createInfo.closestHitShaders) { + auto hit = gfxHit.cast(); + shaderStages.add(VkPipelineShaderStageCreateInfo{ + .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, + .pNext = nullptr, + .flags = 0, + .stage = VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR, + .module = hit->getModuleHandle(), + .pName = hit->getEntryPointName(), + }); + shaderGroups.add(VkRayTracingShaderGroupCreateInfoKHR{ + .sType = VK_STRUCTURE_TYPE_RAY_TRACING_SHADER_GROUP_CREATE_INFO_KHR, + .pNext = nullptr, + .type = VK_RAY_TRACING_SHADER_GROUP_TYPE_TRIANGLES_HIT_GROUP_KHR, + .generalShader = VK_SHADER_UNUSED_KHR, + .closestHitShader = static_cast(shaderStages.size() - 1), + .anyHitShader = VK_SHADER_UNUSED_KHR, + .intersectionShader = VK_SHADER_UNUSED_KHR, + }); + } + } + { + for (auto gfxHit : createInfo.anyHitShaders) { + auto hit = gfxHit.cast(); + shaderStages.add(VkPipelineShaderStageCreateInfo{ + .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, + .pNext = nullptr, + .flags = 0, + .stage = VK_SHADER_STAGE_ANY_HIT_BIT_KHR, + .module = hit->getModuleHandle(), + .pName = hit->getEntryPointName(), + }); + shaderGroups.add(VkRayTracingShaderGroupCreateInfoKHR{ + .sType = VK_STRUCTURE_TYPE_RAY_TRACING_SHADER_GROUP_CREATE_INFO_KHR, + .pNext = nullptr, + .type = VK_RAY_TRACING_SHADER_GROUP_TYPE_TRIANGLES_HIT_GROUP_KHR, + .generalShader = VK_SHADER_UNUSED_KHR, + .closestHitShader = VK_SHADER_UNUSED_KHR, + .anyHitShader = static_cast(shaderStages.size() - 1), + .intersectionShader = VK_SHADER_UNUSED_KHR, + }); + } + } + { + for (auto gfxIntersect : createInfo.intersectionShaders) { + auto intersect = gfxIntersect.cast(); + shaderStages.add(VkPipelineShaderStageCreateInfo{ + .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, + .pNext = nullptr, + .flags = 0, + .stage = VK_SHADER_STAGE_INTERSECTION_BIT_KHR, + .module = intersect->getModuleHandle(), + .pName = intersect->getEntryPointName(), + }); + + shaderGroups.add(VkRayTracingShaderGroupCreateInfoKHR{ + .sType = VK_STRUCTURE_TYPE_RAY_TRACING_SHADER_GROUP_CREATE_INFO_KHR, + .pNext = nullptr, + .type = VK_RAY_TRACING_SHADER_GROUP_TYPE_TRIANGLES_HIT_GROUP_KHR, + .generalShader = VK_SHADER_UNUSED_KHR, + .closestHitShader = VK_SHADER_UNUSED_KHR, + .anyHitShader = VK_SHADER_UNUSED_KHR, + .intersectionShader = static_cast(shaderStages.size() - 1), + }); + } + } + { + for (auto gfxMiss : createInfo.missShaders) { + auto miss = gfxMiss.cast(); + shaderStages.add(VkPipelineShaderStageCreateInfo{ + .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, + .pNext = nullptr, + .flags = 0, + .stage = VK_SHADER_STAGE_MISS_BIT_KHR, + .module = miss->getModuleHandle(), + .pName = miss->getEntryPointName(), + }); + shaderGroups.add(VkRayTracingShaderGroupCreateInfoKHR{ + .sType = VK_STRUCTURE_TYPE_RAY_TRACING_SHADER_GROUP_CREATE_INFO_KHR, + .pNext = nullptr, + .type = VK_RAY_TRACING_SHADER_GROUP_TYPE_GENERAL_KHR, + .generalShader = static_cast(shaderStages.size() - 1), + .closestHitShader = VK_SHADER_UNUSED_KHR, + .anyHitShader = VK_SHADER_UNUSED_KHR, + .intersectionShader = VK_SHADER_UNUSED_KHR, + }); + } + } + { + for (auto gfxCallable : createInfo.callableShaders) { + auto miss = gfxCallable.cast(); + shaderStages.add(VkPipelineShaderStageCreateInfo{ + .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, + .pNext = nullptr, + .flags = 0, + .stage = VK_SHADER_STAGE_CALLABLE_BIT_KHR, + .module = miss->getModuleHandle(), + .pName = miss->getEntryPointName(), + }); + shaderGroups.add(VkRayTracingShaderGroupCreateInfoKHR{ + .sType = VK_STRUCTURE_TYPE_RAY_TRACING_SHADER_GROUP_CREATE_INFO_KHR, + .pNext = nullptr, + .type = VK_RAY_TRACING_SHADER_GROUP_TYPE_GENERAL_KHR, + .generalShader = static_cast(shaderStages.size() - 1), + .closestHitShader = VK_SHADER_UNUSED_KHR, + .anyHitShader = VK_SHADER_UNUSED_KHR, + .intersectionShader = VK_SHADER_UNUSED_KHR, + }); + } + } + uint32 hash = CRC::Calculate(shaderStages.data(), sizeof(VkPipelineShaderStageCreateInfo) * shaderStages.size(), CRC::CRC_32()); + hash = CRC::Calculate(shaderGroups.data(), sizeof(VkRayTracingShaderGroupCreateInfoKHR) * shaderGroups.size(), CRC::CRC_32(), hash); + VkRayTracingPipelineCreateInfoKHR pipelineInfo = { + .sType = VK_STRUCTURE_TYPE_RAY_TRACING_PIPELINE_CREATE_INFO_KHR, + .pNext = nullptr, + .stageCount = static_cast(shaderStages.size()), + .pStages = shaderStages.data(), + .groupCount = static_cast(shaderGroups.size()), + .pGroups = shaderGroups.data(), + .maxPipelineRayRecursionDepth = 24, + .layout = createInfo.pipelineLayout.cast()->getHandle(), + }; + VkPipeline pipelineHandle; + VK_CHECK(vkCreateRayTracingPipelinesKHR(graphics->getDevice(), VK_NULL_HANDLE, cache, 1, &pipelineInfo, nullptr, &pipelineHandle)); + ORayTracingPipeline pipeline = new RayTracingPipeline(graphics, pipelineHandle, createInfo.pipelineLayout); + PRayTracingPipeline handle = pipeline; + rayTracingPipelines[hash] = std::move(pipeline); + return handle; +} diff --git a/src/Engine/Graphics/Vulkan/PipelineCache.h b/src/Engine/Graphics/Vulkan/PipelineCache.h index 8f3816b..768046b 100644 --- a/src/Engine/Graphics/Vulkan/PipelineCache.h +++ b/src/Engine/Graphics/Vulkan/PipelineCache.h @@ -17,6 +17,7 @@ class PipelineCache { private: Map graphicsPipelines; Map computePipelines; + Map rayTracingPipelines; std::mutex cacheLock; VkPipelineCache cache; PGraphics graphics; diff --git a/src/Engine/Graphics/Vulkan/RayTracing.cpp b/src/Engine/Graphics/Vulkan/RayTracing.cpp index 8692b59..2e94150 100644 --- a/src/Engine/Graphics/Vulkan/RayTracing.cpp +++ b/src/Engine/Graphics/Vulkan/RayTracing.cpp @@ -93,8 +93,7 @@ BottomLevelAS::BottomLevelAS(PGraphics graphics, const Gfx::BottomLevelASCreateI VmaAllocationCreateInfo bufferAllocInfo = { .usage = VMA_MEMORY_USAGE_AUTO, }; - buffer = - new BufferAllocation(graphics, "BLAS", bufferInfo, bufferAllocInfo, Gfx::QueueType::GRAPHICS); + buffer = new BufferAllocation(graphics, "BLAS", bufferInfo, bufferAllocInfo, Gfx::QueueType::GRAPHICS); VkAccelerationStructureCreateInfoKHR blasInfo = { .sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_CREATE_INFO_KHR, @@ -140,13 +139,16 @@ BottomLevelAS::BottomLevelAS(PGraphics graphics, const Gfx::BottomLevelASCreateI graphics->getDestructionManager()->queueResourceForDestruction(std::move(transformBuffer)); graphics->getDestructionManager()->queueResourceForDestruction(std::move(scratchAlloc)); - //todo: compact + // todo: compact } BottomLevelAS::~BottomLevelAS() { graphics->getDestructionManager()->queueResourceForDestruction(std::move(buffer)); } -TopLevelAS::TopLevelAS(PGraphics graphics, const Gfx::TopLevelASCreateInfo& createInfo) { - -} +TopLevelAS::TopLevelAS(PGraphics graphics, const Gfx::TopLevelASCreateInfo& createInfo) {} -TopLevelAS::~TopLevelAS() {} \ No newline at end of file +TopLevelAS::~TopLevelAS() {} + +RayTracingPipeline::RayTracingPipeline(PGraphics graphics, VkPipeline handle, Gfx::PPipelineLayout layout) + : Gfx::RayTracingPipeline(layout), graphics(graphics), pipeline(handle) {} + +RayTracingPipeline::~RayTracingPipeline() {} diff --git a/src/Engine/Graphics/Vulkan/RayTracing.h b/src/Engine/Graphics/Vulkan/RayTracing.h index 55d6f27..616a726 100644 --- a/src/Engine/Graphics/Vulkan/RayTracing.h +++ b/src/Engine/Graphics/Vulkan/RayTracing.h @@ -33,7 +33,12 @@ DEFINE_REF(TopLevelAS) class RayTracingPipeline : public Gfx::RayTracingPipeline { public: + RayTracingPipeline(PGraphics graphics, VkPipeline handle, Gfx::PPipelineLayout layout); + virtual ~RayTracingPipeline(); + private: + PGraphics graphics; + VkPipeline pipeline; }; DEFINE_REF(RayTracingPipeline) } // namespace Vulkan