From 3766a10edd878a7c5d20b37dcbbfe591a1ef7251 Mon Sep 17 00:00:00 2001 From: Brandon Mak Date: Sat, 17 Sep 2022 22:28:03 +0800 Subject: [PATCH] WIP --- .../src/Application/SBApplication.cpp | 6 +- .../Graphics/Commands/SHVkCommandBuffer.cpp | 2 +- .../src/Graphics/Commands/SHVkCommandBuffer.h | 2 +- .../src/Graphics/Images/SHVkImage.cpp | 3 +- SHADE_Engine/src/Graphics/Images/SHVkImage.h | 2 +- .../Graphics/MiddleEnd/Interface/SHCamera.cpp | 151 ++++++ .../Graphics/MiddleEnd/Interface/SHCamera.h | 80 +++ .../MiddleEnd/Interface/SHGraphicsConstants.h | 82 +++ .../MiddleEnd/Interface/SHGraphicsSystem.cpp | 485 +++++++++++------- .../MiddleEnd/Interface/SHGraphicsSystem.h | 251 +++++---- .../MiddleEnd/Interface/SHMaterial.cpp | 67 +++ .../Graphics/MiddleEnd/Interface/SHMaterial.h | 75 +++ .../MiddleEnd/Interface/SHMaterial.hpp | 59 +++ .../Interface/SHMaterialInstance.cpp | 62 +++ .../MiddleEnd/Interface/SHMaterialInstance.h | 82 +++ .../Interface/SHMaterialInstance.hpp | 85 +++ .../MiddleEnd/Interface/SHMeshLibrary.cpp | 201 ++++++++ .../MiddleEnd/Interface/SHMeshLibrary.h | 187 +++++++ .../MiddleEnd/Interface/SHRenderTarget.cpp | 2 +- .../MiddleEnd/Interface/SHRenderable.cpp | 49 ++ .../MiddleEnd/Interface/SHRenderable.h | 60 +++ .../MiddleEnd/Interface/SHRenderer.cpp | 57 ++ .../Graphics/MiddleEnd/Interface/SHRenderer.h | 81 +++ .../MiddleEnd/Interface/SHViewport.cpp | 74 +++ .../Graphics/MiddleEnd/Interface/SHViewport.h | 81 +++ .../MiddleEnd/Pipeline/SHPipelineLibrary.cpp | 52 ++ .../MiddleEnd/Pipeline/SHPipelineLibrary.h | 57 ++ .../Pipeline/SHPipelineLayoutParams.h | 2 +- .../src/Graphics/Pipeline/SHPipelineState.h | 2 +- .../Graphics/RenderGraph/SHRenderGraph.cpp | 2 +- .../BlockInterface/SHShaderBlockInterface.cpp | 50 +- .../BlockInterface/SHShaderBlockInterface.h | 8 +- 32 files changed, 2131 insertions(+), 328 deletions(-) create mode 100644 SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHCamera.cpp create mode 100644 SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHCamera.h create mode 100644 SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsConstants.h create mode 100644 SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMaterial.cpp create mode 100644 SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMaterial.h create mode 100644 SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMaterial.hpp create mode 100644 SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMaterialInstance.cpp create mode 100644 SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMaterialInstance.h create mode 100644 SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMaterialInstance.hpp create mode 100644 SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMeshLibrary.cpp create mode 100644 SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMeshLibrary.h create mode 100644 SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderable.cpp create mode 100644 SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderable.h create mode 100644 SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderer.cpp create mode 100644 SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderer.h create mode 100644 SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHViewport.cpp create mode 100644 SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHViewport.h create mode 100644 SHADE_Engine/src/Graphics/MiddleEnd/Pipeline/SHPipelineLibrary.cpp create mode 100644 SHADE_Engine/src/Graphics/MiddleEnd/Pipeline/SHPipelineLibrary.h diff --git a/SHADE_Application/src/Application/SBApplication.cpp b/SHADE_Application/src/Application/SBApplication.cpp index 4216ba03..5420e8c5 100644 --- a/SHADE_Application/src/Application/SBApplication.cpp +++ b/SHADE_Application/src/Application/SBApplication.cpp @@ -2,7 +2,7 @@ #include "SBApplication.h" #include "ECS_Base/Managers/SHSystemManager.h" -#define SHEDITOR +//#define SHEDITOR #ifdef SHEDITOR #include "Editor/SHEditor.h" //#include "Scenes/SBEditorScene.h" @@ -76,7 +76,9 @@ namespace Sandbox #endif graphicsSystem->Run(1.0f); graphicsSystem->EndRender(); - } + + SHADE::SHSystemManager::RunRoutines(false, 0.016f); + } } diff --git a/SHADE_Engine/src/Graphics/Commands/SHVkCommandBuffer.cpp b/SHADE_Engine/src/Graphics/Commands/SHVkCommandBuffer.cpp index f83087dd..b0139f8e 100644 --- a/SHADE_Engine/src/Graphics/Commands/SHVkCommandBuffer.cpp +++ b/SHADE_Engine/src/Graphics/Commands/SHVkCommandBuffer.cpp @@ -255,7 +255,7 @@ namespace SHADE */ /***************************************************************************/ - void SHVkCommandBuffer::SetviewportScissor(float vpWidth, float vpHeight, uint32_t sWidth, uint32_t sHeight, float vpX /*= 0.0f*/, float vpY /*= 0.0f*/, int32_t sX /*= 0.0f*/, int32_t sY /*= 0.0f*/, float vpMinDepth /*= 0.0f*/, float vpMaxDepth /*= 1.0f*/) noexcept + void SHVkCommandBuffer::SetViewportScissor(float vpWidth, float vpHeight, uint32_t sWidth, uint32_t sHeight, float vpX /*= 0.0f*/, float vpY /*= 0.0f*/, int32_t sX /*= 0.0f*/, int32_t sY /*= 0.0f*/, float vpMinDepth /*= 0.0f*/, float vpMaxDepth /*= 1.0f*/) noexcept { vk::Viewport dynamicViewport { diff --git a/SHADE_Engine/src/Graphics/Commands/SHVkCommandBuffer.h b/SHADE_Engine/src/Graphics/Commands/SHVkCommandBuffer.h index 948092bf..888b805a 100644 --- a/SHADE_Engine/src/Graphics/Commands/SHVkCommandBuffer.h +++ b/SHADE_Engine/src/Graphics/Commands/SHVkCommandBuffer.h @@ -104,7 +104,7 @@ namespace SHADE void NextSubpass (void) noexcept; // Dynamic State - void SetviewportScissor (float vpWidth, float vpHeight, uint32_t sWidth, uint32_t sHeight, float vpX = 0.0f, float vpY = 0.0f, int32_t sX = 0.0f, int32_t sY = 0.0f, float vpMinDepth = 0.0f, float vpMaxDepth = 1.0f) noexcept; + void SetViewportScissor (float vpWidth, float vpHeight, uint32_t sWidth, uint32_t sHeight, float vpX = 0.0f, float vpY = 0.0f, int32_t sX = 0.0f, int32_t sY = 0.0f, float vpMinDepth = 0.0f, float vpMaxDepth = 1.0f) noexcept; // Binding Commands void BindPipeline (Handle const& pipelineHdl) noexcept; diff --git a/SHADE_Engine/src/Graphics/Images/SHVkImage.cpp b/SHADE_Engine/src/Graphics/Images/SHVkImage.cpp index f3d5a7b5..6ec1c9f2 100644 --- a/SHADE_Engine/src/Graphics/Images/SHVkImage.cpp +++ b/SHADE_Engine/src/Graphics/Images/SHVkImage.cpp @@ -234,7 +234,7 @@ namespace SHADE return SHVkInstance::GetResourceManager().Create(inLogicalDeviceHdl, parent, createParams); } - void SHVkImage::TransferToDeviceResource(Handle const& cmdBufferHdl) noexcept + void SHVkImage::TransferToDeviceResource(void) noexcept { // prepare copy regions std::vector copyRegions{mipOffsets.size()}; @@ -252,6 +252,7 @@ namespace SHADE copyRegions[i].imageExtent = vk::Extent3D{ width >> i, height >> i, 1 }; } + //PrepareImageTransition(); } /***************************************************************************/ diff --git a/SHADE_Engine/src/Graphics/Images/SHVkImage.h b/SHADE_Engine/src/Graphics/Images/SHVkImage.h index a30b90e6..eec8dc7e 100644 --- a/SHADE_Engine/src/Graphics/Images/SHVkImage.h +++ b/SHADE_Engine/src/Graphics/Images/SHVkImage.h @@ -135,7 +135,7 @@ namespace SHADE /* PUBLIC MEMBER FUNCTIONS */ /*-----------------------------------------------------------------------*/ Handle CreateImageView (Handle const& inLogicalDeviceHdl, Handle const& parent, SHImageViewDetails const& createParams) const noexcept; - void TransferToDeviceResource (Handle const& cmdBufferHdl) noexcept; + void TransferToDeviceResource (void) noexcept; void PrepareImageTransition (vk::ImageLayout oldLayout, vk::ImageLayout newLayout, vk::ImageMemoryBarrier& barrier) noexcept; /*-----------------------------------------------------------------------*/ diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHCamera.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHCamera.cpp new file mode 100644 index 00000000..2f8fb9ea --- /dev/null +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHCamera.cpp @@ -0,0 +1,151 @@ +/************************************************************************************//*! +\file SHCamera.cpp +\author Tng Kah Wei, kahwei.tng, 390009620 +\par email: kahwei.tng\@digipen.edu +\date Aug 21, 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 "SHCamera.h" + +namespace SHADE +{ + /*---------------------------------------------------------------------------------*/ + /* View Set Functions */ + /*---------------------------------------------------------------------------------*/ + 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); + + viewMatrix = SHMatrix::Identity; + 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(3, 1) = -UP.Dot(pos); + viewMatrix(3, 2) = VIEW.Dot(pos); + + isDirty = true; + } + + /*---------------------------------------------------------------------------------*/ + /* Projection Set Functions */ + /*---------------------------------------------------------------------------------*/ + void SHCamera::SetPerspective(float fov, float width, float height, float zNear, float zFar) + { + const float ASPECT_RATIO = width / height; + const float TAN_HALF_FOV = tan(fov * 0.5f); + projMatrix = SHMatrix::Identity; + projMatrix(0, 0) = 1.0f / (ASPECT_RATIO * TAN_HALF_FOV); + projMatrix(1, 1) = 1.0f / TAN_HALF_FOV; + projMatrix(2, 2) = zFar / (zFar - zNear); + projMatrix(2, 3) = 1.0f; + projMatrix(3, 2) = -(zFar * zNear) / (zFar - zNear); + + isDirty = true; + } + void SHCamera::SetOrthographic(float width, float height, float zNear, float zFar) + { + const float R = width * 0.5f; + const float L = -R; + const float T = height * 0.5f; + const float B = -T; + + projMatrix = SHMatrix::Identity; + projMatrix(0, 0) = 2.0f / (R - L); + projMatrix(1, 1) = 2.0f / (B - T); + projMatrix(2, 2) = 1.0f / (zFar - zNear); + projMatrix(3, 0) = -(R + L) / (R - L); + projMatrix(3, 1) = -(B + T) / (B - T); + projMatrix(3, 2) = -zNear / (zFar - zNear); + + isDirty = true; + } + + /*---------------------------------------------------------------------------------*/ + /* Getter Functions */ + /*---------------------------------------------------------------------------------*/ + SHMathMat4f SHCamera::GetViewMatrix() const + { + return viewMatrix; + } + + SHMathMat4f SHCamera::GetProjectionMatrix() const + { + return projMatrix; + } + SHMathMat4f SHCamera::GetViewProjectionMatrix() + { + updateMatrices(); + return vpMatrix; + } + + SHMathMat4f SHCamera::GetInverseViewMatrix() const + { + return inverseVpMatrix; + } + + SHMathMat4f SHCamera::GetInverseProjectionMatrix() const + { + return inverseProjMatrix; + } + + SHMathMat4f SHCamera::GetInverseViewProjectionMatrix() + { + updateMatrices(); + return inverseViewMatrix; + } + + /*---------------------------------------------------------------------------------*/ + /* Mapping Functions */ + /*---------------------------------------------------------------------------------*/ + SHVec3 SHCamera::ScreenToWorld(const SHVec3& vec) const + { + return multiplyHomogenous(inverseVpMatrix, vec); + } + SHVec3 SHCamera::WorldToScreen(const SHVec3& vec) const + { + return multiplyHomogenous(vpMatrix, vec); + } + SHVec3 SHCamera::CameraToWorld(const SHVec3& vec) const + { + return multiplyHomogenous(inverseViewMatrix, vec); + } + SHVec3 SHCamera::WorldToCamera(const SHVec3& vec) const + { + return multiplyHomogenous(viewMatrix, vec); + } + + /*---------------------------------------------------------------------------------*/ + /* Helper Functions */ + /*---------------------------------------------------------------------------------*/ + void SHCamera::updateMatrices() + { + if (isDirty) + { + vpMatrix = viewMatrix * projMatrix; + inverseVpMatrix = vpMatrix; + inverseVpMatrix.Inverse(); + } + } + SHVec3 SHCamera::multiplyHomogenous(const SHMathMat4f& mat, const SHVec3& vec) + { + const SHVec4 HOMO_VEC = { vec[0], vec[1], vec[2], 1.0f }; + const SHVec4 RESULT = mat * HOMO_VEC; + return SHVec3 { RESULT[0], RESULT[1], RESULT[2] }; + } +} diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHCamera.h b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHCamera.h new file mode 100644 index 00000000..fa6e31b5 --- /dev/null +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHCamera.h @@ -0,0 +1,80 @@ +/************************************************************************************//*! +\file SHCamera.h +\author Tng Kah Wei, kahwei.tng, 390009620 +\par email: kahwei.tng\@digipen.edu +\date Aug 21, 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 + +// Project Includes +#include "Math/SHMath.h" + +namespace SHADE +{ + /***********************************************************************************/ + /*! + \brief + Object that manages the view and projection transformations for rendering + a 3D scene. + */ + /***********************************************************************************/ + class SHCamera + { + public: + /*-----------------------------------------------------------------------------*/ + /* Constructor/Destructors */ + /*-----------------------------------------------------------------------------*/ + /*-----------------------------------------------------------------------------*/ + /* View Set Functions */ + /*-----------------------------------------------------------------------------*/ + void SetLookAt(const SHVec3& pos, const SHVec3& target, const SHVec3& up); + + /*-----------------------------------------------------------------------------*/ + /* Projection Set Functions */ + /*-----------------------------------------------------------------------------*/ + void SetPerspective(float fov, float width, float height, float zNear, float zFar); + void SetOrthographic(float width, float height, float zNear, float zFar); + + /*-----------------------------------------------------------------------------*/ + /* Getter Functions */ + /*-----------------------------------------------------------------------------*/ + SHMatrix GetViewMatrix() const; + SHMatrix GetProjectionMatrix() const; + SHMatrix GetViewProjectionMatrix(); + SHMatrix GetInverseViewMatrix() const; + SHMatrix GetInverseProjectionMatrix() const; + SHMatrix GetInverseViewProjectionMatrix(); + + /*-----------------------------------------------------------------------------*/ + /* Mapping Functions */ + /*-----------------------------------------------------------------------------*/ + SHVec3 ScreenToWorld(const SHVec3& vec) const; + SHVec3 WorldToScreen(const SHVec3& vec) const; + SHVec3 CameraToWorld(const SHVec3& vec) const; + SHVec3 WorldToCamera(const SHVec3& vec) const; + + private: + /*-----------------------------------------------------------------------------*/ + /* Data Members */ + /*-----------------------------------------------------------------------------*/ + SHMatrix viewMatrix; + SHMatrix projMatrix; + SHMatrix vpMatrix; + SHMatrix inverseViewMatrix; + SHMatrix inverseProjMatrix; + SHMatrix inverseVpMatrix; + bool isDirty; + + /*-----------------------------------------------------------------------------*/ + /* Helper Functions */ + /*-----------------------------------------------------------------------------*/ + void updateMatrices(); + static SHVec3 multiplyHomogenous(const SHMatrix& mat, const SHMatrix& vec); + }; +} \ No newline at end of file diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsConstants.h b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsConstants.h new file mode 100644 index 00000000..b3bd52d0 --- /dev/null +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsConstants.h @@ -0,0 +1,82 @@ +/************************************************************************************//*! +\file SHGraphicsSystem.h +\author Tng Kah Wei, kahwei.tng, 390009620 +\par email: kahwei.tng\@digipen.edu +\date Sep 8, 2022 +\brief Contains definition of constants that relate to the SHGraphicsSystem. + +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 + +namespace SHADE +{ + /***********************************************************************************/ + /*! + \brief + Contains definition of constants related to the Graphics System. + */ + /***********************************************************************************/ + struct SHGraphicsConstants + { + public: + struct DescriptorSetIndex + { + /***************************************************************************/ + /*! + \brief + DescriptorSet Index for static global values like generic data, and + texture samplers + */ + /***************************************************************************/ + static constexpr uint32_t STATIC_GLOBALS = 0; + /***************************************************************************/ + /*! + \brief + DescriptorSet Index for dynamic global values like lights. + */ + /***************************************************************************/ + static constexpr uint32_t DYNAMIC_GLOBALS = 1; + /***************************************************************************/ + /*! + \brief + DescriptorSet Index for high frequency changing global values like + camera matrices. + */ + /***************************************************************************/ + static constexpr uint32_t HIGH_FREQUENCY_GLOBALS = 2; + /***************************************************************************/ + /*! + \brief + DescriptorSet Index for per-instance/material changing values. + */ + /***************************************************************************/ + static constexpr uint32_t PER_INSTANCE = 3; + + }; + + struct DescriptorSetBindings + { + /***************************************************************************/ + /*! + \brief + DescriptorSet binding for per instance material values. + */ + /***************************************************************************/ + static constexpr uint32_t BATCHED_PER_INST_DATA = 0; + }; + + /*******************************************************************************/ + /*! + \brief + Number of frame buffers used by the Graphics System. + */ + /*******************************************************************************/ + static constexpr int NUM_FRAME_BUFFERS = 3; + }; +} diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp index bb5bfc8b..e19aee57 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp @@ -3,14 +3,14 @@ \author Tng Kah Wei, kahwei.tng, 390009620 \par email: kahwei.tng\@digipen.edu \date Aug 21, 2022 -\brief +\brief + - Copyright (C) 2022 DigiPen Institute of Technology. -Reproduction or disclosure of this file or its contents without the prior written consent +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 "SHpch.h" #include "SHGraphicsSystem.h" #include "Graphics/Instance/SHVkInstance.h" @@ -19,251 +19,370 @@ of DigiPen Institute of Technology is prohibited. //#include "SHRenderer.h" #include "Graphics/Windowing/SHWindow.h" #include "Graphics/MiddleEnd/PerFrame/SHPerFrameData.h" +#include "Graphics/MiddleEnd/Interface/SHViewport.h" +#include "Graphics/MiddleEnd/Interface/SHRenderer.h" +#include "Graphics/Pipeline/SHVkPipeline.h" +#include "Graphics/MiddleEnd/Interface/SHMaterial.h" +#include "Graphics/MiddleEnd/Interface/SHMaterialInstance.h" namespace SHADE { /*---------------------------------------------------------------------------------*/ - /* Constructor/Destructors */ - /*---------------------------------------------------------------------------------*/ - void SHGraphicsSystem::Init(void) - { - // Set Up Instance - SHVkInstance::Init(true, true, true); + /* Constructor/Destructors */ + /*---------------------------------------------------------------------------------*/ + void SHGraphicsSystem::Init(void) + { + /*-----------------------------------------------------------------------*/ + /* BACKEND BOILERPLATE */ + /*-----------------------------------------------------------------------*/ + // Set Up Instance + SHVkInstance::Init(true, true, true); - // Get Physical Device and Construct Logical Device - // TODO: Provide configuration for these options - physicalDevice = SHVkInstance::CreatePhysicalDevice(SH_PHYSICAL_DEVICE_TYPE::BEST); - device = SHVkInstance::CreateLogicalDevice({ SHQueueParams(SH_Q_FAM::GRAPHICS, SH_QUEUE_SELECT::DEDICATED), SHQueueParams(SH_Q_FAM::TRANSFER, SH_QUEUE_SELECT::DEDICATED) }, physicalDevice); + // Get Physical Device and Construct Logical Device + // TODO: Provide configuration for these options + physicalDevice = SHVkInstance::CreatePhysicalDevice(SH_PHYSICAL_DEVICE_TYPE::BEST); + device = SHVkInstance::CreateLogicalDevice({ SHQueueParams(SH_Q_FAM::GRAPHICS, SH_QUEUE_SELECT::DEDICATED), SHQueueParams(SH_Q_FAM::TRANSFER, SH_QUEUE_SELECT::DEDICATED) }, physicalDevice); - // Construct surface - surface = device->CreateSurface(window->GetHWND()); + // Construct surface + surface = device->CreateSurface(window->GetHWND()); - // Construct Swapchain - auto windowDims = window->GetWindowSize(); - swapchain = device->CreateSwapchain(surface, windowDims.first, windowDims.second, SHSwapchainParams - { - .surfaceImageFormats {vk::Format::eB8G8R8A8Unorm, vk::Format::eR8G8B8A8Unorm, vk::Format::eB8G8R8Unorm, vk::Format::eR8G8B8Unorm}, - .depthFormats {vk::Format::eD32Sfloat, vk::Format::eD32SfloatS8Uint, vk::Format::eD24UnormS8Uint}, - .presentModes {vk::PresentModeKHR::eFifo, vk::PresentModeKHR::eMailbox, vk::PresentModeKHR::eImmediate}, - .vsyncOn = false, // TODO: Set to true when shipping game - }); + // Construct Swapchain + auto windowDims = window->GetWindowSize(); + swapchain = device->CreateSwapchain(surface, windowDims.first, windowDims.second, SHSwapchainParams + { + .surfaceImageFormats {vk::Format::eB8G8R8A8Unorm, vk::Format::eR8G8B8A8Unorm, vk::Format::eB8G8R8Unorm, vk::Format::eR8G8B8Unorm}, + .depthFormats {vk::Format::eD32Sfloat, vk::Format::eD32SfloatS8Uint, vk::Format::eD24UnormS8Uint}, + .presentModes {vk::PresentModeKHR::eFifo, vk::PresentModeKHR::eMailbox, vk::PresentModeKHR::eImmediate}, + .vsyncOn = false, // TODO: Set to true when shipping game + }); - window->RegisterWindowSizeCallback([&]([[maybe_unused]] uint32_t width, [[maybe_unused]] uint32_t height) - { - renderContext.SetIsResized(true); - }); + // Register callback to notify render context upon a window resize + window->RegisterWindowSizeCallback([&]([[maybe_unused]] uint32_t width, [[maybe_unused]] uint32_t height) + { + renderContext.SetIsResized(true); + }); - // Create graphics queue - graphicsQueue = device->GetQueue(SH_Q_FAM::GRAPHICS, 0); - + // Create graphics queue + graphicsQueue = device->GetQueue(SH_Q_FAM::GRAPHICS, 0); - // Create Render Context - renderContext.Init - ( - device, - SHPerFrameDataParams - { - .swapchainHdl = swapchain, - .numThreads = 1, - .cmdPoolQueueFamilyType = SH_Q_FAM::GRAPHICS, - .cmdPoolResetMode = SH_CMD_POOL_RESET::POOL_BASED, - .cmdBufferTransient = true, - } - ); - // Create Frame and Command Buffers - for (int i = 0; i < NUM_FRAME_BUFFERS; ++i) - { - //frameBuffers[i] = device->CreateFramebuffer(renderPass, { renderContext.GetFrameData(i).swapchainImageViewHdl }, windowDims[0], windowDims[1]); - SHPerFrameData& frameData = renderContext.GetFrameData(i); + // Create Render Context + renderContext.Init + ( + device, + SHPerFrameDataParams + { + .swapchainHdl = swapchain, + .numThreads = 1, + .cmdPoolQueueFamilyType = SH_Q_FAM::GRAPHICS, + .cmdPoolResetMode = SH_CMD_POOL_RESET::POOL_BASED, + .cmdBufferTransient = true, + } + ); - if (frameData.cmdPoolHdls.empty()) - throw std::runtime_error("No command pools available!"); + // Create a descriptor pool + descPool = device->CreateDescriptorPools(); - Handle commandPool = frameData.cmdPoolHdls[0]; - //commandBuffers[i] = commandPool->RequestCommandBuffer(SH_CMD_BUFFER_TYPE::PRIMARY); // works - } - - descPool = device->CreateDescriptorPools(); + // Create generic command buffer + transferCmdPool = device->CreateCommandPool(SH_QUEUE_FAMILY_ARRAY_INDEX::TRANSFER, SH_CMD_POOL_RESET::POOL_BASED, true); + transferCmdBuffer = transferCmdPool->RequestCommandBuffer(SH_CMD_BUFFER_TYPE::PRIMARY); - /*-----------------------------------------------------------------------*/ - /* RENDERGRAPH TESTING */ - /*-----------------------------------------------------------------------*/ + /*-----------------------------------------------------------------------*/ + /* MIDDLE END SETUP + - Viewports + - Renderer + - Render graph in renderers + - Render graph command buffer semaphores + - Default vertex input state + /*-----------------------------------------------------------------------*/ + // Set Up Cameras + screenCamera = resourceManager.Create(); + screenCamera->SetLookAt(SHVec3(0.0f, 0.0f, -1.0f), SHVec3(0.0f, 0.0f, 1.0f), SHVec3(0.0f, 1.0f, 0.0f)); + screenCamera->SetOrthographic(windowDims.first, windowDims.second, 0.01f, 100.0f); + worldCamera = resourceManager.Create(); + worldCamera->SetLookAt(SHVec3(0.0f, 0.0f, -1.0f), SHVec3(0.0f, 0.0f, 1.0f), SHVec3(0.0f, 1.0f, 0.0f)); + worldCamera->SetPerspective(90.0f, windowDims.first, windowDims.second, 0.0f, 100.0f); - renderGraph.Init(device, swapchain); - renderGraph.AddResource("Position", SH_ATT_DESC_TYPE::COLOR, windowDims.first, windowDims.second, vk::Format::eR16G16B16A16Sfloat); - renderGraph.AddResource("Normals", SH_ATT_DESC_TYPE::COLOR, windowDims.first, windowDims.second, vk::Format::eR16G16B16A16Sfloat); - renderGraph.AddResource("Composite", SH_ATT_DESC_TYPE::COLOR, windowDims.first, windowDims.second, vk::Format::eR16G16B16A16Sfloat); - renderGraph.AddResource("Downscale", SH_ATT_DESC_TYPE::COLOR, windowDims.first, windowDims.second, vk::Format::eR16G16B16A16Sfloat); - renderGraph.AddResource("Present", SH_ATT_DESC_TYPE::COLOR_PRESENT, windowDims.first, windowDims.second); - auto node = renderGraph.AddNode("G-Buffer", { "Composite", "Position", "Normals", "Present" }, {}); // no predecessors - - // First subpass to write to G-Buffer + // Create Default Viewport + defaultViewport = AddViewport(vk::Viewport(0, 0, window->GetWindowSize().first, window->GetWindowSize().second, 0.0f, 1.0f)); + + // Create Debug Renderers + debugScreenRenderer = defaultViewport->AddRenderer(resourceManager); + debugScreenRenderer->SetCamera(screenCamera); + debugWorldRenderer = defaultViewport->AddRenderer(resourceManager); + debugWorldRenderer->SetCamera(worldCamera); + + // Add world renderer to default viewport + worldRenderer = defaultViewport->AddRenderer(resourceManager); + worldRenderer->SetCamera(worldCamera); + + // Get render graph from default viewport world renderer + auto worldRenderGraph = worldRenderer->GetRenderGraph(); + + // Initialize world render graph + worldRenderGraph->Init(device, swapchain); + worldRenderGraph->AddResource("Position", SH_ATT_DESC_TYPE::COLOR, windowDims.first, windowDims.second, vk::Format::eR16G16B16A16Sfloat); + worldRenderGraph->AddResource("Normals", SH_ATT_DESC_TYPE::COLOR, windowDims.first, windowDims.second, vk::Format::eR16G16B16A16Sfloat); + worldRenderGraph->AddResource("Composite", SH_ATT_DESC_TYPE::COLOR, windowDims.first, windowDims.second, vk::Format::eR16G16B16A16Sfloat); + worldRenderGraph->AddResource("Present", SH_ATT_DESC_TYPE::COLOR_PRESENT, windowDims.first, windowDims.second); + auto node = worldRenderGraph->AddNode("G-Buffer", { "Composite", "Position", "Normals", "Present" }, {}); // no predecessors + + //First subpass to write to G-Buffer auto writeSubpass = node->AddSubpass("G-Buffer Write"); writeSubpass->AddColorOutput("Position"); - //writeSubpass->AddColorOutput("Present"); + writeSubpass->AddColorOutput("Normals"); - // Second subpass to read from G-Buffer - //auto compositeSubpass = node->AddSubpass("G-Buffer Composite"); - // compositeSubpass->AddColorOutput("Composite"); - // compositeSubpass->AddInput("Normals"); - // compositeSubpass->AddInput("Position"); + //Second subpass to read from G-Buffer + auto compositeSubpass = node->AddSubpass("G-Buffer Composite"); + compositeSubpass->AddColorOutput("Present"); // TODO: This should be "Composite" and then composite will write to swapchain image "Present" + compositeSubpass->AddInput("Normals"); + compositeSubpass->AddInput("Position"); - auto imguiNode = renderGraph.AddNode("ImGui Node", { "Present" }, {}); // no predecessors - auto imguiSubpass = imguiNode->AddSubpass("ImGui Draw"); - imguiSubpass->AddColorOutput("Present"); + auto imguiNode = worldRenderGraph->AddNode("ImGui Node", { "Present" }, {}); + auto imguiSubpass = imguiNode->AddSubpass("ImGui Draw"); + imguiSubpass->AddColorOutput("Present"); - //auto compositeNode = renderGraph.AddNode("Bloom", { "Composite", "Downscale", "Present" }, { "G-Buffer" }); - //auto bloomSubpass = compositeNode->AddSubpass("Downsample"); - //bloomSubpass->AddInput("Composite"); - //bloomSubpass->AddColorOutput("Downscale"); - //bloomSubpass->AddColorOutput("Present"); + worldRenderGraph->Generate(); - renderGraph.Generate(); + // Create Semaphore + for (auto& semaHandle : graphSemaphores) + { + semaHandle = device->CreateSemaphore(); + } + ConfigureDefaultVertexInputState(); + //pipelineLibrary.Init(device, &defaultVertexInputState, ); + } - /*-----------------------------------------------------------------------*/ - /* RENDERGRAPH END TESTING */ - /*-----------------------------------------------------------------------*/ - } - - void SHGraphicsSystem::Run(float dt) noexcept + /***************************************************************************/ + /*! + + \brief + Main render loop. Loops through viewports -> renderers -> invoke render + graphs sequentially using semaphores. + + \param dt + + \return + + */ + /***************************************************************************/ + void SHGraphicsSystem::Run(double dt) noexcept { + // Frame data for the current frame auto const& frameData = renderContext.GetCurrentFrameData(); - renderGraph.Execute(renderContext.GetCurrentFrame()); + // semaphore index. This is for render graphs to have semaphores to signal that the next render graph will use to wait on. + bool semIndex = 0; - graphicsQueue->SubmitCommandBuffer({ renderGraph.GetCommandBuffer(renderContext.GetCurrentFrame()) }, - { frameData.semRenderFinishHdl }, - { frameData.semImgAvailableHdl }, - vk::PipelineStageFlagBits::eColorAttachmentOutput | vk::PipelineStageFlagBits::eEarlyFragmentTests | vk::PipelineStageFlagBits::eLateFragmentTests); + // For every viewport + for (int vpIndex = 0; vpIndex < static_cast(viewports.size()); ++vpIndex) + { + auto const& renderers = viewports[vpIndex]->GetRenderers(); + // For every renderer + for (int renIndex = 0; renIndex < static_cast(renderers.size()); ++renIndex) + { + // Draw first + renderers[renIndex]->Draw(renderContext.GetCurrentFrame()); + + // get render graph + auto rg = renderers[renIndex]->GetRenderGraph(); + + // submit a command buffer from the current render graph and make it wait for the previous render graph before submitting it to GPU. + graphicsQueue->SubmitCommandBuffer + ( + { rg->GetCommandBuffer(renderContext.GetCurrentFrame()) }, + { (vpIndex == viewports.size() - 1 && renIndex == renderers.size() - 1) ? frameData.semRenderFinishHdl : graphSemaphores[!semIndex]}, + { (vpIndex == 0 && renIndex == 0) ? frameData.semImgAvailableHdl : graphSemaphores[semIndex]}, + {} + ); + + semIndex = !semIndex; + } + } } void SHGraphicsSystem::Exit(void) - { - //renderPass.Free(); - renderContext.Destroy(); - graphicsQueue.Free(); - swapchain.Free(); - surface.Free(); - device.Free(); + { + renderContext.Destroy(); + graphicsQueue.Free(); + swapchain.Free(); + surface.Free(); + device.Free(); - SHVkInstance::Destroy(); - } + SHVkInstance::Destroy(); + } - /*---------------------------------------------------------------------------------*/ - /* Lifecycle Functions */ - /*---------------------------------------------------------------------------------*/ - /***************************************************************************/ - /*! - - \brief - Checks for window resize and acquire next image in swapchain. - - - - */ - /***************************************************************************/ - void SHGraphicsSystem::BeginRender() - { + /*---------------------------------------------------------------------------------*/ + /* Lifecycle Functions */ + /*---------------------------------------------------------------------------------*/ + /***************************************************************************/ + /*! + + \brief + Checks for window resize and acquire next image in swapchain. + + + + */ + /***************************************************************************/ + void SHGraphicsSystem::BeginRender() + { auto windowDims = window->GetWindowSize(); if (renderContext.GetResizeAndReset()) - { + { device->WaitIdle(); // Resize the swapchain swapchain->Resize(surface, windowDims.first, windowDims.second); renderContext.HandleResize(); - } + } - const uint32_t CURR_FRAME_IDX = renderContext.GetCurrentFrame(); - - // #BackEndTest: For for the fence initialized by queue submit - renderContext.WaitForFence(); + const uint32_t CURR_FRAME_IDX = renderContext.GetCurrentFrame(); - // #BackEndTest: Acquire the next image in the swapchain available - renderContext.AcquireNextIamge(); + // #BackEndTest: For for the fence initialized by queue submit + renderContext.WaitForFence(); - // #BackEndTest: Get the current frame from frame manager - auto& currFrameData = renderContext.GetCurrentFrameData(); + // #BackEndTest: Acquire the next image in the swapchain available + renderContext.AcquireNextIamge(); - // #BackEndTest: Reset command pool - if (currFrameData.cmdPoolHdls.empty()) - throw std::runtime_error("No command pools available!"); - currFrameData.cmdPoolHdls[0]->Reset(); + // #BackEndTest: Get the current frame from frame manager + auto& currFrameData = renderContext.GetCurrentFrameData(); - } + // #BackEndTest: Reset command pool + if (currFrameData.cmdPoolHdls.empty()) + throw std::runtime_error("No command pools available!"); + currFrameData.cmdPoolHdls[0]->Reset(); - /***************************************************************************/ - /*! - - \brief - Check if need to resize and advance the frame in the render context. - - */ - /***************************************************************************/ - void SHGraphicsSystem::EndRender() - { - const uint32_t CURR_FRAME_IDX = renderContext.GetCurrentFrame(); - auto& currFrameData = renderContext.GetCurrentFrameData(); + } - // #BackEndTest: Prepare to present current image - vk::PresentInfoKHR presentInfo{}; - presentInfo.waitSemaphoreCount = 1; - presentInfo.pWaitSemaphores = &currFrameData.semRenderFinishHdl->GetVkSem(); - presentInfo.swapchainCount = 1; - presentInfo.pSwapchains = &swapchain->GetVkSwapchain(); - presentInfo.pImageIndices = &CURR_FRAME_IDX; + /***************************************************************************/ + /*! - // #BackEndTest: queues an image for presentation - if (auto result = graphicsQueue->Present(swapchain, {currFrameData.semRenderFinishHdl}, CURR_FRAME_IDX); result != vk::Result::eSuccess) - { - // If swapchain is incompatible/outdated - if (result == vk::Result::eErrorOutOfDateKHR || result == vk::Result::eSuboptimalKHR) - { + \brief + Check if need to resize and advance the frame in the render context. + + */ + /***************************************************************************/ + void SHGraphicsSystem::EndRender() + { + const uint32_t CURR_FRAME_IDX = renderContext.GetCurrentFrame(); + auto& currFrameData = renderContext.GetCurrentFrameData(); + + // #BackEndTest: Prepare to present current image + vk::PresentInfoKHR presentInfo{}; + presentInfo.waitSemaphoreCount = 1; + presentInfo.pWaitSemaphores = &currFrameData.semRenderFinishHdl->GetVkSem(); + presentInfo.swapchainCount = 1; + presentInfo.pSwapchains = &swapchain->GetVkSwapchain(); + presentInfo.pImageIndices = &CURR_FRAME_IDX; + + // #BackEndTest: queues an image for presentation + if (auto result = graphicsQueue->Present(swapchain, { currFrameData.semRenderFinishHdl }, CURR_FRAME_IDX); result != vk::Result::eSuccess) + { + // If swapchain is incompatible/outdated + if (result == vk::Result::eErrorOutOfDateKHR || result == vk::Result::eSuboptimalKHR) + { auto windowDims = window->GetWindowSize(); swapchain->Resize(surface, windowDims.first, windowDims.second); renderContext.HandleResize(); - } - } - - // #BackEndTest: Cycle frame count - renderContext.AdvanceFrame(); - } - //Handle SHGraphicsSystem::AddRenderer() - //{ - // return Handle(); - //} - //void SHGraphicsSystem::RemoveRenderer(Handle renderer) - //{ - //} - Handle SHGraphicsSystem::AddSegment(const VkViewport& viewport, Handle imageToUse) - { - return Handle(); - } - void SHGraphicsSystem::RemoveSegment(Handle segment) - { - } + } + } + // #BackEndTest: Cycle frame count + renderContext.AdvanceFrame(); + } + + Handle SHGraphicsSystem::AddViewport(const vk::Viewport& viewport) + { + // Create the viewport + auto vp = SHVkInstance::GetResourceManager().Create(device, viewport); + viewports.emplace_back(vp); + return vp; + } + + void SHGraphicsSystem::RemoveViewport(Handle viewport) + { + // Check if the viewport exists + auto iter = std::find(viewports.begin(), viewports.end(), viewport); + if (iter == viewports.end()) + throw std::invalid_argument("Attempted to remove viewport that does not belong to this Graphics System."); + + // Remove + viewport.Free(); + viewports.erase(iter); + } + + Handle SHGraphicsSystem::AddMaterial(Handle vertShader, Handle fragShader) + { + // Retrieve pipeline from pipeline storage or create if unavailable + auto shaderPair = std::make_pair(vertShader, fragShader); + Handle pipeline = pipelineLibrary.GetDrawPipline(shaderPair); + if (!pipeline) + { + pipeline = pipelineLibrary.CreateDrawPipeline + ( + shaderPair, + + ); + } + + // Create material + auto mat = resourceManager.Create(); + mat->SetPipeline(pipeline); + + return mat; + } + + void SHGraphicsSystem::RemoveMaterial(Handle material) + { + resourceManager.Free(material); + } + + Handle SHGraphicsSystem::AddMaterialInstance(Handle material) + { + return resourceManager.Create(material); + } + + void SHGraphicsSystem::RemoveMaterialInstance(Handle materialInstance) + { + resourceManager.Free(materialInstance); + } + void SHGraphicsSystem::SetWindow(SHWindow* wind) noexcept { - window = wind; + window = wind; } - SHRenderGraph const& SHGraphicsSystem::GetRenderGraph(void) const noexcept + void SHGraphicsSystem::ConfigureDefaultVertexInputState(void) noexcept { - return renderGraph; + defaultVertexInputState.AddBinding(false, false, {SHVertexAttribute(SHAttribFormat::FLOAT_3D)}); // positions at binding 0 + defaultVertexInputState.AddBinding(false, false, {SHVertexAttribute(SHAttribFormat::FLOAT_2D)}); // UVs at binding 1 + defaultVertexInputState.AddBinding(false, false, {SHVertexAttribute(SHAttribFormat::FLOAT_3D)}); // Normals at binding 2 + defaultVertexInputState.AddBinding(false, false, {SHVertexAttribute(SHAttribFormat::FLOAT_3D)}); // Tangents at binding 3 + defaultVertexInputState.AddBinding(true, true, {SHVertexAttribute(SHAttribFormat::MAT_4D)}); // Transform at binding 4 - 7 (4 slots) } - void SHGraphicsSystem::SHGraphicsSystemRoutine::Execute(double dt) noexcept + void SHGraphicsSystem::BeginRoutine::Execute(double) noexcept { + reinterpret_cast(system)->BeginRender(); + } + + void SHGraphicsSystem::RenderRoutine::Execute(double dt) noexcept + { + reinterpret_cast(system)->Run(dt); + } + + void SHGraphicsSystem::EndRoutine::Execute(double) noexcept + { + reinterpret_cast(system)->EndRender(); } } diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.h b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.h index bd1ccc9b..55238ce6 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.h @@ -3,11 +3,11 @@ \author Tng Kah Wei, kahwei.tng, 390009620 \par email: kahwei.tng\@digipen.edu \date Aug 21, 2022 -\brief +\brief + - Copyright (C) 2022 DigiPen Institute of Technology. -Reproduction or disclosure of this file or its contents without the prior written consent +Reproduction or disclosure of this file or its contents without the prior written consent of DigiPen Institute of Technology is prohibited. *//*************************************************************************************/ #pragma once @@ -24,138 +24,161 @@ of DigiPen Institute of Technology is prohibited. #include "ECS_Base/System/SHSystem.h" #include "ECS_Base/System/SHSystemRoutine.h" #include "Graphics/Descriptors/SHVkDescriptorPool.h" +#include "Graphics/MiddleEnd/Pipeline/SHPipelineLibrary.h" namespace SHADE { - - /*---------------------------------------------------------------------------------*/ - /* Forward Declarations */ - /*---------------------------------------------------------------------------------*/ - class SHVkPhysicalDevice; - class SHVkLogicalDevice; - class SHVkSurface; - class SHVkSwapchain; - class SHScreenSegment; - //class SHRenderer; - class SHWindow; - class SHVkImage; - class SHVkFramebuffer; - class SHVkCommandBuffer; - /*---------------------------------------------------------------------------------*/ - /* Type Definitions */ - /*---------------------------------------------------------------------------------*/ - /***********************************************************************************/ - /*! - \brief - Represents an axis aligned box on the screen to render to along with the - specified Image to render to that spot. - */ - /***********************************************************************************/ - struct SHScreenSegment - { - VkViewport Viewport; - Handle ImageToUse; - }; + /*---------------------------------------------------------------------------------*/ + /* Forward Declarations */ + /*---------------------------------------------------------------------------------*/ + class SHVkPhysicalDevice; + class SHVkLogicalDevice; + class SHVkSurface; + class SHVkSwapchain; + class SHScreenSegment; + class SHWindow; + class SHVkImage; + class SHVkFramebuffer; + class SHVkCommandBuffer; + class SHRenderer; + class SHViewport; + class SHCamera; + class SHVkShaderModule; - /***********************************************************************************/ - /*! - \brief - Manages the lifecycle and provides an interface for rendering multiple objects to - portions of the screen. - */ - /***********************************************************************************/ - class SH_API SHGraphicsSystem : public SHSystem - { - public: - class SH_API SHGraphicsSystemRoutine : public SHSystemRoutine + /*---------------------------------------------------------------------------------*/ + /* Type Definitions */ + /*---------------------------------------------------------------------------------*/ + /***********************************************************************************/ + /*! + \brief + Manages the lifecycle and provides an interface for rendering multiple objects to + portions of the screen. + */ + /***********************************************************************************/ + class SH_API SHGraphicsSystem : public SHSystem + { + public: + class SH_API BeginRoutine final : public SHSystemRoutine { - public: - virtual void Execute(double dt) noexcept override; + public: + virtual void Execute(double dt) noexcept override final; + }; + class SH_API RenderRoutine final : public SHSystemRoutine + { + public: + virtual void Execute(double dt) noexcept override final; + }; + class SH_API EndRoutine final : public SHSystemRoutine + { + public: + virtual void Execute(double dt) noexcept override final; }; - public: - /*-----------------------------------------------------------------------------*/ - /* Constants */ - /*-----------------------------------------------------------------------------*/ - static constexpr int NUM_FRAME_BUFFERS = 3; + public: + /*-----------------------------------------------------------------------------*/ + /* Constants */ + /*-----------------------------------------------------------------------------*/ + static constexpr int NUM_FRAME_BUFFERS = 3; - /*-----------------------------------------------------------------------------*/ - /* Constructor/Destructors */ - /*-----------------------------------------------------------------------------*/ - SHGraphicsSystem (void) = default; - ~SHGraphicsSystem(void) noexcept = default; + /*-----------------------------------------------------------------------------*/ + /* Constructor/Destructors */ + /*-----------------------------------------------------------------------------*/ + SHGraphicsSystem(void) = default; + ~SHGraphicsSystem(void) noexcept = default; - /*-----------------------------------------------------------------------------*/ - /* SHSystem overrides */ - /*-----------------------------------------------------------------------------*/ - virtual void Init(void) override; - void Run (float dt) noexcept; - virtual void Exit(void) override; + /*-----------------------------------------------------------------------------*/ + /* SHSystem overrides */ + /*-----------------------------------------------------------------------------*/ + virtual void Init(void) override final; + void Run(double dt) noexcept; + virtual void Exit(void) override final; - /*-----------------------------------------------------------------------------*/ - /* Lifecycle Functions */ - /*-----------------------------------------------------------------------------*/ - void BeginRender(); - void EndRender(); + /*-----------------------------------------------------------------------------*/ + /* Lifecycle Functions */ + /*-----------------------------------------------------------------------------*/ + void BeginRender(); + void EndRender(); - /*-----------------------------------------------------------------------------*/ - /* Renderers Registration Functions */ - /*-----------------------------------------------------------------------------*/ - //Handle AddRenderer(); - //void RemoveRenderer(Handle renderer); + /*-----------------------------------------------------------------------------*/ + /* Viewport Registration Functions */ + /*-----------------------------------------------------------------------------*/ + Handle AddViewport(const vk::Viewport& viewport); + void RemoveViewport(Handle viewport); - /*-----------------------------------------------------------------------------*/ - /* Viewport Registration Functions */ - /*-----------------------------------------------------------------------------*/ - Handle AddSegment(const VkViewport& viewport, Handle imageToUse); - void RemoveSegment(Handle segment); + /*-----------------------------------------------------------------------------*/ + /* Material Creation Functions */ + /*-----------------------------------------------------------------------------*/ + Handle AddMaterial(Handle vertShader, Handle fragShader); + void RemoveMaterial(Handle material);; + Handle AddMaterialInstance(Handle material); + void RemoveMaterialInstance(Handle materialInstance); + - /*-----------------------------------------------------------------------------*/ - /* Setters */ - /*-----------------------------------------------------------------------------*/ - void SetWindow (SHWindow* wind) noexcept; + /*-----------------------------------------------------------------------------*/ + /* Setters */ + /*-----------------------------------------------------------------------------*/ + void SetWindow(SHWindow* wind) noexcept; - /*-----------------------------------------------------------------------------*/ - /* Getters (Temporary) */ - /*-----------------------------------------------------------------------------*/ - Handle GetDevice() const { return device; } - Handle GetSwapchain() const { return swapchain; } - Handle GetSurface() const { return surface; } - Handle GetPhysicalDevice() const {return physicalDevice;} + /*-----------------------------------------------------------------------------*/ + /* Getters (Temporary) */ + /*-----------------------------------------------------------------------------*/ + Handle GetDevice() const { return device; } + Handle GetSwapchain() const { return swapchain; } + Handle GetSurface() const { return surface; } + Handle GetPhysicalDevice() const { return physicalDevice; } Handle GetQueue() const { return graphicsQueue; } Handle GetDescriptorPool() const { return descPool; } - SHRenderGraph const& GetRenderGraph (void) const noexcept; + //SHRenderGraph const& GetRenderGraph(void) const noexcept; - //Handle GetRenderPass() const { return renderPass; } + //Handle GetRenderPass() const { return renderPass; } - private: - /*-----------------------------------------------------------------------------*/ - /* Data Members */ - /*-----------------------------------------------------------------------------*/ - // Owned Resources - Handle physicalDevice; - Handle device; - Handle surface; - Handle swapchain; - Handle graphicsQueue; - Handle descPool; - //Handle renderPass; // Potentially bring out? - std::vector screenSegments; - SHRenderContext renderContext; - //std::array, NUM_FRAME_BUFFERS> frameBuffers; - //std::array, NUM_FRAME_BUFFERS> commandBuffers; + private: + /*-----------------------------------------------------------------------------*/ + /* Data Members */ + /*-----------------------------------------------------------------------------*/ + // Owned Vulkan Resources + Handle physicalDevice; + Handle device; + Handle surface; + Handle swapchain; + Handle graphicsQueue; + Handle descPool; + Handle transferCmdPool; + Handle transferCmdBuffer; + SHRenderContext renderContext; + std::array, 2> graphSemaphores; - // Not Owned Resources - SHWindow* window; - // Renderers - //Handle debugWorldRenderer; - //Handle debugScreenRenderer; - //std::vector renderers; - SHRenderGraph renderGraph; + // Not Owned Resources + SHWindow* window; - friend SHGraphicsSystemRoutine; - }; + SHPipelineLibrary pipelineLibrary; + + std::vector globalDescSetLayouts; + + // Middle End Resources + ResourceManager resourceManager; + // Viewports + Handle defaultViewport; // Whole screen + std::vector> viewports; // Additional viewports + // Debug Renderers + Handle debugWorldRenderer; + Handle debugScreenRenderer; + + // Temp Cameras + Handle worldCamera; + Handle screenCamera; + + // Temp renderers + Handle worldRenderer; + + SHVertexInputState defaultVertexInputState; + + /*-----------------------------------------------------------------------------*/ + /* Private member functions */ + /*-----------------------------------------------------------------------------*/ + void ConfigureDefaultVertexInputState (void) noexcept; + }; } \ No newline at end of file diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMaterial.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMaterial.cpp new file mode 100644 index 00000000..71e72331 --- /dev/null +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMaterial.cpp @@ -0,0 +1,67 @@ +#include "SHpch.h" +#include "SHMaterial.h" + +#include "Graphics/Pipeline/SHVkPipeline.h" +#include "SHGraphicsConstants.h" +#include "Graphics/Shaders/BlockInterface/SHShaderBlockInterface.h" + +namespace SHADE +{ + /*---------------------------------------------------------------------------------*/ + /* Pipeline Functions */ + /*---------------------------------------------------------------------------------*/ + void SHMaterial::SetPipeline(Handle _pipeline) + { + pipeline = _pipeline; + + // Set up properties based on the pipeline + if (!pipeline) + { + // Clear memory and all that + propMemory.reset(); + return; + } + + // Allocate memory for properties + propMemorySize = getShaderBlockInterface()->GetBytesRequired(); + propMemory.reset(new char[propMemorySize]); + ResetProperties(); + } + + Handle SHMaterial::GetPipeline() const + { + return pipeline; + } + + /*---------------------------------------------------------------------------------*/ + /* Property Functions */ + /*---------------------------------------------------------------------------------*/ + void SHMaterial::ResetProperties() + { + // Reset all the properties to default values + memset(propMemory.get(), 0, propMemorySize); + } + + void SHMaterial::ExportProperties(void* dest) const noexcept + { + memcpy(dest, propMemory.get(), propMemorySize); + } + + size_t SHMaterial::GetPropertiesMemorySize() const noexcept + { + return getShaderBlockInterface()->GetBytesRequired(); + } + + /*---------------------------------------------------------------------------------*/ + /* Helper Functions */ + /*---------------------------------------------------------------------------------*/ + Handle SHMaterial::getShaderBlockInterface() const noexcept + { + return pipeline->GetPipelineLayout()->GetShaderBlockInterface + ( + SHGraphicsConstants::DescriptorSetIndex::PER_INSTANCE, + SHGraphicsConstants::DescriptorSetBindings::BATCHED_PER_INST_DATA, + vk::ShaderStageFlagBits::eFragment + ); + } +} diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMaterial.h b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMaterial.h new file mode 100644 index 00000000..692d857f --- /dev/null +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMaterial.h @@ -0,0 +1,75 @@ +/************************************************************************************//*! +\file SHMaterial.h +\author Tng Kah Wei, kahwei.tng, 390009620 +\par email: kahwei.tng\@digipen.edu +\date Aug 30, 2022 +\brief Contains the class definition of SHMaterial. + + +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" +#include "SHCommonTypes.h" + +namespace SHADE +{ + /*---------------------------------------------------------------------------------*/ + /* Forward Declarations */ + /*---------------------------------------------------------------------------------*/ + class SHVkPipeline; + class SHShaderBlockInterface; + + /*---------------------------------------------------------------------------------*/ + /* Type Definitions */ + /*---------------------------------------------------------------------------------*/ + /***********************************************************************************/ + /*! + \brief + Describes a Pipeline along with it's associated properties for this instance. + */ + /***********************************************************************************/ + class SHMaterial + { + public: + /*-----------------------------------------------------------------------------*/ + /* Pipeline Functions */ + /*-----------------------------------------------------------------------------*/ + void SetPipeline(Handle _pipeline); + Handle GetPipeline() const; + + /*-----------------------------------------------------------------------------*/ + /* Property Functions */ + /*-----------------------------------------------------------------------------*/ + template + void SetProperty(const std::string& key, const T& value); + template + T& GetProperty(const std::string& key); + template + const T& GetProperty(const std::string& key) const; + void ResetProperties(); + void ExportProperties(void* dest) const noexcept; + Byte GetPropertiesMemorySize() const noexcept; + + private: + /*-----------------------------------------------------------------------------*/ + /* Data Members */ + /*-----------------------------------------------------------------------------*/ + Handle pipeline; + std::unique_ptr propMemory; + Byte propMemorySize; + + /*-----------------------------------------------------------------------------*/ + /* Helper Functions */ + /*-----------------------------------------------------------------------------*/ + Handle getShaderBlockInterface() const noexcept; + }; +} + +#include "SHMaterial.hpp" \ No newline at end of file diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMaterial.hpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMaterial.hpp new file mode 100644 index 00000000..49587921 --- /dev/null +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMaterial.hpp @@ -0,0 +1,59 @@ +/************************************************************************************//*! +\file SHMaterial.hpp +\author Tng Kah Wei, kahwei.tng, 390009620 +\par email: kahwei.tng\@digipen.edu +\date Sep 8, 2022 +\brief Contains the template function definitions of SHMaterial. + + +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 + +#include "SHMaterial.h" + +#include "Graphics/Shaders/BlockInterface/SHShaderBlockInterface.h" + + +namespace SHADE +{ + /*---------------------------------------------------------------------------------*/ + /* Property Functions */ + /*---------------------------------------------------------------------------------*/ + template + void SHMaterial::SetProperty(const std::string& key, const T& value) + { + const auto SHADER_INFO = getShaderBlockInterface(); + const auto PROP_INFO = SHADER_INFO->GetVariable(key); + if (PROP_INFO == nullptr) + { + throw std::invalid_argument("Attempted to set an invalid property!"); + } + + // Get offset and modify the memory directly + T* dataPtr = propMemory.get() + PROP_INFO->offset; + *dataPtr = value; + } + template + T& SHMaterial::GetProperty(const std::string& key) + { + const auto SHADER_INFO = getShaderBlockInterface(); + const auto PROP_INFO = SHADER_INFO->GetVariable(key); + if (PROP_INFO == nullptr) + { + throw std::invalid_argument("Attempted to set an invalid property!"); + } + + // Get offset and return the memory directly + T* dataPtr = propMemory.get() + PROP_INFO->offset; + return *dataPtr; + } + template + const T& SHMaterial::GetProperty(const std::string& key) const + { + return const_cast(const_cast(this)->GetProperty(key)); + } + +} diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMaterialInstance.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMaterialInstance.cpp new file mode 100644 index 00000000..5f697208 --- /dev/null +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMaterialInstance.cpp @@ -0,0 +1,62 @@ +/************************************************************************************//*! +\file SHMaterialInstance.cpp +\author Tng Kah Wei, kahwei.tng, 390009620 +\par email: kahwei.tng\@digipen.edu +\date Sep 17, 2022 +\brief Contains the definition of functions of SHMaterialInstance. + +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 "SHMaterialInstance.h" +#include "Tools/SHLogger.h" + +namespace SHADE +{ + /*-----------------------------------------------------------------------------------*/ + /* Constructor */ + /*-----------------------------------------------------------------------------------*/ + SHMaterialInstance::SHMaterialInstance(Handle material) + : baseMaterial { material } + {} + + /*-----------------------------------------------------------------------------------*/ + /* Property Functions */ + /*-----------------------------------------------------------------------------------*/ + void SHMaterialInstance::ResetProperties() noexcept + { + + // Reset all the properties to default values + memset(dataStore.get(), 0, dataStoreSize); + overrideData.clear(); + dataStore.reset(); + } + + void SHMaterialInstance::ExportProperties(void* dest) const + { + assert(dataStore != nullptr); + + if (!baseMaterial) + throw std::runtime_error("[SHMaterialInstance] Attempted to set export a Material Instance with no base Material!"); + + // Copy default data from Material + baseMaterial->ExportProperties(dest); + + // Follow up with copying our data over + const auto SHADER_INFO = getShaderBlockInterface(); + for (const auto& data : overrideData) + { + // Get memory offset to the data + 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); + } + } +} \ 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 new file mode 100644 index 00000000..d2b222e6 --- /dev/null +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMaterialInstance.h @@ -0,0 +1,82 @@ +/************************************************************************************//*! +\file SHMaterialInstance.h +\author Tng Kah Wei, kahwei.tng, 390009620 +\par email: kahwei.tng\@digipen.edu +\date Sep 17, 2022 +\brief Contains the class definition of SHMaterialInstance. + +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 SHMaterial; + class SHGraphicsSystem; + + /*---------------------------------------------------------------------------------*/ + /* Type Definitions */ + /*---------------------------------------------------------------------------------*/ + /***********************************************************************************/ + /*! + \brief + Describes an instance of a SHMaterial that can be used to describe how to render + a SHRenderable. + */ + /***********************************************************************************/ + class SHMaterialInstance + { + public: + /*-----------------------------------------------------------------------------*/ + /* Type Definitions */ + /*-----------------------------------------------------------------------------*/ + struct OverrideData + { + size_t Index; + size_t DataSize; + size_t StoredDataOffset; + }; + + /*-----------------------------------------------------------------------------*/ + /* Constructor */ + /*-----------------------------------------------------------------------------*/ + SHMaterialInstance(Handle material = {}); + + /*-----------------------------------------------------------------------------*/ + /* Property Functions */ + /*-----------------------------------------------------------------------------*/ + template + void SetProperty(const std::string& key, const T& value); + template + T& GetProperty(const std::string& key); + template + const T& GetProperty(const std::string& key) const; + void ResetProperties() noexcept; + void ExportProperties(void* dest) const; + + /*-----------------------------------------------------------------------------*/ + /* Getter Functions */ + /*-----------------------------------------------------------------------------*/ + Handle GetBaseMaterial() const { return baseMaterial; } + + private: + /*-----------------------------------------------------------------------------*/ + /* Data Members */ + /*-----------------------------------------------------------------------------*/ + Handle baseMaterial; + std::vector overrideData; + std::unique_ptr dataStore; + size_t dataStoreSize = 0; + }; +} + +#include "SHMaterialInstance.hpp" \ No newline at end of file diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMaterialInstance.hpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMaterialInstance.hpp new file mode 100644 index 00000000..9980dfae --- /dev/null +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMaterialInstance.hpp @@ -0,0 +1,85 @@ +/************************************************************************************//*! +\file SHMaterialInstance.hpp +\author Tng Kah Wei, kahwei.tng, 390009620 +\par email: kahwei.tng\@digipen.edu +\date Sep 17, 2022 +\brief Contains the definition of functions templates of SHMaterialInstance. + +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 +#include "SHMaterialInstance.h" + +namespace SHADE +{ + /*---------------------------------------------------------------------------------*/ + /* Property Functions */ + /*---------------------------------------------------------------------------------*/ + template + void SHMaterialInstance::SetProperty(const std::string& key, const T& value) + { + const auto SHADER_INFO = getShaderBlockInterface(); + const auto PROP_INFO = SHADER_INFO->GetVariable(key); + if (PROP_INFO == nullptr) + { + throw std::invalid_argument("Attempted to set an invalid property!"); + } + + // Allocate data store if it was empty + if (dataStore == nullptr) + { + dataStoreSize = SHADER_INFO->GetBytesRequired();dataStoreSize + dataStore.reset(new char[dataStoreSize]); + } + + OverrideData od; + od.Index = SHADER_INFO.GetVariableIndex(key); + od.DataSize = sizeof(T); + if (overrideData.empty()) + { + od.StoredDataOffset = 0; + } + else + { + const OverrideData& lastInsertedData = overrideData.back(); + od.StoredDataOffset = lastInsertedData.StoredDataOffset + lastInsertedData.DataSize; + } + + // Get offset and modify the memory directly + T* dataPtr = dataStore.get() + od.StoredDataOffset; + *dataPtr = value; + + // Save the override data information + overrideData.emplace_back(std::move(od)); + } + template + T& SHMaterialInstance::GetProperty(const std::string& key) + { + const auto SHADER_INFO = getShaderBlockInterface(); + const auto PROP_INFO = SHADER_INFO->GetVariable(key); + if (PROP_INFO == nullptr) + { + throw std::invalid_argument("Attempted to get an invalid property!"); + } + + // Search Override Data for the property + uint32_t PROP_IDX = SHADER_INFO.GetVariableIndex(key); + auto prop = std::find(overrideData.begin(), overrideData.end(), [&](const OverrideData& data) + { + return PROP_IDX == data.Index; + }); + if (prop == overrideData.end()) + throw std::invalid_argument("Attempted to get an property that was not set previously!"); + + // Get offset and return the memory directly + T* dataPtr = dataStore.get() + prop->StoredDataOffset; + return *dataPtr; + } + template + const T& SHMaterialInstance::GetProperty(const std::string& key) const + { + return const_cast(const_cast(this)->GetProperty(key)); + } +} \ No newline at end of file diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMeshLibrary.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMeshLibrary.cpp new file mode 100644 index 00000000..3474fea3 --- /dev/null +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMeshLibrary.cpp @@ -0,0 +1,201 @@ +/************************************************************************************//*! +\file SHMeshLibrary.cpp +\author Tng Kah Wei, kahwei.tng, 390009620 +\par email: kahwei.tng\@digipen.edu +\date Aug 30, 2022 +\brief Contains definitions for all of the functions of the classes that deal + with storage and management of vertex and index buffers of meshes. + +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 "SHMeshLibrary.h" + +#include "Graphics/Devices/SHVkLogicalDevice.h" +#include "Graphics/Buffers/SHVkBuffer.h" +#include "Graphics/Commands/SHVkCommandBuffer.h" +#include "../../SHVkUtil.h" + +namespace SHADE +{ + SHADE::Handle SHMeshLibrary::AddMesh(uint32_t vertexCount, const SHMesh::VertexPosition* const positions, const SHMesh::VertexTexCoord* const texCoords, const SHMesh::VertexTangent* const tangents, const SHMesh::VertexNormal* const normals, uint32_t indexCount, const SHMesh::Index* const indices) + { + isDirty = true; + + auto handle = meshes.Create(); + meshAddJobs.emplace_back( MeshAddJob + { + vertexCount, + positions, + texCoords, + tangents, + normals, + indexCount, + indices, + handle + }); + return handle; + } + + void SHMeshLibrary::RemoveMesh(Handle mesh) + { + if (!mesh) + throw std::invalid_argument("Attempted to remove a Mesh that did not belong to the Mesh Library!"); + + meshRemoveJobs.emplace_back(mesh); + isDirty = true; + } + + void SHMeshLibrary::BuildBuffers(Handle device, Handle cmdBuffer) + { + // No changes + if (!isDirty) + return; + + // Remove + if (!meshRemoveJobs.empty()) + { + // - Remove from order list + for (const auto& meshToRemove : meshRemoveJobs) + { + auto searchResult = std::find(meshOrder.begin(), meshOrder.end(), meshToRemove); + // Shouldn't happen, ignore + if (searchResult == meshOrder.end()) + continue; + + // Remove from mesh list + meshOrder.erase(searchResult); + } + meshRemoveJobs.clear(); + // - Shift existing elements in to close up the gaps + int32_t nextVertInsertPoint = 0; + uint32_t nextIdxInsertPoint = 0; + for (auto& mesh : meshOrder) + { + // Check if already in the correct place + if (nextVertInsertPoint != mesh->FirstVertex) + { + /* There's a gap, we need to shift */ + // Vertices + vertPosStorage.erase(vertPosStorage.begin() + nextVertInsertPoint, vertPosStorage.begin() + mesh->FirstVertex); + vertTexCoordStorage.erase(vertTexCoordStorage.begin() + nextVertInsertPoint, vertTexCoordStorage.begin() + mesh->FirstVertex); + vertTangentStorage.erase(vertTangentStorage.begin() + nextVertInsertPoint, vertTangentStorage.begin() + mesh->FirstVertex); + vertNormalStorage.erase(vertNormalStorage.begin() + nextVertInsertPoint, vertNormalStorage.begin() + mesh->FirstVertex); + // - Update mesh data + mesh->FirstVertex = nextVertInsertPoint; + + // Indices + indexStorage.erase(indexStorage.begin() + nextIdxInsertPoint, indexStorage.begin() + mesh->FirstIndex); + // - Update mesh data + mesh->FirstIndex = nextIdxInsertPoint; + + // Prepare for next + nextVertInsertPoint += mesh->VertexCount; + nextIdxInsertPoint += mesh->IndexCount; + } + } + } + + // Add + if (!meshAddJobs.empty()) + { + // - Compute updated size + size_t newVertElems = vertPosStorage.size(); + size_t newIdxElems = indexStorage.size(); + for (const auto& addJob : meshAddJobs) + { + newVertElems += addJob.VertexCount; + newIdxElems += addJob.IndexCount; + } + // - Reserve new memory + vertPosStorage .reserve(newVertElems); + vertTexCoordStorage.reserve(newVertElems); + vertTangentStorage .reserve(newVertElems); + vertNormalStorage .reserve(newVertElems); + indexStorage .reserve(newIdxElems); + // - Append new data + for (auto& addJob : meshAddJobs) + { + // Update handle + SHMesh& meshData = *addJob.Handle; + meshData = SHMesh + { + .FirstVertex = static_cast(vertPosStorage.size()), + .VertexCount = static_cast(addJob.VertexCount), + .FirstIndex = static_cast(indexStorage.size()), + .IndexCount = static_cast(addJob.IndexCount), + }; + + // Copy into storage + vertPosStorage.insert + ( + vertPosStorage.end(), + addJob.VertexPositions, addJob.VertexPositions + addJob.VertexCount + ); + vertTexCoordStorage.insert + ( + vertTexCoordStorage.end(), + addJob.VertexTexCoords, addJob.VertexTexCoords + addJob.VertexCount + ); + vertTangentStorage.insert + ( + vertTangentStorage.end(), + addJob.VertexTangents, addJob.VertexTangents + addJob.VertexCount + ); + vertNormalStorage.insert + ( + vertNormalStorage.end(), + addJob.VertexNormals, addJob.VertexNormals + addJob.VertexCount + ); + indexStorage.insert + ( + indexStorage.end(), + addJob.Indices, addJob.Indices + addJob.IndexCount + ); + } + meshAddJobs.clear(); + } + + // Send to GPU + using BuffUsage = vk::BufferUsageFlagBits; + SHVkUtil::EnsureBufferAndCopyData + ( + device, cmdBuffer, vertPosBuffer, + vertPosStorage.data(), + static_cast(vertPosStorage.size()) * sizeof(SHMesh::VertexPosition), + BuffUsage::eVertexBuffer + ); + SHVkUtil::EnsureBufferAndCopyData + ( + device, cmdBuffer, vertTexCoordBuffer, + vertTexCoordStorage.data(), + static_cast(vertTexCoordStorage.size()) * sizeof(SHMesh::VertexTexCoord), + BuffUsage::eVertexBuffer + ); + SHVkUtil::EnsureBufferAndCopyData + ( + device, cmdBuffer, vertTangentBuffer, + vertTangentStorage.data(), + static_cast(vertTangentStorage.size()) * sizeof(SHMesh::VertexTangent), + BuffUsage::eVertexBuffer + ); + SHVkUtil::EnsureBufferAndCopyData + ( + device, cmdBuffer, vertNormalBuffer, + vertNormalStorage.data(), + static_cast(vertNormalStorage.size()) * sizeof(SHMesh::VertexNormal), + BuffUsage::eVertexBuffer + ); + SHVkUtil::EnsureBufferAndCopyData + ( + device, cmdBuffer, indexBuffer, + indexStorage.data(), + static_cast(indexStorage.size()) * sizeof(SHMesh::Index), + BuffUsage::eIndexBuffer + ); + + isDirty = false; + } +} diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMeshLibrary.h b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMeshLibrary.h new file mode 100644 index 00000000..f8a89687 --- /dev/null +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMeshLibrary.h @@ -0,0 +1,187 @@ +/************************************************************************************//*! +\file SHMeshLibrary.h +\author Tng Kah Wei, kahwei.tng, 390009620 +\par email: kahwei.tng\@digipen.edu +\date Aug 30, 2022 +\brief Contains definitions for all of the classes that deal with storage and + management of vertex and index buffers of meshes. + +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" +#include "Resource/ResourceLibrary.h" +#include "SHVertex.h" + +namespace SHADE +{ + /*---------------------------------------------------------------------------------*/ + /* Forward Declarations */ + /*---------------------------------------------------------------------------------*/ + class SHVkBuffer; + class SHVkLogicalDevice; + class SHVkCommandBuffer; + + /*---------------------------------------------------------------------------------*/ + /* Type Definitions */ + /*---------------------------------------------------------------------------------*/ + /***********************************************************************************/ + /*! + \brief + Represents a single mesh that is stored in a SHMeshLibrary. + */ + /***********************************************************************************/ + class SHMesh + { + public: + /*-----------------------------------------------------------------------------*/ + /* Type Definitions */ + /*-----------------------------------------------------------------------------*/ + using Index = uint32_t; + using VertexPosition = SHMathVec3f; + using VertexTexCoord = SHMathVec2f; + using VertexTangent = SHMathVec3f; + using VertexNormal = SHMathVec3f; + + /*-----------------------------------------------------------------------------*/ + /* Data Members */ + /*-----------------------------------------------------------------------------*/ + int32_t FirstVertex; + uint32_t VertexCount; + uint32_t FirstIndex; + uint32_t IndexCount; + }; + /***********************************************************************************/ + /*! + \brief + Manages storage for all Meshes in the Graphics System as a single set of Vertex + and Index Buffers. + */ + /***********************************************************************************/ + class SHMeshLibrary + { + public: + /*-----------------------------------------------------------------------------*/ + /* Usage Functions */ + /*-----------------------------------------------------------------------------*/ + /*******************************************************************************/ + /*! + + \brief + Adds a mesh to the Mesh Library. But this does not mean that the meshes have + been added yet. A call to "BuildBuffers()" is required to transfer all + meshes into the GPU. + + \param vertexCount + Number of vertices in this Mesh. + \param positions + Pointer to the first in a contiguous array of SHMathVec3s that define vertex + positions. + \param texCoords + Pointer to the first in a contiguous array of SHMathVec2s that define vertex + texture coordinates. + \param tangents + Pointer to the first in a contiguous array of SHMathVec3s that define vertex + tangents. + \param normals + Pointer to the first in a contiguous array of SHMathVec3s that define vertex + normals. + \param indexCount + Number of indices in this mesh. + \param indices + Pointer to the first in a contiguous array of uint32_ts that define mesh + indicies. + + \return + Handle to the created Mesh. This is not valid to be used until a call to + BuildBuffers(). + + */ + /*******************************************************************************/ + Handle AddMesh(uint32_t vertexCount, const SHMesh::VertexPosition* const positions, const SHMesh::VertexTexCoord* const texCoords, const const SHMesh::VertexTangent* const tangents, const SHMesh::VertexNormal* const normals, uint32_t indexCount, const SHMesh::Index* const indices); + /*******************************************************************************/ + /*! + + \brief + Removes a mesh from the MeshLibrary. But this does not mean that the meshes + have been removed yet. A call to "BuildBuffers()" is required to finalise all + changes. + + \param mesh + Handle to the mesh to remove. + + */ + /*******************************************************************************/ + void RemoveMesh(Handle mesh); + /***************************************************************************/ + /*! + + \brief + Finalises all changes to the MeshLibrary into the GPU buffers. + + \param device + Device used to create and update the buffers. + \param cmdBuffer + Command buffer used to set up transfers of data in the GPU memory. This + call must be preceded by calls to cmdBuffer's BeginRecording() and ended + with EndRecording(). Do recall to also submit the cmdBuffer to a transfer + queue. + */ + /***************************************************************************/ + void BuildBuffers(Handle device, Handle cmdBuffer); + + /*-----------------------------------------------------------------------------*/ + /* Getter Functions */ + /*-----------------------------------------------------------------------------*/ + Handle GetVertexPositionsBuffer() const noexcept { return vertPosBuffer; } + Handle GetVertexTexCoordsBuffer() const noexcept { return vertTexCoordBuffer; } + Handle GetVertexTangentsBuffer() const noexcept { return vertTangentBuffer; } + Handle GetVertexNormalsBuffer() const noexcept { return vertNormalBuffer; } + Handle GetIndexBuffer() const { return indexBuffer; } + + private: + /*-----------------------------------------------------------------------------*/ + /* Type Definition */ + /*-----------------------------------------------------------------------------*/ + struct MeshAddJob + { + uint32_t VertexCount = 0; + const SHMesh::VertexPosition* VertexPositions = nullptr; + const SHMesh::VertexTexCoord* VertexTexCoords = nullptr; + const SHMesh::VertexTangent * VertexTangents = nullptr; + const SHMesh::VertexNormal * VertexNormals = nullptr; + uint32_t IndexCount = 0; + const SHMesh::Index * Indices = nullptr; + Handle Handle; + }; + /*-----------------------------------------------------------------------------*/ + /* Data Members */ + /*-----------------------------------------------------------------------------*/ + // Manipulation Queues + std::vector meshAddJobs; + std::vector> meshRemoveJobs; + // Tracking + ResourceLibrary meshes{}; + std::vector> meshOrder; + // CPU Storage + std::vector vertPosStorage; + std::vector vertTexCoordStorage; + std::vector vertTangentStorage; + std::vector vertNormalStorage; + std::vector indexStorage; + // GPU Storage + Handle vertPosBuffer{}; + Handle vertTexCoordBuffer{}; + Handle vertTangentBuffer{}; + Handle vertNormalBuffer{}; + Handle indexBuffer {}; + // Flags + bool isDirty = true; + }; +} diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderTarget.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderTarget.cpp index eec4d28a..e728ff68 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderTarget.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderTarget.cpp @@ -1,2 +1,2 @@ -#include "SHPch.h" +#include "SHpch.h" #include "SHRenderTarget.h" diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderable.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderable.cpp new file mode 100644 index 00000000..41a8d8d0 --- /dev/null +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderable.cpp @@ -0,0 +1,49 @@ +/************************************************************************************//*! +\file SHRenderable.cpp +\author Tng Kah Wei, kahwei.tng, 390009620 +\par email: kahwei.tng\@digipen.edu +\date Sep 19, 2022 +\brief Contains the definition of functions of the SHRenderable Component class. + +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 "SHRenderable.h" +#include "ECS_Base/Managers/SHSystemManager.h" + +namespace SHADE +{ + void SHRenderable::SetMaterial(Handle materialInstance) + { + if (material) + { + material.Free(); + material = {}; + } + + sharedMaterial = materialInstance; + } + + Handle SHRenderable::GetMaterial() const + { + if (material) + return material; + + return sharedMaterial; + } + + Handle SHRenderable::GetModifiableMaterial() + { + // Create a copy if it wasn't created + if (!material) + { + SHGraphicsSystem* gfxSystem = SHSystemManager::GetSystem(); + material = gfxSystem->AddMaterialInstance(sharedMaterial->GetBaseMaterial()); + } + + return material; + } +} \ No newline at end of file diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderable.h b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderable.h new file mode 100644 index 00000000..4d85abd8 --- /dev/null +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderable.h @@ -0,0 +1,60 @@ +/************************************************************************************//*! +\file SHRenderable.h +\author Tng Kah Wei, kahwei.tng, 390009620 +\par email: kahwei.tng\@digipen.edu +\date Sep 19, 2022 +\brief Contains the definition of the SHRenderable Component class. + +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 + +// Project Includes +#include "Resource/Handle.h" +//#include "SHTransform.h" +#include "ECS_Base/Components/SHComponent.h" +#include "Math/SHMatrix.h" + +namespace SHADE +{ + /*-----------------------------------------------------------------------------------*/ + /* Forward Declarations */ + /*-----------------------------------------------------------------------------------*/ + class SHMaterialInstance; + class SHMesh; + /*-----------------------------------------------------------------------------------*/ + /* Type Definitions */ + /*-----------------------------------------------------------------------------------*/ + /*************************************************************************************/ + /*! + \brief + Represents an object that should be rendered. + */ + /*************************************************************************************/ + class SHRenderable : public SHComponent, public ISelfHandle + { + public: + /*-------------------------------------------------------------------------------*/ + /* Usage Functions */ + /*-------------------------------------------------------------------------------*/ + void SetMaterial(Handle materialInstance); + Handle GetMaterial() const; + Handle GetModifiableMaterial(); + + /*-------------------------------------------------------------------------------*/ + /* Data Members */ + /*-------------------------------------------------------------------------------*/ + Handle Mesh; + SHMatrix TransformMatrix; // TODO: Replace with Transform component + + private: + /*-------------------------------------------------------------------------------*/ + /* Data Members */ + /*-------------------------------------------------------------------------------*/ + Handle sharedMaterial; + Handle material; + }; +} + diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderer.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderer.cpp new file mode 100644 index 00000000..6a5b86e3 --- /dev/null +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderer.cpp @@ -0,0 +1,57 @@ +/************************************************************************************//*! +\file SHRenderer.cpp +\author Tng Kah Wei, kahwei.tng, 390009620 +\par email: kahwei.tng\@digipen.edu +\date Aug 21, 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 "SHRenderer.h" +#include "Graphics/Devices/SHVkLogicalDevice.h" +#include "SHViewport.h" +#include "Graphics/Buffers/SHVkBuffer.h" +#include "Graphics/Framebuffer/SHVkFramebuffer.h" +#include "SHMaterial.h" + +namespace SHADE +{ + /*---------------------------------------------------------------------------------*/ + /* Constructor/Destructors */ + /*---------------------------------------------------------------------------------*/ + SHRenderer::SHRenderer(Handle viewport, ResourceManager& resourceManager) + : renderGraph{resourceManager.Create ()} + { + + } + SHRenderer::~SHRenderer() + { + } + + /*-----------------------------------------------------------------------------*/ + /* Camera Registration */ + /*-----------------------------------------------------------------------------*/ + void SHRenderer::SetCamera(Handle _camera) + { + camera = _camera; + } + + /*---------------------------------------------------------------------------------*/ + /* Drawing Functions */ + /*---------------------------------------------------------------------------------*/ + void SHRenderer::Draw(uint32_t frameIndex) const noexcept + { + renderGraph->Execute(frameIndex); + } + + Handle SHRenderer::GetRenderGraph(void) const noexcept + { + return renderGraph; + } + +} diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderer.h b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderer.h new file mode 100644 index 00000000..000fec4f --- /dev/null +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderer.h @@ -0,0 +1,81 @@ +/************************************************************************************//*! +\file SHRenderer.h +\author Tng Kah Wei, kahwei.tng, 390009620 +\par email: kahwei.tng\@digipen.edu +\date Aug 21, 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 "SHCamera.h" +#include "Resource/Handle.h" +#include "SHGraphicsConstants.h" +#include "Graphics/RenderGraph/SHRenderGraph.h" + +namespace SHADE +{ + /*---------------------------------------------------------------------------------*/ + /* Forward Declarations */ + /*---------------------------------------------------------------------------------*/ + class SHVkBuffer; + class SHVkRenderpass; + class SHVkFramebuffer; + class SHMaterial; + class SHVkLogicalDevice; + class SHViewport; + class SHVkImageView; + class SHVkCommandBuffer; + class SHCamera; + + /*---------------------------------------------------------------------------------*/ + /* Type Definitions */ + /*---------------------------------------------------------------------------------*/ + /***********************************************************************************/ + /*! + \brief + Brings together a set of Cameras and objects with various Pipelines to render + them as part of a set. Multiple Renderers can exist to render objects differently + in a separate step. + */ + /***********************************************************************************/ + class SHRenderer + { + public: + /*-----------------------------------------------------------------------------*/ + /* Constructor/Destructors */ + /*-----------------------------------------------------------------------------*/ + SHRenderer(Handle viewport, ResourceManager& resourceManager); + ~SHRenderer(); + + /*-----------------------------------------------------------------------------*/ + /* Camera Registration */ + /*-----------------------------------------------------------------------------*/ + void SetCamera(Handle _camera); + + /*-----------------------------------------------------------------------------*/ + /* Drawing Functions */ + /*-----------------------------------------------------------------------------*/ + void Draw(uint32_t frameIndex) const noexcept; + + /*-----------------------------------------------------------------------------*/ + /* Setters and Getters */ + /*-----------------------------------------------------------------------------*/ + Handle GetRenderGraph (void) const noexcept; + + private: + /*-----------------------------------------------------------------------------*/ + /* Data Members */ + /*-----------------------------------------------------------------------------*/ + Handle camera; + Handle renderGraph; + }; +} diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHViewport.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHViewport.cpp new file mode 100644 index 00000000..47f9ec5a --- /dev/null +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHViewport.cpp @@ -0,0 +1,74 @@ +/************************************************************************************//*! +\file SHViewport.cpp +\author Tng Kah Wei, kahwei.tng, 390009620 +\par email: kahwei.tng\@digipen.edu +\date Aug 27, 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 "SHViewport.h" + +#include "Graphics/Commands/SHVkCommandBuffer.h" +#include "Graphics/Instance/SHVkInstance.h" +#include "Tools/SHLogger.h" +#include "SHRenderer.h" + +namespace SHADE +{ + /*---------------------------------------------------------------------------------*/ + /* Constructor/Destructors */ + /*---------------------------------------------------------------------------------*/ + SHViewport::SHViewport(Handle device, const vk::Viewport& viewport) + : device { device } + , viewport { viewport } + {} + + /*---------------------------------------------------------------------------------*/ + /* Lifecycle Functions */ + /*---------------------------------------------------------------------------------*/ + void SHViewport::SetUp(Handle commandBuffer) + { + commandBuffer->SetViewportScissor + ( + viewport.x, + viewport.y, + static_cast(viewport.width), + static_cast(viewport.height), + viewport.minDepth, + viewport.maxDepth + ); + } + + /*---------------------------------------------------------------------------------*/ + /* Renderer Registration Functions */ + /*---------------------------------------------------------------------------------*/ + Handle SHViewport::AddRenderer(ResourceManager& resourceManager) + { + // Create the renderer + auto renderer = SHVkInstance::GetResourceManager().Create(GetHandle(), resourceManager); + + // Store + renderers.emplace_back(renderer); + + // Return + return renderer; + } + void SHViewport::RemoveRenderer(Handle renderer) + { + auto iter = std::find(renderers.begin(), renderers.end(), renderer); + if (iter == renderers.end()) + { + SHLOG_WARNING("Attempted to remove a Renderer that does not belong to a viewport!"); + return; + } + + // Remove it + iter->Free(); + renderers.erase(iter); + } +} diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHViewport.h b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHViewport.h new file mode 100644 index 00000000..01637db3 --- /dev/null +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHViewport.h @@ -0,0 +1,81 @@ +/************************************************************************************//*! +\file SHViewport.h +\author Tng Kah Wei, kahwei.tng, 390009620 +\par email: kahwei.tng\@digipen.edu +\date Aug 27, 2022 +\brief Contains the class definition of SHViewport. + + +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" + +namespace SHADE +{ + /*---------------------------------------------------------------------------------*/ + /* Forward Declarations */ + /*---------------------------------------------------------------------------------*/ + class SHRenderer; + class SHVkCommandBuffer; + class SHVkLogicalDevice; + class SHVkImageView; + + /*---------------------------------------------------------------------------------*/ + /* Type Definitions */ + /*---------------------------------------------------------------------------------*/ + /***********************************************************************************/ + /*! + \brief + Brings together a set of Renderers that render to the same segment of an image. + */ + /***********************************************************************************/ + class SHViewport : public ISelfHandle + { + public: + /*-----------------------------------------------------------------------------*/ + /* Constructor/Destructors */ + /*-----------------------------------------------------------------------------*/ + SHViewport(Handle device, const vk::Viewport& viewport); + + /*-----------------------------------------------------------------------------*/ + /* Lifecycle Functions */ + /*-----------------------------------------------------------------------------*/ + void SetUp(Handle commandBuffer); + + /*-----------------------------------------------------------------------------*/ + /* Renderers Registration Functions */ + /*-----------------------------------------------------------------------------*/ + Handle AddRenderer(ResourceManager& resourceManager); + void RemoveRenderer(Handle renderer); + + /*-----------------------------------------------------------------------------*/ + /* Getters */ + /*-----------------------------------------------------------------------------*/ + float GetX() const { return viewport.x; } + float GetY() const { return viewport.y; } + float GetWidth() const { return viewport.width; } + float GetHeight() const { return viewport.height; } + float GetMinDepth() const { return viewport.minDepth; } + float GetMaxDepth() const { return viewport.maxDepth; } + const std::vector>& GetRenderers() const { return renderers; } + + + private: + /*-----------------------------------------------------------------------------*/ + /* Data Members */ + /*-----------------------------------------------------------------------------*/ + Handle device; + vk::Viewport viewport; + std::vector> renderers; + }; + +} \ No newline at end of file diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Pipeline/SHPipelineLibrary.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Pipeline/SHPipelineLibrary.cpp new file mode 100644 index 00000000..45bb87ba --- /dev/null +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Pipeline/SHPipelineLibrary.cpp @@ -0,0 +1,52 @@ +#include "SHpch.h" +#include "SHPipelineLibrary.h" +#include "Graphics/Devices/SHVkLogicalDevice.h" + +namespace SHADE +{ + + Handle SHPipelineLibrary::CreateDrawPipeline(std::pair, Handle> const& vsFsPair, Handle renderpass, uint32_t subpass, SHVertexInputState const& vertexInput, std::vector> const& globalDescSetLayouts) noexcept + { + SHPipelineLayoutParams params + { + .shaderModules = {vsFsPair.first, vsFsPair.second}, + .globalDescSetLayouts = globalDescSetLayouts + }; + + // Create the pipeline layout + auto pipelineLayout = logicalDevice->CreatePipelineLayout(params); + + // Create the pipeline and configure the default vertex input state + auto newPipeline = logicalDevice->CreatePipeline(pipelineLayout, nullptr, renderpass, subpass, SH_PIPELINE_TYPE::GRAPHICS); + newPipeline->GetPipelineState().SetVertexInputState(vertexInput); + + // Actually construct the pipeline + newPipeline->ConstructPipeline(); + + // Emplace the new pipeline + pipelines.emplace (vsFsPair, newPipeline); + } + + void SHPipelineLibrary::Init(Handle device, SHVertexInputState const* viState, std::vector> const* globalLayouts) noexcept + { + logicalDevice = device; + vertexInputState = viState; + globalDescSetLayouts = globalLayouts; + } + + Handle SHPipelineLibrary::GetDrawPipline(std::pair, Handle> const& vsFsPair) noexcept + { + // return the pipeline requested for + if (pipelines.contains(vsFsPair)) + return pipelines.at(vsFsPair); + else + return {}; + } + + bool SHPipelineLibrary::CheckDrawPipelineExistence(std::pair, Handle> const& vsFsPair) noexcept + { + // Returns if a pipeline exists or not + return pipelines.contains(vsFsPair); + } + +} \ No newline at end of file diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Pipeline/SHPipelineLibrary.h b/SHADE_Engine/src/Graphics/MiddleEnd/Pipeline/SHPipelineLibrary.h new file mode 100644 index 00000000..fe69e87b --- /dev/null +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Pipeline/SHPipelineLibrary.h @@ -0,0 +1,57 @@ +#pragma once + +#include +#include "Graphics/Shaders/SHVkShaderModule.h" +#include "Graphics/Pipeline/SHVkPipeline.h" + + +namespace SHADE +{ + class SHVRenderpass; + class SHVkDescriptorSetLayouts; + class SHVkPipeline; + + + // Pipeline library is a PURELY MIDDLE END SYSTEM. It is responsible for only creating pipelines from shaders and caching + // them so that they don't need to be recreated again. + class SHPipelineLibrary + { + private: + // TOOD: Move this somewhere eventually. Can use for other things + struct SHHandlePairHash + { + template + std::size_t operator() (std::pair const& pair) const + { + return std::hash()(pair.first.GetId()) ^ std::hash()(pair.second.GetId()); + } + }; + + //! Logical Device required for creation of pipelines + Handle logicalDevice; + + //! a map of pipelines that are hashed using a pair of shader module handles + std::unordered_map, Handle>, Handle, SHHandlePairHash> pipelines; + + //! Default vertex input state for pipeline creation + SHVertexInputState const* vertexInputState; + + std::vector> const* globalDescSetLayouts; + + + public: + void Init (Handle device, SHVertexInputState const* viState, std::vector> const* globalLayouts) noexcept; + + // Draw pipeline functions. used only when creating pipelines for drawing using a vertex and fragment shader + Handle CreateDrawPipeline ( + std::pair, Handle> const& vsFsPair, + Handle renderpass, + uint32_t subpass, + SHVertexInputState const& vertexInput, + std::vector> const& globalDescSetLayouts + ) noexcept; + Handle GetDrawPipline (std::pair, Handle> const& vsFsPair) noexcept; + bool CheckDrawPipelineExistence (std::pair, Handle> const& vsFsPair) noexcept; + + }; +} diff --git a/SHADE_Engine/src/Graphics/Pipeline/SHPipelineLayoutParams.h b/SHADE_Engine/src/Graphics/Pipeline/SHPipelineLayoutParams.h index 961b3f4c..493bd114 100644 --- a/SHADE_Engine/src/Graphics/Pipeline/SHPipelineLayoutParams.h +++ b/SHADE_Engine/src/Graphics/Pipeline/SHPipelineLayoutParams.h @@ -23,7 +23,7 @@ namespace SHADE //! used just for textures or lights for example). In that case, we still //! want to use the layout to initialize the pipeline layout but we do not //! want to use it for allocating descriptor sets. - std::vector> globalDescSetLayouts = {}; + std::vector> const& globalDescSetLayouts = {}; }; } diff --git a/SHADE_Engine/src/Graphics/Pipeline/SHPipelineState.h b/SHADE_Engine/src/Graphics/Pipeline/SHPipelineState.h index 7c24aab7..e692163b 100644 --- a/SHADE_Engine/src/Graphics/Pipeline/SHPipelineState.h +++ b/SHADE_Engine/src/Graphics/Pipeline/SHPipelineState.h @@ -189,7 +189,7 @@ namespace SHADE /* SETTERS AND GETTERS */ /*-----------------------------------------------------------------------*/ - template , SHVertexInputState>>> + template , SHVertexInputState>>> void SetVertexInputState (T&& state) noexcept; void SetInputAssemblyState(SHInputAssemblyState const& state) noexcept; void SetRasterizationState(SHRasterizationState const& state) noexcept; diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp index 41633e55..0181bdad 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp @@ -1035,7 +1035,7 @@ namespace SHADE auto& cmdBuffer = commandBuffers[frameIndex]; cmdBuffer->BeginRecording(); - cmdBuffer->SetviewportScissor(1920.0f, 1080.0f, 1920, 1080); + cmdBuffer->SetViewportScissor(1920.0f, 1080.0f, 1920, 1080); for (auto& node : nodes) { diff --git a/SHADE_Engine/src/Graphics/Shaders/BlockInterface/SHShaderBlockInterface.cpp b/SHADE_Engine/src/Graphics/Shaders/BlockInterface/SHShaderBlockInterface.cpp index 2135b9dd..cfa26e4c 100644 --- a/SHADE_Engine/src/Graphics/Shaders/BlockInterface/SHShaderBlockInterface.cpp +++ b/SHADE_Engine/src/Graphics/Shaders/BlockInterface/SHShaderBlockInterface.cpp @@ -6,30 +6,49 @@ namespace SHADE void SHShaderBlockInterface::AddVariable(std::string name, Variable&& newVariable) noexcept { - variables.try_emplace (std::move(name), std::move (newVariable)); + // Check if this is already inside + if (variableIndexing.contains(name)) + { + 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)); } SHShaderBlockInterface::Variable const* const SHShaderBlockInterface::GetVariable(std::string const& variableName) const noexcept { - if (variables.contains(variableName)) - return &variables.at(variableName); + if (variableIndexing.contains(variableName)) + return &variables.at(variableIndexing.at(variableName).second); return nullptr; } - SHShaderBlockInterface::SHShaderBlockInterface(void) noexcept - : variables{} - , bytesRequired{ 0 } + SHADE::SHShaderBlockInterface::Variable const* const SHShaderBlockInterface::GetVariable(uint32_t index) const noexcept { + if (variableIndexing.size() < index) + return &variables.at(index); + return nullptr; } + uint32_t SHShaderBlockInterface::GetVariableIndex(std::string const& variableName) const noexcept + { + if (!variableIndexing.contains(variableName)) + throw std::invalid_argument("Attempted to retrieve index to variable that does not exist!"); + + return variableIndexing.at(variableName).second; + } + + SHShaderBlockInterface::SHShaderBlockInterface(void) noexcept + : bytesRequired{ 0 } + {} + SHShaderBlockInterface::SHShaderBlockInterface(SHShaderBlockInterface&& rhs) noexcept - : variables{ std::move(rhs.variables) } - , bytesRequired {std::move (rhs.bytesRequired)} - { - - } + : variables { std::move(rhs.variables) } + , variableIndexing { std::move(rhs.variableIndexing) } + , bytesRequired { std::move (rhs.bytesRequired) } + {} void SHShaderBlockInterface::SetBytesRequired(uint32_t bytes) noexcept { @@ -46,16 +65,11 @@ namespace SHADE { if (&rhs == this) return *this; - + variables = std::move(rhs.variables); + variableIndexing = std::move(rhs.variableIndexing); bytesRequired = std::move(rhs.bytesRequired); return *this; } - - SHShaderBlockInterface::~SHShaderBlockInterface(void) noexcept - { - variables.clear(); - } - } \ No newline at end of file diff --git a/SHADE_Engine/src/Graphics/Shaders/BlockInterface/SHShaderBlockInterface.h b/SHADE_Engine/src/Graphics/Shaders/BlockInterface/SHShaderBlockInterface.h index 38c01bde..ee7e7726 100644 --- a/SHADE_Engine/src/Graphics/Shaders/BlockInterface/SHShaderBlockInterface.h +++ b/SHADE_Engine/src/Graphics/Shaders/BlockInterface/SHShaderBlockInterface.h @@ -15,8 +15,9 @@ namespace SHADE }; private: - //! container of variable information - std::unordered_map variables; + //! containers of variable information + std::vector variables; + std::unordered_map variableIndexing; //! bytes required by the block (includes padding). This variable is required uint32_t bytesRequired; @@ -24,12 +25,13 @@ namespace SHADE public: void AddVariable (std::string name, Variable&& newVariable) noexcept; Variable const* const GetVariable (std::string const& variableName) const noexcept; + Variable const* const GetVariable(uint32_t index) const noexcept; + uint32_t GetVariableIndex(std::string const& variableName) const; /*-----------------------------------------------------------------------*/ /* CTORS AND DTORS */ /*-----------------------------------------------------------------------*/ SHShaderBlockInterface(void) noexcept; - ~SHShaderBlockInterface(void) noexcept; SHShaderBlockInterface(SHShaderBlockInterface&& rhs) noexcept; SHShaderBlockInterface& operator=(SHShaderBlockInterface&& rhs) noexcept;