Rendering merge #65
Binary file not shown.
|
@ -84,6 +84,7 @@ namespace Sandbox
|
||||||
SHADE::SHAssetManager::LoadDataTemp("../../Assets/racoon.gltf");
|
SHADE::SHAssetManager::LoadDataTemp("../../Assets/racoon.gltf");
|
||||||
SHADE::SHAssetManager::LoadDataTemp("../../Assets/RaccoonBag_Color_Ver4.dds");
|
SHADE::SHAssetManager::LoadDataTemp("../../Assets/RaccoonBag_Color_Ver4.dds");
|
||||||
SHADE::SHAssetManager::LoadDataTemp("../../Assets/RaccoonPreTexturedVer1_Base9.dds");
|
SHADE::SHAssetManager::LoadDataTemp("../../Assets/RaccoonPreTexturedVer1_Base9.dds");
|
||||||
|
SHADE::SHAssetManager::LoadDataTemp("../../Assets/TD_Checker_Base_Color.dds");
|
||||||
//TODO: REMOVE AFTER PRESENTATION
|
//TODO: REMOVE AFTER PRESENTATION
|
||||||
|
|
||||||
//SHADE::SHSystemManager::RegisterRoutine<SHADE::SHAudioSystem, SHADE::SHAudioSystem::AudioRoutine>();
|
//SHADE::SHSystemManager::RegisterRoutine<SHADE::SHAudioSystem, SHADE::SHAudioSystem::AudioRoutine>();
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
#include "Graphics/MiddleEnd/Interface/SHGraphicsSystem.h"
|
#include "Graphics/MiddleEnd/Interface/SHGraphicsSystem.h"
|
||||||
#include "Scripting/SHScriptEngine.h"
|
#include "Scripting/SHScriptEngine.h"
|
||||||
#include "Math/Transform/SHTransformComponent.h"
|
#include "Math/Transform/SHTransformComponent.h"
|
||||||
|
#include "Graphics/MiddleEnd/Interface/SHMaterialInstance.h"
|
||||||
|
|
||||||
#include "Assets/SHAssetManager.h"
|
#include "Assets/SHAssetManager.h"
|
||||||
|
|
||||||
|
@ -57,70 +58,103 @@ namespace Sandbox
|
||||||
}
|
}
|
||||||
graphicsSystem->BuildMeshBuffers();
|
graphicsSystem->BuildMeshBuffers();
|
||||||
|
|
||||||
//Test Textures
|
// Load Textures
|
||||||
auto textures{ SHADE::SHAssetManager::GetAllTextures() };
|
auto textures = SHADE::SHAssetManager::GetAllTextures();
|
||||||
|
std::vector<Handle<SHTexture>> texHandles;
|
||||||
|
for (const auto& tex : textures)
|
||||||
|
{
|
||||||
|
auto texture = graphicsSystem->Add(tex);
|
||||||
|
texHandles.push_back(texture);
|
||||||
|
}
|
||||||
|
graphicsSystem->BuildTextures();
|
||||||
|
|
||||||
// Create Materials
|
// Create Materials
|
||||||
auto matInst = graphicsSystem->AddOrGetBaseMaterialInstance();
|
auto matInst = graphicsSystem->AddOrGetBaseMaterialInstance();
|
||||||
|
auto customMat = graphicsSystem->AddMaterialInstanceCopy(matInst);
|
||||||
|
customMat->SetProperty("data.color", SHVec4(0.0f, 1.0f, 1.0f, 1.0f));
|
||||||
|
customMat->SetProperty("data.textureIndex", 1);
|
||||||
|
customMat->SetProperty("data.alpha", 0.1f);
|
||||||
|
|
||||||
// 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.05f, 0.05f, 0.05f };
|
||||||
constexpr int NUM_ROWS = 1;
|
constexpr int NUM_ROWS = 100;
|
||||||
constexpr int NUM_COLS = 1;
|
constexpr int NUM_COLS = 100;
|
||||||
static const SHVec3 TEST_OBJ_SPACING = { 1.0f, 1.0f, 1.0f };
|
static const SHVec3 TEST_OBJ_SPACING = { 0.05f, 0.05f, 0.05f };
|
||||||
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 ) + 1.0f, -2.0f, -1.0f };
|
||||||
//for (int z = 0; z < NUM_ROWS; ++z)
|
|
||||||
//for (int x = 0; x < NUM_COLS; ++x)
|
|
||||||
//{
|
|
||||||
// auto entity = SHEntityManager::CreateEntity<SHRenderable, SHTransformComponent>();
|
|
||||||
// auto& renderable = *SHComponentManager::GetComponent_s<SHRenderable>(entity);
|
|
||||||
// auto& transform = *SHComponentManager::GetComponent_s<SHTransformComponent>(entity);
|
|
||||||
|
|
||||||
// renderable.Mesh = handles.front();
|
|
||||||
// renderable.SetMaterial(matInst);
|
|
||||||
|
|
||||||
// // Set initial positions
|
|
||||||
// transform.SetWorldPosition(TEST_OBJ_START_POS + SHVec3{ x * TEST_OBJ_SPACING.x, 0.0f, z * TEST_OBJ_SPACING.z });
|
|
||||||
// //transform.SetLocalScale(TEST_OBJ_SCALE);
|
|
||||||
|
|
||||||
// stressTestObjects.emplace_back(entity);
|
|
||||||
//}
|
|
||||||
|
|
||||||
|
for (int y = 0; y < NUM_ROWS; ++y)
|
||||||
|
for (int x = 0; x < NUM_COLS; ++x)
|
||||||
|
{
|
||||||
auto entity = SHEntityManager::CreateEntity<SHRenderable, SHTransformComponent>();
|
auto entity = SHEntityManager::CreateEntity<SHRenderable, SHTransformComponent>();
|
||||||
auto& renderable = *SHComponentManager::GetComponent_s<SHRenderable>(entity);
|
auto& renderable = *SHComponentManager::GetComponent_s<SHRenderable>(entity);
|
||||||
auto& transform = *SHComponentManager::GetComponent_s<SHTransformComponent>(entity);
|
auto& transform = *SHComponentManager::GetComponent_s<SHTransformComponent>(entity);
|
||||||
|
|
||||||
renderable.Mesh = handles.front();
|
renderable.Mesh = handles.front();
|
||||||
renderable.SetMaterial(matInst);
|
renderable.SetMaterial(customMat);
|
||||||
|
|
||||||
//transform.SetLocalScale(TEST_OBJ_SCALE);
|
if (y == 50)
|
||||||
|
renderable.GetModifiableMaterial()->SetProperty("data.color", SHVec4(1.0f, 0.0f, 0.0f, 1.0f));
|
||||||
|
|
||||||
|
//Set initial positions
|
||||||
|
transform.SetWorldPosition(TEST_OBJ_START_POS + SHVec3{
|
||||||
|
x * TEST_OBJ_SPACING.x,
|
||||||
|
y * TEST_OBJ_SPACING.y,
|
||||||
|
0.0f
|
||||||
|
});
|
||||||
|
//transform.SetWorldPosition({-1.0f, -1.0f, -1.0f});
|
||||||
|
//transform.SetWorldRotation(3.14159265f * 1.5f, -3.14159265f / 2.0f, 0.0f);
|
||||||
|
transform.SetLocalScale(TEST_OBJ_SCALE);
|
||||||
|
|
||||||
stressTestObjects.emplace_back(entity);
|
stressTestObjects.emplace_back(entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto entity = SHEntityManager::CreateEntity<SHRenderable, SHTransformComponent>();
|
||||||
|
auto& renderable = *SHComponentManager::GetComponent_s<SHRenderable>(entity);
|
||||||
|
auto& transform = *SHComponentManager::GetComponent_s<SHTransformComponent>(entity);
|
||||||
|
|
||||||
|
renderable.Mesh = handles.front();
|
||||||
|
renderable.SetMaterial(customMat);
|
||||||
|
renderable.GetModifiableMaterial()->SetProperty("data.color", SHVec4(0.0f, 0.0f, 0.0f, 0.0f));
|
||||||
|
renderable.GetModifiableMaterial()->SetProperty("data.alpha", 1.0f);
|
||||||
|
renderable.GetModifiableMaterial()->SetProperty("data.textureIndex", 1);
|
||||||
|
|
||||||
|
transform.SetWorldPosition ({-3.0f, -1.0f, -1.0f});
|
||||||
|
transform.SetLocalScale({5.0f, 5.0f, 5.0f});
|
||||||
|
|
||||||
|
//auto entity = SHEntityManager::CreateEntity<SHRenderable, SHTransformComponent>();
|
||||||
|
//auto& renderable = *SHComponentManager::GetComponent_s<SHRenderable>(entity);
|
||||||
|
//auto& transform = *SHComponentManager::GetComponent_s<SHTransformComponent>(entity);
|
||||||
|
|
||||||
|
//renderable.Mesh = handles.back();
|
||||||
|
//renderable.SetMaterial(customMat);
|
||||||
|
|
||||||
|
//transform.SetLocalScale(TEST_OBJ_SCALE);
|
||||||
|
//transform.SetWorldPosition({-1.0f, -1.0f, -1.0f});
|
||||||
|
|
||||||
// Create blank entity with a script
|
// Create blank entity with a script
|
||||||
testObj = SHADE::SHEntityManager::CreateEntity();
|
//testObj = SHADE::SHEntityManager::CreateEntity<SHRenderable, SHTransformComponent>();
|
||||||
|
//auto& testObjRenderable = *SHComponentManager::GetComponent_s<SHRenderable>(testObj);
|
||||||
|
//testObjRenderable.Mesh = CUBE_MESH;
|
||||||
|
//testObjRenderable.SetMaterial(matInst);
|
||||||
|
|
||||||
SHADE::SHScriptEngine* scriptEngine = static_cast<SHADE::SHScriptEngine*>(SHADE::SHSystemManager::GetSystem<SHADE::SHScriptEngine>());
|
SHADE::SHScriptEngine* scriptEngine = static_cast<SHADE::SHScriptEngine*>(SHADE::SHSystemManager::GetSystem<SHADE::SHScriptEngine>());
|
||||||
scriptEngine->AddScript(testObj, "TestScript");
|
scriptEngine->AddScript(testObj, "TestScript");
|
||||||
}
|
}
|
||||||
|
|
||||||
void SBTestScene::Update(float dt)
|
void SBTestScene::Update(float dt)
|
||||||
{
|
{
|
||||||
/*static float rotation = 0.0f;
|
static float rotation = 0.0f;
|
||||||
|
|
||||||
auto& transform = *SHADE::SHComponentManager::GetComponent_s<SHADE::SHTransformComponent>(testObj);
|
//auto& transform = *SHADE::SHComponentManager::GetComponent_s<SHADE::SHTransformComponent>(testObj);
|
||||||
|
|
||||||
transform.SetLocalRotation(rotation, 0.0f, 0.0f);
|
//transform.SetWorldPosition({1.0f, 1.0f, -1.0f});
|
||||||
rotation += dt * 10.0f;*/
|
//transform.SetWorldRotation(0.0f, 0.0f + rotation, 0.0f);
|
||||||
/*static float rotation = 0.0f;
|
//rotation += dt * 0.2f;
|
||||||
|
|
||||||
auto& transform = *SHADE::SHComponentManager::GetComponent_s<SHADE::SHTransformComponent>(stressTestObjects[0]);
|
|
||||||
|
|
||||||
transform.SetWorldPosition({rotation, 0.0f, 0.0f});
|
|
||||||
rotation += dt * 10.0f;*/
|
|
||||||
|
|
||||||
// Destroy entity if space is pressed
|
// Destroy entity if space is pressed
|
||||||
if (GetKeyState(VK_SPACE) & 0x8000)
|
if (GetKeyState(VK_SPACE) & 0x8000)
|
||||||
{
|
{
|
||||||
|
rotation = 0.0f;
|
||||||
SHADE::SHScriptEngine* scriptEngine = static_cast<SHADE::SHScriptEngine*>(SHADE::SHSystemManager::GetSystem<SHADE::SHScriptEngine>());
|
SHADE::SHScriptEngine* scriptEngine = static_cast<SHADE::SHScriptEngine*>(SHADE::SHSystemManager::GetSystem<SHADE::SHScriptEngine>());
|
||||||
scriptEngine->RemoveAllScripts(testObj);
|
scriptEngine->RemoveAllScripts(testObj);
|
||||||
}
|
}
|
||||||
|
@ -128,6 +162,7 @@ namespace Sandbox
|
||||||
|
|
||||||
void SBTestScene::Render()
|
void SBTestScene::Render()
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SBTestScene::Unload()
|
void SBTestScene::Unload()
|
||||||
|
|
|
@ -133,6 +133,9 @@ project "SHADE_Engine"
|
||||||
"xcopy /r /y /q \"%{IncludeDir.fmod}\\lib\\fmodstudio.dll\" \"$(OutDir)\""
|
"xcopy /r /y /q \"%{IncludeDir.fmod}\\lib\\fmodstudio.dll\" \"$(OutDir)\""
|
||||||
}
|
}
|
||||||
|
|
||||||
|
filter "configurations:Publish"
|
||||||
|
postbuildcommands {"xcopy /r /y /q \"%{IncludeDir.assimp}\\bin\\Release\\assimp-vc142-mt.dll\" \"$(OutDir)\""}
|
||||||
|
|
||||||
warnings 'Extra'
|
warnings 'Extra'
|
||||||
|
|
||||||
filter "configurations:Debug"
|
filter "configurations:Debug"
|
||||||
|
|
|
@ -2,16 +2,17 @@
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include "Math/SHMath.h"
|
#include "Math/SHMath.h"
|
||||||
|
#include "SH_API.h"
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
struct SHMeshAssetHeader
|
struct SH_API SHMeshAssetHeader
|
||||||
{
|
{
|
||||||
uint32_t vertexCount;
|
uint32_t vertexCount;
|
||||||
uint32_t indexCount;
|
uint32_t indexCount;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct SHMeshAsset
|
struct SH_API SHMeshAsset
|
||||||
{
|
{
|
||||||
bool compiled;
|
bool compiled;
|
||||||
bool changed;
|
bool changed;
|
||||||
|
|
|
@ -74,12 +74,12 @@ namespace SHADE
|
||||||
|
|
||||||
for (auto i{0}; i < file.GetMipCount(); ++i)
|
for (auto i{0}; i < file.GetMipCount(); ++i)
|
||||||
{
|
{
|
||||||
mipOff.push_back(totalBytes);
|
mipOff[i] = totalBytes;
|
||||||
totalBytes += file.GetImageData(i, 0)->m_memSlicePitch;
|
totalBytes += file.GetImageData(i, 0)->m_memSlicePitch;
|
||||||
}
|
}
|
||||||
|
|
||||||
SHTexture::PixelChannel* pixel = new SHTexture::PixelChannel[totalBytes];
|
SHTexture::PixelChannel* pixel = new SHTexture::PixelChannel[totalBytes];
|
||||||
std::memcpy(pixel, file.GetDDSData(), totalBytes);
|
std::memcpy(pixel, file.GetImageData()->m_mem, totalBytes);
|
||||||
//pixel = std::move(reinterpret_cast<SHTexture::PixelChannel const*>(file.GetDDSData()));
|
//pixel = std::move(reinterpret_cast<SHTexture::PixelChannel const*>(file.GetDDSData()));
|
||||||
|
|
||||||
asset.numBytes = totalBytes;
|
asset.numBytes = totalBytes;
|
||||||
|
|
|
@ -39,8 +39,10 @@ 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 }
|
{ vk::DescriptorType::eUniformBufferDynamic, 100 },
|
||||||
|
{ vk::DescriptorType::eStorageImage, 100},
|
||||||
|
{ vk::DescriptorType::eStorageBufferDynamic, 100 }
|
||||||
};
|
};
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Maximum number of descriptor sets allowed
|
/// Maximum number of descriptor sets allowed
|
||||||
|
|
|
@ -155,7 +155,7 @@ namespace SHADE
|
||||||
|
|
||||||
*/
|
*/
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
void SHVkDescriptorSetGroup::ModifyWriteDescImage(uint32_t set, uint32_t binding, std::span<std::pair<Handle<SHVkImageView>, Handle<SHVkSampler>>> const& imageViewsAndSamplers) noexcept
|
void SHVkDescriptorSetGroup::ModifyWriteDescImage(uint32_t set, uint32_t binding, std::span<std::tuple<Handle<SHVkImageView>, Handle<SHVkSampler>, vk::ImageLayout>> const& imageViewsAndSamplers) noexcept
|
||||||
{
|
{
|
||||||
// Find the target writeDescSet
|
// Find the target writeDescSet
|
||||||
BindingAndSetHash writeHash = binding;
|
BindingAndSetHash writeHash = binding;
|
||||||
|
@ -170,9 +170,10 @@ namespace SHADE
|
||||||
for (uint32_t i = 0; i < imageViewsAndSamplers.size(); ++i)
|
for (uint32_t i = 0; i < imageViewsAndSamplers.size(); ++i)
|
||||||
{
|
{
|
||||||
// write sampler and image view
|
// write sampler and image view
|
||||||
auto& ivs = imageViewsAndSamplers[i];
|
auto& [view, sampler, layout] = imageViewsAndSamplers[i];
|
||||||
writeInfo.descImageInfos[i].imageView = ivs.first->GetImageView();
|
writeInfo.descImageInfos[i].imageView = view->GetImageView();
|
||||||
writeInfo.descImageInfos[i].sampler = ivs.second->GetVkSampler();
|
writeInfo.descImageInfos[i].sampler = sampler->GetVkSampler();
|
||||||
|
writeInfo.descImageInfos[i].imageLayout = layout;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <tuple>
|
||||||
|
|
||||||
// Project Includes
|
// Project Includes
|
||||||
#include "Graphics/SHVulkanIncludes.h"
|
#include "Graphics/SHVulkanIncludes.h"
|
||||||
#include "Resource/Handle.h"
|
#include "Resource/Handle.h"
|
||||||
|
@ -63,7 +65,7 @@ namespace SHADE
|
||||||
void UpdateDescriptorSetImages(uint32_t set, uint32_t binding) noexcept;
|
void UpdateDescriptorSetImages(uint32_t set, uint32_t binding) noexcept;
|
||||||
void UpdateDescriptorSetBuffer(uint32_t set, uint32_t binding) noexcept;
|
void UpdateDescriptorSetBuffer(uint32_t set, uint32_t binding) noexcept;
|
||||||
|
|
||||||
void ModifyWriteDescImage(uint32_t set, uint32_t binding, std::span<std::pair<Handle<SHVkImageView>, Handle<SHVkSampler>>> const& imageViewsAndSamplers) noexcept;
|
void ModifyWriteDescImage(uint32_t set, uint32_t binding, std::span<std::tuple<Handle<SHVkImageView>, Handle<SHVkSampler>, vk::ImageLayout>> const& imageViewsAndSamplers) noexcept;
|
||||||
void ModifyWriteDescBuffer (uint32_t set, uint32_t binding, std::span<Handle<SHVkBuffer>> const& buffers, uint32_t offset, uint32_t range) noexcept;
|
void ModifyWriteDescBuffer (uint32_t set, uint32_t binding, std::span<Handle<SHVkBuffer>> const& buffers, uint32_t offset, uint32_t range) noexcept;
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
#include "Graphics/Framebuffer/SHVkFramebuffer.h"
|
#include "Graphics/Framebuffer/SHVkFramebuffer.h"
|
||||||
#include "Graphics/Images/SHVkImageView.h"
|
#include "Graphics/Images/SHVkImageView.h"
|
||||||
#include "Graphics/Descriptors/SHVkDescriptorSetGroup.h"
|
#include "Graphics/Descriptors/SHVkDescriptorSetGroup.h"
|
||||||
|
#include "Graphics/Images/SHVkSampler.h"
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
|
@ -85,6 +86,17 @@ namespace SHADE
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t SHVkLogicalDevice::ComputeAlignedBufferSize(uint32_t originalSize, size_t alignmentSize) const noexcept
|
||||||
|
{
|
||||||
|
uint32_t alignedSize = originalSize;
|
||||||
|
//uint32_t minBuffer
|
||||||
|
if (alignmentSize > 0)
|
||||||
|
{
|
||||||
|
alignedSize = (alignedSize + alignmentSize - 1) & ~(alignmentSize - 1);
|
||||||
|
}
|
||||||
|
return alignedSize;
|
||||||
|
}
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
/*!
|
/*!
|
||||||
|
|
||||||
|
@ -176,6 +188,7 @@ namespace SHADE
|
||||||
// point and lines fill mode
|
// point and lines fill mode
|
||||||
features.fillModeNonSolid = true;
|
features.fillModeNonSolid = true;
|
||||||
features.samplerAnisotropy = VK_TRUE;
|
features.samplerAnisotropy = VK_TRUE;
|
||||||
|
features.multiDrawIndirect = true;
|
||||||
|
|
||||||
// for wide lines
|
// for wide lines
|
||||||
features.wideLines = true;
|
features.wideLines = true;
|
||||||
|
@ -288,13 +301,12 @@ namespace SHADE
|
||||||
|
|
||||||
uint32_t SHVkLogicalDevice::PadUBOSize(uint32_t originalSize) const noexcept
|
uint32_t SHVkLogicalDevice::PadUBOSize(uint32_t originalSize) const noexcept
|
||||||
{
|
{
|
||||||
uint32_t alignedSize = originalSize;
|
return ComputeAlignedBufferSize(originalSize, uboBufferMemoryAlignment);
|
||||||
//uint32_t minBuffer
|
}
|
||||||
if (uboBufferMemoryAlignment > 0)
|
|
||||||
{
|
uint32_t SHVkLogicalDevice::PadSSBOSize(uint32_t originalSize) const noexcept
|
||||||
alignedSize = (alignedSize + uboBufferMemoryAlignment - 1) & ~(uboBufferMemoryAlignment - 1);
|
{
|
||||||
}
|
return ComputeAlignedBufferSize(originalSize, ssboBufferMemoryAlignment);
|
||||||
return alignedSize;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
|
@ -499,6 +511,11 @@ namespace SHADE
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Handle<SHVkSampler> SHVkLogicalDevice::CreateSampler(const SHVkSamplerParams& params) noexcept
|
||||||
|
{
|
||||||
|
return SHVkInstance::GetResourceManager().Create <SHVkSampler>(GetHandle(), params);
|
||||||
|
}
|
||||||
|
|
||||||
Handle<SHVkRenderpass> SHVkLogicalDevice::CreateRenderpass(std::span<vk::AttachmentDescription> const vkDescriptions, std::vector<SHVkSubpassParams> const& subpasses) noexcept
|
Handle<SHVkRenderpass> SHVkLogicalDevice::CreateRenderpass(std::span<vk::AttachmentDescription> const vkDescriptions, std::vector<SHVkSubpassParams> const& subpasses) noexcept
|
||||||
{
|
{
|
||||||
return SHVkInstance::GetResourceManager().Create <SHVkRenderpass>(GetHandle(), vkDescriptions, subpasses);
|
return SHVkInstance::GetResourceManager().Create <SHVkRenderpass>(GetHandle(), vkDescriptions, subpasses);
|
||||||
|
|
|
@ -21,7 +21,6 @@
|
||||||
#include "Graphics/Descriptors/SHVkDescriptorSetLayout.h"
|
#include "Graphics/Descriptors/SHVkDescriptorSetLayout.h"
|
||||||
#include "Graphics/Images/SHVkImage.h"
|
#include "Graphics/Images/SHVkImage.h"
|
||||||
|
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
|
@ -41,6 +40,8 @@ namespace SHADE
|
||||||
class SHShaderBlockInterface;
|
class SHShaderBlockInterface;
|
||||||
class SHVkDescriptorSetGroup;
|
class SHVkDescriptorSetGroup;
|
||||||
class SHSubpass;
|
class SHSubpass;
|
||||||
|
class SHVkSampler;
|
||||||
|
struct SHVkSamplerParams;
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
/*!
|
/*!
|
||||||
|
@ -102,6 +103,7 @@ namespace SHADE
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
void InitializeVMA (void) noexcept;
|
void InitializeVMA (void) noexcept;
|
||||||
void InitializeQueues (std::initializer_list<SHQueueParams> queueCreateParams) noexcept;
|
void InitializeQueues (std::initializer_list<SHQueueParams> queueCreateParams) noexcept;
|
||||||
|
uint32_t ComputeAlignedBufferSize(uint32_t originalSize, size_t typeSize) const noexcept;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
|
@ -121,7 +123,8 @@ namespace SHADE
|
||||||
// Miscellaneous functions
|
// Miscellaneous functions
|
||||||
void WaitIdle (void) noexcept;
|
void WaitIdle (void) noexcept;
|
||||||
uint32_t FindMemoryType (uint32_t typeFilter, vk::MemoryPropertyFlags properties);
|
uint32_t FindMemoryType (uint32_t typeFilter, vk::MemoryPropertyFlags properties);
|
||||||
uint32_t PadUBOSize (uint32_t originalSize) const noexcept;
|
uint32_t PadUBOSize(uint32_t originalSize) const noexcept;
|
||||||
|
uint32_t PadSSBOSize(uint32_t originalSize) const noexcept;
|
||||||
|
|
||||||
// creation functions
|
// creation functions
|
||||||
Handle<SHVkSurface> CreateSurface (HWND const& windowHandle) const noexcept;
|
Handle<SHVkSurface> CreateSurface (HWND const& windowHandle) const noexcept;
|
||||||
|
@ -178,6 +181,7 @@ namespace SHADE
|
||||||
Handle<SHVkRenderpass> const& renderpassHdl,
|
Handle<SHVkRenderpass> const& renderpassHdl,
|
||||||
Handle<SHSubpass> subpass
|
Handle<SHSubpass> subpass
|
||||||
) noexcept;
|
) noexcept;
|
||||||
|
Handle<SHVkSampler> CreateSampler (const SHVkSamplerParams& params) noexcept;
|
||||||
|
|
||||||
Handle<SHVkRenderpass> CreateRenderpass (std::span<vk::AttachmentDescription> const vkDescriptions, std::vector<SHVkSubpassParams> const& subpasses) noexcept;
|
Handle<SHVkRenderpass> CreateRenderpass (std::span<vk::AttachmentDescription> const vkDescriptions, std::vector<SHVkSubpassParams> const& subpasses) noexcept;
|
||||||
Handle<SHVkRenderpass> CreateRenderpass (std::span<vk::AttachmentDescription> const vkDescriptions, std::span<vk::SubpassDescription> const spDescs, std::span<vk::SubpassDependency> const spDeps) noexcept;
|
Handle<SHVkRenderpass> CreateRenderpass (std::span<vk::AttachmentDescription> const vkDescriptions, std::span<vk::SubpassDescription> const spDescs, std::span<vk::SubpassDependency> const spDeps) noexcept;
|
||||||
|
|
|
@ -26,7 +26,7 @@ namespace SHADE
|
||||||
|
|
||||||
*/
|
*/
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
void SHVkImage::PrepStagingBuffer(void* data, uint32_t srcSize) noexcept
|
void SHVkImage::PrepStagingBuffer(const void* data, uint32_t srcSize) noexcept
|
||||||
{
|
{
|
||||||
// For creation of buffer
|
// For creation of buffer
|
||||||
vk::BufferCreateInfo bufferInfo{};
|
vk::BufferCreateInfo bufferInfo{};
|
||||||
|
@ -70,7 +70,7 @@ namespace SHADE
|
||||||
vmaMapMemory(*vmaAllocator, stagingAlloc, &stagingBufferMappedPtr);
|
vmaMapMemory(*vmaAllocator, stagingAlloc, &stagingBufferMappedPtr);
|
||||||
|
|
||||||
if (stagingBufferMappedPtr)
|
if (stagingBufferMappedPtr)
|
||||||
std::memcpy(static_cast<uint8_t*>(stagingBufferMappedPtr), static_cast<uint8_t*>(data), srcSize);
|
std::memcpy(static_cast<uint8_t*>(stagingBufferMappedPtr), static_cast<const uint8_t*>(data), srcSize);
|
||||||
|
|
||||||
const VkDeviceSize offsets = 0;
|
const VkDeviceSize offsets = 0;
|
||||||
const VkDeviceSize sizes = srcSize;
|
const VkDeviceSize sizes = srcSize;
|
||||||
|
@ -82,7 +82,7 @@ namespace SHADE
|
||||||
SHVkImage::SHVkImage(
|
SHVkImage::SHVkImage(
|
||||||
VmaAllocator const* allocator,
|
VmaAllocator const* allocator,
|
||||||
SHImageCreateParams const& imageDetails,
|
SHImageCreateParams const& imageDetails,
|
||||||
unsigned char* data,
|
const unsigned char* data,
|
||||||
uint32_t dataSize,
|
uint32_t dataSize,
|
||||||
std::span<uint32_t> inMipOffsets,
|
std::span<uint32_t> inMipOffsets,
|
||||||
VmaMemoryUsage memUsage,
|
VmaMemoryUsage memUsage,
|
||||||
|
|
|
@ -107,7 +107,7 @@ namespace SHADE
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
/* PRIVATE MEMBER FUNCTIONS */
|
/* PRIVATE MEMBER FUNCTIONS */
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
void PrepStagingBuffer(void* data, uint32_t srcSize) noexcept;
|
void PrepStagingBuffer(const void* data, uint32_t srcSize) noexcept;
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -119,7 +119,7 @@ namespace SHADE
|
||||||
SHVkImage(
|
SHVkImage(
|
||||||
VmaAllocator const* allocator,
|
VmaAllocator const* allocator,
|
||||||
SHImageCreateParams const& imageDetails,
|
SHImageCreateParams const& imageDetails,
|
||||||
unsigned char* data,
|
const unsigned char* data,
|
||||||
uint32_t dataSize,
|
uint32_t dataSize,
|
||||||
std::span<uint32_t> inMipOffsets,
|
std::span<uint32_t> inMipOffsets,
|
||||||
VmaMemoryUsage memUsage,
|
VmaMemoryUsage memUsage,
|
||||||
|
|
|
@ -1,12 +1,62 @@
|
||||||
|
/************************************************************************************//*!
|
||||||
|
\file SHVkSampler.cpp
|
||||||
|
\author Tng Kah Wei, kahwei.tng, 390009620
|
||||||
|
\par email: kahwei.tng\@digipen.edu
|
||||||
|
\date Sep 26, 2022
|
||||||
|
\brief Contains definitions for all of the functions of the SHVkSampler class.
|
||||||
|
|
||||||
|
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 "SHpch.h"
|
||||||
#include "SHVkSampler.h"
|
#include "SHVkSampler.h"
|
||||||
|
|
||||||
|
#include "Graphics/Devices/SHVkLogicalDevice.h"
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
vk::Sampler SHVkSampler::GetVkSampler(void) const noexcept
|
/* Constructors */
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
SHVkSampler::SHVkSampler(Handle<SHVkLogicalDevice> logicalDevice, const SHVkSamplerParams& params) noexcept
|
||||||
|
: device { logicalDevice }
|
||||||
{
|
{
|
||||||
return vkSampler;
|
const vk::SamplerCreateInfo SAMPLER_CREATE_INFO
|
||||||
|
{
|
||||||
|
.magFilter = params.magFilter,
|
||||||
|
.minFilter = params.minFilter,
|
||||||
|
.mipmapMode = params.mipmapMode,
|
||||||
|
.addressModeU = params.addressMode,
|
||||||
|
.addressModeV = params.addressMode,
|
||||||
|
.addressModeW = params.addressMode,
|
||||||
|
.minLod = params.minLod,
|
||||||
|
.maxLod = params.maxLod
|
||||||
|
};
|
||||||
|
|
||||||
|
// Create the sampler
|
||||||
|
vkSampler = device->GetVkLogicalDevice().createSampler(SAMPLER_CREATE_INFO);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SHVkSampler::SHVkSampler(SHVkSampler&& rhs) noexcept
|
||||||
|
: vkSampler { rhs.vkSampler }
|
||||||
|
{
|
||||||
|
rhs.vkSampler = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
SHVkSampler::~SHVkSampler() noexcept
|
||||||
|
{
|
||||||
|
if (vkSampler)
|
||||||
|
device->GetVkLogicalDevice().destroySampler();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
/* Overloaded Operators */
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
SHADE::SHVkSampler& SHVkSampler::operator=(SHVkSampler&& rhs) noexcept
|
||||||
|
{
|
||||||
|
vkSampler = rhs.vkSampler;
|
||||||
|
rhs.vkSampler = nullptr;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -1,28 +1,80 @@
|
||||||
|
/************************************************************************************//*!
|
||||||
|
\file SHVkSampler.h
|
||||||
|
\author Tng Kah Wei, kahwei.tng, 390009620
|
||||||
|
\par email: kahwei.tng\@digipen.edu
|
||||||
|
\date Sep 26, 2022
|
||||||
|
\brief Contains definitions of the SHVkSampler class.
|
||||||
|
|
||||||
|
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
|
#pragma once
|
||||||
|
|
||||||
|
// STL Includes
|
||||||
|
#include <vector>
|
||||||
|
// Project Includes
|
||||||
#include "Graphics/SHVulkanIncludes.h"
|
#include "Graphics/SHVulkanIncludes.h"
|
||||||
|
#include "Resource/Handle.h"
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
/* Forward Declarations */
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
class SHVkLogicalDevice;
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
/* Type Definitions */
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
/*************************************************************************************/
|
||||||
|
/*!
|
||||||
|
\brief
|
||||||
|
Holds parameters for constructing the SHVkSampler.
|
||||||
|
*/
|
||||||
|
/*************************************************************************************/
|
||||||
struct SHVkSamplerParams
|
struct SHVkSamplerParams
|
||||||
{
|
{
|
||||||
vk::Filter minFilter;
|
vk::Filter minFilter = vk::Filter::eLinear;
|
||||||
vk::Filter maxFilter;
|
vk::Filter magFilter = vk::Filter::eLinear;
|
||||||
//vk::Filter maxFilter;
|
vk::SamplerAddressMode addressMode = vk::SamplerAddressMode::eClampToEdge;
|
||||||
|
vk::SamplerMipmapMode mipmapMode = vk::SamplerMipmapMode::eLinear;
|
||||||
|
float minLod = 0;
|
||||||
|
float maxLod = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*************************************************************************************/
|
||||||
|
/*!
|
||||||
|
\brief
|
||||||
|
Wrapper for a VkSampler.
|
||||||
|
*/
|
||||||
|
/*************************************************************************************/
|
||||||
class SHVkSampler
|
class SHVkSampler
|
||||||
{
|
{
|
||||||
private:
|
public:
|
||||||
//! The vulkan sampler handler
|
/*---------------------------------------------------------------------------------*/
|
||||||
vk::Sampler vkSampler;
|
/* Constructors */
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
public:
|
SHVkSampler(Handle<SHVkLogicalDevice> logicalDevice, const SHVkSamplerParams& params = {}) noexcept;
|
||||||
SHVkSampler () noexcept;
|
SHVkSampler(SHVkSampler&& rhs) noexcept;
|
||||||
SHVkSampler (SHVkSampler&& rhs) noexcept;
|
~SHVkSampler() noexcept;
|
||||||
SHVkSampler&& operator=(SHVkSampler&& rhs) noexcept;
|
|
||||||
|
|
||||||
vk::Sampler GetVkSampler (void) const noexcept;
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
/* Overloaded Operators */
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
SHVkSampler& operator=(SHVkSampler&& rhs) noexcept;
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
/* Getter Functions */
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
vk::Sampler GetVkSampler(void) const noexcept { return vkSampler; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
/* Data Members */
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
vk::Sampler vkSampler; //! The Vulkan sampler handler
|
||||||
|
Handle<SHVkLogicalDevice> device; //! Stored device for deallocating the object
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -22,8 +22,11 @@ of DigiPen Institute of Technology is prohibited.
|
||||||
#include "Graphics/Pipeline/SHVkPipeline.h"
|
#include "Graphics/Pipeline/SHVkPipeline.h"
|
||||||
#include "Graphics/MiddleEnd/Interface/SHGraphicsConstants.h"
|
#include "Graphics/MiddleEnd/Interface/SHGraphicsConstants.h"
|
||||||
#include "Graphics/MiddleEnd/Interface/SHMaterialInstance.h"
|
#include "Graphics/MiddleEnd/Interface/SHMaterialInstance.h"
|
||||||
|
#include "Graphics/Descriptors/SHVkDescriptorSetGroup.h"
|
||||||
#include "ECS_Base/Managers/SHComponentManager.h"
|
#include "ECS_Base/Managers/SHComponentManager.h"
|
||||||
#include "Math/Transform/SHTransformComponent.h"
|
#include "Math/Transform/SHTransformComponent.h"
|
||||||
|
#include "Graphics/MiddleEnd/GlobalData/SHGraphicsGlobalData.h"
|
||||||
|
#include "Graphics/Descriptors/SHVkDescriptorPool.h"
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
|
@ -120,7 +123,7 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHBatch::UpdateMaterialBuffer(uint32_t frameIndex)
|
void SHBatch::UpdateMaterialBuffer(uint32_t frameIndex, Handle<SHVkDescriptorPool> descPool)
|
||||||
{
|
{
|
||||||
if (frameIndex >= SHGraphicsConstants::NUM_FRAME_BUFFERS)
|
if (frameIndex >= SHGraphicsConstants::NUM_FRAME_BUFFERS)
|
||||||
{
|
{
|
||||||
|
@ -154,21 +157,17 @@ namespace SHADE
|
||||||
if (!matBufferDirty[frameIndex])
|
if (!matBufferDirty[frameIndex])
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Build CPI Buffer
|
// Build CPU Buffer
|
||||||
char* propsCurrPtr = matPropsData.get();
|
char* propsCurrPtr = matPropsData.get();
|
||||||
for (auto& subBatch : subBatches)
|
for (auto& subBatch : subBatches)
|
||||||
for (const SHRenderable* renderable : subBatch.Renderables)
|
for (const SHRenderable* renderable : subBatch.Renderables)
|
||||||
{
|
{
|
||||||
renderable->GetMaterial()->ExportProperties(propsCurrPtr);
|
renderable->GetMaterial()->ExportProperties(propsCurrPtr);
|
||||||
propsCurrPtr += singleMatPropSize;
|
propsCurrPtr += singleMatPropAlignedSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Transfer to GPU
|
// Transfer to GPU
|
||||||
SHVkUtil::EnsureBufferAndCopyHostVisibleData
|
rebuildMaterialBuffers(frameIndex, descPool);
|
||||||
(
|
|
||||||
device, matPropsBuffer[frameIndex], matPropsData.get(), static_cast<uint32_t>(matPropsDataSize),
|
|
||||||
vk::BufferUsageFlagBits::eStorageBuffer
|
|
||||||
);
|
|
||||||
|
|
||||||
// This frame is updated
|
// This frame is updated
|
||||||
matBufferDirty[frameIndex] = false;
|
matBufferDirty[frameIndex] = false;
|
||||||
|
@ -207,7 +206,7 @@ namespace SHADE
|
||||||
transformDataBuffer[frameIndex]->WriteToMemory(transformData.data(), static_cast<uint32_t>(transformData.size() * sizeof(SHMatrix)), 0, 0);
|
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, Handle<SHVkDescriptorPool> descPool, uint32_t frameIndex)
|
||||||
{
|
{
|
||||||
if (frameIndex >= SHGraphicsConstants::NUM_FRAME_BUFFERS)
|
if (frameIndex >= SHGraphicsConstants::NUM_FRAME_BUFFERS)
|
||||||
{
|
{
|
||||||
|
@ -215,6 +214,9 @@ namespace SHADE
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Save logical device
|
||||||
|
device = _device;
|
||||||
|
|
||||||
// No need to build as there are no changes
|
// No need to build as there are no changes
|
||||||
if (!isDirty[frameIndex])
|
if (!isDirty[frameIndex])
|
||||||
return;
|
return;
|
||||||
|
@ -247,7 +249,8 @@ namespace SHADE
|
||||||
if (!EMPTY_MAT_PROPS)
|
if (!EMPTY_MAT_PROPS)
|
||||||
{
|
{
|
||||||
singleMatPropSize = SHADER_INFO->GetBytesRequired();
|
singleMatPropSize = SHADER_INFO->GetBytesRequired();
|
||||||
matPropTotalBytes = drawData.size() * singleMatPropSize;
|
singleMatPropAlignedSize = device->PadSSBOSize(singleMatPropSize);
|
||||||
|
matPropTotalBytes = numTotalElements * singleMatPropAlignedSize;
|
||||||
if (matPropsDataSize < matPropTotalBytes)
|
if (matPropsDataSize < matPropTotalBytes)
|
||||||
{
|
{
|
||||||
matPropsData.reset(new char[matPropTotalBytes]);
|
matPropsData.reset(new char[matPropTotalBytes]);
|
||||||
|
@ -267,7 +270,7 @@ namespace SHADE
|
||||||
.instanceCount = static_cast<uint32_t>(subBatch.Renderables.size()),
|
.instanceCount = static_cast<uint32_t>(subBatch.Renderables.size()),
|
||||||
.firstIndex = subBatch.Mesh->FirstIndex,
|
.firstIndex = subBatch.Mesh->FirstIndex,
|
||||||
.vertexOffset = subBatch.Mesh->FirstVertex,
|
.vertexOffset = subBatch.Mesh->FirstVertex,
|
||||||
.firstInstance = nextInstanceIndex
|
.firstInstance = nextInstanceIndex++
|
||||||
});
|
});
|
||||||
|
|
||||||
// Fill in buffers (CPU)
|
// Fill in buffers (CPU)
|
||||||
|
@ -289,7 +292,7 @@ namespace SHADE
|
||||||
if (!EMPTY_MAT_PROPS)
|
if (!EMPTY_MAT_PROPS)
|
||||||
{
|
{
|
||||||
renderable->GetMaterial()->ExportProperties(propsCurrPtr);
|
renderable->GetMaterial()->ExportProperties(propsCurrPtr);
|
||||||
propsCurrPtr += singleMatPropSize;
|
propsCurrPtr += singleMatPropAlignedSize;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -304,30 +307,21 @@ 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
|
||||||
if (matPropsData)
|
rebuildMaterialBuffers(frameIndex, descPool);
|
||||||
{
|
|
||||||
SHVkUtil::EnsureBufferAndCopyHostVisibleData
|
|
||||||
(
|
|
||||||
_device, matPropsBuffer[frameIndex], matPropsData.get(), static_cast<uint32_t>(matPropsDataSize),
|
|
||||||
BuffUsage::eStorageBuffer
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
// Mark this frame as no longer dirty
|
||||||
isDirty[frameIndex] = false;
|
isDirty[frameIndex] = false;
|
||||||
|
|
||||||
// Save logical device
|
|
||||||
this->device = _device;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
@ -341,8 +335,20 @@ namespace SHADE
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Bind all required objects before drawing
|
||||||
|
static std::array<uint32_t, 1> dynamicOffset { 0 };
|
||||||
cmdBuffer->BindPipeline(pipeline);
|
cmdBuffer->BindPipeline(pipeline);
|
||||||
cmdBuffer->BindVertexBuffer(SHGraphicsConstants::VertexBufferBindings::TRANSFORM, transformDataBuffer[frameIndex], 0);
|
cmdBuffer->BindVertexBuffer(SHGraphicsConstants::VertexBufferBindings::TRANSFORM, transformDataBuffer[frameIndex], 0);
|
||||||
|
if (matPropsDescSet[frameIndex])
|
||||||
|
{
|
||||||
|
cmdBuffer->BindDescriptorSet
|
||||||
|
(
|
||||||
|
matPropsDescSet[frameIndex],
|
||||||
|
vk::PipelineBindPoint::eGraphics,
|
||||||
|
SHGraphicsConstants::DescriptorSetIndex::PER_INSTANCE,
|
||||||
|
dynamicOffset
|
||||||
|
);
|
||||||
|
}
|
||||||
cmdBuffer->DrawMultiIndirect(drawDataBuffer[frameIndex], static_cast<uint32_t>(drawData.size()));
|
cmdBuffer->DrawMultiIndirect(drawDataBuffer[frameIndex], static_cast<uint32_t>(drawData.size()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -355,4 +361,39 @@ namespace SHADE
|
||||||
dirt = true;
|
dirt = true;
|
||||||
isCPUBuffersDirty = true;
|
isCPUBuffersDirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SHBatch::rebuildMaterialBuffers(uint32_t frameIndex, Handle<SHVkDescriptorPool> descPool)
|
||||||
|
{
|
||||||
|
if (matPropsData)
|
||||||
|
{
|
||||||
|
SHVkUtil::EnsureBufferAndCopyHostVisibleData
|
||||||
|
(
|
||||||
|
device, matPropsBuffer[frameIndex], matPropsData.get(), static_cast<uint32_t>(matPropsDataSize),
|
||||||
|
vk::BufferUsageFlagBits::eStorageBuffer
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!matPropsDescSet[frameIndex])
|
||||||
|
{
|
||||||
|
matPropsDescSet[frameIndex] = descPool->Allocate
|
||||||
|
(
|
||||||
|
{ SHGraphicsGlobalData::GetDescSetLayouts()[SHGraphicsConstants::DescriptorSetIndex::PER_INSTANCE] },
|
||||||
|
{ 0 }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
std::array<Handle<SHVkBuffer>, 1> bufferList = { matPropsBuffer[frameIndex] };
|
||||||
|
matPropsDescSet[frameIndex]->ModifyWriteDescBuffer
|
||||||
|
(
|
||||||
|
SHGraphicsConstants::DescriptorSetIndex::PER_INSTANCE,
|
||||||
|
SHGraphicsConstants::DescriptorSetBindings::BATCHED_PER_INST_DATA,
|
||||||
|
bufferList,
|
||||||
|
0, matPropsDataSize
|
||||||
|
);
|
||||||
|
matPropsDescSet[frameIndex]->UpdateDescriptorSetBuffer
|
||||||
|
(
|
||||||
|
SHGraphicsConstants::DescriptorSetIndex::PER_INSTANCE,
|
||||||
|
SHGraphicsConstants::DescriptorSetBindings::BATCHED_PER_INST_DATA
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,6 +35,8 @@ namespace SHADE
|
||||||
class SHRenderable;
|
class SHRenderable;
|
||||||
class SHVkLogicalDevice;
|
class SHVkLogicalDevice;
|
||||||
class SHMaterialInstance;
|
class SHMaterialInstance;
|
||||||
|
class SHVkDescriptorSetGroup;
|
||||||
|
class SHVkDescriptorPool;
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
/* Type Definitions */
|
/* Type Definitions */
|
||||||
|
@ -74,9 +76,9 @@ 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 UpdateMaterialBuffer(uint32_t frameIndex, Handle<SHVkDescriptorPool> descPool);
|
||||||
void UpdateTransformBuffer(uint32_t frameIndex);
|
void UpdateTransformBuffer(uint32_t frameIndex);
|
||||||
void Build(Handle<SHVkLogicalDevice> device, uint32_t frameIndex);
|
void Build(Handle<SHVkLogicalDevice> device, Handle<SHVkDescriptorPool> descPool, uint32_t frameIndex) ;
|
||||||
void Draw(Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex);
|
void Draw(Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex);
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------*/
|
||||||
|
@ -84,34 +86,44 @@ namespace SHADE
|
||||||
/*-----------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------*/
|
||||||
Handle<SHVkPipeline> GetPipeline() const noexcept { return pipeline; };
|
Handle<SHVkPipeline> GetPipeline() const noexcept { return pipeline; };
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
/*-----------------------------------------------------------------------------*/
|
||||||
|
/* Type Definition */
|
||||||
|
/*-----------------------------------------------------------------------------*/
|
||||||
|
using TripleBool = std::array<bool, SHGraphicsConstants::NUM_FRAME_BUFFERS>;
|
||||||
|
using TripleBuffer = std::array<Handle<SHVkBuffer>, SHGraphicsConstants::NUM_FRAME_BUFFERS>;
|
||||||
|
using TripleDescSet = std::array<Handle<SHVkDescriptorSetGroup>, SHGraphicsConstants::NUM_FRAME_BUFFERS>;
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------*/
|
||||||
/* Data Members */
|
/* Data Members */
|
||||||
/*-----------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------*/
|
||||||
// Resources
|
// Resources
|
||||||
Handle<SHVkLogicalDevice> device;
|
Handle<SHVkLogicalDevice> device;
|
||||||
// Batch Properties
|
// Batch Properties
|
||||||
Handle<SHVkPipeline> pipeline;
|
Handle<SHVkPipeline> pipeline;
|
||||||
std::unordered_set<Handle<SHMaterialInstance>> referencedMatInstances;
|
std::unordered_set<Handle<SHMaterialInstance>> referencedMatInstances;
|
||||||
std::array<bool, SHGraphicsConstants::NUM_FRAME_BUFFERS> matBufferDirty;
|
TripleBool matBufferDirty;
|
||||||
// Batch Tree
|
// Batch Tree
|
||||||
std::vector<SHSubBatch> subBatches;
|
std::vector<SHSubBatch> subBatches;
|
||||||
std::array<bool, SHGraphicsConstants::NUM_FRAME_BUFFERS> isDirty;
|
TripleBool isDirty;
|
||||||
// CPU Buffers
|
// CPU Buffers
|
||||||
std::vector<vk::DrawIndexedIndirectCommand> drawData;
|
std::vector<vk::DrawIndexedIndirectCommand> drawData;
|
||||||
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;
|
Byte singleMatPropAlignedSize = 0;
|
||||||
bool isCPUBuffersDirty = true;
|
Byte singleMatPropSize = 0;
|
||||||
// GPU Buffers
|
bool isCPUBuffersDirty = true;
|
||||||
std::array<Handle<SHVkBuffer>, SHGraphicsConstants::NUM_FRAME_BUFFERS> drawDataBuffer;
|
// GPU Buffers
|
||||||
std::array<Handle<SHVkBuffer>, SHGraphicsConstants::NUM_FRAME_BUFFERS> transformDataBuffer;
|
TripleBuffer drawDataBuffer;
|
||||||
std::array<Handle<SHVkBuffer>, SHGraphicsConstants::NUM_FRAME_BUFFERS> matPropsBuffer;
|
TripleBuffer transformDataBuffer;
|
||||||
|
TripleBuffer matPropsBuffer;
|
||||||
|
TripleDescSet matPropsDescSet;
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------*/
|
||||||
/* Helper Functions */
|
/* Helper Functions */
|
||||||
/*-----------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------*/
|
||||||
void setAllDirtyFlags();
|
void setAllDirtyFlags();
|
||||||
|
void rebuildMaterialBuffers(uint32_t frameIndex, Handle<SHVkDescriptorPool> descPool);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -91,12 +91,12 @@ namespace SHADE
|
||||||
(*superBatch)->Remove(renderable);
|
(*superBatch)->Remove(renderable);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHBatcher::FinaliseBatches(Handle<SHVkLogicalDevice> device, uint32_t frameIndex)
|
void SHBatcher::FinaliseBatches(Handle<SHVkLogicalDevice> device, Handle<SHVkDescriptorPool> descPool, uint32_t frameIndex)
|
||||||
{
|
{
|
||||||
// Build SuperBatches
|
// Build SuperBatches
|
||||||
for (auto& batch : superBatches)
|
for (auto& batch : superBatches)
|
||||||
{
|
{
|
||||||
batch->Build(device, frameIndex);
|
batch->Build(device, descPool, frameIndex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -109,11 +109,11 @@ namespace SHADE
|
||||||
superBatches.clear();
|
superBatches.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHBatcher::UpdateBuffers(uint32_t frameIndex)
|
void SHBatcher::UpdateBuffers(uint32_t frameIndex, Handle<SHVkDescriptorPool> descPool)
|
||||||
{
|
{
|
||||||
for (auto& batch : superBatches)
|
for (auto& batch : superBatches)
|
||||||
{
|
{
|
||||||
batch->UpdateBuffers(frameIndex);
|
batch->UpdateBuffers(frameIndex, descPool);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -27,6 +27,7 @@ namespace SHADE
|
||||||
class SHSuperBatch;
|
class SHSuperBatch;
|
||||||
class SHVkLogicalDevice;
|
class SHVkLogicalDevice;
|
||||||
class SHVkCommandBuffer;
|
class SHVkCommandBuffer;
|
||||||
|
class SHVkDescriptorPool;
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
/* Type Definitions */
|
/* Type Definitions */
|
||||||
|
@ -51,9 +52,9 @@ namespace SHADE
|
||||||
void PrepareBatches();
|
void PrepareBatches();
|
||||||
void AddToBatch(SHRenderable const* renderable);
|
void AddToBatch(SHRenderable const* renderable);
|
||||||
void RemoveFromBatch(SHRenderable const* renderable);
|
void RemoveFromBatch(SHRenderable const* renderable);
|
||||||
void FinaliseBatches(Handle<SHVkLogicalDevice> device, uint32_t frameIndex);
|
void FinaliseBatches(Handle<SHVkLogicalDevice> device, Handle<SHVkDescriptorPool> descPool, uint32_t frameIndex);
|
||||||
void ClearBatches();
|
void ClearBatches();
|
||||||
void UpdateBuffers(uint32_t frameIndex);
|
void UpdateBuffers(uint32_t frameIndex, Handle<SHVkDescriptorPool> descPool);
|
||||||
void RegisterSuperBatch(Handle<SHSuperBatch> superBatch);
|
void RegisterSuperBatch(Handle<SHSuperBatch> superBatch);
|
||||||
void DeregisterSuperBatch(Handle<SHSuperBatch> superBatch);
|
void DeregisterSuperBatch(Handle<SHSuperBatch> superBatch);
|
||||||
|
|
||||||
|
|
|
@ -16,6 +16,7 @@ of DigiPen Institute of Technology is prohibited.
|
||||||
#include "SHBatch.h"
|
#include "SHBatch.h"
|
||||||
#include "Graphics/MiddleEnd/Interface/SHMaterialInstance.h"
|
#include "Graphics/MiddleEnd/Interface/SHMaterialInstance.h"
|
||||||
#include "Graphics/MiddleEnd/Interface/SHRenderable.h"
|
#include "Graphics/MiddleEnd/Interface/SHRenderable.h"
|
||||||
|
#include "Graphics/Descriptors/SHVkDescriptorPool.h"
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
|
@ -78,21 +79,21 @@ namespace SHADE
|
||||||
batches.clear();
|
batches.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHSuperBatch::UpdateBuffers(uint32_t frameIndex)
|
void SHSuperBatch::UpdateBuffers(uint32_t frameIndex, Handle<SHVkDescriptorPool> descPool)
|
||||||
{
|
{
|
||||||
for (auto& batch : batches)
|
for (auto& batch : batches)
|
||||||
{
|
{
|
||||||
batch.UpdateMaterialBuffer(frameIndex);
|
batch.UpdateMaterialBuffer(frameIndex, descPool);
|
||||||
batch.UpdateTransformBuffer(frameIndex);
|
batch.UpdateTransformBuffer(frameIndex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHSuperBatch::Build(Handle<SHVkLogicalDevice> device, uint32_t frameIndex) noexcept
|
void SHSuperBatch::Build(Handle<SHVkLogicalDevice> device, Handle<SHVkDescriptorPool> descPool, uint32_t frameIndex) noexcept
|
||||||
{
|
{
|
||||||
// Build all batches
|
// Build all batches
|
||||||
for (auto& batch : batches)
|
for (auto& batch : batches)
|
||||||
{
|
{
|
||||||
batch.Build(device, frameIndex);
|
batch.Build(device, descPool, frameIndex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -55,8 +55,8 @@ 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 UpdateBuffers(uint32_t frameIndex);
|
void UpdateBuffers(uint32_t frameIndex, Handle<SHVkDescriptorPool> descPool);
|
||||||
void Build(Handle<SHVkLogicalDevice> device, uint32_t frameIndex) noexcept;
|
void Build(Handle<SHVkLogicalDevice> device, Handle<SHVkDescriptorPool> descPool, uint32_t frameIndex) noexcept;
|
||||||
void Draw(Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex) noexcept;
|
void Draw(Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex) noexcept;
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------*/
|
||||||
|
|
|
@ -7,7 +7,22 @@
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
/* Static Definitions */
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
std::vector<Handle<SHVkDescriptorSetLayout>> SHGraphicsGlobalData::globalDescSetLayouts;
|
||||||
|
Handle<SHVkDescriptorSetGroup> SHGraphicsGlobalData::globalDescSets;
|
||||||
|
SHVertexInputState SHGraphicsGlobalData::defaultVertexInputState;
|
||||||
|
Handle<SHVkPipelineLayout> SHGraphicsGlobalData::dummyPipelineLayout;
|
||||||
|
|
||||||
|
void SHGraphicsGlobalData::InitHighFrequencyGlobalData(void) noexcept
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
/* Function Definitions */
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
void SHGraphicsGlobalData::InitDescSetLayouts(Handle<SHVkLogicalDevice> logicalDevice) noexcept
|
void SHGraphicsGlobalData::InitDescSetLayouts(Handle<SHVkLogicalDevice> logicalDevice) noexcept
|
||||||
{
|
{
|
||||||
SHVkDescriptorSetLayout::Binding genericDataBinding
|
SHVkDescriptorSetLayout::Binding genericDataBinding
|
||||||
|
@ -87,18 +102,18 @@ namespace SHADE
|
||||||
InitDefaultVertexInputState();
|
InitDefaultVertexInputState();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<Handle<SHVkDescriptorSetLayout>> const& SHGraphicsGlobalData::GetDescSetLayouts(void) const noexcept
|
std::vector<Handle<SHVkDescriptorSetLayout>> const& SHGraphicsGlobalData::GetDescSetLayouts(void) noexcept
|
||||||
{
|
{
|
||||||
return globalDescSetLayouts;
|
return globalDescSetLayouts;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
SHVertexInputState const& SHGraphicsGlobalData::GetDefaultViState(void) const noexcept
|
SHVertexInputState const& SHGraphicsGlobalData::GetDefaultViState(void) noexcept
|
||||||
{
|
{
|
||||||
return defaultVertexInputState;
|
return defaultVertexInputState;
|
||||||
}
|
}
|
||||||
|
|
||||||
Handle<SHVkPipelineLayout> SHGraphicsGlobalData::GetDummyPipelineLayout(void) const noexcept
|
Handle<SHVkPipelineLayout> SHGraphicsGlobalData::GetDummyPipelineLayout(void) noexcept
|
||||||
{
|
{
|
||||||
return dummyPipelineLayout;
|
return dummyPipelineLayout;
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,31 +15,38 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
//! Global descriptor set layouts. Used to allocate descriptor sets
|
//! Global descriptor set layouts. Used to allocate descriptor sets
|
||||||
std::vector<Handle<SHVkDescriptorSetLayout>> globalDescSetLayouts;
|
static std::vector<Handle<SHVkDescriptorSetLayout>> globalDescSetLayouts;
|
||||||
|
|
||||||
//! Global Descriptor sets
|
//! Global Descriptor sets
|
||||||
Handle<SHVkDescriptorSetGroup> globalDescSets;
|
static Handle<SHVkDescriptorSetGroup> globalDescSets;
|
||||||
|
|
||||||
//! Default vertex input state (used by everything).
|
//! Default vertex input state (used by everything).
|
||||||
SHVertexInputState defaultVertexInputState;
|
static SHVertexInputState defaultVertexInputState;
|
||||||
|
|
||||||
//! Since we want to bind global data but can't do so without a pipeline layout,
|
//! Since we want to bind global data but can't do so without a pipeline layout,
|
||||||
//! we create a dummy pipeline layout to use it for binding.
|
//! we create a dummy pipeline layout to use it for binding.
|
||||||
Handle<SHVkPipelineLayout> dummyPipelineLayout;
|
static Handle<SHVkPipelineLayout> dummyPipelineLayout;
|
||||||
|
|
||||||
|
static void InitHighFrequencyGlobalData (void) noexcept;
|
||||||
|
static void InitDescSetLayouts (Handle<SHVkLogicalDevice> logicalDevice) noexcept;
|
||||||
|
static void InitDefaultVertexInputState (void) noexcept;
|
||||||
|
|
||||||
void InitDescSetLayouts (Handle<SHVkLogicalDevice> logicalDevice) noexcept;
|
|
||||||
void InitDefaultVertexInputState(void) noexcept;
|
|
||||||
public:
|
public:
|
||||||
|
/*-----------------------------------------------------------------------*/
|
||||||
|
/* Constructors */
|
||||||
|
/*-----------------------------------------------------------------------*/
|
||||||
|
SHGraphicsGlobalData() = delete;
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
/* PUBLIC MEMBER FUNCTIONS */
|
/* PUBLIC MEMBER FUNCTIONS */
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
void Init (Handle<SHVkLogicalDevice> logicalDevice) noexcept;
|
static void Init (Handle<SHVkLogicalDevice> logicalDevice) noexcept;
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
/* SETTERS AND GETTERS */
|
/* SETTERS AND GETTERS */
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
std::vector<Handle<SHVkDescriptorSetLayout>> const& GetDescSetLayouts (void) const noexcept;
|
static std::vector<Handle<SHVkDescriptorSetLayout>> const& GetDescSetLayouts (void) noexcept;
|
||||||
SHVertexInputState const& GetDefaultViState (void) const noexcept;
|
static SHVertexInputState const& GetDefaultViState (void) noexcept;
|
||||||
Handle<SHVkPipelineLayout> GetDummyPipelineLayout (void) const noexcept;
|
static Handle<SHVkPipelineLayout> GetDummyPipelineLayout (void) noexcept;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,22 +23,40 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
SHVec3 view = target - pos; view = SHVec3::Normalise(view);
|
SHVec3 view = target - pos; view = SHVec3::Normalise(view);
|
||||||
SHVec3 right = SHVec3::Cross(view, up); right = SHVec3::Normalise(right);
|
SHVec3 right = SHVec3::Cross(view, up); right = SHVec3::Normalise(right);
|
||||||
const SHVec3 UP = SHVec3::Cross(right, view);
|
const SHVec3 UP = SHVec3::Cross(view, right);
|
||||||
|
|
||||||
|
//viewMatrix = SHMatrix::Identity;
|
||||||
|
//viewMatrix(0, 0) = UP[0];
|
||||||
|
//viewMatrix(1, 0) = UP[1];
|
||||||
|
//viewMatrix(2, 0) = UP[2];
|
||||||
|
//viewMatrix(0, 1) = right[0];
|
||||||
|
//viewMatrix(1, 1) = right[1];
|
||||||
|
//viewMatrix(2, 1) = right[2];
|
||||||
|
//viewMatrix(0, 2) = view[0];
|
||||||
|
//viewMatrix(1, 2) = view[1];
|
||||||
|
//viewMatrix(2, 2) = view[2];
|
||||||
|
//viewMatrix(3, 0) = -UP.Dot(pos);
|
||||||
|
//viewMatrix(3, 1) = -right.Dot(pos);
|
||||||
|
//viewMatrix(3, 2) = -view.Dot(pos);
|
||||||
|
|
||||||
viewMatrix = SHMatrix::Identity;
|
viewMatrix = SHMatrix::Identity;
|
||||||
viewMatrix(0, 0) = UP[0];
|
viewMatrix(0, 0) = right[0];
|
||||||
viewMatrix(1, 0) = UP[1];
|
viewMatrix(0, 1) = right[1];
|
||||||
viewMatrix(2, 0) = UP[2];
|
viewMatrix(0, 2) = right[2];
|
||||||
viewMatrix(0, 1) = right[0];
|
|
||||||
viewMatrix(1, 1) = right[1];
|
viewMatrix(1, 0) = UP[0];
|
||||||
viewMatrix(2, 1) = right[2];
|
viewMatrix(1, 1) = UP[1];
|
||||||
viewMatrix(0, 2) = view[0];
|
viewMatrix(1, 2) = UP[2];
|
||||||
viewMatrix(1, 2) = view[1];
|
|
||||||
viewMatrix(2, 2) = view[2];
|
viewMatrix(2, 0) = view[0];
|
||||||
viewMatrix(3, 0) = -UP.Dot(pos);
|
viewMatrix(2, 1) = view[1];
|
||||||
viewMatrix(3, 1) = -right.Dot(pos);
|
viewMatrix(2, 2) = view[2];
|
||||||
viewMatrix(3, 2) = -view.Dot(pos);
|
|
||||||
|
viewMatrix(0, 3) = -right.Dot(pos);
|
||||||
|
viewMatrix(1, 3) = -UP.Dot(pos);
|
||||||
|
viewMatrix(2, 3) = -view.Dot(pos);
|
||||||
|
|
||||||
|
|
||||||
isDirty = true;
|
isDirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -30,6 +30,8 @@ of DigiPen Institute of Technology is prohibited.
|
||||||
#include "SHGraphicsConstants.h"
|
#include "SHGraphicsConstants.h"
|
||||||
#include "Graphics/MiddleEnd/GlobalData/SHGraphicsGlobalData.h"
|
#include "Graphics/MiddleEnd/GlobalData/SHGraphicsGlobalData.h"
|
||||||
#include "Graphics/Buffers/SHVkBuffer.h"
|
#include "Graphics/Buffers/SHVkBuffer.h"
|
||||||
|
#include "Graphics/Images/SHVkSampler.h"
|
||||||
|
#include "Assets/Asset Types/SHTextureAsset.h"
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
|
@ -91,8 +93,10 @@ namespace SHADE
|
||||||
descPool = device->CreateDescriptorPools();
|
descPool = device->CreateDescriptorPools();
|
||||||
|
|
||||||
// Create generic command buffer
|
// Create generic command buffer
|
||||||
transferCmdPool = device->CreateCommandPool(SH_QUEUE_FAMILY_ARRAY_INDEX::TRANSFER, SH_CMD_POOL_RESET::POOL_BASED, true);
|
//transferCmdPool = device->CreateCommandPool(SH_QUEUE_FAMILY_ARRAY_INDEX::GRAPHICS, SH_CMD_POOL_RESET::POOL_BASED, true);
|
||||||
transferCmdBuffer = transferCmdPool->RequestCommandBuffer(SH_CMD_BUFFER_TYPE::PRIMARY);
|
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);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -106,8 +110,7 @@ namespace SHADE
|
||||||
- Global data
|
- Global data
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
|
|
||||||
globalData = resourceManager.Create<SHGraphicsGlobalData>();
|
SHGraphicsGlobalData::Init(device);
|
||||||
globalData->Init(device);
|
|
||||||
|
|
||||||
// Set Up Cameras
|
// Set Up Cameras
|
||||||
screenCamera = resourceManager.Create<SHCamera>();
|
screenCamera = resourceManager.Create<SHCamera>();
|
||||||
|
@ -115,7 +118,7 @@ namespace SHADE
|
||||||
screenCamera->SetOrthographic(static_cast<float>(windowDims.first), static_cast<float>(windowDims.second), 0.01f, 100.0f);
|
screenCamera->SetOrthographic(static_cast<float>(windowDims.first), static_cast<float>(windowDims.second), 0.01f, 100.0f);
|
||||||
worldCamera = resourceManager.Create<SHCamera>();
|
worldCamera = resourceManager.Create<SHCamera>();
|
||||||
//worldCamera->SetLookAt(SHVec3(1.0f, 0.0f, -1.0f), SHVec3(0.0f, 0.0f, 2.0f), SHVec3(0.0f, 1.0f, 0.0f));
|
//worldCamera->SetLookAt(SHVec3(1.0f, 0.0f, -1.0f), SHVec3(0.0f, 0.0f, 2.0f), SHVec3(0.0f, 1.0f, 0.0f));
|
||||||
worldCamera->SetLookAt(SHVec3(0.0f, 5.0f, -1.0f), SHVec3(0.0f, 0.0f, 2.0f), SHVec3(0.0f, 1.0f, 0.0f));
|
worldCamera->SetLookAt(SHVec3(0.0f, 0.0f, 0.0f), SHVec3(0.0f, 0.0f, -2.0f), SHVec3(0.0f, 1.0f, 0.0f));
|
||||||
worldCamera->SetPerspective(90.0f, static_cast<float>(windowDims.first), static_cast<float>(windowDims.second), 0.0f, 100.0f);
|
worldCamera->SetPerspective(90.0f, static_cast<float>(windowDims.first), static_cast<float>(windowDims.second), 0.0f, 100.0f);
|
||||||
|
|
||||||
// Create Default Viewport
|
// Create Default Viewport
|
||||||
|
@ -131,18 +134,20 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize world render graph
|
// Initialize world render graph
|
||||||
worldRenderGraph->Init(device, swapchain, globalData);
|
worldRenderGraph->Init(device, swapchain);
|
||||||
|
worldRenderGraph->AddResource("Depth Buffer", SH_ATT_DESC_TYPE::DEPTH_STENCIL, windowDims.first, windowDims.second, vk::Format::eD32SfloatS8Uint);
|
||||||
//worldRenderGraph->AddResource("Position", SH_ATT_DESC_TYPE::COLOR, windowDims.first, windowDims.second, vk::Format::eR16G16B16A16Sfloat);
|
//worldRenderGraph->AddResource("Position", SH_ATT_DESC_TYPE::COLOR, windowDims.first, windowDims.second, vk::Format::eR16G16B16A16Sfloat);
|
||||||
//worldRenderGraph->AddResource("Normals", SH_ATT_DESC_TYPE::COLOR, windowDims.first, windowDims.second, vk::Format::eR16G16B16A16Sfloat);
|
//worldRenderGraph->AddResource("Normals", SH_ATT_DESC_TYPE::COLOR, windowDims.first, windowDims.second, vk::Format::eR16G16B16A16Sfloat);
|
||||||
//worldRenderGraph->AddResource("Composite", SH_ATT_DESC_TYPE::COLOR, windowDims.first, windowDims.second, vk::Format::eR16G16B16A16Sfloat);
|
//worldRenderGraph->AddResource("Composite", SH_ATT_DESC_TYPE::COLOR, windowDims.first, windowDims.second, vk::Format::eR16G16B16A16Sfloat);
|
||||||
worldRenderGraph->AddResource("Scene", SH_ATT_DESC_TYPE::COLOR, windowDims.first, windowDims.second, vk::Format::eB8G8R8A8Unorm);
|
//worldRenderGraph->AddResource("Scene", SH_ATT_DESC_TYPE::COLOR, windowDims.first, windowDims.second, vk::Format::eB8G8R8A8Unorm);
|
||||||
worldRenderGraph->AddResource("Present", SH_ATT_DESC_TYPE::COLOR_PRESENT, windowDims.first, windowDims.second);
|
worldRenderGraph->AddResource("Present", SH_ATT_DESC_TYPE::COLOR_PRESENT, windowDims.first, windowDims.second);
|
||||||
auto node = worldRenderGraph->AddNode("G-Buffer", { /*"Composite", "Position", */"Present" }, {}); // no predecessors
|
auto node = worldRenderGraph->AddNode("G-Buffer", { /*"Composite", "Position", */"Depth Buffer", "Present" }, {}); // no predecessors
|
||||||
|
|
||||||
//First subpass to write to G-Buffer
|
//First subpass to write to G-Buffer
|
||||||
auto gBufferWriteSubpass = node->AddSubpass("G-Buffer Write");
|
auto gBufferWriteSubpass = node->AddSubpass("G-Buffer Write");
|
||||||
//gBufferWriteSubpass->AddColorOutput("Scene");
|
//gBufferWriteSubpass->AddColorOutput("Scene");
|
||||||
gBufferWriteSubpass->AddColorOutput("Present");
|
gBufferWriteSubpass->AddColorOutput("Present");
|
||||||
|
gBufferWriteSubpass->AddDepthOutput ("Depth Buffer", SH_ATT_DESC_TYPE::DEPTH_STENCIL);
|
||||||
//writeSubpass->AddColorOutput("Normals");
|
//writeSubpass->AddColorOutput("Normals");
|
||||||
|
|
||||||
// //Second subpass to read from G-Buffer
|
// //Second subpass to read from G-Buffer
|
||||||
|
@ -171,7 +176,7 @@ namespace SHADE
|
||||||
debugWorldRenderer->SetCamera(worldCamera);*/
|
debugWorldRenderer->SetCamera(worldCamera);*/
|
||||||
|
|
||||||
// Add world renderer to default viewport
|
// Add world renderer to default viewport
|
||||||
worldRenderer = defaultViewport->AddRenderer(resourceManager, swapchain->GetNumImages(), renderContextCmdPools, descPool, globalData->GetDescSetLayouts()[SHGraphicsConstants::DescriptorSetIndex::HIGH_FREQUENCY_GLOBALS], worldRenderGraph);
|
worldRenderer = defaultViewport->AddRenderer(resourceManager, swapchain->GetNumImages(), renderContextCmdPools, descPool, SHGraphicsGlobalData::GetDescSetLayouts()[SHGraphicsConstants::DescriptorSetIndex::HIGH_FREQUENCY_GLOBALS], worldRenderGraph);
|
||||||
worldRenderer->SetCamera(worldCamera);
|
worldRenderer->SetCamera(worldCamera);
|
||||||
|
|
||||||
|
|
||||||
|
@ -184,8 +189,8 @@ namespace SHADE
|
||||||
shaderModuleLibrary.ImportFromSourceLibrary(device, shaderSourceLibrary);
|
shaderModuleLibrary.ImportFromSourceLibrary(device, shaderSourceLibrary);
|
||||||
auto cubeVS = shaderModuleLibrary.GetShaderModule("TestCubeVs.glsl");
|
auto cubeVS = shaderModuleLibrary.GetShaderModule("TestCubeVs.glsl");
|
||||||
auto cubeFS = shaderModuleLibrary.GetShaderModule("TestCubeFs.glsl");
|
auto cubeFS = shaderModuleLibrary.GetShaderModule("TestCubeFs.glsl");
|
||||||
//triVS->Reflect();
|
cubeVS->Reflect();
|
||||||
//triFS->Reflect();
|
cubeFS->Reflect();
|
||||||
|
|
||||||
defaultMaterial = AddMaterial(cubeVS, cubeFS, gBufferWriteSubpass);
|
defaultMaterial = AddMaterial(cubeVS, cubeFS, gBufferWriteSubpass);
|
||||||
}
|
}
|
||||||
|
@ -224,6 +229,9 @@ namespace SHADE
|
||||||
|
|
||||||
renderContext.ResetFence();
|
renderContext.ResetFence();
|
||||||
|
|
||||||
|
// Bind textures
|
||||||
|
|
||||||
|
|
||||||
// For every viewport
|
// For every viewport
|
||||||
for (int vpIndex = 0; vpIndex < static_cast<int>(viewports.size()); ++vpIndex)
|
for (int vpIndex = 0; vpIndex < static_cast<int>(viewports.size()); ++vpIndex)
|
||||||
{
|
{
|
||||||
|
@ -241,7 +249,7 @@ namespace SHADE
|
||||||
// Begin recording the command buffer
|
// Begin recording the command buffer
|
||||||
currentCmdBuffer->BeginRecording();
|
currentCmdBuffer->BeginRecording();
|
||||||
|
|
||||||
currentCmdBuffer->ForceSetPipelineLayout(globalData->GetDummyPipelineLayout());
|
currentCmdBuffer->ForceSetPipelineLayout(SHGraphicsGlobalData::GetDummyPipelineLayout());
|
||||||
|
|
||||||
// Bind all the buffers required for meshes
|
// Bind all the buffers required for meshes
|
||||||
for (auto& [buffer, bindingPoint] : MESH_DATA)
|
for (auto& [buffer, bindingPoint] : MESH_DATA)
|
||||||
|
@ -252,11 +260,26 @@ namespace SHADE
|
||||||
currentCmdBuffer->BindIndexBuffer(buffer, 0);
|
currentCmdBuffer->BindIndexBuffer(buffer, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Bind textures
|
||||||
|
auto textureDescSet = texLibrary.GetTextureDescriptorSetGroup();
|
||||||
|
if (textureDescSet)
|
||||||
|
{
|
||||||
|
std::array<uint32_t, 1> texDynamicOffset {0};
|
||||||
|
currentCmdBuffer->BindDescriptorSet
|
||||||
|
(
|
||||||
|
textureDescSet,
|
||||||
|
vk::PipelineBindPoint::eGraphics,
|
||||||
|
0,
|
||||||
|
texDynamicOffset
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
// bind camera data
|
// bind camera data
|
||||||
renderers[renIndex]->UpdateDataAndBind(currentCmdBuffer, frameIndex);
|
renderers[renIndex]->UpdateDataAndBind(currentCmdBuffer, frameIndex);
|
||||||
|
|
||||||
// Draw first
|
// Draw first
|
||||||
renderers[renIndex]->Draw(frameIndex);
|
renderers[renIndex]->Draw(frameIndex, descPool);
|
||||||
|
|
||||||
// End the command buffer recording
|
// End the command buffer recording
|
||||||
currentCmdBuffer->EndRecording();
|
currentCmdBuffer->EndRecording();
|
||||||
|
@ -309,7 +332,7 @@ namespace SHADE
|
||||||
for (auto vp : viewports)
|
for (auto vp : viewports)
|
||||||
for (auto renderer : vp->GetRenderers())
|
for (auto renderer : vp->GetRenderers())
|
||||||
{
|
{
|
||||||
renderer->GetRenderGraph()->FinaliseBatch(renderContext.GetCurrentFrame());
|
renderer->GetRenderGraph()->FinaliseBatch(renderContext.GetCurrentFrame(), descPool);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Resize
|
// Resize
|
||||||
|
@ -455,9 +478,37 @@ namespace SHADE
|
||||||
transferCmdBuffer->BeginRecording();
|
transferCmdBuffer->BeginRecording();
|
||||||
meshLibrary.BuildBuffers(device, transferCmdBuffer);
|
meshLibrary.BuildBuffers(device, transferCmdBuffer);
|
||||||
transferCmdBuffer->EndRecording();
|
transferCmdBuffer->EndRecording();
|
||||||
transferQueue->SubmitCommandBuffer({ transferCmdBuffer });
|
graphicsQueue->SubmitCommandBuffer({ transferCmdBuffer });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
/* Texture Registration Functions */
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
Handle<SHTexture> SHGraphicsSystem::Add(const SHTextureAsset& texAsset)
|
||||||
|
{
|
||||||
|
auto sampler = samplerCache.GetSampler(device, SHVkSamplerParams { .maxLod = static_cast<float>(texAsset.mipOffsets.size()) });
|
||||||
|
return texLibrary.Add(texAsset, sampler);
|
||||||
|
}
|
||||||
|
|
||||||
|
SHADE::Handle<SHADE::SHTexture> SHGraphicsSystem::Add(uint32_t pixelCount, const SHTexture::PixelChannel* const pixelData, uint32_t width, uint32_t height, SHTexture::TextureFormat format, std::vector<uint32_t> mipOffsets)
|
||||||
|
{
|
||||||
|
auto sampler = samplerCache.GetSampler(device, SHVkSamplerParams{ .maxLod = static_cast<float>(mipOffsets.size()) });
|
||||||
|
return texLibrary.Add(pixelCount, pixelData, width, height, format, mipOffsets, sampler);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHGraphicsSystem::Remove(Handle<SHTexture> tex)
|
||||||
|
{
|
||||||
|
texLibrary.Remove(tex);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHGraphicsSystem::BuildTextures()
|
||||||
|
{
|
||||||
|
texLibrary.BuildTextures
|
||||||
|
(
|
||||||
|
device, graphicsTexCmdBuffer, graphicsQueue, descPool
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
void SHGraphicsSystem::SetWindow(SHWindow* wind) noexcept
|
void SHGraphicsSystem::SetWindow(SHWindow* wind) noexcept
|
||||||
{
|
{
|
||||||
window = wind;
|
window = wind;
|
||||||
|
@ -493,9 +544,13 @@ namespace SHADE
|
||||||
oldSuperBatch->Remove(&renderable);
|
oldSuperBatch->Remove(&renderable);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add to new SuperBatch
|
// Add to new SuperBatch if there is a material
|
||||||
Handle<SHSuperBatch> newSuperBatch = renderable.GetMaterial()->GetBaseMaterial()->GetPipeline()->GetPipelineState().GetSubpass()->GetSuperBatch();
|
Handle<SHMaterialInstance> newMatInstance = renderable.GetMaterial();
|
||||||
newSuperBatch->Add(&renderable);
|
if (newMatInstance)
|
||||||
|
{
|
||||||
|
Handle<SHSuperBatch> newSuperBatch = newMatInstance->GetBaseMaterial()->GetPipeline()->GetPipelineState().GetSubpass()->GetSuperBatch();
|
||||||
|
newSuperBatch->Add(&renderable);
|
||||||
|
}
|
||||||
|
|
||||||
// Unset change flag
|
// Unset change flag
|
||||||
renderable.ResetChangedFlag();
|
renderable.ResetChangedFlag();
|
||||||
|
|
|
@ -29,6 +29,8 @@ of DigiPen Institute of Technology is prohibited.
|
||||||
#include "Graphics/MiddleEnd/Shaders/SHShaderModuleLibrary.h"
|
#include "Graphics/MiddleEnd/Shaders/SHShaderModuleLibrary.h"
|
||||||
#include "SHMeshLibrary.h"
|
#include "SHMeshLibrary.h"
|
||||||
#include "Graphics/MiddleEnd/Materials/SHMaterialInstanceCache.h"
|
#include "Graphics/MiddleEnd/Materials/SHMaterialInstanceCache.h"
|
||||||
|
#include "../Textures/SHTextureLibrary.h"
|
||||||
|
#include "../Textures/SHVkSamplerCache.h"
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
|
@ -188,6 +190,62 @@ namespace SHADE
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
void BuildMeshBuffers();
|
void BuildMeshBuffers();
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------------------*/
|
||||||
|
/* Texture Registration Functions */
|
||||||
|
/*-----------------------------------------------------------------------------*/
|
||||||
|
/*******************************************************************************/
|
||||||
|
/*!
|
||||||
|
|
||||||
|
\brief
|
||||||
|
Adds a texture to the Texture Library. But this does not mean that the
|
||||||
|
textures have been added yet. A call to "BuildTextures()" is required to
|
||||||
|
transfer all textures into the GPU.
|
||||||
|
|
||||||
|
\param pixelCount
|
||||||
|
Number of pixels in this Mesh.
|
||||||
|
\param positions
|
||||||
|
Pointer to the first in a contiguous array of SHMathVec3s that define vertex
|
||||||
|
positions.
|
||||||
|
\param format
|
||||||
|
Format of the texture loaded in.
|
||||||
|
|
||||||
|
\return
|
||||||
|
Handle to the created Texture. This is not valid to be used until a call to
|
||||||
|
BuildImages().
|
||||||
|
|
||||||
|
*/
|
||||||
|
/*******************************************************************************/
|
||||||
|
Handle<SHTexture> Add(const SHTextureAsset& texAsset);
|
||||||
|
Handle<SHTexture> Add(uint32_t pixelCount, const SHTexture::PixelChannel* const pixelData, uint32_t width, uint32_t height, SHTexture::TextureFormat format, std::vector<uint32_t> mipOffsets);
|
||||||
|
/*******************************************************************************/
|
||||||
|
/*!
|
||||||
|
|
||||||
|
\brief
|
||||||
|
Removes a mesh from the Texture Library. But this does not mean that the
|
||||||
|
textures have been removed yet. A call to "BuildTextures()" is required to
|
||||||
|
finalise all changes.
|
||||||
|
|
||||||
|
\param mesh
|
||||||
|
Handle to the Texture to remove.
|
||||||
|
|
||||||
|
*/
|
||||||
|
/*******************************************************************************/
|
||||||
|
void Remove(Handle<SHTexture> tex);
|
||||||
|
/***************************************************************************/
|
||||||
|
/*!
|
||||||
|
|
||||||
|
\brief
|
||||||
|
Finalises all changes to the Texture Library into the GPU buffers.
|
||||||
|
|
||||||
|
\param cmdBuffer
|
||||||
|
Command buffer used to set up transfers of data in the GPU memory. This
|
||||||
|
call must be preceded by calls to cmdBuffer's BeginRecording() and ended
|
||||||
|
with EndRecording(). Do recall to also submit the cmdBuffer to a transfer
|
||||||
|
queue.
|
||||||
|
*/
|
||||||
|
/***************************************************************************/
|
||||||
|
void BuildTextures();
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------*/
|
||||||
/* Setters */
|
/* Setters */
|
||||||
/*-----------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------*/
|
||||||
|
@ -220,19 +278,20 @@ namespace SHADE
|
||||||
Handle<SHVkQueue> graphicsQueue;
|
Handle<SHVkQueue> graphicsQueue;
|
||||||
Handle<SHVkQueue> transferQueue;
|
Handle<SHVkQueue> transferQueue;
|
||||||
Handle<SHVkDescriptorPool> descPool;
|
Handle<SHVkDescriptorPool> descPool;
|
||||||
|
Handle<SHVkCommandPool> graphicsCmdPool;
|
||||||
Handle<SHVkCommandPool> transferCmdPool;
|
Handle<SHVkCommandPool> transferCmdPool;
|
||||||
Handle<SHVkCommandBuffer> transferCmdBuffer;
|
Handle<SHVkCommandBuffer> transferCmdBuffer;
|
||||||
|
Handle<SHVkCommandBuffer> graphicsTexCmdBuffer;
|
||||||
SHRenderContext renderContext;
|
SHRenderContext renderContext;
|
||||||
std::array<Handle<SHVkSemaphore>, 2> graphSemaphores;
|
std::array<Handle<SHVkSemaphore>, 2> graphSemaphores;
|
||||||
// Not Owned Resources
|
// Not Owned Resources
|
||||||
SHWindow* window = nullptr;
|
SHWindow* window = nullptr;
|
||||||
|
|
||||||
// global data (descriptor sets as well)
|
|
||||||
Handle<SHGraphicsGlobalData> globalData;
|
|
||||||
|
|
||||||
// Middle End Resources
|
// Middle End Resources
|
||||||
ResourceManager resourceManager;
|
ResourceManager resourceManager;
|
||||||
SHMeshLibrary meshLibrary;
|
SHMeshLibrary meshLibrary;
|
||||||
|
SHTextureLibrary texLibrary;
|
||||||
|
SHSamplerCache samplerCache;
|
||||||
SHMaterialInstanceCache materialInstanceCache;
|
SHMaterialInstanceCache materialInstanceCache;
|
||||||
// Viewports
|
// Viewports
|
||||||
Handle<SHViewport> defaultViewport; // Whole screen
|
Handle<SHViewport> defaultViewport; // Whole screen
|
||||||
|
|
|
@ -40,8 +40,6 @@ namespace SHADE
|
||||||
|
|
||||||
void SHMaterialInstance::ExportProperties(void* dest)
|
void SHMaterialInstance::ExportProperties(void* dest)
|
||||||
{
|
{
|
||||||
assert(dataStore != nullptr);
|
|
||||||
|
|
||||||
if (!baseMaterial)
|
if (!baseMaterial)
|
||||||
throw std::runtime_error("[SHMaterialInstance] Attempted to set export a Material Instance with no base Material!");
|
throw std::runtime_error("[SHMaterialInstance] Attempted to set export a Material Instance with no base Material!");
|
||||||
|
|
||||||
|
|
|
@ -15,6 +15,7 @@ of DigiPen Institute of Technology is prohibited.
|
||||||
// Project Includes
|
// Project Includes
|
||||||
#include "Resource/Handle.h"
|
#include "Resource/Handle.h"
|
||||||
#include "Graphics/Shaders/BlockInterface/SHShaderBlockInterface.h"
|
#include "Graphics/Shaders/BlockInterface/SHShaderBlockInterface.h"
|
||||||
|
#include "SH_API.h"
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
|
@ -34,7 +35,7 @@ namespace SHADE
|
||||||
a SHRenderable.
|
a SHRenderable.
|
||||||
*/
|
*/
|
||||||
/***********************************************************************************/
|
/***********************************************************************************/
|
||||||
class SHMaterialInstance
|
class SH_API SHMaterialInstance
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
/*-----------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------*/
|
||||||
|
|
|
@ -48,7 +48,7 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get offset and modify the memory directly
|
// Get offset and modify the memory directly
|
||||||
T* dataPtr = dataStore.get() + od.StoredDataOffset;
|
T* dataPtr = reinterpret_cast<T*>(dataStore.get() + od.StoredDataOffset);
|
||||||
*dataPtr = value;
|
*dataPtr = value;
|
||||||
|
|
||||||
// Save the override data information
|
// Save the override data information
|
||||||
|
|
|
@ -81,7 +81,7 @@ namespace SHADE
|
||||||
if (!material)
|
if (!material)
|
||||||
{
|
{
|
||||||
SHGraphicsSystem* gfxSystem = SHSystemManager::GetSystem<SHGraphicsSystem>();
|
SHGraphicsSystem* gfxSystem = SHSystemManager::GetSystem<SHGraphicsSystem>();
|
||||||
material = gfxSystem->AddOrGetBaseMaterialInstance(sharedMaterial->GetBaseMaterial());
|
material = gfxSystem->AddMaterialInstanceCopy(sharedMaterial);
|
||||||
}
|
}
|
||||||
|
|
||||||
return material;
|
return material;
|
||||||
|
|
|
@ -60,9 +60,9 @@ namespace SHADE
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
/* Drawing Functions */
|
/* Drawing Functions */
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
void SHRenderer::Draw(uint32_t frameIndex) noexcept
|
void SHRenderer::Draw(uint32_t frameIndex, Handle<SHVkDescriptorPool> descPool) noexcept
|
||||||
{
|
{
|
||||||
renderGraph->Execute(frameIndex, commandBuffers[frameIndex]);
|
renderGraph->Execute(frameIndex, commandBuffers[frameIndex], descPool);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHRenderer::UpdateDataAndBind(Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex) noexcept
|
void SHRenderer::UpdateDataAndBind(Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex) noexcept
|
||||||
|
|
|
@ -74,7 +74,7 @@ namespace SHADE
|
||||||
/*-----------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------*/
|
||||||
/* Drawing Functions */
|
/* Drawing Functions */
|
||||||
/*-----------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------*/
|
||||||
void Draw(uint32_t frameIndex) noexcept;
|
void Draw(uint32_t frameIndex, Handle<SHVkDescriptorPool> descPool) noexcept;
|
||||||
void UpdateDataAndBind (Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex) noexcept;
|
void UpdateDataAndBind (Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex) noexcept;
|
||||||
void UpdateCameraDataToBuffer (void) noexcept;
|
void UpdateCameraDataToBuffer (void) noexcept;
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,7 @@ namespace SHADE
|
||||||
SHPipelineLayoutParams params
|
SHPipelineLayoutParams params
|
||||||
{
|
{
|
||||||
.shaderModules = {vsFsPair.first, vsFsPair.second},
|
.shaderModules = {vsFsPair.first, vsFsPair.second},
|
||||||
.globalDescSetLayouts = globalData->GetDescSetLayouts()
|
.globalDescSetLayouts = SHGraphicsGlobalData::GetDescSetLayouts()
|
||||||
};
|
};
|
||||||
|
|
||||||
// Create the pipeline layout
|
// Create the pipeline layout
|
||||||
|
@ -19,7 +19,7 @@ namespace SHADE
|
||||||
|
|
||||||
// Create the pipeline and configure the default vertex input state
|
// Create the pipeline and configure the default vertex input state
|
||||||
auto newPipeline = logicalDevice->CreateGraphicsPipeline(pipelineLayout, nullptr, renderpass, subpass);
|
auto newPipeline = logicalDevice->CreateGraphicsPipeline(pipelineLayout, nullptr, renderpass, subpass);
|
||||||
newPipeline->GetPipelineState().SetVertexInputState(globalData->GetDefaultViState());
|
newPipeline->GetPipelineState().SetVertexInputState(SHGraphicsGlobalData::GetDefaultViState());
|
||||||
|
|
||||||
// Actually construct the pipeline
|
// Actually construct the pipeline
|
||||||
newPipeline->ConstructPipeline();
|
newPipeline->ConstructPipeline();
|
||||||
|
@ -30,10 +30,9 @@ namespace SHADE
|
||||||
return newPipeline;
|
return newPipeline;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHPipelineLibrary::Init(Handle<SHVkLogicalDevice> device, Handle<SHGraphicsGlobalData> inGlobalData) noexcept
|
void SHPipelineLibrary::Init(Handle<SHVkLogicalDevice> device) noexcept
|
||||||
{
|
{
|
||||||
logicalDevice = device;
|
logicalDevice = device;
|
||||||
globalData = inGlobalData;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Handle<SHVkPipeline> SHPipelineLibrary::GetDrawPipline(std::pair<Handle<SHVkShaderModule>, Handle<SHVkShaderModule>> const& vsFsPair) noexcept
|
Handle<SHVkPipeline> SHPipelineLibrary::GetDrawPipline(std::pair<Handle<SHVkShaderModule>, Handle<SHVkShaderModule>> const& vsFsPair) noexcept
|
||||||
|
|
|
@ -24,14 +24,9 @@ namespace SHADE
|
||||||
|
|
||||||
//! a map of pipelines that are hashed using a pair of shader module handles
|
//! a map of pipelines that are hashed using a pair of shader module handles
|
||||||
std::unordered_map<std::pair<Handle<SHVkShaderModule>, Handle<SHVkShaderModule>>, Handle<SHVkPipeline>> pipelines;
|
std::unordered_map<std::pair<Handle<SHVkShaderModule>, Handle<SHVkShaderModule>>, Handle<SHVkPipeline>> pipelines;
|
||||||
|
|
||||||
// Global data
|
|
||||||
Handle<SHGraphicsGlobalData> globalData;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void Init (Handle<SHVkLogicalDevice> device, Handle<SHGraphicsGlobalData> inGlobalData) noexcept;
|
void Init (Handle<SHVkLogicalDevice> device) noexcept;
|
||||||
|
|
||||||
// Draw pipeline functions. used only when creating pipelines for drawing using a vertex and fragment shader
|
// Draw pipeline functions. used only when creating pipelines for drawing using a vertex and fragment shader
|
||||||
Handle<SHVkPipeline> CreateDrawPipeline (
|
Handle<SHVkPipeline> CreateDrawPipeline (
|
||||||
|
|
|
@ -20,18 +20,36 @@ of DigiPen Institute of Technology is prohibited.
|
||||||
#include "Graphics/Commands/SHVkCommandBuffer.h"
|
#include "Graphics/Commands/SHVkCommandBuffer.h"
|
||||||
#include "Graphics/SHVkUtil.h"
|
#include "Graphics/SHVkUtil.h"
|
||||||
#include "Tools/SHLogger.h"
|
#include "Tools/SHLogger.h"
|
||||||
|
#include "Graphics/MiddleEnd/Interface/SHGraphicsConstants.h"
|
||||||
|
#include "Graphics/Descriptors/SHVkDescriptorSetGroup.h"
|
||||||
|
#include "Graphics/Images/SHVkImage.h"
|
||||||
|
#include "Graphics/MiddleEnd/GlobalData/SHGraphicsGlobalData.h"
|
||||||
|
#include "Assets/Asset Types/SHTextureAsset.h"
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
/* Usage Functions */
|
/* Usage Functions */
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
Handle<SHTexture> SHTextureLibrary::Add(uint32_t pixelCount, const SHTexture::PixelChannel* const pixelData, SHTexture::TextureFormat format, uint32_t mipLevels)
|
Handle<SHTexture> SHTextureLibrary::Add(const SHTextureAsset& texAsset, Handle<SHVkSampler> sampler)
|
||||||
|
{
|
||||||
|
return Add
|
||||||
|
(
|
||||||
|
texAsset.numBytes,
|
||||||
|
texAsset.pixelData,
|
||||||
|
texAsset.width, texAsset.height,
|
||||||
|
texAsset.format,
|
||||||
|
texAsset.mipOffsets,
|
||||||
|
sampler
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Handle<SHTexture> SHTextureLibrary::Add(uint32_t pixelCount, const SHTexture::PixelChannel* const pixelData, uint32_t width, uint32_t height, SHTexture::TextureFormat format, std::vector<uint32_t> mipOffsets, Handle<SHVkSampler> sampler)
|
||||||
{
|
{
|
||||||
isDirty = true;
|
isDirty = true;
|
||||||
|
|
||||||
auto handle = resourceManager.Create<SHTexture>();
|
auto handle = resourceManager.Create<SHTexture>();
|
||||||
addJobs.emplace_back(AddJob { pixelCount, pixelData, format, mipLevels });
|
addJobs.emplace_back(AddJob { pixelCount, pixelData, format, sampler, mipOffsets, width, height, handle });
|
||||||
return handle;
|
return handle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -44,22 +62,48 @@ namespace SHADE
|
||||||
isDirty = true;
|
isDirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHTextureLibrary::BuildImages(Handle<SHVkLogicalDevice> device, Handle<SHVkCommandBuffer> cmdBuffer, Handle<SHVkQueue> graphicsQueue, Handle<SHVkDescriptorPool> descPool, Handle<SHVkDescriptorSetLayout> descLayout)
|
void SHTextureLibrary::BuildTextures(Handle<SHVkLogicalDevice> device, Handle<SHVkCommandBuffer> cmdBuffer, Handle<SHVkQueue> graphicsQueue, Handle<SHVkDescriptorPool> descPool)
|
||||||
{
|
{
|
||||||
|
// Don't do anything if there are no updates
|
||||||
|
if (!isDirty)
|
||||||
|
return;
|
||||||
|
|
||||||
/* Remove Textures */
|
/* Remove Textures */
|
||||||
std::vector<vk::ImageMemoryBarrier> pipelineBarriers(addJobs.size());
|
// TODO
|
||||||
|
|
||||||
/* Add Textures */
|
/* Add Textures */
|
||||||
// Transition
|
// Load Textures - Transitions
|
||||||
|
std::vector<vk::ImageMemoryBarrier> pipelineBarriers(addJobs.size());
|
||||||
for (int i = 0; auto& job : addJobs)
|
for (int i = 0; auto& job : addJobs)
|
||||||
{
|
{
|
||||||
job.Image = resourceManager.Create<SHVkImage>();
|
job.Image = resourceManager.Create<SHVkImage>
|
||||||
|
(
|
||||||
|
&device->GetVMAAllocator(),
|
||||||
|
SHImageCreateParams
|
||||||
|
{
|
||||||
|
.imageType = vk::ImageType::e2D,
|
||||||
|
.width = job.Width,
|
||||||
|
.height = job.Height,
|
||||||
|
.depth = 1,
|
||||||
|
.levels = static_cast<uint8_t>(job.MipOffsets.size()),
|
||||||
|
.arrayLayers = 1,
|
||||||
|
.imageFormat = job.TextureFormat,
|
||||||
|
.usageFlags = vk::ImageUsageFlagBits::eSampled | vk::ImageUsageFlagBits::eTransferDst,
|
||||||
|
.createFlags = {}
|
||||||
|
},
|
||||||
|
job.PixelData,
|
||||||
|
job.PixelCount,
|
||||||
|
job.MipOffsets,
|
||||||
|
VmaMemoryUsage::VMA_MEMORY_USAGE_AUTO,
|
||||||
|
VmaAllocationCreateFlagBits {}
|
||||||
|
);
|
||||||
job.Image->PrepareImageTransitionInfo(vk::ImageLayout::eUndefined, vk::ImageLayout::eTransferDstOptimal, pipelineBarriers[i]);
|
job.Image->PrepareImageTransitionInfo(vk::ImageLayout::eUndefined, vk::ImageLayout::eTransferDstOptimal, pipelineBarriers[i]);
|
||||||
++i;
|
++i;
|
||||||
}
|
}
|
||||||
vk::PipelineStageFlagBits srcStage = vk::PipelineStageFlagBits::eTopOfPipe;
|
vk::PipelineStageFlagBits srcStage = vk::PipelineStageFlagBits::eTopOfPipe;
|
||||||
vk::PipelineStageFlagBits dstStage = vk::PipelineStageFlagBits::eTopOfPipe;
|
vk::PipelineStageFlagBits dstStage = vk::PipelineStageFlagBits::eTopOfPipe;
|
||||||
preparePipelineBarriers(vk::ImageLayout::eUndefined, vk::ImageLayout::eTransferDstOptimal, srcStage, dstStage, pipelineBarriers);
|
preparePipelineBarriers(vk::ImageLayout::eUndefined, vk::ImageLayout::eTransferDstOptimal, srcStage, dstStage, pipelineBarriers);
|
||||||
|
cmdBuffer->BeginRecording();
|
||||||
cmdBuffer->PipelineBarrier(vk::PipelineStageFlagBits::eTopOfPipe, vk::PipelineStageFlagBits::eTransfer, {}, {}, {}, pipelineBarriers);
|
cmdBuffer->PipelineBarrier(vk::PipelineStageFlagBits::eTopOfPipe, vk::PipelineStageFlagBits::eTransfer, {}, {}, {}, pipelineBarriers);
|
||||||
|
|
||||||
// Copy
|
// Copy
|
||||||
|
@ -73,13 +117,16 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
// Transition
|
// Transition
|
||||||
job.Image->PrepareImageTransitionInfo(vk::ImageLayout::eTransferDstOptimal, vk::ImageLayout::eShaderReadOnlyOptimal, pipelineBarriers[i]);
|
job.Image->PrepareImageTransitionInfo(vk::ImageLayout::eTransferDstOptimal, vk::ImageLayout::eShaderReadOnlyOptimal, pipelineBarriers[i]);
|
||||||
|
++i;
|
||||||
}
|
}
|
||||||
preparePipelineBarriers(vk::ImageLayout::eTransferDstOptimal, vk::ImageLayout::eShaderReadOnlyOptimal, srcStage, dstStage, pipelineBarriers);
|
preparePipelineBarriers(vk::ImageLayout::eTransferDstOptimal, vk::ImageLayout::eShaderReadOnlyOptimal, srcStage, dstStage, pipelineBarriers);
|
||||||
cmdBuffer->PipelineBarrier(vk::PipelineStageFlagBits::eTopOfPipe, vk::PipelineStageFlagBits::eTransfer, {}, {}, {}, pipelineBarriers);
|
cmdBuffer->PipelineBarrier(vk::PipelineStageFlagBits::eTransfer, vk::PipelineStageFlagBits::eFragmentShader, {}, {}, {}, pipelineBarriers);
|
||||||
|
|
||||||
// Execute Commands
|
// Execute Commands
|
||||||
|
cmdBuffer->EndRecording();
|
||||||
graphicsQueue->SubmitCommandBuffer({ cmdBuffer });
|
graphicsQueue->SubmitCommandBuffer({ cmdBuffer });
|
||||||
device->WaitIdle();
|
device->WaitIdle();
|
||||||
|
graphicsQueue->GetVkQueue().waitIdle();
|
||||||
|
|
||||||
// Create Image View
|
// Create Image View
|
||||||
for (auto& job : addJobs)
|
for (auto& job : addJobs)
|
||||||
|
@ -90,16 +137,45 @@ namespace SHADE
|
||||||
.format = job.TextureFormat,
|
.format = job.TextureFormat,
|
||||||
.imageAspectFlags = vk::ImageAspectFlagBits::eColor,
|
.imageAspectFlags = vk::ImageAspectFlagBits::eColor,
|
||||||
.baseMipLevel = 0,
|
.baseMipLevel = 0,
|
||||||
.mipLevelCount = job.MipLevels,
|
.mipLevelCount = static_cast<uint32_t>(job.MipOffsets.size()),
|
||||||
.baseArrayLayer = 0,
|
.baseArrayLayer = 0,
|
||||||
.layerCount = 0
|
.layerCount = 1
|
||||||
};
|
};
|
||||||
job.Handle->ImageView = job.Image->CreateImageView(device, job.Image, DETAILS);
|
job.TextureHandle->ImageView = job.Image->CreateImageView(device, job.Image, DETAILS);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Build Descriptor
|
// Add Textures
|
||||||
Handle<SHVkDescriptorSetGroup> descSetGroup = descPool->Allocate({ descLayout }, { 1 });
|
for (auto& job : addJobs)
|
||||||
|
{
|
||||||
|
texOrder.emplace_back(job.TextureHandle);
|
||||||
|
combinedImageSamplers.emplace_back(std::make_tuple(job.TextureHandle->ImageView, job.Sampler, vk::ImageLayout::eShaderReadOnlyOptimal));
|
||||||
|
job.TextureHandle->TextureArrayIndex = texOrder.size() - 1;
|
||||||
|
}
|
||||||
|
addJobs.clear();
|
||||||
|
|
||||||
|
/* Build Descriptor Set with all the Textures only if there are textures */
|
||||||
|
if (!texOrder.empty())
|
||||||
|
{
|
||||||
|
if (!texDescriptors)
|
||||||
|
{
|
||||||
|
texDescriptors = descPool->Allocate
|
||||||
|
(
|
||||||
|
{ SHGraphicsGlobalData::GetDescSetLayouts()[SHGraphicsConstants::DescriptorSetIndex::STATIC_GLOBALS] },
|
||||||
|
{ static_cast<uint32_t>(texOrder.size()) }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
texDescriptors->ModifyWriteDescImage
|
||||||
|
(
|
||||||
|
SHGraphicsConstants::DescriptorSetIndex::STATIC_GLOBALS,
|
||||||
|
SHGraphicsConstants::DescriptorSetBindings::IMAGE_AND_SAMPLERS_DATA,
|
||||||
|
combinedImageSamplers
|
||||||
|
);
|
||||||
|
texDescriptors->UpdateDescriptorSetImages
|
||||||
|
(
|
||||||
|
SHGraphicsConstants::DescriptorSetIndex::STATIC_GLOBALS,
|
||||||
|
SHGraphicsConstants::DescriptorSetBindings::IMAGE_AND_SAMPLERS_DATA
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
isDirty = false;
|
isDirty = false;
|
||||||
}
|
}
|
||||||
|
@ -139,4 +215,65 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
vk::Format SHTextureLibrary::ddsLoaderToVkFormat(tinyddsloader::DDSFile::DXGIFormat format, bool isLinear)
|
||||||
|
{
|
||||||
|
switch (format)
|
||||||
|
{
|
||||||
|
case tinyddsloader::DDSFile::DXGIFormat::BC1_UNorm:
|
||||||
|
return vk::Format::eBc1RgbaUnormBlock;
|
||||||
|
case tinyddsloader::DDSFile::DXGIFormat::BC1_UNorm_SRGB:
|
||||||
|
return vk::Format::eBc1RgbaSrgbBlock;
|
||||||
|
case tinyddsloader::DDSFile::DXGIFormat::BC2_UNorm:
|
||||||
|
case tinyddsloader::DDSFile::DXGIFormat::BC2_UNorm_SRGB:
|
||||||
|
return isLinear ? vk::Format::eBc2UnormBlock : vk::Format::eBc2SrgbBlock;
|
||||||
|
case tinyddsloader::DDSFile::DXGIFormat::BC3_UNorm:
|
||||||
|
case tinyddsloader::DDSFile::DXGIFormat::BC3_UNorm_SRGB:
|
||||||
|
return isLinear ? vk::Format::eBc3UnormBlock : vk::Format::eBc3SrgbBlock;
|
||||||
|
case tinyddsloader::DDSFile::DXGIFormat::BC5_UNorm:
|
||||||
|
case tinyddsloader::DDSFile::DXGIFormat::BC5_SNorm:
|
||||||
|
return isLinear ? vk::Format::eBc5UnormBlock : vk::Format::eBc5SnormBlock;
|
||||||
|
case tinyddsloader::DDSFile::DXGIFormat::R8G8B8A8_UNorm:
|
||||||
|
case tinyddsloader::DDSFile::DXGIFormat::R8G8B8A8_UNorm_SRGB:
|
||||||
|
return isLinear ? vk::Format::eR8G8B8A8Unorm : vk::Format::eR8G8B8A8Srgb;
|
||||||
|
case tinyddsloader::DDSFile::DXGIFormat::R8G8B8A8_SNorm:
|
||||||
|
return vk::Format::eR8G8B8A8Snorm;
|
||||||
|
case tinyddsloader::DDSFile::DXGIFormat::B8G8R8A8_UNorm:
|
||||||
|
case tinyddsloader::DDSFile::DXGIFormat::B8G8R8A8_UNorm_SRGB:
|
||||||
|
return isLinear ? vk::Format::eB8G8R8A8Unorm : vk::Format::eB8G8R8A8Srgb;
|
||||||
|
case tinyddsloader::DDSFile::DXGIFormat::B8G8R8X8_UNorm:
|
||||||
|
case tinyddsloader::DDSFile::DXGIFormat::B8G8R8X8_UNorm_SRGB:
|
||||||
|
return isLinear ? vk::Format::eB8G8R8A8Unorm : vk::Format::eB8G8R8Srgb;
|
||||||
|
default:
|
||||||
|
throw std::runtime_error("Unsupported DDS format.");
|
||||||
|
}
|
||||||
|
|
||||||
|
//switch (format)
|
||||||
|
//{
|
||||||
|
//case tinyddsloader::DDSFile::DXGIFormat::R8G8B8A8_UNorm:
|
||||||
|
//case tinyddsloader::DDSFile::DXGIFormat::R8G8B8A8_UNorm_SRGB:
|
||||||
|
// return (isLinear) ? vk::Format::eR8G8B8A8Unorm : vk::Format::eR8G8B8A8Srgb;
|
||||||
|
//
|
||||||
|
|
||||||
|
//case tinyddsloader::DDSFile::DXGIFormat::B8G8R8A8_UNorm:
|
||||||
|
//case tinyddsloader::DDSFile::DXGIFormat::B8G8R8A8_UNorm_SRGB:
|
||||||
|
// return (isLinear) ? vk::Format::eB8G8R8A8Unorm : vk::Format::eB8G8R8A8Srgb;
|
||||||
|
//
|
||||||
|
|
||||||
|
//case tinyddsloader::DDSFile::DXGIFormat::BC1_UNorm:
|
||||||
|
//case tinyddsloader::DDSFile::DXGIFormat::BC1_UNorm_SRGB:
|
||||||
|
// return (isLinear) ? vk::Format::eBc1RgbaUnormBlock : vk::Format::eBc1RgbaSrgbBlock;
|
||||||
|
|
||||||
|
//case tinyddsloader::DDSFile::DXGIFormat::BC2_UNorm:
|
||||||
|
//case tinyddsloader::DDSFile::DXGIFormat::BC2_UNorm_SRGB:
|
||||||
|
// return (isLinear) ? vk::Format::eBc2UnormBlock : vk::Format::eBc2SrgbBlock;
|
||||||
|
|
||||||
|
//case tinyddsloader::DDSFile::DXGIFormat::BC3_UNorm:
|
||||||
|
//case tinyddsloader::DDSFile::DXGIFormat::BC3_UNorm_SRGB:
|
||||||
|
// return (isLinear) ? vk::Format::eBc3UnormBlock : vk::Format::eBc3SrgbBlock;
|
||||||
|
|
||||||
|
//case tinyddsloader::DDSFile::DXGIFormat::BC5_UNorm:
|
||||||
|
// return (isLinear) ? vk::Format::eBc5UnormBlock : vk::Format::eBc5SnormBlock;
|
||||||
|
//
|
||||||
|
//}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,6 +14,8 @@ of DigiPen Institute of Technology is prohibited.
|
||||||
|
|
||||||
// STL Includes
|
// STL Includes
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
// External Dependencies
|
||||||
|
#include "tinyddsloader.h"
|
||||||
// Project Includes
|
// Project Includes
|
||||||
#include "Resource/Handle.h"
|
#include "Resource/Handle.h"
|
||||||
#include "Resource/ResourceLibrary.h"
|
#include "Resource/ResourceLibrary.h"
|
||||||
|
@ -33,6 +35,9 @@ namespace SHADE
|
||||||
class SHVkQueue;
|
class SHVkQueue;
|
||||||
class SHVkDescriptorPool;
|
class SHVkDescriptorPool;
|
||||||
class SHVkDescriptorSetLayout;
|
class SHVkDescriptorSetLayout;
|
||||||
|
class SHVkDescriptorSetGroup;
|
||||||
|
class SHVkSampler;
|
||||||
|
class SHTextureAsset;
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
/* Type Definitions */
|
/* Type Definitions */
|
||||||
|
@ -43,7 +48,7 @@ namespace SHADE
|
||||||
/*-----------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------*/
|
||||||
/* Type Definitions */
|
/* Type Definitions */
|
||||||
/*-----------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------*/
|
||||||
using PixelChannel = float;
|
using PixelChannel = unsigned char;
|
||||||
using TextureFormat = vk::Format; // TODO: Change
|
using TextureFormat = vk::Format; // TODO: Change
|
||||||
using Index = uint32_t;
|
using Index = uint32_t;
|
||||||
|
|
||||||
|
@ -71,7 +76,7 @@ namespace SHADE
|
||||||
|
|
||||||
\brief
|
\brief
|
||||||
Adds a texture to the Texture Library. But this does not mean that the
|
Adds a texture to the Texture Library. But this does not mean that the
|
||||||
textures have been added yet. A call to "BuildImages()" is required to
|
textures have been added yet. A call to "BuildTextures()" is required to
|
||||||
transfer all textures into the GPU.
|
transfer all textures into the GPU.
|
||||||
|
|
||||||
\param pixelCount
|
\param pixelCount
|
||||||
|
@ -88,13 +93,15 @@ namespace SHADE
|
||||||
|
|
||||||
*/
|
*/
|
||||||
/*******************************************************************************/
|
/*******************************************************************************/
|
||||||
Handle<SHTexture> Add(uint32_t pixelCount, const SHTexture::PixelChannel* const pixelData, SHTexture::TextureFormat format, uint32_t mipLevels);
|
|
||||||
|
Handle<SHTexture> Add(const SHTextureAsset& texAsset, Handle<SHVkSampler> sampler);
|
||||||
|
Handle<SHTexture> Add(uint32_t pixelCount, const SHTexture::PixelChannel* const pixelData, uint32_t width, uint32_t height, SHTexture::TextureFormat format, std::vector<uint32_t> mipOffsets, Handle<SHVkSampler> sampler);
|
||||||
/*******************************************************************************/
|
/*******************************************************************************/
|
||||||
/*!
|
/*!
|
||||||
|
|
||||||
\brief
|
\brief
|
||||||
Removes a mesh from the Texture Library. But this does not mean that the
|
Removes a mesh from the Texture Library. But this does not mean that the
|
||||||
textures have been removed yet. A call to "BuildImages()" is required to
|
textures have been removed yet. A call to "BuildTextures()" is required to
|
||||||
finalise all changes.
|
finalise all changes.
|
||||||
|
|
||||||
\param mesh
|
\param mesh
|
||||||
|
@ -118,12 +125,12 @@ namespace SHADE
|
||||||
queue.
|
queue.
|
||||||
*/
|
*/
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
void BuildImages(Handle<SHVkLogicalDevice> device, Handle<SHVkCommandBuffer> cmdBuffer, Handle<SHVkQueue> graphicsQueue, Handle<SHVkDescriptorPool> descPool, Handle<SHVkDescriptorSetLayout> descLayout);
|
void BuildTextures(Handle<SHVkLogicalDevice> device, Handle<SHVkCommandBuffer> cmdBuffer, Handle<SHVkQueue> graphicsQueue, Handle<SHVkDescriptorPool> descPool);
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------*/
|
||||||
/* Getter Functions */
|
/* Getter Functions */
|
||||||
/*-----------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------*/
|
||||||
Handle<SHVkBuffer> GetTextureBuffer() const noexcept { return texStorageBuffer; }
|
Handle<SHVkDescriptorSetGroup> GetTextureDescriptorSetGroup() const noexcept { return texDescriptors; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/*-----------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------*/
|
||||||
|
@ -134,9 +141,12 @@ namespace SHADE
|
||||||
uint32_t PixelCount = 0;
|
uint32_t PixelCount = 0;
|
||||||
const SHTexture::PixelChannel* PixelData = nullptr;
|
const SHTexture::PixelChannel* PixelData = nullptr;
|
||||||
SHTexture::TextureFormat TextureFormat = {};
|
SHTexture::TextureFormat TextureFormat = {};
|
||||||
uint32_t MipLevels = 0;
|
Handle<SHVkSampler> Sampler;
|
||||||
|
std::vector<uint32_t> MipOffsets;
|
||||||
|
uint32_t Width;
|
||||||
|
uint32_t Height;
|
||||||
|
Handle<SHTexture> TextureHandle;
|
||||||
Handle<SHVkImage> Image;
|
Handle<SHVkImage> Image;
|
||||||
Handle<SHTexture> Handle;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------*/
|
||||||
|
@ -149,9 +159,9 @@ namespace SHADE
|
||||||
ResourceManager resourceManager;
|
ResourceManager resourceManager;
|
||||||
std::vector<Handle<SHTexture>> texOrder;
|
std::vector<Handle<SHTexture>> texOrder;
|
||||||
// CPU Storage
|
// CPU Storage
|
||||||
std::vector<SHTexture::PixelChannel> texStorage;
|
std::vector<std::tuple<Handle<SHVkImageView>, Handle<SHVkSampler>, vk::ImageLayout>> combinedImageSamplers;
|
||||||
// GPU Storage
|
// GPU Storage
|
||||||
Handle<SHVkBuffer> texStorageBuffer{};
|
Handle<SHVkDescriptorSetGroup> texDescriptors;
|
||||||
// Flags
|
// Flags
|
||||||
bool isDirty = true;
|
bool isDirty = true;
|
||||||
|
|
||||||
|
@ -159,5 +169,6 @@ namespace SHADE
|
||||||
/* Helper Functions */
|
/* Helper Functions */
|
||||||
/*-----------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------*/
|
||||||
void preparePipelineBarriers(vk::ImageLayout oldLayout, vk::ImageLayout newLayout, vk::PipelineStageFlagBits& srcStage, vk::PipelineStageFlagBits& dstStage, std::vector<vk::ImageMemoryBarrier>& barriers);
|
void preparePipelineBarriers(vk::ImageLayout oldLayout, vk::ImageLayout newLayout, vk::PipelineStageFlagBits& srcStage, vk::PipelineStageFlagBits& dstStage, std::vector<vk::ImageMemoryBarrier>& barriers);
|
||||||
|
vk::Format ddsLoaderToVkFormat(tinyddsloader::DDSFile::DXGIFormat format, bool isLinear);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,75 @@
|
||||||
|
/************************************************************************************//*!
|
||||||
|
\file SHVkSamplerCache.cpp
|
||||||
|
\author Tng Kah Wei, kahwei.tng, 390009620
|
||||||
|
\par email: kahwei.tng\@digipen.edu
|
||||||
|
\date Mar 16, 2022
|
||||||
|
\brief Contains the implementation for the SHVkSamplerCache class.
|
||||||
|
|
||||||
|
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 "SHVkSamplerCache.h"
|
||||||
|
|
||||||
|
// Standard Library
|
||||||
|
#include <functional>
|
||||||
|
// Project Header
|
||||||
|
#include "Graphics/Images/SHVkSampler.h"
|
||||||
|
#include "Graphics/Devices/SHVkLogicalDevice.h"
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
/* Utility Functions */
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
void SHSamplerCache::Clear()
|
||||||
|
{
|
||||||
|
samplersMap.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
/* Getter Functions */
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
Handle<SHVkSampler> SHSamplerCache::GetSampler(Handle<SHVkLogicalDevice> device, const SHVkSamplerParams& params)
|
||||||
|
{
|
||||||
|
// Get the hash to check if it was cached
|
||||||
|
const RawSamplerHash HASH = calcHash
|
||||||
|
(
|
||||||
|
params.minFilter,
|
||||||
|
params.magFilter,
|
||||||
|
params.addressMode,
|
||||||
|
params.mipmapMode,
|
||||||
|
params.minLod,
|
||||||
|
params.maxLod
|
||||||
|
);
|
||||||
|
|
||||||
|
// Check if it was cached
|
||||||
|
auto sampler = samplersMap.find(HASH);
|
||||||
|
if (sampler == samplersMap.end())
|
||||||
|
{
|
||||||
|
const auto BUILD_RESULT = samplersMap.emplace(HASH, device->CreateSampler(params));
|
||||||
|
sampler = BUILD_RESULT.first;
|
||||||
|
}
|
||||||
|
|
||||||
|
return sampler->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
/* Helper Functions */
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
SHSamplerCache::RawSamplerHash SHSamplerCache::calcHash(vk::Filter minFilter, vk::Filter magFilter, vk::SamplerAddressMode addressMode, vk::SamplerMipmapMode mipmapMode, float minLod, float maxLod)
|
||||||
|
{
|
||||||
|
static auto charHasher = std::hash<uint8_t>{};
|
||||||
|
static auto floatHasher = std::hash<float>{};
|
||||||
|
|
||||||
|
const RawSamplerHash H1 = charHasher(static_cast<uint8_t>(minFilter));
|
||||||
|
const RawSamplerHash H2 = charHasher(static_cast<uint8_t>(magFilter));
|
||||||
|
const RawSamplerHash H3 = charHasher(static_cast<uint8_t>(addressMode));
|
||||||
|
const RawSamplerHash H4 = charHasher(static_cast<uint8_t>(mipmapMode));
|
||||||
|
const RawSamplerHash H5 = floatHasher(minLod);
|
||||||
|
const RawSamplerHash H6 = floatHasher(maxLod);
|
||||||
|
|
||||||
|
return H1 ^ (H2 << 1) ^ (H3 << 2) ^ (H4 << 3) ^ (H5 << 4) ^ (H6 << 5);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,80 @@
|
||||||
|
/************************************************************************************//*!
|
||||||
|
\file SHSamplerCache.h
|
||||||
|
\author Tng Kah Wei, kahwei.tng, 390009620
|
||||||
|
\par email: kahwei.tng\@digipen.edu
|
||||||
|
\date Mar 16, 2022
|
||||||
|
\brief Contains the interface for the SHSamplerCache class.
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
// Standard Libraries
|
||||||
|
#include <unordered_map>
|
||||||
|
// External Dependencies
|
||||||
|
#include "Graphics/SHVulkanIncludes.h"
|
||||||
|
// Project Includes
|
||||||
|
#include "Resource/Handle.h"
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
/* Forward Declarations */
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
class SHVkLogicalDevice;
|
||||||
|
class SHVkSampler;
|
||||||
|
struct SHVkSamplerParams;
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
/* Type Definitions */
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
/*************************************************************************************/
|
||||||
|
/*!
|
||||||
|
\brief
|
||||||
|
Class that is responsible for caching and providing Samplers to the user for
|
||||||
|
sampling textures.
|
||||||
|
*/
|
||||||
|
/*************************************************************************************/
|
||||||
|
class SHSamplerCache
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
/* Utility Functions */
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
/// <summary>
|
||||||
|
/// Clears the cache, destroying all created samplers.
|
||||||
|
/// </summary>
|
||||||
|
void Clear();
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
/* Getter Functions */
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
/// <summary>
|
||||||
|
/// Retrieves a Vulkan Sampler of the specified type. If this was retrieved
|
||||||
|
/// before, a cached copy of the Vulkan Sampler will be provided.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="device">Logical device to create the sampler with if needed.</param>
|
||||||
|
/// <param name="params">Describes the parameters for the sampler.</param>
|
||||||
|
/// <returns>Handle to the SHVkSampler object specified.</returns>
|
||||||
|
Handle<SHVkSampler> GetSampler(Handle<SHVkLogicalDevice> device, const SHVkSamplerParams& params);
|
||||||
|
|
||||||
|
private:
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
/* Type Definitions */
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
using RawSamplerHash = size_t;
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
/* Data Members */
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
// Resources
|
||||||
|
std::unordered_map<RawSamplerHash, Handle<SHVkSampler>> samplersMap;
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
/* Helper Functions */
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
static RawSamplerHash calcHash(vk::Filter minFilter, vk::Filter magFilter, vk::SamplerAddressMode addressMode, vk::SamplerMipmapMode mipmapMode, float minLod, float maxLod);
|
||||||
|
};
|
||||||
|
}
|
|
@ -216,10 +216,13 @@ namespace SHADE
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
void SHVkPipelineLayout::PrepareVkDescriptorSetLayouts(void) noexcept
|
void SHVkPipelineLayout::PrepareVkDescriptorSetLayouts(void) noexcept
|
||||||
{
|
{
|
||||||
|
descriptorSetLayoutsPipeline.reserve(descriptorSetLayoutsAllocate.size() + descriptorSetLayoutsGlobal.size());
|
||||||
|
|
||||||
// Settle allocate layouts first
|
// Settle allocate layouts first
|
||||||
vkDescriptorSetLayoutsAllocate.reserve(descriptorSetLayoutsAllocate.size());
|
vkDescriptorSetLayoutsAllocate.reserve(descriptorSetLayoutsAllocate.size());
|
||||||
for (auto const& layout : descriptorSetLayoutsAllocate)
|
for (auto const& layout : descriptorSetLayoutsAllocate)
|
||||||
{
|
{
|
||||||
|
descriptorSetLayoutsPipeline.emplace_back(layout);
|
||||||
vkDescriptorSetLayoutsAllocate.emplace_back(layout->GetVkHandle());
|
vkDescriptorSetLayoutsAllocate.emplace_back(layout->GetVkHandle());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -228,7 +231,10 @@ namespace SHADE
|
||||||
|
|
||||||
// First we insert the global layouts
|
// First we insert the global layouts
|
||||||
for (auto const& layout : descriptorSetLayoutsGlobal)
|
for (auto const& layout : descriptorSetLayoutsGlobal)
|
||||||
|
{
|
||||||
|
descriptorSetLayoutsPipeline.emplace_back(layout);
|
||||||
vkDescriptorSetLayoutsPipeline.emplace_back(layout->GetVkHandle());
|
vkDescriptorSetLayoutsPipeline.emplace_back(layout->GetVkHandle());
|
||||||
|
}
|
||||||
|
|
||||||
// Then we append layouts for allocation at the back of the vector
|
// Then we append layouts for allocation at the back of the vector
|
||||||
std::copy(vkDescriptorSetLayoutsAllocate.begin(), vkDescriptorSetLayoutsAllocate.end(), std::back_inserter(vkDescriptorSetLayoutsPipeline));
|
std::copy(vkDescriptorSetLayoutsAllocate.begin(), vkDescriptorSetLayoutsAllocate.end(), std::back_inserter(vkDescriptorSetLayoutsPipeline));
|
||||||
|
@ -435,6 +441,16 @@ namespace SHADE
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<Handle<SHVkDescriptorSetLayout>> SHVkPipelineLayout::GetDescriptorSetLayoutsPipeline(void) const noexcept
|
||||||
|
{
|
||||||
|
return descriptorSetLayoutsPipeline;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<Handle<SHVkDescriptorSetLayout>> SHVkPipelineLayout::GetDescriptorSetLayoutsAllocate(void) const noexcept
|
||||||
|
{
|
||||||
|
return descriptorSetLayoutsAllocate;
|
||||||
|
}
|
||||||
|
|
||||||
SHVkPipelineLayout& SHVkPipelineLayout::operator=(SHVkPipelineLayout&& rhs) noexcept
|
SHVkPipelineLayout& SHVkPipelineLayout::operator=(SHVkPipelineLayout&& rhs) noexcept
|
||||||
{
|
{
|
||||||
if (&rhs == this)
|
if (&rhs == this)
|
||||||
|
|
|
@ -42,6 +42,9 @@ namespace SHADE
|
||||||
//! We want to store this also because we need to allocate later
|
//! We want to store this also because we need to allocate later
|
||||||
std::vector<vk::DescriptorSetLayout> vkDescriptorSetLayoutsAllocate;
|
std::vector<vk::DescriptorSetLayout> vkDescriptorSetLayoutsAllocate;
|
||||||
|
|
||||||
|
//! Store for descriptor set group creation
|
||||||
|
std::vector<Handle<SHVkDescriptorSetLayout>> descriptorSetLayoutsPipeline;
|
||||||
|
|
||||||
//! Store for pipeline layout recreation
|
//! Store for pipeline layout recreation
|
||||||
std::vector<vk::DescriptorSetLayout> vkDescriptorSetLayoutsPipeline;
|
std::vector<vk::DescriptorSetLayout> vkDescriptorSetLayoutsPipeline;
|
||||||
|
|
||||||
|
@ -71,10 +74,12 @@ namespace SHADE
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
/* SETTERS AND GETTERS */
|
/* SETTERS AND GETTERS */
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
std::vector<Handle<SHVkShaderModule>> const& GetShaderModules (void) const noexcept;
|
std::vector<Handle<SHVkShaderModule>> const& GetShaderModules (void) const noexcept;
|
||||||
vk::PipelineLayout GetVkPipelineLayout (void) const noexcept;
|
vk::PipelineLayout GetVkPipelineLayout (void) const noexcept;
|
||||||
SHPushConstantInterface const& GetPushConstantInterface (void) const noexcept;
|
SHPushConstantInterface const& GetPushConstantInterface (void) const noexcept;
|
||||||
Handle<SHShaderBlockInterface> GetShaderBlockInterface (uint32_t set, uint32_t binding, vk::ShaderStageFlagBits shaderStage) const noexcept;
|
Handle<SHShaderBlockInterface> GetShaderBlockInterface (uint32_t set, uint32_t binding, vk::ShaderStageFlagBits shaderStage) const noexcept;
|
||||||
|
std::vector<Handle<SHVkDescriptorSetLayout>> GetDescriptorSetLayoutsPipeline(void) const noexcept;
|
||||||
|
std::vector<Handle<SHVkDescriptorSetLayout>> GetDescriptorSetLayoutsAllocate(void) const noexcept;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
// Used for attachment description creation for renderpass node
|
||||||
|
enum class SH_ATT_DESC_TYPE
|
||||||
|
{
|
||||||
|
COLOR,
|
||||||
|
COLOR_PRESENT,
|
||||||
|
DEPTH,
|
||||||
|
STENCIL,
|
||||||
|
DEPTH_STENCIL,
|
||||||
|
};
|
||||||
|
}
|
|
@ -11,655 +11,7 @@
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
/***************************************************************************/
|
|
||||||
/*!
|
|
||||||
|
|
||||||
\brief
|
|
||||||
Non-default ctor for the resource. Using the type of the resource, we
|
|
||||||
decide whether or not we create a resource or link with a swapchain
|
|
||||||
resource (image).
|
|
||||||
|
|
||||||
\param logicalDevice
|
|
||||||
Logical device required to create an image resource if the type is NOT
|
|
||||||
SH_ATT_DESC_TYPE::COLOR_PRESENT.
|
|
||||||
|
|
||||||
\param swapchain
|
|
||||||
Swapchain required to get swapchain image if the type IS
|
|
||||||
SH_ATT_DESC_TYPE::COLOR_PRESENT.
|
|
||||||
|
|
||||||
\param type
|
|
||||||
Type of the image resource.
|
|
||||||
|
|
||||||
\param format
|
|
||||||
Format of the image resource.
|
|
||||||
|
|
||||||
\param w
|
|
||||||
Width of the image resource.
|
|
||||||
|
|
||||||
\param h
|
|
||||||
Height of the image resource.
|
|
||||||
|
|
||||||
\param levels
|
|
||||||
Number of mipmap levels of the image resource.
|
|
||||||
|
|
||||||
\param createFlags
|
|
||||||
Create flags used when an image resource needs to be created.
|
|
||||||
|
|
||||||
*/
|
|
||||||
/***************************************************************************/
|
|
||||||
SHRenderGraphResource::SHRenderGraphResource(Handle<SHVkLogicalDevice> const& logicalDevice, Handle<SHVkSwapchain> const& swapchain, std::string const& name, SH_ATT_DESC_TYPE type, vk::Format format, uint32_t w, uint32_t h, uint8_t levels, vk::ImageCreateFlagBits createFlags) noexcept
|
|
||||||
: resourceType{ type }
|
|
||||||
, resourceFormat{ format }
|
|
||||||
, images{}
|
|
||||||
, imageViews{}
|
|
||||||
, width{ w }
|
|
||||||
, height{ h }
|
|
||||||
, mipLevels{ levels }
|
|
||||||
, resourceName{ name }
|
|
||||||
{
|
|
||||||
// If the resource type is an arbitrary image and not swapchain image
|
|
||||||
if (type != SH_ATT_DESC_TYPE::COLOR_PRESENT)
|
|
||||||
{
|
|
||||||
vk::ImageAspectFlags imageAspectFlags;
|
|
||||||
vk::ImageUsageFlags usage = {};
|
|
||||||
|
|
||||||
// Check the resource type and set image usage flags and image aspect flags accordingly
|
|
||||||
switch (resourceType)
|
|
||||||
{
|
|
||||||
case SH_ATT_DESC_TYPE::COLOR:
|
|
||||||
usage |= vk::ImageUsageFlagBits::eColorAttachment;
|
|
||||||
imageAspectFlags |= vk::ImageAspectFlagBits::eColor;
|
|
||||||
break;
|
|
||||||
case SH_ATT_DESC_TYPE::DEPTH:
|
|
||||||
usage |= vk::ImageUsageFlagBits::eDepthStencilAttachment;
|
|
||||||
imageAspectFlags |= vk::ImageAspectFlagBits::eDepth;
|
|
||||||
break;
|
|
||||||
case SH_ATT_DESC_TYPE::STENCIL:
|
|
||||||
usage |= vk::ImageUsageFlagBits::eDepthStencilAttachment;
|
|
||||||
imageAspectFlags |= vk::ImageAspectFlagBits::eStencil;
|
|
||||||
break;
|
|
||||||
case SH_ATT_DESC_TYPE::DEPTH_STENCIL:
|
|
||||||
usage |= vk::ImageUsageFlagBits::eDepthStencilAttachment;
|
|
||||||
imageAspectFlags |= vk::ImageAspectFlagBits::eStencil | vk::ImageAspectFlagBits::eDepth;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// The resource is not a swapchain image, just use the first slot of the vector
|
|
||||||
images.push_back(logicalDevice->CreateImage(width, height, mipLevels, resourceFormat, usage, createFlags));
|
|
||||||
|
|
||||||
// prepare image view details
|
|
||||||
SHImageViewDetails viewDetails
|
|
||||||
{
|
|
||||||
.viewType = vk::ImageViewType::e2D,
|
|
||||||
.format = images[0]->GetImageFormat(),
|
|
||||||
.imageAspectFlags = imageAspectFlags,
|
|
||||||
.baseMipLevel = 0,
|
|
||||||
.mipLevelCount = mipLevels,
|
|
||||||
.baseArrayLayer = 0,
|
|
||||||
.layerCount = 1,
|
|
||||||
};
|
|
||||||
|
|
||||||
// just 1 image view created
|
|
||||||
imageViews.push_back(images[0]->CreateImageView(logicalDevice, images[0], viewDetails));
|
|
||||||
}
|
|
||||||
else // if swapchain image resource
|
|
||||||
{
|
|
||||||
// Prepare image view details
|
|
||||||
SHImageViewDetails viewDetails
|
|
||||||
{
|
|
||||||
.viewType = vk::ImageViewType::e2D,
|
|
||||||
.format = swapchain->GetSurfaceFormatKHR().format,
|
|
||||||
.imageAspectFlags = vk::ImageAspectFlagBits::eColor,
|
|
||||||
.baseMipLevel = 0,
|
|
||||||
.mipLevelCount = 1,
|
|
||||||
.baseArrayLayer = 0,
|
|
||||||
.layerCount = 1,
|
|
||||||
};
|
|
||||||
|
|
||||||
// We want an image handle for every swapchain image
|
|
||||||
images.resize(swapchain->GetNumImages());
|
|
||||||
imageViews.resize(swapchain->GetNumImages());
|
|
||||||
|
|
||||||
for (uint32_t i = 0; i < swapchain->GetNumImages(); ++i)
|
|
||||||
{
|
|
||||||
images[i] = swapchain->GetSwapchainImage(i);
|
|
||||||
imageViews[i] = images[i]->CreateImageView(logicalDevice, images[i], viewDetails);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
/*!
|
|
||||||
|
|
||||||
\brief
|
|
||||||
Move ctor for resource.
|
|
||||||
|
|
||||||
\param rhs
|
|
||||||
The other resource.
|
|
||||||
|
|
||||||
*/
|
|
||||||
/***************************************************************************/
|
|
||||||
SHRenderGraphResource::SHRenderGraphResource(SHRenderGraphResource&& rhs) noexcept
|
|
||||||
: resourceName{ std::move(rhs.resourceName) }
|
|
||||||
, resourceType{ std::move(rhs.resourceType) }
|
|
||||||
, images{ std::move(rhs.images) }
|
|
||||||
, imageViews{ std::move(rhs.imageViews) }
|
|
||||||
, resourceFormat{ std::move(rhs.resourceFormat) }
|
|
||||||
, width{ rhs.width }
|
|
||||||
, height{ rhs.height }
|
|
||||||
, mipLevels{ rhs.mipLevels }
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
/*!
|
|
||||||
|
|
||||||
\brief
|
|
||||||
Move assignment operator.
|
|
||||||
|
|
||||||
\param rhs
|
|
||||||
The other resource.
|
|
||||||
|
|
||||||
\return
|
|
||||||
|
|
||||||
*/
|
|
||||||
/***************************************************************************/
|
|
||||||
SHRenderGraphResource& SHRenderGraphResource::operator=(SHRenderGraphResource&& rhs) noexcept
|
|
||||||
{
|
|
||||||
if (this == &rhs)
|
|
||||||
return *this;
|
|
||||||
|
|
||||||
resourceName = std::move(rhs.resourceName);
|
|
||||||
resourceType = std::move(rhs.resourceType);
|
|
||||||
images = std::move(rhs.images);
|
|
||||||
imageViews = std::move(rhs.imageViews);
|
|
||||||
resourceFormat = std::move(rhs.resourceFormat);
|
|
||||||
width = rhs.width;
|
|
||||||
height = rhs.height;
|
|
||||||
mipLevels = rhs.mipLevels;
|
|
||||||
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
/*!
|
|
||||||
|
|
||||||
\brief
|
|
||||||
Destructor for resource.
|
|
||||||
|
|
||||||
*/
|
|
||||||
/***************************************************************************/
|
|
||||||
SHRenderGraphResource::~SHRenderGraphResource(void) noexcept
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
/*!
|
|
||||||
|
|
||||||
\brief
|
|
||||||
Subpass non-default constructor. Simply initializes variables.
|
|
||||||
|
|
||||||
\param mapping
|
|
||||||
Mapping from a resource handle to an attachment reference referencing
|
|
||||||
the resource.
|
|
||||||
|
|
||||||
\param resources
|
|
||||||
A mapping from string to render graph resource.
|
|
||||||
|
|
||||||
*/
|
|
||||||
/***************************************************************************/
|
|
||||||
SHSubpass::SHSubpass(ResourceManager& rm, Handle<SHRenderGraphNode> const& parent, uint32_t index, std::unordered_map<uint64_t, uint32_t> const* mapping, std::unordered_map<std::string, Handle<SHRenderGraphResource>> const* resources) noexcept
|
|
||||||
: resourceAttachmentMapping{ mapping }
|
|
||||||
, ptrToResources{ resources }
|
|
||||||
, parentNode{ parent }
|
|
||||||
, subpassIndex{ index }
|
|
||||||
, superBatch{}
|
|
||||||
, colorReferences{}
|
|
||||||
, depthReferences{}
|
|
||||||
, inputReferences{}
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
/*!
|
|
||||||
|
|
||||||
\brief
|
|
||||||
Move constructor for subpass.
|
|
||||||
|
|
||||||
\param rhs
|
|
||||||
The subpass the move from.
|
|
||||||
|
|
||||||
*/
|
|
||||||
/***************************************************************************/
|
|
||||||
SHSubpass::SHSubpass(SHSubpass&& rhs) noexcept
|
|
||||||
: subpassIndex{ std::move(rhs.subpassIndex) }
|
|
||||||
, parentNode{ std::move(rhs.parentNode) }
|
|
||||||
, superBatch{ std::move(rhs.superBatch) }
|
|
||||||
, colorReferences{ std::move(rhs.colorReferences) }
|
|
||||||
, depthReferences{ std::move(rhs.depthReferences) }
|
|
||||||
, inputReferences{ std::move(rhs.inputReferences) }
|
|
||||||
, resourceAttachmentMapping{ rhs.resourceAttachmentMapping }
|
|
||||||
, ptrToResources{ rhs.ptrToResources }
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
/*!
|
|
||||||
|
|
||||||
\brief
|
|
||||||
Move assignment operator for subpass.
|
|
||||||
|
|
||||||
\param rhs
|
|
||||||
subpass to move from.
|
|
||||||
|
|
||||||
*/
|
|
||||||
/***************************************************************************/
|
|
||||||
SHSubpass& SHSubpass::operator=(SHSubpass&& rhs) noexcept
|
|
||||||
{
|
|
||||||
if (this == &rhs)
|
|
||||||
return *this;
|
|
||||||
|
|
||||||
subpassIndex = std::move(rhs.subpassIndex);
|
|
||||||
parentNode = std::move(rhs.parentNode);
|
|
||||||
superBatch = std::move(rhs.superBatch);
|
|
||||||
colorReferences = std::move(rhs.colorReferences);
|
|
||||||
depthReferences = std::move(rhs.depthReferences);
|
|
||||||
inputReferences = std::move(rhs.inputReferences);
|
|
||||||
resourceAttachmentMapping = rhs.resourceAttachmentMapping;
|
|
||||||
ptrToResources = rhs.ptrToResources;
|
|
||||||
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
/*!
|
|
||||||
|
|
||||||
\brief
|
|
||||||
Adds a color output to a subpass. Takes in a string and finds the
|
|
||||||
attachment index to create the vk::SubpassReference.
|
|
||||||
|
|
||||||
\param resourceToReference
|
|
||||||
Resource name to find resource to attach.
|
|
||||||
|
|
||||||
*/
|
|
||||||
/***************************************************************************/
|
|
||||||
void SHSubpass::AddColorOutput(std::string resourceToReference) noexcept
|
|
||||||
{
|
|
||||||
colorReferences.push_back({ resourceAttachmentMapping->at(ptrToResources->at(resourceToReference).GetId().Raw), vk::ImageLayout::eColorAttachmentOptimal });
|
|
||||||
}
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
/*!
|
|
||||||
|
|
||||||
\brief
|
|
||||||
Adds a depth output to a subpass. Takes in a string and finds the
|
|
||||||
attachment index to create the vk::SubpassReference.
|
|
||||||
|
|
||||||
\param resourceToReference
|
|
||||||
Resource name to find resource to attach.
|
|
||||||
|
|
||||||
\param attachmentDescriptionType
|
|
||||||
Depending on the type of the resource, initialize the image layout
|
|
||||||
appropriately.
|
|
||||||
|
|
||||||
*/
|
|
||||||
/***************************************************************************/
|
|
||||||
void SHSubpass::AddDepthOutput(std::string resourceToReference, SH_ATT_DESC_TYPE attachmentDescriptionType) noexcept
|
|
||||||
{
|
|
||||||
vk::ImageLayout imageLayout;
|
|
||||||
switch (attachmentDescriptionType)
|
|
||||||
{
|
|
||||||
case SH_ATT_DESC_TYPE::DEPTH:
|
|
||||||
imageLayout = vk::ImageLayout::eDepthAttachmentOptimal;
|
|
||||||
break;
|
|
||||||
case SH_ATT_DESC_TYPE::STENCIL:
|
|
||||||
imageLayout = vk::ImageLayout::eStencilAttachmentOptimal;
|
|
||||||
break;
|
|
||||||
case SH_ATT_DESC_TYPE::DEPTH_STENCIL:
|
|
||||||
imageLayout = vk::ImageLayout::eDepthStencilAttachmentOptimal;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
//Invalid
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
depthReferences.push_back({ resourceAttachmentMapping->at(ptrToResources->at(resourceToReference).GetId().Raw), imageLayout });
|
|
||||||
}
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
/*!
|
|
||||||
|
|
||||||
\brief
|
|
||||||
Adds a input output to a subpass. Takes in a string and finds the
|
|
||||||
attachment index to create the vk::SubpassReference.
|
|
||||||
|
|
||||||
\param resourceToReference
|
|
||||||
Resource name to find resource to attach.
|
|
||||||
|
|
||||||
*/
|
|
||||||
/***************************************************************************/
|
|
||||||
void SHSubpass::AddInput(std::string resourceToReference) noexcept
|
|
||||||
{
|
|
||||||
inputReferences.push_back({ resourceAttachmentMapping->at(ptrToResources->at(resourceToReference).GetId().Raw), vk::ImageLayout::eShaderReadOnlyOptimal });
|
|
||||||
}
|
|
||||||
|
|
||||||
void SHSubpass::Execute(Handle<SHVkCommandBuffer>& commandBuffer, uint32_t frameIndex) noexcept
|
|
||||||
{
|
|
||||||
// Ensure correct transforms are provided
|
|
||||||
superBatch->UpdateBuffers(frameIndex);
|
|
||||||
|
|
||||||
// Draw all the batches
|
|
||||||
superBatch->Draw(commandBuffer, frameIndex);
|
|
||||||
|
|
||||||
// Draw all the exterior draw calls
|
|
||||||
for (auto& drawCall : exteriorDrawCalls)
|
|
||||||
{
|
|
||||||
drawCall(commandBuffer);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void SHSubpass::AddExteriorDrawCalls(std::function<void(Handle<SHVkCommandBuffer>&)> const& newDrawCall) noexcept
|
|
||||||
{
|
|
||||||
exteriorDrawCalls.push_back(newDrawCall);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SHSubpass::Init(ResourceManager& resourceManager) noexcept
|
|
||||||
{
|
|
||||||
superBatch = resourceManager.Create<SHSuperBatch>(GetHandle());
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
/*!
|
|
||||||
|
|
||||||
\brief
|
|
||||||
Getter for parent renderpass.
|
|
||||||
|
|
||||||
\return
|
|
||||||
Returns the parent renderpass the subpass belongs to.
|
|
||||||
|
|
||||||
*/
|
|
||||||
/***************************************************************************/
|
|
||||||
Handle<SHRenderGraphNode> const& SHSubpass::GetParentNode(void) const noexcept
|
|
||||||
{
|
|
||||||
return parentNode;
|
|
||||||
}
|
|
||||||
|
|
||||||
SHADE::SHSubPassIndex SHSubpass::GetIndex() const noexcept
|
|
||||||
{
|
|
||||||
return subpassIndex;
|
|
||||||
}
|
|
||||||
|
|
||||||
Handle<SHSuperBatch> SHSubpass::GetSuperBatch(void) const noexcept
|
|
||||||
{
|
|
||||||
return superBatch;
|
|
||||||
}
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
/*!
|
|
||||||
|
|
||||||
\brief
|
|
||||||
Creates a renderpass for the node. Uses subpass and attachment
|
|
||||||
descriptions already configured beforehand in the render graph.
|
|
||||||
|
|
||||||
*/
|
|
||||||
/***************************************************************************/
|
|
||||||
void SHRenderGraphNode::CreateRenderpass(void) noexcept
|
|
||||||
{
|
|
||||||
renderpass = logicalDeviceHdl->CreateRenderpass(attachmentDescriptions, spDescs, spDeps);
|
|
||||||
}
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
/*!
|
|
||||||
|
|
||||||
\brief
|
|
||||||
Creates a framebuffer from the images used in the renderpass.
|
|
||||||
|
|
||||||
*/
|
|
||||||
/***************************************************************************/
|
|
||||||
void SHRenderGraphNode::CreateFramebuffer(void) noexcept
|
|
||||||
{
|
|
||||||
for (uint32_t i = 0; i < framebuffers.size(); ++i)
|
|
||||||
{
|
|
||||||
std::vector<Handle<SHVkImageView>> imageViews(attResources.size());
|
|
||||||
uint32_t fbWidth = std::numeric_limits<uint32_t>::max();
|
|
||||||
uint32_t fbHeight = std::numeric_limits<uint32_t>::max();
|
|
||||||
|
|
||||||
for (uint32_t j = 0; j < attResources.size(); ++j)
|
|
||||||
{
|
|
||||||
uint32_t imageViewIndex = (attResources[j]->resourceType == SH_ATT_DESC_TYPE::COLOR_PRESENT) ? i : 0;
|
|
||||||
imageViews[j] = attResources[j]->imageViews[imageViewIndex];
|
|
||||||
|
|
||||||
// We want the minimum dimensions for the framebuffer because the image attachments referenced cannot have dimensions smaller than the framebuffer's
|
|
||||||
if (fbWidth > attResources[j]->width)
|
|
||||||
fbWidth = attResources[j]->width;
|
|
||||||
if (fbHeight > attResources[j]->height)
|
|
||||||
fbHeight = attResources[j]->height;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
framebuffers[i] = logicalDeviceHdl->CreateFramebuffer(renderpass, imageViews, fbWidth, fbHeight);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
/*!
|
|
||||||
|
|
||||||
\brief
|
|
||||||
Render Graph node constructor. Note that we do not create the renderpass
|
|
||||||
yet. This is because layouts of attachment descriptions facilitate image
|
|
||||||
transitions and we cannot know guarantee layouts until we've seen all
|
|
||||||
renderpasses and their subpasses in the graph.
|
|
||||||
|
|
||||||
\param swapchain
|
|
||||||
Swapchain required to query number of images as parameters for number
|
|
||||||
of framebuffers to create.
|
|
||||||
|
|
||||||
\param attachmentDescriptionTypes
|
|
||||||
|
|
||||||
|
|
||||||
\return
|
|
||||||
|
|
||||||
*/
|
|
||||||
/***************************************************************************/
|
|
||||||
SHRenderGraphNode::SHRenderGraphNode(ResourceManager& rm, Handle<SHVkLogicalDevice> const& logicalDevice, Handle<SHVkSwapchain> const& swapchain, std::vector<Handle<SHRenderGraphResource>> attRes, std::vector<Handle<SHRenderGraphNode>> predecessors, std::unordered_map<std::string, Handle<SHRenderGraphResource>> const* resources, Handle<SHGraphicsGlobalData> globalData) noexcept
|
|
||||||
: logicalDeviceHdl{ logicalDevice }
|
|
||||||
, renderpass{}
|
|
||||||
, framebuffers{}
|
|
||||||
, prereqNodes{ std::move(predecessors) }
|
|
||||||
, attachmentDescriptions{}
|
|
||||||
, resourceAttachmentMapping{}
|
|
||||||
, attResources{ std::move(attRes) }
|
|
||||||
, subpasses{}
|
|
||||||
, executed{ false }
|
|
||||||
, configured{ false }
|
|
||||||
, resourceManager{ rm }
|
|
||||||
, ptrToResources{ resources }
|
|
||||||
{
|
|
||||||
// pipeline library initialization
|
|
||||||
pipelineLibrary.Init(logicalDeviceHdl, globalData);
|
|
||||||
|
|
||||||
attachmentDescriptions.resize(attResources.size());
|
|
||||||
|
|
||||||
bool containsSwapchainImage = false;
|
|
||||||
for (uint32_t i = 0; i < attResources.size(); ++i)
|
|
||||||
{
|
|
||||||
// As mentioned above we don't initialize much here because it's dependent on how other renderpasses are configured.
|
|
||||||
vk::AttachmentDescription& newDesc = attachmentDescriptions[i];
|
|
||||||
newDesc.samples = vk::SampleCountFlagBits::e1;
|
|
||||||
|
|
||||||
// We set this to clear first. If later we find out that some predecessor is writing to the same attachment,
|
|
||||||
// we set the pred's storeOp to eStore and "this" loadOp to eLoad.
|
|
||||||
newDesc.loadOp = vk::AttachmentLoadOp::eClear;
|
|
||||||
newDesc.storeOp = vk::AttachmentStoreOp::eStore;
|
|
||||||
|
|
||||||
newDesc.stencilLoadOp = vk::AttachmentLoadOp::eClear;
|
|
||||||
newDesc.stencilStoreOp = vk::AttachmentStoreOp::eStore;
|
|
||||||
|
|
||||||
newDesc.format = attResources[i]->resourceFormat;
|
|
||||||
|
|
||||||
if (attResources[i]->resourceType == SH_ATT_DESC_TYPE::COLOR_PRESENT)
|
|
||||||
containsSwapchainImage = true;
|
|
||||||
|
|
||||||
resourceAttachmentMapping.try_emplace(attResources[i].GetId().Raw, i);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!containsSwapchainImage)
|
|
||||||
framebuffers.resize(1);
|
|
||||||
else
|
|
||||||
framebuffers.resize(swapchain->GetNumImages());
|
|
||||||
|
|
||||||
// At this point, we could configure framebuffers if we had the renderpass object but we don't so their creation has to be
|
|
||||||
// deferred to when renderpasses are also created.
|
|
||||||
}
|
|
||||||
|
|
||||||
SHRenderGraphNode::SHRenderGraphNode(SHRenderGraphNode&& rhs) noexcept
|
|
||||||
: resourceManager{ rhs.resourceManager }
|
|
||||||
, logicalDeviceHdl{ rhs.logicalDeviceHdl }
|
|
||||||
, renderpass{ rhs.renderpass }
|
|
||||||
, framebuffers{ std::move(rhs.framebuffers) }
|
|
||||||
, prereqNodes{ std::move(rhs.prereqNodes) }
|
|
||||||
, attachmentDescriptions{ std::move(rhs.attachmentDescriptions) }
|
|
||||||
, attResources{ std::move(rhs.attResources) }
|
|
||||||
, subpasses{ std::move(rhs.subpasses) }
|
|
||||||
, resourceAttachmentMapping{ std::move(rhs.resourceAttachmentMapping) }
|
|
||||||
, subpassIndexing{ std::move(rhs.subpassIndexing) }
|
|
||||||
, configured{ rhs.configured }
|
|
||||||
, executed{ rhs.executed }
|
|
||||||
, ptrToResources{ rhs.ptrToResources }
|
|
||||||
, pipelineLibrary{ std::move(rhs.pipelineLibrary) }
|
|
||||||
, batcher { std::move(rhs.batcher) }
|
|
||||||
|
|
||||||
{
|
|
||||||
rhs.renderpass = {};
|
|
||||||
}
|
|
||||||
|
|
||||||
SHRenderGraphNode& SHRenderGraphNode::operator=(SHRenderGraphNode&& rhs) noexcept
|
|
||||||
{
|
|
||||||
if (&rhs == this)
|
|
||||||
return *this;
|
|
||||||
|
|
||||||
resourceManager = rhs.resourceManager;
|
|
||||||
logicalDeviceHdl = rhs.logicalDeviceHdl;
|
|
||||||
renderpass = rhs.renderpass;
|
|
||||||
framebuffers = std::move(rhs.framebuffers);
|
|
||||||
prereqNodes = std::move(rhs.prereqNodes);
|
|
||||||
attachmentDescriptions = std::move(rhs.attachmentDescriptions);
|
|
||||||
attResources = std::move(rhs.attResources);
|
|
||||||
subpasses = std::move(rhs.subpasses);
|
|
||||||
resourceAttachmentMapping = std::move(rhs.resourceAttachmentMapping);
|
|
||||||
subpassIndexing = std::move(rhs.subpassIndexing);
|
|
||||||
ptrToResources = std::move(rhs.ptrToResources);
|
|
||||||
pipelineLibrary = std::move(rhs.pipelineLibrary);
|
|
||||||
batcher = std::move(rhs.batcher);
|
|
||||||
|
|
||||||
rhs.renderpass = {};
|
|
||||||
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
/*!
|
|
||||||
|
|
||||||
\brief
|
|
||||||
Add subpasses to the renderpass and returns a reference to it.
|
|
||||||
|
|
||||||
\param subpassName
|
|
||||||
Name of the subpass.
|
|
||||||
|
|
||||||
\return
|
|
||||||
Handle to the new subpass.
|
|
||||||
|
|
||||||
*/
|
|
||||||
/***************************************************************************/
|
|
||||||
Handle<SHSubpass> SHRenderGraphNode::AddSubpass(std::string subpassName) noexcept
|
|
||||||
{
|
|
||||||
// if subpass already exists, don't add.
|
|
||||||
if (subpassIndexing.contains(subpassName))
|
|
||||||
{
|
|
||||||
SHLOG_ERROR("Subpass already exists.");
|
|
||||||
return{};
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add subpass to container and create mapping for it
|
|
||||||
subpasses.emplace_back(resourceManager.Create<SHSubpass>(resourceManager, GetHandle(), subpasses.size(), &resourceAttachmentMapping, ptrToResources));
|
|
||||||
subpassIndexing.try_emplace(subpassName, static_cast<uint32_t>(subpasses.size()) - 1u);
|
|
||||||
Handle<SHSubpass> subpass = subpasses.back();
|
|
||||||
subpass->Init(resourceManager);
|
|
||||||
|
|
||||||
// Register the SuperBatch
|
|
||||||
batcher.RegisterSuperBatch(subpass->GetSuperBatch());
|
|
||||||
|
|
||||||
return subpass;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SHRenderGraphNode::Execute(Handle<SHVkCommandBuffer>& commandBuffer, uint32_t frameIndex) noexcept
|
|
||||||
{
|
|
||||||
frameIndex = (framebuffers.size() > 1) ? frameIndex : 0;
|
|
||||||
commandBuffer->BeginRenderpass(renderpass, framebuffers[frameIndex]);
|
|
||||||
|
|
||||||
for (uint32_t i = 0; i < subpasses.size(); ++i)
|
|
||||||
{
|
|
||||||
subpasses[i]->Execute(commandBuffer, frameIndex);
|
|
||||||
|
|
||||||
// Go to next subpass if not last subpass
|
|
||||||
if (i != subpasses.size() - 1)
|
|
||||||
commandBuffer->NextSubpass();
|
|
||||||
}
|
|
||||||
|
|
||||||
commandBuffer->EndRenderpass();
|
|
||||||
}
|
|
||||||
|
|
||||||
Handle<SHVkPipeline> SHRenderGraphNode::GetOrCreatePipeline(std::pair<Handle<SHVkShaderModule>, Handle<SHVkShaderModule>> const& vsFsPair, Handle<SHSubpass> subpass) noexcept
|
|
||||||
{
|
|
||||||
// verify subpass exists
|
|
||||||
if (subpass->GetIndex() >= subpasses.size())
|
|
||||||
{
|
|
||||||
SHLOG_ERROR("Subpass index passed in is not valid. RenderGraphNode does not have that many passes. ");
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
Handle<SHVkPipeline> pipeline = pipelineLibrary.GetDrawPipline(vsFsPair);
|
|
||||||
if (!pipeline)
|
|
||||||
{
|
|
||||||
pipeline = pipelineLibrary.CreateDrawPipeline
|
|
||||||
(
|
|
||||||
vsFsPair,
|
|
||||||
renderpass,
|
|
||||||
subpass
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return pipeline;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SHRenderGraphNode::FinaliseBatch(uint32_t frameIndex)
|
|
||||||
{
|
|
||||||
batcher.FinaliseBatches(logicalDeviceHdl, frameIndex);
|
|
||||||
}
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
/*!
|
|
||||||
|
|
||||||
\brief
|
|
||||||
Get the renderpass from the node.
|
|
||||||
|
|
||||||
\return
|
|
||||||
Handle to the renderpass.
|
|
||||||
|
|
||||||
*/
|
|
||||||
/***************************************************************************/
|
|
||||||
Handle<SHVkRenderpass> SHRenderGraphNode::GetRenderpass(void) const noexcept
|
|
||||||
{
|
|
||||||
return renderpass;
|
|
||||||
}
|
|
||||||
|
|
||||||
Handle<SHSubpass> SHRenderGraphNode::GetSubpass(std::string_view subpassName) const noexcept
|
|
||||||
{
|
|
||||||
return subpasses[subpassIndexing.at(subpassName.data())];
|
|
||||||
}
|
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
/*!
|
/*!
|
||||||
|
@ -779,7 +131,7 @@ namespace SHADE
|
||||||
attDesc.loadOp = vk::AttachmentLoadOp::eLoad;
|
attDesc.loadOp = vk::AttachmentLoadOp::eLoad;
|
||||||
predAttDesc.storeOp = vk::AttachmentStoreOp::eStore;
|
predAttDesc.storeOp = vk::AttachmentStoreOp::eStore;
|
||||||
|
|
||||||
// TODO: Stecil load and store
|
// TODO: Stencil load and store
|
||||||
|
|
||||||
// When an image is done being used in a renderpass, the image layout will end up being the finalLayout
|
// When an image is done being used in a renderpass, the image layout will end up being the finalLayout
|
||||||
// value of the attachment description. We want this to carry over to the next renderpass; specifically
|
// value of the attachment description. We want this to carry over to the next renderpass; specifically
|
||||||
|
@ -976,11 +328,10 @@ namespace SHADE
|
||||||
|
|
||||||
*/
|
*/
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
void SHRenderGraph::Init(Handle<SHVkLogicalDevice> const& logicalDevice, Handle<SHVkSwapchain> const& swapchain, Handle<SHGraphicsGlobalData> inGlobalData) noexcept
|
void SHRenderGraph::Init(Handle<SHVkLogicalDevice> const& logicalDevice, Handle<SHVkSwapchain> const& swapchain) noexcept
|
||||||
{
|
{
|
||||||
logicalDeviceHdl = logicalDevice;
|
logicalDeviceHdl = logicalDevice;
|
||||||
swapchainHdl = swapchain;
|
swapchainHdl = swapchain;
|
||||||
globalData = inGlobalData;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
|
@ -1012,7 +363,6 @@ namespace SHADE
|
||||||
, nodes{ std::move(rhs.nodes) }
|
, nodes{ std::move(rhs.nodes) }
|
||||||
, graphResources{ std::move(rhs.graphResources) }
|
, graphResources{ std::move(rhs.graphResources) }
|
||||||
, resourceManager{ std::move(rhs.resourceManager) }
|
, resourceManager{ std::move(rhs.resourceManager) }
|
||||||
, globalData{ rhs.globalData }
|
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1028,7 +378,6 @@ namespace SHADE
|
||||||
nodes = std::move(rhs.nodes);
|
nodes = std::move(rhs.nodes);
|
||||||
graphResources = std::move(rhs.graphResources);
|
graphResources = std::move(rhs.graphResources);
|
||||||
resourceManager = std::move(rhs.resourceManager);
|
resourceManager = std::move(rhs.resourceManager);
|
||||||
globalData = rhs.globalData;
|
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
@ -1086,7 +435,7 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
nodes.emplace_back(resourceManager.Create<SHRenderGraphNode>(resourceManager, logicalDeviceHdl, swapchainHdl, std::move(resources), std::move(predecessors), &graphResources, globalData));
|
nodes.emplace_back(resourceManager.Create<SHRenderGraphNode>(resourceManager, logicalDeviceHdl, swapchainHdl, std::move(resources), std::move(predecessors), &graphResources));
|
||||||
nodeIndexing.emplace(nodeName, static_cast<uint32_t>(nodes.size()) - 1u);
|
nodeIndexing.emplace(nodeName, static_cast<uint32_t>(nodes.size()) - 1u);
|
||||||
return nodes.at(nodeIndexing[nodeName]);
|
return nodes.at(nodeIndexing[nodeName]);
|
||||||
}
|
}
|
||||||
|
@ -1114,20 +463,20 @@ namespace SHADE
|
||||||
|
|
||||||
// TODO: The graph scope buffers were meant to bind vertex buffers and index buffers for meshes. Find a
|
// TODO: The graph scope buffers were meant to bind vertex buffers and index buffers for meshes. Find a
|
||||||
// better way to manage these
|
// better way to manage these
|
||||||
void SHRenderGraph::Execute(uint32_t frameIndex, Handle<SHVkCommandBuffer> cmdBuffer) noexcept
|
void SHRenderGraph::Execute(uint32_t frameIndex, Handle<SHVkCommandBuffer> cmdBuffer, Handle<SHVkDescriptorPool> descPool) noexcept
|
||||||
{
|
{
|
||||||
// TODO: DON'T HARDCODE THIS
|
// TODO: DON'T HARDCODE THIS
|
||||||
cmdBuffer->SetViewportScissor(1920.0f, 1080.0f, 1920, 1080);
|
cmdBuffer->SetViewportScissor(1920.0f, 1080.0f, 1920, 1080);
|
||||||
|
|
||||||
for (auto& node : nodes)
|
for (auto& node : nodes)
|
||||||
node->Execute(cmdBuffer, frameIndex);
|
node->Execute(cmdBuffer, descPool, frameIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHRenderGraph::FinaliseBatch(uint32_t frameIndex)
|
void SHRenderGraph::FinaliseBatch(uint32_t frameIndex, Handle<SHVkDescriptorPool> descPool)
|
||||||
{
|
{
|
||||||
for (auto& node : nodes)
|
for (auto& node : nodes)
|
||||||
{
|
{
|
||||||
node->FinaliseBatch(frameIndex);
|
node->FinaliseBatch(frameIndex, descPool);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,12 @@
|
||||||
#include "Graphics/MiddleEnd/Pipeline/SHPipelineLibrary.h"
|
#include "Graphics/MiddleEnd/Pipeline/SHPipelineLibrary.h"
|
||||||
#include "Graphics/MiddleEnd/Batching/SHSuperBatch.h"
|
#include "Graphics/MiddleEnd/Batching/SHSuperBatch.h"
|
||||||
#include "../MiddleEnd/Batching/SHBatcher.h"
|
#include "../MiddleEnd/Batching/SHBatcher.h"
|
||||||
|
#include "SHRenderGraphNode.h"
|
||||||
|
#include "SHSubpass.h"
|
||||||
|
#include "SHRenderGraphResource.h"
|
||||||
|
#include "SHRenderGraphNode.h"
|
||||||
|
#include "SHSubpass.h"
|
||||||
|
#include "SHAttachmentDescriptionType.h"
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
@ -24,223 +30,6 @@ namespace SHADE
|
||||||
class SHRenderGraphNode;
|
class SHRenderGraphNode;
|
||||||
class SHGraphicsGlobalData;
|
class SHGraphicsGlobalData;
|
||||||
|
|
||||||
// Used for attachment description creation for renderpass node
|
|
||||||
enum class SH_ATT_DESC_TYPE
|
|
||||||
{
|
|
||||||
COLOR,
|
|
||||||
COLOR_PRESENT,
|
|
||||||
DEPTH,
|
|
||||||
STENCIL,
|
|
||||||
DEPTH_STENCIL,
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
class SH_API SHRenderGraphResource
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
/*-----------------------------------------------------------------------*/
|
|
||||||
/* PRIVATE MEMBER VARIABLES */
|
|
||||||
/*-----------------------------------------------------------------------*/
|
|
||||||
//! Name of the resource
|
|
||||||
std::string resourceName;
|
|
||||||
|
|
||||||
//! Used for initializing image layouts
|
|
||||||
SH_ATT_DESC_TYPE resourceType;
|
|
||||||
|
|
||||||
//! The resource itself (this is a vector because if the resource happens
|
|
||||||
//! to be a swapchain image, then we need however many frames in flight).
|
|
||||||
//! However when it's not a swapchain image, we want this container to be size 1
|
|
||||||
//! because writing to these images will not interfere with images in the previous
|
|
||||||
//! frame, unlike the swapchain image.
|
|
||||||
std::vector<Handle<SHVkImage>> images;
|
|
||||||
|
|
||||||
//! Views to resources (vector because same rationale as images. see above).
|
|
||||||
std::vector<Handle<SHVkImageView>> imageViews;
|
|
||||||
|
|
||||||
//! Image format
|
|
||||||
vk::Format resourceFormat;
|
|
||||||
|
|
||||||
//! width of the resource
|
|
||||||
uint32_t width;
|
|
||||||
|
|
||||||
//! Height of the resource
|
|
||||||
uint32_t height;
|
|
||||||
|
|
||||||
//! Number of mipmap levels
|
|
||||||
uint8_t mipLevels;
|
|
||||||
public:
|
|
||||||
/*-----------------------------------------------------------------------*/
|
|
||||||
/* CTORS AND DTORS */
|
|
||||||
/*-----------------------------------------------------------------------*/
|
|
||||||
SHRenderGraphResource(Handle<SHVkLogicalDevice> const& logicalDevice, Handle<SHVkSwapchain> const& swapchain, std::string const& name, SH_ATT_DESC_TYPE type, vk::Format format, uint32_t w, uint32_t h, uint8_t levels, vk::ImageCreateFlagBits createFlags) noexcept;
|
|
||||||
SHRenderGraphResource(SHRenderGraphResource&& rhs) noexcept;
|
|
||||||
SHRenderGraphResource& operator=(SHRenderGraphResource&& rhs) noexcept;
|
|
||||||
~SHRenderGraphResource(void) noexcept;
|
|
||||||
|
|
||||||
friend class SHRenderGraphNode;
|
|
||||||
friend class SHRenderGraph;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
class SH_API SHSubpass : public ISelfHandle<SHSubpass>
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
/*---------------------------------------------------------------------*/
|
|
||||||
/* PRIVATE MEMBER VARIABLES */
|
|
||||||
/*---------------------------------------------------------------------*/
|
|
||||||
//! The index of the subpass in the render graph
|
|
||||||
uint32_t subpassIndex;
|
|
||||||
|
|
||||||
//! The parent renderpass that this subpass belongs to
|
|
||||||
Handle<SHRenderGraphNode> parentNode;
|
|
||||||
|
|
||||||
//!
|
|
||||||
Handle<SHSuperBatch> superBatch;
|
|
||||||
|
|
||||||
//! Color attachments
|
|
||||||
std::vector<vk::AttachmentReference> colorReferences;
|
|
||||||
|
|
||||||
//! Depth attachments
|
|
||||||
std::vector<vk::AttachmentReference> depthReferences;
|
|
||||||
|
|
||||||
//! Input attachments
|
|
||||||
std::vector<vk::AttachmentReference> inputReferences;
|
|
||||||
|
|
||||||
//! For getting attachment reference indices using handles
|
|
||||||
std::unordered_map<uint64_t, uint32_t> const* resourceAttachmentMapping;
|
|
||||||
|
|
||||||
//! Pointer to resources in the render graph (for getting handle IDs)
|
|
||||||
std::unordered_map<std::string, Handle<SHRenderGraphResource>> const* ptrToResources;
|
|
||||||
|
|
||||||
//! Sometimes there exists entities that we want to render onto a render target
|
|
||||||
//! but don't want it to come from the batching system. An example would be ImGUI.
|
|
||||||
//! For these entities we want to link a function from the outside and draw them
|
|
||||||
//! after we draw everything from the batch. Because of this, these draw calls
|
|
||||||
//! are always the last things drawn, so DO NOT USE THIS FUNCTIONALITY FOR ANYTHING
|
|
||||||
//! COMPLEX.
|
|
||||||
std::vector<std::function<void(Handle<SHVkCommandBuffer>&)>> exteriorDrawCalls;
|
|
||||||
|
|
||||||
public:
|
|
||||||
/*-----------------------------------------------------------------------*/
|
|
||||||
/* CTORS AND DTORS */
|
|
||||||
/*-----------------------------------------------------------------------*/
|
|
||||||
SHSubpass(ResourceManager& rm, Handle<SHRenderGraphNode> const& parent, uint32_t index, std::unordered_map<uint64_t, uint32_t> const* mapping, std::unordered_map<std::string, Handle<SHRenderGraphResource>> const* ptrToResources) noexcept;
|
|
||||||
SHSubpass(SHSubpass&& rhs) noexcept;
|
|
||||||
SHSubpass& operator=(SHSubpass&& rhs) noexcept;
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------*/
|
|
||||||
/* PUBLIC MEMBER FUNCTIONS */
|
|
||||||
/*-----------------------------------------------------------------------*/
|
|
||||||
// Preparation functions
|
|
||||||
void AddColorOutput(std::string resourceToReference) noexcept;
|
|
||||||
void AddDepthOutput(std::string resourceToReference, SH_ATT_DESC_TYPE attachmentDescriptionType = SH_ATT_DESC_TYPE::DEPTH_STENCIL) noexcept;
|
|
||||||
void AddInput(std::string resourceToReference) noexcept;
|
|
||||||
|
|
||||||
// Runtime functions
|
|
||||||
void Execute(Handle<SHVkCommandBuffer>& commandBuffer, uint32_t frameIndex) noexcept;
|
|
||||||
void AddExteriorDrawCalls(std::function<void(Handle<SHVkCommandBuffer>&)> const& newDrawCall) noexcept;
|
|
||||||
|
|
||||||
void Init (ResourceManager& resourceManager) noexcept;
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------*/
|
|
||||||
/* GETTERS AND SETTERS */
|
|
||||||
/*-----------------------------------------------------------------------*/
|
|
||||||
Handle<SHRenderGraphNode> const& GetParentNode(void) const noexcept;
|
|
||||||
SHSubPassIndex GetIndex() const noexcept;
|
|
||||||
Handle<SHSuperBatch> GetSuperBatch (void) const noexcept;
|
|
||||||
|
|
||||||
|
|
||||||
friend class SHRenderGraphNode;
|
|
||||||
friend class SHRenderGraph;
|
|
||||||
};
|
|
||||||
|
|
||||||
class SH_API SHRenderGraphNode : public ISelfHandle<SHRenderGraphNode>
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
/*-----------------------------------------------------------------------*/
|
|
||||||
/* PRIVATE MEMBER VARIABLES */
|
|
||||||
/*-----------------------------------------------------------------------*/
|
|
||||||
ResourceManager& resourceManager;
|
|
||||||
|
|
||||||
//! For Vulkan object creation
|
|
||||||
Handle<SHVkLogicalDevice> logicalDeviceHdl;
|
|
||||||
|
|
||||||
//! Each node will have a renderpass and each renderpass will have its own subpasses.
|
|
||||||
//! These subpasses will execute sequentially.
|
|
||||||
Handle<SHVkRenderpass> renderpass;
|
|
||||||
|
|
||||||
//! Framebuffers used in this renderpass. If renderpass contains usage of a swapchain image
|
|
||||||
//! used for presenting, then we cannot use just 1 framebuffer, we need to have 1 for however many frames in flight.
|
|
||||||
std::vector<Handle<SHVkFramebuffer>> framebuffers;
|
|
||||||
|
|
||||||
//! Nodes that must finish execution before this node is executed will be in this container
|
|
||||||
std::vector<Handle<SHRenderGraphNode>> prereqNodes;
|
|
||||||
|
|
||||||
//! Container of Attachment descriptions
|
|
||||||
std::vector<vk::AttachmentDescription> attachmentDescriptions;
|
|
||||||
|
|
||||||
//! Resources used in this renderpass
|
|
||||||
std::vector<Handle<SHRenderGraphResource>> attResources;
|
|
||||||
|
|
||||||
//! Vector of subpasses
|
|
||||||
std::vector<Handle<SHSubpass>> subpasses;
|
|
||||||
|
|
||||||
//! Descriptions to pass to renderpass for renderpass creation. We want to keep this here because
|
|
||||||
std::vector<vk::SubpassDescription> spDescs;
|
|
||||||
|
|
||||||
//! Subpass dependencies for renderpass creation
|
|
||||||
std::vector<vk::SubpassDependency> spDeps;
|
|
||||||
|
|
||||||
//! For indexing resources fast
|
|
||||||
std::unordered_map<uint64_t, uint32_t> resourceAttachmentMapping;
|
|
||||||
|
|
||||||
//! For indexing subpasses
|
|
||||||
std::map<std::string, uint32_t> subpassIndexing;
|
|
||||||
|
|
||||||
//! Pointer to resources in the render graph (for getting handle IDs)
|
|
||||||
std::unordered_map<std::string, Handle<SHRenderGraphResource>> const* ptrToResources;
|
|
||||||
|
|
||||||
//! Every renderpass will require a pipeline library that will contain pipelines compatible with this renderpass
|
|
||||||
SHPipelineLibrary pipelineLibrary;
|
|
||||||
|
|
||||||
//! Whether or not the node has finished execution
|
|
||||||
bool executed;
|
|
||||||
|
|
||||||
//! Whether or not the node has been configured already or not
|
|
||||||
bool configured;
|
|
||||||
|
|
||||||
SHBatcher batcher;
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------*/
|
|
||||||
/* PRIVATE MEMBER FUNCTIONS */
|
|
||||||
/*-----------------------------------------------------------------------*/
|
|
||||||
void CreateRenderpass (void) noexcept;
|
|
||||||
void CreateFramebuffer(void) noexcept;
|
|
||||||
|
|
||||||
public:
|
|
||||||
/*-----------------------------------------------------------------------*/
|
|
||||||
/* CTORS AND DTORS */
|
|
||||||
/*-----------------------------------------------------------------------*/
|
|
||||||
SHRenderGraphNode (ResourceManager& rm, Handle<SHVkLogicalDevice> const& logicalDevice, Handle<SHVkSwapchain> const& swapchain, std::vector<Handle<SHRenderGraphResource>> attRes, std::vector<Handle<SHRenderGraphNode>> predecessors, std::unordered_map<std::string, Handle<SHRenderGraphResource>> const* resources, Handle<SHGraphicsGlobalData> globalData) noexcept;
|
|
||||||
SHRenderGraphNode(SHRenderGraphNode&& rhs) noexcept;
|
|
||||||
SHRenderGraphNode& operator= (SHRenderGraphNode&& rhs) noexcept;
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------*/
|
|
||||||
/* PUBLIC MEMBER FUNCTIONS */
|
|
||||||
/*-----------------------------------------------------------------------*/
|
|
||||||
Handle<SHSubpass> AddSubpass (std::string subpassName) noexcept;
|
|
||||||
// TODO: RemoveSubpass()
|
|
||||||
void Execute (Handle<SHVkCommandBuffer>& commandBuffer, uint32_t frameIndex) noexcept;
|
|
||||||
Handle<SHVkPipeline> GetOrCreatePipeline (std::pair<Handle<SHVkShaderModule>, Handle<SHVkShaderModule>> const& vsFsPair, Handle<SHSubpass> subpass) noexcept;
|
|
||||||
void FinaliseBatch(uint32_t frameIndex);
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------*/
|
|
||||||
/* SETTERS AND GETTERS */
|
|
||||||
/*-----------------------------------------------------------------------*/
|
|
||||||
Handle<SHVkRenderpass> GetRenderpass (void) const noexcept;
|
|
||||||
Handle<SHSubpass> GetSubpass(std::string_view subpassName) const noexcept;
|
|
||||||
friend class SHRenderGraph;
|
|
||||||
};
|
|
||||||
|
|
||||||
class SH_API SHRenderGraph
|
class SH_API SHRenderGraph
|
||||||
{
|
{
|
||||||
|
@ -272,9 +61,6 @@ namespace SHADE
|
||||||
|
|
||||||
//! Resource library for graph handles
|
//! Resource library for graph handles
|
||||||
ResourceManager resourceManager;
|
ResourceManager resourceManager;
|
||||||
|
|
||||||
//! Handle to global data
|
|
||||||
Handle<SHGraphicsGlobalData> globalData;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
|
@ -288,12 +74,12 @@ namespace SHADE
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
/* PUBLIC MEMBER FUNCTIONS */
|
/* PUBLIC MEMBER FUNCTIONS */
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
void Init (Handle<SHVkLogicalDevice> const& logicalDevice, Handle<SHVkSwapchain> const& swapchain, Handle<SHGraphicsGlobalData> inGlobalData) noexcept;
|
void Init (Handle<SHVkLogicalDevice> const& logicalDevice, Handle<SHVkSwapchain> const& swapchain) noexcept;
|
||||||
void AddResource (std::string resourceName, SH_ATT_DESC_TYPE type, uint32_t w = static_cast<uint32_t>(-1), uint32_t h = static_cast<uint32_t>(-1), vk::Format format = vk::Format::eB8G8R8A8Unorm, uint8_t levels = 1, vk::ImageCreateFlagBits createFlags = {});
|
void AddResource (std::string resourceName, SH_ATT_DESC_TYPE type, uint32_t w = static_cast<uint32_t>(-1), uint32_t h = static_cast<uint32_t>(-1), vk::Format format = vk::Format::eB8G8R8A8Unorm, uint8_t levels = 1, vk::ImageCreateFlagBits createFlags = {});
|
||||||
Handle<SHRenderGraphNode> AddNode (std::string nodeName, std::initializer_list<std::string> resourceNames, std::initializer_list<std::string> predecessorNodes) noexcept;
|
Handle<SHRenderGraphNode> AddNode (std::string nodeName, std::initializer_list<std::string> resourceNames, std::initializer_list<std::string> predecessorNodes) noexcept;
|
||||||
void Generate (void) noexcept;
|
void Generate (void) noexcept;
|
||||||
void Execute (uint32_t frameIndex, Handle<SHVkCommandBuffer> cmdBuffer) noexcept;
|
void Execute (uint32_t frameIndex, Handle<SHVkCommandBuffer> cmdBuffer, Handle<SHVkDescriptorPool> descPool) noexcept;
|
||||||
void FinaliseBatch(uint32_t frameIndex);
|
void FinaliseBatch(uint32_t frameIndex, Handle<SHVkDescriptorPool> descPool);
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
/* SETTERS AND GETTERS */
|
/* SETTERS AND GETTERS */
|
||||||
|
|
|
@ -0,0 +1,276 @@
|
||||||
|
#include "SHpch.h"
|
||||||
|
#include "SHRenderGraphNode.h"
|
||||||
|
#include "Graphics/Devices/SHVkLogicalDevice.h"
|
||||||
|
#include "Graphics/Images/SHVkImageView.h"
|
||||||
|
#include "Graphics/Swapchain/SHVkSwapchain.h"
|
||||||
|
#include "SHRenderGraphResource.h"
|
||||||
|
#include "SHSubpass.h"
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
/*!
|
||||||
|
|
||||||
|
\brief
|
||||||
|
Creates a renderpass for the node. Uses subpass and attachment
|
||||||
|
descriptions already configured beforehand in the render graph.
|
||||||
|
|
||||||
|
*/
|
||||||
|
/***************************************************************************/
|
||||||
|
void SHRenderGraphNode::CreateRenderpass(void) noexcept
|
||||||
|
{
|
||||||
|
renderpass = logicalDeviceHdl->CreateRenderpass(attachmentDescriptions, spDescs, spDeps);
|
||||||
|
}
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
/*!
|
||||||
|
|
||||||
|
\brief
|
||||||
|
Creates a framebuffer from the images used in the renderpass.
|
||||||
|
|
||||||
|
*/
|
||||||
|
/***************************************************************************/
|
||||||
|
void SHRenderGraphNode::CreateFramebuffer(void) noexcept
|
||||||
|
{
|
||||||
|
for (uint32_t i = 0; i < framebuffers.size(); ++i)
|
||||||
|
{
|
||||||
|
std::vector<Handle<SHVkImageView>> imageViews(attResources.size());
|
||||||
|
uint32_t fbWidth = std::numeric_limits<uint32_t>::max();
|
||||||
|
uint32_t fbHeight = std::numeric_limits<uint32_t>::max();
|
||||||
|
|
||||||
|
for (uint32_t j = 0; j < attResources.size(); ++j)
|
||||||
|
{
|
||||||
|
uint32_t imageViewIndex = (attResources[j]->resourceType == SH_ATT_DESC_TYPE::COLOR_PRESENT) ? i : 0;
|
||||||
|
imageViews[j] = attResources[j]->imageViews[imageViewIndex];
|
||||||
|
|
||||||
|
// We want the minimum dimensions for the framebuffer because the image attachments referenced cannot have dimensions smaller than the framebuffer's
|
||||||
|
if (fbWidth > attResources[j]->width)
|
||||||
|
fbWidth = attResources[j]->width;
|
||||||
|
if (fbHeight > attResources[j]->height)
|
||||||
|
fbHeight = attResources[j]->height;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
framebuffers[i] = logicalDeviceHdl->CreateFramebuffer(renderpass, imageViews, fbWidth, fbHeight);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
/*!
|
||||||
|
|
||||||
|
\brief
|
||||||
|
Render Graph node constructor. Note that we do not create the renderpass
|
||||||
|
yet. This is because layouts of attachment descriptions facilitate image
|
||||||
|
transitions and we cannot know guarantee layouts until we've seen all
|
||||||
|
renderpasses and their subpasses in the graph.
|
||||||
|
|
||||||
|
\param swapchain
|
||||||
|
Swapchain required to query number of images as parameters for number
|
||||||
|
of framebuffers to create.
|
||||||
|
|
||||||
|
\param attachmentDescriptionTypes
|
||||||
|
|
||||||
|
|
||||||
|
\return
|
||||||
|
|
||||||
|
*/
|
||||||
|
/***************************************************************************/
|
||||||
|
SHRenderGraphNode::SHRenderGraphNode(ResourceManager& rm, Handle<SHVkLogicalDevice> const& logicalDevice, Handle<SHVkSwapchain> const& swapchain, std::vector<Handle<SHRenderGraphResource>> attRes, std::vector<Handle<SHRenderGraphNode>> predecessors, std::unordered_map<std::string, Handle<SHRenderGraphResource>> const* resources) noexcept
|
||||||
|
: logicalDeviceHdl{ logicalDevice }
|
||||||
|
, renderpass{}
|
||||||
|
, framebuffers{}
|
||||||
|
, prereqNodes{ std::move(predecessors) }
|
||||||
|
, attachmentDescriptions{}
|
||||||
|
, resourceAttachmentMapping{}
|
||||||
|
, attResources{ std::move(attRes) }
|
||||||
|
, subpasses{}
|
||||||
|
, executed{ false }
|
||||||
|
, configured{ false }
|
||||||
|
, resourceManager{ rm }
|
||||||
|
, ptrToResources{ resources }
|
||||||
|
{
|
||||||
|
// pipeline library initialization
|
||||||
|
pipelineLibrary.Init(logicalDeviceHdl);
|
||||||
|
|
||||||
|
attachmentDescriptions.resize(attResources.size());
|
||||||
|
|
||||||
|
bool containsSwapchainImage = false;
|
||||||
|
for (uint32_t i = 0; i < attResources.size(); ++i)
|
||||||
|
{
|
||||||
|
// As mentioned above we don't initialize much here because it's dependent on how other renderpasses are configured.
|
||||||
|
vk::AttachmentDescription& newDesc = attachmentDescriptions[i];
|
||||||
|
newDesc.samples = vk::SampleCountFlagBits::e1;
|
||||||
|
|
||||||
|
// We set this to clear first. If later we find out that some predecessor is writing to the same attachment,
|
||||||
|
// we set the pred's storeOp to eStore and "this" loadOp to eLoad.
|
||||||
|
newDesc.loadOp = vk::AttachmentLoadOp::eClear;
|
||||||
|
newDesc.storeOp = vk::AttachmentStoreOp::eStore;
|
||||||
|
|
||||||
|
newDesc.stencilLoadOp = vk::AttachmentLoadOp::eClear;
|
||||||
|
newDesc.stencilStoreOp = vk::AttachmentStoreOp::eStore;
|
||||||
|
|
||||||
|
newDesc.format = attResources[i]->resourceFormat;
|
||||||
|
|
||||||
|
if (attResources[i]->resourceType == SH_ATT_DESC_TYPE::COLOR_PRESENT)
|
||||||
|
containsSwapchainImage = true;
|
||||||
|
|
||||||
|
resourceAttachmentMapping.try_emplace(attResources[i].GetId().Raw, i);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!containsSwapchainImage)
|
||||||
|
framebuffers.resize(1);
|
||||||
|
else
|
||||||
|
framebuffers.resize(swapchain->GetNumImages());
|
||||||
|
|
||||||
|
// At this point, we could configure framebuffers if we had the renderpass object but we don't so their creation has to be
|
||||||
|
// deferred to when renderpasses are also created.
|
||||||
|
}
|
||||||
|
|
||||||
|
SHRenderGraphNode::SHRenderGraphNode(SHRenderGraphNode&& rhs) noexcept
|
||||||
|
: resourceManager{ rhs.resourceManager }
|
||||||
|
, logicalDeviceHdl{ rhs.logicalDeviceHdl }
|
||||||
|
, renderpass{ rhs.renderpass }
|
||||||
|
, framebuffers{ std::move(rhs.framebuffers) }
|
||||||
|
, prereqNodes{ std::move(rhs.prereqNodes) }
|
||||||
|
, attachmentDescriptions{ std::move(rhs.attachmentDescriptions) }
|
||||||
|
, attResources{ std::move(rhs.attResources) }
|
||||||
|
, subpasses{ std::move(rhs.subpasses) }
|
||||||
|
, resourceAttachmentMapping{ std::move(rhs.resourceAttachmentMapping) }
|
||||||
|
, subpassIndexing{ std::move(rhs.subpassIndexing) }
|
||||||
|
, configured{ rhs.configured }
|
||||||
|
, executed{ rhs.executed }
|
||||||
|
, ptrToResources{ rhs.ptrToResources }
|
||||||
|
, pipelineLibrary{ std::move(rhs.pipelineLibrary) }
|
||||||
|
, batcher{ std::move(rhs.batcher) }
|
||||||
|
|
||||||
|
{
|
||||||
|
rhs.renderpass = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
SHRenderGraphNode& SHRenderGraphNode::operator=(SHRenderGraphNode&& rhs) noexcept
|
||||||
|
{
|
||||||
|
if (&rhs == this)
|
||||||
|
return *this;
|
||||||
|
|
||||||
|
resourceManager = rhs.resourceManager;
|
||||||
|
logicalDeviceHdl = rhs.logicalDeviceHdl;
|
||||||
|
renderpass = rhs.renderpass;
|
||||||
|
framebuffers = std::move(rhs.framebuffers);
|
||||||
|
prereqNodes = std::move(rhs.prereqNodes);
|
||||||
|
attachmentDescriptions = std::move(rhs.attachmentDescriptions);
|
||||||
|
attResources = std::move(rhs.attResources);
|
||||||
|
subpasses = std::move(rhs.subpasses);
|
||||||
|
resourceAttachmentMapping = std::move(rhs.resourceAttachmentMapping);
|
||||||
|
subpassIndexing = std::move(rhs.subpassIndexing);
|
||||||
|
ptrToResources = std::move(rhs.ptrToResources);
|
||||||
|
pipelineLibrary = std::move(rhs.pipelineLibrary);
|
||||||
|
batcher = std::move(rhs.batcher);
|
||||||
|
|
||||||
|
rhs.renderpass = {};
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
/*!
|
||||||
|
|
||||||
|
\brief
|
||||||
|
Add subpasses to the renderpass and returns a reference to it.
|
||||||
|
|
||||||
|
\param subpassName
|
||||||
|
Name of the subpass.
|
||||||
|
|
||||||
|
\return
|
||||||
|
Handle to the new subpass.
|
||||||
|
|
||||||
|
*/
|
||||||
|
/***************************************************************************/
|
||||||
|
Handle<SHSubpass> SHRenderGraphNode::AddSubpass(std::string subpassName) noexcept
|
||||||
|
{
|
||||||
|
// if subpass already exists, don't add.
|
||||||
|
if (subpassIndexing.contains(subpassName))
|
||||||
|
{
|
||||||
|
SHLOG_ERROR("Subpass already exists.");
|
||||||
|
return{};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add subpass to container and create mapping for it
|
||||||
|
subpasses.emplace_back(resourceManager.Create<SHSubpass>(resourceManager, GetHandle(), subpasses.size(), &resourceAttachmentMapping, ptrToResources));
|
||||||
|
subpassIndexing.try_emplace(subpassName, static_cast<uint32_t>(subpasses.size()) - 1u);
|
||||||
|
Handle<SHSubpass> subpass = subpasses.back();
|
||||||
|
subpass->Init(resourceManager);
|
||||||
|
|
||||||
|
// Register the SuperBatch
|
||||||
|
batcher.RegisterSuperBatch(subpass->GetSuperBatch());
|
||||||
|
|
||||||
|
return subpass;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHRenderGraphNode::Execute(Handle<SHVkCommandBuffer>& commandBuffer, Handle<SHVkDescriptorPool> descPool, uint32_t frameIndex) noexcept
|
||||||
|
{
|
||||||
|
frameIndex = (framebuffers.size() > 1) ? frameIndex : 0;
|
||||||
|
commandBuffer->BeginRenderpass(renderpass, framebuffers[frameIndex]);
|
||||||
|
|
||||||
|
for (uint32_t i = 0; i < subpasses.size(); ++i)
|
||||||
|
{
|
||||||
|
subpasses[i]->Execute(commandBuffer, descPool, frameIndex);
|
||||||
|
|
||||||
|
// Go to next subpass if not last subpass
|
||||||
|
if (i != subpasses.size() - 1)
|
||||||
|
commandBuffer->NextSubpass();
|
||||||
|
}
|
||||||
|
|
||||||
|
commandBuffer->EndRenderpass();
|
||||||
|
}
|
||||||
|
|
||||||
|
Handle<SHVkPipeline> SHRenderGraphNode::GetOrCreatePipeline(std::pair<Handle<SHVkShaderModule>, Handle<SHVkShaderModule>> const& vsFsPair, Handle<SHSubpass> subpass) noexcept
|
||||||
|
{
|
||||||
|
// verify subpass exists
|
||||||
|
if (subpass->GetIndex() >= subpasses.size())
|
||||||
|
{
|
||||||
|
SHLOG_ERROR("Subpass index passed in is not valid. RenderGraphNode does not have that many passes. ");
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
Handle<SHVkPipeline> pipeline = pipelineLibrary.GetDrawPipline(vsFsPair);
|
||||||
|
if (!pipeline)
|
||||||
|
{
|
||||||
|
pipeline = pipelineLibrary.CreateDrawPipeline
|
||||||
|
(
|
||||||
|
vsFsPair,
|
||||||
|
renderpass,
|
||||||
|
subpass
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return pipeline;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHRenderGraphNode::FinaliseBatch(uint32_t frameIndex, Handle<SHVkDescriptorPool> descPool)
|
||||||
|
{
|
||||||
|
batcher.FinaliseBatches(logicalDeviceHdl, descPool, frameIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
/*!
|
||||||
|
|
||||||
|
\brief
|
||||||
|
Get the renderpass from the node.
|
||||||
|
|
||||||
|
\return
|
||||||
|
Handle to the renderpass.
|
||||||
|
|
||||||
|
*/
|
||||||
|
/***************************************************************************/
|
||||||
|
Handle<SHVkRenderpass> SHRenderGraphNode::GetRenderpass(void) const noexcept
|
||||||
|
{
|
||||||
|
return renderpass;
|
||||||
|
}
|
||||||
|
|
||||||
|
Handle<SHSubpass> SHRenderGraphNode::GetSubpass(std::string_view subpassName) const noexcept
|
||||||
|
{
|
||||||
|
return subpasses[subpassIndexing.at(subpassName.data())];
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,110 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <unordered_map>
|
||||||
|
#include <map>
|
||||||
|
#include <vector>
|
||||||
|
#include "SHAttachmentDescriptionType.h"
|
||||||
|
#include "Graphics/SHVulkanIncludes.h"
|
||||||
|
#include "SH_API.h"
|
||||||
|
#include "Graphics/MiddleEnd/Pipeline/SHPipelineLibrary.h"
|
||||||
|
#include "Graphics/MiddleEnd/Batching/SHBatcher.h"
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
class ResourceManager;
|
||||||
|
class SHVkFramebuffer;
|
||||||
|
class SHRenderGraphResource;
|
||||||
|
class SHVkLogicalDevice;
|
||||||
|
class SHVkRenderpass;
|
||||||
|
class SHVkDescriptorPool;
|
||||||
|
|
||||||
|
class SH_API SHRenderGraphNode : public ISelfHandle<SHRenderGraphNode>
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
/*-----------------------------------------------------------------------*/
|
||||||
|
/* PRIVATE MEMBER VARIABLES */
|
||||||
|
/*-----------------------------------------------------------------------*/
|
||||||
|
ResourceManager& resourceManager;
|
||||||
|
|
||||||
|
//! For Vulkan object creation
|
||||||
|
Handle<SHVkLogicalDevice> logicalDeviceHdl;
|
||||||
|
|
||||||
|
//! Each node will have a renderpass and each renderpass will have its own subpasses.
|
||||||
|
//! These subpasses will execute sequentially.
|
||||||
|
Handle<SHVkRenderpass> renderpass;
|
||||||
|
|
||||||
|
//! Framebuffers used in this renderpass. If renderpass contains usage of a swapchain image
|
||||||
|
//! used for presenting, then we cannot use just 1 framebuffer, we need to have 1 for however many frames in flight.
|
||||||
|
std::vector<Handle<SHVkFramebuffer>> framebuffers;
|
||||||
|
|
||||||
|
//! Nodes that must finish execution before this node is executed will be in this container
|
||||||
|
std::vector<Handle<SHRenderGraphNode>> prereqNodes;
|
||||||
|
|
||||||
|
//! Container of Attachment descriptions
|
||||||
|
std::vector<vk::AttachmentDescription> attachmentDescriptions;
|
||||||
|
|
||||||
|
//! Resources used in this renderpass
|
||||||
|
std::vector<Handle<SHRenderGraphResource>> attResources;
|
||||||
|
|
||||||
|
//! Vector of subpasses
|
||||||
|
std::vector<Handle<SHSubpass>> subpasses;
|
||||||
|
|
||||||
|
//! Descriptions to pass to renderpass for renderpass creation. We want to keep this here because
|
||||||
|
std::vector<vk::SubpassDescription> spDescs;
|
||||||
|
|
||||||
|
//! Subpass dependencies for renderpass creation
|
||||||
|
std::vector<vk::SubpassDependency> spDeps;
|
||||||
|
|
||||||
|
//! For indexing resources fast
|
||||||
|
std::unordered_map<uint64_t, uint32_t> resourceAttachmentMapping;
|
||||||
|
|
||||||
|
//! For indexing subpasses
|
||||||
|
std::map<std::string, uint32_t> subpassIndexing;
|
||||||
|
|
||||||
|
//! Pointer to resources in the render graph (for getting handle IDs)
|
||||||
|
std::unordered_map<std::string, Handle<SHRenderGraphResource>> const* ptrToResources;
|
||||||
|
|
||||||
|
//! Every renderpass will require a pipeline library that will contain pipelines compatible with this renderpass
|
||||||
|
SHPipelineLibrary pipelineLibrary;
|
||||||
|
|
||||||
|
//! Whether or not the node has finished execution
|
||||||
|
bool executed;
|
||||||
|
|
||||||
|
//! Whether or not the node has been configured already or not
|
||||||
|
bool configured;
|
||||||
|
|
||||||
|
SHBatcher batcher;
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------------*/
|
||||||
|
/* PRIVATE MEMBER FUNCTIONS */
|
||||||
|
/*-----------------------------------------------------------------------*/
|
||||||
|
void CreateRenderpass(void) noexcept;
|
||||||
|
void CreateFramebuffer(void) noexcept;
|
||||||
|
|
||||||
|
public:
|
||||||
|
/*-----------------------------------------------------------------------*/
|
||||||
|
/* CTORS AND DTORS */
|
||||||
|
/*-----------------------------------------------------------------------*/
|
||||||
|
SHRenderGraphNode(ResourceManager& rm, Handle<SHVkLogicalDevice> const& logicalDevice, Handle<SHVkSwapchain> const& swapchain, std::vector<Handle<SHRenderGraphResource>> attRes, std::vector<Handle<SHRenderGraphNode>> predecessors, std::unordered_map<std::string, Handle<SHRenderGraphResource>> const* resources) noexcept;
|
||||||
|
SHRenderGraphNode(SHRenderGraphNode&& rhs) noexcept;
|
||||||
|
SHRenderGraphNode& operator= (SHRenderGraphNode&& rhs) noexcept;
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------------*/
|
||||||
|
/* PUBLIC MEMBER FUNCTIONS */
|
||||||
|
/*-----------------------------------------------------------------------*/
|
||||||
|
Handle<SHSubpass> AddSubpass(std::string subpassName) noexcept;
|
||||||
|
// TODO: RemoveSubpass()
|
||||||
|
void Execute(Handle<SHVkCommandBuffer>& commandBuffer, Handle<SHVkDescriptorPool> descPool, uint32_t frameIndex) noexcept;
|
||||||
|
Handle<SHVkPipeline> GetOrCreatePipeline(std::pair<Handle<SHVkShaderModule>, Handle<SHVkShaderModule>> const& vsFsPair, Handle<SHSubpass> subpass) noexcept;
|
||||||
|
void FinaliseBatch(uint32_t frameIndex, Handle<SHVkDescriptorPool> descPool);
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------------*/
|
||||||
|
/* SETTERS AND GETTERS */
|
||||||
|
/*-----------------------------------------------------------------------*/
|
||||||
|
Handle<SHVkRenderpass> GetRenderpass(void) const noexcept;
|
||||||
|
Handle<SHSubpass> GetSubpass(std::string_view subpassName) const noexcept;
|
||||||
|
friend class SHRenderGraph;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,192 @@
|
||||||
|
#include "SHpch.h"
|
||||||
|
#include "SHRenderGraphResource.h"
|
||||||
|
#include "Graphics/Devices/SHVkLogicalDevice.h"
|
||||||
|
#include "Graphics/Swapchain/SHVkSwapchain.h"
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
/***************************************************************************/
|
||||||
|
/*!
|
||||||
|
|
||||||
|
\brief
|
||||||
|
Non-default ctor for the resource. Using the type of the resource, we
|
||||||
|
decide whether or not we create a resource or link with a swapchain
|
||||||
|
resource (image).
|
||||||
|
|
||||||
|
\param logicalDevice
|
||||||
|
Logical device required to create an image resource if the type is NOT
|
||||||
|
SH_ATT_DESC_TYPE::COLOR_PRESENT.
|
||||||
|
|
||||||
|
\param swapchain
|
||||||
|
Swapchain required to get swapchain image if the type IS
|
||||||
|
SH_ATT_DESC_TYPE::COLOR_PRESENT.
|
||||||
|
|
||||||
|
\param type
|
||||||
|
Type of the image resource.
|
||||||
|
|
||||||
|
\param format
|
||||||
|
Format of the image resource.
|
||||||
|
|
||||||
|
\param w
|
||||||
|
Width of the image resource.
|
||||||
|
|
||||||
|
\param h
|
||||||
|
Height of the image resource.
|
||||||
|
|
||||||
|
\param levels
|
||||||
|
Number of mipmap levels of the image resource.
|
||||||
|
|
||||||
|
\param createFlags
|
||||||
|
Create flags used when an image resource needs to be created.
|
||||||
|
|
||||||
|
*/
|
||||||
|
/***************************************************************************/
|
||||||
|
SHRenderGraphResource::SHRenderGraphResource(Handle<SHVkLogicalDevice> const& logicalDevice, Handle<SHVkSwapchain> const& swapchain, std::string const& name, SH_ATT_DESC_TYPE type, vk::Format format, uint32_t w, uint32_t h, uint8_t levels, vk::ImageCreateFlagBits createFlags) noexcept
|
||||||
|
: resourceType{ type }
|
||||||
|
, resourceFormat{ format }
|
||||||
|
, images{}
|
||||||
|
, imageViews{}
|
||||||
|
, width{ w }
|
||||||
|
, height{ h }
|
||||||
|
, mipLevels{ levels }
|
||||||
|
, resourceName{ name }
|
||||||
|
{
|
||||||
|
// If the resource type is an arbitrary image and not swapchain image
|
||||||
|
if (type != SH_ATT_DESC_TYPE::COLOR_PRESENT)
|
||||||
|
{
|
||||||
|
vk::ImageAspectFlags imageAspectFlags;
|
||||||
|
vk::ImageUsageFlags usage = {};
|
||||||
|
|
||||||
|
// Check the resource type and set image usage flags and image aspect flags accordingly
|
||||||
|
switch (resourceType)
|
||||||
|
{
|
||||||
|
case SH_ATT_DESC_TYPE::COLOR:
|
||||||
|
usage |= vk::ImageUsageFlagBits::eColorAttachment;
|
||||||
|
imageAspectFlags |= vk::ImageAspectFlagBits::eColor;
|
||||||
|
break;
|
||||||
|
case SH_ATT_DESC_TYPE::DEPTH:
|
||||||
|
usage |= vk::ImageUsageFlagBits::eDepthStencilAttachment;
|
||||||
|
imageAspectFlags |= vk::ImageAspectFlagBits::eDepth;
|
||||||
|
break;
|
||||||
|
case SH_ATT_DESC_TYPE::STENCIL:
|
||||||
|
usage |= vk::ImageUsageFlagBits::eDepthStencilAttachment;
|
||||||
|
imageAspectFlags |= vk::ImageAspectFlagBits::eStencil;
|
||||||
|
break;
|
||||||
|
case SH_ATT_DESC_TYPE::DEPTH_STENCIL:
|
||||||
|
usage |= vk::ImageUsageFlagBits::eDepthStencilAttachment;
|
||||||
|
imageAspectFlags |= vk::ImageAspectFlagBits::eStencil | vk::ImageAspectFlagBits::eDepth;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The resource is not a swapchain image, just use the first slot of the vector
|
||||||
|
images.push_back(logicalDevice->CreateImage(width, height, mipLevels, resourceFormat, usage, createFlags));
|
||||||
|
|
||||||
|
// prepare image view details
|
||||||
|
SHImageViewDetails viewDetails
|
||||||
|
{
|
||||||
|
.viewType = vk::ImageViewType::e2D,
|
||||||
|
.format = images[0]->GetImageFormat(),
|
||||||
|
.imageAspectFlags = imageAspectFlags,
|
||||||
|
.baseMipLevel = 0,
|
||||||
|
.mipLevelCount = mipLevels,
|
||||||
|
.baseArrayLayer = 0,
|
||||||
|
.layerCount = 1,
|
||||||
|
};
|
||||||
|
|
||||||
|
// just 1 image view created
|
||||||
|
imageViews.push_back(images[0]->CreateImageView(logicalDevice, images[0], viewDetails));
|
||||||
|
}
|
||||||
|
else // if swapchain image resource
|
||||||
|
{
|
||||||
|
// Prepare image view details
|
||||||
|
SHImageViewDetails viewDetails
|
||||||
|
{
|
||||||
|
.viewType = vk::ImageViewType::e2D,
|
||||||
|
.format = swapchain->GetSurfaceFormatKHR().format,
|
||||||
|
.imageAspectFlags = vk::ImageAspectFlagBits::eColor,
|
||||||
|
.baseMipLevel = 0,
|
||||||
|
.mipLevelCount = 1,
|
||||||
|
.baseArrayLayer = 0,
|
||||||
|
.layerCount = 1,
|
||||||
|
};
|
||||||
|
|
||||||
|
// We want an image handle for every swapchain image
|
||||||
|
images.resize(swapchain->GetNumImages());
|
||||||
|
imageViews.resize(swapchain->GetNumImages());
|
||||||
|
|
||||||
|
for (uint32_t i = 0; i < swapchain->GetNumImages(); ++i)
|
||||||
|
{
|
||||||
|
images[i] = swapchain->GetSwapchainImage(i);
|
||||||
|
imageViews[i] = images[i]->CreateImageView(logicalDevice, images[i], viewDetails);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
/*!
|
||||||
|
|
||||||
|
\brief
|
||||||
|
Move ctor for resource.
|
||||||
|
|
||||||
|
\param rhs
|
||||||
|
The other resource.
|
||||||
|
|
||||||
|
*/
|
||||||
|
/***************************************************************************/
|
||||||
|
SHRenderGraphResource::SHRenderGraphResource(SHRenderGraphResource&& rhs) noexcept
|
||||||
|
: resourceName{ std::move(rhs.resourceName) }
|
||||||
|
, resourceType{ std::move(rhs.resourceType) }
|
||||||
|
, images{ std::move(rhs.images) }
|
||||||
|
, imageViews{ std::move(rhs.imageViews) }
|
||||||
|
, resourceFormat{ std::move(rhs.resourceFormat) }
|
||||||
|
, width{ rhs.width }
|
||||||
|
, height{ rhs.height }
|
||||||
|
, mipLevels{ rhs.mipLevels }
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
/*!
|
||||||
|
|
||||||
|
\brief
|
||||||
|
Move assignment operator.
|
||||||
|
|
||||||
|
\param rhs
|
||||||
|
The other resource.
|
||||||
|
|
||||||
|
\return
|
||||||
|
|
||||||
|
*/
|
||||||
|
/***************************************************************************/
|
||||||
|
SHRenderGraphResource& SHRenderGraphResource::operator=(SHRenderGraphResource&& rhs) noexcept
|
||||||
|
{
|
||||||
|
if (this == &rhs)
|
||||||
|
return *this;
|
||||||
|
|
||||||
|
resourceName = std::move(rhs.resourceName);
|
||||||
|
resourceType = std::move(rhs.resourceType);
|
||||||
|
images = std::move(rhs.images);
|
||||||
|
imageViews = std::move(rhs.imageViews);
|
||||||
|
resourceFormat = std::move(rhs.resourceFormat);
|
||||||
|
width = rhs.width;
|
||||||
|
height = rhs.height;
|
||||||
|
mipLevels = rhs.mipLevels;
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
/*!
|
||||||
|
|
||||||
|
\brief
|
||||||
|
Destructor for resource.
|
||||||
|
|
||||||
|
*/
|
||||||
|
/***************************************************************************/
|
||||||
|
SHRenderGraphResource::~SHRenderGraphResource(void) noexcept
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,62 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include "SHAttachmentDescriptionType.h"
|
||||||
|
#include <vector>
|
||||||
|
#include "Resource/Handle.h"
|
||||||
|
#include "Graphics/SHVulkanIncludes.h"
|
||||||
|
#include "SH_API.h"
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
class SHVkImage;
|
||||||
|
class SHVkImageView;
|
||||||
|
class SHVkLogicalDevice;
|
||||||
|
class SHVkSwapchain;
|
||||||
|
|
||||||
|
class SH_API SHRenderGraphResource
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
/*-----------------------------------------------------------------------*/
|
||||||
|
/* PRIVATE MEMBER VARIABLES */
|
||||||
|
/*-----------------------------------------------------------------------*/
|
||||||
|
//! Name of the resource
|
||||||
|
std::string resourceName;
|
||||||
|
|
||||||
|
//! Used for initializing image layouts
|
||||||
|
SH_ATT_DESC_TYPE resourceType;
|
||||||
|
|
||||||
|
//! The resource itself (this is a vector because if the resource happens
|
||||||
|
//! to be a swapchain image, then we need however many frames in flight).
|
||||||
|
//! However when it's not a swapchain image, we want this container to be size 1
|
||||||
|
//! because writing to these images will not interfere with images in the previous
|
||||||
|
//! frame, unlike the swapchain image.
|
||||||
|
std::vector<Handle<SHVkImage>> images;
|
||||||
|
|
||||||
|
//! Views to resources (vector because same rationale as images. see above).
|
||||||
|
std::vector<Handle<SHVkImageView>> imageViews;
|
||||||
|
|
||||||
|
//! Image format
|
||||||
|
vk::Format resourceFormat;
|
||||||
|
|
||||||
|
//! width of the resource
|
||||||
|
uint32_t width;
|
||||||
|
|
||||||
|
//! Height of the resource
|
||||||
|
uint32_t height;
|
||||||
|
|
||||||
|
//! Number of mipmap levels
|
||||||
|
uint8_t mipLevels;
|
||||||
|
public:
|
||||||
|
/*-----------------------------------------------------------------------*/
|
||||||
|
/* CTORS AND DTORS */
|
||||||
|
/*-----------------------------------------------------------------------*/
|
||||||
|
SHRenderGraphResource(Handle<SHVkLogicalDevice> const& logicalDevice, Handle<SHVkSwapchain> const& swapchain, std::string const& name, SH_ATT_DESC_TYPE type, vk::Format format, uint32_t w, uint32_t h, uint8_t levels, vk::ImageCreateFlagBits createFlags) noexcept;
|
||||||
|
SHRenderGraphResource(SHRenderGraphResource&& rhs) noexcept;
|
||||||
|
SHRenderGraphResource& operator=(SHRenderGraphResource&& rhs) noexcept;
|
||||||
|
~SHRenderGraphResource(void) noexcept;
|
||||||
|
|
||||||
|
friend class SHRenderGraphNode;
|
||||||
|
friend class SHRenderGraph;
|
||||||
|
};
|
||||||
|
}
|
|
@ -0,0 +1,210 @@
|
||||||
|
#include "SHpch.h"
|
||||||
|
#include "SHSubpass.h"
|
||||||
|
#include "Graphics/MiddleEnd/Batching/SHSuperBatch.h"
|
||||||
|
#include "Graphics/Devices/SHVkLogicalDevice.h"
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
/*!
|
||||||
|
|
||||||
|
\brief
|
||||||
|
Subpass non-default constructor. Simply initializes variables.
|
||||||
|
|
||||||
|
\param mapping
|
||||||
|
Mapping from a resource handle to an attachment reference referencing
|
||||||
|
the resource.
|
||||||
|
|
||||||
|
\param resources
|
||||||
|
A mapping from string to render graph resource.
|
||||||
|
|
||||||
|
*/
|
||||||
|
/***************************************************************************/
|
||||||
|
SHSubpass::SHSubpass(ResourceManager& rm, Handle<SHRenderGraphNode> const& parent, uint32_t index, std::unordered_map<uint64_t, uint32_t> const* mapping, std::unordered_map<std::string, Handle<SHRenderGraphResource>> const* resources) noexcept
|
||||||
|
: resourceAttachmentMapping{ mapping }
|
||||||
|
, ptrToResources{ resources }
|
||||||
|
, parentNode{ parent }
|
||||||
|
, subpassIndex{ index }
|
||||||
|
, superBatch{}
|
||||||
|
, colorReferences{}
|
||||||
|
, depthReferences{}
|
||||||
|
, inputReferences{}
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
/*!
|
||||||
|
|
||||||
|
\brief
|
||||||
|
Move constructor for subpass.
|
||||||
|
|
||||||
|
\param rhs
|
||||||
|
The subpass the move from.
|
||||||
|
|
||||||
|
*/
|
||||||
|
/***************************************************************************/
|
||||||
|
SHSubpass::SHSubpass(SHSubpass&& rhs) noexcept
|
||||||
|
: subpassIndex{ std::move(rhs.subpassIndex) }
|
||||||
|
, parentNode{ std::move(rhs.parentNode) }
|
||||||
|
, superBatch{ std::move(rhs.superBatch) }
|
||||||
|
, colorReferences{ std::move(rhs.colorReferences) }
|
||||||
|
, depthReferences{ std::move(rhs.depthReferences) }
|
||||||
|
, inputReferences{ std::move(rhs.inputReferences) }
|
||||||
|
, resourceAttachmentMapping{ rhs.resourceAttachmentMapping }
|
||||||
|
, ptrToResources{ rhs.ptrToResources }
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
/*!
|
||||||
|
|
||||||
|
\brief
|
||||||
|
Move assignment operator for subpass.
|
||||||
|
|
||||||
|
\param rhs
|
||||||
|
subpass to move from.
|
||||||
|
|
||||||
|
*/
|
||||||
|
/***************************************************************************/
|
||||||
|
SHSubpass& SHSubpass::operator=(SHSubpass&& rhs) noexcept
|
||||||
|
{
|
||||||
|
if (this == &rhs)
|
||||||
|
return *this;
|
||||||
|
|
||||||
|
subpassIndex = std::move(rhs.subpassIndex);
|
||||||
|
parentNode = std::move(rhs.parentNode);
|
||||||
|
superBatch = std::move(rhs.superBatch);
|
||||||
|
colorReferences = std::move(rhs.colorReferences);
|
||||||
|
depthReferences = std::move(rhs.depthReferences);
|
||||||
|
inputReferences = std::move(rhs.inputReferences);
|
||||||
|
resourceAttachmentMapping = rhs.resourceAttachmentMapping;
|
||||||
|
ptrToResources = rhs.ptrToResources;
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
/*!
|
||||||
|
|
||||||
|
\brief
|
||||||
|
Adds a color output to a subpass. Takes in a string and finds the
|
||||||
|
attachment index to create the vk::SubpassReference.
|
||||||
|
|
||||||
|
\param resourceToReference
|
||||||
|
Resource name to find resource to attach.
|
||||||
|
|
||||||
|
*/
|
||||||
|
/***************************************************************************/
|
||||||
|
void SHSubpass::AddColorOutput(std::string resourceToReference) noexcept
|
||||||
|
{
|
||||||
|
colorReferences.push_back({ resourceAttachmentMapping->at(ptrToResources->at(resourceToReference).GetId().Raw), vk::ImageLayout::eColorAttachmentOptimal });
|
||||||
|
}
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
/*!
|
||||||
|
|
||||||
|
\brief
|
||||||
|
Adds a depth output to a subpass. Takes in a string and finds the
|
||||||
|
attachment index to create the vk::SubpassReference.
|
||||||
|
|
||||||
|
\param resourceToReference
|
||||||
|
Resource name to find resource to attach.
|
||||||
|
|
||||||
|
\param attachmentDescriptionType
|
||||||
|
Depending on the type of the resource, initialize the image layout
|
||||||
|
appropriately.
|
||||||
|
|
||||||
|
*/
|
||||||
|
/***************************************************************************/
|
||||||
|
void SHSubpass::AddDepthOutput(std::string resourceToReference, SH_ATT_DESC_TYPE attachmentDescriptionType) noexcept
|
||||||
|
{
|
||||||
|
vk::ImageLayout imageLayout;
|
||||||
|
switch (attachmentDescriptionType)
|
||||||
|
{
|
||||||
|
case SH_ATT_DESC_TYPE::DEPTH:
|
||||||
|
imageLayout = vk::ImageLayout::eDepthAttachmentOptimal;
|
||||||
|
break;
|
||||||
|
case SH_ATT_DESC_TYPE::STENCIL:
|
||||||
|
imageLayout = vk::ImageLayout::eStencilAttachmentOptimal;
|
||||||
|
break;
|
||||||
|
case SH_ATT_DESC_TYPE::DEPTH_STENCIL:
|
||||||
|
imageLayout = vk::ImageLayout::eDepthStencilAttachmentOptimal;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
//Invalid
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
depthReferences.push_back({ resourceAttachmentMapping->at(ptrToResources->at(resourceToReference).GetId().Raw), imageLayout });
|
||||||
|
}
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
/*!
|
||||||
|
|
||||||
|
\brief
|
||||||
|
Adds a input output to a subpass. Takes in a string and finds the
|
||||||
|
attachment index to create the vk::SubpassReference.
|
||||||
|
|
||||||
|
\param resourceToReference
|
||||||
|
Resource name to find resource to attach.
|
||||||
|
|
||||||
|
*/
|
||||||
|
/***************************************************************************/
|
||||||
|
void SHSubpass::AddInput(std::string resourceToReference) noexcept
|
||||||
|
{
|
||||||
|
inputReferences.push_back({ resourceAttachmentMapping->at(ptrToResources->at(resourceToReference).GetId().Raw), vk::ImageLayout::eShaderReadOnlyOptimal });
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHSubpass::Execute(Handle<SHVkCommandBuffer>& commandBuffer, Handle<SHVkDescriptorPool> descPool, uint32_t frameIndex) noexcept
|
||||||
|
{
|
||||||
|
// Ensure correct transforms are provided
|
||||||
|
superBatch->UpdateBuffers(frameIndex, descPool);
|
||||||
|
|
||||||
|
// Draw all the batches
|
||||||
|
superBatch->Draw(commandBuffer, frameIndex);
|
||||||
|
|
||||||
|
// Draw all the exterior draw calls
|
||||||
|
for (auto& drawCall : exteriorDrawCalls)
|
||||||
|
{
|
||||||
|
drawCall(commandBuffer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHSubpass::AddExteriorDrawCalls(std::function<void(Handle<SHVkCommandBuffer>&)> const& newDrawCall) noexcept
|
||||||
|
{
|
||||||
|
exteriorDrawCalls.push_back(newDrawCall);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHSubpass::Init(ResourceManager& resourceManager) noexcept
|
||||||
|
{
|
||||||
|
superBatch = resourceManager.Create<SHSuperBatch>(GetHandle());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
/*!
|
||||||
|
|
||||||
|
\brief
|
||||||
|
Getter for parent renderpass.
|
||||||
|
|
||||||
|
\return
|
||||||
|
Returns the parent renderpass the subpass belongs to.
|
||||||
|
|
||||||
|
*/
|
||||||
|
/***************************************************************************/
|
||||||
|
Handle<SHRenderGraphNode> const& SHSubpass::GetParentNode(void) const noexcept
|
||||||
|
{
|
||||||
|
return parentNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
SHADE::SHSubPassIndex SHSubpass::GetIndex() const noexcept
|
||||||
|
{
|
||||||
|
return subpassIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
Handle<SHSuperBatch> SHSubpass::GetSuperBatch(void) const noexcept
|
||||||
|
{
|
||||||
|
return superBatch;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,94 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "SHAttachmentDescriptionType.h"
|
||||||
|
#include <string>
|
||||||
|
#include "SH_API.h"
|
||||||
|
#include "Resource/Handle.h"
|
||||||
|
#include "Graphics/SHVulkanIncludes.h"
|
||||||
|
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
class SHRenderGraphNode;
|
||||||
|
class SHSuperBatch;
|
||||||
|
class SHRenderGraphResource;
|
||||||
|
class SHVkCommandBuffer;
|
||||||
|
class SHVkDescriptorSetLayout;
|
||||||
|
class SHVkDescriptorPool;
|
||||||
|
|
||||||
|
class SH_API SHSubpass : public ISelfHandle<SHSubpass>
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
/*---------------------------------------------------------------------*/
|
||||||
|
/* PRIVATE MEMBER VARIABLES */
|
||||||
|
/*---------------------------------------------------------------------*/
|
||||||
|
//! The index of the subpass in the render graph
|
||||||
|
uint32_t subpassIndex;
|
||||||
|
|
||||||
|
//! The parent renderpass that this subpass belongs to
|
||||||
|
Handle<SHRenderGraphNode> parentNode;
|
||||||
|
|
||||||
|
//!
|
||||||
|
Handle<SHSuperBatch> superBatch;
|
||||||
|
|
||||||
|
//! Descriptor set layout to hold attachments
|
||||||
|
Handle<SHVkDescriptorSetLayout> descriptorSetLayout;
|
||||||
|
|
||||||
|
//! Color attachments
|
||||||
|
std::vector<vk::AttachmentReference> colorReferences;
|
||||||
|
|
||||||
|
//! Depth attachments
|
||||||
|
std::vector<vk::AttachmentReference> depthReferences;
|
||||||
|
|
||||||
|
//! Input attachments
|
||||||
|
std::vector<vk::AttachmentReference> inputReferences;
|
||||||
|
|
||||||
|
//! For getting attachment reference indices using handles
|
||||||
|
std::unordered_map<uint64_t, uint32_t> const* resourceAttachmentMapping;
|
||||||
|
|
||||||
|
//! Pointer to resources in the render graph (for getting handle IDs)
|
||||||
|
std::unordered_map<std::string, Handle<SHRenderGraphResource>> const* ptrToResources;
|
||||||
|
|
||||||
|
//! Sometimes there exists entities that we want to render onto a render target
|
||||||
|
//! but don't want it to come from the batching system. An example would be ImGUI.
|
||||||
|
//! For these entities we want to link a function from the outside and draw them
|
||||||
|
//! after we draw everything from the batch. Because of this, these draw calls
|
||||||
|
//! are always the last things drawn, so DO NOT USE THIS FUNCTIONALITY FOR ANYTHING
|
||||||
|
//! COMPLEX.
|
||||||
|
std::vector<std::function<void(Handle<SHVkCommandBuffer>&)>> exteriorDrawCalls;
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
/*-----------------------------------------------------------------------*/
|
||||||
|
/* CTORS AND DTORS */
|
||||||
|
/*-----------------------------------------------------------------------*/
|
||||||
|
SHSubpass(ResourceManager& rm, Handle<SHRenderGraphNode> const& parent, uint32_t index, std::unordered_map<uint64_t, uint32_t> const* mapping, std::unordered_map<std::string, Handle<SHRenderGraphResource>> const* ptrToResources) noexcept;
|
||||||
|
SHSubpass(SHSubpass&& rhs) noexcept;
|
||||||
|
SHSubpass& operator=(SHSubpass&& rhs) noexcept;
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------------*/
|
||||||
|
/* PUBLIC MEMBER FUNCTIONS */
|
||||||
|
/*-----------------------------------------------------------------------*/
|
||||||
|
// Preparation functions
|
||||||
|
void AddColorOutput(std::string resourceToReference) noexcept;
|
||||||
|
void AddDepthOutput(std::string resourceToReference, SH_ATT_DESC_TYPE attachmentDescriptionType = SH_ATT_DESC_TYPE::DEPTH_STENCIL) noexcept;
|
||||||
|
void AddInput(std::string resourceToReference) noexcept;
|
||||||
|
|
||||||
|
// Runtime functions
|
||||||
|
void Execute(Handle<SHVkCommandBuffer>& commandBuffer, Handle<SHVkDescriptorPool> descPool, uint32_t frameIndex) noexcept;
|
||||||
|
void AddExteriorDrawCalls(std::function<void(Handle<SHVkCommandBuffer>&)> const& newDrawCall) noexcept;
|
||||||
|
|
||||||
|
void Init(ResourceManager& resourceManager) noexcept;
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------------*/
|
||||||
|
/* GETTERS AND SETTERS */
|
||||||
|
/*-----------------------------------------------------------------------*/
|
||||||
|
Handle<SHRenderGraphNode> const& GetParentNode(void) const noexcept;
|
||||||
|
SHSubPassIndex GetIndex() const noexcept;
|
||||||
|
Handle<SHSuperBatch> GetSuperBatch(void) const noexcept;
|
||||||
|
|
||||||
|
|
||||||
|
friend class SHRenderGraphNode;
|
||||||
|
friend class SHRenderGraph;
|
||||||
|
};
|
||||||
|
}
|
|
@ -0,0 +1,23 @@
|
||||||
|
#include "SHpch.h"
|
||||||
|
#include "SHSubpassCompute.h"
|
||||||
|
#include "Graphics/Pipeline/SHVkPipeline.h"
|
||||||
|
#include "Graphics/Descriptors/SHVkDescriptorSetGroup.h"
|
||||||
|
#include "Graphics/Descriptors/SHVkDescriptorPool.h"
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
SHSubpassCompute::SHSubpassCompute(Handle<SHVkPipeline> inPipeline, Handle<SHVkDescriptorPool> descPool) noexcept
|
||||||
|
: pipeline {inPipeline}
|
||||||
|
{
|
||||||
|
// Get the descriptor set layouts required to allocate. we will bind a different pipeline layout, one that includes the layout for global.
|
||||||
|
auto const& layouts = pipeline->GetPipelineLayout()->GetDescriptorSetLayoutsAllocate();
|
||||||
|
|
||||||
|
// Variable counts for the descriptor sets (all should be 1).
|
||||||
|
std::vector<uint32_t> variableCounts{static_cast<uint32_t>(layouts.size())};
|
||||||
|
std::fill (variableCounts.begin(), variableCounts.end(), 0);
|
||||||
|
|
||||||
|
// Allocate descriptor sets to hold the images for reading (STORAGE_IMAGE)
|
||||||
|
descPool->Allocate(layouts, variableCounts);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,25 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <Resource/Handle.h>
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
class SHVkPipeline;
|
||||||
|
class SHVkDescriptorSetGroup;
|
||||||
|
class SHVkDescriptorPool;
|
||||||
|
|
||||||
|
class SHSubpassCompute
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
//! To run the dispatch command
|
||||||
|
Handle<SHVkPipeline> pipeline;
|
||||||
|
|
||||||
|
//! Descriptor set group
|
||||||
|
Handle<SHVkDescriptorSetGroup> descSetGroup;
|
||||||
|
|
||||||
|
public:
|
||||||
|
SHSubpassCompute (Handle<SHVkPipeline> inPipeline, Handle<SHVkDescriptorPool> descPool) noexcept;
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
|
@ -10,10 +10,6 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
class SHVkLogicalDevice;
|
class SHVkLogicalDevice;
|
||||||
class SHVkFramebuffer;
|
class SHVkFramebuffer;
|
||||||
/*-----------------------------------------------------------------------*/
|
|
||||||
/* TYPE DEFINTIIONS */
|
|
||||||
/*-----------------------------------------------------------------------*/
|
|
||||||
using SHSubPassIndex = uint32_t;
|
|
||||||
|
|
||||||
class SHVkRenderpass
|
class SHVkRenderpass
|
||||||
{
|
{
|
||||||
|
|
|
@ -5,9 +5,13 @@
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
|
/*-----------------------------------------------------------------------*/
|
||||||
|
/* TYPE DEFINTIIONS */
|
||||||
|
/*-----------------------------------------------------------------------*/
|
||||||
using SHQueueFamilyIndex = uint32_t;
|
using SHQueueFamilyIndex = uint32_t;
|
||||||
using BindingAndSetHash = uint64_t;
|
using BindingAndSetHash = uint64_t;
|
||||||
using SetIndex = uint32_t;
|
using SetIndex = uint32_t;
|
||||||
|
using SHSubPassIndex = uint32_t;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -27,7 +27,7 @@ namespace SHADE
|
||||||
|
|
||||||
SHADE::SHShaderBlockInterface::Variable const* const SHShaderBlockInterface::GetVariable(uint32_t index) const noexcept
|
SHADE::SHShaderBlockInterface::Variable const* const SHShaderBlockInterface::GetVariable(uint32_t index) const noexcept
|
||||||
{
|
{
|
||||||
if (variableIndexing.size() < index)
|
if (index < variableIndexing.size())
|
||||||
return &variables.at(index);
|
return &variables.at(index);
|
||||||
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
|
@ -2,10 +2,12 @@
|
||||||
|
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
|
||||||
|
#include "SH_API.h"
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
|
|
||||||
class SHShaderBlockInterface
|
class SH_API SHShaderBlockInterface
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
struct Variable
|
struct Variable
|
||||||
|
|
|
@ -111,6 +111,7 @@ namespace SHADE
|
||||||
biggestAlignment = std::max(biggestAlignment, 4u);
|
biggestAlignment = std::max(biggestAlignment, 4u);
|
||||||
break;
|
break;
|
||||||
case SpvOp::SpvOpTypeStruct:
|
case SpvOp::SpvOpTypeStruct:
|
||||||
|
case SpvOp::SpvOpTypeRuntimeArray:
|
||||||
recurseForInfo(&member, interfaceHdl, member.offset, biggestAlignment, parentVarName + std::string(member.name) + ".");
|
recurseForInfo(&member, interfaceHdl, member.offset, biggestAlignment, parentVarName + std::string(member.name) + ".");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,7 +54,7 @@ namespace SHADE
|
||||||
/*-----------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------*/
|
||||||
/* Usage Functions */
|
/* Usage Functions */
|
||||||
/*-----------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------*/
|
||||||
inline Id GetId() const;
|
inline Id GetId() const noexcept;
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------*/
|
||||||
/* Overloaded Operators */
|
/* Overloaded Operators */
|
||||||
|
@ -62,7 +62,7 @@ namespace SHADE
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Converts to true if this is a valid Handle.
|
/// Converts to true if this is a valid Handle.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
inline operator bool() const;
|
inline operator bool() const noexcept;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/*-----------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------*/
|
||||||
|
@ -101,6 +101,7 @@ namespace SHADE
|
||||||
/*-----------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------*/
|
||||||
/* Overloaded Operators */
|
/* Overloaded Operators */
|
||||||
/*-----------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------*/
|
||||||
|
inline bool operator==(const Handle<T>& rhs) const noexcept;
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Returns the underlying object pointed to by the Handle.
|
/// Returns the underlying object pointed to by the Handle.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
@ -8,15 +8,15 @@ namespace SHADE
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
/* HandleBase - Usage Functions */
|
/* HandleBase - Usage Functions */
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
inline HandleBase::Id HandleBase::GetId() const
|
inline HandleBase::Id HandleBase::GetId() const noexcept
|
||||||
{
|
{
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
/* HandleBase - Overloaded Operators */
|
/* HandleBase - Overloaded Operators */
|
||||||
inline HandleBase::operator bool() const
|
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
inline HandleBase::operator bool() const noexcept
|
||||||
{
|
{
|
||||||
return id.Raw != INVALID_ID.Raw;
|
return id.Raw != INVALID_ID.Raw;
|
||||||
}
|
}
|
||||||
|
@ -33,6 +33,12 @@ namespace SHADE
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
/* Handle<T> - Overloaded Operators */
|
/* Handle<T> - Overloaded Operators */
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
template<typename T>
|
||||||
|
bool SHADE::Handle<T>::operator==(const Handle<T>& rhs) const noexcept
|
||||||
|
{
|
||||||
|
return id.Raw == rhs.id.Raw && library == rhs.library;
|
||||||
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
T& Handle<T>::operator*()
|
T& Handle<T>::operator*()
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,72 +1,44 @@
|
||||||
#version 450
|
#version 450
|
||||||
#extension GL_ARB_separate_shader_objects : enable
|
#extension GL_ARB_separate_shader_objects : enable
|
||||||
#extension GL_ARB_shading_language_420pack : 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
|
layout(location = 0) in struct
|
||||||
{
|
{
|
||||||
//mat3 BTN;
|
|
||||||
vec4 vertColor;
|
vec4 vertColor;
|
||||||
//vec3 localSpacePosition;
|
vec2 uv;
|
||||||
//vec2 uv;
|
|
||||||
//vec3 localLightPosition;
|
|
||||||
//vec3 localEyePosition;
|
|
||||||
|
|
||||||
} In;
|
} In;
|
||||||
|
|
||||||
//layout(std140, push_constant) uniform TestPushConstant
|
// material stuff
|
||||||
//{
|
layout(location = 2) flat in struct
|
||||||
// mat4 pvMat;
|
{
|
||||||
// vec4 lightPosition;
|
int materialIndex;
|
||||||
// vec4 eyePosition;
|
} In2;
|
||||||
// vec4 ambientColor;
|
|
||||||
// vec4 lightColor;
|
//layout (set = 0, binding = )
|
||||||
//
|
|
||||||
//} testPushConstant;
|
layout (set = 0, binding = 1) uniform sampler2D textures[]; // for textures (global)
|
||||||
|
layout (set = 3, binding = 0) buffer MaterialProperties // For materials
|
||||||
|
{
|
||||||
|
MatPropData data[];
|
||||||
|
} MatProp;
|
||||||
|
|
||||||
layout(location = 0) out vec4 outColor;
|
layout(location = 0) out vec4 outColor;
|
||||||
|
|
||||||
//layout(binding = 0) uniform sampler2D diffuseMap;
|
|
||||||
//layout(binding = 1) uniform sampler2D normalMap;
|
|
||||||
//layout(binding = 2) uniform sampler2D aoMap;
|
|
||||||
//layout(binding = 3) uniform sampler2D glossinessMap;
|
|
||||||
//layout(binding = 4) uniform sampler2D samplerRoughnessMap;
|
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
//vec3 normal;
|
|
||||||
|
|
||||||
//// Get the tangent space normal from normal map. It is a BC5 texture and therefore only use red and green
|
outColor = texture(textures[nonuniformEXT(MatProp.data[In2.materialIndex].textureIndex)], In.uv) +
|
||||||
//normal.xy = (texture (normalMap, In.uv).gr * 2.0f) - 1.0f;
|
MatProp.data[In2.materialIndex].color / MatProp.data[In2.materialIndex].alpha;
|
||||||
|
|
||||||
//// z value is derived (TODO: Find out what this does)
|
//outColor = vec4 (1.0f);
|
||||||
//normal.z = sqrt(1.0f - dot(normal.xy, normal.xy));
|
|
||||||
|
|
||||||
//// Transform the normal from tangent space to local space
|
|
||||||
//normal = In.BTN * normal;
|
|
||||||
|
|
||||||
//// Get the vector from fragment to light
|
|
||||||
//vec3 localLightDir = normalize(In.localLightPosition - In.localSpacePosition);
|
|
||||||
|
|
||||||
//// get the value of dot between normal from texture and frag to light
|
|
||||||
//float diffuse = max(0, dot(normal, localLightDir));
|
|
||||||
|
|
||||||
//// sample the diffuse texture
|
|
||||||
//vec4 diffuseColor = texture (diffuseMap, In.uv) * In.vertColor;
|
|
||||||
|
|
||||||
//vec3 eyeDirection = normalize(In.localSpacePosition - In.localEyePosition);
|
|
||||||
|
|
||||||
//const float shininess = mix(1, 100, 1 - texture (samplerRoughnessMap, In.uv).r);
|
|
||||||
|
|
||||||
//float specular = pow(max(0, dot(normal, normalize(localLightDir - eyeDirection))), shininess);
|
|
||||||
|
|
||||||
//outColor.rgb = testPushConstant.ambientColor.rgb * diffuseColor.rgb * texture (aoMap, In.uv).rgb;
|
|
||||||
|
|
||||||
//outColor.rgb += testPushConstant.lightColor.rgb * (specular.rrr * 0.4 + diffuse.rrr * diffuseColor.rgb);
|
|
||||||
|
|
||||||
//const float gamma = testPushConstant.eyePosition.w;
|
|
||||||
//outColor.rgb = pow(outColor.rgb, vec3(1.0f / gamma));
|
|
||||||
//outColor.a = diffuseColor.a;
|
|
||||||
|
|
||||||
|
|
||||||
outColor = vec4 (1.0f);
|
|
||||||
}
|
}
|
Binary file not shown.
|
@ -9,27 +9,20 @@ layout(location = 2) in vec3 aNormal;
|
||||||
layout(location = 3) in vec3 aTangent;
|
layout(location = 3) in vec3 aTangent;
|
||||||
layout(location = 4) in mat4 worldTransform;
|
layout(location = 4) in mat4 worldTransform;
|
||||||
|
|
||||||
//layout(std140, push_constant) uniform TestPushConstant
|
|
||||||
//{
|
|
||||||
// mat4 pvMat;
|
|
||||||
// vec4 lightPosition;
|
|
||||||
// vec4 eyePosition;
|
|
||||||
// vec4 ambientColor;
|
|
||||||
// vec4 lightColor;
|
|
||||||
//
|
|
||||||
//} testPushConstant;
|
|
||||||
|
|
||||||
layout(location = 0) out struct
|
layout(location = 0) out struct
|
||||||
{
|
{
|
||||||
//mat3 BTN;
|
vec4 vertColor; // location 0
|
||||||
vec4 vertColor;
|
vec2 uv; // location = 1
|
||||||
//vec3 localSpacePosition;
|
|
||||||
//vec2 uv;
|
|
||||||
//vec3 localLightPosition;
|
|
||||||
//vec3 localEyePosition;
|
|
||||||
|
|
||||||
} Out;
|
} Out;
|
||||||
|
|
||||||
|
// material stuff
|
||||||
|
layout(location = 2) out struct
|
||||||
|
{
|
||||||
|
int materialIndex;
|
||||||
|
} Out2;
|
||||||
|
|
||||||
layout(set = 2, binding = 0) uniform CameraData
|
layout(set = 2, binding = 0) uniform CameraData
|
||||||
{
|
{
|
||||||
vec4 position;
|
vec4 position;
|
||||||
|
@ -38,25 +31,8 @@ layout(set = 2, binding = 0) uniform CameraData
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
//const float gamma = testPushConstant.eyePosition.w;
|
Out.uv = aUV;
|
||||||
//mat4 W2L = inverse(worldTransform);
|
Out2.materialIndex = gl_InstanceIndex;
|
||||||
|
|
||||||
//// Since attributes are instanced we want the local positions of light and eye (camera)
|
|
||||||
//Out.localLightPosition = vec3(W2L * vec4(testPushConstant.lightPosition.xyz, 1.0f));
|
|
||||||
//Out.localEyePosition = vec3(W2L * vec4(testPushConstant.eyePosition.xyz, 1.0f));
|
|
||||||
|
|
||||||
//vec3 biTangent = normalize(cross(aNormal, aTangent));
|
|
||||||
|
|
||||||
//gl_Position = testPushConstant.pvMat * worldTransform * vec4(aVertexPos, 1.0);
|
|
||||||
|
|
||||||
//// Since the normal we are sampling is in tangent space, we want to later convert them to local space
|
|
||||||
//// so we need this matrix to multiply with the sampled texel of the normal map.
|
|
||||||
//Out.BTN = mat3(aTangent, biTangent, aNormal);
|
|
||||||
//Out.localSpacePosition = aVertexPos;
|
|
||||||
//Out.uv = aUV;
|
|
||||||
|
|
||||||
// render NDC first
|
|
||||||
//gl_Position = vec4(aVertexPos, 1.0f);
|
|
||||||
gl_Position = cameraData.vpMat * worldTransform * vec4 (aVertexPos, 1.0f);
|
gl_Position = cameraData.vpMat * worldTransform * vec4 (aVertexPos, 1.0f);
|
||||||
Out.vertColor = vec4 (aVertexPos, 1.0f);
|
Out.vertColor = vec4 (aVertexPos, 1.0f);
|
||||||
}
|
}
|
Binary file not shown.
Loading…
Reference in New Issue