Idk what is still missing

This commit is contained in:
Dynamitos
2024-10-21 11:13:26 +02:00
parent 17746f8d20
commit 07dad4641d
9 changed files with 909 additions and 157 deletions
+2 -4
View File
@@ -396,11 +396,9 @@ void reduce_second_pass(uint groupIndex)
GroupMemoryBarrierWithGroupSync();
// Load the bitfield to the LDS
for (uint e = 0; e < 5; ++e)
for (uint i = groupIndex; i < 319; i+=WORKGROUP_SIZE)
{
uint target_element = 5 * groupIndex + e;
if (target_element < 319)
pParams.cbtBuffer[target_element] = gs_cbtTree[target_element];
pParams.cbtBuffer[i] = gs_cbtTree[i];
}
}
+753
View File
@@ -0,0 +1,753 @@
#version 450
#extension GL_EXT_shader_explicit_arithmetic_types_int64 : require
layout(row_major) uniform;
layout(row_major) buffer;
#line 8 0
struct GeometryCB_std140_0
{
uint totalNumElements_0;
uint baseDepth_0;
uint totalNumVertices_0;
};
#line 8
layout(binding = 0, set = 1)
layout(std140) uniform block_GeometryCB_std140_0
{
uint totalNumElements_0;
uint baseDepth_0;
uint totalNumVertices_0;
}pParams_geometry_0;
#line 1334 1
struct _MatrixStorage_float4x4_ColMajorstd140_0
{
vec4 data_0[4];
};
#line 27 0
struct UpdateCB_std140_0
{
_MatrixStorage_float4x4_ColMajorstd140_0 viewProjectionMatrix_0;
float triangleSize_0;
uint maxSubdivisionDepth_0;
float fov_0;
float farPlaneDistance_0;
};
#line 27
layout(binding = 1, set = 1)
layout(std140) uniform block_UpdateCB_std140_0
{
_MatrixStorage_float4x4_ColMajorstd140_0 viewProjectionMatrix_0;
float triangleSize_0;
uint maxSubdivisionDepth_0;
float fov_0;
float farPlaneDistance_0;
}pParams_update_0;
#line 40
layout(std430, binding = 2, set = 1) buffer StructuredBuffer_vectorx3Cfloatx2C4x3E_t_0 {
vec4 _data[];
} pParams_currentVertexBuffer_0;
#line 40
layout(std430, binding = 3, set = 1) readonly buffer StructuredBuffer_uint_t_0 {
uint _data[];
} pParams_indexedBisectorBuffer_0;
#line 40
layout(std430, binding = 4, set = 1) buffer StructuredBuffer_uint_t_1 {
uint _data[];
} pParams_indirectDrawBuffer_0;
#line 40
layout(std430, binding = 5, set = 1) buffer StructuredBuffer_uint64_t_0 {
uint64_t _data[];
} pParams_heapIDBuffer_0;
#line 20 2
struct _Array_std430_uint3_0
{
uint data_1[3];
};
#line 35
struct BisectorData_std430_0
{
_Array_std430_uint3_0 indices_0;
uint subdivisionPattern_0;
uint problematicNeighbor_0;
uint bisectorState_0;
uint flags_0;
uint propagationID_0;
};
#line 35
layout(std430, binding = 6, set = 1) buffer StructuredBuffer_BisectorData_std430_t_0 {
BisectorData_std430_0 _data[];
} pParams_bisectorDataBuffer_0;
#line 35
layout(std430, binding = 7, set = 1) buffer StructuredBuffer_uint_t_2 {
uint _data[];
} pParams_classificationBuffer_0;
#line 102 3
struct Plane_std140_0
{
vec3 n_0;
float d_0;
};
#line 102
struct _Array_std140_Plane4_0
{
Plane_std140_0 data_2[4];
};
#line 102
struct Frustum_std140_0
{
_Array_std140_Plane4_0 sides_0;
};
#line 19
struct ViewParameter_std140_0
{
Frustum_std140_0 viewFrustum_0;
_MatrixStorage_float4x4_ColMajorstd140_0 viewMatrix_0;
_MatrixStorage_float4x4_ColMajorstd140_0 inverseViewMatrix_0;
_MatrixStorage_float4x4_ColMajorstd140_0 projectionMatrix_0;
_MatrixStorage_float4x4_ColMajorstd140_0 inverseProjection_0;
vec4 cameraPosition_WS_0;
vec4 cameraForward_WS_0;
vec2 screenDimensions_0;
vec2 invScreenDimensions_0;
uint frameIndex_0;
float time_0;
};
#line 22
layout(binding = 0)
layout(std140) uniform block_ViewParameter_std140_0
{
Frustum_std140_0 viewFrustum_0;
_MatrixStorage_float4x4_ColMajorstd140_0 viewMatrix_0;
_MatrixStorage_float4x4_ColMajorstd140_0 inverseViewMatrix_0;
_MatrixStorage_float4x4_ColMajorstd140_0 projectionMatrix_0;
_MatrixStorage_float4x4_ColMajorstd140_0 inverseProjection_0;
vec4 cameraPosition_WS_0;
vec4 cameraForward_WS_0;
vec2 screenDimensions_0;
vec2 invScreenDimensions_0;
uint frameIndex_0;
float time_0;
}pViewParams_0;
#line 22
mat4x4 unpackStorage_0(_MatrixStorage_float4x4_ColMajorstd140_0 _S1)
{
#line 22
return mat4x4(_S1.data_0[0][0], _S1.data_0[1][0], _S1.data_0[2][0], _S1.data_0[3][0], _S1.data_0[0][1], _S1.data_0[1][1], _S1.data_0[2][1], _S1.data_0[3][1], _S1.data_0[0][2], _S1.data_0[1][2], _S1.data_0[2][2], _S1.data_0[3][2], _S1.data_0[0][3], _S1.data_0[1][3], _S1.data_0[2][3], _S1.data_0[3][3]);
}
#line 99
struct Plane_0
{
vec3 n_0;
float d_0;
};
#line 109
Plane_0 unpackStorage_1(Plane_std140_0 _S2)
{
#line 109
Plane_0 _S3 = { _S2.n_0, _S2.d_0 };
#line 109
return _S3;
}
#line 109
void unpackStorage_2(_Array_std140_Plane4_0 _S4, out Plane_0 _S5[4])
{
#line 109
Plane_0 _S6 = unpackStorage_1(_S4.data_2[1]);
#line 109
Plane_0 _S7 = unpackStorage_1(_S4.data_2[2]);
#line 109
Plane_0 _S8 = unpackStorage_1(_S4.data_2[3]);
#line 109
_S5[0] = unpackStorage_1(_S4.data_2[0]);
#line 109
_S5[1] = _S6;
#line 109
_S5[2] = _S7;
#line 109
_S5[3] = _S8;
#line 109
return;
}
#line 17 2
_Array_std430_uint3_0 packStorage_0(uint _S9[3])
{
#line 17
uint _S10[3] = { _S9[0], _S9[1], _S9[2] };
#line 17
_Array_std430_uint3_0 _S11 = { _S10 };
#line 17
return _S11;
}
#line 17
void unpackStorage_3(_Array_std430_uint3_0 _S12, out uint _S13[3])
{
#line 17
_S13[0] = _S12.data_1[0];
#line 17
_S13[1] = _S12.data_1[1];
#line 17
_S13[2] = _S12.data_1[2];
#line 17
return;
}
#line 17
struct BisectorData_0
{
uint indices_0[3];
uint subdivisionPattern_0;
uint problematicNeighbor_0;
uint bisectorState_0;
uint flags_0;
uint propagationID_0;
};
#line 17
BisectorData_0 unpackStorage_4(BisectorData_std430_0 _S14)
{
#line 17
uint _S15[3];
#line 17
unpackStorage_3(_S14.indices_0, _S15);
#line 17
BisectorData_0 _S16 = { _S15, _S14.subdivisionPattern_0, _S14.problematicNeighbor_0, _S14.bisectorState_0, _S14.flags_0, _S14.propagationID_0 };
#line 17
return _S16;
}
#line 17
BisectorData_std430_0 packStorage_1(BisectorData_0 _S17)
{
#line 17
BisectorData_std430_0 _S18 = { packStorage_0(_S17.indices_0), _S17.subdivisionPattern_0, _S17.problematicNeighbor_0, _S17.bisectorState_0, _S17.flags_0, _S17.propagationID_0 };
#line 17
return _S18;
}
#line 38
uint HeapIDDepth_0(uint64_t x_0)
{
#line 38
uint64_t _S19 = x_0;
#line 38
uint depth_0 = 0U;
for(;;)
{
#line 41
if(_S19 > 0UL)
{
}
else
{
#line 41
break;
}
#line 42
uint depth_1 = depth_0 + 1U;
#line 42
_S19 = _S19 >> 1U;
#line 42
depth_0 = depth_1;
#line 41
}
return depth_0;
}
#line 109 3
struct Frustum_0
{
Plane_0 sides_0[4];
};
#line 109
Frustum_0 unpackStorage_5(Frustum_std140_0 _S20)
{
#line 109
Plane_0 _S21[4];
#line 109
unpackStorage_2(_S20.sides_0, _S21);
#line 109
Frustum_0 _S22 = { _S21 };
#line 109
return _S22;
}
#line 26 4
bool FrustumAABBIntersect_0(Frustum_0 frustum_0, vec3 aabbMin_0, vec3 aabbMax_0)
{
vec3 _S23 = (aabbMax_0 + aabbMin_0) * 0.5;
vec3 _S24 = (aabbMax_0 - aabbMin_0) * 0.5;
#line 29
int i_0 = 0;
for(;;)
{
#line 30
if(i_0 < 4)
{
}
else
{
#line 30
break;
}
#line 37
if(dot(_S23 + _S24 * vec3((ivec3(sign((frustum_0.sides_0[i_0].n_0))))), frustum_0.sides_0[i_0].n_0) + frustum_0.sides_0[i_0].d_0 < 0.0)
{
#line 38
return false;
}
#line 30
i_0 = i_0 + 1;
#line 30
}
#line 40
return true;
}
#line 7
struct BisectorGeometry_0
{
vec3 p_0[4];
};
#line 43
int ClassifyBisector_0(BisectorGeometry_0 tri_0, uint depth_2)
{
vec3 viewDir_0 = normalize(- ((tri_0.p_0[0] + tri_0.p_0[1] + tri_0.p_0[2]) / 3.0));
float VdotN_0 = dot(viewDir_0, normalize(cross(tri_0.p_0[2] - tri_0.p_0[1], tri_0.p_0[0] - tri_0.p_0[1])));
#line 50
bool _S25;
if(dot(viewDir_0, pViewParams_0.cameraForward_WS_0.xyz) < 0.0)
{
#line 53
_S25 = VdotN_0 < -0.00100000004749745;
#line 53
}
else
{
#line 53
_S25 = false;
#line 53
}
#line 53
if(_S25)
{
#line 54
return -3;
}
float _S26 = tri_0.p_0[0].x;
#line 57
float _S27 = tri_0.p_0[1].x;
#line 57
float _S28 = tri_0.p_0[2].x;
#line 57
float _S29 = tri_0.p_0[0].y;
#line 57
float _S30 = tri_0.p_0[1].y;
#line 57
float _S31 = tri_0.p_0[2].y;
#line 57
float _S32 = tri_0.p_0[0].z;
#line 57
float _S33 = tri_0.p_0[1].z;
#line 57
float _S34 = tri_0.p_0[2].z;
if(!FrustumAABBIntersect_0(unpackStorage_5(pViewParams_0.viewFrustum_0), vec3(min(min(_S26, _S27), _S28), min(min(_S29, _S30), _S31), min(min(_S32, _S33), _S34)), vec3(max(max(_S26, _S27), _S28), max(max(_S29, _S30), _S31), max(max(_S32, _S33), _S34))))
{
#line 62
return -2;
}
#line 62
mat4x4 _S35 = unpackStorage_0(pParams_update_0.viewProjectionMatrix_0);
vec4 _S36 = (((vec4(tri_0.p_0[0], 1.0)) * (_S35)));
#line 66
vec4 p0P_0 = _S36;
p0P_0.xy = _S36.xy / _S36.w;
p0P_0.xy = p0P_0.xy * 0.5 + 0.5;
vec4 _S37 = (((vec4(tri_0.p_0[1], 1.0)) * (_S35)));
#line 70
vec4 p1P_0 = _S37;
p1P_0.xy = _S37.xy / _S37.w;
p1P_0.xy = p1P_0.xy * 0.5 + 0.5;
vec4 _S38 = (((vec4(tri_0.p_0[2], 1.0)) * (_S35)));
#line 74
vec4 p2P_0 = _S38;
p2P_0.xy = _S38.xy / _S38.w;
p2P_0.xy = p2P_0.xy * 0.5 + 0.5;
#line 85
float areaOverestimation_0 = mix(2.0, 1.0, pow(VdotN_0, 0.20000000298023224));
float area_0 = 0.5 * abs(p0P_0.x * (p2P_0.y - p1P_0.y) + p1P_0.x * (p0P_0.y - p2P_0.y) + p2P_0.x * (p1P_0.y - p0P_0.y)) * (pViewParams_0.screenDimensions_0.x * pViewParams_0.screenDimensions_0.y) * areaOverestimation_0;
if(pParams_update_0.triangleSize_0 < area_0)
{
#line 89
_S25 = depth_2 < pParams_update_0.maxSubdivisionDepth_0;
#line 89
}
else
{
#line 89
_S25 = false;
#line 89
}
#line 89
if(_S25)
{
return 1;
}
else
{
#line 94
if(pParams_update_0.triangleSize_0 * 0.5 > area_0)
{
#line 94
_S25 = true;
#line 94
}
else
{
#line 94
_S25 = depth_2 > pParams_update_0.maxSubdivisionDepth_0;
#line 94
}
#line 94
if(_S25)
{
vec4 _S39 = (((vec4(tri_0.p_0[3], 1.0)) * (_S35)));
#line 97
vec4 p3P_0 = _S39;
p3P_0.xy = _S39.xy / _S39.w;
p3P_0.xy = p3P_0.xy * 0.5 + 0.5;
#line 107
if(pParams_update_0.triangleSize_0 >= 0.5 * abs(p0P_0.x * (p2P_0.y - p3P_0.y) + p3P_0.x * (p0P_0.y - p2P_0.y) + p2P_0.x * (p3P_0.y - p0P_0.y)) * (pViewParams_0.screenDimensions_0.x * pViewParams_0.screenDimensions_0.y) * areaOverestimation_0)
{
#line 107
_S25 = true;
#line 107
}
else
{
#line 107
_S25 = depth_2 > pParams_update_0.maxSubdivisionDepth_0;
#line 107
}
#line 107
int _S40;
#line 107
if(_S25)
{
#line 107
_S40 = -1;
#line 107
}
else
{
#line 107
_S40 = 0;
#line 107
}
#line 107
return _S40;
}
#line 89
}
#line 109
return 0;
}
#line 140
void ClassifyElement_0(uint currentID_0, BisectorGeometry_0 bis_0, uint totalNumElements_1, uint baseDepth_1)
{
uint64_t heapID_0 = pParams_heapIDBuffer_0._data[uint(currentID_0)];
uint depth_3 = HeapIDDepth_0(pParams_heapIDBuffer_0._data[uint(currentID_0)]);
BisectorData_0 cbisectorData_0 = unpackStorage_4(pParams_bisectorDataBuffer_0._data[uint(currentID_0)]);
cbisectorData_0.subdivisionPattern_0 = 0U;
cbisectorData_0.bisectorState_0 = 0U;
cbisectorData_0.problematicNeighbor_0 = 4294967295U;
cbisectorData_0.flags_0 = 1U;
int currentValidity_0 = ClassifyBisector_0(bis_0, depth_3);
if(currentValidity_0 > 0)
{
cbisectorData_0.bisectorState_0 = 1U;
uint targetSlot_0 = atomicAdd(pParams_classificationBuffer_0._data[uint(0UL)], 1U);
pParams_classificationBuffer_0._data[uint(2UL + uint64_t(targetSlot_0))] = currentID_0;
#line 155
}
else
{
#line 155
int _S41;
#line 165
if(currentValidity_0 >= -1)
{
#line 165
_S41 = 1;
#line 165
}
else
{
#line 165
_S41 = 0;
#line 165
}
#line 165
cbisectorData_0.flags_0 = uint(_S41);
#line 155
}
#line 155
bool _S42;
#line 168
if(baseDepth_1 != depth_3)
{
#line 168
_S42 = currentValidity_0 < 0;
#line 168
}
else
{
#line 168
_S42 = false;
#line 168
}
#line 168
if(_S42)
{
cbisectorData_0.bisectorState_0 = 2U;
if(heapID_0 % 2UL == 0UL)
{
uint targetSlot_1 = atomicAdd(pParams_classificationBuffer_0._data[uint(1UL)], 1U);
pParams_classificationBuffer_0._data[uint(2UL + uint64_t(totalNumElements_1) + uint64_t(targetSlot_1))] = currentID_0;
#line 174
}
#line 168
}
#line 183
pParams_bisectorDataBuffer_0._data[uint(currentID_0)] = packStorage_1(cbisectorData_0);
return;
}
#line 14 5
layout(local_size_x = 64, local_size_y = 1, local_size_z = 1) in;
void main()
{
#line 14
uint _S43 = gl_GlobalInvocationID.x;
if(_S43 >= pParams_indirectDrawBuffer_0._data[uint(9)])
{
#line 18
return;
}
uint _S44 = pParams_indexedBisectorBuffer_0._data[uint(_S43)];
BisectorGeometry_0 bis_1;
uint _S45 = 3U * _S44;
#line 25
bis_1.p_0[0] = pParams_currentVertexBuffer_0._data[uint(_S45)].xyz;
bis_1.p_0[1] = pParams_currentVertexBuffer_0._data[uint(_S45 + 1U)].xyz;
bis_1.p_0[2] = pParams_currentVertexBuffer_0._data[uint(_S45 + 2U)].xyz;
bis_1.p_0[3] = pParams_currentVertexBuffer_0._data[uint(3U * pParams_geometry_0.totalNumElements_0 + _S44)].xyz;
ClassifyElement_0(_S44, bis_1, pParams_geometry_0.totalNumElements_0, pParams_geometry_0.baseDepth_0);
return;
}
+123 -136
View File
@@ -71,157 +71,144 @@ struct ComputeParams
RWStructuredBuffer<BisectorData> bisectorDataBuffer;
RWStructuredBuffer<int> propagateBuffer;
RWStructuredBuffer<uint> simplifyBuffer;
RWStructuredBuffer<uint32_t> bitFieldBuffer;
RWStructuredBuffer<uint> cbtBuffer;
RWStructuredBuffer<uint64_t> bitFieldBuffer;
};
ParameterBlock<ComputeParams> pParams;
void SplitElement(uint currentID, uint baseDepth, uint dispatchID)
{
// Get the neighbors information
uint4 cNeighbors = pParams.neighboursBuffer[currentID];
#define WORKGROUP_SIZE 64
// If there is a neighbor X
if (cNeighbors.x != INVALID_POINTER)
// Num elements
#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 + 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 1024
// Tree last level
#define TREE_LAST_LEVEL 10
// First virtual level
#define FIRST_VIRTUAL_LEVEL 11
// Leaf level
#define LEAF_LEVEL 17
// per level offset
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 * 1 + 32 * 2 + 32 * 4 + 32 * 8, // Level 4
32 * 1 + 32 * 2 + 32 * 4 + 32 * 8 + 32 * 16, // Level 5
32 * 1 + 32 * 2 + 32 * 4 + 32 * 8 + 32 * 16 + 32 * 32, // Level 6
32 * 1 + 32 * 2 + 32 * 4 + 32 * 8 + 32 * 16 + 32 * 32 + 32 * 64, // Level 7
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
0, // Level 12
0, // Level 13
0, // Level 14
0, // Level 15
0, // Level 16
0, // Level 17
0, // Level 18
};
static const uint64_t OCBT_bit_mask[18] = { 0xffffffff, // Root 17
0xffffffff, // Level 16
0xffffffff, // level 15
0xffffffff, // level 14
0xffffffff, // level 13
0xffffffff, // level 12
0xffffffff, // level 11
0xffff, // level 10
0xffff, // level 9
0xffff, // level 8
0xff, // level 8
0xffffffffffffffff, // level 7
0xffffffff, // Level 6
0xffff, // level 5
0xff, // level 4
0xf, // level 3
0x3, // level 2
0x1, // level 1
};
static const uint32_t OCBT_bit_count[18] = { 32, // Root 17
32, // Level 16
32, // level 15
32, // level 14
32, // level 13
32, // level 12
32, // level 11
16, // level 10
16, // level 9
16, // level 8
8, // level 8
64, // Level 5
32, // Level 5
16, // Level 4
8, // level 3
4, // level 2
2, // level 1
1, // level 0
};
groupshared uint gs_cbtTree[OCBT_TREE_NUM_SLOTS];
// Define the remaining values
#define BUFFER_ELEMENT_PER_LANE ((OCBT_TREE_NUM_SLOTS + WORKGROUP_SIZE - 1) / WORKGROUP_SIZE)
#define BUFFER_ELEMENT_PER_LANE_NO_BITFIELD ((OCBT_TREE_NUM_SLOTS + WORKGROUP_SIZE - 1) / WORKGROUP_SIZE)
#define BITFIELD_ELEMENT_PER_LANE ((OCBT_BITFIELD_NUM_SLOTS + WORKGROUP_SIZE - 1) / WORKGROUP_SIZE)
#define WAVE_TREE_DEPTH uint(log2(OCBT_NUM_ELEMENTS))
void load_buffer_to_shared_memory(uint groupIndex)
{
// 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;
// Load the bitfield to the LDS
for (uint e = 0; e < BUFFER_ELEMENT_PER_LANE; ++e)
{
uint target_element = BUFFER_ELEMENT_PER_LANE * groupIndex + e;
if (target_element < OCBT_TREE_NUM_SLOTS)
gs_cbtTree[target_element] = pParams.cbtBuffer[target_element];
}
GroupMemoryBarrierWithGroupSync();
}
// If there is a neighbor Y
if (cNeighbors.y != INVALID_POINTER)
uint get_heap_element(uint id)
{
// 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;
}
// Depth of the current triangle
uint64_t heapID = pParams.heapIDBuffer[currentID];
uint currentDepth = HeapIDDepth(heapID);
// Compute the maximal required memory for this subdivision
int maxRequiredMemory = 2 * (currentDepth - baseDepth) - 1;
// Get the twin information
uint twinID = cNeighbors.z;
// 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;
// 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)
// Figure out the location of the first bit of this element
uint32_t real_heap_id = id - 1;
uint32_t depth = uint32_t(log2(real_heap_id + 1));
uint32_t level_first_element = (1u << depth) - 1;
uint32_t id_in_level = real_heap_id - level_first_element;
uint32_t first_bit = OCBT_depth_offset[depth] + OCBT_bit_count[depth] * id_in_level;
if (depth < FIRST_VIRTUAL_LEVEL)
{
// 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;
uint32_t slot = first_bit / 32;
uint32_t local_id = first_bit % 32;
uint32_t target_bits = (gs_cbtTree[slot] >> local_id) & uint32_t(OCBT_bit_mask[depth]);
return (gs_cbtTree[slot] >> local_id) & uint32_t(OCBT_bit_mask[depth]);
}
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);
uint32_t slot = first_bit / 64;
uint32_t local_id = first_bit % 64;
uint64_t target_bits = (pParams.bitFieldBuffer[slot] >> local_id) & OCBT_bit_mask[depth];
uint32_t high = uint(target_bits >> 32);
uint32_t low = uint(target_bits);
return countbits(high) + countbits(low);
}
}
[numthreads(64, 1, 1)]
void Split(uint dispatchID : SV_DispatchThreadID)
void GetHeap(uint groupIndex : SV_GroupIndex, uint dispatchID : SV_DispatchThreadID)
{
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);
load_buffer_to_shared_memory(groupIndex);
pParams.classificationBuffer[dispatchID] = get_heap_element(dispatchID);
}
+13
View File
@@ -0,0 +1,13 @@
import subprocess
e = ['Reset', 'Classify', 'Split', 'PrepareIndirect', 'Allocate', 'Bisect', 'PropagateBisect', 'PrepareSimplify', 'Simplify', 'PropagateSimplify', 'ReducePrePass', 'ReduceFirstPass', 'ReduceSecondPass', 'BisectorIndexation', 'PrepareBisectorIndirect', 'Validate']
def generate(entry: list[str], file: str):
for point in entry:
subprocess.run(['C:/Users/Dynamitos/slang/build/Release/bin/slangc', '-I', '../lib', f'{file}.slang', '-profile', 'spirv_1_6', '-stage', 'compute', '-target','spirv', '-entry', f'{point}', '-o', f'{point}.spv', '-emit-spirv-via-glsl'])
generate(e, 'CBTCompute')
e = ['ClearBuffer', 'EvaluateLEB']
generate(e, 'LEB')
+9 -9
View File
@@ -19,9 +19,9 @@ 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;
static const uint32_t SPLIT_COUNTER = 0;
static const uint32_t SIMPLIFY_COUNTER = 1;
static const uint32_t CLASSIFY_COUNTER_OFFSET = 2;
bool FrustumAABBIntersect(in Frustum frustum, float3 aabbMin, float3 aabbMax)
{
@@ -330,14 +330,13 @@ void AllocateElement(uint currentID)
int numSlots = countbits(bisectorData.subdivisionPattern);
// Request the number of bits we need using an interlock add
uint firstBitIndex = 0;
int firstBitIndex = 0;
InterlockedAdd(pParams.memoryBuffer[0], numSlots, firstBitIndex);
// llocate the bits we need
for (uint bitId = 0; bitId < numSlots; ++bitId)
{
uint index = decode_bit_complement(firstBitIndex + bitId);
bisectorData.indices[bitId] = index;
bisectorData.indices[bitId] = decode_bit_complement(firstBitIndex + bitId);
}
// Output
@@ -664,7 +663,7 @@ void BisectElement(uint currentID, uint dispatchID)
pParams.debugBuffer[dispatchID] = debug;
for (uint siblingIdx = 0; siblingIdx < numSiblings; ++siblingIdx)
{
set_bit_atomic_buffer(cBisectorData.indices[siblingIdx], true);
set_bit_atomic(cBisectorData.indices[siblingIdx], true);
}
}
@@ -709,8 +708,9 @@ void PropagateBisectElement(uint currentID)
}
// Reset the problematic neighbor and the bisection state
pParams.bisectorDataBuffer[currentID].problematicNeighbor = INVALID_POINTER;
pParams.bisectorDataBuffer[currentID].bisectorState = UNCHANGED_ELEMENT;
cBisectorData.problematicNeighbor = INVALID_POINTER;
cBisectorData.bisectorState = UNCHANGED_ELEMENT;
pParams.bisectorDataBuffer[currentID] = cBisectorData;
}
void PrepareSimplifyElement(uint currentID)
@@ -13,7 +13,7 @@ TerrainRenderer::TerrainRenderer(Gfx::PGraphics graphics, PScene scene, Gfx::PDe
Gfx::OPipelineLayout test = graphics->createPipelineLayout();
graphics->beginShaderCompilation(ShaderCompilationInfo{
.modules = {"CompileTest"},
.entryPoints = {{"Split", "CompileTest"}},
.entryPoints = {{"GetHeap", "CompileTest"}},
.rootSignature = test,
});
graphics->createComputeShader({0});
@@ -32,7 +32,7 @@ TerrainRenderer::TerrainRenderer(Gfx::PGraphics graphics, PScene scene, Gfx::PDe
.size = bufferSize,
.data = (uint8*)cbt.rawBuffer(i),
},
.name = "GPUCBT",
.name = fmt::format("GPUCBT{0}", i).c_str(),
});
plainMesh.gpuCBT.bufferArray[i]->pipelineBarrier(Gfx::SE_ACCESS_TRANSFER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_TRANSFER_BIT,
Gfx::SE_ACCESS_SHADER_READ_BIT | Gfx::SE_ACCESS_SHADER_WRITE_BIT,
+1 -1
View File
@@ -313,7 +313,7 @@ void Buffer::createBuffer(uint64 size, uint32 destIndex) {
PCommand command = graphics->getQueueCommands(initialOwner)->getCommands();
command->bindResource(PBufferAllocation(buffers[destIndex]));
vkCmdFillBuffer(command->getHandle(), buffers[destIndex]->buffer, 0, VK_WHOLE_SIZE, clearValue);
pipelineBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
buffers[destIndex]->pipelineBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
VK_ACCESS_MEMORY_READ_BIT | VK_ACCESS_MEMORY_WRITE_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT);
}
}
+1
View File
@@ -792,6 +792,7 @@ void Graphics::pickPhysicalDevice() {
.pNext = &meshShaderFeatures,
.storageBuffer8BitAccess = true,
.uniformAndStorageBuffer8BitAccess = true,
.shaderBufferInt64Atomics = true,
.shaderFloat16 = true,
.shaderInt8 = true,
.shaderUniformBufferArrayNonUniformIndexing = true,
+2 -2
View File
@@ -42,7 +42,7 @@ void Seele::beginCompilation(const ShaderCompilationInfo& info, SlangCompileTarg
// },
//},
{
.name = slang::CompilerOptionName::EmitSpirvDirectly,
.name = slang::CompilerOptionName::EmitSpirvViaGLSL,
.value =
{
.kind = slang::CompilerOptionValueKind::Int,
@@ -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("spirv_1_6");
targetDesc.profile = globalSession->findProfile("glsl_450");
targetDesc.format = target;
sessionDesc.targetCount = 1;
sessionDesc.targets = &targetDesc;