Implemented Shadow maps (still needs improvement) #314
|
@ -7,6 +7,7 @@
|
||||||
Translate: {x: 0, y: 0.304069757, z: 1.73034382}
|
Translate: {x: 0, y: 0.304069757, z: 1.73034382}
|
||||||
Rotate: {x: 0, y: 0, z: 0}
|
Rotate: {x: 0, y: 0, z: 0}
|
||||||
Scale: {x: 1, y: 1, z: 1}
|
Scale: {x: 1, y: 1, z: 1}
|
||||||
|
IsActive: true
|
||||||
Camera Component:
|
Camera Component:
|
||||||
Position: {x: 0, y: 0.304069757, z: 1.73034382}
|
Position: {x: 0, y: 0.304069757, z: 1.73034382}
|
||||||
Pitch: 0
|
Pitch: 0
|
||||||
|
@ -17,6 +18,7 @@
|
||||||
Near: 0.00999999978
|
Near: 0.00999999978
|
||||||
Far: 10000
|
Far: 10000
|
||||||
Perspective: true
|
Perspective: true
|
||||||
|
IsActive: true
|
||||||
Scripts: ~
|
Scripts: ~
|
||||||
- EID: 1
|
- EID: 1
|
||||||
Name: Raccoon
|
Name: Raccoon
|
||||||
|
@ -24,12 +26,14 @@
|
||||||
NumberOfChildren: 1
|
NumberOfChildren: 1
|
||||||
Components:
|
Components:
|
||||||
Transform Component:
|
Transform Component:
|
||||||
Translate: {x: 0, y: 0, z: 0}
|
Translate: {x: -1.86388135, y: 0.0544953719, z: 0}
|
||||||
Rotate: {x: 0, y: 0, z: 0}
|
Rotate: {x: -0, y: 0, z: -0}
|
||||||
Scale: {x: 1, y: 1, z: 1}
|
Scale: {x: 1, y: 1, z: 1}
|
||||||
|
IsActive: true
|
||||||
Renderable Component:
|
Renderable Component:
|
||||||
Mesh: 149697411
|
Mesh: 149697411
|
||||||
Material: 126974645
|
Material: 126974645
|
||||||
|
IsActive: true
|
||||||
Scripts: ~
|
Scripts: ~
|
||||||
- EID: 3
|
- EID: 3
|
||||||
Name: Bag
|
Name: Bag
|
||||||
|
@ -40,9 +44,11 @@
|
||||||
Translate: {x: 0.006237939, y: -0.000393368304, z: 0}
|
Translate: {x: 0.006237939, y: -0.000393368304, z: 0}
|
||||||
Rotate: {x: -0, y: 2.79945588, z: 0}
|
Rotate: {x: -0, y: 2.79945588, z: 0}
|
||||||
Scale: {x: 1.0000881, y: 1, z: 1.0000881}
|
Scale: {x: 1.0000881, y: 1, z: 1.0000881}
|
||||||
|
IsActive: true
|
||||||
Renderable Component:
|
Renderable Component:
|
||||||
Mesh: 144838771
|
Mesh: 144838771
|
||||||
Material: 123745521
|
Material: 123745521
|
||||||
|
IsActive: true
|
||||||
Scripts: ~
|
Scripts: ~
|
||||||
- EID: 2
|
- EID: 2
|
||||||
Name: DirectionalLight
|
Name: DirectionalLight
|
||||||
|
@ -50,12 +56,13 @@
|
||||||
NumberOfChildren: 0
|
NumberOfChildren: 0
|
||||||
Components:
|
Components:
|
||||||
Light Component:
|
Light Component:
|
||||||
Position: {x: 0, y: 0, z: 0}
|
Position: {x: 3, y: 4.5, z: 7}
|
||||||
Type: Directional
|
Type: Directional
|
||||||
Direction: {x: 0, y: 0, z: 1}
|
Direction: {x: -0.298000008, y: 0.522498012, z: 0.798600018}
|
||||||
Color: {x: 1, y: 1, z: 1, w: 1}
|
Color: {x: 1, y: 1, z: 1, w: 1}
|
||||||
Layer: 4294967295
|
Layer: 4294967295
|
||||||
Strength: 0
|
Strength: 0
|
||||||
|
IsActive: true
|
||||||
Scripts: ~
|
Scripts: ~
|
||||||
- EID: 4
|
- EID: 4
|
||||||
Name: AmbientLight
|
Name: AmbientLight
|
||||||
|
@ -69,4 +76,20 @@
|
||||||
Color: {x: 1, y: 1, z: 1, w: 1}
|
Color: {x: 1, y: 1, z: 1, w: 1}
|
||||||
Layer: 4294967295
|
Layer: 4294967295
|
||||||
Strength: 0.600000024
|
Strength: 0.600000024
|
||||||
|
IsActive: true
|
||||||
|
Scripts: ~
|
||||||
|
- EID: 5
|
||||||
|
Name: Floor
|
||||||
|
IsActive: true
|
||||||
|
NumberOfChildren: 0
|
||||||
|
Components:
|
||||||
|
Transform Component:
|
||||||
|
Translate: {x: 0, y: 0.0810000002, z: 0}
|
||||||
|
Rotate: {x: -1.57079637, y: 0, z: 0}
|
||||||
|
Scale: {x: 50, y: 50, z: 50}
|
||||||
|
IsActive: true
|
||||||
|
Renderable Component:
|
||||||
|
Mesh: 141771688
|
||||||
|
Material: 124370424
|
||||||
|
IsActive: true
|
||||||
Scripts: ~
|
Scripts: ~
|
|
@ -6,6 +6,8 @@ struct DirectionalLightStruct
|
||||||
uint isActive;
|
uint isActive;
|
||||||
uint cullingMask;
|
uint cullingMask;
|
||||||
vec4 diffuseColor;
|
vec4 diffuseColor;
|
||||||
|
mat4 pvMatrix;
|
||||||
|
uint shadowData;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct AmbientLightStruct
|
struct AmbientLightStruct
|
||||||
|
@ -22,7 +24,10 @@ layout(set = 3, binding = 1, rgba32f) uniform image2D normals;
|
||||||
layout(set = 3, binding = 2, rgba8) uniform image2D albedo;
|
layout(set = 3, binding = 2, rgba8) uniform image2D albedo;
|
||||||
layout(set = 3, binding = 3, r32ui) uniform uimage2D lightLayerData;
|
layout(set = 3, binding = 3, r32ui) uniform uimage2D lightLayerData;
|
||||||
layout(set = 3, binding = 4, r8) uniform image2D ssaoBlurredImage;
|
layout(set = 3, binding = 4, r8) uniform image2D ssaoBlurredImage;
|
||||||
layout(set = 3, binding = 5, rgba8) uniform image2D targetImage;
|
layout(set = 3, binding = 5, rgba8) uniform image2D positionWorldSpace;
|
||||||
|
layout(set = 3, binding = 6, rgba8) uniform image2D targetImage;
|
||||||
|
|
||||||
|
layout (set = 4, binding = 0) uniform sampler2D shadowMaps[]; // for textures (global)
|
||||||
|
|
||||||
layout(set = 1, binding = 0) uniform LightCounts
|
layout(set = 1, binding = 0) uniform LightCounts
|
||||||
{
|
{
|
||||||
|
@ -43,6 +48,25 @@ layout(std430, set = 1, binding = 4) buffer AmbientLightData
|
||||||
AmbientLightStruct aLightData[];
|
AmbientLightStruct aLightData[];
|
||||||
} AmbLightData;
|
} AmbLightData;
|
||||||
|
|
||||||
|
float CalcShadowValue (sampler2D shadowMap, vec4 worldSpaceFragPos, mat4 lightPV)
|
||||||
|
{
|
||||||
|
vec4 fragPosLightPOV = lightPV * worldSpaceFragPos;
|
||||||
|
vec3 converted = (fragPosLightPOV.xyz / fragPosLightPOV.w) * vec3(0.5f) + vec3(0.5f);
|
||||||
|
|
||||||
|
float sampledDepth = texture(shadowMap, converted.xy).r;
|
||||||
|
|
||||||
|
if (converted.x < 0.0f || converted.x > 1.0f || converted.y < 0.0f || converted.y > 1.0f)
|
||||||
|
return 1.0f;
|
||||||
|
|
||||||
|
if (fragPosLightPOV.z > sampledDepth && fragPosLightPOV.w > 0.0f)
|
||||||
|
{
|
||||||
|
return 0.0f;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return 1.0f;
|
||||||
|
// return step (fragPosLightPOV.z, );
|
||||||
|
}
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
// convenient variables
|
// convenient variables
|
||||||
|
@ -52,6 +76,9 @@ void main()
|
||||||
vec3 pixelDiffuse = imageLoad (albedo, globalThread).rgb;
|
vec3 pixelDiffuse = imageLoad (albedo, globalThread).rgb;
|
||||||
|
|
||||||
// Get position of fragment in world space
|
// Get position of fragment in world space
|
||||||
|
vec4 positionWorld = vec4 (imageLoad (positionWorldSpace, globalThread).rgb, 1.0f);
|
||||||
|
|
||||||
|
// Get position of fragment in view spacee
|
||||||
vec3 positionView = imageLoad (positions, globalThread).rgb;
|
vec3 positionView = imageLoad (positions, globalThread).rgb;
|
||||||
|
|
||||||
// normal of fragment
|
// normal of fragment
|
||||||
|
@ -62,6 +89,18 @@ void main()
|
||||||
|
|
||||||
vec3 fragColor = vec3 (0.0f);
|
vec3 fragColor = vec3 (0.0f);
|
||||||
|
|
||||||
|
vec4 shadowMapColor = vec4 (1.0f);
|
||||||
|
|
||||||
|
for (int i = 0; i < lightCounts.ambientLights; ++i)
|
||||||
|
{
|
||||||
|
if ((lightLayer & AmbLightData.aLightData[i].cullingMask) != 0)
|
||||||
|
{
|
||||||
|
// Just do some add
|
||||||
|
//fragColor += pixelDiffuse.rgb * AmbLightData.aLightData[i].ambientColor.rgb * vec3 (0.5f);
|
||||||
|
fragColor += pixelDiffuse.rgb * AmbLightData.aLightData[i].ambientColor.rgb * vec3 (AmbLightData.aLightData[i].strength);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (int i = 0; i < lightCounts.directionalLights; ++i)
|
for (int i = 0; i < lightCounts.directionalLights; ++i)
|
||||||
{
|
{
|
||||||
if ((lightLayer & DirLightData.dLightData[i].cullingMask) != 0)
|
if ((lightLayer & DirLightData.dLightData[i].cullingMask) != 0)
|
||||||
|
@ -74,16 +113,13 @@ void main()
|
||||||
|
|
||||||
// Calculate the fragment color
|
// Calculate the fragment color
|
||||||
fragColor += DirLightData.dLightData[i].diffuseColor.rgb * diffuseStrength.rrr * pixelDiffuse;
|
fragColor += DirLightData.dLightData[i].diffuseColor.rgb * diffuseStrength.rrr * pixelDiffuse;
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < lightCounts.ambientLights; ++i)
|
// If the shadow map is enabled (test the bit)
|
||||||
|
if ((DirLightData.dLightData[i].shadowData & uint(1)) == 1)
|
||||||
{
|
{
|
||||||
if ((lightLayer & AmbLightData.aLightData[i].cullingMask) != 0)
|
// calculate shadow map here
|
||||||
{
|
fragColor *= CalcShadowValue (shadowMaps[0], positionWorld, DirLightData.dLightData[i].pvMatrix).xxx;
|
||||||
// Just do some add
|
}
|
||||||
//fragColor += pixelDiffuse.rgb * AmbLightData.aLightData[i].ambientColor.rgb * vec3 (0.5f);
|
|
||||||
fragColor += pixelDiffuse.rgb * AmbLightData.aLightData[i].ambientColor.rgb * vec3 (AmbLightData.aLightData[i].strength);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -92,6 +128,12 @@ void main()
|
||||||
|
|
||||||
// store result into result image
|
// store result into result image
|
||||||
imageStore(targetImage, ivec2(gl_GlobalInvocationID.xy), vec4(fragColor.rgb, 1.0f));
|
imageStore(targetImage, ivec2(gl_GlobalInvocationID.xy), vec4(fragColor.rgb, 1.0f));
|
||||||
//imageStore(targetImage, ivec2(gl_GlobalInvocationID.xy), vec4(ssaoVal.rrr, 1.0f));
|
|
||||||
|
// vec2 normTexCoords = vec2 (gl_GlobalInvocationID.xy) / vec2 (1024.0f);
|
||||||
|
// vec4 shadowMapVal = texture(shadowMaps[0], normTexCoords);
|
||||||
|
// if (normTexCoords.x > 1.0f || normTexCoords.y > 1.0f)
|
||||||
|
// shadowMapVal = vec4(0.0f);
|
||||||
|
|
||||||
|
// imageStore(targetImage, ivec2(gl_GlobalInvocationID.xy), shadowMapVal.xxxx);
|
||||||
|
|
||||||
}
|
}
|
Binary file not shown.
|
@ -0,0 +1,22 @@
|
||||||
|
#version 450
|
||||||
|
#extension GL_KHR_vulkan_glsl : enable
|
||||||
|
|
||||||
|
//#include "ShaderDescriptorDefinitions.glsl"
|
||||||
|
|
||||||
|
|
||||||
|
layout(location = 0) in vec3 aVertexPos;
|
||||||
|
layout(location = 4) in mat4 worldTransform;
|
||||||
|
|
||||||
|
layout(set = 1, binding = 0) uniform CameraData
|
||||||
|
{
|
||||||
|
vec4 position;
|
||||||
|
mat4 vpMat;
|
||||||
|
mat4 viewMat;
|
||||||
|
mat4 projMat;
|
||||||
|
} cameraData;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
// clip space for rendering
|
||||||
|
gl_Position = cameraData.vpMat * worldTransform * vec4 (aVertexPos, 1.0f);
|
||||||
|
}
|
Binary file not shown.
|
@ -0,0 +1,3 @@
|
||||||
|
Name: ShadowMap_VS
|
||||||
|
ID: 44646107
|
||||||
|
Type: 2
|
|
@ -16,11 +16,12 @@ layout(location = 0) in struct
|
||||||
vec4 vertPos; // location 0
|
vec4 vertPos; // location 0
|
||||||
vec2 uv; // location = 1
|
vec2 uv; // location = 1
|
||||||
vec4 normal; // location = 2
|
vec4 normal; // location = 2
|
||||||
|
vec4 worldPos; // location = 3
|
||||||
|
|
||||||
} In;
|
} In;
|
||||||
|
|
||||||
// material stuff
|
// material stuff
|
||||||
layout(location = 3) flat in struct
|
layout(location = 4) flat in struct
|
||||||
{
|
{
|
||||||
int materialIndex;
|
int materialIndex;
|
||||||
uint eid;
|
uint eid;
|
||||||
|
@ -38,12 +39,14 @@ layout(location = 1) out uint outEntityID;
|
||||||
layout(location = 2) out uint lightLayerIndices;
|
layout(location = 2) out uint lightLayerIndices;
|
||||||
layout(location = 3) out vec4 normals;
|
layout(location = 3) out vec4 normals;
|
||||||
layout(location = 4) out vec4 albedo;
|
layout(location = 4) out vec4 albedo;
|
||||||
|
layout(location = 5) out vec4 worldSpacePosition;
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
position = In.vertPos;
|
position = In.vertPos;
|
||||||
normals = In.normal;
|
normals = In.normal;
|
||||||
albedo = texture(textures[nonuniformEXT(MatProp.data[In2.materialIndex].textureIndex)], In.uv) * MatProp.data[In2.materialIndex].color;
|
albedo = texture(textures[nonuniformEXT(MatProp.data[In2.materialIndex].textureIndex)], In.uv) * MatProp.data[In2.materialIndex].color;
|
||||||
|
worldSpacePosition = In.worldPos;
|
||||||
|
|
||||||
outEntityID = In2.eid;
|
outEntityID = In2.eid;
|
||||||
lightLayerIndices = In2.lightLayerIndex;
|
lightLayerIndices = In2.lightLayerIndex;
|
||||||
|
|
Binary file not shown.
|
@ -17,11 +17,12 @@ layout(location = 0) out struct
|
||||||
vec4 vertPos; // location 0
|
vec4 vertPos; // location 0
|
||||||
vec2 uv; // location = 1
|
vec2 uv; // location = 1
|
||||||
vec4 normal; // location = 2
|
vec4 normal; // location = 2
|
||||||
|
vec4 worldPos; // location = 3
|
||||||
|
|
||||||
} Out;
|
} Out;
|
||||||
|
|
||||||
// material stuff
|
// material stuff
|
||||||
layout(location = 3) out struct
|
layout(location = 4) out struct
|
||||||
{
|
{
|
||||||
int materialIndex;
|
int materialIndex;
|
||||||
uint eid;
|
uint eid;
|
||||||
|
@ -49,6 +50,8 @@ void main()
|
||||||
// gBuffer position will be in view space
|
// gBuffer position will be in view space
|
||||||
Out.vertPos = modelViewMat * vec4(aVertexPos, 1.0f);
|
Out.vertPos = modelViewMat * vec4(aVertexPos, 1.0f);
|
||||||
|
|
||||||
|
Out.worldPos = worldTransform * vec4 (aVertexPos, 1.0f);
|
||||||
|
|
||||||
// uvs for texturing in fragment shader
|
// uvs for texturing in fragment shader
|
||||||
Out.uv = aUV;
|
Out.uv = aUV;
|
||||||
|
|
||||||
|
|
Binary file not shown.
|
@ -270,8 +270,12 @@ namespace SHADE
|
||||||
camera.viewMatrix(1, 3) = -UP.Dot(camera.position + camera.offset);
|
camera.viewMatrix(1, 3) = -UP.Dot(camera.position + camera.offset);
|
||||||
camera.viewMatrix(2, 3) = -view.Dot(camera.position + camera.offset);
|
camera.viewMatrix(2, 3) = -view.Dot(camera.position + camera.offset);
|
||||||
|
|
||||||
|
//SHVec3 target{ 0.0f,0.0f,-1.0f };
|
||||||
|
//target = SHVec3::RotateX(target, SHMath::DegreesToRadians(camera.pitch));
|
||||||
|
//target = SHVec3::RotateY(target, SHMath::DegreesToRadians(camera.yaw));
|
||||||
|
//target += camera.position;
|
||||||
|
|
||||||
|
//camera.viewMatrix = SHMatrix::Transpose(SHMatrix::LookAtLH(camera.position, target, SHVec3(0.0f, -1.0f, 0.0f)));
|
||||||
|
|
||||||
camera.dirtyView = false;
|
camera.dirtyView = false;
|
||||||
}
|
}
|
||||||
|
@ -309,7 +313,9 @@ namespace SHADE
|
||||||
camera.orthoProjMatrix(2, 3) = -n / (f-n);
|
camera.orthoProjMatrix(2, 3) = -n / (f-n);
|
||||||
camera.orthoProjMatrix(3, 3) = 1.0f;
|
camera.orthoProjMatrix(3, 3) = 1.0f;
|
||||||
|
|
||||||
//camera.orthoProjMatrix = SHMatrix::OrthographicRH(camera.GetWidth(), camera.GetHeight(), camera.GetNear(), camera.GetFar());
|
//camera.perspProjMatrix = SHMatrix::OrthographicLH(9.0f, 9.0f, 0.1f, 20.0f);
|
||||||
|
camera.orthoProjMatrix = SHMatrix::OrthographicRH(camera.GetWidth(), camera.GetHeight(), camera.GetNear(), camera.GetFar());
|
||||||
|
//camera.perspProjMatrix = SHMatrix::OrthographicLH(5.0f, 5.0f, 0.1f, 20.0f);
|
||||||
//camera.projMatrix.Transpose();
|
//camera.projMatrix.Transpose();
|
||||||
|
|
||||||
camera.dirtyProj = false;
|
camera.dirtyProj = false;
|
||||||
|
|
|
@ -489,7 +489,7 @@ namespace SHADE
|
||||||
|
|
||||||
//auto const& renderers = gfxSystem->GetDefaultViewport()->GetRenderers();
|
//auto const& renderers = gfxSystem->GetDefaultViewport()->GetRenderers();
|
||||||
auto renderGraph = gfxSystem->GetRenderGraph();
|
auto renderGraph = gfxSystem->GetRenderGraph();
|
||||||
auto renderPass = renderGraph->GetNode("ImGui Node")->GetRenderpass();
|
auto renderPass = renderGraph->GetNode(SHGraphicsConstants::RenderGraphEntityNames::IMGUI_PASS.data())->GetRenderpass();
|
||||||
|
|
||||||
if(ImGui_ImplVulkan_Init(&initInfo, renderPass->GetVkRenderpass()) == false)
|
if(ImGui_ImplVulkan_Init(&initInfo, renderPass->GetVkRenderpass()) == false)
|
||||||
{
|
{
|
||||||
|
@ -508,7 +508,7 @@ namespace SHADE
|
||||||
|
|
||||||
ImGui_ImplVulkan_DestroyFontUploadObjects();
|
ImGui_ImplVulkan_DestroyFontUploadObjects();
|
||||||
|
|
||||||
renderGraph->GetNode("ImGui Node")->GetSubpass("ImGui Draw")->AddExteriorDrawCalls([](Handle<SHVkCommandBuffer> cmd, Handle<SHRenderer> renderer, uint32_t frameIndex)
|
renderGraph->GetNode(SHGraphicsConstants::RenderGraphEntityNames::IMGUI_PASS.data())->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());
|
||||||
|
|
|
@ -175,6 +175,27 @@ namespace SHADE
|
||||||
writeInfo.descImageInfos[i].sampler = sampler ? sampler->GetVkSampler() : nullptr;
|
writeInfo.descImageInfos[i].sampler = sampler ? sampler->GetVkSampler() : nullptr;
|
||||||
writeInfo.descImageInfos[i].imageLayout = layout;
|
writeInfo.descImageInfos[i].imageLayout = layout;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Rest is not used, so it doesn't matter what's in them, we just want to pacify Vulkan
|
||||||
|
for (uint32_t i = imageViewsAndSamplers.size(); i < writeInfo.descImageInfos.size(); ++i)
|
||||||
|
{
|
||||||
|
writeInfo.descImageInfos[i].sampler = std::get<Handle<SHVkSampler>>(imageViewsAndSamplers.back())->GetVkSampler();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHVkDescriptorSetGroup::ModifyWriteDescImage(uint32_t set, uint32_t binding, std::tuple<Handle<SHVkImageView>, Handle<SHVkSampler>, vk::ImageLayout> const& imageViewAndSampler, uint32_t descIndex) noexcept
|
||||||
|
{
|
||||||
|
// Find the target writeDescSet
|
||||||
|
BindingAndSetHash writeHash = binding;
|
||||||
|
writeHash |= static_cast<uint64_t>(set) << 32;
|
||||||
|
auto& writeInfo = updater.writeInfos[updater.writeHashMap.at(writeHash)];
|
||||||
|
|
||||||
|
// write sampler and image view
|
||||||
|
auto& [view, sampler, layout] = imageViewAndSampler;
|
||||||
|
writeInfo.descImageInfos[descIndex].imageView = view->GetImageView();
|
||||||
|
writeInfo.descImageInfos[descIndex].sampler = sampler ? sampler->GetVkSampler() : nullptr;
|
||||||
|
writeInfo.descImageInfos[descIndex].imageLayout = layout;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHVkDescriptorSetGroup::ModifyWriteDescBuffer(uint32_t set, uint32_t binding, std::span<Handle<SHVkBuffer>> const& buffers, uint32_t offset, uint32_t range) noexcept
|
void SHVkDescriptorSetGroup::ModifyWriteDescBuffer(uint32_t set, uint32_t binding, std::span<Handle<SHVkBuffer>> const& buffers, uint32_t offset, uint32_t range) noexcept
|
||||||
|
@ -200,6 +221,28 @@ namespace SHADE
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SHVkDescriptorSetGroup::UpdateDescriptorSetImage(uint32_t set, uint32_t binding, uint32_t descArrayIndex) noexcept
|
||||||
|
{
|
||||||
|
vk::WriteDescriptorSet writeDescSet{};
|
||||||
|
|
||||||
|
// Get binding + set hash
|
||||||
|
BindingAndSetHash bsHash = SHVkUtil::GenBindingSetHash(set, binding);
|
||||||
|
|
||||||
|
// to index a write for a binding
|
||||||
|
uint32_t writeInfoIndex = updater.writeHashMap[bsHash];
|
||||||
|
|
||||||
|
// Initialize info for write
|
||||||
|
writeDescSet.descriptorType = layoutsUsed[set]->GetBindings()[binding].Type;
|
||||||
|
writeDescSet.dstArrayElement = descArrayIndex;
|
||||||
|
writeDescSet.dstSet = descSets[set];
|
||||||
|
writeDescSet.dstBinding = binding;
|
||||||
|
|
||||||
|
writeDescSet.pImageInfo = updater.writeInfos[writeInfoIndex].descImageInfos.data() + descArrayIndex;
|
||||||
|
writeDescSet.descriptorCount = 1u;
|
||||||
|
|
||||||
|
device->UpdateDescriptorSet(writeDescSet);
|
||||||
|
}
|
||||||
|
|
||||||
void SHVkDescriptorSetGroup::UpdateDescriptorSetImages(uint32_t set, uint32_t binding) noexcept
|
void SHVkDescriptorSetGroup::UpdateDescriptorSetImages(uint32_t set, uint32_t binding) noexcept
|
||||||
{
|
{
|
||||||
vk::WriteDescriptorSet writeDescSet{};
|
vk::WriteDescriptorSet writeDescSet{};
|
||||||
|
|
|
@ -63,10 +63,12 @@ namespace SHADE
|
||||||
/*-----------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------*/
|
||||||
/* Public member functions */
|
/* Public member functions */
|
||||||
/*-----------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------*/
|
||||||
|
void UpdateDescriptorSetImage (uint32_t set, uint32_t binding, uint32_t descArrayIndex) noexcept;
|
||||||
void UpdateDescriptorSetImages(uint32_t set, uint32_t binding) noexcept;
|
void UpdateDescriptorSetImages(uint32_t set, uint32_t binding) noexcept;
|
||||||
void UpdateDescriptorSetBuffer(uint32_t set, uint32_t binding) noexcept;
|
void UpdateDescriptorSetBuffer(uint32_t set, uint32_t binding) noexcept;
|
||||||
|
|
||||||
void ModifyWriteDescImage(uint32_t set, uint32_t binding, std::span<std::tuple<Handle<SHVkImageView>, Handle<SHVkSampler>, vk::ImageLayout>> const& imageViewsAndSamplers) noexcept;
|
void ModifyWriteDescImage(uint32_t set, uint32_t binding, std::span<std::tuple<Handle<SHVkImageView>, Handle<SHVkSampler>, vk::ImageLayout>> const& imageViewsAndSamplers) noexcept;
|
||||||
|
void ModifyWriteDescImage(uint32_t set, uint32_t binding, std::tuple<Handle<SHVkImageView>, Handle<SHVkSampler>, vk::ImageLayout> const& imageViewAndSampler, uint32_t descIndex) noexcept;
|
||||||
void ModifyWriteDescBuffer (uint32_t set, uint32_t binding, std::span<Handle<SHVkBuffer>> const& buffers, uint32_t offset, uint32_t range) noexcept;
|
void ModifyWriteDescBuffer (uint32_t set, uint32_t binding, std::span<Handle<SHVkBuffer>> const& buffers, uint32_t offset, uint32_t range) noexcept;
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -183,33 +183,43 @@ namespace SHADE
|
||||||
/*if (!extensionsSupported)
|
/*if (!extensionsSupported)
|
||||||
SHUtil::ReportWarning("Some of the required extensions cannot be found on the physical device. ");*/
|
SHUtil::ReportWarning("Some of the required extensions cannot be found on the physical device. ");*/
|
||||||
|
|
||||||
vk::PhysicalDeviceFeatures features{}; // ADD MORE FEATURES HERE IF NEEDED
|
vk::PhysicalDeviceDescriptorIndexingFeatures descIndexingFeature
|
||||||
|
{
|
||||||
|
.shaderSampledImageArrayNonUniformIndexing = VK_TRUE,
|
||||||
|
.descriptorBindingPartiallyBound = VK_TRUE,
|
||||||
|
.descriptorBindingVariableDescriptorCount = VK_TRUE,
|
||||||
|
.runtimeDescriptorArray = VK_TRUE,
|
||||||
|
};
|
||||||
|
|
||||||
|
vk::PhysicalDeviceRobustness2FeaturesEXT robustFeatures
|
||||||
|
{
|
||||||
|
.nullDescriptor = VK_TRUE,
|
||||||
|
};
|
||||||
|
|
||||||
|
robustFeatures.pNext = &descIndexingFeature;
|
||||||
|
|
||||||
|
vk::PhysicalDeviceFeatures2 features{}; // ADD MORE FEATURES HERE IF NEEDED
|
||||||
|
|
||||||
// point and lines fill mode
|
// point and lines fill mode
|
||||||
features.fillModeNonSolid = VK_TRUE;
|
features.features.fillModeNonSolid = VK_TRUE;
|
||||||
features.samplerAnisotropy = VK_TRUE;
|
features.features.samplerAnisotropy = VK_TRUE;
|
||||||
features.multiDrawIndirect = VK_TRUE;
|
features.features.multiDrawIndirect = VK_TRUE;
|
||||||
features.independentBlend = VK_TRUE;
|
features.features.independentBlend = VK_TRUE;
|
||||||
|
features.features.wideLines = VK_TRUE;
|
||||||
|
|
||||||
// for wide lines
|
features.pNext = &robustFeatures;
|
||||||
features.wideLines = true;
|
|
||||||
|
|
||||||
vk::PhysicalDeviceDescriptorIndexingFeatures descIndexingFeature{};
|
|
||||||
descIndexingFeature.descriptorBindingVariableDescriptorCount = true;
|
|
||||||
descIndexingFeature.shaderSampledImageArrayNonUniformIndexing = true;
|
|
||||||
descIndexingFeature.runtimeDescriptorArray = true;
|
|
||||||
|
|
||||||
// Prepare to create the device
|
// Prepare to create the device
|
||||||
vk::DeviceCreateInfo deviceCreateInfo
|
vk::DeviceCreateInfo deviceCreateInfo
|
||||||
{
|
{
|
||||||
.pNext = &descIndexingFeature,
|
.pNext = &features,
|
||||||
.queueCreateInfoCount = static_cast<uint32_t>(queueCreateInfos.size()),
|
.queueCreateInfoCount = static_cast<uint32_t>(queueCreateInfos.size()),
|
||||||
.pQueueCreateInfos = queueCreateInfos.data(),
|
.pQueueCreateInfos = queueCreateInfos.data(),
|
||||||
.enabledLayerCount = 0, // deprecated and ignored
|
.enabledLayerCount = 0, // deprecated and ignored
|
||||||
.ppEnabledLayerNames = nullptr, // deprecated and ignored
|
.ppEnabledLayerNames = nullptr, // deprecated and ignored
|
||||||
.enabledExtensionCount = !extensionsSupported ? 0 : static_cast<uint32_t>(requiredExtensions.size()),
|
.enabledExtensionCount = !extensionsSupported ? 0 : static_cast<uint32_t>(requiredExtensions.size()),
|
||||||
.ppEnabledExtensionNames = !extensionsSupported ? nullptr : requiredExtensions.data(),
|
.ppEnabledExtensionNames = !extensionsSupported ? nullptr : requiredExtensions.data(),
|
||||||
.pEnabledFeatures = &features
|
//.pEnabledFeatures = &features
|
||||||
};
|
};
|
||||||
|
|
||||||
// Actually create the device
|
// Actually create the device
|
||||||
|
|
|
@ -10,5 +10,8 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
//! We need to get the light component and initialize the relevant variables.
|
//! We need to get the light component and initialize the relevant variables.
|
||||||
EntityID lightEntity;
|
EntityID lightEntity;
|
||||||
|
|
||||||
|
//! Generate a renderer for the light component
|
||||||
|
bool generateRenderer;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,6 +33,7 @@ namespace SHADE
|
||||||
.maxAnisotropy = 1.0f,
|
.maxAnisotropy = 1.0f,
|
||||||
.minLod = params.minLod,
|
.minLod = params.minLod,
|
||||||
.maxLod = params.maxLod,
|
.maxLod = params.maxLod,
|
||||||
|
.borderColor = vk::BorderColor::eFloatOpaqueWhite
|
||||||
};
|
};
|
||||||
|
|
||||||
// Create the sampler
|
// Create the sampler
|
||||||
|
|
|
@ -551,7 +551,7 @@ namespace SHADE
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
/* SHBatch - Usage Functions */
|
/* SHBatch - Usage Functions */
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
void SHBatch::Draw(Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex)
|
void SHBatch::Draw(Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex, bool bindBatchPipeline/* = true*/)
|
||||||
{
|
{
|
||||||
if (frameIndex >= SHGraphicsConstants::NUM_FRAME_BUFFERS)
|
if (frameIndex >= SHGraphicsConstants::NUM_FRAME_BUFFERS)
|
||||||
{
|
{
|
||||||
|
@ -566,7 +566,10 @@ namespace SHADE
|
||||||
// Bind all required objects before drawing
|
// Bind all required objects before drawing
|
||||||
static std::array<uint32_t, 1> dynamicOffset{ 0 };
|
static std::array<uint32_t, 1> dynamicOffset{ 0 };
|
||||||
cmdBuffer->BeginLabeledSegment("SHBatch for Pipeline #" + std::to_string(pipeline.GetId().Data.Index));
|
cmdBuffer->BeginLabeledSegment("SHBatch for Pipeline #" + std::to_string(pipeline.GetId().Data.Index));
|
||||||
|
|
||||||
|
if (bindBatchPipeline)
|
||||||
cmdBuffer->BindPipeline(pipeline);
|
cmdBuffer->BindPipeline(pipeline);
|
||||||
|
|
||||||
cmdBuffer->BindVertexBuffer(SHGraphicsConstants::VertexBufferBindings::TRANSFORM, transformDataBuffer[frameIndex], 0);
|
cmdBuffer->BindVertexBuffer(SHGraphicsConstants::VertexBufferBindings::TRANSFORM, transformDataBuffer[frameIndex], 0);
|
||||||
cmdBuffer->BindVertexBuffer(SHGraphicsConstants::VertexBufferBindings::INTEGER_DATA, instancedIntegerBuffer[frameIndex], 0);
|
cmdBuffer->BindVertexBuffer(SHGraphicsConstants::VertexBufferBindings::INTEGER_DATA, instancedIntegerBuffer[frameIndex], 0);
|
||||||
if (matPropsDescSet[frameIndex])
|
if (matPropsDescSet[frameIndex])
|
||||||
|
|
|
@ -87,7 +87,7 @@ namespace SHADE
|
||||||
void UpdateTransformBuffer(uint32_t frameIndex);
|
void UpdateTransformBuffer(uint32_t frameIndex);
|
||||||
void UpdateInstancedIntegerBuffer(uint32_t frameIndex);
|
void UpdateInstancedIntegerBuffer(uint32_t frameIndex);
|
||||||
void Build(Handle<SHVkLogicalDevice> device, Handle<SHVkDescriptorPool> descPool, uint32_t frameIndex) ;
|
void Build(Handle<SHVkLogicalDevice> device, Handle<SHVkDescriptorPool> descPool, uint32_t frameIndex) ;
|
||||||
void Draw(Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex);
|
void Draw(Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex, bool bindBatchPipeline = true);
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------*/
|
||||||
/* Getter Functions */
|
/* Getter Functions */
|
||||||
|
|
|
@ -107,12 +107,12 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHSuperBatch::Draw(Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex) noexcept
|
void SHSuperBatch::Draw(Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex, bool bindBatchPipeline /*= true*/) noexcept
|
||||||
{
|
{
|
||||||
// Build all batches
|
// Build all batches
|
||||||
for (auto& batch : batches)
|
for (auto& batch : batches)
|
||||||
{
|
{
|
||||||
batch.Draw(cmdBuffer, frameIndex);
|
batch.Draw(cmdBuffer, frameIndex, bindBatchPipeline);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -57,7 +57,7 @@ namespace SHADE
|
||||||
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, bool bindBatchPipeline = true) noexcept;
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------*/
|
||||||
/* Getter Functions */
|
/* Getter Functions */
|
||||||
|
|
|
@ -13,6 +13,8 @@ namespace SHADE
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
std::vector<Handle<SHVkDescriptorSetLayout>> SHGraphicsPredefinedData::predefinedLayouts;
|
std::vector<Handle<SHVkDescriptorSetLayout>> SHGraphicsPredefinedData::predefinedLayouts;
|
||||||
SHVertexInputState SHGraphicsPredefinedData::defaultVertexInputState;
|
SHVertexInputState SHGraphicsPredefinedData::defaultVertexInputState;
|
||||||
|
SHVertexInputState SHGraphicsPredefinedData::shadowMapVertexInputState;
|
||||||
|
|
||||||
std::vector<SHGraphicsPredefinedData::PerSystem> SHGraphicsPredefinedData::perSystemData;
|
std::vector<SHGraphicsPredefinedData::PerSystem> SHGraphicsPredefinedData::perSystemData;
|
||||||
|
|
||||||
//SHGraphicsPredefinedData::PerSystem SHGraphicsPredefinedData::batchingSystemData;
|
//SHGraphicsPredefinedData::PerSystem SHGraphicsPredefinedData::batchingSystemData;
|
||||||
|
@ -150,12 +152,26 @@ namespace SHADE
|
||||||
Handle<SHVkDescriptorSetLayout> fontDataDescSetLayout = logicalDevice->CreateDescriptorSetLayout({ fontBitmapBinding, fontMatrixBinding });
|
Handle<SHVkDescriptorSetLayout> fontDataDescSetLayout = logicalDevice->CreateDescriptorSetLayout({ fontBitmapBinding, fontMatrixBinding });
|
||||||
SET_VK_OBJ_NAME(logicalDevice, vk::ObjectType::eDescriptorSetLayout, fontDataDescSetLayout->GetVkHandle(), "[Descriptor Set Layout] Font Data");
|
SET_VK_OBJ_NAME(logicalDevice, vk::ObjectType::eDescriptorSetLayout, fontDataDescSetLayout->GetVkHandle(), "[Descriptor Set Layout] Font Data");
|
||||||
|
|
||||||
|
// descriptor binding for storing shadow maps
|
||||||
|
SHVkDescriptorSetLayout::Binding shadowMapBinding
|
||||||
|
{
|
||||||
|
.Type = vk::DescriptorType::eCombinedImageSampler,
|
||||||
|
.Stage = vk::ShaderStageFlagBits::eVertex | vk::ShaderStageFlagBits::eFragment | vk::ShaderStageFlagBits::eCompute,
|
||||||
|
.BindPoint = SHGraphicsConstants::DescriptorSetBindings::IMAGE_AND_SAMPLERS_DATA,
|
||||||
|
.DescriptorCount = 200, // we can have up to 200 textures for now
|
||||||
|
.flags = vk::DescriptorBindingFlagBits::eVariableDescriptorCount,
|
||||||
|
};
|
||||||
|
|
||||||
|
// For global data (generic data and textures)
|
||||||
|
Handle<SHVkDescriptorSetLayout> shadowMapDescLayout = logicalDevice->CreateDescriptorSetLayout({ shadowMapBinding });
|
||||||
|
SET_VK_OBJ_NAME(logicalDevice, vk::ObjectType::eDescriptorSetLayout, shadowMapDescLayout->GetVkHandle(), "[Descriptor Set Layout] Shadow Maps");
|
||||||
|
|
||||||
predefinedLayouts.push_back(staticGlobalLayout);
|
predefinedLayouts.push_back(staticGlobalLayout);
|
||||||
predefinedLayouts.push_back(lightDataDescSetLayout);
|
predefinedLayouts.push_back(lightDataDescSetLayout);
|
||||||
predefinedLayouts.push_back(cameraDataGlobalLayout);
|
predefinedLayouts.push_back(cameraDataGlobalLayout);
|
||||||
predefinedLayouts.push_back(materialDataPerInstanceLayout);
|
predefinedLayouts.push_back(materialDataPerInstanceLayout);
|
||||||
predefinedLayouts.push_back(fontDataDescSetLayout);
|
predefinedLayouts.push_back(fontDataDescSetLayout);
|
||||||
|
predefinedLayouts.push_back(shadowMapDescLayout);
|
||||||
|
|
||||||
perSystemData[SHUtilities::ConvertEnum(SystemType::BATCHING)].descSetLayouts = GetPredefinedDescSetLayouts
|
perSystemData[SHUtilities::ConvertEnum(SystemType::BATCHING)].descSetLayouts = GetPredefinedDescSetLayouts
|
||||||
(
|
(
|
||||||
|
@ -179,7 +195,7 @@ namespace SHADE
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHGraphicsPredefinedData::InitDefaultVertexInputState(void) noexcept
|
void SHGraphicsPredefinedData::InitPredefinedVertexInputState(void) noexcept
|
||||||
{
|
{
|
||||||
defaultVertexInputState.AddBinding(false, false, { SHVertexAttribute(SHAttribFormat::FLOAT_3D) }); // positions at binding 0
|
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_2D) }); // UVs at binding 1
|
||||||
|
@ -187,13 +203,16 @@ namespace SHADE
|
||||||
defaultVertexInputState.AddBinding(false, false, { SHVertexAttribute(SHAttribFormat::FLOAT_3D) }); // Tangents at binding 3
|
defaultVertexInputState.AddBinding(false, false, { SHVertexAttribute(SHAttribFormat::FLOAT_3D) }); // Tangents at binding 3
|
||||||
defaultVertexInputState.AddBinding(true, true, { SHVertexAttribute(SHAttribFormat::MAT_4D) }); // Transform at binding 4 - 7 (4 slots)
|
defaultVertexInputState.AddBinding(true, true, { SHVertexAttribute(SHAttribFormat::MAT_4D) }); // Transform at binding 4 - 7 (4 slots)
|
||||||
defaultVertexInputState.AddBinding(true, true, { SHVertexAttribute(SHAttribFormat::UINT32_2D) }); // Instanced integer data at index 8
|
defaultVertexInputState.AddBinding(true, true, { SHVertexAttribute(SHAttribFormat::UINT32_2D) }); // Instanced integer data at index 8
|
||||||
|
|
||||||
|
shadowMapVertexInputState.AddBinding(false, false, { SHVertexAttribute(SHAttribFormat::FLOAT_3D)});
|
||||||
|
shadowMapVertexInputState.AddBinding(true, true, { SHVertexAttribute(SHAttribFormat::MAT_4D) }, 4, 4); // Transform at binding 4 - 7 (4 slots)
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHGraphicsPredefinedData::Init(Handle<SHVkLogicalDevice> logicalDevice) noexcept
|
void SHGraphicsPredefinedData::Init(Handle<SHVkLogicalDevice> logicalDevice) noexcept
|
||||||
{
|
{
|
||||||
perSystemData.resize(SHUtilities::ConvertEnum(SystemType::NUM_TYPES));
|
perSystemData.resize(SHUtilities::ConvertEnum(SystemType::NUM_TYPES));
|
||||||
InitDescSetLayouts(logicalDevice);
|
InitDescSetLayouts(logicalDevice);
|
||||||
InitDefaultVertexInputState();
|
InitPredefinedVertexInputState();
|
||||||
InitDescMappings();
|
InitDescMappings();
|
||||||
InitDummyPipelineLayouts (logicalDevice);
|
InitDummyPipelineLayouts (logicalDevice);
|
||||||
}
|
}
|
||||||
|
@ -217,6 +236,11 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
SHVertexInputState const& SHGraphicsPredefinedData::GetShadowMapViState(void) noexcept
|
||||||
|
{
|
||||||
|
return shadowMapVertexInputState;
|
||||||
|
}
|
||||||
|
|
||||||
SHGraphicsPredefinedData::PerSystem const& SHGraphicsPredefinedData::GetSystemData(SystemType systemType) noexcept
|
SHGraphicsPredefinedData::PerSystem const& SHGraphicsPredefinedData::GetSystemData(SystemType systemType) noexcept
|
||||||
{
|
{
|
||||||
return perSystemData[static_cast<uint32_t>(systemType)];
|
return perSystemData[static_cast<uint32_t>(systemType)];
|
||||||
|
|
|
@ -28,6 +28,7 @@ namespace SHADE
|
||||||
CAMERA = 0x04,
|
CAMERA = 0x04,
|
||||||
MATERIALS = 0x08,
|
MATERIALS = 0x08,
|
||||||
FONT = 0x10,
|
FONT = 0x10,
|
||||||
|
SHADOW = 0x20,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class SystemType
|
enum class SystemType
|
||||||
|
@ -57,6 +58,9 @@ namespace SHADE
|
||||||
//! Default vertex input state (used by everything).
|
//! Default vertex input state (used by everything).
|
||||||
static SHVertexInputState defaultVertexInputState;
|
static SHVertexInputState defaultVertexInputState;
|
||||||
|
|
||||||
|
//! vertex input state for shadow mapping
|
||||||
|
static SHVertexInputState shadowMapVertexInputState;
|
||||||
|
|
||||||
//! Predefined data for each type of system
|
//! Predefined data for each type of system
|
||||||
static std::vector<PerSystem> perSystemData;
|
static std::vector<PerSystem> perSystemData;
|
||||||
|
|
||||||
|
@ -72,7 +76,7 @@ namespace SHADE
|
||||||
static void InitDescMappings (void) noexcept;
|
static void InitDescMappings (void) noexcept;
|
||||||
static void InitDummyPipelineLayouts (Handle<SHVkLogicalDevice> logicalDevice) noexcept;
|
static void InitDummyPipelineLayouts (Handle<SHVkLogicalDevice> logicalDevice) noexcept;
|
||||||
static void InitDescSetLayouts (Handle<SHVkLogicalDevice> logicalDevice) noexcept;
|
static void InitDescSetLayouts (Handle<SHVkLogicalDevice> logicalDevice) noexcept;
|
||||||
static void InitDefaultVertexInputState (void) noexcept;
|
static void InitPredefinedVertexInputState (void) noexcept;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
|
@ -90,6 +94,7 @@ namespace SHADE
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
static std::vector<Handle<SHVkDescriptorSetLayout>> GetPredefinedDescSetLayouts (SHGraphicsPredefinedData::PredefinedDescSetLayoutTypes types) noexcept;
|
static std::vector<Handle<SHVkDescriptorSetLayout>> GetPredefinedDescSetLayouts (SHGraphicsPredefinedData::PredefinedDescSetLayoutTypes types) noexcept;
|
||||||
static SHVertexInputState const& GetDefaultViState (void) noexcept;
|
static SHVertexInputState const& GetDefaultViState (void) noexcept;
|
||||||
|
static SHVertexInputState const& GetShadowMapViState (void) noexcept;
|
||||||
static PerSystem const& GetSystemData (SystemType systemType) noexcept;
|
static PerSystem const& GetSystemData (SystemType systemType) noexcept;
|
||||||
static SHDescriptorMappings::MapType const& GetMappings (SystemType systemType) noexcept;
|
static SHDescriptorMappings::MapType const& GetMappings (SystemType systemType) noexcept;
|
||||||
//static PerSystem const& GetBatchingSystemData(void) noexcept;
|
//static PerSystem const& GetBatchingSystemData(void) noexcept;
|
||||||
|
|
|
@ -13,7 +13,7 @@ namespace SHADE
|
||||||
CAMERA,
|
CAMERA,
|
||||||
MATERIALS,
|
MATERIALS,
|
||||||
FONT,
|
FONT,
|
||||||
RENDER_GRAPH_RESOURCE,
|
|
||||||
RENDER_GRAPH_NODE_COMPUTE_RESOURCE,
|
RENDER_GRAPH_NODE_COMPUTE_RESOURCE,
|
||||||
|
RENDER_GRAPH_RESOURCE,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -101,7 +101,7 @@ namespace SHADE
|
||||||
// Register function for subpass
|
// Register function for subpass
|
||||||
//auto const& RENDERERS = gfxSystem->GetDefaultViewport()->GetRenderers();
|
//auto const& RENDERERS = gfxSystem->GetDefaultViewport()->GetRenderers();
|
||||||
auto renderGraph = gfxSystem->GetRenderGraph();
|
auto renderGraph = gfxSystem->GetRenderGraph();
|
||||||
auto subPass = renderGraph->GetNode("Debug Draw")->GetSubpass("Debug Draw");
|
auto subPass = renderGraph->GetNode(SHGraphicsConstants::RenderGraphEntityNames::DEBUG_DRAW.data())->GetSubpass("Debug Draw");
|
||||||
subPass->AddExteriorDrawCalls([this](Handle<SHVkCommandBuffer> cmdBuffer, Handle<SHRenderer> renderer, uint32_t frameIndex)
|
subPass->AddExteriorDrawCalls([this](Handle<SHVkCommandBuffer> cmdBuffer, Handle<SHRenderer> renderer, uint32_t frameIndex)
|
||||||
{
|
{
|
||||||
// Set line width first
|
// Set line width first
|
||||||
|
@ -129,7 +129,7 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
cmdBuffer->EndLabeledSegment();
|
cmdBuffer->EndLabeledSegment();
|
||||||
});
|
});
|
||||||
auto subPassWithDepth = renderGraph->GetNode("Debug Draw with Depth")->GetSubpass("Debug Draw with Depth");
|
auto subPassWithDepth = renderGraph->GetNode(SHGraphicsConstants::RenderGraphEntityNames::DEBUG_DRAW_DEPTH_PASS.data())->GetSubpass("Debug Draw with Depth");
|
||||||
subPassWithDepth->AddExteriorDrawCalls([this](Handle<SHVkCommandBuffer> cmdBuffer, Handle<SHRenderer> renderer, uint32_t frameIndex)
|
subPassWithDepth->AddExteriorDrawCalls([this](Handle<SHVkCommandBuffer> cmdBuffer, Handle<SHRenderer> renderer, uint32_t frameIndex)
|
||||||
{
|
{
|
||||||
// Set line width first
|
// Set line width first
|
||||||
|
|
|
@ -31,68 +31,91 @@ namespace SHADE
|
||||||
static constexpr uint32_t EDITOR = 0;
|
static constexpr uint32_t EDITOR = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
//struct DescriptorSetIndex
|
struct RenderGraphEntityNames
|
||||||
//{
|
{
|
||||||
// /***************************************************************************/
|
/***************************************************************************/
|
||||||
// /*!
|
/*!
|
||||||
// \brief
|
|
||||||
// DescriptorSet Index for static global values like generic data, and
|
|
||||||
// texture samplers
|
|
||||||
// */
|
|
||||||
// /***************************************************************************/
|
|
||||||
// static constexpr uint32_t STATIC_GLOBALS = 0;
|
|
||||||
// /***************************************************************************/
|
|
||||||
// /*!
|
|
||||||
// \brief
|
|
||||||
// DescriptorSet Index for dynamic global values like lights.
|
|
||||||
// */
|
|
||||||
// /***************************************************************************/
|
|
||||||
// static constexpr uint32_t DYNAMIC_GLOBALS = 1;
|
|
||||||
// /***************************************************************************/
|
|
||||||
// /*!
|
|
||||||
// \brief
|
|
||||||
// DescriptorSet Index for high frequency changing global values like
|
|
||||||
// camera matrices.
|
|
||||||
// */
|
|
||||||
// /***************************************************************************/
|
|
||||||
// static constexpr uint32_t HIGH_FREQUENCY_GLOBALS = 2;
|
|
||||||
// /***************************************************************************/
|
|
||||||
// /*!
|
|
||||||
// \brief
|
|
||||||
// DescriptorSet Index for per-instance/material changing values.
|
|
||||||
// */
|
|
||||||
// /***************************************************************************/
|
|
||||||
// static constexpr uint32_t PER_INSTANCE = 3;
|
|
||||||
// /***************************************************************************/
|
|
||||||
// /*!
|
|
||||||
// \brief
|
|
||||||
// DescriptorSet Index for render graph resources. Unlike the sets from
|
|
||||||
// 1 to 3 and 6, this set index does not have hard coded bindings and is
|
|
||||||
// NOT part of the layouts included in the global data.
|
|
||||||
// */
|
|
||||||
// /***************************************************************************/
|
|
||||||
// static constexpr uint32_t RENDERGRAPH_RESOURCE = 4;
|
|
||||||
// /***************************************************************************/
|
|
||||||
// /*!
|
|
||||||
// \brief
|
|
||||||
// DescriptorSet Index for render graph node compute resources. For data
|
|
||||||
// that we wish to pass to compute shaders in the render graph, this is
|
|
||||||
// the set to use. Unlike the sets from 1 to 3 and 6, this set index does not have
|
|
||||||
// hard coded bindings and is NOT part of the layouts included in the global
|
|
||||||
// data.
|
|
||||||
// */
|
|
||||||
// /***************************************************************************/
|
|
||||||
// static constexpr uint32_t RENDERGRAPH_NODE_COMPUTE_RESOURCE = 5;
|
|
||||||
|
|
||||||
// /***************************************************************************/
|
\brief
|
||||||
// /*!
|
Name of G-Buffer render graph node.
|
||||||
// \brief
|
|
||||||
// To store font data.
|
*/
|
||||||
//
|
/***************************************************************************/
|
||||||
// */
|
static constexpr std::string_view GBUFFER_PASS = "G-Buffer";
|
||||||
// /***************************************************************************/
|
|
||||||
// static constexpr uint32_t FONT_DATA = 4;
|
/***************************************************************************/
|
||||||
//};
|
/*!
|
||||||
|
|
||||||
|
\brief
|
||||||
|
Name of shadow map render graph node.
|
||||||
|
|
||||||
|
*/
|
||||||
|
/***************************************************************************/
|
||||||
|
static constexpr std::string_view SHADOW_MAP_PASS = "Shadow Map Pass";
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
/*!
|
||||||
|
|
||||||
|
\brief
|
||||||
|
Name of deferred composite render graph node.
|
||||||
|
|
||||||
|
*/
|
||||||
|
/***************************************************************************/
|
||||||
|
static constexpr std::string_view DEFERRED_COMPOSITE_PASS = "Deferred Comp Pass";
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
/*!
|
||||||
|
|
||||||
|
\brief
|
||||||
|
Name of Debug Draw with Depth render graph node.
|
||||||
|
|
||||||
|
*/
|
||||||
|
/***************************************************************************/
|
||||||
|
static constexpr std::string_view DEBUG_DRAW_DEPTH_PASS = "Debug Draw with Depth Pass";
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
/*!
|
||||||
|
|
||||||
|
\brief
|
||||||
|
Name of Debug Draw render graph node.
|
||||||
|
|
||||||
|
*/
|
||||||
|
/***************************************************************************/
|
||||||
|
static constexpr std::string_view DEBUG_DRAW = "Debug Draw Pass";
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
/*!
|
||||||
|
|
||||||
|
\brief
|
||||||
|
Name of screen space pass render graph node.
|
||||||
|
|
||||||
|
*/
|
||||||
|
/***************************************************************************/
|
||||||
|
static constexpr std::string_view SCREEN_SPACE_PASS = "Screen Space Pass";
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
/*!
|
||||||
|
|
||||||
|
\brief
|
||||||
|
Name of ImGui pass render graph node.
|
||||||
|
|
||||||
|
*/
|
||||||
|
/***************************************************************************/
|
||||||
|
static constexpr std::string_view IMGUI_PASS = "ImGui Pass";
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
/*!
|
||||||
|
|
||||||
|
\brief
|
||||||
|
Name of deferred composite compute.
|
||||||
|
|
||||||
|
*/
|
||||||
|
/***************************************************************************/
|
||||||
|
static constexpr std::string_view DEFERRED_COMPOSITE_COMPUTE = "Deferred Composite";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
struct DescriptorSetBindings
|
struct DescriptorSetBindings
|
||||||
{
|
{
|
||||||
|
@ -158,6 +181,16 @@ namespace SHADE
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
static constexpr uint32_t FONT_MATRIX_DATA = 1;
|
static constexpr uint32_t FONT_MATRIX_DATA = 1;
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
/*!
|
||||||
|
\brief
|
||||||
|
Descriptor set binding for shadow map images.
|
||||||
|
|
||||||
|
*/
|
||||||
|
/***************************************************************************/
|
||||||
|
static constexpr uint32_t SHADOW_MAP_IMAGE_SAMPLER_DATA = 0;
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct VertexBufferBindings
|
struct VertexBufferBindings
|
||||||
|
|
|
@ -44,6 +44,9 @@ of DigiPen Institute of Technology is prohibited.
|
||||||
#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"
|
#include "Graphics/MiddleEnd/GlobalData/SHGlobalDescriptorSets.h"
|
||||||
|
#include "Events/SHEvent.h"
|
||||||
|
#include "Graphics/MiddleEnd/Lights/SHLightComponent.h"
|
||||||
|
#include "Input/SHInputManager.h"
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
|
@ -124,6 +127,13 @@ namespace SHADE
|
||||||
|
|
||||||
SHFreetypeInstance::Init();
|
SHFreetypeInstance::Init();
|
||||||
|
|
||||||
|
SHAssetManager::CompileAsset("../../Assets/Shaders/DeferredComposite_CS.glsl", false);
|
||||||
|
SHAssetManager::CompileAsset("../../Assets/Shaders/SSAO_CS.glsl", false);
|
||||||
|
SHAssetManager::CompileAsset("../../Assets/Shaders/SSAOBlur_CS.glsl", false);
|
||||||
|
SHAssetManager::CompileAsset("../../Assets/Shaders/PureCopy_CS.glsl", false);
|
||||||
|
SHAssetManager::CompileAsset("../../Assets/Shaders/TestCube_VS.glsl", false);
|
||||||
|
SHAssetManager::CompileAsset("../../Assets/Shaders/TestCube_FS.glsl", false);
|
||||||
|
|
||||||
// Load Built In Shaders
|
// Load Built In Shaders
|
||||||
static constexpr AssetID VS_DEFAULT = 39210065; defaultVertShader = SHResourceManager::LoadOrGet<SHVkShaderModule>(VS_DEFAULT);
|
static constexpr AssetID VS_DEFAULT = 39210065; defaultVertShader = SHResourceManager::LoadOrGet<SHVkShaderModule>(VS_DEFAULT);
|
||||||
static constexpr AssetID FS_DEFAULT = 46377769; defaultFragShader = SHResourceManager::LoadOrGet<SHVkShaderModule>(FS_DEFAULT);
|
static constexpr AssetID FS_DEFAULT = 46377769; defaultFragShader = SHResourceManager::LoadOrGet<SHVkShaderModule>(FS_DEFAULT);
|
||||||
|
@ -137,6 +147,8 @@ namespace SHADE
|
||||||
static constexpr AssetID TEXT_FS = 38024754; textFS = SHResourceManager::LoadOrGet<SHVkShaderModule>(TEXT_FS);
|
static constexpr AssetID TEXT_FS = 38024754; textFS = SHResourceManager::LoadOrGet<SHVkShaderModule>(TEXT_FS);
|
||||||
static constexpr AssetID RENDER_SC_VS = 48082949; renderToSwapchainVS = SHResourceManager::LoadOrGet<SHVkShaderModule>(RENDER_SC_VS);
|
static constexpr AssetID RENDER_SC_VS = 48082949; renderToSwapchainVS = SHResourceManager::LoadOrGet<SHVkShaderModule>(RENDER_SC_VS);
|
||||||
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);
|
||||||
|
static constexpr AssetID SHADOW_MAP_VS = 44646107; shadowMapVS = SHResourceManager::LoadOrGet<SHVkShaderModule>(SHADOW_MAP_VS);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHGraphicsSystem::InitRenderGraph(void) noexcept
|
void SHGraphicsSystem::InitRenderGraph(void) noexcept
|
||||||
|
@ -169,6 +181,8 @@ namespace SHADE
|
||||||
// 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));
|
||||||
|
|
||||||
|
shadowMapViewport = AddViewport(vk::Viewport(0.0f, 0.0f, static_cast<float>(SHLightingSubSystem::SHADOW_MAP_WIDTH), static_cast<float>(SHLightingSubSystem::SHADOW_MAP_HEIGHT), 0.0f, 1.0f));
|
||||||
|
|
||||||
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)
|
||||||
{
|
{
|
||||||
|
@ -183,22 +197,24 @@ namespace SHADE
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
// Initialize world render graph
|
// Initialize world render graph
|
||||||
renderGraph->Init("World Render Graph", device, swapchain, &resourceManager, renderContextCmdPools);
|
renderGraph->Init("World Render Graph", device, swapchain, &resourceManager, renderContextCmdPools);
|
||||||
renderGraph->AddResource("Position", { SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR, SH_RENDER_GRAPH_RESOURCE_FLAGS::INPUT, SH_RENDER_GRAPH_RESOURCE_FLAGS::STORAGE }, windowDims.first, windowDims.second, vk::Format::eR32G32B32A32Sfloat);
|
renderGraph->AddResource("Position", { SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR, SH_RENDER_GRAPH_RESOURCE_FLAGS::INPUT, SH_RENDER_GRAPH_RESOURCE_FLAGS::STORAGE }, true, 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);
|
renderGraph->AddResource("Position World Space", { SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR, SH_RENDER_GRAPH_RESOURCE_FLAGS::INPUT, SH_RENDER_GRAPH_RESOURCE_FLAGS::STORAGE }, true, 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 }, true, 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);
|
||||||
renderGraph->AddResource("Albedo", { SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR, SH_RENDER_GRAPH_RESOURCE_FLAGS::INPUT, SH_RENDER_GRAPH_RESOURCE_FLAGS::STORAGE }, windowDims.first, windowDims.second);
|
renderGraph->AddResource("Albedo", { SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR, SH_RENDER_GRAPH_RESOURCE_FLAGS::INPUT, SH_RENDER_GRAPH_RESOURCE_FLAGS::STORAGE }, true, windowDims.first, windowDims.second);
|
||||||
renderGraph->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 }, true, windowDims.first, windowDims.second, vk::Format::eD32SfloatS8Uint);
|
||||||
renderGraph->AddResource("Entity ID", { SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR, SH_RENDER_GRAPH_RESOURCE_FLAGS::SHARED }, windowDims.first, windowDims.second, vk::Format::eR32Uint, 1, vk::ImageUsageFlagBits::eTransferSrc);
|
renderGraph->AddResource("Entity ID", { SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR, SH_RENDER_GRAPH_RESOURCE_FLAGS::SHARED }, true, windowDims.first, windowDims.second, vk::Format::eR32Uint, 1, vk::ImageUsageFlagBits::eTransferSrc);
|
||||||
renderGraph->AddResource("Light Layer Indices", { SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR, SH_RENDER_GRAPH_RESOURCE_FLAGS::INPUT, SH_RENDER_GRAPH_RESOURCE_FLAGS::STORAGE }, windowDims.first, windowDims.second, vk::Format::eR32Uint, 1, vk::ImageUsageFlagBits::eTransferSrc);
|
renderGraph->AddResource("Light Layer Indices", { SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR, SH_RENDER_GRAPH_RESOURCE_FLAGS::INPUT, SH_RENDER_GRAPH_RESOURCE_FLAGS::STORAGE }, true, windowDims.first, windowDims.second, vk::Format::eR32Uint, 1, vk::ImageUsageFlagBits::eTransferSrc);
|
||||||
renderGraph->AddResource("Scene", { SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR, SH_RENDER_GRAPH_RESOURCE_FLAGS::INPUT, SH_RENDER_GRAPH_RESOURCE_FLAGS::STORAGE, SH_RENDER_GRAPH_RESOURCE_FLAGS::SHARED }, windowDims.first, windowDims.second);
|
renderGraph->AddResource("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 }, true, windowDims.first, windowDims.second);
|
||||||
renderGraph->AddResource("SSAO", { SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR, SH_RENDER_GRAPH_RESOURCE_FLAGS::INPUT, SH_RENDER_GRAPH_RESOURCE_FLAGS::STORAGE }, windowDims.first, windowDims.second, vk::Format::eR8Unorm);
|
renderGraph->AddResource("SSAO", { SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR, SH_RENDER_GRAPH_RESOURCE_FLAGS::INPUT, SH_RENDER_GRAPH_RESOURCE_FLAGS::STORAGE }, true, 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("SSAO Blur", { SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR, SH_RENDER_GRAPH_RESOURCE_FLAGS::INPUT, SH_RENDER_GRAPH_RESOURCE_FLAGS::STORAGE }, true, windowDims.first, windowDims.second, vk::Format::eR8Unorm);
|
||||||
renderGraph->AddResource("Present", { SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR_PRESENT }, windowDims.first, windowDims.second);
|
renderGraph->AddResource("Present", { SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR_PRESENT }, true, windowDims.first, windowDims.second);
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
/* MAIN NODE */
|
/* MAIN NODE */
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
auto gBufferNode = renderGraph->AddNode("G-Buffer",
|
auto gBufferNode = renderGraph->AddNode(SHGraphicsConstants::RenderGraphEntityNames::GBUFFER_PASS.data(),
|
||||||
|
//auto gBufferNode = renderGraph->AddNode(SHGraphicsConstants::RenderGraphNodeNames::GBUFFER_PASS.data()
|
||||||
{
|
{
|
||||||
"Position",
|
"Position",
|
||||||
"Entity ID",
|
"Entity ID",
|
||||||
|
@ -207,7 +223,8 @@ namespace SHADE
|
||||||
"Albedo",
|
"Albedo",
|
||||||
"Depth Buffer",
|
"Depth Buffer",
|
||||||
"SSAO",
|
"SSAO",
|
||||||
"SSAO Blur"
|
"SSAO Blur",
|
||||||
|
"Position World Space"
|
||||||
},
|
},
|
||||||
{}); // no predecessors
|
{}); // no predecessors
|
||||||
|
|
||||||
|
@ -220,6 +237,7 @@ namespace SHADE
|
||||||
gBufferSubpass->AddColorOutput("Light Layer Indices");
|
gBufferSubpass->AddColorOutput("Light Layer Indices");
|
||||||
gBufferSubpass->AddColorOutput("Normals");
|
gBufferSubpass->AddColorOutput("Normals");
|
||||||
gBufferSubpass->AddColorOutput("Albedo");
|
gBufferSubpass->AddColorOutput("Albedo");
|
||||||
|
gBufferSubpass->AddColorOutput("Position World Space");
|
||||||
gBufferSubpass->AddDepthOutput("Depth Buffer", SH_RENDER_GRAPH_RESOURCE_FLAGS::DEPTH_STENCIL);
|
gBufferSubpass->AddDepthOutput("Depth Buffer", SH_RENDER_GRAPH_RESOURCE_FLAGS::DEPTH_STENCIL);
|
||||||
|
|
||||||
|
|
||||||
|
@ -254,53 +272,52 @@ namespace SHADE
|
||||||
// Add another pass to blur SSAO
|
// Add another pass to blur SSAO
|
||||||
Handle<SHRenderGraphNodeCompute> ssaoBlurPass = gBufferNode->AddNodeCompute("SSAO Blur Step", ssaoBlurShader, { "SSAO", "SSAO Blur" });
|
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", {}, {});
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
/* DEFERRED COMPOSITE NODE */
|
/* DEFERRED COMPOSITE NODE */
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
// This pass will facilitate both lighting and shadows in 1 single pass.
|
// This pass will facilitate both lighting and shadows in 1 single pass.
|
||||||
auto deferredCompositeNode = renderGraph->AddNode("Deferred Comp Pass",
|
auto deferredCompositeNode = renderGraph->AddNode(SHGraphicsConstants::RenderGraphEntityNames::DEFERRED_COMPOSITE_PASS.data(),
|
||||||
{
|
{
|
||||||
"Position",
|
"Position",
|
||||||
"Light Layer Indices",
|
"Light Layer Indices",
|
||||||
"Normals",
|
"Normals",
|
||||||
"Albedo",
|
"Albedo",
|
||||||
"Scene",
|
"Scene",
|
||||||
"SSAO Blur"
|
"SSAO Blur",
|
||||||
|
"Position World Space"
|
||||||
},
|
},
|
||||||
{"G-Buffer"});
|
{ SHGraphicsConstants::RenderGraphEntityNames::GBUFFER_PASS .data()});
|
||||||
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
/* DEFERRED COMPOSITE SUBPASS INIT */
|
/* DEFERRED COMPOSITE SUBPASS INIT */
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
deferredCompositeNode->AddNodeCompute("Deferred Composite", deferredCompositeShader, { "Position", "Normals", "Albedo", "Light Layer Indices", "SSAO Blur", "Scene" });
|
auto deferredCompositeCompute = deferredCompositeNode->AddNodeCompute(SHGraphicsConstants::RenderGraphEntityNames::DEFERRED_COMPOSITE_COMPUTE.data(), deferredCompositeShader, {"Position", "Normals", "Albedo", "Light Layer Indices", "SSAO Blur", "Position World Space", "Scene"}, {}, SHLightingSubSystem::MAX_SHADOWS);
|
||||||
|
deferredCompositeCompute->AddPreComputeFunction([=](Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex)
|
||||||
|
{
|
||||||
|
lightingSubSystem->PrepareShadowMapsForRead(cmdBuffer);
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
/* DEBUG DRAW PASS INIT */
|
/* DEBUG DRAW PASS INIT */
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
// Set up Debug Draw Passes
|
// Set up Debug Draw Passes
|
||||||
// - Depth Tested
|
// - Depth Tested
|
||||||
auto debugDrawNodeDepth = renderGraph->AddNode("Debug Draw with Depth", { "Scene", "Depth Buffer" }, {"G-Buffer", "Deferred Comp Pass"});
|
auto debugDrawNodeDepth = renderGraph->AddNode(SHGraphicsConstants::RenderGraphEntityNames::DEBUG_DRAW_DEPTH_PASS.data(), {"Scene", "Depth Buffer"}, {SHGraphicsConstants::RenderGraphEntityNames::GBUFFER_PASS.data(), SHGraphicsConstants::RenderGraphEntityNames::DEFERRED_COMPOSITE_PASS.data()});
|
||||||
auto debugDrawDepthSubpass = debugDrawNodeDepth->AddSubpass("Debug Draw with Depth", worldViewport, worldRenderer);
|
auto debugDrawDepthSubpass = debugDrawNodeDepth->AddSubpass("Debug Draw with Depth", worldViewport, worldRenderer);
|
||||||
debugDrawDepthSubpass->AddColorOutput("Scene");
|
debugDrawDepthSubpass->AddColorOutput("Scene");
|
||||||
debugDrawDepthSubpass->AddDepthOutput("Depth Buffer");
|
debugDrawDepthSubpass->AddDepthOutput("Depth Buffer");
|
||||||
// - No Depth Test
|
// - No Depth Test
|
||||||
auto debugDrawNode = renderGraph->AddNode("Debug Draw", { "Scene" }, { "Debug Draw with Depth" });
|
auto debugDrawNode = renderGraph->AddNode(SHGraphicsConstants::RenderGraphEntityNames::DEBUG_DRAW.data(), {"Scene"}, {SHGraphicsConstants::RenderGraphEntityNames::DEBUG_DRAW_DEPTH_PASS.data()});
|
||||||
auto debugDrawSubpass = debugDrawNode->AddSubpass("Debug Draw", worldViewport, worldRenderer);
|
auto debugDrawSubpass = debugDrawNode->AddSubpass("Debug Draw", worldViewport, worldRenderer);
|
||||||
debugDrawSubpass->AddColorOutput("Scene");
|
debugDrawSubpass->AddColorOutput("Scene");
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
/* SCREEN SPACE PASS */
|
/* SCREEN SPACE PASS */
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
auto screenSpaceNode = renderGraph->AddNode("Screen Space Pass", { "Scene", "Entity ID" }, {"Deferred Comp Pass", "G-Buffer", "Debug Draw" });
|
auto screenSpaceNode = renderGraph->AddNode(SHGraphicsConstants::RenderGraphEntityNames::SCREEN_SPACE_PASS.data(), {"Scene", "Entity ID"}, {SHGraphicsConstants::RenderGraphEntityNames::DEFERRED_COMPOSITE_PASS.data(), SHGraphicsConstants::RenderGraphEntityNames::GBUFFER_PASS.data(), SHGraphicsConstants::RenderGraphEntityNames::DEBUG_DRAW.data()});
|
||||||
auto uiSubpass = screenSpaceNode->AddSubpass("UI", worldViewport, screenRenderer);
|
auto uiSubpass = screenSpaceNode->AddSubpass("UI", worldViewport, screenRenderer);
|
||||||
uiSubpass->AddColorOutput("Scene");
|
uiSubpass->AddColorOutput("Scene");
|
||||||
uiSubpass->AddColorOutput("Entity ID");
|
uiSubpass->AddColorOutput("Entity ID");
|
||||||
|
@ -315,16 +332,16 @@ namespace SHADE
|
||||||
#ifdef SHEDITOR
|
#ifdef SHEDITOR
|
||||||
{
|
{
|
||||||
// Dummy Node to transition scene render graph resource
|
// Dummy Node to transition scene render graph resource
|
||||||
auto dummyNode = renderGraph->AddNode("Dummy Pass", { "Scene" }, { "Screen Space Pass" });
|
auto dummyNode = renderGraph->AddNode("Dummy Pass", { "Scene" }, { SHGraphicsConstants::RenderGraphEntityNames::SCREEN_SPACE_PASS .data()});
|
||||||
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 imGuiNode = renderGraph->AddNode(SHGraphicsConstants::RenderGraphEntityNames::IMGUI_PASS.data(), {"Present"}, {});
|
||||||
auto imGuiSubpass = imGuiNode->AddSubpass("ImGui Draw", {}, {});
|
auto imGuiSubpass = imGuiNode->AddSubpass("ImGui Draw", {}, {});
|
||||||
imGuiSubpass->AddColorOutput("Present");
|
imGuiSubpass->AddColorOutput("Present");
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
renderGraph->AddRenderToSwapchainNode("Scene", "Present", { "Screen Space Pass" }, { renderToSwapchainVS, renderToSwapchainFS });
|
renderGraph->AddRenderToSwapchainNode("Scene", "Present", { SHGraphicsConstants::RenderGraphEntityNames::SCREEN_SPACE_PASS .data()}, {renderToSwapchainVS, renderToSwapchainFS});
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
@ -393,12 +410,16 @@ namespace SHADE
|
||||||
postOffscreenRenderSubSystem->Init(device, renderGraph->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, &resourceManager, samplerCache.GetSampler (device, SHVkSamplerParams
|
||||||
|
{
|
||||||
|
.addressMode = vk::SamplerAddressMode::eClampToBorder,
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
textRenderingSubSystem = resourceManager.Create<SHTextRenderingSubSystem>();
|
textRenderingSubSystem = resourceManager.Create<SHTextRenderingSubSystem>();
|
||||||
|
|
||||||
// initialize the text renderer
|
// initialize the text renderer
|
||||||
auto uiNode = renderGraph->GetNode("Screen Space Pass");
|
auto uiNode = renderGraph->GetNode(SHGraphicsConstants::RenderGraphEntityNames::SCREEN_SPACE_PASS.data());
|
||||||
textRenderingSubSystem->Init(device, uiNode->GetRenderpass(), uiNode->GetSubpass("UI"), descPool, textVS, textFS);
|
textRenderingSubSystem->Init(device, uiNode->GetRenderpass(), uiNode->GetSubpass("UI"), descPool, textVS, textFS);
|
||||||
|
|
||||||
SHGlobalDescriptorSets::SetLightingSubSystem(lightingSubSystem);
|
SHGlobalDescriptorSets::SetLightingSubSystem(lightingSubSystem);
|
||||||
|
@ -426,7 +447,7 @@ namespace SHADE
|
||||||
defaultMaterial = AddMaterial
|
defaultMaterial = AddMaterial
|
||||||
(
|
(
|
||||||
defaultVertShader, defaultFragShader,
|
defaultVertShader, defaultFragShader,
|
||||||
renderGraph->GetNode("G-Buffer")->GetSubpass("G-Buffer Write")
|
renderGraph->GetNode(SHGraphicsConstants::RenderGraphEntityNames::GBUFFER_PASS.data())->GetSubpass("G-Buffer Write")
|
||||||
);
|
);
|
||||||
defaultMaterial->SetProperty("data.textureIndex", defaultTexture->TextureArrayIndex);
|
defaultMaterial->SetProperty("data.textureIndex", defaultTexture->TextureArrayIndex);
|
||||||
}
|
}
|
||||||
|
@ -451,6 +472,7 @@ namespace SHADE
|
||||||
InitMiddleEnd();
|
InitMiddleEnd();
|
||||||
InitSubsystems();
|
InitSubsystems();
|
||||||
InitBuiltInResources();
|
InitBuiltInResources();
|
||||||
|
InitEvents();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHGraphicsSystem::Exit(void)
|
void SHGraphicsSystem::Exit(void)
|
||||||
|
@ -546,6 +568,15 @@ namespace SHADE
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (SHInputManager::GetKeyDown(SHInputManager::SH_KEYCODE::B))
|
||||||
|
{
|
||||||
|
auto& lightComps = SHComponentManager::GetDense<SHLightComponent>();
|
||||||
|
for (auto& comp : lightComps)
|
||||||
|
{
|
||||||
|
comp.SetEnableShadow(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
renderGraph->Begin(frameIndex);
|
renderGraph->Begin(frameIndex);
|
||||||
auto cmdBuffer = renderGraph->GetCommandBuffer(frameIndex);
|
auto cmdBuffer = renderGraph->GetCommandBuffer(frameIndex);
|
||||||
|
|
||||||
|
@ -726,16 +757,61 @@ namespace SHADE
|
||||||
renderers.erase(iter);
|
renderers.erase(iter);
|
||||||
}
|
}
|
||||||
|
|
||||||
SHEventHandle SHGraphicsSystem::ReceiveLightEnableShadowEvent(SHEventPtr event) noexcept
|
SHEventHandle SHGraphicsSystem::ReceiveLightEnableShadowEvent(SHEventPtr eventPtr) noexcept
|
||||||
{
|
{
|
||||||
|
// we need to wait for the device to finish using the graph first
|
||||||
|
device->WaitIdle();
|
||||||
|
|
||||||
|
auto const& EVENT_DATA = reinterpret_cast<const SHEventSpec<SHLightEnableShadowEvent>*>(eventPtr.get())->data;
|
||||||
|
auto* lightComp = SHComponentManager::GetComponent<SHLightComponent>(EVENT_DATA->lightEntity);
|
||||||
|
std::string resourceName = "ShadowMap " + std::to_string(EVENT_DATA->lightEntity);
|
||||||
|
Handle<SHSubpass> companionSubpass = renderGraph->GetNode(SHGraphicsConstants::RenderGraphEntityNames::GBUFFER_PASS.data())->GetSubpass("G-Buffer Write");
|
||||||
|
|
||||||
|
if (EVENT_DATA->generateRenderer)
|
||||||
|
{
|
||||||
|
// Create new renderer for the light component and give it to the light component
|
||||||
|
Handle<SHRenderer> newRenderer = resourceManager.Create<SHRenderer>(device, swapchain->GetNumImages(), descPool, SHRenderer::PROJECTION_TYPE::ORTHOGRAPHIC);
|
||||||
|
lightComp->SetRenderer (newRenderer);
|
||||||
|
|
||||||
|
// assign shadow map index to light component
|
||||||
|
lightComp->SetShadowMapIndex (lightingSubSystem->GetNumShadowMaps());
|
||||||
|
}
|
||||||
|
|
||||||
// Add the shadow map resource to the graph
|
// Add the shadow map resource to the graph
|
||||||
|
renderGraph->AddResource(resourceName, {SH_RENDER_GRAPH_RESOURCE_FLAGS::DEPTH, SH_RENDER_GRAPH_RESOURCE_FLAGS::INPUT}, false, SHLightingSubSystem::SHADOW_MAP_WIDTH, SHLightingSubSystem::SHADOW_MAP_HEIGHT, vk::Format::eD32Sfloat);
|
||||||
|
|
||||||
// link resource to node. This means linking the resource and regenerating the node's renderpass and framebuffer.
|
// link resource to node. This means linking the resource and regenerating the node's renderpass and framebuffer.
|
||||||
|
auto shadowMapNode = renderGraph->AddNodeAfter(SHGraphicsConstants::RenderGraphEntityNames::SHADOW_MAP_PASS.data() + resourceName, {resourceName.c_str()}, SHGraphicsConstants::RenderGraphEntityNames::GBUFFER_PASS.data());
|
||||||
|
|
||||||
// Add a subpass to render to that shadow map
|
// Add a subpass to render to that shadow map
|
||||||
|
auto newSubpass = shadowMapNode->RuntimeAddSubpass(resourceName + " Subpass", shadowMapViewport, lightComp->GetRenderer());
|
||||||
|
newSubpass->AddDepthOutput(resourceName, SH_RENDER_GRAPH_RESOURCE_FLAGS::DEPTH);
|
||||||
|
|
||||||
//renderGraph->GetNode ();
|
// regenerate the node
|
||||||
return event->handle;
|
shadowMapNode->RuntimeStandaloneRegenerate();
|
||||||
|
|
||||||
|
// Create pipeline from new renderpass and subpass if it's not created yet
|
||||||
|
if (!shadowMapPipeline)
|
||||||
|
{
|
||||||
|
SHPipelineLibrary tempLibrary{};
|
||||||
|
Handle<SHRenderGraphNode> rgNode = renderGraph->GetNode(SHGraphicsConstants::RenderGraphEntityNames::SHADOW_MAP_PASS.data());
|
||||||
|
|
||||||
|
SHRasterizationState rasterState{};
|
||||||
|
rasterState.cull_mode = vk::CullModeFlagBits::eBack;
|
||||||
|
|
||||||
|
tempLibrary.Init(device);
|
||||||
|
tempLibrary.CreateGraphicsPipelines({ shadowMapVS, {} }, shadowMapNode->GetRenderpass(), newSubpass, SHGraphicsPredefinedData::GetShadowMapViState(), rasterState);
|
||||||
|
shadowMapPipeline = tempLibrary.GetGraphicsPipeline({ shadowMapVS, {} });
|
||||||
|
}
|
||||||
|
newSubpass->SetCompanionSubpass(companionSubpass, shadowMapPipeline); // set companion subpass and pipeline
|
||||||
|
|
||||||
|
// add the shadow map to the lighting system
|
||||||
|
uint32_t const NEW_SHADOW_MAP_INDEX = lightingSubSystem->AddShadowMap(renderGraph->GetRenderGraphResource(resourceName), EVENT_DATA->lightEntity);
|
||||||
|
|
||||||
|
auto nodeCompute = renderGraph->GetNode(SHGraphicsConstants::RenderGraphEntityNames::DEFERRED_COMPOSITE_PASS.data())->GetNodeCompute(SHGraphicsConstants::RenderGraphEntityNames::DEFERRED_COMPOSITE_COMPUTE.data());
|
||||||
|
nodeCompute->ModifyWriteDescImageComputeResource(SHGraphicsConstants::DescriptorSetBindings::SHADOW_MAP_IMAGE_SAMPLER_DATA, lightingSubSystem->GetViewSamplerLayout(NEW_SHADOW_MAP_INDEX), NEW_SHADOW_MAP_INDEX);
|
||||||
|
|
||||||
|
return eventPtr->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)
|
||||||
|
@ -1047,6 +1123,7 @@ namespace SHADE
|
||||||
|
|
||||||
mousePickSubSystem->HandleResize();
|
mousePickSubSystem->HandleResize();
|
||||||
postOffscreenRenderSubSystem->HandleResize();
|
postOffscreenRenderSubSystem->HandleResize();
|
||||||
|
//lightingSubSystem->HandleResize(renderGraph->GetNode(SHGraphicsConstants::RenderGraphEntityNames::DEFERRED_COMPOSITE_PASS.data())->GetNodeCompute(SHGraphicsConstants::RenderGraphEntityNames::DEFERRED_COMPOSITE_COMPUTE.data()));
|
||||||
|
|
||||||
worldViewport->SetWidth(static_cast<float>(resizeWidth));
|
worldViewport->SetWidth(static_cast<float>(resizeWidth));
|
||||||
worldViewport->SetHeight(static_cast<float>(resizeHeight));
|
worldViewport->SetHeight(static_cast<float>(resizeHeight));
|
||||||
|
@ -1079,7 +1156,7 @@ namespace SHADE
|
||||||
|
|
||||||
Handle<SHRenderGraphNode> SHGraphicsSystem::GetPrimaryRenderpass() const noexcept
|
Handle<SHRenderGraphNode> SHGraphicsSystem::GetPrimaryRenderpass() const noexcept
|
||||||
{
|
{
|
||||||
return renderGraph->GetNode(G_BUFFER_RENDER_GRAPH_NODE_NAME.data());
|
return renderGraph->GetNode(SHGraphicsConstants::RenderGraphEntityNames::GBUFFER_PASS.data());
|
||||||
}
|
}
|
||||||
|
|
||||||
Handle<SHVkPipeline> SHGraphicsSystem::GetDebugDrawPipeline(DebugDrawPipelineType type) const noexcept
|
Handle<SHVkPipeline> SHGraphicsSystem::GetDebugDrawPipeline(DebugDrawPipelineType type) const noexcept
|
||||||
|
|
|
@ -178,7 +178,7 @@ namespace SHADE
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
/* Light functions */
|
/* Light functions */
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
SHEventHandle ReceiveLightEnableShadowEvent (SHEventPtr event) noexcept;
|
SHEventHandle ReceiveLightEnableShadowEvent (SHEventPtr eventPtr) noexcept;
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------*/
|
||||||
/* Material Functions */
|
/* Material Functions */
|
||||||
|
@ -406,10 +406,6 @@ namespace SHADE
|
||||||
SHWindow* GetWindow() noexcept { return window; }
|
SHWindow* GetWindow() noexcept { return window; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/*-----------------------------------------------------------------------------*/
|
|
||||||
/* Constants */
|
|
||||||
/*-----------------------------------------------------------------------------*/
|
|
||||||
static constexpr std::string_view G_BUFFER_RENDER_GRAPH_NODE_NAME = "G-Buffer";
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------*/
|
||||||
/* Data Members */
|
/* Data Members */
|
||||||
|
@ -446,6 +442,7 @@ namespace SHADE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
Handle<SHViewport> worldViewport; // Whole screen
|
Handle<SHViewport> worldViewport; // Whole screen
|
||||||
|
Handle<SHViewport> shadowMapViewport;
|
||||||
std::vector<Handle<SHViewport>> viewports; // Additional viewports
|
std::vector<Handle<SHViewport>> viewports; // Additional viewports
|
||||||
|
|
||||||
// Renderers
|
// Renderers
|
||||||
|
@ -469,6 +466,7 @@ namespace SHADE
|
||||||
Handle<SHVkShaderModule> textFS;
|
Handle<SHVkShaderModule> textFS;
|
||||||
Handle<SHVkShaderModule> renderToSwapchainVS;
|
Handle<SHVkShaderModule> renderToSwapchainVS;
|
||||||
Handle<SHVkShaderModule> renderToSwapchainFS;
|
Handle<SHVkShaderModule> renderToSwapchainFS;
|
||||||
|
Handle<SHVkShaderModule> shadowMapVS;
|
||||||
|
|
||||||
// Fonts
|
// Fonts
|
||||||
Handle<SHFont> testFont;
|
Handle<SHFont> testFont;
|
||||||
|
@ -483,6 +481,7 @@ namespace SHADE
|
||||||
Handle<SHVkPipeline> debugDrawWireMeshDepthPipeline;
|
Handle<SHVkPipeline> debugDrawWireMeshDepthPipeline;
|
||||||
Handle<SHVkPipeline> debugDrawFilledPipeline;
|
Handle<SHVkPipeline> debugDrawFilledPipeline;
|
||||||
Handle<SHVkPipeline> debugDrawFilledDepthPipeline;
|
Handle<SHVkPipeline> debugDrawFilledDepthPipeline;
|
||||||
|
Handle<SHVkPipeline> shadowMapPipeline; // initialized only when a shadow map is needed
|
||||||
|
|
||||||
// Built-In Textures
|
// Built-In Textures
|
||||||
Handle<SHTexture> defaultTexture;
|
Handle<SHTexture> defaultTexture;
|
||||||
|
|
|
@ -122,4 +122,9 @@ namespace SHADE
|
||||||
return cameraDirector;
|
return cameraDirector;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SHShaderCameraData SHRenderer::GetCPUCameraData(void) const noexcept
|
||||||
|
{
|
||||||
|
return cpuCameraData;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,9 +18,9 @@ of DigiPen Institute of Technology is prohibited.
|
||||||
// Project Includes
|
// Project Includes
|
||||||
#include "SHCamera.h"
|
#include "SHCamera.h"
|
||||||
#include "Resource/SHHandle.h"
|
#include "Resource/SHHandle.h"
|
||||||
#include "Graphics/RenderGraph/SHRenderGraph.h"
|
|
||||||
#include "Math/SHMath.h"
|
#include "Math/SHMath.h"
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include "Graphics/Pipeline/SHPipelineType.h"
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
|
@ -93,6 +93,7 @@ namespace SHADE
|
||||||
/* Setters and Getters */
|
/* Setters and Getters */
|
||||||
/*-----------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------*/
|
||||||
Handle<SHCameraDirector> GetCameraDirector (void) const noexcept;
|
Handle<SHCameraDirector> GetCameraDirector (void) const noexcept;
|
||||||
|
SHShaderCameraData GetCPUCameraData (void) const noexcept;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/*-----------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------*/
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
#include "SHLightComponent.h"
|
#include "SHLightComponent.h"
|
||||||
#include "Graphics/Events/SHGraphicsEvents.h"
|
#include "Graphics/Events/SHGraphicsEvents.h"
|
||||||
#include "Events/SHEventManager.hpp"
|
#include "Events/SHEventManager.hpp"
|
||||||
|
#include "Graphics/MiddleEnd/Interface/SHRenderer.h"
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
|
@ -14,6 +15,7 @@ namespace SHADE
|
||||||
//indexInBuffer = std::numeric_limits<uint32_t>::max();
|
//indexInBuffer = std::numeric_limits<uint32_t>::max();
|
||||||
isActive = true;
|
isActive = true;
|
||||||
//Unbind();
|
//Unbind();
|
||||||
|
renderer = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -116,11 +118,22 @@ namespace SHADE
|
||||||
// Create new event and broadcast it
|
// Create new event and broadcast it
|
||||||
SHLightEnableShadowEvent newEvent;
|
SHLightEnableShadowEvent newEvent;
|
||||||
newEvent.lightEntity = GetEID();
|
newEvent.lightEntity = GetEID();
|
||||||
|
newEvent.generateRenderer = static_cast<bool>(!renderer);
|
||||||
|
|
||||||
SHEventManager::BroadcastEvent<SHLightEnableShadowEvent>(newEvent, SH_GRAPHICS_LIGHT_ENABLE_SHADOW_EVENT);
|
SHEventManager::BroadcastEvent<SHLightEnableShadowEvent>(newEvent, SH_GRAPHICS_LIGHT_ENABLE_SHADOW_EVENT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SHLightComponent::SetRenderer(Handle<SHRenderer> newRenderer) noexcept
|
||||||
|
{
|
||||||
|
renderer = newRenderer;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHLightComponent::SetShadowMapIndex(uint32_t index) noexcept
|
||||||
|
{
|
||||||
|
lightData.shadowMapIndex = index;
|
||||||
|
}
|
||||||
|
|
||||||
SHLightData const& SHLightComponent::GetLightData(void) const noexcept
|
SHLightData const& SHLightComponent::GetLightData(void) const noexcept
|
||||||
{
|
{
|
||||||
return lightData;
|
return lightData;
|
||||||
|
@ -172,6 +185,11 @@ namespace SHADE
|
||||||
return lightData.strength;
|
return lightData.strength;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Handle<SHRenderer> SHLightComponent::GetRenderer(void) const noexcept
|
||||||
|
{
|
||||||
|
return renderer;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
RTTR_REGISTRATION
|
RTTR_REGISTRATION
|
||||||
|
|
|
@ -3,9 +3,11 @@
|
||||||
#include <rttr/registration>
|
#include <rttr/registration>
|
||||||
#include "ECS_Base/Components/SHComponent.h"
|
#include "ECS_Base/Components/SHComponent.h"
|
||||||
#include "SHLightData.h"
|
#include "SHLightData.h"
|
||||||
|
#include "Resource/SHHandle.h"
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
|
class SHRenderer;
|
||||||
|
|
||||||
class SH_API SHLightComponent final : public SHComponent
|
class SH_API SHLightComponent final : public SHComponent
|
||||||
{
|
{
|
||||||
|
@ -14,6 +16,9 @@ namespace SHADE
|
||||||
//! GPU depends on the type of the light.
|
//! GPU depends on the type of the light.
|
||||||
SHLightData lightData;
|
SHLightData lightData;
|
||||||
|
|
||||||
|
//! Renderer to calculate light world to projection matrix
|
||||||
|
Handle<SHRenderer> renderer;
|
||||||
|
|
||||||
//! Since the lighting system is gonna be self contained and light weight, we store this
|
//! Since the lighting system is gonna be self contained and light weight, we store this
|
||||||
//! so that we only write this to the CPU buffer when this light component change, we don't
|
//! so that we only write this to the CPU buffer when this light component change, we don't
|
||||||
//! rewrite everything. However we still write to the GPU buffer when everything changes.
|
//! rewrite everything. However we still write to the GPU buffer when everything changes.
|
||||||
|
@ -49,6 +54,8 @@ namespace SHADE
|
||||||
//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;
|
void SetEnableShadow (bool flag) noexcept;
|
||||||
|
void SetRenderer (Handle<SHRenderer> newRenderer) noexcept;
|
||||||
|
void SetShadowMapIndex (uint32_t index) noexcept;
|
||||||
|
|
||||||
|
|
||||||
SHLightData const& GetLightData (void) const noexcept;
|
SHLightData const& GetLightData (void) const noexcept;
|
||||||
|
@ -61,6 +68,7 @@ namespace SHADE
|
||||||
//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;
|
||||||
|
Handle<SHRenderer> GetRenderer (void) const noexcept;
|
||||||
RTTR_ENABLE()
|
RTTR_ENABLE()
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,6 +10,13 @@
|
||||||
#include "SHLightComponent.h"
|
#include "SHLightComponent.h"
|
||||||
#include "Math/Vector/SHVec4.h"
|
#include "Math/Vector/SHVec4.h"
|
||||||
#include "Math/SHMatrix.h"
|
#include "Math/SHMatrix.h"
|
||||||
|
#include "Graphics/Images/SHVkImageView.h"
|
||||||
|
#include "Graphics/MiddleEnd/Textures/SHVkSamplerCache.h"
|
||||||
|
#include "Graphics/Images/SHVkSampler.h"
|
||||||
|
#include "Graphics/Events/SHGraphicsEvents.h"
|
||||||
|
#include "Graphics/MiddleEnd/Interface/SHRenderer.h"
|
||||||
|
#include "Math/Transform/SHTransformComponent.h"
|
||||||
|
#include "Graphics/RenderGraph/SHRenderGraphNodeCompute.h"
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
|
@ -50,6 +57,19 @@ namespace SHADE
|
||||||
//lightPtr->direction = lightData.direction;
|
//lightPtr->direction = lightData.direction;
|
||||||
lightPtr->diffuseColor = lightData.color;
|
lightPtr->diffuseColor = lightData.color;
|
||||||
lightPtr->active = lightComp->isActive;
|
lightPtr->active = lightComp->isActive;
|
||||||
|
|
||||||
|
// write view projection matrix if renderer is available
|
||||||
|
auto lightRenderer = lightComp->GetRenderer();
|
||||||
|
if (lightRenderer)
|
||||||
|
{
|
||||||
|
lightPtr->pvMatrix = lightRenderer->GetCPUCameraData().viewProjectionMatrix;
|
||||||
|
|
||||||
|
// Boolean to cast shadows in first 8 bits (1 byte)
|
||||||
|
lightPtr->shadowData = lightData.castShadows;
|
||||||
|
|
||||||
|
// Next 24 bits for shadow map index
|
||||||
|
lightPtr->shadowData |= (lightData.shadowMapIndex << 8);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SH_LIGHT_TYPE::POINT:
|
case SH_LIGHT_TYPE::POINT:
|
||||||
|
@ -365,6 +385,32 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SHLightingSubSystem::UpdateShadowMapDesc(void) noexcept
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
SHMatrix SHLightingSubSystem::GetViewMatrix(SHLightComponent* lightComp) noexcept
|
||||||
|
{
|
||||||
|
switch (lightComp->GetLightData().type)
|
||||||
|
{
|
||||||
|
case SH_LIGHT_TYPE::DIRECTIONAL:
|
||||||
|
return SHMatrix::Transpose(SHMatrix::LookAtLH(lightComp->GetLightData().position, SHVec3::Normalise (lightComp->GetLightData().direction), SHVec3(0.0f, -1.0f, 0.0f)));
|
||||||
|
//return SHMatrix::Transpose(SHMatrix::LookAtLH(/*lightComp->GetLightData().position*/SHVec3(1.27862f, 4.78952f, 4.12811f), SHVec3(-0.280564f, -0.66262f, -0.69422f), SHVec3(0.0f, -1.0f, 0.0f)));
|
||||||
|
case SH_LIGHT_TYPE::POINT:
|
||||||
|
return {};
|
||||||
|
case SH_LIGHT_TYPE::SPOT:
|
||||||
|
return {};
|
||||||
|
case SH_LIGHT_TYPE::AMBIENT:
|
||||||
|
return {};
|
||||||
|
case SH_LIGHT_TYPE::NUM_TYPES:
|
||||||
|
return {};
|
||||||
|
default:
|
||||||
|
return {};
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
/*!
|
/*!
|
||||||
|
|
||||||
|
@ -375,13 +421,15 @@ namespace SHADE
|
||||||
|
|
||||||
*/
|
*/
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
void SHLightingSubSystem::Init(Handle<SHVkLogicalDevice> device, Handle<SHVkDescriptorPool> descPool) noexcept
|
void SHLightingSubSystem::Init(Handle<SHVkLogicalDevice> device, Handle<SHVkDescriptorPool> descPool, SHResourceHub* rh, Handle<SHVkSampler> inShadowMapSampler) noexcept
|
||||||
{
|
{
|
||||||
SHComponentManager::CreateComponentSparseSet<SHLightComponent>();
|
SHComponentManager::CreateComponentSparseSet<SHLightComponent>();
|
||||||
|
|
||||||
logicalDevice = device;
|
logicalDevice = device;
|
||||||
|
resourceHub = rh;
|
||||||
uint32_t constexpr NUM_LIGHT_TYPES = SHUtilities::ConvertEnum(SH_LIGHT_TYPE::NUM_TYPES);
|
uint32_t constexpr NUM_LIGHT_TYPES = SHUtilities::ConvertEnum(SH_LIGHT_TYPE::NUM_TYPES);
|
||||||
|
|
||||||
|
#pragma region LIGHTING
|
||||||
std::vector<uint32_t> variableSizes{ NUM_LIGHT_TYPES };
|
std::vector<uint32_t> variableSizes{ NUM_LIGHT_TYPES };
|
||||||
std::fill (variableSizes.begin(), variableSizes.end(), 1);
|
std::fill (variableSizes.begin(), variableSizes.end(), 1);
|
||||||
|
|
||||||
|
@ -418,7 +466,22 @@ namespace SHADE
|
||||||
dynamicOffsets[i].resize(NUM_LIGHT_TYPES + 1); // +1 for the count
|
dynamicOffsets[i].resize(NUM_LIGHT_TYPES + 1); // +1 for the count
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#pragma endregion
|
||||||
|
|
||||||
|
#pragma region SHADOWS
|
||||||
|
//std::vector<uint32_t> shadowDescVariableSizes{ MAX_SHADOWS };
|
||||||
|
//shadowMapDescriptorSet = descPool->Allocate({SHGraphicsPredefinedData::GetPredefinedDescSetLayouts(SHGraphicsPredefinedData::PredefinedDescSetLayoutTypes::SHADOW)}, shadowDescVariableSizes);
|
||||||
|
|
||||||
|
//#ifdef _DEBUG
|
||||||
|
// const auto& SHADOW_MAP_DESC_SETS = shadowMapDescriptorSet->GetVkHandle();
|
||||||
|
// for (int i = 0; i < static_cast<int>(SHADOW_MAP_DESC_SETS.size()); ++i)
|
||||||
|
// SET_VK_OBJ_NAME(logicalDevice, vk::ObjectType::eDescriptorSet, SHADOW_MAP_DESC_SETS[i], "[Descriptor Set] Shadow Map Data Frame #" + std::to_string(i));
|
||||||
|
//#endif
|
||||||
|
|
||||||
|
shadowMapSampler = inShadowMapSampler;
|
||||||
|
shadowMaps.clear();
|
||||||
//numLightComponents = 0;
|
//numLightComponents = 0;
|
||||||
|
#pragma endregion
|
||||||
}
|
}
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
|
@ -452,6 +515,12 @@ namespace SHADE
|
||||||
|
|
||||||
for (auto& light : lightComps)
|
for (auto& light : lightComps)
|
||||||
{
|
{
|
||||||
|
if (auto renderer = light.GetRenderer())
|
||||||
|
{
|
||||||
|
//SHMatrix orthoMatrix = SHMatrix::OrthographicRH()
|
||||||
|
renderer->UpdateDataManual(frameIndex, GetViewMatrix(&light), SHMatrix::OrthographicLH(10.0f, 10.0f, 1.0f, 50.0f));
|
||||||
|
}
|
||||||
|
|
||||||
auto enumValue = SHUtilities::ConvertEnum(light.GetLightData().type);
|
auto enumValue = SHUtilities::ConvertEnum(light.GetLightData().type);
|
||||||
|
|
||||||
// First we want to make sure the light is already bound to the system. if it
|
// First we want to make sure the light is already bound to the system. if it
|
||||||
|
@ -503,7 +572,6 @@ namespace SHADE
|
||||||
// so we do it anyway. #NoteToSelf: if at any point it affects performance, do a check before computing.
|
// so we do it anyway. #NoteToSelf: if at any point it affects performance, do a check before computing.
|
||||||
ComputeDynamicOffsets();
|
ComputeDynamicOffsets();
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
|
@ -526,9 +594,101 @@ namespace SHADE
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t SHLightingSubSystem::AddShadowMap(Handle<SHRenderGraphResource> newShadowMap, EntityID lightEntity) noexcept
|
||||||
|
{
|
||||||
|
// Add to container of shadow maps
|
||||||
|
shadowMapIndexing.emplace(lightEntity, static_cast<uint32_t> (shadowMaps.size()));
|
||||||
|
shadowMaps.emplace_back(newShadowMap);
|
||||||
|
|
||||||
|
// Just use the image view stored in the resource
|
||||||
|
Handle<SHVkImageView> const NEW_IMAGE_VIEW = newShadowMap->GetImageView();
|
||||||
|
|
||||||
|
// Prepare to write to descriptor
|
||||||
|
shadowMapImageSamplers.emplace_back(NEW_IMAGE_VIEW, shadowMapSampler, vk::ImageLayout::eShaderReadOnlyOptimal);
|
||||||
|
|
||||||
|
// Update descriptor set
|
||||||
|
//static constexpr uint32_t SHADOW_MAP_DESC_SET_INDEX = 0;
|
||||||
|
//uint32_t const SHADOW_MAP_DESC_ARRAY_INDEX = static_cast<uint32_t>(shadowMapImageSamplers.size()) - 1u;
|
||||||
|
//shadowMapDescriptorSet->ModifyWriteDescImage
|
||||||
|
//(
|
||||||
|
// SHADOW_MAP_DESC_SET_INDEX,
|
||||||
|
// SHGraphicsConstants::DescriptorSetBindings::SHADOW_MAP_IMAGE_SAMPLER_DATA,
|
||||||
|
// shadowMapImageSamplers[SHADOW_MAP_DESC_ARRAY_INDEX],
|
||||||
|
// SHADOW_MAP_DESC_ARRAY_INDEX
|
||||||
|
//);
|
||||||
|
|
||||||
|
//// TODO: Definitely can be optimized by writing a function that modifies a specific descriptor in the array
|
||||||
|
//shadowMapDescriptorSet->UpdateDescriptorSetImages
|
||||||
|
//(
|
||||||
|
// SHADOW_MAP_DESC_SET_INDEX,
|
||||||
|
// SHGraphicsConstants::DescriptorSetBindings::SHADOW_MAP_IMAGE_SAMPLER_DATA
|
||||||
|
//);
|
||||||
|
|
||||||
|
// add to barriers
|
||||||
|
shadowMapMemoryBarriers.push_back (vk::ImageMemoryBarrier
|
||||||
|
{
|
||||||
|
.srcAccessMask = vk::AccessFlagBits::eDepthStencilAttachmentWrite,
|
||||||
|
.dstAccessMask = vk::AccessFlagBits::eShaderRead,
|
||||||
|
.oldLayout = vk::ImageLayout::eDepthAttachmentOptimal,
|
||||||
|
.newLayout = vk::ImageLayout::eShaderReadOnlyOptimal,
|
||||||
|
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
||||||
|
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
||||||
|
.image = newShadowMap->GetImage()->GetVkImage(),
|
||||||
|
.subresourceRange = vk::ImageSubresourceRange
|
||||||
|
{
|
||||||
|
.aspectMask = vk::ImageAspectFlagBits::eDepth,
|
||||||
|
.baseMipLevel = 0,
|
||||||
|
.levelCount = 1,
|
||||||
|
.baseArrayLayer = 0,
|
||||||
|
.layerCount = 1,
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// return new index of shadow map
|
||||||
|
return static_cast<uint32_t>(shadowMapImageSamplers.size()) - 1u;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHLightingSubSystem::PrepareShadowMapsForRead(Handle<SHVkCommandBuffer> cmdBuffer) noexcept
|
||||||
|
{
|
||||||
|
// Issue barrier to transition shadow maps for reading in compute shader
|
||||||
|
cmdBuffer->PipelineBarrier(vk::PipelineStageFlagBits::eEarlyFragmentTests | vk::PipelineStageFlagBits::eLateFragmentTests, vk::PipelineStageFlagBits::eComputeShader, {}, {}, {}, shadowMapMemoryBarriers);
|
||||||
|
}
|
||||||
|
|
||||||
|
//void SHLightingSubSystem::HandleResize(Handle<SHRenderGraphNodeCompute> compute) noexcept
|
||||||
|
//{
|
||||||
|
// uint32_t const NUM_SHADOW_MAPS = static_cast<uint32_t>(shadowMaps.size());
|
||||||
|
// for (uint32_t i = 0; i < NUM_SHADOW_MAPS; ++i)
|
||||||
|
// {
|
||||||
|
// // Just use the image view stored in the resource
|
||||||
|
// Handle<SHVkImageView> const NEW_IMAGE_VIEW = shadowMaps[i]->GetImageView();
|
||||||
|
|
||||||
|
// // set new image view
|
||||||
|
// std::get<Handle<SHVkImageView>>(shadowMapImageSamplers[i]) = NEW_IMAGE_VIEW;
|
||||||
|
|
||||||
|
// // Set image for barrier
|
||||||
|
// shadowMapMemoryBarriers[i].image = shadowMaps[i]->GetImage()->GetVkImage();
|
||||||
|
// }
|
||||||
|
|
||||||
|
// if (NUM_SHADOW_MAPS > 0)
|
||||||
|
// {
|
||||||
|
// // modify descriptors in render graph node compute
|
||||||
|
// compute->ModifyWriteDescImageComputeResource (SHGraphicsConstants::DescriptorSetBindings::SHADOW_MAP_IMAGE_SAMPLER_DATA, shadowMapImageSamplers);
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
|
||||||
Handle<SHVkDescriptorSetGroup> SHLightingSubSystem::GetLightDataDescriptorSet(void) const noexcept
|
Handle<SHVkDescriptorSetGroup> SHLightingSubSystem::GetLightDataDescriptorSet(void) const noexcept
|
||||||
{
|
{
|
||||||
return lightingDataDescSet;
|
return lightingDataDescSet;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::tuple<Handle<SHVkImageView>, Handle<SHVkSampler>, vk::ImageLayout> const& SHLightingSubSystem::GetViewSamplerLayout(uint32_t index) const noexcept
|
||||||
|
{
|
||||||
|
return shadowMapImageSamplers[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t SHLightingSubSystem::GetNumShadowMaps(void) const noexcept
|
||||||
|
{
|
||||||
|
return static_cast<uint32_t>(shadowMaps.size());
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,9 +3,13 @@
|
||||||
#include "Resource/SHHandle.h"
|
#include "Resource/SHHandle.h"
|
||||||
#include "Math/Vector/SHVec3.h"
|
#include "Math/Vector/SHVec3.h"
|
||||||
#include "Math/Vector/SHVec4.h"
|
#include "Math/Vector/SHVec4.h"
|
||||||
|
#include "Math/SHMatrix.h"
|
||||||
#include "SHLightData.h"
|
#include "SHLightData.h"
|
||||||
#include <array>
|
#include <array>
|
||||||
#include "Graphics/MiddleEnd/Interface/SHGraphicsConstants.h"
|
#include "Graphics/MiddleEnd/Interface/SHGraphicsConstants.h"
|
||||||
|
#include "Graphics/RenderGraph/SHRenderGraphResource.h"
|
||||||
|
#include "ECS_Base/SHECSMacros.h"
|
||||||
|
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
|
@ -16,6 +20,10 @@ namespace SHADE
|
||||||
class SHVkBuffer;
|
class SHVkBuffer;
|
||||||
class SHLightComponent;
|
class SHLightComponent;
|
||||||
class SHVkCommandBuffer;
|
class SHVkCommandBuffer;
|
||||||
|
class SHSamplerCache;
|
||||||
|
class SHVkImageView;
|
||||||
|
class SHVkSampler;
|
||||||
|
class SHRenderGraphNodeCompute;
|
||||||
|
|
||||||
// Represents how the data will be interpreted in GPU. we want to copy to a container of these before passing to GPU.
|
// Represents how the data will be interpreted in GPU. we want to copy to a container of these before passing to GPU.
|
||||||
struct SHDirectionalLightData
|
struct SHDirectionalLightData
|
||||||
|
@ -34,6 +42,12 @@ namespace SHADE
|
||||||
//! Diffuse color emitted by the light
|
//! Diffuse color emitted by the light
|
||||||
alignas (16) SHVec4 diffuseColor;
|
alignas (16) SHVec4 diffuseColor;
|
||||||
|
|
||||||
|
//! Matrix for world to projection from light's perspective
|
||||||
|
SHMatrix pvMatrix;
|
||||||
|
|
||||||
|
//! Represents boolean for casting shadows in first byte and shadow map index in the other 3.
|
||||||
|
uint32_t shadowData;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Represents how the data will be interpreted in GPU. we want to copy to a container of these before passing to GPU.
|
// Represents how the data will be interpreted in GPU. we want to copy to a container of these before passing to GPU.
|
||||||
|
@ -52,19 +66,22 @@ namespace SHADE
|
||||||
//! when a fragment is being evaluated, the shader will use the fragment's
|
//! when a fragment is being evaluated, the shader will use the fragment's
|
||||||
//! layer value to AND with the light's. If result is 1, do lighting calculations.
|
//! layer value to AND with the light's. If result is 1, do lighting calculations.
|
||||||
uint32_t cullingMask;
|
uint32_t cullingMask;
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class SH_API SHLightingSubSystem
|
class SH_API SHLightingSubSystem
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
using DynamicOffsetArray = std::array<std::vector<uint32_t>, static_cast<uint32_t>(SHGraphicsConstants::NUM_FRAME_BUFFERS)>;
|
using DynamicOffsetArray = std::array<std::vector<uint32_t>, static_cast<uint32_t>(SHGraphicsConstants::NUM_FRAME_BUFFERS)>;
|
||||||
|
static constexpr uint32_t MAX_SHADOWS = 200;
|
||||||
|
static constexpr uint32_t SHADOW_MAP_WIDTH = 1024;
|
||||||
|
static constexpr uint32_t SHADOW_MAP_HEIGHT = 1024;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
class PerTypeData
|
class PerTypeData
|
||||||
{
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
/* STATIC MEMBER VARIABLES */
|
/* STATIC MEMBER VARIABLES */
|
||||||
|
@ -123,6 +140,10 @@ namespace SHADE
|
||||||
};
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
/*-----------------------------------------------------------------------*/
|
||||||
|
/* STATIC MEMBER VARIABLES */
|
||||||
|
/*-----------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
//! logical device used for creation
|
//! logical device used for creation
|
||||||
Handle<SHVkLogicalDevice> logicalDevice;
|
Handle<SHVkLogicalDevice> logicalDevice;
|
||||||
|
@ -150,24 +171,59 @@ namespace SHADE
|
||||||
//! don't do anything.
|
//! don't do anything.
|
||||||
//uint32_t numLightComponents;
|
//uint32_t numLightComponents;
|
||||||
|
|
||||||
|
//! Handle to sampler that all shadow map descriptors will use
|
||||||
|
Handle<SHVkSampler> shadowMapSampler;
|
||||||
|
|
||||||
|
//! For indexing shadow maps
|
||||||
|
std::unordered_map<EntityID, uint32_t> shadowMapIndexing;
|
||||||
|
|
||||||
|
//! Shadow maps for every light that casts a shadow Order here doesn't matter. We just want to store it
|
||||||
|
std::vector<Handle<SHRenderGraphResource>> shadowMaps;
|
||||||
|
|
||||||
|
//! Descriptor sets required to be given to the compute shader for shadow calculation. This will be a descriptor array.
|
||||||
|
//! It will also be preallocated.
|
||||||
|
//Handle<SHVkDescriptorSetGroup> shadowMapDescriptorSet;
|
||||||
|
|
||||||
|
//! Combined image samplers for the texture descriptors
|
||||||
|
std::vector<std::tuple<Handle<SHVkImageView>, Handle<SHVkSampler>, vk::ImageLayout>> shadowMapImageSamplers;
|
||||||
|
|
||||||
|
//! Barriers required to transition the resources from whatever layout they are in (probably from VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL)
|
||||||
|
//! to VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL)
|
||||||
|
std::vector<vk::ImageMemoryBarrier> shadowMapMemoryBarriers;
|
||||||
|
|
||||||
|
//! Resource hub from Graphics System
|
||||||
|
SHResourceHub* resourceHub;
|
||||||
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
/* PRIVATE MEMBER FUNCTIONS */
|
/* PRIVATE MEMBER FUNCTIONS */
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
void UpdateDescSet (uint32_t binding) noexcept;
|
void UpdateDescSet (uint32_t binding) noexcept;
|
||||||
void ComputeDynamicOffsets (void) noexcept;
|
void ComputeDynamicOffsets (void) noexcept;
|
||||||
void ResetNumLights (void) noexcept;
|
void ResetNumLights (void) noexcept;
|
||||||
|
void UpdateShadowMapDesc (void) noexcept;
|
||||||
|
SHMatrix GetViewMatrix (SHLightComponent* lightComp) noexcept;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
/* PUBLIC MEMBER FUNCTIONS */
|
/* PUBLIC MEMBER FUNCTIONS */
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
void Init (Handle<SHVkLogicalDevice> device, Handle<SHVkDescriptorPool> descPool) noexcept;
|
void Init (Handle<SHVkLogicalDevice> device, Handle<SHVkDescriptorPool> descPool, SHResourceHub* rh, Handle<SHVkSampler> inShadowMapSampler) noexcept;
|
||||||
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 setIndex, uint32_t frameIndex) noexcept;
|
void BindDescSet (Handle<SHVkCommandBuffer> cmdBuffer, uint32_t setIndex, uint32_t frameIndex) noexcept;
|
||||||
|
uint32_t AddShadowMap (Handle<SHRenderGraphResource> newShadowMap, EntityID lightEntity) noexcept;
|
||||||
|
void PrepareShadowMapsForRead (Handle<SHVkCommandBuffer> cmdBuffer) noexcept;
|
||||||
|
//void HandleResize (Handle<SHRenderGraphNodeCompute> compute) noexcept;
|
||||||
|
//void RemoveShadowMap (uint32_t index) noexcept;
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------------*/
|
||||||
|
/* SETTERS AND GETTERS */
|
||||||
|
/*-----------------------------------------------------------------------*/
|
||||||
Handle<SHVkDescriptorSetGroup> GetLightDataDescriptorSet (void) const noexcept;
|
Handle<SHVkDescriptorSetGroup> GetLightDataDescriptorSet (void) const noexcept;
|
||||||
|
std::tuple<Handle<SHVkImageView>, Handle<SHVkSampler>, vk::ImageLayout> const& GetViewSamplerLayout (uint32_t index) const noexcept;
|
||||||
|
uint32_t GetNumShadowMaps (void) const noexcept;
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,18 +1,23 @@
|
||||||
#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/SHGraphicsPredefinedData.h"
|
|
||||||
#include "Graphics/RenderGraph/SHSubpass.h"
|
#include "Graphics/RenderGraph/SHSubpass.h"
|
||||||
#include "Graphics/SHVkUtil.h"
|
#include "Graphics/SHVkUtil.h"
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
|
|
||||||
Handle<SHVkPipeline> SHPipelineLibrary::CreateGraphicsPipelines(std::pair<Handle<SHVkShaderModule>, Handle<SHVkShaderModule>> const& vsFsPair, Handle<SHVkRenderpass> renderpass, Handle<SHSubpass> subpass) noexcept
|
Handle<SHVkPipeline> SHPipelineLibrary::CreateGraphicsPipelines(std::pair<Handle<SHVkShaderModule>, Handle<SHVkShaderModule>> const& vsFsPair, Handle<SHVkRenderpass> renderpass, Handle<SHSubpass> subpass, SHVertexInputState const& viState/* = SHGraphicsPredefinedData::GetDefaultViState()*/, SHRasterizationState const& rasterState) noexcept
|
||||||
{
|
{
|
||||||
|
std::vector<Handle<SHVkShaderModule>> modules{};
|
||||||
|
if (vsFsPair.first)
|
||||||
|
modules.push_back(vsFsPair.first);
|
||||||
|
if (vsFsPair.second)
|
||||||
|
modules.push_back(vsFsPair.second);
|
||||||
|
|
||||||
SHPipelineLayoutParams params
|
SHPipelineLayoutParams params
|
||||||
{
|
{
|
||||||
.shaderModules = {vsFsPair.first, vsFsPair.second},
|
.shaderModules = std::move(modules),
|
||||||
.predefinedDescSetLayouts = SHGraphicsPredefinedData::GetSystemData(SHGraphicsPredefinedData::SystemType::BATCHING).descSetLayouts
|
.predefinedDescSetLayouts = SHGraphicsPredefinedData::GetSystemData(SHGraphicsPredefinedData::SystemType::BATCHING).descSetLayouts
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -21,7 +26,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(SHGraphicsPredefinedData::GetDefaultViState());
|
newPipeline->GetPipelineState().SetVertexInputState(viState);
|
||||||
|
|
||||||
SHColorBlendState colorBlendState{};
|
SHColorBlendState colorBlendState{};
|
||||||
colorBlendState.logic_op_enable = VK_FALSE;
|
colorBlendState.logic_op_enable = VK_FALSE;
|
||||||
|
@ -30,6 +35,7 @@ namespace SHADE
|
||||||
auto const& subpassColorReferences = subpass->GetColorAttachmentReferences();
|
auto const& subpassColorReferences = subpass->GetColorAttachmentReferences();
|
||||||
colorBlendState.attachments.reserve(subpassColorReferences.size());
|
colorBlendState.attachments.reserve(subpassColorReferences.size());
|
||||||
|
|
||||||
|
|
||||||
for (auto& att : subpassColorReferences)
|
for (auto& att : subpassColorReferences)
|
||||||
{
|
{
|
||||||
colorBlendState.attachments.push_back(vk::PipelineColorBlendAttachmentState
|
colorBlendState.attachments.push_back(vk::PipelineColorBlendAttachmentState
|
||||||
|
@ -48,6 +54,8 @@ namespace SHADE
|
||||||
|
|
||||||
newPipeline->GetPipelineState().SetColorBlenState(colorBlendState);
|
newPipeline->GetPipelineState().SetColorBlenState(colorBlendState);
|
||||||
|
|
||||||
|
newPipeline->GetPipelineState().SetRasterizationState(rasterState);
|
||||||
|
|
||||||
// Actually construct the pipeline
|
// Actually construct the pipeline
|
||||||
newPipeline->ConstructPipeline();
|
newPipeline->ConstructPipeline();
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include "Graphics/Shaders/SHVkShaderModule.h"
|
#include "Graphics/Shaders/SHVkShaderModule.h"
|
||||||
#include "Graphics/Pipeline/SHVkPipeline.h"
|
#include "Graphics/Pipeline/SHVkPipeline.h"
|
||||||
|
#include "Graphics/MiddleEnd/GlobalData/SHGraphicsPredefinedData.h"
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
|
@ -32,7 +33,9 @@ namespace SHADE
|
||||||
Handle<SHVkPipeline> CreateGraphicsPipelines (
|
Handle<SHVkPipeline> CreateGraphicsPipelines (
|
||||||
std::pair<Handle<SHVkShaderModule>, Handle<SHVkShaderModule>> const& vsFsPair,
|
std::pair<Handle<SHVkShaderModule>, Handle<SHVkShaderModule>> const& vsFsPair,
|
||||||
Handle<SHVkRenderpass> renderpass,
|
Handle<SHVkRenderpass> renderpass,
|
||||||
Handle<SHSubpass> subpass
|
Handle<SHSubpass> subpass,
|
||||||
|
SHVertexInputState const& viState = SHGraphicsPredefinedData::GetDefaultViState(),
|
||||||
|
SHRasterizationState const& rasterState = SHRasterizationState{}
|
||||||
) noexcept;
|
) noexcept;
|
||||||
Handle<SHVkPipeline> GetGraphicsPipeline (std::pair<Handle<SHVkShaderModule>, Handle<SHVkShaderModule>> const& vsFsPair) noexcept;
|
Handle<SHVkPipeline> GetGraphicsPipeline (std::pair<Handle<SHVkShaderModule>, Handle<SHVkShaderModule>> const& vsFsPair) noexcept;
|
||||||
bool CheckGraphicsPipelineExistence (std::pair<Handle<SHVkShaderModule>, Handle<SHVkShaderModule>> const& vsFsPair) noexcept;
|
bool CheckGraphicsPipelineExistence (std::pair<Handle<SHVkShaderModule>, Handle<SHVkShaderModule>> const& vsFsPair) noexcept;
|
||||||
|
|
|
@ -195,7 +195,7 @@ namespace SHADE
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHVertexInputState::AddBinding(bool instanced, bool calcOffset, std::initializer_list<SHVertexAttribute> inAttribs) noexcept
|
void SHVertexInputState::AddBinding(bool instanced, bool calcOffset, std::initializer_list<SHVertexAttribute> inAttribs, uint32_t fixedBinding /*= static_cast<uint32_t>(-1)*/, uint32_t fixedAttributeLocation/* = static_cast<uint32_t>(-1)*/) noexcept
|
||||||
{
|
{
|
||||||
// add a binding and get ref to it
|
// add a binding and get ref to it
|
||||||
bindings.emplace_back();
|
bindings.emplace_back();
|
||||||
|
@ -210,7 +210,7 @@ namespace SHADE
|
||||||
// Offset is 0 at first (for first element)
|
// Offset is 0 at first (for first element)
|
||||||
uint32_t offset = 0;
|
uint32_t offset = 0;
|
||||||
|
|
||||||
binding.binding = static_cast<uint32_t>(bindings.size() - 1);
|
binding.binding = (fixedBinding != static_cast<uint32_t>(-1)) ? fixedBinding : static_cast<uint32_t>(bindings.size() - 1);
|
||||||
|
|
||||||
// for every attribute passed in
|
// for every attribute passed in
|
||||||
for (auto const& attrib : inAttribs)
|
for (auto const& attrib : inAttribs)
|
||||||
|
@ -226,10 +226,11 @@ namespace SHADE
|
||||||
auto& vertexAttrib = attributes.back();
|
auto& vertexAttrib = attributes.back();
|
||||||
|
|
||||||
// The binding for that attribute description is index of the new binding created earlier in this function
|
// The binding for that attribute description is index of the new binding created earlier in this function
|
||||||
vertexAttrib.binding = static_cast<uint32_t>(bindings.size() - 1);
|
vertexAttrib.binding = (fixedBinding != static_cast<uint32_t>(-1)) ? fixedBinding : static_cast<uint32_t>(bindings.size() - 1);
|
||||||
|
|
||||||
//Attribute location. New index is simply + 1 of the previous. Starts from 0 obviously
|
//Attribute location. New index is simply + 1 of the previous. Starts from 0 obviously
|
||||||
vertexAttrib.location = static_cast<uint32_t>(attributes.size () - 1);
|
vertexAttrib.location = (fixedAttributeLocation != static_cast<uint32_t>(-1)) ? fixedAttributeLocation + i : static_cast<uint32_t>(attributes.size () - 1);
|
||||||
|
//vertexAttrib.location = static_cast<uint32_t>(attributes.size() - 1);
|
||||||
|
|
||||||
// Get the vkFormat associated with the SHAttribFormat
|
// Get the vkFormat associated with the SHAttribFormat
|
||||||
vertexAttrib.format = format;
|
vertexAttrib.format = format;
|
||||||
|
|
|
@ -34,7 +34,7 @@ namespace SHADE
|
||||||
SHVertexInputState& operator= (SHVertexInputState const& rhs) noexcept;
|
SHVertexInputState& operator= (SHVertexInputState const& rhs) noexcept;
|
||||||
SHVertexInputState& operator= (SHVertexInputState&& rhs) noexcept;
|
SHVertexInputState& operator= (SHVertexInputState&& rhs) noexcept;
|
||||||
|
|
||||||
void AddBinding(bool instanced, bool calcOffset, std::initializer_list<SHVertexAttribute> inAttribs) noexcept;
|
void AddBinding(bool instanced, bool calcOffset, std::initializer_list<SHVertexAttribute> inAttribs, uint32_t fixedBinding = static_cast<uint32_t>(-1), uint32_t fixedAttributeLocation = static_cast<uint32_t>(-1)) noexcept;
|
||||||
|
|
||||||
friend class SHVkPipelineState;
|
friend class SHVkPipelineState;
|
||||||
friend class SHVkPipeline;
|
friend class SHVkPipeline;
|
||||||
|
|
|
@ -18,6 +18,8 @@ namespace SHADE
|
||||||
vk::ShaderStageFlags stageFlags;
|
vk::ShaderStageFlags stageFlags;
|
||||||
|
|
||||||
for (auto& shaderModule : shaderModules)
|
for (auto& shaderModule : shaderModules)
|
||||||
|
{
|
||||||
|
if (shaderModule)
|
||||||
{
|
{
|
||||||
// References for convenience
|
// References for convenience
|
||||||
auto const& reflectedData = shaderModule->GetReflectedData();
|
auto const& reflectedData = shaderModule->GetReflectedData();
|
||||||
|
@ -81,7 +83,7 @@ namespace SHADE
|
||||||
|
|
||||||
stageFlags |= shaderModule->GetShaderStageFlagBits();
|
stageFlags |= shaderModule->GetShaderStageFlagBits();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// After all the sizes of the push constant blocks have been added, record the size in the interface
|
// After all the sizes of the push constant blocks have been added, record the size in the interface
|
||||||
|
@ -132,6 +134,9 @@ namespace SHADE
|
||||||
//! Now we take descriptor set info from all shaders and prepare some bindings for the descriptor set
|
//! Now we take descriptor set info from all shaders and prepare some bindings for the descriptor set
|
||||||
for (auto& shaderModule : shaderModules)
|
for (auto& shaderModule : shaderModules)
|
||||||
{
|
{
|
||||||
|
if (!shaderModule)
|
||||||
|
continue;
|
||||||
|
|
||||||
auto const& descBindingInfo = shaderModule->GetReflectedData().GetDescriptorBindingInfo();
|
auto const& descBindingInfo = shaderModule->GetReflectedData().GetDescriptorBindingInfo();
|
||||||
auto const& reflectedSets = descBindingInfo.GetReflectedSets();
|
auto const& reflectedSets = descBindingInfo.GetReflectedSets();
|
||||||
|
|
||||||
|
@ -200,11 +205,13 @@ namespace SHADE
|
||||||
newBinding.DescriptorCount = SHVkDescriptorSetLayout::Binding::VARIABLE_DESCRIPTOR_UPPER_BOUND;
|
newBinding.DescriptorCount = SHVkDescriptorSetLayout::Binding::VARIABLE_DESCRIPTOR_UPPER_BOUND;
|
||||||
|
|
||||||
// Set the flags for variable bindings
|
// Set the flags for variable bindings
|
||||||
newBinding.flags = vk::DescriptorBindingFlagBits::eVariableDescriptorCount;
|
newBinding.flags = vk::DescriptorBindingFlagBits::eVariableDescriptorCount | vk::DescriptorBindingFlagBits::ePartiallyBound;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
SHLOG_ERROR("Variable size binding is detected, but the binding is not the last binding of the set and is therefore invalid. ");
|
SHLOG_ERROR("Variable size binding is detected, but the binding is not the last binding of the set and is therefore invalid. ");
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
setsWithBindings[CURRENT_SET].emplace_back(newBinding);
|
setsWithBindings[CURRENT_SET].emplace_back(newBinding);
|
||||||
}
|
}
|
||||||
|
@ -326,11 +333,10 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
for (auto& mod : shaderModules)
|
for (auto& mod : shaderModules)
|
||||||
{
|
{
|
||||||
mod->AddCallback([this]()
|
if (mod)
|
||||||
{
|
{
|
||||||
RecreateIfNeeded();
|
mod->AddCallback([this]() { RecreateIfNeeded(); });
|
||||||
}
|
}
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
RecreateIfNeeded ();
|
RecreateIfNeeded ();
|
||||||
|
|
|
@ -54,7 +54,7 @@ namespace SHADE
|
||||||
|
|
||||||
*/
|
*/
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
void SHRenderGraph::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 SHRenderGraph::AddResource(std::string resourceName, std::initializer_list<SH_RENDER_GRAPH_RESOURCE_FLAGS> typeFlags, bool resizeWithWindow, 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 /*= {}*/)
|
||||||
{
|
{
|
||||||
// If we set to
|
// If we set to
|
||||||
if (w == static_cast<uint32_t>(-1) && h == static_cast<uint32_t>(-1))
|
if (w == static_cast<uint32_t>(-1) && h == static_cast<uint32_t>(-1))
|
||||||
|
@ -64,7 +64,7 @@ namespace SHADE
|
||||||
format = renderGraphStorage->swapchain->GetSurfaceFormatKHR().format;
|
format = renderGraphStorage->swapchain->GetSurfaceFormatKHR().format;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto resource = renderGraphStorage->resourceHub->Create<SHRenderGraphResource>(renderGraphStorage, resourceName, typeFlags, format, w, h, levels, usageFlags, createFlags);
|
auto resource = renderGraphStorage->resourceHub->Create<SHRenderGraphResource>(renderGraphStorage, resourceName, typeFlags, format, w, h, levels, usageFlags, createFlags, resizeWithWindow);
|
||||||
renderGraphStorage->graphResources->try_emplace(resourceName, resource);
|
renderGraphStorage->graphResources->try_emplace(resourceName, resource);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -106,6 +106,9 @@ namespace SHADE
|
||||||
|
|
||||||
for (auto& affectedNode : affectedNodes)
|
for (auto& affectedNode : affectedNodes)
|
||||||
nodes[affectedNode]->CreateFramebuffer();
|
nodes[affectedNode]->CreateFramebuffer();
|
||||||
|
|
||||||
|
renderGraphStorage->graphResources->at(resourceName).Free();
|
||||||
|
renderGraphStorage->graphResources->erase (resourceName);
|
||||||
/*
|
/*
|
||||||
* IMPORTANT NOTES
|
* IMPORTANT NOTES
|
||||||
*
|
*
|
||||||
|
@ -166,68 +169,7 @@ namespace SHADE
|
||||||
|
|
||||||
for (uint32_t i = 0; auto& node : nodes)
|
for (uint32_t i = 0; auto& node : nodes)
|
||||||
{
|
{
|
||||||
// key is handle ID, value is final layout.
|
node->StandaloneConfigureAttDesc(i == nodes.size() - 1);
|
||||||
std::unordered_map<uint32_t, vk::ImageLayout> resourceAttFinalLayouts;
|
|
||||||
if (node->subpasses.empty())
|
|
||||||
{
|
|
||||||
SHLOG_ERROR("Node does not contain a subpass. Cannot configure attachment descriptions as a result. ");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// We first want to take all resources track their layout as undefined at the start of the node/renderpass
|
|
||||||
auto const resources = node->GetResources();
|
|
||||||
for (auto& resource : resources)
|
|
||||||
{
|
|
||||||
resource->GetInfoTracker()->TrackLayout(node, {}, vk::ImageLayout::eUndefined);
|
|
||||||
}
|
|
||||||
|
|
||||||
// attempt to get all final layouts for all resources
|
|
||||||
for (auto& subpass : node->subpasses)
|
|
||||||
{
|
|
||||||
for (auto& color : subpass->colorReferences)
|
|
||||||
{
|
|
||||||
// If final renderpass and attachment is a COLOR_PRESENT resource, make resource transition to present after last subpass
|
|
||||||
if (i == nodes.size() - 1 && (node->attResources[color.attachment]->resourceTypeFlags & static_cast<uint32_t>(SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR_PRESENT)))
|
|
||||||
resourceAttFinalLayouts[color.attachment] = vk::ImageLayout::ePresentSrcKHR;
|
|
||||||
else
|
|
||||||
resourceAttFinalLayouts[color.attachment] = color.layout;
|
|
||||||
|
|
||||||
node->attResources[color.attachment]->infoTracker->TrackLayout(node, subpass, color.layout);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (auto& depth : subpass->depthReferences)
|
|
||||||
{
|
|
||||||
resourceAttFinalLayouts[depth.attachment] = depth.layout;
|
|
||||||
node->attResources[depth.attachment]->infoTracker->TrackLayout(node, subpass, depth.layout);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (auto& input : subpass->inputReferences)
|
|
||||||
{
|
|
||||||
resourceAttFinalLayouts[input.attachment] = input.layout;
|
|
||||||
node->attResources[input.attachment]->infoTracker->TrackLayout(node, subpass, input.layout);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (uint32_t j = 0; j < node->attachmentDescriptions.size(); ++j)
|
|
||||||
{
|
|
||||||
auto& att = node->attachmentDescriptions[j];
|
|
||||||
auto& resource = node->attResources[j];
|
|
||||||
|
|
||||||
// If resource is from another render graph, use the final layout it had when it was last used in that graph. This is initialized in LinkNonOwningResource.
|
|
||||||
// We also want to load the attachment, not "don't care".
|
|
||||||
if (resource->resourceTypeFlags & SHUtilities::ConvertEnum(SH_RENDER_GRAPH_RESOURCE_FLAGS::SHARED) &&
|
|
||||||
renderGraphStorage->nonOwningResourceInitialLayouts.contains(resource.GetId().Raw))
|
|
||||||
{
|
|
||||||
att.initialLayout = renderGraphStorage->nonOwningResourceInitialLayouts.at (resource.GetId().Raw);
|
|
||||||
att.loadOp = vk::AttachmentLoadOp::eLoad;
|
|
||||||
att.stencilLoadOp = vk::AttachmentLoadOp::eLoad;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
att.initialLayout = vk::ImageLayout::eUndefined;
|
|
||||||
|
|
||||||
att.finalLayout = resourceAttFinalLayouts[j];
|
|
||||||
resource->GetInfoTracker()->TrackLayout(node, {}, att.finalLayout);
|
|
||||||
}
|
|
||||||
++i;
|
++i;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -333,6 +275,17 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SHRenderGraph::ReindexNodes(void) noexcept
|
||||||
|
{
|
||||||
|
nodeIndexing.clear();
|
||||||
|
uint32_t i = 0;
|
||||||
|
for (auto& node : nodes)
|
||||||
|
{
|
||||||
|
nodeIndexing.emplace (node->name, i);
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
/*!
|
/*!
|
||||||
|
|
||||||
|
@ -473,6 +426,65 @@ namespace SHADE
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
/*!
|
||||||
|
|
||||||
|
\brief
|
||||||
|
This function is purely used for dynamic nodes (if such a thing were to
|
||||||
|
exist in our architecture). In other words, don't use this function unless
|
||||||
|
the new node is fully standalone and does not rely or is a prereq of
|
||||||
|
other nodes.
|
||||||
|
|
||||||
|
\param nodeName
|
||||||
|
Name of new node
|
||||||
|
|
||||||
|
\param resourceInstruction
|
||||||
|
Resources for the node
|
||||||
|
|
||||||
|
\param nodeToAddAfter
|
||||||
|
The node to add the new node after.
|
||||||
|
|
||||||
|
\return
|
||||||
|
|
||||||
|
*/
|
||||||
|
/***************************************************************************/
|
||||||
|
Handle<SHRenderGraphNode> SHRenderGraph::AddNodeAfter(std::string nodeName, std::initializer_list<ResourceInstruction> resourceInstruction, std::string nodeToAddAfter) noexcept
|
||||||
|
{
|
||||||
|
if (nodeIndexing.contains(nodeName))
|
||||||
|
{
|
||||||
|
SHLOG_ERROR("Node already exists, cannot add node. ");
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<SHAttachmentDescInitParams> descInitParams;
|
||||||
|
for (auto const& instruction : resourceInstruction)
|
||||||
|
{
|
||||||
|
// If the resource that the new node is requesting for exists, allow the graph to reference it
|
||||||
|
if (renderGraphStorage->graphResources->contains(instruction.resourceName))
|
||||||
|
{
|
||||||
|
descInitParams.push_back(
|
||||||
|
{
|
||||||
|
.resourceHdl = renderGraphStorage->graphResources->at(instruction.resourceName),
|
||||||
|
.dontClearOnLoad = instruction.dontClearOnLoad,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SHLOG_ERROR("Resource doesn't exist in graph yet. Cannot create new node.");
|
||||||
|
return{};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// get target node
|
||||||
|
auto targetNode = nodes.begin() + nodeIndexing.at(nodeToAddAfter);
|
||||||
|
|
||||||
|
auto node = nodes.insert(targetNode, renderGraphStorage->resourceHub->Create<SHRenderGraphNode>(nodeName, renderGraphStorage, std::move(descInitParams), std::vector<Handle<SHRenderGraphNode>>()));
|
||||||
|
ReindexNodes ();
|
||||||
|
return *node;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void SHRenderGraph::AddRenderToSwapchainNode(std::string toSwapchainResource, std::string swapchainResource, std::initializer_list<std::string> predecessorNodes, std::pair<Handle<SHVkShaderModule>, Handle<SHVkShaderModule>> shaderModules) noexcept
|
void SHRenderGraph::AddRenderToSwapchainNode(std::string toSwapchainResource, std::string swapchainResource, std::initializer_list<std::string> predecessorNodes, std::pair<Handle<SHVkShaderModule>, Handle<SHVkShaderModule>> shaderModules) noexcept
|
||||||
{
|
{
|
||||||
for (auto& node : predecessorNodes)
|
for (auto& node : predecessorNodes)
|
||||||
|
@ -532,10 +544,6 @@ namespace SHADE
|
||||||
ConfigureSubSystems();
|
ConfigureSubSystems();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHRenderGraph::Regenerate(void) noexcept
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
/*!
|
/*!
|
||||||
|
@ -571,12 +579,15 @@ namespace SHADE
|
||||||
auto const& descMappings = SHGraphicsPredefinedData::GetMappings(SHGraphicsPredefinedData::SystemType::BATCHING);
|
auto const& descMappings = SHGraphicsPredefinedData::GetMappings(SHGraphicsPredefinedData::SystemType::BATCHING);
|
||||||
|
|
||||||
for (auto& node : nodes)
|
for (auto& node : nodes)
|
||||||
|
{
|
||||||
|
if (node->renderpass)
|
||||||
{
|
{
|
||||||
// bind static global data
|
// bind static global data
|
||||||
SHGlobalDescriptorSets::BindStaticGlobalData(cmdBuffer, SH_PIPELINE_TYPE::GRAPHICS, descMappings.at(SHPredefinedDescriptorTypes::STATIC_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();
|
||||||
}
|
}
|
||||||
|
@ -604,10 +615,13 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
// resize resources
|
// resize resources
|
||||||
for (auto& [name, resource] : *renderGraphStorage->graphResources)
|
for (auto& [name, resource] : *renderGraphStorage->graphResources)
|
||||||
|
{
|
||||||
|
if (resource->resizeWithWindow)
|
||||||
{
|
{
|
||||||
if (!renderGraphStorage->nonOwningResourceInitialLayouts.contains (resource.GetId().Raw))
|
if (!renderGraphStorage->nonOwningResourceInitialLayouts.contains (resource.GetId().Raw))
|
||||||
resource->HandleResize(newWidth, newHeight);
|
resource->HandleResize(newWidth, newHeight);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (auto& node : nodes)
|
for (auto& node : nodes)
|
||||||
{
|
{
|
||||||
|
|
|
@ -55,6 +55,7 @@ namespace SHADE
|
||||||
void ConfigureRenderpasses (void) noexcept;
|
void ConfigureRenderpasses (void) noexcept;
|
||||||
void ConfigureSubSystems (void) noexcept;
|
void ConfigureSubSystems (void) noexcept;
|
||||||
void ConfigureFramebuffers (void) noexcept;
|
void ConfigureFramebuffers (void) noexcept;
|
||||||
|
void ReindexNodes (void) noexcept;
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
/* PRIVATE MEMBER VARIABLES */
|
/* PRIVATE MEMBER VARIABLES */
|
||||||
|
@ -101,6 +102,7 @@ namespace SHADE
|
||||||
(
|
(
|
||||||
std::string resourceName,
|
std::string resourceName,
|
||||||
std::initializer_list<SH_RENDER_GRAPH_RESOURCE_FLAGS> typeFlags,
|
std::initializer_list<SH_RENDER_GRAPH_RESOURCE_FLAGS> typeFlags,
|
||||||
|
bool resizeWithWindow = true,
|
||||||
uint32_t w = static_cast<uint32_t>(-1),
|
uint32_t w = static_cast<uint32_t>(-1),
|
||||||
uint32_t h = static_cast<uint32_t>(-1),
|
uint32_t h = static_cast<uint32_t>(-1),
|
||||||
vk::Format format = vk::Format::eB8G8R8A8Unorm,
|
vk::Format format = vk::Format::eB8G8R8A8Unorm,
|
||||||
|
@ -123,6 +125,12 @@ namespace SHADE
|
||||||
std::initializer_list<ResourceInstruction> resourceInstruction,
|
std::initializer_list<ResourceInstruction> resourceInstruction,
|
||||||
std::initializer_list<std::string> predecessorNodes
|
std::initializer_list<std::string> predecessorNodes
|
||||||
) noexcept;
|
) noexcept;
|
||||||
|
Handle<SHRenderGraphNode> AddNodeAfter
|
||||||
|
(
|
||||||
|
std::string nodeName,
|
||||||
|
std::initializer_list<ResourceInstruction> resourceInstruction,
|
||||||
|
std::string nodeToAddAfter
|
||||||
|
) noexcept;
|
||||||
|
|
||||||
void AddRenderToSwapchainNode
|
void AddRenderToSwapchainNode
|
||||||
(
|
(
|
||||||
|
@ -134,7 +142,6 @@ namespace SHADE
|
||||||
) noexcept;
|
) 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<SHVkDescriptorPool> descPool) noexcept;
|
void Execute (uint32_t frameIndex, Handle<SHVkDescriptorPool> descPool) noexcept;
|
||||||
void Begin (uint32_t frameIndex) noexcept;
|
void Begin (uint32_t frameIndex) noexcept;
|
||||||
|
@ -165,7 +172,14 @@ namespace SHADE
|
||||||
* that manage the resources instead and can facilitate such linking of resources. Either that, or we allow only 1 render graph,
|
* that manage the resources instead and can facilitate such linking of resources. Either that, or we allow only 1 render graph,
|
||||||
* but different matrices (SHRenderer) can be used in different nodes.
|
* but different matrices (SHRenderer) can be used in different nodes.
|
||||||
* - There are also way too many hash maps created for ease of access. This definitely can be cut down.
|
* - There are also way too many hash maps created for ease of access. This definitely can be cut down.
|
||||||
* -
|
* - In hindsight there should have been a distinction between static and dynamic nodes. Static nodes are the ones that are accounted
|
||||||
|
* for in the generation of the render graph. Dynamic nodes begin with nothing at first, but allows for linking of resources and subpasses
|
||||||
|
* while the render graph is executing. The resources here should also be dynamic, which means it should never be used in anywhere else other
|
||||||
|
* than in the node that is using it. This would mean its initial layouts are always specified as undefined and final layouts specified as
|
||||||
|
* whatever the last subpass that is using that resource specifies in the node. Dynamic nodes are meant to render to resources that would later
|
||||||
|
* be used externally, as descriptors for example (the descriptors can be used in a render graph node compute for example). Dynamic nodes run as
|
||||||
|
* if they are the only nodes in the graph, because their resources are not used in other nodes and are thus not predecessors or successors of any
|
||||||
|
* other node.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
|
@ -32,9 +32,12 @@ namespace SHADE
|
||||||
renderpass.Free();
|
renderpass.Free();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!spDescs.empty())
|
||||||
|
{
|
||||||
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);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
/*!
|
/*!
|
||||||
|
@ -45,6 +48,8 @@ namespace SHADE
|
||||||
*/
|
*/
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
void SHRenderGraphNode::CreateFramebuffer(void) noexcept
|
void SHRenderGraphNode::CreateFramebuffer(void) noexcept
|
||||||
|
{
|
||||||
|
if (renderpass)
|
||||||
{
|
{
|
||||||
if (!framebuffers.empty())
|
if (!framebuffers.empty())
|
||||||
{
|
{
|
||||||
|
@ -78,8 +83,11 @@ namespace SHADE
|
||||||
SET_VK_OBJ_NAME(graphStorage->logicalDevice, vk::ObjectType::eFramebuffer, framebuffers[i]->GetVkFramebuffer(), "[Framebuffer] " + name + std::to_string(i));
|
SET_VK_OBJ_NAME(graphStorage->logicalDevice, vk::ObjectType::eFramebuffer, framebuffers[i]->GetVkFramebuffer(), "[Framebuffer] " + name + std::to_string(i));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void SHRenderGraphNode::HandleResize(void) noexcept
|
void SHRenderGraphNode::HandleResize(void) noexcept
|
||||||
|
{
|
||||||
|
if (renderpass)
|
||||||
{
|
{
|
||||||
renderpass->HandleResize();
|
renderpass->HandleResize();
|
||||||
|
|
||||||
|
@ -114,23 +122,32 @@ namespace SHADE
|
||||||
nodeCompute->HandleResize();
|
nodeCompute->HandleResize();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void SHRenderGraphNode::ConfigureSubpasses(void) noexcept
|
void SHRenderGraphNode::ConfigureSubpasses(void) noexcept
|
||||||
{
|
{
|
||||||
|
if (subpasses.empty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
uint32_t numValidSubpasses = std::count_if(subpasses.begin(), subpasses.end(), [](Handle<SHSubpass> subpass) {return !subpass->HasNoAttachments();});
|
||||||
|
|
||||||
// Create subpass description and dependencies based on number of subpasses
|
// Create subpass description and dependencies based on number of subpasses
|
||||||
spDescs.resize(subpasses.size());
|
spDescs.resize(numValidSubpasses);
|
||||||
spDeps.resize(subpasses.size());
|
spDeps.resize(numValidSubpasses);
|
||||||
|
|
||||||
// Now we want to loop through all attachments in all subpasses in the node and query
|
// 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
|
// the resources being used. For each resource we want to query the type and record it
|
||||||
// in bit fields (1 bit for each subpass).
|
// in bit fields (1 bit for each subpass).
|
||||||
uint32_t colorRead = 0, colorWrite = 0, depthRead = 0, depthWrite = 0, inputDependencies = 0;
|
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 all subpasses (see above description about bit field for this).
|
||||||
for (auto& subpass : subpasses)
|
for (uint32_t i = 0; auto& subpass : subpasses)
|
||||||
{
|
{
|
||||||
|
// skip if subpass is not valid
|
||||||
|
if (subpass->HasNoAttachments())
|
||||||
|
continue;
|
||||||
|
|
||||||
// Configure subpass description
|
// Configure subpass description
|
||||||
auto& desc = spDescs[i];
|
auto& desc = spDescs[i];
|
||||||
desc.pColorAttachments = subpass->colorReferences.data();
|
desc.pColorAttachments = subpass->colorReferences.data();
|
||||||
|
@ -186,8 +203,11 @@ namespace SHADE
|
||||||
|
|
||||||
// Loop through all subpasses again but this time we use the bit field to initialize
|
// Loop through all subpasses again but this time we use the bit field to initialize
|
||||||
// the dependencies.
|
// the dependencies.
|
||||||
for (i = 0; i < subpasses.size(); ++i)
|
for (uint32_t i = 0; auto & subpass : subpasses)
|
||||||
{
|
{
|
||||||
|
if (subpass->HasNoAttachments())
|
||||||
|
continue;
|
||||||
|
|
||||||
vk::PipelineStageFlags srcStage;
|
vk::PipelineStageFlags srcStage;
|
||||||
vk::PipelineStageFlags dstStage;
|
vk::PipelineStageFlags dstStage;
|
||||||
vk::AccessFlags srcAccess;
|
vk::AccessFlags srcAccess;
|
||||||
|
@ -245,6 +265,8 @@ namespace SHADE
|
||||||
|
|
||||||
// initialize input descriptors
|
// initialize input descriptors
|
||||||
subpasses[i]->CreateInputDescriptors();
|
subpasses[i]->CreateInputDescriptors();
|
||||||
|
|
||||||
|
++i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -343,6 +365,7 @@ namespace SHADE
|
||||||
, spDeps{ std::move(rhs.spDeps) }
|
, spDeps{ std::move(rhs.spDeps) }
|
||||||
, nodeComputes{ std::move(rhs.nodeComputes) }
|
, nodeComputes{ std::move(rhs.nodeComputes) }
|
||||||
, name { std::move(rhs.name) }
|
, name { std::move(rhs.name) }
|
||||||
|
, ISelfHandle<SHRenderGraphNode>{std::move(rhs)}
|
||||||
|
|
||||||
{
|
{
|
||||||
rhs.renderpass = {};
|
rhs.renderpass = {};
|
||||||
|
@ -419,7 +442,7 @@ namespace SHADE
|
||||||
return subpass;
|
return subpass;
|
||||||
}
|
}
|
||||||
|
|
||||||
Handle<SHRenderGraphNodeCompute> SHRenderGraphNode::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> SHRenderGraphNode::AddNodeCompute(std::string nodeName, Handle<SHVkShaderModule> computeShaderModule, std::initializer_list<std::string> resources, std::unordered_set<BindingAndSetHash>&& dynamicBufferBindings, uint32_t variableDescCount/* = 0*/, float numWorkGroupScale/* = 1.0f*/) noexcept
|
||||||
{
|
{
|
||||||
// Look for the required resources in the graph
|
// Look for the required resources in the graph
|
||||||
std::vector<Handle<SHRenderGraphResource>> nodeComputeResources{};
|
std::vector<Handle<SHRenderGraphResource>> nodeComputeResources{};
|
||||||
|
@ -435,7 +458,7 @@ namespace SHADE
|
||||||
std::vector<Handle<SHRenderGraphResource>> temp (nodeComputeResources);
|
std::vector<Handle<SHRenderGraphResource>> temp (nodeComputeResources);
|
||||||
|
|
||||||
// Create the subpass compute with the resources
|
// Create the subpass compute with the resources
|
||||||
auto nodeCompute = graphStorage->resourceHub->Create<SHRenderGraphNodeCompute>(std::move(nodeName), graphStorage, computeShaderModule, std::move(nodeComputeResources), std::move (dynamicBufferBindings), nodeComputes.empty());
|
auto nodeCompute = graphStorage->resourceHub->Create<SHRenderGraphNodeCompute>(std::move(nodeName), graphStorage, computeShaderModule, std::move(nodeComputeResources), std::move (dynamicBufferBindings), nodeComputes.empty(), variableDescCount);
|
||||||
nodeComputes.push_back(nodeCompute);
|
nodeComputes.push_back(nodeCompute);
|
||||||
|
|
||||||
for (auto& resource : temp)
|
for (auto& resource : temp)
|
||||||
|
@ -483,6 +506,68 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SHRenderGraphNode::StandaloneConfigureAttDesc(bool isLastNode) noexcept
|
||||||
|
{
|
||||||
|
// key is handle ID, value is final layout.
|
||||||
|
std::unordered_map<uint32_t, vk::ImageLayout> resourceAttFinalLayouts;
|
||||||
|
if (!subpasses.empty())
|
||||||
|
{
|
||||||
|
// We first want to take all resources track their layout as undefined at the start of the node/renderpass
|
||||||
|
for (auto& resource : attResources)
|
||||||
|
{
|
||||||
|
resource->GetInfoTracker()->TrackLayout(GetHandle(), {}, vk::ImageLayout::eUndefined);
|
||||||
|
}
|
||||||
|
|
||||||
|
// attempt to get all final layouts for all resources
|
||||||
|
for (auto& subpass : subpasses)
|
||||||
|
{
|
||||||
|
for (auto& color : subpass->colorReferences)
|
||||||
|
{
|
||||||
|
// If final renderpass and attachment is a COLOR_PRESENT resource, make resource transition to present after last subpass
|
||||||
|
if (isLastNode && (attResources[color.attachment]->resourceTypeFlags & static_cast<uint32_t>(SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR_PRESENT)))
|
||||||
|
resourceAttFinalLayouts[color.attachment] = vk::ImageLayout::ePresentSrcKHR;
|
||||||
|
else
|
||||||
|
resourceAttFinalLayouts[color.attachment] = color.layout;
|
||||||
|
|
||||||
|
attResources[color.attachment]->infoTracker->TrackLayout(GetHandle(), subpass, color.layout);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto& depth : subpass->depthReferences)
|
||||||
|
{
|
||||||
|
resourceAttFinalLayouts[depth.attachment] = depth.layout;
|
||||||
|
attResources[depth.attachment]->infoTracker->TrackLayout(GetHandle(), subpass, depth.layout);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto& input : subpass->inputReferences)
|
||||||
|
{
|
||||||
|
resourceAttFinalLayouts[input.attachment] = input.layout;
|
||||||
|
attResources[input.attachment]->infoTracker->TrackLayout(GetHandle(), subpass, input.layout);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (uint32_t j = 0; j < attachmentDescriptions.size(); ++j)
|
||||||
|
{
|
||||||
|
auto& att = attachmentDescriptions[j];
|
||||||
|
auto& resource = attResources[j];
|
||||||
|
|
||||||
|
// If resource is from another render graph, use the final layout it had when it was last used in that graph. This is initialized in LinkNonOwningResource.
|
||||||
|
// We also want to load the attachment, not "don't care".
|
||||||
|
if (resource->resourceTypeFlags & SHUtilities::ConvertEnum(SH_RENDER_GRAPH_RESOURCE_FLAGS::SHARED) &&
|
||||||
|
graphStorage->nonOwningResourceInitialLayouts.contains(resource.GetId().Raw))
|
||||||
|
{
|
||||||
|
att.initialLayout = graphStorage->nonOwningResourceInitialLayouts.at(resource.GetId().Raw);
|
||||||
|
att.loadOp = vk::AttachmentLoadOp::eLoad;
|
||||||
|
att.stencilLoadOp = vk::AttachmentLoadOp::eLoad;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
att.initialLayout = vk::ImageLayout::eUndefined;
|
||||||
|
|
||||||
|
att.finalLayout = resourceAttFinalLayouts[j];
|
||||||
|
resource->GetInfoTracker()->TrackLayout(GetHandle(), {}, att.finalLayout);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
/*!
|
/*!
|
||||||
|
|
||||||
|
@ -509,14 +594,14 @@ namespace SHADE
|
||||||
// remove attachment reference
|
// remove attachment reference
|
||||||
attachmentDescriptions.erase (attachmentDescriptions.begin() + index);
|
attachmentDescriptions.erase (attachmentDescriptions.begin() + index);
|
||||||
|
|
||||||
|
// erase from mapping as well
|
||||||
|
resourceAttachmentMapping->erase(resourceHandleID);
|
||||||
|
|
||||||
// Remove footprint of attachment from all subpasses as well
|
// Remove footprint of attachment from all subpasses as well
|
||||||
for (auto it = subpasses.begin(); it != subpasses.end(); ++it)
|
for (auto it = subpasses.begin(); it != subpasses.end(); ++it)
|
||||||
{
|
{
|
||||||
// attempt to detach resource from subpass
|
// If the subpass uses the resource, just remove the subpass since the subpass will be invalid
|
||||||
(*it)->DetachResource(resourceName, index);
|
if ((*it)->UsesResource(index))
|
||||||
|
|
||||||
// If the subpass ends up having no attachments after, erase it from the node
|
|
||||||
if ((*it)->HasNoAttachments())
|
|
||||||
{
|
{
|
||||||
// erase from indexing
|
// erase from indexing
|
||||||
subpassIndexing.erase((*it)->GetName());
|
subpassIndexing.erase((*it)->GetName());
|
||||||
|
@ -530,12 +615,32 @@ namespace SHADE
|
||||||
for (uint32_t i = 0; i < subpasses.size(); ++i)
|
for (uint32_t i = 0; i < subpasses.size(); ++i)
|
||||||
subpasses[i]->SetIndex(i);
|
subpasses[i]->SetIndex(i);
|
||||||
|
|
||||||
|
// remove node computes using the resource
|
||||||
|
for (auto it = nodeComputes.begin(); it != nodeComputes.end(); ++it)
|
||||||
|
{
|
||||||
|
if ((*it)->UsesResource(resourceHandleID))
|
||||||
|
{
|
||||||
|
it = nodeComputes.erase(it);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// recompute the barriers for the other computes
|
||||||
|
for (auto it = nodeComputes.begin(); it != nodeComputes.end(); ++it)
|
||||||
|
{
|
||||||
|
if (it == nodeComputes.begin())
|
||||||
|
(*it)->SetFollowingEndRenderpass(true);
|
||||||
|
|
||||||
|
(*it)->InitializeBarriers();
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHRenderGraphNode::Execute(Handle<SHVkCommandBuffer> commandBuffer, Handle<SHVkDescriptorPool> descPool, uint32_t frameIndex) noexcept
|
void SHRenderGraphNode::Execute(Handle<SHVkCommandBuffer> commandBuffer, Handle<SHVkDescriptorPool> descPool, uint32_t frameIndex) noexcept
|
||||||
|
{
|
||||||
|
if (renderpass)
|
||||||
{
|
{
|
||||||
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]);
|
||||||
|
@ -545,7 +650,7 @@ namespace SHADE
|
||||||
subpasses[i]->Execute(commandBuffer, descPool, frameIndex);
|
subpasses[i]->Execute(commandBuffer, descPool, frameIndex);
|
||||||
|
|
||||||
// Go to next subpass if not last subpass
|
// Go to next subpass if not last subpass
|
||||||
if (i != static_cast<uint32_t>(subpasses.size()) - 1u)
|
if (i != static_cast<uint32_t>(subpasses.size()) - 1u && !subpasses[i]->HasNoAttachments())
|
||||||
commandBuffer->NextSubpass();
|
commandBuffer->NextSubpass();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -569,6 +674,7 @@ namespace SHADE
|
||||||
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
|
||||||
{
|
{
|
||||||
|
@ -599,6 +705,77 @@ namespace SHADE
|
||||||
batcher.FinaliseBatches(graphStorage->logicalDevice, descPool, frameIndex);
|
batcher.FinaliseBatches(graphStorage->logicalDevice, descPool, frameIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
/*!
|
||||||
|
|
||||||
|
\brief
|
||||||
|
This function simply appends to the container of VkAttachmentDescription
|
||||||
|
and attResources. It will assume the resource is used standalone in the
|
||||||
|
node and will not account for its usage in other nodes. As such its
|
||||||
|
initialLayout will always be UNDEFINED and its finalLayout will be
|
||||||
|
whatever is calculated if the node is regenerated using
|
||||||
|
StandaloneRegnerate. This function also does not affect the render graph
|
||||||
|
while its running since the 2 containers above have already been copied
|
||||||
|
to the GPU.
|
||||||
|
|
||||||
|
\param resourceName
|
||||||
|
The name of the resource for getting the resource.
|
||||||
|
|
||||||
|
*/
|
||||||
|
/***************************************************************************/
|
||||||
|
void SHRenderGraphNode::RuntimeLinkResource(std::string resourceName) noexcept
|
||||||
|
{
|
||||||
|
// Get new resource
|
||||||
|
Handle<SHRenderGraphResource> newResource = graphStorage->graphResources->at(resourceName);
|
||||||
|
|
||||||
|
// append new resource to container
|
||||||
|
attResources.push_back(newResource);
|
||||||
|
|
||||||
|
attachmentDescriptions.push_back(vk::AttachmentDescription
|
||||||
|
{
|
||||||
|
.format = newResource->GetResourceFormat(),
|
||||||
|
.samples = vk::SampleCountFlagBits::e1,
|
||||||
|
.loadOp = vk::AttachmentLoadOp::eClear,
|
||||||
|
.storeOp = vk::AttachmentStoreOp::eStore,
|
||||||
|
.stencilLoadOp = vk::AttachmentLoadOp::eClear,
|
||||||
|
.stencilStoreOp = vk::AttachmentStoreOp::eStore,
|
||||||
|
});
|
||||||
|
|
||||||
|
resourceAttachmentMapping->try_emplace(newResource.GetId().Raw, attachmentDescriptions.size() - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
Handle<SHSubpass> SHRenderGraphNode::RuntimeAddSubpass(std::string subpassName, Handle<SHViewport> viewport, Handle<SHRenderer> renderer) noexcept
|
||||||
|
{
|
||||||
|
return AddSubpass(std::move (subpassName), viewport, renderer);
|
||||||
|
}
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
/*!
|
||||||
|
|
||||||
|
\brief
|
||||||
|
USE WITH CAUTION because the function does not reevaluate resource
|
||||||
|
layouts in attachment descriptions. All resources here will start at
|
||||||
|
UNDEFINED and end at whatever the last subpass using the attachment
|
||||||
|
specifies. It will also not support render graph node computes given its
|
||||||
|
complexity if it has to be accounted for.
|
||||||
|
|
||||||
|
IN SHORT, IT GENERATES A RENDERPASS AS IF ITS THE ONLY NODE
|
||||||
|
IN THE RENDER GRAPH. SEE NOTES IN SHRenderGraph.h
|
||||||
|
|
||||||
|
This function is mainly meant for nodes that are dynamic (in hindsight,
|
||||||
|
there really should have been a distinction between static and dynamic
|
||||||
|
nodes).
|
||||||
|
|
||||||
|
*/
|
||||||
|
/***************************************************************************/
|
||||||
|
void SHRenderGraphNode::RuntimeStandaloneRegenerate(void) noexcept
|
||||||
|
{
|
||||||
|
StandaloneConfigureAttDesc(false);
|
||||||
|
ConfigureSubpasses();
|
||||||
|
CreateRenderpass();
|
||||||
|
CreateFramebuffer();
|
||||||
|
}
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
/*!
|
/*!
|
||||||
|
|
||||||
|
@ -633,4 +810,15 @@ namespace SHADE
|
||||||
return attResources;
|
return attResources;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Handle<SHRenderGraphNodeCompute> SHRenderGraphNode::GetNodeCompute(std::string nodeComputeName) const noexcept
|
||||||
|
{
|
||||||
|
for (auto nc : nodeComputes)
|
||||||
|
{
|
||||||
|
if (nc->name == nodeComputeName)
|
||||||
|
return nc;
|
||||||
|
}
|
||||||
|
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -93,6 +93,9 @@ namespace SHADE
|
||||||
void CreateFramebuffer(void) noexcept;
|
void CreateFramebuffer(void) noexcept;
|
||||||
void HandleResize (void) noexcept;
|
void HandleResize (void) noexcept;
|
||||||
void ConfigureSubpasses (void) noexcept;
|
void ConfigureSubpasses (void) noexcept;
|
||||||
|
bool DetachResource(std::string const& resourceName, uint64_t resourceHandleID) noexcept;
|
||||||
|
void AddDummySubpassIfNeeded(void) noexcept;
|
||||||
|
void StandaloneConfigureAttDesc (bool isLastNode) noexcept;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
|
@ -106,15 +109,17 @@ namespace SHADE
|
||||||
/* PUBLIC MEMBER FUNCTIONS */
|
/* PUBLIC MEMBER FUNCTIONS */
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
Handle<SHSubpass> AddSubpass(std::string subpassName, Handle<SHViewport> viewport, Handle<SHRenderer> renderer) 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 = {}, uint32_t variableDescCount = 0, float numWorkGroupScale = 1.0f) noexcept;
|
||||||
void AddDummySubpassIfNeeded (void) noexcept;
|
|
||||||
bool DetachResource (std::string const& resourceName, uint64_t resourceHandleID) noexcept;
|
|
||||||
|
|
||||||
// TODO: RemoveSubpass()
|
|
||||||
void Execute(Handle<SHVkCommandBuffer> commandBuffer, Handle<SHVkDescriptorPool> descPool, uint32_t frameIndex) noexcept;
|
void Execute(Handle<SHVkCommandBuffer> commandBuffer, Handle<SHVkDescriptorPool> descPool, uint32_t frameIndex) noexcept;
|
||||||
Handle<SHVkPipeline> GetOrCreatePipeline(std::pair<Handle<SHVkShaderModule>, Handle<SHVkShaderModule>> const& vsFsPair, Handle<SHSubpass> subpass) noexcept;
|
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);
|
||||||
|
|
||||||
|
// Runtime functions that don't affect the renderpass
|
||||||
|
void RuntimeLinkResource(std::string resourceName) noexcept;
|
||||||
|
Handle<SHSubpass> RuntimeAddSubpass(std::string subpassName, Handle<SHViewport> viewport, Handle<SHRenderer> renderer) noexcept;
|
||||||
|
void RuntimeStandaloneRegenerate (void) noexcept;
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
/* SETTERS AND GETTERS */
|
/* SETTERS AND GETTERS */
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
|
@ -122,6 +127,7 @@ namespace SHADE
|
||||||
Handle<SHSubpass> GetSubpass(std::string_view subpassName) const noexcept;
|
Handle<SHSubpass> GetSubpass(std::string_view subpassName) const noexcept;
|
||||||
Handle<SHRenderGraphResource> GetResource (uint32_t resourceIndex) const noexcept;
|
Handle<SHRenderGraphResource> GetResource (uint32_t resourceIndex) const noexcept;
|
||||||
std::vector<Handle<SHRenderGraphResource>> const& GetResources (void) const noexcept;
|
std::vector<Handle<SHRenderGraphResource>> const& GetResources (void) const noexcept;
|
||||||
|
Handle<SHRenderGraphNodeCompute> GetNodeCompute (std::string nodeComputeName) const noexcept;
|
||||||
friend class SHRenderGraph;
|
friend class SHRenderGraph;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,56 @@
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
SHRenderGraphNodeCompute::SHRenderGraphNodeCompute(std::string nodeName, Handle<SHRenderGraphStorage> graphStorage, Handle<SHVkShaderModule> computeShaderModule, std::vector<Handle<SHRenderGraphResource>>&& subpassComputeResources, std::unordered_set<BindingAndSetHash>&& dynamicBufferBindings, bool followingEndRP, float inNumWorkGroupScale/* = 1.0f*/) noexcept
|
|
||||||
|
bool SHRenderGraphNodeCompute::UsesResource(uint64_t resourceHandleID) const noexcept
|
||||||
|
{
|
||||||
|
for (auto& resource : resources)
|
||||||
|
{
|
||||||
|
if (resource.GetId().Raw == resourceHandleID)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHRenderGraphNodeCompute::InitializeBarriers(void) noexcept
|
||||||
|
{
|
||||||
|
for (uint32_t i = 0; auto & barriers : memoryBarriers)
|
||||||
|
{
|
||||||
|
barriers.clear();
|
||||||
|
|
||||||
|
for (auto& resource : resources)
|
||||||
|
{
|
||||||
|
vk::AccessFlags srcAccessMask = (followingEndRenderpass) ? vk::AccessFlagBits::eInputAttachmentRead : (vk::AccessFlagBits::eShaderRead | vk::AccessFlagBits::eShaderWrite);
|
||||||
|
barriers.push_back(vk::ImageMemoryBarrier
|
||||||
|
{
|
||||||
|
.srcAccessMask = srcAccessMask,
|
||||||
|
.dstAccessMask = vk::AccessFlagBits::eShaderRead | vk::AccessFlagBits::eShaderWrite,
|
||||||
|
.oldLayout = vk::ImageLayout::eGeneral,
|
||||||
|
.newLayout = vk::ImageLayout::eGeneral,
|
||||||
|
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
||||||
|
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
||||||
|
.image = resource->GetImage((resource->resourceTypeFlags & static_cast<uint32_t>(SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR_PRESENT)) ? i : 0)->GetVkImage(),
|
||||||
|
.subresourceRange = vk::ImageSubresourceRange
|
||||||
|
{
|
||||||
|
.aspectMask = resource->imageAspectFlags,
|
||||||
|
.baseMipLevel = 0,
|
||||||
|
.levelCount = resource->mipLevels,
|
||||||
|
.baseArrayLayer = 0,
|
||||||
|
.layerCount = 1,
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHRenderGraphNodeCompute::SetFollowingEndRenderpass(uint32_t flag) noexcept
|
||||||
|
{
|
||||||
|
followingEndRenderpass = flag;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
SHRenderGraphNodeCompute::SHRenderGraphNodeCompute(std::string nodeName, Handle<SHRenderGraphStorage> graphStorage, Handle<SHVkShaderModule> computeShaderModule, std::vector<Handle<SHRenderGraphResource>>&& subpassComputeResources, std::unordered_set<BindingAndSetHash>&& dynamicBufferBindings, bool followingEndRP, uint32_t variableDescCount, float inNumWorkGroupScale/* = 1.0f*/) noexcept
|
||||||
: computePipeline{}
|
: computePipeline{}
|
||||||
, pipelineLayout{}
|
, pipelineLayout{}
|
||||||
, resources{}
|
, resources{}
|
||||||
|
@ -68,10 +117,12 @@ namespace SHADE
|
||||||
// check if all layouts are there
|
// check if all layouts are there
|
||||||
if (layouts.size() == descMappings.at(SHPredefinedDescriptorTypes::RENDER_GRAPH_NODE_COMPUTE_RESOURCE) + 1)
|
if (layouts.size() == descMappings.at(SHPredefinedDescriptorTypes::RENDER_GRAPH_NODE_COMPUTE_RESOURCE) + 1)
|
||||||
{
|
{
|
||||||
|
Handle<SHVkDescriptorSetLayout> computeResourceLayout = {};
|
||||||
|
computeResourceLayout = layouts[descMappings.at(SHPredefinedDescriptorTypes::RENDER_GRAPH_NODE_COMPUTE_RESOURCE)];
|
||||||
|
|
||||||
// create compute resources
|
// create compute resources
|
||||||
computeResource = graphStorage->resourceHub->Create<ComputeResource>();
|
computeResource = graphStorage->resourceHub->Create<ComputeResource>();
|
||||||
auto computeResourceLayout = layouts[descMappings.at(SHPredefinedDescriptorTypes::RENDER_GRAPH_NODE_COMPUTE_RESOURCE)];
|
computeResource->descSet = graphStorage->descriptorPool->Allocate({ computeResourceLayout }, {variableDescCount});
|
||||||
computeResource->descSet = graphStorage->descriptorPool->Allocate({ computeResourceLayout }, { 1 });
|
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
for (auto set : computeResource->descSet->GetVkHandle())
|
for (auto set : computeResource->descSet->GetVkHandle())
|
||||||
SET_VK_OBJ_NAME(graphStorage->logicalDevice, vk::ObjectType::eDescriptorSet, set, "[Descriptor Set] " + name + " Resources");
|
SET_VK_OBJ_NAME(graphStorage->logicalDevice, vk::ObjectType::eDescriptorSet, set, "[Descriptor Set] " + name + " Resources");
|
||||||
|
@ -91,6 +142,11 @@ namespace SHADE
|
||||||
|
|
||||||
void SHRenderGraphNodeCompute::Execute(Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex) noexcept
|
void SHRenderGraphNodeCompute::Execute(Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex) noexcept
|
||||||
{
|
{
|
||||||
|
for (auto& fn : preComputeFunctions)
|
||||||
|
{
|
||||||
|
fn (cmdBuffer, frameIndex);
|
||||||
|
}
|
||||||
|
|
||||||
// bind the compute pipeline
|
// bind the compute pipeline
|
||||||
cmdBuffer->BindPipeline(computePipeline);
|
cmdBuffer->BindPipeline(computePipeline);
|
||||||
|
|
||||||
|
@ -157,35 +213,7 @@ namespace SHADE
|
||||||
groupSizeX = maxWidth / workGroupSizeX;
|
groupSizeX = maxWidth / workGroupSizeX;
|
||||||
groupSizeY = maxHeight / workGroupSizeY;
|
groupSizeY = maxHeight / workGroupSizeY;
|
||||||
|
|
||||||
for (uint32_t i = 0; auto& barriers : memoryBarriers)
|
InitializeBarriers();
|
||||||
{
|
|
||||||
barriers.clear();
|
|
||||||
|
|
||||||
for (auto& resource : resources)
|
|
||||||
{
|
|
||||||
vk::AccessFlags srcAccessMask = (followingEndRenderpass) ? vk::AccessFlagBits::eInputAttachmentRead : (vk::AccessFlagBits::eShaderRead | vk::AccessFlagBits::eShaderWrite);
|
|
||||||
barriers.push_back(vk::ImageMemoryBarrier
|
|
||||||
{
|
|
||||||
.srcAccessMask = srcAccessMask,
|
|
||||||
.dstAccessMask = vk::AccessFlagBits::eShaderRead | vk::AccessFlagBits::eShaderWrite,
|
|
||||||
.oldLayout = vk::ImageLayout::eGeneral,
|
|
||||||
.newLayout = vk::ImageLayout::eGeneral,
|
|
||||||
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
|
||||||
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
|
||||||
.image = resource->GetImage((resource->resourceTypeFlags & static_cast<uint32_t>(SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR_PRESENT)) ? i : 0)->GetVkImage(),
|
|
||||||
.subresourceRange = vk::ImageSubresourceRange
|
|
||||||
{
|
|
||||||
.aspectMask = resource->imageAspectFlags,
|
|
||||||
.baseMipLevel = 0,
|
|
||||||
.levelCount = resource->mipLevels,
|
|
||||||
.baseArrayLayer = 0,
|
|
||||||
.layerCount = 1,
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
++i;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHRenderGraphNodeCompute::SetDynamicOffsets(std::span<uint32_t> perFrameSizes) noexcept
|
void SHRenderGraphNodeCompute::SetDynamicOffsets(std::span<uint32_t> perFrameSizes) noexcept
|
||||||
|
@ -219,4 +247,17 @@ namespace SHADE
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SHRenderGraphNodeCompute::ModifyWriteDescImageComputeResource(uint32_t binding, SHVkDescriptorSetGroup::viewSamplerLayout const& viewSamplerLayout, uint32_t descArrayIndex) noexcept
|
||||||
|
{
|
||||||
|
static constexpr uint32_t COMPUTE_RESOURCE_SET_INDEX = 0;
|
||||||
|
computeResource->descSet->ModifyWriteDescImage(COMPUTE_RESOURCE_SET_INDEX, binding, viewSamplerLayout, descArrayIndex);
|
||||||
|
computeResource->descSet->UpdateDescriptorSetImage(COMPUTE_RESOURCE_SET_INDEX, binding, descArrayIndex);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHRenderGraphNodeCompute::AddPreComputeFunction(PreComputeFunction const& fn) noexcept
|
||||||
|
{
|
||||||
|
preComputeFunctions.push_back(fn);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,6 +25,10 @@ namespace SHADE
|
||||||
|
|
||||||
class SHRenderGraphNodeCompute
|
class SHRenderGraphNodeCompute
|
||||||
{
|
{
|
||||||
|
public:
|
||||||
|
using PreComputeFunction = std::function<void(Handle<SHVkCommandBuffer>, uint32_t)>;
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Binding of set SHGraphicsConstants::DescriptorSetIndex::RENDERGRAPH_NODE_COMPUTE_RESOURCE
|
// Binding of set SHGraphicsConstants::DescriptorSetIndex::RENDERGRAPH_NODE_COMPUTE_RESOURCE
|
||||||
struct ComputeResource
|
struct ComputeResource
|
||||||
|
@ -73,8 +77,23 @@ namespace SHADE
|
||||||
//! Name of this node
|
//! Name of this node
|
||||||
std::string name;
|
std::string name;
|
||||||
|
|
||||||
|
std::vector<PreComputeFunction> preComputeFunctions;
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
/*-----------------------------------------------------------------------*/
|
||||||
|
/* PRIVATE MEMBER FUNCTIONS */
|
||||||
|
/*-----------------------------------------------------------------------*/
|
||||||
|
bool UsesResource (uint64_t resourceHandleID) const noexcept;
|
||||||
|
void InitializeBarriers (void) noexcept;
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------------*/
|
||||||
|
/* PRIVATE SETTERS AND GETTERS */
|
||||||
|
/*-----------------------------------------------------------------------*/
|
||||||
|
void SetFollowingEndRenderpass (uint32_t flag) noexcept;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
SHRenderGraphNodeCompute(std::string nodeName, Handle<SHRenderGraphStorage> graphStorage, Handle<SHVkShaderModule> computeShaderModule, std::vector<Handle<SHRenderGraphResource>>&& subpassComputeResources, std::unordered_set<BindingAndSetHash>&& dynamicBufferBindings, bool followingEndRP, float inNumWorkGroupScale = 1.0f) noexcept;
|
SHRenderGraphNodeCompute(std::string nodeName, Handle<SHRenderGraphStorage> graphStorage, Handle<SHVkShaderModule> computeShaderModule, std::vector<Handle<SHRenderGraphResource>>&& subpassComputeResources, std::unordered_set<BindingAndSetHash>&& dynamicBufferBindings, bool followingEndRP, uint32_t variableDescCount, float inNumWorkGroupScale = 1.0f) noexcept;
|
||||||
|
|
||||||
void Execute (Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex) noexcept;
|
void Execute (Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex) noexcept;
|
||||||
void HandleResize (void) noexcept;
|
void HandleResize (void) noexcept;
|
||||||
|
@ -84,7 +103,9 @@ namespace SHADE
|
||||||
|
|
||||||
void ModifyWriteDescBufferComputeResource (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 binding, std::span<SHVkDescriptorSetGroup::viewSamplerLayout> const& viewSamplerLayouts) noexcept;
|
void ModifyWriteDescImageComputeResource(uint32_t binding, std::span<SHVkDescriptorSetGroup::viewSamplerLayout> const& viewSamplerLayouts) noexcept;
|
||||||
|
void ModifyWriteDescImageComputeResource(uint32_t binding, SHVkDescriptorSetGroup::viewSamplerLayout const& viewSamplerLayout, uint32_t descArrayIndex) noexcept;
|
||||||
|
|
||||||
|
void AddPreComputeFunction (PreComputeFunction const& fn) noexcept;
|
||||||
|
|
||||||
friend class SHRenderGraph;
|
friend class SHRenderGraph;
|
||||||
friend class SHRenderGraphNode;
|
friend class SHRenderGraphNode;
|
||||||
|
|
|
@ -78,7 +78,7 @@ namespace SHADE
|
||||||
|
|
||||||
*/
|
*/
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
SHRenderGraphResource::SHRenderGraphResource(Handle<SHRenderGraphStorage> renderGraphStorage, std::string const& name, std::initializer_list<SH_RENDER_GRAPH_RESOURCE_FLAGS> typeFlags, vk::Format format, uint32_t w, uint32_t h, uint8_t levels, vk::ImageUsageFlagBits usageFlags, vk::ImageCreateFlagBits createFlags) noexcept
|
SHRenderGraphResource::SHRenderGraphResource(Handle<SHRenderGraphStorage> renderGraphStorage, std::string const& name, std::initializer_list<SH_RENDER_GRAPH_RESOURCE_FLAGS> typeFlags, vk::Format format, uint32_t w, uint32_t h, uint8_t levels, vk::ImageUsageFlagBits usageFlags, vk::ImageCreateFlagBits createFlags, bool inResizeWithWindow) noexcept
|
||||||
: graphStorage{renderGraphStorage}
|
: graphStorage{renderGraphStorage}
|
||||||
, resourceTypeFlags{ }
|
, resourceTypeFlags{ }
|
||||||
, resourceFormat{ format }
|
, resourceFormat{ format }
|
||||||
|
@ -88,6 +88,7 @@ namespace SHADE
|
||||||
, height{ h }
|
, height{ h }
|
||||||
, mipLevels{ levels }
|
, mipLevels{ levels }
|
||||||
, resourceName{ name }
|
, resourceName{ name }
|
||||||
|
, resizeWithWindow { inResizeWithWindow }
|
||||||
{
|
{
|
||||||
// If the resource type is an arbitrary image and not swapchain image
|
// If the resource type is an arbitrary image and not swapchain image
|
||||||
if (typeFlags.size() == 1 && *typeFlags.begin() == SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR_PRESENT)
|
if (typeFlags.size() == 1 && *typeFlags.begin() == SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR_PRESENT)
|
||||||
|
@ -210,6 +211,7 @@ namespace SHADE
|
||||||
, imageAspectFlags{ rhs.imageAspectFlags }
|
, imageAspectFlags{ rhs.imageAspectFlags }
|
||||||
, graphStorage{rhs.graphStorage}
|
, graphStorage{rhs.graphStorage}
|
||||||
, infoTracker {std::move (rhs.infoTracker)}
|
, infoTracker {std::move (rhs.infoTracker)}
|
||||||
|
, resizeWithWindow{rhs.resizeWithWindow}
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -242,7 +244,8 @@ namespace SHADE
|
||||||
mipLevels = rhs.mipLevels;
|
mipLevels = rhs.mipLevels;
|
||||||
imageAspectFlags = rhs.imageAspectFlags;
|
imageAspectFlags = rhs.imageAspectFlags;
|
||||||
graphStorage = rhs.graphStorage;
|
graphStorage = rhs.graphStorage;
|
||||||
infoTracker = std::move(infoTracker);
|
infoTracker = std::move(rhs.infoTracker);
|
||||||
|
resizeWithWindow = rhs.resizeWithWindow;
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
|
@ -96,11 +96,14 @@ namespace SHADE
|
||||||
//! For tracking resource states in stages of the render graphs
|
//! For tracking resource states in stages of the render graphs
|
||||||
Handle<InfoTracker> infoTracker;
|
Handle<InfoTracker> infoTracker;
|
||||||
|
|
||||||
|
//! Whether or not to resize (recreate vulkan image) when window resizes
|
||||||
|
bool resizeWithWindow;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
/* CTORS AND DTORS */
|
/* CTORS AND DTORS */
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
SHRenderGraphResource(Handle<SHRenderGraphStorage> renderGraphStorage, std::string const& name, std::initializer_list<SH_RENDER_GRAPH_RESOURCE_FLAGS> typeFlags, vk::Format format, uint32_t w, uint32_t h, uint8_t levels, vk::ImageUsageFlagBits usageFlags, vk::ImageCreateFlagBits createFlags) noexcept;
|
SHRenderGraphResource(Handle<SHRenderGraphStorage> renderGraphStorage, std::string const& name, std::initializer_list<SH_RENDER_GRAPH_RESOURCE_FLAGS> typeFlags, vk::Format format, uint32_t w, uint32_t h, uint8_t levels, vk::ImageUsageFlagBits usageFlags, vk::ImageCreateFlagBits createFlags, bool inResizeWithWindow) noexcept;
|
||||||
SHRenderGraphResource(SHRenderGraphResource&& rhs) noexcept;
|
SHRenderGraphResource(SHRenderGraphResource&& rhs) noexcept;
|
||||||
SHRenderGraphResource& operator=(SHRenderGraphResource&& rhs) noexcept;
|
SHRenderGraphResource& operator=(SHRenderGraphResource&& rhs) noexcept;
|
||||||
~SHRenderGraphResource(void) noexcept;
|
~SHRenderGraphResource(void) noexcept;
|
||||||
|
|
|
@ -77,6 +77,7 @@ namespace SHADE
|
||||||
, name { rhs.name }
|
, name { rhs.name }
|
||||||
, viewport {rhs.viewport}
|
, viewport {rhs.viewport}
|
||||||
, renderer {rhs.renderer}
|
, renderer {rhs.renderer}
|
||||||
|
, companionSubpass {rhs.companionSubpass}
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -113,6 +114,7 @@ namespace SHADE
|
||||||
name = std::move(rhs.name);
|
name = std::move(rhs.name);
|
||||||
renderer = rhs.renderer;
|
renderer = rhs.renderer;
|
||||||
viewport = rhs.viewport;
|
viewport = rhs.viewport;
|
||||||
|
companionSubpass = rhs.companionSubpass;
|
||||||
|
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
|
@ -162,7 +164,7 @@ namespace SHADE
|
||||||
switch (attachmentDescriptionType)
|
switch (attachmentDescriptionType)
|
||||||
{
|
{
|
||||||
case SH_RENDER_GRAPH_RESOURCE_FLAGS::DEPTH:
|
case SH_RENDER_GRAPH_RESOURCE_FLAGS::DEPTH:
|
||||||
imageLayout = vk::ImageLayout::eDepthAttachmentOptimal;
|
imageLayout = vk::ImageLayout::eDepthStencilAttachmentOptimal;
|
||||||
break;
|
break;
|
||||||
case SH_RENDER_GRAPH_RESOURCE_FLAGS::STENCIL:
|
case SH_RENDER_GRAPH_RESOURCE_FLAGS::STENCIL:
|
||||||
imageLayout = vk::ImageLayout::eStencilAttachmentOptimal;
|
imageLayout = vk::ImageLayout::eStencilAttachmentOptimal;
|
||||||
|
@ -211,6 +213,8 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
commandBuffer->BeginLabeledSegment(name);
|
commandBuffer->BeginLabeledSegment(name);
|
||||||
|
|
||||||
|
if (!HasNoAttachments())
|
||||||
|
{
|
||||||
// Ensure correct transforms are provided
|
// Ensure correct transforms are provided
|
||||||
superBatch->UpdateBuffers(frameIndex, descPool);
|
superBatch->UpdateBuffers(frameIndex, descPool);
|
||||||
|
|
||||||
|
@ -227,8 +231,19 @@ namespace SHADE
|
||||||
if (renderer)
|
if (renderer)
|
||||||
renderer->BindDescriptorSet(commandBuffer, SH_PIPELINE_TYPE::GRAPHICS, descMappings.at(SHPredefinedDescriptorTypes::CAMERA), frameIndex);
|
renderer->BindDescriptorSet(commandBuffer, SH_PIPELINE_TYPE::GRAPHICS, descMappings.at(SHPredefinedDescriptorTypes::CAMERA), frameIndex);
|
||||||
|
|
||||||
|
// If companion subpass is not a valid handle, render super batch normally
|
||||||
|
if (!companionSubpass.companion)
|
||||||
|
{
|
||||||
// Draw all the batches
|
// Draw all the batches
|
||||||
superBatch->Draw(commandBuffer, frameIndex);
|
superBatch->Draw(commandBuffer, frameIndex);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// if not bind pipeline for companion and and execute draw command
|
||||||
|
commandBuffer->BindPipeline(companionSubpass.pipeline);
|
||||||
|
companionSubpass.companion->superBatch->Draw(commandBuffer, frameIndex, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Draw all the exterior draw calls
|
// Draw all the exterior draw calls
|
||||||
for (auto& drawCall : exteriorDrawCalls)
|
for (auto& drawCall : exteriorDrawCalls)
|
||||||
|
@ -265,43 +280,27 @@ namespace SHADE
|
||||||
|
|
||||||
*/
|
*/
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
void SHSubpass::DetachResource(std::string const& resourceName, uint32_t attachmentIndex) noexcept
|
bool SHSubpass::UsesResource(uint32_t attachmentIndex) noexcept
|
||||||
{
|
{
|
||||||
for (uint32_t i = 0; i < colorReferences.size(); ++i)
|
for (uint32_t i = 0; i < colorReferences.size(); ++i)
|
||||||
{
|
{
|
||||||
if (colorReferences[i].attachment == attachmentIndex)
|
if (colorReferences[i].attachment == attachmentIndex)
|
||||||
{
|
return true;
|
||||||
colorReferences.erase (colorReferences.begin() + i);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (uint32_t i = 0; i < depthReferences.size(); ++i)
|
for (uint32_t i = 0; i < depthReferences.size(); ++i)
|
||||||
{
|
{
|
||||||
if (depthReferences[i].attachment == attachmentIndex)
|
if (depthReferences[i].attachment == attachmentIndex)
|
||||||
{
|
return true;
|
||||||
depthReferences.erase(depthReferences.begin() + i);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (uint32_t i = 0; i < inputReferences.size(); ++i)
|
for (uint32_t i = 0; i < inputReferences.size(); ++i)
|
||||||
{
|
{
|
||||||
if (inputReferences[i].attachment == attachmentIndex)
|
if (inputReferences[i].attachment == attachmentIndex)
|
||||||
{
|
return true;
|
||||||
inputReferences.erase(inputReferences.begin() + i);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (uint32_t i = 0; i < inputNames.size(); ++i)
|
return false;
|
||||||
{
|
|
||||||
if (inputNames[i] == resourceName)
|
|
||||||
{
|
|
||||||
inputNames.erase(inputNames.begin() + i);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SHSubpass::HasNoAttachments(void) const noexcept
|
bool SHSubpass::HasNoAttachments(void) const noexcept
|
||||||
|
@ -458,6 +457,12 @@ namespace SHADE
|
||||||
subpassIndex = index;
|
subpassIndex = index;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SHSubpass::SetCompanionSubpass(Handle<SHSubpass> companion, Handle<SHVkPipeline> pipeline) noexcept
|
||||||
|
{
|
||||||
|
companionSubpass.companion = companion;
|
||||||
|
companionSubpass.pipeline = pipeline;
|
||||||
|
}
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
/*!
|
/*!
|
||||||
|
|
||||||
|
|
|
@ -21,12 +21,23 @@ namespace SHADE
|
||||||
class SHVkSampler;
|
class SHVkSampler;
|
||||||
class SHRenderer;
|
class SHRenderer;
|
||||||
class SHViewport;
|
class SHViewport;
|
||||||
|
class SHVkPipeline;
|
||||||
|
|
||||||
class SH_API SHSubpass : public ISelfHandle<SHSubpass>
|
class SH_API SHSubpass : public ISelfHandle<SHSubpass>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
using ExteriorDrawCallFunction = std::function<void(Handle<SHVkCommandBuffer>, Handle<SHRenderer>, uint32_t)>;
|
using ExteriorDrawCallFunction = std::function<void(Handle<SHVkCommandBuffer>, Handle<SHRenderer>, uint32_t)>;
|
||||||
|
|
||||||
|
// Allows for subpasses to run using a companions data
|
||||||
|
struct CompanionSubpass
|
||||||
|
{
|
||||||
|
// subpass whose data will be borrowed to draw
|
||||||
|
Handle<SHSubpass> companion;
|
||||||
|
|
||||||
|
// Pipeline that will be used for all the draw calls from all batches of the companion subpass
|
||||||
|
Handle<SHVkPipeline> pipeline;
|
||||||
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/*---------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------*/
|
||||||
/* PRIVATE MEMBER VARIABLES */
|
/* PRIVATE MEMBER VARIABLES */
|
||||||
|
@ -94,6 +105,15 @@ namespace SHADE
|
||||||
// For identifying subpasses
|
// For identifying subpasses
|
||||||
std::string name;
|
std::string name;
|
||||||
|
|
||||||
|
//! Optional component to a companion subpass. If the subpass handle of this object
|
||||||
|
//! is valid, the subpass will be drawn using this companion's data.
|
||||||
|
CompanionSubpass companionSubpass;
|
||||||
|
|
||||||
|
private:
|
||||||
|
/*-----------------------------------------------------------------------*/
|
||||||
|
/* PRIVATE MEMBER FUNCTIONS */
|
||||||
|
/*-----------------------------------------------------------------------*/
|
||||||
|
bool UsesResource(uint32_t attachmentIndex) noexcept;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
|
@ -119,7 +139,6 @@ namespace SHADE
|
||||||
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 BindInputDescriptorSets (Handle<SHVkCommandBuffer> cmdBuffer, uint32_t setIndex, 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;
|
bool HasNoAttachments (void) const noexcept;
|
||||||
|
|
||||||
void Init(SHResourceHub& resourceManager) noexcept;
|
void Init(SHResourceHub& resourceManager) noexcept;
|
||||||
|
@ -128,13 +147,18 @@ namespace SHADE
|
||||||
void CreateInputDescriptors (void) noexcept;
|
void CreateInputDescriptors (void) noexcept;
|
||||||
void UpdateWriteDescriptors (void) noexcept;
|
void UpdateWriteDescriptors (void) noexcept;
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------*/
|
|
||||||
/* GETTERS AND SETTERS */
|
|
||||||
/*-----------------------------------------------------------------------*/
|
|
||||||
private:
|
private:
|
||||||
|
/*-----------------------------------------------------------------------*/
|
||||||
|
/* PRIVATE GETTERS AND SETTERS */
|
||||||
|
/*-----------------------------------------------------------------------*/
|
||||||
void SetIndex (uint32_t index) noexcept;
|
void SetIndex (uint32_t index) noexcept;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
/*-----------------------------------------------------------------------*/
|
||||||
|
/* PUBLIC SETTERS AND GETTERS */
|
||||||
|
/*-----------------------------------------------------------------------*/
|
||||||
|
void SetCompanionSubpass (Handle<SHSubpass> companion, Handle<SHVkPipeline> pipeline) noexcept;
|
||||||
|
|
||||||
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;
|
||||||
|
|
Loading…
Reference in New Issue