From a545426b3293263ac4ddb7fbe930e19a868a4c02 Mon Sep 17 00:00:00 2001 From: Dynamitos Date: Mon, 13 Nov 2023 09:07:23 +0100 Subject: [PATCH] Reducing startup time significantly --- res/shaders/BasePass.slang | 10 ++- res/shaders/LegacyBasePass.slang | 5 +- res/shaders/lib/BRDF.slang | 2 +- res/shaders/lib/LightEnv.slang | 44 +++++------ res/shaders/lib/MaterialParameter.slang | 85 ++++++++++++++++++--- res/shaders/lib/StaticMeshVertexData.slang | 20 +++-- src/Engine/Component/Camera.cpp | 2 +- src/Engine/Containers/Array.h | 13 +++- src/Engine/Graphics/VertexData.cpp | 2 +- src/Engine/Graphics/Vulkan/Allocator.cpp | 12 ++- src/Engine/Graphics/Vulkan/RenderTarget.cpp | 1 + 11 files changed, 134 insertions(+), 62 deletions(-) diff --git a/res/shaders/BasePass.slang b/res/shaders/BasePass.slang index 659670b..0805509 100644 --- a/res/shaders/BasePass.slang +++ b/res/shaders/BasePass.slang @@ -15,17 +15,19 @@ layout(set=5) ParameterBlock pLightCullingData; [shader("pixel")] -float4 fragmentMain(in MaterialParameter params : PARAMETER) : SV_Target +float4 fragmentMain(in FragmentParameter params : PARAMETER) : SV_Target { - let brdf = pMaterial.prepare(params); + MaterialParameter materialParams = params.getMaterialParameter(); + LightingParameter lightingParams = params.getLightingParameter(); + let brdf = pMaterial.prepare(materialParams); float3 result = float3(0, 0, 0); for(int i = 0; i < pLightEnv.numDirectionalLights; ++i) { - result += pLightEnv.directionalLights[i].illuminate(params, brdf); + result += pLightEnv.directionalLights[i].illuminate(lightingParams, brdf); } for(int i = 0; i < pLightEnv.numPointLights; ++i) { - result += pLightEnv.pointLights[i].illuminate(params, brdf); + result += pLightEnv.pointLights[i].illuminate(lightingParams, brdf); } return float4(result, 1.0f); } diff --git a/res/shaders/LegacyBasePass.slang b/res/shaders/LegacyBasePass.slang index 1d19c35..9fb1f60 100644 --- a/res/shaders/LegacyBasePass.slang +++ b/res/shaders/LegacyBasePass.slang @@ -15,11 +15,12 @@ layout(set=2) ParameterBlock pScene; [shader("vertex")] -VertexAttributes vertexMain( +void vertexMain( uint vertexId: SV_VertexID, uint instanceId: SV_InstanceID, + out FragmentParameter params: PARAMETER, ){ InstanceData inst = pScene.instances[instanceId]; VertexAttributes attr = pVertexData.getAttributes(vertexId, inst.transformMatrix); - return attr; + params = attr.getParameter(inst.transformMatrix); } \ No newline at end of file diff --git a/res/shaders/lib/BRDF.slang b/res/shaders/lib/BRDF.slang index 0cc3c3a..82b83e6 100644 --- a/res/shaders/lib/BRDF.slang +++ b/res/shaders/lib/BRDF.slang @@ -29,7 +29,7 @@ struct BlinnPhong : IBRDF float3 h = normalize(lightDir_TS + viewDir_TS); float nDotH = saturate(dot(normal, h)); - return baseColor * (nDotL + nDotH) * lightColor; + return baseColor; } }; diff --git a/res/shaders/lib/LightEnv.slang b/res/shaders/lib/LightEnv.slang index 31d0477..044acc2 100644 --- a/res/shaders/lib/LightEnv.slang +++ b/res/shaders/lib/LightEnv.slang @@ -4,7 +4,7 @@ import MaterialParameter; interface ILightEnv { - float3 illuminate(MaterialParameter input, B brdf); + float3 illuminate(LightingParameter input, B brdf); }; struct DirectionalLight : ILightEnv @@ -12,10 +12,10 @@ struct DirectionalLight : ILightEnv float4 color; float4 direction; - float3 illuminate(MaterialParameter input, B brdf) + float3 illuminate(LightingParameter params, B brdf) { - float3 lightDir_TS = normalize(direction.xyz); - return brdf.evaluate(input.viewDir_TS, -lightDir_TS, color.xyz); + float3 lightDir_TS = mul(params.tbn, normalize(direction.xyz)); + return brdf.evaluate(params.viewDir_TS, -lightDir_TS, color.xyz); } }; @@ -24,41 +24,37 @@ struct PointLight : ILightEnv float4 position_WS; float4 colorRange; - float3 illuminate(MaterialParameter input, B brdf) + float3 illuminate(LightingParameter params, B brdf) { - float3 position_TS = position_WS.xyz; - float3 lightDir_TS = position_TS - input.position_TS; + float3 position_TS = mul(params.tbn, position_WS.xyz); + float3 lightDir_TS = position_TS - params.position_TS; float d = length(lightDir_TS); float illuminance = max(1 - d / colorRange.w, 0); - return illuminance * brdf.evaluate(input.viewDir_TS, normalize(lightDir_TS), colorRange.xyz); + return illuminance * brdf.evaluate(params.viewDir_TS, normalize(lightDir_TS), colorRange.xyz); } bool insidePlane(Plane plane) { - return dot(plane.n, getViewPos().xyz) - plane.d < -colorRange.w; + return true;//dot(plane.n, getViewPos().xyz) - plane.d < -colorRange.w; } bool insideFrustum(Frustum frustum, float zNear, float zFar) { bool result = true; - if(getViewPos().z - colorRange.w > zNear || getViewPos().z + colorRange.w < zFar) - { - //result = false; - } - for(int i = 0; i < 4 && result; ++i) - { - if(insidePlane(frustum.sides[i])) - { - //result = false; - } - } + //if(getViewPos().z - colorRange.w > zNear || getViewPos().z + colorRange.w < zFar) + //{ + // //result = false; + //} + //for(int i = 0; i < 4 && result; ++i) + //{ + // if(insidePlane(frustum.sides[i])) + // { + // //result = false; + // } + //} return result; } - float3 getViewPos() - { - return mul(pViewParams.viewMatrix, position_WS).xyz; - } }; struct LightEnv diff --git a/res/shaders/lib/MaterialParameter.slang b/res/shaders/lib/MaterialParameter.slang index 1659ad5..98740a2 100644 --- a/res/shaders/lib/MaterialParameter.slang +++ b/res/shaders/lib/MaterialParameter.slang @@ -1,17 +1,80 @@ +import Common; + struct MaterialParameter { - float3 position_TS; - float3 worldPosition; - float2 texCoords; - float3 normal; - float3 tangent; - float3 biTangent; - float3 viewDir_TS; - float3 vertexColor; -} + float3 position_TS : POSITION0; + float3 position_WS : POSITION1; + float2 texCoords : TEXCOORDS0; + float3 vertexColor : COLOR0; +}; +// data used by light environment +struct LightingParameter +{ + // world to tangent space + float3x3 tbn; + float3 position_TS; + float3 viewDir_TS; +}; + +// data passed to fragment shader +struct FragmentParameter +{ + float3 position_TS; + float3 viewDir_TS; + float3 normal_WS; + float3 tangent_WS; + float3 biTangent_WS; + float3 position_WS; + float4 position_CS : SV_Position; + float2 texCoords; + float3 vertexColor; + MaterialParameter getMaterialParameter() + { + MaterialParameter result; + result.position_TS = position_TS; + result.position_WS = position_WS; + result.texCoords = texCoords; + result.vertexColor = vertexColor; + return result; + } + LightingParameter getLightingParameter() + { + LightingParameter result; + result.tbn = transpose(float3x3(normalize(tangent_WS), normalize(biTangent_WS), normalize(normal_WS))); + result.position_TS = position_TS; + result.viewDir_TS = viewDir_TS; + return result; + } +}; + +// data retrieved from VertexData struct VertexAttributes { - MaterialParameter parameter : PARAMETER; - float4 clipPosition: SV_POSITION; + float3 normal_MS; + float3 tangent_MS; + float3 biTangent_MS; + float3 position_WS; + float4 position_CS; + float2 texCoords; + float3 vertexColor; + FragmentParameter getParameter(float4x4 transformMatrix) + { + float3 tangent_WS = mul(transformMatrix, float4(normalize(tangent_MS), 0)).xyz; + float3 biTangent_WS = mul(transformMatrix, float4(normalize(biTangent_MS), 0)).xyz; + float3 normal_WS = mul(transformMatrix, float4(normalize(normal_MS), 0)).xyz; + // Transforms from world space into tangent space + float3x3 tbn = transpose(float3x3(tangent_WS, biTangent_WS, normal_WS)); + FragmentParameter result; + result.position_TS = mul(tbn, position_WS); + result.viewDir_TS = mul(tbn, pViewParams.cameraPos_WS.xyz - position_WS); + result.normal_WS = normal_WS; + result.tangent_WS = tangent_WS; + result.biTangent_WS = biTangent_WS; + result.position_WS = position_WS; + result.position_CS = position_CS; + result.texCoords = texCoords; + result.vertexColor = vertexColor; + return result; + } }; diff --git a/res/shaders/lib/StaticMeshVertexData.slang b/res/shaders/lib/StaticMeshVertexData.slang index dd89d60..3112a7f 100644 --- a/res/shaders/lib/StaticMeshVertexData.slang +++ b/res/shaders/lib/StaticMeshVertexData.slang @@ -7,19 +7,17 @@ struct StaticMeshVertexData : IVertexData VertexAttributes getAttributes(uint index, float4x4 transform) { VertexAttributes attributes; - MaterialParameter params; - float4 localPos = float4(positions[3 * index + 0], positions[3 * index + 1], positions[3 * index + 2], 1); - float4 worldPos = mul(transform, localPos); + float4 modelPos = float4(positions[3 * index + 0], positions[3 * index + 1], positions[3 * index + 2], 1); + float4 worldPos = mul(transform, modelPos); float4 viewPos = mul(pViewParams.viewMatrix, worldPos); float4 clipPos = mul(pViewParams.projectionMatrix, viewPos); - params.worldPosition = worldPos.xyz; - params.texCoords = float2(texCoords[2 * index + 0], texCoords[2 * index + 1]); - params.normal = float3(normals[3 * index + 0], normals[3 * index + 1], normals[3 * index + 2]); - params.tangent = float3(tangents[3 * index + 0], tangents[3 * index + 1], tangents[3 * index + 2]); - params.biTangent = float3(biTangents[3 * index + 0], biTangents[3 * index + 1], biTangents[3 * index + 2]); - params.vertexColor = float3(color[3 * index + 0], color[3 * index + 1], color[3 * index + 2]); - attributes.parameter = params; - attributes.clipPosition = clipPos; + attributes.normal_MS = float3(normals[3 * index + 0], normals[3 * index + 1], normals[3 * index + 2]); + attributes.tangent_MS = float3(tangents[3 * index + 0], tangents[3 * index + 1], tangents[3 * index + 2]); + attributes.biTangent_MS = float3(biTangents[3 * index + 0], biTangents[3 * index + 1], biTangents[3 * index + 2]); + attributes.position_WS = worldPos.xyz; + attributes.position_CS = clipPos; + attributes.texCoords = float2(texCoords[2 * index + 0], texCoords[2 * index + 1]); + attributes.vertexColor = float3(color[3 * index + 0], color[3 * index + 1], color[3 * index + 2]); return attributes; } StructuredBuffer positions; diff --git a/src/Engine/Component/Camera.cpp b/src/Engine/Component/Camera.cpp index 588e619..f6cf937 100644 --- a/src/Engine/Component/Camera.cpp +++ b/src/Engine/Component/Camera.cpp @@ -55,7 +55,7 @@ void Camera::buildViewMatrix() Vector eyePos = getTransform().getPosition();//getAbsoluteTransform().getPosition(); Vector lookAt = eyePos + glm::normalize(Vector(cos(yaw) * cos(pitch), sin(pitch), sin(yaw) * cos(pitch))); //std::cout << "Eye: " << eyePos << " lookAt: " << lookAt << std::endl; - viewMatrix = glm::lookAt(eyePos, lookAt, Vector(0, 1, 0)); + viewMatrix = glm::lookAt(Vector(100, 0, 10), Vector(0, 0, 0), Vector(0, 1, 0));//glm::lookAt(eyePos, lookAt, Vector(0, 1, 0)); bNeedsViewBuild = false; } diff --git a/src/Engine/Containers/Array.h b/src/Engine/Containers/Array.h index 9a8e6c0..8a5b643 100644 --- a/src/Engine/Containers/Array.h +++ b/src/Engine/Containers/Array.h @@ -607,10 +607,17 @@ private: { newData[i] = std::forward(_data[i]); } - // As well as default initialize the others - for(size_type i = arraySize; i < newSize; ++i) + if constexpr (std::is_integral_v || std::is_floating_point_v) { - std::allocator_traits::construct(allocator, &newData[i], value); + std::memset(&newData[arraySize], 0, sizeof(T) * (newSize - arraySize)); + } + else + { + // As well as default initialize the others + for (size_type i = arraySize; i < newSize; ++i) + { + std::allocator_traits::construct(allocator, &newData[i], value); + } } deallocateArray(_data, allocated); arraySize = newSize; diff --git a/src/Engine/Graphics/VertexData.cpp b/src/Engine/Graphics/VertexData.cpp index 9f30742..d180a9c 100644 --- a/src/Engine/Graphics/VertexData.cpp +++ b/src/Engine/Graphics/VertexData.cpp @@ -29,7 +29,7 @@ void VertexData::updateMesh(const Component::Transform& transform, PMesh mesh) matInstanceData.meshes.add(MeshInstanceData{ .id = mesh->id, .instance = InstanceData { - .transformMatrix = transform.toMatrix(), + .transformMatrix = Matrix4(1),//transform.toMatrix(), }, .indexBuffer = mesh->indexBuffer, }); diff --git a/src/Engine/Graphics/Vulkan/Allocator.cpp b/src/Engine/Graphics/Vulkan/Allocator.cpp index 4d9fceb..6a84289 100644 --- a/src/Engine/Graphics/Vulkan/Allocator.cpp +++ b/src/Engine/Graphics/Vulkan/Allocator.cpp @@ -59,6 +59,7 @@ Allocation::Allocation(PGraphics graphics, PAllocator allocator, VkDeviceSize si allocInfo.memoryTypeIndex = memoryTypeIndex; isDedicated = dedicatedInfo != nullptr; allocInfo.pNext = dedicatedInfo; + //std::cout << "New allocation" << std::endl; VK_CHECK(vkAllocateMemory(device, &allocInfo, nullptr, &allocatedMemory)); bytesAllocated = size; freeRanges[0] = size; @@ -69,6 +70,7 @@ Allocation::Allocation(PGraphics graphics, PAllocator allocator, VkDeviceSize si Allocation::~Allocation() { + vkFreeMemory(device, allocatedMemory, nullptr); assert(bytesUsed == 0); } @@ -180,7 +182,7 @@ Allocator::Allocator(PGraphics graphics) VkMemoryHeap memoryHeap = memProperties.memoryHeaps[i]; HeapInfo heapInfo; heapInfo.maxSize = memoryHeap.size; - std::cout << "Creating heap " << i << " with properties " << memoryHeap.flags << " size " << memoryHeap.size << std::endl; + //std::cout << "Creating heap " << i << " with properties " << memoryHeap.flags << " size " << memoryHeap.size << std::endl; heaps.add(std::move(heapInfo)); } } @@ -212,7 +214,7 @@ OSubAllocation Allocator::allocate(const VkMemoryRequirements2 &memRequirements2 { OAllocation newAllocation = new Allocation(graphics, this, requirements.size, memoryTypeIndex, properties, dedicatedInfo); heaps[heapIndex].inUse += newAllocation->bytesAllocated; - std::cout << "Heap " << heapIndex << ": " << (float)heaps[heapIndex].inUse / heaps[heapIndex].maxSize << "%" << std::endl; + //std::cout << "Heap " << heapIndex << ": " << (float)heaps[heapIndex].inUse / heaps[heapIndex].maxSize << "%" << std::endl; heaps[heapIndex].allocations.add(std::move(newAllocation)); return heaps[heapIndex].allocations.back()->getSuballocation(requirements.size, requirements.alignment); } @@ -232,12 +234,14 @@ OSubAllocation Allocator::allocate(const VkMemoryRequirements2 &memRequirements2 // no suitable allocations found, allocate new block OAllocation newAllocation = new Allocation(graphics, this, (requirements.size > MemoryBlockSize) ? requirements.size : (VkDeviceSize)MemoryBlockSize, memoryTypeIndex, properties, nullptr); heaps[heapIndex].inUse += newAllocation->bytesAllocated; - std::cout << "Heap " << heapIndex << ": " << (float)heaps[heapIndex].inUse / heaps[heapIndex].maxSize << "%" << std::endl; heaps[heapIndex].allocations.add(std::move(newAllocation)); + //std::cout << "Heap " << heapIndex << ": " << (float)heaps[heapIndex].inUse / heaps[heapIndex].maxSize << "%" << std::endl; + heaps[heapIndex].allocations.add(std::move(newAllocation)); return heaps[heapIndex].allocations.back()->getSuballocation(requirements.size, requirements.alignment); } void Allocator::free(PAllocation allocation) { + //std::cout << "Freeing allocation" << std::endl; for (uint32 heapIndex = 0; heapIndex < heaps.size(); ++heapIndex) { for (uint32 alloc = 0; alloc < heaps[heapIndex].allocations.size(); ++alloc) @@ -245,7 +249,7 @@ void Allocator::free(PAllocation allocation) if (heaps[heapIndex].allocations[alloc] == allocation) { heaps[heapIndex].inUse -= allocation->bytesAllocated; - std::cout << "Heap " << heapIndex << ": " << (float)heaps[heapIndex].inUse / heaps[heapIndex].maxSize << "%" << std::endl; + //std::cout << "Heap " << heapIndex << ": " << (float)heaps[heapIndex].inUse / heaps[heapIndex].maxSize << "%" << std::endl; heaps[heapIndex].allocations.removeAt(alloc, false); return; } diff --git a/src/Engine/Graphics/Vulkan/RenderTarget.cpp b/src/Engine/Graphics/Vulkan/RenderTarget.cpp index f2c254a..a609b8e 100644 --- a/src/Engine/Graphics/Vulkan/RenderTarget.cpp +++ b/src/Engine/Graphics/Vulkan/RenderTarget.cpp @@ -99,6 +99,7 @@ Window::Window(PGraphics graphics, const WindowCreateInfo &createInfo) Window::~Window() { + vkDestroySwapchainKHR(graphics->getDevice(), swapchain, nullptr); vkDestroySurfaceKHR(instance, surface, nullptr); glfwDestroyWindow(static_cast(windowHandle)); }