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; vec4 Color;
} Out; } Out;
layout(set = 2, binding = 0) uniform CameraData layout(set = 1, binding = 0) uniform CameraData
{ {
vec4 position; vec4 position;
mat4 vpMat; mat4 vpMat;
mat4 viewMat; mat4 viewMat;
mat4 perspectiveMat; mat4 projMat;
mat4 orthoMat;
} cameraData; } cameraData;
void main() void main()

View File

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

View File

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

View File

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

View File

@ -28,7 +28,7 @@ layout(location = 3) flat in struct
} In2; } In2;
layout (set = 0, binding = 1) uniform sampler2D textures[]; // for textures (global) 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[]; MatPropData data[];
} MatProp; } MatProp;

Binary file not shown.

View File

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

Binary file not shown.

View File

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

Binary file not shown.

View File

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

Binary file not shown.

View File

@ -28,7 +28,7 @@ layout(location = 3) flat in struct
} In2; } In2;
layout (set = 0, binding = 1) uniform sampler2D textures[]; // for textures (global) 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[]; MatPropData data[];
} MatProp; } MatProp;

Binary file not shown.

View File

@ -26,7 +26,7 @@ layout(location = 3) flat in struct
} In2; } In2;
layout (set = 0, binding = 1) uniform sampler2D textures[]; // for textures (global) 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[]; MatPropData data[];
} MatProp; } MatProp;

View File

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

View File

@ -29,13 +29,12 @@ layout(location = 3) out struct
} Out2; } Out2;
layout(set = 2, binding = 0) uniform CameraData layout(set = 1, binding = 0) uniform CameraData
{ {
vec4 position; vec4 position;
mat4 vpMat; mat4 vpMat;
mat4 viewMat; mat4 viewMat;
mat4 perspectiveMat; mat4 projMat;
mat4 orthoMat;
} cameraData; } cameraData;
void main() 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 = 0) out vec4 color;
layout(location = 1) out uint outEntityID; layout(location = 1) out uint outEntityID;

Binary file not shown.

View File

@ -25,13 +25,12 @@ layout(location = 3) out struct
} Out2; } Out2;
// Camera data // Camera data
layout(set = 2, binding = 0) uniform CameraData layout(set = 1, binding = 0) uniform CameraData
{ {
vec4 position; vec4 position;
mat4 vpMat; mat4 vpMat;
mat4 viewMat; mat4 viewMat;
mat4 perspectiveMat; mat4 projMat;
mat4 orthoMat;
} cameraData; } cameraData;
// push constants // push constants
@ -44,7 +43,7 @@ layout(std140, push_constant) uniform TestPushConstant
} testPushConstant; } testPushConstant;
// Descriptor sets // Descriptor sets
layout(std430, set = 4, binding = 1) buffer GlyphTransforms layout(std430, set = 2, binding = 1) buffer GlyphTransforms
{ {
mat4 matrices[]; mat4 matrices[];
} glyphTransforms; } glyphTransforms;
@ -96,6 +95,6 @@ void main()
Out2.textColor = testPushConstant.textColor; Out2.textColor = testPushConstant.textColor;
// transform the vertex position to font space // 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); // 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_ARB_shading_language_420pack : enable
#extension GL_EXT_nonuniform_qualifier : require #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; layout(location = 0) out vec4 fragColor;

View File

@ -28,7 +28,7 @@ layout(location = 3) flat in struct
} In2; } In2;
layout (set = 0, binding = 1) uniform sampler2D textures[]; // for textures (global) 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[]; MatPropData data[];
} MatProp; } MatProp;

Binary file not shown.

View File

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

Binary file not shown.

View File

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

View File

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

View File

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

View File

@ -5,21 +5,22 @@ typedef uint32_t SHEventIdentifier;
typedef uint32_t SHEventHandle; typedef uint32_t SHEventHandle;
//Add your event identifiers here: //Add your event identifiers here:
constexpr SHEventIdentifier SH_EXAMPLE_EVENT { 0 }; constexpr SHEventIdentifier SH_EXAMPLE_EVENT { 0 };
constexpr SHEventIdentifier SH_ENTITY_DESTROYED_EVENT { 1 }; constexpr SHEventIdentifier SH_ENTITY_DESTROYED_EVENT { 1 };
constexpr SHEventIdentifier SH_ENTITY_CREATION_EVENT { 2 }; constexpr SHEventIdentifier SH_ENTITY_CREATION_EVENT { 2 };
constexpr SHEventIdentifier SH_COMPONENT_ADDED_EVENT { 3 }; constexpr SHEventIdentifier SH_COMPONENT_ADDED_EVENT { 3 };
constexpr SHEventIdentifier SH_COMPONENT_REMOVED_EVENT { 4 }; constexpr SHEventIdentifier SH_COMPONENT_REMOVED_EVENT { 4 };
constexpr SHEventIdentifier SH_SCENEGRAPH_CHANGE_PARENT_EVENT { 5 }; constexpr SHEventIdentifier SH_SCENEGRAPH_CHANGE_PARENT_EVENT { 5 };
constexpr SHEventIdentifier SH_SCENEGRAPH_ADD_CHILD_EVENT { 6 }; constexpr SHEventIdentifier SH_SCENEGRAPH_ADD_CHILD_EVENT { 6 };
constexpr SHEventIdentifier SH_SCENEGRAPH_REMOVE_CHILD_EVENT { 7 }; constexpr SHEventIdentifier SH_SCENEGRAPH_REMOVE_CHILD_EVENT { 7 };
constexpr SHEventIdentifier SH_PHYSICS_COLLIDER_ADDED_EVENT { 8 }; constexpr SHEventIdentifier SH_PHYSICS_COLLIDER_ADDED_EVENT { 8 };
constexpr SHEventIdentifier SH_PHYSICS_COLLIDER_REMOVED_EVENT { 9 }; constexpr SHEventIdentifier SH_PHYSICS_COLLIDER_REMOVED_EVENT { 9 };
constexpr SHEventIdentifier SH_EDITOR_ON_PLAY_EVENT { 10 }; constexpr SHEventIdentifier SH_EDITOR_ON_PLAY_EVENT { 10 };
constexpr SHEventIdentifier SH_EDITOR_ON_PAUSE_EVENT { 11 }; constexpr SHEventIdentifier SH_EDITOR_ON_PAUSE_EVENT { 11 };
constexpr SHEventIdentifier SH_EDITOR_ON_STOP_EVENT { 12 }; constexpr SHEventIdentifier SH_EDITOR_ON_STOP_EVENT { 12 };
constexpr SHEventIdentifier SH_SCENE_INIT_PRE { 13 }; constexpr SHEventIdentifier SH_SCENE_INIT_PRE { 13 };
constexpr SHEventIdentifier SH_SCENE_INIT_POST { 14 }; constexpr SHEventIdentifier SH_SCENE_INIT_POST { 14 };
constexpr SHEventIdentifier SH_SCENE_EXIT_PRE { 15 }; constexpr SHEventIdentifier SH_SCENE_EXIT_PRE { 15 };
constexpr SHEventIdentifier SH_SCENE_EXIT_POST { 16 }; 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); uint32_t bindPointIndex = static_cast<uint32_t>(bindPoint);
vkCommandBuffer.bindDescriptorSets(SHVkUtil::GetPipelineBindPointFromType(bindPoint), bindPointData[bindPointIndex].boundPipelineLayoutHdl->GetVkPipelineLayout(), firstSet, descSetGroup->GetVkHandle(), dynamicOffsets); 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 BindPipeline (Handle<SHVkPipeline> const& pipelineHdl) noexcept;
void BindVertexBuffer (uint32_t bindingPoint, Handle<SHVkBuffer> const& buffer, vk::DeviceSize offset) 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 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 // Draw Commands
void DrawArrays (uint32_t vertexCount, uint32_t instanceCount, uint32_t firstVertex, uint32_t firstInstance) const noexcept; 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) for (uint32_t i = 0; i < layouts.size(); ++i)
{ {
vkLayouts[i] = layouts[i]->GetVkHandle(); vkLayouts[i] = layouts[i]->GetVkHandle();
setIndexing.emplace(layouts[i]->GetSetIndex(), i);
} }
// Check for variable descriptor count // Check for variable descriptor count
@ -87,7 +86,7 @@ namespace SHADE
for (auto& binding : bindings) for (auto& binding : bindings)
{ {
BindingAndSetHash writeHash = binding.BindPoint; 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 // new write for the binding
updater.writeInfos.emplace_back(); updater.writeInfos.emplace_back();
@ -208,16 +207,13 @@ namespace SHADE
// Get binding + set hash // Get binding + set hash
BindingAndSetHash bsHash = SHVkUtil::GenBindingSetHash(set, binding); BindingAndSetHash bsHash = SHVkUtil::GenBindingSetHash(set, binding);
// to index a set
uint32_t setIndex = setIndexing[set];
// to index a write for a binding // to index a write for a binding
uint32_t writeInfoIndex = updater.writeHashMap[bsHash]; uint32_t writeInfoIndex = updater.writeHashMap[bsHash];
// Initialize info for write // Initialize info for write
writeDescSet.descriptorType = layoutsUsed[setIndex]->GetBindings()[binding].Type; writeDescSet.descriptorType = layoutsUsed[set]->GetBindings()[binding].Type;
writeDescSet.dstArrayElement = 0; writeDescSet.dstArrayElement = 0;
writeDescSet.dstSet = descSets[setIndex]; writeDescSet.dstSet = descSets[set];
writeDescSet.dstBinding = binding; writeDescSet.dstBinding = binding;
writeDescSet.pImageInfo = updater.writeInfos[writeInfoIndex].descImageInfos.data(); writeDescSet.pImageInfo = updater.writeInfos[writeInfoIndex].descImageInfos.data();
@ -233,16 +229,13 @@ namespace SHADE
// Get binding + set hash // Get binding + set hash
BindingAndSetHash bsHash = SHVkUtil::GenBindingSetHash(set, binding); BindingAndSetHash bsHash = SHVkUtil::GenBindingSetHash(set, binding);
// to index a set
uint32_t setIndex = setIndexing[set];
// to index a write for a binding // to index a write for a binding
uint32_t writeInfoIndex = updater.writeHashMap[bsHash]; uint32_t writeInfoIndex = updater.writeHashMap[bsHash];
// Initialize info for write // Initialize info for write
writeDescSet.descriptorType = layoutsUsed[setIndex]->GetBindings()[binding].Type; writeDescSet.descriptorType = layoutsUsed[set]->GetBindings()[binding].Type;
writeDescSet.dstArrayElement = 0; writeDescSet.dstArrayElement = 0;
writeDescSet.dstSet = descSets[setIndex]; writeDescSet.dstSet = descSets[set];
writeDescSet.dstBinding = binding; writeDescSet.dstBinding = binding;
writeDescSet.pBufferInfo = updater.writeInfos[writeInfoIndex].descBufferInfos.data(); writeDescSet.pBufferInfo = updater.writeInfos[writeInfoIndex].descBufferInfos.data();

View File

@ -21,7 +21,6 @@ namespace SHADE
class SHVkImageView; class SHVkImageView;
class SHVkBuffer; class SHVkBuffer;
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
/* Type Definitions */ /* Type Definitions */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
@ -91,10 +90,10 @@ namespace SHADE
//! Descriptor pool to allocate descriptor sets //! Descriptor pool to allocate descriptor sets
Handle<SHVkDescriptorPool> descPool; Handle<SHVkDescriptorPool> descPool;
//! Sometimes when we pass in a layout, the set of the layout used in the ////! 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 ////! shader cannot be used to index into descSets. This is to mitigate that issue
//! when we update descriptor sets. ////! when we update descriptor sets.
std::unordered_map<SetIndex, uint32_t> setIndexing; //std::unordered_map<SetIndex, uint32_t> setIndexing;
//! Descriptor sets //! Descriptor sets
std::vector<vk::DescriptorSet> descSets; std::vector<vk::DescriptorSet> descSets;

View File

@ -5,146 +5,138 @@
namespace SHADE namespace SHADE
{ {
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
/* Constructor/Destructor */ /* Constructor/Destructor */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
SHVkDescriptorSetLayout::SHVkDescriptorSetLayout(Handle<SHVkLogicalDevice> device, SetIndex set, const std::vector<Binding>& bindings, bool genImmutableSamplers/* = false*/) SHVkDescriptorSetLayout::SHVkDescriptorSetLayout(Handle<SHVkLogicalDevice> device, const std::vector<Binding>& bindings, bool genImmutableSamplers/* = false*/)
: device { device } : device{ device }
, layoutDesc { bindings } , layoutDesc{ bindings }
, setIndex {set}
, immutableSampler{} , immutableSampler{}
{
// Check if auto-binding point calculation configuration is valid
bool autoCalc = false;
for (const auto& binding : bindings)
{ {
// Check if auto-binding point calculation configuration is valid if (binding.BindPoint == Binding::AUTO_CALC_BINDING)
bool autoCalc = false;
for (const auto& binding : bindings)
{
if (binding.BindPoint == Binding::AUTO_CALC_BINDING)
{
autoCalc = true;
}
else if (autoCalc)
{
throw std::invalid_argument("For auto calculation of bindings, all bindings must be set to AUTO_CALC_BINDING!");
}
}
vk::Sampler tempVkSampler = nullptr;
if (genImmutableSamplers)
{
// Create sampler
immutableSampler = device->CreateSampler(
{
.minFilter = vk::Filter::eLinear,
.magFilter = vk::Filter::eLinear,
.addressMode = vk::SamplerAddressMode::eRepeat,
.mipmapMode = vk::SamplerMipmapMode::eLinear,
.minLod = -1000,
.maxLod = 1000
}
);
tempVkSampler = immutableSampler->GetVkSampler();
}
// Fill up VK bindings with auto calculated bind points if needed
std::vector<vk::DescriptorSetLayoutBinding> layoutBindings;
layoutBindings.reserve(bindings.size());
int bindCount = 0;
for (const auto& binding : bindings)
{
const uint32_t CURR_BIND_POINT = autoCalc ? bindCount : binding.BindPoint;
const vk::DescriptorSetLayoutBinding VK_BINDING =
{
.binding = CURR_BIND_POINT,
.descriptorType = binding.Type,
.descriptorCount = binding.DescriptorCount,
.stageFlags = binding.Stage,
.pImmutableSamplers = genImmutableSamplers ? &tempVkSampler : nullptr,
};
layoutBindings.emplace_back(VK_BINDING);
// Save for future reference
layoutDesc[bindCount++].BindPoint = CURR_BIND_POINT;
}
// TODO: Check layout support with physical device
// Prepare binding flags
std::vector<vk::DescriptorBindingFlags> combinedBindings(bindings.size());
for (uint32_t i = 0; i < bindings.size(); ++i)
combinedBindings[i] = bindings[i].flags;
const vk::DescriptorSetLayoutBindingFlagsCreateInfo BINDING_FLAGS_CREATE_INFO
{
.bindingCount = static_cast<uint32_t>(bindings.size()), // Number of flags = number of bindings
.pBindingFlags = combinedBindings.data(), // address to flags
};
// Create the layout
const vk::DescriptorSetLayoutCreateInfo DESC_SET_LAYOUT_CREATE_INFO
{
.pNext = &BINDING_FLAGS_CREATE_INFO,
.flags = {},
.bindingCount = static_cast<uint32_t>(layoutBindings.size()),
.pBindings = layoutBindings.data(),
};
setLayout = device->GetVkLogicalDevice().createDescriptorSetLayout(DESC_SET_LAYOUT_CREATE_INFO);
}
SHVkDescriptorSetLayout::SHVkDescriptorSetLayout(SHVkDescriptorSetLayout&& rhs) noexcept
: device {rhs.device}
, setLayout {rhs.setLayout}
, layoutDesc{std::move (rhs.layoutDesc)}
, setIndex{ rhs.setIndex }
, immutableSampler{ rhs.immutableSampler }
{
rhs.setLayout = VK_NULL_HANDLE;
}
SHVkDescriptorSetLayout::~SHVkDescriptorSetLayout() noexcept
{
// Destroy layout
if (setLayout)
device->GetVkLogicalDevice().destroyDescriptorSetLayout(setLayout);
}
std::vector<SHVkDescriptorSetLayout::Binding> const& SHVkDescriptorSetLayout::GetBindings(void) const noexcept
{
return layoutDesc;
}
SetIndex SHVkDescriptorSetLayout::GetSetIndex(void) const noexcept
{
return setIndex;
}
uint32_t SHVkDescriptorSetLayout::GetNumDynamicOffsetsRequired(void) const noexcept
{
uint32_t numDynamicBindings = 0;
for (auto& binding : layoutDesc)
{ {
if (binding.Type == vk::DescriptorType::eUniformBufferDynamic || binding.Type == vk::DescriptorType::eStorageBufferDynamic) autoCalc = true;
++numDynamicBindings; }
else if (autoCalc)
{
throw std::invalid_argument("For auto calculation of bindings, all bindings must be set to AUTO_CALC_BINDING!");
} }
return numDynamicBindings;
} }
SHVkDescriptorSetLayout& SHVkDescriptorSetLayout::operator=(SHVkDescriptorSetLayout&& rhs) noexcept vk::Sampler tempVkSampler = nullptr;
if (genImmutableSamplers)
{ {
if (&rhs == this) // Create sampler
return *this; immutableSampler = device->CreateSampler(
{
.minFilter = vk::Filter::eLinear,
.magFilter = vk::Filter::eLinear,
.addressMode = vk::SamplerAddressMode::eRepeat,
.mipmapMode = vk::SamplerMipmapMode::eLinear,
.minLod = -1000,
.maxLod = 1000
}
);
device = rhs.device; tempVkSampler = immutableSampler->GetVkSampler();
setLayout = rhs.setLayout;
layoutDesc = std::move(rhs.layoutDesc);
setIndex = rhs.setIndex;
immutableSampler = rhs.immutableSampler;
rhs.setLayout = VK_NULL_HANDLE;
return *this;
} }
// Fill up VK bindings with auto calculated bind points if needed
std::vector<vk::DescriptorSetLayoutBinding> layoutBindings;
layoutBindings.reserve(bindings.size());
int bindCount = 0;
for (const auto& binding : bindings)
{
const uint32_t CURR_BIND_POINT = autoCalc ? bindCount : binding.BindPoint;
const vk::DescriptorSetLayoutBinding VK_BINDING =
{
.binding = CURR_BIND_POINT,
.descriptorType = binding.Type,
.descriptorCount = binding.DescriptorCount,
.stageFlags = binding.Stage,
.pImmutableSamplers = genImmutableSamplers ? &tempVkSampler : nullptr,
};
layoutBindings.emplace_back(VK_BINDING);
// Save for future reference
layoutDesc[bindCount++].BindPoint = CURR_BIND_POINT;
}
// TODO: Check layout support with physical device
// Prepare binding flags
std::vector<vk::DescriptorBindingFlags> combinedBindings(bindings.size());
for (uint32_t i = 0; i < bindings.size(); ++i)
combinedBindings[i] = bindings[i].flags;
const vk::DescriptorSetLayoutBindingFlagsCreateInfo BINDING_FLAGS_CREATE_INFO
{
.bindingCount = static_cast<uint32_t>(bindings.size()), // Number of flags = number of bindings
.pBindingFlags = combinedBindings.data(), // address to flags
};
// Create the layout
const vk::DescriptorSetLayoutCreateInfo DESC_SET_LAYOUT_CREATE_INFO
{
.pNext = &BINDING_FLAGS_CREATE_INFO,
.flags = {},
.bindingCount = static_cast<uint32_t>(layoutBindings.size()),
.pBindings = layoutBindings.data(),
};
setLayout = device->GetVkLogicalDevice().createDescriptorSetLayout(DESC_SET_LAYOUT_CREATE_INFO);
}
SHVkDescriptorSetLayout::SHVkDescriptorSetLayout(SHVkDescriptorSetLayout&& rhs) noexcept
: device{ rhs.device }
, setLayout{ rhs.setLayout }
, layoutDesc{ std::move(rhs.layoutDesc) }
, immutableSampler{ rhs.immutableSampler }
{
rhs.setLayout = VK_NULL_HANDLE;
}
SHVkDescriptorSetLayout::~SHVkDescriptorSetLayout() noexcept
{
// Destroy layout
if (setLayout)
device->GetVkLogicalDevice().destroyDescriptorSetLayout(setLayout);
}
std::vector<SHVkDescriptorSetLayout::Binding> const& SHVkDescriptorSetLayout::GetBindings(void) const noexcept
{
return layoutDesc;
}
uint32_t SHVkDescriptorSetLayout::GetNumDynamicOffsetsRequired(void) const noexcept
{
uint32_t numDynamicBindings = 0;
for (auto& binding : layoutDesc)
{
if (binding.Type == vk::DescriptorType::eUniformBufferDynamic || binding.Type == vk::DescriptorType::eStorageBufferDynamic)
++numDynamicBindings;
}
return numDynamicBindings;
}
SHVkDescriptorSetLayout& SHVkDescriptorSetLayout::operator=(SHVkDescriptorSetLayout&& rhs) noexcept
{
if (&rhs == this)
return *this;
device = rhs.device;
setLayout = rhs.setLayout;
layoutDesc = std::move(rhs.layoutDesc);
immutableSampler = rhs.immutableSampler;
rhs.setLayout = VK_NULL_HANDLE;
return *this;
}
} }

View File

@ -6,109 +6,107 @@
namespace SHADE namespace SHADE
{ {
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
/* Forward Declarations */ /* Forward Declarations */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
class SHVkLogicalDevice; class SHVkLogicalDevice;
class SHVkSampler; class SHVkSampler;
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
/* Type Definitions */ /* Type Definitions */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
/// <summary>
/// RAII wrapper object for a Vulkan Descriptor Set Layout object.
/// </summary>
class SHVkDescriptorSetLayout
{
public:
/*-----------------------------------------------------------------------------*/
/* Type Definitions */
/*-----------------------------------------------------------------------------*/
/// <summary> /// <summary>
/// RAII wrapper object for a Vulkan Descriptor Set Layout object. /// Object that describes how a descriptor binding in a DescriptorSetLayout is
/// structured.
/// </summary> /// </summary>
class SHVkDescriptorSetLayout struct Binding
{ {
public: /*-------------------------------------------------------------------------*/
/*-----------------------------------------------------------------------------*/ /* Constants */
/* Type Definitions */ /*-------------------------------------------------------------------------*/
/*-----------------------------------------------------------------------------*/ /// <summary>
/// <summary> /// If set for the "BindPoint", binding points are automatically calculated.
/// Object that describes how a descriptor binding in a DescriptorSetLayout is /// </summary>
/// structured. static constexpr uint32_t AUTO_CALC_BINDING = std::numeric_limits<uint32_t>::max();
/// </summary>
struct Binding
{
/*-------------------------------------------------------------------------*/
/* Constants */
/*-------------------------------------------------------------------------*/
/// <summary>
/// If set for the "BindPoint", binding points are automatically calculated.
/// </summary>
static constexpr uint32_t AUTO_CALC_BINDING = std::numeric_limits<uint32_t>::max();
/// <summary> /// <summary>
/// For use in Binding DescriptorCount. /// For use in Binding DescriptorCount.
/// </summary> /// </summary>
static constexpr uint32_t VARIABLE_DESCRIPTOR_UPPER_BOUND = 2000; static constexpr uint32_t VARIABLE_DESCRIPTOR_UPPER_BOUND = 2000;
/*-------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------*/
/* Data Members */ /* Data Members */
/*-------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------*/
/// <summary> /// <summary>
/// Type of element for the descriptor. /// Type of element for the descriptor.
/// </summary> /// </summary>
vk::DescriptorType Type = {}; vk::DescriptorType Type = {};
/// <summary> /// <summary>
/// Shader stage that this binding is for. /// Shader stage that this binding is for.
/// </summary> /// </summary>
vk::ShaderStageFlags Stage = {}; vk::ShaderStageFlags Stage = {};
/// <summary> /// <summary>
/// Binding point for the Descriptor within the Descriptor Set. /// Binding point for the Descriptor within the Descriptor Set.
/// </summary> /// </summary>
uint32_t BindPoint = AUTO_CALC_BINDING; uint32_t BindPoint = AUTO_CALC_BINDING;
/// <summary> /// <summary>
/// Number of elements in the binding. When VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT /// Number of elements in the binding. When VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT
/// is used in VkDescriptorBindingFlagBits, this value represents the upper bound. /// is used in VkDescriptorBindingFlagBits, this value represents the upper bound.
/// </summary> /// </summary>
uint32_t DescriptorCount = 1; uint32_t DescriptorCount = 1;
vk::DescriptorBindingFlags flags = {}; vk::DescriptorBindingFlags flags = {};
};
/*-----------------------------------------------------------------------------*/
/* Constructor/Destructors */
/*-----------------------------------------------------------------------------*/
SHVkDescriptorSetLayout() = delete;
/// <summary>
/// Constructs a DescriptorSetLayout with the specified properties and device.
/// </summary>
/// <param name="device"></param>
/// <param name="bindings"></param>
SHVkDescriptorSetLayout(Handle<SHVkLogicalDevice> device, SetIndex setIndex, const std::vector<Binding>& bindings, bool genImmutableSamplers = false);
SHVkDescriptorSetLayout(const SHVkDescriptorSetLayout&) = delete;
SHVkDescriptorSetLayout(SHVkDescriptorSetLayout&& rhs) noexcept;
/// <summary>
/// Destructor which will unload and deallocate all resources for this Set.
/// </summary>
~SHVkDescriptorSetLayout() noexcept;
/*-----------------------------------------------------------------------------*/
/* Overloaded Operators */
/*-----------------------------------------------------------------------------*/
SHVkDescriptorSetLayout& operator=(const SHVkDescriptorSetLayout&) = delete;
SHVkDescriptorSetLayout& operator=(SHVkDescriptorSetLayout&& rhs) noexcept;
/*-----------------------------------------------------------------------------*/
/* Getter Functions */
/*-----------------------------------------------------------------------------*/
/// <summary>
/// Retrieves the handle to the Vulkan Descriptor Set Layout handle.
/// </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;
private:
/*-----------------------------------------------------------------------------*/
/* Data Members */
/*-----------------------------------------------------------------------------*/
Handle<SHVkLogicalDevice> device;
vk::DescriptorSetLayout setLayout;
std::vector<Binding> layoutDesc; // Stores description of the layout
SetIndex setIndex; // Index of the set
Handle<SHVkSampler> immutableSampler;
}; };
/*-----------------------------------------------------------------------------*/
/* Constructor/Destructors */
/*-----------------------------------------------------------------------------*/
SHVkDescriptorSetLayout() = delete;
/// <summary>
/// Constructs a DescriptorSetLayout with the specified properties and device.
/// </summary>
/// <param name="device"></param>
/// <param name="bindings"></param>
SHVkDescriptorSetLayout(Handle<SHVkLogicalDevice> device, const std::vector<Binding>& bindings, bool genImmutableSamplers = false);
SHVkDescriptorSetLayout(const SHVkDescriptorSetLayout&) = delete;
SHVkDescriptorSetLayout(SHVkDescriptorSetLayout&& rhs) noexcept;
/// <summary>
/// Destructor which will unload and deallocate all resources for this Set.
/// </summary>
~SHVkDescriptorSetLayout() noexcept;
/*-----------------------------------------------------------------------------*/
/* Overloaded Operators */
/*-----------------------------------------------------------------------------*/
SHVkDescriptorSetLayout& operator=(const SHVkDescriptorSetLayout&) = delete;
SHVkDescriptorSetLayout& operator=(SHVkDescriptorSetLayout&& rhs) noexcept;
/*-----------------------------------------------------------------------------*/
/* Getter Functions */
/*-----------------------------------------------------------------------------*/
/// <summary>
/// Retrieves the handle to the Vulkan Descriptor Set Layout handle.
/// </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;
uint32_t GetNumDynamicOffsetsRequired(void) const noexcept;
private:
/*-----------------------------------------------------------------------------*/
/* Data Members */
/*-----------------------------------------------------------------------------*/
Handle<SHVkLogicalDevice> device;
vk::DescriptorSetLayout setLayout;
std::vector<Binding> layoutDesc; // Stores description of the layout
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 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::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<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<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<SHVkDescriptorPool> CreateDescriptorPools (const SHVkDescriptorPool::Config& config = {}) noexcept;
Handle<SHVkDescriptorSetGroup> CreateDescriptorSetGroup(Handle<SHVkDescriptorPool> pool, Handle<SHVkDescriptorSetGroup> CreateDescriptorSetGroup(Handle<SHVkDescriptorPool> pool,
std::vector<Handle<SHVkDescriptorSetLayout>> const& layouts, 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 "Graphics/Descriptors/SHVkDescriptorSetGroup.h"
#include "ECS_Base/Managers/SHComponentManager.h" #include "ECS_Base/Managers/SHComponentManager.h"
#include "Math/Transform/SHTransformComponent.h" #include "Math/Transform/SHTransformComponent.h"
#include "Graphics/MiddleEnd/GlobalData/SHGraphicsGlobalData.h" #include "Graphics/MiddleEnd/GlobalData/SHGraphicsPredefinedData.h"
#include "Graphics/Descriptors/SHVkDescriptorPool.h" #include "Graphics/Descriptors/SHVkDescriptorPool.h"
#include "Scene/SHSceneManager.h" #include "Scene/SHSceneManager.h"
#include "UI/SHUIComponent.h" #include "UI/SHUIComponent.h"
@ -411,11 +411,12 @@ namespace SHADE
instancedIntegerData.reserve(numTotalElements); instancedIntegerData.reserve(numTotalElements);
instancedIntegerData.clear(); instancedIntegerData.clear();
auto const& descMappings = SHGraphicsPredefinedData::GetMappings(SHGraphicsPredefinedData::SystemType::BATCHING);
// - Material Properties Data // - Material Properties Data
const Handle<SHShaderBlockInterface> SHADER_INFO = pipeline->GetPipelineLayout()->GetShaderBlockInterface const Handle<SHShaderBlockInterface> SHADER_INFO = pipeline->GetPipelineLayout()->GetShaderBlockInterface
( (
SHGraphicsConstants::DescriptorSetIndex::PER_INSTANCE, descMappings.at(SHPredefinedDescriptorTypes::MATERIALS),
SHGraphicsConstants::DescriptorSetBindings::BATCHED_PER_INST_DATA, SHGraphicsConstants::DescriptorSetBindings::BATCHED_PER_INST_DATA,
vk::ShaderStageFlagBits::eFragment vk::ShaderStageFlagBits::eFragment
); );
@ -570,11 +571,14 @@ namespace SHADE
cmdBuffer->BindVertexBuffer(SHGraphicsConstants::VertexBufferBindings::INTEGER_DATA, instancedIntegerBuffer[frameIndex], 0); cmdBuffer->BindVertexBuffer(SHGraphicsConstants::VertexBufferBindings::INTEGER_DATA, instancedIntegerBuffer[frameIndex], 0);
if (matPropsDescSet[frameIndex]) if (matPropsDescSet[frameIndex])
{ {
auto const& descMappings = SHGraphicsPredefinedData::GetMappings(SHGraphicsPredefinedData::SystemType::BATCHING);
cmdBuffer->BindDescriptorSet cmdBuffer->BindDescriptorSet
( (
matPropsDescSet[frameIndex], matPropsDescSet[frameIndex],
SH_PIPELINE_TYPE::GRAPHICS, SH_PIPELINE_TYPE::GRAPHICS,
SHGraphicsConstants::DescriptorSetIndex::PER_INSTANCE, //SHGraphicsConstants::DescriptorSetIndex::PER_INSTANCE,
descMappings.at(SHPredefinedDescriptorTypes::MATERIALS),
dynamicOffset dynamicOffset
); );
} }
@ -582,6 +586,31 @@ namespace SHADE
cmdBuffer->EndLabeledSegment(); 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 */ /* SHBatch - Helper Functions */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
@ -607,7 +636,7 @@ namespace SHADE
{ {
matPropsDescSet[frameIndex] = descPool->Allocate matPropsDescSet[frameIndex] = descPool->Allocate
( (
{ SHGraphicsGlobalData::GetDescSetLayouts()[SHGraphicsConstants::DescriptorSetIndex::PER_INSTANCE] }, SHGraphicsPredefinedData::GetPredefinedDescSetLayouts(SHGraphicsPredefinedData::PredefinedDescSetLayoutTypes::MATERIALS),
{ 0 } { 0 }
); );
#ifdef _DEBUG #ifdef _DEBUG
@ -618,17 +647,20 @@ namespace SHADE
} }
#endif #endif
} }
static constexpr uint32_t MATERIAL_DESC_SET_INDEX = 0;
std::array<Handle<SHVkBuffer>, 1> bufferList = { matPropsBuffer[frameIndex] }; std::array<Handle<SHVkBuffer>, 1> bufferList = { matPropsBuffer[frameIndex] };
matPropsDescSet[frameIndex]->ModifyWriteDescBuffer matPropsDescSet[frameIndex]->ModifyWriteDescBuffer
( (
SHGraphicsConstants::DescriptorSetIndex::PER_INSTANCE, MATERIAL_DESC_SET_INDEX,
SHGraphicsConstants::DescriptorSetBindings::BATCHED_PER_INST_DATA, SHGraphicsConstants::DescriptorSetBindings::BATCHED_PER_INST_DATA,
bufferList, bufferList,
0, static_cast<uint32_t>(matPropsDataSize) 0, static_cast<uint32_t>(matPropsDataSize)
); );
matPropsDescSet[frameIndex]->UpdateDescriptorSetBuffer matPropsDescSet[frameIndex]->UpdateDescriptorSetBuffer
( (
SHGraphicsConstants::DescriptorSetIndex::PER_INSTANCE, MATERIAL_DESC_SET_INDEX,
SHGraphicsConstants::DescriptorSetBindings::BATCHED_PER_INST_DATA SHGraphicsConstants::DescriptorSetBindings::BATCHED_PER_INST_DATA
); );
} }

View File

@ -94,6 +94,8 @@ namespace SHADE
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
Handle<SHVkPipeline> GetPipeline() const noexcept { return pipeline; }; Handle<SHVkPipeline> GetPipeline() const noexcept { return pipeline; };
bool IsEmpty() const noexcept { return subBatches.empty(); } bool IsEmpty() const noexcept { return subBatches.empty(); }
Handle<SHVkBuffer> GetTransformBuffer(uint32_t frameIndex) const noexcept;
Handle<SHVkBuffer> GetMDIBuffer(uint32_t frameIndex) const noexcept;
private: private:
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
@ -122,7 +124,7 @@ namespace SHADE
std::unique_ptr<char> matPropsData; std::unique_ptr<char> matPropsData;
Byte matPropsDataSize = 0; Byte matPropsDataSize = 0;
Byte singleMatPropAlignedSize = 0; Byte singleMatPropAlignedSize = 0;
Byte singleMatPropSize = 0; Byte singleMatPropSize = 0;
bool isCPUBuffersDirty = true; bool isCPUBuffersDirty = true;
// GPU Buffers // GPU Buffers
TripleBuffer drawDataBuffer; TripleBuffer drawDataBuffer;

View File

@ -54,7 +54,7 @@ namespace SHADE
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
void Add(const SHRenderable* renderable) noexcept; void Add(const SHRenderable* renderable) noexcept;
void Remove(const SHRenderable* renderable) noexcept; void Remove(const SHRenderable* renderable) noexcept;
void Clear() noexcept; void Clear() noexcept;
void UpdateBuffers(uint32_t frameIndex, Handle<SHVkDescriptorPool> descPool); void UpdateBuffers(uint32_t frameIndex, Handle<SHVkDescriptorPool> descPool);
void Build(Handle<SHVkLogicalDevice> device, Handle<SHVkDescriptorPool> descPool, uint32_t frameIndex) noexcept; void Build(Handle<SHVkLogicalDevice> device, Handle<SHVkDescriptorPool> descPool, uint32_t frameIndex) noexcept;
void Draw(Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex) noexcept; void Draw(Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex) noexcept;
@ -63,6 +63,7 @@ namespace SHADE
/* Getter Functions */ /* Getter Functions */
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
Handle<SHSubpass> GetSubpass() const noexcept { return subpass; }; Handle<SHSubpass> GetSubpass() const noexcept { return subpass; };
const std::vector<SHBatch>& GetBatches() const noexcept { return batches; }
private: 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(); createMeshBatches();
// Register function for subpass // Register function for subpass
auto const& RENDERERS = gfxSystem->GetDefaultViewport()->GetRenderers(); //auto const& RENDERERS = gfxSystem->GetDefaultViewport()->GetRenderers();
auto renderGraph = RENDERERS[SHGraphicsConstants::RenderGraphIndices::WORLD]->GetRenderGraph(); auto renderGraph = gfxSystem->GetRenderGraph();
auto subPass = renderGraph->GetNode("Debug Draw")->GetSubpass("Debug Draw"); 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(); const uint32_t FRAME_IDX = gfxSystem->GetCurrentFrameIndex();
cmdBuffer->BeginLabeledSegment("SHDebugDraw (No Depth Test)"); cmdBuffer->BeginLabeledSegment("SHDebugDraw (No Depth Test)");
@ -126,7 +126,7 @@ namespace SHADE
cmdBuffer->EndLabeledSegment(); cmdBuffer->EndLabeledSegment();
}); });
auto subPassWithDepth = renderGraph->GetNode("Debug Draw with Depth")->GetSubpass("Debug Draw with Depth"); 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(); const uint32_t FRAME_IDX = gfxSystem->GetCurrentFrameIndex();
cmdBuffer->BeginLabeledSegment("SHDebugDraw (Depth Tested)"); cmdBuffer->BeginLabeledSegment("SHDebugDraw (Depth Tested)");

View File

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

View File

@ -19,7 +19,6 @@ of DigiPen Institute of Technology is prohibited.
#include "Camera/SHCameraSystem.h" #include "Camera/SHCameraSystem.h"
#include "Editor/SHEditor.h" #include "Editor/SHEditor.h"
#include "ECS_Base/Managers/SHSystemManager.h" #include "ECS_Base/Managers/SHSystemManager.h"
//#include "SHRenderer.h"
#include "Graphics/Windowing/SHWindow.h" #include "Graphics/Windowing/SHWindow.h"
#include "Graphics/MiddleEnd/PerFrame/SHPerFrameData.h" #include "Graphics/MiddleEnd/PerFrame/SHPerFrameData.h"
#include "Graphics/MiddleEnd/Interface/SHViewport.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/Interface/SHRenderable.h"
#include "Graphics/MiddleEnd/Batching/SHSuperBatch.h" #include "Graphics/MiddleEnd/Batching/SHSuperBatch.h"
#include "SHGraphicsConstants.h" #include "SHGraphicsConstants.h"
#include "Graphics/MiddleEnd/GlobalData/SHGraphicsGlobalData.h" #include "Graphics/MiddleEnd/GlobalData/SHGraphicsPredefinedData.h"
#include "Graphics/Buffers/SHVkBuffer.h" #include "Graphics/Buffers/SHVkBuffer.h"
#include "Graphics/Images/SHVkSampler.h" #include "Graphics/Images/SHVkSampler.h"
#include "Assets/Asset Types/SHTextureAsset.h" #include "Assets/Asset Types/SHTextureAsset.h"
@ -44,6 +43,7 @@ of DigiPen Institute of Technology is prohibited.
#include "../Meshes/SHPrimitiveGenerator.h" #include "../Meshes/SHPrimitiveGenerator.h"
#include "Graphics/MiddleEnd/TextRendering/SHFreetypeInstance.h" #include "Graphics/MiddleEnd/TextRendering/SHFreetypeInstance.h"
#include "Graphics/MiddleEnd/TextRendering/SHTextRenderingSubSystem.h" #include "Graphics/MiddleEnd/TextRendering/SHTextRenderingSubSystem.h"
#include "Graphics/MiddleEnd/GlobalData/SHGlobalDescriptorSets.h"
namespace SHADE namespace SHADE
{ {
@ -139,7 +139,7 @@ namespace SHADE
static constexpr AssetID RENDER_SC_FS = 36869006; renderToSwapchainFS = SHResourceManager::LoadOrGet<SHVkShaderModule>(RENDER_SC_FS); 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 /* MIDDLE END SETUP
@ -153,82 +153,82 @@ namespace SHADE
auto windowDims = window->GetWindowSize(); auto windowDims = window->GetWindowSize();
auto cameraSystem = SHSystemManager::GetSystem<SHCameraSystem>(); 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(); 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 // 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)); 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() }; std::vector<Handle<SHVkCommandPool>> renderContextCmdPools{ swapchain->GetNumImages() };
for (uint32_t i = 0; i < renderContextCmdPools.size(); ++i) for (uint32_t i = 0; i < renderContextCmdPools.size(); ++i)
{ {
renderContextCmdPools[i] = renderContext.GetFrameData(i).cmdPoolHdls[0]; renderContextCmdPools[i] = renderContext.GetFrameData(i).cmdPoolHdls[0];
} }
// Get render graph from default viewport world renderer
renderGraph = resourceManager.Create<SHRenderGraph>();
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
/* WORLD RENDER GRAPH RESOURCES */ /* WORLD RENDER GRAPH RESOURCES */
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
// Initialize world render graph // Initialize world render graph
worldRenderGraph->Init("World Render Graph", device, swapchain, &resourceManager); renderGraph->Init("World Render Graph", device, swapchain, &resourceManager, renderContextCmdPools);
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); 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);
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->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("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); 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);
worldRenderGraph->AddResource("Depth Buffer", { SH_RENDER_GRAPH_RESOURCE_FLAGS::DEPTH_STENCIL }, windowDims.first, windowDims.second, vk::Format::eD32SfloatS8Uint); renderGraph->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); 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);
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); 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);
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); 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);
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); 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);
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("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 */ /* MAIN NODE */
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
auto gBufferNode = worldRenderGraph->AddNode("G-Buffer", auto gBufferNode = renderGraph->AddNode("G-Buffer",
{ {
"Position", "Position",
"Entity ID", "Entity ID",
"Light Layer Indices", "Light Layer Indices",
"Normals", "Normals",
//"Tangents",
"Albedo", "Albedo",
"Depth Buffer", "Depth Buffer",
"Scene",
"SSAO", "SSAO",
"SSAO Blur" "SSAO Blur"
}, },
{}); // no predecessors {}); // no predecessors
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
/* G-BUFFER SUBPASS INIT */ /* 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("Position");
gBufferSubpass->AddColorOutput("Entity ID"); gBufferSubpass->AddColorOutput("Entity ID");
gBufferSubpass->AddColorOutput("Light Layer Indices"); gBufferSubpass->AddColorOutput("Light Layer Indices");
gBufferSubpass->AddColorOutput("Normals"); gBufferSubpass->AddColorOutput("Normals");
//gBufferSubpass->AddColorOutput("Tangents");
gBufferSubpass->AddColorOutput("Albedo"); gBufferSubpass->AddColorOutput("Albedo");
gBufferSubpass->AddDepthOutput("Depth Buffer", SH_RENDER_GRAPH_RESOURCE_FLAGS::DEPTH_STENCIL); gBufferSubpass->AddDepthOutput("Depth Buffer", SH_RENDER_GRAPH_RESOURCE_FLAGS::DEPTH_STENCIL);
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
/* SSAO PASS AND DATA INIT */ /* SSAO PASS AND DATA INIT */
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
ssaoStorage = resourceManager.Create<SHSSAO>(); ssaoStorage = resourceManager.Create<SHSSAO>();
// command buffer operation to transfer data for ssao
ssaoTransferCmdBuffer = graphicsCmdPool->RequestCommandBuffer(SH_CMD_BUFFER_TYPE::PRIMARY); ssaoTransferCmdBuffer = graphicsCmdPool->RequestCommandBuffer(SH_CMD_BUFFER_TYPE::PRIMARY);
SET_VK_OBJ_NAME(device, vk::ObjectType::eCommandBuffer, ssaoTransferCmdBuffer->GetVkCommandBuffer(), "[Command Buffer] SSAO Pass (Graphics)"); SET_VK_OBJ_NAME(device, vk::ObjectType::eCommandBuffer, ssaoTransferCmdBuffer->GetVkCommandBuffer(), "[Command Buffer] SSAO Pass (Graphics)");
ssaoTransferCmdBuffer->BeginRecording(); ssaoTransferCmdBuffer->BeginRecording();
@ -237,95 +237,102 @@ namespace SHADE
ssaoTransferCmdBuffer->EndRecording(); ssaoTransferCmdBuffer->EndRecording();
graphicsQueue->SubmitCommandBuffer({ ssaoTransferCmdBuffer }); 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(); graphicsQueue->WaitIdle();
ssaoStorage->PrepareRotationVectorsVkData(device); ssaoStorage->PrepareRotationVectorsVkData(device);
// Add the pass to generate an image with just SSAO data
Handle<SHRenderGraphNodeCompute> ssaoPass = gBufferNode->AddNodeCompute("SSAO", ssaoShader, { "Position", "Normals", "SSAO" }); Handle<SHRenderGraphNodeCompute> ssaoPass = gBufferNode->AddNodeCompute("SSAO", ssaoShader, { "Position", "Normals", "SSAO" });
auto ssaoDataBuffer = ssaoStorage->GetBuffer(); 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(); 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 */ /* DEFERRED COMPOSITE SUBPASS INIT */
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
gBufferNode->AddNodeCompute("Deferred Composite", deferredCompositeShader, {"Position", "Normals", "Albedo", "Light Layer Indices", "SSAO Blur", "Scene"}); deferredCompositeNode->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");
}
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
/* GENERATE WORLD RENDER GRAPH */ /* DEBUG DRAW PASS INIT */
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
// Generate world render graph // Set up Debug Draw Passes
worldRenderGraph->Generate(); // - 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 auto screenSpaceNode = renderGraph->AddNode("Screen Space Pass", { "Scene", "Entity ID" }, {"Deferred Comp Pass", "G-Buffer", "Debug Draw" });
screenRenderGraph = resourceManager.Create<SHRenderGraph>(); auto uiSubpass = screenSpaceNode->AddSubpass("UI", worldViewport, screenRenderer);
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");
uiSubpass->AddColorOutput("Scene"); uiSubpass->AddColorOutput("Scene");
uiSubpass->AddColorOutput("Entity ID"); 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 #ifdef SHEDITOR
{ {
// Dummy Node to transition scene render graph resource // Dummy Node to transition scene render graph resource
auto dummyNode = screenRenderGraph->AddNode("Dummy Pass", { "Scene" }, { "Screen Space Pass" }); // no predecessors auto dummyNode = renderGraph->AddNode("Dummy Pass", { "Scene" }, { "Screen Space Pass" });
auto dummySubpass = dummyNode->AddSubpass("Dummy Subpass"); auto dummySubpass = dummyNode->AddSubpass("Dummy Subpass", {}, {});
dummySubpass->AddInput("Scene"); dummySubpass->AddInput("Scene");
}
auto imGuiNode = renderGraph->AddNode("ImGui Node", { "Present" }, {});
auto imGuiSubpass = imGuiNode->AddSubpass("ImGui Draw", {}, {});
imGuiSubpass->AddColorOutput("Present");
}
#else #else
screenRenderGraph->AddRenderToSwapchainNode("Scene", "Present", {"Screen Space Pass"}, {renderToSwapchainVS, renderToSwapchainFS}); renderGraph->AddRenderToSwapchainNode("Scene", "Present", { "Screen Space Pass" }, { renderToSwapchainVS, renderToSwapchainFS });
#endif #endif
screenRenderGraph->Generate();
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
/* BIND RENDER GRAPH TO RENDERER */ /* GENERATE RENDER GRAPH */
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
// Add world renderer to default viewport // Generate render graph
worldRenderer = worldViewport->AddRenderer(resourceManager, swapchain->GetNumImages(), renderContextCmdPools, descPool, SHGraphicsGlobalData::GetDescSetLayouts()[SHGraphicsConstants::DescriptorSetIndex::HIGH_FREQUENCY_GLOBALS], worldRenderGraph); renderGraph->Generate();
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);
// Create debug draw pipeline // Create debug draw pipeline
debugDrawPipeline = createDebugDrawPipeline(debugDrawNode->GetRenderpass(), debugDrawSubpass, false, false, false); debugDrawPipeline = createDebugDrawPipeline(debugDrawNode->GetRenderpass(), debugDrawSubpass, false, false, false);
@ -356,13 +363,10 @@ namespace SHADE
void SHGraphicsSystem::InitMiddleEnd(void) noexcept void SHGraphicsSystem::InitMiddleEnd(void) noexcept
{ {
SHGraphicsGlobalData::Init(device); SHGraphicsPredefinedData::Init(device);
InitSceneRenderGraph(); InitRenderGraph();
#ifdef SHEDITOR
InitEditorRenderGraph();
#endif
// Create Semaphore // Create Semaphore
for (auto& semaHandle : graphSemaphores) for (auto& semaHandle : graphSemaphores)
@ -374,7 +378,7 @@ namespace SHADE
void SHGraphicsSystem::InitSubsystems(void) noexcept void SHGraphicsSystem::InitSubsystems(void) noexcept
{ {
mousePickSystem = resourceManager.Create<SHMousePickSystem>(); mousePickSubSystem = resourceManager.Create<SHMousePickSystem>();
std::vector<Handle<SHVkCommandPool>> cmdPools; std::vector<Handle<SHVkCommandPool>> cmdPools;
cmdPools.reserve(swapchain->GetNumImages()); cmdPools.reserve(swapchain->GetNumImages());
@ -382,11 +386,11 @@ namespace SHADE
cmdPools.push_back(renderContext.GetFrameData(i).cmdPoolHdls[0]); cmdPools.push_back(renderContext.GetFrameData(i).cmdPoolHdls[0]);
// Mouse picking system for the editor (Will still run with editor disabled) // 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 // Register the post offscreen render to the system
postOffscreenRender = resourceManager.Create<SHPostOffscreenRenderSystem>(); postOffscreenRenderSubSystem = resourceManager.Create<SHPostOffscreenRenderSystem>();
postOffscreenRender->Init(device, worldRenderGraph->GetRenderGraphResource("Scene"), descPool); postOffscreenRenderSubSystem->Init(device, renderGraph->GetRenderGraphResource("Scene"), descPool);
lightingSubSystem = resourceManager.Create<SHLightingSubSystem>(); lightingSubSystem = resourceManager.Create<SHLightingSubSystem>();
lightingSubSystem->Init(device, descPool); lightingSubSystem->Init(device, descPool);
@ -394,11 +398,10 @@ namespace SHADE
textRenderingSubSystem = resourceManager.Create<SHTextRenderingSubSystem>(); textRenderingSubSystem = resourceManager.Create<SHTextRenderingSubSystem>();
// initialize the text renderer // initialize the text renderer
auto uiNode = screenRenderGraph->GetNode("Screen Space Pass"); auto uiNode = renderGraph->GetNode("Screen Space Pass");
textRenderingSubSystem->Init(device, uiNode->GetRenderpass(), uiNode->GetSubpass("UI"), descPool, textVS, textFS, [=](Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex) textRenderingSubSystem->Init(device, uiNode->GetRenderpass(), uiNode->GetSubpass("UI"), descPool, textVS, textFS);
{
screenRenderer->BindDescSet(cmdBuffer, frameIndex); SHGlobalDescriptorSets::SetLightingSubSystem(lightingSubSystem);
});
} }
@ -422,42 +425,21 @@ namespace SHADE
defaultMaterial = AddMaterial defaultMaterial = AddMaterial
( (
defaultVertShader, defaultFragShader, defaultVertShader, defaultFragShader,
worldRenderGraph->GetNode("G-Buffer")->GetSubpass("G-Buffer Write") renderGraph->GetNode("G-Buffer")->GetSubpass("G-Buffer Write")
); );
defaultMaterial->SetProperty("data.textureIndex", defaultTexture->TextureArrayIndex); defaultMaterial->SetProperty("data.textureIndex", defaultTexture->TextureArrayIndex);
} }
#ifdef SHEDITOR
void SHGraphicsSystem::InitEditorRenderGraph(void) noexcept void SHGraphicsSystem::InitEvents(void) noexcept
{ {
auto windowDims = window->GetWindowSize(); std::shared_ptr<SHEventReceiverSpec<SHGraphicsSystem>> thisReceiver
{
// Create Default Viewport std::make_shared<SHEventReceiverSpec<SHGraphicsSystem>>(this, &SHGraphicsSystem::ReceiveLightEnableShadowEvent)
editorViewport = AddViewport(vk::Viewport(0.0f, 0.0f, static_cast<float>(windowDims.first), static_cast<float>(windowDims.second), 0.0f, 1.0f)); };
ReceiverPtr receiver = std::dynamic_pointer_cast<SHEventReceiver>(thisReceiver);
// Get render graph from viewport editor renderer SHEventManager::SubscribeTo(SH_GRAPHICS_LIGHT_ENABLE_SHADOW_EVENT, receiver);
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);
} }
#endif
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
/* Constructor/Destructors */ /* Constructor/Destructors */
@ -544,99 +526,52 @@ namespace SHADE
textRenderingSubSystem->Run(frameIndex); 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)
{
/*-----------------------------------------------------------------------*/
/* Renderer start */
/*-----------------------------------------------------------------------*/
// get command buffer of the renderer in the current frame
auto currentCmdBuffer = renderers[renIndex]->GetCommandBuffer(frameIndex);
// 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);
// Bind all the buffers required for meshes
for (auto& [buffer, bindingPoint] : MESH_DATA)
{
if (buffer->GetUsageBits() & vk::BufferUsageFlagBits::eVertexBuffer)
currentCmdBuffer->BindVertexBuffer(bindingPoint, buffer, 0);
else if (buffer->GetUsageBits() & vk::BufferUsageFlagBits::eIndexBuffer)
currentCmdBuffer->BindIndexBuffer(buffer, 0);
}
lightingSubSystem->BindDescSet(currentCmdBuffer, 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 #ifdef SHEDITOR
if (renderers[renIndex] == worldRenderer) if (renderer == worldRenderer)
{ {
auto editorSystem = SHSystemManager::GetSystem<SHEditor>(); auto editorSystem = SHSystemManager::GetSystem<SHEditor>();
if (editorSystem->editorState != SHEditor::State::PLAY) if (editorSystem->editorState != SHEditor::State::PLAY)
worldRenderer->UpdateDataAndBind(currentCmdBuffer, frameIndex, cameraSystem->GetEditorCamera()->GetViewMatrix(), cameraSystem->GetEditorCamera()->GetProjMatrix(), cameraSystem->GetEditorCamera()->GetOrthoMatrix()); worldRenderer->UpdateDataManual(frameIndex, cameraSystem->GetEditorCamera()->GetViewMatrix(), cameraSystem->GetEditorCamera()->GetProjMatrix());
else
renderers[renIndex]->UpdateDataAndBind(currentCmdBuffer, frameIndex);
}
else else
renderers[renIndex]->UpdateDataAndBind(currentCmdBuffer, frameIndex); renderer->UpdateData(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] },
{ vk::PipelineStageFlagBits::eColorAttachmentOutput },
{ (vpIndex == viewports.size() - 1 && renIndex == renderers.size() - 1) ? frameData.fenceHdl : Handle<SHVkFence>{} }
);
semIndex = !semIndex;
} }
else
renderer->UpdateData(frameIndex);
#else
renderers[renIndex]->UpdateDataAndBind(frameIndex);
#endif
} }
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)
cmdBuffer->BindVertexBuffer(bindingPoint, buffer, 0);
else if (buffer->GetUsageBits() & vk::BufferUsageFlagBits::eIndexBuffer)
cmdBuffer->BindIndexBuffer(buffer, 0);
}
renderGraph->Execute(frameIndex, descPool);
renderGraph->End(frameIndex);
graphicsQueue->SubmitCommandBuffer
(
{ renderGraph->GetCommandBuffer(frameIndex) },
{ frameData.semRenderFinishHdl },
{ frameData.semImgAvailableHdl },
{ vk::PipelineStageFlagBits::eColorAttachmentOutput },
{ frameData.fenceHdl }
);
} }
/***************************************************************************/ /***************************************************************************/
/*! /*!
@ -674,12 +609,8 @@ namespace SHADE
// #BackEndTest: For for the fence initialized by queue submit // #BackEndTest: For for the fence initialized by queue submit
renderContext.WaitForFence(); renderContext.WaitForFence();
// Finalise all batches // finalize batches for render graph
for (auto vp : viewports) renderGraph->FinaliseBatch(renderContext.GetCurrentFrame(), descPool);
for (auto renderer : vp->GetRenderers())
{
renderer->GetRenderGraph()->FinaliseBatch(renderContext.GetCurrentFrame(), descPool);
}
// #BackEndTest: Acquire the next image in the swapchain available // #BackEndTest: Acquire the next image in the swapchain available
renderContext.AcquireNextIamge(); renderContext.AcquireNextIamge();
@ -720,7 +651,7 @@ namespace SHADE
const uint32_t CURR_FRAME_IDX = renderContext.GetCurrentFrame(); const uint32_t CURR_FRAME_IDX = renderContext.GetCurrentFrame();
auto& currFrameData = renderContext.GetCurrentFrameData(); auto& currFrameData = renderContext.GetCurrentFrameData();
mousePickSystem->Run(graphicsQueue, CURR_FRAME_IDX); mousePickSubSystem->Run(graphicsQueue, CURR_FRAME_IDX);
// #BackEndTest: queues an image for presentation // #BackEndTest: queues an image for presentation
if (auto result = graphicsQueue->Present(swapchain, { currFrameData.semRenderFinishHdl }, CURR_FRAME_IDX); result != vk::Result::eSuccess) if (auto result = graphicsQueue->Present(swapchain, { currFrameData.semRenderFinishHdl }, CURR_FRAME_IDX); result != vk::Result::eSuccess)
@ -760,6 +691,52 @@ namespace SHADE
viewports.erase(iter); 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) Handle<SHMaterial> SHGraphicsSystem::AddMaterial(Handle<SHVkShaderModule> vertShader, Handle<SHVkShaderModule> fragShader, Handle<SHSubpass> subpass)
{ {
// Retrieve pipeline from pipeline storage or create if unavailable // Retrieve pipeline from pipeline storage or create if unavailable
@ -883,6 +860,8 @@ namespace SHADE
); );
device->WaitIdle(); device->WaitIdle();
graphicsTexCmdBuffer.Free(); graphicsTexCmdBuffer = {}; graphicsTexCmdBuffer.Free(); graphicsTexCmdBuffer = {};
SHGlobalDescriptorSets::SetStaticGlobalDataDescriptorSet(texLibrary.GetTextureDescriptorSetGroup());
} }
Handle<SHTexture> SHGraphicsSystem::GetTextureHandle(SHTexture::Index textureId) const Handle<SHTexture> SHGraphicsSystem::GetTextureHandle(SHTexture::Index textureId) const
@ -900,7 +879,7 @@ namespace SHADE
void SHGraphicsSystem::BuildFonts(void) noexcept 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 #pragma endregion ADD_REMOVE
@ -1044,6 +1023,10 @@ namespace SHADE
graphSemaphores[0].Free(); graphSemaphores[0].Free();
graphSemaphores[1].Free(); graphSemaphores[1].Free();
for (auto& semaHandle : graphSemaphores)
semaHandle = device->CreateSemaphore();
auto windowDims = window->GetWindowSize(); auto windowDims = window->GetWindowSize();
// Resize the swapchain // Resize the swapchain
@ -1051,23 +1034,21 @@ namespace SHADE
renderContext.HandleResize(); renderContext.HandleResize();
worldRenderGraph->HandleResize(resizeWidth, resizeHeight); renderGraph->HandleResize(resizeWidth, resizeHeight);
#ifdef SHEDITOR #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 #endif
screenRenderGraph->HandleResize(resizeWidth, resizeHeight); mousePickSubSystem->HandleResize();
postOffscreenRenderSubSystem->HandleResize();
mousePickSystem->HandleResize();
postOffscreenRender->HandleResize();
worldViewport->SetWidth(static_cast<float>(resizeWidth)); worldViewport->SetWidth(static_cast<float>(resizeWidth));
worldViewport->SetHeight(static_cast<float>(resizeHeight)); 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>(); auto cameraSystem = SHSystemManager::GetSystem<SHCameraSystem>();
#ifdef SHEDITOR #ifdef SHEDITOR
cameraSystem->GetEditorCamera()->SetWidth(static_cast<float>(resizeWidth)); cameraSystem->GetEditorCamera()->SetWidth(static_cast<float>(resizeWidth));
@ -1076,8 +1057,6 @@ namespace SHADE
#endif #endif
for (auto& semaHandle : graphSemaphores)
semaHandle = device->CreateSemaphore();
} }
void SHGraphicsSystem::AwaitGraphicsExecution() void SHGraphicsSystem::AwaitGraphicsExecution()
@ -1091,9 +1070,14 @@ namespace SHADE
} }
Handle<SHRenderGraph> SHGraphicsSystem::GetRenderGraph(void) const noexcept
{
return renderGraph;
}
Handle<SHRenderGraphNode> SHGraphicsSystem::GetPrimaryRenderpass() const noexcept 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 Handle<SHVkPipeline> SHGraphicsSystem::GetDebugDrawPipeline(DebugDrawPipelineType type) const noexcept
@ -1126,7 +1110,7 @@ namespace SHADE
device, SHPipelineLayoutParams device, SHPipelineLayoutParams
{ {
.shaderModules = { (instanced ? debugMeshVertShader : debugVertShader) , debugFragShader }, .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); 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 "Graphics/MiddleEnd/PostProcessing/SHSSAO.h"
#include "Camera/SHCameraDirector.h" #include "Camera/SHCameraDirector.h"
#include "Graphics/MiddleEnd/TextRendering/SHFontLibrary.h" #include "Graphics/MiddleEnd/TextRendering/SHFontLibrary.h"
#include "Graphics/MiddleEnd/Interface/SHRenderer.h"
#include "Graphics/Events/SHGraphicsEvents.h"
namespace SHADE namespace SHADE
{ {
@ -49,9 +51,7 @@ namespace SHADE
class SHVkImage; class SHVkImage;
class SHVkFramebuffer; class SHVkFramebuffer;
class SHVkCommandBuffer; class SHVkCommandBuffer;
class SHRenderer;
class SHViewport; class SHViewport;
class SHCamera;
class SHVkShaderModule; class SHVkShaderModule;
class SHMaterial; class SHMaterial;
class SHMaterialInstance; class SHMaterialInstance;
@ -99,14 +99,11 @@ namespace SHADE
{ {
private: private:
void InitBoilerplate (void) noexcept; void InitBoilerplate (void) noexcept;
void InitSceneRenderGraph (void) noexcept; void InitRenderGraph (void) noexcept;
void InitMiddleEnd (void) noexcept; void InitMiddleEnd (void) noexcept;
void InitSubsystems (void) noexcept; void InitSubsystems (void) noexcept;
void InitBuiltInResources (void); void InitBuiltInResources (void);
void InitEvents (void) noexcept;
#ifdef SHEDITOR
void InitEditorRenderGraph (void) noexcept;
#endif
public: public:
class SH_API BeginRoutine final : public SHSystemRoutine class SH_API BeginRoutine final : public SHSystemRoutine
@ -171,6 +168,17 @@ namespace SHADE
Handle<SHViewport> AddViewport(const vk::Viewport& viewport); Handle<SHViewport> AddViewport(const vk::Viewport& viewport);
void RemoveViewport(Handle<SHViewport> 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 */ /* Material Functions */
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
@ -382,8 +390,9 @@ namespace SHADE
#ifdef SHEDITOR #ifdef SHEDITOR
Handle<SHViewport> GetEditorViewport () const {return editorViewport;}; Handle<SHViewport> GetEditorViewport () const {return editorViewport;};
#endif #endif
Handle<SHMousePickSystem> GetMousePickSystem(void) const noexcept {return mousePickSystem;}; Handle<SHMousePickSystem> GetMousePickSystem(void) const noexcept {return mousePickSubSystem;};
Handle<SHPostOffscreenRenderSystem> GetPostOffscreenRenderSystem(void) const noexcept {return postOffscreenRender;}; Handle<SHPostOffscreenRenderSystem> GetPostOffscreenRenderSystem(void) const noexcept {return postOffscreenRenderSubSystem;};
Handle<SHRenderGraph> GetRenderGraph (void) const noexcept;
Handle<SHRenderGraphNode> GetPrimaryRenderpass() const noexcept; Handle<SHRenderGraphNode> GetPrimaryRenderpass() const noexcept;
Handle<SHVkPipeline> GetDebugDrawPipeline(DebugDrawPipelineType type) const noexcept; Handle<SHVkPipeline> GetDebugDrawPipeline(DebugDrawPipelineType type) const noexcept;
uint32_t GetCurrentFrameIndex(void) const noexcept { return renderContext.GetCurrentFrame(); } uint32_t GetCurrentFrameIndex(void) const noexcept { return renderContext.GetCurrentFrame(); }
@ -441,10 +450,8 @@ namespace SHADE
// Renderers // Renderers
Handle<SHRenderer> worldRenderer; Handle<SHRenderer> worldRenderer;
Handle<SHRenderer> screenRenderer; Handle<SHRenderer> screenRenderer;
std::vector<Handle<SHRenderer>> renderers;
// Temp Cameras
Handle<SHCamera> worldCamera;
Handle<SHCamera> screenCamera;
DirectorHandle worldCameraDirector; DirectorHandle worldCameraDirector;
@ -483,15 +490,15 @@ namespace SHADE
std::array<Handle<SHMesh>, MAX_PRIMITIVE_TYPES> primitiveMeshes; std::array<Handle<SHMesh>, MAX_PRIMITIVE_TYPES> primitiveMeshes;
// Render Graphs // Render Graphs
Handle<SHRenderGraph> worldRenderGraph; Handle<SHRenderGraph> renderGraph;
Handle<SHRenderGraph> screenRenderGraph; //Handle<SHRenderGraph> screenRenderGraph;
#ifdef SHEDITOR #ifdef SHEDITOR
Handle<SHRenderGraph> editorRenderGraph; //Handle<SHRenderGraph> editorRenderGraph;
#endif #endif
// Sub systems // Sub systems
Handle<SHMousePickSystem> mousePickSystem; Handle<SHMousePickSystem> mousePickSubSystem;
Handle<SHPostOffscreenRenderSystem> postOffscreenRender; Handle<SHPostOffscreenRenderSystem> postOffscreenRenderSubSystem;
Handle<SHLightingSubSystem> lightingSubSystem; Handle<SHLightingSubSystem> lightingSubSystem;
Handle<SHTextRenderingSubSystem> textRenderingSubSystem; Handle<SHTextRenderingSubSystem> textRenderingSubSystem;
Handle<SHSSAO> ssaoStorage; Handle<SHSSAO> ssaoStorage;

View File

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

View File

@ -16,6 +16,7 @@ of DigiPen Institute of Technology is prohibited.
#include "SHMaterial.h" #include "SHMaterial.h"
#include "Graphics/Pipeline/SHVkPipeline.h" #include "Graphics/Pipeline/SHVkPipeline.h"
#include "Tools/Logger/SHLogger.h" #include "Tools/Logger/SHLogger.h"
#include "Graphics/MiddleEnd/GlobalData/SHGraphicsPredefinedData.h"
namespace SHADE namespace SHADE
{ {
@ -78,11 +79,12 @@ namespace SHADE
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
Handle<SHShaderBlockInterface> SHMaterialInstance::getShaderBlockInterface() const noexcept Handle<SHShaderBlockInterface> SHMaterialInstance::getShaderBlockInterface() const noexcept
{ {
return baseMaterial->GetPipeline()->GetPipelineLayout()->GetShaderBlockInterface return baseMaterial->GetPipeline()->GetPipelineLayout()->GetShaderBlockInterface
( (
SHGraphicsConstants::DescriptorSetIndex::PER_INSTANCE, SHGraphicsPredefinedData::GetMappings(SHGraphicsPredefinedData::SystemType::BATCHING).at(SHPredefinedDescriptorTypes::MATERIALS),
SHGraphicsConstants::DescriptorSetBindings::BATCHED_PER_INST_DATA, //SHGraphicsConstants::DescriptorSetIndex::PER_INSTANCE,
vk::ShaderStageFlagBits::eFragment SHGraphicsConstants::DescriptorSetBindings::BATCHED_PER_INST_DATA,
); vk::ShaderStageFlagBits::eFragment
);
} }
} }

View File

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

View File

@ -14,7 +14,6 @@ of DigiPen Institute of Technology is prohibited.
#include "SHRenderer.h" #include "SHRenderer.h"
#include "Graphics/Devices/SHVkLogicalDevice.h" #include "Graphics/Devices/SHVkLogicalDevice.h"
#include "SHViewport.h"
#include "Graphics/Buffers/SHVkBuffer.h" #include "Graphics/Buffers/SHVkBuffer.h"
#include "Graphics/Framebuffer/SHVkFramebuffer.h" #include "Graphics/Framebuffer/SHVkFramebuffer.h"
#include "SHMaterial.h" #include "SHMaterial.h"
@ -22,22 +21,22 @@ of DigiPen Institute of Technology is prohibited.
#include "Graphics/Descriptors/SHVkDescriptorSetGroup.h" #include "Graphics/Descriptors/SHVkDescriptorSetGroup.h"
#include "Graphics/Buffers/SHVkBuffer.h" #include "Graphics/Buffers/SHVkBuffer.h"
#include "Camera/SHCameraDirector.h" #include "Camera/SHCameraDirector.h"
#include "Graphics/MiddleEnd/GlobalData/SHGraphicsPredefinedData.h"
namespace SHADE namespace SHADE
{ {
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
/* Constructor/Destructors */ /* 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) SHRenderer::SHRenderer(Handle<SHVkLogicalDevice> logicalDevice, uint32_t numFrames, Handle<SHVkDescriptorPool> descriptorPool, PROJECTION_TYPE type)
: viewport { viewport } : projectionType{type}
, renderGraph { renderGraph }
{ {
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) //for (uint32_t i = 0; i < commandBuffers.size(); ++i)
commandBuffers[i] = cmdPools[i]->RequestCommandBuffer(SH_CMD_BUFFER_TYPE::PRIMARY); // 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 #ifdef _DEBUG
const auto& CAM_DESC_SETS = cameraDescriptorSet->GetVkHandle(); const auto& CAM_DESC_SETS = cameraDescriptorSet->GetVkHandle();
@ -51,25 +50,16 @@ namespace SHADE
std::array cameraBufferArray{cameraBuffer}; 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) 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 void SHRenderer::SetCameraDirector(Handle<SHCameraDirector> director) noexcept
@ -77,63 +67,55 @@ namespace SHADE
cameraDirector = director; cameraDirector = director;
} }
/*-----------------------------------------------------------------------------------*/ void SHRenderer::UpdateData(uint32_t frameIndex) noexcept
/* Drawing Functions */
/*-----------------------------------------------------------------------------------*/
void SHRenderer::Draw(uint32_t frameIndex, Handle<SHVkDescriptorPool> descPool) noexcept
{ {
renderGraph->Execute(frameIndex, commandBuffers[frameIndex], descPool); if (cameraDirector)
}
void SHRenderer::UpdateDataAndBind(Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex) noexcept
{
if (camera && cameraDirector)
{ {
//UpdateDataAndBind(cmdBuffer, frameIndex, SHMatrix::Transpose(cameraDirector->GetVPMatrix())); switch (projectionType)
UpdateDataAndBind(cmdBuffer, frameIndex, cameraDirector->GetViewMatrix(), cameraDirector->GetProjMatrix(), cameraDirector->GetOrthoMatrix()); {
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, 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); 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 }; 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, pipelineType, setIndex, std::span{ dynamicOffsets.data(), 1 });
cmdBuffer->BindDescriptorSet(cameraDescriptorSet, SH_PIPELINE_TYPE::COMPUTE, SHGraphicsConstants::DescriptorSetIndex::HIGH_FREQUENCY_GLOBALS, 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.viewProjectionMatrix = SHMatrix::Transpose(projMatrix * viewMatrix);
cpuCameraData.viewMatrix = SHMatrix::Transpose(viewMatrix); cpuCameraData.viewMatrix = SHMatrix::Transpose(viewMatrix);
cpuCameraData.projectionMatrix = SHMatrix::Transpose(projMatrix); cpuCameraData.projectionMatrix = SHMatrix::Transpose(projMatrix);
cpuCameraData.orthoMatrix = SHMatrix::Transpose (orthoMatrix);
} }
Handle<SHRenderGraph> SHRenderer::GetRenderGraph(void) const noexcept //Handle<SHVkCommandBuffer> SHRenderer::GetCommandBuffer(uint32_t frameIndex) const noexcept
{ //{
return renderGraph; // return commandBuffers[frameIndex];
} //}
Handle<SHVkCommandBuffer> SHRenderer::GetCommandBuffer(uint32_t frameIndex) const noexcept
{
return commandBuffers[frameIndex];
}
Handle<SHCameraDirector> SHRenderer::GetCameraDirector(void) const noexcept Handle<SHCameraDirector> SHRenderer::GetCameraDirector(void) const noexcept
{ {

View File

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

View File

@ -56,11 +56,11 @@ namespace SHADE
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
void SetUp(Handle<SHVkCommandBuffer> commandBuffer); void SetUp(Handle<SHVkCommandBuffer> commandBuffer);
/*-----------------------------------------------------------------------------*/ ///*-----------------------------------------------------------------------------*/
/* Renderers Registration Functions */ ///* 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); //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); //void RemoveRenderer(Handle<SHRenderer> renderer);
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
/* Setters */ /* Setters */
@ -79,7 +79,7 @@ namespace SHADE
float GetHeight() const { return viewport.height; } float GetHeight() const { return viewport.height; }
float GetMinDepth() const { return viewport.minDepth; } float GetMinDepth() const { return viewport.minDepth; }
float GetMaxDepth() const { return viewport.maxDepth; } float GetMaxDepth() const { return viewport.maxDepth; }
std::vector<Handle<SHRenderer>>& GetRenderers() { return renderers; } //std::vector<Handle<SHRenderer>>& GetRenderers() { return renderers; }
private: private:
@ -88,7 +88,7 @@ namespace SHADE
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
Handle<SHVkLogicalDevice> device; Handle<SHVkLogicalDevice> device;
vk::Viewport viewport; vk::Viewport viewport;
std::vector<Handle<SHRenderer>> renderers; //std::vector<Handle<SHRenderer>> renderers;
}; };
} }

View File

@ -1,5 +1,7 @@
#include "SHpch.h" #include "SHpch.h"
#include "SHLightComponent.h" #include "SHLightComponent.h"
#include "Graphics/Events/SHGraphicsEvents.h"
#include "Events/SHEventManager.hpp"
namespace SHADE namespace SHADE
{ {
@ -104,6 +106,21 @@ namespace SHADE
//MakeDirty(); //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 SHLightData const& SHLightComponent::GetLightData(void) const noexcept
{ {
return lightData; 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. ////! If the light's data is already in the buffers, this will be set to true.
//bool bound; //bool bound;
public: public:
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
/* LIFECYCLE FUNCTIONS */ /* LIFECYCLE FUNCTIONS */
@ -49,6 +48,7 @@ namespace SHADE
//void Unbind (void) noexcept; //void Unbind (void) noexcept;
//void SetBound (uint32_t inIndexInBuffer) noexcept; //void SetBound (uint32_t inIndexInBuffer) noexcept;
void SetStrength (float value) noexcept; // serialized void SetStrength (float value) noexcept; // serialized
void SetEnableShadow (bool flag) noexcept;
SHLightData const& GetLightData (void) const noexcept; SHLightData const& GetLightData (void) const noexcept;
@ -59,7 +59,7 @@ namespace SHADE
uint32_t const& GetCullingMask (void) const noexcept; // serialized uint32_t const& GetCullingMask (void) const noexcept; // serialized
//bool IsDirty (void) const noexcept; //bool IsDirty (void) const noexcept;
//bool GetBound (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; float GetStrength (void) const noexcept;
RTTR_ENABLE() RTTR_ENABLE()
}; };

View File

@ -16,6 +16,12 @@ namespace SHADE
// Diffuse color set to 1 // Diffuse color set to 1
color = SHVec4::One; 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 struct SHLightData
{ {
static constexpr uint32_t INVALID_SHADOW_MAP_INDEX = std::numeric_limits<uint32_t>::max();
//! position of the light //! position of the light
SHVec3 position; SHVec3 position;
@ -46,6 +48,13 @@ namespace SHADE
//! Strength of the light //! Strength of the light
float strength; 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; void Reset (void) noexcept;
//! TODO: //! TODO:

View File

@ -1,6 +1,6 @@
#include "SHpch.h" #include "SHpch.h"
#include "SHLightingSubSystem.h" #include "SHLightingSubSystem.h"
#include "Graphics/MiddleEnd/GlobalData/SHGraphicsGlobalData.h" #include "Graphics/MiddleEnd/GlobalData/SHGraphicsPredefinedData.h"
#include "Tools/Utilities/SHUtilities.h" #include "Tools/Utilities/SHUtilities.h"
#include "Graphics/Devices/SHVkLogicalDevice.h" #include "Graphics/Devices/SHVkLogicalDevice.h"
#include "Graphics/Buffers/SHVkBuffer.h" #include "Graphics/Buffers/SHVkBuffer.h"
@ -320,15 +320,16 @@ namespace SHADE
void SHLightingSubSystem::UpdateDescSet(uint32_t binding) noexcept void SHLightingSubSystem::UpdateDescSet(uint32_t binding) noexcept
{ {
auto buffer = perTypeData[binding].GetDataBuffer(); auto buffer = perTypeData[binding].GetDataBuffer();
static constexpr uint32_t LIGHTING_DATA_SET_INDEX = 0;
// We bind the buffer with the correct desc set binding // 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 binding + 1, // we want to +1 here because the first binding is reserved for count
{ &buffer, 1 }, { &buffer, 1 },
0, 0,
perTypeData[binding].GetDataSize() * perTypeData[binding].GetMaxLights()); 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); std::fill (variableSizes.begin(), variableSizes.end(), 1);
// Create the descriptor set // 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 #ifdef _DEBUG
const auto& CAM_DESC_SETS = lightingDataDescSet->GetVkHandle(); const auto& CAM_DESC_SETS = lightingDataDescSet->GetVkHandle();
for (int i = 0; i < static_cast<int>(CAM_DESC_SETS.size()); ++i) 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 // 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"); 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); static constexpr uint32_t LIGHTING_DATA_SET_INDEX = 0;
lightingDataDescSet->UpdateDescriptorSetBuffer(SHGraphicsConstants::DescriptorSetIndex::DYNAMIC_GLOBALS, SHGraphicsConstants::DescriptorSetBindings::LIGHTING_COUNT); 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) 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). //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/SHVec3.h"
#include "Math/Vector/SHVec4.h" #include "Math/Vector/SHVec4.h"
#include "SHLightData.h" #include "SHLightData.h"
#include <array>
#include "Graphics/MiddleEnd/Interface/SHGraphicsConstants.h" #include "Graphics/MiddleEnd/Interface/SHGraphicsConstants.h"
namespace SHADE namespace SHADE
@ -57,8 +58,11 @@ namespace SHADE
class SH_API SHLightingSubSystem 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 class PerTypeData
{ {
private: private:
@ -130,7 +134,7 @@ namespace SHADE
std::array<PerTypeData, static_cast<uint32_t>(SH_LIGHT_TYPE::NUM_TYPES)> perTypeData; std::array<PerTypeData, static_cast<uint32_t>(SH_LIGHT_TYPE::NUM_TYPES)> perTypeData;
//! Container to store dynamic offsets for binding descriptor sets //! 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 //! 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; 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 Run (SHMatrix const& viewMat, uint32_t frameIndex) noexcept;
void Exit (void) 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 "SHpch.h"
#include "SHPipelineLibrary.h" #include "SHPipelineLibrary.h"
#include "Graphics/Devices/SHVkLogicalDevice.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/RenderGraph/SHSubpass.h"
#include "Graphics/SHVkUtil.h" #include "Graphics/SHVkUtil.h"
@ -13,7 +13,7 @@ namespace SHADE
SHPipelineLayoutParams params SHPipelineLayoutParams params
{ {
.shaderModules = {vsFsPair.first, vsFsPair.second}, .shaderModules = {vsFsPair.first, vsFsPair.second},
.globalDescSetLayouts = SHGraphicsGlobalData::GetDescSetLayouts() .predefinedDescSetLayouts = SHGraphicsPredefinedData::GetSystemData(SHGraphicsPredefinedData::SystemType::BATCHING).descSetLayouts
}; };
// Create the pipeline layout // Create the pipeline layout
@ -21,7 +21,7 @@ namespace SHADE
// Create the pipeline and configure the default vertex input state // Create the pipeline and configure the default vertex input state
auto newPipeline = logicalDevice->CreateGraphicsPipeline(pipelineLayout, nullptr, renderpass, subpass); auto newPipeline = logicalDevice->CreateGraphicsPipeline(pipelineLayout, nullptr, renderpass, subpass);
newPipeline->GetPipelineState().SetVertexInputState(SHGraphicsGlobalData::GetDefaultViState()); newPipeline->GetPipelineState().SetVertexInputState(SHGraphicsPredefinedData::GetDefaultViState());
SHColorBlendState colorBlendState{}; SHColorBlendState colorBlendState{};
colorBlendState.logic_op_enable = VK_FALSE; colorBlendState.logic_op_enable = VK_FALSE;

View File

@ -10,7 +10,7 @@ namespace SHADE
class SHVkDescriptorSetLayouts; class SHVkDescriptorSetLayouts;
class SHVkPipeline; class SHVkPipeline;
class SHSubpass; 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 // 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. // them so that they don't need to be recreated again.

View File

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

View File

@ -3,6 +3,7 @@
#include "Resource/SHHandle.h" #include "Resource/SHHandle.h"
#include "msdf-atlas-gen/msdf-atlas-gen.h" #include "msdf-atlas-gen/msdf-atlas-gen.h"
#include "Assets/Asset Types/SHFontAsset.h" #include "Assets/Asset Types/SHFontAsset.h"
#include "Graphics/Pipeline/SHPipelineType.h"
namespace SHADE namespace SHADE
{ {
@ -57,6 +58,7 @@ namespace SHADE
SHFont (Handle<SHVkLogicalDevice> inLogicalDeviceHdl, SHFontAsset const& asset) noexcept; SHFont (Handle<SHVkLogicalDevice> inLogicalDeviceHdl, SHFontAsset const& asset) noexcept;
void TransferToGPU (Handle<SHVkCommandBuffer> commandBuffer) noexcept; void TransferToGPU (Handle<SHVkCommandBuffer> commandBuffer) noexcept;
void DoPostTransfer (Handle<SHVkDescriptorPool> descPool, Handle<SHVkDescriptorSetLayout> layout) 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/Devices/SHVkLogicalDevice.h"
#include "Graphics/MiddleEnd/TextRendering/SHFont.h" #include "Graphics/MiddleEnd/TextRendering/SHFont.h"
#include "Graphics/Buffers/SHVkBuffer.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/Pipeline/SHVkPipeline.h"
#include "Graphics/SHVkUtil.h" #include "Graphics/SHVkUtil.h"
#include "Graphics/RenderGraph/SHSubpass.h" #include "Graphics/RenderGraph/SHSubpass.h"
#include "Math/Transform/SHTransformComponent.h" #include "Math/Transform/SHTransformComponent.h"
#include "Graphics/MiddleEnd/GlobalData/SHGlobalDescriptorSets.h"
#include "Graphics/MiddleEnd/Interface/SHRenderer.h"
namespace SHADE 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>(); SHComponentManager::CreateComponentSparseSet<SHTextRenderableComponent>();
cameraDescSetBind = bindFunction;
logicalDevice = device; logicalDevice = device;
// prepare pipeline layout params // prepare pipeline layout params
SHPipelineLayoutParams plParams SHPipelineLayoutParams plParams
{ {
.shaderModules = {textVS, textFS}, .shaderModules = {textVS, textFS},
.globalDescSetLayouts = SHGraphicsGlobalData::GetDescSetLayouts() .predefinedDescSetLayouts = SHGraphicsPredefinedData::GetSystemData(SHGraphicsPredefinedData::SystemType::TEXT_RENDERING).descSetLayouts
}; };
pipelineLayout = logicalDevice->CreatePipelineLayout(plParams); pipelineLayout = logicalDevice->CreatePipelineLayout(plParams);
@ -157,24 +157,6 @@ namespace SHADE
// Construct pipeline // Construct pipeline
pipeline->ConstructPipeline(); 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 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& 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) for (auto& comp : textRendererComps)
{ {
auto* transform = SHComponentManager::GetComponent<SHTransformComponent>(comp.GetEID()); auto* transform = SHComponentManager::GetComponent<SHTransformComponent>(comp.GetEID());
@ -205,15 +192,19 @@ namespace SHADE
// bind the pipeline // bind the pipeline
cmdBuffer->BindPipeline(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) // bind VBO (position and indices)
cmdBuffer->BindVertexBuffer(SHGraphicsConstants::VertexBufferBindings::CALCULATED_GLYPH_POSITION, comp.charPositionDataBuffer, 0); cmdBuffer->BindVertexBuffer(SHGraphicsConstants::VertexBufferBindings::CALCULATED_GLYPH_POSITION, comp.charPositionDataBuffer, 0);
cmdBuffer->BindVertexBuffer(SHGraphicsConstants::VertexBufferBindings::GLYPH_INDEX, comp.indexingDataBuffer, 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.worldTransform", transform->GetTRS(), SH_PIPELINE_TYPE::GRAPHICS);
cmdBuffer->SetPushConstantVariable("TestPushConstant.eid", comp.GetEID(), 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); cmdBuffer->SetPushConstantVariable("TestPushConstant.textColor", SHVec3 (1.0f, 1.0f, 1.0f), SH_PIPELINE_TYPE::GRAPHICS);
@ -223,9 +214,7 @@ namespace SHADE
// call draw call // call draw call
cmdBuffer->DrawArrays(4, comp.text.size(), 0, 0); cmdBuffer->DrawArrays(4, comp.text.size(), 0, 0);
//glDrawArraysInstanced(GL_TRIANGLE_FAN, 0, 4, static_cast<GLsizei>(textComp.lastRenderedCharacterIndex) + 1); //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 //Handle<SHVkDescriptorSetLayout> SHTextRenderingSubSystem::GetFontDataDescSetLayout(void) const noexcept
{ //{
return fontDataDescSetLayout; // return fontDataDescSetLayout;
} //}
} }

View File

@ -20,6 +20,7 @@ namespace SHADE
class SHVkRenderpass; class SHVkRenderpass;
class SHSubpass; class SHSubpass;
class SHVkShaderModule; class SHVkShaderModule;
class SHRenderer;
class SHTextRenderingSubSystem class SHTextRenderingSubSystem
{ {
@ -41,24 +42,20 @@ namespace SHADE
Handle<SHVkPipelineLayout> pipelineLayout; Handle<SHVkPipelineLayout> pipelineLayout;
//! Descriptor set for font data access in shaders //! Descriptor set for font data access in shaders
Handle<SHVkDescriptorSetLayout> fontDataDescSetLayout; //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;
private: private:
void RecomputePositions(SHTextRenderableComponent& textComp) noexcept; void RecomputePositions(SHTextRenderableComponent& textComp) noexcept;
public: 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 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; 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/Descriptors/SHVkDescriptorSetGroup.h"
#include "Graphics/Images/SHVkImage.h" #include "Graphics/Images/SHVkImage.h"
#include "Graphics/Images/SHVkImageView.h" #include "Graphics/Images/SHVkImageView.h"
#include "Graphics/MiddleEnd/GlobalData/SHGraphicsGlobalData.h" #include "Graphics/MiddleEnd/GlobalData/SHGraphicsPredefinedData.h"
#include "Assets/Asset Types/SHTextureAsset.h" #include "Assets/Asset Types/SHTextureAsset.h"
namespace SHADE namespace SHADE
@ -168,22 +168,23 @@ namespace SHADE
} }
texDescriptors = descPool->Allocate texDescriptors = descPool->Allocate
( (
{ SHGraphicsGlobalData::GetDescSetLayouts()[SHGraphicsConstants::DescriptorSetIndex::STATIC_GLOBALS] }, { SHGraphicsPredefinedData::GetPredefinedDescSetLayouts(SHGraphicsPredefinedData::PredefinedDescSetLayoutTypes::STATIC_DATA) },
{ static_cast<uint32_t>(texOrder.size()) } { static_cast<uint32_t>(texOrder.size()) }
); );
#ifdef _DEBUG #ifdef _DEBUG
for (auto set : texDescriptors->GetVkHandle()) for (auto set : texDescriptors->GetVkHandle())
SET_VK_OBJ_NAME(device, vk::ObjectType::eDescriptorSet, set, "[Descriptor Set] Static Globals"); SET_VK_OBJ_NAME(device, vk::ObjectType::eDescriptorSet, set, "[Descriptor Set] Static Globals");
#endif #endif
static constexpr uint32_t TEX_DESCRIPTOR_SET_INDEX = 0;
texDescriptors->ModifyWriteDescImage texDescriptors->ModifyWriteDescImage
( (
SHGraphicsConstants::DescriptorSetIndex::STATIC_GLOBALS, TEX_DESCRIPTOR_SET_INDEX,
SHGraphicsConstants::DescriptorSetBindings::IMAGE_AND_SAMPLERS_DATA, SHGraphicsConstants::DescriptorSetBindings::IMAGE_AND_SAMPLERS_DATA,
combinedImageSamplers combinedImageSamplers
); );
texDescriptors->UpdateDescriptorSetImages texDescriptors->UpdateDescriptorSetImages
( (
SHGraphicsConstants::DescriptorSetIndex::STATIC_GLOBALS, TEX_DESCRIPTOR_SET_INDEX,
SHGraphicsConstants::DescriptorSetBindings::IMAGE_AND_SAMPLERS_DATA 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 //! 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 the layout to initialize the pipeline layout but we do not
//! want to use it for allocating descriptor sets. //! 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 //! 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 //! 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. // 1 descriptor set layout for every descriptor set detected.
for (auto const& set : setsWithBindings) for (auto const& set : setsWithBindings)
{ {
auto newDescriptorSetLayout = logicalDeviceHdl->CreateDescriptorSetLayout(set.first, set.second); auto newDescriptorSetLayout = logicalDeviceHdl->CreateDescriptorSetLayout(set.second);
descriptorSetLayoutsAllocate.push_back(newDescriptorSetLayout); descriptorSetLayoutsAllocate.push_back(newDescriptorSetLayout);
} }
@ -317,7 +317,7 @@ namespace SHADE
, logicalDeviceHdl {inLogicalDeviceHdl} , logicalDeviceHdl {inLogicalDeviceHdl}
, pushConstantInterface{} , pushConstantInterface{}
, vkPcRanges{} , 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{} , descriptorSetLayoutsAllocate{}
, vkDescriptorSetLayoutsAllocate{} , vkDescriptorSetLayoutsAllocate{}
, descriptorSetLayoutsPipeline{} , descriptorSetLayoutsPipeline{}

View File

@ -12,8 +12,10 @@
#include "SHRenderGraphStorage.h" #include "SHRenderGraphStorage.h"
#include "Graphics/RenderGraph/SHRenderGraphNodeCompute.h" #include "Graphics/RenderGraph/SHRenderGraphNodeCompute.h"
#include "Tools/Utilities/SHUtilities.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/RenderGraph/SHRenderToSwapchainImageSystem.h"
#include "Graphics/MiddleEnd/GlobalData/SHGlobalDescriptorSets.h"
namespace SHADE namespace SHADE
{ {
@ -66,6 +68,56 @@ namespace SHADE
renderGraphStorage->graphResources->try_emplace(resourceName, resource); 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 void SHRenderGraph::LinkNonOwningResource(Handle<SHRenderGraph> resourceOrigin, std::string resourceName) noexcept
{ {
// resource to link // resource to link
@ -234,140 +286,12 @@ namespace SHADE
*/ */
/***************************************************************************/ /***************************************************************************/
void SHRenderGraph::ConfigureSubpasses(void) noexcept void SHRenderGraph::ConfigureAllSubpasses(void) noexcept
{ {
// For all nodes // For all nodes
for (auto& node : nodes) for (auto& node : nodes)
{ {
// Create subpass description and dependencies based on number of subpasses node->ConfigureSubpasses();
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();
}
} }
} }
@ -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>(); //resourceHub = std::make_shared<SHResourceHub>();
@ -437,6 +361,11 @@ namespace SHADE
renderGraphStorage->resourceHub = resourceHub; renderGraphStorage->resourceHub = resourceHub;
renderGraphStorage->descriptorPool = logicalDevice->CreateDescriptorPools(); 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); name = std::move(graphName);
} }
@ -555,17 +484,24 @@ namespace SHADE
if (renderGraphStorage->graphResources->contains(toSwapchainResource) && renderGraphStorage->graphResources->contains(swapchainResource)) 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 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->AddColorOutput(swapchainResource);
newSubpass->AddInput(toSwapchainResource); newSubpass->AddInput(toSwapchainResource);
renderToSwapchainImageSystem = renderGraphStorage->resourceHub->Create<SHRenderToSwapchainImageSystem> (newNode, newSubpass, shaderModules); 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()); 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. // draw a quad.
cmdBuffer->DrawArrays(4, 1, 0, 0); cmdBuffer->DrawArrays(4, 1, 0, 0);
@ -590,12 +526,17 @@ namespace SHADE
{ {
CheckForNodeComputes(); CheckForNodeComputes();
ConfigureAttachmentDescriptions(); ConfigureAttachmentDescriptions();
ConfigureSubpasses(); ConfigureAllSubpasses();
ConfigureRenderpasses(); ConfigureRenderpasses();
ConfigureFramebuffers(); ConfigureFramebuffers();
ConfigureSubSystems(); 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 // TODO: The graph scope buffers were meant to bind vertex buffers and index buffers for meshes. Find a
// better way to manage these // 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); 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) 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); node->Execute(cmdBuffer, descPool, frameIndex);
}
cmdBuffer->EndLabeledSegment(); 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) void SHRenderGraph::FinaliseBatch(uint32_t frameIndex, Handle<SHVkDescriptorPool> descPool)
{ {
for (auto& node : nodes) for (auto& node : nodes)
@ -670,4 +638,9 @@ namespace SHADE
return {}; return {};
} }
Handle<SHVkCommandBuffer> SHRenderGraph::GetCommandBuffer(uint32_t frameIndex) const noexcept
{
return commandBuffers[frameIndex];
}
} }

View File

@ -29,7 +29,7 @@ namespace SHADE
class SHVkCommandPool; class SHVkCommandPool;
class SHVkCommandBuffer; class SHVkCommandBuffer;
class SHRenderGraphNode; class SHRenderGraphNode;
class SHGraphicsGlobalData; class SHGraphicsPredefinedData;
class SHVkDescriptorPool; class SHVkDescriptorPool;
class SHRenderGraphStorage; class SHRenderGraphStorage;
class SHRenderToSwapchainImageSystem; class SHRenderToSwapchainImageSystem;
@ -51,7 +51,7 @@ namespace SHADE
/* PRIVATE MEMBER FUNCTIONS */ /* PRIVATE MEMBER FUNCTIONS */
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
void ConfigureAttachmentDescriptions (void) noexcept; void ConfigureAttachmentDescriptions (void) noexcept;
void ConfigureSubpasses (void) noexcept; void ConfigureAllSubpasses (void) noexcept;
void ConfigureRenderpasses (void) noexcept; void ConfigureRenderpasses (void) noexcept;
void ConfigureSubSystems (void) noexcept; void ConfigureSubSystems (void) noexcept;
void ConfigureFramebuffers (void) noexcept; void ConfigureFramebuffers (void) noexcept;
@ -74,6 +74,9 @@ namespace SHADE
//! For rendering onto the swapchain //! For rendering onto the swapchain
Handle<SHRenderToSwapchainImageSystem> renderToSwapchainImageSystem; Handle<SHRenderToSwapchainImageSystem> renderToSwapchainImageSystem;
//! Command buffer to issue rendering commands
std::vector<Handle<SHVkCommandBuffer>> commandBuffers;
public: public:
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
/* CTORS AND DTORS */ /* CTORS AND DTORS */
@ -86,24 +89,66 @@ namespace SHADE
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
/* PUBLIC MEMBER FUNCTIONS */ /* PUBLIC MEMBER FUNCTIONS */
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
void Init (std::string graphName, Handle<SHVkLogicalDevice> logicalDevice, Handle<SHVkSwapchain> swapchain, SHResourceHub* resourceHub) noexcept; void Init
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; std::string graphName,
Handle<SHRenderGraphNode> AddNode (std::string nodeName, std::initializer_list<ResourceInstruction> resourceInstruction, std::initializer_list<std::string> predecessorNodes) noexcept; Handle<SHVkLogicalDevice> logicalDevice,
void AddRenderToSwapchainNode (std::string toSwapchainResource, std::string swapchainResource, std::initializer_list<std::string> predecessorNodes, std::pair<Handle<SHVkShaderModule>, Handle<SHVkShaderModule>> shaderModules) noexcept; 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 Generate (void) noexcept;
void Regenerate (void) noexcept;
void CheckForNodeComputes (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 FinaliseBatch (uint32_t frameIndex, Handle<SHVkDescriptorPool> descPool);
void HandleResize (uint32_t newWidth, uint32_t newHeight) noexcept; void HandleResize (uint32_t newWidth, uint32_t newHeight) noexcept;
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
/* SETTERS AND GETTERS */ /* SETTERS AND GETTERS */
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
Handle<SHRenderGraphNode> GetNode (std::string const& nodeName) const noexcept; Handle<SHRenderGraphNode> GetNode (std::string const& nodeName) const noexcept;
std::vector<Handle<SHRenderGraphNode>> const& GetNodes (void) const noexcept; std::vector<Handle<SHRenderGraphNode>> const& GetNodes (void) const noexcept;
Handle<SHRenderGraphResource> GetRenderGraphResource (std::string const& resourceName) 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 "SHRenderGraphStorage.h"
#include "Graphics/RenderGraph/SHRenderGraphNodeCompute.h" #include "Graphics/RenderGraph/SHRenderGraphNodeCompute.h"
#include "Graphics/SHVkUtil.h" #include "Graphics/SHVkUtil.h"
#include "Graphics/MiddleEnd/GlobalData/SHGlobalDescriptorSets.h"
#include "Graphics/MiddleEnd/GlobalData/SHGraphicsPredefinedData.h"
namespace SHADE namespace SHADE
{ {
@ -24,6 +26,12 @@ namespace SHADE
/***************************************************************************/ /***************************************************************************/
void SHRenderGraphNode::CreateRenderpass(void) noexcept void SHRenderGraphNode::CreateRenderpass(void) noexcept
{ {
if (renderpass)
{
if (renderpass)
renderpass.Free();
}
renderpass = graphStorage->logicalDevice->CreateRenderpass(attachmentDescriptions, spDescs, spDeps); renderpass = graphStorage->logicalDevice->CreateRenderpass(attachmentDescriptions, spDescs, spDeps);
SET_VK_OBJ_NAME(graphStorage->logicalDevice, vk::ObjectType::eRenderPass, renderpass->GetVkRenderpass(), "[RenderPass] " + name); SET_VK_OBJ_NAME(graphStorage->logicalDevice, vk::ObjectType::eRenderPass, renderpass->GetVkRenderpass(), "[RenderPass] " + name);
} }
@ -38,6 +46,15 @@ namespace SHADE
/***************************************************************************/ /***************************************************************************/
void SHRenderGraphNode::CreateFramebuffer(void) noexcept 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) for (uint32_t i = 0; i < framebuffers.size(); ++i)
{ {
std::vector<Handle<SHVkImageView>> imageViews(attResources.size()); 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 subpass already exists, don't add.
if (subpassIndexing.contains(subpassName)) if (subpassIndexing.contains(subpassName))
@ -253,6 +403,8 @@ namespace SHADE
graphStorage->resourceHub->Create<SHSubpass> graphStorage->resourceHub->Create<SHSubpass>
( (
subpassName, subpassName,
viewport,
renderer,
graphStorage, GetHandle(), static_cast<uint32_t>(subpasses.size()), graphStorage, GetHandle(), static_cast<uint32_t>(subpasses.size()),
resourceAttachmentMapping.get() resourceAttachmentMapping.get()
) )
@ -318,7 +470,7 @@ namespace SHADE
} }
// insert them all for a subpass to transition them. This subpass is the last subpass // 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) for (auto& resource : resourcesInvolved)
{ {
dummySubpass->AddGeneralInput(resource); 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; uint32_t framebufferIndex = (framebuffers.size() > 1) ? frameIndex : 0;
commandBuffer->BeginRenderpass(renderpass, framebuffers[framebufferIndex]); commandBuffer->BeginRenderpass(renderpass, framebuffers[framebufferIndex]);
@ -347,12 +551,23 @@ namespace SHADE
commandBuffer->EndRenderpass(); 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 // Execute all subpass computes
for (auto& sbCompute : nodeComputes) for (auto& sbCompute : nodeComputes)
{
sbCompute->Execute(commandBuffer, frameIndex); sbCompute->Execute(commandBuffer, frameIndex);
}
} }
Handle<SHVkPipeline> SHRenderGraphNode::GetOrCreatePipeline(std::pair<Handle<SHVkShaderModule>, Handle<SHVkShaderModule>> const& vsFsPair, Handle<SHSubpass> subpass) noexcept 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 SHVkLogicalDevice;
class SHVkRenderpass; class SHVkRenderpass;
class SHVkDescriptorPool; class SHVkDescriptorPool;
class SHGraphicsGlobalData; class SHGraphicsPredefinedData;
class SHRenderGraphStorage; class SHRenderGraphStorage;
class SHRenderGraphNodeCompute; class SHRenderGraphNodeCompute;
class SHRenderer;
class SHViewport;
class SH_API SHRenderGraphNode : public ISelfHandle<SHRenderGraphNode> class SH_API SHRenderGraphNode : public ISelfHandle<SHRenderGraphNode>
{ {
@ -53,7 +55,7 @@ namespace SHADE
//! Vector of subpasses //! Vector of subpasses
std::vector<Handle<SHSubpass>> 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; std::vector<vk::SubpassDescription> spDescs;
//! Subpass dependencies for renderpass creation //! Subpass dependencies for renderpass creation
@ -90,6 +92,7 @@ namespace SHADE
void CreateRenderpass(void) noexcept; void CreateRenderpass(void) noexcept;
void CreateFramebuffer(void) noexcept; void CreateFramebuffer(void) noexcept;
void HandleResize (void) noexcept; void HandleResize (void) noexcept;
void ConfigureSubpasses (void) noexcept;
public: public:
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
@ -102,12 +105,13 @@ namespace SHADE
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
/* PUBLIC MEMBER FUNCTIONS */ /* 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; 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; void AddDummySubpassIfNeeded (void) noexcept;
bool DetachResource (std::string const& resourceName, uint64_t resourceHandleID) noexcept;
// TODO: RemoveSubpass() // 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; Handle<SHVkPipeline> GetOrCreatePipeline(std::pair<Handle<SHVkShaderModule>, Handle<SHVkShaderModule>> const& vsFsPair, Handle<SHSubpass> subpass) noexcept;
void FinaliseBatch(uint32_t frameIndex, Handle<SHVkDescriptorPool> descPool); void FinaliseBatch(uint32_t frameIndex, Handle<SHVkDescriptorPool> descPool);

View File

@ -6,10 +6,11 @@
#include "Graphics/Descriptors/SHVkDescriptorSetLayout.h" #include "Graphics/Descriptors/SHVkDescriptorSetLayout.h"
#include "Graphics/Devices/SHVkLogicalDevice.h" #include "Graphics/Devices/SHVkLogicalDevice.h"
#include "Graphics/Pipeline/SHVkPipelineLayout.h" #include "Graphics/Pipeline/SHVkPipelineLayout.h"
#include "Graphics/MiddleEnd/GlobalData/SHGraphicsGlobalData.h" #include "Graphics/MiddleEnd/GlobalData/SHGraphicsPredefinedData.h"
#include "SHRenderGraphStorage.h" #include "SHRenderGraphStorage.h"
#include "SHRenderGraphResource.h" #include "SHRenderGraphResource.h"
#include "Graphics/Commands/SHVkCommandBuffer.h" #include "Graphics/Commands/SHVkCommandBuffer.h"
#include "Graphics/MiddleEnd/Interface/SHRenderer.h"
namespace SHADE namespace SHADE
{ {
@ -23,11 +24,12 @@ namespace SHADE
, numWorkGroupScale {std::clamp(inNumWorkGroupScale, 0.0f, 1.0f)} , numWorkGroupScale {std::clamp(inNumWorkGroupScale, 0.0f, 1.0f)}
, computeResource{} , computeResource{}
, name { std::move(nodeName) } , name { std::move(nodeName) }
, renderer{ }
{ {
SHPipelineLayoutParams pipelineLayoutParams SHPipelineLayoutParams pipelineLayoutParams
{ {
.shaderModules = {computeShaderModule}, .shaderModules = {computeShaderModule},
.globalDescSetLayouts = SHGraphicsGlobalData::GetDescSetLayouts(), .predefinedDescSetLayouts = SHGraphicsPredefinedData::GetSystemData(SHGraphicsPredefinedData::SystemType::RENDER_GRAPH_NODE_COMPUTE).descSetLayouts,
.dynamicBufferBindings = std::move(dynamicBufferBindings), .dynamicBufferBindings = std::move(dynamicBufferBindings),
}; };
@ -45,10 +47,13 @@ namespace SHADE
// save the resources // save the resources
resources = std::move (subpassComputeResources); 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. //Get the descriptor set layouts required to allocate. We only want the ones for allocate because
auto const& graphResourceLayout = computePipeline->GetPipelineLayout()->GetDescriptorSetLayoutsPipeline()[SHGraphicsConstants::DescriptorSetIndex::RENDERGRAPH_RESOURCE]; //global descriptors are already bound in the main system.
auto const& graphResourceLayout = layouts[descMappings.at(SHPredefinedDescriptorTypes::RENDER_GRAPH_RESOURCE)];
// Allocate descriptor sets to hold the images for reading (STORAGE_IMAGE) // Allocate descriptor sets to hold the images for reading (STORAGE_IMAGE)
for (uint32_t i = 0; i < SHGraphicsConstants::NUM_FRAME_BUFFERS; ++i) for (uint32_t i = 0; i < SHGraphicsConstants::NUM_FRAME_BUFFERS; ++i)
@ -60,14 +65,12 @@ namespace SHADE
#endif #endif
} }
// check if all layouts are there
auto const& layouts = computePipeline->GetPipelineLayout()->GetDescriptorSetLayoutsPipeline(); if (layouts.size() == descMappings.at(SHPredefinedDescriptorTypes::RENDER_GRAPH_NODE_COMPUTE_RESOURCE) + 1)
if (layouts.size() == SHGraphicsConstants::DescriptorSetIndex::RENDERGRAPH_NODE_COMPUTE_RESOURCE + 1)
{ {
// create compute resources // create compute resources
computeResource = graphStorage->resourceHub->Create<ComputeResource>(); 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 }); computeResource->descSet = graphStorage->descriptorPool->Allocate({ computeResourceLayout }, { 1 });
#ifdef _DEBUG #ifdef _DEBUG
for (auto set : computeResource->descSet->GetVkHandle()) for (auto set : computeResource->descSet->GetVkHandle())
@ -91,14 +94,22 @@ namespace SHADE
// bind the compute pipeline // bind the compute pipeline
cmdBuffer->BindPipeline(computePipeline); cmdBuffer->BindPipeline(computePipeline);
// bind descriptor sets auto const& descMappings = SHGraphicsPredefinedData::GetMappings(SHGraphicsPredefinedData::SystemType::RENDER_GRAPH_NODE_COMPUTE);
cmdBuffer->BindDescriptorSet(graphResourceDescSets[frameIndex], SH_PIPELINE_TYPE::COMPUTE, SHGraphicsConstants::DescriptorSetIndex::RENDERGRAPH_RESOURCE, {});
// bind render graph resource
cmdBuffer->BindDescriptorSet(graphResourceDescSets[frameIndex], SH_PIPELINE_TYPE::COMPUTE, descMappings.at(SHPredefinedDescriptorTypes::RENDER_GRAPH_RESOURCE), {});
// bind compute resource
if (computeResource) 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 // dispatch compute
cmdBuffer->ComputeDispatch(groupSizeX, groupSizeY, 1); cmdBuffer->ComputeDispatch(groupSizeX, groupSizeY, 1);
@ -109,8 +120,14 @@ namespace SHADE
void SHRenderGraphNodeCompute::HandleResize(void) noexcept 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 // 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 // everything below here needs resizing
for (uint32_t frameIndex = 0; frameIndex < SHGraphicsConstants::NUM_FRAME_BUFFERS; ++frameIndex) 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; 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); 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]->ModifyWriteDescImage(RENDER_GRAPH_RESOURCE_UPDATE_SET_INDEX, binding.BindPoint, { &vsl, 1 });
graphResourceDescSets[frameIndex]->UpdateDescriptorSetImages(SHGraphicsConstants::DescriptorSetIndex::RENDERGRAPH_RESOURCE, binding.BindPoint); graphResourceDescSets[frameIndex]->UpdateDescriptorSetImages(RENDER_GRAPH_RESOURCE_UPDATE_SET_INDEX, binding.BindPoint);
++i; ++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); renderer = inRenderer;
computeResource->descSet->UpdateDescriptorSetBuffer(set, binding);
} }
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); static constexpr uint32_t COMPUTE_RESOURCE_SET_INDEX = 0;
computeResource->descSet->UpdateDescriptorSetImages(set, binding);
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 <initializer_list>
#include <string> #include <string>
#include <unordered_set> #include <unordered_set>
#include "Resource/SHHandle.h"
namespace SHADE namespace SHADE
{ {
@ -19,6 +20,7 @@ namespace SHADE
class SHVkShaderModule; class SHVkShaderModule;
class SHVkCommandBuffer; class SHVkCommandBuffer;
class SHVkBuffer; class SHVkBuffer;
class SHRenderer;
class SHRenderGraphNodeCompute class SHRenderGraphNodeCompute
@ -53,6 +55,9 @@ namespace SHADE
//! vector of resources needed by the subpass compute //! vector of resources needed by the subpass compute
std::vector<Handle<SHRenderGraphResource>> resources; 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. //! X dimension work group size. Should scale with resource size.
uint32_t groupSizeX; uint32_t groupSizeX;
@ -75,9 +80,10 @@ namespace SHADE
void HandleResize (void) noexcept; void HandleResize (void) noexcept;
void SetDynamicOffsets (std::span<uint32_t> perFrameSizes) 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 ModifyWriteDescBufferComputeResource (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 ModifyWriteDescImageComputeResource(uint32_t binding, std::span<SHVkDescriptorSetGroup::viewSamplerLayout> const& viewSamplerLayouts) noexcept;
friend class SHRenderGraph; friend class SHRenderGraph;

View File

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

View File

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

View File

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

View File

@ -11,6 +11,9 @@
#include "Graphics/Swapchain/SHVkSwapchain.h" #include "Graphics/Swapchain/SHVkSwapchain.h"
#include "Graphics/Images/SHVkSampler.h" #include "Graphics/Images/SHVkSampler.h"
#include "SHRenderGraphResource.h" #include "SHRenderGraphResource.h"
#include "Graphics/MiddleEnd/Interface/SHViewport.h"
#include "Graphics/MiddleEnd/Interface/SHRenderer.h"
#include "Graphics/MiddleEnd/GlobalData/SHGraphicsPredefinedData.h"
namespace SHADE 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 } : resourceAttachmentMapping{ mapping }
, parentNode{ parent } , parentNode{ parent }
, subpassIndex{ index } , subpassIndex{ index }
@ -41,6 +44,8 @@ namespace SHADE
, name { name } , name { name }
, graphStorage{ renderGraphStorage } , graphStorage{ renderGraphStorage }
, inputImageDescriptorSets{} , inputImageDescriptorSets{}
, viewport {inViewport}
, renderer {inRenderer}
{ {
} }
@ -63,7 +68,6 @@ namespace SHADE
, depthReferences{ std::move(rhs.depthReferences) } , depthReferences{ std::move(rhs.depthReferences) }
, inputReferences{ std::move(rhs.inputReferences) } , inputReferences{ std::move(rhs.inputReferences) }
, resourceAttachmentMapping{ rhs.resourceAttachmentMapping } , resourceAttachmentMapping{ rhs.resourceAttachmentMapping }
, descriptorSetLayout{ rhs.descriptorSetLayout }
, exteriorDrawCalls{ std::move(rhs.exteriorDrawCalls) } , exteriorDrawCalls{ std::move(rhs.exteriorDrawCalls) }
, graphStorage{ rhs.graphStorage } , graphStorage{ rhs.graphStorage }
, inputNames{ std::move(rhs.inputNames) } , inputNames{ std::move(rhs.inputNames) }
@ -71,6 +75,8 @@ namespace SHADE
, inputDescriptorLayout{ rhs.inputDescriptorLayout } , inputDescriptorLayout{ rhs.inputDescriptorLayout }
, inputSamplers{ rhs.inputSamplers } , inputSamplers{ rhs.inputSamplers }
, name { rhs.name } , name { rhs.name }
, viewport {rhs.viewport}
, renderer {rhs.renderer}
{ {
} }
@ -98,7 +104,6 @@ namespace SHADE
depthReferences = std::move(rhs.depthReferences); depthReferences = std::move(rhs.depthReferences);
inputReferences = std::move(rhs.inputReferences); inputReferences = std::move(rhs.inputReferences);
resourceAttachmentMapping = std::move(rhs.resourceAttachmentMapping); resourceAttachmentMapping = std::move(rhs.resourceAttachmentMapping);
descriptorSetLayout = rhs.descriptorSetLayout;
exteriorDrawCalls = std::move(rhs.exteriorDrawCalls); exteriorDrawCalls = std::move(rhs.exteriorDrawCalls);
graphStorage = rhs.graphStorage; graphStorage = rhs.graphStorage;
inputNames = std::move(rhs.inputNames); inputNames = std::move(rhs.inputNames);
@ -106,6 +111,9 @@ namespace SHADE
inputDescriptorLayout = rhs.inputDescriptorLayout; inputDescriptorLayout = rhs.inputDescriptorLayout;
inputSamplers = rhs.inputSamplers; inputSamplers = rhs.inputSamplers;
name = std::move(rhs.name); name = std::move(rhs.name);
renderer = rhs.renderer;
viewport = rhs.viewport;
return *this; return *this;
} }
@ -199,21 +207,33 @@ namespace SHADE
inputReferences.push_back({ resourceAttachmentMapping->at(graphStorage->graphResources->at(resourceToReference).GetId().Raw), vk::ImageLayout::eGeneral }); 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); commandBuffer->BeginLabeledSegment(name);
// Ensure correct transforms are provided // Ensure correct transforms are provided
superBatch->UpdateBuffers(frameIndex, descPool); 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 // Draw all the batches
superBatch->Draw(commandBuffer, frameIndex); superBatch->Draw(commandBuffer, frameIndex);
// Draw all the exterior draw calls // Draw all the exterior draw calls
for (auto& drawCall : exteriorDrawCalls) for (auto& drawCall : exteriorDrawCalls)
{ {
drawCall(commandBuffer, frameIndex); drawCall(commandBuffer, renderer, frameIndex);
} }
commandBuffer->EndLabeledSegment(); commandBuffer->EndLabeledSegment();
} }
@ -223,15 +243,73 @@ namespace SHADE
UpdateWriteDescriptors(); 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()) 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); exteriorDrawCalls.push_back(newDrawCall);
} }
@ -247,6 +325,21 @@ namespace SHADE
if (inputNames.empty()) if (inputNames.empty())
return; 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); inputImageDescriptorSets.resize(SHGraphicsConstants::NUM_FRAME_BUFFERS);
std::vector<SHVkDescriptorSetLayout::Binding> bindings{}; std::vector<SHVkDescriptorSetLayout::Binding> bindings{};
@ -266,7 +359,7 @@ namespace SHADE
} }
// We build a new descriptor set layout to store our images // 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. // 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) for (uint32_t i = 0; i < bindings.size(); ++i)
@ -334,66 +427,36 @@ namespace SHADE
// Update descriptor sets // Update descriptor sets
auto args = std::make_tuple(resource->GetImageView(viewIndex), inputSamplers[i], descriptorLayout); 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; ++i;
} }
} }
//void SHSubpass::InitComputeBarriers(void) noexcept /***************************************************************************/
//{ /*!
// std::unordered_set <uint64_t> handleBarriers{};
\brief
// // we will have swapchainNumImages vectors of vector of barriers This function is mainly used for the purposes of giving a subpass a new
// subpassComputeBarriers.resize(graphStorage->swapchain->GetNumImages()); index in the case another subpass in the node gets deleted, and subpasses
need to be re-indexed.
// for (auto sbCompute : subpassComputes)
// { \param index
// // for every resource the subpass compute is using New index of the subpass.
// for (auto resource : sbCompute->resources)
// { */
// // Get the resource handle /***************************************************************************/
// uint64_t resourceRaw = resource.GetId().Raw; void SHSubpass::SetIndex(uint32_t index) noexcept
{
// // if the barrier is not registered subpassIndex = index;
// 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);
// }
// }
// }
//}
/***************************************************************************/ /***************************************************************************/
/*! /*!

View File

@ -19,15 +19,28 @@ namespace SHADE
class SHRenderGraphStorage; class SHRenderGraphStorage;
class SHVkShaderModule; class SHVkShaderModule;
class SHVkSampler; class SHVkSampler;
class SHRenderer;
class SHViewport;
class SH_API SHSubpass : public ISelfHandle<SHSubpass> class SH_API SHSubpass : public ISelfHandle<SHSubpass>
{ {
public:
using ExteriorDrawCallFunction = std::function<void(Handle<SHVkCommandBuffer>, Handle<SHRenderer>, uint32_t)>;
private: private:
/*---------------------------------------------------------------------*/ /*---------------------------------------------------------------------*/
/* PRIVATE MEMBER VARIABLES */ /* PRIVATE MEMBER VARIABLES */
/*---------------------------------------------------------------------*/ /*---------------------------------------------------------------------*/
Handle<SHRenderGraphStorage> graphStorage; 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 //! The index of the subpass in the render graph
uint32_t subpassIndex; uint32_t subpassIndex;
@ -37,9 +50,6 @@ namespace SHADE
//! //!
Handle<SHSuperBatch> superBatch; Handle<SHSuperBatch> superBatch;
//! Descriptor set layout to hold attachments
Handle<SHVkDescriptorSetLayout> descriptorSetLayout;
//! Color attachments //! Color attachments
std::vector<vk::AttachmentReference> colorReferences; std::vector<vk::AttachmentReference> colorReferences;
@ -79,8 +89,9 @@ namespace SHADE
//! after we draw everything from the batch. Because of this, these draw calls //! 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 //! are always the last things drawn, so DO NOT USE THIS FUNCTIONALITY FOR ANYTHING
//! COMPLEX. //! COMPLEX.
std::vector<std::function<void(Handle<SHVkCommandBuffer>&, uint32_t)>> exteriorDrawCalls; std::vector<ExteriorDrawCallFunction> exteriorDrawCalls;
/// For identifying subpasses
// For identifying subpasses
std::string name; std::string name;
@ -88,7 +99,7 @@ namespace SHADE
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
/* CTORS AND DTORS */ /* 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(SHSubpass&& rhs) noexcept;
SHSubpass& operator=(SHSubpass&& rhs) noexcept; SHSubpass& operator=(SHSubpass&& rhs) noexcept;
@ -102,12 +113,14 @@ namespace SHADE
void AddGeneralDepthOutput(std::string resourceToReference) noexcept; void AddGeneralDepthOutput(std::string resourceToReference) noexcept;
void AddInput(std::string resourceToReference) noexcept; void AddInput(std::string resourceToReference) noexcept;
void AddGeneralInput (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 // 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 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; void Init(SHResourceHub& resourceManager) noexcept;
@ -118,6 +131,10 @@ namespace SHADE
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
/* GETTERS AND SETTERS */ /* GETTERS AND SETTERS */
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
private:
void SetIndex (uint32_t index) noexcept;
public:
Handle<SHRenderGraphNode> const& GetParentNode(void) const noexcept; Handle<SHRenderGraphNode> const& GetParentNode(void) const noexcept;
SHSubPassIndex GetIndex() const noexcept; SHSubPassIndex GetIndex() const noexcept;
Handle<SHSuperBatch> GetSuperBatch(void) const noexcept; Handle<SHSuperBatch> GetSuperBatch(void) const noexcept;

View File

@ -347,4 +347,14 @@ namespace SHADE
return vkDepthFormat; 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::SwapchainKHR const& GetVkSwapchain (void) const noexcept;
vk::SurfaceFormatKHR GetSurfaceFormatKHR (void) const noexcept; vk::SurfaceFormatKHR GetSurfaceFormatKHR (void) const noexcept;
vk::Format GetDepthFormat (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 "ECS_Base/Managers/SHComponentManager.h"
#include "Graphics/MiddleEnd/Materials/SHMaterialSpec.h" #include "Graphics/MiddleEnd/Materials/SHMaterialSpec.h"
#include "Tools/Logger/SHLog.h" #include "Tools/Logger/SHLog.h"
#include "Graphics/MiddleEnd/GlobalData/SHGraphicsPredefinedData.h"
namespace SHADE namespace SHADE
@ -264,7 +265,8 @@ namespace SHADE
if(spec.properties.IsDefined()) if(spec.properties.IsDefined())
{ {
auto fragShader = SHResourceManager::LoadOrGet<SHVkShaderModule>(spec.fragShader); 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()); int const varCount = static_cast<int>(interface->GetVariableCount());
for (int i = 0; i < varCount; ++i) 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));
// }
//
//}