diff --git a/res/shaders/WaterPass.slang b/res/shaders/WaterPass.slang index bb5741f..3e988ca 100644 --- a/res/shaders/WaterPass.slang +++ b/res/shaders/WaterPass.slang @@ -9,6 +9,11 @@ struct WaterPayload uint numMeshes; }; +//struct WaterPayload +//{ +// TileDescriptor descriptors[BLOCK_SIZE]; +//} + struct WaterTile { int2 location; @@ -75,12 +80,24 @@ struct MaterialParams layout(set = 1) ParameterBlock pWaterMaterial; -[numthreads(1, 1, 1)] +//groupshared WaterPayload waterPayload; +//groupshared uint head; + +[numthreads(BLOCK_SIZE, 1, 1)] [shader("amplification")] void taskMain( uint threadID: SV_GroupThreadID, uint3 groupID: SV_GroupID + // uint dispatchID: SV_DispatchThreadID, ) { + //if(threadID == 0) + //{ + // head = 0; + //} + //if(dispatchID >= 1600) + //{ + // return; + //} WaterTile tile = pWaterMaterial.tiles[groupID.x]; GroupMemoryBarrierWithGroupSync(); AABB bounding; @@ -111,6 +128,10 @@ void taskMain( payload.offset = bounding.minCorner; payload.extent = tile.extent / numMeshes; payload.numMeshes = numMeshes; + //uint index = 0; + //InterlockedAdd(head, 1, index); + //waterPayload.descriptors[index] = payload; + //GroupMemoryBarrierWithGroupSync(); DispatchMesh(numMeshes, numMeshes, 1, payload); } diff --git a/res/shaders/terrain/CBT.slang b/res/shaders/terrain/CBT.slang index c545613..43fceb9 100644 --- a/res/shaders/terrain/CBT.slang +++ b/res/shaders/terrain/CBT.slang @@ -108,7 +108,7 @@ static const uint32_t OCBT_bit_count[18] = { 32, // Root 17 #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)) +#define WAVE_TREE_DEPTH uint(17) uint32_t cbt_size() { @@ -174,9 +174,7 @@ uint get_heap_element(uint id) 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); + return countbits(uint(target_bits >> 32)) + countbits(uint(target_bits)); } } @@ -298,15 +296,11 @@ void reduce_prepass(uint dispatchThreadID) { // First element of the pair uint64_t target_bits = pParams.bitFieldBuffer[dispatchThreadID * 8 + 2 * pairIdx]; - uint32_t high = uint(target_bits >> 32); - uint32_t low = uint(target_bits); - uint elementC = countbits(high) + countbits(low); + uint elementC = countbits(uint(target_bits >> 32)) + countbits(uint(target_bits)); // Second element of the pair target_bits = pParams.bitFieldBuffer[dispatchThreadID * 8 + 2 * pairIdx + 1]; - high = uint(target_bits >> 32); - low = uint(target_bits); - elementC += countbits(high) + countbits(low); + elementC += countbits(uint(target_bits >> 32)) + countbits(uint(target_bits)); // Store in the right bits packedSum |= (elementC << pairIdx * 8); @@ -396,9 +390,11 @@ void reduce_second_pass(uint groupIndex) GroupMemoryBarrierWithGroupSync(); // Load the bitfield to the LDS - for (uint i = groupIndex; i < 319; i+=WORKGROUP_SIZE) + for (uint e = 0; e < 5; ++e) { - pParams.cbtBuffer[i] = gs_cbtTree[i]; + uint target_element = 5 * groupIndex + e; + if (target_element < 319) + pParams.cbtBuffer[target_element] = gs_cbtTree[target_element]; } } @@ -494,4 +490,4 @@ void set_bit_atomic_buffer(uint bitID, bool state) uint32_t bit_count_buffer() { return pParams.cbtBuffer[0]; -} \ No newline at end of file +} diff --git a/res/shaders/terrain/CBTCompute.slang b/res/shaders/terrain/CBTCompute.slang index e76da52..3faf50e 100644 --- a/res/shaders/terrain/CBTCompute.slang +++ b/res/shaders/terrain/CBTCompute.slang @@ -10,38 +10,48 @@ void Reset() ResetBuffers(); } -[numthreads(WORKGROUP_SIZE, 1, 1)] -void Classify(uint currentID : SV_DispatchThreadID) +[numthreads(1, 1, 1)] +void Classify(uint dispatchID : SV_DispatchThreadID) { - // This thread doesn't have any work to do, we're done - if (currentID >= pParams.indirectDrawBuffer[9]) + if(dispatchID > 0) return; + for(uint i = 0; i < pParams.indirectDrawBuffer[9]; ++i) + { + // This thread doesn't have any work to do, we're done + //if (currentID >= pParams.indirectDrawBuffer[9]) + // return; - // Operate the indirection - currentID = pParams.indexedBisectorBuffer[currentID]; + // Operate the indirection + uint currentID = pParams.indexedBisectorBuffer[i]; - // Read the current geometry data - BisectorGeometry bis; - bis.p[0] = pParams.currentVertexBuffer[3 * currentID].xyz; - bis.p[1] = pParams.currentVertexBuffer[3 * currentID + 1].xyz; - bis.p[2] = pParams.currentVertexBuffer[3 * currentID + 2].xyz; - bis.p[3] = pParams.currentVertexBuffer[3 * pParams.geometry.totalNumElements + currentID].xyz; + // Read the current geometry data + BisectorGeometry bis; + bis.p[0] = pParams.currentVertexBuffer[3 * currentID].xyz; + bis.p[1] = pParams.currentVertexBuffer[3 * currentID + 1].xyz; + bis.p[2] = pParams.currentVertexBuffer[3 * currentID + 2].xyz; + bis.p[3] = pParams.currentVertexBuffer[3 * pParams.geometry.totalNumElements + currentID].xyz; - // Classify the element - ClassifyElement(currentID, bis, pParams.geometry.totalNumElements, pParams.geometry.baseDepth); + // Classify the element + ClassifyElement(currentID, bis, pParams.geometry.totalNumElements, pParams.geometry.baseDepth); + } } -[numthreads(WORKGROUP_SIZE, 1, 1)] +[numthreads(1, 1, 1)] void Split(uint dispatchID : SV_DispatchThreadID) { - if (dispatchID >= pParams.classificationBuffer[SPLIT_COUNTER]) + if(dispatchID > 0) return; + for(dispatchID = 0; dispatchID < pParams.classificationBuffer[SPLIT_COUNTER]; ++dispatchID) + { + //if (dispatchID >= pParams.classificationBuffer[SPLIT_COUNTER]) + // return; - // Grab the real elementID - uint currentID = pParams.classificationBuffer[CLASSIFY_COUNTER_OFFSET + dispatchID]; + // Grab the real elementID + uint currentID = pParams.classificationBuffer[CLASSIFY_COUNTER_OFFSET + dispatchID]; - // Split the element - SplitElement(currentID, pParams.geometry.baseDepth); + // Split the element + SplitElement(currentID, pParams.geometry.baseDepth); + } } [numthreads(1, 1, 1)] @@ -52,74 +62,102 @@ void PrepareIndirect(uint currentID : SV_DispatchThreadID) pParams.indirectDispatchBuffer[currentID * 3 + 2] = 1; } -[numthreads(WORKGROUP_SIZE, 1, 1)] +[numthreads(1, 1, 1)] void Allocate(uint groupIndex : SV_GroupIndex, uint dispatchID : SV_DispatchThreadID) { - // Load the CBT to the LDS - load_buffer_to_shared_memory(groupIndex); - - // If this element doesn't need to be processed, we're done - if (dispatchID >= pParams.allocateBuffer[0]) + if(dispatchID > 0) return; - // Allocate the required bits - AllocateElement(pParams.allocateBuffer[1 + dispatchID]); + for(uint i = 0; i < 64; ++i) + { + // Load the CBT to the LDS + load_buffer_to_shared_memory(i); + } + + // If this element doesn't need to be processed, we're done + //if (dispatchID >= pParams.allocateBuffer[0]) + // return; + for(uint i = 0; i < pParams.allocateBuffer[0]; ++i) + { + // Allocate the required bits + AllocateElement(pParams.allocateBuffer[1 + i]); + } } -[numthreads(WORKGROUP_SIZE, 1, 1)] +[numthreads(1, 1, 1)] void Bisect(uint groupIndex : SV_GroupIndex, uint dispatchID : SV_DispatchThreadID) { - // If this element doesn't need to be processed, we're done - if (dispatchID >= pParams.allocateBuffer[0]) + if(dispatchID > 0) return; - - // Operation the bisection of this element - BisectElement(pParams.allocateBuffer[1 + dispatchID], dispatchID); + // If this element doesn't need to be processed, we're done + //if (dispatchID >= pParams.allocateBuffer[0]) + // return; + for(uint i = 0; i < pParams.allocateBuffer[0]; ++i) + { + // Operation the bisection of this element + BisectElement(pParams.allocateBuffer[1 + i], i); + } } -[numthreads(WORKGROUP_SIZE, 1, 1)] +[numthreads(1, 1, 1)] void PropagateBisect(uint dispatchID : SV_DispatchThreadID) { - // If this element doesn't need to be processed, we're done - if (dispatchID >= pParams.propagateBuffer[0]) + if(dispatchID > 0) return; - - PropagateBisectElement(pParams.propagateBuffer[2 + dispatchID]); + // If this element doesn't need to be processed, we're done + //if (dispatchID >= pParams.propagateBuffer[0]) + // return; + for(uint i = 0; i < pParams.propagateBuffer[0]; ++i) + { + PropagateBisectElement(pParams.propagateBuffer[2 + i]); + } } -[numthreads(WORKGROUP_SIZE, 1, 1)] +[numthreads(1, 1, 1)] void PrepareSimplify(uint dispatchID : SV_DispatchThreadID) { + if(dispatchID > 0) + return; // If this element doesn't need to be processed, we're done - if (dispatchID >= pParams.classificationBuffer[SIMPLIFY_COUNTER]) - return; + //if (dispatchID >= pParams.classificationBuffer[SIMPLIFY_COUNTER]) + // return; + for(uint i = 0; i < pParams.classificationBuffer[SIMPLIFY_COUNTER]; ++i) + { + // Grab the real elementID + uint currentID = pParams.classificationBuffer[CLASSIFY_COUNTER_OFFSET + pParams.geometry.totalNumElements + i]; - // Grab the real elementID - uint currentID = pParams.classificationBuffer[CLASSIFY_COUNTER_OFFSET + pParams.geometry.totalNumElements + dispatchID]; - - // Simplify an element - PrepareSimplifyElement(currentID); + // Simplify an element + PrepareSimplifyElement(currentID); + } } -[numthreads(WORKGROUP_SIZE, 1, 1)] -void Simplify(uint currentID : SV_DispatchThreadID) +[numthreads(1, 1, 1)] +void Simplify(uint dispatchID : SV_DispatchThreadID) { - // This thread doesn't have any work to do, we're done - if (currentID >= pParams.simplifyBuffer[0]) + if(dispatchID > 0) return; - - // Simplify an element - SimplifyElement(pParams.simplifyBuffer[1 + currentID]); + // This thread doesn't have any work to do, we're done + //if (currentID >= pParams.simplifyBuffer[0]) + // return; + for(uint i = 0; i < pParams.simplifyBuffer[0]; ++i) + { + // Simplify an element + SimplifyElement(pParams.simplifyBuffer[1 + i]); + } } -[numthreads(WORKGROUP_SIZE, 1, 1)] +[numthreads(1, 1, 1)] void PropagateSimplify(uint dispatchID : SV_DispatchThreadID) { - // If this element doesn't need to be processed, we're done - if (dispatchID >= pParams.propagateBuffer[1]) + if(dispatchID > 0) return; - - PropagateElementSimplify(pParams.propagateBuffer[2 + dispatchID]); + // If this element doesn't need to be processed, we're done + //if (dispatchID >= pParams.propagateBuffer[1]) + // return; + for(uint i = 0; i < pParams.propagateBuffer[1]; ++i) + { + PropagateElementSimplify(pParams.propagateBuffer[2 + i]); + } } [numthreads(WORKGROUP_SIZE, 1, 1)] @@ -142,15 +180,20 @@ void ReduceSecondPass(uint groupIndex : SV_GroupIndex) reduce_second_pass(groupIndex); } -[numthreads(WORKGROUP_SIZE, 1, 1)] +[numthreads(1, 1, 1)] void BisectorIndexation(uint currentID : SV_DispatchThreadID) { - // This thread doesn't have any work to do, we're done - if (currentID >= pParams.geometry.totalNumElements) + if(currentID > 0) return; + // This thread doesn't have any work to do, we're done + //if (currentID >= pParams.geometry.totalNumElements) + // return; - // Indexate this bisector - BisectorElementIndexation(currentID); + for(uint i = 0; i < pParams.geometry.totalNumElements; ++i) + { + // Indexate this bisector + BisectorElementIndexation(i); + } } [numthreads(1, 1, 1)] diff --git a/res/shaders/terrain/CompileTest.glsl b/res/shaders/terrain/CompileTest.glsl index 244c87d..75d9078 100644 --- a/res/shaders/terrain/CompileTest.glsl +++ b/res/shaders/terrain/CompileTest.glsl @@ -1,753 +1,455 @@ #version 450 #extension GL_EXT_shader_explicit_arithmetic_types_int64 : require +#extension GL_KHR_memory_scope_semantics : 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 { +#line 178 0 +layout(std430, binding = 2) buffer StructuredBuffer_uint_t_0 { uint _data[]; } pParams_classificationBuffer_0; -#line 102 3 -struct Plane_std140_0 -{ - vec3 n_0; - float d_0; -}; +#line 178 +layout(std430, binding = 9) buffer StructuredBuffer_uint_t_1 { + uint _data[]; +} pParams_cbtBuffer_0; +#line 63 +layout(std430, binding = 10) buffer StructuredBuffer_uint64_t_0 { + uint64_t _data[]; +} pParams_bitFieldBuffer_0; -#line 102 -struct _Array_std140_Plane4_0 -{ - Plane_std140_0 data_2[4]; -}; +#line 119 +const uint64_t OCBT_bit_mask_0[18] = { 18446744073709551615UL, 18446744073709551615UL, 18446744073709551615UL, 18446744073709551615UL, 18446744073709551615UL, 18446744073709551615UL, 18446744073709551615UL, 65535UL, 65535UL, 65535UL, 255UL, 18446744073709551615UL, 18446744073709551615UL, 65535UL, 255UL, 15UL, 3UL, 1UL }; - -#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 141 +const uint OCBT_bit_count_0[18] = { 32U, 32U, 32U, 32U, 32U, 32U, 32U, 16U, 16U, 16U, 8U, 64U, 32U, 16U, 8U, 4U, 2U, 1U }; #line 97 - vec4 p3P_0 = _S39; - p3P_0.xy = _S39.xy / _S39.w; - p3P_0.xy = p3P_0.xy * 0.5 + 0.5; +const uint OCBT_depth_offset_0[18] = { 0U, 32U, 96U, 224U, 480U, 992U, 2016U, 4064U, 6112U, 10208U, 18400U, 0U, 0U, 0U, 0U, 0U, 0U, 0U }; -#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 163 +shared uint gs_cbtTree_0[831]; -#line 140 -void ClassifyElement_0(uint currentID_0, BisectorGeometry_0 bis_0, uint totalNumElements_1, uint baseDepth_1) +#line 171 +void load_buffer_to_shared_memory_0(uint groupIndex_0) { - 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)]); +#line 171 + uint e_0 = 0U; - 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) + for(;;) { - - 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 174 + if(int(e_0) < 13) { - -#line 165 - _S41 = 1; - -#line 165 } else { -#line 165 - _S41 = 0; - -#line 165 +#line 174 + break; } - -#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 target_element_0 = uint(13 * int(groupIndex_0) + int(e_0)); + if(int(target_element_0) < 831) { - 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 178 + gs_cbtTree_0[target_element_0] = pParams_cbtBuffer_0._data[uint(target_element_0)]; -#line 174 +#line 177 } -#line 168 +#line 174 + e_0 = e_0 + 1U; + +#line 174 } -#line 183 - pParams_bisectorDataBuffer_0._data[uint(currentID_0)] = packStorage_1(cbisectorData_0); +#line 180 + controlBarrier(gl_ScopeWorkgroup, gl_ScopeWorkgroup, gl_StorageSemanticsShared, gl_SemanticsAcquireRelease); return; } -#line 14 5 +#line 183 +uint get_heap_element_0(uint id_0) +{ + + uint real_heap_id_0 = id_0 - 1U; + uint depth_0 = uint(log2(float(real_heap_id_0 + 1U))); + + + uint first_bit_0 = OCBT_depth_offset_0[depth_0] + OCBT_bit_count_0[depth_0] * (real_heap_id_0 - ((1U << depth_0) - 1U)); + if(depth_0 < 11U) + { + + + + return gs_cbtTree_0[first_bit_0 / 32U] >> first_bit_0 % 32U & uint(OCBT_bit_mask_0[depth_0]); + } + else + { + + + uint64_t target_bits_0 = pParams_bitFieldBuffer_0._data[uint(first_bit_0 / 64U)] >> first_bit_0 % 64U & OCBT_bit_mask_0[depth_0]; + + + return bitCount(uint(target_bits_0 >> 32)) + bitCount(uint(target_bits_0)); + } + +#line 205 +} + + + + +uint decode_bit_0(uint handle_0) +{ + +#line 210 + uint b_0; + +#line 210 + uint heapElementID_0 = 1U; + +#line 210 + uint currentDepth_0 = 0U; + +#line 210 + uint bitCount_0 = handle_0; + +#line 227 + for(;;) + { + +#line 227 + if(currentDepth_0 < 11U) + { + } + else + { + +#line 227 + break; + } + + uint heapValue_0 = get_heap_element_0(2U * heapElementID_0); + + + if(bitCount_0 < heapValue_0) + { + +#line 233 + b_0 = 0U; + +#line 233 + } + else + { + +#line 233 + b_0 = 1U; + +#line 233 + } + + + uint _S1 = 2U * heapElementID_0 + b_0; + + + uint _S2 = bitCount_0 - heapValue_0 * b_0; + +#line 227 + uint currentDepth_1 = currentDepth_0 + 1U; + +#line 227 + heapElementID_0 = _S1; + +#line 227 + currentDepth_0 = currentDepth_1; + +#line 227 + bitCount_0 = _S2; + +#line 227 + } + +#line 243 + uint _S3 = currentDepth_0 + 1U; + + + uint64_t _S4 = pParams_bitFieldBuffer_0._data[uint(int(heapElementID_0) - 2048)]; + +#line 210 + uint _S5 = bitCount_0; + +#line 210 + uint64_t mask_0 = 18446744073709551615UL; + +#line 210 + currentDepth_0 = _S3; + +#line 210 + bitCount_0 = 32U; + +#line 210 + uint _S6 = _S5; + +#line 249 + for(;;) + { + +#line 249 + if(currentDepth_0 < uint(log2(1.31072e+05)) + 1U) + { + } + else + { + +#line 249 + break; + } + +#line 257 + uint64_t target_bits_1 = _S4 >> bitCount_0 * (2U * heapElementID_0 - 1U - ((1U << currentDepth_0) - 1U)) % 64U & mask_0; + uint heapValue_1 = bitCount(uint(target_bits_1 >> 32)) + bitCount(uint(target_bits_1)); + + + if(_S6 < heapValue_1) + { + +#line 261 + b_0 = 0U; + +#line 261 + } + else + { + +#line 261 + b_0 = 1U; + +#line 261 + } + + + uint _S7 = 2U * heapElementID_0 + b_0; + + + uint _S8 = _S6 - heapValue_1 * b_0; + + + uint bitCount_1 = bitCount_0 / 2U; + uint64_t _S9 = mask_0 >> bitCount_1; + +#line 249 + uint currentDepth_2 = currentDepth_0 + 1U; + +#line 249 + heapElementID_0 = _S7; + +#line 249 + mask_0 = _S9; + +#line 249 + currentDepth_0 = currentDepth_2; + +#line 249 + bitCount_0 = bitCount_1; + +#line 249 + _S6 = _S8; + +#line 249 + } + +#line 273 + return heapElementID_0 ^ 131072U; +} + + + +uint decode_bit_complement_0(uint handle_1) +{ + +#line 278 + uint b_1; + +#line 278 + uint heapElementID_1 = 1U; + +#line 278 + uint currentDepth_3 = 0U; + +#line 278 + uint c_0 = 65536U; + +#line 278 + uint bitCount_2 = handle_1; + +#line 299 + for(;;) + { + +#line 299 + if(currentDepth_3 < 11U) + { + } + else + { + +#line 299 + break; + } + uint heapValue_2 = c_0 - get_heap_element_0(2U * heapElementID_1); + if(bitCount_2 < heapValue_2) + { + +#line 302 + b_1 = 0U; + +#line 302 + } + else + { + +#line 302 + b_1 = 1U; + +#line 302 + } + + uint _S10 = 2U * heapElementID_1 + b_1; + uint _S11 = bitCount_2 - heapValue_2 * b_1; + uint c_1 = c_0 / 2U; + +#line 299 + uint currentDepth_4 = currentDepth_3 + 1U; + +#line 299 + heapElementID_1 = _S10; + +#line 299 + currentDepth_3 = currentDepth_4; + +#line 299 + c_0 = c_1; + +#line 299 + bitCount_2 = _S11; + +#line 299 + } + +#line 310 + uint _S12 = currentDepth_3 + 1U; + + + uint64_t _S13 = pParams_bitFieldBuffer_0._data[uint(int(heapElementID_1) - 2048)]; + +#line 278 + uint _S14 = bitCount_2; + +#line 278 + uint64_t mask_1 = 18446744073709551615UL; + +#line 278 + currentDepth_3 = _S12; + +#line 278 + bitCount_2 = 32U; + +#line 278 + uint _S15 = _S14; + +#line 316 + for(;;) + { + +#line 316 + if(currentDepth_3 < uint(log2(1.31072e+05)) + 1U) + { + } + else + { + +#line 316 + break; + } + +#line 324 + uint64_t target_bits_2 = _S13 >> bitCount_2 * (2U * heapElementID_1 - 1U - ((1U << currentDepth_3) - 1U)) % 64U & mask_1; + uint heapValue_3 = c_0 - bitCount(uint(target_bits_2 >> 32)) + bitCount(uint(target_bits_2)); + + if(_S15 < heapValue_3) + { + +#line 327 + b_1 = 0U; + +#line 327 + } + else + { + +#line 327 + b_1 = 1U; + +#line 327 + } + + uint _S16 = 2U * heapElementID_1 + b_1; + uint _S17 = _S15 - heapValue_3 * b_1; + uint c_2 = c_0 / 2U; + + + uint bitCount_3 = bitCount_2 / 2U; + uint64_t _S18 = mask_1 >> bitCount_3; + +#line 316 + uint currentDepth_5 = currentDepth_3 + 1U; + +#line 316 + heapElementID_1 = _S16; + +#line 316 + mask_1 = _S18; + +#line 316 + currentDepth_3 = currentDepth_5; + +#line 316 + bitCount_2 = bitCount_3; + +#line 316 + c_0 = c_2; + +#line 316 + _S15 = _S17; + +#line 316 + } + +#line 338 + return heapElementID_1 ^ 131072U; +} + + + layout(local_size_x = 64, local_size_y = 1, local_size_z = 1) in; void main() { -#line 14 - uint _S43 = gl_GlobalInvocationID.x; +#line 343 + uint _S19 = 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); + load_buffer_to_shared_memory_0(gl_LocalInvocationIndex); + pParams_classificationBuffer_0._data[uint(_S19)] = decode_bit_0(_S19); + pParams_classificationBuffer_0._data[uint(_S19 * 2U)] = decode_bit_complement_0(_S19); return; } diff --git a/res/shaders/terrain/CompileTest.slang b/res/shaders/terrain/CompileTest.slang index ecde828..05ed6aa 100644 --- a/res/shaders/terrain/CompileTest.slang +++ b/res/shaders/terrain/CompileTest.slang @@ -206,9 +206,143 @@ uint get_heap_element(uint id) } } +// decodes the position of the i-th one in the bitfield +uint decode_bit(uint handle) +{ +#if defined(NAIVE_DECODE) + uint bitID = 1; + for (uint currentDepth = 0; currentDepth < WAVE_TREE_DEPTH; ++currentDepth) + { + uint heapValue = get_heap_element(2 * bitID); + uint b = handle < heapValue ? 0 : 1; + + bitID = 2 * bitID + b; + handle -= heapValue * b; + } + + return (bitID ^ OCBT_NUM_ELEMENTS); +#else + uint currentDepth = 0; + uint heapElementID = 1u; + for (currentDepth = 0; currentDepth < FIRST_VIRTUAL_LEVEL; ++currentDepth) + { + // Read the left element + uint heapValue = get_heap_element(2u * heapElementID); + + // Does it fall in the right or left subtree? + uint b = handle < heapValue ? 0u : 1u; + + // Pick a subtree + heapElementID = 2u * heapElementID + b; + + // Move the iterator to exclude the right subtree if required + handle -= heapValue * b; + } + + // Align with the internal depth + currentDepth++; + + // Ok we have our subtree, now we need to pick the right bit + uint64_t heapValue = pParams.bitFieldBuffer[heapElementID - OCBT_LAST_LEVEL_SIZE * 2]; + uint64_t mask = 0xffffffff; + uint32_t bitCount = 32; + for (; currentDepth < (WAVE_TREE_DEPTH + 1); ++currentDepth) + { + // Figure out the location of the first bit of this element + uint real_heap_id = 2 * heapElementID - 1; + uint level_first_element = (1u << currentDepth) - 1; + uint id_in_level = real_heap_id - level_first_element; + uint first_bit = bitCount * id_in_level; + uint local_id = first_bit % 64; + uint64_t target_bits = (heapValue >> local_id) & mask; + uint heapValue = countbits(uint(target_bits >> 32)) + countbits(uint(target_bits)); + + // Does it fall in the right or left subtree? + uint b = handle < heapValue ? 0u : 1u; + + // Pick a subtree + heapElementID = 2u * heapElementID + b; + + // Move the iterator to exclude the right subtree if required + handle -= heapValue * b; + + // Adjust the mask and bitcount + bitCount /= 2; + mask = mask >> bitCount; + } + return (heapElementID ^ OCBT_NUM_ELEMENTS); +#endif +} + +// decodes the position of the i-th zero in the bitfield +uint decode_bit_complement(uint handle) +{ +#if defined(NAIVE_DECODE) + uint bitID = 1u; + uint c = OCBT_NUM_ELEMENTS / 2u; + + while (bitID < OCBT_NUM_ELEMENTS) { + uint heapValue = c - get_heap_element(2u * bitID); + uint b = handle < heapValue ? 0u : 1u; + + bitID = 2u * bitID + b; + handle -= heapValue * b; + c /= 2u; + } + + return (bitID ^ OCBT_NUM_ELEMENTS); +#else + uint heapElementID = 1u; + uint c = OCBT_NUM_ELEMENTS / 2u; + uint currentDepth = 0; + + for (currentDepth = 0; currentDepth < FIRST_VIRTUAL_LEVEL; ++currentDepth) + { + uint heapValue = c - get_heap_element(2u * heapElementID); + uint b = handle < heapValue ? 0u : 1u; + + heapElementID = 2u * heapElementID + b; + handle -= heapValue * b; + c /= 2u; + } + + // Align with the internal depth + currentDepth++; + + // Ok we have our subtree, now we need to pick the right bit + uint64_t heapValue = pParams.bitFieldBuffer[heapElementID - OCBT_LAST_LEVEL_SIZE * 2]; + uint64_t mask = 0xffffffff; + uint32_t bitCount = 32; + for (; currentDepth < (WAVE_TREE_DEPTH + 1); ++currentDepth) + { + // Figure out the location of the first bit of this element + uint real_heap_id = 2 * heapElementID - 1; + uint level_first_element = (1u << currentDepth) - 1; + uint id_in_level = real_heap_id - level_first_element; + uint first_bit = bitCount * id_in_level; + uint local_id = first_bit % 64; + uint64_t target_bits = (heapValue >> local_id) & mask; + uint heapValue = c - countbits(uint(target_bits >> 32)) + countbits(uint(target_bits));; + + uint b = handle < heapValue ? 0u : 1u; + + heapElementID = 2u * heapElementID + b; + handle -= heapValue * b; + c /= 2u; + + // Adjust the mask and bitcount + bitCount /= 2; + mask = mask >> bitCount; + } + + return (heapElementID ^ OCBT_NUM_ELEMENTS); +#endif +} + [numthreads(64, 1, 1)] void GetHeap(uint groupIndex : SV_GroupIndex, uint dispatchID : SV_DispatchThreadID) { load_buffer_to_shared_memory(groupIndex); - pParams.classificationBuffer[dispatchID] = get_heap_element(dispatchID); + pParams.classificationBuffer[dispatchID] = decode_bit(dispatchID); + pParams.classificationBuffer[dispatchID * 2] = decode_bit_complement(dispatchID); } \ No newline at end of file diff --git a/res/shaders/terrain/CompileTest.spv b/res/shaders/terrain/CompileTest.spv new file mode 100644 index 0000000..75d9078 --- /dev/null +++ b/res/shaders/terrain/CompileTest.spv @@ -0,0 +1,455 @@ +#version 450 +#extension GL_EXT_shader_explicit_arithmetic_types_int64 : require +#extension GL_KHR_memory_scope_semantics : require +layout(row_major) uniform; +layout(row_major) buffer; + +#line 178 0 +layout(std430, binding = 2) buffer StructuredBuffer_uint_t_0 { + uint _data[]; +} pParams_classificationBuffer_0; + +#line 178 +layout(std430, binding = 9) buffer StructuredBuffer_uint_t_1 { + uint _data[]; +} pParams_cbtBuffer_0; + +#line 63 +layout(std430, binding = 10) buffer StructuredBuffer_uint64_t_0 { + uint64_t _data[]; +} pParams_bitFieldBuffer_0; + +#line 119 +const uint64_t OCBT_bit_mask_0[18] = { 18446744073709551615UL, 18446744073709551615UL, 18446744073709551615UL, 18446744073709551615UL, 18446744073709551615UL, 18446744073709551615UL, 18446744073709551615UL, 65535UL, 65535UL, 65535UL, 255UL, 18446744073709551615UL, 18446744073709551615UL, 65535UL, 255UL, 15UL, 3UL, 1UL }; + +#line 141 +const uint OCBT_bit_count_0[18] = { 32U, 32U, 32U, 32U, 32U, 32U, 32U, 16U, 16U, 16U, 8U, 64U, 32U, 16U, 8U, 4U, 2U, 1U }; + +#line 97 +const uint OCBT_depth_offset_0[18] = { 0U, 32U, 96U, 224U, 480U, 992U, 2016U, 4064U, 6112U, 10208U, 18400U, 0U, 0U, 0U, 0U, 0U, 0U, 0U }; + +#line 163 +shared uint gs_cbtTree_0[831]; + + +#line 171 +void load_buffer_to_shared_memory_0(uint groupIndex_0) +{ + +#line 171 + uint e_0 = 0U; + + + for(;;) + { + +#line 174 + if(int(e_0) < 13) + { + } + else + { + +#line 174 + break; + } + uint target_element_0 = uint(13 * int(groupIndex_0) + int(e_0)); + if(int(target_element_0) < 831) + { + +#line 178 + gs_cbtTree_0[target_element_0] = pParams_cbtBuffer_0._data[uint(target_element_0)]; + +#line 177 + } + +#line 174 + e_0 = e_0 + 1U; + +#line 174 + } + +#line 180 + controlBarrier(gl_ScopeWorkgroup, gl_ScopeWorkgroup, gl_StorageSemanticsShared, gl_SemanticsAcquireRelease); + return; +} + + +#line 183 +uint get_heap_element_0(uint id_0) +{ + + uint real_heap_id_0 = id_0 - 1U; + uint depth_0 = uint(log2(float(real_heap_id_0 + 1U))); + + + uint first_bit_0 = OCBT_depth_offset_0[depth_0] + OCBT_bit_count_0[depth_0] * (real_heap_id_0 - ((1U << depth_0) - 1U)); + if(depth_0 < 11U) + { + + + + return gs_cbtTree_0[first_bit_0 / 32U] >> first_bit_0 % 32U & uint(OCBT_bit_mask_0[depth_0]); + } + else + { + + + uint64_t target_bits_0 = pParams_bitFieldBuffer_0._data[uint(first_bit_0 / 64U)] >> first_bit_0 % 64U & OCBT_bit_mask_0[depth_0]; + + + return bitCount(uint(target_bits_0 >> 32)) + bitCount(uint(target_bits_0)); + } + +#line 205 +} + + + + +uint decode_bit_0(uint handle_0) +{ + +#line 210 + uint b_0; + +#line 210 + uint heapElementID_0 = 1U; + +#line 210 + uint currentDepth_0 = 0U; + +#line 210 + uint bitCount_0 = handle_0; + +#line 227 + for(;;) + { + +#line 227 + if(currentDepth_0 < 11U) + { + } + else + { + +#line 227 + break; + } + + uint heapValue_0 = get_heap_element_0(2U * heapElementID_0); + + + if(bitCount_0 < heapValue_0) + { + +#line 233 + b_0 = 0U; + +#line 233 + } + else + { + +#line 233 + b_0 = 1U; + +#line 233 + } + + + uint _S1 = 2U * heapElementID_0 + b_0; + + + uint _S2 = bitCount_0 - heapValue_0 * b_0; + +#line 227 + uint currentDepth_1 = currentDepth_0 + 1U; + +#line 227 + heapElementID_0 = _S1; + +#line 227 + currentDepth_0 = currentDepth_1; + +#line 227 + bitCount_0 = _S2; + +#line 227 + } + +#line 243 + uint _S3 = currentDepth_0 + 1U; + + + uint64_t _S4 = pParams_bitFieldBuffer_0._data[uint(int(heapElementID_0) - 2048)]; + +#line 210 + uint _S5 = bitCount_0; + +#line 210 + uint64_t mask_0 = 18446744073709551615UL; + +#line 210 + currentDepth_0 = _S3; + +#line 210 + bitCount_0 = 32U; + +#line 210 + uint _S6 = _S5; + +#line 249 + for(;;) + { + +#line 249 + if(currentDepth_0 < uint(log2(1.31072e+05)) + 1U) + { + } + else + { + +#line 249 + break; + } + +#line 257 + uint64_t target_bits_1 = _S4 >> bitCount_0 * (2U * heapElementID_0 - 1U - ((1U << currentDepth_0) - 1U)) % 64U & mask_0; + uint heapValue_1 = bitCount(uint(target_bits_1 >> 32)) + bitCount(uint(target_bits_1)); + + + if(_S6 < heapValue_1) + { + +#line 261 + b_0 = 0U; + +#line 261 + } + else + { + +#line 261 + b_0 = 1U; + +#line 261 + } + + + uint _S7 = 2U * heapElementID_0 + b_0; + + + uint _S8 = _S6 - heapValue_1 * b_0; + + + uint bitCount_1 = bitCount_0 / 2U; + uint64_t _S9 = mask_0 >> bitCount_1; + +#line 249 + uint currentDepth_2 = currentDepth_0 + 1U; + +#line 249 + heapElementID_0 = _S7; + +#line 249 + mask_0 = _S9; + +#line 249 + currentDepth_0 = currentDepth_2; + +#line 249 + bitCount_0 = bitCount_1; + +#line 249 + _S6 = _S8; + +#line 249 + } + +#line 273 + return heapElementID_0 ^ 131072U; +} + + + +uint decode_bit_complement_0(uint handle_1) +{ + +#line 278 + uint b_1; + +#line 278 + uint heapElementID_1 = 1U; + +#line 278 + uint currentDepth_3 = 0U; + +#line 278 + uint c_0 = 65536U; + +#line 278 + uint bitCount_2 = handle_1; + +#line 299 + for(;;) + { + +#line 299 + if(currentDepth_3 < 11U) + { + } + else + { + +#line 299 + break; + } + uint heapValue_2 = c_0 - get_heap_element_0(2U * heapElementID_1); + if(bitCount_2 < heapValue_2) + { + +#line 302 + b_1 = 0U; + +#line 302 + } + else + { + +#line 302 + b_1 = 1U; + +#line 302 + } + + uint _S10 = 2U * heapElementID_1 + b_1; + uint _S11 = bitCount_2 - heapValue_2 * b_1; + uint c_1 = c_0 / 2U; + +#line 299 + uint currentDepth_4 = currentDepth_3 + 1U; + +#line 299 + heapElementID_1 = _S10; + +#line 299 + currentDepth_3 = currentDepth_4; + +#line 299 + c_0 = c_1; + +#line 299 + bitCount_2 = _S11; + +#line 299 + } + +#line 310 + uint _S12 = currentDepth_3 + 1U; + + + uint64_t _S13 = pParams_bitFieldBuffer_0._data[uint(int(heapElementID_1) - 2048)]; + +#line 278 + uint _S14 = bitCount_2; + +#line 278 + uint64_t mask_1 = 18446744073709551615UL; + +#line 278 + currentDepth_3 = _S12; + +#line 278 + bitCount_2 = 32U; + +#line 278 + uint _S15 = _S14; + +#line 316 + for(;;) + { + +#line 316 + if(currentDepth_3 < uint(log2(1.31072e+05)) + 1U) + { + } + else + { + +#line 316 + break; + } + +#line 324 + uint64_t target_bits_2 = _S13 >> bitCount_2 * (2U * heapElementID_1 - 1U - ((1U << currentDepth_3) - 1U)) % 64U & mask_1; + uint heapValue_3 = c_0 - bitCount(uint(target_bits_2 >> 32)) + bitCount(uint(target_bits_2)); + + if(_S15 < heapValue_3) + { + +#line 327 + b_1 = 0U; + +#line 327 + } + else + { + +#line 327 + b_1 = 1U; + +#line 327 + } + + uint _S16 = 2U * heapElementID_1 + b_1; + uint _S17 = _S15 - heapValue_3 * b_1; + uint c_2 = c_0 / 2U; + + + uint bitCount_3 = bitCount_2 / 2U; + uint64_t _S18 = mask_1 >> bitCount_3; + +#line 316 + uint currentDepth_5 = currentDepth_3 + 1U; + +#line 316 + heapElementID_1 = _S16; + +#line 316 + mask_1 = _S18; + +#line 316 + currentDepth_3 = currentDepth_5; + +#line 316 + bitCount_2 = bitCount_3; + +#line 316 + c_0 = c_2; + +#line 316 + _S15 = _S17; + +#line 316 + } + +#line 338 + return heapElementID_1 ^ 131072U; +} + + + +layout(local_size_x = 64, local_size_y = 1, local_size_z = 1) in; +void main() +{ + +#line 343 + uint _S19 = gl_GlobalInvocationID.x; + + load_buffer_to_shared_memory_0(gl_LocalInvocationIndex); + pParams_classificationBuffer_0._data[uint(_S19)] = decode_bit_0(_S19); + pParams_classificationBuffer_0._data[uint(_S19 * 2U)] = decode_bit_complement_0(_S19); + return; +} + diff --git a/res/shaders/terrain/CompileTest.spv-asm b/res/shaders/terrain/CompileTest.spv-asm new file mode 100644 index 0000000..c5c0feb Binary files /dev/null and b/res/shaders/terrain/CompileTest.spv-asm differ