diff --git a/SHADE_Application/src/Application/SBApplication.cpp b/SHADE_Application/src/Application/SBApplication.cpp index 5420e8c5..da13491b 100644 --- a/SHADE_Application/src/Application/SBApplication.cpp +++ b/SHADE_Application/src/Application/SBApplication.cpp @@ -37,7 +37,9 @@ namespace Sandbox window.Create(hInstance, hPrevInstance, lpCmdLine, nCmdShow); SHADE::SHSystemManager::CreateSystem(); SHADE::SHGraphicsSystem* graphicsSystem = static_cast(SHADE::SHSystemManager::GetSystem()); - SHADE::SHSystemManager::RegisterRoutine(1); + SHADE::SHSystemManager::RegisterRoutine(1); + SHADE::SHSystemManager::RegisterRoutine(1); + SHADE::SHSystemManager::RegisterRoutine(1); graphicsSystem->SetWindow(&window); diff --git a/SHADE_Engine/src/ECS_Base/System/SHSystem.h b/SHADE_Engine/src/ECS_Base/System/SHSystem.h index 19b16f72..93ea6a59 100644 --- a/SHADE_Engine/src/ECS_Base/System/SHSystem.h +++ b/SHADE_Engine/src/ECS_Base/System/SHSystem.h @@ -11,13 +11,14 @@ #pragma once #include "../SHECSMacros.h" +#include "SH_API.h" namespace SHADE { class SHSystemManager; - class SHSystem + class SH_API SHSystem { private: SystemID systemID; diff --git a/SHADE_Engine/src/ECS_Base/System/SHSystemRoutine.h b/SHADE_Engine/src/ECS_Base/System/SHSystemRoutine.h index cdb62438..2b6d8dc1 100644 --- a/SHADE_Engine/src/ECS_Base/System/SHSystemRoutine.h +++ b/SHADE_Engine/src/ECS_Base/System/SHSystemRoutine.h @@ -7,6 +7,7 @@ #include "SHRoutineStats.h" #include "SHSystem.h" #include +#include "SH_API.h" namespace SHADE @@ -15,7 +16,7 @@ namespace SHADE class SHSystemManager; - class SHSystemRoutine + class SH_API SHSystemRoutine { friend class SHSystemManager; protected: diff --git a/SHADE_Engine/src/Editor/SHEditor.cpp b/SHADE_Engine/src/Editor/SHEditor.cpp index 6d0f1a28..89814bc5 100644 --- a/SHADE_Engine/src/Editor/SHEditor.cpp +++ b/SHADE_Engine/src/Editor/SHEditor.cpp @@ -43,8 +43,8 @@ namespace SHADE imguiCommandPool = gfxSystem->GetDevice()->CreateCommandPool(SH_QUEUE_FAMILY_ARRAY_INDEX::GRAPHICS, SH_CMD_POOL_RESET::POOL_BASED, true); imguiCommandBuffer = imguiCommandPool->RequestCommandBuffer(SH_CMD_BUFFER_TYPE::PRIMARY); - auto renderPass = gfxSystem->GetRenderGraph().GetNode("ImGui Node")->GetRenderpass(); - ImGui_ImplVulkan_Init(&initInfo, renderPass->GetVkRenderpass()); + /*auto renderPass = gfxSystem->GetRenderGraph().GetNode("ImGui Node")->GetRenderpass(); + ImGui_ImplVulkan_Init(&initInfo, renderPass->GetVkRenderpass());*/ imguiCommandBuffer->BeginRecording(); ImGui_ImplVulkan_CreateFontsTexture(imguiCommandBuffer->GetVkCommandBuffer()); @@ -53,9 +53,9 @@ namespace SHADE ImGui_ImplVulkan_DestroyFontUploadObjects(); - gfxSystem->GetRenderGraph().GetNode("ImGui Node")->GetSubpass("ImGui Draw")->AddExteriorDrawCalls([](Handle& cmd) { + /*gfxSystem->GetRenderGraph().GetNode("ImGui Node")->GetSubpass("ImGui Draw")->AddExteriorDrawCalls([](Handle& cmd) { ImGui_ImplVulkan_RenderDrawData(ImGui::GetDrawData(), cmd->GetVkCommandBuffer()); - }); + });*/ //ImGuiIO& io = ImGui::GetIO(); //int w, h; diff --git a/SHADE_Engine/src/Graphics/Buffers/SHVkBuffer.cpp b/SHADE_Engine/src/Graphics/Buffers/SHVkBuffer.cpp index 7913574c..20b94626 100644 --- a/SHADE_Engine/src/Graphics/Buffers/SHVkBuffer.cpp +++ b/SHADE_Engine/src/Graphics/Buffers/SHVkBuffer.cpp @@ -33,8 +33,20 @@ namespace SHADE }; cmdBufferHdl->GetVkCommandBuffer().copyBuffer(stagingBuffer, vkBuffer, 1, ©Region); } + } - // TODO: Need to destroy staging buffer. Obviously not here but after the command has finished executing. + void SHVkBuffer::ResizeNoCopy(uint32_t newSize) + { + Destroy(); + vk::Buffer tempBuffer; + std::tie(tempBuffer, std::ignore) = createBuffer(newSize); + vkBuffer = tempBuffer; + } + + void SHVkBuffer::ResizeReplace(uint32_t newSize, void* data, uint32_t srcSize) + { + Destroy(); + Init(newSize, data, srcSize, bufferUsageFlags, allocCreateInfo.usage, allocCreateInfo.flags); } vk::Buffer SHVkBuffer::GetVkBuffer(void) const noexcept @@ -195,12 +207,12 @@ namespace SHADE // results of allocation VmaAllocation stagingAlloc; - // To get around VMA's usage for C version of vulkan, create a temp first..., + // To get around VMA's usage for C version of Vulkan, create a temp first..., VkBuffer tempBuffer{}; // Create the buffer... vmaCreateBuffer(vmaAllocator, - &bufferInfo.operator VkBufferCreateInfo & (), // TODO: Verify if this works (can use renderdoc to check buffer variables?) + &bufferInfo.operator VkBufferCreateInfo & (), // TODO: Verify if this works (can use RenderDoc to check buffer variables?) &allocCreateInfo, &tempBuffer, &stagingAlloc, &allocInfo); @@ -221,6 +233,32 @@ namespace SHADE vmaUnmapMemory(vmaAllocator, stagingAlloc); } + std::pair SHVkBuffer::createBuffer(uint32_t size) + { + // Modify the size based on the parameter + sizeStored = size; + bufferCreateInfo.size = sizeStored; + + // parameters of a vmaAllocation retrieved via vmaGetAllocationInfo + VmaAllocationInfo allocInfo; + + // To get around VMA's usage for C version of vulkan, create a temp first..., + VkBuffer tempBuffer{}; + + // Create the buffer... + auto result = vmaCreateBuffer(vmaAllocator, + &bufferCreateInfo.operator VkBufferCreateInfo & (), + &allocCreateInfo, + &tempBuffer, &alloc, &allocInfo); + + if (result != VK_SUCCESS) + SHVulkanDebugUtil::ReportVkError(vk::Result(result), "Failed to create vulkan buffer. "); + else + SHVulkanDebugUtil::ReportVkSuccess("Successfully created buffer. "); + + return { tempBuffer, allocInfo }; + } + /***************************************************************************/ /*! @@ -230,17 +268,15 @@ namespace SHADE */ /***************************************************************************/ SHVkBuffer::SHVkBuffer(std::reference_wrapper allocator) noexcept - : vkBuffer{} - , stagingBuffer{} - , sizeStored{ 0 } - , mappedPtr{ nullptr } - , alloc {nullptr} - , randomAccessOptimized{false} - , boundToCoherent {false} - , vmaAllocator{allocator} - { - - } + : vkBuffer{} + , stagingBuffer{} + , sizeStored{ 0 } + , mappedPtr{ nullptr } + , alloc {nullptr} + , randomAccessOptimized{false} + , boundToCoherent {false} + , vmaAllocator{allocator} + {} SHVkBuffer::SHVkBuffer( uint32_t inSize, @@ -266,6 +302,8 @@ namespace SHADE , boundToCoherent{ rhs.boundToCoherent} , vmaAllocator{ rhs.vmaAllocator } , bufferUsageFlags {rhs.bufferUsageFlags} + , bufferCreateInfo { rhs.bufferCreateInfo } + , allocCreateInfo { rhs.allocCreateInfo } { rhs.vkBuffer = VK_NULL_HANDLE; @@ -285,6 +323,8 @@ namespace SHADE boundToCoherent = rhs.boundToCoherent; vmaAllocator = std::move (rhs.vmaAllocator); rhs.vkBuffer = VK_NULL_HANDLE; + bufferCreateInfo = rhs.bufferCreateInfo; + allocCreateInfo = rhs.allocCreateInfo; bufferUsageFlags = rhs.bufferUsageFlags; return *this; @@ -344,47 +384,26 @@ namespace SHADE { sizeStored = inSize; - // For creation of buffer - vk::BufferCreateInfo bufferInfo{}; + // Set the buffer flags + bufferUsageFlags = bufferUsage; // initialize size and usage (vertex, index, uniform, etc) - bufferInfo.size = sizeStored; - bufferInfo.usage = bufferUsage; - bufferInfo.sharingMode = vk::SharingMode::eExclusive; + bufferCreateInfo = vk::BufferCreateInfo{}; + bufferCreateInfo.usage = bufferUsageFlags; + bufferCreateInfo.sharingMode = vk::SharingMode::eExclusive; // Prepare allocation parameters for call to create buffers later - VmaAllocationCreateInfo allocCreateInfo{}; + allocCreateInfo = VmaAllocationCreateInfo{}; allocCreateInfo.usage = memUsage; // If vma allocation flags include dedicated bit, immediately activate dst bit if (allocCreateInfo.flags & VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT) - bufferInfo.usage |= vk::BufferUsageFlagBits::eTransferDst; - + bufferCreateInfo.usage |= vk::BufferUsageFlagBits::eTransferDst; allocCreateInfo.flags = allocFlags; - // parameters of a vmaAllocation retrieved via vmaGetAllocationInfo - VmaAllocationInfo allocInfo; - - // To get around VMA's usage for C version of vulkan, create a temp first..., - VkBuffer tempBuffer{}; - - // Create the buffer... - auto result = vmaCreateBuffer(vmaAllocator, - &bufferInfo.operator VkBufferCreateInfo &(), - &allocCreateInfo, - &tempBuffer, &alloc, &allocInfo); - - if (result != VK_SUCCESS) - SHVulkanDebugUtil::ReportVkError(vk::Result (result), "Failed to create vulkan buffer. "); - else - SHVulkanDebugUtil::ReportVkSuccess("Successfully created buffer. "); - - // ...then assign it to the hpp version + auto [tempBuffer, allocInfo] = createBuffer(sizeStored); vkBuffer = tempBuffer; - // Set the buffer flags - bufferUsageFlags = bufferInfo.usage; - // This probably means that a HOST_CACHED memory type is used on allocation if (allocFlags & VMA_ALLOCATION_CREATE_HOST_ACCESS_RANDOM_BIT) randomAccessOptimized = true; @@ -456,7 +475,7 @@ namespace SHADE /***************************************************************************/ void SHVkBuffer::Destroy(void) noexcept { - vmaDestroyBuffer(vmaAllocator, vkBuffer, alloc); + if (vkBuffer) + vmaDestroyBuffer(vmaAllocator, vkBuffer, alloc); } - } diff --git a/SHADE_Engine/src/Graphics/Buffers/SHVkBuffer.h b/SHADE_Engine/src/Graphics/Buffers/SHVkBuffer.h index 9df1a1d0..7f4e0889 100644 --- a/SHADE_Engine/src/Graphics/Buffers/SHVkBuffer.h +++ b/SHADE_Engine/src/Graphics/Buffers/SHVkBuffer.h @@ -47,13 +47,18 @@ namespace SHADE //! buffer usage info flags vk::BufferUsageFlags bufferUsageFlags; + vk::BufferCreateInfo bufferCreateInfo; + VmaAllocationCreateInfo allocCreateInfo; + //! Reference to the allocator + //VmaAllocator const& vmaAllocator; std::reference_wrapper vmaAllocator; /*-----------------------------------------------------------------------*/ /* PRIVATE MEMBER FUNCTIONS */ /*-----------------------------------------------------------------------*/ void PrepStagingBuffer (void* data, uint32_t srcSize) noexcept; + std::pair createBuffer(uint32_t size); public: /*-----------------------------------------------------------------------*/ @@ -62,13 +67,13 @@ namespace SHADE SHVkBuffer (void) noexcept = delete; SHVkBuffer (std::reference_wrapper allocator) noexcept; SHVkBuffer ( - uint32_t inSize, + uint32_t inSize, void* data, uint32_t srcSize, std::reference_wrapper allocator, vk::BufferUsageFlags bufferUsage, - VmaMemoryUsage memUsage, - VmaAllocationCreateFlags allocFlags + VmaMemoryUsage memUsage = VMA_MEMORY_USAGE_AUTO, + VmaAllocationCreateFlags allocFlags = {} ) noexcept; SHVkBuffer(SHVkBuffer&& rhs) noexcept; SHVkBuffer& operator=(SHVkBuffer&& rhs) noexcept; @@ -78,21 +83,23 @@ namespace SHADE /*-----------------------------------------------------------------------*/ /* PUBLIC MEMBER VARIABLES */ /*-----------------------------------------------------------------------*/ - void Init ( - uint32_t inSize, - void* data, - uint32_t srcSize, - vk::BufferUsageFlags bufferUsage, - VmaMemoryUsage memUsage, - VmaAllocationCreateFlags allocFlags - ) noexcept; - void Destroy (void) noexcept; + void Init ( + uint32_t inSize, + void* data, + uint32_t srcSize, + vk::BufferUsageFlags bufferUsage, + VmaMemoryUsage memUsage, + VmaAllocationCreateFlags allocFlags + ) noexcept; + void Destroy (void) noexcept; - void Map (void) noexcept; - void Unmap (void) noexcept; - void WriteToMemory (void* data, uint32_t sizeToWrite, uint32_t srcOffset, uint32_t dstOffset) noexcept; - void MapWriteUnmap (void* data, uint32_t sizeToWrite, uint32_t srcOffset, uint32_t dstOffset) noexcept; + void Map (void) noexcept; + void Unmap (void) noexcept; + void WriteToMemory (void* data, uint32_t sizeToWrite, uint32_t srcOffset, uint32_t dstOffset) noexcept; + void MapWriteUnmap (void* data, uint32_t sizeToWrite, uint32_t srcOffset, uint32_t dstOffset) noexcept; void TransferToDeviceResource(Handle const& cmdBufferHdl) noexcept; + void ResizeNoCopy (uint32_t newSize); + void ResizeReplace (uint32_t newSize, void* data, uint32_t srcSize); /*-----------------------------------------------------------------------*/ /* SETTERS AND GETTERS */ diff --git a/SHADE_Engine/src/Graphics/Commands/SHVkCommandBuffer.cpp b/SHADE_Engine/src/Graphics/Commands/SHVkCommandBuffer.cpp index b0139f8e..b393971c 100644 --- a/SHADE_Engine/src/Graphics/Commands/SHVkCommandBuffer.cpp +++ b/SHADE_Engine/src/Graphics/Commands/SHVkCommandBuffer.cpp @@ -451,6 +451,33 @@ namespace SHADE // //vkCommandBuffer.pipelineBarrier() //} + /***************************************************************************/ + /*! + + \brief + Issues a multi indirect draw call. + + \param indirectDrawData + SHVkBuffer containing the data for the multi indirect draw call. + \param drawCount + Number of multi indirect draw sub-calls stored in indirectDrawData. + + */ + /***************************************************************************/ + + void SHVkCommandBuffer::DrawMultiIndirect(Handle indirectDrawData, uint32_t drawCount) + { + if (cmdBufferState != SH_CMD_BUFFER_STATE::RECORDING) + { + SHLOG_ERROR("Command buffer must have started recording before a pipeline can be bound."); + return; + } + + vkCommandBuffer.drawIndexedIndirect(indirectDrawData->GetVkBuffer(), 0, drawCount, sizeof(vk::DrawIndexedIndirectCommand)); + } + + + /***************************************************************************/ /*! diff --git a/SHADE_Engine/src/Graphics/Commands/SHVkCommandBuffer.h b/SHADE_Engine/src/Graphics/Commands/SHVkCommandBuffer.h index 888b805a..c478bddf 100644 --- a/SHADE_Engine/src/Graphics/Commands/SHVkCommandBuffer.h +++ b/SHADE_Engine/src/Graphics/Commands/SHVkCommandBuffer.h @@ -96,7 +96,7 @@ namespace SHADE /*-----------------------------------------------------------------------*/ void Reset(void); - // Begins, Ends and Nexts + // Begins and Ends void BeginRecording (void) noexcept; void EndRecording (void) noexcept; void BeginRenderpass (Handle const& renderpassHdl, Handle const& framebufferHdl, vk::Offset2D offset = {0, 0}, vk::Extent2D extent = {0, 0}) noexcept; @@ -127,6 +127,7 @@ namespace SHADE bool IsReadyToSubmit (void) const noexcept; void HandlePostSubmit (void) noexcept; + void DrawMultiIndirect (Handle indirectDrawData, uint32_t drawCount); // Push Constant variable setting template diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.cpp new file mode 100644 index 00000000..0a38e40b --- /dev/null +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.cpp @@ -0,0 +1,181 @@ +/************************************************************************************//*! +\file SHBatch.cpp +\author Tng Kah Wei, kahwei.tng, 390009620 +\par email: kahwei.tng\@digipen.edu +\date Aug 30, 2022 +\brief Contains the definition of SHBatch's functions. + + +Copyright (C) 2022 DigiPen Institute of Technology. +Reproduction or disclosure of this file or its contents without the prior written consent +of DigiPen Institute of Technology is prohibited. +*//*************************************************************************************/ +#include "SHpch.h" +#include "SHBatch.h" + +#include "Graphics/Commands/SHVkCommandBuffer.h" +#include "Graphics/MiddleEnd/Interface/SHRenderable.h" +#include "Graphics/MiddleEnd/Interface/SHMeshLibrary.h" +#include "Graphics/Devices/SHVkLogicalDevice.h" +#include "Graphics/SHVkUtil.h" +#include "Graphics/Pipeline/SHVkPipeline.h" +#include "Graphics/MiddleEnd/Interface/SHGraphicsConstants.h" +#include "Graphics/MiddleEnd/Interface/SHMaterialInstance.h" + +namespace SHADE +{ + /*---------------------------------------------------------------------------------*/ + /* SHBatch - Usage Functions */ + /*---------------------------------------------------------------------------------*/ + SHBatch::SHBatch(Handle pipeline) + : pipeline { pipeline } + { + if (!pipeline) + throw std::invalid_argument("Attempted to create a SHBatch with an invalid SHPipeline!"); + } + + void SHBatch::Add(Handle renderable) + { + // Check if we have a SubBatch with the same mesh yet + auto subBatch = std::find_if(subBatches.begin(), subBatches.end(), [&](const SHSubBatch& batch) + { + return batch.Mesh == renderable->Mesh; + }); + + // Create one if not found + if (subBatch == subBatches.end()) + { + subBatches.emplace_back(renderable->Mesh); + subBatch = subBatches.end() - 1; + } + + // Add renderable in + subBatch->Renderables.insert(renderable); + } + + void SHBatch::Remove(Handle renderable) + { + // Check if we have a SubBatch with the same mesh yet + auto subBatch = std::find_if(subBatches.begin(), subBatches.end(), [&](const SHSubBatch& batch) + { + return batch.Mesh == renderable->Mesh; + }); + + // Attempt to remove if it exists + if (subBatch == subBatches.end()) + return; + + subBatch->Renderables.erase(renderable); + } + + void SHBatch::Clear() + { + subBatches.clear(); + + // Clear CPU buffers + drawData.clear(); + transformData.clear(); + matPropsData.reset(); + matPropsDataSize = 0; + + + // Clear GPU buffers + drawDataBuffer.Free(); + transformDataBuffer.Free(); + matPropsBuffer.Free(); + } + + void SHBatch::Build(Handle device, Handle cmdBuffer) + { + // No need to build as there are no changes + if (!isDirty) + return; + + // Count number of elements + size_t numTotalElements = 0; + for (const auto& subBatch : subBatches) + { + numTotalElements += subBatch.Renderables.size(); + } + + // Generate CPU buffers + // - Draw data + drawData.reserve(subBatches.size()); + drawData.clear(); + // - Transform data + transformData.reserve(numTotalElements); + transformData.clear(); + // - Material Properties Data + const Byte SINGLE_MAT_PROPS_SIZE = pipeline->GetPipelineLayout()->GetShaderBlockInterface + ( + SHGraphicsConstants::DescriptorSetIndex::PER_INSTANCE, + SHGraphicsConstants::DescriptorSetBindings::BATCHED_PER_INST_DATA, + vk::ShaderStageFlagBits::eFragment + )->GetBytesRequired(); + const Byte MATPROPS_TOTAL_BYTES = drawData.size() * SINGLE_MAT_PROPS_SIZE; + if (matPropsDataSize < MATPROPS_TOTAL_BYTES) + { + matPropsData.reset(new char[MATPROPS_TOTAL_BYTES]); + matPropsDataSize = MATPROPS_TOTAL_BYTES; + } + + // Build Sub Batches + uint32_t nextInstanceIndex = 0; + char* propsCurrPtr = matPropsData.get(); + for (auto& subBatch : subBatches) + { + // Create command + drawData.emplace_back(vk::DrawIndexedIndirectCommand + { + .indexCount = subBatch.Mesh->IndexCount, + .instanceCount = static_cast(subBatch.Renderables.size()), + .firstIndex = subBatch.Mesh->FirstIndex, + .vertexOffset = subBatch.Mesh->FirstVertex, + .firstInstance = nextInstanceIndex + }); + + // Fill in buffers (CPU) + for (Handle renderable : subBatch.Renderables) + { + // Transform + transformData.emplace_back(renderable->TransformMatrix); + // Material Properties + renderable->GetMaterial()->ExportProperties(propsCurrPtr); + propsCurrPtr += SINGLE_MAT_PROPS_SIZE; + } + } + + // Send all buffered data to the GPU buffers + using BuffUsage = vk::BufferUsageFlagBits; + // - Draw Data + const uint32_t DRAW_DATA_BYTES = static_cast(drawData.size() * sizeof(vk::DrawIndexedIndirectCommand)); + SHVkUtil::EnsureBufferAndCopyData + ( + device, cmdBuffer, drawDataBuffer, drawData.data(), DRAW_DATA_BYTES, + BuffUsage::eIndirectBuffer + ); + // - Transform Buffer + const uint32_t TF_DATA_BYTES = static_cast(transformData.size() * sizeof(SHMatrix)); + SHVkUtil::EnsureBufferAndCopyData + ( + device, cmdBuffer, transformDataBuffer, transformData.data(), TF_DATA_BYTES, + BuffUsage::eVertexBuffer + ); + // - Material Properties Buffer + SHVkUtil::EnsureBufferAndCopyData + ( + device, cmdBuffer, matPropsBuffer, matPropsData.get(), static_cast(MATPROPS_TOTAL_BYTES), + BuffUsage::eStorageBuffer + ); + + isDirty = false; + } + + /*---------------------------------------------------------------------------------*/ + /* SHBatch - Usage Functions */ + /*---------------------------------------------------------------------------------*/ + void SHBatch::Draw(Handle cmdBuffer) + { + cmdBuffer->DrawMultiIndirect(drawDataBuffer, static_cast(drawData.size())); + } +} diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.h b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.h new file mode 100644 index 00000000..e87c16ef --- /dev/null +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.h @@ -0,0 +1,101 @@ +/************************************************************************************//*! +\file SHBatch.h +\author Tng Kah Wei, kahwei.tng, 390009620 +\par email: kahwei.tng\@digipen.edu +\date Aug 30, 2022 +\brief Contains the definition of SHSubBatch and SHBatch. + + +Copyright (C) 2022 DigiPen Institute of Technology. +Reproduction or disclosure of this file or its contents without the prior written consent +of DigiPen Institute of Technology is prohibited. +*//*************************************************************************************/ +#pragma once + +// STL Includes +#include +// External Dependencies +#include "Graphics/SHVulkanIncludes.h" +// Project Includes +#include "Resource/Handle.h" +#include "Graphics/MiddleEnd/Interface/SHMaterial.h" +#include "Math/SHMatrix.h" + +namespace SHADE +{ + /*---------------------------------------------------------------------------------*/ + /* Forward Declarations */ + /*---------------------------------------------------------------------------------*/ + class SHVkBuffer; + class SHVkCommandBuffer; + class SHVkPipeline; + class SHMesh; + class SHRenderable; + class SHVkLogicalDevice; + + /*---------------------------------------------------------------------------------*/ + /* Type Definitions */ + /*---------------------------------------------------------------------------------*/ + /***********************************************************************************/ + /*! + \brief + Describes a segment of the sub batch operation. + */ + /***********************************************************************************/ + struct SHSubBatch + { + public: + /*-----------------------------------------------------------------------------*/ + /* Data Members */ + /*-----------------------------------------------------------------------------*/ + Handle Mesh; + std::unordered_set> Renderables; + }; + /***********************************************************************************/ + /*! + \brief + Describes a segment of the sub batch operation. + */ + /***********************************************************************************/ + class SHBatch + { + public: + /*-----------------------------------------------------------------------------*/ + /* Constructor/Destructors */ + /*-----------------------------------------------------------------------------*/ + SHBatch(Handle pipeline); + + /*-----------------------------------------------------------------------------*/ + /* Usage Functions */ + /*-----------------------------------------------------------------------------*/ + void Add(Handle renderable); + void Remove(Handle renderable); + void Clear(); + void Build(Handle device, Handle cmdBuffer); + void Draw(Handle cmdBuffer); + + /*-----------------------------------------------------------------------------*/ + /* Getter Functions */ + /*-----------------------------------------------------------------------------*/ + Handle GetPipeline() const noexcept { return pipeline; }; + + private: + /*-----------------------------------------------------------------------------*/ + /* Data Members */ + /*-----------------------------------------------------------------------------*/ + // Batch Properties + Handle pipeline; + // Batch Tree + std::vector subBatches; + bool isDirty = true; + // CPU Buffers + std::vector drawData; + std::vector transformData; + std::unique_ptr matPropsData; + Byte matPropsDataSize = 0; + // GPU Buffers + Handle drawDataBuffer; + Handle transformDataBuffer; + Handle matPropsBuffer; + }; +} diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatcher.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatcher.cpp new file mode 100644 index 00000000..ced97876 --- /dev/null +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatcher.cpp @@ -0,0 +1,107 @@ +/************************************************************************************//*! +\file SHBatcher.cpp +\author Tng Kah Wei, kahwei.tng, 390009620 +\par email: kahwei.tng\@digipen.edu +\date Aug 30, 2022 +\brief + + +Copyright (C) 2022 DigiPen Institute of Technology. +Reproduction or disclosure of this file or its contents without the prior written consent +of DigiPen Institute of Technology is prohibited. +*//*************************************************************************************/ +#include "SHpch.h" +#include "SHBatcher.h" +// STL Includes +#include +// Project Includes +#include "SHSuperBatch.h" +#include "Graphics/MiddleEnd/Interface/SHRenderable.h" +#include "Graphics/Devices/SHVkLogicalDevice.h" +#include "Graphics/Commands/SHVkCommandBuffer.h" +#include "Graphics/MiddleEnd/Interface/SHMaterialInstance.h" +#include "Graphics/Pipeline/SHVkPipeline.h" + +namespace SHADE +{ + /*---------------------------------------------------------------------------------*/ + /* Lifecycle Functions */ + /*---------------------------------------------------------------------------------*/ + void SHBatcher::Init(const std::vector& _renderables, Handle _renderGraph) + { + renderables = &_renderables; + renderGraph = _renderGraph; + } + + /*---------------------------------------------------------------------------------*/ + /* Usage Functions */ + /*---------------------------------------------------------------------------------*/ + void SHBatcher::PrepareBatches() + { + // Iterate through all renderables and send it into the batching + for (auto iter = renderables->cbegin(); iter != renderables->cend(); ++iter) + { + AddToBatch(iter->GetHandle()); + } + } + + void SHBatcher::AddToBatch(Handle renderable) + { + // Get Subpass Index for this renderables pipeline + const SHSubPassIndex SUB_PASS_IDX = renderable->GetMaterial()->GetBaseMaterial()->GetPipeline()->GetPipelineState().GetSubpassIndex(); + + + // Check if there is a SuperBatch for the specific RenderPass + auto superBatch = std::find_if(superBatches.begin(), superBatches.end(), [&](const SHSuperBatch& superBatch) + { + return superBatch.GetSubpassId() == SUB_PASS_IDX; + }); + + // Create if it doesn't exist + if (superBatch == superBatches.end()) + { + superBatches.emplace_back(SUB_PASS_IDX); + superBatch = superBatches.end(); + } + + // Add the Renderable + superBatch->Add(renderable->GetHandle()); + } + + void SHBatcher::RemoveFromBatch(Handle renderable) + { + // Get Subpass Index for this renderables pipeline + const SHSubPassIndex SUB_PASS_IDX = renderable->GetMaterial()->GetBaseMaterial()->GetPipeline()->GetPipelineState().GetSubpassIndex(); + + // Check if there is a SuperBatch for the specific RenderPass + auto superBatch = std::find_if(superBatches.begin(), superBatches.end(), [&](const SHSuperBatch& superBatch) + { + return superBatch.GetSubpassId() == SUB_PASS_IDX; + }); + + // Remove if it exists + if (superBatch == superBatches.end()) + return; + + superBatch->Remove(renderable); + } + + void SHBatcher::FinaliseBatches(Handle device, Handle cmdBuffer) + { + // Build SuperBatches + for (auto& batch : superBatches) + { + batch.Build(device, cmdBuffer); + } + } + + void SHBatcher::ClearBatches() + { + for (auto& batch : superBatches) + { + batch.Clear(); + } + superBatches.clear(); + } + +} diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatcher.h b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatcher.h new file mode 100644 index 00000000..ccbbd1d0 --- /dev/null +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatcher.h @@ -0,0 +1,63 @@ +/************************************************************************************//*! +\file SHBatcher.h +\author Tng Kah Wei, kahwei.tng, 390009620 +\par email: kahwei.tng\@digipen.edu +\date Aug 30, 2022 +\brief + + +Copyright (C) 2022 DigiPen Institute of Technology. +Reproduction or disclosure of this file or its contents without the prior written consent +of DigiPen Institute of Technology is prohibited. +*//*************************************************************************************/ +#pragma once + +// STL Includes +#include +// Project Includes +#include "Resource/Handle.h" + +namespace SHADE +{ + /*---------------------------------------------------------------------------------*/ + /* Forward Declarations */ + /*---------------------------------------------------------------------------------*/ + class SHRenderable; + class SHRenderGraph; + class SHSuperBatch; + class SHVkLogicalDevice; + class SHVkCommandBuffer; + + /*---------------------------------------------------------------------------------*/ + /* Type Definitions */ + /*---------------------------------------------------------------------------------*/ + /***********************************************************************************/ + /*! + \brief + Handles batching of all Renderables assigned to a specific Renderer. + */ + /***********************************************************************************/ + class SHBatcher + { + public: + /*-----------------------------------------------------------------------------*/ + /* Lifecycle Functions */ + /*-----------------------------------------------------------------------------*/ + void Init(const std::vector& _renderables, Handle _renderGraph); + + /*-----------------------------------------------------------------------------*/ + /* Usage Functions */ + /*-----------------------------------------------------------------------------*/ + void PrepareBatches(); + void AddToBatch(Handle renderable); + void RemoveFromBatch(Handle renderable); + void FinaliseBatches(Handle device, Handle cmdBuffer); + void ClearBatches(); + + private: + const std::vector* renderables = nullptr; + Handle renderGraph; + // Children + std::vector superBatches; + }; +} \ No newline at end of file diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHSuperBatch.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHSuperBatch.cpp new file mode 100644 index 00000000..6ca498f3 --- /dev/null +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHSuperBatch.cpp @@ -0,0 +1,99 @@ +/************************************************************************************//*! +\file SHSuperBatch.cpp +\author Tng Kah Wei, kahwei.tng, 390009620 +\par email: kahwei.tng\@digipen.edu +\date Sep 8, 2022 +\brief Contains the definition of SHSuperBatch's functions. + + +Copyright (C) 2022 DigiPen Institute of Technology. +Reproduction or disclosure of this file or its contents without the prior written consent +of DigiPen Institute of Technology is prohibited. +*//*************************************************************************************/ +#include "SHpch.h" +#include "SHSuperBatch.h" + +#include "SHBatch.h" +#include "Graphics/MiddleEnd/Interface/SHMaterialInstance.h" +#include "Graphics/MiddleEnd/Interface/SHRenderable.h" + +namespace SHADE +{ + /*---------------------------------------------------------------------------------*/ + /* Constructor/Destructors */ + /*---------------------------------------------------------------------------------*/ + + SHSuperBatch::SHSuperBatch(SHSubPassIndex subPass) + : subpassIndex { subPass } + {} + + /*---------------------------------------------------------------------------------*/ + /* Usage Functions */ + /*---------------------------------------------------------------------------------*/ + void SHSuperBatch::Add(Handle renderable) noexcept + { + const Handle PIPELINE = renderable->GetMaterial()->GetBaseMaterial()->GetPipeline(); + + // Check if we have a batch with the same pipeline first + auto batch = std::find_if(batches.begin(), batches.end(), [&](const SHBatch& batch) + { + return batch.GetPipeline() == PIPELINE; + }); + + + // Create one if not found + if (batch == batches.end()) + { + batches.emplace_back(PIPELINE); + batch = batches.end() - 1; + } + + // Add renderable in + batch->Add(renderable); + } + + void SHSuperBatch::Remove(Handle renderable) noexcept + { + const Handle PIPELINE = renderable->GetMaterial()->GetBaseMaterial()->GetPipeline(); + + // Check if we have a Batch with the same pipeline yet + auto batch = std::find_if(batches.begin(), batches.end(), [&](const SHBatch& batch) + { + return batch.GetPipeline() == PIPELINE; + }); + + // Attempt to remove if it exists + if (batch == batches.end()) + return; + + batch->Remove(renderable); + } + + void SHSuperBatch::Clear() noexcept + { + for (auto& batch : batches) + { + batch.Clear(); + } + batches.clear(); + } + + void SHSuperBatch::Build(Handle device, Handle cmdBuffer) noexcept + { + // Build all batches + for (auto& batch : batches) + { + batch.Build(device, cmdBuffer); + } + } + + void SHSuperBatch::Draw(Handle cmdBuffer) noexcept + { + // Build all batches + for (auto& batch : batches) + { + batch.Draw(cmdBuffer); + } + } + +} diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHSuperBatch.h b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHSuperBatch.h new file mode 100644 index 00000000..55f23dbb --- /dev/null +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHSuperBatch.h @@ -0,0 +1,76 @@ +/************************************************************************************//*! +\file SHSuperBatch.h +\author Tng Kah Wei, kahwei.tng, 390009620 +\par email: kahwei.tng\@digipen.edu +\date Sep 8, 2022 +\brief Contains the definition of SHSuperBatch. + + +Copyright (C) 2022 DigiPen Institute of Technology. +Reproduction or disclosure of this file or its contents without the prior written consent +of DigiPen Institute of Technology is prohibited. +*//*************************************************************************************/ +#pragma once + +// External Dependencies +#include "Graphics/SHVulkanIncludes.h" +// Project Includes +#include "Resource/Handle.h" +#include "SHBatch.h" +#include "Graphics/Pipeline/SHVkPipeline.h" + +namespace SHADE +{ + /*---------------------------------------------------------------------------------*/ + /* Forward Declarations */ + /*---------------------------------------------------------------------------------*/ + class SHVkBuffer; + class SHVkCommandBuffer; + class SHMesh; + class SHRenderable; + class SHVkLogicalDevice; + class SHSubpass; + + /*---------------------------------------------------------------------------------*/ + /* Type Definitions */ + /*---------------------------------------------------------------------------------*/ + /***********************************************************************************/ + /*! + \brief + Stores and manages data for all of the batches associated with a specific SubPass + within a RenderGraph. + */ + /***********************************************************************************/ + class SHSuperBatch + { + public: + /*-----------------------------------------------------------------------------*/ + /* Constructor/Destructors */ + /*-----------------------------------------------------------------------------*/ + SHSuperBatch(SHSubPassIndex subPass); + + /*-----------------------------------------------------------------------------*/ + /* Usage Functions */ + /*-----------------------------------------------------------------------------*/ + void Add(Handle renderable) noexcept; + void Remove(Handle renderable) noexcept; + void Clear() noexcept; + void Build(Handle device, Handle cmdBuffer) noexcept; + void Draw(Handle cmdBuffer) noexcept; + + /*-----------------------------------------------------------------------------*/ + /* Getter Functions */ + /*-----------------------------------------------------------------------------*/ + SHSubPassIndex GetSubpassId() const noexcept { return subpassIndex; }; + + private: + /*-----------------------------------------------------------------------------*/ + /* Data Members */ + /*-----------------------------------------------------------------------------*/ + // Batch Properties + SHSubPassIndex subpassIndex; + // Children + std::vector batches; + }; +} + diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHCamera.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHCamera.cpp index 2f8fb9ea..7e7412b9 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHCamera.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHCamera.cpp @@ -21,23 +21,23 @@ namespace SHADE /*---------------------------------------------------------------------------------*/ void SHCamera::SetLookAt(const SHVec3& pos, const SHVec3& target, const SHVec3& up) { - const SHVec3 VIEW = (target - pos).Normalized(); - const SHVec3 RIGHT = SHVec3::Cross(VIEW, up).Normalized(); - const SHVec3 UP = SHVec3::Cross(RIGHT, VIEW); + SHVec3 view = target - pos; view = SHVec3::Normalise(view); + SHVec3 right = SHVec3::Cross(view, up); right = SHVec3::Normalise(right); + const SHVec3 UP = SHVec3::Cross(right, view); viewMatrix = SHMatrix::Identity; - viewMatrix(0, 0) = RIGHT[0]; - viewMatrix(1, 0) = RIGHT[1]; - viewMatrix(2, 0) = RIGHT[2]; + viewMatrix(0, 0) = right[0]; + viewMatrix(1, 0) = right[1]; + viewMatrix(2, 0) = right[2]; viewMatrix(0, 1) = UP[0]; viewMatrix(1, 1) = UP[1]; viewMatrix(2, 1) = UP[2]; - viewMatrix(0, 2) = -VIEW[0]; - viewMatrix(1, 2) = -VIEW[1]; - viewMatrix(2, 2) = -VIEW[2]; - viewMatrix(3, 0) = -RIGHT.Dot(pos); + viewMatrix(0, 2) = -view[0]; + viewMatrix(1, 2) = -view[1]; + viewMatrix(2, 2) = -view[2]; + viewMatrix(3, 0) = -right.Dot(pos); viewMatrix(3, 1) = -UP.Dot(pos); - viewMatrix(3, 2) = VIEW.Dot(pos); + viewMatrix(3, 2) = view.Dot(pos); isDirty = true; } @@ -79,32 +79,32 @@ namespace SHADE /*---------------------------------------------------------------------------------*/ /* Getter Functions */ /*---------------------------------------------------------------------------------*/ - SHMathMat4f SHCamera::GetViewMatrix() const + SHMatrix SHCamera::GetViewMatrix() const { return viewMatrix; } - SHMathMat4f SHCamera::GetProjectionMatrix() const + SHMatrix SHCamera::GetProjectionMatrix() const { return projMatrix; } - SHMathMat4f SHCamera::GetViewProjectionMatrix() + SHMatrix SHCamera::GetViewProjectionMatrix() { updateMatrices(); return vpMatrix; } - SHMathMat4f SHCamera::GetInverseViewMatrix() const + SHMatrix SHCamera::GetInverseViewMatrix() const { return inverseVpMatrix; } - SHMathMat4f SHCamera::GetInverseProjectionMatrix() const + SHMatrix SHCamera::GetInverseProjectionMatrix() const { return inverseProjMatrix; } - SHMathMat4f SHCamera::GetInverseViewProjectionMatrix() + SHMatrix SHCamera::GetInverseViewProjectionMatrix() { updateMatrices(); return inverseViewMatrix; @@ -138,11 +138,11 @@ namespace SHADE if (isDirty) { vpMatrix = viewMatrix * projMatrix; - inverseVpMatrix = vpMatrix; - inverseVpMatrix.Inverse(); + inverseVpMatrix = SHMatrix::Inverse(vpMatrix); } } - SHVec3 SHCamera::multiplyHomogenous(const SHMathMat4f& mat, const SHVec3& vec) + + SHVec3 SHCamera::multiplyHomogenous(const SHMatrix& mat, const SHVec3& vec) { const SHVec4 HOMO_VEC = { vec[0], vec[1], vec[2], 1.0f }; const SHVec4 RESULT = mat * HOMO_VEC; diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHCamera.h b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHCamera.h index fa6e31b5..c54f29ed 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHCamera.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHCamera.h @@ -75,6 +75,6 @@ namespace SHADE /* Helper Functions */ /*-----------------------------------------------------------------------------*/ void updateMatrices(); - static SHVec3 multiplyHomogenous(const SHMatrix& mat, const SHMatrix& vec); + static SHVec3 multiplyHomogenous(const SHMatrix& mat, const SHVec3& vec); }; } \ No newline at end of file diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.h b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.h index 4f20afd4..7dcf12c0 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.h @@ -46,6 +46,8 @@ namespace SHADE class SHViewport; class SHCamera; class SHVkShaderModule; + class SHMaterial; + class SHMaterialInstance; /*---------------------------------------------------------------------------------*/ /* Type Definitions */ diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMaterialInstance.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMaterialInstance.cpp index 5f697208..8b0778d2 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMaterialInstance.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMaterialInstance.cpp @@ -11,6 +11,10 @@ of DigiPen Institute of Technology is prohibited. *//*************************************************************************************/ #include "SHpch.h" #include "SHMaterialInstance.h" + +#include "SHGraphicsConstants.h" +#include "SHMaterial.h" +#include "Graphics/Pipeline/SHVkPipeline.h" #include "Tools/SHLogger.h" namespace SHADE @@ -39,7 +43,7 @@ namespace SHADE assert(dataStore != nullptr); if (!baseMaterial) - throw std::runtime_error("[SHMaterialInstance] Attempted to set export a Material Instance with no base Material!"); + throw std::runtime_error("[SHMaterialInstance] Attempted to set export a Material Instance with no base Material!"); // Copy default data from Material baseMaterial->ExportProperties(dest); @@ -49,14 +53,27 @@ namespace SHADE for (const auto& data : overrideData) { // Get memory offset to the data - SHShaderBlockInterface::Variable variable = SHADER_INFO->GetVariable(data.Index); + const SHShaderBlockInterface::Variable* variable = SHADER_INFO->GetVariable(data.Index); if (variable == nullptr) { SHLOG_WARNING("[SHMaterialInstance] Invalid override data indices provided. Skipping."); continue; } const auto DATA_OFFSET = variable->offset; - memcpy_s(dest + DATA_OFFSET, dataStore.get() + data.StoredDataOffset, data.DataSize); + memcpy(static_cast(dest) + DATA_OFFSET, dataStore.get() + data.StoredDataOffset, data.DataSize); } } + + /*---------------------------------------------------------------------------------*/ + /* Helper Functions */ + /*---------------------------------------------------------------------------------*/ + Handle SHMaterialInstance::getShaderBlockInterface() const noexcept + { + return baseMaterial->GetPipeline()->GetPipelineLayout()->GetShaderBlockInterface + ( + SHGraphicsConstants::DescriptorSetIndex::PER_INSTANCE, + SHGraphicsConstants::DescriptorSetBindings::BATCHED_PER_INST_DATA, + vk::ShaderStageFlagBits::eFragment + ); + } } \ No newline at end of file diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMaterialInstance.h b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMaterialInstance.h index d2b222e6..db0201b7 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMaterialInstance.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMaterialInstance.h @@ -14,6 +14,7 @@ of DigiPen Institute of Technology is prohibited. #include // Project Includes #include "Resource/Handle.h" +#include "Graphics/Shaders/BlockInterface/SHShaderBlockInterface.h" namespace SHADE { @@ -76,6 +77,11 @@ namespace SHADE std::vector overrideData; std::unique_ptr dataStore; size_t dataStoreSize = 0; + + /*-----------------------------------------------------------------------------*/ + /* Helper Functions */ + /*-----------------------------------------------------------------------------*/ + Handle getShaderBlockInterface() const noexcept; }; } diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMaterialInstance.hpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMaterialInstance.hpp index 9980dfae..0aead306 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMaterialInstance.hpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMaterialInstance.hpp @@ -30,12 +30,12 @@ namespace SHADE // Allocate data store if it was empty if (dataStore == nullptr) { - dataStoreSize = SHADER_INFO->GetBytesRequired();dataStoreSize + dataStoreSize = SHADER_INFO->GetBytesRequired(); dataStore.reset(new char[dataStoreSize]); } OverrideData od; - od.Index = SHADER_INFO.GetVariableIndex(key); + od.Index = SHADER_INFO->GetVariableIndex(key); od.DataSize = sizeof(T); if (overrideData.empty()) { @@ -65,7 +65,7 @@ namespace SHADE } // Search Override Data for the property - uint32_t PROP_IDX = SHADER_INFO.GetVariableIndex(key); + uint32_t PROP_IDX = SHADER_INFO->GetVariableIndex(key); auto prop = std::find(overrideData.begin(), overrideData.end(), [&](const OverrideData& data) { return PROP_IDX == data.Index; diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMeshLibrary.h b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMeshLibrary.h index f8a89687..ffebb74d 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMeshLibrary.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMeshLibrary.h @@ -17,7 +17,7 @@ of DigiPen Institute of Technology is prohibited. // Project Includes #include "Resource/Handle.h" #include "Resource/ResourceLibrary.h" -#include "SHVertex.h" +#include "Math/SHMath.h" namespace SHADE { @@ -44,10 +44,10 @@ namespace SHADE /* Type Definitions */ /*-----------------------------------------------------------------------------*/ using Index = uint32_t; - using VertexPosition = SHMathVec3f; - using VertexTexCoord = SHMathVec2f; - using VertexTangent = SHMathVec3f; - using VertexNormal = SHMathVec3f; + using VertexPosition = SHVec3; + using VertexTexCoord = SHVec2; + using VertexTangent = SHVec3; + using VertexNormal = SHVec3; /*-----------------------------------------------------------------------------*/ /* Data Members */ diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderable.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderable.cpp index 41a8d8d0..eb59ee14 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderable.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderable.cpp @@ -13,6 +13,8 @@ of DigiPen Institute of Technology is prohibited. #include "SHRenderable.h" #include "ECS_Base/Managers/SHSystemManager.h" +#include "SHGraphicsSystem.h" +#include "SHMaterialInstance.h" namespace SHADE { @@ -46,4 +48,4 @@ namespace SHADE return material; } -} \ No newline at end of file +} diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderer.h b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderer.h index 000fec4f..7bc143e6 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderer.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderer.h @@ -18,7 +18,6 @@ of DigiPen Institute of Technology is prohibited. // Project Includes #include "SHCamera.h" #include "Resource/Handle.h" -#include "SHGraphicsConstants.h" #include "Graphics/RenderGraph/SHRenderGraph.h" namespace SHADE @@ -76,6 +75,6 @@ namespace SHADE /* Data Members */ /*-----------------------------------------------------------------------------*/ Handle camera; - Handle renderGraph; + Handle renderGraph; }; } diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHViewport.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHViewport.cpp index 47f9ec5a..565ee04f 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHViewport.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHViewport.cpp @@ -17,6 +17,7 @@ of DigiPen Institute of Technology is prohibited. #include "Graphics/Instance/SHVkInstance.h" #include "Tools/SHLogger.h" #include "SHRenderer.h" +#include "Resource/ResourceLibrary.h" namespace SHADE { diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHViewport.h b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHViewport.h index 01637db3..e970e32c 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHViewport.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHViewport.h @@ -28,6 +28,7 @@ namespace SHADE class SHVkCommandBuffer; class SHVkLogicalDevice; class SHVkImageView; + class ResourceManager; /*---------------------------------------------------------------------------------*/ /* Type Definitions */ diff --git a/SHADE_Engine/src/Graphics/Pipeline/SHPipelineState.cpp b/SHADE_Engine/src/Graphics/Pipeline/SHPipelineState.cpp index 6094958e..0b4f033f 100644 --- a/SHADE_Engine/src/Graphics/Pipeline/SHPipelineState.cpp +++ b/SHADE_Engine/src/Graphics/Pipeline/SHPipelineState.cpp @@ -107,7 +107,7 @@ namespace SHADE return renderpassHdl; } - uint32_t SHVkPipelineState::GetSubpassIndex(void) const noexcept + SHSubPassIndex SHVkPipelineState::GetSubpassIndex(void) const noexcept { return subpassIndex; } diff --git a/SHADE_Engine/src/Graphics/Pipeline/SHPipelineState.h b/SHADE_Engine/src/Graphics/Pipeline/SHPipelineState.h index e692163b..08c35060 100644 --- a/SHADE_Engine/src/Graphics/Pipeline/SHPipelineState.h +++ b/SHADE_Engine/src/Graphics/Pipeline/SHPipelineState.h @@ -208,7 +208,7 @@ namespace SHADE SHDepthStencilState const& GetDepthStencilState (void) const noexcept; SHColorBlendState const& GetColorBlenState (void) const noexcept; Handle const& GetRenderpass (void) const noexcept; - uint32_t GetSubpassIndex (void) const noexcept; + SHSubPassIndex GetSubpassIndex (void) const noexcept; void SetDirty(bool isDirty) noexcept; }; diff --git a/SHADE_Engine/src/Graphics/Renderpass/SHVkRenderpass.h b/SHADE_Engine/src/Graphics/Renderpass/SHVkRenderpass.h index b0ae7445..afed0736 100644 --- a/SHADE_Engine/src/Graphics/Renderpass/SHVkRenderpass.h +++ b/SHADE_Engine/src/Graphics/Renderpass/SHVkRenderpass.h @@ -10,6 +10,10 @@ namespace SHADE { class SHVkLogicalDevice; class SHVkFramebuffer; + /*-----------------------------------------------------------------------*/ + /* TYPE DEFINTIIONS */ + /*-----------------------------------------------------------------------*/ + using SHSubPassIndex = uint32_t; class SHVkRenderpass { diff --git a/SHADE_Engine/src/Graphics/SHVkUtil.cpp b/SHADE_Engine/src/Graphics/SHVkUtil.cpp index 2fa03fbf..0c6af0d9 100644 --- a/SHADE_Engine/src/Graphics/SHVkUtil.cpp +++ b/SHADE_Engine/src/Graphics/SHVkUtil.cpp @@ -1,6 +1,10 @@ #include "SHPch.h" #include "SHVkUtil.h" +#include "Graphics/Buffers/SHVkBuffer.h" +#include "Graphics/Commands/SHVkCommandBuffer.h" +#include "Graphics/Devices/SHVkLogicalDevice.h" + namespace SHADE { @@ -19,4 +23,29 @@ namespace SHADE IsDepthOnlyFormat(format); } + void SHVkUtil::EnsureBufferAndCopyData(Handle device, Handle cmdBuffer, Handle& bufferHandle, void* src, uint32_t size, vk::BufferUsageFlagBits usage) + { + if (bufferHandle) + { + // Resize + bufferHandle->ResizeReplace(size, src, size); + } + else + { + // Create new + using BuffUsage = vk::BufferUsageFlagBits; + bufferHandle = device->CreateBuffer + ( + size, + src, + size, + usage | BuffUsage::eTransferDst, + VmaMemoryUsage::VMA_MEMORY_USAGE_AUTO, + VmaAllocationCreateFlagBits::VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT + ); + } + + // Order transfers + bufferHandle->TransferToDeviceResource(cmdBuffer); + } } diff --git a/SHADE_Engine/src/Graphics/SHVkUtil.h b/SHADE_Engine/src/Graphics/SHVkUtil.h index 4513f59c..fdbb9dee 100644 --- a/SHADE_Engine/src/Graphics/SHVkUtil.h +++ b/SHADE_Engine/src/Graphics/SHVkUtil.h @@ -3,13 +3,53 @@ #include "SHVulkanIncludes.h" +#include "Resource/Handle.h" + namespace SHADE { + /*---------------------------------------------------------------------------------*/ + /* Forward Declarations */ + /*---------------------------------------------------------------------------------*/ + class SHVkLogicalDevice; + class SHVkCommandBuffer; + class SHVkBuffer; + + /*---------------------------------------------------------------------------------*/ + /* Type Definitions */ + /*---------------------------------------------------------------------------------*/ class SHVkUtil { public: static bool IsDepthOnlyFormat (vk::Format format) noexcept; static bool IsDepthStencilAttachment(vk::Format format) noexcept; + /***********************************************************************************/ + /*! + + \brief + Ensures that the specified bufferHandle contains a buffer that fits the specified + size and creates it if it does not exist. This follows by issuing a transfer + command into the created buffer. + + All created buffers will use VMA_MEMORY_USAGE_AUTO and + VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT. + + \param device + Device used to create the SHVkBuffer. + \param cmdBuffer + CommandBuffer which commands for issuing transferring the data to the GPU. + \param bufferHandle + Reference to the handle that holds any existing buffer or will be used to hold the + created buffer. + \param src + Data to copy from. + \param size + Size of data to copy. + \param usage + Usage flags for the buffer. + + */ + /***********************************************************************************/ + static void EnsureBufferAndCopyData(Handle device, Handle cmdBuffer, Handle& bufferHandle, void* src, uint32_t size, vk::BufferUsageFlagBits usage); }; } diff --git a/SHADE_Engine/src/Graphics/Shaders/BlockInterface/SHShaderBlockInterface.cpp b/SHADE_Engine/src/Graphics/Shaders/BlockInterface/SHShaderBlockInterface.cpp index cfa26e4c..7ed50c59 100644 --- a/SHADE_Engine/src/Graphics/Shaders/BlockInterface/SHShaderBlockInterface.cpp +++ b/SHADE_Engine/src/Graphics/Shaders/BlockInterface/SHShaderBlockInterface.cpp @@ -1,5 +1,6 @@ #include "SHPch.h" #include "SHShaderBlockInterface.h" +#include "Tools/SHLogger.h" namespace SHADE { @@ -12,14 +13,14 @@ namespace SHADE SHLOG_WARNING("[SHShaderBlockInterface] Attempted to specify a variable with a duplicate name. This will be ignored."); return; } - variableIndexing.emplace_back(std::move(newVariable)); - variables.try_emplace (std::move(name), static_cast(variableIndexing.size() - 1)); + variables.emplace_back(std::move(newVariable)); + variableIndexing.try_emplace(std::move(name), static_cast(variables.size() - 1)); } SHShaderBlockInterface::Variable const* const SHShaderBlockInterface::GetVariable(std::string const& variableName) const noexcept { if (variableIndexing.contains(variableName)) - return &variables.at(variableIndexing.at(variableName).second); + return &variables.at(variableIndexing.at(variableName)); return nullptr; } @@ -32,12 +33,12 @@ namespace SHADE return nullptr; } - uint32_t SHShaderBlockInterface::GetVariableIndex(std::string const& variableName) const noexcept + uint32_t SHShaderBlockInterface::GetVariableIndex(std::string const& variableName) const { if (!variableIndexing.contains(variableName)) throw std::invalid_argument("Attempted to retrieve index to variable that does not exist!"); - return variableIndexing.at(variableName).second; + return variableIndexing.at(variableName); } SHShaderBlockInterface::SHShaderBlockInterface(void) noexcept @@ -47,7 +48,7 @@ namespace SHADE SHShaderBlockInterface::SHShaderBlockInterface(SHShaderBlockInterface&& rhs) noexcept : variables { std::move(rhs.variables) } , variableIndexing { std::move(rhs.variableIndexing) } - , bytesRequired { std::move (rhs.bytesRequired) } + , bytesRequired { rhs.bytesRequired } {} void SHShaderBlockInterface::SetBytesRequired(uint32_t bytes) noexcept @@ -68,7 +69,7 @@ namespace SHADE variables = std::move(rhs.variables); variableIndexing = std::move(rhs.variableIndexing); - bytesRequired = std::move(rhs.bytesRequired); + bytesRequired = rhs.bytesRequired; return *this; } diff --git a/SHADE_Engine/src/Resource/Handle.h b/SHADE_Engine/src/Resource/Handle.h index afaec8e1..c56e29bd 100644 --- a/SHADE_Engine/src/Resource/Handle.h +++ b/SHADE_Engine/src/Resource/Handle.h @@ -10,7 +10,7 @@ namespace SHADE /*---------------------------------------------------------------------------------*/ template class ResourceLibrary; - + /*---------------------------------------------------------------------------------*/ /* Type Definitions */ /*---------------------------------------------------------------------------------*/ @@ -89,7 +89,7 @@ namespace SHADE /*-----------------------------------------------------------------------------*/ Handle() = default; ~Handle() = default; - + /*-----------------------------------------------------------------------------*/ /* Usage Functions */ /*-----------------------------------------------------------------------------*/ diff --git a/SHADE_Engine/src/Resource/Handle.hpp b/SHADE_Engine/src/Resource/Handle.hpp index d7f48ba1..0c6e6bf4 100644 --- a/SHADE_Engine/src/Resource/Handle.hpp +++ b/SHADE_Engine/src/Resource/Handle.hpp @@ -14,16 +14,16 @@ namespace SHADE /*---------------------------------------------------------------------------------*/ /* HandleBase - Overloaded Operators */ - /*---------------------------------------------------------------------------------*/ inline HandleBase::operator bool() const + /*---------------------------------------------------------------------------------*/ { return id.Raw != INVALID_ID.Raw; } - + /*---------------------------------------------------------------------------------*/ /* Handle - Usage Functions */ /*---------------------------------------------------------------------------------*/ - template + template inline void Handle::Free() { library->Free(*this); diff --git a/SHADE_Engine/src/Resource/ResourceLibrary.h b/SHADE_Engine/src/Resource/ResourceLibrary.h index 01a78d16..4588b9fe 100644 --- a/SHADE_Engine/src/Resource/ResourceLibrary.h +++ b/SHADE_Engine/src/Resource/ResourceLibrary.h @@ -62,14 +62,14 @@ namespace SHADE /*-----------------------------------------------------------------------------*/ SparseSet objects; SparseSet versionCounts; - std::queue freeList; + std::queue freeList; uint32_t lastIdx = 0; /*-----------------------------------------------------------------------------*/ /* Helper Functions */ /*-----------------------------------------------------------------------------*/ void assertHandleValid(Handle handle) const; - uint32_t getAvailableFreeIndex(); + uint32_t getAvailableFreeIndex(); }; ///