Fixed some bugs in render graph

- Changed the eid buffer for instanced rendering to a vec2 (potentially vec3 or 4), to pass other types of data like light layer index. 
- Renamed some render graph nodes and subpasses. Added a dummy render pass to transition the scene to read only optimal.
- offscreen buffer resource now transitions to eShaderReadOnlyOptimal instead of eGeneral
This commit is contained in:
Brandon Mak 2022-10-26 01:08:02 +08:00
parent 5016600397
commit 4b7a837469
14 changed files with 85 additions and 34 deletions

View File

@ -110,7 +110,7 @@ namespace SHADE
// Clear CPU buffers // Clear CPU buffers
drawData.clear(); drawData.clear();
transformData.clear(); transformData.clear();
eidData.clear(); instancedIntegerData.clear();
matPropsData.reset(); matPropsData.reset();
matPropsDataSize = 0; matPropsDataSize = 0;
@ -120,7 +120,7 @@ namespace SHADE
{ {
drawDataBuffer[i].Free(); drawDataBuffer[i].Free();
transformDataBuffer[i].Free(); transformDataBuffer[i].Free();
eidBuffer[i].Free(); instancedIntegerBuffer[i].Free();
matPropsBuffer[i].Free(); matPropsBuffer[i].Free();
} }
} }
@ -208,7 +208,7 @@ namespace SHADE
transformDataBuffer[frameIndex]->WriteToMemory(transformData.data(), static_cast<uint32_t>(transformData.size() * sizeof(SHMatrix)), 0, 0); transformDataBuffer[frameIndex]->WriteToMemory(transformData.data(), static_cast<uint32_t>(transformData.size() * sizeof(SHMatrix)), 0, 0);
} }
void SHBatch::UpdateEIDBuffer(uint32_t frameIndex) void SHBatch::UpdateInstancedIntegerBuffer(uint32_t frameIndex)
{ {
if (frameIndex >= SHGraphicsConstants::NUM_FRAME_BUFFERS) if (frameIndex >= SHGraphicsConstants::NUM_FRAME_BUFFERS)
{ {
@ -217,18 +217,23 @@ namespace SHADE
} }
// Reset Transform Data // Reset Transform Data
eidData.clear(); instancedIntegerData.clear();
// Populate on the CPU // Populate on the CPU
for (auto& subBatch : subBatches) for (auto& subBatch : subBatches)
for (const SHRenderable* renderable : subBatch.Renderables) for (const SHRenderable* renderable : subBatch.Renderables)
{ {
eidData.emplace_back(renderable->GetEID()); instancedIntegerData.emplace_back(SHInstancedIntegerData
{
renderable->GetEID(),
renderable->GetLightLayer()
}
);
} }
// Transfer to GPU // Transfer to GPU
if (eidBuffer[frameIndex]) if (instancedIntegerBuffer[frameIndex])
eidBuffer[frameIndex]->WriteToMemory(eidData.data(), static_cast<EntityID>(eidData.size() * sizeof(EntityID)), 0, 0); instancedIntegerBuffer[frameIndex]->WriteToMemory(instancedIntegerData.data(), static_cast<uint32_t>(instancedIntegerData.size() * sizeof(SHInstancedIntegerData)), 0, 0);
} }
@ -264,8 +269,8 @@ namespace SHADE
transformData.reserve(numTotalElements); transformData.reserve(numTotalElements);
transformData.clear(); transformData.clear();
// - EID data // - EID data
eidData.reserve(numTotalElements); instancedIntegerData.reserve(numTotalElements);
eidData.clear(); instancedIntegerData.clear();
// - Material Properties Data // - Material Properties Data
@ -320,8 +325,13 @@ namespace SHADE
transformData.emplace_back(transform->GetTRS()); transformData.emplace_back(transform->GetTRS());
} }
eidData.emplace_back(eid); instancedIntegerData.emplace_back(SHInstancedIntegerData
{
eid,
renderable->GetLightLayer()
}
);
// Material Properties // Material Properties
if (!EMPTY_MAT_PROPS) if (!EMPTY_MAT_PROPS)
{ {
@ -351,10 +361,10 @@ namespace SHADE
device, transformDataBuffer[frameIndex], transformData.data(), TF_DATA_BYTES, device, transformDataBuffer[frameIndex], transformData.data(), TF_DATA_BYTES,
BuffUsage::eVertexBuffer BuffUsage::eVertexBuffer
); );
const uint32_t EID_DATA_BYTES = static_cast<uint32_t>(eidData.size() * sizeof(EntityID)); const uint32_t EID_DATA_BYTES = static_cast<uint32_t>(instancedIntegerData.size() * sizeof(SHInstancedIntegerData));
SHVkUtil::EnsureBufferAndCopyHostVisibleData SHVkUtil::EnsureBufferAndCopyHostVisibleData
( (
device, eidBuffer[frameIndex], eidData.data(), EID_DATA_BYTES, device, instancedIntegerBuffer[frameIndex], instancedIntegerData.data(), EID_DATA_BYTES,
BuffUsage::eVertexBuffer BuffUsage::eVertexBuffer
); );
// - Material Properties Buffer // - Material Properties Buffer
@ -378,8 +388,8 @@ namespace SHADE
// Bind all required objects before drawing // Bind all required objects before drawing
static std::array<uint32_t, 1> dynamicOffset { 0 }; static std::array<uint32_t, 1> dynamicOffset { 0 };
cmdBuffer->BindPipeline(pipeline); cmdBuffer->BindPipeline(pipeline);
cmdBuffer->BindVertexBuffer(SHGraphicsConstants::VertexBufferBindings::TRANSFORM, transformDataBuffer[frameIndex], 0); cmdBuffer->BindVertexBuffer(SHGraphicsConstants::VertexBufferBindings::TRANSFORM, transformDataBuffer[frameIndex], 0);
cmdBuffer->BindVertexBuffer(SHGraphicsConstants::VertexBufferBindings::EID, eidBuffer[frameIndex], 0); cmdBuffer->BindVertexBuffer(SHGraphicsConstants::VertexBufferBindings::INTEGER_DATA, instancedIntegerBuffer[frameIndex], 0);
if (matPropsDescSet[frameIndex]) if (matPropsDescSet[frameIndex])
{ {
cmdBuffer->BindDescriptorSet cmdBuffer->BindDescriptorSet

View File

@ -23,6 +23,7 @@ of DigiPen Institute of Technology is prohibited.
#include "Math/SHMatrix.h" #include "Math/SHMatrix.h"
#include "Graphics/MiddleEnd/Interface/SHGraphicsConstants.h" #include "Graphics/MiddleEnd/Interface/SHGraphicsConstants.h"
#include "ECS_Base/SHECSMacros.h" #include "ECS_Base/SHECSMacros.h"
#include "Graphics/MiddleEnd/Interface/SHInstancedIntegerData.h"
namespace SHADE namespace SHADE
{ {
@ -79,7 +80,7 @@ namespace SHADE
void Clear(); void Clear();
void UpdateMaterialBuffer(uint32_t frameIndex, Handle<SHVkDescriptorPool> descPool); void UpdateMaterialBuffer(uint32_t frameIndex, Handle<SHVkDescriptorPool> descPool);
void UpdateTransformBuffer(uint32_t frameIndex); void UpdateTransformBuffer(uint32_t frameIndex);
void UpdateEIDBuffer(uint32_t frameIndex); void UpdateInstancedIntegerBuffer(uint32_t frameIndex);
void Build(Handle<SHVkLogicalDevice> device, Handle<SHVkDescriptorPool> descPool, uint32_t frameIndex) ; void Build(Handle<SHVkLogicalDevice> device, Handle<SHVkDescriptorPool> descPool, uint32_t frameIndex) ;
void Draw(Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex); void Draw(Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex);
@ -111,7 +112,7 @@ namespace SHADE
// CPU Buffers // CPU Buffers
std::vector<vk::DrawIndexedIndirectCommand> drawData; std::vector<vk::DrawIndexedIndirectCommand> drawData;
std::vector<SHMatrix> transformData; std::vector<SHMatrix> transformData;
std::vector<EntityID> eidData; std::vector<SHInstancedIntegerData> instancedIntegerData;
std::unique_ptr<char> matPropsData; std::unique_ptr<char> matPropsData;
Byte matPropsDataSize = 0; Byte matPropsDataSize = 0;
Byte singleMatPropAlignedSize = 0; Byte singleMatPropAlignedSize = 0;
@ -120,7 +121,7 @@ namespace SHADE
// GPU Buffers // GPU Buffers
TripleBuffer drawDataBuffer; TripleBuffer drawDataBuffer;
TripleBuffer transformDataBuffer; TripleBuffer transformDataBuffer;
TripleBuffer eidBuffer; TripleBuffer instancedIntegerBuffer;
TripleBuffer matPropsBuffer; TripleBuffer matPropsBuffer;
TripleDescSet matPropsDescSet; TripleDescSet matPropsDescSet;

View File

@ -85,7 +85,7 @@ namespace SHADE
{ {
batch.UpdateMaterialBuffer(frameIndex, descPool); batch.UpdateMaterialBuffer(frameIndex, descPool);
batch.UpdateTransformBuffer(frameIndex); batch.UpdateTransformBuffer(frameIndex);
batch.UpdateEIDBuffer(frameIndex); batch.UpdateInstancedIntegerBuffer(frameIndex);
} }
} }

View File

@ -115,7 +115,7 @@ namespace SHADE
defaultVertexInputState.AddBinding(false, false, { SHVertexAttribute(SHAttribFormat::FLOAT_3D) }); // Normals at binding 2 defaultVertexInputState.AddBinding(false, false, { SHVertexAttribute(SHAttribFormat::FLOAT_3D) }); // Normals at binding 2
defaultVertexInputState.AddBinding(false, false, { SHVertexAttribute(SHAttribFormat::FLOAT_3D) }); // Tangents at binding 3 defaultVertexInputState.AddBinding(false, false, { SHVertexAttribute(SHAttribFormat::FLOAT_3D) }); // Tangents at binding 3
defaultVertexInputState.AddBinding(true, true, { SHVertexAttribute(SHAttribFormat::MAT_4D) }); // Transform at binding 4 - 7 (4 slots) defaultVertexInputState.AddBinding(true, true, { SHVertexAttribute(SHAttribFormat::MAT_4D) }); // Transform at binding 4 - 7 (4 slots)
defaultVertexInputState.AddBinding(true, true, { SHVertexAttribute(SHAttribFormat::UINT32_1D) }); // EID at binding 8 defaultVertexInputState.AddBinding(true, true, { SHVertexAttribute(SHAttribFormat::UINT32_2D) }); // Instanced integer data at index 8
} }
void SHGraphicsGlobalData::Init(Handle<SHVkLogicalDevice> logicalDevice) noexcept void SHGraphicsGlobalData::Init(Handle<SHVkLogicalDevice> logicalDevice) noexcept

View File

@ -182,7 +182,7 @@ namespace SHADE
Vertex buffer bindings for the eid buffer. Vertex buffer bindings for the eid buffer.
*/ */
/***************************************************************************/ /***************************************************************************/
static constexpr uint32_t EID = 5; static constexpr uint32_t INTEGER_DATA = 5;
}; };

View File

@ -176,18 +176,21 @@ namespace SHADE
worldRenderGraph->AddResource("Scene Pre-Process", { SH_ATT_DESC_TYPE_FLAGS::COLOR, SH_ATT_DESC_TYPE_FLAGS::INPUT, SH_ATT_DESC_TYPE_FLAGS::STORAGE }, windowDims.first, windowDims.second); worldRenderGraph->AddResource("Scene Pre-Process", { SH_ATT_DESC_TYPE_FLAGS::COLOR, SH_ATT_DESC_TYPE_FLAGS::INPUT, SH_ATT_DESC_TYPE_FLAGS::STORAGE }, windowDims.first, windowDims.second);
worldRenderGraph->AddResource("Scene", { SH_ATT_DESC_TYPE_FLAGS::COLOR, SH_ATT_DESC_TYPE_FLAGS::INPUT, SH_ATT_DESC_TYPE_FLAGS::STORAGE }, windowDims.first, windowDims.second); worldRenderGraph->AddResource("Scene", { SH_ATT_DESC_TYPE_FLAGS::COLOR, SH_ATT_DESC_TYPE_FLAGS::INPUT, SH_ATT_DESC_TYPE_FLAGS::STORAGE }, windowDims.first, windowDims.second);
worldRenderGraph->AddResource("Depth Buffer", { SH_ATT_DESC_TYPE_FLAGS::DEPTH_STENCIL }, windowDims.first, windowDims.second, vk::Format::eD32SfloatS8Uint); worldRenderGraph->AddResource("Depth Buffer", { SH_ATT_DESC_TYPE_FLAGS::DEPTH_STENCIL }, windowDims.first, windowDims.second, vk::Format::eD32SfloatS8Uint);
worldRenderGraph->AddResource("Entity ID", { SH_ATT_DESC_TYPE_FLAGS::COLOR }, windowDims.first, windowDims.second, vk::Format::eR32Uint, 1, vk::ImageUsageFlagBits::eTransferSrc); worldRenderGraph->AddResource("Entity ID", { SH_ATT_DESC_TYPE_FLAGS::COLOR }, windowDims.first, windowDims.second, vk::Format::eR32G32Uint, 1, vk::ImageUsageFlagBits::eTransferSrc);
auto node = worldRenderGraph->AddNode("G-Buffer", { "Entity ID", "Depth Buffer", "Scene", "Scene Pre-Process"}, {}); // no predecessors auto gBufferNode = worldRenderGraph->AddNode("G-Buffer", { "Entity ID", "Depth Buffer", "Scene", "Scene Pre-Process"}, {}); // no predecessors
auto gBufferSubpass = gBufferNode->AddSubpass("G-Buffer Write");
gBufferSubpass->AddColorOutput("Scene Pre-Process");
gBufferSubpass->AddColorOutput("Entity ID");
gBufferSubpass->AddDepthOutput("Depth Buffer", SH_ATT_DESC_TYPE_FLAGS::DEPTH_STENCIL);
//First subpass to write to G-Buffer auto kirschShader = shaderModuleLibrary.GetShaderModule("KirschCs.glsl");
auto gBufferWriteSubpass = node->AddSubpass("G-Buffer Write"); gBufferNode->AddNodeCompute (kirschShader, {"Scene Pre-Process", "Scene"});
gBufferWriteSubpass->AddColorOutput("Scene Pre-Process");
gBufferWriteSubpass->AddColorOutput("Entity ID"); auto dummyNode = worldRenderGraph->AddNode("Dummy Pass", { "Scene" }, {"G-Buffer"}); // no predecessors
gBufferWriteSubpass->AddDepthOutput("Depth Buffer", SH_ATT_DESC_TYPE_FLAGS::DEPTH_STENCIL); auto dummySubpass = dummyNode->AddSubpass("Dummy Subpass");
dummySubpass->AddInput("Scene");
auto greyscale = shaderModuleLibrary.GetShaderModule("KirschCs.glsl");
node->AddNodeCompute (greyscale, {"Scene Pre-Process", "Scene"});
// Generate world render graph // Generate world render graph
worldRenderGraph->Generate(); worldRenderGraph->Generate();
@ -201,7 +204,7 @@ namespace SHADE
auto cubeVS = shaderModuleLibrary.GetShaderModule("TestCubeVs.glsl"); auto cubeVS = shaderModuleLibrary.GetShaderModule("TestCubeVs.glsl");
auto cubeFS = shaderModuleLibrary.GetShaderModule("TestCubeFs.glsl"); auto cubeFS = shaderModuleLibrary.GetShaderModule("TestCubeFs.glsl");
defaultMaterial = AddMaterial(cubeVS, cubeFS, gBufferWriteSubpass); defaultMaterial = AddMaterial(cubeVS, cubeFS, gBufferSubpass);
} }

View File

@ -0,0 +1,12 @@
#pragma once
#include "ECS_Base/SHECSMacros.h"
namespace SHADE
{
struct SHInstancedIntegerData
{
EntityID eid;
uint32_t lightLayer;
};
}

View File

@ -68,7 +68,7 @@ namespace SHADE
{ {
std::vector combinedImageSampler std::vector combinedImageSampler
{ {
std::make_tuple(offscreenRender->GetImageView(), offscreenRenderSampler, vk::ImageLayout::eGeneral), std::make_tuple(offscreenRender->GetImageView(), offscreenRenderSampler, vk::ImageLayout::eShaderReadOnlyOptimal),
}; };
// Register the image view and sampler with the descriptor set. Now whenever rendering to the offscreen image is done, the descriptor set will see the change // Register the image view and sampler with the descriptor set. Now whenever rendering to the offscreen image is done, the descriptor set will see the change

View File

@ -142,6 +142,12 @@ namespace SHADE
case SHAttribFormat::UINT32_1D: case SHAttribFormat::UINT32_1D:
return std::make_tuple(1, 4, vk::Format::eR32Uint); return std::make_tuple(1, 4, vk::Format::eR32Uint);
case SHAttribFormat::UINT32_2D:
return std::make_tuple(1, 8, vk::Format::eR32G32Uint);
case SHAttribFormat::UINT32_3D:
return std::make_tuple(1, 12, vk::Format::eR32G32B32Uint);
case SHAttribFormat::UINT32_4D:
return std::make_tuple(1, 16, vk::Format::eR32G32B32A32Uint);
} }
return std::make_tuple(0, 0, vk::Format::eR32Sfloat); return std::make_tuple(0, 0, vk::Format::eR32Sfloat);
} }

View File

@ -142,6 +142,9 @@ namespace SHADE
attDesc.loadOp = vk::AttachmentLoadOp::eLoad; attDesc.loadOp = vk::AttachmentLoadOp::eLoad;
predAttDesc.storeOp = vk::AttachmentStoreOp::eStore; predAttDesc.storeOp = vk::AttachmentStoreOp::eStore;
attDesc.stencilLoadOp = vk::AttachmentLoadOp::eLoad;
attDesc.stencilStoreOp = vk::AttachmentStoreOp::eStore;
// TODO: Stencil load and store // TODO: Stencil load and store
// When an image is done being used in a renderpass, the image layout will end up being the finalLayout // When an image is done being used in a renderpass, the image layout will end up being the finalLayout

View File

@ -51,6 +51,18 @@ namespace SHADE
case vk::Format::eR32Uint: case vk::Format::eR32Uint:
case vk::Format::eR32Sfloat: case vk::Format::eR32Sfloat:
return 4; return 4;
case vk::Format::eR32G32Sint:
case vk::Format::eR32G32Uint:
case vk::Format::eR32G32Sfloat:
return 8;
case vk::Format::eR32G32B32Sint:
case vk::Format::eR32G32B32Uint:
case vk::Format::eR32G32B32Sfloat:
return 12;
case vk::Format::eR32G32B32A32Sint:
case vk::Format::eR32G32B32A32Uint:
case vk::Format::eR32G32B32A32Sfloat:
return 16;
} }
return 0; return 0;
} }

View File

@ -22,6 +22,9 @@ namespace SHADE
// integer formats // integer formats
UINT32_1D, UINT32_1D,
UINT32_2D,
UINT32_3D,
UINT32_4D,
}; };
struct SHVertexAttribute struct SHVertexAttribute

View File

@ -3,12 +3,13 @@
//#include "ShaderDescriptorDefinitions.glsl" //#include "ShaderDescriptorDefinitions.glsl"
layout(location = 0) in vec3 aVertexPos; layout(location = 0) in vec3 aVertexPos;
layout(location = 1) in vec2 aUV; layout(location = 1) in vec2 aUV;
layout(location = 2) in vec3 aNormal; layout(location = 2) in vec3 aNormal;
layout(location = 3) in vec3 aTangent; layout(location = 3) in vec3 aTangent;
layout(location = 4) in mat4 worldTransform; layout(location = 4) in mat4 worldTransform;
layout(location = 8) in uint eid; layout(location = 8) in uvec2 integerData;
layout(location = 0) out struct layout(location = 0) out struct
@ -36,7 +37,7 @@ void main()
{ {
Out.uv = aUV; Out.uv = aUV;
Out2.materialIndex = gl_InstanceIndex; Out2.materialIndex = gl_InstanceIndex;
Out2.eid = eid; Out2.eid = integerData[0];
gl_Position = cameraData.vpMat * worldTransform * vec4 (aVertexPos, 1.0f); gl_Position = cameraData.vpMat * worldTransform * vec4 (aVertexPos, 1.0f);
Out.vertColor = vec4 (aVertexPos, 1.0f); Out.vertColor = vec4 (aVertexPos, 1.0f);
} }

Binary file not shown.