From 77eb92838c567a6e37861e39d4f94dab27bbb8d2 Mon Sep 17 00:00:00 2001 From: Dynamitos Date: Sun, 5 Nov 2023 10:36:01 +0100 Subject: [PATCH] compiles again --- res/shaders/BasePass.slang | 26 +- res/shaders/ComputeFrustums.slang | 11 +- res/shaders/LightCulling.slang | 5 +- res/shaders/MeshletBasePass.slang | 6 +- res/shaders/Skybox.slang | 34 +-- res/shaders/TextPass.slang | 15 +- res/shaders/UIPass.slang | 22 +- res/shaders/lib/LightEnv.slang | 9 - res/shaders/lib/Material.slang | 5 +- res/shaders/lib/Meshlet.slang | 1 - res/shaders/lib/Scene.slang | 0 res/shaders/lib/SkinnedMeshVertexData.slang | 2 - res/shaders/lib/StaticMeshVertexData.slang | 4 +- res/shaders/lib/VertexData.slang | 3 +- src/AssetViewer/main.cpp | 1 - src/Editor/Asset/FontLoader.cpp | 10 +- src/Editor/Asset/MaterialLoader.cpp | 149 +++++----- src/Editor/Asset/MeshLoader.cpp | 15 +- src/Editor/Asset/MeshLoader.h | 2 +- src/Editor/Asset/TextureLoader.cpp | 19 +- src/Editor/Window/InspectorView.cpp | 16 +- src/Editor/Window/InspectorView.h | 6 - src/Editor/Window/SceneView.cpp | 12 +- src/Editor/Window/SceneView.h | 6 +- src/Editor/Window/ViewportControl.h | 3 + src/Editor/main.cpp | 4 +- src/Engine/Asset/AssetRegistry.cpp | 57 ++-- src/Engine/Asset/AssetRegistry.h | 21 +- src/Engine/Asset/FontAsset.cpp | 4 +- src/Engine/Asset/FontAsset.h | 3 +- src/Engine/Asset/MaterialAsset.cpp | 11 + src/Engine/Asset/MaterialAsset.h | 9 +- src/Engine/Asset/MaterialInstanceAsset.cpp | 8 + src/Engine/Asset/MaterialInstanceAsset.h | 5 +- src/Engine/Asset/MeshAsset.h | 2 +- src/Engine/Asset/TextureAsset.h | 6 +- src/Engine/Component/Camera.h | 2 - src/Engine/Containers/Array.h | 3 +- src/Engine/Containers/Map.h | 39 ++- src/Engine/Graphics/CMakeLists.txt | 3 - src/Engine/Graphics/Descriptor.h | 4 +- src/Engine/Graphics/Enums.cpp | 2 +- src/Engine/Graphics/Enums.h | 6 - src/Engine/Graphics/Graphics.cpp | 4 +- src/Engine/Graphics/Graphics.h | 1 + src/Engine/Graphics/Initializer.cpp | 112 +++++--- src/Engine/Graphics/Initializer.h | 55 +--- src/Engine/Graphics/Mesh.cpp | 2 +- src/Engine/Graphics/Mesh.h | 16 +- src/Engine/Graphics/RenderPass/BasePass.cpp | 175 ++++++------ src/Engine/Graphics/RenderPass/BasePass.h | 32 ++- src/Engine/Graphics/RenderPass/CMakeLists.txt | 1 + src/Engine/Graphics/RenderPass/DebugPass.cpp | 251 ++++++++-------- src/Engine/Graphics/RenderPass/DebugPass.h | 14 +- .../Graphics/RenderPass/DepthPrepass.cpp | 47 ++- src/Engine/Graphics/RenderPass/DepthPrepass.h | 13 +- .../Graphics/RenderPass/LightCullingPass.cpp | 154 ++++------ .../Graphics/RenderPass/LightCullingPass.h | 43 +-- src/Engine/Graphics/RenderPass/RenderGraph.h | 4 +- src/Engine/Graphics/RenderPass/RenderPass.cpp | 54 ++++ src/Engine/Graphics/RenderPass/RenderPass.h | 26 +- .../Graphics/RenderPass/SkyboxRenderPass.cpp | 7 +- .../Graphics/RenderPass/SkyboxRenderPass.h | 14 +- src/Engine/Graphics/RenderPass/TextPass.cpp | 16 +- src/Engine/Graphics/RenderPass/TextPass.h | 20 +- src/Engine/Graphics/RenderPass/UIPass.cpp | 21 +- src/Engine/Graphics/RenderPass/UIPass.h | 4 +- src/Engine/Graphics/RenderTarget.cpp | 24 +- src/Engine/Graphics/RenderTarget.h | 18 +- src/Engine/Graphics/Resources.cpp | 5 +- src/Engine/Graphics/Resources.h | 4 +- src/Engine/Graphics/Shader.cpp | 162 +++++++---- src/Engine/Graphics/Shader.h | 70 +++-- src/Engine/Graphics/ShaderCompiler.cpp | 18 -- src/Engine/Graphics/ShaderCompiler.h | 19 -- src/Engine/Graphics/StaticMeshVertexData.cpp | 3 +- src/Engine/Graphics/StaticMeshVertexData.h | 3 +- src/Engine/Graphics/VertexData.cpp | 12 +- src/Engine/Graphics/VertexData.h | 4 +- src/Engine/Graphics/Vulkan/Allocator.cpp | 268 ++++++++++++------ src/Engine/Graphics/Vulkan/Allocator.h | 145 +++------- src/Engine/Graphics/Vulkan/Buffer.cpp | 55 ++-- src/Engine/Graphics/Vulkan/Buffer.h | 14 +- src/Engine/Graphics/Vulkan/CommandBuffer.cpp | 4 +- src/Engine/Graphics/Vulkan/DescriptorSets.cpp | 14 +- src/Engine/Graphics/Vulkan/Enums.cpp | 2 +- src/Engine/Graphics/Vulkan/Graphics.cpp | 100 ++++--- src/Engine/Graphics/Vulkan/Graphics.h | 4 +- src/Engine/Graphics/Vulkan/Initializer.cpp | 1 + src/Engine/Graphics/Vulkan/Initializer.h | 5 + src/Engine/Graphics/Vulkan/PipelineCache.cpp | 40 +-- src/Engine/Graphics/Vulkan/PipelineCache.h | 6 +- src/Engine/Graphics/Vulkan/RenderPass.cpp | 4 +- src/Engine/Graphics/Vulkan/Texture.cpp | 10 +- src/Engine/Material/Material.cpp | 40 +-- src/Engine/Material/Material.h | 15 +- src/Engine/Material/MaterialInstance.cpp | 53 ++-- src/Engine/Material/MaterialInstance.h | 16 +- src/Engine/Material/ShaderExpression.cpp | 44 +-- src/Engine/Material/ShaderExpression.h | 25 +- src/Engine/Math/Math.h | 5 - src/Engine/Math/Transform.cpp | 33 --- src/Engine/Math/Transform.h | 2 - src/Engine/Math/Vector.h | 96 ------- src/Engine/MinimalEngine.h | 180 +++++++----- src/Engine/Scene/LightEnvironment.cpp | 16 +- src/Engine/Scene/LightEnvironment.h | 4 +- src/Engine/Scene/Scene.cpp | 1 + src/Engine/Serialization/Serialization.h | 43 ++- src/Engine/Window/GameView.cpp | 9 +- src/Engine/Window/GameView.h | 2 +- src/Engine/Window/WindowManager.cpp | 2 +- 112 files changed, 1717 insertions(+), 1540 deletions(-) delete mode 100644 res/shaders/lib/Scene.slang create mode 100644 src/Engine/Graphics/RenderPass/RenderPass.cpp delete mode 100644 src/Engine/Graphics/ShaderCompiler.cpp delete mode 100644 src/Engine/Graphics/ShaderCompiler.h diff --git a/res/shaders/BasePass.slang b/res/shaders/BasePass.slang index 93f98d7..56e14cd 100644 --- a/res/shaders/BasePass.slang +++ b/res/shaders/BasePass.slang @@ -1,7 +1,31 @@ import Common; +import LightEnv; +import Material; +import MaterialParameter; + +struct LightCullingData +{ + RWStructuredBuffer oLightIndexList; + RWStructuredBuffer tLightIndexList; + + RWTexture2D oLightGrid; + RWTexture2D tLightGrid; +}; +ParameterBuffer gLightCullingData; [shader("pixel")] void pixelMain(in VertexAttributes attribs, out float4 baseColor) { - BRDF brdf = gMaterial.prepare(); + MaterialParameter params = MaterialParameter.create(attribs); + BRDF brdf = gMaterial.prepare(params); + float3 result = float3(0, 0, 0); + for(int i = 0; i < gLightEnv.numDirectionalLights; ++i) + { + result += gLightEnv.directionalLights[i].illuminate(params, brdf); + } + for(int i = 0; i < gLightEnv.numPointLights; ++i) + { + result += gLightEnv.pointLights[i].illuminate(params, brdf); + } + return float4(result, 1.0f); } diff --git a/res/shaders/ComputeFrustums.slang b/res/shaders/ComputeFrustums.slang index 97eaa8b..12a4f2e 100644 --- a/res/shaders/ComputeFrustums.slang +++ b/res/shaders/ComputeFrustums.slang @@ -8,16 +8,15 @@ struct ComputeShaderInput uint groupIndex : SV_GroupIndex; }; -layout(set = 0, binding = 1, std430) -cbuffer DispatchParams +struct DispatchParams { uint3 numThreadGroups; uint pad0; uint3 numThreads; uint pad1; + RWShaderBuffer frustums; } -layout(set = 0, binding = 2, std430) -RWShaderBuffer out_Frustums; +ParameterBuffer dispatchParams; [numthreads(BLOCK_SIZE, BLOCK_SIZE, 1)] @@ -49,9 +48,9 @@ void computeFrustums(ComputeShaderInput in) frustum.planes[2] = computePlane(eyePos, viewSpace[0], viewSpace[1]); frustum.planes[3] = computePlane(eyePos, viewSpace[3], viewSpace[2]); - if(in.dispatchThreadID.x < numThreads.x && in.dispatchThreadID.y < numThreads.y) + if(in.dispatchThreadID.x < dispatchParams.numThreads.x && in.dispatchThreadID.y < dispatchParams.numThreads.y) { uint index = in.dispatchThreadID.x + (in.dispatchThreadID.y * numThreads.x); - out_Frustums[index] = frustum; + dispatchParams.frustums[index] = frustum; } } diff --git a/res/shaders/LightCulling.slang b/res/shaders/LightCulling.slang index d0d0781..29e2c47 100644 --- a/res/shaders/LightCulling.slang +++ b/res/shaders/LightCulling.slang @@ -1,5 +1,5 @@ -import LightEnv; import Common; +import LightEnv; struct ComputeShaderInput { @@ -27,13 +27,10 @@ struct CullingParams RWTexture2D tLightGrid; StructuredBuffer frustums; - }; ParameterBlock gCullingParams; // Debug -//layout(set = INDEX_VIEW_PARAMS, binding = 10) //Texture2D lightCountHeatMap; -//layout(set = INDEX_VIEW_PARAMS, binding = 11) //RWTexture2D debugTexture; groupshared uint uMinDepth; diff --git a/res/shaders/MeshletBasePass.slang b/res/shaders/MeshletBasePass.slang index 12bd440..2eaabc1 100644 --- a/res/shaders/MeshletBasePass.slang +++ b/res/shaders/MeshletBasePass.slang @@ -2,7 +2,7 @@ import Common; import BRDF; import Meshlet; import Scene; -import StaticMeshVertexData; +import VertexData; struct MeshPayload { @@ -61,7 +61,7 @@ void taskMain( DispatchMesh(head, 1, 1, p); } -groupshared StaticMeshVertexAttributes gs_vertices[MAX_VERTICES]; +groupshared VertexAttributes gs_vertices[MAX_VERTICES]; groupshared uint3 gs_indices[MAX_PRIMITIVES]; groupshared uint gs_numVertices; groupshared uint gs_numPrimitives; @@ -78,7 +78,7 @@ void meshMain( in uint threadID: SV_GroupIndex, in uint groupID: SV_GroupID, in payload MeshPayload meshPayload, - out Vertices vertices, + out Vertices vertices, out Indices indices ){ InstanceData inst = scene.instances[meshPayload.instanceId[groupID]]; diff --git a/res/shaders/Skybox.slang b/res/shaders/Skybox.slang index bc19ab6..c06e43f 100644 --- a/res/shaders/Skybox.slang +++ b/res/shaders/Skybox.slang @@ -10,9 +10,12 @@ struct VertexShaderOutput float4 clipPos : SV_Position; float3 texCoords; }; - -[[vk::push_constant]] -ConstantBuffer transformMatrix; +struct SkyboxData +{ + float4x4 transformMatrix; + float4 fogBlend; +}; +ParameterBuffer gSkyboxData; [shader("vertex")] VertexShaderOutput vertexMain( @@ -27,16 +30,13 @@ VertexShaderOutput vertexMain( return output; } -[[vk::push_constant]] -ConstantBuffer fogBlend; - -layout(set = 0, binding = 1) -TextureCube cubeMap; -layout(set = 0, binding = 2) -TextureCube cubeMap2; -layout(set = 0, binding = 3) -SamplerState sampler; - +struct TextureData +{ + TextureCube cubeMap; + TextureCube cubeMap2; + SamplerState sampler; +}; +ParameterBuffer textures; static const float lowerLimit = 0.0; static const float upperLimit = 0.1; @@ -44,11 +44,11 @@ static const float upperLimit = 0.1; float4 fragmentMain( VertexShaderOutput output) : SV_Target { - float4 texture1 = cubeMap.Sample(sampler, output.texCoords); - float4 texture2 = cubeMap2.Sample(sampler, output.texCoords); - float4 finalColor = lerp(texture1, texture2, fogBlend.w); + float4 texture1 = textures.cubeMap.Sample(textures.sampler, output.texCoords); + float4 texture2 = textures.cubeMap2.Sample(textures.sampler, output.texCoords); + float4 finalColor = lerp(texture1, texture2, gSkyboxData.fogBlend.w); float factor = (output.texCoords.y - lowerLimit) / (upperLimit - lowerLimit); factor = clamp(factor, 0.0, 1.0); - return lerp(float4(fogBlend.xyz, 1), finalColor, factor); + return lerp(float4(gSkyboxData.fogBlend.xyz, 1), finalColor, factor); } \ No newline at end of file diff --git a/res/shaders/TextPass.slang b/res/shaders/TextPass.slang index 8ba61bd..cc7988a 100644 --- a/res/shaders/TextPass.slang +++ b/res/shaders/TextPass.slang @@ -1,26 +1,19 @@ +import Common; struct GlyphData { float4 bearingSize; }; -struct ViewData -{ - float4x4 projectionMatrix; -} struct TextData { float4 textColor; float scale; } -layout(set = 0, binding = 0) -ConstantBuffer viewData; -layout(set = 0, binding = 1) -SamplerState glyphSampler; +ParameterBuffer glyphSampler; //layout(set = 1) //ShaderBuffer glyphData; -layout(set = 1) -Texture2D glyphTextures[]; -layout(push_constant) +ParameterBuffer[]> glyphTextures; +[[vk::push_constant]] ConstantBuffer textData; struct VertexStageInput diff --git a/res/shaders/UIPass.slang b/res/shaders/UIPass.slang index 5ede207..221dbda 100644 --- a/res/shaders/UIPass.slang +++ b/res/shaders/UIPass.slang @@ -1,3 +1,5 @@ +import Common; + struct RenderElementStyle { float3 position; @@ -15,22 +17,14 @@ struct RenderElementStyle float2 dimensions; }; -struct ViewData +struct UIParameter { - float4x4 projectionMatrix; -}; + SamplerState backgroundSampler; + uint numBackgroundTextures; + Texture2D backgroundTextures[]; +} -layout(set = 0, binding = 0) -ConstantBuffer viewData; - -layout(set = 0, binding = 1) -SamplerState backgroundSampler; - -layout(set = 0, binding = 2) -ConstantBuffer numBackgroundTextures; - -layout(set = 0, binding = 3) -Texture2D backgroundTextures[]; +ParameterBuffer params; struct VertexStageOutput { diff --git a/res/shaders/lib/LightEnv.slang b/res/shaders/lib/LightEnv.slang index 3a90b96..36834e2 100644 --- a/res/shaders/lib/LightEnv.slang +++ b/res/shaders/lib/LightEnv.slang @@ -70,12 +70,3 @@ struct LightEnv }; ParameterBlock gLightEnv; - -//layout(set = INDEX_LIGHT_ENV, binding = 0, std430) -//ShaderBuffer directionalLights; -//layout(set = INDEX_LIGHT_ENV, binding = 1, std430) -//ConstantBuffer numDirectionalLights; -//layout(set = INDEX_LIGHT_ENV, binding = 2, std430) -//ShaderBuffer pointLights; -//layout(set = INDEX_LIGHT_ENV, binding = 3, std430) -//ConstantBuffer numPointLights; diff --git a/res/shaders/lib/Material.slang b/res/shaders/lib/Material.slang index d57d7e6..86c7275 100644 --- a/res/shaders/lib/Material.slang +++ b/res/shaders/lib/Material.slang @@ -1,12 +1,11 @@ import Common; import BRDF; +import MaterialParameter; interface IMaterial { associatedtype BRDF : IBRDF; - BRDF prepare(MaterialFragmentParameter input); - + BRDF prepare(MaterialParameter input); }; -layout(set = INDEX_MATERIAL) ParameterBlock gMaterial; diff --git a/res/shaders/lib/Meshlet.slang b/res/shaders/lib/Meshlet.slang index cf7b37b..14814e3 100644 --- a/res/shaders/lib/Meshlet.slang +++ b/res/shaders/lib/Meshlet.slang @@ -37,6 +37,5 @@ struct Scene StructuredBuffer vertexIndices; }; -layout(set = INDEX_SCENE_DATA) ParameterBlock scene; diff --git a/res/shaders/lib/Scene.slang b/res/shaders/lib/Scene.slang deleted file mode 100644 index e69de29..0000000 diff --git a/res/shaders/lib/SkinnedMeshVertexData.slang b/res/shaders/lib/SkinnedMeshVertexData.slang index bbcb315..fd2ac96 100644 --- a/res/shaders/lib/SkinnedMeshVertexData.slang +++ b/res/shaders/lib/SkinnedMeshVertexData.slang @@ -63,5 +63,3 @@ struct SkinnedMeshVertexData : VertexData StructuredBuffer boneWeights; StructuredBuffer bones; } -layout(set = INDEX_VERTEX_DATA) -ParameterBlock vertexData; \ No newline at end of file diff --git a/res/shaders/lib/StaticMeshVertexData.slang b/res/shaders/lib/StaticMeshVertexData.slang index 0cb2685..599737b 100644 --- a/res/shaders/lib/StaticMeshVertexData.slang +++ b/res/shaders/lib/StaticMeshVertexData.slang @@ -54,6 +54,4 @@ struct StaticMeshVertexData : VertexData StructuredBuffer normals; StructuredBuffer tangents; StructuredBuffer biTangents; -} -layout(set = INDEX_VERTEX_DATA) -ParameterBlock vertexData; \ No newline at end of file +} \ No newline at end of file diff --git a/res/shaders/lib/VertexData.slang b/res/shaders/lib/VertexData.slang index a8d6078..eb73292 100644 --- a/res/shaders/lib/VertexData.slang +++ b/res/shaders/lib/VertexData.slang @@ -12,4 +12,5 @@ interface VertexAttributes interface VertexData { VertexAttributes getAttributes(uint index, float4x4 transform); -}; \ No newline at end of file +}; +ParameterBlock vertexData; \ No newline at end of file diff --git a/src/AssetViewer/main.cpp b/src/AssetViewer/main.cpp index efb6e48..9aee2e7 100644 --- a/src/AssetViewer/main.cpp +++ b/src/AssetViewer/main.cpp @@ -4,7 +4,6 @@ #include "Asset/TextureAsset.h" #include "Asset/MaterialAsset.h" #include "Asset/MaterialInstanceAsset.h" -#include "Graphics/Vulkan/VulkanGraphics.h" #include "Asset/AssetRegistry.h" using namespace Seele; diff --git a/src/Editor/Asset/FontLoader.cpp b/src/Editor/Asset/FontLoader.cpp index 6b80263..a6b321a 100644 --- a/src/Editor/Asset/FontLoader.cpp +++ b/src/Editor/Asset/FontLoader.cpp @@ -2,7 +2,7 @@ #include "Graphics/Graphics.h" #include "Asset/FontAsset.h" #include "Asset/AssetRegistry.h" -#include "Graphics/GraphicsResources.h" +#include "Graphics/Resources.h" #include #include FT_FREETYPE_H @@ -22,10 +22,12 @@ void FontLoader::importAsset(FontImportArgs args) { std::filesystem::path assetPath = args.filePath.filename(); assetPath.replace_extension("asset"); - PFontAsset asset = new FontAsset(args.importPath, assetPath.stem().string()); + OFontAsset asset = new FontAsset(args.importPath, assetPath.stem().string()); asset->setStatus(Asset::Status::Loading); - AssetRegistry::get().registerFont(asset); - import(args, asset); + // the registry takes ownership, but we need to edit the reference + PFontAsset ref = asset; + AssetRegistry::get().registerFont(std::move(asset)); + import(args, ref); } // in case of the space character there is no bitmap diff --git a/src/Editor/Asset/MaterialLoader.cpp b/src/Editor/Asset/MaterialLoader.cpp index 44738d1..c1bcc6a 100644 --- a/src/Editor/Asset/MaterialLoader.cpp +++ b/src/Editor/Asset/MaterialLoader.cpp @@ -7,6 +7,7 @@ #include "Material/ShaderExpression.h" #include "Asset/TextureAsset.h" #include +#include using namespace Seele; using json = nlohmann::json; @@ -14,12 +15,12 @@ using json = nlohmann::json; MaterialLoader::MaterialLoader(Gfx::PGraphics graphics) : graphics(graphics) { - PMaterialAsset placeholderAsset = new MaterialAsset(); + OMaterialAsset placeholderAsset = new MaterialAsset(); import(MaterialImportArgs{ .filePath = std::filesystem::absolute("./shaders/Placeholder.asset"), .importPath = "", }, placeholderAsset); - AssetRegistry::get().assetRoot->materials[""] = placeholderAsset; + AssetRegistry::get().assetRoot->materials[""] = std::move(placeholderAsset); } MaterialLoader::~MaterialLoader() @@ -30,10 +31,11 @@ void MaterialLoader::importAsset(MaterialImportArgs args) { std::filesystem::path assetPath = args.filePath.filename(); assetPath.replace_extension("asset"); - PMaterialAsset asset = new MaterialAsset(args.importPath, assetPath.stem().string()); + OMaterialAsset asset = new MaterialAsset(args.importPath, assetPath.stem().string()); asset->setStatus(Asset::Status::Loading); - AssetRegistry::get().registerMaterial(asset); - import(args, asset); + PMaterialAsset ref = asset; + AssetRegistry::get().registerMaterial(std::move(asset)); + import(args, ref); } void MaterialLoader::import(MaterialImportArgs args, PMaterialAsset asset) @@ -42,7 +44,7 @@ void MaterialLoader::import(MaterialImportArgs args, PMaterialAsset asset) json j; jsonstream >> j; std::string materialName = j["name"].get() + "Material"; - Gfx::PDescriptorLayout layout = graphics->createDescriptorLayout(materialName + "Layout"); + Gfx::ODescriptorLayout layout = graphics->createDescriptorLayout(materialName + "Layout"); //Shader file needs to conform to the slang standard, which prohibits _ materialName.erase(std::remove(materialName.begin(), materialName.end(), '_'), materialName.end()); materialName.erase(std::remove(materialName.begin(), materialName.end(), '.'), materialName.end()); @@ -50,19 +52,18 @@ void MaterialLoader::import(MaterialImportArgs args, PMaterialAsset asset) uint32 uniformBufferOffset = 0; uint32 bindingCounter = 0; // Uniform buffers are always binding 0 uint32 uniformBinding = -1; - Map expressions; - int32 key = 0; - int32 auxKey = -1; - Map parameters; - for(auto param : j["params"].items()) + Map expressions; + uint32 key = 0; + uint32 auxKey = 0; + Array parameters; + for(auto& param : j["params"].items()) { std::string type = param.value()["type"].get(); auto defaultValue = param.value().find("default"); // TODO: ALIGNMENT RULES if(type.compare("float") == 0) { - PFloatParameter p = new FloatParameter(param.key(), uniformBufferOffset, 0); - p->key = auxKey; + OFloatParameter p = new FloatParameter(param.key(), uniformBufferOffset, 0); if(uniformBinding == -1) { layout->addDescriptorBinding(bindingCounter, Gfx::SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER); @@ -73,14 +74,13 @@ void MaterialLoader::import(MaterialImportArgs args, PMaterialAsset asset) { p->data = std::stof(defaultValue.value().get()); } - expressions[auxKey--] = p; - parameters[param.key()] = p; + parameters.add(p->key); + expressions[p->key] = std::move(p); } // TODO: ALIGNMENT RULES else if(type.compare("float3") == 0) { - PVectorParameter p = new VectorParameter(param.key(), uniformBufferOffset, 0); - p->key = auxKey; + OVectorParameter p = new VectorParameter(param.key(), uniformBufferOffset, 0); if(uniformBinding == -1) { layout->addDescriptorBinding(bindingCounter, Gfx::SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER); @@ -91,13 +91,12 @@ void MaterialLoader::import(MaterialImportArgs args, PMaterialAsset asset) { p->data = parseVector(defaultValue.value().get().c_str()); } - expressions[auxKey--] = p; - parameters[param.key()] = p; + parameters.add(p->key); + expressions[p->key] = std::move(p); } else if(type.compare("Texture2D") == 0) { - PTextureParameter p = new TextureParameter(param.key(), 0, bindingCounter); - p->key = auxKey; + OTextureParameter p = new TextureParameter(param.key(), 0, bindingCounter); layout->addDescriptorBinding(bindingCounter++, Gfx::SE_DESCRIPTOR_TYPE_SAMPLED_IMAGE); if(defaultValue != param.value().end()) { @@ -108,17 +107,16 @@ void MaterialLoader::import(MaterialImportArgs args, PMaterialAsset asset) { p->data = AssetRegistry::findTexture(""); // this will return placeholder texture } - expressions[auxKey--] = p; - parameters[param.key()] = p; + parameters.add(p->key); + expressions[p->key] = std::move(p); } else if(type.compare("SamplerState") == 0) { - PSamplerParameter p = new SamplerParameter(param.key(), 0, bindingCounter); - p->key = auxKey; + OSamplerParameter p = new SamplerParameter(param.key(), 0, bindingCounter); layout->addDescriptorBinding(bindingCounter++, Gfx::SE_DESCRIPTOR_TYPE_SAMPLER); p->data = graphics->createSamplerState({}); - expressions[auxKey--] = p; - parameters[param.key()] = p; + parameters.add(p->key); + expressions[p->key] = std::move(p); } else { @@ -126,99 +124,100 @@ void MaterialLoader::import(MaterialImportArgs args, PMaterialAsset asset) } } uint32 uniformDataSize = uniformBufferOffset; - auto referenceExpression = [&auxKey, &expressions](json obj) -> PShaderExpression + auto referenceExpression = [&auxKey, &expressions](json obj) -> std::string { if(obj.is_string()) { - PConstantExpression c = new ConstantExpression(obj.get(), ExpressionType::UNKNOWN); - c->key = auxKey; - expressions[auxKey--] = c; - return c; + std::string str = obj.get(); + if (expressions.contains(str)) + { + return str; + } + OConstantExpression c = new ConstantExpression(str, ExpressionType::UNKNOWN); + std::string name = std::format("Const{0}", auxKey++); + c->key = name; + expressions[c->key] = std::move(c); + return name; } else { - return expressions[obj.get()]; + return std::format("{0}", obj.get()); } }; MaterialNode mat; - for(auto param : j["code"].items()) + for(auto& param : j["code"].items()) { - auto obj = param.value(); + auto& obj = param.value(); std::string exp = obj["exp"].get(); if(exp.compare("Add") == 0) { - PAddExpression p = new AddExpression(); - p->key = key; - p->inputs["lhs"].source = referenceExpression(obj["lhs"])->key; - p->inputs["rhs"].source = referenceExpression(obj["rhs"])->key; - expressions[key++] = p; + OAddExpression p = new AddExpression(); + std::string name = std::format("{0}", key++); + p->key = name; + p->inputs["lhs"].source = referenceExpression(obj["lhs"]); + p->inputs["rhs"].source = referenceExpression(obj["rhs"]); + expressions[name] = std::move(p); } if(exp.compare("Sub") == 0) { - PSubExpression p = new SubExpression(); - p->key = key; - p->inputs["lhs"].source = referenceExpression(obj["lhs"])->key; - p->inputs["rhs"].source = referenceExpression(obj["rhs"])->key; - expressions[key++] = p; + OSubExpression p = new SubExpression(); + std::string name = std::format("{0}", key++); + p->key = name; + p->inputs["lhs"].source = referenceExpression(obj["lhs"]); + p->inputs["rhs"].source = referenceExpression(obj["rhs"]); + expressions[name] = std::move(p); } if(exp.compare("Mul") == 0) { - PMulExpression p = new MulExpression(); - p->key = key; - p->inputs["lhs"].source = referenceExpression(obj["lhs"])->key; - p->inputs["rhs"].source = referenceExpression(obj["rhs"])->key; - expressions[key++] = p; + OMulExpression p = new MulExpression(); + std::string name = std::format("{0}", key++); + p->key = name; + p->inputs["lhs"].source = referenceExpression(obj["lhs"]); + p->inputs["rhs"].source = referenceExpression(obj["rhs"]); + expressions[name] = std::move(p); } if(exp.compare("Swizzle") == 0) { - PSwizzleExpression p = new SwizzleExpression(); - p->key = key; - p->inputs["target"].source = referenceExpression(obj["target"])->key; + OSwizzleExpression p = new SwizzleExpression(); + std::string name = std::format("{0}", key); + p->key = name; + p->inputs["target"].source = referenceExpression(obj["target"]); int32 i = 0; - for(auto c : obj["comp"].items()) + for(auto& c : obj["comp"].items()) { p->comp[i++] = c.value().get(); } - expressions[key++] = p; + expressions[name] = std::move(p); } if(exp.compare("Sample") == 0) { - PSampleExpression p = new SampleExpression(); - p->key = key; - p->inputs["texture"].source = parameters[obj["texture"].get()]->key; - p->inputs["sampler"].source = parameters[obj["sampler"].get()]->key; - p->inputs["coords"].source = referenceExpression(obj["coords"])->key; - expressions[key++] = p; + OSampleExpression p = new SampleExpression(); + std::string name = std::format("{0}", key); + p->key = name; + p->inputs["texture"].source = referenceExpression(obj["texture"]); + p->inputs["sampler"].source = referenceExpression(obj["sampler"]); + p->inputs["coords"].source = referenceExpression(obj["coords"]); + expressions[name] = std::move(p); } if(exp.compare("BRDF") == 0) { mat.profile = obj["profile"].get(); - for(auto val : obj["values"].items()) + for(auto& val : obj["values"].items()) { - mat.variables[val.key()] = referenceExpression(val.value()); + mat.variables[val.key()] = val.value(); } } } layout->create(); - Array codeExp; - for(const auto& [_, e] : expressions) - { - codeExp.add(e); - } - Array params; - for(const auto& [_, p] : parameters) - { - params.add(p); - } asset->material = new Material( graphics, - std::move(params), std::move(layout), uniformDataSize, uniformBinding, materialName, - std::move(codeExp), + std::move(expressions), + std::move(parameters), std::move(mat) ); diff --git a/src/Editor/Asset/MeshLoader.cpp b/src/Editor/Asset/MeshLoader.cpp index 5ba04e0..4133d6c 100644 --- a/src/Editor/Asset/MeshLoader.cpp +++ b/src/Editor/Asset/MeshLoader.cpp @@ -33,10 +33,11 @@ void MeshLoader::importAsset(MeshImportArgs args) { std::filesystem::path assetPath = args.filePath.filename(); assetPath.replace_extension("asset"); - PMeshAsset asset = new MeshAsset(args.importPath, assetPath.stem().string()); + OMeshAsset asset = new MeshAsset(args.importPath, assetPath.stem().string()); + PMeshAsset ref = asset; asset->setStatus(Asset::Status::Loading); - AssetRegistry::get().registerMesh(asset); - import(args, asset); + AssetRegistry::get().registerMesh(std::move(asset)); + import(args, ref); } void MeshLoader::loadMaterials(const aiScene* scene, const std::string& baseName, const std::filesystem::path& meshDirectory, const std::string& importPath, Array& globalMaterials) @@ -133,7 +134,7 @@ void findMeshRoots(aiNode *node, List &meshNodes) } } -void MeshLoader::loadGlobalMeshes(const aiScene* scene, const Array& materials, Array& globalMeshes, Component::Collider& collider) +void MeshLoader::loadGlobalMeshes(const aiScene* scene, const Array& materials, Array& globalMeshes, Component::Collider& collider) { for (uint32 meshIndex = 0; meshIndex < scene->mNumMeshes; ++meshIndex) { @@ -318,20 +319,22 @@ void MeshLoader::import(MeshImportArgs args, PMeshAsset meshAsset) loadTextures(scene, args.filePath.parent_path(), args.importPath); loadMaterials(scene, args.filePath.stem().string(), args.filePath.parent_path(), args.importPath, globalMaterials); - Array globalMeshes(scene->mNumMeshes); + Array globalMeshes(scene->mNumMeshes); Component::Collider collider; loadGlobalMeshes(scene, globalMaterials, globalMeshes, collider); List meshNodes; findMeshRoots(scene->mRootNode, meshNodes); + Array meshes; for (auto meshNode : meshNodes) { for(uint32 i = 0; i < meshNode->mNumMeshes; ++i) { - meshAsset->addMesh(globalMeshes[meshNode->mMeshes[i]]); + meshes.add(std::move(globalMeshes[meshNode->mMeshes[i]])); } } + meshAsset->meshes = std::move(meshes); meshAsset->physicsMesh = std::move(collider); diff --git a/src/Editor/Asset/MeshLoader.h b/src/Editor/Asset/MeshLoader.h index 00cb087..00b061b 100644 --- a/src/Editor/Asset/MeshLoader.h +++ b/src/Editor/Asset/MeshLoader.h @@ -26,7 +26,7 @@ public: private: void loadMaterials(const aiScene* scene, const std::string& baseName, const std::filesystem::path& meshDirectory, const std::string& importPath, Array& globalMaterials); void loadTextures(const aiScene* scene, const std::filesystem::path& meshDirectory, const std::string& importPath); - void loadGlobalMeshes(const aiScene* scene, const Array& materials, Array& globalMeshes, Component::Collider& collider); + void loadGlobalMeshes(const aiScene* scene, const Array& materials, Array& globalMeshes, Component::Collider& collider); void convertAssimpARGB(unsigned char* dst, aiTexel* src, uint32 numPixels); void import(MeshImportArgs args, PMeshAsset meshAsset); diff --git a/src/Editor/Asset/TextureLoader.cpp b/src/Editor/Asset/TextureLoader.cpp index 5ed41ac..3442e5c 100644 --- a/src/Editor/Asset/TextureLoader.cpp +++ b/src/Editor/Asset/TextureLoader.cpp @@ -2,7 +2,7 @@ #include "Asset/TextureAsset.h" #include "Graphics/Graphics.h" #include "Asset/AssetRegistry.h" -#include "Graphics/Vulkan/VulkanGraphicsEnums.h" +#include "Graphics/Vulkan/Enums.h" #define STB_IMAGE_IMPLEMENTATION #include #define STB_IMAGE_WRITE_IMPLEMENTATION @@ -14,15 +14,13 @@ using namespace Seele; TextureLoader::TextureLoader(Gfx::PGraphics graphics) : graphics(graphics) { - //(std::filesystem::absolute("./textures/placeholder.ktx")); - //placeholderAsset->load(graphics); - //AssetRegistry::get().assetRoot.textures[""] = placeholderAsset; - placeholderAsset = new TextureAsset(); + OTextureAsset placeholder = new TextureAsset(); + placeholderAsset = placeholder; import(TextureImportArgs{ .filePath = std::filesystem::absolute("./textures/placeholder.png"), .importPath = "", }, placeholderAsset); - AssetRegistry::get().assetRoot->textures[""] = placeholderAsset; + AssetRegistry::get().assetRoot->textures[""] = std::move(placeholder); } TextureLoader::~TextureLoader() @@ -33,11 +31,12 @@ void TextureLoader::importAsset(TextureImportArgs args) { std::filesystem::path assetPath = args.filePath.filename(); assetPath.replace_extension("asset"); - PTextureAsset asset = new TextureAsset(args.importPath, assetPath.stem().string()); + + OTextureAsset asset = new TextureAsset(args.importPath, assetPath.stem().string()); + PTextureAsset ref = asset; asset->setStatus(Asset::Status::Loading); - asset->setTexture(placeholderAsset->getTexture()); - AssetRegistry::get().registerTexture(asset); - import(args, asset); + AssetRegistry::get().registerTexture(std::move(asset)); + import(args, ref); } PTextureAsset TextureLoader::getPlaceholderTexture() diff --git a/src/Editor/Window/InspectorView.cpp b/src/Editor/Window/InspectorView.cpp index 9085c95..dd1e298 100644 --- a/src/Editor/Window/InspectorView.cpp +++ b/src/Editor/Window/InspectorView.cpp @@ -11,13 +11,13 @@ using namespace Seele::Editor; InspectorView::InspectorView(Gfx::PGraphics graphics, PWindow window, const ViewportCreateInfo &createInfo) : View(graphics, std::move(window), std::move(createInfo), "InspectorView") - , renderGraph(RenderGraphBuilder::build( - UIPass(graphics), - TextPass(graphics) - )) + //, renderGraph(RenderGraphBuilder::build( + // UIPass(graphics), + // TextPass(graphics) + //)) , uiSystem(new UI::System()) { - renderGraph.updateViewport(viewport); + //renderGraph.updateViewport(viewport); uiSystem->updateViewport(viewport); } @@ -41,15 +41,11 @@ void InspectorView::commitUpdate() void InspectorView::prepareRender() { - renderGraph.updatePassData( - uiSystem->getUIPassData(), - uiSystem->getTextPassData() - ); + } void InspectorView::render() { - renderGraph.render(uiSystem->getVirtualCamera()); } void InspectorView::keyCallback(KeyCode, InputAction, KeyModifier) diff --git a/src/Editor/Window/InspectorView.h b/src/Editor/Window/InspectorView.h index d373513..fa6ee8c 100644 --- a/src/Editor/Window/InspectorView.h +++ b/src/Editor/Window/InspectorView.h @@ -24,12 +24,6 @@ public: virtual void render() override; void selectActor(); protected: - RenderGraph< - UIPass, - TextPass> renderGraph; - - UIPassData uiPassData; - TextPassData textPassData; UI::PSystem uiSystem; PActor selectedActor; diff --git a/src/Editor/Window/SceneView.cpp b/src/Editor/Window/SceneView.cpp index 7a64437..9534a6b 100644 --- a/src/Editor/Window/SceneView.cpp +++ b/src/Editor/Window/SceneView.cpp @@ -7,7 +7,7 @@ #include "Asset/AssetRegistry.h" #include "Actor/CameraActor.h" #include "Component/Camera.h" -#include "Component/StaticMesh.h" +#include "Component/Mesh.h" using namespace Seele; using namespace Seele::Editor; @@ -16,9 +16,9 @@ SceneView::SceneView(Gfx::PGraphics graphics, PWindow owner, const ViewportCreat : View(graphics, owner, createInfo, "SceneView") , scene(new Scene(graphics)) , renderGraph(RenderGraphBuilder::build( - DepthPrepass(graphics), - LightCullingPass(graphics), - BasePass(graphics) + DepthPrepass(graphics, scene), + LightCullingPass(graphics, scene), + BasePass(graphics, scene) )) , cameraSystem(createInfo.dimensions, Vector(0, 0, 10)) { @@ -49,14 +49,10 @@ void SceneView::update() void SceneView::commitUpdate() { - depthPrepassData.staticDrawList = scene->getStaticMeshes(); - lightCullingPassData.lightEnv = scene->getLightBuffer(); - basePassData.staticDrawList = scene->getStaticMeshes(); } void SceneView::prepareRender() { - renderGraph.updatePassData(depthPrepassData, lightCullingPassData, basePassData); } void SceneView::render() diff --git a/src/Editor/Window/SceneView.h b/src/Editor/Window/SceneView.h index 1532ca8..d3ce57f 100644 --- a/src/Editor/Window/SceneView.h +++ b/src/Editor/Window/SceneView.h @@ -26,7 +26,7 @@ public: PScene getScene() const { return scene; } private: - PScene scene; + OScene scene; Component::Camera viewportCamera; RenderGraph< @@ -34,10 +34,6 @@ private: LightCullingPass, BasePass> renderGraph; - DepthPrepassData depthPrepassData; - LightCullingPassData lightCullingPassData; - BasePassData basePassData; - dp::thread_pool<> pool; ViewportControl cameraSystem; diff --git a/src/Editor/Window/ViewportControl.h b/src/Editor/Window/ViewportControl.h index ec7c4f4..d8704b6 100644 --- a/src/Editor/Window/ViewportControl.h +++ b/src/Editor/Window/ViewportControl.h @@ -2,6 +2,9 @@ #include "MinimalEngine.h" #include "Math/Vector.h" #include "Component/Camera.h" +#include "Math/Math.h" +#include "Graphics/Enums.h" +#include "Containers/Array.h" namespace Seele { diff --git a/src/Editor/main.cpp b/src/Editor/main.cpp index 81c7783..503b6c9 100644 --- a/src/Editor/main.cpp +++ b/src/Editor/main.cpp @@ -5,7 +5,7 @@ #include "Asset/AssetRegistry.h" #include "Asset/AssetImporter.h" #include "Asset/TextureLoader.h" -#include "Graphics/Vulkan/VulkanGraphics.h" +#include "Graphics/Vulkan/Graphics.h" #include "Asset/MeshLoader.h" #include "Asset/TextureLoader.h" #include "Asset/MaterialLoader.h" @@ -25,7 +25,7 @@ int main() std::string sourcePath = "C:/Users/Dynamitos/TrackClear/"; std::string binaryPath = "C:/Users/Dynamitos/TrackClear/bin/TrackClear.dll"; - Gfx::PGraphics graphics = new Vulkan::Graphics(); + Gfx::OGraphics graphics = new Vulkan::Graphics(); GraphicsInitializer initializer; graphics->init(initializer); diff --git a/src/Engine/Asset/AssetRegistry.cpp b/src/Engine/Asset/AssetRegistry.cpp index 993320c..07dfbda 100644 --- a/src/Engine/Asset/AssetRegistry.cpp +++ b/src/Engine/Asset/AssetRegistry.cpp @@ -193,28 +193,28 @@ void AssetRegistry::peekAsset(ArchiveBuffer& buffer) AssetFolder* folder = getOrCreateFolder(folderPath); - PAsset asset; + OAsset asset; switch (identifier) { case TextureAsset::IDENTIFIER: asset = new TextureAsset(folderPath, name); - folder->textures[asset->getName()] = asset; + folder->textures[name] = std::move(asset); break; case MeshAsset::IDENTIFIER: asset = new MeshAsset(folderPath, name); - folder->meshes[asset->getName()] = asset; + folder->meshes[name] = std::move(asset); break; case MaterialAsset::IDENTIFIER: asset = new MaterialAsset(folderPath, name); - folder->materials[asset->getName()] = asset; + folder->materials[name] = std::move(asset); break; case MaterialInstanceAsset::IDENTIFIER: asset = new MaterialInstanceAsset(folderPath, name); - // TODO + folder->instances[name] = std::move(asset); break; case FontAsset::IDENTIFIER: asset = new FontAsset(folderPath, name); - folder->fonts[asset->getName()] = asset; + folder->fonts[name] = std::move(asset); break; default: throw new std::logic_error("Unknown Identifier"); @@ -241,20 +241,19 @@ void AssetRegistry::loadAsset(ArchiveBuffer& buffer) switch (identifier) { case TextureAsset::IDENTIFIER: - asset = folder->textures.at(name); + asset = PTextureAsset(folder->textures.at(name)); break; case MeshAsset::IDENTIFIER: - asset = folder->meshes.at(name); + asset = PMeshAsset(folder->meshes.at(name)); break; case MaterialAsset::IDENTIFIER: - asset = folder->materials.at(name); + asset = PMaterialAsset(folder->materials.at(name)); break; case MaterialInstanceAsset::IDENTIFIER: - //asset = new MaterialInstanceAsset(path); - // TODO + asset = PMaterialInstanceAsset(folder->instances.at(name)); break; case FontAsset::IDENTIFIER: - asset = folder->fonts.at(name); + asset = PFontAsset(folder->fonts.at(name)); break; default: throw new std::logic_error("Unknown Identifier"); @@ -272,19 +271,23 @@ void AssetRegistry::saveFolder(const std::filesystem::path& folderPath, AssetFol std::filesystem::create_directory(rootFolder / folderPath); for (const auto& [name, texture] : folder->textures) { - saveAsset(texture, TextureAsset::IDENTIFIER, folderPath, name); + saveAsset(PTextureAsset(texture), TextureAsset::IDENTIFIER, folderPath, name); } for (const auto& [name, mesh] : folder->meshes) { - saveAsset(mesh, MeshAsset::IDENTIFIER, folderPath, name); + saveAsset(PMeshAsset(mesh), MeshAsset::IDENTIFIER, folderPath, name); } for (const auto& [name, material] : folder->materials) { - saveAsset(material, MaterialAsset::IDENTIFIER, folderPath, name); + saveAsset(PMaterialAsset(material), MaterialAsset::IDENTIFIER, folderPath, name); + } + for (const auto& [name, material] : folder->instances) + { + saveAsset(PMaterialInstanceAsset(material), MaterialInstanceAsset::IDENTIFIER, folderPath, name); } for (const auto& [name, font] : folder->fonts) { - saveAsset(font, FontAsset::IDENTIFIER, folderPath, name); + saveAsset(PFontAsset(font), FontAsset::IDENTIFIER, folderPath, name); } for (auto& [name, child] : folder->children) { @@ -316,28 +319,34 @@ std::filesystem::path AssetRegistry::getRootFolder() return get().rootFolder; } -void AssetRegistry::registerMesh(PMeshAsset mesh) +void AssetRegistry::registerMesh(OMeshAsset mesh) { AssetFolder* folder = getOrCreateFolder(mesh->getFolderPath()); - folder->meshes[mesh->getName()] = mesh; + folder->meshes[mesh->getName()] = std::move(mesh); } -void AssetRegistry::registerTexture(PTextureAsset texture) +void AssetRegistry::registerTexture(OTextureAsset texture) { AssetFolder* folder = getOrCreateFolder(texture->getFolderPath()); - folder->textures[texture->getName()] = texture; + folder->textures[texture->getName()] = std::move(texture); } -void AssetRegistry::registerFont(PFontAsset font) +void AssetRegistry::registerFont(OFontAsset font) { AssetFolder* folder = getOrCreateFolder(font->getFolderPath()); - folder->fonts[font->getName()] = font; + folder->fonts[font->getName()] = std::move(font); } -void AssetRegistry::registerMaterial(PMaterialAsset material) +void AssetRegistry::registerMaterial(OMaterialAsset material) { AssetFolder* folder = getOrCreateFolder(material->getFolderPath()); - folder->materials[material->getName()] = material; + folder->materials[material->getName()] = std::move(material); +} + +void AssetRegistry::registerMaterialInstance(OMaterialInstanceAsset material) +{ + AssetFolder* folder = getOrCreateFolder(material->getFolderPath()); + folder->instances[material->getName()] = std::move(material); } AssetRegistry::AssetFolder* AssetRegistry::getOrCreateFolder(std::string fullPath) diff --git a/src/Engine/Asset/AssetRegistry.h b/src/Engine/Asset/AssetRegistry.h index 93d9ec1..b9f2c17 100644 --- a/src/Engine/Asset/AssetRegistry.h +++ b/src/Engine/Asset/AssetRegistry.h @@ -10,8 +10,8 @@ DECLARE_REF(TextureAsset) DECLARE_REF(FontAsset) DECLARE_REF(MeshAsset) DECLARE_REF(MaterialAsset) +DECLARE_REF(MaterialInstanceAsset) DECLARE_NAME_REF(Gfx, Graphics) - class AssetRegistry { public: @@ -24,6 +24,7 @@ public: static PTextureAsset findTexture(const std::string& filePath); static PFontAsset findFont(const std::string& name); static PMaterialAsset findMaterial(const std::string& filePath); + static PMaterialInstanceAsset findMaterialInstance(const std::string& filePath); static std::ofstream createWriteStream(const std::filesystem::path& relativePath, std::ios_base::openmode openmode = std::ios::out); static std::ifstream createReadStream(const std::filesystem::path& relativePath, std::ios_base::openmode openmode = std::ios::in); @@ -36,10 +37,11 @@ public: { std::string folderPath; Map children; - Map textures; - Map fonts; - Map meshes; - Map materials; + Map textures; + Map fonts; + Map meshes; + Map materials; + Map instances; AssetFolder(std::string_view folderPath); ~AssetFolder(); }; @@ -59,10 +61,11 @@ private: void saveFolder(const std::filesystem::path& folderPath, AssetFolder* folder); void saveAsset(PAsset asset, uint64 identifier, const std::filesystem::path& folderPath, std::string name); - void registerMesh(PMeshAsset mesh); - void registerTexture(PTextureAsset texture); - void registerFont(PFontAsset font); - void registerMaterial(PMaterialAsset material); + void registerMesh(OMeshAsset mesh); + void registerTexture(OTextureAsset texture); + void registerFont(OFontAsset font); + void registerMaterial(OMaterialAsset material); + void registerMaterialInstance(OMaterialInstanceAsset instance); std::ofstream internalCreateWriteStream(const std::filesystem::path& relativePath, std::ios_base::openmode openmode = std::ios::out); std::ifstream internalCreateReadStream(const std::filesystem::path& relaitvePath, std::ios_base::openmode openmode = std::ios::in); diff --git a/src/Engine/Asset/FontAsset.cpp b/src/Engine/Asset/FontAsset.cpp index 25aacf0..4071cde 100644 --- a/src/Engine/Asset/FontAsset.cpp +++ b/src/Engine/Asset/FontAsset.cpp @@ -117,7 +117,9 @@ void FontAsset::load(ArchiveBuffer& buffer) .usage = Gfx::SE_IMAGE_USAGE_SAMPLED_BIT, }; - glyph.texture = buffer.getGraphics()->createTexture2D(createInfo); + Gfx::OTexture2D texture = buffer.getGraphics()->createTexture2D(createInfo); + glyph.texture = texture; + usedTextures.add(std::move(texture)); ktxTexture_Destroy(ktxTexture(kTexture)); diff --git a/src/Engine/Asset/FontAsset.h b/src/Engine/Asset/FontAsset.h index afbf3cf..aec72a0 100644 --- a/src/Engine/Asset/FontAsset.h +++ b/src/Engine/Asset/FontAsset.h @@ -18,13 +18,14 @@ public: struct Glyph { - Gfx::OTexture2D texture; + Gfx::PTexture2D texture; IVector2 size; IVector2 bearing; uint32 advance; }; const Map getGlyphData() const { return glyphs; } private: + Array usedTextures; Map glyphs; friend class FontLoader; }; diff --git a/src/Engine/Asset/MaterialAsset.cpp b/src/Engine/Asset/MaterialAsset.cpp index 4a9d04c..5cf5916 100644 --- a/src/Engine/Asset/MaterialAsset.cpp +++ b/src/Engine/Asset/MaterialAsset.cpp @@ -1,6 +1,7 @@ #include "MaterialAsset.h" #include "Material/Material.h" #include "Graphics/Graphics.h" +#include "MaterialInstanceAsset.h" using namespace Seele; @@ -29,3 +30,13 @@ void MaterialAsset::load(ArchiveBuffer& buffer) material->compile(); } +OMaterialInstanceAsset Seele::MaterialAsset::instantiate(const InstantiationParameter& params) +{ + OMaterialInstance instance = material->instantiate(); + instance->setBaseMaterial(this); + OMaterialInstanceAsset asset = new MaterialInstanceAsset(params.folderPath, params.name); + asset->setHandle(std::move(instance)); + return asset; +} + + diff --git a/src/Engine/Asset/MaterialAsset.h b/src/Engine/Asset/MaterialAsset.h index d824ebb..ce38668 100644 --- a/src/Engine/Asset/MaterialAsset.h +++ b/src/Engine/Asset/MaterialAsset.h @@ -4,6 +4,12 @@ namespace Seele { DECLARE_REF(Material) +DECLARE_REF(MaterialInstanceAsset) +struct InstantiationParameter +{ + std::string name; + std::string folderPath; +}; class MaterialAsset : public Asset { public: @@ -14,8 +20,9 @@ public: virtual void save(ArchiveBuffer& buffer) const override; virtual void load(ArchiveBuffer& buffer) override; PMaterial getMaterial() const { return material; } + OMaterialInstanceAsset instantiate(const InstantiationParameter& params); private: - PMaterial material; + OMaterial material; friend class MaterialLoader; }; DEFINE_REF(MaterialAsset) diff --git a/src/Engine/Asset/MaterialInstanceAsset.cpp b/src/Engine/Asset/MaterialInstanceAsset.cpp index ec17e57..0a39fe8 100644 --- a/src/Engine/Asset/MaterialInstanceAsset.cpp +++ b/src/Engine/Asset/MaterialInstanceAsset.cpp @@ -2,6 +2,7 @@ #include "Material/MaterialInstance.h" #include "Material/Material.h" #include "Graphics/Graphics.h" +#include "Asset/AssetRegistry.h" using namespace Seele; @@ -21,8 +22,15 @@ MaterialInstanceAsset::~MaterialInstanceAsset() void MaterialInstanceAsset::save(ArchiveBuffer& buffer) const { + Serialization::save(buffer, baseMaterial->getAssetIdentifier()); + material->save(buffer); } void MaterialInstanceAsset::load(ArchiveBuffer& buffer) { + std::string id; + Serialization::load(buffer, id); + material->load(buffer); + baseMaterial = AssetRegistry::findMaterial(id); + material->setBaseMaterial(baseMaterial); } diff --git a/src/Engine/Asset/MaterialInstanceAsset.h b/src/Engine/Asset/MaterialInstanceAsset.h index 5a44e89..3a14fa3 100644 --- a/src/Engine/Asset/MaterialInstanceAsset.h +++ b/src/Engine/Asset/MaterialInstanceAsset.h @@ -13,8 +13,11 @@ public: virtual ~MaterialInstanceAsset(); virtual void save(ArchiveBuffer& buffer) const override; virtual void load(ArchiveBuffer& buffer) override; + void setHandle(OMaterialInstance handle) { material = std::move(handle); } + void setBase(PMaterialAsset base) { baseMaterial = base; } private: - PMaterialInstance material; + OMaterialInstance material; + PMaterialAsset baseMaterial; }; DEFINE_REF(MaterialInstanceAsset) } // namespace Seele diff --git a/src/Engine/Asset/MeshAsset.h b/src/Engine/Asset/MeshAsset.h index 8890390..57091bf 100644 --- a/src/Engine/Asset/MeshAsset.h +++ b/src/Engine/Asset/MeshAsset.h @@ -16,7 +16,7 @@ public: virtual void save(ArchiveBuffer& buffer) const override; virtual void load(ArchiveBuffer& buffer) override; //Workaround while no editor - Array meshes; + Array meshes; Component::Collider physicsMesh; }; DEFINE_REF(MeshAsset) diff --git a/src/Engine/Asset/TextureAsset.h b/src/Engine/Asset/TextureAsset.h index 264d9ce..784c17b 100644 --- a/src/Engine/Asset/TextureAsset.h +++ b/src/Engine/Asset/TextureAsset.h @@ -13,16 +13,16 @@ public: virtual ~TextureAsset(); virtual void save(ArchiveBuffer& buffer) const override; virtual void load(ArchiveBuffer& buffer) override; - void setTexture(Gfx::PTexture _texture) + void setTexture(Gfx::OTexture _texture) { - texture = _texture; + texture = std::move(_texture); } Gfx::PTexture getTexture() { return texture; } private: - Gfx::PTexture texture; + Gfx::OTexture texture; friend class TextureLoader; }; DEFINE_REF(TextureAsset) diff --git a/src/Engine/Component/Camera.h b/src/Engine/Component/Camera.h index b87c5df..ce3921c 100644 --- a/src/Engine/Component/Camera.h +++ b/src/Engine/Component/Camera.h @@ -5,7 +5,6 @@ namespace Seele { -DECLARE_NAME_REF(Gfx, Viewport) namespace Component { struct Camera @@ -24,7 +23,6 @@ struct Camera { return Vector(viewMatrix[3]); } - void setViewport(Gfx::PViewport viewport); void mouseMove(float deltaX, float deltaY); void mouseScroll(float x); void moveX(float amount); diff --git a/src/Engine/Containers/Array.h b/src/Engine/Containers/Array.h index b6802a1..37eb7ae 100644 --- a/src/Engine/Containers/Array.h +++ b/src/Engine/Containers/Array.h @@ -393,7 +393,8 @@ public: std::allocator_traits::construct(allocator, &_data[arraySize++], arguments...); return _data[arraySize - 1]; } - template + template + requires std::predicate constexpr void remove_if(Pred pred, bool keepOrder = true) { remove(find(pred), keepOrder); diff --git a/src/Engine/Containers/Map.h b/src/Engine/Containers/Map.h index 1af971b..8ff3416 100644 --- a/src/Engine/Containers/Map.h +++ b/src/Engine/Containers/Map.h @@ -272,6 +272,39 @@ public: return getNode(root)->pair.value; } + constexpr const mapped_type& operator[](const key_type& key) const + { + size_t it = root; + while (!equal(getNode(it)->pair.key, key)) + { + if (comp(key, getNode(it)->pair.key)) + { + it = getNode(it)->leftChild; + } + else + { + it = getNode(it)->rightChild; + } + } + return getNode(it)->pair.value; + } + constexpr const mapped_type& operator[](key_type&& key) const + { + size_t it = root; + while (!equal(getNode(it)->pair.key, key)) + { + if (comp(key, getNode(it)->pair.key)) + { + it = getNode(it)->leftChild; + } + else + { + it = getNode(it)->rightChild; + } + } + return getNode(it)->pair.value; + } + constexpr mapped_type& at(const key_type& key) { root = splay(root, key); @@ -414,11 +447,11 @@ public: buffer.readBytes(&len, sizeof(uint64)); for(uint64 i = 0; i < len; ++i) { - K k; - V v; + K k = K(); + V v = V(); Serialization::load(buffer, k); Serialization::load(buffer, v); - this->operator[](k) = v; + this->operator[](std::move(k)) = std::move(v); } } private: diff --git a/src/Engine/Graphics/CMakeLists.txt b/src/Engine/Graphics/CMakeLists.txt index 6351b28..2ea9e45 100644 --- a/src/Engine/Graphics/CMakeLists.txt +++ b/src/Engine/Graphics/CMakeLists.txt @@ -19,8 +19,6 @@ target_sources(Engine Resources.cpp Shader.h Shader.cpp - ShaderCompiler.h - ShaderCompiler.cpp StaticMeshVertexData.h StaticMeshVertexData.cpp Texture.h @@ -40,7 +38,6 @@ target_sources(Engine RenderTarget.h Resources.h Shader.h - ShaderCompiler.h StaticMeshVertexData.h Texture.h VertexData.h) diff --git a/src/Engine/Graphics/Descriptor.h b/src/Engine/Graphics/Descriptor.h index 6a06af5..06e3434 100644 --- a/src/Engine/Graphics/Descriptor.h +++ b/src/Engine/Graphics/Descriptor.h @@ -132,12 +132,12 @@ public: virtual ~PipelineLayout() {} virtual void create() = 0; virtual void reset() = 0; - void addDescriptorLayout(uint32 setIndex, const PDescriptorLayout layout); + void addDescriptorLayout(uint32 setIndex, PDescriptorLayout layout); void addPushConstants(const SePushConstantRange& pushConstants); virtual uint32 getHash() const = 0; protected: - Array descriptorSetLayouts; + Array descriptorSetLayouts; Array pushConstants; }; DEFINE_REF(PipelineLayout) diff --git a/src/Engine/Graphics/Enums.cpp b/src/Engine/Graphics/Enums.cpp index 351fd86..8aa47cb 100644 --- a/src/Engine/Graphics/Enums.cpp +++ b/src/Engine/Graphics/Enums.cpp @@ -1,4 +1,4 @@ -#include "GraphicsEnums.h" +#include "Enums.h" using namespace Seele; using namespace Seele::Gfx; diff --git a/src/Engine/Graphics/Enums.h b/src/Engine/Graphics/Enums.h index 15f62cb..fbddc34 100644 --- a/src/Engine/Graphics/Enums.h +++ b/src/Engine/Graphics/Enums.h @@ -173,12 +173,6 @@ static constexpr uint32 numVerticesPerMeshlet = 64; static constexpr uint32 numPrimitivesPerMeshlet = 126; double getCurrentFrameDelta(); -enum class RenderPassType : uint8 -{ - DepthPrepass, - BasePass -}; - enum class QueueType { GRAPHICS = 1, diff --git a/src/Engine/Graphics/Graphics.cpp b/src/Engine/Graphics/Graphics.cpp index 162b605..2090bb4 100644 --- a/src/Engine/Graphics/Graphics.cpp +++ b/src/Engine/Graphics/Graphics.cpp @@ -1,5 +1,6 @@ #include "Graphics.h" -#include "ShaderCompiler.h" +#include "Shader.h" +#include "Graphics.h" using namespace Seele::Gfx; @@ -11,3 +12,4 @@ Graphics::Graphics() Graphics::~Graphics() { } + diff --git a/src/Engine/Graphics/Graphics.h b/src/Engine/Graphics/Graphics.h index 526f769..2864797 100644 --- a/src/Engine/Graphics/Graphics.h +++ b/src/Engine/Graphics/Graphics.h @@ -2,6 +2,7 @@ #include "MinimalEngine.h" #include "Resources.h" #include "Containers/Array.h" +#include "Shader.h" namespace Seele { diff --git a/src/Engine/Graphics/Initializer.cpp b/src/Engine/Graphics/Initializer.cpp index 4ec8ac4..a9e3c1b 100644 --- a/src/Engine/Graphics/Initializer.cpp +++ b/src/Engine/Graphics/Initializer.cpp @@ -1,48 +1,92 @@ #include "Initializer.h" using namespace Seele; -using namespace Seele::Graphics; +using namespace Seele::Gfx; LegacyPipelineCreateInfo::LegacyPipelineCreateInfo() : topology(Gfx::SE_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST) , multisampleState(MultisampleState{ .samples = 1, }) - , rasterizationState(RasterizationState{ - .polygonMode = Gfx::SE_POLYGON_MODE_FILL, - .cullMode = Gfx::SE_CULL_MODE_BACK_BIT, - .frontFace = Gfx::SE_FRONT_FACE_COUNTER_CLOCKWISE, - }) - , depthStencilState(DepthStencilState{ - .depthTestEnable = true, - .depthWriteEnable = true, - .stencilTestEnable = false, - .depthCompareOp = Gfx::SE_COMPARE_OP_LESS_OR_EQUAL, - .minDepthBounds = 0.0f, - .maxDepthBounds = 1.0f, - }) - , colorBlend(ColorBlendState{ - .logicOpEnable = false, - .attachmentCount = 0, - .blendAttachments = { - ColorBlendState::BlendAttachment{ - .colorWriteMask = - Gfx::SE_COLOR_COMPONENT_R_BIT | - Gfx::SE_COLOR_COMPONENT_G_BIT | - Gfx::SE_COLOR_COMPONENT_B_BIT | - Gfx::SE_COLOR_COMPONENT_A_BIT, - } - }, - .blendConstants = { - 1.0f, - 1.0f, - 1.0f, - 1.0f, - }, - }) + , rasterizationState(RasterizationState{ + .polygonMode = Gfx::SE_POLYGON_MODE_FILL, + .cullMode = Gfx::SE_CULL_MODE_BACK_BIT, + .frontFace = Gfx::SE_FRONT_FACE_COUNTER_CLOCKWISE, + }) + , depthStencilState(DepthStencilState{ + .depthTestEnable = true, + .depthWriteEnable = true, + .stencilTestEnable = false, + .depthCompareOp = Gfx::SE_COMPARE_OP_LESS_OR_EQUAL, + .minDepthBounds = 0.0f, + .maxDepthBounds = 1.0f, + }) + , colorBlend(ColorBlendState{ + .logicOpEnable = false, + .attachmentCount = 0, + .blendAttachments = { + ColorBlendState::BlendAttachment{ + .colorWriteMask = + Gfx::SE_COLOR_COMPONENT_R_BIT | + Gfx::SE_COLOR_COMPONENT_G_BIT | + Gfx::SE_COLOR_COMPONENT_B_BIT | + Gfx::SE_COLOR_COMPONENT_A_BIT, + } + }, + .blendConstants = { + 1.0f, + 1.0f, + 1.0f, + 1.0f, + }, + }) { } -Seele::Gfx::LegacyPipelineCreateInfo::~LegacyPipelineCreateInfo() +LegacyPipelineCreateInfo::~LegacyPipelineCreateInfo() +{ +} + + +MeshPipelineCreateInfo::MeshPipelineCreateInfo() + : multisampleState(MultisampleState{ + .samples = 1, + }) + , rasterizationState(RasterizationState{ + .polygonMode = Gfx::SE_POLYGON_MODE_FILL, + .cullMode = Gfx::SE_CULL_MODE_BACK_BIT, + .frontFace = Gfx::SE_FRONT_FACE_COUNTER_CLOCKWISE, + }) + , depthStencilState(DepthStencilState{ + .depthTestEnable = true, + .depthWriteEnable = true, + .stencilTestEnable = false, + .depthCompareOp = Gfx::SE_COMPARE_OP_LESS_OR_EQUAL, + .minDepthBounds = 0.0f, + .maxDepthBounds = 1.0f, + }) + , colorBlend(ColorBlendState{ + .logicOpEnable = false, + .attachmentCount = 0, + .blendAttachments = { + ColorBlendState::BlendAttachment{ + .colorWriteMask = + Gfx::SE_COLOR_COMPONENT_R_BIT | + Gfx::SE_COLOR_COMPONENT_G_BIT | + Gfx::SE_COLOR_COMPONENT_B_BIT | + Gfx::SE_COLOR_COMPONENT_A_BIT, + } + }, + .blendConstants = { + 1.0f, + 1.0f, + 1.0f, + 1.0f, + }, + }) +{ +} + +MeshPipelineCreateInfo::~MeshPipelineCreateInfo() { } diff --git a/src/Engine/Graphics/Initializer.h b/src/Engine/Graphics/Initializer.h index 4c249fa..8cceb58 100644 --- a/src/Engine/Graphics/Initializer.h +++ b/src/Engine/Graphics/Initializer.h @@ -2,7 +2,6 @@ #include "Enums.h" #include "Containers/Map.h" #include "Math/Math.h" -#include "Shader.h" namespace Seele { @@ -26,7 +25,7 @@ struct GraphicsInitializer , engineName("SeeleEngine") , windowLayoutFile(nullptr) , layers{"VK_LAYER_KHRONOS_validation"} - , instanceExtensions{} + , instanceExtensions{"VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME"} , deviceExtensions{"VK_KHR_swapchain"} , windowHandle(nullptr) { @@ -102,18 +101,17 @@ struct IndexBufferCreateInfo struct UniformBufferCreateInfo { DataSource sourceData = DataSource(); - uint8 bDynamic = 0; + uint8 dynamic = 0; }; struct ShaderBufferCreateInfo { DataSource sourceData = DataSource(); uint32 stride; - uint8 bDynamic = 0; + uint8 dynamic = 0; }; struct ShaderCreateInfo { std::string mainModule; - //It's possible to input multiple source files for materials or vertexFactories Array additionalModules; std::string name; // Debug info std::string entryPoint; @@ -136,7 +134,7 @@ struct VertexElement SeFormat vertexFormat; uint8 attributeIndex; uint8 stride; - uint8 bInstanced = 0; + uint8 instanced = 0; }; static_assert(std::is_aggregate_v); struct RasterizationState @@ -191,6 +189,11 @@ struct ColorBlendState float blendConstants[4]; }; DECLARE_REF(VertexDeclaration) +DECLARE_REF(VertexShader) +DECLARE_REF(TaskShader) +DECLARE_REF(MeshShader) +DECLARE_REF(FragmentShader) +DECLARE_REF(ComputeShader) DECLARE_REF(RenderPass) DECLARE_REF(PipelineLayout) struct LegacyPipelineCreateInfo @@ -220,44 +223,8 @@ struct MeshPipelineCreateInfo RasterizationState rasterizationState; DepthStencilState depthStencilState; ColorBlendState colorBlend; - MeshPipelineCreateInfo() - : multisampleState(MultisampleState{ - .samples = 1, - }) - , rasterizationState(RasterizationState{ - .polygonMode = Gfx::SE_POLYGON_MODE_FILL, - .cullMode = Gfx::SE_CULL_MODE_BACK_BIT, - .frontFace = Gfx::SE_FRONT_FACE_COUNTER_CLOCKWISE, - }) - , depthStencilState(DepthStencilState{ - .depthTestEnable = true, - .depthWriteEnable = true, - .stencilTestEnable = false, - .depthCompareOp = Gfx::SE_COMPARE_OP_LESS_OR_EQUAL, - .minDepthBounds = 0.0f, - .maxDepthBounds = 1.0f, - }) - , colorBlend(ColorBlendState{ - .logicOpEnable = false, - .attachmentCount = 0, - .blendAttachments = { - ColorBlendState::BlendAttachment{ - .colorWriteMask = - Gfx::SE_COLOR_COMPONENT_R_BIT | - Gfx::SE_COLOR_COMPONENT_G_BIT | - Gfx::SE_COLOR_COMPONENT_B_BIT | - Gfx::SE_COLOR_COMPONENT_A_BIT, - } - }, - .blendConstants = { - 1.0f, - 1.0f, - 1.0f, - 1.0f, - }, - }) - { - } + MeshPipelineCreateInfo(); + ~MeshPipelineCreateInfo(); }; struct ComputePipelineCreateInfo { diff --git a/src/Engine/Graphics/Mesh.cpp b/src/Engine/Graphics/Mesh.cpp index 3b53100..c374689 100644 --- a/src/Engine/Graphics/Mesh.cpp +++ b/src/Engine/Graphics/Mesh.cpp @@ -11,7 +11,7 @@ Mesh::~Mesh() { } -void Mesh::save(ArchiveBuffer& buffer) +void Mesh::save(ArchiveBuffer& buffer) const { Serialization::save(buffer, vertexData->getTypeName()); Serialization::save(buffer, vertexCount); diff --git a/src/Engine/Graphics/Mesh.h b/src/Engine/Graphics/Mesh.h index 6465580..fec3fb7 100644 --- a/src/Engine/Graphics/Mesh.h +++ b/src/Engine/Graphics/Mesh.h @@ -15,9 +15,23 @@ public: uint64 vertexCount; PMaterialInstance referencedMaterial; Array meshlets; - void save(ArchiveBuffer& buffer); + void save(ArchiveBuffer& buffer) const; void load(ArchiveBuffer& buffer); private: }; DEFINE_REF(Mesh) +namespace Serialization +{ + template<> + static void save(ArchiveBuffer& buffer, const OMesh& ptr) + { + ptr->save(buffer); + } + template<> + static void load(ArchiveBuffer& buffer, OMesh& ptr) + { + ptr = new Mesh(); + ptr->load(buffer); + } +} // namespace Serialization } // namespace Seele \ No newline at end of file diff --git a/src/Engine/Graphics/RenderPass/BasePass.cpp b/src/Engine/Graphics/RenderPass/BasePass.cpp index 0d23b3d..d835105 100644 --- a/src/Engine/Graphics/RenderPass/BasePass.cpp +++ b/src/Engine/Graphics/RenderPass/BasePass.cpp @@ -1,5 +1,6 @@ #include "BasePass.h" #include "Graphics/Graphics.h" +#include "Graphics/Shader.h" #include "Window/Window.h" #include "Component/Camera.h" #include "Component/Mesh.h" @@ -13,47 +14,25 @@ using namespace Seele; BasePass::BasePass(Gfx::PGraphics graphics, PScene scene) : RenderPass(graphics, scene) - , descriptorSets(4) + , descriptorSets(6) { - UniformBufferCreateInfo uniformInitializer; basePassLayout = graphics->createPipelineLayout(); - lightLayout = graphics->createDescriptorLayout("LightLayout"); - - // Directional Lights - lightLayout->addDescriptorBinding(0, Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER); - lightLayout->addDescriptorBinding(1, Gfx::SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER); - // Point Lights - lightLayout->addDescriptorBinding(2, Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER); - lightLayout->addDescriptorBinding(3, Gfx::SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER); - // Light Index List - lightLayout->addDescriptorBinding(4, Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER); - // Light Grid - lightLayout->addDescriptorBinding(5, Gfx::SE_DESCRIPTOR_TYPE_STORAGE_IMAGE); - lightLayout->create(); - basePassLayout->addDescriptorLayout(INDEX_LIGHT_ENV, lightLayout); - descriptorSets[INDEX_LIGHT_ENV] = lightLayout->allocateDescriptorSet(); + basePassLayout->addDescriptorLayout(INDEX_VIEW_PARAMS, viewParamsLayout); + basePassLayout->addDescriptorLayout(INDEX_LIGHT_ENV, scene->getLightEnvironment()->getDescriptorLayout()); - viewLayout = graphics->createDescriptorLayout("ViewLayout"); - viewLayout->addDescriptorBinding(0, Gfx::SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER); - uniformInitializer.sourceData.size = sizeof(ViewParameter); - uniformInitializer.sourceData.data = (uint8*)&viewParams; - uniformInitializer.bDynamic = true; - viewParamBuffer = graphics->createUniformBuffer(uniformInitializer); - viewLayout->create(); - basePassLayout->addDescriptorLayout(INDEX_VIEW_PARAMS, viewLayout); - descriptorSets[INDEX_VIEW_PARAMS] = viewLayout->allocateDescriptorSet(); + lightCullingLayout = graphics->createDescriptorLayout("BasePassLightCulling"); + // oLightIndexList + lightCullingLayout->addDescriptorBinding(0, Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER); + // tLightIndexList + lightCullingLayout->addDescriptorBinding(1, Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER); + // oLightGrid + lightCullingLayout->addDescriptorBinding(2, Gfx::SE_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER); + // tLightGrid + lightCullingLayout->addDescriptorBinding(3, Gfx::SE_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER); + lightCullingLayout->create(); - sceneLayout = graphics->createDescriptorLayout("SceneLayout"); - sceneLayout->addDescriptorBinding(0, Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER); - sceneLayout->addDescriptorBinding(1, Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER); - sceneLayout->create(); - basePassLayout->addDescriptorLayout(INDEX_SCENE_DATA, sceneLayout); - //basePassLayout->addPushConstants(Gfx::SePushConstantRange{ - // .stageFlags = (Gfx::SE_SHADER_STAGE_VERTEX_BIT | Gfx::SE_SHADER_STAGE_FRAGMENT_BIT), - // .offset = 0, - // .size = sizeof(uint32), - //}); + basePassLayout->addDescriptorLayout(INDEX_LIGHT_CULLING, lightCullingLayout); } BasePass::~BasePass() @@ -62,61 +41,95 @@ BasePass::~BasePass() void BasePass::beginFrame(const Component::Camera& cam) { - DataSource uniformUpdate; + RenderPass::beginFrame(cam); - viewParams.viewMatrix = cam.getViewMatrix(); - viewParams.projectionMatrix = viewport->getProjectionMatrix(); - viewParams.cameraPosition = Vector4(cam.getCameraPosition(), 1); - viewParams.screenDimensions = Vector2(static_cast(viewport->getSizeX()), static_cast(viewport->getSizeY())); - uniformUpdate.size = sizeof(ViewParameter); - uniformUpdate.data = (uint8*)&viewParams; - viewParamBuffer->updateContents(uniformUpdate); - viewLayout->reset(); - lightLayout->reset(); - - descriptorSets[INDEX_SCENE_DATA] = sceneLayout->allocateDescriptorSet(); - descriptorSets[INDEX_SCENE_DATA]->updateBuffer(0, passData.sceneDataBuffer); - descriptorSets[INDEX_SCENE_DATA]->writeChanges(); - descriptorSets[INDEX_LIGHT_ENV] = lightLayout->allocateDescriptorSet(); - descriptorSets[INDEX_VIEW_PARAMS] = viewLayout->allocateDescriptorSet(); - descriptorSets[INDEX_VIEW_PARAMS]->updateBuffer(0, viewParamBuffer); - descriptorSets[INDEX_VIEW_PARAMS]->writeChanges(); - //std::cout << "BasePass beginFrame()" << std::endl; - //co_return; + lightCullingLayout->reset(); + descriptorSets[INDEX_VIEW_PARAMS] = viewParamsSet; + descriptorSets[INDEX_LIGHT_ENV] = scene->getLightEnvironment()->getDescriptorSet(); + descriptorSets[INDEX_LIGHT_CULLING] = lightCullingLayout->allocateDescriptorSet(); } void BasePass::render() { - oLightIndexList->pipelineBarrier( - Gfx::SE_ACCESS_SHADER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT, - Gfx::SE_ACCESS_SHADER_READ_BIT, Gfx::SE_PIPELINE_STAGE_FRAGMENT_SHADER_BIT); - oLightGrid->pipelineBarrier( - Gfx::SE_ACCESS_SHADER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT, - Gfx::SE_ACCESS_SHADER_READ_BIT, Gfx::SE_PIPELINE_STAGE_FRAGMENT_SHADER_BIT); + oLightIndexList->pipelineBarrier( + Gfx::SE_ACCESS_SHADER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT, + Gfx::SE_ACCESS_SHADER_READ_BIT, Gfx::SE_PIPELINE_STAGE_FRAGMENT_SHADER_BIT); + tLightIndexList->pipelineBarrier( + Gfx::SE_ACCESS_SHADER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT, + Gfx::SE_ACCESS_SHADER_READ_BIT, Gfx::SE_PIPELINE_STAGE_FRAGMENT_SHADER_BIT); + oLightGrid->pipelineBarrier( + Gfx::SE_ACCESS_SHADER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT, + Gfx::SE_ACCESS_SHADER_READ_BIT, Gfx::SE_PIPELINE_STAGE_FRAGMENT_SHADER_BIT); + tLightGrid->pipelineBarrier( + Gfx::SE_ACCESS_SHADER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT, + Gfx::SE_ACCESS_SHADER_READ_BIT, Gfx::SE_PIPELINE_STAGE_FRAGMENT_SHADER_BIT); - descriptorSets[INDEX_LIGHT_ENV]->updateBuffer(0, passData.lightEnv.directionalLights); - descriptorSets[INDEX_LIGHT_ENV]->updateBuffer(1, passData.lightEnv.numDirectional); - descriptorSets[INDEX_LIGHT_ENV]->updateBuffer(2, passData.lightEnv.pointLights); - descriptorSets[INDEX_LIGHT_ENV]->updateBuffer(3, passData.lightEnv.numPoints); - descriptorSets[INDEX_LIGHT_ENV]->updateBuffer(4, oLightIndexList); - descriptorSets[INDEX_LIGHT_ENV]->updateTexture(5, oLightGrid); - descriptorSets[INDEX_LIGHT_ENV]->writeChanges(); + descriptorSets[INDEX_LIGHT_CULLING]->updateBuffer(0, oLightIndexList); + descriptorSets[INDEX_LIGHT_CULLING]->updateBuffer(1, tLightIndexList); + descriptorSets[INDEX_LIGHT_CULLING]->updateTexture(2, oLightGrid); + descriptorSets[INDEX_LIGHT_CULLING]->updateTexture(3, tLightGrid); + descriptorSets[INDEX_LIGHT_CULLING]->writeChanges(); graphics->beginRenderPass(renderPass); - for (const auto& meshBatch : passData.staticDrawList) + Gfx::ShaderPermutation permutation; + permutation.hasFragment = true; + permutation.useMeshShading = true; + permutation.hasTaskShader = true; + std::memcpy(permutation.taskFile, "MeshletBasePass", std::strlen("MeshletBasePass")); + std::memcpy(permutation.vertexMeshFile, "MeshletBasePass", std::strlen("MeshletBasePass")); + std::memcpy(permutation.fragmentFile, "BasePass", std::strlen("BasePass")); + for (VertexData* vertexData : VertexData::getList()) { - processor->processMeshBatch(meshBatch, viewport, renderPass, basePassLayout, primitiveLayout, descriptorSets); + std::memcpy(permutation.vertexDataName, vertexData->getTypeName().c_str(), std::strlen(vertexData->getTypeName().c_str())); + const auto& materials = vertexData->getMaterialData(); + for (const auto& [_, materialData] : materials) + { + // Create Pipeline(Material, VertexData) + // Descriptors: + // ViewData => global, static + // LightEnv => global, static + // LightCulling => global, static + // Material => per material + // VertexData => per meshtype + // SceneData => per material instance + + std::memcpy(permutation.materialName, materialData.material->getName().c_str(), std::strlen(materialData.material->getName().c_str())); + Gfx::PermutationId id(permutation); + + Gfx::PRenderCommand command = graphics->createRenderCommand("DepthRender"); + Gfx::OPipelineLayout layout = graphics->createPipelineLayout(basePassLayout); + layout->addDescriptorLayout(INDEX_MATERIAL, materialData.material->getDescriptorLayout()); + layout->addDescriptorLayout(INDEX_VERTEX_DATA, vertexData->getVertexDataLayout()); + layout->addDescriptorLayout(INDEX_SCENE_DATA, vertexData->getInstanceDataLayout()); + layout->create(); + + const Gfx::ShaderCollection* collection = graphics->getShaderCompiler()->findShaders(id); + assert(collection != nullptr); + Gfx::MeshPipelineCreateInfo pipelineInfo; + pipelineInfo.taskShader = collection->taskShader; + pipelineInfo.meshShader = collection->meshShader; + pipelineInfo.fragmentShader = collection->fragmentShader; + pipelineInfo.pipelineLayout = layout; + pipelineInfo.renderPass = renderPass; + pipelineInfo.depthStencilState.depthCompareOp = Gfx::SE_COMPARE_OP_LESS_OR_EQUAL; + Gfx::PGraphicsPipeline pipeline = graphics->createGraphicsPipeline(pipelineInfo); + command->bindPipeline(pipeline); + + descriptorSets[INDEX_VERTEX_DATA] = vertexData->getVertexDataSet(); + for (const auto& [_, instance] : materialData.instances) + { + descriptorSets[INDEX_MATERIAL] = instance.materialInstance->getDescriptorSet(); + descriptorSets[INDEX_SCENE_DATA] = instance.descriptorSet; + command->bindDescriptor(descriptorSets); + command->dispatch(instance.numMeshes, 1, 1); + } + } } - graphics->executeCommands(processor->getRenderCommands()); graphics->endRenderPass(); - //std::cout << "BasePass render()" << std::endl; - //co_return; } void BasePass::endFrame() { - //std::cout << "BasePass endFrame()" << std::endl; - //co_return; } void BasePass::publishOutputs() @@ -131,16 +144,14 @@ void BasePass::createRenderPass() depthAttachment->loadOp = Gfx::SE_ATTACHMENT_LOAD_OP_LOAD; colorAttachment->loadOp = Gfx::SE_ATTACHMENT_LOAD_OP_CLEAR; colorAttachment->storeOp = Gfx::SE_ATTACHMENT_STORE_OP_STORE; - Gfx::PRenderTargetLayout layout = new Gfx::RenderTargetLayout(colorAttachment, depthAttachment); - renderPass = graphics->createRenderPass(layout, viewport); + Gfx::ORenderTargetLayout layout = new Gfx::RenderTargetLayout(colorAttachment, depthAttachment); + renderPass = graphics->createRenderPass(std::move(layout), viewport); oLightIndexList = resources->requestBuffer("LIGHTCULLING_OLIGHTLIST"); + tLightIndexList = resources->requestBuffer("LIGHTCULLING_TLIGHTLIST"); oLightGrid = resources->requestTexture("LIGHTCULLING_OLIGHTGRID"); + tLightGrid = resources->requestTexture("LIGHTCULLING_TLIGHTGRID"); } void BasePass::modifyRenderPassMacros(Map& defines) { - defines["INDEX_LIGHT_ENV"] = "0"; - defines["INDEX_VIEW_PARAMS"] = "1"; - defines["INDEX_MATERIAL"] = "2"; - defines["INDEX_SCENE_DATA"] = "3"; } diff --git a/src/Engine/Graphics/RenderPass/BasePass.h b/src/Engine/Graphics/RenderPass/BasePass.h index 5cb739a..a4c0ed2 100644 --- a/src/Engine/Graphics/RenderPass/BasePass.h +++ b/src/Engine/Graphics/RenderPass/BasePass.h @@ -9,6 +9,8 @@ class BasePass : public RenderPass { public: BasePass(Gfx::PGraphics graphics, PScene scene); + BasePass(BasePass&&) = default; + BasePass& operator=(BasePass&&) = default; virtual ~BasePass(); virtual void beginFrame(const Component::Camera& cam) override; virtual void render() override; @@ -19,24 +21,26 @@ public: private: Gfx::PRenderTargetAttachment colorAttachment; Gfx::PTexture2D depthBuffer; + Gfx::PShaderBuffer oLightIndexList; + Gfx::PShaderBuffer tLightIndexList; + Gfx::PTexture2D oLightGrid; + Gfx::PTexture2D tLightGrid; Array descriptorSets; PCameraActor source; Gfx::OPipelineLayout basePassLayout; - // Set 0: Light environment - static constexpr uint32 INDEX_LIGHT_ENV = 0; - Gfx::OShaderBuffer oLightIndexList; - Gfx::OTexture oLightGrid; - Gfx::ODescriptorLayout lightLayout; - // Set 1: viewParameter - static constexpr uint32 INDEX_VIEW_PARAMS = 1; - Gfx::ODescriptorLayout viewLayout; - Gfx::OUniformBuffer viewParamBuffer; - // Set 2: materials, generated - static constexpr uint32 INDEX_MATERIAL = 2; - // Set 3: primitive scene data - static constexpr uint32 INDEX_SCENE_DATA = 3; - Gfx::ODescriptorLayout sceneLayout; + // Set 0: viewParameter, provided by renderpass + // Set 1: light environment, provided by lightenv + static constexpr uint32 INDEX_LIGHT_ENV = 1; + // Set 2: light culling data + static constexpr uint32 INDEX_LIGHT_CULLING = 2; + Gfx::ODescriptorLayout lightCullingLayout; + // Set 3: material data, generated from material + static constexpr uint32 INDEX_MATERIAL = 3; + // Set 4: vertex buffers, provided by vertexdata + static constexpr uint32 INDEX_VERTEX_DATA = 4; + // Set 5: instance data, provided by vertexdata + static constexpr uint32 INDEX_SCENE_DATA = 5; }; DEFINE_REF(BasePass) } // namespace Seele diff --git a/src/Engine/Graphics/RenderPass/CMakeLists.txt b/src/Engine/Graphics/RenderPass/CMakeLists.txt index 8a20ec3..d721e48 100644 --- a/src/Engine/Graphics/RenderPass/CMakeLists.txt +++ b/src/Engine/Graphics/RenderPass/CMakeLists.txt @@ -12,6 +12,7 @@ target_sources(Engine RenderGraphResources.h RenderGraphResources.cpp RenderPass.h + RenderPass.cpp SkyboxRenderPass.h SkyboxRenderPass.cpp TextPass.h diff --git a/src/Engine/Graphics/RenderPass/DebugPass.cpp b/src/Engine/Graphics/RenderPass/DebugPass.cpp index c0f2fd8..e0dc0bf 100644 --- a/src/Engine/Graphics/RenderPass/DebugPass.cpp +++ b/src/Engine/Graphics/RenderPass/DebugPass.cpp @@ -16,128 +16,129 @@ void Seele::addDebugVertices(Array verts) gDebugVertices.addAll(verts); } -DebugPass::DebugPass(Gfx::PGraphics graphics) - : RenderPass(graphics) -{ - -} -DebugPass::~DebugPass() -{ - -} - -void DebugPass::beginFrame(const Component::Camera& cam) -{ - DataSource uniformUpdate; - - viewParams.viewMatrix = cam.getViewMatrix(); - viewParams.projectionMatrix = viewport->getProjectionMatrix(); - viewParams.cameraPosition = Vector4(cam.getCameraPosition(), 1); - viewParams.screenDimensions = Vector2(static_cast(viewport->getSizeX()), static_cast(viewport->getSizeY())); - uniformUpdate.size = sizeof(ViewParameter); - uniformUpdate.data = (uint8*)&viewParams; - viewParamsBuffer->updateContents(uniformUpdate); - descriptorLayout->reset(); - descriptorSet = descriptorLayout->allocateDescriptorSet(); - descriptorSet->updateBuffer(0, viewParamsBuffer); - descriptorSet->writeChanges(); - - VertexBufferCreateInfo vertexBufferInfo = { - .sourceData = { - .size = sizeof(DebugVertex) * passData.vertices.size(), - .data = (uint8*)passData.vertices.data(), - }, - .vertexSize = sizeof(DebugVertex), - .numVertices = (uint32)passData.vertices.size(), - }; - debugVertices = graphics->createVertexBuffer(vertexBufferInfo); - -} - -void DebugPass::render() -{ - graphics->beginRenderPass(renderPass); - Gfx::PRenderCommand renderCommand = graphics->createRenderCommand("DebugRender"); - renderCommand->setViewport(viewport); - renderCommand->bindPipeline(pipeline); - renderCommand->bindDescriptor(descriptorSet); - renderCommand->bindVertexBuffer({VertexInputStream(0, 0, debugVertices)}); - renderCommand->draw((uint32)passData.vertices.size(), 1, 0, 0); - graphics->executeCommands(Array{renderCommand}); - graphics->endRenderPass(); -} - -void DebugPass::endFrame() -{ - -} - -void DebugPass::publishOutputs() -{ - UniformBufferCreateInfo viewCreateInfo = { - .sourceData = DataSource { - .size = sizeof(ViewParameter), - .data = nullptr, - }, - .bDynamic = true - }; - viewParamsBuffer = graphics->createUniformBuffer(viewCreateInfo); - - descriptorLayout = graphics->createDescriptorLayout("DebugDescLayout"); - descriptorLayout->addDescriptorBinding(0, Gfx::SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER); - descriptorLayout->create(); - - pipelineLayout = graphics->createPipelineLayout(); - pipelineLayout->addDescriptorLayout(0, descriptorLayout); - pipelineLayout->create(); -} - -void DebugPass::createRenderPass() -{ - Gfx::PRenderTargetAttachment baseColorAttachment = resources->requestRenderTarget("BASEPASS_COLOR"); - baseColorAttachment->loadOp = Gfx::SE_ATTACHMENT_LOAD_OP_LOAD; - Gfx::PRenderTargetAttachment depthAttachment = resources->requestRenderTarget("DEPTHPREPASS_DEPTH"); - depthAttachment->loadOp = Gfx::SE_ATTACHMENT_LOAD_OP_LOAD; - Gfx::PRenderTargetLayout layout = new Gfx::RenderTargetLayout(baseColorAttachment, depthAttachment); - renderPass = graphics->createRenderPass(layout, viewport); - - ShaderCreateInfo createInfo; - createInfo.name = "DebugVertex"; - createInfo.mainModule = "Debug"; - createInfo.entryPoint = "vertexMain"; - createInfo.defines["INDEX_VIEW_PARAMS"] = "0"; - Gfx::PVertexShader vertexShader = graphics->createVertexShader(createInfo); - - createInfo.name = "DebugFragment"; - - createInfo.entryPoint = "fragmentMain"; - Gfx::PFragmentShader fragmentShader = graphics->createFragmentShader(createInfo); - - Gfx::PVertexDeclaration vertexDecl = graphics->createVertexDeclaration({ - Gfx::VertexElement { - .streamIndex = 0, - .offset = offsetof(DebugVertex, position), - .vertexFormat = Gfx::SE_FORMAT_R32G32B32_SFLOAT, - .attributeIndex = 0, - .stride = sizeof(DebugVertex), - }, - Gfx::VertexElement { - .streamIndex = 0, - .offset = offsetof(DebugVertex, color), - .vertexFormat = Gfx::SE_FORMAT_R32G32B32_SFLOAT, - .attributeIndex = 1, - .stride = sizeof(DebugVertex), - } - }); - - GraphicsPipelineCreateInfo gfxInfo; - gfxInfo.vertexDeclaration = vertexDecl; - gfxInfo.vertexShader = vertexShader; - gfxInfo.fragmentShader = fragmentShader; - gfxInfo.rasterizationState.polygonMode = Gfx::SE_POLYGON_MODE_LINE; - gfxInfo.rasterizationState.lineWidth = 5.f; - gfxInfo.topology = Gfx::SE_PRIMITIVE_TOPOLOGY_LINE_LIST; - gfxInfo.pipelineLayout = pipelineLayout; - gfxInfo.renderPass = renderPass; - pipeline = graphics->createGraphicsPipeline(gfxInfo); -} +//DebugPass::DebugPass(Gfx::PGraphics graphics, PScene scene) +// : RenderPass(graphics, scene) +//{ +// +//} +//DebugPass::~DebugPass() +//{ +// +//} +// +//void DebugPass::beginFrame(const Component::Camera& cam) +//{ +// RenderPass::beginFrame(cam); +// DataSource uniformUpdate; +// +// viewParams.viewMatrix = cam.getViewMatrix(); +// viewParams.projectionMatrix = viewport->getProjectionMatrix(); +// viewParams.cameraPosition = Vector4(cam.getCameraPosition(), 1); +// viewParams.screenDimensions = Vector2(static_cast(viewport->getSizeX()), static_cast(viewport->getSizeY())); +// uniformUpdate.size = sizeof(ViewParameter); +// uniformUpdate.data = (uint8*)&viewParams; +// viewParamsBuffer->updateContents(uniformUpdate); +// descriptorLayout->reset(); +// descriptorSet = descriptorLayout->allocateDescriptorSet(); +// descriptorSet->updateBuffer(0, viewParamsBuffer); +// descriptorSet->writeChanges(); +// +// VertexBufferCreateInfo vertexBufferInfo = { +// .sourceData = { +// .size = sizeof(DebugVertex) * passData.vertices.size(), +// .data = (uint8*)passData.vertices.data(), +// }, +// .vertexSize = sizeof(DebugVertex), +// .numVertices = (uint32)passData.vertices.size(), +// }; +// debugVertices = graphics->createVertexBuffer(vertexBufferInfo); +// +//} +// +//void DebugPass::render() +//{ +// graphics->beginRenderPass(renderPass); +// Gfx::PRenderCommand renderCommand = graphics->createRenderCommand("DebugRender"); +// renderCommand->setViewport(viewport); +// renderCommand->bindPipeline(pipeline); +// renderCommand->bindDescriptor(descriptorSet); +// renderCommand->bindVertexBuffer({VertexInputStream(0, 0, debugVertices)}); +// renderCommand->draw((uint32)passData.vertices.size(), 1, 0, 0); +// graphics->executeCommands(Array{renderCommand}); +// graphics->endRenderPass(); +//} +// +//void DebugPass::endFrame() +//{ +// +//} +// +//void DebugPass::publishOutputs() +//{ +// UniformBufferCreateInfo viewCreateInfo = { +// .sourceData = DataSource { +// .size = sizeof(ViewParameter), +// .data = nullptr, +// }, +// .dynamic = true +// }; +// viewParamsBuffer = graphics->createUniformBuffer(viewCreateInfo); +// +// descriptorLayout = graphics->createDescriptorLayout("DebugDescLayout"); +// descriptorLayout->addDescriptorBinding(0, Gfx::SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER); +// descriptorLayout->create(); +// +// pipelineLayout = graphics->createPipelineLayout(); +// pipelineLayout->addDescriptorLayout(0, descriptorLayout); +// pipelineLayout->create(); +//} +// +//void DebugPass::createRenderPass() +//{ +// Gfx::PRenderTargetAttachment baseColorAttachment = resources->requestRenderTarget("BASEPASS_COLOR"); +// baseColorAttachment->loadOp = Gfx::SE_ATTACHMENT_LOAD_OP_LOAD; +// Gfx::PRenderTargetAttachment depthAttachment = resources->requestRenderTarget("DEPTHPREPASS_DEPTH"); +// depthAttachment->loadOp = Gfx::SE_ATTACHMENT_LOAD_OP_LOAD; +// Gfx::PRenderTargetLayout layout = new Gfx::RenderTargetLayout(baseColorAttachment, depthAttachment); +// renderPass = graphics->createRenderPass(layout, viewport); +// +// ShaderCreateInfo createInfo; +// createInfo.name = "DebugVertex"; +// createInfo.mainModule = "Debug"; +// createInfo.entryPoint = "vertexMain"; +// createInfo.defines["INDEX_VIEW_PARAMS"] = "0"; +// Gfx::PVertexShader vertexShader = graphics->createVertexShader(createInfo); +// +// createInfo.name = "DebugFragment"; +// +// createInfo.entryPoint = "fragmentMain"; +// Gfx::PFragmentShader fragmentShader = graphics->createFragmentShader(createInfo); +// +// Gfx::PVertexDeclaration vertexDecl = graphics->createVertexDeclaration({ +// Gfx::VertexElement { +// .streamIndex = 0, +// .offset = offsetof(DebugVertex, position), +// .vertexFormat = Gfx::SE_FORMAT_R32G32B32_SFLOAT, +// .attributeIndex = 0, +// .stride = sizeof(DebugVertex), +// }, +// Gfx::VertexElement { +// .streamIndex = 0, +// .offset = offsetof(DebugVertex, color), +// .vertexFormat = Gfx::SE_FORMAT_R32G32B32_SFLOAT, +// .attributeIndex = 1, +// .stride = sizeof(DebugVertex), +// } +// }); +// +// GraphicsPipelineCreateInfo gfxInfo; +// gfxInfo.vertexDeclaration = vertexDecl; +// gfxInfo.vertexShader = vertexShader; +// gfxInfo.fragmentShader = fragmentShader; +// gfxInfo.rasterizationState.polygonMode = Gfx::SE_POLYGON_MODE_LINE; +// gfxInfo.rasterizationState.lineWidth = 5.f; +// gfxInfo.topology = Gfx::SE_PRIMITIVE_TOPOLOGY_LINE_LIST; +// gfxInfo.pipelineLayout = pipelineLayout; +// gfxInfo.renderPass = renderPass; +// pipeline = graphics->createGraphicsPipeline(gfxInfo); +//} diff --git a/src/Engine/Graphics/RenderPass/DebugPass.h b/src/Engine/Graphics/RenderPass/DebugPass.h index 382cadf..2f7218a 100644 --- a/src/Engine/Graphics/RenderPass/DebugPass.h +++ b/src/Engine/Graphics/RenderPass/DebugPass.h @@ -11,7 +11,9 @@ DECLARE_REF(Viewport) class DebugPass : public RenderPass { public: - DebugPass(Gfx::PGraphics graphics); + DebugPass(Gfx::PGraphics graphics, PScene scene); + DebugPass(DebugPass&&) = default; + DebugPass& operator=(DebugPass&&) = default; virtual ~DebugPass(); virtual void beginFrame(const Component::Camera& cam) override; virtual void render() override; @@ -19,12 +21,12 @@ public: virtual void publishOutputs() override; virtual void createRenderPass() override; private: - Gfx::PVertexBuffer debugVertices; - Gfx::PUniformBuffer viewParamsBuffer; - Gfx::PDescriptorLayout descriptorLayout; + Gfx::OVertexBuffer debugVertices; + Gfx::OUniformBuffer viewParamsBuffer; + Gfx::ODescriptorLayout descriptorLayout; Gfx::PDescriptorSet descriptorSet; - Gfx::PPipelineLayout pipelineLayout; - Gfx::PGraphicsPipeline pipeline; + Gfx::OPipelineLayout pipelineLayout; + Gfx::OGraphicsPipeline pipeline; }; DEFINE_REF(DebugPass) } // namespace Seele diff --git a/src/Engine/Graphics/RenderPass/DepthPrepass.cpp b/src/Engine/Graphics/RenderPass/DepthPrepass.cpp index e1f2380..4a73e80 100644 --- a/src/Engine/Graphics/RenderPass/DepthPrepass.cpp +++ b/src/Engine/Graphics/RenderPass/DepthPrepass.cpp @@ -1,5 +1,6 @@ #include "DepthPrepass.h" #include "Graphics/Graphics.h" +#include "Graphics/Shader.h" #include "Window/Window.h" #include "Component/Camera.h" #include "Component/Mesh.h" @@ -16,15 +17,7 @@ DepthPrepass::DepthPrepass(Gfx::PGraphics graphics, PScene scene) UniformBufferCreateInfo uniformInitializer; depthPrepassLayout = graphics->createPipelineLayout(); - - viewLayout = graphics->createDescriptorLayout("ViewLayout"); - viewLayout->addDescriptorBinding(0, Gfx::SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER); - uniformInitializer.sourceData.size = sizeof(ViewParameter); - uniformInitializer.sourceData.data = (uint8*)&viewParams; - uniformInitializer.bDynamic = true; - viewParamBuffer = graphics->createUniformBuffer(uniformInitializer); - viewLayout->create(); - depthPrepassLayout->addDescriptorLayout(INDEX_VIEW_PARAMS, viewLayout); + depthPrepassLayout->addDescriptorLayout(INDEX_VIEW_PARAMS, viewParamsLayout); } DepthPrepass::~DepthPrepass() @@ -33,22 +26,8 @@ DepthPrepass::~DepthPrepass() void DepthPrepass::beginFrame(const Component::Camera& cam) { - DataSource uniformUpdate; - - viewParams.viewMatrix = cam.getViewMatrix(); - viewParams.projectionMatrix = viewport->getProjectionMatrix(); - viewParams.cameraPosition = Vector4(cam.getCameraPosition(), 1); - viewParams.screenDimensions = Vector2(static_cast(viewport->getSizeX()), static_cast(viewport->getSizeY())); - uniformUpdate.size = sizeof(ViewParameter); - uniformUpdate.data = (uint8*)&viewParams; - viewParamBuffer->updateContents(uniformUpdate); - viewLayout->reset(); - descriptorSets[INDEX_VIEW_PARAMS] = viewLayout->allocateDescriptorSet(); - descriptorSets[INDEX_VIEW_PARAMS]->updateBuffer(0, viewParamBuffer); - descriptorSets[INDEX_VIEW_PARAMS]->writeChanges(); - - //std::cout << "DepthPrepass beginFrame()" << std::endl; - //co_return; + RenderPass::beginFrame(cam); + descriptorSets[INDEX_VIEW_PARAMS] = viewParamsSet; } void DepthPrepass::render() @@ -57,9 +36,16 @@ void DepthPrepass::render() Gfx::SE_ACCESS_SHADER_READ_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT, Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT); depthAttachment->getTexture()->transferOwnership(Gfx::QueueType::GRAPHICS); + Gfx::ShaderPermutation permutation; + permutation.hasFragment = false; + permutation.useMeshShading = true; + permutation.hasTaskShader = true; + std::memcpy(permutation.taskFile, "MeshletBasePass", sizeof("MeshletBasePass")); + std::memcpy(permutation.vertexMeshFile, "MeshletBasePass", sizeof("MeshletBasePass")); graphics->beginRenderPass(renderPass); for (VertexData* vertexData : VertexData::getList()) { + std::memcpy(permutation.vertexDataName, vertexData->getTypeName().c_str(), std::strlen(vertexData->getTypeName().c_str())); const auto& materials = vertexData->getMaterialData(); for (const auto& [_, materialData] : materials) { @@ -69,6 +55,9 @@ void DepthPrepass::render() // Material => per material // VertexData => per meshtype // SceneData => per material instance + std::memcpy(permutation.materialName, materialData.material->getName().c_str(), std::strlen(materialData.material->getName().c_str())); + Gfx::PermutationId id(permutation); + Gfx::PRenderCommand command = graphics->createRenderCommand("DepthRender"); Gfx::OPipelineLayout layout = graphics->createPipelineLayout(depthPrepassLayout); layout->addDescriptorLayout(INDEX_MATERIAL, materialData.material->getDescriptorLayout()); @@ -91,14 +80,10 @@ void DepthPrepass::render() } } graphics->endRenderPass(); - //std::cout << "DepthPrepass render()" << std::endl; - //co_return; } void DepthPrepass::endFrame() { - //std::cout << "DepthPrepass endFrame()" << std::endl; - //co_return; } void DepthPrepass::publishOutputs() @@ -119,8 +104,8 @@ void DepthPrepass::publishOutputs() void DepthPrepass::createRenderPass() { - Gfx::PRenderTargetLayout layout = new Gfx::RenderTargetLayout(depthAttachment); - renderPass = graphics->createRenderPass(layout, viewport); + Gfx::ORenderTargetLayout layout = new Gfx::RenderTargetLayout(depthAttachment); + renderPass = graphics->createRenderPass(std::move(layout), viewport); } void DepthPrepass::modifyRenderPassMacros(Map& defines) diff --git a/src/Engine/Graphics/RenderPass/DepthPrepass.h b/src/Engine/Graphics/RenderPass/DepthPrepass.h index ab88717..9ce581f 100644 --- a/src/Engine/Graphics/RenderPass/DepthPrepass.h +++ b/src/Engine/Graphics/RenderPass/DepthPrepass.h @@ -8,7 +8,9 @@ class DepthPrepass : public RenderPass { public: DepthPrepass(Gfx::PGraphics graphics, PScene scene); - ~DepthPrepass(); + DepthPrepass(DepthPrepass&&) = default; + DepthPrepass& operator=(DepthPrepass&&) = default; + virtual ~DepthPrepass(); virtual void beginFrame(const Component::Camera& cam) override; virtual void render() override; virtual void endFrame() override; @@ -23,15 +25,12 @@ private: Gfx::OPipelineLayout depthPrepassLayout; // Set 0: viewParameter - static constexpr uint32 INDEX_VIEW_PARAMS = 0; - Gfx::ODescriptorLayout viewLayout; - Gfx::OUniformBuffer viewParamBuffer; // Set 1: materials, generated - static constexpr uint32 INDEX_MATERIAL = 1; + constexpr static uint32 INDEX_MATERIAL = 1; // Set 2: vertices, from VertexData - static constexpr uint32 INDEX_VERTEX_DATA = 2; + constexpr static uint32 INDEX_VERTEX_DATA = 2; // Set 3: mesh data, either index buffer or meshlet data - static constexpr uint32 INDEX_SCENE_DATA = 3; + constexpr static uint32 INDEX_SCENE_DATA = 3; Gfx::ODescriptorLayout sceneDataLayout; }; DEFINE_REF(DepthPrepass) diff --git a/src/Engine/Graphics/RenderPass/LightCullingPass.cpp b/src/Engine/Graphics/RenderPass/LightCullingPass.cpp index a73155c..fbd96cb 100644 --- a/src/Engine/Graphics/RenderPass/LightCullingPass.cpp +++ b/src/Engine/Graphics/RenderPass/LightCullingPass.cpp @@ -19,46 +19,30 @@ LightCullingPass::~LightCullingPass() void LightCullingPass::beginFrame(const Component::Camera& cam) { + RenderPass::beginFrame(cam); uint32_t viewportWidth = viewport->getSizeX(); uint32_t viewportHeight = viewport->getSizeY(); - DataSource uniformUpdate; - viewParams.viewMatrix = cam.getViewMatrix(); - viewParams.projectionMatrix = viewport->getProjectionMatrix(); - viewParams.cameraPosition = Vector4(cam.getCameraPosition(), 1); - viewParams.screenDimensions = Vector2(static_cast(viewportWidth), static_cast(viewportHeight)); - uniformUpdate.size = sizeof(ViewParameter); - uniformUpdate.data = (uint8*)&viewParams; - viewParamsBuffer->updateContents(uniformUpdate); - - DataSource counterReset; uint32 reset = 0; - counterReset.data = (uint8*)&reset; - counterReset.size = sizeof(uint32); + DataSource counterReset = { + .size = sizeof(uint32), + .data = (uint8*)&reset, + }; oLightIndexCounter->updateContents(counterReset); tLightIndexCounter->updateContents(counterReset); cullingDescriptorLayout->reset(); - lightEnvDescriptorLayout->reset(); cullingDescriptorSet = cullingDescriptorLayout->allocateDescriptorSet(); - lightEnvDescriptorSet = lightEnvDescriptorLayout->allocateDescriptorSet(); - cullingDescriptorSet->updateBuffer(0, viewParamsBuffer); - cullingDescriptorSet->updateBuffer(1, dispatchParamsBuffer); - cullingDescriptorSet->updateBuffer(3, oLightIndexCounter); - cullingDescriptorSet->updateBuffer(4, tLightIndexCounter); - cullingDescriptorSet->updateBuffer(5, oLightIndexList); - cullingDescriptorSet->updateBuffer(6, tLightIndexList); - cullingDescriptorSet->updateTexture(7, oLightGrid); - cullingDescriptorSet->updateTexture(8, tLightGrid); - cullingDescriptorSet->updateBuffer(9, frustumBuffer); - - - lightEnvDescriptorSet->updateBuffer(0, passData.lightEnv.directionalLights); - lightEnvDescriptorSet->updateBuffer(1, passData.lightEnv.numDirectional); - lightEnvDescriptorSet->updateBuffer(2, passData.lightEnv.pointLights); - lightEnvDescriptorSet->updateBuffer(3, passData.lightEnv.numPoints); - lightEnvDescriptorSet->writeChanges(); + cullingDescriptorSet->updateBuffer(0, dispatchParamsBuffer); + cullingDescriptorSet->updateTexture(1, depthAttachment); + cullingDescriptorSet->updateBuffer(2, oLightIndexCounter); + cullingDescriptorSet->updateBuffer(3, tLightIndexCounter); + cullingDescriptorSet->updateBuffer(4, oLightIndexList); + cullingDescriptorSet->updateBuffer(5, tLightIndexList); + cullingDescriptorSet->updateTexture(6, Gfx::PTexture2D(oLightGrid)); + cullingDescriptorSet->updateTexture(7, Gfx::PTexture2D(tLightGrid)); + cullingDescriptorSet->updateBuffer(8, frustumBuffer); //std::cout << "LightCulling beginFrame()" << std::endl; //co_return; } @@ -80,9 +64,8 @@ void LightCullingPass::render() cullingDescriptorSet->writeChanges(); Gfx::PComputeCommand computeCommand = graphics->createComputeCommand("CullingCommand"); computeCommand->bindPipeline(cullingPipeline); - Array descriptorSets = {cullingDescriptorSet, lightEnvDescriptorSet}; - computeCommand->bindDescriptor(descriptorSets); - //computeCommand->dispatch(dispatchParams.numThreadGroups.x, dispatchParams.numThreadGroups.y, dispatchParams.numThreadGroups.z); + computeCommand->bindDescriptor({ viewParamsSet, lightEnv->getDescriptorSet(), cullingDescriptorSet }); + computeCommand->dispatch(dispatchParams.numThreadGroups.x, dispatchParams.numThreadGroups.y, dispatchParams.numThreadGroups.z); Array commands = {computeCommand}; graphics->executeCommands(commands); depthAttachment->changeLayout(Gfx::SE_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL); @@ -105,42 +88,41 @@ void LightCullingPass::publishOutputs() glm::uvec3 numThreadGroups = glm::ceil(glm::vec3(viewportWidth / (float)BLOCK_SIZE, viewportHeight / (float)BLOCK_SIZE, 1)); dispatchParams.numThreadGroups = numThreadGroups; dispatchParams.numThreads = numThreadGroups * glm::uvec3(BLOCK_SIZE, BLOCK_SIZE, 1); + dispatchParamsBuffer = graphics->createUniformBuffer(UniformBufferCreateInfo{ + .sourceData = { + .size = sizeof(DispatchParams), + .data = (uint8*)&dispatchParams, + }, + .dynamic = false, + }); cullingDescriptorLayout = graphics->createDescriptorLayout("CullingLayout"); - //ViewParams + // Dispatchparams cullingDescriptorLayout->addDescriptorBinding(0, Gfx::SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER); - //Dispatchparams - cullingDescriptorLayout->addDescriptorBinding(1, Gfx::SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER); //DepthTexture - cullingDescriptorLayout->addDescriptorBinding(2, Gfx::SE_DESCRIPTOR_TYPE_SAMPLED_IMAGE); + cullingDescriptorLayout->addDescriptorBinding(1, Gfx::SE_DESCRIPTOR_TYPE_SAMPLED_IMAGE); //o_lightIndexCounter - cullingDescriptorLayout->addDescriptorBinding(3, Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER); + cullingDescriptorLayout->addDescriptorBinding(2, Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER); //t_lightIndexCounter - cullingDescriptorLayout->addDescriptorBinding(4, Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER); + cullingDescriptorLayout->addDescriptorBinding(3, Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER); //o_lightIndexList - cullingDescriptorLayout->addDescriptorBinding(5, Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER); + cullingDescriptorLayout->addDescriptorBinding(4, Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER); //t_lightIndexList - cullingDescriptorLayout->addDescriptorBinding(6, Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER); + cullingDescriptorLayout->addDescriptorBinding(5, Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER); //o_lightGrid - cullingDescriptorLayout->addDescriptorBinding(7, Gfx::SE_DESCRIPTOR_TYPE_STORAGE_IMAGE); + cullingDescriptorLayout->addDescriptorBinding(6, Gfx::SE_DESCRIPTOR_TYPE_STORAGE_IMAGE); //t_lightGrid - cullingDescriptorLayout->addDescriptorBinding(8, Gfx::SE_DESCRIPTOR_TYPE_STORAGE_IMAGE); + cullingDescriptorLayout->addDescriptorBinding(7, Gfx::SE_DESCRIPTOR_TYPE_STORAGE_IMAGE); //Frustums - cullingDescriptorLayout->addDescriptorBinding(9, Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER, viewportWidth * viewportHeight); + cullingDescriptorLayout->addDescriptorBinding(8, Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER, viewportWidth * viewportHeight); - - lightEnvDescriptorLayout = graphics->createDescriptorLayout("LightEnv"); - // Directional Lights - lightEnvDescriptorLayout->addDescriptorBinding(0, Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER, MAX_DIRECTIONAL_LIGHTS); - lightEnvDescriptorLayout->addDescriptorBinding(1, Gfx::SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER); - // Point Lights - lightEnvDescriptorLayout->addDescriptorBinding(2, Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER, MAX_POINT_LIGHTS); - lightEnvDescriptorLayout->addDescriptorBinding(3, Gfx::SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER); + lightEnv = scene->getLightEnvironment(); cullingLayout = graphics->createPipelineLayout(); - cullingLayout->addDescriptorLayout(0, cullingDescriptorLayout); - cullingLayout->addDescriptorLayout(1, lightEnvDescriptorLayout); + cullingLayout->addDescriptorLayout(0, viewParamsLayout); + cullingLayout->addDescriptorLayout(1, lightEnv->getDescriptorLayout()); + cullingLayout->addDescriptorLayout(2, cullingDescriptorLayout); cullingLayout->create(); ShaderCreateInfo createInfo; @@ -148,9 +130,6 @@ void LightCullingPass::publishOutputs() createInfo.mainModule = "LightCulling"; createInfo.entryPoint = "cullLights"; - createInfo.defines["INDEX_VIEW_PARAMS"] = "0"; - createInfo.defines["INDEX_LIGHT_ENV"] = "1"; - createInfo.defines["NUM_MATERIAL_TEXCOORDS"] = "0"; cullingShader = graphics->createComputeShader(createInfo); Gfx::ComputePipelineCreateInfo pipelineInfo; @@ -167,7 +146,7 @@ void LightCullingPass::publishOutputs() .owner = Gfx::QueueType::COMPUTE, }, .stride = sizeof(uint32), - .bDynamic = true, + .dynamic = true, }; oLightIndexCounter = graphics->createShaderBuffer(structInfo); tLightIndexCounter = graphics->createShaderBuffer(structInfo); @@ -181,7 +160,7 @@ void LightCullingPass::publishOutputs() .owner = Gfx::QueueType::COMPUTE }, .stride = sizeof(uint32), - .bDynamic = false, + .dynamic = false, }; oLightIndexList = graphics->createShaderBuffer(structInfo); tLightIndexList = graphics->createShaderBuffer(structInfo); @@ -197,8 +176,8 @@ void LightCullingPass::publishOutputs() oLightGrid = graphics->createTexture2D(textureInfo); tLightGrid = graphics->createTexture2D(textureInfo); - resources->registerTextureOutput("LIGHTCULLING_OLIGHTGRID", oLightGrid); - resources->registerTextureOutput("LIGHTCULLING_TLIGHTGRID", tLightGrid); + resources->registerTextureOutput("LIGHTCULLING_OLIGHTGRID", Gfx::PTexture2D(oLightGrid)); + resources->registerTextureOutput("LIGHTCULLING_TLIGHTGRID", Gfx::PTexture2D(tLightGrid)); } @@ -219,28 +198,22 @@ void LightCullingPass::setupFrustums() glm::uvec3 numThreads = glm::ceil(glm::vec3(viewportWidth / (float)BLOCK_SIZE, viewportHeight / (float)BLOCK_SIZE, 1)); glm::uvec3 numThreadGroups = glm::ceil(glm::vec3(numThreads.x / (float)BLOCK_SIZE, numThreads.y / (float)BLOCK_SIZE, 1)); - viewParams = { - .viewMatrix = Matrix4(), - .projectionMatrix = Matrix4(), - .cameraPosition = Vector4(), - .screenDimensions = glm::vec2(viewportWidth, viewportHeight), - }; + RenderPass::beginFrame(Component::Camera()); dispatchParams.numThreads = numThreads; dispatchParams.numThreadGroups = numThreadGroups; - Gfx::PDescriptorLayout frustumDescriptorLayout = graphics->createDescriptorLayout("FrustumLayout"); + Gfx::ODescriptorLayout frustumDescriptorLayout = graphics->createDescriptorLayout("FrustumLayout"); frustumDescriptorLayout->addDescriptorBinding(0, Gfx::SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER); - frustumDescriptorLayout->addDescriptorBinding(1, Gfx::SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER); - frustumDescriptorLayout->addDescriptorBinding(2, Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER); + frustumDescriptorLayout->addDescriptorBinding(1, Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER); frustumLayout = graphics->createPipelineLayout(); - frustumLayout->addDescriptorLayout(0, frustumDescriptorLayout); + frustumLayout->addDescriptorLayout(0, viewParamsLayout); + frustumLayout->addDescriptorLayout(1, frustumDescriptorLayout); frustumLayout->create(); ShaderCreateInfo createInfo; createInfo.name = "Frustum"; createInfo.mainModule = "ComputeFrustums"; createInfo.entryPoint = "computeFrustums"; - createInfo.defines["INDEX_VIEW_PARAMS"] = "0"; frustumShader = graphics->createComputeShader(createInfo); Gfx::ComputePipelineCreateInfo pipelineInfo; @@ -248,40 +221,31 @@ void LightCullingPass::setupFrustums() pipelineInfo.pipelineLayout = frustumLayout; frustumPipeline = graphics->createComputePipeline(pipelineInfo); - DataSource resourceInfo; - UniformBufferCreateInfo uniformInfo; - resourceInfo.size = sizeof(ViewParameter); - resourceInfo.data = (uint8*)&viewParams; - resourceInfo.owner = Gfx::QueueType::COMPUTE; - uniformInfo.sourceData = resourceInfo; - uniformInfo.bDynamic = false; - viewParamsBuffer = graphics->createUniformBuffer(uniformInfo); - - resourceInfo.size = sizeof(DispatchParams); - resourceInfo.data = (uint8*)&dispatchParams; - uniformInfo.sourceData = resourceInfo; - uniformInfo.bDynamic = false; - dispatchParamsBuffer = graphics->createUniformBuffer(uniformInfo); - - ShaderBufferCreateInfo structuredInfo = { + Gfx::OUniformBuffer frustumDispatchParamsBuffer = graphics->createUniformBuffer(UniformBufferCreateInfo{ + .sourceData = { + .size = sizeof(DispatchParams), + .data = (uint8*) & dispatchParams, + }, + .dynamic = false, + }); + + frustumBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{ .sourceData = { .size = sizeof(Frustum) * numThreads.x * numThreads.y * numThreads.z, .data = nullptr, }, .stride = sizeof(Frustum), - .bDynamic = false, - }; - frustumBuffer = graphics->createShaderBuffer(structuredInfo); + .dynamic = false, + }); frustumDescriptorSet = frustumDescriptorLayout->allocateDescriptorSet(); - frustumDescriptorSet->updateBuffer(0, viewParamsBuffer); - frustumDescriptorSet->updateBuffer(1, dispatchParamsBuffer); - frustumDescriptorSet->updateBuffer(2, frustumBuffer); + frustumDescriptorSet->updateBuffer(0, frustumDispatchParamsBuffer); + frustumDescriptorSet->updateBuffer(1, frustumBuffer); frustumDescriptorSet->writeChanges(); Gfx::PComputeCommand command = graphics->createComputeCommand("FrustumCommand"); command->bindPipeline(frustumPipeline); - command->bindDescriptor(frustumDescriptorSet); + command->bindDescriptor({ viewParamsSet, frustumDescriptorSet }); command->dispatch(numThreadGroups.x, numThreadGroups.y, numThreadGroups.z); Array commands = {command}; graphics->executeCommands(commands); diff --git a/src/Engine/Graphics/RenderPass/LightCullingPass.h b/src/Engine/Graphics/RenderPass/LightCullingPass.h index a8c80fd..ce0b174 100644 --- a/src/Engine/Graphics/RenderPass/LightCullingPass.h +++ b/src/Engine/Graphics/RenderPass/LightCullingPass.h @@ -12,6 +12,8 @@ class LightCullingPass : public RenderPass { public: LightCullingPass(Gfx::PGraphics graphics, PScene scene); + LightCullingPass(LightCullingPass&&) = default; + LightCullingPass& operator=(LightCullingPass&&) = default; virtual ~LightCullingPass(); virtual void beginFrame(const Component::Camera& cam) override; virtual void render() override; @@ -39,30 +41,29 @@ private: { Plane planes[4]; }; - - Gfx::PShaderBuffer frustumBuffer; - Gfx::PUniformBuffer dispatchParamsBuffer; - Gfx::PUniformBuffer viewParamsBuffer; - Gfx::PDescriptorSet frustumDescriptorSet; - Gfx::PComputeShader frustumShader; - Gfx::PPipelineLayout frustumLayout; - Gfx::PComputePipeline frustumPipeline; + Gfx::OShaderBuffer frustumBuffer; + Gfx::OUniformBuffer dispatchParamsBuffer; + Gfx::OUniformBuffer viewParamsBuffer; + Gfx::PDescriptorSet frustumDescriptorSet; + Gfx::OComputeShader frustumShader; + Gfx::OPipelineLayout frustumLayout; + Gfx::OComputePipeline frustumPipeline; + + PLightEnvironment lightEnv; Gfx::PTexture2D depthAttachment; - Gfx::PShaderBuffer frustums; - Gfx::PShaderBuffer oLightIndexCounter; - Gfx::PShaderBuffer tLightIndexCounter; - Gfx::PShaderBuffer oLightIndexList; - Gfx::PShaderBuffer tLightIndexList; - Gfx::PTexture2D oLightGrid; - Gfx::PTexture2D tLightGrid; - Gfx::PDescriptorSet lightEnvDescriptorSet; + Gfx::OShaderBuffer frustums; + Gfx::OShaderBuffer oLightIndexCounter; + Gfx::OShaderBuffer tLightIndexCounter; + Gfx::OShaderBuffer oLightIndexList; + Gfx::OShaderBuffer tLightIndexList; + Gfx::OTexture2D oLightGrid; + Gfx::OTexture2D tLightGrid; Gfx::PDescriptorSet cullingDescriptorSet; - Gfx::PDescriptorLayout lightEnvDescriptorLayout; - Gfx::PDescriptorLayout cullingDescriptorLayout; - Gfx::PComputeShader cullingShader; - Gfx::PPipelineLayout cullingLayout; - Gfx::PComputePipeline cullingPipeline; + Gfx::ODescriptorLayout cullingDescriptorLayout; + Gfx::OComputeShader cullingShader; + Gfx::OPipelineLayout cullingLayout; + Gfx::OComputePipeline cullingPipeline; }; DEFINE_REF(LightCullingPass) } // namespace Seele diff --git a/src/Engine/Graphics/RenderPass/RenderGraph.h b/src/Engine/Graphics/RenderPass/RenderGraph.h index 172ab52..50ebb77 100644 --- a/src/Engine/Graphics/RenderPass/RenderGraph.h +++ b/src/Engine/Graphics/RenderPass/RenderGraph.h @@ -24,7 +24,7 @@ template class RenderGraph : private RenderGraph { public: - RenderGraph(PRenderGraphResources resources, This&& pass, Rest&&... rest) + RenderGraph(PRenderGraphResources resources, This pass, Rest... rest) : RenderGraph(resources, std::move(rest)...) , resources(resources) , rp(std::move(pass)) @@ -83,7 +83,7 @@ class RenderGraphBuilder { public: template - static RenderGraph build(RenderPasses&&... renderPasses) + static RenderGraph build(RenderPasses... renderPasses) { PRenderGraphResources resources = new RenderGraphResources(); return RenderGraph(resources, std::move(renderPasses)...); diff --git a/src/Engine/Graphics/RenderPass/RenderPass.cpp b/src/Engine/Graphics/RenderPass/RenderPass.cpp new file mode 100644 index 0000000..d58db43 --- /dev/null +++ b/src/Engine/Graphics/RenderPass/RenderPass.cpp @@ -0,0 +1,54 @@ +#include "RenderPass.h" + +using namespace Seele; + +RenderPass::RenderPass(Gfx::PGraphics graphics, PScene scene) + : graphics(graphics) + , scene(scene) +{ + + viewParamsLayout = graphics->createDescriptorLayout("ViewLayout"); + viewParamsLayout->addDescriptorBinding(0, Gfx::SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER); + UniformBufferCreateInfo uniformInitializer = { + .sourceData = { + .size = sizeof(ViewParameter), + .data = (uint8*)&viewParams, + }, + .dynamic = true, + }; + viewParamsBuffer = graphics->createUniformBuffer(uniformInitializer); + viewParamsLayout->create(); +} + +RenderPass::~RenderPass() +{} + +void RenderPass::beginFrame(const Component::Camera& cam) +{ + viewParams = { + .viewMatrix = cam.getViewMatrix(), + .projectionMatrix = viewport->getProjectionMatrix(), + .cameraPosition = Vector4(cam.getCameraPosition(), 1), + .screenDimensions = Vector2(static_cast(viewport->getSizeX()), static_cast(viewport->getSizeY())), + }; + DataSource uniformUpdate = { + .size = sizeof(ViewParameter), + .data = (uint8*)&viewParams, + }; + viewParamsBuffer->updateContents(uniformUpdate); + viewParamsLayout->reset(); + viewParamsSet = viewParamsLayout->allocateDescriptorSet(); + viewParamsSet->updateBuffer(0, viewParamsBuffer); + viewParamsSet->writeChanges(); +} + +void RenderPass::setResources(PRenderGraphResources _resources) +{ + resources = _resources; +} + +void RenderPass::setViewport(Gfx::PViewport _viewport) +{ + viewport = _viewport; + publishOutputs(); +} \ No newline at end of file diff --git a/src/Engine/Graphics/RenderPass/RenderPass.h b/src/Engine/Graphics/RenderPass/RenderPass.h index 663fa13..4f2b398 100644 --- a/src/Engine/Graphics/RenderPass/RenderPass.h +++ b/src/Engine/Graphics/RenderPass/RenderPass.h @@ -15,23 +15,17 @@ DECLARE_NAME_REF(Gfx, RenderPass) class RenderPass { public: - RenderPass(Gfx::PGraphics graphics, PScene scene) - : graphics(graphics) - , scene(scene) - {} - virtual ~RenderPass() - {} - virtual void beginFrame(const Component::Camera& cam) = 0; + RenderPass(Gfx::PGraphics graphics, PScene scene); + RenderPass(RenderPass&&) = default; + RenderPass& operator=(RenderPass&&) = default; + virtual ~RenderPass(); + virtual void beginFrame(const Component::Camera& cam); virtual void render() = 0; virtual void endFrame() = 0; virtual void publishOutputs() = 0; virtual void createRenderPass() = 0; - void setResources(PRenderGraphResources _resources) { resources = _resources; } - void setViewport(Gfx::PViewport _viewport) - { - viewport = _viewport; - publishOutputs(); - } + void setResources(PRenderGraphResources _resources); + void setViewport(Gfx::PViewport _viewport); protected: struct ViewParameter { @@ -42,7 +36,11 @@ protected: Vector2 pad0; } viewParams; PRenderGraphResources resources; - Gfx::PRenderPass renderPass; + static constexpr uint32 INDEX_VIEW_PARAMS = 0; + Gfx::ODescriptorLayout viewParamsLayout; + Gfx::OShaderBuffer viewParamsBuffer; + Gfx::PDescriptorSet viewParamsSet; + Gfx::ORenderPass renderPass; Gfx::PGraphics graphics; Gfx::PViewport viewport; PScene scene; diff --git a/src/Engine/Graphics/RenderPass/SkyboxRenderPass.cpp b/src/Engine/Graphics/RenderPass/SkyboxRenderPass.cpp index 5cadae6..1802fa6 100644 --- a/src/Engine/Graphics/RenderPass/SkyboxRenderPass.cpp +++ b/src/Engine/Graphics/RenderPass/SkyboxRenderPass.cpp @@ -86,6 +86,7 @@ SkyboxRenderPass::~SkyboxRenderPass() void SkyboxRenderPass::beginFrame(const Component::Camera& cam) { + RenderPass::beginFrame(cam); DataSource uniformUpdate; viewParams.viewMatrix = cam.getViewMatrix(); @@ -131,7 +132,7 @@ void SkyboxRenderPass::publishOutputs() .size = sizeof(ViewParameter), .data = nullptr, }, - .bDynamic = true + .dynamic = true }; viewParamsBuffer = graphics->createUniformBuffer(viewCreateInfo); @@ -161,8 +162,8 @@ void SkyboxRenderPass::createRenderPass() baseColorAttachment->loadOp = Gfx::SE_ATTACHMENT_LOAD_OP_LOAD; Gfx::PRenderTargetAttachment depthAttachment = resources->requestRenderTarget("DEPTHPREPASS_DEPTH"); depthAttachment->loadOp = Gfx::SE_ATTACHMENT_LOAD_OP_LOAD; - Gfx::PRenderTargetLayout layout = new Gfx::RenderTargetLayout(baseColorAttachment, depthAttachment); - renderPass = graphics->createRenderPass(layout, viewport); + Gfx::ORenderTargetLayout layout = new Gfx::RenderTargetLayout(baseColorAttachment, depthAttachment); + renderPass = graphics->createRenderPass(std::move(layout), viewport); ShaderCreateInfo createInfo; createInfo.name = "SkyboxVertex"; diff --git a/src/Engine/Graphics/RenderPass/SkyboxRenderPass.h b/src/Engine/Graphics/RenderPass/SkyboxRenderPass.h index c83c2da..822696c 100644 --- a/src/Engine/Graphics/RenderPass/SkyboxRenderPass.h +++ b/src/Engine/Graphics/RenderPass/SkyboxRenderPass.h @@ -12,6 +12,8 @@ class SkyboxRenderPass : public RenderPass { public: SkyboxRenderPass(Gfx::PGraphics graphics, PScene scene); + SkyboxRenderPass(SkyboxRenderPass&&) = default; + SkyboxRenderPass& operator=(SkyboxRenderPass&&) = default; virtual ~SkyboxRenderPass(); virtual void beginFrame(const Component::Camera& cam) override; virtual void render() override; @@ -19,13 +21,13 @@ public: virtual void publishOutputs() override; virtual void createRenderPass() override; private: - Gfx::PVertexBuffer cubeBuffer; - Gfx::PUniformBuffer viewParamsBuffer; - Gfx::PDescriptorLayout descriptorLayout; + Gfx::OVertexBuffer cubeBuffer; + Gfx::OUniformBuffer viewParamsBuffer; + Gfx::ODescriptorLayout descriptorLayout; Gfx::PDescriptorSet descriptorSet; - Gfx::PPipelineLayout pipelineLayout; - Gfx::PGraphicsPipeline pipeline; - Gfx::PSamplerState skyboxSampler; + Gfx::OPipelineLayout pipelineLayout; + Gfx::OGraphicsPipeline pipeline; + Gfx::OSamplerState skyboxSampler; Component::Skybox skybox; }; DEFINE_REF(SkyboxRenderPass) diff --git a/src/Engine/Graphics/RenderPass/TextPass.cpp b/src/Engine/Graphics/RenderPass/TextPass.cpp index a9b77fe..d051e13 100644 --- a/src/Engine/Graphics/RenderPass/TextPass.cpp +++ b/src/Engine/Graphics/RenderPass/TextPass.cpp @@ -15,8 +15,9 @@ TextPass::~TextPass() } -void TextPass::beginFrame(const Component::Camera&) +void TextPass::beginFrame(const Component::Camera& cam) { + RenderPass::beginFrame(cam); for(TextRender& render : texts) { FontData& fd = getFontData(render.font); @@ -126,7 +127,7 @@ void TextPass::createRenderPass() .vertexFormat = Gfx::SE_FORMAT_R32G32_SFLOAT, .attributeIndex = 0, .stride = sizeof(GlyphInstanceData), - .bInstanced = 1 + .instanced = 1 }); elements.add({ .binding = 0, @@ -134,7 +135,7 @@ void TextPass::createRenderPass() .vertexFormat = Gfx::SE_FORMAT_R32G32_SFLOAT, .attributeIndex = 1, .stride = sizeof(GlyphInstanceData), - .bInstanced = 1 + .instanced = 1 }); elements.add({ .binding = 0, @@ -142,7 +143,7 @@ void TextPass::createRenderPass() .vertexFormat = Gfx::SE_FORMAT_R32_UINT, .attributeIndex = 2, .stride = sizeof(GlyphInstanceData), - .bInstanced = 1 + .instanced = 1 }); declaration = graphics->createVertexDeclaration(elements); @@ -160,7 +161,7 @@ void TextPass::createRenderPass() .size = sizeof(Matrix4), .data = nullptr, }, - .bDynamic = true, + .dynamic = true, }); glyphSampler = graphics->createSamplerState({ @@ -184,8 +185,8 @@ void TextPass::createRenderPass() .size = sizeof(TextData)}); pipelineLayout->create(); - Gfx::PRenderTargetLayout layout = new Gfx::RenderTargetLayout(renderTarget, depthAttachment); - renderPass = graphics->createRenderPass(layout, viewport); + Gfx::ORenderTargetLayout layout = new Gfx::RenderTargetLayout(renderTarget, depthAttachment); + renderPass = graphics->createRenderPass(std::move(layout), viewport); Gfx::LegacyPipelineCreateInfo pipelineInfo; pipelineInfo.vertexDeclaration = declaration; @@ -229,6 +230,7 @@ TextPass::FontData& TextPass::getFontData(PFontAsset font) } fd.glyphDataSet = glyphData; + textureArrayLayout->reset(); fd.textureArraySet = textureArrayLayout->allocateDescriptorSet(); fd.textureArraySet->updateTextureArray(0, textures); fd.textureArraySet->writeChanges(); diff --git a/src/Engine/Graphics/RenderPass/TextPass.h b/src/Engine/Graphics/RenderPass/TextPass.h index d3ca9c1..8b54143 100644 --- a/src/Engine/Graphics/RenderPass/TextPass.h +++ b/src/Engine/Graphics/RenderPass/TextPass.h @@ -21,6 +21,8 @@ class TextPass : public RenderPass { public: TextPass(Gfx::PGraphics graphics, PScene scene); + TextPass(TextPass&&) = default; + TextPass& operator=(TextPass&&) = default; virtual ~TextPass(); virtual void beginFrame(const Component::Camera& cam) override; virtual void render() override; @@ -65,19 +67,19 @@ private: Gfx::PRenderTargetAttachment renderTarget; Gfx::PRenderTargetAttachment depthAttachment; - Gfx::PDescriptorLayout generalLayout; - Gfx::PDescriptorLayout textureArrayLayout; + Gfx::ODescriptorLayout generalLayout; + Gfx::ODescriptorLayout textureArrayLayout; Gfx::PDescriptorSet generalSet; - Gfx::PUniformBuffer projectionBuffer; - Gfx::PSamplerState glyphSampler; + Gfx::OUniformBuffer projectionBuffer; + Gfx::OSamplerState glyphSampler; - Gfx::PVertexDeclaration declaration; - Gfx::PVertexShader vertexShader; - Gfx::PFragmentShader fragmentShader; - Gfx::PPipelineLayout pipelineLayout; - Gfx::PGraphicsPipeline pipeline; + Gfx::OVertexDeclaration declaration; + Gfx::OVertexShader vertexShader; + Gfx::OFragmentShader fragmentShader; + Gfx::OPipelineLayout pipelineLayout; + Gfx::OGraphicsPipeline pipeline; Array texts; }; DEFINE_REF(TextPass); diff --git a/src/Engine/Graphics/RenderPass/UIPass.cpp b/src/Engine/Graphics/RenderPass/UIPass.cpp index 13ea809..a5cf8d0 100644 --- a/src/Engine/Graphics/RenderPass/UIPass.cpp +++ b/src/Engine/Graphics/RenderPass/UIPass.cpp @@ -15,8 +15,9 @@ UIPass::~UIPass() } -void UIPass::beginFrame(const Component::Camera&) +void UIPass::beginFrame(const Component::Camera& cam) { + RenderPass::beginFrame(cam); VertexBufferCreateInfo info = { .sourceData = { .size = (uint32)(sizeof(UI::RenderElementStyle) * renderElements.size()), @@ -103,7 +104,7 @@ void UIPass::createRenderPass() .vertexFormat = Gfx::SE_FORMAT_R32G32B32_SFLOAT, .attributeIndex = 0, .stride = sizeof(UI::RenderElementStyle), - .bInstanced = 1 + .instanced = 1 }); decl.add({ .binding = 0, @@ -111,7 +112,7 @@ void UIPass::createRenderPass() .vertexFormat = Gfx::SE_FORMAT_R32_UINT, .attributeIndex = 1, .stride = sizeof(UI::RenderElementStyle), - .bInstanced = 1 + .instanced = 1 }); decl.add({ .binding = 0, @@ -119,7 +120,7 @@ void UIPass::createRenderPass() .vertexFormat = Gfx::SE_FORMAT_R32G32B32_SFLOAT, .attributeIndex = 2, .stride = sizeof(UI::RenderElementStyle), - .bInstanced = 1 + .instanced = 1 }); decl.add({ .binding = 0, @@ -127,7 +128,7 @@ void UIPass::createRenderPass() .vertexFormat = Gfx::SE_FORMAT_R32_SFLOAT, .attributeIndex = 3, .stride = sizeof(UI::RenderElementStyle), - .bInstanced = 1 + .instanced = 1 }); decl.add({ .binding = 0, @@ -135,7 +136,7 @@ void UIPass::createRenderPass() .vertexFormat = Gfx::SE_FORMAT_R32G32_SFLOAT, .attributeIndex = 4, .stride = sizeof(UI::RenderElementStyle), - .bInstanced = 1 + .instanced = 1 }); declaration = graphics->createVertexDeclaration(decl); @@ -152,7 +153,7 @@ void UIPass::createRenderPass() .size = sizeof(Matrix4), .data = (uint8*)&projectionMatrix, }, - .bDynamic = false, + .dynamic = false, }; Gfx::PUniformBuffer uniformBuffer = graphics->createUniformBuffer(info); Gfx::PSamplerState backgroundSampler = graphics->createSamplerState({}); @@ -162,7 +163,7 @@ void UIPass::createRenderPass() .size = sizeof(uint32), .data = nullptr }, - .bDynamic = true, + .dynamic = true, }; numTexturesBuffer = graphics->createUniformBuffer(info); @@ -176,8 +177,8 @@ void UIPass::createRenderPass() pipelineLayout->addDescriptorLayout(0, descriptorLayout); pipelineLayout->create(); - Gfx::PRenderTargetLayout layout = new Gfx::RenderTargetLayout(renderTarget, depthAttachment); - renderPass = graphics->createRenderPass(layout, viewport); + Gfx::ORenderTargetLayout layout = new Gfx::RenderTargetLayout(std::move(renderTarget), std::move(depthAttachment)); + renderPass = graphics->createRenderPass(std::move(layout), viewport); Gfx::LegacyPipelineCreateInfo pipelineInfo; pipelineInfo.vertexDeclaration = declaration; diff --git a/src/Engine/Graphics/RenderPass/UIPass.h b/src/Engine/Graphics/RenderPass/UIPass.h index 477852d..e72e2b5 100644 --- a/src/Engine/Graphics/RenderPass/UIPass.h +++ b/src/Engine/Graphics/RenderPass/UIPass.h @@ -11,6 +11,8 @@ class UIPass : public RenderPass { public: UIPass(Gfx::PGraphics graphics, PScene scene); + UIPass(UIPass&&) = default; + UIPass& operator=(UIPass&&) = default; virtual ~UIPass(); virtual void beginFrame(const Component::Camera& cam) override; virtual void render() override; @@ -24,7 +26,7 @@ private: Gfx::OTexture2D depthBuffer; Gfx::ODescriptorLayout descriptorLayout; - Gfx::ODescriptorSet descriptorSet; + Gfx::PDescriptorSet descriptorSet; Gfx::OUniformBuffer numTexturesBuffer; Gfx::OVertexBuffer elementBuffer; diff --git a/src/Engine/Graphics/RenderTarget.cpp b/src/Engine/Graphics/RenderTarget.cpp index 690953c..c00456e 100644 --- a/src/Engine/Graphics/RenderTarget.cpp +++ b/src/Engine/Graphics/RenderTarget.cpp @@ -8,38 +8,40 @@ RenderTargetLayout::RenderTargetLayout() : inputAttachments() , colorAttachments() , depthAttachment() + , width(0) + , height(0) { } -RenderTargetLayout::RenderTargetLayout(ORenderTargetAttachment depthAttachment) +RenderTargetLayout::RenderTargetLayout(PRenderTargetAttachment depthAttachment) : inputAttachments() , colorAttachments() - , depthAttachment(std::move(depthAttachment)) + , depthAttachment(depthAttachment) , width(depthAttachment->getTexture()->getSizeX()) , height(depthAttachment->getTexture()->getSizeY()) { } -RenderTargetLayout::RenderTargetLayout(ORenderTargetAttachment colorAttachment, ORenderTargetAttachment depthAttachment) +RenderTargetLayout::RenderTargetLayout(PRenderTargetAttachment colorAttachment, PRenderTargetAttachment depthAttachment) : inputAttachments() - , depthAttachment(std::move(depthAttachment)) + , depthAttachment(depthAttachment) , width(depthAttachment->getTexture()->getSizeX()) , height(depthAttachment->getTexture()->getSizeY()) { colorAttachments.add(colorAttachment); } -RenderTargetLayout::RenderTargetLayout(Array colorAttachments, ORenderTargetAttachment depthAttachment) +RenderTargetLayout::RenderTargetLayout(Array colorAttachments, PRenderTargetAttachment depthAttachment) : inputAttachments() - , colorAttachments(std::move(colorAttachments)) - , depthAttachment(std::move(depthAttachment)) + , colorAttachments(colorAttachments) + , depthAttachment(depthAttachment) , width(depthAttachment->getTexture()->getSizeX()) , height(depthAttachment->getTexture()->getSizeY()) { } -RenderTargetLayout::RenderTargetLayout(Array inputAttachments, Array colorAttachments, ORenderTargetAttachment depthAttachment) - : inputAttachments(std::move(inputAttachments)) - , colorAttachments(std::move(colorAttachments)) - , depthAttachment(std::move(depthAttachment)) +RenderTargetLayout::RenderTargetLayout(Array inputAttachments, Array colorAttachments, PRenderTargetAttachment depthAttachment) + : inputAttachments(inputAttachments) + , colorAttachments(colorAttachments) + , depthAttachment(depthAttachment) , width(depthAttachment->getTexture()->getSizeX()) , height(depthAttachment->getTexture()->getSizeY()) { diff --git a/src/Engine/Graphics/RenderTarget.h b/src/Engine/Graphics/RenderTarget.h index 97d6291..5eafb8a 100644 --- a/src/Engine/Graphics/RenderTarget.h +++ b/src/Engine/Graphics/RenderTarget.h @@ -167,13 +167,13 @@ class RenderTargetLayout { public: RenderTargetLayout(); - RenderTargetLayout(ORenderTargetAttachment depthAttachment); - RenderTargetLayout(ORenderTargetAttachment colorAttachment, ORenderTargetAttachment depthAttachment); - RenderTargetLayout(Array colorAttachments, ORenderTargetAttachment depthAttachmet); - RenderTargetLayout(Array inputAttachments, Array colorAttachments, ORenderTargetAttachment depthAttachment); - Array inputAttachments; - Array colorAttachments; - ORenderTargetAttachment depthAttachment; + RenderTargetLayout(PRenderTargetAttachment depthAttachment); + RenderTargetLayout(PRenderTargetAttachment colorAttachment, PRenderTargetAttachment depthAttachment); + RenderTargetLayout(Array colorAttachments, PRenderTargetAttachment depthAttachmet); + RenderTargetLayout(Array inputAttachments, Array colorAttachments, PRenderTargetAttachment depthAttachment); + Array inputAttachments; + Array colorAttachments; + PRenderTargetAttachment depthAttachment; uint32 width; uint32 height; }; @@ -184,7 +184,9 @@ class RenderPass public: RenderPass(ORenderTargetLayout layout) : layout(std::move(layout)) {} virtual ~RenderPass() {} - inline PRenderTargetLayout getLayout() { return layout; } + RenderPass(RenderPass&&) = default; + RenderPass& operator=(RenderPass&&) = default; + PRenderTargetLayout getLayout() const { return layout; } protected: ORenderTargetLayout layout; diff --git a/src/Engine/Graphics/Resources.cpp b/src/Engine/Graphics/Resources.cpp index 9009cf2..9758ac7 100644 --- a/src/Engine/Graphics/Resources.cpp +++ b/src/Engine/Graphics/Resources.cpp @@ -1,9 +1,12 @@ -#include "GraphicsResources.h" +#include "Resources.h" #include "Graphics.h" #include "RenderPass/DepthPrepass.h" #include "RenderPass/BasePass.h" #include "Material/Material.h" +using namespace Seele; +using namespace Seele::Gfx; + QueueOwnedResource::QueueOwnedResource(QueueFamilyMapping mapping, QueueType startQueueType) : currentOwner(startQueueType) , mapping(mapping) diff --git a/src/Engine/Graphics/Resources.h b/src/Engine/Graphics/Resources.h index 5554944..a8d69a7 100644 --- a/src/Engine/Graphics/Resources.h +++ b/src/Engine/Graphics/Resources.h @@ -83,7 +83,7 @@ class VertexDeclaration { public: VertexDeclaration(); - ~VertexDeclaration(); + virtual ~VertexDeclaration(); static PVertexDeclaration createDeclaration(PGraphics graphics, const Array& elementList); private: @@ -126,7 +126,7 @@ public: virtual void bindIndexBuffer(Gfx::PIndexBuffer indexBuffer) = 0; virtual void pushConstants(Gfx::PPipelineLayout layout, Gfx::SeShaderStageFlags stage, uint32 offset, uint32 size, const void* data) = 0; virtual void draw(uint32 vertexCount, uint32 instanceCount, int32 firstVertex, uint32 firstInstance) = 0; - virtual void dispatch(uint32 groupX, uint32 groupY, uint32 groupZ); + virtual void dispatch(uint32 groupX, uint32 groupY, uint32 groupZ) = 0; std::string name; }; DEFINE_REF(RenderCommand) diff --git a/src/Engine/Graphics/Shader.cpp b/src/Engine/Graphics/Shader.cpp index fd12844..484c72d 100644 --- a/src/Engine/Graphics/Shader.cpp +++ b/src/Engine/Graphics/Shader.cpp @@ -5,89 +5,125 @@ using namespace Seele; using namespace Seele::Gfx; -std::string getShaderNameFromRenderPassType(Gfx::RenderPassType type) -{ - switch (type) - { - case Gfx::RenderPassType::DepthPrepass: - return "DepthPrepass"; - case Gfx::RenderPassType::BasePass: - return "ForwardPlus"; - default: - return ""; - } -} -void modifyRenderPassMacros(Gfx::RenderPassType type, Map& defines) -{ - switch (type) - { - case Gfx::RenderPassType::DepthPrepass: - DepthPrepass::modifyRenderPassMacros(defines); - break; - case Gfx::RenderPassType::BasePass: - BasePass::modifyRenderPassMacros(defines); - break; - } -} - -ShaderMap::ShaderMap() +ShaderCompiler::ShaderCompiler(Gfx::PGraphics graphics) + : graphics(graphics) { } -ShaderMap::~ShaderMap() +ShaderCompiler::~ShaderCompiler() { } -const ShaderCollection* ShaderMap::findShaders(PermutationId&& id) const +const ShaderCollection* ShaderCompiler::findShaders(PermutationId id) const { - for (uint32 i = 0; i < shaders.size(); ++i) + return &shaders[id]; +} + +void ShaderCompiler::registerMaterial(PMaterial material) +{ + materials[material->getName()] = material; + compile(); +} + +void ShaderCompiler::registerVertexData(VertexData* vd) +{ + vertexData[vd->getTypeName()] = vd; + compile(); +} + +void ShaderCompiler::registerRenderPass(std::string name, std::string mainFile, bool useMaterials, bool hasFragmentShader, std::string fragmentFile, bool useMeshShading, bool hasTaskShader, std::string taskFile) +{ + passes[name] = PassConfig{ + .taskFile = taskFile, + .mainFile = mainFile, + .fragmentFile = fragmentFile, + .hasFragmentShader = hasFragmentShader, + .useMeshShading = useMeshShading, + .hasTaskShader = hasTaskShader, + .useMaterial = useMaterials, + }; + compile(); +} + + +void ShaderCompiler::compile() +{ + ShaderPermutation permutation; + for (const auto& [name, pass] : passes) { - if (shaders[i].id == id) + std::memset(&permutation, 0, sizeof(ShaderPermutation)); + permutation = { + .hasFragment = pass.hasFragmentShader, + .useMeshShading = pass.useMeshShading, + .hasTaskShader = pass.hasTaskShader, + }; + std::memcpy(permutation.vertexMeshFile, pass.mainFile.c_str(), sizeof(permutation.vertexMeshFile)); + if (pass.hasFragmentShader) { - return &(shaders[i]); + std::memcpy(permutation.fragmentFile, pass.fragmentFile.c_str(), sizeof(permutation.fragmentFile)); + } + if (pass.hasTaskShader) + { + std::memcpy(permutation.taskFile, pass.taskFile.c_str(), sizeof(permutation.taskFile)); + } + for (const auto& [vdName, vd] : vertexData) + { + std::memcpy(permutation.vertexDataName, vd->getTypeName().c_str(), sizeof(permutation.vertexDataName)); + if (pass.useMaterial) + { + for (const auto& [matName, mat] : materials) + { + std::memcpy(permutation.materialName, matName.c_str(), sizeof(permutation.materialName)); + createShaders(permutation); + } + } + else + { + std::memset(permutation.materialName, 0, sizeof(permutation.materialName)); + createShaders(permutation); + } } } - return nullptr; } -ShaderCollection& ShaderMap::createShaders( - PGraphics graphics, - RenderPassType renderPass, - PMaterial material, - bool /*bPositionOnly*/) + +ShaderCollection& ShaderCompiler::createShaders(ShaderPermutation permutation) { std::scoped_lock lock(shadersLock); - ShaderCollection& collection = shaders.add(); - //collection.vertexDeclaration = bPositionOnly ? vertexInput->getPositionDeclaration() : vertexInput->getDeclaration(); + ShaderCollection collection; ShaderCreateInfo createInfo; - createInfo.entryPoint = "vertexMain"; - createInfo.typeParameter = { material->getName().c_str() }; - createInfo.defines["NUM_MATERIAL_TEXCOORDS"] = "1"; - createInfo.defines["USE_INSTANCING"] = "0"; - modifyRenderPassMacros(renderPass, createInfo.defines); - createInfo.name = getShaderNameFromRenderPassType(renderPass) + " Material " + material->getName(); + createInfo.typeParameter = { permutation.materialName, permutation.vertexDataName }; + createInfo.name = std::format("Material {0}", permutation.materialName); + createInfo.additionalModules.add(permutation.materialName); + createInfo.additionalModules.add(permutation.vertexDataName); - std::ifstream codeStream("./shaders/" + getShaderNameFromRenderPassType(renderPass)); - - createInfo.mainModule = getShaderNameFromRenderPassType(renderPass); - createInfo.additionalModules.add(vertexInput->getShaderFilename()); - createInfo.additionalModules.add(material->getName()); - - collection.vertexShader = graphics->createVertexShader(createInfo); - - if (renderPass != RenderPassType::DepthPrepass) + if (permutation.useMeshShading) { - createInfo.entryPoint = "fragmentMain"; + if (permutation.hasTaskShader) + { + createInfo.mainModule = permutation.taskFile; + createInfo.entryPoint = "taskMain"; + collection.taskShader = graphics->createTaskShader(createInfo); + } + createInfo.mainModule = permutation.vertexMeshFile; + createInfo.entryPoint = "meshMain"; + collection.meshShader = graphics->createMeshShader(createInfo); + } + else + { + createInfo.mainModule = permutation.vertexMeshFile; + createInfo.entryPoint = "vertexMain"; + collection.vertexShader = graphics->createVertexShader(createInfo); + } + if (permutation.hasFragment) + { + createInfo.mainModule = permutation.fragmentFile; + createInfo.entryPoint = "fragmentMain"; collection.fragmentShader = graphics->createFragmentShader(createInfo); } - ShaderPermutation permutation; - std::string materialName = material->getName(); - std::string vertexInputName = vertexInput->getName(); - permutation.passType = renderPass; - std::memcpy(permutation.materialName, materialName.c_str(), sizeof(permutation.materialName)); - std::memcpy(permutation.vertexInputName, vertexInputName.c_str(), sizeof(permutation.vertexInputName)); - collection.id = PermutationId(permutation); + PermutationId perm = PermutationId(permutation); + shaders[perm] = std::move(collection); - return collection; + return shaders[perm]; } \ No newline at end of file diff --git a/src/Engine/Graphics/Shader.h b/src/Engine/Graphics/Shader.h index 1bc9168..2f765b4 100644 --- a/src/Engine/Graphics/Shader.h +++ b/src/Engine/Graphics/Shader.h @@ -2,6 +2,7 @@ #include "Enums.h" #include "CRC.h" #include "Resources.h" +#include "VertexData.h" namespace Seele { @@ -52,9 +53,14 @@ DEFINE_REF(ComputeShader) //using the type parameters used to generate it struct ShaderPermutation { - RenderPassType passType; - char vertexInputName[15]; - char materialName[16]; + char taskFile[32]; + char vertexMeshFile[32]; + char fragmentFile[32]; + char vertexDataName[32]; + char materialName[32]; + uint8 hasFragment : 1; + uint8 useMeshShading : 1; + uint8 hasTaskShader : 1; //TODO: lightmapping etc }; //Hashed ShaderPermutation for fast lookup @@ -67,47 +73,59 @@ struct PermutationId PermutationId(ShaderPermutation permutation) : hash(CRC::Calculate(&permutation, sizeof(ShaderPermutation), CRC::CRC_32())) {} - friend inline bool operator==(const PermutationId& lhs, const PermutationId& rhs) + friend constexpr bool operator==(const PermutationId& lhs, const PermutationId& rhs) { return lhs.hash == rhs.hash; } - friend inline bool operator!=(const PermutationId& lhs, const PermutationId& rhs) + friend constexpr auto operator<=>(const PermutationId& lhs, const PermutationId& rhs) { - return lhs.hash != rhs.hash; - } - friend inline bool operator<(const PermutationId& lhs, const PermutationId& rhs) - { - return lhs.hash < rhs.hash; - } - friend inline bool operator>(const PermutationId& lhs, const PermutationId& rhs) - { - return lhs.hash > rhs.hash; + return lhs.hash <=> rhs.hash; } }; struct ShaderCollection { - PermutationId id; - OVertexDeclaration vertexDeclaration; OVertexShader vertexShader; OTaskShader taskShader; OMeshShader meshShader; OFragmentShader fragmentShader; }; -class ShaderMap +class ShaderCompiler { public: - ShaderMap(); - ~ShaderMap(); - const ShaderCollection* findShaders(PermutationId&& id) const; - ShaderCollection& createShaders( - PGraphics graphics, - RenderPassType passName, - bool bPositionOnly); + ShaderCompiler(Gfx::PGraphics graphics); + ~ShaderCompiler(); + const ShaderCollection* findShaders(PermutationId id) const; + void registerMaterial(PMaterial material); + void registerVertexData(VertexData* vertexData); + void registerRenderPass(std::string name, + std::string mainFile, + bool useMaterials = false, + bool hasFragmentShader = false, + std::string fragmentFile = "", + bool useMeshShading = false, + bool hasTaskShader = false, + std::string taskFile = ""); private: + void compile(); + ShaderCollection& createShaders(ShaderPermutation permutation); std::mutex shadersLock; - Array shaders; + Map shaders; + Map materials; + Map vertexData; + struct PassConfig + { + std::string taskFile; + std::string mainFile; + std::string fragmentFile; + bool hasFragmentShader; + bool useMeshShading; + bool hasTaskShader; + bool useMaterial; + }; + Map passes; + Gfx::PGraphics graphics; }; -DEFINE_REF(ShaderMap) +DEFINE_REF(ShaderCompiler) } } // namespace Seele \ No newline at end of file diff --git a/src/Engine/Graphics/ShaderCompiler.cpp b/src/Engine/Graphics/ShaderCompiler.cpp deleted file mode 100644 index e5d44cb..0000000 --- a/src/Engine/Graphics/ShaderCompiler.cpp +++ /dev/null @@ -1,18 +0,0 @@ -#include "ShaderCompiler.h" -#include "Graphics.h" - -using namespace Seele; -using namespace Seele::Gfx; - -ShaderCompiler::ShaderCompiler(PGraphics graphics) - : graphics(graphics) -{ - -} - -ShaderCompiler::~ShaderCompiler() -{ - -} - - diff --git a/src/Engine/Graphics/ShaderCompiler.h b/src/Engine/Graphics/ShaderCompiler.h deleted file mode 100644 index b60303b..0000000 --- a/src/Engine/Graphics/ShaderCompiler.h +++ /dev/null @@ -1,19 +0,0 @@ -#pragma once -#include "Material/Material.h" - -namespace Seele -{ -DECLARE_NAME_REF(Gfx, Graphics) -namespace Gfx -{ -class ShaderCompiler -{ -public: - ShaderCompiler(PGraphics graphics); - ~ShaderCompiler(); -private: - PGraphics graphics; -}; -DEFINE_REF(ShaderCompiler) -} // namespace Gfx -} // namespace Seele \ No newline at end of file diff --git a/src/Engine/Graphics/StaticMeshVertexData.cpp b/src/Engine/Graphics/StaticMeshVertexData.cpp index 6b03482..67420a4 100644 --- a/src/Engine/Graphics/StaticMeshVertexData.cpp +++ b/src/Engine/Graphics/StaticMeshVertexData.cpp @@ -135,7 +135,7 @@ void StaticMeshVertexData::resizeBuffers() .size = verticesAllocated * sizeof(Vector), }, .stride = sizeof(Vector), - .bDynamic = true, + .dynamic = true, }; positions = graphics->createShaderBuffer(createInfo); normals = graphics->createShaderBuffer(createInfo); @@ -174,6 +174,7 @@ void StaticMeshVertexData::updateBuffers() .size = biTangentData.size() * sizeof(Vector), .data = (uint8*)biTangentData.data(), }); + descriptorLayout->reset(); descriptorSet = descriptorLayout->allocateDescriptorSet(); descriptorSet->updateBuffer(0, positions); descriptorSet->updateBuffer(1, texCoords); diff --git a/src/Engine/Graphics/StaticMeshVertexData.h b/src/Engine/Graphics/StaticMeshVertexData.h index 28c8bcc..491236e 100644 --- a/src/Engine/Graphics/StaticMeshVertexData.h +++ b/src/Engine/Graphics/StaticMeshVertexData.h @@ -1,4 +1,5 @@ #pragma once +#include "Math/Vector.h" #include "VertexData.h" namespace Seele @@ -35,6 +36,6 @@ private: Gfx::OShaderBuffer biTangents; Array biTangentData; Gfx::ODescriptorLayout descriptorLayout; - Gfx::ODescriptorSet descriptorSet; + Gfx::PDescriptorSet descriptorSet; }; } diff --git a/src/Engine/Graphics/VertexData.cpp b/src/Engine/Graphics/VertexData.cpp index efcdd6e..83e6840 100644 --- a/src/Engine/Graphics/VertexData.cpp +++ b/src/Engine/Graphics/VertexData.cpp @@ -70,7 +70,7 @@ void VertexData::loadMesh(MeshId id, Array loadedMeshlets) .data = (uint8*)meshlets.data() }, .stride = sizeof(MeshletDescription), - .bDynamic = true, + .dynamic = true, }); vertexIndicesBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo { .sourceData = { @@ -78,7 +78,7 @@ void VertexData::loadMesh(MeshId id, Array loadedMeshlets) .data = (uint8*)vertexIndices.data(), }, .stride = sizeof(uint32), - .bDynamic = true, + .dynamic = true, }); primitiveIndicesBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo { .sourceData = { @@ -86,7 +86,7 @@ void VertexData::loadMesh(MeshId id, Array loadedMeshlets) .data = (uint8*)primitiveIndices.data(), }, .stride = sizeof(uint8), - .bDynamic = true, + .dynamic = true, }); } @@ -114,6 +114,7 @@ void VertexData::createDescriptors() }, .stride = sizeof(InstanceData) }); + instanceDataLayout->reset(); matInst.descriptorSet = instanceDataLayout->allocateDescriptorSet(); matInst.descriptorSet->updateBuffer(0, instanceBuffer); if (Gfx::useMeshShading) @@ -187,15 +188,18 @@ void Seele::VertexData::init(Gfx::PGraphics graphics) } instanceDataLayout->create(); resizeBuffers(); + graphics->getShaderCompiler()->registerVertexData(this); } VertexData::VertexData() : idCounter(0) , dirty(false) + , head(0) + , verticesAllocated(0) { } -void Meshlet::save(ArchiveBuffer& buffer) +void Meshlet::save(ArchiveBuffer& buffer) const { Serialization::save(buffer, uniqueVertices); Serialization::save(buffer, primitiveLayout); diff --git a/src/Engine/Graphics/VertexData.h b/src/Engine/Graphics/VertexData.h index d0c63d5..9e67823 100644 --- a/src/Engine/Graphics/VertexData.h +++ b/src/Engine/Graphics/VertexData.h @@ -26,7 +26,7 @@ struct Meshlet StaticArray primitiveLayout; // indices into the uniqueVertices array, only uint8 needed uint32 numVertices; uint32 numPrimitives; - void save(ArchiveBuffer& buffer); + void save(ArchiveBuffer& buffer) const; void load(ArchiveBuffer& buffer); }; class VertexData @@ -101,7 +101,7 @@ protected: Array meshlets; Array primitiveIndices; Array vertexIndices; - Gfx::OGraphics graphics; + Gfx::PGraphics graphics; Gfx::ODescriptorLayout instanceDataLayout; // for mesh shading Gfx::OShaderBuffer meshletBuffer; diff --git a/src/Engine/Graphics/Vulkan/Allocator.cpp b/src/Engine/Graphics/Vulkan/Allocator.cpp index 35c792e..ff87c72 100644 --- a/src/Engine/Graphics/Vulkan/Allocator.cpp +++ b/src/Engine/Graphics/Vulkan/Allocator.cpp @@ -4,7 +4,7 @@ using namespace Seele::Vulkan; -SubAllocation::SubAllocation(Allocation *owner, VkDeviceSize allocatedOffset, VkDeviceSize size, VkDeviceSize alignedOffset, VkDeviceSize allocatedSize) +SubAllocation::SubAllocation(PAllocation owner, VkDeviceSize allocatedOffset, VkDeviceSize size, VkDeviceSize alignedOffset, VkDeviceSize allocatedSize) : owner(owner) , size(size) , allocatedOffset(allocatedOffset) @@ -18,12 +18,22 @@ SubAllocation::~SubAllocation() owner->markFree(this); } -VkDeviceMemory SubAllocation::getHandle() const +constexpr VkDeviceMemory SubAllocation::getHandle() const { return owner->getHandle(); } -bool SubAllocation::isReadable() const +constexpr VkDeviceSize SubAllocation::getSize() const +{ + return size; +} + +constexpr VkDeviceSize SubAllocation::getOffset() const +{ + return alignedOffset; +} + +constexpr bool SubAllocation::isReadable() const { return owner->isReadable(); } @@ -61,8 +71,7 @@ Allocation::Allocation(PGraphics graphics, PAllocator allocator, VkDeviceSize si allocInfo.pNext = dedicatedInfo; VK_CHECK(vkAllocateMemory(device, &allocInfo, nullptr, &allocatedMemory)); bytesAllocated = size; - PSubAllocation freeRange = new SubAllocation(this, 0, size, 0, size); - freeRanges[0] = freeRange; + freeRanges[0] = new SubAllocation(this, 0, size, 0, size); canMap = (properties & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) == VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT; isMapped = false; @@ -72,15 +81,15 @@ Allocation::~Allocation() { } -PSubAllocation Allocation::getSuballocation(VkDeviceSize requestedSize, VkDeviceSize alignment) +OSubAllocation Allocation::getSuballocation(VkDeviceSize requestedSize, VkDeviceSize alignment) { std::scoped_lock lck(lock); if (isDedicated) { if (activeAllocations.empty() && requestedSize == bytesAllocated) { - PSubAllocation suballoc = freeRanges[0]; - activeAllocations[0] = suballoc.getHandle(); + OSubAllocation suballoc = std::move(freeRanges[0]); + activeAllocations.add(suballoc); freeRanges.clear(); bytesUsed += requestedSize; return suballoc; @@ -92,37 +101,38 @@ PSubAllocation Allocation::getSuballocation(VkDeviceSize requestedSize, VkDevice } for (auto& it : freeRanges) { - VkDeviceSize allocatedOffset = it.first; - PSubAllocation freeAllocation = it.second; + VkDeviceSize allocatedOffset = it.key; + OSubAllocation& freeAllocation = it.value; assert(allocatedOffset == freeAllocation->allocatedOffset); - VkDeviceSize alignedOffset = align(allocatedOffset, alignment); - VkDeviceSize alignmentAdjustment = alignedOffset - allocatedOffset; - VkDeviceSize size = alignmentAdjustment + requestedSize; - if (freeAllocation->size == size) + VkDeviceSize alignedOffset = allocatedOffset + alignment - 1; + alignedOffset /= alignment; + alignedOffset *= alignment; + VkDeviceSize allocatedSize = requestedSize + (alignedOffset - allocatedOffset); + if (freeAllocation->size == allocatedSize) { - activeAllocations[allocatedOffset] = freeAllocation.getHandle(); + activeAllocations.add(freeAllocation); freeRanges.erase(allocatedOffset); - bytesUsed += size; - return freeAllocation; + bytesUsed += allocatedSize; + return std::move(freeAllocation); } - else if (size < freeAllocation->allocatedSize) + else if (allocatedSize < freeAllocation->allocatedSize) { - freeAllocation->size -= size; - freeAllocation->allocatedSize -= size; - freeAllocation->allocatedOffset += size; - freeAllocation->alignedOffset += size; - PSubAllocation subAlloc = new SubAllocation(this, allocatedOffset, size, alignedOffset, size); - activeAllocations[allocatedOffset] = subAlloc.getHandle(); + freeAllocation->size -= allocatedSize; + freeAllocation->allocatedSize -= allocatedSize; + freeAllocation->allocatedOffset += allocatedSize; + freeAllocation->alignedOffset += allocatedSize; + OSubAllocation subAlloc = new SubAllocation(this, allocatedOffset, allocatedSize, alignedOffset, allocatedSize); + activeAllocations.add(subAlloc); + freeRanges[freeAllocation->allocatedOffset] = std::move(freeAllocation); freeRanges.erase(allocatedOffset); - freeRanges[freeAllocation->allocatedOffset] = freeAllocation; - bytesUsed += size; + bytesUsed += allocatedSize; return subAlloc; } } return nullptr; } -void Allocation::markFree(SubAllocation *allocation) +void Allocation::markFree(PSubAllocation allocation) { // Dont free if it is already a free allocation, since they also mark themselves on deletion if (freeRanges.find(allocation->allocatedOffset) != freeRanges.end()) @@ -143,7 +153,7 @@ void Allocation::markFree(SubAllocation *allocation) && freeAlloc->allocatedOffset + freeAlloc->allocatedSize >= upperBound) { // allocation is already in a free region - return; + assert(false); } if (freeAlloc->allocatedOffset + freeAlloc->allocatedSize == lowerBound) { @@ -157,35 +167,34 @@ void Allocation::markFree(SubAllocation *allocation) auto foundAlloc = freeRanges.find(upperBound); if (foundAlloc != freeRanges.end()) { - freeRangeToDelete = foundAlloc->second; // There is a free allocation ending where the new free one ends + freeRangeToDelete = foundAlloc->value; if (allocHandle != nullptr) { // extend allocHandle by another foundAlloc->allocatedSize bytes - allocHandle->allocatedSize += foundAlloc->second->allocatedSize; - freeRanges.erase(foundAlloc->first); + allocHandle->allocatedSize += foundAlloc->value->allocatedSize; + freeRanges.erase(foundAlloc->key); } else { // set foundAlloc back by size amount - allocHandle = foundAlloc->second; + allocHandle = foundAlloc->value; allocHandle->allocatedOffset -= allocation->allocatedSize; allocHandle->alignedOffset -= allocation->allocatedSize; allocHandle->size += allocation->allocatedSize; allocHandle->allocatedSize += allocation->allocatedSize; - // place back at correct offset - freeRanges[allocHandle->allocatedOffset] = allocHandle; + // place back at correct offset, move original owning pointer + freeRanges[allocHandle->allocatedOffset] = std::move(foundAlloc->value); // remove from offset map since key changes - freeRanges.erase(foundAlloc->first); + freeRanges.erase(foundAlloc->key); } } if (allocHandle == nullptr) { - allocHandle = new SubAllocation(this, allocation->allocatedOffset, allocation->size, allocation->alignedOffset, allocation->allocatedSize); - freeRanges[allocation->allocatedOffset] = allocHandle; + freeRanges[allocation->allocatedOffset] = new SubAllocation(this, allocation->allocatedOffset, allocation->size, allocation->alignedOffset, allocation->allocatedSize); } - activeAllocations.erase(allocation->allocatedOffset); + activeAllocations.remove_if([&](const PSubAllocation& a) {return a.getHandle() == allocation.getHandle(); }); } bytesUsed -= allocation->allocatedSize; if(bytesUsed == 0) @@ -194,25 +203,73 @@ void Allocation::markFree(SubAllocation *allocation) } } +constexpr VkDeviceMemory Allocation::getHandle() const +{ + return allocatedMemory; +} + +constexpr void* Allocation::getMappedPointer() +{ + if (!canMap) + { + return nullptr; + } + if (!isMapped) + { + vkMapMemory(device, allocatedMemory, 0, bytesAllocated, 0, &mappedPointer); + isMapped = true; + } + return mappedPointer; +} + +constexpr bool Allocation::isReadable() const +{ + return readable; +} + +void Allocation::flushMemory() +{ + VkMappedMemoryRange range = { + .sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE, + .pNext = 0, + .memory = allocatedMemory, + .offset = 0, + .size = bytesAllocated, + }; + vkFlushMappedMemoryRanges(device, 1, &range); +} + +void Allocation::invalidateMemory() +{ + VkMappedMemoryRange range = { + .sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE, + .pNext = 0, + .memory = allocatedMemory, + .size = bytesAllocated, + }; + vkInvalidateMappedMemoryRanges(device, 1, &range); +} + Allocator::Allocator(PGraphics graphics) : graphics(graphics) { vkGetPhysicalDeviceMemoryProperties(graphics->getPhysicalDevice(), &memProperties); - heaps.resize(memProperties.memoryHeapCount); + heaps.reserve(memProperties.memoryHeapCount); for (size_t i = 0; i < memProperties.memoryHeapCount; ++i) { VkMemoryHeap memoryHeap = memProperties.memoryHeaps[i]; - HeapInfo &heapInfo = heaps[i]; + HeapInfo heapInfo; heapInfo.maxSize = memoryHeap.size; + heaps.add(std::move(heapInfo)); } } Allocator::~Allocator() { std::scoped_lock lck(lock); - for (auto heap : heaps) + for (auto& heap : heaps) { - for (auto alloc : heap.allocations) + for (auto& alloc : heap.allocations) { assert(alloc->activeAllocations.empty()); assert(alloc->freeRanges.size() == 1); @@ -222,7 +279,7 @@ Allocator::~Allocator() graphics = nullptr; } -PSubAllocation Allocator::allocate(const VkMemoryRequirements2 &memRequirements2, VkMemoryPropertyFlags properties, VkMemoryDedicatedAllocateInfo *dedicatedInfo) +OSubAllocation Allocator::allocate(const VkMemoryRequirements2 &memRequirements2, VkMemoryPropertyFlags properties, VkMemoryDedicatedAllocateInfo *dedicatedInfo) { std::scoped_lock lck(lock); const VkMemoryRequirements &requirements = memRequirements2.memoryRequirements; @@ -234,17 +291,17 @@ PSubAllocation Allocator::allocate(const VkMemoryRequirements2 &memRequirements2 VkMemoryDedicatedRequirements *dedicatedReq = (VkMemoryDedicatedRequirements *)memRequirements2.pNext; if (dedicatedReq->prefersDedicatedAllocation) { - PAllocation newAllocation = new Allocation(graphics, this, requirements.size, memoryTypeIndex, properties, dedicatedInfo); - heaps[heapIndex].allocations.add(newAllocation); + OAllocation newAllocation = new Allocation(graphics, this, requirements.size, memoryTypeIndex, properties, dedicatedInfo); heaps[heapIndex].inUse += newAllocation->bytesAllocated; - return newAllocation->getSuballocation(requirements.size, requirements.alignment); + heaps[heapIndex].allocations.add(std::move(newAllocation)); + return heaps[heapIndex].allocations.back()->getSuballocation(requirements.size, requirements.alignment); } } - for (auto alloc : heaps[heapIndex].allocations) + for (auto& alloc : heaps[heapIndex].allocations) { if(alloc->memoryTypeIndex == memoryTypeIndex) { - PSubAllocation suballoc = alloc->getSuballocation(requirements.size, requirements.alignment); + OSubAllocation suballoc = alloc->getSuballocation(requirements.size, requirements.alignment); if (suballoc != nullptr) { return suballoc; @@ -253,16 +310,16 @@ PSubAllocation Allocator::allocate(const VkMemoryRequirements2 &memRequirements2 } // no suitable allocations found, allocate new block - PAllocation newAllocation = new Allocation(graphics, this, (requirements.size > MemoryBlockSize) ? requirements.size : (VkDeviceSize)MemoryBlockSize, memoryTypeIndex, properties, nullptr); - heaps[heapIndex].allocations.add(newAllocation); + OAllocation newAllocation = new Allocation(graphics, this, (requirements.size > MemoryBlockSize) ? requirements.size : (VkDeviceSize)MemoryBlockSize, memoryTypeIndex, properties, nullptr); heaps[heapIndex].inUse += newAllocation->bytesAllocated; - return newAllocation->getSuballocation(requirements.size, requirements.alignment); + heaps[heapIndex].allocations.add(std::move(newAllocation)); + return heaps[heapIndex].allocations.back()->getSuballocation(requirements.size, requirements.alignment); } void Allocator::free(Allocation *allocation) { std::scoped_lock lck(lock); - for (auto heap : heaps) + for (auto& heap : heaps) { for (uint32 i = 0; i < heap.allocations.size(); ++i) { @@ -288,12 +345,58 @@ uint32 Allocator::findMemoryType(uint32 typeFilter, VkMemoryPropertyFlags proper throw std::runtime_error("error finding memory"); } -StagingBuffer::StagingBuffer() +StagingBuffer::StagingBuffer(OSubAllocation allocation, VkBuffer buffer, VkBufferUsageFlags usage, uint8 readable) + : allocation(std::move(allocation)) + , buffer(buffer) + , usage(usage) + , readable(readable) { } StagingBuffer::~StagingBuffer() { + assert(allocation == nullptr); + // buffer went out of scope without being cleaned up +} + +void* StagingBuffer::getMappedPointer() +{ + return allocation->getMappedPointer(); +} + +void StagingBuffer::flushMappedMemory() +{ + allocation->flushMemory(); +} + +void StagingBuffer::invalidateMemory() +{ + allocation->invalidateMemory(); +} + +constexpr VkDeviceMemory StagingBuffer::getMemoryHandle() const +{ + return allocation->getHandle(); +} + +constexpr VkDeviceSize StagingBuffer::getOffset() const +{ + return allocation->getOffset(); +} + +constexpr uint64 StagingBuffer::getSize() const +{ + return allocation->getSize(); +} + +constexpr bool StagingBuffer::isReadable() const +{ + return readable; +} + +constexpr VkBufferUsageFlags StagingBuffer::getUsage() const +{ + return usage; } StagingManager::StagingManager(PGraphics graphics, PAllocator allocator) @@ -309,22 +412,22 @@ void StagingManager::clearPending() { } -PStagingBuffer StagingManager::allocateStagingBuffer(uint64 size, VkBufferUsageFlags usage, bool bCPURead) +OStagingBuffer StagingManager::allocateStagingBuffer(uint64 size, VkBufferUsageFlags usage, bool readable) { std::scoped_lock l(lock); for (auto it = freeBuffers.begin(); it != freeBuffers.end(); ++it) { - auto freeBuffer = *it; - if (freeBuffer->getSize() == size && freeBuffer->isReadable() == bCPURead && freeBuffer->usage == usage) + auto& freeBuffer = *it; + if (freeBuffer->getSize() == size && freeBuffer->isReadable() == readable && freeBuffer->getUsage() == usage) { //std::cout << "Reusing staging buffer" << std::endl; - activeBuffers.add(freeBuffer.getHandle()); + activeBuffers.add(freeBuffer); freeBuffers.remove(it, false); - return freeBuffer; + return std::move(freeBuffer); } } //std::cout << "Creating new stagingbuffer" << std::endl; - PStagingBuffer stagingBuffer = new StagingBuffer(); + VkBuffer buffer; VkBufferCreateInfo stagingBufferCreateInfo = init::BufferCreateInfo(usage, size); stagingBufferCreateInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE; uint32 queueIndex = graphics->getFamilyMapping().getQueueTypeFamilyIndex(Gfx::QueueType::DEDICATED_TRANSFER); @@ -332,37 +435,42 @@ PStagingBuffer StagingManager::allocateStagingBuffer(uint64 size, VkBufferUsageF stagingBufferCreateInfo.pQueueFamilyIndices = &queueIndex; VkDevice vulkanDevice = graphics->getDevice(); - VK_CHECK(vkCreateBuffer(vulkanDevice, &stagingBufferCreateInfo, nullptr, &stagingBuffer->buffer)); + VK_CHECK(vkCreateBuffer(vulkanDevice, &stagingBufferCreateInfo, nullptr, &buffer)); - VkMemoryDedicatedRequirements dedicatedReqs; - dedicatedReqs.sType = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS; - dedicatedReqs.pNext = nullptr; - VkMemoryRequirements2 memReqs; - memReqs.sType = VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2; - memReqs.pNext = &dedicatedReqs; - VkBufferMemoryRequirementsInfo2 bufferQuery; - bufferQuery.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_REQUIREMENTS_INFO_2; - bufferQuery.pNext = nullptr; - bufferQuery.buffer = stagingBuffer->buffer; + VkMemoryDedicatedRequirements dedicatedReqs = { + .sType = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS, + .pNext = nullptr, + }; + VkMemoryRequirements2 memReqs = { + .sType = VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2, + .pNext = &dedicatedReqs, + }; + VkBufferMemoryRequirementsInfo2 bufferQuery = { + .sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_REQUIREMENTS_INFO_2, + .pNext = nullptr, + .buffer = buffer, + }; vkGetBufferMemoryRequirements2(vulkanDevice, &bufferQuery, &memReqs); memReqs.memoryRequirements.alignment = (16 > memReqs.memoryRequirements.alignment) ? 16 : memReqs.memoryRequirements.alignment; - - stagingBuffer->allocation = allocator->allocate(memReqs, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | (bCPURead ? VK_MEMORY_PROPERTY_HOST_COHERENT_BIT : VK_MEMORY_PROPERTY_HOST_CACHED_BIT), stagingBuffer->buffer); - stagingBuffer->bReadable = bCPURead; - stagingBuffer->size = size; - stagingBuffer->usage = usage; - vkBindBufferMemory(graphics->getDevice(), stagingBuffer->buffer, stagingBuffer->getMemoryHandle(), stagingBuffer->getOffset()); - activeBuffers.add(stagingBuffer.getHandle()); + OStagingBuffer stagingBuffer = new StagingBuffer( + allocator->allocate(memReqs, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | (readable ? VK_MEMORY_PROPERTY_HOST_COHERENT_BIT : VK_MEMORY_PROPERTY_HOST_CACHED_BIT), buffer), + buffer, + usage, + readable + ); + vkBindBufferMemory(graphics->getDevice(), buffer, stagingBuffer->getMemoryHandle(), stagingBuffer->getOffset()); + + activeBuffers.add(stagingBuffer); return stagingBuffer; } -void StagingManager::releaseStagingBuffer(PStagingBuffer buffer) +void StagingManager::releaseStagingBuffer(OStagingBuffer buffer) { std::scoped_lock l(lock); - freeBuffers.add(buffer); - activeBuffers.remove(activeBuffers.find(buffer.getHandle())); + activeBuffers.remove(buffer); + freeBuffers.add(std::move(buffer)); } \ No newline at end of file diff --git a/src/Engine/Graphics/Vulkan/Allocator.h b/src/Engine/Graphics/Vulkan/Allocator.h index 16be7cf..dda6762 100644 --- a/src/Engine/Graphics/Vulkan/Allocator.h +++ b/src/Engine/Graphics/Vulkan/Allocator.h @@ -10,29 +10,23 @@ namespace Seele namespace Vulkan { DECLARE_REF(Graphics) -class Allocation; -class Allocator; +DECLARE_REF(Allocator) +DECLARE_REF(Allocation) class SubAllocation { public: - SubAllocation(Allocation *owner, VkDeviceSize allocatedOffset, VkDeviceSize size, VkDeviceSize alignedOffset, VkDeviceSize allocatedSize); + SubAllocation(PAllocation owner, VkDeviceSize allocatedOffset, VkDeviceSize size, VkDeviceSize alignedOffset, VkDeviceSize allocatedSize); ~SubAllocation(); - VkDeviceMemory getHandle() const; - inline VkDeviceSize getSize() const - { - return size; - } - inline VkDeviceSize getOffset() const - { - return alignedOffset; - } - inline bool isReadable() const; + constexpr VkDeviceMemory getHandle() const; + constexpr VkDeviceSize getSize() const; + constexpr VkDeviceSize getOffset() const; + constexpr bool isReadable() const; void *getMappedPointer(); void flushMemory(); void invalidateMemory(); private: - Allocation *owner; + PAllocation owner; VkDeviceSize size; VkDeviceSize allocatedOffset; VkDeviceSize alignedOffset; @@ -44,54 +38,16 @@ DEFINE_REF(SubAllocation) class Allocation { public: - Allocation(PGraphics graphics, Allocator *allocator, VkDeviceSize size, uint8 memoryTypeIndex, + Allocation(PGraphics graphics, PAllocator allocator, VkDeviceSize size, uint8 memoryTypeIndex, VkMemoryPropertyFlags properties, VkMemoryDedicatedAllocateInfo *dedicatedInfo = nullptr); ~Allocation(); - PSubAllocation getSuballocation(VkDeviceSize size, VkDeviceSize alignment); - void markFree(SubAllocation *alloc); - inline VkDeviceMemory getHandle() const - { - return allocatedMemory; - } - inline void *getMappedPointer() - { - if (!canMap) - { - return nullptr; - } - if (!isMapped) - { - vkMapMemory(device, allocatedMemory, 0, bytesAllocated, 0, &mappedPointer); - isMapped = true; - } - return mappedPointer; - } - - inline bool isReadable() const - { - return readable; - } - - void flushMemory() - { - VkMappedMemoryRange range; - range.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE; - range.pNext = 0; - range.memory = allocatedMemory; - range.size = bytesAllocated; - range.offset = 0; - vkFlushMappedMemoryRanges(device, 1, &range); - } - - void invalidateMemory() - { - VkMappedMemoryRange range; - range.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE; - range.pNext = 0; - range.memory = allocatedMemory; - range.size = bytesAllocated; - vkInvalidateMappedMemoryRanges(device, 1, &range); - } + OSubAllocation getSuballocation(VkDeviceSize size, VkDeviceSize alignment); + void markFree(PSubAllocation alloc); + constexpr VkDeviceMemory getHandle() const; + constexpr void* getMappedPointer(); + constexpr bool isReadable() const; + void flushMemory(); + void invalidateMemory(); private: VkDevice device; @@ -99,8 +55,8 @@ private: VkDeviceSize bytesAllocated; VkDeviceSize bytesUsed; VkDeviceMemory allocatedMemory; - std::map activeAllocations; - std::map freeRanges; + Array activeAllocations; + Map freeRanges; std::mutex lock; void *mappedPointer; uint8 isDedicated : 1; @@ -142,7 +98,6 @@ public: } void free(Allocation *allocation); - void notifyUsageChanged(int64 usageChange); private: enum { @@ -152,7 +107,12 @@ private: { VkDeviceSize maxSize = 0; VkDeviceSize inUse = 0; - Array allocations; + Array allocations; + HeapInfo() {} + HeapInfo(const HeapInfo& other) = delete; + HeapInfo(HeapInfo&& other) = default; + HeapInfo& operator=(const HeapInfo& other) = delete; + HeapInfo& operator=(HeapInfo&& other) = default; }; Array heaps; uint32 findMemoryType(uint32 typeBits, VkMemoryPropertyFlags properties); @@ -161,52 +121,29 @@ private: VkPhysicalDeviceMemoryProperties memProperties; }; DEFINE_REF(Allocator) - +DECLARE_REF(StagingManager) class StagingBuffer { public: - StagingBuffer(); + StagingBuffer(OSubAllocation allocation, VkBuffer buffer, VkBufferUsageFlags usage, uint8 readable); ~StagingBuffer(); - void *getMappedPointer() - { - return allocation->getMappedPointer(); - } - void flushMappedMemory() - { - allocation->flushMemory(); - } - void invalidateMemory() - { - allocation->invalidateMemory(); - } - VkBuffer getHandle() const + void* getMappedPointer(); + void flushMappedMemory(); + void invalidateMemory(); + constexpr VkBuffer getHandle() const { return buffer; } - VkDeviceMemory getMemoryHandle() const - { - return allocation->getHandle(); - } - VkDeviceSize getOffset() const - { - return allocation->getOffset(); - } - uint64 getSize() const - { - return size; - } - bool isReadable() const - { - return bReadable; - } - + constexpr VkDeviceMemory getMemoryHandle() const; + constexpr VkDeviceSize getOffset() const; + constexpr uint64 getSize() const; + constexpr bool isReadable() const; + constexpr VkBufferUsageFlags getUsage() const; private: - PSubAllocation allocation; + OSubAllocation allocation; VkBuffer buffer; - uint64 size; VkBufferUsageFlags usage; - uint8 bReadable; - friend class StagingManager; + uint8 readable; }; DEFINE_REF(StagingBuffer) @@ -215,15 +152,15 @@ class StagingManager public: StagingManager(PGraphics graphics, PAllocator allocator); ~StagingManager(); - PStagingBuffer allocateStagingBuffer(uint64 size, VkBufferUsageFlags usageFlags = VK_BUFFER_USAGE_TRANSFER_SRC_BIT, bool bCPURead = false); - void releaseStagingBuffer(PStagingBuffer buffer); + OStagingBuffer allocateStagingBuffer(uint64 size, VkBufferUsageFlags usageFlags = VK_BUFFER_USAGE_TRANSFER_SRC_BIT, bool bCPURead = false); + void releaseStagingBuffer(OStagingBuffer buffer); void clearPending(); private: PGraphics graphics; PAllocator allocator; - Array freeBuffers; - Array activeBuffers; + Array freeBuffers; + Array activeBuffers; std::mutex lock; }; DEFINE_REF(StagingManager) diff --git a/src/Engine/Graphics/Vulkan/Buffer.cpp b/src/Engine/Graphics/Vulkan/Buffer.cpp index 582c7b0..b68bb98 100644 --- a/src/Engine/Graphics/Vulkan/Buffer.cpp +++ b/src/Engine/Graphics/Vulkan/Buffer.cpp @@ -1,4 +1,6 @@ #include "Buffer.h" +#include "Initializer.h" +#include "CommandBuffer.h" using namespace Seele; using namespace Seele::Vulkan; @@ -7,20 +9,20 @@ struct PendingBuffer { uint64 offset; uint64 size; - PStagingBuffer stagingBuffer; + OStagingBuffer stagingBuffer; Gfx::QueueType prevQueue; - bool bWriteOnly; + bool writeOnly; }; static std::map pendingBuffers; -Buffer::Buffer(PGraphics graphics, uint64 size, VkBufferUsageFlags usage, Gfx::QueueType& queueType, bool bDynamic) +Buffer::Buffer(PGraphics graphics, uint64 size, VkBufferUsageFlags usage, Gfx::QueueType& queueType, bool dynamic) : graphics(graphics) , currentBuffer(0) , size(size) , owner(queueType) { - if(bDynamic) + if(dynamic) { numBuffers = Gfx::numFramesBuffered; } @@ -166,12 +168,12 @@ void Buffer::executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlag vkCmdPipelineBarrier(commandBuffer->getHandle(), srcStage, dstStage, 0, 0, nullptr, numBuffers, dynamicBarriers, 0, nullptr); } -void * Buffer::lock(bool bWriteOnly) +void * Buffer::lock(bool writeOnly) { - return lockRegion(0, size, bWriteOnly); + return lockRegion(0, size, writeOnly); } -void * Buffer::lockRegion(uint64 regionOffset, uint64 regionSize, bool bWriteOnly) +void * Buffer::lockRegion(uint64 regionOffset, uint64 regionSize, bool writeOnly) { void *data = nullptr; @@ -190,16 +192,16 @@ void * Buffer::lockRegion(uint64 regionOffset, uint64 regionSize, bool bWriteOnl //assert(bStatic || bDynamic || bUAV); PendingBuffer pending; - pending.bWriteOnly = bWriteOnly; + pending.writeOnly = writeOnly; pending.prevQueue = owner; pending.offset = regionOffset; pending.size = regionSize; - if (bWriteOnly) + if (writeOnly) { //requestOwnershipTransfer(Gfx::QueueType::DEDICATED_TRANSFER); - PStagingBuffer stagingBuffer = graphics->getStagingManager()->allocateStagingBuffer(regionSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT); + OStagingBuffer stagingBuffer = graphics->getStagingManager()->allocateStagingBuffer(regionSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT); data = stagingBuffer->getMappedPointer(); - pending.stagingBuffer = stagingBuffer; + pending.stagingBuffer = std::move(stagingBuffer); } else { @@ -220,7 +222,7 @@ void * Buffer::lockRegion(uint64 regionOffset, uint64 regionSize, bool bWriteOnl barrier.size = size; vkCmdPipelineBarrier(handle, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, nullptr, 1, &barrier, 0, nullptr); - PStagingBuffer stagingBuffer = graphics->getStagingManager()->allocateStagingBuffer(size, VK_BUFFER_USAGE_TRANSFER_DST_BIT, true); + OStagingBuffer stagingBuffer = graphics->getStagingManager()->allocateStagingBuffer(size, VK_BUFFER_USAGE_TRANSFER_DST_BIT, true); VkBufferCopy regions; regions.size = size; @@ -233,11 +235,12 @@ void * Buffer::lockRegion(uint64 regionOffset, uint64 regionSize, bool bWriteOnl vkQueueWaitIdle(graphics->getQueueCommands(owner)->getQueue()->getHandle()); stagingBuffer->getMappedPointer(); // this maps the memory if not mapped already stagingBuffer->flushMappedMemory(); - pending.stagingBuffer = stagingBuffer; - data = stagingBuffer->getMappedPointer(); + + pending.stagingBuffer = std::move(stagingBuffer); + } - pendingBuffers[this] = pending; + pendingBuffers[this] = std::move(pending); assert(data); return data; @@ -248,10 +251,9 @@ void Buffer::unlock() auto found = pendingBuffers.find(this); if (found != pendingBuffers.end()) { - PendingBuffer pending = found->second; + PendingBuffer& pending = found->second; pending.stagingBuffer->flushMappedMemory(); - pendingBuffers.erase(this); - if (pending.bWriteOnly) + if (pending.writeOnly) { PStagingBuffer stagingBuffer = pending.stagingBuffer; PCmdBuffer cmdBuffer = graphics->getQueueCommands(owner)->getCommands(); @@ -265,16 +267,17 @@ void Buffer::unlock() graphics->getQueueCommands(owner)->submitCommands(); } //requestOwnershipTransfer(pending.prevQueue); - graphics->getStagingManager()->releaseStagingBuffer(pending.stagingBuffer); + graphics->getStagingManager()->releaseStagingBuffer(std::move(pending.stagingBuffer)); + pendingBuffers.erase(this); } } UniformBuffer::UniformBuffer(PGraphics graphics, const UniformBufferCreateInfo &createInfo) : Gfx::UniformBuffer(graphics->getFamilyMapping(), createInfo.sourceData) - , Vulkan::Buffer(graphics, createInfo.sourceData.size, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, currentOwner, createInfo.bDynamic) + , Vulkan::Buffer(graphics, createInfo.sourceData.size, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, currentOwner, createInfo.dynamic) , dedicatedStagingBuffer(nullptr) { - if(createInfo.bDynamic) + if(createInfo.dynamic) { dedicatedStagingBuffer = graphics->getStagingManager()->allocateStagingBuffer(createInfo.sourceData.size, VK_BUFFER_USAGE_TRANSFER_SRC_BIT); } @@ -302,13 +305,13 @@ bool UniformBuffer::updateContents(const DataSource &sourceData) unlock(); return true; } -void* UniformBuffer::lock(bool bWriteOnly) +void* UniformBuffer::lock(bool writeOnly) { if(dedicatedStagingBuffer != nullptr) { return dedicatedStagingBuffer->getMappedPointer(); } - return Vulkan::Buffer::lock(bWriteOnly); + return Vulkan::Buffer::lock(writeOnly); } void UniformBuffer::unlock() @@ -359,7 +362,7 @@ VkAccessFlags UniformBuffer::getDestAccessMask() ShaderBuffer::ShaderBuffer(PGraphics graphics, const ShaderBufferCreateInfo &sourceData) : Gfx::ShaderBuffer(graphics->getFamilyMapping(), sourceData.stride, sourceData.sourceData.size / sourceData.stride, sourceData.sourceData) - , Vulkan::Buffer(graphics, sourceData.sourceData.size, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, currentOwner, sourceData.bDynamic) + , Vulkan::Buffer(graphics, sourceData.sourceData.size, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, currentOwner, sourceData.dynamic) { if (sourceData.sourceData.data != nullptr) { @@ -383,13 +386,13 @@ bool ShaderBuffer::updateContents(const DataSource &sourceData) unlock(); return true; } -void* ShaderBuffer::lock(bool bWriteOnly) +void* ShaderBuffer::lock(bool writeOnly) { if(dedicatedStagingBuffer != nullptr) { return dedicatedStagingBuffer->getMappedPointer(); } - return ShaderBuffer::lock(bWriteOnly); + return ShaderBuffer::lock(writeOnly); } void ShaderBuffer::unlock() diff --git a/src/Engine/Graphics/Vulkan/Buffer.h b/src/Engine/Graphics/Vulkan/Buffer.h index be9fad2..a8ef84d 100644 --- a/src/Engine/Graphics/Vulkan/Buffer.h +++ b/src/Engine/Graphics/Vulkan/Buffer.h @@ -11,7 +11,7 @@ namespace Vulkan class Buffer { public: - Buffer(PGraphics graphics, uint64 size, VkBufferUsageFlags usage, Gfx::QueueType& queueType, bool bDynamic = false); + Buffer(PGraphics graphics, uint64 size, VkBufferUsageFlags usage, Gfx::QueueType& queueType, bool dynamic = false); virtual ~Buffer(); VkBuffer getHandle() const { @@ -26,8 +26,8 @@ public: { currentBuffer = (currentBuffer + 1) % numBuffers; } - virtual void *lock(bool bWriteOnly = true); - virtual void *lockRegion(uint64 regionOffset, uint64 regionSize, bool bWriteOnly = true); + virtual void *lock(bool writeOnly = true); + virtual void *lockRegion(uint64 regionOffset, uint64 regionSize, bool writeOnly = true); virtual void unlock(); protected: @@ -62,7 +62,7 @@ public: virtual ~UniformBuffer(); virtual bool updateContents(const DataSource &sourceData); - virtual void* lock(bool bWriteOnly = true) override; + virtual void* lock(bool writeOnly = true) override; virtual void unlock() override; protected: // Inherited via Vulkan::Buffer @@ -75,7 +75,7 @@ protected: VkAccessFlags dstAccess, VkPipelineStageFlags dstStage); private: - PStagingBuffer dedicatedStagingBuffer; + OStagingBuffer dedicatedStagingBuffer; }; DEFINE_REF(UniformBuffer) @@ -86,7 +86,7 @@ public: virtual ~ShaderBuffer(); virtual bool updateContents(const DataSource &sourceData); - virtual void* lock(bool bWriteOnly = true) override; + virtual void* lock(bool writeOnly = true) override; virtual void unlock() override; protected: // Inherited via Vulkan::Buffer @@ -98,7 +98,7 @@ protected: virtual void executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage, VkAccessFlags dstAccess, VkPipelineStageFlags dstStage); private: - PStagingBuffer dedicatedStagingBuffer; + OStagingBuffer dedicatedStagingBuffer; }; DEFINE_REF(ShaderBuffer) diff --git a/src/Engine/Graphics/Vulkan/CommandBuffer.cpp b/src/Engine/Graphics/Vulkan/CommandBuffer.cpp index 0076332..c8ec381 100644 --- a/src/Engine/Graphics/Vulkan/CommandBuffer.cpp +++ b/src/Engine/Graphics/Vulkan/CommandBuffer.cpp @@ -313,7 +313,7 @@ void RenderCommand::draw(uint32 vertexCount, uint32 instanceCount, int32 firstVe void RenderCommand::dispatch(uint32 groupX, uint32 groupY, uint32 groupZ) { assert(threadId == std::this_thread::get_id()); - vkCmdDrawMeshTasksEXT(handle, groupX, groupY, groupZ); + graphics->vkCmdDrawMeshTasksEXT(handle, groupX, groupY, groupZ); } ComputeCommand::ComputeCommand(PGraphics graphics, VkCommandPool cmdPool) @@ -524,4 +524,4 @@ void CommandBufferManager::submitCommands(PSemaphore signalSemaphore) allocatedBuffers.add(new CmdBuffer(graphics, commandPool, this)); activeCmdBuffer = allocatedBuffers.back(); activeCmdBuffer->begin(); -} +} \ No newline at end of file diff --git a/src/Engine/Graphics/Vulkan/DescriptorSets.cpp b/src/Engine/Graphics/Vulkan/DescriptorSets.cpp index 6f765f7..fa85344 100644 --- a/src/Engine/Graphics/Vulkan/DescriptorSets.cpp +++ b/src/Engine/Graphics/Vulkan/DescriptorSets.cpp @@ -2,6 +2,7 @@ #include "Graphics.h" #include "Initializer.h" #include "CommandBuffer.h" +#include "Texture.h" using namespace Seele; using namespace Seele::Vulkan; @@ -130,12 +131,12 @@ void DescriptorSet::updateBuffer(uint32_t binding, Gfx::PUniformBuffer uniformBu VkWriteDescriptorSet writeDescriptor = init::WriteDescriptorSet(setHandle, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, binding, &bufferInfos.back()); writeDescriptors.add(writeDescriptor); - cachedData[binding] = new UniformBuffer(*vulkanBuffer.getHandle()); + cachedData[binding] = vulkanBuffer.getHandle(); } -void DescriptorSet::updateBuffer(uint32_t binding, Gfx::PShaderBuffer ShaderBuffer) +void DescriptorSet::updateBuffer(uint32_t binding, Gfx::PShaderBuffer shaderBuffer) { - PShaderBuffer vulkanBuffer = ShaderBuffer.cast(); + PShaderBuffer vulkanBuffer = shaderBuffer.cast(); ShaderBuffer* cachedBuffer = reinterpret_cast(cachedData[binding]); if(vulkanBuffer.getHandle() == cachedBuffer) { @@ -349,21 +350,20 @@ Gfx::PDescriptorSet DescriptorAllocator::allocateDescriptorSet() VK_CHECK(vkAllocateDescriptorSets(graphics->getDevice(), &allocInfo, &cachedHandles[setIndex]->setHandle)); } cachedHandles[setIndex]->allocate(); - descriptorSet = cachedHandles[setIndex]; - PDescriptorSet vulkanSet = descriptorSet.cast(); + PDescriptorSet vulkanSet = cachedHandles[setIndex]; vulkanSet->cachedData.resize(layout.bindings.size()); // Not really pretty, but this way the set knows which ones are valid std::memset(vulkanSet->cachedData.data(), 0, sizeof(void*) * vulkanSet->cachedData.size()); //Found set, stop searching - return; + return vulkanSet; } if(nextAlloc == nullptr) { nextAlloc = new DescriptorAllocator(graphics, layout); } - nextAlloc->allocateDescriptorSet(descriptorSet); + return nextAlloc->allocateDescriptorSet(); //throw std::logic_error("Out of descriptor sets"); } diff --git a/src/Engine/Graphics/Vulkan/Enums.cpp b/src/Engine/Graphics/Vulkan/Enums.cpp index 8da81e4..bc6b258 100644 --- a/src/Engine/Graphics/Vulkan/Enums.cpp +++ b/src/Engine/Graphics/Vulkan/Enums.cpp @@ -1,4 +1,4 @@ -#include "VulkanGraphicsEnums.h" +#include "Enums.h" using namespace Seele; using namespace Seele::Vulkan; diff --git a/src/Engine/Graphics/Vulkan/Graphics.cpp b/src/Engine/Graphics/Vulkan/Graphics.cpp index d28e9f0..8da271c 100644 --- a/src/Engine/Graphics/Vulkan/Graphics.cpp +++ b/src/Engine/Graphics/Vulkan/Graphics.cpp @@ -8,6 +8,7 @@ #include "RenderTarget.h" #include "RenderPass.h" #include "Framebuffer.h" +#include "Shader.h" #include using namespace Seele; @@ -134,8 +135,8 @@ Gfx::OUniformBuffer Graphics::createUniformBuffer(const UniformBufferCreateInfo Gfx::OShaderBuffer Graphics::createShaderBuffer(const ShaderBufferCreateInfo &bulkData) { - OShaderBuffer ShaderBuffer = new ShaderBuffer(this, bulkData); - return ShaderBuffer; + OShaderBuffer shaderBuffer = new ShaderBuffer(this, bulkData); + return shaderBuffer; } Gfx::OVertexBuffer Graphics::createVertexBuffer(const VertexBufferCreateInfo &bulkData) { @@ -150,13 +151,13 @@ Gfx::OIndexBuffer Graphics::createIndexBuffer(const IndexBufferCreateInfo &bulkD } Gfx::PRenderCommand Graphics::createRenderCommand(const std::string& name) { - ORenderCommand cmdBuffer = getGraphicsCommands()->createRenderCommand(activeRenderPass, activeFramebuffer, name); + PRenderCommand cmdBuffer = getGraphicsCommands()->createRenderCommand(activeRenderPass, activeFramebuffer, name); return cmdBuffer; } Gfx::PComputeCommand Graphics::createComputeCommand(const std::string& name) { - OComputeCommand cmdBuffer = getComputeCommands()->createComputeCommand(name); + PComputeCommand cmdBuffer = getComputeCommands()->createComputeCommand(name); return cmdBuffer; } @@ -172,52 +173,51 @@ Gfx::OVertexShader Graphics::createVertexShader(const ShaderCreateInfo& createIn shader->create(createInfo); return shader; } -Gfx::PControlShader Graphics::createControlShader(const ShaderCreateInfo& createInfo) +Gfx::OFragmentShader Graphics::createFragmentShader(const ShaderCreateInfo& createInfo) { - PControlShader shader = new ControlShader(this); + OFragmentShader shader = new FragmentShader(this); shader->create(createInfo); return shader; } -Gfx::PEvaluationShader Graphics::createEvaluationShader(const ShaderCreateInfo& createInfo) +Gfx::OComputeShader Graphics::createComputeShader(const ShaderCreateInfo& createInfo) { - PEvaluationShader shader = new EvaluationShader(this); + OComputeShader shader = new ComputeShader(this); shader->create(createInfo); return shader; } -Gfx::PGeometryShader Graphics::createGeometryShader(const ShaderCreateInfo& createInfo) +Gfx::OTaskShader Graphics::createTaskShader(const ShaderCreateInfo& createInfo) { - PGeometryShader shader = new GeometryShader(this); + OTaskShader shader = new TaskShader(this); shader->create(createInfo); return shader; } -Gfx::PFragmentShader Graphics::createFragmentShader(const ShaderCreateInfo& createInfo) +Gfx::OMeshShader Graphics::createMeshShader(const ShaderCreateInfo& createInfo) { - PFragmentShader shader = new FragmentShader(this); - shader->create(createInfo); - return shader; -} -Gfx::PComputeShader Graphics::createComputeShader(const ShaderCreateInfo& createInfo) -{ - PComputeShader shader = new ComputeShader(this); + OMeshShader shader = new MeshShader(this); shader->create(createInfo); return shader; } -Gfx::PGraphicsPipeline Graphics::createGraphicsPipeline(const GraphicsPipelineCreateInfo& createInfo) +Gfx::OGraphicsPipeline Graphics::createGraphicsPipeline(const Gfx::LegacyPipelineCreateInfo& createInfo) { - PGraphicsPipeline pipeline = pipelineCache->createPipeline(createInfo); + OGraphicsPipeline pipeline = pipelineCache->createPipeline(createInfo); + return pipeline; +} +Gfx::OGraphicsPipeline Graphics::createGraphicsPipeline(const Gfx::MeshPipelineCreateInfo& createInfo) +{ + OGraphicsPipeline pipeline = pipelineCache->createPipeline(createInfo); return pipeline; } -Gfx::PComputePipeline Graphics::createComputePipeline(const ComputePipelineCreateInfo& createInfo) +Gfx::OComputePipeline Graphics::createComputePipeline(const Gfx::ComputePipelineCreateInfo& createInfo) { - PComputePipeline pipeline = pipelineCache->createPipeline(createInfo); + OComputePipeline pipeline = pipelineCache->createPipeline(createInfo); return pipeline; } -Gfx::PSamplerState Graphics::createSamplerState(const SamplerCreateInfo& createInfo) +Gfx::OSamplerState Graphics::createSamplerState(const SamplerCreateInfo& createInfo) { - PSamplerState sampler = new SamplerState(); + OSamplerState sampler = new SamplerState(); VkSamplerCreateInfo vkInfo = init::SamplerCreateInfo(); vkInfo.addressModeU = cast(createInfo.addressModeU); @@ -239,14 +239,14 @@ Gfx::PSamplerState Graphics::createSamplerState(const SamplerCreateInfo& createI VK_CHECK(vkCreateSampler(handle, &vkInfo, nullptr, &sampler->sampler)); return sampler; } -Gfx::PDescriptorLayout Graphics::createDescriptorLayout(const std::string& name) +Gfx::ODescriptorLayout Graphics::createDescriptorLayout(const std::string& name) { - PDescriptorLayout layout = new DescriptorLayout(this, name); + ODescriptorLayout layout = new DescriptorLayout(this, name); return layout; } -Gfx::PPipelineLayout Graphics::createPipelineLayout(Gfx::PPipelineLayout baseLayout) +Gfx::OPipelineLayout Graphics::createPipelineLayout(Gfx::PPipelineLayout baseLayout) { - PPipelineLayout layout = new PipelineLayout(this, baseLayout); + OPipelineLayout layout = new PipelineLayout(this, baseLayout); return layout; } @@ -317,6 +317,10 @@ void Graphics::copyTexture(Gfx::PTexture srcTexture, Gfx::PTexture dstTexture) } } +void Graphics::vkCmdDrawMeshTasksEXT(VkCommandBuffer handle, uint32 groupX, uint32 groupY, uint32 groupZ) +{ + cmdDrawMeshTasks(handle, groupX, groupY, groupZ); +} PCommandBufferManager Graphics::getQueueCommands(Gfx::QueueType queueType) { switch (queueType) @@ -361,7 +365,7 @@ PCommandBufferManager Graphics::getDedicatedTransferCommands() { if(dedicatedTransferCommands == nullptr) { - dedicatedTransferCommands = new CommandBufferManager(this, dedicatedTransferQueue); + dedicatedTransferCommands = new CommandBufferManager(this, dedicatedTransferQueue != nullptr ? dedicatedTransferQueue : transferQueue); } return dedicatedTransferCommands; } @@ -441,7 +445,7 @@ void Graphics::pickPhysicalDevice() { uint32 currentRating = 0; vkGetPhysicalDeviceProperties(dev, &props); - vkGetPhysicalDeviceFeatures(dev, &features); + vkGetPhysicalDeviceFeatures2(dev, &features); if (props.deviceType == VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU) { std::cout << "found dedicated gpu " << props.deviceName << std::endl; @@ -461,7 +465,7 @@ void Graphics::pickPhysicalDevice() } physicalDevice = bestDevice; vkGetPhysicalDeviceProperties(physicalDevice, &props); - vkGetPhysicalDeviceFeatures(physicalDevice, &features); + vkGetPhysicalDeviceFeatures2(physicalDevice, &features); } void Graphics::createDevice(GraphicsInitializer initializer) @@ -563,13 +567,13 @@ void Graphics::createDevice(GraphicsInitializer initializer) (uint32)queueInfos.size(), &features); - VkPhysicalDeviceDescriptorIndexingFeatures descriptorIndexing = {}; - std::memset(&descriptorIndexing, 0, sizeof(descriptorIndexing)); - descriptorIndexing.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES; - descriptorIndexing.shaderSampledImageArrayNonUniformIndexing = VK_TRUE; - descriptorIndexing.runtimeDescriptorArray = VK_TRUE; - descriptorIndexing.descriptorBindingVariableDescriptorCount = VK_TRUE; - descriptorIndexing.descriptorBindingPartiallyBound = VK_TRUE; + VkPhysicalDeviceDescriptorIndexingFeatures descriptorIndexing = { + .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES, + .shaderSampledImageArrayNonUniformIndexing = VK_TRUE, + .descriptorBindingPartiallyBound = VK_TRUE, + .descriptorBindingVariableDescriptorCount = VK_TRUE, + .runtimeDescriptorArray = VK_TRUE, + }; deviceInfo.pNext = &descriptorIndexing; #if ENABLE_VALIDATION VkDeviceDiagnosticsConfigCreateInfoNV crashDiagInfo; @@ -581,6 +585,18 @@ void Graphics::createDevice(GraphicsInitializer initializer) VK_DEVICE_DIAGNOSTICS_CONFIG_ENABLE_SHADER_DEBUG_INFO_BIT_NV; descriptorIndexing.pNext = &crashDiagInfo; #endif + VkPhysicalDeviceMeshShaderFeaturesEXT enabledMeshShaderFeatures = { + .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MESH_SHADER_FEATURES_EXT, + .taskShader = VK_TRUE, + .meshShader = VK_TRUE, + }; + if (Gfx::useMeshShading) + { + descriptorIndexing.pNext = &enabledMeshShaderFeatures; + initializer.deviceExtensions.add("VK_EXT_mesh_shader"); + initializer.deviceExtensions.add("VK_KHR_SPIRV_1_4_EXTENSION_NAME"); + initializer.deviceExtensions.add("VK_KHR_SHADER_FLOAT_CONTROLS_EXTENSION_NAME"); + } deviceInfo.enabledExtensionCount = (uint32)initializer.deviceExtensions.size(); deviceInfo.ppEnabledExtensionNames = initializer.deviceExtensions.data(); deviceInfo.enabledLayerCount = (uint32_t)initializer.layers.size(); @@ -590,6 +606,8 @@ void Graphics::createDevice(GraphicsInitializer initializer) VK_CHECK(vkCreateDevice(physicalDevice, &deviceInfo, nullptr, &handle)); std::cout << "Vulkan handle: " << handle << std::endl; + cmdDrawMeshTasks = (PFN_vkCmdDrawMeshTasksEXT)vkGetDeviceProcAddr(handle, "vkCmdDrawMeshTasksEXT"); + graphicsQueue = new Queue(this, Gfx::QueueType::GRAPHICS, graphicsQueueInfo.familyIndex, 0); if (Gfx::useAsyncCompute && asyncComputeInfo.familyIndex != -1) { @@ -613,12 +631,8 @@ void Graphics::createDevice(GraphicsInitializer initializer) { dedicatedTransferQueue = new Queue(this, Gfx::QueueType::DEDICATED_TRANSFER, dedicatedTransferQueueInfo.familyIndex, 0); } - else - { - dedicatedTransferQueue = transferQueue; - } queueMapping.graphicsFamily = graphicsQueue->getFamilyIndex(); queueMapping.computeFamily = computeQueue->getFamilyIndex(); queueMapping.transferFamily = transferQueue->getFamilyIndex(); - queueMapping.dedicatedTransferFamily = dedicatedTransferQueue->getFamilyIndex(); + queueMapping.dedicatedTransferFamily = dedicatedTransferQueue != nullptr ? dedicatedTransferQueue->getFamilyIndex() : transferQueue->getFamilyIndex(); } diff --git a/src/Engine/Graphics/Vulkan/Graphics.h b/src/Engine/Graphics/Vulkan/Graphics.h index c31b790..fb73da5 100644 --- a/src/Engine/Graphics/Vulkan/Graphics.h +++ b/src/Engine/Graphics/Vulkan/Graphics.h @@ -73,7 +73,9 @@ public: virtual Gfx::OPipelineLayout createPipelineLayout(Gfx::PPipelineLayout baseLayout = nullptr) override; virtual void copyTexture(Gfx::PTexture srcTexture, Gfx::PTexture dstTexture) override; + void vkCmdDrawMeshTasksEXT(VkCommandBuffer handle, uint32 groupX, uint32 groupY, uint32 groupZ); protected: + PFN_vkCmdDrawMeshTasksEXT cmdDrawMeshTasks; Array getRequiredExtensions(); void initInstance(GraphicsInitializer initInfo); void setupDebugCallback(); @@ -97,7 +99,7 @@ protected: thread_local static OCommandBufferManager transferCommands; thread_local static OCommandBufferManager dedicatedTransferCommands; VkPhysicalDeviceProperties props; - VkPhysicalDeviceFeatures features; + VkPhysicalDeviceFeatures2 features; VkDebugReportCallbackEXT callback; std::mutex viewportLock; Array viewports; diff --git a/src/Engine/Graphics/Vulkan/Initializer.cpp b/src/Engine/Graphics/Vulkan/Initializer.cpp index 854905e..11fe525 100644 --- a/src/Engine/Graphics/Vulkan/Initializer.cpp +++ b/src/Engine/Graphics/Vulkan/Initializer.cpp @@ -1,6 +1,7 @@ #include "Initializer.h" #include #include "Initializer.h" +#include "Initializer.h" using namespace Seele::Vulkan; diff --git a/src/Engine/Graphics/Vulkan/Initializer.h b/src/Engine/Graphics/Vulkan/Initializer.h index 822451b..50d37b5 100644 --- a/src/Engine/Graphics/Vulkan/Initializer.h +++ b/src/Engine/Graphics/Vulkan/Initializer.h @@ -51,6 +51,11 @@ VkDeviceCreateInfo DeviceCreateInfo( uint32_t queueCount, VkPhysicalDeviceFeatures *features); +VkDeviceCreateInfo DeviceCreateInfo( + VkDeviceQueueCreateInfo* queueInfos, + uint32_t queueCount, + VkPhysicalDeviceFeatures2* features); + VkSwapchainCreateInfoKHR SwapchainCreateInfo( VkSurfaceKHR surface, uint32_t minImageCount, diff --git a/src/Engine/Graphics/Vulkan/PipelineCache.cpp b/src/Engine/Graphics/Vulkan/PipelineCache.cpp index aa28f40..5499ec5 100644 --- a/src/Engine/Graphics/Vulkan/PipelineCache.cpp +++ b/src/Engine/Graphics/Vulkan/PipelineCache.cpp @@ -48,7 +48,7 @@ PipelineCache::~PipelineCache() std::cout << "Written " << cacheSize << " bytes to cache" << std::endl; } -PGraphicsPipeline PipelineCache::createPipeline(const Gfx::LegacyPipelineCreateInfo& gfxInfo) +OGraphicsPipeline PipelineCache::createPipeline(const Gfx::LegacyPipelineCreateInfo& gfxInfo) { uint32 stageCount = 0; @@ -99,7 +99,7 @@ PGraphicsPipeline PipelineCache::createPipeline(const Gfx::LegacyPipelineCreateI *res = VkVertexInputBindingDescription{ .binding = elem.binding, .stride = elem.stride, - .inputRate = elem.bInstanced ? VK_VERTEX_INPUT_RATE_INSTANCE : VK_VERTEX_INPUT_RATE_VERTEX, + .inputRate = elem.instanced ? VK_VERTEX_INPUT_RATE_INSTANCE : VK_VERTEX_INPUT_RATE_VERTEX, }; } vertexInput.pVertexAttributeDescriptions = attributes.data(); @@ -217,12 +217,12 @@ PGraphicsPipeline PipelineCache::createPipeline(const Gfx::LegacyPipelineCreateI std::cout << "Gfx creation time: " << delta << std::endl; - PGraphicsPipeline result = new GraphicsPipeline(graphics, pipelineHandle, layout); + OGraphicsPipeline result = new GraphicsPipeline(graphics, pipelineHandle, layout); return result; } -PGraphicsPipeline PipelineCache::createPipeline(const Gfx::MeshPipelineCreateInfo& gfxInfo) +OGraphicsPipeline PipelineCache::createPipeline(const Gfx::MeshPipelineCreateInfo& gfxInfo) { uint32 stageCount = 0; @@ -361,33 +361,35 @@ PGraphicsPipeline PipelineCache::createPipeline(const Gfx::MeshPipelineCreateInf int64 delta = std::chrono::duration_cast(endTime - beginTime).count(); std::cout << "Gfx creation time: " << delta << std::endl; - - PGraphicsPipeline result = new GraphicsPipeline(graphics, pipelineHandle, layout); + OGraphicsPipeline result = new GraphicsPipeline(graphics, pipelineHandle, layout); return result; } -PComputePipeline PipelineCache::createPipeline(const Gfx::ComputePipelineCreateInfo& computeInfo) +OComputePipeline PipelineCache::createPipeline(const Gfx::ComputePipelineCreateInfo& computeInfo) { - VkComputePipelineCreateInfo createInfo; - createInfo.sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO; - createInfo.pNext = 0; - createInfo.flags = 0; - createInfo.basePipelineIndex = 0; - createInfo.basePipelineHandle = VK_NULL_HANDLE; auto layout = computeInfo.pipelineLayout.cast(); - createInfo.layout = layout->getHandle(); auto computeStage = computeInfo.computeShader.cast(); - createInfo.stage = init::PipelineShaderStageCreateInfo( - VK_SHADER_STAGE_COMPUTE_BIT, - computeStage->getModuleHandle(), - computeStage->getEntryPointName()); + + VkComputePipelineCreateInfo createInfo = { + .sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO, + .pNext = 0, + .flags = 0, + .stage = init::PipelineShaderStageCreateInfo( + VK_SHADER_STAGE_COMPUTE_BIT, + computeStage->getModuleHandle(), + computeStage->getEntryPointName()), + .layout = layout->getHandle(), + .basePipelineHandle = VK_NULL_HANDLE, + .basePipelineIndex = 0, + }; + VkPipeline pipelineHandle; auto beginTime = std::chrono::high_resolution_clock::now(); VK_CHECK(vkCreateComputePipelines(graphics->getDevice(), cache, 1, &createInfo, nullptr, &pipelineHandle)); auto endTime = std::chrono::high_resolution_clock::now(); int64 delta = std::chrono::duration_cast(endTime - beginTime).count(); std::cout << "Compute creation time: " << delta << std::endl; - PComputePipeline result = new ComputePipeline(graphics, pipelineHandle, layout); + OComputePipeline result = new ComputePipeline(graphics, pipelineHandle, layout); return result; } \ No newline at end of file diff --git a/src/Engine/Graphics/Vulkan/PipelineCache.h b/src/Engine/Graphics/Vulkan/PipelineCache.h index 8cd0493..98dbc2d 100644 --- a/src/Engine/Graphics/Vulkan/PipelineCache.h +++ b/src/Engine/Graphics/Vulkan/PipelineCache.h @@ -10,9 +10,9 @@ class PipelineCache public: PipelineCache(PGraphics graphics, const std::string& cacheFilePath); ~PipelineCache(); - PGraphicsPipeline createPipeline(const Gfx::LegacyPipelineCreateInfo& createInfo); - PGraphicsPipeline createPipeline(const Gfx::MeshPipelineCreateInfo& createInfo); - PComputePipeline createPipeline(const Gfx::ComputePipelineCreateInfo& createInfo); + OGraphicsPipeline createPipeline(const Gfx::LegacyPipelineCreateInfo& createInfo); + OGraphicsPipeline createPipeline(const Gfx::MeshPipelineCreateInfo& createInfo); + OComputePipeline createPipeline(const Gfx::ComputePipelineCreateInfo& createInfo); private: VkPipelineCache cache; PGraphics graphics; diff --git a/src/Engine/Graphics/Vulkan/RenderPass.cpp b/src/Engine/Graphics/Vulkan/RenderPass.cpp index 4ac9c8e..82c1d11 100644 --- a/src/Engine/Graphics/Vulkan/RenderPass.cpp +++ b/src/Engine/Graphics/Vulkan/RenderPass.cpp @@ -3,6 +3,7 @@ #include "Graphics.h" #include "Framebuffer.h" #include "Texture.h" +#include "RenderPass.h" using namespace Seele; using namespace Seele::Vulkan; @@ -143,4 +144,5 @@ uint32 RenderPass::getFramebufferHash() description.depthAttachment = tex->getView(); } return CRC::Calculate(&description, sizeof(FramebufferDescription), CRC::CRC_32()); -} \ No newline at end of file +} + diff --git a/src/Engine/Graphics/Vulkan/Texture.cpp b/src/Engine/Graphics/Vulkan/Texture.cpp index d4a5654..6b71cdf 100644 --- a/src/Engine/Graphics/Vulkan/Texture.cpp +++ b/src/Engine/Graphics/Vulkan/Texture.cpp @@ -1,10 +1,6 @@ -#include "VulkanGraphicsResources.h" -#include "VulkanGraphics.h" -#include "VulkanInitializer.h" -#include "VulkanGraphicsEnums.h" -#include "VulkanAllocator.h" -#include "VulkanCommandBuffer.h" -#include "Graphics/GraphicsEnums.h" +#include "Texture.h" +#include "Initializer.h" +#include "CommandBuffer.h" #include using namespace Seele; diff --git a/src/Engine/Material/Material.cpp b/src/Engine/Material/Material.cpp index 4ab733c..02bbcfe 100644 --- a/src/Engine/Material/Material.cpp +++ b/src/Engine/Material/Material.cpp @@ -9,23 +9,23 @@ Material::Material() { } -Material::Material(Gfx::PGraphics graphics, - Array parameter, +Material::Material(Gfx::PGraphics graphics, Gfx::ODescriptorLayout layout, uint32 uniformDataSize, uint32 uniformBinding, std::string materialName, - Array expressions, + Map expressions, + Array parameter, MaterialNode brdf) : graphics(graphics) - , parameters(std::move(parameter)) , uniformDataSize(uniformDataSize) , uniformBinding(uniformBinding) + , instanceId(0) , layout(std::move(layout)) , materialName(materialName) , codeExpressions(std::move(expressions)) - , brdf(brdf) - , instanceId(0) + , parameters(std::move(parameter)) + , brdf(std::move(brdf)) { } @@ -33,14 +33,19 @@ Material::~Material() { } -PMaterialInstance Seele::Material::instantiate() +OMaterialInstance Material::instantiate() { - return new MaterialInstance(instanceId++, graphics, this, layout, parameters, uniformBinding, uniformDataSize); + return new MaterialInstance( + instanceId++, + graphics, + codeExpressions, + parameters, + uniformBinding, + uniformDataSize); } void Material::save(ArchiveBuffer& buffer) const { - Serialization::save(buffer, brdfName); Serialization::save(buffer, uniformDataSize); Serialization::save(buffer, uniformBinding); Serialization::save(buffer, instanceId); @@ -59,13 +64,11 @@ void Material::save(ArchiveBuffer& buffer) const Serialization::save(buffer, binding.descriptorType); Serialization::save(buffer, binding.shaderStages); } - Serialization::save(buffer, instances); } void Material::load(ArchiveBuffer& buffer) { graphics = buffer.getGraphics(); - Serialization::load(buffer, brdfName); Serialization::load(buffer, uniformDataSize); Serialization::load(buffer, uniformBinding); Serialization::load(buffer, instanceId); @@ -98,11 +101,6 @@ void Material::load(ArchiveBuffer& buffer) layout->addDescriptorBinding(binding, descriptorType, descriptorCount, bindingFlags, shaderStages); } layout->create(); - Serialization::load(buffer, instances); - for (auto& instance : instances) - { - instance->setBaseMaterial(this); - } } void Material::compile() @@ -114,21 +112,23 @@ void Material::compile() codeStream << "struct " << materialName << " : IMaterial {\n"; for(const auto& parameter : parameters) { - parameter->generateDeclaration(codeStream); + PShaderParameter handle = PShaderExpression(codeExpressions[parameter]); + handle->generateDeclaration(codeStream); } codeStream << "\ttypedef " << brdf.profile << " BRDF;\n"; codeStream << "\t" << brdf.profile << " prepare(MaterialFragmentParameter input) {\n"; codeStream << "\t\t" << brdf.profile << " result;\n"; - Map varState; - for(const auto& expr : codeExpressions) + Map varState; + for(const auto& [_, expr] :codeExpressions) { codeStream << expr->evaluate(varState); } for(const auto& [name, exp] : brdf.variables) { - codeStream << "\t\tresult." << name << " = " << varState[exp->key] << ";"; + codeStream << "\t\tresult." << name << " = " << varState[exp] << ";"; } codeStream << "\t\treturn result;\n"; codeStream << "\t}\n"; codeStream << "};\n"; + graphics->getShaderCompiler()->registerMaterial(this); } diff --git a/src/Engine/Material/Material.h b/src/Engine/Material/Material.h index 446a949..65e4bba 100644 --- a/src/Engine/Material/Material.h +++ b/src/Engine/Material/Material.h @@ -9,18 +9,17 @@ class Material { public: Material(); - Material(Gfx::PGraphics graphics, - Array parameter, + Material(Gfx::PGraphics graphics, Gfx::ODescriptorLayout layout, uint32 uniformDataSize, uint32 uniformBinding, std::string materialName, - Array expressions, + Map expressions, + Array parameter, MaterialNode brdf); ~Material(); const Gfx::PDescriptorLayout getDescriptorLayout() const { return layout; } - PMaterialInstance instantiate(); - PMaterialInstance getInstance(uint64 instance) { return instances[instance]; } + OMaterialInstance instantiate(); const std::string& getName() const { return materialName; } void save(ArchiveBuffer& buffer) const; @@ -30,15 +29,13 @@ public: private: Gfx::PGraphics graphics; - std::string brdfName; uint32 uniformDataSize; uint32 uniformBinding; uint64 instanceId; Gfx::ODescriptorLayout layout; std::string materialName; - Array codeExpressions; - Array parameters; - Array instances; + Map codeExpressions; + Array parameters; MaterialNode brdf; }; DEFINE_REF(Material) diff --git a/src/Engine/Material/MaterialInstance.cpp b/src/Engine/Material/MaterialInstance.cpp index 08bbb00..ad709fe 100644 --- a/src/Engine/Material/MaterialInstance.cpp +++ b/src/Engine/Material/MaterialInstance.cpp @@ -8,17 +8,34 @@ MaterialInstance::MaterialInstance() { } -MaterialInstance::MaterialInstance(uint64 id, Gfx::PGraphics graphics, PMaterial baseMaterial, Gfx::PDescriptorLayout layout, Array params, uint32 uniformBinding, uint32 uniformSize) - : id(id), graphics(graphics), baseMaterial(baseMaterial), layout(layout), parameters(params), uniformBinding(uniformBinding) +MaterialInstance::MaterialInstance(uint64 id, + Gfx::PGraphics graphics, + Map& expressions, + Array params, + uint32 uniformBinding, + uint32 uniformSize) + : id(id) + , graphics(graphics) + , uniformBinding(uniformBinding) { uniformBuffer = graphics->createUniformBuffer(UniformBufferCreateInfo{ .sourceData = { .size = uniformSize, }, - .bDynamic = true, + .dynamic = true, } ); uniformData.resize(uniformSize); + ArchiveBuffer buffer(graphics); + parameters.reserve(params.size()); + for (int i = 0; i < params.size(); ++i) + { + Serialization::save(buffer, params[i]); + buffer.rewind(); + OShaderParameter param; + Serialization::load(buffer, param); + parameters.add(std::move(param)); + } } MaterialInstance::~MaterialInstance() @@ -28,6 +45,8 @@ MaterialInstance::~MaterialInstance() void MaterialInstance::updateDescriptor() { + Gfx::PDescriptorLayout layout = baseMaterial->getMaterial()->getDescriptorLayout(); + layout->reset(); descriptor = layout->allocateDescriptorSet(); for (auto& param : parameters) { @@ -36,16 +55,27 @@ void MaterialInstance::updateDescriptor() descriptor->writeChanges(); } -Gfx::PDescriptorSet Seele::MaterialInstance::getDescriptorSet() const +Gfx::PDescriptorSet MaterialInstance::getDescriptorSet() const { return descriptor; } +void MaterialInstance::setBaseMaterial(PMaterialAsset asset) +{ + uniformBuffer = graphics->createUniformBuffer(UniformBufferCreateInfo{ + .sourceData = { + .size = uniformData.size(), + }, + .dynamic = true, + } + ); + baseMaterial = asset; +} + void MaterialInstance::save(ArchiveBuffer& buffer) const { Serialization::save(buffer, uniformData); Serialization::save(buffer, uniformBinding); - Serialization::save(buffer, uniformBuffer); Serialization::save(buffer, parameters); Serialization::save(buffer, id); } @@ -55,19 +85,6 @@ void MaterialInstance::load(ArchiveBuffer& buffer) graphics = buffer.getGraphics(); Serialization::load(buffer, uniformData); Serialization::load(buffer, uniformBinding); - Serialization::load(buffer, uniformBuffer); Serialization::load(buffer, parameters); Serialization::load(buffer, id); } - -void MaterialInstance::setBaseMaterial(PMaterial material) -{ - layout = material->getDescriptorLayout(); - baseMaterial = material; - descriptor = layout->allocateDescriptorSet(); - for (auto& param : parameters) - { - param->updateDescriptorSet(descriptor, uniformData.data()); - } - descriptor->writeChanges(); -} diff --git a/src/Engine/Material/MaterialInstance.h b/src/Engine/Material/MaterialInstance.h index 5cbc6df..d663dd5 100644 --- a/src/Engine/Material/MaterialInstance.h +++ b/src/Engine/Material/MaterialInstance.h @@ -1,6 +1,7 @@ #pragma once #include "Material.h" #include "Graphics/Buffer.h" +#include "Asset/MaterialAsset.h" namespace Seele { @@ -8,16 +9,22 @@ class MaterialInstance { public: MaterialInstance(); - MaterialInstance(uint64 id, Gfx::PGraphics graphics, PMaterial baseMaterial, Gfx::PDescriptorLayout descriptor, Array params, uint32 uniformBinding, uint32 uniformSize); + MaterialInstance(uint64 id, + Gfx::PGraphics graphics, + Map& expressions, + Array params, + uint32 uniformBinding, + uint32 uniformSize); ~MaterialInstance(); void updateDescriptor(); Gfx::PDescriptorSet getDescriptorSet() const; - PMaterial getBaseMaterial() const { return baseMaterial; } + PMaterial getBaseMaterial() const { return baseMaterial->getMaterial(); } uint64 getId() const { return id; } + void setBaseMaterial(PMaterialAsset asset); + void save(ArchiveBuffer& buffer) const; void load(ArchiveBuffer& buffer); - void setBaseMaterial(PMaterial material); private: Gfx::PGraphics graphics; @@ -25,9 +32,8 @@ private: uint32 uniformBinding; Gfx::OUniformBuffer uniformBuffer; Array parameters; - Gfx::PDescriptorLayout layout; Gfx::PDescriptorSet descriptor; - PMaterial baseMaterial; + PMaterialAsset baseMaterial; uint64 id; }; DEFINE_REF(MaterialInstance) diff --git a/src/Engine/Material/ShaderExpression.cpp b/src/Engine/Material/ShaderExpression.cpp index d1d566c..5153f06 100644 --- a/src/Engine/Material/ShaderExpression.cpp +++ b/src/Engine/Material/ShaderExpression.cpp @@ -31,6 +31,15 @@ void ExpressionOutput::load(ArchiveBuffer& buffer) Serialization::load(buffer, type); } +ShaderExpression::ShaderExpression() +{ +} + +ShaderExpression::ShaderExpression(std::string key) + : key(key) +{ +} + void ShaderExpression::save(ArchiveBuffer& buffer) const { Serialization::save(buffer, inputs); @@ -46,7 +55,7 @@ void ShaderExpression::load(ArchiveBuffer& buffer) } ShaderParameter::ShaderParameter(std::string name, uint32 byteOffset, uint32 binding) - : name(name) + : ShaderExpression(name) , byteOffset(byteOffset) , binding(binding) { @@ -56,16 +65,16 @@ ShaderParameter::~ShaderParameter() { } -std::string ShaderParameter::evaluate(Map& varState) const +std::string ShaderParameter::evaluate(Map& varState) const { - varState[key] = name; + varState[key] = key; return ""; } void ShaderParameter::save(ArchiveBuffer& buffer) const { ShaderExpression::save(buffer); - Serialization::save(buffer, name); + Serialization::save(buffer, key); Serialization::save(buffer, byteOffset); Serialization::save(buffer, binding); } @@ -73,7 +82,7 @@ void ShaderParameter::save(ArchiveBuffer& buffer) const void ShaderParameter::load(ArchiveBuffer& buffer) { ShaderExpression::load(buffer); - Serialization::load(buffer, name); + Serialization::load(buffer, key); Serialization::load(buffer, byteOffset); Serialization::load(buffer, binding); } @@ -109,7 +118,7 @@ void FloatParameter::updateDescriptorSet(Gfx::PDescriptorSet, uint8* dst) void FloatParameter::generateDeclaration(std::ofstream& stream) const { - stream << "\tlayout(offset = " << byteOffset << ") float " << name << ";\n"; + stream << "\tlayout(offset = " << byteOffset << ") float " << key << ";\n"; } VectorParameter::VectorParameter(std::string name, uint32 byteOffset, uint32 binding) @@ -131,7 +140,7 @@ void VectorParameter::updateDescriptorSet(Gfx::PDescriptorSet, uint8* dst) void VectorParameter::generateDeclaration(std::ofstream& stream) const { - stream << "\tlayout(offset = " << byteOffset << ") float3 " << name << ";\n"; + stream << "\tlayout(offset = " << byteOffset << ") float3 " << key << ";\n"; } void VectorParameter::save(ArchiveBuffer& buffer) const @@ -164,7 +173,7 @@ void TextureParameter::updateDescriptorSet(Gfx::PDescriptorSet descriptorSet, ui void TextureParameter::generateDeclaration(std::ofstream& stream) const { - stream << "\tTexture2D " << name << ";\n"; + stream << "\tTexture2D " << key << ";\n"; } void TextureParameter::save(ArchiveBuffer& buffer) const @@ -200,7 +209,7 @@ void SamplerParameter::updateDescriptorSet(Gfx::PDescriptorSet descriptorSet, ui void SamplerParameter::generateDeclaration(std::ofstream& stream) const { - stream << "\tSamplerState " << name << ";\n"; + stream << "\tSamplerState " << key << ";\n"; } void SamplerParameter::save(ArchiveBuffer& buffer) const @@ -233,7 +242,7 @@ void CombinedTextureParameter::updateDescriptorSet(Gfx::PDescriptorSet descripto void CombinedTextureParameter::generateDeclaration(std::ofstream& stream) const { - stream << "\tTexture2D " << name << ";\n"; + stream << "\tTexture2D " << key << ";\n"; } void CombinedTextureParameter::save(ArchiveBuffer& buffer) const @@ -267,9 +276,9 @@ ConstantExpression::~ConstantExpression() } -std::string ConstantExpression::evaluate(Map& varState) const +std::string ConstantExpression::evaluate(Map& varState) const { - std::string varName = std::format("const_exp_{}", std::abs(key)); + std::string varName = std::format("const_exp_{}", key); varState[key] = varName; return std::format("let {} = {};\n", varName, expr); } @@ -296,7 +305,7 @@ AddExpression::~AddExpression() } -std::string AddExpression::evaluate(Map& varState) const +std::string AddExpression::evaluate(Map& varState) const { std::string varName = std::format("exp_{}", key); varState[key] = varName; @@ -313,7 +322,7 @@ void AddExpression::load(ArchiveBuffer& buffer) ShaderExpression::load(buffer); } -std::string SubExpression::evaluate(Map& varState) const +std::string SubExpression::evaluate(Map& varState) const { std::string varName = std::format("exp_{}", key); varState[key] = varName; @@ -330,7 +339,7 @@ void SubExpression::load(ArchiveBuffer& buffer) ShaderExpression::load(buffer); } -std::string MulExpression::evaluate(Map& varState) const +std::string MulExpression::evaluate(Map& varState) const { std::string varName = std::format("exp_{}", key); varState[key] = varName; @@ -347,7 +356,7 @@ void MulExpression::load(ArchiveBuffer& buffer) ShaderExpression::load(buffer); } -std::string SwizzleExpression::evaluate(Map& varState) const +std::string SwizzleExpression::evaluate(Map& varState) const { std::string varName = std::format("exp_{}", key); std::string swizzle = ""; @@ -370,6 +379,7 @@ std::string SwizzleExpression::evaluate(Map& varState) const break; case 3: swizzle += "w"; + break; default: throw std::logic_error("invalid component"); } @@ -390,7 +400,7 @@ void SwizzleExpression::load(ArchiveBuffer& buffer) Serialization::load(buffer, comp); } -std::string SampleExpression::evaluate(Map& varState) const +std::string SampleExpression::evaluate(Map& varState) const { std::string varName = std::format("exp_{}", key); varState[key] = varName; diff --git a/src/Engine/Material/ShaderExpression.h b/src/Engine/Material/ShaderExpression.h index cef7c81..7e30a22 100644 --- a/src/Engine/Material/ShaderExpression.h +++ b/src/Engine/Material/ShaderExpression.h @@ -18,7 +18,7 @@ enum class ExpressionType }; struct ExpressionInput { - int source; + std::string source; ExpressionType type = ExpressionType::UNKNOWN; void save(ArchiveBuffer& buffer) const; void load(ArchiveBuffer& buffer); @@ -35,9 +35,11 @@ struct ShaderExpression { Map inputs; ExpressionOutput output; - int32 key; + std::string key; + ShaderExpression(); + ShaderExpression(std::string key); virtual uint64 getIdentifier() const = 0; - virtual std::string evaluate(Map& varState) const = 0; + virtual std::string evaluate(Map& varState) const = 0; virtual void save(ArchiveBuffer& buffer) const; virtual void load(ArchiveBuffer& buffer); }; @@ -46,7 +48,6 @@ DEFINE_REF(ShaderExpression) DECLARE_NAME_REF(Gfx, DescriptorSet) struct ShaderParameter : public ShaderExpression { - std::string name; uint32 byteOffset; uint32 binding; ShaderParameter() {} @@ -56,7 +57,7 @@ struct ShaderParameter : public ShaderExpression virtual void updateDescriptorSet(Gfx::PDescriptorSet descriptorSet, uint8* dst) = 0; virtual void generateDeclaration(std::ofstream& stream) const = 0; virtual uint64 getIdentifier() const = 0; - virtual std::string evaluate(Map& varState) const override; + virtual std::string evaluate(Map& varState) const override; virtual void save(ArchiveBuffer& buffer) const; virtual void load(ArchiveBuffer& buffer); }; @@ -143,7 +144,7 @@ struct ConstantExpression : public ShaderExpression ConstantExpression(std::string expr, ExpressionType type); virtual ~ConstantExpression(); virtual uint64 getIdentifier() const { return IDENTIFIER; } - virtual std::string evaluate(Map& varState) const override; + virtual std::string evaluate(Map& varState) const override; virtual void save(ArchiveBuffer& buffer) const override; virtual void load(ArchiveBuffer& buffer) override; }; @@ -154,7 +155,7 @@ struct AddExpression : public ShaderExpression AddExpression(); virtual ~AddExpression(); virtual uint64 getIdentifier() const { return IDENTIFIER; } - virtual std::string evaluate(Map& varState) const override; + virtual std::string evaluate(Map& varState) const override; virtual void save(ArchiveBuffer& buffer) const override; virtual void load(ArchiveBuffer& buffer) override; }; @@ -165,7 +166,7 @@ struct SubExpression : public ShaderExpression SubExpression() {} virtual ~SubExpression() {} virtual uint64 getIdentifier() const { return IDENTIFIER; } - virtual std::string evaluate(Map& varState) const override; + virtual std::string evaluate(Map& varState) const override; virtual void save(ArchiveBuffer& buffer) const override; virtual void load(ArchiveBuffer& buffer) override; }; @@ -176,7 +177,7 @@ struct MulExpression : public ShaderExpression MulExpression() {} virtual ~MulExpression() {} virtual uint64 getIdentifier() const { return IDENTIFIER; } - virtual std::string evaluate(Map& varState) const override; + virtual std::string evaluate(Map& varState) const override; virtual void save(ArchiveBuffer& buffer) const override; virtual void load(ArchiveBuffer& buffer) override; }; @@ -188,7 +189,7 @@ struct SwizzleExpression : public ShaderExpression SwizzleExpression() {} virtual ~SwizzleExpression() {} virtual uint64 getIdentifier() const { return IDENTIFIER; } - virtual std::string evaluate(Map& varState) const override; + virtual std::string evaluate(Map& varState) const override; virtual void save(ArchiveBuffer& buffer) const override; virtual void load(ArchiveBuffer& buffer) override; }; @@ -199,7 +200,7 @@ struct SampleExpression : public ShaderExpression SampleExpression() {} virtual ~SampleExpression() {} virtual uint64 getIdentifier() const { return IDENTIFIER; } - virtual std::string evaluate(Map& varState) const override; + virtual std::string evaluate(Map& varState) const override; virtual void save(ArchiveBuffer& buffer) const override; virtual void load(ArchiveBuffer& buffer) override; }; @@ -208,7 +209,7 @@ DEFINE_REF(SampleExpression) struct MaterialNode { std::string profile; - Map variables; + Map variables; MaterialNode() {} ~MaterialNode() {} void save(ArchiveBuffer& buffer) const; diff --git a/src/Engine/Math/Math.h b/src/Engine/Math/Math.h index 9a18713..885473c 100644 --- a/src/Engine/Math/Math.h +++ b/src/Engine/Math/Math.h @@ -53,9 +53,4 @@ struct Rect3D Vector size; Vector offset; }; -template -inline constexpr T align(const T ptr, int64_t alignment) -{ - return (T)(((uint64_t)ptr + alignment - 1) & ~(alignment - 1)); -} } // namespace Seele \ No newline at end of file diff --git a/src/Engine/Math/Transform.cpp b/src/Engine/Math/Transform.cpp index 4c5a51c..6c11c56 100644 --- a/src/Engine/Math/Transform.cpp +++ b/src/Engine/Math/Transform.cpp @@ -41,10 +41,6 @@ Transform::Transform(Quaternion rotation, Vector scale) Transform::~Transform() { } -Vector Transform::inverseTransformPosition(const Vector &v) const -{ - return (unrotateVector(rotation, v - Vector(position))) * getSafeScaleReciprocal(scale); -} Matrix4 Transform::toMatrix() const { Matrix4 mat; @@ -95,35 +91,6 @@ Matrix4 Transform::toMatrix() const return mat; } -Vector Transform::getSafeScaleReciprocal(const Vector4 &inScale, float tolerance) -{ - Vector safeReciprocalScale; - if (abs(inScale.x) <= tolerance) - { - safeReciprocalScale.x = 0.f; - } - else - { - safeReciprocalScale.x = 1 / inScale.x; - } - if (abs(inScale.y) <= tolerance) - { - safeReciprocalScale.y = 0.f; - } - else - { - safeReciprocalScale.y = 1 / inScale.y; - } - if (abs(inScale.z) <= tolerance) - { - safeReciprocalScale.z = 0.f; - } - else - { - safeReciprocalScale.z = 1 / inScale.z; - } - return safeReciprocalScale; -} Vector Transform::transformPosition(const Vector &v) const { diff --git a/src/Engine/Math/Transform.h b/src/Engine/Math/Transform.h index 6252e97..1a6bb2e 100644 --- a/src/Engine/Math/Transform.h +++ b/src/Engine/Math/Transform.h @@ -17,9 +17,7 @@ public: Transform(Vector position, Quaternion rotation, Vector scale); Transform(Quaternion rotation, Vector scale); ~Transform(); - Vector inverseTransformPosition(const Vector &v) const; Matrix4 toMatrix() const; - static Vector getSafeScaleReciprocal(const Vector4 &inScale, float tolerance = 0.000000001f); Vector transformPosition(const Vector &v) const; Vector getPosition() const; diff --git a/src/Engine/Math/Vector.h b/src/Engine/Math/Vector.h index 0d3ed16..739180a 100644 --- a/src/Engine/Math/Vector.h +++ b/src/Engine/Math/Vector.h @@ -12,7 +12,6 @@ #pragma warning(pop) #endif #include -#include "Serialization/Serialization.h" namespace Seele { @@ -32,103 +31,8 @@ typedef glm::quat Quaternion; Vector parseVector(const char*); -static inline float square(float x) -{ - return x * x; -} - -static inline Vector unrotateVector(Quaternion quaternion, Vector v) -{ - const Vector q(-quaternion.x, -quaternion.y, -quaternion.z); - const Vector t = 2.f * glm::cross(q, v); - const Vector result = v + (quaternion.w * t) + glm::cross(q, t); - return result; -} - -static inline bool equalsQuaternion(const Quaternion &right, const Quaternion &left, float tolerance) -{ - return (abs(right.x - left.x) <= tolerance && abs(right.y - left.y) <= tolerance && abs(right.z - left.z) <= tolerance && abs(right.w - left.w) <= tolerance) || (abs(right.x + left.x) <= tolerance && abs(right.y + left.y) <= tolerance && abs(right.z + left.z) <= tolerance && abs(right.w + left.w) <= tolerance); -} - -static inline float clampRotatorAxis(float angle) -{ - angle = fmod(angle, 360.f); - if (angle < 0.f) - { - angle += 360.f; - } - return angle; -} -static inline float normalizeRotatorAxis(float angle) -{ - angle = clampRotatorAxis(angle); - - if (angle > 180.f) - { - angle -= 360.f; - } - return angle; -} - - -static inline Vector toRotator(const Quaternion &other) -{ - const float singularityTest = other.z * other.x - other.w * other.y; - const float yawY = 2.f * (other.w * other.z + other.x * other.y); - const float yawX = (1.f - 2.f * (square(other.y) + square(other.z))); - - const float SINGULARITY_THRESHOLD = 0.4999995f; - constexpr const float RAD_TO_DEG = (180.f) / glm::pi(); - Vector rotatorFromQuat; - - if (singularityTest < -SINGULARITY_THRESHOLD) - { - rotatorFromQuat.x = -90.f; - rotatorFromQuat.y = atan2(yawY, yawX) * RAD_TO_DEG; - rotatorFromQuat.z = normalizeRotatorAxis(-rotatorFromQuat.y - (2.f * atan2(other.x, other.w) * RAD_TO_DEG)); - } - else if (singularityTest > SINGULARITY_THRESHOLD) - { - rotatorFromQuat.x = 90.f; - rotatorFromQuat.y = atan2(yawY, yawX) * RAD_TO_DEG; - rotatorFromQuat.z = normalizeRotatorAxis(rotatorFromQuat.y - (2.f * atan2(other.x, other.w) * RAD_TO_DEG)); - } - else - { - rotatorFromQuat.x = asin(2.f * (singularityTest)) * RAD_TO_DEG; - rotatorFromQuat.y = atan2(yawY, yawX) * RAD_TO_DEG; - rotatorFromQuat.z = atan2(-2.f * (other.w * other.x + other.y * other.z), (1.f - 2.f * (square(other.x) + square(other.y)))) * RAD_TO_DEG; - } - return rotatorFromQuat; -} void to_json(nlohmann::json& j, const Vector& vec); void from_json(nlohmann::json& j, Vector& vec); - -namespace Serialization -{ - static void save(ArchiveBuffer& buffer, const IVector2& vec) - { - save(buffer, vec.x); - save(buffer, vec.y); - } - static void load(ArchiveBuffer& buffer, IVector2& vec) - { - save(buffer, vec.x); - save(buffer, vec.y); - } - static void save(ArchiveBuffer& buffer, const Vector& vec) - { - save(buffer, vec.x); - save(buffer, vec.y); - save(buffer, vec.z); - } - static void load(ArchiveBuffer& buffer, Vector& vec) - { - save(buffer, vec.x); - save(buffer, vec.y); - save(buffer, vec.z); - } -} // namespace Serialization } // namespace Seele std::ostream& operator<<(std::ostream& stream, const Seele::Vector2& vector); diff --git a/src/Engine/MinimalEngine.h b/src/Engine/MinimalEngine.h index 5043187..c84d903 100644 --- a/src/Engine/MinimalEngine.h +++ b/src/Engine/MinimalEngine.h @@ -26,56 +26,6 @@ namespace Seele { -template > -class OwningPtr -{ -public: - OwningPtr() - : pointer(nullptr) - { - } - OwningPtr(T* ptr) - : pointer(ptr) - {} - template - OwningPtr(OwningPtr&& other) - { - pointer = static_cast(other.pointer); - } - OwningPtr(const OwningPtr& other) = delete; - OwningPtr(OwningPtr&& other) - { - pointer = other.pointer; - other.pointer = nullptr; - } - OwningPtr& operator=(const OwningPtr& other) = delete; - OwningPtr& operator=(OwningPtr&& other) - { - if (this != &other) - { - pointer = other.pointer; - } - return *this; - } - constexpr T* operator->() - { - return pointer; - } - constexpr const T* operator->() const - { - return pointer; - } - constexpr bool operator==(const OwningPtr& rhs) const noexcept - { - return pointer == rhs.pointer; - } - constexpr auto operator<=>(const OwningPtr& rhs) const noexcept - { - return pointer <=> rhs.pointer; - } -private: - T* pointer; -}; template class RefPtr { @@ -88,44 +38,42 @@ public: : object(nullptr) { } - RefPtr(T *ptr) + RefPtr(T* ptr) : object(ptr) { } - constexpr RefPtr(const RefPtr &other) noexcept + constexpr RefPtr(const RefPtr& other) noexcept : object(other.object) { } - constexpr RefPtr(RefPtr &&rhs) noexcept + constexpr RefPtr(RefPtr&& rhs) noexcept : object(std::move(rhs.object)) { rhs.object = nullptr; } template - constexpr RefPtr(const RefPtr &other) + constexpr RefPtr cast() { - object = other.cast(); - } - constexpr RefPtr(OwningPtr& owning) - { - object = owning.getHandle(); - } - constexpr RefPtr(const OwningPtr& owning) - { - object = owning.getHandle(); - } - template - constexpr const RefPtr cast() const - { - T *t = object; - F *f = dynamic_cast(t); + T* t = object; + F* f = dynamic_cast(t); if (f == nullptr) { return nullptr; } return RefPtr(f); } - constexpr RefPtr &operator=(const RefPtr &other) + template + constexpr const RefPtr cast() const + { + T* t = object; + F* f = dynamic_cast(t); + if (f == nullptr) + { + return nullptr; + } + return RefPtr(f); + } + constexpr RefPtr& operator=(const RefPtr& other) { if (this != &other) { @@ -133,7 +81,7 @@ public: } return *this; } - constexpr RefPtr &operator=(RefPtr &&rhs) noexcept + constexpr RefPtr& operator=(RefPtr&& rhs) noexcept { if (this != &rhs) { @@ -149,15 +97,25 @@ public: { return object == rhs.object; } - constexpr auto operator<=>(const RefPtr &rhs) const noexcept + constexpr auto operator<=>(const RefPtr& rhs) const noexcept { return object <=> rhs.object; } - constexpr T *operator->() + template + constexpr operator RefPtr() + { + return RefPtr(static_cast(object)); + } + template + constexpr operator RefPtr() const + { + return RefPtr(static_cast(object)); + } + constexpr T* operator->() { return object; } - constexpr const T *operator->() const + constexpr const T* operator->() const { return object; } @@ -172,6 +130,73 @@ public: private: T* object; }; +template > +class OwningPtr +{ +public: + OwningPtr() + : pointer(nullptr) + { + } + OwningPtr(T* ptr) + : pointer(ptr) + {} + template + OwningPtr(OwningPtr&& other) + { + pointer = dynamic_cast(*other); + } + OwningPtr(const OwningPtr& other) = delete; + OwningPtr(OwningPtr&& other) noexcept + { + pointer = other.pointer; + other.pointer = nullptr; + } + OwningPtr& operator=(const OwningPtr& other) = delete; + OwningPtr& operator=(OwningPtr&& other) noexcept + { + if (this != &other) + { + pointer = other.pointer; + } + return *this; + } + operator RefPtr() + { + return RefPtr(pointer); + } + operator RefPtr() const + { + return RefPtr(pointer); + } + constexpr T* operator->() + { + return pointer; + } + constexpr const T* operator->() const + { + return pointer; + } + constexpr T* operator*() + { + return pointer; + } + constexpr const T* operator*() const + { + return pointer; + } + constexpr bool operator==(const OwningPtr& rhs) const noexcept + { + return pointer == rhs.pointer; + } + constexpr auto operator<=>(const OwningPtr& rhs) const noexcept + { + return pointer <=> rhs.pointer; + } +private: + friend class RefPtr; + T* pointer; +}; template class UniquePtr { @@ -197,8 +222,11 @@ public: UniquePtr &operator=(const UniquePtr &rhs) = delete; UniquePtr &operator=(UniquePtr &&rhs) { - handle = rhs.handle; - rhs.handle = nullptr; + if (this != &rhs) + { + handle = rhs.handle; + rhs.handle = nullptr; + } return *this; } ~UniquePtr() diff --git a/src/Engine/Scene/LightEnvironment.cpp b/src/Engine/Scene/LightEnvironment.cpp index 5972aa7..07e8d3b 100644 --- a/src/Engine/Scene/LightEnvironment.cpp +++ b/src/Engine/Scene/LightEnvironment.cpp @@ -16,7 +16,7 @@ LightEnvironment::LightEnvironment(Gfx::PGraphics graphics) .size = sizeof(LightEnv), .data = (uint8*) &lightEnv, }, - .bDynamic = true, + .dynamic = true, }); directionalLights = graphics->createShaderBuffer(ShaderBufferCreateInfo{ .sourceData = { @@ -24,7 +24,7 @@ LightEnvironment::LightEnvironment(Gfx::PGraphics graphics) .data = (uint8*)dirs.data(), }, .stride = sizeof(Component::DirectionalLight), - .bDynamic = true, + .dynamic = true, }); pointLights = graphics->createShaderBuffer(ShaderBufferCreateInfo{ .sourceData = { @@ -32,7 +32,7 @@ LightEnvironment::LightEnvironment(Gfx::PGraphics graphics) .data = (uint8*)dirs.data(), }, .stride = sizeof(Component::PointLight), - .bDynamic = true, + .dynamic = true, }); } @@ -78,3 +78,13 @@ void LightEnvironment::commit() set->updateBuffer(1, directionalLights); set->updateBuffer(2, pointLights); } + +const Gfx::PDescriptorLayout Seele::LightEnvironment::getDescriptorLayout() const +{ + return layout; +} + +Gfx::PDescriptorSet Seele::LightEnvironment::getDescriptorSet() +{ + return set; +} diff --git a/src/Engine/Scene/LightEnvironment.h b/src/Engine/Scene/LightEnvironment.h index 4adc196..759d0ac 100644 --- a/src/Engine/Scene/LightEnvironment.h +++ b/src/Engine/Scene/LightEnvironment.h @@ -15,6 +15,8 @@ public: void addDirectionalLight(Component::DirectionalLight dirLight); void addPointLight(Component::PointLight pointLight); void commit(); + const Gfx::PDescriptorLayout getDescriptorLayout() const; + Gfx::PDescriptorSet getDescriptorSet(); private: #define MAX_DIRECTIONAL_LIGHTS 4 #define MAX_POINT_LIGHTS 256 @@ -29,7 +31,7 @@ private: Array dirs; Array points; Gfx::ODescriptorLayout layout; - Gfx::ODescriptorSet set; + Gfx::PDescriptorSet set; Gfx::PGraphics graphics; }; DEFINE_REF(LightEnvironment) diff --git a/src/Engine/Scene/Scene.cpp b/src/Engine/Scene/Scene.cpp index 8fcef86..3a0e73d 100644 --- a/src/Engine/Scene/Scene.cpp +++ b/src/Engine/Scene/Scene.cpp @@ -25,6 +25,7 @@ Scene::~Scene() void Scene::update(float deltaTime) { + lightEnv->reset(); physics.update(deltaTime); } diff --git a/src/Engine/Serialization/Serialization.h b/src/Engine/Serialization/Serialization.h index 8593340..af802ef 100644 --- a/src/Engine/Serialization/Serialization.h +++ b/src/Engine/Serialization/Serialization.h @@ -1,5 +1,6 @@ #pragma once #include "ArchiveBuffer.h" +#include "Math/Vector.h" namespace Seele { @@ -25,6 +26,38 @@ namespace Serialization { buffer.readBytes(&type, sizeof(type)); } + static void save(ArchiveBuffer& buffer, const IVector2& vec) + { + save(buffer, vec.x); + save(buffer, vec.y); + } + static void load(ArchiveBuffer& buffer, IVector2& vec) + { + save(buffer, vec.x); + save(buffer, vec.y); + } + static void save(ArchiveBuffer& buffer, const Vector2& vec) + { + save(buffer, vec.x); + save(buffer, vec.y); + } + static void load(ArchiveBuffer& buffer, Vector2& vec) + { + save(buffer, vec.x); + save(buffer, vec.y); + } + static void save(ArchiveBuffer& buffer, const Vector& vec) + { + save(buffer, vec.x); + save(buffer, vec.y); + save(buffer, vec.z); + } + static void load(ArchiveBuffer& buffer, Vector& vec) + { + save(buffer, vec.x); + save(buffer, vec.y); + save(buffer, vec.z); + } template static void save(ArchiveBuffer& buffer, const T& type) { @@ -92,7 +125,7 @@ namespace Serialization { uint64 length = type.size(); buffer.writeBytes(&length, sizeof(uint64)); - for (const auto& x : type) + for (const T& x : type) { save(buffer, x); } @@ -102,10 +135,12 @@ namespace Serialization { uint64 length = 0; buffer.readBytes(&length, sizeof(uint64)); - type.resize(length); - for (auto& x : type) + type.reserve(length); + for (uint32 i = 0; i < length; ++i) { - load(buffer, x); + T t = T(); + load(buffer, t); + type.add(std::move(t)); } } } // namespace Serialization diff --git a/src/Engine/Window/GameView.cpp b/src/Engine/Window/GameView.cpp index c1db590..fc04f11 100644 --- a/src/Engine/Window/GameView.cpp +++ b/src/Engine/Window/GameView.cpp @@ -11,10 +11,10 @@ GameView::GameView(Gfx::PGraphics graphics, PWindow window, const ViewportCreate : View(graphics, window, createInfo, "Game") , gameInterface(dllPath) , renderGraph(RenderGraphBuilder::build( - DepthPrepass(graphics, scene), - LightCullingPass(graphics, scene), - BasePass(graphics, scene), - SkyboxRenderPass(graphics, scene) + std::move(DepthPrepass(graphics, scene)), + std::move(LightCullingPass(graphics, scene)), + std::move(BasePass(graphics, scene)), + std::move(SkyboxRenderPass(graphics, scene)) )) { reloadGame(); @@ -43,6 +43,7 @@ void GameView::update() { vd->createDescriptors(); } + scene->getLightEnvironment()->commit(); auto endTime = std::chrono::high_resolution_clock::now(); std::chrono::duration duration = (endTime - startTime); updateTime = duration.count(); diff --git a/src/Engine/Window/GameView.h b/src/Engine/Window/GameView.h index b7bb939..4afd057 100644 --- a/src/Engine/Window/GameView.h +++ b/src/Engine/Window/GameView.h @@ -32,7 +32,7 @@ private: > renderGraph; PEntity camera; - PScene scene; + OScene scene; PSystemGraph systemGraph; dp::thread_pool<> threadPool; float updateTime = 0; diff --git a/src/Engine/Window/WindowManager.cpp b/src/Engine/Window/WindowManager.cpp index 64a79dc..98f32e5 100644 --- a/src/Engine/Window/WindowManager.cpp +++ b/src/Engine/Window/WindowManager.cpp @@ -22,7 +22,7 @@ PWindow WindowManager::addWindow(Gfx::PGraphics graphics, const WindowCreateInfo void WindowManager::notifyWindowClosed(PWindow window) { - windows.remove(windows.find([window] (OWindow w) { return window == w; })); + windows.remove(windows.find([window] (const OWindow& w) { return window == w; })); if(windows.empty()) { exit(0);