Nothing works

This commit is contained in:
Dynamitos
2024-10-14 18:14:08 +02:00
parent 98a7e16756
commit 62d6662ad1
14 changed files with 244 additions and 187 deletions
+7 -7
View File
@@ -2,13 +2,13 @@
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;
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;
+38 -45
View File
@@ -1,26 +1,44 @@
import Parameters;
// The maximal size of the LDS is 16kbyte.
#ifndef WORKGROUP_SIZE
#define WORKGROUP_SIZE 64
#endif
/*
Level 0: 32 bit // [0, 131072] x 1, needs a minimum of 18 bits (rounded up to 32 for alignment and required for atomic operations)
Level 1: 32 bit // [0, 65536] x 2, needs a minimum of 17 bits (rounded up to 32 for alignment and required for atomic operations)
Level 2: 32 bit // [0, 32768] x 4, needs a minimum of 16 bits (bumped to 32 bits for atomic operations)
Level 3: 32 bit // [0, 16384] x 8, needs a minimum of 15 bits (rounded up to 16 for alignment and bumped to 32 bits for atomic operations)
Level 4: 32 bit // [0, 8192] x 16, needs a minimum of 14 bits (rounded up to 16 for alignment and bumped to 32 bits for atomic operations)
Level 5: 32 bit // [0, 4096] x 32, needs a minimum of 13 bits (rounded up to 16 for alignment and bumped to 32 bits for atomic operations)
Level 6: 32 bit // [0, 2048] x 64, needs a minimum of 12 bits (rounded up to 16 for alignment and bumped to 32 bits for atomic operations)
Level 7: 16 bit // [0, 1024] x 128, needs a minimum of 11 bits (rounded up to 16 for alignment)
Level 8: 16 bit // [0, 512] x 256, needs a minimum of 10 bits (rounded up to 16 for alignment)
Level 9: 16 bit // [0, 256] x 512, needs a minimum of 9 bits (rounded up to 16 for alignment)
Level 10: 8 bit // [0, 128] x 1024, needs a minimum of 8 bits
Level 11: Raw 64 bits representation
*/
// Num elements
#define OCBT_NUM_ELEMENTS 1048576
#define OCBT_NUM_ELEMENTS 131072
// Tree sizes
#define OCBT_TREE_SIZE_BITS (32 * 1 + 32 * 2 + 32 * 4 + 32 * 8 + 32 * 16 + 32 * 32 + 32 * 64 + 16 * 128 + 16 * 256 + 16 * 512 + 16 * 1024 + 16* 2048 + 16 * 4096 + 8 * 8192)
#define OCBT_TREE_SIZE_BITS (32 * 1 + 32 * 2 + 32 * 4 + 32 * 8 + 32 * 16 + 32 * 32 + 32 * 64 + 16 * 128 + 16 * 256 + 16 * 512 + 8 * 1024)
#define OCBT_TREE_NUM_SLOTS (OCBT_TREE_SIZE_BITS / 32)
#define OCBT_BITFIELD_NUM_SLOTS (OCBT_NUM_ELEMENTS / 64)
#define OCBT_LAST_LEVEL_SIZE 8192
#define OCBT_LAST_LEVEL_SIZE 1024
// Tree last level
#define TREE_LAST_LEVEL 13
#define TREE_LAST_LEVEL 10
// First virtual level
#define FIRST_VIRTUAL_LEVEL 14
#define FIRST_VIRTUAL_LEVEL 11
// Leaf level
#define LEAF_LEVEL 20
#define LEAF_LEVEL 17
// per level offset
static const uint32_t OCBT_depth_offset[21] = { 0, // Level 0
static const uint32_t OCBT_depth_offset[18] = { 0, // Level 0
32 * 1, // level 1
32 * 1 + 32 * 2, // level 2
32 * 1 + 32 * 2 + 32 * 4, // level 3
@@ -32,20 +50,17 @@ static const uint32_t OCBT_depth_offset[21] = { 0, // Level 0
32 * 1 + 32 * 2 + 32 * 4 + 32 * 8 + 32 * 16 + 32 * 32 + 32 * 64 + 16 * 128, // Level 8
32 * 1 + 32 * 2 + 32 * 4 + 32 * 8 + 32 * 16 + 32 * 32 + 32 * 64 + 16 * 128 + 16 * 256, // Level 9
32 * 1 + 32 * 2 + 32 * 4 + 32 * 8 + 32 * 16 + 32 * 32 + 32 * 64 + 16 * 128 + 16 * 256 + 16 * 512, // Level 10
32 * 1 + 32 * 2 + 32 * 4 + 32 * 8 + 32 * 16 + 32 * 32 + 32 * 64 + 16 * 128 + 16 * 256 + 16 * 512 + 16 * 1024, // Level 11
32 * 1 + 32 * 2 + 32 * 4 + 32 * 8 + 32 * 16 + 32 * 32 + 32 * 64 + 16 * 128 + 16 * 256 + 16 * 512 + 16 * 1024 + 16 * 2048, // Level 12
32 * 1 + 32 * 2 + 32 * 4 + 32 * 8 + 32 * 16 + 32 * 32 + 32 * 64 + 16 * 128 + 16 * 256 + 16 * 512 + 16 * 1024 + 16 * 2048 + 16 * 4096, // Level 13
0, // Level 12
0, // Level 13
0, // Level 14
0, // Level 15
0, // Level 16
0, // Level 17
0, // Level 18
0, // Level 19
0, // Level 20
};
static const uint64_t OCBT_bit_mask[21] = { 0xffffffff, // Root 17
static const uint64_t OCBT_bit_mask[18] = { 0xffffffff, // Root 17
0xffffffff, // Level 16
0xffffffff, // level 15
0xffffffff, // level 14
@@ -56,9 +71,6 @@ static const uint64_t OCBT_bit_mask[21] = { 0xffffffff, // Root 17
0xffff, // level 10
0xffff, // level 9
0xffff, // level 8
0xffff, // level 8
0xffff, // level 8
0xffff, // level 8
0xff, // level 8
0xffffffffffffffff, // level 7
@@ -70,7 +82,7 @@ static const uint64_t OCBT_bit_mask[21] = { 0xffffffff, // Root 17
0x1, // level 1
};
static const uint32_t OCBT_bit_count[21] = { 32, // Root 17
static const uint32_t OCBT_bit_count[18] = { 32, // Root 17
32, // Level 16
32, // level 15
32, // level 14
@@ -81,9 +93,6 @@ static const uint32_t OCBT_bit_count[21] = { 32, // Root 17
16, // level 10
16, // level 9
16, // level 8
16, // level 8
16, // level 8
16, // level 8
8, // level 8
64, // Level 5
@@ -417,11 +426,9 @@ void reduce_first_pass(uint dispatchThreadID, uint groupIndex)
{
// Load the lowest level (and only the last level)
const uint level0Offset = OCBT_depth_offset[TREE_LAST_LEVEL] / 32;
for (uint e = 0; e < 4; ++e)
{
uint target_element = 4 * dispatchThreadID + e;
gs_cbtTree[level0Offset + target_element] = pParams.cbtBuffer[level0Offset + target_element];
}
if (groupIndex % 2 == 0)
gs_cbtTree[level0Offset + dispatchThreadID / 2] = pParams.cbtBuffer[level0Offset + dispatchThreadID / 2];
GroupMemoryBarrierWithGroupSync();
// First we do a reduction until each lane has exactly one element to process
@@ -444,29 +451,15 @@ void reduce_first_pass(uint dispatchThreadID, uint groupIndex)
GroupMemoryBarrierWithGroupSync();
// Load the first reduced level
const uint level2Offset = OCBT_depth_offset[TREE_LAST_LEVEL - 1] / 32;
for (uint e = 0; e < 4; ++e)
{
uint target_element = 4 * dispatchThreadID + e;
pParams.cbtBuffer[level2Offset + target_element] = gs_cbtTree[level2Offset + target_element];
}
// Load the first reduced level
const uint level3Offset = OCBT_depth_offset[TREE_LAST_LEVEL - 2] / 32;
for (uint e = 0; e < 2; ++e)
{
uint target_element = 2 * dispatchThreadID + e;
pParams.cbtBuffer[level3Offset + target_element] = gs_cbtTree[level3Offset + target_element];
}
const uint level4Offset = OCBT_depth_offset[TREE_LAST_LEVEL - 3] / 32;
pParams.cbtBuffer[level4Offset + dispatchThreadID] = gs_cbtTree[level4Offset + dispatchThreadID];
const uint level5Offset = OCBT_depth_offset[TREE_LAST_LEVEL - 4] / 32;
if (groupIndex % 2 == 0)
pParams.cbtBuffer[level5Offset + dispatchThreadID / 2] = gs_cbtTree[level5Offset + dispatchThreadID / 2];
pParams.cbtBuffer[level2Offset + dispatchThreadID / 2] = gs_cbtTree[level2Offset + dispatchThreadID / 2];
const uint level3Offset = OCBT_depth_offset[TREE_LAST_LEVEL - 2] / 32;
if (groupIndex % 4 == 0)
pParams.cbtBuffer[level3Offset + dispatchThreadID / 4] = gs_cbtTree[level3Offset + dispatchThreadID / 4];
}
void reduce_second_pass(uint groupIndex)
{
// Load the lowest level (and only the last level)
+36 -27
View File
@@ -16,7 +16,7 @@ struct BisectorGeometry
// global
// update
int classifyBisector(in BisectorGeometry tri, uint depth)
int classifyBisector(in BisectorGeometry tri, uint depth, inout DebugStruct debug)
{
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;
@@ -24,49 +24,49 @@ int classifyBisector(in BisectorGeometry tri, uint depth)
float fDotV = dot(viewDir, pViewParams.cameraForward_WS.xyz);
float vDotN = dot(viewDir, triNormal);
debug.fDotV = fDotV;
debug.vDotN = vDotN;
if(fDotV < 0.0 && vDotN < -1e-3)
{
debug.area = 420;
return BACK_FACE_CULLED;
}
AABB aabb;
aabb.minCorner = float3(min(min(tri.p[0].x, tri.p[1].x), tri.p[2].x), min(min(tri.p[0].y, tri.p[1].y), tri.p[2].y), min(min(tri.p[0].z, tri.p[1].z), tri.p[2].z));
aabb.maxCorner = 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));
if(aabb.insideFrustum(pViewParams.viewFrustum))
return FRUSTUM_CULLED;
//if(aabb.insideFrustum(pViewParams.viewFrustum))
// return FRUSTUM_CULLED;
float4x4 viewProjectionMatrix = mul(pViewParams.projectionMatrix, pViewParams.viewMatrix);
float4 p0P = mul(pViewParams.viewMatrix, float4(tri.p[0], 1.0));
p0P.xy = p0P.xy / p0P.w;
p0P.xy = (p0P.xy * 0.5 + 0.5);
float4 p0P = clipToScreen(mul(viewProjectionMatrix, float4(tri.p[0], 1.0)));
float4 p1P = mul(viewProjectionMatrix, float4(tri.p[1], 1.0));
p1P.xy = p1P.xy / p1P.w;
p1P.xy = (p1P.xy * 0.5 + 0.5);
float4 p1P = clipToScreen(mul(viewProjectionMatrix, float4(tri.p[1], 1.0)));
float4 p2P = mul(viewProjectionMatrix, float4(tri.p[2], 1.0));
p2P.xy = p2P.xy / p2P.w;
p2P.xy = (p2P.xy * 0.5 + 0.5);
float4 p2P = clipToScreen(mul(viewProjectionMatrix, float4(tri.p[2], 1.0)));
float area = 0.5 * abs(p0P.x * (p2P.y - p1P.y) + p1P.x * (p0P.y - p2P.y) + p2P.x * (p1P.y - p0P.y));
area *= pViewParams.screenDimensions.x * pViewParams.screenDimensions.y;
float area = 0.5 * abs(p0P.x * (p1P.y - p2P.y) + p1P.x * (p2P.y - p0P.y) + p2P.x * (p0P.y - p1P.y));
float areaOverestimation = lerp(2.0, 1.0, pow(vDotN, 0.2));
area *= areaOverestimation;
debug.areaP[0] = p0P.xy;
debug.areaP[1] = p1P.xy;
debug.areaP[2] = p2P.xy;
debug.area = area;
if(pParams.update.triangleSize < area && depth < pParams.update.maxSubdivisionDepth)
{
return BISECT_ELEMENT;
}
else if((pParams.update.triangleSize * 0.5 > area) || (depth > pParams.update.maxSubdivisionDepth))
{
float4 p3P = mul(viewProjectionMatrix, float4(tri.p[3], 1.0));
p3P.xy = p3P.xy / p3P.w;
p3P.xy = (p3P.xy * 0.5 + 0.5);
float4 p3P = clipToScreen(mul(viewProjectionMatrix, float4(tri.p[3], 1.0)));
float areaParent = 0.5 * abs(p0P.x * (p2P.y - p3P.y) + p3P.x * (p0P.y - p2P.y) + p2P.x * (p3P.y - p0P.y));
areaParent *= pViewParams.screenDimensions.x * pViewParams.screenDimensions.y;
float areaParent = 0.5 * abs(p0P.x * (p3P.y - p2P.y) + p3P.x * (p2P.y - p0P.y) + p2P.x * (p0P.y - p3P.y));
areaParent *= areaOverestimation;
return ((pParams.update.triangleSize >= areaParent ) || (depth > pParams.update.maxSubdivisionDepth)) ? TOO_SMALL : UNCHANGED_ELEMENT;
}
@@ -136,7 +136,7 @@ void reset()
[numthreads(WORKGROUP_SIZE, 1, 1)]
void classify(uint dispatchID : SV_DispatchThreadID)
{
if(dispatchID > pParams.indirectDrawBuffer[9])
if(dispatchID >= pParams.indirectDrawBuffer[9])
return;
uint currentID = pParams.indexedBisectorBuffer[dispatchID];
@@ -155,7 +155,13 @@ void classify(uint dispatchID : SV_DispatchThreadID)
cBisectorData.problematicNeighbor = INVALID_POINTER;
cBisectorData.flags = VISIBLE_BISECTOR;
int currentValidity = classifyBisector(bis, depth);
DebugStruct debug;
debug.sourceP[0] = float4(bis.p[0], 1);
debug.sourceP[1] = float4(bis.p[1], 1);
debug.sourceP[2] = float4(bis.p[2], 1);
int currentValidity = classifyBisector(bis, depth, debug);
debug.validity = currentValidity;
pParams.debugBuffer[dispatchID] = debug;
if(currentValidity > UNCHANGED_ELEMENT)
{
uint targetSlot;
@@ -1085,7 +1091,7 @@ void leb_DecodeNodeAttributeArray_parent_child(uint64_t heapID, inout float3 chi
}
}
void evaluateElementPosition(uint64_t heapID, uint32_t vertexDataOffset, uint minDepth, out Triangle parentTri, out Triangle childTri)
void evaluateElementPosition(uint64_t heapID, uint32_t vertexDataOffset, uint minDepth, RWStructuredBuffer<float3> vertexBuffer, out Triangle parentTri, out Triangle childTri)
{
// Get the depth of the element
uint depth = heapIDDepth(heapID);
@@ -1098,9 +1104,9 @@ void evaluateElementPosition(uint64_t heapID, uint32_t vertexDataOffset, uint mi
uint primitiveID = uint((heapID >> subTreeDepth) - baseHeapID);
// Grab the base positions of the element
float3 p0 = float3(pParams.currentVertexBuffer[3 * primitiveID + vertexDataOffset]);
float3 p1 = float3(pParams.currentVertexBuffer[3 * primitiveID + 1 + vertexDataOffset]);
float3 p2 = float3(pParams.currentVertexBuffer[3 * primitiveID + 2 + vertexDataOffset]);
float3 p0 = float3(vertexBuffer[3 * primitiveID + vertexDataOffset]);
float3 p1 = float3(vertexBuffer[3 * primitiveID + 1 + vertexDataOffset]);
float3 p2 = float3(vertexBuffer[3 * primitiveID + 2 + vertexDataOffset]);
// Heap ID in the sub triangle
uint64_t mask = subTreeDepth != 0uL ? 0xFFFFFFFFFFFFFFFFull >> (64ull - subTreeDepth) : 0ull;
@@ -1127,6 +1133,9 @@ void evaluateElementPosition(uint64_t heapID, uint32_t vertexDataOffset, uint mi
childTri.p[2] = float3(childArray[0][2], childArray[1][2], childArray[2][2]);
}
layout(push_constant)
ConstantBuffer<uint> preRender;
[numthreads(WORKGROUP_SIZE, 1, 1)]
void evaluateLeb(uint currentID : SV_DispatchThreadID, uint groupIndex: SV_GroupIndex)
{
@@ -1136,7 +1145,7 @@ void evaluateLeb(uint currentID : SV_DispatchThreadID, uint groupIndex: SV_Group
GroupMemoryBarrierWithGroupSync();
uint numBisectors;
if(pViewParams.frameIndex == -1)
if(preRender == 1)
{
numBisectors = pParams.indirectDrawBuffer[9];
}
@@ -1153,7 +1162,7 @@ void evaluateLeb(uint currentID : SV_DispatchThreadID, uint groupIndex: SV_Group
uint depth = heapIDDepth(cHeapID);
Triangle parentTri, childTri;
evaluateElementPosition(cHeapID, 0, pParams.geometry.baseDepth, parentTri, childTri);
evaluateElementPosition(cHeapID, 0, pParams.geometry.baseDepth, pParams.currentVertexBuffer, parentTri, childTri);
pParams.lebPositionBuffer[3 * currentID + 0] = childTri.p[0];
pParams.lebPositionBuffer[3 * currentID + 1] = childTri.p[1];
+11
View File
@@ -26,6 +26,16 @@ struct UpdateCB
float farPlaneDistance;
}
struct DebugStruct
{
float4 sourceP[3];
float2 areaP[3];
float area;
int validity;
float fDotV;
float vDotN;
}
struct ComputeParams
{
ConstantBuffer<GeometryCB> geometry;
@@ -52,5 +62,6 @@ struct ComputeParams
RWStructuredBuffer<uint> modifiedBisectorIndices;
RWStructuredBuffer<float3> lebPositionBuffer;
StructuredBuffer<float3x3> lebMatrixCache;
RWStructuredBuffer<DebugStruct> debugBuffer;
};
ParameterBlock<ComputeParams> pParams;