Render graph fixes with attachment layouts #52
|
@ -36,12 +36,12 @@ namespace Sandbox
|
||||||
graphicsSystem->BuildMeshBuffers();
|
graphicsSystem->BuildMeshBuffers();
|
||||||
|
|
||||||
// Create Materials
|
// Create Materials
|
||||||
auto matInst = graphicsSystem->AddMaterialInstance();
|
auto matInst = graphicsSystem->AddOrGetBaseMaterialInstance();
|
||||||
|
|
||||||
// Create Stress Test Objects
|
// Create Stress Test Objects
|
||||||
static const SHVec3 TEST_OBJ_SCALE = { 0.2f, 0.2f, 0.2f };
|
static const SHVec3 TEST_OBJ_SCALE = { 0.2f, 0.2f, 0.2f };
|
||||||
constexpr int NUM_ROWS = 200;
|
constexpr int NUM_ROWS = 1;
|
||||||
constexpr int NUM_COLS = 100;
|
constexpr int NUM_COLS = 1;
|
||||||
static const SHVec3 TEST_OBJ_SPACING = { 1.0f, 1.0f, 1.0f };
|
static const SHVec3 TEST_OBJ_SPACING = { 1.0f, 1.0f, 1.0f };
|
||||||
static const SHVec3 TEST_OBJ_START_POS = { - (NUM_COLS / 2 * TEST_OBJ_SPACING.x ), 0.0f, 0.0f };
|
static const SHVec3 TEST_OBJ_START_POS = { - (NUM_COLS / 2 * TEST_OBJ_SPACING.x ), 0.0f, 0.0f };
|
||||||
for (int z = 0; z < NUM_ROWS; ++z)
|
for (int z = 0; z < NUM_ROWS; ++z)
|
||||||
|
|
|
@ -324,11 +324,14 @@ namespace SHADE
|
||||||
void SHVkCommandBuffer::BindVertexBuffer(uint32_t bindingPoint, Handle<SHVkBuffer> const& buffer, vk::DeviceSize offset) noexcept
|
void SHVkCommandBuffer::BindVertexBuffer(uint32_t bindingPoint, Handle<SHVkBuffer> const& buffer, vk::DeviceSize offset) noexcept
|
||||||
{
|
{
|
||||||
if (cmdBufferState == SH_CMD_BUFFER_STATE::RECORDING)
|
if (cmdBufferState == SH_CMD_BUFFER_STATE::RECORDING)
|
||||||
|
{
|
||||||
|
if (buffer)
|
||||||
{
|
{
|
||||||
auto bufferHandle = buffer->GetVkBuffer();
|
auto bufferHandle = buffer->GetVkBuffer();
|
||||||
vkCommandBuffer.bindVertexBuffers(bindingPoint, 1, &bufferHandle, &offset);
|
vkCommandBuffer.bindVertexBuffers(bindingPoint, 1, &bufferHandle, &offset);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
/*!
|
/*!
|
||||||
|
@ -445,6 +448,7 @@ namespace SHADE
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (indirectDrawData)
|
||||||
vkCommandBuffer.drawIndexedIndirect(indirectDrawData->GetVkBuffer(), 0, drawCount, sizeof(vk::DrawIndexedIndirectCommand));
|
vkCommandBuffer.drawIndexedIndirect(indirectDrawData->GetVkBuffer(), 0, drawCount, sizeof(vk::DrawIndexedIndirectCommand));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -39,7 +39,8 @@ namespace SHADE
|
||||||
std::vector<vk::DescriptorPoolSize> Limits =
|
std::vector<vk::DescriptorPoolSize> Limits =
|
||||||
{
|
{
|
||||||
{ vk::DescriptorType::eCombinedImageSampler, 100 },
|
{ vk::DescriptorType::eCombinedImageSampler, 100 },
|
||||||
{ vk::DescriptorType::eUniformBuffer, 100 }
|
{ vk::DescriptorType::eUniformBuffer, 100 },
|
||||||
|
{ vk::DescriptorType::eUniformBufferDynamic, 100 }
|
||||||
};
|
};
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Maximum number of descriptor sets allowed
|
/// Maximum number of descriptor sets allowed
|
||||||
|
|
|
@ -58,6 +58,9 @@ namespace SHADE
|
||||||
// Add renderable in
|
// Add renderable in
|
||||||
subBatch->Renderables.insert(renderable);
|
subBatch->Renderables.insert(renderable);
|
||||||
|
|
||||||
|
// Also add material instance in
|
||||||
|
referencedMatInstances.insert(renderable->GetMaterial());
|
||||||
|
|
||||||
// Mark all as dirty
|
// Mark all as dirty
|
||||||
setAllDirtyFlags();
|
setAllDirtyFlags();
|
||||||
}
|
}
|
||||||
|
@ -76,6 +79,22 @@ namespace SHADE
|
||||||
|
|
||||||
subBatch->Renderables.erase(renderable);
|
subBatch->Renderables.erase(renderable);
|
||||||
|
|
||||||
|
// Check if other renderables in subBatches contain the same material instance
|
||||||
|
bool matUnused = true;
|
||||||
|
for (const auto& sb : subBatches)
|
||||||
|
for (const auto& rend : sb.Renderables)
|
||||||
|
{
|
||||||
|
if (rend->GetMaterial() == renderable->GetMaterial())
|
||||||
|
{
|
||||||
|
matUnused = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Material is no longer in this library, so we remove it
|
||||||
|
if (matUnused)
|
||||||
|
referencedMatInstances.erase(renderable->GetMaterial());
|
||||||
|
|
||||||
// Mark all as dirty
|
// Mark all as dirty
|
||||||
for (bool& dirt : isDirty)
|
for (bool& dirt : isDirty)
|
||||||
dirt = true;
|
dirt = true;
|
||||||
|
@ -101,6 +120,60 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SHBatch::UpdateMaterialBuffer(uint32_t frameIndex)
|
||||||
|
{
|
||||||
|
if (frameIndex >= SHGraphicsConstants::NUM_FRAME_BUFFERS)
|
||||||
|
{
|
||||||
|
SHLOG_WARNING("[SHBatch] Attempted to update transform buffers with an invalid frame index.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if there are even material properties to update
|
||||||
|
if (!matPropsData)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Check if any materials have changed
|
||||||
|
bool hasChanged = false;
|
||||||
|
for (const auto& material : referencedMatInstances)
|
||||||
|
{
|
||||||
|
if (material->HasChanged())
|
||||||
|
{
|
||||||
|
hasChanged = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// We need to update all the material buffers if the materials have changed
|
||||||
|
if (hasChanged)
|
||||||
|
{
|
||||||
|
for (auto& dirt : matBufferDirty)
|
||||||
|
dirt = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if this frame's buffer is dirty
|
||||||
|
if (!matBufferDirty[frameIndex])
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Build CPI Buffer
|
||||||
|
char* propsCurrPtr = matPropsData.get();
|
||||||
|
for (auto& subBatch : subBatches)
|
||||||
|
for (const SHRenderable* renderable : subBatch.Renderables)
|
||||||
|
{
|
||||||
|
renderable->GetMaterial()->ExportProperties(propsCurrPtr);
|
||||||
|
propsCurrPtr += singleMatPropSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Transfer to GPU
|
||||||
|
SHVkUtil::EnsureBufferAndCopyHostVisibleData
|
||||||
|
(
|
||||||
|
device, matPropsBuffer[frameIndex], matPropsData.get(), static_cast<uint32_t>(matPropsDataSize),
|
||||||
|
vk::BufferUsageFlagBits::eStorageBuffer
|
||||||
|
);
|
||||||
|
|
||||||
|
// This frame is updated
|
||||||
|
matBufferDirty[frameIndex] = false;
|
||||||
|
}
|
||||||
|
|
||||||
void SHBatch::UpdateTransformBuffer(uint32_t frameIndex)
|
void SHBatch::UpdateTransformBuffer(uint32_t frameIndex)
|
||||||
{
|
{
|
||||||
if (frameIndex >= SHGraphicsConstants::NUM_FRAME_BUFFERS)
|
if (frameIndex >= SHGraphicsConstants::NUM_FRAME_BUFFERS)
|
||||||
|
@ -130,10 +203,11 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
|
|
||||||
// Transfer to GPU
|
// Transfer to GPU
|
||||||
transformDataBuffer[frameIndex]->WriteToMemory(transformData.data(), transformData.size() * sizeof(SHMatrix), 0, 0);
|
if (transformDataBuffer[frameIndex])
|
||||||
|
transformDataBuffer[frameIndex]->WriteToMemory(transformData.data(), static_cast<uint32_t>(transformData.size() * sizeof(SHMatrix)), 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHBatch::Build(Handle<SHVkLogicalDevice> device, uint32_t frameIndex)
|
void SHBatch::Build(Handle<SHVkLogicalDevice> _device, uint32_t frameIndex)
|
||||||
{
|
{
|
||||||
if (frameIndex >= SHGraphicsConstants::NUM_FRAME_BUFFERS)
|
if (frameIndex >= SHGraphicsConstants::NUM_FRAME_BUFFERS)
|
||||||
{
|
{
|
||||||
|
@ -169,7 +243,6 @@ namespace SHADE
|
||||||
vk::ShaderStageFlagBits::eFragment
|
vk::ShaderStageFlagBits::eFragment
|
||||||
);
|
);
|
||||||
const bool EMPTY_MAT_PROPS = !SHADER_INFO;
|
const bool EMPTY_MAT_PROPS = !SHADER_INFO;
|
||||||
Byte singleMatPropSize = 0;
|
|
||||||
Byte matPropTotalBytes = 0;
|
Byte matPropTotalBytes = 0;
|
||||||
if (!EMPTY_MAT_PROPS)
|
if (!EMPTY_MAT_PROPS)
|
||||||
{
|
{
|
||||||
|
@ -231,14 +304,14 @@ namespace SHADE
|
||||||
const uint32_t DRAW_DATA_BYTES = static_cast<uint32_t>(drawData.size() * sizeof(vk::DrawIndexedIndirectCommand));
|
const uint32_t DRAW_DATA_BYTES = static_cast<uint32_t>(drawData.size() * sizeof(vk::DrawIndexedIndirectCommand));
|
||||||
SHVkUtil::EnsureBufferAndCopyHostVisibleData
|
SHVkUtil::EnsureBufferAndCopyHostVisibleData
|
||||||
(
|
(
|
||||||
device, drawDataBuffer[frameIndex], drawData.data(), DRAW_DATA_BYTES,
|
_device, drawDataBuffer[frameIndex], drawData.data(), DRAW_DATA_BYTES,
|
||||||
BuffUsage::eIndirectBuffer
|
BuffUsage::eIndirectBuffer
|
||||||
);
|
);
|
||||||
// - Transform Buffer
|
// - Transform Buffer
|
||||||
const uint32_t TF_DATA_BYTES = static_cast<uint32_t>(transformData.size() * sizeof(SHMatrix));
|
const uint32_t TF_DATA_BYTES = static_cast<uint32_t>(transformData.size() * sizeof(SHMatrix));
|
||||||
SHVkUtil::EnsureBufferAndCopyHostVisibleData
|
SHVkUtil::EnsureBufferAndCopyHostVisibleData
|
||||||
(
|
(
|
||||||
device, transformDataBuffer[frameIndex], transformData.data(), TF_DATA_BYTES,
|
_device, transformDataBuffer[frameIndex], transformData.data(), TF_DATA_BYTES,
|
||||||
BuffUsage::eVertexBuffer
|
BuffUsage::eVertexBuffer
|
||||||
);
|
);
|
||||||
// - Material Properties Buffer
|
// - Material Properties Buffer
|
||||||
|
@ -246,12 +319,15 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
SHVkUtil::EnsureBufferAndCopyHostVisibleData
|
SHVkUtil::EnsureBufferAndCopyHostVisibleData
|
||||||
(
|
(
|
||||||
device, matPropsBuffer[frameIndex], matPropsData.get(), static_cast<uint32_t>(matPropsDataSize),
|
_device, matPropsBuffer[frameIndex], matPropsData.get(), static_cast<uint32_t>(matPropsDataSize),
|
||||||
BuffUsage::eStorageBuffer
|
BuffUsage::eStorageBuffer
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
isDirty[frameIndex] = false;
|
isDirty[frameIndex] = false;
|
||||||
|
|
||||||
|
// Save logical device
|
||||||
|
this->device = _device;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
|
|
@ -34,6 +34,7 @@ namespace SHADE
|
||||||
class SHMesh;
|
class SHMesh;
|
||||||
class SHRenderable;
|
class SHRenderable;
|
||||||
class SHVkLogicalDevice;
|
class SHVkLogicalDevice;
|
||||||
|
class SHMaterialInstance;
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
/* Type Definitions */
|
/* Type Definitions */
|
||||||
|
@ -73,6 +74,7 @@ namespace SHADE
|
||||||
void Add(const SHRenderable* renderable);
|
void Add(const SHRenderable* renderable);
|
||||||
void Remove(const SHRenderable* renderable);
|
void Remove(const SHRenderable* renderable);
|
||||||
void Clear();
|
void Clear();
|
||||||
|
void UpdateMaterialBuffer(uint32_t frameIndex);
|
||||||
void UpdateTransformBuffer(uint32_t frameIndex);
|
void UpdateTransformBuffer(uint32_t frameIndex);
|
||||||
void Build(Handle<SHVkLogicalDevice> device, uint32_t frameIndex);
|
void Build(Handle<SHVkLogicalDevice> device, uint32_t frameIndex);
|
||||||
void Draw(Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex);
|
void Draw(Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex);
|
||||||
|
@ -86,8 +88,12 @@ namespace SHADE
|
||||||
/*-----------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------*/
|
||||||
/* Data Members */
|
/* Data Members */
|
||||||
/*-----------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------*/
|
||||||
|
// Resources
|
||||||
|
Handle<SHVkLogicalDevice> device;
|
||||||
// Batch Properties
|
// Batch Properties
|
||||||
Handle<SHVkPipeline> pipeline;
|
Handle<SHVkPipeline> pipeline;
|
||||||
|
std::unordered_set<Handle<SHMaterialInstance>> referencedMatInstances;
|
||||||
|
std::array<bool, SHGraphicsConstants::NUM_FRAME_BUFFERS> matBufferDirty;
|
||||||
// Batch Tree
|
// Batch Tree
|
||||||
std::vector<SHSubBatch> subBatches;
|
std::vector<SHSubBatch> subBatches;
|
||||||
std::array<bool, SHGraphicsConstants::NUM_FRAME_BUFFERS> isDirty;
|
std::array<bool, SHGraphicsConstants::NUM_FRAME_BUFFERS> isDirty;
|
||||||
|
@ -96,6 +102,7 @@ namespace SHADE
|
||||||
std::vector<SHMatrix> transformData;
|
std::vector<SHMatrix> transformData;
|
||||||
std::unique_ptr<char> matPropsData;
|
std::unique_ptr<char> matPropsData;
|
||||||
Byte matPropsDataSize = 0;
|
Byte matPropsDataSize = 0;
|
||||||
|
Byte singleMatPropSize = 0;
|
||||||
bool isCPUBuffersDirty = true;
|
bool isCPUBuffersDirty = true;
|
||||||
// GPU Buffers
|
// GPU Buffers
|
||||||
std::array<Handle<SHVkBuffer>, SHGraphicsConstants::NUM_FRAME_BUFFERS> drawDataBuffer;
|
std::array<Handle<SHVkBuffer>, SHGraphicsConstants::NUM_FRAME_BUFFERS> drawDataBuffer;
|
||||||
|
|
|
@ -109,11 +109,11 @@ namespace SHADE
|
||||||
superBatches.clear();
|
superBatches.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHBatcher::UpdateTransformBuffer(uint32_t frameIndex)
|
void SHBatcher::UpdateBuffers(uint32_t frameIndex)
|
||||||
{
|
{
|
||||||
for (auto& batch : superBatches)
|
for (auto& batch : superBatches)
|
||||||
{
|
{
|
||||||
batch->UpdateTransformBuffer(frameIndex);
|
batch->UpdateBuffers(frameIndex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -53,7 +53,7 @@ namespace SHADE
|
||||||
void RemoveFromBatch(SHRenderable const* renderable);
|
void RemoveFromBatch(SHRenderable const* renderable);
|
||||||
void FinaliseBatches(Handle<SHVkLogicalDevice> device, uint32_t frameIndex);
|
void FinaliseBatches(Handle<SHVkLogicalDevice> device, uint32_t frameIndex);
|
||||||
void ClearBatches();
|
void ClearBatches();
|
||||||
void UpdateTransformBuffer(uint32_t frameIndex);
|
void UpdateBuffers(uint32_t frameIndex);
|
||||||
void RegisterSuperBatch(Handle<SHSuperBatch> superBatch);
|
void RegisterSuperBatch(Handle<SHSuperBatch> superBatch);
|
||||||
void DeregisterSuperBatch(Handle<SHSuperBatch> superBatch);
|
void DeregisterSuperBatch(Handle<SHSuperBatch> superBatch);
|
||||||
|
|
||||||
|
|
|
@ -78,10 +78,11 @@ namespace SHADE
|
||||||
batches.clear();
|
batches.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHSuperBatch::UpdateTransformBuffer(uint32_t frameIndex)
|
void SHSuperBatch::UpdateBuffers(uint32_t frameIndex)
|
||||||
{
|
{
|
||||||
for (auto& batch : batches)
|
for (auto& batch : batches)
|
||||||
{
|
{
|
||||||
|
batch.UpdateMaterialBuffer(frameIndex);
|
||||||
batch.UpdateTransformBuffer(frameIndex);
|
batch.UpdateTransformBuffer(frameIndex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -55,7 +55,7 @@ namespace SHADE
|
||||||
void Add(const SHRenderable* renderable) noexcept;
|
void Add(const SHRenderable* renderable) noexcept;
|
||||||
void Remove(const SHRenderable* renderable) noexcept;
|
void Remove(const SHRenderable* renderable) noexcept;
|
||||||
void Clear() noexcept;
|
void Clear() noexcept;
|
||||||
void UpdateTransformBuffer(uint32_t frameIndex);
|
void UpdateBuffers(uint32_t frameIndex);
|
||||||
void Build(Handle<SHVkLogicalDevice> device, uint32_t frameIndex) noexcept;
|
void Build(Handle<SHVkLogicalDevice> device, uint32_t frameIndex) noexcept;
|
||||||
void Draw(Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex) noexcept;
|
void Draw(Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex) noexcept;
|
||||||
|
|
||||||
|
|
|
@ -150,9 +150,9 @@ namespace SHADE
|
||||||
//compositeSubpass->AddInput("Position");
|
//compositeSubpass->AddInput("Position");
|
||||||
|
|
||||||
// TODO: Use macro to add this node when SH_EDITOR is enabled
|
// TODO: Use macro to add this node when SH_EDITOR is enabled
|
||||||
//auto imguiNode = worldRenderGraph->AddNode("ImGui Node", { "Present" }, {});
|
auto imguiNode = worldRenderGraph->AddNode("ImGui Node", { "Present" }, {"G-Buffer"});
|
||||||
//auto imguiSubpass = imguiNode->AddSubpass("ImGui Draw");
|
auto imguiSubpass = imguiNode->AddSubpass("ImGui Draw");
|
||||||
//imguiSubpass->AddColorOutput("Present");
|
imguiSubpass->AddColorOutput("Present");
|
||||||
|
|
||||||
worldRenderGraph->Generate();
|
worldRenderGraph->Generate();
|
||||||
|
|
||||||
|
@ -415,14 +415,19 @@ namespace SHADE
|
||||||
resourceManager.Free(material);
|
resourceManager.Free(material);
|
||||||
}
|
}
|
||||||
|
|
||||||
Handle<SHMaterialInstance> SHGraphicsSystem::AddMaterialInstance(Handle<SHMaterial> material)
|
Handle<SHMaterialInstance> SHGraphicsSystem::AddOrGetBaseMaterialInstance(Handle<SHMaterial> material)
|
||||||
{
|
{
|
||||||
return resourceManager.Create<SHMaterialInstance>(material);
|
return materialInstanceCache.CreateOrGet(resourceManager, material);
|
||||||
}
|
}
|
||||||
|
|
||||||
SHADE::Handle<SHADE::SHMaterialInstance> SHGraphicsSystem::AddMaterialInstance()
|
SHADE::Handle<SHADE::SHMaterialInstance> SHGraphicsSystem::AddOrGetBaseMaterialInstance()
|
||||||
{
|
{
|
||||||
return AddMaterialInstance(defaultMaterial);
|
return AddOrGetBaseMaterialInstance(defaultMaterial);
|
||||||
|
}
|
||||||
|
|
||||||
|
SHADE::Handle<SHADE::SHMaterialInstance> SHGraphicsSystem::AddMaterialInstanceCopy(Handle<SHMaterialInstance> materialInst)
|
||||||
|
{
|
||||||
|
return resourceManager.Create<SHMaterialInstance>(materialInst->GetBaseMaterial());
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHGraphicsSystem::RemoveMaterialInstance(Handle<SHMaterialInstance> materialInstance)
|
void SHGraphicsSystem::RemoveMaterialInstance(Handle<SHMaterialInstance> materialInstance)
|
||||||
|
|
|
@ -28,6 +28,7 @@ of DigiPen Institute of Technology is prohibited.
|
||||||
#include "Graphics/MiddleEnd/Shaders/SHShaderSourceLibrary.h"
|
#include "Graphics/MiddleEnd/Shaders/SHShaderSourceLibrary.h"
|
||||||
#include "Graphics/MiddleEnd/Shaders/SHShaderModuleLibrary.h"
|
#include "Graphics/MiddleEnd/Shaders/SHShaderModuleLibrary.h"
|
||||||
#include "SHMeshLibrary.h"
|
#include "SHMeshLibrary.h"
|
||||||
|
#include "Graphics/MiddleEnd/Materials/SHMaterialInstanceCache.h"
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
|
@ -119,9 +120,10 @@ namespace SHADE
|
||||||
/* Material Creation Functions */
|
/* Material Creation Functions */
|
||||||
/*-----------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------*/
|
||||||
Handle<SHMaterial> AddMaterial(Handle<SHVkShaderModule> vertShader, Handle<SHVkShaderModule> fragShader, Handle<SHSubpass> subpass);
|
Handle<SHMaterial> AddMaterial(Handle<SHVkShaderModule> vertShader, Handle<SHVkShaderModule> fragShader, Handle<SHSubpass> subpass);
|
||||||
void RemoveMaterial(Handle<SHMaterial> material);;
|
void RemoveMaterial(Handle<SHMaterial> material);
|
||||||
Handle<SHMaterialInstance> AddMaterialInstance();
|
Handle<SHMaterialInstance> AddOrGetBaseMaterialInstance();
|
||||||
Handle<SHMaterialInstance> AddMaterialInstance(Handle<SHMaterial> material);
|
Handle<SHMaterialInstance> AddOrGetBaseMaterialInstance(Handle<SHMaterial> material);
|
||||||
|
Handle<SHMaterialInstance> AddMaterialInstanceCopy(Handle<SHMaterialInstance> materialInst);
|
||||||
void RemoveMaterialInstance(Handle<SHMaterialInstance> materialInstance);
|
void RemoveMaterialInstance(Handle<SHMaterialInstance> materialInstance);
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------*/
|
||||||
|
@ -230,6 +232,7 @@ namespace SHADE
|
||||||
// Middle End Resources
|
// Middle End Resources
|
||||||
ResourceManager resourceManager;
|
ResourceManager resourceManager;
|
||||||
SHMeshLibrary meshLibrary;
|
SHMeshLibrary meshLibrary;
|
||||||
|
SHMaterialInstanceCache materialInstanceCache;
|
||||||
// Viewports
|
// Viewports
|
||||||
Handle<SHViewport> defaultViewport; // Whole screen
|
Handle<SHViewport> defaultViewport; // Whole screen
|
||||||
std::vector<Handle<SHViewport>> viewports; // Additional viewports
|
std::vector<Handle<SHViewport>> viewports; // Additional viewports
|
||||||
|
|
|
@ -38,7 +38,7 @@ namespace SHADE
|
||||||
dataStore.reset();
|
dataStore.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHMaterialInstance::ExportProperties(void* dest) const
|
void SHMaterialInstance::ExportProperties(void* dest)
|
||||||
{
|
{
|
||||||
assert(dataStore != nullptr);
|
assert(dataStore != nullptr);
|
||||||
|
|
||||||
|
@ -62,6 +62,9 @@ namespace SHADE
|
||||||
const auto DATA_OFFSET = variable->offset;
|
const auto DATA_OFFSET = variable->offset;
|
||||||
memcpy(static_cast<char*>(dest) + DATA_OFFSET, dataStore.get() + data.StoredDataOffset, data.DataSize);
|
memcpy(static_cast<char*>(dest) + DATA_OFFSET, dataStore.get() + data.StoredDataOffset, data.DataSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Data was exported so unflag
|
||||||
|
dataWasChanged = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
|
|
@ -62,12 +62,13 @@ namespace SHADE
|
||||||
template<typename T>
|
template<typename T>
|
||||||
const T& GetProperty(const std::string& key) const;
|
const T& GetProperty(const std::string& key) const;
|
||||||
void ResetProperties() noexcept;
|
void ResetProperties() noexcept;
|
||||||
void ExportProperties(void* dest) const;
|
void ExportProperties(void* dest);
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------*/
|
||||||
/* Getter Functions */
|
/* Getter Functions */
|
||||||
/*-----------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------*/
|
||||||
Handle<SHMaterial> GetBaseMaterial() const { return baseMaterial; }
|
Handle<SHMaterial> GetBaseMaterial() const noexcept { return baseMaterial; }
|
||||||
|
bool HasChanged() const noexcept { return dataWasChanged; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/*-----------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------*/
|
||||||
|
@ -77,6 +78,7 @@ namespace SHADE
|
||||||
std::vector<OverrideData> overrideData;
|
std::vector<OverrideData> overrideData;
|
||||||
std::unique_ptr<char> dataStore;
|
std::unique_ptr<char> dataStore;
|
||||||
size_t dataStoreSize = 0;
|
size_t dataStoreSize = 0;
|
||||||
|
bool dataWasChanged = false;
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------*/
|
||||||
/* Helper Functions */
|
/* Helper Functions */
|
||||||
|
|
|
@ -53,6 +53,9 @@ namespace SHADE
|
||||||
|
|
||||||
// Save the override data information
|
// Save the override data information
|
||||||
overrideData.emplace_back(std::move(od));
|
overrideData.emplace_back(std::move(od));
|
||||||
|
|
||||||
|
// Flag
|
||||||
|
dataWasChanged = true;
|
||||||
}
|
}
|
||||||
template<typename T>
|
template<typename T>
|
||||||
T& SHMaterialInstance::GetProperty(const std::string& key)
|
T& SHMaterialInstance::GetProperty(const std::string& key)
|
||||||
|
|
|
@ -81,7 +81,7 @@ namespace SHADE
|
||||||
if (!material)
|
if (!material)
|
||||||
{
|
{
|
||||||
SHGraphicsSystem* gfxSystem = SHSystemManager::GetSystem<SHGraphicsSystem>();
|
SHGraphicsSystem* gfxSystem = SHSystemManager::GetSystem<SHGraphicsSystem>();
|
||||||
material = gfxSystem->AddMaterialInstance(sharedMaterial->GetBaseMaterial());
|
material = gfxSystem->AddOrGetBaseMaterialInstance(sharedMaterial->GetBaseMaterial());
|
||||||
}
|
}
|
||||||
|
|
||||||
return material;
|
return material;
|
||||||
|
|
|
@ -0,0 +1,47 @@
|
||||||
|
/************************************************************************************//*!
|
||||||
|
\file SHMaterialInstanceCache.cpp
|
||||||
|
\author Tng Kah Wei, kahwei.tng, 390009620
|
||||||
|
\par email: kahwei.tng\@digipen.edu
|
||||||
|
\date Sep 25, 2022
|
||||||
|
\brief Contains the definition of SHMaterialInstanceCache's functions.
|
||||||
|
|
||||||
|
|
||||||
|
Copyright (C) 2022 DigiPen Institute of Technology.
|
||||||
|
Reproduction or disclosure of this file or its contents without the prior written consent
|
||||||
|
of DigiPen Institute of Technology is prohibited.
|
||||||
|
*//*************************************************************************************/
|
||||||
|
#include "SHpch.h"
|
||||||
|
#include "SHMaterialInstanceCache.h"
|
||||||
|
|
||||||
|
#include "Graphics/MiddleEnd/Interface/SHMaterialInstance.h"
|
||||||
|
#include "Resource/ResourceLibrary.h"
|
||||||
|
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
/* Usage Functions */
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
SHADE::Handle<SHADE::SHMaterialInstance> SHMaterialInstanceCache::CreateOrGet(ResourceManager& manager, Handle<SHMaterial> material)
|
||||||
|
{
|
||||||
|
// Check if there is already an existing instance
|
||||||
|
auto matInst = cache.find(material);
|
||||||
|
if (matInst == cache.end())
|
||||||
|
{
|
||||||
|
// Create and return
|
||||||
|
return cache.emplace(material, manager.Create<SHMaterialInstance>(material)).first->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
return matInst->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHMaterialInstanceCache::Remove(Handle<SHMaterial> material)
|
||||||
|
{
|
||||||
|
cache.erase(material);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHMaterialInstanceCache::Clear()
|
||||||
|
{
|
||||||
|
cache.clear();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,93 @@
|
||||||
|
/************************************************************************************//*!
|
||||||
|
\file SHMaterialInstanceCache.h
|
||||||
|
\author Tng Kah Wei, kahwei.tng, 390009620
|
||||||
|
\par email: kahwei.tng\@digipen.edu
|
||||||
|
\date Sep 25, 2022
|
||||||
|
\brief Contains the definition of SHMaterialInstanceCache.
|
||||||
|
|
||||||
|
|
||||||
|
Copyright (C) 2022 DigiPen Institute of Technology.
|
||||||
|
Reproduction or disclosure of this file or its contents without the prior written consent
|
||||||
|
of DigiPen Institute of Technology is prohibited.
|
||||||
|
*//*************************************************************************************/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
// STL Includes
|
||||||
|
#include <unordered_map>
|
||||||
|
// Project Includes
|
||||||
|
#include "Resource/Handle.h"
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
/* Forward Declarations */
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
class SHMaterial;
|
||||||
|
class SHMaterialInstance;
|
||||||
|
class ResourceManager;
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
/* Type Definitions */
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
/*************************************************************************************/
|
||||||
|
/*!
|
||||||
|
\brief
|
||||||
|
Creates and caches base SHMaterialInstances. Note that base SHMaterialInstances
|
||||||
|
refer to SHMaterialInstances with no overrides.
|
||||||
|
*/
|
||||||
|
/*************************************************************************************/
|
||||||
|
class SHMaterialInstanceCache
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
/* Usage Functions */
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
/***********************************************************************************/
|
||||||
|
/*!
|
||||||
|
|
||||||
|
\brief
|
||||||
|
|
||||||
|
|
||||||
|
\param material
|
||||||
|
Material to get the SHMaterialInstance for.
|
||||||
|
|
||||||
|
\return
|
||||||
|
Handle to the base SHMaterialInstance that is mapped to SHMaterial.
|
||||||
|
|
||||||
|
*/
|
||||||
|
/***********************************************************************************/
|
||||||
|
Handle<SHMaterialInstance> CreateOrGet(ResourceManager& manager, Handle<SHMaterial> material);
|
||||||
|
/***********************************************************************************/
|
||||||
|
/*!
|
||||||
|
|
||||||
|
\brief
|
||||||
|
Removes a SHMaterialInstance from the cache with a matching material.
|
||||||
|
|
||||||
|
\param material
|
||||||
|
Handle to a SHMaterial that is used to check for removal.
|
||||||
|
|
||||||
|
*/
|
||||||
|
/***********************************************************************************/
|
||||||
|
void Remove(Handle<SHMaterial> material);
|
||||||
|
/***********************************************************************************/
|
||||||
|
/*!
|
||||||
|
|
||||||
|
\brief
|
||||||
|
Removes all SHMaterialInstances in the cache.
|
||||||
|
|
||||||
|
*/
|
||||||
|
/***********************************************************************************/
|
||||||
|
void Clear();
|
||||||
|
|
||||||
|
private:
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
/* Type Definitions */
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
using MaterialMap = std::unordered_map<Handle<SHMaterial>, Handle<SHMaterialInstance>>;
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
/* Data Members */
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
MaterialMap cache;
|
||||||
|
};
|
||||||
|
}
|
|
@ -220,7 +220,6 @@ namespace SHADE
|
||||||
, depthReferences{}
|
, depthReferences{}
|
||||||
, inputReferences{}
|
, inputReferences{}
|
||||||
{
|
{
|
||||||
superBatch = rm.Create<SHSuperBatch>(GetHandle());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
|
@ -349,7 +348,7 @@ namespace SHADE
|
||||||
void SHSubpass::Execute(Handle<SHVkCommandBuffer>& commandBuffer, uint32_t frameIndex) noexcept
|
void SHSubpass::Execute(Handle<SHVkCommandBuffer>& commandBuffer, uint32_t frameIndex) noexcept
|
||||||
{
|
{
|
||||||
// Ensure correct transforms are provided
|
// Ensure correct transforms are provided
|
||||||
superBatch->UpdateTransformBuffer(frameIndex);
|
superBatch->UpdateBuffers(frameIndex);
|
||||||
|
|
||||||
// Draw all the batches
|
// Draw all the batches
|
||||||
superBatch->Draw(commandBuffer, frameIndex);
|
superBatch->Draw(commandBuffer, frameIndex);
|
||||||
|
@ -366,6 +365,12 @@ namespace SHADE
|
||||||
exteriorDrawCalls.push_back(newDrawCall);
|
exteriorDrawCalls.push_back(newDrawCall);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SHSubpass::Init(ResourceManager& resourceManager) noexcept
|
||||||
|
{
|
||||||
|
superBatch = resourceManager.Create<SHSuperBatch>(GetHandle());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
/*!
|
/*!
|
||||||
|
|
||||||
|
@ -524,6 +529,9 @@ namespace SHADE
|
||||||
, configured{ rhs.configured }
|
, configured{ rhs.configured }
|
||||||
, executed{ rhs.executed }
|
, executed{ rhs.executed }
|
||||||
, ptrToResources{ rhs.ptrToResources }
|
, ptrToResources{ rhs.ptrToResources }
|
||||||
|
, pipelineLibrary{ std::move(rhs.pipelineLibrary) }
|
||||||
|
, batcher { std::move(rhs.batcher) }
|
||||||
|
|
||||||
{
|
{
|
||||||
rhs.renderpass = {};
|
rhs.renderpass = {};
|
||||||
}
|
}
|
||||||
|
@ -544,6 +552,8 @@ namespace SHADE
|
||||||
resourceAttachmentMapping = std::move(rhs.resourceAttachmentMapping);
|
resourceAttachmentMapping = std::move(rhs.resourceAttachmentMapping);
|
||||||
subpassIndexing = std::move(rhs.subpassIndexing);
|
subpassIndexing = std::move(rhs.subpassIndexing);
|
||||||
ptrToResources = std::move(rhs.ptrToResources);
|
ptrToResources = std::move(rhs.ptrToResources);
|
||||||
|
pipelineLibrary = std::move(rhs.pipelineLibrary);
|
||||||
|
batcher = std::move(rhs.batcher);
|
||||||
|
|
||||||
rhs.renderpass = {};
|
rhs.renderpass = {};
|
||||||
|
|
||||||
|
@ -577,6 +587,7 @@ namespace SHADE
|
||||||
subpasses.emplace_back(resourceManager.Create<SHSubpass>(resourceManager, GetHandle(), subpasses.size(), &resourceAttachmentMapping, ptrToResources));
|
subpasses.emplace_back(resourceManager.Create<SHSubpass>(resourceManager, GetHandle(), subpasses.size(), &resourceAttachmentMapping, ptrToResources));
|
||||||
subpassIndexing.try_emplace(subpassName, static_cast<uint32_t>(subpasses.size()) - 1u);
|
subpassIndexing.try_emplace(subpassName, static_cast<uint32_t>(subpasses.size()) - 1u);
|
||||||
Handle<SHSubpass> subpass = subpasses.back();
|
Handle<SHSubpass> subpass = subpasses.back();
|
||||||
|
subpass->Init(resourceManager);
|
||||||
|
|
||||||
// Register the SuperBatch
|
// Register the SuperBatch
|
||||||
batcher.RegisterSuperBatch(subpass->GetSuperBatch());
|
batcher.RegisterSuperBatch(subpass->GetSuperBatch());
|
||||||
|
@ -705,7 +716,7 @@ namespace SHADE
|
||||||
// First we want to take all the attachment descriptions and initialize the
|
// First we want to take all the attachment descriptions and initialize the
|
||||||
// finalLayout to whatever layout is specified in the last subpass that references the attachment.
|
// finalLayout to whatever layout is specified in the last subpass that references the attachment.
|
||||||
|
|
||||||
for (auto& node : nodes)
|
for (uint32_t i = 0; auto& node : nodes)
|
||||||
{
|
{
|
||||||
// key is handle ID, value is pair (first is initial layout, second is final layout).
|
// key is handle ID, value is pair (first is initial layout, second is final layout).
|
||||||
std::unordered_map<uint32_t, vk::ImageLayout> resourceAttLayouts;
|
std::unordered_map<uint32_t, vk::ImageLayout> resourceAttLayouts;
|
||||||
|
@ -719,7 +730,7 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
for (auto& color : subpass->colorReferences)
|
for (auto& color : subpass->colorReferences)
|
||||||
{
|
{
|
||||||
if (node->attResources[color.attachment]->resourceType == SH_ATT_DESC_TYPE::COLOR_PRESENT)
|
if (i == nodes.size() - 1 && node->attResources[color.attachment]->resourceType == SH_ATT_DESC_TYPE::COLOR_PRESENT)
|
||||||
resourceAttLayouts[color.attachment] = vk::ImageLayout::ePresentSrcKHR;
|
resourceAttLayouts[color.attachment] = vk::ImageLayout::ePresentSrcKHR;
|
||||||
else
|
else
|
||||||
resourceAttLayouts[color.attachment] = color.layout;
|
resourceAttLayouts[color.attachment] = color.layout;
|
||||||
|
@ -738,6 +749,7 @@ namespace SHADE
|
||||||
att.initialLayout = vk::ImageLayout::eUndefined;
|
att.initialLayout = vk::ImageLayout::eUndefined;
|
||||||
att.finalLayout = resourceAttLayouts[i];
|
att.finalLayout = resourceAttLayouts[i];
|
||||||
}
|
}
|
||||||
|
++i;
|
||||||
}
|
}
|
||||||
|
|
||||||
// at this point all attachment descs will have their final layouts initialized as if they were standalone and did
|
// at this point all attachment descs will have their final layouts initialized as if they were standalone and did
|
||||||
|
@ -846,7 +858,7 @@ namespace SHADE
|
||||||
for (auto& inputAtt : subpass->inputReferences)
|
for (auto& inputAtt : subpass->inputReferences)
|
||||||
{
|
{
|
||||||
auto resource = node->attResources[inputAtt.attachment];
|
auto resource = node->attResources[inputAtt.attachment];
|
||||||
if (resource->resourceType == SH_ATT_DESC_TYPE::COLOR)
|
if (resource->resourceType == SH_ATT_DESC_TYPE::COLOR || resource->resourceType == SH_ATT_DESC_TYPE::COLOR_PRESENT)
|
||||||
colorRead |= (1 << i);
|
colorRead |= (1 << i);
|
||||||
else if (resource->resourceType == SH_ATT_DESC_TYPE::DEPTH_STENCIL)
|
else if (resource->resourceType == SH_ATT_DESC_TYPE::DEPTH_STENCIL)
|
||||||
depthRead |= (1 << i);
|
depthRead |= (1 << i);
|
||||||
|
@ -993,6 +1005,34 @@ namespace SHADE
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SHRenderGraph::SHRenderGraph(SHRenderGraph&& rhs) noexcept
|
||||||
|
: logicalDeviceHdl{ rhs.logicalDeviceHdl }
|
||||||
|
, swapchainHdl{ rhs.swapchainHdl }
|
||||||
|
, nodeIndexing{ std::move(rhs.nodeIndexing) }
|
||||||
|
, nodes{ std::move(rhs.nodes) }
|
||||||
|
, graphResources{ std::move(rhs.graphResources) }
|
||||||
|
, resourceManager{ std::move(rhs.resourceManager) }
|
||||||
|
, globalData{ rhs.globalData }
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
SHRenderGraph& SHRenderGraph::operator=(SHRenderGraph&& rhs) noexcept
|
||||||
|
{
|
||||||
|
if (&rhs == this)
|
||||||
|
return *this;
|
||||||
|
|
||||||
|
logicalDeviceHdl = rhs.logicalDeviceHdl;
|
||||||
|
swapchainHdl = rhs.swapchainHdl;
|
||||||
|
nodeIndexing = std::move(rhs.nodeIndexing);
|
||||||
|
nodes = std::move(rhs.nodes);
|
||||||
|
graphResources = std::move(rhs.graphResources);
|
||||||
|
resourceManager = std::move(rhs.resourceManager);
|
||||||
|
globalData = rhs.globalData;
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
/*!
|
/*!
|
||||||
|
|
||||||
|
|
|
@ -140,6 +140,8 @@ namespace SHADE
|
||||||
void Execute(Handle<SHVkCommandBuffer>& commandBuffer, uint32_t frameIndex) noexcept;
|
void Execute(Handle<SHVkCommandBuffer>& commandBuffer, uint32_t frameIndex) noexcept;
|
||||||
void AddExteriorDrawCalls(std::function<void(Handle<SHVkCommandBuffer>&)> const& newDrawCall) noexcept;
|
void AddExteriorDrawCalls(std::function<void(Handle<SHVkCommandBuffer>&)> const& newDrawCall) noexcept;
|
||||||
|
|
||||||
|
void Init (ResourceManager& resourceManager) noexcept;
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
/* GETTERS AND SETTERS */
|
/* GETTERS AND SETTERS */
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
|
@ -279,6 +281,8 @@ namespace SHADE
|
||||||
/* CTORS AND DTORS */
|
/* CTORS AND DTORS */
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
SHRenderGraph (void) noexcept;
|
SHRenderGraph (void) noexcept;
|
||||||
|
SHRenderGraph(SHRenderGraph&& rhs) noexcept;
|
||||||
|
SHRenderGraph& operator=(SHRenderGraph&& rhs) noexcept;
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
/* PUBLIC MEMBER FUNCTIONS */
|
/* PUBLIC MEMBER FUNCTIONS */
|
||||||
|
|
Loading…
Reference in New Issue