diff --git a/ZEngine/ZEngine/Core/Containers/ContainerCommon.h b/ZEngine/ZEngine/Core/Containers/ContainerCommon.h new file mode 100644 index 00000000..3e38de25 --- /dev/null +++ b/ZEngine/ZEngine/Core/Containers/ContainerCommon.h @@ -0,0 +1,19 @@ +#pragma once +#include +#include +#include + +namespace ZEngine::Core::Containers +{ + enum class EntryState : uint8_t + { + Empty = 0, + Occupied = 1, + Deleted = 2, + }; + + inline uint64_t hash_compute(const char* str) + { + return rapidhash(str, Helpers::secure_strlen(str)); + } +} // namespace ZEngine::Core::Containers diff --git a/ZEngine/ZEngine/Core/Containers/HashMap.h b/ZEngine/ZEngine/Core/Containers/HashMap.h index b7527a1b..0a4262cf 100644 --- a/ZEngine/ZEngine/Core/Containers/HashMap.h +++ b/ZEngine/ZEngine/Core/Containers/HashMap.h @@ -1,9 +1,8 @@ #pragma once #include +#include #include -#include #include -#include #include #include #include @@ -22,14 +21,6 @@ namespace ZEngine::Core::Containers { - // EntryState is also defined in UnorderedHashMap.h — keep both identical. - enum class EntryState : uint8_t - { - Empty = 0, - Occupied = 1, - Deleted = 2 - }; - template struct OrderedHashEntry { @@ -441,8 +432,4 @@ namespace ZEngine::Core::Containers size_type m_tail = npos; }; - inline uint64_t hash_compute(const char* str) - { - return rapidhash(str, Helpers::secure_strlen(str)); - } } // namespace ZEngine::Core::Containers diff --git a/ZEngine/ZEngine/Core/Containers/UnorderedHashMap.h b/ZEngine/ZEngine/Core/Containers/UnorderedHashMap.h index 8f119a56..591a3876 100644 --- a/ZEngine/ZEngine/Core/Containers/UnorderedHashMap.h +++ b/ZEngine/ZEngine/Core/Containers/UnorderedHashMap.h @@ -1,9 +1,8 @@ #pragma once #include +#include #include -#include #include -#include #include #include #include @@ -21,13 +20,6 @@ namespace ZEngine::Core::Containers { - enum class EntryState : uint8_t - { - Empty = 0, - Occupied = 1, - Deleted = 2, - }; - template struct HashEntry { @@ -373,9 +365,4 @@ namespace ZEngine::Core::Containers size_type m_size = 0; }; - inline uint64_t hash_compute(const char* str) - { - return rapidhash(str, Helpers::secure_strlen(str)); - } - } // namespace ZEngine::Core::Containers diff --git a/ZEngine/ZEngine/Hardwares/VulkanDevice.cpp b/ZEngine/ZEngine/Hardwares/VulkanDevice.cpp index 49b89a01..74f4977a 100644 --- a/ZEngine/ZEngine/Hardwares/VulkanDevice.cpp +++ b/ZEngine/ZEngine/Hardwares/VulkanDevice.cpp @@ -1255,7 +1255,7 @@ namespace ZEngine::Hardwares m_command_buffer_state = CommandBufferState::Recording; } - void CommandBuffer::BeginSecondary(Rendering::Renderers::RenderPasses::RenderPass* const render_pass, VkFramebuffer framebuffer) + void CommandBuffer::BeginSecondary(Rendering::Renderers::RenderPasses::GraphicPass* const render_pass, VkFramebuffer framebuffer) { ZENGINE_VALIDATE_ASSERT(m_command_buffer_state == CommandBufferState::Idle, "command buffer must be in Idle state") ZENGINE_VALIDATE_ASSERT(BufferType == CommandBufferType::Secondary, "command buffer must be Secondary Buffer Type") @@ -1273,7 +1273,7 @@ namespace ZEngine::Hardwares ZENGINE_VALIDATE_ASSERT(vkBeginCommandBuffer(m_command_buffer, &command_buffer_begin_info) == VK_SUCCESS, "Failed to begin the Command Buffer") m_command_buffer_state = CommandBufferState::Recording; - m_active_render_pass = render_pass; + m_in_render_pass = true; } void CommandBuffer::End() @@ -1347,7 +1347,7 @@ namespace ZEngine::Hardwares m_clear_value[1].depthStencil.stencil = stencil; } - void CommandBuffer::BeginRenderPass(Rendering::Renderers::RenderPasses::RenderPass* const render_pass, VkFramebuffer framebuffer, bool is_content_secondary_command_buffer) + void CommandBuffer::BeginRenderPass(Rendering::Renderers::RenderPasses::GraphicPass* const render_pass, VkFramebuffer framebuffer, bool is_content_secondary_command_buffer) { ZENGINE_VALIDATE_ASSERT(m_command_buffer != nullptr, "Command buffer can't be null") ZENGINE_VALIDATE_ASSERT(BufferType == CommandBufferType::Primary, "command buffer must be Primary Buffer Type") @@ -1402,18 +1402,19 @@ namespace ZEngine::Hardwares vkCmdBeginRenderPass(m_command_buffer, &render_pass_begin_info, is_content_secondary_command_buffer ? VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS : VK_SUBPASS_CONTENTS_INLINE); - m_active_render_pass = render_pass; + m_in_render_pass = true; ZReleaseScratch(scratch); } void CommandBuffer::EndRenderPass() { - if (m_active_render_pass) + if (m_in_render_pass) { ZENGINE_VALIDATE_ASSERT(m_command_buffer != nullptr, "Command buffer can't be null") vkCmdEndRenderPass(m_command_buffer); - m_active_render_pass = nullptr; + m_active_pipeline = nullptr; + m_in_render_pass = false; } } @@ -1421,11 +1422,10 @@ namespace ZEngine::Hardwares { ZENGINE_VALIDATE_ASSERT(m_command_buffer != nullptr, "Command buffer can't be null") - if (auto render_pass = m_active_render_pass) + if (m_active_pipeline) { - auto pipeline = render_pass->Pipeline; - auto pipeline_layout = pipeline->Layout; - auto shader = pipeline->Shader; + auto pipeline_layout = m_active_pipeline->Layout; + auto shader = m_active_pipeline->Shader; const auto& set_layout = shader->SetLayouts; const auto& descriptor_set_map = shader->DescriptorSetMap; @@ -1459,7 +1459,7 @@ namespace ZEngine::Hardwares const uint32_t* offsets = (actual_dynamic_count > 0) ? dynamic_offsets : nullptr; uint32_t count = (actual_dynamic_count > 0) ? actual_dynamic_count : 0; - vkCmdBindDescriptorSets(m_command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout, 0, frame_sets.size(), frame_sets.data(), count, offsets); + vkCmdBindDescriptorSets(m_command_buffer, m_active_pipeline->GetBindPoint(), pipeline_layout, 0, frame_sets.size(), frame_sets.data(), count, offsets); } ZReleaseScratch(scratch); } @@ -1469,22 +1469,21 @@ namespace ZEngine::Hardwares { ZENGINE_VALIDATE_ASSERT(m_command_buffer != nullptr, "Command buffer can't be null") ZENGINE_VALIDATE_ASSERT(descriptor != nullptr, "DescriptorSet can't be null") - if (auto render_pass = m_active_render_pass) + if (m_active_pipeline) { - auto pipeline_layout = render_pass->Pipeline->Layout; - VkDescriptorSet desc_set[1] = {descriptor}; - vkCmdBindDescriptorSets(m_command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout, 0, 1, desc_set, 0, nullptr); + VkDescriptorSet desc_set[1] = {descriptor}; + vkCmdBindDescriptorSets(m_command_buffer, m_active_pipeline->GetBindPoint(), m_active_pipeline->Layout, 0, 1, desc_set, 0, nullptr); } } - void CommandBuffer::BindPipeline(Rendering::Specifications::PipelineBindPoint bind_point, Rendering::Renderers::Pipelines::GraphicPipeline* const pipeline) + void CommandBuffer::BindPipeline(Rendering::Renderers::Pipelines::IPipeline* const pipeline) { ZENGINE_VALIDATE_ASSERT(m_command_buffer != nullptr, "Command buffer can't be null") ZENGINE_VALIDATE_ASSERT(pipeline != nullptr, "Pipeline can't be null") ZENGINE_VALIDATE_ASSERT(pipeline->Handle != VK_NULL_HANDLE, "Pipeline Handle can't be null") - // todo : adapt value based on bind_point - vkCmdBindPipeline(m_command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline->Handle); + vkCmdBindPipeline(m_command_buffer, pipeline->GetBindPoint(), pipeline->Handle); + m_active_pipeline = pipeline; } void CommandBuffer::DrawIndirect(VkBuffer buffer, uint32_t offset, uint32_t draw_count) @@ -1592,10 +1591,9 @@ namespace ZEngine::Hardwares { ZENGINE_VALIDATE_ASSERT(m_command_buffer != nullptr, "Command buffer can't be null") - if (auto render_pass = m_active_render_pass) + if (m_active_pipeline) { - auto pipeline_layout = render_pass->Pipeline->Layout; - vkCmdPushConstants(m_command_buffer, pipeline_layout, stage_flags, offset, size, data); + vkCmdPushConstants(m_command_buffer, m_active_pipeline->Layout, stage_flags, offset, size, data); } } @@ -1838,7 +1836,13 @@ namespace ZEngine::Hardwares Rendering::Renderers::RenderPasses::RenderPass* VulkanDevice::CreateRenderPass(Rendering::Specifications::RenderPassSpecification spec) { - auto pass = ZPushStructCtorArgs(Arena, Rendering::Renderers::RenderPasses::RenderPass); + if (spec.Type == Rendering::Specifications::RenderPassType::COMPUTE) + { + auto pass = ZPushStructCtorArgs(Arena, Rendering::Renderers::RenderPasses::ComputePass); + pass->Initialize(this, std::move(spec)); + return pass; + } + auto pass = ZPushStructCtorArgs(Arena, Rendering::Renderers::RenderPasses::GraphicPass); pass->Initialize(this, std::move(spec)); return pass; } diff --git a/ZEngine/ZEngine/Hardwares/VulkanDevice.h b/ZEngine/ZEngine/Hardwares/VulkanDevice.h index cb639f9f..5e792911 100644 --- a/ZEngine/ZEngine/Hardwares/VulkanDevice.h +++ b/ZEngine/ZEngine/Hardwares/VulkanDevice.h @@ -1,5 +1,15 @@ #pragma once #include + +namespace ZEngine::Rendering::Renderers::Pipelines +{ + struct IPipeline; +} +namespace ZEngine::Rendering::Renderers::RenderPasses +{ + struct GraphicPass; +} + // clang-format off #include #include @@ -138,7 +148,7 @@ namespace ZEngine::Hardwares void Free(); VkCommandBuffer GetHandle() const; void Begin(); - void BeginSecondary(Rendering::Renderers::RenderPasses::RenderPass* const render_pass, VkFramebuffer framebuffer); + void BeginSecondary(Rendering::Renderers::RenderPasses::GraphicPass* const render_pass, VkFramebuffer framebuffer); void End(); bool Completed(); bool IsExecutable(); @@ -152,11 +162,11 @@ namespace ZEngine::Hardwares Rendering::Primitives::Fence* GetSignalFence(); void ClearColor(float r, float g, float b, float a); void ClearDepth(float depth_color, uint32_t stencil); - void BeginRenderPass(Rendering::Renderers::RenderPasses::RenderPass* const, VkFramebuffer framebuffer, bool is_content_secondary_command_buffer); + void BeginRenderPass(Rendering::Renderers::RenderPasses::GraphicPass* const, VkFramebuffer framebuffer, bool is_content_secondary_command_buffer); void EndRenderPass(); void BindDescriptorSets(uint32_t frame_index = 0, const uint32_t* dynamic_offsets = nullptr, uint32_t dynamic_offset_count = 0); void BindDescriptorSet(const VkDescriptorSet& descriptor); - void BindPipeline(Rendering::Specifications::PipelineBindPoint bind_point, Rendering::Renderers::Pipelines::GraphicPipeline* const pipeline); + void BindPipeline(Rendering::Renderers::Pipelines::IPipeline* const pipeline); void DrawIndirect(VkBuffer buffer, uint32_t offset, uint32_t draw_count); void DrawIndexedIndirect(VkBuffer buffer, uint32_t offset, uint32_t count); void DrawIndexed(uint32_t indexCount, uint32_t instanceCount, uint32_t firstIndex, int32_t vertexOffset, uint32_t firstInstance); @@ -177,7 +187,8 @@ namespace ZEngine::Hardwares VkClearValue m_clear_value[2] = {0}; ZRawPtr(Rendering::Primitives::Fence) m_signal_fence; ZRawPtr(Rendering::Primitives::Semaphore) m_signal_semaphore; - ZRawPtr(Rendering::Renderers::RenderPasses::RenderPass) m_active_render_pass; + Rendering::Renderers::Pipelines::IPipeline* m_active_pipeline = nullptr; + bool m_in_render_pass = false; }; ZDEFINE_PTR(CommandBuffer); diff --git a/ZEngine/ZEngine/Rendering/Renderers/Base/IComputeCallbackPass.cpp b/ZEngine/ZEngine/Rendering/Renderers/Base/IComputeCallbackPass.cpp index 0904be17..7a738eca 100644 --- a/ZEngine/ZEngine/Rendering/Renderers/Base/IComputeCallbackPass.cpp +++ b/ZEngine/ZEngine/Rendering/Renderers/Base/IComputeCallbackPass.cpp @@ -7,23 +7,24 @@ namespace ZEngine::Rendering::Renderers SetupCompute(device, res_builder); } - void IComputeCallbackPass::Compile(Hardwares::VulkanDevicePtr const /*device*/, Rendering::Scenes::SceneDataPtr const /*scene*/, RenderPasses::RenderPassBuilder* /*pass_builder*/, RenderGraphResourceInspectorPtr /*res_inspector*/, RenderPasses::RenderPass** const /*output_pass*/) + void IComputeCallbackPass::Compile(Hardwares::VulkanDevicePtr const device, Rendering::Scenes::SceneDataPtr const /*scene*/, RenderPasses::RenderPassBuilder* pass_builder, RenderGraphResourceInspectorPtr /*res_inspector*/, RenderPasses::RenderPass** const output_pass) { - // TODO(compute-pipeline.md §5): construct ComputePassBuilder, call UseShader(GetShaderName()), - // optionally SetPushConstantRange(GetPushConstantSize()), then create and Bake() a - // COMPUTE RenderPass and write it to *output_pass. + if (!output_pass || *output_pass) + return; + + auto spec = pass_builder->UseComputeShader(GetShaderName(), GetPushConstantSize()).Detach(); + *output_pass = device->CreateRenderPass(std::move(spec)); + static_cast(*output_pass)->Bake(); } - void IComputeCallbackPass::Execute(Hardwares::VulkanDevicePtr const device, RenderGraphResourceInspectorPtr res_inspector, Rendering::Scenes::SceneDataPtr const scene, RenderPasses::RenderPass* const /*pass*/, Buffers::FramebufferVNext* const /*framebuffer — always null for compute passes*/, Hardwares::CommandBufferPtr const command_buffer) + void IComputeCallbackPass::Execute(Hardwares::VulkanDevicePtr const device, RenderGraphResourceInspectorPtr res_inspector, Rendering::Scenes::SceneDataPtr const scene, RenderPasses::RenderPass* const pass, Buffers::FramebufferVNext* const /*framebuffer*/, Hardwares::CommandBufferPtr const command_buffer) { - // TODO(compute-pipeline.md §4): bind compute pipeline via - // vkCmdBindPipeline(command_buffer->GetHandle(), VK_PIPELINE_BIND_POINT_COMPUTE, - // pass->ComputePipeline->Handle); - // then delegate: - // ExecuteCompute(device, res_inspector, scene, - // pass->ComputePipeline->Handle, - // pass->ComputePipeline->Layout, command_buffer); - ExecuteCompute(device, res_inspector, scene, VK_NULL_HANDLE, VK_NULL_HANDLE, command_buffer); + auto* cp = static_cast(pass); + if (!cp->Pipeline || cp->Pipeline->Handle == VK_NULL_HANDLE) + return; + + command_buffer->BindPipeline(cp->Pipeline); + ExecuteCompute(device, res_inspector, scene, cp->Pipeline->Handle, cp->Pipeline->Layout, command_buffer); } } // namespace ZEngine::Rendering::Renderers diff --git a/ZEngine/ZEngine/Rendering/Renderers/Base/IComputeCallbackPass.h b/ZEngine/ZEngine/Rendering/Renderers/Base/IComputeCallbackPass.h index a2a837d8..b3d68da9 100644 --- a/ZEngine/ZEngine/Rendering/Renderers/Base/IComputeCallbackPass.h +++ b/ZEngine/ZEngine/Rendering/Renderers/Base/IComputeCallbackPass.h @@ -6,51 +6,17 @@ namespace ZEngine::Rendering::Renderers { - /// @brief Base class for compute dispatch passes in the render graph. - /// - /// @details Handles the boilerplate shared by every compute pass: - /// - Setup() delegates to SetupCompute() so subclasses only see the resource builder. - /// - Compile() builds a COMPUTE RenderPass automatically from GetShaderName() and - /// GetPushConstantSize() — subclasses never touch RenderPassBuilder. - /// - Execute() binds the compute pipeline then delegates to ExecuteCompute(). - /// - /// Concrete compute passes only implement SetupCompute(), ExecuteCompute(), and - /// GetShaderName(). GetPushConstantSize() is optional (defaults to 0). - /// - /// The render graph interacts with compute passes through the same IRenderGraphCallbackPass - /// interface as graphics passes. The COMPUTE type in the RenderPassSpecification produced by - /// Compile() tells the graph to skip VkRenderPass / framebuffer creation for this pass. struct IComputeCallbackPass : public IRenderGraphCallbackPass { - /// @brief Delegates to SetupCompute() — subclasses declare resource reads/writes there. - void Setup(Hardwares::VulkanDevicePtr const device, cstring name, RenderGraphResourceBuilderPtr const res_builder, RenderGraphResourceInspectorPtr res_inspector) final; + void Setup(Hardwares::VulkanDevicePtr const device, cstring name, RenderGraphResourceBuilderPtr const res_builder, RenderGraphResourceInspectorPtr res_inspector) final; + void Compile(Hardwares::VulkanDevicePtr const device, Rendering::Scenes::SceneDataPtr const scene, RenderPasses::RenderPassBuilder* pass_builder, RenderGraphResourceInspectorPtr res_inspector, RenderPasses::RenderPass** const output_pass) final; + void Execute(Hardwares::VulkanDevicePtr const device, RenderGraphResourceInspectorPtr res_inspector, Rendering::Scenes::SceneDataPtr const scene, RenderPasses::RenderPass* const pass, Buffers::FramebufferVNext* const framebuffer, Hardwares::CommandBufferPtr const command_buffer) final; - /// @brief Builds a COMPUTE RenderPass from GetShaderName() and GetPushConstantSize(). - /// Subclasses do not override this. - /// NOTE: Full implementation requires ComputePassBuilder and ComputePipeline - /// (see compute-pipeline.md §2 and §5). Stubbed until those land. - void Compile(Hardwares::VulkanDevicePtr const device, Rendering::Scenes::SceneDataPtr const scene, RenderPasses::RenderPassBuilder* pass_builder, RenderGraphResourceInspectorPtr res_inspector, RenderPasses::RenderPass** const output_pass) final; + virtual void SetupCompute(Hardwares::VulkanDevicePtr const device, RenderGraphResourceBuilderPtr const res_builder) = 0; + virtual void ExecuteCompute(Hardwares::VulkanDevicePtr const device, RenderGraphResourceInspectorPtr res_inspector, Rendering::Scenes::SceneDataPtr scene, VkPipeline pipeline, VkPipelineLayout layout, Hardwares::CommandBufferPtr const command_buffer) = 0; + virtual cstring GetShaderName() const = 0; - /// @brief Binds the compute pipeline then calls ExecuteCompute(). - /// NOTE: Pipeline bind requires ComputePipeline on RenderPass (compute-pipeline.md §4). - /// Stubbed until that lands. - void Execute(Hardwares::VulkanDevicePtr const device, RenderGraphResourceInspectorPtr res_inspector, Rendering::Scenes::SceneDataPtr const scene, RenderPasses::RenderPass* const pass, Buffers::FramebufferVNext* const framebuffer, Hardwares::CommandBufferPtr const command_buffer) final; - - /// @brief Declare resource reads and writes for this pass. - /// Called from Setup(); receives only the resource builder. - virtual void SetupCompute(Hardwares::VulkanDevicePtr const device, RenderGraphResourceBuilderPtr const res_builder) = 0; - - /// @brief Record the compute dispatch commands for this pass. - /// Called from Execute() after the compute pipeline is bound. - /// pipeline / layout are extracted from pass->ComputePipeline (see compute-pipeline.md §4). - virtual void ExecuteCompute(Hardwares::VulkanDevicePtr const device, RenderGraphResourceInspectorPtr res_inspector, Rendering::Scenes::SceneDataPtr scene, VkPipeline pipeline, VkPipelineLayout layout, Hardwares::CommandBufferPtr const command_buffer) = 0; - - /// @brief Name of the compute shader (e.g. "ssao_compute", "bloom_threshold_compute"). - /// Used by Compile() to look up the shader in the device cache. - virtual const char* GetShaderName() const = 0; - - /// @brief Push constant size in bytes. Override to non-zero if the shader uses push constants. - virtual uint32_t GetPushConstantSize() const + virtual uint32_t GetPushConstantSize() const { return 0; } diff --git a/ZEngine/ZEngine/Rendering/Renderers/Base/RenderPass.cpp b/ZEngine/ZEngine/Rendering/Renderers/Base/RenderPass.cpp index 8414463f..0f682eb5 100644 --- a/ZEngine/ZEngine/Rendering/Renderers/Base/RenderPass.cpp +++ b/ZEngine/ZEngine/Rendering/Renderers/Base/RenderPass.cpp @@ -9,26 +9,26 @@ using namespace ZEngine::Helpers; namespace ZEngine::Rendering::Renderers::RenderPasses { - RenderPass::~RenderPass() + /* + * GraphicPass + */ + + GraphicPass::~GraphicPass() { Dispose(); } - void RenderPass::Initialize(Hardwares::VulkanDevice* device, Specifications::RenderPassSpecification specification) + void GraphicPass::Initialize(Hardwares::VulkanDevice* device, Specifications::RenderPassSpecification specification) { m_device = device; Specification = std::move(specification); - if ((specification.Type != Specifications::RenderPassType::GRAPHIC) && (specification.Type != Specifications::RenderPassType::COMPUTE)) - { - return; - } - - RenderTargets.init(device->Arena, 4); + RenderTargets.init(m_device->Arena, 4); + BoundBindings.init(m_device->Arena, 16); if (Specification.SwapchainAsRenderTarget) { - Specification.PipelineSpecification.Attachment = m_device->SwapchainPtr->SwapchainAttachment; // Todo : Can potential Dispose() issue + Specification.PipelineSpecification.Attachment = m_device->SwapchainPtr->SwapchainAttachment; Pipeline = ZPushStructCtorArgs(m_device->Arena, Pipelines::GraphicPipeline); Pipeline->Initialize(m_device, std::move(Specification.PipelineSpecification)); } @@ -46,7 +46,6 @@ namespace ZEngine::Rendering::Renderers::RenderPasses for (const auto& handle : Specification.Inputs) { const auto& texture = device->GlobalTextures.Access(handle); - bool is_depth_texture = texture->IsDepthTexture; ImageLayout initial_layout = is_depth_texture ? ImageLayout::DEPTH_STENCIL_ATTACHMENT_OPTIMAL : ImageLayout::COLOR_ATTACHMENT_OPTIMAL; ImageLayout final_layout = is_depth_texture ? ImageLayout::DEPTH_STENCIL_ATTACHMENT_OPTIMAL : ImageLayout::COLOR_ATTACHMENT_OPTIMAL; @@ -59,7 +58,6 @@ namespace ZEngine::Rendering::Renderers::RenderPasses attachment_specification.ColorsMap[color_map_index].Initial = initial_layout; attachment_specification.ColorsMap[color_map_index].Final = final_layout; attachment_specification.ColorsMap[color_map_index].ReferenceLayout = reference_layout; - color_map_index++; } @@ -79,13 +77,11 @@ namespace ZEngine::Rendering::Renderers::RenderPasses attachment_specification.ColorsMap[color_map_index].Initial = initial_layout; attachment_specification.ColorsMap[color_map_index].Final = final_layout; attachment_specification.ColorsMap[color_map_index].ReferenceLayout = reference_layout; - color_map_index++; } Attachment = ZPushStructCtorArgs(m_device->Arena, RenderPasses::Attachment, m_device, std::move(attachment_specification)); - - Specification.PipelineSpecification.Attachment = Attachment; // Todo : Can potential Dispose() issue + Specification.PipelineSpecification.Attachment = Attachment; Pipeline = ZPushStructCtorArgs(m_device->Arena, Pipelines::GraphicPipeline); Pipeline->Initialize(m_device, std::move(Specification.PipelineSpecification)); @@ -94,10 +90,9 @@ namespace ZEngine::Rendering::Renderers::RenderPasses } } - void RenderPass::Dispose() + void GraphicPass::Dispose() { - // NOTE: dead code today. If wired up later, route through VulkanDevice::DestroyTexture - // instead — Remove() reclaims the slot with no timeline gate. + // NOTE: dead code today. If wired up later, route through VulkanDevice::DestroyTexture. for (auto& handle : Specification.ExternalOutputs) { m_device->GlobalTextures.Remove(handle); @@ -108,35 +103,30 @@ namespace ZEngine::Rendering::Renderers::RenderPasses Pipeline->Dispose(); } - if (!(Specification.SwapchainAsRenderTarget) && Attachment) + if (!Specification.SwapchainAsRenderTarget && Attachment) { Attachment->Dispose(); } } - void RenderPass::Bake() + void GraphicPass::Bake() { - if ((Specification.Type != Specifications::RenderPassType::GRAPHIC) && (Specification.Type != Specifications::RenderPassType::COMPUTE)) - { - return; - } Pipeline->Bake(); } - bool RenderPass::Verify() + bool GraphicPass::Verify() { bool verify = true; const auto& layout_binding_specification = Pipeline->Shader->LayoutBindingSpecifications; - if (Inputs.size() != layout_binding_specification.size()) + if (BoundBindings.size() != layout_binding_specification.size()) { std::vector missing_names; for (const auto& specification : layout_binding_specification) { - std::string name(specification.Name); - if (!Inputs.count(name)) + if (!BoundBindings.contains(specification.Name)) { - missing_names.emplace_back(name); + missing_names.emplace_back(specification.Name); } } auto start = missing_names.begin(); @@ -151,7 +141,7 @@ namespace ZEngine::Rendering::Renderers::RenderPasses return verify; } - void RenderPass::SetDynamicUniform(std::string_view key_name, VkDeviceSize range) + void GraphicPass::SetDynamicUniform(std::string_view key_name, VkDeviceSize range) { auto validity_output = ValidateInput(key_name); if (!validity_output.first) @@ -190,11 +180,10 @@ namespace ZEngine::Rendering::Renderers::RenderPasses } vkUpdateDescriptorSets(m_device->LogicalDevice, write_reqs.size(), write_reqs.data(), 0, nullptr); - - Inputs.insert(key_name.data()); + BoundBindings.insert(key_name.data()); } - void RenderPass::SetStorageBuffer(std::string_view key_name, const Core::Memory::BufferView* buffer) + void GraphicPass::SetStorageBuffer(std::string_view key_name, const Core::Memory::BufferView* buffer) { if (!buffer || !buffer->Handle) { @@ -233,10 +222,10 @@ namespace ZEngine::Rendering::Renderers::RenderPasses }; } vkUpdateDescriptorSets(m_device->LogicalDevice, (uint32_t) write_reqs.size(), write_reqs.data(), 0, nullptr); - Inputs.insert(key_name.data()); + BoundBindings.insert(key_name.data()); } - void RenderPass::SetTexture(std::string_view key_name, const Textures::TextureHandle& handle) + void GraphicPass::SetTexture(std::string_view key_name, const Textures::TextureHandle& handle) { auto validity_output = ValidateInput(key_name); if (!validity_output.first) @@ -253,10 +242,7 @@ namespace ZEngine::Rendering::Renderers::RenderPasses return; } - // Use the descriptor type declared in the shader (SAMPLED_IMAGE or COMBINED_IMAGE_SAMPLER) - // rather than hardcoding — avoids type mismatches with the pipeline layout. const VkDescriptorType vk_type = Specifications::DescriptorTypeMap[VALUE_FROM_SPEC_MAP(spec.DescriptorTypeValue)]; - auto frame_count = m_device->SwapchainPtr->BufferredFrameCount; auto tex_buf = m_device->GlobalTextures.Access(handle); auto img_buf = m_device->ImageBufferManager.Access(tex_buf->BufferHandle); @@ -277,10 +263,10 @@ namespace ZEngine::Rendering::Renderers::RenderPasses }; } vkUpdateDescriptorSets(m_device->LogicalDevice, (uint32_t) write_reqs.size(), write_reqs.data(), 0, nullptr); - Inputs.insert(key_name.data()); + BoundBindings.insert(key_name.data()); } - void RenderPass::SetSampler(cstring key_name, const VkDescriptorImageInfo& sampler_info) + void GraphicPass::SetSampler(cstring key_name, const VkDescriptorImageInfo& sampler_info) { auto validity_output = ValidateInput(key_name); if (!validity_output.first) @@ -313,19 +299,16 @@ namespace ZEngine::Rendering::Renderers::RenderPasses }; } vkUpdateDescriptorSets(m_device->LogicalDevice, (uint32_t) write_reqs.size(), write_reqs.data(), 0, nullptr); - Inputs.insert(key_name); + BoundBindings.insert(key_name); } - void RenderPass::UseTextureArray(std::string_view key_name) + void GraphicPass::UseTextureArray(std::string_view key_name) { auto validity_output = ValidateInput(key_name); if (!validity_output.first) return; const auto& binding_spec = validity_output.second; - - // Only SAMPLED_IMAGE arrays belong in BindlessTextureSlotRequests. - // Samplers are compile-time resources — use SetSampler() for them. ZENGINE_VALIDATE_ASSERT(binding_spec.DescriptorTypeValue == Specifications::DescriptorType::SAMPLED_IMAGE, "UseTextureArray: binding is not a SAMPLED_IMAGE array — use SetSampler() for samplers") auto shader = Pipeline->Shader; @@ -345,10 +328,10 @@ namespace ZEngine::Rendering::Renderers::RenderPasses m_device->BindlessTextureSlotRequests.insert(key); } - Inputs.insert(key_name.data()); + BoundBindings.insert(key_name.data()); } - void RenderPass::UpdateInputBinding() + void GraphicPass::UpdateInputBinding() { for (const auto& [binding_name, texture] : Specification.InputTextures) { @@ -356,7 +339,7 @@ namespace ZEngine::Rendering::Renderers::RenderPasses } } - void RenderPass::UpdateRenderTargets() + void GraphicPass::UpdateRenderTargets() { RenderTargets.clear(); @@ -367,22 +350,14 @@ namespace ZEngine::Rendering::Renderers::RenderPasses auto texture = m_device->GlobalTextures.Access(input); if (width == 0) - { width = texture->Width; - } else - { ZENGINE_VALIDATE_ASSERT(width == texture->Width, "Render Target Width is invalid for Framebuffer creation") - } if (height == 0) - { height = texture->Height; - } else - { ZENGINE_VALIDATE_ASSERT(height == texture->Height, "Render Target Height is invalid for Framebuffer creation") - } RenderTargets.push(input.Index); } @@ -392,22 +367,14 @@ namespace ZEngine::Rendering::Renderers::RenderPasses auto texture = m_device->GlobalTextures.Access(output); if (width == 0) - { width = texture->Width; - } else - { ZENGINE_VALIDATE_ASSERT(width == texture->Width, "Render Target Width is invalid for Framebuffer creation") - } if (height == 0) - { height = texture->Height; - } else - { ZENGINE_VALIDATE_ASSERT(height == texture->Height, "Render Target Height is invalid for Framebuffer creation") - } RenderTargets.push(output.Index); } @@ -416,22 +383,22 @@ namespace ZEngine::Rendering::Renderers::RenderPasses RenderAreaHeight = height; } - ZRawPtr(Renderers::RenderPasses::Attachment) RenderPass::GetAttachment() const + struct Attachment* GraphicPass::GetAttachment() const { return Specification.SwapchainAsRenderTarget ? m_device->SwapchainPtr->SwapchainAttachment : Attachment; } - uint32_t RenderPass::GetRenderAreaWidth() const + uint32_t GraphicPass::GetRenderAreaWidth() const { return Specification.SwapchainAsRenderTarget ? m_device->SwapchainPtr->SwapchainImageWidth : RenderAreaWidth; } - uint32_t RenderPass::GetRenderAreaHeight() const + uint32_t GraphicPass::GetRenderAreaHeight() const { return Specification.SwapchainAsRenderTarget ? m_device->SwapchainPtr->SwapchainImageHeight : RenderAreaHeight; } - std::pair RenderPass::ValidateInput(std::string_view key) + std::pair GraphicPass::ValidateInput(std::string_view key) { bool valid{true}; const auto& shader = Pipeline->Shader; @@ -446,6 +413,36 @@ namespace ZEngine::Rendering::Renderers::RenderPasses return {valid, binding_spec}; } + /* + * ComputePass + */ + + ComputePass::~ComputePass() + { + Dispose(); + } + + void ComputePass::Initialize(Hardwares::VulkanDevice* device, Specifications::RenderPassSpecification specification) + { + m_device = device; + Specification = std::move(specification); + + Pipeline = ZPushStructCtorArgs(m_device->Arena, Pipelines::ComputePipeline); + Pipeline->Initialize(m_device, Specification.ComputeShaderName, Specification.ComputePushConstantSize); + } + + void ComputePass::Dispose() + { + if (Pipeline) + Pipeline->Dispose(); + } + + void ComputePass::Bake() + { + if (Pipeline) + Pipeline->Bake(); + } + /* * RenderPassBuilder */ @@ -566,13 +563,18 @@ namespace ZEngine::Rendering::Renderers::RenderPasses return *this; } + RenderPassBuilder& RenderPassBuilder::UseComputeShader(cstring name, uint32_t push_constant_size) + { + m_spec.Type = RenderPassType::COMPUTE; + m_spec.ComputeShaderName = name; + m_spec.ComputePushConstantSize = push_constant_size; + return *this; + } + RenderPassBuilder& RenderPassBuilder::UseRenderTarget(const Textures::TextureHandle& target) { if (m_spec.ExternalOutputs.capacity() <= 0) - { m_spec.ExternalOutputs.init(Arena, 4); - } - m_spec.ExternalOutputs.push(target); return *this; } @@ -580,9 +582,7 @@ namespace ZEngine::Rendering::Renderers::RenderPasses RenderPassBuilder& RenderPassBuilder::AddRenderTarget(const Specifications::TextureSpecification& target_spec) { if (m_spec.Outputs.capacity() <= 0) - { m_spec.Outputs.init(Arena, 4); - } m_spec.Outputs.push(target_spec); return *this; } @@ -590,9 +590,7 @@ namespace ZEngine::Rendering::Renderers::RenderPasses RenderPassBuilder& RenderPassBuilder::AddInputAttachment(const Textures::TextureHandle& input) { if (m_spec.Inputs.capacity() <= 0) - { m_spec.Inputs.init(Arena, 4); - } m_spec.Inputs.push(input); return *this; } @@ -600,9 +598,7 @@ namespace ZEngine::Rendering::Renderers::RenderPasses RenderPassBuilder& RenderPassBuilder::AddInputTexture(std::string_view key, const Textures::TextureHandle& input) { if (m_spec.InputTextures.capacity() <= 0) - { m_spec.InputTextures.init(Arena, 4); - } m_spec.InputTextures[key.data()] = input; return *this; } diff --git a/ZEngine/ZEngine/Rendering/Renderers/Base/RenderPass.h b/ZEngine/ZEngine/Rendering/Renderers/Base/RenderPass.h index 929fc513..49a19545 100644 --- a/ZEngine/ZEngine/Rendering/Renderers/Base/RenderPass.h +++ b/ZEngine/ZEngine/Rendering/Renderers/Base/RenderPass.h @@ -1,5 +1,6 @@ #pragma once #include +#include #include #include #include @@ -7,61 +8,81 @@ #include #include #include -#include -#include namespace ZEngine::Rendering::Renderers::RenderPasses { + // Base node stored by the render graph. The concrete subtype is determined by + // Specification.Type at creation time (VulkanDevice::CreateRenderPass). struct RenderPass { - RenderPass() {} - ~RenderPass(); - - uint32_t RenderAreaWidth = 0; - uint32_t RenderAreaHeight = 0; - - Specifications::RenderPassSpecification Specification = {}; - std::set Inputs = {}; - Core::Containers::Array RenderTargets = {}; - Renderers::RenderPasses::Attachment* Attachment = {nullptr}; - Pipelines::GraphicPipeline* Pipeline = {nullptr}; - - void Initialize(Hardwares::VulkanDevice* device, Specifications::RenderPassSpecification specification); - void Dispose(); - void Bake(); - bool Verify(); - - // Bind a storage buffer (STORAGE_BUFFER) to all frame descriptor sets by name. - void SetStorageBuffer(std::string_view name, const Core::Memory::BufferView* buffer); + RenderPass() = default; + virtual ~RenderPass() = default; + + Specifications::RenderPassSpecification Specification = {}; + + virtual void Initialize(Hardwares::VulkanDevice* device, Specifications::RenderPassSpecification specification) = 0; + virtual void Dispose() = 0; + virtual void Bake() = 0; + virtual bool Verify() + { + return true; + } + }; + ZDEFINE_PTR(RenderPass); - // Bind a per-frame dynamic uniform (UNIFORM_BUFFER_DYNAMIC) from the FrameHeap. - void SetDynamicUniform(std::string_view name, VkDeviceSize range); + struct GraphicPass : RenderPass + { + public: + ~GraphicPass(); + + uint32_t RenderAreaWidth = 0; + uint32_t RenderAreaHeight = 0; + + Core::Containers::HashSet BoundBindings = {}; + Core::Containers::Array RenderTargets = {}; + struct Attachment* Attachment = {nullptr}; + Pipelines::GraphicPipeline* Pipeline = {nullptr}; + + void Initialize(Hardwares::VulkanDevice* device, Specifications::RenderPassSpecification specification) override; + void Dispose() override; + void Bake() override; + bool Verify() override; + + void SetStorageBuffer(std::string_view name, const Core::Memory::BufferView* buffer); + void SetDynamicUniform(std::string_view name, VkDeviceSize range); + void SetTexture(std::string_view name, const Textures::TextureHandle& texture); + void SetSampler(cstring name, const VkDescriptorImageInfo& sampler_info); + void UseTextureArray(std::string_view name); + + void UpdateInputBinding(); + struct Attachment* GetAttachment() const; + void UpdateRenderTargets(); + uint32_t GetRenderAreaWidth() const; + uint32_t GetRenderAreaHeight() const; - // Bind a single texture as SAMPLED_IMAGE (or the type declared in the shader). - void SetTexture(std::string_view name, const Textures::TextureHandle& texture); + private: + std::pair ValidateInput(std::string_view key); - // Bind a sampler at compile time (SAMPLER). Use for LinearWrapSampler etc. - void SetSampler(cstring name, const VkDescriptorImageInfo& sampler_info); + private: + Hardwares::VulkanDevice* m_device = nullptr; + }; + ZDEFINE_PTR(GraphicPass); - // Connects this pass to the engine's global bindless TextureArray - // (set=1, binding=0, 600 slots). Registers descriptor sets for per-frame - // texture slot updates via DeviceSwapchain::Present(). - // Asserts that the named binding is VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE. - void UseTextureArray(std::string_view name); + struct ComputePass : RenderPass + { + public: + ~ComputePass(); - void UpdateInputBinding(); - ZRawPtr(Renderers::RenderPasses::Attachment) GetAttachment() const; - void UpdateRenderTargets(); - uint32_t GetRenderAreaWidth() const; - uint32_t GetRenderAreaHeight() const; + Pipelines::ComputePipeline* Pipeline = {nullptr}; - private: - std::pair ValidateInput(std::string_view key); + void Initialize(Hardwares::VulkanDevice* device, Specifications::RenderPassSpecification specification) override; + void Dispose() override; + void Bake() override; private: - Hardwares::VulkanDevice* m_device; + Hardwares::VulkanDevice* m_device = nullptr; }; - ZDEFINE_PTR(RenderPass); + ZDEFINE_PTR(ComputePass); struct RenderPassBuilder { @@ -90,6 +111,7 @@ namespace ZEngine::Rendering::Renderers::RenderPasses RenderPassBuilder& SetOffset(uint32_t input_attribute_index, uint32_t offset); RenderPassBuilder& UseShader(std::string_view name); + RenderPassBuilder& UseComputeShader(cstring name, uint32_t push_constant_size = 0); RenderPassBuilder& UseRenderTarget(const Textures::TextureHandle& target); RenderPassBuilder& AddRenderTarget(const Specifications::TextureSpecification& target_spec); RenderPassBuilder& AddInputAttachment(const Textures::TextureHandle& target); diff --git a/ZEngine/ZEngine/Rendering/Renderers/Compute/BloomPass.h b/ZEngine/ZEngine/Rendering/Renderers/Compute/BloomPass.h index 65320fb4..4a975af6 100644 --- a/ZEngine/ZEngine/Rendering/Renderers/Compute/BloomPass.h +++ b/ZEngine/ZEngine/Rendering/Renderers/Compute/BloomPass.h @@ -6,7 +6,7 @@ namespace ZEngine::Rendering::Renderers { struct BloomPass final : public IComputeCallbackPass { - const char* GetShaderName() const override + cstring GetShaderName() const override { return "bloom_threshold_compute"; } diff --git a/ZEngine/ZEngine/Rendering/Renderers/Compute/FrustumCullingPass.h b/ZEngine/ZEngine/Rendering/Renderers/Compute/FrustumCullingPass.h index fbd83cfd..5ebaa857 100644 --- a/ZEngine/ZEngine/Rendering/Renderers/Compute/FrustumCullingPass.h +++ b/ZEngine/ZEngine/Rendering/Renderers/Compute/FrustumCullingPass.h @@ -6,7 +6,7 @@ namespace ZEngine::Rendering::Renderers { struct FrustumCullingPass final : public IComputeCallbackPass { - const char* GetShaderName() const override + cstring GetShaderName() const override { return "frustum_cull_compute"; } diff --git a/ZEngine/ZEngine/Rendering/Renderers/Compute/SSAOPass.h b/ZEngine/ZEngine/Rendering/Renderers/Compute/SSAOPass.h index 5b150fa9..fbce2172 100644 --- a/ZEngine/ZEngine/Rendering/Renderers/Compute/SSAOPass.h +++ b/ZEngine/ZEngine/Rendering/Renderers/Compute/SSAOPass.h @@ -6,7 +6,7 @@ namespace ZEngine::Rendering::Renderers { struct SSAOPass final : public IComputeCallbackPass { - const char* GetShaderName() const override + cstring GetShaderName() const override { return "ssao_compute"; } diff --git a/ZEngine/ZEngine/Rendering/Renderers/Compute/SkinningPass.h b/ZEngine/ZEngine/Rendering/Renderers/Compute/SkinningPass.h index 82d405a0..3a063cb6 100644 --- a/ZEngine/ZEngine/Rendering/Renderers/Compute/SkinningPass.h +++ b/ZEngine/ZEngine/Rendering/Renderers/Compute/SkinningPass.h @@ -6,7 +6,7 @@ namespace ZEngine::Rendering::Renderers { struct SkinningPass final : public IComputeCallbackPass { - const char* GetShaderName() const override + cstring GetShaderName() const override { return "skinning_compute"; } diff --git a/ZEngine/ZEngine/Rendering/Renderers/GraphicRenderer.cpp b/ZEngine/ZEngine/Rendering/Renderers/GraphicRenderer.cpp index 3c6cacae..fade63fe 100644 --- a/ZEngine/ZEngine/Rendering/Renderers/GraphicRenderer.cpp +++ b/ZEngine/ZEngine/Rendering/Renderers/GraphicRenderer.cpp @@ -88,17 +88,19 @@ namespace ZEngine::Rendering::Renderers auto* light_pass = RenderGraph->GetPass("Lighting Pass"); if (depth_pass && depth_pass->Handle) { - depth_pass->Handle->SetStorageBuffer("TransformSB", &scene->TransformBuffer); - depth_pass->Handle->SetStorageBuffer("DrawDataSB", &scene->RenderDataBuffer); + auto* gp = static_cast(depth_pass->Handle); + gp->SetStorageBuffer("TransformSB", &scene->TransformBuffer); + gp->SetStorageBuffer("DrawDataSB", &scene->RenderDataBuffer); } if (gbuffer_pass && gbuffer_pass->Handle) { - gbuffer_pass->Handle->SetStorageBuffer("TransformSB", &scene->TransformBuffer); - gbuffer_pass->Handle->SetStorageBuffer("DrawDataSB", &scene->RenderDataBuffer); - gbuffer_pass->Handle->SetStorageBuffer("MatSB", &scene->MaterialBuffer); + auto* gp = static_cast(gbuffer_pass->Handle); + gp->SetStorageBuffer("TransformSB", &scene->TransformBuffer); + gp->SetStorageBuffer("DrawDataSB", &scene->RenderDataBuffer); + gp->SetStorageBuffer("MatSB", &scene->MaterialBuffer); } if (light_pass && light_pass->Handle && scene->LightBuffer.Handle) - light_pass->Handle->SetStorageBuffer("LightSB", &scene->LightBuffer); + static_cast(light_pass->Handle)->SetStorageBuffer("LightSB", &scene->LightBuffer); m_static_buffers_bound = true; ZENGINE_CORE_INFO("[GraphicRenderer] Bound TransformSB/DrawDataSB/MatSB/LightSB to passes") } @@ -117,14 +119,16 @@ namespace ZEngine::Rendering::Renderers auto* gbuffer_pass = RenderGraph->GetPass("G-Buffer Pass"); if (depth_pass && depth_pass->Handle) { - depth_pass->Handle->SetStorageBuffer("VertexSB", vtx_buf); - depth_pass->Handle->SetStorageBuffer("IndexSB", idx_buf); + auto* gp = static_cast(depth_pass->Handle); + gp->SetStorageBuffer("VertexSB", vtx_buf); + gp->SetStorageBuffer("IndexSB", idx_buf); } if (gbuffer_pass && gbuffer_pass->Handle) { - gbuffer_pass->Handle->SetStorageBuffer("VertexSB", vtx_buf); - gbuffer_pass->Handle->SetStorageBuffer("IndexSB", idx_buf); - gbuffer_pass->Handle->UseTextureArray("TextureArray"); + auto* gp = static_cast(gbuffer_pass->Handle); + gp->SetStorageBuffer("VertexSB", vtx_buf); + gp->SetStorageBuffer("IndexSB", idx_buf); + gp->UseTextureArray("TextureArray"); } m_global_buffers_bound = true; ZENGINE_CORE_INFO("[GraphicRenderer] Bound global VertexSB/IndexSB to geometry passes") diff --git a/ZEngine/ZEngine/Rendering/Renderers/Graphics/CompositePass.cpp b/ZEngine/ZEngine/Rendering/Renderers/Graphics/CompositePass.cpp index fcc920d5..f8480364 100644 --- a/ZEngine/ZEngine/Rendering/Renderers/Graphics/CompositePass.cpp +++ b/ZEngine/ZEngine/Rendering/Renderers/Graphics/CompositePass.cpp @@ -25,20 +25,18 @@ namespace ZEngine::Rendering::Renderers *output_pass = device->CreateRenderPass(std::move(pass_spec)); (*output_pass)->Bake(); } - (*output_pass)->SetSampler("LinearWrapSampler", device->GlobalLinearWrapSamplerImageInfo); - (*output_pass)->Verify(); + auto* gp = static_cast(*output_pass); + gp->SetSampler("LinearWrapSampler", device->GlobalLinearWrapSamplerImageInfo); + gp->Verify(); } void CompositePass::Execute(Hardwares::VulkanDevicePtr const device, RenderGraphResourceInspectorPtr res_inspector, Rendering::Scenes::SceneDataPtr const scene, RenderPasses::RenderPass* const pass, Buffers::FramebufferVNext* const framebuffer, Hardwares::CommandBufferPtr const command_buffer) { - command_buffer->BeginRenderPass(pass, framebuffer->Handle, false); - { - uint32_t w = pass->GetRenderAreaWidth(); - uint32_t h = pass->GetRenderAreaHeight(); - command_buffer->SetViewport(w, h); - command_buffer->SetScissor(w, h); - } - command_buffer->BindPipeline(Specifications::PipelineBindPoint::GRAPHIC, pass->Pipeline); + auto* gp = static_cast(pass); + command_buffer->BeginRenderPass(gp, framebuffer->Handle, false); + command_buffer->SetViewport(gp->GetRenderAreaWidth(), gp->GetRenderAreaHeight()); + command_buffer->SetScissor(gp->GetRenderAreaWidth(), gp->GetRenderAreaHeight()); + command_buffer->BindPipeline(gp->Pipeline); command_buffer->BindDescriptorSets(device->SwapchainPtr->CurrentFrame->Index, nullptr, 0u); command_buffer->Draw(3, 1, 0, 0); command_buffer->EndRenderPass(); diff --git a/ZEngine/ZEngine/Rendering/Renderers/Graphics/DepthPrePass.cpp b/ZEngine/ZEngine/Rendering/Renderers/Graphics/DepthPrePass.cpp index 6d076cb7..30ced510 100644 --- a/ZEngine/ZEngine/Rendering/Renderers/Graphics/DepthPrePass.cpp +++ b/ZEngine/ZEngine/Rendering/Renderers/Graphics/DepthPrePass.cpp @@ -35,28 +35,23 @@ namespace ZEngine::Rendering::Renderers if (scene) { - (*output_pass)->SetDynamicUniform("UBCamera", sizeof(UBOCameraLayout)); - // VertexSB/IndexSB/DrawDataSB/TransformSB bound by UpdateRMMBindings via BufferView*. - (*output_pass)->Verify(); + auto* gp = static_cast(*output_pass); + gp->SetDynamicUniform("UBCamera", sizeof(UBOCameraLayout)); + gp->Verify(); } } void DepthPrePass::Execute(Hardwares::VulkanDevicePtr const device, RenderGraphResourceInspectorPtr res_inspector, Rendering::Scenes::SceneDataPtr const scene, RenderPasses::RenderPass* const pass, Buffers::FramebufferVNext* const framebuffer, Hardwares::CommandBufferPtr const command_buffer) { if (!scene || scene->IndirectCommandCount == 0 || !scene->RMMVertexHandle.IsValid()) - { return; - } - command_buffer->BeginRenderPass(pass, framebuffer->Handle, false); - { - uint32_t w = pass->GetRenderAreaWidth(); - uint32_t h = pass->GetRenderAreaHeight(); - command_buffer->SetViewport(w, h); - command_buffer->SetScissor(w, h); - } - command_buffer->BindPipeline(Specifications::PipelineBindPoint::GRAPHIC, pass->Pipeline); - command_buffer->BindDescriptorSets(device->SwapchainPtr->CurrentFrame->Index, scene ? &scene->CameraHeapOffset : nullptr, scene ? 1u : 0u); + auto* gp = static_cast(pass); + command_buffer->BeginRenderPass(gp, framebuffer->Handle, false); + command_buffer->SetViewport(gp->GetRenderAreaWidth(), gp->GetRenderAreaHeight()); + command_buffer->SetScissor(gp->GetRenderAreaWidth(), gp->GetRenderAreaHeight()); + command_buffer->BindPipeline(gp->Pipeline); + command_buffer->BindDescriptorSets(device->SwapchainPtr->CurrentFrame->Index, &scene->CameraHeapOffset, 1u); command_buffer->DrawIndirect(device->FrameHeaps[device->SwapchainPtr->CurrentFrame->Index].Handle, scene->IndirectHeapOffset, scene->IndirectCommandCount); command_buffer->EndRenderPass(); } diff --git a/ZEngine/ZEngine/Rendering/Renderers/Graphics/GbufferPass.cpp b/ZEngine/ZEngine/Rendering/Renderers/Graphics/GbufferPass.cpp index a0f35a1a..3dc75c4a 100644 --- a/ZEngine/ZEngine/Rendering/Renderers/Graphics/GbufferPass.cpp +++ b/ZEngine/ZEngine/Rendering/Renderers/Graphics/GbufferPass.cpp @@ -32,12 +32,11 @@ namespace ZEngine::Rendering::Renderers if (scene) { - (*output_pass)->SetDynamicUniform("UBCamera", sizeof(UBOCameraLayout)); - // VertexSB / IndexSB bound by GraphicRenderer::UpdateRMMBindings (RMM path). - // DrawDataSB/TransformSB/MatSB bound by UpdateRMMBindings via BufferView*. - (*output_pass)->UseTextureArray("TextureArray"); - (*output_pass)->SetSampler("LinearWrapSampler", device->GlobalLinearWrapSamplerImageInfo); - (*output_pass)->Verify(); + auto* gp = static_cast(*output_pass); + gp->SetDynamicUniform("UBCamera", sizeof(UBOCameraLayout)); + gp->UseTextureArray("TextureArray"); + gp->SetSampler("LinearWrapSampler", device->GlobalLinearWrapSamplerImageInfo); + gp->Verify(); } } @@ -45,14 +44,13 @@ namespace ZEngine::Rendering::Renderers { CHECK_AND_ESCAPE_NULL(scene) - command_buffer->BeginRenderPass(pass, framebuffer->Handle, false); + auto* gp = static_cast(pass); + command_buffer->BeginRenderPass(gp, framebuffer->Handle, false); if (scene->IndirectCommandCount > 0 && scene->RMMVertexHandle.IsValid()) { - uint32_t w = pass->GetRenderAreaWidth(); - uint32_t h = pass->GetRenderAreaHeight(); - command_buffer->SetViewport(w, h); - command_buffer->SetScissor(w, h); - command_buffer->BindPipeline(Specifications::PipelineBindPoint::GRAPHIC, pass->Pipeline); + command_buffer->SetViewport(gp->GetRenderAreaWidth(), gp->GetRenderAreaHeight()); + command_buffer->SetScissor(gp->GetRenderAreaWidth(), gp->GetRenderAreaHeight()); + command_buffer->BindPipeline(gp->Pipeline); command_buffer->BindDescriptorSets(device->SwapchainPtr->CurrentFrame->Index, &scene->CameraHeapOffset, 1u); command_buffer->DrawIndirect(device->FrameHeaps[device->SwapchainPtr->CurrentFrame->Index].Handle, scene->IndirectHeapOffset, scene->IndirectCommandCount); } diff --git a/ZEngine/ZEngine/Rendering/Renderers/Graphics/GridPass.cpp b/ZEngine/ZEngine/Rendering/Renderers/Graphics/GridPass.cpp index 07282b87..2dcb2038 100644 --- a/ZEngine/ZEngine/Rendering/Renderers/Graphics/GridPass.cpp +++ b/ZEngine/ZEngine/Rendering/Renderers/Graphics/GridPass.cpp @@ -59,24 +59,22 @@ namespace ZEngine::Rendering::Renderers (*output_pass)->Bake(); } - if (scene) { - (*output_pass)->SetDynamicUniform("UBCamera", sizeof(UBOCameraLayout)); + auto* gp = static_cast(*output_pass); + if (scene) + gp->SetDynamicUniform("UBCamera", sizeof(UBOCameraLayout)); + gp->Verify(); } - (*output_pass)->Verify(); } void GridPass::Execute(Hardwares::VulkanDevicePtr const device, RenderGraphResourceInspectorPtr res_inspector, Rendering::Scenes::SceneDataPtr const scene, RenderPasses::RenderPass* const pass, Buffers::FramebufferVNext* const framebuffer, Hardwares::CommandBufferPtr const command_buffer) { - command_buffer->BeginRenderPass(pass, framebuffer->Handle, false); - { - uint32_t w = pass->GetRenderAreaWidth(); - uint32_t h = pass->GetRenderAreaHeight(); - command_buffer->SetViewport(w, h); - command_buffer->SetScissor(w, h); - } + auto* gp = static_cast(pass); auto* rrm = ZEngine::Engine::GetContext()->RenderResourceManager; - command_buffer->BindPipeline(Specifications::PipelineBindPoint::GRAPHIC, pass->Pipeline); + command_buffer->BeginRenderPass(gp, framebuffer->Handle, false); + command_buffer->SetViewport(gp->GetRenderAreaWidth(), gp->GetRenderAreaHeight()); + command_buffer->SetScissor(gp->GetRenderAreaWidth(), gp->GetRenderAreaHeight()); + command_buffer->BindPipeline(gp->Pipeline); command_buffer->BindVertexBuffer(*rrm->GetBuiltinVertexBuffer()); command_buffer->BindIndexBuffer(*rrm->GetBuiltinIndexBuffer(), VK_INDEX_TYPE_UINT32); command_buffer->BindDescriptorSets(device->SwapchainPtr->CurrentFrame->Index, scene ? &scene->CameraHeapOffset : nullptr, scene ? 1u : 0u); diff --git a/ZEngine/ZEngine/Rendering/Renderers/Graphics/LightingPass.cpp b/ZEngine/ZEngine/Rendering/Renderers/Graphics/LightingPass.cpp index ca3fb97e..fab3c159 100644 --- a/ZEngine/ZEngine/Rendering/Renderers/Graphics/LightingPass.cpp +++ b/ZEngine/ZEngine/Rendering/Renderers/Graphics/LightingPass.cpp @@ -31,7 +31,8 @@ namespace ZEngine::Rendering::Renderers (*output_pass)->Bake(); } - (*output_pass)->SetDynamicUniform("UBCamera", sizeof(UBOCameraLayout)); + auto* gp = static_cast(*output_pass); + gp->SetDynamicUniform("UBCamera", sizeof(UBOCameraLayout)); auto albedo_ao_handle = res_inspector->GetRenderTarget(RendererResourceName::GBufferAlbedoAOName); auto normal_rough_handle = res_inspector->GetRenderTarget(RendererResourceName::GBufferNormalRoughnessName); @@ -39,31 +40,28 @@ namespace ZEngine::Rendering::Renderers auto depth_handle = res_inspector->GetRenderTarget(RendererResourceName::FrameDepthRenderTargetName); if (albedo_ao_handle.Valid()) - (*output_pass)->SetTexture("GBufferAlbedoAO", albedo_ao_handle); + gp->SetTexture("GBufferAlbedoAO", albedo_ao_handle); if (normal_rough_handle.Valid()) - (*output_pass)->SetTexture("GBufferNormalRoughness", normal_rough_handle); + gp->SetTexture("GBufferNormalRoughness", normal_rough_handle); if (metallic_emit_handle.Valid()) - (*output_pass)->SetTexture("GBufferMetallicEmissive", metallic_emit_handle); + gp->SetTexture("GBufferMetallicEmissive", metallic_emit_handle); if (depth_handle.Valid()) - (*output_pass)->SetTexture("GBufferDepth", depth_handle); + gp->SetTexture("GBufferDepth", depth_handle); if (scene && scene->LightBuffer.Handle) - (*output_pass)->SetStorageBuffer("LightSB", &scene->LightBuffer); + gp->SetStorageBuffer("LightSB", &scene->LightBuffer); - (*output_pass)->SetSampler("GBufferSampler", device->GlobalLinearWrapSamplerImageInfo); - (*output_pass)->Verify(); + gp->SetSampler("GBufferSampler", device->GlobalLinearWrapSamplerImageInfo); + gp->Verify(); } void LightingPass::Execute(Hardwares::VulkanDevicePtr const device, RenderGraphResourceInspectorPtr res_inspector, Rendering::Scenes::SceneDataPtr const scene, RenderPasses::RenderPass* const pass, Buffers::FramebufferVNext* const framebuffer, Hardwares::CommandBufferPtr const command_buffer) { - command_buffer->BeginRenderPass(pass, framebuffer->Handle, false); - { - uint32_t w = pass->GetRenderAreaWidth(); - uint32_t h = pass->GetRenderAreaHeight(); - command_buffer->SetViewport(w, h); - command_buffer->SetScissor(w, h); - } - command_buffer->BindPipeline(Specifications::PipelineBindPoint::GRAPHIC, pass->Pipeline); + auto* gp = static_cast(pass); + command_buffer->BeginRenderPass(gp, framebuffer->Handle, false); + command_buffer->SetViewport(gp->GetRenderAreaWidth(), gp->GetRenderAreaHeight()); + command_buffer->SetScissor(gp->GetRenderAreaWidth(), gp->GetRenderAreaHeight()); + command_buffer->BindPipeline(gp->Pipeline); command_buffer->BindDescriptorSets(device->SwapchainPtr->CurrentFrame->Index, scene ? &scene->CameraHeapOffset : nullptr, scene ? 1u : 0u); command_buffer->Draw(3, 1, 0, 0); command_buffer->EndRenderPass(); diff --git a/ZEngine/ZEngine/Rendering/Renderers/Graphics/SkyboxPass.cpp b/ZEngine/ZEngine/Rendering/Renderers/Graphics/SkyboxPass.cpp index fc703652..d3e2a1b0 100644 --- a/ZEngine/ZEngine/Rendering/Renderers/Graphics/SkyboxPass.cpp +++ b/ZEngine/ZEngine/Rendering/Renderers/Graphics/SkyboxPass.cpp @@ -85,10 +85,11 @@ namespace ZEngine::Rendering::Renderers if (scene && m_env_map.Valid()) { - (*output_pass)->SetDynamicUniform("UBCamera", sizeof(UBOCameraLayout)); - (*output_pass)->SetTexture("EnvMap", m_env_map); - (*output_pass)->SetSampler("LinearClampToEdgeSampler", device->GlobalLinearClampToEdgeSamplerImageInfo); - (*output_pass)->Verify(); + auto* gp = static_cast(*output_pass); + gp->SetDynamicUniform("UBCamera", sizeof(UBOCameraLayout)); + gp->SetTexture("EnvMap", m_env_map); + gp->SetSampler("LinearClampToEdgeSampler", device->GlobalLinearClampToEdgeSamplerImageInfo); + gp->Verify(); } } @@ -97,15 +98,12 @@ namespace ZEngine::Rendering::Renderers if (!m_env_map.Valid()) return; - command_buffer->BeginRenderPass(pass, framebuffer->Handle, false); - { - uint32_t w = pass->GetRenderAreaWidth(); - uint32_t h = pass->GetRenderAreaHeight(); - command_buffer->SetViewport(w, h); - command_buffer->SetScissor(w, h); - } + auto* gp = static_cast(pass); auto* rrm = ZEngine::Engine::GetContext()->RenderResourceManager; - command_buffer->BindPipeline(Specifications::PipelineBindPoint::GRAPHIC, pass->Pipeline); + command_buffer->BeginRenderPass(gp, framebuffer->Handle, false); + command_buffer->SetViewport(gp->GetRenderAreaWidth(), gp->GetRenderAreaHeight()); + command_buffer->SetScissor(gp->GetRenderAreaWidth(), gp->GetRenderAreaHeight()); + command_buffer->BindPipeline(gp->Pipeline); command_buffer->BindVertexBuffer(*rrm->GetBuiltinVertexBuffer()); command_buffer->BindIndexBuffer(*rrm->GetBuiltinIndexBuffer(), VK_INDEX_TYPE_UINT32); command_buffer->BindDescriptorSets(device->SwapchainPtr->CurrentFrame->Index, scene ? &scene->CameraHeapOffset : nullptr, scene ? 1u : 0u); diff --git a/ZEngine/ZEngine/Rendering/Renderers/Pipelines/RendererPipeline.cpp b/ZEngine/ZEngine/Rendering/Renderers/Pipelines/RendererPipeline.cpp index d12fd2c5..3b3b1c89 100644 --- a/ZEngine/ZEngine/Rendering/Renderers/Pipelines/RendererPipeline.cpp +++ b/ZEngine/ZEngine/Rendering/Renderers/Pipelines/RendererPipeline.cpp @@ -7,6 +7,59 @@ using namespace ZEngine::Core::Containers; namespace ZEngine::Rendering::Renderers::Pipelines { + void ComputePipeline::Initialize(Hardwares::VulkanDevice* device, cstring shader_name, uint32_t /*push_constant_size*/) + { + Device = device; + Specifications::ShaderSpecification spec{}; + spec.Name = shader_name; + auto shader_handle = Device->CompileShader(spec); + if (!shader_handle) + { + ZENGINE_CORE_ERROR("") + return; + } + + Shader = Device->ShaderManager.Access(shader_handle); + } + + void ComputePipeline::Bake() + { + ZENGINE_VALIDATE_ASSERT(Shader, "ComputePipeline::Bake called with no shader") + ZENGINE_VALIDATE_ASSERT(!Shader->ShaderCreateInfos.empty(), "Compute shader has no stage info") + ZENGINE_VALIDATE_ASSERT(Shader->ShaderCreateInfos[0].stage == VK_SHADER_STAGE_COMPUTE_BIT, "Shader stage is not VK_SHADER_STAGE_COMPUTE_BIT") + + VkPipelineLayoutCreateInfo layout_ci = {}; + layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; + layout_ci.setLayoutCount = (uint32_t) Shader->SetLayouts.size(); + layout_ci.pSetLayouts = Shader->SetLayouts.data(); + layout_ci.pushConstantRangeCount = (uint32_t) Shader->PushConstants.size(); + layout_ci.pPushConstantRanges = Shader->PushConstants.data(); + ZENGINE_VALIDATE_ASSERT(vkCreatePipelineLayout(Device->LogicalDevice, &layout_ci, nullptr, &Layout) == VK_SUCCESS, "Failed to create compute pipeline layout") + + VkComputePipelineCreateInfo ci = {}; + ci.sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO; + ci.stage = Shader->ShaderCreateInfos[0]; + ci.layout = Layout; + ZENGINE_VALIDATE_ASSERT(vkCreateComputePipelines(Device->LogicalDevice, VK_NULL_HANDLE, 1, &ci, nullptr, &Handle) == VK_SUCCESS, "Failed to create compute pipeline") + } + + void ComputePipeline::Dispose() + { + if (Shader) + Shader->Dispose(); + + if (Layout != VK_NULL_HANDLE) + { + vkDestroyPipelineLayout(Device->LogicalDevice, Layout, nullptr); + Layout = VK_NULL_HANDLE; + } + if (Handle != VK_NULL_HANDLE) + { + vkDestroyPipeline(Device->LogicalDevice, Handle, nullptr); + Handle = VK_NULL_HANDLE; + } + } + void GraphicPipeline::Initialize(Hardwares::VulkanDevice* device, Specifications::GraphicRendererPipelineSpecification&& spec) { Device = device; diff --git a/ZEngine/ZEngine/Rendering/Renderers/Pipelines/RendererPipeline.h b/ZEngine/ZEngine/Rendering/Renderers/Pipelines/RendererPipeline.h index e6176ddf..003415c7 100644 --- a/ZEngine/ZEngine/Rendering/Renderers/Pipelines/RendererPipeline.h +++ b/ZEngine/ZEngine/Rendering/Renderers/Pipelines/RendererPipeline.h @@ -7,20 +7,41 @@ namespace ZEngine::Rendering::Renderers::Pipelines { - struct GraphicPipeline + struct IPipeline { - public: - GraphicPipeline() {} - ~GraphicPipeline() {} + virtual ~IPipeline() = default; + Shaders::Shader* Shader = nullptr; + Hardwares::VulkanDevice* Device = nullptr; + VkPipeline Handle = VK_NULL_HANDLE; + VkPipelineLayout Layout = VK_NULL_HANDLE; + + virtual VkPipelineBindPoint GetBindPoint() const = 0; + virtual void Bake() = 0; + virtual void Dispose() = 0; + }; + + struct GraphicPipeline : IPipeline + { Specifications::GraphicRendererPipelineSpecification Specification = {}; - Shaders::Shader* Shader = nullptr; - Hardwares::VulkanDevice* Device = nullptr; - VkPipeline Handle = VK_NULL_HANDLE; - VkPipelineLayout Layout = VK_NULL_HANDLE; - void Initialize(Hardwares::VulkanDevice* device, Specifications::GraphicRendererPipelineSpecification&& spec); - void Bake(); - void Dispose(); + VkPipelineBindPoint GetBindPoint() const override + { + return VK_PIPELINE_BIND_POINT_GRAPHICS; + } + void Initialize(Hardwares::VulkanDevice* device, Specifications::GraphicRendererPipelineSpecification&& spec); + void Bake() override; + void Dispose() override; + }; + + struct ComputePipeline : IPipeline + { + VkPipelineBindPoint GetBindPoint() const override + { + return VK_PIPELINE_BIND_POINT_COMPUTE; + } + void Initialize(Hardwares::VulkanDevice* device, cstring shader_name, uint32_t push_constant_size = 0); + void Bake() override; + void Dispose() override; }; -} // namespace ZEngine::Rendering::Renderers::Pipelines \ No newline at end of file +} // namespace ZEngine::Rendering::Renderers::Pipelines diff --git a/ZEngine/ZEngine/Rendering/Renderers/RenderGraph.cpp b/ZEngine/ZEngine/Rendering/Renderers/RenderGraph.cpp index 6d89beb4..fc74d0ad 100644 --- a/ZEngine/ZEngine/Rendering/Renderers/RenderGraph.cpp +++ b/ZEngine/ZEngine/Rendering/Renderers/RenderGraph.cpp @@ -351,15 +351,16 @@ namespace ZEngine::Rendering::Renderers for (auto& pass : Passes) { - if (!pass.Handle) + if (!pass.Handle || pass.Handle->Specification.Type == Specifications::RenderPassType::COMPUTE) continue; + auto* gp = static_cast(pass.Handle); for (const auto& r : pass.Reads) { if (!r.Handle.Valid() || !r.BindingKey) continue; const auto& res = Resources[r.Handle.Index]; if (res.TextureHandle.Valid()) - pass.Handle->SetTexture(r.BindingKey, res.TextureHandle); + gp->SetTexture(r.BindingKey, res.TextureHandle); } } @@ -847,11 +848,12 @@ namespace ZEngine::Rendering::Renderers if (view_count == 0 || w == 0) continue; - pass.Handle->RenderAreaWidth = w; - pass.Handle->RenderAreaHeight = h; + auto* gp = static_cast(pass.Handle); + gp->RenderAreaWidth = w; + gp->RenderAreaHeight = h; - VkRenderPass rp = pass.Handle->GetAttachment()->GetHandle(); - VkFramebuffer vk_fb = Device->CreateFramebuffer(Core::Containers::ArrayView{view_buf, view_count}, rp, w, h); + VkRenderPass rp = gp->GetAttachment()->GetHandle(); + VkFramebuffer vk_fb = Device->CreateFramebuffer(Core::Containers::ArrayView{view_buf, view_count}, rp, w, h); if (vk_fb == VK_NULL_HANDLE) { diff --git a/ZEngine/ZEngine/Rendering/Renderers/ZUIRenderer.cpp b/ZEngine/ZEngine/Rendering/Renderers/ZUIRenderer.cpp index cc1cc7d2..8a42888e 100644 --- a/ZEngine/ZEngine/Rendering/Renderers/ZUIRenderer.cpp +++ b/ZEngine/ZEngine/Rendering/Renderers/ZUIRenderer.cpp @@ -66,7 +66,7 @@ namespace ZEngine::Rendering::Renderers .UseShader("zui_draw") .UseSwapchainAsRenderTarget(); - DrawPass = Device->CreateRenderPass(pass_builder->Detach()); + DrawPass = static_cast(Device->CreateRenderPass(pass_builder->Detach())); DrawPass->UseTextureArray("TextureArray"); DrawPass->SetSampler("LinearClampSampler", Device->GlobalLinearClampToEdgeSamplerImageInfo); DrawPass->Verify(); @@ -766,7 +766,7 @@ namespace ZEngine::Rendering::Renderers secondary_cb->ResetState(); secondary_cb->BeginSecondary(DrawPass, current_fb); secondary_cb->SetViewport(DrawPass->GetRenderAreaWidth(), DrawPass->GetRenderAreaHeight()); - secondary_cb->BindPipeline(Specifications::PipelineBindPoint::GRAPHIC, DrawPass->Pipeline); + secondary_cb->BindPipeline(DrawPass->Pipeline); secondary_cb->BindVertexBuffer(VtxBHandles[fi]); secondary_cb->BindIndexBuffer(IdxBHandles[fi], VK_INDEX_TYPE_UINT16); diff --git a/ZEngine/ZEngine/Rendering/Renderers/ZUIRenderer.h b/ZEngine/ZEngine/Rendering/Renderers/ZUIRenderer.h index ccaa4a56..456a6e6b 100644 --- a/ZEngine/ZEngine/Rendering/Renderers/ZUIRenderer.h +++ b/ZEngine/ZEngine/Rendering/Renderers/ZUIRenderer.h @@ -39,23 +39,23 @@ namespace ZEngine::Rendering::Renderers struct ZUIRenderer : public IRenderer { - static constexpr uint32_t FRAMES_IN_FLIGHT = 3; - static constexpr uint32_t ZUICommandBufferIndex = 1; + static constexpr uint32_t FRAMES_IN_FLIGHT = 3; + static constexpr uint32_t ZUICommandBufferIndex = 1; - RenderPasses::RenderPass* DrawPass = nullptr; // zui_draw pipeline + RenderPasses::GraphicPass* DrawPass = nullptr; // Per-frame vertex + index buffers - Core::Memory::BufferView VtxBHandles[FRAMES_IN_FLIGHT] = {}; - Core::Memory::BufferView IdxBHandles[FRAMES_IN_FLIGHT] = {}; + Core::Memory::BufferView VtxBHandles[FRAMES_IN_FLIGHT] = {}; + Core::Memory::BufferView IdxBHandles[FRAMES_IN_FLIGHT] = {}; - void Initialize(Hardwares::VulkanDevicePtr device) override; - void Deinitialize() override; + void Initialize(Hardwares::VulkanDevicePtr device) override; + void Deinitialize() override; // Translate the ZUIBox tree into a flat ZUIRenderPayload. - void PreparePayload(UI::ZUIContext* ctx, ZUIRenderPayload* out, Core::Memory::ArenaAllocator* payload_arena); + void PreparePayload(UI::ZUIContext* ctx, ZUIRenderPayload* out, Core::Memory::ArenaAllocator* payload_arena); // Submit to Vulkan. - void Submit(Hardwares::CommandBuffer* primary_cmd, const ZUIRenderPayload& payload); + void Submit(Hardwares::CommandBuffer* primary_cmd, const ZUIRenderPayload& payload); }; ZDEFINE_PTR(ZUIRenderer); diff --git a/ZEngine/ZEngine/Rendering/Specifications/RenderPassSpecification.h b/ZEngine/ZEngine/Rendering/Specifications/RenderPassSpecification.h index f4bc0860..5bde8f47 100644 --- a/ZEngine/ZEngine/Rendering/Specifications/RenderPassSpecification.h +++ b/ZEngine/ZEngine/Rendering/Specifications/RenderPassSpecification.h @@ -20,6 +20,8 @@ namespace ZEngine::Rendering::Specifications bool SwapchainAsRenderTarget = false; RenderPassType Type = {RenderPassType::GRAPHIC}; Specifications::GraphicRendererPipelineSpecification PipelineSpecification = {}; + const char* ComputeShaderName = nullptr; + uint32_t ComputePushConstantSize = 0; Core::Containers::Array Inputs = {}; Core::Containers::UnorderedHashMap InputTextures = {}; Core::Containers::Array Outputs = {};