Fix SetMesh(), SHResourceManager and BatcherDispatcher issues that blocked mesh switching #151

Merged
Pycorax merged 4 commits from Fix-SetMesh into main 2022-11-01 15:35:04 +08:00
7 changed files with 54 additions and 45 deletions

View File

@ -358,6 +358,7 @@ namespace SHADE
[component](AssetID const& id)
{
component->SetMesh(SHResourceManager::LoadOrGet<SHMesh>(id));
SHResourceManager::FinaliseChanges();
}, SHDragDrop::DRAG_RESOURCE);
}
else

View File

@ -74,11 +74,12 @@ namespace SHADE
void SHBatch::Remove(const SHRenderable* renderable)
{
// Check if we have a SubBatch with the same mesh yet
// Check if we have a SubBatch with the existing mesh yet (if changed, we use the old mesh)
Handle<SHMesh> prevSubBatchMesh = renderable->HasMeshChanged() ? renderable->GetPrevMesh() : renderable->GetMesh();
auto subBatch = std::find_if(subBatches.begin(), subBatches.end(), [&](const SHSubBatch& batch)
{
return batch.Mesh == renderable->GetMesh();
});
{
return batch.Mesh == prevSubBatchMesh;
});
// Attempt to remove if it exists
if (subBatch == subBatches.end())
@ -88,9 +89,7 @@ namespace SHADE
// Check if other renderables in subBatches contain the same material instance
bool matUnused = true;
Handle<SHMaterialInstance> matToCheck = renderable->HasMaterialChanged() ? renderable->GetPrevMaterial() : renderable->GetMaterial();
for (const auto& sb : subBatches)
{
// Check material usage

View File

@ -37,9 +37,9 @@ namespace SHADE
// Check if we have a batch with the same pipeline first
auto batch = std::find_if(batches.begin(), batches.end(), [&](const SHBatch& batch)
{
return batch.GetPipeline() == PIPELINE;
});
{
return batch.GetPipeline() == PIPELINE;
});
// Create one if not found

View File

@ -106,10 +106,7 @@ namespace SHADE
descPool = device->CreateDescriptorPools();
// Create generic command buffer
//transferCmdPool = device->CreateCommandPool(SH_QUEUE_FAMILY_ARRAY_INDEX::GRAPHICS, SH_CMD_POOL_RESET::POOL_BASED, true);
graphicsCmdPool = device->CreateCommandPool(SH_QUEUE_FAMILY_ARRAY_INDEX::GRAPHICS, SH_CMD_POOL_RESET::POOL_BASED, true);
transferCmdBuffer = graphicsCmdPool->RequestCommandBuffer(SH_CMD_BUFFER_TYPE::PRIMARY);
graphicsTexCmdBuffer = graphicsCmdPool->RequestCommandBuffer(SH_CMD_BUFFER_TYPE::PRIMARY);
// Load Built In Shaders
static constexpr AssetID VS_DEFAULT = 39210065; defaultVertShader = SHResourceManager::LoadOrGet<SHVkShaderModule>(VS_DEFAULT);
@ -621,10 +618,14 @@ namespace SHADE
void SHGraphicsSystem::BuildMeshBuffers()
{
transferCmdBuffer = graphicsCmdPool->RequestCommandBuffer(SH_CMD_BUFFER_TYPE::PRIMARY);
device->WaitIdle();
transferCmdBuffer->BeginRecording();
meshLibrary.BuildBuffers(device, transferCmdBuffer);
transferCmdBuffer->EndRecording();
graphicsQueue->SubmitCommandBuffer({ transferCmdBuffer });
device->WaitIdle();
transferCmdBuffer.Free(); transferCmdBuffer = {};
}
/*---------------------------------------------------------------------------------*/
@ -649,10 +650,14 @@ namespace SHADE
void SHGraphicsSystem::BuildTextures()
{
graphicsTexCmdBuffer = graphicsCmdPool->RequestCommandBuffer(SH_CMD_BUFFER_TYPE::PRIMARY);
device->WaitIdle();
texLibrary.BuildTextures
(
device, graphicsTexCmdBuffer, graphicsQueue, descPool
);
device->WaitIdle();
graphicsTexCmdBuffer.Free(); graphicsTexCmdBuffer = {};
}
#pragma endregion ADD_REMOVE
@ -692,6 +697,7 @@ namespace SHADE
void SHGraphicsSystem::EndRoutine::Execute(double) noexcept
{
reinterpret_cast<SHGraphicsSystem*>(system)->EndRender();
SHResourceManager::FinaliseChanges();
}
/*-----------------------------------------------------------------------------------*/
@ -709,8 +715,13 @@ namespace SHADE
if (!renderable.HasChanged())
continue;
// Remove from old material's SuperBatch
Handle<SHMaterialInstance> prevMaterial = renderable.GetPrevMaterial();
if (!renderable.GetMesh())
{
SHLOG_CRITICAL("NULL Mesh provided!");
}
// Remove from the SuperBatch it is previously in (prevMat if mat has changed)
Handle<SHMaterialInstance> prevMaterial = renderable.HasMaterialChanged() ? renderable.GetPrevMaterial() : renderable.GetMaterial();
if (prevMaterial)
{
Handle<SHSuperBatch> oldSuperBatch = prevMaterial->GetBaseMaterial()->GetPipeline()->GetPipelineState().GetSubpass()->GetSuperBatch();

View File

@ -21,9 +21,11 @@ namespace SHADE
/*-----------------------------------------------------------------------------------*/
SHResourceHub SHResourceManager::resourceHub;
std::unordered_map<std::type_index, std::unordered_map<AssetID, Handle<void>>> SHResourceManager::handlesMap;
std::unordered_map<std::type_index, SHADE::SHResourceManager::HandleAssetMap> SHResourceManager::assetIdMap;
std::unordered_map<std::type_index, SHResourceManager::HandleAssetMap> SHResourceManager::assetIdMap;
std::unordered_map<std::type_index, std::function<void(AssetID)>> SHResourceManager::typedFreeFuncMap;
std::vector<AssetID> SHResourceManager::loadedAssetData;
bool SHResourceManager::textureChanged = false;
bool SHResourceManager::meshChanged = false;
/*-----------------------------------------------------------------------------------*/
/* Function Definitions */
@ -63,8 +65,17 @@ namespace SHADE
SHGraphicsSystem* gfxSystem = SHSystemManager::GetSystem<SHGraphicsSystem>();
if (gfxSystem == nullptr)
throw std::runtime_error("[SHResourceManager] Attempted to load graphics resource without a SHGraphicsSystem installed.");
gfxSystem->BuildMeshBuffers();
gfxSystem->BuildTextures();
if (meshChanged)
{
gfxSystem->BuildMeshBuffers();
meshChanged = false;
}
if (textureChanged)
{
gfxSystem->BuildTextures();
textureChanged = false;
}
// Free CPU Resources
for (auto assetId : loadedAssetData)

View File

@ -28,33 +28,15 @@ of DigiPen Institute of Technology is prohibited.
namespace SHADE
{
/// <summary>
/// Template structs that maps a resource to their loaded asset representation type.
/// </summary>
template<typename T = void>
struct SHResourceLoader
{
using AssetType = void;
};
template<>
struct SHResourceLoader<SHMesh>
{
using AssetType = SHMeshAsset;
};
template<>
struct SHResourceLoader<SHTexture>
{
using AssetType = SHTextureAsset;
};
template<>
struct SHResourceLoader<SHVkShaderModule>
{
using AssetType = SHShaderAsset;
};
template<>
struct SHResourceLoader<SHMaterial>
{
using AssetType = SHMaterialAsset;
};
struct SHResourceLoader { using AssetType = void; };
template<> struct SHResourceLoader<SHMesh> { using AssetType = SHMeshAsset; };
template<> struct SHResourceLoader<SHTexture> { using AssetType = SHTextureAsset; };
template<> struct SHResourceLoader<SHVkShaderModule> { using AssetType = SHShaderAsset; };
template<> struct SHResourceLoader<SHMaterial> { using AssetType = SHMaterialAsset; };
/// <summary>
/// Static class responsible for loading and caching runtime resources from their
@ -97,7 +79,7 @@ namespace SHADE
/// <param name="assetId">Handle to the resource to unload.</param>
static void Unload(AssetID assetId);
/// <summary>
/// Needs to be called to finalise all changes to loads.
/// Needs to be called to finalise all changes to loads, unless at runtime.
/// </summary>
static void FinaliseChanges();
@ -147,6 +129,9 @@ namespace SHADE
static std::unordered_map<std::type_index, std::function<void(AssetID)>> typedFreeFuncMap;
// Pointers to temp CPU resources
static std::vector<AssetID> loadedAssetData;
// Dirty Flags
static bool meshChanged;
static bool textureChanged;
/*---------------------------------------------------------------------------------*/
/* Helper Functions */

View File

@ -54,7 +54,7 @@ namespace SHADE
}
auto handle = load<ResourceType>(assetId, *assetData);
Handle genericHandle = Handle();
Handle genericHandle = Handle(handle);
typedHandleMap.get().emplace(assetId, genericHandle);
typedAssetIdMap.get().emplace(genericHandle, assetId);
return handle;
@ -139,6 +139,7 @@ namespace SHADE
if constexpr (std::is_same_v<ResourceType, SHMesh>)
{
loadedAssetData.emplace_back(assetId);
meshChanged = true;
return gfxSystem->AddMesh
(
@ -155,6 +156,7 @@ namespace SHADE
else if constexpr (std::is_same_v<ResourceType, SHTexture>)
{
loadedAssetData.emplace_back(assetId);
textureChanged = true;
return gfxSystem->AddTexture
(