Refactored Graphics #297

Merged
Xenosas1337 merged 13 commits from SP3-1-Rendering into main 2023-01-01 12:35:09 +08:00
100 changed files with 2354 additions and 1296 deletions

File diff suppressed because it is too large Load Diff

View File

@ -11,13 +11,12 @@ layout(location = 0) out struct
vec4 Color;
} Out;
layout(set = 2, binding = 0) uniform CameraData
layout(set = 1, binding = 0) uniform CameraData
{
vec4 position;
mat4 vpMat;
mat4 viewMat;
mat4 perspectiveMat;
mat4 orthoMat;
mat4 projMat;
} cameraData;
void main()

View File

@ -10,13 +10,12 @@ layout(location = 0) out struct
vec4 vertColor; // location 0
} Out;
layout(set = 2, binding = 0) uniform CameraData
layout(set = 1, binding = 0) uniform CameraData
{
vec4 position;
mat4 vpMat;
mat4 viewMat;
mat4 perspectiveMat;
mat4 orthoMat;
mat4 projMat;
} cameraData;
void main()

View File

@ -17,12 +17,12 @@ struct AmbientLightStruct
};
layout(local_size_x = 16, local_size_y = 16) in;
layout(set = 4, binding = 0, rgba32f) uniform image2D positions;
layout(set = 4, binding = 1, rgba32f) uniform image2D normals;
layout(set = 4, binding = 2, rgba8) uniform image2D albedo;
layout(set = 4, binding = 3, r32ui) uniform uimage2D lightLayerData;
layout(set = 4, binding = 4, r8) uniform image2D ssaoBlurredImage;
layout(set = 4, binding = 5, rgba8) uniform image2D targetImage;
layout(set = 3, binding = 0, rgba32f) uniform image2D positions;
layout(set = 3, binding = 1, rgba32f) uniform image2D normals;
layout(set = 3, binding = 2, rgba8) uniform image2D albedo;
layout(set = 3, binding = 3, r32ui) uniform uimage2D lightLayerData;
layout(set = 3, binding = 4, r8) uniform image2D ssaoBlurredImage;
layout(set = 3, binding = 5, rgba8) uniform image2D targetImage;
layout(set = 1, binding = 0) uniform LightCounts
{

View File

@ -50,8 +50,8 @@
#define NUM_MASKS 8
layout(local_size_x = 16, local_size_y = 16) in;
layout(set = 4, binding = 0, rgba8) uniform image2D inputImage;
layout(set = 4, binding = 1, rgba8) uniform image2D resultImage;
layout(set = 3, binding = 0, rgba8) uniform image2D inputImage;
layout(set = 3, binding = 1, rgba8) uniform image2D resultImage;
const float kirsch[8][3][3] = {
{

View File

@ -28,7 +28,7 @@ layout(location = 3) flat in struct
} In2;
layout (set = 0, binding = 1) uniform sampler2D textures[]; // for textures (global)
layout (std430, set = 3, binding = 0) buffer MaterialProperties // For materials
layout (std430, set = 2, binding = 0) buffer MaterialProperties // For materials
{
MatPropData data[];
} MatProp;

Binary file not shown.

View File

@ -46,8 +46,8 @@
layout(local_size_x = 16, local_size_y = 16) in;
layout(set = 4, binding = 0, rgba8) uniform image2D inputImage;
layout(set = 4, binding = 1, rgba8) uniform image2D targetImage;
layout(set = 3, binding = 0, rgba8) uniform image2D inputImage;
layout(set = 3, binding = 1, rgba8) uniform image2D targetImage;
void main()

Binary file not shown.

View File

@ -5,8 +5,8 @@
#define SHM_WIDTH BLUR_WIDTH + 16 - 1
layout(local_size_x = 16, local_size_y = 16) in;
layout(set = 4, binding = 0, r8) uniform image2D ssaoImage;
layout(set = 4, binding = 1, r8) uniform image2D ssaoBlurImage;
layout(set = 3, binding = 0, r8) uniform image2D ssaoImage;
layout(set = 3, binding = 1, r8) uniform image2D ssaoBlurImage;
float GetSSAOValue(ivec2 uv, ivec2 imageSize)

Binary file not shown.

View File

@ -1,5 +1,7 @@
#version 450
#pragma vscode_glsllint_stage : comp
const uint NUM_SAMPLES = 64;
const uint NUM_ROTATIONS = 16;
const int ROTATION_KERNEL_W = 4;
@ -10,19 +12,19 @@ const float RADIUS = 0.2f;
const float BIAS = 0.0025f;
layout(local_size_x = 16, local_size_y = 16) in;
layout(set = 4, binding = 0, rgba32f) uniform image2D positions;
layout(set = 4, binding = 1, rgba32f) uniform image2D normals;
layout(set = 4, binding = 2, rgba32f) uniform image2D outputImage;
layout(set = 3, binding = 0, rgba32f) uniform image2D positions;
layout(set = 3, binding = 1, rgba32f) uniform image2D normals;
layout(set = 3, binding = 2, rgba32f) uniform image2D outputImage;
// SSAO data
layout(std430, set = 5, binding = 0) buffer SSAOData
layout(std430, set = 4, binding = 0) buffer SSAOData
{
vec4 samples[NUM_SAMPLES];
} ssaoData;
layout (set = 5, binding = 1) uniform sampler2D noiseTexture;
layout (set = 4, binding = 1) uniform sampler2D noiseTexture;
layout(set = 2, binding = 0) uniform CameraData
{

Binary file not shown.

View File

@ -28,7 +28,7 @@ layout(location = 3) flat in struct
} In2;
layout (set = 0, binding = 1) uniform sampler2D textures[]; // for textures (global)
layout (std430, set = 3, binding = 0) buffer MaterialProperties // For materials
layout (std430, set = 2, binding = 0) buffer MaterialProperties // For materials
{
MatPropData data[];
} MatProp;

Binary file not shown.

View File

@ -26,7 +26,7 @@ layout(location = 3) flat in struct
} In2;
layout (set = 0, binding = 1) uniform sampler2D textures[]; // for textures (global)
layout (std430, set = 3, binding = 0) buffer MaterialProperties // For materials
layout (std430, set = 2, binding = 0) buffer MaterialProperties // For materials
{
MatPropData data[];
} MatProp;

View File

@ -34,16 +34,15 @@ layout(location = 3) out struct
} Out2;
layout(set = 2, binding = 0) uniform CameraData
layout(set = 1, binding = 0) uniform CameraData
{
vec4 position;
mat4 vpMat;
mat4 viewMat;
mat4 perspectiveMat;
mat4 orthoMat;
mat4 projMat;
} cameraData;
layout (std430, set = 3, binding = 0) buffer MaterialProperties // For materials
layout (std430, set = 2, binding = 0) buffer MaterialProperties // For materials
{
MatPropData data[];
} MatProp;

View File

@ -29,13 +29,12 @@ layout(location = 3) out struct
} Out2;
layout(set = 2, binding = 0) uniform CameraData
layout(set = 1, binding = 0) uniform CameraData
{
vec4 position;
mat4 vpMat;
mat4 viewMat;
mat4 perspectiveMat;
mat4 orthoMat;
mat4 projMat;
} cameraData;
void main()

Binary file not shown.

View File

@ -28,7 +28,7 @@ layout(location = 3) flat in struct
layout(set = 4, binding = 0) uniform sampler2D fontBitmap;
layout(set = 2, binding = 0) uniform sampler2D fontBitmap;
layout(location = 0) out vec4 color;
layout(location = 1) out uint outEntityID;

Binary file not shown.

View File

@ -25,13 +25,12 @@ layout(location = 3) out struct
} Out2;
// Camera data
layout(set = 2, binding = 0) uniform CameraData
layout(set = 1, binding = 0) uniform CameraData
{
vec4 position;
mat4 vpMat;
mat4 viewMat;
mat4 perspectiveMat;
mat4 orthoMat;
mat4 projMat;
} cameraData;
// push constants
@ -44,7 +43,7 @@ layout(std140, push_constant) uniform TestPushConstant
} testPushConstant;
// Descriptor sets
layout(std430, set = 4, binding = 1) buffer GlyphTransforms
layout(std430, set = 2, binding = 1) buffer GlyphTransforms
{
mat4 matrices[];
} glyphTransforms;
@ -96,6 +95,6 @@ void main()
Out2.textColor = testPushConstant.textColor;
// transform the vertex position to font space
gl_Position = cameraData.orthoMat * localModel * vec4(vertexPos, 1.0f);
gl_Position = cameraData.projMat * localModel * vec4(vertexPos, 1.0f);
// gl_Position = vec4(vertexPos, 1.0f);
}

Binary file not shown.

View File

@ -3,7 +3,7 @@
#extension GL_ARB_shading_language_420pack : enable
#extension GL_EXT_nonuniform_qualifier : require
layout (input_attachment_index = 0, set = 4, binding = 0) uniform subpassInput sceneTexture;
layout (input_attachment_index = 0, set = 0, binding = 0) uniform subpassInput sceneTexture;
layout(location = 0) out vec4 fragColor;

View File

@ -28,7 +28,7 @@ layout(location = 3) flat in struct
} In2;
layout (set = 0, binding = 1) uniform sampler2D textures[]; // for textures (global)
layout (std430, set = 3, binding = 0) buffer MaterialProperties // For materials
layout (std430, set = 2, binding = 0) buffer MaterialProperties // For materials
{
MatPropData data[];
} MatProp;

Binary file not shown.

View File

@ -29,13 +29,12 @@ layout(location = 3) out struct
} Out2;
layout(set = 2, binding = 0) uniform CameraData
layout(set = 1, binding = 0) uniform CameraData
{
vec4 position;
mat4 vpMat;
mat4 viewMat;
mat4 perspectiveMat;
mat4 orthoMat;
mat4 projMat;
} cameraData;
void main()
@ -60,7 +59,7 @@ void main()
Out.normal.rgb = normalize (Out.normal.rgb);
// clip space for rendering
gl_Position = cameraData.orthoMat * worldTransform * vec4 (aVertexPos, 1.0f);
gl_Position = cameraData.projMat * worldTransform * vec4 (aVertexPos, 1.0f);
gl_Position.z += 0.1f; // HAX
// gl_Position = vec4 (aVertexPos, 1.0f);
}

Binary file not shown.

View File

@ -226,7 +226,7 @@ namespace SHADE
const SHMatrix& SHCameraComponent::GetPerspectiveMatrix() const noexcept
{
return orthoProjMatrix;
return perspProjMatrix;
}
//void SHCameraComponent::SetMainCamera(size_t directorCameraIndex) noexcept

View File

@ -196,10 +196,12 @@ namespace SHADE
if (!fragShader)
return;
auto const& mappings = SHGraphicsPredefinedData::GetMappings(SHGraphicsPredefinedData::SystemType::BATCHING);
// Get interface for the shader combination
auto interface = fragShader->GetReflectedData().GetDescriptorBindingInfo().GetShaderBlockInterface
(
SHGraphicsConstants::DescriptorSetIndex::PER_INSTANCE,
mappings.at(SHPredefinedDescriptorTypes::MATERIALS),
SHGraphicsConstants::DescriptorSetBindings::BATCHED_PER_INST_DATA
);
if (!interface)

View File

@ -501,10 +501,7 @@ namespace SHADE
imguiCommandBuffer = imguiCommandPool->RequestCommandBuffer(SH_CMD_BUFFER_TYPE::PRIMARY);
//auto const& renderers = gfxSystem->GetDefaultViewport()->GetRenderers();
auto const& renderers = gfxSystem->GetEditorViewport()->GetRenderers();
SHASSERT(!renderers.empty(), "No Renderers available")
auto renderGraph = renderers[SHGraphicsConstants::RenderGraphIndices::EDITOR]->GetRenderGraph();
auto renderGraph = gfxSystem->GetRenderGraph();
auto renderPass = renderGraph->GetNode("ImGui Node")->GetRenderpass();
if(ImGui_ImplVulkan_Init(&initInfo, renderPass->GetVkRenderpass()) == false)
@ -524,7 +521,7 @@ namespace SHADE
ImGui_ImplVulkan_DestroyFontUploadObjects();
renderGraph->GetNode("ImGui Node")->GetSubpass("ImGui Draw")->AddExteriorDrawCalls([](Handle<SHVkCommandBuffer>& cmd, uint32_t frameIndex)
renderGraph->GetNode("ImGui Node")->GetSubpass("ImGui Draw")->AddExteriorDrawCalls([](Handle<SHVkCommandBuffer> cmd, Handle<SHRenderer> renderer, uint32_t frameIndex)
{
cmd->BeginLabeledSegment("ImGui Draw");
ImGui_ImplVulkan_RenderDrawData(ImGui::GetDrawData(), cmd->GetVkCommandBuffer());

View File

@ -22,4 +22,5 @@ constexpr SHEventIdentifier SH_SCENE_INIT_PRE { 13 };
constexpr SHEventIdentifier SH_SCENE_INIT_POST { 14 };
constexpr SHEventIdentifier SH_SCENE_EXIT_PRE { 15 };
constexpr SHEventIdentifier SH_SCENE_EXIT_POST { 16 };
constexpr SHEventIdentifier SH_GRAPHICS_LIGHT_ENABLE_SHADOW_EVENT { 17 };

View File

@ -367,7 +367,7 @@ namespace SHADE
}
}
void SHVkCommandBuffer::BindDescriptorSet(Handle<SHVkDescriptorSetGroup> descSetGroup, SH_PIPELINE_TYPE bindPoint, uint32_t firstSet, std::span<uint32_t> dynamicOffsets)
void SHVkCommandBuffer::BindDescriptorSet(Handle<SHVkDescriptorSetGroup> descSetGroup, SH_PIPELINE_TYPE bindPoint, uint32_t firstSet, std::span<uint32_t> const dynamicOffsets)
{
uint32_t bindPointIndex = static_cast<uint32_t>(bindPoint);
vkCommandBuffer.bindDescriptorSets(SHVkUtil::GetPipelineBindPointFromType(bindPoint), bindPointData[bindPointIndex].boundPipelineLayoutHdl->GetVkPipelineLayout(), firstSet, descSetGroup->GetVkHandle(), dynamicOffsets);

View File

@ -125,7 +125,7 @@ namespace SHADE
void BindPipeline (Handle<SHVkPipeline> const& pipelineHdl) noexcept;
void BindVertexBuffer (uint32_t bindingPoint, Handle<SHVkBuffer> const& buffer, vk::DeviceSize offset) noexcept;
void BindIndexBuffer (Handle<SHVkBuffer> const& buffer, uint32_t startingIndex) const noexcept;
void BindDescriptorSet (Handle<SHVkDescriptorSetGroup> descSetGroup, SH_PIPELINE_TYPE bindPoint, uint32_t firstSet, std::span<uint32_t> dynamicOffsets);
void BindDescriptorSet (Handle<SHVkDescriptorSetGroup> descSetGroup, SH_PIPELINE_TYPE bindPoint, uint32_t firstSet, std::span<uint32_t> const dynamicOffsets);
// Draw Commands
void DrawArrays (uint32_t vertexCount, uint32_t instanceCount, uint32_t firstVertex, uint32_t firstInstance) const noexcept;

View File

@ -53,7 +53,6 @@ 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
@ -87,7 +86,7 @@ namespace SHADE
for (auto& binding : bindings)
{
BindingAndSetHash writeHash = binding.BindPoint;
writeHash |= static_cast<uint64_t>(layouts[i]->GetSetIndex()) << 32;
writeHash |= static_cast<uint64_t>(i) << 32;
// new write for the binding
updater.writeInfos.emplace_back();
@ -208,16 +207,13 @@ namespace SHADE
// Get binding + set hash
BindingAndSetHash bsHash = SHVkUtil::GenBindingSetHash(set, binding);
// to index a set
uint32_t setIndex = setIndexing[set];
// 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.descriptorType = layoutsUsed[set]->GetBindings()[binding].Type;
writeDescSet.dstArrayElement = 0;
writeDescSet.dstSet = descSets[setIndex];
writeDescSet.dstSet = descSets[set];
writeDescSet.dstBinding = binding;
writeDescSet.pImageInfo = updater.writeInfos[writeInfoIndex].descImageInfos.data();
@ -233,16 +229,13 @@ namespace SHADE
// Get binding + set hash
BindingAndSetHash bsHash = SHVkUtil::GenBindingSetHash(set, binding);
// to index a set
uint32_t setIndex = setIndexing[set];
// 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.descriptorType = layoutsUsed[set]->GetBindings()[binding].Type;
writeDescSet.dstArrayElement = 0;
writeDescSet.dstSet = descSets[setIndex];
writeDescSet.dstSet = descSets[set];
writeDescSet.dstBinding = binding;
writeDescSet.pBufferInfo = updater.writeInfos[writeInfoIndex].descBufferInfos.data();

View File

@ -21,7 +21,6 @@ namespace SHADE
class SHVkImageView;
class SHVkBuffer;
/*---------------------------------------------------------------------------------*/
/* Type Definitions */
/*---------------------------------------------------------------------------------*/
@ -91,10 +90,10 @@ namespace SHADE
//! Descriptor pool to allocate descriptor sets
Handle<SHVkDescriptorPool> 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<SetIndex, uint32_t> setIndexing;
////! 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<SetIndex, uint32_t> setIndexing;
//! Descriptor sets
std::vector<vk::DescriptorSet> descSets;

View File

@ -8,10 +8,9 @@ namespace SHADE
/*---------------------------------------------------------------------------------*/
/* Constructor/Destructor */
/*---------------------------------------------------------------------------------*/
SHVkDescriptorSetLayout::SHVkDescriptorSetLayout(Handle<SHVkLogicalDevice> device, SetIndex set, const std::vector<Binding>& bindings, bool genImmutableSamplers/* = false*/)
: device { device }
, layoutDesc { bindings }
, setIndex {set}
SHVkDescriptorSetLayout::SHVkDescriptorSetLayout(Handle<SHVkLogicalDevice> device, const std::vector<Binding>& bindings, bool genImmutableSamplers/* = false*/)
: device{ device }
, layoutDesc{ bindings }
, immutableSampler{}
{
// Check if auto-binding point calculation configuration is valid
@ -93,10 +92,9 @@ namespace SHADE
}
SHVkDescriptorSetLayout::SHVkDescriptorSetLayout(SHVkDescriptorSetLayout&& rhs) noexcept
: device {rhs.device}
, setLayout {rhs.setLayout}
, layoutDesc{std::move (rhs.layoutDesc)}
, setIndex{ rhs.setIndex }
: device{ rhs.device }
, setLayout{ rhs.setLayout }
, layoutDesc{ std::move(rhs.layoutDesc) }
, immutableSampler{ rhs.immutableSampler }
{
rhs.setLayout = VK_NULL_HANDLE;
@ -114,11 +112,6 @@ namespace SHADE
return layoutDesc;
}
SetIndex SHVkDescriptorSetLayout::GetSetIndex(void) const noexcept
{
return setIndex;
}
uint32_t SHVkDescriptorSetLayout::GetNumDynamicOffsetsRequired(void) const noexcept
{
uint32_t numDynamicBindings = 0;
@ -139,7 +132,6 @@ namespace SHADE
device = rhs.device;
setLayout = rhs.setLayout;
layoutDesc = std::move(rhs.layoutDesc);
setIndex = rhs.setIndex;
immutableSampler = rhs.immutableSampler;
rhs.setLayout = VK_NULL_HANDLE;

View File

@ -75,7 +75,7 @@ namespace SHADE
/// </summary>
/// <param name="device"></param>
/// <param name="bindings"></param>
SHVkDescriptorSetLayout(Handle<SHVkLogicalDevice> device, SetIndex setIndex, const std::vector<Binding>& bindings, bool genImmutableSamplers = false);
SHVkDescriptorSetLayout(Handle<SHVkLogicalDevice> device, const std::vector<Binding>& bindings, bool genImmutableSamplers = false);
SHVkDescriptorSetLayout(const SHVkDescriptorSetLayout&) = delete;
SHVkDescriptorSetLayout(SHVkDescriptorSetLayout&& rhs) noexcept;
/// <summary>
@ -97,9 +97,8 @@ namespace SHADE
/// </summary>
/// <returns>Handle to the Vulkan Descriptor Set Layout handle.</returns>
inline const vk::DescriptorSetLayout& GetVkHandle() const { return setLayout; }
std::vector<Binding> const& GetBindings (void) const noexcept;
SetIndex GetSetIndex (void) const noexcept;
uint32_t GetNumDynamicOffsetsRequired (void) const noexcept;
std::vector<Binding> const& GetBindings(void) const noexcept;
uint32_t GetNumDynamicOffsetsRequired(void) const noexcept;
private:
/*-----------------------------------------------------------------------------*/
@ -108,7 +107,6 @@ namespace SHADE
Handle<SHVkLogicalDevice> device;
vk::DescriptorSetLayout setLayout;
std::vector<Binding> layoutDesc; // Stores description of the layout
SetIndex setIndex; // Index of the set
Handle<SHVkSampler> immutableSampler;
};
}

View File

@ -561,9 +561,9 @@ namespace SHADE
}
Handle<SHVkDescriptorSetLayout> SHVkLogicalDevice::CreateDescriptorSetLayout(SetIndex setIndex, std::vector<SHVkDescriptorSetLayout::Binding> const& bindings, bool genImmutableSamplers/* = false*/) noexcept
Handle<SHVkDescriptorSetLayout> SHVkLogicalDevice::CreateDescriptorSetLayout(std::vector<SHVkDescriptorSetLayout::Binding> const& bindings, bool genImmutableSamplers/* = false*/) noexcept
{
return SHVkInstance::GetResourceManager().Create <SHVkDescriptorSetLayout>(GetHandle(), setIndex, bindings, genImmutableSamplers);
return SHVkInstance::GetResourceManager().Create <SHVkDescriptorSetLayout>(GetHandle(), bindings, genImmutableSamplers);
}
Handle<SHVkDescriptorPool> SHVkLogicalDevice::CreateDescriptorPools(const SHVkDescriptorPool::Config& config /*= {}*/) noexcept

View File

@ -190,7 +190,7 @@ namespace SHADE
Handle<SHVkRenderpass> CreateRenderpass (std::span<vk::AttachmentDescription> const vkDescriptions, std::vector<SHVkSubpassParams> const& subpasses) noexcept;
Handle<SHVkRenderpass> CreateRenderpass (std::span<vk::AttachmentDescription> const vkDescriptions, std::span<vk::SubpassDescription> const spDescs, std::span<vk::SubpassDependency> const spDeps) noexcept;
Handle<SHVkFramebuffer> CreateFramebuffer (Handle<SHVkRenderpass> const& renderpassHdl, std::vector<Handle<SHVkImageView>> const& attachments, uint32_t inWidth, uint32_t inHeight) noexcept;
Handle<SHVkDescriptorSetLayout> CreateDescriptorSetLayout (SetIndex setIndex, std::vector<SHVkDescriptorSetLayout::Binding> const& bindings, bool genImmutableSamplers = false) noexcept;
Handle<SHVkDescriptorSetLayout> CreateDescriptorSetLayout (std::vector<SHVkDescriptorSetLayout::Binding> const& bindings, bool genImmutableSamplers = false) noexcept;
Handle<SHVkDescriptorPool> CreateDescriptorPools (const SHVkDescriptorPool::Config& config = {}) noexcept;
Handle<SHVkDescriptorSetGroup> CreateDescriptorSetGroup(Handle<SHVkDescriptorPool> pool,
std::vector<Handle<SHVkDescriptorSetLayout>> const& layouts,

View File

@ -0,0 +1,14 @@
#pragma once
#include <string>
#include <initializer_list>
#include "ECS_Base/SHECSMacros.h"
namespace SHADE
{
struct SHLightEnableShadowEvent
{
//! We need to get the light component and initialize the relevant variables.
EntityID lightEntity;
};
}

View File

@ -25,7 +25,7 @@ of DigiPen Institute of Technology is prohibited.
#include "Graphics/Descriptors/SHVkDescriptorSetGroup.h"
#include "ECS_Base/Managers/SHComponentManager.h"
#include "Math/Transform/SHTransformComponent.h"
#include "Graphics/MiddleEnd/GlobalData/SHGraphicsGlobalData.h"
#include "Graphics/MiddleEnd/GlobalData/SHGraphicsPredefinedData.h"
#include "Graphics/Descriptors/SHVkDescriptorPool.h"
#include "Scene/SHSceneManager.h"
#include "UI/SHUIComponent.h"
@ -411,11 +411,12 @@ namespace SHADE
instancedIntegerData.reserve(numTotalElements);
instancedIntegerData.clear();
auto const& descMappings = SHGraphicsPredefinedData::GetMappings(SHGraphicsPredefinedData::SystemType::BATCHING);
// - Material Properties Data
const Handle<SHShaderBlockInterface> SHADER_INFO = pipeline->GetPipelineLayout()->GetShaderBlockInterface
(
SHGraphicsConstants::DescriptorSetIndex::PER_INSTANCE,
descMappings.at(SHPredefinedDescriptorTypes::MATERIALS),
SHGraphicsConstants::DescriptorSetBindings::BATCHED_PER_INST_DATA,
vk::ShaderStageFlagBits::eFragment
);
@ -570,11 +571,14 @@ namespace SHADE
cmdBuffer->BindVertexBuffer(SHGraphicsConstants::VertexBufferBindings::INTEGER_DATA, instancedIntegerBuffer[frameIndex], 0);
if (matPropsDescSet[frameIndex])
{
auto const& descMappings = SHGraphicsPredefinedData::GetMappings(SHGraphicsPredefinedData::SystemType::BATCHING);
cmdBuffer->BindDescriptorSet
(
matPropsDescSet[frameIndex],
SH_PIPELINE_TYPE::GRAPHICS,
SHGraphicsConstants::DescriptorSetIndex::PER_INSTANCE,
//SHGraphicsConstants::DescriptorSetIndex::PER_INSTANCE,
descMappings.at(SHPredefinedDescriptorTypes::MATERIALS),
dynamicOffset
);
}
@ -582,6 +586,31 @@ namespace SHADE
cmdBuffer->EndLabeledSegment();
}
/*-----------------------------------------------------------------------------------*/
/* SHBatch - Getter Functions */
/*-----------------------------------------------------------------------------------*/
Handle<SHVkBuffer> SHBatch::GetTransformBuffer(uint32_t frameIndex) const noexcept
{
if (frameIndex >= transformDataBuffer.size())
{
SHLOG_WARNING("[SHBatch] Attempted to retrieve a transform buffer of an invalid index.");
return {};
}
return transformDataBuffer[frameIndex];
}
Handle<SHVkBuffer> SHBatch::GetMDIBuffer(uint32_t frameIndex) const noexcept
{
if (frameIndex >= drawDataBuffer.size())
{
SHLOG_WARNING("[SHBatch] Attempted to retrieve a MDI draw data buffer of an invalid index.");
return {};
}
return drawDataBuffer[frameIndex];
}
/*---------------------------------------------------------------------------------*/
/* SHBatch - Helper Functions */
/*---------------------------------------------------------------------------------*/
@ -607,7 +636,7 @@ namespace SHADE
{
matPropsDescSet[frameIndex] = descPool->Allocate
(
{ SHGraphicsGlobalData::GetDescSetLayouts()[SHGraphicsConstants::DescriptorSetIndex::PER_INSTANCE] },
SHGraphicsPredefinedData::GetPredefinedDescSetLayouts(SHGraphicsPredefinedData::PredefinedDescSetLayoutTypes::MATERIALS),
{ 0 }
);
#ifdef _DEBUG
@ -618,17 +647,20 @@ namespace SHADE
}
#endif
}
static constexpr uint32_t MATERIAL_DESC_SET_INDEX = 0;
std::array<Handle<SHVkBuffer>, 1> bufferList = { matPropsBuffer[frameIndex] };
matPropsDescSet[frameIndex]->ModifyWriteDescBuffer
(
SHGraphicsConstants::DescriptorSetIndex::PER_INSTANCE,
MATERIAL_DESC_SET_INDEX,
SHGraphicsConstants::DescriptorSetBindings::BATCHED_PER_INST_DATA,
bufferList,
0, static_cast<uint32_t>(matPropsDataSize)
);
matPropsDescSet[frameIndex]->UpdateDescriptorSetBuffer
(
SHGraphicsConstants::DescriptorSetIndex::PER_INSTANCE,
MATERIAL_DESC_SET_INDEX,
SHGraphicsConstants::DescriptorSetBindings::BATCHED_PER_INST_DATA
);
}

View File

@ -94,6 +94,8 @@ namespace SHADE
/*-----------------------------------------------------------------------------*/
Handle<SHVkPipeline> GetPipeline() const noexcept { return pipeline; };
bool IsEmpty() const noexcept { return subBatches.empty(); }
Handle<SHVkBuffer> GetTransformBuffer(uint32_t frameIndex) const noexcept;
Handle<SHVkBuffer> GetMDIBuffer(uint32_t frameIndex) const noexcept;
private:
/*-----------------------------------------------------------------------------*/

View File

@ -63,6 +63,7 @@ namespace SHADE
/* Getter Functions */
/*-----------------------------------------------------------------------------*/
Handle<SHSubpass> GetSubpass() const noexcept { return subpass; };
const std::vector<SHBatch>& GetBatches() const noexcept { return batches; }
private:
/*-----------------------------------------------------------------------------*/

View File

@ -0,0 +1,17 @@
#include "SHpch.h"
#include "SHDescriptorMappings.h"
namespace SHADE
{
void SHDescriptorMappings::AddMappings(std::initializer_list<std::pair<SHPredefinedDescriptorTypes, uint32_t>> inMappings) noexcept
{
for (auto& map : inMappings)
mappings.emplace(map);
}
SHDescriptorMappings::MapType const& SHDescriptorMappings::GetMappings(void) const noexcept
{
return mappings;
}
}

View File

@ -0,0 +1,29 @@
#pragma once
#include <unordered_map>
#include "Graphics/MiddleEnd/GlobalData/SHPredefinedDescriptorTypes.h"
namespace SHADE
{
class SHDescriptorMappings
{
public:
using MapType = std::unordered_map<SHPredefinedDescriptorTypes, uint32_t>;
private:
//! To map an enum value from descriptor set types to set indices
MapType mappings;
public:
/*-----------------------------------------------------------------------*/
/* PUBLIC MEMBER FUNCTIONS */
/*-----------------------------------------------------------------------*/
void AddMappings (std::initializer_list<std::pair<SHPredefinedDescriptorTypes, uint32_t>> inMappings) noexcept;
/*-----------------------------------------------------------------------*/
/* SETTERS AND GETTERS */
/*-----------------------------------------------------------------------*/
MapType const& GetMappings (void) const noexcept;
};
}

View File

@ -0,0 +1,51 @@
#include "SHpch.h"
#include "SHGlobalDescriptorSets.h"
#include "Graphics/MiddleEnd/Lights/SHLightingSubSystem.h"
#include "Graphics/Commands/SHVkCommandBuffer.h"
namespace SHADE
{
Handle<SHVkDescriptorSetGroup> SHGlobalDescriptorSets::staticGlobalDataDescriptorSet;
Handle<SHLightingSubSystem> SHGlobalDescriptorSets::lightingSubSystem;
//void SHGlobalDescriptorSets::BindLightingData(Handle<SHVkCommandBuffer> cmdBuffer, SH_PIPELINE_TYPE pipelineType, uint32_t firstSet) noexcept
//{
// // Bind descriptor set for light data
// cmdBuffer->BindDescriptorSet(SHGlobalDescriptorSets::GetLightDescriptorSet(), SH_PIPELINE_TYPE::COMPUTE, descMappings[SHGraphicsPredefinedData::PredefinedDescSetLayoutTypes::LIGHTS], const std::span{ TEX_DYNAMIC_OFFSET.data(), 1 });
//}
void SHGlobalDescriptorSets::BindLightingData(Handle<SHVkCommandBuffer> cmdBuffer, SH_PIPELINE_TYPE pipelineType, uint32_t setIndex, uint32_t frameIndex) noexcept
{
lightingSubSystem->BindDescSet(cmdBuffer, setIndex, frameIndex);
}
void SHGlobalDescriptorSets::BindStaticGlobalData(Handle<SHVkCommandBuffer> cmdBuffer, SH_PIPELINE_TYPE pipelineType, uint32_t setIndex) noexcept
{
// Bind descriptor set for static global data
static std::array<uint32_t, 1> TEX_DYNAMIC_OFFSET{ 0 };
cmdBuffer->BindDescriptorSet(staticGlobalDataDescriptorSet, pipelineType, setIndex, std::span{ TEX_DYNAMIC_OFFSET.data(), 1 });
}
/***************************************************************************/
/*!
\brief
Sets the Handle to descriptor set for lights.
\param lightDescSet
The handle to set to.
*/
/***************************************************************************/
void SHGlobalDescriptorSets::SetLightingSubSystem(Handle<SHLightingSubSystem> system) noexcept
{
lightingSubSystem = system;
}
void SHGlobalDescriptorSets::SetStaticGlobalDataDescriptorSet(Handle<SHVkDescriptorSetGroup> staticGlobalDescSet) noexcept
{
staticGlobalDataDescriptorSet = staticGlobalDescSet;
}
}

View File

@ -0,0 +1,36 @@
#pragma once
#include "Graphics/Descriptors/SHVkDescriptorSetGroup.h"
#include "Resource/SHHandle.h"
#include "Graphics/Pipeline/SHPipelineType.h"
namespace SHADE
{
class SHLightingSubSystem;
class SHVkCommandBuffer;
// This class is mainly for descriptors that are truly global, meaning they only come from 1 place and they are shared between many systems
class SHGlobalDescriptorSets
{
private:
//! Static global descriptor sets for miscellaneous data and textures
static Handle<SHVkDescriptorSetGroup> staticGlobalDataDescriptorSet;
//! Lighting sub system required to get information to bind descriptor sets for light data
static Handle<SHLightingSubSystem> lightingSubSystem;
public:
/*-----------------------------------------------------------------------*/
/* PUBLIC MEMBER FUNCTIONS */
/*-----------------------------------------------------------------------*/
static void BindLightingData (Handle<SHVkCommandBuffer> cmdBuffer, SH_PIPELINE_TYPE pipelineType, uint32_t setIndex, uint32_t frameIndex) noexcept;
static void BindStaticGlobalData (Handle<SHVkCommandBuffer> cmdBuffer, SH_PIPELINE_TYPE pipelineType, uint32_t setIndex) noexcept;
/*-----------------------------------------------------------------------*/
/* SETTERS AND GETTERS */
/*-----------------------------------------------------------------------*/
static void SetLightingSubSystem (Handle<SHLightingSubSystem> system) noexcept;
static void SetStaticGlobalDataDescriptorSet (Handle<SHVkDescriptorSetGroup> staticGlobalDescSet) noexcept;
};
}

View File

@ -1,143 +0,0 @@
#include "SHpch.h"
#include "SHGraphicsGlobalData.h"
#include "Graphics/Devices/SHVkLogicalDevice.h"
#include "Graphics/Pipeline/SHPipelineState.h"
#include "Graphics/Pipeline/SHVkPipelineLayout.h"
#include "Graphics/Descriptors/SHVkDescriptorSetLayout.h"
#include "Graphics/MiddleEnd/Lights/SHLightData.h"
#include "Tools/Utilities/SHUtilities.h"
namespace SHADE
{
/*-----------------------------------------------------------------------------------*/
/* Static Definitions */
/*-----------------------------------------------------------------------------------*/
std::vector<Handle<SHVkDescriptorSetLayout>> SHGraphicsGlobalData::globalDescSetLayouts;
SHVertexInputState SHGraphicsGlobalData::defaultVertexInputState;
Handle<SHVkPipelineLayout> SHGraphicsGlobalData::dummyPipelineLayout;
void SHGraphicsGlobalData::InitHighFrequencyGlobalData(void) noexcept
{
}
/*-----------------------------------------------------------------------------------*/
/* Function Definitions */
/*-----------------------------------------------------------------------------------*/
void SHGraphicsGlobalData::InitDescSetLayouts(Handle<SHVkLogicalDevice> logicalDevice) noexcept
{
SHVkDescriptorSetLayout::Binding genericDataBinding
{
.Type = vk::DescriptorType::eUniformBufferDynamic,
.Stage = vk::ShaderStageFlagBits::eVertex | vk::ShaderStageFlagBits::eFragment | vk::ShaderStageFlagBits::eCompute,
.BindPoint = SHGraphicsConstants::DescriptorSetBindings::GENERIC_DATA,
.DescriptorCount = 1,
};
SHVkDescriptorSetLayout::Binding texturesBinding
{
.Type = vk::DescriptorType::eCombinedImageSampler,
.Stage = vk::ShaderStageFlagBits::eVertex | vk::ShaderStageFlagBits::eFragment | vk::ShaderStageFlagBits::eCompute,
.BindPoint = SHGraphicsConstants::DescriptorSetBindings::IMAGE_AND_SAMPLERS_DATA,
.DescriptorCount = 2000, // we can have up to 2000 textures for now
.flags = vk::DescriptorBindingFlagBits::eVariableDescriptorCount,
};
// For global data (generic data and textures)
Handle<SHVkDescriptorSetLayout> staticGlobalLayout = logicalDevice->CreateDescriptorSetLayout(SHGraphicsConstants::DescriptorSetIndex::STATIC_GLOBALS, { genericDataBinding, texturesBinding });
SET_VK_OBJ_NAME(logicalDevice, vk::ObjectType::eDescriptorSetLayout, staticGlobalLayout->GetVkHandle(), "[Descriptor Set Layout] Static Globals");
std::vector<SHVkDescriptorSetLayout::Binding> lightBindings{};
// This is the binding we use to count the lights (binding 0)
lightBindings.push_back(SHVkDescriptorSetLayout::Binding
{
.Type = vk::DescriptorType::eUniformBufferDynamic,
.Stage = vk::ShaderStageFlagBits::eCompute,
.BindPoint = 0,
.DescriptorCount = 1,
});
for (uint32_t i = 1; i <= SHUtilities::ConvertEnum(SH_LIGHT_TYPE::NUM_TYPES); ++i)
{
lightBindings.push_back (SHVkDescriptorSetLayout::Binding
{
.Type = vk::DescriptorType::eStorageBufferDynamic,
.Stage = vk::ShaderStageFlagBits::eCompute,
.BindPoint = i,
.DescriptorCount = 1,
});
}
// For Dynamic global data (lights)
Handle<SHVkDescriptorSetLayout> dynamicGlobalLayout = logicalDevice->CreateDescriptorSetLayout(SHGraphicsConstants::DescriptorSetIndex::DYNAMIC_GLOBALS, lightBindings);
SET_VK_OBJ_NAME(logicalDevice, vk::ObjectType::eDescriptorSetLayout, dynamicGlobalLayout->GetVkHandle(), "[Descriptor Set Layout] Dynamic Globals");
// For High frequency global data (camera)
SHVkDescriptorSetLayout::Binding cameraDataBinding
{
.Type = vk::DescriptorType::eUniformBufferDynamic,
.Stage = vk::ShaderStageFlagBits::eVertex | vk::ShaderStageFlagBits::eCompute,
.BindPoint = SHGraphicsConstants::DescriptorSetBindings::CAMERA_DATA,
.DescriptorCount = 1,
};
Handle<SHVkDescriptorSetLayout> cameraDataGlobalLayout = logicalDevice->CreateDescriptorSetLayout(SHGraphicsConstants::DescriptorSetIndex::HIGH_FREQUENCY_GLOBALS, { cameraDataBinding });
SET_VK_OBJ_NAME(logicalDevice, vk::ObjectType::eDescriptorSetLayout, cameraDataGlobalLayout->GetVkHandle(), "[Descriptor Set Layout] High Frequency Globals");
// For per instance data (transforms, materials, etc.)
SHVkDescriptorSetLayout::Binding materialDataBinding
{
.Type = vk::DescriptorType::eStorageBufferDynamic,
.Stage = vk::ShaderStageFlagBits::eFragment | vk::ShaderStageFlagBits::eVertex,
.BindPoint = SHGraphicsConstants::DescriptorSetBindings::BATCHED_PER_INST_DATA,
.DescriptorCount = 1,
};
Handle<SHVkDescriptorSetLayout> materialDataPerInstanceLayout = logicalDevice->CreateDescriptorSetLayout(SHGraphicsConstants::DescriptorSetIndex::PER_INSTANCE, { materialDataBinding });
SET_VK_OBJ_NAME(logicalDevice, vk::ObjectType::eDescriptorSetLayout, materialDataPerInstanceLayout->GetVkHandle(), "[Descriptor Set Layout] Material Globals");
globalDescSetLayouts.push_back(staticGlobalLayout);
globalDescSetLayouts.push_back(dynamicGlobalLayout);
globalDescSetLayouts.push_back(cameraDataGlobalLayout);
globalDescSetLayouts.push_back(materialDataPerInstanceLayout);
dummyPipelineLayout = logicalDevice->CreatePipelineLayoutDummy(SHPipelineLayoutParamsDummy{globalDescSetLayouts});
}
void SHGraphicsGlobalData::InitDefaultVertexInputState(void) noexcept
{
defaultVertexInputState.AddBinding(false, false, { SHVertexAttribute(SHAttribFormat::FLOAT_3D) }); // positions at binding 0
defaultVertexInputState.AddBinding(false, false, { SHVertexAttribute(SHAttribFormat::FLOAT_2D) }); // UVs at binding 1
defaultVertexInputState.AddBinding(false, false, { SHVertexAttribute(SHAttribFormat::FLOAT_3D) }); // Normals at binding 2
defaultVertexInputState.AddBinding(false, false, { SHVertexAttribute(SHAttribFormat::FLOAT_3D) }); // Tangents at binding 3
defaultVertexInputState.AddBinding(true, true, { SHVertexAttribute(SHAttribFormat::MAT_4D) }); // Transform at binding 4 - 7 (4 slots)
defaultVertexInputState.AddBinding(true, true, { SHVertexAttribute(SHAttribFormat::UINT32_2D) }); // Instanced integer data at index 8
}
void SHGraphicsGlobalData::Init(Handle<SHVkLogicalDevice> logicalDevice) noexcept
{
InitDescSetLayouts(logicalDevice);
InitDefaultVertexInputState();
}
std::vector<Handle<SHVkDescriptorSetLayout>> const& SHGraphicsGlobalData::GetDescSetLayouts(void) noexcept
{
return globalDescSetLayouts;
}
SHVertexInputState const& SHGraphicsGlobalData::GetDefaultViState(void) noexcept
{
return defaultVertexInputState;
}
Handle<SHVkPipelineLayout> SHGraphicsGlobalData::GetDummyPipelineLayout(void) noexcept
{
return dummyPipelineLayout;
}
}

View File

@ -1,49 +0,0 @@
#pragma once
#include "SH_API.h"
#include "Graphics/Pipeline/SHPipelineState.h"
#include "Graphics/MiddleEnd/Interface/SHGraphicsConstants.h"
namespace SHADE
{
class SHVkLogicalDevice;
class SHVkDescriptorSetLayout;
class SHVkDescriptorSetGroup;
class SHVkPipelineLayout;
class SH_API SHGraphicsGlobalData
{
private:
//! Global descriptor set layouts. Used to allocate descriptor sets
static std::vector<Handle<SHVkDescriptorSetLayout>> globalDescSetLayouts;
//! Default vertex input state (used by everything).
static 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.
static Handle<SHVkPipelineLayout> dummyPipelineLayout;
static void InitHighFrequencyGlobalData (void) noexcept;
static void InitDescSetLayouts (Handle<SHVkLogicalDevice> logicalDevice) noexcept;
static void InitDefaultVertexInputState (void) noexcept;
public:
/*-----------------------------------------------------------------------*/
/* Constructors */
/*-----------------------------------------------------------------------*/
SHGraphicsGlobalData() = delete;
/*-----------------------------------------------------------------------*/
/* PUBLIC MEMBER FUNCTIONS */
/*-----------------------------------------------------------------------*/
static void Init (Handle<SHVkLogicalDevice> logicalDevice) noexcept;
/*-----------------------------------------------------------------------*/
/* SETTERS AND GETTERS */
/*-----------------------------------------------------------------------*/
static std::vector<Handle<SHVkDescriptorSetLayout>> const& GetDescSetLayouts (void) noexcept;
static SHVertexInputState const& GetDefaultViState (void) noexcept;
static Handle<SHVkPipelineLayout> GetDummyPipelineLayout (void) noexcept;
};
}

View File

@ -0,0 +1,256 @@
#include "SHpch.h"
#include "SHGraphicsPredefinedData.h"
#include "Graphics/Devices/SHVkLogicalDevice.h"
#include "Graphics/Pipeline/SHPipelineState.h"
#include "Graphics/Pipeline/SHVkPipelineLayout.h"
#include "Graphics/Descriptors/SHVkDescriptorSetLayout.h"
#include "Graphics/MiddleEnd/Lights/SHLightData.h"
namespace SHADE
{
/*-----------------------------------------------------------------------------------*/
/* Static Definitions */
/*-----------------------------------------------------------------------------------*/
std::vector<Handle<SHVkDescriptorSetLayout>> SHGraphicsPredefinedData::predefinedLayouts;
SHVertexInputState SHGraphicsPredefinedData::defaultVertexInputState;
std::vector<SHGraphicsPredefinedData::PerSystem> SHGraphicsPredefinedData::perSystemData;
//SHGraphicsPredefinedData::PerSystem SHGraphicsPredefinedData::batchingSystemData;
//SHGraphicsPredefinedData::PerSystem SHGraphicsPredefinedData::textSystemData;
//SHGraphicsPredefinedData::PerSystem SHGraphicsPredefinedData::renderGraphNodeComputeData;
void SHGraphicsPredefinedData::InitDescMappings(void) noexcept
{
perSystemData[SHUtilities::ConvertEnum(SystemType::BATCHING)].descMappings.AddMappings
({
{SHPredefinedDescriptorTypes::STATIC_DATA, 0},
{SHPredefinedDescriptorTypes::CAMERA, 1},
{SHPredefinedDescriptorTypes::MATERIALS, 2},
});
perSystemData[SHUtilities::ConvertEnum(SystemType::TEXT_RENDERING)].descMappings.AddMappings
({
{SHPredefinedDescriptorTypes::STATIC_DATA, 0},
{SHPredefinedDescriptorTypes::CAMERA, 1},
{SHPredefinedDescriptorTypes::FONT, 2},
});
perSystemData[SHUtilities::ConvertEnum(SystemType::RENDER_GRAPH_NODE_COMPUTE)].descMappings.AddMappings
({
{SHPredefinedDescriptorTypes::STATIC_DATA, 0},
{SHPredefinedDescriptorTypes::LIGHTS, 1},
{SHPredefinedDescriptorTypes::CAMERA, 2},
{SHPredefinedDescriptorTypes::RENDER_GRAPH_RESOURCE, 3},
{SHPredefinedDescriptorTypes::RENDER_GRAPH_NODE_COMPUTE_RESOURCE, 4},
});
}
void SHGraphicsPredefinedData::InitDummyPipelineLayouts(Handle<SHVkLogicalDevice> logicalDevice) noexcept
{
perSystemData[SHUtilities::ConvertEnum(SystemType::BATCHING)].dummyPipelineLayout = logicalDevice->CreatePipelineLayoutDummy(SHPipelineLayoutParamsDummy{ perSystemData[SHUtilities::ConvertEnum(SystemType::BATCHING)].descSetLayouts });
perSystemData[SHUtilities::ConvertEnum(SystemType::TEXT_RENDERING)].dummyPipelineLayout = logicalDevice->CreatePipelineLayoutDummy(SHPipelineLayoutParamsDummy{ perSystemData[SHUtilities::ConvertEnum(SystemType::TEXT_RENDERING)].descSetLayouts });
perSystemData[SHUtilities::ConvertEnum(SystemType::RENDER_GRAPH_NODE_COMPUTE)].dummyPipelineLayout = logicalDevice->CreatePipelineLayoutDummy(SHPipelineLayoutParamsDummy{ perSystemData[SHUtilities::ConvertEnum(SystemType::RENDER_GRAPH_NODE_COMPUTE)].descSetLayouts });
}
/*-----------------------------------------------------------------------------------*/
/* Function Definitions */
/*-----------------------------------------------------------------------------------*/
void SHGraphicsPredefinedData::InitDescSetLayouts(Handle<SHVkLogicalDevice> logicalDevice) noexcept
{
SHVkDescriptorSetLayout::Binding genericDataBinding
{
.Type = vk::DescriptorType::eUniformBufferDynamic,
.Stage = vk::ShaderStageFlagBits::eVertex | vk::ShaderStageFlagBits::eFragment | vk::ShaderStageFlagBits::eCompute,
.BindPoint = SHGraphicsConstants::DescriptorSetBindings::GENERIC_DATA,
.DescriptorCount = 1,
};
SHVkDescriptorSetLayout::Binding texturesBinding
{
.Type = vk::DescriptorType::eCombinedImageSampler,
.Stage = vk::ShaderStageFlagBits::eVertex | vk::ShaderStageFlagBits::eFragment | vk::ShaderStageFlagBits::eCompute,
.BindPoint = SHGraphicsConstants::DescriptorSetBindings::IMAGE_AND_SAMPLERS_DATA,
.DescriptorCount = 2000, // we can have up to 2000 textures for now
.flags = vk::DescriptorBindingFlagBits::eVariableDescriptorCount,
};
// For global data (generic data and textures)
Handle<SHVkDescriptorSetLayout> staticGlobalLayout = logicalDevice->CreateDescriptorSetLayout({ genericDataBinding, texturesBinding });
SET_VK_OBJ_NAME(logicalDevice, vk::ObjectType::eDescriptorSetLayout, staticGlobalLayout->GetVkHandle(), "[Descriptor Set Layout] Static Globals");
std::vector<SHVkDescriptorSetLayout::Binding> lightBindings{};
// This is the binding we use to count the lights (binding 0)
lightBindings.push_back(SHVkDescriptorSetLayout::Binding
{
.Type = vk::DescriptorType::eUniformBufferDynamic,
.Stage = vk::ShaderStageFlagBits::eCompute,
.BindPoint = 0,
.DescriptorCount = 1,
});
for (uint32_t i = 1; i <= SHUtilities::ConvertEnum(SH_LIGHT_TYPE::NUM_TYPES); ++i)
{
lightBindings.push_back (SHVkDescriptorSetLayout::Binding
{
.Type = vk::DescriptorType::eStorageBufferDynamic,
.Stage = vk::ShaderStageFlagBits::eCompute,
.BindPoint = i,
.DescriptorCount = 1,
});
}
// For Dynamic global data (lights)
Handle<SHVkDescriptorSetLayout> lightDataDescSetLayout = logicalDevice->CreateDescriptorSetLayout(lightBindings);
SET_VK_OBJ_NAME(logicalDevice, vk::ObjectType::eDescriptorSetLayout, lightDataDescSetLayout->GetVkHandle(), "[Descriptor Set Layout] Dynamic Globals");
// For High frequency global data (camera)
SHVkDescriptorSetLayout::Binding cameraDataBinding
{
.Type = vk::DescriptorType::eUniformBufferDynamic,
.Stage = vk::ShaderStageFlagBits::eVertex | vk::ShaderStageFlagBits::eCompute,
.BindPoint = SHGraphicsConstants::DescriptorSetBindings::CAMERA_DATA,
.DescriptorCount = 1,
};
Handle<SHVkDescriptorSetLayout> cameraDataGlobalLayout = logicalDevice->CreateDescriptorSetLayout({ cameraDataBinding });
SET_VK_OBJ_NAME(logicalDevice, vk::ObjectType::eDescriptorSetLayout, cameraDataGlobalLayout->GetVkHandle(), "[Descriptor Set Layout] High Frequency Globals");
// For per instance data (transforms, materials, etc.)
SHVkDescriptorSetLayout::Binding materialDataBinding
{
.Type = vk::DescriptorType::eStorageBufferDynamic,
.Stage = vk::ShaderStageFlagBits::eFragment | vk::ShaderStageFlagBits::eVertex,
.BindPoint = SHGraphicsConstants::DescriptorSetBindings::BATCHED_PER_INST_DATA,
.DescriptorCount = 1,
};
Handle<SHVkDescriptorSetLayout> materialDataPerInstanceLayout = logicalDevice->CreateDescriptorSetLayout({ materialDataBinding });
SET_VK_OBJ_NAME(logicalDevice, vk::ObjectType::eDescriptorSetLayout, materialDataPerInstanceLayout->GetVkHandle(), "[Descriptor Set Layout] Material Globals");
// font bitmap data (texture)
SHVkDescriptorSetLayout::Binding fontBitmapBinding
{
.Type = vk::DescriptorType::eCombinedImageSampler,
.Stage = vk::ShaderStageFlagBits::eFragment,
.BindPoint = SHGraphicsConstants::DescriptorSetBindings::FONT_BITMAP_DATA,
.DescriptorCount = 1,
};
// font data in the form of matrices
SHVkDescriptorSetLayout::Binding fontMatrixBinding
{
.Type = vk::DescriptorType::eStorageBuffer,
.Stage = vk::ShaderStageFlagBits::eVertex,
.BindPoint = SHGraphicsConstants::DescriptorSetBindings::FONT_MATRIX_DATA,
.DescriptorCount = 1,
};
Handle<SHVkDescriptorSetLayout> fontDataDescSetLayout = logicalDevice->CreateDescriptorSetLayout({ fontBitmapBinding, fontMatrixBinding });
SET_VK_OBJ_NAME(logicalDevice, vk::ObjectType::eDescriptorSetLayout, fontDataDescSetLayout->GetVkHandle(), "[Descriptor Set Layout] Font Data");
predefinedLayouts.push_back(staticGlobalLayout);
predefinedLayouts.push_back(lightDataDescSetLayout);
predefinedLayouts.push_back(cameraDataGlobalLayout);
predefinedLayouts.push_back(materialDataPerInstanceLayout);
predefinedLayouts.push_back(fontDataDescSetLayout);
perSystemData[SHUtilities::ConvertEnum(SystemType::BATCHING)].descSetLayouts = GetPredefinedDescSetLayouts
(
SHGraphicsPredefinedData::PredefinedDescSetLayoutTypes::STATIC_DATA |
SHGraphicsPredefinedData::PredefinedDescSetLayoutTypes::CAMERA |
SHGraphicsPredefinedData::PredefinedDescSetLayoutTypes::MATERIALS
);
perSystemData[SHUtilities::ConvertEnum(SystemType::TEXT_RENDERING)].descSetLayouts = GetPredefinedDescSetLayouts
(
SHGraphicsPredefinedData::PredefinedDescSetLayoutTypes::STATIC_DATA |
SHGraphicsPredefinedData::PredefinedDescSetLayoutTypes::CAMERA |
SHGraphicsPredefinedData::PredefinedDescSetLayoutTypes::FONT
);
perSystemData[SHUtilities::ConvertEnum(SystemType::RENDER_GRAPH_NODE_COMPUTE)].descSetLayouts = GetPredefinedDescSetLayouts
(
SHGraphicsPredefinedData::PredefinedDescSetLayoutTypes::STATIC_DATA |
SHGraphicsPredefinedData::PredefinedDescSetLayoutTypes::CAMERA |
SHGraphicsPredefinedData::PredefinedDescSetLayoutTypes::LIGHTS
);
}
void SHGraphicsPredefinedData::InitDefaultVertexInputState(void) noexcept
{
defaultVertexInputState.AddBinding(false, false, { SHVertexAttribute(SHAttribFormat::FLOAT_3D) }); // positions at binding 0
defaultVertexInputState.AddBinding(false, false, { SHVertexAttribute(SHAttribFormat::FLOAT_2D) }); // UVs at binding 1
defaultVertexInputState.AddBinding(false, false, { SHVertexAttribute(SHAttribFormat::FLOAT_3D) }); // Normals at binding 2
defaultVertexInputState.AddBinding(false, false, { SHVertexAttribute(SHAttribFormat::FLOAT_3D) }); // Tangents at binding 3
defaultVertexInputState.AddBinding(true, true, { SHVertexAttribute(SHAttribFormat::MAT_4D) }); // Transform at binding 4 - 7 (4 slots)
defaultVertexInputState.AddBinding(true, true, { SHVertexAttribute(SHAttribFormat::UINT32_2D) }); // Instanced integer data at index 8
}
void SHGraphicsPredefinedData::Init(Handle<SHVkLogicalDevice> logicalDevice) noexcept
{
perSystemData.resize(SHUtilities::ConvertEnum(SystemType::NUM_TYPES));
InitDescSetLayouts(logicalDevice);
InitDefaultVertexInputState();
InitDescMappings();
InitDummyPipelineLayouts (logicalDevice);
}
std::vector<Handle<SHVkDescriptorSetLayout>> SHGraphicsPredefinedData::GetPredefinedDescSetLayouts(SHGraphicsPredefinedData::PredefinedDescSetLayoutTypes types) noexcept
{
std::vector<Handle<SHVkDescriptorSetLayout>> layoutsFound;
for (uint8_t i = 0; i < numPredefinedDescSetLayoutTypes; ++i)
{
auto result = types & static_cast<SHGraphicsPredefinedData::PredefinedDescSetLayoutTypes>(static_cast<uint64_t>(1) << i);
if (static_cast<uint64_t>(result))
layoutsFound.push_back(predefinedLayouts[i]);
}
return layoutsFound;
}
SHVertexInputState const& SHGraphicsPredefinedData::GetDefaultViState(void) noexcept
{
return defaultVertexInputState;
}
SHGraphicsPredefinedData::PerSystem const& SHGraphicsPredefinedData::GetSystemData(SystemType systemType) noexcept
{
return perSystemData[static_cast<uint32_t>(systemType)];
}
SHDescriptorMappings::MapType const& SHGraphicsPredefinedData::GetMappings(SystemType systemType) noexcept
{
return perSystemData[static_cast<uint32_t>(systemType)].descMappings.GetMappings();
}
SHGraphicsPredefinedData::PredefinedDescSetLayoutTypes operator|(SHGraphicsPredefinedData::PredefinedDescSetLayoutTypes lhs, SHGraphicsPredefinedData::PredefinedDescSetLayoutTypes rhs) noexcept
{
return static_cast<SHGraphicsPredefinedData::PredefinedDescSetLayoutTypes>(static_cast<uint64_t>(lhs) | static_cast<uint64_t>(rhs));
}
SHGraphicsPredefinedData::PredefinedDescSetLayoutTypes operator&(SHGraphicsPredefinedData::PredefinedDescSetLayoutTypes lhs, SHGraphicsPredefinedData::PredefinedDescSetLayoutTypes rhs) noexcept
{
return static_cast<SHGraphicsPredefinedData::PredefinedDescSetLayoutTypes>(static_cast<uint64_t>(lhs) & static_cast<uint64_t>(rhs));
}
//SHGraphicsPredefinedData::PerSystem const& SHGraphicsPredefinedData::GetBatchingSystemData(void) noexcept
//{
// return batchingSystemData;
//}
//SHGraphicsPredefinedData::PerSystem const& SHGraphicsPredefinedData::GetTextSystemData(void) noexcept
//{
// return textSystemData;
//}
//SHGraphicsPredefinedData::PerSystem const& SHGraphicsPredefinedData::GetRenderGraphNodeComputeData(void) noexcept
//{
// return renderGraphNodeComputeData;
//}
}

View File

@ -0,0 +1,102 @@
#pragma once
#include "SH_API.h"
#include "Graphics/Pipeline/SHPipelineState.h"
#include "Graphics/MiddleEnd/Interface/SHGraphicsConstants.h"
#include "Graphics/MiddleEnd/GlobalData/SHDescriptorMappings.h"
#include "Tools/Utilities/SHUtilities.h"
#include "Tools/SHEnumWrapper.h"
#include <unordered_map>
namespace SHADE
{
class SHVkLogicalDevice;
class SHVkDescriptorSetLayout;
class SHVkDescriptorSetGroup;
class SHVkPipelineLayout;
class SH_API SHGraphicsPredefinedData
{
public:
static constexpr uint8_t numPredefinedDescSetLayoutTypes = 64;
// This enum is mainly to initialize a bit field to retrieve bit fields from SHPRedefinedData
enum class PredefinedDescSetLayoutTypes : uint64_t
{
STATIC_DATA = 0x01,
LIGHTS = 0x02,
CAMERA = 0x04,
MATERIALS = 0x08,
FONT = 0x10,
};
enum class SystemType
{
BATCHING = 0,
TEXT_RENDERING,
RENDER_GRAPH_NODE_COMPUTE,
NUM_TYPES
};
struct PerSystem
{
//! vector of descriptor set layouts used by a system
std::vector<Handle<SHVkDescriptorSetLayout>> descSetLayouts;
//! pipeline layout used for binding descriptor sets in the system
Handle<SHVkPipelineLayout> dummyPipelineLayout;
//! Descriptor type mappings for the system
SHDescriptorMappings descMappings;
};
private:
//! Global descriptor set layouts. Used to allocate descriptor sets
static std::vector<Handle<SHVkDescriptorSetLayout>> predefinedLayouts;
//! Default vertex input state (used by everything).
static SHVertexInputState defaultVertexInputState;
//! Predefined data for each type of system
static std::vector<PerSystem> perSystemData;
////! predefined data for the batching system
//static PerSystem batchingSystemData;
////! predefined data for the text system
//static PerSystem textSystemData;
////! predefined data for the render graph node computes
//static PerSystem renderGraphNodeComputeData;
static void InitDescMappings (void) noexcept;
static void InitDummyPipelineLayouts (Handle<SHVkLogicalDevice> logicalDevice) noexcept;
static void InitDescSetLayouts (Handle<SHVkLogicalDevice> logicalDevice) noexcept;
static void InitDefaultVertexInputState (void) noexcept;
public:
/*-----------------------------------------------------------------------*/
/* Constructors */
/*-----------------------------------------------------------------------*/
SHGraphicsPredefinedData() = delete;
/*-----------------------------------------------------------------------*/
/* PUBLIC MEMBER FUNCTIONS */
/*-----------------------------------------------------------------------*/
static void Init (Handle<SHVkLogicalDevice> logicalDevice) noexcept;
/*-----------------------------------------------------------------------*/
/* SETTERS AND GETTERS */
/*-----------------------------------------------------------------------*/
static std::vector<Handle<SHVkDescriptorSetLayout>> GetPredefinedDescSetLayouts (SHGraphicsPredefinedData::PredefinedDescSetLayoutTypes types) noexcept;
static SHVertexInputState const& GetDefaultViState (void) noexcept;
static PerSystem const& GetSystemData (SystemType systemType) noexcept;
static SHDescriptorMappings::MapType const& GetMappings (SystemType systemType) noexcept;
//static PerSystem const& GetBatchingSystemData(void) noexcept;
//static PerSystem const& GetTextSystemData(void) noexcept;
//static PerSystem const& GetRenderGraphNodeComputeData(void) noexcept;
};
SHGraphicsPredefinedData::PredefinedDescSetLayoutTypes operator| (SHGraphicsPredefinedData::PredefinedDescSetLayoutTypes lhs, SHGraphicsPredefinedData::PredefinedDescSetLayoutTypes rhs) noexcept;
SHGraphicsPredefinedData::PredefinedDescSetLayoutTypes operator& (SHGraphicsPredefinedData::PredefinedDescSetLayoutTypes lhs, SHGraphicsPredefinedData::PredefinedDescSetLayoutTypes rhs) noexcept;
}

View File

@ -0,0 +1,19 @@
#pragma once
namespace SHADE
{
// This enum is different from PredefinedDescSetLayoutTypes in that it is used to initialize a hash table to
// with the values here as keys and set indices as values. It is worth noting that some values here
// are not in the above table. This is because those values don't have predefined descriptor set layouts.
// Their layouts and set indices are instead created through introspection in the pipeline layout.
enum class SHPredefinedDescriptorTypes
{
STATIC_DATA,
LIGHTS,
CAMERA,
MATERIALS,
FONT,
RENDER_GRAPH_RESOURCE,
RENDER_GRAPH_NODE_COMPUTE_RESOURCE,
};
}

View File

@ -99,10 +99,10 @@ namespace SHADE
createMeshBatches();
// Register function for subpass
auto const& RENDERERS = gfxSystem->GetDefaultViewport()->GetRenderers();
auto renderGraph = RENDERERS[SHGraphicsConstants::RenderGraphIndices::WORLD]->GetRenderGraph();
//auto const& RENDERERS = gfxSystem->GetDefaultViewport()->GetRenderers();
auto renderGraph = gfxSystem->GetRenderGraph();
auto subPass = renderGraph->GetNode("Debug Draw")->GetSubpass("Debug Draw");
subPass->AddExteriorDrawCalls([this](Handle<SHVkCommandBuffer>& cmdBuffer, uint32_t frameIndex)
subPass->AddExteriorDrawCalls([this](Handle<SHVkCommandBuffer> cmdBuffer, Handle<SHRenderer> renderer, uint32_t frameIndex)
{
const uint32_t FRAME_IDX = gfxSystem->GetCurrentFrameIndex();
cmdBuffer->BeginLabeledSegment("SHDebugDraw (No Depth Test)");
@ -126,7 +126,7 @@ namespace SHADE
cmdBuffer->EndLabeledSegment();
});
auto subPassWithDepth = renderGraph->GetNode("Debug Draw with Depth")->GetSubpass("Debug Draw with Depth");
subPassWithDepth->AddExteriorDrawCalls([this](Handle<SHVkCommandBuffer>& cmdBuffer, uint32_t frameIndex)
subPassWithDepth->AddExteriorDrawCalls([this](Handle<SHVkCommandBuffer> cmdBuffer, Handle<SHRenderer> renderer, uint32_t frameIndex)
{
const uint32_t FRAME_IDX = gfxSystem->GetCurrentFrameIndex();
cmdBuffer->BeginLabeledSegment("SHDebugDraw (Depth Tested)");

View File

@ -31,68 +31,68 @@ namespace SHADE
static constexpr uint32_t EDITOR = 0;
};
struct DescriptorSetIndex
{
/***************************************************************************/
/*!
\brief
DescriptorSet Index for static global values like generic data, and
texture samplers
*/
/***************************************************************************/
static constexpr uint32_t STATIC_GLOBALS = 0;
/***************************************************************************/
/*!
\brief
DescriptorSet Index for dynamic global values like lights.
*/
/***************************************************************************/
static constexpr uint32_t DYNAMIC_GLOBALS = 1;
/***************************************************************************/
/*!
\brief
DescriptorSet Index for high frequency changing global values like
camera matrices.
*/
/***************************************************************************/
static constexpr uint32_t HIGH_FREQUENCY_GLOBALS = 2;
/***************************************************************************/
/*!
\brief
DescriptorSet Index for per-instance/material changing values.
*/
/***************************************************************************/
static constexpr uint32_t PER_INSTANCE = 3;
/***************************************************************************/
/*!
\brief
DescriptorSet Index for render graph resources. Unlike the sets from
1 to 3 and 6, this set index does not have hard coded bindings and is
NOT part of the layouts included in the global data.
*/
/***************************************************************************/
static constexpr uint32_t RENDERGRAPH_RESOURCE = 4;
/***************************************************************************/
/*!
\brief
DescriptorSet Index for render graph node compute resources. For data
that we wish to pass to compute shaders in the render graph, this is
the set to use. Unlike the sets from 1 to 3 and 6, this set index does not have
hard coded bindings and is NOT part of the layouts included in the global
data.
*/
/***************************************************************************/
static constexpr uint32_t RENDERGRAPH_NODE_COMPUTE_RESOURCE = 5;
//struct DescriptorSetIndex
//{
// /***************************************************************************/
// /*!
// \brief
// DescriptorSet Index for static global values like generic data, and
// texture samplers
// */
// /***************************************************************************/
// static constexpr uint32_t STATIC_GLOBALS = 0;
// /***************************************************************************/
// /*!
// \brief
// DescriptorSet Index for dynamic global values like lights.
// */
// /***************************************************************************/
// static constexpr uint32_t DYNAMIC_GLOBALS = 1;
// /***************************************************************************/
// /*!
// \brief
// DescriptorSet Index for high frequency changing global values like
// camera matrices.
// */
// /***************************************************************************/
// static constexpr uint32_t HIGH_FREQUENCY_GLOBALS = 2;
// /***************************************************************************/
// /*!
// \brief
// DescriptorSet Index for per-instance/material changing values.
// */
// /***************************************************************************/
// static constexpr uint32_t PER_INSTANCE = 3;
// /***************************************************************************/
// /*!
// \brief
// DescriptorSet Index for render graph resources. Unlike the sets from
// 1 to 3 and 6, this set index does not have hard coded bindings and is
// NOT part of the layouts included in the global data.
// */
// /***************************************************************************/
// static constexpr uint32_t RENDERGRAPH_RESOURCE = 4;
// /***************************************************************************/
// /*!
// \brief
// DescriptorSet Index for render graph node compute resources. For data
// that we wish to pass to compute shaders in the render graph, this is
// the set to use. Unlike the sets from 1 to 3 and 6, this set index does not have
// hard coded bindings and is NOT part of the layouts included in the global
// data.
// */
// /***************************************************************************/
// static constexpr uint32_t RENDERGRAPH_NODE_COMPUTE_RESOURCE = 5;
/***************************************************************************/
/*!
\brief
To store font data.
*/
/***************************************************************************/
static constexpr uint32_t FONT_DATA = 4;
};
// /***************************************************************************/
// /*!
// \brief
// To store font data.
//
// */
// /***************************************************************************/
// static constexpr uint32_t FONT_DATA = 4;
//};
struct DescriptorSetBindings
{

View File

@ -19,7 +19,6 @@ of DigiPen Institute of Technology is prohibited.
#include "Camera/SHCameraSystem.h"
#include "Editor/SHEditor.h"
#include "ECS_Base/Managers/SHSystemManager.h"
//#include "SHRenderer.h"
#include "Graphics/Windowing/SHWindow.h"
#include "Graphics/MiddleEnd/PerFrame/SHPerFrameData.h"
#include "Graphics/MiddleEnd/Interface/SHViewport.h"
@ -31,7 +30,7 @@ of DigiPen Institute of Technology is prohibited.
#include "Graphics/MiddleEnd/Interface/SHRenderable.h"
#include "Graphics/MiddleEnd/Batching/SHSuperBatch.h"
#include "SHGraphicsConstants.h"
#include "Graphics/MiddleEnd/GlobalData/SHGraphicsGlobalData.h"
#include "Graphics/MiddleEnd/GlobalData/SHGraphicsPredefinedData.h"
#include "Graphics/Buffers/SHVkBuffer.h"
#include "Graphics/Images/SHVkSampler.h"
#include "Assets/Asset Types/SHTextureAsset.h"
@ -44,6 +43,7 @@ of DigiPen Institute of Technology is prohibited.
#include "../Meshes/SHPrimitiveGenerator.h"
#include "Graphics/MiddleEnd/TextRendering/SHFreetypeInstance.h"
#include "Graphics/MiddleEnd/TextRendering/SHTextRenderingSubSystem.h"
#include "Graphics/MiddleEnd/GlobalData/SHGlobalDescriptorSets.h"
namespace SHADE
{
@ -139,7 +139,7 @@ namespace SHADE
static constexpr AssetID RENDER_SC_FS = 36869006; renderToSwapchainFS = SHResourceManager::LoadOrGet<SHVkShaderModule>(RENDER_SC_FS);
}
void SHGraphicsSystem::InitSceneRenderGraph(void) noexcept
void SHGraphicsSystem::InitRenderGraph(void) noexcept
{
/*-----------------------------------------------------------------------*/
/* MIDDLE END SETUP
@ -153,60 +153,59 @@ namespace SHADE
auto windowDims = window->GetWindowSize();
auto cameraSystem = SHSystemManager::GetSystem<SHCameraSystem>();
// Set Up Cameras
screenCamera = resourceManager.Create<SHCamera>();
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<float>(windowDims.first), static_cast<float>(windowDims.second), 0.01f, 100.0f);
worldCamera = resourceManager.Create<SHCamera>();
worldCamera->SetLookAt(SHVec3(0.0f, 0.0f, 0.0f), SHVec3(0.0f, 0.0f, -2.0f), SHVec3(0.0f, 1.0f, 0.0f));
worldCamera->SetPerspective(90.0f, static_cast<float>(windowDims.first), static_cast<float>(windowDims.second), 0.0f, 100.0f);
worldCameraDirector = cameraSystem->CreateDirector();
/*-----------------------------------------------------------------------*/
/* PREPARE RENDERERS */
/*-----------------------------------------------------------------------*/
// Add world renderer to default viewport
worldRenderer = AddRenderer(SHRenderer::PROJECTION_TYPE::PERSPECTIVE);
worldRenderer->SetCameraDirector(worldCameraDirector);
// Add screen renderer to default viewport
screenRenderer = AddRenderer(SHRenderer::PROJECTION_TYPE::ORTHOGRAPHIC);
screenRenderer->SetCameraDirector(worldCameraDirector);
// Create Default Viewport
worldViewport = AddViewport(vk::Viewport(0.0f, 0.0f, static_cast<float>(window->GetWindowSize().first), static_cast<float>(window->GetWindowSize().second), 0.0f, 1.0f));
// Get render graph from default viewport world renderer
worldRenderGraph = resourceManager.Create<SHRenderGraph>();
std::vector<Handle<SHVkCommandPool>> renderContextCmdPools{ swapchain->GetNumImages() };
for (uint32_t i = 0; i < renderContextCmdPools.size(); ++i)
{
renderContextCmdPools[i] = renderContext.GetFrameData(i).cmdPoolHdls[0];
}
// Get render graph from default viewport world renderer
renderGraph = resourceManager.Create<SHRenderGraph>();
/*-----------------------------------------------------------------------*/
/* WORLD RENDER GRAPH RESOURCES */
/*-----------------------------------------------------------------------*/
// Initialize world render graph
worldRenderGraph->Init("World Render Graph", device, swapchain, &resourceManager);
worldRenderGraph->AddResource("Position", { SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR, SH_RENDER_GRAPH_RESOURCE_FLAGS::INPUT, SH_RENDER_GRAPH_RESOURCE_FLAGS::STORAGE }, windowDims.first, windowDims.second, vk::Format::eR32G32B32A32Sfloat);
worldRenderGraph->AddResource("Normals", { SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR, SH_RENDER_GRAPH_RESOURCE_FLAGS::INPUT, SH_RENDER_GRAPH_RESOURCE_FLAGS::STORAGE }, windowDims.first, windowDims.second, vk::Format::eR32G32B32A32Sfloat);
renderGraph->Init("World Render Graph", device, swapchain, &resourceManager, renderContextCmdPools);
renderGraph->AddResource("Position", { SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR, SH_RENDER_GRAPH_RESOURCE_FLAGS::INPUT, SH_RENDER_GRAPH_RESOURCE_FLAGS::STORAGE }, windowDims.first, windowDims.second, vk::Format::eR32G32B32A32Sfloat);
renderGraph->AddResource("Normals", { SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR, SH_RENDER_GRAPH_RESOURCE_FLAGS::INPUT, SH_RENDER_GRAPH_RESOURCE_FLAGS::STORAGE }, windowDims.first, windowDims.second, vk::Format::eR32G32B32A32Sfloat);
//worldRenderGraph->AddResource("Tangents", { SH_ATT_DESC_TYPE_FLAGS::COLOR, SH_ATT_DESC_TYPE_FLAGS::INPUT, SH_ATT_DESC_TYPE_FLAGS::STORAGE }, windowDims.first, windowDims.second, vk::Format::eR32G32B32A32Sfloat);
worldRenderGraph->AddResource("Albedo", { SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR, SH_RENDER_GRAPH_RESOURCE_FLAGS::INPUT, SH_RENDER_GRAPH_RESOURCE_FLAGS::STORAGE }, windowDims.first, windowDims.second);
worldRenderGraph->AddResource("Depth Buffer", { SH_RENDER_GRAPH_RESOURCE_FLAGS::DEPTH_STENCIL }, windowDims.first, windowDims.second, vk::Format::eD32SfloatS8Uint);
worldRenderGraph->AddResource("Entity ID", { SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR, SH_RENDER_GRAPH_RESOURCE_FLAGS::SHARED }, windowDims.first, windowDims.second, vk::Format::eR32Uint, 1, vk::ImageUsageFlagBits::eTransferSrc);
worldRenderGraph->AddResource("Light Layer Indices", { SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR, SH_RENDER_GRAPH_RESOURCE_FLAGS::INPUT, SH_RENDER_GRAPH_RESOURCE_FLAGS::STORAGE }, windowDims.first, windowDims.second, vk::Format::eR32Uint, 1, vk::ImageUsageFlagBits::eTransferSrc);
worldRenderGraph->AddResource("Scene", { SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR, SH_RENDER_GRAPH_RESOURCE_FLAGS::INPUT, SH_RENDER_GRAPH_RESOURCE_FLAGS::STORAGE, SH_RENDER_GRAPH_RESOURCE_FLAGS::SHARED }, windowDims.first, windowDims.second);
worldRenderGraph->AddResource("SSAO", { SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR, SH_RENDER_GRAPH_RESOURCE_FLAGS::INPUT, SH_RENDER_GRAPH_RESOURCE_FLAGS::STORAGE }, windowDims.first, windowDims.second, vk::Format::eR8Unorm);
worldRenderGraph->AddResource("SSAO Blur", { SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR, SH_RENDER_GRAPH_RESOURCE_FLAGS::INPUT, SH_RENDER_GRAPH_RESOURCE_FLAGS::STORAGE }, windowDims.first, windowDims.second, vk::Format::eR8Unorm);
renderGraph->AddResource("Albedo", { SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR, SH_RENDER_GRAPH_RESOURCE_FLAGS::INPUT, SH_RENDER_GRAPH_RESOURCE_FLAGS::STORAGE }, windowDims.first, windowDims.second);
renderGraph->AddResource("Depth Buffer", { SH_RENDER_GRAPH_RESOURCE_FLAGS::DEPTH_STENCIL }, windowDims.first, windowDims.second, vk::Format::eD32SfloatS8Uint);
renderGraph->AddResource("Entity ID", { SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR, SH_RENDER_GRAPH_RESOURCE_FLAGS::SHARED }, windowDims.first, windowDims.second, vk::Format::eR32Uint, 1, vk::ImageUsageFlagBits::eTransferSrc);
renderGraph->AddResource("Light Layer Indices", { SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR, SH_RENDER_GRAPH_RESOURCE_FLAGS::INPUT, SH_RENDER_GRAPH_RESOURCE_FLAGS::STORAGE }, windowDims.first, windowDims.second, vk::Format::eR32Uint, 1, vk::ImageUsageFlagBits::eTransferSrc);
renderGraph->AddResource("Scene", { SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR, SH_RENDER_GRAPH_RESOURCE_FLAGS::INPUT, SH_RENDER_GRAPH_RESOURCE_FLAGS::STORAGE, SH_RENDER_GRAPH_RESOURCE_FLAGS::SHARED }, windowDims.first, windowDims.second);
renderGraph->AddResource("SSAO", { SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR, SH_RENDER_GRAPH_RESOURCE_FLAGS::INPUT, SH_RENDER_GRAPH_RESOURCE_FLAGS::STORAGE }, windowDims.first, windowDims.second, vk::Format::eR8Unorm);
renderGraph->AddResource("SSAO Blur", { SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR, SH_RENDER_GRAPH_RESOURCE_FLAGS::INPUT, SH_RENDER_GRAPH_RESOURCE_FLAGS::STORAGE }, windowDims.first, windowDims.second, vk::Format::eR8Unorm);
renderGraph->AddResource("Present", { SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR_PRESENT }, windowDims.first, windowDims.second);
/*-----------------------------------------------------------------------*/
/* MAIN NODE */
/*-----------------------------------------------------------------------*/
auto gBufferNode = worldRenderGraph->AddNode("G-Buffer",
auto gBufferNode = renderGraph->AddNode("G-Buffer",
{
"Position",
"Entity ID",
"Light Layer Indices",
"Normals",
//"Tangents",
"Albedo",
"Depth Buffer",
"Scene",
"SSAO",
"SSAO Blur"
},
@ -215,20 +214,21 @@ namespace SHADE
/*-----------------------------------------------------------------------*/
/* G-BUFFER SUBPASS INIT */
/*-----------------------------------------------------------------------*/
auto gBufferSubpass = gBufferNode->AddSubpass("G-Buffer Write");
auto gBufferSubpass = gBufferNode->AddSubpass("G-Buffer Write", worldViewport, worldRenderer);
gBufferSubpass->AddColorOutput("Position");
gBufferSubpass->AddColorOutput("Entity ID");
gBufferSubpass->AddColorOutput("Light Layer Indices");
gBufferSubpass->AddColorOutput("Normals");
//gBufferSubpass->AddColorOutput("Tangents");
gBufferSubpass->AddColorOutput("Albedo");
gBufferSubpass->AddDepthOutput("Depth Buffer", SH_RENDER_GRAPH_RESOURCE_FLAGS::DEPTH_STENCIL);
/*-----------------------------------------------------------------------*/
/* SSAO PASS AND DATA INIT */
/*-----------------------------------------------------------------------*/
ssaoStorage = resourceManager.Create<SHSSAO>();
// command buffer operation to transfer data for ssao
ssaoTransferCmdBuffer = graphicsCmdPool->RequestCommandBuffer(SH_CMD_BUFFER_TYPE::PRIMARY);
SET_VK_OBJ_NAME(device, vk::ObjectType::eCommandBuffer, ssaoTransferCmdBuffer->GetVkCommandBuffer(), "[Command Buffer] SSAO Pass (Graphics)");
ssaoTransferCmdBuffer->BeginRecording();
@ -237,95 +237,102 @@ namespace SHADE
ssaoTransferCmdBuffer->EndRecording();
graphicsQueue->SubmitCommandBuffer({ ssaoTransferCmdBuffer });
// Set up Debug Draw Passes
// - Depth Tested
auto debugDrawNodeDepth = worldRenderGraph->AddNode("Debug Draw with Depth", { "Scene", "Depth Buffer" }, {"G-Buffer"});
auto debugDrawDepthSubpass = debugDrawNodeDepth->AddSubpass("Debug Draw with Depth");
debugDrawDepthSubpass->AddColorOutput("Scene");
debugDrawDepthSubpass->AddDepthOutput("Depth Buffer");
// - No Depth Test
auto debugDrawNode = worldRenderGraph->AddNode("Debug Draw", { "Scene" }, { "Debug Draw with Depth" });
auto debugDrawSubpass = debugDrawNode->AddSubpass("Debug Draw");
debugDrawSubpass->AddColorOutput("Scene");
// wait for command buffer to finish executing
graphicsQueue->WaitIdle();
ssaoStorage->PrepareRotationVectorsVkData(device);
// Add the pass to generate an image with just SSAO data
Handle<SHRenderGraphNodeCompute> ssaoPass = gBufferNode->AddNodeCompute("SSAO", ssaoShader, { "Position", "Normals", "SSAO" });
auto ssaoDataBuffer = ssaoStorage->GetBuffer();
ssaoPass->ModifyWriteDescBufferComputeResource(SHGraphicsConstants::DescriptorSetIndex::RENDERGRAPH_NODE_COMPUTE_RESOURCE, SHSSAO::DESC_SET_BUFFER_BINDING, { &ssaoDataBuffer, 1 }, 0, ssaoStorage->GetBuffer()->GetSizeStored());
ssaoPass->ModifyWriteDescBufferComputeResource(SHSSAO::DESC_SET_BUFFER_BINDING, { &ssaoDataBuffer, 1 }, 0, ssaoStorage->GetBuffer()->GetSizeStored());
auto viewSamplerLayout = ssaoStorage->GetViewSamplerLayout();
ssaoPass->ModifyWriteDescImageComputeResource(SHGraphicsConstants::DescriptorSetIndex::RENDERGRAPH_NODE_COMPUTE_RESOURCE, SHSSAO::DESC_SET_IMAGE_BINDING, {&viewSamplerLayout, 1});
ssaoPass->ModifyWriteDescImageComputeResource(SHSSAO::DESC_SET_IMAGE_BINDING, { &viewSamplerLayout, 1 });
ssaoPass->SetRenderer(worldRenderer);
// Add another pass to blur SSAO
Handle<SHRenderGraphNodeCompute> ssaoBlurPass = gBufferNode->AddNodeCompute("SSAO Blur Step", ssaoBlurShader, { "SSAO", "SSAO Blur" });
/*-----------------------------------------------------------------------*/
/* SHADOW MAP PASS */
/*-----------------------------------------------------------------------*/
// Shadow map pass will have no resources bound at first. Lighting system will add resources to the node.
// It will initially also not have any subpasses since they will be added for each light that casts shadows.
//auto shadowMapPass = renderGraph->AddNode("Shadow Map Pass", {}, {});
Handle<SHRenderGraphNodeCompute> ssaoBlurPass = gBufferNode->AddNodeCompute("SSAO Blur Step", ssaoBlurShader, {"SSAO", "SSAO Blur"});
/*-----------------------------------------------------------------------*/
/* DEFERRED COMPOSITE NODE */
/*-----------------------------------------------------------------------*/
// This pass will facilitate both lighting and shadows in 1 single pass.
auto deferredCompositeNode = renderGraph->AddNode("Deferred Comp Pass",
{
"Position",
"Light Layer Indices",
"Normals",
"Albedo",
"Scene",
"SSAO Blur"
},
{"G-Buffer"});
/*-----------------------------------------------------------------------*/
/* DEFERRED COMPOSITE SUBPASS INIT */
/*-----------------------------------------------------------------------*/
gBufferNode->AddNodeCompute("Deferred Composite", deferredCompositeShader, {"Position", "Normals", "Albedo", "Light Layer Indices", "SSAO Blur", "Scene"});
{
//// Dummy Node to transition scene render graph resource
//auto dummyNode = worldRenderGraph->AddNode("Dummy Pass", { "Scene" }, { "Debug Draw" }); // no predecessors
//auto dummySubpass = dummyNode->AddSubpass("Dummy Subpass");
//dummySubpass->AddInput("Scene");
}
deferredCompositeNode->AddNodeCompute("Deferred Composite", deferredCompositeShader, { "Position", "Normals", "Albedo", "Light Layer Indices", "SSAO Blur", "Scene" });
/*-----------------------------------------------------------------------*/
/* GENERATE WORLD RENDER GRAPH */
/* DEBUG DRAW PASS INIT */
/*-----------------------------------------------------------------------*/
// Generate world render graph
worldRenderGraph->Generate();
// Set up Debug Draw Passes
// - Depth Tested
auto debugDrawNodeDepth = renderGraph->AddNode("Debug Draw with Depth", { "Scene", "Depth Buffer" }, {"G-Buffer", "Deferred Comp Pass"});
auto debugDrawDepthSubpass = debugDrawNodeDepth->AddSubpass("Debug Draw with Depth", worldViewport, worldRenderer);
debugDrawDepthSubpass->AddColorOutput("Scene");
debugDrawDepthSubpass->AddDepthOutput("Depth Buffer");
// - No Depth Test
auto debugDrawNode = renderGraph->AddNode("Debug Draw", { "Scene" }, { "Debug Draw with Depth" });
auto debugDrawSubpass = debugDrawNode->AddSubpass("Debug Draw", worldViewport, worldRenderer);
debugDrawSubpass->AddColorOutput("Scene");
/*-----------------------------------------------------------------------*/
/* SCREEN RENDER GRAPH */
/* SCREEN SPACE PASS */
/*-----------------------------------------------------------------------*/
// Initialize screen render graph
screenRenderGraph = resourceManager.Create<SHRenderGraph>();
screenRenderGraph->Init("Screen Render Graph", device, swapchain, &resourceManager);
screenRenderGraph->LinkNonOwningResource(worldRenderGraph, "Scene");
screenRenderGraph->LinkNonOwningResource(worldRenderGraph, "Entity ID");
screenRenderGraph->AddResource("Present", { SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR_PRESENT }, windowDims.first, windowDims.second);
auto screenSpaceNode = screenRenderGraph->AddNode("Screen Space Pass", { "Scene", "Entity ID"}, {});
auto uiSubpass = screenSpaceNode->AddSubpass("UI");
auto screenSpaceNode = renderGraph->AddNode("Screen Space Pass", { "Scene", "Entity ID" }, {"Deferred Comp Pass", "G-Buffer", "Debug Draw" });
auto uiSubpass = screenSpaceNode->AddSubpass("UI", worldViewport, screenRenderer);
uiSubpass->AddColorOutput("Scene");
uiSubpass->AddColorOutput("Entity ID");
uiSubpass->AddExteriorDrawCalls([=](Handle<SHVkCommandBuffer>& cmdBuffer, uint32_t frameIndex)
uiSubpass->AddExteriorDrawCalls([=](Handle<SHVkCommandBuffer> cmdBuffer, Handle<SHRenderer> renderer, uint32_t frameIndex)
{
textRenderingSubSystem->Render(cmdBuffer, frameIndex);
textRenderingSubSystem->Render(cmdBuffer, renderer, frameIndex);
});
/*-----------------------------------------------------------------------*/
/* RENDER TO SWAPCHAIN IMAGE FOR PRESENT PASS */
/*-----------------------------------------------------------------------*/
#ifdef SHEDITOR
{
// Dummy Node to transition scene render graph resource
auto dummyNode = screenRenderGraph->AddNode("Dummy Pass", { "Scene" }, { "Screen Space Pass" }); // no predecessors
auto dummySubpass = dummyNode->AddSubpass("Dummy Subpass");
auto dummyNode = renderGraph->AddNode("Dummy Pass", { "Scene" }, { "Screen Space Pass" });
auto dummySubpass = dummyNode->AddSubpass("Dummy Subpass", {}, {});
dummySubpass->AddInput("Scene");
}
auto imGuiNode = renderGraph->AddNode("ImGui Node", { "Present" }, {});
auto imGuiSubpass = imGuiNode->AddSubpass("ImGui Draw", {}, {});
imGuiSubpass->AddColorOutput("Present");
}
#else
screenRenderGraph->AddRenderToSwapchainNode("Scene", "Present", {"Screen Space Pass"}, {renderToSwapchainVS, renderToSwapchainFS});
renderGraph->AddRenderToSwapchainNode("Scene", "Present", { "Screen Space Pass" }, { renderToSwapchainVS, renderToSwapchainFS });
#endif
screenRenderGraph->Generate();
/*-----------------------------------------------------------------------*/
/* BIND RENDER GRAPH TO RENDERER */
/* GENERATE RENDER GRAPH */
/*-----------------------------------------------------------------------*/
// Add world renderer to default viewport
worldRenderer = worldViewport->AddRenderer(resourceManager, swapchain->GetNumImages(), renderContextCmdPools, descPool, SHGraphicsGlobalData::GetDescSetLayouts()[SHGraphicsConstants::DescriptorSetIndex::HIGH_FREQUENCY_GLOBALS], worldRenderGraph);
worldRenderer->SetCamera(worldCamera);
worldRenderer->SetCameraDirector(worldCameraDirector);
// Add screen renderer to default viewport
screenRenderer = worldViewport->AddRenderer(resourceManager, swapchain->GetNumImages(), renderContextCmdPools, descPool, SHGraphicsGlobalData::GetDescSetLayouts()[SHGraphicsConstants::DescriptorSetIndex::HIGH_FREQUENCY_GLOBALS], screenRenderGraph);
screenRenderer->SetCamera(screenCamera);
screenRenderer->SetCameraDirector(worldCameraDirector);
// Generate render graph
renderGraph->Generate();
// Create debug draw pipeline
debugDrawPipeline = createDebugDrawPipeline(debugDrawNode->GetRenderpass(), debugDrawSubpass, false, false, false);
@ -356,13 +363,10 @@ namespace SHADE
void SHGraphicsSystem::InitMiddleEnd(void) noexcept
{
SHGraphicsGlobalData::Init(device);
SHGraphicsPredefinedData::Init(device);
InitSceneRenderGraph();
InitRenderGraph();
#ifdef SHEDITOR
InitEditorRenderGraph();
#endif
// Create Semaphore
for (auto& semaHandle : graphSemaphores)
@ -374,7 +378,7 @@ namespace SHADE
void SHGraphicsSystem::InitSubsystems(void) noexcept
{
mousePickSystem = resourceManager.Create<SHMousePickSystem>();
mousePickSubSystem = resourceManager.Create<SHMousePickSystem>();
std::vector<Handle<SHVkCommandPool>> cmdPools;
cmdPools.reserve(swapchain->GetNumImages());
@ -382,11 +386,11 @@ namespace SHADE
cmdPools.push_back(renderContext.GetFrameData(i).cmdPoolHdls[0]);
// Mouse picking system for the editor (Will still run with editor disabled)
mousePickSystem->Init(device, cmdPools, worldRenderGraph->GetRenderGraphResource("Entity ID"));
mousePickSubSystem->Init(device, cmdPools, renderGraph->GetRenderGraphResource("Entity ID"));
// Register the post offscreen render to the system
postOffscreenRender = resourceManager.Create<SHPostOffscreenRenderSystem>();
postOffscreenRender->Init(device, worldRenderGraph->GetRenderGraphResource("Scene"), descPool);
postOffscreenRenderSubSystem = resourceManager.Create<SHPostOffscreenRenderSystem>();
postOffscreenRenderSubSystem->Init(device, renderGraph->GetRenderGraphResource("Scene"), descPool);
lightingSubSystem = resourceManager.Create<SHLightingSubSystem>();
lightingSubSystem->Init(device, descPool);
@ -394,11 +398,10 @@ namespace SHADE
textRenderingSubSystem = resourceManager.Create<SHTextRenderingSubSystem>();
// initialize the text renderer
auto uiNode = screenRenderGraph->GetNode("Screen Space Pass");
textRenderingSubSystem->Init(device, uiNode->GetRenderpass(), uiNode->GetSubpass("UI"), descPool, textVS, textFS, [=](Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex)
{
screenRenderer->BindDescSet(cmdBuffer, frameIndex);
});
auto uiNode = renderGraph->GetNode("Screen Space Pass");
textRenderingSubSystem->Init(device, uiNode->GetRenderpass(), uiNode->GetSubpass("UI"), descPool, textVS, textFS);
SHGlobalDescriptorSets::SetLightingSubSystem(lightingSubSystem);
}
@ -422,42 +425,21 @@ namespace SHADE
defaultMaterial = AddMaterial
(
defaultVertShader, defaultFragShader,
worldRenderGraph->GetNode("G-Buffer")->GetSubpass("G-Buffer Write")
renderGraph->GetNode("G-Buffer")->GetSubpass("G-Buffer Write")
);
defaultMaterial->SetProperty("data.textureIndex", defaultTexture->TextureArrayIndex);
}
#ifdef SHEDITOR
void SHGraphicsSystem::InitEditorRenderGraph(void) noexcept
void SHGraphicsSystem::InitEvents(void) noexcept
{
auto windowDims = window->GetWindowSize();
// Create Default Viewport
editorViewport = AddViewport(vk::Viewport(0.0f, 0.0f, static_cast<float>(windowDims.first), static_cast<float>(windowDims.second), 0.0f, 1.0f));
// Get render graph from viewport editor renderer
editorRenderGraph = resourceManager.Create<SHRenderGraph>();
std::vector<Handle<SHVkCommandPool>> renderContextCmdPools{ swapchain->GetNumImages() };
for (uint32_t i = 0; i < renderContextCmdPools.size(); ++i)
renderContextCmdPools[i] = renderContext.GetFrameData(i).cmdPoolHdls[0];
editorRenderGraph->Init("Editor Render Graph", device, swapchain, &resourceManager);
editorRenderGraph->AddResource("Present", { SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR_PRESENT }, windowDims.first, windowDims.second);
auto imguiNode = editorRenderGraph->AddNode("ImGui Node", { "Present"}, {});
auto imguiSubpass = imguiNode->AddSubpass("ImGui Draw");
imguiSubpass->AddColorOutput("Present");
// Generate world render graph
editorRenderGraph->Generate();
// Add world renderer to default viewport
editorRenderer = editorViewport->AddRenderer(resourceManager, swapchain->GetNumImages(), renderContextCmdPools, descPool, SHGraphicsGlobalData::GetDescSetLayouts()[SHGraphicsConstants::DescriptorSetIndex::HIGH_FREQUENCY_GLOBALS], editorRenderGraph);
editorRenderer->SetCamera(worldCamera);
std::shared_ptr<SHEventReceiverSpec<SHGraphicsSystem>> thisReceiver
{
std::make_shared<SHEventReceiverSpec<SHGraphicsSystem>>(this, &SHGraphicsSystem::ReceiveLightEnableShadowEvent)
};
ReceiverPtr receiver = std::dynamic_pointer_cast<SHEventReceiver>(thisReceiver);
SHEventManager::SubscribeTo(SH_GRAPHICS_LIGHT_ENABLE_SHADOW_EVENT, receiver);
}
#endif
/*---------------------------------------------------------------------------------*/
/* Constructor/Destructors */
@ -544,99 +526,52 @@ namespace SHADE
textRenderingSubSystem->Run(frameIndex);
// For every viewport
for (int vpIndex = 0; vpIndex < static_cast<int>(viewports.size()); ++vpIndex)
for (auto renderer : renderers)
{
auto& renderers = viewports[vpIndex]->GetRenderers();
// For every renderer
for (int renIndex = 0; renIndex < static_cast<int>(renderers.size()); ++renIndex)
#ifdef SHEDITOR
if (renderer == worldRenderer)
{
/*-----------------------------------------------------------------------*/
/* Renderer start */
/*-----------------------------------------------------------------------*/
// get command buffer of the renderer in the current frame
auto currentCmdBuffer = renderers[renIndex]->GetCommandBuffer(frameIndex);
auto editorSystem = SHSystemManager::GetSystem<SHEditor>();
if (editorSystem->editorState != SHEditor::State::PLAY)
worldRenderer->UpdateDataManual(frameIndex, cameraSystem->GetEditorCamera()->GetViewMatrix(), cameraSystem->GetEditorCamera()->GetProjMatrix());
else
renderer->UpdateData(frameIndex);
}
else
renderer->UpdateData(frameIndex);
#else
renderers[renIndex]->UpdateDataAndBind(frameIndex);
#endif
}
// Begin recording the command buffer
currentCmdBuffer->BeginRecording();
// set viewport and scissor
uint32_t w = static_cast<uint32_t>(viewports[vpIndex]->GetWidth());
uint32_t h = static_cast<uint32_t>(viewports[vpIndex]->GetHeight());
currentCmdBuffer->SetViewportScissor (static_cast<float>(w), static_cast<float>(h), w, h);
// Force set the pipeline layout
currentCmdBuffer->ForceSetPipelineLayout(SHGraphicsGlobalData::GetDummyPipelineLayout(), SH_PIPELINE_TYPE::GRAPHICS);
currentCmdBuffer->ForceSetPipelineLayout(SHGraphicsGlobalData::GetDummyPipelineLayout(), SH_PIPELINE_TYPE::COMPUTE);
renderGraph->Begin(frameIndex);
auto cmdBuffer = renderGraph->GetCommandBuffer(frameIndex);
// Bind all the buffers required for meshes
for (auto& [buffer, bindingPoint] : MESH_DATA)
{
if (buffer->GetUsageBits() & vk::BufferUsageFlagBits::eVertexBuffer)
currentCmdBuffer->BindVertexBuffer(bindingPoint, buffer, 0);
cmdBuffer->BindVertexBuffer(bindingPoint, buffer, 0);
else if (buffer->GetUsageBits() & vk::BufferUsageFlagBits::eIndexBuffer)
currentCmdBuffer->BindIndexBuffer(buffer, 0);
cmdBuffer->BindIndexBuffer(buffer, 0);
}
lightingSubSystem->BindDescSet(currentCmdBuffer, frameIndex);
renderGraph->Execute(frameIndex, descPool);
renderGraph->End(frameIndex);
// Bind textures
auto textureDescSet = texLibrary.GetTextureDescriptorSetGroup();
if (textureDescSet)
{
std::array<uint32_t, 1> texDynamicOffset {0};
currentCmdBuffer->BindDescriptorSet
(
textureDescSet,
SH_PIPELINE_TYPE::GRAPHICS,
0,
texDynamicOffset
);
}
// bind camera data
//renderers[renIndex]->UpdateDataAndBind(currentCmdBuffer, frameIndex);
#ifdef SHEDITOR
if (renderers[renIndex] == worldRenderer)
{
auto editorSystem = SHSystemManager::GetSystem<SHEditor>();
if (editorSystem->editorState != SHEditor::State::PLAY)
worldRenderer->UpdateDataAndBind(currentCmdBuffer, frameIndex, cameraSystem->GetEditorCamera()->GetViewMatrix(), cameraSystem->GetEditorCamera()->GetProjMatrix(), cameraSystem->GetEditorCamera()->GetOrthoMatrix());
else
renderers[renIndex]->UpdateDataAndBind(currentCmdBuffer, frameIndex);
}
else
renderers[renIndex]->UpdateDataAndBind(currentCmdBuffer, frameIndex);
#else
renderers[renIndex]->UpdateDataAndBind(currentCmdBuffer, frameIndex);
#endif
// Draw the scene
renderers[renIndex]->Draw(frameIndex, descPool);
// 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
(
{ currentCmdBuffer },
{ (vpIndex == viewports.size() - 1 && renIndex == renderers.size() - 1) ? frameData.semRenderFinishHdl : graphSemaphores[!semIndex] },
{ (vpIndex == 0 && renIndex == 0) ? frameData.semImgAvailableHdl : graphSemaphores[semIndex] },
{ renderGraph->GetCommandBuffer(frameIndex) },
{ frameData.semRenderFinishHdl },
{ frameData.semImgAvailableHdl },
{ vk::PipelineStageFlagBits::eColorAttachmentOutput },
{ (vpIndex == viewports.size() - 1 && renIndex == renderers.size() - 1) ? frameData.fenceHdl : Handle<SHVkFence>{} }
{ frameData.fenceHdl }
);
semIndex = !semIndex;
}
}
}
/***************************************************************************/
/*!
@ -674,12 +609,8 @@ namespace SHADE
// #BackEndTest: For for the fence initialized by queue submit
renderContext.WaitForFence();
// Finalise all batches
for (auto vp : viewports)
for (auto renderer : vp->GetRenderers())
{
renderer->GetRenderGraph()->FinaliseBatch(renderContext.GetCurrentFrame(), descPool);
}
// finalize batches for render graph
renderGraph->FinaliseBatch(renderContext.GetCurrentFrame(), descPool);
// #BackEndTest: Acquire the next image in the swapchain available
renderContext.AcquireNextIamge();
@ -720,7 +651,7 @@ namespace SHADE
const uint32_t CURR_FRAME_IDX = renderContext.GetCurrentFrame();
auto& currFrameData = renderContext.GetCurrentFrameData();
mousePickSystem->Run(graphicsQueue, CURR_FRAME_IDX);
mousePickSubSystem->Run(graphicsQueue, CURR_FRAME_IDX);
// #BackEndTest: queues an image for presentation
if (auto result = graphicsQueue->Present(swapchain, { currFrameData.semRenderFinishHdl }, CURR_FRAME_IDX); result != vk::Result::eSuccess)
@ -760,6 +691,52 @@ namespace SHADE
viewports.erase(iter);
}
/*---------------------------------------------------------------------------------*/
/* Renderer Registration Functions */
/*---------------------------------------------------------------------------------*/
Handle<SHRenderer> SHGraphicsSystem::AddRenderer(SHRenderer::PROJECTION_TYPE projectionType)
{
std::vector<Handle<SHVkCommandPool>> renderContextCmdPools{ swapchain->GetNumImages() };
for (uint32_t i = 0; i < renderContextCmdPools.size(); ++i)
{
renderContextCmdPools[i] = renderContext.GetFrameData(i).cmdPoolHdls[0];
}
// Create the renderer
auto renderer = resourceManager.Create<SHRenderer>(device, swapchain->GetNumImages(), descPool, projectionType);
// Store
renderers.emplace_back(renderer);
// Return
return renderer;
}
void SHGraphicsSystem::RemoveRenderer(Handle<SHRenderer> renderer)
{
auto iter = std::find(renderers.begin(), renderers.end(), renderer);
if (iter == renderers.end())
{
SHLOG_WARNING("Attempted to remove a Renderer that does not belong to a viewport!");
return;
}
// Remove it
iter->Free();
renderers.erase(iter);
}
SHEventHandle SHGraphicsSystem::ReceiveLightEnableShadowEvent(SHEventPtr event) noexcept
{
// Add the shadow map resource to the graph
// link resource to node. This means linking the resource and regenerating the node's renderpass and framebuffer.
// Add a subpass to render to that shadow map
//renderGraph->GetNode ();
return event->handle;
}
Handle<SHMaterial> SHGraphicsSystem::AddMaterial(Handle<SHVkShaderModule> vertShader, Handle<SHVkShaderModule> fragShader, Handle<SHSubpass> subpass)
{
// Retrieve pipeline from pipeline storage or create if unavailable
@ -883,6 +860,8 @@ namespace SHADE
);
device->WaitIdle();
graphicsTexCmdBuffer.Free(); graphicsTexCmdBuffer = {};
SHGlobalDescriptorSets::SetStaticGlobalDataDescriptorSet(texLibrary.GetTextureDescriptorSetGroup());
}
Handle<SHTexture> SHGraphicsSystem::GetTextureHandle(SHTexture::Index textureId) const
@ -900,7 +879,7 @@ namespace SHADE
void SHGraphicsSystem::BuildFonts(void) noexcept
{
fontLibrary.BuildFonts(device, graphicsQueue, graphicsCmdPool, descPool, textRenderingSubSystem->GetFontDataDescSetLayout(), resourceManager);
fontLibrary.BuildFonts(device, graphicsQueue, graphicsCmdPool, descPool, SHGraphicsPredefinedData::GetPredefinedDescSetLayouts(SHGraphicsPredefinedData::PredefinedDescSetLayoutTypes::FONT)[0], resourceManager);
}
#pragma endregion ADD_REMOVE
@ -1044,6 +1023,10 @@ namespace SHADE
graphSemaphores[0].Free();
graphSemaphores[1].Free();
for (auto& semaHandle : graphSemaphores)
semaHandle = device->CreateSemaphore();
auto windowDims = window->GetWindowSize();
// Resize the swapchain
@ -1051,23 +1034,21 @@ namespace SHADE
renderContext.HandleResize();
worldRenderGraph->HandleResize(resizeWidth, resizeHeight);
renderGraph->HandleResize(resizeWidth, resizeHeight);
#ifdef SHEDITOR
editorRenderGraph->HandleResize(windowDims.first, windowDims.second);
// NOTE: These 2 lines are actually not necessary because the editor viewport is not even used for
// setting dynamic viewport or scissor state. ImGUI takes care of that for us.
//editorViewport->SetWidth(windowDims.first);
//editorViewport->SetHeight(windowDims.second);
#endif
screenRenderGraph->HandleResize(resizeWidth, resizeHeight);
mousePickSystem->HandleResize();
postOffscreenRender->HandleResize();
mousePickSubSystem->HandleResize();
postOffscreenRenderSubSystem->HandleResize();
worldViewport->SetWidth(static_cast<float>(resizeWidth));
worldViewport->SetHeight(static_cast<float>(resizeHeight));
//worldCamera->SetPerspective(90.0f, static_cast<float>(resizeWidth), static_cast<float>(resizeHeight), 0.0f, 100.0f);
//screenCamera->SetOrthographic(static_cast<float>(resizeWidth), static_cast<float>(resizeHeight), 0.01f, 100.0f);
auto cameraSystem = SHSystemManager::GetSystem<SHCameraSystem>();
#ifdef SHEDITOR
cameraSystem->GetEditorCamera()->SetWidth(static_cast<float>(resizeWidth));
@ -1076,8 +1057,6 @@ namespace SHADE
#endif
for (auto& semaHandle : graphSemaphores)
semaHandle = device->CreateSemaphore();
}
void SHGraphicsSystem::AwaitGraphicsExecution()
@ -1091,9 +1070,14 @@ namespace SHADE
}
Handle<SHRenderGraph> SHGraphicsSystem::GetRenderGraph(void) const noexcept
{
return renderGraph;
}
Handle<SHRenderGraphNode> SHGraphicsSystem::GetPrimaryRenderpass() const noexcept
{
return worldRenderGraph->GetNode(G_BUFFER_RENDER_GRAPH_NODE_NAME.data());
return renderGraph->GetNode(G_BUFFER_RENDER_GRAPH_NODE_NAME.data());
}
Handle<SHVkPipeline> SHGraphicsSystem::GetDebugDrawPipeline(DebugDrawPipelineType type) const noexcept
@ -1126,7 +1110,7 @@ namespace SHADE
device, SHPipelineLayoutParams
{
.shaderModules = { (instanced ? debugMeshVertShader : debugVertShader) , debugFragShader },
.globalDescSetLayouts = SHGraphicsGlobalData::GetDescSetLayouts()
.predefinedDescSetLayouts = SHGraphicsPredefinedData::GetSystemData(SHGraphicsPredefinedData::SystemType::BATCHING).descSetLayouts
}
);
auto pipeline = resourceManager.Create<SHVkPipeline>(device, pipelineLayout, nullptr, renderPass, subpass);

View File

@ -34,6 +34,8 @@ of DigiPen Institute of Technology is prohibited.
#include "Graphics/MiddleEnd/PostProcessing/SHSSAO.h"
#include "Camera/SHCameraDirector.h"
#include "Graphics/MiddleEnd/TextRendering/SHFontLibrary.h"
#include "Graphics/MiddleEnd/Interface/SHRenderer.h"
#include "Graphics/Events/SHGraphicsEvents.h"
namespace SHADE
{
@ -49,9 +51,7 @@ namespace SHADE
class SHVkImage;
class SHVkFramebuffer;
class SHVkCommandBuffer;
class SHRenderer;
class SHViewport;
class SHCamera;
class SHVkShaderModule;
class SHMaterial;
class SHMaterialInstance;
@ -99,14 +99,11 @@ namespace SHADE
{
private:
void InitBoilerplate (void) noexcept;
void InitSceneRenderGraph (void) noexcept;
void InitRenderGraph (void) noexcept;
void InitMiddleEnd (void) noexcept;
void InitSubsystems (void) noexcept;
void InitBuiltInResources (void);
#ifdef SHEDITOR
void InitEditorRenderGraph (void) noexcept;
#endif
void InitEvents (void) noexcept;
public:
class SH_API BeginRoutine final : public SHSystemRoutine
@ -171,6 +168,17 @@ namespace SHADE
Handle<SHViewport> AddViewport(const vk::Viewport& viewport);
void RemoveViewport(Handle<SHViewport> viewport);
/*-----------------------------------------------------------------------------*/
/* Renderers Registration Functions */
/*-----------------------------------------------------------------------------*/
Handle<SHRenderer> AddRenderer(SHRenderer::PROJECTION_TYPE projectionType);
void RemoveRenderer(Handle<SHRenderer> renderer);
/*-----------------------------------------------------------------------*/
/* Light functions */
/*-----------------------------------------------------------------------*/
SHEventHandle ReceiveLightEnableShadowEvent (SHEventPtr event) noexcept;
/*-----------------------------------------------------------------------------*/
/* Material Functions */
/*-----------------------------------------------------------------------------*/
@ -382,8 +390,9 @@ namespace SHADE
#ifdef SHEDITOR
Handle<SHViewport> GetEditorViewport () const {return editorViewport;};
#endif
Handle<SHMousePickSystem> GetMousePickSystem(void) const noexcept {return mousePickSystem;};
Handle<SHPostOffscreenRenderSystem> GetPostOffscreenRenderSystem(void) const noexcept {return postOffscreenRender;};
Handle<SHMousePickSystem> GetMousePickSystem(void) const noexcept {return mousePickSubSystem;};
Handle<SHPostOffscreenRenderSystem> GetPostOffscreenRenderSystem(void) const noexcept {return postOffscreenRenderSubSystem;};
Handle<SHRenderGraph> GetRenderGraph (void) const noexcept;
Handle<SHRenderGraphNode> GetPrimaryRenderpass() const noexcept;
Handle<SHVkPipeline> GetDebugDrawPipeline(DebugDrawPipelineType type) const noexcept;
uint32_t GetCurrentFrameIndex(void) const noexcept { return renderContext.GetCurrentFrame(); }
@ -441,10 +450,8 @@ namespace SHADE
// Renderers
Handle<SHRenderer> worldRenderer;
Handle<SHRenderer> screenRenderer;
std::vector<Handle<SHRenderer>> renderers;
// Temp Cameras
Handle<SHCamera> worldCamera;
Handle<SHCamera> screenCamera;
DirectorHandle worldCameraDirector;
@ -483,15 +490,15 @@ namespace SHADE
std::array<Handle<SHMesh>, MAX_PRIMITIVE_TYPES> primitiveMeshes;
// Render Graphs
Handle<SHRenderGraph> worldRenderGraph;
Handle<SHRenderGraph> screenRenderGraph;
Handle<SHRenderGraph> renderGraph;
//Handle<SHRenderGraph> screenRenderGraph;
#ifdef SHEDITOR
Handle<SHRenderGraph> editorRenderGraph;
//Handle<SHRenderGraph> editorRenderGraph;
#endif
// Sub systems
Handle<SHMousePickSystem> mousePickSystem;
Handle<SHPostOffscreenRenderSystem> postOffscreenRender;
Handle<SHMousePickSystem> mousePickSubSystem;
Handle<SHPostOffscreenRenderSystem> postOffscreenRenderSubSystem;
Handle<SHLightingSubSystem> lightingSubSystem;
Handle<SHTextRenderingSubSystem> textRenderingSubSystem;
Handle<SHSSAO> ssaoStorage;

View File

@ -9,6 +9,8 @@
#include "ECS_Base/Managers/SHSystemManager.h"
#include "SHGraphicsSystem.h"
#include "SHMaterialInstance.h"
#include "Graphics/MiddleEnd/GlobalData/SHGraphicsPredefinedData.h"
namespace SHADE
{
@ -95,9 +97,11 @@ namespace SHADE
/*-----------------------------------------------------------------------------------*/
Handle<SHShaderBlockInterface> SHMaterial::GetShaderBlockInterface() const noexcept
{
auto const& mappings = SHGraphicsPredefinedData::GetMappings(SHGraphicsPredefinedData::SystemType::BATCHING);
return pipeline->GetPipelineLayout()->GetShaderBlockInterface
(
SHGraphicsConstants::DescriptorSetIndex::PER_INSTANCE,
mappings.at (SHPredefinedDescriptorTypes::MATERIALS),
//SHGraphicsConstants::DescriptorSetIndex::PER_INSTANCE,
SHGraphicsConstants::DescriptorSetBindings::BATCHED_PER_INST_DATA,
vk::ShaderStageFlagBits::eFragment
);

View File

@ -16,6 +16,7 @@ of DigiPen Institute of Technology is prohibited.
#include "SHMaterial.h"
#include "Graphics/Pipeline/SHVkPipeline.h"
#include "Tools/Logger/SHLogger.h"
#include "Graphics/MiddleEnd/GlobalData/SHGraphicsPredefinedData.h"
namespace SHADE
{
@ -80,7 +81,8 @@ namespace SHADE
{
return baseMaterial->GetPipeline()->GetPipelineLayout()->GetShaderBlockInterface
(
SHGraphicsConstants::DescriptorSetIndex::PER_INSTANCE,
SHGraphicsPredefinedData::GetMappings(SHGraphicsPredefinedData::SystemType::BATCHING).at(SHPredefinedDescriptorTypes::MATERIALS),
//SHGraphicsConstants::DescriptorSetIndex::PER_INSTANCE,
SHGraphicsConstants::DescriptorSetBindings::BATCHED_PER_INST_DATA,
vk::ShaderStageFlagBits::eFragment
);

View File

@ -56,7 +56,7 @@ namespace SHADE
};
// Create descriptor set layout
offscreenRenderDescSetLayout = logicalDevice->CreateDescriptorSetLayout(0, { imageBinding }, false);
offscreenRenderDescSetLayout = logicalDevice->CreateDescriptorSetLayout({ imageBinding }, false);
// Create descriptor set
offscreenRenderDescSet = descriptorPool->Allocate({ offscreenRenderDescSetLayout }, { 1 });

View File

@ -14,7 +14,6 @@ of DigiPen Institute of Technology is prohibited.
#include "SHRenderer.h"
#include "Graphics/Devices/SHVkLogicalDevice.h"
#include "SHViewport.h"
#include "Graphics/Buffers/SHVkBuffer.h"
#include "Graphics/Framebuffer/SHVkFramebuffer.h"
#include "SHMaterial.h"
@ -22,22 +21,22 @@ of DigiPen Institute of Technology is prohibited.
#include "Graphics/Descriptors/SHVkDescriptorSetGroup.h"
#include "Graphics/Buffers/SHVkBuffer.h"
#include "Camera/SHCameraDirector.h"
#include "Graphics/MiddleEnd/GlobalData/SHGraphicsPredefinedData.h"
namespace SHADE
{
/*-----------------------------------------------------------------------------------*/
/* Constructor/Destructors */
/*-----------------------------------------------------------------------------------*/
SHRenderer::SHRenderer(Handle<SHVkLogicalDevice> logicalDevice, uint32_t numFrames, std::vector<Handle<SHVkCommandPool>>& cmdPools, Handle<SHVkDescriptorPool> descriptorPool, Handle<SHVkDescriptorSetLayout> cameraDescLayout, Handle<SHViewport> viewport, Handle<SHRenderGraph> renderGraph)
: viewport { viewport }
, renderGraph { renderGraph }
SHRenderer::SHRenderer(Handle<SHVkLogicalDevice> logicalDevice, uint32_t numFrames, Handle<SHVkDescriptorPool> descriptorPool, PROJECTION_TYPE type)
: projectionType{type}
{
commandBuffers.resize(static_cast<std::size_t>(numFrames));
//commandBuffers.resize(static_cast<std::size_t>(numFrames));
for (uint32_t i = 0; i < commandBuffers.size(); ++i)
commandBuffers[i] = cmdPools[i]->RequestCommandBuffer(SH_CMD_BUFFER_TYPE::PRIMARY);
//for (uint32_t i = 0; i < commandBuffers.size(); ++i)
// commandBuffers[i] = cmdPools[i]->RequestCommandBuffer(SH_CMD_BUFFER_TYPE::PRIMARY);
cameraDescriptorSet = descriptorPool->Allocate({ cameraDescLayout }, { 1 });
cameraDescriptorSet = descriptorPool->Allocate(SHGraphicsPredefinedData::GetPredefinedDescSetLayouts(SHGraphicsPredefinedData::PredefinedDescSetLayoutTypes::CAMERA), { 1 });
#ifdef _DEBUG
const auto& CAM_DESC_SETS = cameraDescriptorSet->GetVkHandle();
@ -51,25 +50,16 @@ namespace SHADE
std::array cameraBufferArray{cameraBuffer};
cameraDescriptorSet->ModifyWriteDescBuffer(SHGraphicsConstants::DescriptorSetIndex::HIGH_FREQUENCY_GLOBALS, SHGraphicsConstants::DescriptorSetBindings::CAMERA_DATA, std::span<Handle<SHVkBuffer>>{ cameraBufferArray.data(), cameraBufferArray.size()}, 0, sizeof (SHShaderCameraData));
// We use index 0 because the descriptor set is standalone created from a single desc set layout. What the driver sees is that this set is at index 0 during updating.
static constexpr uint8_t SET_0 = 0;
cameraDescriptorSet->UpdateDescriptorSetBuffer(SHGraphicsConstants::DescriptorSetIndex::HIGH_FREQUENCY_GLOBALS, SHGraphicsConstants::DescriptorSetBindings::CAMERA_DATA);
cameraDescriptorSet->ModifyWriteDescBuffer(SET_0, SHGraphicsConstants::DescriptorSetBindings::CAMERA_DATA, std::span<Handle<SHVkBuffer>>{ cameraBufferArray.data(), cameraBufferArray.size()}, 0, sizeof (SHShaderCameraData));
cameraDescriptorSet->UpdateDescriptorSetBuffer(SET_0, SHGraphicsConstants::DescriptorSetBindings::CAMERA_DATA);
}
SHRenderer::~SHRenderer(void)
{
//for (auto& cmdBuffer : commandBuffers)
//{
// cmdBuffer.Free();
//}
}
/*-----------------------------------------------------------------------------------*/
/* Camera Registration */
/*-----------------------------------------------------------------------------------*/
void SHRenderer::SetCamera(Handle<SHCamera> _camera)
{
camera = _camera;
}
void SHRenderer::SetCameraDirector(Handle<SHCameraDirector> director) noexcept
@ -77,63 +67,55 @@ namespace SHADE
cameraDirector = director;
}
/*-----------------------------------------------------------------------------------*/
/* Drawing Functions */
/*-----------------------------------------------------------------------------------*/
void SHRenderer::Draw(uint32_t frameIndex, Handle<SHVkDescriptorPool> descPool) noexcept
void SHRenderer::UpdateData(uint32_t frameIndex) noexcept
{
renderGraph->Execute(frameIndex, commandBuffers[frameIndex], descPool);
if (cameraDirector)
{
switch (projectionType)
{
case PROJECTION_TYPE::DEFAULT:
UpdateDataManual(frameIndex, cameraDirector->GetViewMatrix(), cameraDirector->GetProjMatrix());
break;
case PROJECTION_TYPE::PERSPECTIVE:
UpdateDataManual(frameIndex, cameraDirector->GetViewMatrix(), cameraDirector->GetPerspectiveMatrix());
break;
case PROJECTION_TYPE::ORTHOGRAPHIC:
UpdateDataManual(frameIndex, cameraDirector->GetViewMatrix(), cameraDirector->GetOrthoMatrix());
break;
default:
UpdateDataManual(frameIndex, cameraDirector->GetViewMatrix(), cameraDirector->GetProjMatrix());
break;
}
void SHRenderer::UpdateDataAndBind(Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex) noexcept
{
if (camera && cameraDirector)
{
//UpdateDataAndBind(cmdBuffer, frameIndex, SHMatrix::Transpose(cameraDirector->GetVPMatrix()));
UpdateDataAndBind(cmdBuffer, frameIndex, cameraDirector->GetViewMatrix(), cameraDirector->GetProjMatrix(), cameraDirector->GetOrthoMatrix());
}
}
void SHRenderer::UpdateDataAndBind(Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex, SHMatrix const& viewMatrix, SHMatrix const& projMatrix, SHMatrix const& orthoMatrix) noexcept
void SHRenderer::UpdateDataManual(uint32_t frameIndex, SHMatrix const& viewMatrix, SHMatrix const& projMatrix) noexcept
{
SetViewProjectionMatrix(viewMatrix, projMatrix, orthoMatrix);
SetViewProjectionMatrix(viewMatrix, projMatrix);
//cpuCameraData.viewProjectionMatrix = camera->GetViewProjectionMatrix();
cameraBuffer->WriteToMemory(&cpuCameraData, sizeof(SHShaderCameraData), 0, cameraDataAlignedSize * frameIndex);
BindDescSet(cmdBuffer, frameIndex);
//BindDescSet(cmdBuffer, frameIndex);
}
void SHRenderer::BindDescSet(Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex) noexcept
void SHRenderer::BindDescriptorSet(Handle<SHVkCommandBuffer> cmdBuffer, SH_PIPELINE_TYPE pipelineType, uint32_t setIndex, uint32_t frameIndex) noexcept
{
std::array<uint32_t, 1> dynamicOffsets{ frameIndex * cameraDataAlignedSize };
cmdBuffer->BindDescriptorSet(cameraDescriptorSet, SH_PIPELINE_TYPE::GRAPHICS, SHGraphicsConstants::DescriptorSetIndex::HIGH_FREQUENCY_GLOBALS, std::span{ dynamicOffsets.data(), 1 });
cmdBuffer->BindDescriptorSet(cameraDescriptorSet, SH_PIPELINE_TYPE::COMPUTE, SHGraphicsConstants::DescriptorSetIndex::HIGH_FREQUENCY_GLOBALS, std::span{ dynamicOffsets.data(), 1 });
cmdBuffer->BindDescriptorSet(cameraDescriptorSet, pipelineType, setIndex, std::span{ dynamicOffsets.data(), 1 });
}
void SHRenderer::UpdateCameraDataToBuffer(void) noexcept
void SHRenderer::SetViewProjectionMatrix(SHMatrix const& viewMatrix, SHMatrix const& projMatrix) noexcept
{
}
void SHRenderer::SetViewProjectionMatrix(SHMatrix const& viewMatrix, SHMatrix const& projMatrix, SHMatrix const& orthoMatrix) noexcept
{
//cpuCameraData.viewProjectionMatrix = camera->GetViewMatrix() * camera->GetProjectionMatrix();
cpuCameraData.viewProjectionMatrix = SHMatrix::Transpose(projMatrix * viewMatrix);
cpuCameraData.viewMatrix = SHMatrix::Transpose(viewMatrix);
cpuCameraData.projectionMatrix = SHMatrix::Transpose(projMatrix);
cpuCameraData.orthoMatrix = SHMatrix::Transpose (orthoMatrix);
}
Handle<SHRenderGraph> SHRenderer::GetRenderGraph(void) const noexcept
{
return renderGraph;
}
Handle<SHVkCommandBuffer> SHRenderer::GetCommandBuffer(uint32_t frameIndex) const noexcept
{
return commandBuffers[frameIndex];
}
//Handle<SHVkCommandBuffer> SHRenderer::GetCommandBuffer(uint32_t frameIndex) const noexcept
//{
// return commandBuffers[frameIndex];
//}
Handle<SHCameraDirector> SHRenderer::GetCameraDirector(void) const noexcept
{

View File

@ -32,12 +32,11 @@ namespace SHADE
class SHVkFramebuffer;
class SHMaterial;
class SHVkLogicalDevice;
class SHViewport;
class SHVkImageView;
class SHVkCommandBuffer;
class SHCamera;
class SHVkDescriptorSetGroup;
class SHGraphicsGlobalData;
class SHGraphicsPredefinedData;
class SHVkDescriptorPool;
class SHVkBuffer;
class SHCameraDirector;
@ -48,7 +47,6 @@ namespace SHADE
SHMatrix viewProjectionMatrix;
SHMatrix viewMatrix;
SHMatrix projectionMatrix;
SHMatrix orthoMatrix;
};
/*---------------------------------------------------------------------------------*/
@ -64,35 +62,36 @@ namespace SHADE
/***********************************************************************************/
class SHRenderer
{
public:
enum class PROJECTION_TYPE
{
DEFAULT,
PERSPECTIVE,
ORTHOGRAPHIC
};
/*-----------------------------------------------------------------------------*/
/* Constructor/Destructors */
/*-----------------------------------------------------------------------------*/
SHRenderer(Handle<SHVkLogicalDevice> logicalDevice, uint32_t numFrames, std::vector<Handle<SHVkCommandPool>>& cmdPools, Handle<SHVkDescriptorPool> descriptorPool, Handle<SHVkDescriptorSetLayout> cameraDescLayout, Handle<SHViewport> viewport, Handle<SHRenderGraph> renderGraph);
SHRenderer(Handle<SHVkLogicalDevice> logicalDevice, uint32_t numFrames, Handle<SHVkDescriptorPool> descriptorPool, PROJECTION_TYPE type);
~SHRenderer(void);
/*-----------------------------------------------------------------------------*/
/* Camera Registration */
/*-----------------------------------------------------------------------------*/
void SetCamera(Handle<SHCamera> _camera);
void SetCameraDirector (Handle<SHCameraDirector> director) noexcept;
/*-----------------------------------------------------------------------------*/
/* Drawing Functions */
/*-----------------------------------------------------------------------------*/
void Draw(uint32_t frameIndex, Handle<SHVkDescriptorPool> descPool) noexcept;
void UpdateDataAndBind(Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex) noexcept;
void UpdateDataAndBind(Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex, SHMatrix const& viewMatrix, SHMatrix const& projMatrix, SHMatrix const& orthoMatrix) noexcept;
void BindDescSet (Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex) noexcept;
void UpdateCameraDataToBuffer (void) noexcept;
void SetViewProjectionMatrix (SHMatrix const& viewMatrix, SHMatrix const& projMatrix, SHMatrix const& orthoMatrix) noexcept;
void UpdateData(uint32_t frameIndex) noexcept;
void UpdateDataManual(uint32_t frameIndex, SHMatrix const& viewMatrix, SHMatrix const& projMatrix) noexcept;
void BindDescriptorSet (Handle<SHVkCommandBuffer> cmdBuffer, SH_PIPELINE_TYPE pipelineType, uint32_t setIndex, uint32_t frameIndex) noexcept;
void SetViewProjectionMatrix (SHMatrix const& viewMatrix, SHMatrix const& projMatrix) noexcept;
/*-----------------------------------------------------------------------------*/
/* Setters and Getters */
/*-----------------------------------------------------------------------------*/
Handle<SHRenderGraph> GetRenderGraph (void) const noexcept;
Handle<SHVkCommandBuffer> GetCommandBuffer(uint32_t frameIndex) const noexcept;
Handle<SHCameraDirector> GetCameraDirector (void) const noexcept;
private:
@ -102,9 +101,6 @@ namespace SHADE
//! Vulkan UBOs need to be aligned, this is pad SHShaderCameraData struct
uint32_t cameraDataAlignedSize;
Handle<SHViewport> viewport;
Handle<SHCamera> camera;
Handle<SHRenderGraph> renderGraph;
Handle<SHVkDescriptorSetGroup> cameraDescriptorSet;
Handle<SHVkBuffer> cameraBuffer;
@ -114,10 +110,10 @@ namespace SHADE
// GPU.
SHShaderCameraData cpuCameraData;
//! Command buffers for the render graph
std::vector<Handle<SHVkCommandBuffer>> commandBuffers;
////! Command buffers for the render graph
//std::vector<Handle<SHVkCommandBuffer>> commandBuffers;
PROJECTION_TYPE projectionType;
};
}

View File

@ -46,34 +46,6 @@ namespace SHADE
);
}
/*---------------------------------------------------------------------------------*/
/* Renderer Registration Functions */
/*---------------------------------------------------------------------------------*/
Handle<SHRenderer> SHViewport::AddRenderer(SHResourceHub& resourceManager, uint32_t numFrames, std::vector<Handle<SHVkCommandPool>>& cmdPools, Handle<SHVkDescriptorPool> descriptorPool, Handle<SHVkDescriptorSetLayout> cameraDescLayout, Handle<SHRenderGraph> renderGraph)
{
// Create the renderer
auto renderer = resourceManager.Create<SHRenderer>(device, numFrames, cmdPools, descriptorPool, cameraDescLayout, GetHandle(), renderGraph);
// Store
renderers.emplace_back(renderer);
// Return
return renderer;
}
void SHViewport::RemoveRenderer(Handle<SHRenderer> renderer)
{
auto iter = std::find(renderers.begin(), renderers.end(), renderer);
if (iter == renderers.end())
{
SHLOG_WARNING("Attempted to remove a Renderer that does not belong to a viewport!");
return;
}
// Remove it
iter->Free();
renderers.erase(iter);
}
void SHViewport::SetWidth(float w) noexcept
{
viewport.width = w;

View File

@ -56,11 +56,11 @@ namespace SHADE
/*-----------------------------------------------------------------------------*/
void SetUp(Handle<SHVkCommandBuffer> commandBuffer);
/*-----------------------------------------------------------------------------*/
/* Renderers Registration Functions */
/*-----------------------------------------------------------------------------*/
Handle<SHRenderer> AddRenderer(SHResourceHub& resourceManager, uint32_t numFrames, std::vector<Handle<SHVkCommandPool>>& cmdPools, Handle<SHVkDescriptorPool> descriptorPool, Handle<SHVkDescriptorSetLayout> cameraDescLayout, Handle<SHRenderGraph> renderGraph);
void RemoveRenderer(Handle<SHRenderer> renderer);
///*-----------------------------------------------------------------------------*/
///* Renderers Registration Functions */
///*-----------------------------------------------------------------------------*/
//Handle<SHRenderer> AddRenderer(SHResourceHub& resourceManager, uint32_t numFrames, std::vector<Handle<SHVkCommandPool>>& cmdPools, Handle<SHVkDescriptorPool> descriptorPool, Handle<SHVkDescriptorSetLayout> cameraDescLayout, Handle<SHRenderGraph> renderGraph);
//void RemoveRenderer(Handle<SHRenderer> renderer);
/*-----------------------------------------------------------------------------*/
/* Setters */
@ -79,7 +79,7 @@ namespace SHADE
float GetHeight() const { return viewport.height; }
float GetMinDepth() const { return viewport.minDepth; }
float GetMaxDepth() const { return viewport.maxDepth; }
std::vector<Handle<SHRenderer>>& GetRenderers() { return renderers; }
//std::vector<Handle<SHRenderer>>& GetRenderers() { return renderers; }
private:
@ -88,7 +88,7 @@ namespace SHADE
/*-----------------------------------------------------------------------------*/
Handle<SHVkLogicalDevice> device;
vk::Viewport viewport;
std::vector<Handle<SHRenderer>> renderers;
//std::vector<Handle<SHRenderer>> renderers;
};
}

View File

@ -1,5 +1,7 @@
#include "SHpch.h"
#include "SHLightComponent.h"
#include "Graphics/Events/SHGraphicsEvents.h"
#include "Events/SHEventManager.hpp"
namespace SHADE
{
@ -104,6 +106,21 @@ namespace SHADE
//MakeDirty();
}
void SHLightComponent::SetEnableShadow(bool flag) noexcept
{
lightData.castShadows = flag;
// If the flag is true
if (flag && lightData.shadowMapIndex == SHLightData::INVALID_SHADOW_MAP_INDEX)
{
// Create new event and broadcast it
SHLightEnableShadowEvent newEvent;
newEvent.lightEntity = GetEID();
SHEventManager::BroadcastEvent<SHLightEnableShadowEvent>(newEvent, SH_GRAPHICS_LIGHT_ENABLE_SHADOW_EVENT);
}
}
SHLightData const& SHLightComponent::GetLightData(void) const noexcept
{
return lightData;

View File

@ -25,7 +25,6 @@ namespace SHADE
////! If the light's data is already in the buffers, this will be set to true.
//bool bound;
public:
/*-----------------------------------------------------------------------*/
/* LIFECYCLE FUNCTIONS */
@ -49,6 +48,7 @@ namespace SHADE
//void Unbind (void) noexcept;
//void SetBound (uint32_t inIndexInBuffer) noexcept;
void SetStrength (float value) noexcept; // serialized
void SetEnableShadow (bool flag) noexcept;
SHLightData const& GetLightData (void) const noexcept;
@ -59,7 +59,7 @@ namespace SHADE
uint32_t const& GetCullingMask (void) const noexcept; // serialized
//bool IsDirty (void) const noexcept;
//bool GetBound (void) const noexcept;
uint32_t GetIndexInBuffer (void) const noexcept;
//uint32_t GetIndexInBuffer (void) const noexcept;
float GetStrength (void) const noexcept;
RTTR_ENABLE()
};

View File

@ -16,6 +16,12 @@ namespace SHADE
// Diffuse color set to 1
color = SHVec4::One;
// light will default not cast shadows
castShadows = false;
// shadow map index is invalid.
shadowMapIndex = INVALID_SHADOW_MAP_INDEX;
}
}

View File

@ -26,6 +26,8 @@ namespace SHADE
/***************************************************************************/
struct SHLightData
{
static constexpr uint32_t INVALID_SHADOW_MAP_INDEX = std::numeric_limits<uint32_t>::max();
//! position of the light
SHVec3 position;
@ -46,6 +48,13 @@ namespace SHADE
//! Strength of the light
float strength;
//! Whether or not the light will cast a shadow. More technically, whether or
//! not the light will result in the addition of a depth map into the render graph
//! to be used for shadow mapping calculations.
bool castShadows;
//! Index of the shadow map when it gets placed in the descriptor array of textures (that are all shadow maps).
uint32_t shadowMapIndex;
void Reset (void) noexcept;
//! TODO:

View File

@ -1,6 +1,6 @@
#include "SHpch.h"
#include "SHLightingSubSystem.h"
#include "Graphics/MiddleEnd/GlobalData/SHGraphicsGlobalData.h"
#include "Graphics/MiddleEnd/GlobalData/SHGraphicsPredefinedData.h"
#include "Tools/Utilities/SHUtilities.h"
#include "Graphics/Devices/SHVkLogicalDevice.h"
#include "Graphics/Buffers/SHVkBuffer.h"
@ -320,15 +320,16 @@ namespace SHADE
void SHLightingSubSystem::UpdateDescSet(uint32_t binding) noexcept
{
auto buffer = perTypeData[binding].GetDataBuffer();
static constexpr uint32_t LIGHTING_DATA_SET_INDEX = 0;
// We bind the buffer with the correct desc set binding
lightingDataDescSet->ModifyWriteDescBuffer(SHGraphicsConstants::DescriptorSetIndex::DYNAMIC_GLOBALS,
lightingDataDescSet->ModifyWriteDescBuffer(LIGHTING_DATA_SET_INDEX,
binding + 1, // we want to +1 here because the first binding is reserved for count
{ &buffer, 1 },
0,
perTypeData[binding].GetDataSize() * perTypeData[binding].GetMaxLights());
lightingDataDescSet->UpdateDescriptorSetBuffer(SHGraphicsConstants::DescriptorSetIndex::DYNAMIC_GLOBALS, binding + 1); // +1 here, same reason. see above
lightingDataDescSet->UpdateDescriptorSetBuffer(LIGHTING_DATA_SET_INDEX, binding + 1); // +1 here, same reason. see above
}
/***************************************************************************/
@ -385,7 +386,7 @@ namespace SHADE
std::fill (variableSizes.begin(), variableSizes.end(), 1);
// Create the descriptor set
lightingDataDescSet = descPool->Allocate({ SHGraphicsGlobalData::GetDescSetLayouts()[SHGraphicsConstants::DescriptorSetIndex::DYNAMIC_GLOBALS] }, variableSizes);
lightingDataDescSet = descPool->Allocate({ SHGraphicsPredefinedData::GetPredefinedDescSetLayouts(SHGraphicsPredefinedData::PredefinedDescSetLayoutTypes::LIGHTS) }, variableSizes);
#ifdef _DEBUG
const auto& CAM_DESC_SETS = lightingDataDescSet->GetVkHandle();
for (int i = 0; i < static_cast<int>(CAM_DESC_SETS.size()); ++i)
@ -408,8 +409,9 @@ namespace SHADE
// Create the GPU buffer to hold light count
lightCountsBuffer = logicalDevice->CreateBuffer(lightCountsAlignedSize * SHGraphicsConstants::NUM_FRAME_BUFFERS, nullptr, lightCountsAlignedSize * SHGraphicsConstants::NUM_FRAME_BUFFERS, vk::BufferUsageFlagBits::eUniformBuffer, VMA_MEMORY_USAGE_AUTO, VMA_ALLOCATION_CREATE_MAPPED_BIT | VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT, "Light Count Data");
lightingDataDescSet->ModifyWriteDescBuffer(SHGraphicsConstants::DescriptorSetIndex::DYNAMIC_GLOBALS, SHGraphicsConstants::DescriptorSetBindings::LIGHTING_COUNT, {&lightCountsBuffer, 1}, 0, sizeof (uint32_t) * NUM_LIGHT_TYPES);
lightingDataDescSet->UpdateDescriptorSetBuffer(SHGraphicsConstants::DescriptorSetIndex::DYNAMIC_GLOBALS, SHGraphicsConstants::DescriptorSetBindings::LIGHTING_COUNT);
static constexpr uint32_t LIGHTING_DATA_SET_INDEX = 0;
lightingDataDescSet->ModifyWriteDescBuffer(LIGHTING_DATA_SET_INDEX, SHGraphicsConstants::DescriptorSetBindings::LIGHTING_COUNT, { &lightCountsBuffer, 1 }, 0, sizeof(uint32_t) * NUM_LIGHT_TYPES);
lightingDataDescSet->UpdateDescriptorSetBuffer(LIGHTING_DATA_SET_INDEX, SHGraphicsConstants::DescriptorSetBindings::LIGHTING_COUNT);
for (uint32_t i = 0; i < SHGraphicsConstants::NUM_FRAME_BUFFERS; ++i)
{
@ -517,11 +519,16 @@ namespace SHADE
}
void SHLightingSubSystem::BindDescSet(Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex) noexcept
void SHLightingSubSystem::BindDescSet(Handle<SHVkCommandBuffer> cmdBuffer, uint32_t setIndex, uint32_t frameIndex) noexcept
{
//Bind descriptor set(We bind at an offset because the buffer holds NUM_FRAME_BUFFERS sets of data).
cmdBuffer->BindDescriptorSet(lightingDataDescSet, SH_PIPELINE_TYPE::COMPUTE, SHGraphicsConstants::DescriptorSetIndex::DYNAMIC_GLOBALS, { dynamicOffsets[frameIndex] });
cmdBuffer->BindDescriptorSet(lightingDataDescSet, SH_PIPELINE_TYPE::COMPUTE, setIndex, { dynamicOffsets[frameIndex] });
}
Handle<SHVkDescriptorSetGroup> SHLightingSubSystem::GetLightDataDescriptorSet(void) const noexcept
{
return lightingDataDescSet;
}
}

View File

@ -4,6 +4,7 @@
#include "Math/Vector/SHVec3.h"
#include "Math/Vector/SHVec4.h"
#include "SHLightData.h"
#include <array>
#include "Graphics/MiddleEnd/Interface/SHGraphicsConstants.h"
namespace SHADE
@ -57,8 +58,11 @@ namespace SHADE
class SH_API SHLightingSubSystem
{
private:
public:
using DynamicOffsetArray = std::array<std::vector<uint32_t>, static_cast<uint32_t>(SHGraphicsConstants::NUM_FRAME_BUFFERS)>;
private:
class PerTypeData
{
private:
@ -130,7 +134,7 @@ namespace SHADE
std::array<PerTypeData, static_cast<uint32_t>(SH_LIGHT_TYPE::NUM_TYPES)> perTypeData;
//! Container to store dynamic offsets for binding descriptor sets
std::array<std::vector<uint32_t>, static_cast<uint32_t>(SHGraphicsConstants::NUM_FRAME_BUFFERS)> dynamicOffsets;
DynamicOffsetArray dynamicOffsets;
//! holds the data that represents how many lights are in the scene
std::array<uint32_t, static_cast<uint32_t>(SH_LIGHT_TYPE::NUM_TYPES)> lightCountsData;
@ -162,7 +166,8 @@ namespace SHADE
void Run (SHMatrix const& viewMat, uint32_t frameIndex) noexcept;
void Exit (void) noexcept;
void BindDescSet (Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex) noexcept;
void BindDescSet (Handle<SHVkCommandBuffer> cmdBuffer, uint32_t setIndex, uint32_t frameIndex) noexcept;
Handle<SHVkDescriptorSetGroup> GetLightDataDescriptorSet (void) const noexcept;
};
}

View File

@ -1,7 +1,7 @@
#include "SHpch.h"
#include "SHPipelineLibrary.h"
#include "Graphics/Devices/SHVkLogicalDevice.h"
#include "Graphics/MiddleEnd/GlobalData/SHGraphicsGlobalData.h"
#include "Graphics/MiddleEnd/GlobalData/SHGraphicsPredefinedData.h"
#include "Graphics/RenderGraph/SHSubpass.h"
#include "Graphics/SHVkUtil.h"
@ -13,7 +13,7 @@ namespace SHADE
SHPipelineLayoutParams params
{
.shaderModules = {vsFsPair.first, vsFsPair.second},
.globalDescSetLayouts = SHGraphicsGlobalData::GetDescSetLayouts()
.predefinedDescSetLayouts = SHGraphicsPredefinedData::GetSystemData(SHGraphicsPredefinedData::SystemType::BATCHING).descSetLayouts
};
// Create the pipeline layout
@ -21,7 +21,7 @@ namespace SHADE
// Create the pipeline and configure the default vertex input state
auto newPipeline = logicalDevice->CreateGraphicsPipeline(pipelineLayout, nullptr, renderpass, subpass);
newPipeline->GetPipelineState().SetVertexInputState(SHGraphicsGlobalData::GetDefaultViState());
newPipeline->GetPipelineState().SetVertexInputState(SHGraphicsPredefinedData::GetDefaultViState());
SHColorBlendState colorBlendState{};
colorBlendState.logic_op_enable = VK_FALSE;

View File

@ -10,7 +10,7 @@ namespace SHADE
class SHVkDescriptorSetLayouts;
class SHVkPipeline;
class SHSubpass;
class SHGraphicsGlobalData;
class SHGraphicsPredefinedData;
// Pipeline library is a PURELY MIDDLE END SYSTEM. It is responsible for only creating pipelines from shaders and caching
// them so that they don't need to be recreated again.

View File

@ -1,7 +1,7 @@
#include "SHpch.h"
#include "SHFont.h"
#include "Graphics/Devices/SHVkLogicalDevice.h"
#include "Graphics/MiddleEnd/GlobalData/SHGraphicsGlobalData.h"
#include "Graphics/MiddleEnd/GlobalData/SHGraphicsPredefinedData.h"
#include "Graphics/Descriptors/SHVkDescriptorSetGroup.h"
#include "Graphics/Buffers/SHVkBuffer.h"
#include "Graphics/Images/SHVkSampler.h"
@ -121,17 +121,23 @@ namespace SHADE
descSet = descPool->Allocate({ layout }, { 1 });
auto viewLayoutSampler = std::make_tuple(bitmapDataImageView, sampler, vk::ImageLayout::eShaderReadOnlyOptimal);
descSet->ModifyWriteDescImage(SHGraphicsConstants::DescriptorSetIndex::FONT_DATA, SHGraphicsConstants::DescriptorSetBindings::FONT_BITMAP_DATA, {&viewLayoutSampler, 1});
static constexpr uint32_t FONT_DATA_SET_INDEX = 0;
descSet->ModifyWriteDescImage(FONT_DATA_SET_INDEX, SHGraphicsConstants::DescriptorSetBindings::FONT_BITMAP_DATA, {&viewLayoutSampler, 1});
descSet->ModifyWriteDescBuffer(SHGraphicsConstants::DescriptorSetIndex::FONT_DATA,
descSet->ModifyWriteDescBuffer(FONT_DATA_SET_INDEX,
SHGraphicsConstants::DescriptorSetBindings::FONT_MATRIX_DATA, { &matrixDataBuffer, 1 }, 0, fontAsset.glyphTransformations.size() * sizeof(SHMatrix));
// Bind image and buffer to desc set.
descSet->UpdateDescriptorSetImages(SHGraphicsConstants::DescriptorSetIndex::FONT_DATA, SHGraphicsConstants::DescriptorSetBindings::FONT_BITMAP_DATA);
descSet->UpdateDescriptorSetBuffer(SHGraphicsConstants::DescriptorSetIndex::FONT_DATA, SHGraphicsConstants::DescriptorSetBindings::FONT_MATRIX_DATA);
descSet->UpdateDescriptorSetImages(FONT_DATA_SET_INDEX, SHGraphicsConstants::DescriptorSetBindings::FONT_BITMAP_DATA);
descSet->UpdateDescriptorSetBuffer(FONT_DATA_SET_INDEX, SHGraphicsConstants::DescriptorSetBindings::FONT_MATRIX_DATA);
}
void SHFont::BindDescriptorSet(Handle<SHVkCommandBuffer> commandBuffer, SH_PIPELINE_TYPE pipelineType, uint32_t setIndex) noexcept
{
commandBuffer->BindDescriptorSet(descSet, SH_PIPELINE_TYPE::GRAPHICS, setIndex, {});
}
std::unordered_map<msdfgen::unicode_t, uint32_t> SHFont::GetUnicodeIndexing(void) const noexcept
{
return unicodeIndexing;

View File

@ -3,6 +3,7 @@
#include "Resource/SHHandle.h"
#include "msdf-atlas-gen/msdf-atlas-gen.h"
#include "Assets/Asset Types/SHFontAsset.h"
#include "Graphics/Pipeline/SHPipelineType.h"
namespace SHADE
{
@ -57,6 +58,7 @@ namespace SHADE
SHFont (Handle<SHVkLogicalDevice> inLogicalDeviceHdl, SHFontAsset const& asset) noexcept;
void TransferToGPU (Handle<SHVkCommandBuffer> commandBuffer) noexcept;
void DoPostTransfer (Handle<SHVkDescriptorPool> descPool, Handle<SHVkDescriptorSetLayout> layout) noexcept;
void BindDescriptorSet (Handle<SHVkCommandBuffer> commandBuffer, SH_PIPELINE_TYPE pipelineType, uint32_t setIndex) noexcept;
/*-----------------------------------------------------------------------*/

View File

@ -6,11 +6,13 @@
#include "Graphics/Devices/SHVkLogicalDevice.h"
#include "Graphics/MiddleEnd/TextRendering/SHFont.h"
#include "Graphics/Buffers/SHVkBuffer.h"
#include "Graphics/MiddleEnd/GlobalData/SHGraphicsGlobalData.h"
#include "Graphics/MiddleEnd/GlobalData/SHGraphicsPredefinedData.h"
#include "Graphics/Pipeline/SHVkPipeline.h"
#include "Graphics/SHVkUtil.h"
#include "Graphics/RenderGraph/SHSubpass.h"
#include "Math/Transform/SHTransformComponent.h"
#include "Graphics/MiddleEnd/GlobalData/SHGlobalDescriptorSets.h"
#include "Graphics/MiddleEnd/Interface/SHRenderer.h"
namespace SHADE
{
@ -91,19 +93,17 @@ namespace SHADE
}
void SHTextRenderingSubSystem::Init(Handle<SHVkLogicalDevice> device, Handle<SHVkRenderpass> compatibleRenderpass, Handle<SHSubpass> subpass, Handle<SHVkDescriptorPool> descPool, Handle<SHVkShaderModule> textVS, Handle<SHVkShaderModule> textFS, std::function<void(Handle<SHVkCommandBuffer>, uint32_t)> const& bindFunction) noexcept
void SHTextRenderingSubSystem::Init(Handle<SHVkLogicalDevice> device, Handle<SHVkRenderpass> compatibleRenderpass, Handle<SHSubpass> subpass, Handle<SHVkDescriptorPool> descPool, Handle<SHVkShaderModule> textVS, Handle<SHVkShaderModule> textFS) noexcept
{
SHComponentManager::CreateComponentSparseSet<SHTextRenderableComponent>();
cameraDescSetBind = bindFunction;
logicalDevice = device;
// prepare pipeline layout params
SHPipelineLayoutParams plParams
{
.shaderModules = {textVS, textFS},
.globalDescSetLayouts = SHGraphicsGlobalData::GetDescSetLayouts()
.predefinedDescSetLayouts = SHGraphicsPredefinedData::GetSystemData(SHGraphicsPredefinedData::SystemType::TEXT_RENDERING).descSetLayouts
};
pipelineLayout = logicalDevice->CreatePipelineLayout(plParams);
@ -157,24 +157,6 @@ namespace SHADE
// Construct pipeline
pipeline->ConstructPipeline();
SHVkDescriptorSetLayout::Binding fontBitmapBinding
{
.Type = vk::DescriptorType::eCombinedImageSampler,
.Stage = vk::ShaderStageFlagBits::eFragment,
.BindPoint = SHGraphicsConstants::DescriptorSetBindings::FONT_BITMAP_DATA,
.DescriptorCount = 1,
};
SHVkDescriptorSetLayout::Binding fontMatrixBinding
{
.Type = vk::DescriptorType::eStorageBuffer,
.Stage = vk::ShaderStageFlagBits::eVertex,
.BindPoint = SHGraphicsConstants::DescriptorSetBindings::FONT_MATRIX_DATA,
.DescriptorCount = 1,
};
fontDataDescSetLayout = logicalDevice->CreateDescriptorSetLayout(SHGraphicsConstants::DescriptorSetIndex::FONT_DATA, { fontBitmapBinding, fontMatrixBinding });
}
void SHTextRenderingSubSystem::Run(uint32_t frameIndex) noexcept
@ -192,9 +174,14 @@ namespace SHADE
}
}
void SHTextRenderingSubSystem::Render(Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex) noexcept
void SHTextRenderingSubSystem::Render(Handle<SHVkCommandBuffer> cmdBuffer, Handle<SHRenderer> renderer, uint32_t frameIndex) noexcept
{
auto& textRendererComps = SHComponentManager::GetDense<SHTextRenderableComponent>();
auto const& mappings = SHGraphicsPredefinedData::GetMappings(SHGraphicsPredefinedData::SystemType::TEXT_RENDERING);
uint32_t fontSetIndex = mappings.at(SHPredefinedDescriptorTypes::FONT);
uint32_t staticGlobalSetIndex = mappings.at(SHPredefinedDescriptorTypes::STATIC_DATA);
uint32_t cameraSetIndex = mappings.at(SHPredefinedDescriptorTypes::CAMERA);
for (auto& comp : textRendererComps)
{
auto* transform = SHComponentManager::GetComponent<SHTransformComponent>(comp.GetEID());
@ -205,15 +192,19 @@ namespace SHADE
// bind the pipeline
cmdBuffer->BindPipeline(pipeline);
// Bind global data
SHGlobalDescriptorSets::BindStaticGlobalData(cmdBuffer, SH_PIPELINE_TYPE::GRAPHICS, staticGlobalSetIndex);
// Bind camera data
renderer->BindDescriptorSet(cmdBuffer, SH_PIPELINE_TYPE::GRAPHICS, cameraSetIndex, frameIndex);
// bind descriptors for font (matrices)
fontHandle->BindDescriptorSet(cmdBuffer, SH_PIPELINE_TYPE::GRAPHICS, fontSetIndex);
// bind VBO (position and indices)
cmdBuffer->BindVertexBuffer(SHGraphicsConstants::VertexBufferBindings::CALCULATED_GLYPH_POSITION, comp.charPositionDataBuffer, 0);
cmdBuffer->BindVertexBuffer(SHGraphicsConstants::VertexBufferBindings::GLYPH_INDEX, comp.indexingDataBuffer, 0);
cameraDescSetBind(cmdBuffer, frameIndex);
// bind descriptors for font (matrices)
cmdBuffer->BindDescriptorSet(fontHandle->GetDescriptorSet(), SH_PIPELINE_TYPE::GRAPHICS, SHGraphicsConstants::DescriptorSetIndex::FONT_DATA, {});
cmdBuffer->SetPushConstantVariable("TestPushConstant.worldTransform", transform->GetTRS(), SH_PIPELINE_TYPE::GRAPHICS);
cmdBuffer->SetPushConstantVariable("TestPushConstant.eid", comp.GetEID(), SH_PIPELINE_TYPE::GRAPHICS);
cmdBuffer->SetPushConstantVariable("TestPushConstant.textColor", SHVec3 (1.0f, 1.0f, 1.0f), SH_PIPELINE_TYPE::GRAPHICS);
@ -223,9 +214,7 @@ namespace SHADE
// call draw call
cmdBuffer->DrawArrays(4, comp.text.size(), 0, 0);
//glDrawArraysInstanced(GL_TRIANGLE_FAN, 0, 4, static_cast<GLsizei>(textComp.lastRenderedCharacterIndex) + 1);
}
}
}
@ -234,9 +223,9 @@ namespace SHADE
}
Handle<SHVkDescriptorSetLayout> SHTextRenderingSubSystem::GetFontDataDescSetLayout(void) const noexcept
{
return fontDataDescSetLayout;
}
//Handle<SHVkDescriptorSetLayout> SHTextRenderingSubSystem::GetFontDataDescSetLayout(void) const noexcept
//{
// return fontDataDescSetLayout;
//}
}

View File

@ -20,6 +20,7 @@ namespace SHADE
class SHVkRenderpass;
class SHSubpass;
class SHVkShaderModule;
class SHRenderer;
class SHTextRenderingSubSystem
{
@ -41,24 +42,20 @@ namespace SHADE
Handle<SHVkPipelineLayout> pipelineLayout;
//! Descriptor set for font data access in shaders
Handle<SHVkDescriptorSetLayout> fontDataDescSetLayout;
//! Super temporary. Global descriptor set needs to be revamped along with
//! entire graphics system.
std::function<void(Handle<SHVkCommandBuffer>, uint32_t)> cameraDescSetBind;
//Handle<SHVkDescriptorSetLayout> fontDataDescSetLayout;
private:
void RecomputePositions(SHTextRenderableComponent& textComp) noexcept;
public:
void Init(Handle<SHVkLogicalDevice> device, Handle<SHVkRenderpass> compatibleRenderpass, Handle<SHSubpass> subpass, Handle<SHVkDescriptorPool> descPool, Handle<SHVkShaderModule> textVS, Handle<SHVkShaderModule> textFS, std::function<void(Handle<SHVkCommandBuffer>, uint32_t)> const& bindFunction) noexcept;
void Init(Handle<SHVkLogicalDevice> device, Handle<SHVkRenderpass> compatibleRenderpass, Handle<SHSubpass> subpass, Handle<SHVkDescriptorPool> descPool, Handle<SHVkShaderModule> textVS, Handle<SHVkShaderModule> textFS) noexcept;
void Run(uint32_t frameIndex) noexcept;
void Render (Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex) noexcept;
void Render (Handle<SHVkCommandBuffer> cmdBuffer, Handle<SHRenderer> renderer, uint32_t frameIndex) noexcept;
void Exit(void) noexcept;
Handle<SHVkDescriptorSetLayout> GetFontDataDescSetLayout (void) const noexcept;
//Handle<SHVkDescriptorSetLayout> GetFontDataDescSetLayout (void) const noexcept;
};

View File

@ -24,7 +24,7 @@ of DigiPen Institute of Technology is prohibited.
#include "Graphics/Descriptors/SHVkDescriptorSetGroup.h"
#include "Graphics/Images/SHVkImage.h"
#include "Graphics/Images/SHVkImageView.h"
#include "Graphics/MiddleEnd/GlobalData/SHGraphicsGlobalData.h"
#include "Graphics/MiddleEnd/GlobalData/SHGraphicsPredefinedData.h"
#include "Assets/Asset Types/SHTextureAsset.h"
namespace SHADE
@ -168,22 +168,23 @@ namespace SHADE
}
texDescriptors = descPool->Allocate
(
{ SHGraphicsGlobalData::GetDescSetLayouts()[SHGraphicsConstants::DescriptorSetIndex::STATIC_GLOBALS] },
{ SHGraphicsPredefinedData::GetPredefinedDescSetLayouts(SHGraphicsPredefinedData::PredefinedDescSetLayoutTypes::STATIC_DATA) },
{ static_cast<uint32_t>(texOrder.size()) }
);
#ifdef _DEBUG
for (auto set : texDescriptors->GetVkHandle())
SET_VK_OBJ_NAME(device, vk::ObjectType::eDescriptorSet, set, "[Descriptor Set] Static Globals");
#endif
static constexpr uint32_t TEX_DESCRIPTOR_SET_INDEX = 0;
texDescriptors->ModifyWriteDescImage
(
SHGraphicsConstants::DescriptorSetIndex::STATIC_GLOBALS,
TEX_DESCRIPTOR_SET_INDEX,
SHGraphicsConstants::DescriptorSetBindings::IMAGE_AND_SAMPLERS_DATA,
combinedImageSamplers
);
texDescriptors->UpdateDescriptorSetImages
(
SHGraphicsConstants::DescriptorSetIndex::STATIC_GLOBALS,
TEX_DESCRIPTOR_SET_INDEX,
SHGraphicsConstants::DescriptorSetBindings::IMAGE_AND_SAMPLERS_DATA
);
}

View File

@ -25,7 +25,7 @@ namespace SHADE
//! used just for textures or lights for example). In that case, we still
//! want to use the layout to initialize the pipeline layout but we do not
//! want to use it for allocating descriptor sets.
std::vector<Handle<SHVkDescriptorSetLayout>> const& globalDescSetLayouts = {};
std::vector<Handle<SHVkDescriptorSetLayout>> const& predefinedDescSetLayouts = {};
//! Since both SPIRV-Reflect and GLSL don't provide ways to describe UBOs or
//! SSBOs as dynamic, we need to do it ourselves. This will store bindings

View File

@ -220,7 +220,7 @@ namespace SHADE
// 1 descriptor set layout for every descriptor set detected.
for (auto const& set : setsWithBindings)
{
auto newDescriptorSetLayout = logicalDeviceHdl->CreateDescriptorSetLayout(set.first, set.second);
auto newDescriptorSetLayout = logicalDeviceHdl->CreateDescriptorSetLayout(set.second);
descriptorSetLayoutsAllocate.push_back(newDescriptorSetLayout);
}
@ -317,7 +317,7 @@ namespace SHADE
, logicalDeviceHdl {inLogicalDeviceHdl}
, pushConstantInterface{}
, vkPcRanges{}
, descriptorSetLayoutsGlobal{pipelineLayoutParams.globalDescSetLayouts } // do a copy, some other pipeline layout might need this
, descriptorSetLayoutsGlobal{pipelineLayoutParams.predefinedDescSetLayouts } // do a copy, some other pipeline layout might need this
, descriptorSetLayoutsAllocate{}
, vkDescriptorSetLayoutsAllocate{}
, descriptorSetLayoutsPipeline{}

View File

@ -12,8 +12,10 @@
#include "SHRenderGraphStorage.h"
#include "Graphics/RenderGraph/SHRenderGraphNodeCompute.h"
#include "Tools/Utilities/SHUtilities.h"
#include "Graphics/MiddleEnd/GlobalData/SHGraphicsGlobalData.h"
#include "Graphics/MiddleEnd/GlobalData/SHGraphicsPredefinedData.h"
#include "Graphics/RenderGraph/SHRenderToSwapchainImageSystem.h"
#include "Graphics/MiddleEnd/GlobalData/SHGlobalDescriptorSets.h"
namespace SHADE
{
@ -66,6 +68,56 @@ namespace SHADE
renderGraphStorage->graphResources->try_emplace(resourceName, resource);
}
void SHRenderGraph::RemoveResource(std::string resourceName) noexcept
{
// 1. Check if nodes are using said attachment and remove if they are
// - Check subpasses while at it and remove as well if used as attachment
// 2. Regenerate graph
// - Delete all vulkan objects first as well and clear the necessary containers
if (!renderGraphStorage->graphResources->contains(resourceName))
return;
renderGraphStorage->logicalDevice->WaitIdle();
uint64_t handleID = renderGraphStorage->graphResources->at (resourceName).GetId().Raw;
// Record nodes that will be affected
std::vector<uint32_t> affectedNodes{};
// Detach resource from all nodes if applicable
for (uint32_t i = 0; i < nodes.size(); ++i)
{
if (nodes[i]->DetachResource(resourceName, handleID))
affectedNodes.emplace_back(i);
}
// Up to this point the nodes and subpasses should have no trace of the deleted resource. Attachment
// descriptions and subpass indices should also have been reconfigured at this point. However, this
// means that the subpass descriptions and subpass dependencies need to be reconfigured.
// configure subpass dependencies and descriptions.
for (auto& affectedNode : affectedNodes)
nodes[affectedNode]->ConfigureSubpasses();
for (auto& affectedNode : affectedNodes)
nodes[affectedNode]->CreateRenderpass();
for (auto& affectedNode : affectedNodes)
nodes[affectedNode]->CreateFramebuffer();
/*
* IMPORTANT NOTES
*
* This remove resource function would be more complete if it accounted for renderpass compatibility by
* recreating the graphics pipelines stored in render graph nodes. However due to time constraints, this is left out. As such,
* pipelines that are recreated with a certain renderpass and subpass will assumed to be compatible when used in different subpasses.
*
* This function also recreates renderpasses and framebuffers so it does not account for removing of resources that are used in nodes whose
* renderpasses and framebuffers are used externally in systems like Editor with ImGui.
*/
}
void SHRenderGraph::LinkNonOwningResource(Handle<SHRenderGraph> resourceOrigin, std::string resourceName) noexcept
{
// resource to link
@ -234,140 +286,12 @@ namespace SHADE
*/
/***************************************************************************/
void SHRenderGraph::ConfigureSubpasses(void) noexcept
void SHRenderGraph::ConfigureAllSubpasses(void) noexcept
{
// For all nodes
for (auto& node : nodes)
{
// Create subpass description and dependencies based on number of subpasses
node->spDescs.resize(node->subpasses.size());
node->spDeps.resize(node->subpasses.size());
// Now we want to loop through all attachments in all subpasses in the node and query
// the resources being used. For each resource we want to query the type and record it
// in bit fields (1 bit for each subpass).
uint32_t colorRead = 0, colorWrite = 0, depthRead = 0, depthWrite = 0, inputDependencies = 0;
uint32_t i = 0;
// For all subpasses (see above description about bit field for this).
for (auto& subpass : node->subpasses)
{
// Configure subpass description
auto& desc = node->spDescs[i];
desc.pColorAttachments = subpass->colorReferences.data();
desc.colorAttachmentCount = static_cast<uint32_t>(subpass->colorReferences.size());
desc.pInputAttachments = subpass->inputReferences.data();
desc.inputAttachmentCount = static_cast<uint32_t>(subpass->inputReferences.size());
desc.pDepthStencilAttachment = subpass->depthReferences.data();
desc.pipelineBindPoint = vk::PipelineBindPoint::eGraphics; // TODO: Just graphics for now. See if its possible to allow user defined params.
// Get reference to subpass description
auto& dep = node->spDeps[i];
// Configure subpass index for dependencies
dep.srcSubpass = (i == 0) ? VK_SUBPASS_EXTERNAL : i - 1;
dep.dstSubpass = i;
// First we want to see if the subpass has color, depth or input attachments and set bit field accordingly
if (subpass->colorReferences.size())
{
colorRead |= (1 << i);
colorWrite |= (1 << i);
}
// Same thing for depth
if (subpass->depthReferences.size())
{
depthRead |= (1 << i);
depthWrite |= (1 << i);
}
if (subpass->inputReferences.size())
inputDependencies |= (1 << i);
// Input attachments can be any type, so we need to check what type it is
for (auto& inputAtt : subpass->inputReferences)
{
auto resource = node->attResources[inputAtt.attachment];
if (resource->resourceTypeFlags & static_cast<uint32_t>(SH_RENDER_GRAPH_RESOURCE_FLAGS::INPUT))
{
if (resource->resourceTypeFlags & static_cast<uint32_t>(SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR) ||
resource->resourceTypeFlags & static_cast<uint32_t>(SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR_PRESENT))
colorRead |= (1 << i);
else if (resource->resourceTypeFlags & static_cast<uint32_t>(SH_RENDER_GRAPH_RESOURCE_FLAGS::DEPTH_STENCIL))
depthRead |= (1 << i);
}
else
{
SHLOG_ERROR("While configuring subpass, an input reference was detected but the resource to be used is not marked as SH_ATT_DESC_TYPE_FLAGS::INPUT. ");
}
}
++i;
}
// Loop through all subpasses again but this time we use the bit field to initialize
// the dependencies.
for (i = 0; i < node->subpasses.size(); ++i)
{
vk::PipelineStageFlags srcStage;
vk::PipelineStageFlags dstStage;
vk::AccessFlags srcAccess;
vk::AccessFlags dstAccess;
auto& dep = node->spDeps[i];
if (colorRead & (1 << i))
{
srcStage |= vk::PipelineStageFlagBits::eColorAttachmentOutput;
dstStage |= vk::PipelineStageFlagBits::eColorAttachmentOutput;
srcAccess |= vk::AccessFlagBits::eColorAttachmentWrite;
dstAccess |= vk::AccessFlagBits::eColorAttachmentRead;
}
if (colorWrite & (1 << i))
{
srcStage |= vk::PipelineStageFlagBits::eColorAttachmentOutput;
dstStage |= vk::PipelineStageFlagBits::eColorAttachmentOutput;
srcAccess |= vk::AccessFlagBits::eColorAttachmentWrite;
dstAccess |= vk::AccessFlagBits::eColorAttachmentWrite | vk::AccessFlagBits::eColorAttachmentRead;
}
if (depthRead & (1 << i))
{
srcStage |= vk::PipelineStageFlagBits::eEarlyFragmentTests;
dstStage |= vk::PipelineStageFlagBits::eEarlyFragmentTests | vk::PipelineStageFlagBits::eLateFragmentTests;
srcAccess |= vk::AccessFlagBits::eDepthStencilAttachmentWrite;
dstAccess |= vk::AccessFlagBits::eDepthStencilAttachmentRead;
}
if (depthWrite & (1 << i))
{
srcStage |= vk::PipelineStageFlagBits::eEarlyFragmentTests;
dstStage |= vk::PipelineStageFlagBits::eEarlyFragmentTests | vk::PipelineStageFlagBits::eLateFragmentTests;
srcAccess |= vk::AccessFlagBits::eDepthStencilAttachmentWrite;
dstAccess |= vk::AccessFlagBits::eDepthStencilAttachmentRead | vk::AccessFlagBits::eDepthStencilAttachmentWrite;
}
if (inputDependencies & (1 << i))
{
dstStage |= vk::PipelineStageFlagBits::eFragmentShader;
dstAccess |= vk::AccessFlagBits::eInputAttachmentRead;
}
//// If subpass of first renderpass, stage flag should be bottom of pipe
//if (&node == &nodes.front() && i == 0)
// srcStage = vk::PipelineStageFlagBits::eBottomOfPipe;
//// If subpass of last renderpass, stage flag should be bottom of pipe
//if (&node == &nodes.back() && i == node->subpasses.size() - 1)
// dstStage = vk::PipelineStageFlagBits::eTopOfPipe;
dep.srcStageMask = srcStage;
dep.dstStageMask = dstStage;
dep.srcAccessMask = srcAccess;
dep.dstAccessMask = dstAccess;
dep.srcStageMask = srcStage;
// initialize input descriptors
node->subpasses[i]->CreateInputDescriptors();
}
node->ConfigureSubpasses();
}
}
@ -424,7 +348,7 @@ namespace SHADE
*/
/***************************************************************************/
void SHRenderGraph::Init(std::string graphName, Handle<SHVkLogicalDevice> logicalDevice, Handle<SHVkSwapchain> swapchain, SHResourceHub* resourceHub) noexcept
void SHRenderGraph::Init(std::string graphName, Handle<SHVkLogicalDevice> logicalDevice, Handle<SHVkSwapchain> swapchain, SHResourceHub* resourceHub, std::vector<Handle<SHVkCommandPool>>& cmdPools) noexcept
{
//resourceHub = std::make_shared<SHResourceHub>();
@ -437,6 +361,11 @@ namespace SHADE
renderGraphStorage->resourceHub = resourceHub;
renderGraphStorage->descriptorPool = logicalDevice->CreateDescriptorPools();
commandBuffers.resize(static_cast<std::size_t>(swapchain->GetNumImages()));
for (uint32_t i = 0; i < commandBuffers.size(); ++i)
commandBuffers[i] = cmdPools[i]->RequestCommandBuffer(SH_CMD_BUFFER_TYPE::PRIMARY);
name = std::move(graphName);
}
@ -555,17 +484,24 @@ namespace SHADE
if (renderGraphStorage->graphResources->contains(toSwapchainResource) && renderGraphStorage->graphResources->contains(swapchainResource))
{
auto newNode = AddNode("Render To Present", { ResourceInstruction (toSwapchainResource.c_str()), ResourceInstruction(swapchainResource.c_str()) }, predecessorNodes);
auto newSubpass = newNode->AddSubpass("Render");
auto newSubpass = newNode->AddSubpass("Render", {}, {});
newSubpass->AddColorOutput(swapchainResource);
newSubpass->AddInput(toSwapchainResource);
renderToSwapchainImageSystem = renderGraphStorage->resourceHub->Create<SHRenderToSwapchainImageSystem> (newNode, newSubpass, shaderModules);
newSubpass->AddExteriorDrawCalls([=](Handle<SHVkCommandBuffer>& cmdBuffer, uint32_t frameIndex)
newSubpass->AddExteriorDrawCalls([=](Handle<SHVkCommandBuffer> cmdBuffer, Handle<SHRenderer> renderer, uint32_t frameIndex)
{
cmdBuffer->BindPipeline(renderToSwapchainImageSystem->GetPipeline());
newSubpass->BindDescriptorInputDescriptorSets (cmdBuffer, frameIndex);
// If we are rendering to present image, the width and height will be the dimensions of that image. So we need to set viewport scissor.
auto resource = renderGraphStorage->graphResources->at(swapchainResource);
uint32_t w = static_cast<uint32_t>(resource->GetWidth());
uint32_t h = static_cast<uint32_t>(resource->GetHeight());
cmdBuffer->SetViewportScissor(static_cast<float>(w), static_cast<float>(h), w, h);
static constexpr uint32_t INPUT_IMAGE_SET_INDEX = 0;
newSubpass->BindInputDescriptorSets (cmdBuffer, INPUT_IMAGE_SET_INDEX, frameIndex);
// draw a quad.
cmdBuffer->DrawArrays(4, 1, 0, 0);
@ -590,12 +526,17 @@ namespace SHADE
{
CheckForNodeComputes();
ConfigureAttachmentDescriptions();
ConfigureSubpasses();
ConfigureAllSubpasses();
ConfigureRenderpasses();
ConfigureFramebuffers();
ConfigureSubSystems();
}
void SHRenderGraph::Regenerate(void) noexcept
{
}
/***************************************************************************/
/*!
@ -616,14 +557,41 @@ namespace SHADE
// 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, Handle<SHVkCommandBuffer> cmdBuffer, Handle<SHVkDescriptorPool> descPool) noexcept
void SHRenderGraph::Execute(uint32_t frameIndex, Handle<SHVkDescriptorPool> descPool) noexcept
{
auto cmdBuffer = commandBuffers[frameIndex];
cmdBuffer->BeginLabeledSegment(name);
auto batchingSystemData = SHGraphicsPredefinedData::GetSystemData(SHGraphicsPredefinedData::SystemType::BATCHING);
// Force bind pipeline layout
cmdBuffer->ForceSetPipelineLayout(batchingSystemData.dummyPipelineLayout, SH_PIPELINE_TYPE::GRAPHICS);
cmdBuffer->ForceSetPipelineLayout(batchingSystemData.dummyPipelineLayout, SH_PIPELINE_TYPE::COMPUTE);
auto const& descMappings = SHGraphicsPredefinedData::GetMappings(SHGraphicsPredefinedData::SystemType::BATCHING);
for (auto& node : nodes)
{
// bind static global data
SHGlobalDescriptorSets::BindStaticGlobalData(cmdBuffer, SH_PIPELINE_TYPE::GRAPHICS, descMappings.at(SHPredefinedDescriptorTypes::STATIC_DATA));
node->Execute(cmdBuffer, descPool, frameIndex);
}
cmdBuffer->EndLabeledSegment();
}
void SHRenderGraph::Begin(uint32_t frameIndex) noexcept
{
commandBuffers[frameIndex]->BeginRecording();
}
void SHRenderGraph::End(uint32_t frameIndex) noexcept
{
commandBuffers[frameIndex]->EndRecording();
}
void SHRenderGraph::FinaliseBatch(uint32_t frameIndex, Handle<SHVkDescriptorPool> descPool)
{
for (auto& node : nodes)
@ -670,4 +638,9 @@ namespace SHADE
return {};
}
Handle<SHVkCommandBuffer> SHRenderGraph::GetCommandBuffer(uint32_t frameIndex) const noexcept
{
return commandBuffers[frameIndex];
}
}

View File

@ -29,7 +29,7 @@ namespace SHADE
class SHVkCommandPool;
class SHVkCommandBuffer;
class SHRenderGraphNode;
class SHGraphicsGlobalData;
class SHGraphicsPredefinedData;
class SHVkDescriptorPool;
class SHRenderGraphStorage;
class SHRenderToSwapchainImageSystem;
@ -51,7 +51,7 @@ namespace SHADE
/* PRIVATE MEMBER FUNCTIONS */
/*-----------------------------------------------------------------------*/
void ConfigureAttachmentDescriptions (void) noexcept;
void ConfigureSubpasses (void) noexcept;
void ConfigureAllSubpasses (void) noexcept;
void ConfigureRenderpasses (void) noexcept;
void ConfigureSubSystems (void) noexcept;
void ConfigureFramebuffers (void) noexcept;
@ -74,6 +74,9 @@ namespace SHADE
//! For rendering onto the swapchain
Handle<SHRenderToSwapchainImageSystem> renderToSwapchainImageSystem;
//! Command buffer to issue rendering commands
std::vector<Handle<SHVkCommandBuffer>> commandBuffers;
public:
/*-----------------------------------------------------------------------*/
/* CTORS AND DTORS */
@ -86,15 +89,56 @@ namespace SHADE
/*-----------------------------------------------------------------------*/
/* PUBLIC MEMBER FUNCTIONS */
/*-----------------------------------------------------------------------*/
void Init (std::string graphName, Handle<SHVkLogicalDevice> logicalDevice, Handle<SHVkSwapchain> swapchain, SHResourceHub* resourceHub) noexcept;
void AddResource(std::string resourceName, std::initializer_list<SH_RENDER_GRAPH_RESOURCE_FLAGS> typeFlags, uint32_t w = static_cast<uint32_t>(-1), uint32_t h = static_cast<uint32_t>(-1), vk::Format format = vk::Format::eB8G8R8A8Unorm, uint8_t levels = 1, vk::ImageUsageFlagBits usageFlags = {}, vk::ImageCreateFlagBits createFlags = {});
void LinkNonOwningResource (Handle<SHRenderGraph> resourceOrigin, std::string resourceName) noexcept;
Handle<SHRenderGraphNode> AddNode (std::string nodeName, std::initializer_list<ResourceInstruction> resourceInstruction, std::initializer_list<std::string> predecessorNodes) noexcept;
void AddRenderToSwapchainNode (std::string toSwapchainResource, std::string swapchainResource, std::initializer_list<std::string> predecessorNodes, std::pair<Handle<SHVkShaderModule>, Handle<SHVkShaderModule>> shaderModules) noexcept;
void Init
(
std::string graphName,
Handle<SHVkLogicalDevice> logicalDevice,
Handle<SHVkSwapchain> swapchain, SHResourceHub* resourceHub,
std::vector<Handle<SHVkCommandPool>>& cmdPools
) noexcept;
void AddResource
(
std::string resourceName,
std::initializer_list<SH_RENDER_GRAPH_RESOURCE_FLAGS> typeFlags,
uint32_t w = static_cast<uint32_t>(-1),
uint32_t h = static_cast<uint32_t>(-1),
vk::Format format = vk::Format::eB8G8R8A8Unorm,
uint8_t levels = 1,
vk::ImageUsageFlagBits usageFlags = {},
vk::ImageCreateFlagBits createFlags = {}
);
void RemoveResource (std::string resourceName) noexcept;
void LinkNonOwningResource
(
Handle<SHRenderGraph> resourceOrigin,
std::string resourceName
) noexcept;
Handle<SHRenderGraphNode> AddNode
(
std::string nodeName,
std::initializer_list<ResourceInstruction> resourceInstruction,
std::initializer_list<std::string> predecessorNodes
) noexcept;
void AddRenderToSwapchainNode
(
std::string toSwapchainResource,
std::string swapchainResource,
std::initializer_list<std::string> predecessorNodes,
std::pair<Handle<SHVkShaderModule>,
Handle<SHVkShaderModule>> shaderModules
) noexcept;
void Generate (void) noexcept;
void Regenerate (void) noexcept;
void CheckForNodeComputes (void) noexcept;
void Execute (uint32_t frameIndex, Handle<SHVkCommandBuffer> cmdBuffer, Handle<SHVkDescriptorPool> descPool) noexcept;
void Execute (uint32_t frameIndex, Handle<SHVkDescriptorPool> descPool) noexcept;
void Begin (uint32_t frameIndex) noexcept;
void End (uint32_t frameIndex) noexcept;
void FinaliseBatch (uint32_t frameIndex, Handle<SHVkDescriptorPool> descPool);
void HandleResize (uint32_t newWidth, uint32_t newHeight) noexcept;
@ -104,6 +148,7 @@ namespace SHADE
Handle<SHRenderGraphNode> GetNode (std::string const& nodeName) const noexcept;
std::vector<Handle<SHRenderGraphNode>> const& GetNodes (void) const noexcept;
Handle<SHRenderGraphResource> GetRenderGraphResource (std::string const& resourceName) const noexcept;
Handle<SHVkCommandBuffer> GetCommandBuffer (uint32_t frameIndex) const noexcept;
};
}

View File

@ -9,6 +9,8 @@
#include "SHRenderGraphStorage.h"
#include "Graphics/RenderGraph/SHRenderGraphNodeCompute.h"
#include "Graphics/SHVkUtil.h"
#include "Graphics/MiddleEnd/GlobalData/SHGlobalDescriptorSets.h"
#include "Graphics/MiddleEnd/GlobalData/SHGraphicsPredefinedData.h"
namespace SHADE
{
@ -24,6 +26,12 @@ namespace SHADE
/***************************************************************************/
void SHRenderGraphNode::CreateRenderpass(void) noexcept
{
if (renderpass)
{
if (renderpass)
renderpass.Free();
}
renderpass = graphStorage->logicalDevice->CreateRenderpass(attachmentDescriptions, spDescs, spDeps);
SET_VK_OBJ_NAME(graphStorage->logicalDevice, vk::ObjectType::eRenderPass, renderpass->GetVkRenderpass(), "[RenderPass] " + name);
}
@ -38,6 +46,15 @@ namespace SHADE
/***************************************************************************/
void SHRenderGraphNode::CreateFramebuffer(void) noexcept
{
if (!framebuffers.empty())
{
for (auto fbo : framebuffers)
{
if (fbo)
fbo.Free();
}
}
for (uint32_t i = 0; i < framebuffers.size(); ++i)
{
std::vector<Handle<SHVkImageView>> imageViews(attResources.size());
@ -98,6 +115,139 @@ namespace SHADE
}
}
void SHRenderGraphNode::ConfigureSubpasses(void) noexcept
{
// Create subpass description and dependencies based on number of subpasses
spDescs.resize(subpasses.size());
spDeps.resize(subpasses.size());
// Now we want to loop through all attachments in all subpasses in the node and query
// the resources being used. For each resource we want to query the type and record it
// in bit fields (1 bit for each subpass).
uint32_t colorRead = 0, colorWrite = 0, depthRead = 0, depthWrite = 0, inputDependencies = 0;
uint32_t i = 0;
// For all subpasses (see above description about bit field for this).
for (auto& subpass : subpasses)
{
// Configure subpass description
auto& desc = spDescs[i];
desc.pColorAttachments = subpass->colorReferences.data();
desc.colorAttachmentCount = static_cast<uint32_t>(subpass->colorReferences.size());
desc.pInputAttachments = subpass->inputReferences.data();
desc.inputAttachmentCount = static_cast<uint32_t>(subpass->inputReferences.size());
desc.pDepthStencilAttachment = subpass->depthReferences.data();
desc.pipelineBindPoint = vk::PipelineBindPoint::eGraphics; // TODO: Just graphics for now. See if its possible to allow user defined params.
// Get reference to subpass description
auto& dep = spDeps[i];
// Configure subpass index for dependencies
dep.srcSubpass = (i == 0) ? VK_SUBPASS_EXTERNAL : i - 1;
dep.dstSubpass = i;
// First we want to see if the subpass has color, depth or input attachments and set bit field accordingly
if (subpass->colorReferences.size())
{
colorRead |= (1 << i);
colorWrite |= (1 << i);
}
// Same thing for depth
if (subpass->depthReferences.size())
{
depthRead |= (1 << i);
depthWrite |= (1 << i);
}
if (subpass->inputReferences.size())
inputDependencies |= (1 << i);
// Input attachments can be any type, so we need to check what type it is
for (auto& inputAtt : subpass->inputReferences)
{
auto resource = attResources[inputAtt.attachment];
if (resource->resourceTypeFlags & static_cast<uint32_t>(SH_RENDER_GRAPH_RESOURCE_FLAGS::INPUT))
{
if (resource->resourceTypeFlags & static_cast<uint32_t>(SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR) ||
resource->resourceTypeFlags & static_cast<uint32_t>(SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR_PRESENT))
colorRead |= (1 << i);
else if (resource->resourceTypeFlags & static_cast<uint32_t>(SH_RENDER_GRAPH_RESOURCE_FLAGS::DEPTH_STENCIL))
depthRead |= (1 << i);
}
else
{
SHLOG_ERROR("While configuring subpass, an input reference was detected but the resource to be used is not marked as SH_ATT_DESC_TYPE_FLAGS::INPUT. ");
}
}
++i;
}
// Loop through all subpasses again but this time we use the bit field to initialize
// the dependencies.
for (i = 0; i < subpasses.size(); ++i)
{
vk::PipelineStageFlags srcStage;
vk::PipelineStageFlags dstStage;
vk::AccessFlags srcAccess;
vk::AccessFlags dstAccess;
auto& dep = spDeps[i];
if (colorRead & (1 << i))
{
srcStage |= vk::PipelineStageFlagBits::eColorAttachmentOutput;
dstStage |= vk::PipelineStageFlagBits::eColorAttachmentOutput;
srcAccess |= vk::AccessFlagBits::eColorAttachmentWrite;
dstAccess |= vk::AccessFlagBits::eColorAttachmentRead;
}
if (colorWrite & (1 << i))
{
srcStage |= vk::PipelineStageFlagBits::eColorAttachmentOutput;
dstStage |= vk::PipelineStageFlagBits::eColorAttachmentOutput;
srcAccess |= vk::AccessFlagBits::eColorAttachmentWrite;
dstAccess |= vk::AccessFlagBits::eColorAttachmentWrite | vk::AccessFlagBits::eColorAttachmentRead;
}
if (depthRead & (1 << i))
{
srcStage |= vk::PipelineStageFlagBits::eEarlyFragmentTests;
dstStage |= vk::PipelineStageFlagBits::eEarlyFragmentTests | vk::PipelineStageFlagBits::eLateFragmentTests;
srcAccess |= vk::AccessFlagBits::eDepthStencilAttachmentWrite;
dstAccess |= vk::AccessFlagBits::eDepthStencilAttachmentRead;
}
if (depthWrite & (1 << i))
{
srcStage |= vk::PipelineStageFlagBits::eEarlyFragmentTests;
dstStage |= vk::PipelineStageFlagBits::eEarlyFragmentTests | vk::PipelineStageFlagBits::eLateFragmentTests;
srcAccess |= vk::AccessFlagBits::eDepthStencilAttachmentWrite;
dstAccess |= vk::AccessFlagBits::eDepthStencilAttachmentRead | vk::AccessFlagBits::eDepthStencilAttachmentWrite;
}
if (inputDependencies & (1 << i))
{
dstStage |= vk::PipelineStageFlagBits::eFragmentShader;
dstAccess |= vk::AccessFlagBits::eInputAttachmentRead;
}
//// If subpass of first renderpass, stage flag should be bottom of pipe
//if (&node == &nodes.front() && i == 0)
// srcStage = vk::PipelineStageFlagBits::eBottomOfPipe;
//// If subpass of last renderpass, stage flag should be bottom of pipe
//if (&node == &nodes.back() && i == subpasses.size() - 1)
// dstStage = vk::PipelineStageFlagBits::eTopOfPipe;
dep.srcStageMask = srcStage;
dep.dstStageMask = dstStage;
dep.srcAccessMask = srcAccess;
dep.dstAccessMask = dstAccess;
dep.srcStageMask = srcStage;
// initialize input descriptors
subpasses[i]->CreateInputDescriptors();
}
}
/***************************************************************************/
/*!
@ -238,7 +388,7 @@ namespace SHADE
*/
/***************************************************************************/
Handle<SHSubpass> SHRenderGraphNode::AddSubpass(std::string subpassName) noexcept
Handle<SHSubpass> SHRenderGraphNode::AddSubpass(std::string subpassName, Handle<SHViewport> viewport, Handle<SHRenderer> renderer) noexcept
{
// if subpass already exists, don't add.
if (subpassIndexing.contains(subpassName))
@ -253,6 +403,8 @@ namespace SHADE
graphStorage->resourceHub->Create<SHSubpass>
(
subpassName,
viewport,
renderer,
graphStorage, GetHandle(), static_cast<uint32_t>(subpasses.size()),
resourceAttachmentMapping.get()
)
@ -318,7 +470,7 @@ namespace SHADE
}
// insert them all for a subpass to transition them. This subpass is the last subpass
auto dummySubpass = AddSubpass("dummy");
auto dummySubpass = AddSubpass("dummy", {}, {});
for (auto& resource : resourcesInvolved)
{
dummySubpass->AddGeneralInput(resource);
@ -331,7 +483,59 @@ namespace SHADE
}
}
void SHRenderGraphNode::Execute(Handle<SHVkCommandBuffer>& commandBuffer, Handle<SHVkDescriptorPool> descPool, uint32_t frameIndex) noexcept
/***************************************************************************/
/*!
\brief
For detaching attachments from the node. The node would need to be
rebuilt but it won't be done in this function. This function just removes
any footprint of the resource in the class.
\param resourceHandleID
The handle ID of the resource.
*/
/***************************************************************************/
bool SHRenderGraphNode::DetachResource(std::string const& resourceName, uint64_t resourceHandleID) noexcept
{
if (resourceAttachmentMapping->contains(resourceHandleID))
{
// Get attachment index in the node's attachment container
auto index = resourceAttachmentMapping->at(resourceHandleID);
// remove attachment from the list of attachments
attResources.erase (attResources.begin() + index);
// remove attachment reference
attachmentDescriptions.erase (attachmentDescriptions.begin() + index);
// Remove footprint of attachment from all subpasses as well
for (auto it = subpasses.begin(); it != subpasses.end(); ++it)
{
// attempt to detach resource from subpass
(*it)->DetachResource(resourceName, index);
// If the subpass ends up having no attachments after, erase it from the node
if ((*it)->HasNoAttachments())
{
// erase from indexing
subpassIndexing.erase((*it)->GetName());
// erase from container of subpasses.
it = subpasses.erase(it);
}
}
// give existing subpasses new indices
for (uint32_t i = 0; i < subpasses.size(); ++i)
subpasses[i]->SetIndex(i);
return true;
}
return false;
}
void SHRenderGraphNode::Execute(Handle<SHVkCommandBuffer> commandBuffer, Handle<SHVkDescriptorPool> descPool, uint32_t frameIndex) noexcept
{
uint32_t framebufferIndex = (framebuffers.size() > 1) ? frameIndex : 0;
commandBuffer->BeginRenderpass(renderpass, framebuffers[framebufferIndex]);
@ -347,13 +551,24 @@ namespace SHADE
commandBuffer->EndRenderpass();
auto const& descMappings = SHGraphicsPredefinedData::GetMappings(SHGraphicsPredefinedData::SystemType::RENDER_GRAPH_NODE_COMPUTE);
// We bind these 2 descriptor sets here because they apply to all node computes
if (!nodeComputes.empty())
{
commandBuffer->ForceSetPipelineLayout(SHGraphicsPredefinedData::GetSystemData(SHGraphicsPredefinedData::SystemType::RENDER_GRAPH_NODE_COMPUTE).dummyPipelineLayout, SH_PIPELINE_TYPE::COMPUTE);
// bind static global data
SHGlobalDescriptorSets::BindStaticGlobalData(commandBuffer, SH_PIPELINE_TYPE::COMPUTE, descMappings.at(SHPredefinedDescriptorTypes::STATIC_DATA));
// bind lighting data
SHGlobalDescriptorSets::BindLightingData(commandBuffer, SH_PIPELINE_TYPE::COMPUTE, descMappings.at(SHPredefinedDescriptorTypes::LIGHTS), frameIndex);
}
// Execute all subpass computes
for (auto& sbCompute : nodeComputes)
{
sbCompute->Execute(commandBuffer, frameIndex);
}
}
Handle<SHVkPipeline> SHRenderGraphNode::GetOrCreatePipeline(std::pair<Handle<SHVkShaderModule>, Handle<SHVkShaderModule>> const& vsFsPair, Handle<SHSubpass> subpass) noexcept
{

View File

@ -19,9 +19,11 @@ namespace SHADE
class SHVkLogicalDevice;
class SHVkRenderpass;
class SHVkDescriptorPool;
class SHGraphicsGlobalData;
class SHGraphicsPredefinedData;
class SHRenderGraphStorage;
class SHRenderGraphNodeCompute;
class SHRenderer;
class SHViewport;
class SH_API SHRenderGraphNode : public ISelfHandle<SHRenderGraphNode>
{
@ -53,7 +55,7 @@ namespace SHADE
//! Vector of subpasses
std::vector<Handle<SHSubpass>> subpasses;
//! Descriptions to pass to renderpass for renderpass creation. We want to keep this here because
//! Descriptions to pass to renderpass for renderpass creation.
std::vector<vk::SubpassDescription> spDescs;
//! Subpass dependencies for renderpass creation
@ -90,6 +92,7 @@ namespace SHADE
void CreateRenderpass(void) noexcept;
void CreateFramebuffer(void) noexcept;
void HandleResize (void) noexcept;
void ConfigureSubpasses (void) noexcept;
public:
/*-----------------------------------------------------------------------*/
@ -102,12 +105,13 @@ namespace SHADE
/*-----------------------------------------------------------------------*/
/* PUBLIC MEMBER FUNCTIONS */
/*-----------------------------------------------------------------------*/
Handle<SHSubpass> AddSubpass(std::string subpassName) noexcept;
Handle<SHSubpass> AddSubpass(std::string subpassName, Handle<SHViewport> viewport, Handle<SHRenderer> renderer) noexcept;
Handle<SHRenderGraphNodeCompute> AddNodeCompute(std::string nodeName, Handle<SHVkShaderModule> computeShaderModule, std::initializer_list<std::string> resources, std::unordered_set<BindingAndSetHash>&& dynamicBufferBindings = {}, float numWorkGroupScale = 1.0f) noexcept;
void AddDummySubpassIfNeeded (void) noexcept;
bool DetachResource (std::string const& resourceName, uint64_t resourceHandleID) noexcept;
// TODO: RemoveSubpass()
void Execute(Handle<SHVkCommandBuffer>& commandBuffer, Handle<SHVkDescriptorPool> descPool, uint32_t frameIndex) noexcept;
void Execute(Handle<SHVkCommandBuffer> commandBuffer, Handle<SHVkDescriptorPool> descPool, uint32_t frameIndex) noexcept;
Handle<SHVkPipeline> GetOrCreatePipeline(std::pair<Handle<SHVkShaderModule>, Handle<SHVkShaderModule>> const& vsFsPair, Handle<SHSubpass> subpass) noexcept;
void FinaliseBatch(uint32_t frameIndex, Handle<SHVkDescriptorPool> descPool);

View File

@ -6,10 +6,11 @@
#include "Graphics/Descriptors/SHVkDescriptorSetLayout.h"
#include "Graphics/Devices/SHVkLogicalDevice.h"
#include "Graphics/Pipeline/SHVkPipelineLayout.h"
#include "Graphics/MiddleEnd/GlobalData/SHGraphicsGlobalData.h"
#include "Graphics/MiddleEnd/GlobalData/SHGraphicsPredefinedData.h"
#include "SHRenderGraphStorage.h"
#include "SHRenderGraphResource.h"
#include "Graphics/Commands/SHVkCommandBuffer.h"
#include "Graphics/MiddleEnd/Interface/SHRenderer.h"
namespace SHADE
{
@ -23,11 +24,12 @@ namespace SHADE
, numWorkGroupScale {std::clamp(inNumWorkGroupScale, 0.0f, 1.0f)}
, computeResource{}
, name { std::move(nodeName) }
, renderer{ }
{
SHPipelineLayoutParams pipelineLayoutParams
{
.shaderModules = {computeShaderModule},
.globalDescSetLayouts = SHGraphicsGlobalData::GetDescSetLayouts(),
.predefinedDescSetLayouts = SHGraphicsPredefinedData::GetSystemData(SHGraphicsPredefinedData::SystemType::RENDER_GRAPH_NODE_COMPUTE).descSetLayouts,
.dynamicBufferBindings = std::move(dynamicBufferBindings),
};
@ -45,10 +47,13 @@ namespace SHADE
// save the resources
resources = std::move (subpassComputeResources);
auto const& descMappings = SHGraphicsPredefinedData::GetMappings(SHGraphicsPredefinedData::SystemType::RENDER_GRAPH_NODE_COMPUTE);
auto const& layouts = computePipeline->GetPipelineLayout()->GetDescriptorSetLayoutsPipeline();
//Get the descriptor set layouts required to allocate. We only want the ones for allocate because
//global descriptors are already bound in the main system.
auto const& graphResourceLayout = computePipeline->GetPipelineLayout()->GetDescriptorSetLayoutsPipeline()[SHGraphicsConstants::DescriptorSetIndex::RENDERGRAPH_RESOURCE];
auto const& graphResourceLayout = layouts[descMappings.at(SHPredefinedDescriptorTypes::RENDER_GRAPH_RESOURCE)];
// Allocate descriptor sets to hold the images for reading (STORAGE_IMAGE)
for (uint32_t i = 0; i < SHGraphicsConstants::NUM_FRAME_BUFFERS; ++i)
@ -60,14 +65,12 @@ namespace SHADE
#endif
}
auto const& layouts = computePipeline->GetPipelineLayout()->GetDescriptorSetLayoutsPipeline();
if (layouts.size() == SHGraphicsConstants::DescriptorSetIndex::RENDERGRAPH_NODE_COMPUTE_RESOURCE + 1)
// check if all layouts are there
if (layouts.size() == descMappings.at(SHPredefinedDescriptorTypes::RENDER_GRAPH_NODE_COMPUTE_RESOURCE) + 1)
{
// create compute resources
computeResource = graphStorage->resourceHub->Create<ComputeResource>();
auto computeResourceLayout = layouts[SHGraphicsConstants::DescriptorSetIndex::RENDERGRAPH_NODE_COMPUTE_RESOURCE];
auto computeResourceLayout = layouts[descMappings.at(SHPredefinedDescriptorTypes::RENDER_GRAPH_NODE_COMPUTE_RESOURCE)];
computeResource->descSet = graphStorage->descriptorPool->Allocate({ computeResourceLayout }, { 1 });
#ifdef _DEBUG
for (auto set : computeResource->descSet->GetVkHandle())
@ -91,14 +94,22 @@ namespace SHADE
// bind the compute pipeline
cmdBuffer->BindPipeline(computePipeline);
// bind descriptor sets
cmdBuffer->BindDescriptorSet(graphResourceDescSets[frameIndex], SH_PIPELINE_TYPE::COMPUTE, SHGraphicsConstants::DescriptorSetIndex::RENDERGRAPH_RESOURCE, {});
auto const& descMappings = SHGraphicsPredefinedData::GetMappings(SHGraphicsPredefinedData::SystemType::RENDER_GRAPH_NODE_COMPUTE);
// bind render graph resource
cmdBuffer->BindDescriptorSet(graphResourceDescSets[frameIndex], SH_PIPELINE_TYPE::COMPUTE, descMappings.at(SHPredefinedDescriptorTypes::RENDER_GRAPH_RESOURCE), {});
// bind compute resource
if (computeResource)
{
cmdBuffer->BindDescriptorSet(computeResource->descSet, SH_PIPELINE_TYPE::COMPUTE, SHGraphicsConstants::DescriptorSetIndex::RENDERGRAPH_NODE_COMPUTE_RESOURCE, computeResource->dynamicOffsets[frameIndex]);
cmdBuffer->BindDescriptorSet(computeResource->descSet, SH_PIPELINE_TYPE::COMPUTE, descMappings.at(SHPredefinedDescriptorTypes::RENDER_GRAPH_NODE_COMPUTE_RESOURCE), computeResource->dynamicOffsets[frameIndex]);
}
// bind camera data
if (renderer)
renderer->BindDescriptorSet (cmdBuffer, SH_PIPELINE_TYPE::COMPUTE, descMappings.at(SHPredefinedDescriptorTypes::CAMERA), frameIndex);
// dispatch compute
cmdBuffer->ComputeDispatch(groupSizeX, groupSizeY, 1);
@ -109,8 +120,14 @@ namespace SHADE
void SHRenderGraphNodeCompute::HandleResize(void) noexcept
{
// We need to get from mappings because we want the introspected layout from the vector of layouts (of which the first few are predefined)
uint32_t RENDER_GRAPH_RESOURCE_SET_INDEX = SHGraphicsPredefinedData::GetMappings(SHGraphicsPredefinedData::SystemType::RENDER_GRAPH_NODE_COMPUTE).at (SHPredefinedDescriptorTypes::RENDER_GRAPH_RESOURCE);
// Since the descriptor set is standalone, the index we want to use is not the one in the shaders, it should always be 0.
uint32_t RENDER_GRAPH_RESOURCE_UPDATE_SET_INDEX = 0;
// Get the layout for the render graph resource. We can index it this way because the container returned is a container of layouts that includes the global ones
auto pipelineDescSetLayouts = computePipeline->GetPipelineLayout()->GetDescriptorSetLayoutsPipeline()[SHGraphicsConstants::DescriptorSetIndex::RENDERGRAPH_RESOURCE];
auto pipelineDescSetLayouts = computePipeline->GetPipelineLayout()->GetDescriptorSetLayoutsPipeline()[RENDER_GRAPH_RESOURCE_SET_INDEX];
// everything below here needs resizing
for (uint32_t frameIndex = 0; frameIndex < SHGraphicsConstants::NUM_FRAME_BUFFERS; ++frameIndex)
@ -123,8 +140,8 @@ namespace SHADE
uint32_t imageIndex = (resources[i]->resourceTypeFlags & static_cast<uint32_t>(SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR_PRESENT)) ? frameIndex : 0;
SHVkDescriptorSetGroup::viewSamplerLayout vsl = std::make_tuple(resources[i]->GetImageView(imageIndex), Handle<SHVkSampler>{}, vk::ImageLayout::eGeneral);
graphResourceDescSets[frameIndex]->ModifyWriteDescImage(SHGraphicsConstants::DescriptorSetIndex::RENDERGRAPH_RESOURCE, binding.BindPoint, { &vsl, 1 });
graphResourceDescSets[frameIndex]->UpdateDescriptorSetImages(SHGraphicsConstants::DescriptorSetIndex::RENDERGRAPH_RESOURCE, binding.BindPoint);
graphResourceDescSets[frameIndex]->ModifyWriteDescImage(RENDER_GRAPH_RESOURCE_UPDATE_SET_INDEX, binding.BindPoint, { &vsl, 1 });
graphResourceDescSets[frameIndex]->UpdateDescriptorSetImages(RENDER_GRAPH_RESOURCE_UPDATE_SET_INDEX, binding.BindPoint);
++i;
}
}
@ -181,16 +198,24 @@ namespace SHADE
}
}
void SHRenderGraphNodeCompute::ModifyWriteDescBufferComputeResource(uint32_t set, uint32_t binding, std::span<Handle<SHVkBuffer>> const& buffers, uint32_t offset, uint32_t range) noexcept
void SHRenderGraphNodeCompute::SetRenderer(Handle<SHRenderer> inRenderer) noexcept
{
computeResource->descSet->ModifyWriteDescBuffer(set, binding, buffers, offset, range);
computeResource->descSet->UpdateDescriptorSetBuffer(set, binding);
renderer = inRenderer;
}
void SHRenderGraphNodeCompute::ModifyWriteDescImageComputeResource(uint32_t set, uint32_t binding, std::span<SHVkDescriptorSetGroup::viewSamplerLayout> const& viewSamplerLayouts) noexcept
void SHRenderGraphNodeCompute::ModifyWriteDescBufferComputeResource(uint32_t binding, std::span<Handle<SHVkBuffer>> const& buffers, uint32_t offset, uint32_t range) noexcept
{
computeResource->descSet->ModifyWriteDescImage(set, binding, viewSamplerLayouts);
computeResource->descSet->UpdateDescriptorSetImages(set, binding);
static constexpr uint32_t COMPUTE_RESOURCE_SET_INDEX = 0;
computeResource->descSet->ModifyWriteDescBuffer(COMPUTE_RESOURCE_SET_INDEX, binding, buffers, offset, range);
computeResource->descSet->UpdateDescriptorSetBuffer(COMPUTE_RESOURCE_SET_INDEX, binding);
}
void SHRenderGraphNodeCompute::ModifyWriteDescImageComputeResource(uint32_t binding, std::span<SHVkDescriptorSetGroup::viewSamplerLayout> const& viewSamplerLayouts) noexcept
{
static constexpr uint32_t COMPUTE_RESOURCE_SET_INDEX = 0;
computeResource->descSet->ModifyWriteDescImage(COMPUTE_RESOURCE_SET_INDEX, binding, viewSamplerLayouts);
computeResource->descSet->UpdateDescriptorSetImages(COMPUTE_RESOURCE_SET_INDEX, binding);
}

View File

@ -7,6 +7,7 @@
#include <initializer_list>
#include <string>
#include <unordered_set>
#include "Resource/SHHandle.h"
namespace SHADE
{
@ -19,6 +20,7 @@ namespace SHADE
class SHVkShaderModule;
class SHVkCommandBuffer;
class SHVkBuffer;
class SHRenderer;
class SHRenderGraphNodeCompute
@ -53,6 +55,9 @@ namespace SHADE
//! vector of resources needed by the subpass compute
std::vector<Handle<SHRenderGraphResource>> resources;
//! For binding optional camera data to the post compute
Handle<SHRenderer> renderer;
//! X dimension work group size. Should scale with resource size.
uint32_t groupSizeX;
@ -75,9 +80,10 @@ namespace SHADE
void HandleResize (void) noexcept;
void SetDynamicOffsets (std::span<uint32_t> perFrameSizes) noexcept;
void SetRenderer (Handle<SHRenderer> inRenderer) noexcept;
void ModifyWriteDescBufferComputeResource (uint32_t set, uint32_t binding, std::span<Handle<SHVkBuffer>> const& buffers, uint32_t offset, uint32_t range) noexcept;
void ModifyWriteDescImageComputeResource(uint32_t set, uint32_t binding, std::span<SHVkDescriptorSetGroup::viewSamplerLayout> const& viewSamplerLayouts) noexcept;
void ModifyWriteDescBufferComputeResource (uint32_t binding, std::span<Handle<SHVkBuffer>> const& buffers, uint32_t offset, uint32_t range) noexcept;
void ModifyWriteDescImageComputeResource(uint32_t binding, std::span<SHVkDescriptorSetGroup::viewSamplerLayout> const& viewSamplerLayouts) noexcept;
friend class SHRenderGraph;

View File

@ -262,11 +262,13 @@ namespace SHADE
void SHRenderGraphResource::HandleResize(uint32_t newWidth, uint32_t newHeight) noexcept
{
width = newWidth;
height = newHeight;
if ((resourceTypeFlags & static_cast<uint32_t>(SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR_PRESENT)) == 0)
{
width = newWidth;
height = newHeight;
// prepare image view details
SHImageViewDetails viewDetails
{
@ -287,6 +289,9 @@ namespace SHADE
}
else
{
width = graphStorage->swapchain->GetWidth();
height = graphStorage->swapchain->GetHeight();
// Prepare image view details
SHImageViewDetails viewDetails
{

View File

@ -7,7 +7,7 @@ namespace SHADE
{
class SHVkLogicalDevice;
class SHVkSwapchain;
class SHGraphicsGlobalData;
class SHGraphicsPredefinedData;
class SHVkDescriptorPool;
class SHRenderGraphResource;

View File

@ -1,7 +1,7 @@
#include "SHpch.h"
#include "SHRenderToSwapchainImageSystem.h"
#include "Graphics/Devices/SHVkLogicalDevice.h"
#include "Graphics/MiddleEnd/GlobalData/SHGraphicsGlobalData.h"
#include "Graphics/MiddleEnd/GlobalData/SHGraphicsPredefinedData.h"
#include "Graphics/RenderGraph/SHRenderGraphNode.h"
#include "Graphics/RenderGraph/SHSubpass.h"
#include "Graphics/SHVkUtil.h"
@ -24,7 +24,7 @@ namespace SHADE
auto pipelineLayout = logicalDevice->CreatePipelineLayout(SHPipelineLayoutParams
{
.shaderModules = {shaderModules.first, shaderModules.second},
.globalDescSetLayouts = SHGraphicsGlobalData::GetDescSetLayouts(),
.predefinedDescSetLayouts = {}
});
pipeline = logicalDevice->CreateGraphicsPipeline(pipelineLayout, nullptr, renderGraphNode->GetRenderpass(), subpass);

View File

@ -11,6 +11,9 @@
#include "Graphics/Swapchain/SHVkSwapchain.h"
#include "Graphics/Images/SHVkSampler.h"
#include "SHRenderGraphResource.h"
#include "Graphics/MiddleEnd/Interface/SHViewport.h"
#include "Graphics/MiddleEnd/Interface/SHRenderer.h"
#include "Graphics/MiddleEnd/GlobalData/SHGraphicsPredefinedData.h"
namespace SHADE
{
@ -30,7 +33,7 @@ namespace SHADE
*/
/***************************************************************************/
SHSubpass::SHSubpass(const std::string& name, Handle<SHRenderGraphStorage> renderGraphStorage, Handle<SHRenderGraphNode> const& parent, uint32_t index, std::unordered_map<uint64_t, uint32_t> const* mapping) noexcept
SHSubpass::SHSubpass(const std::string& name, Handle<SHViewport> inViewport, Handle<SHRenderer> inRenderer, Handle<SHRenderGraphStorage> renderGraphStorage, Handle<SHRenderGraphNode> const& parent, uint32_t index, std::unordered_map<uint64_t, uint32_t> const* mapping) noexcept
: resourceAttachmentMapping{ mapping }
, parentNode{ parent }
, subpassIndex{ index }
@ -41,6 +44,8 @@ namespace SHADE
, name { name }
, graphStorage{ renderGraphStorage }
, inputImageDescriptorSets{}
, viewport {inViewport}
, renderer {inRenderer}
{
}
@ -63,7 +68,6 @@ namespace SHADE
, depthReferences{ std::move(rhs.depthReferences) }
, inputReferences{ std::move(rhs.inputReferences) }
, resourceAttachmentMapping{ rhs.resourceAttachmentMapping }
, descriptorSetLayout{ rhs.descriptorSetLayout }
, exteriorDrawCalls{ std::move(rhs.exteriorDrawCalls) }
, graphStorage{ rhs.graphStorage }
, inputNames{ std::move(rhs.inputNames) }
@ -71,6 +75,8 @@ namespace SHADE
, inputDescriptorLayout{ rhs.inputDescriptorLayout }
, inputSamplers{ rhs.inputSamplers }
, name { rhs.name }
, viewport {rhs.viewport}
, renderer {rhs.renderer}
{
}
@ -98,7 +104,6 @@ namespace SHADE
depthReferences = std::move(rhs.depthReferences);
inputReferences = std::move(rhs.inputReferences);
resourceAttachmentMapping = std::move(rhs.resourceAttachmentMapping);
descriptorSetLayout = rhs.descriptorSetLayout;
exteriorDrawCalls = std::move(rhs.exteriorDrawCalls);
graphStorage = rhs.graphStorage;
inputNames = std::move(rhs.inputNames);
@ -106,6 +111,9 @@ namespace SHADE
inputDescriptorLayout = rhs.inputDescriptorLayout;
inputSamplers = rhs.inputSamplers;
name = std::move(rhs.name);
renderer = rhs.renderer;
viewport = rhs.viewport;
return *this;
}
@ -199,21 +207,33 @@ namespace SHADE
inputReferences.push_back({ resourceAttachmentMapping->at(graphStorage->graphResources->at(resourceToReference).GetId().Raw), vk::ImageLayout::eGeneral });
}
void SHSubpass::Execute(Handle<SHVkCommandBuffer>& commandBuffer, Handle<SHVkDescriptorPool> descPool, uint32_t frameIndex) noexcept
void SHSubpass::Execute(Handle<SHVkCommandBuffer> commandBuffer, Handle<SHVkDescriptorPool> descPool, uint32_t frameIndex) noexcept
{
commandBuffer->BeginLabeledSegment(name);
// Ensure correct transforms are provided
superBatch->UpdateBuffers(frameIndex, descPool);
if (viewport)
{
// set viewport and scissor
uint32_t w = static_cast<uint32_t>(viewport->GetWidth());
uint32_t h = static_cast<uint32_t>(viewport->GetHeight());
commandBuffer->SetViewportScissor(static_cast<float>(w), static_cast<float>(h), w, h);
}
auto const& descMappings = SHGraphicsPredefinedData::GetMappings(SHGraphicsPredefinedData::SystemType::BATCHING);
if (renderer)
renderer->BindDescriptorSet(commandBuffer, SH_PIPELINE_TYPE::GRAPHICS, descMappings.at(SHPredefinedDescriptorTypes::CAMERA), frameIndex);
// Draw all the batches
superBatch->Draw(commandBuffer, frameIndex);
// Draw all the exterior draw calls
for (auto& drawCall : exteriorDrawCalls)
{
drawCall(commandBuffer, frameIndex);
drawCall(commandBuffer, renderer, frameIndex);
}
commandBuffer->EndLabeledSegment();
}
@ -223,15 +243,73 @@ namespace SHADE
UpdateWriteDescriptors();
}
void SHSubpass::BindDescriptorInputDescriptorSets(Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex) const noexcept
void SHSubpass::BindInputDescriptorSets(Handle<SHVkCommandBuffer> cmdBuffer, uint32_t setIndex, uint32_t frameIndex) const noexcept
{
if (!inputImageDescriptorSets.empty())
{
cmdBuffer->BindDescriptorSet(inputImageDescriptorSets[frameIndex], SH_PIPELINE_TYPE::GRAPHICS, SHGraphicsConstants::DescriptorSetIndex::RENDERGRAPH_RESOURCE, { });
cmdBuffer->BindDescriptorSet(inputImageDescriptorSets[frameIndex], SH_PIPELINE_TYPE::GRAPHICS, setIndex, { });
}
}
void SHSubpass::AddExteriorDrawCalls(std::function<void(Handle<SHVkCommandBuffer>&, uint32_t)> const& newDrawCall) noexcept
/***************************************************************************/
/*!
\brief
Removes all footprints of a resource in the subpass.
\param resourceName
Name of resource.
\param attachmentIndex
index of attachment.
*/
/***************************************************************************/
void SHSubpass::DetachResource(std::string const& resourceName, uint32_t attachmentIndex) noexcept
{
for (uint32_t i = 0; i < colorReferences.size(); ++i)
{
if (colorReferences[i].attachment == attachmentIndex)
{
colorReferences.erase (colorReferences.begin() + i);
break;
}
}
for (uint32_t i = 0; i < depthReferences.size(); ++i)
{
if (depthReferences[i].attachment == attachmentIndex)
{
depthReferences.erase(depthReferences.begin() + i);
break;
}
}
for (uint32_t i = 0; i < inputReferences.size(); ++i)
{
if (inputReferences[i].attachment == attachmentIndex)
{
inputReferences.erase(inputReferences.begin() + i);
break;
}
}
for (uint32_t i = 0; i < inputNames.size(); ++i)
{
if (inputNames[i] == resourceName)
{
inputNames.erase(inputNames.begin() + i);
break;
}
}
}
bool SHSubpass::HasNoAttachments(void) const noexcept
{
return colorReferences.empty() && depthReferences.empty() && inputReferences.empty();
}
void SHSubpass::AddExteriorDrawCalls(ExteriorDrawCallFunction const& newDrawCall) noexcept
{
exteriorDrawCalls.push_back(newDrawCall);
}
@ -247,6 +325,21 @@ namespace SHADE
if (inputNames.empty())
return;
for (auto& set : inputImageDescriptorSets)
{
if (set)
set.Free();
}
if (inputDescriptorLayout)
inputDescriptorLayout.Free();
for (auto& sampler : inputSamplers)
{
if (sampler)
sampler.Free();
}
inputImageDescriptorSets.resize(SHGraphicsConstants::NUM_FRAME_BUFFERS);
std::vector<SHVkDescriptorSetLayout::Binding> bindings{};
@ -266,7 +359,7 @@ namespace SHADE
}
// We build a new descriptor set layout to store our images
inputDescriptorLayout = graphStorage->logicalDevice->CreateDescriptorSetLayout(SHGraphicsConstants::DescriptorSetIndex::RENDERGRAPH_RESOURCE, bindings);
inputDescriptorLayout = graphStorage->logicalDevice->CreateDescriptorSetLayout(bindings);
// we store a sampler if its an input attachment. if it is storage image, no need sampler, store an empty handle.
for (uint32_t i = 0; i < bindings.size(); ++i)
@ -334,66 +427,36 @@ namespace SHADE
// Update descriptor sets
auto args = std::make_tuple(resource->GetImageView(viewIndex), inputSamplers[i], descriptorLayout);
group->ModifyWriteDescImage(SHGraphicsConstants::DescriptorSetIndex::RENDERGRAPH_RESOURCE, binding.BindPoint, std::span{&args, 1});
group->UpdateDescriptorSetImages(SHGraphicsConstants::DescriptorSetIndex::RENDERGRAPH_RESOURCE, binding.BindPoint);
// Since the descriptor set is standalone, the index we want to use is not the one in the shaders, it should always be 0.
uint32_t RENDER_GRAPH_RESOURCE_SET_INDEX = 0;
group->ModifyWriteDescImage(RENDER_GRAPH_RESOURCE_SET_INDEX, binding.BindPoint, std::span{&args, 1});
group->UpdateDescriptorSetImages(RENDER_GRAPH_RESOURCE_SET_INDEX, binding.BindPoint);
}
++i;
}
}
//void SHSubpass::InitComputeBarriers(void) noexcept
//{
// std::unordered_set <uint64_t> handleBarriers{};
/***************************************************************************/
/*!
// // we will have swapchainNumImages vectors of vector of barriers
// subpassComputeBarriers.resize(graphStorage->swapchain->GetNumImages());
\brief
This function is mainly used for the purposes of giving a subpass a new
index in the case another subpass in the node gets deleted, and subpasses
need to be re-indexed.
// for (auto sbCompute : subpassComputes)
// {
// // for every resource the subpass compute is using
// for (auto resource : sbCompute->resources)
// {
// // Get the resource handle
// uint64_t resourceRaw = resource.GetId().Raw;
\param index
New index of the subpass.
// // if the barrier is not registered
// if (!handleBarriers.contains(resourceRaw))
// {
// // If the resource is a swapchain image
// bool isSwapchainImage = (resource->resourceTypeFlags & static_cast<uint32_t>(SH_ATT_DESC_TYPE_FLAGS::COLOR_PRESENT));
// for (uint32_t i = 0; i < graphStorage->swapchain->GetNumImages(); ++i)
// {
// // if swapchain image, we want the index of the swapchain image, if not take base image
// uint32_t imageIndex = isSwapchainImage ? i : 0;
// // Prepare image barrier
// vk::ImageMemoryBarrier imageBarrier
// {
// .oldLayout = colorReferences[resourceAttachmentMapping->at(resource.GetId().Raw)].layout,
// .newLayout = vk::ImageLayout::eGeneral,
// .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
// .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
// .image = resource->GetImage(imageIndex)->GetVkImage(),
// .subresourceRange =
// {
// .aspectMask = resource->imageAspectFlags,
// .levelCount = resource->GetMipLevels(),
// .baseArrayLayer = 0,
// .layerCount = 1
// }
// };
// // push the barrier
// subpassComputeBarriers[i].push_back(imageBarrier);
// }
// // Image transition registered
// handleBarriers.emplace(resourceRaw);
// }
// }
// }
//}
*/
/***************************************************************************/
void SHSubpass::SetIndex(uint32_t index) noexcept
{
subpassIndex = index;
}
/***************************************************************************/
/*!

View File

@ -19,15 +19,28 @@ namespace SHADE
class SHRenderGraphStorage;
class SHVkShaderModule;
class SHVkSampler;
class SHRenderer;
class SHViewport;
class SH_API SHSubpass : public ISelfHandle<SHSubpass>
{
public:
using ExteriorDrawCallFunction = std::function<void(Handle<SHVkCommandBuffer>, Handle<SHRenderer>, uint32_t)>;
private:
/*---------------------------------------------------------------------*/
/* PRIVATE MEMBER VARIABLES */
/*---------------------------------------------------------------------*/
Handle<SHRenderGraphStorage> graphStorage;
//! Viewport to specify what part of the screen we want to draw on. This
//! will be used in vkCmdSetViewport/Scissor.
Handle<SHViewport> viewport;
//! Renderer used during the subpass execution. This dictates what matrix gets
//! passed to the shaders.
Handle<SHRenderer> renderer;
//! The index of the subpass in the render graph
uint32_t subpassIndex;
@ -37,9 +50,6 @@ namespace SHADE
//!
Handle<SHSuperBatch> superBatch;
//! Descriptor set layout to hold attachments
Handle<SHVkDescriptorSetLayout> descriptorSetLayout;
//! Color attachments
std::vector<vk::AttachmentReference> colorReferences;
@ -79,8 +89,9 @@ namespace SHADE
//! after we draw everything from the batch. Because of this, these draw calls
//! are always the last things drawn, so DO NOT USE THIS FUNCTIONALITY FOR ANYTHING
//! COMPLEX.
std::vector<std::function<void(Handle<SHVkCommandBuffer>&, uint32_t)>> exteriorDrawCalls;
/// For identifying subpasses
std::vector<ExteriorDrawCallFunction> exteriorDrawCalls;
// For identifying subpasses
std::string name;
@ -88,7 +99,7 @@ namespace SHADE
/*-----------------------------------------------------------------------*/
/* CTORS AND DTORS */
/*-----------------------------------------------------------------------*/
SHSubpass(const std::string& name, Handle<SHRenderGraphStorage> renderGraphStorage, Handle<SHRenderGraphNode> const& parent, uint32_t index, std::unordered_map<uint64_t, uint32_t> const* mapping) noexcept;
SHSubpass(const std::string& name, Handle<SHViewport> inViewport, Handle<SHRenderer> inRenderer, Handle<SHRenderGraphStorage> renderGraphStorage, Handle<SHRenderGraphNode> const& parent, uint32_t index, std::unordered_map<uint64_t, uint32_t> const* mapping) noexcept;
SHSubpass(SHSubpass&& rhs) noexcept;
SHSubpass& operator=(SHSubpass&& rhs) noexcept;
@ -102,12 +113,14 @@ namespace SHADE
void AddGeneralDepthOutput(std::string resourceToReference) noexcept;
void AddInput(std::string resourceToReference) noexcept;
void AddGeneralInput (std::string resourceToReference) noexcept;
void AddExteriorDrawCalls(std::function<void(Handle<SHVkCommandBuffer>&, uint32_t)> const& newDrawCall) noexcept;
void AddExteriorDrawCalls(ExteriorDrawCallFunction const& newDrawCall) noexcept;
// Runtime functions
void Execute(Handle<SHVkCommandBuffer>& commandBuffer, Handle<SHVkDescriptorPool> descPool, uint32_t frameIndex) noexcept;
void Execute(Handle<SHVkCommandBuffer> commandBuffer, Handle<SHVkDescriptorPool> descPool, uint32_t frameIndex) noexcept;
void HandleResize (void) noexcept;
void BindDescriptorInputDescriptorSets (Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex) const noexcept;
void BindInputDescriptorSets (Handle<SHVkCommandBuffer> cmdBuffer, uint32_t setIndex, uint32_t frameIndex) const noexcept;
void DetachResource (std::string const& resourceName, uint32_t attachmentIndex) noexcept;
bool HasNoAttachments (void) const noexcept;
void Init(SHResourceHub& resourceManager) noexcept;
@ -118,6 +131,10 @@ namespace SHADE
/*-----------------------------------------------------------------------*/
/* GETTERS AND SETTERS */
/*-----------------------------------------------------------------------*/
private:
void SetIndex (uint32_t index) noexcept;
public:
Handle<SHRenderGraphNode> const& GetParentNode(void) const noexcept;
SHSubPassIndex GetIndex() const noexcept;
Handle<SHSuperBatch> GetSuperBatch(void) const noexcept;

View File

@ -347,4 +347,14 @@ namespace SHADE
return vkDepthFormat;
}
uint32_t SHVkSwapchain::GetWidth(void) const noexcept
{
return width;
}
uint32_t SHVkSwapchain::GetHeight(void) const noexcept
{
return height;
}
}

View File

@ -101,6 +101,8 @@ namespace SHADE
vk::SwapchainKHR const& GetVkSwapchain (void) const noexcept;
vk::SurfaceFormatKHR GetSurfaceFormatKHR (void) const noexcept;
vk::Format GetDepthFormat (void) const noexcept;
uint32_t GetWidth (void) const noexcept;
uint32_t GetHeight (void) const noexcept;
};
}

View File

@ -10,6 +10,7 @@
#include "ECS_Base/Managers/SHComponentManager.h"
#include "Graphics/MiddleEnd/Materials/SHMaterialSpec.h"
#include "Tools/Logger/SHLog.h"
#include "Graphics/MiddleEnd/GlobalData/SHGraphicsPredefinedData.h"
namespace SHADE
@ -264,7 +265,8 @@ namespace SHADE
if(spec.properties.IsDefined())
{
auto fragShader = SHResourceManager::LoadOrGet<SHVkShaderModule>(spec.fragShader);
auto interface = fragShader->GetReflectedData().GetDescriptorBindingInfo().GetShaderBlockInterface(SHGraphicsConstants::DescriptorSetIndex::PER_INSTANCE, SHGraphicsConstants::DescriptorSetBindings::BATCHED_PER_INST_DATA);
auto const& mappings = SHGraphicsPredefinedData::GetMappings(SHGraphicsPredefinedData::SystemType::BATCHING);
auto interface = fragShader->GetReflectedData().GetDescriptorBindingInfo().GetShaderBlockInterface(mappings.at(SHPredefinedDescriptorTypes::MATERIALS), SHGraphicsConstants::DescriptorSetBindings::BATCHED_PER_INST_DATA);
int const varCount = static_cast<int>(interface->GetVariableCount());
for (int i = 0; i < varCount; ++i)

View File

@ -0,0 +1,67 @@
#pragma once
#include <iostream>
//namespace SHADE
//{
// template<typename BitType>
// class SHEnumWrapper
// {
// public:
// using UnderlyingType = typename std::underlying_type_t<BitType>;
//
// private:
// UnderlyingType mask;
//
// public:
//
// constexpr SHEnumWrapper(void) noexcept
// : mask{ 0 }
// {
//
// };
//
// constexpr SHEnumWrapper(BitType bit) noexcept
// : mask{ static_cast<UnderlyingType>(bit) }
// {
//
// };
//
// constexpr SHEnumWrapper(SHEnumWrapper<BitType> const& rhs) noexcept = default;
// constexpr SHEnumWrapper& operator= (SHEnumWrapper<BitType> const& rhs) noexcept = default;
//
// constexpr explicit SHEnumWrapper(UnderlyingType flags) noexcept
// : mask{ flags }
// {
//
// };
//
// constexpr SHEnumWrapper<BitType> operator| (SHEnumWrapper<BitType> const& rhs) const noexcept
// {
// return static_cast<SHEnumWrapper<BitType>> (mask | rhs.mask);
// };
//
// constexpr SHEnumWrapper<BitType> operator& (SHEnumWrapper<BitType> const& rhs) const noexcept
// {
// return static_cast<SHEnumWrapper<BitType>> (mask & rhs.mask);
// };
//
// constexpr operator UnderlyingType() const noexcept
// {
// return mask;
// };
// };
//
// template<typename BitType, typename = std::enable_if_t<std::is_enum_v<BitType>>>
// inline BitType operator|(const BitType& left, const BitType& right)
// {
// return static_cast<BitType>(static_cast<int>(left) | static_cast<int>(right));
// }
//
// template<typename BitType, typename = std::enable_if_t<std::is_enum_v<BitType>>>
// inline BitType operator&(const BitType& left, const BitType& right)
// {
// return static_cast<BitType>(static_cast<int>(left) & static_cast<int>(right));
// }
//
//}