Added triple buffering to SHDebugDrawSystem

This commit is contained in:
Kah Wei 2022-10-27 10:12:30 +08:00
parent 57027da80b
commit 2108d9e1f6
10 changed files with 114 additions and 26 deletions

View File

@ -149,6 +149,10 @@ namespace Sandbox
{
SHFrameRateController::UpdateFRC();
SHInputManager::UpdateInput(SHFrameRateController::GetRawDeltaTime());
auto debugDraw = SHSystemManager::GetSystem<SHDebugDrawSystem>();
//debugDraw->DrawLine(SHVec4(1.0f, 1.0f, 1.0f, 1.0f), SHVec3(-5.0f, 0.0f, 0.0f), SHVec3(5.0f, 0.0f, 0.0f));
debugDraw->DrawCube(SHVec4(1.0f, 1.0f, 1.0f, 1.0f), {}, SHVec3(1.0f, 1.0f, 1.0f));
SHSceneManager::UpdateSceneManager();
#ifdef SHEDITOR
if(editor->editorState == SHEditor::State::PLAY)

View File

@ -17,6 +17,7 @@
#include "Assets/SHAssetManager.h"
#include "Camera/SHCameraComponent.h"
#include "Resource/SHResourceManager.h"
#include "Graphics/MiddleEnd/Interface/SHDebugDrawSystem.h"
using namespace SHADE;

View File

@ -11,6 +11,9 @@ of DigiPen Institute of Technology is prohibited.
*//*************************************************************************************/
#include "SHpch.h"
#include "SHDebugDrawSystem.h"
// STL Includes
#include <algorithm>
// Project Includes
#include "../Meshes/SHMeshData.h"
#include "../Meshes/SHPrimitiveGenerator.h"
#include "ECS_Base/Managers/SHSystemManager.h"
@ -26,25 +29,30 @@ namespace SHADE
/* DrawRoutine */
/*---------------------------------------------------------------------------------*/
SHDebugDrawSystem::ProcessPointsRoutine::ProcessPointsRoutine()
: SHSystemRoutine("Debug Draw")
{}
: SHSystemRoutine("Debug Draw", true)
{
SystemFamily::GetID<SHDebugDrawSystem>();
}
void SHDebugDrawSystem::ProcessPointsRoutine::Execute(double dt) noexcept
{
auto gfxSys = SHSystemManager::GetSystem<SHGraphicsSystem>();
if (gfxSys)
if (!gfxSys)
{
SHLOG_WARNING("[DebugDraw] Attempted to do debug draw without a graphics system.");
return;
}
// Get current frame index
const uint32_t FRAME_IDX = gfxSys->GetCurrentFrameIndex();
// Create the buffer if it doesn't exist or just update it
SHDebugDrawSystem* system = static_cast<SHDebugDrawSystem*>(GetSystem());
system->numPoints = system->points.size();
system->numPoints[FRAME_IDX] = system->points.size();
const uint32_t DATA_SIZE = sizeof(PointVertex) * system->points.size();
if (DATA_SIZE > 0)
{
SHVkUtil::EnsureBufferAndCopyHostVisibleData(gfxSys->GetDevice(), system->vertexBuffer, system->points.data(), DATA_SIZE, vk::BufferUsageFlagBits::eVertexBuffer);
system->vertexBuffers[FRAME_IDX]->WriteToMemory(system->points.data(), DATA_SIZE, 0, 0);
}
// Reset for next frame
@ -61,23 +69,45 @@ namespace SHADE
auto const& RENDERERS = GFX_SYSTEM->GetDefaultViewport()->GetRenderers();
auto renderGraph = RENDERERS[SHGraphicsConstants::RenderGraphIndices::WORLD]->GetRenderGraph();
auto subPass = renderGraph->GetNode("Debug Draw")->GetSubpass("Debug Draw");
subPass->AddExteriorDrawCalls([&](Handle<SHVkCommandBuffer>& cmdBuffer)
subPass->AddExteriorDrawCalls([this, GFX_SYSTEM](Handle<SHVkCommandBuffer>& cmdBuffer)
{
// Get Current frame index
const uint32_t FRAME_IDX = GFX_SYSTEM->GetCurrentFrameIndex();
// Don't draw if no points
if (numPoints <= 0)
if (numPoints[FRAME_IDX] <= 0)
return;
cmdBuffer->BindPipeline(GFX_SYSTEM->GetDebugDrawPipeline());
cmdBuffer->BindVertexBuffer(0, vertexBuffer, 0);
cmdBuffer->DrawArrays(static_cast<uint32_t>(points.size()), 1, 0, 0);
cmdBuffer->BindVertexBuffer(0, vertexBuffers[FRAME_IDX], 0);
cmdBuffer->DrawArrays(numPoints[FRAME_IDX], 1, 0, 0);
});
// Reset trackers
std::fill_n(numPoints.begin(), numPoints.size(), 0);
// Allocate buffers
static constexpr uint32_t BUFFER_SIZE = MAX_POINTS * sizeof(PointVertex);
for (Handle<SHVkBuffer>& bufHandle : vertexBuffers)
{
bufHandle = GFX_SYSTEM->GetDevice()->CreateBuffer
(
BUFFER_SIZE,
nullptr,
0,
vk::BufferUsageFlagBits::eVertexBuffer,
VmaMemoryUsage::VMA_MEMORY_USAGE_AUTO,
VmaAllocationCreateFlagBits::VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT | VmaAllocationCreateFlagBits::VMA_ALLOCATION_CREATE_MAPPED_BIT
);
}
}
void SHDebugDrawSystem::Exit()
{
if (vertexBuffer)
for (auto vertexBuffer : vertexBuffers)
{
vertexBuffer.Free();
if (vertexBuffer)
vertexBuffer.Free();
}
}
@ -86,6 +116,12 @@ namespace SHADE
/*---------------------------------------------------------------------------------*/
void SHDebugDrawSystem::DrawLine(const SHVec4& color, const SHVec3& startPt, const SHVec3& endPt)
{
if (points.size() > MAX_POINTS)
{
SHLOG_WARNING("[DebugDraw] Exceeded maximum size of drawable debug elements.");
return;
}
points.emplace_back(PointVertex{ startPt, color });
points.emplace_back(PointVertex{ endPt, color });
}

View File

@ -22,6 +22,7 @@ of DigiPen Institute of Technology is prohibited.
#include "ECS_Base/System/SHSystemRoutine.h"
#include "Resource/SHHandle.h"
#include "Graphics/Buffers/SHVkBuffer.h"
#include "SHGraphicsConstants.h"
namespace SHADE
{
@ -34,7 +35,7 @@ namespace SHADE
Manages the Debug Draw system.
*/
/***********************************************************************************/
class SH_API SHDebugDrawSystem : public SHSystem
class SH_API SHDebugDrawSystem final : public SHSystem
{
public:
/*-------------------------------------------------------------------------------*/
@ -66,22 +67,30 @@ namespace SHADE
void DrawSphere(const SHVec4& color, const SHVec3& pos, double radius);
private:
/*-------------------------------------------------------------------------------*/
/* Type Definitions */
/*-------------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------------*/
/* Type Definitions */
/*---------------------------------------------------------------------------------*/
struct SH_API PointVertex
{
SHVec3 Position;
SHVec4 Position;
SHVec4 Color;
};
/*-------------------------------------------------------------------------------*/
/* Data Members */
/*-------------------------------------------------------------------------------*/
using TripleBuffer = std::array<Handle<SHVkBuffer>, SHGraphicsConstants::NUM_FRAME_BUFFERS>;
using TripleUInt = std::array<uint32_t, SHGraphicsConstants::NUM_FRAME_BUFFERS>;
/*---------------------------------------------------------------------------------*/
/* Constants */
/*---------------------------------------------------------------------------------*/
static constexpr uint32_t MAX_POINTS = 100'000;
/*---------------------------------------------------------------------------------*/
/* Data Members */
/*---------------------------------------------------------------------------------*/
// CPU Buffers
std::vector<PointVertex> points;
// GPU Buffers
Handle<SHVkBuffer> vertexBuffer;
uint32_t numPoints = 0;
TripleBuffer vertexBuffers;
TripleUInt numPoints;
// Cached Points for polygon drawing
std::vector<SHVec3> spherePoints;
};

View File

@ -24,6 +24,13 @@ namespace SHADE
// Ensure dereferenced type is SHVec3
static_assert(std::is_same_v<SHVec3, std::remove_cvref_t<decltype(*pointListBegin)>>, "Parameters to DrawPoly must be SHVec3.");
// Check if points exceeded max
if (points.size() > MAX_POINTS)
{
SHLOG_WARNING("[DebugDraw] Exceeded maximum size of drawable debug elements.");
return;
}
const size_t POINTS_COUNT = pointListEnd - pointListBegin;
// Invalid polygon
if (POINTS_COUNT < 2)

View File

@ -37,6 +37,7 @@ of DigiPen Institute of Technology is prohibited.
#include "Assets/Asset Types/SHTextureAsset.h"
#include "Graphics/MiddleEnd/Interface/SHMousePickSystem.h"
#include "Graphics/MiddleEnd/Lights/SHLightingSubSystem.h"
#include "Graphics/SHVkUtil.h"
namespace SHADE
{
@ -239,12 +240,41 @@ namespace SHADE
.globalDescSetLayouts = SHGraphicsGlobalData::GetDescSetLayouts()
}
);
debugDrawPipeline = resourceManager.Create<SHVkPipeline>(device, debugDrawPipelineLayout);
debugDrawPipeline = resourceManager.Create<SHVkPipeline>(device, debugDrawPipelineLayout, nullptr, debugDrawNode->GetRenderpass(), debugDrawSubpass);
debugDrawPipeline->GetPipelineState().SetRasterizationState(SHRasterizationState
{
.polygonMode = vk::PolygonMode::eLine,
.cull_mode = vk::CullModeFlagBits::eNone
});
SHVertexInputState debugDrawVertexInputState;
debugDrawVertexInputState.AddBinding(false, true, { SHVertexAttribute(SHAttribFormat::FLOAT_4D), SHVertexAttribute(SHAttribFormat::FLOAT_4D) });
debugDrawPipeline->GetPipelineState().SetVertexInputState(debugDrawVertexInputState);
SHColorBlendState colorBlendState{};
colorBlendState.logic_op_enable = VK_FALSE;
colorBlendState.logic_op = vk::LogicOp::eCopy;
auto const& subpassColorReferences = debugDrawSubpass->GetColorAttachmentReferences();
colorBlendState.attachments.reserve(subpassColorReferences.size());
for (auto& att : subpassColorReferences)
{
colorBlendState.attachments.push_back(vk::PipelineColorBlendAttachmentState
{
.blendEnable = SHVkUtil::IsBlendCompatible(debugDrawSubpass->GetFormatFromAttachmentReference(att.attachment)),
.srcColorBlendFactor = vk::BlendFactor::eSrcAlpha,
.dstColorBlendFactor = vk::BlendFactor::eOneMinusSrcAlpha,
.colorBlendOp = vk::BlendOp::eAdd,
.srcAlphaBlendFactor = vk::BlendFactor::eOne,
.dstAlphaBlendFactor = vk::BlendFactor::eZero,
.alphaBlendOp = vk::BlendOp::eAdd,
.colorWriteMask = vk::ColorComponentFlagBits::eR | vk::ColorComponentFlagBits::eG | vk::ColorComponentFlagBits::eB | vk::ColorComponentFlagBits::eA,
}
);
}
debugDrawPipeline->GetPipelineState().SetColorBlenState(colorBlendState);
debugDrawPipeline->ConstructPipeline();
}
void SHGraphicsSystem::InitMiddleEnd(void) noexcept

View File

@ -288,7 +288,7 @@ namespace SHADE
Handle<SHMousePickSystem> GetMousePickSystem(void) const noexcept {return mousePickSystem;};
Handle<SHPostOffscreenRenderSystem> GetPostOffscreenRenderSystem(void) const noexcept {return postOffscreenRender;};
Handle<SHVkPipeline> GetDebugDrawPipeline(void) const noexcept { return debugDrawPipeline; }
uint32_t GetCurrentFrameIndex(void) const noexcept { return renderContext.GetCurrentFrame(); }
private:

View File

@ -47,12 +47,13 @@ namespace SHADE
/*-----------------------------------------------------------------------*/
/* CTORS AND DTORS */
/*-----------------------------------------------------------------------*/
//! For constructing a graphics pipeline
SHVkPipeline (Handle<SHVkLogicalDevice> const& inLogicalDeviceHdl,
Handle<SHVkPipelineLayout> const& inPipelineLayout,
SHVkPipelineState const* const state,
Handle<SHVkRenderpass> const& renderpassHdl,
Handle<SHSubpass> subpass) noexcept;
//! For constructing a compute pipeline
SHVkPipeline(Handle<SHVkLogicalDevice> const& inLogicalDeviceHdl,
Handle<SHVkPipelineLayout> const& inPipelineLayout) noexcept;

View File

@ -1,7 +1,7 @@
#version 450
#extension GL_KHR_vulkan_glsl : enable
layout(location = 0) in vec3 aVertexPos;
layout(location = 0) in vec4 aVertexPos;
layout(location = 1) in vec4 aVertColor;
@ -19,6 +19,6 @@ layout(set = 2, binding = 0) uniform CameraData
void main()
{
gl_Position = cameraData.vpMat * vec4 (aVertexPos, 1.0f);
gl_Position = cameraData.vpMat * vec4 (aVertexPos.xyz, 1.0f);
Out.vertColor = aVertColor;
}

Binary file not shown.