From 51eba31ad4d5a5ea6a9ca3a6637c0e5de41a57a4 Mon Sep 17 00:00:00 2001 From: Xiao Qi Date: Wed, 19 Oct 2022 18:38:11 +0800 Subject: [PATCH 01/13] Added animation asset class Added animation reading from assimp scene Separated assimp loading from mesh loader in preparation for exe use --- SHADE_Engine/SHAnimationAsset.h | 30 ++++ .../src/Assets/Asset Types/SHAnimationAsset.h | 30 ++++ .../src/Assets/Libraries/SHAssimpLibrary.cpp | 143 ++++++++++++++++ .../src/Assets/Libraries/SHAssimpLibrary.h | 36 ++++ .../src/Assets/Libraries/SHMeshLoader.cpp | 162 ------------------ .../src/Assets/Libraries/SHMeshLoader.h | 16 +- SHADE_Engine/src/Assets/SHAssetManager.cpp | 77 +++++---- SHADE_Engine/src/Assets/SHAssetManager.h | 9 +- 8 files changed, 287 insertions(+), 216 deletions(-) create mode 100644 SHADE_Engine/SHAnimationAsset.h create mode 100644 SHADE_Engine/src/Assets/Asset Types/SHAnimationAsset.h create mode 100644 SHADE_Engine/src/Assets/Libraries/SHAssimpLibrary.cpp create mode 100644 SHADE_Engine/src/Assets/Libraries/SHAssimpLibrary.h diff --git a/SHADE_Engine/SHAnimationAsset.h b/SHADE_Engine/SHAnimationAsset.h new file mode 100644 index 00000000..d8d0ffb1 --- /dev/null +++ b/SHADE_Engine/SHAnimationAsset.h @@ -0,0 +1,30 @@ +/*************************************************************************//** + * \file SHAnimationAsset.h + * \author Loh Xiao Qi + * \date October 2022 + * \brief + * + * 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 + +#include +#include +#include "SH_API.power h" + +namespace SHADE +{ + struct SH_API SHAnimationAsset + { + std::string name; + + std::vector nodeChannels; + std::vector meshChannels; + std::vector morphMeshChannels; + + double duration; + double ticksPerSecond; + }; +} \ No newline at end of file diff --git a/SHADE_Engine/src/Assets/Asset Types/SHAnimationAsset.h b/SHADE_Engine/src/Assets/Asset Types/SHAnimationAsset.h new file mode 100644 index 00000000..76f4c0ac --- /dev/null +++ b/SHADE_Engine/src/Assets/Asset Types/SHAnimationAsset.h @@ -0,0 +1,30 @@ +/*************************************************************************//** + * \file SHAnimationAsset.h + * \author Loh Xiao Qi + * \date October 2022 + * \brief + * + * 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 + +#include +#include +#include "SH_API.h" + +namespace SHADE +{ + struct SH_API SHAnimationAsset + { + std::string name; + + std::vector nodeChannels; + std::vector meshChannels; + std::vector morphMeshChannels; + + double duration; + double ticksPerSecond; + }; +} \ No newline at end of file diff --git a/SHADE_Engine/src/Assets/Libraries/SHAssimpLibrary.cpp b/SHADE_Engine/src/Assets/Libraries/SHAssimpLibrary.cpp new file mode 100644 index 00000000..feea9f35 --- /dev/null +++ b/SHADE_Engine/src/Assets/Libraries/SHAssimpLibrary.cpp @@ -0,0 +1,143 @@ +/*************************************************************************//** + * \file SHAssimpLibrary.cpp + * \author Loh Xiao Qi + * \date October 2022 + * \brief + * + * 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 "SHAssimpLibrary.h" +#include + +namespace SHADE +{ + Assimp::Importer SHAssimpLibrary::aiImporter; + + void SHAssimpLibrary::ProcessNode(aiNode const& node, aiScene const& scene, MeshVectorRef meshes) noexcept + { + for (size_t i {0}; i < node.mNumMeshes; ++i) + { + aiMesh* mesh = scene.mMeshes[node.mMeshes[i]]; + meshes.push_back(ProcessMesh(*mesh)); + } + + for (size_t i{ 0 }; i < node.mNumChildren; ++i) + { + ProcessNode(*node.mChildren[i], scene, meshes); + } + } + + void SHAssimpLibrary::ExtractAnimations(aiScene const& scene, AnimVectorRef anims) noexcept + { + if (scene.HasAnimations()) + { + std::vector anims(scene.mNumAnimations); + for (auto i{0}; i < scene.mNumAnimations; ++i) + { + auto const& anim {*scene.mAnimations[i]}; + + anims[i].name = anim.mName.C_Str(); + + anims[i].duration = anim.mDuration; + anims[i].ticksPerSecond = anim.mTicksPerSecond; + + std::copy_n(anim.mChannels, anim.mNumChannels, anims[i].nodeChannels.data()); + std::copy_n(anim.mMeshChannels, anim.mNumMeshChannels, anims[i].meshChannels.data()); + std::copy_n(anim.mMorphMeshChannels, anim.mNumMorphMeshChannels, anims[i].morphMeshChannels.data()); + } + } + } + + SHMeshAsset SHAssimpLibrary::ProcessMesh(aiMesh const& mesh) noexcept + { + SHMeshAsset result + { + .compiled { false}, + .changed { false } + }; + + for (size_t i{0}; i < mesh.mNumVertices; ++i) + { + // Vertex position + SHVec3 vertex; + vertex.x = mesh.mVertices[i].x; + vertex.y = mesh.mVertices[i].y; + vertex.z = mesh.mVertices[i].z; + result.vertexPosition.push_back(vertex); + + // Tex coords + SHVec2 texCoord{0.f, 0.f}; + if (mesh.mTextureCoords[0]) + { + texCoord.x = mesh.mTextureCoords[0][i].x; + texCoord.y = mesh.mTextureCoords[0][i].y; + } + result.texCoords.push_back(texCoord); + + // Normals + SHVec3 normal{0.f, 0.f, 0.f}; + if (mesh.mNormals) + { + normal.x = mesh.mNormals[i].x; + normal.y = mesh.mNormals[i].y; + normal.z = mesh.mNormals[i].z; + } + result.vertexNormal.push_back(normal); + + // Tangent + SHVec3 tangent{0.f, 0.f, 0.f}; + if (mesh.mTangents) + { + tangent.x = mesh.mTangents[i].x; + tangent.y = mesh.mTangents[i].y; + tangent.z = mesh.mTangents[i].z; + } + result.vertexTangent.push_back(tangent); + } + + for (size_t i {0}; i < mesh.mNumFaces; ++i) + { + aiFace face = mesh.mFaces[i]; + for (size_t j{0}; j < face.mNumIndices; ++j) + { + result.indices.push_back(face.mIndices[j]); + } + } + + result.header.vertexCount = static_cast(result.vertexPosition.size()); + result.header.indexCount = static_cast(result.indices.size()); + result.header.meshName = mesh.mName.C_Str(); + + return result; + } + + void SHAssimpLibrary::LoadFromFile(AssetPath path, MeshVectorRef meshes, AnimVectorRef anims) noexcept + { + const aiScene* scene = aiImporter.ReadFile(path.string().c_str(), + aiProcess_Triangulate // Make sure we get triangles rather than nvert polygons + | aiProcess_GenUVCoords // Convert any type of mapping to uv mapping + | aiProcess_TransformUVCoords // preprocess UV transformations (scaling, translation ...) + | aiProcess_FindInstances // search for instanced meshes and remove them by references to one master + | aiProcess_CalcTangentSpace // calculate tangents and bitangents if possible + | aiProcess_JoinIdenticalVertices // join identical vertices/ optimize indexing + | aiProcess_RemoveRedundantMaterials // remove redundant materials + | aiProcess_FindInvalidData // detect invalid model data, such as invalid normal vectors + | aiProcess_FlipUVs // flip the V to match the Vulkans way of doing UVs + ); + + if (!scene || !scene->HasMeshes()) + { + SHLOG_ERROR("ERROR in GLTF::ASSIMP: {}\nFile: {}", aiImporter.GetErrorString(), path.string()); + return; + } + + ExtractAnimations(*scene, anims); + + ProcessNode(*scene->mRootNode, *scene, meshes); + + aiImporter.FreeScene(); + } +} diff --git a/SHADE_Engine/src/Assets/Libraries/SHAssimpLibrary.h b/SHADE_Engine/src/Assets/Libraries/SHAssimpLibrary.h new file mode 100644 index 00000000..a4a0447a --- /dev/null +++ b/SHADE_Engine/src/Assets/Libraries/SHAssimpLibrary.h @@ -0,0 +1,36 @@ +/*************************************************************************//** + * \file SHAssimpLibrary.h + * \author Loh Xiao Qi + * \date October 2022 + * \brief + * + * 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 +#include +#include +#include +#include "../SHAssetMacros.h" +#include "../Asset Types/SHMeshAsset.h" +#include "../Asset Types/SHAnimationAsset.h" + +namespace SHADE +{ + class SHAssimpLibrary + { + private: + using MeshVectorRef = std::vector&; + using AnimVectorRef = std::vector&; + + static Assimp::Importer aiImporter; + static void ProcessNode(aiNode const& node, aiScene const& scene,MeshVectorRef meshes) noexcept; + static void ExtractAnimations(aiScene const& scene, AnimVectorRef anims) noexcept; + static SHMeshAsset ProcessMesh(aiMesh const& mesh) noexcept; + + public: + static void LoadFromFile(AssetPath path, MeshVectorRef meshes, AnimVectorRef anims) noexcept; + }; +} \ No newline at end of file diff --git a/SHADE_Engine/src/Assets/Libraries/SHMeshLoader.cpp b/SHADE_Engine/src/Assets/Libraries/SHMeshLoader.cpp index 4bfa2d9b..73fed1fb 100644 --- a/SHADE_Engine/src/Assets/Libraries/SHMeshLoader.cpp +++ b/SHADE_Engine/src/Assets/Libraries/SHMeshLoader.cpp @@ -12,128 +12,10 @@ *****************************************************************************/ #include "SHpch.h" #include "SHMeshLoader.h" -#include #include namespace SHADE { - Assimp::Importer SHMeshLoader::aiImporter; - - void SHMeshLoader::ProcessNode(aiNode const& node, aiScene const& scene, std::vector& meshes) noexcept - { - for (size_t i {0}; i < node.mNumMeshes; ++i) - { - aiMesh* mesh = scene.mMeshes[node.mMeshes[i]]; - meshes.push_back(ProcessMesh(*mesh, scene)); - } - - for (size_t i{ 0 }; i < node.mNumChildren; ++i) - { - ProcessNode(*node.mChildren[i], scene, meshes); - } - } - - SHMeshAsset SHMeshLoader::ProcessMesh(aiMesh const& mesh, aiScene const& scene) noexcept - { - (void)scene; - - SHMeshAsset result - { - .compiled { false}, - .changed { false } - }; - - for (size_t i{0}; i < mesh.mNumVertices; ++i) - { - // Vertex position - SHVec3 vertex; - vertex.x = mesh.mVertices[i].x; - vertex.y = mesh.mVertices[i].y; - vertex.z = mesh.mVertices[i].z; - result.vertexPosition.push_back(vertex); - - // Tex coords - SHVec2 texCoord{0.f, 0.f}; - if (mesh.mTextureCoords[0]) - { - texCoord.x = mesh.mTextureCoords[0][i].x; - texCoord.y = mesh.mTextureCoords[0][i].y; - } - result.texCoords.push_back(texCoord); - - // Normals - SHVec3 normal{0.f, 0.f, 0.f}; - if (mesh.mNormals) - { - normal.x = mesh.mNormals[i].x; - normal.y = mesh.mNormals[i].y; - normal.z = mesh.mNormals[i].z; - } - result.vertexNormal.push_back(normal); - - // Tangent - SHVec3 tangent{0.f, 0.f, 0.f}; - if (mesh.mTangents) - { - tangent.x = mesh.mTangents[i].x; - tangent.y = mesh.mTangents[i].y; - tangent.z = mesh.mTangents[i].z; - } - result.vertexTangent.push_back(tangent); - } - - for (size_t i {0}; i < mesh.mNumFaces; ++i) - { - aiFace face = mesh.mFaces[i]; - for (size_t j{0}; j < face.mNumIndices; ++j) - { - result.indices.push_back(face.mIndices[j]); - } - } - - result.header.vertexCount = static_cast(result.vertexPosition.size()); - result.header.indexCount = static_cast(result.indices.size()); - result.header.meshName = mesh.mName.C_Str(); - - return result; - } - - void SHMeshLoader::LoadExternal(std::vector& meshes, AssetPath path) noexcept - { - const aiScene* scene = aiImporter.ReadFile(path.string().c_str(), - aiProcess_Triangulate // Make sure we get triangles rather than nvert polygons - | aiProcess_GenUVCoords // Convert any type of mapping to uv mapping - | aiProcess_TransformUVCoords // preprocess UV transformations (scaling, translation ...) - | aiProcess_FindInstances // search for instanced meshes and remove them by references to one master - | aiProcess_CalcTangentSpace // calculate tangents and bitangents if possible - | aiProcess_JoinIdenticalVertices // join identical vertices/ optimize indexing - | aiProcess_RemoveRedundantMaterials // remove redundant materials - | aiProcess_FindInvalidData // detect invalid model data, such as invalid normal vectors - | aiProcess_FlipUVs // flip the V to match the Vulkans way of doing UVs - ); - - if (!scene || !scene->HasMeshes()) - { - SHLOG_ERROR("ERROR in GLTF::ASSIMP: {}\nFile: {}", aiImporter.GetErrorString(), path.string()); - return; - } - - //TODO MATERIALS FROM MESHES - //if (scene->HasMaterials()) - //{ - // for (int i{0}; i < scene->mNumMaterials; ++i) - // { - // if (scene->mMaterials[i]->mNumProperties > 0) - // { - // for (int j{0}; j < scene->mMaterials[i]->mProperties[j].) - // } - //std::cout << scene->mMaterials[i]->; - // } - //} - - ProcessNode(*scene->mRootNode, *scene, meshes); - } - void SHMeshLoader::LoadSHMesh(SHMeshAsset& mesh, AssetPath path) noexcept { std::ifstream file{ path.string(), std::ios::in | std::ios::binary }; @@ -168,38 +50,6 @@ namespace SHADE file.read(reinterpret_cast(vertNorm.data()), vertexVec3Byte); file.read(reinterpret_cast(texCoord.data()), vertexVec2Byte); file.read(reinterpret_cast(indices.data()), sizeof(uint32_t) * indexCount); - - //for (auto i{ 0 }; i < vertCount; ++i) - //{ - // file >> vertPos[i].x; - // file >> vertPos[i].y; - // file >> vertPos[i].z; - //} - // - //for (auto i{ 0 }; i < vertCount; ++i) - //{ - // file >> vertTan[i].x; - // file >> vertTan[i].y; - // file >> vertTan[i].z; - //} - - //for (auto i{ 0 }; i < vertCount; ++i) - //{ - // file >> vertNorm[i].x; - // file >> vertNorm[i].y; - // file >> vertNorm[i].z; - //} - - //for (auto i{ 0 }; i < vertCount; ++i) - //{ - // file >> texCoord[i].x; - // file >> texCoord[i].y; - //} - - //for (auto i{ 0 }; i < indexCount; ++i) - //{ - // file >> indices[i]; - //} mesh.compiled = true; mesh.changed = false; @@ -216,16 +66,4 @@ namespace SHADE file.close(); } - - void SHMeshLoader::LoadMesh(std::vector& meshes, AssetPath path) noexcept - { - if (path.extension().string() == GLTF_EXTENSION) - { - LoadExternal(meshes, path); - return; - } - - meshes.emplace_back(); - LoadSHMesh(meshes.back(), path); - } } diff --git a/SHADE_Engine/src/Assets/Libraries/SHMeshLoader.h b/SHADE_Engine/src/Assets/Libraries/SHMeshLoader.h index a27d63ea..f01b942a 100644 --- a/SHADE_Engine/src/Assets/Libraries/SHMeshLoader.h +++ b/SHADE_Engine/src/Assets/Libraries/SHMeshLoader.h @@ -10,27 +10,13 @@ * of DigiPen Institute of Technology is prohibited. *****************************************************************************/ #pragma once -#include -#include #include "../SHAssetMacros.h" #include "../Asset Types/SHMeshAsset.h" -#include namespace SHADE { - class SHMeshLoader + struct SHMeshLoader { - private: - static Assimp::Importer aiImporter; - - static void ProcessNode(aiNode const& node, aiScene const& scene, std::vector& meshes) noexcept; - - static SHMeshAsset ProcessMesh(aiMesh const& mesh, aiScene const& scene) noexcept; - - static void LoadExternal(std::vector& meshes, AssetPath path) noexcept; - - public: - static void LoadMesh(std::vector& meshes, AssetPath path) noexcept; static void LoadSHMesh(SHMeshAsset& meshes, AssetPath path) noexcept; }; } \ No newline at end of file diff --git a/SHADE_Engine/src/Assets/SHAssetManager.cpp b/SHADE_Engine/src/Assets/SHAssetManager.cpp index aa9772dd..faca24b2 100644 --- a/SHADE_Engine/src/Assets/SHAssetManager.cpp +++ b/SHADE_Engine/src/Assets/SHAssetManager.cpp @@ -14,6 +14,7 @@ #include "SHAssetMetaHandler.h" #include "Filesystem/SHFileSystem.h" +#include "Libraries/SHAssimpLibrary.h" #include "Libraries/SHMeshLoader.h" #include "Libraries/SHTextureLoader.h" @@ -200,38 +201,38 @@ namespace SHADE } - void SHAssetManager::LoadDataTemp(std::string p) noexcept - { - AssetPath path{ p }; + //void SHAssetManager::LoadDataTemp(std::string p) noexcept + //{ + // AssetPath path{ p }; - if (path.extension().string() == FBX_EXTENSION - || path.extension().string() == GLTF_EXTENSION - || path.extension().string() == MESH_EXTENSION) - { - LoadGLTF( - { - .name {path.filename().string()}, - .id {0}, - .type {AssetType::MESH}, - .path {path}, - .location {0} - } - ); - } - else if (path.extension().string() == DDS_EXTENSION - || path.extension().string() == TEXTURE_EXTENSION) - { - LoadDDS( - { - .name {path.filename().string()}, - .id {0}, - .type {AssetType::DDS}, - .path {path}, - .location {0} - } - ); - } - } + // if (path.extension().string() == FBX_EXTENSION + // || path.extension().string() == GLTF_EXTENSION + // || path.extension().string() == MESH_EXTENSION) + // { + // LoadGLTF( + // { + // .name {path.filename().string()}, + // .id {0}, + // .type {AssetType::MESH}, + // .path {path}, + // .location {0} + // } + // ); + // } + // else if (path.extension().string() == DDS_EXTENSION + // || path.extension().string() == TEXTURE_EXTENSION) + // { + // LoadDDS( + // { + // .name {path.filename().string()}, + // .id {0}, + // .type {AssetType::DDS}, + // .path {path}, + // .location {0} + // } + // ); + // } + //} std::vector SHAssetManager::GetAllMeshes() noexcept { @@ -319,11 +320,12 @@ namespace SHADE return false; } - void SHAssetManager::LoadGLTF(SHAsset asset) noexcept + void SHAssetManager::LoadGLTF(AssetPath path) noexcept { std::vector meshes; - - SHMeshLoader::LoadMesh(meshes, asset.path); + std::vector anims; + + SHAssimpLibrary::LoadFromFile(path, meshes, anims); for (auto const& mesh : meshes) { @@ -333,7 +335,7 @@ namespace SHADE AssetPath path; if (!mesh.compiled) { - path = SHMeshCompiler::CompileMeshBinary(mesh, asset.path); + path = SHMeshCompiler::CompileMeshBinary(mesh, path); } assetCollection.emplace_back( @@ -344,6 +346,11 @@ namespace SHADE 0 ); } + + for (auto const& anim : anims) + { + //TODO Register anim resource and compile into binary + } } void SHAssetManager::LoadDDS(SHAsset asset) noexcept diff --git a/SHADE_Engine/src/Assets/SHAssetManager.h b/SHADE_Engine/src/Assets/SHAssetManager.h index 50549e01..b2c4216b 100644 --- a/SHADE_Engine/src/Assets/SHAssetManager.h +++ b/SHADE_Engine/src/Assets/SHAssetManager.h @@ -71,12 +71,16 @@ namespace SHADE // -------------------------------------------------------------------------/ //TODO: TEMPORARY FOR TESTING GLTF & DDS - static void LoadDataTemp(std::string path) noexcept; + //static void LoadDataTemp(std::string path) noexcept; static std::vector GetAllMeshes() noexcept; static std::vector GetAllTextures() noexcept; static SHMeshAsset const* GetMesh(AssetID id) noexcept; static SHTextureAsset const* GetTexture(AssetID id) noexcept; + + // Specialised load calls + static void LoadGLTF(AssetPath path) noexcept; + static void LoadDDS(SHAsset asset) noexcept; private: /**************************************************************************** * \brief Load resource data into memory @@ -118,9 +122,6 @@ namespace SHADE static bool IsRecognised(char const*) noexcept; - // Specialised load calls - static void LoadGLTF(SHAsset asset) noexcept; - static void LoadDDS(SHAsset asset) noexcept; static FMOD::System* audioSystem; static std::unordered_map* audioSoundList; From c177dabcd04890fbc9483c2fd066ab77b65a2725 Mon Sep 17 00:00:00 2001 From: Brandon Mak Date: Thu, 20 Oct 2022 19:36:43 +0800 Subject: [PATCH 02/13] WIP (not working) --- .../Graphics/Devices/SHVkLogicalDevice.cpp | 9 +++++ .../src/Graphics/Devices/SHVkLogicalDevice.h | 7 +++- .../MiddleEnd/Pipeline/SHPipelineLibrary.cpp | 14 ++++---- .../MiddleEnd/Pipeline/SHPipelineLibrary.h | 8 ++--- .../Graphics/RenderGraph/SHRenderGraph.cpp | 31 +++++++++-------- .../src/Graphics/RenderGraph/SHRenderGraph.h | 11 ++++--- .../RenderGraph/SHRenderGraphNode.cpp | 30 ++++++++--------- .../Graphics/RenderGraph/SHRenderGraphNode.h | 9 ++--- .../RenderGraph/SHRenderGraphResource.cpp | 17 +++++----- .../RenderGraph/SHRenderGraphResource.h | 3 +- .../RenderGraph/SHRenderGraphStorage.h | 33 +++++++++++++++++++ .../src/Graphics/RenderGraph/SHSubpass.cpp | 16 +++++++-- .../src/Graphics/RenderGraph/SHSubpass.h | 13 +++++++- .../Graphics/RenderGraph/SHSubpassCompute.cpp | 21 +++++++++--- .../Graphics/RenderGraph/SHSubpassCompute.h | 22 ++++++++++--- 15 files changed, 172 insertions(+), 72 deletions(-) create mode 100644 SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphStorage.h diff --git a/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.cpp b/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.cpp index 7c7acfc5..a6b415a9 100644 --- a/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.cpp +++ b/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.cpp @@ -233,6 +233,8 @@ namespace SHADE , vmaAllocator{rhs.vmaAllocator} , nonDedicatedBestIndex {0} , parentPhysicalDeviceHdl {rhs.parentPhysicalDeviceHdl} + , uboBufferMemoryAlignment{ 0 } + , ssboBufferMemoryAlignment{ 0 } { rhs.vkLogicalDevice = VK_NULL_HANDLE; } @@ -261,6 +263,8 @@ namespace SHADE vmaAllocator = rhs.vmaAllocator; nonDedicatedBestIndex = 0; parentPhysicalDeviceHdl = rhs.parentPhysicalDeviceHdl; + uboBufferMemoryAlignment = rhs.uboBufferMemoryAlignment; + ssboBufferMemoryAlignment = rhs.ssboBufferMemoryAlignment; rhs.vkLogicalDevice = VK_NULL_HANDLE; @@ -529,6 +533,11 @@ namespace SHADE } + Handle SHVkLogicalDevice::CreateComputePipeline(Handle const& pipelineLayoutHdl) noexcept + { + return SHVkInstance::GetResourceManager().Create (GetHandle(), pipelineLayoutHdl); + } + Handle SHVkLogicalDevice::CreateSampler(const SHVkSamplerParams& params) noexcept { return SHVkInstance::GetResourceManager().Create (GetHandle(), params); diff --git a/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.h b/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.h index 6f7048b8..58d8b398 100644 --- a/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.h +++ b/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.h @@ -175,12 +175,17 @@ namespace SHADE std::string const& shaderName ) noexcept; - Handle CreateGraphicsPipeline ( + Handle CreateGraphicsPipeline ( Handle const& pipelineLayoutHdl, SHVkPipelineState const* const state, Handle const& renderpassHdl, Handle subpass ) noexcept; + + Handle CreateComputePipeline ( + Handle const& pipelineLayoutHdl + ) noexcept; + Handle CreateSampler (const SHVkSamplerParams& params) noexcept; Handle CreateRenderpass (std::span const vkDescriptions, std::vector const& subpasses) noexcept; diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Pipeline/SHPipelineLibrary.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Pipeline/SHPipelineLibrary.cpp index 682b549c..495a3d37 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Pipeline/SHPipelineLibrary.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Pipeline/SHPipelineLibrary.cpp @@ -8,7 +8,7 @@ namespace SHADE { - Handle SHPipelineLibrary::CreateDrawPipeline(std::pair, Handle> const& vsFsPair, Handle renderpass, Handle subpass) noexcept + Handle SHPipelineLibrary::CreateGraphicsPipelines(std::pair, Handle> const& vsFsPair, Handle renderpass, Handle subpass) noexcept { SHPipelineLayoutParams params { @@ -52,7 +52,7 @@ namespace SHADE newPipeline->ConstructPipeline(); // Emplace the new pipeline - pipelines.emplace (vsFsPair, newPipeline); + graphicsPipelines.emplace (vsFsPair, newPipeline); return newPipeline; } @@ -62,19 +62,19 @@ namespace SHADE logicalDevice = device; } - Handle SHPipelineLibrary::GetDrawPipline(std::pair, Handle> const& vsFsPair) noexcept + Handle SHPipelineLibrary::GetGraphicsPipeline(std::pair, Handle> const& vsFsPair) noexcept { // return the pipeline requested for - if (pipelines.contains(vsFsPair)) - return pipelines.at(vsFsPair); + if (graphicsPipelines.contains(vsFsPair)) + return graphicsPipelines.at(vsFsPair); else return {}; } - bool SHPipelineLibrary::CheckDrawPipelineExistence(std::pair, Handle> const& vsFsPair) noexcept + bool SHPipelineLibrary::CheckGraphicsPipelineExistence(std::pair, Handle> const& vsFsPair) noexcept { // Returns if a pipeline exists or not - return pipelines.contains(vsFsPair); + return graphicsPipelines.contains(vsFsPair); } } \ No newline at end of file diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Pipeline/SHPipelineLibrary.h b/SHADE_Engine/src/Graphics/MiddleEnd/Pipeline/SHPipelineLibrary.h index 9a411d25..aeb023c5 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Pipeline/SHPipelineLibrary.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Pipeline/SHPipelineLibrary.h @@ -23,19 +23,19 @@ namespace SHADE Handle logicalDevice; //! a map of pipelines that are hashed using a pair of shader module handles - std::unordered_map, Handle>, Handle> pipelines; + std::unordered_map, Handle>, Handle> graphicsPipelines; public: void Init (Handle device) noexcept; // Draw pipeline functions. used only when creating pipelines for drawing using a vertex and fragment shader - Handle CreateDrawPipeline ( + Handle CreateGraphicsPipelines ( std::pair, Handle> const& vsFsPair, Handle renderpass, Handle subpass ) noexcept; - Handle GetDrawPipline (std::pair, Handle> const& vsFsPair) noexcept; - bool CheckDrawPipelineExistence (std::pair, Handle> const& vsFsPair) noexcept; + Handle GetGraphicsPipeline (std::pair, Handle> const& vsFsPair) noexcept; + bool CheckGraphicsPipelineExistence (std::pair, Handle> const& vsFsPair) noexcept; }; } diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp index 98cb6709..1db410c0 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp @@ -9,6 +9,7 @@ #include "Graphics/Buffers/SHVkBuffer.h" #include "Tools/SHLogger.h" #include "SHAttachmentDescInitParams.h" +#include "SHRenderGraphStorage.h" namespace SHADE { @@ -52,12 +53,12 @@ namespace SHADE // If we set to if (w == static_cast(-1) && h == static_cast(-1)) { - w = swapchainHdl->GetSwapchainImage(0)->GetWidth(); - h = swapchainHdl->GetSwapchainImage(0)->GetHeight(); - format = swapchainHdl->GetSurfaceFormatKHR().format; + w = renderGraphStorage->swapchain->GetSwapchainImage(0)->GetWidth(); + h = renderGraphStorage->swapchain->GetSwapchainImage(0)->GetHeight(); + format = renderGraphStorage->swapchain->GetSurfaceFormatKHR().format; } - graphResources.try_emplace(resourceName, resourceManager->Create(logicalDeviceHdl, swapchainHdl, resourceName, typeFlags, format, w, h, levels, usageFlags, createFlags)); + graphResources.try_emplace(resourceName, resourceManager->Create(renderGraphStorage, resourceName, typeFlags, format, w, h, levels, usageFlags, createFlags)); } /***************************************************************************/ @@ -343,10 +344,15 @@ namespace SHADE */ /***************************************************************************/ - void SHRenderGraph::Init(Handle const& logicalDevice, Handle const& swapchain) noexcept + void SHRenderGraph::Init(Handle logicalDevice, Handle swapchain) noexcept { - logicalDeviceHdl = logicalDevice; - swapchainHdl = swapchain; + renderGraphStorage = resourceManager->Create(); + + renderGraphStorage->logicalDevice = logicalDevice; + renderGraphStorage->swapchain = swapchain; + + renderGraphStorage->resourceManager = resourceManager; + renderGraphStorage->descriptorPool = logicalDevice->CreateDescriptorPools(); } /***************************************************************************/ @@ -361,8 +367,7 @@ namespace SHADE */ /***************************************************************************/ SHRenderGraph::SHRenderGraph(void) noexcept - : logicalDeviceHdl{ } - , swapchainHdl{ } + : renderGraphStorage{} , nodes{} , graphResources{} , resourceManager{nullptr} @@ -371,8 +376,7 @@ namespace SHADE } SHRenderGraph::SHRenderGraph(SHRenderGraph&& rhs) noexcept - : logicalDeviceHdl{ rhs.logicalDeviceHdl } - , swapchainHdl{ rhs.swapchainHdl } + : renderGraphStorage{ rhs.renderGraphStorage } , nodeIndexing{ std::move(rhs.nodeIndexing) } , nodes{ std::move(rhs.nodes) } , graphResources{ std::move(rhs.graphResources) } @@ -386,8 +390,7 @@ namespace SHADE if (&rhs == this) return *this; - logicalDeviceHdl = rhs.logicalDeviceHdl; - swapchainHdl = rhs.swapchainHdl; + renderGraphStorage = rhs.renderGraphStorage; nodeIndexing = std::move(rhs.nodeIndexing); nodes = std::move(rhs.nodes); graphResources = std::move(rhs.graphResources); @@ -456,7 +459,7 @@ namespace SHADE } } - nodes.emplace_back(resourceManager->Create(resourceManager, logicalDeviceHdl, swapchainHdl, std::move(descInitParams), std::move(predecessors), &graphResources)); + nodes.emplace_back(resourceManager->Create(renderGraphStorage, std::move(descInitParams), std::move(predecessors), &graphResources)); nodeIndexing.emplace(nodeName, static_cast(nodes.size()) - 1u); return nodes.at(nodeIndexing[nodeName]); } diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.h b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.h index 952c6d8f..9dbfa6d3 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.h +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.h @@ -30,7 +30,8 @@ namespace SHADE class SHVkCommandBuffer; class SHRenderGraphNode; class SHGraphicsGlobalData; - + class SHVkDescriptorPool; + class SHRenderGraphStorage; class SH_API SHRenderGraph { @@ -56,10 +57,12 @@ namespace SHADE /*-----------------------------------------------------------------------*/ /* PRIVATE MEMBER VARIABLES */ /*-----------------------------------------------------------------------*/ - Handle logicalDeviceHdl; + //Handle logicalDeviceHdl; //! swapchain used for querying image count - Handle swapchainHdl; + //Handle swapchainHdl; + + Handle renderGraphStorage; //! For indexing render graph node container std::map nodeIndexing; @@ -85,7 +88,7 @@ namespace SHADE /*-----------------------------------------------------------------------*/ /* PUBLIC MEMBER FUNCTIONS */ /*-----------------------------------------------------------------------*/ - void Init (Handle const& logicalDevice, Handle const& swapchain) noexcept; + void Init (Handle logicalDevice, Handle swapchain) noexcept; void AddResource(std::string resourceName, std::initializer_list typeFlags, uint32_t w = static_cast(-1), uint32_t h = static_cast(-1), vk::Format format = vk::Format::eB8G8R8A8Unorm, uint8_t levels = 1, vk::ImageUsageFlagBits usageFlags = {}, vk::ImageCreateFlagBits createFlags = {}); Handle AddNode (std::string nodeName, std::initializer_list resourceInstruction, std::initializer_list predecessorNodes) noexcept; diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.cpp b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.cpp index ec184386..f9b3c42d 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.cpp +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.cpp @@ -6,6 +6,7 @@ #include "Graphics/Framebuffer/SHVkFramebuffer.h" #include "SHRenderGraphResource.h" #include "SHSubpass.h" +#include "SHRenderGraphStorage.h" namespace SHADE { @@ -21,7 +22,7 @@ namespace SHADE /***************************************************************************/ void SHRenderGraphNode::CreateRenderpass(void) noexcept { - renderpass = logicalDeviceHdl->CreateRenderpass(attachmentDescriptions, spDescs, spDeps); + renderpass = graphStorage->logicalDevice->CreateRenderpass(attachmentDescriptions, spDescs, spDeps); } /***************************************************************************/ @@ -53,7 +54,7 @@ namespace SHADE } - framebuffers[i] = logicalDeviceHdl->CreateFramebuffer(renderpass, imageViews, fbWidth, fbHeight); + framebuffers[i] = graphStorage->logicalDevice->CreateFramebuffer(renderpass, imageViews, fbWidth, fbHeight); } } @@ -104,8 +105,8 @@ namespace SHADE */ /***************************************************************************/ - SHRenderGraphNode::SHRenderGraphNode(std::shared_ptr rm, Handle const& logicalDevice, Handle const& swapchain, std::vector attDescInitParams, std::vector> predecessors, std::unordered_map> const* resources) noexcept - : logicalDeviceHdl{ logicalDevice } + SHRenderGraphNode::SHRenderGraphNode(Handle renderGraphStorage, std::vector attDescInitParams, std::vector> predecessors, std::unordered_map> const* resources) noexcept + : graphStorage{ renderGraphStorage} , renderpass{} , framebuffers{} , prereqNodes{ std::move(predecessors) } @@ -115,11 +116,10 @@ namespace SHADE , subpasses{} , executed{ false } , configured{ false } - , resourceManager{ rm } , ptrToResources{ resources } { // pipeline library initialization - pipelineLibrary.Init(logicalDeviceHdl); + pipelineLibrary.Init(graphStorage->logicalDevice); // Store all the handles to resources attResources.reserve (attDescInitParams.size()); @@ -155,15 +155,14 @@ namespace SHADE if (!containsSwapchainImage) framebuffers.resize(1); else - framebuffers.resize(swapchain->GetNumImages()); + framebuffers.resize(graphStorage->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{ std::move (rhs.resourceManager) } - , logicalDeviceHdl{ rhs.logicalDeviceHdl } + : graphStorage{ rhs.graphStorage} , renderpass{ rhs.renderpass } , framebuffers{ std::move(rhs.framebuffers) } , prereqNodes{ std::move(rhs.prereqNodes) } @@ -189,8 +188,7 @@ namespace SHADE if (&rhs == this) return *this; - resourceManager = std::move(rhs.resourceManager); - logicalDeviceHdl = rhs.logicalDeviceHdl; + graphStorage = rhs.graphStorage; renderpass = rhs.renderpass; framebuffers = std::move(rhs.framebuffers); prereqNodes = std::move(rhs.prereqNodes); @@ -235,10 +233,10 @@ namespace SHADE } // Add subpass to container and create mapping for it - subpasses.emplace_back(resourceManager->Create(GetHandle(), subpasses.size(), &resourceAttachmentMapping, ptrToResources)); + subpasses.emplace_back(graphStorage->resourceManager->Create(GetHandle(), subpasses.size(), &resourceAttachmentMapping, ptrToResources)); subpassIndexing.try_emplace(subpassName, static_cast(subpasses.size()) - 1u); Handle subpass = subpasses.back(); - subpass->Init(*resourceManager); + subpass->Init(*graphStorage->resourceManager); // Register the SuperBatch batcher.RegisterSuperBatch(subpass->GetSuperBatch()); @@ -273,10 +271,10 @@ namespace SHADE } - Handle pipeline = pipelineLibrary.GetDrawPipline(vsFsPair); + Handle pipeline = pipelineLibrary.GetGraphicsPipeline(vsFsPair); if (!pipeline) { - pipeline = pipelineLibrary.CreateDrawPipeline + pipeline = pipelineLibrary.CreateGraphicsPipelines ( vsFsPair, renderpass, @@ -289,7 +287,7 @@ namespace SHADE void SHRenderGraphNode::FinaliseBatch(uint32_t frameIndex, Handle descPool) { - batcher.FinaliseBatches(logicalDeviceHdl, descPool, frameIndex); + batcher.FinaliseBatches(graphStorage->logicalDevice, descPool, frameIndex); } /***************************************************************************/ diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.h b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.h index 77861108..04638c37 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.h +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.h @@ -19,6 +19,8 @@ namespace SHADE class SHVkLogicalDevice; class SHVkRenderpass; class SHVkDescriptorPool; + class SHGraphicsGlobalData; + class SHRenderGraphStorage; class SH_API SHRenderGraphNode : public ISelfHandle { @@ -26,10 +28,9 @@ namespace SHADE /*-----------------------------------------------------------------------*/ /* PRIVATE MEMBER VARIABLES */ /*-----------------------------------------------------------------------*/ - std::shared_ptr resourceManager; - //! For Vulkan object creation - Handle logicalDeviceHdl; + //Handle logicalDeviceHdl; + Handle graphStorage; //! Each node will have a renderpass and each renderpass will have its own subpasses. //! These subpasses will execute sequentially. @@ -88,7 +89,7 @@ namespace SHADE /*-----------------------------------------------------------------------*/ /* CTORS AND DTORS */ /*-----------------------------------------------------------------------*/ - SHRenderGraphNode(std::shared_ptr rm, Handle const& logicalDevice, Handle const& swapchain, std::vector attDescInitParams, std::vector> predecessors, std::unordered_map> const* resources) noexcept; + SHRenderGraphNode(Handle renderGraphStorage, std::vector attDescInitParams, std::vector> predecessors, std::unordered_map> const* resources) noexcept; SHRenderGraphNode(SHRenderGraphNode&& rhs) noexcept; SHRenderGraphNode& operator= (SHRenderGraphNode&& rhs) noexcept; diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphResource.cpp b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphResource.cpp index adf3b6cd..3d05f466 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphResource.cpp +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphResource.cpp @@ -5,6 +5,7 @@ #include "Graphics/Images/SHVkImageView.h" #include "Graphics/Buffers/SHVkBuffer.h" #include "Graphics/SHVkUtil.h" +#include "SHRenderGraphStorage.h" namespace SHADE { @@ -45,7 +46,7 @@ namespace SHADE */ /***************************************************************************/ - SHRenderGraphResource::SHRenderGraphResource(Handle const& logicalDevice, Handle const& swapchain, std::string const& name, std::initializer_list typeFlags, vk::Format format, uint32_t w, uint32_t h, uint8_t levels, vk::ImageUsageFlagBits usageFlags, vk::ImageCreateFlagBits createFlags) noexcept + SHRenderGraphResource::SHRenderGraphResource(Handle graphStorage, std::string const& name, std::initializer_list typeFlags, vk::Format format, uint32_t w, uint32_t h, uint8_t levels, vk::ImageUsageFlagBits usageFlags, vk::ImageCreateFlagBits createFlags) noexcept : logicalDevice {logicalDevice} , swapchain{ swapchain } , resourceTypeFlags{ } @@ -75,13 +76,13 @@ namespace SHADE }; // We want an image handle for every swapchain image - images.resize(swapchain->GetNumImages()); - imageViews.resize(swapchain->GetNumImages()); + images.resize(graphStorage->swapchain->GetNumImages()); + imageViews.resize(graphStorage->swapchain->GetNumImages()); - for (uint32_t i = 0; i < swapchain->GetNumImages(); ++i) + for (uint32_t i = 0; i < graphStorage->swapchain->GetNumImages(); ++i) { - images[i] = swapchain->GetSwapchainImage(i); - imageViews[i] = images[i]->CreateImageView(logicalDevice, images[i], viewDetails); + images[i] = graphStorage->swapchain->GetSwapchainImage(i); + imageViews[i] = images[i]->CreateImageView(graphStorage->logicalDevice, images[i], viewDetails); } } else // if swapchain image resource @@ -126,7 +127,7 @@ namespace SHADE } // 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)); + images.push_back(graphStorage->logicalDevice->CreateImage(width, height, mipLevels, resourceFormat, usage, createFlags)); // prepare image view details SHImageViewDetails viewDetails @@ -141,7 +142,7 @@ namespace SHADE }; // just 1 image view created - imageViews.push_back(images[0]->CreateImageView(logicalDevice, images[0], viewDetails)); + imageViews.push_back(images[0]->CreateImageView(graphStorage->logicalDevice, images[0], viewDetails)); } } diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphResource.h b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphResource.h index efaf9bf5..e11f6ed8 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphResource.h +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphResource.h @@ -15,6 +15,7 @@ namespace SHADE class SHVkSwapchain; class SHVkCommandBuffer; class SHVkBuffer; + class SHRenderGraphStorage; static constexpr uint32_t NON_SWAPCHAIN_RESOURCE_INDEX = 0; @@ -69,7 +70,7 @@ namespace SHADE /*-----------------------------------------------------------------------*/ /* CTORS AND DTORS */ /*-----------------------------------------------------------------------*/ - SHRenderGraphResource(Handle const& logicalDevice, Handle const& swapchain, std::string const& name, std::initializer_list typeFlags, vk::Format format, uint32_t w, uint32_t h, uint8_t levels, vk::ImageUsageFlagBits usageFlags, vk::ImageCreateFlagBits createFlags) noexcept; + SHRenderGraphResource(Handle graphStorage, std::string const& name, std::initializer_list typeFlags, vk::Format format, uint32_t w, uint32_t h, uint8_t levels, vk::ImageUsageFlagBits usageFlags, vk::ImageCreateFlagBits createFlags) noexcept; SHRenderGraphResource(SHRenderGraphResource&& rhs) noexcept; SHRenderGraphResource& operator=(SHRenderGraphResource&& rhs) noexcept; ~SHRenderGraphResource(void) noexcept; diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphStorage.h b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphStorage.h new file mode 100644 index 00000000..9fcc4528 --- /dev/null +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphStorage.h @@ -0,0 +1,33 @@ +#pragma once + +#include "Resource/Handle.h" +#include + +namespace SHADE +{ + class SHVkLogicalDevice; + class SHVkSwapchain; + class SHGraphicsGlobalData; + class SHVkDescriptorPool; + + class SHRenderGraphStorage + { + //! Logical device for creation of vulkan objects + Handle logicalDevice; + + //! swapchain hdl + Handle swapchain; + + //! Resource manager for creation of objects + std::shared_ptr resourceManager; + + //! Descriptor pool for the descriptor sets to be created in the subpasses + Handle descriptorPool; + + friend class SHRenderGraph; + friend class SHRenderGraphNode; + friend class SHSubpass; + friend class SHRenderGraphResource; + friend class SHSubpassCompute; + }; +} diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHSubpass.cpp b/SHADE_Engine/src/Graphics/RenderGraph/SHSubpass.cpp index ffbe4ff0..9926fc2f 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHSubpass.cpp +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHSubpass.cpp @@ -4,6 +4,10 @@ #include "Graphics/Devices/SHVkLogicalDevice.h" #include "SHRenderGraphNode.h" #include "SHRenderGraphResource.h" +#include "Graphics/Shaders/SHVkShaderModule.h" +#include "SHRenderGraphNode.h" +#include "SHRenderGraphStorage.h" +#include "Graphics/RenderGraph/SHSubpassCompute.h" namespace SHADE { @@ -23,7 +27,7 @@ namespace SHADE */ /***************************************************************************/ - SHSubpass::SHSubpass(Handle const& parent, uint32_t index, std::unordered_map const* mapping, std::unordered_map> const* resources) noexcept + SHSubpass::SHSubpass(Handle renderGraphStorage, Handle const& parent, uint32_t index, std::unordered_map const* mapping, std::unordered_map> const* resources) noexcept : resourceAttachmentMapping{ mapping } , ptrToResources{ resources } , parentNode{ parent } @@ -32,6 +36,7 @@ namespace SHADE , colorReferences{} , depthReferences{} , inputReferences{} + , graphStorage{ renderGraphStorage } { } @@ -56,7 +61,8 @@ namespace SHADE , resourceAttachmentMapping{ rhs.resourceAttachmentMapping } , ptrToResources{ rhs.ptrToResources } , descriptorSetLayout{ rhs.descriptorSetLayout } - , exteriorDrawCalls{ std::move (rhs.exteriorDrawCalls) } + , exteriorDrawCalls{ std::move(rhs.exteriorDrawCalls) } + , graphStorage{ std::move(rhs.graphStorage) } { } @@ -87,6 +93,7 @@ namespace SHADE ptrToResources = rhs.ptrToResources; descriptorSetLayout = rhs.descriptorSetLayout; exteriorDrawCalls = std::move(rhs.exteriorDrawCalls); + graphStorage = std::move(rhs.graphStorage); return *this; } @@ -182,6 +189,11 @@ namespace SHADE exteriorDrawCalls.push_back(newDrawCall); } + Handle SHSubpass::ActivateSubpassCompute(Handle computeShaderModule, std::initializer_list resources) noexcept + { + //subpassCompute = graphStorage->resourceManager->Create(, parentNode->GetGraphDescPool(), resources); + } + void SHSubpass::Init(ResourceManager& resourceManager) noexcept { superBatch = resourceManager.Create(GetHandle()); diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHSubpass.h b/SHADE_Engine/src/Graphics/RenderGraph/SHSubpass.h index c567a897..71496b92 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHSubpass.h +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHSubpass.h @@ -15,6 +15,9 @@ namespace SHADE class SHVkCommandBuffer; class SHVkDescriptorSetLayout; class SHVkDescriptorPool; + class SHRenderGraphStorage; + class SHSubpassCompute; + class SHVkShaderModule; class SH_API SHSubpass : public ISelfHandle { @@ -22,6 +25,8 @@ namespace SHADE /*---------------------------------------------------------------------*/ /* PRIVATE MEMBER VARIABLES */ /*---------------------------------------------------------------------*/ + Handle graphStorage; + //! The index of the subpass in the render graph uint32_t subpassIndex; @@ -49,6 +54,10 @@ namespace SHADE //! Pointer to resources in the render graph (for getting handle IDs) std::unordered_map> const* ptrToResources; + //! Sometimes we want the subpass to do something to the images instead + //! of drawing objects on the image (i.e. compute). + Handle subpassCompute; + //! 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 @@ -62,7 +71,7 @@ namespace SHADE /*-----------------------------------------------------------------------*/ /* CTORS AND DTORS */ /*-----------------------------------------------------------------------*/ - SHSubpass(Handle const& parent, uint32_t index, std::unordered_map const* mapping, std::unordered_map> const* ptrToResources) noexcept; + SHSubpass(Handle renderGraphStorage, Handle const& parent, uint32_t index, std::unordered_map const* mapping, std::unordered_map> const* ptrToResources) noexcept; SHSubpass(SHSubpass&& rhs) noexcept; SHSubpass& operator=(SHSubpass&& rhs) noexcept; @@ -78,6 +87,8 @@ namespace SHADE void Execute(Handle& commandBuffer, Handle descPool, uint32_t frameIndex) noexcept; void AddExteriorDrawCalls(std::function&)> const& newDrawCall) noexcept; + Handle ActivateSubpassCompute(Handle computeShaderModule, std::initializer_list resources) noexcept; + void Init(ResourceManager& resourceManager) noexcept; /*-----------------------------------------------------------------------*/ diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHSubpassCompute.cpp b/SHADE_Engine/src/Graphics/RenderGraph/SHSubpassCompute.cpp index ccd0e6c3..722e7e4f 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHSubpassCompute.cpp +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHSubpassCompute.cpp @@ -3,21 +3,32 @@ #include "Graphics/Pipeline/SHVkPipeline.h" #include "Graphics/Descriptors/SHVkDescriptorSetGroup.h" #include "Graphics/Descriptors/SHVkDescriptorPool.h" +#include "Graphics/Devices/SHVkLogicalDevice.h" +#include "Graphics/Pipeline/SHVkPipelineLayout.h" +#include "SHRenderGraphStorage.h" +//#include "" namespace SHADE { - SHSubpassCompute::SHSubpassCompute(Handle inPipeline, Handle descPool) noexcept - : pipeline {inPipeline} + SHSubpassCompute::SHSubpassCompute(Handle graphStorage, Handle computeShaderModule, std::initializer_list resources) noexcept + : pipeline{} { + SHPipelineLayoutParams pipelineLayoutParams + { + //.globalDescSetLayouts + }; + + //pipeline = logicalDevice->CreateComputePipeline() + // 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 variableCounts{static_cast(layouts.size())}; - std::fill (variableCounts.begin(), variableCounts.end(), 0); + std::vector variableCounts{ static_cast(layouts.size()) }; + std::fill(variableCounts.begin(), variableCounts.end(), 0); // Allocate descriptor sets to hold the images for reading (STORAGE_IMAGE) - descPool->Allocate(layouts, variableCounts); + descSetGroup = graphStorage->descriptorPool->Allocate(layouts, variableCounts); } } diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHSubpassCompute.h b/SHADE_Engine/src/Graphics/RenderGraph/SHSubpassCompute.h index 3ebc5676..8dfc361e 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHSubpassCompute.h +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHSubpassCompute.h @@ -1,24 +1,36 @@ #pragma once -#include +#include "Resource/Handle.h" +#include +#include namespace SHADE { class SHVkPipeline; class SHVkDescriptorSetGroup; class SHVkDescriptorPool; + class SHVkLogicalDevice; + class SHVkPipelineLayout; + class SHRenderGraphStorage; + class SHVkShaderModule; class SHSubpassCompute { private: //! To run the dispatch command - Handle pipeline; + Handle pipeline; - //! Descriptor set group + //! Pipeline layout for the pipline creation + Handle pipelineLayout; + + //! Descriptor set group to hold the images for reading (STORAGE_IMAGE) Handle descSetGroup; - + + //! Required resources to be used in the descriptors + std::vector resourcesRequired; + public: - SHSubpassCompute (Handle inPipeline, Handle descPool) noexcept; + SHSubpassCompute(Handle graphStorage, Handle computeShaderModule, std::initializer_list resources) noexcept; }; } From c252e4ce4b7591da5eafa04a02329d32f20e06b1 Mon Sep 17 00:00:00 2001 From: Brandon Mak Date: Fri, 21 Oct 2022 07:01:51 +0800 Subject: [PATCH 03/13] Some restructuring with render graph storage. Lesser parameters passed around. --- Assets/Editor/Layouts/UserLayout.ini | 20 +++++++++---------- .../Descriptors/SHVkDescriptorPool.cpp | 3 ++- .../RenderGraph/SHRenderGraphNode.cpp | 2 +- .../RenderGraph/SHRenderGraphResource.cpp | 17 ++++++++-------- .../RenderGraph/SHRenderGraphResource.h | 9 +++------ .../src/Graphics/RenderGraph/SHSubpass.cpp | 3 ++- 6 files changed, 26 insertions(+), 28 deletions(-) diff --git a/Assets/Editor/Layouts/UserLayout.ini b/Assets/Editor/Layouts/UserLayout.ini index 33b4ccfd..530ee770 100644 --- a/Assets/Editor/Layouts/UserLayout.ini +++ b/Assets/Editor/Layouts/UserLayout.ini @@ -1,16 +1,16 @@ [Window][MainStatusBar] -Pos=0,1389 -Size=2547,20 +Pos=0,1060 +Size=1920,20 Collapsed=0 [Window][SHEditorMenuBar] Pos=0,48 -Size=2547,1341 +Size=1920,1012 Collapsed=0 [Window][Hierarchy Panel] -Pos=0,172 -Size=571,1217 +Pos=0,142 +Size=571,918 Collapsed=0 DockId=0x00000004,0 @@ -20,25 +20,25 @@ Size=400,400 Collapsed=0 [Window][Inspector] -Pos=2276,48 -Size=271,1341 +Pos=1649,48 +Size=271,1012 Collapsed=0 DockId=0x00000006,0 [Window][Profiler] Pos=0,48 -Size=571,122 +Size=571,92 Collapsed=0 DockId=0x00000003,0 [Window][Viewport] Pos=573,48 -Size=1701,1341 +Size=1074,1012 Collapsed=0 DockId=0x00000002,0 [Docking][Data] -DockSpace ID=0xC5C9B8AB Window=0xBE4044E9 Pos=8,79 Size=2547,1341 Split=X +DockSpace ID=0xC5C9B8AB Window=0xBE4044E9 Pos=8,79 Size=1920,1012 Split=X DockNode ID=0x00000005 Parent=0xC5C9B8AB SizeRef=1992,1036 Split=X DockNode ID=0x00000001 Parent=0x00000005 SizeRef=571,1036 Split=Y Selected=0x1E6EB881 DockNode ID=0x00000003 Parent=0x00000001 SizeRef=225,94 Selected=0x1E6EB881 diff --git a/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorPool.cpp b/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorPool.cpp index 6b770c3d..e5618c9c 100644 --- a/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorPool.cpp +++ b/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorPool.cpp @@ -25,7 +25,8 @@ namespace SHADE } SHVkDescriptorPool::SHVkDescriptorPool(SHVkDescriptorPool&& rhs) noexcept - : device{ rhs.device } + : ISelfHandle (rhs) + , device{ rhs.device } , pool{ rhs.pool } { rhs.pool = VK_NULL_HANDLE; diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.cpp b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.cpp index f9b3c42d..48855806 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.cpp +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.cpp @@ -233,7 +233,7 @@ namespace SHADE } // Add subpass to container and create mapping for it - subpasses.emplace_back(graphStorage->resourceManager->Create(GetHandle(), subpasses.size(), &resourceAttachmentMapping, ptrToResources)); + subpasses.emplace_back(graphStorage->resourceManager->Create(graphStorage, GetHandle(), subpasses.size(), &resourceAttachmentMapping, ptrToResources)); subpassIndexing.try_emplace(subpassName, static_cast(subpasses.size()) - 1u); Handle subpass = subpasses.back(); subpass->Init(*graphStorage->resourceManager); diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphResource.cpp b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphResource.cpp index 3d05f466..d3f20665 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphResource.cpp +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphResource.cpp @@ -46,9 +46,8 @@ namespace SHADE */ /***************************************************************************/ - SHRenderGraphResource::SHRenderGraphResource(Handle graphStorage, std::string const& name, std::initializer_list typeFlags, vk::Format format, uint32_t w, uint32_t h, uint8_t levels, vk::ImageUsageFlagBits usageFlags, vk::ImageCreateFlagBits createFlags) noexcept - : logicalDevice {logicalDevice} - , swapchain{ swapchain } + SHRenderGraphResource::SHRenderGraphResource(Handle renderGraphStorage, std::string const& name, std::initializer_list typeFlags, vk::Format format, uint32_t w, uint32_t h, uint8_t levels, vk::ImageUsageFlagBits usageFlags, vk::ImageCreateFlagBits createFlags) noexcept + : graphStorage{renderGraphStorage} , resourceTypeFlags{ } , resourceFormat{ format } , images{} @@ -67,7 +66,7 @@ namespace SHADE SHImageViewDetails viewDetails { .viewType = vk::ImageViewType::e2D, - .format = swapchain->GetSurfaceFormatKHR().format, + .format = graphStorage->swapchain->GetSurfaceFormatKHR().format, .imageAspectFlags = vk::ImageAspectFlagBits::eColor, .baseMipLevel = 0, .mipLevelCount = 1, @@ -167,7 +166,7 @@ namespace SHADE , height{ rhs.height } , mipLevels{ rhs.mipLevels } , imageAspectFlags{ rhs.imageAspectFlags } - , swapchain {rhs.swapchain} + , graphStorage{rhs.graphStorage} { } @@ -199,7 +198,7 @@ namespace SHADE height = rhs.height; mipLevels = rhs.mipLevels; imageAspectFlags = rhs.imageAspectFlags; - swapchain = rhs.swapchain; + graphStorage = rhs.graphStorage; return *this; } @@ -248,7 +247,7 @@ namespace SHADE SHImageViewDetails viewDetails { .viewType = vk::ImageViewType::e2D, - .format = swapchain->GetSurfaceFormatKHR().format, + .format = graphStorage->swapchain->GetSurfaceFormatKHR().format, .imageAspectFlags = vk::ImageAspectFlagBits::eColor, .baseMipLevel = 0, .mipLevelCount = 1, @@ -256,9 +255,9 @@ namespace SHADE .layerCount = 1, }; - for (uint32_t i = 0; i < swapchain->GetNumImages(); ++i) + for (uint32_t i = 0; i < graphStorage->swapchain->GetNumImages(); ++i) { - images[i] = swapchain->GetSwapchainImage(i); + images[i] = graphStorage->swapchain->GetSwapchainImage(i); imageViews[i]->ViewNewImage(images[i], viewDetails); } } diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphResource.h b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphResource.h index e11f6ed8..4bdecc49 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphResource.h +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphResource.h @@ -25,11 +25,8 @@ namespace SHADE /*-----------------------------------------------------------------------*/ /* PRIVATE MEMBER VARIABLES */ /*-----------------------------------------------------------------------*/ - // for creation/recreation - Handle logicalDevice; - - // for creation/recreation - Handle swapchain; + //! Storage from the render graph + Handle graphStorage; //! Name of the resource std::string resourceName; @@ -70,7 +67,7 @@ namespace SHADE /*-----------------------------------------------------------------------*/ /* CTORS AND DTORS */ /*-----------------------------------------------------------------------*/ - SHRenderGraphResource(Handle graphStorage, std::string const& name, std::initializer_list typeFlags, vk::Format format, uint32_t w, uint32_t h, uint8_t levels, vk::ImageUsageFlagBits usageFlags, vk::ImageCreateFlagBits createFlags) noexcept; + SHRenderGraphResource(Handle renderGraphStorage, std::string const& name, std::initializer_list typeFlags, vk::Format format, uint32_t w, uint32_t h, uint8_t levels, vk::ImageUsageFlagBits usageFlags, vk::ImageCreateFlagBits createFlags) noexcept; SHRenderGraphResource(SHRenderGraphResource&& rhs) noexcept; SHRenderGraphResource& operator=(SHRenderGraphResource&& rhs) noexcept; ~SHRenderGraphResource(void) noexcept; diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHSubpass.cpp b/SHADE_Engine/src/Graphics/RenderGraph/SHSubpass.cpp index 9926fc2f..3daafb8f 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHSubpass.cpp +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHSubpass.cpp @@ -191,7 +191,8 @@ namespace SHADE Handle SHSubpass::ActivateSubpassCompute(Handle computeShaderModule, std::initializer_list resources) noexcept { - //subpassCompute = graphStorage->resourceManager->Create(, parentNode->GetGraphDescPool(), resources); + subpassCompute = graphStorage->resourceManager->Create(graphStorage, computeShaderModule, resources); + return subpassCompute; } void SHSubpass::Init(ResourceManager& resourceManager) noexcept From e8073bb67fc368fdd4d5e79ff9d8c2d18ddc6238 Mon Sep 17 00:00:00 2001 From: Brandon Mak Date: Fri, 21 Oct 2022 08:42:58 +0800 Subject: [PATCH 04/13] WIP --- SHADE_Engine/src/Graphics/RenderGraph/SHSubpassCompute.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHSubpassCompute.cpp b/SHADE_Engine/src/Graphics/RenderGraph/SHSubpassCompute.cpp index 722e7e4f..f30fa85f 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHSubpassCompute.cpp +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHSubpassCompute.cpp @@ -5,6 +5,7 @@ #include "Graphics/Descriptors/SHVkDescriptorPool.h" #include "Graphics/Devices/SHVkLogicalDevice.h" #include "Graphics/Pipeline/SHVkPipelineLayout.h" +#include "Graphics/MiddleEnd/GlobalData/SHGraphicsGlobalData.h" #include "SHRenderGraphStorage.h" //#include "" @@ -15,7 +16,7 @@ namespace SHADE { SHPipelineLayoutParams pipelineLayoutParams { - //.globalDescSetLayouts + .globalDescSetLayouts = SHGraphicsGlobalData::GetDescSetLayouts() }; //pipeline = logicalDevice->CreateComputePipeline() From 9df517f3b30885d78c5ce63a5add0d002680d9b6 Mon Sep 17 00:00:00 2001 From: Xiao Qi Date: Fri, 21 Oct 2022 20:28:54 +0800 Subject: [PATCH 05/13] SP3-170 SP3-238 Restructured asset and asset loading library types to be derived from common base class. Storage of assets and loaders based on pointers. Created general templated calls to get data from asset manager based on asset type passed in as template argument. More concise internal interface when loading and storing assets with libraries --- Assets/Cube.003.shmesh.shmeta | 2 +- Assets/Cube.012.shmesh.shmeta | 2 +- .../RaccoonPreTexturedVer1_Base9.shtex.shmeta | 2 +- SHADE_Application/src/Scenes/SBTestScene.cpp | 47 +- .../src/Assets/Asset Types/SHAnimationAsset.h | 4 +- .../src/Assets/Asset Types/SHAssetData.h | 19 + .../src/Assets/Asset Types/SHInternalAsset.h | 21 + .../src/Assets/Asset Types/SHMeshAsset.h | 6 +- .../src/Assets/Asset Types/SHTextureAsset.h | 3 +- .../src/Assets/Libraries/SHAssetLoader.h | 21 + .../src/Assets/Libraries/SHAssimpLibrary.cpp | 26 +- .../src/Assets/Libraries/SHAssimpLibrary.h | 6 +- .../src/Assets/Libraries/SHMeshCompiler.cpp | 2 +- .../src/Assets/Libraries/SHMeshLoader.cpp | 13 +- .../src/Assets/Libraries/SHMeshLoader.h | 6 +- .../src/Assets/Libraries/SHTextureLoader.cpp | 9 + .../src/Assets/Libraries/SHTextureLoader.h | 17 +- SHADE_Engine/src/Assets/SHAsset.h | 5 +- SHADE_Engine/src/Assets/SHAssetMacros.h | 51 ++- SHADE_Engine/src/Assets/SHAssetManager.cpp | 422 ++++-------------- SHADE_Engine/src/Assets/SHAssetManager.h | 80 ++-- .../src/Assets/SHAssetMetaHandler.cpp | 14 +- 22 files changed, 300 insertions(+), 478 deletions(-) create mode 100644 SHADE_Engine/src/Assets/Asset Types/SHAssetData.h create mode 100644 SHADE_Engine/src/Assets/Asset Types/SHInternalAsset.h create mode 100644 SHADE_Engine/src/Assets/Libraries/SHAssetLoader.h diff --git a/Assets/Cube.003.shmesh.shmeta b/Assets/Cube.003.shmesh.shmeta index d41be546..207f3999 100644 --- a/Assets/Cube.003.shmesh.shmeta +++ b/Assets/Cube.003.shmesh.shmeta @@ -1,3 +1,3 @@ Name: Cube.003 ID: 110152941 -Type:  +Type: 6 diff --git a/Assets/Cube.012.shmesh.shmeta b/Assets/Cube.012.shmesh.shmeta index d5cd1090..3af04f93 100644 --- a/Assets/Cube.012.shmesh.shmeta +++ b/Assets/Cube.012.shmesh.shmeta @@ -1,3 +1,3 @@ Name: Cube.012 ID: 107348815 -Type:  +Type: 6 diff --git a/Assets/RaccoonPreTexturedVer1_Base9.shtex.shmeta b/Assets/RaccoonPreTexturedVer1_Base9.shtex.shmeta index f8c267d9..3905aa4f 100644 --- a/Assets/RaccoonPreTexturedVer1_Base9.shtex.shmeta +++ b/Assets/RaccoonPreTexturedVer1_Base9.shtex.shmeta @@ -1,3 +1,3 @@ Name: RaccoonPreTexturedVer1_Base9 ID: 91918845 -Type:  +Type: 4 diff --git a/SHADE_Application/src/Scenes/SBTestScene.cpp b/SHADE_Application/src/Scenes/SBTestScene.cpp index f1d656ee..50a87fd3 100644 --- a/SHADE_Application/src/Scenes/SBTestScene.cpp +++ b/SHADE_Application/src/Scenes/SBTestScene.cpp @@ -13,6 +13,9 @@ #include "Physics/Components/SHRigidBodyComponent.h" #include "Physics/Components/SHColliderComponent.h" +#include "Assets/Asset Types/SHMeshAsset.h" +#include "Assets/Asset Types/SHTextureAsset.h" + #include "Assets/SHAssetManager.h" using namespace SHADE; @@ -39,34 +42,26 @@ namespace Sandbox // Create temp meshes const auto CUBE_MESH = SHADE::SHPrimitiveGenerator::Cube(*graphicsSystem); + auto assets = SHAssetManager::GetAllAssets(); + //Test Racoon mesh - auto meshes = SHADE::SHAssetManager::GetAllMeshes(); - std::vector> handles; - for (auto const& mesh : meshes) - { - if (mesh.header.meshName == "Cube.012") - { - handles.push_back(graphicsSystem->AddMesh( - mesh.header.vertexCount, - mesh.vertexPosition.data(), - mesh.texCoords.data(), - mesh.vertexTangent.data(), - mesh.vertexNormal.data(), - mesh.header.indexCount, - mesh.indices.data() - )); - } - } + auto mesh = SHAssetManager::GetData(107348815); + Handle handle; + handle = (graphicsSystem->AddMesh( + mesh->header.vertexCount, + mesh->vertexPosition.data(), + mesh->texCoords.data(), + mesh->vertexTangent.data(), + mesh->vertexNormal.data(), + mesh->header.indexCount, + mesh->indices.data() + )); graphicsSystem->BuildMeshBuffers(); // Load Textures - auto textures = SHADE::SHAssetManager::GetAllTextures(); - std::vector> texHandles; - for (const auto& tex : textures) - { - auto texture = graphicsSystem->Add(tex); - texHandles.push_back(texture); - } + auto texture = SHAssetManager::GetData(91918845); + Handle texHandle; + texHandle = graphicsSystem->Add(*texture); graphicsSystem->BuildTextures(); // Create Materials @@ -116,7 +111,7 @@ namespace Sandbox auto& renderable = *SHComponentManager::GetComponent_s(raccoonSpin); auto& transform = *SHComponentManager::GetComponent_s(raccoonSpin); - renderable.Mesh = handles.front(); + renderable.Mesh = handle; renderable.SetMaterial(customMat); renderable.GetModifiableMaterial()->SetProperty("data.color", SHVec4(0.0f, 0.0f, 0.0f, 0.0f)); renderable.GetModifiableMaterial()->SetProperty("data.alpha", 1.0f); @@ -157,7 +152,7 @@ namespace Sandbox auto& renderableShowcase = *SHComponentManager::GetComponent_s(raccoonShowcase); auto& transformShowcase = *SHComponentManager::GetComponent_s(raccoonShowcase); - renderableShowcase.Mesh = handles.front(); + renderableShowcase.Mesh = handle; renderableShowcase.SetMaterial(customMat); renderableShowcase.GetModifiableMaterial()->SetProperty("data.color", SHVec4(0.0f, 0.0f, 0.0f, 0.0f)); renderableShowcase.GetModifiableMaterial()->SetProperty("data.alpha", 1.0f); diff --git a/SHADE_Engine/src/Assets/Asset Types/SHAnimationAsset.h b/SHADE_Engine/src/Assets/Asset Types/SHAnimationAsset.h index 76f4c0ac..b411a11e 100644 --- a/SHADE_Engine/src/Assets/Asset Types/SHAnimationAsset.h +++ b/SHADE_Engine/src/Assets/Asset Types/SHAnimationAsset.h @@ -12,11 +12,11 @@ #include #include -#include "SH_API.h" +#include "SHAssetData.h" namespace SHADE { - struct SH_API SHAnimationAsset + struct SH_API SHAnimationAsset : SHAssetData { std::string name; diff --git a/SHADE_Engine/src/Assets/Asset Types/SHAssetData.h b/SHADE_Engine/src/Assets/Asset Types/SHAssetData.h new file mode 100644 index 00000000..8db9824c --- /dev/null +++ b/SHADE_Engine/src/Assets/Asset Types/SHAssetData.h @@ -0,0 +1,19 @@ +/*************************************************************************//** + * \file SHAssetDataBase.h + * \author Loh Xiao Qi + * \date October 2022 + * \brief + * + * 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 + +namespace SHADE +{ + struct SHAssetData + { + virtual ~SHAssetData(){} + }; +} diff --git a/SHADE_Engine/src/Assets/Asset Types/SHInternalAsset.h b/SHADE_Engine/src/Assets/Asset Types/SHInternalAsset.h new file mode 100644 index 00000000..8bef34e9 --- /dev/null +++ b/SHADE_Engine/src/Assets/Asset Types/SHInternalAsset.h @@ -0,0 +1,21 @@ +/*************************************************************************//** + * \file SHInternalAsset.h + * \author Loh Xiao Qi + * \date October 2022 + * \brief + * + * 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 + +#include "SHAsset.h" + +namespace SHADE +{ + struct SHInternalAsset : SHAsset + { + + }; +} \ No newline at end of file diff --git a/SHADE_Engine/src/Assets/Asset Types/SHMeshAsset.h b/SHADE_Engine/src/Assets/Asset Types/SHMeshAsset.h index 68c0d150..20b442ba 100644 --- a/SHADE_Engine/src/Assets/Asset Types/SHMeshAsset.h +++ b/SHADE_Engine/src/Assets/Asset Types/SHMeshAsset.h @@ -14,7 +14,7 @@ #include #include "Math/SHMath.h" -#include "SH_API.h" +#include "SHAssetData.h" namespace SHADE { @@ -22,10 +22,10 @@ namespace SHADE { uint32_t vertexCount; uint32_t indexCount; - std::string meshName; + std::string name; }; - struct SH_API SHMeshAsset + struct SH_API SHMeshAsset : SHAssetData { bool compiled; bool changed; diff --git a/SHADE_Engine/src/Assets/Asset Types/SHTextureAsset.h b/SHADE_Engine/src/Assets/Asset Types/SHTextureAsset.h index d24b6c02..d26a2c30 100644 --- a/SHADE_Engine/src/Assets/Asset Types/SHTextureAsset.h +++ b/SHADE_Engine/src/Assets/Asset Types/SHTextureAsset.h @@ -2,10 +2,11 @@ #include "tinyddsloader.h" #include "Graphics/MiddleEnd/Textures/SHTextureLibrary.h" +#include "SHAssetData.h" namespace SHADE { - struct SHTextureAsset + struct SHTextureAsset : SHAssetData { bool compiled; diff --git a/SHADE_Engine/src/Assets/Libraries/SHAssetLoader.h b/SHADE_Engine/src/Assets/Libraries/SHAssetLoader.h new file mode 100644 index 00000000..41595519 --- /dev/null +++ b/SHADE_Engine/src/Assets/Libraries/SHAssetLoader.h @@ -0,0 +1,21 @@ +/*************************************************************************//** + * \file SHAssetLoader.h + * \author Loh Xiao Qi + * \date October 2022 + * \brief + * + * 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 + +#include "Assets/Asset Types/SHAssetData.h" + +namespace SHADE +{ + struct SHAssetLoader + { + virtual SHAssetData* Load(AssetPath path) = 0; + }; +} diff --git a/SHADE_Engine/src/Assets/Libraries/SHAssimpLibrary.cpp b/SHADE_Engine/src/Assets/Libraries/SHAssimpLibrary.cpp index feea9f35..f4be0b68 100644 --- a/SHADE_Engine/src/Assets/Libraries/SHAssimpLibrary.cpp +++ b/SHADE_Engine/src/Assets/Libraries/SHAssimpLibrary.cpp @@ -51,13 +51,11 @@ namespace SHADE } } - SHMeshAsset SHAssimpLibrary::ProcessMesh(aiMesh const& mesh) noexcept + SHMeshAsset* SHAssimpLibrary::ProcessMesh(aiMesh const& mesh) noexcept { - SHMeshAsset result - { - .compiled { false}, - .changed { false } - }; + SHMeshAsset* result = new SHMeshAsset(); + result->compiled = false; + result->changed = false; for (size_t i{0}; i < mesh.mNumVertices; ++i) { @@ -66,7 +64,7 @@ namespace SHADE vertex.x = mesh.mVertices[i].x; vertex.y = mesh.mVertices[i].y; vertex.z = mesh.mVertices[i].z; - result.vertexPosition.push_back(vertex); + result->vertexPosition.push_back(vertex); // Tex coords SHVec2 texCoord{0.f, 0.f}; @@ -75,7 +73,7 @@ namespace SHADE texCoord.x = mesh.mTextureCoords[0][i].x; texCoord.y = mesh.mTextureCoords[0][i].y; } - result.texCoords.push_back(texCoord); + result->texCoords.push_back(texCoord); // Normals SHVec3 normal{0.f, 0.f, 0.f}; @@ -85,7 +83,7 @@ namespace SHADE normal.y = mesh.mNormals[i].y; normal.z = mesh.mNormals[i].z; } - result.vertexNormal.push_back(normal); + result->vertexNormal.push_back(normal); // Tangent SHVec3 tangent{0.f, 0.f, 0.f}; @@ -95,7 +93,7 @@ namespace SHADE tangent.y = mesh.mTangents[i].y; tangent.z = mesh.mTangents[i].z; } - result.vertexTangent.push_back(tangent); + result->vertexTangent.push_back(tangent); } for (size_t i {0}; i < mesh.mNumFaces; ++i) @@ -103,13 +101,13 @@ namespace SHADE aiFace face = mesh.mFaces[i]; for (size_t j{0}; j < face.mNumIndices; ++j) { - result.indices.push_back(face.mIndices[j]); + result->indices.push_back(face.mIndices[j]); } } - result.header.vertexCount = static_cast(result.vertexPosition.size()); - result.header.indexCount = static_cast(result.indices.size()); - result.header.meshName = mesh.mName.C_Str(); + result->header.vertexCount = static_cast(result->vertexPosition.size()); + result->header.indexCount = static_cast(result->indices.size()); + result->header.name = mesh.mName.C_Str(); return result; } diff --git a/SHADE_Engine/src/Assets/Libraries/SHAssimpLibrary.h b/SHADE_Engine/src/Assets/Libraries/SHAssimpLibrary.h index a4a0447a..83755b4c 100644 --- a/SHADE_Engine/src/Assets/Libraries/SHAssimpLibrary.h +++ b/SHADE_Engine/src/Assets/Libraries/SHAssimpLibrary.h @@ -22,13 +22,13 @@ namespace SHADE class SHAssimpLibrary { private: - using MeshVectorRef = std::vector&; - using AnimVectorRef = std::vector&; + using MeshVectorRef = std::vector&; + using AnimVectorRef = std::vector&; static Assimp::Importer aiImporter; static void ProcessNode(aiNode const& node, aiScene const& scene,MeshVectorRef meshes) noexcept; static void ExtractAnimations(aiScene const& scene, AnimVectorRef anims) noexcept; - static SHMeshAsset ProcessMesh(aiMesh const& mesh) noexcept; + static SHMeshAsset* ProcessMesh(aiMesh const& mesh) noexcept; public: static void LoadFromFile(AssetPath path, MeshVectorRef meshes, AnimVectorRef anims) noexcept; diff --git a/SHADE_Engine/src/Assets/Libraries/SHMeshCompiler.cpp b/SHADE_Engine/src/Assets/Libraries/SHMeshCompiler.cpp index 8026f0e1..2346714e 100644 --- a/SHADE_Engine/src/Assets/Libraries/SHMeshCompiler.cpp +++ b/SHADE_Engine/src/Assets/Libraries/SHMeshCompiler.cpp @@ -20,7 +20,7 @@ std::string SHADE::SHMeshCompiler::CompileMeshBinary(SHMeshAsset const& asset, A { std::string newPath{ path.string() }; newPath = newPath.substr(0, newPath.find_last_of('/') + 1); - newPath += asset.header.meshName + MESH_EXTENSION; + newPath += asset.header.name + MESH_EXTENSION.data(); std::ofstream file{ newPath, std::ios::out | std::ios::binary | std::ios::trunc }; if (!file.is_open()) diff --git a/SHADE_Engine/src/Assets/Libraries/SHMeshLoader.cpp b/SHADE_Engine/src/Assets/Libraries/SHMeshLoader.cpp index 73fed1fb..90dd58d4 100644 --- a/SHADE_Engine/src/Assets/Libraries/SHMeshLoader.cpp +++ b/SHADE_Engine/src/Assets/Libraries/SHMeshLoader.cpp @@ -16,7 +16,7 @@ namespace SHADE { - void SHMeshLoader::LoadSHMesh(SHMeshAsset& mesh, AssetPath path) noexcept + void SHMeshLoader::LoadSHMesh(AssetPath path, SHMeshAsset& mesh) noexcept { std::ifstream file{ path.string(), std::ios::in | std::ios::binary }; if (!file.is_open()) @@ -56,7 +56,7 @@ namespace SHADE mesh.header.indexCount = indexCount; mesh.header.vertexCount = vertCount; - mesh.header.meshName = name; + mesh.header.name = name; mesh.vertexPosition = std::move(vertPos); mesh.vertexTangent = std::move(vertTan); @@ -66,4 +66,13 @@ namespace SHADE file.close(); } + + SHAssetData* SHMeshLoader::Load(AssetPath path) + { + auto result = new SHMeshAsset(); + + LoadSHMesh(path, *result); + + return result; + } } diff --git a/SHADE_Engine/src/Assets/Libraries/SHMeshLoader.h b/SHADE_Engine/src/Assets/Libraries/SHMeshLoader.h index f01b942a..34c4e5d2 100644 --- a/SHADE_Engine/src/Assets/Libraries/SHMeshLoader.h +++ b/SHADE_Engine/src/Assets/Libraries/SHMeshLoader.h @@ -12,11 +12,13 @@ #pragma once #include "../SHAssetMacros.h" #include "../Asset Types/SHMeshAsset.h" +#include "SHAssetLoader.h" namespace SHADE { - struct SHMeshLoader + struct SHMeshLoader : public SHAssetLoader { - static void LoadSHMesh(SHMeshAsset& meshes, AssetPath path) noexcept; + void LoadSHMesh(AssetPath path, SHMeshAsset& meshes) noexcept; + SHAssetData* Load(AssetPath path) override; }; } \ No newline at end of file diff --git a/SHADE_Engine/src/Assets/Libraries/SHTextureLoader.cpp b/SHADE_Engine/src/Assets/Libraries/SHTextureLoader.cpp index 5147562a..8b986524 100644 --- a/SHADE_Engine/src/Assets/Libraries/SHTextureLoader.cpp +++ b/SHADE_Engine/src/Assets/Libraries/SHTextureLoader.cpp @@ -133,6 +133,15 @@ namespace SHADE file.close(); } + SHAssetData* SHTextureLoader::Load(AssetPath path) + { + auto result = new SHTextureAsset(); + + LoadImageAsset(path, *result); + + return result; + } + void SHTextureLoader::LoadImageAsset(AssetPath path, SHTextureAsset& asset) { if (path.extension().string() == DDS_EXTENSION) diff --git a/SHADE_Engine/src/Assets/Libraries/SHTextureLoader.h b/SHADE_Engine/src/Assets/Libraries/SHTextureLoader.h index eb61ea91..8bdf91b1 100644 --- a/SHADE_Engine/src/Assets/Libraries/SHTextureLoader.h +++ b/SHADE_Engine/src/Assets/Libraries/SHTextureLoader.h @@ -15,19 +15,20 @@ #include "../SHAssetMacros.h" #include "../Asset Types/SHTextureAsset.h" #include "tinyddsloader.h" +#include "SHAssetLoader.h" namespace SHADE { - class SHTextureLoader + class SHTextureLoader : public SHAssetLoader { private: - static std::string TinyDDSResultToString(tinyddsloader::Result value); - static vk::Format ddsLoaderToVkFormat(tinyddsloader::DDSFile::DXGIFormat format, bool isLinear); - - - static void LoadTinyDDS(AssetPath path, SHTextureAsset& asset) noexcept; + std::string TinyDDSResultToString(tinyddsloader::Result value); + vk::Format ddsLoaderToVkFormat(tinyddsloader::DDSFile::DXGIFormat format, bool isLinear); + + void LoadTinyDDS(AssetPath path, SHTextureAsset& asset) noexcept; public: - static void LoadImageAsset(AssetPath paths, SHTextureAsset& image); - static void LoadSHTexture(AssetPath path, SHTextureAsset& asset) noexcept; + void LoadImageAsset(AssetPath paths, SHTextureAsset& image); + void LoadSHTexture(AssetPath path, SHTextureAsset& asset) noexcept; + SHAssetData* Load(AssetPath path) override; }; } diff --git a/SHADE_Engine/src/Assets/SHAsset.h b/SHADE_Engine/src/Assets/SHAsset.h index 8d7b55d1..86e8a722 100644 --- a/SHADE_Engine/src/Assets/SHAsset.h +++ b/SHADE_Engine/src/Assets/SHAsset.h @@ -12,11 +12,12 @@ #pragma once #include "Filesystem/SHFileSystem.h" -#include "SHAssetMacros.h" +#include "Assets/SHAssetMacros.h" +#include "SH_API.h" namespace SHADE { - struct SHAsset + struct SH_API SHAsset { AssetName name; AssetID id; diff --git a/SHADE_Engine/src/Assets/SHAssetMacros.h b/SHADE_Engine/src/Assets/SHAssetMacros.h index 61c5879d..0fdfa04e 100644 --- a/SHADE_Engine/src/Assets/SHAssetMacros.h +++ b/SHADE_Engine/src/Assets/SHAssetMacros.h @@ -32,12 +32,12 @@ typedef std::filesystem::path AssetPath; typedef unsigned char* AssetData; typedef std::string AssetMetaVersion; typedef std::string AssetExtension; -typedef unsigned char AssetTypeMeta; +typedef size_t AssetTypeMeta; typedef FMOD::Sound* SHSound; // Asset Meta Version -#define ASSET_META_VER "1.0" +constexpr std::string_view ASSET_META_VER { "1.0" }; // Asset type enum enum class AssetType : AssetTypeMeta @@ -53,34 +53,35 @@ enum class AssetType : AssetTypeMeta SCENE, PREFAB, AUDIO_WAV, - DDS + DDS, + MAX_COUNT }; //Directory #ifdef _PUBLISH -#define ASSET_ROOT "Assets" +constexpr std::string_view ASSET_ROOT {"Assets"}; #else -#define ASSET_ROOT "../../Assets" +constexpr std::string_view ASSET_ROOT {"../../Assets"}; #endif // ASSET EXTENSIONS -#define META_EXTENSION ".shmeta" -#define IMAGE_EXTENSION ".png" -#define AUDIO_EXTENSION ".ogg" -#define AUDIO_WAV_EXTENSION ".wav" -#define SHADER_EXTENSION ".glsl" -#define SCRIPT_EXTENSION ".cs" -#define SCENE_EXTENSION ".SHADE" -#define PREFAB_EXTENSION ".SHPrefab" -#define MATERIAL_EXTENSION ".SHMat" -#define TEXTURE_EXTENSION ".shtex" -#define DDS_EXTENSION ".dds" -#define FBX_EXTENSION ".fbx" -#define GLTF_EXTENSION ".gltf" -#define MESH_EXTENSION ".shmesh" +constexpr std::string_view META_EXTENSION {".shmeta"}; +constexpr std::string_view IMAGE_EXTENSION {".png"}; +constexpr std::string_view AUDIO_EXTENSION {".ogg"}; +constexpr std::string_view AUDIO_WAV_EXTENSION {".wav"}; +constexpr std::string_view SHADER_EXTENSION {".glsl"}; +constexpr std::string_view SCRIPT_EXTENSION {".cs"}; +constexpr std::string_view SCENE_EXTENSION {".SHADE"}; +constexpr std::string_view PREFAB_EXTENSION {".SHPrefab"}; +constexpr std::string_view MATERIAL_EXTENSION {".SHMat"}; +constexpr std::string_view TEXTURE_EXTENSION {".shtex"}; +constexpr std::string_view DDS_EXTENSION {".dds"}; +constexpr std::string_view FBX_EXTENSION {".fbx"}; +constexpr std::string_view GLTF_EXTENSION {".gltf"}; +constexpr std::string_view MESH_EXTENSION {".shmesh"}; -std::string const EXTENSIONS[] = { +constexpr std::string_view EXTENSIONS[] = { AUDIO_EXTENSION, SHADER_EXTENSION, MATERIAL_EXTENSION, @@ -96,10 +97,12 @@ std::string const EXTENSIONS[] = { GLTF_EXTENSION }; +constexpr size_t TYPE_COUNT {static_cast(AssetType::MAX_COUNT) }; + // Error flags -#define FILE_NOT_FOUND_ERR "FILE NOT FOUND" -#define META_NOT_FOUND_ERR "META NOT FOUND" -#define ASSET_NOT_FOUND_ERR "ASSET NOT FOUND" -#define EXT_DOES_NOT_EXIST "TYPE DOES NOT HAVE EXTENSION DEFINED" +constexpr std::string_view FILE_NOT_FOUND_ERR {"FILE NOT FOUND"}; +constexpr std::string_view META_NOT_FOUND_ERR {"META NOT FOUND"}; +constexpr std::string_view ASSET_NOT_FOUND_ERR {"ASSET NOT FOUND"}; +constexpr std::string_view EXT_DOES_NOT_EXIST {"TYPE DOES NOT HAVE EXTENSION DEFINED"}; #endif // !SH_ASSET_MACROS_H diff --git a/SHADE_Engine/src/Assets/SHAssetManager.cpp b/SHADE_Engine/src/Assets/SHAssetManager.cpp index faca24b2..2658e83b 100644 --- a/SHADE_Engine/src/Assets/SHAssetManager.cpp +++ b/SHADE_Engine/src/Assets/SHAssetManager.cpp @@ -26,11 +26,10 @@ namespace SHADE FMOD::System* SHAssetManager::audioSystem; std::unordered_map* SHAssetManager::audioSoundList; - std::vector SHAssetManager::assetCollection; - std::unordered_map SHAssetManager::assetRegistry; + std::vector SHAssetManager::loaders(TYPE_COUNT); - std::unordered_map SHAssetManager::meshCollection; - std::unordered_map SHAssetManager::textureCollection; + std::vector SHAssetManager::assetCollection; + std::unordered_map SHAssetManager::assetData; /**************************************************************************** * \brief Static function to generate asset ID. @@ -81,7 +80,37 @@ namespace SHADE // return std::filesystem::path(); //} - return std::filesystem::path(ASSET_ROOT + folder + path.filename().string()); + return std::filesystem::path(std::string(ASSET_ROOT) + folder + path.filename().string()); + } + + AssetPath SHAssetManager::GenerateNewPath(AssetName name, AssetType type) + { + std::string folder; + + switch(type) + { + case AssetType::SCENE: + folder = "scenes/"; + break; + + case AssetType::PREFAB: + folder = "prefabs/"; + break; + + case AssetType::MATERIAL: + folder = "materials/"; + break; + + default: + folder = "/"; + } + + return std::filesystem::path{ + std::string(ASSET_ROOT) + + folder + + name + + std::string(EXTENSIONS[static_cast(type)]) + }; } /**************************************************************************** @@ -117,7 +146,7 @@ namespace SHADE // folder = ""; // break; //} - AssetPath path{ ASSET_ROOT + folder + name + SHAssetMetaHandler::GetExtensionFromType(type) }; + AssetPath path{ std::string{ASSET_ROOT} + folder + name + SHAssetMetaHandler::GetExtensionFromType(type) }; SHAssetMetaHandler::WriteMetaData(meta); @@ -126,6 +155,19 @@ namespace SHADE return id; } + AssetID SHAssetManager::CreateAsset(AssetName name, AssetType type) noexcept + { + AssetID id = GenerateAssetID(type); + + assetCollection.emplace_back( + name, + id, + type, + GenerateNewPath(name, type), + 0 + ); + return id; + } /**************************************************************************** * \brief Import new asset from outside editor window. * @@ -134,7 +176,10 @@ namespace SHADE ****************************************************************************/ AssetID SHAssetManager::ImportNewAsset(char const* p) noexcept { - std::filesystem::path const path{ p }; + std::filesystem::path const path{ p }; + + auto const type = SHAssetMetaHandler::GetTypeFromExtension(path.extension().string()); + auto const id = GenerateAssetID(type); std::filesystem::path const newPath{ GenerateLocalPath(path) }; if (newPath.empty()) @@ -145,11 +190,7 @@ namespace SHADE std::filesystem::copy(path, newPath); - AssetID id{ RetrieveAsset(newPath.string().c_str()) }; - if (id != 0) - { - LoadData(id); - } + assetCollection.push_back(CreateAssetFromPath(newPath)); return id; } @@ -160,158 +201,14 @@ namespace SHADE ****************************************************************************/ void SHAssetManager::RefreshAllAssets() noexcept { - std::vector metaFiles; - std::vector AssetFiles; - //SHFileSystem::LoadAllFiles(metaFiles, AssetFiles); - //std::vector AssetFilesVerified; - std::vector AssetFilesNew; - - for (auto const& asset : AssetFiles) - { - bool found = false; - for (auto it {metaFiles.begin()}; it != metaFiles.end(); ++it) - { - std::string fileExtCheck{ asset.filename().string() }; - fileExtCheck += META_EXTENSION; - if (it->filename().string() == fileExtCheck) - { - metaFiles.erase(it); - found = true; - break; - } - } - - if (!found && IsRecognised(asset.extension().string().c_str())) - { - AssetFilesNew.push_back(asset); - } - } - - std::vector newLoad; - newLoad.reserve(AssetFilesNew.size()); - - //TODO: Handle if meta does not match all assets (if meta exist and asset doesnt, vice versa) - for (auto const& file : AssetFilesNew) - { - newLoad.push_back(RegisterAssetNew(file)); - } - - //UpdateAllSpriteSets(); - - } - - //void SHAssetManager::LoadDataTemp(std::string p) noexcept - //{ - // AssetPath path{ p }; - - // if (path.extension().string() == FBX_EXTENSION - // || path.extension().string() == GLTF_EXTENSION - // || path.extension().string() == MESH_EXTENSION) - // { - // LoadGLTF( - // { - // .name {path.filename().string()}, - // .id {0}, - // .type {AssetType::MESH}, - // .path {path}, - // .location {0} - // } - // ); - // } - // else if (path.extension().string() == DDS_EXTENSION - // || path.extension().string() == TEXTURE_EXTENSION) - // { - // LoadDDS( - // { - // .name {path.filename().string()}, - // .id {0}, - // .type {AssetType::DDS}, - // .path {path}, - // .location {0} - // } - // ); - // } - //} - - std::vector SHAssetManager::GetAllMeshes() noexcept - { - std::vector result; - for (auto const& mesh : meshCollection) - { - result.push_back(mesh.second); - } - - return result; - } - - std::vector SHAssetManager::GetAllTextures() noexcept - { - std::vector result; - for (auto const& dds : textureCollection) - { - result.push_back(dds.second); - } - - return result; - } - - SHMeshAsset const* SHAssetManager::GetMesh(AssetID id) noexcept - { - if (meshCollection.find(id) == meshCollection.end()) - { - return nullptr; - } - - return &meshCollection[id]; - } - - SHTextureAsset const* SHAssetManager::GetTexture(AssetID id) noexcept - { - if (textureCollection.find(id) == textureCollection.end()) - { - return nullptr; - } - - return &textureCollection[id]; - } - - /**************************************************************************** - * \param Path for meta data file - * \param Path for asset file - - * \brief Links meta data to asset in registries. Meta data should - * already exist - ****************************************************************************/ - void SHAssetManager::RegisterAsset(AssetPath const& metaPath, AssetPath const& path) noexcept - { - SHAsset const meta = SHAssetMetaHandler::RetrieveMetaData(metaPath); - - assetCollection.push_back(meta); - } - - /**************************************************************************** - * \param Path for asset file - - * \brief Creates new meta data for new asset. - ****************************************************************************/ - SHAsset SHAssetManager::RegisterAssetNew(AssetPath const& asset) noexcept - { - SHAsset meta; - meta.type = SHAssetMetaHandler::GetTypeFromExtension(asset.extension().string()); - meta.id = GenerateAssetID(meta.type); - - assetCollection.push_back(meta); - - SHAssetMetaHandler::WriteMetaData(meta); - return assetCollection.back(); } bool SHAssetManager::IsRecognised(char const* ext) noexcept { for (auto const& e : EXTENSIONS) { - if (strcmp(ext, e.c_str()) == 0) + if (strcmp(ext, e.data()) == 0) { return true; } @@ -320,60 +217,31 @@ namespace SHADE return false; } - void SHAssetManager::LoadGLTF(AssetPath path) noexcept + SHAsset SHAssetManager::CreateAssetFromPath(AssetPath path) noexcept { - std::vector meshes; - std::vector anims; - - SHAssimpLibrary::LoadFromFile(path, meshes, anims); + SHAsset result; - for (auto const& mesh : meshes) - { - auto id{ GenerateAssetID(AssetType::MESH) }; - meshCollection.emplace(id, mesh); + result.name = path.stem().string(); + result.type = SHAssetMetaHandler::GetTypeFromExtension(path.extension().string()); + result.id = GenerateAssetID(result.type); + result.path = path; - AssetPath path; - if (!mesh.compiled) - { - path = SHMeshCompiler::CompileMeshBinary(mesh, path); - } - - assetCollection.emplace_back( - mesh.header.meshName, - id, - AssetType::MESH, - path, - 0 - ); - } - - for (auto const& anim : anims) - { - //TODO Register anim resource and compile into binary - } + return result; } - void SHAssetManager::LoadDDS(SHAsset asset) noexcept + void SHAssetManager::InitLoaders() noexcept { - SHTextureAsset image; - - SHTextureLoader::LoadImageAsset(asset.path, image); - - if (!image.compiled) - { - auto id{ GenerateAssetID(AssetType::TEXTURE) }; - textureCollection.emplace(id, image); - - auto path{ SHTextureCompiler::CompileTextureBinary(image, asset.path) }; - - assetCollection.emplace_back( - image.name, - id, - AssetType::TEXTURE, - path, - 0 - ); - } + loaders[static_cast(AssetType::AUDIO)] = nullptr; + loaders[static_cast(AssetType::SHADER)] = nullptr; + loaders[static_cast(AssetType::MATERIAL)] = nullptr; + loaders[static_cast(AssetType::IMAGE)] = dynamic_cast(new SHTextureLoader()); + loaders[static_cast(AssetType::TEXTURE)] = nullptr; + loaders[static_cast(AssetType::MESH)] = dynamic_cast(new SHMeshLoader()); + loaders[static_cast(AssetType::SCRIPT)] = nullptr; + loaders[static_cast(AssetType::SCENE)] = nullptr; + loaders[static_cast(AssetType::PREFAB)] = nullptr; + loaders[static_cast(AssetType::AUDIO_WAV)] = nullptr; + loaders[static_cast(AssetType::DDS)] = nullptr; } /**************************************************************************** @@ -381,7 +249,8 @@ namespace SHADE ****************************************************************************/ void SHAssetManager::Load() noexcept { - RetrieveAssets(); + InitLoaders(); + BuildAssetCollection(); LoadAllData(); } @@ -390,143 +259,40 @@ namespace SHADE ****************************************************************************/ void SHAssetManager::LoadAllData() noexcept { - //TODO Remove when on demand loading is done for (auto const& asset : assetCollection) { - switch (asset.type) - { - case AssetType::MESH: - meshCollection.emplace(asset.id, SHMeshAsset()); - SHMeshLoader::LoadSHMesh(meshCollection[asset.id], asset.path); - break; - - case AssetType::TEXTURE: - textureCollection.emplace(asset.id, SHTextureAsset()); - SHTextureLoader::LoadSHTexture(asset.path, textureCollection[asset.id]); - break; - - default: - void; - } + SHAssetData* data = loaders[static_cast(asset.type)]->Load(asset.path); + assetData.emplace(asset.id, data); } } - void SHAssetManager::LoadData(AssetID id) noexcept + SHAssetData* SHAssetManager::LoadData(SHAsset const& asset) noexcept { - (void)id; - } + SHAssetData* data = loaders[static_cast(asset.type)]->Load(asset.path); - /**************************************************************************** - * \brief Retrieve all asset files and meta files from filesystem - ****************************************************************************/ - void SHAssetManager::RetrieveAssets() noexcept - { - std::vector metaFiles; - std::vector AssetFiles; - - for (auto const dir : std::filesystem::recursive_directory_iterator(ASSET_ROOT)) + if (data == nullptr) { - if (dir.path().extension().string() == META_EXTENSION) - { - auto meta{ SHAssetMetaHandler::RetrieveMetaData(dir.path()) }; - - assetCollection.push_back(meta); - assetRegistry.emplace(meta.id, meta); - } - } - - //TODO: Write new function for file manager to loop through all files - //SHFileSystem::StartupFillDirectories(ASSET_ROOT); - //FolderPointer rootFolder = SHFileSystem::GetRoot(); - - //for (auto const& meta : metaFiles) - //{ - // for (std::vector::const_iterator it{ AssetFiles.cbegin() }; - // it != AssetFiles.cend(); - // ++it) - // { - // // Asset exists for meta file - // std::string fileExtCheck{ it->filename().string() }; - // fileExtCheck += META_EXTENSION; - // if (meta.filename().string() == fileExtCheck) - // { - // RegisterAsset(meta, *it); - // AssetFiles.erase(it); - // break; - // } - // } - //} - - //TODO: Handle if meta does not match all assets (if meta exist and asset doesnt, vice versa) - //for (auto const& file : AssetFiles) - //{ - // if (IsRecognised(file.extension().string().c_str())) - // { - // SHAssetMetaHandler::WriteMetaData(RegisterAssetNew(file)); - // } - // else - // { - // std::cout << "Unsupported File Format: " << file.filename() << "\n"; - // } - //} - } - - AssetID SHAssetManager::RetrieveAsset(char const* path) noexcept - { - std::filesystem::path p{ path }; - if (IsRecognised(p.extension().string().c_str())) - { - SHAsset const& meta{ RegisterAssetNew(p) }; - SHAssetMetaHandler::WriteMetaData(meta); - return meta.id; + SHLOG_ERROR("Unable to load asset into memory: {}\n", asset.path.string()); } else { - std::cout << "Unsupported File Format: " << p.filename() << "\n"; + assetData.emplace(asset.id, data); } - // Assert that file imported is not recognised - return 0; + return data; } - /**************************************************************************** - * \param Full path of file - - * \brief Extracts file name from path. Formats file name into readable - * with spaces and capitalises first letter of every word - ****************************************************************************/ - AssetName SHAssetManager::GetNameFromPath(AssetPath filepath) noexcept + void SHAssetManager::BuildAssetCollection() noexcept { - std::string name{ filepath.filename().string() }; - name = name.substr(0, name.find_last_of('.')); - - //if (name[0] <= 122 && name[0] >= 97) - //{ - // name[0] -= 32; - //} - - //for (size_t i{ 1 }; i < name.length(); ++i) - //{ - // // Replace all underscores with spaces - // if (name[i] == '_') - // { - // name[i] = ' '; - // continue; - // } - - // if (name[i + 1] <= 'Z' && name[i + 1] >= 'A' - // && name[i] <= 'z' && name[i] >= 'a') - // { - // name.insert(i + 1, 1, ' '); - // continue; - // } - - // if (name[i - 1] == ' ' && name[i] <= 'z' && name[i] >= 'a') - // { - // name[i] -= 32; - // } - //} - - return name; + for (auto const& dir : std::filesystem::recursive_directory_iterator{ASSET_ROOT}) + { + if (dir.is_regular_file()) + { + if (dir.path().extension().string() == META_EXTENSION.data()) + { + assetCollection.push_back(SHAssetMetaHandler::RetrieveMetaData(dir.path())); + } + } + } } } diff --git a/SHADE_Engine/src/Assets/SHAssetManager.h b/SHADE_Engine/src/Assets/SHAssetManager.h index b2c4216b..74029bdd 100644 --- a/SHADE_Engine/src/Assets/SHAssetManager.h +++ b/SHADE_Engine/src/Assets/SHAssetManager.h @@ -11,9 +11,10 @@ #pragma once #include "tinyddsloader.h" #include "SHAsset.h" +#include "Asset Types/SHAssetData.h" +#include "Libraries/SHAssetLoader.h" +#include -#include "Asset Types/SHMeshAsset.h" -#include "Asset Types/SHTextureAsset.h" #include "SH_API.h" namespace SHADE @@ -28,6 +29,8 @@ namespace SHADE static AssetPath GenerateLocalPath(AssetPath path) noexcept; + static AssetPath GenerateNewPath(AssetName name, AssetType type); + /**************************************************************************** * \brief Deallocate all memory used by resource data ****************************************************************************/ @@ -54,6 +57,7 @@ namespace SHADE * \return resource id generated for new asset ****************************************************************************/ static AssetID CreateNewAsset(AssetType, AssetName) noexcept; + static AssetID CreateAsset(AssetName name, AssetType type) noexcept; /**************************************************************************** * \brief Import new resource from outside editor window. @@ -70,67 +74,49 @@ namespace SHADE static void RefreshAllAssets() noexcept; // -------------------------------------------------------------------------/ - //TODO: TEMPORARY FOR TESTING GLTF & DDS - //static void LoadDataTemp(std::string path) noexcept; - static std::vector GetAllMeshes() noexcept; - static std::vector GetAllTextures() noexcept; + template + static std::enable_if_t, T const * const> GetData(AssetID id) noexcept + { + if (assetData.contains(id)) + { + for (auto const& asset : assetCollection) + { + if (asset.id == id) + { + assetData.emplace(id, LoadData(asset)); + return dynamic_cast(assetData[id]); + } + } - static SHMeshAsset const* GetMesh(AssetID id) noexcept; - static SHTextureAsset const* GetTexture(AssetID id) noexcept; - - // Specialised load calls - static void LoadGLTF(AssetPath path) noexcept; - static void LoadDDS(SHAsset asset) noexcept; + SHLOG_ERROR("Asset ID provided does not exist: {}", id); + return nullptr; + } + + return dynamic_cast(assetData[id]); + } private: /**************************************************************************** * \brief Load resource data into memory ****************************************************************************/ static void LoadAllData() noexcept; - static void LoadData(AssetID id) noexcept; + static SHAssetData* LoadData(SHAsset const& asset) noexcept; - /**************************************************************************** - * \brief Retrieve all resource files and meta files from filesystem - ****************************************************************************/ - static void RetrieveAssets() noexcept; - - static AssetID RetrieveAsset(char const* path) noexcept; - - /**************************************************************************** - * \param Full path of file - - * \brief Extracts file name from path. Formats file name into readable - * with spaces and capitalises first letter of every word - ****************************************************************************/ - static AssetName GetNameFromPath(AssetPath) noexcept; - - /**************************************************************************** - * \param Path for meta data file - * \param Path for resource file - - * \brief Links meta data to resource in registries. Meta data should - * already exist - ****************************************************************************/ - static void RegisterAsset(AssetPath const&, AssetPath const&) noexcept; - - /**************************************************************************** - * \param Path for resource file - - * \brief Creates new meta data for new resource. - ****************************************************************************/ - static SHAsset RegisterAssetNew(AssetPath const&) noexcept; + inline static void BuildAssetCollection() noexcept; static bool IsRecognised(char const*) noexcept; + + static SHAsset CreateAssetFromPath(AssetPath path) noexcept; + static void InitLoaders() noexcept; static FMOD::System* audioSystem; static std::unordered_map* audioSoundList; + static std::vector loaders; + // For all resources static std::vector assetCollection; - static std::unordered_map assetRegistry; - - static std::unordered_map meshCollection; - static std::unordered_map textureCollection; + static std::unordered_map assetData; }; } diff --git a/SHADE_Engine/src/Assets/SHAssetMetaHandler.cpp b/SHADE_Engine/src/Assets/SHAssetMetaHandler.cpp index 442c3d96..1bfec00d 100644 --- a/SHADE_Engine/src/Assets/SHAssetMetaHandler.cpp +++ b/SHADE_Engine/src/Assets/SHAssetMetaHandler.cpp @@ -37,7 +37,7 @@ namespace SHADE { for (int i{0}; i < EXTENSIONS->size(); ++i) { - if (ext == EXTENSIONS[i]) + if (strcmp(ext.c_str(), EXTENSIONS[i].data()) == 0) { return static_cast(i); } @@ -53,7 +53,7 @@ namespace SHADE ****************************************************************************/ AssetExtension SHAssetMetaHandler::GetExtensionFromType(AssetType type) noexcept { - return EXTENSIONS[static_cast(type)]; + return AssetExtension(EXTENSIONS[static_cast(type)]); } /**************************************************************************** @@ -124,16 +124,6 @@ namespace SHADE metaFile << "ID: " << meta.id << "\n"; metaFile << "Type: " << static_cast(meta.type) << std::endl; - ////TODO Add in information that is specific to types like mesh - //switch(meta.type) - //{ - //case AssetType::MESH: - // break; - - //default: - // break; - //} - metaFile.close(); } From 449cd28bb353b5b3a41f103dc1b6cc3540b22b17 Mon Sep 17 00:00:00 2001 From: Xiao Qi Date: Fri, 21 Oct 2022 20:55:21 +0800 Subject: [PATCH 06/13] Took test scene from main --- SHADE_Application/src/Scenes/SBTestScene.cpp | 5 ----- 1 file changed, 5 deletions(-) diff --git a/SHADE_Application/src/Scenes/SBTestScene.cpp b/SHADE_Application/src/Scenes/SBTestScene.cpp index bd33e63c..41326174 100644 --- a/SHADE_Application/src/Scenes/SBTestScene.cpp +++ b/SHADE_Application/src/Scenes/SBTestScene.cpp @@ -13,9 +13,6 @@ #include "Physics/Components/SHRigidBodyComponent.h" #include "Physics/Components/SHColliderComponent.h" -#include "Assets/Asset Types/SHMeshAsset.h" -#include "Assets/Asset Types/SHTextureAsset.h" - #include "Assets/SHAssetManager.h" #include "Resource/SHResourceManager.h" @@ -43,8 +40,6 @@ namespace Sandbox // Create temp meshes const auto CUBE_MESH = SHADE::SHPrimitiveGenerator::Cube(*graphicsSystem); - auto assets = SHAssetManager::GetAllAssets(); - //Test Racoon mesh std::vector> handles; std::vector> texHandles; From cc6e2189fa7df84faec49733f7cf417da947a970 Mon Sep 17 00:00:00 2001 From: Brandon Mak Date: Fri, 21 Oct 2022 20:56:14 +0800 Subject: [PATCH 07/13] WIP --- SHADE_Engine/src/Camera/SHCameraSystem.cpp | 1 + .../MiddleEnd/Interface/SHGraphicsConstants.h | 8 + .../MiddleEnd/Interface/SHGraphicsSystem.cpp | 35 ++- .../src/Graphics/Pipeline/SHVkPipeline.cpp | 23 ++ .../RenderGraph/SHAttachmentDescriptionType.h | 1 + .../Graphics/RenderGraph/SHRenderGraph.cpp | 45 +++- .../src/Graphics/RenderGraph/SHRenderGraph.h | 4 - .../RenderGraph/SHRenderGraphNode.cpp | 12 +- .../Graphics/RenderGraph/SHRenderGraphNode.h | 5 +- .../RenderGraph/SHRenderGraphResource.cpp | 11 + .../RenderGraph/SHRenderGraphResource.h | 11 +- .../RenderGraph/SHRenderGraphStorage.h | 3 + .../src/Graphics/RenderGraph/SHSubpass.cpp | 199 +++++++++++++++++- .../src/Graphics/RenderGraph/SHSubpass.h | 51 +++-- .../Graphics/RenderGraph/SHSubpassCompute.cpp | 34 ++- .../Graphics/RenderGraph/SHSubpassCompute.h | 28 ++- .../Graphics/Shaders/SHShaderReflected.cpp | 3 + TempShaderFolder/GreyscaleCs.glsl | 38 ++++ TempShaderFolder/GreyscaleCs.spv | Bin 0 -> 1400 bytes 19 files changed, 437 insertions(+), 75 deletions(-) create mode 100644 TempShaderFolder/GreyscaleCs.glsl create mode 100644 TempShaderFolder/GreyscaleCs.spv diff --git a/SHADE_Engine/src/Camera/SHCameraSystem.cpp b/SHADE_Engine/src/Camera/SHCameraSystem.cpp index 9c97131a..c9822b82 100644 --- a/SHADE_Engine/src/Camera/SHCameraSystem.cpp +++ b/SHADE_Engine/src/Camera/SHCameraSystem.cpp @@ -62,6 +62,7 @@ namespace SHADE system->editorCamera.position -= UP * dt * camera.movementSpeed; system->editorCamera.dirtyView = true; } + system->UpdateCameraComponent(system->editorCamera); } diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsConstants.h b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsConstants.h index 67cbc001..a0457b65 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsConstants.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsConstants.h @@ -63,6 +63,14 @@ namespace SHADE */ /***************************************************************************/ static constexpr uint32_t PER_INSTANCE = 3; + /***************************************************************************/ + /*! + \brief + DescriptorSet Index for render graph resources. + */ + /***************************************************************************/ + static constexpr uint32_t RENDERGRAPH_RESOURCE = 4; + }; diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp index 06762db8..386cef54 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp @@ -115,6 +115,23 @@ namespace SHADE 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); + + + // TODO: This is VERY temporarily here until a more solid resource management system is implemented + shaderSourceLibrary.Init("../../TempShaderFolder/"); + + shaderSourceLibrary.LoadShader(0, "TestCubeVs.glsl", SH_SHADER_TYPE::VERTEX, true); + shaderSourceLibrary.LoadShader(1, "TestCubeFs.glsl", SH_SHADER_TYPE::FRAGMENT, true); + + shaderSourceLibrary.LoadShader(2, "GreyscaleCs.glsl", SH_SHADER_TYPE::COMPUTE, true); + + shaderModuleLibrary.ImportFromSourceLibrary(device, shaderSourceLibrary); + auto cubeVS = shaderModuleLibrary.GetShaderModule("TestCubeVs.glsl"); + auto cubeFS = shaderModuleLibrary.GetShaderModule("TestCubeFs.glsl"); + auto greyscale = shaderModuleLibrary.GetShaderModule("GreyscaleCs.glsl"); + cubeVS->Reflect(); + cubeFS->Reflect(); + greyscale->Reflect(); } void SHGraphicsSystem::InitSceneRenderGraph(void) noexcept @@ -166,6 +183,13 @@ namespace SHADE gBufferWriteSubpass->AddColorOutput("Entity ID"); gBufferWriteSubpass->AddDepthOutput("Depth Buffer", SH_ATT_DESC_TYPE_FLAGS::DEPTH_STENCIL); + auto greyscale = shaderModuleLibrary.GetShaderModule("GreyscaleCs.glsl"); + + auto greyscaleSubpass = node->AddSubpass("Greyscale Subpass"); + greyscaleSubpass->AddGeneralInput("Scene"); + greyscaleSubpass->AddSubpassCompute(greyscale); + + // We do this to just transition our scene layout to shader read auto sceneLayoutTransitionSubpass = node->AddSubpass("Scene Layout Transition"); sceneLayoutTransitionSubpass->AddInput("Scene"); @@ -177,20 +201,11 @@ namespace SHADE worldRenderer = worldViewport->AddRenderer(resourceManager, swapchain->GetNumImages(), renderContextCmdPools, descPool, SHGraphicsGlobalData::GetDescSetLayouts()[SHGraphicsConstants::DescriptorSetIndex::HIGH_FREQUENCY_GLOBALS], worldRenderGraph); worldRenderer->SetCamera(worldCamera); - - // TODO: This is VERY temporarily here until a more solid resource management system is implemented - shaderSourceLibrary.Init("../../TempShaderFolder/"); - - shaderSourceLibrary.LoadShader(0, "TestCubeVs.glsl", SH_SHADER_TYPE::VERTEX, true); - shaderSourceLibrary.LoadShader(1, "TestCubeFs.glsl", SH_SHADER_TYPE::FRAGMENT, true); - - shaderModuleLibrary.ImportFromSourceLibrary(device, shaderSourceLibrary); auto cubeVS = shaderModuleLibrary.GetShaderModule("TestCubeVs.glsl"); auto cubeFS = shaderModuleLibrary.GetShaderModule("TestCubeFs.glsl"); - cubeVS->Reflect(); - cubeFS->Reflect(); defaultMaterial = AddMaterial(cubeVS, cubeFS, gBufferWriteSubpass); + } void SHGraphicsSystem::InitMiddleEnd(void) noexcept diff --git a/SHADE_Engine/src/Graphics/Pipeline/SHVkPipeline.cpp b/SHADE_Engine/src/Graphics/Pipeline/SHVkPipeline.cpp index c03fd2a7..973218d1 100644 --- a/SHADE_Engine/src/Graphics/Pipeline/SHVkPipeline.cpp +++ b/SHADE_Engine/src/Graphics/Pipeline/SHVkPipeline.cpp @@ -171,6 +171,29 @@ namespace SHADE void SHVkPipeline::CreateComputePipeline(void) noexcept { + auto shaderModule = pipelineLayout->GetShaderModules()[0]; + + vk::PipelineShaderStageCreateInfo shaderStageCreateInfo + { + .stage = vk::ShaderStageFlagBits::eCompute, + .module = shaderModule->GetVkShaderModule(), + .pName = shaderModule->GetEntryPoint().c_str(), + }; + + vk::ComputePipelineCreateInfo cpCreateInfo + { + .flags = {}, + .stage = shaderStageCreateInfo, + .layout = pipelineLayout->GetVkPipelineLayout(), + }; + + if (auto result = logicalDeviceHdl->GetVkLogicalDevice().createComputePipelines({}, 1, &cpCreateInfo, nullptr, &vkPipeline); result != vk::Result::eSuccess) + SHVulkanDebugUtil::ReportVkError(result, "Failed to create Compute Pipeline. "); + else + { + SHVulkanDebugUtil::ReportVkSuccess("Successfully created a Compute Pipeline. "); + created = true; + } } diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHAttachmentDescriptionType.h b/SHADE_Engine/src/Graphics/RenderGraph/SHAttachmentDescriptionType.h index 241292d4..efd3fb0f 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHAttachmentDescriptionType.h +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHAttachmentDescriptionType.h @@ -12,4 +12,5 @@ namespace SHADE DEPTH_STENCIL = 0x10, INPUT = 0x20 }; + } diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp index 1db410c0..df588c05 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp @@ -10,6 +10,7 @@ #include "Tools/SHLogger.h" #include "SHAttachmentDescInitParams.h" #include "SHRenderGraphStorage.h" +#include "Graphics/RenderGraph/SHSubpassCompute.h" namespace SHADE { @@ -78,36 +79,48 @@ namespace SHADE for (uint32_t i = 0; auto& node : nodes) { - // key is handle ID, value is pair (first is initial layout, second is final layout). - std::unordered_map resourceAttLayouts; + // key is handle ID, value is final layout. + std::unordered_map resourceAttFinalLayouts; if (node->subpasses.empty()) { SHLOG_ERROR("Node does not contain a subpass. Cannot configure attachment descriptions as a result. "); return; } + // attempt to get all final layouts for all resources for (auto& subpass : node->subpasses) { for (auto& color : subpass->colorReferences) { + // If final renderpass and attachment is a COLOR_PRESENT resource, make resource transition to present after last subpass if (i == nodes.size() - 1 && (node->attResources[color.attachment]->resourceTypeFlags & static_cast(SH_ATT_DESC_TYPE_FLAGS::COLOR_PRESENT))) - resourceAttLayouts[color.attachment] = vk::ImageLayout::ePresentSrcKHR; + resourceAttFinalLayouts[color.attachment] = vk::ImageLayout::ePresentSrcKHR; else - resourceAttLayouts[color.attachment] = color.layout; + resourceAttFinalLayouts[color.attachment] = color.layout; } for (auto& depth : subpass->depthReferences) - resourceAttLayouts[depth.attachment] = depth.layout; + resourceAttFinalLayouts[depth.attachment] = depth.layout; for (auto& input : subpass->inputReferences) - resourceAttLayouts[input.attachment] = input.layout; + resourceAttFinalLayouts[input.attachment] = input.layout; + + // Go through all subpass computes and initialize final layouts to GENERAL when a resource is detected to be used in it + //for (auto sbCompute : subpass->subpassComputes) + //{ + // auto const& indices = sbCompute->attachmentDescriptionIndices; + // for (auto& index : indices) + // { + // resourceAttFinalLayouts[index] = vk::ImageLayout::eGeneral; + // } + //} } for (uint32_t j = 0; j < node->attachmentDescriptions.size(); ++j) { auto& att = node->attachmentDescriptions[j]; att.initialLayout = vk::ImageLayout::eUndefined; - att.finalLayout = resourceAttLayouts[j]; + att.finalLayout = resourceAttFinalLayouts[j]; } ++i; } @@ -175,7 +188,7 @@ namespace SHADE // Now we want to loop through all attachments in all subpasses in the node and query // the resources being used. For each resource we want to query the type and record it // in bit fields (1 bit for each subpass). - uint32_t colorRead = 0, colorWrite = 0, depthRead = 0, depthWrite = 0, inputDependencies = 0; + uint32_t colorRead = 0, colorWrite = 0, depthRead = 0, depthWrite = 0, inputDependencies = 0, descriptorDependencies = 0; uint32_t i = 0; @@ -214,6 +227,9 @@ namespace SHADE if (subpass->inputReferences.size()) inputDependencies |= (1 << i); + if (!subpass->subpassComputes.empty()) + descriptorDependencies |= (1 << i); + // Input attachments can be any type, so we need to check what type it is for (auto& inputAtt : subpass->inputReferences) { @@ -279,6 +295,12 @@ namespace SHADE dstAccess |= vk::AccessFlagBits::eInputAttachmentRead; } + if (descriptorDependencies & (1 << i)) + { + dstStage |= vk::PipelineStageFlagBits::eComputeShader; + dstAccess |= vk::AccessFlagBits::eShaderWrite | vk::AccessFlagBits::eShaderRead; + } + //// If subpass of first renderpass, stage flag should be bottom of pipe //if (&node == &nodes.front() && i == 0) // srcStage = vk::PipelineStageFlagBits::eBottomOfPipe; @@ -293,6 +315,9 @@ namespace SHADE dep.dstAccessMask = dstAccess; dep.srcStageMask = srcStage; + + // initialize the barriers + //node->subpasses[i]->InitComputeBarriers(); } } } @@ -353,6 +378,8 @@ namespace SHADE renderGraphStorage->resourceManager = resourceManager; renderGraphStorage->descriptorPool = logicalDevice->CreateDescriptorPools(); + + renderGraphStorage->ptrToResources = &graphResources; } /***************************************************************************/ @@ -459,7 +486,7 @@ namespace SHADE } } - nodes.emplace_back(resourceManager->Create(renderGraphStorage, std::move(descInitParams), std::move(predecessors), &graphResources)); + nodes.emplace_back(resourceManager->Create(renderGraphStorage, std::move(descInitParams), std::move(predecessors))); nodeIndexing.emplace(nodeName, static_cast(nodes.size()) - 1u); return nodes.at(nodeIndexing[nodeName]); } diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.h b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.h index 9dbfa6d3..529476cf 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.h +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.h @@ -57,10 +57,6 @@ namespace SHADE /*-----------------------------------------------------------------------*/ /* PRIVATE MEMBER VARIABLES */ /*-----------------------------------------------------------------------*/ - //Handle logicalDeviceHdl; - - //! swapchain used for querying image count - //Handle swapchainHdl; Handle renderGraphStorage; diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.cpp b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.cpp index 48855806..0d88a93a 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.cpp +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.cpp @@ -83,6 +83,11 @@ namespace SHADE framebuffers[i]->HandleResize(renderpass, imageViews, fbWidth, fbHeight); } + + for (auto& subpass : subpasses) + { + subpass->HandleResize(); + } } /***************************************************************************/ @@ -105,7 +110,7 @@ namespace SHADE */ /***************************************************************************/ - SHRenderGraphNode::SHRenderGraphNode(Handle renderGraphStorage, std::vector attDescInitParams, std::vector> predecessors, std::unordered_map> const* resources) noexcept + SHRenderGraphNode::SHRenderGraphNode(Handle renderGraphStorage, std::vector attDescInitParams, std::vector> predecessors) noexcept : graphStorage{ renderGraphStorage} , renderpass{} , framebuffers{} @@ -116,7 +121,6 @@ namespace SHADE , subpasses{} , executed{ false } , configured{ false } - , ptrToResources{ resources } { // pipeline library initialization pipelineLibrary.Init(graphStorage->logicalDevice); @@ -173,7 +177,6 @@ namespace SHADE , subpassIndexing{ std::move(rhs.subpassIndexing) } , configured{ rhs.configured } , executed{ rhs.executed } - , ptrToResources{ rhs.ptrToResources } , pipelineLibrary{ std::move(rhs.pipelineLibrary) } , batcher{ std::move(rhs.batcher) } , spDescs{ std::move(rhs.spDescs) } @@ -197,7 +200,6 @@ namespace SHADE 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); spDescs = std::move(rhs.spDescs); @@ -233,7 +235,7 @@ namespace SHADE } // Add subpass to container and create mapping for it - subpasses.emplace_back(graphStorage->resourceManager->Create(graphStorage, GetHandle(), subpasses.size(), &resourceAttachmentMapping, ptrToResources)); + subpasses.emplace_back(graphStorage->resourceManager->Create(graphStorage, GetHandle(), subpasses.size(), &resourceAttachmentMapping)); subpassIndexing.try_emplace(subpassName, static_cast(subpasses.size()) - 1u); Handle subpass = subpasses.back(); subpass->Init(*graphStorage->resourceManager); diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.h b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.h index 04638c37..7c3622ad 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.h +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.h @@ -64,9 +64,6 @@ namespace SHADE //! For indexing subpasses std::map subpassIndexing; - //! Pointer to resources in the render graph (for getting handle IDs) - std::unordered_map> const* ptrToResources; - //! Every renderpass will require a pipeline library that will contain pipelines compatible with this renderpass SHPipelineLibrary pipelineLibrary; @@ -89,7 +86,7 @@ namespace SHADE /*-----------------------------------------------------------------------*/ /* CTORS AND DTORS */ /*-----------------------------------------------------------------------*/ - SHRenderGraphNode(Handle renderGraphStorage, std::vector attDescInitParams, std::vector> predecessors, std::unordered_map> const* resources) noexcept; + SHRenderGraphNode(Handle renderGraphStorage, std::vector attDescInitParams, std::vector> predecessors) noexcept; SHRenderGraphNode(SHRenderGraphNode&& rhs) noexcept; SHRenderGraphNode& operator= (SHRenderGraphNode&& rhs) noexcept; diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphResource.cpp b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphResource.cpp index d3f20665..651ba88b 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphResource.cpp +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphResource.cpp @@ -308,6 +308,7 @@ namespace SHADE return resourceFormat; } + uint32_t SHRenderGraphResource::GetWidth(void) const noexcept { return width; @@ -323,4 +324,14 @@ namespace SHADE return imageViews [index]; } + Handle SHRenderGraphResource::GetImage(uint32_t index /*= NON_SWAPCHAIN_RESOURCE_INDEX*/) const noexcept + { + return images[index]; + } + + uint8_t SHRenderGraphResource::GetMipLevels(void) const noexcept + { + return mipLevels; + } + } \ No newline at end of file diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphResource.h b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphResource.h index 4bdecc49..55f25864 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphResource.h +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphResource.h @@ -82,12 +82,15 @@ namespace SHADE /*-----------------------------------------------------------------------*/ /* SETTERS AND GETTERS */ /*-----------------------------------------------------------------------*/ - vk::Format GetResourceFormat (void) const noexcept; - uint32_t GetWidth (void) const noexcept; - uint32_t GetHeight (void) const noexcept; - Handle GetImageView (uint32_t index = NON_SWAPCHAIN_RESOURCE_INDEX) const noexcept; + vk::Format GetResourceFormat (void) const noexcept; + uint32_t GetWidth (void) const noexcept; + uint32_t GetHeight (void) const noexcept; + Handle GetImageView (uint32_t index = NON_SWAPCHAIN_RESOURCE_INDEX) const noexcept; + Handle GetImage (uint32_t index = NON_SWAPCHAIN_RESOURCE_INDEX) const noexcept; + uint8_t GetMipLevels (void) const noexcept; friend class SHRenderGraphNode; friend class SHRenderGraph; + friend class SHSubpass; }; } diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphStorage.h b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphStorage.h index 9fcc4528..cb274697 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphStorage.h +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphStorage.h @@ -24,6 +24,9 @@ namespace SHADE //! Descriptor pool for the descriptor sets to be created in the subpasses Handle descriptorPool; + //! For accessing resources anyone in the graph + std::unordered_map> const* ptrToResources; + friend class SHRenderGraph; friend class SHRenderGraphNode; friend class SHSubpass; diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHSubpass.cpp b/SHADE_Engine/src/Graphics/RenderGraph/SHSubpass.cpp index 3daafb8f..e6472c52 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHSubpass.cpp +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHSubpass.cpp @@ -8,6 +8,10 @@ #include "SHRenderGraphNode.h" #include "SHRenderGraphStorage.h" #include "Graphics/RenderGraph/SHSubpassCompute.h" +#include "Graphics/Descriptors/SHVkDescriptorSetGroup.h" +#include "Graphics/Swapchain/SHVkSwapchain.h" +#include "Graphics/Images/SHVkSampler.h" +#include "SHRenderGraphResource.h" namespace SHADE { @@ -27,9 +31,8 @@ namespace SHADE */ /***************************************************************************/ - SHSubpass::SHSubpass(Handle renderGraphStorage, Handle const& parent, uint32_t index, std::unordered_map const* mapping, std::unordered_map> const* resources) noexcept + SHSubpass::SHSubpass(Handle renderGraphStorage, Handle const& parent, uint32_t index, std::unordered_map const* mapping) noexcept : resourceAttachmentMapping{ mapping } - , ptrToResources{ resources } , parentNode{ parent } , subpassIndex{ index } , superBatch{} @@ -37,6 +40,8 @@ namespace SHADE , depthReferences{} , inputReferences{} , graphStorage{ renderGraphStorage } + , subpassComputes{} + , inputImageDescriptors {SHGraphicsConstants::NUM_FRAME_BUFFERS} { } @@ -59,10 +64,10 @@ namespace SHADE , depthReferences{ std::move(rhs.depthReferences) } , inputReferences{ std::move(rhs.inputReferences) } , resourceAttachmentMapping{ rhs.resourceAttachmentMapping } - , ptrToResources{ rhs.ptrToResources } , descriptorSetLayout{ rhs.descriptorSetLayout } , exteriorDrawCalls{ std::move(rhs.exteriorDrawCalls) } , graphStorage{ std::move(rhs.graphStorage) } + , subpassComputes{std::move (rhs.subpassComputes)} { } @@ -90,10 +95,10 @@ namespace SHADE depthReferences = std::move(rhs.depthReferences); inputReferences = std::move(rhs.inputReferences); resourceAttachmentMapping = rhs.resourceAttachmentMapping; - ptrToResources = rhs.ptrToResources; descriptorSetLayout = rhs.descriptorSetLayout; exteriorDrawCalls = std::move(rhs.exteriorDrawCalls); graphStorage = std::move(rhs.graphStorage); + subpassComputes = std::move(rhs.subpassComputes); return *this; } @@ -112,7 +117,7 @@ namespace SHADE /***************************************************************************/ void SHSubpass::AddColorOutput(std::string resourceToReference) noexcept { - colorReferences.push_back({ resourceAttachmentMapping->at(ptrToResources->at(resourceToReference).GetId().Raw), vk::ImageLayout::eColorAttachmentOptimal }); + colorReferences.push_back({ resourceAttachmentMapping->at(graphStorage->ptrToResources->at(resourceToReference).GetId().Raw), vk::ImageLayout::eColorAttachmentOptimal }); } /***************************************************************************/ @@ -149,7 +154,7 @@ namespace SHADE //Invalid return; } - depthReferences.push_back({ resourceAttachmentMapping->at(ptrToResources->at(resourceToReference).GetId().Raw), imageLayout }); + depthReferences.push_back({ resourceAttachmentMapping->at(graphStorage->ptrToResources->at(resourceToReference).GetId().Raw), imageLayout }); } /***************************************************************************/ @@ -166,7 +171,15 @@ namespace SHADE /***************************************************************************/ void SHSubpass::AddInput(std::string resourceToReference) noexcept { - inputReferences.push_back({ resourceAttachmentMapping->at(ptrToResources->at(resourceToReference).GetId().Raw), vk::ImageLayout::eShaderReadOnlyOptimal }); + inputReferences.push_back({ resourceAttachmentMapping->at(graphStorage->ptrToResources->at(resourceToReference).GetId().Raw), vk::ImageLayout::eShaderReadOnlyOptimal }); + + inputNames.push_back(resourceToReference); + } + + void SHSubpass::AddGeneralInput(std::string resourceToReference) noexcept + { + inputReferences.push_back({ resourceAttachmentMapping->at(graphStorage->ptrToResources->at(resourceToReference).GetId().Raw), vk::ImageLayout::eGeneral }); + } void SHSubpass::Execute(Handle& commandBuffer, Handle descPool, uint32_t frameIndex) noexcept @@ -182,6 +195,17 @@ namespace SHADE { drawCall(commandBuffer); } + + // if there are subpass computes, transition all to GENERAL layout first + for (auto& sbCompute : subpassComputes) + { + + } + } + + void SHSubpass::HandleResize(void) noexcept + { + UpdateWriteDescriptors(); } void SHSubpass::AddExteriorDrawCalls(std::function&)> const& newDrawCall) noexcept @@ -189,9 +213,27 @@ namespace SHADE exteriorDrawCalls.push_back(newDrawCall); } - Handle SHSubpass::ActivateSubpassCompute(Handle computeShaderModule, std::initializer_list resources) noexcept + Handle SHSubpass::AddSubpassCompute(Handle computeShaderModule/*, std::initializer_list resources*/) noexcept { - subpassCompute = graphStorage->resourceManager->Create(graphStorage, computeShaderModule, resources); + //// for the subpass compute to store indices to the resources, see member comments + //std::unordered_set attDescIndices{}; + //attDescIndices.reserve (resources.size()); + + //// Look for the required resources in the graph + //std::vector> subpassComputeResources{}; + //subpassComputeResources.reserve(resources.size()); + + //for (auto& resourceName : resources) + //{ + // auto resource = graphStorage->ptrToResources->at(resourceName); + // subpassComputeResources.push_back(resource); + // attDescIndices.emplace(resourceAttachmentMapping->at (resource.GetId().Raw)); + //} + + // Create the subpass compute with the resources + auto subpassCompute = graphStorage->resourceManager->Create(graphStorage, computeShaderModule/*, std::move(subpassComputeResources), std::move (attDescIndices)*/); + subpassComputes.push_back(subpassCompute); + return subpassCompute; } @@ -201,6 +243,145 @@ namespace SHADE } + void SHSubpass::CreateInputDescriptors(void) noexcept + { + //std::vector bindings{}; + + //for (auto& input : inputReferences) + //{ + // SHVkDescriptorSetLayout::Binding newBinding + // { + // .Type = (input.layout == vk::ImageLayout::eShaderReadOnlyOptimal) ? vk::DescriptorType::eInputAttachment : vk::DescriptorType::eStorageImage, + // .Stage = vk::ShaderStageFlagBits::eFragment | vk::ShaderStageFlagBits::eCompute, + // .BindPoint = static_cast(bindings.size()), + // .DescriptorCount = 1, + // .flags = {}, + // }; + + // bindings.push_back(newBinding); + //} + + //// We build a new descriptor set layout to store our images + //inputDescriptorLayout = graphStorage->logicalDevice->CreateDescriptorSetLayout(SHGraphicsConstants::DescriptorSetIndex::RENDERGRAPH_RESOURCE, bindings); + + //// we store a sampler if its an input attachment. if it is storage image, no need sampler, store an empty handle. + //for (uint32_t i = 0; i < bindings.size(); ++i) + //{ + // if (bindings[i].Type == vk::DescriptorType::eInputAttachment) + // { + // auto newSampler = graphStorage->logicalDevice->CreateSampler(SHVkSamplerParams + // { + // .minFilter = vk::Filter::eLinear, + // .magFilter = vk::Filter::eLinear, + // .addressMode = vk::SamplerAddressMode::eRepeat, + // .mipmapMode = vk::SamplerMipmapMode::eLinear, + // .minLod = -1000, + // .maxLod = 1000 + // } + // ); + + // inputSamplers.push_back(newSampler); + // } + // else + // { + // inputSamplers.push_back({}); + // } + //} + + //// maybe do this in handle resize? + //UpdateWriteDescriptors(); + } + + void SHSubpass::UpdateWriteDescriptors(void) noexcept + { + //auto const& bindings = inputDescriptorLayout->GetBindings(); + + //std::vector variableCounts{ static_cast(bindings.size()), 0 }; + + //uint32_t i = 0; + + //// For every frame's descriptor set + //for (auto& group : inputImageDescriptors) + //{ + // if (group) + // group.Free(); + + // group = graphStorage->descriptorPool->Allocate({ inputDescriptorLayout }, variableCounts); + + // for (auto& binding : bindings) + // { + // // get the resource + // auto resource = graphStorage->ptrToResources->at(inputNames[binding.BindPoint]); + + // // If resource is swapchain image, get the correct image, if not just get 0. + // uint32_t viewIndex = (resource->resourceTypeFlags & static_cast(SH_ATT_DESC_TYPE_FLAGS::COLOR_PRESENT)) ? i : 0; + + // // layout is GENERAL if image is meant to be used as storage image, if not use SHADER_READ_ONLY_OPTINAL + // vk::ImageLayout descriptorLayout = (binding.Type == vk::DescriptorType::eStorageImage) ? vk::ImageLayout::eGeneral : vk::ImageLayout::eShaderReadOnlyOptimal; + + // // Update descriptor sets + // auto args = std::make_tuple(resource->GetImageView(viewIndex), inputSamplers[i], descriptorLayout); + // group->ModifyWriteDescImage(SHGraphicsConstants::DescriptorSetIndex::RENDERGRAPH_RESOURCE, binding.BindPoint, std::span{&args, 1}); + // group->UpdateDescriptorSetImages(SHGraphicsConstants::DescriptorSetIndex::RENDERGRAPH_RESOURCE, binding.BindPoint); + // } + + // ++i; + //} + } + + //void SHSubpass::InitComputeBarriers(void) noexcept + //{ + // std::unordered_set handleBarriers{}; + + // // we will have swapchainNumImages vectors of vector of barriers + // subpassComputeBarriers.resize(graphStorage->swapchain->GetNumImages()); + + // for (auto sbCompute : subpassComputes) + // { + // // for every resource the subpass compute is using + // for (auto resource : sbCompute->resources) + // { + // // Get the resource handle + // uint64_t resourceRaw = resource.GetId().Raw; + + // // if the barrier is not registered + // if (!handleBarriers.contains(resourceRaw)) + // { + // // If the resource is a swapchain image + // bool isSwapchainImage = (resource->resourceTypeFlags & static_cast(SH_ATT_DESC_TYPE_FLAGS::COLOR_PRESENT)); + // for (uint32_t i = 0; i < graphStorage->swapchain->GetNumImages(); ++i) + // { + // // if swapchain image, we want the index of the swapchain image, if not take base image + // uint32_t imageIndex = isSwapchainImage ? i : 0; + + // // Prepare image barrier + // vk::ImageMemoryBarrier imageBarrier + // { + // .oldLayout = colorReferences[resourceAttachmentMapping->at(resource.GetId().Raw)].layout, + // .newLayout = vk::ImageLayout::eGeneral, + // .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, + // .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, + // .image = resource->GetImage(imageIndex)->GetVkImage(), + // .subresourceRange = + // { + // .aspectMask = resource->imageAspectFlags, + // .levelCount = resource->GetMipLevels(), + // .baseArrayLayer = 0, + // .layerCount = 1 + // } + // }; + + // // push the barrier + // subpassComputeBarriers[i].push_back(imageBarrier); + // } + + // // Image transition registered + // handleBarriers.emplace(resourceRaw); + // } + // } + // } + //} + /***************************************************************************/ /*! diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHSubpass.h b/SHADE_Engine/src/Graphics/RenderGraph/SHSubpass.h index 71496b92..48874a06 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHSubpass.h +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHSubpass.h @@ -14,10 +14,12 @@ namespace SHADE class SHRenderGraphResource; class SHVkCommandBuffer; class SHVkDescriptorSetLayout; + class SHVkDescriptorSetGroup; class SHVkDescriptorPool; class SHRenderGraphStorage; class SHSubpassCompute; class SHVkShaderModule; + class SHVkSampler; class SH_API SHSubpass : public ISelfHandle { @@ -25,38 +27,52 @@ namespace SHADE /*---------------------------------------------------------------------*/ /* PRIVATE MEMBER VARIABLES */ /*---------------------------------------------------------------------*/ - Handle graphStorage; + Handle graphStorage; //! The index of the subpass in the render graph - uint32_t subpassIndex; + uint32_t subpassIndex; //! The parent renderpass that this subpass belongs to - Handle parentNode; + Handle parentNode; //! - Handle superBatch; + Handle superBatch; //! Descriptor set layout to hold attachments - Handle descriptorSetLayout; + Handle descriptorSetLayout; //! Color attachments - std::vector colorReferences; + std::vector colorReferences; //! Depth attachments - std::vector depthReferences; + std::vector depthReferences; //! Input attachments - std::vector inputReferences; + std::vector inputReferences; + + //! This is mainly for when we want to retrieve resources using names. + std::vector inputNames; //! For getting attachment reference indices using handles std::unordered_map const* resourceAttachmentMapping; - //! Pointer to resources in the render graph (for getting handle IDs) - std::unordered_map> const* ptrToResources; + //! Descriptor set group to hold the images for input + std::vector> inputImageDescriptors; + + //! Descriptor set layout for allocating descriptor set for inputs + Handle inputDescriptorLayout; + + std::vector> inputSamplers; //! Sometimes we want the subpass to do something to the images instead //! of drawing objects on the image (i.e. compute). - Handle subpassCompute; + std::vector> subpassComputes; + + ////! subpass compute image barriers. We do this because every frame has a different + ////! swapchain image. If the resource we want to transition is not a swapchain image, + ////! we duplicate the barrier anyway, not much memory wasted. ;) + //std::vector> subpassComputeBarriers{}; + //! 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. @@ -71,7 +87,7 @@ namespace SHADE /*-----------------------------------------------------------------------*/ /* CTORS AND DTORS */ /*-----------------------------------------------------------------------*/ - SHSubpass(Handle renderGraphStorage, Handle const& parent, uint32_t index, std::unordered_map const* mapping, std::unordered_map> const* ptrToResources) noexcept; + SHSubpass(Handle renderGraphStorage, Handle const& parent, uint32_t index, std::unordered_map const* mapping) noexcept; SHSubpass(SHSubpass&& rhs) noexcept; SHSubpass& operator=(SHSubpass&& rhs) noexcept; @@ -82,14 +98,20 @@ namespace SHADE void AddColorOutput(std::string resourceToReference) noexcept; void AddDepthOutput(std::string resourceToReference, SH_ATT_DESC_TYPE_FLAGS attachmentDescriptionType = SH_ATT_DESC_TYPE_FLAGS::DEPTH_STENCIL) noexcept; void AddInput(std::string resourceToReference) noexcept; + void AddGeneralInput (std::string resourceToReference) noexcept; + void AddExteriorDrawCalls(std::function&)> const& newDrawCall) noexcept; // Runtime functions void Execute(Handle& commandBuffer, Handle descPool, uint32_t frameIndex) noexcept; - void AddExteriorDrawCalls(std::function&)> const& newDrawCall) noexcept; + void HandleResize (void) noexcept; - Handle ActivateSubpassCompute(Handle computeShaderModule, std::initializer_list resources) noexcept; + Handle AddSubpassCompute(Handle computeShaderModule/*, std::initializer_list resources*/) noexcept; void Init(ResourceManager& resourceManager) noexcept; + + //void InitComputeBarriers (void) noexcept; + void CreateInputDescriptors (void) noexcept; + void UpdateWriteDescriptors (void) noexcept; /*-----------------------------------------------------------------------*/ /* GETTERS AND SETTERS */ @@ -102,5 +124,6 @@ namespace SHADE friend class SHRenderGraphNode; friend class SHRenderGraph; + friend class SHSubpass; }; } diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHSubpassCompute.cpp b/SHADE_Engine/src/Graphics/RenderGraph/SHSubpassCompute.cpp index f30fa85f..79242c7d 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHSubpassCompute.cpp +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHSubpassCompute.cpp @@ -11,25 +11,43 @@ namespace SHADE { - SHSubpassCompute::SHSubpassCompute(Handle graphStorage, Handle computeShaderModule, std::initializer_list resources) noexcept + SHSubpassCompute::SHSubpassCompute(Handle graphStorage, Handle computeShaderModule/*, std::vector>&& subpassComputeResources, std::unordered_set&& attDescIndices*/) noexcept : pipeline{} { SHPipelineLayoutParams pipelineLayoutParams { + .shaderModules = {computeShaderModule}, .globalDescSetLayouts = SHGraphicsGlobalData::GetDescSetLayouts() }; - //pipeline = logicalDevice->CreateComputePipeline() + // Create descriptor set from + pipelineLayout = graphStorage->logicalDevice->CreatePipelineLayout (pipelineLayoutParams); - // 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(); + // Create the compute pipeline + pipeline = graphStorage->logicalDevice->CreateComputePipeline(pipelineLayout); + + pipeline->ConstructPipeline(); + + // Get the descriptor set layouts required to allocate. We only want the ones for allocate because + // global descriptors are already bound in the main system. + //auto const& layouts = pipeline->GetPipelineLayout()->GetDescriptorSetLayoutsAllocate(); // Variable counts for the descriptor sets (all should be 1). - std::vector variableCounts{ static_cast(layouts.size()) }; - std::fill(variableCounts.begin(), variableCounts.end(), 0); + //std::vector variableCounts{ static_cast(layouts.size()) }; + //std::fill(variableCounts.begin(), variableCounts.end(), 0); - // Allocate descriptor sets to hold the images for reading (STORAGE_IMAGE) - descSetGroup = graphStorage->descriptorPool->Allocate(layouts, variableCounts); + //// Allocate descriptor sets to hold the images for reading (STORAGE_IMAGE) + //descSetGroup = graphStorage->descriptorPool->Allocate(layouts, variableCounts); + + //// save the resources + //resources = std::move (subpassComputeResources); + + //// we save this because when we configure the graph, we want to make sure final layouts + //// of attachment descriptions are set to GENERAL. See ConfigureAttachmentDescriptions in SHRenderGraph.cpp. + //attachmentDescriptionIndices = std::move (attDescIndices); + + //descSetGroup->ModifyWriteDescImage (SHGraphicsConstants::DescriptorSetIndex::RENDERGRAPH_RESOURCE, ) } + //SHSubpass } diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHSubpassCompute.h b/SHADE_Engine/src/Graphics/RenderGraph/SHSubpassCompute.h index 8dfc361e..aae2a9b9 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHSubpassCompute.h +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHSubpassCompute.h @@ -3,6 +3,7 @@ #include "Resource/Handle.h" #include #include +#include namespace SHADE { @@ -12,26 +13,37 @@ namespace SHADE class SHVkLogicalDevice; class SHVkPipelineLayout; class SHRenderGraphStorage; + class SHRenderGraphResource; class SHVkShaderModule; class SHSubpassCompute { private: //! To run the dispatch command - Handle pipeline; + Handle pipeline; - //! Pipeline layout for the pipline creation - Handle pipelineLayout; + //! Pipeline layout for the pipeline creation + Handle pipelineLayout; - //! Descriptor set group to hold the images for reading (STORAGE_IMAGE) - Handle descSetGroup; + ////! Descriptor set group to hold the images for reading (STORAGE_IMAGE) + //Handle descSetGroup; - //! Required resources to be used in the descriptors - std::vector resourcesRequired; + ////! Required resources to be used in the descriptors + //std::vector resourcesRequired; + + ////! vector of resources needed by the subpass compute + //std::vector> resources; + + ////! we save this because when we configure the graph, we want to make sure final layouts + ////! of attachment descriptions are set to GENERAL. See ConfigureAttachmentDescriptions in SHRenderGraph.cpp. + //std::unordered_set attachmentDescriptionIndices{}; public: - SHSubpassCompute(Handle graphStorage, Handle computeShaderModule, std::initializer_list resources) noexcept; + SHSubpassCompute(Handle graphStorage, Handle computeShaderModule/*, std::vector>&& subpassComputeResources, std::unordered_set&& attDescIndices*/) noexcept; + //void ExecuteSubpass (void) noexcept; + friend class SHRenderGraph; + friend class SHSubpass; }; } diff --git a/SHADE_Engine/src/Graphics/Shaders/SHShaderReflected.cpp b/SHADE_Engine/src/Graphics/Shaders/SHShaderReflected.cpp index 41327988..e635f763 100644 --- a/SHADE_Engine/src/Graphics/Shaders/SHShaderReflected.cpp +++ b/SHADE_Engine/src/Graphics/Shaders/SHShaderReflected.cpp @@ -177,6 +177,9 @@ namespace SHADE return vk::DescriptorType::eStorageBufferDynamic; case SpvReflectDescriptorType::SPV_REFLECT_DESCRIPTOR_TYPE_INPUT_ATTACHMENT: return vk::DescriptorType::eInputAttachment; + case SpvReflectDescriptorType::SPV_REFLECT_DESCRIPTOR_TYPE_STORAGE_IMAGE: + return vk::DescriptorType::eStorageImage; + break; default: return vk::DescriptorType::eCombinedImageSampler; break; diff --git a/TempShaderFolder/GreyscaleCs.glsl b/TempShaderFolder/GreyscaleCs.glsl new file mode 100644 index 00000000..3167a57c --- /dev/null +++ b/TempShaderFolder/GreyscaleCs.glsl @@ -0,0 +1,38 @@ +/* Start Header *****************************************************************/ + +/*! \file (e.g. kirsch.comp) + + \author William Zheng, william.zheng, 60001906. Brandon Mak, brandon.hao 390003920. + + \par william.zheng\@digipen.edu. brandon.hao\@digipen.edu. + + \date Sept 20, 2022 + + \brief Copyright (C) 20xx 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. */ + + /* End Header *******************************************************************/ + +#version 450 + +layout(local_size_x = 16, local_size_y = 16) in; +layout(set = 4, binding = 0, rgba8) uniform image2D targetImage; + + +void main() +{ + // load the image + vec4 color = imageLoad (targetImage, ivec2 (gl_GlobalInvocationID)); + + // get the average + float average = 0.2126 * color.r + 0.7152 * color.g + 0.0722 * color.b; + + // store result into result image + imageStore(targetImage, ivec2(gl_GlobalInvocationID), vec4(average, average, average, 1.0f)); + +} + + + + diff --git a/TempShaderFolder/GreyscaleCs.spv b/TempShaderFolder/GreyscaleCs.spv new file mode 100644 index 0000000000000000000000000000000000000000..5b36e00317061a12d75127def8a67c940e8969c6 GIT binary patch literal 1400 zcmZ9K+fEZv6o$97g$e>9Ld9b%o)E04oRoku(M*~&0pb-`lVLh(CK*~%#wI3S=!H+< zjql+b_yoRy@8OM!|2NDsqkFQl*8i{5UTaTjWO2;7b8g&Cx@~uMX55Gv=O)}}roHyt zcJnmtG}qQwiI{SwERdLK#Z;urlH(xm;h2$J6c2Z1gX!XwSyFZ9z6+Gq)oc6S-k#Tf zfbRiXw{r!ROT@>?i$!bVc6<=`~7t}_mcimkhFTkei)>2zt?)5<&@oZ>0lTQi1$>J8n-3%GTe~O0W<4_ zggo$z94|=EYHH?gWE*gqJuiDyTwPLAydEOM)UOLyrQwhTO*Ae|yjJ(mp|0i7pF`}n zSTOhI%n46P*8w{8oR)^;Md@kp1W!Jgx#&s$taLrc;VzioHzgeNv*W|s=1cQ03e(^G4`hG+`DMraOTzRs|E6r`KK{*rF2o!w>dsue z3mii24gC$aL&0p8Ut;*L*#Yms|HK?%X5x*(JHqUGQo^3W^tdEpZy$u&(Ok|Qs4Dxa z<(!l=?n=%v>%QXHCI1ew_>RQU^Qwe?_;z($?gsZte(rWl0>@stkNsotpA`dcNO*_3 z#PaUQCXbz1-d)-7mUmA!?*soSuXSHG_3&A(hq9@)B(Yk{vf-`PifrBz-fBIPO+9?f z#-8D*!JeCv;+`K17x%m>3}-uiA{&ll+*8?b#XUb0CKjLFcTG0^4X^))H*&nMSK(c@ WB;*i>kN+^#y}2{>@&8uWEy*9dZd@?{ literal 0 HcmV?d00001 From 304071cb0abc4d629bcf25aab651b73f87061028 Mon Sep 17 00:00:00 2001 From: Xiao Qi Date: Sat, 22 Oct 2022 00:42:50 +0800 Subject: [PATCH 08/13] Apparently static keyword gives error but it compiles --- SHADE_Engine/src/Resource/SHResourceManager.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SHADE_Engine/src/Resource/SHResourceManager.hpp b/SHADE_Engine/src/Resource/SHResourceManager.hpp index cff4e84b..fb0dcc6a 100644 --- a/SHADE_Engine/src/Resource/SHResourceManager.hpp +++ b/SHADE_Engine/src/Resource/SHResourceManager.hpp @@ -134,7 +134,7 @@ namespace SHADE /* Query Functions */ /*-----------------------------------------------------------------------------------*/ template - std::optional SHResourceManager::GetAssetID(Handle handle) + static std::optional SHResourceManager::GetAssetID(Handle handle) { const Handle GENERIC_HANDLE = Handle(handle); auto [typedHandleMap, typedAssetIdMap] = getAssetHandleMap(); From d4fe63722a480eb18cbd24840a17eb007b695a0d Mon Sep 17 00:00:00 2001 From: Brandon Mak Date: Sun, 23 Oct 2022 15:05:31 +0800 Subject: [PATCH 09/13] WIP (TODO: remember to change commit message) --- Assets/Editor/Layouts/UserLayout.ini | 26 +-- .../Graphics/Commands/SHVkCommandBuffer.cpp | 30 ++- .../src/Graphics/Commands/SHVkCommandBuffer.h | 25 ++- .../Descriptors/SHVkDescriptorSetGroup.cpp | 9 +- .../Descriptors/SHVkDescriptorSetGroup.h | 2 + .../Graphics/MiddleEnd/Batching/SHBatch.cpp | 4 +- .../MiddleEnd/Batching/SHSuperBatch.cpp | 140 ++++++------- .../MiddleEnd/Interface/SHGraphicsSystem.cpp | 33 ++- .../Interface/SHPostOffscreenRenderSystem.cpp | 2 +- .../MiddleEnd/Interface/SHRenderer.cpp | 2 +- .../src/Graphics/Pipeline/SHPipelineType.h | 6 +- .../src/Graphics/Pipeline/SHVkPipeline.cpp | 26 +-- .../src/Graphics/Pipeline/SHVkPipeline.h | 1 + .../Graphics/Pipeline/SHVkPipelineLayout.cpp | 32 +-- .../Graphics/Pipeline/SHVkPipelineLayout.h | 12 +- .../RenderGraph/SHAttachmentDescriptionType.h | 3 +- .../Graphics/RenderGraph/SHRenderGraph.cpp | 71 +++---- .../src/Graphics/RenderGraph/SHRenderGraph.h | 12 +- .../RenderGraph/SHRenderGraphNode.cpp | 82 +++++++- .../Graphics/RenderGraph/SHRenderGraphNode.h | 9 + .../RenderGraph/SHRenderGraphNodeCompute.cpp | 109 ++++++++++ .../RenderGraph/SHRenderGraphNodeCompute.h | 57 +++++ .../RenderGraph/SHRenderGraphResource.cpp | 8 + .../RenderGraph/SHRenderGraphResource.h | 2 + .../RenderGraph/SHRenderGraphStorage.h | 15 +- .../src/Graphics/RenderGraph/SHSubpass.cpp | 194 +++++++++--------- .../src/Graphics/RenderGraph/SHSubpass.h | 7 +- .../Graphics/RenderGraph/SHSubpassCompute.cpp | 53 ----- .../Graphics/RenderGraph/SHSubpassCompute.h | 49 ----- SHADE_Engine/src/Graphics/SHVkUtil.cpp | 15 ++ SHADE_Engine/src/Graphics/SHVkUtil.h | 12 +- TempShaderFolder/GreyscaleCs.glsl | 38 ---- TempShaderFolder/GreyscaleCs.spv | Bin 1400 -> 0 bytes TempShaderFolder/KirschCs.glsl | 167 +++++++++++++++ TempShaderFolder/KirschCs.spv | Bin 0 -> 5900 bytes 35 files changed, 788 insertions(+), 465 deletions(-) create mode 100644 SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNodeCompute.cpp create mode 100644 SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNodeCompute.h delete mode 100644 SHADE_Engine/src/Graphics/RenderGraph/SHSubpassCompute.cpp delete mode 100644 SHADE_Engine/src/Graphics/RenderGraph/SHSubpassCompute.h delete mode 100644 TempShaderFolder/GreyscaleCs.glsl delete mode 100644 TempShaderFolder/GreyscaleCs.spv create mode 100644 TempShaderFolder/KirschCs.glsl create mode 100644 TempShaderFolder/KirschCs.spv diff --git a/Assets/Editor/Layouts/UserLayout.ini b/Assets/Editor/Layouts/UserLayout.ini index 530ee770..005c3556 100644 --- a/Assets/Editor/Layouts/UserLayout.ini +++ b/Assets/Editor/Layouts/UserLayout.ini @@ -1,16 +1,16 @@ [Window][MainStatusBar] -Pos=0,1060 -Size=1920,20 +Pos=0,1367 +Size=3440,20 Collapsed=0 [Window][SHEditorMenuBar] Pos=0,48 -Size=1920,1012 +Size=3440,1319 Collapsed=0 [Window][Hierarchy Panel] -Pos=0,142 -Size=571,918 +Pos=0,170 +Size=646,1197 Collapsed=0 DockId=0x00000004,0 @@ -20,29 +20,29 @@ Size=400,400 Collapsed=0 [Window][Inspector] -Pos=1649,48 -Size=271,1012 +Pos=3169,48 +Size=271,1319 Collapsed=0 DockId=0x00000006,0 [Window][Profiler] Pos=0,48 -Size=571,92 +Size=646,120 Collapsed=0 DockId=0x00000003,0 [Window][Viewport] -Pos=573,48 -Size=1074,1012 +Pos=648,48 +Size=2519,1319 Collapsed=0 DockId=0x00000002,0 [Docking][Data] -DockSpace ID=0xC5C9B8AB Window=0xBE4044E9 Pos=8,79 Size=1920,1012 Split=X +DockSpace ID=0xC5C9B8AB Window=0xBE4044E9 Pos=0,71 Size=3440,1319 Split=X DockNode ID=0x00000005 Parent=0xC5C9B8AB SizeRef=1992,1036 Split=X - DockNode ID=0x00000001 Parent=0x00000005 SizeRef=571,1036 Split=Y Selected=0x1E6EB881 + DockNode ID=0x00000001 Parent=0x00000005 SizeRef=646,1036 Split=Y Selected=0x1E6EB881 DockNode ID=0x00000003 Parent=0x00000001 SizeRef=225,94 Selected=0x1E6EB881 DockNode ID=0x00000004 Parent=0x00000001 SizeRef=225,940 Selected=0xE096E5AE - DockNode ID=0x00000002 Parent=0x00000005 SizeRef=1074,1036 CentralNode=1 Selected=0x13926F0B + DockNode ID=0x00000002 Parent=0x00000005 SizeRef=999,1036 CentralNode=1 Selected=0x13926F0B DockNode ID=0x00000006 Parent=0xC5C9B8AB SizeRef=271,1036 Selected=0xE7039252 diff --git a/SHADE_Engine/src/Graphics/Commands/SHVkCommandBuffer.cpp b/SHADE_Engine/src/Graphics/Commands/SHVkCommandBuffer.cpp index 4501ba7b..a744c795 100644 --- a/SHADE_Engine/src/Graphics/Commands/SHVkCommandBuffer.cpp +++ b/SHADE_Engine/src/Graphics/Commands/SHVkCommandBuffer.cpp @@ -10,6 +10,7 @@ #include "Graphics/Buffers/SHVkBuffer.h" #include "Graphics/Images/SHVkImage.h" #include "Graphics/Descriptors/SHVkDescriptorSetGroup.h" +#include "Graphics/SHVkUtil.h" namespace SHADE @@ -299,7 +300,7 @@ namespace SHADE SHLOG_ERROR("Command buffer must have started recording before a pipeline can be bound. "); return; } - boundPipelineLayoutHdl = pipelineHdl->GetPipelineLayout(); + bindPointData[static_cast(pipelineHdl->GetPipelineType())].boundPipelineLayoutHdl = pipelineHdl->GetPipelineLayout(); vkCommandBuffer.bindPipeline(pipelineHdl->GetPipelineBindPoint(), pipelineHdl->GetVkPipeline()); } @@ -358,9 +359,10 @@ namespace SHADE } } - void SHVkCommandBuffer::BindDescriptorSet(Handle descSetGroup, vk::PipelineBindPoint bindPoint, uint32_t firstSet, std::span dynamicOffsets) + void SHVkCommandBuffer::BindDescriptorSet(Handle descSetGroup, SH_PIPELINE_TYPE bindPoint, uint32_t firstSet, std::span dynamicOffsets) { - vkCommandBuffer.bindDescriptorSets(bindPoint, boundPipelineLayoutHdl->GetVkPipelineLayout(), firstSet, descSetGroup->GetVkHandle(), dynamicOffsets); + uint32_t bindPointIndex = static_cast(bindPoint); + vkCommandBuffer.bindDescriptorSets(SHVkUtil::GetPipelineBindPointFromType(bindPoint), bindPointData[bindPointIndex].boundPipelineLayoutHdl->GetVkPipelineLayout(), firstSet, descSetGroup->GetVkHandle(), dynamicOffsets); } /***************************************************************************/ @@ -452,6 +454,11 @@ namespace SHADE vkCommandBuffer.drawIndexedIndirect(indirectDrawData->GetVkBuffer(), 0, drawCount, sizeof(vk::DrawIndexedIndirectCommand)); } + void SHVkCommandBuffer::ComputeDispatch(uint32_t groupCountX, uint32_t groupCountY, uint32_t groupCountZ) noexcept + { + vkCommandBuffer.dispatch (groupCountX, groupCountY, groupCountZ); + } + void SHVkCommandBuffer::CopyBufferToImage(const vk::Buffer& src, const vk::Image& dst, const std::vector& copyInfo) { vkCommandBuffer.copyBufferToImage @@ -500,9 +507,9 @@ namespace SHADE // //vkCommandBuffer.pipelineBarrier() //} - void SHVkCommandBuffer::ForceSetPipelineLayout(Handle pipelineLayout) noexcept + void SHVkCommandBuffer::ForceSetPipelineLayout(Handle pipelineLayout, SH_PIPELINE_TYPE pipelineType) noexcept { - boundPipelineLayoutHdl = pipelineLayout; + bindPointData[static_cast(pipelineType)].boundPipelineLayoutHdl = pipelineLayout; } /***************************************************************************/ @@ -513,12 +520,13 @@ namespace SHADE */ /***************************************************************************/ - void SHVkCommandBuffer::SubmitPushConstants(void) const noexcept + void SHVkCommandBuffer::SubmitPushConstants(SH_PIPELINE_TYPE bindPoint) const noexcept { - vkCommandBuffer.pushConstants(boundPipelineLayoutHdl->GetVkPipelineLayout(), - boundPipelineLayoutHdl->GetPushConstantInterface().GetShaderStageFlags(), + auto layoutHdl = bindPointData[static_cast(bindPoint)].boundPipelineLayoutHdl; + vkCommandBuffer.pushConstants(layoutHdl->GetVkPipelineLayout(), + layoutHdl->GetPushConstantInterface().GetShaderStageFlags(), 0, - boundPipelineLayoutHdl->GetPushConstantInterface().GetSize(), pushConstantData); + layoutHdl->GetPushConstantInterface().GetSize(), pushConstantData); } /***************************************************************************/ @@ -695,7 +703,7 @@ namespace SHADE , usageFlags{ rhs.usageFlags } , commandBufferCount{ rhs.commandBufferCount } , parentPool{ rhs.parentPool } - , boundPipelineLayoutHdl{ rhs.boundPipelineLayoutHdl } + , bindPointData{ std::move (rhs.bindPointData)} { memcpy(pushConstantData, rhs.pushConstantData, PUSH_CONSTANT_SIZE); @@ -728,7 +736,7 @@ namespace SHADE usageFlags = rhs.usageFlags; commandBufferCount = rhs.commandBufferCount; parentPool = rhs.parentPool; - boundPipelineLayoutHdl = rhs.boundPipelineLayoutHdl; + bindPointData = std::move(rhs.bindPointData); memcpy(pushConstantData, rhs.pushConstantData, PUSH_CONSTANT_SIZE); rhs.vkCommandBuffer = VK_NULL_HANDLE; diff --git a/SHADE_Engine/src/Graphics/Commands/SHVkCommandBuffer.h b/SHADE_Engine/src/Graphics/Commands/SHVkCommandBuffer.h index 9416a1aa..70a209ee 100644 --- a/SHADE_Engine/src/Graphics/Commands/SHVkCommandBuffer.h +++ b/SHADE_Engine/src/Graphics/Commands/SHVkCommandBuffer.h @@ -6,6 +6,7 @@ #include "SHCommandPoolResetMode.h" #include "Resource/ResourceLibrary.h" #include "Graphics/Pipeline/SHVkPipelineLayout.h" +#include "Graphics/Pipeline/SHPipelineType.h" namespace SHADE { @@ -39,7 +40,14 @@ namespace SHADE friend class ResourceLibrary; static constexpr uint16_t PUSH_CONSTANT_SIZE = 512; + private: + struct PipelineBindPointData + { + //! The currently bound pipeline + Handle boundPipelineLayoutHdl; + }; + /*-----------------------------------------------------------------------*/ /* PRIVATE MEMBER VARIABLES */ /*-----------------------------------------------------------------------*/ @@ -66,8 +74,8 @@ namespace SHADE //! The command pool that this command buffer belongs to Handle parentPool; - //! The currently bound pipeline - Handle boundPipelineLayoutHdl; + //! Every command buffer will have a set of pipeline bind point specific data + std::array(SH_PIPELINE_TYPE::NUM_TYPES)> bindPointData; //! The push constant data for the command buffer uint8_t pushConstantData[PUSH_CONSTANT_SIZE]; @@ -112,13 +120,16 @@ namespace SHADE void BindPipeline (Handle const& pipelineHdl) noexcept; void BindVertexBuffer (uint32_t bindingPoint, Handle const& buffer, vk::DeviceSize offset) noexcept; void BindIndexBuffer (Handle const& buffer, uint32_t startingIndex) const noexcept; - void BindDescriptorSet (Handle descSetGroup, vk::PipelineBindPoint bindPoint, uint32_t firstSet, std::span dynamicOffsets); + void BindDescriptorSet (Handle descSetGroup, SH_PIPELINE_TYPE bindPoint, uint32_t firstSet, std::span dynamicOffsets); // Draw Commands void DrawArrays (uint32_t vertexCount, uint32_t instanceCount, uint32_t firstVertex, uint32_t firstInstance) const noexcept; void DrawIndexed (uint32_t indexCount, uint32_t firstIndex, uint32_t vertexOffset) const noexcept; void DrawMultiIndirect (Handle indirectDrawData, uint32_t drawCount); + // Compute Commands + void ComputeDispatch (uint32_t groupCountX, uint32_t groupCountY, uint32_t groupCountZ) noexcept; + // Buffer Copy void CopyBufferToImage (const vk::Buffer& src, const vk::Image& dst, const std::vector& copyInfo); void CopyImageToBuffer (const vk::Image& src, const vk::Buffer& dst, const std::vector& copyInfo); @@ -138,13 +149,13 @@ namespace SHADE // Push Constant variable setting template - void SetPushConstantVariable(std::string variableName, T const& data) noexcept + void SetPushConstantVariable(std::string variableName, T const& data, SH_PIPELINE_TYPE bindPoint) noexcept { - memcpy (static_cast(pushConstantData) + boundPipelineLayoutHdl->GetPushConstantInterface().GetOffset(variableName), &data, sizeof (T)); + memcpy (static_cast(pushConstantData) + bindPointData[static_cast(bindPoint)].boundPipelineLayoutHdl->GetPushConstantInterface().GetOffset(variableName), &data, sizeof (T)); }; - void ForceSetPipelineLayout (Handle pipelineLayout) noexcept; + void ForceSetPipelineLayout (Handle pipelineLayout, SH_PIPELINE_TYPE pipelineType) noexcept; - void SubmitPushConstants (void) const noexcept; + void SubmitPushConstants (SH_PIPELINE_TYPE bindPoint) const noexcept; /*-----------------------------------------------------------------------*/ /* GETTERS AND SETTERS */ diff --git a/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorSetGroup.cpp b/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorSetGroup.cpp index ea859718..de68c583 100644 --- a/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorSetGroup.cpp +++ b/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorSetGroup.cpp @@ -91,7 +91,7 @@ namespace SHADE // new write for the binding updater.writeInfos.emplace_back(); - updater.writeHashMap.try_emplace(writeHash, updater.writeInfos.size() - 1); + updater.writeHashMap.try_emplace(writeHash, static_cast(updater.writeInfos.size()) - 1u); auto& writeInfo = updater.writeInfos.back(); // Descriptor count for the write descriptor set. Usually this is set to 1, but if binding is variable sized, set to info passed in @@ -102,10 +102,10 @@ namespace SHADE //case vk::DescriptorType::eSampler: //case vk::DescriptorType::eSampledImage: case vk::DescriptorType::eCombinedImageSampler: + case vk::DescriptorType::eStorageImage: + case vk::DescriptorType::eInputAttachment: writeInfo.descImageInfos.resize(descriptorCount); - break; - //case vk::DescriptorType::eStorageImage: - // break; + break; case vk::DescriptorType::eUniformTexelBuffer: case vk::DescriptorType::eStorageTexelBuffer: case vk::DescriptorType::eUniformBuffer: @@ -165,6 +165,7 @@ namespace SHADE if (imageViewsAndSamplers.size() > writeInfo.descImageInfos.size()) { SHLOG_ERROR("Attempting write too many descriptors into descriptor set. Failed to write to vk::WriteDescriptorSet. "); + return; } for (uint32_t i = 0; i < imageViewsAndSamplers.size(); ++i) diff --git a/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorSetGroup.h b/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorSetGroup.h index f2b886e8..85c3ef97 100644 --- a/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorSetGroup.h +++ b/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorSetGroup.h @@ -31,6 +31,8 @@ namespace SHADE class SHVkDescriptorSetGroup { public: + using viewSamplerLayout = std::tuple, Handle, vk::ImageLayout>; + /*-----------------------------------------------------------------------------*/ /* Constructor/Destructors */ /*-----------------------------------------------------------------------------*/ diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.cpp index 2705b4d1..40826047 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.cpp @@ -369,7 +369,7 @@ namespace SHADE /*---------------------------------------------------------------------------------*/ void SHBatch::Draw(Handle cmdBuffer, uint32_t frameIndex) { - if (frameIndex >= SHGraphicsConstants::NUM_FRAME_BUFFERS) + if (frameIndex >= SHGraphicsConstants::NUM_FRAME_BUFFERS) { SHLOG_WARNING("[SHBatch] Attempted to draw a batch with an invalid frame index."); return; @@ -385,7 +385,7 @@ namespace SHADE cmdBuffer->BindDescriptorSet ( matPropsDescSet[frameIndex], - vk::PipelineBindPoint::eGraphics, + SH_PIPELINE_TYPE::GRAPHICS, SHGraphicsConstants::DescriptorSetIndex::PER_INSTANCE, dynamicOffset ); diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHSuperBatch.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHSuperBatch.cpp index add51196..14f2aa76 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHSuperBatch.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHSuperBatch.cpp @@ -20,91 +20,91 @@ of DigiPen Institute of Technology is prohibited. namespace SHADE { - /*---------------------------------------------------------------------------------*/ - /* Constructor/Destructors */ - /*---------------------------------------------------------------------------------*/ + /*---------------------------------------------------------------------------------*/ + /* Constructor/Destructors */ + /*---------------------------------------------------------------------------------*/ - SHSuperBatch::SHSuperBatch(Handle sp) - : subpass { sp } - {} + SHSuperBatch::SHSuperBatch(Handle sp) + : subpass{ sp } + {} - /*---------------------------------------------------------------------------------*/ - /* Usage Functions */ - /*---------------------------------------------------------------------------------*/ - void SHSuperBatch::Add(const SHRenderable* renderable) noexcept + /*---------------------------------------------------------------------------------*/ + /* Usage Functions */ + /*---------------------------------------------------------------------------------*/ + void SHSuperBatch::Add(const SHRenderable* renderable) noexcept + { + const Handle PIPELINE = renderable->GetMaterial()->GetBaseMaterial()->GetPipeline(); + + // Check if we have a batch with the same pipeline first + auto batch = std::find_if(batches.begin(), batches.end(), [&](const SHBatch& batch) + { + return batch.GetPipeline() == PIPELINE; + }); + + + // Create one if not found + if (batch == batches.end()) { - const Handle PIPELINE = renderable->GetMaterial()->GetBaseMaterial()->GetPipeline(); - - // Check if we have a batch with the same pipeline first - auto batch = std::find_if(batches.begin(), batches.end(), [&](const SHBatch& batch) - { - return batch.GetPipeline() == PIPELINE; - }); - - - // Create one if not found - if (batch == batches.end()) - { - batches.emplace_back(PIPELINE); - batch = batches.end() - 1; - } - - // Add renderable in - batch->Add(renderable); + batches.emplace_back(PIPELINE); + batch = batches.end() - 1; } - void SHSuperBatch::Remove(const SHRenderable* renderable) noexcept + // Add renderable in + batch->Add(renderable); + } + + void SHSuperBatch::Remove(const SHRenderable* renderable) noexcept + { + const Handle PIPELINE = renderable->GetMaterial()->GetBaseMaterial()->GetPipeline(); + + // Check if we have a Batch with the same pipeline yet + auto batch = std::find_if(batches.begin(), batches.end(), [&](const SHBatch& batch) + { + return batch.GetPipeline() == PIPELINE; + }); + + // Attempt to remove if it exists + if (batch == batches.end()) + return; + + batch->Remove(renderable); + } + + void SHSuperBatch::Clear() noexcept + { + for (auto& batch : batches) { - const Handle PIPELINE = renderable->GetMaterial()->GetBaseMaterial()->GetPipeline(); - - // Check if we have a Batch with the same pipeline yet - auto batch = std::find_if(batches.begin(), batches.end(), [&](const SHBatch& batch) - { - return batch.GetPipeline() == PIPELINE; - }); - - // Attempt to remove if it exists - if (batch == batches.end()) - return; - - batch->Remove(renderable); + batch.Clear(); } + batches.clear(); + } - void SHSuperBatch::Clear() noexcept + void SHSuperBatch::UpdateBuffers(uint32_t frameIndex, Handle descPool) + { + for (auto& batch : batches) { - for (auto& batch : batches) - { - batch.Clear(); - } - batches.clear(); + batch.UpdateMaterialBuffer(frameIndex, descPool); + batch.UpdateTransformBuffer(frameIndex); + batch.UpdateEIDBuffer(frameIndex); } + } - void SHSuperBatch::UpdateBuffers(uint32_t frameIndex, Handle descPool) + void SHSuperBatch::Build(Handle device, Handle descPool, uint32_t frameIndex) noexcept + { + // Build all batches + for (auto& batch : batches) { - for (auto& batch : batches) - { - batch.UpdateMaterialBuffer(frameIndex, descPool); - batch.UpdateTransformBuffer(frameIndex); - batch.UpdateEIDBuffer(frameIndex); - } + batch.Build(device, descPool, frameIndex); } + } - void SHSuperBatch::Build(Handle device, Handle descPool, uint32_t frameIndex) noexcept + void SHSuperBatch::Draw(Handle cmdBuffer, uint32_t frameIndex) noexcept + { + // Build all batches + for (auto& batch : batches) { - // Build all batches - for (auto& batch : batches) - { - batch.Build(device, descPool, frameIndex); - } - } - - void SHSuperBatch::Draw(Handle cmdBuffer, uint32_t frameIndex) noexcept - { - // Build all batches - for (auto& batch : batches) - { - batch.Draw(cmdBuffer, frameIndex); - } + batch.Draw(cmdBuffer, frameIndex); } + } } diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp index 386cef54..992cbdf1 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp @@ -123,12 +123,12 @@ namespace SHADE shaderSourceLibrary.LoadShader(0, "TestCubeVs.glsl", SH_SHADER_TYPE::VERTEX, true); shaderSourceLibrary.LoadShader(1, "TestCubeFs.glsl", SH_SHADER_TYPE::FRAGMENT, true); - shaderSourceLibrary.LoadShader(2, "GreyscaleCs.glsl", SH_SHADER_TYPE::COMPUTE, true); + shaderSourceLibrary.LoadShader(2, "KirschCs.glsl", SH_SHADER_TYPE::COMPUTE, true); shaderModuleLibrary.ImportFromSourceLibrary(device, shaderSourceLibrary); auto cubeVS = shaderModuleLibrary.GetShaderModule("TestCubeVs.glsl"); auto cubeFS = shaderModuleLibrary.GetShaderModule("TestCubeFs.glsl"); - auto greyscale = shaderModuleLibrary.GetShaderModule("GreyscaleCs.glsl"); + auto greyscale = shaderModuleLibrary.GetShaderModule("KirschCs.glsl"); cubeVS->Reflect(); cubeFS->Reflect(); greyscale->Reflect(); @@ -171,28 +171,25 @@ namespace SHADE // Initialize world render graph worldRenderGraph->Init(device, swapchain); - worldRenderGraph->AddResource("Scene", { SH_ATT_DESC_TYPE_FLAGS::COLOR, SH_ATT_DESC_TYPE_FLAGS::INPUT }, windowDims.first, windowDims.second); + worldRenderGraph->AddResource("Scene Pre Postprocess", { SH_ATT_DESC_TYPE_FLAGS::COLOR, SH_ATT_DESC_TYPE_FLAGS::INPUT, SH_ATT_DESC_TYPE_FLAGS::STORAGE }, windowDims.first, windowDims.second); + worldRenderGraph->AddResource("Scene", { SH_ATT_DESC_TYPE_FLAGS::COLOR, SH_ATT_DESC_TYPE_FLAGS::INPUT, SH_ATT_DESC_TYPE_FLAGS::STORAGE }, windowDims.first, windowDims.second); worldRenderGraph->AddResource("Depth Buffer", { SH_ATT_DESC_TYPE_FLAGS::DEPTH_STENCIL }, windowDims.first, windowDims.second, vk::Format::eD32SfloatS8Uint); worldRenderGraph->AddResource("Entity ID", { SH_ATT_DESC_TYPE_FLAGS::COLOR }, windowDims.first, windowDims.second, vk::Format::eR32Uint, 1, vk::ImageUsageFlagBits::eTransferSrc); - auto node = worldRenderGraph->AddNode("G-Buffer", { "Entity ID", "Depth Buffer", "Scene"}, {}); // no predecessors + auto node = worldRenderGraph->AddNode("G-Buffer", { "Entity ID", "Depth Buffer", "Scene", "Scene Pre Postprocess"}, {}); // no predecessors //First subpass to write to G-Buffer auto gBufferWriteSubpass = node->AddSubpass("G-Buffer Write"); - gBufferWriteSubpass->AddColorOutput("Scene"); + gBufferWriteSubpass->AddColorOutput("Scene Pre Postprocess"); gBufferWriteSubpass->AddColorOutput("Entity ID"); gBufferWriteSubpass->AddDepthOutput("Depth Buffer", SH_ATT_DESC_TYPE_FLAGS::DEPTH_STENCIL); - auto greyscale = shaderModuleLibrary.GetShaderModule("GreyscaleCs.glsl"); - - auto greyscaleSubpass = node->AddSubpass("Greyscale Subpass"); - greyscaleSubpass->AddGeneralInput("Scene"); - greyscaleSubpass->AddSubpassCompute(greyscale); - - // We do this to just transition our scene layout to shader read - auto sceneLayoutTransitionSubpass = node->AddSubpass("Scene Layout Transition"); - sceneLayoutTransitionSubpass->AddInput("Scene"); + //auto sceneLayoutTransitionSubpass = node->AddSubpass("Scene Layout Transition"); + //sceneLayoutTransitionSubpass->AddGeneralInput("Scene"); + + auto greyscale = shaderModuleLibrary.GetShaderModule("KirschCs.glsl"); + node->AddNodeCompute (greyscale, {"Scene Pre Postprocess", "Scene"}); // Generate world render graph worldRenderGraph->Generate(); @@ -375,7 +372,7 @@ namespace SHADE uint32_t h = static_cast(viewports[vpIndex]->GetHeight()); currentCmdBuffer->SetViewportScissor (static_cast(w), static_cast(h), w, h); - currentCmdBuffer->ForceSetPipelineLayout(SHGraphicsGlobalData::GetDummyPipelineLayout()); + currentCmdBuffer->ForceSetPipelineLayout(SHGraphicsGlobalData::GetDummyPipelineLayout(), SH_PIPELINE_TYPE::GRAPHICS); // Bind all the buffers required for meshes for (auto& [buffer, bindingPoint] : MESH_DATA) @@ -395,7 +392,7 @@ namespace SHADE currentCmdBuffer->BindDescriptorSet ( textureDescSet, - vk::PipelineBindPoint::eGraphics, + SH_PIPELINE_TYPE::GRAPHICS, 0, texDynamicOffset ); @@ -741,8 +738,8 @@ namespace SHADE auto cameraSystem = SHSystemManager::GetSystem(); #ifdef SHEDITOR - cameraSystem->GetEditorCamera()->SetWidth(resizeWidth); - cameraSystem->GetEditorCamera()->SetHeight(resizeHeight); + cameraSystem->GetEditorCamera()->SetWidth(static_cast(resizeWidth)); + cameraSystem->GetEditorCamera()->SetHeight(static_cast(resizeHeight)); #else #endif diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHPostOffscreenRenderSystem.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHPostOffscreenRenderSystem.cpp index 8b41a979..ebce5c9e 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHPostOffscreenRenderSystem.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHPostOffscreenRenderSystem.cpp @@ -68,7 +68,7 @@ namespace SHADE { std::vector combinedImageSampler { - std::make_tuple(offscreenRender->GetImageView(), offscreenRenderSampler, vk::ImageLayout::eShaderReadOnlyOptimal), + std::make_tuple(offscreenRender->GetImageView(), offscreenRenderSampler, vk::ImageLayout::eGeneral), }; // Register the image view and sampler with the descriptor set. Now whenever rendering to the offscreen image is done, the descriptor set will see the change diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderer.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderer.cpp index 2532f308..a1806ccd 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderer.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderer.cpp @@ -82,7 +82,7 @@ namespace SHADE std::array dynamicOffsets{ frameIndex * cameraDataAlignedSize }; - cmdBuffer->BindDescriptorSet(cameraDescriptorSet, vk::PipelineBindPoint::eGraphics, SHGraphicsConstants::DescriptorSetIndex::HIGH_FREQUENCY_GLOBALS, std::span{ dynamicOffsets.data(), 1 }); + cmdBuffer->BindDescriptorSet(cameraDescriptorSet, SH_PIPELINE_TYPE::GRAPHICS, SHGraphicsConstants::DescriptorSetIndex::HIGH_FREQUENCY_GLOBALS, std::span{ dynamicOffsets.data(), 1 }); } } diff --git a/SHADE_Engine/src/Graphics/Pipeline/SHPipelineType.h b/SHADE_Engine/src/Graphics/Pipeline/SHPipelineType.h index e7f5b6a8..2c1c80ff 100644 --- a/SHADE_Engine/src/Graphics/Pipeline/SHPipelineType.h +++ b/SHADE_Engine/src/Graphics/Pipeline/SHPipelineType.h @@ -5,9 +5,13 @@ namespace SHADE { enum class SH_PIPELINE_TYPE { - GRAPHICS, + GRAPHICS = 0, COMPUTE, + RAY_TRACING, + NUM_TYPES, }; + + } #endif \ No newline at end of file diff --git a/SHADE_Engine/src/Graphics/Pipeline/SHVkPipeline.cpp b/SHADE_Engine/src/Graphics/Pipeline/SHVkPipeline.cpp index 973218d1..973ae72f 100644 --- a/SHADE_Engine/src/Graphics/Pipeline/SHVkPipeline.cpp +++ b/SHADE_Engine/src/Graphics/Pipeline/SHVkPipeline.cpp @@ -4,6 +4,7 @@ #include "Graphics/Shaders/SHVkShaderModule.h" #include "Graphics/Debugging/SHVulkanDebugUtil.h" #include "Graphics/RenderGraph/SHRenderGraph.h" +#include "Graphics/SHVkUtil.h" namespace SHADE { @@ -268,7 +269,7 @@ namespace SHADE , logicalDeviceHdl{ rhs.logicalDeviceHdl } , pipelineLayout { rhs.pipelineLayout } { - vkPipeline = VK_NULL_HANDLE; + rhs.vkPipeline = VK_NULL_HANDLE; } /***************************************************************************/ @@ -308,7 +309,8 @@ namespace SHADE /***************************************************************************/ SHVkPipeline::~SHVkPipeline(void) noexcept { - logicalDeviceHdl->GetVkLogicalDevice().destroyPipeline(vkPipeline, nullptr); + if (vkPipeline) + logicalDeviceHdl->GetVkLogicalDevice().destroyPipeline(vkPipeline, nullptr); } /***************************************************************************/ @@ -336,7 +338,7 @@ namespace SHADE created = rhs.created; logicalDeviceHdl = rhs.logicalDeviceHdl; - vkPipeline = VK_NULL_HANDLE; + rhs.vkPipeline = VK_NULL_HANDLE; return *this; } @@ -422,18 +424,7 @@ namespace SHADE /***************************************************************************/ vk::PipelineBindPoint SHVkPipeline::GetPipelineBindPoint(void) const noexcept { - switch (pipelineType) - { - case SH_PIPELINE_TYPE::GRAPHICS: - return vk::PipelineBindPoint::eGraphics; - case SH_PIPELINE_TYPE::COMPUTE: - return vk::PipelineBindPoint::eCompute; - break; - default: - return vk::PipelineBindPoint::eGraphics; - break; - - } + return SHVkUtil::GetPipelineBindPointFromType(pipelineType); } /***************************************************************************/ @@ -473,4 +464,9 @@ namespace SHADE return pipelineLayout; } + SH_PIPELINE_TYPE SHVkPipeline::GetPipelineType(void) const noexcept + { + return pipelineType; + } + } \ No newline at end of file diff --git a/SHADE_Engine/src/Graphics/Pipeline/SHVkPipeline.h b/SHADE_Engine/src/Graphics/Pipeline/SHVkPipeline.h index fe55a41e..9ec18650 100644 --- a/SHADE_Engine/src/Graphics/Pipeline/SHVkPipeline.h +++ b/SHADE_Engine/src/Graphics/Pipeline/SHVkPipeline.h @@ -77,6 +77,7 @@ namespace SHADE vk::Pipeline GetVkPipeline (void) const noexcept; bool GetIsCreated (void) const noexcept; Handle GetPipelineLayout (void) const noexcept; + SH_PIPELINE_TYPE GetPipelineType (void) const noexcept; }; } diff --git a/SHADE_Engine/src/Graphics/Pipeline/SHVkPipelineLayout.cpp b/SHADE_Engine/src/Graphics/Pipeline/SHVkPipelineLayout.cpp index 7a76447d..37d00795 100644 --- a/SHADE_Engine/src/Graphics/Pipeline/SHVkPipelineLayout.cpp +++ b/SHADE_Engine/src/Graphics/Pipeline/SHVkPipelineLayout.cpp @@ -216,9 +216,18 @@ namespace SHADE /***************************************************************************/ void SHVkPipelineLayout::PrepareVkDescriptorSetLayouts(void) noexcept { + // pipeline layouts contain global layouts first, then layouts for allocation descriptorSetLayoutsPipeline.reserve(descriptorSetLayoutsAllocate.size() + descriptorSetLayoutsGlobal.size()); + vkDescriptorSetLayoutsPipeline.reserve(descriptorSetLayoutsAllocate.size() + descriptorSetLayoutsGlobal.size()); - // Settle allocate layouts first + // First we insert the global layouts + for (auto const& layout : descriptorSetLayoutsGlobal) + { + descriptorSetLayoutsPipeline.emplace_back(layout); + //vkDescriptorSetLayoutsPipeline.emplace_back(layout->GetVkHandle()); + } + + // Then the allocate layouts vkDescriptorSetLayoutsAllocate.reserve(descriptorSetLayoutsAllocate.size()); for (auto const& layout : descriptorSetLayoutsAllocate) { @@ -226,18 +235,13 @@ namespace SHADE vkDescriptorSetLayoutsAllocate.emplace_back(layout->GetVkHandle()); } - // pipeline layouts contain global layouts first, then layouts for allocation - vkDescriptorSetLayoutsPipeline.reserve(descriptorSetLayoutsAllocate.size() + descriptorSetLayoutsGlobal.size()); - - // First we insert the global layouts - for (auto const& layout : descriptorSetLayoutsGlobal) + for (auto const& layout : descriptorSetLayoutsPipeline) { - descriptorSetLayoutsPipeline.emplace_back(layout); vkDescriptorSetLayoutsPipeline.emplace_back(layout->GetVkHandle()); } // 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)); } /***************************************************************************/ @@ -294,6 +298,7 @@ namespace SHADE , descriptorSetLayoutsGlobal{pipelineLayoutParams.globalDescSetLayouts } // do a copy, some other pipeline layout might need this , descriptorSetLayoutsAllocate{} , vkDescriptorSetLayoutsAllocate{} + , descriptorSetLayoutsPipeline{} , vkDescriptorSetLayoutsPipeline{} { for (auto& mod : shaderModules) @@ -318,6 +323,7 @@ namespace SHADE , descriptorSetLayoutsGlobal{} , descriptorSetLayoutsAllocate{} , vkDescriptorSetLayoutsAllocate{} + , descriptorSetLayoutsPipeline{} , vkDescriptorSetLayoutsPipeline{} { @@ -368,7 +374,8 @@ namespace SHADE , descriptorSetLayoutsGlobal {std::move (rhs.descriptorSetLayoutsGlobal)} , descriptorSetLayoutsAllocate {std::move (rhs.descriptorSetLayoutsAllocate)} , vkDescriptorSetLayoutsAllocate{std::move (rhs.vkDescriptorSetLayoutsAllocate)} - , vkDescriptorSetLayoutsPipeline{std::move (rhs.vkDescriptorSetLayoutsAllocate)} + , descriptorSetLayoutsPipeline { std::move(rhs.descriptorSetLayoutsPipeline) } + , vkDescriptorSetLayoutsPipeline{ std::move(rhs.vkDescriptorSetLayoutsPipeline) } { rhs.vkPipelineLayout = VK_NULL_HANDLE; } @@ -441,12 +448,12 @@ namespace SHADE return {}; } - std::vector> SHVkPipelineLayout::GetDescriptorSetLayoutsPipeline(void) const noexcept + std::vector> const& SHVkPipelineLayout::GetDescriptorSetLayoutsPipeline(void) const noexcept { return descriptorSetLayoutsPipeline; } - std::vector> SHVkPipelineLayout::GetDescriptorSetLayoutsAllocate(void) const noexcept + std::vector> const& SHVkPipelineLayout::GetDescriptorSetLayoutsAllocate(void) const noexcept { return descriptorSetLayoutsAllocate; } @@ -464,7 +471,8 @@ namespace SHADE descriptorSetLayoutsGlobal = std::move(rhs.descriptorSetLayoutsGlobal); descriptorSetLayoutsAllocate = std::move(rhs.descriptorSetLayoutsAllocate); vkDescriptorSetLayoutsAllocate = std::move(rhs.vkDescriptorSetLayoutsAllocate); - vkDescriptorSetLayoutsPipeline = std::move(rhs.vkDescriptorSetLayoutsAllocate); + descriptorSetLayoutsPipeline = std::move(rhs.descriptorSetLayoutsPipeline); + vkDescriptorSetLayoutsPipeline = std::move(rhs.vkDescriptorSetLayoutsPipeline); rhs.vkPipelineLayout = VK_NULL_HANDLE; diff --git a/SHADE_Engine/src/Graphics/Pipeline/SHVkPipelineLayout.h b/SHADE_Engine/src/Graphics/Pipeline/SHVkPipelineLayout.h index f5d363fa..b4298e00 100644 --- a/SHADE_Engine/src/Graphics/Pipeline/SHVkPipelineLayout.h +++ b/SHADE_Engine/src/Graphics/Pipeline/SHVkPipelineLayout.h @@ -74,12 +74,12 @@ namespace SHADE /*-----------------------------------------------------------------------*/ /* SETTERS AND GETTERS */ /*-----------------------------------------------------------------------*/ - std::vector> const& GetShaderModules (void) const noexcept; - vk::PipelineLayout GetVkPipelineLayout (void) const noexcept; - SHPushConstantInterface const& GetPushConstantInterface (void) const noexcept; - Handle GetShaderBlockInterface (uint32_t set, uint32_t binding, vk::ShaderStageFlagBits shaderStage) const noexcept; - std::vector> GetDescriptorSetLayoutsPipeline(void) const noexcept; - std::vector> GetDescriptorSetLayoutsAllocate(void) const noexcept; + std::vector> const& GetShaderModules (void) const noexcept; + vk::PipelineLayout GetVkPipelineLayout (void) const noexcept; + SHPushConstantInterface const& GetPushConstantInterface (void) const noexcept; + Handle GetShaderBlockInterface (uint32_t set, uint32_t binding, vk::ShaderStageFlagBits shaderStage) const noexcept; + std::vector> const& GetDescriptorSetLayoutsPipeline(void) const noexcept; + std::vector> const& GetDescriptorSetLayoutsAllocate(void) const noexcept; }; } diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHAttachmentDescriptionType.h b/SHADE_Engine/src/Graphics/RenderGraph/SHAttachmentDescriptionType.h index efd3fb0f..c4d44ea8 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHAttachmentDescriptionType.h +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHAttachmentDescriptionType.h @@ -10,7 +10,8 @@ namespace SHADE DEPTH = 0x04, STENCIL = 0x08, DEPTH_STENCIL = 0x10, - INPUT = 0x20 + INPUT = 0x20, + STORAGE = 0x40 }; } diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp index df588c05..1c0798f1 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp @@ -10,7 +10,7 @@ #include "Tools/SHLogger.h" #include "SHAttachmentDescInitParams.h" #include "SHRenderGraphStorage.h" -#include "Graphics/RenderGraph/SHSubpassCompute.h" +#include "Graphics/RenderGraph/SHRenderGraphNodeCompute.h" namespace SHADE { @@ -59,7 +59,7 @@ namespace SHADE format = renderGraphStorage->swapchain->GetSurfaceFormatKHR().format; } - graphResources.try_emplace(resourceName, resourceManager->Create(renderGraphStorage, resourceName, typeFlags, format, w, h, levels, usageFlags, createFlags)); + renderGraphStorage->graphResources->try_emplace(resourceName, resourceManager->Create(renderGraphStorage, resourceName, typeFlags, format, w, h, levels, usageFlags, createFlags)); } /***************************************************************************/ @@ -104,16 +104,6 @@ namespace SHADE for (auto& input : subpass->inputReferences) resourceAttFinalLayouts[input.attachment] = input.layout; - - // Go through all subpass computes and initialize final layouts to GENERAL when a resource is detected to be used in it - //for (auto sbCompute : subpass->subpassComputes) - //{ - // auto const& indices = sbCompute->attachmentDescriptionIndices; - // for (auto& index : indices) - // { - // resourceAttFinalLayouts[index] = vk::ImageLayout::eGeneral; - // } - //} } for (uint32_t j = 0; j < node->attachmentDescriptions.size(); ++j) @@ -188,7 +178,7 @@ namespace SHADE // Now we want to loop through all attachments in all subpasses in the node and query // the resources being used. For each resource we want to query the type and record it // in bit fields (1 bit for each subpass). - uint32_t colorRead = 0, colorWrite = 0, depthRead = 0, depthWrite = 0, inputDependencies = 0, descriptorDependencies = 0; + uint32_t colorRead = 0, colorWrite = 0, depthRead = 0, depthWrite = 0, inputDependencies = 0; uint32_t i = 0; @@ -227,9 +217,6 @@ namespace SHADE if (subpass->inputReferences.size()) inputDependencies |= (1 << i); - if (!subpass->subpassComputes.empty()) - descriptorDependencies |= (1 << i); - // Input attachments can be any type, so we need to check what type it is for (auto& inputAtt : subpass->inputReferences) { @@ -295,12 +282,6 @@ namespace SHADE dstAccess |= vk::AccessFlagBits::eInputAttachmentRead; } - if (descriptorDependencies & (1 << i)) - { - dstStage |= vk::PipelineStageFlagBits::eComputeShader; - dstAccess |= vk::AccessFlagBits::eShaderWrite | vk::AccessFlagBits::eShaderRead; - } - //// If subpass of first renderpass, stage flag should be bottom of pipe //if (&node == &nodes.front() && i == 0) // srcStage = vk::PipelineStageFlagBits::eBottomOfPipe; @@ -316,8 +297,8 @@ namespace SHADE dep.srcStageMask = srcStage; - // initialize the barriers - //node->subpasses[i]->InitComputeBarriers(); + // initialize input descriptors + node->subpasses[i]->CreateInputDescriptors(); } } } @@ -371,15 +352,16 @@ namespace SHADE /***************************************************************************/ void SHRenderGraph::Init(Handle logicalDevice, Handle swapchain) noexcept { + resourceManager = std::make_shared(); + renderGraphStorage = resourceManager->Create(); + renderGraphStorage->graphResources = resourceManager->Create>>(); renderGraphStorage->logicalDevice = logicalDevice; renderGraphStorage->swapchain = swapchain; renderGraphStorage->resourceManager = resourceManager; renderGraphStorage->descriptorPool = logicalDevice->CreateDescriptorPools(); - - renderGraphStorage->ptrToResources = &graphResources; } /***************************************************************************/ @@ -396,20 +378,17 @@ namespace SHADE SHRenderGraph::SHRenderGraph(void) noexcept : renderGraphStorage{} , nodes{} - , graphResources{} , resourceManager{nullptr} { - resourceManager = std::make_shared(); } SHRenderGraph::SHRenderGraph(SHRenderGraph&& rhs) noexcept : renderGraphStorage{ rhs.renderGraphStorage } , nodeIndexing{ std::move(rhs.nodeIndexing) } , nodes{ std::move(rhs.nodes) } - , graphResources{ std::move(rhs.graphResources) } , resourceManager{ std::move(rhs.resourceManager) } { - + } SHRenderGraph& SHRenderGraph::operator=(SHRenderGraph&& rhs) noexcept @@ -420,7 +399,6 @@ namespace SHADE renderGraphStorage = rhs.renderGraphStorage; nodeIndexing = std::move(rhs.nodeIndexing); nodes = std::move(rhs.nodes); - graphResources = std::move(rhs.graphResources); resourceManager = std::move(rhs.resourceManager); return *this; @@ -456,12 +434,12 @@ namespace SHADE for (auto const& instruction : resourceInstruction) { // If the resource that the new node is requesting for exists, allow the graph to reference it - if (graphResources.contains(instruction.resourceName)) + if (renderGraphStorage->graphResources->contains(instruction.resourceName)) { descInitParams.push_back( { - .resourceHdl = graphResources.at(instruction.resourceName), - .dontClearOnLoad = false, + .resourceHdl = renderGraphStorage->graphResources->at(instruction.resourceName), + .dontClearOnLoad = instruction.dontClearOnLoad, } ); } @@ -506,12 +484,31 @@ namespace SHADE /***************************************************************************/ void SHRenderGraph::Generate(void) noexcept { + CheckForNodeComputes(); ConfigureAttachmentDescriptions(); ConfigureSubpasses(); ConfigureRenderpasses(); ConfigureFramebuffers(); } + /***************************************************************************/ + /*! + + \brief + This function goes through all renderpasses and checks for existence of + node computes. If they exist, adds dummy subpasses to transition resources + into general. + + */ + /***************************************************************************/ + void SHRenderGraph::CheckForNodeComputes(void) noexcept + { + for (auto& node : nodes) + { + node->AddDummySubpassIfNeeded(); + } + } + // 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 cmdBuffer, Handle descPool) noexcept @@ -531,7 +528,7 @@ namespace SHADE void SHRenderGraph::HandleResize(uint32_t newWidth, uint32_t newHeight) noexcept { // resize resources - for (auto& [name, resource]: graphResources) + for (auto& [name, resource] : *renderGraphStorage->graphResources) resource->HandleResize(newWidth, newHeight); for (auto& node : nodes) @@ -551,9 +548,9 @@ namespace SHADE Handle SHRenderGraph::GetRenderGraphResource(std::string const& resourceName) const noexcept { - if (graphResources.contains(resourceName)) + if (renderGraphStorage->graphResources->contains(resourceName)) { - return graphResources.at(resourceName); + return renderGraphStorage->graphResources->at(resourceName); } return {}; } diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.h b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.h index 529476cf..b445134c 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.h +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.h @@ -66,9 +66,6 @@ namespace SHADE //! Render graph nodes std::vector> nodes; - //! Resources that exist for the entire render graph - std::unordered_map> graphResources; - //! Resource library for graph handles std::shared_ptr resourceManager; @@ -88,10 +85,11 @@ namespace SHADE void AddResource(std::string resourceName, std::initializer_list typeFlags, uint32_t w = static_cast(-1), uint32_t h = static_cast(-1), vk::Format format = vk::Format::eB8G8R8A8Unorm, uint8_t levels = 1, vk::ImageUsageFlagBits usageFlags = {}, vk::ImageCreateFlagBits createFlags = {}); Handle AddNode (std::string nodeName, std::initializer_list resourceInstruction, std::initializer_list predecessorNodes) noexcept; - void Generate (void) noexcept; - void Execute (uint32_t frameIndex, Handle cmdBuffer, Handle descPool) noexcept; - void FinaliseBatch(uint32_t frameIndex, Handle descPool); - void HandleResize (uint32_t newWidth, uint32_t newHeight) noexcept; + void Generate (void) noexcept; + void CheckForNodeComputes (void) noexcept; + void Execute (uint32_t frameIndex, Handle cmdBuffer, Handle descPool) noexcept; + void FinaliseBatch (uint32_t frameIndex, Handle descPool); + void HandleResize (uint32_t newWidth, uint32_t newHeight) noexcept; /*-----------------------------------------------------------------------*/ /* SETTERS AND GETTERS */ diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.cpp b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.cpp index 0d88a93a..c315bffd 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.cpp +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.cpp @@ -7,6 +7,8 @@ #include "SHRenderGraphResource.h" #include "SHSubpass.h" #include "SHRenderGraphStorage.h" +#include "Graphics/RenderGraph/SHRenderGraphNodeCompute.h" +#include "Graphics/SHVkUtil.h" namespace SHADE { @@ -80,7 +82,6 @@ namespace SHADE fbHeight = attResources[j]->height; } - framebuffers[i]->HandleResize(renderpass, imageViews, fbWidth, fbHeight); } @@ -88,6 +89,11 @@ namespace SHADE { subpass->HandleResize(); } + + for (auto& nodeCompute : nodeComputes) + { + nodeCompute->HandleResize(); + } } /***************************************************************************/ @@ -121,6 +127,7 @@ namespace SHADE , subpasses{} , executed{ false } , configured{ false } + , nodeComputes{} { // pipeline library initialization pipelineLibrary.Init(graphStorage->logicalDevice); @@ -181,6 +188,7 @@ namespace SHADE , batcher{ std::move(rhs.batcher) } , spDescs{ std::move(rhs.spDescs) } , spDeps{ std::move(rhs.spDeps) } + , nodeComputes{ std::move(rhs.nodeComputes) } { rhs.renderpass = {}; @@ -204,6 +212,7 @@ namespace SHADE batcher = std::move(rhs.batcher); spDescs = std::move(rhs.spDescs); spDeps = std::move(rhs.spDeps); + nodeComputes = std::move(rhs.nodeComputes); rhs.renderpass = {}; @@ -235,7 +244,7 @@ namespace SHADE } // Add subpass to container and create mapping for it - subpasses.emplace_back(graphStorage->resourceManager->Create(graphStorage, GetHandle(), subpasses.size(), &resourceAttachmentMapping)); + subpasses.emplace_back(graphStorage->resourceManager->Create(graphStorage, GetHandle(), static_cast(subpasses.size()), &resourceAttachmentMapping)); subpassIndexing.try_emplace(subpassName, static_cast(subpasses.size()) - 1u); Handle subpass = subpasses.back(); subpass->Init(*graphStorage->resourceManager); @@ -246,21 +255,84 @@ namespace SHADE return subpass; } + Handle SHRenderGraphNode::AddNodeCompute(Handle computeShaderModule, std::initializer_list resources, float numWorkGroupScale/* = 1.0f*/) noexcept + { + // Look for the required resources in the graph + std::vector> nodeComputeResources{}; + nodeComputeResources.reserve(resources.size()); + + for (auto& resourceName : resources) + { + auto resource = graphStorage->graphResources->at(resourceName); + nodeComputeResources.push_back(resource); + } + + // Create the subpass compute with the resources + auto nodeCompute = graphStorage->resourceManager->Create(graphStorage, computeShaderModule, std::move(nodeComputeResources)); + nodeComputes.push_back(nodeCompute); + + return nodeCompute; + } + + /***************************************************************************/ + /*! + + \brief + This function checks all node computes and adds a subpass to transition + all needed resources to general. + + */ + /***************************************************************************/ + void SHRenderGraphNode::AddDummySubpassIfNeeded(void) noexcept + { + if (!nodeComputes.empty()) + { + // we save the resource names involved + std::unordered_set resourcesInvolved; + for (auto& compute : nodeComputes) + { + for (auto& resource : compute->resources) + { + resourcesInvolved.emplace(resource->GetName()); + } + } + + // insert them all for a subpass to transition them. This subpass is the last subpass + auto dummySubpass = AddSubpass("dummy"); + for (auto& resource : resourcesInvolved) + { + dummySubpass->AddGeneralInput(resource); + + if (SHVkUtil::IsDepthStencilAttachment(graphStorage->graphResources->at(resource)->GetResourceFormat())) + dummySubpass->AddGeneralDepthOutput(resource); + else + dummySubpass->AddGeneralColorOutput(resource); + } + } + } + void SHRenderGraphNode::Execute(Handle& commandBuffer, Handle descPool, uint32_t frameIndex) noexcept { - frameIndex = (framebuffers.size() > 1) ? frameIndex : 0; - commandBuffer->BeginRenderpass(renderpass, framebuffers[frameIndex]); + uint32_t framebufferIndex = (framebuffers.size() > 1) ? frameIndex : 0; + commandBuffer->BeginRenderpass(renderpass, framebuffers[framebufferIndex]); 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) + if (i != static_cast(subpasses.size()) - 1u) commandBuffer->NextSubpass(); } commandBuffer->EndRenderpass(); + + + // Execute all subpass computes + for (auto& sbCompute : nodeComputes) + { + sbCompute->Execute(commandBuffer, frameIndex); + } } Handle SHRenderGraphNode::GetOrCreatePipeline(std::pair, Handle> const& vsFsPair, Handle subpass) noexcept diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.h b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.h index 7c3622ad..335b93e3 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.h +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.h @@ -21,6 +21,7 @@ namespace SHADE class SHVkDescriptorPool; class SHGraphicsGlobalData; class SHRenderGraphStorage; + class SHRenderGraphNodeCompute; class SH_API SHRenderGraphNode : public ISelfHandle { @@ -67,6 +68,10 @@ namespace SHADE //! Every renderpass will require a pipeline library that will contain pipelines compatible with this renderpass SHPipelineLibrary pipelineLibrary; + //! Sometimes we want the subpass to do something to the images instead + //! of drawing objects on the image (i.e. compute). + std::vector> nodeComputes; + //! Whether or not the node has finished execution bool executed; @@ -75,6 +80,7 @@ namespace SHADE SHBatcher batcher; + /*-----------------------------------------------------------------------*/ /* PRIVATE MEMBER FUNCTIONS */ /*-----------------------------------------------------------------------*/ @@ -94,6 +100,9 @@ namespace SHADE /* PUBLIC MEMBER FUNCTIONS */ /*-----------------------------------------------------------------------*/ Handle AddSubpass(std::string subpassName) noexcept; + Handle AddNodeCompute(Handle computeShaderModule, std::initializer_list resources, float numWorkGroupScale = 1.0f) noexcept; + void AddDummySubpassIfNeeded (void) noexcept; + // TODO: RemoveSubpass() void Execute(Handle& commandBuffer, Handle descPool, uint32_t frameIndex) noexcept; Handle GetOrCreatePipeline(std::pair, Handle> const& vsFsPair, Handle subpass) noexcept; diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNodeCompute.cpp b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNodeCompute.cpp new file mode 100644 index 00000000..a5208fcf --- /dev/null +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNodeCompute.cpp @@ -0,0 +1,109 @@ +#include "SHpch.h" +#include "SHRenderGraphNodeCompute.h" +#include "Graphics/Pipeline/SHVkPipeline.h" +#include "Graphics/Descriptors/SHVkDescriptorSetGroup.h" +#include "Graphics/Descriptors/SHVkDescriptorPool.h" +#include "Graphics/Descriptors/SHVkDescriptorSetLayout.h" +#include "Graphics/Devices/SHVkLogicalDevice.h" +#include "Graphics/Pipeline/SHVkPipelineLayout.h" +#include "Graphics/MiddleEnd/GlobalData/SHGraphicsGlobalData.h" +#include "SHRenderGraphStorage.h" +#include "SHRenderGraphResource.h" +#include "Graphics/Commands/SHVkCommandBuffer.h" + +namespace SHADE +{ + SHRenderGraphNodeCompute::SHRenderGraphNodeCompute(Handle graphStorage, Handle computeShaderModule, std::vector>&& subpassComputeResources, float inNumWorkGroupScale/* = 1.0f*/) noexcept + : computePipeline{} + , pipelineLayout{} + , resources{} + , groupSizeX{0} + , groupSizeY{0} + , numWorkGroupScale {std::clamp(inNumWorkGroupScale, 0.0f, 1.0f)} + { + SHPipelineLayoutParams pipelineLayoutParams + { + .shaderModules = {computeShaderModule}, + .globalDescSetLayouts = SHGraphicsGlobalData::GetDescSetLayouts() + }; + + // Create pipeline layout from parameters + pipelineLayout = graphStorage->logicalDevice->CreatePipelineLayout (pipelineLayoutParams); + + // Create the compute pipeline + computePipeline = graphStorage->logicalDevice->CreateComputePipeline(pipelineLayout); + + // and construct it + computePipeline->ConstructPipeline(); + + // save the resources + resources = std::move (subpassComputeResources); + + //Get the descriptor set layouts required to allocate. We only want the ones for allocate because + //global descriptors are already bound in the main system. + auto const& layouts = computePipeline->GetPipelineLayout()->GetDescriptorSetLayoutsAllocate(); + + //Variable counts for the descriptor sets (all should be 1). + std::vector variableCounts{ static_cast(layouts.size()) }; + std::fill(variableCounts.begin(), variableCounts.end(), 0); + + // Allocate descriptor sets to hold the images for reading (STORAGE_IMAGE) + for (uint32_t i = 0; i < SHGraphicsConstants::NUM_FRAME_BUFFERS; ++i) + { + descSetGroups[i] = graphStorage->descriptorPool->Allocate(layouts, variableCounts); + } + + + HandleResize(); + } + + void SHRenderGraphNodeCompute::Execute(Handle cmdBuffer, uint32_t frameIndex) noexcept + { + // bind the compute pipeline + cmdBuffer->BindPipeline(computePipeline); + + // bind descriptor sets + cmdBuffer->BindDescriptorSet(descSetGroups[frameIndex], SH_PIPELINE_TYPE::COMPUTE, SHGraphicsConstants::DescriptorSetIndex::RENDERGRAPH_RESOURCE, {}); + + // dispatch compute + cmdBuffer->ComputeDispatch(groupSizeX, groupSizeY, 1); + + // TODO: barrier + + } + + void SHRenderGraphNodeCompute::HandleResize(void) noexcept + { + // Get the layout for the render graph resource. We can index it this way because the container returned is a container of layouts that includes the global ones + auto pipelineDescSetLayouts = computePipeline->GetPipelineLayout()->GetDescriptorSetLayoutsPipeline()[SHGraphicsConstants::DescriptorSetIndex::RENDERGRAPH_RESOURCE]; + + // everything below here needs resizing + for (uint32_t frameIndex = 0; frameIndex < SHGraphicsConstants::NUM_FRAME_BUFFERS; ++frameIndex) + { + uint32_t i = 0; + + // loop through bindings and write descriptor sets + for (auto& binding : pipelineDescSetLayouts->GetBindings()) + { + uint32_t imageIndex = (resources[i]->resourceTypeFlags & static_cast(SH_ATT_DESC_TYPE_FLAGS::COLOR_PRESENT)) ? frameIndex : 0; + + SHVkDescriptorSetGroup::viewSamplerLayout vsl = std::make_tuple(resources[i]->GetImageView(imageIndex), Handle{}, vk::ImageLayout::eGeneral); + descSetGroups[frameIndex]->ModifyWriteDescImage(SHGraphicsConstants::DescriptorSetIndex::RENDERGRAPH_RESOURCE, binding.BindPoint, { &vsl, 1 }); + descSetGroups[frameIndex]->UpdateDescriptorSetImages(SHGraphicsConstants::DescriptorSetIndex::RENDERGRAPH_RESOURCE, binding.BindPoint); + ++i; + } + } + + // Get the group size from the max width and height + uint32_t maxWidth = 0, maxHeight = 0; + for (auto& resource : resources) + { + maxWidth = std::max(resource->GetWidth(), maxWidth); + maxHeight = std::max(resource->GetHeight(), maxHeight); + } + + groupSizeX = maxWidth / workGroupSizeX; + groupSizeY = maxHeight / workGroupSizeY; + } + +} diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNodeCompute.h b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNodeCompute.h new file mode 100644 index 00000000..e35326f7 --- /dev/null +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNodeCompute.h @@ -0,0 +1,57 @@ +#pragma once + +#include "Resource/Handle.h" +#include "Graphics/MiddleEnd/Interface/SHGraphicsConstants.h" +#include +#include +#include + +namespace SHADE +{ + class SHVkPipeline; + class SHVkDescriptorSetGroup; + class SHVkDescriptorPool; + class SHVkLogicalDevice; + class SHVkPipelineLayout; + class SHRenderGraphStorage; + class SHRenderGraphResource; + class SHVkShaderModule; + class SHVkCommandBuffer; + + class SHRenderGraphNodeCompute + { + private: + static constexpr uint32_t workGroupSizeX = 16; + static constexpr uint32_t workGroupSizeY = 16; + + //! To run the dispatch command + Handle computePipeline; + + //! Pipeline layout for the pipeline creation + Handle pipelineLayout; + + //! Descriptor set group to hold the images for reading (STORAGE_IMAGE) + std::array, SHGraphicsConstants::NUM_FRAME_BUFFERS> descSetGroups; + + //! vector of resources needed by the subpass compute + std::vector> resources; + + //! X dimension work group size. Should scale with resource size. + uint32_t groupSizeX; + + //! Y dimension work group size + uint32_t groupSizeY; + + float numWorkGroupScale; + + public: + SHRenderGraphNodeCompute(Handle graphStorage, Handle computeShaderModule, std::vector>&& subpassComputeResources, float inNumWorkGroupScale = 1.0f) noexcept; + + void Execute (Handle cmdBuffer, uint32_t frameIndex) noexcept; + void HandleResize (void) noexcept; + + friend class SHRenderGraph; + friend class SHRenderGraphNode; + }; +} + diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphResource.cpp b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphResource.cpp index 651ba88b..502e09b2 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphResource.cpp +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphResource.cpp @@ -117,6 +117,9 @@ namespace SHADE usage |= vk::ImageUsageFlagBits::eInputAttachment; usage |= vk::ImageUsageFlagBits::eSampled; break; + case SH_ATT_DESC_TYPE_FLAGS::STORAGE: + usage |= vk::ImageUsageFlagBits::eStorage; + break; case SH_ATT_DESC_TYPE_FLAGS::COLOR_PRESENT: { SHLOG_ERROR ("COLOR_PRESENT cannot be with other resource type flags. "); @@ -334,4 +337,9 @@ namespace SHADE return mipLevels; } + std::string SHRenderGraphResource::GetName(void) const noexcept + { + return resourceName; + } + } \ No newline at end of file diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphResource.h b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphResource.h index 55f25864..832fa772 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphResource.h +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphResource.h @@ -88,9 +88,11 @@ namespace SHADE Handle GetImageView (uint32_t index = NON_SWAPCHAIN_RESOURCE_INDEX) const noexcept; Handle GetImage (uint32_t index = NON_SWAPCHAIN_RESOURCE_INDEX) const noexcept; uint8_t GetMipLevels (void) const noexcept; + std::string GetName (void) const noexcept; friend class SHRenderGraphNode; friend class SHRenderGraph; friend class SHSubpass; + friend class SHRenderGraphNodeCompute; }; } diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphStorage.h b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphStorage.h index cb274697..f8123191 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphStorage.h +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphStorage.h @@ -9,13 +9,14 @@ namespace SHADE class SHVkSwapchain; class SHGraphicsGlobalData; class SHVkDescriptorPool; + class SHRenderGraphResource; class SHRenderGraphStorage { //! Logical device for creation of vulkan objects Handle logicalDevice; - //! swapchain hdl + //! swapchain handle Handle swapchain; //! Resource manager for creation of objects @@ -24,13 +25,19 @@ namespace SHADE //! Descriptor pool for the descriptor sets to be created in the subpasses Handle descriptorPool; - //! For accessing resources anyone in the graph - std::unordered_map> const* ptrToResources; + //! For accessing resources anywhere in the graph + Handle>> graphResources; + + //SHRenderGraphStorage(void) noexcept; + //SHRenderGraphStorage(SHRenderGraphStorage&& rhs) noexcept; + //SHRenderGraphStorage& operator=(SHRenderGraphStorage&& rhs) noexcept; friend class SHRenderGraph; friend class SHRenderGraphNode; friend class SHSubpass; friend class SHRenderGraphResource; - friend class SHSubpassCompute; + friend class SHRenderGraphNodeCompute; }; + + } diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHSubpass.cpp b/SHADE_Engine/src/Graphics/RenderGraph/SHSubpass.cpp index e6472c52..5e3449c2 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHSubpass.cpp +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHSubpass.cpp @@ -7,7 +7,6 @@ #include "Graphics/Shaders/SHVkShaderModule.h" #include "SHRenderGraphNode.h" #include "SHRenderGraphStorage.h" -#include "Graphics/RenderGraph/SHSubpassCompute.h" #include "Graphics/Descriptors/SHVkDescriptorSetGroup.h" #include "Graphics/Swapchain/SHVkSwapchain.h" #include "Graphics/Images/SHVkSampler.h" @@ -40,7 +39,6 @@ namespace SHADE , depthReferences{} , inputReferences{} , graphStorage{ renderGraphStorage } - , subpassComputes{} , inputImageDescriptors {SHGraphicsConstants::NUM_FRAME_BUFFERS} { } @@ -66,8 +64,12 @@ namespace SHADE , resourceAttachmentMapping{ rhs.resourceAttachmentMapping } , descriptorSetLayout{ rhs.descriptorSetLayout } , exteriorDrawCalls{ std::move(rhs.exteriorDrawCalls) } - , graphStorage{ std::move(rhs.graphStorage) } - , subpassComputes{std::move (rhs.subpassComputes)} + , graphStorage{ rhs.graphStorage } + , inputNames{ std::move(rhs.inputNames) } + , inputImageDescriptors{ std::move(rhs.inputImageDescriptors) } + , inputDescriptorLayout{ rhs.inputDescriptorLayout } + , inputSamplers{ rhs.inputSamplers } + { } @@ -97,8 +99,11 @@ namespace SHADE resourceAttachmentMapping = rhs.resourceAttachmentMapping; descriptorSetLayout = rhs.descriptorSetLayout; exteriorDrawCalls = std::move(rhs.exteriorDrawCalls); - graphStorage = std::move(rhs.graphStorage); - subpassComputes = std::move(rhs.subpassComputes); + graphStorage = rhs.graphStorage; + inputNames = std::move(rhs.inputNames); + inputImageDescriptors = std::move(rhs.inputImageDescriptors); + inputDescriptorLayout = rhs.inputDescriptorLayout; + inputSamplers = rhs.inputSamplers; return *this; } @@ -117,7 +122,12 @@ namespace SHADE /***************************************************************************/ void SHSubpass::AddColorOutput(std::string resourceToReference) noexcept { - colorReferences.push_back({ resourceAttachmentMapping->at(graphStorage->ptrToResources->at(resourceToReference).GetId().Raw), vk::ImageLayout::eColorAttachmentOptimal }); + colorReferences.push_back({ resourceAttachmentMapping->at(graphStorage->graphResources->at(resourceToReference).GetId().Raw), vk::ImageLayout::eColorAttachmentOptimal }); + } + + void SHSubpass::AddGeneralColorOutput(std::string resourceToReference) noexcept + { + colorReferences.push_back({ resourceAttachmentMapping->at(graphStorage->graphResources->at(resourceToReference).GetId().Raw), vk::ImageLayout::eGeneral }); } /***************************************************************************/ @@ -154,7 +164,13 @@ namespace SHADE //Invalid return; } - depthReferences.push_back({ resourceAttachmentMapping->at(graphStorage->ptrToResources->at(resourceToReference).GetId().Raw), imageLayout }); + depthReferences.push_back({ resourceAttachmentMapping->at(graphStorage->graphResources->at(resourceToReference).GetId().Raw), imageLayout }); + } + + void SHSubpass::AddGeneralDepthOutput(std::string resourceToReference) noexcept + { + depthReferences.push_back({ resourceAttachmentMapping->at(graphStorage->graphResources->at(resourceToReference).GetId().Raw), vk::ImageLayout::eGeneral }); + } /***************************************************************************/ @@ -171,15 +187,14 @@ namespace SHADE /***************************************************************************/ void SHSubpass::AddInput(std::string resourceToReference) noexcept { - inputReferences.push_back({ resourceAttachmentMapping->at(graphStorage->ptrToResources->at(resourceToReference).GetId().Raw), vk::ImageLayout::eShaderReadOnlyOptimal }); + inputReferences.push_back({ resourceAttachmentMapping->at(graphStorage->graphResources->at(resourceToReference).GetId().Raw), vk::ImageLayout::eShaderReadOnlyOptimal }); inputNames.push_back(resourceToReference); } void SHSubpass::AddGeneralInput(std::string resourceToReference) noexcept { - inputReferences.push_back({ resourceAttachmentMapping->at(graphStorage->ptrToResources->at(resourceToReference).GetId().Raw), vk::ImageLayout::eGeneral }); - + inputReferences.push_back({ resourceAttachmentMapping->at(graphStorage->graphResources->at(resourceToReference).GetId().Raw), vk::ImageLayout::eGeneral }); } void SHSubpass::Execute(Handle& commandBuffer, Handle descPool, uint32_t frameIndex) noexcept @@ -196,11 +211,6 @@ namespace SHADE drawCall(commandBuffer); } - // if there are subpass computes, transition all to GENERAL layout first - for (auto& sbCompute : subpassComputes) - { - - } } void SHSubpass::HandleResize(void) noexcept @@ -213,29 +223,6 @@ namespace SHADE exteriorDrawCalls.push_back(newDrawCall); } - Handle SHSubpass::AddSubpassCompute(Handle computeShaderModule/*, std::initializer_list resources*/) noexcept - { - //// for the subpass compute to store indices to the resources, see member comments - //std::unordered_set attDescIndices{}; - //attDescIndices.reserve (resources.size()); - - //// Look for the required resources in the graph - //std::vector> subpassComputeResources{}; - //subpassComputeResources.reserve(resources.size()); - - //for (auto& resourceName : resources) - //{ - // auto resource = graphStorage->ptrToResources->at(resourceName); - // subpassComputeResources.push_back(resource); - // attDescIndices.emplace(resourceAttachmentMapping->at (resource.GetId().Raw)); - //} - - // Create the subpass compute with the resources - auto subpassCompute = graphStorage->resourceManager->Create(graphStorage, computeShaderModule/*, std::move(subpassComputeResources), std::move (attDescIndices)*/); - subpassComputes.push_back(subpassCompute); - - return subpassCompute; - } void SHSubpass::Init(ResourceManager& resourceManager) noexcept { @@ -245,48 +232,51 @@ namespace SHADE void SHSubpass::CreateInputDescriptors(void) noexcept { - //std::vector bindings{}; + if (inputNames.empty()) + return; - //for (auto& input : inputReferences) - //{ - // SHVkDescriptorSetLayout::Binding newBinding - // { - // .Type = (input.layout == vk::ImageLayout::eShaderReadOnlyOptimal) ? vk::DescriptorType::eInputAttachment : vk::DescriptorType::eStorageImage, - // .Stage = vk::ShaderStageFlagBits::eFragment | vk::ShaderStageFlagBits::eCompute, - // .BindPoint = static_cast(bindings.size()), - // .DescriptorCount = 1, - // .flags = {}, - // }; + std::vector bindings{}; - // bindings.push_back(newBinding); - //} + for (auto& input : inputReferences) + { + SHVkDescriptorSetLayout::Binding newBinding + { + .Type = (input.layout == vk::ImageLayout::eShaderReadOnlyOptimal) ? vk::DescriptorType::eInputAttachment : vk::DescriptorType::eStorageImage, + .Stage = vk::ShaderStageFlagBits::eFragment, + .BindPoint = static_cast(bindings.size()), + .DescriptorCount = 1, + .flags = {}, + }; - //// We build a new descriptor set layout to store our images - //inputDescriptorLayout = graphStorage->logicalDevice->CreateDescriptorSetLayout(SHGraphicsConstants::DescriptorSetIndex::RENDERGRAPH_RESOURCE, bindings); + bindings.push_back(newBinding); + } - //// we store a sampler if its an input attachment. if it is storage image, no need sampler, store an empty handle. - //for (uint32_t i = 0; i < bindings.size(); ++i) - //{ - // if (bindings[i].Type == vk::DescriptorType::eInputAttachment) - // { - // auto newSampler = graphStorage->logicalDevice->CreateSampler(SHVkSamplerParams - // { - // .minFilter = vk::Filter::eLinear, - // .magFilter = vk::Filter::eLinear, - // .addressMode = vk::SamplerAddressMode::eRepeat, - // .mipmapMode = vk::SamplerMipmapMode::eLinear, - // .minLod = -1000, - // .maxLod = 1000 - // } - // ); + // We build a new descriptor set layout to store our images + inputDescriptorLayout = graphStorage->logicalDevice->CreateDescriptorSetLayout(SHGraphicsConstants::DescriptorSetIndex::RENDERGRAPH_RESOURCE, bindings); - // inputSamplers.push_back(newSampler); - // } - // else - // { - // inputSamplers.push_back({}); - // } - //} + // we store a sampler if its an input attachment. if it is storage image, no need sampler, store an empty handle. + for (uint32_t i = 0; i < bindings.size(); ++i) + { + if (bindings[i].Type == vk::DescriptorType::eInputAttachment) + { + auto newSampler = graphStorage->logicalDevice->CreateSampler(SHVkSamplerParams + { + .minFilter = vk::Filter::eLinear, + .magFilter = vk::Filter::eLinear, + .addressMode = vk::SamplerAddressMode::eRepeat, + .mipmapMode = vk::SamplerMipmapMode::eLinear, + .minLod = -1000, + .maxLod = 1000 + } + ); + + inputSamplers.push_back(newSampler); + } + else + { + inputSamplers.push_back({}); + } + } //// maybe do this in handle resize? //UpdateWriteDescriptors(); @@ -294,39 +284,43 @@ namespace SHADE void SHSubpass::UpdateWriteDescriptors(void) noexcept { - //auto const& bindings = inputDescriptorLayout->GetBindings(); + if (inputNames.empty()) + return; - //std::vector variableCounts{ static_cast(bindings.size()), 0 }; + auto const& bindings = inputDescriptorLayout->GetBindings(); - //uint32_t i = 0; + std::vector variableCounts{ static_cast(bindings.size()) }; + std::fill (variableCounts.begin(), variableCounts.end(), 0u); - //// For every frame's descriptor set - //for (auto& group : inputImageDescriptors) - //{ - // if (group) - // group.Free(); - // group = graphStorage->descriptorPool->Allocate({ inputDescriptorLayout }, variableCounts); + // For every frame's descriptor set + for (auto& group : inputImageDescriptors) + { + if (group) + group.Free(); - // for (auto& binding : bindings) - // { - // // get the resource - // auto resource = graphStorage->ptrToResources->at(inputNames[binding.BindPoint]); + group = graphStorage->descriptorPool->Allocate({ inputDescriptorLayout }, variableCounts); - // // If resource is swapchain image, get the correct image, if not just get 0. - // uint32_t viewIndex = (resource->resourceTypeFlags & static_cast(SH_ATT_DESC_TYPE_FLAGS::COLOR_PRESENT)) ? i : 0; + uint32_t i = 0; + for (auto& binding : bindings) + { + // get the resource + auto resource = graphStorage->graphResources->at(inputNames[binding.BindPoint]); - // // layout is GENERAL if image is meant to be used as storage image, if not use SHADER_READ_ONLY_OPTINAL - // vk::ImageLayout descriptorLayout = (binding.Type == vk::DescriptorType::eStorageImage) ? vk::ImageLayout::eGeneral : vk::ImageLayout::eShaderReadOnlyOptimal; + // If resource is swapchain image, get the correct image, if not just get 0. + uint32_t viewIndex = (resource->resourceTypeFlags & static_cast(SH_ATT_DESC_TYPE_FLAGS::COLOR_PRESENT)) ? i : 0; - // // Update descriptor sets - // auto args = std::make_tuple(resource->GetImageView(viewIndex), inputSamplers[i], descriptorLayout); - // group->ModifyWriteDescImage(SHGraphicsConstants::DescriptorSetIndex::RENDERGRAPH_RESOURCE, binding.BindPoint, std::span{&args, 1}); - // group->UpdateDescriptorSetImages(SHGraphicsConstants::DescriptorSetIndex::RENDERGRAPH_RESOURCE, binding.BindPoint); - // } + // layout is GENERAL if image is meant to be used as storage image, if not use SHADER_READ_ONLY_OPTINAL + vk::ImageLayout descriptorLayout = (binding.Type == vk::DescriptorType::eStorageImage) ? vk::ImageLayout::eGeneral : vk::ImageLayout::eShaderReadOnlyOptimal; - // ++i; - //} + // Update descriptor sets + auto args = std::make_tuple(resource->GetImageView(viewIndex), inputSamplers[i], descriptorLayout); + group->ModifyWriteDescImage(SHGraphicsConstants::DescriptorSetIndex::RENDERGRAPH_RESOURCE, binding.BindPoint, std::span{&args, 1}); + group->UpdateDescriptorSetImages(SHGraphicsConstants::DescriptorSetIndex::RENDERGRAPH_RESOURCE, binding.BindPoint); + } + + ++i; + } } //void SHSubpass::InitComputeBarriers(void) noexcept diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHSubpass.h b/SHADE_Engine/src/Graphics/RenderGraph/SHSubpass.h index 48874a06..5a9dafb2 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHSubpass.h +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHSubpass.h @@ -17,7 +17,6 @@ namespace SHADE class SHVkDescriptorSetGroup; class SHVkDescriptorPool; class SHRenderGraphStorage; - class SHSubpassCompute; class SHVkShaderModule; class SHVkSampler; @@ -64,9 +63,6 @@ namespace SHADE std::vector> inputSamplers; - //! Sometimes we want the subpass to do something to the images instead - //! of drawing objects on the image (i.e. compute). - std::vector> subpassComputes; ////! subpass compute image barriers. We do this because every frame has a different ////! swapchain image. If the resource we want to transition is not a swapchain image, @@ -96,7 +92,9 @@ namespace SHADE /*-----------------------------------------------------------------------*/ // Preparation functions void AddColorOutput(std::string resourceToReference) noexcept; + void AddGeneralColorOutput(std::string resourceToReference) noexcept; void AddDepthOutput(std::string resourceToReference, SH_ATT_DESC_TYPE_FLAGS attachmentDescriptionType = SH_ATT_DESC_TYPE_FLAGS::DEPTH_STENCIL) noexcept; + void AddGeneralDepthOutput(std::string resourceToReference) noexcept; void AddInput(std::string resourceToReference) noexcept; void AddGeneralInput (std::string resourceToReference) noexcept; void AddExteriorDrawCalls(std::function&)> const& newDrawCall) noexcept; @@ -105,7 +103,6 @@ namespace SHADE void Execute(Handle& commandBuffer, Handle descPool, uint32_t frameIndex) noexcept; void HandleResize (void) noexcept; - Handle AddSubpassCompute(Handle computeShaderModule/*, std::initializer_list resources*/) noexcept; void Init(ResourceManager& resourceManager) noexcept; diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHSubpassCompute.cpp b/SHADE_Engine/src/Graphics/RenderGraph/SHSubpassCompute.cpp deleted file mode 100644 index 79242c7d..00000000 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHSubpassCompute.cpp +++ /dev/null @@ -1,53 +0,0 @@ -#include "SHpch.h" -#include "SHSubpassCompute.h" -#include "Graphics/Pipeline/SHVkPipeline.h" -#include "Graphics/Descriptors/SHVkDescriptorSetGroup.h" -#include "Graphics/Descriptors/SHVkDescriptorPool.h" -#include "Graphics/Devices/SHVkLogicalDevice.h" -#include "Graphics/Pipeline/SHVkPipelineLayout.h" -#include "Graphics/MiddleEnd/GlobalData/SHGraphicsGlobalData.h" -#include "SHRenderGraphStorage.h" -//#include "" - -namespace SHADE -{ - SHSubpassCompute::SHSubpassCompute(Handle graphStorage, Handle computeShaderModule/*, std::vector>&& subpassComputeResources, std::unordered_set&& attDescIndices*/) noexcept - : pipeline{} - { - SHPipelineLayoutParams pipelineLayoutParams - { - .shaderModules = {computeShaderModule}, - .globalDescSetLayouts = SHGraphicsGlobalData::GetDescSetLayouts() - }; - - // Create descriptor set from - pipelineLayout = graphStorage->logicalDevice->CreatePipelineLayout (pipelineLayoutParams); - - // Create the compute pipeline - pipeline = graphStorage->logicalDevice->CreateComputePipeline(pipelineLayout); - - pipeline->ConstructPipeline(); - - // Get the descriptor set layouts required to allocate. We only want the ones for allocate because - // global descriptors are already bound in the main system. - //auto const& layouts = pipeline->GetPipelineLayout()->GetDescriptorSetLayoutsAllocate(); - - // Variable counts for the descriptor sets (all should be 1). - //std::vector variableCounts{ static_cast(layouts.size()) }; - //std::fill(variableCounts.begin(), variableCounts.end(), 0); - - //// Allocate descriptor sets to hold the images for reading (STORAGE_IMAGE) - //descSetGroup = graphStorage->descriptorPool->Allocate(layouts, variableCounts); - - //// save the resources - //resources = std::move (subpassComputeResources); - - //// we save this because when we configure the graph, we want to make sure final layouts - //// of attachment descriptions are set to GENERAL. See ConfigureAttachmentDescriptions in SHRenderGraph.cpp. - //attachmentDescriptionIndices = std::move (attDescIndices); - - //descSetGroup->ModifyWriteDescImage (SHGraphicsConstants::DescriptorSetIndex::RENDERGRAPH_RESOURCE, ) - } - - //SHSubpass -} diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHSubpassCompute.h b/SHADE_Engine/src/Graphics/RenderGraph/SHSubpassCompute.h deleted file mode 100644 index aae2a9b9..00000000 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHSubpassCompute.h +++ /dev/null @@ -1,49 +0,0 @@ -#pragma once - -#include "Resource/Handle.h" -#include -#include -#include - -namespace SHADE -{ - class SHVkPipeline; - class SHVkDescriptorSetGroup; - class SHVkDescriptorPool; - class SHVkLogicalDevice; - class SHVkPipelineLayout; - class SHRenderGraphStorage; - class SHRenderGraphResource; - class SHVkShaderModule; - - class SHSubpassCompute - { - private: - //! To run the dispatch command - Handle pipeline; - - //! Pipeline layout for the pipeline creation - Handle pipelineLayout; - - ////! Descriptor set group to hold the images for reading (STORAGE_IMAGE) - //Handle descSetGroup; - - ////! Required resources to be used in the descriptors - //std::vector resourcesRequired; - - ////! vector of resources needed by the subpass compute - //std::vector> resources; - - ////! we save this because when we configure the graph, we want to make sure final layouts - ////! of attachment descriptions are set to GENERAL. See ConfigureAttachmentDescriptions in SHRenderGraph.cpp. - //std::unordered_set attachmentDescriptionIndices{}; - - public: - SHSubpassCompute(Handle graphStorage, Handle computeShaderModule/*, std::vector>&& subpassComputeResources, std::unordered_set&& attDescIndices*/) noexcept; - - //void ExecuteSubpass (void) noexcept; - friend class SHRenderGraph; - friend class SHSubpass; - }; -} - diff --git a/SHADE_Engine/src/Graphics/SHVkUtil.cpp b/SHADE_Engine/src/Graphics/SHVkUtil.cpp index c8c563a1..cf486a7a 100644 --- a/SHADE_Engine/src/Graphics/SHVkUtil.cpp +++ b/SHADE_Engine/src/Graphics/SHVkUtil.cpp @@ -55,6 +55,21 @@ namespace SHADE return 0; } + vk::PipelineBindPoint SHVkUtil::GetPipelineBindPointFromType(SH_PIPELINE_TYPE pipelineType) noexcept + { + switch (pipelineType) + { + case SH_PIPELINE_TYPE::GRAPHICS: + return vk::PipelineBindPoint::eGraphics; + case SH_PIPELINE_TYPE::COMPUTE: + return vk::PipelineBindPoint::eCompute; + case SH_PIPELINE_TYPE::RAY_TRACING: + return vk::PipelineBindPoint::eRayTracingKHR; + default: + return vk::PipelineBindPoint::eGraphics; + } + } + void SHVkUtil::EnsureBufferAndCopyData(Handle device, Handle cmdBuffer, Handle& bufferHandle, void* src, uint32_t size, vk::BufferUsageFlagBits usage) { if (bufferHandle) diff --git a/SHADE_Engine/src/Graphics/SHVkUtil.h b/SHADE_Engine/src/Graphics/SHVkUtil.h index ca3b6f83..ab11b537 100644 --- a/SHADE_Engine/src/Graphics/SHVkUtil.h +++ b/SHADE_Engine/src/Graphics/SHVkUtil.h @@ -4,6 +4,7 @@ #include "SHVulkanIncludes.h" #include "Resource/Handle.h" +#include "Graphics/Pipeline/SHPipelineType.h" namespace SHADE { @@ -20,11 +21,12 @@ namespace SHADE class SHVkUtil { public: - static bool IsDepthOnlyFormat (vk::Format format) noexcept; - static bool IsDepthStencilAttachment (vk::Format format) noexcept; - static bool IsBlendCompatible (vk::Format format) noexcept; - static uint32_t GetBytesPerPixelFromFormat (vk::Format format) noexcept; - + static bool IsDepthOnlyFormat (vk::Format format) noexcept; + static bool IsDepthStencilAttachment (vk::Format format) noexcept; + static bool IsBlendCompatible (vk::Format format) noexcept; + static uint32_t GetBytesPerPixelFromFormat (vk::Format format) noexcept; + static vk::PipelineBindPoint GetPipelineBindPointFromType (SH_PIPELINE_TYPE pipelineType) noexcept; + /***********************************************************************************/ /*! diff --git a/TempShaderFolder/GreyscaleCs.glsl b/TempShaderFolder/GreyscaleCs.glsl deleted file mode 100644 index 3167a57c..00000000 --- a/TempShaderFolder/GreyscaleCs.glsl +++ /dev/null @@ -1,38 +0,0 @@ -/* Start Header *****************************************************************/ - -/*! \file (e.g. kirsch.comp) - - \author William Zheng, william.zheng, 60001906. Brandon Mak, brandon.hao 390003920. - - \par william.zheng\@digipen.edu. brandon.hao\@digipen.edu. - - \date Sept 20, 2022 - - \brief Copyright (C) 20xx 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. */ - - /* End Header *******************************************************************/ - -#version 450 - -layout(local_size_x = 16, local_size_y = 16) in; -layout(set = 4, binding = 0, rgba8) uniform image2D targetImage; - - -void main() -{ - // load the image - vec4 color = imageLoad (targetImage, ivec2 (gl_GlobalInvocationID)); - - // get the average - float average = 0.2126 * color.r + 0.7152 * color.g + 0.0722 * color.b; - - // store result into result image - imageStore(targetImage, ivec2(gl_GlobalInvocationID), vec4(average, average, average, 1.0f)); - -} - - - - diff --git a/TempShaderFolder/GreyscaleCs.spv b/TempShaderFolder/GreyscaleCs.spv deleted file mode 100644 index 5b36e00317061a12d75127def8a67c940e8969c6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1400 zcmZ9K+fEZv6o$97g$e>9Ld9b%o)E04oRoku(M*~&0pb-`lVLh(CK*~%#wI3S=!H+< zjql+b_yoRy@8OM!|2NDsqkFQl*8i{5UTaTjWO2;7b8g&Cx@~uMX55Gv=O)}}roHyt zcJnmtG}qQwiI{SwERdLK#Z;urlH(xm;h2$J6c2Z1gX!XwSyFZ9z6+Gq)oc6S-k#Tf zfbRiXw{r!ROT@>?i$!bVc6<=`~7t}_mcimkhFTkei)>2zt?)5<&@oZ>0lTQi1$>J8n-3%GTe~O0W<4_ zggo$z94|=EYHH?gWE*gqJuiDyTwPLAydEOM)UOLyrQwhTO*Ae|yjJ(mp|0i7pF`}n zSTOhI%n46P*8w{8oR)^;Md@kp1W!Jgx#&s$taLrc;VzioHzgeNv*W|s=1cQ03e(^G4`hG+`DMraOTzRs|E6r`KK{*rF2o!w>dsue z3mii24gC$aL&0p8Ut;*L*#Yms|HK?%X5x*(JHqUGQo^3W^tdEpZy$u&(Ok|Qs4Dxa z<(!l=?n=%v>%QXHCI1ew_>RQU^Qwe?_;z($?gsZte(rWl0>@stkNsotpA`dcNO*_3 z#PaUQCXbz1-d)-7mUmA!?*soSuXSHG_3&A(hq9@)B(Yk{vf-`PifrBz-fBIPO+9?f z#-8D*!JeCv;+`K17x%m>3}-uiA{&ll+*8?b#XUb0CKjLFcTG0^4X^))H*&nMSK(c@ WB;*i>kN+^#y}2{>@&8uWEy*9dZd@?{ diff --git a/TempShaderFolder/KirschCs.glsl b/TempShaderFolder/KirschCs.glsl new file mode 100644 index 00000000..3dec174d --- /dev/null +++ b/TempShaderFolder/KirschCs.glsl @@ -0,0 +1,167 @@ +//#version 450 +// +//layout(local_size_x = 16, local_size_y = 16) in; +//layout(set = 4, binding = 0, rgba8) uniform image2D targetImage; +// +// +//void main() +//{ +// ivec2 imageSize = imageSize (targetImage); +// +// if (gl_GlobalInvocationID.x >= imageSize.x && gl_GlobalInvocationID.y >= imageSize.y) +// return; +// +// // load the image +// vec4 color = imageLoad (targetImage, ivec2 (gl_GlobalInvocationID)); +// +// // get the average +// float average = 0.2126 * color.r + 0.7152 * color.g + 0.0722 * color.b; +// +// // store result into result image +// imageStore(targetImage, ivec2(gl_GlobalInvocationID), vec4(average, average, average, 1.0f)); +// +//} +// +// +// +// + +/* Start Header *****************************************************************/ + +/*! \file (e.g. kirsch.comp) + + \author William Zheng, william.zheng, 60001906. Brandon Mak, brandon.hao 390003920. + + \par william.zheng\@digipen.edu. brandon.hao\@digipen.edu. + + \date Sept 20, 2022 + + \brief Copyright (C) 20xx 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. */ + + /* End Header *******************************************************************/ + +#version 450 + +#define MASK_WIDTH 3 +#define HALF_M_WIDTH MASK_WIDTH / 2 +#define SHM_WIDTH 18 +#define NUM_MASKS 8 + +layout(local_size_x = 16, local_size_y = 16) in; +layout(set = 4, binding = 0, rgba8) uniform image2D inputImage; +layout(set = 4, binding = 1, rgba8) uniform image2D resultImage; + +const float kirsch[8][3][3] = { + { + {5, 5, 5}, + {-3, 0, -3}, /*rotation 1 */ + {-3, -3, -3} + }, + { + {5, 5, -3}, + {5, 0, -3}, /*rotation 2 */ + {-3, -3, -3} + }, + { + {5, -3, -3}, + {5, 0, -3}, /*rotation 3 */ + {5, -3, -3} + }, + { + {-3, -3, -3}, + {5, 0, -3}, /*rotation 4 */ + {5, 5, -3} + }, + { + {-3, -3, -3}, + {-3, 0, -3}, /*rotation 5 */ + {5, 5, 5} + }, + { + {-3, -3, -3}, + {-3, 0, 5}, /*rotation 6 */ + {-3, 5, 5} + }, + { + {-3, -3, 5}, + {-3, 0, 5}, /*rotation 7 */ + {-3, -3, 5} + }, + { + {-3, 5, 5}, + {-3, 0, 5}, /*rotation 8 */ + {-3, -3, -3} + } +}; + +vec3 GetImageValues(ivec2 uv, ivec2 inputImageSize) +{ + if (uv.x >= 0 && uv.y >= 0 && uv.x < inputImageSize.x && uv.y < inputImageSize.y) + { + return imageLoad(inputImage, uv).rgb; + } + else + return vec3(0.0f); +} + +//two extra row/col +shared vec3 sData[16 + 2][16 + 2]; + +void main() +{ + // convenient variables + ivec3 globalThread = ivec3(gl_GlobalInvocationID); + ivec3 localThread = ivec3(gl_LocalInvocationID); + ivec2 inputImageSize = imageSize(inputImage); + + // load shared memory + ivec2 start = ivec2(gl_WorkGroupID) * ivec2(gl_WorkGroupSize) - ivec2(HALF_M_WIDTH); + for (int i = localThread.x; i < SHM_WIDTH; i += int(gl_WorkGroupSize.x)) + { + for (int j = localThread.y; j < SHM_WIDTH; j += int(gl_WorkGroupSize.y)) + { + // get from source image (either real values or 0) + vec3 sourceValue = GetImageValues(start + ivec2(i, j), inputImageSize); + sData[i][j] = sourceValue; + } + } + + // wait for shared memory to finish loading + barrier(); + + // max (between all 8 masks) + vec3 maxSum = vec3(0.0f); + + // loop through all masks + for (int i = 0; i < NUM_MASKS; ++i) + { + vec3 sum = vec3(0.0f); + + // start of shared memory + ivec2 shmStart = ivec2(localThread + HALF_M_WIDTH); + for (int j = -1; j < HALF_M_WIDTH + 1; ++j) + { + for (int k = -1; k < HALF_M_WIDTH + 1; ++k) + { + // Perform convolution using shared_memory + sum += sData[shmStart.x + j][shmStart.y + k] * kirsch[i][j + 1][k + 1]; + } + } + + // Get highest sum + maxSum = max(sum, maxSum); + } + + // average the max sum + maxSum = min(max(maxSum / 8, 0), 1.0f); + + // store result into result image + imageStore(resultImage, ivec2(gl_GlobalInvocationID.xy), vec4(maxSum, 1.0f)); + +} + + + + diff --git a/TempShaderFolder/KirschCs.spv b/TempShaderFolder/KirschCs.spv new file mode 100644 index 0000000000000000000000000000000000000000..1ae5408b12013ad40918e0477191c76630795dbb GIT binary patch literal 5900 zcmZXW37l1R702(ajDQHJ7)Ui}izShWqBRr@VNY^$urZgchR4hUp1fI{nKz+X;8LlW zErzX{Ek?W9YWrkm`(i7$+MX>InQNhazxVx5pWAf#{5a?Q&iY^Oebdr>^(-5o7+iMT@y8fBCu>pUzJs!ktPQ;t43(?H^6S9K zpcl-ghQ4{ZuHDFMp++)jJ;m5?>aNHfR1BBw`sS_&EM*(vz{f3DW-RQU0U^4J8@IQN@6XO4_*D~*lR zM{VjF&oMubX~{Mt&&~C=>^$W7NPTReu`|TBW-o#pEsvFl@|f0a`!supIqS+3<>cRm z94c?`tCL`_E3u>3Zeww{?rYSy4)vvR^Vnf!(M{!qwSv00*jOFK5HMIZ1+ohQL^n(tfy_grsUs`G=3pC znA_|9UBa4u8`KY_XFIYJm~$95FImp%@5Jsv%83PJ9+2~m*qP|s)?31=?ImZ9ID{^~ zKlYi2>;yhXCwqRw%=;XS9=-KD*Mj7ac-QTm3+cKXX>aY~jqQA{+dgZM&MvQiEzIp zB!j;t+4_XMJ--O7ZJsd^|0VS3HC5ohocLmW>)Z;=(O<0d6>RHFB}Ct^V(T+r8T{AK z&6l@c@Lx~7b2@L#`3>|b;5_yT{+sAii3{F2zXhyso-q;sZS<*xV*GdD^ck;=dA^Ho zzIWpuzrUSfoA2*u*v4Nw&E8Y6 zJ(Io3ej4jvi+&PV2QI{3jeKU}p3ZK$H`)=q9{pqxvCl%6Gq!}(Hg-9(2dn^Fv7PVP zi8Izc)sDIw(ESca-P6$JPUEE7k{>x>9>&x}VcX$JF_Bb6FtMAgpotb#Q;}<9H zdFb+I1LyHf<+|~^htCJD$M3TQTqyz!p7_5<9d7b3k=%6p03h%5si{hN^bl~HQ| z-5NL1Z!WR|q0CV&ii86zl*y zfw9(JrR{(qOLas{smBqltm8N5^`Hbcuv^-10B058y5-*pjMX3ChBqZ1@n7!EiEBc} zU3&|wGKHS(Wa?+mLSuKKkE*)US+vcqh6wVjtdxE_VZPAGEIr z)-qS!zI%|-_ua{-wC{V7?*l&eeLvD%W%T_3x;3Kj2hruCul9R@waitI@5qhl?!kNz z^*)3yANEb?t}E`{htZ9Zk2)Vgx6UFEc^^fW5Bp>2&KY$+j&6*6yl0<4-vR8Q-(26v zn}NQl^*wa&T-e`7FV6S_Y&q{w#QYGw*#Ae^a>jTLdy%(+ZoXo-BYy(q>}5UUt#ttM zr$GNz+)3yA8Mqn98zc8~up3;IVt$c0W9_F;&U5vQJsV}r`%CoVymw&B#k~6D%#VBH z8Ebo2t*4B7zd|qW(XX-PqMklE^S$@xdskyUzd?8Auz!p0cVssE<$8Yyn!r)OSpBZk z7=70DTVh>h%=LS8&ob`CAJFAuE`4(5$M?x^NzCy_bbI*SaE?ELI}5lh?f;+QjMX2p ze?jjmAlC9%xLAvM#zoHG(C;cBa{dly&SQc3#>M*eIq!1hKfu0ZuSNb7tOLF52?%MqhdN1z>az4R5fG%g9;2um|Gjao!S0euf%r{=YYaF1j z^V(PceyW@Z{F~ano&$VlffG3E4&>~DejvK%eGoFf6^Epl`N+5fhoZ~hNZq-}!+_iZ za36ISB7OXh>U#u`v$lHFJ{;Zti$K&~j4mIwABiq!ZSPdnQQpH|*#A+$KF)2tJ)ENx z>Ej&6JQ{QY=TMJ1mY_RFag9e{%SX(S= Date: Sun, 23 Oct 2022 16:04:58 +0800 Subject: [PATCH 10/13] Camera Director integrated Still has bug --- .../src/Application/SBApplication.cpp | 1 + SHADE_Application/src/Scenes/SBTestScene.cpp | 5 + SHADE_Engine/src/Camera/SHCameraComponent.cpp | 62 ++++- SHADE_Engine/src/Camera/SHCameraComponent.h | 2 + SHADE_Engine/src/Camera/SHCameraDirector.cpp | 65 +++++ SHADE_Engine/src/Camera/SHCameraDirector.h | 43 +++ SHADE_Engine/src/Camera/SHCameraSystem.cpp | 252 +++++++++++++----- SHADE_Engine/src/Camera/SHCameraSystem.h | 23 +- .../MiddleEnd/Interface/SHGraphicsSystem.cpp | 32 ++- .../MiddleEnd/Interface/SHRenderer.cpp | 27 +- .../Graphics/MiddleEnd/Interface/SHRenderer.h | 7 +- 11 files changed, 421 insertions(+), 98 deletions(-) create mode 100644 SHADE_Engine/src/Camera/SHCameraDirector.cpp create mode 100644 SHADE_Engine/src/Camera/SHCameraDirector.h diff --git a/SHADE_Application/src/Application/SBApplication.cpp b/SHADE_Application/src/Application/SBApplication.cpp index 8733e7b9..9bfd82de 100644 --- a/SHADE_Application/src/Application/SBApplication.cpp +++ b/SHADE_Application/src/Application/SBApplication.cpp @@ -93,6 +93,7 @@ namespace Sandbox SHSystemManager::RegisterRoutine(); SHSystemManager::RegisterRoutine(); + SHSystemManager::RegisterRoutine(); #ifdef SHEDITOR SHSystemManager::RegisterRoutine(); diff --git a/SHADE_Application/src/Scenes/SBTestScene.cpp b/SHADE_Application/src/Scenes/SBTestScene.cpp index f1d656ee..6b3fee1d 100644 --- a/SHADE_Application/src/Scenes/SBTestScene.cpp +++ b/SHADE_Application/src/Scenes/SBTestScene.cpp @@ -14,6 +14,7 @@ #include "Physics/Components/SHColliderComponent.h" #include "Assets/SHAssetManager.h" +#include "Camera/SHCameraComponent.h" using namespace SHADE; @@ -166,6 +167,10 @@ namespace Sandbox transformShowcase.SetWorldPosition({ 3.0f, -1.0f, -1.0f }); transformShowcase.SetLocalScale({ 5.0f, 5.0f, 5.0f }); scriptEngine->AddScript(raccoonShowcase, "RaccoonShowcase"); + + SHComponentManager::AddComponent(0); + SHComponentManager::RemoveComponent (0); + SHComponentManager::RemoveComponent (0); } void SBTestScene::Update(float dt) diff --git a/SHADE_Engine/src/Camera/SHCameraComponent.cpp b/SHADE_Engine/src/Camera/SHCameraComponent.cpp index 650ed3c5..5d49c887 100644 --- a/SHADE_Engine/src/Camera/SHCameraComponent.cpp +++ b/SHADE_Engine/src/Camera/SHCameraComponent.cpp @@ -1,13 +1,15 @@ #include "SHpch.h" #include "SHCameraComponent.h" #include "ECS_Base/Managers/SHComponentManager.h" - +#include "SHCameraSystem.h" +#include "ECS_Base/Managers/SHSystemManager.h" +#include "Math/Transform/SHTransformComponent.h" namespace SHADE { SHCameraComponent::SHCameraComponent() :yaw(0.0f), pitch(0.0f), roll(0.0f) - , width(1920.0f), height(1080.0f), zNear(0.01f), zFar(10000.0f), fov(90.0f), movementSpeed(1.0f), turnSpeed(1.0f) + , width(1920.0f), height(1080.0f), zNear(0.01f), zFar(10000.0f), fov(90.0f), movementSpeed(1.0f), turnSpeed(0.5f) , perspProj(true), dirtyView(true), dirtyProj(true) , viewMatrix(), projMatrix() , position() @@ -22,33 +24,69 @@ namespace SHADE void SHCameraComponent::SetYaw(float yaw) noexcept { this->yaw = yaw; + if (SHComponentManager::HasComponent(GetEID())) + { + auto transform = SHComponentManager::GetComponent(GetEID()); + SHVec3 rotation = transform->GetWorldRotation(); + transform->SetWorldRotation(SHVec3{rotation.x,yaw, rotation.z}); + } dirtyView = true; } void SHCameraComponent::SetPitch(float pitch) noexcept { this->pitch = pitch; + if (SHComponentManager::HasComponent(GetEID())) + { + auto transform = SHComponentManager::GetComponent(GetEID()); + SHVec3 rotation = transform->GetWorldRotation(); + transform->SetWorldRotation(SHVec3{ pitch,rotation.y, rotation.z }); + } dirtyView = true; } void SHCameraComponent::SetRoll(float roll) noexcept { this->roll = roll; + if (SHComponentManager::HasComponent(GetEID())) + { + auto transform = SHComponentManager::GetComponent(GetEID()); + SHVec3 rotation = transform->GetWorldRotation(); + transform->SetWorldRotation(SHVec3{ rotation.x,rotation.y, roll}); + } dirtyView = true; } void SHCameraComponent::SetPositionX(float x) noexcept { position.x = x; + if (SHComponentManager::HasComponent(GetEID())) + { + auto transform = SHComponentManager::GetComponent(GetEID()); + SHVec3 position = transform->GetWorldPosition(); + transform->SetWorldRotation(SHVec3{ x,position.y, position.z}); + } dirtyView = true; } void SHCameraComponent::SetPositionY(float y) noexcept { position.y = y; + if (SHComponentManager::HasComponent(GetEID())) + { + auto transform = SHComponentManager::GetComponent(GetEID()); + SHVec3 position = transform->GetWorldPosition(); + transform->SetWorldRotation(SHVec3{ position.x,y, position.z }); + } dirtyView = true; } void SHCameraComponent::SetPositionZ(float z) noexcept { position.z = z; + if (SHComponentManager::HasComponent(GetEID())) + { + auto transform = SHComponentManager::GetComponent(GetEID()); + SHVec3 position = transform->GetWorldPosition(); + transform->SetWorldRotation(SHVec3{ position.x,position.y, z }); + } dirtyView = true; } void SHCameraComponent::SetPosition(float x,float y, float z) noexcept @@ -56,11 +94,23 @@ namespace SHADE position.x = x; position.y = y; position.z = z; + if (SHComponentManager::HasComponent(GetEID())) + { + auto transform = SHComponentManager::GetComponent(GetEID()); + SHVec3 position = transform->GetWorldPosition(); + transform->SetWorldRotation(SHVec3{ x,y, z }); + } dirtyView = true; } void SHCameraComponent::SetPosition(SHVec3& pos) noexcept { this->position = pos; + if (SHComponentManager::HasComponent(GetEID())) + { + auto transform = SHComponentManager::GetComponent(GetEID()); + SHVec3 position = transform->GetWorldPosition(); + transform->SetWorldRotation(pos); + } dirtyView = true; } @@ -128,4 +178,12 @@ namespace SHADE return projMatrix; } + void SHCameraComponent::SetMainCamera(size_t directorCameraIndex) noexcept + { + auto system = SHSystemManager::GetSystem(); + system->GetDirector(directorCameraIndex)->SetMainCamera(*this); + } + + + } diff --git a/SHADE_Engine/src/Camera/SHCameraComponent.h b/SHADE_Engine/src/Camera/SHCameraComponent.h index c86fa160..1149b1e1 100644 --- a/SHADE_Engine/src/Camera/SHCameraComponent.h +++ b/SHADE_Engine/src/Camera/SHCameraComponent.h @@ -70,6 +70,8 @@ namespace SHADE const SHMatrix& GetViewMatrix() const noexcept; const SHMatrix& GetProjMatrix() const noexcept; + void SetMainCamera(size_t cameraDirectorIndex = 0) noexcept; + float movementSpeed; SHVec3 turnSpeed; diff --git a/SHADE_Engine/src/Camera/SHCameraDirector.cpp b/SHADE_Engine/src/Camera/SHCameraDirector.cpp new file mode 100644 index 00000000..559897c0 --- /dev/null +++ b/SHADE_Engine/src/Camera/SHCameraDirector.cpp @@ -0,0 +1,65 @@ +#include "SHpch.h" +#include "SHCameraDirector.h" +#include "SHCameraComponent.h" +#include "ECS_Base/Managers/SHComponentManager.h" +#include "ECS_Base/SHECSMacros.h" +#include "ECS_Base/Managers/SHEntityManager.h" +#include "Tools/SHLog.h" + +namespace SHADE +{ + SHCameraDirector::SHCameraDirector() + :mainCameraEID(MAX_EID), transitionCameraEID(MAX_EID) + { + } + + + SHMatrix SHCameraDirector::GetViewMatrix() const noexcept + { + return viewMatrix; + } + SHMatrix SHCameraDirector::GetProjMatrix() const noexcept + { + return projMatrix; + } + SHMatrix SHCameraDirector::GetVPMatrix() const noexcept + { + return projMatrix * viewMatrix; + } + + void SHCameraDirector::UpdateMatrix() noexcept + { + if (mainCameraEID == MAX_EID) + { + auto& dense = SHComponentManager::GetDense(); + if (dense.size() == 0) + { + return; + } + mainCameraEID = dense[0].GetEID(); + } + SHCameraComponent* camComponent = SHComponentManager::GetComponent_s(mainCameraEID); + if (!camComponent) + { + SHLOG_WARNING("Camera Director warning: Entity does not have a camera"); + } + else + { + viewMatrix = camComponent->GetViewMatrix(); + projMatrix = camComponent->GetProjMatrix(); + } + } + + void SHCameraDirector::SetMainCamera(SHCameraComponent& camera) noexcept + { + if (SHEntityManager::IsValidEID(camera.GetEID()) == false) + { + SHLOG_WARNING("Camera Director Warning: Attempting to set an invalid entity as main camera.") + return; + } + mainCameraEID = camera.GetEID(); + } + + + +} diff --git a/SHADE_Engine/src/Camera/SHCameraDirector.h b/SHADE_Engine/src/Camera/SHCameraDirector.h new file mode 100644 index 00000000..b1311147 --- /dev/null +++ b/SHADE_Engine/src/Camera/SHCameraDirector.h @@ -0,0 +1,43 @@ +#pragma once + +#include "SH_API.h" +#include "ECS_Base/Entity/SHEntity.h" +#include "Math/SHMatrix.h" +#include "Resource/Handle.h" + + +namespace SHADE +{ + class SHCameraComponent; + + + + class SH_API SHCameraDirector + { + public: + SHCameraDirector(); + ~SHCameraDirector() = default; + + + EntityID mainCameraEID; + EntityID transitionCameraEID; + + SHMatrix GetViewMatrix() const noexcept; + SHMatrix GetProjMatrix() const noexcept; + SHMatrix GetVPMatrix() const noexcept; + void UpdateMatrix() noexcept; + void SetMainCamera(SHCameraComponent& cam) noexcept; + + + private: + + + protected: + SHMatrix viewMatrix; + SHMatrix projMatrix; + + }; + + typedef Handle DirectorHandle; + +} diff --git a/SHADE_Engine/src/Camera/SHCameraSystem.cpp b/SHADE_Engine/src/Camera/SHCameraSystem.cpp index c9822b82..40b63294 100644 --- a/SHADE_Engine/src/Camera/SHCameraSystem.cpp +++ b/SHADE_Engine/src/Camera/SHCameraSystem.cpp @@ -2,67 +2,115 @@ #include "SHCameraSystem.h" #include "Math/SHMathHelpers.h" #include "Input/SHInputManager.h" - +#include "Math/Vector/SHVec2.h" +#include "ECS_Base/Managers/SHComponentManager.h" +#include "Math/Transform/SHTransformComponent.h" namespace SHADE { + void SHCameraSystem::UpdateEditorCamera(double dt) noexcept + { + + auto& camera = editorCamera; + SHVec3 view, right, UP; + GetCameraAxis(camera, view, right, UP); + if (SHInputManager::GetKey(SHInputManager::SH_KEYCODE::A)) + { + camera.position -= right * dt * camera.movementSpeed; + camera.dirtyView = true; + } + if (SHInputManager::GetKey(SHInputManager::SH_KEYCODE::D)) + { + camera.position += right * dt * camera.movementSpeed; + camera.dirtyView = true; + } + if (SHInputManager::GetKey(SHInputManager::SH_KEYCODE::W)) + { + camera.position += view * dt * camera.movementSpeed; + camera.dirtyView = true; + } + if (SHInputManager::GetKey(SHInputManager::SH_KEYCODE::S)) + { + camera.position -= view * dt * camera.movementSpeed; + camera.dirtyView = true; + } + if (SHInputManager::GetKey(SHInputManager::SH_KEYCODE::Q)) + { + camera.position += UP * dt * camera.movementSpeed; + camera.dirtyView = true; + } + if (SHInputManager::GetKey(SHInputManager::SH_KEYCODE::E)) + { + camera.position -= UP * dt * camera.movementSpeed; + camera.dirtyView = true; + } + if (SHInputManager::GetKey(SHInputManager::SH_KEYCODE::RMB)) + { + double mouseX, mouseY; + SHInputManager::GetMouseVelocity(&mouseX, &mouseY); + + //std::cout << camera.yaw << std::endl; + + camera.pitch -= mouseY * dt * camera.turnSpeed.x; + camera.yaw -= mouseX * dt * camera.turnSpeed.y; + camera.dirtyView = true; + } + + UpdateCameraComponent(editorCamera); + } void SHCameraSystem::EditorCameraUpdate::Execute(double dt) noexcept { SHCameraSystem* system = static_cast(GetSystem()); auto& camera = system->editorCamera; - SHVec3 target{ 0.0f,0.0f,-1.0f }; - SHVec3 up = { 0.0f,1.0f,0.0f }; - - - SHVec3::RotateY(target, SHMath::DegreesToRadians(camera.yaw)); - SHVec3::RotateX(target, SHMath::DegreesToRadians(camera.pitch)); - target += camera.position; - ////SHVec3::RotateZ(target, SHMath::DegreesToRadians(camera.roll)); - - //target = SHVec3::Normalise(target); - - SHVec3::RotateZ(up, camera.roll); - up = SHVec3::Normalise(up); - - - SHVec3 view = target - camera.position; view = SHVec3::Normalise(view); - SHVec3 right = SHVec3::Cross(view, up); right = SHVec3::Normalise(right); - const SHVec3 UP = SHVec3::Cross(view, right); - + SHVec3 view, right, UP; + system->GetCameraAxis(camera, view, right, UP); if (SHInputManager::GetKey(SHInputManager::SH_KEYCODE::A)) { - system->editorCamera.position -= right * dt * camera.movementSpeed; - system->editorCamera.dirtyView = true; + //std::cout << "Camera movement: "<editorCamera.position += right * dt * camera.movementSpeed; - system->editorCamera.dirtyView = true; + camera.position += right * dt * camera.movementSpeed; + camera.dirtyView = true; } if (SHInputManager::GetKey(SHInputManager::SH_KEYCODE::W)) { - system->editorCamera.position += view * dt * camera.movementSpeed; - system->editorCamera.dirtyView = true; + camera.position += view * dt * camera.movementSpeed; + camera.dirtyView = true; } if (SHInputManager::GetKey(SHInputManager::SH_KEYCODE::S)) { - system->editorCamera.position -= view * dt * camera.movementSpeed; - system->editorCamera.dirtyView = true; + camera.position -= view * dt * camera.movementSpeed; + camera.dirtyView = true; } if (SHInputManager::GetKey(SHInputManager::SH_KEYCODE::Q)) { - system->editorCamera.position += UP * dt * camera.movementSpeed; - system->editorCamera.dirtyView = true; + camera.position += UP * dt * camera.movementSpeed; + camera.dirtyView = true; } if (SHInputManager::GetKey(SHInputManager::SH_KEYCODE::E)) { - system->editorCamera.position -= UP * dt * camera.movementSpeed; - system->editorCamera.dirtyView = true; + camera.position -= UP * dt * camera.movementSpeed; + camera.dirtyView = true; + } + if (SHInputManager::GetKey(SHInputManager::SH_KEYCODE::RMB)) + { + double mouseX, mouseY; + SHInputManager::GetMouseVelocity(&mouseX,&mouseY); + + //std::cout << camera.yaw << std::endl; + + camera.pitch -= mouseY * dt * camera.turnSpeed.x; + camera.yaw -= mouseX * dt * camera.turnSpeed.y; + camera.dirtyView = true; } + //std::cout << "Camera position: " << camera.position.x << " " << camera.position.y << std::endl; system->UpdateCameraComponent(system->editorCamera); } @@ -88,26 +136,26 @@ namespace SHADE void SHCameraSystem::UpdateCameraComponent(SHCameraComponent& camera) noexcept { + if (SHComponentManager::HasComponent(camera.GetEID()) == true && &camera != &editorCamera) + { + auto transform = SHComponentManager::GetComponent(camera.GetEID()); + SHVec3 rotation = transform->GetWorldRotation(); + camera.pitch = SHMath::RadiansToDegrees(rotation.x); + camera.yaw = SHMath::RadiansToDegrees(rotation.y); + camera.roll = SHMath::RadiansToDegrees(rotation.z); + camera.position = transform->GetWorldPosition(); + } + + if (camera.dirtyView) { - SHVec3 target{ 0.0f,0.0f,-1.0f }; - SHVec3 up = { 0.0f,1.0f,0.0f }; + + SHVec3 view, right, UP; + + //ClampCameraRotation(camera); - SHVec3::RotateY(target, SHMath::DegreesToRadians(camera.yaw)); - SHVec3::RotateX(target, SHMath::DegreesToRadians(camera.pitch)); - target += camera.position; - ////SHVec3::RotateZ(target, SHMath::DegreesToRadians(camera.roll)); - - //target = SHVec3::Normalise(target); - - SHVec3::RotateZ(up, camera.roll); - up = SHVec3::Normalise(up); - - - SHVec3 view = target - camera.position; view = SHVec3::Normalise(view); - SHVec3 right = SHVec3::Cross(view, up); right = SHVec3::Normalise(right); - const SHVec3 UP = SHVec3::Cross(view, right); + GetCameraAxis(camera, view, right, UP); camera.viewMatrix = SHMatrix::Identity; camera.viewMatrix(0, 0) = right[0]; @@ -143,38 +191,100 @@ namespace SHADE camera.projMatrix(3, 2) = 1.0f; camera.projMatrix(2, 3) = -(camera.zFar * camera.zNear) / (camera.zFar - camera.zNear); - //const float fov_rad = SHMath::DegreesToRadians(camera.fov); - //const float focal_length = 1.0f / tan(fov_rad * 0.5f); - - //camera.projMatrix(0,0) = focal_length / camera.GetAspectRatio(); - //camera.projMatrix(1,1) = -focal_length; - //camera.projMatrix(2,2) = camera.zNear / (camera.zFar - camera.zNear); - //camera.projMatrix(2,3) = camera.zFar * (camera.zNear / (camera.zFar - camera.zNear)); - //camera.projMatrix(3,2) = -1.0f; - //camera.projMatrix(3,3) = 0.0f; - - //camera.projMatrix = SHMatrix::Inverse(camera.projMatrix); - + camera.dirtyProj = false; } else { - const float R = camera.width * 0.5f; - const float L = -R; - const float T = camera.height * 0.5f; - const float B = -T; + //const float R = camera.width * 0.5f; + //const float L = -R; + //const float T = camera.height * 0.5f; + //const float B = -T; - camera.projMatrix = SHMatrix::Identity; - camera.projMatrix(0, 0) = 2.0f / (R - L); - camera.projMatrix(1, 1) = 2.0f / (B - T); - camera.projMatrix(2, 2) = 1.0f / (camera.zFar - camera.zNear); - camera.projMatrix(3, 0) = -(R + L) / (R - L); - camera.projMatrix(3, 1) = -(B + T) / (B - T); - camera.projMatrix(3, 2) = -camera.zNear / (camera.zFar - camera.zNear); + //camera.projMatrix = SHMatrix::Identity; + //camera.projMatrix(0, 0) = 2.0f / (R - L); + //camera.projMatrix(1, 1) = 2.0f / (B - T); + //camera.projMatrix(2, 2) = 1.0f / (camera.zFar - camera.zNear); + //camera.projMatrix(3, 0) = -(R + L) / (R - L); + //camera.projMatrix(3, 1) = -(B + T) / (B - T); + //camera.projMatrix(3, 2) = -camera.zNear / (camera.zFar - camera.zNear); camera.dirtyProj = false; } } } + void SHCameraSystem::GetCameraAxis(SHCameraComponent const& camera, SHVec3& forward, SHVec3& right, SHVec3& upVec) const noexcept + { + SHVec3 target{ 0.0f,0.0f,-1.0f }; + SHVec3 up = { 0.0f,1.0f,0.0f }; + + + target = SHVec3::RotateY(target, SHMath::DegreesToRadians(camera.yaw)); + target =SHVec3::RotateX(target, SHMath::DegreesToRadians(camera.pitch)); + target += camera.position; + ////SHVec3::RotateZ(target, SHMath::DegreesToRadians(camera.roll)); + + //target = SHVec3::Normalise(target); + + SHVec3::RotateZ(up, camera.roll); + up = SHVec3::Normalise(up); + + + forward = target - camera.position; forward = SHVec3::Normalise(forward); + right = SHVec3::Cross(forward, up); right = SHVec3::Normalise(right); + upVec = SHVec3::Cross(forward, right); + } + + void SHCameraSystem::CameraSystemUpdate::Execute(double dt) noexcept + { + SHCameraSystem* system = static_cast(GetSystem()); + auto& dense = SHComponentManager::GetDense(); + for (auto& cam : dense) + { + system->UpdateCameraComponent(cam); + } + for (auto& handle : system->directorHandleList) + { + handle->UpdateMatrix(); + } + + + } + + + DirectorHandle SHCameraSystem::CreateDirector() noexcept + { + auto handle = directorLibrary.Create(); + directorHandleList.emplace_back(handle); + return handle; + } + + DirectorHandle SHCameraSystem::GetDirector(size_t index) noexcept + { + if (index < directorHandleList.size()) + { + return directorHandleList[index]; + } + else + { + return CreateDirector(); + } + } + void SHCameraSystem::ClampCameraRotation(SHCameraComponent& camera) noexcept + { + + + + if (camera.pitch > 85) + camera.SetPitch(85); + if (camera.pitch < -85) + camera.SetPitch(-85); + if (camera.roll > 85) + camera.SetRoll(85); + if (camera.roll < -85) + camera.SetRoll(-85); + + } + } diff --git a/SHADE_Engine/src/Camera/SHCameraSystem.h b/SHADE_Engine/src/Camera/SHCameraSystem.h index fe7fd145..dacda574 100644 --- a/SHADE_Engine/src/Camera/SHCameraSystem.h +++ b/SHADE_Engine/src/Camera/SHCameraSystem.h @@ -3,9 +3,10 @@ #include "ECS_Base/System/SHSystem.h" #include "SHCameraComponent.h" #include "ECS_Base/System/SHSystemRoutine.h" +#include "Resource/ResourceLibrary.h" +#include "SHCameraDirector.h" #include "SH_API.h" - namespace SHADE { class SH_API SHCameraSystem final : public SHSystem @@ -14,8 +15,9 @@ namespace SHADE //A camera component that represents editor camera. //This is not tied to any entity. Hence this EID should not be used. SHCameraComponent editorCamera; - + ResourceLibrary directorLibrary; + std::vector directorHandleList; public: SHCameraSystem(void) = default; @@ -34,12 +36,27 @@ namespace SHADE }; friend class EditorCameraUpdate; - SHCameraComponent* GetEditorCamera (void) noexcept; + class SH_API CameraSystemUpdate final: public SHSystemRoutine + { + public: + CameraSystemUpdate() : SHSystemRoutine("Camera System Update", false) {}; + virtual void Execute(double dt)noexcept override final; + }; + friend class CameraSystemUpdate; + + SHCameraComponent* GetEditorCamera (void) noexcept; + void GetCameraAxis(SHCameraComponent const& camera, SHVec3& forward, SHVec3& right, SHVec3& up) const noexcept; + DirectorHandle CreateDirector() noexcept; + DirectorHandle GetDirector(size_t index) noexcept; + void ClampCameraRotation(SHCameraComponent& camera) noexcept; + void UpdateEditorCamera(double dt) noexcept; protected: void UpdateCameraComponent(SHCameraComponent& camera) noexcept; + + }; diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp index 992cbdf1..cbf3ad95 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp @@ -147,6 +147,7 @@ namespace SHADE /*-----------------------------------------------------------------------*/ auto windowDims = window->GetWindowSize(); + auto cameraSystem = SHSystemManager::GetSystem(); // Set Up Cameras screenCamera = resourceManager.Create(); @@ -198,6 +199,8 @@ namespace SHADE worldRenderer = worldViewport->AddRenderer(resourceManager, swapchain->GetNumImages(), renderContextCmdPools, descPool, SHGraphicsGlobalData::GetDescSetLayouts()[SHGraphicsConstants::DescriptorSetIndex::HIGH_FREQUENCY_GLOBALS], worldRenderGraph); worldRenderer->SetCamera(worldCamera); + worldRenderer->SetCameraDirector(cameraSystem->CreateDirector()); + auto cubeVS = shaderModuleLibrary.GetShaderModule("TestCubeVs.glsl"); auto cubeFS = shaderModuleLibrary.GetShaderModule("TestCubeFs.glsl"); @@ -335,21 +338,7 @@ namespace SHADE auto cameraSystem = SHSystemManager::GetSystem(); -#ifdef SHEDITOR - auto editorSystem = SHSystemManager::GetSystem(); - if (editorSystem->editorState != SHEditor::State::PLAY) - { - worldRenderer->SetViewProjectionMatrix(SHMatrix::Transpose(cameraSystem->GetEditorCamera()->GetProjMatrix() * cameraSystem->GetEditorCamera()->GetViewMatrix())); - } - else - { - // main camera - } - -#else - // main camera -#endif // For every viewport for (int vpIndex = 0; vpIndex < static_cast(viewports.size()); ++vpIndex) @@ -399,7 +388,22 @@ namespace SHADE } // bind camera data + //renderers[renIndex]->UpdateDataAndBind(currentCmdBuffer, frameIndex); + +#ifdef SHEDITOR + if (renderers[renIndex] == worldRenderer) + { + auto editorSystem = SHSystemManager::GetSystem(); + if (editorSystem->editorState != SHEditor::State::PLAY) + worldRenderer->UpdateDataAndBind(currentCmdBuffer, frameIndex, SHMatrix::Transpose(cameraSystem->GetEditorCamera()->GetProjMatrix() * cameraSystem->GetEditorCamera()->GetViewMatrix())); + else + renderers[renIndex]->UpdateDataAndBind(currentCmdBuffer, frameIndex); + } + else + renderers[renIndex]->UpdateDataAndBind(currentCmdBuffer, frameIndex); +#else renderers[renIndex]->UpdateDataAndBind(currentCmdBuffer, frameIndex); +#endif // Draw first renderers[renIndex]->Draw(frameIndex, descPool); diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderer.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderer.cpp index a1806ccd..962130be 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderer.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderer.cpp @@ -21,6 +21,7 @@ of DigiPen Institute of Technology is prohibited. #include "Graphics/MiddleEnd/Interface/SHGraphicsConstants.h" #include "Graphics/Descriptors/SHVkDescriptorSetGroup.h" #include "Graphics/Buffers/SHVkBuffer.h" +#include "Camera/SHCameraDirector.h" namespace SHADE { @@ -65,6 +66,11 @@ namespace SHADE camera = _camera; } + void SHRenderer::SetCameraDirector(Handle director) noexcept + { + cameraDirector = director; + } + /*-----------------------------------------------------------------------------------*/ /* Drawing Functions */ /*-----------------------------------------------------------------------------------*/ @@ -75,17 +81,24 @@ namespace SHADE void SHRenderer::UpdateDataAndBind(Handle cmdBuffer, uint32_t frameIndex) noexcept { - if (camera) + if (camera && cameraDirector) { - //cpuCameraData.viewProjectionMatrix = camera->GetViewProjectionMatrix(); - cameraBuffer->WriteToMemory(&cpuCameraData, sizeof(SHShaderCameraData), 0, cameraDataAlignedSize * frameIndex); - - std::array dynamicOffsets{ frameIndex * cameraDataAlignedSize }; - - cmdBuffer->BindDescriptorSet(cameraDescriptorSet, SH_PIPELINE_TYPE::GRAPHICS, SHGraphicsConstants::DescriptorSetIndex::HIGH_FREQUENCY_GLOBALS, std::span{ dynamicOffsets.data(), 1 }); + UpdateDataAndBind(cmdBuffer, frameIndex, SHMatrix::Transpose(cameraDirector->GetVPMatrix())); } } + void SHRenderer::UpdateDataAndBind(Handle cmdBuffer, uint32_t frameIndex, SHMatrix exteriorMatrix) noexcept + { + SetViewProjectionMatrix(exteriorMatrix); + + //cpuCameraData.viewProjectionMatrix = camera->GetViewProjectionMatrix(); + cameraBuffer->WriteToMemory(&cpuCameraData, sizeof(SHShaderCameraData), 0, cameraDataAlignedSize * frameIndex); + + std::array dynamicOffsets{ frameIndex * cameraDataAlignedSize }; + + cmdBuffer->BindDescriptorSet(cameraDescriptorSet, SH_PIPELINE_TYPE::GRAPHICS, SHGraphicsConstants::DescriptorSetIndex::HIGH_FREQUENCY_GLOBALS, std::span{ dynamicOffsets.data(), 1 }); + } + void SHRenderer::UpdateCameraDataToBuffer(void) noexcept { } diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderer.h b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderer.h index 57c63e7f..a70e1996 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderer.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderer.h @@ -40,6 +40,7 @@ namespace SHADE class SHGraphicsGlobalData; class SHVkDescriptorPool; class SHVkBuffer; + class SHCameraDirector; struct SHShaderCameraData { @@ -71,12 +72,14 @@ namespace SHADE /* Camera Registration */ /*-----------------------------------------------------------------------------*/ void SetCamera(Handle _camera); + void SetCameraDirector (Handle director) noexcept; /*-----------------------------------------------------------------------------*/ /* Drawing Functions */ /*-----------------------------------------------------------------------------*/ void Draw(uint32_t frameIndex, Handle descPool) noexcept; - void UpdateDataAndBind (Handle cmdBuffer, uint32_t frameIndex) noexcept; + void UpdateDataAndBind(Handle cmdBuffer, uint32_t frameIndex) noexcept; + void UpdateDataAndBind(Handle cmdBuffer, uint32_t frameIndex, SHMatrix exteriorMatrix) noexcept; void UpdateCameraDataToBuffer (void) noexcept; void SetViewProjectionMatrix (SHMatrix const& vpMatrix) noexcept; @@ -99,6 +102,8 @@ namespace SHADE Handle cameraDescriptorSet; Handle cameraBuffer; + Handle cameraDirector; + // we really only need 1 copy even though we need %swapchainImages copies for // GPU. SHShaderCameraData cpuCameraData; From a81ef91373ff317e74f5545a3d3d2bcf04071faa Mon Sep 17 00:00:00 2001 From: Brandon Mak Date: Sun, 23 Oct 2022 16:47:39 +0800 Subject: [PATCH 11/13] Removed some commented code --- .../src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp index 0de5af17..7ecd92d2 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp @@ -185,10 +185,6 @@ namespace SHADE gBufferWriteSubpass->AddColorOutput("Entity ID"); gBufferWriteSubpass->AddDepthOutput("Depth Buffer", SH_ATT_DESC_TYPE_FLAGS::DEPTH_STENCIL); - // We do this to just transition our scene layout to shader read - //auto sceneLayoutTransitionSubpass = node->AddSubpass("Scene Layout Transition"); - //sceneLayoutTransitionSubpass->AddGeneralInput("Scene"); - auto greyscale = shaderModuleLibrary.GetShaderModule("KirschCs.glsl"); node->AddNodeCompute (greyscale, {"Scene Pre-Process", "Scene"}); From a83d1f8f04ae82332d9fd065b34eec911e2e4ff3 Mon Sep 17 00:00:00 2001 From: Xiao Qi Date: Sun, 23 Oct 2022 16:55:57 +0800 Subject: [PATCH 12/13] Removed line that loaded all assets Separated template function in asset manager into hpp file Fixed bug in checking map contains --- SHADE_Engine/src/Assets/SHAssetManager.cpp | 17 +++++------- SHADE_Engine/src/Assets/SHAssetManager.h | 22 +++------------- SHADE_Engine/src/Assets/SHAssetManager.hpp | 26 +++++++++++++++++++ .../src/Resource/SHResourceManager.hpp | 2 +- 4 files changed, 37 insertions(+), 30 deletions(-) create mode 100644 SHADE_Engine/src/Assets/SHAssetManager.hpp diff --git a/SHADE_Engine/src/Assets/SHAssetManager.cpp b/SHADE_Engine/src/Assets/SHAssetManager.cpp index bcae992e..3032ba51 100644 --- a/SHADE_Engine/src/Assets/SHAssetManager.cpp +++ b/SHADE_Engine/src/Assets/SHAssetManager.cpp @@ -56,18 +56,15 @@ namespace SHADE ****************************************************************************/ void SHAssetManager::Unload() noexcept { - for (auto const& asset : assetCollection) - { - SHAssetMetaHandler::WriteMetaData(asset); - } + } - void SHAssetManager::Unload(AssetID assetId) noexcept - { - // TODO - } + void SHAssetManager::Unload(AssetID assetId) noexcept + { + // TODO + } - AssetPath SHAssetManager::GenerateLocalPath(AssetPath path) noexcept + AssetPath SHAssetManager::GenerateLocalPath(AssetPath path) noexcept { if (!IsRecognised(path.extension().string().c_str())) { @@ -256,7 +253,7 @@ namespace SHADE { InitLoaders(); BuildAssetCollection(); - LoadAllData(); + //LoadAllData(); } /**************************************************************************** diff --git a/SHADE_Engine/src/Assets/SHAssetManager.h b/SHADE_Engine/src/Assets/SHAssetManager.h index 4c1ded71..9ee7ab92 100644 --- a/SHADE_Engine/src/Assets/SHAssetManager.h +++ b/SHADE_Engine/src/Assets/SHAssetManager.h @@ -76,25 +76,7 @@ namespace SHADE // -------------------------------------------------------------------------/ template - static std::enable_if_t, T const * const> GetData(AssetID id) noexcept - { - if (assetData.contains(id)) - { - for (auto const& asset : assetCollection) - { - if (asset.id == id) - { - assetData.emplace(id, LoadData(asset)); - return dynamic_cast(assetData[id]); - } - } - - SHLOG_ERROR("Asset ID provided does not exist: {}", id); - return nullptr; - } - - return dynamic_cast(assetData[id]); - } + static std::enable_if_t, T const* const> GetData(AssetID id) noexcept; private: /**************************************************************************** * \brief Load resource data into memory @@ -121,3 +103,5 @@ namespace SHADE static std::unordered_map assetData; }; } + +#include "SHAssetManager.hpp" diff --git a/SHADE_Engine/src/Assets/SHAssetManager.hpp b/SHADE_Engine/src/Assets/SHAssetManager.hpp new file mode 100644 index 00000000..6c420778 --- /dev/null +++ b/SHADE_Engine/src/Assets/SHAssetManager.hpp @@ -0,0 +1,26 @@ + +#include "SHAssetManager.h" + +namespace SHADE +{ + template + std::enable_if_t, T const* const> SHAssetManager::GetData(AssetID id) noexcept + { + if (!assetData.contains(id)) + { + for (auto const& asset : assetCollection) + { + if (asset.id == id) + { + assetData.emplace(id, LoadData(asset)); + return dynamic_cast(assetData[id]); + } + } + + SHLOG_ERROR("Asset ID provided does not exist: {}", id); + return nullptr; + } + + return dynamic_cast(assetData[id]); + } +} diff --git a/SHADE_Engine/src/Resource/SHResourceManager.hpp b/SHADE_Engine/src/Resource/SHResourceManager.hpp index fb0dcc6a..cff4e84b 100644 --- a/SHADE_Engine/src/Resource/SHResourceManager.hpp +++ b/SHADE_Engine/src/Resource/SHResourceManager.hpp @@ -134,7 +134,7 @@ namespace SHADE /* Query Functions */ /*-----------------------------------------------------------------------------------*/ template - static std::optional SHResourceManager::GetAssetID(Handle handle) + std::optional SHResourceManager::GetAssetID(Handle handle) { const Handle GENERIC_HANDLE = Handle(handle); auto [typedHandleMap, typedAssetIdMap] = getAssetHandleMap(); From f9a28c81d4ab01f182114524119b8ef290627ad8 Mon Sep 17 00:00:00 2001 From: Xiao Qi Date: Sun, 23 Oct 2022 17:18:46 +0800 Subject: [PATCH 13/13] Fixed vulkan breaking error --- SHADE_Application/src/Scenes/SBTestScene.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SHADE_Application/src/Scenes/SBTestScene.cpp b/SHADE_Application/src/Scenes/SBTestScene.cpp index b414ecaf..0c06a092 100644 --- a/SHADE_Application/src/Scenes/SBTestScene.cpp +++ b/SHADE_Application/src/Scenes/SBTestScene.cpp @@ -52,7 +52,7 @@ namespace Sandbox if (asset.name == "Cube.012") handles.emplace_back(SHResourceManager::LoadOrGet(asset.id)); break; - case AssetType::TEXTURE: + case AssetType::IMAGE: texHandles.emplace_back(SHResourceManager::LoadOrGet(asset.id)); break; }