Idk what is still missing
This commit is contained in:
@@ -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];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
#define WORKGROUP_SIZE 64
|
||||
|
||||
// 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)
|
||||
{
|
||||
// Get the neighbors information
|
||||
uint4 cNeighbors = pParams.neighboursBuffer[currentID];
|
||||
|
||||
// If there is a neighbor X
|
||||
if (cNeighbors.x != INVALID_POINTER)
|
||||
// Load the bitfield to the LDS
|
||||
for (uint e = 0; e < BUFFER_ELEMENT_PER_LANE; ++e)
|
||||
{
|
||||
// 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;
|
||||
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)
|
||||
{
|
||||
// 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)
|
||||
{
|
||||
// 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;
|
||||
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]);
|
||||
}
|
||||
|
||||
// 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)
|
||||
else
|
||||
{
|
||||
// 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);
|
||||
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);
|
||||
}
|
||||
@@ -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')
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user