Merge remote-tracking branch 'origin/SP3-1-Rendering' into SP3-1-Rendering

This commit is contained in:
Brandon Mak 2022-09-27 20:07:29 +08:00
commit 70940534e1
46 changed files with 5500 additions and 275 deletions

Binary file not shown.

4993
Assets/racoon.gltf Normal file

File diff suppressed because one or more lines are too long

View File

@ -144,7 +144,7 @@ if %_e%==14 (goto :done) else (goto :tinyddsloader)
:tinyddsloader
echo --------------------tinyddsloader-------------------------
rmdir "Dependencies/tinyddsloader" /S /Q
git clone https://github.com/benikabocha/tinyddsloader.git "Dependencies/tinyddsloader"
git clone https://github.com/SHADE-DP/tinyddsloader.git "Dependencies/tinyddsloader"
:done
echo DONE!

View File

@ -78,7 +78,7 @@ namespace Sandbox
SHADE::SHSystemManager::RegisterRoutine<SHADE::SHInputManagerSystem, SHADE::SHInputManagerSystem::InputManagerRoutine>();
//TODO: REMOVE AFTER PRESENTATION
SHADE::SHAssetManager::LoadDataTemp("../../Assets/racoon.fbx");
SHADE::SHAssetManager::LoadDataTemp("../../Assets/racoon.gltf");
SHADE::SHAssetManager::LoadDataTemp("../../Assets/RaccoonBag_Color_Ver4.dds");
SHADE::SHAssetManager::LoadDataTemp("../../Assets/RaccoonPreTexturedVer1_Base9.dds");
SHADE::SHAssetManager::LoadDataTemp("../../Assets/TD_Checker_Base_Color.dds");

View File

@ -42,7 +42,7 @@ namespace Sandbox
std::vector<Handle<SHMesh>> handles;
for (auto const& mesh : meshes)
{
handles.push_back(graphicsSystem->AddMesh(
handles.push_back(graphicsSystem->AddMesh(
mesh.header.vertexCount,
mesh.vertexPosition.data(),
mesh.texCoords.data(),
@ -55,7 +55,7 @@ namespace Sandbox
graphicsSystem->BuildMeshBuffers();
// Load Textures
auto textures = SHADE::SHAssetManager::GetAllDDS();
auto textures = SHADE::SHAssetManager::GetAllTextures();
std::vector<Handle<SHTexture>> texHandles;
for (const auto& tex : textures)
{
@ -98,15 +98,17 @@ namespace Sandbox
renderable.Mesh = handles.front();
renderable.SetMaterial(matInst);
transform.SetWorldPosition({0.0f, 0.0f, -1.0f});
transform.SetLocalScale(TEST_OBJ_SCALE);
////transform.SetLocalScale(TEST_OBJ_SCALE);
stressTestObjects.emplace_back(entity);
//stressTestObjects.emplace_back(entity);
// Create blank entity with a script
//testObj = SHADE::SHEntityManager::CreateEntity();
//SHADE::SHScriptEngine* scriptEngine = static_cast<SHADE::SHScriptEngine*>(SHADE::SHSystemManager::GetSystem<SHADE::SHScriptEngine>());
//scriptEngine->AddScript(testObj, "TestScript");
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>());
scriptEngine->AddScript(testObj, "TestScript");
}
void SBTestScene::Update(float dt)
@ -119,7 +121,7 @@ namespace Sandbox
rotation += dt * 10.0f;*/
static float rotation = 0.0f;
auto& transform = *SHADE::SHComponentManager::GetComponent_s<SHADE::SHTransformComponent>(stressTestObjects[0]);
auto& transform = *SHADE::SHComponentManager::GetComponent_s<SHADE::SHTransformComponent>(testObj);
transform.SetWorldRotation(0.0f, 0.0f + rotation, 0.0f);
rotation += dt * 0.2f;

View File

@ -1,11 +0,0 @@
#pragma once
#include "tinyddsloader.h"
namespace SHADE
{
struct SHDDSAsset
{
tinyddsloader::DDSFile image;
};
}

View File

@ -0,0 +1,46 @@
#pragma once
#include "tinyddsloader.h"
#include "Graphics/MiddleEnd/Textures/SHTextureLibrary.h"
#include <memory>
namespace SHADE
{
struct SHTextureAsset
{
uint32_t numBytes;
uint32_t width;
uint32_t height;
SHTexture::TextureFormat format;
std::vector<uint32_t> mipOffsets;
SHTexture::PixelChannel const * pixelData;
SHTextureAsset()
: numBytes{ 0 },
width{ 0 },
height{ 0 },
format{ SHTexture::TextureFormat::eUndefined },
pixelData{ nullptr }
{}
SHTextureAsset(SHTextureAsset const& rhs)
: numBytes{ rhs.numBytes },
width{ rhs.width },
height{ rhs.height },
format{ rhs.format },
mipOffsets{ rhs.mipOffsets },
pixelData(rhs.pixelData)
{}
//SHTextureAsset(SHTextureAsset&& rhs)
// : numBytes{ rhs.numBytes },
// width{ rhs.width },
// height{ rhs.height },
// format{ rhs.format },
// mipOffsets{ rhs.mipOffsets },
// pixelData(std::move(rhs.pixelData))
//{}
};
}

View File

@ -1,38 +0,0 @@
#include "SHpch.h"
#include "SHDDSLoader.h"
namespace SHADE
{
std::string SHDDSLoader::TinyDDSResultToString(tinyddsloader::Result value)
{
switch (value)
{
case tinyddsloader::Result::ErrorFileOpen:
return "File open err";
case tinyddsloader::Result::ErrorRead:
return "File read err";
case tinyddsloader::Result::ErrorMagicWord:
return "File header magicword err";
case tinyddsloader::Result::ErrorSize:
return "File size err";
case tinyddsloader::Result::ErrorVerify:
return "Pixel format err";
case tinyddsloader::Result::ErrorNotSupported:
return "Unsupported format";
case tinyddsloader::Result::ErrorInvalidData:
return "Invalid data";
default:
return "Unknown";
}
}
void SHDDSLoader::LoadImageAsset(AssetPath path, SHDDSAsset& asset)
{
tinyddsloader::Result loadResult = tinyddsloader::Result::Success;
loadResult = asset.image.Load(path.string().c_str());
if (loadResult != tinyddsloader::Result::Success)
{
SHLOG_ERROR("Unable to load DDS file: {} at {}", TinyDDSResultToString(loadResult), path.string());
}
}
}

View File

@ -1,18 +0,0 @@
#pragma once
#define TINYDDSLOADER_IMPLEMENTATION
#include "../SHAssetMacros.h"
#include "../Asset Types/SHDDSAsset.h"
#include "tinyddsloader.h"
#include <vector>
namespace SHADE
{
class SHDDSLoader
{
private:
static std::string TinyDDSResultToString(tinyddsloader::Result value);
public:
static void LoadImageAsset(AssetPath paths, SHDDSAsset& image);
};
}

View File

@ -100,9 +100,7 @@ namespace SHADE
| aiProcess_JoinIdenticalVertices
// join identical vertices/ optimize indexing
| aiProcess_RemoveRedundantMaterials // remove redundant materials
| aiProcess_FindInvalidData
// detect invalid model data, such as invalid normal vectors
| aiProcess_PreTransformVertices // pre-transform all vertices
| aiProcess_FindInvalidData// detect invalid model data, such as invalid normal vectors
| aiProcess_FlipUVs // flip the V to match the Vulkans way of doing UVs
);

View File

@ -0,0 +1,48 @@
#include "SHpch.h"
#include "SHMeshWriter.h"
#include <fstream>
void SHADE::SHMeshWriter::WriteMeshBinary(SHMeshAsset const& asset, AssetPath path) noexcept
{
std::ofstream file{path, std::ios::out | std::ios::binary};
if (!file.is_open())
{
SHLOG_ERROR("Unable to open file for writing mesh file: {}", path.string());
}
file.write(
reinterpret_cast<char const*>(&(asset.header.vertexCount)),
sizeof(uint32_t)
);
file.write(
reinterpret_cast<const char*>(&(asset.header.indexCount)),
sizeof(uint32_t)
);
auto const vertexVec3Byte {sizeof(SHVec3) * asset.header.vertexCount};
auto const vertexVec2Byte {sizeof(SHVec2) * asset.header.vertexCount};
file.write(
reinterpret_cast<char const*>(asset.vertexPosition.data()),
vertexVec3Byte
);
file.write(
reinterpret_cast<char const*>(asset.vertexTangent.data()),
vertexVec3Byte
);
file.write(
reinterpret_cast<char const*>(asset.vertexNormal.data()),
vertexVec3Byte
);
file.write(
reinterpret_cast<char const*>(asset.texCoords.data()),
vertexVec2Byte
);
file.close();
}

View File

@ -0,0 +1,14 @@
#pragma once
#include "../Asset Types/SHMeshAsset.h"
#include "../SHAssetMacros.h"
namespace SHADE
{
class SHMeshWriter
{
private:
public:
static void WriteMeshBinary(SHMeshAsset const& asset, AssetPath path) noexcept;
};
}

View File

@ -0,0 +1,92 @@
#include "SHpch.h"
#include "SHTextureLoader.h"
namespace SHADE
{
std::string SHTextureLoader::TinyDDSResultToString(tinyddsloader::Result value)
{
switch (value)
{
case tinyddsloader::Result::ErrorFileOpen:
return "File open err";
case tinyddsloader::Result::ErrorRead:
return "File read err";
case tinyddsloader::Result::ErrorMagicWord:
return "File header magic word err";
case tinyddsloader::Result::ErrorSize:
return "File size err";
case tinyddsloader::Result::ErrorVerify:
return "Pixel format err";
case tinyddsloader::Result::ErrorNotSupported:
return "Unsupported format";
case tinyddsloader::Result::ErrorInvalidData:
return "Invalid data";
default:
return "Unknown";
}
}
vk::Format SHTextureLoader::ddsLoaderToVkFormat(tinyddsloader::DDSFile::DXGIFormat format, bool isLinear)
{
switch (format)
{
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:
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.");
}
}
void SHTextureLoader::LoadImageAsset(AssetPath path, SHTextureAsset& asset)
{
tinyddsloader::Result loadResult = tinyddsloader::Result::Success;
tinyddsloader::DDSFile file;
loadResult = file.Load(path.string().c_str());
if (loadResult != tinyddsloader::Result::Success)
{
SHLOG_ERROR("Unable to load Texture file: {} at {}", TinyDDSResultToString(loadResult), path.string());
}
size_t totalBytes{ 0 };
std::vector<uint32_t> mipOff(file.GetMipCount());
for (auto i{0}; i < file.GetMipCount(); ++i)
{
mipOff[i] = totalBytes;
totalBytes += file.GetImageData(i, 0)->m_memSlicePitch;
}
SHTexture::PixelChannel* pixel = new SHTexture::PixelChannel[totalBytes];
std::memcpy(pixel, file.GetDDSData(), totalBytes);
//pixel = std::move(reinterpret_cast<SHTexture::PixelChannel const*>(file.GetDDSData()));
asset.numBytes = totalBytes;
asset.width = file.GetWidth();
asset.height = file.GetHeight();
asset.format = ddsLoaderToVkFormat(file.GetFormat(), true);
asset.mipOffsets = std::move(mipOff);
asset.pixelData = std::move(pixel);
}
}

View File

@ -0,0 +1,19 @@
#pragma once
#define TINYDDSLOADER_IMPLEMENTATION
#include "../SHAssetMacros.h"
#include "../Asset Types/SHTextureAsset.h"
#include "tinyddsloader.h"
namespace SHADE
{
class SHTextureLoader
{
private:
static std::string TinyDDSResultToString(tinyddsloader::Result value);
static vk::Format ddsLoaderToVkFormat(tinyddsloader::DDSFile::DXGIFormat format, bool isLinear);
public:
static void LoadImageAsset(AssetPath paths, SHTextureAsset& image);
};
}

View File

@ -69,8 +69,10 @@ enum class AssetType : uint8_t
#define SCENE_EXTENSION ".SHADE"
#define PREFAB_EXTENSION ".SHPrefab"
#define MATERIAL_EXTENSION ".SHMat"
#define TEXTURE_EXTENSION ".dds"
#define TEXTURE_EXTENSION ".shtex"
#define DDS_EXTENSION ".dds"
#define FBX_EXTENSION ".fbx"
#define GLTF_EXTENSION ".gltf"
#define MESH_EXTENSION ".shmesh"
std::string const EXTENSIONS[] = {
@ -79,12 +81,14 @@ std::string const EXTENSIONS[] = {
MATERIAL_EXTENSION,
IMAGE_EXTENSION,
TEXTURE_EXTENSION,
DDS_EXTENSION,
MESH_EXTENSION,
SCRIPT_EXTENSION,
SCENE_EXTENSION,
PREFAB_EXTENSION,
AUDIO_WAV_EXTENSION,
FBX_EXTENSION
FBX_EXTENSION,
GLTF_EXTENSION
};
// Error flags

View File

@ -15,7 +15,7 @@
#include "Filesystem/SHFileSystem.h"
#include "Libraries/SHMeshLoader.h"
#include "Libraries/SHDDSLoader.h"
#include "Libraries/SHTextureLoader.h"
namespace SHADE
{
@ -26,7 +26,7 @@ namespace SHADE
std::unordered_map<AssetID, SHAsset> SHAssetManager::assetRegistry;
std::unordered_map<AssetID, SHMeshAsset> SHAssetManager::meshCollection;
std::unordered_map<AssetID, SHDDSAsset> SHAssetManager::ddsCollection;
std::unordered_map<AssetID, SHTextureAsset> SHAssetManager::textureCollection;
/****************************************************************************
* \brief Static function to generate asset ID.
@ -199,7 +199,7 @@ namespace SHADE
{
AssetPath path{ p };
if (path.extension().string() == FBX_EXTENSION)
if (path.extension().string() == GLTF_EXTENSION)
{
LoadGLTF(
{
@ -211,7 +211,7 @@ namespace SHADE
}
);
}
else if (path.extension().string() == TEXTURE_EXTENSION)
else if (path.extension().string() == DDS_EXTENSION)
{
LoadDDS(
{
@ -236,10 +236,10 @@ namespace SHADE
return result;
}
std::vector<SHDDSAsset> SHAssetManager::GetAllDDS() noexcept
std::vector<SHTextureAsset> SHAssetManager::GetAllTextures() noexcept
{
std::vector<SHDDSAsset> result;
for (auto const& dds : ddsCollection)
std::vector<SHTextureAsset> result;
for (auto const& dds : textureCollection)
{
result.push_back(dds.second);
}
@ -305,11 +305,11 @@ namespace SHADE
void SHAssetManager::LoadDDS(SHAsset asset) noexcept
{
SHDDSAsset image;
SHTextureAsset image;
SHDDSLoader::LoadImageAsset(asset.path, image);
SHTextureLoader::LoadImageAsset(asset.path, image);
ddsCollection.emplace(GenerateAssetID(AssetType::DDS), image);
textureCollection.emplace(GenerateAssetID(AssetType::DDS), image);
}
/****************************************************************************

View File

@ -13,7 +13,7 @@
#include "SHAsset.h"
#include "Asset Types/SHMeshAsset.h"
#include "Asset Types/SHDDSAsset.h"
#include "Asset Types/SHTextureAsset.h"
#include "SH_API.h"
namespace SHADE
@ -73,7 +73,7 @@ namespace SHADE
//TODO: TEMPORARY FOR TESTING GLTF & DDS
static void LoadDataTemp(std::string path) noexcept;
static std::vector<SHMeshAsset> GetAllMeshes() noexcept;
static std::vector<SHDDSAsset> GetAllDDS() noexcept;
static std::vector<SHTextureAsset> GetAllTextures() noexcept;
private:
/****************************************************************************
@ -128,6 +128,6 @@ namespace SHADE
static std::unordered_map<AssetID, SHAsset> assetRegistry;
static std::unordered_map<AssetID, SHMeshAsset> meshCollection;
static std::unordered_map<AssetID, SHDDSAsset> ddsCollection;
static std::unordered_map<AssetID, SHTextureAsset> textureCollection;
};
}

View File

@ -41,7 +41,8 @@ namespace SHADE
{ vk::DescriptorType::eCombinedImageSampler, 100 },
{ vk::DescriptorType::eUniformBuffer, 100 },
{ vk::DescriptorType::eUniformBufferDynamic, 100 },
{ vk::DescriptorType::eStorageImage, 100}
{ vk::DescriptorType::eStorageImage, 100},
{ vk::DescriptorType::eStorageBufferDynamic, 100 }
};
/// <summary>
/// Maximum number of descriptor sets allowed

View File

@ -188,6 +188,7 @@ namespace SHADE
// point and lines fill mode
features.fillModeNonSolid = true;
features.samplerAnisotropy = VK_TRUE;
features.multiDrawIndirect = true;
// for wide lines
features.wideLines = true;

View File

@ -22,8 +22,11 @@ of DigiPen Institute of Technology is prohibited.
#include "Graphics/Pipeline/SHVkPipeline.h"
#include "Graphics/MiddleEnd/Interface/SHGraphicsConstants.h"
#include "Graphics/MiddleEnd/Interface/SHMaterialInstance.h"
#include "Graphics/Descriptors/SHVkDescriptorSetGroup.h"
#include "ECS_Base/Managers/SHComponentManager.h"
#include "Math/Transform/SHTransformComponent.h"
#include "Graphics/MiddleEnd/GlobalData/SHGraphicsGlobalData.h"
#include "Graphics/Descriptors/SHVkDescriptorPool.h"
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)
{
@ -154,21 +157,17 @@ namespace SHADE
if (!matBufferDirty[frameIndex])
return;
// Build CPI Buffer
// Build CPU Buffer
char* propsCurrPtr = matPropsData.get();
for (auto& subBatch : subBatches)
for (const SHRenderable* renderable : subBatch.Renderables)
{
renderable->GetMaterial()->ExportProperties(propsCurrPtr);
propsCurrPtr += singleMatPropSize;
propsCurrPtr += singleMatPropAlignedSize;
}
// Transfer to GPU
SHVkUtil::EnsureBufferAndCopyHostVisibleData
(
device, matPropsBuffer[frameIndex], matPropsData.get(), static_cast<uint32_t>(matPropsDataSize),
vk::BufferUsageFlagBits::eStorageBuffer
);
rebuildMaterialBuffers(frameIndex, descPool);
// This frame is updated
matBufferDirty[frameIndex] = false;
@ -207,7 +206,7 @@ namespace SHADE
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)
{
@ -247,7 +246,8 @@ namespace SHADE
if (!EMPTY_MAT_PROPS)
{
singleMatPropSize = SHADER_INFO->GetBytesRequired();
matPropTotalBytes = drawData.size() * singleMatPropSize;
singleMatPropAlignedSize = device->PadSSBOSize(singleMatPropSize);
matPropTotalBytes = drawData.size() * singleMatPropAlignedSize;
if (matPropsDataSize < matPropTotalBytes)
{
matPropsData.reset(new char[matPropTotalBytes]);
@ -289,7 +289,7 @@ namespace SHADE
if (!EMPTY_MAT_PROPS)
{
renderable->GetMaterial()->ExportProperties(propsCurrPtr);
propsCurrPtr += singleMatPropSize;
propsCurrPtr += singleMatPropAlignedSize;
}
}
}
@ -304,30 +304,24 @@ namespace SHADE
const uint32_t DRAW_DATA_BYTES = static_cast<uint32_t>(drawData.size() * sizeof(vk::DrawIndexedIndirectCommand));
SHVkUtil::EnsureBufferAndCopyHostVisibleData
(
_device, drawDataBuffer[frameIndex], drawData.data(), DRAW_DATA_BYTES,
device, drawDataBuffer[frameIndex], drawData.data(), DRAW_DATA_BYTES,
BuffUsage::eIndirectBuffer
);
// - Transform Buffer
const uint32_t TF_DATA_BYTES = static_cast<uint32_t>(transformData.size() * sizeof(SHMatrix));
SHVkUtil::EnsureBufferAndCopyHostVisibleData
(
_device, transformDataBuffer[frameIndex], transformData.data(), TF_DATA_BYTES,
device, transformDataBuffer[frameIndex], transformData.data(), TF_DATA_BYTES,
BuffUsage::eVertexBuffer
);
// - Material Properties Buffer
if (matPropsData)
{
SHVkUtil::EnsureBufferAndCopyHostVisibleData
(
_device, matPropsBuffer[frameIndex], matPropsData.get(), static_cast<uint32_t>(matPropsDataSize),
BuffUsage::eStorageBuffer
);
}
rebuildMaterialBuffers(frameIndex, descPool);
// Mark this frame as no longer dirty
isDirty[frameIndex] = false;
// Save logical device
this->device = _device;
this->device = device;
}
/*---------------------------------------------------------------------------------*/
@ -341,8 +335,20 @@ namespace SHADE
return;
}
// Bind all required objects before drawing
static std::array<uint32_t, 1> dynamicOffset { 0 };
cmdBuffer->BindPipeline(pipeline);
cmdBuffer->BindVertexBuffer(SHGraphicsConstants::VertexBufferBindings::TRANSFORM, transformDataBuffer[frameIndex], 0);
if (matPropsDescSet[frameIndex])
{
cmdBuffer->BindDescriptorSet
(
matPropsDescSet[frameIndex],
vk::PipelineBindPoint::eGraphics,
0,
dynamicOffset
);
}
cmdBuffer->DrawMultiIndirect(drawDataBuffer[frameIndex], static_cast<uint32_t>(drawData.size()));
}
@ -355,4 +361,39 @@ namespace SHADE
dirt = 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] },
{ static_cast<uint32_t>(drawData.size()) }
);
}
std::array<Handle<SHVkBuffer>, 1> bufferList = { matPropsBuffer[frameIndex] };
matPropsDescSet[frameIndex]->ModifyWriteDescBuffer
(
SHGraphicsConstants::DescriptorSetIndex::PER_INSTANCE,
SHGraphicsConstants::DescriptorSetBindings::BATCHED_PER_INST_DATA,
bufferList,
0, 1
);
matPropsDescSet[frameIndex]->UpdateDescriptorSetBuffer
(
SHGraphicsConstants::DescriptorSetIndex::PER_INSTANCE,
SHGraphicsConstants::DescriptorSetBindings::BATCHED_PER_INST_DATA
);
}
}
}

View File

@ -35,6 +35,8 @@ namespace SHADE
class SHRenderable;
class SHVkLogicalDevice;
class SHMaterialInstance;
class SHVkDescriptorSetGroup;
class SHVkDescriptorPool;
/*---------------------------------------------------------------------------------*/
/* Type Definitions */
@ -74,9 +76,9 @@ namespace SHADE
void Add(const SHRenderable* renderable);
void Remove(const SHRenderable* renderable);
void Clear();
void UpdateMaterialBuffer(uint32_t frameIndex);
void UpdateMaterialBuffer(uint32_t frameIndex, Handle<SHVkDescriptorPool> descPool);
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);
/*-----------------------------------------------------------------------------*/
@ -84,34 +86,44 @@ namespace SHADE
/*-----------------------------------------------------------------------------*/
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 */
/*-----------------------------------------------------------------------------*/
// Resources
Handle<SHVkLogicalDevice> device;
Handle<SHVkLogicalDevice> device;
// Batch Properties
Handle<SHVkPipeline> pipeline;
Handle<SHVkPipeline> pipeline;
std::unordered_set<Handle<SHMaterialInstance>> referencedMatInstances;
std::array<bool, SHGraphicsConstants::NUM_FRAME_BUFFERS> matBufferDirty;
TripleBool matBufferDirty;
// Batch Tree
std::vector<SHSubBatch> subBatches;
std::array<bool, SHGraphicsConstants::NUM_FRAME_BUFFERS> isDirty;
// CPU Buffers
std::vector<vk::DrawIndexedIndirectCommand> drawData;
std::vector<SHMatrix> transformData;
std::unique_ptr<char> matPropsData;
Byte matPropsDataSize = 0;
Byte singleMatPropSize = 0;
bool isCPUBuffersDirty = true;
// GPU Buffers
std::array<Handle<SHVkBuffer>, SHGraphicsConstants::NUM_FRAME_BUFFERS> drawDataBuffer;
std::array<Handle<SHVkBuffer>, SHGraphicsConstants::NUM_FRAME_BUFFERS> transformDataBuffer;
std::array<Handle<SHVkBuffer>, SHGraphicsConstants::NUM_FRAME_BUFFERS> matPropsBuffer;
std::vector<SHSubBatch> subBatches;
TripleBool isDirty;
// CPU Buffers
std::vector<vk::DrawIndexedIndirectCommand> drawData;
std::vector<SHMatrix> transformData;
std::unique_ptr<char> matPropsData;
Byte matPropsDataSize = 0;
Byte singleMatPropAlignedSize = 0;
Byte singleMatPropSize = 0;
bool isCPUBuffersDirty = true;
// GPU Buffers
TripleBuffer drawDataBuffer;
TripleBuffer transformDataBuffer;
TripleBuffer matPropsBuffer;
TripleDescSet matPropsDescSet;
/*-----------------------------------------------------------------------------*/
/* Helper Functions */
/*-----------------------------------------------------------------------------*/
void setAllDirtyFlags();
void rebuildMaterialBuffers(uint32_t frameIndex, Handle<SHVkDescriptorPool> descPool);
};
}

View File

@ -91,12 +91,12 @@ namespace SHADE
(*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
for (auto& batch : superBatches)
{
batch->Build(device, frameIndex);
batch->Build(device, descPool, frameIndex);
}
}
@ -109,11 +109,11 @@ namespace SHADE
superBatches.clear();
}
void SHBatcher::UpdateBuffers(uint32_t frameIndex)
void SHBatcher::UpdateBuffers(uint32_t frameIndex, Handle<SHVkDescriptorPool> descPool)
{
for (auto& batch : superBatches)
{
batch->UpdateBuffers(frameIndex);
batch->UpdateBuffers(frameIndex, descPool);
}
}

View File

@ -27,6 +27,7 @@ namespace SHADE
class SHSuperBatch;
class SHVkLogicalDevice;
class SHVkCommandBuffer;
class SHVkDescriptorPool;
/*---------------------------------------------------------------------------------*/
/* Type Definitions */
@ -51,9 +52,9 @@ namespace SHADE
void PrepareBatches();
void AddToBatch(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 UpdateBuffers(uint32_t frameIndex);
void UpdateBuffers(uint32_t frameIndex, Handle<SHVkDescriptorPool> descPool);
void RegisterSuperBatch(Handle<SHSuperBatch> superBatch);
void DeregisterSuperBatch(Handle<SHSuperBatch> superBatch);

View File

@ -16,6 +16,7 @@ of DigiPen Institute of Technology is prohibited.
#include "SHBatch.h"
#include "Graphics/MiddleEnd/Interface/SHMaterialInstance.h"
#include "Graphics/MiddleEnd/Interface/SHRenderable.h"
#include "Graphics/Descriptors/SHVkDescriptorPool.h"
namespace SHADE
{
@ -78,21 +79,21 @@ namespace SHADE
batches.clear();
}
void SHSuperBatch::UpdateBuffers(uint32_t frameIndex)
void SHSuperBatch::UpdateBuffers(uint32_t frameIndex, Handle<SHVkDescriptorPool> descPool)
{
for (auto& batch : batches)
{
batch.UpdateMaterialBuffer(frameIndex);
batch.UpdateMaterialBuffer(frameIndex, descPool);
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
for (auto& batch : batches)
{
batch.Build(device, frameIndex);
batch.Build(device, descPool, frameIndex);
}
}

View File

@ -55,8 +55,8 @@ namespace SHADE
void Add(const SHRenderable* renderable) noexcept;
void Remove(const SHRenderable* renderable) noexcept;
void Clear() noexcept;
void UpdateBuffers(uint32_t frameIndex);
void Build(Handle<SHVkLogicalDevice> device, uint32_t frameIndex) noexcept;
void UpdateBuffers(uint32_t frameIndex, Handle<SHVkDescriptorPool> descPool);
void Build(Handle<SHVkLogicalDevice> device, Handle<SHVkDescriptorPool> descPool, uint32_t frameIndex) noexcept;
void Draw(Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex) noexcept;
/*-----------------------------------------------------------------------------*/

View File

@ -7,7 +7,17 @@
namespace SHADE
{
/*-----------------------------------------------------------------------------------*/
/* Static Definitions */
/*-----------------------------------------------------------------------------------*/
std::vector<Handle<SHVkDescriptorSetLayout>> SHGraphicsGlobalData::globalDescSetLayouts;
Handle<SHVkDescriptorSetGroup> SHGraphicsGlobalData::globalDescSets;
SHVertexInputState SHGraphicsGlobalData::defaultVertexInputState;
Handle<SHVkPipelineLayout> SHGraphicsGlobalData::dummyPipelineLayout;
/*-----------------------------------------------------------------------------------*/
/* Function Definitions */
/*-----------------------------------------------------------------------------------*/
void SHGraphicsGlobalData::InitDescSetLayouts(Handle<SHVkLogicalDevice> logicalDevice) noexcept
{
SHVkDescriptorSetLayout::Binding genericDataBinding
@ -87,18 +97,18 @@ namespace SHADE
InitDefaultVertexInputState();
}
std::vector<Handle<SHVkDescriptorSetLayout>> const& SHGraphicsGlobalData::GetDescSetLayouts(void) const noexcept
std::vector<Handle<SHVkDescriptorSetLayout>> const& SHGraphicsGlobalData::GetDescSetLayouts(void) noexcept
{
return globalDescSetLayouts;
}
SHVertexInputState const& SHGraphicsGlobalData::GetDefaultViState(void) const noexcept
SHVertexInputState const& SHGraphicsGlobalData::GetDefaultViState(void) noexcept
{
return defaultVertexInputState;
}
Handle<SHVkPipelineLayout> SHGraphicsGlobalData::GetDummyPipelineLayout(void) const noexcept
Handle<SHVkPipelineLayout> SHGraphicsGlobalData::GetDummyPipelineLayout(void) noexcept
{
return dummyPipelineLayout;
}

View File

@ -15,31 +15,37 @@ namespace SHADE
{
private:
//! Global descriptor set layouts. Used to allocate descriptor sets
std::vector<Handle<SHVkDescriptorSetLayout>> globalDescSetLayouts;
static std::vector<Handle<SHVkDescriptorSetLayout>> globalDescSetLayouts;
//! Global Descriptor sets
Handle<SHVkDescriptorSetGroup> globalDescSets;
static Handle<SHVkDescriptorSetGroup> globalDescSets;
//! 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,
//! we create a dummy pipeline layout to use it for binding.
Handle<SHVkPipelineLayout> dummyPipelineLayout;
static Handle<SHVkPipelineLayout> dummyPipelineLayout;
static void InitDescSetLayouts (Handle<SHVkLogicalDevice> logicalDevice) noexcept;
static void InitDefaultVertexInputState(void) noexcept;
void InitDescSetLayouts (Handle<SHVkLogicalDevice> logicalDevice) noexcept;
void InitDefaultVertexInputState(void) noexcept;
public:
/*-----------------------------------------------------------------------*/
/* Constructors */
/*-----------------------------------------------------------------------*/
SHGraphicsGlobalData() = delete;
/*-----------------------------------------------------------------------*/
/* PUBLIC MEMBER FUNCTIONS */
/*-----------------------------------------------------------------------*/
void Init (Handle<SHVkLogicalDevice> logicalDevice) noexcept;
static void Init (Handle<SHVkLogicalDevice> logicalDevice) noexcept;
/*-----------------------------------------------------------------------*/
/* SETTERS AND GETTERS */
/*-----------------------------------------------------------------------*/
std::vector<Handle<SHVkDescriptorSetLayout>> const& GetDescSetLayouts (void) const noexcept;
SHVertexInputState const& GetDefaultViState (void) const noexcept;
Handle<SHVkPipelineLayout> GetDummyPipelineLayout (void) const noexcept;
static std::vector<Handle<SHVkDescriptorSetLayout>> const& GetDescSetLayouts (void) noexcept;
static SHVertexInputState const& GetDefaultViState (void) noexcept;
static Handle<SHVkPipelineLayout> GetDummyPipelineLayout (void) noexcept;
};
}

View File

@ -31,7 +31,7 @@ of DigiPen Institute of Technology is prohibited.
#include "Graphics/MiddleEnd/GlobalData/SHGraphicsGlobalData.h"
#include "Graphics/Buffers/SHVkBuffer.h"
#include "Graphics/Images/SHVkSampler.h"
#include "Assets/Asset Types/SHDDSAsset.h"
#include "Assets/Asset Types/SHTextureAsset.h"
namespace SHADE
{
@ -110,8 +110,7 @@ namespace SHADE
- Global data
/*-----------------------------------------------------------------------*/
globalData = resourceManager.Create<SHGraphicsGlobalData>();
globalData->Init(device);
SHGraphicsGlobalData::Init(device);
// Set Up Cameras
screenCamera = resourceManager.Create<SHCamera>();
@ -135,7 +134,7 @@ namespace SHADE
}
// 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, swapchain->GetDepthFormat());
//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);
@ -177,7 +176,7 @@ namespace SHADE
debugWorldRenderer->SetCamera(worldCamera);*/
// 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);
@ -250,7 +249,7 @@ namespace SHADE
// Begin recording the command buffer
currentCmdBuffer->BeginRecording();
currentCmdBuffer->ForceSetPipelineLayout(globalData->GetDummyPipelineLayout());
currentCmdBuffer->ForceSetPipelineLayout(SHGraphicsGlobalData::GetDummyPipelineLayout());
// Bind all the buffers required for meshes
for (auto& [buffer, bindingPoint] : MESH_DATA)
@ -261,22 +260,26 @@ namespace SHADE
currentCmdBuffer->BindIndexBuffer(buffer, 0);
}
std::array<uint32_t, 1> texDynamicOffset {0};
// Bind textures
currentCmdBuffer->BindDescriptorSet
(
texLibrary.GetTextureDescriptorSetGroup(),
auto textureDescSet = texLibrary.GetTextureDescriptorSetGroup();
if (textureDescSet)
{
std::array<uint32_t, 1> texDynamicOffset {0};
currentCmdBuffer->BindDescriptorSet
(
textureDescSet,
vk::PipelineBindPoint::eGraphics,
0,
std::span<uint32_t, 1>{texDynamicOffset.data(), texDynamicOffset.size()}
);
texDynamicOffset
);
}
// bind camera data
renderers[renIndex]->UpdateDataAndBind(currentCmdBuffer, frameIndex);
// Draw first
renderers[renIndex]->Draw(frameIndex);
renderers[renIndex]->Draw(frameIndex, descPool);
// End the command buffer recording
currentCmdBuffer->EndRecording();
@ -329,7 +332,7 @@ namespace SHADE
for (auto vp : viewports)
for (auto renderer : vp->GetRenderers())
{
renderer->GetRenderGraph()->FinaliseBatch(renderContext.GetCurrentFrame());
renderer->GetRenderGraph()->FinaliseBatch(renderContext.GetCurrentFrame(), descPool);
}
// Resize
@ -481,10 +484,10 @@ namespace SHADE
/*---------------------------------------------------------------------------------*/
/* Texture Registration Functions */
/*---------------------------------------------------------------------------------*/
Handle<SHTexture> SHGraphicsSystem::Add(const SHDDSAsset& ddsAsset)
Handle<SHTexture> SHGraphicsSystem::Add(const SHTextureAsset& texAsset)
{
auto sampler = samplerCache.GetSampler(device, SHVkSamplerParams { .maxLod = static_cast<float>(ddsAsset.image.GetMipCount()) });
return texLibrary.Add(ddsAsset, sampler);
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)
@ -502,8 +505,7 @@ namespace SHADE
{
texLibrary.BuildTextures
(
device, graphicsTexCmdBuffer, graphicsQueue, descPool,
globalData->GetDescSetLayouts()[SHGraphicsConstants::DescriptorSetIndex::STATIC_GLOBALS]
device, graphicsTexCmdBuffer, graphicsQueue, descPool
);
}
@ -542,9 +544,13 @@ namespace SHADE
oldSuperBatch->Remove(&renderable);
}
// Add to new SuperBatch
Handle<SHSuperBatch> newSuperBatch = renderable.GetMaterial()->GetBaseMaterial()->GetPipeline()->GetPipelineState().GetSubpass()->GetSuperBatch();
newSuperBatch->Add(&renderable);
// Add to new SuperBatch if there is a material
Handle<SHMaterialInstance> newMatInstance = renderable.GetMaterial();
if (newMatInstance)
{
Handle<SHSuperBatch> newSuperBatch = newMatInstance->GetBaseMaterial()->GetPipeline()->GetPipelineState().GetSubpass()->GetSuperBatch();
newSuperBatch->Add(&renderable);
}
// Unset change flag
renderable.ResetChangedFlag();

View File

@ -215,7 +215,7 @@ namespace SHADE
*/
/*******************************************************************************/
Handle<SHTexture> Add(const SHDDSAsset& ddsAsset);
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);
/*******************************************************************************/
/*!
@ -287,9 +287,6 @@ namespace SHADE
// Not Owned Resources
SHWindow* window = nullptr;
// global data (descriptor sets as well)
Handle<SHGraphicsGlobalData> globalData;
// Middle End Resources
ResourceManager resourceManager;
SHMeshLibrary meshLibrary;

View File

@ -60,9 +60,9 @@ namespace SHADE
/*-----------------------------------------------------------------------------------*/
/* 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

View File

@ -74,7 +74,7 @@ namespace SHADE
/*-----------------------------------------------------------------------------*/
/* 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 UpdateCameraDataToBuffer (void) noexcept;

View File

@ -11,7 +11,7 @@ namespace SHADE
SHPipelineLayoutParams params
{
.shaderModules = {vsFsPair.first, vsFsPair.second},
.globalDescSetLayouts = globalData->GetDescSetLayouts()
.globalDescSetLayouts = SHGraphicsGlobalData::GetDescSetLayouts()
};
// Create the pipeline layout
@ -19,7 +19,7 @@ namespace SHADE
// Create the pipeline and configure the default vertex input state
auto newPipeline = logicalDevice->CreateGraphicsPipeline(pipelineLayout, nullptr, renderpass, subpass);
newPipeline->GetPipelineState().SetVertexInputState(globalData->GetDefaultViState());
newPipeline->GetPipelineState().SetVertexInputState(SHGraphicsGlobalData::GetDefaultViState());
// Actually construct the pipeline
newPipeline->ConstructPipeline();
@ -30,10 +30,9 @@ namespace SHADE
return newPipeline;
}
void SHPipelineLibrary::Init(Handle<SHVkLogicalDevice> device, Handle<SHGraphicsGlobalData> inGlobalData) noexcept
void SHPipelineLibrary::Init(Handle<SHVkLogicalDevice> device) noexcept
{
logicalDevice = device;
globalData = inGlobalData;
}
Handle<SHVkPipeline> SHPipelineLibrary::GetDrawPipline(std::pair<Handle<SHVkShaderModule>, Handle<SHVkShaderModule>> const& vsFsPair) noexcept

View File

@ -24,14 +24,9 @@ namespace SHADE
//! 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;
// Global data
Handle<SHGraphicsGlobalData> globalData;
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
Handle<SHVkPipeline> CreateDrawPipeline (

View File

@ -22,39 +22,24 @@ of DigiPen Institute of Technology is prohibited.
#include "Tools/SHLogger.h"
#include "Graphics/MiddleEnd/Interface/SHGraphicsConstants.h"
#include "Graphics/Descriptors/SHVkDescriptorSetGroup.h"
#include "Assets/Asset Types/SHDDSAsset.h"
#include "Graphics/Images/SHVkImage.h"
#include "Graphics/MiddleEnd/GlobalData/SHGraphicsGlobalData.h"
#include "Assets/Asset Types/SHTextureAsset.h"
namespace SHADE
{
/*---------------------------------------------------------------------------------*/
/* Usage Functions */
/*---------------------------------------------------------------------------------*/
Handle<SHTexture> SHTextureLibrary::Add(const SHDDSAsset& ddsAsset, Handle<SHVkSampler> sampler)
Handle<SHTexture> SHTextureLibrary::Add(const SHTextureAsset& texAsset, Handle<SHVkSampler> sampler)
{
// Define constants
const uint32_t IMG_WIDTH = ddsAsset.image.GetWidth();
const uint32_t IMG_HEIGHT = ddsAsset.image.GetHeight();
const uint32_t MIPMAP_LEVEL = ddsAsset.image.GetMipCount();
// Compute total texture size and create buffer image copy objects
std::vector<uint32_t> mipOffsets(MIPMAP_LEVEL);
uint32_t texBytes = 0;
for (uint32_t i = 0; i < MIPMAP_LEVEL; i++)
{
mipOffsets[i] = texBytes;
// Get ready for next mip
texBytes += ddsAsset.image.GetImageData(i)->m_memSlicePitch;
}
return Add
(
texBytes,
reinterpret_cast<const SHTexture::PixelChannel*>(ddsAsset.image.m_dds.data()),
IMG_WIDTH, IMG_HEIGHT,
ddsLoaderToVkFormat(ddsAsset.image.GetFormat(), true),
mipOffsets,
texAsset.numBytes,
texAsset.pixelData,
texAsset.width, texAsset.height,
texAsset.format,
texAsset.mipOffsets,
sampler
);
}
@ -77,7 +62,7 @@ namespace SHADE
isDirty = true;
}
void SHTextureLibrary::BuildTextures(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)
@ -168,23 +153,29 @@ namespace SHADE
}
addJobs.clear();
/* Build Descriptor Set with all the Textures */
if (!texDescriptors)
/* Build Descriptor Set with all the Textures only if there are textures */
if (!texOrder.empty())
{
texDescriptors = descPool->Allocate({ descLayout }, { static_cast<uint32_t>(texOrder.size()) });
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
);
}
const auto ALIGNED_SIZE = device->PadSSBOSize(sizeof(uint32_t));
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;
}

View File

@ -37,7 +37,7 @@ namespace SHADE
class SHVkDescriptorSetLayout;
class SHVkDescriptorSetGroup;
class SHVkSampler;
struct SHDDSAsset;
class SHTextureAsset;
/*---------------------------------------------------------------------------------*/
/* Type Definitions */
@ -94,7 +94,7 @@ namespace SHADE
*/
/*******************************************************************************/
Handle<SHTexture> Add(const SHDDSAsset& ddsAsset, Handle<SHVkSampler> sampler);
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);
/*******************************************************************************/
/*!
@ -125,7 +125,7 @@ namespace SHADE
queue.
*/
/***************************************************************************/
void BuildTextures(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 */

View File

@ -328,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;
swapchainHdl = swapchain;
globalData = inGlobalData;
}
/***************************************************************************/
@ -364,7 +363,6 @@ namespace SHADE
, nodes{ std::move(rhs.nodes) }
, graphResources{ std::move(rhs.graphResources) }
, resourceManager{ std::move(rhs.resourceManager) }
, globalData{ rhs.globalData }
{
}
@ -380,7 +378,6 @@ namespace SHADE
nodes = std::move(rhs.nodes);
graphResources = std::move(rhs.graphResources);
resourceManager = std::move(rhs.resourceManager);
globalData = rhs.globalData;
return *this;
}
@ -438,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);
return nodes.at(nodeIndexing[nodeName]);
}
@ -466,20 +463,20 @@ namespace SHADE
// TODO: The graph scope buffers were meant to bind vertex buffers and index buffers for meshes. Find a
// 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
cmdBuffer->SetViewportScissor(1920.0f, 1080.0f, 1920, 1080);
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)
{
node->FinaliseBatch(frameIndex);
node->FinaliseBatch(frameIndex, descPool);
}
}

View File

@ -61,9 +61,6 @@ namespace SHADE
//! Resource library for graph handles
ResourceManager resourceManager;
//! Handle to global data
Handle<SHGraphicsGlobalData> globalData;
public:
/*-----------------------------------------------------------------------*/
@ -77,12 +74,12 @@ namespace SHADE
/*-----------------------------------------------------------------------*/
/* 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 = {});
Handle<SHRenderGraphNode> AddNode (std::string nodeName, std::initializer_list<std::string> resourceNames, std::initializer_list<std::string> predecessorNodes) noexcept;
void Generate (void) noexcept;
void Execute (uint32_t frameIndex, Handle<SHVkCommandBuffer> cmdBuffer) noexcept;
void FinaliseBatch(uint32_t frameIndex);
void Execute (uint32_t frameIndex, Handle<SHVkCommandBuffer> cmdBuffer, Handle<SHVkDescriptorPool> descPool) noexcept;
void FinaliseBatch(uint32_t frameIndex, Handle<SHVkDescriptorPool> descPool);
/*-----------------------------------------------------------------------*/
/* SETTERS AND GETTERS */

View File

@ -76,7 +76,7 @@ namespace SHADE
*/
/***************************************************************************/
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
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{}
@ -91,7 +91,7 @@ namespace SHADE
, ptrToResources{ resources }
{
// pipeline library initialization
pipelineLibrary.Init(logicalDeviceHdl, globalData);
pipelineLibrary.Init(logicalDeviceHdl);
attachmentDescriptions.resize(attResources.size());
@ -207,14 +207,14 @@ namespace SHADE
return subpass;
}
void SHRenderGraphNode::Execute(Handle<SHVkCommandBuffer>& commandBuffer, uint32_t frameIndex) noexcept
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, frameIndex);
subpasses[i]->Execute(commandBuffer, descPool, frameIndex);
// Go to next subpass if not last subpass
if (i != subpasses.size() - 1)
@ -247,9 +247,9 @@ namespace SHADE
return pipeline;
}
void SHRenderGraphNode::FinaliseBatch(uint32_t frameIndex)
void SHRenderGraphNode::FinaliseBatch(uint32_t frameIndex, Handle<SHVkDescriptorPool> descPool)
{
batcher.FinaliseBatches(logicalDeviceHdl, frameIndex);
batcher.FinaliseBatches(logicalDeviceHdl, descPool, frameIndex);
}
/***************************************************************************/

View File

@ -17,6 +17,7 @@ namespace SHADE
class SHRenderGraphResource;
class SHVkLogicalDevice;
class SHVkRenderpass;
class SHVkDescriptorPool;
class SH_API SHRenderGraphNode : public ISelfHandle<SHRenderGraphNode>
{
@ -85,7 +86,7 @@ namespace SHADE
/*-----------------------------------------------------------------------*/
/* 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(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;
@ -94,9 +95,9 @@ namespace SHADE
/*-----------------------------------------------------------------------*/
Handle<SHSubpass> AddSubpass(std::string subpassName) noexcept;
// TODO: RemoveSubpass()
void Execute(Handle<SHVkCommandBuffer>& commandBuffer, uint32_t frameIndex) noexcept;
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);
void FinaliseBatch(uint32_t frameIndex, Handle<SHVkDescriptorPool> descPool);
/*-----------------------------------------------------------------------*/
/* SETTERS AND GETTERS */

View File

@ -156,10 +156,10 @@ namespace SHADE
inputReferences.push_back({ resourceAttachmentMapping->at(ptrToResources->at(resourceToReference).GetId().Raw), vk::ImageLayout::eShaderReadOnlyOptimal });
}
void SHSubpass::Execute(Handle<SHVkCommandBuffer>& commandBuffer, uint32_t frameIndex) noexcept
void SHSubpass::Execute(Handle<SHVkCommandBuffer>& commandBuffer, Handle<SHVkDescriptorPool> descPool, uint32_t frameIndex) noexcept
{
// Ensure correct transforms are provided
superBatch->UpdateBuffers(frameIndex);
superBatch->UpdateBuffers(frameIndex, descPool);
// Draw all the batches
superBatch->Draw(commandBuffer, frameIndex);

View File

@ -14,6 +14,7 @@ namespace SHADE
class SHRenderGraphResource;
class SHVkCommandBuffer;
class SHVkDescriptorSetLayout;
class SHVkDescriptorPool;
class SH_API SHSubpass : public ISelfHandle<SHSubpass>
{
@ -74,7 +75,7 @@ namespace SHADE
void AddInput(std::string resourceToReference) noexcept;
// Runtime functions
void Execute(Handle<SHVkCommandBuffer>& commandBuffer, uint32_t frameIndex) noexcept;
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;

View File

@ -1,6 +1,8 @@
#include "SHPch.h"
#include "SHWindowMap.h"
#include "SHWindow.h"
#include "ECS_Base/Managers/SHSystemManager.h"
#include "Input/SHInputManagerSystem.h"
namespace SHADE
@ -339,6 +341,14 @@ namespace SHADE
OnPosChange(reinterpret_cast<LPWINDOWPOS>(lparam));
break;
}
case WM_MOUSEWHEEL:
{
if (auto im = SHSystemManager::GetSystem<SHInputManagerSystem>())
{
im->PollWheelVerticalDelta(wparam);
}
break;
}
default:
return ::DefWindowProc(hwnd, msg, wparam, lparam);
}

View File

@ -12,6 +12,7 @@
#pragma once
//#include <Xinput.h>
//#include "../../SHADE_Managed/src/SHpch.h"
#include "SH_API.h"
#include "ECS_Base/System/SHSystem.h"
#include "ECS_Base/System/SHFixedSystemRoutine.h"

View File

@ -54,7 +54,7 @@ namespace SHADE
/*-----------------------------------------------------------------------------*/
/* Usage Functions */
/*-----------------------------------------------------------------------------*/
inline Id GetId() const;
inline Id GetId() const noexcept;
/*-----------------------------------------------------------------------------*/
/* Overloaded Operators */
@ -62,7 +62,7 @@ namespace SHADE
/// <summary>
/// Converts to true if this is a valid Handle.
/// </summary>
inline operator bool() const;
inline operator bool() const noexcept;
protected:
/*-----------------------------------------------------------------------------*/
@ -101,6 +101,7 @@ namespace SHADE
/*-----------------------------------------------------------------------------*/
/* Overloaded Operators */
/*-----------------------------------------------------------------------------*/
inline bool operator==(const Handle<T>& rhs) const noexcept;
/// <summary>
/// Returns the underlying object pointed to by the Handle.
/// </summary>

View File

@ -8,15 +8,15 @@ namespace SHADE
/*---------------------------------------------------------------------------------*/
/* HandleBase - Usage Functions */
/*---------------------------------------------------------------------------------*/
inline HandleBase::Id HandleBase::GetId() const
inline HandleBase::Id HandleBase::GetId() const noexcept
{
return id;
}
/*---------------------------------------------------------------------------------*/
/* HandleBase - Overloaded Operators */
inline HandleBase::operator bool() const
/*---------------------------------------------------------------------------------*/
inline HandleBase::operator bool() const noexcept
{
return id.Raw != INVALID_ID.Raw;
}
@ -33,6 +33,12 @@ namespace SHADE
/*---------------------------------------------------------------------------------*/
/* 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>
T& Handle<T>::operator*()
{

View File

@ -38,5 +38,6 @@ void main()
{
vec4 color;
color = (texture (textures[1], In.uv));
//outColor = vec4(1.0f);
outColor = color;
}