Implemented scanline and silhouette effect #363
|
@ -0,0 +1,8 @@
|
|||
- VertexShader: 37048829
|
||||
FragmentShader: 45685219
|
||||
SubPass: G-Buffer Write
|
||||
Properties:
|
||||
data.color: {x: 1, y: 1, z: 1, w: 1}
|
||||
data.textureIndex: 57342922
|
||||
data.alpha: 0
|
||||
data.beta: {x: 1, y: 1, z: 1}
|
|
@ -0,0 +1,3 @@
|
|||
Name: ShinyHightlight
|
||||
ID: 122370915
|
||||
Type: 7
|
|
@ -0,0 +1,8 @@
|
|||
- VertexShader: 38847805
|
||||
FragmentShader: 42962441
|
||||
SubPass: Object VFX Subpass No Depth
|
||||
Properties:
|
||||
data.color: {x: 1, y: 1, z: 1, w: 1}
|
||||
data.textureIndex: 0
|
||||
data.alpha: 0
|
||||
data.beta: {x: 1, y: 1, z: 1}
|
|
@ -0,0 +1,3 @@
|
|||
Name: Silhouette
|
||||
ID: 126391182
|
||||
Type: 7
|
|
@ -8599,7 +8599,7 @@
|
|||
IsActive: true
|
||||
Renderable Component:
|
||||
Mesh: 136892700
|
||||
Material: 131956078
|
||||
Material: 122370915
|
||||
IsActive: true
|
||||
RigidBody Component:
|
||||
Type: Dynamic
|
||||
|
@ -9594,6 +9594,9 @@
|
|||
Text: My name is Brandon.
|
||||
Font: 176667660
|
||||
IsActive: true
|
||||
UI Component:
|
||||
Canvas ID: 199
|
||||
IsActive: true
|
||||
Scripts: ~
|
||||
- EID: 206
|
||||
Name: Timer
|
||||
|
@ -9609,6 +9612,9 @@
|
|||
Text: My name is Brandon.
|
||||
Font: 176667660
|
||||
IsActive: true
|
||||
UI Component:
|
||||
Canvas ID: 199
|
||||
IsActive: true
|
||||
Scripts: ~
|
||||
- EID: 139
|
||||
Name: Multiplier
|
||||
|
@ -9624,6 +9630,9 @@
|
|||
Text: TEST
|
||||
Font: 176667660
|
||||
IsActive: true
|
||||
UI Component:
|
||||
Canvas ID: 199
|
||||
IsActive: true
|
||||
Scripts: ~
|
||||
- EID: 11
|
||||
Name: GamePause
|
||||
|
|
|
@ -26,6 +26,7 @@ layout(set = 3, binding = 3, r32ui) uniform uimage2D lightLayerData;
|
|||
layout(set = 3, binding = 4, r8) uniform image2D ssaoBlurredImage;
|
||||
layout(set = 3, binding = 5, rgba8) uniform image2D positionWorldSpace;
|
||||
layout(set = 3, binding = 6, rgba8) uniform image2D targetImage;
|
||||
layout(set = 3, binding = 7, rgba8) uniform image2D objectVFXImage;
|
||||
|
||||
layout (set = 4, binding = 0) uniform sampler2D shadowMaps[]; // for textures (global)
|
||||
|
||||
|
@ -141,6 +142,9 @@ void main()
|
|||
float ssaoVal = imageLoad (ssaoBlurredImage, globalThread).r;
|
||||
fragColor *= ssaoVal;
|
||||
|
||||
vec4 objectVFXColor = imageLoad (objectVFXImage, globalThread);
|
||||
fragColor += objectVFXColor.rgb * objectVFXColor.a;
|
||||
|
||||
// store result into result image
|
||||
imageStore(targetImage, ivec2(gl_GlobalInvocationID.xy), vec4(fragColor.rgb, 1.0f));
|
||||
|
||||
|
|
Binary file not shown.
|
@ -0,0 +1,97 @@
|
|||
#version 450
|
||||
#extension GL_ARB_separate_shader_objects : enable
|
||||
#extension GL_ARB_shading_language_420pack : enable
|
||||
#extension GL_EXT_nonuniform_qualifier : require
|
||||
|
||||
struct MatPropData
|
||||
{
|
||||
int textureIndex;
|
||||
float highlightPosition;
|
||||
};
|
||||
|
||||
struct GenericData
|
||||
{
|
||||
//! Delta time
|
||||
float dt;
|
||||
|
||||
//! Elapsed time of the application
|
||||
float elapsedTime;
|
||||
|
||||
//! Viewport width of the scene (excluding imgui, that means smaller than window)
|
||||
uint viewportWidth;
|
||||
|
||||
//! Ditto but for height
|
||||
uint viewportHeight;
|
||||
};
|
||||
|
||||
|
||||
layout(location = 0) in struct
|
||||
{
|
||||
vec4 vertPos; // location 0
|
||||
vec2 uv; // location = 1
|
||||
vec4 normal; // location = 2
|
||||
vec4 worldPos; // location = 3
|
||||
} In;
|
||||
|
||||
// material stuff
|
||||
layout(location = 4) flat in struct
|
||||
{
|
||||
int materialIndex;
|
||||
uint eid;
|
||||
uint lightLayerIndex;
|
||||
vec3 screenSpacePos;
|
||||
|
||||
} In2;
|
||||
|
||||
layout (set = 0, binding = 0) uniform GenericDataBuffer
|
||||
{
|
||||
GenericData data;
|
||||
} genericDataBuffer;
|
||||
|
||||
layout (set = 0, binding = 1) uniform sampler2D textures[]; // for textures (global)
|
||||
layout (std430, set = 2, binding = 0) buffer MaterialProperties // For materials
|
||||
{
|
||||
MatPropData data[];
|
||||
} MatProp;
|
||||
|
||||
layout(location = 0) out vec4 position;
|
||||
layout(location = 1) out uint outEntityID;
|
||||
layout(location = 2) out uint lightLayerIndices;
|
||||
layout(location = 3) out vec4 normals;
|
||||
layout(location = 4) out vec4 albedo;
|
||||
layout(location = 5) out vec4 worldSpacePosition;
|
||||
layout(location = 6) out vec4 objectVFX;
|
||||
|
||||
float map (float value, float srcLow, float srcHigh, float dstLow, float dstHigh)
|
||||
{
|
||||
return dstLow + (value - srcLow) * (dstHigh - dstLow) / (srcHigh - srcLow);
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
position = In.vertPos;
|
||||
normals = In.normal;
|
||||
albedo = texture(textures[nonuniformEXT(MatProp.data[In2.materialIndex].textureIndex)], In.uv);
|
||||
worldSpacePosition = In.worldPos;
|
||||
|
||||
outEntityID = In2.eid;
|
||||
lightLayerIndices = In2.lightLayerIndex;
|
||||
|
||||
float vpHeight = (float (In2.screenSpacePos.y) - (genericDataBuffer.data.elapsedTime * 4000.0f * (1.0f - In2.screenSpacePos.z)));
|
||||
vpHeight = float (int (vpHeight) % genericDataBuffer.data.viewportHeight);
|
||||
float scanlineScale = 2500.0f * (1.0f - In2.screenSpacePos.z);
|
||||
|
||||
float lowerLimit = vpHeight - scanlineScale;
|
||||
float upperLimit = vpHeight + scanlineScale;
|
||||
if (gl_FragCoord.y > lowerLimit && gl_FragCoord.y < upperLimit)
|
||||
{
|
||||
float opacity = 0.0f;
|
||||
opacity = map (abs (gl_FragCoord.y - vpHeight), 0.0f, upperLimit - vpHeight, 0.0f, 1.0f);
|
||||
opacity = 1.0f - clamp (opacity, 0.0f, 1.0f);
|
||||
|
||||
|
||||
objectVFX = vec4(opacity);
|
||||
}
|
||||
else
|
||||
objectVFX = vec4(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
}
|
Binary file not shown.
|
@ -0,0 +1,3 @@
|
|||
Name: ShinyHighlight_FS
|
||||
ID: 45685219
|
||||
Type: 2
|
|
@ -0,0 +1,99 @@
|
|||
#version 450
|
||||
#extension GL_KHR_vulkan_glsl : enable
|
||||
|
||||
layout(location = 0) in vec3 aVertexPos;
|
||||
layout(location = 1) in vec2 aUV;
|
||||
layout(location = 2) in vec3 aNormal;
|
||||
layout(location = 3) in vec3 aTangent;
|
||||
layout(location = 4) in mat4 worldTransform;
|
||||
layout(location = 8) in uvec2 integerData;
|
||||
layout(location = 9) in uvec4 aBoneIndices;
|
||||
layout(location = 10) in vec4 aBoneWeights;
|
||||
layout(location = 11) in uint firstBoneIndex;
|
||||
|
||||
layout(location = 0) out struct
|
||||
{
|
||||
vec4 vertPos; // location 0
|
||||
vec2 uv; // location = 1
|
||||
vec4 normal; // location = 2
|
||||
vec4 worldPos; // location = 3
|
||||
|
||||
} Out;
|
||||
|
||||
struct GenericData
|
||||
{
|
||||
//! Delta time
|
||||
float dt;
|
||||
|
||||
//! Elapsed time of the application
|
||||
float elapsedTime;
|
||||
|
||||
//! Viewport width of the scene (excluding imgui, that means smaller than window)
|
||||
uint viewportWidth;
|
||||
|
||||
//! Ditto but for height
|
||||
uint viewportHeight;
|
||||
};
|
||||
|
||||
// material stuff
|
||||
layout(location = 4) out struct
|
||||
{
|
||||
int materialIndex;
|
||||
uint eid;
|
||||
uint lightLayerIndex;
|
||||
vec3 screenSpacePos;
|
||||
|
||||
|
||||
} Out2;
|
||||
|
||||
layout(set = 1, binding = 0) uniform CameraData
|
||||
{
|
||||
vec4 position;
|
||||
mat4 vpMat;
|
||||
mat4 viewMat;
|
||||
mat4 projMat;
|
||||
} cameraData;
|
||||
|
||||
layout (set = 0, binding = 0) uniform GenericDataBuffer
|
||||
{
|
||||
GenericData data;
|
||||
} genericDataBuffer;
|
||||
|
||||
void main()
|
||||
{
|
||||
Out2.materialIndex = gl_InstanceIndex;
|
||||
Out2.eid = integerData[0];
|
||||
Out2.lightLayerIndex = integerData[1];
|
||||
|
||||
// for transforming gBuffer position and normal data
|
||||
mat4 modelViewMat = cameraData.viewMat * worldTransform;
|
||||
|
||||
// gBuffer position will be in view space
|
||||
Out.vertPos = modelViewMat * vec4(aVertexPos, 1.0f);
|
||||
|
||||
Out.worldPos = worldTransform * vec4 (aVertexPos, 1.0f);
|
||||
|
||||
// uvs for texturing in fragment shader
|
||||
Out.uv = aUV;
|
||||
|
||||
mat3 transposeInv = mat3 (transpose(inverse(modelViewMat)));
|
||||
|
||||
// normals are also in view space
|
||||
Out.normal.rgb = transposeInv * aNormal.rgb;
|
||||
Out.normal.rgb = normalize (Out.normal.rgb);
|
||||
|
||||
// Get center of object in world position
|
||||
vec4 worldPos = vec4(worldTransform[3][0], worldTransform[3][1], worldTransform[3][2], 1.0f);
|
||||
|
||||
// transform to clip space
|
||||
worldPos = cameraData.vpMat * worldPos;
|
||||
worldPos.xyz /= worldPos.w;
|
||||
|
||||
// transform to screen space
|
||||
worldPos.xy = ((worldPos.xy + vec2(1.0f)) * vec2 (0.5f)) * vec2 (genericDataBuffer.data.viewportWidth, genericDataBuffer.data.viewportHeight);
|
||||
|
||||
Out2.screenSpacePos = worldPos.xyz;
|
||||
|
||||
// clip space for rendering
|
||||
gl_Position = cameraData.vpMat * worldTransform * vec4 (aVertexPos, 1.0f);
|
||||
}
|
Binary file not shown.
|
@ -0,0 +1,3 @@
|
|||
Name: ShinyHighlight_VS
|
||||
ID: 37048829
|
||||
Type: 2
|
|
@ -0,0 +1,67 @@
|
|||
#version 450
|
||||
#extension GL_ARB_separate_shader_objects : enable
|
||||
#extension GL_ARB_shading_language_420pack : enable
|
||||
#extension GL_EXT_nonuniform_qualifier : require
|
||||
|
||||
struct MatPropData
|
||||
{
|
||||
vec4 color;
|
||||
};
|
||||
|
||||
struct GenericData
|
||||
{
|
||||
//! Delta time
|
||||
float dt;
|
||||
|
||||
//! Elapsed time of the application
|
||||
float elapsedTime;
|
||||
|
||||
//! Viewport width of the scene (excluding imgui, that means smaller than window)
|
||||
uint viewportWidth;
|
||||
|
||||
//! Ditto but for height
|
||||
uint viewportHeight;
|
||||
};
|
||||
|
||||
layout(location = 0) in struct
|
||||
{
|
||||
vec4 vertPos; // location 0
|
||||
vec2 uv; // location = 1
|
||||
vec4 normal; // location = 2
|
||||
vec4 worldPos; // location = 3
|
||||
} In;
|
||||
|
||||
// material stuff
|
||||
layout(location = 4) flat in struct
|
||||
{
|
||||
int materialIndex;
|
||||
uint eid;
|
||||
uint lightLayerIndex;
|
||||
} In2;
|
||||
|
||||
layout (set = 0, binding = 1) uniform sampler2D textures[]; // for textures (global)
|
||||
layout (std430, set = 2, binding = 0) buffer MaterialProperties // For materials
|
||||
{
|
||||
MatPropData data[];
|
||||
} MatProp;
|
||||
|
||||
layout (set = 0, binding = 0) uniform GenericDataBuffer
|
||||
{
|
||||
GenericData data;
|
||||
} genericDataBuffer;
|
||||
|
||||
layout(location = 0) out vec4 objectVFX;
|
||||
layout(input_attachment_index = 0, set = 3, binding = 0) uniform subpassInput depthBuffer;
|
||||
|
||||
void main()
|
||||
{
|
||||
// Sample depth buffer using UV and save it
|
||||
float currentDepth = subpassLoad (depthBuffer).r;
|
||||
|
||||
// Use depth buffer to check against current fragment's depth. If fragment is behind depth buffer, render fragment.
|
||||
if (currentDepth > gl_FragCoord.z)
|
||||
discard;
|
||||
|
||||
objectVFX = MatProp.data[In2.materialIndex].color;
|
||||
|
||||
}
|
Binary file not shown.
|
@ -0,0 +1,3 @@
|
|||
Name: Silhouette_FS
|
||||
ID: 42962441
|
||||
Type: 2
|
|
@ -0,0 +1,68 @@
|
|||
#version 450
|
||||
#extension GL_KHR_vulkan_glsl : enable
|
||||
|
||||
//#include "ShaderDescriptorDefinitions.glsl"
|
||||
|
||||
|
||||
layout(location = 0) in vec3 aVertexPos;
|
||||
layout(location = 1) in vec2 aUV;
|
||||
layout(location = 2) in vec3 aNormal;
|
||||
layout(location = 3) in vec3 aTangent;
|
||||
layout(location = 4) in mat4 worldTransform;
|
||||
layout(location = 8) in uvec2 integerData;
|
||||
layout(location = 9) in uvec4 aBoneIndices;
|
||||
layout(location = 10) in vec4 aBoneWeights;
|
||||
layout(location = 11) in uint firstBoneIndex;
|
||||
|
||||
layout(location = 0) out struct
|
||||
{
|
||||
vec4 vertPos; // location 0
|
||||
vec2 uv; // location = 1
|
||||
vec4 normal; // location = 2
|
||||
vec4 worldPos; // location = 3
|
||||
|
||||
} Out;
|
||||
|
||||
// material stuff
|
||||
layout(location = 4) out struct
|
||||
{
|
||||
int materialIndex;
|
||||
uint eid;
|
||||
uint lightLayerIndex;
|
||||
|
||||
} Out2;
|
||||
|
||||
layout(set = 1, binding = 0) uniform CameraData
|
||||
{
|
||||
vec4 position;
|
||||
mat4 vpMat;
|
||||
mat4 viewMat;
|
||||
mat4 projMat;
|
||||
} cameraData;
|
||||
|
||||
void main()
|
||||
{
|
||||
Out2.materialIndex = gl_InstanceIndex;
|
||||
Out2.eid = integerData[0];
|
||||
Out2.lightLayerIndex = integerData[1];
|
||||
|
||||
// for transforming gBuffer position and normal data
|
||||
mat4 modelViewMat = cameraData.viewMat * worldTransform;
|
||||
|
||||
// gBuffer position will be in view space
|
||||
Out.vertPos = modelViewMat * vec4(aVertexPos, 1.0f);
|
||||
|
||||
Out.worldPos = worldTransform * vec4 (aVertexPos, 1.0f);
|
||||
|
||||
// uvs for texturing in fragment shader
|
||||
Out.uv = aUV;
|
||||
|
||||
mat3 transposeInv = mat3 (transpose(inverse(modelViewMat)));
|
||||
|
||||
// normals are also in view space
|
||||
Out.normal.rgb = transposeInv * aNormal.rgb;
|
||||
Out.normal.rgb = normalize (Out.normal.rgb);
|
||||
|
||||
// clip space for rendering
|
||||
gl_Position = cameraData.vpMat * worldTransform * vec4 (aVertexPos, 1.0f);
|
||||
}
|
Binary file not shown.
|
@ -0,0 +1,3 @@
|
|||
Name: Silhouette_VS
|
||||
ID: 38847805
|
||||
Type: 2
|
|
@ -3,7 +3,7 @@
|
|||
#extension GL_ARB_shading_language_420pack : enable
|
||||
#extension GL_EXT_nonuniform_qualifier : require
|
||||
|
||||
layout (input_attachment_index = 0, set = 0, binding = 0) uniform subpassInput sceneTexture;
|
||||
layout (input_attachment_index = 0, set = 3, binding = 0) uniform subpassInput sceneTexture;
|
||||
|
||||
|
||||
layout(location = 0) out vec4 fragColor;
|
||||
|
|
Binary file not shown.
|
@ -0,0 +1,20 @@
|
|||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
struct SHCompileAssetEvent
|
||||
{
|
||||
//! Name of the asset (where applicable)
|
||||
std::string assetName;
|
||||
|
||||
//! asset ID of the asset
|
||||
AssetID assetID;
|
||||
|
||||
//! type of the asset
|
||||
AssetType assetType;
|
||||
};
|
||||
}
|
||||
|
|
@ -11,6 +11,7 @@
|
|||
#include "SHpch.h"
|
||||
#include "SHShaderSourceCompiler.h"
|
||||
#include "shaderc/shaderc.hpp"
|
||||
#include "Events/SHEventManager.hpp"
|
||||
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
|
|
|
@ -28,6 +28,8 @@
|
|||
|
||||
#include "Filesystem/SHFileSystem.h"
|
||||
#include <rttr/registration.h>
|
||||
#include "Assets/Events/SHAssetManagerEvents.h"
|
||||
#include "Events/SHEventManager.hpp"
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
|
@ -39,7 +41,7 @@ namespace SHADE
|
|||
std::vector<SHAssetLoader*> SHAssetManager::loaders(TYPE_COUNT);
|
||||
|
||||
std::unordered_map<AssetID, SHAsset> SHAssetManager::assetCollection;
|
||||
std::unordered_map<AssetID, SHAssetData * const> SHAssetManager::assetData;
|
||||
std::unordered_map<AssetID, SHAssetData *> SHAssetManager::assetData;
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -167,6 +169,17 @@ namespace SHADE
|
|||
return {};
|
||||
}
|
||||
|
||||
AssetID SHAssetManager::GetAssetIDFromPath(AssetPath const& path) noexcept
|
||||
{
|
||||
for (auto const& pair : assetCollection)
|
||||
{
|
||||
if (pair.second.path.stem() == path.stem())
|
||||
return pair.first;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* \brief Create record for new asset. CAN ONLY CREATE FOR CUSTOM
|
||||
* ASSETS CREATED BY THE ENGINE.
|
||||
|
@ -438,10 +451,39 @@ namespace SHADE
|
|||
return;
|
||||
}
|
||||
|
||||
AssetID target{ 0 };
|
||||
if (genMeta)
|
||||
{
|
||||
GenerateNewMeta(newPath);
|
||||
auto result = GenerateNewMeta(newPath);
|
||||
target = result.has_value() ? result.value() : 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
target = GetAssetIDFromPath(path);
|
||||
|
||||
//Reload data
|
||||
auto result = GetAsset(target);
|
||||
if (result.has_value())
|
||||
{
|
||||
auto const& asset{ result.value() };
|
||||
auto newData = loaders[static_cast<size_t>(asset.type)]->Load(asset.path);
|
||||
delete assetData[target];
|
||||
assetData[target] = newData;
|
||||
}
|
||||
else
|
||||
{
|
||||
SHLOG_ERROR("[Asset Manager] Critical: reload of existing compiled data failed");
|
||||
}
|
||||
}
|
||||
|
||||
// send compile asset event
|
||||
SHCompileAssetEvent compileShaderEvent
|
||||
{
|
||||
.assetName = newPath.filename().stem().string(),
|
||||
.assetID = target,
|
||||
.assetType = AssetType::SHADER,
|
||||
};
|
||||
SHEventManager::BroadcastEvent<SHCompileAssetEvent>(compileShaderEvent, SH_ASSET_COMPILE_EVENT);
|
||||
}
|
||||
|
||||
FolderPointer SHAssetManager::GetRootFolder() noexcept
|
||||
|
|
|
@ -50,7 +50,7 @@ namespace SHADE
|
|||
* \return const& to unordered_map<AssetName, AssetID>
|
||||
****************************************************************************/
|
||||
static std::vector<SHAsset> GetAllAssets() noexcept;
|
||||
static std::optional<SHAsset> GetAsset(AssetID id) noexcept;
|
||||
static std::optional<SHAsset> GetAsset(AssetID id) noexcept;
|
||||
|
||||
static AssetType GetType(AssetID id) noexcept;
|
||||
|
||||
|
@ -97,6 +97,7 @@ namespace SHADE
|
|||
|
||||
private:
|
||||
|
||||
static AssetID GetAssetIDFromPath(AssetPath const& path) noexcept;
|
||||
static void InitLoaders() noexcept;
|
||||
static void LoadAllData() noexcept;
|
||||
static SHAssetData* LoadData(SHAsset const& asset) noexcept;
|
||||
|
@ -122,7 +123,7 @@ namespace SHADE
|
|||
|
||||
// For all resources
|
||||
static std::unordered_map<AssetID, SHAsset> assetCollection;
|
||||
static std::unordered_map<AssetID, SHAssetData * const> assetData;
|
||||
static std::unordered_map<AssetID, SHAssetData *> assetData;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -29,4 +29,5 @@ constexpr SHEventIdentifier SH_WINDOW_RESIZE_EVENT { 20 };
|
|||
constexpr SHEventIdentifier SH_BUTTON_RELEASE_EVENT { 21 };
|
||||
constexpr SHEventIdentifier SH_BUTTON_HOVER_ENTER_EVENT { 22 };
|
||||
constexpr SHEventIdentifier SH_BUTTON_HOVER_EXIT_EVENT { 23 };
|
||||
constexpr SHEventIdentifier SH_ASSET_COMPILE_EVENT { 24 };
|
||||
|
||||
|
|
|
@ -0,0 +1,53 @@
|
|||
#include "SHpch.h"
|
||||
#include "SHGraphicsGenericData.h"
|
||||
#include "Graphics/Devices/SHVkLogicalDevice.h"
|
||||
#include "Graphics/MiddleEnd/Interface/SHGraphicsConstants.h"
|
||||
#include "Graphics/Descriptors/SHVkDescriptorSetGroup.h"
|
||||
#include "Graphics/Buffers/SHVkBuffer.h"
|
||||
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
void SHGraphicsGenericData::Init(Handle<SHVkLogicalDevice> logicalDevice, Handle<SHVkDescriptorSetGroup> descSet) noexcept
|
||||
{
|
||||
alignedGpuStructSize = logicalDevice->PadUBOSize(sizeof (GpuStruct));
|
||||
|
||||
gpuBuffer = logicalDevice->CreateBuffer(alignedGpuStructSize * SHGraphicsConstants::NUM_FRAME_BUFFERS, nullptr, alignedGpuStructSize * SHGraphicsConstants::NUM_FRAME_BUFFERS, vk::BufferUsageFlagBits::eUniformBuffer, VMA_MEMORY_USAGE_AUTO, VMA_ALLOCATION_CREATE_MAPPED_BIT | VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT, "Generic Data");
|
||||
|
||||
std::array gpuBufferArray{ gpuBuffer };
|
||||
|
||||
// We use index 0 because the descriptor set is standalone created from a single desc set layout. What the driver sees is that this set is at index 0 during updating.
|
||||
static constexpr uint8_t SET_0 = 0;
|
||||
|
||||
descSet->ModifyWriteDescBuffer(SET_0, SHGraphicsConstants::DescriptorSetBindings::GENERIC_DATA, std::span<Handle<SHVkBuffer>>{ gpuBufferArray.data(), gpuBufferArray.size()}, 0, sizeof(GpuStruct));
|
||||
|
||||
descSet->UpdateDescriptorSetBuffer(SET_0, SHGraphicsConstants::DescriptorSetBindings::GENERIC_DATA);
|
||||
|
||||
}
|
||||
|
||||
void SHGraphicsGenericData::UpdateBuffer(uint32_t frameIndex) noexcept
|
||||
{
|
||||
gpuBuffer->WriteToMemory(&data, sizeof(GpuStruct), 0, alignedGpuStructSize * frameIndex);
|
||||
}
|
||||
|
||||
void SHGraphicsGenericData::SetDt(float dt) noexcept
|
||||
{
|
||||
data.dt = dt;
|
||||
}
|
||||
|
||||
void SHGraphicsGenericData::UpdateElapsedTime(float dt) noexcept
|
||||
{
|
||||
data.elapsedTime += dt;
|
||||
}
|
||||
|
||||
void SHGraphicsGenericData::SetViewportWidth(uint32_t width) noexcept
|
||||
{
|
||||
data.viewportWidth = width;
|
||||
}
|
||||
|
||||
void SHGraphicsGenericData::SetViewportHeight(uint32_t height) noexcept
|
||||
{
|
||||
data.viewportHeight = height;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include "Resource/SHHandle.h"
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
class SHVkDescriptorSetGroup;
|
||||
class SHVkBuffer;
|
||||
class SHVkLogicalDevice;
|
||||
|
||||
class SHGraphicsGenericData
|
||||
{
|
||||
public:
|
||||
struct GpuStruct
|
||||
{
|
||||
//! Delta time
|
||||
float dt{ 0.0f };
|
||||
|
||||
//! Elapsed time of the application
|
||||
float elapsedTime{ 0.0f };
|
||||
|
||||
//! Viewport width of the scene (excluding imgui, that means smaller than window)
|
||||
uint32_t viewportWidth{ 0 };
|
||||
|
||||
//! Ditto but for height
|
||||
uint32_t viewportHeight{ 0 };
|
||||
};
|
||||
private:
|
||||
|
||||
//! This will be access
|
||||
GpuStruct data;
|
||||
|
||||
//! Buffer to hold the generic data
|
||||
Handle<SHVkBuffer> gpuBuffer;
|
||||
|
||||
//! gpu struct size for GPU to use
|
||||
uint32_t alignedGpuStructSize;
|
||||
|
||||
public:
|
||||
void Init (Handle<SHVkLogicalDevice> logicalDevice, Handle<SHVkDescriptorSetGroup> descSet) noexcept;
|
||||
void UpdateBuffer(uint32_t frameIndex) noexcept;
|
||||
|
||||
void SetDt (float dt) noexcept;
|
||||
void UpdateElapsedTime (float dt) noexcept;
|
||||
void SetViewportWidth(uint32_t width) noexcept;
|
||||
void SetViewportHeight(uint32_t height) noexcept;
|
||||
|
||||
};
|
||||
}
|
||||
|
|
@ -2,11 +2,13 @@
|
|||
#include "SHGlobalDescriptorSets.h"
|
||||
#include "Graphics/MiddleEnd/Lights/SHLightingSubSystem.h"
|
||||
#include "Graphics/Commands/SHVkCommandBuffer.h"
|
||||
#include "Graphics/MiddleEnd/GenericData/SHGraphicsGenericData.h"
|
||||
#include "Graphics/Devices/SHVkLogicalDevice.h"
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
|
||||
Handle<SHVkDescriptorSetGroup> SHGlobalDescriptorSets::staticGlobalDataDescriptorSet;
|
||||
Handle<SHVkDescriptorSetGroup> SHGlobalDescriptorSets::genericAndTextureDataDescSet;
|
||||
Handle<SHLightingSubSystem> SHGlobalDescriptorSets::lightingSubSystem;
|
||||
|
||||
//void SHGlobalDescriptorSets::BindLightingData(Handle<SHVkCommandBuffer> cmdBuffer, SH_PIPELINE_TYPE pipelineType, uint32_t firstSet) noexcept
|
||||
|
@ -20,11 +22,13 @@ namespace SHADE
|
|||
lightingSubSystem->BindDescSet(cmdBuffer, setIndex, frameIndex);
|
||||
}
|
||||
|
||||
void SHGlobalDescriptorSets::BindStaticGlobalData(Handle<SHVkCommandBuffer> cmdBuffer, SH_PIPELINE_TYPE pipelineType, uint32_t setIndex) noexcept
|
||||
void SHGlobalDescriptorSets::BindGenericAndTextureData(Handle<SHVkLogicalDevice> device, Handle<SHVkCommandBuffer> cmdBuffer, SH_PIPELINE_TYPE pipelineType, uint32_t setIndex, uint32_t frameIndex) noexcept
|
||||
{
|
||||
uint32_t alignedGenericStructSize = device->PadUBOSize(sizeof(SHGraphicsGenericData::GpuStruct));
|
||||
|
||||
// Bind descriptor set for static global data
|
||||
static std::array<uint32_t, 1> TEX_DYNAMIC_OFFSET{ 0 };
|
||||
cmdBuffer->BindDescriptorSet(staticGlobalDataDescriptorSet, pipelineType, setIndex, std::span{ TEX_DYNAMIC_OFFSET.data(), 1 });
|
||||
static std::array TEX_DYNAMIC_OFFSET = { alignedGenericStructSize, };
|
||||
cmdBuffer->BindDescriptorSet(genericAndTextureDataDescSet, pipelineType, setIndex, std::span{ TEX_DYNAMIC_OFFSET.data(), 1 });
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
|
@ -43,9 +47,9 @@ namespace SHADE
|
|||
lightingSubSystem = system;
|
||||
}
|
||||
|
||||
void SHGlobalDescriptorSets::SetStaticGlobalDataDescriptorSet(Handle<SHVkDescriptorSetGroup> staticGlobalDescSet) noexcept
|
||||
void SHGlobalDescriptorSets::SetStaticGlobalDataDescriptorSet(Handle<SHVkDescriptorSetGroup> descSet) noexcept
|
||||
{
|
||||
staticGlobalDataDescriptorSet = staticGlobalDescSet;
|
||||
genericAndTextureDataDescSet = descSet;
|
||||
}
|
||||
|
||||
}
|
|
@ -15,7 +15,7 @@ namespace SHADE
|
|||
private:
|
||||
|
||||
//! Static global descriptor sets for miscellaneous data and textures
|
||||
static Handle<SHVkDescriptorSetGroup> staticGlobalDataDescriptorSet;
|
||||
static Handle<SHVkDescriptorSetGroup> genericAndTextureDataDescSet;
|
||||
|
||||
//! Lighting sub system required to get information to bind descriptor sets for light data
|
||||
static Handle<SHLightingSubSystem> lightingSubSystem;
|
||||
|
@ -25,7 +25,7 @@ namespace SHADE
|
|||
/* PUBLIC MEMBER FUNCTIONS */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
static void BindLightingData (Handle<SHVkCommandBuffer> cmdBuffer, SH_PIPELINE_TYPE pipelineType, uint32_t setIndex, uint32_t frameIndex) noexcept;
|
||||
static void BindStaticGlobalData (Handle<SHVkCommandBuffer> cmdBuffer, SH_PIPELINE_TYPE pipelineType, uint32_t setIndex) noexcept;
|
||||
static void BindGenericAndTextureData (Handle<SHVkLogicalDevice> device, Handle<SHVkCommandBuffer> cmdBuffer, SH_PIPELINE_TYPE pipelineType, uint32_t setIndex, uint32_t frameIndex) noexcept;
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* SETTERS AND GETTERS */
|
||||
|
|
|
@ -25,9 +25,10 @@ namespace SHADE
|
|||
{
|
||||
perSystemData[SHUtilities::ConvertEnum(SystemType::BATCHING)].descMappings.AddMappings
|
||||
({
|
||||
{SHPredefinedDescriptorTypes::STATIC_DATA, 0},
|
||||
{SHPredefinedDescriptorTypes::CAMERA, 1},
|
||||
{SHPredefinedDescriptorTypes::PER_INSTANCE_BATCH, 2},
|
||||
{SHPredefinedDescriptorTypes::STATIC_DATA, 0},
|
||||
{SHPredefinedDescriptorTypes::CAMERA, 1},
|
||||
{SHPredefinedDescriptorTypes::PER_INSTANCE_BATCH, 2},
|
||||
{SHPredefinedDescriptorTypes::RENDER_GRAPH_RESOURCE, 3},
|
||||
});
|
||||
|
||||
perSystemData[SHUtilities::ConvertEnum(SystemType::BATCHING_ANIM)].descMappings.AddMappings
|
||||
|
|
|
@ -129,11 +129,13 @@ namespace SHADE
|
|||
static constexpr std::string_view GBUFFER_WRITE_SUBPASS = "G-Buffer Write";
|
||||
static constexpr std::string_view UI_SUBPASS = "UI";
|
||||
static constexpr std::string_view VFX_SUBPASS = "VFX";
|
||||
static constexpr std::string_view OBJ_VFX_SUBPASS = "Object VFX Subpass No Depth";
|
||||
|
||||
static constexpr std::array USABLE_SUBPASSES =
|
||||
{
|
||||
GBUFFER_WRITE_SUBPASS,
|
||||
UI_SUBPASS
|
||||
UI_SUBPASS,
|
||||
OBJ_VFX_SUBPASS
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
@ -47,6 +47,7 @@ of DigiPen Institute of Technology is prohibited.
|
|||
#include "Events/SHEvent.h"
|
||||
#include "Graphics/MiddleEnd/Lights/SHLightComponent.h"
|
||||
#include "Input/SHInputManager.h"
|
||||
#include "Assets/Events/SHAssetManagerEvents.h"
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
|
@ -210,10 +211,11 @@ namespace SHADE
|
|||
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 }, true, 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("Object VFX", { 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);
|
||||
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 }, true, windowDims.first, windowDims.second, vk::Format::eD32SfloatS8Uint);
|
||||
renderGraph->AddResource("Depth Buffer", { SH_RENDER_GRAPH_RESOURCE_FLAGS::DEPTH, SH_RENDER_GRAPH_RESOURCE_FLAGS::INPUT }, true, windowDims.first, windowDims.second, vk::Format::eD32SfloatS8Uint);
|
||||
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 }, 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 }, true, windowDims.first, windowDims.second);
|
||||
|
@ -235,7 +237,8 @@ namespace SHADE
|
|||
"Depth Buffer",
|
||||
"SSAO",
|
||||
"SSAO Blur",
|
||||
"Position World Space"
|
||||
"Position World Space",
|
||||
"Object VFX"
|
||||
},
|
||||
{}); // no predecessors
|
||||
|
||||
|
@ -249,9 +252,16 @@ namespace SHADE
|
|||
gBufferSubpass->AddColorOutput("Normals");
|
||||
gBufferSubpass->AddColorOutput("Albedo");
|
||||
gBufferSubpass->AddColorOutput("Position World Space");
|
||||
gBufferSubpass->AddColorOutput("Object VFX");
|
||||
gBufferSubpass->AddDepthOutput("Depth Buffer", SH_RENDER_GRAPH_RESOURCE_FLAGS::DEPTH_STENCIL);
|
||||
|
||||
usableSubpassesMapping.emplace (std::string (SHGraphicsConstants::RenderGraphEntityNames::GBUFFER_WRITE_SUBPASS.data()), gBufferSubpass);
|
||||
// We add the object VFX render target and depth buffer as input just in case we want to make comparisons
|
||||
auto objectVfxSubpassNoDepth = gBufferNode->AddSubpass(SHGraphicsConstants::RenderGraphEntityNames::OBJ_VFX_SUBPASS.data(), worldViewport, worldRenderer);
|
||||
objectVfxSubpassNoDepth->AddColorOutput("Object VFX");
|
||||
objectVfxSubpassNoDepth->AddInput ("Depth Buffer");
|
||||
|
||||
usableSubpassesMapping.emplace(std::string(SHGraphicsConstants::RenderGraphEntityNames::GBUFFER_WRITE_SUBPASS.data()), gBufferSubpass);
|
||||
usableSubpassesMapping.emplace(std::string(SHGraphicsConstants::RenderGraphEntityNames::OBJ_VFX_SUBPASS.data()), objectVfxSubpassNoDepth);
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* SSAO PASS AND DATA INIT */
|
||||
|
@ -297,15 +307,15 @@ namespace SHADE
|
|||
"Albedo",
|
||||
"Scene",
|
||||
"SSAO Blur",
|
||||
"Position World Space"
|
||||
"Position World Space",
|
||||
"Object VFX"
|
||||
},
|
||||
{ SHGraphicsConstants::RenderGraphEntityNames::GBUFFER_PASS .data()});
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* DEFERRED COMPOSITE SUBPASS INIT */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
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);
|
||||
auto deferredCompositeCompute = deferredCompositeNode->AddNodeCompute(SHGraphicsConstants::RenderGraphEntityNames::DEFERRED_COMPOSITE_COMPUTE.data(), deferredCompositeShader, {"Position", "Normals", "Albedo", "Light Layer Indices", "SSAO Blur", "Position World Space", "Scene", "Object VFX"}, {}, SHLightingSubSystem::MAX_SHADOWS);
|
||||
deferredCompositeCompute->AddPreComputeFunction([=](Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex)
|
||||
{
|
||||
lightingSubSystem->PrepareShadowMapsForRead(cmdBuffer);
|
||||
|
@ -409,7 +419,6 @@ namespace SHADE
|
|||
|
||||
InitRenderGraph();
|
||||
|
||||
|
||||
// Create Semaphore
|
||||
for (auto& semaHandle : graphSemaphores)
|
||||
{
|
||||
|
@ -491,12 +500,34 @@ namespace SHADE
|
|||
|
||||
void SHGraphicsSystem::InitEvents(void) noexcept
|
||||
{
|
||||
std::shared_ptr<SHEventReceiverSpec<SHGraphicsSystem>> thisReceiver
|
||||
std::shared_ptr<SHEventReceiverSpec<SHGraphicsSystem>> lightEnableShadowReceiver
|
||||
{
|
||||
std::make_shared<SHEventReceiverSpec<SHGraphicsSystem>>(this, &SHGraphicsSystem::ReceiveLightEnableShadowEvent)
|
||||
};
|
||||
ReceiverPtr receiver = std::dynamic_pointer_cast<SHEventReceiver>(thisReceiver);
|
||||
SHEventManager::SubscribeTo(SH_GRAPHICS_LIGHT_ENABLE_SHADOW_EVENT, receiver);
|
||||
ReceiverPtr lightEnableShadowReceivePtr = std::dynamic_pointer_cast<SHEventReceiver>(lightEnableShadowReceiver);
|
||||
SHEventManager::SubscribeTo(SH_GRAPHICS_LIGHT_ENABLE_SHADOW_EVENT, lightEnableShadowReceivePtr);
|
||||
|
||||
std::shared_ptr<SHEventReceiverSpec<SHGraphicsSystem>> compileAssetReceiever
|
||||
{
|
||||
std::make_shared<SHEventReceiverSpec<SHGraphicsSystem>>(this, &SHGraphicsSystem::ReceiveCompileAssetEvent)
|
||||
};
|
||||
ReceiverPtr compileAssetReceivePtr = std::dynamic_pointer_cast<SHEventReceiver>(compileAssetReceiever);
|
||||
SHEventManager::SubscribeTo(SH_ASSET_COMPILE_EVENT, compileAssetReceivePtr);
|
||||
}
|
||||
|
||||
void SHGraphicsSystem::InitGenericDataAndTexturesDescSet(void) noexcept
|
||||
{
|
||||
// descriptor set for generic data and textures
|
||||
genericAndTextureDescSet = descPool->Allocate(SHGraphicsPredefinedData::GetPredefinedDescSetLayouts(SHGraphicsPredefinedData::PredefinedDescSetLayoutTypes::STATIC_DATA), { SHTextureLibrary::DEFAULT_MAX_TEXTURES });
|
||||
|
||||
for (auto set : genericAndTextureDescSet->GetVkHandle())
|
||||
SET_VK_OBJ_NAME(device, vk::ObjectType::eDescriptorSet, set, "[Descriptor Set] Static Globals");
|
||||
|
||||
SHGlobalDescriptorSets::SetStaticGlobalDataDescriptorSet(genericAndTextureDescSet);
|
||||
|
||||
// Create buffer for generic data and attach to descriptor set
|
||||
graphicsGenericData.Init(device, genericAndTextureDescSet);
|
||||
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
|
@ -507,6 +538,7 @@ namespace SHADE
|
|||
InitBoilerplate();
|
||||
InitMiddleEnd();
|
||||
InitSubsystems();
|
||||
InitGenericDataAndTexturesDescSet();
|
||||
InitBuiltInResources();
|
||||
InitEvents();
|
||||
}
|
||||
|
@ -536,7 +568,7 @@ namespace SHADE
|
|||
|
||||
*/
|
||||
/***************************************************************************/
|
||||
void SHGraphicsSystem::Run(double) noexcept
|
||||
void SHGraphicsSystem::Run(double dt) noexcept
|
||||
{
|
||||
if (window->IsMinimized() || renderContext.GetWindowIsDead())
|
||||
{
|
||||
|
@ -572,6 +604,9 @@ namespace SHADE
|
|||
|
||||
auto cameraSystem = SHSystemManager::GetSystem<SHCameraSystem>();
|
||||
|
||||
graphicsGenericData.SetDt(dt);
|
||||
graphicsGenericData.UpdateElapsedTime(dt);
|
||||
graphicsGenericData.UpdateBuffer(frameIndex);
|
||||
|
||||
{
|
||||
#ifdef SHEDITOR
|
||||
|
@ -860,6 +895,29 @@ namespace SHADE
|
|||
return eventPtr->handle;
|
||||
}
|
||||
|
||||
SHEventHandle SHGraphicsSystem::ReceiveCompileAssetEvent(SHEventPtr eventPtr) noexcept
|
||||
{
|
||||
auto const& EVENT_DATA = reinterpret_cast<const SHEventSpec<SHCompileAssetEvent>*>(eventPtr.get())->data;
|
||||
|
||||
// check for asset type
|
||||
if (EVENT_DATA->assetType == AssetType::SHADER)
|
||||
{
|
||||
// loop through all shaders
|
||||
auto denseIterators = SHVkInstance::GetResourceManager().GetDenseAccess<SHVkShaderModule>();
|
||||
for (auto it = denseIterators.first; it != denseIterators.second; ++it)
|
||||
{
|
||||
if (it->GetName() == EVENT_DATA->assetName)
|
||||
{
|
||||
auto* shaderAsset = SHAssetManager::GetData<SHShaderAsset>(EVENT_DATA->assetID);
|
||||
it->OnChange(shaderAsset->spirvBinary);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return eventPtr->handle;
|
||||
}
|
||||
|
||||
Handle<SHMaterial> SHGraphicsSystem::AddMaterial(Handle<SHVkShaderModule> vertShader, Handle<SHVkShaderModule> fragShader, Handle<SHSubpass> subpass)
|
||||
{
|
||||
// Retrieve pipeline from pipeline storage or create if unavailable
|
||||
|
@ -980,12 +1038,11 @@ namespace SHADE
|
|||
device->WaitIdle();
|
||||
texLibrary.BuildTextures
|
||||
(
|
||||
device, graphicsTexCmdBuffer, graphicsQueue, descPool
|
||||
device, graphicsTexCmdBuffer, graphicsQueue, genericAndTextureDescSet
|
||||
);
|
||||
device->WaitIdle();
|
||||
graphicsTexCmdBuffer.Free(); graphicsTexCmdBuffer = {};
|
||||
SHGlobalDescriptorSets::SetStaticGlobalDataDescriptorSet(texLibrary.GetTextureDescriptorSetGroup());
|
||||
|
||||
//SHGlobalDescriptorSets::SetStaticGlobalDataDescriptorSet(texLibrary.GetTextureDescriptorSetGroup());
|
||||
}
|
||||
|
||||
Handle<SHTexture> SHGraphicsSystem::GetTextureHandle(SHTexture::Index textureId) const
|
||||
|
@ -1134,6 +1191,10 @@ namespace SHADE
|
|||
resizeWidth = newWidth;
|
||||
resizeHeight = newHeight;
|
||||
|
||||
graphicsGenericData.SetViewportWidth(resizeWidth);
|
||||
graphicsGenericData.SetViewportHeight(resizeHeight);
|
||||
|
||||
|
||||
renderContext.SetIsResized(true);
|
||||
}
|
||||
|
||||
|
@ -1186,6 +1247,7 @@ namespace SHADE
|
|||
|
||||
SHEventManager::BroadcastEvent<SHWindowResizeEvent>(newEvent, SH_WINDOW_RESIZE_EVENT);
|
||||
|
||||
|
||||
#else
|
||||
// Create new event and broadcast it
|
||||
SHWindowResizeEvent newEvent;
|
||||
|
|
|
@ -37,6 +37,7 @@ of DigiPen Institute of Technology is prohibited.
|
|||
#include "Graphics/MiddleEnd/Interface/SHRenderer.h"
|
||||
#include "Graphics/Events/SHGraphicsEvents.h"
|
||||
#include "Graphics/MiddleEnd/TrajectoryRendering/SHTrajectoryRenderingSubSystem.h"
|
||||
#include "Graphics/MiddleEnd/GenericData/SHGraphicsGenericData.h"
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
|
@ -106,6 +107,7 @@ namespace SHADE
|
|||
void InitSubsystems (void) noexcept;
|
||||
void InitBuiltInResources (void);
|
||||
void InitEvents (void) noexcept;
|
||||
void InitGenericDataAndTexturesDescSet (void) noexcept;
|
||||
|
||||
public:
|
||||
class SH_API BeginRoutine final : public SHSystemRoutine
|
||||
|
@ -181,6 +183,11 @@ namespace SHADE
|
|||
/*-----------------------------------------------------------------------*/
|
||||
SHEventHandle ReceiveLightEnableShadowEvent (SHEventPtr eventPtr) noexcept;
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Asset Events */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
SHEventHandle ReceiveCompileAssetEvent (SHEventPtr eventPtr) noexcept;
|
||||
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/* Material Functions */
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
|
@ -433,6 +440,7 @@ namespace SHADE
|
|||
SHResourceHub resourceManager;
|
||||
SHMeshLibrary meshLibrary;
|
||||
SHTextureLibrary texLibrary;
|
||||
SHGraphicsGenericData graphicsGenericData;
|
||||
SHFontLibrary fontLibrary;
|
||||
SHSamplerCache samplerCache;
|
||||
SHMaterialInstanceCache materialInstanceCache;
|
||||
|
@ -490,6 +498,8 @@ namespace SHADE
|
|||
Handle<SHVkPipeline> debugDrawFilledDepthPipeline;
|
||||
Handle<SHVkPipeline> shadowMapPipeline; // initialized only when a shadow map is needed
|
||||
|
||||
Handle<SHVkDescriptorSetGroup> genericAndTextureDescSet;
|
||||
|
||||
// Built-In Textures
|
||||
Handle<SHTexture> defaultTexture;
|
||||
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#include "Graphics/MiddleEnd/GlobalData/SHGlobalDescriptorSets.h"
|
||||
#include "Graphics/MiddleEnd/Interface/SHRenderer.h"
|
||||
#include "Scene/SHSceneManager.h"
|
||||
#include "UI/SHUIComponent.h"
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
|
@ -197,7 +198,7 @@ namespace SHADE
|
|||
cmdBuffer->BindPipeline(pipeline);
|
||||
|
||||
// Bind global data
|
||||
SHGlobalDescriptorSets::BindStaticGlobalData(cmdBuffer, SH_PIPELINE_TYPE::GRAPHICS, staticGlobalSetIndex);
|
||||
SHGlobalDescriptorSets::BindGenericAndTextureData(logicalDevice, cmdBuffer, SH_PIPELINE_TYPE::GRAPHICS, staticGlobalSetIndex, frameIndex);
|
||||
|
||||
// Bind camera data
|
||||
renderer->BindDescriptorSet(cmdBuffer, SH_PIPELINE_TYPE::GRAPHICS, cameraSetIndex, frameIndex);
|
||||
|
@ -209,7 +210,12 @@ namespace SHADE
|
|||
cmdBuffer->BindVertexBuffer(SHGraphicsConstants::VertexBufferBindings::CALCULATED_GLYPH_POSITION, comp.charPositionDataBuffer, 0);
|
||||
cmdBuffer->BindVertexBuffer(SHGraphicsConstants::VertexBufferBindings::GLYPH_INDEX, comp.indexingDataBuffer, 0);
|
||||
|
||||
cmdBuffer->SetPushConstantVariable("TestPushConstant.worldTransform", transform->GetTRS(), SH_PIPELINE_TYPE::GRAPHICS);
|
||||
if (auto* uiComp = SHComponentManager::GetComponent_s<SHUIComponent>(comp.GetEID()))
|
||||
cmdBuffer->SetPushConstantVariable("TestPushConstant.worldTransform", uiComp->GetMatrix(), SH_PIPELINE_TYPE::GRAPHICS);
|
||||
else
|
||||
cmdBuffer->SetPushConstantVariable("TestPushConstant.worldTransform", transform->GetTRS(), SH_PIPELINE_TYPE::GRAPHICS);
|
||||
|
||||
|
||||
cmdBuffer->SetPushConstantVariable("TestPushConstant.eid", comp.GetEID(), SH_PIPELINE_TYPE::GRAPHICS);
|
||||
cmdBuffer->SetPushConstantVariable("TestPushConstant.textColor", SHVec3 (1.0f, 1.0f, 1.0f), SH_PIPELINE_TYPE::GRAPHICS);
|
||||
|
||||
|
|
|
@ -63,7 +63,7 @@ namespace SHADE
|
|||
isDirty = true;
|
||||
}
|
||||
|
||||
void SHTextureLibrary::BuildTextures(Handle<SHVkLogicalDevice> device, Handle<SHVkCommandBuffer> cmdBuffer, Handle<SHVkQueue> graphicsQueue, Handle<SHVkDescriptorPool> descPool)
|
||||
void SHTextureLibrary::BuildTextures(Handle<SHVkLogicalDevice> device, Handle<SHVkCommandBuffer> cmdBuffer, Handle<SHVkQueue> graphicsQueue, Handle<SHVkDescriptorSetGroup> descSet/*, Handle<SHVkDescriptorPool> descPool*/)
|
||||
{
|
||||
// Don't do anything if there are no updates
|
||||
if (!isDirty)
|
||||
|
@ -162,27 +162,28 @@ namespace SHADE
|
|||
/* Build Descriptor Set with all the Textures only if there are textures */
|
||||
if (!texOrder.empty())
|
||||
{
|
||||
if (texDescriptors)
|
||||
{
|
||||
texDescriptors.Free();
|
||||
}
|
||||
texDescriptors = descPool->Allocate
|
||||
(
|
||||
{ SHGraphicsPredefinedData::GetPredefinedDescSetLayouts(SHGraphicsPredefinedData::PredefinedDescSetLayoutTypes::STATIC_DATA) },
|
||||
{ static_cast<uint32_t>(texOrder.size()) }
|
||||
);
|
||||
#ifdef _DEBUG
|
||||
for (auto set : texDescriptors->GetVkHandle())
|
||||
SET_VK_OBJ_NAME(device, vk::ObjectType::eDescriptorSet, set, "[Descriptor Set] Static Globals");
|
||||
#endif
|
||||
|
||||
// if (descSet)
|
||||
// {
|
||||
// descSet.Free();
|
||||
// }
|
||||
// descSet = descPool->Allocate
|
||||
// (
|
||||
// { SHGraphicsPredefinedData::GetPredefinedDescSetLayouts(SHGraphicsPredefinedData::PredefinedDescSetLayoutTypes::STATIC_DATA) },
|
||||
// { static_cast<uint32_t>(texOrder.size()) }
|
||||
// );
|
||||
//#ifdef _DEBUG
|
||||
// for (auto set : descSet->GetVkHandle())
|
||||
// SET_VK_OBJ_NAME(device, vk::ObjectType::eDescriptorSet, set, "[Descriptor Set] Static Globals");
|
||||
//#endif
|
||||
static constexpr uint32_t TEX_DESCRIPTOR_SET_INDEX = 0;
|
||||
texDescriptors->ModifyWriteDescImage
|
||||
descSet->ModifyWriteDescImage
|
||||
(
|
||||
TEX_DESCRIPTOR_SET_INDEX,
|
||||
SHGraphicsConstants::DescriptorSetBindings::IMAGE_AND_SAMPLERS_DATA,
|
||||
combinedImageSamplers
|
||||
);
|
||||
texDescriptors->UpdateDescriptorSetImages
|
||||
descSet->UpdateDescriptorSetImages
|
||||
(
|
||||
TEX_DESCRIPTOR_SET_INDEX,
|
||||
SHGraphicsConstants::DescriptorSetBindings::IMAGE_AND_SAMPLERS_DATA
|
||||
|
|
|
@ -66,6 +66,13 @@ namespace SHADE
|
|||
class SHTextureLibrary
|
||||
{
|
||||
public:
|
||||
//! This exists because a poor decision was made to place the textures and
|
||||
//! generic data as 2 bindings in a single layout. Because of this, the recreation
|
||||
//! of the texture library would mean the recreation of the desc set that also
|
||||
//! involves the generic data, which is bad bad bad. Solution is to separate the
|
||||
//! 2 desc sets.
|
||||
static constexpr uint32_t DEFAULT_MAX_TEXTURES = 2000;
|
||||
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/* Usage Functions */
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
|
@ -112,7 +119,7 @@ namespace SHADE
|
|||
/*!
|
||||
|
||||
\brief
|
||||
Finalises all changes to the Texture Library into the GPU buffers.
|
||||
Finalizes all changes to the Texture Library into the GPU buffers.
|
||||
|
||||
\param device
|
||||
Device used to create and update the buffers.
|
||||
|
@ -123,12 +130,12 @@ namespace SHADE
|
|||
queue.
|
||||
*/
|
||||
/***************************************************************************/
|
||||
void BuildTextures(Handle<SHVkLogicalDevice> device, Handle<SHVkCommandBuffer> cmdBuffer, Handle<SHVkQueue> graphicsQueue, Handle<SHVkDescriptorPool> descPool);
|
||||
void BuildTextures(Handle<SHVkLogicalDevice> device, Handle<SHVkCommandBuffer> cmdBuffer, Handle<SHVkQueue> graphicsQueue, Handle<SHVkDescriptorSetGroup> descSet/*, Handle<SHVkDescriptorPool> descPool*/);
|
||||
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/* Getter Functions */
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
Handle<SHVkDescriptorSetGroup> GetTextureDescriptorSetGroup() const noexcept { return texDescriptors; }
|
||||
//Handle<SHVkDescriptorSetGroup> GetTextureDescriptorSetGroup() const noexcept { return descSet; }
|
||||
/***************************************************************************/
|
||||
/*!
|
||||
*
|
||||
|
@ -173,8 +180,8 @@ namespace SHADE
|
|||
std::vector<Handle<SHTexture>> texOrder;
|
||||
// CPU Storage
|
||||
std::vector<std::tuple<Handle<SHVkImageView>, Handle<SHVkSampler>, vk::ImageLayout>> combinedImageSamplers;
|
||||
// GPU Storage
|
||||
Handle<SHVkDescriptorSetGroup> texDescriptors;
|
||||
//// GPU Storage
|
||||
//Handle<SHVkDescriptorSetGroup> descSet;
|
||||
// Flags
|
||||
bool isDirty = true;
|
||||
|
||||
|
|
|
@ -164,7 +164,7 @@ namespace SHADE
|
|||
cmdBuffer->BindPipeline(pipeline);
|
||||
|
||||
// Bind global data
|
||||
SHGlobalDescriptorSets::BindStaticGlobalData(cmdBuffer, SH_PIPELINE_TYPE::GRAPHICS, staticGlobalSetIndex);
|
||||
SHGlobalDescriptorSets::BindGenericAndTextureData(logicalDevice, cmdBuffer, SH_PIPELINE_TYPE::GRAPHICS, staticGlobalSetIndex, frameIndex);
|
||||
|
||||
// Bind camera data
|
||||
renderer->BindDescriptorSet(cmdBuffer, SH_PIPELINE_TYPE::GRAPHICS, cameraSetIndex, frameIndex);
|
||||
|
|
|
@ -235,6 +235,9 @@ namespace SHADE
|
|||
, pipelineLayout { inPipelineLayout }
|
||||
, created {false}
|
||||
{
|
||||
if (pipelineLayout)
|
||||
pipelineLayout->AddCallback([this]() {ConstructPipeline();});
|
||||
|
||||
// We want to create a pipeline
|
||||
if (state != nullptr)
|
||||
{
|
||||
|
@ -359,7 +362,10 @@ namespace SHADE
|
|||
{
|
||||
// if it was created before, destroy it
|
||||
if (created)
|
||||
{
|
||||
logicalDeviceHdl->WaitIdle();
|
||||
logicalDeviceHdl->GetVkLogicalDevice().destroyPipeline(vkPipeline, nullptr);
|
||||
}
|
||||
|
||||
// Set to false again. If creation succeeds after this, this will be true
|
||||
created = false;
|
||||
|
|
|
@ -298,6 +298,10 @@ namespace SHADE
|
|||
|
||||
descriptorSetLayoutsAllocate.clear();
|
||||
|
||||
dynamicBufferBindings.clear();
|
||||
|
||||
descriptorSetLayoutsPipeline.clear();
|
||||
|
||||
// We don't need to use vulkan to destroy descriptor sets here since they are just owned by the container with handles
|
||||
vkDescriptorSetLayoutsAllocate.clear();
|
||||
vkDescriptorSetLayoutsPipeline.clear();
|
||||
|
@ -450,6 +454,15 @@ namespace SHADE
|
|||
}
|
||||
else
|
||||
SHVulkanDebugUtil::ReportVkSuccess("Successfully created Pipeline Layout. ");
|
||||
|
||||
// Call callbacks
|
||||
for (auto& callback : onChangeCallbacks)
|
||||
callback();
|
||||
}
|
||||
|
||||
void SHVkPipelineLayout::AddCallback(ChangeCallback&& callback) noexcept
|
||||
{
|
||||
onChangeCallbacks.emplace_back(std::move(callback));
|
||||
}
|
||||
|
||||
std::vector<Handle<SHVkShaderModule>> const& SHVkPipelineLayout::GetShaderModules(void) const noexcept
|
||||
|
|
|
@ -10,6 +10,9 @@ namespace SHADE
|
|||
|
||||
class SHVkPipelineLayout
|
||||
{
|
||||
public:
|
||||
using ChangeCallback = std::function<void()>;
|
||||
|
||||
private:
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* PRIVATE MEMBER VARIABLES */
|
||||
|
@ -51,6 +54,12 @@ namespace SHADE
|
|||
//! Store for pipeline layout recreation
|
||||
std::vector<vk::DescriptorSetLayout> vkDescriptorSetLayoutsPipeline;
|
||||
|
||||
//! When pipeline layout needs to be recreated, this container could serve as an event
|
||||
//! response to call all the functions that need to be called. Specifically
|
||||
//! pipelines that need to use the new pipeline layout
|
||||
std::vector<ChangeCallback> onChangeCallbacks;
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* PRIVATE MEMBER FUNCTIONS */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
@ -73,6 +82,7 @@ namespace SHADE
|
|||
/* PUBLIC MEMBER FUNCTIONS */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
void RecreateIfNeeded (void) noexcept;
|
||||
void AddCallback(ChangeCallback&& callback) noexcept;
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* SETTERS AND GETTERS */
|
||||
|
|
|
@ -512,8 +512,9 @@ namespace SHADE
|
|||
uint32_t h = static_cast<uint32_t>(resource->GetHeight());
|
||||
cmdBuffer->SetViewportScissor(static_cast<float>(w), static_cast<float>(h), w, h);
|
||||
|
||||
static constexpr uint32_t INPUT_IMAGE_SET_INDEX = 0;
|
||||
newSubpass->BindInputDescriptorSets (cmdBuffer, INPUT_IMAGE_SET_INDEX, frameIndex);
|
||||
//static constexpr uint32_t INPUT_IMAGE_SET_INDEX = 0;
|
||||
auto const& mappings = SHGraphicsPredefinedData::GetMappings(SHGraphicsPredefinedData::SystemType::BATCHING);
|
||||
newSubpass->BindInputDescriptorSets (cmdBuffer, mappings.at(SHPredefinedDescriptorTypes::RENDER_GRAPH_RESOURCE), frameIndex);
|
||||
|
||||
// draw a quad.
|
||||
cmdBuffer->DrawArrays(4, 1, 0, 0);
|
||||
|
@ -570,9 +571,10 @@ namespace SHADE
|
|||
auto cmdBuffer = commandBuffers[frameIndex];
|
||||
cmdBuffer->BeginLabeledSegment(name);
|
||||
|
||||
auto batchingSystemData = SHGraphicsPredefinedData::GetSystemData(SHGraphicsPredefinedData::SystemType::BATCHING);
|
||||
auto const& batchingSystemData = SHGraphicsPredefinedData::GetSystemData(SHGraphicsPredefinedData::SystemType::BATCHING);
|
||||
|
||||
// Force bind pipeline layout
|
||||
|
||||
// Force bind pipeline layout
|
||||
cmdBuffer->ForceSetPipelineLayout(batchingSystemData.dummyPipelineLayout, SH_PIPELINE_TYPE::GRAPHICS);
|
||||
cmdBuffer->ForceSetPipelineLayout(batchingSystemData.dummyPipelineLayout, SH_PIPELINE_TYPE::COMPUTE);
|
||||
|
||||
|
@ -584,7 +586,7 @@ namespace SHADE
|
|||
if (node->renderpass)
|
||||
{
|
||||
// bind static global data
|
||||
SHGlobalDescriptorSets::BindStaticGlobalData(cmdBuffer, SH_PIPELINE_TYPE::GRAPHICS, descMappings.at(SHPredefinedDescriptorTypes::STATIC_DATA));
|
||||
SHGlobalDescriptorSets::BindGenericAndTextureData(renderGraphStorage->logicalDevice, cmdBuffer, SH_PIPELINE_TYPE::GRAPHICS, descMappings.at(SHPredefinedDescriptorTypes::STATIC_DATA), frameIndex);
|
||||
|
||||
// Bind all the buffers required for meshes
|
||||
for (auto& [buffer, bindingPoint] : MESH_DATA)
|
||||
|
|
|
@ -184,12 +184,13 @@ namespace SHADE
|
|||
for (auto& inputAtt : subpass->inputReferences)
|
||||
{
|
||||
auto resource = attResources[inputAtt.attachment];
|
||||
if (resource->resourceTypeFlags & static_cast<uint32_t>(SH_RENDER_GRAPH_RESOURCE_FLAGS::INPUT))
|
||||
auto typeFlags = resource->resourceTypeFlags;
|
||||
if (typeFlags & static_cast<uint32_t>(SH_RENDER_GRAPH_RESOURCE_FLAGS::INPUT))
|
||||
{
|
||||
if (resource->resourceTypeFlags & static_cast<uint32_t>(SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR) ||
|
||||
resource->resourceTypeFlags & static_cast<uint32_t>(SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR_PRESENT))
|
||||
if (typeFlags & static_cast<uint32_t>(SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR) ||
|
||||
typeFlags & static_cast<uint32_t>(SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR_PRESENT))
|
||||
colorRead |= (1 << i);
|
||||
else if (resource->resourceTypeFlags & static_cast<uint32_t>(SH_RENDER_GRAPH_RESOURCE_FLAGS::DEPTH_STENCIL))
|
||||
else if (typeFlags & static_cast<uint32_t>(SH_RENDER_GRAPH_RESOURCE_FLAGS::DEPTH_STENCIL) || typeFlags & static_cast<uint32_t>(SH_RENDER_GRAPH_RESOURCE_FLAGS::DEPTH))
|
||||
depthRead |= (1 << i);
|
||||
}
|
||||
else
|
||||
|
@ -265,6 +266,7 @@ namespace SHADE
|
|||
|
||||
// initialize input descriptors
|
||||
subpasses[i]->CreateInputDescriptors();
|
||||
subpasses[i]->GenerateDummyPipielineLayout();
|
||||
|
||||
++i;
|
||||
}
|
||||
|
@ -664,7 +666,7 @@ namespace SHADE
|
|||
commandBuffer->ForceSetPipelineLayout(SHGraphicsPredefinedData::GetSystemData(SHGraphicsPredefinedData::SystemType::RENDER_GRAPH_NODE_COMPUTE).dummyPipelineLayout, SH_PIPELINE_TYPE::COMPUTE);
|
||||
|
||||
// bind static global data
|
||||
SHGlobalDescriptorSets::BindStaticGlobalData(commandBuffer, SH_PIPELINE_TYPE::COMPUTE, descMappings.at(SHPredefinedDescriptorTypes::STATIC_DATA));
|
||||
SHGlobalDescriptorSets::BindGenericAndTextureData(graphStorage->logicalDevice, commandBuffer, SH_PIPELINE_TYPE::COMPUTE, descMappings.at(SHPredefinedDescriptorTypes::STATIC_DATA), frameIndex);
|
||||
|
||||
// bind lighting data
|
||||
SHGlobalDescriptorSets::BindLightingData(commandBuffer, SH_PIPELINE_TYPE::COMPUTE, descMappings.at(SHPredefinedDescriptorTypes::LIGHTS), frameIndex);
|
||||
|
|
|
@ -226,11 +226,15 @@ namespace SHADE
|
|||
commandBuffer->SetViewportScissor(static_cast<float>(w), static_cast<float>(h), w, h);
|
||||
}
|
||||
|
||||
commandBuffer->ForceSetPipelineLayout(dummyPipelineLayout, SH_PIPELINE_TYPE::GRAPHICS);
|
||||
|
||||
auto const& descMappings = SHGraphicsPredefinedData::GetMappings(SHGraphicsPredefinedData::SystemType::BATCHING);
|
||||
|
||||
if (renderer)
|
||||
renderer->BindDescriptorSet(commandBuffer, SH_PIPELINE_TYPE::GRAPHICS, descMappings.at(SHPredefinedDescriptorTypes::CAMERA), frameIndex);
|
||||
|
||||
BindInputDescriptorSets (commandBuffer, descMappings.at(SHPredefinedDescriptorTypes::RENDER_GRAPH_RESOURCE), frameIndex);
|
||||
|
||||
// If companion subpass is not a valid handle, render super batch normally
|
||||
if (!companionSubpass.companion)
|
||||
{
|
||||
|
@ -439,6 +443,33 @@ namespace SHADE
|
|||
}
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
/*!
|
||||
|
||||
\brief
|
||||
Generates the dummy pipeline layout for subpass; specifically add the
|
||||
input descriptor set layout if it exists.
|
||||
|
||||
|
||||
\return
|
||||
|
||||
*/
|
||||
/***************************************************************************/
|
||||
void SHSubpass::GenerateDummyPipielineLayout(void) noexcept
|
||||
{
|
||||
auto const& batchingSystemData = SHGraphicsPredefinedData::GetSystemData(SHGraphicsPredefinedData::SystemType::BATCHING);
|
||||
std::vector newLayouts = batchingSystemData.descSetLayouts;
|
||||
if (inputDescriptorLayout)
|
||||
{
|
||||
newLayouts.push_back(inputDescriptorLayout);
|
||||
}
|
||||
|
||||
dummyPipelineLayout = graphStorage->logicalDevice->CreatePipelineLayoutDummy
|
||||
(
|
||||
SHPipelineLayoutParamsDummy{ newLayouts }
|
||||
);
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
/*!
|
||||
|
||||
|
|
|
@ -22,6 +22,7 @@ namespace SHADE
|
|||
class SHRenderer;
|
||||
class SHViewport;
|
||||
class SHVkPipeline;
|
||||
class SHVkPipelineLayout;
|
||||
|
||||
class SH_API SHSubpass : public ISelfHandle<SHSubpass>
|
||||
{
|
||||
|
@ -87,6 +88,12 @@ namespace SHADE
|
|||
|
||||
std::vector<Handle<SHVkSampler>> inputSamplers;
|
||||
|
||||
//! Dummy pipeline layout for subpass to bind before draw.
|
||||
//! // IMPORTANT NOTE: After implementing input descriptors, every subpass differs in number input descriptors.
|
||||
//! Before binding the input descriptors, a pipeline layout containing the desc set layouts
|
||||
//! for the input descriptors is required, making this umbrella initial dummy bind invalid.
|
||||
Handle<SHVkPipelineLayout> dummyPipelineLayout;
|
||||
|
||||
|
||||
////! subpass compute image barriers. We do this because every frame has a different
|
||||
////! swapchain image. If the resource we want to transition is not a swapchain image,
|
||||
|
@ -146,6 +153,7 @@ namespace SHADE
|
|||
//void InitComputeBarriers (void) noexcept;
|
||||
void CreateInputDescriptors (void) noexcept;
|
||||
void UpdateWriteDescriptors (void) noexcept;
|
||||
void GenerateDummyPipielineLayout (void) noexcept;
|
||||
|
||||
private:
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
|
|
@ -7,20 +7,16 @@
|
|||
namespace SHADE
|
||||
{
|
||||
|
||||
SHVkShaderModule::SHVkShaderModule(Handle<SHVkLogicalDevice> const& inLogicalDeviceHdl, std::vector<uint32_t> const& binaryData, std::string inEntryPoint, vk::ShaderStageFlagBits stage, std::string const& name) noexcept
|
||||
: logicalDeviceHdl {inLogicalDeviceHdl}
|
||||
, shaderStage {stage}
|
||||
, entryPoint {inEntryPoint}
|
||||
, vkShaderModule {nullptr}
|
||||
, spirvBinary{}
|
||||
, shaderName {name}
|
||||
, reflectedData {}
|
||||
void SHVkShaderModule::Recompile(void) noexcept
|
||||
{
|
||||
if (vkShaderModule)
|
||||
logicalDeviceHdl->GetVkLogicalDevice().destroyShaderModule(vkShaderModule, nullptr);
|
||||
|
||||
// Prepare the create info
|
||||
vk::ShaderModuleCreateInfo moduleCreateInfo
|
||||
{
|
||||
.codeSize = binaryData.size() * sizeof (uint32_t),
|
||||
.pCode = binaryData.data(),
|
||||
.codeSize = spirvBinary.size() * sizeof(uint32_t),
|
||||
.pCode = spirvBinary.data(),
|
||||
};
|
||||
|
||||
if (auto result = logicalDeviceHdl->GetVkLogicalDevice().createShaderModule(&moduleCreateInfo, nullptr, &vkShaderModule); result != vk::Result::eSuccess)
|
||||
|
@ -30,10 +26,18 @@ namespace SHADE
|
|||
}
|
||||
else
|
||||
SHVulkanDebugUtil::ReportVkSuccess("Successfully created shader module.");
|
||||
}
|
||||
|
||||
// TODO: Right now, this is doing a copy, we need to figure out if its better to just move from the resource management (source library) instead. The hope is that
|
||||
// shader modules only need 1 of themselves.
|
||||
spirvBinary = binaryData;
|
||||
SHVkShaderModule::SHVkShaderModule(Handle<SHVkLogicalDevice> const& inLogicalDeviceHdl, std::vector<uint32_t> const& binaryData, std::string inEntryPoint, vk::ShaderStageFlagBits stage, std::string const& name) noexcept
|
||||
: logicalDeviceHdl {inLogicalDeviceHdl}
|
||||
, shaderStage {stage}
|
||||
, entryPoint {inEntryPoint}
|
||||
, vkShaderModule {nullptr}
|
||||
, spirvBinary{binaryData}
|
||||
, shaderName {name}
|
||||
, reflectedData {}
|
||||
{
|
||||
Recompile();
|
||||
}
|
||||
|
||||
SHVkShaderModule::SHVkShaderModule(SHVkShaderModule&& rhs) noexcept
|
||||
|
@ -81,13 +85,18 @@ namespace SHADE
|
|||
}
|
||||
}
|
||||
|
||||
void SHVkShaderModule::OnChange(void) noexcept
|
||||
void SHVkShaderModule::OnChange(std::vector<uint32_t> const& newBinaryData) noexcept
|
||||
{
|
||||
// assign new binary data and recompile shader
|
||||
spirvBinary = newBinaryData;
|
||||
|
||||
Recompile();
|
||||
|
||||
for (auto& callback : onChangeCallbacks)
|
||||
callback();
|
||||
}
|
||||
|
||||
void SHVkShaderModule::AddCallback(SHShaderChangeCallback&& callback) noexcept
|
||||
void SHVkShaderModule::AddCallback(ChangeCallback&& callback) noexcept
|
||||
{
|
||||
onChangeCallbacks.emplace_back(std::move(callback));
|
||||
}
|
||||
|
@ -112,4 +121,9 @@ namespace SHADE
|
|||
return reflectedData;
|
||||
}
|
||||
|
||||
std::string SHVkShaderModule::GetName(void) const noexcept
|
||||
{
|
||||
return shaderName;
|
||||
}
|
||||
|
||||
}
|
|
@ -16,7 +16,7 @@ namespace SHADE
|
|||
/*-----------------------------------------------------------------------*/
|
||||
/* TYPE DEFINITIONS */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
using SHShaderChangeCallback = std::function<void()>;
|
||||
using ChangeCallback = std::function<void()>;
|
||||
|
||||
private:
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
@ -47,12 +47,13 @@ namespace SHADE
|
|||
//! response to call all the functions that need to be called. Specifically
|
||||
//! pipeline layouts that need to re-parse the newly reflected data and create
|
||||
//! descriptor set layouts and push constant ranges.
|
||||
std::vector<SHShaderChangeCallback> onChangeCallbacks;
|
||||
std::vector<ChangeCallback> onChangeCallbacks;
|
||||
|
||||
// #NoteToSelf: From Tomas module, pipeline shader stage create info isn't created here
|
||||
// because the struct allows specialization info which should not be part of a module itself.
|
||||
// This struct should be created in the pipeline instead.
|
||||
|
||||
void Recompile (void) noexcept;
|
||||
|
||||
public:
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
@ -67,8 +68,8 @@ namespace SHADE
|
|||
/* PUBLIC MEMBER FUNCTIONS */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
void Reflect (void) noexcept;
|
||||
void OnChange (void) noexcept;
|
||||
void AddCallback (SHShaderChangeCallback&& callback) noexcept;
|
||||
void OnChange (std::vector<uint32_t> const& newBinaryData) noexcept;
|
||||
void AddCallback (ChangeCallback&& callback) noexcept;
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* SETTERS AND GETTERS */
|
||||
|
@ -77,6 +78,7 @@ namespace SHADE
|
|||
vk::ShaderStageFlagBits GetShaderStageFlagBits (void) const noexcept;
|
||||
vk::ShaderModule GetVkShaderModule (void) const noexcept;
|
||||
SHShaderReflected const& GetReflectedData (void) const noexcept;
|
||||
std::string GetName (void) const noexcept;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue