From d4e3aaa59b57afb3ceaca1bbf2d822badc6f53c2 Mon Sep 17 00:00:00 2001 From: __prav__ Date: Sun, 14 Dec 2025 16:01:12 -0500 Subject: [PATCH 01/36] wip: glow material addition --- Engine/include/Popcorn/Core/Helpers.h | 46 +++++++++++++---- .../Vulkan/RenderFlows/RenderFlowVk.h | 3 -- Engine/shaders/vulkan/composite.frag | 5 +- Engine/shaders/vulkan/lighting.frag | 2 +- Engine/src/Popcorn/Loaders/GltfLoader.cpp | 49 +++++++++---------- .../Popcorn/Platform/Vulkan/RendererVk.cpp | 1 + 6 files changed, 64 insertions(+), 42 deletions(-) diff --git a/Engine/include/Popcorn/Core/Helpers.h b/Engine/include/Popcorn/Core/Helpers.h index 942efd51..087036b4 100644 --- a/Engine/include/Popcorn/Core/Helpers.h +++ b/Engine/include/Popcorn/Core/Helpers.h @@ -4,6 +4,7 @@ #include #include #include +#include #ifdef PC_DEBUG #include @@ -12,37 +13,62 @@ #endif ENGINE_NAMESPACE_BEGIN -constexpr std::size_t shift_l(std::size_t n) { return 1 << n; } + +// --- TYPES & VALUES ------------------------------------------------------ +// --- TYPES & VALUES ------------------------------------------------------ +// --- TYPES & VALUES ------------------------------------------------------ +using PC_Byte_t = uint8_t; + +extern int PC_PRINT_LEVEL; enum TagType { Constr, Destr, Print }; -using byte_t = uint8_t; +// --- BITWISE HELPERS ----------------------------------------------------- +// --- BITWISE HELPERS ----------------------------------------------------- +// --- BITWISE HELPERS ----------------------------------------------------- +constexpr std::size_t PC_ShiftLeft(std::size_t n) { return 1 << n; } + +// --- STRING HELPERS ------------------------------------------------------ +// --- STRING HELPERS ------------------------------------------------------ +// --- STRING HELPERS ------------------------------------------------------ +[[nodiscard]] static bool PC_StrEndsWith(const char *s, const char *suffix) { + if (!s || !suffix) + return false; -extern int PC_print_lvl; + size_t sLen = strlen(s); + size_t suffixLen = strlen(suffix); + if (sLen < suffixLen) + return false; + + return strcmp(s + sLen - suffixLen, suffix) == 0; +} + +// --- LOGGING HELPERS ----------------------------------------------------- +// --- LOGGING HELPERS ----------------------------------------------------- +// --- LOGGING HELPERS ----------------------------------------------------- static void PC_Print(const std::string &msg, const TagType tag, const std::string &className) { - - if (PC_print_lvl < 0) { + if (PC_PRINT_LEVEL < 0) { std::cout << "MISSING CONSTRUCTOR MESSAGE" << '\n'; return; }; if (tag == TagType::Constr) { - PC_print_lvl++; + PC_PRINT_LEVEL++; } else if (tag == TagType::Destr) - PC_print_lvl--; + PC_PRINT_LEVEL--; std::stringstream ss; - auto lvl = PC_print_lvl < 10 ? " " + std::to_string(PC_print_lvl) - : std::to_string(PC_print_lvl); + auto lvl = PC_PRINT_LEVEL < 10 ? " " + std::to_string(PC_PRINT_LEVEL) + : std::to_string(PC_PRINT_LEVEL); if (tag == TagType::Print) { lvl = " "; }; ss << lvl << " "; - for (int i = 0; i < std::min(PC_print_lvl, 10); ++i) { + for (int i = 0; i < std::min(PC_PRINT_LEVEL, 10); ++i) { ss << "| "; } diff --git a/Engine/include/Popcorn/Platform/Vulkan/RenderFlows/RenderFlowVk.h b/Engine/include/Popcorn/Platform/Vulkan/RenderFlows/RenderFlowVk.h index 014d9fec..59902876 100644 --- a/Engine/include/Popcorn/Platform/Vulkan/RenderFlows/RenderFlowVk.h +++ b/Engine/include/Popcorn/Platform/Vulkan/RenderFlows/RenderFlowVk.h @@ -19,9 +19,6 @@ ENGINE_NAMESPACE_BEGIN GFX_NAMESPACE_BEGIN -// TODO: Refactor -// - Vulkan specific for now. -// - Make it platform agnostic class RenderFlowVk { public: RenderFlowVk(); diff --git a/Engine/shaders/vulkan/composite.frag b/Engine/shaders/vulkan/composite.frag index fee1bfbe..ad91373f 100644 --- a/Engine/shaders/vulkan/composite.frag +++ b/Engine/shaders/vulkan/composite.frag @@ -38,8 +38,11 @@ void main() { // vec3 fogColor = vec3(0.020, 0.067, 0.102); // cyan // vec3 fogColor = vec3(0.122, 0.122, 0.027); // cyan // vec3 fogColor = vec3(0.090, 0.020, 0.039); // cyan - vec3 darkCyan = vec3(0.063, 0.200, 0.196); + // vec3 darkCyan = vec3(0.063, 0.200, 0.196); // present + // vec3 darkCyan = vec3(0.0, 0.0, 0.0); // present + // vec3 darkCyan = vec3(0.024, 0.122, 0.149); + vec3 darkCyan = vec3(0.259, 0.000, 0.125); // vec3 darkViolet = vec3(0.047, 0.004, 0.071); // vec3 darkViolet = vec3(0.043, 0.000, 0.078); // vec3 darkViolet = vec3(0.031, 0.000, 0.071); diff --git a/Engine/shaders/vulkan/lighting.frag b/Engine/shaders/vulkan/lighting.frag index c70c005e..3b257851 100644 --- a/Engine/shaders/vulkan/lighting.frag +++ b/Engine/shaders/vulkan/lighting.frag @@ -117,7 +117,7 @@ void main() { // float ambient = 0.0025; // float ambient = 0.1; - float ambient = 0.08; + float ambient = 0.02; finalColor += albedo * ambient; // Ambient outColor = vec4(finalColor, 1.0); diff --git a/Engine/src/Popcorn/Loaders/GltfLoader.cpp b/Engine/src/Popcorn/Loaders/GltfLoader.cpp index a088d5e5..3d771c8a 100644 --- a/Engine/src/Popcorn/Loaders/GltfLoader.cpp +++ b/Engine/src/Popcorn/Loaders/GltfLoader.cpp @@ -13,6 +13,7 @@ #include "LoaderUtils.h" #include "LoadersDefs.h" #include "Material.h" +#include "MaterialTypes.h" #include "Mesh.h" #include "Shader.h" #include "SplineFactory.h" @@ -442,20 +443,14 @@ GltfLoader::ExtractMaterialData(const tinygltf::Model &model, MaterialTypes GltfLoader::GetGltfMaterialType(const tinygltf::Material &material) { - const auto &pbr = material.pbrMetallicRoughness; + const char *matName = material.name.c_str(); - // Determine material type - bool isPBR = pbr.metallicFactor > 0.0f || pbr.roughnessFactor > 0.0f || - material.normalTexture.index != -1 || - material.occlusionTexture.index != -1; - - if (isPBR) { - PC_PRINT("PBR Mat", TagType::Print, "GltfLoader.cpp") - return MaterialTypes::PbrMat; - } else { - PC_PRINT("Basic Mat", TagType::Print, "GltfLoader.cpp") + const char *suffix = "_unlit"; + if (PC_StrEndsWith(matName, suffix)) { return MaterialTypes::BasicMat; - } + } else { + return MaterialTypes::PbrMat; + }; } // @@ -470,9 +465,9 @@ GltfLoader::GetGltfMaterialType(const tinygltf::Material &material) { VertexBuffer * GltfLoader::ExtractVertexBuffer(const tinygltf::Model &model, const tinygltf::Primitive &primitive) { - const byte_t *posData = nullptr; - const byte_t *normData = nullptr; - const byte_t *uvData = nullptr; + const PC_Byte_t *posData = nullptr; + const PC_Byte_t *normData = nullptr; + const PC_Byte_t *uvData = nullptr; size_t posStride = 0; size_t normStride = 0; @@ -494,7 +489,7 @@ GltfLoader::ExtractVertexBuffer(const tinygltf::Model &model, const auto &posView = model.bufferViews[posAccessor.bufferView]; const auto &posBuffer = model.buffers[posView.buffer]; - posData = reinterpret_cast( + posData = reinterpret_cast( posBuffer.data.data() + posAccessor.byteOffset + posView.byteOffset); posStride = posView.byteStride ? posView.byteStride : 3 * sizeof(float); posByteSize = tinygltf::GetComponentSizeInBytes(posAccessor.componentType) * @@ -512,7 +507,7 @@ GltfLoader::ExtractVertexBuffer(const tinygltf::Model &model, model.bufferViews[normAccessor.bufferView]; // normView is HERE const auto &normBuffer = model.buffers[normView.buffer]; - normData = reinterpret_cast( + normData = reinterpret_cast( normBuffer.data.data() + normAccessor.byteOffset + normView.byteOffset); normStride = normView.byteStride ? normView.byteStride : 3 * sizeof(float); normByteSize = @@ -534,7 +529,7 @@ GltfLoader::ExtractVertexBuffer(const tinygltf::Model &model, model.bufferViews[uvAccessor.bufferView]; // uvView is HERE const auto &uvBuffer = model.buffers[uvView.buffer]; - uvData = reinterpret_cast( + uvData = reinterpret_cast( uvBuffer.data.data() + uvAccessor.byteOffset + uvView.byteOffset); uvStride = uvView.byteStride ? uvView.byteStride : 2 * sizeof(float); uvByteSize = @@ -564,14 +559,14 @@ GltfLoader::ExtractVertexBuffer(const tinygltf::Model &model, size_t baseOffset = i * totalAttrByteSize; size_t cpyOffset = 0; - const byte_t *pos = - reinterpret_cast(posData + i * posStride); + const PC_Byte_t *pos = + reinterpret_cast(posData + i * posStride); vertices->Fill(pos, posByteSize, baseOffset + cpyOffset); cpyOffset += posByteSize; if (normData) { - const byte_t *norm = - reinterpret_cast(normData + i * normStride); + const PC_Byte_t *norm = + reinterpret_cast(normData + i * normStride); vertices->Fill(norm, normByteSize, baseOffset + cpyOffset); cpyOffset += normByteSize; } else { @@ -581,8 +576,8 @@ GltfLoader::ExtractVertexBuffer(const tinygltf::Model &model, } if (uvData) { - const byte_t *uv = - reinterpret_cast(uvData + i * uvStride); + const PC_Byte_t *uv = + reinterpret_cast(uvData + i * uvStride); vertices->Fill(uv, uvByteSize, baseOffset + cpyOffset); cpyOffset += uvByteSize; } else { @@ -606,8 +601,8 @@ GltfLoader::ExtractIndexBuffer(const tinygltf::Model &model, const auto &indexView = model.bufferViews[indexAccessor.bufferView]; const auto &gltfIndexBuffer = model.buffers[indexView.buffer]; - const byte_t *srcData = gltfIndexBuffer.data.data() + indexView.byteOffset + - indexAccessor.byteOffset; + const PC_Byte_t *srcData = gltfIndexBuffer.data.data() + + indexView.byteOffset + indexAccessor.byteOffset; // Handle stride (distance between indices in bytes) // size_t stride = indexView.byteStride; @@ -639,7 +634,7 @@ GltfLoader::ExtractIndexBuffer(const tinygltf::Model &model, // Convert indices to 32-bit for (size_t i = 0; i < indexCount; ++i) { const size_t offset = i * stride; - const byte_t *src = srcData + offset; + const PC_Byte_t *src = srcData + offset; uint32_t indexValue = 0; switch (indexAccessor.componentType) { diff --git a/Engine/src/Popcorn/Platform/Vulkan/RendererVk.cpp b/Engine/src/Popcorn/Platform/Vulkan/RendererVk.cpp index 19f9599a..04252af5 100644 --- a/Engine/src/Popcorn/Platform/Vulkan/RendererVk.cpp +++ b/Engine/src/Popcorn/Platform/Vulkan/RendererVk.cpp @@ -183,6 +183,7 @@ void RendererVk::ProcessGameObjectNode(GameObject *node) { // Recursive case Popcorn::Gfx::GameObjectTypes::Mesh: // { auto *mesh = static_cast(node); + for (auto &basicSubmesh : mesh->GetSubmeshes()) { RenderFlowVk::RegisterMaterialAndSubmesh(&basicSubmesh); } From dfb55f836944143ee17676cf27062697820e5d4c Mon Sep 17 00:00:00 2001 From: __prav__ Date: Sun, 14 Dec 2025 20:03:43 -0500 Subject: [PATCH 02/36] refactor: renames and utils --- Engine/include/Popcorn/Core/Buffer.h | 14 +++++------ Engine/include/Popcorn/Events/Event.h | 12 +++++----- .../include/Popcorn/Graphics/BufferObjects.h | 4 ++-- Engine/include/Popcorn/Graphics/Renderer.h | 4 ++-- Engine/include/Popcorn/Graphics/Shader.h | 8 +++---- .../Platform/Vulkan/Memory/HelpersVk.h | 24 +++++++++---------- Engine/src/Popcorn/Core/Externs.cpp | 2 +- .../Platform/Vulkan/Memory/MemoryVk.cpp | 4 ++-- 8 files changed, 36 insertions(+), 36 deletions(-) diff --git a/Engine/include/Popcorn/Core/Buffer.h b/Engine/include/Popcorn/Core/Buffer.h index fdf18122..ebd3713f 100644 --- a/Engine/include/Popcorn/Core/Buffer.h +++ b/Engine/include/Popcorn/Core/Buffer.h @@ -32,8 +32,8 @@ struct HasPrint< class Buffer { public: - Buffer() { - // PC_PRINT("CREATED(DEFAULT)", TagType::Constr, "BUFFER") + Buffer() { + // PC_PRINT("CREATED(DEFAULT)", TagType::Constr, "BUFFER") }; ~Buffer() { FreeBytes(); @@ -64,13 +64,13 @@ class Buffer { m_size = size; }; - [[nodiscard]] inline byte_t *GetData() const { - return static_cast(m_data); + [[nodiscard]] inline PC_Byte_t *GetData() const { + return static_cast(m_data); }; void WriteBytes(const void *data, uint64_t size, uint64_t offset = 0) { PC_ASSERT(offset + size <= m_size, "WriteBytes out of bounds!"); - memcpy(static_cast(m_data) + offset, data, size); + memcpy(static_cast(m_data) + offset, data, size); } // @@ -183,13 +183,13 @@ class Buffer { void AllocBytes(uint64_t size) { FreeBytes(); - m_data = new byte_t[size]; + m_data = new PC_Byte_t[size]; m_size = size; }; void FreeBytes() { if (m_data) - delete[] static_cast(m_data); + delete[] static_cast(m_data); m_data = nullptr; m_size = 0; }; diff --git a/Engine/include/Popcorn/Events/Event.h b/Engine/include/Popcorn/Events/Event.h index 7f3d3efb..e957d732 100644 --- a/Engine/include/Popcorn/Events/Event.h +++ b/Engine/include/Popcorn/Events/Event.h @@ -38,12 +38,12 @@ enum class EventType { enum class EventCategory { None = 0, - ApplicationEvent = shift_l(1), - WindowEvent = shift_l(2), - KeyboardEvent = shift_l(3), - MouseEvent = shift_l(4), - TimeEvent = shift_l(5), - VulkanEvent = shift_l(6) + ApplicationEvent = PC_ShiftLeft(1), + WindowEvent = PC_ShiftLeft(2), + KeyboardEvent = PC_ShiftLeft(3), + MouseEvent = PC_ShiftLeft(4), + TimeEvent = PC_ShiftLeft(5), + VulkanEvent = PC_ShiftLeft(6) }; // HASH DEFINE START ---------------------------------------------------------- diff --git a/Engine/include/Popcorn/Graphics/BufferObjects.h b/Engine/include/Popcorn/Graphics/BufferObjects.h index c3dc0630..0367f85b 100644 --- a/Engine/include/Popcorn/Graphics/BufferObjects.h +++ b/Engine/include/Popcorn/Graphics/BufferObjects.h @@ -131,7 +131,7 @@ class VertexBuffer { return m_layout; } - [[nodiscard]] inline byte_t *GetBufferData() const { + [[nodiscard]] inline PC_Byte_t *GetBufferData() const { return m_buffer.GetData(); } @@ -230,7 +230,7 @@ template class IndexBuffer { m_buffer.WriteBytes(data, size, offset); } - [[nodiscard]] inline byte_t *GetBufferData() const { + [[nodiscard]] inline PC_Byte_t *GetBufferData() const { return m_buffer.GetData(); } diff --git a/Engine/include/Popcorn/Graphics/Renderer.h b/Engine/include/Popcorn/Graphics/Renderer.h index 259757f3..e6339216 100644 --- a/Engine/include/Popcorn/Graphics/Renderer.h +++ b/Engine/include/Popcorn/Graphics/Renderer.h @@ -10,8 +10,8 @@ GFX_NAMESPACE_BEGIN enum class RendererType { None = 0, - OpenGL = shift_l(1), - Vulkan = shift_l(2), + OpenGL = PC_ShiftLeft(1), + Vulkan = PC_ShiftLeft(2), // DirectX = shift_l(3), // Metal = shift_l(4) }; diff --git a/Engine/include/Popcorn/Graphics/Shader.h b/Engine/include/Popcorn/Graphics/Shader.h index 019467cf..2409000a 100644 --- a/Engine/include/Popcorn/Graphics/Shader.h +++ b/Engine/include/Popcorn/Graphics/Shader.h @@ -17,12 +17,12 @@ enum ShaderStages { // // Graphics types VertexBit = 1, - TesselationBit = shift_l(1), - GeometryBit = shift_l(2), - FragmentBit = shift_l(3), + TesselationBit = PC_ShiftLeft(1), + GeometryBit = PC_ShiftLeft(2), + FragmentBit = PC_ShiftLeft(3), // // Compute types - ComputeBit = shift_l(4) + ComputeBit = PC_ShiftLeft(4) // // Ray tracing types // TODO: Fill it out when time arrives diff --git a/Engine/include/Popcorn/Platform/Vulkan/Memory/HelpersVk.h b/Engine/include/Popcorn/Platform/Vulkan/Memory/HelpersVk.h index bd57a417..fa4f41f8 100644 --- a/Engine/include/Popcorn/Platform/Vulkan/Memory/HelpersVk.h +++ b/Engine/include/Popcorn/Platform/Vulkan/Memory/HelpersVk.h @@ -29,8 +29,8 @@ template <> struct PcCopyUniformToMemory { ~PcCopyUniformToMemory() = default; void operator()(void *uboMapping, MaterialHashType matId) { - byte_t *basicMatUboMapping = - (byte_t *)uboMapping + bufferViews.basicMatUbo.offset + + PC_Byte_t *basicMatUboMapping = + (PC_Byte_t *)uboMapping + bufferViews.basicMatUbo.offset + bufferOffsets.materialOffsets[matId]; // all offsets are aligned uint64_t uniformSize = UniformDefs::BasicMaterialUniform::size; memcpy(basicMatUboMapping, &uniform, uniformSize); @@ -62,8 +62,8 @@ template <> struct PcCopyUniformToMemory { } void operator()(void *uboMapping, MaterialHashType matId) { - byte_t *dst = (byte_t *)uboMapping + bufferViews.pbrMatUbo.offset + - bufferOffsets.materialOffsets[matId]; + PC_Byte_t *dst = (PC_Byte_t *)uboMapping + bufferViews.pbrMatUbo.offset + + bufferOffsets.materialOffsets[matId]; memcpy(dst, &uniform, UniformDefs::PbrMaterialUniform::size); } @@ -87,8 +87,8 @@ template <> struct PcCopyUniformToMemory { size_t submeshIndex) { const auto &offsetTriple = bufferOffsets.submeshesOffsets[matId][submeshIndex]; - byte_t *dst = (byte_t *)uboMapping + bufferViews.submeshUbo.offset + - offsetTriple.uboOffset; + PC_Byte_t *dst = (PC_Byte_t *)uboMapping + bufferViews.submeshUbo.offset + + offsetTriple.uboOffset; memcpy(dst, &uniform, UniformDefs::SubmeshUniform::size); } @@ -125,8 +125,8 @@ template <> struct PcCopyUniformToMemory { } void operator()(void *ssboMapping, size_t index) { - byte_t *lightSsboMapping = - (byte_t *)ssboMapping + bufferViews.lightsSsbo.offset + + PC_Byte_t *lightSsboMapping = + (PC_Byte_t *)ssboMapping + bufferViews.lightsSsbo.offset + bufferOffsets.lightsOffsets[index]; // aligned offset constexpr uint64_t uniformSize = UniformDefs::LightUniform::size; @@ -156,8 +156,8 @@ template <> struct PcCopyUniformToMemory { } void operator()(void *uboMapping, size_t index) { - byte_t *dst = (byte_t *)uboMapping + bufferViews.camerasUbo.offset + - bufferOffsets.camerasOffsets[index]; + PC_Byte_t *dst = (PC_Byte_t *)uboMapping + bufferViews.camerasUbo.offset + + bufferOffsets.camerasOffsets[index]; memcpy(dst, &uniform, UniformDefs::CameraUniform::size); } @@ -177,8 +177,8 @@ template <> struct PcCopyUniformToMemory { } void operator()(void *uboMapping, size_t index) { - byte_t *dst = (byte_t *)uboMapping + bufferViews.emptysUbo.offset + - bufferOffsets.emptysOffsets[index]; + PC_Byte_t *dst = (PC_Byte_t *)uboMapping + bufferViews.emptysUbo.offset + + bufferOffsets.emptysOffsets[index]; memcpy(dst, &uniform, UniformDefs::EmptyUniform::size); } diff --git a/Engine/src/Popcorn/Core/Externs.cpp b/Engine/src/Popcorn/Core/Externs.cpp index ebc166c7..05412661 100644 --- a/Engine/src/Popcorn/Core/Externs.cpp +++ b/Engine/src/Popcorn/Core/Externs.cpp @@ -2,5 +2,5 @@ #include "Popcorn/Core/Base.h" ENGINE_NAMESPACE_BEGIN -int PC_print_lvl = 0; +int PC_PRINT_LEVEL = 0; ENGINE_NAMESPACE_END diff --git a/Engine/src/Popcorn/Platform/Vulkan/Memory/MemoryVk.cpp b/Engine/src/Popcorn/Platform/Vulkan/Memory/MemoryVk.cpp index b402d42c..c8a7f199 100644 --- a/Engine/src/Popcorn/Platform/Vulkan/Memory/MemoryVk.cpp +++ b/Engine/src/Popcorn/Platform/Vulkan/Memory/MemoryVk.cpp @@ -252,7 +252,7 @@ void MemoryVk::FillVbosIbosUbosSubmeshMaterial( const VkDeviceSize vboSize = submesh->GetVertexBuffer()->GetCount() * vboLayout.strideValue; - memcpy((byte_t *)m_vboStagingMapping + + memcpy((PC_Byte_t *)m_vboStagingMapping + m_bufferOffsets.submeshesOffsets[matId][i].vboOffset, submesh->GetVertexBuffer()->GetBufferData(), (size_t)vboSize); @@ -260,7 +260,7 @@ void MemoryVk::FillVbosIbosUbosSubmeshMaterial( // IBOs --------------------------------------------------------------- IndexBuffer *indexBuffer = submesh->GetIndexBuffer(); const VkDeviceSize iboSize = indexBuffer->GetCount() * sizeof(uint32_t); - memcpy((byte_t *)m_iboStagingMapping + + memcpy((PC_Byte_t *)m_iboStagingMapping + m_bufferOffsets.submeshesOffsets[matId][i].iboOffset, indexBuffer->GetBufferData(), (size_t)iboSize); } From ab803029de26b1202fe7153e4614645035a857d2 Mon Sep 17 00:00:00 2001 From: __prav__ Date: Tue, 16 Dec 2025 21:39:45 -0500 Subject: [PATCH 03/36] refactor: minor perf - changed submesh material maps to arrays --- Engine/include/Popcorn/Graphics/Shader.h | 1 + .../Vulkan/RenderFlows/RenderFlowVk.h | 23 +++++++++++++-- .../RenderFlows/GBufferRenderFlowVk.cpp | 9 +++--- .../Vulkan/RenderFlows/RenderFlowVk.cpp | 29 +++++++++++-------- .../Popcorn/Platform/Vulkan/RendererVk.cpp | 6 +++- 5 files changed, 48 insertions(+), 20 deletions(-) diff --git a/Engine/include/Popcorn/Graphics/Shader.h b/Engine/include/Popcorn/Graphics/Shader.h index 2409000a..48f7da7f 100644 --- a/Engine/include/Popcorn/Graphics/Shader.h +++ b/Engine/include/Popcorn/Graphics/Shader.h @@ -87,6 +87,7 @@ class ShaderLibrary { switch (R) { case RendererType::Vulkan: { auto it = s_shaders.find(T); + if (it != s_shaders.end()) { return it->second; } else { diff --git a/Engine/include/Popcorn/Platform/Vulkan/RenderFlows/RenderFlowVk.h b/Engine/include/Popcorn/Platform/Vulkan/RenderFlows/RenderFlowVk.h index 59902876..4be3c90a 100644 --- a/Engine/include/Popcorn/Platform/Vulkan/RenderFlows/RenderFlowVk.h +++ b/Engine/include/Popcorn/Platform/Vulkan/RenderFlows/RenderFlowVk.h @@ -7,6 +7,7 @@ #include "GlobalMacros.h" #include "Light.h" #include "MaterialTypes.h" +#include "MemoryDefsVk.h" #include "Mesh.h" #include "RenderFlowDefs.h" #include "SamplerVk.h" @@ -70,7 +71,7 @@ class RenderFlowVk { virtual void DestroyAttachments() = 0; public: - void Prepare() { + void CreateGfxResources() { PC_WARN("Preparing Renderflow............................") CreateAttachments(); @@ -115,6 +116,18 @@ class RenderFlowVk { template static void UnregisterMaterialAndSubmesh(Submesh *submesh); + static void CreateDrawOrderList() { + s_basicMatBucketDrawOrder.reserve(s_basicMatSubmeshBuckets.size()); + s_pbrMatBucketDrawOrder.reserve(s_pbrMatSubmeshBuckets.size()); + + for (auto &[materialHash, submeshBucket] : s_basicMatSubmeshBuckets) { + s_basicMatBucketDrawOrder.push_back(materialHash); + } + for (auto &[materialHash, submeshBucket] : s_pbrMatSubmeshBuckets) { + s_pbrMatBucketDrawOrder.push_back(materialHash); + } + }; + public: struct SamplersVk { SamplerVk colorSampler; @@ -128,8 +141,12 @@ class RenderFlowVk { protected: // // Game object refs ------------------------------------------------------- - static PcMaterialSubmeshesMap s_basicMatSubmeshesMap; - static PcMaterialSubmeshesMap s_pbrMatSubmeshesMap; + static PcMaterialSubmeshesMap + s_basicMatSubmeshBuckets; + static PcMaterialSubmeshesMap s_pbrMatSubmeshBuckets; + + static std::vector s_basicMatBucketDrawOrder; + static std::vector s_pbrMatBucketDrawOrder; static std::vector s_lights; static std::vector s_cameras; diff --git a/Engine/src/Popcorn/Platform/Vulkan/RenderFlows/GBufferRenderFlowVk.cpp b/Engine/src/Popcorn/Platform/Vulkan/RenderFlows/GBufferRenderFlowVk.cpp index 9127ec75..240024e7 100644 --- a/Engine/src/Popcorn/Platform/Vulkan/RenderFlows/GBufferRenderFlowVk.cpp +++ b/Engine/src/Popcorn/Platform/Vulkan/RenderFlows/GBufferRenderFlowVk.cpp @@ -659,8 +659,8 @@ void GBufferRenderFlowVk::RecordCommandBuffer(const uint32_t frameIndex, cameraSets.size(), cameraSets.data(), 1, &cameraOffset); - // TODO: Optimize - currently iterates over a map, make it vector - for (auto &[materialHash, submeshes] : s_basicMatSubmeshesMap) { + for (const MaterialHashType materialHash : s_basicMatBucketDrawOrder) { + auto &submeshes = s_basicMatSubmeshBuckets[materialHash]; uint32_t basicMatOffset = bufferOffsets.materialOffsets[materialHash]; // Descriptor set 1 - Basic material @@ -702,8 +702,9 @@ void GBufferRenderFlowVk::RecordCommandBuffer(const uint32_t frameIndex, cameraSets.size(), cameraSets.data(), 1, &cameraOffset); - // TODO: Optimize - currently iterates over a map, make it vector - for (auto &[materialHash, submeshes] : s_pbrMatSubmeshesMap) { + for (const MaterialHashType materialHash : s_pbrMatBucketDrawOrder) { + auto &submeshes = s_pbrMatSubmeshBuckets[materialHash]; + uint32_t pbrMatOffset = bufferOffsets.materialOffsets[materialHash]; // Descriptor set 1 - Pbr material diff --git a/Engine/src/Popcorn/Platform/Vulkan/RenderFlows/RenderFlowVk.cpp b/Engine/src/Popcorn/Platform/Vulkan/RenderFlows/RenderFlowVk.cpp index d6ef6b85..e0237211 100644 --- a/Engine/src/Popcorn/Platform/Vulkan/RenderFlows/RenderFlowVk.cpp +++ b/Engine/src/Popcorn/Platform/Vulkan/RenderFlows/RenderFlowVk.cpp @@ -17,9 +17,12 @@ GFX_NAMESPACE_BEGIN // // Game Object refs ------------------------------------------------------- PcMaterialSubmeshesMap - RenderFlowVk::s_basicMatSubmeshesMap{}; + RenderFlowVk::s_basicMatSubmeshBuckets{}; PcMaterialSubmeshesMap - RenderFlowVk::s_pbrMatSubmeshesMap{}; + RenderFlowVk::s_pbrMatSubmeshBuckets{}; + +std::vector RenderFlowVk::s_basicMatBucketDrawOrder{}; +std::vector RenderFlowVk::s_pbrMatBucketDrawOrder{}; std::vector RenderFlowVk::s_lights{}; std::vector RenderFlowVk::s_cameras{}; @@ -162,8 +165,8 @@ void RenderFlowVk::AllocMemory() { // Extract - // 1. All vbos, ibos, ubos individual offsets (BufferOffsets) // 2. Ubo & ssbo bufferView sizes (not aligned) - memory->ExtractOffsetsMaterialsSubmeshes(s_basicMatSubmeshesMap); - memory->ExtractOffsetsMaterialsSubmeshes(s_pbrMatSubmeshesMap); + memory->ExtractOffsetsMaterialsSubmeshes(s_basicMatSubmeshBuckets); + memory->ExtractOffsetsMaterialsSubmeshes(s_pbrMatSubmeshBuckets); memory->ExtractOffsetsLightsCamerasEmptys(s_lights, s_cameras, s_emptys); // Aligns vbo & ibo (BufferViews) for optimal copy (staging -> local) @@ -180,9 +183,10 @@ void RenderFlowVk::AllocMemory() { memory->AllocUboSsboLocalBuffers(); // clean up in RenderFlowVk::FreeMemory() // Fill submesh vbos, ibos and ubos, material ubos - memory->FillVbosIbosUbosSubmeshMaterial(s_basicMatSubmeshesMap, + memory->FillVbosIbosUbosSubmeshMaterial(s_basicMatSubmeshBuckets, s_basicMaterials); - memory->FillVbosIbosUbosSubmeshMaterial(s_pbrMatSubmeshesMap, s_pbrMaterials); + memory->FillVbosIbosUbosSubmeshMaterial(s_pbrMatSubmeshBuckets, + s_pbrMaterials); PC_ASSERT(s_submeshCount, "Submesh count is zero."); @@ -196,8 +200,8 @@ void RenderFlowVk::AllocMemory() { void RenderFlowVk::CopyDynamicUniformsToMemory(const uint32_t currentFrame) { auto *memory = ContextVk::Memory(); - memory->FillUbosSubmesh(s_basicMatSubmeshesMap, currentFrame); - memory->FillUbosSubmesh(s_pbrMatSubmeshesMap, currentFrame); + memory->FillUbosSubmesh(s_basicMatSubmeshBuckets, currentFrame); + memory->FillUbosSubmesh(s_pbrMatSubmeshBuckets, currentFrame); memory->FillUbosSsbosLightCameraEmpty(s_lights, s_cameras, s_emptys, currentFrame); @@ -244,13 +248,14 @@ template void RenderFlowVk::RegisterMaterialAndSubmesh(Submesh *submesh) { if constexpr (T == MaterialTypes::BasicMat) { uint32_t materialId = PC_HashMaterialGroups(submesh->GetMaterial()); - if (PC_ValidateAndAddSubmesh(submesh, s_basicMatSubmeshesMap[materialId])) { + if (PC_ValidateAndAddSubmesh(submesh, + s_basicMatSubmeshBuckets[materialId])) { s_basicMaterials[materialId] = submesh->GetMaterial(); ++s_submeshCount; }; } else if constexpr (T == MaterialTypes::PbrMat) { uint32_t materialId = PC_HashMaterialGroups(submesh->GetMaterial()); - if (PC_ValidateAndAddSubmesh(submesh, s_pbrMatSubmeshesMap[materialId])) { + if (PC_ValidateAndAddSubmesh(submesh, s_pbrMatSubmeshBuckets[materialId])) { s_pbrMaterials[materialId] = submesh->GetMaterial(); ++s_submeshCount; }; @@ -266,13 +271,13 @@ void RenderFlowVk::UnregisterMaterialAndSubmesh(Submesh *submesh) { if constexpr (T == MaterialTypes::BasicMat) { uint32_t materialId = PC_HashMaterialGroups(submesh->GetMaterial()); if (PC_ValidateAndRemoveSubmesh(submesh, - s_basicMatSubmeshesMap[materialId])) { + s_basicMatSubmeshBuckets[materialId])) { --s_submeshCount; }; } else if constexpr (T == MaterialTypes::PbrMat) { uint32_t materialId = PC_HashMaterialGroups(submesh->GetMaterial()); if (PC_ValidateAndRemoveSubmesh(submesh, - s_pbrMatSubmeshesMap[materialId])) { + s_pbrMatSubmeshBuckets[materialId])) { --s_submeshCount; }; } diff --git a/Engine/src/Popcorn/Platform/Vulkan/RendererVk.cpp b/Engine/src/Popcorn/Platform/Vulkan/RendererVk.cpp index 04252af5..d60d7494 100644 --- a/Engine/src/Popcorn/Platform/Vulkan/RendererVk.cpp +++ b/Engine/src/Popcorn/Platform/Vulkan/RendererVk.cpp @@ -116,7 +116,7 @@ void RendererVk::PrepareRenderFlows() { for (auto &renderFlow : s_renderFlows) { PC_WARN("Preparing renderflow...") - renderFlow->Prepare(); // Creates Vulkan: + renderFlow->CreateGfxResources(); // Creates Vulkan: // - Attachments // - ImageBarriers // - RenderPass @@ -140,6 +140,9 @@ void RendererVk::CreateRenderFlowResources() { PC_WARN("Expensive initialization operation: Creating workflow Vulkan " "resources! Should only be done once") + // Copies material hashed submesh buckets to an std::vector for faster + // iteration in hot loops + RenderFlowVk::CreateDrawOrderList(); // // Allocate memory, samplers & load shaders in the shader library RenderFlowVk::AllocMemory(); @@ -190,6 +193,7 @@ void RendererVk::ProcessGameObjectNode(GameObject *node) { // Recursive for (auto &pbrSubmesh : mesh->GetSubmeshes()) { RenderFlowVk::RegisterMaterialAndSubmesh(&pbrSubmesh); } + } break; case Popcorn::Gfx::GameObjectTypes::Camera: // From aa6ab7f6ff177fe879b2879ca4a930137cb1c3ec Mon Sep 17 00:00:00 2001 From: __prav__ Date: Sun, 21 Dec 2025 21:14:40 -0500 Subject: [PATCH 04/36] wip: dynamic rendering + shadows repass - 1 --- .../Vulkan/RenderFlows/RFlowResourcesVk.h | 31 +++++++++++++++++++ .../Vulkan/RenderFlows/RenderFlowDefs.h | 1 - .../Vulkan/RenderFlows/ShadowsRFlowVk.h | 17 ++++++++++ .../Vulkan/RenderFlows/RFlowResourcesVk.cpp | 27 ++++++++++++++++ 4 files changed, 75 insertions(+), 1 deletion(-) create mode 100644 Engine/include/Popcorn/Platform/Vulkan/RenderFlows/RFlowResourcesVk.h create mode 100644 Engine/include/Popcorn/Platform/Vulkan/RenderFlows/ShadowsRFlowVk.h create mode 100644 Engine/src/Popcorn/Platform/Vulkan/RenderFlows/RFlowResourcesVk.cpp diff --git a/Engine/include/Popcorn/Platform/Vulkan/RenderFlows/RFlowResourcesVk.h b/Engine/include/Popcorn/Platform/Vulkan/RenderFlows/RFlowResourcesVk.h new file mode 100644 index 00000000..479e493d --- /dev/null +++ b/Engine/include/Popcorn/Platform/Vulkan/RenderFlows/RFlowResourcesVk.h @@ -0,0 +1,31 @@ +#pragma once + +#include "CommonVk.h" +#include "GlobalMacros.h" +#include "RenderFlowDefs.h" + +ENGINE_NAMESPACE_BEGIN +GFX_NAMESPACE_BEGIN + +enum RFlowImageTypes { Color, Depth }; + +class RFlowResourcesVk { + // Images + // Barriers + // + // Descriptor Sets + // Attachments + +public: + RFlowResourcesVk() = default; + + void CreateImageColor(const std::vector &formatCandidatesList, + uint32_t width, uint32_t height, + VkImageUsageFlags usage, ImageVk &imageVk); + +private: + // void +}; + +GFX_NAMESPACE_END +ENGINE_NAMESPACE_END diff --git a/Engine/include/Popcorn/Platform/Vulkan/RenderFlows/RenderFlowDefs.h b/Engine/include/Popcorn/Platform/Vulkan/RenderFlows/RenderFlowDefs.h index a225eb7b..cde36d97 100644 --- a/Engine/include/Popcorn/Platform/Vulkan/RenderFlows/RenderFlowDefs.h +++ b/Engine/include/Popcorn/Platform/Vulkan/RenderFlows/RenderFlowDefs.h @@ -49,7 +49,6 @@ template struct PcRenderFlowImages { template struct PcRenderFlowImages { PcRenderFlowImages() {} - PC_STATIC_ASSERT(Count == MAX_FRAMES_IN_FLIGHT, "Count must be equal to MAX_FRAMES_IN_FLIGHT for Gbuffer"); PcFramesImages_Bundle albedoImages{}; diff --git a/Engine/include/Popcorn/Platform/Vulkan/RenderFlows/ShadowsRFlowVk.h b/Engine/include/Popcorn/Platform/Vulkan/RenderFlows/ShadowsRFlowVk.h new file mode 100644 index 00000000..94c3d656 --- /dev/null +++ b/Engine/include/Popcorn/Platform/Vulkan/RenderFlows/ShadowsRFlowVk.h @@ -0,0 +1,17 @@ +#pragma once + +#include "GlobalMacros.h" +#include "RenderFlowVk.h" + +ENGINE_NAMESPACE_BEGIN +GFX_NAMESPACE_BEGIN + +class ShadowsRFlowsVk : public RenderFlowVk { + ShadowsRFlowsVk(); + virtual ~ShadowsRFlowsVk() override = default; + + virtual void CreateAttachments() override; +}; + +GFX_NAMESPACE_END +ENGINE_NAMESPACE_END diff --git a/Engine/src/Popcorn/Platform/Vulkan/RenderFlows/RFlowResourcesVk.cpp b/Engine/src/Popcorn/Platform/Vulkan/RenderFlows/RFlowResourcesVk.cpp new file mode 100644 index 00000000..8b89a437 --- /dev/null +++ b/Engine/src/Popcorn/Platform/Vulkan/RenderFlows/RFlowResourcesVk.cpp @@ -0,0 +1,27 @@ +#include "RFlowResourcesVk.h" +#include "GlobalMacros.h" + +ENGINE_NAMESPACE_BEGIN +GFX_NAMESPACE_BEGIN + +void RFlowResourcesVk::CreateImageColor( + const std::vector &formatCandidatesList, uint32_t width, + uint32_t height, VkImageUsageFlags usage, ImageVk &imageVk) { + VkFormat colorFormat = ImageVk::FindSupportedFormat( + formatCandidatesList, VK_IMAGE_TILING_OPTIMAL, + VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT); + + VkImageCreateInfo colorImageInfo{}; + ImageVk::GetDefaultImageCreateInfo(colorImageInfo, width, height, + colorFormat); + colorImageInfo.format = colorFormat; + colorImageInfo.usage = + VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT; + + VmaAllocationCreateInfo colorAlloc{.usage = VMA_MEMORY_USAGE_AUTO}; + + imageVk.CreateVmaImage(colorImageInfo, colorAlloc); +}; + +GFX_NAMESPACE_END +ENGINE_NAMESPACE_END From c5fd5dddbe5813b282f61890d60a41bd1a41d9c0 Mon Sep 17 00:00:00 2001 From: __prav__ Date: Mon, 22 Dec 2025 22:34:41 -0500 Subject: [PATCH 05/36] wip: resource abstraction --- .../include/Popcorn/Platform/Vulkan/ImageVk.h | 6 +- .../Vulkan/RenderFlows/GBufferRenderFlowVk.h | 9 +-- .../Vulkan/RenderFlows/RFlowResourcesVk.h | 68 +++++++++++++++++-- .../Vulkan/RenderFlows/RenderFlowVk.h | 2 + .../RenderFlows/GBufferRenderFlowVk.cpp | 4 +- .../Vulkan/RenderFlows/RFlowResourcesVk.cpp | 19 ------ 6 files changed, 73 insertions(+), 35 deletions(-) diff --git a/Engine/include/Popcorn/Platform/Vulkan/ImageVk.h b/Engine/include/Popcorn/Platform/Vulkan/ImageVk.h index 613e6427..2e1925f9 100644 --- a/Engine/include/Popcorn/Platform/Vulkan/ImageVk.h +++ b/Engine/include/Popcorn/Platform/Vulkan/ImageVk.h @@ -42,9 +42,9 @@ class ImageVk { public: // --- UTILS ------------------------------------------------------------- - static VkFormat FindSupportedFormat(const std::vector &candidates, - VkImageTiling tiling, - VkFormatFeatureFlags features); + [[nodiscard]] static VkFormat + FindSupportedFormat(const std::vector &candidates, + VkImageTiling tiling, VkFormatFeatureFlags features); const bool FormatHasStencilComponent() const { PC_ASSERT(m_format != VK_FORMAT_UNDEFINED, "m_format is null"); diff --git a/Engine/include/Popcorn/Platform/Vulkan/RenderFlows/GBufferRenderFlowVk.h b/Engine/include/Popcorn/Platform/Vulkan/RenderFlows/GBufferRenderFlowVk.h index cb82c5f5..d4fa1b23 100644 --- a/Engine/include/Popcorn/Platform/Vulkan/RenderFlows/GBufferRenderFlowVk.h +++ b/Engine/include/Popcorn/Platform/Vulkan/RenderFlows/GBufferRenderFlowVk.h @@ -14,13 +14,8 @@ GFX_NAMESPACE_BEGIN class GBufferRenderFlowVk : public RenderFlowVk { public: - GBufferRenderFlowVk() { - PC_PRINT("CREATED", TagType::Constr, "GBufferRenderFlowVk") - } - - virtual ~GBufferRenderFlowVk() override { - PC_PRINT("DESTROYED", TagType::Destr, "GBufferRenderflowVk") - } + GBufferRenderFlowVk() {}; + virtual ~GBufferRenderFlowVk() override = default; #ifdef PC_DEBUG virtual void PrintVboIbo() override; diff --git a/Engine/include/Popcorn/Platform/Vulkan/RenderFlows/RFlowResourcesVk.h b/Engine/include/Popcorn/Platform/Vulkan/RenderFlows/RFlowResourcesVk.h index 479e493d..83dd1c44 100644 --- a/Engine/include/Popcorn/Platform/Vulkan/RenderFlows/RFlowResourcesVk.h +++ b/Engine/include/Popcorn/Platform/Vulkan/RenderFlows/RFlowResourcesVk.h @@ -7,7 +7,18 @@ ENGINE_NAMESPACE_BEGIN GFX_NAMESPACE_BEGIN -enum RFlowImageTypes { Color, Depth }; +enum RFlowImages { + Color_RGBA_HiRes, + Color_RGBA_LoRes, + Depth_Auto, +}; + +enum RFlowResources { + Image = 1, + Buffer, + Uniform, + Shader, +}; class RFlowResourcesVk { // Images @@ -19,9 +30,58 @@ class RFlowResourcesVk { public: RFlowResourcesVk() = default; - void CreateImageColor(const std::vector &formatCandidatesList, - uint32_t width, uint32_t height, - VkImageUsageFlags usage, ImageVk &imageVk); + template + void CreateImage(uint32_t width, uint32_t height, ImageVk &imageVk) { + std::vector formatCandidates{}; + VkFormat selectedFormat; + VkImageCreateInfo imageCreateInfo{}; + VmaAllocationCreateInfo imageAlloc{.usage = VMA_MEMORY_USAGE_AUTO}; + + if constexpr (T == RFlowImages::Color_RGBA_LoRes) { + // --- Color --- + // Low Res color + formatCandidates = {VK_FORMAT_R8G8B8A8_UNORM, VK_FORMAT_B8G8R8A8_UNORM}; + selectedFormat = ImageVk::FindSupportedFormat( + formatCandidates, VK_IMAGE_TILING_OPTIMAL, + VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT); + + ImageVk::GetDefaultImageCreateInfo(imageCreateInfo, width, height, + selectedFormat); + imageCreateInfo.format = selectedFormat; + imageCreateInfo.usage = + VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT; + } else if constexpr (T == RFlowImages::Color_RGBA_HiRes) { + // --- Color --- + // High Res color, fallback to low res + formatCandidates = {VK_FORMAT_R16G16B16A16_SFLOAT, + VK_FORMAT_R8G8B8A8_UNORM}; + selectedFormat = ImageVk::FindSupportedFormat( + formatCandidates, VK_IMAGE_TILING_OPTIMAL, + VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT); + + ImageVk::GetDefaultImageCreateInfo(imageCreateInfo, width, height, + selectedFormat); + imageCreateInfo.format = selectedFormat; + imageCreateInfo.usage = + VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT; + } else { + // --- Depth --- + // High Res depth, fallback to low res + formatCandidates = {VK_FORMAT_D32_SFLOAT, VK_FORMAT_D32_SFLOAT_S8_UINT, + VK_FORMAT_D24_UNORM_S8_UINT}; + selectedFormat = ImageVk::FindSupportedFormat( + formatCandidates, VK_IMAGE_TILING_OPTIMAL, + VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT); + + ImageVk::GetDefaultImageCreateInfo(imageCreateInfo, width, height, + selectedFormat); + imageCreateInfo.format = selectedFormat; + imageCreateInfo.usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | + VK_IMAGE_USAGE_SAMPLED_BIT; + } + + imageVk.CreateVmaImage(imageCreateInfo, imageAlloc); + }; private: // void diff --git a/Engine/include/Popcorn/Platform/Vulkan/RenderFlows/RenderFlowVk.h b/Engine/include/Popcorn/Platform/Vulkan/RenderFlows/RenderFlowVk.h index 4be3c90a..914ab8dc 100644 --- a/Engine/include/Popcorn/Platform/Vulkan/RenderFlows/RenderFlowVk.h +++ b/Engine/include/Popcorn/Platform/Vulkan/RenderFlows/RenderFlowVk.h @@ -39,6 +39,8 @@ class RenderFlowVk { static void AllocDescriptorsGlobal(); static void UpdateDescriptorSetsGlobal(); + // static void CreateGlobalResources(); + public: #ifdef PC_DEBUG virtual void PrintVboIbo() {}; diff --git a/Engine/src/Popcorn/Platform/Vulkan/RenderFlows/GBufferRenderFlowVk.cpp b/Engine/src/Popcorn/Platform/Vulkan/RenderFlows/GBufferRenderFlowVk.cpp index 240024e7..1ae2bd75 100644 --- a/Engine/src/Popcorn/Platform/Vulkan/RenderFlows/GBufferRenderFlowVk.cpp +++ b/Engine/src/Popcorn/Platform/Vulkan/RenderFlows/GBufferRenderFlowVk.cpp @@ -44,8 +44,8 @@ void GBufferRenderFlowVk::CreateAttachments() { VK_FORMAT_D32_SFLOAT_S8_UINT, VK_FORMAT_D24_UNORM_S8_UINT}; std::vector normalCandidates = { - VK_FORMAT_R16G16B16A16_SFLOAT, // high precision normals - VK_FORMAT_R8G8B8A8_UNORM // Fallback (low precision) + VK_FORMAT_R16G16B16A16_SFLOAT, + VK_FORMAT_R8G8B8A8_UNORM // Fallback (low precision) }; std::vector roughnessMetallicCandidates = { VK_FORMAT_R8G8B8A8_UNORM, VK_FORMAT_B8G8R8A8_UNORM}; diff --git a/Engine/src/Popcorn/Platform/Vulkan/RenderFlows/RFlowResourcesVk.cpp b/Engine/src/Popcorn/Platform/Vulkan/RenderFlows/RFlowResourcesVk.cpp index 8b89a437..69d47b3a 100644 --- a/Engine/src/Popcorn/Platform/Vulkan/RenderFlows/RFlowResourcesVk.cpp +++ b/Engine/src/Popcorn/Platform/Vulkan/RenderFlows/RFlowResourcesVk.cpp @@ -4,24 +4,5 @@ ENGINE_NAMESPACE_BEGIN GFX_NAMESPACE_BEGIN -void RFlowResourcesVk::CreateImageColor( - const std::vector &formatCandidatesList, uint32_t width, - uint32_t height, VkImageUsageFlags usage, ImageVk &imageVk) { - VkFormat colorFormat = ImageVk::FindSupportedFormat( - formatCandidatesList, VK_IMAGE_TILING_OPTIMAL, - VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT); - - VkImageCreateInfo colorImageInfo{}; - ImageVk::GetDefaultImageCreateInfo(colorImageInfo, width, height, - colorFormat); - colorImageInfo.format = colorFormat; - colorImageInfo.usage = - VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT; - - VmaAllocationCreateInfo colorAlloc{.usage = VMA_MEMORY_USAGE_AUTO}; - - imageVk.CreateVmaImage(colorImageInfo, colorAlloc); -}; - GFX_NAMESPACE_END ENGINE_NAMESPACE_END From afe5d8d5fb531e89a59796c8186e95f3104e2a1e Mon Sep 17 00:00:00 2001 From: __prav__ Date: Tue, 23 Dec 2025 21:21:27 -0500 Subject: [PATCH 06/36] wip: dynamic rendering - day 3 --- .../include/Popcorn/Platform/Vulkan/ImageVk.h | 1 + .../Vulkan/RenderFlows/GBufferRenderFlowVk.h | 14 ++ .../Vulkan/RenderFlows/RFlowResourcesVk.h | 56 ++++- .../Vulkan/RenderFlows/RenderFlowVk.h | 10 +- .../RenderFlows/GBufferRenderFlowVk.cpp | 235 +++++------------- 5 files changed, 136 insertions(+), 180 deletions(-) diff --git a/Engine/include/Popcorn/Platform/Vulkan/ImageVk.h b/Engine/include/Popcorn/Platform/Vulkan/ImageVk.h index 2e1925f9..5a0a2879 100644 --- a/Engine/include/Popcorn/Platform/Vulkan/ImageVk.h +++ b/Engine/include/Popcorn/Platform/Vulkan/ImageVk.h @@ -25,6 +25,7 @@ class ImageVk { [[nodiscard]] const VkImageView &GetVkImageView() const { return m_imageView; }; + [[nodiscard]] const VkFormat &GetVkImageFormat() const { return m_format; }; static void GetDefaultImageCreateInfo(VkImageCreateInfo &imageInfo, uint32_t width, uint32_t height, diff --git a/Engine/include/Popcorn/Platform/Vulkan/RenderFlows/GBufferRenderFlowVk.h b/Engine/include/Popcorn/Platform/Vulkan/RenderFlows/GBufferRenderFlowVk.h index d4fa1b23..c905ad1c 100644 --- a/Engine/include/Popcorn/Platform/Vulkan/RenderFlows/GBufferRenderFlowVk.h +++ b/Engine/include/Popcorn/Platform/Vulkan/RenderFlows/GBufferRenderFlowVk.h @@ -27,6 +27,8 @@ class GBufferRenderFlowVk : public RenderFlowVk { virtual void CreateFramebuffers() override; virtual void CreateRenderPass() override; + virtual void CreateRenderInfoState() override; + virtual void DestroyRenderPass() override; virtual void DestroyFramebuffers() override; virtual void DestroyAttachments() override; @@ -73,6 +75,18 @@ class GBufferRenderFlowVk : public RenderFlowVk { AttachmentsVk m_attachmentsVk{}; DescriptorSetsVk m_descriptorSetsVk{}; + struct RenderInfoStateVk { + std::array albedoInfo{}; + std::array normalInfo{}; + std::array + roughnessMetallicInfo{}; + std::array depthInfo{}; + + std::array renderingInfo{}; + }; + + RenderInfoStateVk m_renderInfoState{}; + RenderPassVk m_renderPass; PcFramesFramebuffers_Bundle m_framebuffers; diff --git a/Engine/include/Popcorn/Platform/Vulkan/RenderFlows/RFlowResourcesVk.h b/Engine/include/Popcorn/Platform/Vulkan/RenderFlows/RFlowResourcesVk.h index 83dd1c44..c583d343 100644 --- a/Engine/include/Popcorn/Platform/Vulkan/RenderFlows/RFlowResourcesVk.h +++ b/Engine/include/Popcorn/Platform/Vulkan/RenderFlows/RFlowResourcesVk.h @@ -1,8 +1,8 @@ #pragma once -#include "CommonVk.h" #include "GlobalMacros.h" -#include "RenderFlowDefs.h" +#include "ImageVk.h" +#include ENGINE_NAMESPACE_BEGIN GFX_NAMESPACE_BEGIN @@ -30,13 +30,30 @@ class RFlowResourcesVk { public: RFlowResourcesVk() = default; + static void + GetDefaultRenderingAttachmentInfo(const VkImageView &imageView, + VkRenderingAttachmentInfo &renderAttInfo) { + renderAttInfo.sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO; + renderAttInfo.clearValue = { + {0.0f, 0.0f, 0.0f, 1.0f}}; // VkClearValue for Albedo + renderAttInfo.imageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; + renderAttInfo.imageView = imageView; + renderAttInfo.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; + renderAttInfo.storeOp = VK_ATTACHMENT_STORE_OP_STORE; + } + + static void GetDefaultRenderingInfo() {} + template - void CreateImage(uint32_t width, uint32_t height, ImageVk &imageVk) { + static void CreateImageAndView(uint32_t width, uint32_t height, + ImageVk &imageVk) { std::vector formatCandidates{}; VkFormat selectedFormat; VkImageCreateInfo imageCreateInfo{}; VmaAllocationCreateInfo imageAlloc{.usage = VMA_MEMORY_USAGE_AUTO}; + VkImageViewCreateInfo imageViewCreateInfo{}; + if constexpr (T == RFlowImages::Color_RGBA_LoRes) { // --- Color --- // Low Res color @@ -50,6 +67,15 @@ class RFlowResourcesVk { imageCreateInfo.format = selectedFormat; imageCreateInfo.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT; + + imageVk.CreateVmaImage(imageCreateInfo, imageAlloc); + + // --- Image View --- + ImageVk::GetDefaultImageViewCreateInfo( + imageViewCreateInfo, imageVk.GetVkImage(), selectedFormat); + imageViewCreateInfo.format = selectedFormat; + imageViewCreateInfo.subresourceRange.aspectMask = + VK_IMAGE_ASPECT_COLOR_BIT; } else if constexpr (T == RFlowImages::Color_RGBA_HiRes) { // --- Color --- // High Res color, fallback to low res @@ -64,6 +90,15 @@ class RFlowResourcesVk { imageCreateInfo.format = selectedFormat; imageCreateInfo.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT; + + imageVk.CreateVmaImage(imageCreateInfo, imageAlloc); + + // --- Image View --- + ImageVk::GetDefaultImageViewCreateInfo( + imageViewCreateInfo, imageVk.GetVkImage(), selectedFormat); + imageViewCreateInfo.format = selectedFormat; + imageViewCreateInfo.subresourceRange.aspectMask = + VK_IMAGE_ASPECT_COLOR_BIT; } else { // --- Depth --- // High Res depth, fallback to low res @@ -78,9 +113,22 @@ class RFlowResourcesVk { imageCreateInfo.format = selectedFormat; imageCreateInfo.usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT; + + imageVk.CreateVmaImage(imageCreateInfo, imageAlloc); + + // --- Image View --- + ImageVk::GetDefaultImageViewCreateInfo( + imageViewCreateInfo, imageVk.GetVkImage(), selectedFormat); + imageViewCreateInfo.format = selectedFormat; + imageViewCreateInfo.subresourceRange.aspectMask = + VK_IMAGE_ASPECT_DEPTH_BIT; + if (imageVk.FormatHasStencilComponent()) { + imageViewCreateInfo.subresourceRange.aspectMask |= + VK_IMAGE_ASPECT_STENCIL_BIT; + } } - imageVk.CreateVmaImage(imageCreateInfo, imageAlloc); + imageVk.CreateImageView(imageViewCreateInfo); }; private: diff --git a/Engine/include/Popcorn/Platform/Vulkan/RenderFlows/RenderFlowVk.h b/Engine/include/Popcorn/Platform/Vulkan/RenderFlows/RenderFlowVk.h index 914ab8dc..eaac2137 100644 --- a/Engine/include/Popcorn/Platform/Vulkan/RenderFlows/RenderFlowVk.h +++ b/Engine/include/Popcorn/Platform/Vulkan/RenderFlows/RenderFlowVk.h @@ -25,6 +25,8 @@ class RenderFlowVk { RenderFlowVk(); virtual ~RenderFlowVk(); + // + // --- Create/Init stuff ---------------------------------------------------- static void AllocMemory(); static void FreeMemory(); @@ -34,12 +36,12 @@ class RenderFlowVk { static void CopyDynamicUniformsToMemory(const uint32_t currentFrame); static void AllocShaders(); - static void FreeShaders(); static void AllocDescriptorsGlobal(); static void UpdateDescriptorSetsGlobal(); - // static void CreateGlobalResources(); + // --- Cleanup stuff -------------------------------------------------------- + static void FreeShaders(); public: #ifdef PC_DEBUG @@ -63,8 +65,10 @@ class RenderFlowVk { private: virtual void CreateAttachments() = 0; virtual void CreateImageBarriers() = 0; - virtual void CreateRenderPass() = 0; virtual void CreateFramebuffers() = 0; + virtual void CreateRenderPass() = 0; + + virtual void CreateRenderInfoState() = 0; virtual void CreateCommandBuffers() = 0; diff --git a/Engine/src/Popcorn/Platform/Vulkan/RenderFlows/GBufferRenderFlowVk.cpp b/Engine/src/Popcorn/Platform/Vulkan/RenderFlows/GBufferRenderFlowVk.cpp index 1ae2bd75..fb0a63ae 100644 --- a/Engine/src/Popcorn/Platform/Vulkan/RenderFlows/GBufferRenderFlowVk.cpp +++ b/Engine/src/Popcorn/Platform/Vulkan/RenderFlows/GBufferRenderFlowVk.cpp @@ -8,7 +8,6 @@ #include "DescriptorLayoutsVk.h" #include "DescriptorPoolsVk.h" #include "FramebufferVk.h" -#include "ImageVk.h" #include "MaterialTypes.h" #include "Memory/MemoryVk.h" #include "Mesh.h" @@ -16,6 +15,7 @@ #include "Popcorn/Core/Base.h" #include "Popcorn/Core/Helpers.h" #include "Popcorn/Loaders/LoadersDefs.h" +#include "RFlowResourcesVk.h" #include "RenderPassVk.h" #include #include @@ -33,186 +33,75 @@ GFX_NAMESPACE_BEGIN // --- CREATE ATTACHMENTS ------------------------------------------------------ // void GBufferRenderFlowVk::CreateAttachments() { - const auto &swapchainExtent = ContextVk::Swapchain()->GetSwapchainExtent(); + // TODO: DELETE +} - const auto &width = swapchainExtent.width; - const auto &height = swapchainExtent.height; - - std::vector albedoCandidates = {VK_FORMAT_R8G8B8A8_UNORM, - VK_FORMAT_B8G8R8A8_UNORM}; - std::vector depthCandidates = {VK_FORMAT_D32_SFLOAT, - VK_FORMAT_D32_SFLOAT_S8_UINT, - VK_FORMAT_D24_UNORM_S8_UINT}; - std::vector normalCandidates = { - VK_FORMAT_R16G16B16A16_SFLOAT, - VK_FORMAT_R8G8B8A8_UNORM // Fallback (low precision) - }; - std::vector roughnessMetallicCandidates = { - VK_FORMAT_R8G8B8A8_UNORM, VK_FORMAT_B8G8R8A8_UNORM}; - - VkFormat albedoFormat = - ImageVk::FindSupportedFormat(albedoCandidates, VK_IMAGE_TILING_OPTIMAL, - VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT); - VkFormat depthFormat = ImageVk::FindSupportedFormat( - depthCandidates, VK_IMAGE_TILING_OPTIMAL, - VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT); - VkFormat normalFormat = - ImageVk::FindSupportedFormat(normalCandidates, VK_IMAGE_TILING_OPTIMAL, - VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT); - - VkFormat roughnessMetallicFormat = ImageVk::FindSupportedFormat( - roughnessMetallicCandidates, VK_IMAGE_TILING_OPTIMAL, - VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT); +void GBufferRenderFlowVk::CreateRenderInfoState() { // + // --- RENDER ATTACHMENTS INFO ----------------------------------------------- + // --- RENDER ATTACHMENTS INFO ----------------------------------------------- // - // --- Create g-buffer images ------------------------------------------------ - VkImageCreateInfo albedoImageInfo{}; - ImageVk::GetDefaultImageCreateInfo(albedoImageInfo, width, height, - albedoFormat); - albedoImageInfo.format = albedoFormat; - albedoImageInfo.usage = - VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT; - - VkImageCreateInfo depthImageInfo{}; - ImageVk::GetDefaultImageCreateInfo(depthImageInfo, width, height, - depthFormat); - depthImageInfo.format = depthFormat; - depthImageInfo.usage = - VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT; - - VkImageCreateInfo normalImageInfo{}; - ImageVk::GetDefaultImageCreateInfo(normalImageInfo, width, height, - normalFormat); - normalImageInfo.format = normalFormat; - normalImageInfo.usage = - VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT; - - VkImageCreateInfo roughnessMetallicImageInfo{}; - ImageVk::GetDefaultImageCreateInfo(roughnessMetallicImageInfo, width, height, - roughnessMetallicFormat); - roughnessMetallicImageInfo.format = roughnessMetallicFormat; - roughnessMetallicImageInfo.usage = - VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT; - - VmaAllocationCreateInfo albedoAlloc{.usage = VMA_MEMORY_USAGE_AUTO}; - VmaAllocationCreateInfo depthAlloc{.usage = VMA_MEMORY_USAGE_AUTO}; - VmaAllocationCreateInfo normalAlloc{.usage = VMA_MEMORY_USAGE_AUTO}; - VmaAllocationCreateInfo roughnessMetallicAlloc{.usage = - VMA_MEMORY_USAGE_AUTO}; - - for (size_t i = 0; i < MAX_FRAMES_IN_FLIGHT; ++i) { - ImageVk &albedoImage = s_gBufferImages.albedoImages[i]; - ImageVk &depthImage = s_gBufferImages.depthImages[i]; - ImageVk &normalImage = s_gBufferImages.normalImages[i]; - ImageVk &roughnessMetallicImage = - s_gBufferImages.roughnessMetallicImages[i]; - - albedoImage.CreateVmaImage(albedoImageInfo, albedoAlloc); - depthImage.CreateVmaImage(depthImageInfo, depthAlloc); - normalImage.CreateVmaImage(normalImageInfo, normalAlloc); - roughnessMetallicImage.CreateVmaImage(roughnessMetallicImageInfo, - roughnessMetallicAlloc); - - // - // - // --- Create g-buffer image-views ----------------------------------------- - VkImageViewCreateInfo albedoViewInfo{}; - ImageVk::GetDefaultImageViewCreateInfo( - albedoViewInfo, albedoImage.GetVkImage(), albedoFormat); - albedoViewInfo.format = albedoFormat; - albedoViewInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; - - VkImageViewCreateInfo depthViewInfo{}; - ImageVk::GetDefaultImageViewCreateInfo( - depthViewInfo, depthImage.GetVkImage(), depthFormat); - depthViewInfo.format = depthFormat; - depthViewInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT; - if (depthImage.FormatHasStencilComponent()) { - depthViewInfo.subresourceRange.aspectMask |= VK_IMAGE_ASPECT_STENCIL_BIT; - } - - VkImageViewCreateInfo normalViewInfo{}; - ImageVk::GetDefaultImageViewCreateInfo( - normalViewInfo, normalImage.GetVkImage(), normalFormat); - normalViewInfo.format = normalFormat; - normalViewInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; - - VkImageViewCreateInfo roughnessMetallicViewInfo{}; - ImageVk::GetDefaultImageViewCreateInfo(roughnessMetallicViewInfo, - roughnessMetallicImage.GetVkImage(), - roughnessMetallicFormat); - roughnessMetallicViewInfo.format = roughnessMetallicFormat; - roughnessMetallicViewInfo.subresourceRange.aspectMask = - VK_IMAGE_ASPECT_COLOR_BIT; - - albedoImage.CreateImageView(albedoViewInfo); - depthImage.CreateImageView(depthViewInfo); - normalImage.CreateImageView(normalViewInfo); - roughnessMetallicImage.CreateImageView(roughnessMetallicViewInfo); + for (int i = 0; i < MAX_FRAMES_IN_FLIGHT; ++i) { + // albedo + VkRenderingAttachmentInfo &albedoInfo = m_renderInfoState.albedoInfo[i]; + RFlowResourcesVk::GetDefaultRenderingAttachmentInfo( + s_gBufferImages.albedoImages[i].GetVkImageView(), albedoInfo); + VkClearValue clearAlbedo = {{0.0f, 0.0f, 0.0f, 1.0f}}; + albedoInfo.clearValue = clearAlbedo; + + // normal + VkRenderingAttachmentInfo &normalInfo = m_renderInfoState.normalInfo[i]; + RFlowResourcesVk::GetDefaultRenderingAttachmentInfo( + s_gBufferImages.normalImages[i].GetVkImageView(), normalInfo); + VkClearValue clearNormal = {{0.0f, 0.0f, 0.0f, 0.0f}}; + normalInfo.clearValue = clearNormal; + + // roughnessMetallic + VkRenderingAttachmentInfo &roughnessMetallicInfo = + m_renderInfoState.roughnessMetallicInfo[i]; + RFlowResourcesVk::GetDefaultRenderingAttachmentInfo( + s_gBufferImages.roughnessMetallicImages[i].GetVkImageView(), + roughnessMetallicInfo); + + VkClearValue clearRoughnessMetallic = {{0.0f, 0.0f, 0.0f, 0.0f}}; + roughnessMetallicInfo.clearValue = clearRoughnessMetallic; + + // depth + VkRenderingAttachmentInfo &depthInfo = m_renderInfoState.depthInfo[i]; + RFlowResourcesVk::GetDefaultRenderingAttachmentInfo( + s_gBufferImages.depthImages[i].GetVkImageView(), depthInfo); + bool depthHasStencilComponent = + s_gBufferImages.depthImages[i].FormatHasStencilComponent(); + depthInfo.imageLayout = VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL; + depthInfo.imageLayout = + depthHasStencilComponent + ? VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL + : VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL; + VkClearValue clearDepth{}; + clearDepth.depthStencil.depth = 1.0f; + clearDepth.depthStencil.stencil = 0; + depthInfo.clearValue = clearDepth; // + // --- RENDER INFO --------------------------------------------------------- + // --- RENDER INFO --------------------------------------------------------- // - // --- Create g-buffer attachments ----------------------------------------- - VkAttachmentDescription albedoAttachment{}; - AttachmentVk::GetDefaultAttachmentDescription(albedoAttachment); - albedoAttachment.format = albedoFormat; - albedoAttachment.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; - albedoAttachment.finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; - albedoAttachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; - albedoAttachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE; - - VkAttachmentDescription depthAttachment{}; - AttachmentVk::GetDefaultAttachmentDescription(depthAttachment); - depthAttachment.format = depthFormat; - depthAttachment.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; - depthAttachment.finalLayout = - depthImage.FormatHasStencilComponent() - ? VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL - : VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL; - depthAttachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; - depthAttachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE; - - depthAttachment.stencilLoadOp = depthImage.FormatHasStencilComponent() - ? VK_ATTACHMENT_LOAD_OP_CLEAR - : VK_ATTACHMENT_LOAD_OP_DONT_CARE; - depthAttachment.stencilStoreOp = depthImage.FormatHasStencilComponent() - ? VK_ATTACHMENT_STORE_OP_STORE - : VK_ATTACHMENT_STORE_OP_DONT_CARE; - - VkAttachmentDescription normalAttachment{}; - AttachmentVk::GetDefaultAttachmentDescription(normalAttachment); - normalAttachment.format = normalFormat; - normalAttachment.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; - normalAttachment.finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; - normalAttachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; - normalAttachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE; - - VkAttachmentDescription roughnessMetallicAttachment{}; - AttachmentVk::GetDefaultAttachmentDescription(roughnessMetallicAttachment); - roughnessMetallicAttachment.format = roughnessMetallicFormat; - roughnessMetallicAttachment.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; - roughnessMetallicAttachment.finalLayout = - VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; - roughnessMetallicAttachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; - roughnessMetallicAttachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE; - - m_attachmentsVk.albedoAttachments[i].SetImageVk(&albedoImage); - m_attachmentsVk.depthAttachments[i].SetImageVk(&depthImage); - m_attachmentsVk.normalAttachments[i].SetImageVk(&normalImage); - m_attachmentsVk.roughnessMetallicAttachments[i].SetImageVk( - &roughnessMetallicImage); - - m_attachmentsVk.albedoAttachments[i].SetAttachmentDescription( - albedoAttachment); - m_attachmentsVk.depthAttachments[i].SetAttachmentDescription( - depthAttachment); - m_attachmentsVk.normalAttachments[i].SetAttachmentDescription( - normalAttachment); - m_attachmentsVk.roughnessMetallicAttachments[i].SetAttachmentDescription( - roughnessMetallicAttachment); + auto &swapchainExtent = ContextVk::Swapchain()->GetSwapchainExtent(); + VkRenderingInfo &renderingInfo = m_renderInfoState.renderingInfo[i]; + renderingInfo.sType = VK_STRUCTURE_TYPE_RENDERING_INFO; + renderingInfo.renderArea = VkRect2D{{0, 0}, swapchainExtent}; + renderingInfo.colorAttachmentCount = 3; + // std::array colorAttachments{ + // {albedoInfo, normalInfo, roughnessMetallicInfo}}; + VkRenderingAttachmentInfo colorAttachments[3]{albedoInfo, normalInfo, + roughnessMetallicInfo}; + VkRenderingAttachmentInfo depthAttachments[1]{depthInfo}; + // renderingInfo.pColorAttachments = + // m_renderInfoState.albedoInfo colorAttachments; + renderingInfo.pDepthAttachment = depthAttachments; } -} +}; // // From b8561b124af5fc886794d4822f3b5b823ccc787c Mon Sep 17 00:00:00 2001 From: __prav__ Date: Wed, 24 Dec 2025 21:31:28 -0500 Subject: [PATCH 07/36] wip: dynamic rendering day 5 --- .../Vulkan/RenderFlows/GBufferRenderFlowVk.h | 17 +++++++--- .../Vulkan/RenderFlows/RFlowResourcesVk.h | 5 +++ .../RenderFlows/GBufferRenderFlowVk.cpp | 31 +++++++++++-------- .../Popcorn/Platform/Vulkan/RendererVk.cpp | 10 +++--- 4 files changed, 40 insertions(+), 23 deletions(-) diff --git a/Engine/include/Popcorn/Platform/Vulkan/RenderFlows/GBufferRenderFlowVk.h b/Engine/include/Popcorn/Platform/Vulkan/RenderFlows/GBufferRenderFlowVk.h index c905ad1c..e887665f 100644 --- a/Engine/include/Popcorn/Platform/Vulkan/RenderFlows/GBufferRenderFlowVk.h +++ b/Engine/include/Popcorn/Platform/Vulkan/RenderFlows/GBufferRenderFlowVk.h @@ -76,11 +76,16 @@ class GBufferRenderFlowVk : public RenderFlowVk { DescriptorSetsVk m_descriptorSetsVk{}; struct RenderInfoStateVk { - std::array albedoInfo{}; - std::array normalInfo{}; - std::array - roughnessMetallicInfo{}; - std::array depthInfo{}; + std::array< + // 0: Albedo + // 1: Normal + // 2: RoughnessMetallic + std::array, MAX_FRAMES_IN_FLIGHT> + colorAttachmentInfos{}; + std::array< + // 0: Depth + std::array, MAX_FRAMES_IN_FLIGHT> + depthAttachmentInfos{}; std::array renderingInfo{}; }; @@ -96,6 +101,8 @@ class GBufferRenderFlowVk : public RenderFlowVk { std::array m_commandBuffers{}; ImageBarriersVk m_imageBarriers; + + struct RenderAttachmentInfos {}; }; GFX_NAMESPACE_END diff --git a/Engine/include/Popcorn/Platform/Vulkan/RenderFlows/RFlowResourcesVk.h b/Engine/include/Popcorn/Platform/Vulkan/RenderFlows/RFlowResourcesVk.h index c583d343..b6acc480 100644 --- a/Engine/include/Popcorn/Platform/Vulkan/RenderFlows/RFlowResourcesVk.h +++ b/Engine/include/Popcorn/Platform/Vulkan/RenderFlows/RFlowResourcesVk.h @@ -40,6 +40,11 @@ class RFlowResourcesVk { renderAttInfo.imageView = imageView; renderAttInfo.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; renderAttInfo.storeOp = VK_ATTACHMENT_STORE_OP_STORE; + // + // For the future: MSAA + renderAttInfo.resolveMode = VK_RESOLVE_MODE_NONE; + renderAttInfo.resolveImageView = VK_NULL_HANDLE; + renderAttInfo.resolveImageLayout = VK_IMAGE_LAYOUT_UNDEFINED; } static void GetDefaultRenderingInfo() {} diff --git a/Engine/src/Popcorn/Platform/Vulkan/RenderFlows/GBufferRenderFlowVk.cpp b/Engine/src/Popcorn/Platform/Vulkan/RenderFlows/GBufferRenderFlowVk.cpp index fb0a63ae..fd93fa22 100644 --- a/Engine/src/Popcorn/Platform/Vulkan/RenderFlows/GBufferRenderFlowVk.cpp +++ b/Engine/src/Popcorn/Platform/Vulkan/RenderFlows/GBufferRenderFlowVk.cpp @@ -44,14 +44,16 @@ void GBufferRenderFlowVk::CreateRenderInfoState() { // for (int i = 0; i < MAX_FRAMES_IN_FLIGHT; ++i) { // albedo - VkRenderingAttachmentInfo &albedoInfo = m_renderInfoState.albedoInfo[i]; + VkRenderingAttachmentInfo &albedoInfo = + m_renderInfoState.colorAttachmentInfos[i][0]; RFlowResourcesVk::GetDefaultRenderingAttachmentInfo( s_gBufferImages.albedoImages[i].GetVkImageView(), albedoInfo); VkClearValue clearAlbedo = {{0.0f, 0.0f, 0.0f, 1.0f}}; albedoInfo.clearValue = clearAlbedo; // normal - VkRenderingAttachmentInfo &normalInfo = m_renderInfoState.normalInfo[i]; + VkRenderingAttachmentInfo &normalInfo = + m_renderInfoState.colorAttachmentInfos[i][1]; RFlowResourcesVk::GetDefaultRenderingAttachmentInfo( s_gBufferImages.normalImages[i].GetVkImageView(), normalInfo); VkClearValue clearNormal = {{0.0f, 0.0f, 0.0f, 0.0f}}; @@ -59,7 +61,7 @@ void GBufferRenderFlowVk::CreateRenderInfoState() { // roughnessMetallic VkRenderingAttachmentInfo &roughnessMetallicInfo = - m_renderInfoState.roughnessMetallicInfo[i]; + m_renderInfoState.colorAttachmentInfos[i][2]; RFlowResourcesVk::GetDefaultRenderingAttachmentInfo( s_gBufferImages.roughnessMetallicImages[i].GetVkImageView(), roughnessMetallicInfo); @@ -68,7 +70,8 @@ void GBufferRenderFlowVk::CreateRenderInfoState() { roughnessMetallicInfo.clearValue = clearRoughnessMetallic; // depth - VkRenderingAttachmentInfo &depthInfo = m_renderInfoState.depthInfo[i]; + VkRenderingAttachmentInfo &depthInfo = + m_renderInfoState.depthAttachmentInfos[i][0]; RFlowResourcesVk::GetDefaultRenderingAttachmentInfo( s_gBufferImages.depthImages[i].GetVkImageView(), depthInfo); bool depthHasStencilComponent = @@ -89,17 +92,19 @@ void GBufferRenderFlowVk::CreateRenderInfoState() { // auto &swapchainExtent = ContextVk::Swapchain()->GetSwapchainExtent(); VkRenderingInfo &renderingInfo = m_renderInfoState.renderingInfo[i]; + renderingInfo.sType = VK_STRUCTURE_TYPE_RENDERING_INFO; - renderingInfo.renderArea = VkRect2D{{0, 0}, swapchainExtent}; + renderingInfo.renderArea = {{0, 0}, swapchainExtent}; + renderingInfo.layerCount = 1; renderingInfo.colorAttachmentCount = 3; - // std::array colorAttachments{ - // {albedoInfo, normalInfo, roughnessMetallicInfo}}; - VkRenderingAttachmentInfo colorAttachments[3]{albedoInfo, normalInfo, - roughnessMetallicInfo}; - VkRenderingAttachmentInfo depthAttachments[1]{depthInfo}; - // renderingInfo.pColorAttachments = - // m_renderInfoState.albedoInfo colorAttachments; - renderingInfo.pDepthAttachment = depthAttachments; + renderingInfo.pColorAttachments = + m_renderInfoState.colorAttachmentInfos[i].data(); + renderingInfo.pDepthAttachment = + m_renderInfoState.depthAttachmentInfos[i].data(); + + renderingInfo.pStencilAttachment = nullptr; + renderingInfo.pNext = nullptr; + renderingInfo.flags = 0; } }; diff --git a/Engine/src/Popcorn/Platform/Vulkan/RendererVk.cpp b/Engine/src/Popcorn/Platform/Vulkan/RendererVk.cpp index d60d7494..37ed8565 100644 --- a/Engine/src/Popcorn/Platform/Vulkan/RendererVk.cpp +++ b/Engine/src/Popcorn/Platform/Vulkan/RendererVk.cpp @@ -117,11 +117,11 @@ void RendererVk::PrepareRenderFlows() { for (auto &renderFlow : s_renderFlows) { PC_WARN("Preparing renderflow...") renderFlow->CreateGfxResources(); // Creates Vulkan: - // - Attachments - // - ImageBarriers - // - RenderPass - // - Framebuffer - // - Commandbuffers + // - Attachments + // - ImageBarriers + // - RenderPass + // - Framebuffer + // - Commandbuffers } s_renderFlowCmdBuffers[RenderFlows::GBuffer] = From fee9cacc67971fa50088edf4c3254f994b3b0c09 Mon Sep 17 00:00:00 2001 From: __prav__ Date: Fri, 26 Dec 2025 13:47:23 -0500 Subject: [PATCH 08/36] wip: dynamic rendering - day 6 --- .../Vulkan/Pipelines/MaterialPipelinesVk.h | 4 + .../Vulkan/Pipelines/PipelineDefsVk.h | 1 + .../Platform/Vulkan/Pipelines/PipelineVk.h | 8 ++ .../Vulkan/RenderFlows/GBufferRenderFlowVk.h | 8 +- .../Vulkan/RenderFlows/RenderFlowDefs.h | 5 ++ .../Vulkan/Pipelines/MaterialPipelinesVk.cpp | 87 +++++++++++++++++++ .../Platform/Vulkan/Pipelines/PipelineVk.cpp | 20 ++--- .../RenderFlows/GBufferRenderFlowVk.cpp | 8 +- 8 files changed, 124 insertions(+), 17 deletions(-) diff --git a/Engine/include/Popcorn/Platform/Vulkan/Pipelines/MaterialPipelinesVk.h b/Engine/include/Popcorn/Platform/Vulkan/Pipelines/MaterialPipelinesVk.h index 17f07f3f..dc83c710 100644 --- a/Engine/include/Popcorn/Platform/Vulkan/Pipelines/MaterialPipelinesVk.h +++ b/Engine/include/Popcorn/Platform/Vulkan/Pipelines/MaterialPipelinesVk.h @@ -21,6 +21,8 @@ class BasicMatPipelineVk : public PipelineVk { virtual void Create(const BufferDefs::Layout &vertexBufferLayout, const VkRenderPass &renderPass) override; + virtual void Create(const BufferDefs::Layout &vertexBufferLayout, + const PcAttachmentsInfo &attachmentLayouts) override; }; // @@ -36,6 +38,8 @@ class PbrMatPipelineVk : public PipelineVk { virtual void Create(const BufferDefs::Layout &vertexBufferLayout, const VkRenderPass &renderPass) override; + virtual void Create(const BufferDefs::Layout &vertexBufferLayout, + const PcAttachmentsInfo &attachmentLayouts) override; }; GFX_NAMESPACE_END diff --git a/Engine/include/Popcorn/Platform/Vulkan/Pipelines/PipelineDefsVk.h b/Engine/include/Popcorn/Platform/Vulkan/Pipelines/PipelineDefsVk.h index db8588d3..c0e4d301 100644 --- a/Engine/include/Popcorn/Platform/Vulkan/Pipelines/PipelineDefsVk.h +++ b/Engine/include/Popcorn/Platform/Vulkan/Pipelines/PipelineDefsVk.h @@ -23,6 +23,7 @@ struct GfxPipelineState { VkPipelineMultisampleStateCreateInfo multisampleState{}; VkPipelineColorBlendStateCreateInfo colorBlendState{}; VkPipelineLayoutCreateInfo pipelineLayout{}; + VkPipelineRenderingCreateInfo renderingInfoState{}; }; struct ComputePipelineState { diff --git a/Engine/include/Popcorn/Platform/Vulkan/Pipelines/PipelineVk.h b/Engine/include/Popcorn/Platform/Vulkan/Pipelines/PipelineVk.h index c6015eeb..ab17f14d 100644 --- a/Engine/include/Popcorn/Platform/Vulkan/Pipelines/PipelineVk.h +++ b/Engine/include/Popcorn/Platform/Vulkan/Pipelines/PipelineVk.h @@ -15,6 +15,12 @@ ENGINE_NAMESPACE_BEGIN GFX_NAMESPACE_BEGIN +typedef struct PcAttachmentsInfo { + std::vector colorFormats; + std::vector depthFormats; + std::vector stencilFormats; +} PcAttachmentsInfo; + template class PipelineVk { public: [[nodiscard]] inline const VkPipeline &GetVkPipeline() const { @@ -28,6 +34,8 @@ template class PipelineVk { virtual void Create(const BufferDefs::Layout &vertexBufferLayout, const VkRenderPass &renderPass) = 0; + virtual void Create(const BufferDefs::Layout &vertexBufferLayout, + const PcAttachmentsInfo &attachmentLayouts) = 0; void Destroy(); diff --git a/Engine/include/Popcorn/Platform/Vulkan/RenderFlows/GBufferRenderFlowVk.h b/Engine/include/Popcorn/Platform/Vulkan/RenderFlows/GBufferRenderFlowVk.h index e887665f..b6e5ede7 100644 --- a/Engine/include/Popcorn/Platform/Vulkan/RenderFlows/GBufferRenderFlowVk.h +++ b/Engine/include/Popcorn/Platform/Vulkan/RenderFlows/GBufferRenderFlowVk.h @@ -76,15 +76,13 @@ class GBufferRenderFlowVk : public RenderFlowVk { DescriptorSetsVk m_descriptorSetsVk{}; struct RenderInfoStateVk { - std::array< + PcRenderAttachmentInfoState<3> // 0: Albedo // 1: Normal // 2: RoughnessMetallic - std::array, MAX_FRAMES_IN_FLIGHT> colorAttachmentInfos{}; - std::array< + PcRenderAttachmentInfoState<1> // 0: Depth - std::array, MAX_FRAMES_IN_FLIGHT> depthAttachmentInfos{}; std::array renderingInfo{}; @@ -101,8 +99,6 @@ class GBufferRenderFlowVk : public RenderFlowVk { std::array m_commandBuffers{}; ImageBarriersVk m_imageBarriers; - - struct RenderAttachmentInfos {}; }; GFX_NAMESPACE_END diff --git a/Engine/include/Popcorn/Platform/Vulkan/RenderFlows/RenderFlowDefs.h b/Engine/include/Popcorn/Platform/Vulkan/RenderFlows/RenderFlowDefs.h index cde36d97..5ed67544 100644 --- a/Engine/include/Popcorn/Platform/Vulkan/RenderFlows/RenderFlowDefs.h +++ b/Engine/include/Popcorn/Platform/Vulkan/RenderFlows/RenderFlowDefs.h @@ -84,5 +84,10 @@ using PcFramesDepthImageBarriers = using PcPresentationImageBarriers = std::vector>; +template +using PcRenderAttachmentInfoState = + std::array, + MAX_FRAMES_IN_FLIGHT>; + GFX_NAMESPACE_END ENGINE_NAMESPACE_END diff --git a/Engine/src/Popcorn/Platform/Vulkan/Pipelines/MaterialPipelinesVk.cpp b/Engine/src/Popcorn/Platform/Vulkan/Pipelines/MaterialPipelinesVk.cpp index b91d381e..708b5da0 100644 --- a/Engine/src/Popcorn/Platform/Vulkan/Pipelines/MaterialPipelinesVk.cpp +++ b/Engine/src/Popcorn/Platform/Vulkan/Pipelines/MaterialPipelinesVk.cpp @@ -28,6 +28,9 @@ void BasicMatPipelineVk::Create(const BufferDefs::Layout &vertexBufferLayout, const VkRenderPass &renderPass) { const VkDevice &device = ContextVk::Device()->GetDevice(); + // + // --- SET SHADER STUFF ------------------------------------------------------ + // --- SET SHADER STUFF ------------------------------------------------------ const Buffer &vertShaderBuffer = Material::GetShader(ShaderStages::VertexBit); const Buffer &fragShaderBuffer = @@ -42,6 +45,9 @@ void BasicMatPipelineVk::Create(const BufferDefs::Layout &vertexBufferLayout, SetShaderStagesMask(ShaderStages::VertexBit | ShaderStages::FragmentBit); CreateShaderStageCreateInfos(shaderModules); + // + // --- VBO/IBO STUFF --------------------------------------------------------- + // --- VBO/IBO STUFF --------------------------------------------------------- VkVertexInputBindingDescription bindingDescription{}; VertexBufferVk::GetDefaultVertexInputBindingDescription(vertexBufferLayout, bindingDescription); @@ -76,6 +82,12 @@ void BasicMatPipelineVk::Create(const BufferDefs::Layout &vertexBufferLayout, pipelineState.depthStencilState.front = {}; pipelineState.depthStencilState.back = {}; + pipelineState.renderingInfoState.sType = + VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO; + pipelineState.renderingInfoState.pNext = VK_NULL_HANDLE; + pipelineState.renderingInfoState.colorAttachmentCount = 3; + // pipelineState.renderingInfoState.pColorAttachmentFormats = + auto *layouts = ContextVk::DescriptorLayouts(); VkDescriptorSetLayout &cameraLayout = layouts->GetLayout(); @@ -183,5 +195,80 @@ void PbrMatPipelineVk::Create(const BufferDefs::Layout &vertexBufferLayout, PC_DestroyShaderModule(device, fragShaderModule); }; +void PbrMatPipelineVk::Create(const BufferDefs::Layout &vertexBufferLayout, + const PcAttachmentsInfo &attachmentLayouts) { + const VkDevice &device = ContextVk::Device()->GetDevice(); + + const Buffer &vertShaderBuffer = + Material::GetShader(ShaderStages::VertexBit); + const Buffer &fragShaderBuffer = + Material::GetShader(ShaderStages::FragmentBit); + + auto vertShaderModule = PC_CreateShaderModule(device, vertShaderBuffer); + auto fragShaderModule = PC_CreateShaderModule(device, fragShaderBuffer); + + std::forward_list shaderModules = {vertShaderModule, + fragShaderModule}; + + SetShaderStagesMask(ShaderStages::VertexBit | ShaderStages::FragmentBit); + CreateShaderStageCreateInfos(shaderModules); + + VkVertexInputBindingDescription bindingDescription{}; + VertexBufferVk::GetDefaultVertexInputBindingDescription(vertexBufferLayout, + bindingDescription); + bindingDescription.binding = 0; + + std::vector attributeDescriptions{}; + VertexBufferVk::GetDefaultVertexInputAttributeDescriptions( + vertexBufferLayout, attributeDescriptions); + + std::vector colorBlendAttachments{}; + colorBlendAttachments.resize(3); + + GfxPipelineState pipelineState{}; + PipelineUtilsVk::GetDefaultGfxPipelineState(vertexBufferLayout, pipelineState, + colorBlendAttachments); + + pipelineState.vertexInputState.vertexBindingDescriptionCount = 1; + pipelineState.vertexInputState.vertexAttributeDescriptionCount = + static_cast(attributeDescriptions.size()); + pipelineState.vertexInputState.pVertexBindingDescriptions = + &bindingDescription; + pipelineState.vertexInputState.pVertexAttributeDescriptions = + attributeDescriptions.data(); + + pipelineState.depthStencilState.depthTestEnable = VK_TRUE; + pipelineState.depthStencilState.depthWriteEnable = VK_TRUE; + pipelineState.depthStencilState.depthCompareOp = VK_COMPARE_OP_LESS; + pipelineState.depthStencilState.depthBoundsTestEnable = VK_FALSE; + pipelineState.depthStencilState.minDepthBounds = 0.0f; + pipelineState.depthStencilState.maxDepthBounds = 1.0f; + pipelineState.depthStencilState.stencilTestEnable = VK_FALSE; + pipelineState.depthStencilState.front = {}; + pipelineState.depthStencilState.back = {}; + + auto *layouts = ContextVk::DescriptorLayouts(); + VkDescriptorSetLayout &cameraLayout = + layouts->GetLayout(); + VkDescriptorSetLayout &pbrMatLayout = + layouts->GetLayout(); + VkDescriptorSetLayout &submeshLayout = + layouts->GetLayout(); + + std::array dSetLayouts = { + cameraLayout, pbrMatLayout, submeshLayout}; + + // Pipeline Layout (descriptor set layout data) + pipelineState.pipelineLayout.setLayoutCount = dSetLayouts.size(); + pipelineState.pipelineLayout.pSetLayouts = dSetLayouts.data(); + + CreatePipelineLayout(device, pipelineState.pipelineLayout); + CreateVkPipeline(device, pipelineState, renderPass); + + // Destroy shader modules + PC_DestroyShaderModule(device, vertShaderModule); + PC_DestroyShaderModule(device, fragShaderModule); +}; + GFX_NAMESPACE_END ENGINE_NAMESPACE_END diff --git a/Engine/src/Popcorn/Platform/Vulkan/Pipelines/PipelineVk.cpp b/Engine/src/Popcorn/Platform/Vulkan/Pipelines/PipelineVk.cpp index cc9688b7..3322041a 100644 --- a/Engine/src/Popcorn/Platform/Vulkan/Pipelines/PipelineVk.cpp +++ b/Engine/src/Popcorn/Platform/Vulkan/Pipelines/PipelineVk.cpp @@ -8,7 +8,7 @@ GFX_NAMESPACE_BEGIN template <> void PipelineVk::CreateVkPipeline( - const VkDevice &device, const PipelineStateType &pipelineCreateInfo, + const VkDevice &device, const PipelineStateType &pipelineState, const VkRenderPass &renderPass) { if (m_pipeline != VK_NULL_HANDLE) { @@ -16,7 +16,7 @@ void PipelineVk::CreateVkPipeline( return; }; - GfxPipelineState createInfo = pipelineCreateInfo; + const GfxPipelineState &gfxPipelineState = pipelineState; if (m_shaderStageCreateInfos.size() == 0) { PC_WARN("No shader stages set") }; @@ -29,15 +29,15 @@ void PipelineVk::CreateVkPipeline( pipelineInfo.stageCount = m_shaderStageCreateInfos.size(); pipelineInfo.pStages = m_shaderStageCreateInfos.data(); - pipelineInfo.pVertexInputState = &createInfo.vertexInputState; - pipelineInfo.pInputAssemblyState = &createInfo.inputAssemblyState; - pipelineInfo.pViewportState = &createInfo.viewportState; - pipelineInfo.pRasterizationState = &createInfo.rasterizationState; - pipelineInfo.pDepthStencilState = &createInfo.depthStencilState; + pipelineInfo.pVertexInputState = &gfxPipelineState.vertexInputState; + pipelineInfo.pInputAssemblyState = &gfxPipelineState.inputAssemblyState; + pipelineInfo.pViewportState = &gfxPipelineState.viewportState; + pipelineInfo.pRasterizationState = &gfxPipelineState.rasterizationState; + pipelineInfo.pDepthStencilState = &gfxPipelineState.depthStencilState; // pipelineInfo.pDepthStencilState = nullptr; - pipelineInfo.pMultisampleState = &createInfo.multisampleState; - pipelineInfo.pColorBlendState = &createInfo.colorBlendState; - pipelineInfo.pDynamicState = &createInfo.dynamicState; + pipelineInfo.pMultisampleState = &gfxPipelineState.multisampleState; + pipelineInfo.pColorBlendState = &gfxPipelineState.colorBlendState; + pipelineInfo.pDynamicState = &gfxPipelineState.dynamicState; pipelineInfo.layout = m_pipelineLayout; diff --git a/Engine/src/Popcorn/Platform/Vulkan/RenderFlows/GBufferRenderFlowVk.cpp b/Engine/src/Popcorn/Platform/Vulkan/RenderFlows/GBufferRenderFlowVk.cpp index fd93fa22..0bfb6fae 100644 --- a/Engine/src/Popcorn/Platform/Vulkan/RenderFlows/GBufferRenderFlowVk.cpp +++ b/Engine/src/Popcorn/Platform/Vulkan/RenderFlows/GBufferRenderFlowVk.cpp @@ -428,7 +428,13 @@ void GBufferRenderFlowVk::UpdateDescriptorSetsLocal() { // --- CREATE PIPELINES -------------------------------------------------------- // void GBufferRenderFlowVk::CreatePipelines() { - // Draws Gltf models + // + // PASS + // ---- + // 1. Dynamic renderflow info + // 2. Create one material pipeline instead of multiple (maybe one inbuilt, and + // one custom) + m_basicMatPipelineVk.Create(GltfVertexBufferLayout, m_renderPass.GetVkRenderPass()); m_pbrMatPipelineVk.Create(GltfVertexBufferLayout, From 4ec35ac73b1eb075e13cb8a025a241b3e7b35346 Mon Sep 17 00:00:00 2001 From: __prav__ Date: Sat, 27 Dec 2025 17:49:15 -0500 Subject: [PATCH 09/36] wip: dynamic rendering -- day 7 --- Engine/include/Popcorn.h | 25 +++++++++++++++++-- .../Platform/Vulkan/Pipelines/PipelineVk.h | 4 +++ 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/Engine/include/Popcorn.h b/Engine/include/Popcorn.h index 1458b61c..38ac03b1 100644 --- a/Engine/include/Popcorn.h +++ b/Engine/include/Popcorn.h @@ -42,19 +42,40 @@ static void UnregisterScene(Scene &scene) { s_renderer->RemoveScene(&scene); }; static void StartGame() { // TODO: Move the ownership of commandbuffers to Renderflow base class - s_renderer->CreateRenderFlows(); + s_renderer->CreateRenderFlows(); // NEW: Make your own renderflows + // 1. Each renderflow takes in + // a. Attachments (and Info) + // b. RenderInfo + // c. PipelineInfo + // s_renderer->PrepareRenderFlows(); // Creates attachments, renderflows, // framebuffers, and command buffers + // s_renderer->AssignSceneObjectsToRenderFlows(); // Sorts submeshes material // wise & adds to renderflows + // s_renderer->CreateRenderFlowResources(); // Renderflow submeshes converted and // copied to vulkan memory objects + // 1. Alloc Memory + // 2. Create Samplers + // 3. Alloc Shaders + // 4. Alloc DSets Global + // 5. Update DSets Global + // 6. Loops renderflows - + // a. Alloc DSets Local + // b. Update DSets Local + // c. Create Pipelines + // 7. Free Shaders #ifdef PC_DEBUG // s_renderer->PrintScenes(); // s_renderer->DebugPreGameLoop(); #endif - s_application->StartGameLoop(); // Starts game loop + s_application + ->StartGameLoop(); // Starts game loop + // 1. Update Layers - DOES NOTHING - FIX IT! Move the + // update stuff here from the Render layers + // 2. Render Layers - Copy Dynamic UBOs to memory }; static SplineFactory *GetSplineFactory() { return ContextGfx::AppSplines(); } diff --git a/Engine/include/Popcorn/Platform/Vulkan/Pipelines/PipelineVk.h b/Engine/include/Popcorn/Platform/Vulkan/Pipelines/PipelineVk.h index ab17f14d..de684e60 100644 --- a/Engine/include/Popcorn/Platform/Vulkan/Pipelines/PipelineVk.h +++ b/Engine/include/Popcorn/Platform/Vulkan/Pipelines/PipelineVk.h @@ -63,6 +63,10 @@ template class PipelineVk { const PipelineStateType &pipelineCreateInfo, const VkRenderPass &renderPass); + // void CreateVkPipeline(const VkDevice &device, + // const PipelineStateType &pipelineCreateInfo, + // const VkRenderPass &renderPass); + void CreateShaderStageCreateInfos( std::forward_list &shaderModules); From 138c06320c6b8258d4f3fb47842d4c2017df28d2 Mon Sep 17 00:00:00 2001 From: __prav__ Date: Mon, 29 Dec 2025 21:33:59 -0500 Subject: [PATCH 10/36] wip: dynamic rendering - day 7 --- Engine/include/Popcorn.h | 78 +++++++++++++++---- Engine/src/Popcorn/Core/Application.cpp | 1 + .../Vulkan/Pipelines/MaterialPipelinesVk.cpp | 6 ++ .../renderflows/gbufferRflow.h | 0 .../renderflows/lightingRflow.h | 0 .../renderflows/shadowsRflow.h | 0 .../renderflows/transclucencyRflow.h | 0 7 files changed, 72 insertions(+), 13 deletions(-) create mode 100644 Sandbox/02-Street-Scene/renderflows/gbufferRflow.h create mode 100644 Sandbox/02-Street-Scene/renderflows/lightingRflow.h create mode 100644 Sandbox/02-Street-Scene/renderflows/shadowsRflow.h create mode 100644 Sandbox/02-Street-Scene/renderflows/transclucencyRflow.h diff --git a/Engine/include/Popcorn.h b/Engine/include/Popcorn.h index 38ac03b1..20f491da 100644 --- a/Engine/include/Popcorn.h +++ b/Engine/include/Popcorn.h @@ -40,20 +40,48 @@ static void AddLayer(Layer *layer) { static void RegisterScene(Scene &scene) { s_renderer->AddScene(&scene); }; static void UnregisterScene(Scene &scene) { s_renderer->RemoveScene(&scene); }; +static void MakeRenderFlows() { + enum class RenderFlowKind { Forward = 0, Deferred }; + enum class ImageAttachmentKind { + ColorRGBA_HighRes, + ColorRGBA_LowRes, + Depth_Auto, + }; + + typedef struct RenderFlowCreateInfo { + const char *name; + RenderFlowKind renderFlowkind; + std::vector imageAttachmentKind; + // std::vector<>() + } RenderFlowCreateInfo; + + // s_renderer->DefineRenderFlow( + // { + // } + // ) +} + static void StartGame() { // TODO: Move the ownership of commandbuffers to Renderflow base class - s_renderer->CreateRenderFlows(); // NEW: Make your own renderflows - // 1. Each renderflow takes in - // a. Attachments (and Info) - // b. RenderInfo - // c. PipelineInfo - // - s_renderer->PrepareRenderFlows(); // Creates attachments, renderflows, - // framebuffers, and command buffers - // + // + // + // NEW: --- Make your own renderflows --- + s_renderer->CreateRenderFlows(); // 1. Each renderflow takes in + // a. Attachments (and Info) + // b. RenderInfo + // c. PipelineInfo + // + s_renderer->PrepareRenderFlows( + // + // Images / Buffers + // + ); // Creates attachments, renderflows, + // framebuffers, and command buffers + // s_renderer->AssignSceneObjectsToRenderFlows(); // Sorts submeshes material // wise & adds to renderflows - // + // 1. Calculates offsets + + // alignment and stuff s_renderer->CreateRenderFlowResources(); // Renderflow submeshes converted and // copied to vulkan memory objects // 1. Alloc Memory @@ -73,9 +101,33 @@ static void StartGame() { s_application ->StartGameLoop(); // Starts game loop - // 1. Update Layers - DOES NOTHING - FIX IT! Move the - // update stuff here from the Render layers - // 2. Render Layers - Copy Dynamic UBOs to memory + // 1. Update Layers - Update transforms etc. for render + // 2. Render Layers - + // a. Copy Dynamic UBOs to memory + // b. Begin command buffer + // c. Begin Renderpass/rendering + // d. Set viewport & scissor + // e. Bind VBO + // f. Bind IBO + // g. Bind basicMat pipeline + // h. Bind D-Sets (global - camera stuff) + // i. Loop over material (basicMat) buckets - + // i1. Bind D-Sets (local - basic mat) + // i2. Loop over submeshes - + // i1a. Bind D-Sets (local - submesh) + // i2a. DRAW indexed + // j. Bind pbrMat pipeline + // k. Bind D-Sets (global - camera stuff) + // l. Loop over material (pbrMat) buckets - + // l1. Bind D-Sets (local - pbr mat) + // l2. Loop over submeshes - + // l1a. Bind D-Sets (local - submesh) + // l2a. DRAW indexed + // m. End Renderpass/rendering + // n. Barrier transition stuff + // o. End command buffer + // + // }; static SplineFactory *GetSplineFactory() { return ContextGfx::AppSplines(); } diff --git a/Engine/src/Popcorn/Core/Application.cpp b/Engine/src/Popcorn/Core/Application.cpp index eb9ebac6..1a4fe938 100644 --- a/Engine/src/Popcorn/Core/Application.cpp +++ b/Engine/src/Popcorn/Core/Application.cpp @@ -109,6 +109,7 @@ bool Application::OnWindowClose(WindowCloseEvent &e) const { } bool Application::OnClockTick(TimeEvent &e) { + // Polls for window events (keyboard, mouse etc) Window::OnUpdate(e); // diff --git a/Engine/src/Popcorn/Platform/Vulkan/Pipelines/MaterialPipelinesVk.cpp b/Engine/src/Popcorn/Platform/Vulkan/Pipelines/MaterialPipelinesVk.cpp index 708b5da0..0fe6a5ff 100644 --- a/Engine/src/Popcorn/Platform/Vulkan/Pipelines/MaterialPipelinesVk.cpp +++ b/Engine/src/Popcorn/Platform/Vulkan/Pipelines/MaterialPipelinesVk.cpp @@ -247,6 +247,12 @@ void PbrMatPipelineVk::Create(const BufferDefs::Layout &vertexBufferLayout, pipelineState.depthStencilState.front = {}; pipelineState.depthStencilState.back = {}; + pipelineState.renderingInfoState.sType = + VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO; + pipelineState.renderingInfoState.pNext = VK_NULL_HANDLE; + pipelineState.renderingInfoState.colorAttachmentCount = 3; + // pipelineState.renderingInfoState.pColorAttachmentFormats = + auto *layouts = ContextVk::DescriptorLayouts(); VkDescriptorSetLayout &cameraLayout = layouts->GetLayout(); diff --git a/Sandbox/02-Street-Scene/renderflows/gbufferRflow.h b/Sandbox/02-Street-Scene/renderflows/gbufferRflow.h new file mode 100644 index 00000000..e69de29b diff --git a/Sandbox/02-Street-Scene/renderflows/lightingRflow.h b/Sandbox/02-Street-Scene/renderflows/lightingRflow.h new file mode 100644 index 00000000..e69de29b diff --git a/Sandbox/02-Street-Scene/renderflows/shadowsRflow.h b/Sandbox/02-Street-Scene/renderflows/shadowsRflow.h new file mode 100644 index 00000000..e69de29b diff --git a/Sandbox/02-Street-Scene/renderflows/transclucencyRflow.h b/Sandbox/02-Street-Scene/renderflows/transclucencyRflow.h new file mode 100644 index 00000000..e69de29b From 52d5ed6ecb40c86b1cc6becbf6e98b8fd7ec10d5 Mon Sep 17 00:00:00 2001 From: __prav__ Date: Thu, 1 Jan 2026 21:02:41 -0500 Subject: [PATCH 11/36] wip: dynamic rendering and render map for future - day 8 --- Engine/include/Api.h | 61 ++++++++++++++++++++++++++++++++++++++++ Engine/include/Popcorn.h | 10 ++++--- 2 files changed, 67 insertions(+), 4 deletions(-) create mode 100644 Engine/include/Api.h diff --git a/Engine/include/Api.h b/Engine/include/Api.h new file mode 100644 index 00000000..a62a4e36 --- /dev/null +++ b/Engine/include/Api.h @@ -0,0 +1,61 @@ +#pragma once + +#include "GlobalMacros.h" +#include + +ENGINE_NAMESPACE_BEGIN +GFX_NAMESPACE_BEGIN + +// +// Typedefs --------------------------------------------------------------- +// Typedefs --------------------------------------------------------------- +// Typedefs --------------------------------------------------------------- + +enum class DrawKind { Geometry = 0, FullscreenTri }; +enum class DrawTargetKind { ColorImage, DepthImage }; + +enum class ColorFormat { + Low_UNorm8_Linear, + Low_UNorm8_SRGB, + Medium_Float16, + High_Float32, +}; + +enum class DepthFormat { + Low_D16, + Medium_D24, + High_D32, +}; + +template struct DrawAttachment; + +template +struct DrawAttachment { + // TODO: Add a "tuple" of ColorFormats (Vk pipelines take multiple color + // attachments, MRT - Multiple Render Targets) +}; + +template <> struct DrawAttachment { + // TODO: Add a single DepthFormat (Vk pipelines only every take one depth + // attachment each) +}; + +static DrawAttachment imgsColor5{}; +static DrawAttachment img2{}; + +typedef struct { +} DrawData; + +typedef struct { + uint16_t col; + uint16_t row; + +} GfxPipeline; + +// +// Typedefs --------------------------------------------------------------- +// Typedefs --------------------------------------------------------------- +// Typedefs --------------------------------------------------------------- + +GFX_NAMESPACE_END +ENGINE_NAMESPACE_END diff --git a/Engine/include/Popcorn.h b/Engine/include/Popcorn.h index 20f491da..a04acf29 100644 --- a/Engine/include/Popcorn.h +++ b/Engine/include/Popcorn.h @@ -48,7 +48,12 @@ static void MakeRenderFlows() { Depth_Auto, }; - typedef struct RenderFlowCreateInfo { + typedef struct { + ImageAttachmentKind kind; + + } RFlowResource; + + typedef struct { const char *name; RenderFlowKind renderFlowkind; std::vector imageAttachmentKind; @@ -64,7 +69,6 @@ static void MakeRenderFlows() { static void StartGame() { // TODO: Move the ownership of commandbuffers to Renderflow base class // - // // NEW: --- Make your own renderflows --- s_renderer->CreateRenderFlows(); // 1. Each renderflow takes in // a. Attachments (and Info) @@ -72,9 +76,7 @@ static void StartGame() { // c. PipelineInfo // s_renderer->PrepareRenderFlows( - // // Images / Buffers - // ); // Creates attachments, renderflows, // framebuffers, and command buffers // From 9eb581ff5ede7b6616fb8a2f542e42625749816b Mon Sep 17 00:00:00 2001 From: __prav__ Date: Fri, 2 Jan 2026 17:45:04 -0500 Subject: [PATCH 12/36] wip: rehaul + dynamic renderflows design --- Engine/include/Api.h | 47 +++++++++++++------ .../Popcorn/Graphics/Materials/Material.h | 8 +--- .../Platform/Vulkan/Memory/MemoryDefsVk.h | 3 ++ .../Popcorn/Platform/Vulkan/Memory/MemoryVk.h | 4 +- .../Vulkan/RenderFlows/RenderFlowVk.h | 4 +- Engine/include/Popcorn/Scene/GameObject.h | 7 --- Engine/include/Popcorn/Scene/Scene.h | 3 +- .../Platform/Vulkan/Memory/MemoryVk.cpp | 10 ++-- .../RenderFlows/GBufferRenderFlowVk.cpp | 4 +- .../Vulkan/RenderFlows/RenderFlowVk.cpp | 6 ++- 10 files changed, 57 insertions(+), 39 deletions(-) diff --git a/Engine/include/Api.h b/Engine/include/Api.h index a62a4e36..bf825264 100644 --- a/Engine/include/Api.h +++ b/Engine/include/Api.h @@ -1,15 +1,17 @@ #pragma once +#include "BufferObjects.h" #include "GlobalMacros.h" +#include #include ENGINE_NAMESPACE_BEGIN GFX_NAMESPACE_BEGIN // -// Typedefs --------------------------------------------------------------- -// Typedefs --------------------------------------------------------------- -// Typedefs --------------------------------------------------------------- +// Attachments stuff ------------------------------------------------------ +// Attachments stuff ------------------------------------------------------ +// Attachments stuff ------------------------------------------------------ enum class DrawKind { Geometry = 0, FullscreenTri }; enum class DrawTargetKind { ColorImage, DepthImage }; @@ -31,31 +33,48 @@ template struct DrawAttachment; template struct DrawAttachment { - // TODO: Add a "tuple" of ColorFormats (Vk pipelines take multiple color - // attachments, MRT - Multiple Render Targets) + static constexpr uint16_t countValue = Count; + std::array colorFormats; }; template <> struct DrawAttachment { - // TODO: Add a single DepthFormat (Vk pipelines only every take one depth - // attachment each) + static constexpr uint16_t countValue = 1; + std::array depthFormats; }; -static DrawAttachment imgsColor5{}; -static DrawAttachment img2{}; +// +// Scene data ------------------------------------------------------------- +// Scene data ------------------------------------------------------------- +// Scene data ------------------------------------------------------------- +typedef struct { + BufferDefs::Layout vboLayout; + VertexBuffer *vbo; + IndexBuffer *ibo; +} GeometryData; + +// typedef struct {} + +typedef struct { + uint32_t sceneId; +} SceneData; +// +// VBO IBO UBO stuff ------------------------------------------------------ +// VBO IBO UBO stuff ------------------------------------------------------ +// VBO IBO UBO stuff ------------------------------------------------------ typedef struct { } DrawData; +// +// Pipelines stuff -------------------------------------------------------- +// Pipelines stuff -------------------------------------------------------- +// Pipelines stuff -------------------------------------------------------- + typedef struct { uint16_t col; uint16_t row; } GfxPipeline; -// -// Typedefs --------------------------------------------------------------- -// Typedefs --------------------------------------------------------------- -// Typedefs --------------------------------------------------------------- - GFX_NAMESPACE_END ENGINE_NAMESPACE_END diff --git a/Engine/include/Popcorn/Graphics/Materials/Material.h b/Engine/include/Popcorn/Graphics/Materials/Material.h index 3f3f5841..7b88f2f3 100644 --- a/Engine/include/Popcorn/Graphics/Materials/Material.h +++ b/Engine/include/Popcorn/Graphics/Materials/Material.h @@ -15,12 +15,8 @@ class Mesh; template class Material { public: - Material() { - // PC_PRINT("CREATED", TagType::Constr, "Material.h"); - } - virtual ~Material() { - // PC_PRINT("DESTROYED", TagType::Destr, "Material.h"); - } + Material() = default; + virtual ~Material() {} static constexpr MaterialTypes type_value = T; diff --git a/Engine/include/Popcorn/Platform/Vulkan/Memory/MemoryDefsVk.h b/Engine/include/Popcorn/Platform/Vulkan/Memory/MemoryDefsVk.h index f8a1d641..bcc1a45d 100644 --- a/Engine/include/Popcorn/Platform/Vulkan/Memory/MemoryDefsVk.h +++ b/Engine/include/Popcorn/Platform/Vulkan/Memory/MemoryDefsVk.h @@ -21,6 +21,9 @@ template using PcMaterialSubmeshesMap = std::unordered_map *>>; +template +using PcMaterialSubmeshIndexMap = std::vector; + struct PcSubmeshOffsets { VkDeviceSize vboOffset = 0; VkDeviceSize iboOffset = 0; diff --git a/Engine/include/Popcorn/Platform/Vulkan/Memory/MemoryVk.h b/Engine/include/Popcorn/Platform/Vulkan/Memory/MemoryVk.h index 271263f6..d4b06ded 100644 --- a/Engine/include/Popcorn/Platform/Vulkan/Memory/MemoryVk.h +++ b/Engine/include/Popcorn/Platform/Vulkan/Memory/MemoryVk.h @@ -63,8 +63,10 @@ class MemoryVk { // Dynamic buffer data, they all change per frame template - void FillUbosSubmesh(PcMaterialSubmeshesMap &materialSubmeshesMap, + void FillUbosSubmesh(PcMaterialSubmeshIndexMap &materialSubmeshIndexMap, + PcMaterialSubmeshesMap &materialSubmeshesMap, const uint32_t currentFrame); + void FillUbosSsbosLightCameraEmpty(std::vector &lights, std::vector &cameras, std::vector &emptys, diff --git a/Engine/include/Popcorn/Platform/Vulkan/RenderFlows/RenderFlowVk.h b/Engine/include/Popcorn/Platform/Vulkan/RenderFlows/RenderFlowVk.h index eaac2137..f52d9cfc 100644 --- a/Engine/include/Popcorn/Platform/Vulkan/RenderFlows/RenderFlowVk.h +++ b/Engine/include/Popcorn/Platform/Vulkan/RenderFlows/RenderFlowVk.h @@ -151,8 +151,8 @@ class RenderFlowVk { s_basicMatSubmeshBuckets; static PcMaterialSubmeshesMap s_pbrMatSubmeshBuckets; - static std::vector s_basicMatBucketDrawOrder; - static std::vector s_pbrMatBucketDrawOrder; + static PcMaterialSubmeshIndexMap s_basicMatDrawOrder; + static PcMaterialSubmeshIndexMap s_pbrMatDrawOrder; static std::vector s_lights; static std::vector s_cameras; diff --git a/Engine/include/Popcorn/Scene/GameObject.h b/Engine/include/Popcorn/Scene/GameObject.h index 75fc0657..4e6922b9 100644 --- a/Engine/include/Popcorn/Scene/GameObject.h +++ b/Engine/include/Popcorn/Scene/GameObject.h @@ -7,7 +7,6 @@ #include "Transforms.h" #include #include -#include #include #include #include @@ -17,12 +16,6 @@ ENGINE_NAMESPACE_BEGIN GFX_NAMESPACE_BEGIN -struct SceneData { - uint32_t sceneId; - // TODO: make this definition - // like ambient lights data, env map etc. -}; - enum class GameObjectTypes { None = 0, Mesh, diff --git a/Engine/include/Popcorn/Scene/Scene.h b/Engine/include/Popcorn/Scene/Scene.h index b306bc0f..874e47a7 100644 --- a/Engine/include/Popcorn/Scene/Scene.h +++ b/Engine/include/Popcorn/Scene/Scene.h @@ -5,7 +5,6 @@ #include "GlobalMacros.h" #include "Popcorn/Core/Base.h" #include "Popcorn/Core/Time.h" -#include #include #include #include @@ -75,7 +74,7 @@ class Scene { private: static uint32_t s_sceneId; - SceneData m_sceneData{}; // like ambient lights data, env map etc. + // SceneData m_sceneData{}; // like ambient lights data, env map etc. std::vector m_nodes; std::unordered_map m_gameObjectsByName; diff --git a/Engine/src/Popcorn/Platform/Vulkan/Memory/MemoryVk.cpp b/Engine/src/Popcorn/Platform/Vulkan/Memory/MemoryVk.cpp index c8a7f199..808d4768 100644 --- a/Engine/src/Popcorn/Platform/Vulkan/Memory/MemoryVk.cpp +++ b/Engine/src/Popcorn/Platform/Vulkan/Memory/MemoryVk.cpp @@ -268,9 +268,13 @@ void MemoryVk::FillVbosIbosUbosSubmeshMaterial( }; template -void MemoryVk::FillUbosSubmesh(PcMaterialSubmeshesMap &materialSubmeshesMap, - const uint32_t currentFrame) { - for (auto &[matId, submeshes] : materialSubmeshesMap) { +void MemoryVk::FillUbosSubmesh( + PcMaterialSubmeshIndexMap &materialSubmeshIndexMap, + PcMaterialSubmeshesMap &materialSubmeshesMap, + const uint32_t currentFrame) { + for (MaterialHashType matId : materialSubmeshIndexMap) { + auto &submeshes = materialSubmeshesMap[matId]; + for (size_t i = 0; i < submeshes.size(); ++i) { Submesh *submesh = submeshes[i]; const glm::mat4 &worldMatrix = submesh->GetParentMesh()->GetWorldMatrix(); diff --git a/Engine/src/Popcorn/Platform/Vulkan/RenderFlows/GBufferRenderFlowVk.cpp b/Engine/src/Popcorn/Platform/Vulkan/RenderFlows/GBufferRenderFlowVk.cpp index 0bfb6fae..fde854ec 100644 --- a/Engine/src/Popcorn/Platform/Vulkan/RenderFlows/GBufferRenderFlowVk.cpp +++ b/Engine/src/Popcorn/Platform/Vulkan/RenderFlows/GBufferRenderFlowVk.cpp @@ -559,7 +559,7 @@ void GBufferRenderFlowVk::RecordCommandBuffer(const uint32_t frameIndex, cameraSets.size(), cameraSets.data(), 1, &cameraOffset); - for (const MaterialHashType materialHash : s_basicMatBucketDrawOrder) { + for (const MaterialHashType materialHash : s_basicMatDrawOrder) { auto &submeshes = s_basicMatSubmeshBuckets[materialHash]; uint32_t basicMatOffset = bufferOffsets.materialOffsets[materialHash]; @@ -602,7 +602,7 @@ void GBufferRenderFlowVk::RecordCommandBuffer(const uint32_t frameIndex, cameraSets.size(), cameraSets.data(), 1, &cameraOffset); - for (const MaterialHashType materialHash : s_pbrMatBucketDrawOrder) { + for (const MaterialHashType materialHash : s_pbrMatDrawOrder) { auto &submeshes = s_pbrMatSubmeshBuckets[materialHash]; uint32_t pbrMatOffset = bufferOffsets.materialOffsets[materialHash]; diff --git a/Engine/src/Popcorn/Platform/Vulkan/RenderFlows/RenderFlowVk.cpp b/Engine/src/Popcorn/Platform/Vulkan/RenderFlows/RenderFlowVk.cpp index e0237211..b5e3fb73 100644 --- a/Engine/src/Popcorn/Platform/Vulkan/RenderFlows/RenderFlowVk.cpp +++ b/Engine/src/Popcorn/Platform/Vulkan/RenderFlows/RenderFlowVk.cpp @@ -21,8 +21,10 @@ PcMaterialSubmeshesMap PcMaterialSubmeshesMap RenderFlowVk::s_pbrMatSubmeshBuckets{}; -std::vector RenderFlowVk::s_basicMatBucketDrawOrder{}; -std::vector RenderFlowVk::s_pbrMatBucketDrawOrder{}; +PcMaterialSubmeshIndexMap + RenderFlowVk::s_basicMatDrawOrder{}; +PcMaterialSubmeshIndexMap + RenderFlowVk::s_pbrMatDrawOrder{}; std::vector RenderFlowVk::s_lights{}; std::vector RenderFlowVk::s_cameras{}; From d88004ccc15386fe3a1ea5e4f1178f5496338f09 Mon Sep 17 00:00:00 2001 From: __prav__ Date: Sun, 4 Jan 2026 18:54:46 -0500 Subject: [PATCH 13/36] wip: dynamic rendering + new Paint pass system --- Engine/include/Api.h | 47 ++++++++++++++----- .../Graphics/PaintPasses/BloomBlurPass.h | 0 .../Graphics/PaintPasses/BloomExtractPass.h | 10 ++++ .../Graphics/PaintPasses/CompositePass.h | 0 .../Graphics/PaintPasses/CustomPaintPass.h | 10 ++++ .../Graphics/PaintPasses/GBufferPass.h | 9 ++++ .../Graphics/PaintPasses/LightingPass.h | 9 ++++ .../Popcorn/Graphics/PaintPasses/PaintPass.h | 17 +++++++ .../Popcorn/Graphics/PaintPasses/PostFXPass.h | 0 .../Popcorn/Graphics/PaintPasses/ShadowPass.h | 9 ++++ .../Graphics/PaintPasses/TransclucencyPass.h | 9 ++++ 11 files changed, 108 insertions(+), 12 deletions(-) create mode 100644 Engine/include/Popcorn/Graphics/PaintPasses/BloomBlurPass.h create mode 100644 Engine/include/Popcorn/Graphics/PaintPasses/BloomExtractPass.h create mode 100644 Engine/include/Popcorn/Graphics/PaintPasses/CompositePass.h create mode 100644 Engine/include/Popcorn/Graphics/PaintPasses/CustomPaintPass.h create mode 100644 Engine/include/Popcorn/Graphics/PaintPasses/GBufferPass.h create mode 100644 Engine/include/Popcorn/Graphics/PaintPasses/LightingPass.h create mode 100644 Engine/include/Popcorn/Graphics/PaintPasses/PaintPass.h create mode 100644 Engine/include/Popcorn/Graphics/PaintPasses/PostFXPass.h create mode 100644 Engine/include/Popcorn/Graphics/PaintPasses/ShadowPass.h create mode 100644 Engine/include/Popcorn/Graphics/PaintPasses/TransclucencyPass.h diff --git a/Engine/include/Api.h b/Engine/include/Api.h index bf825264..6418354f 100644 --- a/Engine/include/Api.h +++ b/Engine/include/Api.h @@ -8,6 +8,33 @@ ENGINE_NAMESPACE_BEGIN GFX_NAMESPACE_BEGIN +// +// Shading stuff ---------------------------------------------------------- +// Shading stuff ---------------------------------------------------------- +// Shading stuff ---------------------------------------------------------- +enum class ShadingModel : uint8_t { + None = 0, + Pbr, // Cook–Torrance BRDF (GGX, Fresnel, NDF) + Basic, // Lambert + Blinn-Phong + + // --- future ----------------------------------------------------------- + ClearCoat, // PBR + second specular lobes + Subsurface, // Light scattering inside + Hair, // Anisotropic strand lighting ? + Unlit // No lighting applied +}; + +enum class MaterialRole : uint8_t { + Opaque, // Deferred, depth write ON, no blending + Masked, // Deferred, alpha test, depth write ON + Translucent, // Forward, blending ON, depth write OFF + Unlit, // Forward, no lighting, optional blending + + // --- future ----------------------------------------------------------- + Decal, // Projects onto existing surfaces + Volumetric // Participating media(fog, smoke etc.) +}; + // // Attachments stuff ------------------------------------------------------ // Attachments stuff ------------------------------------------------------ @@ -46,22 +73,20 @@ template <> struct DrawAttachment { // Scene data ------------------------------------------------------------- // Scene data ------------------------------------------------------------- // Scene data ------------------------------------------------------------- -typedef struct { - BufferDefs::Layout vboLayout; - VertexBuffer *vbo; - IndexBuffer *ibo; -} GeometryData; - -// typedef struct {} +// typedef struct { +// BufferDefs::Layout vboLayout; +// VertexBuffer *vbo; +// IndexBuffer *ibo; +// } GeometryData; typedef struct { uint32_t sceneId; } SceneData; // -// VBO IBO UBO stuff ------------------------------------------------------ -// VBO IBO UBO stuff ------------------------------------------------------ -// VBO IBO UBO stuff ------------------------------------------------------ +// Renderflow info stuff -------------------------------------------------- +// Renderflow info stuff -------------------------------------------------- +// Renderflow info stuff -------------------------------------------------- typedef struct { } DrawData; @@ -69,11 +94,9 @@ typedef struct { // Pipelines stuff -------------------------------------------------------- // Pipelines stuff -------------------------------------------------------- // Pipelines stuff -------------------------------------------------------- - typedef struct { uint16_t col; uint16_t row; - } GfxPipeline; GFX_NAMESPACE_END diff --git a/Engine/include/Popcorn/Graphics/PaintPasses/BloomBlurPass.h b/Engine/include/Popcorn/Graphics/PaintPasses/BloomBlurPass.h new file mode 100644 index 00000000..e69de29b diff --git a/Engine/include/Popcorn/Graphics/PaintPasses/BloomExtractPass.h b/Engine/include/Popcorn/Graphics/PaintPasses/BloomExtractPass.h new file mode 100644 index 00000000..4f0325f7 --- /dev/null +++ b/Engine/include/Popcorn/Graphics/PaintPasses/BloomExtractPass.h @@ -0,0 +1,10 @@ + +#pragma once + +#include "GlobalMacros.h" + +ENGINE_NAMESPACE_BEGIN +GFX_NAMESPACE_BEGIN + +GFX_NAMESPACE_END +ENGINE_NAMESPACE_END diff --git a/Engine/include/Popcorn/Graphics/PaintPasses/CompositePass.h b/Engine/include/Popcorn/Graphics/PaintPasses/CompositePass.h new file mode 100644 index 00000000..e69de29b diff --git a/Engine/include/Popcorn/Graphics/PaintPasses/CustomPaintPass.h b/Engine/include/Popcorn/Graphics/PaintPasses/CustomPaintPass.h new file mode 100644 index 00000000..4f0325f7 --- /dev/null +++ b/Engine/include/Popcorn/Graphics/PaintPasses/CustomPaintPass.h @@ -0,0 +1,10 @@ + +#pragma once + +#include "GlobalMacros.h" + +ENGINE_NAMESPACE_BEGIN +GFX_NAMESPACE_BEGIN + +GFX_NAMESPACE_END +ENGINE_NAMESPACE_END diff --git a/Engine/include/Popcorn/Graphics/PaintPasses/GBufferPass.h b/Engine/include/Popcorn/Graphics/PaintPasses/GBufferPass.h new file mode 100644 index 00000000..b6937895 --- /dev/null +++ b/Engine/include/Popcorn/Graphics/PaintPasses/GBufferPass.h @@ -0,0 +1,9 @@ +#pragma once + +#include "GlobalMacros.h" + +ENGINE_NAMESPACE_BEGIN +GFX_NAMESPACE_BEGIN + +GFX_NAMESPACE_END +ENGINE_NAMESPACE_END diff --git a/Engine/include/Popcorn/Graphics/PaintPasses/LightingPass.h b/Engine/include/Popcorn/Graphics/PaintPasses/LightingPass.h new file mode 100644 index 00000000..b6937895 --- /dev/null +++ b/Engine/include/Popcorn/Graphics/PaintPasses/LightingPass.h @@ -0,0 +1,9 @@ +#pragma once + +#include "GlobalMacros.h" + +ENGINE_NAMESPACE_BEGIN +GFX_NAMESPACE_BEGIN + +GFX_NAMESPACE_END +ENGINE_NAMESPACE_END diff --git a/Engine/include/Popcorn/Graphics/PaintPasses/PaintPass.h b/Engine/include/Popcorn/Graphics/PaintPasses/PaintPass.h new file mode 100644 index 00000000..7d65ae74 --- /dev/null +++ b/Engine/include/Popcorn/Graphics/PaintPasses/PaintPass.h @@ -0,0 +1,17 @@ +#pragma once + +#include "GlobalMacros.h" + +ENGINE_NAMESPACE_BEGIN +GFX_NAMESPACE_BEGIN + +class PaintPass { + PaintPass() = default; + virtual ~PaintPass() {}; + + virtual void SetAttachments() = 0; + virtual void SetMaterialsToPasses() = 0; +}; + +GFX_NAMESPACE_END +ENGINE_NAMESPACE_END diff --git a/Engine/include/Popcorn/Graphics/PaintPasses/PostFXPass.h b/Engine/include/Popcorn/Graphics/PaintPasses/PostFXPass.h new file mode 100644 index 00000000..e69de29b diff --git a/Engine/include/Popcorn/Graphics/PaintPasses/ShadowPass.h b/Engine/include/Popcorn/Graphics/PaintPasses/ShadowPass.h new file mode 100644 index 00000000..b6937895 --- /dev/null +++ b/Engine/include/Popcorn/Graphics/PaintPasses/ShadowPass.h @@ -0,0 +1,9 @@ +#pragma once + +#include "GlobalMacros.h" + +ENGINE_NAMESPACE_BEGIN +GFX_NAMESPACE_BEGIN + +GFX_NAMESPACE_END +ENGINE_NAMESPACE_END diff --git a/Engine/include/Popcorn/Graphics/PaintPasses/TransclucencyPass.h b/Engine/include/Popcorn/Graphics/PaintPasses/TransclucencyPass.h new file mode 100644 index 00000000..b6937895 --- /dev/null +++ b/Engine/include/Popcorn/Graphics/PaintPasses/TransclucencyPass.h @@ -0,0 +1,9 @@ +#pragma once + +#include "GlobalMacros.h" + +ENGINE_NAMESPACE_BEGIN +GFX_NAMESPACE_BEGIN + +GFX_NAMESPACE_END +ENGINE_NAMESPACE_END From e146b169cfc9437cf311367c5991253bd5010689 Mon Sep 17 00:00:00 2001 From: __prav__ Date: Sun, 4 Jan 2026 20:47:48 -0500 Subject: [PATCH 14/36] wip: paint passes - day 12 --- Engine/include/Api.h | 30 -------- .../Popcorn/Graphics/PaintPasses/PaintPass.h | 14 +++- .../Graphics/PaintPasses/PaintPassDefs.h | 69 +++++++++++++++++++ 3 files changed, 82 insertions(+), 31 deletions(-) create mode 100644 Engine/include/Popcorn/Graphics/PaintPasses/PaintPassDefs.h diff --git a/Engine/include/Api.h b/Engine/include/Api.h index 6418354f..959fe47a 100644 --- a/Engine/include/Api.h +++ b/Engine/include/Api.h @@ -2,7 +2,6 @@ #include "BufferObjects.h" #include "GlobalMacros.h" -#include #include ENGINE_NAMESPACE_BEGIN @@ -40,35 +39,6 @@ enum class MaterialRole : uint8_t { // Attachments stuff ------------------------------------------------------ // Attachments stuff ------------------------------------------------------ -enum class DrawKind { Geometry = 0, FullscreenTri }; -enum class DrawTargetKind { ColorImage, DepthImage }; - -enum class ColorFormat { - Low_UNorm8_Linear, - Low_UNorm8_SRGB, - Medium_Float16, - High_Float32, -}; - -enum class DepthFormat { - Low_D16, - Medium_D24, - High_D32, -}; - -template struct DrawAttachment; - -template -struct DrawAttachment { - static constexpr uint16_t countValue = Count; - std::array colorFormats; -}; - -template <> struct DrawAttachment { - static constexpr uint16_t countValue = 1; - std::array depthFormats; -}; - // // Scene data ------------------------------------------------------------- // Scene data ------------------------------------------------------------- diff --git a/Engine/include/Popcorn/Graphics/PaintPasses/PaintPass.h b/Engine/include/Popcorn/Graphics/PaintPasses/PaintPass.h index 7d65ae74..3ca79e5a 100644 --- a/Engine/include/Popcorn/Graphics/PaintPasses/PaintPass.h +++ b/Engine/include/Popcorn/Graphics/PaintPasses/PaintPass.h @@ -1,6 +1,7 @@ #pragma once #include "GlobalMacros.h" +#include "PaintPasses/PaintPassDefs.h" ENGINE_NAMESPACE_BEGIN GFX_NAMESPACE_BEGIN @@ -9,8 +10,19 @@ class PaintPass { PaintPass() = default; virtual ~PaintPass() {}; - virtual void SetAttachments() = 0; + void SetAttachmentInfos( + const DrawAttachmentInfo &colorAttachmentInfo, + const DrawAttachmentInfo + &depthAttachmentInfo) { + m_colorAttachmentInfo = colorAttachmentInfo; + m_depthAttachmentInfo = depthAttachmentInfo; + }; + virtual void SetMaterialsToPasses() = 0; + +protected: + DrawAttachmentInfo m_colorAttachmentInfo{}; + DrawAttachmentInfo m_depthAttachmentInfo{}; }; GFX_NAMESPACE_END diff --git a/Engine/include/Popcorn/Graphics/PaintPasses/PaintPassDefs.h b/Engine/include/Popcorn/Graphics/PaintPasses/PaintPassDefs.h new file mode 100644 index 00000000..803f2006 --- /dev/null +++ b/Engine/include/Popcorn/Graphics/PaintPasses/PaintPassDefs.h @@ -0,0 +1,69 @@ +#pragma once + +#include "GlobalMacros.h" +#include +#include +#include + +ENGINE_NAMESPACE_BEGIN +GFX_NAMESPACE_BEGIN + +// +// Attachments stuff ------------------------------------------------------ +// Attachments stuff ------------------------------------------------------ +// Attachments stuff ------------------------------------------------------ +enum class DrawKind { Geometry = 0, FullscreenTri }; +enum class DrawTargetKind { ColorImage, DepthImage }; + +enum class ColorFormat : uint8_t { + Low_UNorm8_Linear, // 8-bit UNORM, linear color space (LDR, non-gamma) + Low_UNorm8_SRGB, // 8-bit UNORM, sRGB color space (LDR, gamma-correct) + Medium_Float16, // 16-bit float per channel (HDR, good perf/quality balance) + High_Float32, // 32-bit float per channel (HDR, highest precision) +}; + +enum class DepthFormat : uint8_t { + Low_D16, // 16-bit depth (fast, low precision) + Medium_D24, // 24-bit depth (balanced precision) + High_D32, // 32-bit float depth (high precision, large scenes) +}; + +template struct DrawAttachmentInfo; + +template <> struct DrawAttachmentInfo { + std::vector colorFormats{}; +}; + +template <> struct DrawAttachmentInfo { + std::array depthFormats{}; +}; + +// +// Shading stuff ---------------------------------------------------------- +// Shading stuff ---------------------------------------------------------- +// Shading stuff ---------------------------------------------------------- +enum class ShadingModel : uint8_t { + None = 0, + Pbr, // Cook–Torrance BRDF (GGX, Fresnel, NDF) + Basic, // Lambert + Blinn-Phong + + // --- future ----------------------------------------------------------- + ClearCoat, // PBR + second specular lobes + Subsurface, // Light scattering inside + Hair, // Anisotropic strand lighting ? + Unlit // No lighting applied +}; + +enum class MaterialRole : uint8_t { + Opaque, // Deferred, depth write ON, no blending + Masked, // Deferred, alpha test, depth write ON + Translucent, // Forward, blending ON, depth write OFF + Unlit, // Forward, no lighting, optional blending + + // --- future ----------------------------------------------------------- + Decal, // Projects onto existing surfaces + Volumetric // Participating media(fog, smoke etc.) +}; + +GFX_NAMESPACE_END +ENGINE_NAMESPACE_END From d9d9ec34bcb8b5d552b346f1d70a11b29e292811 Mon Sep 17 00:00:00 2001 From: __prav__ Date: Sun, 4 Jan 2026 20:48:13 -0500 Subject: [PATCH 15/36] wip: paint passes day - 12 b --- Engine/include/Api.h | 30 ------------------------------ 1 file changed, 30 deletions(-) diff --git a/Engine/include/Api.h b/Engine/include/Api.h index 959fe47a..69d9b534 100644 --- a/Engine/include/Api.h +++ b/Engine/include/Api.h @@ -7,37 +7,7 @@ ENGINE_NAMESPACE_BEGIN GFX_NAMESPACE_BEGIN -// -// Shading stuff ---------------------------------------------------------- -// Shading stuff ---------------------------------------------------------- -// Shading stuff ---------------------------------------------------------- -enum class ShadingModel : uint8_t { - None = 0, - Pbr, // Cook–Torrance BRDF (GGX, Fresnel, NDF) - Basic, // Lambert + Blinn-Phong - - // --- future ----------------------------------------------------------- - ClearCoat, // PBR + second specular lobes - Subsurface, // Light scattering inside - Hair, // Anisotropic strand lighting ? - Unlit // No lighting applied -}; - -enum class MaterialRole : uint8_t { - Opaque, // Deferred, depth write ON, no blending - Masked, // Deferred, alpha test, depth write ON - Translucent, // Forward, blending ON, depth write OFF - Unlit, // Forward, no lighting, optional blending - // --- future ----------------------------------------------------------- - Decal, // Projects onto existing surfaces - Volumetric // Participating media(fog, smoke etc.) -}; - -// -// Attachments stuff ------------------------------------------------------ -// Attachments stuff ------------------------------------------------------ -// Attachments stuff ------------------------------------------------------ // // Scene data ------------------------------------------------------------- From 86181f0a1147a25e59a03bf0c529b72974cf1e10 Mon Sep 17 00:00:00 2001 From: __prav__ Date: Tue, 6 Jan 2026 21:30:53 -0500 Subject: [PATCH 16/36] wip: paint passes - 1 --- Engine/include/Popcorn.h | 2 +- .../Graphics/PaintPasses/PaintPassDefs.h | 57 ++++++++++++++++++- 2 files changed, 57 insertions(+), 2 deletions(-) diff --git a/Engine/include/Popcorn.h b/Engine/include/Popcorn.h index a04acf29..9edea5d0 100644 --- a/Engine/include/Popcorn.h +++ b/Engine/include/Popcorn.h @@ -40,7 +40,7 @@ static void AddLayer(Layer *layer) { static void RegisterScene(Scene &scene) { s_renderer->AddScene(&scene); }; static void UnregisterScene(Scene &scene) { s_renderer->RemoveScene(&scene); }; -static void MakeRenderFlows() { +static void DefinePaintPasses() { enum class RenderFlowKind { Forward = 0, Deferred }; enum class ImageAttachmentKind { ColorRGBA_HighRes, diff --git a/Engine/include/Popcorn/Graphics/PaintPasses/PaintPassDefs.h b/Engine/include/Popcorn/Graphics/PaintPasses/PaintPassDefs.h index 803f2006..94e4d294 100644 --- a/Engine/include/Popcorn/Graphics/PaintPasses/PaintPassDefs.h +++ b/Engine/include/Popcorn/Graphics/PaintPasses/PaintPassDefs.h @@ -3,6 +3,7 @@ #include "GlobalMacros.h" #include #include +#include #include ENGINE_NAMESPACE_BEGIN @@ -28,14 +29,68 @@ enum class DepthFormat : uint8_t { High_D32, // 32-bit float depth (high precision, large scenes) }; +struct alignas(16) ClearColorValue { + float r = .0f; + float g = .0f; + float b = .0f; + float a = .0f; +}; + +struct alignas(16) ClearDepthStencilValue { + float depth = 1.0f; + float stencil = .0f; +}; + template struct DrawAttachmentInfo; template <> struct DrawAttachmentInfo { std::vector colorFormats{}; + std::vector clearColorValues{}; }; template <> struct DrawAttachmentInfo { - std::array depthFormats{}; + DepthFormat depthFormat; + ClearDepthStencilValue clearDepthStencilValue; +}; + +typedef struct { + uint32_t x; + uint32_t y; +} CoordsXY_U32; + +typedef struct { + int32_t x; + int32_t y; +} CoordsXY_I32; + +typedef struct { + float x; + float y; +} CoordsXY_Float; + +struct PaintArea { + CoordsXY_U32 offset{0, 0}; + CoordsXY_U32 extent{100, 100}; +}; + +enum class PaintPassFlags : uint32_t { + None = 0, + + // Raster behaviour + +}; + +// Only for raster pipelines +struct PaintPassInfo { + // Render info + DrawAttachmentInfo colorImagesInfo; + DrawAttachmentInfo depthImageInfo; + PaintArea paintArea; + + // Pipeline info + + // ShaderSet shaders; + // PassFlags }; // From 3ad399584e97f6fb7a21b423f74c16ee40c4f69c Mon Sep 17 00:00:00 2001 From: __prav__ Date: Thu, 8 Jan 2026 19:11:15 -0500 Subject: [PATCH 17/36] wip: paint passes - design comments --- .../Graphics/PaintPasses/PaintPassDefs.h | 26 +++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/Engine/include/Popcorn/Graphics/PaintPasses/PaintPassDefs.h b/Engine/include/Popcorn/Graphics/PaintPasses/PaintPassDefs.h index 94e4d294..722c2bcc 100644 --- a/Engine/include/Popcorn/Graphics/PaintPasses/PaintPassDefs.h +++ b/Engine/include/Popcorn/Graphics/PaintPasses/PaintPassDefs.h @@ -87,9 +87,31 @@ struct PaintPassInfo { DrawAttachmentInfo depthImageInfo; PaintArea paintArea; - // Pipeline info + // Material info split into two kinds based on DrawKind. -- + + // Surface Materials - First type + // Custom surface materials -- + // User can either + // 1. Provide shaders set + // - Provide custom uniforms and layouts + // 2. Choose from existing shader set (engine provided) like water1, water2 + // etc + // - Modify uniforms only, no custom uniforms + // Prebaked surface materials -- + // User can either + // 1. Choose from existing materials + // - Modify uniforms only, no custom uniforms + // + // FullScreen materials - Second type + // User can either + // 1. Provide shaders set + // - Provide custom uniforms and layouts + // 2. Choose from existing shader set (engine provided) like bloomExtract, + // 3TapBlur etc + // - Modify uniforms only, no custom uniforms + // + // - // ShaderSet shaders; // PassFlags }; From 95868bdf92984de0849ff8399258969fc90acd8e Mon Sep 17 00:00:00 2001 From: __prav__ Date: Thu, 8 Jan 2026 22:05:42 -0500 Subject: [PATCH 18/36] wip: uniform buffer data revamp - paint passes --- .../Graphics/PaintPasses/PaintPassDefs.h | 45 ++++++++++++++----- Engine/include/Popcorn/Graphics/Uniforms.h | 27 +++++++++++ 2 files changed, 60 insertions(+), 12 deletions(-) diff --git a/Engine/include/Popcorn/Graphics/PaintPasses/PaintPassDefs.h b/Engine/include/Popcorn/Graphics/PaintPasses/PaintPassDefs.h index 722c2bcc..1b70bff3 100644 --- a/Engine/include/Popcorn/Graphics/PaintPasses/PaintPassDefs.h +++ b/Engine/include/Popcorn/Graphics/PaintPasses/PaintPassDefs.h @@ -1,6 +1,9 @@ #pragma once #include "GlobalMacros.h" +#include "MaterialTypes.h" +#include "Sources.h" +#include "Uniforms.h" #include #include #include @@ -80,6 +83,17 @@ enum class PaintPassFlags : uint32_t { }; +typedef struct { + const char *vertShaderLoc; + const char *fragShaderLoc; +} ShaderSet; + +struct MaterialInfo { + ShaderSet shaderSet; + + UniformDefs::Uniforms uniform; +}; + // Only for raster pipelines struct PaintPassInfo { // Render info @@ -87,26 +101,33 @@ struct PaintPassInfo { DrawAttachmentInfo depthImageInfo; PaintArea paintArea; + // Material data + MaterialInfo materialInfo; + + // Varying data + // Uniform data + // Material info split into two kinds based on DrawKind. -- - // Surface Materials - First type - // Custom surface materials -- - // User can either - // 1. Provide shaders set + // SURFACE MATERIALS - FIRST TYPE + // 1. Custom surface materials -- + // User can either + // a. Provide shaders set // - Provide custom uniforms and layouts - // 2. Choose from existing shader set (engine provided) like water1, water2 + // b. Choose from existing shader set (engine provided) like water1, water2 // etc // - Modify uniforms only, no custom uniforms - // Prebaked surface materials -- - // User can either - // 1. Choose from existing materials + // + // 2. Prebaked surface materials -- + // User can either + // a. Choose from existing materials // - Modify uniforms only, no custom uniforms // - // FullScreen materials - Second type - // User can either - // 1. Provide shaders set + // FULLSCREEN MATERIALS - SECOND TYPE + // 1. Custom fullscreen materials + // a. Provide shaders set // - Provide custom uniforms and layouts - // 2. Choose from existing shader set (engine provided) like bloomExtract, + // b. Choose from existing shader set (engine provided) like bloomExtract, // 3TapBlur etc // - Modify uniforms only, no custom uniforms // diff --git a/Engine/include/Popcorn/Graphics/Uniforms.h b/Engine/include/Popcorn/Graphics/Uniforms.h index c86a0f9a..66edd155 100644 --- a/Engine/include/Popcorn/Graphics/Uniforms.h +++ b/Engine/include/Popcorn/Graphics/Uniforms.h @@ -1,6 +1,8 @@ #pragma once #include "GlobalMacros.h" +#include "Popcorn/Core/Assert.h" +#include #include #include #include @@ -19,6 +21,31 @@ enum class Uniforms { // add more.. }; +// clang-format off +enum class UniformAttrs { + None = 0, + Float, + Vec2, Vec3, Vec4, + Mat3, Mat4, + Bool +}; + +static constexpr size_t GetUniformAttrSize(UniformAttrs attr) { + switch (attr) + { + case UniformAttrs::Float: return 4; + case UniformAttrs::Vec2: return sizeof(glm::vec2); + case UniformAttrs::Vec3: return sizeof(glm::vec3); + case UniformAttrs::Vec4: return sizeof(glm::vec4); + case UniformAttrs::Mat3: return sizeof(glm::mat3); + case UniformAttrs::Mat4: return sizeof(glm::mat4); + default: + PC_ASSERT(false, "Unknown AttrType"); + return 0; + } +}; +// clang-format on + template struct Uniform { static constexpr Uniforms layout = L; // Internally aligned size From aa3b028ab4480363a70911924116e67b131a3657 Mon Sep 17 00:00:00 2001 From: __prav__ Date: Fri, 9 Jan 2026 21:13:17 -0500 Subject: [PATCH 19/36] feat: paint pass, render graph impl --- .../Graphics/PaintPasses/PaintPassDefs.h | 31 ++++++++++++++----- 1 file changed, 23 insertions(+), 8 deletions(-) diff --git a/Engine/include/Popcorn/Graphics/PaintPasses/PaintPassDefs.h b/Engine/include/Popcorn/Graphics/PaintPasses/PaintPassDefs.h index 1b70bff3..800ed849 100644 --- a/Engine/include/Popcorn/Graphics/PaintPasses/PaintPassDefs.h +++ b/Engine/include/Popcorn/Graphics/PaintPasses/PaintPassDefs.h @@ -16,7 +16,7 @@ GFX_NAMESPACE_BEGIN // Attachments stuff ------------------------------------------------------ // Attachments stuff ------------------------------------------------------ // Attachments stuff ------------------------------------------------------ -enum class DrawKind { Geometry = 0, FullscreenTri }; +enum class DrawKind { MaterialGeometry = 0, FullscreenTri }; enum class DrawTargetKind { ColorImage, DepthImage }; enum class ColorFormat : uint8_t { @@ -78,9 +78,7 @@ struct PaintArea { enum class PaintPassFlags : uint32_t { None = 0, - // Raster behaviour - }; typedef struct { @@ -88,10 +86,23 @@ typedef struct { const char *fragShaderLoc; } ShaderSet; -struct MaterialInfo { - ShaderSet shaderSet; +struct MaterialsSubmeshBuckets { + // Submesh data sorted material so the paintPipelineInfo can select buckets + // for material specific draw (internally extract vbo ibo) +}; + +typedef struct { + // contains submesh bucket references +} MatSubmeshBucket; - UniformDefs::Uniforms uniform; +struct PaintPipelineInfo { + // For materials: + // -- Extract info from the Gltf file and pass + // + // Uniforms *uniforms; + ShaderSet shaderSet; + MatSubmeshBucket matSubmeshBucket; // gets vbo, ibo info + // SSBO miscData; }; // Only for raster pipelines @@ -101,8 +112,12 @@ struct PaintPassInfo { DrawAttachmentInfo depthImageInfo; PaintArea paintArea; - // Material data - MaterialInfo materialInfo; + // TODO: Think about Buffer data as well (SSBOs) + + // Draw kind + const DrawKind drawKind; + + const PaintPipelineInfo *paintPipelineInfos; // Varying data // Uniform data From 2642f71e705e447fab62db0e8ff79f247fbd4d25 Mon Sep 17 00:00:00 2001 From: __prav__ Date: Sat, 10 Jan 2026 22:27:40 -0500 Subject: [PATCH 20/36] feat: paint passes + uniform buffers --- Engine/include/Popcorn.h | 36 +++---------- .../Graphics/PaintPasses/PaintPassDefs.h | 50 ++++--------------- Engine/include/Popcorn/Graphics/Uniforms.h | 24 +++++++++ 3 files changed, 43 insertions(+), 67 deletions(-) diff --git a/Engine/include/Popcorn.h b/Engine/include/Popcorn.h index 9edea5d0..bc0e8f2a 100644 --- a/Engine/include/Popcorn.h +++ b/Engine/include/Popcorn.h @@ -41,24 +41,6 @@ static void RegisterScene(Scene &scene) { s_renderer->AddScene(&scene); }; static void UnregisterScene(Scene &scene) { s_renderer->RemoveScene(&scene); }; static void DefinePaintPasses() { - enum class RenderFlowKind { Forward = 0, Deferred }; - enum class ImageAttachmentKind { - ColorRGBA_HighRes, - ColorRGBA_LowRes, - Depth_Auto, - }; - - typedef struct { - ImageAttachmentKind kind; - - } RFlowResource; - - typedef struct { - const char *name; - RenderFlowKind renderFlowkind; - std::vector imageAttachmentKind; - // std::vector<>() - } RenderFlowCreateInfo; // s_renderer->DefineRenderFlow( // { @@ -70,16 +52,14 @@ static void StartGame() { // TODO: Move the ownership of commandbuffers to Renderflow base class // // NEW: --- Make your own renderflows --- - s_renderer->CreateRenderFlows(); // 1. Each renderflow takes in - // a. Attachments (and Info) - // b. RenderInfo - // c. PipelineInfo - // - s_renderer->PrepareRenderFlows( - // Images / Buffers - ); // Creates attachments, renderflows, - // framebuffers, and command buffers - // + s_renderer->CreateRenderFlows(); // 1. Each renderflow takes in + // a. Attachments (and Info) + // b. RenderInfo + // c. PipelineInfo + // + s_renderer->PrepareRenderFlows(); // Creates attachments, renderflows, + // framebuffers, and command buffers + // s_renderer->AssignSceneObjectsToRenderFlows(); // Sorts submeshes material // wise & adds to renderflows // 1. Calculates offsets + diff --git a/Engine/include/Popcorn/Graphics/PaintPasses/PaintPassDefs.h b/Engine/include/Popcorn/Graphics/PaintPasses/PaintPassDefs.h index 800ed849..adb989de 100644 --- a/Engine/include/Popcorn/Graphics/PaintPasses/PaintPassDefs.h +++ b/Engine/include/Popcorn/Graphics/PaintPasses/PaintPassDefs.h @@ -93,16 +93,20 @@ struct MaterialsSubmeshBuckets { typedef struct { // contains submesh bucket references -} MatSubmeshBucket; +} SubmeshBucket; + +typedef struct { +} SamplerInfo; struct PaintPipelineInfo { // For materials: - // -- Extract info from the Gltf file and pass + // -- Extract info from the Gltf file (Submesh class) // - // Uniforms *uniforms; + // Uniform *uniforms; // includes data? For copy ops + // UniformArray *uniforms; ShaderSet shaderSet; - MatSubmeshBucket matSubmeshBucket; // gets vbo, ibo info - // SSBO miscData; + SubmeshBucket *submeshBucket; // gets vbo, ibo info + SamplerInfo samplerInfo; }; // Only for raster pipelines @@ -110,45 +114,13 @@ struct PaintPassInfo { // Render info DrawAttachmentInfo colorImagesInfo; DrawAttachmentInfo depthImageInfo; - PaintArea paintArea; - // TODO: Think about Buffer data as well (SSBOs) + PaintArea paintArea; // Draw kind - const DrawKind drawKind; + DrawKind drawKind; const PaintPipelineInfo *paintPipelineInfos; - - // Varying data - // Uniform data - - // Material info split into two kinds based on DrawKind. -- - - // SURFACE MATERIALS - FIRST TYPE - // 1. Custom surface materials -- - // User can either - // a. Provide shaders set - // - Provide custom uniforms and layouts - // b. Choose from existing shader set (engine provided) like water1, water2 - // etc - // - Modify uniforms only, no custom uniforms - // - // 2. Prebaked surface materials -- - // User can either - // a. Choose from existing materials - // - Modify uniforms only, no custom uniforms - // - // FULLSCREEN MATERIALS - SECOND TYPE - // 1. Custom fullscreen materials - // a. Provide shaders set - // - Provide custom uniforms and layouts - // b. Choose from existing shader set (engine provided) like bloomExtract, - // 3TapBlur etc - // - Modify uniforms only, no custom uniforms - // - // - - // PassFlags }; // diff --git a/Engine/include/Popcorn/Graphics/Uniforms.h b/Engine/include/Popcorn/Graphics/Uniforms.h index 66edd155..a2ccec47 100644 --- a/Engine/include/Popcorn/Graphics/Uniforms.h +++ b/Engine/include/Popcorn/Graphics/Uniforms.h @@ -2,6 +2,7 @@ #include "GlobalMacros.h" #include "Popcorn/Core/Assert.h" +#include #include #include #include @@ -46,6 +47,29 @@ static constexpr size_t GetUniformAttrSize(UniformAttrs attr) { }; // clang-format on +template struct UniformData { + static constexpr uint32_t Count = sizeof...(Attrs); + + inline static constexpr std::array Sizes = [] { + std::array s; + uint32_t i = 0; + ((s[i++] = GetUniformAttrSize(Attrs)), ...); + return s; + }(); + + inline static constexpr std::array Offsets = [] { + std::array offsets; + uint32_t i = 0; + ((offsets[i++] += GetUniformAttrSize(Attrs)), ...); + return offsets; + }(); + + inline static constexpr size_t TotalSize = (GetUniformAttrSize(Attrs) + ...); + +private: + alignas(16) std::byte data[TotalSize]; +}; + template struct Uniform { static constexpr Uniforms layout = L; // Internally aligned size From 4d30e2dd983b18893328e5ffd4e62f7ce9b4ed54 Mon Sep 17 00:00:00 2001 From: __prav__ Date: Sun, 11 Jan 2026 18:28:43 -0500 Subject: [PATCH 21/36] wip: uniforms + paint passes - day 2 --- Engine/include/Popcorn/Graphics/Uniforms.h | 43 +++++++++++++++++++--- 1 file changed, 38 insertions(+), 5 deletions(-) diff --git a/Engine/include/Popcorn/Graphics/Uniforms.h b/Engine/include/Popcorn/Graphics/Uniforms.h index a2ccec47..de7093f2 100644 --- a/Engine/include/Popcorn/Graphics/Uniforms.h +++ b/Engine/include/Popcorn/Graphics/Uniforms.h @@ -45,27 +45,60 @@ static constexpr size_t GetUniformAttrSize(UniformAttrs attr) { return 0; } }; + +template struct UniformAttrType; +template <> +struct UniformAttrType { using type = float; }; +template <> +struct UniformAttrType { using type = glm::vec2; }; +template <> +struct UniformAttrType { using type = glm::vec3; }; +template <> +struct UniformAttrType { using type = glm::vec4; }; +template <> +struct UniformAttrType { using type = glm::mat3; }; +template <> +struct UniformAttrType { using type = glm::mat4; }; // clang-format on -template struct UniformData { +template class UniformData { +public: + // --- Helpers --- static constexpr uint32_t Count = sizeof...(Attrs); - inline static constexpr std::array Sizes = [] { - std::array s; + inline static constexpr std::array Types = [] { + std::array s; uint32_t i = 0; - ((s[i++] = GetUniformAttrSize(Attrs)), ...); + ((s[i++] = Attrs), ...); return s; }(); inline static constexpr std::array Offsets = [] { std::array offsets; uint32_t i = 0; - ((offsets[i++] += GetUniformAttrSize(Attrs)), ...); + size_t offset = 0; + ((offsets[i++] = offset, offset += GetUniformAttrSize(Attrs)), ...); return offsets; }(); inline static constexpr size_t TotalSize = (GetUniformAttrSize(Attrs) + ...); + // + // --- Methods --- + template + typename UniformAttrType::type *GetAttr() { + static_assert(Index < Count, "Uniform attribute index out of bounds"); + using ExtractedGlmType = UniformAttrType::type; + return reinterpret_cast(data + Offsets[Index]); + }; + + template + const typename UniformAttrType::type *GetAttr() const { + static_assert(Index < Count, "Uniform attribute index out of bounds"); + using ExtractedGlmType = UniformAttrType::type; + return reinterpret_cast(data + Offsets[Index]); + }; + private: alignas(16) std::byte data[TotalSize]; }; From ed7ebb7e80c5e033d353927569165d28a9103c87 Mon Sep 17 00:00:00 2001 From: __prav__ Date: Sun, 11 Jan 2026 21:08:00 -0500 Subject: [PATCH 22/36] wip: uniform data runtime class --- .../Graphics/PaintPasses/PaintPassDefs.h | 4 +++ Engine/include/Popcorn/Graphics/Uniforms.h | 33 ++++++++++++++++--- 2 files changed, 33 insertions(+), 4 deletions(-) diff --git a/Engine/include/Popcorn/Graphics/PaintPasses/PaintPassDefs.h b/Engine/include/Popcorn/Graphics/PaintPasses/PaintPassDefs.h index adb989de..91c840d7 100644 --- a/Engine/include/Popcorn/Graphics/PaintPasses/PaintPassDefs.h +++ b/Engine/include/Popcorn/Graphics/PaintPasses/PaintPassDefs.h @@ -104,6 +104,10 @@ struct PaintPipelineInfo { // // Uniform *uniforms; // includes data? For copy ops // UniformArray *uniforms; + + // TODO: In Uniforms header file -- make helper + // std::vector uniformSets; + ShaderSet shaderSet; SubmeshBucket *submeshBucket; // gets vbo, ibo info SamplerInfo samplerInfo; diff --git a/Engine/include/Popcorn/Graphics/Uniforms.h b/Engine/include/Popcorn/Graphics/Uniforms.h index de7093f2..268d5765 100644 --- a/Engine/include/Popcorn/Graphics/Uniforms.h +++ b/Engine/include/Popcorn/Graphics/Uniforms.h @@ -61,6 +61,7 @@ template <> struct UniformAttrType { using type = glm::mat4; }; // clang-format on +// TODO: MAKE EVERYTHING RUNTIME FUCKKKKKK template class UniformData { public: // --- Helpers --- @@ -73,6 +74,11 @@ template class UniformData { return s; }(); + // TODO: ALIGNMENT FOR VULKAN!!! + // TODO: ALIGNMENT FOR VULKAN!!! + // TODO: ALIGNMENT FOR VULKAN!!! + // TODO: ALIGNMENT FOR VULKAN!!! + // TODO: ALIGNMENT FOR VULKAN!!! inline static constexpr std::array Offsets = [] { std::array offsets; uint32_t i = 0; @@ -86,23 +92,42 @@ template class UniformData { // // --- Methods --- template - typename UniformAttrType::type *GetAttr() { + typename UniformAttrType::type &GetAttr() { static_assert(Index < Count, "Uniform attribute index out of bounds"); using ExtractedGlmType = UniformAttrType::type; - return reinterpret_cast(data + Offsets[Index]); + return reinterpret_cast(data + Offsets[Index]); }; template - const typename UniformAttrType::type *GetAttr() const { + const typename UniformAttrType::type &GetAttr() const { static_assert(Index < Count, "Uniform attribute index out of bounds"); using ExtractedGlmType = UniformAttrType::type; - return reinterpret_cast(data + Offsets[Index]); + return reinterpret_cast(data + Offsets[Index]); }; private: alignas(16) std::byte data[TotalSize]; }; +struct UniformSetView { + const void *data; // pointer to raw bytes + uint32_t size; // total size + const uint32_t *offsets; // optional (debug / validation) + uint32_t count; // number of attributes + uint32_t setIndex; // Vulkan descriptor set index +}; + +// TODO: Convert this to set +template +inline static constexpr UniformSetView +PcMakeUniformSetView(UniformData &u, uint32_t setIndex) { + return {.data = u.RawData(), // pointer to bytes + .size = UniformData::TotalSize, + .offsets = UniformData::Offsets.data(), + .count = UniformData::Count, + .setIndex = setIndex}; +} + template struct Uniform { static constexpr Uniforms layout = L; // Internally aligned size From 1adaa935073a54b3cd4d48c936fef0a55526fcba Mon Sep 17 00:00:00 2001 From: __prav__ Date: Sun, 11 Jan 2026 21:42:09 -0500 Subject: [PATCH 23/36] wip: uniform sets added --- .../Popcorn/Graphics/PaintPasses/PaintPassDefs.h | 6 +++--- Engine/include/Popcorn/Graphics/Uniforms.h | 14 +++++++++++++- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/Engine/include/Popcorn/Graphics/PaintPasses/PaintPassDefs.h b/Engine/include/Popcorn/Graphics/PaintPasses/PaintPassDefs.h index 91c840d7..a42881e6 100644 --- a/Engine/include/Popcorn/Graphics/PaintPasses/PaintPassDefs.h +++ b/Engine/include/Popcorn/Graphics/PaintPasses/PaintPassDefs.h @@ -102,11 +102,11 @@ struct PaintPipelineInfo { // For materials: // -- Extract info from the Gltf file (Submesh class) // - // Uniform *uniforms; // includes data? For copy ops - // UniformArray *uniforms; // TODO: In Uniforms header file -- make helper - // std::vector uniformSets; + std::vector uniformSets; + + // Make one for SSBOs too ShaderSet shaderSet; SubmeshBucket *submeshBucket; // gets vbo, ibo info diff --git a/Engine/include/Popcorn/Graphics/Uniforms.h b/Engine/include/Popcorn/Graphics/Uniforms.h index 268d5765..0b61d3a7 100644 --- a/Engine/include/Popcorn/Graphics/Uniforms.h +++ b/Engine/include/Popcorn/Graphics/Uniforms.h @@ -7,6 +7,7 @@ #include #include #include +#include ENGINE_NAMESPACE_BEGIN GFX_NAMESPACE_BEGIN @@ -61,7 +62,12 @@ template <> struct UniformAttrType { using type = glm::mat4; }; // clang-format on -// TODO: MAKE EVERYTHING RUNTIME FUCKKKKKK +struct UniformSet { + std::vector layout; + std::vector offsets; + std::vector data; +}; + template class UniformData { public: // --- Helpers --- @@ -74,6 +80,12 @@ template class UniformData { return s; }(); + UniformSet MakeSet() const { + return {.layout = std::vector(Types.begin(), Types.end()), + .offsets = std::vector(Offsets.begin(), Offsets.end()), + .data = std::vector(data, data + TotalSize)}; + } + // TODO: ALIGNMENT FOR VULKAN!!! // TODO: ALIGNMENT FOR VULKAN!!! // TODO: ALIGNMENT FOR VULKAN!!! From 614a41c16dfede886cb19cd8f99d6f5afda66fa1 Mon Sep 17 00:00:00 2001 From: __prav__ Date: Mon, 12 Jan 2026 20:15:38 -0500 Subject: [PATCH 24/36] wip: paintpasses - continue --- .../Popcorn/Graphics/PaintPasses/PaintPassDefs.h | 1 - Engine/include/Popcorn/Graphics/Uniforms.h | 12 ++++++------ .../Popcorn/Platform/Vulkan/Memory/HelpersVk.h | 3 +-- .../Platform/Vulkan/RenderFlows/RenderFlowVk.cpp | 6 ++++-- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/Engine/include/Popcorn/Graphics/PaintPasses/PaintPassDefs.h b/Engine/include/Popcorn/Graphics/PaintPasses/PaintPassDefs.h index a42881e6..50819cda 100644 --- a/Engine/include/Popcorn/Graphics/PaintPasses/PaintPassDefs.h +++ b/Engine/include/Popcorn/Graphics/PaintPasses/PaintPassDefs.h @@ -103,7 +103,6 @@ struct PaintPipelineInfo { // -- Extract info from the Gltf file (Submesh class) // - // TODO: In Uniforms header file -- make helper std::vector uniformSets; // Make one for SSBOs too diff --git a/Engine/include/Popcorn/Graphics/Uniforms.h b/Engine/include/Popcorn/Graphics/Uniforms.h index 0b61d3a7..2733a1f2 100644 --- a/Engine/include/Popcorn/Graphics/Uniforms.h +++ b/Engine/include/Popcorn/Graphics/Uniforms.h @@ -73,7 +73,7 @@ template class UniformData { // --- Helpers --- static constexpr uint32_t Count = sizeof...(Attrs); - inline static constexpr std::array Types = [] { + inline static constexpr std::array Layout = [] { std::array s; uint32_t i = 0; ((s[i++] = Attrs), ...); @@ -81,7 +81,7 @@ template class UniformData { }(); UniformSet MakeSet() const { - return {.layout = std::vector(Types.begin(), Types.end()), + return {.layout = std::vector(Layout.begin(), Layout.end()), .offsets = std::vector(Offsets.begin(), Offsets.end()), .data = std::vector(data, data + TotalSize)}; } @@ -104,16 +104,16 @@ template class UniformData { // // --- Methods --- template - typename UniformAttrType::type &GetAttr() { + typename UniformAttrType::type &GetAttr() { static_assert(Index < Count, "Uniform attribute index out of bounds"); - using ExtractedGlmType = UniformAttrType::type; + using ExtractedGlmType = UniformAttrType::type; return reinterpret_cast(data + Offsets[Index]); }; template - const typename UniformAttrType::type &GetAttr() const { + const typename UniformAttrType::type &GetAttr() const { static_assert(Index < Count, "Uniform attribute index out of bounds"); - using ExtractedGlmType = UniformAttrType::type; + using ExtractedGlmType = UniformAttrType::type; return reinterpret_cast(data + Offsets[Index]); }; diff --git a/Engine/include/Popcorn/Platform/Vulkan/Memory/HelpersVk.h b/Engine/include/Popcorn/Platform/Vulkan/Memory/HelpersVk.h index fa4f41f8..0442575b 100644 --- a/Engine/include/Popcorn/Platform/Vulkan/Memory/HelpersVk.h +++ b/Engine/include/Popcorn/Platform/Vulkan/Memory/HelpersVk.h @@ -105,8 +105,7 @@ template <> struct PcCopyUniformToMemory { : bufferViews(bfrViews), bufferOffsets(bfrOffsets) { const LightData &lightData = light->GetLightData(); - // TODO: Fix this -- this is not actually world position - const glm::vec3 &worldPos = light->GetPosition(); + const glm::vec3 &worldPos = light->GetWorldPosition(); // PC_WARN("LIGHT POSITION BEFORE COPY " << worldPos.x << ", " << worldPos.y // << ", " << worldPos.z) diff --git a/Engine/src/Popcorn/Platform/Vulkan/RenderFlows/RenderFlowVk.cpp b/Engine/src/Popcorn/Platform/Vulkan/RenderFlows/RenderFlowVk.cpp index b5e3fb73..405f6f05 100644 --- a/Engine/src/Popcorn/Platform/Vulkan/RenderFlows/RenderFlowVk.cpp +++ b/Engine/src/Popcorn/Platform/Vulkan/RenderFlows/RenderFlowVk.cpp @@ -202,8 +202,10 @@ void RenderFlowVk::AllocMemory() { void RenderFlowVk::CopyDynamicUniformsToMemory(const uint32_t currentFrame) { auto *memory = ContextVk::Memory(); - memory->FillUbosSubmesh(s_basicMatSubmeshBuckets, currentFrame); - memory->FillUbosSubmesh(s_pbrMatSubmeshBuckets, currentFrame); + memory->FillUbosSubmesh(s_basicMatDrawOrder, s_basicMatSubmeshBuckets, + currentFrame); + memory->FillUbosSubmesh(s_pbrMatDrawOrder, s_pbrMatSubmeshBuckets, + currentFrame); memory->FillUbosSsbosLightCameraEmpty(s_lights, s_cameras, s_emptys, currentFrame); From eca35c99f096aeb09552a1f83293138ebc2884e2 Mon Sep 17 00:00:00 2001 From: __prav__ Date: Thu, 15 Jan 2026 21:42:46 -0500 Subject: [PATCH 25/36] wip: dynamic render flows --- .../Graphics/PaintPasses/PaintPassDefs.h | 25 +++++++++++-------- Engine/include/Popcorn/Graphics/Uniforms.h | 5 +++- 2 files changed, 19 insertions(+), 11 deletions(-) diff --git a/Engine/include/Popcorn/Graphics/PaintPasses/PaintPassDefs.h b/Engine/include/Popcorn/Graphics/PaintPasses/PaintPassDefs.h index 50819cda..18e7bce0 100644 --- a/Engine/include/Popcorn/Graphics/PaintPasses/PaintPassDefs.h +++ b/Engine/include/Popcorn/Graphics/PaintPasses/PaintPassDefs.h @@ -2,9 +2,8 @@ #include "GlobalMacros.h" #include "MaterialTypes.h" -#include "Sources.h" +#include "Mesh.h" #include "Uniforms.h" -#include #include #include #include @@ -86,15 +85,24 @@ typedef struct { const char *fragShaderLoc; } ShaderSet; -struct MaterialsSubmeshBuckets { +struct UniformLayout {}; + +typedef struct { + std::vector uniformLayout; + // TODO: Refactor material to be runtime. Not static + std::vector *> submeshes; +} MaterialInfo; + +struct DataBuffers { + std::vector uniformSets; // contains actual data + std::vector materialInfos; + // MaterialTypes materials[]; + // + // // Submesh data sorted material so the paintPipelineInfo can select buckets // for material specific draw (internally extract vbo ibo) }; -typedef struct { - // contains submesh bucket references -} SubmeshBucket; - typedef struct { } SamplerInfo; @@ -103,12 +111,9 @@ struct PaintPipelineInfo { // -- Extract info from the Gltf file (Submesh class) // - std::vector uniformSets; - // Make one for SSBOs too ShaderSet shaderSet; - SubmeshBucket *submeshBucket; // gets vbo, ibo info SamplerInfo samplerInfo; }; diff --git a/Engine/include/Popcorn/Graphics/Uniforms.h b/Engine/include/Popcorn/Graphics/Uniforms.h index 2733a1f2..bcb87f5e 100644 --- a/Engine/include/Popcorn/Graphics/Uniforms.h +++ b/Engine/include/Popcorn/Graphics/Uniforms.h @@ -70,6 +70,9 @@ struct UniformSet { template class UniformData { public: + std::byte *RawData() { return data; }; + const std::byte *RawData() const { return data; }; + // --- Helpers --- static constexpr uint32_t Count = sizeof...(Attrs); @@ -133,7 +136,7 @@ struct UniformSetView { template inline static constexpr UniformSetView PcMakeUniformSetView(UniformData &u, uint32_t setIndex) { - return {.data = u.RawData(), // pointer to bytes + return {.data = u.RawData(), .size = UniformData::TotalSize, .offsets = UniformData::Offsets.data(), .count = UniformData::Count, From 7f0d62e90329f6bffeb027c0a923ad7da7daeca9 Mon Sep 17 00:00:00 2001 From: __prav__ Date: Fri, 16 Jan 2026 21:03:41 -0500 Subject: [PATCH 26/36] wip: paint passes and stuff --- .../Graphics/PaintPasses/PaintPassDefs.h | 67 ++++++++++++++----- Engine/include/Popcorn/Graphics/Uniforms.h | 2 + Engine/shaders/vulkan/lighting.frag | 2 + 3 files changed, 56 insertions(+), 15 deletions(-) diff --git a/Engine/include/Popcorn/Graphics/PaintPasses/PaintPassDefs.h b/Engine/include/Popcorn/Graphics/PaintPasses/PaintPassDefs.h index 18e7bce0..9977d1c2 100644 --- a/Engine/include/Popcorn/Graphics/PaintPasses/PaintPassDefs.h +++ b/Engine/include/Popcorn/Graphics/PaintPasses/PaintPassDefs.h @@ -1,5 +1,6 @@ #pragma once +#include "BufferObjects.h" #include "GlobalMacros.h" #include "MaterialTypes.h" #include "Mesh.h" @@ -85,19 +86,31 @@ typedef struct { const char *fragShaderLoc; } ShaderSet; -struct UniformLayout {}; +typedef struct { + size_t offset; // buffer view offset (in bytes) + size_t range; // buffer view range (in bytes) + std::byte *accessPtr; // or some shit like that +} BufferView; + +// User copies material info here (Gltf loader does this for the user) +struct MaterialInfo { + const char *name; + uint32_t materialId; + ShaderSet shaderSet; + std::vector uniformLayout; + BufferView bufferView; // view into UBO memory (Vulkan staging buffer?) + // TODO: Link to submesh memory +}; typedef struct { std::vector uniformLayout; - // TODO: Refactor material to be runtime. Not static - std::vector *> submeshes; -} MaterialInfo; + BufferView bufferView; // view into UBO memory (Vulkan staging buffer?) +} ScreenspaceInfo; +// Engine will "bind" these buffers later (every frame); you are just setting +// the memory layouts struct DataBuffers { - std::vector uniformSets; // contains actual data - std::vector materialInfos; - // MaterialTypes materials[]; - // + // // Submesh data sorted material so the paintPipelineInfo can select buckets // for material specific draw (internally extract vbo ibo) @@ -106,23 +119,47 @@ struct DataBuffers { typedef struct { } SamplerInfo; -struct PaintPipelineInfo { - // For materials: - // -- Extract info from the Gltf file (Submesh class) - // +// Collect all submeshes of a certain "type" (maybe like +typedef struct { + std::vector uniformSets; // contains actual data - // Make one for SSBOs too +} SubmeshBucket; - ShaderSet shaderSet; +struct PaintPipelineInfo { + // Make one for SSBOs too SamplerInfo samplerInfo; + + // Material info - For Material DrawKind + MaterialInfo materialInfo; // Material UBO (Layout + BufferView) + SubmeshBucket submeshBucket; // Submesh VBO, IBO, UBO (Layout + BufferViews) + + // Screenspace info - For FullscreenTri DrawKind + ScreenspaceInfo screenspaceInfo; // Screenspace UBO (Layout + BufferView) }; +/** + * Basic Vert - SET 0 (0 - Camera UBO) + * - SET 2 (0 - Submesh UBO) + * Basic Frag - SET 1 (0 - Basic UBO) + * + * Pbr Vert - SET 0 (0 - Camera UBO) + * - SET 2 (0 - Submesh UBO) + * Pbr Frag - SET 1 (0 - Pbr UBO) + * + * Lighting Frag - SET 0 (0 - Camera UBO) + * - SET 1 (0 - Light SSBO) + * (1 - Sampler Tex) + * (2 - Sampler Tex) + * (3 - Sampler Tex) + * (4 - Sampler Tex) + * + */ + // Only for raster pipelines struct PaintPassInfo { // Render info DrawAttachmentInfo colorImagesInfo; DrawAttachmentInfo depthImageInfo; - PaintArea paintArea; // Draw kind diff --git a/Engine/include/Popcorn/Graphics/Uniforms.h b/Engine/include/Popcorn/Graphics/Uniforms.h index bcb87f5e..246b503d 100644 --- a/Engine/include/Popcorn/Graphics/Uniforms.h +++ b/Engine/include/Popcorn/Graphics/Uniforms.h @@ -86,6 +86,8 @@ template class UniformData { UniformSet MakeSet() const { return {.layout = std::vector(Layout.begin(), Layout.end()), .offsets = std::vector(Offsets.begin(), Offsets.end()), + // TODO: Change data to a "BufferView" that views into a large UBOs + // byte array .data = std::vector(data, data + TotalSize)}; } diff --git a/Engine/shaders/vulkan/lighting.frag b/Engine/shaders/vulkan/lighting.frag index 3b257851..c05f4da6 100644 --- a/Engine/shaders/vulkan/lighting.frag +++ b/Engine/shaders/vulkan/lighting.frag @@ -13,6 +13,7 @@ struct LightUniform { float outerConeAngle; }; +// SET 0 layout(set = 0, binding = 0) uniform CameraUBO { mat4 view; mat4 proj; @@ -21,6 +22,7 @@ layout(set = 0, binding = 0) uniform CameraUBO { vec3 camPos; } camera; +// SET 1 layout(set = 1, binding = 0) readonly buffer LightBuffer { LightUniform lights[]; }; From 2702f9d839f118d10b53b81fad3627138dd96a8b Mon Sep 17 00:00:00 2001 From: __prav__ Date: Mon, 19 Jan 2026 20:17:04 -0500 Subject: [PATCH 27/36] wip: new paintpass architecture - 1/7 --- .../Graphics/PaintPasses/GBufferPass.h | 27 +++++++++++++++ .../Popcorn/Graphics/PaintPasses/PaintPass.h | 8 +++-- .../{PostFXPass.h => PaintPassBuilder.h} | 0 .../Graphics/PaintPasses/PaintPassDefs.h | 28 +++++++++------- .../PaintPasses/PaintPassMemorySource.h | 33 +++++++++++++++++++ .../Popcorn/Graphics/PaintPasses/PostFxPass.h | 0 .../myPaintPass_01.h} | 0 .../myPaintPass_02.h} | 0 .../paintpasses/paintPassBuilder.h | 31 +++++++++++++++++ .../renderflows/transclucencyRflow.h | 0 10 files changed, 114 insertions(+), 13 deletions(-) rename Engine/include/Popcorn/Graphics/PaintPasses/{PostFXPass.h => PaintPassBuilder.h} (100%) create mode 100644 Engine/include/Popcorn/Graphics/PaintPasses/PaintPassMemorySource.h rename Sandbox/02-Street-Scene/renderflows/gbufferRflow.h => Engine/include/Popcorn/Graphics/PaintPasses/PostFxPass.h (100%) rename Sandbox/02-Street-Scene/{renderflows/lightingRflow.h => paintpasses/myPaintPass_01.h} (100%) rename Sandbox/02-Street-Scene/{renderflows/shadowsRflow.h => paintpasses/myPaintPass_02.h} (100%) create mode 100644 Sandbox/02-Street-Scene/paintpasses/paintPassBuilder.h delete mode 100644 Sandbox/02-Street-Scene/renderflows/transclucencyRflow.h diff --git a/Engine/include/Popcorn/Graphics/PaintPasses/GBufferPass.h b/Engine/include/Popcorn/Graphics/PaintPasses/GBufferPass.h index b6937895..4fabe788 100644 --- a/Engine/include/Popcorn/Graphics/PaintPasses/GBufferPass.h +++ b/Engine/include/Popcorn/Graphics/PaintPasses/GBufferPass.h @@ -1,9 +1,36 @@ #pragma once #include "GlobalMacros.h" +#include "PaintPasses/PaintPass.h" +#include "PaintPasses/PaintPassDefs.h" ENGINE_NAMESPACE_BEGIN GFX_NAMESPACE_BEGIN +class GBufferPass : PaintPass { + GBufferPass() = default; + virtual ~GBufferPass() override {}; + + void Init() { + DrawAttachmentInfo colorImage{ + .colorFormats = + { + ColorFormat::Low_UNorm8_Linear, // albedo + ColorFormat::Medium_Float16, // high precision normals + ColorFormat::Low_UNorm8_Linear, // roughness metallic + }, + .clearColorValues = + { + {0.0f, 0.0f, 0.0f, 1.0f}, // albedo + {0.5f, 0.5f, 1.0f, 0.0f}, // normals + {1.0f, 0.0f, 0.0f, 0.0f}, // roughness metallic + }, + }; + DrawAttachmentInfo depthImage{ + .depthFormat = DepthFormat::Medium_D24, + .clearDepthStencilValue = {.depth = 1.0f, .stencil = 0.0f}}; + } +}; + GFX_NAMESPACE_END ENGINE_NAMESPACE_END diff --git a/Engine/include/Popcorn/Graphics/PaintPasses/PaintPass.h b/Engine/include/Popcorn/Graphics/PaintPasses/PaintPass.h index 3ca79e5a..a38fcb24 100644 --- a/Engine/include/Popcorn/Graphics/PaintPasses/PaintPass.h +++ b/Engine/include/Popcorn/Graphics/PaintPasses/PaintPass.h @@ -7,6 +7,7 @@ ENGINE_NAMESPACE_BEGIN GFX_NAMESPACE_BEGIN class PaintPass { +public: PaintPass() = default; virtual ~PaintPass() {}; @@ -18,11 +19,14 @@ class PaintPass { m_depthAttachmentInfo = depthAttachmentInfo; }; - virtual void SetMaterialsToPasses() = 0; - protected: + // + // --- Attachments stuff ----------------------------------------------------- DrawAttachmentInfo m_colorAttachmentInfo{}; DrawAttachmentInfo m_depthAttachmentInfo{}; + + // + // --- Paint pass info stuff ------------------------------------------------- }; GFX_NAMESPACE_END diff --git a/Engine/include/Popcorn/Graphics/PaintPasses/PostFXPass.h b/Engine/include/Popcorn/Graphics/PaintPasses/PaintPassBuilder.h similarity index 100% rename from Engine/include/Popcorn/Graphics/PaintPasses/PostFXPass.h rename to Engine/include/Popcorn/Graphics/PaintPasses/PaintPassBuilder.h diff --git a/Engine/include/Popcorn/Graphics/PaintPasses/PaintPassDefs.h b/Engine/include/Popcorn/Graphics/PaintPasses/PaintPassDefs.h index 9977d1c2..3fe0c17e 100644 --- a/Engine/include/Popcorn/Graphics/PaintPasses/PaintPassDefs.h +++ b/Engine/include/Popcorn/Graphics/PaintPasses/PaintPassDefs.h @@ -39,6 +39,9 @@ struct alignas(16) ClearColorValue { float a = .0f; }; +typedef struct { +} GlobalUniformSet; + struct alignas(16) ClearDepthStencilValue { float depth = 1.0f; float stencil = .0f; @@ -97,32 +100,35 @@ struct MaterialInfo { const char *name; uint32_t materialId; ShaderSet shaderSet; + // store uniform data here std::vector uniformLayout; + // copy your uniforms here (from gltf loader) BufferView bufferView; // view into UBO memory (Vulkan staging buffer?) // TODO: Link to submesh memory }; typedef struct { + const char *name; + // store uniform data here std::vector uniformLayout; + // copy your uniforms here (from gltf loader) BufferView bufferView; // view into UBO memory (Vulkan staging buffer?) } ScreenspaceInfo; -// Engine will "bind" these buffers later (every frame); you are just setting -// the memory layouts -struct DataBuffers { - - // - // Submesh data sorted material so the paintPipelineInfo can select buckets - // for material specific draw (internally extract vbo ibo) -}; - typedef struct { + // From Vulkan defs } SamplerInfo; // Collect all submeshes of a certain "type" (maybe like typedef struct { - std::vector uniformSets; // contains actual data - + // TODO: Write a vertex version + std::vector vertexLayout; + // TODO: Write a index version + std::vector indexLayout; + // + std::vector uniformLayout; + // copy your uniforms here (from gltf loader) + BufferView bufferView; // view into UBO memory (Vulkan staging buffer?) } SubmeshBucket; struct PaintPipelineInfo { diff --git a/Engine/include/Popcorn/Graphics/PaintPasses/PaintPassMemorySource.h b/Engine/include/Popcorn/Graphics/PaintPasses/PaintPassMemorySource.h new file mode 100644 index 00000000..b40dfc04 --- /dev/null +++ b/Engine/include/Popcorn/Graphics/PaintPasses/PaintPassMemorySource.h @@ -0,0 +1,33 @@ +#pragma once + +#include "GlobalMacros.h" +#include +#include + +ENGINE_NAMESPACE_BEGIN +GFX_NAMESPACE_BEGIN + +class PaintPassMemorySource { + // Raw data + + // Deps - Submesh draw order + // VBO + // IBO + // UBO (submesh specific) + + // Global Uniform Sets + // UBO (Camera, Lights etc) + // SSBO + // TODO: Template this + void GetVboView(uint32_t index) {}; + void GetIboView(uint32_t index) {}; + void GetUboView(uint32_t index) {}; + +private: + std::byte *vbos = nullptr; + std::byte *ibos = nullptr; + std::byte *ubos = nullptr; +}; + +GFX_NAMESPACE_END +ENGINE_NAMESPACE_END diff --git a/Sandbox/02-Street-Scene/renderflows/gbufferRflow.h b/Engine/include/Popcorn/Graphics/PaintPasses/PostFxPass.h similarity index 100% rename from Sandbox/02-Street-Scene/renderflows/gbufferRflow.h rename to Engine/include/Popcorn/Graphics/PaintPasses/PostFxPass.h diff --git a/Sandbox/02-Street-Scene/renderflows/lightingRflow.h b/Sandbox/02-Street-Scene/paintpasses/myPaintPass_01.h similarity index 100% rename from Sandbox/02-Street-Scene/renderflows/lightingRflow.h rename to Sandbox/02-Street-Scene/paintpasses/myPaintPass_01.h diff --git a/Sandbox/02-Street-Scene/renderflows/shadowsRflow.h b/Sandbox/02-Street-Scene/paintpasses/myPaintPass_02.h similarity index 100% rename from Sandbox/02-Street-Scene/renderflows/shadowsRflow.h rename to Sandbox/02-Street-Scene/paintpasses/myPaintPass_02.h diff --git a/Sandbox/02-Street-Scene/paintpasses/paintPassBuilder.h b/Sandbox/02-Street-Scene/paintpasses/paintPassBuilder.h new file mode 100644 index 00000000..412f293b --- /dev/null +++ b/Sandbox/02-Street-Scene/paintpasses/paintPassBuilder.h @@ -0,0 +1,31 @@ +#pragma once + +namespace Paint { +class PaintPassBuilder { + PaintPassBuilder() = default; + + void Init() { + // shadow.Init(); + // gbuffer.Init(); + // bloomExtract.Init(); + // lighting.Init(); + // transclucency.Init(); + // bloomBlur.Init(); + // postFx.Init(); + // composite.Init(); + // myPaintPass.Init(); + } + + void Build() {} + + // ShadowPass shadow; + // GBufferPass gbuffer; + // LightingPass lighting; + // TransclucencyPass transclucency; + // BloomExtractPass bloomExtract; + // BloomBlurPass bloomBlur; + // PostFxPass postFx; + // CompositePass composite; + // CustomPass myPaintPass; +}; +} // namespace Paint diff --git a/Sandbox/02-Street-Scene/renderflows/transclucencyRflow.h b/Sandbox/02-Street-Scene/renderflows/transclucencyRflow.h deleted file mode 100644 index e69de29b..00000000 From 99e82f6aac0a06a30438f72cbc6d3430cacc3bb3 Mon Sep 17 00:00:00 2001 From: __prav__ Date: Tue, 20 Jan 2026 21:04:27 -0500 Subject: [PATCH 28/36] wip: renderflow - paintpass conversion --- .../Graphics/PaintPasses/GBufferPass.h | 5 +- .../Graphics/PaintPasses/PaintPassDefs.h | 1 - .../RenderFlows/GBufferRenderFlowVk.cpp | 180 +++++++++++++++++- Sandbox/02-Street-Scene/main-paintpasses.cpp | 74 +++++++ .../paintpasses/paintPassBuilder.h | 42 ++-- 5 files changed, 277 insertions(+), 25 deletions(-) create mode 100644 Sandbox/02-Street-Scene/main-paintpasses.cpp diff --git a/Engine/include/Popcorn/Graphics/PaintPasses/GBufferPass.h b/Engine/include/Popcorn/Graphics/PaintPasses/GBufferPass.h index 4fabe788..3f4847ae 100644 --- a/Engine/include/Popcorn/Graphics/PaintPasses/GBufferPass.h +++ b/Engine/include/Popcorn/Graphics/PaintPasses/GBufferPass.h @@ -10,13 +10,12 @@ GFX_NAMESPACE_BEGIN class GBufferPass : PaintPass { GBufferPass() = default; virtual ~GBufferPass() override {}; - void Init() { DrawAttachmentInfo colorImage{ .colorFormats = { - ColorFormat::Low_UNorm8_Linear, // albedo - ColorFormat::Medium_Float16, // high precision normals + ColorFormat::Low_UNorm8_SRGB, // albedo + ColorFormat::Low_UNorm8_Linear, // high precision normals ColorFormat::Low_UNorm8_Linear, // roughness metallic }, .clearColorValues = diff --git a/Engine/include/Popcorn/Graphics/PaintPasses/PaintPassDefs.h b/Engine/include/Popcorn/Graphics/PaintPasses/PaintPassDefs.h index 3fe0c17e..cba2bdff 100644 --- a/Engine/include/Popcorn/Graphics/PaintPasses/PaintPassDefs.h +++ b/Engine/include/Popcorn/Graphics/PaintPasses/PaintPassDefs.h @@ -125,7 +125,6 @@ typedef struct { std::vector vertexLayout; // TODO: Write a index version std::vector indexLayout; - // std::vector uniformLayout; // copy your uniforms here (from gltf loader) BufferView bufferView; // view into UBO memory (Vulkan staging buffer?) diff --git a/Engine/src/Popcorn/Platform/Vulkan/RenderFlows/GBufferRenderFlowVk.cpp b/Engine/src/Popcorn/Platform/Vulkan/RenderFlows/GBufferRenderFlowVk.cpp index fde854ec..f9cd2c97 100644 --- a/Engine/src/Popcorn/Platform/Vulkan/RenderFlows/GBufferRenderFlowVk.cpp +++ b/Engine/src/Popcorn/Platform/Vulkan/RenderFlows/GBufferRenderFlowVk.cpp @@ -33,7 +33,185 @@ GFX_NAMESPACE_BEGIN // --- CREATE ATTACHMENTS ------------------------------------------------------ // void GBufferRenderFlowVk::CreateAttachments() { - // TODO: DELETE + const auto &swapchainExtent = ContextVk::Swapchain()->GetSwapchainExtent(); + + const auto &width = swapchainExtent.width; + const auto &height = swapchainExtent.height; + + std::vector albedoCandidates = {VK_FORMAT_R8G8B8A8_UNORM, + VK_FORMAT_B8G8R8A8_UNORM}; + std::vector depthCandidates = {VK_FORMAT_D32_SFLOAT, + VK_FORMAT_D32_SFLOAT_S8_UINT, + VK_FORMAT_D24_UNORM_S8_UINT}; + std::vector normalCandidates = { + VK_FORMAT_R16G16B16A16_SFLOAT, // high precision normals + VK_FORMAT_R8G8B8A8_UNORM // Fallback (low precision) + }; + std::vector roughnessMetallicCandidates = { + VK_FORMAT_R8G8B8A8_UNORM, VK_FORMAT_B8G8R8A8_UNORM}; + + VkFormat albedoFormat = + ImageVk::FindSupportedFormat(albedoCandidates, VK_IMAGE_TILING_OPTIMAL, + VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT); + VkFormat depthFormat = ImageVk::FindSupportedFormat( + depthCandidates, VK_IMAGE_TILING_OPTIMAL, + VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT); + VkFormat normalFormat = + ImageVk::FindSupportedFormat(normalCandidates, VK_IMAGE_TILING_OPTIMAL, + VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT); + + VkFormat roughnessMetallicFormat = ImageVk::FindSupportedFormat( + roughnessMetallicCandidates, VK_IMAGE_TILING_OPTIMAL, + VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT); + + // + // + // --- Create g-buffer images ------------------------------------------------ + VkImageCreateInfo albedoImageInfo{}; + ImageVk::GetDefaultImageCreateInfo(albedoImageInfo, width, height, + albedoFormat); + albedoImageInfo.format = albedoFormat; + albedoImageInfo.usage = + VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT; + + VkImageCreateInfo depthImageInfo{}; + ImageVk::GetDefaultImageCreateInfo(depthImageInfo, width, height, + depthFormat); + depthImageInfo.format = depthFormat; + depthImageInfo.usage = + VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT; + + VkImageCreateInfo normalImageInfo{}; + ImageVk::GetDefaultImageCreateInfo(normalImageInfo, width, height, + normalFormat); + normalImageInfo.format = normalFormat; + normalImageInfo.usage = + VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT; + + VkImageCreateInfo roughnessMetallicImageInfo{}; + ImageVk::GetDefaultImageCreateInfo(roughnessMetallicImageInfo, width, height, + roughnessMetallicFormat); + roughnessMetallicImageInfo.format = roughnessMetallicFormat; + roughnessMetallicImageInfo.usage = + VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT; + + VmaAllocationCreateInfo albedoAlloc{.usage = VMA_MEMORY_USAGE_AUTO}; + VmaAllocationCreateInfo depthAlloc{.usage = VMA_MEMORY_USAGE_AUTO}; + VmaAllocationCreateInfo normalAlloc{.usage = VMA_MEMORY_USAGE_AUTO}; + VmaAllocationCreateInfo roughnessMetallicAlloc{.usage = + VMA_MEMORY_USAGE_AUTO}; + + for (size_t i = 0; i < MAX_FRAMES_IN_FLIGHT; ++i) { + ImageVk &albedoImage = s_gBufferImages.albedoImages[i]; + ImageVk &depthImage = s_gBufferImages.depthImages[i]; + ImageVk &normalImage = s_gBufferImages.normalImages[i]; + ImageVk &roughnessMetallicImage = + s_gBufferImages.roughnessMetallicImages[i]; + + albedoImage.CreateVmaImage(albedoImageInfo, albedoAlloc); + depthImage.CreateVmaImage(depthImageInfo, depthAlloc); + normalImage.CreateVmaImage(normalImageInfo, normalAlloc); + roughnessMetallicImage.CreateVmaImage(roughnessMetallicImageInfo, + roughnessMetallicAlloc); + + // + // + // --- Create g-buffer image-views ----------------------------------------- + VkImageViewCreateInfo albedoViewInfo{}; + ImageVk::GetDefaultImageViewCreateInfo( + albedoViewInfo, albedoImage.GetVkImage(), albedoFormat); + albedoViewInfo.format = albedoFormat; + albedoViewInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; + + VkImageViewCreateInfo depthViewInfo{}; + ImageVk::GetDefaultImageViewCreateInfo( + depthViewInfo, depthImage.GetVkImage(), depthFormat); + depthViewInfo.format = depthFormat; + depthViewInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT; + if (depthImage.FormatHasStencilComponent()) { + depthViewInfo.subresourceRange.aspectMask |= VK_IMAGE_ASPECT_STENCIL_BIT; + } + + VkImageViewCreateInfo normalViewInfo{}; + ImageVk::GetDefaultImageViewCreateInfo( + normalViewInfo, normalImage.GetVkImage(), normalFormat); + normalViewInfo.format = normalFormat; + normalViewInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; + + VkImageViewCreateInfo roughnessMetallicViewInfo{}; + ImageVk::GetDefaultImageViewCreateInfo(roughnessMetallicViewInfo, + roughnessMetallicImage.GetVkImage(), + roughnessMetallicFormat); + roughnessMetallicViewInfo.format = roughnessMetallicFormat; + roughnessMetallicViewInfo.subresourceRange.aspectMask = + VK_IMAGE_ASPECT_COLOR_BIT; + + albedoImage.CreateImageView(albedoViewInfo); + depthImage.CreateImageView(depthViewInfo); + normalImage.CreateImageView(normalViewInfo); + roughnessMetallicImage.CreateImageView(roughnessMetallicViewInfo); + + // + // + // --- Create g-buffer attachments ----------------------------------------- + VkAttachmentDescription albedoAttachment{}; + AttachmentVk::GetDefaultAttachmentDescription(albedoAttachment); + albedoAttachment.format = albedoFormat; + albedoAttachment.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; + albedoAttachment.finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; + albedoAttachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; + albedoAttachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE; + + VkAttachmentDescription depthAttachment{}; + AttachmentVk::GetDefaultAttachmentDescription(depthAttachment); + depthAttachment.format = depthFormat; + depthAttachment.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; + depthAttachment.finalLayout = + depthImage.FormatHasStencilComponent() + ? VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL + : VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL; + depthAttachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; + depthAttachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE; + + depthAttachment.stencilLoadOp = depthImage.FormatHasStencilComponent() + ? VK_ATTACHMENT_LOAD_OP_CLEAR + : VK_ATTACHMENT_LOAD_OP_DONT_CARE; + depthAttachment.stencilStoreOp = depthImage.FormatHasStencilComponent() + ? VK_ATTACHMENT_STORE_OP_STORE + : VK_ATTACHMENT_STORE_OP_DONT_CARE; + + VkAttachmentDescription normalAttachment{}; + AttachmentVk::GetDefaultAttachmentDescription(normalAttachment); + normalAttachment.format = normalFormat; + normalAttachment.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; + normalAttachment.finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; + normalAttachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; + normalAttachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE; + + VkAttachmentDescription roughnessMetallicAttachment{}; + AttachmentVk::GetDefaultAttachmentDescription(roughnessMetallicAttachment); + roughnessMetallicAttachment.format = roughnessMetallicFormat; + roughnessMetallicAttachment.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; + roughnessMetallicAttachment.finalLayout = + VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; + roughnessMetallicAttachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; + roughnessMetallicAttachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE; + + m_attachmentsVk.albedoAttachments[i].SetImageVk(&albedoImage); + m_attachmentsVk.depthAttachments[i].SetImageVk(&depthImage); + m_attachmentsVk.normalAttachments[i].SetImageVk(&normalImage); + m_attachmentsVk.roughnessMetallicAttachments[i].SetImageVk( + &roughnessMetallicImage); + + m_attachmentsVk.albedoAttachments[i].SetAttachmentDescription( + albedoAttachment); + m_attachmentsVk.depthAttachments[i].SetAttachmentDescription( + depthAttachment); + m_attachmentsVk.normalAttachments[i].SetAttachmentDescription( + normalAttachment); + m_attachmentsVk.roughnessMetallicAttachments[i].SetAttachmentDescription( + roughnessMetallicAttachment); + } } void GBufferRenderFlowVk::CreateRenderInfoState() { diff --git a/Sandbox/02-Street-Scene/main-paintpasses.cpp b/Sandbox/02-Street-Scene/main-paintpasses.cpp new file mode 100644 index 00000000..03a6f642 --- /dev/null +++ b/Sandbox/02-Street-Scene/main-paintpasses.cpp @@ -0,0 +1,74 @@ +// TODO: Add to Popcorn.h instead of a whole bunch of these: +#include "paintpasses/paintPassBuilder.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace Popcorn; +class BlenderScene : public Scene {}; // Game Objects are owned by Scene +class GameLayer : public Layer { +public: + GameLayer() = default; + + virtual void OnAttach() override { + Popcorn::Context::ConvertGltfToScene("../assets/models/gold.gltf", scene); + Popcorn::Context::RegisterScene(scene); + + // Init paintpass builder + paintPassBuilder.InitPasses(); + } + + virtual void OnDetach() override { + // Popcorn::Context::DisposeScene(scene); + } + virtual void OnUpdate(TimeEvent &e) override {} + virtual void OnRender() override { + // Draws all scenes + Popcorn::Context::RenderScenes(scene); + } + virtual bool OnEvent(Event &e) override { return false; } + +private: + BlenderScene scene; + Camera *camera; + + GameObject *rotorA; + + Paint::PaintPassBuilder paintPassBuilder; +}; + +int main(int argc, char **argv) { + Popcorn::Context::BeginContext(); + + auto gameLayer = new GameLayer(); + + Popcorn::Context::AddLayer(gameLayer); + Popcorn::Context::StartGame(); + + Popcorn::Context::EndContext(); + + return 0; +} diff --git a/Sandbox/02-Street-Scene/paintpasses/paintPassBuilder.h b/Sandbox/02-Street-Scene/paintpasses/paintPassBuilder.h index 412f293b..c067b64f 100644 --- a/Sandbox/02-Street-Scene/paintpasses/paintPassBuilder.h +++ b/Sandbox/02-Street-Scene/paintpasses/paintPassBuilder.h @@ -2,30 +2,32 @@ namespace Paint { class PaintPassBuilder { +public: PaintPassBuilder() = default; - void Init() { - // shadow.Init(); - // gbuffer.Init(); - // bloomExtract.Init(); - // lighting.Init(); - // transclucency.Init(); - // bloomBlur.Init(); - // postFx.Init(); - // composite.Init(); - // myPaintPass.Init(); + void InitPasses() { + // m_shadow.Init(); + // m_gbuffer.Init(); + // m_bloomExtract.Init(); + // m_lighting.Init(); + // m_transclucency.Init(); + // m_bloomBlur.Init(); + // m_postFx.Init(); + // m_composite.Init(); + // m_myPaintPass_01.Init(); + // m_myPaintPass_02.Init(); } void Build() {} - - // ShadowPass shadow; - // GBufferPass gbuffer; - // LightingPass lighting; - // TransclucencyPass transclucency; - // BloomExtractPass bloomExtract; - // BloomBlurPass bloomBlur; - // PostFxPass postFx; - // CompositePass composite; - // CustomPass myPaintPass; + // ShadowPass m_shadow; + // GBufferPass m_gbuffer; + // LightingPass m_lighting; + // TransclucencyPass m_transclucency; + // BloomExtractPass m_bloomExtract; + // BloomBlurPass m_bloomBlur; + // PostFxPass m_postFx; + // CompositePass m_composite; + // CustomPass m_myPaintPass_01; + // CustomPass m_myPaintPass_02; }; } // namespace Paint From 086d5f0eebb8d607a71749310089a56f2fcfe662 Mon Sep 17 00:00:00 2001 From: __prav__ Date: Tue, 20 Jan 2026 21:41:39 -0500 Subject: [PATCH 29/36] wip: renderflows to paintpasses - 2 --- Engine/CMakeLists.txt | 2 + .../Popcorn/Graphics/PaintPasses/PaintPass.h | 7 ++ .../Graphics/PaintPasses/PaintPassDefs.h | 9 ++ .../Platform/Vulkan/PaintPasses/PaintPassVk.h | 112 ++++++++++++++++++ .../Vulkan/RenderFlows/RFlowResourcesVk.h | 6 +- 5 files changed, 134 insertions(+), 2 deletions(-) create mode 100644 Engine/include/Popcorn/Platform/Vulkan/PaintPasses/PaintPassVk.h diff --git a/Engine/CMakeLists.txt b/Engine/CMakeLists.txt index e028d51a..0411e3c1 100644 --- a/Engine/CMakeLists.txt +++ b/Engine/CMakeLists.txt @@ -123,6 +123,7 @@ target_include_directories( $ $ $ + $ $ $ $ @@ -141,6 +142,7 @@ target_include_directories( INTERFACE $ $ $ + $ $ $ $ diff --git a/Engine/include/Popcorn/Graphics/PaintPasses/PaintPass.h b/Engine/include/Popcorn/Graphics/PaintPasses/PaintPass.h index a38fcb24..e7089a6c 100644 --- a/Engine/include/Popcorn/Graphics/PaintPasses/PaintPass.h +++ b/Engine/include/Popcorn/Graphics/PaintPasses/PaintPass.h @@ -17,8 +17,15 @@ class PaintPass { &depthAttachmentInfo) { m_colorAttachmentInfo = colorAttachmentInfo; m_depthAttachmentInfo = depthAttachmentInfo; + + MakeAttachmentInfos(); }; +protected: + // + // --- Platform internals ---------------------------------------------------- + virtual void MakeAttachmentInfos() = 0; + protected: // // --- Attachments stuff ----------------------------------------------------- diff --git a/Engine/include/Popcorn/Graphics/PaintPasses/PaintPassDefs.h b/Engine/include/Popcorn/Graphics/PaintPasses/PaintPassDefs.h index cba2bdff..839d9c57 100644 --- a/Engine/include/Popcorn/Graphics/PaintPasses/PaintPassDefs.h +++ b/Engine/include/Popcorn/Graphics/PaintPasses/PaintPassDefs.h @@ -47,16 +47,25 @@ struct alignas(16) ClearDepthStencilValue { float stencil = .0f; }; +enum class AttachmentFlags : uint32_t { + None = 0, + SampledBit, + ColorBit, + DepthBit, +}; + template struct DrawAttachmentInfo; template <> struct DrawAttachmentInfo { std::vector colorFormats{}; std::vector clearColorValues{}; + AttachmentFlags attachmentFlag = AttachmentFlags::ColorBit; }; template <> struct DrawAttachmentInfo { DepthFormat depthFormat; ClearDepthStencilValue clearDepthStencilValue; + AttachmentFlags attachmentFlag = AttachmentFlags::DepthBit; }; typedef struct { diff --git a/Engine/include/Popcorn/Platform/Vulkan/PaintPasses/PaintPassVk.h b/Engine/include/Popcorn/Platform/Vulkan/PaintPasses/PaintPassVk.h new file mode 100644 index 00000000..18cc6a83 --- /dev/null +++ b/Engine/include/Popcorn/Platform/Vulkan/PaintPasses/PaintPassVk.h @@ -0,0 +1,112 @@ +#pragma once + +#include "GlobalMacros.h" +#include "ImageVk.h" +#include "PaintPasses/PaintPass.h" + +ENGINE_NAMESPACE_BEGIN +GFX_NAMESPACE_BEGIN + +enum RFlowImages { + Color_RGBA_HiRes, + Low_UNorm8_Linear, + Depth_Auto, +}; + +class PaintPassVk : public PaintPass { + PaintPassVk() = default; + + void MakeAttachmentInfos() override {}; + + template + static void CreateImageAndView(uint32_t width, uint32_t height, + ImageVk &imageVk) { + std::vector formatCandidates{}; + VkFormat selectedFormat; + VkImageCreateInfo imageCreateInfo{}; + VmaAllocationCreateInfo imageAlloc{.usage = VMA_MEMORY_USAGE_AUTO}; + + VkImageViewCreateInfo imageViewCreateInfo{}; + + // TODO: Write for paintpass typedefs + + if constexpr (T == RFlowImages::Low_UNorm8_Linear) { + // --- Color --- + // Low Res color + formatCandidates = {VK_FORMAT_R8G8B8A8_UNORM, VK_FORMAT_B8G8R8A8_UNORM}; + selectedFormat = ImageVk::FindSupportedFormat( + formatCandidates, VK_IMAGE_TILING_OPTIMAL, + VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT); + + ImageVk::GetDefaultImageCreateInfo(imageCreateInfo, width, height, + selectedFormat); + imageCreateInfo.format = selectedFormat; + imageCreateInfo.usage = + VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT; + + imageVk.CreateVmaImage(imageCreateInfo, imageAlloc); + + // --- Image View --- + ImageVk::GetDefaultImageViewCreateInfo( + imageViewCreateInfo, imageVk.GetVkImage(), selectedFormat); + imageViewCreateInfo.format = selectedFormat; + imageViewCreateInfo.subresourceRange.aspectMask = + VK_IMAGE_ASPECT_COLOR_BIT; + } else if constexpr (T == RFlowImages::Color_RGBA_HiRes) { + // --- Color --- + // High Res color, fallback to low res + formatCandidates = {VK_FORMAT_R16G16B16A16_SFLOAT, + VK_FORMAT_R8G8B8A8_UNORM}; + selectedFormat = ImageVk::FindSupportedFormat( + formatCandidates, VK_IMAGE_TILING_OPTIMAL, + VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT); + + ImageVk::GetDefaultImageCreateInfo(imageCreateInfo, width, height, + selectedFormat); + imageCreateInfo.format = selectedFormat; + imageCreateInfo.usage = + VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT; + + imageVk.CreateVmaImage(imageCreateInfo, imageAlloc); + + // --- Image View --- + ImageVk::GetDefaultImageViewCreateInfo( + imageViewCreateInfo, imageVk.GetVkImage(), selectedFormat); + imageViewCreateInfo.format = selectedFormat; + imageViewCreateInfo.subresourceRange.aspectMask = + VK_IMAGE_ASPECT_COLOR_BIT; + } else { + // --- Depth --- + // High Res depth, fallback to low res + formatCandidates = {VK_FORMAT_D32_SFLOAT, VK_FORMAT_D32_SFLOAT_S8_UINT, + VK_FORMAT_D24_UNORM_S8_UINT}; + selectedFormat = ImageVk::FindSupportedFormat( + formatCandidates, VK_IMAGE_TILING_OPTIMAL, + VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT); + + ImageVk::GetDefaultImageCreateInfo(imageCreateInfo, width, height, + selectedFormat); + imageCreateInfo.format = selectedFormat; + imageCreateInfo.usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | + VK_IMAGE_USAGE_SAMPLED_BIT; + + imageVk.CreateVmaImage(imageCreateInfo, imageAlloc); + + // --- Image View --- + ImageVk::GetDefaultImageViewCreateInfo( + imageViewCreateInfo, imageVk.GetVkImage(), selectedFormat); + imageViewCreateInfo.format = selectedFormat; + imageViewCreateInfo.subresourceRange.aspectMask = + VK_IMAGE_ASPECT_DEPTH_BIT; + if (imageVk.FormatHasStencilComponent()) { + imageViewCreateInfo.subresourceRange.aspectMask |= + VK_IMAGE_ASPECT_STENCIL_BIT; + } + } + + imageVk.CreateImageView(imageViewCreateInfo); + }; +}; + +GFX_NAMESPACE_END +ENGINE_NAMESPACE_END diff --git a/Engine/include/Popcorn/Platform/Vulkan/RenderFlows/RFlowResourcesVk.h b/Engine/include/Popcorn/Platform/Vulkan/RenderFlows/RFlowResourcesVk.h index b6acc480..e41e875d 100644 --- a/Engine/include/Popcorn/Platform/Vulkan/RenderFlows/RFlowResourcesVk.h +++ b/Engine/include/Popcorn/Platform/Vulkan/RenderFlows/RFlowResourcesVk.h @@ -9,7 +9,7 @@ GFX_NAMESPACE_BEGIN enum RFlowImages { Color_RGBA_HiRes, - Color_RGBA_LoRes, + Low_UNorm8_Linear, Depth_Auto, }; @@ -49,6 +49,8 @@ class RFlowResourcesVk { static void GetDefaultRenderingInfo() {} + // Creates [one image + one view] combo + // TODO: future, [one image + multiple views] template static void CreateImageAndView(uint32_t width, uint32_t height, ImageVk &imageVk) { @@ -59,7 +61,7 @@ class RFlowResourcesVk { VkImageViewCreateInfo imageViewCreateInfo{}; - if constexpr (T == RFlowImages::Color_RGBA_LoRes) { + if constexpr (T == RFlowImages::Low_UNorm8_Linear) { // --- Color --- // Low Res color formatCandidates = {VK_FORMAT_R8G8B8A8_UNORM, VK_FORMAT_B8G8R8A8_UNORM}; From 49be7ce01b550a8312e40127854d0a7a5dabf8cc Mon Sep 17 00:00:00 2001 From: __prav__ Date: Fri, 23 Jan 2026 21:00:25 -0500 Subject: [PATCH 30/36] feat: paint pass forward movement :D --- Engine/include/Popcorn.h | 11 ++--- .../Popcorn/Graphics/PaintPasses/Example.h | 14 ++++++ .../Graphics/PaintPasses/GBufferPass.h | 8 +++- .../Popcorn/Graphics/PaintPasses/PaintPass.h | 13 +++--- .../Graphics/PaintPasses/PaintPassBuilder.h | 0 .../Graphics/PaintPasses/PaintPassDefs.h | 3 -- Engine/include/Popcorn/Graphics/Renderer.h | 12 +++-- .../Popcorn/Platform/OpenGL/RendererOpenGL.h | 4 ++ .../Platform/Vulkan/PaintPasses/PaintPassVk.h | 22 +++++---- .../Vulkan/RenderFlows/RFlowResourcesVk.h | 8 ++-- .../Popcorn/Platform/Vulkan/RendererVk.h | 4 ++ .../Popcorn/Platform/Vulkan/RendererVk.cpp | 45 +++++++++++++++++++ .../paintpasses/paintPassBuilder.h | 32 ++++++++----- 13 files changed, 130 insertions(+), 46 deletions(-) create mode 100644 Engine/include/Popcorn/Graphics/PaintPasses/Example.h delete mode 100644 Engine/include/Popcorn/Graphics/PaintPasses/PaintPassBuilder.h diff --git a/Engine/include/Popcorn.h b/Engine/include/Popcorn.h index bc0e8f2a..1475b19b 100644 --- a/Engine/include/Popcorn.h +++ b/Engine/include/Popcorn.h @@ -40,18 +40,13 @@ static void AddLayer(Layer *layer) { static void RegisterScene(Scene &scene) { s_renderer->AddScene(&scene); }; static void UnregisterScene(Scene &scene) { s_renderer->RemoveScene(&scene); }; -static void DefinePaintPasses() { - - // s_renderer->DefineRenderFlow( - // { - // } - // ) -} - static void StartGame() { // TODO: Move the ownership of commandbuffers to Renderflow base class // // NEW: --- Make your own renderflows --- + // + // s_renderer->MakePaintPasses(); + // s_renderer->CreateRenderFlows(); // 1. Each renderflow takes in // a. Attachments (and Info) // b. RenderInfo diff --git a/Engine/include/Popcorn/Graphics/PaintPasses/Example.h b/Engine/include/Popcorn/Graphics/PaintPasses/Example.h new file mode 100644 index 00000000..e416828f --- /dev/null +++ b/Engine/include/Popcorn/Graphics/PaintPasses/Example.h @@ -0,0 +1,14 @@ +#pragma once + +#include "GlobalMacros.h" +#include "PaintPasses/GBufferPass.h" + +ENGINE_NAMESPACE_BEGIN +GFX_NAMESPACE_BEGIN + +class Pass { + GBufferPass *gbuffer; +}; + +GFX_NAMESPACE_END +ENGINE_NAMESPACE_END diff --git a/Engine/include/Popcorn/Graphics/PaintPasses/GBufferPass.h b/Engine/include/Popcorn/Graphics/PaintPasses/GBufferPass.h index 3f4847ae..fb63f0b5 100644 --- a/Engine/include/Popcorn/Graphics/PaintPasses/GBufferPass.h +++ b/Engine/include/Popcorn/Graphics/PaintPasses/GBufferPass.h @@ -7,10 +7,14 @@ ENGINE_NAMESPACE_BEGIN GFX_NAMESPACE_BEGIN -class GBufferPass : PaintPass { +class GBufferPass : public PaintPass { +public: GBufferPass() = default; virtual ~GBufferPass() override {}; + void Init() { + // + // --- Create attachments (images) ----------------------------------------- DrawAttachmentInfo colorImage{ .colorFormats = { @@ -28,6 +32,8 @@ class GBufferPass : PaintPass { DrawAttachmentInfo depthImage{ .depthFormat = DepthFormat::Medium_D24, .clearDepthStencilValue = {.depth = 1.0f, .stencil = 0.0f}}; + + SetAttachmentInfos(colorImage, depthImage); } }; diff --git a/Engine/include/Popcorn/Graphics/PaintPasses/PaintPass.h b/Engine/include/Popcorn/Graphics/PaintPasses/PaintPass.h index e7089a6c..f73f5ce4 100644 --- a/Engine/include/Popcorn/Graphics/PaintPasses/PaintPass.h +++ b/Engine/include/Popcorn/Graphics/PaintPasses/PaintPass.h @@ -6,9 +6,11 @@ ENGINE_NAMESPACE_BEGIN GFX_NAMESPACE_BEGIN +class PaintPassVk; + class PaintPass { public: - PaintPass() = default; + PaintPass() {}; virtual ~PaintPass() {}; void SetAttachmentInfos( @@ -17,16 +19,11 @@ class PaintPass { &depthAttachmentInfo) { m_colorAttachmentInfo = colorAttachmentInfo; m_depthAttachmentInfo = depthAttachmentInfo; - - MakeAttachmentInfos(); }; -protected: - // - // --- Platform internals ---------------------------------------------------- - virtual void MakeAttachmentInfos() = 0; + friend class PaintPassVk; -protected: +private: // // --- Attachments stuff ----------------------------------------------------- DrawAttachmentInfo m_colorAttachmentInfo{}; diff --git a/Engine/include/Popcorn/Graphics/PaintPasses/PaintPassBuilder.h b/Engine/include/Popcorn/Graphics/PaintPasses/PaintPassBuilder.h deleted file mode 100644 index e69de29b..00000000 diff --git a/Engine/include/Popcorn/Graphics/PaintPasses/PaintPassDefs.h b/Engine/include/Popcorn/Graphics/PaintPasses/PaintPassDefs.h index 839d9c57..286460b9 100644 --- a/Engine/include/Popcorn/Graphics/PaintPasses/PaintPassDefs.h +++ b/Engine/include/Popcorn/Graphics/PaintPasses/PaintPassDefs.h @@ -1,9 +1,6 @@ #pragma once -#include "BufferObjects.h" #include "GlobalMacros.h" -#include "MaterialTypes.h" -#include "Mesh.h" #include "Uniforms.h" #include #include diff --git a/Engine/include/Popcorn/Graphics/Renderer.h b/Engine/include/Popcorn/Graphics/Renderer.h index e6339216..a50fe3e9 100644 --- a/Engine/include/Popcorn/Graphics/Renderer.h +++ b/Engine/include/Popcorn/Graphics/Renderer.h @@ -1,17 +1,19 @@ #pragma once #include "GlobalMacros.h" +#include "PaintPasses/PaintPass.h" #include "Popcorn/Core/Window.h" #include "Popcorn/Events/WindowEvent.h" #include "SceneLibrary.h" +#include ENGINE_NAMESPACE_BEGIN GFX_NAMESPACE_BEGIN enum class RendererType { None = 0, - OpenGL = PC_ShiftLeft(1), - Vulkan = PC_ShiftLeft(2), + OpenGL, + Vulkan // DirectX = shift_l(3), // Metal = shift_l(4) }; @@ -39,10 +41,14 @@ class Renderer { void AddScene(Scene *scene) { m_sceneLibrary.Add(scene); }; void RemoveScene(Scene *scene) { m_sceneLibrary.Remove(scene); }; + // TODO: Delete virtual void CreateRenderFlows() = 0; virtual void DestroyRenderFlows() = 0; virtual void PrepareRenderFlows() = 0; + // PaintPasses + virtual void MakePaintPasses(const std::vector &paintPasses) = 0; + virtual void AssignSceneObjectsToRenderFlows() = 0; virtual void CreateRenderFlowResources() = 0; virtual void ProcessGameObjectNode(GameObject *node) = 0; @@ -55,7 +61,7 @@ class Renderer { Renderer(const Renderer &) = delete; Renderer &operator=(const Renderer &) = delete; Renderer(Renderer &&) = delete; - Renderer &operator=(const Renderer &&) = delete; + Renderer &operator=(Renderer &&) = delete; #ifdef PC_DEBUG void PrintScenes() const { m_sceneLibrary.PrintScenes(); }; diff --git a/Engine/include/Popcorn/Platform/OpenGL/RendererOpenGL.h b/Engine/include/Popcorn/Platform/OpenGL/RendererOpenGL.h index bd5430f0..00f98f62 100644 --- a/Engine/include/Popcorn/Platform/OpenGL/RendererOpenGL.h +++ b/Engine/include/Popcorn/Platform/OpenGL/RendererOpenGL.h @@ -14,6 +14,10 @@ class RendererOpenGL : public Renderer { virtual void CreateRenderFlows() override {}; virtual void DestroyRenderFlows() override {}; virtual void PrepareRenderFlows() override {}; + + virtual void + MakePaintPasses(const std::vector &paintPasses) override {}; + virtual void AssignSceneObjectsToRenderFlows() override {}; virtual void CreateRenderFlowResources() override {}; diff --git a/Engine/include/Popcorn/Platform/Vulkan/PaintPasses/PaintPassVk.h b/Engine/include/Popcorn/Platform/Vulkan/PaintPasses/PaintPassVk.h index 18cc6a83..f0b6060c 100644 --- a/Engine/include/Popcorn/Platform/Vulkan/PaintPasses/PaintPassVk.h +++ b/Engine/include/Popcorn/Platform/Vulkan/PaintPasses/PaintPassVk.h @@ -7,18 +7,21 @@ ENGINE_NAMESPACE_BEGIN GFX_NAMESPACE_BEGIN -enum RFlowImages { +enum PaintPassColorFormats { Color_RGBA_HiRes, Low_UNorm8_Linear, Depth_Auto, }; -class PaintPassVk : public PaintPass { - PaintPassVk() = default; - - void MakeAttachmentInfos() override {}; +class PaintPassVk { +public: + PaintPassVk(const PaintPass &pp) : m_paintPass(pp) {}; + void MakeAttachmentInfos() { + // m_paintPass.m_colorAttachmentInfo; + // m_paintPass.m_depthAttachmentInfo; + }; - template + template static void CreateImageAndView(uint32_t width, uint32_t height, ImageVk &imageVk) { std::vector formatCandidates{}; @@ -30,7 +33,7 @@ class PaintPassVk : public PaintPass { // TODO: Write for paintpass typedefs - if constexpr (T == RFlowImages::Low_UNorm8_Linear) { + if constexpr (T == PaintPassColorFormats::Low_UNorm8_Linear) { // --- Color --- // Low Res color formatCandidates = {VK_FORMAT_R8G8B8A8_UNORM, VK_FORMAT_B8G8R8A8_UNORM}; @@ -52,7 +55,7 @@ class PaintPassVk : public PaintPass { imageViewCreateInfo.format = selectedFormat; imageViewCreateInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; - } else if constexpr (T == RFlowImages::Color_RGBA_HiRes) { + } else if constexpr (T == PaintPassColorFormats::Color_RGBA_HiRes) { // --- Color --- // High Res color, fallback to low res formatCandidates = {VK_FORMAT_R16G16B16A16_SFLOAT, @@ -106,6 +109,9 @@ class PaintPassVk : public PaintPass { imageVk.CreateImageView(imageViewCreateInfo); }; + +private: + const PaintPass &m_paintPass; }; GFX_NAMESPACE_END diff --git a/Engine/include/Popcorn/Platform/Vulkan/RenderFlows/RFlowResourcesVk.h b/Engine/include/Popcorn/Platform/Vulkan/RenderFlows/RFlowResourcesVk.h index e41e875d..7b4d1c52 100644 --- a/Engine/include/Popcorn/Platform/Vulkan/RenderFlows/RFlowResourcesVk.h +++ b/Engine/include/Popcorn/Platform/Vulkan/RenderFlows/RFlowResourcesVk.h @@ -7,7 +7,7 @@ ENGINE_NAMESPACE_BEGIN GFX_NAMESPACE_BEGIN -enum RFlowImages { +enum PaintPassColorFormats { Color_RGBA_HiRes, Low_UNorm8_Linear, Depth_Auto, @@ -51,7 +51,7 @@ class RFlowResourcesVk { // Creates [one image + one view] combo // TODO: future, [one image + multiple views] - template + template static void CreateImageAndView(uint32_t width, uint32_t height, ImageVk &imageVk) { std::vector formatCandidates{}; @@ -61,7 +61,7 @@ class RFlowResourcesVk { VkImageViewCreateInfo imageViewCreateInfo{}; - if constexpr (T == RFlowImages::Low_UNorm8_Linear) { + if constexpr (T == PaintPassColorFormats::Low_UNorm8_Linear) { // --- Color --- // Low Res color formatCandidates = {VK_FORMAT_R8G8B8A8_UNORM, VK_FORMAT_B8G8R8A8_UNORM}; @@ -83,7 +83,7 @@ class RFlowResourcesVk { imageViewCreateInfo.format = selectedFormat; imageViewCreateInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; - } else if constexpr (T == RFlowImages::Color_RGBA_HiRes) { + } else if constexpr (T == PaintPassColorFormats::Color_RGBA_HiRes) { // --- Color --- // High Res color, fallback to low res formatCandidates = {VK_FORMAT_R16G16B16A16_SFLOAT, diff --git a/Engine/include/Popcorn/Platform/Vulkan/RendererVk.h b/Engine/include/Popcorn/Platform/Vulkan/RendererVk.h index d12a38a5..5ba3f45c 100644 --- a/Engine/include/Popcorn/Platform/Vulkan/RendererVk.h +++ b/Engine/include/Popcorn/Platform/Vulkan/RendererVk.h @@ -24,6 +24,10 @@ class RendererVk : public Renderer { virtual void CreateRenderFlows() override; virtual void DestroyRenderFlows() override; virtual void PrepareRenderFlows() override; + + virtual void + MakePaintPasses(const std::vector &paintPasses) override; + virtual void AssignSceneObjectsToRenderFlows() override; virtual void CreateRenderFlowResources() override; diff --git a/Engine/src/Popcorn/Platform/Vulkan/RendererVk.cpp b/Engine/src/Popcorn/Platform/Vulkan/RendererVk.cpp index 37ed8565..9297cf6b 100644 --- a/Engine/src/Popcorn/Platform/Vulkan/RendererVk.cpp +++ b/Engine/src/Popcorn/Platform/Vulkan/RendererVk.cpp @@ -5,6 +5,8 @@ #include "GameObject.h" #include "LightingRenderFlowVk.h" #include "Material.h" +#include "PaintPasses/PaintPass.h" +#include "PaintPasses/PaintPassVk.h" #include "Popcorn/Core/Base.h" #include "Popcorn/Core/Helpers.h" #include "RenderFlowDefs.h" @@ -85,6 +87,10 @@ void RendererVk::DestroyVulkanContext() { // --------------------------------------------------------------------------- // --- RENDER WORKFLOWS ------------------------------------------------------ void RendererVk::CreateRenderFlows() { + // + // TODO: Take PaintPasses (paintpasses are only Info objects. they will be + // converted to RenderflowVks with Vulkan memory and vulkan passes) + // s_renderFlows.emplace_back(new GBufferRenderFlowVk()); s_renderFlows.emplace_back(new LightingRenderFlowVk()); s_renderFlows.emplace_back(new CompositeRenderFlowVk()); @@ -134,6 +140,45 @@ void RendererVk::PrepareRenderFlows() { &s_renderFlows[2]->GetCommandBuffers(); } +void MakePaintPasses(const std::vector &paintPasses) { + // Create Draw order list? + // PaintPassInfos, (contains PaintPipelineInfos) + // make sequence from ^ + + // + // 0. Extract data and create Vulkan memory from SubmeshBucketData + // (VBOs, IBOs, UBOs, SSBOs, Samplers, Compute) + // + // --- Global --- + // 1. Create Vulkan AttachmentInfos from DrawAttachmentInfos + // + // --- Per pass --- + // --- Per pipeline --- + // 2. Create Vulkan RenderingInfos from + // PaintPassInfo.PaintPipelineInfos[index] + // 3. Make DSets from SubmeshBucketData, MaterialData, .etc + // types - global(L0), per material(L1), per submesh(L2) + // linked to step 0 + // 4. Make shader modules and samplers (material/fullscreen) + // 5. Make Vulkan pipeline based on the renderinfos ^^ + // 6. Free shaders? + // + // --- Global/Outside --- + // 7. Accessor class to all of the above resources + // 8. Ready for game loop !! + // + + // + // STEP 0. + // + // STEP 1. + // --- Create Vulkan AttachmentInfos from DrawAttachmentInfos -------------- + // + for (const PaintPass &paintPass : paintPasses) { + PaintPassVk::MakeAttachmentInfos(); + } +}; + void RendererVk::CreateRenderFlowResources() { // // CREATE WORKFLOW RESOURCES ----------------------------------------------- diff --git a/Sandbox/02-Street-Scene/paintpasses/paintPassBuilder.h b/Sandbox/02-Street-Scene/paintpasses/paintPassBuilder.h index c067b64f..df88127b 100644 --- a/Sandbox/02-Street-Scene/paintpasses/paintPassBuilder.h +++ b/Sandbox/02-Street-Scene/paintpasses/paintPassBuilder.h @@ -1,26 +1,36 @@ #pragma once +#include namespace Paint { class PaintPassBuilder { public: PaintPassBuilder() = default; void InitPasses() { - // m_shadow.Init(); - // m_gbuffer.Init(); - // m_bloomExtract.Init(); - // m_lighting.Init(); - // m_transclucency.Init(); - // m_bloomBlur.Init(); - // m_postFx.Init(); - // m_composite.Init(); - // m_myPaintPass_01.Init(); - // m_myPaintPass_02.Init(); + + if (Popcorn::Gfx::Renderer::GetAPI() == + Popcorn::Gfx::RendererType::Vulkan) { + }; + + // + // TODO: Create actual memory for paintpasses (PaintPassVks) + // + // m_shadow->Init(); + // m_gbuffer->Init(); + // m_bloomExtract->Init(); + // m_lighting->Init(); + // m_transclucency->Init(); + // m_bloomBlur->Init(); + // m_postFx->Init(); + // m_composite->Init(); + // m_myPaintPass_01->Init(); + // m_myPaintPass_02->Init(); } void Build() {} + // ShadowPass m_shadow; - // GBufferPass m_gbuffer; + // GBufferPass *m_gbuffer; // LightingPass m_lighting; // TransclucencyPass m_transclucency; // BloomExtractPass m_bloomExtract; From 6590511fe7ddaa41287a2597e969a5117e6ffb9b Mon Sep 17 00:00:00 2001 From: __prav__ Date: Sat, 24 Jan 2026 17:27:47 -0500 Subject: [PATCH 31/36] wip: paintpasses - slow progress --- Engine/include/Popcorn.h | 6 ++-- .../Graphics/PaintPasses/PaintPassDefs.h | 7 +++-- Engine/include/Popcorn/Graphics/Renderer.h | 3 +- .../Popcorn/Platform/OpenGL/RendererOpenGL.h | 2 +- .../Platform/Vulkan/PaintPasses/PaintPassVk.h | 20 ++++++++----- .../Popcorn/Platform/Vulkan/RendererVk.h | 6 +++- Engine/src/Popcorn/Loaders/GltfLoader.cpp | 29 +++++++++++++++---- .../Popcorn/Platform/Vulkan/RendererVk.cpp | 16 ++++++++-- .../paintpasses/paintPassBuilder.h | 8 +---- 9 files changed, 67 insertions(+), 30 deletions(-) diff --git a/Engine/include/Popcorn.h b/Engine/include/Popcorn.h index 1475b19b..9dfa4238 100644 --- a/Engine/include/Popcorn.h +++ b/Engine/include/Popcorn.h @@ -11,6 +11,7 @@ #include "Scene.h" #include "SplineFactory.h" #include +#include ENGINE_NAMESPACE_BEGIN CTX_NAMESPACE_BEGIN @@ -45,8 +46,9 @@ static void StartGame() { // // NEW: --- Make your own renderflows --- // - // s_renderer->MakePaintPasses(); - // + // const std::vector paintPasses{}; + // s_renderer->MakePaintPasses(paintPasses); + s_renderer->CreateRenderFlows(); // 1. Each renderflow takes in // a. Attachments (and Info) // b. RenderInfo diff --git a/Engine/include/Popcorn/Graphics/PaintPasses/PaintPassDefs.h b/Engine/include/Popcorn/Graphics/PaintPasses/PaintPassDefs.h index 286460b9..4054cef8 100644 --- a/Engine/include/Popcorn/Graphics/PaintPasses/PaintPassDefs.h +++ b/Engine/include/Popcorn/Graphics/PaintPasses/PaintPassDefs.h @@ -46,9 +46,12 @@ struct alignas(16) ClearDepthStencilValue { enum class AttachmentFlags : uint32_t { None = 0, + // Usage bits SampledBit, ColorBit, DepthBit, + StorageBit, + DepthStencilBit, }; template struct DrawAttachmentInfo; @@ -56,13 +59,13 @@ template struct DrawAttachmentInfo; template <> struct DrawAttachmentInfo { std::vector colorFormats{}; std::vector clearColorValues{}; - AttachmentFlags attachmentFlag = AttachmentFlags::ColorBit; + AttachmentFlags attachmentFlags = AttachmentFlags::ColorBit; }; template <> struct DrawAttachmentInfo { DepthFormat depthFormat; ClearDepthStencilValue clearDepthStencilValue; - AttachmentFlags attachmentFlag = AttachmentFlags::DepthBit; + AttachmentFlags attachmentFlags = AttachmentFlags::DepthBit; }; typedef struct { diff --git a/Engine/include/Popcorn/Graphics/Renderer.h b/Engine/include/Popcorn/Graphics/Renderer.h index a50fe3e9..34861b80 100644 --- a/Engine/include/Popcorn/Graphics/Renderer.h +++ b/Engine/include/Popcorn/Graphics/Renderer.h @@ -47,7 +47,8 @@ class Renderer { virtual void PrepareRenderFlows() = 0; // PaintPasses - virtual void MakePaintPasses(const std::vector &paintPasses) = 0; + virtual void + ProcessPaintPasses(const std::vector &paintPasses) = 0; virtual void AssignSceneObjectsToRenderFlows() = 0; virtual void CreateRenderFlowResources() = 0; diff --git a/Engine/include/Popcorn/Platform/OpenGL/RendererOpenGL.h b/Engine/include/Popcorn/Platform/OpenGL/RendererOpenGL.h index 00f98f62..5a760118 100644 --- a/Engine/include/Popcorn/Platform/OpenGL/RendererOpenGL.h +++ b/Engine/include/Popcorn/Platform/OpenGL/RendererOpenGL.h @@ -16,7 +16,7 @@ class RendererOpenGL : public Renderer { virtual void PrepareRenderFlows() override {}; virtual void - MakePaintPasses(const std::vector &paintPasses) override {}; + ProcessPaintPasses(const std::vector &paintPasses) override {}; virtual void AssignSceneObjectsToRenderFlows() override {}; virtual void CreateRenderFlowResources() override {}; diff --git a/Engine/include/Popcorn/Platform/Vulkan/PaintPasses/PaintPassVk.h b/Engine/include/Popcorn/Platform/Vulkan/PaintPasses/PaintPassVk.h index f0b6060c..9d3c8d73 100644 --- a/Engine/include/Popcorn/Platform/Vulkan/PaintPasses/PaintPassVk.h +++ b/Engine/include/Popcorn/Platform/Vulkan/PaintPasses/PaintPassVk.h @@ -3,25 +3,32 @@ #include "GlobalMacros.h" #include "ImageVk.h" #include "PaintPasses/PaintPass.h" +#include "PaintPasses/PaintPassDefs.h" ENGINE_NAMESPACE_BEGIN GFX_NAMESPACE_BEGIN enum PaintPassColorFormats { - Color_RGBA_HiRes, Low_UNorm8_Linear, + Color_RGBA_HiRes, Depth_Auto, }; class PaintPassVk { public: PaintPassVk(const PaintPass &pp) : m_paintPass(pp) {}; + + PaintPassVk(const PaintPassVk &) = delete; + PaintPassVk(PaintPassVk &&) = default; + void MakeAttachmentInfos() { - // m_paintPass.m_colorAttachmentInfo; - // m_paintPass.m_depthAttachmentInfo; + m_paintPass.m_colorAttachmentInfo; + m_paintPass.m_depthAttachmentInfo; + + // Create Vk Images }; - template + template static void CreateImageAndView(uint32_t width, uint32_t height, ImageVk &imageVk) { std::vector formatCandidates{}; @@ -30,10 +37,9 @@ class PaintPassVk { VmaAllocationCreateInfo imageAlloc{.usage = VMA_MEMORY_USAGE_AUTO}; VkImageViewCreateInfo imageViewCreateInfo{}; - // TODO: Write for paintpass typedefs - if constexpr (T == PaintPassColorFormats::Low_UNorm8_Linear) { + if constexpr (T == ColorFormat::Low_UNorm8_Linear) { // --- Color --- // Low Res color formatCandidates = {VK_FORMAT_R8G8B8A8_UNORM, VK_FORMAT_B8G8R8A8_UNORM}; @@ -55,7 +61,7 @@ class PaintPassVk { imageViewCreateInfo.format = selectedFormat; imageViewCreateInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; - } else if constexpr (T == PaintPassColorFormats::Color_RGBA_HiRes) { + } else if constexpr (T == ColorFormats::Color_RGBA_HiRes) { // --- Color --- // High Res color, fallback to low res formatCandidates = {VK_FORMAT_R16G16B16A16_SFLOAT, diff --git a/Engine/include/Popcorn/Platform/Vulkan/RendererVk.h b/Engine/include/Popcorn/Platform/Vulkan/RendererVk.h index 5ba3f45c..ce81ba08 100644 --- a/Engine/include/Popcorn/Platform/Vulkan/RendererVk.h +++ b/Engine/include/Popcorn/Platform/Vulkan/RendererVk.h @@ -3,6 +3,7 @@ #include "ContextVk.h" #include "GameObject.h" #include "GlobalMacros.h" +#include "PaintPasses/PaintPassVk.h" #include "Popcorn/Core/Window.h" #include "Popcorn/Events/WindowEvent.h" #include "RenderFlowVk.h" @@ -26,7 +27,7 @@ class RendererVk : public Renderer { virtual void PrepareRenderFlows() override; virtual void - MakePaintPasses(const std::vector &paintPasses) override; + ProcessPaintPasses(const std::vector &paintPasses) override; virtual void AssignSceneObjectsToRenderFlows() override; virtual void CreateRenderFlowResources() override; @@ -48,6 +49,9 @@ class RendererVk : public Renderer { static ContextVk *s_vulkanContext; static std::vector s_renderFlows; static PcRenderFlowCmdBuffersMap s_renderFlowCmdBuffers; + + // New + std::vector m_paintPassVks; }; GFX_NAMESPACE_END diff --git a/Engine/src/Popcorn/Loaders/GltfLoader.cpp b/Engine/src/Popcorn/Loaders/GltfLoader.cpp index 3d771c8a..47e3f7ea 100644 --- a/Engine/src/Popcorn/Loaders/GltfLoader.cpp +++ b/Engine/src/Popcorn/Loaders/GltfLoader.cpp @@ -394,6 +394,18 @@ void GltfLoader::ExtractMeshData(const tinygltf::Model &model, } }; +static float PC_SrgbToLinear(float c) { + if (c <= 0.04045f) + return c / 12.92f; + else + return pow((c + 0.055f) / 1.055f, 2.4f); +} + +static glm::vec3 PC_SrgbToLinear(glm::vec3 c) { + return glm::vec3(PC_SrgbToLinear(c.r), PC_SrgbToLinear(c.g), + PC_SrgbToLinear(c.b)); +} + // // // @@ -417,9 +429,12 @@ GltfLoader::ExtractMaterialData(const tinygltf::Model &model, if constexpr (T == MaterialTypes::PbrMat) { // Add shader byte code - materialData.baseColorFactor = glm::vec4( - gltfMatData.baseColorFactor[0], gltfMatData.baseColorFactor[1], - gltfMatData.baseColorFactor[2], gltfMatData.baseColorFactor[3]); + // Blender exports baseColorFactor in Srgb space + materialData.baseColorFactor = + glm::vec4(PC_SrgbToLinear(gltfMatData.baseColorFactor[0]), + PC_SrgbToLinear(gltfMatData.baseColorFactor[1]), + PC_SrgbToLinear(gltfMatData.baseColorFactor[2]), + gltfMatData.baseColorFactor[3]); materialData.metallicFactor = gltfMatData.metallicFactor; materialData.roughnessFactor = gltfMatData.roughnessFactor; materialData.hasNormalTexture = material.normalTexture.index != -1; @@ -428,9 +443,11 @@ GltfLoader::ExtractMaterialData(const tinygltf::Model &model, } else { // DEFAULTS TO BASIC MATERIAL // Add shader byte code - materialData.baseColorFactor = glm::vec4( - gltfMatData.baseColorFactor[0], gltfMatData.baseColorFactor[1], - gltfMatData.baseColorFactor[2], gltfMatData.baseColorFactor[3]); + materialData.baseColorFactor = + glm::vec4(PC_SrgbToLinear(gltfMatData.baseColorFactor[0]), + PC_SrgbToLinear(gltfMatData.baseColorFactor[1]), + PC_SrgbToLinear(gltfMatData.baseColorFactor[2]), + gltfMatData.baseColorFactor[3]); } // // Add shader files based on material type diff --git a/Engine/src/Popcorn/Platform/Vulkan/RendererVk.cpp b/Engine/src/Popcorn/Platform/Vulkan/RendererVk.cpp index 9297cf6b..76a958fb 100644 --- a/Engine/src/Popcorn/Platform/Vulkan/RendererVk.cpp +++ b/Engine/src/Popcorn/Platform/Vulkan/RendererVk.cpp @@ -92,10 +92,21 @@ void RendererVk::CreateRenderFlows() { // converted to RenderflowVks with Vulkan memory and vulkan passes) // s_renderFlows.emplace_back(new GBufferRenderFlowVk()); - s_renderFlows.emplace_back(new LightingRenderFlowVk()); - s_renderFlows.emplace_back(new CompositeRenderFlowVk()); + // s_renderFlows.emplace_back(new LightingRenderFlowVk()); + // s_renderFlows.emplace_back(new CompositeRenderFlowVk()); } +void RendererVk::ProcessPaintPasses(const std::vector &paintPasses) { + // Converts PaintPasses to Vulkan CreateInfo objects + // Create Vulkan PaintPasses + for (const PaintPass &paintPass : paintPasses) { + PaintPassVk paintPassVk{paintPass}; + paintPassVk.MakeAttachmentInfos(); + + m_paintPassVks.emplace_back(std::move(paintPassVk)); + } +}; + void RendererVk::DestroyRenderFlows() { vkDeviceWaitIdle(ContextVk::Device()->GetDevice()); @@ -175,7 +186,6 @@ void MakePaintPasses(const std::vector &paintPasses) { // --- Create Vulkan AttachmentInfos from DrawAttachmentInfos -------------- // for (const PaintPass &paintPass : paintPasses) { - PaintPassVk::MakeAttachmentInfos(); } }; diff --git a/Sandbox/02-Street-Scene/paintpasses/paintPassBuilder.h b/Sandbox/02-Street-Scene/paintpasses/paintPassBuilder.h index df88127b..7cf615be 100644 --- a/Sandbox/02-Street-Scene/paintpasses/paintPassBuilder.h +++ b/Sandbox/02-Street-Scene/paintpasses/paintPassBuilder.h @@ -1,17 +1,11 @@ #pragma once -#include namespace Paint { class PaintPassBuilder { public: PaintPassBuilder() = default; void InitPasses() { - - if (Popcorn::Gfx::Renderer::GetAPI() == - Popcorn::Gfx::RendererType::Vulkan) { - }; - // // TODO: Create actual memory for paintpasses (PaintPassVks) // @@ -30,7 +24,7 @@ class PaintPassBuilder { void Build() {} // ShadowPass m_shadow; - // GBufferPass *m_gbuffer; + // GBufferPass m_gbuffer; // LightingPass m_lighting; // TransclucencyPass m_transclucency; // BloomExtractPass m_bloomExtract; From 3f0b9aa6a042085800a15ea508ef2a9140ad44c4 Mon Sep 17 00:00:00 2001 From: __prav__ Date: Sun, 25 Jan 2026 20:08:50 -0500 Subject: [PATCH 32/36] wip: paint passes - complete rehaul --- Engine/include/Popcorn.h | 2 +- .../Graphics/PaintPasses/DataStructures.h | 26 +++ .../Popcorn/Graphics/PaintPasses/PaintPass.h | 16 +- .../Graphics/PaintPasses/PaintPassDefs.h | 26 +-- .../Platform/Vulkan/PaintPasses/PaintPassVk.h | 181 +++++++++--------- .../Popcorn/Platform/Vulkan/RendererVk.cpp | 3 + 6 files changed, 134 insertions(+), 120 deletions(-) create mode 100644 Engine/include/Popcorn/Graphics/PaintPasses/DataStructures.h diff --git a/Engine/include/Popcorn.h b/Engine/include/Popcorn.h index 9dfa4238..5fdc497b 100644 --- a/Engine/include/Popcorn.h +++ b/Engine/include/Popcorn.h @@ -47,7 +47,7 @@ static void StartGame() { // NEW: --- Make your own renderflows --- // // const std::vector paintPasses{}; - // s_renderer->MakePaintPasses(paintPasses); + // s_renderer->ProcessPaintPasses(paintPasses); s_renderer->CreateRenderFlows(); // 1. Each renderflow takes in // a. Attachments (and Info) diff --git a/Engine/include/Popcorn/Graphics/PaintPasses/DataStructures.h b/Engine/include/Popcorn/Graphics/PaintPasses/DataStructures.h new file mode 100644 index 00000000..ace5e697 --- /dev/null +++ b/Engine/include/Popcorn/Graphics/PaintPasses/DataStructures.h @@ -0,0 +1,26 @@ + +#pragma once + +#include "GlobalMacros.h" +#include + +ENGINE_NAMESPACE_BEGIN +GFX_NAMESPACE_BEGIN + +typedef struct { + uint32_t x; + uint32_t y; +} CoordsXY_U32; + +typedef struct { + int32_t x; + int32_t y; +} CoordsXY_I32; + +typedef struct { + float x; + float y; +} CoordsXY_Float; + +GFX_NAMESPACE_END +ENGINE_NAMESPACE_END diff --git a/Engine/include/Popcorn/Graphics/PaintPasses/PaintPass.h b/Engine/include/Popcorn/Graphics/PaintPasses/PaintPass.h index f73f5ce4..d485ad2b 100644 --- a/Engine/include/Popcorn/Graphics/PaintPasses/PaintPass.h +++ b/Engine/include/Popcorn/Graphics/PaintPasses/PaintPass.h @@ -10,27 +10,15 @@ class PaintPassVk; class PaintPass { public: - PaintPass() {}; + PaintPass(const PaintPassInfo &info) : m_info(info) {}; virtual ~PaintPass() {}; - void SetAttachmentInfos( - const DrawAttachmentInfo &colorAttachmentInfo, - const DrawAttachmentInfo - &depthAttachmentInfo) { - m_colorAttachmentInfo = colorAttachmentInfo; - m_depthAttachmentInfo = depthAttachmentInfo; - }; - friend class PaintPassVk; private: - // - // --- Attachments stuff ----------------------------------------------------- - DrawAttachmentInfo m_colorAttachmentInfo{}; - DrawAttachmentInfo m_depthAttachmentInfo{}; - // // --- Paint pass info stuff ------------------------------------------------- + const PaintPassInfo &m_info; }; GFX_NAMESPACE_END diff --git a/Engine/include/Popcorn/Graphics/PaintPasses/PaintPassDefs.h b/Engine/include/Popcorn/Graphics/PaintPasses/PaintPassDefs.h index 4054cef8..c2b5ca7b 100644 --- a/Engine/include/Popcorn/Graphics/PaintPasses/PaintPassDefs.h +++ b/Engine/include/Popcorn/Graphics/PaintPasses/PaintPassDefs.h @@ -1,5 +1,6 @@ #pragma once +#include "DataStructures.h" #include "GlobalMacros.h" #include "Uniforms.h" #include @@ -17,10 +18,10 @@ enum class DrawKind { MaterialGeometry = 0, FullscreenTri }; enum class DrawTargetKind { ColorImage, DepthImage }; enum class ColorFormat : uint8_t { - Low_UNorm8_Linear, // 8-bit UNORM, linear color space (LDR, non-gamma) - Low_UNorm8_SRGB, // 8-bit UNORM, sRGB color space (LDR, gamma-correct) - Medium_Float16, // 16-bit float per channel (HDR, good perf/quality balance) - High_Float32, // 32-bit float per channel (HDR, highest precision) + Low_UNorm8_Linear, // 8-bit UNORM, linear color space (LDR, non-gamma) + Low_UNorm8_SRGB, // 8-bit UNORM, sRGB color space (LDR, gamma-correct) + Medium_Float16_Linear, // 16-bit float per channel (MDR, good perf/quality + // balance) }; enum class DepthFormat : uint8_t { @@ -59,30 +60,17 @@ template struct DrawAttachmentInfo; template <> struct DrawAttachmentInfo { std::vector colorFormats{}; std::vector clearColorValues{}; + std::vector sizes{}; AttachmentFlags attachmentFlags = AttachmentFlags::ColorBit; }; template <> struct DrawAttachmentInfo { DepthFormat depthFormat; ClearDepthStencilValue clearDepthStencilValue; + CoordsXY_U32 size; AttachmentFlags attachmentFlags = AttachmentFlags::DepthBit; }; -typedef struct { - uint32_t x; - uint32_t y; -} CoordsXY_U32; - -typedef struct { - int32_t x; - int32_t y; -} CoordsXY_I32; - -typedef struct { - float x; - float y; -} CoordsXY_Float; - struct PaintArea { CoordsXY_U32 offset{0, 0}; CoordsXY_U32 extent{100, 100}; diff --git a/Engine/include/Popcorn/Platform/Vulkan/PaintPasses/PaintPassVk.h b/Engine/include/Popcorn/Platform/Vulkan/PaintPasses/PaintPassVk.h index 9d3c8d73..ad0e0b77 100644 --- a/Engine/include/Popcorn/Platform/Vulkan/PaintPasses/PaintPassVk.h +++ b/Engine/include/Popcorn/Platform/Vulkan/PaintPasses/PaintPassVk.h @@ -3,34 +3,37 @@ #include "GlobalMacros.h" #include "ImageVk.h" #include "PaintPasses/PaintPass.h" -#include "PaintPasses/PaintPassDefs.h" +#include ENGINE_NAMESPACE_BEGIN GFX_NAMESPACE_BEGIN -enum PaintPassColorFormats { - Low_UNorm8_Linear, - Color_RGBA_HiRes, - Depth_Auto, -}; +// enum PaintPassColorFormats { +// Low_UNorm8_Linear, +// Color_RGBA_HiRes, +// Depth_Auto, +// }; class PaintPassVk { public: - PaintPassVk(const PaintPass &pp) : m_paintPass(pp) {}; + PaintPassVk(const PaintPass &pp) : m_paintPass(pp) {} PaintPassVk(const PaintPassVk &) = delete; PaintPassVk(PaintPassVk &&) = default; void MakeAttachmentInfos() { - m_paintPass.m_colorAttachmentInfo; - m_paintPass.m_depthAttachmentInfo; + // m_paintPass.m_colorAttachmentInfo; + // m_paintPass.m_depthAttachmentInfo; // Create Vk Images - }; + } + + void CreateImageAndView(ImageVk &imageVk, uint32_t attachmentIndex) { + uint32_t width = + m_paintPass.m_info.colorImagesInfo.sizes[attachmentIndex].x; + uint32_t height = + m_paintPass.m_info.colorImagesInfo.sizes[attachmentIndex].y; - template - static void CreateImageAndView(uint32_t width, uint32_t height, - ImageVk &imageVk) { std::vector formatCandidates{}; VkFormat selectedFormat; VkImageCreateInfo imageCreateInfo{}; @@ -39,79 +42,85 @@ class PaintPassVk { VkImageViewCreateInfo imageViewCreateInfo{}; // TODO: Write for paintpass typedefs - if constexpr (T == ColorFormat::Low_UNorm8_Linear) { - // --- Color --- - // Low Res color - formatCandidates = {VK_FORMAT_R8G8B8A8_UNORM, VK_FORMAT_B8G8R8A8_UNORM}; - selectedFormat = ImageVk::FindSupportedFormat( - formatCandidates, VK_IMAGE_TILING_OPTIMAL, - VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT); - - ImageVk::GetDefaultImageCreateInfo(imageCreateInfo, width, height, - selectedFormat); - imageCreateInfo.format = selectedFormat; - imageCreateInfo.usage = - VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT; - - imageVk.CreateVmaImage(imageCreateInfo, imageAlloc); - - // --- Image View --- - ImageVk::GetDefaultImageViewCreateInfo( - imageViewCreateInfo, imageVk.GetVkImage(), selectedFormat); - imageViewCreateInfo.format = selectedFormat; - imageViewCreateInfo.subresourceRange.aspectMask = - VK_IMAGE_ASPECT_COLOR_BIT; - } else if constexpr (T == ColorFormats::Color_RGBA_HiRes) { - // --- Color --- - // High Res color, fallback to low res - formatCandidates = {VK_FORMAT_R16G16B16A16_SFLOAT, - VK_FORMAT_R8G8B8A8_UNORM}; - selectedFormat = ImageVk::FindSupportedFormat( - formatCandidates, VK_IMAGE_TILING_OPTIMAL, - VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT); - - ImageVk::GetDefaultImageCreateInfo(imageCreateInfo, width, height, - selectedFormat); - imageCreateInfo.format = selectedFormat; - imageCreateInfo.usage = - VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT; - - imageVk.CreateVmaImage(imageCreateInfo, imageAlloc); - - // --- Image View --- - ImageVk::GetDefaultImageViewCreateInfo( - imageViewCreateInfo, imageVk.GetVkImage(), selectedFormat); - imageViewCreateInfo.format = selectedFormat; - imageViewCreateInfo.subresourceRange.aspectMask = - VK_IMAGE_ASPECT_COLOR_BIT; - } else { - // --- Depth --- - // High Res depth, fallback to low res - formatCandidates = {VK_FORMAT_D32_SFLOAT, VK_FORMAT_D32_SFLOAT_S8_UINT, - VK_FORMAT_D24_UNORM_S8_UINT}; - selectedFormat = ImageVk::FindSupportedFormat( - formatCandidates, VK_IMAGE_TILING_OPTIMAL, - VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT); - - ImageVk::GetDefaultImageCreateInfo(imageCreateInfo, width, height, - selectedFormat); - imageCreateInfo.format = selectedFormat; - imageCreateInfo.usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | - VK_IMAGE_USAGE_SAMPLED_BIT; - - imageVk.CreateVmaImage(imageCreateInfo, imageAlloc); - - // --- Image View --- - ImageVk::GetDefaultImageViewCreateInfo( - imageViewCreateInfo, imageVk.GetVkImage(), selectedFormat); - imageViewCreateInfo.format = selectedFormat; - imageViewCreateInfo.subresourceRange.aspectMask = - VK_IMAGE_ASPECT_DEPTH_BIT; - if (imageVk.FormatHasStencilComponent()) { - imageViewCreateInfo.subresourceRange.aspectMask |= - VK_IMAGE_ASPECT_STENCIL_BIT; - } - } + // if constexpr (T == ColorFormat::Low_UNorm8_Linear) { + // // --- Color --- + // // Low Res color + // formatCandidates = {VK_FORMAT_R8G8B8A8_UNORM, + // VK_FORMAT_B8G8R8A8_UNORM}; selectedFormat = + // ImageVk::FindSupportedFormat( + // formatCandidates, VK_IMAGE_TILING_OPTIMAL, + // VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT); + // + // ImageVk::GetDefaultImageCreateInfo(imageCreateInfo, width, height, + // selectedFormat); + // imageCreateInfo.format = selectedFormat; + // + // imageCreateInfo.usage = + // VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT; + // + // imageVk.CreateVmaImage(imageCreateInfo, imageAlloc); + // + // // --- Image View --- + // ImageVk::GetDefaultImageViewCreateInfo( + // imageViewCreateInfo, imageVk.GetVkImage(), selectedFormat); + // imageViewCreateInfo.format = selectedFormat; + // imageViewCreateInfo.subresourceRange.aspectMask = + // VK_IMAGE_ASPECT_COLOR_BIT; + // } else if constexpr (T == ColorFormat::Medium_Float16_Linear) { + // // --- Color --- + // // High Res color, fallback to low res + // formatCandidates = {VK_FORMAT_R16G16B16A16_SFLOAT, + // VK_FORMAT_R8G8B8A8_UNORM}; + // selectedFormat = ImageVk::FindSupportedFormat( + // formatCandidates, VK_IMAGE_TILING_OPTIMAL, + // VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT); + // + // ImageVk::GetDefaultImageCreateInfo(imageCreateInfo, width, height, + // selectedFormat); + // imageCreateInfo.format = selectedFormat; + // imageCreateInfo.usage = + // VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT; + // + // imageVk.CreateVmaImage(imageCreateInfo, imageAlloc); + // + // // --- Image View --- + // ImageVk::GetDefaultImageViewCreateInfo( + // imageViewCreateInfo, imageVk.GetVkImage(), selectedFormat); + // imageViewCreateInfo.format = selectedFormat; + // imageViewCreateInfo.subresourceRange.aspectMask = + // VK_IMAGE_ASPECT_COLOR_BIT; + // } + // + // // else { + // // // --- Depth --- + // // // High Res depth, fallback to low res + // // formatCandidates = {VK_FORMAT_D32_SFLOAT, + // VK_FORMAT_D32_SFLOAT_S8_UINT, + // // VK_FORMAT_D24_UNORM_S8_UINT}; + // // selectedFormat = ImageVk::FindSupportedFormat( + // // formatCandidates, VK_IMAGE_TILING_OPTIMAL, + // // VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT); + // // + // // ImageVk::GetDefaultImageCreateInfo(imageCreateInfo, width, height, + // // selectedFormat); + // // imageCreateInfo.format = selectedFormat; + // // imageCreateInfo.usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT + // | + // // VK_IMAGE_USAGE_SAMPLED_BIT; + // // + // // imageVk.CreateVmaImage(imageCreateInfo, imageAlloc); + // // + // // // --- Image View --- + // // ImageVk::GetDefaultImageViewCreateInfo( + // // imageViewCreateInfo, imageVk.GetVkImage(), selectedFormat); + // // imageViewCreateInfo.format = selectedFormat; + // // imageViewCreateInfo.subresourceRange.aspectMask = + // // VK_IMAGE_ASPECT_DEPTH_BIT; + // // if (imageVk.FormatHasStencilComponent()) { + // // imageViewCreateInfo.subresourceRange.aspectMask |= + // // VK_IMAGE_ASPECT_STENCIL_BIT; + // // } + // // } imageVk.CreateImageView(imageViewCreateInfo); }; diff --git a/Engine/src/Popcorn/Platform/Vulkan/RendererVk.cpp b/Engine/src/Popcorn/Platform/Vulkan/RendererVk.cpp index 76a958fb..744b1bad 100644 --- a/Engine/src/Popcorn/Platform/Vulkan/RendererVk.cpp +++ b/Engine/src/Popcorn/Platform/Vulkan/RendererVk.cpp @@ -12,6 +12,7 @@ #include "RenderFlowDefs.h" #include "RenderFlowVk.h" #include "Shader.h" +#include #include #include #include @@ -99,6 +100,8 @@ void RendererVk::CreateRenderFlows() { void RendererVk::ProcessPaintPasses(const std::vector &paintPasses) { // Converts PaintPasses to Vulkan CreateInfo objects // Create Vulkan PaintPasses + // paintPassVk modifies the members of PaintPass to store the created render + // object infos like bufferViews, mem locations etc for (const PaintPass &paintPass : paintPasses) { PaintPassVk paintPassVk{paintPass}; paintPassVk.MakeAttachmentInfos(); From 7aedf30cb7cbbf5bcfbcabcfbebb2cefca029634 Mon Sep 17 00:00:00 2001 From: __prav__ Date: Tue, 27 Jan 2026 12:51:47 -0500 Subject: [PATCH 33/36] wip: paintpasses - memory management - 1 --- .../Graphics/PaintPasses/DataStructures.h | 17 +++++++++++++++++ .../Popcorn/Graphics/PaintPasses/PaintPass.h | 5 ++++- .../Graphics/PaintPasses/PaintPassDefs.h | 12 +++--------- ...aintPassMemorySource.h => PaintPassMemory.h} | 6 +++++- .../Popcorn/Platform/Vulkan/Memory/MemoryVk.h | 3 +++ 5 files changed, 32 insertions(+), 11 deletions(-) rename Engine/include/Popcorn/Graphics/PaintPasses/{PaintPassMemorySource.h => PaintPassMemory.h} (78%) diff --git a/Engine/include/Popcorn/Graphics/PaintPasses/DataStructures.h b/Engine/include/Popcorn/Graphics/PaintPasses/DataStructures.h index ace5e697..e97eda26 100644 --- a/Engine/include/Popcorn/Graphics/PaintPasses/DataStructures.h +++ b/Engine/include/Popcorn/Graphics/PaintPasses/DataStructures.h @@ -2,11 +2,14 @@ #pragma once #include "GlobalMacros.h" +#include #include ENGINE_NAMESPACE_BEGIN GFX_NAMESPACE_BEGIN +// +// --- USEFUL DATA STRUCTURES -------------------------------------------------- typedef struct { uint32_t x; uint32_t y; @@ -22,5 +25,19 @@ typedef struct { float y; } CoordsXY_Float; +// +// --- PAINT PASS SPECIFIC ----------------------------------------------------- +typedef struct { + size_t offset; // buffer view offset (in bytes) + size_t range; // buffer view range (in bytes) + std::byte *accessPtr; +} MemView_Buffer; + +typedef struct { + size_t offset; // buffer view offset (in bytes) + size_t range; // buffer view range (in bytes) + std::byte *accessPtr; +} MemView_Image; + GFX_NAMESPACE_END ENGINE_NAMESPACE_END diff --git a/Engine/include/Popcorn/Graphics/PaintPasses/PaintPass.h b/Engine/include/Popcorn/Graphics/PaintPasses/PaintPass.h index d485ad2b..adef3c13 100644 --- a/Engine/include/Popcorn/Graphics/PaintPasses/PaintPass.h +++ b/Engine/include/Popcorn/Graphics/PaintPasses/PaintPass.h @@ -17,8 +17,11 @@ class PaintPass { private: // - // --- Paint pass info stuff ------------------------------------------------- + // --- CREATION INFO STUFF -------------------------------------------------- const PaintPassInfo &m_info; + + // + // --- MEMORY VIEWS STUFF --------------------------------------------------- }; GFX_NAMESPACE_END diff --git a/Engine/include/Popcorn/Graphics/PaintPasses/PaintPassDefs.h b/Engine/include/Popcorn/Graphics/PaintPasses/PaintPassDefs.h index c2b5ca7b..ba49c486 100644 --- a/Engine/include/Popcorn/Graphics/PaintPasses/PaintPassDefs.h +++ b/Engine/include/Popcorn/Graphics/PaintPasses/PaintPassDefs.h @@ -86,12 +86,6 @@ typedef struct { const char *fragShaderLoc; } ShaderSet; -typedef struct { - size_t offset; // buffer view offset (in bytes) - size_t range; // buffer view range (in bytes) - std::byte *accessPtr; // or some shit like that -} BufferView; - // User copies material info here (Gltf loader does this for the user) struct MaterialInfo { const char *name; @@ -100,7 +94,7 @@ struct MaterialInfo { // store uniform data here std::vector uniformLayout; // copy your uniforms here (from gltf loader) - BufferView bufferView; // view into UBO memory (Vulkan staging buffer?) + MemView_Buffer bufferView; // view into UBO memory (Vulkan staging buffer?) // TODO: Link to submesh memory }; @@ -109,7 +103,7 @@ typedef struct { // store uniform data here std::vector uniformLayout; // copy your uniforms here (from gltf loader) - BufferView bufferView; // view into UBO memory (Vulkan staging buffer?) + MemView_Buffer bufferView; // view into UBO memory (Vulkan staging buffer?) } ScreenspaceInfo; typedef struct { @@ -124,7 +118,7 @@ typedef struct { std::vector indexLayout; std::vector uniformLayout; // copy your uniforms here (from gltf loader) - BufferView bufferView; // view into UBO memory (Vulkan staging buffer?) + MemView_Buffer bufferView; // view into UBO memory (Vulkan staging buffer?) } SubmeshBucket; struct PaintPipelineInfo { diff --git a/Engine/include/Popcorn/Graphics/PaintPasses/PaintPassMemorySource.h b/Engine/include/Popcorn/Graphics/PaintPasses/PaintPassMemory.h similarity index 78% rename from Engine/include/Popcorn/Graphics/PaintPasses/PaintPassMemorySource.h rename to Engine/include/Popcorn/Graphics/PaintPasses/PaintPassMemory.h index b40dfc04..d8a1eefd 100644 --- a/Engine/include/Popcorn/Graphics/PaintPasses/PaintPassMemorySource.h +++ b/Engine/include/Popcorn/Graphics/PaintPasses/PaintPassMemory.h @@ -7,7 +7,7 @@ ENGINE_NAMESPACE_BEGIN GFX_NAMESPACE_BEGIN -class PaintPassMemorySource { +class PaintPassMemory { // Raw data // Deps - Submesh draw order @@ -24,9 +24,13 @@ class PaintPassMemorySource { void GetUboView(uint32_t index) {}; private: + // + // TODO: Organise memory from gameobjects/materials or whatever to store here std::byte *vbos = nullptr; std::byte *ibos = nullptr; std::byte *ubos = nullptr; + + // Images? do i need images? do i? do i???? }; GFX_NAMESPACE_END diff --git a/Engine/include/Popcorn/Platform/Vulkan/Memory/MemoryVk.h b/Engine/include/Popcorn/Platform/Vulkan/Memory/MemoryVk.h index d4b06ded..53454c9d 100644 --- a/Engine/include/Popcorn/Platform/Vulkan/Memory/MemoryVk.h +++ b/Engine/include/Popcorn/Platform/Vulkan/Memory/MemoryVk.h @@ -158,6 +158,9 @@ class MemoryVk { // // Buffer views ----------------------------------------------------------- PcBufferViews m_bufferViews{}; + + // --- NEW ---------------------------------------------------------------- + // --- Pass specific views --- }; GFX_NAMESPACE_END From 0f0a8925dd6064c4e4fd2e8c254267c2301aa3b7 Mon Sep 17 00:00:00 2001 From: __prav__ Date: Tue, 27 Jan 2026 15:13:15 -0500 Subject: [PATCH 34/36] wip: paintpasses - memory stuff - 2 --- .../Graphics/PaintPasses/DataStructures.h | 12 +++- .../Popcorn/Graphics/PaintPasses/PaintPass.h | 32 ++++++++-- .../Graphics/PaintPasses/PaintPassDefs.h | 63 +++++++++++-------- 3 files changed, 73 insertions(+), 34 deletions(-) diff --git a/Engine/include/Popcorn/Graphics/PaintPasses/DataStructures.h b/Engine/include/Popcorn/Graphics/PaintPasses/DataStructures.h index e97eda26..c8f345de 100644 --- a/Engine/include/Popcorn/Graphics/PaintPasses/DataStructures.h +++ b/Engine/include/Popcorn/Graphics/PaintPasses/DataStructures.h @@ -30,13 +30,19 @@ typedef struct { typedef struct { size_t offset; // buffer view offset (in bytes) size_t range; // buffer view range (in bytes) - std::byte *accessPtr; -} MemView_Buffer; + void *accessPtr; +} MemView_Buffer_ReadWrite; typedef struct { size_t offset; // buffer view offset (in bytes) size_t range; // buffer view range (in bytes) - std::byte *accessPtr; + const void *accessPtr; +} MemView_Buffer_ReadOnly; + +typedef struct { + size_t offset; // buffer view offset (in bytes) + size_t range; // buffer view range (in bytes) + void *accessPtr; } MemView_Image; GFX_NAMESPACE_END diff --git a/Engine/include/Popcorn/Graphics/PaintPasses/PaintPass.h b/Engine/include/Popcorn/Graphics/PaintPasses/PaintPass.h index adef3c13..a65e2e86 100644 --- a/Engine/include/Popcorn/Graphics/PaintPasses/PaintPass.h +++ b/Engine/include/Popcorn/Graphics/PaintPasses/PaintPass.h @@ -8,20 +8,44 @@ GFX_NAMESPACE_BEGIN class PaintPassVk; +class PaintPipeline { +public: + PaintPipeline(const PaintPipelineInfo &info, + const SubmeshBucket &submeshBucket) + : m_info(info), m_submeshBucket(submeshBucket) {}; + +private: + const PaintPipelineInfo &m_info; + const SubmeshBucket &m_submeshBucket; // Uses this data + + // + // --- MEMORY VIEWS STUFF --------------------------------------------------- + // + // view into UBO memory + MemView_Buffer_ReadWrite + uboBufferView; // copy your material data here (from helper + // methods, automatically done from GltfLoader) + // TODO: Link to submesh bucket ? +}; + class PaintPass { public: - PaintPass(const PaintPassInfo &info) : m_info(info) {}; + PaintPass(const PaintPassInfo &info) + : m_info(info) { + // TODO: Error out when paintkind is material geometry and the + // submeshes aren't provided + }; virtual ~PaintPass() {}; + PaintPass(const PaintPass &) = delete; + PaintPass(PaintPass &&) = default; + friend class PaintPassVk; private: // // --- CREATION INFO STUFF -------------------------------------------------- const PaintPassInfo &m_info; - - // - // --- MEMORY VIEWS STUFF --------------------------------------------------- }; GFX_NAMESPACE_END diff --git a/Engine/include/Popcorn/Graphics/PaintPasses/PaintPassDefs.h b/Engine/include/Popcorn/Graphics/PaintPasses/PaintPassDefs.h index ba49c486..7df79c3a 100644 --- a/Engine/include/Popcorn/Graphics/PaintPasses/PaintPassDefs.h +++ b/Engine/include/Popcorn/Graphics/PaintPasses/PaintPassDefs.h @@ -14,8 +14,18 @@ GFX_NAMESPACE_BEGIN // Attachments stuff ------------------------------------------------------ // Attachments stuff ------------------------------------------------------ // Attachments stuff ------------------------------------------------------ -enum class DrawKind { MaterialGeometry = 0, FullscreenTri }; -enum class DrawTargetKind { ColorImage, DepthImage }; +enum class PaintPipelineKind { + None = 0, + PaintMaterialGeometry, // Shades all the geometry made of one kind of a + // material -- ONLY one specific kinda material. All + // the geometry (submeshes) are arranged in a + // contiguous memory "bucket" known as submesh buckets. + // PaintPipeline of this kind needs a ref to the + // submesh bucket + PaintTriangle // Shades ONE fullscreen triangle -- +}; + +enum class PaintImageKind { None = 0, ColorImage, DepthImage }; enum class ColorFormat : uint8_t { Low_UNorm8_Linear, // 8-bit UNORM, linear color space (LDR, non-gamma) @@ -55,16 +65,16 @@ enum class AttachmentFlags : uint32_t { DepthStencilBit, }; -template struct DrawAttachmentInfo; +template struct DrawAttachmentInfo; -template <> struct DrawAttachmentInfo { +template <> struct DrawAttachmentInfo { std::vector colorFormats{}; std::vector clearColorValues{}; std::vector sizes{}; AttachmentFlags attachmentFlags = AttachmentFlags::ColorBit; }; -template <> struct DrawAttachmentInfo { +template <> struct DrawAttachmentInfo { DepthFormat depthFormat; ClearDepthStencilValue clearDepthStencilValue; CoordsXY_U32 size; @@ -86,42 +96,44 @@ typedef struct { const char *fragShaderLoc; } ShaderSet; -// User copies material info here (Gltf loader does this for the user) -struct MaterialInfo { - const char *name; - uint32_t materialId; - ShaderSet shaderSet; - // store uniform data here - std::vector uniformLayout; - // copy your uniforms here (from gltf loader) - MemView_Buffer bufferView; // view into UBO memory (Vulkan staging buffer?) - // TODO: Link to submesh memory -}; - typedef struct { - const char *name; // store uniform data here std::vector uniformLayout; // copy your uniforms here (from gltf loader) - MemView_Buffer bufferView; // view into UBO memory (Vulkan staging buffer?) + MemView_Buffer_ReadWrite + bufferView; // view into UBO memory (Vulkan staging buffer?) } ScreenspaceInfo; typedef struct { // From Vulkan defs } SamplerInfo; -// Collect all submeshes of a certain "type" (maybe like +// User copies material info here (Gltf loader does this for the user) +struct MaterialInfo { + ShaderSet shaderSet; + std::vector uniformLayout; +}; + typedef struct { // TODO: Write a vertex version std::vector vertexLayout; + MemView_Buffer_ReadOnly vboBucketView; // TODO: Write a index version std::vector indexLayout; - std::vector uniformLayout; + MemView_Buffer_ReadOnly iboBucketView; + // copy your uniforms here (from gltf loader) - MemView_Buffer bufferView; // view into UBO memory (Vulkan staging buffer?) + std::vector uniformLayout; + MemView_Buffer_ReadWrite + uboBucketView; // View into UBO memory - contains all the submesh data + // that needs to be sent as UBOs - for example things like + // transform matrices, world positions etc } SubmeshBucket; struct PaintPipelineInfo { + // Draw kind + PaintPipelineKind paintPipelineKind; + // Make one for SSBOs too SamplerInfo samplerInfo; @@ -154,13 +166,10 @@ struct PaintPipelineInfo { // Only for raster pipelines struct PaintPassInfo { // Render info - DrawAttachmentInfo colorImagesInfo; - DrawAttachmentInfo depthImageInfo; + DrawAttachmentInfo colorImagesInfo; + DrawAttachmentInfo depthImageInfo; PaintArea paintArea; - // Draw kind - DrawKind drawKind; - const PaintPipelineInfo *paintPipelineInfos; }; From 982ae78ab6d09a5157a5a01c9c565d9603e9fb9a Mon Sep 17 00:00:00 2001 From: __prav__ Date: Tue, 27 Jan 2026 21:20:39 -0500 Subject: [PATCH 35/36] wip: paintpasses - implementation --- .../Graphics/PaintPasses/DataStructures.h | 29 ++++++++++-------- .../Popcorn/Graphics/PaintPasses/PaintPass.h | 12 ++++---- .../Graphics/PaintPasses/PaintPassDefs.h | 30 ++++++++----------- .../Vulkan/Descriptors/DescriptorLayoutsVk.h | 25 +++++++++------- .../RenderFlows/GBufferRenderFlowVk.cpp | 16 +++++----- .../RenderFlows/LightingRenderFlowVk.cpp | 4 ++- 6 files changed, 59 insertions(+), 57 deletions(-) diff --git a/Engine/include/Popcorn/Graphics/PaintPasses/DataStructures.h b/Engine/include/Popcorn/Graphics/PaintPasses/DataStructures.h index c8f345de..2a6f9ff5 100644 --- a/Engine/include/Popcorn/Graphics/PaintPasses/DataStructures.h +++ b/Engine/include/Popcorn/Graphics/PaintPasses/DataStructures.h @@ -27,22 +27,25 @@ typedef struct { // // --- PAINT PASS SPECIFIC ----------------------------------------------------- +typedef enum { + MEM_ACCESS_READ, + MEM_ACCESS_WRITE, + MEM_ACCESS_READ_WRITE +} MemAccess; + +// A window into the buffer memory that shaders have access to. This memory +// lives in the CPU, and will be copied to the GPU later as required typedef struct { - size_t offset; // buffer view offset (in bytes) - size_t range; // buffer view range (in bytes) - void *accessPtr; -} MemView_Buffer_ReadWrite; + uint64_t stride; // buffer stride (in bytes) + uint64_t offset; // buffer view offset (in bytes) + uint64_t range; // buffer view range (in bytes) + MemAccess access; +} BufferView; typedef struct { - size_t offset; // buffer view offset (in bytes) - size_t range; // buffer view range (in bytes) - const void *accessPtr; -} MemView_Buffer_ReadOnly; - -typedef struct { - size_t offset; // buffer view offset (in bytes) - size_t range; // buffer view range (in bytes) - void *accessPtr; + uint64_t offset; // buffer view offset (in bytes) + uint64_t range; // buffer view range (in bytes) + MemAccess access; } MemView_Image; GFX_NAMESPACE_END diff --git a/Engine/include/Popcorn/Graphics/PaintPasses/PaintPass.h b/Engine/include/Popcorn/Graphics/PaintPasses/PaintPass.h index a65e2e86..bd4ae78d 100644 --- a/Engine/include/Popcorn/Graphics/PaintPasses/PaintPass.h +++ b/Engine/include/Popcorn/Graphics/PaintPasses/PaintPass.h @@ -11,21 +11,19 @@ class PaintPassVk; class PaintPipeline { public: PaintPipeline(const PaintPipelineInfo &info, - const SubmeshBucket &submeshBucket) - : m_info(info), m_submeshBucket(submeshBucket) {}; + const SubmeshBuffersBucket &submeshBuffersBucket) + : m_info(info), m_submeshBuffersBucket(submeshBuffersBucket) {} private: const PaintPipelineInfo &m_info; - const SubmeshBucket &m_submeshBucket; // Uses this data + const SubmeshBuffersBucket &m_submeshBuffersBucket; // Uses this data // // --- MEMORY VIEWS STUFF --------------------------------------------------- // // view into UBO memory - MemView_Buffer_ReadWrite - uboBufferView; // copy your material data here (from helper - // methods, automatically done from GltfLoader) - // TODO: Link to submesh bucket ? + BufferView uboBufferView; // copy your material data here (from helper + // methods, automatically done from GltfLoader) }; class PaintPass { diff --git a/Engine/include/Popcorn/Graphics/PaintPasses/PaintPassDefs.h b/Engine/include/Popcorn/Graphics/PaintPasses/PaintPassDefs.h index 7df79c3a..2659b376 100644 --- a/Engine/include/Popcorn/Graphics/PaintPasses/PaintPassDefs.h +++ b/Engine/include/Popcorn/Graphics/PaintPasses/PaintPassDefs.h @@ -65,16 +65,16 @@ enum class AttachmentFlags : uint32_t { DepthStencilBit, }; -template struct DrawAttachmentInfo; +template struct PaintAttachmentInfo; -template <> struct DrawAttachmentInfo { +template <> struct PaintAttachmentInfo { std::vector colorFormats{}; std::vector clearColorValues{}; std::vector sizes{}; AttachmentFlags attachmentFlags = AttachmentFlags::ColorBit; }; -template <> struct DrawAttachmentInfo { +template <> struct PaintAttachmentInfo { DepthFormat depthFormat; ClearDepthStencilValue clearDepthStencilValue; CoordsXY_U32 size; @@ -86,11 +86,6 @@ struct PaintArea { CoordsXY_U32 extent{100, 100}; }; -enum class PaintPassFlags : uint32_t { - None = 0, - // Raster behaviour -}; - typedef struct { const char *vertShaderLoc; const char *fragShaderLoc; @@ -100,8 +95,7 @@ typedef struct { // store uniform data here std::vector uniformLayout; // copy your uniforms here (from gltf loader) - MemView_Buffer_ReadWrite - bufferView; // view into UBO memory (Vulkan staging buffer?) + BufferView bufferView; // view into UBO memory (Vulkan staging buffer?) } ScreenspaceInfo; typedef struct { @@ -110,6 +104,7 @@ typedef struct { // User copies material info here (Gltf loader does this for the user) struct MaterialInfo { + uint64_t batchId; ShaderSet shaderSet; std::vector uniformLayout; }; @@ -117,18 +112,18 @@ struct MaterialInfo { typedef struct { // TODO: Write a vertex version std::vector vertexLayout; - MemView_Buffer_ReadOnly vboBucketView; + BufferView vboBucketView; // TODO: Write a index version std::vector indexLayout; - MemView_Buffer_ReadOnly iboBucketView; + BufferView iboBucketView; // copy your uniforms here (from gltf loader) std::vector uniformLayout; - MemView_Buffer_ReadWrite + BufferView uboBucketView; // View into UBO memory - contains all the submesh data // that needs to be sent as UBOs - for example things like // transform matrices, world positions etc -} SubmeshBucket; +} SubmeshBuffersBucket; struct PaintPipelineInfo { // Draw kind @@ -138,8 +133,7 @@ struct PaintPipelineInfo { SamplerInfo samplerInfo; // Material info - For Material DrawKind - MaterialInfo materialInfo; // Material UBO (Layout + BufferView) - SubmeshBucket submeshBucket; // Submesh VBO, IBO, UBO (Layout + BufferViews) + MaterialInfo materialInfo; // Material UBO (Layout + BufferView) // Screenspace info - For FullscreenTri DrawKind ScreenspaceInfo screenspaceInfo; // Screenspace UBO (Layout + BufferView) @@ -166,8 +160,8 @@ struct PaintPipelineInfo { // Only for raster pipelines struct PaintPassInfo { // Render info - DrawAttachmentInfo colorImagesInfo; - DrawAttachmentInfo depthImageInfo; + PaintAttachmentInfo colorImagesInfo; + PaintAttachmentInfo depthImageInfo; PaintArea paintArea; const PaintPipelineInfo *paintPipelineInfos; diff --git a/Engine/include/Popcorn/Platform/Vulkan/Descriptors/DescriptorLayoutsVk.h b/Engine/include/Popcorn/Platform/Vulkan/Descriptors/DescriptorLayoutsVk.h index 9d28edc2..246eb008 100644 --- a/Engine/include/Popcorn/Platform/Vulkan/Descriptors/DescriptorLayoutsVk.h +++ b/Engine/include/Popcorn/Platform/Vulkan/Descriptors/DescriptorLayoutsVk.h @@ -39,21 +39,26 @@ class DescriptorLayoutsVk { [[nodiscard]] static VkDeviceSize GetDescriptorBufferRange(const VkPhysicalDeviceLimits &limits) { if constexpr (T == DescriptorSets::CameraSet) { - return PC_AlignCeil(UniformDefs::CameraUniform::size, - limits.minUniformBufferOffsetAlignment); + return UniformDefs::CameraUniform::size; + // return PC_AlignCeil(UniformDefs::CameraUniform::size, + // limits.minUniformBufferOffsetAlignment); } else if constexpr (T == DescriptorSets::BasicMatSet) { - return PC_AlignCeil(UniformDefs::BasicMaterialUniform::size, - limits.minUniformBufferOffsetAlignment); + return UniformDefs::BasicMaterialUniform::size; + // return PC_AlignCeil(UniformDefs::BasicMaterialUniform::size, + // limits.minUniformBufferOffsetAlignment); } else if constexpr (T == DescriptorSets::PbrMatSet) { - return PC_AlignCeil(UniformDefs::PbrMaterialUniform::size, - limits.minUniformBufferOffsetAlignment); + return UniformDefs::PbrMaterialUniform::size; + // return PC_AlignCeil(UniformDefs::PbrMaterialUniform::size, + // limits.minUniformBufferOffsetAlignment); } else if constexpr (T == DescriptorSets::SubmeshSet) { - return PC_AlignCeil(UniformDefs::SubmeshUniform::size, - limits.minUniformBufferOffsetAlignment); + return UniformDefs::SubmeshUniform::size; + // return PC_AlignCeil(UniformDefs::SubmeshUniform::size, + // limits.minUniformBufferOffsetAlignment); } else if constexpr (T == DescriptorSets::PresentSet) { } else if constexpr (T == DescriptorSets::LightingSet) { - return PC_AlignCeil(UniformDefs::LightUniform::size, - limits.minStorageBufferOffsetAlignment); + return UniformDefs::LightUniform::size; + // return PC_AlignCeil(UniformDefs::LightUniform::size, + // limits.minStorageBufferOffsetAlignment); }; }; diff --git a/Engine/src/Popcorn/Platform/Vulkan/RenderFlows/GBufferRenderFlowVk.cpp b/Engine/src/Popcorn/Platform/Vulkan/RenderFlows/GBufferRenderFlowVk.cpp index f9cd2c97..c1f6a29b 100644 --- a/Engine/src/Popcorn/Platform/Vulkan/RenderFlows/GBufferRenderFlowVk.cpp +++ b/Engine/src/Popcorn/Platform/Vulkan/RenderFlows/GBufferRenderFlowVk.cpp @@ -17,6 +17,7 @@ #include "Popcorn/Loaders/LoadersDefs.h" #include "RFlowResourcesVk.h" #include "RenderPassVk.h" +#include "Uniforms.h" #include #include #include @@ -533,18 +534,17 @@ void GBufferRenderFlowVk::UpdateDescriptorSetsLocal() { VkDescriptorBufferInfo submeshBufferInfo{}; submeshBufferInfo.buffer = memory->GetUboSet(i); submeshBufferInfo.offset = memory->GetBufferViews().submeshUbo.offset; - submeshBufferInfo.range = - // memory->GetBufferViews().submeshUbo.alignedSize; - DescriptorLayoutsVk::GetDescriptorBufferRange< - DescriptorSets::SubmeshSet>(properties.limits); + submeshBufferInfo.range = UniformDefs::SubmeshUniform::size; + // memory->GetBufferViews().submeshUbo.alignedSize; + // DescriptorLayoutsVk::GetDescriptorBufferRange< + // DescriptorSets::SubmeshSet>(properties.limits); VkDescriptorBufferInfo basicMatBufferInfo{}; basicMatBufferInfo.buffer = memory->GetUboSet(i); basicMatBufferInfo.offset = memory->GetBufferViews().basicMatUbo.offset; - basicMatBufferInfo.range = - // memory->GetBufferViews().basicMatUbo.alignedSize; - DescriptorLayoutsVk::GetDescriptorBufferRange< - DescriptorSets::BasicMatSet>(properties.limits); + basicMatBufferInfo.range = DescriptorLayoutsVk::GetDescriptorBufferRange< + DescriptorSets::BasicMatSet>(properties.limits); + // memory->GetBufferViews().basicMatUbo.alignedSize; VkDescriptorBufferInfo pbrMatBufferInfo{}; pbrMatBufferInfo.buffer = memory->GetUboSet(i); diff --git a/Engine/src/Popcorn/Platform/Vulkan/RenderFlows/LightingRenderFlowVk.cpp b/Engine/src/Popcorn/Platform/Vulkan/RenderFlows/LightingRenderFlowVk.cpp index 003c79c8..b49326c8 100644 --- a/Engine/src/Popcorn/Platform/Vulkan/RenderFlows/LightingRenderFlowVk.cpp +++ b/Engine/src/Popcorn/Platform/Vulkan/RenderFlows/LightingRenderFlowVk.cpp @@ -236,7 +236,9 @@ void LightingRenderFlowVk::UpdateDescriptorSetsLocal() { VkDescriptorBufferInfo lightBufferInfo{}; lightBufferInfo.buffer = memory->GetSsboSet(i); lightBufferInfo.offset = memory->GetBufferViews().lightsSsbo.offset; - lightBufferInfo.range = memory->GetBufferViews().lightsSsbo.alignedSize; + lightBufferInfo.range = + // let shader access full buffer + memory->GetBufferViews().lightsSsbo.alignedSize; // DescriptorLayoutsVk::GetDescriptorBufferRange< // DescriptorSets::LightingSet>(properties.limits); From 15c32817d8ac75c548c9ceea1c8f7afe00175bb4 Mon Sep 17 00:00:00 2001 From: __prav__ Date: Sun, 8 Feb 2026 20:51:45 -0500 Subject: [PATCH 36/36] feat: paintpass implementation -- day 1 --- Engine/include/Api.h | 43 --------- Engine/include/Popcorn.h | 16 ---- Engine/include/Popcorn/Core/Layer.h | 3 + Engine/include/Popcorn/Core/LayerStack.h | 10 +- .../Graphics/PaintPasses/DataStructures.h | 2 - .../Popcorn/Graphics/PaintPasses/PaintPass.h | 22 ++++- .../Graphics/PaintPasses/PaintPassDefs.h | 51 ++++++----- Engine/include/Popcorn/Graphics/Shader.h | 4 +- Engine/include/Popcorn/Scene/SceneLibrary.h | 18 ++++ Engine/include/Popcorn2.h | 91 +++++++++++++++++++ Engine/src/CMakeLists.txt | 2 + Engine/src/Popcorn.cpp | 9 ++ Engine/src/Popcorn/Core/LayerStack.cpp | 26 +++--- Sandbox/02-Street-Scene/main-paintpasses.cpp | 4 + tasks/daily.txt | 1 + 15 files changed, 195 insertions(+), 107 deletions(-) delete mode 100644 Engine/include/Api.h create mode 100644 Engine/include/Popcorn2.h create mode 100644 Engine/src/Popcorn.cpp diff --git a/Engine/include/Api.h b/Engine/include/Api.h deleted file mode 100644 index 69d9b534..00000000 --- a/Engine/include/Api.h +++ /dev/null @@ -1,43 +0,0 @@ -#pragma once - -#include "BufferObjects.h" -#include "GlobalMacros.h" -#include - -ENGINE_NAMESPACE_BEGIN -GFX_NAMESPACE_BEGIN - - - -// -// Scene data ------------------------------------------------------------- -// Scene data ------------------------------------------------------------- -// Scene data ------------------------------------------------------------- -// typedef struct { -// BufferDefs::Layout vboLayout; -// VertexBuffer *vbo; -// IndexBuffer *ibo; -// } GeometryData; - -typedef struct { - uint32_t sceneId; -} SceneData; - -// -// Renderflow info stuff -------------------------------------------------- -// Renderflow info stuff -------------------------------------------------- -// Renderflow info stuff -------------------------------------------------- -typedef struct { -} DrawData; - -// -// Pipelines stuff -------------------------------------------------------- -// Pipelines stuff -------------------------------------------------------- -// Pipelines stuff -------------------------------------------------------- -typedef struct { - uint16_t col; - uint16_t row; -} GfxPipeline; - -GFX_NAMESPACE_END -ENGINE_NAMESPACE_END diff --git a/Engine/include/Popcorn.h b/Engine/include/Popcorn.h index 5fdc497b..64235ec7 100644 --- a/Engine/include/Popcorn.h +++ b/Engine/include/Popcorn.h @@ -138,18 +138,6 @@ static void EndContext() { // return *s_application; // }; -static void FillNamedLookUpMap(Scene &scene, GameObject *node) { - if (node == nullptr) { - PC_WARN("node is nullptr") - return; - } - scene.AddGameObjectToNamedLookUp(node->GetName(), node); - - for (GameObject *child : node->GetChildren()) { - FillNamedLookUpMap(scene, child); - } -} - static void ConvertGltfToScene(const std::string &filename, Scene &scene) { tinygltf::Model model; GltfLoader::LoadFromFile(filename, model); @@ -162,10 +150,6 @@ static void ConvertGltfToScene(const std::string &filename, Scene &scene) { scene.SetAnimationTracks(animationTracks); PC_WARN("ANIMATION TRACK SIZE AFTER: " << animationTracks.size()) - - for (GameObject *gameObj : scene.GetGameObjects()) { - FillNamedLookUpMap(scene, gameObj); - } }; CTX_NAMESPACE_END diff --git a/Engine/include/Popcorn/Core/Layer.h b/Engine/include/Popcorn/Core/Layer.h index dce6ba10..66a2cc8b 100644 --- a/Engine/include/Popcorn/Core/Layer.h +++ b/Engine/include/Popcorn/Core/Layer.h @@ -9,6 +9,9 @@ class Layer { public: virtual ~Layer() = default; + Layer(const Layer &) = delete; + Layer &operator=(const Layer &) = delete; + virtual void OnAttach(); virtual void OnDetach(); diff --git a/Engine/include/Popcorn/Core/LayerStack.h b/Engine/include/Popcorn/Core/LayerStack.h index 3ee0e9e2..185d3197 100644 --- a/Engine/include/Popcorn/Core/LayerStack.h +++ b/Engine/include/Popcorn/Core/LayerStack.h @@ -26,27 +26,27 @@ class LayerStack { // cb(it); // } - for (auto it = m_layer_stack.rbegin(); it != m_layer_stack.rend(); ++it) { + for (auto it = m_layerStack.rbegin(); it != m_layerStack.rend(); ++it) { cb(it); } }; // TODO: Refactor when dealing with time void UpdateLayers(TimeEvent &e) { - for (Layer *l : m_layer_stack) { + for (Layer *l : m_layerStack) { l->OnUpdate(e); } }; void RenderLayers() { - for (Layer *l : m_layer_stack) { + for (Layer *l : m_layerStack) { l->OnRender(); } }; private: - std::vector m_layer_stack; - uint32_t m_separator_index = 0; + std::vector m_layerStack; + uint32_t m_separatorIndex = 0; }; ENGINE_NAMESPACE_END diff --git a/Engine/include/Popcorn/Graphics/PaintPasses/DataStructures.h b/Engine/include/Popcorn/Graphics/PaintPasses/DataStructures.h index 2a6f9ff5..7d3450d7 100644 --- a/Engine/include/Popcorn/Graphics/PaintPasses/DataStructures.h +++ b/Engine/include/Popcorn/Graphics/PaintPasses/DataStructures.h @@ -1,8 +1,6 @@ - #pragma once #include "GlobalMacros.h" -#include #include ENGINE_NAMESPACE_BEGIN diff --git a/Engine/include/Popcorn/Graphics/PaintPasses/PaintPass.h b/Engine/include/Popcorn/Graphics/PaintPasses/PaintPass.h index bd4ae78d..8838e86c 100644 --- a/Engine/include/Popcorn/Graphics/PaintPasses/PaintPass.h +++ b/Engine/include/Popcorn/Graphics/PaintPasses/PaintPass.h @@ -8,27 +8,33 @@ GFX_NAMESPACE_BEGIN class PaintPassVk; +// Every paint pipeline in a paint pass will have it's own shaders class PaintPipeline { public: PaintPipeline(const PaintPipelineInfo &info, const SubmeshBuffersBucket &submeshBuffersBucket) : m_info(info), m_submeshBuffersBucket(submeshBuffersBucket) {} + PaintPipeline(const PaintPipeline &) = delete; + PaintPipeline(PaintPipeline &&) = default; + private: const PaintPipelineInfo &m_info; - const SubmeshBuffersBucket &m_submeshBuffersBucket; // Uses this data // // --- MEMORY VIEWS STUFF --------------------------------------------------- // // view into UBO memory + const SubmeshBuffersBucket &m_submeshBuffersBucket; // Uses this data BufferView uboBufferView; // copy your material data here (from helper // methods, automatically done from GltfLoader) }; class PaintPass { public: - PaintPass(const PaintPassInfo &info) + PaintPass( + // PaintPass creation info + const PaintPassInfo &info) : m_info(info) { // TODO: Error out when paintkind is material geometry and the // submeshes aren't provided @@ -44,6 +50,18 @@ class PaintPass { // // --- CREATION INFO STUFF -------------------------------------------------- const PaintPassInfo &m_info; + + // + // --- PAINT PIPELINES ------------------------------------------------------ + std::vector m_paintPipelines; + + // + // Extract data from GLTFs - + // + // Submesh buckets + // VBO + IBO data here, beginning of every paintpass - these will be bound + // what about UBOs? + // Submesh UBOs can be drilled to PaintPipeline }; GFX_NAMESPACE_END diff --git a/Engine/include/Popcorn/Graphics/PaintPasses/PaintPassDefs.h b/Engine/include/Popcorn/Graphics/PaintPasses/PaintPassDefs.h index 2659b376..7b77f3a5 100644 --- a/Engine/include/Popcorn/Graphics/PaintPasses/PaintPassDefs.h +++ b/Engine/include/Popcorn/Graphics/PaintPasses/PaintPassDefs.h @@ -16,13 +16,12 @@ GFX_NAMESPACE_BEGIN // Attachments stuff ------------------------------------------------------ enum class PaintPipelineKind { None = 0, - PaintMaterialGeometry, // Shades all the geometry made of one kind of a - // material -- ONLY one specific kinda material. All - // the geometry (submeshes) are arranged in a - // contiguous memory "bucket" known as submesh buckets. - // PaintPipeline of this kind needs a ref to the - // submesh bucket - PaintTriangle // Shades ONE fullscreen triangle -- + Material, // Shades all the geometry made of one kind of a material -- ONLY + // one specific kinda material. All the geometry (submeshes) are + // arranged in a contiguous memory "bucket" known as submesh + // buckets. PaintPipeline of this kind needs a ref to the submesh + // bucket + BigTriangle // Shades ONE fullscreen triangle -- }; enum class PaintImageKind { None = 0, ColorImage, DepthImage }; @@ -89,26 +88,12 @@ struct PaintArea { typedef struct { const char *vertShaderLoc; const char *fragShaderLoc; -} ShaderSet; - -typedef struct { - // store uniform data here - std::vector uniformLayout; - // copy your uniforms here (from gltf loader) - BufferView bufferView; // view into UBO memory (Vulkan staging buffer?) -} ScreenspaceInfo; +} ShadersLoc; typedef struct { // From Vulkan defs } SamplerInfo; -// User copies material info here (Gltf loader does this for the user) -struct MaterialInfo { - uint64_t batchId; - ShaderSet shaderSet; - std::vector uniformLayout; -}; - typedef struct { // TODO: Write a vertex version std::vector vertexLayout; @@ -125,6 +110,21 @@ typedef struct { // transform matrices, world positions etc } SubmeshBuffersBucket; +// User copies material info here (Gltf loader does this for the user) +struct MaterialInfo { + uint64_t batchId; + // Shader info + ShadersLoc shaderFiles; + std::vector uniformLayout; +}; + +typedef struct { + // store uniform data here + std::vector uniformLayout; + // copy your uniforms here (from gltf loader) + BufferView bufferView; // view into UBO memory (Vulkan staging buffer?) +} ScreenspaceInfo; + struct PaintPipelineInfo { // Draw kind PaintPipelineKind paintPipelineKind; @@ -159,12 +159,15 @@ struct PaintPipelineInfo { // Only for raster pipelines struct PaintPassInfo { - // Render info + // Attachments info PaintAttachmentInfo colorImagesInfo; PaintAttachmentInfo depthImageInfo; + + // Render info PaintArea paintArea; - const PaintPipelineInfo *paintPipelineInfos; + // Paint pipelines + const std::vector paintPipelineInfos; }; // diff --git a/Engine/include/Popcorn/Graphics/Shader.h b/Engine/include/Popcorn/Graphics/Shader.h index 48f7da7f..02062342 100644 --- a/Engine/include/Popcorn/Graphics/Shader.h +++ b/Engine/include/Popcorn/Graphics/Shader.h @@ -83,7 +83,7 @@ class ShaderLibrary { template void LoadShaders(); template void UnloadShaders(); - template Buffer &GetShader() { + template Buffer &GetShader() { switch (R) { case RendererType::Vulkan: { auto it = s_shaders.find(T); @@ -117,7 +117,7 @@ class ShaderLibrary { private: bool m_shadersLoaded = false; static ShaderLibrary *s_instance; - static std::map s_shaders; + static std::map s_shaders; }; GFX_NAMESPACE_END diff --git a/Engine/include/Popcorn/Scene/SceneLibrary.h b/Engine/include/Popcorn/Scene/SceneLibrary.h index a78ecb8d..d93c658f 100644 --- a/Engine/include/Popcorn/Scene/SceneLibrary.h +++ b/Engine/include/Popcorn/Scene/SceneLibrary.h @@ -23,10 +23,28 @@ class SceneLibrary { return m_scenes; } + static void FillNamedLookUpMap(Scene *scene, GameObject *node) { + if (node == nullptr) { + PC_WARN("node is nullptr") + return; + } + scene->AddGameObjectToNamedLookUp(node->GetName(), node); + + for (GameObject *child : node->GetChildren()) { + FillNamedLookUpMap(scene, child); + } + } + void Add(Scene *scene) { auto it = std::find(m_scenes.begin(), m_scenes.end(), scene); if (it == m_scenes.end()) { m_scenes.emplace_back(scene); + + // Populates a named lookUp map for fast game object access in the scene + for (GameObject *gameObj : scene->GetGameObjects()) { + FillNamedLookUpMap(scene, gameObj); + } + PC_PRINT("Scene added to library", TagType::Print, "SceneLibrary") } else { PC_WARN("Scene not added, it already exists in sceneLibrary") diff --git a/Engine/include/Popcorn2.h b/Engine/include/Popcorn2.h new file mode 100644 index 00000000..427200f2 --- /dev/null +++ b/Engine/include/Popcorn2.h @@ -0,0 +1,91 @@ + +#pragma once + +#include "Animation.h" +#include "Application.h" +#include "Assert.h" +#include "ContextGfx.h" +#include "GameObject.h" +#include "GlobalMacros.h" +#include "GltfLoader.h" +#include "Layer.h" +#include "Scene.h" +#include "SplineFactory.h" +#include +#include + +ENGINE_NAMESPACE_BEGIN +CTX_NAMESPACE_BEGIN + +static Application *s_application = nullptr; +static Renderer *s_renderer = nullptr; + +using Model = tinygltf::Model; + +// +// --- CORE METHODS (INIT PHASE) ----------------------------------------------- +static void BeginContext(); +static void EndContext(); +static void AddLayer(Layer *); + +// --- GAME SCENE UTILS -------------------------------------------------------- +static void RegisterScene(Scene &scene); +static void UnregisterScene(Scene &scene); + +// --- GLTF TO SCENE UTILS ----------------------------------------------------- +static void ExtractScenesFromGltfFile(const std::string &gltfFile); +// -- Extract scene data -- +// +// -- GameObject data -- +// - cameras, +// - lights, +// - static meshes, +// - skinned meshes, +// - static meshes (animatable), +// - terrain chunked meshes +// +// Make CPU structured buffers for related Uniform/SSBO data for each game +// object type, and rules around it (for dynamic data) +// Let users define the Layouts for these buffers +// +// -- Material Data -- +// - Opaque +// - Masked +// - Transclucent +// - Unlit +// - Emissive +// - ClearCoat +// - Subsurface (skin/wax) SONY HEHEHEHE +// - Additive (aura fx) +// - Volumetric (God rays, fog shapes) +// +// Make CPU structured buffers for related Uniform/SSBO data for each material +// type, and rules around it (for dynamic data) Let users define the Layouts +// for these buffers +// +// -- ScreenSpace Data -- (NON GLTF!) JUST FYI +// - Unlit +// - SSAO +// - SSR +// - SSGI +// - Screen-space shadows +// - Motion vectors +// - TAA history +// - Depth-based fog +// - Bloom thresholds +// - Exposure / tonemapping +// - Vignette +// - Film grain +// - Color grading LUTs + +// --- FOR CUSTOM ANIMATIONS --------------------------------------------------- +static SplineFactory *GetSplineFactory(); +static CurveFactory *GetCurveFactory(); + +// +// --- GAME METHODS ------------------------------------------------------------ +static void StartGame(); +static void PaintFrame(); + +CTX_NAMESPACE_END +ENGINE_NAMESPACE_END diff --git a/Engine/src/CMakeLists.txt b/Engine/src/CMakeLists.txt index fc1357c8..e5200136 100644 --- a/Engine/src/CMakeLists.txt +++ b/Engine/src/CMakeLists.txt @@ -10,6 +10,8 @@ set(SCENE_IMPL_DIR Popcorn/Scene) add_library( Popcorn # + Popcorn.cpp + # # CORE ${CORE_IMPL_DIR}/Application.cpp ${CORE_IMPL_DIR}/Externs.cpp diff --git a/Engine/src/Popcorn.cpp b/Engine/src/Popcorn.cpp new file mode 100644 index 00000000..1db92e3f --- /dev/null +++ b/Engine/src/Popcorn.cpp @@ -0,0 +1,9 @@ +#include "Popcorn2.h" + +ENGINE_NAMESPACE_BEGIN +CTX_NAMESPACE_BEGIN + +static void BeginContext() {}; + +CTX_NAMESPACE_END +ENGINE_NAMESPACE_END diff --git a/Engine/src/Popcorn/Core/LayerStack.cpp b/Engine/src/Popcorn/Core/LayerStack.cpp index 51d0cce7..8ccc0773 100644 --- a/Engine/src/Popcorn/Core/LayerStack.cpp +++ b/Engine/src/Popcorn/Core/LayerStack.cpp @@ -5,39 +5,39 @@ ENGINE_NAMESPACE_BEGIN LayerStack::~LayerStack() { // CLEAN UP AND FREE RESOURCES - for (Layer *l : m_layer_stack) { + for (Layer *l : m_layerStack) { l->OnDetach(); delete l; l = nullptr; } - m_layer_stack.clear(); + m_layerStack.clear(); }; void LayerStack::PushLayer(Layer *l) { - m_layer_stack.emplace(m_layer_stack.begin() + m_separator_index++, l); + m_layerStack.emplace(m_layerStack.begin() + m_separatorIndex++, l); }; void LayerStack::PopLayer(Layer *l) { - auto it = std::find(m_layer_stack.begin(), - m_layer_stack.begin() + m_separator_index, l); + auto it = std::find(m_layerStack.begin(), + m_layerStack.begin() + m_separatorIndex, l); - if (it != m_layer_stack.begin() + m_separator_index) { + if (it != m_layerStack.begin() + m_separatorIndex) { l->OnDetach(); - m_layer_stack.erase(it); - --m_separator_index; + m_layerStack.erase(it); + --m_separatorIndex; } } -void LayerStack::PushOverlay(Layer *ol) { m_layer_stack.emplace_back(ol); } +void LayerStack::PushOverlay(Layer *ol) { m_layerStack.emplace_back(ol); } void LayerStack::PopOverlay(Layer *ol) { - auto it = std::find(m_layer_stack.begin() + m_separator_index, - m_layer_stack.end(), ol); + auto it = std::find(m_layerStack.begin() + m_separatorIndex, + m_layerStack.end(), ol); - if (it != m_layer_stack.end()) { + if (it != m_layerStack.end()) { ol->OnDetach(); - m_layer_stack.erase(it); + m_layerStack.erase(it); } } diff --git a/Sandbox/02-Street-Scene/main-paintpasses.cpp b/Sandbox/02-Street-Scene/main-paintpasses.cpp index 03a6f642..eefaf417 100644 --- a/Sandbox/02-Street-Scene/main-paintpasses.cpp +++ b/Sandbox/02-Street-Scene/main-paintpasses.cpp @@ -28,13 +28,17 @@ #include using namespace Popcorn; + class BlenderScene : public Scene {}; // Game Objects are owned by Scene + class GameLayer : public Layer { public: GameLayer() = default; virtual void OnAttach() override { Popcorn::Context::ConvertGltfToScene("../assets/models/gold.gltf", scene); + // Popcorn::Context::ConvertGltfToScene("../assets/models/gold.gltf", + // scene); Popcorn::Context::RegisterScene(scene); // Init paintpass builder diff --git a/tasks/daily.txt b/tasks/daily.txt index 7e327b11..fb299323 100644 --- a/tasks/daily.txt +++ b/tasks/daily.txt @@ -8,3 +8,4 @@ --- WEEK ------ TASK ---------------------------------------------- TIME --------- :: Sep 01 +