diff --git a/.vscode/settings.json b/.vscode/settings.json index 1263a01..dc4ef5c 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -24,5 +24,11 @@ "lldb.dereferencePointers": true, "lldb.consoleMode": "commands", "cmake.generator": "Xcode", - "editor.tabSize": 4 + "editor.tabSize": 4, + "slang.additionalSearchPaths": [ + "res/shaders/", + "res/shaders/lib" + ], + "slang.slangdLocation": "C:\\Users\\Dynamitos\\slang\\build\\Release\\bin\\slangd.exe", + "slang.searchInAllWorkspaceDirectories": false } \ No newline at end of file diff --git a/res/shaders/terrain/CBTCompute.slang b/res/shaders/terrain/CBTCompute.slang index 394f56e..756f424 100644 --- a/res/shaders/terrain/CBTCompute.slang +++ b/res/shaders/terrain/CBTCompute.slang @@ -41,7 +41,7 @@ void Split(uint dispatchID : SV_DispatchThreadID) uint currentID = pParams.classificationBuffer[CLASSIFY_COUNTER_OFFSET + dispatchID]; // Split the element - SplitElement(currentID, pParams.geometry.baseDepth); + SplitElement(currentID, pParams.geometry.baseDepth, dispatchID); } [numthreads(1, 1, 1)] diff --git a/res/shaders/terrain/CompileTest.slang b/res/shaders/terrain/CompileTest.slang index 9f99343..b38cdcc 100644 --- a/res/shaders/terrain/CompileTest.slang +++ b/res/shaders/terrain/CompileTest.slang @@ -1,4 +1,65 @@ +// Pointer to an invalid neighbor or index +const static int INVALID_POINTER = 4294967295; +// Possible culling state +const static int BACK_FACE_CULLED = -3; +const static int FRUSTUM_CULLED = -2; +const static int TOO_SMALL = -1; +const static int UNCHANGED_ELEMENT = 0; +const static int BISECT_ELEMENT = 1; +const static int SIMPLIFY_ELEMENT = 2; +const static int MERGED_ELEMENT = 3; + +// Bisector flags +const static int VISIBLE_BISECTOR = 0x1; +const static int MODIFIED_BISECTOR = 0x2; + + +// Possible splits +static const uint64_t NO_SPLIT = 0x00; +static const uint64_t CENTER_SPLIT = 0x01; +static const uint64_t RIGHT_SPLIT = 0x02; +static const uint64_t LEFT_SPLIT = 0x04; +static const uint64_t RIGHT_DOUBLE_SPLIT = (CENTER_SPLIT | RIGHT_SPLIT); +static const uint64_t LEFT_DOUBLE_SPLIT = (CENTER_SPLIT | LEFT_SPLIT); +static const uint64_t TRIPLE_SPLIT = (CENTER_SPLIT | RIGHT_SPLIT | LEFT_SPLIT); + +// Split buffer slots +static const uint64_t SPLIT_COUNTER = 0; +static const uint64_t SIMPLIFY_COUNTER = 1; +static const uint64_t CLASSIFY_COUNTER_OFFSET = 2; + + +struct BisectorData +{ + // Allocated indices for this bisector + uint32_t indices[3]; + + // Subvision that should be applied to this bisector + uint32_t subdivisionPattern; + + // Neighbor that should be processed + uint32_t problematicNeighbor; + + // State of this bisector (split, merge, etc) + uint32_t bisectorState; + + // Visibility and modification flags of a bisector + uint32_t flags; + + // ID used for the propagation + uint32_t propagationID; +}; + +uint HeapIDDepth(uint64_t x) +{ + uint depth = 0; + while (x > 0u) { + ++depth; + x >>= 1u; + } + return depth; +} struct ComputeParams { RWStructuredBuffer indirectDrawBuffer; @@ -6,45 +67,161 @@ struct ComputeParams RWStructuredBuffer classificationBuffer; RWStructuredBuffer allocateBuffer; RWStructuredBuffer memoryBuffer; + RWStructuredBuffer neighboursBuffer; + RWStructuredBuffer bisectorDataBuffer; RWStructuredBuffer propagateBuffer; RWStructuredBuffer simplifyBuffer; + RWStructuredBuffer bitFieldBuffer; }; ParameterBlock pParams; -// Split buffer slots -static const uint64_t SPLIT_COUNTER = 0; -static const uint64_t SIMPLIFY_COUNTER = 1; -static const uint64_t CLASSIFY_COUNTER_OFFSET = 2; -void ResetBuffers() +void SplitElement(uint currentID, uint baseDepth, uint dispatchID) { - pParams.memoryBuffer[0] = 0; - pParams.memoryBuffer[1] = 0; + // Get the neighbors information + uint4 cNeighbors = pParams.neighboursBuffer[currentID]; - pParams.classificationBuffer[SPLIT_COUNTER] = 0; - pParams.classificationBuffer[SIMPLIFY_COUNTER] = 0; + // If there is a neighbor X + if (cNeighbors.x != INVALID_POINTER) + { + // This is on the path of it's neighbor X + uint4 xNeighbors = pParams.neighboursBuffer[cNeighbors.x]; + if (xNeighbors.z == currentID && pParams.bisectorDataBuffer[cNeighbors.x].bisectorState != UNCHANGED_ELEMENT) + return; + } - pParams.allocateBuffer[0] = 0; + // If there is a neighbor Y + if (cNeighbors.y != INVALID_POINTER) + { + // This is on the path of it's neighbor Y + uint4 yNeighbors = pParams.neighboursBuffer[cNeighbors.y]; + if (yNeighbors.z == currentID && pParams.bisectorDataBuffer[cNeighbors.y].bisectorState != UNCHANGED_ELEMENT) + return; + } - pParams.propagateBuffer[0] = 0; - pParams.propagateBuffer[1] = 0; + // Depth of the current triangle + uint64_t heapID = pParams.heapIDBuffer[currentID]; + uint currentDepth = HeapIDDepth(heapID); - pParams.simplifyBuffer[0] = 0; + // Compute the maximal required memory for this subdivision + int maxRequiredMemory = 2 * (currentDepth - baseDepth) - 1; - pParams.indirectDrawBuffer[0] = 0; - pParams.indirectDrawBuffer[1] = 1; - pParams.indirectDrawBuffer[2] = 0; - pParams.indirectDrawBuffer[3] = 0; + // Get the twin information + uint twinID = cNeighbors.z; - pParams.indirectDrawBuffer[4] = 0; - pParams.indirectDrawBuffer[5] = 1; - pParams.indirectDrawBuffer[6] = 0; - pParams.indirectDrawBuffer[7] = 0; + // This avoid the massive over-reservation and saves a bunch of artifacts + if (twinID == INVALID_POINTER) + maxRequiredMemory = 1; + else if (pParams.neighboursBuffer[twinID].z == currentID) + maxRequiredMemory = 2; - pParams.indirectDrawBuffer[8] = 0; + // Try to reserve + int remainingMemory; + InterlockedAdd(pParams.memoryBuffer[1], -maxRequiredMemory, remainingMemory); + // Did someone manage to sneak-in while we were trying to pick the memory, add it back and try again + if (remainingMemory < maxRequiredMemory) + { + // Then add back the required memory and stop + InterlockedAdd(pParams.memoryBuffer[1], maxRequiredMemory, remainingMemory); + return; + } + + // Let's actually count the memory that we will be using + uint usedMemory = 1; + uint prevPattern; + InterlockedOr(pParams.bisectorDataBuffer[currentID].subdivisionPattern, CENTER_SPLIT, prevPattern); + + // If this is not zero, it means an other neighbor went faster than us, we restore the memory and leave. + if (prevPattern != 0) + { + InterlockedAdd(pParams.memoryBuffer[1], maxRequiredMemory, remainingMemory); + return; + } + + // Mark this for allocation + uint targetLocation = 0; + InterlockedAdd(pParams.allocateBuffer[0], 1, targetLocation); + pParams.allocateBuffer[1 + targetLocation] = currentID; + + // While we're not done (up the tree or everything is subdivided properly) + bool done = false; + while (!done) + { + // If this neighbor is not allocated, we're done. + if (twinID == INVALID_POINTER) + break; + + // Grab the bisector of the neighbor + uint64_t nHeapID = pParams.heapIDBuffer[twinID]; + BisectorData nBisectorData = pParams.bisectorDataBuffer[twinID]; + uint nDepth = HeapIDDepth(nHeapID); + uint4 nNeighbors = pParams.neighboursBuffer[twinID]; + + // If both triangles have the same depth + if (nDepth == currentDepth) + { + // Raised the center split + InterlockedOr(pParams.bisectorDataBuffer[twinID].subdivisionPattern, CENTER_SPLIT, prevPattern); + + // Only account for it if it was not raised before. + if (prevPattern == 0) + { + // Mark this for allocation + uint targetLocation = 0; + InterlockedAdd(pParams.allocateBuffer[0], 1, targetLocation); + pParams.allocateBuffer[1 + targetLocation] = twinID; + usedMemory++; + } + + // And we're done + done = true; + } + // If this node has already been subdivided, it means that we need to add the third subdivision and we're done + else + { + if (nNeighbors[0] == currentID) + InterlockedOr(pParams.bisectorDataBuffer[twinID].subdivisionPattern, RIGHT_DOUBLE_SPLIT, prevPattern); + else // if (nNeighbors[1] == currentID) + InterlockedOr(pParams.bisectorDataBuffer[twinID].subdivisionPattern, LEFT_DOUBLE_SPLIT, prevPattern); + + if (prevPattern != 0) + { + usedMemory++; + done = true; + } + else + { + // Mark this for allocation + uint targetLocation = 0; + InterlockedAdd(pParams.allocateBuffer[0], 1, targetLocation); + pParams.allocateBuffer[1 + targetLocation] = twinID; + + // Account for two splits + usedMemory += 2; + + // the new bisector that needs to be propagated + currentID = twinID; + currentDepth = nDepth; + twinID = pParams.neighboursBuffer[currentID].z; + } + } + } + int change = maxRequiredMemory - usedMemory; + if(change > 0) + { + // Add back the unused memory (in case) + InterlockedAdd(pParams.memoryBuffer[1], change, remainingMemory); + } } -[numthreads(1, 1, 1)] -void Reset() +[numthreads(64, 1, 1)] +void Split(uint dispatchID : SV_DispatchThreadID) { - ResetBuffers(); -} \ No newline at end of file + if (dispatchID >= pParams.classificationBuffer[SPLIT_COUNTER]) + return; + + // Grab the real elementID + uint currentID = pParams.classificationBuffer[CLASSIFY_COUNTER_OFFSET + dispatchID]; + + // Split the element + SplitElement(currentID, 7, dispatchID); +} diff --git a/res/shaders/terrain/Parameters.slang b/res/shaders/terrain/Parameters.slang index 5234cd6..b4bcbf8 100644 --- a/res/shaders/terrain/Parameters.slang +++ b/res/shaders/terrain/Parameters.slang @@ -29,9 +29,12 @@ struct UpdateCB struct DebugStruct { - uint3 neighbours; - int status; -} + int maxRequiredMemory; + int usedMemory; + uint memoryChange; + uint twinID; +}; + struct ComputeParams { @@ -59,6 +62,6 @@ struct ComputeParams RWStructuredBuffer modifiedBisectorIndices; RWStructuredBuffer lebPositionBuffer; StructuredBuffer lebMatrixCache; - RWStructuredBuffer debugBuffer; + globallycoherent RWStructuredBuffer debugBuffer; }; ParameterBlock pParams; diff --git a/res/shaders/terrain/update_utils.slang b/res/shaders/terrain/update_utils.slang index c39f0b1..b8e90d7 100644 --- a/res/shaders/terrain/update_utils.slang +++ b/res/shaders/terrain/update_utils.slang @@ -23,13 +23,30 @@ static const uint64_t SPLIT_COUNTER = 0; static const uint64_t SIMPLIFY_COUNTER = 1; static const uint64_t CLASSIFY_COUNTER_OFFSET = 2; +bool FrustumAABBIntersect(in Frustum frustum, float3 aabbMin, float3 aabbMax) +{ + float3 center = (aabbMax + aabbMin) * 0.5; + float3 extents = (aabbMax - aabbMin) * 0.5; + for (int i = 0; i < 4; i++) + { + Plane plane = frustum.sides[i]; + float3 normal_sign = sign(plane.n); + float3 test_point = center + extents * normal_sign; + + float dotProd = dot(test_point, plane.n); + if (dotProd + plane.d < 0) + return false; + } + return true; +} + int ClassifyBisector(in BisectorGeometry tri, uint depth) { // Check the triangle's visibility float3 triNormal = normalize(cross(tri.p[2] - tri.p[1], tri.p[0] - tri.p[1])); float3 triCenter = (tri.p[0] + tri.p[1] + tri.p[2]) / 3.0; float3 viewDir = normalize(-triCenter); - float FdotV = dot(viewDir, pViewParams.cameraForward_WS.xyz); + float FdotV = dot(viewDir, -pViewParams.cameraForward_WS.xyz); float VdotN = dot(viewDir, triNormal); // Here we don't use 0 as it introduces stability issues at grazing angles @@ -41,11 +58,11 @@ int ClassifyBisector(in BisectorGeometry tri, uint depth) float3 aabbMax = float3(max(max(tri.p[0].x, tri.p[1].x), tri.p[2].x), max(max(tri.p[0].y, tri.p[1].y), tri.p[2].y), max(max(tri.p[0].z, tri.p[1].z), tri.p[2].z)); // First we do a frustum culling pass - //if (!FrustumAABBIntersect(_FrustumPlanes, aabbMin, aabbMax)) - // return FRUSTUM_CULLED; + if (!FrustumAABBIntersect(pViewParams.viewFrustum, aabbMin, aabbMax)) + return FRUSTUM_CULLED; // Project the points on screen - float4x4 viewProjectionMatrix = mul(pViewParams.projectionMatrix, pViewParams.viewMatrix); + float4x4 viewProjectionMatrix = pParams.update.viewProjectionMatrix;//mul(pViewParams.projectionMatrix, pViewParams.viewMatrix); float4 p0P = mul(viewProjectionMatrix, float4(tri.p[0], 1.0)); p0P.xy = p0P.xy / p0P.w; p0P.xy = (p0P.xy * 0.5 + 0.5); @@ -166,16 +183,20 @@ void ClassifyElement(uint currentID, BisectorGeometry bis, uint totalNumElements pParams.bisectorDataBuffer[currentID] = cbisectorData; } -void SplitElement(uint currentID, uint baseDepth) +void SplitElement(uint currentID, uint baseDepth, uint dispatchID) { + DebugStruct debug; + debug.maxRequiredMemory = 0; + debug.usedMemory = 0; + debug.memoryChange = 0; // Get the neighbors information - uint3 cNeighbors = pParams.neighboursBuffer[currentID].xyz; + uint4 cNeighbors = pParams.neighboursBuffer[currentID]; // If there is a neighbor X if (cNeighbors.x != INVALID_POINTER) { // This is on the path of it's neighbor X - uint3 xNeighbors = pParams.neighboursBuffer[cNeighbors.x].xyz; + uint4 xNeighbors = pParams.neighboursBuffer[cNeighbors.x]; if (xNeighbors.z == currentID && pParams.bisectorDataBuffer[cNeighbors.x].bisectorState != UNCHANGED_ELEMENT) return; } @@ -184,7 +205,7 @@ void SplitElement(uint currentID, uint baseDepth) if (cNeighbors.y != INVALID_POINTER) { // This is on the path of it's neighbor Y - uint3 yNeighbors = pParams.neighboursBuffer[cNeighbors.y].xyz; + uint4 yNeighbors = pParams.neighboursBuffer[cNeighbors.y]; if (yNeighbors.z == currentID && pParams.bisectorDataBuffer[cNeighbors.y].bisectorState != UNCHANGED_ELEMENT) return; } @@ -205,10 +226,13 @@ void SplitElement(uint currentID, uint baseDepth) else if (pParams.neighboursBuffer[twinID].z == currentID) maxRequiredMemory = 2; + debug.maxRequiredMemory = maxRequiredMemory; + debug.twinID = twinID; + // Try to reserve int remainingMemory; InterlockedAdd(pParams.memoryBuffer[1], -maxRequiredMemory, remainingMemory); - + debug.memoryChange = -maxRequiredMemory; // Did someone manage to sneak-in while we were trying to pick the memory, add it back and try again if (remainingMemory < maxRequiredMemory) { @@ -218,7 +242,7 @@ void SplitElement(uint currentID, uint baseDepth) } // Let's actually count the memory that we will be using - uint usedMemory = 1; + int usedMemory = 1; uint prevPattern; InterlockedOr(pParams.bisectorDataBuffer[currentID].subdivisionPattern, CENTER_SPLIT, prevPattern); @@ -246,7 +270,7 @@ void SplitElement(uint currentID, uint baseDepth) uint64_t nHeapID = pParams.heapIDBuffer[twinID]; BisectorData nBisectorData = pParams.bisectorDataBuffer[twinID]; uint nDepth = HeapIDDepth(nHeapID); - uint3 nNeighbors = pParams.neighboursBuffer[twinID].xyz; + uint4 nNeighbors = pParams.neighboursBuffer[twinID]; // If both triangles have the same depth if (nDepth == currentDepth) @@ -297,9 +321,13 @@ void SplitElement(uint currentID, uint baseDepth) } } } + int change = maxRequiredMemory - usedMemory; // Add back the unused memory (in case) - InterlockedAdd(pParams.memoryBuffer[1], max(maxRequiredMemory - usedMemory, 0), remainingMemory); + InterlockedAdd(pParams.memoryBuffer[1], change, remainingMemory); + debug.memoryChange += change; + debug.usedMemory = usedMemory; + pParams.debugBuffer[dispatchID] = debug; } void AllocateElement(uint currentID) @@ -335,7 +363,7 @@ void AllocateElement(uint currentID) void evaluate_neighbors(uint currentID, uint bisectorID, out uint resX, out uint resY) { BisectorData nBisectorData = pParams.bisectorDataBuffer[bisectorID]; - uint3 nNeighbors = pParams.neighboursBuffer[bisectorID].xyz; + uint4 nNeighbors = pParams.neighboursBuffer[bisectorID]; if (nBisectorData.subdivisionPattern == 0x01) { resX = nBisectorData.indices[SUBLING0_ID]; @@ -399,7 +427,7 @@ void BisectElement(uint currentID) uint currentSubdiv = cBisectorData.subdivisionPattern; // neighbors of the parent - uint3 cNeighbors = pParams.neighboursBuffer[currentID].xyz; + uint4 cNeighbors = pParams.neighboursBuffer[currentID]; uint p_n0 = cNeighbors[0]; uint p_n1 = cNeighbors[1]; uint p_n2 = cNeighbors[2]; @@ -421,15 +449,15 @@ void BisectElement(uint currentID) pParams.heapIDBuffer[siblingID0] = 2 * baseHeapID + 1; // Update the neighbors - uint3 modifiedNeighbors; + uint4 modifiedNeighbors; modifiedNeighbors[0] = siblingID0; modifiedNeighbors[1] = resX; modifiedNeighbors[2] = p_n0; - pParams.neighboursOutputBuffer[currentID] = uint4(modifiedNeighbors, 0); + pParams.neighboursOutputBuffer[currentID] = modifiedNeighbors; modifiedNeighbors[0] = resY; modifiedNeighbors[1] = currentID; modifiedNeighbors[2] = p_n1; - pParams.neighboursOutputBuffer[siblingID0] = uint4(modifiedNeighbors, 0); + pParams.neighboursOutputBuffer[siblingID0] = modifiedNeighbors; // Keep track of the parent BisectorData modifiedBisector = cBisectorData; @@ -444,7 +472,7 @@ void BisectElement(uint currentID) pParams.bisectorDataBuffer[siblingID0] = modifiedBisector; // Mark this for propagation - uint targetLocation = 0; + uint targetLocation; InterlockedAdd(pParams.propagateBuffer[0], 1, targetLocation); pParams.propagateBuffer[2 + targetLocation] = siblingID0; } @@ -463,19 +491,19 @@ void BisectElement(uint currentID) pParams.heapIDBuffer[siblingID0] = 2 * baseHeapID + 1; pParams.heapIDBuffer[siblingID1] = 4 * baseHeapID + 1; - uint3 modifiedNeighbors; + uint4 modifiedNeighbors; modifiedNeighbors[0] = siblingID1; modifiedNeighbors[1] = res0X; modifiedNeighbors[2] = siblingID0; - pParams.neighboursOutputBuffer[currentID] = uint4(modifiedNeighbors, 0); + pParams.neighboursOutputBuffer[currentID] = modifiedNeighbors; modifiedNeighbors[0] = res1Y; modifiedNeighbors[1] = currentID; modifiedNeighbors[2] = p_n1; - pParams.neighboursOutputBuffer[siblingID0] = uint4(modifiedNeighbors, 0); + pParams.neighboursOutputBuffer[siblingID0] = modifiedNeighbors; modifiedNeighbors[0] = res0Y; modifiedNeighbors[1] = currentID; modifiedNeighbors[2] = res1X; - pParams.neighboursOutputBuffer[siblingID1] = uint4(modifiedNeighbors, 0); + pParams.neighboursOutputBuffer[siblingID1] = modifiedNeighbors; // Keep track of the parent BisectorData modifiedBisector = cBisectorData; @@ -497,7 +525,7 @@ void BisectElement(uint currentID) pParams.bisectorDataBuffer[siblingID1] = modifiedBisector; // Mark this for propagation - uint targetLocation = 0; + uint targetLocation; InterlockedAdd(pParams.propagateBuffer[0], 1, targetLocation); pParams.propagateBuffer[2 + targetLocation] = siblingID0; } @@ -516,19 +544,19 @@ void BisectElement(uint currentID) pParams.heapIDBuffer[siblingID0] = 4 * baseHeapID + 2; pParams.heapIDBuffer[siblingID1] = 4 * baseHeapID + 3; - uint3 modifiedNeighbors; + uint4 modifiedNeighbors; modifiedNeighbors[0] = siblingID1; modifiedNeighbors[1] = res1X; modifiedNeighbors[2] = p_n0; - pParams.neighboursOutputBuffer[currentID] = uint4(modifiedNeighbors, 0); + pParams.neighboursOutputBuffer[currentID] = modifiedNeighbors; modifiedNeighbors[0] = siblingID1; modifiedNeighbors[1] = res0X; modifiedNeighbors[2] = res1Y; - pParams.neighboursOutputBuffer[siblingID0] = uint4(modifiedNeighbors, 0); + pParams.neighboursOutputBuffer[siblingID0] = modifiedNeighbors; modifiedNeighbors[0] = res0Y; modifiedNeighbors[1] = siblingID0; modifiedNeighbors[2] = currentID; - pParams.neighboursOutputBuffer[siblingID1] = uint4(modifiedNeighbors, 0); + pParams.neighboursOutputBuffer[siblingID1] = modifiedNeighbors; // Keep track of the parent BisectorData modifiedBisector = cBisectorData; @@ -568,23 +596,23 @@ void BisectElement(uint currentID) pParams.heapIDBuffer[siblingID1] = 4 * baseHeapID + 1; pParams.heapIDBuffer[siblingID2] = 4 * baseHeapID + 3; - uint3 modifiedNeighbors; + uint4 modifiedNeighbors; modifiedNeighbors[0] = siblingID1; modifiedNeighbors[1] = res0X; modifiedNeighbors[2] = siblingID2; - pParams.neighboursOutputBuffer[currentID] = uint4(modifiedNeighbors, 0); + pParams.neighboursOutputBuffer[currentID] = modifiedNeighbors; modifiedNeighbors[0] = siblingID2; modifiedNeighbors[1] = res1X; modifiedNeighbors[2] = res2Y; - pParams.neighboursOutputBuffer[siblingID0] = uint4(modifiedNeighbors, 0); + pParams.neighboursOutputBuffer[siblingID0] = modifiedNeighbors; modifiedNeighbors[0] = res0Y; modifiedNeighbors[1] = currentID; modifiedNeighbors[2] = res2X; - pParams.neighboursOutputBuffer[siblingID1] = uint4(modifiedNeighbors, 0); + pParams.neighboursOutputBuffer[siblingID1] = modifiedNeighbors; modifiedNeighbors[0] = res1Y; modifiedNeighbors[1] = siblingID0; modifiedNeighbors[2] = currentID; - pParams.neighboursOutputBuffer[siblingID2] = uint4(modifiedNeighbors, 0); + pParams.neighboursOutputBuffer[siblingID2] = modifiedNeighbors; // Keep track of the parent BisectorData modifiedBisector = cBisectorData; @@ -930,7 +958,8 @@ void ValidateBisector(uint currentID) return; // Load the bisector data of the target element - uint3 cNeighbors = pParams.neighboursBuffer[currentID].xyz; + uint4 cNeighbors = pParams.neighboursBuffer[currentID]; + uint4 tempnNeighbours[3]; bool failed = false; uint targetNeighbor = INVALID_POINTER; @@ -941,7 +970,8 @@ void ValidateBisector(uint currentID) if (neighborID != INVALID_POINTER) { bool found = false; - uint3 nNeighbors = pParams.neighboursBuffer[neighborID].xyz; + uint4 nNeighbors = pParams.neighboursBuffer[neighborID]; + tempnNeighbours[i] = nNeighbors; for (uint j = 0; j < 3; ++j) { if (nNeighbors[j] == currentID) diff --git a/src/Engine/Graphics/CBT/CBT.cpp b/src/Engine/Graphics/CBT/CBT.cpp index a6a0886..8d5d265 100644 --- a/src/Engine/Graphics/CBT/CBT.cpp +++ b/src/Engine/Graphics/CBT/CBT.cpp @@ -124,7 +124,7 @@ CPUMesh Seele::generateCPUMesh(uint32 cbtNumElements) { neighbours.x = halfedge.prevID != -1 ? cbtNumElements + halfedge.prevID : UINT32_MAX; neighbours.y = halfedge.nextID != -1 ? cbtNumElements + halfedge.nextID : UINT32_MAX; neighbours.z = halfedge.twinID != -1 ? cbtNumElements + halfedge.twinID : UINT32_MAX; - result.neighborsArray[elementID] = UVector4(neighbours, 1); + result.neighborsArray[elementID] = UVector4(neighbours, 0); result.basePoints[3 * halfedgeIdx + 2] = basePoints[halfedge.vertexID]; @@ -404,6 +404,7 @@ void MeshUpdater::evaluateLeb(const BaseMesh& baseMesh, CBTMesh& mesh, Gfx::PDes Gfx::PUniformBuffer geometryBuffer, Gfx::PUniformBuffer updateBuffer, Gfx::PShaderBuffer lebMatrixCache, bool clear, bool complete) { if (clear) { + graphics->beginDebugRegion("ClearLEB"); Gfx::PDescriptorSet set = layout->allocateDescriptorSet(); set->updateBuffer(GEOMETRY_CB, 0, geometryBuffer); set->updateBuffer(LEB_POSITION_BUFFER, 0, mesh.currentVertexBuffer); @@ -415,8 +416,10 @@ void MeshUpdater::evaluateLeb(const BaseMesh& baseMesh, CBTMesh& mesh, Gfx::PDes graphics->executeCommands(std::move(clearCmd)); mesh.currentVertexBuffer->pipelineBarrier(Gfx::SE_ACCESS_SHADER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT, Gfx::SE_ACCESS_SHADER_READ_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT); + graphics->endDebugRegion(); } graphics->waitDeviceIdle(); + graphics->beginDebugRegion("EvaluateLEB"); Gfx::PDescriptorSet set = layout->allocateDescriptorSet(); set->updateBuffer(GEOMETRY_CB, 0, geometryBuffer); set->updateBuffer(UPDATE_CB, 0, updateBuffer); @@ -436,6 +439,7 @@ void MeshUpdater::evaluateLeb(const BaseMesh& baseMesh, CBTMesh& mesh, Gfx::PDes graphics->executeCommands(std::move(evalCmd)); mesh.lebVertexBuffer->pipelineBarrier(Gfx::SE_ACCESS_SHADER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT, Gfx::SE_ACCESS_SHADER_READ_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT); + graphics->endDebugRegion(); } void MeshUpdater::update(CBTMesh& mesh, Gfx::PDescriptorSet viewParamsSet, Gfx::PUniformBuffer geometryCB, Gfx::PUniformBuffer updateCB) { @@ -444,8 +448,8 @@ void MeshUpdater::update(CBTMesh& mesh, Gfx::PDescriptorSet viewParamsSet, Gfx:: Gfx::PShaderBuffer nextNeighborsBuffer = mesh.neighborsBuffers[nextNeighborsBufferIdx]; resetBuffers(mesh); - - // classify + graphics->waitDeviceIdle(); + graphics->beginDebugRegion("Classify"); { Gfx::PDescriptorSet set = layout->allocateDescriptorSet(); set->updateBuffer(GEOMETRY_CB, 0, geometryCB); @@ -467,8 +471,10 @@ void MeshUpdater::update(CBTMesh& mesh, Gfx::PDescriptorSet viewParamsSet, Gfx:: mesh.updateBuffer->pipelineBarrier(Gfx::SE_ACCESS_SHADER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT, Gfx::SE_ACCESS_SHADER_READ_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT); } + graphics->endDebugRegion(); + graphics->waitDeviceIdle(); - // prepare indirect pass + graphics->beginDebugRegion("PrepareIndirect"); { Gfx::PDescriptorSet set = layout->allocateDescriptorSet(); set->updateBuffer(ALLOCATE_BUFFER, 0, mesh.classificationBuffer); @@ -482,9 +488,10 @@ void MeshUpdater::update(CBTMesh& mesh, Gfx::PDescriptorSet viewParamsSet, Gfx:: indirectBuffer->pipelineBarrier(Gfx::SE_ACCESS_SHADER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT, Gfx::SE_ACCESS_SHADER_READ_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT); } + graphics->endDebugRegion(); graphics->waitDeviceIdle(); - // split pass + graphics->beginDebugRegion("Split"); { Gfx::PDescriptorSet set = layout->allocateDescriptorSet(); set->updateBuffer(GEOMETRY_CB, 0, geometryCB); @@ -508,9 +515,10 @@ void MeshUpdater::update(CBTMesh& mesh, Gfx::PDescriptorSet viewParamsSet, Gfx:: mesh.allocateBuffer->pipelineBarrier(Gfx::SE_ACCESS_SHADER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT, Gfx::SE_ACCESS_SHADER_READ_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT); } + graphics->endDebugRegion(); graphics->waitDeviceIdle(); - // prepare indirect pass + graphics->beginDebugRegion("PrepareIndirect"); { Gfx::PDescriptorSet set = layout->allocateDescriptorSet(); set->updateBuffer(ALLOCATE_BUFFER, 0, mesh.allocateBuffer); @@ -524,9 +532,10 @@ void MeshUpdater::update(CBTMesh& mesh, Gfx::PDescriptorSet viewParamsSet, Gfx:: indirectBuffer->pipelineBarrier(Gfx::SE_ACCESS_SHADER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT, Gfx::SE_ACCESS_SHADER_READ_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT); } + graphics->endDebugRegion(); graphics->waitDeviceIdle(); - // Allocate Pass + graphics->beginDebugRegion("Allocate"); { Gfx::PDescriptorSet set = layout->allocateDescriptorSet(); set->updateBuffer(GEOMETRY_CB, 0, geometryCB); @@ -546,17 +555,19 @@ void MeshUpdater::update(CBTMesh& mesh, Gfx::PDescriptorSet viewParamsSet, Gfx:: mesh.updateBuffer->pipelineBarrier(Gfx::SE_ACCESS_SHADER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT, Gfx::SE_ACCESS_SHADER_READ_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT); } + graphics->endDebugRegion(); graphics->waitDeviceIdle(); - // copy + graphics->beginDebugRegion("Copy"); currentNeighborsBuffer->pipelineBarrier(Gfx::SE_ACCESS_SHADER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT, Gfx::SE_ACCESS_TRANSFER_READ_BIT, Gfx::SE_PIPELINE_STAGE_TRANSFER_BIT); graphics->copyBuffer(currentNeighborsBuffer, nextNeighborsBuffer); nextNeighborsBuffer->pipelineBarrier(Gfx::SE_ACCESS_TRANSFER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_TRANSFER_BIT, Gfx::SE_ACCESS_SHADER_READ_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT); + graphics->endDebugRegion(); graphics->waitDeviceIdle(); - // bisect + graphics->beginDebugRegion("Bisect"); { Gfx::PDescriptorSet set = layout->allocateDescriptorSet(); set->updateBuffer(GEOMETRY_CB, 0, geometryCB); @@ -579,9 +590,10 @@ void MeshUpdater::update(CBTMesh& mesh, Gfx::PDescriptorSet viewParamsSet, Gfx:: nextNeighborsBuffer->pipelineBarrier(Gfx::SE_ACCESS_SHADER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT, Gfx::SE_ACCESS_SHADER_READ_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT); } + graphics->endDebugRegion(); graphics->waitDeviceIdle(); - // Prepare indirect pass + graphics->beginDebugRegion("PrepareIndirect"); { Gfx::PDescriptorSet set = layout->allocateDescriptorSet(); set->updateBuffer(ALLOCATE_BUFFER, 0, mesh.propagateBuffer); @@ -595,9 +607,10 @@ void MeshUpdater::update(CBTMesh& mesh, Gfx::PDescriptorSet viewParamsSet, Gfx:: indirectBuffer->pipelineBarrier(Gfx::SE_ACCESS_SHADER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT, Gfx::SE_ACCESS_SHADER_READ_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT); } + graphics->endDebugRegion(); graphics->waitDeviceIdle(); - // propagate split pass + graphics->beginDebugRegion("PropagateBisect"); { Gfx::PDescriptorSet set = layout->allocateDescriptorSet(); set->updateBuffer(GEOMETRY_CB, 0, geometryCB); @@ -615,9 +628,10 @@ void MeshUpdater::update(CBTMesh& mesh, Gfx::PDescriptorSet viewParamsSet, Gfx:: mesh.updateBuffer->pipelineBarrier(Gfx::SE_ACCESS_SHADER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT, Gfx::SE_ACCESS_SHADER_READ_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT); } + graphics->endDebugRegion(); graphics->waitDeviceIdle(); - // prepare simplify + graphics->beginDebugRegion("PrepareSimplify"); { Gfx::PDescriptorSet set = layout->allocateDescriptorSet(); set->updateBuffer(GEOMETRY_CB, 0, geometryCB); @@ -637,9 +651,10 @@ void MeshUpdater::update(CBTMesh& mesh, Gfx::PDescriptorSet viewParamsSet, Gfx:: mesh.simplificationBuffer->pipelineBarrier(Gfx::SE_ACCESS_SHADER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT, Gfx::SE_ACCESS_SHADER_READ_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT); } + graphics->endDebugRegion(); graphics->waitDeviceIdle(); - // Prepare Indirect Simplify + graphics->beginDebugRegion("PrepareIndirectSimplify"); { Gfx::PDescriptorSet set = layout->allocateDescriptorSet(); set->updateBuffer(ALLOCATE_BUFFER, 0, mesh.simplificationBuffer); @@ -653,9 +668,10 @@ void MeshUpdater::update(CBTMesh& mesh, Gfx::PDescriptorSet viewParamsSet, Gfx:: indirectBuffer->pipelineBarrier(Gfx::SE_ACCESS_SHADER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT, Gfx::SE_ACCESS_SHADER_READ_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT); } + graphics->endDebugRegion(); graphics->waitDeviceIdle(); - // Simplify Pass + graphics->beginDebugRegion("Simplify"); { Gfx::PDescriptorSet set = layout->allocateDescriptorSet(); set->updateBuffer(GEOMETRY_CB, 0, geometryCB); @@ -677,9 +693,10 @@ void MeshUpdater::update(CBTMesh& mesh, Gfx::PDescriptorSet viewParamsSet, Gfx:: nextNeighborsBuffer->pipelineBarrier(Gfx::SE_ACCESS_SHADER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT, Gfx::SE_ACCESS_SHADER_READ_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT); } + graphics->endDebugRegion(); graphics->waitDeviceIdle(); - // Prepare Indirect Propagate Simplify + graphics->beginDebugRegion("PrepareIndirectPropagateSimplify"); { Gfx::PDescriptorSet set = layout->allocateDescriptorSet(); set->updateBuffer(ALLOCATE_BUFFER, 0, mesh.propagateBuffer); @@ -693,9 +710,10 @@ void MeshUpdater::update(CBTMesh& mesh, Gfx::PDescriptorSet viewParamsSet, Gfx:: indirectBuffer->pipelineBarrier(Gfx::SE_ACCESS_SHADER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT, Gfx::SE_ACCESS_SHADER_READ_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT); } + graphics->endDebugRegion(); graphics->waitDeviceIdle(); - // Propagate Simplify Pass + graphics->beginDebugRegion("PropagateSimplify"); { Gfx::PDescriptorSet set = layout->allocateDescriptorSet(); set->updateBuffer(GEOMETRY_CB, 0, geometryCB); @@ -714,9 +732,10 @@ void MeshUpdater::update(CBTMesh& mesh, Gfx::PDescriptorSet viewParamsSet, Gfx:: nextNeighborsBuffer->pipelineBarrier(Gfx::SE_ACCESS_SHADER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT, Gfx::SE_ACCESS_SHADER_READ_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT); } + graphics->endDebugRegion(); graphics->waitDeviceIdle(); - // Update Tree + graphics->beginDebugRegion("Update Tree"); { Gfx::PDescriptorSet set = layout->allocateDescriptorSet(); set->updateBuffer(CBT_BUFFER0, 0, mesh.gpuCBT.bufferArray[0]); @@ -747,6 +766,7 @@ void MeshUpdater::update(CBTMesh& mesh, Gfx::PDescriptorSet viewParamsSet, Gfx:: mesh.gpuCBT.bufferArray[0]->pipelineBarrier(Gfx::SE_ACCESS_SHADER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT, Gfx::SE_ACCESS_SHADER_READ_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT); } + graphics->endDebugRegion(); graphics->waitDeviceIdle(); mesh.currentNeighborsBufferIdx = nextNeighborsBufferIdx; @@ -778,6 +798,7 @@ void MeshUpdater::validation(const CBTMesh& mesh, Gfx::PUniformBuffer geometryCB } void MeshUpdater::resetBuffers(const CBTMesh& mesh) { + graphics->beginDebugRegion("ResetBuffers"); Gfx::PDescriptorSet set = layout->allocateDescriptorSet(); set->updateBuffer(CBT_BUFFER0, 0, mesh.gpuCBT.bufferArray[0]); set->updateBuffer(CBT_BUFFER1, 0, mesh.gpuCBT.bufferArray[1]); @@ -796,12 +817,14 @@ void MeshUpdater::resetBuffers(const CBTMesh& mesh) { graphics->executeCommands(std::move(resetCmd)); memoryBuffer->pipelineBarrier(Gfx::SE_ACCESS_SHADER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT, Gfx::SE_ACCESS_SHADER_READ_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT); + graphics->endDebugRegion(); } void MeshUpdater::prepareIndirection(CBTMesh& mesh, Gfx::PUniformBuffer geometryCB) { uint32 numGroups = (mesh.totalNumElements + WORKGROUP_SIZE - 1) / WORKGROUP_SIZE; - // Bitsector indexation + graphics->waitDeviceIdle(); + graphics->beginDebugRegion("BisectorIndexation"); { Gfx::PDescriptorSet set = layout->allocateDescriptorSet(); set->updateBuffer(GEOMETRY_CB, 0, geometryCB); @@ -821,7 +844,9 @@ void MeshUpdater::prepareIndirection(CBTMesh& mesh, Gfx::PUniformBuffer geometry } mesh.indirectDrawBuffer->pipelineBarrier(Gfx::SE_ACCESS_SHADER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT, Gfx::SE_ACCESS_SHADER_READ_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT); - // Prepare bisector indirect dispatch + graphics->endDebugRegion(); + graphics->waitDeviceIdle(); + graphics->beginDebugRegion("PrepareBisectorIndirectDispatch"); { Gfx::PDescriptorSet set = layout->allocateDescriptorSet(); set->updateBuffer(INDIRECT_DRAW_BUFFER, 0, mesh.indirectDrawBuffer); @@ -836,6 +861,8 @@ void MeshUpdater::prepareIndirection(CBTMesh& mesh, Gfx::PUniformBuffer geometry mesh.indirectDispatchBuffer->pipelineBarrier(Gfx::SE_ACCESS_SHADER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT, Gfx::SE_ACCESS_SHADER_READ_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT); } + graphics->endDebugRegion(); + graphics->waitDeviceIdle(); } bool MeshUpdater::checkIfValid() { return true; } diff --git a/src/Engine/Graphics/Graphics.h b/src/Engine/Graphics/Graphics.h index f0ab1b6..2117048 100644 --- a/src/Engine/Graphics/Graphics.h +++ b/src/Engine/Graphics/Graphics.h @@ -97,6 +97,9 @@ class Graphics { virtual Gfx::OPipelineStatisticsQuery createPipelineStatisticsQuery(const std::string& name = "") = 0; virtual Gfx::OTimestampQuery createTimestampQuery(uint64 numTimestamps, const std::string& name = "") = 0; + virtual void beginDebugRegion(const std::string& name) = 0; + virtual void endDebugRegion() = 0; + virtual void resolveTexture(PTexture source, PTexture destination) = 0; virtual void copyTexture(PTexture src, PTexture dst) = 0; diff --git a/src/Engine/Graphics/Initializer.h b/src/Engine/Graphics/Initializer.h index bd45e80..7ab9916 100644 --- a/src/Engine/Graphics/Initializer.h +++ b/src/Engine/Graphics/Initializer.h @@ -34,7 +34,7 @@ struct WindowCreateInfo { }; struct ViewportCreateInfo { URect dimensions; - float fieldOfView = 1.222f; // 70 deg + float fieldOfView = glm::radians(70.0f); Gfx::SeSampleCountFlags numSamples; }; // doesnt own the data, only proxy it diff --git a/src/Engine/Graphics/RenderPass/RenderPass.cpp b/src/Engine/Graphics/RenderPass/RenderPass.cpp index aa855b4..2177ce2 100644 --- a/src/Engine/Graphics/RenderPass/RenderPass.cpp +++ b/src/Engine/Graphics/RenderPass/RenderPass.cpp @@ -25,6 +25,28 @@ RenderPass::~RenderPass() {} void RenderPass::beginFrame(const Component::Camera& cam) { auto screenDim = Vector2(static_cast(viewport->getWidth()), static_cast(viewport->getHeight())); viewParams = { + .viewFrustum = + { + .planes = + { + Plane{ + .n = Vector(-0.62628, 0, 0.7796), + .d = 3.898, + }, + Plane{ + .n = Vector(0.62628, 0, 0.7796), + .d = 3.898, + }, + Plane{ + .n = Vector(0, 0.81915, 0.57358), + .d = 2.86788, + }, + Plane{ + .n = Vector(0, -0.81915, 0.57358), + .d = 2.86788, + }, + }, + }, .viewMatrix = cam.getViewMatrix(), .inverseViewMatrix = glm::inverse(cam.getViewMatrix()), .projectionMatrix = viewport->getProjectionMatrix(), diff --git a/src/Engine/Graphics/RenderPass/TerrainRenderer.cpp b/src/Engine/Graphics/RenderPass/TerrainRenderer.cpp index 7db50ad..69d8745 100644 --- a/src/Engine/Graphics/RenderPass/TerrainRenderer.cpp +++ b/src/Engine/Graphics/RenderPass/TerrainRenderer.cpp @@ -10,13 +10,13 @@ using namespace Seele; TerrainRenderer::TerrainRenderer(Gfx::PGraphics graphics, PScene scene, Gfx::PDescriptorLayout viewParamsLayout, Gfx::PDescriptorSet viewParamsSet) : graphics(graphics), scene(scene) { - //Gfx::OPipelineLayout test = graphics->createPipelineLayout(); - //graphics->beginShaderCompilation(ShaderCompilationInfo{ - // .modules = {"CompileTest"}, - // .entryPoints = {{"Reset", "CompileTest"}}, - // .rootSignature = test, - //}); - //graphics->createComputeShader({0}); + Gfx::OPipelineLayout test = graphics->createPipelineLayout(); + graphics->beginShaderCompilation(ShaderCompilationInfo{ + .modules = {"CompileTest"}, + .entryPoints = {{"Split", "CompileTest"}}, + .rootSignature = test, + }); + graphics->createComputeShader({0}); meshUpdater.init(graphics, viewParamsLayout); lebCache.init(graphics, 5); CBT<18> cbt; @@ -223,9 +223,9 @@ TerrainRenderer::TerrainRenderer(Gfx::PGraphics graphics, PScene scene, Gfx::PDe Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT); UpdateCB updateCB = { .viewProjectionMatrix = Matrix4(0), - .triangleSize = 10.0f, + .triangleSize = 60.0f, .maxSubdivisionDepth = 63, - .fov = 70.0f, + .fov = 1.22173f, .farPlaneDistance = 1000.0f, }; updateBuffer = graphics->createUniformBuffer(UniformBufferCreateInfo{ @@ -265,6 +265,8 @@ TerrainRenderer::TerrainRenderer(Gfx::PGraphics graphics, PScene scene, Gfx::PDe graphics->waitDeviceIdle(); applyDeformation(viewParamsSet); graphics->waitDeviceIdle(); + meshUpdater.validation(plainMesh, geometryBuffer); + graphics->waitDeviceIdle(); } TerrainRenderer::~TerrainRenderer() {} @@ -274,9 +276,9 @@ static bool first = true; void TerrainRenderer::beginFrame(Gfx::PDescriptorSet viewParamsSet, const Component::Camera& cam) { UpdateCB updateCB = { .viewProjectionMatrix = viewport->getProjectionMatrix() * cam.getViewMatrix(), - .triangleSize = 10.0f, + .triangleSize = 60.0f, .maxSubdivisionDepth = 63, - .fov = 70.0f, + .fov = 1.22173f, .farPlaneDistance = 1000.0f, }; updateBuffer = graphics->createUniformBuffer(UniformBufferCreateInfo{ @@ -296,6 +298,8 @@ void TerrainRenderer::beginFrame(Gfx::PDescriptorSet viewParamsSet, const Compon graphics->waitDeviceIdle(); applyDeformation(viewParamsSet); graphics->waitDeviceIdle(); + meshUpdater.validation(plainMesh, geometryBuffer); + graphics->waitDeviceIdle(); } Gfx::ORenderCommand TerrainRenderer::render(Gfx::PDescriptorSet viewParamsSet) { @@ -344,6 +348,7 @@ void TerrainRenderer::setViewport(Gfx::PViewport _viewport, Gfx::PRenderPass ren } void TerrainRenderer::applyDeformation(Gfx::PDescriptorSet viewParamsSet) { + graphics->beginDebugRegion("ApplyDeformation"); Gfx::PDescriptorSet set = meshUpdater.layout->allocateDescriptorSet(); set->updateBuffer(GEOMETRY_CB, 0, geometryBuffer); set->updateBuffer(INDIRECT_DRAW_BUFFER, 0, plainMesh.indirectDrawBuffer); @@ -358,4 +363,5 @@ void TerrainRenderer::applyDeformation(Gfx::PDescriptorSet viewParamsSet) { graphics->executeCommands(std::move(command)); plainMesh.currentVertexBuffer->pipelineBarrier(Gfx::SE_ACCESS_SHADER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT, Gfx::SE_ACCESS_SHADER_READ_BIT, Gfx::SE_PIPELINE_STAGE_VERTEX_SHADER_BIT); + graphics->endDebugRegion(); } diff --git a/src/Engine/Graphics/Vulkan/Graphics.cpp b/src/Engine/Graphics/Vulkan/Graphics.cpp index 834555c..eb20260 100644 --- a/src/Engine/Graphics/Vulkan/Graphics.cpp +++ b/src/Engine/Graphics/Vulkan/Graphics.cpp @@ -33,6 +33,8 @@ thread_local PCommandPool Seele::Vulkan::Graphics::transferCommands = nullptr; PFN_vkCmdDrawMeshTasksEXT cmdDrawMeshTasks; PFN_vkCmdDrawMeshTasksIndirectEXT cmdDrawMeshTasksIndirect; PFN_vkSetDebugUtilsObjectNameEXT setDebugUtilsObjectName; +PFN_vkQueueBeginDebugUtilsLabelEXT queueBeginDebugUtilsLabelEXT; +PFN_vkQueueEndDebugUtilsLabelEXT queueEndDebugUtilsLabelEXT; PFN_vkCreateAccelerationStructureKHR createAccelerationStructure; PFN_vkCmdBuildAccelerationStructuresKHR cmdBuildAccelerationStructures; PFN_vkGetAccelerationStructureBuildSizesKHR getAccelerationStructureBuildSize; @@ -57,6 +59,18 @@ VkResult vkSetDebugUtilsObjectNameEXT(VkDevice device, const VkDebugUtilsObjectN return VK_SUCCESS; } +void vkQueueBeginDebugUtilsLabelEXT(VkQueue queue, const VkDebugUtilsLabelEXT* pLabelInfo) { + if (queueBeginDebugUtilsLabelEXT != nullptr) { + queueBeginDebugUtilsLabelEXT(queue, pLabelInfo); + } +} + +void vkQueueEndDebugUtilsLabelEXT(VkQueue queue) { + if (queueEndDebugUtilsLabelEXT != nullptr) { + queueEndDebugUtilsLabelEXT(queue); + } +} + VkResult vkCreateAccelerationStructureKHR(VkDevice device, const VkAccelerationStructureCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkAccelerationStructureKHR* pAccelerationStructure) { return createAccelerationStructure(device, pCreateInfo, pAllocator, pAccelerationStructure); @@ -164,7 +178,7 @@ void Graphics::endRenderPass() { getGraphicsCommands()->getCommands()->endRender void Graphics::waitDeviceIdle() { getGraphicsCommands()->submitCommands(); - vkDeviceWaitIdle(handle); + vkDeviceWaitIdle(handle); getGraphicsCommands()->refreshCommands(); } @@ -288,6 +302,17 @@ Gfx::OTimestampQuery Graphics::createTimestampQuery(uint64 numTimestamps, const return new TimestampQuery(this, name); } +void Graphics::beginDebugRegion(const std::string& name) { + VkDebugUtilsLabelEXT label = { + .sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_LABEL_EXT, + .pNext = nullptr, + .pLabelName = name.c_str(), + }; + vkQueueBeginDebugUtilsLabelEXT(queues[graphicsQueue]->getHandle(), &label); +} + +void Graphics::endDebugRegion() { vkQueueEndDebugUtilsLabelEXT(queues[graphicsQueue]->getHandle()); } + void Graphics::resolveTexture(Gfx::PTexture source, Gfx::PTexture destination) { PTextureBase sourceTex = source.cast(); PTextureBase destinationTex = destination.cast(); @@ -389,7 +414,6 @@ void Graphics::copyBuffer(Gfx::PShaderBuffer srcBuffer, Gfx::PShaderBuffer dstBu vkCmdCopyBuffer(getGraphicsCommands()->getCommands()->getHandle(), src->getHandle(), dst->getHandle(), 1, ®ion); } - Gfx::OBottomLevelAS Graphics::createBottomLevelAccelerationStructure(const Gfx::BottomLevelASCreateInfo& createInfo) { return new BottomLevelAS(this, createInfo); } @@ -401,9 +425,9 @@ Gfx::OTopLevelAS Graphics::createTopLevelAccelerationStructure(const Gfx::TopLev void Graphics::buildBottomLevelAccelerationStructures(Array data) { Gfx::PShaderBuffer verticesBuffer = StaticMeshVertexData::getInstance()->getPositionBuffer(); Gfx::PIndexBuffer indexBuffer = StaticMeshVertexData::getInstance()->getIndexBuffer(); - + // Setup vertices and indices for a single triangle - + // Create buffers for the bottom level geometry // For the sake of simplicity we won't stage the vertex data to the GPU memory @@ -411,7 +435,6 @@ void Graphics::buildBottomLevelAccelerationStructures(Array const VkBufferUsageFlags buffer_usage_flags = VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT; - VkBufferCreateInfo transformBufferInfo = { .sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, .pNext = nullptr, @@ -437,9 +460,9 @@ void Graphics::buildBottomLevelAccelerationStructures(Array VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_TRANSFER_READ_BIT, VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR | VK_PIPELINE_STAGE_TRANSFER_BIT); verticesBuffer->pipelineBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_ACCESS_SHADER_READ_BIT, - VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR); + VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR); indexBuffer->pipelineBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_ACCESS_SHADER_READ_BIT, - VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR); + VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR); Array geometries(data.size()); Array buildGeometries(data.size()); @@ -672,7 +695,7 @@ void Graphics::initInstance(GraphicsInitializer initInfo) { extensions.add("VK_KHR_portability_enumeration"); #endif Array layers = initInfo.layers; - //layers.add("VK_LAYER_KHRONOS_validation"); + // layers.add("VK_LAYER_KHRONOS_validation"); VkInstanceCreateInfo info = { .sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO, .pNext = nullptr, @@ -885,9 +908,9 @@ void Graphics::createDevice(GraphicsInitializer initializer) { #ifdef __APPLE__ initializer.deviceExtensions.add("VK_KHR_portability_subset"); #endif - //initializer.deviceExtensions.add(VK_KHR_ACCELERATION_STRUCTURE_EXTENSION_NAME); - //initializer.deviceExtensions.add(VK_KHR_RAY_TRACING_PIPELINE_EXTENSION_NAME); - //initializer.deviceExtensions.add(VK_KHR_DEFERRED_HOST_OPERATIONS_EXTENSION_NAME); + // initializer.deviceExtensions.add(VK_KHR_ACCELERATION_STRUCTURE_EXTENSION_NAME); + // initializer.deviceExtensions.add(VK_KHR_RAY_TRACING_PIPELINE_EXTENSION_NAME); + // initializer.deviceExtensions.add(VK_KHR_DEFERRED_HOST_OPERATIONS_EXTENSION_NAME); VkDeviceCreateInfo deviceInfo = { .sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO, .pNext = &features, @@ -920,6 +943,8 @@ void Graphics::createDevice(GraphicsInitializer initializer) { cmdDrawMeshTasks = (PFN_vkCmdDrawMeshTasksEXT)vkGetDeviceProcAddr(handle, "vkCmdDrawMeshTasksEXT"); cmdDrawMeshTasksIndirect = (PFN_vkCmdDrawMeshTasksIndirectEXT)vkGetDeviceProcAddr(handle, "vkCmdDrawMeshTasksIndirectEXT"); setDebugUtilsObjectName = (PFN_vkSetDebugUtilsObjectNameEXT)vkGetInstanceProcAddr(instance, "vkSetDebugUtilsObjectNameEXT"); + queueBeginDebugUtilsLabelEXT = (PFN_vkQueueBeginDebugUtilsLabelEXT)vkGetInstanceProcAddr(instance, "vkQueueBeginDebugUtilsLabelEXT"); + queueEndDebugUtilsLabelEXT = (PFN_vkQueueEndDebugUtilsLabelEXT)vkGetInstanceProcAddr(instance, "vkQueueEndDebugUtilsLabelEXT"); createAccelerationStructure = (PFN_vkCreateAccelerationStructureKHR)vkGetDeviceProcAddr(handle, "vkCreateAccelerationStructureKHR"); cmdBuildAccelerationStructures = diff --git a/src/Engine/Graphics/Vulkan/Graphics.h b/src/Engine/Graphics/Vulkan/Graphics.h index 1f2036e..ebff45c 100644 --- a/src/Engine/Graphics/Vulkan/Graphics.h +++ b/src/Engine/Graphics/Vulkan/Graphics.h @@ -76,6 +76,9 @@ class Graphics : public Gfx::Graphics { virtual Gfx::OPipelineStatisticsQuery createPipelineStatisticsQuery(const std::string& name = "") override; virtual Gfx::OTimestampQuery createTimestampQuery(uint64 numTimestamps, const std::string& name = "") override; + virtual void beginDebugRegion(const std::string& name) override; + virtual void endDebugRegion() override; + virtual void resolveTexture(Gfx::PTexture source, Gfx::PTexture destination) override; virtual void copyTexture(Gfx::PTexture src, Gfx::PTexture dst) override; diff --git a/src/Engine/Graphics/slang-compile.cpp b/src/Engine/Graphics/slang-compile.cpp index 268c807..821be5e 100644 --- a/src/Engine/Graphics/slang-compile.cpp +++ b/src/Engine/Graphics/slang-compile.cpp @@ -33,14 +33,14 @@ void Seele::beginCompilation(const ShaderCompilationInfo& info, SlangCompileTarg slang::SessionDesc sessionDesc; sessionDesc.flags = 0; Array option = { - { - .name = slang::CompilerOptionName::Capability, - .value = - { - .kind = slang::CompilerOptionValueKind::Int, - .intValue0 = globalSession->findCapability("GLSL_450"), - }, - }, + //{ + // .name = slang::CompilerOptionName::Capability, + // .value = + // { + // .kind = slang::CompilerOptionValueKind::Int, + // .intValue0 = globalSession->findCapability("GLSL_450"), + // }, + //}, { .name = slang::CompilerOptionName::EmitSpirvDirectly, .value = @@ -88,7 +88,7 @@ void Seele::beginCompilation(const ShaderCompilationInfo& info, SlangCompileTarg sessionDesc.preprocessorMacroCount = macros.size(); sessionDesc.preprocessorMacros = macros.data(); slang::TargetDesc targetDesc; - targetDesc.profile = globalSession->findProfile("glsl_450"); + targetDesc.profile = globalSession->findProfile("spirv_1_6"); targetDesc.format = target; sessionDesc.targetCount = 1; sessionDesc.targets = &targetDesc;