From 5f305f96090a8290ec3eaeed54e1f983c7296ca9 Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Tue, 20 Sep 2022 18:13:13 +0800 Subject: [PATCH 01/26] Added SHTextureLibrary stub --- .../MiddleEnd/Textures/SHTextureLibrary.cpp | 41 +++++ .../MiddleEnd/Textures/SHTextureLibrary.h | 142 ++++++++++++++++++ 2 files changed, 183 insertions(+) create mode 100644 SHADE_Engine/src/Graphics/MiddleEnd/Textures/SHTextureLibrary.cpp create mode 100644 SHADE_Engine/src/Graphics/MiddleEnd/Textures/SHTextureLibrary.h diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Textures/SHTextureLibrary.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Textures/SHTextureLibrary.cpp new file mode 100644 index 00000000..97b72977 --- /dev/null +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Textures/SHTextureLibrary.cpp @@ -0,0 +1,41 @@ +/************************************************************************************//*! +\file SHTextureLibrary.cpp +\author Tng Kah Wei, kahwei.tng, 390009620 +\par email: kahwei.tng\@digipen.edu +\date Sep 20, 2022 +\brief Contains definitions for all of the functions of the classes that deal + with storage and management of buffers for textures. + +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 "SHTextureLibrary.h" + +#include "Graphics/Devices/SHVkLogicalDevice.h" +#include "Graphics/Buffers/SHVkBuffer.h" +#include "Graphics/Commands/SHVkCommandBuffer.h" +#include "Graphics/SHVkUtil.h" + +namespace SHADE +{ + /*-----------------------------------------------------------------------------*/ + /* Usage Functions */ + /*-----------------------------------------------------------------------------*/ + Handle SHTextureLibrary::Add(uint32_t pixelCount, const SHTexture::PixelChannel* const pixelData) + { + return {}; + } + + void SHTextureLibrary::Remove(Handle mesh) + { + + } + + void SHTextureLibrary::BuildBuffers(Handle device, Handle cmdBuffer) + { + + } + +} diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Textures/SHTextureLibrary.h b/SHADE_Engine/src/Graphics/MiddleEnd/Textures/SHTextureLibrary.h new file mode 100644 index 00000000..a0167cba --- /dev/null +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Textures/SHTextureLibrary.h @@ -0,0 +1,142 @@ +/************************************************************************************//*! +\file SHTextureLibrary.h +\author Tng Kah Wei, kahwei.tng, 390009620 +\par email: kahwei.tng\@digipen.edu +\date Sep 20, 2022 +\brief Contains definitions for all of the classes that deal with storage and + management of textures. + +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 "Math/SHMath.h" + +namespace SHADE +{ + /*---------------------------------------------------------------------------------*/ + /* Forward Declarations */ + /*---------------------------------------------------------------------------------*/ + class SHVkBuffer; + class SHVkLogicalDevice; + class SHVkCommandBuffer; + + /*---------------------------------------------------------------------------------*/ + /* Type Definitions */ + /*---------------------------------------------------------------------------------*/ + class SHTexture + { + public: + /*-----------------------------------------------------------------------------*/ + /* Type Definitions */ + /*-----------------------------------------------------------------------------*/ + using PixelChannel = uint8_t; + + /*-----------------------------------------------------------------------------*/ + /* Data Members */ + /*-----------------------------------------------------------------------------*/ + }; + /***********************************************************************************/ + /*! + \brief + Manages storage for all textures in the Graphics System as a single set of + textures. + */ + /***********************************************************************************/ + class SHTextureLibrary + { + public: + /*-----------------------------------------------------------------------------*/ + /* Usage Functions */ + /*-----------------------------------------------------------------------------*/ + /*******************************************************************************/ + /*! + + \brief + Adds a texture to the Texture Library. But this does not mean that the + textures have been added yet. A call to "BuildBuffers()" is required to + transfer all textures into the GPU. + + \param pixelCount + Number of pixels in this Mesh. + \param positions + Pointer to the first in a contiguous array of SHMathVec3s that define vertex + positions. + + \return + Handle to the created Texture. This is not valid to be used until a call to + BuildBuffers(). + + */ + /*******************************************************************************/ + Handle Add(uint32_t pixelCount, const SHTexture::PixelChannel* const pixelData); + /*******************************************************************************/ + /*! + + \brief + Removes a mesh from the Texture Library. But this does not mean that the + textures have been removed yet. A call to "BuildBuffers()" is required to + finalise all changes. + + \param mesh + Handle to the mesh to remove. + + */ + /*******************************************************************************/ + void Remove(Handle mesh); + /***************************************************************************/ + /*! + + \brief + Finalises all changes to the Texture Library 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 GetTextureBuffer() const noexcept { return texStorageBuffer; } + + private: + /*-----------------------------------------------------------------------------*/ + /* Type Definition */ + /*-----------------------------------------------------------------------------*/ + struct AddJob + { + uint32_t PixelCount = 0; + const SHTexture::PixelChannel* PixelData = nullptr; + Handle Handle; + }; + /*-----------------------------------------------------------------------------*/ + /* Data Members */ + /*-----------------------------------------------------------------------------*/ + // Manipulation Queues + std::vector addJobs; + std::vector> removeJobs; + // Tracking + ResourceLibrary textures{}; + std::vector> texOrder; + // CPU Storage + std::vector texStorage; + // GPU Storage + Handle texStorageBuffer{}; + // Flags + bool isDirty = true; + }; +} From 3d9abcf19ca550e3f850e9e232af76b5dd73ac07 Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Thu, 22 Sep 2022 09:19:18 +0800 Subject: [PATCH 02/26] Implemented image creation for textures in the texture bank --- SHADE_Engine/SHADE_Engine.vcxproj | 34 +++++ SHADE_Engine/SHADE_Engine.vcxproj.filters | 143 +++++++++++++++++- .../Graphics/Commands/SHVkCommandBuffer.cpp | 63 ++++---- .../src/Graphics/Commands/SHVkCommandBuffer.h | 6 +- .../src/Graphics/Images/SHVkImage.cpp | 33 +--- SHADE_Engine/src/Graphics/Images/SHVkImage.h | 4 +- .../MiddleEnd/Textures/SHTextureLibrary.cpp | 115 +++++++++++++- .../MiddleEnd/Textures/SHTextureLibrary.h | 35 +++-- SHADE_Engine/src/Math/SHMath.h | 2 +- 9 files changed, 350 insertions(+), 85 deletions(-) diff --git a/SHADE_Engine/SHADE_Engine.vcxproj b/SHADE_Engine/SHADE_Engine.vcxproj index 37ddf8f5..2aa3b608 100644 --- a/SHADE_Engine/SHADE_Engine.vcxproj +++ b/SHADE_Engine/SHADE_Engine.vcxproj @@ -138,6 +138,7 @@ xcopy /s /r /y /q "$(SolutionDir)/Dependencies/dotnet/bin" "$(OutDir)" + @@ -167,13 +168,31 @@ xcopy /s /r /y /q "$(SolutionDir)/Dependencies/dotnet/bin" "$(OutDir)" + + + + + + + + + + + + + + + + + + @@ -250,6 +269,7 @@ xcopy /s /r /y /q "$(SolutionDir)/Dependencies/dotnet/bin" "$(OutDir)" + @@ -273,12 +293,26 @@ xcopy /s /r /y /q "$(SolutionDir)/Dependencies/dotnet/bin" "$(OutDir)" + + + + + + + + + + + + + + diff --git a/SHADE_Engine/SHADE_Engine.vcxproj.filters b/SHADE_Engine/SHADE_Engine.vcxproj.filters index f52aebb0..74be0df1 100644 --- a/SHADE_Engine/SHADE_Engine.vcxproj.filters +++ b/SHADE_Engine/SHADE_Engine.vcxproj.filters @@ -28,6 +28,9 @@ {078AA1A3-F318-2B6D-9C37-3F6888A53B13} + + {8C1A20B0-78BC-4A86-6177-5EDA4DB8D1D6} + {DBC7D3B0-C769-FE86-B024-12DB9C6585D7} @@ -70,15 +73,30 @@ {4B204703-3704-0859-A064-02AC8C67F2DA} + + {7A02D7B0-E60F-0597-6FF6-0082DB02D14D} + + + {85EFB65D-F107-9E87-BAB4-2D21268C3221} + {EBA1D3FF-D75C-C3AB-8014-3CF66CAE0D3C} + + {1F603FFC-8B22-7386-D4D2-011340D44B64} + {8CDBA7C9-F8E8-D5AF-81CF-D19AEDDBA166} + + {D04C14FB-3C5A-42E1-C540-3ECC314D0E98} + {2460C057-1070-6C28-7929-D14665585BC1} + + {7E76F08B-EA83-1E72-736A-1A5DDF76EA28} + {FBD334F8-67EA-328E-B061-BEAF1CB70316} @@ -121,6 +139,9 @@ {EAD6C33D-5697-3F74-1FD2-88F18B518450} + + {3AB383AD-2681-77B3-0F15-E8D9FB815318} + {F1B75745-5D6D-D03A-E661-CA115216C73E} @@ -207,6 +228,9 @@ ECS_Base\UnitTesting + + Editor + Engine @@ -294,18 +318,69 @@ Graphics\Instance + + Graphics\MiddleEnd\Batching + + + Graphics\MiddleEnd\Batching + + + Graphics\MiddleEnd\Batching + + + Graphics\MiddleEnd\GlobalData + + + Graphics\MiddleEnd\Interface + + + Graphics\MiddleEnd\Interface + Graphics\MiddleEnd\Interface + + Graphics\MiddleEnd\Interface + + + Graphics\MiddleEnd\Interface + + + Graphics\MiddleEnd\Interface + + + Graphics\MiddleEnd\Interface + + + Graphics\MiddleEnd\Interface + Graphics\MiddleEnd\Interface + + Graphics\MiddleEnd\Interface + + + Graphics\MiddleEnd\Interface + + + Graphics\MiddleEnd\Interface + + + Graphics\MiddleEnd\Meshes + + + Graphics\MiddleEnd\Meshes + Graphics\MiddleEnd\PerFrame Graphics\MiddleEnd\PerFrame + + Graphics\MiddleEnd\Pipeline + Graphics\MiddleEnd\Shaders @@ -315,6 +390,9 @@ Graphics\MiddleEnd\Shaders + + Graphics\MiddleEnd\Textures + Graphics\Pipeline @@ -421,7 +499,13 @@ Math - Math + Math\Transform + + + Math\Transform + + + Math\Transform Math\Vector @@ -498,8 +582,6 @@ Tools - - @@ -529,6 +611,9 @@ ECS_Base\UnitTesting + + Editor + Engine @@ -598,24 +683,66 @@ Graphics\Instance + + Graphics\MiddleEnd\Batching + + + Graphics\MiddleEnd\Batching + + + Graphics\MiddleEnd\Batching + + + Graphics\MiddleEnd\GlobalData + + + Graphics\MiddleEnd\Interface + Graphics\MiddleEnd\Interface + + Graphics\MiddleEnd\Interface + + + Graphics\MiddleEnd\Interface + + + Graphics\MiddleEnd\Interface + Graphics\MiddleEnd\Interface + + Graphics\MiddleEnd\Interface + + + Graphics\MiddleEnd\Interface + + + Graphics\MiddleEnd\Interface + + + Graphics\MiddleEnd\Meshes + Graphics\MiddleEnd\PerFrame Graphics\MiddleEnd\PerFrame + + Graphics\MiddleEnd\Pipeline + Graphics\MiddleEnd\Shaders Graphics\MiddleEnd\Shaders + + Graphics\MiddleEnd\Textures + Graphics\Pipeline @@ -698,7 +825,13 @@ Math - Math + Math\Transform + + + Math\Transform + + + Math\Transform Math\Vector @@ -740,7 +873,5 @@ Tools - - \ No newline at end of file diff --git a/SHADE_Engine/src/Graphics/Commands/SHVkCommandBuffer.cpp b/SHADE_Engine/src/Graphics/Commands/SHVkCommandBuffer.cpp index 6898b7e0..cddb6cdb 100644 --- a/SHADE_Engine/src/Graphics/Commands/SHVkCommandBuffer.cpp +++ b/SHADE_Engine/src/Graphics/Commands/SHVkCommandBuffer.cpp @@ -8,6 +8,7 @@ #include "Graphics/Framebuffer/SHVkFramebuffer.h" #include "Graphics/Pipeline/SHVkPipeline.h" #include "Graphics/Buffers/SHVkBuffer.h" +#include "Graphics/Images/SHVkImage.h" #include "Graphics/Descriptors/SHVkDescriptorSetGroup.h" @@ -421,9 +422,42 @@ namespace SHADE vkCommandBuffer.drawIndexed(indexCount, 1, firstIndex, vertexOffset, 0); } + + /***************************************************************************/ + /*! + \brief + Issues a multi indirect draw call. - void SHVkCommandBuffer::PipelineBarrier ( + \param indirectDrawData + SHVkBuffer containing the data for the multi indirect draw call. + \param drawCount + Number of multi indirect draw sub-calls stored in indirectDrawData. + + */ + /***************************************************************************/ + + void SHVkCommandBuffer::DrawMultiIndirect(Handle indirectDrawData, uint32_t drawCount) + { + if (cmdBufferState != SH_CMD_BUFFER_STATE::RECORDING) + { + SHLOG_ERROR("Command buffer must have started recording before a pipeline can be bound."); + return; + } + + vkCommandBuffer.drawIndexedIndirect(indirectDrawData->GetVkBuffer(), 0, drawCount, sizeof(vk::DrawIndexedIndirectCommand)); + } + + void SHVkCommandBuffer::CopyBufferToImage(const vk::Buffer& src, const vk::Image& dst, const std::vector& copyInfo) + { + vkCommandBuffer.copyBufferToImage + ( + src, dst, vk::ImageLayout::eTransferDstOptimal, + static_cast(copyInfo.size()), copyInfo.data() + ); + } + + void SHVkCommandBuffer::PipelineBarrier( vk::PipelineStageFlags srcStage, vk::PipelineStageFlags dstStage, vk::DependencyFlags deps, @@ -457,33 +491,6 @@ namespace SHADE // //vkCommandBuffer.pipelineBarrier() //} - /***************************************************************************/ - /*! - - \brief - Issues a multi indirect draw call. - - \param indirectDrawData - SHVkBuffer containing the data for the multi indirect draw call. - \param drawCount - Number of multi indirect draw sub-calls stored in indirectDrawData. - - */ - /***************************************************************************/ - - void SHVkCommandBuffer::DrawMultiIndirect(Handle indirectDrawData, uint32_t drawCount) - { - if (cmdBufferState != SH_CMD_BUFFER_STATE::RECORDING) - { - SHLOG_ERROR("Command buffer must have started recording before a pipeline can be bound."); - return; - } - - vkCommandBuffer.drawIndexedIndirect(indirectDrawData->GetVkBuffer(), 0, drawCount, sizeof(vk::DrawIndexedIndirectCommand)); - } - - - /***************************************************************************/ /*! diff --git a/SHADE_Engine/src/Graphics/Commands/SHVkCommandBuffer.h b/SHADE_Engine/src/Graphics/Commands/SHVkCommandBuffer.h index d945fce8..f780638a 100644 --- a/SHADE_Engine/src/Graphics/Commands/SHVkCommandBuffer.h +++ b/SHADE_Engine/src/Graphics/Commands/SHVkCommandBuffer.h @@ -15,6 +15,7 @@ namespace SHADE class SHVkFramebuffer; class SHVkPipeline; class SHVkBuffer; + class SHVkImage; class SHVkDescriptorSetGroup; enum class SH_CMD_BUFFER_TYPE @@ -116,6 +117,10 @@ namespace SHADE // Draw Commands void DrawArrays (uint32_t vertexCount, uint32_t instanceCount, uint32_t firstVertex, uint32_t firstInstance) const noexcept; void DrawIndexed (uint32_t indexCount, uint32_t firstIndex, uint32_t vertexOffset) const noexcept; + void DrawMultiIndirect (Handle indirectDrawData, uint32_t drawCount); + + // Buffer Copy + void CopyBufferToImage (const vk::Buffer& src, const vk::Image& dst, const std::vector& copyInfo); // memory barriers void PipelineBarrier ( @@ -129,7 +134,6 @@ namespace SHADE bool IsReadyToSubmit (void) const noexcept; void HandlePostSubmit (void) noexcept; - void DrawMultiIndirect (Handle indirectDrawData, uint32_t drawCount); // Push Constant variable setting template diff --git a/SHADE_Engine/src/Graphics/Images/SHVkImage.cpp b/SHADE_Engine/src/Graphics/Images/SHVkImage.cpp index 6ec1c9f2..b8bf273e 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(void) noexcept + void SHVkImage::TransferToDeviceResource(Handle cmdBufferHdl) noexcept { // prepare copy regions std::vector copyRegions{mipOffsets.size()}; @@ -252,7 +252,7 @@ namespace SHADE copyRegions[i].imageExtent = vk::Extent3D{ width >> i, height >> i, 1 }; } - //PrepareImageTransition(); + cmdBufferHdl->CopyBufferToImage(stagingBuffer, vkImage, copyRegions); } /***************************************************************************/ @@ -274,7 +274,7 @@ namespace SHADE */ /***************************************************************************/ - void SHVkImage::PrepareImageTransition(vk::ImageLayout oldLayout, vk::ImageLayout newLayout, vk::ImageMemoryBarrier& barrier) noexcept + void SHVkImage::PrepareImageTransitionInfo(vk::ImageLayout oldLayout, vk::ImageLayout newLayout, vk::ImageMemoryBarrier& barrier) noexcept { barrier.oldLayout = oldLayout; barrier.newLayout = newLayout; @@ -286,33 +286,6 @@ namespace SHADE barrier.subresourceRange.levelCount = mipLevelCount; barrier.subresourceRange.baseArrayLayer = 0; barrier.subresourceRange.layerCount = layerCount; - - vk::PipelineStageFlagBits srcStage = vk::PipelineStageFlagBits::eTopOfPipe; - vk::PipelineStageFlagBits dstStage = vk::PipelineStageFlagBits::eTopOfPipe; - - if (oldLayout == vk::ImageLayout::eUndefined && newLayout == vk::ImageLayout::eTransferDstOptimal) - { - srcStage = vk::PipelineStageFlagBits::eTopOfPipe; - dstStage = vk::PipelineStageFlagBits::eTransfer; - - barrier.srcAccessMask = vk::AccessFlagBits::eNone; - barrier.dstAccessMask = vk::AccessFlagBits::eTransferWrite; - } - else if (oldLayout == vk::ImageLayout::eTransferDstOptimal && newLayout == vk::ImageLayout::eShaderReadOnlyOptimal) - { - srcStage = vk::PipelineStageFlagBits::eTransfer; - - // TODO, what if we want to access in compute shader - dstStage = vk::PipelineStageFlagBits::eFragmentShader; - - barrier.srcAccessMask = vk::AccessFlagBits::eTransferWrite; - barrier.dstAccessMask = vk::AccessFlagBits::eShaderRead; - } - else - { - SHLOG_ERROR("Image layouts are invalid. "); - } - } void SHVkImage::LinkWithExteriorImage(vk::Image inVkImage, vk::ImageType type, uint32_t inWidth, uint32_t inHeight, uint32_t inDepth, uint32_t layers, uint8_t levels, vk::Format format, vk::ImageUsageFlags flags) noexcept diff --git a/SHADE_Engine/src/Graphics/Images/SHVkImage.h b/SHADE_Engine/src/Graphics/Images/SHVkImage.h index eec8dc7e..91d4f2d2 100644 --- a/SHADE_Engine/src/Graphics/Images/SHVkImage.h +++ b/SHADE_Engine/src/Graphics/Images/SHVkImage.h @@ -135,8 +135,8 @@ namespace SHADE /* PUBLIC MEMBER FUNCTIONS */ /*-----------------------------------------------------------------------*/ Handle CreateImageView (Handle const& inLogicalDeviceHdl, Handle const& parent, SHImageViewDetails const& createParams) const noexcept; - void TransferToDeviceResource (void) noexcept; - void PrepareImageTransition (vk::ImageLayout oldLayout, vk::ImageLayout newLayout, vk::ImageMemoryBarrier& barrier) noexcept; + void TransferToDeviceResource (Handle cmdBufferHdl) noexcept; + void PrepareImageTransitionInfo (vk::ImageLayout oldLayout, vk::ImageLayout newLayout, vk::ImageMemoryBarrier& barrier) noexcept; /*-----------------------------------------------------------------------*/ /* GETTERS AND SETTERS */ diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Textures/SHTextureLibrary.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Textures/SHTextureLibrary.cpp index 97b72977..3be4dd11 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Textures/SHTextureLibrary.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Textures/SHTextureLibrary.cpp @@ -13,29 +13,130 @@ of DigiPen Institute of Technology is prohibited. #include "SHpch.h" #include "SHTextureLibrary.h" +#include "Graphics/SHVulkanIncludes.h" + #include "Graphics/Devices/SHVkLogicalDevice.h" #include "Graphics/Buffers/SHVkBuffer.h" #include "Graphics/Commands/SHVkCommandBuffer.h" #include "Graphics/SHVkUtil.h" +#include "Tools/SHLogger.h" namespace SHADE { - /*-----------------------------------------------------------------------------*/ - /* Usage Functions */ - /*-----------------------------------------------------------------------------*/ - Handle SHTextureLibrary::Add(uint32_t pixelCount, const SHTexture::PixelChannel* const pixelData) + /*---------------------------------------------------------------------------------*/ + /* Usage Functions */ + /*---------------------------------------------------------------------------------*/ + Handle SHTextureLibrary::Add(uint32_t pixelCount, const SHTexture::PixelChannel* const pixelData, SHTexture::TextureFormat format, int mipLevels) { - return {}; + isDirty = true; + + auto handle = resourceManager.Create(); + addJobs.emplace_back(AddJob { pixelCount, pixelData, format, mipLevels }); + return handle; } - void SHTextureLibrary::Remove(Handle mesh) + void SHTextureLibrary::Remove(Handle texture) { + if (!texture) + throw std::invalid_argument("Attempted to remove a Texture that did not belong to the Texture Library!"); + removeJobs.emplace_back(texture); + isDirty = true; } - void SHTextureLibrary::BuildBuffers(Handle device, Handle cmdBuffer) + void SHTextureLibrary::BuildImages(Handle device, Handle cmdBuffer, Handle graphicsQueue, Handle descPool, Handle descLayout) { + /* Remove Textures */ + std::vector pipelineBarriers(addJobs.size()); + /* Add Textures */ + // Transition + for (int i = 0; auto& job : addJobs) + { + job.Image = resourceManager.Create(); + job.Image->PrepareImageTransitionInfo(vk::ImageLayout::eUndefined, vk::ImageLayout::eTransferDstOptimal, pipelineBarriers[i]); + ++i; + } + vk::PipelineStageFlagBits srcStage = vk::PipelineStageFlagBits::eTopOfPipe; + vk::PipelineStageFlagBits dstStage = vk::PipelineStageFlagBits::eTopOfPipe; + preparePipelineBarriers(vk::ImageLayout::eUndefined, vk::ImageLayout::eTransferDstOptimal, srcStage, dstStage, pipelineBarriers); + cmdBuffer->PipelineBarrier(vk::PipelineStageFlagBits::eTopOfPipe, vk::PipelineStageFlagBits::eTransfer, {}, {}, {}, pipelineBarriers); + + // Copy + for (auto& job : addJobs) + { + job.Image->TransferToDeviceResource(cmdBuffer); + } + + // Transition + for (int i = 0; auto & job : addJobs) + { + // Transition + job.Image->PrepareImageTransitionInfo(vk::ImageLayout::eTransferDstOptimal, vk::ImageLayout::eShaderReadOnlyOptimal, pipelineBarriers[i]); + } + preparePipelineBarriers(vk::ImageLayout::eTransferDstOptimal, vk::ImageLayout::eShaderReadOnlyOptimal, srcStage, dstStage, pipelineBarriers); + cmdBuffer->PipelineBarrier(vk::PipelineStageFlagBits::eTopOfPipe, vk::PipelineStageFlagBits::eTransfer, {}, {}, {}, pipelineBarriers); + + // Execute Commands + graphicsQueue->SubmitCommandBuffer({ cmdBuffer }); + device->WaitIdle(); + + // Create Image View + for (auto& job : addJobs) + { + const SHImageViewDetails DETAILS + { + .viewType = vk::ImageViewType::e2D, + .format = job.TextureFormat, + .imageAspectFlags = vk::ImageAspectFlagBits::eColor, + .baseMipLevel = 0, + .mipLevelCount = job.MipLevels, + .baseArrayLayer = 0, + .layerCount = 0 + }; + job.Handle->ImageView = job.Image->CreateImageView(device, job.Image, DETAILS); + } + + // Build Descriptor + Handle descSetGroup = descPool->Allocate({ descLayout }, { 1 }).front(); + + + isDirty = false; + } + + /*---------------------------------------------------------------------------------*/ + /* Usage Functions */ + /*---------------------------------------------------------------------------------*/ + void SHTextureLibrary::preparePipelineBarriers(vk::ImageLayout oldLayout, vk::ImageLayout newLayout, vk::PipelineStageFlagBits& srcStage, vk::PipelineStageFlagBits& dstStage, std::vector& barriers) + { + if (oldLayout == vk::ImageLayout::eUndefined && newLayout == vk::ImageLayout::eTransferDstOptimal) + { + srcStage = vk::PipelineStageFlagBits::eTopOfPipe; + dstStage = vk::PipelineStageFlagBits::eTransfer; + + for (auto& barrier : barriers) + { + barrier.srcAccessMask = vk::AccessFlagBits::eNone; + barrier.dstAccessMask = vk::AccessFlagBits::eTransferWrite; + } + } + else if (oldLayout == vk::ImageLayout::eTransferDstOptimal && newLayout == vk::ImageLayout::eShaderReadOnlyOptimal) + { + srcStage = vk::PipelineStageFlagBits::eTransfer; + + // TODO, what if we want to access in compute shader + dstStage = vk::PipelineStageFlagBits::eFragmentShader; + + for (auto& barrier : barriers) + { + barrier.srcAccessMask = vk::AccessFlagBits::eTransferWrite; + barrier.dstAccessMask = vk::AccessFlagBits::eShaderRead; + } + } + else + { + SHLOG_ERROR("Image layouts are invalid. "); + } } } diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Textures/SHTextureLibrary.h b/SHADE_Engine/src/Graphics/MiddleEnd/Textures/SHTextureLibrary.h index a0167cba..d30b02ed 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Textures/SHTextureLibrary.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Textures/SHTextureLibrary.h @@ -37,11 +37,15 @@ namespace SHADE /*-----------------------------------------------------------------------------*/ /* Type Definitions */ /*-----------------------------------------------------------------------------*/ - using PixelChannel = uint8_t; + using PixelChannel = void; + using TextureFormat = vk::Format; // TODO: Change + using Index = uint32_t; /*-----------------------------------------------------------------------------*/ /* Data Members */ /*-----------------------------------------------------------------------------*/ + Handle ImageView; + Index TextureArrayIndex = std::numeric_limits::max(); }; /***********************************************************************************/ /*! @@ -61,7 +65,7 @@ namespace SHADE \brief Adds a texture to the Texture Library. But this does not mean that the - textures have been added yet. A call to "BuildBuffers()" is required to + textures have been added yet. A call to "BuildImages()" is required to transfer all textures into the GPU. \param pixelCount @@ -69,20 +73,22 @@ namespace SHADE \param positions Pointer to the first in a contiguous array of SHMathVec3s that define vertex positions. + \param format + Format of the texture loaded in. \return Handle to the created Texture. This is not valid to be used until a call to - BuildBuffers(). + BuildImages(). */ /*******************************************************************************/ - Handle Add(uint32_t pixelCount, const SHTexture::PixelChannel* const pixelData); + Handle Add(uint32_t pixelCount, const SHTexture::PixelChannel* const pixelData, SHTexture::TextureFormat format, int mipLevels); /*******************************************************************************/ /*! \brief Removes a mesh from the Texture Library. But this does not mean that the - textures have been removed yet. A call to "BuildBuffers()" is required to + textures have been removed yet. A call to "BuildImages()" is required to finalise all changes. \param mesh @@ -106,7 +112,7 @@ namespace SHADE queue. */ /***************************************************************************/ - void BuildBuffers(Handle device, Handle cmdBuffer); + void BuildImages(Handle device, Handle cmdBuffer, Handle graphicsQueue); /*-----------------------------------------------------------------------------*/ /* Getter Functions */ @@ -119,10 +125,14 @@ namespace SHADE /*-----------------------------------------------------------------------------*/ struct AddJob { - uint32_t PixelCount = 0; - const SHTexture::PixelChannel* PixelData = nullptr; - Handle Handle; + uint32_t PixelCount = 0; + const SHTexture::PixelChannel* PixelData = nullptr; + SHTexture::TextureFormat TextureFormat = {}; + int MipLevels = 0; + Handle Image; + Handle Handle; }; + /*-----------------------------------------------------------------------------*/ /* Data Members */ /*-----------------------------------------------------------------------------*/ @@ -130,7 +140,7 @@ namespace SHADE std::vector addJobs; std::vector> removeJobs; // Tracking - ResourceLibrary textures{}; + ResourceManager resourceManager; std::vector> texOrder; // CPU Storage std::vector texStorage; @@ -138,5 +148,10 @@ namespace SHADE Handle texStorageBuffer{}; // Flags bool isDirty = true; + + /*-----------------------------------------------------------------------------*/ + /* Helper Functions */ + /*-----------------------------------------------------------------------------*/ + void preparePipelineBarriers(vk::ImageLayout oldLayout, vk::ImageLayout newLayout, vk::PipelineStageFlagBits& srcStage, vk::PipelineStageFlagBits& dstStage, std::vector& barriers); }; } diff --git a/SHADE_Engine/src/Math/SHMath.h b/SHADE_Engine/src/Math/SHMath.h index 55bf73a9..5fcea9fc 100644 --- a/SHADE_Engine/src/Math/SHMath.h +++ b/SHADE_Engine/src/Math/SHMath.h @@ -9,4 +9,4 @@ #include "SHQuaternion.h" #include "SHMatrix.h" -#include "SHTransform.h" \ No newline at end of file +#include "Transform/SHTransform.h" \ No newline at end of file From ba181eb9c908ec63cf55bdaf543f77479832d451 Mon Sep 17 00:00:00 2001 From: Brandon Mak Date: Thu, 22 Sep 2022 09:23:40 +0800 Subject: [PATCH 03/26] Shifted Command buffers outside of render graph Command buffers now exist in renderer instead Graphics system that calls the renderer, begins and ends the renderer recording in it's main loop as well --- SHADE_Engine/SHADE_Engine.vcxproj | 34 +++++ SHADE_Engine/SHADE_Engine.vcxproj.filters | 143 +++++++++++++++++- .../Descriptors/SHVkDescriptorPool.cpp | 5 +- .../Graphics/Descriptors/SHVkDescriptorPool.h | 2 +- .../MiddleEnd/Interface/SHGraphicsSystem.cpp | 36 ++++- .../MiddleEnd/Interface/SHRenderer.cpp | 21 ++- .../Graphics/MiddleEnd/Interface/SHRenderer.h | 12 +- .../MiddleEnd/Interface/SHViewport.cpp | 4 +- .../Graphics/MiddleEnd/Interface/SHViewport.h | 3 +- .../Graphics/RenderGraph/SHRenderGraph.cpp | 44 +----- .../src/Graphics/RenderGraph/SHRenderGraph.h | 12 +- SHADE_Engine/src/Math/SHMath.h | 2 +- 12 files changed, 239 insertions(+), 79 deletions(-) diff --git a/SHADE_Engine/SHADE_Engine.vcxproj b/SHADE_Engine/SHADE_Engine.vcxproj index 37ddf8f5..2aa3b608 100644 --- a/SHADE_Engine/SHADE_Engine.vcxproj +++ b/SHADE_Engine/SHADE_Engine.vcxproj @@ -138,6 +138,7 @@ xcopy /s /r /y /q "$(SolutionDir)/Dependencies/dotnet/bin" "$(OutDir)" + @@ -167,13 +168,31 @@ xcopy /s /r /y /q "$(SolutionDir)/Dependencies/dotnet/bin" "$(OutDir)" + + + + + + + + + + + + + + + + + + @@ -250,6 +269,7 @@ xcopy /s /r /y /q "$(SolutionDir)/Dependencies/dotnet/bin" "$(OutDir)" + @@ -273,12 +293,26 @@ xcopy /s /r /y /q "$(SolutionDir)/Dependencies/dotnet/bin" "$(OutDir)" + + + + + + + + + + + + + + diff --git a/SHADE_Engine/SHADE_Engine.vcxproj.filters b/SHADE_Engine/SHADE_Engine.vcxproj.filters index f52aebb0..74be0df1 100644 --- a/SHADE_Engine/SHADE_Engine.vcxproj.filters +++ b/SHADE_Engine/SHADE_Engine.vcxproj.filters @@ -28,6 +28,9 @@ {078AA1A3-F318-2B6D-9C37-3F6888A53B13} + + {8C1A20B0-78BC-4A86-6177-5EDA4DB8D1D6} + {DBC7D3B0-C769-FE86-B024-12DB9C6585D7} @@ -70,15 +73,30 @@ {4B204703-3704-0859-A064-02AC8C67F2DA} + + {7A02D7B0-E60F-0597-6FF6-0082DB02D14D} + + + {85EFB65D-F107-9E87-BAB4-2D21268C3221} + {EBA1D3FF-D75C-C3AB-8014-3CF66CAE0D3C} + + {1F603FFC-8B22-7386-D4D2-011340D44B64} + {8CDBA7C9-F8E8-D5AF-81CF-D19AEDDBA166} + + {D04C14FB-3C5A-42E1-C540-3ECC314D0E98} + {2460C057-1070-6C28-7929-D14665585BC1} + + {7E76F08B-EA83-1E72-736A-1A5DDF76EA28} + {FBD334F8-67EA-328E-B061-BEAF1CB70316} @@ -121,6 +139,9 @@ {EAD6C33D-5697-3F74-1FD2-88F18B518450} + + {3AB383AD-2681-77B3-0F15-E8D9FB815318} + {F1B75745-5D6D-D03A-E661-CA115216C73E} @@ -207,6 +228,9 @@ ECS_Base\UnitTesting + + Editor + Engine @@ -294,18 +318,69 @@ Graphics\Instance + + Graphics\MiddleEnd\Batching + + + Graphics\MiddleEnd\Batching + + + Graphics\MiddleEnd\Batching + + + Graphics\MiddleEnd\GlobalData + + + Graphics\MiddleEnd\Interface + + + Graphics\MiddleEnd\Interface + Graphics\MiddleEnd\Interface + + Graphics\MiddleEnd\Interface + + + Graphics\MiddleEnd\Interface + + + Graphics\MiddleEnd\Interface + + + Graphics\MiddleEnd\Interface + + + Graphics\MiddleEnd\Interface + Graphics\MiddleEnd\Interface + + Graphics\MiddleEnd\Interface + + + Graphics\MiddleEnd\Interface + + + Graphics\MiddleEnd\Interface + + + Graphics\MiddleEnd\Meshes + + + Graphics\MiddleEnd\Meshes + Graphics\MiddleEnd\PerFrame Graphics\MiddleEnd\PerFrame + + Graphics\MiddleEnd\Pipeline + Graphics\MiddleEnd\Shaders @@ -315,6 +390,9 @@ Graphics\MiddleEnd\Shaders + + Graphics\MiddleEnd\Textures + Graphics\Pipeline @@ -421,7 +499,13 @@ Math - Math + Math\Transform + + + Math\Transform + + + Math\Transform Math\Vector @@ -498,8 +582,6 @@ Tools - - @@ -529,6 +611,9 @@ ECS_Base\UnitTesting + + Editor + Engine @@ -598,24 +683,66 @@ Graphics\Instance + + Graphics\MiddleEnd\Batching + + + Graphics\MiddleEnd\Batching + + + Graphics\MiddleEnd\Batching + + + Graphics\MiddleEnd\GlobalData + + + Graphics\MiddleEnd\Interface + Graphics\MiddleEnd\Interface + + Graphics\MiddleEnd\Interface + + + Graphics\MiddleEnd\Interface + + + Graphics\MiddleEnd\Interface + Graphics\MiddleEnd\Interface + + Graphics\MiddleEnd\Interface + + + Graphics\MiddleEnd\Interface + + + Graphics\MiddleEnd\Interface + + + Graphics\MiddleEnd\Meshes + Graphics\MiddleEnd\PerFrame Graphics\MiddleEnd\PerFrame + + Graphics\MiddleEnd\Pipeline + Graphics\MiddleEnd\Shaders Graphics\MiddleEnd\Shaders + + Graphics\MiddleEnd\Textures + Graphics\Pipeline @@ -698,7 +825,13 @@ Math - Math + Math\Transform + + + Math\Transform + + + Math\Transform Math\Vector @@ -740,7 +873,5 @@ Tools - - \ No newline at end of file diff --git a/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorPool.cpp b/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorPool.cpp index 77663ab8..6b770c3d 100644 --- a/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorPool.cpp +++ b/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorPool.cpp @@ -50,9 +50,8 @@ namespace SHADE return *this; } - std::vector> SHVkDescriptorPool::Allocate(const std::vector>& layouts, std::vector const& variableDescCounts) + Handle SHVkDescriptorPool::Allocate(const std::vector>& layouts, std::vector const& variableDescCounts) { - SHVkInstance::GetResourceManager().Create(device, GetHandle(), layouts, variableDescCounts); - return {}; + return SHVkInstance::GetResourceManager().Create(device, GetHandle(), layouts, variableDescCounts); } } diff --git a/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorPool.h b/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorPool.h index 9314d940..b862ec09 100644 --- a/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorPool.h +++ b/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorPool.h @@ -101,7 +101,7 @@ namespace SHADE /// Handles to the created Descriptor Sets. If this DescriptorPool has run out of /// space, lesser number of Handles will be returned. /// - std::vector> Allocate(const std::vector>& layouts, std::vector const& variableDescCounts); + Handle Allocate(const std::vector>& layouts, std::vector const& variableDescCounts); private: /*-----------------------------------------------------------------------------*/ diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp index 1130a02b..b38fa275 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp @@ -29,6 +29,7 @@ of DigiPen Institute of Technology is prohibited. #include "Graphics/MiddleEnd/Batching/SHSuperBatch.h" #include "SHGraphicsConstants.h" #include "Graphics/MiddleEnd/GlobalData/SHGraphicsGlobalData.h" +#include "Graphics/Buffers/SHVkBuffer.h" namespace SHADE { @@ -129,7 +130,7 @@ namespace SHADE } // Initialize world render graph - worldRenderGraph->Init(device, swapchain, renderContextCmdPools, globalData); + worldRenderGraph->Init(device, swapchain, globalData); //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); @@ -167,7 +168,7 @@ namespace SHADE debugWorldRenderer->SetCamera(worldCamera);*/ // Add world renderer to default viewport - worldRenderer = defaultViewport->AddRenderer(resourceManager, swapchain->GetNumImages(), descPool, globalData->GetDescSetLayouts()[SHGraphicsConstants::DescriptorSetIndex::HIGH_FREQUENCY_GLOBALS], worldRenderGraph); + worldRenderer = defaultViewport->AddRenderer(resourceManager, swapchain->GetNumImages(), renderContextCmdPools, descPool, globalData->GetDescSetLayouts()[SHGraphicsConstants::DescriptorSetIndex::HIGH_FREQUENCY_GLOBALS], worldRenderGraph); worldRenderer->SetCamera(worldCamera); @@ -228,16 +229,37 @@ namespace SHADE // For every renderer for (int renIndex = 0; renIndex < static_cast(renderers.size()); ++renIndex) { - // Draw first - renderers[renIndex]->Draw(renderContext.GetCurrentFrame(), MESH_DATA); + /*-----------------------------------------------------------------------*/ + /* Renderer start */ + /*-----------------------------------------------------------------------*/ + // get command buffer of the renderer in the current frame + auto currentCmdBuffer = renderers[renIndex]->GetCommandBuffer(renderContext.GetCurrentFrame()); - // get render graph - auto rg = renderers[renIndex]->GetRenderGraph(); + // Begin recording the command buffer + currentCmdBuffer->BeginRecording(); + + // Bind all the buffers required for meshes + for (auto& [buffer, bindingPoint] : MESH_DATA) + { + if (buffer->GetUsageBits() & vk::BufferUsageFlagBits::eVertexBuffer) + currentCmdBuffer->BindVertexBuffer(bindingPoint, buffer, 0); + else if (buffer->GetUsageBits() & vk::BufferUsageFlagBits::eIndexBuffer) + currentCmdBuffer->BindIndexBuffer(buffer, 0); + } + + // Draw first + renderers[renIndex]->Draw(renderContext.GetCurrentFrame()); + + // End the command buffer recording + currentCmdBuffer->EndRecording(); + /*-----------------------------------------------------------------------*/ + /* Renderer end */ + /*-----------------------------------------------------------------------*/ // 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()) }, + { currentCmdBuffer }, { (vpIndex == viewports.size() - 1 && renIndex == renderers.size() - 1) ? frameData.semRenderFinishHdl : graphSemaphores[!semIndex] }, { (vpIndex == 0 && renIndex == 0) ? frameData.semImgAvailableHdl : graphSemaphores[semIndex] }, { vk::PipelineStageFlagBits::eColorAttachmentOutput }, diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderer.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderer.cpp index 90e137fe..223ceb4f 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderer.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderer.cpp @@ -20,20 +20,28 @@ of DigiPen Institute of Technology is prohibited. #include "SHMaterial.h" #include "Graphics/MiddleEnd/Interface/SHGraphicsConstants.h" #include "Graphics/Descriptors/SHVkDescriptorSetGroup.h" +#include "Graphics/Buffers/SHVkBuffer.h" namespace SHADE { /*-----------------------------------------------------------------------------------*/ /* Constructor/Destructors */ /*-----------------------------------------------------------------------------------*/ - SHRenderer::SHRenderer(Handle logicalDevice, uint32_t numFrames, Handle descriptorPool, Handle cameraDescLayout, Handle viewport, Handle renderGraph) + SHRenderer::SHRenderer(Handle logicalDevice, uint32_t numFrames, std::vector>& cmdPools, Handle descriptorPool, Handle cameraDescLayout, Handle viewport, Handle renderGraph) : viewport { viewport } , renderGraph { renderGraph } { - cameraDescriptorSet = logicalDevice->CreateDescriptorSetGroup(descriptorPool, { cameraDescLayout }, { 1 }); + commandBuffers.resize(static_cast(numFrames)); + + for (uint32_t i = 0; i < commandBuffers.size(); ++i) + commandBuffers[i] = cmdPools[i]->RequestCommandBuffer(SH_CMD_BUFFER_TYPE::PRIMARY); + + cameraDescriptorSet = descriptorPool->Allocate({ cameraDescLayout }, { 1 }); cpuCameraData.resize(numFrames); cameraDataAlignedSize = logicalDevice->PadUBOSize(sizeof(SHShaderCameraData)); + + cameraBuffer = logicalDevice->CreateBuffer(cameraDataAlignedSize * numFrames, nullptr, cameraDataAlignedSize * numFrames, vk::BufferUsageFlagBits::eUniformBuffer, VMA_MEMORY_USAGE_AUTO, VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT); } /*-----------------------------------------------------------------------------------*/ @@ -47,9 +55,9 @@ namespace SHADE /*-----------------------------------------------------------------------------------*/ /* Drawing Functions */ /*-----------------------------------------------------------------------------------*/ - void SHRenderer::Draw(uint32_t frameIndex, std::initializer_list, uint32_t>> graphScopeBuffers) noexcept + void SHRenderer::Draw(uint32_t frameIndex) noexcept { - renderGraph->Execute(frameIndex, graphScopeBuffers); + renderGraph->Execute(frameIndex, commandBuffers[frameIndex]); } void SHRenderer::BindDescriptorSet(Handle cmdBuffer, uint32_t frameIndex) noexcept @@ -64,4 +72,9 @@ namespace SHADE return renderGraph; } + Handle SHRenderer::GetCommandBuffer(uint32_t frameIndex) const noexcept + { + return commandBuffers[frameIndex]; + } + } diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderer.h b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderer.h index 843ad6bf..bbb7773b 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderer.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderer.h @@ -39,6 +39,7 @@ namespace SHADE class SHVkDescriptorSetGroup; class SHGraphicsGlobalData; class SHVkDescriptorPool; + class SHVkBuffer; struct SHShaderCameraData { @@ -63,7 +64,7 @@ namespace SHADE /*-----------------------------------------------------------------------------*/ /* Constructor/Destructors */ /*-----------------------------------------------------------------------------*/ - SHRenderer(Handle logicalDevice, uint32_t numFrames, Handle descriptorPool, Handle cameraDescLayout, Handle viewport, Handle renderGraph); + SHRenderer(Handle logicalDevice, uint32_t numFrames, std::vector>& cmdPools, Handle descriptorPool, Handle cameraDescLayout, Handle viewport, Handle renderGraph); /*-----------------------------------------------------------------------------*/ /* Camera Registration */ @@ -73,13 +74,14 @@ namespace SHADE /*-----------------------------------------------------------------------------*/ /* Drawing Functions */ /*-----------------------------------------------------------------------------*/ - void Draw(uint32_t frameIndex, std::initializer_list, uint32_t>> graphScopeBuffers) noexcept; + void Draw(uint32_t frameIndex) noexcept; void BindDescriptorSet (Handle cmdBuffer, uint32_t frameIndex) noexcept; /*-----------------------------------------------------------------------------*/ /* Setters and Getters */ /*-----------------------------------------------------------------------------*/ Handle GetRenderGraph (void) const noexcept; + Handle GetCommandBuffer(uint32_t frameIndex) const noexcept; private: /*-----------------------------------------------------------------------------*/ @@ -92,7 +94,13 @@ namespace SHADE Handle camera; Handle renderGraph; Handle cameraDescriptorSet; + Handle cameraBuffer; std::vector cpuCameraData; + + //! Command buffers for the render graph + std::vector> commandBuffers; + + }; } diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHViewport.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHViewport.cpp index 1e38acf1..25c5bca2 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHViewport.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHViewport.cpp @@ -49,10 +49,10 @@ namespace SHADE /*---------------------------------------------------------------------------------*/ /* Renderer Registration Functions */ /*---------------------------------------------------------------------------------*/ - Handle SHViewport::AddRenderer(ResourceManager& resourceManager, uint32_t numFrames, Handle descriptorPool, Handle cameraDescLayout, Handle renderGraph) + Handle SHViewport::AddRenderer(ResourceManager& resourceManager, uint32_t numFrames, std::vector>& cmdPools, Handle descriptorPool, Handle cameraDescLayout, Handle renderGraph) { // Create the renderer - auto renderer = resourceManager.Create(device, numFrames, descriptorPool, cameraDescLayout, GetHandle(), renderGraph); + auto renderer = resourceManager.Create(device, numFrames, cmdPools, descriptorPool, cameraDescLayout, GetHandle(), renderGraph); // Store renderers.emplace_back(renderer); diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHViewport.h b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHViewport.h index 608446a3..d97d62ce 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHViewport.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHViewport.h @@ -32,6 +32,7 @@ namespace SHADE class SHRenderGraph; class SHVkDescriptorPool; class SHVkDescriptorSetLayout; + class SHVkCommandPool; /*---------------------------------------------------------------------------------*/ /* Type Definitions */ @@ -58,7 +59,7 @@ namespace SHADE /*-----------------------------------------------------------------------------*/ /* Renderers Registration Functions */ /*-----------------------------------------------------------------------------*/ - Handle AddRenderer(ResourceManager& resourceManager, uint32_t numFrames, Handle descriptorPool, Handle cameraDescLayout, Handle renderGraph); + Handle AddRenderer(ResourceManager& resourceManager, uint32_t numFrames, std::vector>& cmdPools, Handle descriptorPool, Handle cameraDescLayout, Handle renderGraph); void RemoveRenderer(Handle renderer); /*-----------------------------------------------------------------------------*/ diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp index d7404db2..d02e8f7d 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp @@ -946,25 +946,6 @@ namespace SHADE } } - /***************************************************************************/ - /*! - - \brief - Configures command pools and command buffers. - - */ - /***************************************************************************/ - void SHRenderGraph::ConfigureCommands(void) noexcept - { - //commandPools.resize (static_cast(swapchainHdl->GetNumImages())); - commandBuffers.resize(static_cast(swapchainHdl->GetNumImages())); - - for (uint32_t i = 0; i < commandBuffers.size(); ++i) - { - commandBuffers[i] = commandPools[i]->RequestCommandBuffer(SH_CMD_BUFFER_TYPE::PRIMARY); - } - } - /***************************************************************************/ /*! @@ -980,12 +961,11 @@ namespace SHADE */ /***************************************************************************/ - void SHRenderGraph::Init(Handle const& logicalDevice, Handle const& swapchain, std::vector> const& cmdPools, Handle inGlobalData) noexcept + void SHRenderGraph::Init(Handle const& logicalDevice, Handle const& swapchain, Handle inGlobalData) noexcept { logicalDeviceHdl = logicalDevice; swapchainHdl = swapchain; globalData = inGlobalData; - commandPools = cmdPools; } /***************************************************************************/ @@ -1087,33 +1067,17 @@ namespace SHADE ConfigureSubpasses(); ConfigureRenderpasses(); ConfigureFramebuffers(); - ConfigureCommands(); } // TODO: The graph scope buffers were meant to bind vertex buffers and index buffers for meshes. Find a // better way to manage these - void SHRenderGraph::Execute(uint32_t frameIndex, std::initializer_list, uint32_t>> graphScopeBuffers) noexcept + void SHRenderGraph::Execute(uint32_t frameIndex, Handle cmdBuffer) noexcept { - //commandPools[frameIndex]->Reset(); - - auto& cmdBuffer = commandBuffers[frameIndex]; - cmdBuffer->BeginRecording(); - // TODO: DON'T HARDCODE THIS cmdBuffer->SetViewportScissor(1920.0f, 1080.0f, 1920, 1080); - for (auto& [buffer, bindingPoint]: graphScopeBuffers) - { - if (buffer->GetUsageBits() & vk::BufferUsageFlagBits::eVertexBuffer) - cmdBuffer->BindVertexBuffer(bindingPoint, buffer, 0); - else if (buffer->GetUsageBits() & vk::BufferUsageFlagBits::eIndexBuffer) - cmdBuffer->BindIndexBuffer(buffer, 0); - } - for (auto& node : nodes) node->Execute(cmdBuffer, frameIndex); - - cmdBuffer->EndRecording(); } void SHRenderGraph::FinaliseBatch() @@ -1132,9 +1096,5 @@ namespace SHADE return {}; } - Handle const& SHRenderGraph::GetCommandBuffer(uint32_t frameIndex) const noexcept - { - return commandBuffers[frameIndex]; - } } \ No newline at end of file diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.h b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.h index 0ecda65a..cbb9586d 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.h +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.h @@ -250,7 +250,6 @@ namespace SHADE void ConfigureSubpasses (void) noexcept; void ConfigureRenderpasses (void) noexcept; void ConfigureFramebuffers (void) noexcept; - void ConfigureCommands (void) noexcept; /*-----------------------------------------------------------------------*/ /* PRIVATE MEMBER VARIABLES */ @@ -271,12 +270,6 @@ namespace SHADE //! Resource library for graph handles ResourceManager resourceManager; - - //! Command pool for the render graph. DO NOT RESET OR FREE THESE, THEY ARE NON-OWNING. TODO: If application is multithreaded, we need more pools. - std::vector> commandPools; - - //! Command buffers for the render graph - std::vector> commandBuffers; //! Handle to global data Handle globalData; @@ -290,18 +283,17 @@ namespace SHADE /*-----------------------------------------------------------------------*/ /* PUBLIC MEMBER FUNCTIONS */ /*-----------------------------------------------------------------------*/ - void Init (Handle const& logicalDevice, Handle const& swapchain, std::vector> const& cmdPools, Handle inGlobalData) noexcept; + void Init (Handle const& logicalDevice, Handle const& swapchain, Handle inGlobalData) noexcept; void AddResource (std::string resourceName, SH_ATT_DESC_TYPE type, uint32_t w = static_cast(-1), uint32_t h = static_cast(-1), vk::Format format = vk::Format::eB8G8R8A8Unorm, uint8_t levels = 1, vk::ImageCreateFlagBits createFlags = {}); Handle AddNode (std::string nodeName, std::initializer_list resourceNames, std::initializer_list predecessorNodes) noexcept; void Generate (void) noexcept; - void Execute (uint32_t frameIndex, std::initializer_list, uint32_t>> graphScopeBuffers) noexcept; + void Execute (uint32_t frameIndex, Handle cmdBuffer) noexcept; void FinaliseBatch(); /*-----------------------------------------------------------------------*/ /* SETTERS AND GETTERS */ /*-----------------------------------------------------------------------*/ Handle GetNode (std::string const& nodeName) const noexcept; - Handle const& GetCommandBuffer (uint32_t frameIndex) const noexcept; }; } diff --git a/SHADE_Engine/src/Math/SHMath.h b/SHADE_Engine/src/Math/SHMath.h index 55bf73a9..5fcea9fc 100644 --- a/SHADE_Engine/src/Math/SHMath.h +++ b/SHADE_Engine/src/Math/SHMath.h @@ -9,4 +9,4 @@ #include "SHQuaternion.h" #include "SHMatrix.h" -#include "SHTransform.h" \ No newline at end of file +#include "Transform/SHTransform.h" \ No newline at end of file From 7ddf665460b326c3872338da35ec8e8051cb83ff Mon Sep 17 00:00:00 2001 From: Brandon Mak Date: Thu, 22 Sep 2022 12:12:44 +0800 Subject: [PATCH 04/26] Updated Descriptor sets Descriptor set layouts now have set index stored in them It should be noted that when passed into a pipeline layout as global descriptor sets, these don't matter since the pipeline layout will use these in the order that they are passed in. --- .../Descriptors/SHDescriptorSetUpdater.cpp | 22 ---- .../Descriptors/SHDescriptorSetUpdater.h | 6 -- .../Descriptors/SHVkDescriptorSetGroup.cpp | 102 +++++++++++++----- .../Descriptors/SHVkDescriptorSetGroup.h | 22 +++- .../Descriptors/SHVkDescriptorSetLayout.cpp | 10 +- .../Descriptors/SHVkDescriptorSetLayout.h | 4 +- .../Graphics/Devices/SHVkLogicalDevice.cpp | 4 +- .../src/Graphics/Devices/SHVkLogicalDevice.h | 2 +- .../src/Graphics/Images/SHVkSampler.cpp | 5 + .../src/Graphics/Images/SHVkSampler.h | 1 + .../GlobalData/SHGraphicsGlobalData.cpp | 8 +- .../MiddleEnd/Interface/SHGraphicsSystem.cpp | 8 +- .../MiddleEnd/Interface/SHRenderer.cpp | 6 ++ .../Graphics/Pipeline/SHVkPipelineLayout.cpp | 2 +- SHADE_Engine/src/Graphics/SHVkUtil.cpp | 10 ++ SHADE_Engine/src/Graphics/SHVkUtil.h | 2 + SHADE_Engine/src/Graphics/SHVulkanDefines.h | 2 + SHADE_Engine/src/Graphics/SHVulkanIncludes.h | 1 + .../src/Graphics/Shaders/SHShaderReflected.h | 2 - .../ShaderDescriptorDefinitions.glsl | 11 ++ TempShaderFolder/TestCubeVs.glsl | 8 ++ TempShaderFolder/TestCubeVs.spv | Bin 1428 -> 1680 bytes 22 files changed, 163 insertions(+), 75 deletions(-) create mode 100644 TempShaderFolder/ShaderDescriptorDefinitions.glsl diff --git a/SHADE_Engine/src/Graphics/Descriptors/SHDescriptorSetUpdater.cpp b/SHADE_Engine/src/Graphics/Descriptors/SHDescriptorSetUpdater.cpp index a1b1cbc2..6cd7ddfd 100644 --- a/SHADE_Engine/src/Graphics/Descriptors/SHDescriptorSetUpdater.cpp +++ b/SHADE_Engine/src/Graphics/Descriptors/SHDescriptorSetUpdater.cpp @@ -20,23 +20,6 @@ namespace SHADE } - /***************************************************************************/ - /*! - - \brief - Links the write infos to the vulkan write descriptor sets. - - */ - /***************************************************************************/ - void SHDescriptorSetUpdater::LinkInfoToWriteDescSet(void) noexcept - { - for (uint32_t i = 0; i < writeInfos.size(); ++i) - { - writeDescSets[i].pImageInfo = writeInfos[i].descImageInfos.data(); - writeDescSets[i].pBufferInfo = writeInfos[i].descBufferInfos.data(); - writeDescSets[i].pTexelBufferView = writeInfos[i].descTexelBufferInfos.data(); - } - } SHDescriptorWriteInfo& SHDescriptorWriteInfo::operator=(SHDescriptorWriteInfo&& rhs) noexcept { @@ -65,11 +48,6 @@ namespace SHADE } - std::vector const& SHDescriptorSetUpdater::GetWriteDescriptorSets(void) const noexcept - { - return writeDescSets; - } - SHDescriptorSetUpdater& SHDescriptorSetUpdater::operator=(SHDescriptorSetUpdater&& rhs) noexcept { if (&rhs == this) diff --git a/SHADE_Engine/src/Graphics/Descriptors/SHDescriptorSetUpdater.h b/SHADE_Engine/src/Graphics/Descriptors/SHDescriptorSetUpdater.h index 7a5ae967..8595d2a0 100644 --- a/SHADE_Engine/src/Graphics/Descriptors/SHDescriptorSetUpdater.h +++ b/SHADE_Engine/src/Graphics/Descriptors/SHDescriptorSetUpdater.h @@ -41,10 +41,6 @@ namespace SHADE //! When we want to update a write, we need to use this to identify the index of the write. std::unordered_map writeHashMap; - //! We keep this here because we want this to be immediately passable to vkUpdateDescriptorSets - std::vector writeDescSets; - - void LinkInfoToWriteDescSet(void) noexcept; public: SHDescriptorSetUpdater (void) noexcept; @@ -52,8 +48,6 @@ namespace SHADE SHDescriptorSetUpdater& operator= (SHDescriptorSetUpdater&& rhs) noexcept; public: - std::vector const& GetWriteDescriptorSets (void) const noexcept; - friend class SHVkDescriptorSetGroup; }; } diff --git a/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorSetGroup.cpp b/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorSetGroup.cpp index 4e83d319..f579d377 100644 --- a/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorSetGroup.cpp +++ b/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorSetGroup.cpp @@ -7,6 +7,11 @@ #include "Graphics/Devices/SHVkLogicalDevice.h" #include "Graphics/Descriptors/SHVkDescriptorSetLayout.h" #include "Tools/SHLogger.h" +#include "Graphics/Images/SHVkImage.h" +#include "Graphics/Images/SHVkImageView.h" +#include "Graphics/Images/SHVkSampler.h" +#include "Graphics/Buffers/SHVkBuffer.h" +#include "Graphics/SHVkUtil.h" namespace SHADE { @@ -39,6 +44,7 @@ namespace SHADE : device{deviceHdl} , descPool {pool} , descSets{} + , layoutsUsed {layouts} { // Create the layout for each concurrent frame std::vector vkLayouts{ layouts.size() }; @@ -47,6 +53,7 @@ namespace SHADE for (uint32_t i = 0; i < layouts.size(); ++i) { vkLayouts[i] = layouts[i]->GetVkHandle(); + setIndexing.emplace(layouts[i]->GetSetIndex(), i); } // Check for variable descriptor count @@ -73,34 +80,22 @@ namespace SHADE // allocate descriptor sets descSets = device->GetVkLogicalDevice().allocateDescriptorSets(DESC_SET_LAYOUT_CREATE_INFO); - - - // Now we want to prepare the write descriptor sets for writing later. + // Now we want to prepare the write descriptor sets info for writing later. for (uint32_t i = 0; i < layouts.size(); ++i) { auto const& bindings = layouts[i]->GetBindings(); for (auto& binding : bindings) { BindingAndSetHash writeHash = binding.BindPoint; - writeHash |= static_cast(i) << 32; + writeHash |= static_cast(layouts[i]->GetSetIndex()) << 32; // new write for the binding updater.writeInfos.emplace_back(); updater.writeHashMap.try_emplace(writeHash, updater.writeInfos.size() - 1); auto& writeInfo = updater.writeInfos.back(); - updater.writeDescSets.emplace_back(); - auto& writeDescSet = updater.writeDescSets.back(); - - // Initialize info for write - writeDescSet.descriptorType = binding.Type; - writeDescSet.dstArrayElement = 0; - writeDescSet.dstSet = descSets[i]; - writeDescSet.dstBinding = binding.BindPoint; - // Descriptor count for the write descriptor set. Usually this is set to 1, but if binding is variable sized, set to info passed in uint32_t descriptorCount = (binding.flags & vk::DescriptorBindingFlagBits::eVariableDescriptorCount) ? variableDescCounts[i] : 1; - writeDescSet.descriptorCount = descriptorCount; switch (binding.Type) { @@ -114,8 +109,10 @@ namespace SHADE case vk::DescriptorType::eUniformTexelBuffer: case vk::DescriptorType::eStorageTexelBuffer: case vk::DescriptorType::eUniformBuffer: + case vk::DescriptorType::eUniformBufferDynamic: case vk::DescriptorType::eStorageBuffer: - writeInfo.descImageInfos.resize (descriptorCount); + case vk::DescriptorType::eStorageBufferDynamic: + writeInfo.descBufferInfos.resize (descriptorCount); break; //case vk::DescriptorType::eUniformBufferDynamic: // break; @@ -130,8 +127,6 @@ namespace SHADE } } } - // Link all the writeDescSet data for vkUpdateDescriptorSets to write to the linked descriptors - updater.LinkInfoToWriteDescSet(); } /***************************************************************************/ @@ -160,7 +155,7 @@ namespace SHADE */ /***************************************************************************/ - void SHVkDescriptorSetGroup::ModifyWriteDescImage(uint32_t set, uint32_t binding, std::vector> const& imageViewsAndSamplers) noexcept + void SHVkDescriptorSetGroup::ModifyWriteDescImage(uint32_t set, uint32_t binding, std::span, Handle>> const& imageViewsAndSamplers) noexcept { // Find the target writeDescSet BindingAndSetHash writeHash = binding; @@ -176,32 +171,81 @@ namespace SHADE { // write sampler and image view auto& ivs = imageViewsAndSamplers[i]; - writeInfo.descImageInfos[i].imageView = ivs.first; - writeInfo.descImageInfos[i].sampler = ivs.second; + writeInfo.descImageInfos[i].imageView = ivs.first->GetImageView(); + writeInfo.descImageInfos[i].sampler = ivs.second->GetVkSampler(); } } - - void SHVkDescriptorSetGroup::UpdateDescriptorSet(void) noexcept + void SHVkDescriptorSetGroup::ModifyWriteDescBuffer(uint32_t set, uint32_t binding, std::span> const& buffers) noexcept { - device->UpdateDescriptorSets(updater.GetWriteDescriptorSets()); + // Find the target writeDescSet + BindingAndSetHash writeHash = binding; + writeHash |= static_cast(set) << 32; + auto& writeInfo = updater.writeInfos[updater.writeHashMap.at(writeHash)]; + + if (buffers.size() > writeInfo.descBufferInfos.size()) + { + SHLOG_ERROR("Attempting write too many descriptors into descriptor set. Failed to write to vk::WriteDescriptorSet. "); + } + + for (uint32_t i = 0; i < buffers.size(); ++i) + { + // write sampler and image view + auto& buffer = buffers[i]; + writeInfo.descBufferInfos[i].buffer = buffer->GetVkBuffer(); + } + } - - void SHVkDescriptorSetGroup::UpdateSingleDescriptorSetImages(uint32_t set, uint32_t binding) noexcept + void SHVkDescriptorSetGroup::UpdateDescriptorSetImages(uint32_t set, uint32_t binding) noexcept { vk::WriteDescriptorSet writeDescSet{}; + // Get binding + set hash + BindingAndSetHash bsHash = SHVkUtil::GenBindingSetHash(set, binding); + + // to index a set + uint32_t setIndex = setIndexing[bsHash]; + + // to index a write for a binding + uint32_t writeInfoIndex = updater.writeHashMap[bsHash]; + // Initialize info for write - writeDescSet.descriptorType = vk::DescriptorType::eCombinedImageSampler; + writeDescSet.descriptorType = layoutsUsed[setIndex]->GetBindings()[binding].Type; writeDescSet.dstArrayElement = 0; - writeDescSet.dstSet = descSets[set]; + writeDescSet.dstSet = descSets[setIndex]; writeDescSet.dstBinding = binding; - writeDescSet.pImageInfo = updater.writeInfos[set].descImageInfos.data(); - writeDescSet.descriptorCount = static_cast(updater.writeInfos[set].descImageInfos.size()); + writeDescSet.pImageInfo = updater.writeInfos[writeInfoIndex].descImageInfos.data(); + writeDescSet.descriptorCount = static_cast(updater.writeInfos[writeInfoIndex].descImageInfos.size()); device->UpdateDescriptorSet(writeDescSet); } + void SHVkDescriptorSetGroup::UpdateDescriptorSetBuffer(uint32_t set, uint32_t binding) noexcept + { + vk::WriteDescriptorSet writeDescSet{}; + + // Get binding + set hash + BindingAndSetHash bsHash = SHVkUtil::GenBindingSetHash(set, binding); + + // to index a set + uint32_t setIndex = setIndexing[bsHash]; + + // to index a write for a binding + uint32_t writeInfoIndex = updater.writeHashMap[bsHash]; + + // Initialize info for write + writeDescSet.descriptorType = layoutsUsed[setIndex]->GetBindings()[binding].Type; + writeDescSet.dstArrayElement = 0; + writeDescSet.dstSet = descSets[setIndex]; + writeDescSet.dstBinding = binding; + + writeDescSet.pBufferInfo = updater.writeInfos[writeInfoIndex].descBufferInfos.data(); + writeDescSet.descriptorCount = static_cast(updater.writeInfos[writeInfoIndex].descBufferInfos.size()); + + device->UpdateDescriptorSet(writeDescSet); + + } + } \ No newline at end of file diff --git a/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorSetGroup.h b/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorSetGroup.h index b65fb1e6..bc87ff1d 100644 --- a/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorSetGroup.h +++ b/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorSetGroup.h @@ -14,6 +14,10 @@ namespace SHADE class SHVkLogicalDevice; class SHVkDescriptorPool; class SHVkDescriptorSetLayout; + class SHVkSampler; + class SHVkImage; + class SHVkImageView; + class SHVkBuffer; /*---------------------------------------------------------------------------------*/ @@ -54,12 +58,14 @@ namespace SHADE SHVkDescriptorSetGroup& operator=(SHVkDescriptorSetGroup&& rhs) noexcept = default; /*-----------------------------------------------------------------------------*/ - /* Descriptor set writing */ + /* Public member functions */ /*-----------------------------------------------------------------------------*/ - void ModifyWriteDescImage(uint32_t set, uint32_t binding, std::vector> const& imageViewsAndSamplers) noexcept; - void UpdateDescriptorSet(void) noexcept; + void UpdateDescriptorSetImages(uint32_t set, uint32_t binding) noexcept; + void UpdateDescriptorSetBuffer(uint32_t set, uint32_t binding) noexcept; + + void ModifyWriteDescImage(uint32_t set, uint32_t binding, std::span, Handle>> const& imageViewsAndSamplers) noexcept; + void ModifyWriteDescBuffer (uint32_t set, uint32_t binding, std::span> const& buffers) noexcept; - void UpdateSingleDescriptorSetImages(uint32_t set, uint32_t binding) noexcept; /*-----------------------------------------------------------------------------*/ /* Getter Functions */ @@ -81,9 +87,17 @@ namespace SHADE //! Descriptor pool to allocate descriptor sets Handle descPool; + //! Sometimes when we pass in a layout, the set of the layout used in the + //! shader cannot be used to index into descSets. This is to mitigate that issue + //! when we update descriptor sets. + std::unordered_map setIndexing; + //! Descriptor sets std::vector descSets; + //! Layouts used to create this descriptor set group + std::vector> layoutsUsed; + //! for updating descriptor sets. We want to cache this so that we don't create the //! write structs at runtime. SHDescriptorSetUpdater updater; diff --git a/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorSetLayout.cpp b/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorSetLayout.cpp index da1a3645..002aa29d 100644 --- a/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorSetLayout.cpp +++ b/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorSetLayout.cpp @@ -7,9 +7,10 @@ namespace SHADE /*---------------------------------------------------------------------------------*/ /* Constructor/Destructor */ /*---------------------------------------------------------------------------------*/ - SHVkDescriptorSetLayout::SHVkDescriptorSetLayout(Handle device, const std::vector& bindings) + SHVkDescriptorSetLayout::SHVkDescriptorSetLayout(Handle device, SetIndex set, const std::vector& bindings) : device { device } , layoutDesc { bindings } + , setIndex {set} { // Check if auto-binding point calculation configuration is valid bool autoCalc = false; @@ -74,6 +75,7 @@ namespace SHADE : device {rhs.device} , setLayout {rhs.setLayout} , layoutDesc{std::move (rhs.layoutDesc)} + , setIndex {rhs.setIndex} { rhs.setLayout = VK_NULL_HANDLE; } @@ -90,6 +92,11 @@ namespace SHADE return layoutDesc; } + SetIndex SHVkDescriptorSetLayout::GetSetIndex(void) const noexcept + { + return setIndex; + } + SHVkDescriptorSetLayout& SHVkDescriptorSetLayout::operator=(SHVkDescriptorSetLayout&& rhs) noexcept { if (&rhs == this) @@ -98,6 +105,7 @@ namespace SHADE device = rhs.device; setLayout = rhs.setLayout; layoutDesc = std::move(rhs.layoutDesc); + setIndex = rhs.setIndex; rhs.setLayout = VK_NULL_HANDLE; diff --git a/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorSetLayout.h b/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorSetLayout.h index 1acba189..9b436026 100644 --- a/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorSetLayout.h +++ b/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorSetLayout.h @@ -74,7 +74,7 @@ namespace SHADE /// /// /// - SHVkDescriptorSetLayout(Handle device, const std::vector& bindings); + SHVkDescriptorSetLayout(Handle device, SetIndex setIndex, const std::vector& bindings); SHVkDescriptorSetLayout(const SHVkDescriptorSetLayout&) = delete; SHVkDescriptorSetLayout(SHVkDescriptorSetLayout&& rhs) noexcept; /// @@ -97,6 +97,7 @@ namespace SHADE /// Handle to the Vulkan Descriptor Set Layout handle. inline const vk::DescriptorSetLayout& GetVkHandle() const { return setLayout; } std::vector const& GetBindings (void) const noexcept; + SetIndex GetSetIndex (void) const noexcept; private: /*-----------------------------------------------------------------------------*/ @@ -105,5 +106,6 @@ namespace SHADE Handle device; vk::DescriptorSetLayout setLayout; std::vector layoutDesc; // Stores description of the layout + SetIndex setIndex; // Index of the set }; } \ No newline at end of file diff --git a/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.cpp b/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.cpp index a956af2c..64508a2b 100644 --- a/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.cpp +++ b/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.cpp @@ -510,9 +510,9 @@ namespace SHADE } - Handle SHVkLogicalDevice::CreateDescriptorSetLayout(std::vector const& bindings) noexcept + Handle SHVkLogicalDevice::CreateDescriptorSetLayout(SetIndex setIndex, std::vector const& bindings) noexcept { - return SHVkInstance::GetResourceManager().Create (GetHandle(), bindings); + return SHVkInstance::GetResourceManager().Create (GetHandle(), setIndex, bindings); } diff --git a/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.h b/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.h index 6c59572a..365e68c9 100644 --- a/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.h +++ b/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.h @@ -182,7 +182,7 @@ namespace SHADE Handle CreateRenderpass (std::span const vkDescriptions, std::vector const& subpasses) noexcept; Handle CreateRenderpass (std::span const vkDescriptions, std::span const spDescs, std::span const spDeps) noexcept; Handle CreateFramebuffer (Handle const& renderpassHdl, std::vector> const& attachments, uint32_t inWidth, uint32_t inHeight) noexcept; - Handle CreateDescriptorSetLayout (std::vector const& bindings) noexcept; + Handle CreateDescriptorSetLayout (SetIndex setIndex, std::vector const& bindings) noexcept; Handle CreateDescriptorPools (const SHVkDescriptorPool::Config& config = {}) noexcept; Handle CreateDescriptorSetGroup(Handle pool, std::vector> const& layouts, diff --git a/SHADE_Engine/src/Graphics/Images/SHVkSampler.cpp b/SHADE_Engine/src/Graphics/Images/SHVkSampler.cpp index e7a97126..b4bbf89b 100644 --- a/SHADE_Engine/src/Graphics/Images/SHVkSampler.cpp +++ b/SHADE_Engine/src/Graphics/Images/SHVkSampler.cpp @@ -4,4 +4,9 @@ namespace SHADE { + vk::Sampler SHVkSampler::GetVkSampler(void) const noexcept + { + return vkSampler; + } + } \ No newline at end of file diff --git a/SHADE_Engine/src/Graphics/Images/SHVkSampler.h b/SHADE_Engine/src/Graphics/Images/SHVkSampler.h index d58edb8f..eae23adf 100644 --- a/SHADE_Engine/src/Graphics/Images/SHVkSampler.h +++ b/SHADE_Engine/src/Graphics/Images/SHVkSampler.h @@ -22,6 +22,7 @@ namespace SHADE SHVkSampler (SHVkSampler&& rhs) noexcept; SHVkSampler&& operator=(SHVkSampler&& rhs) noexcept; + vk::Sampler GetVkSampler (void) const noexcept; }; } diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/GlobalData/SHGraphicsGlobalData.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/GlobalData/SHGraphicsGlobalData.cpp index 5289b635..d9ffa6b5 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/GlobalData/SHGraphicsGlobalData.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/GlobalData/SHGraphicsGlobalData.cpp @@ -27,7 +27,7 @@ namespace SHADE }; // For global data (generic data and textures) - Handle staticGlobalLayout = logicalDevice->CreateDescriptorSetLayout({ genericDataBinding, texturesBinding }); + Handle staticGlobalLayout = logicalDevice->CreateDescriptorSetLayout(SHGraphicsConstants::DescriptorSetIndex::STATIC_GLOBALS,{ genericDataBinding, texturesBinding }); SHVkDescriptorSetLayout::Binding lightBinding { @@ -38,7 +38,7 @@ namespace SHADE }; // For Dynamic global data (lights) - Handle dynamicGlobalLayout = logicalDevice->CreateDescriptorSetLayout({ lightBinding }); + Handle dynamicGlobalLayout = logicalDevice->CreateDescriptorSetLayout(SHGraphicsConstants::DescriptorSetIndex::DYNAMIC_GLOBALS, { lightBinding }); SHVkDescriptorSetLayout::Binding cameraDataBinding { @@ -49,7 +49,7 @@ namespace SHADE }; // For High frequency global data (camera) - Handle cameraDataGlobalLayout = logicalDevice->CreateDescriptorSetLayout({ cameraDataBinding }); + Handle cameraDataGlobalLayout = logicalDevice->CreateDescriptorSetLayout(SHGraphicsConstants::DescriptorSetIndex::HIGH_FREQUENCY_GLOBALS, { cameraDataBinding }); SHVkDescriptorSetLayout::Binding materialDataBinding { @@ -60,7 +60,7 @@ namespace SHADE }; // For High frequency global data (camera) - Handle materialDataPerInstanceLayout = logicalDevice->CreateDescriptorSetLayout({ materialDataBinding }); + Handle materialDataPerInstanceLayout = logicalDevice->CreateDescriptorSetLayout(SHGraphicsConstants::DescriptorSetIndex::PER_INSTANCE, { materialDataBinding }); globalDescSetLayouts.push_back(staticGlobalLayout); globalDescSetLayouts.push_back(dynamicGlobalLayout); diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp index b38fa275..1026d01b 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp @@ -204,6 +204,7 @@ namespace SHADE { // Frame data for the current frame auto const& frameData = renderContext.GetCurrentFrameData(); + uint32_t frameIndex = 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; @@ -233,7 +234,7 @@ namespace SHADE /* Renderer start */ /*-----------------------------------------------------------------------*/ // get command buffer of the renderer in the current frame - auto currentCmdBuffer = renderers[renIndex]->GetCommandBuffer(renderContext.GetCurrentFrame()); + auto currentCmdBuffer = renderers[renIndex]->GetCommandBuffer(frameIndex); // Begin recording the command buffer currentCmdBuffer->BeginRecording(); @@ -247,8 +248,11 @@ namespace SHADE currentCmdBuffer->BindIndexBuffer(buffer, 0); } + // bind camera data + renderers[renIndex]->BindDescriptorSet(currentCmdBuffer, frameIndex); + // Draw first - renderers[renIndex]->Draw(renderContext.GetCurrentFrame()); + renderers[renIndex]->Draw(frameIndex); // End the command buffer recording currentCmdBuffer->EndRecording(); diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderer.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderer.cpp index 223ceb4f..fd702968 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderer.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderer.cpp @@ -42,6 +42,12 @@ namespace SHADE cameraDataAlignedSize = logicalDevice->PadUBOSize(sizeof(SHShaderCameraData)); cameraBuffer = logicalDevice->CreateBuffer(cameraDataAlignedSize * numFrames, nullptr, cameraDataAlignedSize * numFrames, vk::BufferUsageFlagBits::eUniformBuffer, VMA_MEMORY_USAGE_AUTO, VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT); + + std::array cameraBufferArray{cameraBuffer}; + + cameraDescriptorSet->ModifyWriteDescBuffer(SHGraphicsConstants::DescriptorSetIndex::HIGH_FREQUENCY_GLOBALS, SHGraphicsConstants::DescriptorSetBindings::CAMERA_DATA, std::span>{ cameraBufferArray.data(), cameraBufferArray.size()}); + + cameraDescriptorSet->UpdateDescriptorSetBuffer(SHGraphicsConstants::DescriptorSetIndex::HIGH_FREQUENCY_GLOBALS, SHGraphicsConstants::DescriptorSetBindings::CAMERA_DATA); } /*-----------------------------------------------------------------------------------*/ diff --git a/SHADE_Engine/src/Graphics/Pipeline/SHVkPipelineLayout.cpp b/SHADE_Engine/src/Graphics/Pipeline/SHVkPipelineLayout.cpp index cc738aed..fc40f394 100644 --- a/SHADE_Engine/src/Graphics/Pipeline/SHVkPipelineLayout.cpp +++ b/SHADE_Engine/src/Graphics/Pipeline/SHVkPipelineLayout.cpp @@ -198,7 +198,7 @@ namespace SHADE // 1 descriptor set layout for every descriptor set detected. for (auto const& set : setsWithBindings) { - auto newDescriptorSetLayout = logicalDeviceHdl->CreateDescriptorSetLayout(set.second); + auto newDescriptorSetLayout = logicalDeviceHdl->CreateDescriptorSetLayout(set.first, set.second); descriptorSetLayoutsAllocate.push_back(newDescriptorSetLayout); } diff --git a/SHADE_Engine/src/Graphics/SHVkUtil.cpp b/SHADE_Engine/src/Graphics/SHVkUtil.cpp index c570caf2..e4f9f37e 100644 --- a/SHADE_Engine/src/Graphics/SHVkUtil.cpp +++ b/SHADE_Engine/src/Graphics/SHVkUtil.cpp @@ -71,4 +71,14 @@ namespace SHADE ); } } + + BindingAndSetHash SHVkUtil::GenBindingSetHash(uint32_t set, uint32_t binding) noexcept + { + // Find the target writeDescSet + BindingAndSetHash writeHash = binding; + writeHash |= static_cast(set) << 32; + + return writeHash; + } + } diff --git a/SHADE_Engine/src/Graphics/SHVkUtil.h b/SHADE_Engine/src/Graphics/SHVkUtil.h index 46ebf096..cba5b062 100644 --- a/SHADE_Engine/src/Graphics/SHVkUtil.h +++ b/SHADE_Engine/src/Graphics/SHVkUtil.h @@ -76,6 +76,8 @@ namespace SHADE */ /***********************************************************************************/ static void EnsureBufferAndCopyHostVisibleData(Handle device, Handle& bufferHandle, void* src, uint32_t size, vk::BufferUsageFlagBits usage); + + static BindingAndSetHash GenBindingSetHash (uint32_t set, uint32_t binding) noexcept; }; } diff --git a/SHADE_Engine/src/Graphics/SHVulkanDefines.h b/SHADE_Engine/src/Graphics/SHVulkanDefines.h index 542f379d..2f625f7e 100644 --- a/SHADE_Engine/src/Graphics/SHVulkanDefines.h +++ b/SHADE_Engine/src/Graphics/SHVulkanDefines.h @@ -6,6 +6,8 @@ namespace SHADE { using SHQueueFamilyIndex = uint32_t; + using BindingAndSetHash = uint64_t; + using SetIndex = uint32_t; } diff --git a/SHADE_Engine/src/Graphics/SHVulkanIncludes.h b/SHADE_Engine/src/Graphics/SHVulkanIncludes.h index 472226a0..63aa672b 100644 --- a/SHADE_Engine/src/Graphics/SHVulkanIncludes.h +++ b/SHADE_Engine/src/Graphics/SHVulkanIncludes.h @@ -6,5 +6,6 @@ #define VULKAN_HPP_DISPATCH_LOADER_DYNAMIC 1 #define VULKAN_HPP_NO_NODISCARD_WARNINGS #include +#include "Graphics/SHVulkanDefines.h" #endif diff --git a/SHADE_Engine/src/Graphics/Shaders/SHShaderReflected.h b/SHADE_Engine/src/Graphics/Shaders/SHShaderReflected.h index 88c7a2e1..3986f823 100644 --- a/SHADE_Engine/src/Graphics/Shaders/SHShaderReflected.h +++ b/SHADE_Engine/src/Graphics/Shaders/SHShaderReflected.h @@ -9,8 +9,6 @@ namespace SHADE { - using BindingAndSetHash = uint64_t; - struct SHShaderDescriptorBindingInfo { private: diff --git a/TempShaderFolder/ShaderDescriptorDefinitions.glsl b/TempShaderFolder/ShaderDescriptorDefinitions.glsl new file mode 100644 index 00000000..c70a9f5b --- /dev/null +++ b/TempShaderFolder/ShaderDescriptorDefinitions.glsl @@ -0,0 +1,11 @@ +#define SET_STATIC_GLOBALS 0 +#define SET_DYNAMIC_GLOBALS 1 +#define SET_HIGH_FREQUENCY_GLOBALS 2 + +#define BINDING_GENERIC_DATA 0 +#define BINDING_IMAGE_AND_SAMPLERS_DATA 1 +#define BINDING_LIGHTS_DATA 0 +#define BINDING_CAMERA_DATA 0 +#define BINDING_BATCHED_PER_INST_DATA 0 + + diff --git a/TempShaderFolder/TestCubeVs.glsl b/TempShaderFolder/TestCubeVs.glsl index f7dce787..08c465a0 100644 --- a/TempShaderFolder/TestCubeVs.glsl +++ b/TempShaderFolder/TestCubeVs.glsl @@ -1,6 +1,8 @@ #version 450 #extension GL_KHR_vulkan_glsl : enable +//#include "ShaderDescriptorDefinitions.glsl" + layout(location = 0) in vec3 aVertexPos; layout(location = 1) in vec2 aUV; layout(location = 2) in vec3 aNormal; @@ -28,6 +30,12 @@ layout(location = 0) out struct } Out; +layout(set = 2, binding = 0) uniform CameraData +{ + vec4 position; + mat4 vpMat; +} cameraData; + void main() { //const float gamma = testPushConstant.eyePosition.w; diff --git a/TempShaderFolder/TestCubeVs.spv b/TempShaderFolder/TestCubeVs.spv index 2b0d3b93c0c4a570f997eae1f3763e05cb6cbbab..be24aa3a944eff08f83a27869e46ef93dcc93eae 100644 GIT binary patch delta 293 zcmbQjJ%N{(nMs+Qfq{{Mi-DIxe#voP(Rt6mg1_tNE+|;5(m&B4p1_m}D1c`w_ zL4I*&NoIZ?h|LC7%Lrtb75FBW0BMkZJs_P7*FX6kw9PW?IXrD+jd@ dWRNBhD**YrKpLbGp;Bdp1`vZ(-aV!)n3^0DNT#AOHXW From e87c4c8dc846a5c391905f48e7dbba663e2b3742 Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Thu, 22 Sep 2022 12:39:05 +0800 Subject: [PATCH 05/26] Fixed SHTextureLibrary compiler errors --- .../MiddleEnd/Textures/SHTextureLibrary.cpp | 2 +- .../Graphics/MiddleEnd/Textures/SHTextureLibrary.h | 14 ++++++++++---- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Textures/SHTextureLibrary.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Textures/SHTextureLibrary.cpp index 3be4dd11..80be81df 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Textures/SHTextureLibrary.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Textures/SHTextureLibrary.cpp @@ -26,7 +26,7 @@ namespace SHADE /*---------------------------------------------------------------------------------*/ /* Usage Functions */ /*---------------------------------------------------------------------------------*/ - Handle SHTextureLibrary::Add(uint32_t pixelCount, const SHTexture::PixelChannel* const pixelData, SHTexture::TextureFormat format, int mipLevels) + Handle SHTextureLibrary::Add(uint32_t pixelCount, const SHTexture::PixelChannel* const pixelData, SHTexture::TextureFormat format, uint32_t mipLevels) { isDirty = true; diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Textures/SHTextureLibrary.h b/SHADE_Engine/src/Graphics/MiddleEnd/Textures/SHTextureLibrary.h index d30b02ed..5cf974ef 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Textures/SHTextureLibrary.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Textures/SHTextureLibrary.h @@ -18,6 +18,7 @@ of DigiPen Institute of Technology is prohibited. #include "Resource/Handle.h" #include "Resource/ResourceLibrary.h" #include "Math/SHMath.h" +#include "Graphics/SHVulkanIncludes.h" namespace SHADE { @@ -27,6 +28,11 @@ namespace SHADE class SHVkBuffer; class SHVkLogicalDevice; class SHVkCommandBuffer; + class SHVkImage; + class SHVkImageView; + class SHVkQueue; + class SHVkDescriptorPool; + class SHVkDescriptorSetLayout; /*---------------------------------------------------------------------------------*/ /* Type Definitions */ @@ -37,7 +43,7 @@ namespace SHADE /*-----------------------------------------------------------------------------*/ /* Type Definitions */ /*-----------------------------------------------------------------------------*/ - using PixelChannel = void; + using PixelChannel = float; using TextureFormat = vk::Format; // TODO: Change using Index = uint32_t; @@ -82,7 +88,7 @@ namespace SHADE */ /*******************************************************************************/ - Handle Add(uint32_t pixelCount, const SHTexture::PixelChannel* const pixelData, SHTexture::TextureFormat format, int mipLevels); + Handle Add(uint32_t pixelCount, const SHTexture::PixelChannel* const pixelData, SHTexture::TextureFormat format, uint32_t mipLevels); /*******************************************************************************/ /*! @@ -112,7 +118,7 @@ namespace SHADE queue. */ /***************************************************************************/ - void BuildImages(Handle device, Handle cmdBuffer, Handle graphicsQueue); + void BuildImages(Handle device, Handle cmdBuffer, Handle graphicsQueue, Handle descPool, Handle descLayout); /*-----------------------------------------------------------------------------*/ /* Getter Functions */ @@ -128,7 +134,7 @@ namespace SHADE uint32_t PixelCount = 0; const SHTexture::PixelChannel* PixelData = nullptr; SHTexture::TextureFormat TextureFormat = {}; - int MipLevels = 0; + uint32_t MipLevels = 0; Handle Image; Handle Handle; }; From cb31628e663a0f0fb1ef7eb829d41f06740c1f4e Mon Sep 17 00:00:00 2001 From: Brandon Mak Date: Thu, 22 Sep 2022 19:38:43 +0800 Subject: [PATCH 06/26] Dummy pipeline layout ctor created Renderer now can update and bind descriptor set --- SHADE_Application/src/Scenes/SBTestScene.cpp | 18 +++++-- SHADE_Application/src/Scenes/SBTestScene.h | 2 +- .../src/Graphics/Buffers/SHVkBuffer.cpp | 49 ++++++----------- .../src/Graphics/Buffers/SHVkBuffer.h | 4 +- .../Graphics/Commands/SHVkCommandBuffer.cpp | 5 ++ .../src/Graphics/Commands/SHVkCommandBuffer.h | 1 + .../Descriptors/SHVkDescriptorSetGroup.cpp | 4 +- .../Descriptors/SHVkDescriptorSetGroup.h | 2 +- .../Graphics/Devices/SHVkLogicalDevice.cpp | 7 ++- .../src/Graphics/Devices/SHVkLogicalDevice.h | 3 +- .../GlobalData/SHGraphicsGlobalData.cpp | 9 ++++ .../GlobalData/SHGraphicsGlobalData.h | 6 +++ .../Graphics/MiddleEnd/Interface/SHCamera.cpp | 34 ++++++------ .../MiddleEnd/Interface/SHGraphicsSystem.cpp | 7 +-- .../MiddleEnd/Interface/SHRenderer.cpp | 16 ++++-- .../Graphics/MiddleEnd/Interface/SHRenderer.h | 8 ++- .../Pipeline/SHPipelineLayoutParams.h | 9 ++++ .../src/Graphics/Pipeline/SHPipelineState.h | 2 +- .../Graphics/Pipeline/SHVkPipelineLayout.cpp | 50 +++++++++++++++--- .../Graphics/Pipeline/SHVkPipelineLayout.h | 3 +- TempShaderFolder/TestCubeVs.glsl | 3 +- TempShaderFolder/TestCubeVs.spv | Bin 1680 -> 1768 bytes 22 files changed, 161 insertions(+), 81 deletions(-) diff --git a/SHADE_Application/src/Scenes/SBTestScene.cpp b/SHADE_Application/src/Scenes/SBTestScene.cpp index 873d0fed..aef39ddd 100644 --- a/SHADE_Application/src/Scenes/SBTestScene.cpp +++ b/SHADE_Application/src/Scenes/SBTestScene.cpp @@ -7,6 +7,7 @@ #include "Graphics/MiddleEnd/Interface/SHRenderable.h" #include "Scene/SHSceneManager.h" #include "Graphics/MiddleEnd/Interface/SHGraphicsSystem.h" +#include "Math/Transform/SHTransformComponent.h" using namespace SHADE; @@ -28,6 +29,8 @@ namespace Sandbox } void SBTestScene::Init() { + SHComponentManager::CreateComponentSparseSet(); + SHADE::SHGraphicsSystem* graphicsSystem = static_cast(SHADE::SHSystemManager::GetSystem()); // Create temp meshes const auto CUBE_MESH = SHADE::SHPrimitiveGenerator::Cube(*graphicsSystem); @@ -37,16 +40,25 @@ namespace Sandbox auto matInst = graphicsSystem->AddMaterialInstance(); // Create entity and add mesh - auto entity = SHADE::SHEntityManager::CreateEntity(); - auto& renderable = *SHADE::SHComponentManager::GetComponent_s(entity); + testEntity = SHADE::SHEntityManager::CreateEntity(); + SHComponentManager::AddComponent(testEntity); + auto& renderable = *SHADE::SHComponentManager::GetComponent_s(testEntity); + auto& transform = *SHADE::SHComponentManager::GetComponent_s(testEntity); + renderable.Mesh = CUBE_MESH; renderable.SetMaterial(matInst); renderable.TransformMatrix.Translate(0.0f, 0.0f, 2.0f); + + transform.SetWorldPosition (SHVec3 (0.0f, 0.0f, 2.0f)); } void SBTestScene::Update(float dt) { - (void)dt; + static float rotation = 0.0f; + auto& transform = *SHADE::SHComponentManager::GetComponent_s(testEntity); + transform.SetWorldRotation (rotation, 0.0f, 0.0f); + + rotation += dt * 10.0f; } void SBTestScene::Render() diff --git a/SHADE_Application/src/Scenes/SBTestScene.h b/SHADE_Application/src/Scenes/SBTestScene.h index 6776c671..bb382477 100644 --- a/SHADE_Application/src/Scenes/SBTestScene.h +++ b/SHADE_Application/src/Scenes/SBTestScene.h @@ -9,7 +9,7 @@ namespace Sandbox { private: EntityID camera; - + unsigned int testEntity; public: virtual void Load(); diff --git a/SHADE_Engine/src/Graphics/Buffers/SHVkBuffer.cpp b/SHADE_Engine/src/Graphics/Buffers/SHVkBuffer.cpp index 4bfc1e4b..59916731 100644 --- a/SHADE_Engine/src/Graphics/Buffers/SHVkBuffer.cpp +++ b/SHADE_Engine/src/Graphics/Buffers/SHVkBuffer.cpp @@ -49,6 +49,11 @@ namespace SHADE Init(newSize, data, srcSize, bufferUsageFlags, allocCreateInfo.usage, allocCreateInfo.flags); } + void SHVkBuffer::FlushAllocation(uint32_t srcOffset, uint32_t dstOffset) noexcept + { + vmaFlushAllocation(vmaAllocator, alloc, srcOffset, dstOffset); + } + vk::Buffer SHVkBuffer::GetVkBuffer(void) const noexcept { return vkBuffer; @@ -72,8 +77,7 @@ namespace SHADE /***************************************************************************/ void SHVkBuffer::Map(void) noexcept { - if (!boundToCoherent) - vmaMapMemory(vmaAllocator, alloc, &mappedPtr); + vmaMapMemory(vmaAllocator, alloc, &mappedPtr); } /***************************************************************************/ @@ -90,11 +94,8 @@ namespace SHADE /***************************************************************************/ void SHVkBuffer::Unmap(void) noexcept { - if (!boundToCoherent) - { - vmaUnmapMemory(vmaAllocator, alloc); - mappedPtr = nullptr; - } + vmaUnmapMemory(vmaAllocator, alloc); + mappedPtr = nullptr; } /***************************************************************************/ @@ -132,9 +133,7 @@ namespace SHADE Otherwise, only the copying is carried out. In the instance where memory is non-coherent but HOST_VISIBLE, we want to - write to data and then unmap and flush it immediately. If you want to write - to memory in random-access fashion, consider, mapping, writing a few - things, unmapping then flushing. + write to data and then unmap and flush it immediately. \param vmaAllocator The VMA allocator object. @@ -155,18 +154,11 @@ namespace SHADE /***************************************************************************/ void SHVkBuffer::MapWriteUnmap(void* data, uint32_t sizeToWrite, uint32_t srcOffset, uint32_t dstOffset) noexcept { - if (!boundToCoherent) - { - // map from host visible memory to pointer, do a DMA, and then unmap - Map(); - WriteToMemory(data, sizeToWrite, srcOffset, dstOffset); - Unmap(); - } - else - { - if (mappedPtr) - std::memcpy(static_cast(mappedPtr) + dstOffset, static_cast(data) + srcOffset, sizeToWrite); - } + // map from host visible memory to pointer, do a DMA, and then unmap + Map(); + WriteToMemory(data, sizeToWrite, srcOffset, dstOffset); + Unmap(); + FlushAllocation(srcOffset, dstOffset); } /***************************************************************************/ @@ -279,7 +271,6 @@ namespace SHADE , mappedPtr{ nullptr } , alloc {nullptr} , randomAccessOptimized{false} - , boundToCoherent {false} , vmaAllocator{allocator} {} @@ -304,7 +295,6 @@ namespace SHADE , mappedPtr{ std::move(rhs.mappedPtr) } , alloc{ std::move (rhs.alloc) } , randomAccessOptimized{ rhs.randomAccessOptimized } - , boundToCoherent{ rhs.boundToCoherent} , vmaAllocator{ rhs.vmaAllocator } , bufferUsageFlags {rhs.bufferUsageFlags} , bufferCreateInfo { rhs.bufferCreateInfo } @@ -325,7 +315,6 @@ namespace SHADE mappedPtr = std::move(rhs.mappedPtr); alloc = std::move(rhs.alloc); randomAccessOptimized = rhs.randomAccessOptimized; - boundToCoherent = rhs.boundToCoherent; vmaAllocator = std::move (rhs.vmaAllocator); rhs.vkBuffer = VK_NULL_HANDLE; bufferCreateInfo = rhs.bufferCreateInfo; @@ -430,16 +419,12 @@ namespace SHADE // mainly host visible. Can be cached (need to flush/invalidate), uncached (always coherent) and coherent (virtual). if(memPropFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) { - // If memory is marked to be coherent between CPU and GPU (no need flush/invalidate) (TODO: Verify if VMA_ALLOCATION_CREATE_MAPPED_BIT is used when VMA_MEMORY_USAGE_AUTO is set) - // TODO: also verify that coherent bit = pointer is already mapped - if (memPropFlags & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT) - { - boundToCoherent = true; - mappedPtr = allocInfo.pMappedData; - } + if (allocFlags | VMA_ALLOCATION_CREATE_MAPPED_BIT) + mappedPtr = allocInfo.pMappedData; else mappedPtr = nullptr; + if (data) MapWriteUnmap(data, srcSize, 0, 0); } diff --git a/SHADE_Engine/src/Graphics/Buffers/SHVkBuffer.h b/SHADE_Engine/src/Graphics/Buffers/SHVkBuffer.h index 49f22e37..648a07e8 100644 --- a/SHADE_Engine/src/Graphics/Buffers/SHVkBuffer.h +++ b/SHADE_Engine/src/Graphics/Buffers/SHVkBuffer.h @@ -41,9 +41,6 @@ namespace SHADE //! If initialized with vma random access flag, this is true bool randomAccessOptimized; - //! Whether or not this buffer is bound to coherent memory - bool boundToCoherent; - //! buffer usage info flags vk::BufferUsageFlags bufferUsageFlags; @@ -100,6 +97,7 @@ namespace SHADE void TransferToDeviceResource(Handle const& cmdBufferHdl) noexcept; void ResizeNoCopy (uint32_t newSize); void ResizeReplace (uint32_t newSize, void* data, uint32_t srcSize); + void FlushAllocation (uint32_t srcOffset, uint32_t dstOffset) noexcept; /*-----------------------------------------------------------------------*/ /* SETTERS AND GETTERS */ diff --git a/SHADE_Engine/src/Graphics/Commands/SHVkCommandBuffer.cpp b/SHADE_Engine/src/Graphics/Commands/SHVkCommandBuffer.cpp index cddb6cdb..83095371 100644 --- a/SHADE_Engine/src/Graphics/Commands/SHVkCommandBuffer.cpp +++ b/SHADE_Engine/src/Graphics/Commands/SHVkCommandBuffer.cpp @@ -491,6 +491,11 @@ namespace SHADE // //vkCommandBuffer.pipelineBarrier() //} + void SHVkCommandBuffer::ForceSetPipelineLayout(Handle pipelineLayout) noexcept + { + boundPipelineLayoutHdl = pipelineLayout; + } + /***************************************************************************/ /*! diff --git a/SHADE_Engine/src/Graphics/Commands/SHVkCommandBuffer.h b/SHADE_Engine/src/Graphics/Commands/SHVkCommandBuffer.h index f780638a..c18527b3 100644 --- a/SHADE_Engine/src/Graphics/Commands/SHVkCommandBuffer.h +++ b/SHADE_Engine/src/Graphics/Commands/SHVkCommandBuffer.h @@ -141,6 +141,7 @@ namespace SHADE { memcpy (static_cast(pushConstantData) + boundPipelineLayoutHdl->GetPushConstantInterface().GetOffset(variableName), &data, sizeof (T)); }; + void ForceSetPipelineLayout (Handle pipelineLayout) noexcept; void SubmitPushConstants (void) const noexcept; diff --git a/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorSetGroup.cpp b/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorSetGroup.cpp index f579d377..c1732535 100644 --- a/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorSetGroup.cpp +++ b/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorSetGroup.cpp @@ -176,7 +176,7 @@ namespace SHADE } } - void SHVkDescriptorSetGroup::ModifyWriteDescBuffer(uint32_t set, uint32_t binding, std::span> const& buffers) noexcept + void SHVkDescriptorSetGroup::ModifyWriteDescBuffer(uint32_t set, uint32_t binding, std::span> const& buffers, uint32_t offset, uint32_t range) noexcept { // Find the target writeDescSet BindingAndSetHash writeHash = binding; @@ -193,6 +193,8 @@ namespace SHADE // write sampler and image view auto& buffer = buffers[i]; writeInfo.descBufferInfos[i].buffer = buffer->GetVkBuffer(); + writeInfo.descBufferInfos[i].offset = offset; + writeInfo.descBufferInfos[i].range = range; } } diff --git a/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorSetGroup.h b/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorSetGroup.h index bc87ff1d..d92d55e9 100644 --- a/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorSetGroup.h +++ b/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorSetGroup.h @@ -64,7 +64,7 @@ namespace SHADE void UpdateDescriptorSetBuffer(uint32_t set, uint32_t binding) noexcept; void ModifyWriteDescImage(uint32_t set, uint32_t binding, std::span, Handle>> const& imageViewsAndSamplers) noexcept; - void ModifyWriteDescBuffer (uint32_t set, uint32_t binding, std::span> const& buffers) noexcept; + void ModifyWriteDescBuffer (uint32_t set, uint32_t binding, std::span> const& buffers, uint32_t offset, uint32_t range) noexcept; /*-----------------------------------------------------------------------------*/ diff --git a/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.cpp b/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.cpp index 64508a2b..65b0d9ca 100644 --- a/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.cpp +++ b/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.cpp @@ -467,7 +467,12 @@ namespace SHADE */ /***************************************************************************/ - Handle SHVkLogicalDevice::CreatePipelineLayout(SHPipelineLayoutParams& pipelineLayoutParams) noexcept + Handle SHVkLogicalDevice::CreatePipelineLayout(SHPipelineLayoutParams const& pipelineLayoutParams) noexcept + { + return SHVkInstance::GetResourceManager().Create (GetHandle(), pipelineLayoutParams); + } + + Handle SHVkLogicalDevice::CreatePipelineLayoutDummy(SHPipelineLayoutParamsDummy const& pipelineLayoutParams) noexcept { return SHVkInstance::GetResourceManager().Create (GetHandle(), pipelineLayoutParams); } diff --git a/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.h b/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.h index 365e68c9..3a27e4b1 100644 --- a/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.h +++ b/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.h @@ -187,7 +187,8 @@ namespace SHADE Handle CreateDescriptorSetGroup(Handle pool, std::vector> const& layouts, std::vector const& variableDescCounts) noexcept; - Handle CreatePipelineLayout (SHPipelineLayoutParams& pipelineLayoutParams) noexcept; + Handle CreatePipelineLayout(SHPipelineLayoutParams const& pipelineLayoutParams) noexcept; + Handle CreatePipelineLayoutDummy(SHPipelineLayoutParamsDummy const& pipelineLayoutParams) noexcept; Handle CreateFence (void) const noexcept; Handle CreateSemaphore (void) const noexcept; diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/GlobalData/SHGraphicsGlobalData.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/GlobalData/SHGraphicsGlobalData.cpp index d9ffa6b5..ee6d0e8c 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/GlobalData/SHGraphicsGlobalData.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/GlobalData/SHGraphicsGlobalData.cpp @@ -2,6 +2,7 @@ #include "SHGraphicsGlobalData.h" #include "Graphics/Devices/SHVkLogicalDevice.h" #include "Graphics/Pipeline/SHPipelineState.h" +#include "Graphics/Pipeline/SHVkPipelineLayout.h" #include "Graphics/Descriptors/SHVkDescriptorSetLayout.h" namespace SHADE @@ -66,6 +67,9 @@ namespace SHADE globalDescSetLayouts.push_back(dynamicGlobalLayout); globalDescSetLayouts.push_back(cameraDataGlobalLayout); globalDescSetLayouts.push_back(materialDataPerInstanceLayout); + + + dummyPipelineLayout = logicalDevice->CreatePipelineLayoutDummy(SHPipelineLayoutParamsDummy{globalDescSetLayouts}); } void SHGraphicsGlobalData::InitDefaultVertexInputState(void) noexcept @@ -94,4 +98,9 @@ namespace SHADE return defaultVertexInputState; } + Handle SHGraphicsGlobalData::GetDummyPipelineLayout(void) const noexcept + { + return dummyPipelineLayout; + } + } diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/GlobalData/SHGraphicsGlobalData.h b/SHADE_Engine/src/Graphics/MiddleEnd/GlobalData/SHGraphicsGlobalData.h index fb595250..9333d0ab 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/GlobalData/SHGraphicsGlobalData.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/GlobalData/SHGraphicsGlobalData.h @@ -9,6 +9,7 @@ namespace SHADE class SHVkLogicalDevice; class SHVkDescriptorSetLayout; class SHVkDescriptorSetGroup; + class SHVkPipelineLayout; class SH_API SHGraphicsGlobalData { @@ -22,6 +23,10 @@ namespace SHADE //! Default vertex input state (used by everything). SHVertexInputState defaultVertexInputState; + //! Since we want to bind global data but can't do so without a pipeline layout, + //! we create a dummy pipeline layout to use it for binding. + Handle dummyPipelineLayout; + void InitDescSetLayouts (Handle logicalDevice) noexcept; void InitDefaultVertexInputState(void) noexcept; public: @@ -35,5 +40,6 @@ namespace SHADE /*-----------------------------------------------------------------------*/ std::vector> const& GetDescSetLayouts (void) const noexcept; SHVertexInputState const& GetDefaultViState (void) const noexcept; + Handle GetDummyPipelineLayout (void) const noexcept; }; } diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHCamera.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHCamera.cpp index 7e7412b9..992aff05 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHCamera.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHCamera.cpp @@ -22,24 +22,24 @@ namespace SHADE void SHCamera::SetLookAt(const SHVec3& pos, const SHVec3& target, const SHVec3& up) { SHVec3 view = target - pos; view = SHVec3::Normalise(view); - SHVec3 right = SHVec3::Cross(view, up); right = SHVec3::Normalise(right); - const SHVec3 UP = SHVec3::Cross(right, view); + SHVec3 right = SHVec3::Cross(view, up); right = SHVec3::Normalise(right); + const SHVec3 UP = SHVec3::Cross(right, view); - viewMatrix = SHMatrix::Identity; - viewMatrix(0, 0) = right[0]; - viewMatrix(1, 0) = right[1]; - viewMatrix(2, 0) = right[2]; - viewMatrix(0, 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; + viewMatrix = SHMatrix::Identity; + viewMatrix(0, 0) = UP[0]; + viewMatrix(1, 0) = UP[1]; + viewMatrix(2, 0) = UP[2]; + viewMatrix(0, 1) = right[0]; + viewMatrix(1, 1) = right[1]; + viewMatrix(2, 1) = right[2]; + viewMatrix(0, 2) = view[0]; + viewMatrix(1, 2) = view[1]; + viewMatrix(2, 2) = view[2]; + viewMatrix(3, 0) = -UP.Dot(pos); + viewMatrix(3, 1) = -right.Dot(pos); + viewMatrix(3, 2) = -view.Dot(pos); + + isDirty = true; } /*---------------------------------------------------------------------------------*/ diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp index 1026d01b..cee00c9b 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp @@ -114,7 +114,7 @@ namespace SHADE 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(static_cast(windowDims.first), static_cast(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->SetLookAt(SHVec3(1.0f, 0.0f, -1.0f), SHVec3(0.0f, 0.0f, 2.0f), SHVec3(0.0f, 1.0f, 0.0f)); worldCamera->SetPerspective(90.0f, static_cast(windowDims.first), static_cast(windowDims.second), 0.0f, 100.0f); // Create Default Viewport @@ -221,7 +221,6 @@ namespace SHADE renderContext.ResetFence(); - // For every viewport for (int vpIndex = 0; vpIndex < static_cast(viewports.size()); ++vpIndex) { @@ -239,6 +238,8 @@ namespace SHADE // Begin recording the command buffer currentCmdBuffer->BeginRecording(); + currentCmdBuffer->ForceSetPipelineLayout(globalData->GetDummyPipelineLayout()); + // Bind all the buffers required for meshes for (auto& [buffer, bindingPoint] : MESH_DATA) { @@ -249,7 +250,7 @@ namespace SHADE } // bind camera data - renderers[renIndex]->BindDescriptorSet(currentCmdBuffer, frameIndex); + renderers[renIndex]->UpdateDataAndBind(currentCmdBuffer, frameIndex); // Draw first renderers[renIndex]->Draw(frameIndex); diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderer.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderer.cpp index fd702968..c7e2a86d 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderer.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderer.cpp @@ -37,15 +37,14 @@ namespace SHADE commandBuffers[i] = cmdPools[i]->RequestCommandBuffer(SH_CMD_BUFFER_TYPE::PRIMARY); cameraDescriptorSet = descriptorPool->Allocate({ cameraDescLayout }, { 1 }); - cpuCameraData.resize(numFrames); cameraDataAlignedSize = logicalDevice->PadUBOSize(sizeof(SHShaderCameraData)); - cameraBuffer = logicalDevice->CreateBuffer(cameraDataAlignedSize * numFrames, nullptr, cameraDataAlignedSize * numFrames, vk::BufferUsageFlagBits::eUniformBuffer, VMA_MEMORY_USAGE_AUTO, VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT); + cameraBuffer = logicalDevice->CreateBuffer(cameraDataAlignedSize * numFrames, nullptr, cameraDataAlignedSize * numFrames, vk::BufferUsageFlagBits::eUniformBuffer, VMA_MEMORY_USAGE_AUTO, VMA_ALLOCATION_CREATE_MAPPED_BIT | VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT); std::array cameraBufferArray{cameraBuffer}; - cameraDescriptorSet->ModifyWriteDescBuffer(SHGraphicsConstants::DescriptorSetIndex::HIGH_FREQUENCY_GLOBALS, SHGraphicsConstants::DescriptorSetBindings::CAMERA_DATA, std::span>{ cameraBufferArray.data(), cameraBufferArray.size()}); + cameraDescriptorSet->ModifyWriteDescBuffer(SHGraphicsConstants::DescriptorSetIndex::HIGH_FREQUENCY_GLOBALS, SHGraphicsConstants::DescriptorSetBindings::CAMERA_DATA, std::span>{ cameraBufferArray.data(), cameraBufferArray.size()}, 0, sizeof (SHShaderCameraData)); cameraDescriptorSet->UpdateDescriptorSetBuffer(SHGraphicsConstants::DescriptorSetIndex::HIGH_FREQUENCY_GLOBALS, SHGraphicsConstants::DescriptorSetBindings::CAMERA_DATA); } @@ -66,13 +65,20 @@ namespace SHADE renderGraph->Execute(frameIndex, commandBuffers[frameIndex]); } - void SHRenderer::BindDescriptorSet(Handle cmdBuffer, uint32_t frameIndex) noexcept + void SHRenderer::UpdateDataAndBind(Handle cmdBuffer, uint32_t frameIndex) noexcept { - std::array dynamicOffsets{ frameIndex * cameraDataAlignedSize }; + cpuCameraData.viewProjectionMatrix = camera->GetViewProjectionMatrix(); + cameraBuffer->WriteToMemory(&cpuCameraData, sizeof(SHShaderCameraData), 0, cameraDataAlignedSize * frameIndex); + + std::array dynamicOffsets{ frameIndex * cameraDataAlignedSize }; cmdBuffer->BindDescriptorSet(cameraDescriptorSet, vk::PipelineBindPoint::eGraphics, SHGraphicsConstants::DescriptorSetIndex::HIGH_FREQUENCY_GLOBALS, std::span{ dynamicOffsets.data(), 1 }); } + void SHRenderer::UpdateCameraDataToBuffer(void) noexcept + { + } + 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 index bbb7773b..255ab289 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderer.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderer.h @@ -75,7 +75,8 @@ namespace SHADE /* Drawing Functions */ /*-----------------------------------------------------------------------------*/ void Draw(uint32_t frameIndex) noexcept; - void BindDescriptorSet (Handle cmdBuffer, uint32_t frameIndex) noexcept; + void UpdateDataAndBind (Handle cmdBuffer, uint32_t frameIndex) noexcept; + void UpdateCameraDataToBuffer (void) noexcept; /*-----------------------------------------------------------------------------*/ /* Setters and Getters */ @@ -95,7 +96,10 @@ namespace SHADE Handle renderGraph; Handle cameraDescriptorSet; Handle cameraBuffer; - std::vector cpuCameraData; + + // we really only need 1 copy even though we need %swapchainImages copies for + // GPU. + SHShaderCameraData cpuCameraData; //! Command buffers for the render graph std::vector> commandBuffers; diff --git a/SHADE_Engine/src/Graphics/Pipeline/SHPipelineLayoutParams.h b/SHADE_Engine/src/Graphics/Pipeline/SHPipelineLayoutParams.h index 493bd114..093e03d4 100644 --- a/SHADE_Engine/src/Graphics/Pipeline/SHPipelineLayoutParams.h +++ b/SHADE_Engine/src/Graphics/Pipeline/SHPipelineLayoutParams.h @@ -25,6 +25,15 @@ namespace SHADE //! want to use it for allocating descriptor sets. std::vector> const& globalDescSetLayouts = {}; }; + + struct SHPipelineLayoutParamsDummy + { + /*-----------------------------------------------------------------------*/ + /* MEMBER VARIABLES */ + /*-----------------------------------------------------------------------*/ + + std::vector> const& globalDescSetLayouts = {}; + }; } #endif diff --git a/SHADE_Engine/src/Graphics/Pipeline/SHPipelineState.h b/SHADE_Engine/src/Graphics/Pipeline/SHPipelineState.h index a43035f5..2769d6cc 100644 --- a/SHADE_Engine/src/Graphics/Pipeline/SHPipelineState.h +++ b/SHADE_Engine/src/Graphics/Pipeline/SHPipelineState.h @@ -64,7 +64,7 @@ namespace SHADE vk::CullModeFlags cull_mode{ vk::CullModeFlagBits::eBack }; //! CW or CCW - vk::FrontFace frontFacingOrientation{ vk::FrontFace::eClockwise }; + vk::FrontFace frontFacingOrientation{ vk::FrontFace::eCounterClockwise }; bool depthBias{ VK_FALSE }; }; diff --git a/SHADE_Engine/src/Graphics/Pipeline/SHVkPipelineLayout.cpp b/SHADE_Engine/src/Graphics/Pipeline/SHVkPipelineLayout.cpp index fc40f394..25be112e 100644 --- a/SHADE_Engine/src/Graphics/Pipeline/SHVkPipelineLayout.cpp +++ b/SHADE_Engine/src/Graphics/Pipeline/SHVkPipelineLayout.cpp @@ -254,12 +254,6 @@ namespace SHADE // Clear pc ranges vkPcRanges.clear(); - // Kill all descriptor set layouts - for (auto& layout : descriptorSetLayoutsGlobal) - SHVkInstance::GetResourceManager().Free(layout); - - descriptorSetLayoutsGlobal.clear(); - for (auto& layout : descriptorSetLayoutsAllocate) SHVkInstance::GetResourceManager().Free(layout); @@ -285,9 +279,9 @@ namespace SHADE */ /***************************************************************************/ - SHVkPipelineLayout::SHVkPipelineLayout(Handle const& inLogicalDeviceHdl, SHPipelineLayoutParams& pipelineLayoutParams) noexcept + SHVkPipelineLayout::SHVkPipelineLayout(Handle const& inLogicalDeviceHdl, SHPipelineLayoutParams const& pipelineLayoutParams) noexcept : vkPipelineLayout {VK_NULL_HANDLE} - , shaderModules{std::move (pipelineLayoutParams.shaderModules)} + , shaderModules{pipelineLayoutParams.shaderModules} , logicalDeviceHdl {inLogicalDeviceHdl} , pushConstantInterface{} , vkPcRanges{} @@ -308,6 +302,46 @@ namespace SHADE RecreateIfNeeded (); } + + SHVkPipelineLayout::SHVkPipelineLayout(Handle const& inLogicalDeviceHdl, SHPipelineLayoutParamsDummy const& pipelineLayoutParams) noexcept + : vkPipelineLayout{ VK_NULL_HANDLE } + , shaderModules{ } + , logicalDeviceHdl{ inLogicalDeviceHdl } + , pushConstantInterface{} + , vkPcRanges{} + , descriptorSetLayoutsGlobal{} + , descriptorSetLayoutsAllocate{} + , vkDescriptorSetLayoutsAllocate{} + , vkDescriptorSetLayoutsPipeline{} + + { + vkDescriptorSetLayoutsPipeline.resize(pipelineLayoutParams.globalDescSetLayouts.size()); + for (uint32_t i = 0; auto& layout : vkDescriptorSetLayoutsPipeline) + { + layout = pipelineLayoutParams.globalDescSetLayouts[i]->GetVkHandle(); + ++i; + } + + vk::PipelineLayoutCreateInfo plCreateInfo{}; + + // Set push constant data to pipeline layout + plCreateInfo.pushConstantRangeCount = 0; + plCreateInfo.pPushConstantRanges = nullptr; + + // To initialize the descriptor set layouts for the pipeline layout. + plCreateInfo.setLayoutCount = static_cast(vkDescriptorSetLayoutsPipeline.size()); + plCreateInfo.pSetLayouts = vkDescriptorSetLayoutsPipeline.data(); + + if (auto const RESULT = logicalDeviceHdl->GetVkLogicalDevice().createPipelineLayout(&plCreateInfo, nullptr, &vkPipelineLayout); RESULT != vk::Result::eSuccess) + { + SHVulkanDebugUtil::ReportVkError(RESULT, "Failed to create Pipeline Layout. "); + return; + } + else + SHVulkanDebugUtil::ReportVkSuccess("Successfully created Pipeline Layout. "); + + } + /***************************************************************************/ /*! diff --git a/SHADE_Engine/src/Graphics/Pipeline/SHVkPipelineLayout.h b/SHADE_Engine/src/Graphics/Pipeline/SHVkPipelineLayout.h index bce827a7..e43ceb73 100644 --- a/SHADE_Engine/src/Graphics/Pipeline/SHVkPipelineLayout.h +++ b/SHADE_Engine/src/Graphics/Pipeline/SHVkPipelineLayout.h @@ -57,7 +57,8 @@ namespace SHADE /*-----------------------------------------------------------------------*/ /* CTORS AND DTORS */ /*-----------------------------------------------------------------------*/ - SHVkPipelineLayout (Handle const& inLogicalDeviceHdl, SHPipelineLayoutParams& pipelineLayoutParams) noexcept; + SHVkPipelineLayout(Handle const& inLogicalDeviceHdl, SHPipelineLayoutParams const& pipelineLayoutParams) noexcept; + SHVkPipelineLayout(Handle const& inLogicalDeviceHdl, SHPipelineLayoutParamsDummy const& pipelineLayoutParams) noexcept; SHVkPipelineLayout (SHVkPipelineLayout&& rhs) noexcept; ~SHVkPipelineLayout (void) noexcept; SHVkPipelineLayout& operator= (SHVkPipelineLayout&& rhs) noexcept; diff --git a/TempShaderFolder/TestCubeVs.glsl b/TempShaderFolder/TestCubeVs.glsl index 08c465a0..1e3a11d7 100644 --- a/TempShaderFolder/TestCubeVs.glsl +++ b/TempShaderFolder/TestCubeVs.glsl @@ -56,6 +56,7 @@ void main() //Out.uv = aUV; // render NDC first - gl_Position = vec4(aVertexPos, 1.0); + //gl_Position = vec4(aVertexPos, 1.0f); + gl_Position = cameraData.vpMat * vec4 (aVertexPos, 1.0f); Out.vertColor = vec4 (aVertexPos, 1.0f); } \ No newline at end of file diff --git a/TempShaderFolder/TestCubeVs.spv b/TempShaderFolder/TestCubeVs.spv index be24aa3a944eff08f83a27869e46ef93dcc93eae..f0b31ea23f835273164024fc22e42f8e3c4cc918 100644 GIT binary patch literal 1768 zcmZ9LYflqF6ovA)6cQnt1#>m=i~9Dg9|GoNw`AM0r!p4p%3jC{`b}#7qs2w-+Gw^LtyZIX*zODl z?P2^Q@Y;bNdhMp&^2?c)S}q13ZLFE~OPV{m^>FmqrpMD+&=t&MughQqHC z8*`)x{bsn?ahwB=*>Us|j=nh#AC7x$D1wiUxa(6*m~kW(963t~PBmaO*Di5-;0Z@w z){(cN9Q1Va65bGI5U0PD1f`h1Vcsen`^;;u z%E-$;-~}0DO_=_Ym%1wY(o@%C@?RI`Jn-ZP(`z`F?}mKxqhHQqt!GM$e`xGVtCUZ^rbH=GI~e9-b$JFDCNQQR(m)Fo0uO+Y5Fpf|^dXR_|oJT=)`F;hZ}nK#o;x7x?;<~Z#)pTBqp zW66{p5zew%aCTY$0~^LTi<0Y-JCYsAuH=DaPg2rvO8U1pmsPdZ?zTFeR{KM@HyU-v z>5nMrMqwOu`(YCF((pWhH(TI^aW9(mi-d|8#rhTXJ+B&PQTHfFPJ<*3zRMMw;n>86 z<1h_}vCtXE=R6J%T_^ZfSFOP-q+d+`n1Do2cJ{W7{ha!7gS-_dg`RJo1F}0e~y~6%O zVa%K5wa3^ChV~e<1Y>RBFHHh!! zKDDUt&)$&FIuysByW;%+bAWU05~dHxVf4*DUza&;U-IknS*v2ft7{K^VXw=Ymaa)Q z)B}0(>2pp0v(hyQYcKb&%I4f#^5>-CgH>fQL!W~fQWI}MnwrF4=RR*0j5CDIwxo%Hkqe*u2BY>p zY4R~I`1hr$0}da5C&zp*yO(_41A8{be<)3DW=y_E(!{{okI#DntIFqo;S-1dM4Dc} z;p21fU@!Hy(Bx)uhCf1hQ*VSauT=@N`Ye=lt>u{11-71J^x%0LIY#~?bwp2_686I< z&dlE{FY~@7;f}e-x9S8RzVCzYqu9q?`Cu$xvnCs?*hf9bihXPgV}DITyx2!WKKJSS Mz=!`=Szk&10e+KzwEzGB From 495d2b4b66e512fc84ce77617b139fdeb1bc579a Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Thu, 22 Sep 2022 20:04:53 +0800 Subject: [PATCH 07/26] Added per-frame update of gpu transforms buffer --- .../Graphics/MiddleEnd/Batching/SHBatch.cpp | 26 ++++++++++++------- .../src/Graphics/MiddleEnd/Batching/SHBatch.h | 1 + .../Graphics/MiddleEnd/Batching/SHBatcher.cpp | 8 ++++++ .../Graphics/MiddleEnd/Batching/SHBatcher.h | 1 + .../MiddleEnd/Batching/SHSuperBatch.cpp | 8 ++++++ .../MiddleEnd/Batching/SHSuperBatch.h | 1 + .../Graphics/RenderGraph/SHRenderGraph.cpp | 8 ++++++ .../src/Graphics/RenderGraph/SHRenderGraph.h | 1 + 8 files changed, 45 insertions(+), 9 deletions(-) diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.cpp index 08ffa88e..c2090fc0 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.cpp @@ -86,6 +86,23 @@ namespace SHADE matPropsBuffer.Free(); } + void SHBatch::UpdateTransformBuffer() + { + // Reset Transform Data + transformData.clear(); + + // Populate on the CPU + for (auto& subBatch : subBatches) + for (const SHRenderable* renderable : subBatch.Renderables) + { + // Transform + transformData.emplace_back(renderable->TransformMatrix); + } + + // Transfer to GPU + transformDataBuffer->WriteToMemory(transformData.data(), transformData.size() * sizeof(SHMatrix), 0, 0); + } + void SHBatch::Build(Handle device) { // No need to build as there are no changes @@ -159,36 +176,27 @@ namespace SHADE // Send all buffered data to the GPU buffers using BuffUsage = vk::BufferUsageFlagBits; // - Draw Data - if (drawDataBuffer) - drawDataBuffer->Unmap(); const uint32_t DRAW_DATA_BYTES = static_cast(drawData.size() * sizeof(vk::DrawIndexedIndirectCommand)); SHVkUtil::EnsureBufferAndCopyHostVisibleData ( device, drawDataBuffer, drawData.data(), DRAW_DATA_BYTES, BuffUsage::eIndirectBuffer ); - drawDataBuffer->Map(); // - Transform Buffer - if (transformDataBuffer) - transformDataBuffer->Unmap(); const uint32_t TF_DATA_BYTES = static_cast(transformData.size() * sizeof(SHMatrix)); SHVkUtil::EnsureBufferAndCopyHostVisibleData ( device, transformDataBuffer, transformData.data(), TF_DATA_BYTES, BuffUsage::eVertexBuffer ); - transformDataBuffer->Map(); // - Material Properties Buffer if (!EMPTY_MAT_PROPS) { - if (matPropsBuffer) - matPropsBuffer->Unmap(); SHVkUtil::EnsureBufferAndCopyHostVisibleData ( device, matPropsBuffer, matPropsData.get(), static_cast(matPropTotalBytes), BuffUsage::eStorageBuffer ); - matPropsBuffer->Map(); } isDirty = false; diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.h b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.h index a5b808ff..f438d6c1 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.h @@ -71,6 +71,7 @@ namespace SHADE void Add(const SHRenderable* renderable); void Remove(const SHRenderable* renderable); void Clear(); + void UpdateTransformBuffer(); void Build(Handle device); void Draw(Handle cmdBuffer); diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatcher.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatcher.cpp index c92d9585..ea216ed5 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatcher.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatcher.cpp @@ -109,6 +109,14 @@ namespace SHADE superBatches.clear(); } + void SHBatcher::UpdateTransformBuffer() + { + for (auto& batch : superBatches) + { + batch->UpdateTransformBuffer(); + } + } + void SHBatcher::RegisterSuperBatch(Handle superBatch) { superBatches.emplace_back(superBatch); diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatcher.h b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatcher.h index 4c8ac811..89dea2eb 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatcher.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatcher.h @@ -53,6 +53,7 @@ namespace SHADE void RemoveFromBatch(SHRenderable const* renderable); void FinaliseBatches(Handle device); void ClearBatches(); + void UpdateTransformBuffer(); void RegisterSuperBatch(Handle superBatch); void DeregisterSuperBatch(Handle superBatch); diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHSuperBatch.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHSuperBatch.cpp index 09d2a720..8b7ea619 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHSuperBatch.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHSuperBatch.cpp @@ -78,6 +78,14 @@ namespace SHADE batches.clear(); } + void SHSuperBatch::UpdateTransformBuffer() + { + for (auto& batch : batches) + { + batch.UpdateTransformBuffer(); + } + } + void SHSuperBatch::Build(Handle device) noexcept { // Build all batches diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHSuperBatch.h b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHSuperBatch.h index b44dd349..6151e56e 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHSuperBatch.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHSuperBatch.h @@ -55,6 +55,7 @@ namespace SHADE void Add(const SHRenderable* renderable) noexcept; void Remove(const SHRenderable* renderable) noexcept; void Clear() noexcept; + void UpdateTransformBuffer(); void Build(Handle device) noexcept; void Draw(Handle cmdBuffer) noexcept; diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp index d02e8f7d..f53f3e99 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp @@ -348,6 +348,9 @@ namespace SHADE void SHSubpass::Execute(Handle& commandBuffer) noexcept { + // Ensure correct transforms are provided + superBatch->UpdateTransformBuffer(); + // Draw all the batches superBatch->Draw(commandBuffer); @@ -626,6 +629,11 @@ namespace SHADE batcher.FinaliseBatches(logicalDeviceHdl); } + void SHRenderGraphNode::UpdateBatchTransforms() + { + batcher.UpdateTransformBuffer(); + } + /***************************************************************************/ /*! diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.h b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.h index cbb9586d..16770475 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.h +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.h @@ -231,6 +231,7 @@ namespace SHADE void Execute (Handle& commandBuffer, uint32_t frameIndex) noexcept; Handle GetOrCreatePipeline (std::pair, Handle> const& vsFsPair, Handle subpass) noexcept; void FinaliseBatch(); + void UpdateBatchTransforms(); /*-----------------------------------------------------------------------*/ /* SETTERS AND GETTERS */ From 5c4384b589ce146828a8c83a64b16c720338f21b Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Thu, 22 Sep 2022 20:53:03 +0800 Subject: [PATCH 08/26] Fixed SHVkBuffer initial copy data for mapped buffers and made the cube spin --- .../src/Application/SBApplication.cpp | 6 +++-- SHADE_Application/src/Scenes/SBTestScene.cpp | 21 +++++++++--------- SHADE_Application/src/Scenes/SBTestScene.h | 2 +- .../src/Graphics/Buffers/SHVkBuffer.cpp | 14 ++++++++---- .../MiddleEnd/Interface/SHRenderable.cpp | 1 - TempShaderFolder/TestCubeVs.glsl | 2 +- TempShaderFolder/TestCubeVs.spv | Bin 1768 -> 1804 bytes 7 files changed, 26 insertions(+), 20 deletions(-) diff --git a/SHADE_Application/src/Application/SBApplication.cpp b/SHADE_Application/src/Application/SBApplication.cpp index 53cc1e40..93d1cdff 100644 --- a/SHADE_Application/src/Application/SBApplication.cpp +++ b/SHADE_Application/src/Application/SBApplication.cpp @@ -22,8 +22,8 @@ #include "ECS_Base/Managers/SHEntityManager.h" #include "Graphics/MiddleEnd/Interface/SHRenderable.h" #include "Scene/SHSceneManager.h" - #include "Scenes/SBTestScene.h" +#include "Math/Transform/SHTransformComponent.h" using namespace SHADE; @@ -58,8 +58,10 @@ namespace Sandbox SHADE::SHSystemManager::RegisterRoutine(); SHADE::SHSystemManager::RegisterRoutine(); SHADE::SHSystemManager::RegisterRoutine(); - SHADE::SHComponentManager::CreateComponentSparseSet(); + SHADE::SHComponentManager::CreateComponentSparseSet(); + SHADE::SHComponentManager::CreateComponentSparseSet(); + // Set up graphics system and windows graphicsSystem->SetWindow(&window); sdlWindow = SDL_CreateWindowFrom(window.GetHWND()); diff --git a/SHADE_Application/src/Scenes/SBTestScene.cpp b/SHADE_Application/src/Scenes/SBTestScene.cpp index 93d4e19b..e6082d3f 100644 --- a/SHADE_Application/src/Scenes/SBTestScene.cpp +++ b/SHADE_Application/src/Scenes/SBTestScene.cpp @@ -30,8 +30,6 @@ namespace Sandbox } void SBTestScene::Init() { - SHComponentManager::CreateComponentSparseSet(); - SHADE::SHGraphicsSystem* graphicsSystem = static_cast(SHADE::SHSystemManager::GetSystem()); // Create temp meshes const auto CUBE_MESH = SHADE::SHPrimitiveGenerator::Cube(*graphicsSystem); @@ -41,27 +39,28 @@ namespace Sandbox auto matInst = graphicsSystem->AddMaterialInstance(); // Create entity and add mesh - testEntity = SHADE::SHEntityManager::CreateEntity(); - SHComponentManager::AddComponent(testEntity); - auto& renderable = *SHADE::SHComponentManager::GetComponent_s(testEntity); - auto& transform = *SHADE::SHComponentManager::GetComponent_s(testEntity); + testObj = SHADE::SHEntityManager::CreateEntity(); + //SHComponentManager::AddComponent(testObj); + auto& renderable = *SHADE::SHComponentManager::GetComponent_s(testObj); + auto& transform = *SHADE::SHComponentManager::GetComponent_s(testObj); renderable.Mesh = CUBE_MESH; renderable.SetMaterial(matInst); renderable.TransformMatrix.Translate(0.0f, 0.0f, 2.0f); - - transform.SetWorldPosition (SHVec3 (0.0f, 0.0f, 2.0f)); // Add script SHADE::SHScriptEngine* scriptEngine = static_cast(SHADE::SHSystemManager::GetSystem()); - scriptEngine->AddScript(*SHADE::SHEntityManager::GetEntityByID(testEntity), "TestScript"); + scriptEngine->AddScript(*SHADE::SHEntityManager::GetEntityByID(testObj), "TestScript"); } + void SBTestScene::Update(float dt) { static float rotation = 0.0f; - auto& transform = *SHADE::SHComponentManager::GetComponent_s(testEntity); - transform.SetWorldRotation (rotation, 0.0f, 0.0f); + auto& renderable = *SHADE::SHComponentManager::GetComponent_s(testObj); + SHTransform tf; + tf.rotation = SHVec3(rotation, 0.0f, 0.0f); + renderable.TransformMatrix = tf.ComputeTRS(); rotation += dt * 10.0f; diff --git a/SHADE_Application/src/Scenes/SBTestScene.h b/SHADE_Application/src/Scenes/SBTestScene.h index bb382477..81ee3e7b 100644 --- a/SHADE_Application/src/Scenes/SBTestScene.h +++ b/SHADE_Application/src/Scenes/SBTestScene.h @@ -9,7 +9,7 @@ namespace Sandbox { private: EntityID camera; - unsigned int testEntity; + EntityID testObj; public: virtual void Load(); diff --git a/SHADE_Engine/src/Graphics/Buffers/SHVkBuffer.cpp b/SHADE_Engine/src/Graphics/Buffers/SHVkBuffer.cpp index 59916731..da4bc292 100644 --- a/SHADE_Engine/src/Graphics/Buffers/SHVkBuffer.cpp +++ b/SHADE_Engine/src/Graphics/Buffers/SHVkBuffer.cpp @@ -419,14 +419,20 @@ namespace SHADE // mainly host visible. Can be cached (need to flush/invalidate), uncached (always coherent) and coherent (virtual). if(memPropFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) { - if (allocFlags | VMA_ALLOCATION_CREATE_MAPPED_BIT) - mappedPtr = allocInfo.pMappedData; + const bool CREATE_MAPPED = allocFlags & VMA_ALLOCATION_CREATE_MAPPED_BIT; + + if (CREATE_MAPPED) + mappedPtr = allocInfo.pMappedData; else mappedPtr = nullptr; - if (data) - MapWriteUnmap(data, srcSize, 0, 0); + { + if (CREATE_MAPPED) + WriteToMemory(data, srcSize, 0, 0); + else + MapWriteUnmap(data, srcSize, 0, 0); + } } else { diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderable.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderable.cpp index 984e753b..32a6a99a 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderable.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderable.cpp @@ -27,7 +27,6 @@ namespace SHADE sharedMaterial = {}; material = {}; oldMaterial = {}; - } void SHRenderable::OnDestroy() diff --git a/TempShaderFolder/TestCubeVs.glsl b/TempShaderFolder/TestCubeVs.glsl index 1e3a11d7..b2d52104 100644 --- a/TempShaderFolder/TestCubeVs.glsl +++ b/TempShaderFolder/TestCubeVs.glsl @@ -57,6 +57,6 @@ void main() // render NDC first //gl_Position = vec4(aVertexPos, 1.0f); - gl_Position = cameraData.vpMat * vec4 (aVertexPos, 1.0f); + gl_Position = cameraData.vpMat * worldTransform * vec4 (aVertexPos, 1.0f); Out.vertColor = vec4 (aVertexPos, 1.0f); } \ No newline at end of file diff --git a/TempShaderFolder/TestCubeVs.spv b/TempShaderFolder/TestCubeVs.spv index f0b31ea23f835273164024fc22e42f8e3c4cc918..eb9a1209e697acf798dc5ab441bdbdfed631bc9c 100644 GIT binary patch literal 1804 zcmZ9LYflqF6o$uM06{=RE-KcRdPflzh>1~S3Mn6|U_ib$lXfMWY`4vJTQ8sd3;L7% zRemw?eRg-qhH1{udEfKSnKNgm#X^13m`i5b%$i-3js;T?W6X@1NakkixV1TqyPMlP zTPWsCF%hDfH&+tBq;JpqAz)T^LspSJmc5j1%XVZ%{R*1@XmLrqHe2oH;bF72-|h?s z?P2^q@Y;bNdhMF$S&>`4gFzTE>G9HrCAgMa`Yudd^6XzxJb`dlK1j_@y89QZ0SA z>9KW2xT1L|jzJHcKUQZN{h%L-N5fqmj^f1U&g|z?`K9FU>_?@yfp9swM|)z!GcTk( zb0Cg>Gu-Sr&H=~lIC=?3-yDYz$2~R`!AD2j^{Fn*IFJgCoaF?k8Zerx7dSoegd;EO z$lFv7db)lA*Mu3w-5XA8Dkblk-ZF^OuRNw_VCo>wn+Lo7c>iF|x+oUDCIrS`mN%if zDqGQd>ISp_lD<=#t1`w$hA+!!zct}$&FJAO^5~(*N`nDt=p0zG|M z)66-k7yWI`#Ng3`-950M>!~q6-=V*+IBTi7B9H$AKCwrdiNTQz%ss=g_jAqU<1FZ3 zXl8GC^kCiroU4U*kjK0O@UC7jdFUg9J^qT}O~2QdzAVe=9sPPEB|TY@!8?3YKK=Qv zHNaiFLz}0FNNZ K|EH|4Wd8wmlZ7(? literal 1768 zcmZ9LYflqF6ovA)6cQnt1#>m=i~9Dg9|GoNw`AM0r!p4p%3jC{`b}#7qs2w-+Gw^LtyZIX*zODl z?P2^Q@Y;bNdhMp&^2?c)S}q13ZLFE~OPV{m^>FmqrpMD+&=t&MughQqHC z8*`)x{bsn?ahwB=*>Us|j=nh#AC7x$D1wiUxa(6*m~kW(963t~PBmaO*Di5-;0Z@w z){(cN9Q1Va65bGI5U0PD1f`h1Vcsen`^;;u z%E-$;-~}0DO_=_Ym%1wY(o@%C@?RI`Jn-ZP(`z`F?}mKxqhHQqt!GM$e`xGVtCUZ^rbH=GI~e9-b$JFDCNQQ Date: Fri, 23 Sep 2022 13:14:46 +0800 Subject: [PATCH 09/26] progress on input manager, near ready for PR --- .../src/Input/SHInputManagerSystem.cpp | 147 +++++ SHADE_Engine/src/Input/SHInputManagerSystem.h | 559 ++++++++++++++++++ 2 files changed, 706 insertions(+) create mode 100644 SHADE_Engine/src/Input/SHInputManagerSystem.cpp create mode 100644 SHADE_Engine/src/Input/SHInputManagerSystem.h diff --git a/SHADE_Engine/src/Input/SHInputManagerSystem.cpp b/SHADE_Engine/src/Input/SHInputManagerSystem.cpp new file mode 100644 index 00000000..d5e9bb3f --- /dev/null +++ b/SHADE_Engine/src/Input/SHInputManagerSystem.cpp @@ -0,0 +1,147 @@ +/********************************************************************* + * \file SHInputManagerSystem.cpp + * \author Ryan Wang Nian Jing + * \brief Definition of input manager. + * Handles input from keyboard and mouse. Soon to include controller. + * + * \copyright 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 "SHInputManagerSystem.h" + +namespace SHADE +{ + /*------------------------------------------------------------------------*/ + /* Static defines */ + /*------------------------------------------------------------------------*/ + + unsigned SHInputManagerSystem::keyCount = 0; + bool SHInputManagerSystem::keys[MAX_KEYS]; + bool SHInputManagerSystem::keysLast[MAX_KEYS]; + double SHInputManagerSystem::keysHeldTime[MAX_KEYS]; + double SHInputManagerSystem::keysReleasedTime[MAX_KEYS]; + + unsigned SHInputManagerSystem::keyToggleCount = 0; + bool SHInputManagerSystem::keysToggle[MAX_KEYS]; + bool SHInputManagerSystem::keysToggleLast[MAX_KEYS]; + double SHInputManagerSystem::keysToggleOnTime[MAX_KEYS]; + double SHInputManagerSystem::keysToggleOffTime[MAX_KEYS]; + + int SHInputManagerSystem::mouseScreenX = 0; + int SHInputManagerSystem::mouseScreenY = 0; + int SHInputManagerSystem::mouseScreenXLast = 0; + int SHInputManagerSystem::mouseScreenYLast = 0; + int SHInputManagerSystem::mouseWheelVerticalDelta = 0; + int SHInputManagerSystem::mouseWheelVerticalDeltaPoll = 0; + + void SHInputManagerSystem::InputManagerRoutine:: + FixedExecute(double dt) noexcept + { + //Keyboard and Mouse Buttons//////////////////////////////////////////////// + //Poll + unsigned char keyboardState[MAX_KEYS]; + GetKeyboardState(keyboardState); + keyCount = 0; + keyToggleCount = 0; + for (size_t i = 0; i < MAX_KEYS; ++i) + { + //Ignore shift, ctrl and alt since they are split to left and right + if (static_cast(i) == SH_KEYCODE::SHIFT || + static_cast(i) == SH_KEYCODE::CTRL || + static_cast(i) == SH_KEYCODE::ALT) + continue; + + //Pressed state + if (keyboardState[i] & 0b10000000) + { + ++keyCount; + keys[i] = true; + } + else keys[i] = false; + + //Toggle state + if (keyboardState[i] & 0b00000001) + { + ++keyToggleCount; + keysToggle[i] = true; + } + else keysToggle[i] = false; + } + + //Timers + for (size_t i = 0; i < MAX_KEYS; ++i) + { + if (keys[i]) //Key is down + { + if (!keysLast[i]) //Key was just pressed + { + keysHeldTime[i] = 0.0; //Reset timer + } + keysHeldTime[i] += dt; //Tick up + } + else //Key is up + { + if (keysLast[i]) //Key was just released + { + keysReleasedTime[i] = 0.0; //Reset timer + } + keysReleasedTime[i] += dt; //Tick up + } + } + + //Write to lastKeys + memcpy(keysLast, keys, sizeof(keys)); + + //Mouse Positioning///////////////////////////////////// + //https://stackoverflow.com/a/6423739 + + //Get cursor position, even when it is outside window + POINT p; + GetCursorPos(&p); + mouseScreenX = p.x; + mouseScreenY = p.y; + + //Mouse wheel vertical delta updating + mouseWheelVerticalDelta = 0; + mouseWheelVerticalDelta = mouseWheelVerticalDeltaPoll; + mouseWheelVerticalDeltaPoll = 0; + } + + bool SHInputManagerSystem::AnyKeyDown(SH_KEYCODE* firstDetected) noexcept + { + for (size_t i = 0; i < MAX_KEYS; ++i) + { + if (keys[i] && !keysLast[i]) + { + if (firstDetected) *firstDetected = static_cast(i); + return true; + } + } + return false; + } + + bool SHInputManagerSystem::AnyKey(SH_KEYCODE* firstDetected) noexcept + { + for (size_t i = 0; i < MAX_KEYS; ++i) + { + if (keys[i]) + { + if (firstDetected) *firstDetected = static_cast(i); + return true; + } + } + return false; + } + + bool SHInputManagerSystem::AnyKeyUp(SH_KEYCODE* firstDetected) noexcept + { + for (size_t i = 0; i < MAX_KEYS; ++i) + { + + } + } + +} //namespace SHADE \ No newline at end of file diff --git a/SHADE_Engine/src/Input/SHInputManagerSystem.h b/SHADE_Engine/src/Input/SHInputManagerSystem.h new file mode 100644 index 00000000..39c97d6f --- /dev/null +++ b/SHADE_Engine/src/Input/SHInputManagerSystem.h @@ -0,0 +1,559 @@ +/********************************************************************* + * \file SHInputManagerSystem.h + * \author Ryan Wang Nian Jing + * \brief Declaration of input manager. + * Handles input from keyboard and mouse. Soon to include controller. + * + * \copyright 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 +#include "../../SHADE_Managed/src/SHpch.h" +#include "ECS_Base/System/SHSystem.h" +#include "ECS_Base/System/SHFixedSystemRoutine.h" + +namespace SHADE +{ + class SH_API SHInputManagerSystem : public SHSystem + { + public: + class SH_API InputManagerRoutine : public SHFixedSystemRoutine + { + public: + virtual void FixedExecute(double dt) noexcept override final; + }; + + public: + /*------------------------------------------------------------------------*/ + /* Enumerations */ + /*------------------------------------------------------------------------*/ + enum class SH_KEYCODE + { + LMB = 0X01, + RMB = 0X02, + CANCEL = 0X03, + MMB = 0X04, + XMB1 = 0X05, + XMB2 = 0X06, + + BACKSPACE = 0X08, + TAB = 0X09, + + CLEAR = 0X0C, + ENTER = 0X0D, + + SHIFT = 0X10, //USE LEFT OR RIGHT SHIFT INSTEAD + CTRL = 0X11, //USE LEFT OR RIGHT CTRL INSTEAD + ALT = 0X12, //USE LEFT OR RIGHT ALT INSTEAD + PAUSE = 0X13, + CAPS_LOCK = 0X14, + IME_KANA = 0X15, + IME_HANGUL = 0X15, + IME_ON = 0X16, + IME_JUNJA = 0X17, + IME_FINAL = 0X18, + IME_HANJA = 0X19, + IME_KANJI = 0X19, + IME_OFF = 0X1A, + ESCAPE = 0X1B, + IME_CONVERT = 0X1C, + IME_NONCONVERT = 0X1D, + IME_ACCEPT = 0X1E, + IME_MODECHANGE = 0X1F, + SPACE = 0X20, + PAGE_UP = 0X21, + PAGE_DOWN = 0X22, + END = 0X23, + HOME = 0X24, + LEFT_ARROW = 0X25, + UP_ARROW = 0X26, + RIGHT_ARROW = 0X27, + DOWN_ARROW = 0X28, + SELECT = 0X29, + PRINT = 0X2A, + EXECUTE = 0X2B, + PRINT_SCREEN = 0X2C, + INSERT = 0X2D, + DEL = 0X2E, + HELP = 0X2F, + + NUMBER_0 = 0X30, + NUMBER_1, + NUMBER_2, + NUMBER_3, + NUMBER_4, + NUMBER_5, + NUMBER_6, + NUMBER_7, + NUMBER_8, + NUMBER_9, + + A = 0X41, + B, + C, + D, + E, + F, + G, + H, + I, + J, + K, + L, + M, + N, + O, + P, + Q, + R, + S, + T, + U, + V, + W, + X, + Y, + Z, + + LEFT_WINDOWS = 0X5B, + RIGHT_WINDOWS, + APPS, + + SLEEP = 0X5F, + + NUMPAD_0 = 0X60, + NUMPAD_1, + NUMPAD_2, + NUMPAD_3, + NUMPAD_4, + NUMPAD_5, + NUMPAD_6, + NUMPAD_7, + NUMPAD_8, + NUMPAD_9, + + MULTIPLY = 0X6A, + ADD, + SEPARATOR, + SUBTRACT, + DECIMAL, + DIVIDE, + + F1 = 0X70, + F2, + F3, + F4, + F5, + F6, + F7, + F8, + F9, + F10, + F11, + F12, + F13, + F14, + F15, + F16, + F17, + F18, + F19, + F20, + F21, + F22, + F23, + F24, + + NUM_LOCK = 0X90, + SCROLL_LOCK = 0X91, + + OEM_PC98_NUMPAD_EQUAL = 0X92, + OEM_FUJITSU_DICTIONARY = 0X92, + OEM_FUJITSU_UNREGISTER, + OEM_FUJITSU_REGISTER, + OEM_FUJITSU_LEFT_THUMB, + OEM_FUJITSU_RIGHT_THUMB, + + LEFT_SHIFT = 0XA0, + RIGHT_SHIFT, + LEFT_CTRL, + RIGHT_CTRL, + LEFT_ALT, + RIGHT_ALT, + BROWSER_BACK, + BROWSER_FORWARD, + BROWSER_REFRESH, + BROWSER_STOP, + BROWSER_SEARCH, + BROWSER_FAVOURITES, + BROWSER_HOME, + VOLUME_MUTE, + VOLUME_DOWN, + VOLUME_UP, + MEDIA_NEXT_TRACK, + MEDIA_PREVIOUS_TRACK, + MEDIA_STOP, + MEDIA_PLAY_PAUSE, + LAUNCH_MAIL, + LAUNCH_MEDIA_SELECT, + LAUNCH_APP_1, + LAUNCH_APP_2, + + OEM_1 = 0XBA, + OEM_PLUS, + OEM_COMMA, + OEM_MINUS, + OEM_PERIOD, + OEM_2, + OEM_3, + + GAMEPAD_A = 0XC3, + GAMEPAD_B, + GAMEPAD_X, + GAMEPAD_Y, + GAMEPAD_RIGHTSHOULDER, + GAMEPAD_LEFTSHOULDER, + GAMEPAD_LEFTTRIGGER, + GAMEPAD_RIGHTTRIGGER, + GAMEPAD_DPAD_UP, + GAMEPAD_DPAD_DOWN, + GAMEPAD_DPAD_LEFT, + GAMEPAD_DPAD_RIGHT, + GAMEPAD_MENU, + GAMEPAD_VIEW, + GAMEPAD_LEFT_THUMBSTICK_BUTTON, + GAMEPAD_RIGHT_THUMBSTICK_BUTTON, + GAMEPAD_LEFT_THUMBSTICK_UP, + GAMEPAD_LEFT_THUMBSTICK_DOWN, + GAMEPAD_LEFT_THUMBSTICK_RIGHT, + GAMEPAD_LEFT_THUMBSTICK_LEFT, + GAMEPAD_RIGHT_THUMBSTICK_UP, + GAMEPAD_RIGHT_THUMBSTICK_DOWN, + GAMEPAD_RIGHT_THUMBSTICK_RIGHT, + GAMEPAD_RIGHT_THUMBSTICK_LEFT, + + OEM_4, + OEM_5, + OEM_6, + OEM_7, + OEM_8, + + OEM_AX = 0XE1, + OEM_102, + OEM_ICO_HELP, + OEM_ICO_00, + IME_PROCESS, + OEM_ICO_CLEAR, + PACKET, + + OEM_RESET = 0XE9, + OEM_JUMP, + OEM_PA1, + OEM_PA2, + OEM_PA3, + OEM_WSCTRL, + OEM_CUSEL, + OEM_ATTN, + OEM_FINISH, + OEM_COPY, + OEM_AUTO, + OEM_ENLW, + OEM_BACKTAB, + + ATTN, + CRSEL, + EXSEL, + EREOF, + PLAY, + ZOOM, + NONAME, + PA_1, + OEM_CLEAR + }; + + public: + /*------------------------------------------------------------------------*/ + /* Constructors & Destructor */ + /*------------------------------------------------------------------------*/ + SHInputManagerSystem() noexcept = default; + ~SHInputManagerSystem() noexcept = default; + + SHInputManagerSystem(const SHInputManagerSystem&) = delete; + SHInputManagerSystem(SHInputManagerSystem&&) = delete; + + SHInputManagerSystem& operator= (const SHInputManagerSystem&) = delete; + SHInputManagerSystem& operator= (SHInputManagerSystem&&) = delete; + + /*------------------------------------------------------------------------*/ + /* SHSystem Overrides */ + /*------------------------------------------------------------------------*/ + virtual void Init() override final; + virtual void Exit() override final; + + /*------------------------------------------------------------------------*/ + /* Member Functions */ + /*------------------------------------------------------------------------*/ + + //Needs to be linked to WM_MOUSEWHEEL in wndProc + static inline void PollWheelVerticalDelta(WPARAM wParam) noexcept + { + mouseWheelVerticalDeltaPoll += GET_WHEEL_DELTA_WPARAM(wParam); + } + + //For testing purposes + //static void PrintCurrentState() noexcept; + + /*------------------------------------------------------------------------*/ + /* Input state accessors (KB & M) */ + /*------------------------------------------------------------------------*/ + //Get how many keys are presently down + static inline unsigned GetKeyCount() noexcept + { + return keyCount; + } + + //How many keys are presently toggled + static inline unsigned GetKeyToggleCount() noexcept + { + return keyToggleCount; + } + + //Any key pressed in THIS FRAME ONLY + //Keys being held beforehand don't count + //Output parameter is which key was first to be detected + static bool AnyKeyDown(SH_KEYCODE* firstKey = nullptr) noexcept; + + //Any key is being held down + //Return false if no key being held + //Output parameter is which key was first to be detected + static bool AnyKey(SH_KEYCODE* firstKey = nullptr) noexcept; + + //Any key released in THIS FRAME ONLY + //Keys that are released beforehand don't count + //Output parameter is which key was first to be detected + static bool AnyKeyUp(SH_KEYCODE* firstKey = nullptr) noexcept; + + //Check if a particular key was pressed down in THIS FRAME ONLY + //Keys being held beforehand don't count + //Output parameter is how long the key has been released for prior + static inline bool GetKeyDown (SH_KEYCODE key, + double* releasedTime = nullptr) noexcept + { + if (releasedTime) *releasedTime = keysReleasedTime[static_cast(key)]; + return (keys[static_cast(key)] && !keysLast[static_cast(key)]); + } + + //Check if a particular key was toggled on in THIS FRAME ONLY + //Keys that stay toggled on afterwards don't count + //Output parameter is how long the key has been toggled off for prior + static inline bool GetKeyToggleOn (SH_KEYCODE key, + double* toggleOffTime = nullptr) noexcept + { + if (toggleOffTime) + *toggleOffTime = keysToggleOffTime[static_cast(key)]; + return (keysToggle[static_cast(key)] && + !keysToggleLast[static_cast(key)]); + } + + //Check if a particular key is presently being held down on + //Output parameter is how long the key has been held and released + static inline bool GetKey(SH_KEYCODE key, + double* heldTime = nullptr, double* releasedTime = nullptr) noexcept + { + if (heldTime) *heldTime = keysHeldTime[static_cast(key)]; + if (releasedTime) *releasedTime = keysReleasedTime[static_cast(key)]; + return keys[static_cast(key)]; + } + + //Check if a particular key is presently toggled on + //Output parameter is how long the key has been toggled on and off + static inline bool GetKeyToggle(SH_KEYCODE key, + double* onTime = nullptr, double* offTime = nullptr) noexcept + { + if (onTime) *onTime = keysToggleOnTime[static_cast(key)]; + if (offTime) *offTime = keysToggleOffTime[static_cast(key)]; + return keysToggle[static_cast(key)]; + } + + //Check if a particular key was released in THIS FRAME ONLY + //Keys already released beforehand don't count + //Output parameter is how long the key has been held for prior + static inline bool GetKeyUp(SH_KEYCODE key, + double* heldTime = nullptr) noexcept + { + if (heldTime) *heldTime = keysHeldTime[static_cast(key)]; + return (!keys[static_cast(key)] && keysLast[static_cast(key)]); + } + + //Check if a particular key was toggled off in THIS FRAME ONLY + //Keys that stay toggled off afterwards don't count + //Output parameter is how long the key has been toggled on for prior + static inline bool GetKeyToggleOff(SH_KEYCODE key, + double* toggleOnTime = nullptr) noexcept + { + if (toggleOnTime) + *toggleOnTime = keysToggleOnTime[static_cast(key)]; + return (!keysToggle[static_cast(key)] && + keysToggleLast[static_cast(key)]); + } + + //Mouse///////////// + + //Get the mouse location with respect to the screen + static inline void GetMouseScreenPosition (int* x = nullptr, + int* y = nullptr) noexcept + { + if (x) *x = mouseScreenX; + if (y) *y = mouseScreenY; + } + + //Get the mouse location with respect to current window + static inline void GetMouseWindowPosition (int* x = nullptr, + int* y = nullptr) noexcept + { + POINT p{ mouseScreenX, mouseScreenY }; + ScreenToClient(GetActiveWindow(), &p); + if (x) *x = mouseScreenX; + if (y) *y = mouseScreenY; + } + + //Get the mouse wheel vertical delta + static inline int GetMouseWheelVerticalDelta() noexcept + { + return mouseWheelVerticalDelta; + } + + //GET INPUT TIMINGS/////////////////////////////////////////////////////////// + + //Keyboard///////////// + + //How long has this key been held down for + static inline double GetKeyHeldTime(SH_KEYCODE key) noexcept + { + return keysHeldTime[static_cast(key)]; + } + + //How long has this key been released for + static inline double GetKeyReleasedTime(SH_KEYCODE key) noexcept + { + return keysReleasedTime[static_cast(key)]; + } + + //How long has this key been toggled on for + static inline double GetKeyToggleOnTime(SH_KEYCODE key) noexcept + { + return keysToggleOnTime[static_cast(key)]; + } + + //How long has this keen been toggled off for + static inline double GetKeyToggleOffTime(SH_KEYCODE key) noexcept + { + return keysToggleOffTime[static_cast(key)]; + } + + /*------------------------------------------------------------------------*/ + /* Other Functions */ + /*------------------------------------------------------------------------*/ + + //Mouse//////////////////////// + + //Move mouse cursor to a position on the screen + static inline void SetMouseScreenPosition(int x = 0, int y = 0) noexcept + { + SetCursorPos(x, y); + } + + //Move mouse cursor to a position on the active window + static inline void SetMouseWindowPosition(int x = 0, int y = 0) noexcept + { + POINT p{ x, y }; + ClientToScreen(GetActiveWindow(), &p); + SetCursorPos(p.x, p.y); + } + + private: + /*------------------------------------------------------------------------*/ + /* Constants */ + /*------------------------------------------------------------------------*/ + static constexpr size_t MAX_KEYS = UCHAR_MAX + 1; + + /*------------------------------------------------------------------------*/ + /* Data Members */ + /*------------------------------------------------------------------------*/ + + //KEYBOARD AND MOUSE BUTTONS//////////////////////////////////////////////// + + //How many keys are presently being pressed + static unsigned keyCount; + + //Key states of all keys presently + //true for being pressed, false for released + static bool keys[MAX_KEYS]; + + //Key states of all keys in the last frame + //true for being pressed, false for released + static bool keysLast[MAX_KEYS]; + + //Key held durations + //Stops ticking up when released + //Will be reset when held again + static double keysHeldTime[MAX_KEYS]; + + //Key released durations + //Stops ticking up when held + //Will be reset when off again + static double keysReleasedTime[MAX_KEYS]; + + //How many keys are presently being toggled + static unsigned keyToggleCount; + + //Toggle key states of keys (not neccessarily just caps/num/scroll locks) + static bool keysToggle[MAX_KEYS]; + + //Toggle key states of keys in the last frame + static bool keysToggleLast[MAX_KEYS]; + + //Key toggle durations + //Stops ticking up when untoggled + //Will be reset when toggled again + static double keysToggleOnTime[MAX_KEYS]; + + //Key untoggle durations + //Stops ticking up when toggled + //Will be reset when untoggled again + static double keysToggleOffTime[MAX_KEYS]; + + //MOUSE VARIABLES/////////////////////////////////////////////////////////// + + //Present horizontal positioning of the mouse WRT the screen + static int mouseScreenX; + //Present vertical positioning of the mouse WRT the screen + static int mouseScreenY; + + //Horizontal positioning of the mouse WRT screen in last frame + static int mouseScreenXLast; + //Vertical positioning of the mouse WRT screen in the last frame + static int mouseScreenYLast; + + //For polling mouse wheel events, not to be read + static int mouseWheelVerticalDeltaPoll; + //Mouse wheel vertical rotation speed. Positive is rotation AWAY from user + static int mouseWheelVerticalDelta; + + //CONTROLLER VARIABLES////////////////////////////////////////////////////// + + //OTHER VARIABLES/////////////////////////////////////////////////////////// + + //Axis bindings + //X + + //Y + + //Other mappings + + //Buffer + }; +} \ No newline at end of file From 23f0f9f77e68cf050e58f7de3f84c6c02e3b521f Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Fri, 23 Sep 2022 16:24:08 +0800 Subject: [PATCH 10/26] Triple buffered the batching buffers --- .../Graphics/MiddleEnd/Batching/SHBatch.cpp | 177 +++++++++++------- .../src/Graphics/MiddleEnd/Batching/SHBatch.h | 22 ++- .../Graphics/MiddleEnd/Batching/SHBatcher.cpp | 10 +- .../Graphics/MiddleEnd/Batching/SHBatcher.h | 4 +- .../MiddleEnd/Batching/SHSuperBatch.cpp | 14 +- .../MiddleEnd/Batching/SHSuperBatch.h | 6 +- .../MiddleEnd/Interface/SHGraphicsSystem.cpp | 2 +- .../Graphics/RenderGraph/SHRenderGraph.cpp | 25 +-- .../src/Graphics/RenderGraph/SHRenderGraph.h | 7 +- 9 files changed, 158 insertions(+), 109 deletions(-) diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.cpp index c2090fc0..1ac783e0 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.cpp @@ -33,6 +33,9 @@ namespace SHADE { if (!pipeline) throw std::invalid_argument("Attempted to create a SHBatch with an invalid SHPipeline!"); + + // Mark all as dirty + setAllDirtyFlags(); } void SHBatch::Add(const SHRenderable* renderable) @@ -52,6 +55,9 @@ namespace SHADE // Add renderable in subBatch->Renderables.insert(renderable); + + // Mark all as dirty + setAllDirtyFlags(); } void SHBatch::Remove(const SHRenderable* renderable) @@ -67,6 +73,10 @@ namespace SHADE return; subBatch->Renderables.erase(renderable); + + // Mark all as dirty + for (bool& dirt : isDirty) + dirt = true; } void SHBatch::Clear() @@ -81,13 +91,22 @@ namespace SHADE // Clear GPU buffers - drawDataBuffer.Free(); - transformDataBuffer.Free(); - matPropsBuffer.Free(); + for (int i = 0; i < SHGraphicsConstants::NUM_FRAME_BUFFERS; ++i) + { + drawDataBuffer[i].Free(); + transformDataBuffer[i].Free(); + matPropsBuffer[i].Free(); + } } - void SHBatch::UpdateTransformBuffer() + void SHBatch::UpdateTransformBuffer(uint32_t frameIndex) { + if (frameIndex >= SHGraphicsConstants::NUM_FRAME_BUFFERS) + { + SHLOG_WARNING("[SHBatch] Attempted to update transform buffers with an invalid frame index."); + return; + } + // Reset Transform Data transformData.clear(); @@ -100,13 +119,19 @@ namespace SHADE } // Transfer to GPU - transformDataBuffer->WriteToMemory(transformData.data(), transformData.size() * sizeof(SHMatrix), 0, 0); + transformDataBuffer[frameIndex]->WriteToMemory(transformData.data(), transformData.size() * sizeof(SHMatrix), 0, 0); } - void SHBatch::Build(Handle device) + void SHBatch::Build(Handle device, uint32_t frameIndex) { + if (frameIndex >= SHGraphicsConstants::NUM_FRAME_BUFFERS) + { + SHLOG_WARNING("[SHBatch] Attempted to update build batch buffers with an invalid frame index."); + return; + } + // No need to build as there are no changes - if (!isDirty) + if (!isDirty[frameIndex]) return; // Count number of elements @@ -116,61 +141,67 @@ namespace SHADE numTotalElements += subBatch.Renderables.size(); } - // Generate CPU buffers - // - Draw data - drawData.reserve(subBatches.size()); - drawData.clear(); - // - Transform data - transformData.reserve(numTotalElements); - transformData.clear(); - // - Material Properties Data - const Handle SHADER_INFO = pipeline->GetPipelineLayout()->GetShaderBlockInterface - ( - SHGraphicsConstants::DescriptorSetIndex::PER_INSTANCE, - SHGraphicsConstants::DescriptorSetBindings::BATCHED_PER_INST_DATA, - vk::ShaderStageFlagBits::eFragment - ); - const bool EMPTY_MAT_PROPS = !SHADER_INFO; - Byte singleMatPropSize = 0; - Byte matPropTotalBytes = 0; - if (!EMPTY_MAT_PROPS) + // Generate CPU buffers if there are changes + if (isCPUBuffersDirty) { - singleMatPropSize = SHADER_INFO->GetBytesRequired(); - matPropTotalBytes = drawData.size() * singleMatPropSize; - if (matPropsDataSize < matPropTotalBytes) + // - Draw data + drawData.reserve(subBatches.size()); + drawData.clear(); + // - Transform data + transformData.reserve(numTotalElements); + transformData.clear(); + // - Material Properties Data + const Handle SHADER_INFO = pipeline->GetPipelineLayout()->GetShaderBlockInterface + ( + SHGraphicsConstants::DescriptorSetIndex::PER_INSTANCE, + SHGraphicsConstants::DescriptorSetBindings::BATCHED_PER_INST_DATA, + vk::ShaderStageFlagBits::eFragment + ); + const bool EMPTY_MAT_PROPS = !SHADER_INFO; + Byte singleMatPropSize = 0; + Byte matPropTotalBytes = 0; + if (!EMPTY_MAT_PROPS) { - matPropsData.reset(new char[matPropTotalBytes]); - matPropsDataSize = matPropTotalBytes; - } - } - - // Build Sub Batches - uint32_t nextInstanceIndex = 0; - char* propsCurrPtr = matPropsData.get(); - for (auto& subBatch : subBatches) - { - // Create command - drawData.emplace_back(vk::DrawIndexedIndirectCommand - { - .indexCount = subBatch.Mesh->IndexCount, - .instanceCount = static_cast(subBatch.Renderables.size()), - .firstIndex = subBatch.Mesh->FirstIndex, - .vertexOffset = subBatch.Mesh->FirstVertex, - .firstInstance = nextInstanceIndex - }); - - // Fill in buffers (CPU) - for (const SHRenderable* renderable : subBatch.Renderables) - { - // Transform - transformData.emplace_back(renderable->TransformMatrix); - // Material Properties - if (!EMPTY_MAT_PROPS) + singleMatPropSize = SHADER_INFO->GetBytesRequired(); + matPropTotalBytes = drawData.size() * singleMatPropSize; + if (matPropsDataSize < matPropTotalBytes) { - renderable->GetMaterial()->ExportProperties(propsCurrPtr); - propsCurrPtr += singleMatPropSize; + matPropsData.reset(new char[matPropTotalBytes]); + matPropsDataSize = matPropTotalBytes; } } + + // Build Sub Batches + uint32_t nextInstanceIndex = 0; + char* propsCurrPtr = matPropsData.get(); + for (auto& subBatch : subBatches) + { + // Create command + drawData.emplace_back(vk::DrawIndexedIndirectCommand + { + .indexCount = subBatch.Mesh->IndexCount, + .instanceCount = static_cast(subBatch.Renderables.size()), + .firstIndex = subBatch.Mesh->FirstIndex, + .vertexOffset = subBatch.Mesh->FirstVertex, + .firstInstance = nextInstanceIndex + }); + + // Fill in buffers (CPU) + for (const SHRenderable* renderable : subBatch.Renderables) + { + // Transform + transformData.emplace_back(renderable->TransformMatrix); + // Material Properties + if (!EMPTY_MAT_PROPS) + { + renderable->GetMaterial()->ExportProperties(propsCurrPtr); + propsCurrPtr += singleMatPropSize; + } + } + } + + // Successfully update CPU buffers + isCPUBuffersDirty = false; } // Send all buffered data to the GPU buffers @@ -179,36 +210,52 @@ namespace SHADE const uint32_t DRAW_DATA_BYTES = static_cast(drawData.size() * sizeof(vk::DrawIndexedIndirectCommand)); SHVkUtil::EnsureBufferAndCopyHostVisibleData ( - device, drawDataBuffer, drawData.data(), DRAW_DATA_BYTES, + device, drawDataBuffer[frameIndex], drawData.data(), DRAW_DATA_BYTES, BuffUsage::eIndirectBuffer ); // - Transform Buffer const uint32_t TF_DATA_BYTES = static_cast(transformData.size() * sizeof(SHMatrix)); SHVkUtil::EnsureBufferAndCopyHostVisibleData ( - device, transformDataBuffer, transformData.data(), TF_DATA_BYTES, + device, transformDataBuffer[frameIndex], transformData.data(), TF_DATA_BYTES, BuffUsage::eVertexBuffer ); // - Material Properties Buffer - if (!EMPTY_MAT_PROPS) + if (matPropsData) { SHVkUtil::EnsureBufferAndCopyHostVisibleData ( - device, matPropsBuffer, matPropsData.get(), static_cast(matPropTotalBytes), + device, matPropsBuffer[frameIndex], matPropsData.get(), static_cast(matPropsDataSize), BuffUsage::eStorageBuffer ); } - isDirty = false; + isDirty[frameIndex] = false; } /*---------------------------------------------------------------------------------*/ /* SHBatch - Usage Functions */ /*---------------------------------------------------------------------------------*/ - void SHBatch::Draw(Handle cmdBuffer) + void SHBatch::Draw(Handle cmdBuffer, uint32_t frameIndex) { + if (frameIndex >= SHGraphicsConstants::NUM_FRAME_BUFFERS) + { + SHLOG_WARNING("[SHBatch] Attempted to draw a batch with an invalid frame index."); + return; + } + cmdBuffer->BindPipeline(pipeline); - cmdBuffer->BindVertexBuffer(SHGraphicsConstants::VertexBufferBindings::TRANSFORM, transformDataBuffer, 0); - cmdBuffer->DrawMultiIndirect(drawDataBuffer, static_cast(drawData.size())); + cmdBuffer->BindVertexBuffer(SHGraphicsConstants::VertexBufferBindings::TRANSFORM, transformDataBuffer[frameIndex], 0); + cmdBuffer->DrawMultiIndirect(drawDataBuffer[frameIndex], static_cast(drawData.size())); + } + + /*---------------------------------------------------------------------------------*/ + /* SHBatch - Helper Functions */ + /*---------------------------------------------------------------------------------*/ + void SHBatch::setAllDirtyFlags() + { + for (bool& dirt : isDirty) + dirt = true; + isCPUBuffersDirty = true; } } diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.h b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.h index f438d6c1..a572adca 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.h @@ -14,12 +14,14 @@ of DigiPen Institute of Technology is prohibited. // STL Includes #include +#include // External Dependencies #include "Graphics/SHVulkanIncludes.h" // Project Includes #include "Resource/Handle.h" #include "Graphics/MiddleEnd/Interface/SHMaterial.h" #include "Math/SHMatrix.h" +#include "Graphics/MiddleEnd/Interface/SHGraphicsConstants.h" namespace SHADE { @@ -71,9 +73,9 @@ namespace SHADE void Add(const SHRenderable* renderable); void Remove(const SHRenderable* renderable); void Clear(); - void UpdateTransformBuffer(); - void Build(Handle device); - void Draw(Handle cmdBuffer); + void UpdateTransformBuffer(uint32_t frameIndex); + void Build(Handle device, uint32_t frameIndex); + void Draw(Handle cmdBuffer, uint32_t frameIndex); /*-----------------------------------------------------------------------------*/ /* Getter Functions */ @@ -88,15 +90,21 @@ namespace SHADE Handle pipeline; // Batch Tree std::vector subBatches; - bool isDirty = true; + std::array isDirty; // CPU Buffers std::vector drawData; std::vector transformData; std::unique_ptr matPropsData; Byte matPropsDataSize = 0; + bool isCPUBuffersDirty = true; // GPU Buffers - Handle drawDataBuffer; - Handle transformDataBuffer; - Handle matPropsBuffer; + std::array, SHGraphicsConstants::NUM_FRAME_BUFFERS> drawDataBuffer; + std::array, SHGraphicsConstants::NUM_FRAME_BUFFERS> transformDataBuffer; + std::array, SHGraphicsConstants::NUM_FRAME_BUFFERS> matPropsBuffer; + + /*-----------------------------------------------------------------------------*/ + /* Helper Functions */ + /*-----------------------------------------------------------------------------*/ + void setAllDirtyFlags(); }; } diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatcher.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatcher.cpp index ea216ed5..ecd99a20 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatcher.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatcher.cpp @@ -91,12 +91,12 @@ namespace SHADE (*superBatch)->Remove(renderable); } - void SHBatcher::FinaliseBatches(Handle device) + void SHBatcher::FinaliseBatches(Handle device, uint32_t frameIndex) { // Build SuperBatches for (auto& batch : superBatches) { - batch->Build(device); + batch->Build(device, frameIndex); } } @@ -109,11 +109,11 @@ namespace SHADE superBatches.clear(); } - void SHBatcher::UpdateTransformBuffer() - { + void SHBatcher::UpdateTransformBuffer(uint32_t frameIndex) +{ for (auto& batch : superBatches) { - batch->UpdateTransformBuffer(); + batch->UpdateTransformBuffer(frameIndex); } } diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatcher.h b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatcher.h index 89dea2eb..b4fff203 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatcher.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatcher.h @@ -51,9 +51,9 @@ namespace SHADE void PrepareBatches(); void AddToBatch(SHRenderable const* renderable); void RemoveFromBatch(SHRenderable const* renderable); - void FinaliseBatches(Handle device); + void FinaliseBatches(Handle device, uint32_t frameIndex); void ClearBatches(); - void UpdateTransformBuffer(); + void UpdateTransformBuffer(uint32_t frameIndex); void RegisterSuperBatch(Handle superBatch); void DeregisterSuperBatch(Handle superBatch); diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHSuperBatch.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHSuperBatch.cpp index 8b7ea619..a259f2cf 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHSuperBatch.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHSuperBatch.cpp @@ -78,29 +78,29 @@ namespace SHADE batches.clear(); } - void SHSuperBatch::UpdateTransformBuffer() - { + void SHSuperBatch::UpdateTransformBuffer(uint32_t frameIndex) +{ for (auto& batch : batches) { - batch.UpdateTransformBuffer(); + batch.UpdateTransformBuffer(frameIndex); } } - void SHSuperBatch::Build(Handle device) noexcept + void SHSuperBatch::Build(Handle device, uint32_t frameIndex) noexcept { // Build all batches for (auto& batch : batches) { - batch.Build(device); + batch.Build(device, frameIndex); } } - void SHSuperBatch::Draw(Handle cmdBuffer) noexcept + void SHSuperBatch::Draw(Handle cmdBuffer, uint32_t frameIndex) noexcept { // Build all batches for (auto& batch : batches) { - batch.Draw(cmdBuffer); + batch.Draw(cmdBuffer, frameIndex); } } diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHSuperBatch.h b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHSuperBatch.h index 6151e56e..5379ee61 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHSuperBatch.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHSuperBatch.h @@ -55,9 +55,9 @@ namespace SHADE void Add(const SHRenderable* renderable) noexcept; void Remove(const SHRenderable* renderable) noexcept; void Clear() noexcept; - void UpdateTransformBuffer(); - void Build(Handle device) noexcept; - void Draw(Handle cmdBuffer) noexcept; + void UpdateTransformBuffer(uint32_t frameIndex); + void Build(Handle device, uint32_t frameIndex) noexcept; + void Draw(Handle cmdBuffer, uint32_t frameIndex) noexcept; /*-----------------------------------------------------------------------------*/ /* Getter Functions */ diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp index cee00c9b..a68812f8 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp @@ -306,7 +306,7 @@ namespace SHADE for (auto vp : viewports) for (auto renderer : vp->GetRenderers()) { - renderer->GetRenderGraph()->FinaliseBatch(); + renderer->GetRenderGraph()->FinaliseBatch(renderContext.GetCurrentFrame()); } // Resize diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp index f53f3e99..ecf9059c 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp @@ -346,13 +346,13 @@ namespace SHADE inputReferences.push_back({ resourceAttachmentMapping->at(ptrToResources->at(resourceToReference).GetId().Raw), vk::ImageLayout::eShaderReadOnlyOptimal }); } - void SHSubpass::Execute(Handle& commandBuffer) noexcept + void SHSubpass::Execute(Handle& commandBuffer, uint32_t frameIndex) noexcept { // Ensure correct transforms are provided - superBatch->UpdateTransformBuffer(); + superBatch->UpdateTransformBuffer(frameIndex); // Draw all the batches - superBatch->Draw(commandBuffer); + superBatch->Draw(commandBuffer, frameIndex); // Draw all the exterior draw calls for (auto& drawCall : exteriorDrawCalls) @@ -591,7 +591,7 @@ namespace SHADE for (uint32_t i = 0; i < subpasses.size(); ++i) { - subpasses[i]->Execute(commandBuffer); + subpasses[i]->Execute(commandBuffer, frameIndex); // Go to next subpass if not last subpass if (i != subpasses.size() - 1) @@ -624,14 +624,9 @@ namespace SHADE return pipeline; } - void SHRenderGraphNode::FinaliseBatch() - { - batcher.FinaliseBatches(logicalDeviceHdl); - } - - void SHRenderGraphNode::UpdateBatchTransforms() - { - batcher.UpdateTransformBuffer(); + void SHRenderGraphNode::FinaliseBatch(uint32_t frameIndex) +{ + batcher.FinaliseBatches(logicalDeviceHdl, frameIndex); } /***************************************************************************/ @@ -1088,11 +1083,11 @@ namespace SHADE node->Execute(cmdBuffer, frameIndex); } - void SHRenderGraph::FinaliseBatch() - { + void SHRenderGraph::FinaliseBatch(uint32_t frameIndex) +{ for (auto& node : nodes) { - node->FinaliseBatch(); + node->FinaliseBatch(frameIndex); } } diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.h b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.h index 16770475..b8c00417 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.h +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.h @@ -137,7 +137,7 @@ namespace SHADE void AddInput(std::string resourceToReference) noexcept; // Runtime functions - void Execute(Handle& commandBuffer) noexcept; + void Execute(Handle& commandBuffer, uint32_t frameIndex) noexcept; void AddExteriorDrawCalls(std::function&)> const& newDrawCall) noexcept; /*-----------------------------------------------------------------------*/ @@ -230,8 +230,7 @@ namespace SHADE // TODO: RemoveSubpass() void Execute (Handle& commandBuffer, uint32_t frameIndex) noexcept; Handle GetOrCreatePipeline (std::pair, Handle> const& vsFsPair, Handle subpass) noexcept; - void FinaliseBatch(); - void UpdateBatchTransforms(); + void FinaliseBatch(uint32_t frameIndex); /*-----------------------------------------------------------------------*/ /* SETTERS AND GETTERS */ @@ -289,7 +288,7 @@ namespace SHADE Handle AddNode (std::string nodeName, std::initializer_list resourceNames, std::initializer_list predecessorNodes) noexcept; void Generate (void) noexcept; void Execute (uint32_t frameIndex, Handle cmdBuffer) noexcept; - void FinaliseBatch(); + void FinaliseBatch(uint32_t frameIndex); /*-----------------------------------------------------------------------*/ /* SETTERS AND GETTERS */ From 77cccd63be66d2e0991c29f5c3d1c0751bc06ff1 Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Fri, 23 Sep 2022 16:41:44 +0800 Subject: [PATCH 11/26] Renderables now use TransformComponent's matrix --- SHADE_Application/src/Scenes/SBTestScene.cpp | 10 ++------ .../Graphics/MiddleEnd/Batching/SHBatch.cpp | 24 +++++++++++++++++-- .../MiddleEnd/Interface/SHRenderable.cpp | 1 - .../MiddleEnd/Interface/SHRenderable.h | 1 - 4 files changed, 24 insertions(+), 12 deletions(-) diff --git a/SHADE_Application/src/Scenes/SBTestScene.cpp b/SHADE_Application/src/Scenes/SBTestScene.cpp index c642aa67..1c4af3a7 100644 --- a/SHADE_Application/src/Scenes/SBTestScene.cpp +++ b/SHADE_Application/src/Scenes/SBTestScene.cpp @@ -45,11 +45,7 @@ namespace Sandbox renderable.Mesh = CUBE_MESH; renderable.SetMaterial(matInst); - // Create transform - auto& transform = *SHADE::SHComponentManager::GetComponent_s(testObj); - transform.SetLocalPosition(SHVec3{ 0.0f, 0.0f, 2.0f }); - renderable.TransformMatrix = SHMatrix::Translate(0.0f, 0.0f, 2.0f); SHADE::SHScriptEngine* scriptEngine = static_cast(SHADE::SHSystemManager::GetSystem()); scriptEngine->AddScript(*SHADE::SHEntityManager::GetEntityByID(testObj), "TestScript"); } @@ -58,11 +54,9 @@ namespace Sandbox { static float rotation = 0.0f; - auto& renderable = *SHADE::SHComponentManager::GetComponent_s(testObj); - SHTransform tf; - tf.rotation = SHVec3(rotation, 0.0f, 0.0f); - renderable.TransformMatrix = tf.ComputeTRS(); + auto& transform = *SHADE::SHComponentManager::GetComponent_s(testObj); + transform.SetLocalRotation(rotation, 0.0f, 0.0f); rotation += dt * 10.0f; // Destroy entity if space is pressed diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.cpp index 1ac783e0..9d496821 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.cpp @@ -22,6 +22,8 @@ of DigiPen Institute of Technology is prohibited. #include "Graphics/Pipeline/SHVkPipeline.h" #include "Graphics/MiddleEnd/Interface/SHGraphicsConstants.h" #include "Graphics/MiddleEnd/Interface/SHMaterialInstance.h" +#include "ECS_Base/Managers/SHComponentManager.h" +#include "Math/Transform/SHTransformComponent.h" namespace SHADE { @@ -115,7 +117,16 @@ namespace SHADE for (const SHRenderable* renderable : subBatch.Renderables) { // Transform - transformData.emplace_back(renderable->TransformMatrix); + auto transform = SHComponentManager::GetComponent_s(renderable->GetEID()); + if (!transform) + { + SHLOG_WARNING("[SHBatch] Entity contianing a SHRenderable with no SHTransformComponent found!"); + transformData.emplace_back(); + } + else + { + transformData.emplace_back(transform->GetTRS()); + } } // Transfer to GPU @@ -190,7 +201,16 @@ namespace SHADE for (const SHRenderable* renderable : subBatch.Renderables) { // Transform - transformData.emplace_back(renderable->TransformMatrix); + auto transform = SHComponentManager::GetComponent_s(renderable->GetEID()); + if (!transform) + { + SHLOG_WARNING("[SHBatch] Entity contianing a SHRenderable with no SHTransformComponent found!"); + transformData.emplace_back(); + } + else + { + transformData.emplace_back(transform->GetTRS()); + } // Material Properties if (!EMPTY_MAT_PROPS) { diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderable.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderable.cpp index 32a6a99a..5199565c 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderable.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderable.cpp @@ -92,5 +92,4 @@ namespace SHADE materialChanged = false; oldMaterial = {}; } - } diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderable.h b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderable.h index 0d48b5cb..3bb7cfda 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderable.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderable.h @@ -66,7 +66,6 @@ namespace SHADE /* Data Members */ /*-------------------------------------------------------------------------------*/ Handle Mesh; - SHMatrix TransformMatrix; // TODO: Replace with Transform component private: /*-------------------------------------------------------------------------------*/ From f8391d6c9e6bf3ae48bf2b8dbe1e84a06e36c566 Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Fri, 23 Sep 2022 16:45:06 +0800 Subject: [PATCH 12/26] Modified TestScene space bar input to not destroy the object, only remove scripts --- SHADE_Application/src/Scenes/SBTestScene.cpp | 7 +++++-- SHADE_Engine/src/Scripting/SHScriptEngine.cpp | 12 ++++++------ SHADE_Engine/src/Scripting/SHScriptEngine.h | 6 +++--- 3 files changed, 14 insertions(+), 11 deletions(-) diff --git a/SHADE_Application/src/Scenes/SBTestScene.cpp b/SHADE_Application/src/Scenes/SBTestScene.cpp index 1c4af3a7..f5985715 100644 --- a/SHADE_Application/src/Scenes/SBTestScene.cpp +++ b/SHADE_Application/src/Scenes/SBTestScene.cpp @@ -47,7 +47,7 @@ namespace Sandbox renderable.SetMaterial(matInst); SHADE::SHScriptEngine* scriptEngine = static_cast(SHADE::SHSystemManager::GetSystem()); - scriptEngine->AddScript(*SHADE::SHEntityManager::GetEntityByID(testObj), "TestScript"); + scriptEngine->AddScript(testObj, "TestScript"); } void SBTestScene::Update(float dt) @@ -61,7 +61,10 @@ namespace Sandbox // Destroy entity if space is pressed if (GetKeyState(VK_SPACE) & 0x8000) - SHADE::SHEntityManager::DestroyEntity(testObj); + { + SHADE::SHScriptEngine* scriptEngine = static_cast(SHADE::SHSystemManager::GetSystem()); + scriptEngine->RemoveAllScripts(testObj); + } } void SBTestScene::Render() diff --git a/SHADE_Engine/src/Scripting/SHScriptEngine.cpp b/SHADE_Engine/src/Scripting/SHScriptEngine.cpp index fada5b70..0c508a34 100644 --- a/SHADE_Engine/src/Scripting/SHScriptEngine.cpp +++ b/SHADE_Engine/src/Scripting/SHScriptEngine.cpp @@ -103,17 +103,17 @@ namespace SHADE /*-----------------------------------------------------------------------------------*/ /* Script Manipulation Functions */ /*-----------------------------------------------------------------------------------*/ - bool SHScriptEngine::AddScript(const SHEntity& entity, const std::string_view& scriptName) + bool SHScriptEngine::AddScript(EntityID entity, const std::string_view& scriptName) { - return csScriptsAdd(entity.GetEID(), scriptName.data()); + return csScriptsAdd(entity, scriptName.data()); } - void SHScriptEngine::RemoveAllScripts(const SHEntity& entity) + void SHScriptEngine::RemoveAllScripts(EntityID entity) { - csScriptsRemoveAll(entity.GetEID()); + csScriptsRemoveAll(entity); } - void SHScriptEngine::RemoveAllScriptsImmediately(const SHEntity& entity, bool callOnDestroy) + void SHScriptEngine::RemoveAllScriptsImmediately(EntityID entity, bool callOnDestroy) { - csScriptsRemoveAllImmediately(entity.GetEID(), callOnDestroy); + csScriptsRemoveAllImmediately(entity, callOnDestroy); } /*---------------------------------------------------------------------------------*/ diff --git a/SHADE_Engine/src/Scripting/SHScriptEngine.h b/SHADE_Engine/src/Scripting/SHScriptEngine.h index 0994bb5d..08852e90 100644 --- a/SHADE_Engine/src/Scripting/SHScriptEngine.h +++ b/SHADE_Engine/src/Scripting/SHScriptEngine.h @@ -116,14 +116,14 @@ namespace SHADE /// True if successfully added. False otherwise with the error logged to the /// console. /// - bool AddScript(const SHEntity& entity, const std::string_view& scriptName); + bool AddScript(EntityID entity, const std::string_view& scriptName); /// /// Removes all Scripts attached to the specified Entity. Does not do anything /// if the specified Entity is invalid or does not have any Scripts /// attached. /// /// The entity to remove the scripts from. - void RemoveAllScripts(const SHEntity& entity); + void RemoveAllScripts(EntityID entity); /// /// Removes all Scripts attached to the specified Entity. Unlike /// RemoveAllScripts(), this removes all the scripts immediately. @@ -135,7 +135,7 @@ namespace SHADE /// Whether or not to call OnDestroy on the scripts. This is ignored if not in /// play mode. /// - void RemoveAllScriptsImmediately(const SHEntity& entity, bool callOnDestroy); + void RemoveAllScriptsImmediately(EntityID entity, bool callOnDestroy); /*-----------------------------------------------------------------------------*/ /* Script Serialisation Functions */ From 800732706ef7a18dea432d4cbbcff96b971f7a4f Mon Sep 17 00:00:00 2001 From: mushgunAX Date: Fri, 23 Sep 2022 17:42:31 +0800 Subject: [PATCH 13/26] input pch move, init, exit, etc definitions --- .../src/Input/SHInputManagerSystem.cpp | 35 ++++++++++++++++++- SHADE_Engine/src/Input/SHInputManagerSystem.h | 2 +- 2 files changed, 35 insertions(+), 2 deletions(-) diff --git a/SHADE_Engine/src/Input/SHInputManagerSystem.cpp b/SHADE_Engine/src/Input/SHInputManagerSystem.cpp index d5e9bb3f..cbc49d7d 100644 --- a/SHADE_Engine/src/Input/SHInputManagerSystem.cpp +++ b/SHADE_Engine/src/Input/SHInputManagerSystem.cpp @@ -10,6 +10,7 @@ *********************************************************************/ #pragma once +#include #include "SHInputManagerSystem.h" namespace SHADE @@ -37,6 +38,33 @@ namespace SHADE int SHInputManagerSystem::mouseWheelVerticalDelta = 0; int SHInputManagerSystem::mouseWheelVerticalDeltaPoll = 0; + void SHInputManagerSystem::Init() + { + keyCount = 0; + SecureZeroMemory(keys, sizeof(keys)); + SecureZeroMemory(keysLast, sizeof(keysLast)); + SecureZeroMemory(keysHeldTime, sizeof(keysHeldTime)); + SecureZeroMemory(keysReleasedTime, sizeof(keysReleasedTime)); + + keyToggleCount = 0; + SecureZeroMemory(keysToggle, sizeof(keysToggle)); + SecureZeroMemory(keysToggleLast, sizeof(keysToggleLast)); + SecureZeroMemory(keysToggleOnTime, sizeof(keysToggleOnTime)); + SecureZeroMemory(keysToggleOffTime, sizeof(keysToggleOffTime)); + + mouseScreenX = 0; + mouseScreenY = 0; + mouseScreenXLast = 0; + mouseScreenYLast = 0; + mouseWheelVerticalDelta = 0; + mouseWheelVerticalDeltaPoll = 0; + } + + void SHInputManagerSystem::Exit() + { + //No dynamically allocated memory. Nothing to do here. + } + void SHInputManagerSystem::InputManagerRoutine:: FixedExecute(double dt) noexcept { @@ -140,8 +168,13 @@ namespace SHADE { for (size_t i = 0; i < MAX_KEYS; ++i) { - + if (!keys[i] && keysLast[i]) + { + if (firstDetected) *firstDetected = static_cast(i); + return true; + } } + return false; } } //namespace SHADE \ No newline at end of file diff --git a/SHADE_Engine/src/Input/SHInputManagerSystem.h b/SHADE_Engine/src/Input/SHInputManagerSystem.h index 39c97d6f..6ee73ae9 100644 --- a/SHADE_Engine/src/Input/SHInputManagerSystem.h +++ b/SHADE_Engine/src/Input/SHInputManagerSystem.h @@ -11,7 +11,7 @@ #pragma once //#include -#include "../../SHADE_Managed/src/SHpch.h" +//#include "../../SHADE_Managed/src/SHpch.h" #include "ECS_Base/System/SHSystem.h" #include "ECS_Base/System/SHFixedSystemRoutine.h" From bb382461115fb4f7d9b4abd160aadfd3edbbb5fa Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Fri, 23 Sep 2022 18:49:04 +0800 Subject: [PATCH 14/26] Added stress test code for 20000 objects --- SHADE_Application/src/Scenes/SBTestScene.cpp | 43 ++++++++++++++----- SHADE_Application/src/Scenes/SBTestScene.h | 1 + .../Graphics/MiddleEnd/Batching/SHBatch.cpp | 3 +- .../MiddleEnd/Batching/SHSuperBatch.cpp | 2 +- .../Graphics/MiddleEnd/Interface/SHCamera.cpp | 36 ++++++++-------- .../MiddleEnd/Interface/SHGraphicsSystem.cpp | 3 +- 6 files changed, 57 insertions(+), 31 deletions(-) diff --git a/SHADE_Application/src/Scenes/SBTestScene.cpp b/SHADE_Application/src/Scenes/SBTestScene.cpp index f5985715..0caf3c7e 100644 --- a/SHADE_Application/src/Scenes/SBTestScene.cpp +++ b/SHADE_Application/src/Scenes/SBTestScene.cpp @@ -38,26 +38,49 @@ namespace Sandbox // Create Materials auto matInst = graphicsSystem->AddMaterialInstance(); - // Create entity and add mesh - testObj = SHADE::SHEntityManager::CreateEntity(); - auto& renderable = *SHADE::SHComponentManager::GetComponent_s(testObj); - auto& transform = *SHADE::SHComponentManager::GetComponent_s(testObj); + // Create Stress Test Objects + static const SHVec3 TEST_OBJ_SCALE = { 0.2f, 0.2f, 0.2f }; + constexpr int NUM_ROWS = 200; + constexpr int NUM_COLS = 100; + static const SHVec3 TEST_OBJ_SPACING = { 1.0f, 1.0f, 1.0f }; + static const SHVec3 TEST_OBJ_START_POS = { - (NUM_COLS / 2 * TEST_OBJ_SPACING.x ), 0.0f, 0.0f }; + for (int z = 0; z < NUM_ROWS; ++z) + for (int x = 0; x < NUM_COLS; ++x) + { + auto entity = SHEntityManager::CreateEntity(); + auto& renderable = *SHComponentManager::GetComponent_s(entity); + auto& transform = *SHComponentManager::GetComponent_s(entity); - renderable.Mesh = CUBE_MESH; - renderable.SetMaterial(matInst); + renderable.Mesh = CUBE_MESH; + renderable.SetMaterial(matInst); + // Set initial positions + transform.SetWorldPosition(TEST_OBJ_START_POS + SHVec3{ x * TEST_OBJ_SPACING.x, 0.0f, z * TEST_OBJ_SPACING.z }); + //transform.SetLocalScale(TEST_OBJ_SCALE); + + stressTestObjects.emplace_back(entity); + } + + // Create blank entity with a script + testObj = SHADE::SHEntityManager::CreateEntity(); SHADE::SHScriptEngine* scriptEngine = static_cast(SHADE::SHSystemManager::GetSystem()); scriptEngine->AddScript(testObj, "TestScript"); } void SBTestScene::Update(float dt) { - static float rotation = 0.0f; + /*static float rotation = 0.0f; - auto& transform = *SHADE::SHComponentManager::GetComponent_s(testObj); + auto& transform = *SHADE::SHComponentManager::GetComponent_s(testObj); - transform.SetLocalRotation(rotation, 0.0f, 0.0f); - rotation += dt * 10.0f; + transform.SetLocalRotation(rotation, 0.0f, 0.0f); + rotation += dt * 10.0f;*/ + /*static float rotation = 0.0f; + + auto& transform = *SHADE::SHComponentManager::GetComponent_s(stressTestObjects[0]); + + transform.SetWorldPosition({rotation, 0.0f, 0.0f}); + rotation += dt * 10.0f;*/ // Destroy entity if space is pressed if (GetKeyState(VK_SPACE) & 0x8000) diff --git a/SHADE_Application/src/Scenes/SBTestScene.h b/SHADE_Application/src/Scenes/SBTestScene.h index 81ee3e7b..3a1598d5 100644 --- a/SHADE_Application/src/Scenes/SBTestScene.h +++ b/SHADE_Application/src/Scenes/SBTestScene.h @@ -10,6 +10,7 @@ namespace Sandbox private: EntityID camera; EntityID testObj; + std::vector stressTestObjects; public: virtual void Load(); diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.cpp index 9d496821..a68ee7fa 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.cpp @@ -117,7 +117,7 @@ namespace SHADE for (const SHRenderable* renderable : subBatch.Renderables) { // Transform - auto transform = SHComponentManager::GetComponent_s(renderable->GetEID()); + auto transform = SHComponentManager::GetComponent(renderable->GetEID()); if (!transform) { SHLOG_WARNING("[SHBatch] Entity contianing a SHRenderable with no SHTransformComponent found!"); @@ -211,6 +211,7 @@ namespace SHADE { transformData.emplace_back(transform->GetTRS()); } + // Material Properties if (!EMPTY_MAT_PROPS) { diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHSuperBatch.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHSuperBatch.cpp index a259f2cf..633d40a9 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHSuperBatch.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHSuperBatch.cpp @@ -79,7 +79,7 @@ namespace SHADE } void SHSuperBatch::UpdateTransformBuffer(uint32_t frameIndex) -{ + { for (auto& batch : batches) { batch.UpdateTransformBuffer(frameIndex); diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHCamera.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHCamera.cpp index 992aff05..4a1117c3 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHCamera.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHCamera.cpp @@ -22,24 +22,24 @@ namespace SHADE void SHCamera::SetLookAt(const SHVec3& pos, const SHVec3& target, const SHVec3& up) { SHVec3 view = target - pos; view = SHVec3::Normalise(view); - SHVec3 right = SHVec3::Cross(view, up); right = SHVec3::Normalise(right); - const SHVec3 UP = SHVec3::Cross(right, view); - - viewMatrix = SHMatrix::Identity; - viewMatrix(0, 0) = UP[0]; - viewMatrix(1, 0) = UP[1]; - viewMatrix(2, 0) = UP[2]; - viewMatrix(0, 1) = right[0]; - viewMatrix(1, 1) = right[1]; - viewMatrix(2, 1) = right[2]; - viewMatrix(0, 2) = view[0]; - viewMatrix(1, 2) = view[1]; - viewMatrix(2, 2) = view[2]; - viewMatrix(3, 0) = -UP.Dot(pos); - viewMatrix(3, 1) = -right.Dot(pos); - viewMatrix(3, 2) = -view.Dot(pos); - - isDirty = true; + SHVec3 right = SHVec3::Cross(view, up); right = SHVec3::Normalise(right); + const SHVec3 UP = SHVec3::Cross(right, view); + + viewMatrix = SHMatrix::Identity; + viewMatrix(0, 0) = UP[0]; + viewMatrix(1, 0) = UP[1]; + viewMatrix(2, 0) = UP[2]; + viewMatrix(0, 1) = right[0]; + viewMatrix(1, 1) = right[1]; + viewMatrix(2, 1) = right[2]; + viewMatrix(0, 2) = view[0]; + viewMatrix(1, 2) = view[1]; + viewMatrix(2, 2) = view[2]; + viewMatrix(3, 0) = -UP.Dot(pos); + viewMatrix(3, 1) = -right.Dot(pos); + viewMatrix(3, 2) = -view.Dot(pos); + + isDirty = true; } /*---------------------------------------------------------------------------------*/ diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp index a68812f8..48f16713 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp @@ -114,7 +114,8 @@ namespace SHADE 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(static_cast(windowDims.first), static_cast(windowDims.second), 0.01f, 100.0f); worldCamera = resourceManager.Create(); - worldCamera->SetLookAt(SHVec3(1.0f, 0.0f, -1.0f), SHVec3(0.0f, 0.0f, 2.0f), SHVec3(0.0f, 1.0f, 0.0f)); + //worldCamera->SetLookAt(SHVec3(1.0f, 0.0f, -1.0f), SHVec3(0.0f, 0.0f, 2.0f), SHVec3(0.0f, 1.0f, 0.0f)); + worldCamera->SetLookAt(SHVec3(0.0f, 5.0f, -1.0f), SHVec3(0.0f, 0.0f, 2.0f), SHVec3(0.0f, 1.0f, 0.0f)); worldCamera->SetPerspective(90.0f, static_cast(windowDims.first), static_cast(windowDims.second), 0.0f, 100.0f); // Create Default Viewport From bd54b16e0170834d33b11cd740289f1af7df6acd Mon Sep 17 00:00:00 2001 From: Brandon Mak Date: Fri, 23 Sep 2022 18:50:40 +0800 Subject: [PATCH 15/26] Ctor for compute pipelines --- .../Graphics/Devices/SHVkLogicalDevice.cpp | 4 +-- .../src/Graphics/Devices/SHVkLogicalDevice.h | 6 ++-- .../MiddleEnd/Pipeline/SHPipelineLibrary.cpp | 2 +- .../src/Graphics/Pipeline/SHVkPipeline.cpp | 35 ++++++++++++++++--- .../src/Graphics/Pipeline/SHVkPipeline.h | 6 ++-- 5 files changed, 40 insertions(+), 13 deletions(-) diff --git a/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.cpp b/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.cpp index 65b0d9ca..5ed17511 100644 --- a/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.cpp +++ b/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.cpp @@ -493,9 +493,9 @@ namespace SHADE */ /***************************************************************************/ - Handle SHVkLogicalDevice::CreatePipeline(Handle const& pipelineLayoutHdl, SHVkPipelineState const* const state, Handle const& renderpassHdl, Handle subpass, SH_PIPELINE_TYPE type) noexcept + Handle SHVkLogicalDevice::CreateGraphicsPipeline(Handle const& pipelineLayoutHdl, SHVkPipelineState const* const state, Handle const& renderpassHdl, Handle subpass) noexcept { - return SHVkInstance::GetResourceManager().Create (GetHandle(), pipelineLayoutHdl, state, renderpassHdl, subpass, type); + return SHVkInstance::GetResourceManager().Create (GetHandle(), pipelineLayoutHdl, state, renderpassHdl, subpass); } diff --git a/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.h b/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.h index 3a27e4b1..8a197ef8 100644 --- a/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.h +++ b/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.h @@ -21,6 +21,7 @@ #include "Graphics/Descriptors/SHVkDescriptorSetLayout.h" #include "Graphics/Images/SHVkImage.h" + namespace SHADE { /*-----------------------------------------------------------------------*/ @@ -171,12 +172,11 @@ namespace SHADE std::string const& shaderName ) noexcept; - Handle CreatePipeline ( + Handle CreateGraphicsPipeline ( Handle const& pipelineLayoutHdl, SHVkPipelineState const* const state, Handle const& renderpassHdl, - Handle subpass, - SH_PIPELINE_TYPE type + Handle subpass ) noexcept; Handle CreateRenderpass (std::span const vkDescriptions, std::vector const& subpasses) noexcept; diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Pipeline/SHPipelineLibrary.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Pipeline/SHPipelineLibrary.cpp index e09a4945..92d832f1 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Pipeline/SHPipelineLibrary.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Pipeline/SHPipelineLibrary.cpp @@ -18,7 +18,7 @@ namespace SHADE 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); + auto newPipeline = logicalDevice->CreateGraphicsPipeline(pipelineLayout, nullptr, renderpass, subpass); newPipeline->GetPipelineState().SetVertexInputState(globalData->GetDefaultViState()); // Actually construct the pipeline diff --git a/SHADE_Engine/src/Graphics/Pipeline/SHVkPipeline.cpp b/SHADE_Engine/src/Graphics/Pipeline/SHVkPipeline.cpp index 1c47c21a..c03fd2a7 100644 --- a/SHADE_Engine/src/Graphics/Pipeline/SHVkPipeline.cpp +++ b/SHADE_Engine/src/Graphics/Pipeline/SHVkPipeline.cpp @@ -179,7 +179,7 @@ namespace SHADE /*! \brief - Non-default ctor. + Non-default ctor for creating graphics pipeline. \param inLogicalDeviceHdl Needed for creation and destruction. @@ -200,14 +200,12 @@ namespace SHADE The subpass that this pipeline will be used in. If state is not nullptr, this parameter is ignored. - \param type - The type of the pipeline. */ /***************************************************************************/ - SHVkPipeline::SHVkPipeline(Handle const& inLogicalDeviceHdl, Handle const& inPipelineLayout, SHVkPipelineState const* const state, Handle const& renderpassHdl, Handle subpass, SH_PIPELINE_TYPE type) noexcept + SHVkPipeline::SHVkPipeline(Handle const& inLogicalDeviceHdl, Handle const& inPipelineLayout, SHVkPipelineState const* const state, Handle const& renderpassHdl, Handle subpass) noexcept : pipelineState{ } - , pipelineType {type} + , pipelineType {SH_PIPELINE_TYPE::GRAPHICS} , vkPipeline {VK_NULL_HANDLE} , logicalDeviceHdl{ inLogicalDeviceHdl } , pipelineLayout { inPipelineLayout } @@ -250,6 +248,33 @@ namespace SHADE vkPipeline = VK_NULL_HANDLE; } + /***************************************************************************/ + /*! + + \brief + Just to differentiate between compute and graphics pipeline, we will + have a constructor that takes in less parameters; sufficient for the + compute pipeline to be created. + + \param inLogicalDeviceHdl + \param inPipelineLayout + + \return + + */ + /***************************************************************************/ + SHVkPipeline::SHVkPipeline(Handle const& inLogicalDeviceHdl, Handle const& inPipelineLayout) noexcept + : pipelineState{ } + , pipelineType{ SH_PIPELINE_TYPE::COMPUTE } + , vkPipeline{ VK_NULL_HANDLE } + , logicalDeviceHdl{ inLogicalDeviceHdl } + , pipelineLayout{ inPipelineLayout } + , created{ false } + + { + + } + /***************************************************************************/ /*! diff --git a/SHADE_Engine/src/Graphics/Pipeline/SHVkPipeline.h b/SHADE_Engine/src/Graphics/Pipeline/SHVkPipeline.h index 6edf0e98..fe55a41e 100644 --- a/SHADE_Engine/src/Graphics/Pipeline/SHVkPipeline.h +++ b/SHADE_Engine/src/Graphics/Pipeline/SHVkPipeline.h @@ -51,8 +51,10 @@ namespace SHADE Handle const& inPipelineLayout, SHVkPipelineState const* const state, Handle const& renderpassHdl, - Handle subpass, - SH_PIPELINE_TYPE type) noexcept; + Handle subpass) noexcept; + + SHVkPipeline(Handle const& inLogicalDeviceHdl, + Handle const& inPipelineLayout) noexcept; SHVkPipeline (SHVkPipeline&& rhs) noexcept; ~SHVkPipeline (void) noexcept; From 759c87e2a19655246630ca8f3773d51d7abf8669 Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Sat, 24 Sep 2022 02:07:47 +0800 Subject: [PATCH 16/26] Material data on the GPU is now updated when material data changes --- .../Graphics/MiddleEnd/Batching/SHBatch.cpp | 85 ++++++++++++++++++- .../src/Graphics/MiddleEnd/Batching/SHBatch.h | 7 ++ .../Graphics/MiddleEnd/Batching/SHBatcher.cpp | 6 +- .../Graphics/MiddleEnd/Batching/SHBatcher.h | 2 +- .../MiddleEnd/Batching/SHSuperBatch.cpp | 3 +- .../MiddleEnd/Batching/SHSuperBatch.h | 4 +- .../Interface/SHMaterialInstance.cpp | 5 +- .../MiddleEnd/Interface/SHMaterialInstance.h | 6 +- .../Interface/SHMaterialInstance.hpp | 3 + .../Graphics/RenderGraph/SHRenderGraph.cpp | 4 +- 10 files changed, 109 insertions(+), 16 deletions(-) diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.cpp index a68ee7fa..4667d5db 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.cpp @@ -58,6 +58,9 @@ namespace SHADE // Add renderable in subBatch->Renderables.insert(renderable); + // Also add material instance in + referencedMatInstances.insert(renderable->GetMaterial()); + // Mark all as dirty setAllDirtyFlags(); } @@ -67,8 +70,8 @@ namespace SHADE // Check if we have a SubBatch with the same mesh yet auto subBatch = std::find_if(subBatches.begin(), subBatches.end(), [&](const SHSubBatch& batch) { - return batch.Mesh == renderable->Mesh; - }); + return batch.Mesh == renderable->Mesh; + }); // Attempt to remove if it exists if (subBatch == subBatches.end()) @@ -76,6 +79,22 @@ namespace SHADE subBatch->Renderables.erase(renderable); + // Check if other renderables in subBatches contain the same material instance + bool matUnused = true; + for (const auto& subBatch : subBatches) + for (const auto& rend : subBatch.Renderables) + { + if (rend->GetMaterial() == renderable->GetMaterial()) + { + matUnused = false; + break; + } + } + + // Material is no longer in this library, so we remove it + if (matUnused) + referencedMatInstances.erase(renderable->GetMaterial()); + // Mark all as dirty for (bool& dirt : isDirty) dirt = true; @@ -101,7 +120,63 @@ namespace SHADE } } - void SHBatch::UpdateTransformBuffer(uint32_t frameIndex) + void SHBatch::UpdateMaterialBuffer(uint32_t frameIndex) + { + if (frameIndex >= SHGraphicsConstants::NUM_FRAME_BUFFERS) + { + SHLOG_WARNING("[SHBatch] Attempted to update transform buffers with an invalid frame index."); + return; + } + + // Check if there are even material properties to update + if (!matPropsData) + return; + + // Check if any materials have changed + bool hasChanged = false; + for (auto material : referencedMatInstances) + { + if (material->HasChanged()) + { + hasChanged = true; + break; + } + } + + // We need to update all the material buffers if the materials have changed + if (hasChanged) + { + for (auto& dirt : matBufferDirty) + dirt = true; + } + + // Check if this frame's buffer is dirty + if (!matBufferDirty[frameIndex]) + return; + + // Build CPI Buffer + uint32_t nextInstanceIndex = 0; + char* propsCurrPtr = matPropsData.get(); + for (auto& subBatch : subBatches) + for (const SHRenderable* renderable : subBatch.Renderables) + { + + renderable->GetMaterial()->ExportProperties(propsCurrPtr); + propsCurrPtr += singleMatPropSize; + } + + // Transfer to GPU + SHVkUtil::EnsureBufferAndCopyHostVisibleData + ( + device, matPropsBuffer[frameIndex], matPropsData.get(), static_cast(matPropsDataSize), + vk::BufferUsageFlagBits::eStorageBuffer + ); + + // This frame is updated + matBufferDirty[frameIndex] = false; + } + + void SHBatch::UpdateTransformBuffer(uint32_t frameIndex) { if (frameIndex >= SHGraphicsConstants::NUM_FRAME_BUFFERS) { @@ -169,7 +244,6 @@ namespace SHADE vk::ShaderStageFlagBits::eFragment ); const bool EMPTY_MAT_PROPS = !SHADER_INFO; - Byte singleMatPropSize = 0; Byte matPropTotalBytes = 0; if (!EMPTY_MAT_PROPS) { @@ -252,6 +326,9 @@ namespace SHADE } isDirty[frameIndex] = false; + + // Save logical device + this->device = device; } /*---------------------------------------------------------------------------------*/ diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.h b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.h index a572adca..d40a66ea 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.h @@ -34,6 +34,7 @@ namespace SHADE class SHMesh; class SHRenderable; class SHVkLogicalDevice; + class SHMaterialInstance; /*---------------------------------------------------------------------------------*/ /* Type Definitions */ @@ -73,6 +74,7 @@ namespace SHADE void Add(const SHRenderable* renderable); void Remove(const SHRenderable* renderable); void Clear(); + void UpdateMaterialBuffer(uint32_t frameIndex); void UpdateTransformBuffer(uint32_t frameIndex); void Build(Handle device, uint32_t frameIndex); void Draw(Handle cmdBuffer, uint32_t frameIndex); @@ -86,8 +88,12 @@ namespace SHADE /*-----------------------------------------------------------------------------*/ /* Data Members */ /*-----------------------------------------------------------------------------*/ + // Resources + Handle device; // Batch Properties Handle pipeline; + std::unordered_set> referencedMatInstances; + std::array matBufferDirty; // Batch Tree std::vector subBatches; std::array isDirty; @@ -96,6 +102,7 @@ namespace SHADE std::vector transformData; std::unique_ptr matPropsData; Byte matPropsDataSize = 0; + Byte singleMatPropSize = 0; bool isCPUBuffersDirty = true; // GPU Buffers std::array, SHGraphicsConstants::NUM_FRAME_BUFFERS> drawDataBuffer; diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatcher.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatcher.cpp index ecd99a20..c4320aac 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatcher.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatcher.cpp @@ -109,11 +109,11 @@ namespace SHADE superBatches.clear(); } - void SHBatcher::UpdateTransformBuffer(uint32_t frameIndex) -{ + void SHBatcher::UpdateBuffers(uint32_t frameIndex) + { for (auto& batch : superBatches) { - batch->UpdateTransformBuffer(frameIndex); + batch->UpdateBuffers(frameIndex); } } diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatcher.h b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatcher.h index b4fff203..985e8e16 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatcher.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatcher.h @@ -53,7 +53,7 @@ namespace SHADE void RemoveFromBatch(SHRenderable const* renderable); void FinaliseBatches(Handle device, uint32_t frameIndex); void ClearBatches(); - void UpdateTransformBuffer(uint32_t frameIndex); + void UpdateBuffers(uint32_t frameIndex); void RegisterSuperBatch(Handle superBatch); void DeregisterSuperBatch(Handle superBatch); diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHSuperBatch.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHSuperBatch.cpp index 633d40a9..b0173399 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHSuperBatch.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHSuperBatch.cpp @@ -78,10 +78,11 @@ namespace SHADE batches.clear(); } - void SHSuperBatch::UpdateTransformBuffer(uint32_t frameIndex) + void SHSuperBatch::UpdateBuffers(uint32_t frameIndex) { for (auto& batch : batches) { + batch.UpdateMaterialBuffer(frameIndex); batch.UpdateTransformBuffer(frameIndex); } } diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHSuperBatch.h b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHSuperBatch.h index 5379ee61..a09fc64e 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHSuperBatch.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHSuperBatch.h @@ -54,8 +54,8 @@ namespace SHADE /*-----------------------------------------------------------------------------*/ void Add(const SHRenderable* renderable) noexcept; void Remove(const SHRenderable* renderable) noexcept; - void Clear() noexcept; - void UpdateTransformBuffer(uint32_t frameIndex); + void Clear() noexcept; + void UpdateBuffers(uint32_t frameIndex); void Build(Handle device, uint32_t frameIndex) noexcept; void Draw(Handle cmdBuffer, uint32_t frameIndex) noexcept; diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMaterialInstance.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMaterialInstance.cpp index 57a91941..0e5a61dd 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMaterialInstance.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMaterialInstance.cpp @@ -38,7 +38,7 @@ namespace SHADE dataStore.reset(); } - void SHMaterialInstance::ExportProperties(void* dest) const + void SHMaterialInstance::ExportProperties(void* dest) { assert(dataStore != nullptr); @@ -62,6 +62,9 @@ namespace SHADE const auto DATA_OFFSET = variable->offset; memcpy(static_cast(dest) + DATA_OFFSET, dataStore.get() + data.StoredDataOffset, data.DataSize); } + + // Data was exported so unflag + dataWasChanged = false; } /*---------------------------------------------------------------------------------*/ diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMaterialInstance.h b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMaterialInstance.h index db0201b7..5d6c4925 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMaterialInstance.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMaterialInstance.h @@ -62,12 +62,13 @@ namespace SHADE template const T& GetProperty(const std::string& key) const; void ResetProperties() noexcept; - void ExportProperties(void* dest) const; + void ExportProperties(void* dest); /*-----------------------------------------------------------------------------*/ /* Getter Functions */ /*-----------------------------------------------------------------------------*/ - Handle GetBaseMaterial() const { return baseMaterial; } + Handle GetBaseMaterial() const noexcept { return baseMaterial; } + bool HasChanged() const noexcept { return dataWasChanged; } private: /*-----------------------------------------------------------------------------*/ @@ -77,6 +78,7 @@ namespace SHADE std::vector overrideData; std::unique_ptr dataStore; size_t dataStoreSize = 0; + bool dataWasChanged = false; /*-----------------------------------------------------------------------------*/ /* Helper Functions */ diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMaterialInstance.hpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMaterialInstance.hpp index 0aead306..b3dc6c3a 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMaterialInstance.hpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMaterialInstance.hpp @@ -53,6 +53,9 @@ namespace SHADE // Save the override data information overrideData.emplace_back(std::move(od)); + + // Flag + dataWasChanged = true; } template T& SHMaterialInstance::GetProperty(const std::string& key) diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp index ecf9059c..6070361f 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp @@ -348,8 +348,8 @@ namespace SHADE void SHSubpass::Execute(Handle& commandBuffer, uint32_t frameIndex) noexcept { - // Ensure correct transforms are provided - superBatch->UpdateTransformBuffer(frameIndex); + // Ensure updated transforms and materials are provided + superBatch->UpdateBuffers(frameIndex); // Draw all the batches superBatch->Draw(commandBuffer, frameIndex); From 15f12a2608fc2fa398fe855e803bfc8f9e11d4cc Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Sat, 24 Sep 2022 02:13:09 +0800 Subject: [PATCH 17/26] Fixed warnings in SHBatch.cpp --- .../Graphics/MiddleEnd/Batching/SHBatch.cpp | 20 +++++++++---------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.cpp index 4667d5db..7b2ebd49 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.cpp @@ -81,8 +81,8 @@ namespace SHADE // Check if other renderables in subBatches contain the same material instance bool matUnused = true; - for (const auto& subBatch : subBatches) - for (const auto& rend : subBatch.Renderables) + for (const auto& sb : subBatches) + for (const auto& rend : sb.Renderables) { if (rend->GetMaterial() == renderable->GetMaterial()) { @@ -134,7 +134,7 @@ namespace SHADE // Check if any materials have changed bool hasChanged = false; - for (auto material : referencedMatInstances) + for (const auto& material : referencedMatInstances) { if (material->HasChanged()) { @@ -155,12 +155,10 @@ namespace SHADE return; // Build CPI Buffer - uint32_t nextInstanceIndex = 0; char* propsCurrPtr = matPropsData.get(); for (auto& subBatch : subBatches) for (const SHRenderable* renderable : subBatch.Renderables) { - renderable->GetMaterial()->ExportProperties(propsCurrPtr); propsCurrPtr += singleMatPropSize; } @@ -205,10 +203,10 @@ namespace SHADE } // Transfer to GPU - transformDataBuffer[frameIndex]->WriteToMemory(transformData.data(), transformData.size() * sizeof(SHMatrix), 0, 0); + transformDataBuffer[frameIndex]->WriteToMemory(transformData.data(), static_cast(transformData.size() * sizeof(SHMatrix)), 0, 0); } - void SHBatch::Build(Handle device, uint32_t frameIndex) + void SHBatch::Build(Handle _device, uint32_t frameIndex) { if (frameIndex >= SHGraphicsConstants::NUM_FRAME_BUFFERS) { @@ -305,14 +303,14 @@ namespace SHADE const uint32_t DRAW_DATA_BYTES = static_cast(drawData.size() * sizeof(vk::DrawIndexedIndirectCommand)); SHVkUtil::EnsureBufferAndCopyHostVisibleData ( - device, drawDataBuffer[frameIndex], drawData.data(), DRAW_DATA_BYTES, + _device, drawDataBuffer[frameIndex], drawData.data(), DRAW_DATA_BYTES, BuffUsage::eIndirectBuffer ); // - Transform Buffer const uint32_t TF_DATA_BYTES = static_cast(transformData.size() * sizeof(SHMatrix)); SHVkUtil::EnsureBufferAndCopyHostVisibleData ( - device, transformDataBuffer[frameIndex], transformData.data(), TF_DATA_BYTES, + _device, transformDataBuffer[frameIndex], transformData.data(), TF_DATA_BYTES, BuffUsage::eVertexBuffer ); // - Material Properties Buffer @@ -320,7 +318,7 @@ namespace SHADE { SHVkUtil::EnsureBufferAndCopyHostVisibleData ( - device, matPropsBuffer[frameIndex], matPropsData.get(), static_cast(matPropsDataSize), + _device, matPropsBuffer[frameIndex], matPropsData.get(), static_cast(matPropsDataSize), BuffUsage::eStorageBuffer ); } @@ -328,7 +326,7 @@ namespace SHADE isDirty[frameIndex] = false; // Save logical device - this->device = device; + this->device = _device; } /*---------------------------------------------------------------------------------*/ From 8ab5afd3c4761274d0423657bdfdd801b345fe23 Mon Sep 17 00:00:00 2001 From: mushgunAX Date: Sun, 25 Sep 2022 16:39:01 +0800 Subject: [PATCH 18/26] first version of IM ready for PR --- .../src/Application/SBApplication.cpp | 4 ++++ .../src/Input/SHInputManagerSystem.cpp | 6 ++++++ SHADE_Engine/src/Input/SHInputManagerSystem.h | 21 +++++++++++++++++++ 3 files changed, 31 insertions(+) diff --git a/SHADE_Application/src/Application/SBApplication.cpp b/SHADE_Application/src/Application/SBApplication.cpp index bb4ccc35..7ef8adfe 100644 --- a/SHADE_Application/src/Application/SBApplication.cpp +++ b/SHADE_Application/src/Application/SBApplication.cpp @@ -23,6 +23,7 @@ #include "Graphics/MiddleEnd/Interface/SHRenderable.h" #include "Scene/SHSceneManager.h" #include "Math/Transform/SHTransformSystem.h" +#include "Input/SHInputManagerSystem.h" #include "Scenes/SBTestScene.h" #include "Math/Transform/SHTransformComponent.h" @@ -52,6 +53,7 @@ namespace Sandbox SHADE::SHSystemManager::CreateSystem(); SHADE::SHSystemManager::CreateSystem(); SHADE::SHGraphicsSystem* graphicsSystem = static_cast(SHADE::SHSystemManager::GetSystem()); + SHADE::SHSystemManager::CreateSystem(); // Create Routines SHADE::SHSystemManager::RegisterRoutine(); @@ -71,6 +73,8 @@ namespace Sandbox SHADE::SHComponentManager::CreateComponentSparseSet(); SHADE::SHComponentManager::CreateComponentSparseSet(); + + SHADE::SHSystemManager::RegisterRoutine(); // Set up graphics system and windows graphicsSystem->SetWindow(&window); diff --git a/SHADE_Engine/src/Input/SHInputManagerSystem.cpp b/SHADE_Engine/src/Input/SHInputManagerSystem.cpp index cbc49d7d..1beabe3f 100644 --- a/SHADE_Engine/src/Input/SHInputManagerSystem.cpp +++ b/SHADE_Engine/src/Input/SHInputManagerSystem.cpp @@ -35,6 +35,8 @@ namespace SHADE int SHInputManagerSystem::mouseScreenY = 0; int SHInputManagerSystem::mouseScreenXLast = 0; int SHInputManagerSystem::mouseScreenYLast = 0; + double SHInputManagerSystem::mouseVelocityX = 0; + double SHInputManagerSystem::mouseVelocityY = 0; int SHInputManagerSystem::mouseWheelVerticalDelta = 0; int SHInputManagerSystem::mouseWheelVerticalDeltaPoll = 0; @@ -126,6 +128,10 @@ namespace SHADE //Mouse Positioning///////////////////////////////////// //https://stackoverflow.com/a/6423739 + //Set last positioning + mouseScreenXLast = mouseScreenX; + mouseScreenYLast = mouseScreenY; + //Get cursor position, even when it is outside window POINT p; GetCursorPos(&p); diff --git a/SHADE_Engine/src/Input/SHInputManagerSystem.h b/SHADE_Engine/src/Input/SHInputManagerSystem.h index 6ee73ae9..77d8f8fd 100644 --- a/SHADE_Engine/src/Input/SHInputManagerSystem.h +++ b/SHADE_Engine/src/Input/SHInputManagerSystem.h @@ -420,6 +420,16 @@ namespace SHADE if (y) *y = mouseScreenY; } + //Get the mouse velocity + //Two output parameters for x and y velocitites + //In pixels per second for both + static inline void GetMouseVelocity(double* x = nullptr, + double* y = nullptr) noexcept + { + if (x) *x = mouseVelocityX; + if (y) *y = mouseVelocityY; + } + //Get the mouse wheel vertical delta static inline int GetMouseWheelVerticalDelta() noexcept { @@ -529,15 +539,26 @@ namespace SHADE //MOUSE VARIABLES/////////////////////////////////////////////////////////// //Present horizontal positioning of the mouse WRT the screen + //Increasing rightwards static int mouseScreenX; //Present vertical positioning of the mouse WRT the screen + //Increasing downwards static int mouseScreenY; //Horizontal positioning of the mouse WRT screen in last frame + //Increasing rightwards static int mouseScreenXLast; //Vertical positioning of the mouse WRT screen in the last frame + //Increasing downwards static int mouseScreenYLast; + //The velocity at which the mouse is being moved horizontally (px/s) + //Rightwards is positive + static double mouseVelocityX; + //The velocity at which the mouse is being moved vertically (px/s) + //Downwards is positive + static double mouseVelocityY; + //For polling mouse wheel events, not to be read static int mouseWheelVerticalDeltaPoll; //Mouse wheel vertical rotation speed. Positive is rotation AWAY from user From 4e60b3495acb2e2cdc86df3e98a706b5c517fa9c Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Sun, 25 Sep 2022 20:28:01 +0800 Subject: [PATCH 19/26] Handles will now properly show up automatically dereferenced or NULL in Visual Studio's debug views --- SHADE_Engine/NatvisFile.natvis | 10 ++++++++++ SHADE_Engine/premake5.lua | 3 ++- 2 files changed, 12 insertions(+), 1 deletion(-) create mode 100644 SHADE_Engine/NatvisFile.natvis diff --git a/SHADE_Engine/NatvisFile.natvis b/SHADE_Engine/NatvisFile.natvis new file mode 100644 index 00000000..6747262b --- /dev/null +++ b/SHADE_Engine/NatvisFile.natvis @@ -0,0 +1,10 @@ + + + + NULL + ID = {id.Data.Index} Version = {id.Data.Version} Type = {"$T1"} + + (*library).objects.denseArray[(*library).objects.sparseArray[id.Data.Index]] + + + \ No newline at end of file diff --git a/SHADE_Engine/premake5.lua b/SHADE_Engine/premake5.lua index 84acd8fa..2e6c39f9 100644 --- a/SHADE_Engine/premake5.lua +++ b/SHADE_Engine/premake5.lua @@ -15,7 +15,8 @@ project "SHADE_Engine" "%{prj.location}/src/**.hpp", "%{prj.location}/src/**.c", "%{prj.location}/src/**.cpp", - "%{prj.location}/src/**.glsl" + "%{prj.location}/src/**.glsl", + "%{prj.location}/**.natvis" } includedirs From a197ae842ccb379f962445579388c5c5a1517894 Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Sun, 25 Sep 2022 21:46:57 +0800 Subject: [PATCH 20/26] Fixed crash on AMD GPUs resulting from Nvidia treating UniformBuffers and UniformBuffersDynamic as the same --- SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorPool.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorPool.h b/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorPool.h index b862ec09..91112496 100644 --- a/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorPool.h +++ b/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorPool.h @@ -39,7 +39,8 @@ namespace SHADE std::vector Limits = { { vk::DescriptorType::eCombinedImageSampler, 100 }, - { vk::DescriptorType::eUniformBuffer, 100 } + { vk::DescriptorType::eUniformBuffer, 100 }, + { vk::DescriptorType::eUniformBufferDynamic, 100 } }; /// /// Maximum number of descriptor sets allowed From fc5ff763f3d64b84d05a3b1da30ad7372ad74207 Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Sun, 25 Sep 2022 22:55:14 +0800 Subject: [PATCH 21/26] Added SHMaterialInstanceCache --- SHADE_Application/src/Scenes/SBTestScene.cpp | 2 +- .../MiddleEnd/Interface/SHGraphicsSystem.cpp | 13 ++- .../MiddleEnd/Interface/SHGraphicsSystem.h | 11 ++- .../MiddleEnd/Interface/SHRenderable.cpp | 2 +- .../Materials/SHMaterialInstanceCache.cpp | 47 ++++++++++ .../Materials/SHMaterialInstanceCache.h | 93 +++++++++++++++++++ 6 files changed, 158 insertions(+), 10 deletions(-) create mode 100644 SHADE_Engine/src/Graphics/MiddleEnd/Materials/SHMaterialInstanceCache.cpp create mode 100644 SHADE_Engine/src/Graphics/MiddleEnd/Materials/SHMaterialInstanceCache.h diff --git a/SHADE_Application/src/Scenes/SBTestScene.cpp b/SHADE_Application/src/Scenes/SBTestScene.cpp index 0caf3c7e..c91fee9c 100644 --- a/SHADE_Application/src/Scenes/SBTestScene.cpp +++ b/SHADE_Application/src/Scenes/SBTestScene.cpp @@ -36,7 +36,7 @@ namespace Sandbox graphicsSystem->BuildMeshBuffers(); // Create Materials - auto matInst = graphicsSystem->AddMaterialInstance(); + auto matInst = graphicsSystem->AddOrGetBaseMaterialInstance(); // Create Stress Test Objects static const SHVec3 TEST_OBJ_SCALE = { 0.2f, 0.2f, 0.2f }; diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp index 48f16713..b909aeff 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp @@ -415,14 +415,19 @@ namespace SHADE resourceManager.Free(material); } - Handle SHGraphicsSystem::AddMaterialInstance(Handle material) + Handle SHGraphicsSystem::AddOrGetBaseMaterialInstance(Handle material) { - return resourceManager.Create(material); + return materialInstanceCache.CreateOrGet(resourceManager, material); } - SHADE::Handle SHGraphicsSystem::AddMaterialInstance() + SHADE::Handle SHGraphicsSystem::AddOrGetBaseMaterialInstance() { - return AddMaterialInstance(defaultMaterial); + return AddOrGetBaseMaterialInstance(defaultMaterial); + } + + SHADE::Handle SHGraphicsSystem::AddMaterialInstanceCopy(Handle materialInst) + { + return resourceManager.Create(materialInst->GetBaseMaterial()); } void SHGraphicsSystem::RemoveMaterialInstance(Handle materialInstance) diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.h b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.h index 3dc452be..bee7a0f1 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.h @@ -28,6 +28,7 @@ of DigiPen Institute of Technology is prohibited. #include "Graphics/MiddleEnd/Shaders/SHShaderSourceLibrary.h" #include "Graphics/MiddleEnd/Shaders/SHShaderModuleLibrary.h" #include "SHMeshLibrary.h" +#include "Graphics/MiddleEnd/Materials/SHMaterialInstanceCache.h" namespace SHADE { @@ -119,9 +120,10 @@ namespace SHADE /* Material Creation Functions */ /*-----------------------------------------------------------------------------*/ Handle AddMaterial(Handle vertShader, Handle fragShader, Handle subpass); - void RemoveMaterial(Handle material);; - Handle AddMaterialInstance(); - Handle AddMaterialInstance(Handle material); + void RemoveMaterial(Handle material); + Handle AddOrGetBaseMaterialInstance(); + Handle AddOrGetBaseMaterialInstance(Handle material); + Handle AddMaterialInstanceCopy(Handle materialInst); void RemoveMaterialInstance(Handle materialInstance); /*-----------------------------------------------------------------------------*/ @@ -228,8 +230,9 @@ namespace SHADE Handle globalData; // Middle End Resources - ResourceManager resourceManager; + ResourceManager resourceManager; SHMeshLibrary meshLibrary; + SHMaterialInstanceCache materialInstanceCache; // Viewports Handle defaultViewport; // Whole screen std::vector> viewports; // Additional viewports diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderable.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderable.cpp index 5199565c..a4cda42d 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderable.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderable.cpp @@ -81,7 +81,7 @@ namespace SHADE if (!material) { SHGraphicsSystem* gfxSystem = SHSystemManager::GetSystem(); - material = gfxSystem->AddMaterialInstance(sharedMaterial->GetBaseMaterial()); + material = gfxSystem->AddOrGetBaseMaterialInstance(sharedMaterial->GetBaseMaterial()); } return material; diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Materials/SHMaterialInstanceCache.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Materials/SHMaterialInstanceCache.cpp new file mode 100644 index 00000000..ed3d27c3 --- /dev/null +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Materials/SHMaterialInstanceCache.cpp @@ -0,0 +1,47 @@ +/************************************************************************************//*! +\file SHMaterialInstanceCache.cpp +\author Tng Kah Wei, kahwei.tng, 390009620 +\par email: kahwei.tng\@digipen.edu +\date Sep 25, 2022 +\brief Contains the definition of SHMaterialInstanceCache's functions. + + +Copyright (C) 2022 DigiPen Institute of Technology. +Reproduction or disclosure of this file or its contents without the prior written consent +of DigiPen Institute of Technology is prohibited. +*//*************************************************************************************/ +#include "SHpch.h" +#include "SHMaterialInstanceCache.h" + +#include "Graphics/MiddleEnd/Interface/SHMaterialInstance.h" +#include "Resource/ResourceLibrary.h" + + +namespace SHADE +{ + /*---------------------------------------------------------------------------------*/ + /* Usage Functions */ + /*---------------------------------------------------------------------------------*/ + SHADE::Handle SHMaterialInstanceCache::CreateOrGet(ResourceManager& manager, Handle material) + { + // Check if there is already an existing instance + auto matInst = cache.find(material); + if (matInst == cache.end()) + { + // Create and return + return cache.emplace(material, manager.Create(material)).first->second; + } + + return matInst->second; + } + + void SHMaterialInstanceCache::Remove(Handle material) + { + cache.erase(material); + } + + void SHMaterialInstanceCache::Clear() + { + cache.clear(); + } +} diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Materials/SHMaterialInstanceCache.h b/SHADE_Engine/src/Graphics/MiddleEnd/Materials/SHMaterialInstanceCache.h new file mode 100644 index 00000000..d85cb553 --- /dev/null +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Materials/SHMaterialInstanceCache.h @@ -0,0 +1,93 @@ +/************************************************************************************//*! +\file SHMaterialInstanceCache.h +\author Tng Kah Wei, kahwei.tng, 390009620 +\par email: kahwei.tng\@digipen.edu +\date Sep 25, 2022 +\brief Contains the definition of SHMaterialInstanceCache. + + +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 SHMaterialInstance; + class ResourceManager; + + /*-----------------------------------------------------------------------------------*/ + /* Type Definitions */ + /*-----------------------------------------------------------------------------------*/ + /*************************************************************************************/ + /*! + \brief + Creates and caches base SHMaterialInstances. Note that base SHMaterialInstances + refer to SHMaterialInstances with no overrides. + */ + /*************************************************************************************/ + class SHMaterialInstanceCache + { + public: + /*---------------------------------------------------------------------------------*/ + /* Usage Functions */ + /*---------------------------------------------------------------------------------*/ + /***********************************************************************************/ + /*! + + \brief + + + \param material + Material to get the SHMaterialInstance for. + + \return + Handle to the base SHMaterialInstance that is mapped to SHMaterial. + + */ + /***********************************************************************************/ + Handle CreateOrGet(ResourceManager& manager, Handle material); + /***********************************************************************************/ + /*! + + \brief + Removes a SHMaterialInstance from the cache with a matching material. + + \param material + Handle to a SHMaterial that is used to check for removal. + + */ + /***********************************************************************************/ + void Remove(Handle material); + /***********************************************************************************/ + /*! + + \brief + Removes all SHMaterialInstances in the cache. + + */ + /***********************************************************************************/ + void Clear(); + + private: + /*---------------------------------------------------------------------------------*/ + /* Type Definitions */ + /*---------------------------------------------------------------------------------*/ + using MaterialMap = std::unordered_map, Handle>; + + /*---------------------------------------------------------------------------------*/ + /* Data Members */ + /*---------------------------------------------------------------------------------*/ + MaterialMap cache; + }; +} From dc6289e8cf8c6a2b6e815d49bc8f69d6bd9e40b4 Mon Sep 17 00:00:00 2001 From: Brandon Mak Date: Sun, 25 Sep 2022 23:25:51 +0800 Subject: [PATCH 22/26] WIP --- SHADE_Application/src/Scenes/SBTestScene.cpp | 4 +- .../Graphics/Commands/SHVkCommandBuffer.cpp | 234 +++++++++--------- .../Graphics/MiddleEnd/Batching/SHBatch.cpp | 3 +- .../MiddleEnd/Interface/SHGraphicsSystem.cpp | 6 +- .../Graphics/RenderGraph/SHRenderGraph.cpp | 36 ++- .../src/Graphics/RenderGraph/SHRenderGraph.h | 2 + 6 files changed, 161 insertions(+), 124 deletions(-) diff --git a/SHADE_Application/src/Scenes/SBTestScene.cpp b/SHADE_Application/src/Scenes/SBTestScene.cpp index c91fee9c..fc2f9731 100644 --- a/SHADE_Application/src/Scenes/SBTestScene.cpp +++ b/SHADE_Application/src/Scenes/SBTestScene.cpp @@ -40,8 +40,8 @@ namespace Sandbox // Create Stress Test Objects static const SHVec3 TEST_OBJ_SCALE = { 0.2f, 0.2f, 0.2f }; - constexpr int NUM_ROWS = 200; - constexpr int NUM_COLS = 100; + constexpr int NUM_ROWS = 1; + constexpr int NUM_COLS = 1; static const SHVec3 TEST_OBJ_SPACING = { 1.0f, 1.0f, 1.0f }; static const SHVec3 TEST_OBJ_START_POS = { - (NUM_COLS / 2 * TEST_OBJ_SPACING.x ), 0.0f, 0.0f }; for (int z = 0; z < NUM_ROWS; ++z) diff --git a/SHADE_Engine/src/Graphics/Commands/SHVkCommandBuffer.cpp b/SHADE_Engine/src/Graphics/Commands/SHVkCommandBuffer.cpp index 83095371..eb65598c 100644 --- a/SHADE_Engine/src/Graphics/Commands/SHVkCommandBuffer.cpp +++ b/SHADE_Engine/src/Graphics/Commands/SHVkCommandBuffer.cpp @@ -16,7 +16,7 @@ namespace SHADE { /***************************************************************************/ /*! - + \brief Frees the command buffer. @@ -30,13 +30,13 @@ namespace SHADE /***************************************************************************/ /*! - + \brief - Only the command buffer is allocated using - VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT bit, is resetting + Only the command buffer is allocated using + VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT bit, is resetting individually permitted. Otherwise, throw exception. IMPORTANT NOTE: the command buffer cannot be in the pending state!!! - + */ /***************************************************************************/ void SHVkCommandBuffer::Reset(void) @@ -67,10 +67,10 @@ namespace SHADE /***************************************************************************/ /*! - + \brief Begins the command buffer. - + */ /***************************************************************************/ void SHVkCommandBuffer::BeginRecording(void) noexcept @@ -108,10 +108,10 @@ namespace SHADE /***************************************************************************/ /*! - + \brief End the recording of a command buffer. - + */ /***************************************************************************/ void SHVkCommandBuffer::EndRecording(void) noexcept @@ -121,21 +121,21 @@ namespace SHADE SHLOG_ERROR("Command Buffer not in recording state, cannot end recording. "); return; } - + vkCommandBuffer.end(); cmdBufferState = SH_CMD_BUFFER_STATE::EXECUTABLE; } /***************************************************************************/ /*! - + \brief - Begins a renderpass in the command buffer. 2 important things to note - here, the command buffer used MUST be a primary command buffer and + Begins a renderpass in the command buffer. 2 important things to note + here, the command buffer used MUST be a primary command buffer and command buffer MUST be in a recording state. - + \param renderpassHdl - Renderpass for obvious reasons. + Renderpass for obvious reasons. \param framebufferHdl Framebuffer required in the begin info. @@ -145,7 +145,7 @@ namespace SHADE \param extent Extent of the render area in the framebuffer. - + */ /***************************************************************************/ void SHVkCommandBuffer::BeginRenderpass(Handle const& renderpassHdl, Handle const& framebufferHdl, vk::Offset2D offset, vk::Extent2D extent) noexcept @@ -170,7 +170,7 @@ namespace SHADE vk::RenderPassBeginInfo renderPassInfo{}; renderPassInfo.renderPass = renderpassHdl->GetVkRenderpass(); renderPassInfo.framebuffer = framebufferHdl->GetVkFramebuffer(); - + // If the extent passed in is 0, use the framebuffer dimensions instead. if (extent.width == 0 && extent.height == 0) renderPassInfo.renderArea.extent = framebufferExtent; @@ -192,16 +192,16 @@ namespace SHADE } // Begin the render pass - vkCommandBuffer.beginRenderPass (&renderPassInfo, vk::SubpassContents::eInline); + vkCommandBuffer.beginRenderPass(&renderPassInfo, vk::SubpassContents::eInline); } /***************************************************************************/ /*! - + \brief Ends a renderpass. - + */ /***************************************************************************/ void SHVkCommandBuffer::EndRenderpass(void) noexcept @@ -216,14 +216,14 @@ namespace SHADE /***************************************************************************/ /*! - + \brief Sets the viewport dynamically for the command buffer. #NoteToSelf: Dynamic state will not affect pipelines that don't use dynamic state so there isn't a need to do any checks. Also, setting dynamic state like this only needs to happen ONCE per command buffer UNLESS a different viewport is to be used for different drawing commands. - + \param vpWidth viewport width @@ -254,7 +254,7 @@ namespace SHADE \param vpMaxDepth viewport maximum depth value - + */ /***************************************************************************/ 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 @@ -283,13 +283,13 @@ namespace SHADE /***************************************************************************/ /*! - + \brief Binds a pipeline object to the command buffer. - + \param pipelineHdl The pipeline to bind. - + */ /***************************************************************************/ void SHVkCommandBuffer::BindPipeline(Handle const& pipelineHdl) noexcept @@ -307,7 +307,7 @@ namespace SHADE /*! \brief - Binds a buffer to the vertex buffer binding point specified in + Binds a buffer to the vertex buffer binding point specified in bindingPoint. \param bindingPoint @@ -321,29 +321,32 @@ namespace SHADE */ /***************************************************************************/ - void SHVkCommandBuffer::BindVertexBuffer (uint32_t bindingPoint, Handle const& buffer, vk::DeviceSize offset) noexcept + void SHVkCommandBuffer::BindVertexBuffer(uint32_t bindingPoint, Handle const& buffer, vk::DeviceSize offset) noexcept { if (cmdBufferState == SH_CMD_BUFFER_STATE::RECORDING) { - auto bufferHandle = buffer->GetVkBuffer(); - vkCommandBuffer.bindVertexBuffers (bindingPoint, 1, &bufferHandle, &offset); + if (buffer) + { + auto bufferHandle = buffer->GetVkBuffer(); + vkCommandBuffer.bindVertexBuffers(bindingPoint, 1, &bufferHandle, &offset); + } } } /***************************************************************************/ /*! - + \brief Binds an index buffer to the pipeline. - + \param buffer The buffer to bind. \param startingIndex - The starting index in the index buffer. For example, 0 would mean - starting at the beginning. 5 would mean starting at byte offset + The starting index in the index buffer. For example, 0 would mean + starting at the beginning. 5 would mean starting at byte offset size(uint32_t) * 5. - + */ /***************************************************************************/ void SHVkCommandBuffer::BindIndexBuffer(Handle const& buffer, uint32_t startingIndex) const noexcept @@ -351,33 +354,33 @@ namespace SHADE if (cmdBufferState == SH_CMD_BUFFER_STATE::RECORDING) { auto bufferHandle = buffer->GetVkBuffer(); - vkCommandBuffer.bindIndexBuffer (bufferHandle, sizeof (uint32_t) * startingIndex, vk::IndexType::eUint32); + vkCommandBuffer.bindIndexBuffer(bufferHandle, sizeof(uint32_t) * startingIndex, vk::IndexType::eUint32); } } void SHVkCommandBuffer::BindDescriptorSet(Handle descSetGroup, vk::PipelineBindPoint bindPoint, uint32_t firstSet, std::span dynamicOffsets) { - vkCommandBuffer.bindDescriptorSets (bindPoint, boundPipelineLayoutHdl->GetVkPipelineLayout(), firstSet, descSetGroup->GetVkHandle(), dynamicOffsets); + vkCommandBuffer.bindDescriptorSets(bindPoint, boundPipelineLayoutHdl->GetVkPipelineLayout(), firstSet, descSetGroup->GetVkHandle(), dynamicOffsets); } /***************************************************************************/ /*! - + \brief Calls vkCmdDraw. - + \param vertexCount How many vertices to draw \param instanceCount Number of instances to draw - + \param firstVertex First vertex in the buffer of vertices to start from \param firstInstance First instance to start from. - + */ /***************************************************************************/ void SHVkCommandBuffer::DrawArrays(uint32_t vertexCount, uint32_t instanceCount, uint32_t firstVertex, uint32_t firstInstance) const noexcept @@ -387,30 +390,30 @@ namespace SHADE SHLOG_ERROR("Command buffer must have started recording before a pipeline can be bound. "); return; } - vkCommandBuffer.draw (vertexCount, instanceCount, firstVertex, firstInstance); + vkCommandBuffer.draw(vertexCount, instanceCount, firstVertex, firstInstance); } /***************************************************************************/ /*! - + \brief Issues a non-instanced indexed draw call. - + \param indexCount Number of indices to draw. \param firstIndex Starting index. if the array was 0, 2, 5, 4, and we indicated this to be - 1. The draw call would start from index 2. + 1. The draw call would start from index 2. \param vertexOffset - Starting vertex offset. This would indicate that vertex pulling should + Starting vertex offset. This would indicate that vertex pulling should start from a certain vertex. So a vertex offset of 3 (for example) would mean an index of 0 would mean the 3rd vertex. - + */ /***************************************************************************/ - void SHVkCommandBuffer::DrawIndexed (uint32_t indexCount, uint32_t firstIndex, uint32_t vertexOffset) const noexcept + void SHVkCommandBuffer::DrawIndexed(uint32_t indexCount, uint32_t firstIndex, uint32_t vertexOffset) const noexcept { if (cmdBufferState != SH_CMD_BUFFER_STATE::RECORDING) { @@ -422,7 +425,7 @@ namespace SHADE vkCommandBuffer.drawIndexed(indexCount, 1, firstIndex, vertexOffset, 0); } - + /***************************************************************************/ /*! @@ -445,35 +448,36 @@ namespace SHADE return; } - vkCommandBuffer.drawIndexedIndirect(indirectDrawData->GetVkBuffer(), 0, drawCount, sizeof(vk::DrawIndexedIndirectCommand)); + if (indirectDrawData) + vkCommandBuffer.drawIndexedIndirect(indirectDrawData->GetVkBuffer(), 0, drawCount, sizeof(vk::DrawIndexedIndirectCommand)); } void SHVkCommandBuffer::CopyBufferToImage(const vk::Buffer& src, const vk::Image& dst, const std::vector& copyInfo) { - vkCommandBuffer.copyBufferToImage - ( - src, dst, vk::ImageLayout::eTransferDstOptimal, - static_cast(copyInfo.size()), copyInfo.data() - ); + vkCommandBuffer.copyBufferToImage + ( + src, dst, vk::ImageLayout::eTransferDstOptimal, + static_cast(copyInfo.size()), copyInfo.data() + ); } void SHVkCommandBuffer::PipelineBarrier( - vk::PipelineStageFlags srcStage, - vk::PipelineStageFlags dstStage, - vk::DependencyFlags deps, - std::vector const& memoryBarriers, - std::vector const& bufferMemoryBarriers, - std::vector const& imageMemoryBarriers - ) const noexcept + vk::PipelineStageFlags srcStage, + vk::PipelineStageFlags dstStage, + vk::DependencyFlags deps, + std::vector const& memoryBarriers, + std::vector const& bufferMemoryBarriers, + std::vector const& imageMemoryBarriers + ) const noexcept { - vkCommandBuffer.pipelineBarrier ( - srcStage, - dstStage, - deps, - memoryBarriers, - bufferMemoryBarriers, - imageMemoryBarriers - ); + vkCommandBuffer.pipelineBarrier( + srcStage, + dstStage, + deps, + memoryBarriers, + bufferMemoryBarriers, + imageMemoryBarriers + ); } bool SHVkCommandBuffer::IsReadyToSubmit(void) const noexcept @@ -498,10 +502,10 @@ namespace SHADE /***************************************************************************/ /*! - + \brief Calls vkCmdPushConstants and submits data stored in command buffer. - + */ /***************************************************************************/ void SHVkCommandBuffer::SubmitPushConstants(void) const noexcept @@ -514,13 +518,13 @@ namespace SHADE /***************************************************************************/ /*! - + \brief Simply returns the command buffer handle. - - \return + + \return The command buffer handle. - + */ /***************************************************************************/ vk::CommandBuffer const& SHVkCommandBuffer::GetVkCommandBuffer(void) const noexcept @@ -530,11 +534,11 @@ namespace SHADE /***************************************************************************/ /*! - + \brief - See https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/vkGetRenderAreaGranularity.html + See https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/vkGetRenderAreaGranularity.html or look up vkGetRenderAreaGranularity. - + \param renderpassHdl Renderpass to get info from. @@ -544,9 +548,9 @@ namespace SHADE \param renderArea For the comparison. Again, look it up on the webpage. - \return + \return If optimal, true. otherwise false. - + */ /***************************************************************************/ bool SHVkCommandBuffer::IsRenderAreaOptimal(Handle const& renderpassHdl, vk::Extent2D const& framebufferExtent, vk::Rect2D const& renderArea) const noexcept @@ -558,14 +562,14 @@ namespace SHADE /***************************************************************************/ /*! - + \brief Setter for the state of the command buffer. - + \param state - - \return - + + \return + */ /***************************************************************************/ void SHVkCommandBuffer::SetState(SH_CMD_BUFFER_STATE state) noexcept @@ -575,12 +579,12 @@ namespace SHADE /***************************************************************************/ /*! - + \brief Returns the state of the command buffer. - - \return - + + \return + */ /***************************************************************************/ SH_CMD_BUFFER_STATE SHVkCommandBuffer::GetState(void) const noexcept @@ -590,14 +594,14 @@ namespace SHADE /***************************************************************************/ /*! - + \brief Creates a command buffer. Cmd buffer can be primary or secondary. If secondary, flags will automatically have renderpass continue bit. Command pool used to create this command buffer will determine whether or not - this buffer will be allocated with + this buffer will be allocated with VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT using the reset mode. - + \param logicalDevice Need a logical device to create a buffer. @@ -606,7 +610,7 @@ namespace SHADE \param type Type of the command buffer; primary or secondary. - + */ /***************************************************************************/ SHVkCommandBuffer::SHVkCommandBuffer(Handle const& commandPool, SH_CMD_BUFFER_TYPE type) noexcept @@ -616,7 +620,7 @@ namespace SHADE , parentPoolResetMode{ SH_CMD_POOL_RESET::POOL_BASED } , usageFlags{} , commandBufferCount{ 0 } - , parentPool{commandPool} + , parentPool{ commandPool } , pushConstantData{} { @@ -657,54 +661,54 @@ namespace SHADE commandBufferType = type; commandBufferCount = allocateInfo.commandBufferCount; - if (parentPool->GetIsTransient ()) + if (parentPool->GetIsTransient()) usageFlags = vk::CommandBufferUsageFlagBits::eOneTimeSubmit; if (commandBufferType == SH_CMD_BUFFER_TYPE::SECONDARY) usageFlags |= vk::CommandBufferUsageFlagBits::eRenderPassContinue; - + // Reset all the push constant data to 0 - memset (pushConstantData, 0, PUSH_CONSTANT_SIZE); + memset(pushConstantData, 0, PUSH_CONSTANT_SIZE); } /***************************************************************************/ /*! - + \brief Move ctor. Invalidates Vulkan handles. - + \param rhs the other command buffer. - + */ /***************************************************************************/ SHVkCommandBuffer::SHVkCommandBuffer(SHVkCommandBuffer&& rhs) noexcept - : vkCommandBuffer {std::move (rhs.vkCommandBuffer)} - , cmdBufferState {rhs.cmdBufferState} - , commandBufferType {rhs.commandBufferType} - , parentPoolResetMode {rhs.parentPoolResetMode} - , usageFlags {rhs.usageFlags} - , commandBufferCount {rhs.commandBufferCount} - , parentPool {rhs.parentPool} - , boundPipelineLayoutHdl{rhs.boundPipelineLayoutHdl } + : vkCommandBuffer{ std::move(rhs.vkCommandBuffer) } + , cmdBufferState{ rhs.cmdBufferState } + , commandBufferType{ rhs.commandBufferType } + , parentPoolResetMode{ rhs.parentPoolResetMode } + , usageFlags{ rhs.usageFlags } + , commandBufferCount{ rhs.commandBufferCount } + , parentPool{ rhs.parentPool } + , boundPipelineLayoutHdl{ rhs.boundPipelineLayoutHdl } { - memcpy (pushConstantData, rhs.pushConstantData, PUSH_CONSTANT_SIZE); + memcpy(pushConstantData, rhs.pushConstantData, PUSH_CONSTANT_SIZE); rhs.vkCommandBuffer = VK_NULL_HANDLE; } /***************************************************************************/ /*! - + \brief Move assignment operator. Invalidates Vulkan handles. - + \param rhs The other Vulkan Handle. - - \return + + \return a reference itself. - + */ /***************************************************************************/ SHVkCommandBuffer& SHVkCommandBuffer::operator=(SHVkCommandBuffer&& rhs) noexcept diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.cpp index 7b2ebd49..f73c5306 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.cpp @@ -203,7 +203,8 @@ namespace SHADE } // Transfer to GPU - transformDataBuffer[frameIndex]->WriteToMemory(transformData.data(), static_cast(transformData.size() * sizeof(SHMatrix)), 0, 0); + if (transformDataBuffer[frameIndex]) + transformDataBuffer[frameIndex]->WriteToMemory(transformData.data(), static_cast(transformData.size() * sizeof(SHMatrix)), 0, 0); } void SHBatch::Build(Handle _device, uint32_t frameIndex) diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp index b909aeff..bb2391e3 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp @@ -150,9 +150,9 @@ namespace SHADE //compositeSubpass->AddInput("Position"); // TODO: Use macro to add this node when SH_EDITOR is enabled - //auto imguiNode = worldRenderGraph->AddNode("ImGui Node", { "Present" }, {}); - //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"); worldRenderGraph->Generate(); diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp index 6070361f..7ef5c0b9 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp @@ -348,7 +348,7 @@ namespace SHADE void SHSubpass::Execute(Handle& commandBuffer, uint32_t frameIndex) noexcept { - // Ensure updated transforms and materials are provided + // Ensure correct transforms are provided superBatch->UpdateBuffers(frameIndex); // Draw all the batches @@ -524,6 +524,7 @@ namespace SHADE , configured{ rhs.configured } , executed{ rhs.executed } , ptrToResources{ rhs.ptrToResources } + , pipelineLibrary{ std::move(rhs.pipelineLibrary) } { rhs.renderpass = {}; } @@ -544,6 +545,7 @@ namespace SHADE resourceAttachmentMapping = std::move(rhs.resourceAttachmentMapping); subpassIndexing = std::move(rhs.subpassIndexing); ptrToResources = std::move(rhs.ptrToResources); + pipelineLibrary = std::move(rhs.pipelineLibrary); rhs.renderpass = {}; @@ -625,7 +627,7 @@ namespace SHADE } void SHRenderGraphNode::FinaliseBatch(uint32_t frameIndex) -{ + { batcher.FinaliseBatches(logicalDeviceHdl, frameIndex); } @@ -993,6 +995,34 @@ namespace SHADE } + SHRenderGraph::SHRenderGraph(SHRenderGraph&& rhs) noexcept + : logicalDeviceHdl{ rhs.logicalDeviceHdl } + , swapchainHdl{ rhs.swapchainHdl } + , nodeIndexing{ std::move(rhs.nodeIndexing) } + , nodes{ std::move(rhs.nodes) } + , graphResources{ std::move(rhs.graphResources) } + , resourceManager{ std::move(rhs.resourceManager) } + , globalData{ rhs.globalData } + { + + } + + SHRenderGraph& SHRenderGraph::operator=(SHRenderGraph&& rhs) noexcept + { + if (&rhs == this) + return *this; + + logicalDeviceHdl = rhs.logicalDeviceHdl; + swapchainHdl = rhs.swapchainHdl; + nodeIndexing = std::move(rhs.nodeIndexing); + nodes = std::move(rhs.nodes); + graphResources = std::move(rhs.graphResources); + resourceManager = std::move(rhs.resourceManager); + globalData = rhs.globalData; + + return *this; + } + /***************************************************************************/ /*! @@ -1084,7 +1114,7 @@ namespace SHADE } void SHRenderGraph::FinaliseBatch(uint32_t frameIndex) -{ + { for (auto& node : nodes) { node->FinaliseBatch(frameIndex); diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.h b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.h index b8c00417..d5421bdc 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.h +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.h @@ -279,6 +279,8 @@ namespace SHADE /* CTORS AND DTORS */ /*-----------------------------------------------------------------------*/ SHRenderGraph (void) noexcept; + SHRenderGraph(SHRenderGraph&& rhs) noexcept; + SHRenderGraph& operator=(SHRenderGraph&& rhs) noexcept; /*-----------------------------------------------------------------------*/ /* PUBLIC MEMBER FUNCTIONS */ From 864983360425cba5505f4d306cabe8e99c07aca9 Mon Sep 17 00:00:00 2001 From: Brandon Mak Date: Sun, 25 Sep 2022 23:45:05 +0800 Subject: [PATCH 23/26] subpass not null anymore --- SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp | 8 +++++++- SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.h | 2 ++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp index 7ef5c0b9..85d822b5 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp @@ -220,7 +220,6 @@ namespace SHADE , depthReferences{} , inputReferences{} { - superBatch = rm.Create(GetHandle()); } /***************************************************************************/ @@ -366,6 +365,12 @@ namespace SHADE exteriorDrawCalls.push_back(newDrawCall); } + void SHSubpass::Init(ResourceManager& resourceManager) noexcept + { + superBatch = resourceManager.Create(GetHandle()); + + } + /***************************************************************************/ /*! @@ -579,6 +584,7 @@ namespace SHADE subpasses.emplace_back(resourceManager.Create(resourceManager, GetHandle(), subpasses.size(), &resourceAttachmentMapping, ptrToResources)); subpassIndexing.try_emplace(subpassName, static_cast(subpasses.size()) - 1u); Handle subpass = subpasses.back(); + subpass->Init(resourceManager); // Register the SuperBatch batcher.RegisterSuperBatch(subpass->GetSuperBatch()); diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.h b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.h index d5421bdc..45624436 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.h +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.h @@ -140,6 +140,8 @@ namespace SHADE void Execute(Handle& commandBuffer, uint32_t frameIndex) noexcept; void AddExteriorDrawCalls(std::function&)> const& newDrawCall) noexcept; + void Init (ResourceManager& resourceManager) noexcept; + /*-----------------------------------------------------------------------*/ /* GETTERS AND SETTERS */ /*-----------------------------------------------------------------------*/ From a5c804ca8bba5f62921ca6b5e92fe651da2f916b Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Mon, 26 Sep 2022 00:08:32 +0800 Subject: [PATCH 24/26] Fixed SHRenderGraph not moving the batcher --- SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp index 85d822b5..92276f95 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp @@ -530,6 +530,8 @@ namespace SHADE , executed{ rhs.executed } , ptrToResources{ rhs.ptrToResources } , pipelineLibrary{ std::move(rhs.pipelineLibrary) } + , batcher { std::move(rhs.batcher) } + { rhs.renderpass = {}; } @@ -551,6 +553,7 @@ namespace SHADE subpassIndexing = std::move(rhs.subpassIndexing); ptrToResources = std::move(rhs.ptrToResources); pipelineLibrary = std::move(rhs.pipelineLibrary); + batcher = std::move(rhs.batcher); rhs.renderpass = {}; From 31dff230ef62e09237293e0a4d822c3db1d4f315 Mon Sep 17 00:00:00 2001 From: Brandon Mak Date: Mon, 26 Sep 2022 00:37:58 +0800 Subject: [PATCH 25/26] FIXED MY SHIT WHEE --- .../src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp | 2 +- SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp index bb2391e3..2637cb75 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp @@ -150,7 +150,7 @@ namespace SHADE //compositeSubpass->AddInput("Position"); // TODO: Use macro to add this node when SH_EDITOR is enabled - auto imguiNode = worldRenderGraph->AddNode("ImGui Node", { "Present" }, {}); + auto imguiNode = worldRenderGraph->AddNode("ImGui Node", { "Present" }, {"G-Buffer"}); auto imguiSubpass = imguiNode->AddSubpass("ImGui Draw"); imguiSubpass->AddColorOutput("Present"); diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp index 92276f95..3f5641c0 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp @@ -716,7 +716,7 @@ namespace SHADE // First we want to take all the attachment descriptions and initialize the // finalLayout to whatever layout is specified in the last subpass that references the attachment. - for (auto& node : nodes) + for (uint32_t i = 0; auto& node : nodes) { // key is handle ID, value is pair (first is initial layout, second is final layout). std::unordered_map resourceAttLayouts; @@ -730,7 +730,7 @@ namespace SHADE { for (auto& color : subpass->colorReferences) { - if (node->attResources[color.attachment]->resourceType == SH_ATT_DESC_TYPE::COLOR_PRESENT) + if (i == nodes.size() - 1 && node->attResources[color.attachment]->resourceType == SH_ATT_DESC_TYPE::COLOR_PRESENT) resourceAttLayouts[color.attachment] = vk::ImageLayout::ePresentSrcKHR; else resourceAttLayouts[color.attachment] = color.layout; @@ -749,6 +749,7 @@ namespace SHADE att.initialLayout = vk::ImageLayout::eUndefined; att.finalLayout = resourceAttLayouts[i]; } + ++i; } // at this point all attachment descs will have their final layouts initialized as if they were standalone and did @@ -857,7 +858,7 @@ namespace SHADE for (auto& inputAtt : subpass->inputReferences) { auto resource = node->attResources[inputAtt.attachment]; - if (resource->resourceType == SH_ATT_DESC_TYPE::COLOR) + if (resource->resourceType == SH_ATT_DESC_TYPE::COLOR || resource->resourceType == SH_ATT_DESC_TYPE::COLOR_PRESENT) colorRead |= (1 << i); else if (resource->resourceType == SH_ATT_DESC_TYPE::DEPTH_STENCIL) depthRead |= (1 << i); From 6d68e6cb5e2df8fade43c6aa779644bd0e05993a Mon Sep 17 00:00:00 2001 From: Brandon Mak Date: Mon, 26 Sep 2022 00:37:58 +0800 Subject: [PATCH 26/26] FIXED MY SHIT WHEE (render graph color present attachment now have correct layout) --- .../src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp | 2 +- SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp index bb2391e3..2637cb75 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp @@ -150,7 +150,7 @@ namespace SHADE //compositeSubpass->AddInput("Position"); // TODO: Use macro to add this node when SH_EDITOR is enabled - auto imguiNode = worldRenderGraph->AddNode("ImGui Node", { "Present" }, {}); + auto imguiNode = worldRenderGraph->AddNode("ImGui Node", { "Present" }, {"G-Buffer"}); auto imguiSubpass = imguiNode->AddSubpass("ImGui Draw"); imguiSubpass->AddColorOutput("Present"); diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp index 92276f95..3f5641c0 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp @@ -716,7 +716,7 @@ namespace SHADE // First we want to take all the attachment descriptions and initialize the // finalLayout to whatever layout is specified in the last subpass that references the attachment. - for (auto& node : nodes) + for (uint32_t i = 0; auto& node : nodes) { // key is handle ID, value is pair (first is initial layout, second is final layout). std::unordered_map resourceAttLayouts; @@ -730,7 +730,7 @@ namespace SHADE { for (auto& color : subpass->colorReferences) { - if (node->attResources[color.attachment]->resourceType == SH_ATT_DESC_TYPE::COLOR_PRESENT) + if (i == nodes.size() - 1 && node->attResources[color.attachment]->resourceType == SH_ATT_DESC_TYPE::COLOR_PRESENT) resourceAttLayouts[color.attachment] = vk::ImageLayout::ePresentSrcKHR; else resourceAttLayouts[color.attachment] = color.layout; @@ -749,6 +749,7 @@ namespace SHADE att.initialLayout = vk::ImageLayout::eUndefined; att.finalLayout = resourceAttLayouts[i]; } + ++i; } // at this point all attachment descs will have their final layouts initialized as if they were standalone and did @@ -857,7 +858,7 @@ namespace SHADE for (auto& inputAtt : subpass->inputReferences) { auto resource = node->attResources[inputAtt.attachment]; - if (resource->resourceType == SH_ATT_DESC_TYPE::COLOR) + if (resource->resourceType == SH_ATT_DESC_TYPE::COLOR || resource->resourceType == SH_ATT_DESC_TYPE::COLOR_PRESENT) colorRead |= (1 << i); else if (resource->resourceType == SH_ATT_DESC_TYPE::DEPTH_STENCIL) depthRead |= (1 << i);