Merge branch 'main' into SP3-4-Editor

This commit is contained in:
Sri Sham Haran 2022-11-17 13:34:34 +08:00
commit 920e977232
36 changed files with 639 additions and 336 deletions

View File

@ -21,141 +21,6 @@
Layer: 4294967295 Layer: 4294967295
Strength: 0 Strength: 0
Scripts: ~ Scripts: ~
- EID: 1
Name: Floor
IsActive: true
NumberOfChildren: 0
Components:
Transform Component:
Translate: {x: -1.440328, y: -4.41369677, z: -5}
Rotate: {x: -0, y: 0, z: -0}
Scale: {x: 49.4798889, y: 0.5, z: 17.5}
Renderable Component:
Mesh: 149697411
Material: 126974645
RigidBody Component:
Type: Static
Mass: 1
Drag: 0.00999999978
Angular Drag: 0.00999999978
Use Gravity: true
Interpolate: true
Freeze Position X: false
Freeze Position Y: false
Freeze Position Z: false
Freeze Rotation X: false
Freeze Rotation Y: false
Freeze Rotation Z: false
Collider Component:
Colliders:
- Is Trigger: false
Type: Box
Half Extents: {x: 1, y: 1, z: 1}
Friction: 0.400000006
Bounciness: 0
Density: 1
Position Offset: {x: 0, y: 0, z: 0}
Scripts: ~
- EID: 10
Name: Default
IsActive: true
NumberOfChildren: 0
Components:
Transform Component:
Translate: {x: -4.40482807, y: 2.57871056, z: -5.21213436}
Rotate: {x: -0.361265004, y: 1.11661232, z: -0.626627684}
Scale: {x: 0.999982238, y: 0.999987125, z: 0.999981165}
RigidBody Component:
Type: Dynamic
Mass: 1
Drag: 0
Angular Drag: 0
Use Gravity: true
Interpolate: true
Freeze Position X: false
Freeze Position Y: false
Freeze Position Z: false
Freeze Rotation X: false
Freeze Rotation Y: false
Freeze Rotation Z: false
Collider Component:
Colliders:
- Is Trigger: false
Type: Box
Half Extents: {x: 1, y: 1, z: 1}
Friction: 0.400000006
Bounciness: 0
Density: 1
Position Offset: {x: 0, y: 0, z: 0}
Scripts: ~
- EID: 3
Name: Empty
IsActive: true
NumberOfChildren: 0
Components:
Transform Component:
Translate: {x: -0.0094268322, y: 0, z: 0}
Rotate: {x: -0, y: 0, z: -0}
Scale: {x: 1, y: 1, z: 1}
Scripts: ~
- EID: 4
Name: Empty2
IsActive: true
NumberOfChildren: 0
Components:
Transform Component:
Translate: {x: 0, y: 0, z: 0}
Rotate: {x: 0, y: 0, z: 0}
Scale: {x: 1, y: 1, z: 1}
Scripts: ~
- EID: 9
Name: Bag
IsActive: true
NumberOfChildren: 0
Components:
Transform Component:
Translate: {x: 0, y: 0, z: 0}
Rotate: {x: 0, y: 0, z: 0}
Scale: {x: 1, y: 1, z: 1}
Renderable Component:
Mesh: 144838771
Material: 123745521
Scripts: ~
- EID: 6
Name: AI
IsActive: true
NumberOfChildren: 0
Components:
Transform Component:
Translate: {x: -8, y: -2, z: 2.5}
Rotate: {x: 0, y: 0, z: 0}
Scale: {x: 1, y: 1, z: 1}
Renderable Component:
Mesh: 149697411
Material: 126974645
RigidBody Component:
Type: Dynamic
Mass: 1
Drag: 0
Angular Drag: 0
Use Gravity: true
Interpolate: false
Freeze Position X: false
Freeze Position Y: false
Freeze Position Z: false
Freeze Rotation X: true
Freeze Rotation Y: true
Freeze Rotation Z: true
Collider Component:
Colliders:
- Is Trigger: false
Type: Box
Half Extents: {x: 0.5, y: 0.5, z: 0.5}
Friction: 0.400000006
Bounciness: 0
Density: 1
Position Offset: {x: 0, y: 0.5, z: 0}
Scripts: ~
- EID: 7 - EID: 7
Name: BigBoi Name: BigBoi
IsActive: true IsActive: true
@ -182,45 +47,3 @@
Layer: 4294967295 Layer: 4294967295
Strength: 0.25 Strength: 0.25
Scripts: ~ Scripts: ~
- EID: 5
Name: item
IsActive: true
NumberOfChildren: 0
Components:
Transform Component:
Translate: {x: 0, y: -2, z: -5}
Rotate: {x: 0, y: 0, z: 0}
Scale: {x: 2, y: 2, z: 2}
Renderable Component:
Mesh: 144838771
Material: 123745521
RigidBody Component:
Type: Dynamic
Mass: 1
Drag: 0
Angular Drag: 0
Use Gravity: true
Interpolate: false
Freeze Position X: false
Freeze Position Y: false
Freeze Position Z: false
Freeze Rotation X: true
Freeze Rotation Y: true
Freeze Rotation Z: true
Collider Component:
Colliders:
- Is Trigger: false
Type: Box
Half Extents: {x: 1, y: 1, z: 1}
Friction: 0.400000006
Bounciness: 0
Density: 1
Position Offset: {x: 0, y: 0.5, z: 0}
- Is Trigger: true
Type: Box
Half Extents: {x: 2, y: 2, z: 2}
Friction: 0.400000006
Bounciness: 0
Density: 1
Position Offset: {x: 0, y: 0.5, z: 0}
Scripts: ~

View File

@ -0,0 +1,50 @@
#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;
int textureIndex;
float alpha;
vec3 beta;
};
layout(location = 0) in struct
{
vec4 vertPos; // location 0
vec2 uv; // location = 1
vec4 normal; // location = 2
} In;
// material stuff
layout(location = 3) flat in struct
{
int materialIndex;
uint eid;
uint lightLayerIndex;
} In2;
layout (set = 0, binding = 1) uniform sampler2D textures[]; // for textures (global)
layout (std430, set = 3, 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;
void main()
{
position = In.vertPos;
normals = In.normal;
albedo = normals * texture(textures[nonuniformEXT(MatProp.data[In2.materialIndex].textureIndex)], In.uv) * MatProp.data[In2.materialIndex].color;
outEntityID = In2.eid;
lightLayerIndices = In2.lightLayerIndex;
}

Binary file not shown.

View File

@ -0,0 +1,3 @@
Name: Normals_FS
ID: 48689301
Type: 2

View File

@ -115,6 +115,7 @@ namespace Sandbox
SHSystemManager::RegisterRoutine<SHDebugDrawSystem, SHDebugDrawSystem::ProcessPointsRoutine>(); SHSystemManager::RegisterRoutine<SHDebugDrawSystem, SHDebugDrawSystem::ProcessPointsRoutine>();
SHSystemManager::RegisterRoutine<SHScriptEngine, SHScriptEngine::GizmosDrawRoutine>(); SHSystemManager::RegisterRoutine<SHScriptEngine, SHScriptEngine::GizmosDrawRoutine>();
SHSystemManager::RegisterRoutine<SHGraphicsSystem, SHGraphicsSystem::PrepareRenderRoutine>();
SHSystemManager::RegisterRoutine<SHGraphicsSystem, SHGraphicsSystem::BatcherDispatcherRoutine>(); SHSystemManager::RegisterRoutine<SHGraphicsSystem, SHGraphicsSystem::BatcherDispatcherRoutine>();
SHSystemManager::RegisterRoutine<SHGraphicsSystem, SHGraphicsSystem::BeginRoutine>(); SHSystemManager::RegisterRoutine<SHGraphicsSystem, SHGraphicsSystem::BeginRoutine>();

View File

@ -155,7 +155,17 @@ namespace SHADE
return AssetType::INVALID; return AssetType::INVALID;
} }
/**************************************************************************** std::optional<SHADE::SHAsset> SHAssetManager::GetAsset(AssetID id) noexcept
{
if (assetCollection.contains(id))
{
return assetCollection[id];
}
return {};
}
/****************************************************************************
* \brief Create record for new asset. CAN ONLY CREATE FOR CUSTOM * \brief Create record for new asset. CAN ONLY CREATE FOR CUSTOM
* ASSETS CREATED BY THE ENGINE. * ASSETS CREATED BY THE ENGINE.
* *

View File

@ -50,6 +50,7 @@ namespace SHADE
* \return const& to unordered_map<AssetName, AssetID> * \return const& to unordered_map<AssetName, AssetID>
****************************************************************************/ ****************************************************************************/
static std::vector<SHAsset> GetAllAssets() noexcept; static std::vector<SHAsset> GetAllAssets() noexcept;
static std::optional<SHAsset> GetAsset(AssetID id) noexcept;
static AssetType GetType(AssetID id) noexcept; static AssetType GetType(AssetID id) noexcept;

View File

@ -446,8 +446,8 @@ namespace SHADE
DrawContextMenu(component); DrawContextMenu(component);
Handle<SHMesh> const& mesh = component->GetMesh(); Handle<SHMesh> const& mesh = component->GetMesh();
Handle<SHMaterialInstance> const& mat = component->GetMaterial(); Handle<SHMaterialInstance> const& mat = component->GetMaterial();
const auto MESH_NAME = SHResourceManager::GetAssetName<SHMesh>(mesh).value_or("");
SHEditorWidgets::DragDropReadOnlyField<AssetID>("Mesh", std::to_string(SHResourceManager::GetAssetID<SHMesh>(mesh).value_or(0)).data(), [component]() SHEditorWidgets::DragDropReadOnlyField<AssetID>("Mesh", MESH_NAME, [component]()
{ {
Handle<SHMesh> const& mesh = component->GetMesh(); Handle<SHMesh> const& mesh = component->GetMesh();
return SHResourceManager::GetAssetID<SHMesh>(mesh).value_or(0); return SHResourceManager::GetAssetID<SHMesh>(mesh).value_or(0);
@ -463,13 +463,15 @@ namespace SHADE
SHResourceManager::FinaliseChanges(); SHResourceManager::FinaliseChanges();
}, SHDragDrop::DRAG_RESOURCE); }, SHDragDrop::DRAG_RESOURCE);
SHEditorWidgets::DragDropReadOnlyField<AssetID>("Material", mat ? std::to_string(SHResourceManager::GetAssetID<SHMaterial>(mat->GetBaseMaterial()).value_or(0)).data() : "", [component]() const auto MAT_NAME = mat ? SHResourceManager::GetAssetName<SHMaterial>(mat->GetBaseMaterial()).value_or("") : "";
{ SHEditorWidgets::DragDropReadOnlyField<AssetID>("Material", MAT_NAME,
Handle<SHMaterialInstance> const& mat = component->GetMaterial(); [component]()
if(!mat) {
return static_cast<AssetID>(0); Handle<SHMaterialInstance> const& mat = component->GetMaterial();
return SHResourceManager::GetAssetID<SHMaterial>(mat->GetBaseMaterial()).value_or(0); if (!mat)
}, return static_cast<AssetID>(0);
return SHResourceManager::GetAssetID<SHMaterial>(mat->GetBaseMaterial()).value_or(0);
},
[component](AssetID const& id) [component](AssetID const& id)
{ {
if (SHAssetManager::GetType(id) != AssetType::MATERIAL) if (SHAssetManager::GetType(id) != AssetType::MATERIAL)

View File

@ -78,7 +78,26 @@ namespace SHADE
ImGui::BeginDisabled(!isDirty); ImGui::BeginDisabled(!isDirty);
if(ImGui::Button(std::format("{} Save", ICON_MD_SAVE).data())) if(ImGui::Button(std::format("{} Save", ICON_MD_SAVE).data()))
{ {
//save auto gfxSystem = SHSystemManager::GetSystem<SHGraphicsSystem>();
// Replace Material if it's been instantiated
auto matHandle = SHResourceManager::Get<SHMaterial>(currentViewedMaterial);
if (matHandle)
{
// - Get Shader Modules
auto vertShader = SHResourceManager::LoadOrGet<SHVkShaderModule>(currentMatSpec->vertexShader);
auto fragShader = SHResourceManager::LoadOrGet<SHVkShaderModule>(currentMatSpec->fragShader);
if (vertShader && fragShader && gfxSystem)
{
// - Retrieve pipeline from pipeline library
auto renderPass = gfxSystem->GetPrimaryRenderpass();
auto subPass = renderPass->GetSubpass(currentMatSpec->subpassName);
auto pipeline = renderPass->GetOrCreatePipeline({ vertShader, fragShader }, subPass);
// - Set Pipeline
matHandle->SetPipeline(pipeline);
}
}
// Save Properties
if(auto matAsset = SHAssetManager::GetData<SHMaterialAsset>(currentViewedMaterial)) if(auto matAsset = SHAssetManager::GetData<SHMaterialAsset>(currentViewedMaterial))
{ {
YAML::Emitter out; YAML::Emitter out;
@ -102,7 +121,20 @@ namespace SHADE
currentMaterial->SetProperty(VARIABLE->offset, PROP_NODE.as<float>()); currentMaterial->SetProperty(VARIABLE->offset, PROP_NODE.as<float>());
break; break;
case SHADE::SHShaderBlockInterface::Variable::Type::INT: case SHADE::SHShaderBlockInterface::Variable::Type::INT:
currentMaterial->SetProperty(VARIABLE->offset, PROP_NODE.as<int>()); {
Handle<SHTexture> texture = SHResourceManager::LoadOrGet<SHTexture>(PROP_NODE.as<int>());
// HACK: Need to split this out to a separate pass before loading the materials and subsequently, the scenes
gfxSystem->BuildTextures();
if (texture)
{
matHandle->SetProperty(VARIABLE->offset, texture->TextureArrayIndex);
}
else
{
SHLOG_WARNING("[] Attempted to load invalid texture! Setting to 0.");
matHandle->SetProperty(VARIABLE->offset, 0);
}
}
break; break;
case SHADE::SHShaderBlockInterface::Variable::Type::VECTOR2: case SHADE::SHShaderBlockInterface::Variable::Type::VECTOR2:
currentMaterial->SetProperty(VARIABLE->offset, PROP_NODE.as<SHVec2>()); currentMaterial->SetProperty(VARIABLE->offset, PROP_NODE.as<SHVec2>());
@ -136,12 +168,38 @@ namespace SHADE
{ {
/*if(!shaderModule) /*if(!shaderModule)
return;*/ return;*/
auto gfxSystem = SHSystemManager::GetSystem<SHGraphicsSystem>();
auto interface = gfxSystem->GetDefaultMaterialInstance()->GetBaseMaterial()->GetShaderBlockInterface();
//auto interface = shaderModule->GetReflectedData().GetDescriptorBindingInfo().GetShaderBlockInterface(SHGraphicsConstants::DescriptorSetIndex::PER_INSTANCE, SHGraphicsConstants::DescriptorSetBindings::BATCHED_PER_INST_DATA); //auto interface = shaderModule->GetReflectedData().GetDescriptorBindingInfo().GetShaderBlockInterface(SHGraphicsConstants::DescriptorSetIndex::PER_INSTANCE, SHGraphicsConstants::DescriptorSetBindings::BATCHED_PER_INST_DATA);
int const varCount = static_cast<int>(interface->GetVariableCount()); // Shader
bool shaderChanged = false;
const auto* SHADER_INFO = SHAssetManager::GetData<SHShaderAsset>(currentMatSpec->fragShader);
const std::string SHADER_NAME = SHADER_INFO ? SHADER_INFO->name : "Unknown Shader";
ImGui::BeginDisabled();
isDirty |= SHEditorWidgets::DragDropReadOnlyField<AssetID>
(
"Fragment Shader", SHADER_NAME.data(),
[this]() { return currentMatSpec->fragShader; },
[this](const AssetID& id) { currentMatSpec->fragShader = id; },
SHDragDrop::DRAG_RESOURCE
);
ImGui::EndDisabled();
// Load the shader to access it's data
auto fragShader = SHResourceManager::LoadOrGet<SHVkShaderModule>(currentMatSpec->fragShader);
if (!fragShader)
return;
// Get interface for the shader combination
auto interface = fragShader->GetReflectedData().GetDescriptorBindingInfo().GetShaderBlockInterface
(
SHGraphicsConstants::DescriptorSetIndex::PER_INSTANCE,
SHGraphicsConstants::DescriptorSetBindings::BATCHED_PER_INST_DATA
);
if (!interface)
return;
// Properties
int const varCount = static_cast<int>(interface->GetVariableCount());
for (int i = 0; i < varCount; ++i) for (int i = 0; i < varCount; ++i)
{ {
auto variable = interface->GetVariable(i); auto variable = interface->GetVariable(i);

View File

@ -38,11 +38,11 @@ namespace SHADE
/// </summary> /// </summary>
std::vector<vk::DescriptorPoolSize> Limits = std::vector<vk::DescriptorPoolSize> Limits =
{ {
{ vk::DescriptorType::eCombinedImageSampler, 100 }, { vk::DescriptorType::eCombinedImageSampler, 1000 },
{ vk::DescriptorType::eUniformBuffer, 100 }, { vk::DescriptorType::eUniformBuffer, 1000 },
{ vk::DescriptorType::eUniformBufferDynamic, 100 }, { vk::DescriptorType::eUniformBufferDynamic, 1000 },
{ vk::DescriptorType::eStorageImage, 100}, { vk::DescriptorType::eStorageImage, 1000 },
{ vk::DescriptorType::eStorageBufferDynamic, 100 } { vk::DescriptorType::eStorageBufferDynamic, 1000 }
}; };
/// <summary> /// <summary>
/// Maximum number of descriptor sets allowed /// Maximum number of descriptor sets allowed

View File

@ -43,6 +43,85 @@ namespace SHADE
setAllDirtyFlags(); setAllDirtyFlags();
} }
SHBatch::SHBatch(SHBatch&& rhs)
: device { rhs.device }
, pipeline { rhs.pipeline }
, referencedMatInstances { std::move(rhs.referencedMatInstances) }
, matBufferDirty { std::move(rhs.matBufferDirty) }
, subBatches { std::move(rhs.subBatches) }
, drawData { std::move(drawData) }
, transformData { std::move(rhs.transformData) }
, instancedIntegerData { std::move(rhs.instancedIntegerData) }
, matPropsData { std::move(rhs.matPropsData) }
, matPropsDataSize { rhs.matPropsDataSize }
, singleMatPropAlignedSize { rhs.singleMatPropAlignedSize }
, singleMatPropSize { rhs.singleMatPropSize }
, isCPUBuffersDirty { rhs.isCPUBuffersDirty }
, drawDataBuffer { rhs.drawDataBuffer }
, transformDataBuffer { rhs.transformDataBuffer }
, instancedIntegerBuffer { rhs.instancedIntegerBuffer }
, matPropsBuffer { rhs.matPropsBuffer }
, matPropsDescSet { rhs.matPropsDescSet }
{
rhs.drawDataBuffer = {};
rhs.transformDataBuffer = {};
rhs.instancedIntegerBuffer = {};
rhs.matPropsBuffer = {};
rhs.matPropsDescSet = {};
}
SHBatch& SHBatch::operator=(SHBatch&& rhs)
{
if (this == &rhs)
return *this;
device = rhs.device ;
pipeline = rhs.pipeline ;
referencedMatInstances = std::move(rhs.referencedMatInstances);
matBufferDirty = std::move(rhs.matBufferDirty) ;
subBatches = std::move(rhs.subBatches) ;
drawData = std::move(drawData) ;
transformData = std::move(rhs.transformData) ;
instancedIntegerData = std::move(rhs.instancedIntegerData) ;
matPropsData = std::move(rhs.matPropsData) ;
matPropsDataSize = rhs.matPropsDataSize ;
singleMatPropAlignedSize = rhs.singleMatPropAlignedSize ;
singleMatPropSize = rhs.singleMatPropSize ;
isCPUBuffersDirty = rhs.isCPUBuffersDirty ;
drawDataBuffer = rhs.drawDataBuffer ;
transformDataBuffer = rhs.transformDataBuffer ;
instancedIntegerBuffer = rhs.instancedIntegerBuffer ;
matPropsBuffer = rhs.matPropsBuffer ;
matPropsDescSet = rhs.matPropsDescSet ;
// Unset values
rhs.drawDataBuffer = {};
rhs.transformDataBuffer = {};
rhs.instancedIntegerBuffer = {};
rhs.matPropsBuffer = {};
rhs.matPropsDescSet = {};
return *this;
}
SHBatch::~SHBatch()
{
// Free GPU buffers
for (int i = 0; i < SHGraphicsConstants::NUM_FRAME_BUFFERS; ++i)
{
if (drawDataBuffer[i])
drawDataBuffer[i].Free();
if (transformDataBuffer[i])
transformDataBuffer[i].Free();
if (instancedIntegerBuffer[i])
instancedIntegerBuffer[i].Free();
if (matPropsBuffer[i])
matPropsBuffer[i].Free();
if (matPropsDescSet[i])
matPropsDescSet[i].Free();
}
}
void SHBatch::Add(const SHRenderable* renderable) void SHBatch::Add(const SHRenderable* renderable)
{ {
// Ignore if null // Ignore if null

View File

@ -71,6 +71,11 @@ namespace SHADE
/* Constructor/Destructors */ /* Constructor/Destructors */
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
SHBatch(Handle<SHVkPipeline> pipeline); SHBatch(Handle<SHVkPipeline> pipeline);
SHBatch(const SHBatch&) = delete;
SHBatch(SHBatch&& rhs);
SHBatch& operator=(const SHBatch&) = delete;
SHBatch& operator=(SHBatch&& rhs);
~SHBatch();
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
/* Usage Functions */ /* Usage Functions */
@ -117,7 +122,7 @@ namespace SHADE
std::unique_ptr<char> matPropsData; std::unique_ptr<char> matPropsData;
Byte matPropsDataSize = 0; Byte matPropsDataSize = 0;
Byte singleMatPropAlignedSize = 0; Byte singleMatPropAlignedSize = 0;
Byte singleMatPropSize = 0; Byte singleMatPropSize = 0;
bool isCPUBuffersDirty = true; bool isCPUBuffersDirty = true;
// GPU Buffers // GPU Buffers
TripleBuffer drawDataBuffer; TripleBuffer drawDataBuffer;

View File

@ -69,9 +69,9 @@ namespace SHADE
batch->Remove(renderable); batch->Remove(renderable);
// If batch is empty, remove batch // TODO: If the pipeline is unloaded, we remove the batch
if (batch->IsEmpty()) /*if (batch->IsEmpty() && !batch->GetPipeline())
batches.erase(batch); batches.erase(batch);*/
} }
void SHSuperBatch::Clear() noexcept void SHSuperBatch::Clear() noexcept

View File

@ -570,13 +570,6 @@ namespace SHADE
return; return;
} }
// Finalise all batches
for (auto vp : viewports)
for (auto renderer : vp->GetRenderers())
{
renderer->GetRenderGraph()->FinaliseBatch(renderContext.GetCurrentFrame(), descPool);
}
// Resize // Resize
auto windowDims = window->GetWindowSize(); auto windowDims = window->GetWindowSize();
if (renderContext.GetResizeAndReset()) if (renderContext.GetResizeAndReset())
@ -591,6 +584,13 @@ namespace SHADE
// #BackEndTest: For for the fence initialized by queue submit // #BackEndTest: For for the fence initialized by queue submit
renderContext.WaitForFence(); renderContext.WaitForFence();
// Finalise all batches
for (auto vp : viewports)
for (auto renderer : vp->GetRenderers())
{
renderer->GetRenderGraph()->FinaliseBatch(renderContext.GetCurrentFrame(), descPool);
}
// #BackEndTest: Acquire the next image in the swapchain available // #BackEndTest: Acquire the next image in the swapchain available
renderContext.AcquireNextIamge(); renderContext.AcquireNextIamge();
const uint32_t CURR_FRAME_IDX_2 = renderContext.GetCurrentFrame(); const uint32_t CURR_FRAME_IDX_2 = renderContext.GetCurrentFrame();
@ -602,8 +602,6 @@ namespace SHADE
if (currFrameData.cmdPoolHdls.empty()) if (currFrameData.cmdPoolHdls.empty())
throw std::runtime_error("No command pools available!"); throw std::runtime_error("No command pools available!");
currFrameData.cmdPoolHdls[0]->Reset(); currFrameData.cmdPoolHdls[0]->Reset();
} }
/***************************************************************************/ /***************************************************************************/
@ -710,6 +708,11 @@ namespace SHADE
return resourceManager.Create<SHMaterialInstance>(materialInst->GetBaseMaterial()); return resourceManager.Create<SHMaterialInstance>(materialInst->GetBaseMaterial());
} }
std::pair<typename SHResourceHub::dense_iterator<SHMaterialInstance>, typename SHResourceHub::dense_iterator<SHMaterialInstance>> SHGraphicsSystem::GetAllMaterialInstances()
{
return resourceManager.GetDenseAccess<SHMaterialInstance>();
}
void SHGraphicsSystem::RemoveMaterialInstance(Handle<SHMaterialInstance> materialInstance) void SHGraphicsSystem::RemoveMaterialInstance(Handle<SHMaterialInstance> materialInstance)
{ {
resourceManager.Free(materialInstance); resourceManager.Free(materialInstance);
@ -807,7 +810,7 @@ namespace SHADE
void SHGraphicsSystem::BeginRoutine::Execute(double) noexcept void SHGraphicsSystem::BeginRoutine::Execute(double) noexcept
{ {
SHResourceManager::FinaliseChanges(); // Begin rendering
reinterpret_cast<SHGraphicsSystem*>(system)->BeginRender(); reinterpret_cast<SHGraphicsSystem*>(system)->BeginRender();
} }
@ -833,6 +836,36 @@ namespace SHADE
void SHGraphicsSystem::EndRoutine::Execute(double) noexcept void SHGraphicsSystem::EndRoutine::Execute(double) noexcept
{ {
reinterpret_cast<SHGraphicsSystem*>(system)->EndRender(); reinterpret_cast<SHGraphicsSystem*>(system)->EndRender();
// Reset all material isDirty
auto gfxSystem = reinterpret_cast<SHGraphicsSystem*>(system);
auto [matBegin, matEnd] = gfxSystem->resourceManager.GetDenseAccess<SHMaterial>();
for (auto iter = matBegin; iter != matEnd; ++iter)
{
iter->ClearChangeFlag();
}
}
SHGraphicsSystem::PrepareRenderRoutine::PrepareRenderRoutine()
: SHSystemRoutine("Graphics System Pre-Render", true)
{}
void SHGraphicsSystem::PrepareRenderRoutine::Execute(double) noexcept
{
// Finish up, loading, unloading any resources
SHResourceManager::FinaliseChanges();
// Clean up and update all materials
auto gfxSystem = reinterpret_cast<SHGraphicsSystem*>(system);
auto [matInstBegin, matInstEnd] = gfxSystem->resourceManager.GetDenseAccess<SHMaterialInstance>();
for (auto iter = matInstBegin; iter != matInstEnd; ++iter)
{
auto baseMat = iter->GetBaseMaterial();
if (baseMat && baseMat->HasPipelineChanged())
{
iter->ResetProperties();
}
}
} }
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
@ -844,9 +877,12 @@ namespace SHADE
void SHGraphicsSystem::BatcherDispatcherRoutine::Execute(double) noexcept void SHGraphicsSystem::BatcherDispatcherRoutine::Execute(double) noexcept
{ {
auto& renderables = SHComponentManager::GetDense<SHRenderable>(); auto& renderables = SHComponentManager::GetDense<SHRenderable>();
for (auto& renderable : renderables) for (auto& renderable : renderables)
{ {
// Check if the material instance is now unused
renderable.CleanUpMaterials();
if (!renderable.HasChanged()) if (!renderable.HasChanged())
continue; continue;
@ -858,8 +894,7 @@ namespace SHADE
oldSuperBatch->Remove(&renderable); oldSuperBatch->Remove(&renderable);
} }
// Add to new SuperBatch if there is a material // Add to new SuperBatch if there is a material and a mesh to render
// Add to new SuperBatch if there is a material and a mesh to render
Handle<SHMaterialInstance> newMatInstance = renderable.GetMaterial(); Handle<SHMaterialInstance> newMatInstance = renderable.GetMaterial();
if (newMatInstance && renderable.GetMesh()) if (newMatInstance && renderable.GetMesh())
{ {

View File

@ -95,25 +95,31 @@ namespace SHADE
class SH_API BeginRoutine final : public SHSystemRoutine class SH_API BeginRoutine final : public SHSystemRoutine
{ {
public: public:
BeginRoutine(); BeginRoutine();
virtual void Execute(double dt) noexcept override final; virtual void Execute(double dt) noexcept override final;
}; };
class SH_API RenderRoutine final : public SHSystemRoutine class SH_API RenderRoutine final : public SHSystemRoutine
{ {
public: public:
RenderRoutine(); RenderRoutine();
virtual void Execute(double dt) noexcept override final; virtual void Execute(double dt) noexcept override final;
}; };
class SH_API EndRoutine final : public SHSystemRoutine class SH_API EndRoutine final : public SHSystemRoutine
{ {
public: public:
EndRoutine(); EndRoutine();
virtual void Execute(double dt) noexcept override final;
};
class SH_API PrepareRenderRoutine final : public SHSystemRoutine
{
public:
PrepareRenderRoutine();
virtual void Execute(double dt) noexcept override final; virtual void Execute(double dt) noexcept override final;
}; };
class SH_API BatcherDispatcherRoutine final : public SHSystemRoutine class SH_API BatcherDispatcherRoutine final : public SHSystemRoutine
{ {
public: public:
BatcherDispatcherRoutine(); BatcherDispatcherRoutine();
virtual void Execute(double dt) noexcept override final; virtual void Execute(double dt) noexcept override final;
}; };
@ -156,6 +162,7 @@ namespace SHADE
Handle<SHMaterialInstance> AddOrGetBaseMaterialInstance(); Handle<SHMaterialInstance> AddOrGetBaseMaterialInstance();
Handle<SHMaterialInstance> AddOrGetBaseMaterialInstance(Handle<SHMaterial> material); Handle<SHMaterialInstance> AddOrGetBaseMaterialInstance(Handle<SHMaterial> material);
Handle<SHMaterialInstance> AddMaterialInstanceCopy(Handle<SHMaterialInstance> materialInst); Handle<SHMaterialInstance> AddMaterialInstanceCopy(Handle<SHMaterialInstance> materialInst);
std::pair<typename SHResourceHub::dense_iterator<SHMaterialInstance>, typename SHResourceHub::dense_iterator<SHMaterialInstance>> GetAllMaterialInstances();
void RemoveMaterialInstance(Handle<SHMaterialInstance> materialInstance); void RemoveMaterialInstance(Handle<SHMaterialInstance> materialInstance);
Handle<SHMaterial> GetDefaultMaterial() { return defaultMaterial; } Handle<SHMaterial> GetDefaultMaterial() { return defaultMaterial; }
Handle<SHMaterialInstance> GetDefaultMaterialInstance() { return AddOrGetBaseMaterialInstance(defaultMaterial); } Handle<SHMaterialInstance> GetDefaultMaterialInstance() { return AddOrGetBaseMaterialInstance(defaultMaterial); }
@ -166,10 +173,10 @@ namespace SHADE
/*******************************************************************************/ /*******************************************************************************/
/*! /*!
\brief \brief
Adds a mesh to the Mesh Library. But this does not mean that the meshes have Adds a mesh to the Mesh Library. But this does not mean that the meshes have
been added yet. A call to "BuildBuffers()" is required to transfer all been added yet. A call to "BuildBuffers()" is required to transfer all
meshes into the GPU. meshes into the GPU.
\param vertexCount \param vertexCount
Number of vertices in this Mesh. Number of vertices in this Mesh.

View File

@ -6,91 +6,109 @@
#include "Graphics/Shaders/BlockInterface/SHShaderBlockInterface.h" #include "Graphics/Shaders/BlockInterface/SHShaderBlockInterface.h"
#include "Math/Vector/SHVec3.h" #include "Math/Vector/SHVec3.h"
#include "Math/Vector/SHVec4.h" #include "Math/Vector/SHVec4.h"
#include "ECS_Base/Managers/SHSystemManager.h"
#include "SHGraphicsSystem.h"
#include "SHMaterialInstance.h"
namespace SHADE namespace SHADE
{ {
/*---------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
/* Pipeline Functions */ /* Pipeline Functions */
/*---------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
void SHMaterial::SetPipeline(Handle<SHVkPipeline> _pipeline) void SHMaterial::SetPipeline(Handle<SHVkPipeline> _pipeline)
{ {
pipeline = _pipeline; // Reassignment, we ignore
if (_pipeline == pipeline)
return;
// Set up properties based on the pipeline pipeline = _pipeline;
if (!pipeline)
{
// Clear memory and all that
propMemory.reset();
return;
}
// Allocate memory for properties // Set up properties based on the pipeline
const Handle<SHShaderBlockInterface> SHADER_INFO = GetShaderBlockInterface(); if (pipeline)
propMemorySize = SHADER_INFO ? SHADER_INFO->GetBytesRequired() : 0;
if (propMemorySize <= 0)
{
propMemory.reset();
}
else
{
propMemory.reset(new char[propMemorySize]);
}
ResetProperties();
}
Handle<SHVkPipeline> SHMaterial::GetPipeline() const
{
return pipeline;
}
/*---------------------------------------------------------------------------------*/
/* Property Functions */
/*---------------------------------------------------------------------------------*/
void SHMaterial::ResetProperties()
{ {
// Reset all the properties to default values // Allocate memory for properties
if (propMemory) const Handle<SHShaderBlockInterface> SHADER_INFO = GetShaderBlockInterface();
memset(propMemory.get(), 0, propMemorySize); propMemorySize = SHADER_INFO ? SHADER_INFO->GetBytesRequired() : 0;
if (propMemorySize <= 0)
// Initialize Vectors to all 1.0 by default {
const Handle<SHShaderBlockInterface> SHADER_INFO = GetShaderBlockInterface(); propMemory.reset();
for (int i = 0; i < SHADER_INFO->GetVariableCount(); ++i) }
{ else
const auto& VAR = SHADER_INFO->GetVariable(i); {
switch (VAR->type) propMemory.reset(new char[propMemorySize]);
{ }
case SHShaderBlockInterface::Variable::Type::VECTOR3:
setPropertyUnsafe(VAR->offset, SHVec3::One);
break;
case SHShaderBlockInterface::Variable::Type::VECTOR4:
setPropertyUnsafe(VAR->offset, SHVec4::One);
break;
}
}
} }
void SHMaterial::ExportProperties(void* dest) const noexcept // Reset since pipeline changed
{ ResetProperties();
if (propMemory)
memcpy(dest, propMemory.get(), propMemorySize);
}
size_t SHMaterial::GetPropertiesMemorySize() const noexcept // Mark changed so that we know to update dependent material instances
{ propertiesChanged = true;
const Handle<SHShaderBlockInterface> SHADER_INFO = GetShaderBlockInterface(); }
return SHADER_INFO ? SHADER_INFO->GetBytesRequired() : 0;
}
/*---------------------------------------------------------------------------------*/ Handle<SHVkPipeline> SHMaterial::GetPipeline() const
/* Helper Functions */ {
/*---------------------------------------------------------------------------------*/ return pipeline;
Handle<SHShaderBlockInterface> SHMaterial::GetShaderBlockInterface() const noexcept }
{
return pipeline->GetPipelineLayout()->GetShaderBlockInterface /*-----------------------------------------------------------------------------------*/
( /* Property Functions */
SHGraphicsConstants::DescriptorSetIndex::PER_INSTANCE, /*-----------------------------------------------------------------------------------*/
SHGraphicsConstants::DescriptorSetBindings::BATCHED_PER_INST_DATA, void SHMaterial::ResetProperties()
vk::ShaderStageFlagBits::eFragment {
); // Reset all the properties to default values
} if (propMemory)
memset(propMemory.get(), 0, propMemorySize);
// Initialize Vectors to all 1.0 by default
const Handle<SHShaderBlockInterface> SHADER_INFO = GetShaderBlockInterface();
for (int i = 0; i < SHADER_INFO->GetVariableCount(); ++i)
{
const auto& VAR = SHADER_INFO->GetVariable(i);
switch (VAR->type)
{
case SHShaderBlockInterface::Variable::Type::VECTOR3:
setPropertyUnsafe(VAR->offset, SHVec3::One);
break;
case SHShaderBlockInterface::Variable::Type::VECTOR4:
setPropertyUnsafe(VAR->offset, SHVec4::One);
break;
}
}
propertiesChanged = true;
}
void SHMaterial::ExportProperties(void* dest) const noexcept
{
if (propMemory)
memcpy(dest, propMemory.get(), propMemorySize);
}
size_t SHMaterial::GetPropertiesMemorySize() const noexcept
{
const Handle<SHShaderBlockInterface> SHADER_INFO = GetShaderBlockInterface();
return SHADER_INFO ? SHADER_INFO->GetBytesRequired() : 0;
}
/*-----------------------------------------------------------------------------------*/
/* Helper Functions */
/*-----------------------------------------------------------------------------------*/
Handle<SHShaderBlockInterface> SHMaterial::GetShaderBlockInterface() const noexcept
{
return pipeline->GetPipelineLayout()->GetShaderBlockInterface
(
SHGraphicsConstants::DescriptorSetIndex::PER_INSTANCE,
SHGraphicsConstants::DescriptorSetBindings::BATCHED_PER_INST_DATA,
vk::ShaderStageFlagBits::eFragment
);
}
/*-----------------------------------------------------------------------------------*/
/* Query Functions */
/*-----------------------------------------------------------------------------------*/
void SHMaterial::ClearChangeFlag() noexcept
{
propertiesChanged = false;
}
} }

View File

@ -36,7 +36,7 @@ namespace SHADE
Describes a Pipeline along with it's associated properties for this instance. Describes a Pipeline along with it's associated properties for this instance.
*/ */
/***********************************************************************************/ /***********************************************************************************/
class SH_API SHMaterial class SH_API SHMaterial : public ISelfHandle<SHMaterial>
{ {
public: public:
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
@ -68,6 +68,10 @@ namespace SHADE
/* Query Functions */ /* Query Functions */
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
Handle<SHShaderBlockInterface> GetShaderBlockInterface() const noexcept; Handle<SHShaderBlockInterface> GetShaderBlockInterface() const noexcept;
bool HasPipelineChanged() const noexcept { return pipelineChanged; }
bool HasPropertiesChanged() const noexcept { return propertiesChanged; }
bool HasChanged() const noexcept { return pipelineChanged || propertiesChanged; }
void ClearChangeFlag() noexcept;
private: private:
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
@ -76,6 +80,8 @@ namespace SHADE
Handle<SHVkPipeline> pipeline; Handle<SHVkPipeline> pipeline;
std::unique_ptr<char> propMemory; std::unique_ptr<char> propMemory;
Byte propMemorySize = 0; Byte propMemorySize = 0;
bool propertiesChanged = true;
bool pipelineChanged = true;
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
/* Helper Functions */ /* Helper Functions */

View File

@ -33,8 +33,7 @@ namespace SHADE
} }
// Get offset and modify the memory directly // Get offset and modify the memory directly
T* dataPtr = reinterpret_cast<T*>(propMemory.get() + PROP_INFO->offset); setPropertyUnsafe(PROP_INFO->offset, value);
*dataPtr = value;
} }
template<typename T> template<typename T>
@ -85,6 +84,12 @@ namespace SHADE
template<typename T> template<typename T>
void SHMaterial::setPropertyUnsafe(uint32_t memOffset, const T& value) void SHMaterial::setPropertyUnsafe(uint32_t memOffset, const T& value)
{ {
// Size check
if (memOffset + sizeof(T) > propMemorySize)
{
throw std::runtime_error("Attempted to write to out of bounds MaterialInstance properties memory");
}
(*reinterpret_cast<T*>(propMemory.get() + memOffset)) = value; (*reinterpret_cast<T*>(propMemory.get() + memOffset)) = value;
propertiesChanged = true;
} }
} }

View File

@ -31,11 +31,11 @@ namespace SHADE
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
void SHMaterialInstance::ResetProperties() noexcept void SHMaterialInstance::ResetProperties() noexcept
{ {
// Reset all the properties to default values // Reset all the properties to default values
memset(dataStore.get(), 0, dataStoreSize); memset(dataStore.get(), 0, dataStoreSize);
overrideData.clear(); overrideData.clear();
dataStore.reset(); dataStore.reset();
dataWasChanged = true;
} }
void SHMaterialInstance::ExportProperties(void* dest) void SHMaterialInstance::ExportProperties(void* dest)
@ -65,9 +65,17 @@ namespace SHADE
dataWasChanged = false; dataWasChanged = false;
} }
/*---------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
/* Helper Functions */ /* Query Functions */
/*---------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
bool SHMaterialInstance::HasChanged() const noexcept
{
return dataWasChanged || (baseMaterial && baseMaterial->HasChanged());
}
/*-----------------------------------------------------------------------------------*/
/* Helper Functions */
/*-----------------------------------------------------------------------------------*/
Handle<SHShaderBlockInterface> SHMaterialInstance::getShaderBlockInterface() const noexcept Handle<SHShaderBlockInterface> SHMaterialInstance::getShaderBlockInterface() const noexcept
{ {
return baseMaterial->GetPipeline()->GetPipelineLayout()->GetShaderBlockInterface return baseMaterial->GetPipeline()->GetPipelineLayout()->GetShaderBlockInterface

View File

@ -69,7 +69,8 @@ namespace SHADE
/* Getter Functions */ /* Getter Functions */
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
Handle<SHMaterial> GetBaseMaterial() const noexcept { return baseMaterial; } Handle<SHMaterial> GetBaseMaterial() const noexcept { return baseMaterial; }
bool HasChanged() const noexcept { return dataWasChanged; } bool HasChanged() const noexcept;
bool IsBlank() const noexcept { return overrideData.empty(); } // No overrides
private: private:
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/

View File

@ -59,6 +59,12 @@ namespace SHADE
od.StoredDataOffset = lastInsertedData.StoredDataOffset + lastInsertedData.DataSize; od.StoredDataOffset = lastInsertedData.StoredDataOffset + lastInsertedData.DataSize;
} }
// Size check
if (od.StoredDataOffset + sizeof(T) > dataStoreSize)
{
throw std::runtime_error("Attempted to write to out of bounds MaterialInstance properties memory");
}
// Save the override data information // Save the override data information
overrideData.emplace_back(std::move(od)); overrideData.emplace_back(std::move(od));
existingOverride = overrideData.end() - 1; existingOverride = overrideData.end() - 1;

View File

@ -97,6 +97,14 @@ namespace SHADE
return material; return material;
} }
void SHRenderable::CleanUpMaterials() noexcept
{
if (material && material->IsBlank())
{
SetMaterial(sharedMaterial);
}
}
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
/* Mesh Functions */ /* Mesh Functions */
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
@ -115,6 +123,20 @@ namespace SHADE
return lightLayer; return lightLayer;
} }
bool SHRenderable::HasChanged() const noexcept
{
if (matChanged || meshChanged)
return true;
// If the underlying material has changed
auto mat = GetMaterial();
if (mat)
{
return mat->HasChanged();
}
return false;
}
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
/* Batcher Dispatcher Functions */ /* Batcher Dispatcher Functions */
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/

View File

@ -53,6 +53,10 @@ namespace SHADE
Handle<SHMaterialInstance> GetModifiableMaterial(); Handle<SHMaterialInstance> GetModifiableMaterial();
Handle<SHMaterialInstance> GetPrevMaterial() const noexcept { return oldMaterial; } Handle<SHMaterialInstance> GetPrevMaterial() const noexcept { return oldMaterial; }
bool HasMaterialChanged() const noexcept { return matChanged; } bool HasMaterialChanged() const noexcept { return matChanged; }
/// <summary>
/// Clears the modifiable material if it is unused.
/// </summary>
void CleanUpMaterials() noexcept;
/*-------------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------------*/
/* Mesh Functions */ /* Mesh Functions */
@ -70,7 +74,7 @@ namespace SHADE
/*-------------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------------*/
/* Batcher Dispatcher Functions */ /* Batcher Dispatcher Functions */
/*-------------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------------*/
bool HasChanged() const noexcept { return matChanged || meshChanged; } // Whether or not the mesh or material has changed bool HasChanged() const noexcept; // Whether or not the mesh or material has changed
void ResetChangedFlag(); // TODO: Lock it so that only SHBatcherDispatcher can access this void ResetChangedFlag(); // TODO: Lock it so that only SHBatcherDispatcher can access this
private: private:

View File

@ -34,7 +34,7 @@ namespace SHADE
{ {
colorBlendState.attachments.push_back(vk::PipelineColorBlendAttachmentState colorBlendState.attachments.push_back(vk::PipelineColorBlendAttachmentState
{ {
.blendEnable = SHVkUtil::IsBlendCompatible (subpass->GetFormatFromAttachmentReference(att.attachment)) ? true : false, .blendEnable = SHVkUtil::IsBlendCompatible(subpass->GetFormatFromAttachmentReference(att.attachment)),
.srcColorBlendFactor = vk::BlendFactor::eSrcAlpha, .srcColorBlendFactor = vk::BlendFactor::eSrcAlpha,
.dstColorBlendFactor = vk::BlendFactor::eOneMinusSrcAlpha, .dstColorBlendFactor = vk::BlendFactor::eOneMinusSrcAlpha,
.colorBlendOp = vk::BlendOp::eAdd, .colorBlendOp = vk::BlendOp::eAdd,

View File

@ -129,11 +129,11 @@ namespace SHADE
for (auto& predResource : prereq->attResources) for (auto& predResource : prereq->attResources)
{ {
// if a predecessor's resource is used by this node, we want to copy the final layout from the pred to the initial of this node // if a predecessor's resource is used by this node, we want to copy the final layout from the pred to the initial of this node
if (uint64_t resourceID = predResource.GetId().Raw; node->resourceAttachmentMapping.contains(resourceID)) if (uint64_t resourceID = predResource.GetId().Raw; node->resourceAttachmentMapping->contains(resourceID))
{ {
// Get the resource's attachment index in BOTH the predecessor and the current node // Get the resource's attachment index in BOTH the predecessor and the current node
uint32_t prereqResourceAttIndex = prereq->resourceAttachmentMapping[resourceID]; uint32_t prereqResourceAttIndex = prereq->resourceAttachmentMapping->at(resourceID);
uint32_t resourceAttIndex = node->resourceAttachmentMapping[resourceID]; uint32_t resourceAttIndex = node->resourceAttachmentMapping->at(resourceID);
// Use the resource attachment index to get the attachment description in the renderpass // Use the resource attachment index to get the attachment description in the renderpass
auto& attDesc = node->attachmentDescriptions[resourceAttIndex]; auto& attDesc = node->attachmentDescriptions[resourceAttIndex];

View File

@ -124,7 +124,7 @@ namespace SHADE
, framebuffers{} , framebuffers{}
, prereqNodes{ std::move(predecessors) } , prereqNodes{ std::move(predecessors) }
, attachmentDescriptions{} , attachmentDescriptions{}
, resourceAttachmentMapping{} , resourceAttachmentMapping { new std::unordered_map<uint64_t, uint32_t> }
, attResources{ } , attResources{ }
, subpasses{} , subpasses{}
, executed{ false } , executed{ false }
@ -163,7 +163,7 @@ namespace SHADE
if (attResources[i]->resourceTypeFlags & static_cast<uint32_t>(SH_ATT_DESC_TYPE_FLAGS::COLOR_PRESENT)) if (attResources[i]->resourceTypeFlags & static_cast<uint32_t>(SH_ATT_DESC_TYPE_FLAGS::COLOR_PRESENT))
containsSwapchainImage = true; containsSwapchainImage = true;
resourceAttachmentMapping.try_emplace(attResources[i].GetId().Raw, i); resourceAttachmentMapping->try_emplace(attResources[i].GetId().Raw, i);
} }
if (!containsSwapchainImage) if (!containsSwapchainImage)
@ -254,7 +254,7 @@ namespace SHADE
( (
subpassName, subpassName,
graphStorage, GetHandle(), static_cast<uint32_t>(subpasses.size()), graphStorage, GetHandle(), static_cast<uint32_t>(subpasses.size()),
&resourceAttachmentMapping resourceAttachmentMapping.get()
) )
); );
subpassIndexing.try_emplace(subpassName, static_cast<uint32_t>(subpasses.size()) - 1u); subpassIndexing.try_emplace(subpassName, static_cast<uint32_t>(subpasses.size()) - 1u);

View File

@ -60,7 +60,7 @@ namespace SHADE
std::vector<vk::SubpassDependency> spDeps; std::vector<vk::SubpassDependency> spDeps;
//! For indexing resources fast //! For indexing resources fast
std::unordered_map<uint64_t, uint32_t> resourceAttachmentMapping; std::unique_ptr<std::unordered_map<uint64_t, uint32_t>> resourceAttachmentMapping;
//! For indexing subpasses //! For indexing subpasses
std::map<std::string, uint32_t> subpassIndexing; std::map<std::string, uint32_t> subpassIndexing;

View File

@ -97,7 +97,7 @@ namespace SHADE
colorReferences = std::move(rhs.colorReferences); colorReferences = std::move(rhs.colorReferences);
depthReferences = std::move(rhs.depthReferences); depthReferences = std::move(rhs.depthReferences);
inputReferences = std::move(rhs.inputReferences); inputReferences = std::move(rhs.inputReferences);
resourceAttachmentMapping = rhs.resourceAttachmentMapping; resourceAttachmentMapping = std::move(rhs.resourceAttachmentMapping);
descriptorSetLayout = rhs.descriptorSetLayout; descriptorSetLayout = rhs.descriptorSetLayout;
exteriorDrawCalls = std::move(rhs.exteriorDrawCalls); exteriorDrawCalls = std::move(rhs.exteriorDrawCalls);
graphStorage = rhs.graphStorage; graphStorage = rhs.graphStorage;

View File

@ -86,8 +86,16 @@ namespace SHADE
{ {
if (bufferHandle) if (bufferHandle)
{ {
// Resize // Resize if we need to resize
bufferHandle->ResizeReplace(size, src, size); if (bufferHandle->GetSizeStored() < size)
{
bufferHandle->ResizeReplace(size, src, size);
}
// Otherwise just copy the data over
else
{
bufferHandle->MapWriteUnmap(src, size, 0, 0);
}
} }
else else
{ {
@ -113,8 +121,16 @@ namespace SHADE
{ {
if (bufferHandle) if (bufferHandle)
{ {
// Resize // Resize if we need to resize
bufferHandle->ResizeReplace(size, src, size); // TODO: Set to host visible method? if (bufferHandle->GetSizeStored() < size)
{
bufferHandle->ResizeReplace(size, src, size);
}
// Otherwise just copy the data over
else
{
bufferHandle->MapWriteUnmap(src, size, 0, 0);
}
} }
else else
{ {

View File

@ -38,6 +38,11 @@ namespace SHADE
class SHResourceLibrary : public SHResourceLibraryBase class SHResourceLibrary : public SHResourceLibraryBase
{ {
public: public:
/*-----------------------------------------------------------------------------*/
/* Type Definitions */
/*-----------------------------------------------------------------------------*/
using dense_iterator = typename SparseSet<T>::dense_iterator;
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
/* Constructor */ /* Constructor */
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
@ -74,6 +79,16 @@ namespace SHADE
/// <returns>Read-only reference to the resource object.</returns> /// <returns>Read-only reference to the resource object.</returns>
const T& Get(Handle<T> handle) const; const T& Get(Handle<T> handle) const;
/*-----------------------------------------------------------------------------*/
/* Direct Dense Access Functions */
/*-----------------------------------------------------------------------------*/
/// <summary>
/// Provides access to the dense array of the SparseSet.
/// These iterators should not be used to manipulate the underlying vector.
/// </summary>
/// <returns>Pair of begin and end iterators to the dense vector.</returns>
std::pair<dense_iterator, dense_iterator> GetDenseAccess();
private: private:
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
/* Data Members */ /* Data Members */
@ -96,6 +111,12 @@ namespace SHADE
class SHResourceHub final class SHResourceHub final
{ {
public: public:
/*-----------------------------------------------------------------------------*/
/* Type Definitions */
/*-----------------------------------------------------------------------------*/
template<typename T>
using dense_iterator = typename SHResourceLibrary<T>::dense_iterator;
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
/* Constructors/Destructors */ /* Constructors/Destructors */
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
@ -138,6 +159,18 @@ namespace SHADE
template<typename T> template<typename T>
const T& Get(Handle<T> handle) const; const T& Get(Handle<T> handle) const;
/*-----------------------------------------------------------------------------*/
/* Direct Dense Access Functions */
/*-----------------------------------------------------------------------------*/
/// <summary>
/// Provides access to the dense array of the SparseSet.
/// These iterators should not be used to manipulate the underlying vector.
/// </summary>
/// <typeparam name="T">Type of resource to access.</typeparam>
/// <returns>Pair of begin and end iterators to the dense vector.</returns>
template <typename T>
std::pair<dense_iterator<T>, dense_iterator<T>> GetDenseAccess();
private: private:
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
/* Type Definition */ /* Type Definition */

View File

@ -79,6 +79,15 @@ namespace SHADE
return objects[handle.GetId().Data.Index]; return objects[handle.GetId().Data.Index];
} }
/*---------------------------------------------------------------------------------*/
/* ResourceLibrary - Direct Dense Access Functions */
/*---------------------------------------------------------------------------------*/
template<typename T>
std::pair<typename SHResourceLibrary<T>::dense_iterator, typename SHResourceLibrary<T>::dense_iterator> SHResourceLibrary<T>::GetDenseAccess()
{
return objects.GetDenseAccess();
}
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
/* ResourceLibrary - Helper Functions */ /* ResourceLibrary - Helper Functions */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
@ -105,7 +114,7 @@ namespace SHADE
} }
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
/* ResourceManager - Usage Functions */ /* ResourceHub - Usage Functions */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
template <typename T, typename ... Args> template <typename T, typename ... Args>
Handle<T> SHResourceHub::Create(Args&&... args) Handle<T> SHResourceHub::Create(Args&&... args)
@ -132,7 +141,7 @@ namespace SHADE
} }
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
/* ResourceManager - Helper Functions */ /* ResourceHub - Helper Functions */
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
template <typename T> template <typename T>
SHResourceLibrary<T>& SHResourceHub::getLibrary() SHResourceLibrary<T>& SHResourceHub::getLibrary()
@ -161,4 +170,13 @@ namespace SHADE
{ {
return const_cast<SHResourceHub*>(this).getLibrary<T>(); return const_cast<SHResourceHub*>(this).getLibrary<T>();
} }
/*---------------------------------------------------------------------------------*/
/* ResourceHub - Direct Dense Access Functions */
/*---------------------------------------------------------------------------------*/
template <typename T>
std::pair<typename SHResourceHub::dense_iterator<T>, typename SHResourceHub::dense_iterator<T>> SHResourceHub::GetDenseAccess()
{
return getLibrary<T>().GetDenseAccess();
}
} }

View File

@ -103,4 +103,17 @@ namespace SHADE
return {}; return {};
} }
std::optional<std::string> SHResourceManager::GetAssetName(Handle<void> handle)
{
const Handle GENERIC_HANDLE = Handle(handle);
auto assetId = GetAssetID(GENERIC_HANDLE);
if (assetId.has_value())
{
const auto ASSET_INFO = SHAssetManager::GetAsset(assetId.value());
if (ASSET_INFO.has_value())
return ASSET_INFO.value().name;
}
return {};
}
} }

View File

@ -13,8 +13,6 @@ of DigiPen Institute of Technology is prohibited.
// STL Includes // STL Includes
#include <unordered_map> #include <unordered_map>
namespace SHADE { class SHMaterial; }
// Project Includes // Project Includes
#include "SH_API.h" #include "SH_API.h"
#include "SHResourceLibrary.h" #include "SHResourceLibrary.h"
@ -31,17 +29,26 @@ namespace SHADE { class SHMaterial; }
namespace SHADE namespace SHADE
{ {
/*-----------------------------------------------------------------------------------*/
/* Forward Declarations */
/*-----------------------------------------------------------------------------------*/
class SHMaterial;
/*-----------------------------------------------------------------------------------*/
/* Type Definitions */
/*-----------------------------------------------------------------------------------*/
/// <summary> /// <summary>
/// Template structs that maps a resource to their loaded asset representation type. /// Template structs that maps a resource to their loaded asset representation type.
/// </summary> /// </summary>
template<typename T = void> template<typename T = void>
struct SHResourceLoader { using AssetType = void; }; struct SHResourceLoader { using AssetType = void; };
template<> struct SHResourceLoader<SHMesh> { using AssetType = SHMeshData; }; template<> struct SHResourceLoader<SHMesh> { using AssetType = SHMeshData; };
template<> struct SHResourceLoader<SHTexture> { using AssetType = SHTextureAsset; }; template<> struct SHResourceLoader<SHTexture> { using AssetType = SHTextureAsset; };
template<> struct SHResourceLoader<SHVkShaderModule> { using AssetType = SHShaderAsset; }; template<> struct SHResourceLoader<SHVkShaderModule> { using AssetType = SHShaderAsset; };
template<> struct SHResourceLoader<SHMaterialSpec> { using AssetType = SHMaterialAsset; }; template<> struct SHResourceLoader<SHMaterialSpec> { using AssetType = SHMaterialAsset; };
template<> struct SHResourceLoader<SHMaterial> { using AssetType = SHMaterialSpec; }; template<> struct SHResourceLoader<SHMaterial> { using AssetType = SHMaterialSpec; };
/// <summary>
/// <summary>
/// Static class responsible for loading and caching runtime resources from their /// Static class responsible for loading and caching runtime resources from their
/// serialised Asset IDs. /// serialised Asset IDs.
/// </summary> /// </summary>
@ -57,9 +64,7 @@ namespace SHADE
/// Note that for specific types, the retrieved Handle may not be valid until after /// Note that for specific types, the retrieved Handle may not be valid until after
/// FinaliseChanges() is called. /// FinaliseChanges() is called.
/// </summary> /// </summary>
/// <typeparam name="ResourceType"> /// <typeparam name="ResourceType">Type of resource to load.</typeparam>
/// Type of resource to load.
/// </typeparam>
/// <param name="assetId">Asset ID of the resource to load.</param> /// <param name="assetId">Asset ID of the resource to load.</param>
/// <returns>Handle to a loaded runtime asset.</returns> /// <returns>Handle to a loaded runtime asset.</returns>
template<typename ResourceType> template<typename ResourceType>
@ -67,6 +72,17 @@ namespace SHADE
template<> template<>
static inline Handle<SHMaterial> LoadOrGet<SHMaterial>(AssetID assetId); static inline Handle<SHMaterial> LoadOrGet<SHMaterial>(AssetID assetId);
/// <summary> /// <summary>
/// Retrieves an existing loaded object of the specified type if it has already been
/// loaded prior.
/// </summary>
/// <typeparam name="ResourceType">Type of resource to load.</typeparam>
/// <param name="assetId">Asset ID of the resource to retrieve.</param>
/// <returns>
/// Handle to a loaded runtime asset. Null handle if not loaded before.
/// </returns>
template<typename ResourceType>
static Handle<ResourceType> Get(AssetID assetId);
/// <summary>
/// Unloads an existing loaded asset. Attempting to unload an invalid Handle will /// Unloads an existing loaded asset. Attempting to unload an invalid Handle will
/// simply do nothing except emit a warning. /// simply do nothing except emit a warning.
/// Faster than the untemplated version. /// Faster than the untemplated version.
@ -114,6 +130,31 @@ namespace SHADE
/// value. /// value.
/// </return> /// </return>
static std::optional<AssetID> GetAssetID(Handle<void> handle); static std::optional<AssetID> GetAssetID(Handle<void> handle);
/// <summary>
/// Retrieves the name associated with the AssetID that is associated with the
/// specified Handle.
/// Faster than the untemplated version.
/// </summary>
/// <typeparam name="ResourceType">Type of resource to get the name of.</typeparam>
/// <param name="handle">Handle to get the name of.</param>
/// <return>
/// Name for the specified Handle. If the Handle is invalid, there will be no
/// value.
/// </return>
template<typename T>
static std::optional<std::string> GetAssetName(Handle<T> handle);
/// <summary>
/// Retrieves the name associated with the AssetID that is associated with the
/// specified Handle.
/// Compared to the templated version, this function is slower as it requires
/// searching through the storage of all resource types.
/// </summary>
/// <param name="handle">Handle to get the name of.</param>
/// <return>
/// Name for the specified Handle. If the Handle is invalid, there will be no
/// value.
/// </return>
static std::optional<std::string> GetAssetName(Handle<void> handle);
private: private:
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/

View File

@ -93,6 +93,16 @@ namespace SHADE
return handle; return handle;
} }
template<typename ResourceType>
Handle<ResourceType> SHResourceManager::Get(AssetID assetId)
{
auto [typedHandleMap, typedAssetIdMap] = getAssetHandleMap<ResourceType>();
if (typedHandleMap.get().contains(assetId))
return Handle<ResourceType>(typedHandleMap.get()[assetId]);
else
return Handle<ResourceType>();
}
template<typename ResourceType> template<typename ResourceType>
void SHResourceManager::Unload(Handle<ResourceType> asset) void SHResourceManager::Unload(Handle<ResourceType> asset)
{ {
@ -139,6 +149,18 @@ namespace SHADE
return {}; return {};
} }
template<typename T>
std::optional<std::string> SHADE::SHResourceManager::GetAssetName(Handle<T> handle)
{
auto assetId = GetAssetID<T>(handle);
if (assetId.has_value())
{
const auto ASSET_INFO = SHAssetManager::GetAsset(assetId.value());
if (ASSET_INFO.has_value())
return ASSET_INFO.value().name;
}
return {};
}
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
/* Helper Functions */ /* Helper Functions */

View File

@ -49,6 +49,7 @@ namespace SHADE
using const_pointer = const T*; using const_pointer = const T*;
using reference = T&; using reference = T&;
using const_reference = const T&; using const_reference = const T&;
using dense_iterator = typename std::vector<T>::iterator;
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
/* Constructors/Destructors */ /* Constructors/Destructors */
@ -59,10 +60,6 @@ namespace SHADE
SparseSet(); SparseSet();
~SparseSet() = default; ~SparseSet() = default;
//// Disallow moving or copying
//SparseSet(const SparseSet&) = delete;
//SparseSet(SparseSet&&) = delete;
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
/* Usage Functions */ /* Usage Functions */
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
@ -192,6 +189,16 @@ namespace SHADE
/// </exception> /// </exception>
const T& operator[](index_type idx) const; const T& operator[](index_type idx) const;
/*-----------------------------------------------------------------------------*/
/* Direct Dense Access Functions */
/*-----------------------------------------------------------------------------*/
/// <summary>
/// Provides access to the dense array of the SparseSet.
/// These iterators should not be used to manipulate the underlying vector.
/// </summary>
/// <returns>Pair of begin and end iterators to the dense vector.</returns>
std::pair<dense_iterator, dense_iterator> GetDenseAccess();
protected: protected:
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
/* Constants */ /* Constants */

View File

@ -143,4 +143,13 @@ namespace SHADE
{ {
return at(idx); return at(idx);
} }
/*---------------------------------------------------------------------------------*/
/* Direct Dense Access Functions */
/*---------------------------------------------------------------------------------*/
template<typename T>
std::pair<typename SparseSet<T>::dense_iterator, typename SparseSet<T>::dense_iterator> SparseSet<T>::GetDenseAccess()
{
return { denseArray.begin(), denseArray.end() };
}
} }