From 1ca861459cb06533d033cd0abc11ea3bc0e3fb9f Mon Sep 17 00:00:00 2001 From: Dynamitos Date: Thu, 26 Oct 2023 18:37:29 +0200 Subject: [PATCH] Refactoring graphics --- res/shaders/LightCulling.slang | 50 +- res/shaders/lib/LightEnv.slang | 16 +- res/shaders/lib/MaterialParameter.slang | 2 + res/shaders/test.glsl | 618 +++++++------ src/Engine/Asset/FontAsset.cpp | 3 +- src/Engine/Asset/MeshAsset.cpp | 3 - src/Engine/Asset/TextureAsset.cpp | 3 +- src/Engine/Component/Camera.h | 1 - src/Engine/Component/KeyboardInput.h | 2 +- src/Engine/Component/Mesh.h | 1 - src/Engine/Component/Skybox.h | 2 +- src/Engine/Containers/Array.h | 14 + src/Engine/Graphics/Buffer.cpp | 91 ++ src/Engine/Graphics/Buffer.h | 153 ++++ src/Engine/Graphics/CMakeLists.txt | 30 +- src/Engine/Graphics/Descriptor.cpp | 47 + src/Engine/Graphics/Descriptor.h | 122 +++ .../Graphics/{GraphicsEnums.cpp => Enums.cpp} | 0 .../Graphics/{GraphicsEnums.h => Enums.h} | 0 src/Engine/Graphics/Graphics.h | 30 +- src/Engine/Graphics/GraphicsResources.cpp | 549 ----------- src/Engine/Graphics/GraphicsResources.h | 851 ------------------ .../{GraphicsInitializer.h => Initializer.h} | 166 ++-- src/Engine/Graphics/Mesh.cpp | 5 +- src/Engine/Graphics/Mesh.h | 1 - src/Engine/Graphics/RenderPass/BasePass.cpp | 9 +- src/Engine/Graphics/RenderPass/BasePass.h | 1 - src/Engine/Graphics/RenderPass/DebugPass.cpp | 1 + src/Engine/Graphics/RenderPass/DebugPass.h | 1 - .../Graphics/RenderPass/DepthPrepass.cpp | 2 +- .../Graphics/RenderPass/LightCullingPass.cpp | 8 +- .../Graphics/RenderPass/LightCullingPass.h | 8 +- .../RenderPass/RenderGraphResources.h | 4 +- src/Engine/Graphics/RenderPass/RenderPass.h | 14 - .../Graphics/RenderPass/SkyboxRenderPass.cpp | 27 +- .../Graphics/RenderPass/SkyboxRenderPass.h | 5 +- src/Engine/Graphics/RenderPass/TextPass.cpp | 18 +- src/Engine/Graphics/RenderPass/TextPass.h | 7 +- src/Engine/Graphics/RenderPass/UIPass.cpp | 32 +- src/Engine/Graphics/RenderPass/UIPass.h | 14 +- src/Engine/Graphics/RenderTarget.cpp | 81 ++ src/Engine/Graphics/RenderTarget.h | 194 ++++ src/Engine/Graphics/Resources.cpp | 77 ++ src/Engine/Graphics/Resources.h | 150 +++ src/Engine/Graphics/Shader.cpp | 92 ++ src/Engine/Graphics/Shader.h | 108 +++ src/Engine/Graphics/ShaderCompiler.cpp | 1 - src/Engine/Graphics/ShaderCompiler.h | 1 - src/Engine/Graphics/StaticMeshVertexData.cpp | 9 +- src/Engine/Graphics/StaticMeshVertexData.h | 2 +- src/Engine/Graphics/Texture.cpp | 41 + src/Engine/Graphics/Texture.h | 110 +++ src/Engine/Graphics/TopologyData.cpp | 1 - src/Engine/Graphics/TopologyData.h | 17 - src/Engine/Graphics/VertexData.cpp | 2 + src/Engine/Graphics/VertexData.h | 10 +- .../{VulkanAllocator.cpp => Allocator.cpp} | 6 +- .../Vulkan/{VulkanAllocator.h => Allocator.h} | 2 +- .../Vulkan/{VulkanBuffer.cpp => Buffer.cpp} | 8 +- src/Engine/Graphics/Vulkan/Buffer.h | 145 +++ src/Engine/Graphics/Vulkan/CMakeLists.txt | 90 +- ...kanCommandBuffer.cpp => CommandBuffer.cpp} | 19 +- ...{VulkanCommandBuffer.h => CommandBuffer.h} | 7 +- ...nDescriptorSets.cpp => DescriptorSets.cpp} | 10 +- ...ulkanDescriptorSets.h => DescriptorSets.h} | 5 +- .../{VulkanGraphicsEnums.cpp => Enums.cpp} | 0 .../Vulkan/{VulkanGraphicsEnums.h => Enums.h} | 11 +- ...{VulkanFramebuffer.cpp => Framebuffer.cpp} | 11 +- .../{VulkanFramebuffer.h => Framebuffer.h} | 4 +- .../{VulkanGraphics.cpp => Graphics.cpp} | 0 .../Vulkan/{VulkanGraphics.h => Graphics.h} | 15 +- ...{VulkanInitializer.cpp => Initializer.cpp} | 2 +- .../{VulkanInitializer.h => Initializer.h} | 0 .../{VulkanPipeline.cpp => Pipeline.cpp} | 14 +- .../Vulkan/{VulkanPipeline.h => Pipeline.h} | 7 +- src/Engine/Graphics/Vulkan/PipelineCache.cpp | 393 ++++++++ ...{VulkanPipelineCache.h => PipelineCache.h} | 9 +- .../Vulkan/{VulkanQueue.cpp => Queue.cpp} | 11 +- .../Vulkan/{VulkanQueue.h => Queue.h} | 2 +- .../{VulkanRenderPass.cpp => RenderPass.cpp} | 10 +- .../{VulkanRenderPass.h => RenderPass.h} | 3 +- .../{VulkanViewport.cpp => RenderTarget.cpp} | 0 src/Engine/Graphics/Vulkan/RenderTarget.h | 83 ++ ...kanGraphicsResources.cpp => Resources.cpp} | 0 src/Engine/Graphics/Vulkan/Resources.h | 80 ++ .../Vulkan/{VulkanShader.cpp => Shader.cpp} | 0 .../Vulkan/{VulkanShader.h => Shader.h} | 15 +- .../Vulkan/{VulkanTexture.cpp => Texture.cpp} | 0 src/Engine/Graphics/Vulkan/Texture.h | 264 ++++++ .../Graphics/Vulkan/VulkanGraphicsResources.h | 535 ----------- .../Graphics/Vulkan/VulkanPipelineCache.cpp | 381 -------- src/Engine/Material/Material.cpp | 19 +- src/Engine/Material/Material.h | 2 +- src/Engine/Material/MaterialInstance.cpp | 10 +- src/Engine/Material/MaterialInstance.h | 4 +- src/Engine/Material/ShaderExpression.cpp | 3 +- src/Engine/Scene/CMakeLists.txt | 7 +- src/Engine/Scene/LightEnvironment.cpp | 35 + src/Engine/Scene/LightEnvironment.h | 32 + src/Engine/Scene/Scene.cpp | 13 +- src/Engine/Scene/Scene.h | 18 +- src/Engine/System/CMakeLists.txt | 5 +- src/Engine/System/LightGather.cpp | 18 + src/Engine/System/LightGather.h | 18 + src/Engine/System/MeshUpdater.cpp | 5 + src/Engine/System/MeshUpdater.h | 2 + src/Engine/UI/RenderHierarchy.h | 3 +- src/Engine/UI/System.cpp | 25 - src/Engine/UI/System.h | 2 - src/Engine/Window/GameView.cpp | 4 +- src/Engine/Window/GameView.h | 5 - src/Engine/Window/Window.h | 2 +- test.glsl | 171 ---- 113 files changed, 3131 insertions(+), 3221 deletions(-) create mode 100644 src/Engine/Graphics/Buffer.cpp create mode 100644 src/Engine/Graphics/Buffer.h create mode 100644 src/Engine/Graphics/Descriptor.cpp create mode 100644 src/Engine/Graphics/Descriptor.h rename src/Engine/Graphics/{GraphicsEnums.cpp => Enums.cpp} (100%) rename src/Engine/Graphics/{GraphicsEnums.h => Enums.h} (100%) delete mode 100644 src/Engine/Graphics/GraphicsResources.cpp delete mode 100644 src/Engine/Graphics/GraphicsResources.h rename src/Engine/Graphics/{GraphicsInitializer.h => Initializer.h} (58%) create mode 100644 src/Engine/Graphics/RenderTarget.cpp create mode 100644 src/Engine/Graphics/RenderTarget.h create mode 100644 src/Engine/Graphics/Resources.cpp create mode 100644 src/Engine/Graphics/Resources.h create mode 100644 src/Engine/Graphics/Shader.cpp create mode 100644 src/Engine/Graphics/Shader.h create mode 100644 src/Engine/Graphics/Texture.cpp create mode 100644 src/Engine/Graphics/Texture.h delete mode 100644 src/Engine/Graphics/TopologyData.cpp delete mode 100644 src/Engine/Graphics/TopologyData.h rename src/Engine/Graphics/Vulkan/{VulkanAllocator.cpp => Allocator.cpp} (99%) rename src/Engine/Graphics/Vulkan/{VulkanAllocator.h => Allocator.h} (99%) rename src/Engine/Graphics/Vulkan/{VulkanBuffer.cpp => Buffer.cpp} (98%) create mode 100644 src/Engine/Graphics/Vulkan/Buffer.h rename src/Engine/Graphics/Vulkan/{VulkanCommandBuffer.cpp => CommandBuffer.cpp} (98%) rename src/Engine/Graphics/Vulkan/{VulkanCommandBuffer.h => CommandBuffer.h} (97%) rename src/Engine/Graphics/Vulkan/{VulkanDescriptorSets.cpp => DescriptorSets.cpp} (98%) rename src/Engine/Graphics/Vulkan/{VulkanDescriptorSets.h => DescriptorSets.h} (97%) rename src/Engine/Graphics/Vulkan/{VulkanGraphicsEnums.cpp => Enums.cpp} (100%) rename src/Engine/Graphics/Vulkan/{VulkanGraphicsEnums.h => Enums.h} (96%) rename src/Engine/Graphics/Vulkan/{VulkanFramebuffer.cpp => Framebuffer.cpp} (93%) rename src/Engine/Graphics/Vulkan/{VulkanFramebuffer.h => Framebuffer.h} (91%) rename src/Engine/Graphics/Vulkan/{VulkanGraphics.cpp => Graphics.cpp} (100%) rename src/Engine/Graphics/Vulkan/{VulkanGraphics.h => Graphics.h} (89%) rename src/Engine/Graphics/Vulkan/{VulkanInitializer.cpp => Initializer.cpp} (99%) rename src/Engine/Graphics/Vulkan/{VulkanInitializer.h => Initializer.h} (100%) rename src/Engine/Graphics/Vulkan/{VulkanPipeline.cpp => Pipeline.cpp} (69%) rename src/Engine/Graphics/Vulkan/{VulkanPipeline.h => Pipeline.h} (81%) create mode 100644 src/Engine/Graphics/Vulkan/PipelineCache.cpp rename src/Engine/Graphics/Vulkan/{VulkanPipelineCache.h => PipelineCache.h} (54%) rename src/Engine/Graphics/Vulkan/{VulkanQueue.cpp => Queue.cpp} (90%) rename src/Engine/Graphics/Vulkan/{VulkanQueue.h => Queue.h} (95%) rename src/Engine/Graphics/Vulkan/{VulkanRenderPass.cpp => RenderPass.cpp} (97%) rename src/Engine/Graphics/Vulkan/{VulkanRenderPass.h => RenderPass.h} (94%) rename src/Engine/Graphics/Vulkan/{VulkanViewport.cpp => RenderTarget.cpp} (100%) create mode 100644 src/Engine/Graphics/Vulkan/RenderTarget.h rename src/Engine/Graphics/Vulkan/{VulkanGraphicsResources.cpp => Resources.cpp} (100%) create mode 100644 src/Engine/Graphics/Vulkan/Resources.h rename src/Engine/Graphics/Vulkan/{VulkanShader.cpp => Shader.cpp} (100%) rename src/Engine/Graphics/Vulkan/{VulkanShader.h => Shader.h} (75%) rename src/Engine/Graphics/Vulkan/{VulkanTexture.cpp => Texture.cpp} (100%) create mode 100644 src/Engine/Graphics/Vulkan/Texture.h delete mode 100644 src/Engine/Graphics/Vulkan/VulkanGraphicsResources.h delete mode 100644 src/Engine/Graphics/Vulkan/VulkanPipelineCache.cpp create mode 100644 src/Engine/Scene/LightEnvironment.cpp create mode 100644 src/Engine/Scene/LightEnvironment.h create mode 100644 src/Engine/System/LightGather.cpp create mode 100644 src/Engine/System/LightGather.h delete mode 100644 test.glsl diff --git a/res/shaders/LightCulling.slang b/res/shaders/LightCulling.slang index 2f69ae3..d0d0781 100644 --- a/res/shaders/LightCulling.slang +++ b/res/shaders/LightCulling.slang @@ -8,36 +8,28 @@ struct ComputeShaderInput uint3 dispatchThreadID : SV_DispatchThreadID; uint groupIndex : SV_GroupIndex; }; -layout(set = INDEX_VIEW_PARAMS, binding = 1) -cbuffer DispatchParams +struct CullingParams { uint3 numThreadGroups; uint pad0; uint3 numThreads; uint pad1; -} -layout(set = INDEX_VIEW_PARAMS, binding = 2) -Texture2D depthTextureVS; + Texture2D depthTextureVS; -layout(set = INDEX_VIEW_PARAMS, binding = 3) -globallycoherent RWShaderBuffer oLightIndexCounter; -layout(set = INDEX_VIEW_PARAMS, binding = 4) -globallycoherent RWShaderBuffer tLightIndexCounter; + globallycoherent RWStructuredBuffer oLightIndexCounter; + globallycoherent RWStructuredBuffer tLightIndexCounter; -layout(set = INDEX_VIEW_PARAMS, binding = 5) -RWShaderBuffer oLightIndexList; -layout(set = INDEX_VIEW_PARAMS, binding = 6) -RWShaderBuffer tLightIndexList; + RWStructuredBuffer oLightIndexList; + RWStructuredBuffer tLightIndexList; -layout(set = INDEX_VIEW_PARAMS, binding = 7) -RWTexture2D oLightGrid; -layout(set = INDEX_VIEW_PARAMS, binding = 8) -RWTexture2D tLightGrid; + RWTexture2D oLightGrid; + RWTexture2D tLightGrid; -layout(set = INDEX_VIEW_PARAMS, binding = 9) -ShaderBuffer frustums; + StructuredBuffer frustums; +}; +ParameterBlock gCullingParams; // Debug //layout(set = INDEX_VIEW_PARAMS, binding = 10) //Texture2D lightCountHeatMap; @@ -83,7 +75,7 @@ void tAppendLight(uint lightIndex) void cullLights(ComputeShaderInput in) { int2 texCoord = int2(in.dispatchThreadID.xy); - float fDepth = depthTextureVS.Load(int3(texCoord, 0)).r; + float fDepth = gCullingParams.depthTextureVS.Load(int3(texCoord, 0)).r; uint uDepth = asuint(fDepth); if(in.groupIndex == 0) @@ -92,7 +84,7 @@ void cullLights(ComputeShaderInput in) uMaxDepth = 0x0; oLightCount = 0; tLightCount = 0; - groupFrustum = frustums[in.groupID.x + (in.groupID.y * numThreadGroups.x)]; + groupFrustum = gCullingParams.frustums[in.groupID.x + (in.groupID.y * gCullingParams.numThreadGroups.x)]; } GroupMemoryBarrierWithGroupSync(); @@ -111,9 +103,9 @@ void cullLights(ComputeShaderInput in) Plane minPlane = {float3(0, 0, -1), -minDepthVS}; - for ( uint i = in.groupIndex; i < numPointLights; i += BLOCK_SIZE * BLOCK_SIZE ) + for ( uint i = in.groupIndex; i < gLightEnv.numPointLights; i += BLOCK_SIZE * BLOCK_SIZE ) { - PointLight light = pointLights[i]; + PointLight light = gLightEnv.pointLights[i]; //TODO: why doesn't this check go through? //if(light.insideFrustum(groupFrustum, nearClipVS, maxDepthVS)) { @@ -129,23 +121,23 @@ void cullLights(ComputeShaderInput in) if(in.groupIndex == 0) { - InterlockedAdd(oLightIndexCounter[0], oLightCount, oLightIndexStartOffset); - oLightGrid[in.groupID.xy] = uint2(oLightIndexStartOffset, oLightCount); + InterlockedAdd(gCullingParams.oLightIndexCounter[0], oLightCount, oLightIndexStartOffset); + gCullingParams.oLightGrid[in.groupID.xy] = uint2(oLightIndexStartOffset, oLightCount); - InterlockedAdd(tLightIndexCounter[0], tLightCount, tLightIndexStartOffset); - tLightGrid[in.groupID.xy] = uint2(tLightIndexStartOffset, tLightCount); + InterlockedAdd(gCullingParams.tLightIndexCounter[0], tLightCount, tLightIndexStartOffset); + gCullingParams.tLightGrid[in.groupID.xy] = uint2(tLightIndexStartOffset, tLightCount); } GroupMemoryBarrierWithGroupSync(); for (uint j = in.groupIndex; j < oLightCount; j += BLOCK_SIZE * BLOCK_SIZE) { - oLightIndexList[oLightIndexStartOffset + j] = oLightList[j]; + gCullingParams.oLightIndexList[oLightIndexStartOffset + j] = oLightList[j]; } // For transparent geometry. for ( uint k = in.groupIndex; k < tLightCount; k += BLOCK_SIZE * BLOCK_SIZE ) { - tLightIndexList[tLightIndexStartOffset + k] = tLightList[k]; + gCullingParams.tLightIndexList[tLightIndexStartOffset + k] = tLightList[k]; } diff --git a/res/shaders/lib/LightEnv.slang b/res/shaders/lib/LightEnv.slang index e366b6c..3a90b96 100644 --- a/res/shaders/lib/LightEnv.slang +++ b/res/shaders/lib/LightEnv.slang @@ -4,7 +4,7 @@ import Common; interface ILightEnv { - float3 illuminate(MaterialFragmentParameter input, B brdf); + float3 illuminate(MaterialParameter input, B brdf); }; struct DirectionalLight : ILightEnv @@ -12,9 +12,9 @@ struct DirectionalLight : ILightEnv float4 color; float4 direction; - float3 illuminate(MaterialFragmentParameter input, B brdf) + float3 illuminate(MaterialParameter input, B brdf) { - float3 lightDir_TS = input.transformWorldToTangent(normalize(direction.xyz)); + float3 lightDir_TS = normalize(direction.xyz); return brdf.evaluate(input.viewDir_TS, -lightDir_TS, color.xyz); } }; @@ -24,9 +24,9 @@ struct PointLight : ILightEnv float4 position_WS; float4 colorRange; - float3 illuminate(MaterialFragmentParameter input, B brdf) + float3 illuminate(MaterialParameter input, B brdf) { - float3 position_TS = input.transformWorldToTangent(position_WS.xyz); + float3 position_TS = position_WS.xyz; float3 lightDir_TS = position_TS - input.position_TS; float d = length(lightDir_TS); float illuminance = max(1 - d / colorRange.w, 0); @@ -48,7 +48,7 @@ struct PointLight : ILightEnv } for(int i = 0; i < 4 && result; ++i) { - if(insidePlane(frustum.planes[i])) + if(insidePlane(frustum.sides[i])) { //result = false; } @@ -57,7 +57,7 @@ struct PointLight : ILightEnv } float3 getViewPos() { - return mul(gViewParams.viewMatrix, position_WS).xyz; + return mul(viewParams.viewMatrix, position_WS).xyz; } }; @@ -65,7 +65,7 @@ struct LightEnv { StructuredBuffer directionalLights; uint numDirectionalLights; - StructureBuffer pointLights; + StructuredBuffer pointLights; uint numPointLights; }; diff --git a/res/shaders/lib/MaterialParameter.slang b/res/shaders/lib/MaterialParameter.slang index 51ae33a..4e09c13 100644 --- a/res/shaders/lib/MaterialParameter.slang +++ b/res/shaders/lib/MaterialParameter.slang @@ -2,11 +2,13 @@ import VertexData; struct MaterialParameter { +float3 position_TS; float3 worldPosition; float2 texCoords; float3 normal; float3 tangent; float3 biTangent; + float3 viewDir_TS; static MaterialParameter create(VertexAttributes attrib) { diff --git a/res/shaders/test.glsl b/res/shaders/test.glsl index 51a51d9..731997e 100755 --- a/res/shaders/test.glsl +++ b/res/shaders/test.glsl @@ -1,73 +1,114 @@ #version 450 -#extension GL_EXT_mesh_shader : require -#extension GL_EXT_shader_8bit_storage : require -#extension GL_EXT_shader_explicit_arithmetic_types : require +#extension GL_EXT_samplerless_texture_functions : require layout(row_major) uniform; layout(row_major) buffer; -#line 1 0 -struct InstanceData_0 +#line 11 0 +struct CullingParams_0 { - mat4x4 transformMatrix_0; + uvec3 numThreadGroups_0; + uint pad0_0; + uvec3 numThreads_0; + uint pad1_0; }; -#line 45 1 -layout(std430, binding = 0, set = 2) readonly buffer StructuredBuffer_InstanceData_t_0 { - InstanceData_0 _data[]; -} scene_instances_0; - -#line 1 2 -struct MeshletDescription_0 +#line 35 1 +layout(binding = 0, set = 1) +layout(std140) uniform _S1 { - uint vertexCount_0; - uint primitiveCount_0; - uint vertexOffset_0; - uint primitiveOffset_0; -}; + uvec3 numThreadGroups_0; + uint pad0_0; + uvec3 numThreads_0; + uint pad1_0; +}gCullingParams_0; + +#line 2113 2 +layout(binding = 1, set = 1) +uniform texture2D gCullingParams_depthTextureVS_0; -#line 46 1 -layout(std430, binding = 0, set = 1) readonly buffer StructuredBuffer_MeshletDescription_t_0 { - MeshletDescription_0 _data[]; -} meshlets_meshletInfos_0; - -#line 9 2 -layout(std430, binding = 1, set = 1) readonly buffer StructuredBuffer_uint8_t_0 { - uint8_t _data[]; -} meshlets_primitiveIndices_0; - -#line 9 -layout(std430, binding = 2, set = 1) readonly buffer StructuredBuffer_uint_t_0 { +#line 11 0 +layout(std430, binding = 2, set = 1) buffer StructuredBuffer_uint_t_0 { uint _data[]; -} meshlets_vertexIndices_0; +} gCullingParams_oLightIndexCounter_0; -#line 35 3 -layout(std430, binding = 0, set = 3) readonly buffer StructuredBuffer_float3_t_0 { - vec3 _data[]; -} vertexData_positions_0; +#line 11 +layout(std430, binding = 3, set = 1) buffer StructuredBuffer_uint_t_1 { + uint _data[]; +} gCullingParams_tLightIndexCounter_0; -#line 35 -layout(std430, binding = 1, set = 3) readonly buffer StructuredBuffer_float2_t_0 { - vec2 _data[]; -} vertexData_texCoords_0; +#line 11 +layout(std430, binding = 4, set = 1) buffer StructuredBuffer_uint_t_2 { + uint _data[]; +} gCullingParams_oLightIndexList_0; -#line 35 -layout(std430, binding = 2, set = 3) readonly buffer StructuredBuffer_float3_t_1 { - vec3 _data[]; -} vertexData_normals_0; +#line 11 +layout(std430, binding = 5, set = 1) buffer StructuredBuffer_uint_t_3 { + uint _data[]; +} gCullingParams_tLightIndexList_0; -#line 35 -layout(std430, binding = 3, set = 3) readonly buffer StructuredBuffer_float3_t_2 { - vec3 _data[]; -} vertexData_tangents_0; +#line 1572 2 +layout(rg32ui) +layout(binding = 6, set = 1) +uniform uimage2D gCullingParams_oLightGrid_0; -#line 35 -layout(std430, binding = 4, set = 3) readonly buffer StructuredBuffer_float3_t_3 { - vec3 _data[]; -} vertexData_biTangents_0; -#line 5 4 +#line 1572 +layout(rg32ui) +layout(binding = 7, set = 1) +uniform uimage2D gCullingParams_tLightGrid_0; + + +#line 26 1 +struct Plane_0 +{ + vec3 n_0; + float d_0; +}; + +struct Frustum_0 +{ + Plane_0 sides_0[4]; + Plane_0 basePlane_0; +}; + + +#line 11 0 +layout(std430, binding = 8, set = 1) readonly buffer StructuredBuffer_Frustum_t_0 { + Frustum_0 _data[]; +} gCullingParams_frustums_0; + +#line 64 3 +struct LightEnv_0 +{ + uint numDirectionalLights_0; + uint numPointLights_0; +}; + + +#line 25 +layout(binding = 0, set = 2) +layout(std140) uniform _S2 +{ + uint numDirectionalLights_0; + uint numPointLights_0; +}gLightEnv_0; + +#line 22 +struct PointLight_0 +{ + vec4 position_WS_0; + vec4 colorRange_0; +}; + + +#line 64 +layout(std430, binding = 2, set = 2) readonly buffer StructuredBuffer_PointLight_t_0 { + PointLight_0 _data[]; +} gLightEnv_pointLights_0; + +#line 5 1 struct ViewParameter_0 { mat4x4 viewMatrix_0; @@ -77,7 +118,7 @@ struct ViewParameter_0 }; layout(binding = 0) -layout(std140) uniform _S1 +layout(std140) uniform _S3 { mat4x4 viewMatrix_0; mat4x4 projectionMatrix_0; @@ -85,264 +126,257 @@ layout(std140) uniform _S1 vec2 screenDimensions_0; }viewParams_0; -#line 1267 5 -out gl_MeshPerVertexEXT -{ - vec4 gl_Position; -} gl_MeshVerticesEXT[64]; +#line 39 0 +shared uint uMinDepth_0; -#line 24 1 -shared uint gs_numVertices_0; +#line 40 +shared uint uMaxDepth_0; -#line 5 3 -struct StaticMeshVertexAttributes_0 -{ - vec4 clipPosition_0; - vec3 worldPosition_0; - vec2 texCoords_0; - vec3 normal_0; - vec3 tangent_0; - vec3 biTangent_0; -}; + +shared uint oLightCount_0; -#line 22 1 -shared StaticMeshVertexAttributes_0 gs_vertices_0[64]; + +shared uint tLightCount_0; -shared uint gs_numPrimitives_0; +#line 42 +shared Frustum_0 groupFrustum_0; -#line 23 -shared uvec3 gs_indices_0[126]; +#line 50 +shared uint tLightList_0[1024]; -#line 7910 6 -layout(location = 0) -out vec3 _S2[64]; - - -#line 7910 -layout(location = 1) -out vec2 _S3[64]; - - -#line 7910 -layout(location = 2) -out vec3 _S4[64]; - - -#line 7910 -layout(location = 3) -out vec3 _S5[64]; - - -#line 7910 -layout(location = 4) -out vec3 _S6[64]; - - -#line 7910 -out uvec3 gl_PrimitiveTriangleIndicesEXT[126]; - - -#line 900 7 -StaticMeshVertexAttributes_0 StaticMeshVertexData_getAttributes_0(uint _S7, InstanceData_0 _S8) -{ - -#line 41 3 - vec4 worldPos_0 = (((vec4(vertexData_positions_0._data[_S7], 1.0)) * (_S8.transformMatrix_0))); - -#line 39 - StaticMeshVertexAttributes_0 attr_0; - -#line 44 - attr_0.clipPosition_0 = ((((((worldPos_0) * (viewParams_0.viewMatrix_0)))) * (viewParams_0.projectionMatrix_0))); - attr_0.worldPosition_0 = worldPos_0.xyz; - attr_0.texCoords_0 = vertexData_texCoords_0._data[_S7]; - attr_0.normal_0 = vertexData_normals_0._data[_S7]; - attr_0.tangent_0 = vertexData_tangents_0._data[_S7]; - attr_0.biTangent_0 = vertexData_biTangents_0._data[_S7]; - return attr_0; -} - - -#line 39 1 -layout(local_size_x = 32, local_size_y = 1, local_size_z = 1) in; -layout(max_vertices = 64) out; -layout(max_primitives = 126) out; -layout(triangles) out; -void main() -{ - InstanceData_0 _S9 = scene_instances_0._data[gl_LocalInvocationIndex]; - MeshletDescription_0 m_0 = meshlets_meshletInfos_0._data[gl_WorkGroupID.x]; - -#line 51 - uint _S10 = m_0.vertexCount_0 - 1U; - #line 63 - uint _S11 = m_0.primitiveCount_0 - 1U; - -#line 82 - uint v_0 = min(gl_LocalInvocationIndex, _S10); - - - - uint v_1 = gl_LocalInvocationIndex + 32U; - uint v_2 = min(v_1, _S10); - -#line 92 - uint p_0 = min(gl_LocalInvocationIndex, _S11); - -#line 98 - uint p_1 = min(v_1, _S11); - -#line 104 - uint p_2 = min(gl_LocalInvocationIndex + 64U, _S11); - -#line 110 - uint p_3 = min(gl_LocalInvocationIndex + 96U, _S11); - -#line 110 - uint loop_0 = 0U; - -#line 110 - for(;;) +void tAppendLight_0(uint lightIndex_0) +{ + uint index_0; + ((index_0) = atomicAdd((tLightCount_0), (1U))); + if(index_0 < 1024U) { + tLightList_0[index_0] = lightIndex_0; -#line 51 - uint v_3 = min(gl_LocalInvocationIndex + loop_0 * 32U, _S10); - atomicMax((gs_numVertices_0), (v_3 + 1U)); - - - gs_vertices_0[v_3] = StaticMeshVertexData_getAttributes_0(uint(int(meshlets_vertexIndices_0._data[m_0.vertexOffset_0 + v_3])), _S9); - -#line 48 - uint loop_1 = loop_0 + 1U; - -#line 48 - if(loop_1 < 2U) - { - } - else - { - -#line 48 - break; - } - -#line 48 - loop_0 = loop_1; - -#line 48 +#line 67 } -#line 48 - loop_0 = 0U; -#line 48 - for(;;) - { - -#line 63 - uint p_4 = min(gl_LocalInvocationIndex + loop_0 * 32U, _S11); - atomicMax((gs_numPrimitives_0), (p_4 + 1U)); - - uint _S12 = p_4 * 3U; - -#line 66 - uint _S13 = m_0.primitiveOffset_0 + _S12; - - - - uint idx1_0 = meshlets_vertexIndices_0._data[m_0.vertexOffset_0 + uint(meshlets_primitiveIndices_0._data[_S13 + 1U])]; - uint idx2_0 = meshlets_vertexIndices_0._data[m_0.vertexOffset_0 + uint(meshlets_primitiveIndices_0._data[_S13 + 2U])]; - gs_indices_0[_S12] = uvec3(meshlets_vertexIndices_0._data[m_0.vertexOffset_0 + uint(meshlets_primitiveIndices_0._data[_S13])]); - gs_indices_0[_S12 + 1U] = uvec3(idx1_0); - gs_indices_0[_S12 + 2U] = uvec3(idx2_0); - -#line 60 - uint loop_2 = loop_0 + 1U; - -#line 60 - if(loop_2 < 4U) - { - } - else - { - -#line 60 - break; - } - -#line 60 - loop_0 = loop_2; - -#line 60 - } - -#line 77 - barrier(); - SetMeshOutputsEXT(gs_numVertices_0, gs_numPrimitives_0); - barrier(); - - - - StaticMeshVertexAttributes_0 _S14 = gs_vertices_0[v_0]; - -#line 83 - gl_MeshVerticesEXT[v_0].gl_Position = gs_vertices_0[v_0].clipPosition_0; - -#line 83 - _S2[v_0] = _S14.worldPosition_0; - -#line 83 - _S3[v_0] = _S14.texCoords_0; - -#line 83 - _S4[v_0] = _S14.normal_0; - -#line 83 - _S5[v_0] = _S14.tangent_0; - -#line 83 - _S6[v_0] = _S14.biTangent_0; - -#line 88 - StaticMeshVertexAttributes_0 _S15 = gs_vertices_0[v_2]; - -#line 88 - gl_MeshVerticesEXT[v_2].gl_Position = gs_vertices_0[v_2].clipPosition_0; - -#line 88 - _S2[v_2] = _S15.worldPosition_0; - -#line 88 - _S3[v_2] = _S15.texCoords_0; - -#line 88 - _S4[v_2] = _S15.normal_0; - -#line 88 - _S5[v_2] = _S15.tangent_0; - -#line 88 - _S6[v_2] = _S15.biTangent_0; - -#line 93 - gl_PrimitiveTriangleIndicesEXT[p_0] = gs_indices_0[p_0]; - -#line 99 - gl_PrimitiveTriangleIndicesEXT[p_1] = gs_indices_0[p_1]; - -#line 105 - gl_PrimitiveTriangleIndicesEXT[p_2] = gs_indices_0[p_2]; - -#line 111 - gl_PrimitiveTriangleIndicesEXT[p_3] = gs_indices_0[p_3]; return; } + +#line 58 3 +vec3 PointLight_getViewPos_0(PointLight_0 this_0) +{ + return (((this_0.position_WS_0) * (viewParams_0.viewMatrix_0))).xyz; +} + + +#line 36 +bool PointLight_insidePlane_0(PointLight_0 this_1, Plane_0 plane_0) +{ + return dot(plane_0.n_0, PointLight_getViewPos_0(this_1).xyz) - plane_0.d_0 < - this_1.colorRange_0.w; +} + + +#line 46 0 +shared uint oLightList_0[1024]; + + +#line 53 +void oAppendLight_0(uint lightIndex_1) +{ + uint index_1; + ((index_1) = atomicAdd((oLightCount_0), (1U))); + if(index_1 < 1024U) + { + oLightList_0[index_1] = lightIndex_1; + +#line 57 + } + + + + return; +} + + +#line 45 +shared uint oLightIndexStartOffset_0; + + + +shared uint tLightIndexStartOffset_0; + + +#line 75 +layout(local_size_x = 32, local_size_y = 32, local_size_z = 1) in; +void main() +{ + ivec3 _S4 = ivec3(ivec2(gl_GlobalInvocationID.xy), 0); + + uint uDepth_0 = floatBitsToUint((texelFetch((gCullingParams_depthTextureVS_0), ((_S4)).xy, ((_S4)).z)).x); + bool _S5 = gl_LocalInvocationIndex == 0U; + +#line 81 + if(_S5) + { + uMinDepth_0 = 4294967295U; + uMaxDepth_0 = 0U; + oLightCount_0 = 0U; + tLightCount_0 = 0U; + groupFrustum_0 = gCullingParams_frustums_0._data[gl_WorkGroupID.x + gl_WorkGroupID.y * gCullingParams_0.numThreadGroups_0.x]; + +#line 81 + } + +#line 90 + barrier(); + + atomicMin((uMinDepth_0), (uDepth_0)); + atomicMax((uMaxDepth_0), (uDepth_0)); + + barrier(); + +#line 104 + Plane_0 _S6 = { vec3(0.0, 0.0, -1.0), - uintBitsToFloat(uMinDepth_0) }; + +#line 125 + uvec2 _S7 = gl_WorkGroupID.xy; + +#line 125 + uint i_0 = gl_LocalInvocationIndex; + +#line 125 + for(;;) + { + +#line 106 + if(i_0 < gLightEnv_0.numPointLights_0) + { + } + else + { + +#line 106 + break; + } + PointLight_0 light_0 = gLightEnv_pointLights_0._data[i_0]; + + + + tAppendLight_0(i_0); + if(!PointLight_insidePlane_0(light_0, _S6)) + { + oAppendLight_0(i_0); + +#line 113 + } + +#line 106 + i_0 = i_0 + 1024U; + +#line 106 + } + +#line 120 + barrier(); + + if(_S5) + { + ((oLightIndexStartOffset_0) = atomicAdd((gCullingParams_oLightIndexCounter_0._data[0U]), (oLightCount_0))); + imageStore((gCullingParams_oLightGrid_0), ivec2((_S7)), uvec4(uvec2(oLightIndexStartOffset_0, oLightCount_0), uint(0), uint(0))); + + ((tLightIndexStartOffset_0) = atomicAdd((gCullingParams_tLightIndexCounter_0._data[0U]), (tLightCount_0))); + imageStore((gCullingParams_tLightGrid_0), ivec2((_S7)), uvec4(uvec2(tLightIndexStartOffset_0, tLightCount_0), uint(0), uint(0))); + +#line 122 + } + +#line 130 + barrier(); + +#line 130 + uint k_0; + +#line 130 + if(gl_LocalInvocationIndex < oLightCount_0) + { + +#line 130 + k_0 = gl_LocalInvocationIndex; + +#line 130 + for(;;) + { + + + gCullingParams_oLightIndexList_0._data[oLightIndexStartOffset_0 + k_0] = oLightList_0[k_0]; + +#line 132 + uint j_0 = k_0 + 1024U; + +#line 132 + if(j_0 < oLightCount_0) + { + } + else + { + +#line 132 + break; + } + +#line 132 + k_0 = j_0; + +#line 132 + } + +#line 132 + } + +#line 132 + if(gl_LocalInvocationIndex < tLightCount_0) + { + +#line 132 + k_0 = gl_LocalInvocationIndex; + +#line 132 + for(;;) + { + +#line 140 + gCullingParams_tLightIndexList_0._data[tLightIndexStartOffset_0 + k_0] = tLightList_0[k_0]; + +#line 138 + uint k_1 = k_0 + 1024U; + +#line 138 + if(k_1 < tLightCount_0) + { + } + else + { + +#line 138 + break; + } + +#line 138 + k_0 = k_1; + +#line 138 + } + +#line 138 + } + +#line 144 + return; +} + diff --git a/src/Engine/Asset/FontAsset.cpp b/src/Engine/Asset/FontAsset.cpp index 33013af..665a8fb 100644 --- a/src/Engine/Asset/FontAsset.cpp +++ b/src/Engine/Asset/FontAsset.cpp @@ -1,6 +1,7 @@ #include "FontAsset.h" #include "Graphics/Graphics.h" -#include "Graphics/Vulkan/VulkanGraphicsEnums.h" +#include "Graphics/Vulkan/Enums.h" +#include "Graphics/Texture.h" #include using namespace Seele; diff --git a/src/Engine/Asset/MeshAsset.cpp b/src/Engine/Asset/MeshAsset.cpp index 4ff1cac..46afa40 100644 --- a/src/Engine/Asset/MeshAsset.cpp +++ b/src/Engine/Asset/MeshAsset.cpp @@ -2,9 +2,6 @@ #include "Graphics/Graphics.h" #include "Graphics/Mesh.h" #include "AssetRegistry.h" -#include "Graphics/VertexShaderInput.h" -#include "Material/MaterialInterface.h" -#include "Graphics/StaticMeshVertexInput.h" using namespace Seele; diff --git a/src/Engine/Asset/TextureAsset.cpp b/src/Engine/Asset/TextureAsset.cpp index f0b6558..0090e71 100644 --- a/src/Engine/Asset/TextureAsset.cpp +++ b/src/Engine/Asset/TextureAsset.cpp @@ -1,8 +1,7 @@ #include "TextureAsset.h" -#include "Graphics/GraphicsResources.h" #include "Graphics/Graphics.h" #include "Window/WindowManager.h" -#include "Graphics/Vulkan/VulkanGraphicsEnums.h" +#include "Graphics/Vulkan/Enums.h" #include "ktx.h" using namespace Seele; diff --git a/src/Engine/Component/Camera.h b/src/Engine/Component/Camera.h index 1b951e2..3a3cc73 100644 --- a/src/Engine/Component/Camera.h +++ b/src/Engine/Component/Camera.h @@ -1,7 +1,6 @@ #pragma once #include "Component.h" #include "Math/Matrix.h" -#include "Graphics/GraphicsResources.h" #include "Transform.h" namespace Seele diff --git a/src/Engine/Component/KeyboardInput.h b/src/Engine/Component/KeyboardInput.h index ef43905..33d3b61 100644 --- a/src/Engine/Component/KeyboardInput.h +++ b/src/Engine/Component/KeyboardInput.h @@ -1,5 +1,5 @@ #pragma once -#include "Graphics/GraphicsResources.h" +#include "Graphics/Resources.h" namespace Seele { diff --git a/src/Engine/Component/Mesh.h b/src/Engine/Component/Mesh.h index 406cdd5..7d2f6e9 100644 --- a/src/Engine/Component/Mesh.h +++ b/src/Engine/Component/Mesh.h @@ -1,7 +1,6 @@ #pragma once #include "Asset/MeshAsset.h" #include "Graphics/VertexData.h" -#include "Graphics/TopologyData.h" #include "Material/MaterialInstance.h" namespace Seele diff --git a/src/Engine/Component/Skybox.h b/src/Engine/Component/Skybox.h index e2e5f61..77cf477 100644 --- a/src/Engine/Component/Skybox.h +++ b/src/Engine/Component/Skybox.h @@ -1,5 +1,5 @@ #pragma once -#include "Graphics/GraphicsResources.h" +#include "Graphics/Texture.h" namespace Seele { diff --git a/src/Engine/Containers/Array.h b/src/Engine/Containers/Array.h index e479e1c..a3b4c6a 100644 --- a/src/Engine/Containers/Array.h +++ b/src/Engine/Containers/Array.h @@ -310,6 +310,20 @@ public: } return end(); } + + template + requires std::predicate + constexpr iterator find(Pred pred) noexcept + { + for (size_type i = 0; i < arraySize; ++i) + { + if (pred(_data[i])) + { + return const_iterator(&_data[i]); + } + } + return end(); + } constexpr allocator_type get_allocator() const noexcept { return allocator; diff --git a/src/Engine/Graphics/Buffer.cpp b/src/Engine/Graphics/Buffer.cpp new file mode 100644 index 0000000..2ba96c5 --- /dev/null +++ b/src/Engine/Graphics/Buffer.cpp @@ -0,0 +1,91 @@ +#include "Buffer.h" + +using namespace Seele; +using namespace Seele::Gfx; + +Buffer::Buffer(QueueFamilyMapping mapping, QueueType startQueue) + : QueueOwnedResource(mapping, startQueue) +{ +} + +Buffer::~Buffer() +{ +} + +UniformBuffer::UniformBuffer(QueueFamilyMapping mapping, const BulkResourceData& resourceData) + : Buffer(mapping, resourceData.owner) + , contents(resourceData.size) +{ + if (resourceData.data != nullptr) + { + std::memcpy(contents.data(), resourceData.data, contents.size()); + } +} + +UniformBuffer::~UniformBuffer() +{ +} + +bool UniformBuffer::updateContents(const BulkResourceData& resourceData) +{ + assert(contents.size() == resourceData.size); + if (std::memcmp(contents.data(), resourceData.data, contents.size()) == 0) + { + return false; + } + std::memcpy(contents.data(), resourceData.data, contents.size()); + return true; +} + +ShaderBuffer::ShaderBuffer(QueueFamilyMapping mapping, uint32 stride, uint32 numElements, const BulkResourceData& resourceData) + : Buffer(mapping, resourceData.owner) + , contents(resourceData.size) + , stride(stride) + , numElements(numElements) +{ + if (resourceData.data != nullptr) + { + std::memcpy(contents.data(), resourceData.data, resourceData.size); + } +} +ShaderBuffer::~ShaderBuffer() +{ +} + +bool ShaderBuffer::updateContents(const BulkResourceData& resourceData) +{ + assert(contents.size() >= resourceData.size); + if (std::memcmp(contents.data(), resourceData.data, resourceData.size) == 0) + { + return false; + } + std::memcpy(contents.data(), resourceData.data, resourceData.size); + return true; +} +VertexBuffer::VertexBuffer(QueueFamilyMapping mapping, uint32 numVertices, uint32 vertexSize, QueueType startQueueType) + : Buffer(mapping, startQueueType) + , numVertices(numVertices) + , vertexSize(vertexSize) +{ +} +VertexBuffer::~VertexBuffer() +{ +} +IndexBuffer::IndexBuffer(QueueFamilyMapping mapping, uint64 size, Gfx::SeIndexType indexType, QueueType startQueueType) + : Buffer(mapping, startQueueType) + , indexType(indexType) +{ + switch (indexType) + { + case SE_INDEX_TYPE_UINT16: + numIndices = size / sizeof(uint16); + break; + case SE_INDEX_TYPE_UINT32: + numIndices = size / sizeof(uint32); + default: + break; + } +} +IndexBuffer::~IndexBuffer() +{ +} \ No newline at end of file diff --git a/src/Engine/Graphics/Buffer.h b/src/Engine/Graphics/Buffer.h new file mode 100644 index 0000000..3bcf165 --- /dev/null +++ b/src/Engine/Graphics/Buffer.h @@ -0,0 +1,153 @@ +#pragma once +#include "Resources.h" + +namespace Seele +{ +namespace Gfx +{ + +// IMPORTANT!! +// WHEN DERIVING FROM ANY Gfx:: BASE CLASSES WITH MULTIPLE INHERITANCE +// ALWAYS PUT THE Gfx:: BASE CLASS FIRST +// This is because the refcounting object is unique per allocation, so +// the base address of both the Gfx:: and the implementation class +// need to match for it to work +class Buffer : public QueueOwnedResource +{ +public: + Buffer(QueueFamilyMapping mapping, QueueType startQueueType); + virtual ~Buffer(); + +protected: + // Inherited via QueueOwnedResource + virtual void executeOwnershipBarrier(QueueType newOwner) = 0; +}; + +class UniformBuffer : public Buffer +{ +public: + UniformBuffer(QueueFamilyMapping mapping, const BulkResourceData& resourceData); + virtual ~UniformBuffer(); + // returns true if an update was performed, false if the old contents == new contents + virtual bool updateContents(const BulkResourceData& resourceData); + bool isDataEquals(UniformBuffer* other) + { + if(other == nullptr) + { + return false; + } + if(contents.size() != other->contents.size()) + { + return false; + } + if(std::memcmp(contents.data(), other->contents.data(), contents.size()) != 0) + { + return false; + } + return true; + } +protected: + Array contents; + // Inherited via QueueOwnedResource + virtual void executeOwnershipBarrier(QueueType newOwner) = 0; + virtual void executePipelineBarrier(SeAccessFlags srcAccess, SePipelineStageFlags srcStage, + SeAccessFlags dstAccess, SePipelineStageFlags dstStage) = 0; +}; +DEFINE_REF(UniformBuffer) + +class VertexBuffer : public Buffer +{ +public: + VertexBuffer(QueueFamilyMapping mapping, uint32 numVertices, uint32 vertexSize, QueueType startQueueType); + virtual ~VertexBuffer(); + constexpr uint32 getNumVertices() const + { + return numVertices; + } + // Size of one vertex in bytes + constexpr uint32 getVertexSize() const + { + return vertexSize; + } + + virtual void updateRegion(BulkResourceData update) = 0; + virtual void download(Array& buffer) = 0; +protected: + // Inherited via QueueOwnedResource + virtual void executeOwnershipBarrier(QueueType newOwner) = 0; + virtual void executePipelineBarrier(SeAccessFlags srcAccess, SePipelineStageFlags srcStage, + SeAccessFlags dstAccess, SePipelineStageFlags dstStage) = 0; + uint32 numVertices; + uint32 vertexSize; +}; +DEFINE_REF(VertexBuffer) + +class IndexBuffer : public Buffer +{ +public: + IndexBuffer(QueueFamilyMapping mapping, uint64 size, Gfx::SeIndexType index, QueueType startQueueType); + virtual ~IndexBuffer(); + constexpr uint64 getNumIndices() const + { + return numIndices; + } + constexpr Gfx::SeIndexType getIndexType() const + { + return indexType; + } + + virtual void download(Array& buffer) = 0; +protected: + // Inherited via QueueOwnedResource + virtual void executeOwnershipBarrier(QueueType newOwner) = 0; + virtual void executePipelineBarrier(SeAccessFlags srcAccess, SePipelineStageFlags srcStage, + SeAccessFlags dstAccess, SePipelineStageFlags dstStage) = 0; + Gfx::SeIndexType indexType; + uint64 numIndices; +}; +DEFINE_REF(IndexBuffer) + +class ShaderBuffer : public Buffer +{ +public: + ShaderBuffer(QueueFamilyMapping mapping, uint32 stride, uint32 numElements, const BulkResourceData& bulkResourceData); + virtual ~ShaderBuffer(); + virtual bool updateContents(const BulkResourceData& resourceData); + bool isDataEquals(ShaderBuffer* other) + { + if(other == nullptr) + { + return false; + } + if(contents.size() != other->contents.size()) + { + return false; + } + if(std::memcmp(contents.data(), other->contents.data(), contents.size()) != 0) + { + return false; + } + return true; + } + constexpr uint32 getNumElements() const + { + return numElements; + } + constexpr uint32 getStride() const + { + return stride; + } +protected: + // Inherited via QueueOwnedResource + virtual void executeOwnershipBarrier(QueueType newOwner) = 0; + virtual void executePipelineBarrier(SeAccessFlags srcAccess, SePipelineStageFlags srcStage, + SeAccessFlags dstAccess, SePipelineStageFlags dstStage) = 0; + + Array contents; + uint32 numElements; + uint32 stride; +}; +DEFINE_REF(ShaderBuffer) + +} +} \ No newline at end of file diff --git a/src/Engine/Graphics/CMakeLists.txt b/src/Engine/Graphics/CMakeLists.txt index c88e677..f791abd 100644 --- a/src/Engine/Graphics/CMakeLists.txt +++ b/src/Engine/Graphics/CMakeLists.txt @@ -1,33 +1,47 @@ target_sources(Engine PRIVATE + Buffer.h + Buffer.cpp DebugVertex.h - GraphicsResources.h - GraphicsResources.cpp - GraphicsInitializer.h - GraphicsEnums.h - GraphicsEnums.cpp + Descriptor.h + Descriptor.cpp + Enums.h + Enums.cpp Graphics.h Graphics.cpp + Initializer.h Mesh.h Mesh.cpp + RenderTarget.h + RenderTarget.cpp + Resources.h + Resources.cpp + Shader.h + Shader.cpp ShaderCompiler.h ShaderCompiler.cpp StaticMeshVertexData.h StaticMeshVertexData.cpp + Texture.h + Texture.cpp VertexData.h VertexData.cpp) target_sources(Engine PUBLIC FILE_SET HEADERS FILES + Buffer.h DebugVertex.h - GraphicsResources.h - GraphicsInitializer.h - GraphicsEnums.h + Descriptor.h Graphics.h + Initializer.h Mesh.h + RenderTarget.h + Resources.h + Shader.h ShaderCompiler.h StaticMeshVertexData.h + Texture.h VertexData.h) add_subdirectory(RenderPass/) diff --git a/src/Engine/Graphics/Descriptor.cpp b/src/Engine/Graphics/Descriptor.cpp new file mode 100644 index 0000000..7c6cb1e --- /dev/null +++ b/src/Engine/Graphics/Descriptor.cpp @@ -0,0 +1,47 @@ +#include "Descriptor.h" + +using namespace Seele; +using namespace Seele::Gfx; + +void DescriptorLayout::addDescriptorBinding(uint32 bindingIndex, SeDescriptorType type, uint32 arrayCount, SeDescriptorBindingFlags bindingFlags, SeShaderStageFlags shaderStages) +{ + if (descriptorBindings.size() <= bindingIndex) + { + descriptorBindings.resize(bindingIndex + 1); + } + DescriptorBinding& binding = descriptorBindings[bindingIndex]; + binding.binding = bindingIndex; + binding.descriptorType = type; + binding.descriptorCount = arrayCount; + binding.bindingFlags = bindingFlags; + binding.shaderStages = shaderStages; +} + +PDescriptorSet DescriptorLayout::allocateDescriptorSet() +{ + std::scoped_lock lock(allocatorLock); + PDescriptorSet result; + allocator->allocateDescriptorSet(result); + return result; +} + +void DescriptorLayout::reset() +{ + std::scoped_lock lock(allocatorLock); + allocator->reset(); +} + +void PipelineLayout::addDescriptorLayout(uint32 setIndex, PDescriptorLayout layout) +{ + if (descriptorSetLayouts.size() <= setIndex) + { + descriptorSetLayouts.resize(setIndex + 1); + } + descriptorSetLayouts[setIndex] = layout; + layout->setIndex = setIndex; +} + +void PipelineLayout::addPushConstants(const SePushConstantRange& pushConstant) +{ + pushConstants.add(pushConstant); +} diff --git a/src/Engine/Graphics/Descriptor.h b/src/Engine/Graphics/Descriptor.h new file mode 100644 index 0000000..8684c33 --- /dev/null +++ b/src/Engine/Graphics/Descriptor.h @@ -0,0 +1,122 @@ +#pragma once +#include "Enums.h" +#include "Resources.h" + +namespace Seele +{ +namespace Gfx +{ + +class DescriptorBinding +{ +public: + DescriptorBinding() + : binding(0), descriptorType(SE_DESCRIPTOR_TYPE_MAX_ENUM), descriptorCount(0x7fff), shaderStages(SE_SHADER_STAGE_ALL) + { + } + DescriptorBinding(const DescriptorBinding& other) + : binding(other.binding), descriptorType(other.descriptorType), descriptorCount(other.descriptorCount), shaderStages(other.shaderStages) + { + } + uint32 binding; + SeDescriptorType descriptorType; + uint32 descriptorCount; + SeDescriptorBindingFlags bindingFlags = 0; + SeShaderStageFlags shaderStages; +}; +DEFINE_REF(DescriptorBinding) + +DECLARE_REF(DescriptorSet) +class DescriptorAllocator +{ +public: + DescriptorAllocator() {} + virtual ~DescriptorAllocator() {} + virtual void allocateDescriptorSet(PDescriptorSet& descriptorSet) = 0; + virtual void reset() = 0; +}; +DEFINE_REF(DescriptorAllocator) +DECLARE_REF(UniformBuffer) +DECLARE_REF(ShaderBuffer) +DECLARE_REF(Texture) +DECLARE_REF(SamplerState) +class DescriptorSet +{ +public: + virtual ~DescriptorSet() {} + virtual void writeChanges() = 0; + virtual void updateBuffer(uint32 binding, PUniformBuffer uniformBuffer) = 0; + virtual void updateBuffer(uint32 binding, PShaderBuffer ShaderBuffer) = 0; + virtual void updateSampler(uint32 binding, PSamplerState samplerState) = 0; + virtual void updateTexture(uint32 binding, PTexture texture, PSamplerState samplerState = nullptr) = 0; + virtual void updateTextureArray(uint32_t binding, Array texture) = 0; + virtual bool operator<(PDescriptorSet other) = 0; + + virtual uint32 getSetIndex() const = 0; +}; +DEFINE_REF(DescriptorSet) + +class DescriptorLayout +{ +public: + DescriptorLayout(const std::string& name) + : setIndex(0) + , name(name) + { + } + virtual ~DescriptorLayout() {} + DescriptorLayout& operator=(const DescriptorLayout& other) + { + if (this != &other) + { + descriptorBindings.resize(other.descriptorBindings.size()); + for (uint32 i = 0; i < descriptorBindings.size(); ++i) + { + descriptorBindings[i] = other.descriptorBindings[i]; + } + } + return *this; + } + virtual void create() = 0; + virtual void addDescriptorBinding(uint32 binding, SeDescriptorType type, uint32 arrayCount = 1, SeDescriptorBindingFlags bindingFlags = 0, SeShaderStageFlags shaderStages = SeShaderStageFlagBits::SE_SHADER_STAGE_ALL); + virtual void reset(); + virtual PDescriptorSet allocateDescriptorSet(); + const Array& getBindings() const { return descriptorBindings; } + constexpr uint32 getSetIndex() const { return setIndex; } + constexpr void setSetIndex(uint32 _setIndex) { setIndex = _setIndex; } + +protected: + Array descriptorBindings; + PDescriptorAllocator allocator; + std::mutex allocatorLock; + uint32 setIndex; + std::string name; + friend class PipelineLayout; + friend class DescriptorAllocator; +}; +DEFINE_REF(DescriptorLayout) +class PipelineLayout +{ +public: + PipelineLayout(PPipelineLayout baseLayout) + { + if (baseLayout != nullptr) + { + descriptorSetLayouts = baseLayout->descriptorSetLayouts; + pushConstants = baseLayout->pushConstants; + } + } + virtual ~PipelineLayout() {} + virtual void create() = 0; + virtual void reset() = 0; + void addDescriptorLayout(uint32 setIndex, PDescriptorLayout layout); + void addPushConstants(const SePushConstantRange& pushConstants); + virtual uint32 getHash() const = 0; + +protected: + Array descriptorSetLayouts; + Array pushConstants; +}; +DEFINE_REF(PipelineLayout) +} +} \ No newline at end of file diff --git a/src/Engine/Graphics/GraphicsEnums.cpp b/src/Engine/Graphics/Enums.cpp similarity index 100% rename from src/Engine/Graphics/GraphicsEnums.cpp rename to src/Engine/Graphics/Enums.cpp diff --git a/src/Engine/Graphics/GraphicsEnums.h b/src/Engine/Graphics/Enums.h similarity index 100% rename from src/Engine/Graphics/GraphicsEnums.h rename to src/Engine/Graphics/Enums.h diff --git a/src/Engine/Graphics/Graphics.h b/src/Engine/Graphics/Graphics.h index 3e64849..76ccec8 100644 --- a/src/Engine/Graphics/Graphics.h +++ b/src/Engine/Graphics/Graphics.h @@ -1,13 +1,31 @@ #pragma once #include "MinimalEngine.h" -#include "GraphicsResources.h" +#include "Resources.h" #include "Containers/Array.h" -#include "ShaderCompiler.h" namespace Seele { namespace Gfx { +DECLARE_REF(Window) +DECLARE_REF(Viewport) +DECLARE_REF(RenderTargetLayout) +DECLARE_REF(ShaderCompiler) +DECLARE_REF(Texture) +DECLARE_REF(Texture2D) +DECLARE_REF(Texture3D) +DECLARE_REF(TextureCube) +DECLARE_REF(DescriptorLayout) +DECLARE_REF(VertexShader) +DECLARE_REF(FragmentShader) +DECLARE_REF(ComputeShader) +DECLARE_REF(TaskShader) +DECLARE_REF(MeshShader) +DECLARE_REF(ShaderBuffer) +DECLARE_REF(VertexBuffer) +DECLARE_REF(IndexBuffer) +DECLARE_REF(UniformBuffer) +DECLARE_REF(PipelineLayout) class Graphics { public: @@ -46,12 +64,12 @@ public: virtual PComputeCommand createComputeCommand(const std::string& name = "") = 0; virtual PVertexDeclaration createVertexDeclaration(const Array& element) = 0; virtual PVertexShader createVertexShader(const ShaderCreateInfo& createInfo) = 0; - virtual PControlShader createControlShader(const ShaderCreateInfo& createInfo) = 0; - virtual PEvaluationShader createEvaluationShader(const ShaderCreateInfo& createInfo) = 0; - virtual PGeometryShader createGeometryShader(const ShaderCreateInfo& createInfo) = 0; virtual PFragmentShader createFragmentShader(const ShaderCreateInfo& createInfo) = 0; virtual PComputeShader createComputeShader(const ShaderCreateInfo& createInfo) = 0; - virtual PGraphicsPipeline createGraphicsPipeline(const GraphicsPipelineCreateInfo& createInfo) = 0; + virtual PMeshShader createMeshShader(const ShaderCreateInfo& createInfo) = 0; + virtual PTaskShader createTaskShader(const ShaderCreateInfo& createInfo) = 0; + virtual PGraphicsPipeline createGraphicsPipeline(const LegacyPipelineCreateInfo& createInfo) = 0; + virtual PGraphicsPipeline createGraphicsPipeline(const MeshPipelineCreateInfo& createInfo) = 0; virtual PComputePipeline createComputePipeline(const ComputePipelineCreateInfo& createInfo) = 0; virtual PSamplerState createSamplerState(const SamplerCreateInfo& createInfo) = 0; diff --git a/src/Engine/Graphics/GraphicsResources.cpp b/src/Engine/Graphics/GraphicsResources.cpp deleted file mode 100644 index 53284ec..0000000 --- a/src/Engine/Graphics/GraphicsResources.cpp +++ /dev/null @@ -1,549 +0,0 @@ -#include "GraphicsResources.h" -#include "Graphics.h" -#include "RenderPass/DepthPrepass.h" -#include "RenderPass/BasePass.h" -#include "Material/Material.h" - -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() -{ -} - -ShaderMap::~ShaderMap() -{ -} - -const ShaderCollection* ShaderMap::findShaders(PermutationId&& id) const -{ - for(uint32 i = 0; i < shaders.size(); ++i) - { - if(shaders[i].id == id) - { - return &(shaders[i]); - } - } - return nullptr; -} -ShaderCollection& ShaderMap::createShaders( - PGraphics graphics, - RenderPassType renderPass, - PMaterial material, - VertexInputType* vertexInput, - bool /*bPositionOnly*/) -{ - std::scoped_lock lock(shadersLock); - ShaderCollection& collection = shaders.add(); - //collection.vertexDeclaration = bPositionOnly ? vertexInput->getPositionDeclaration() : vertexInput->getDeclaration(); - - 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(); - - 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) - { - 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); - - return collection; -} -void DescriptorLayout::addDescriptorBinding(uint32 bindingIndex, SeDescriptorType type, uint32 arrayCount, SeDescriptorBindingFlags bindingFlags, SeShaderStageFlags shaderStages) -{ - if (descriptorBindings.size() <= bindingIndex) - { - descriptorBindings.resize(bindingIndex + 1); - } - DescriptorBinding& binding = descriptorBindings[bindingIndex]; - binding.binding = bindingIndex; - binding.descriptorType = type; - binding.descriptorCount = arrayCount; - binding.bindingFlags = bindingFlags; - binding.shaderStages = shaderStages; -} - -PDescriptorSet DescriptorLayout::allocateDescriptorSet() -{ - std::scoped_lock lock(allocatorLock); - PDescriptorSet result; - allocator->allocateDescriptorSet(result); - return result; -} - -void DescriptorLayout::reset() -{ - std::scoped_lock lock(allocatorLock); - allocator->reset(); -} - -void PipelineLayout::addDescriptorLayout(uint32 setIndex, PDescriptorLayout layout) -{ - if (descriptorSetLayouts.size() <= setIndex) - { - descriptorSetLayouts.resize(setIndex + 1); - } - descriptorSetLayouts[setIndex] = layout; - layout->setIndex = setIndex; -} - -void PipelineLayout::addPushConstants(const SePushConstantRange &pushConstant) -{ - pushConstants.add(pushConstant); -} - -QueueOwnedResource::QueueOwnedResource(QueueFamilyMapping mapping, QueueType startQueueType) - : currentOwner(startQueueType) - , mapping(mapping) -{ -} - -QueueOwnedResource::~QueueOwnedResource() -{ -} - -void QueueOwnedResource::transferOwnership(QueueType newOwner) -{ - if(mapping.needsTransfer(currentOwner, newOwner)) - { - executeOwnershipBarrier(newOwner); - } - currentOwner = newOwner; -} - -void QueueOwnedResource::pipelineBarrier(SeAccessFlags srcAccess, SePipelineStageFlags srcStage, SeAccessFlags dstAccess, SePipelineStageFlags dstStage) -{ - // maybe add some checks - executePipelineBarrier(srcAccess, srcStage, dstAccess, dstStage); -} - -Buffer::Buffer(QueueFamilyMapping mapping, QueueType startQueue) - : QueueOwnedResource(mapping, startQueue) -{ -} - -Buffer::~Buffer() -{ -} - -UniformBuffer::UniformBuffer(QueueFamilyMapping mapping, const BulkResourceData& resourceData) - : Buffer(mapping, resourceData.owner) - , contents(resourceData.size) -{ - if(resourceData.data != nullptr) - { - std::memcpy(contents.data(), resourceData.data, contents.size()); - } -} - -UniformBuffer::~UniformBuffer() -{ -} - -bool UniformBuffer::updateContents(const BulkResourceData& resourceData) -{ - assert(contents.size() == resourceData.size); - if(std::memcmp(contents.data(), resourceData.data, contents.size()) == 0) - { - return false; - } - std::memcpy(contents.data(), resourceData.data, contents.size()); - return true; -} - -ShaderBuffer::ShaderBuffer(QueueFamilyMapping mapping, uint32 stride, uint32 numElements, const BulkResourceData& resourceData) - : Buffer(mapping, resourceData.owner) - , contents(resourceData.size) - , stride(stride) - , numElements(numElements) -{ - if(resourceData.data != nullptr) - { - std::memcpy(contents.data(), resourceData.data, resourceData.size); - } -} -ShaderBuffer::~ShaderBuffer() -{ -} - -bool ShaderBuffer::updateContents(const BulkResourceData& resourceData) -{ - assert(contents.size() >= resourceData.size); - if(std::memcmp(contents.data(), resourceData.data, resourceData.size) == 0) - { - return false; - } - std::memcpy(contents.data(), resourceData.data, resourceData.size); - return true; -} -VertexBuffer::VertexBuffer(QueueFamilyMapping mapping, uint32 numVertices, uint32 vertexSize, QueueType startQueueType) - : Buffer(mapping, startQueueType) - , numVertices(numVertices) - , vertexSize(vertexSize) -{ -} -VertexBuffer::~VertexBuffer() -{ -} -IndexBuffer::IndexBuffer(QueueFamilyMapping mapping, uint64 size, Gfx::SeIndexType indexType, QueueType startQueueType) - : Buffer(mapping, startQueueType) - , indexType(indexType) -{ - switch (indexType) - { - case SE_INDEX_TYPE_UINT16: - numIndices = size / sizeof(uint16); - break; - case SE_INDEX_TYPE_UINT32: - numIndices = size / sizeof(uint32); - default: - break; - } -} -IndexBuffer::~IndexBuffer() -{ -} -VertexStream::VertexStream() -{} -VertexStream::VertexStream(uint32 stride, uint32 offset, uint8 instanced) - : stride(stride) - , offset(offset) - , instanced(instanced) -{ -} -VertexStream::~VertexStream() -{ -} -void VertexStream::addVertexElement(VertexElement element) -{ - vertexDescription.add(element); -} -const Array VertexStream::getVertexDescriptions() const -{ - return vertexDescription; -} - -VertexDataManager::VertexDataManager(PGraphics graphics) - : currentSize(8 * 1024 * 1024) - , inUse(0) - , graphics(graphics) -{ - VertexBufferCreateInfo defaultInfo = { - .resourceData = { - .size = currentSize, - .data = nullptr, - } - }; - buffer = graphics->createVertexBuffer(defaultInfo); -} - -VertexDataManager::~VertexDataManager() -{ - -} - -VertexDataAllocation VertexDataManager::createVertexBuffer(const VertexBufferCreateInfo& vbInfo) -{ - VertexDataAllocation data = allocateData(vbInfo.resourceData.size); - - buffer->updateRegion(BulkResourceData{ - .size = data.size, - .offset = data.offset, - .data = vbInfo.resourceData.data - }); - - activeAllocations[data.offset] = data; - - return data; -} - -void VertexDataManager::freeAllocation(VertexDataAllocation alloc) -{ - uint64 lowerBound = alloc.offset; - uint64 upperBound = alloc.offset + alloc.size; - bool joinedLower = false; - uint64 lowerOffset = 0; - - //Join lower bound - for (auto& [offset, freeAlloc] : freeRanges) - { - if (freeAlloc.offset <= lowerBound - && freeAlloc.offset + freeAlloc.size >= upperBound) - { - // allocation is already in a free region - return; - } - if (freeAlloc.offset + freeAlloc.size == lowerBound) - { - //extend freeAlloc by the allocatedSize - freeAlloc.size += alloc.size; - joinedLower = true; - lowerOffset = freeAlloc.offset; - break; - } - } - //Join upper bound - auto foundAlloc = freeRanges.find(upperBound); - if (foundAlloc != freeRanges.end()) - { - // There is a free allocation ending where the new free one ends - if (joinedLower) - { - // extend allocHandle by another foundAlloc->allocatedSize bytes - freeRanges[lowerOffset].size += foundAlloc->value.size; - freeRanges.erase(upperBound); - } - else - { - // set foundAlloc back by size amount - freeRanges[upperBound].offset -= alloc.size; - freeRanges[upperBound].size += alloc.size; - // place back at correct offset - freeRanges[freeRanges[upperBound].offset] = freeRanges[upperBound]; - // remove from offset map since key changes - freeRanges.erase(upperBound); - } - } - else - { - // No matching upper bound found - if(!joinedLower) - { - // Lower bound also not joined, create new range - freeRanges[alloc.offset] = alloc; - } - } - activeAllocations.erase(alloc.offset); - inUse -= alloc.size; -} - - -VertexDataAllocation VertexDataManager::allocateData(uint64 size) -{ - for (auto& [offset, freeAllocation] : freeRanges) - { - assert(offset == freeAllocation.offset); - if (freeAllocation.size == size) - { - activeAllocations[offset] = freeAllocation; - freeRanges.erase(offset); - inUse += size; - return freeAllocation; - } - else if (size < freeAllocation.size) - { - freeAllocation.size -= size; - freeAllocation.offset += size; - VertexDataAllocation subAlloc = VertexDataAllocation(size, offset); - activeAllocations[offset] = subAlloc; - freeRanges[freeAllocation.offset] = freeAllocation; - freeRanges.erase(offset); - inUse += size; - return subAlloc; - } - } - throw std::logic_error("TODO: expand buffer"); -} - -VertexDeclaration::VertexDeclaration() -{ -} -VertexDeclaration::~VertexDeclaration() -{ -} - -static std::mutex vertexDeclarationLock; -static Map vertexDeclarationCache; - -PVertexDeclaration VertexDeclaration::createDeclaration(PGraphics graphics, const Array& elementList) -{ - std::scoped_lock lock(vertexDeclarationLock); - uint32 key = CRC::Calculate(&elementList, sizeof(VertexElement) * elementList.size(), CRC::CRC_32()); - - auto found = vertexDeclarationCache[key]; - if(found == nullptr) - { - return found; - } - - PVertexDeclaration newDeclaration = graphics->createVertexDeclaration(elementList); - - vertexDeclarationCache[key] = newDeclaration; - return newDeclaration; -} - -Texture::Texture(QueueFamilyMapping mapping, Gfx::QueueType startQueueType) - : QueueOwnedResource(mapping, startQueueType) -{ -} - -Texture::~Texture() -{ -} - -Texture2D::Texture2D(QueueFamilyMapping mapping, Gfx::QueueType startQueueType) - : Texture(mapping, startQueueType) -{ -} - -Texture2D::~Texture2D() -{ -} - -Texture3D::Texture3D(QueueFamilyMapping mapping, Gfx::QueueType startQueueType) - : Texture(mapping, startQueueType) -{ -} - -Texture3D::~Texture3D() -{ -} - -TextureCube::TextureCube(QueueFamilyMapping mapping, Gfx::QueueType startQueueType) - : Texture(mapping, startQueueType) -{ -} - -TextureCube::~TextureCube() -{ -} - -RenderCommand::RenderCommand() -{ -} - -RenderCommand::~RenderCommand() -{ -} - -ComputeCommand::ComputeCommand() -{ - -} - -ComputeCommand::~ComputeCommand() -{ - -} - -RenderTargetLayout::RenderTargetLayout() - : inputAttachments() - , colorAttachments() - , depthAttachment() -{ -} - -RenderTargetLayout::RenderTargetLayout(PRenderTargetAttachment depthAttachment) - : inputAttachments() - , colorAttachments() - , depthAttachment(depthAttachment) - , width(depthAttachment->getTexture()->getSizeX()) - , height(depthAttachment->getTexture()->getSizeY()) -{ -} - -RenderTargetLayout::RenderTargetLayout(PRenderTargetAttachment colorAttachment, PRenderTargetAttachment depthAttachment) - : inputAttachments() - , depthAttachment(depthAttachment) - , width(depthAttachment->getTexture()->getSizeX()) - , height(depthAttachment->getTexture()->getSizeY()) -{ - colorAttachments.add(colorAttachment); -} -RenderTargetLayout::RenderTargetLayout(Array colorAttachments, PRenderTargetAttachment depthAttachment) - : inputAttachments() - , colorAttachments(colorAttachments) - , depthAttachment(depthAttachment) - , width(depthAttachment->getTexture()->getSizeX()) - , height(depthAttachment->getTexture()->getSizeY()) -{ -} -RenderTargetLayout::RenderTargetLayout(Array inputAttachments, Array colorAttachments, PRenderTargetAttachment depthAttachment) - : inputAttachments(inputAttachments) - , colorAttachments(colorAttachments) - , depthAttachment(depthAttachment) - , width(depthAttachment->getTexture()->getSizeX()) - , height(depthAttachment->getTexture()->getSizeY()) -{ -} - -Window::Window(const WindowCreateInfo &createInfo) - : windowState(createInfo) -{ -} - -Window::~Window() -{ -} - -Viewport::Viewport(PWindow owner, const ViewportCreateInfo &viewportInfo) - : sizeX(viewportInfo.dimensions.size.x) - , sizeY(viewportInfo.dimensions.size.y) - , offsetX(viewportInfo.dimensions.offset.x) - , offsetY(viewportInfo.dimensions.offset.y) - , fieldOfView(viewportInfo.fieldOfView) - , owner(owner) -{ -} - -Viewport::~Viewport() -{ -} - -Matrix4 Viewport::getProjectionMatrix() const -{ - if(fieldOfView > 0.0f) - { - return glm::perspective(fieldOfView, sizeX / static_cast(sizeY), 0.1f, 1000.0f); - } - else - { - return glm::ortho(0.0f, (float)sizeX, (float)sizeY, 0.0f); - } -} - diff --git a/src/Engine/Graphics/GraphicsResources.h b/src/Engine/Graphics/GraphicsResources.h deleted file mode 100644 index 1747907..0000000 --- a/src/Engine/Graphics/GraphicsResources.h +++ /dev/null @@ -1,851 +0,0 @@ -#pragma once -#include "Math/Math.h" -#include "GraphicsEnums.h" -#include "Containers/Array.h" -#include "Containers/List.h" -#include "GraphicsInitializer.h" -#include "CRC.h" -#include - - -#ifndef ENABLE_VALIDATION -#define ENABLE_VALIDATION 0 -#endif - -namespace Seele -{ -struct VertexInputStream; -struct VertexStreamComponent; -class VertexInputType; -struct MeshBatchElement; -DECLARE_REF(Material) -namespace Gfx -{ -DECLARE_REF(Graphics) - -class SamplerState -{ -public: - virtual ~SamplerState() - { - } -}; -DEFINE_REF(SamplerState) - -class Shader -{}; -DEFINE_REF(Shader) - -class VertexShader -{ -public: - VertexShader() {} - virtual ~VertexShader() {} -}; -DEFINE_REF(VertexShader) -class ControlShader -{ -public: - ControlShader() : numPatchPoints(0) {} - virtual ~ControlShader() {} - uint32 getNumPatches() const { return numPatchPoints; } - -protected: - uint32 numPatchPoints; -}; -DEFINE_REF(ControlShader) -class EvaluationShader -{ -public: - EvaluationShader() {} - virtual ~EvaluationShader() {} -}; -DEFINE_REF(EvaluationShader) -class GeometryShader -{ -public: - GeometryShader() {} - virtual ~GeometryShader() {} -}; -DEFINE_REF(GeometryShader) -class FragmentShader -{ -public: - FragmentShader() {} - virtual ~FragmentShader() {} -}; -DEFINE_REF(FragmentShader) - -class ComputeShader -{ -public: - ComputeShader() {} - virtual ~ComputeShader() {} -}; -DEFINE_REF(ComputeShader) - -//Uniquely identifies a permutation of shaders -//using the type parameters used to generate it -struct ShaderPermutation -{ - RenderPassType passType; - char vertexInputName[15]; - char materialName[16]; - //TODO: lightmapping etc -}; -//Hashed ShaderPermutation for fast lookup -struct PermutationId -{ - uint32 hash; - PermutationId() - : hash(0) - {} - PermutationId(ShaderPermutation permutation) - : hash(CRC::Calculate(&permutation, sizeof(ShaderPermutation), CRC::CRC_32())) - {} - 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; - } - 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; - } -}; -struct ShaderCollection -{ - PermutationId id; - //PVertexDeclaration vertexDeclaration; - PVertexShader vertexShader; - PControlShader controlShader; - PEvaluationShader evalutionShader; - PGeometryShader geometryShader; - PFragmentShader fragmentShader; -}; -class ShaderMap -{ -public: - ShaderMap(); - ~ShaderMap(); - const ShaderCollection* findShaders(PermutationId&& id) const; - ShaderCollection& createShaders( - PGraphics graphics, - RenderPassType passName, - PMaterial material, - VertexInputType* vertexInput, - bool bPositionOnly); -private: - std::mutex shadersLock; - Array shaders; -}; -DEFINE_REF(ShaderMap) - -class DescriptorBinding -{ -public: - DescriptorBinding() - : binding(0), descriptorType(SE_DESCRIPTOR_TYPE_MAX_ENUM), descriptorCount(0x7fff), shaderStages(SE_SHADER_STAGE_ALL) - { - } - DescriptorBinding(const DescriptorBinding &other) - : binding(other.binding), descriptorType(other.descriptorType), descriptorCount(other.descriptorCount), shaderStages(other.shaderStages) - { - } - uint32 binding; - SeDescriptorType descriptorType; - uint32 descriptorCount; - SeDescriptorBindingFlags bindingFlags = 0; - SeShaderStageFlags shaderStages; -}; -DEFINE_REF(DescriptorBinding) - -DECLARE_REF(DescriptorSet) -class DescriptorAllocator -{ -public: - DescriptorAllocator() {} - virtual ~DescriptorAllocator() {} - virtual void allocateDescriptorSet(PDescriptorSet &descriptorSet) = 0; - virtual void reset() = 0; -}; -DEFINE_REF(DescriptorAllocator) -DECLARE_REF(UniformBuffer) -DECLARE_REF(ShaderBuffer) -DECLARE_REF(Texture) -class DescriptorSet -{ -public: - virtual ~DescriptorSet() {} - virtual void writeChanges() = 0; - virtual void updateBuffer(uint32 binding, PUniformBuffer uniformBuffer) = 0; - virtual void updateBuffer(uint32 binding, PShaderBuffer ShaderBuffer) = 0; - virtual void updateSampler(uint32 binding, PSamplerState samplerState) = 0; - virtual void updateTexture(uint32 binding, PTexture texture, PSamplerState samplerState = nullptr) = 0; - virtual void updateTextureArray(uint32_t binding, Array texture) = 0; - virtual bool operator<(PDescriptorSet other) = 0; - - virtual uint32 getSetIndex() const = 0; -}; -DEFINE_REF(DescriptorSet) - -class DescriptorLayout -{ -public: - DescriptorLayout(const std::string& name) - : setIndex(0) - , name(name) - { - } - virtual ~DescriptorLayout() {} - DescriptorLayout& operator=(const DescriptorLayout &other) - { - if(this != &other) - { - descriptorBindings.resize(other.descriptorBindings.size()); - for(uint32 i = 0; i < descriptorBindings.size(); ++i) - { - descriptorBindings[i] = other.descriptorBindings[i]; - } - } - return *this; - } - virtual void create() = 0; - virtual void addDescriptorBinding(uint32 binding, SeDescriptorType type, uint32 arrayCount = 1, SeDescriptorBindingFlags bindingFlags = 0, SeShaderStageFlags shaderStages = SeShaderStageFlagBits::SE_SHADER_STAGE_ALL); - virtual void reset(); - virtual PDescriptorSet allocateDescriptorSet(); - const Array &getBindings() const { return descriptorBindings; } - constexpr uint32 getSetIndex() const { return setIndex; } - constexpr void setSetIndex(uint32 _setIndex) { setIndex = _setIndex; } - -protected: - Array descriptorBindings; - PDescriptorAllocator allocator; - std::mutex allocatorLock; - uint32 setIndex; - std::string name; - friend class PipelineLayout; - friend class DescriptorAllocator; -}; -DEFINE_REF(DescriptorLayout) -class PipelineLayout -{ -public: - PipelineLayout(PPipelineLayout baseLayout) - { - if(baseLayout != nullptr) - { - descriptorSetLayouts = baseLayout->descriptorSetLayouts; - pushConstants = baseLayout->pushConstants; - } - } - virtual ~PipelineLayout() {} - virtual void create() = 0; - virtual void reset() = 0; - void addDescriptorLayout(uint32 setIndex, PDescriptorLayout layout); - void addPushConstants(const SePushConstantRange &pushConstants); - virtual uint32 getHash() const = 0; - -protected: - Array descriptorSetLayouts; - Array pushConstants; -}; -DEFINE_REF(PipelineLayout) - -struct QueueFamilyMapping -{ - uint32 graphicsFamily; - uint32 computeFamily; - uint32 transferFamily; - uint32 dedicatedTransferFamily; - uint32 getQueueTypeFamilyIndex(Gfx::QueueType type) const - { - switch (type) - { - case Gfx::QueueType::GRAPHICS: - return graphicsFamily; - case Gfx::QueueType::COMPUTE: - return computeFamily; - case Gfx::QueueType::TRANSFER: - return transferFamily; - case Gfx::QueueType::DEDICATED_TRANSFER: - return dedicatedTransferFamily; - default: - return 0x7fff; - } - } - bool needsTransfer(Gfx::QueueType src, Gfx::QueueType dst) const - { - uint32 srcIndex = getQueueTypeFamilyIndex(src); - uint32 dstIndex = getQueueTypeFamilyIndex(dst); - return srcIndex != dstIndex; - } -}; - -class QueueOwnedResource -{ -public: - QueueOwnedResource(QueueFamilyMapping mapping, QueueType startQueueType); - virtual ~QueueOwnedResource(); - - //Preliminary checks to see if the barrier should be executed at all - void transferOwnership(QueueType newOwner); - void pipelineBarrier(SeAccessFlags srcAccess, SePipelineStageFlags srcStage, SeAccessFlags dstAccess, SePipelineStageFlags dstStage); - -protected: - virtual void executeOwnershipBarrier(QueueType newOwner) = 0; - virtual void executePipelineBarrier(SeAccessFlags srcAccess, SePipelineStageFlags srcStage, - SeAccessFlags dstAccess, SePipelineStageFlags dstStage) = 0; - Gfx::QueueType currentOwner; - QueueFamilyMapping mapping; -}; -DEFINE_REF(QueueOwnedResource) - -// IMPORTANT!! -// WHEN DERIVING FROM ANY Gfx:: BASE CLASSES WITH MULTIPLE INHERITANCE -// ALWAYS PUT THE Gfx:: BASE CLASS FIRST -// This is because the refcounting object is unique per allocation, so -// the base address of both the Gfx:: and the implementation class -// need to match for it to work -class Buffer : public QueueOwnedResource -{ -public: - Buffer(QueueFamilyMapping mapping, QueueType startQueueType); - virtual ~Buffer(); - -protected: - // Inherited via QueueOwnedResource - virtual void executeOwnershipBarrier(QueueType newOwner) = 0; -}; - -class UniformBuffer : public Buffer -{ -public: - UniformBuffer(QueueFamilyMapping mapping, const BulkResourceData& resourceData); - virtual ~UniformBuffer(); - // returns true if an update was performed, false if the old contents == new contents - virtual bool updateContents(const BulkResourceData& resourceData); - bool isDataEquals(UniformBuffer* other) - { - if(other == nullptr) - { - return false; - } - if(contents.size() != other->contents.size()) - { - return false; - } - if(std::memcmp(contents.data(), other->contents.data(), contents.size()) != 0) - { - return false; - } - return true; - } -protected: - Array contents; - // Inherited via QueueOwnedResource - virtual void executeOwnershipBarrier(QueueType newOwner) = 0; - virtual void executePipelineBarrier(SeAccessFlags srcAccess, SePipelineStageFlags srcStage, - SeAccessFlags dstAccess, SePipelineStageFlags dstStage) = 0; -}; -DEFINE_REF(UniformBuffer) - -class VertexBuffer : public Buffer -{ -public: - VertexBuffer(QueueFamilyMapping mapping, uint32 numVertices, uint32 vertexSize, QueueType startQueueType); - virtual ~VertexBuffer(); - constexpr uint32 getNumVertices() const - { - return numVertices; - } - // Size of one vertex in bytes - constexpr uint32 getVertexSize() const - { - return vertexSize; - } - - virtual void updateRegion(BulkResourceData update) = 0; - virtual void download(Array& buffer) = 0; -protected: - // Inherited via QueueOwnedResource - virtual void executeOwnershipBarrier(QueueType newOwner) = 0; - virtual void executePipelineBarrier(SeAccessFlags srcAccess, SePipelineStageFlags srcStage, - SeAccessFlags dstAccess, SePipelineStageFlags dstStage) = 0; - uint32 numVertices; - uint32 vertexSize; -}; -DEFINE_REF(VertexBuffer) - -class IndexBuffer : public Buffer -{ -public: - IndexBuffer(QueueFamilyMapping mapping, uint64 size, Gfx::SeIndexType index, QueueType startQueueType); - virtual ~IndexBuffer(); - constexpr uint64 getNumIndices() const - { - return numIndices; - } - constexpr Gfx::SeIndexType getIndexType() const - { - return indexType; - } - - virtual void download(Array& buffer) = 0; -protected: - // Inherited via QueueOwnedResource - virtual void executeOwnershipBarrier(QueueType newOwner) = 0; - virtual void executePipelineBarrier(SeAccessFlags srcAccess, SePipelineStageFlags srcStage, - SeAccessFlags dstAccess, SePipelineStageFlags dstStage) = 0; - Gfx::SeIndexType indexType; - uint64 numIndices; -}; -DEFINE_REF(IndexBuffer) - -class ShaderBuffer : public Buffer -{ -public: - ShaderBuffer(QueueFamilyMapping mapping, uint32 stride, uint32 numElements, const BulkResourceData& bulkResourceData); - virtual ~ShaderBuffer(); - virtual bool updateContents(const BulkResourceData& resourceData); - bool isDataEquals(ShaderBuffer* other) - { - if(other == nullptr) - { - return false; - } - if(contents.size() != other->contents.size()) - { - return false; - } - if(std::memcmp(contents.data(), other->contents.data(), contents.size()) != 0) - { - return false; - } - return true; - } - constexpr uint32 getNumElements() const - { - return numElements; - } - constexpr uint32 getStride() const - { - return stride; - } -protected: - // Inherited via QueueOwnedResource - virtual void executeOwnershipBarrier(QueueType newOwner) = 0; - virtual void executePipelineBarrier(SeAccessFlags srcAccess, SePipelineStageFlags srcStage, - SeAccessFlags dstAccess, SePipelineStageFlags dstStage) = 0; - - Array contents; - uint32 numElements; - uint32 stride; -}; -DEFINE_REF(ShaderBuffer) -class VertexStream -{ -public: - VertexStream(); - VertexStream(uint32 stride, uint32 offset, uint8 instanced); - ~VertexStream(); - void addVertexElement(VertexElement element); - const Array getVertexDescriptions() const; - inline uint8 isInstanced() const { return instanced; } - - uint32 stride; - uint32 offset; - Array vertexDescription; - uint8 instanced; -}; -DEFINE_REF(VertexStream) - -struct VertexDataAllocation -{ - uint64 size; - uint64 offset; -}; - -class VertexDataManager -{ -public: - VertexDataManager(PGraphics graphics); - virtual ~VertexDataManager(); - - VertexDataAllocation createVertexBuffer(const VertexBufferCreateInfo& vbInfo); - void freeAllocation(VertexDataAllocation alloc); - - PVertexBuffer getVertexBuffer() const { return buffer; } -private: - VertexDataAllocation allocateData(uint64 size); - Map freeRanges; - Map activeAllocations; - uint64 currentSize; - uint64 inUse; - PVertexBuffer buffer; - PGraphics graphics; -}; -DEFINE_REF(VertexDataManager) - -class VertexDeclaration -{ -public: - VertexDeclaration(); - ~VertexDeclaration(); - - static PVertexDeclaration createDeclaration(PGraphics graphics, const Array& elementList); -private: -}; -DEFINE_REF(VertexDeclaration) -class GraphicsPipeline -{ -public: - GraphicsPipeline(const GraphicsPipelineCreateInfo& createInfo, PPipelineLayout layout) : createInfo(createInfo) , layout(layout) {} - virtual ~GraphicsPipeline(){} - const GraphicsPipelineCreateInfo& getCreateInfo() const {return createInfo;} - PPipelineLayout getPipelineLayout() const { return layout; } -protected: - GraphicsPipelineCreateInfo createInfo; - PPipelineLayout layout; -}; -DEFINE_REF(GraphicsPipeline) - -class ComputePipeline -{ -public: - ComputePipeline(const ComputePipelineCreateInfo& createInfo, PPipelineLayout layout) : createInfo(createInfo), layout(layout) {} - virtual ~ComputePipeline(){} - const ComputePipelineCreateInfo& getCreateInfo() const { return createInfo; } - PPipelineLayout getPipelineLayout() const { return layout; } -protected: - ComputePipelineCreateInfo createInfo; - PPipelineLayout layout; -}; -DEFINE_REF(ComputePipeline) - -// IMPORTANT!! -// WHEN DERIVING FROM ANY Gfx:: BASE CLASSES WITH MULTIPLE INHERITANCE -// ALWAYS PUT THE Gfx:: BASE CLASS FIRST -// This is because the refcounting object is unique per allocation, so -// the base address of both the Gfx:: and the implementation class -// need to match for it to work -class Texture : public QueueOwnedResource -{ -public: - Texture(QueueFamilyMapping mapping, QueueType startQueueType); - virtual ~Texture(); - - virtual SeFormat getFormat() const = 0; - virtual uint32 getSizeX() const = 0; - virtual uint32 getSizeY() const = 0; - virtual uint32 getSizeZ() const = 0; - virtual uint32 getNumFaces() const { return 1; } - virtual SeSampleCountFlags getNumSamples() const = 0; - virtual uint32 getMipLevels() const = 0; - virtual void changeLayout(SeImageLayout newLayout) = 0; - virtual class Texture2D* getTexture2D() { return nullptr; } - virtual class Texture3D* getTexture3D() { return nullptr; } - virtual class TextureCube* getTextureCube() { return nullptr; } - virtual void* getNativeHandle() { return nullptr; } - virtual void download(uint32 mipLevel, uint32 arrayLayer, uint32 face, Array& buffer) = 0; -protected: - // Inherited via QueueOwnedResource - virtual void executeOwnershipBarrier(QueueType newOwner) = 0; - virtual void executePipelineBarrier(SeAccessFlags srcAccess, SePipelineStageFlags srcStage, - SeAccessFlags dstAccess, SePipelineStageFlags dstStage) = 0; -}; -DEFINE_REF(Texture) - -class Texture2D : public Texture -{ -public: - Texture2D(QueueFamilyMapping mapping, QueueType startQueueType); - virtual ~Texture2D(); - - virtual SeFormat getFormat() const = 0; - virtual uint32 getSizeX() const = 0; - virtual uint32 getSizeY() const = 0; - virtual uint32 getSizeZ() const = 0; - virtual SeSampleCountFlags getNumSamples() const = 0; - virtual uint32 getMipLevels() const = 0; - virtual void changeLayout(SeImageLayout newLayout) = 0; - virtual class Texture2D* getTexture2D() { return this; } -protected: - //Inherited via QueueOwnedResource - virtual void executeOwnershipBarrier(QueueType newOwner) = 0; - virtual void executePipelineBarrier(SeAccessFlags srcAccess, SePipelineStageFlags srcStage, - SeAccessFlags dstAccess, SePipelineStageFlags dstStage) = 0; -}; -DEFINE_REF(Texture2D) - -class Texture3D : public Texture -{ -public: - Texture3D(QueueFamilyMapping mapping, QueueType startQueueType); - virtual ~Texture3D(); - - virtual SeFormat getFormat() const = 0; - virtual uint32 getSizeX() const = 0; - virtual uint32 getSizeY() const = 0; - virtual uint32 getSizeZ() const = 0; - virtual SeSampleCountFlags getNumSamples() const = 0; - virtual uint32 getMipLevels() const = 0; - virtual void changeLayout(SeImageLayout newLayout) = 0; - virtual class Texture3D* getTexture3D() { return this; } -protected: - //Inherited via QueueOwnedResource - virtual void executeOwnershipBarrier(QueueType newOwner) = 0; - virtual void executePipelineBarrier(SeAccessFlags srcAccess, SePipelineStageFlags srcStage, - SeAccessFlags dstAccess, SePipelineStageFlags dstStage) = 0; -}; -DEFINE_REF(Texture3D) - -class TextureCube : public Texture -{ -public: - TextureCube(QueueFamilyMapping mapping, QueueType startQueueType); - virtual ~TextureCube(); - - virtual SeFormat getFormat() const = 0; - virtual uint32 getSizeX() const = 0; - virtual uint32 getSizeY() const = 0; - virtual uint32 getSizeZ() const = 0; - virtual uint32 getNumFaces() const { return 6; } - virtual SeSampleCountFlags getNumSamples() const = 0; - virtual uint32 getMipLevels() const = 0; - virtual void changeLayout(SeImageLayout newLayout) = 0; - virtual class TextureCube* getTextureCube() { return this; } -protected: - //Inherited via QueueOwnedResource - virtual void executeOwnershipBarrier(QueueType newOwner) = 0; - virtual void executePipelineBarrier(SeAccessFlags srcAccess, SePipelineStageFlags srcStage, - SeAccessFlags dstAccess, SePipelineStageFlags dstStage) = 0; -}; -DEFINE_REF(TextureCube) - -DECLARE_REF(Viewport) -class RenderCommand -{ -public: - RenderCommand(); - virtual ~RenderCommand(); - virtual bool isReady() = 0; - virtual void setViewport(Gfx::PViewport viewport) = 0; - virtual void bindPipeline(Gfx::PGraphicsPipeline pipeline) = 0; - virtual void bindDescriptor(Gfx::PDescriptorSet set) = 0; - virtual void bindDescriptor(const Array& sets) = 0; - virtual void bindVertexBuffer(const Array& streams) = 0; - 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); - std::string name; -}; -DEFINE_REF(RenderCommand) -class ComputeCommand -{ -public: - ComputeCommand(); - virtual ~ComputeCommand(); - virtual bool isReady() = 0; - virtual void bindPipeline(Gfx::PComputePipeline pipeline) = 0; - virtual void bindDescriptor(Gfx::PDescriptorSet set) = 0; - virtual void bindDescriptor(const Array& sets) = 0; - virtual void pushConstants(Gfx::PPipelineLayout layout, Gfx::SeShaderStageFlags stage, uint32 offset, uint32 size, const void* data) = 0; - virtual void dispatch(uint32 threadX, uint32 threadY, uint32 threadZ) = 0; - std::string name; -}; -DEFINE_REF(ComputeCommand) - -class Window -{ -public: - Window(const WindowCreateInfo &createInfo); - virtual ~Window(); - virtual void beginFrame() = 0; - virtual void endFrame() = 0; - virtual void onWindowCloseEvent() = 0; - virtual PTexture2D getBackBuffer() const = 0; - virtual void setKeyCallback(std::function callback) = 0; - virtual void setMouseMoveCallback(std::function callback) = 0; - virtual void setMouseButtonCallback(std::function callback) = 0; - virtual void setScrollCallback(std::function callback) = 0; - virtual void setFileCallback(std::function callback) = 0; - virtual void setCloseCallback(std::function callback) = 0; - SeFormat getSwapchainFormat() const - { - return windowState.pixelFormat; - } - SeSampleCountFlags getNumSamples() const - { - return windowState.numSamples; - } - uint32 getSizeX() const - { - return windowState.width; - } - uint32 getSizeY() const - { - return windowState.height; - } - -protected: - WindowCreateInfo windowState; -}; -DEFINE_REF(Window) - -class Viewport -{ -public: - Viewport(PWindow owner, const ViewportCreateInfo &createInfo); - virtual ~Viewport(); - virtual void resize(uint32 newX, uint32 newY) = 0; - virtual void move(uint32 newOffsetX, uint32 newOffsetY) = 0; - constexpr PWindow getOwner() const {return owner;} - constexpr uint32 getSizeX() const {return sizeX;} - constexpr uint32 getSizeY() const {return sizeY;} - constexpr uint32 getOffsetX() const {return offsetX;} - constexpr uint32 getOffsetY() const {return offsetY;} - Matrix4 getProjectionMatrix() const; -protected: - uint32 sizeX; - uint32 sizeY; - uint32 offsetX; - uint32 offsetY; - float fieldOfView; - PWindow owner; -}; -DEFINE_REF(Viewport) - -class RenderTargetAttachment -{ -public: - RenderTargetAttachment(PTexture2D texture, - SeAttachmentLoadOp loadOp = SE_ATTACHMENT_LOAD_OP_LOAD, - SeAttachmentStoreOp storeOp = SE_ATTACHMENT_STORE_OP_STORE, - SeAttachmentLoadOp stencilLoadOp = SE_ATTACHMENT_LOAD_OP_DONT_CARE, - SeAttachmentStoreOp stencilStoreOp = SE_ATTACHMENT_STORE_OP_DONT_CARE) - : loadOp(loadOp) - , storeOp(storeOp) - , stencilLoadOp(stencilLoadOp) - , stencilStoreOp(stencilStoreOp) - , texture(texture) - , clear() - , componentFlags(0) - { - } - virtual ~RenderTargetAttachment() - { - } - virtual PTexture2D getTexture() - { - return texture; - } - virtual SeFormat getFormat() const - { - return texture->getFormat(); - } - virtual SeSampleCountFlags getNumSamples() const - { - return texture->getNumSamples(); - } - virtual uint32 getSizeX() const - { - return texture->getSizeX(); - } - virtual uint32 getSizeY() const - { - return texture->getSizeY(); - } - inline SeAttachmentLoadOp getLoadOp() const { return loadOp; } - inline SeAttachmentStoreOp getStoreOp() const { return storeOp; } - inline SeAttachmentLoadOp getStencilLoadOp() const { return stencilLoadOp; } - inline SeAttachmentStoreOp getStencilStoreOp() const { return stencilStoreOp; } - SeClearValue clear; - SeColorComponentFlags componentFlags; - SeAttachmentLoadOp loadOp; - SeAttachmentStoreOp storeOp; - SeAttachmentLoadOp stencilLoadOp; - SeAttachmentStoreOp stencilStoreOp; -protected: - PTexture2D texture; -}; -DEFINE_REF(RenderTargetAttachment) - -class SwapchainAttachment : public RenderTargetAttachment -{ -public: - SwapchainAttachment(PWindow owner, - SeAttachmentLoadOp loadOp = SE_ATTACHMENT_LOAD_OP_LOAD, - SeAttachmentStoreOp storeOp = SE_ATTACHMENT_STORE_OP_STORE, - SeAttachmentLoadOp stencilLoadOp = SE_ATTACHMENT_LOAD_OP_DONT_CARE, - SeAttachmentStoreOp stencilStoreOp = SE_ATTACHMENT_STORE_OP_DONT_CARE) - : RenderTargetAttachment(nullptr, loadOp, storeOp, stencilLoadOp, stencilStoreOp), owner(owner) - { - clear.color.float32[0] = 0.0f; - clear.color.float32[1] = 0.0f; - clear.color.float32[2] = 0.0f; - clear.color.float32[3] = 1.0f; - componentFlags = SE_COLOR_COMPONENT_R_BIT | SE_COLOR_COMPONENT_G_BIT | SE_COLOR_COMPONENT_B_BIT | SE_COLOR_COMPONENT_A_BIT; - } - virtual PTexture2D getTexture() override - { - return owner->getBackBuffer(); - } - virtual SeFormat getFormat() const override - { - return owner->getSwapchainFormat(); - } - virtual SeSampleCountFlags getNumSamples() const override - { - return owner->getNumSamples(); - } - virtual uint32 getSizeX() const - { - return owner->getSizeX(); - } - virtual uint32 getSizeY() const - { - return owner->getSizeY(); - } -private: - PWindow owner; -}; -DEFINE_REF(SwapchainAttachment) - -class RenderTargetLayout -{ -public: - RenderTargetLayout(); - 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; -}; -DEFINE_REF(RenderTargetLayout) - -class RenderPass -{ -public: - RenderPass(PRenderTargetLayout layout) : layout(layout) {} - virtual ~RenderPass() {} - inline PRenderTargetLayout getLayout() const { return layout; } - -protected: - PRenderTargetLayout layout; -}; -DEFINE_REF(RenderPass) -} // namespace Gfx -} // namespace Seele \ No newline at end of file diff --git a/src/Engine/Graphics/GraphicsInitializer.h b/src/Engine/Graphics/Initializer.h similarity index 58% rename from src/Engine/Graphics/GraphicsInitializer.h rename to src/Engine/Graphics/Initializer.h index 31b6ed3..875fa51 100644 --- a/src/Engine/Graphics/GraphicsInitializer.h +++ b/src/Engine/Graphics/Initializer.h @@ -1,6 +1,7 @@ #pragma once -#include "GraphicsEnums.h" +#include "Enums.h" #include "Containers/Map.h" +#include "Math/Math.h" namespace Seele { @@ -129,7 +130,7 @@ struct SePushConstantRange }; struct VertexElement { - uint8 streamIndex; + uint8 binding; uint8 offset; SeFormat vertexFormat; uint8 attributeIndex; @@ -188,57 +189,117 @@ struct ColorBlendState } blendAttachments[16]; float blendConstants[4]; }; -} // namespace Gfx -DECLARE_NAME_REF(Gfx, VertexDeclaration) -DECLARE_NAME_REF(Gfx, VertexShader) -DECLARE_NAME_REF(Gfx, ControlShader) -DECLARE_NAME_REF(Gfx, EvaluationShader) -DECLARE_NAME_REF(Gfx, GeometryShader) -DECLARE_NAME_REF(Gfx, FragmentShader) -DECLARE_NAME_REF(Gfx, ComputeShader) -DECLARE_NAME_REF(Gfx, PipelineLayout) -DECLARE_NAME_REF(Gfx, RenderPass) -struct GraphicsPipelineCreateInfo + +DECLARE_REF(VertexDeclaration) +DECLARE_REF(VertexShader) +DECLARE_REF(FragmentShader) +DECLARE_REF(TaskShader) +DECLARE_REF(MeshShader) +DECLARE_REF(ComputeShader) +DECLARE_REF(PipelineLayout) +DECLARE_REF(RenderPass) +struct LegacyPipelineCreateInfo { - Gfx::PVertexDeclaration vertexDeclaration; - Gfx::PVertexShader vertexShader; - Gfx::PControlShader controlShader; - Gfx::PEvaluationShader evalShader; - Gfx::PGeometryShader geometryShader; - Gfx::PFragmentShader fragmentShader; - Gfx::PRenderPass renderPass; - Gfx::PPipelineLayout pipelineLayout; - Gfx::SePrimitiveTopology topology; - Gfx::RasterizationState rasterizationState; - Gfx::DepthStencilState depthStencilState; - Gfx::MultisampleState multisampleState; - Gfx::ColorBlendState colorBlend; - GraphicsPipelineCreateInfo() - { - std::memset((void*)this, 0, sizeof(*this)); - topology = Gfx::SE_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST; - rasterizationState.cullMode = Gfx::SE_CULL_MODE_BACK_BIT; - rasterizationState.polygonMode = Gfx::SE_POLYGON_MODE_FILL; - rasterizationState.frontFace = Gfx::SE_FRONT_FACE_COUNTER_CLOCKWISE; - depthStencilState.depthCompareOp = Gfx::SE_COMPARE_OP_LESS_OR_EQUAL; - depthStencilState.minDepthBounds = 0.0f; - depthStencilState.maxDepthBounds = 1.0f; - depthStencilState.stencilTestEnable = false; - depthStencilState.depthWriteEnable = true; - depthStencilState.depthTestEnable = true; - multisampleState.samples = 1; - colorBlend.attachmentCount = 0; - colorBlend.logicOpEnable = false; - colorBlend.blendConstants[0] = 1.0f; - colorBlend.blendConstants[1] = 1.0f; - colorBlend.blendConstants[2] = 1.0f; - colorBlend.blendConstants[3] = 1.0f; - colorBlend.blendAttachments[0].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; - } + PVertexDeclaration vertexDeclaration; + SePrimitiveTopology topology; + PVertexShader vertexShader; + PFragmentShader fragmentShader; + PRenderPass renderPass; + PPipelineLayout pipelineLayout; + MultisampleState multisampleState; + RasterizationState rasterizationState; + DepthStencilState depthStencilState; + ColorBlendState colorBlend; + LegacyPipelineCreateInfo() + : topology(Gfx::SE_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST) + , 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, + }) + , multisampleState(MultisampleState{ + .samples = 1, + }) + , 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, + }, + }) + { + } +}; + +struct MeshPipelineCreateInfo +{ + PTaskShader taskShader; + PMeshShader meshShader; + PFragmentShader fragmentShader; + PRenderPass renderPass; + PPipelineLayout pipelineLayout; + MultisampleState multisampleState; + RasterizationState rasterizationState; + DepthStencilState depthStencilState; + ColorBlendState colorBlend; + MeshPipelineCreateInfo() + : 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, + }) + , multisampleState(MultisampleState{ + .samples = 1, + }) + , 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, + }, + }) + { + } }; struct ComputePipelineCreateInfo { @@ -249,4 +310,5 @@ struct ComputePipelineCreateInfo std::memset((void*)this, 0, sizeof(*this)); } }; +} // namespace Gfx } // namespace Seele \ No newline at end of file diff --git a/src/Engine/Graphics/Mesh.cpp b/src/Engine/Graphics/Mesh.cpp index fe76da0..621ddff 100644 --- a/src/Engine/Graphics/Mesh.cpp +++ b/src/Engine/Graphics/Mesh.cpp @@ -1,12 +1,9 @@ #include "Mesh.h" -#include "VertexShaderInput.h" #include "Graphics/Graphics.h" using namespace Seele; -Mesh::Mesh(PVertexShaderInput vertexInput, Gfx::PIndexBuffer indexBuffer) - : vertexInput(vertexInput) - , indexBuffer(indexBuffer) +Mesh::Mesh() { } diff --git a/src/Engine/Graphics/Mesh.h b/src/Engine/Graphics/Mesh.h index ea73a83..2b16ec4 100644 --- a/src/Engine/Graphics/Mesh.h +++ b/src/Engine/Graphics/Mesh.h @@ -1,5 +1,4 @@ #pragma once -#include "GraphicsResources.h" #include "Asset/MaterialInstanceAsset.h" #include "VertexData.h" diff --git a/src/Engine/Graphics/RenderPass/BasePass.cpp b/src/Engine/Graphics/RenderPass/BasePass.cpp index 50fd9bd..7aa0451 100644 --- a/src/Engine/Graphics/RenderPass/BasePass.cpp +++ b/src/Engine/Graphics/RenderPass/BasePass.cpp @@ -7,6 +7,7 @@ #include "Math/Vector.h" #include "RenderGraph.h" #include "Material/MaterialInstance.h" +#include "Graphics/Descriptor.h" using namespace Seele; @@ -59,14 +60,6 @@ BasePass::~BasePass() { } -void BasePass::readScene() -{ - Array instances; - scene->view([] - (const Component::Transform& transform, const Component::Mesh& mesh) { - }); -} - void BasePass::beginFrame(const Component::Camera& cam) { BulkResourceData uniformUpdate; diff --git a/src/Engine/Graphics/RenderPass/BasePass.h b/src/Engine/Graphics/RenderPass/BasePass.h index 4ad19f9..573a6c5 100644 --- a/src/Engine/Graphics/RenderPass/BasePass.h +++ b/src/Engine/Graphics/RenderPass/BasePass.h @@ -10,7 +10,6 @@ class BasePass : public RenderPass public: BasePass(Gfx::PGraphics graphics, PScene scene); virtual ~BasePass(); - virtual void readScene() override; virtual void beginFrame(const Component::Camera& cam) override; virtual void render() override; virtual void endFrame() override; diff --git a/src/Engine/Graphics/RenderPass/DebugPass.cpp b/src/Engine/Graphics/RenderPass/DebugPass.cpp index adbadb8..a44893e 100644 --- a/src/Engine/Graphics/RenderPass/DebugPass.cpp +++ b/src/Engine/Graphics/RenderPass/DebugPass.cpp @@ -1,5 +1,6 @@ #include "DebugPass.h" #include "Graphics/Graphics.h" +#include "Graphics/RenderTarget.h" using namespace Seele; diff --git a/src/Engine/Graphics/RenderPass/DebugPass.h b/src/Engine/Graphics/RenderPass/DebugPass.h index 6911bfb..382cadf 100644 --- a/src/Engine/Graphics/RenderPass/DebugPass.h +++ b/src/Engine/Graphics/RenderPass/DebugPass.h @@ -1,6 +1,5 @@ #pragma once #include "RenderPass.h" -#include "Graphics/GraphicsResources.h" #include "Scene/Scene.h" #include "Graphics/DebugVertex.h" diff --git a/src/Engine/Graphics/RenderPass/DepthPrepass.cpp b/src/Engine/Graphics/RenderPass/DepthPrepass.cpp index 1c50c79..7256611 100644 --- a/src/Engine/Graphics/RenderPass/DepthPrepass.cpp +++ b/src/Engine/Graphics/RenderPass/DepthPrepass.cpp @@ -68,7 +68,7 @@ void DepthPrepass::render() // ViewData => global, static // Material => per material // VertexData => per meshtype - // SceneData => per topology + // SceneData => per material instance Gfx::PRenderCommand command = graphics->createRenderCommand("DepthRender"); Gfx::PPipelineLayout layout = graphics->createPipelineLayout(depthPrepassLayout); layout->addDescriptorLayout(INDEX_MATERIAL, materialData.material->getDescriptorLayout()); diff --git a/src/Engine/Graphics/RenderPass/LightCullingPass.cpp b/src/Engine/Graphics/RenderPass/LightCullingPass.cpp index 3c80b13..cc4542b 100644 --- a/src/Engine/Graphics/RenderPass/LightCullingPass.cpp +++ b/src/Engine/Graphics/RenderPass/LightCullingPass.cpp @@ -7,8 +7,8 @@ using namespace Seele; -LightCullingPass::LightCullingPass(Gfx::PGraphics graphics) - : RenderPass(graphics) +LightCullingPass::LightCullingPass(Gfx::PGraphics graphics, PScene scene) + : RenderPass(graphics, scene) { } @@ -153,7 +153,7 @@ void LightCullingPass::publishOutputs() createInfo.defines["NUM_MATERIAL_TEXCOORDS"] = "0"; cullingShader = graphics->createComputeShader(createInfo); - ComputePipelineCreateInfo pipelineInfo; + Gfx::ComputePipelineCreateInfo pipelineInfo; pipelineInfo.computeShader = cullingShader; pipelineInfo.pipelineLayout = cullingLayout; cullingPipeline = graphics->createComputePipeline(pipelineInfo); @@ -243,7 +243,7 @@ void LightCullingPass::setupFrustums() createInfo.defines["INDEX_VIEW_PARAMS"] = "0"; frustumShader = graphics->createComputeShader(createInfo); - ComputePipelineCreateInfo pipelineInfo; + Gfx::ComputePipelineCreateInfo pipelineInfo; pipelineInfo.computeShader = frustumShader; pipelineInfo.pipelineLayout = frustumLayout; frustumPipeline = graphics->createComputePipeline(pipelineInfo); diff --git a/src/Engine/Graphics/RenderPass/LightCullingPass.h b/src/Engine/Graphics/RenderPass/LightCullingPass.h index 08cc886..a8c80fd 100644 --- a/src/Engine/Graphics/RenderPass/LightCullingPass.h +++ b/src/Engine/Graphics/RenderPass/LightCullingPass.h @@ -1,6 +1,6 @@ #pragma once #include "RenderPass.h" -#include "Graphics/GraphicsResources.h" +#include "Graphics/Resources.h" #include "Scene/Scene.h" namespace Seele @@ -8,14 +8,10 @@ namespace Seele DECLARE_REF(CameraActor) DECLARE_REF(Scene) DECLARE_REF(Viewport) -struct LightCullingPassData -{ - LightEnv lightEnv; -}; class LightCullingPass : public RenderPass { public: - LightCullingPass(Gfx::PGraphics graphics); + LightCullingPass(Gfx::PGraphics graphics, PScene scene); virtual ~LightCullingPass(); virtual void beginFrame(const Component::Camera& cam) override; virtual void render() override; diff --git a/src/Engine/Graphics/RenderPass/RenderGraphResources.h b/src/Engine/Graphics/RenderPass/RenderGraphResources.h index 2f729c2..c447444 100644 --- a/src/Engine/Graphics/RenderPass/RenderGraphResources.h +++ b/src/Engine/Graphics/RenderPass/RenderGraphResources.h @@ -1,6 +1,8 @@ #pragma once #include "MinimalEngine.h" -#include "Graphics/GraphicsResources.h" +#include "Graphics/RenderTarget.h" +#include "Graphics/Texture.h" +#include "Graphics/Buffer.h" namespace Seele { diff --git a/src/Engine/Graphics/RenderPass/RenderPass.h b/src/Engine/Graphics/RenderPass/RenderPass.h index 631ff49..663fa13 100644 --- a/src/Engine/Graphics/RenderPass/RenderPass.h +++ b/src/Engine/Graphics/RenderPass/RenderPass.h @@ -3,7 +3,6 @@ #include "Math/Math.h" #include "RenderGraphResources.h" #include "Component/Camera.h" -#include "Graphics/TopologyData.h" #include "Scene/Scene.h" #include "Material/MaterialInstance.h" #include "Graphics/VertexData.h" @@ -42,19 +41,6 @@ protected: Vector2 screenDimensions; Vector2 pad0; } viewParams; - struct DrawListId - { - DrawListId(PMaterialInstance mat, PVertexData vertex) - { - id = mat->getBaseMaterial()->getName(); - } - std::strong_ordering operator<=>(const DrawListId& other) const - { - return id <=> other.id; - } - std::string id; - }; - Map drawList; PRenderGraphResources resources; Gfx::PRenderPass renderPass; Gfx::PGraphics graphics; diff --git a/src/Engine/Graphics/RenderPass/SkyboxRenderPass.cpp b/src/Engine/Graphics/RenderPass/SkyboxRenderPass.cpp index ee8e587..68a8b9f 100644 --- a/src/Engine/Graphics/RenderPass/SkyboxRenderPass.cpp +++ b/src/Engine/Graphics/RenderPass/SkyboxRenderPass.cpp @@ -1,11 +1,18 @@ #include "SkyboxRenderPass.h" #include "Graphics/Graphics.h" +#include "Asset/AssetRegistry.h" using namespace Seele; -SkyboxRenderPass::SkyboxRenderPass(Gfx::PGraphics graphics) - : RenderPass(graphics) +SkyboxRenderPass::SkyboxRenderPass(Gfx::PGraphics graphics, PScene scene) + : RenderPass(graphics, scene) { + skybox = Seele::Component::Skybox{ + .day = AssetRegistry::findTexture("FS000_Day_01")->getTexture().cast(), + .night = AssetRegistry::findTexture("FS000_Night_01")->getTexture().cast(), + .fogColor = Vector(0.2, 0.1, 0.6), + .blendFactor = 0, + }; Array vertices = { // Back Vector(-512, -512, 512), @@ -91,8 +98,8 @@ void SkyboxRenderPass::beginFrame(const Component::Camera& cam) descriptorLayout->reset(); descriptorSet = descriptorLayout->allocateDescriptorSet(); descriptorSet->updateBuffer(0, viewParamsBuffer); - descriptorSet->updateTexture(1, passData.skybox.day); - descriptorSet->updateTexture(2, passData.skybox.night); + descriptorSet->updateTexture(1, skybox.day); + descriptorSet->updateTexture(2, skybox.night); descriptorSet->updateSampler(3, skyboxSampler); descriptorSet->writeChanges(); } @@ -104,9 +111,9 @@ void SkyboxRenderPass::render() renderCommand->setViewport(viewport); renderCommand->bindPipeline(pipeline); renderCommand->bindDescriptor(descriptorSet); - renderCommand->bindVertexBuffer({ VertexInputStream(0, 0, cubeBuffer) }); - renderCommand->pushConstants(pipelineLayout, Gfx::SE_SHADER_STAGE_FRAGMENT_BIT, 0, sizeof(Vector), &passData.skybox.fogColor); - renderCommand->pushConstants(pipelineLayout, Gfx::SE_SHADER_STAGE_FRAGMENT_BIT, sizeof(Vector), sizeof(float), &passData.skybox.blendFactor); + renderCommand->bindVertexBuffer({ cubeBuffer }); + renderCommand->pushConstants(pipelineLayout, Gfx::SE_SHADER_STAGE_FRAGMENT_BIT, 0, sizeof(Vector), &skybox.fogColor); + renderCommand->pushConstants(pipelineLayout, Gfx::SE_SHADER_STAGE_FRAGMENT_BIT, sizeof(Vector), sizeof(float), &skybox.blendFactor); renderCommand->draw(36, 1, 0, 0); graphics->executeCommands(Array{ renderCommand }); graphics->endRenderPass(); @@ -170,15 +177,15 @@ void SkyboxRenderPass::createRenderPass() Gfx::PVertexDeclaration vertexDecl = graphics->createVertexDeclaration({ Gfx::VertexElement { - .streamIndex = 0, + .binding = 0, .offset = 0, .vertexFormat = Gfx::SE_FORMAT_R32G32B32_SFLOAT, .attributeIndex = 0, .stride = sizeof(Vector), } - }); + }); - GraphicsPipelineCreateInfo gfxInfo; + Gfx::LegacyPipelineCreateInfo gfxInfo; gfxInfo.vertexDeclaration = vertexDecl; gfxInfo.vertexShader = vertexShader; gfxInfo.fragmentShader = fragmentShader; diff --git a/src/Engine/Graphics/RenderPass/SkyboxRenderPass.h b/src/Engine/Graphics/RenderPass/SkyboxRenderPass.h index bbb7e43..c83c2da 100644 --- a/src/Engine/Graphics/RenderPass/SkyboxRenderPass.h +++ b/src/Engine/Graphics/RenderPass/SkyboxRenderPass.h @@ -1,6 +1,6 @@ #pragma once #include "RenderPass.h" -#include "Graphics/GraphicsResources.h" +#include "Graphics/Resources.h" #include "Component/Skybox.h" namespace Seele @@ -11,7 +11,7 @@ DECLARE_REF(Viewport) class SkyboxRenderPass : public RenderPass { public: - SkyboxRenderPass(Gfx::PGraphics graphics); + SkyboxRenderPass(Gfx::PGraphics graphics, PScene scene); virtual ~SkyboxRenderPass(); virtual void beginFrame(const Component::Camera& cam) override; virtual void render() override; @@ -26,6 +26,7 @@ private: Gfx::PPipelineLayout pipelineLayout; Gfx::PGraphicsPipeline pipeline; Gfx::PSamplerState skyboxSampler; + Component::Skybox skybox; }; DEFINE_REF(SkyboxRenderPass) } // namespace Seele diff --git a/src/Engine/Graphics/RenderPass/TextPass.cpp b/src/Engine/Graphics/RenderPass/TextPass.cpp index ff59698..47322f2 100644 --- a/src/Engine/Graphics/RenderPass/TextPass.cpp +++ b/src/Engine/Graphics/RenderPass/TextPass.cpp @@ -1,12 +1,12 @@ #include "TextPass.h" #include "RenderGraph.h" #include "Graphics/Graphics.h" -#include "Graphics/VertexShaderInput.h" +#include "Graphics/RenderTarget.h" using namespace Seele; -TextPass::TextPass(Gfx::PGraphics graphics) - : RenderPass(graphics) +TextPass::TextPass(Gfx::PGraphics graphics, PScene scene) + : RenderPass(graphics, scene) { } @@ -17,7 +17,7 @@ TextPass::~TextPass() void TextPass::beginFrame(const Component::Camera&) { - for(TextRender& render : passData.texts) + for(TextRender& render : texts) { FontData& fd = getFontData(render.font); TextResources& res = textResources[render.font].add(); @@ -82,7 +82,7 @@ void TextPass::render() for(const auto& resource : res) { command->bindDescriptor({generalSet, resource.textureArraySet}); - command->bindVertexBuffer({VertexInputStream(0, 0, resource.vertexBuffer)}); + command->bindVertexBuffer({resource.vertexBuffer}); command->pushConstants(pipelineLayout, Gfx::SE_SHADER_STAGE_VERTEX_BIT | Gfx::SE_SHADER_STAGE_FRAGMENT_BIT, 0, sizeof(TextData), &resource.textData); command->draw(4, static_cast(resource.vertexBuffer->getNumVertices()), 0, 0); @@ -121,7 +121,7 @@ void TextPass::createRenderPass() fragmentShader = graphics->createFragmentShader(createInfo); Array elements; elements.add({ - .streamIndex = 0, + .binding = 0, .offset = offsetof(GlyphInstanceData, position), .vertexFormat = Gfx::SE_FORMAT_R32G32_SFLOAT, .attributeIndex = 0, @@ -129,7 +129,7 @@ void TextPass::createRenderPass() .bInstanced = 1 }); elements.add({ - .streamIndex = 0, + .binding = 0, .offset = offsetof(GlyphInstanceData, widthHeight), .vertexFormat = Gfx::SE_FORMAT_R32G32_SFLOAT, .attributeIndex = 1, @@ -137,7 +137,7 @@ void TextPass::createRenderPass() .bInstanced = 1 }); elements.add({ - .streamIndex = 0, + .binding = 0, .offset = offsetof(GlyphInstanceData, glyphIndex), .vertexFormat = Gfx::SE_FORMAT_R32_UINT, .attributeIndex = 2, @@ -187,7 +187,7 @@ void TextPass::createRenderPass() Gfx::PRenderTargetLayout layout = new Gfx::RenderTargetLayout(renderTarget, depthAttachment); renderPass = graphics->createRenderPass(layout, viewport); - GraphicsPipelineCreateInfo pipelineInfo; + Gfx::LegacyPipelineCreateInfo pipelineInfo; pipelineInfo.vertexDeclaration = declaration; pipelineInfo.vertexShader = vertexShader; pipelineInfo.fragmentShader = fragmentShader; diff --git a/src/Engine/Graphics/RenderPass/TextPass.h b/src/Engine/Graphics/RenderPass/TextPass.h index aff3bda..d3ca9c1 100644 --- a/src/Engine/Graphics/RenderPass/TextPass.h +++ b/src/Engine/Graphics/RenderPass/TextPass.h @@ -1,7 +1,7 @@ #pragma once #include "RenderPass.h" #include "UI/RenderHierarchy.h" -#include "Graphics/GraphicsResources.h" +#include "Graphics/Resources.h" #include "Asset/FontAsset.h" namespace Seele @@ -20,7 +20,7 @@ struct TextRender class TextPass : public RenderPass { public: - TextPass(Gfx::PGraphics graphics); + TextPass(Gfx::PGraphics graphics, PScene scene); virtual ~TextPass(); virtual void beginFrame(const Component::Camera& cam) override; virtual void render() override; @@ -60,7 +60,7 @@ private: Gfx::PDescriptorSet textureArraySet; TextData textData; }; - std::map> textResources; + Map> textResources; Gfx::PRenderTargetAttachment renderTarget; Gfx::PRenderTargetAttachment depthAttachment; @@ -78,6 +78,7 @@ private: Gfx::PFragmentShader fragmentShader; Gfx::PPipelineLayout pipelineLayout; Gfx::PGraphicsPipeline pipeline; + Array texts; }; DEFINE_REF(TextPass); } // namespace Seele diff --git a/src/Engine/Graphics/RenderPass/UIPass.cpp b/src/Engine/Graphics/RenderPass/UIPass.cpp index 18ae0ac..edb294a 100644 --- a/src/Engine/Graphics/RenderPass/UIPass.cpp +++ b/src/Engine/Graphics/RenderPass/UIPass.cpp @@ -1,11 +1,12 @@ #include "UIPass.h" #include "RenderGraph.h" #include "Graphics/Graphics.h" +#include "Graphics/RenderTarget.h" using namespace Seele; -UIPass::UIPass(Gfx::PGraphics graphics) - : RenderPass(graphics) +UIPass::UIPass(Gfx::PGraphics graphics, PScene scene) + : RenderPass(graphics, scene) { } @@ -18,20 +19,20 @@ void UIPass::beginFrame(const Component::Camera&) { VertexBufferCreateInfo info = { .resourceData = { - .size = (uint32)(sizeof(UI::RenderElementStyle) * passData.renderElements.size()), - .data = (uint8*)passData.renderElements.data() + .size = (uint32)(sizeof(UI::RenderElementStyle) * renderElements.size()), + .data = (uint8*)renderElements.data() }, .vertexSize = sizeof(UI::RenderElementStyle), - .numVertices = (uint32)passData.renderElements.size(), + .numVertices = (uint32)renderElements.size(), }; elementBuffer = graphics->createVertexBuffer(info); - uint32 numTextures = static_cast(passData.usedTextures.size()); + uint32 numTextures = static_cast(usedTextures.size()); numTexturesBuffer->updateContents({ .size = sizeof(uint32), .data = (uint8*)&numTextures, }); descriptorSet->updateBuffer(2, numTexturesBuffer); - descriptorSet->updateTextureArray(3, passData.usedTextures); + descriptorSet->updateTextureArray(3, usedTextures); descriptorSet->writeChanges(); //co_return; } @@ -42,11 +43,12 @@ void UIPass::render() Gfx::PRenderCommand command = graphics->createRenderCommand("UIPassCommand"); command->setViewport(viewport); command->bindPipeline(pipeline); - command->bindVertexBuffer({VertexInputStream(0, 0, elementBuffer)}); + command->bindVertexBuffer({elementBuffer}); command->bindDescriptor(descriptorSet); - command->draw(4, static_cast(passData.renderElements.size()), 0, 0); + command->draw(4, static_cast(renderElements.size()), 0, 0); graphics->executeCommands(Array({command})); graphics->endRenderPass(); + //co_return; } @@ -96,7 +98,7 @@ void UIPass::createRenderPass() fragmentShader = graphics->createFragmentShader(createInfo); Array decl; decl.add({ - .streamIndex = 0, + .binding = 0, .offset = offsetof(UI::RenderElementStyle, position), .vertexFormat = Gfx::SE_FORMAT_R32G32B32_SFLOAT, .attributeIndex = 0, @@ -104,7 +106,7 @@ void UIPass::createRenderPass() .bInstanced = 1 }); decl.add({ - .streamIndex = 0, + .binding = 0, .offset = offsetof(UI::RenderElementStyle, backgroundImageIndex), .vertexFormat = Gfx::SE_FORMAT_R32_UINT, .attributeIndex = 1, @@ -112,7 +114,7 @@ void UIPass::createRenderPass() .bInstanced = 1 }); decl.add({ - .streamIndex = 0, + .binding = 0, .offset = offsetof(UI::RenderElementStyle, backgroundColor), .vertexFormat = Gfx::SE_FORMAT_R32G32B32_SFLOAT, .attributeIndex = 2, @@ -120,7 +122,7 @@ void UIPass::createRenderPass() .bInstanced = 1 }); decl.add({ - .streamIndex = 0, + .binding = 0, .offset = offsetof(UI::RenderElementStyle, opacity), .vertexFormat = Gfx::SE_FORMAT_R32_SFLOAT, .attributeIndex = 3, @@ -128,7 +130,7 @@ void UIPass::createRenderPass() .bInstanced = 1 }); decl.add({ - .streamIndex = 0, + .binding = 0, .offset = offsetof(UI::RenderElementStyle, dimensions), .vertexFormat = Gfx::SE_FORMAT_R32G32_SFLOAT, .attributeIndex = 4, @@ -177,7 +179,7 @@ void UIPass::createRenderPass() Gfx::PRenderTargetLayout layout = new Gfx::RenderTargetLayout(renderTarget, depthAttachment); renderPass = graphics->createRenderPass(layout, viewport); - GraphicsPipelineCreateInfo pipelineInfo; + Gfx::LegacyPipelineCreateInfo pipelineInfo; pipelineInfo.vertexDeclaration = declaration; pipelineInfo.vertexShader = vertexShader; pipelineInfo.fragmentShader = fragmentShader; diff --git a/src/Engine/Graphics/RenderPass/UIPass.h b/src/Engine/Graphics/RenderPass/UIPass.h index 7c6fc82..a3e595c 100644 --- a/src/Engine/Graphics/RenderPass/UIPass.h +++ b/src/Engine/Graphics/RenderPass/UIPass.h @@ -1,21 +1,16 @@ #pragma once #include "RenderPass.h" #include "UI/RenderHierarchy.h" -#include "Graphics/GraphicsResources.h" +#include "Graphics/Resources.h" namespace Seele { DECLARE_NAME_REF(Gfx, Texture2D) DECLARE_NAME_REF(Gfx, RenderTargetAttachment) -struct UIPassData -{ - Array renderElements; - Array usedTextures; -}; -class UIPass : public RenderPass +class UIPass : public RenderPass { public: - UIPass(Gfx::PGraphics graphics); + UIPass(Gfx::PGraphics graphics, PScene scene); virtual ~UIPass(); virtual void beginFrame(const Component::Camera& cam) override; virtual void render() override; @@ -39,6 +34,9 @@ private: Gfx::PFragmentShader fragmentShader; Gfx::PPipelineLayout pipelineLayout; Gfx::PGraphicsPipeline pipeline; + + Array renderElements; + Array usedTextures; }; DEFINE_REF(UIPass); } // namespace Seele diff --git a/src/Engine/Graphics/RenderTarget.cpp b/src/Engine/Graphics/RenderTarget.cpp new file mode 100644 index 0000000..9f246d9 --- /dev/null +++ b/src/Engine/Graphics/RenderTarget.cpp @@ -0,0 +1,81 @@ +#include "RenderTarget.h" + +using namespace Seele; +using namespace Seele::Gfx; + + +RenderTargetLayout::RenderTargetLayout() + : inputAttachments() + , colorAttachments() + , depthAttachment() +{ +} + +RenderTargetLayout::RenderTargetLayout(PRenderTargetAttachment depthAttachment) + : inputAttachments() + , colorAttachments() + , depthAttachment(depthAttachment) + , width(depthAttachment->getTexture()->getSizeX()) + , height(depthAttachment->getTexture()->getSizeY()) +{ +} + +RenderTargetLayout::RenderTargetLayout(PRenderTargetAttachment colorAttachment, PRenderTargetAttachment depthAttachment) + : inputAttachments() + , depthAttachment(depthAttachment) + , width(depthAttachment->getTexture()->getSizeX()) + , height(depthAttachment->getTexture()->getSizeY()) +{ + colorAttachments.add(colorAttachment); +} +RenderTargetLayout::RenderTargetLayout(Array colorAttachments, PRenderTargetAttachment depthAttachment) + : inputAttachments() + , colorAttachments(colorAttachments) + , depthAttachment(depthAttachment) + , width(depthAttachment->getTexture()->getSizeX()) + , height(depthAttachment->getTexture()->getSizeY()) +{ +} +RenderTargetLayout::RenderTargetLayout(Array inputAttachments, Array colorAttachments, PRenderTargetAttachment depthAttachment) + : inputAttachments(inputAttachments) + , colorAttachments(colorAttachments) + , depthAttachment(depthAttachment) + , width(depthAttachment->getTexture()->getSizeX()) + , height(depthAttachment->getTexture()->getSizeY()) +{ +} + +Window::Window(const WindowCreateInfo& createInfo) + : windowState(createInfo) +{ +} + +Window::~Window() +{ +} + +Viewport::Viewport(PWindow owner, const ViewportCreateInfo& viewportInfo) + : sizeX(viewportInfo.dimensions.size.x) + , sizeY(viewportInfo.dimensions.size.y) + , offsetX(viewportInfo.dimensions.offset.x) + , offsetY(viewportInfo.dimensions.offset.y) + , fieldOfView(viewportInfo.fieldOfView) + , owner(owner) +{ +} + +Viewport::~Viewport() +{ +} + +Matrix4 Viewport::getProjectionMatrix() const +{ + if (fieldOfView > 0.0f) + { + return glm::perspective(fieldOfView, sizeX / static_cast(sizeY), 0.1f, 1000.0f); + } + else + { + return glm::ortho(0.0f, (float)sizeX, (float)sizeY, 0.0f); + } +} diff --git a/src/Engine/Graphics/RenderTarget.h b/src/Engine/Graphics/RenderTarget.h new file mode 100644 index 0000000..14bd78d --- /dev/null +++ b/src/Engine/Graphics/RenderTarget.h @@ -0,0 +1,194 @@ +#pragma once +#include "Resources.h" +#include "Texture.h" + +namespace Seele +{ +namespace Gfx +{ + +class Window +{ +public: + Window(const WindowCreateInfo &createInfo); + virtual ~Window(); + virtual void beginFrame() = 0; + virtual void endFrame() = 0; + virtual void onWindowCloseEvent() = 0; + virtual PTexture2D getBackBuffer() const = 0; + virtual void setKeyCallback(std::function callback) = 0; + virtual void setMouseMoveCallback(std::function callback) = 0; + virtual void setMouseButtonCallback(std::function callback) = 0; + virtual void setScrollCallback(std::function callback) = 0; + virtual void setFileCallback(std::function callback) = 0; + virtual void setCloseCallback(std::function callback) = 0; + SeFormat getSwapchainFormat() const + { + return windowState.pixelFormat; + } + SeSampleCountFlags getNumSamples() const + { + return windowState.numSamples; + } + uint32 getSizeX() const + { + return windowState.width; + } + uint32 getSizeY() const + { + return windowState.height; + } + +protected: + WindowCreateInfo windowState; +}; +DEFINE_REF(Window) + +class Viewport +{ +public: + Viewport(PWindow owner, const ViewportCreateInfo &createInfo); + virtual ~Viewport(); + virtual void resize(uint32 newX, uint32 newY) = 0; + virtual void move(uint32 newOffsetX, uint32 newOffsetY) = 0; + constexpr PWindow getOwner() const {return owner;} + constexpr uint32 getSizeX() const {return sizeX;} + constexpr uint32 getSizeY() const {return sizeY;} + constexpr uint32 getOffsetX() const {return offsetX;} + constexpr uint32 getOffsetY() const {return offsetY;} + Matrix4 getProjectionMatrix() const; +protected: + uint32 sizeX; + uint32 sizeY; + uint32 offsetX; + uint32 offsetY; + float fieldOfView; + PWindow owner; +}; +DEFINE_REF(Viewport) + +class RenderTargetAttachment +{ +public: + RenderTargetAttachment(PTexture2D texture, + SeAttachmentLoadOp loadOp = SE_ATTACHMENT_LOAD_OP_LOAD, + SeAttachmentStoreOp storeOp = SE_ATTACHMENT_STORE_OP_STORE, + SeAttachmentLoadOp stencilLoadOp = SE_ATTACHMENT_LOAD_OP_DONT_CARE, + SeAttachmentStoreOp stencilStoreOp = SE_ATTACHMENT_STORE_OP_DONT_CARE) + : loadOp(loadOp) + , storeOp(storeOp) + , stencilLoadOp(stencilLoadOp) + , stencilStoreOp(stencilStoreOp) + , texture(texture) + , clear() + , componentFlags(0) + { + } + virtual ~RenderTargetAttachment() + { + } + virtual PTexture2D getTexture() + { + return texture; + } + virtual SeFormat getFormat() const + { + return texture->getFormat(); + } + virtual SeSampleCountFlags getNumSamples() const + { + return texture->getNumSamples(); + } + virtual uint32 getSizeX() const + { + return texture->getSizeX(); + } + virtual uint32 getSizeY() const + { + return texture->getSizeY(); + } + inline SeAttachmentLoadOp getLoadOp() const { return loadOp; } + inline SeAttachmentStoreOp getStoreOp() const { return storeOp; } + inline SeAttachmentLoadOp getStencilLoadOp() const { return stencilLoadOp; } + inline SeAttachmentStoreOp getStencilStoreOp() const { return stencilStoreOp; } + SeClearValue clear; + SeColorComponentFlags componentFlags; + SeAttachmentLoadOp loadOp; + SeAttachmentStoreOp storeOp; + SeAttachmentLoadOp stencilLoadOp; + SeAttachmentStoreOp stencilStoreOp; +protected: + PTexture2D texture; +}; +DEFINE_REF(RenderTargetAttachment) + +class SwapchainAttachment : public RenderTargetAttachment +{ +public: + SwapchainAttachment(PWindow owner, + SeAttachmentLoadOp loadOp = SE_ATTACHMENT_LOAD_OP_LOAD, + SeAttachmentStoreOp storeOp = SE_ATTACHMENT_STORE_OP_STORE, + SeAttachmentLoadOp stencilLoadOp = SE_ATTACHMENT_LOAD_OP_DONT_CARE, + SeAttachmentStoreOp stencilStoreOp = SE_ATTACHMENT_STORE_OP_DONT_CARE) + : RenderTargetAttachment(nullptr, loadOp, storeOp, stencilLoadOp, stencilStoreOp), owner(owner) + { + clear.color.float32[0] = 0.0f; + clear.color.float32[1] = 0.0f; + clear.color.float32[2] = 0.0f; + clear.color.float32[3] = 1.0f; + componentFlags = SE_COLOR_COMPONENT_R_BIT | SE_COLOR_COMPONENT_G_BIT | SE_COLOR_COMPONENT_B_BIT | SE_COLOR_COMPONENT_A_BIT; + } + virtual PTexture2D getTexture() override + { + return owner->getBackBuffer(); + } + virtual SeFormat getFormat() const override + { + return owner->getSwapchainFormat(); + } + virtual SeSampleCountFlags getNumSamples() const override + { + return owner->getNumSamples(); + } + virtual uint32 getSizeX() const + { + return owner->getSizeX(); + } + virtual uint32 getSizeY() const + { + return owner->getSizeY(); + } +private: + PWindow owner; +}; +DEFINE_REF(SwapchainAttachment) + +class RenderTargetLayout +{ +public: + RenderTargetLayout(); + 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; +}; +DEFINE_REF(RenderTargetLayout) + +class RenderPass +{ +public: + RenderPass(PRenderTargetLayout layout) : layout(layout) {} + virtual ~RenderPass() {} + inline PRenderTargetLayout getLayout() const { return layout; } + +protected: + PRenderTargetLayout layout; +}; +DEFINE_REF(RenderPass) +} +} \ No newline at end of file diff --git a/src/Engine/Graphics/Resources.cpp b/src/Engine/Graphics/Resources.cpp new file mode 100644 index 0000000..9009cf2 --- /dev/null +++ b/src/Engine/Graphics/Resources.cpp @@ -0,0 +1,77 @@ +#include "GraphicsResources.h" +#include "Graphics.h" +#include "RenderPass/DepthPrepass.h" +#include "RenderPass/BasePass.h" +#include "Material/Material.h" + +QueueOwnedResource::QueueOwnedResource(QueueFamilyMapping mapping, QueueType startQueueType) + : currentOwner(startQueueType) + , mapping(mapping) +{ +} + +QueueOwnedResource::~QueueOwnedResource() +{ +} + +void QueueOwnedResource::transferOwnership(QueueType newOwner) +{ + if(mapping.needsTransfer(currentOwner, newOwner)) + { + executeOwnershipBarrier(newOwner); + } + currentOwner = newOwner; +} + +void QueueOwnedResource::pipelineBarrier(SeAccessFlags srcAccess, SePipelineStageFlags srcStage, SeAccessFlags dstAccess, SePipelineStageFlags dstStage) +{ + // maybe add some checks + executePipelineBarrier(srcAccess, srcStage, dstAccess, dstStage); +} + + +VertexDeclaration::VertexDeclaration() +{ +} +VertexDeclaration::~VertexDeclaration() +{ +} + +static std::mutex vertexDeclarationLock; +static Map vertexDeclarationCache; + +PVertexDeclaration VertexDeclaration::createDeclaration(PGraphics graphics, const Array& elementList) +{ + std::scoped_lock lock(vertexDeclarationLock); + uint32 key = CRC::Calculate(&elementList, sizeof(VertexElement) * elementList.size(), CRC::CRC_32()); + + auto found = vertexDeclarationCache[key]; + if(found == nullptr) + { + return found; + } + + PVertexDeclaration newDeclaration = graphics->createVertexDeclaration(elementList); + + vertexDeclarationCache[key] = newDeclaration; + return newDeclaration; +} + +RenderCommand::RenderCommand() +{ +} + +RenderCommand::~RenderCommand() +{ +} + +ComputeCommand::ComputeCommand() +{ + +} + +ComputeCommand::~ComputeCommand() +{ + +} + diff --git a/src/Engine/Graphics/Resources.h b/src/Engine/Graphics/Resources.h new file mode 100644 index 0000000..9260568 --- /dev/null +++ b/src/Engine/Graphics/Resources.h @@ -0,0 +1,150 @@ +#pragma once +#include "Math/Math.h" +#include "Enums.h" +#include "Containers/Array.h" +#include "Containers/List.h" +#include "Initializer.h" +#include "Buffer.h" +#include "CRC.h" +#include + + +#ifndef ENABLE_VALIDATION +#define ENABLE_VALIDATION 0 +#endif + +namespace Seele +{ +DECLARE_REF(Material) +namespace Gfx +{ +DECLARE_REF(DescriptorSet) +DECLARE_REF(Graphics) +DECLARE_REF(VertexBuffer) +DECLARE_REF(IndexBuffer) +class SamplerState +{ +public: + virtual ~SamplerState() + { + } +}; +DEFINE_REF(SamplerState) + +struct QueueFamilyMapping +{ + uint32 graphicsFamily; + uint32 computeFamily; + uint32 transferFamily; + uint32 dedicatedTransferFamily; + uint32 getQueueTypeFamilyIndex(Gfx::QueueType type) const + { + switch (type) + { + case Gfx::QueueType::GRAPHICS: + return graphicsFamily; + case Gfx::QueueType::COMPUTE: + return computeFamily; + case Gfx::QueueType::TRANSFER: + return transferFamily; + case Gfx::QueueType::DEDICATED_TRANSFER: + return dedicatedTransferFamily; + default: + return 0x7fff; + } + } + bool needsTransfer(Gfx::QueueType src, Gfx::QueueType dst) const + { + uint32 srcIndex = getQueueTypeFamilyIndex(src); + uint32 dstIndex = getQueueTypeFamilyIndex(dst); + return srcIndex != dstIndex; + } +}; + +class QueueOwnedResource +{ +public: + QueueOwnedResource(QueueFamilyMapping mapping, QueueType startQueueType); + virtual ~QueueOwnedResource(); + + //Preliminary checks to see if the barrier should be executed at all + void transferOwnership(QueueType newOwner); + void pipelineBarrier(SeAccessFlags srcAccess, SePipelineStageFlags srcStage, SeAccessFlags dstAccess, SePipelineStageFlags dstStage); + +protected: + virtual void executeOwnershipBarrier(QueueType newOwner) = 0; + virtual void executePipelineBarrier(SeAccessFlags srcAccess, SePipelineStageFlags srcStage, + SeAccessFlags dstAccess, SePipelineStageFlags dstStage) = 0; + Gfx::QueueType currentOwner; + QueueFamilyMapping mapping; +}; +DEFINE_REF(QueueOwnedResource) + +class VertexDeclaration +{ +public: + VertexDeclaration(); + ~VertexDeclaration(); + + static PVertexDeclaration createDeclaration(PGraphics graphics, const Array& elementList); +private: +}; +DEFINE_REF(VertexDeclaration) +class GraphicsPipeline +{ +public: + GraphicsPipeline(PPipelineLayout layout) : layout(layout) {} + virtual ~GraphicsPipeline(){} + PPipelineLayout getPipelineLayout() const { return layout; } +protected: + PPipelineLayout layout; +}; +DEFINE_REF(GraphicsPipeline) + +class ComputePipeline +{ +public: + ComputePipeline(PPipelineLayout layout) : layout(layout) {} + virtual ~ComputePipeline(){} + PPipelineLayout getPipelineLayout() const { return layout; } +protected: + PPipelineLayout layout; +}; +DEFINE_REF(ComputePipeline) + +DECLARE_REF(Viewport) +class RenderCommand +{ +public: + RenderCommand(); + virtual ~RenderCommand(); + virtual bool isReady() = 0; + virtual void setViewport(Gfx::PViewport viewport) = 0; + virtual void bindPipeline(Gfx::PGraphicsPipeline pipeline) = 0; + virtual void bindDescriptor(Gfx::PDescriptorSet set) = 0; + virtual void bindDescriptor(const Array& sets) = 0; + virtual void bindVertexBuffer(const Array& buffer) = 0; + 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); + std::string name; +}; +DEFINE_REF(RenderCommand) +class ComputeCommand +{ +public: + ComputeCommand(); + virtual ~ComputeCommand(); + virtual bool isReady() = 0; + virtual void bindPipeline(Gfx::PComputePipeline pipeline) = 0; + virtual void bindDescriptor(Gfx::PDescriptorSet set) = 0; + virtual void bindDescriptor(const Array& sets) = 0; + virtual void pushConstants(Gfx::PPipelineLayout layout, Gfx::SeShaderStageFlags stage, uint32 offset, uint32 size, const void* data) = 0; + virtual void dispatch(uint32 threadX, uint32 threadY, uint32 threadZ) = 0; + std::string name; +}; +DEFINE_REF(ComputeCommand) + +} // namespace Gfx +} // namespace Seele \ No newline at end of file diff --git a/src/Engine/Graphics/Shader.cpp b/src/Engine/Graphics/Shader.cpp new file mode 100644 index 0000000..948b957 --- /dev/null +++ b/src/Engine/Graphics/Shader.cpp @@ -0,0 +1,92 @@ +#include "Shader.h" + +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() +{ +} + +ShaderMap::~ShaderMap() +{ +} + +const ShaderCollection* ShaderMap::findShaders(PermutationId&& id) const +{ + for (uint32 i = 0; i < shaders.size(); ++i) + { + if (shaders[i].id == id) + { + return &(shaders[i]); + } + } + return nullptr; +} +ShaderCollection& ShaderMap::createShaders( + PGraphics graphics, + RenderPassType renderPass, + PMaterial material, + VertexInputType* vertexInput, + bool /*bPositionOnly*/) +{ + std::scoped_lock lock(shadersLock); + ShaderCollection& collection = shaders.add(); + //collection.vertexDeclaration = bPositionOnly ? vertexInput->getPositionDeclaration() : vertexInput->getDeclaration(); + + 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(); + + 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) + { + 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); + + return collection; +} \ No newline at end of file diff --git a/src/Engine/Graphics/Shader.h b/src/Engine/Graphics/Shader.h new file mode 100644 index 0000000..bddd1a0 --- /dev/null +++ b/src/Engine/Graphics/Shader.h @@ -0,0 +1,108 @@ +#pragma once +#include "Enums.h" + +namespace Seele +{ +namespace Gfx +{ + +class Shader +{}; +DEFINE_REF(Shader) +class TaskShader +{ +public: + TaskShader() {} + virtual ~TaskShader() {} +}; +DEFINE_REF(TaskShader) +class MeshShader +{ +public: + MeshShader() {} + virtual ~MeshShader() {} +}; +DEFINE_REF(MeshShader) +class VertexShader +{ +public: + VertexShader() {} + virtual ~VertexShader() {} +}; +DEFINE_REF(VertexShader) +class FragmentShader +{ +public: + FragmentShader() {} + virtual ~FragmentShader() {} +}; +DEFINE_REF(FragmentShader) + +class ComputeShader +{ +public: + ComputeShader() {} + virtual ~ComputeShader() {} +}; +DEFINE_REF(ComputeShader) + + //Uniquely identifies a permutation of shaders + //using the type parameters used to generate it +struct ShaderPermutation +{ + RenderPassType passType; + char vertexInputName[15]; + char materialName[16]; + //TODO: lightmapping etc +}; +//Hashed ShaderPermutation for fast lookup +struct PermutationId +{ + uint32 hash; + PermutationId() + : hash(0) + {} + PermutationId(ShaderPermutation permutation) + : hash(CRC::Calculate(&permutation, sizeof(ShaderPermutation), CRC::CRC_32())) + {} + 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; + } + 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; + } +}; +struct ShaderCollection +{ + PermutationId id; + //PVertexDeclaration vertexDeclaration; + PVertexShader vertexShader; + PFragmentShader fragmentShader; +}; +class ShaderMap +{ +public: + ShaderMap(); + ~ShaderMap(); + const ShaderCollection* findShaders(PermutationId&& id) const; + ShaderCollection& createShaders( + PGraphics graphics, + RenderPassType passName, + bool bPositionOnly); +private: + std::mutex shadersLock; + Array shaders; +}; +DEFINE_REF(ShaderMap) +} +} // namespace Seele \ No newline at end of file diff --git a/src/Engine/Graphics/ShaderCompiler.cpp b/src/Engine/Graphics/ShaderCompiler.cpp index 008bba6..a32e1e3 100644 --- a/src/Engine/Graphics/ShaderCompiler.cpp +++ b/src/Engine/Graphics/ShaderCompiler.cpp @@ -1,5 +1,4 @@ #include "ShaderCompiler.h" -#include "VertexShaderInput.h" #include "Graphics.h" using namespace Seele; diff --git a/src/Engine/Graphics/ShaderCompiler.h b/src/Engine/Graphics/ShaderCompiler.h index 02ada7c..1b3fe08 100644 --- a/src/Engine/Graphics/ShaderCompiler.h +++ b/src/Engine/Graphics/ShaderCompiler.h @@ -1,6 +1,5 @@ #pragma once #include "Material/Material.h" -#include "GraphicsResources.h" namespace Seele { diff --git a/src/Engine/Graphics/StaticMeshVertexData.cpp b/src/Engine/Graphics/StaticMeshVertexData.cpp index 7dd6d11..a9b19c9 100644 --- a/src/Engine/Graphics/StaticMeshVertexData.cpp +++ b/src/Engine/Graphics/StaticMeshVertexData.cpp @@ -2,8 +2,13 @@ using namespace Seele; -StaticMeshVertexData::StaticMeshVertexData() -{} +extern List vertexDataList; + +StaticMeshVertexData::StaticMeshVertexData(Gfx::PGraphics graphics) + : VertexData(graphics) +{ + vertexDataList.add(this); +} StaticMeshVertexData::~StaticMeshVertexData() {} diff --git a/src/Engine/Graphics/StaticMeshVertexData.h b/src/Engine/Graphics/StaticMeshVertexData.h index dee4fc4..80ffe1b 100644 --- a/src/Engine/Graphics/StaticMeshVertexData.h +++ b/src/Engine/Graphics/StaticMeshVertexData.h @@ -5,7 +5,7 @@ namespace Seele class StaticMeshVertexData : public VertexData { public: - StaticMeshVertexData(); + StaticMeshVertexData(Gfx::PGraphics graphics); virtual ~StaticMeshVertexData(); private: }; diff --git a/src/Engine/Graphics/Texture.cpp b/src/Engine/Graphics/Texture.cpp new file mode 100644 index 0000000..bbeebe3 --- /dev/null +++ b/src/Engine/Graphics/Texture.cpp @@ -0,0 +1,41 @@ +#include "Texture.h" + +using namespace Seele; +using namespace Seele::Gfx; + + +Texture::Texture(QueueFamilyMapping mapping, Gfx::QueueType startQueueType) + : QueueOwnedResource(mapping, startQueueType) +{ +} + +Texture::~Texture() +{ +} + +Texture2D::Texture2D(QueueFamilyMapping mapping, Gfx::QueueType startQueueType) + : Texture(mapping, startQueueType) +{ +} + +Texture2D::~Texture2D() +{ +} + +Texture3D::Texture3D(QueueFamilyMapping mapping, Gfx::QueueType startQueueType) + : Texture(mapping, startQueueType) +{ +} + +Texture3D::~Texture3D() +{ +} + +TextureCube::TextureCube(QueueFamilyMapping mapping, Gfx::QueueType startQueueType) + : Texture(mapping, startQueueType) +{ +} + +TextureCube::~TextureCube() +{ +} diff --git a/src/Engine/Graphics/Texture.h b/src/Engine/Graphics/Texture.h new file mode 100644 index 0000000..c1da3c6 --- /dev/null +++ b/src/Engine/Graphics/Texture.h @@ -0,0 +1,110 @@ +#pragma once +#include "Resources.h" + +namespace Seele +{ +namespace Gfx +{ + +// IMPORTANT!! +// WHEN DERIVING FROM ANY Gfx:: BASE CLASSES WITH MULTIPLE INHERITANCE +// ALWAYS PUT THE Gfx:: BASE CLASS FIRST +// This is because the refcounting object is unique per allocation, so +// the base address of both the Gfx:: and the implementation class +// need to match for it to work +class Texture : public QueueOwnedResource +{ +public: + Texture(QueueFamilyMapping mapping, QueueType startQueueType); + virtual ~Texture(); + + virtual SeFormat getFormat() const = 0; + virtual uint32 getSizeX() const = 0; + virtual uint32 getSizeY() const = 0; + virtual uint32 getSizeZ() const = 0; + virtual uint32 getNumFaces() const { return 1; } + virtual SeSampleCountFlags getNumSamples() const = 0; + virtual uint32 getMipLevels() const = 0; + virtual void changeLayout(SeImageLayout newLayout) = 0; + virtual class Texture2D* getTexture2D() { return nullptr; } + virtual class Texture3D* getTexture3D() { return nullptr; } + virtual class TextureCube* getTextureCube() { return nullptr; } + virtual void* getNativeHandle() { return nullptr; } + virtual void download(uint32 mipLevel, uint32 arrayLayer, uint32 face, Array& buffer) = 0; +protected: + // Inherited via QueueOwnedResource + virtual void executeOwnershipBarrier(QueueType newOwner) = 0; + virtual void executePipelineBarrier(SeAccessFlags srcAccess, SePipelineStageFlags srcStage, + SeAccessFlags dstAccess, SePipelineStageFlags dstStage) = 0; +}; +DEFINE_REF(Texture) + +class Texture2D : public Texture +{ +public: + Texture2D(QueueFamilyMapping mapping, QueueType startQueueType); + virtual ~Texture2D(); + + virtual SeFormat getFormat() const = 0; + virtual uint32 getSizeX() const = 0; + virtual uint32 getSizeY() const = 0; + virtual uint32 getSizeZ() const = 0; + virtual SeSampleCountFlags getNumSamples() const = 0; + virtual uint32 getMipLevels() const = 0; + virtual void changeLayout(SeImageLayout newLayout) = 0; + virtual class Texture2D* getTexture2D() { return this; } +protected: + //Inherited via QueueOwnedResource + virtual void executeOwnershipBarrier(QueueType newOwner) = 0; + virtual void executePipelineBarrier(SeAccessFlags srcAccess, SePipelineStageFlags srcStage, + SeAccessFlags dstAccess, SePipelineStageFlags dstStage) = 0; +}; +DEFINE_REF(Texture2D) + +class Texture3D : public Texture +{ +public: + Texture3D(QueueFamilyMapping mapping, QueueType startQueueType); + virtual ~Texture3D(); + + virtual SeFormat getFormat() const = 0; + virtual uint32 getSizeX() const = 0; + virtual uint32 getSizeY() const = 0; + virtual uint32 getSizeZ() const = 0; + virtual SeSampleCountFlags getNumSamples() const = 0; + virtual uint32 getMipLevels() const = 0; + virtual void changeLayout(SeImageLayout newLayout) = 0; + virtual class Texture3D* getTexture3D() { return this; } +protected: + //Inherited via QueueOwnedResource + virtual void executeOwnershipBarrier(QueueType newOwner) = 0; + virtual void executePipelineBarrier(SeAccessFlags srcAccess, SePipelineStageFlags srcStage, + SeAccessFlags dstAccess, SePipelineStageFlags dstStage) = 0; +}; +DEFINE_REF(Texture3D) + +class TextureCube : public Texture +{ +public: + TextureCube(QueueFamilyMapping mapping, QueueType startQueueType); + virtual ~TextureCube(); + + virtual SeFormat getFormat() const = 0; + virtual uint32 getSizeX() const = 0; + virtual uint32 getSizeY() const = 0; + virtual uint32 getSizeZ() const = 0; + virtual uint32 getNumFaces() const { return 6; } + virtual SeSampleCountFlags getNumSamples() const = 0; + virtual uint32 getMipLevels() const = 0; + virtual void changeLayout(SeImageLayout newLayout) = 0; + virtual class TextureCube* getTextureCube() { return this; } +protected: + //Inherited via QueueOwnedResource + virtual void executeOwnershipBarrier(QueueType newOwner) = 0; + virtual void executePipelineBarrier(SeAccessFlags srcAccess, SePipelineStageFlags srcStage, + SeAccessFlags dstAccess, SePipelineStageFlags dstStage) = 0; +}; +DEFINE_REF(TextureCube) + +} +} \ No newline at end of file diff --git a/src/Engine/Graphics/TopologyData.cpp b/src/Engine/Graphics/TopologyData.cpp deleted file mode 100644 index 4f0704d..0000000 --- a/src/Engine/Graphics/TopologyData.cpp +++ /dev/null @@ -1 +0,0 @@ -#include "TopologyData.h" \ No newline at end of file diff --git a/src/Engine/Graphics/TopologyData.h b/src/Engine/Graphics/TopologyData.h deleted file mode 100644 index 87e6ec6..0000000 --- a/src/Engine/Graphics/TopologyData.h +++ /dev/null @@ -1,17 +0,0 @@ -#pragma once -#include "GraphicsResources.h" -#include "VertexData.h" - -namespace Seele -{ -class TopologyData -{ -public: - TopologyData(); - virtual ~TopologyData(); - virtual void bind() = 0; -protected: - VertexData* vertexData; -}; -DEFINE_REF(TopologyData) -} // namespace Seele \ No newline at end of file diff --git a/src/Engine/Graphics/VertexData.cpp b/src/Engine/Graphics/VertexData.cpp index 0b194ee..89be4fd 100644 --- a/src/Engine/Graphics/VertexData.cpp +++ b/src/Engine/Graphics/VertexData.cpp @@ -1,6 +1,8 @@ #include "VertexData.h" #include "Material/Material.h" #include "Graphics/Graphics.h" +#include "Graphics/Descriptor.h" +#include "Component/Mesh.h" using namespace Seele; diff --git a/src/Engine/Graphics/VertexData.h b/src/Engine/Graphics/VertexData.h index 95dd72d..5478da4 100644 --- a/src/Engine/Graphics/VertexData.h +++ b/src/Engine/Graphics/VertexData.h @@ -1,11 +1,17 @@ #pragma once -#include "GraphicsResources.h" #include "Material/MaterialInstance.h" -#include "Component/Mesh.h" #include "Component/Transform.h" +#include "Containers/List.h" +#include "Graphics/Resources.h" +#include "Graphics/Descriptor.h" +#include "Graphics/Buffer.h" namespace Seele { +namespace Component +{ + struct Mesh; +} struct MeshId { uint64 id; diff --git a/src/Engine/Graphics/Vulkan/VulkanAllocator.cpp b/src/Engine/Graphics/Vulkan/Allocator.cpp similarity index 99% rename from src/Engine/Graphics/Vulkan/VulkanAllocator.cpp rename to src/Engine/Graphics/Vulkan/Allocator.cpp index bde1459..15155ff 100644 --- a/src/Engine/Graphics/Vulkan/VulkanAllocator.cpp +++ b/src/Engine/Graphics/Vulkan/Allocator.cpp @@ -1,6 +1,6 @@ -#include "VulkanAllocator.h" -#include "VulkanGraphics.h" -#include "VulkanInitializer.h" +#include "Allocator.h" +#include "Graphics.h" +#include "Initializer.h" using namespace Seele::Vulkan; diff --git a/src/Engine/Graphics/Vulkan/VulkanAllocator.h b/src/Engine/Graphics/Vulkan/Allocator.h similarity index 99% rename from src/Engine/Graphics/Vulkan/VulkanAllocator.h rename to src/Engine/Graphics/Vulkan/Allocator.h index 409b5c8..774d9e6 100644 --- a/src/Engine/Graphics/Vulkan/VulkanAllocator.h +++ b/src/Engine/Graphics/Vulkan/Allocator.h @@ -1,6 +1,6 @@ #pragma once #include "MinimalEngine.h" -#include "VulkanGraphicsEnums.h" +#include "Enums.h" #include "Containers/Map.h" #include "Containers/Array.h" #include diff --git a/src/Engine/Graphics/Vulkan/VulkanBuffer.cpp b/src/Engine/Graphics/Vulkan/Buffer.cpp similarity index 98% rename from src/Engine/Graphics/Vulkan/VulkanBuffer.cpp rename to src/Engine/Graphics/Vulkan/Buffer.cpp index 0e7ed34..2f3fb23 100644 --- a/src/Engine/Graphics/Vulkan/VulkanBuffer.cpp +++ b/src/Engine/Graphics/Vulkan/Buffer.cpp @@ -1,8 +1,4 @@ -#include "VulkanGraphicsResources.h" -#include "VulkanInitializer.h" -#include "VulkanGraphics.h" -#include "VulkanCommandBuffer.h" -#include "VulkanAllocator.h" +#include "Buffer.h" using namespace Seele; using namespace Seele::Vulkan; @@ -16,7 +12,7 @@ struct PendingBuffer bool bWriteOnly; }; -static std::map pendingBuffers; +static std::map pendingBuffers; ShaderBuffer::ShaderBuffer(PGraphics graphics, uint64 size, VkBufferUsageFlags usage, Gfx::QueueType& queueType, bool bDynamic) : graphics(graphics) diff --git a/src/Engine/Graphics/Vulkan/Buffer.h b/src/Engine/Graphics/Vulkan/Buffer.h new file mode 100644 index 0000000..135a1db --- /dev/null +++ b/src/Engine/Graphics/Vulkan/Buffer.h @@ -0,0 +1,145 @@ +#pragma once +#include "Graphics/Buffer.h" +#include "Graphics.h" +#include "Allocator.h" + +namespace Seele +{ +namespace Vulkan +{ + +class ShaderBuffer +{ +public: + ShaderBuffer(PGraphics graphics, uint64 size, VkBufferUsageFlags usage, Gfx::QueueType& queueType, bool bDynamic = false); + virtual ~ShaderBuffer(); + VkBuffer getHandle() const + { + return buffers[currentBuffer].buffer; + } + uint64 getSize() const + { + return size; + } + VkDeviceSize getOffset() const; + void advanceBuffer() + { + currentBuffer = (currentBuffer + 1) % numBuffers; + } + virtual void *lock(bool bWriteOnly = true); + virtual void *lockRegion(uint64 regionOffset, uint64 regionSize, bool bWriteOnly = true); + virtual void unlock(); + +protected: + struct BufferAllocation + { + VkBuffer buffer; + PSubAllocation allocation; + }; + PGraphics graphics; + uint32 currentBuffer; + uint64 size; + Gfx::QueueType& owner; + BufferAllocation buffers[Gfx::numFramesBuffered]; + uint32 numBuffers; + + void executeOwnershipBarrier(Gfx::QueueType newOwner); + void executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage, + VkAccessFlags dstAccess, VkPipelineStageFlags dstStage); + + virtual void requestOwnershipTransfer(Gfx::QueueType newOwner) = 0; + + virtual VkAccessFlags getSourceAccessMask() = 0; + virtual VkAccessFlags getDestAccessMask() = 0; +}; +DEFINE_REF(ShaderBuffer) + +DECLARE_REF(StagingBuffer) +class UniformBuffer : public Gfx::UniformBuffer, public ShaderBuffer +{ +public: + UniformBuffer(PGraphics graphics, const UniformBufferCreateInfo &resourceData); + virtual ~UniformBuffer(); + virtual bool updateContents(const BulkResourceData &resourceData); + + virtual void* lock(bool bWriteOnly = true) override; + virtual void unlock() override; +protected: + // Inherited via Vulkan::Buffer + virtual VkAccessFlags getSourceAccessMask(); + virtual VkAccessFlags getDestAccessMask(); + virtual void requestOwnershipTransfer(Gfx::QueueType newOwner); + // Inherited via QueueOwnedResource + virtual void executeOwnershipBarrier(Gfx::QueueType newOwner); + virtual void executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage, + VkAccessFlags dstAccess, VkPipelineStageFlags dstStage); + +private: + PStagingBuffer dedicatedStagingBuffer; +}; +DEFINE_REF(UniformBuffer) + +class ShaderBuffer : public Gfx::ShaderBuffer, public ShaderBuffer +{ +public: + ShaderBuffer(PGraphics graphics, const ShaderBufferCreateInfo &resourceData); + virtual ~ShaderBuffer(); + virtual bool updateContents(const BulkResourceData &resourceData); + + virtual void* lock(bool bWriteOnly = true) override; + virtual void unlock() override; +protected: + // Inherited via Vulkan::Buffer + virtual VkAccessFlags getSourceAccessMask(); + virtual VkAccessFlags getDestAccessMask(); + virtual void requestOwnershipTransfer(Gfx::QueueType newOwner); + // Inherited via QueueOwnedResource + virtual void executeOwnershipBarrier(Gfx::QueueType newOwner); + virtual void executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage, + VkAccessFlags dstAccess, VkPipelineStageFlags dstStage); +private: + PStagingBuffer dedicatedStagingBuffer; +}; +DEFINE_REF(ShaderBuffer) + +class VertexBuffer : public Gfx::VertexBuffer, public ShaderBuffer +{ +public: + VertexBuffer(PGraphics graphics, const VertexBufferCreateInfo &resourceData); + virtual ~VertexBuffer(); + + virtual void updateRegion(BulkResourceData update) override; + virtual void download(Array& buffer) override; +protected: + // Inherited via Vulkan::Buffer + virtual VkAccessFlags getSourceAccessMask(); + virtual VkAccessFlags getDestAccessMask(); + virtual void requestOwnershipTransfer(Gfx::QueueType newOwner); + // Inherited via QueueOwnedResource + virtual void executeOwnershipBarrier(Gfx::QueueType newOwner); + virtual void executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage, + VkAccessFlags dstAccess, VkPipelineStageFlags dstStage); +}; +DEFINE_REF(VertexBuffer) + +class IndexBuffer : public Gfx::IndexBuffer, public ShaderBuffer +{ +public: + IndexBuffer(PGraphics graphics, const IndexBufferCreateInfo &resourceData); + virtual ~IndexBuffer(); + + virtual void download(Array& buffer) override; +protected: + // Inherited via Vulkan::Buffer + virtual VkAccessFlags getSourceAccessMask(); + virtual VkAccessFlags getDestAccessMask(); + virtual void requestOwnershipTransfer(Gfx::QueueType newOwner); + // Inherited via QueueOwnedResource + virtual void executeOwnershipBarrier(Gfx::QueueType newOwner); + virtual void executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage, + VkAccessFlags dstAccess, VkPipelineStageFlags dstStage); +}; +DEFINE_REF(IndexBuffer) + +} +} \ No newline at end of file diff --git a/src/Engine/Graphics/Vulkan/CMakeLists.txt b/src/Engine/Graphics/Vulkan/CMakeLists.txt index 2ff5e1e..9e71b87 100644 --- a/src/Engine/Graphics/Vulkan/CMakeLists.txt +++ b/src/Engine/Graphics/Vulkan/CMakeLists.txt @@ -1,49 +1,55 @@ target_sources(Engine PRIVATE - VulkanAllocator.h - VulkanAllocator.cpp - VulkanBuffer.cpp - VulkanCommandBuffer.h - VulkanCommandBuffer.cpp - VulkanFramebuffer.h - VulkanFramebuffer.cpp - VulkanGraphics.h - VulkanGraphics.cpp - VulkanGraphicsResources.h - VulkanGraphicsResources.cpp - VulkanDescriptorSets.h - VulkanDescriptorSets.cpp - VulkanGraphicsEnums.h - VulkanGraphicsEnums.cpp - VulkanInitializer.h - VulkanInitializer.cpp - VulkanRenderPass.h - VulkanRenderPass.cpp - VulkanPipeline.h - VulkanPipeline.cpp - VulkanPipelineCache.h - VulkanPipelineCache.cpp - VulkanShader.h - VulkanShader.cpp - VulkanTexture.cpp - VulkanQueue.h - VulkanQueue.cpp - VulkanViewport.cpp) + Allocator.h + Allocator.cpp + Buffer.h + Buffer.cpp + CommandBuffer.h + CommandBuffer.cpp + DescriptorSets.h + DescriptorSets.cpp + Enums.h + Enums.cpp + Framebuffer.h + Framebuffer.cpp + Graphics.h + Graphics.cpp + Initializer.h + Initializer.cpp + Pipeline.h + Pipeline.cpp + PipelineCache.h + PipelineCache.cpp + Queue.h + Queue.cpp + RenderPass.h + RenderPass.cpp + RenderTarget.h + RenderTarget.cpp + Resources.h + Resources.cpp + Shader.h + Shader.cpp + Texture.h + Texture.cpp) target_sources(Engine PUBLIC FILE_SET HEADERS FILES - VulkanAllocator.h - VulkanCommandBuffer.h - VulkanFramebuffer.h - VulkanGraphics.h - VulkanGraphicsResources.h - VulkanDescriptorSets.h - VulkanGraphicsEnums.h - VulkanInitializer.h - VulkanRenderPass.h - VulkanPipeline.h - VulkanPipelineCache.h - VulkanShader.h - VulkanQueue.h) + Allocator.h + Buffer.h + CommandBuffer.h + DescriptorSets.h + Enums.h + Framebuffer.h + Graphics.h + Initializer.h + Pipeline.h + PipelineCache.h + Queue.h + RenderPass.h + RenderTarget.h + Resources.h + Shader.h + Texture.h) \ No newline at end of file diff --git a/src/Engine/Graphics/Vulkan/VulkanCommandBuffer.cpp b/src/Engine/Graphics/Vulkan/CommandBuffer.cpp similarity index 98% rename from src/Engine/Graphics/Vulkan/VulkanCommandBuffer.cpp rename to src/Engine/Graphics/Vulkan/CommandBuffer.cpp index 1d5f9af..4b2587c 100644 --- a/src/Engine/Graphics/Vulkan/VulkanCommandBuffer.cpp +++ b/src/Engine/Graphics/Vulkan/CommandBuffer.cpp @@ -1,13 +1,12 @@ -#include "VulkanCommandBuffer.h" -#include "VulkanInitializer.h" -#include "VulkanGraphics.h" -#include "VulkanPipeline.h" -#include "VulkanGraphicsEnums.h" -#include "VulkanFramebuffer.h" -#include "VulkanRenderPass.h" -#include "VulkanPipeline.h" -#include "VulkanDescriptorSets.h" -#include "Graphics/MeshBatch.h" +#include "CommandBuffer.h" +#include "Initializer.h" +#include "Graphics.h" +#include "Pipeline.h" +#include "Enums.h" +#include "Framebuffer.h" +#include "RenderPass.h" +#include "Pipeline.h" +#include "DescriptorSets.h" using namespace Seele; using namespace Seele::Vulkan; diff --git a/src/Engine/Graphics/Vulkan/VulkanCommandBuffer.h b/src/Engine/Graphics/Vulkan/CommandBuffer.h similarity index 97% rename from src/Engine/Graphics/Vulkan/VulkanCommandBuffer.h rename to src/Engine/Graphics/Vulkan/CommandBuffer.h index 0fefc8b..9420f84 100644 --- a/src/Engine/Graphics/Vulkan/VulkanCommandBuffer.h +++ b/src/Engine/Graphics/Vulkan/CommandBuffer.h @@ -1,6 +1,7 @@ #pragma once -#include "VulkanGraphicsResources.h" -#include "VulkanQueue.h" +#include "Queue.h" +#include "DescriptorSets.h" +#include "Buffer.h" namespace Seele { @@ -87,7 +88,7 @@ public: virtual void bindPipeline(Gfx::PGraphicsPipeline pipeline) override; virtual void bindDescriptor(Gfx::PDescriptorSet descriptorSet) override; virtual void bindDescriptor(const Array& descriptorSets) override; - virtual void bindVertexBuffer(const Array& streams) override; + virtual void bindVertexBuffer(const Array& buffers) override; virtual void bindIndexBuffer(Gfx::PIndexBuffer indexBuffer) override; virtual void pushConstants(Gfx::PPipelineLayout layout, Gfx::SeShaderStageFlags stage, uint32 offset, uint32 size, const void* data) override; virtual void draw(uint32 vertexCount, uint32 instanceCount, int32 firstVertex, uint32 firstInstance) override; diff --git a/src/Engine/Graphics/Vulkan/VulkanDescriptorSets.cpp b/src/Engine/Graphics/Vulkan/DescriptorSets.cpp similarity index 98% rename from src/Engine/Graphics/Vulkan/VulkanDescriptorSets.cpp rename to src/Engine/Graphics/Vulkan/DescriptorSets.cpp index 0a38918..4f09e64 100644 --- a/src/Engine/Graphics/Vulkan/VulkanDescriptorSets.cpp +++ b/src/Engine/Graphics/Vulkan/DescriptorSets.cpp @@ -1,9 +1,7 @@ -#include "VulkanDescriptorSets.h" -#include "VulkanGraphicsResources.h" -#include "VulkanGraphicsEnums.h" -#include "VulkanGraphics.h" -#include "VulkanInitializer.h" -#include "VulkanCommandBuffer.h" +#include "DescriptorSets.h" +#include "Graphics.h" +#include "Initializer.h" +#include "CommandBuffer.h" using namespace Seele; using namespace Seele::Vulkan; diff --git a/src/Engine/Graphics/Vulkan/VulkanDescriptorSets.h b/src/Engine/Graphics/Vulkan/DescriptorSets.h similarity index 97% rename from src/Engine/Graphics/Vulkan/VulkanDescriptorSets.h rename to src/Engine/Graphics/Vulkan/DescriptorSets.h index b801aed..621821b 100644 --- a/src/Engine/Graphics/Vulkan/VulkanDescriptorSets.h +++ b/src/Engine/Graphics/Vulkan/DescriptorSets.h @@ -1,5 +1,8 @@ #pragma once -#include "VulkanGraphicsResources.h" +#include "Enums.h" +#include "Graphics/Descriptor.h" +#include "Containers/List.h" +#include "Resources.h" namespace Seele { diff --git a/src/Engine/Graphics/Vulkan/VulkanGraphicsEnums.cpp b/src/Engine/Graphics/Vulkan/Enums.cpp similarity index 100% rename from src/Engine/Graphics/Vulkan/VulkanGraphicsEnums.cpp rename to src/Engine/Graphics/Vulkan/Enums.cpp diff --git a/src/Engine/Graphics/Vulkan/VulkanGraphicsEnums.h b/src/Engine/Graphics/Vulkan/Enums.h similarity index 96% rename from src/Engine/Graphics/Vulkan/VulkanGraphicsEnums.h rename to src/Engine/Graphics/Vulkan/Enums.h index 060b077..5508d9b 100644 --- a/src/Engine/Graphics/Vulkan/VulkanGraphicsEnums.h +++ b/src/Engine/Graphics/Vulkan/Enums.h @@ -1,5 +1,5 @@ #pragma once -#include "Graphics/GraphicsEnums.h" +#include "Graphics/Enums.h" #include #include @@ -25,11 +25,10 @@ namespace Vulkan enum class ShaderType { VERTEX = 0, - CONTROL = 1, - EVALUATION = 2, - GEOMETRY = 3, - FRAGMENT = 4, - COMPUTE = 5, + FRAGMENT = 1, + COMPUTE = 2, + TASK = 3, + MESH = 4, }; VkDescriptorType cast(const Gfx::SeDescriptorType &descriptorType); diff --git a/src/Engine/Graphics/Vulkan/VulkanFramebuffer.cpp b/src/Engine/Graphics/Vulkan/Framebuffer.cpp similarity index 93% rename from src/Engine/Graphics/Vulkan/VulkanFramebuffer.cpp rename to src/Engine/Graphics/Vulkan/Framebuffer.cpp index 3765ef1..a7d83c9 100644 --- a/src/Engine/Graphics/Vulkan/VulkanFramebuffer.cpp +++ b/src/Engine/Graphics/Vulkan/Framebuffer.cpp @@ -1,8 +1,9 @@ -#include "VulkanFramebuffer.h" -#include "VulkanGraphicsEnums.h" -#include "VulkanInitializer.h" -#include "VulkanRenderPass.h" -#include "VulkanGraphics.h" +#include "Framebuffer.h" +#include "Enums.h" +#include "Initializer.h" +#include "RenderPass.h" +#include "Graphics.h" +#include "Texture.h" using namespace Seele; using namespace Seele::Vulkan; diff --git a/src/Engine/Graphics/Vulkan/VulkanFramebuffer.h b/src/Engine/Graphics/Vulkan/Framebuffer.h similarity index 91% rename from src/Engine/Graphics/Vulkan/VulkanFramebuffer.h rename to src/Engine/Graphics/Vulkan/Framebuffer.h index 2a062fa..f9067b6 100644 --- a/src/Engine/Graphics/Vulkan/VulkanFramebuffer.h +++ b/src/Engine/Graphics/Vulkan/Framebuffer.h @@ -1,5 +1,7 @@ #pragma once -#include "VulkanGraphicsResources.h" +#include "Enums.h" +#include "Graphics.h" +#include "Graphics/RenderTarget.h" namespace Seele { diff --git a/src/Engine/Graphics/Vulkan/VulkanGraphics.cpp b/src/Engine/Graphics/Vulkan/Graphics.cpp similarity index 100% rename from src/Engine/Graphics/Vulkan/VulkanGraphics.cpp rename to src/Engine/Graphics/Vulkan/Graphics.cpp diff --git a/src/Engine/Graphics/Vulkan/VulkanGraphics.h b/src/Engine/Graphics/Vulkan/Graphics.h similarity index 89% rename from src/Engine/Graphics/Vulkan/VulkanGraphics.h rename to src/Engine/Graphics/Vulkan/Graphics.h index fb4db6f..d2cd119 100644 --- a/src/Engine/Graphics/Vulkan/VulkanGraphics.h +++ b/src/Engine/Graphics/Vulkan/Graphics.h @@ -1,5 +1,5 @@ #pragma once -#include "VulkanGraphicsResources.h" +#include "Enums.h" #include "Graphics/Graphics.h" namespace Seele @@ -14,6 +14,9 @@ DECLARE_REF(RenderPass) DECLARE_REF(Framebuffer) DECLARE_REF(RenderCommand) DECLARE_REF(PipelineCache) +DECLARE_REF(Window) +DECLARE_REF(RenderTargetLayout) +DECLARE_REF(Viewport) class Graphics : public Gfx::Graphics { public: @@ -55,13 +58,13 @@ public: virtual Gfx::PComputeCommand createComputeCommand(const std::string& name) override; virtual Gfx::PVertexDeclaration createVertexDeclaration(const Array& element) override; virtual Gfx::PVertexShader createVertexShader(const ShaderCreateInfo& createInfo) override; - virtual Gfx::PControlShader createControlShader(const ShaderCreateInfo& createInfo) override; - virtual Gfx::PEvaluationShader createEvaluationShader(const ShaderCreateInfo& createInfo) override; - virtual Gfx::PGeometryShader createGeometryShader(const ShaderCreateInfo& createInfo) override; virtual Gfx::PFragmentShader createFragmentShader(const ShaderCreateInfo& createInfo) override; virtual Gfx::PComputeShader createComputeShader(const ShaderCreateInfo& createInfo) override; - virtual Gfx::PGraphicsPipeline createGraphicsPipeline(const GraphicsPipelineCreateInfo& createInfo) override; - virtual Gfx::PComputePipeline createComputePipeline(const ComputePipelineCreateInfo& createInfo) override; + virtual Gfx::PTaskShader createTaskShader(const ShaderCreateInfo& createInfo) override; + virtual Gfx::PMeshShader createMeshShader(const ShaderCreateInfo& createInfo) override; + virtual Gfx::PGraphicsPipeline createGraphicsPipeline(const Gfx::LegacyPipelineCreateInfo& createInfo) override; + virtual Gfx::PGraphicsPipeline createGraphicsPipeline(const Gfx::MeshPipelineCreateInfo& createInfo) override; + virtual Gfx::PComputePipeline createComputePipeline(const Gfx::ComputePipelineCreateInfo& createInfo) override; virtual Gfx::PSamplerState createSamplerState(const SamplerCreateInfo& createInfo) override; virtual Gfx::PDescriptorLayout createDescriptorLayout(const std::string& name = "") override; diff --git a/src/Engine/Graphics/Vulkan/VulkanInitializer.cpp b/src/Engine/Graphics/Vulkan/Initializer.cpp similarity index 99% rename from src/Engine/Graphics/Vulkan/VulkanInitializer.cpp rename to src/Engine/Graphics/Vulkan/Initializer.cpp index fb2b9b1..d934652 100644 --- a/src/Engine/Graphics/Vulkan/VulkanInitializer.cpp +++ b/src/Engine/Graphics/Vulkan/Initializer.cpp @@ -1,4 +1,4 @@ -#include "VulkanInitializer.h" +#include "Initializer.h" #include using namespace Seele::Vulkan; diff --git a/src/Engine/Graphics/Vulkan/VulkanInitializer.h b/src/Engine/Graphics/Vulkan/Initializer.h similarity index 100% rename from src/Engine/Graphics/Vulkan/VulkanInitializer.h rename to src/Engine/Graphics/Vulkan/Initializer.h diff --git a/src/Engine/Graphics/Vulkan/VulkanPipeline.cpp b/src/Engine/Graphics/Vulkan/Pipeline.cpp similarity index 69% rename from src/Engine/Graphics/Vulkan/VulkanPipeline.cpp rename to src/Engine/Graphics/Vulkan/Pipeline.cpp index 09ec5fb..c8a0b0e 100644 --- a/src/Engine/Graphics/Vulkan/VulkanPipeline.cpp +++ b/src/Engine/Graphics/Vulkan/Pipeline.cpp @@ -1,12 +1,12 @@ -#include "VulkanPipeline.h" -#include "VulkanDescriptorSets.h" -#include "VulkanGraphics.h" +#include "Pipeline.h" +#include "DescriptorSets.h" +#include "Graphics.h" using namespace Seele; using namespace Seele::Vulkan; -GraphicsPipeline::GraphicsPipeline(PGraphics graphics, VkPipeline handle, PPipelineLayout pipelineLayout, const GraphicsPipelineCreateInfo& createInfo) - : Gfx::GraphicsPipeline(createInfo, pipelineLayout) +GraphicsPipeline::GraphicsPipeline(PGraphics graphics, VkPipeline handle, PPipelineLayout pipelineLayout) + : Gfx::GraphicsPipeline(pipelineLayout) , graphics(graphics) , pipeline(handle) { @@ -26,8 +26,8 @@ VkPipelineLayout GraphicsPipeline::getLayout() const return layout.cast()->getHandle(); } -ComputePipeline::ComputePipeline(PGraphics graphics, VkPipeline handle, PPipelineLayout pipelineLayout, const ComputePipelineCreateInfo& createInfo) - : Gfx::ComputePipeline(createInfo, pipelineLayout) +ComputePipeline::ComputePipeline(PGraphics graphics, VkPipeline handle, PPipelineLayout pipelineLayout) + : Gfx::ComputePipeline(pipelineLayout) , graphics(graphics) , pipeline(handle) { diff --git a/src/Engine/Graphics/Vulkan/VulkanPipeline.h b/src/Engine/Graphics/Vulkan/Pipeline.h similarity index 81% rename from src/Engine/Graphics/Vulkan/VulkanPipeline.h rename to src/Engine/Graphics/Vulkan/Pipeline.h index 4a06988..ba35967 100644 --- a/src/Engine/Graphics/Vulkan/VulkanPipeline.h +++ b/src/Engine/Graphics/Vulkan/Pipeline.h @@ -1,5 +1,6 @@ #pragma once -#include "VulkanGraphicsResources.h" +#include "Enums.h" +#include "Graphics/Resources.h" namespace Seele { @@ -10,7 +11,7 @@ DECLARE_REF(Graphics) class GraphicsPipeline : public Gfx::GraphicsPipeline { public: - GraphicsPipeline(PGraphics graphics, VkPipeline handle, PPipelineLayout pipelineLayout, const GraphicsPipelineCreateInfo& createInfo); + GraphicsPipeline(PGraphics graphics, VkPipeline handle, PPipelineLayout pipelineLayout); virtual ~GraphicsPipeline(); void bind(VkCommandBuffer handle); VkPipelineLayout getLayout() const; @@ -22,7 +23,7 @@ DEFINE_REF(GraphicsPipeline) class ComputePipeline : public Gfx::ComputePipeline { public: - ComputePipeline(PGraphics graphics, VkPipeline handle, PPipelineLayout pipelineLayout, const ComputePipelineCreateInfo& createInfo); + ComputePipeline(PGraphics graphics, VkPipeline handle, PPipelineLayout pipelineLayout); virtual ~ComputePipeline(); void bind(VkCommandBuffer handle); VkPipelineLayout getLayout() const; diff --git a/src/Engine/Graphics/Vulkan/PipelineCache.cpp b/src/Engine/Graphics/Vulkan/PipelineCache.cpp new file mode 100644 index 0000000..40cf1c4 --- /dev/null +++ b/src/Engine/Graphics/Vulkan/PipelineCache.cpp @@ -0,0 +1,393 @@ +#include "PipelineCache.h" +#include "Graphics.h" +#include "Enums.h" +#include "Initializer.h" +#include "RenderPass.h" +#include "DescriptorSets.h" +#include "Shader.h" +#include + +using namespace Seele; +using namespace Seele::Vulkan; + +PipelineCache::PipelineCache(PGraphics graphics, const std::string& cacheFilePath) + : graphics(graphics) + , cacheFile(cacheFilePath) +{ + std::ifstream stream(cacheFilePath, std::ios::binary | std::ios::ate); + VkPipelineCacheCreateInfo cacheCreateInfo; + cacheCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO; + cacheCreateInfo.pNext = nullptr; + cacheCreateInfo.flags = 0; + cacheCreateInfo.initialDataSize = 0; + if(stream.good()) + { + Array cacheData; + uint32 fileSize = static_cast(stream.tellg()); + cacheData.resize(fileSize); + stream.seekg(0); + stream.read((char*)cacheData.data(), fileSize); + cacheCreateInfo.initialDataSize = fileSize; + cacheCreateInfo.pInitialData = cacheData.data(); + std::cout << "Loaded " << fileSize << " bytes from pipeline cache" << std::endl; + } + VK_CHECK(vkCreatePipelineCache(graphics->getDevice(), &cacheCreateInfo, nullptr, &cache)); +} + +PipelineCache::~PipelineCache() +{ + VkDeviceSize cacheSize; + vkGetPipelineCacheData(graphics->getDevice(), cache, &cacheSize, nullptr); + Array cacheData; + vkGetPipelineCacheData(graphics->getDevice(), cache, &cacheSize, cacheData.data()); + std::ofstream stream(cacheFile, std::ios::binary); + stream.write((char*)cacheData.data(), cacheSize); + stream.flush(); + stream.close(); + vkDestroyPipelineCache(graphics->getDevice(), cache, nullptr); + std::cout << "Written " << cacheSize << " bytes to cache" << std::endl; +} + +PGraphicsPipeline PipelineCache::createPipeline(const Gfx::LegacyPipelineCreateInfo& gfxInfo) +{ + uint32 stageCount = 0; + + VkPipelineShaderStageCreateInfo stageInfos[2]; + std::memset(stageInfos, 0, sizeof(stageInfos)); + + PVertexShader vertexShader = gfxInfo.vertexShader.cast(); + stageInfos[stageCount++] = { + .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, + .stage = VK_SHADER_STAGE_VERTEX_BIT, + .module = vertexShader->getModuleHandle(), + .pName = vertexShader->getEntryPointName(), + }; + + if(gfxInfo.fragmentShader != nullptr) + { + PFragmentShader fragment = gfxInfo.fragmentShader.cast(); + + stageInfos[stageCount++] = { + .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, + .stage = VK_SHADER_STAGE_FRAGMENT_BIT, + .module = fragment->getModuleHandle(), + .pName = fragment->getEntryPointName(), + }; + } + VkPipelineVertexInputStateCreateInfo vertexInput = + init::PipelineVertexInputStateCreateInfo(); + + Array bindings; + Array attributes; + if (gfxInfo.vertexDeclaration != nullptr) + { + PVertexDeclaration decl = gfxInfo.vertexDeclaration.cast(); + for (const auto& elem : decl->elementList) + { + attributes.add(VkVertexInputAttributeDescription{ + .location = elem.attributeIndex, + .binding = elem.binding, + .format = cast(elem.vertexFormat), + .offset = elem.offset, + }); + auto res = bindings.find([elem](const VkVertexInputBindingDescription& b) {return b.binding == elem.binding; }); + if (res == bindings.end()) + { + bindings.add({}); + res = bindings.end(); + } + *res = VkVertexInputBindingDescription{ + .binding = elem.binding, + .stride = elem.stride, + .inputRate = elem.bInstanced ? VK_VERTEX_INPUT_RATE_INSTANCE : VK_VERTEX_INPUT_RATE_VERTEX, + }; + } + vertexInput.pVertexAttributeDescriptions = attributes.data(); + vertexInput.vertexAttributeDescriptionCount = attributes.size(); + vertexInput.pVertexBindingDescriptions = bindings.data(); + vertexInput.vertexBindingDescriptionCount = bindings.size(); + } + + VkPipelineInputAssemblyStateCreateInfo assemblyInfo = + init::PipelineInputAssemblyStateCreateInfo( + cast(gfxInfo.topology), + 0, + false + ); + VkPipelineViewportStateCreateInfo viewportInfo = + init::PipelineViewportStateCreateInfo( + 1, + 1, + 0 + ); + VkPipelineRasterizationStateCreateInfo rasterizationState = + init::PipelineRasterizationStateCreateInfo( + cast(gfxInfo.rasterizationState.polygonMode), + gfxInfo.rasterizationState.cullMode, + (VkFrontFace)gfxInfo.rasterizationState.frontFace, + 0 + ); + rasterizationState.depthBiasEnable = gfxInfo.rasterizationState.depthBiasEnable; + rasterizationState.depthBiasClamp = gfxInfo.rasterizationState.depthBiasClamp; + rasterizationState.depthBiasConstantFactor = gfxInfo.rasterizationState.depthBoasConstantFactor; + rasterizationState.depthBiasSlopeFactor = gfxInfo.rasterizationState.depthBiasSlopeFactor; + rasterizationState.depthClampEnable = gfxInfo.rasterizationState.depthClampEnable; + rasterizationState.lineWidth = gfxInfo.rasterizationState.lineWidth; + rasterizationState.rasterizerDiscardEnable = gfxInfo.rasterizationState.rasterizerDiscardEnable; + + VkPipelineMultisampleStateCreateInfo multisampleState = + init::PipelineMultisampleStateCreateInfo( + (VkSampleCountFlagBits)gfxInfo.multisampleState.samples, + 0); + multisampleState.alphaToCoverageEnable = gfxInfo.multisampleState.alphaCoverageEnable; + multisampleState.alphaToOneEnable = gfxInfo.multisampleState.alphaToOneEnable; + multisampleState.minSampleShading = gfxInfo.multisampleState.minSampleShading; + multisampleState.sampleShadingEnable = gfxInfo.multisampleState.sampleShadingEnable; + + VkPipelineDepthStencilStateCreateInfo depthStencilState = + init::PipelineDepthStencilStateCreateInfo( + gfxInfo.depthStencilState.depthTestEnable, + gfxInfo.depthStencilState.depthWriteEnable, + cast(gfxInfo.depthStencilState.depthCompareOp) + ); + + const auto& colorAttachments = gfxInfo.renderPass->getLayout()->colorAttachments; + Array blendAttachments(colorAttachments.size()); + for(uint32 i = 0; i < colorAttachments.size(); ++i) + { + const Gfx::ColorBlendState::BlendAttachment& attachment = gfxInfo.colorBlend.blendAttachments[i]; + blendAttachments[i] = { + .blendEnable = attachment.blendEnable, + .srcColorBlendFactor = (VkBlendFactor)attachment.srcColorBlendFactor, + .dstColorBlendFactor = (VkBlendFactor)attachment.dstColorBlendFactor, + .colorBlendOp = (VkBlendOp)attachment.colorBlendOp, + .srcAlphaBlendFactor = (VkBlendFactor)attachment.srcAlphaBlendFactor, + .dstAlphaBlendFactor = (VkBlendFactor)attachment.dstAlphaBlendFactor, + .alphaBlendOp = (VkBlendOp)attachment.alphaBlendOp, + .colorWriteMask = attachment.colorWriteMask, + }; + } + VkPipelineColorBlendStateCreateInfo blendState = + init::PipelineColorBlendStateCreateInfo( + (uint32)blendAttachments.size(), + blendAttachments.data() + ); + blendState.logicOpEnable = gfxInfo.colorBlend.logicOpEnable; + blendState.logicOp = (VkLogicOp)gfxInfo.colorBlend.logicOp; + std::memcpy(blendState.blendConstants, gfxInfo.colorBlend.blendConstants, sizeof(gfxInfo.colorBlend.blendConstants)); + + uint32 numDynamicEnabled = 0; + StaticArray dynamicEnabled; + dynamicEnabled[numDynamicEnabled++] = VK_DYNAMIC_STATE_VIEWPORT; + dynamicEnabled[numDynamicEnabled++] = VK_DYNAMIC_STATE_SCISSOR; + + VkPipelineDynamicStateCreateInfo dynamicState = + init::PipelineDynamicStateCreateInfo( + dynamicEnabled.data(), + numDynamicEnabled, + 0 + ); + + PPipelineLayout layout = gfxInfo.pipelineLayout.cast(); + + VkPipeline pipelineHandle; + + VkGraphicsPipelineCreateInfo createInfo = { + .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, + .pNext = 0, + .flags = 0, + .stageCount = stageCount, + .pStages = stageInfos, + .pVertexInputState = &vertexInput, + .pInputAssemblyState = &assemblyInfo, + .pViewportState = &viewportInfo, + .pRasterizationState = &rasterizationState, + .pMultisampleState = &multisampleState, + .pDepthStencilState = &depthStencilState, + .pColorBlendState = &blendState, + .pDynamicState = &dynamicState, + .layout = layout->getHandle(), + .renderPass = gfxInfo.renderPass.cast()->getHandle(), + .subpass = 0, + }; + auto beginTime = std::chrono::high_resolution_clock::now(); + VK_CHECK(vkCreateGraphicsPipelines(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 << "Gfx creation time: " << delta << std::endl; + + + PGraphicsPipeline result = new GraphicsPipeline(graphics, pipelineHandle, layout); + return result; +} + + +PGraphicsPipeline PipelineCache::createPipeline(const Gfx::MeshPipelineCreateInfo& gfxInfo) +{ + uint32 stageCount = 0; + + VkPipelineShaderStageCreateInfo stageInfos[3]; + std::memset(stageInfos, 0, sizeof(stageInfos)); + + if (gfxInfo.taskShader != nullptr) + { + PTaskShader taskShader = gfxInfo.taskShader.cast(); + stageInfos[stageCount++] = { + .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, + .stage = VK_SHADER_STAGE_TASK_BIT_EXT, + .module = taskShader->getModuleHandle(), + .pName = taskShader->getEntryPointName(), + }; + } + + PMeshShader meshShader = gfxInfo.meshShader.cast(); + stageInfos[stageCount++] = { + .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, + .stage = VK_SHADER_STAGE_MESH_BIT_EXT, + .module = meshShader->getModuleHandle(), + .pName = meshShader->getEntryPointName(), + }; + + if (gfxInfo.fragmentShader != nullptr) + { + PFragmentShader fragment = gfxInfo.fragmentShader.cast(); + + stageInfos[stageCount++] = { + .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, + .stage = VK_SHADER_STAGE_FRAGMENT_BIT, + .module = fragment->getModuleHandle(), + .pName = fragment->getEntryPointName(), + }; + } + VkPipelineViewportStateCreateInfo viewportInfo = + init::PipelineViewportStateCreateInfo( + 1, + 1, + 0 + ); + VkPipelineRasterizationStateCreateInfo rasterizationState = + init::PipelineRasterizationStateCreateInfo( + cast(gfxInfo.rasterizationState.polygonMode), + gfxInfo.rasterizationState.cullMode, + (VkFrontFace)gfxInfo.rasterizationState.frontFace, + 0 + ); + rasterizationState.depthBiasEnable = gfxInfo.rasterizationState.depthBiasEnable; + rasterizationState.depthBiasClamp = gfxInfo.rasterizationState.depthBiasClamp; + rasterizationState.depthBiasConstantFactor = gfxInfo.rasterizationState.depthBoasConstantFactor; + rasterizationState.depthBiasSlopeFactor = gfxInfo.rasterizationState.depthBiasSlopeFactor; + rasterizationState.depthClampEnable = gfxInfo.rasterizationState.depthClampEnable; + rasterizationState.lineWidth = gfxInfo.rasterizationState.lineWidth; + rasterizationState.rasterizerDiscardEnable = gfxInfo.rasterizationState.rasterizerDiscardEnable; + + VkPipelineMultisampleStateCreateInfo multisampleState = + init::PipelineMultisampleStateCreateInfo( + (VkSampleCountFlagBits)gfxInfo.multisampleState.samples, + 0); + multisampleState.alphaToCoverageEnable = gfxInfo.multisampleState.alphaCoverageEnable; + multisampleState.alphaToOneEnable = gfxInfo.multisampleState.alphaToOneEnable; + multisampleState.minSampleShading = gfxInfo.multisampleState.minSampleShading; + multisampleState.sampleShadingEnable = gfxInfo.multisampleState.sampleShadingEnable; + + VkPipelineDepthStencilStateCreateInfo depthStencilState = + init::PipelineDepthStencilStateCreateInfo( + gfxInfo.depthStencilState.depthTestEnable, + gfxInfo.depthStencilState.depthWriteEnable, + cast(gfxInfo.depthStencilState.depthCompareOp) + ); + + const auto& colorAttachments = gfxInfo.renderPass->getLayout()->colorAttachments; + Array blendAttachments(colorAttachments.size()); + for (uint32 i = 0; i < colorAttachments.size(); ++i) + { + const Gfx::ColorBlendState::BlendAttachment& attachment = gfxInfo.colorBlend.blendAttachments[i]; + blendAttachments[i] = { + .blendEnable = attachment.blendEnable, + .srcColorBlendFactor = (VkBlendFactor)attachment.srcColorBlendFactor, + .dstColorBlendFactor = (VkBlendFactor)attachment.dstColorBlendFactor, + .colorBlendOp = (VkBlendOp)attachment.colorBlendOp, + .srcAlphaBlendFactor = (VkBlendFactor)attachment.srcAlphaBlendFactor, + .dstAlphaBlendFactor = (VkBlendFactor)attachment.dstAlphaBlendFactor, + .alphaBlendOp = (VkBlendOp)attachment.alphaBlendOp, + .colorWriteMask = attachment.colorWriteMask, + }; + } + VkPipelineColorBlendStateCreateInfo blendState = + init::PipelineColorBlendStateCreateInfo( + (uint32)blendAttachments.size(), + blendAttachments.data() + ); + blendState.logicOpEnable = gfxInfo.colorBlend.logicOpEnable; + blendState.logicOp = (VkLogicOp)gfxInfo.colorBlend.logicOp; + std::memcpy(blendState.blendConstants, gfxInfo.colorBlend.blendConstants, sizeof(gfxInfo.colorBlend.blendConstants)); + + uint32 numDynamicEnabled = 0; + StaticArray dynamicEnabled; + dynamicEnabled[numDynamicEnabled++] = VK_DYNAMIC_STATE_VIEWPORT; + dynamicEnabled[numDynamicEnabled++] = VK_DYNAMIC_STATE_SCISSOR; + + VkPipelineDynamicStateCreateInfo dynamicState = + init::PipelineDynamicStateCreateInfo( + dynamicEnabled.data(), + numDynamicEnabled, + 0 + ); + + PPipelineLayout layout = gfxInfo.pipelineLayout.cast(); + + VkPipeline pipelineHandle; + + VkGraphicsPipelineCreateInfo createInfo = { + .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, + .pNext = 0, + .flags = 0, + .stageCount = stageCount, + .pStages = stageInfos, + .pVertexInputState = nullptr, + .pInputAssemblyState = nullptr, + .pViewportState = &viewportInfo, + .pRasterizationState = &rasterizationState, + .pMultisampleState = &multisampleState, + .pDepthStencilState = &depthStencilState, + .pColorBlendState = &blendState, + .pDynamicState = &dynamicState, + .layout = layout->getHandle(), + .renderPass = gfxInfo.renderPass.cast()->getHandle(), + .subpass = 0, + }; + auto beginTime = std::chrono::high_resolution_clock::now(); + VK_CHECK(vkCreateGraphicsPipelines(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 << "Gfx creation time: " << delta << std::endl; + + + PGraphicsPipeline result = new GraphicsPipeline(graphics, pipelineHandle, layout); + return result; +} + + +PComputePipeline 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()); + 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); + return result; +} \ No newline at end of file diff --git a/src/Engine/Graphics/Vulkan/VulkanPipelineCache.h b/src/Engine/Graphics/Vulkan/PipelineCache.h similarity index 54% rename from src/Engine/Graphics/Vulkan/VulkanPipelineCache.h rename to src/Engine/Graphics/Vulkan/PipelineCache.h index 94e458c..8cd0493 100644 --- a/src/Engine/Graphics/Vulkan/VulkanPipelineCache.h +++ b/src/Engine/Graphics/Vulkan/PipelineCache.h @@ -1,5 +1,5 @@ #pragma once -#include "VulkanPipeline.h" +#include "Pipeline.h" namespace Seele { @@ -10,14 +10,13 @@ class PipelineCache public: PipelineCache(PGraphics graphics, const std::string& cacheFilePath); ~PipelineCache(); - PGraphicsPipeline createPipeline(const GraphicsPipelineCreateInfo& createInfo); - PComputePipeline createPipeline(const ComputePipelineCreateInfo& createInfo); + PGraphicsPipeline createPipeline(const Gfx::LegacyPipelineCreateInfo& createInfo); + PGraphicsPipeline createPipeline(const Gfx::MeshPipelineCreateInfo& createInfo); + PComputePipeline createPipeline(const Gfx::ComputePipelineCreateInfo& createInfo); private: VkPipelineCache cache; PGraphics graphics; std::string cacheFile; - std::mutex createdPipelinesLock; - Map createdPipelines; }; DEFINE_REF(PipelineCache) } // namespace Vulkan diff --git a/src/Engine/Graphics/Vulkan/VulkanQueue.cpp b/src/Engine/Graphics/Vulkan/Queue.cpp similarity index 90% rename from src/Engine/Graphics/Vulkan/VulkanQueue.cpp rename to src/Engine/Graphics/Vulkan/Queue.cpp index 4dae95e..690e566 100644 --- a/src/Engine/Graphics/Vulkan/VulkanQueue.cpp +++ b/src/Engine/Graphics/Vulkan/Queue.cpp @@ -1,9 +1,8 @@ -#include "VulkanQueue.h" -#include "VulkanInitializer.h" -#include "VulkanGraphics.h" -#include "VulkanAllocator.h" -#include "VulkanCommandBuffer.h" -#include "VulkanGraphicsEnums.h" +#include "Queue.h" +#include "Initializer.h" +#include "Graphics.h" +#include "Allocator.h" +#include "CommandBuffer.h" using namespace Seele; using namespace Seele::Vulkan; diff --git a/src/Engine/Graphics/Vulkan/VulkanQueue.h b/src/Engine/Graphics/Vulkan/Queue.h similarity index 95% rename from src/Engine/Graphics/Vulkan/VulkanQueue.h rename to src/Engine/Graphics/Vulkan/Queue.h index 3dda53b..50a100f 100644 --- a/src/Engine/Graphics/Vulkan/VulkanQueue.h +++ b/src/Engine/Graphics/Vulkan/Queue.h @@ -1,5 +1,5 @@ #pragma once -#include "VulkanGraphicsResources.h" +#include "Resources.h" namespace Seele { diff --git a/src/Engine/Graphics/Vulkan/VulkanRenderPass.cpp b/src/Engine/Graphics/Vulkan/RenderPass.cpp similarity index 97% rename from src/Engine/Graphics/Vulkan/VulkanRenderPass.cpp rename to src/Engine/Graphics/Vulkan/RenderPass.cpp index ab0d914..6632c7b 100644 --- a/src/Engine/Graphics/Vulkan/VulkanRenderPass.cpp +++ b/src/Engine/Graphics/Vulkan/RenderPass.cpp @@ -1,8 +1,8 @@ -#include "VulkanRenderPass.h" -#include "VulkanInitializer.h" -#include "VulkanGraphicsEnums.h" -#include "VulkanGraphics.h" -#include "VulkanFramebuffer.h" +#include "RenderPass.h" +#include "Initializer.h" +#include "Graphics.h" +#include "Framebuffer.h" +#include "Texture.h" using namespace Seele; using namespace Seele::Vulkan; diff --git a/src/Engine/Graphics/Vulkan/VulkanRenderPass.h b/src/Engine/Graphics/Vulkan/RenderPass.h similarity index 94% rename from src/Engine/Graphics/Vulkan/VulkanRenderPass.h rename to src/Engine/Graphics/Vulkan/RenderPass.h index 945e985..f9d292c 100644 --- a/src/Engine/Graphics/Vulkan/VulkanRenderPass.h +++ b/src/Engine/Graphics/Vulkan/RenderPass.h @@ -1,5 +1,6 @@ #pragma once -#include "VulkanGraphicsResources.h" +#include "Graphics/RenderTarget.h" +#include "Graphics.h" namespace Seele { diff --git a/src/Engine/Graphics/Vulkan/VulkanViewport.cpp b/src/Engine/Graphics/Vulkan/RenderTarget.cpp similarity index 100% rename from src/Engine/Graphics/Vulkan/VulkanViewport.cpp rename to src/Engine/Graphics/Vulkan/RenderTarget.cpp diff --git a/src/Engine/Graphics/Vulkan/RenderTarget.h b/src/Engine/Graphics/Vulkan/RenderTarget.h new file mode 100644 index 0000000..a173d1a --- /dev/null +++ b/src/Engine/Graphics/Vulkan/RenderTarget.h @@ -0,0 +1,83 @@ +#pragma once +#include "Graphics/RenderTarget.h" +#include "Graphics.h" +#include "Texture.h" +#include "Resources.h" + +namespace Seele +{ +namespace Vulkan +{ + +class Window : public Gfx::Window +{ +public: + Window(PGraphics graphics, const WindowCreateInfo &createInfo); + virtual ~Window(); + virtual void beginFrame() override; + virtual void endFrame() override; + virtual Gfx::PTexture2D getBackBuffer() const override; + virtual void onWindowCloseEvent() override; + virtual void setKeyCallback(std::function callback) override; + virtual void setMouseMoveCallback(std::function callback) override; + virtual void setMouseButtonCallback(std::function callback) override; + virtual void setScrollCallback(std::function callback) override; + virtual void setFileCallback(std::function callback) override; + virtual void setCloseCallback(std::function callback); + + VkFormat getPixelFormat() const + { + return cast(windowState.pixelFormat); + } + + std::function keyCallback; + std::function mouseMoveCallback; + std::function mouseButtonCallback; + std::function scrollCallback; + std::function fileCallback; + std::function closeCallback; +protected: + void advanceBackBuffer(); + void recreateSwapchain(const WindowCreateInfo &createInfo); + void present(); + void destroySwapchain(); + void createSwapchain(); + void chooseSurfaceFormat(const Array &available, Gfx::SeFormat preferred); + void choosePresentMode(const Array &modes); + + PTexture2D backBufferImages[Gfx::numFramesBuffered]; + PSemaphore renderFinished[Gfx::numFramesBuffered]; + PSemaphore imageAcquired[Gfx::numFramesBuffered]; + PSemaphore imageAcquiredSemaphore; + + PGraphics graphics; + VkInstance instance; + VkSwapchainKHR swapchain; + VkSampleCountFlags numSamples; + VkPresentModeKHR presentMode; + VkSurfaceKHR surface; + VkSurfaceFormatKHR surfaceFormat; + void *windowHandle; + int32 currentImageIndex; + int32 acquiredImageIndex; + int32 preAcquiredImageIndex; + int32 semaphoreIndex; +}; +DEFINE_REF(Window) + +class Viewport : public Gfx::Viewport +{ +public: + Viewport(PGraphics graphics, PWindow owner, const ViewportCreateInfo &createInfo); + virtual ~Viewport(); + virtual void resize(uint32 newX, uint32 newY); + virtual void move(uint32 newOffsetX, uint32 newOffsetY); + VkViewport getHandle() const { return handle; } +private: + VkViewport handle; + PGraphics graphics; + friend class Graphics; +}; +DECLARE_REF(Viewport) +} +} \ No newline at end of file diff --git a/src/Engine/Graphics/Vulkan/VulkanGraphicsResources.cpp b/src/Engine/Graphics/Vulkan/Resources.cpp similarity index 100% rename from src/Engine/Graphics/Vulkan/VulkanGraphicsResources.cpp rename to src/Engine/Graphics/Vulkan/Resources.cpp diff --git a/src/Engine/Graphics/Vulkan/Resources.h b/src/Engine/Graphics/Vulkan/Resources.h new file mode 100644 index 0000000..401155f --- /dev/null +++ b/src/Engine/Graphics/Vulkan/Resources.h @@ -0,0 +1,80 @@ +#pragma once +#include +#include +#include "Graphics/Resources.h" +#include "Allocator.h" + +namespace Seele +{ +namespace Vulkan +{ + +DECLARE_REF(DescriptorAllocator) +DECLARE_REF(CommandBufferManager) +DECLARE_REF(CmdBuffer) +DECLARE_REF(Graphics) +DECLARE_REF(SubAllocation) +class Semaphore +{ +public: + Semaphore(PGraphics graphics); + virtual ~Semaphore(); + inline VkSemaphore getHandle() const + { + return handle; + } + +private: + VkSemaphore handle; + PGraphics graphics; +}; +DEFINE_REF(Semaphore) + +class Fence +{ +public: + Fence(PGraphics graphics); + ~Fence(); + bool isSignaled(); + void reset(); + inline VkFence getHandle() const + { + return fence; + } + void wait(uint32 timeout); + /*Event& operator co_await() + { + return signaled; + }*/ + bool operator<(const Fence &other) const + { + return fence < other.fence; + } + +private: + PGraphics graphics; + bool signaled; + VkFence fence; +}; +DEFINE_REF(Fence) + +class VertexDeclaration : public Gfx::VertexDeclaration +{ +public: + Array elementList; + + VertexDeclaration(const Array& elementList); + virtual ~VertexDeclaration(); +private: +}; +DEFINE_REF(VertexDeclaration) + +class SamplerState : public Gfx::SamplerState +{ +public: + VkSampler sampler; +}; +DEFINE_REF(SamplerState) + +} // namespace Vulkan +} // namespace Seele diff --git a/src/Engine/Graphics/Vulkan/VulkanShader.cpp b/src/Engine/Graphics/Vulkan/Shader.cpp similarity index 100% rename from src/Engine/Graphics/Vulkan/VulkanShader.cpp rename to src/Engine/Graphics/Vulkan/Shader.cpp diff --git a/src/Engine/Graphics/Vulkan/VulkanShader.h b/src/Engine/Graphics/Vulkan/Shader.h similarity index 75% rename from src/Engine/Graphics/Vulkan/VulkanShader.h rename to src/Engine/Graphics/Vulkan/Shader.h index 1d9012c..d85d831 100644 --- a/src/Engine/Graphics/Vulkan/VulkanShader.h +++ b/src/Engine/Graphics/Vulkan/Shader.h @@ -1,6 +1,7 @@ #pragma once -#include "VulkanGraphicsResources.h" -#include "VulkanGraphicsEnums.h" +#include "Resources.h" +#include "Enums.h" +#include "Graphics/Shader.h" namespace Seele { @@ -51,18 +52,16 @@ public: } }; typedef ShaderBase VertexShader; -typedef ShaderBase ControlShader; -typedef ShaderBase EvaluationShader; -typedef ShaderBase GeometryShader; typedef ShaderBase FragmentShader; typedef ShaderBase ComputeShader; +typedef ShaderBase TaskShader; +typedef ShaderBase MeshShader; DEFINE_REF(VertexShader) -DEFINE_REF(ControlShader) -DEFINE_REF(EvaluationShader) -DEFINE_REF(GeometryShader) DEFINE_REF(FragmentShader) DEFINE_REF(ComputeShader) +DEFINE_REF(TaskShader) +DEFINE_REF(MeshShader) } // namespace Vulkan } \ No newline at end of file diff --git a/src/Engine/Graphics/Vulkan/VulkanTexture.cpp b/src/Engine/Graphics/Vulkan/Texture.cpp similarity index 100% rename from src/Engine/Graphics/Vulkan/VulkanTexture.cpp rename to src/Engine/Graphics/Vulkan/Texture.cpp diff --git a/src/Engine/Graphics/Vulkan/Texture.h b/src/Engine/Graphics/Vulkan/Texture.h new file mode 100644 index 0000000..5c81c47 --- /dev/null +++ b/src/Engine/Graphics/Vulkan/Texture.h @@ -0,0 +1,264 @@ +#pragma once +#include "Graphics/Texture.h" +#include "Graphics.h" +#include "Allocator.h" + +namespace Seele +{ +namespace Vulkan +{ + +class TextureHandle +{ +public: + TextureHandle(PGraphics graphics, VkImageViewType viewType, + const TextureCreateInfo& createInfo, Gfx::QueueType& owner, VkImage existingImage = VK_NULL_HANDLE); + virtual ~TextureHandle(); + + inline VkImage getImage() const + { + return image; + } + inline VkImageView getView() const + { + return defaultView; + } + inline Gfx::SeImageLayout getLayout() const + { + return layout; + } + inline VkImageAspectFlags getAspect() const + { + return aspect; + } + inline VkImageUsageFlags getUsage() const + { + return usage; + } + inline Gfx::SeFormat getFormat() const + { + return format; + } + inline Gfx::SeSampleCountFlags getNumSamples() const + { + return samples; + } + inline uint32 getMipLevels() const + { + return mipLevels; + } + inline bool isDepthStencil() const + { + return aspect & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT); + } + void executeOwnershipBarrier(Gfx::QueueType newOwner); + void executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage, + VkAccessFlags dstAccess, VkPipelineStageFlags dstStage); + void changeLayout(Gfx::SeImageLayout newLayout); + void download(uint32 mipLevel, uint32 arrayLayer, uint32 face, Array& buffer); + +private: + //Updates via reference + Gfx::QueueType& currentOwner; + PGraphics graphics; + PSubAllocation allocation; + uint32 sizeX; + uint32 sizeY; + uint32 sizeZ; + uint32 arrayCount; + uint32 layerCount; + uint32 mipLevels; + uint32 samples; + Gfx::SeFormat format; + Gfx::SeImageUsageFlags usage; + VkImage image; + VkImageView defaultView; + VkImageAspectFlags aspect; + Gfx::SeImageLayout layout; + friend class TextureBase; + friend class Texture2D; + friend class Texture3D; + friend class TextureCube; + friend class Graphics; +}; + +class TextureBase +{ +public: + static TextureHandle* cast(Gfx::PTexture texture); + +protected: + TextureHandle* textureHandle; + friend class Graphics; +}; +DECLARE_REF(TextureBase) +class Texture2D : public Gfx::Texture2D, public TextureBase +{ +public: + Texture2D(PGraphics graphics, const TextureCreateInfo& createInfo, VkImage existingImage = VK_NULL_HANDLE); + virtual ~Texture2D(); + virtual uint32 getSizeX() const override + { + return textureHandle->sizeX; + } + virtual uint32 getSizeY() const override + { + return textureHandle->sizeY; + } + virtual uint32 getSizeZ() const override + { + return textureHandle->sizeZ; + } + virtual Gfx::SeFormat getFormat() const override + { + return textureHandle->format; + } + virtual Gfx::SeSampleCountFlags getNumSamples() const override + { + return textureHandle->getNumSamples(); + } + virtual uint32 getMipLevels() const override + { + return textureHandle->getMipLevels(); + } + virtual void changeLayout(Gfx::SeImageLayout newLayout) override; + virtual void download(uint32 mipLevel, uint32 arrayLayer, uint32 face, Array& buffer) override; + virtual void* getNativeHandle() override + { + return textureHandle; + } + inline VkImage getHandle() const + { + return textureHandle->image; + } + inline VkImageView getView() const + { + return textureHandle->defaultView; + } + inline bool isDepthStencil() const + { + return textureHandle->isDepthStencil(); + } +protected: + // Inherited via QueueOwnedResource + virtual void executeOwnershipBarrier(Gfx::QueueType newOwner); + virtual void executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage, + VkAccessFlags dstAccess, VkPipelineStageFlags dstStage); + +}; +DEFINE_REF(Texture2D) + +class Texture3D : public Gfx::Texture3D, public TextureBase +{ +public: + Texture3D(PGraphics graphics, const TextureCreateInfo& createInfo, VkImage existingImage = VK_NULL_HANDLE); + virtual ~Texture3D(); + virtual uint32 getSizeX() const override + { + return textureHandle->sizeX; + } + virtual uint32 getSizeY() const override + { + return textureHandle->sizeY; + } + virtual uint32 getSizeZ() const override + { + return textureHandle->sizeZ; + } + virtual Gfx::SeFormat getFormat() const override + { + return textureHandle->format; + } + virtual Gfx::SeSampleCountFlags getNumSamples() const override + { + return textureHandle->getNumSamples(); + } + virtual uint32 getMipLevels() const override + { + return textureHandle->getMipLevels(); + } + virtual void changeLayout(Gfx::SeImageLayout newLayout) override; + virtual void download(uint32 mipLevel, uint32 arrayLayer, uint32 face, Array& buffer) override; + virtual void* getNativeHandle() override + { + return textureHandle; + } + inline VkImage getHandle() const + { + return textureHandle->image; + } + inline VkImageView getView() const + { + return textureHandle->defaultView; + } + inline bool isDepthStencil() const + { + return textureHandle->isDepthStencil(); + } +protected: + // Inherited via QueueOwnedResource + virtual void executeOwnershipBarrier(Gfx::QueueType newOwner); + virtual void executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage, + VkAccessFlags dstAccess, VkPipelineStageFlags dstStage); + +}; +DEFINE_REF(Texture3D) + +class TextureCube : public Gfx::TextureCube, public TextureBase +{ +public: + TextureCube(PGraphics graphics, const TextureCreateInfo& createInfo, VkImage existingImage = VK_NULL_HANDLE); + virtual ~TextureCube(); + virtual uint32 getSizeX() const override + { + return textureHandle->sizeX; + } + virtual uint32 getSizeY() const override + { + return textureHandle->sizeY; + } + virtual uint32 getSizeZ() const override + { + return textureHandle->sizeZ; + } + virtual Gfx::SeFormat getFormat() const override + { + return textureHandle->format; + } + virtual Gfx::SeSampleCountFlags getNumSamples() const override + { + return textureHandle->getNumSamples(); + } + virtual uint32 getMipLevels() const override + { + return textureHandle->getMipLevels(); + } + virtual void changeLayout(Gfx::SeImageLayout newLayout) override; + virtual void download(uint32 mipLevel, uint32 arrayLayer, uint32 face, Array& buffer) override; + virtual void* getNativeHandle() override + { + return textureHandle; + } + inline VkImage getHandle() const + { + return textureHandle->image; + } + inline VkImageView getView() const + { + return textureHandle->defaultView; + } + inline bool isDepthStencil() const + { + return textureHandle->isDepthStencil(); + } +protected: + // Inherited via QueueOwnedResource + virtual void executeOwnershipBarrier(Gfx::QueueType newOwner); + virtual void executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage, + VkAccessFlags dstAccess, VkPipelineStageFlags dstStage); + +}; +DEFINE_REF(TextureCube) + +} +} \ No newline at end of file diff --git a/src/Engine/Graphics/Vulkan/VulkanGraphicsResources.h b/src/Engine/Graphics/Vulkan/VulkanGraphicsResources.h deleted file mode 100644 index a185806..0000000 --- a/src/Engine/Graphics/Vulkan/VulkanGraphicsResources.h +++ /dev/null @@ -1,535 +0,0 @@ -#pragma once -#include -#include -#include "Graphics/GraphicsResources.h" -#include "VulkanAllocator.h" - -namespace Seele -{ -namespace Vulkan -{ - -DECLARE_REF(DescriptorAllocator) -DECLARE_REF(CommandBufferManager) -DECLARE_REF(CmdBuffer) -DECLARE_REF(Graphics) -DECLARE_REF(SubAllocation) -class Semaphore -{ -public: - Semaphore(PGraphics graphics); - virtual ~Semaphore(); - inline VkSemaphore getHandle() const - { - return handle; - } - -private: - VkSemaphore handle; - PGraphics graphics; -}; -DEFINE_REF(Semaphore) - -class Fence -{ -public: - Fence(PGraphics graphics); - ~Fence(); - bool isSignaled(); - void reset(); - inline VkFence getHandle() const - { - return fence; - } - void wait(uint32 timeout); - /*Event& operator co_await() - { - return signaled; - }*/ - bool operator<(const Fence &other) const - { - return fence < other.fence; - } - -private: - PGraphics graphics; - bool signaled; - VkFence fence; -}; -DEFINE_REF(Fence) - -class VertexDeclaration : public Gfx::VertexDeclaration -{ -public: - Array elementList; - - VertexDeclaration(const Array& elementList); - virtual ~VertexDeclaration(); -private: -}; -DEFINE_REF(VertexDeclaration) - -class ShaderBuffer -{ -public: - ShaderBuffer(PGraphics graphics, uint64 size, VkBufferUsageFlags usage, Gfx::QueueType& queueType, bool bDynamic = false); - virtual ~ShaderBuffer(); - VkBuffer getHandle() const - { - return buffers[currentBuffer].buffer; - } - uint64 getSize() const - { - return size; - } - VkDeviceSize getOffset() const; - void advanceBuffer() - { - currentBuffer = (currentBuffer + 1) % numBuffers; - } - virtual void *lock(bool bWriteOnly = true); - virtual void *lockRegion(uint64 regionOffset, uint64 regionSize, bool bWriteOnly = true); - virtual void unlock(); - -protected: - struct BufferAllocation - { - VkBuffer buffer; - PSubAllocation allocation; - }; - PGraphics graphics; - uint32 currentBuffer; - uint64 size; - Gfx::QueueType& owner; - BufferAllocation buffers[Gfx::numFramesBuffered]; - uint32 numBuffers; - - void executeOwnershipBarrier(Gfx::QueueType newOwner); - void executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage, - VkAccessFlags dstAccess, VkPipelineStageFlags dstStage); - - virtual void requestOwnershipTransfer(Gfx::QueueType newOwner) = 0; - - virtual VkAccessFlags getSourceAccessMask() = 0; - virtual VkAccessFlags getDestAccessMask() = 0; -}; -DEFINE_REF(ShaderBuffer) - -DECLARE_REF(StagingBuffer) -class UniformBuffer : public Gfx::UniformBuffer, public ShaderBuffer -{ -public: - UniformBuffer(PGraphics graphics, const UniformBufferCreateInfo &resourceData); - virtual ~UniformBuffer(); - virtual bool updateContents(const BulkResourceData &resourceData); - - virtual void* lock(bool bWriteOnly = true) override; - virtual void unlock() override; -protected: - // Inherited via Vulkan::Buffer - virtual VkAccessFlags getSourceAccessMask(); - virtual VkAccessFlags getDestAccessMask(); - virtual void requestOwnershipTransfer(Gfx::QueueType newOwner); - // Inherited via QueueOwnedResource - virtual void executeOwnershipBarrier(Gfx::QueueType newOwner); - virtual void executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage, - VkAccessFlags dstAccess, VkPipelineStageFlags dstStage); - -private: - PStagingBuffer dedicatedStagingBuffer; -}; -DEFINE_REF(UniformBuffer) - -class ShaderBuffer : public Gfx::ShaderBuffer, public ShaderBuffer -{ -public: - ShaderBuffer(PGraphics graphics, const ShaderBufferCreateInfo &resourceData); - virtual ~ShaderBuffer(); - virtual bool updateContents(const BulkResourceData &resourceData); - - virtual void* lock(bool bWriteOnly = true) override; - virtual void unlock() override; -protected: - // Inherited via Vulkan::Buffer - virtual VkAccessFlags getSourceAccessMask(); - virtual VkAccessFlags getDestAccessMask(); - virtual void requestOwnershipTransfer(Gfx::QueueType newOwner); - // Inherited via QueueOwnedResource - virtual void executeOwnershipBarrier(Gfx::QueueType newOwner); - virtual void executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage, - VkAccessFlags dstAccess, VkPipelineStageFlags dstStage); -private: - PStagingBuffer dedicatedStagingBuffer; -}; -DEFINE_REF(ShaderBuffer) - -class VertexBuffer : public Gfx::VertexBuffer, public ShaderBuffer -{ -public: - VertexBuffer(PGraphics graphics, const VertexBufferCreateInfo &resourceData); - virtual ~VertexBuffer(); - - virtual void updateRegion(BulkResourceData update) override; - virtual void download(Array& buffer) override; -protected: - // Inherited via Vulkan::Buffer - virtual VkAccessFlags getSourceAccessMask(); - virtual VkAccessFlags getDestAccessMask(); - virtual void requestOwnershipTransfer(Gfx::QueueType newOwner); - // Inherited via QueueOwnedResource - virtual void executeOwnershipBarrier(Gfx::QueueType newOwner); - virtual void executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage, - VkAccessFlags dstAccess, VkPipelineStageFlags dstStage); -}; -DEFINE_REF(VertexBuffer) - -class IndexBuffer : public Gfx::IndexBuffer, public ShaderBuffer -{ -public: - IndexBuffer(PGraphics graphics, const IndexBufferCreateInfo &resourceData); - virtual ~IndexBuffer(); - - virtual void download(Array& buffer) override; -protected: - // Inherited via Vulkan::Buffer - virtual VkAccessFlags getSourceAccessMask(); - virtual VkAccessFlags getDestAccessMask(); - virtual void requestOwnershipTransfer(Gfx::QueueType newOwner); - // Inherited via QueueOwnedResource - virtual void executeOwnershipBarrier(Gfx::QueueType newOwner); - virtual void executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage, - VkAccessFlags dstAccess, VkPipelineStageFlags dstStage); -}; -DEFINE_REF(IndexBuffer) - -class TextureHandle -{ -public: - TextureHandle(PGraphics graphics, VkImageViewType viewType, - const TextureCreateInfo& createInfo, Gfx::QueueType& owner, VkImage existingImage = VK_NULL_HANDLE); - virtual ~TextureHandle(); - - inline VkImage getImage() const - { - return image; - } - inline VkImageView getView() const - { - return defaultView; - } - inline Gfx::SeImageLayout getLayout() const - { - return layout; - } - inline VkImageAspectFlags getAspect() const - { - return aspect; - } - inline VkImageUsageFlags getUsage() const - { - return usage; - } - inline Gfx::SeFormat getFormat() const - { - return format; - } - inline Gfx::SeSampleCountFlags getNumSamples() const - { - return samples; - } - inline uint32 getMipLevels() const - { - return mipLevels; - } - inline bool isDepthStencil() const - { - return aspect & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT); - } - void executeOwnershipBarrier(Gfx::QueueType newOwner); - void executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage, - VkAccessFlags dstAccess, VkPipelineStageFlags dstStage); - void changeLayout(Gfx::SeImageLayout newLayout); - void download(uint32 mipLevel, uint32 arrayLayer, uint32 face, Array& buffer); - -private: - //Updates via reference - Gfx::QueueType& currentOwner; - PGraphics graphics; - PSubAllocation allocation; - uint32 sizeX; - uint32 sizeY; - uint32 sizeZ; - uint32 arrayCount; - uint32 layerCount; - uint32 mipLevels; - uint32 samples; - Gfx::SeFormat format; - Gfx::SeImageUsageFlags usage; - VkImage image; - VkImageView defaultView; - VkImageAspectFlags aspect; - Gfx::SeImageLayout layout; - friend class TextureBase; - friend class Texture2D; - friend class Texture3D; - friend class TextureCube; - friend class Graphics; -}; - -class TextureBase -{ -public: - static TextureHandle* cast(Gfx::PTexture texture); - -protected: - TextureHandle* textureHandle; - friend class Graphics; -}; -DECLARE_REF(TextureBase) -class Texture2D : public Gfx::Texture2D, public TextureBase -{ -public: - Texture2D(PGraphics graphics, const TextureCreateInfo& createInfo, VkImage existingImage = VK_NULL_HANDLE); - virtual ~Texture2D(); - virtual uint32 getSizeX() const override - { - return textureHandle->sizeX; - } - virtual uint32 getSizeY() const override - { - return textureHandle->sizeY; - } - virtual uint32 getSizeZ() const override - { - return textureHandle->sizeZ; - } - virtual Gfx::SeFormat getFormat() const override - { - return textureHandle->format; - } - virtual Gfx::SeSampleCountFlags getNumSamples() const override - { - return textureHandle->getNumSamples(); - } - virtual uint32 getMipLevels() const override - { - return textureHandle->getMipLevels(); - } - virtual void changeLayout(Gfx::SeImageLayout newLayout) override; - virtual void download(uint32 mipLevel, uint32 arrayLayer, uint32 face, Array& buffer) override; - virtual void* getNativeHandle() override - { - return textureHandle; - } - inline VkImage getHandle() const - { - return textureHandle->image; - } - inline VkImageView getView() const - { - return textureHandle->defaultView; - } - inline bool isDepthStencil() const - { - return textureHandle->isDepthStencil(); - } -protected: - // Inherited via QueueOwnedResource - virtual void executeOwnershipBarrier(Gfx::QueueType newOwner); - virtual void executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage, - VkAccessFlags dstAccess, VkPipelineStageFlags dstStage); - -}; -DEFINE_REF(Texture2D) - -class Texture3D : public Gfx::Texture3D, public TextureBase -{ -public: - Texture3D(PGraphics graphics, const TextureCreateInfo& createInfo, VkImage existingImage = VK_NULL_HANDLE); - virtual ~Texture3D(); - virtual uint32 getSizeX() const override - { - return textureHandle->sizeX; - } - virtual uint32 getSizeY() const override - { - return textureHandle->sizeY; - } - virtual uint32 getSizeZ() const override - { - return textureHandle->sizeZ; - } - virtual Gfx::SeFormat getFormat() const override - { - return textureHandle->format; - } - virtual Gfx::SeSampleCountFlags getNumSamples() const override - { - return textureHandle->getNumSamples(); - } - virtual uint32 getMipLevels() const override - { - return textureHandle->getMipLevels(); - } - virtual void changeLayout(Gfx::SeImageLayout newLayout) override; - virtual void download(uint32 mipLevel, uint32 arrayLayer, uint32 face, Array& buffer) override; - virtual void* getNativeHandle() override - { - return textureHandle; - } - inline VkImage getHandle() const - { - return textureHandle->image; - } - inline VkImageView getView() const - { - return textureHandle->defaultView; - } - inline bool isDepthStencil() const - { - return textureHandle->isDepthStencil(); - } -protected: - // Inherited via QueueOwnedResource - virtual void executeOwnershipBarrier(Gfx::QueueType newOwner); - virtual void executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage, - VkAccessFlags dstAccess, VkPipelineStageFlags dstStage); - -}; -DEFINE_REF(Texture3D) - -class TextureCube : public Gfx::TextureCube, public TextureBase -{ -public: - TextureCube(PGraphics graphics, const TextureCreateInfo& createInfo, VkImage existingImage = VK_NULL_HANDLE); - virtual ~TextureCube(); - virtual uint32 getSizeX() const override - { - return textureHandle->sizeX; - } - virtual uint32 getSizeY() const override - { - return textureHandle->sizeY; - } - virtual uint32 getSizeZ() const override - { - return textureHandle->sizeZ; - } - virtual Gfx::SeFormat getFormat() const override - { - return textureHandle->format; - } - virtual Gfx::SeSampleCountFlags getNumSamples() const override - { - return textureHandle->getNumSamples(); - } - virtual uint32 getMipLevels() const override - { - return textureHandle->getMipLevels(); - } - virtual void changeLayout(Gfx::SeImageLayout newLayout) override; - virtual void download(uint32 mipLevel, uint32 arrayLayer, uint32 face, Array& buffer) override; - virtual void* getNativeHandle() override - { - return textureHandle; - } - inline VkImage getHandle() const - { - return textureHandle->image; - } - inline VkImageView getView() const - { - return textureHandle->defaultView; - } - inline bool isDepthStencil() const - { - return textureHandle->isDepthStencil(); - } -protected: - // Inherited via QueueOwnedResource - virtual void executeOwnershipBarrier(Gfx::QueueType newOwner); - virtual void executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage, - VkAccessFlags dstAccess, VkPipelineStageFlags dstStage); - -}; -DEFINE_REF(TextureCube) - -class SamplerState : public Gfx::SamplerState -{ -public: - VkSampler sampler; -}; -DEFINE_REF(SamplerState) - -class Window : public Gfx::Window -{ -public: - Window(PGraphics graphics, const WindowCreateInfo &createInfo); - virtual ~Window(); - virtual void beginFrame() override; - virtual void endFrame() override; - virtual Gfx::PTexture2D getBackBuffer() const override; - virtual void onWindowCloseEvent() override; - virtual void setKeyCallback(std::function callback) override; - virtual void setMouseMoveCallback(std::function callback) override; - virtual void setMouseButtonCallback(std::function callback) override; - virtual void setScrollCallback(std::function callback) override; - virtual void setFileCallback(std::function callback) override; - virtual void setCloseCallback(std::function callback); - - VkFormat getPixelFormat() const - { - return cast(windowState.pixelFormat); - } - - std::function keyCallback; - std::function mouseMoveCallback; - std::function mouseButtonCallback; - std::function scrollCallback; - std::function fileCallback; - std::function closeCallback; -protected: - void advanceBackBuffer(); - void recreateSwapchain(const WindowCreateInfo &createInfo); - void present(); - void destroySwapchain(); - void createSwapchain(); - void chooseSurfaceFormat(const Array &available, Gfx::SeFormat preferred); - void choosePresentMode(const Array &modes); - - PTexture2D backBufferImages[Gfx::numFramesBuffered]; - PSemaphore renderFinished[Gfx::numFramesBuffered]; - PSemaphore imageAcquired[Gfx::numFramesBuffered]; - PSemaphore imageAcquiredSemaphore; - - PGraphics graphics; - VkInstance instance; - VkSwapchainKHR swapchain; - VkSampleCountFlags numSamples; - VkPresentModeKHR presentMode; - VkSurfaceKHR surface; - VkSurfaceFormatKHR surfaceFormat; - void *windowHandle; - int32 currentImageIndex; - int32 acquiredImageIndex; - int32 preAcquiredImageIndex; - int32 semaphoreIndex; -}; -DEFINE_REF(Window) - -class Viewport : public Gfx::Viewport -{ -public: - Viewport(PGraphics graphics, PWindow owner, const ViewportCreateInfo &createInfo); - virtual ~Viewport(); - virtual void resize(uint32 newX, uint32 newY); - virtual void move(uint32 newOffsetX, uint32 newOffsetY); - VkViewport getHandle() const { return handle; } -private: - VkViewport handle; - PGraphics graphics; - friend class Graphics; -}; -DECLARE_REF(Viewport) -} // namespace Vulkan -} // namespace Seele diff --git a/src/Engine/Graphics/Vulkan/VulkanPipelineCache.cpp b/src/Engine/Graphics/Vulkan/VulkanPipelineCache.cpp deleted file mode 100644 index 10edf3c..0000000 --- a/src/Engine/Graphics/Vulkan/VulkanPipelineCache.cpp +++ /dev/null @@ -1,381 +0,0 @@ -#include "VulkanPipelineCache.h" -#include "VulkanGraphics.h" -#include "VulkanGraphicsEnums.h" -#include "VulkanInitializer.h" -#include "VulkanRenderPass.h" -#include "VulkanDescriptorSets.h" -#include "VulkanShader.h" -#include - -using namespace Seele; -using namespace Seele::Vulkan; - -PipelineCache::PipelineCache(PGraphics graphics, const std::string& cacheFilePath) - : graphics(graphics) - , cacheFile(cacheFilePath) -{ - std::ifstream stream(cacheFilePath, std::ios::binary | std::ios::ate); - VkPipelineCacheCreateInfo cacheCreateInfo; - cacheCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO; - cacheCreateInfo.pNext = nullptr; - cacheCreateInfo.flags = 0; - cacheCreateInfo.initialDataSize = 0; - if(stream.good()) - { - Array cacheData; - uint32 fileSize = static_cast(stream.tellg()); - cacheData.resize(fileSize); - stream.seekg(0); - stream.read((char*)cacheData.data(), fileSize); - cacheCreateInfo.initialDataSize = fileSize; - cacheCreateInfo.pInitialData = cacheData.data(); - std::cout << "Loaded " << fileSize << " bytes from pipeline cache" << std::endl; - } - VK_CHECK(vkCreatePipelineCache(graphics->getDevice(), &cacheCreateInfo, nullptr, &cache)); -} - -PipelineCache::~PipelineCache() -{ - VkDeviceSize cacheSize; - vkGetPipelineCacheData(graphics->getDevice(), cache, &cacheSize, nullptr); - Array cacheData; - vkGetPipelineCacheData(graphics->getDevice(), cache, &cacheSize, cacheData.data()); - std::ofstream stream(cacheFile, std::ios::binary); - stream.write((char*)cacheData.data(), cacheSize); - stream.flush(); - stream.close(); - vkDestroyPipelineCache(graphics->getDevice(), cache, nullptr); - std::cout << "Written " << cacheSize << " bytes to cache" << std::endl; -} - -struct PipelineCreateHashStruct -{ - uint32 vertexHash; - uint32 controlHash; - uint32 evalHash; - uint32 geometryHash; - uint32 fragmentHash; - uint32 pipelineLayoutHash; - VkPipelineTessellationStateCreateInfo tess; - VkVertexInputAttributeDescription attribs[16]; - VkVertexInputBindingDescription bindings[16]; - VkPipelineInputAssemblyStateCreateInfo inputAssembly; - VkPipelineViewportStateCreateInfo viewport; - VkPipelineRasterizationStateCreateInfo rasterization; - VkPipelineMultisampleStateCreateInfo multisample; - VkPipelineDepthStencilStateCreateInfo depthStencil; - VkPipelineColorBlendAttachmentState blendAttachments[16]; - VkPipelineColorBlendStateCreateInfo blendState; -}; - -PGraphicsPipeline PipelineCache::createPipeline(const GraphicsPipelineCreateInfo& gfxInfo) -{ - VkGraphicsPipelineCreateInfo createInfo; - createInfo.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO; - createInfo.pNext = 0; - createInfo.flags = 0; - createInfo.stageCount = 0; - - VkPipelineTessellationStateCreateInfo tessInfo; - std::memset(&tessInfo, 0, sizeof(VkPipelineTessellationStateCreateInfo)); - VkPipelineShaderStageCreateInfo stageInfos[5]; - std::memset(stageInfos, 0, sizeof(stageInfos)); - PipelineCreateHashStruct hashStruct; - std::memset(&hashStruct, 0, sizeof(PipelineCreateHashStruct)); - - PVertexShader vertexShader = gfxInfo.vertexShader.cast(); - VkPipelineShaderStageCreateInfo& vertInfo = stageInfos[createInfo.stageCount++]; - vertInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; - vertInfo.stage = VK_SHADER_STAGE_VERTEX_BIT; - vertInfo.module = vertexShader->getModuleHandle(); - vertInfo.pName = vertexShader->getEntryPointName(); - hashStruct.vertexHash = vertexShader->getShaderHash(); - - if(gfxInfo.controlShader != nullptr) - { - assert(gfxInfo.evalShader != nullptr); - PControlShader control = gfxInfo.controlShader.cast(); - PEvaluationShader eval = gfxInfo.evalShader.cast(); - - VkPipelineShaderStageCreateInfo& controlInfo = stageInfos[createInfo.stageCount++]; - controlInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; - controlInfo.stage = VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT; - controlInfo.module = control->getModuleHandle(); - controlInfo.pName = control->getEntryPointName(); - - VkPipelineShaderStageCreateInfo& evalInfo = stageInfos[createInfo.stageCount++]; - evalInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; - evalInfo.stage = VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT; - evalInfo.module = eval->getModuleHandle(); - evalInfo.pName = eval->getEntryPointName(); - - tessInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO; - tessInfo.pNext = 0; - tessInfo.flags = 0; - tessInfo.patchControlPoints = control->getNumPatches(); - - hashStruct.controlHash = control->getShaderHash(); - hashStruct.evalHash = eval->getShaderHash(); - hashStruct.tess = tessInfo; - } - if(gfxInfo.geometryShader != nullptr) - { - PGeometryShader geometry = gfxInfo.geometryShader.cast(); - - VkPipelineShaderStageCreateInfo& geometryInfo = stageInfos[createInfo.stageCount++]; - geometryInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; - geometryInfo.stage = VK_SHADER_STAGE_GEOMETRY_BIT; - geometryInfo.module = geometry->getModuleHandle(); - geometryInfo.pName = geometry->getEntryPointName(); - - hashStruct.geometryHash = geometry->getShaderHash(); - } - if(gfxInfo.fragmentShader != nullptr) - { - PFragmentShader fragment = gfxInfo.fragmentShader.cast(); - - VkPipelineShaderStageCreateInfo& fragmentInfo = stageInfos[createInfo.stageCount++]; - fragmentInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; - fragmentInfo.stage = VK_SHADER_STAGE_FRAGMENT_BIT; - fragmentInfo.module = fragment->getModuleHandle(); - fragmentInfo.pName = fragment->getEntryPointName(); - - hashStruct.fragmentHash = fragment->getShaderHash(); - } - VkPipelineVertexInputStateCreateInfo vertexInput = - init::PipelineVertexInputStateCreateInfo(); - PVertexDeclaration vertexDecl = gfxInfo.vertexDeclaration; - auto vertexStreams = vertexDecl->elementList; - uint32 bindingNum = 0; - uint32 bindingsMask = 0; - uint32 attributesNum = 0; - Array bindings; - Array attributes; - Map bindingToStream; - Map streamToBinding; - assert(DEFAULT_ALLOC_SIZE == 16); - std::memset(bindings.data(), 0, sizeof(VkVertexInputBindingDescription) * 16); - std::memset(attributes.data(), 0, sizeof(VkVertexInputAttributeDescription) * 16); - for(auto& element : vertexStreams) - { - //if((1 << element.attributeIndex) & vertexAttributeMask) // TODO: attribute mask - { - if(element.streamIndex >= bindings.size()) - { - bindings.resize(element.streamIndex + 1); // This should not cause any actual allocations - } - VkVertexInputBindingDescription& currBinding = bindings[element.streamIndex]; - if((bindingsMask & (1 << element.streamIndex)) != 0) - { - assert(currBinding.binding == element.streamIndex); - assert(currBinding.inputRate == element.bInstanced ? VK_VERTEX_INPUT_RATE_INSTANCE : VK_VERTEX_INPUT_RATE_VERTEX); - assert(currBinding.stride == element.stride); - } - else - { - assert(currBinding.binding == 0 && currBinding.inputRate == 0 && currBinding.stride == 0); - currBinding.binding = element.streamIndex; - currBinding.inputRate = element.bInstanced ? VK_VERTEX_INPUT_RATE_INSTANCE : VK_VERTEX_INPUT_RATE_VERTEX; - currBinding.stride = element.stride; - - bindingsMask |= 1 << element.streamIndex; - } - } - } - - for(uint32 i = 0; i < bindings.size(); ++i) - { - if(!((1 << i) & bindingsMask)) - { - continue; - } - - bindingToStream[bindingNum] = i; - streamToBinding[i] = bindingNum; - VkVertexInputBindingDescription& currBinding = bindings[bindingNum]; - currBinding = bindings[i]; - currBinding.binding = bindingNum; - bindingNum++; - } - - for(auto& element : vertexStreams) - { - //TODO: vertex attribute mask - if(attributesNum >= attributes.size()) - { - attributes.resize(attributesNum + 1); // This should not cause any actual allocations - } - - VkVertexInputAttributeDescription& currAttribute = attributes[attributesNum++]; - currAttribute.location = element.attributeIndex; - currAttribute.binding = streamToBinding[element.streamIndex]; - currAttribute.format = cast(element.vertexFormat); - currAttribute.offset = element.offset; - } - - std::memcpy(hashStruct.bindings, bindings.data(), bindings.size() * sizeof(VkVertexInputBindingDescription)); - std::memcpy(hashStruct.attribs, attributes.data(), attributes.size() * sizeof(VkVertexInputAttributeDescription)); - - vertexInput.pVertexBindingDescriptions = bindings.data(); - vertexInput.vertexBindingDescriptionCount = (uint32)bindings.size(); - vertexInput.pVertexAttributeDescriptions = attributes.data(); - vertexInput.vertexAttributeDescriptionCount = (uint32)attributes.size(); - - VkPipelineInputAssemblyStateCreateInfo assemblyInfo = - init::PipelineInputAssemblyStateCreateInfo( - cast(gfxInfo.topology), - 0, - false - ); - hashStruct.inputAssembly = assemblyInfo; - - VkPipelineViewportStateCreateInfo viewportInfo = - init::PipelineViewportStateCreateInfo( - 1, - 1, - 0 - ); - hashStruct.viewport = viewportInfo; - - VkPipelineRasterizationStateCreateInfo rasterizationState = - init::PipelineRasterizationStateCreateInfo( - cast(gfxInfo.rasterizationState.polygonMode), - gfxInfo.rasterizationState.cullMode, - (VkFrontFace)gfxInfo.rasterizationState.frontFace, - 0 - ); - rasterizationState.depthBiasEnable = gfxInfo.rasterizationState.depthBiasEnable; - rasterizationState.depthBiasClamp = gfxInfo.rasterizationState.depthBiasClamp; - rasterizationState.depthBiasConstantFactor = gfxInfo.rasterizationState.depthBoasConstantFactor; - rasterizationState.depthBiasSlopeFactor = gfxInfo.rasterizationState.depthBiasSlopeFactor; - rasterizationState.depthClampEnable = gfxInfo.rasterizationState.depthClampEnable; - rasterizationState.lineWidth = gfxInfo.rasterizationState.lineWidth; - rasterizationState.rasterizerDiscardEnable = gfxInfo.rasterizationState.rasterizerDiscardEnable; - - hashStruct.rasterization = rasterizationState; - - VkPipelineMultisampleStateCreateInfo multisampleState = - init::PipelineMultisampleStateCreateInfo( - (VkSampleCountFlagBits)gfxInfo.multisampleState.samples, - 0); - multisampleState.alphaToCoverageEnable = gfxInfo.multisampleState.alphaCoverageEnable; - multisampleState.alphaToOneEnable = gfxInfo.multisampleState.alphaToOneEnable; - multisampleState.minSampleShading = gfxInfo.multisampleState.minSampleShading; - multisampleState.sampleShadingEnable = gfxInfo.multisampleState.sampleShadingEnable; - - hashStruct.multisample = multisampleState; - - VkPipelineDepthStencilStateCreateInfo depthStencilState = - init::PipelineDepthStencilStateCreateInfo( - gfxInfo.depthStencilState.depthTestEnable, - gfxInfo.depthStencilState.depthWriteEnable, - cast(gfxInfo.depthStencilState.depthCompareOp) - ); - - hashStruct.depthStencil = depthStencilState; - - const auto& colorAttachments = gfxInfo.renderPass->getLayout()->colorAttachments; - Array blendAttachments(colorAttachments.size()); - for(uint32 i = 0; i < colorAttachments.size(); ++i) - { - const Gfx::ColorBlendState::BlendAttachment& attachment = gfxInfo.colorBlend.blendAttachments[i]; - VkPipelineColorBlendAttachmentState& blendAttachment = blendAttachments[i]; - blendAttachment.alphaBlendOp = (VkBlendOp)attachment.alphaBlendOp; - blendAttachment.blendEnable = attachment.blendEnable; - blendAttachment.colorBlendOp = (VkBlendOp)attachment.colorBlendOp; - blendAttachment.colorWriteMask = attachment.colorWriteMask; - blendAttachment.dstAlphaBlendFactor = (VkBlendFactor)attachment.dstAlphaBlendFactor; - blendAttachment.srcAlphaBlendFactor = (VkBlendFactor)attachment.srcAlphaBlendFactor; - blendAttachment.dstColorBlendFactor = (VkBlendFactor)attachment.dstColorBlendFactor; - blendAttachment.srcColorBlendFactor = (VkBlendFactor)attachment.srcColorBlendFactor; - - hashStruct.blendAttachments[i] = blendAttachment; - } - VkPipelineColorBlendStateCreateInfo blendState = - init::PipelineColorBlendStateCreateInfo( - (uint32)blendAttachments.size(), - blendAttachments.data() - ); - blendState.logicOpEnable = gfxInfo.colorBlend.logicOpEnable; - blendState.logicOp = (VkLogicOp)gfxInfo.colorBlend.logicOp; - std::memcpy(blendState.blendConstants, gfxInfo.colorBlend.blendConstants, sizeof(float)*4); - - hashStruct.blendState = blendState; - hashStruct.blendState.pAttachments = nullptr; - - uint32 numDynamicEnabled = 0; - StaticArray dynamicEnabled; - dynamicEnabled[numDynamicEnabled++] = VK_DYNAMIC_STATE_VIEWPORT; - dynamicEnabled[numDynamicEnabled++] = VK_DYNAMIC_STATE_SCISSOR; - - VkPipelineDynamicStateCreateInfo dynamicState = - init::PipelineDynamicStateCreateInfo( - dynamicEnabled.data(), - numDynamicEnabled, - 0 - ); - - PPipelineLayout layout = gfxInfo.pipelineLayout.cast(); - hashStruct.pipelineLayoutHash = layout->getHash(); - - uint32 hash = CRC::Calculate(&hashStruct, sizeof(PipelineCreateHashStruct), CRC::CRC_32()); - VkPipeline pipelineHandle; - - std::scoped_lock lock(createdPipelinesLock); - auto foundPipeline = createdPipelines.find(hash); - if (foundPipeline != createdPipelines.end()) - { - pipelineHandle = foundPipeline->value; - } - else - { - createInfo.pStages = stageInfos; - createInfo.pVertexInputState = &vertexInput; - createInfo.pInputAssemblyState = &assemblyInfo; - createInfo.pTessellationState = &tessInfo; - createInfo.pViewportState = &viewportInfo; - createInfo.pRasterizationState = &rasterizationState; - createInfo.pMultisampleState = &multisampleState; - createInfo.pDepthStencilState = &depthStencilState; - createInfo.pColorBlendState = &blendState; - createInfo.pDynamicState = &dynamicState; - createInfo.renderPass = gfxInfo.renderPass.cast()->getHandle(); - createInfo.layout = layout->getHandle(); - createInfo.subpass = 0; - - auto beginTime = std::chrono::high_resolution_clock::now(); - VK_CHECK(vkCreateGraphicsPipelines(graphics->getDevice(), cache, 1, &createInfo, nullptr, &pipelineHandle)); - auto endTime = std::chrono::high_resolution_clock::now(); - int64 delta = std::chrono::duration_cast(endTime - beginTime).count(); - createdPipelines[hash] = pipelineHandle; - std::cout << "Gfx creation time: " << delta << std::endl; - } - - PGraphicsPipeline result = new GraphicsPipeline(graphics, pipelineHandle, layout, gfxInfo); - return result; -} - -PComputePipeline PipelineCache::createPipeline(const 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()); - 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, computeInfo); - return result; -} \ No newline at end of file diff --git a/src/Engine/Material/Material.cpp b/src/Engine/Material/Material.cpp index 3bb7757..268f8b6 100644 --- a/src/Engine/Material/Material.cpp +++ b/src/Engine/Material/Material.cpp @@ -30,24 +30,9 @@ Material::~Material() { } -Gfx::PDescriptorSet Material::createDescriptorSet() +PMaterialInstance Seele::Material::instantiate() { - Gfx::PDescriptorSet descriptorSet = layout->allocateDescriptorSet(); - BulkResourceData uniformUpdate = { - .size = uniformDataSize, - .data = (uint8*)uniformData.data(), - }; - for(auto param : parameters) - { - param->updateDescriptorSet(descriptorSet, uniformData.data()); - } - if(uniformUpdate.size != 0) - { - uniformBuffer->updateContents(uniformUpdate); - descriptorSet->updateBuffer(uniformBinding, uniformBuffer); - } - descriptorSet->writeChanges(); - return descriptorSet; + return new MaterialInstance(instanceId++, graphics, this, layout, parameters, uniformBinding, uniformDataSize); } void Material::save(ArchiveBuffer& buffer) const diff --git a/src/Engine/Material/Material.h b/src/Engine/Material/Material.h index 11ca147..ba8d2ee 100644 --- a/src/Engine/Material/Material.h +++ b/src/Engine/Material/Material.h @@ -1,6 +1,6 @@ #pragma once #include "ShaderExpression.h" -#include "Graphics/GraphicsResources.h" +#include "Graphics/Descriptor.h" namespace Seele { diff --git a/src/Engine/Material/MaterialInstance.cpp b/src/Engine/Material/MaterialInstance.cpp index 434853a..c8c4139 100644 --- a/src/Engine/Material/MaterialInstance.cpp +++ b/src/Engine/Material/MaterialInstance.cpp @@ -4,8 +4,8 @@ using namespace Seele; -MaterialInstance::MaterialInstance(uint64 id, Gfx::PGraphics graphics, PMaterial baseMaterial, Gfx::PDescriptorSet descriptor, Array params, uint32 uniformBinding, uint32 uniformSize) - : id(id), graphics(graphics), baseMaterial(baseMaterial), descriptor(descriptor), parameters(params), uniformBinding(uniformBinding) +MaterialInstance::MaterialInstance(uint64 id, Gfx::PGraphics graphics, PMaterial baseMaterial, Gfx::PDescriptorLayout descriptor, Array params, uint32 uniformBinding, uint32 uniformSize) + : id(id), graphics(graphics), baseMaterial(baseMaterial), layout(layout), parameters(params), uniformBinding(uniformBinding) { uniformBuffer = graphics->createUniformBuffer(UniformBufferCreateInfo{ .resourceData = { @@ -20,4 +20,8 @@ MaterialInstance::MaterialInstance(uint64 id, Gfx::PGraphics graphics, PMaterial MaterialInstance::~MaterialInstance() { -} \ No newline at end of file +} + +void Seele::MaterialInstance::updateDescriptor() +{ +} diff --git a/src/Engine/Material/MaterialInstance.h b/src/Engine/Material/MaterialInstance.h index efee411..2dbdb9d 100644 --- a/src/Engine/Material/MaterialInstance.h +++ b/src/Engine/Material/MaterialInstance.h @@ -1,12 +1,13 @@ #pragma once #include "Material.h" +#include "Graphics/Buffer.h" namespace Seele { class MaterialInstance { public: - MaterialInstance(uint64 id, Gfx::PGraphics graphics, PMaterial baseMaterial, Gfx::PDescriptorSet descriptor, Array params, uint32 uniformBinding, uint32 uniformSize); + MaterialInstance(uint64 id, Gfx::PGraphics graphics, PMaterial baseMaterial, Gfx::PDescriptorLayout descriptor, Array params, uint32 uniformBinding, uint32 uniformSize); ~MaterialInstance(); void updateDescriptor(); Gfx::PDescriptorSet getDescriptorSet() const; @@ -18,6 +19,7 @@ private: uint32 uniformBinding; Gfx::PUniformBuffer uniformBuffer; Array parameters; + Gfx::PDescriptorLayout layout; Gfx::PDescriptorSet descriptor; PMaterial baseMaterial; uint64 id; diff --git a/src/Engine/Material/ShaderExpression.cpp b/src/Engine/Material/ShaderExpression.cpp index 9440a35..d1d566c 100644 --- a/src/Engine/Material/ShaderExpression.cpp +++ b/src/Engine/Material/ShaderExpression.cpp @@ -1,8 +1,9 @@ #include "ShaderExpression.h" -#include "Graphics/GraphicsResources.h" +#include "Graphics/Resources.h" #include "Asset/TextureAsset.h" #include "Asset/AssetRegistry.h" #include "Graphics/Graphics.h" +#include "Graphics/Descriptor.h" using namespace Seele; diff --git a/src/Engine/Scene/CMakeLists.txt b/src/Engine/Scene/CMakeLists.txt index fab34c8..583abbb 100644 --- a/src/Engine/Scene/CMakeLists.txt +++ b/src/Engine/Scene/CMakeLists.txt @@ -1,13 +1,16 @@ target_sources(Engine PRIVATE EventManager.h + LightEnvironment.h + LightEnvironment.cpp Util.h - Scene.cpp - Scene.h) + Scene.h + Scene.cpp) target_sources(Engine PUBLIC FILE_SET HEADERS FILES EventManager.h + LightEnvironment.h Util.h Scene.h) \ No newline at end of file diff --git a/src/Engine/Scene/LightEnvironment.cpp b/src/Engine/Scene/LightEnvironment.cpp new file mode 100644 index 0000000..683a9c2 --- /dev/null +++ b/src/Engine/Scene/LightEnvironment.cpp @@ -0,0 +1,35 @@ +#include "LightEnvironment.h" +#include "Graphics/Graphics.h" + +using namespace Seele; + +LightEnvironment::LightEnvironment(Gfx::PGraphics graphics) + : graphics(graphics) +{ + layout = graphics->createDescriptorLayout("LightEnvironment"); + layout->addDescriptorBinding(0, Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER); + layout->addDescriptorBinding(1, Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER); + layout->addDescriptorBinding(2, Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER); + layout->addDescriptorBinding(3, Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER); +} + +LightEnvironment::~LightEnvironment() +{ +} + +void LightEnvironment::reset() +{ + +} + +void LightEnvironment::addDirectionalLight(Component::DirectionalLight dirLight) +{ +} + +void LightEnvironment::addPointLight(Component::PointLight pointLight) +{ +} + +void LightEnvironment::commit() +{ +} diff --git a/src/Engine/Scene/LightEnvironment.h b/src/Engine/Scene/LightEnvironment.h new file mode 100644 index 0000000..6cede36 --- /dev/null +++ b/src/Engine/Scene/LightEnvironment.h @@ -0,0 +1,32 @@ +#pragma once +#include "Graphics/Descriptor.h" +#include "Graphics/Buffer.h" +#include "Component/DirectionalLight.h" +#include "Component/PointLight.h" + +namespace Seele +{ +class LightEnvironment +{ +public: + LightEnvironment(Gfx::PGraphics graphics); + ~LightEnvironment(); + void reset(); + void addDirectionalLight(Component::DirectionalLight dirLight); + void addPointLight(Component::PointLight pointLight); + void commit(); +private: + #define MAX_DIRECTIONAL_LIGHTS 4 + #define MAX_POINT_LIGHTS 256 + Gfx::PShaderBuffer directionalLights; + Gfx::PUniformBuffer numDirectional; + Gfx::PShaderBuffer pointLights; + Gfx::PUniformBuffer numPoints;; + Array dirs; + Array points; + Gfx::PDescriptorLayout layout; + Gfx::PDescriptorSet set; + Gfx::PGraphics graphics; +}; +DEFINE_REF(LightEnvironment) +} \ No newline at end of file diff --git a/src/Engine/Scene/Scene.cpp b/src/Engine/Scene/Scene.cpp index 64c2a1b..c20be05 100644 --- a/src/Engine/Scene/Scene.cpp +++ b/src/Engine/Scene/Scene.cpp @@ -1,7 +1,7 @@ #include "Scene.h" #include "Graphics/Graphics.h" #include "Graphics/Mesh.h" -#include "Component/StaticMesh.h" +#include "Component/Mesh.h" #include "Component/Transform.h" #include "Asset/AssetRegistry.h" #include "Asset/TextureAsset.h" @@ -81,14 +81,3 @@ LightEnv Scene::getLightBuffer() }); return lightEnv; } - - -Component::Skybox Scene::getSkybox() -{ - return Seele::Component::Skybox { - .day = AssetRegistry::findTexture("FS000_Day_01")->getTexture().cast(), - .night = AssetRegistry::findTexture("FS000_Night_01")->getTexture().cast(), - .fogColor = Vector(0.2, 0.1, 0.6), - .blendFactor = 0, - }; -} \ No newline at end of file diff --git a/src/Engine/Scene/Scene.h b/src/Engine/Scene/Scene.h index bc3534a..b52567e 100644 --- a/src/Engine/Scene/Scene.h +++ b/src/Engine/Scene/Scene.h @@ -2,25 +2,14 @@ #include #include "MinimalEngine.h" #include "Graphics/Graphics.h" -#include "Graphics/MeshBatch.h" #include "Physics/PhysicsSystem.h" #include "Component/Skybox.h" +#include "LightEnvironment.h" namespace Seele { DECLARE_REF(Material) DECLARE_REF(Entity) - -#define MAX_DIRECTIONAL_LIGHTS 4 -#define MAX_POINT_LIGHTS 256 -struct LightEnv -{ - Gfx::PShaderBuffer directionalLights; - Gfx::PUniformBuffer numDirectional; - Gfx::PShaderBuffer pointLights; - Gfx::PUniformBuffer numPoints; -}; - class Scene { public: @@ -55,12 +44,11 @@ public: { registry.view().each(func); } - LightEnv getLightBuffer(); - Component::Skybox getSkybox(); + PLightEnvironment getLightEnvironment() { return lightEnv; } Gfx::PGraphics getGraphics() const { return graphics; } entt::registry registry; private: - LightEnv lightEnv; + PLightEnvironment lightEnv; PhysicsSystem physics; Gfx::PGraphics graphics; }; diff --git a/src/Engine/System/CMakeLists.txt b/src/Engine/System/CMakeLists.txt index caff95b..1a6ed51 100644 --- a/src/Engine/System/CMakeLists.txt +++ b/src/Engine/System/CMakeLists.txt @@ -3,6 +3,8 @@ target_sources(Engine ComponentSystem.h Executor.h Executor.cpp + LightGather.h + LightGather.cpp MeshUpdater.h MeshUpdater.cpp SystemBase.h @@ -13,7 +15,8 @@ target_sources(Engine PUBLIC FILE_SET HEADERS FILES ComponentSystem.h - MeshUpdater.h Executor.h + LightGather.h + MeshUpdater.h SystemBase.h SystemGraph.h) \ No newline at end of file diff --git a/src/Engine/System/LightGather.cpp b/src/Engine/System/LightGather.cpp new file mode 100644 index 0000000..702d807 --- /dev/null +++ b/src/Engine/System/LightGather.cpp @@ -0,0 +1,18 @@ +#include "LightGather.h" + +using namespace Seele; +using namespace Seele::System; + +LightGather::LightGather(PScene scene) + : SystemBase(scene) + , lightEnv(scene->getLightEnvironment()) +{ +} + +LightGather::~LightGather() +{ +} + +void LightGather::update() +{ +} diff --git a/src/Engine/System/LightGather.h b/src/Engine/System/LightGather.h new file mode 100644 index 0000000..ca34c94 --- /dev/null +++ b/src/Engine/System/LightGather.h @@ -0,0 +1,18 @@ +#pragma once +#include "SystemBase.h" + +namespace Seele +{ +namespace System +{ +class LightGather : public SystemBase +{ +public: + LightGather(PScene scene); + virtual ~LightGather(); + virtual void update() override; +private: + PLightEnvironment lightEnv; +}; +} +} \ No newline at end of file diff --git a/src/Engine/System/MeshUpdater.cpp b/src/Engine/System/MeshUpdater.cpp index f619071..5aeeb89 100644 --- a/src/Engine/System/MeshUpdater.cpp +++ b/src/Engine/System/MeshUpdater.cpp @@ -3,6 +3,11 @@ using namespace Seele; using namespace Seele::System; +MeshUpdater::MeshUpdater(PScene scene) + : ComponentSystem(scene) +{ +} + void MeshUpdater::update(Component::Transform& transform, Component::Mesh& mesh) { mesh.vertexData->updateMesh(transform, mesh); diff --git a/src/Engine/System/MeshUpdater.h b/src/Engine/System/MeshUpdater.h index 82b21f3..c9f6dee 100644 --- a/src/Engine/System/MeshUpdater.h +++ b/src/Engine/System/MeshUpdater.h @@ -10,6 +10,8 @@ namespace System class MeshUpdater : public ComponentSystem { public: + MeshUpdater(PScene scene); + virtual ~MeshUpdater(); virtual void update(Component::Transform& transform, Component::Mesh& mesh) override; private: }; diff --git a/src/Engine/UI/RenderHierarchy.h b/src/Engine/UI/RenderHierarchy.h index dbccd2b..2016a54 100644 --- a/src/Engine/UI/RenderHierarchy.h +++ b/src/Engine/UI/RenderHierarchy.h @@ -1,7 +1,8 @@ #pragma once #include "Elements/Element.h" #include "Containers/List.h" -#include "Graphics/GraphicsResources.h" +#include "Graphics/Resources.h" +#include "Graphics/Texture.h" namespace Seele { diff --git a/src/Engine/UI/System.cpp b/src/Engine/UI/System.cpp index 8e2b56e..c6f5d8d 100644 --- a/src/Engine/UI/System.cpp +++ b/src/Engine/UI/System.cpp @@ -27,31 +27,6 @@ void System::updateViewport(Gfx::PViewport viewport) //TODO set viewport FoV to 0 } -UIPassData System::getUIPassData() -{ - UIPassData uiPassData; - RenderElementStyle& style = uiPassData.renderElements.add(); - style.position = Vector(0, 0, -0.1); - style.dimensions = Vector2(0.4, 0.4); - style.backgroundColor = Vector(0.2, 0.3, 0.1); - style.backgroundImageIndex = 0; - uiPassData.usedTextures.add(AssetRegistry::findTexture("")->getTexture()); - return uiPassData; -} - -TextPassData System::getTextPassData() -{ - TextPassData textPassData; - TextRender& render = textPassData.texts.add(); - render.font = AssetRegistry::findFont("Calibri"); - render.text = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus quis magna ex. Morbi ullamcorper fringilla risus eget vehicula. Praesent vel quam vel ante molestie gravida vitae ac enim. Donec vitae eleifend orci. Phasellus at sodales lorem, ac eleifend turpis. Vivamus vitae condimentum lacus, a bibendum neque. Ut et est ut felis varius vehicula. Etiam lorem magna, dapibus vitae felis in, vulputate suscipit neque. Aenean facilisis ac risus et scelerisque. Ut tincidunt eros quis posuere iaculis. Curabitur justo lacus, molestie id varius vel, sodales efficitur diam. Integer orci velit, condimentum sit amet turpis sit amet, congue blandit nisl. Donec pretium ligula id mauris pretium commodo. Mauris quis lectus mi. In blandit, dolor non accumsan venenatis, ipsum erat congue neque, quis elementum orci nunc vel justo. "; - //render.text = "Seele Engine"; - render.position = Vector2(0.f, 300.f); - render.scale = 0.1f; - render.textColor = Vector4(1, 0, 0, 1); - return textPassData; -} - Component::Camera System::getVirtualCamera() const { return virtualCamera; diff --git a/src/Engine/UI/System.h b/src/Engine/UI/System.h index 1eacf3a..580a9e6 100644 --- a/src/Engine/UI/System.h +++ b/src/Engine/UI/System.h @@ -16,8 +16,6 @@ public: virtual ~System(); void update(); void updateViewport(Gfx::PViewport viewport); - UIPassData getUIPassData(); - TextPassData getTextPassData(); Component::Camera getVirtualCamera() const; private: Component::Camera virtualCamera; diff --git a/src/Engine/Window/GameView.cpp b/src/Engine/Window/GameView.cpp index 46eca36..d27bb24 100644 --- a/src/Engine/Window/GameView.cpp +++ b/src/Engine/Window/GameView.cpp @@ -12,9 +12,9 @@ GameView::GameView(Gfx::PGraphics graphics, PWindow window, const ViewportCreate , gameInterface(dllPath) , renderGraph(RenderGraphBuilder::build( DepthPrepass(graphics, scene), - LightCullingPass(graphics), + LightCullingPass(graphics, scene), BasePass(graphics, scene), - SkyboxRenderPass(graphics) + SkyboxRenderPass(graphics, scene) )) { reloadGame(); diff --git a/src/Engine/Window/GameView.h b/src/Engine/Window/GameView.h index 82ccdf9..b7bb939 100644 --- a/src/Engine/Window/GameView.h +++ b/src/Engine/Window/GameView.h @@ -30,11 +30,6 @@ private: BasePass, SkyboxRenderPass > renderGraph; - - DepthPrepassData depthPrepassData; - LightCullingPassData lightCullingData; - BasePassData basePassData; - SkyboxPassData skyboxData; PEntity camera; PScene scene; diff --git a/src/Engine/Window/Window.h b/src/Engine/Window/Window.h index 48f6941..b2a975d 100644 --- a/src/Engine/Window/Window.h +++ b/src/Engine/Window/Window.h @@ -1,6 +1,6 @@ #pragma once -#include "Graphics/GraphicsResources.h" #include "View.h" +#include "Graphics/RenderTarget.h" namespace Seele { diff --git a/test.glsl b/test.glsl deleted file mode 100644 index 16c42c3..0000000 --- a/test.glsl +++ /dev/null @@ -1,171 +0,0 @@ -#version 450 -#extension GL_EXT_mesh_shader : require -layout(row_major) uniform; -layout(row_major) buffer; - -#line 3 0 -struct InstanceData_0 -{ - mat4x4 transformMatrix_0; -}; - - -#line 25 1 -layout(std430, binding = 0, set = 2) readonly buffer StructuredBuffer_InstanceData_t_0 { - InstanceData_0 _data[]; -} scene_instances_0; - -#line 20 2 -struct MeshData_0 -{ - uint numMeshlets_0; - uint meshletOffset_0; -}; - - -#line 8 0 -layout(std430, binding = 1, set = 2) readonly buffer StructuredBuffer_MeshData_t_0 { - MeshData_0 _data[]; -} scene_meshData_0; - -#line 5 3 -struct ViewParameter_0 -{ - mat4x4 viewMatrix_0; - mat4x4 projectionMatrix_0; - vec4 cameraPos_WS_0; - vec2 screenDimensions_0; -}; - -layout(binding = 0) -layout(std140) uniform _S1 -{ - mat4x4 viewMatrix_0; - mat4x4 projectionMatrix_0; - vec4 cameraPos_WS_0; - vec2 screenDimensions_0; -}viewParams_0; - -#line 14 1 -shared uint head_0; - - -#line 15 -shared mat4x4 localToClip_0; - - -#line 26 3 -struct Plane_0 -{ - vec3 n_0; - float d_0; -}; - -struct Frustum_0 -{ - Plane_0 sides_0[4]; - Plane_0 basePlane_0; -}; - - -#line 16 1 -shared Frustum_0 viewFrustum_0; - - -#line 7 -struct MeshPayload_0 -{ - uint instanceId_0[512]; - uint meshletId_0[512]; -}; - -taskPayloadSharedEXT MeshPayload_0 p_0; - - -#line 21 -layout(local_size_x = 128, local_size_y = 1, local_size_z = 1) in; -void main() -{ - -#line 21 - uint _S2 = gl_WorkGroupID.x; - - - - InstanceData_0 instance_0 = scene_instances_0._data[_S2]; - if(gl_LocalInvocationIndex == 0U) - { - head_0 = 0U; - localToClip_0 = ((((((instance_0.transformMatrix_0) * (viewParams_0.viewMatrix_0)))) * (viewParams_0.projectionMatrix_0))); - - viewFrustum_0.sides_0[0].n_0 = vec3(1.0, 0.0, 0.0); - viewFrustum_0.sides_0[0].d_0 = -1.0; - - viewFrustum_0.sides_0[1].n_0 = vec3(-1.0, 0.0, 0.0); - viewFrustum_0.sides_0[1].d_0 = 1.0; - - viewFrustum_0.sides_0[2].n_0 = vec3(0.0, -1.0, 0.0); - viewFrustum_0.sides_0[2].d_0 = 1.0; - - viewFrustum_0.sides_0[1].n_0 = vec3(0.0, 1.0, 0.0); - viewFrustum_0.sides_0[1].d_0 = -1.0; - - viewFrustum_0.basePlane_0.n_0 = vec3(0.0, 0.0, 1.0); - viewFrustum_0.basePlane_0.d_0 = 0.0; - -#line 26 - } - -#line 46 - barrier(); - MeshData_0 _S3 = scene_meshData_0._data[_S2]; - -#line 47 - if(gl_LocalInvocationIndex < 512U) - { - -#line 47 - uint i_0 = gl_LocalInvocationIndex; - -#line 47 - for(;;) - { - - uint m_0 = _S3.meshletOffset_0 + min(_S3.numMeshlets_0, i_0); - - - - uint index_0; - ((index_0) = atomicAdd((head_0), (1U))); - p_0.meshletId_0[index_0] = m_0; - p_0.instanceId_0[index_0] = _S2; - -#line 48 - uint i_1 = i_0 + 128U; - -#line 48 - if(i_1 < 512U) - { - } - else - { - -#line 48 - break; - } - -#line 48 - i_0 = i_1; - -#line 48 - } - -#line 48 - } - -#line 60 - barrier(); - EmitMeshTasksEXT((head_0), (1U), (1U)); - return; -} -