Pinning down the issue
This commit is contained in:
@@ -9,6 +9,11 @@ struct WaterPayload
|
|||||||
uint numMeshes;
|
uint numMeshes;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//struct WaterPayload
|
||||||
|
//{
|
||||||
|
// TileDescriptor descriptors[BLOCK_SIZE];
|
||||||
|
//}
|
||||||
|
|
||||||
struct WaterTile
|
struct WaterTile
|
||||||
{
|
{
|
||||||
int2 location;
|
int2 location;
|
||||||
@@ -75,12 +80,24 @@ struct MaterialParams
|
|||||||
layout(set = 1)
|
layout(set = 1)
|
||||||
ParameterBlock<MaterialParams> pWaterMaterial;
|
ParameterBlock<MaterialParams> pWaterMaterial;
|
||||||
|
|
||||||
[numthreads(1, 1, 1)]
|
//groupshared WaterPayload waterPayload;
|
||||||
|
//groupshared uint head;
|
||||||
|
|
||||||
|
[numthreads(BLOCK_SIZE, 1, 1)]
|
||||||
[shader("amplification")]
|
[shader("amplification")]
|
||||||
void taskMain(
|
void taskMain(
|
||||||
uint threadID: SV_GroupThreadID,
|
uint threadID: SV_GroupThreadID,
|
||||||
uint3 groupID: SV_GroupID
|
uint3 groupID: SV_GroupID
|
||||||
|
// uint dispatchID: SV_DispatchThreadID,
|
||||||
) {
|
) {
|
||||||
|
//if(threadID == 0)
|
||||||
|
//{
|
||||||
|
// head = 0;
|
||||||
|
//}
|
||||||
|
//if(dispatchID >= 1600)
|
||||||
|
//{
|
||||||
|
// return;
|
||||||
|
//}
|
||||||
WaterTile tile = pWaterMaterial.tiles[groupID.x];
|
WaterTile tile = pWaterMaterial.tiles[groupID.x];
|
||||||
GroupMemoryBarrierWithGroupSync();
|
GroupMemoryBarrierWithGroupSync();
|
||||||
AABB bounding;
|
AABB bounding;
|
||||||
@@ -111,6 +128,10 @@ void taskMain(
|
|||||||
payload.offset = bounding.minCorner;
|
payload.offset = bounding.minCorner;
|
||||||
payload.extent = tile.extent / numMeshes;
|
payload.extent = tile.extent / numMeshes;
|
||||||
payload.numMeshes = numMeshes;
|
payload.numMeshes = numMeshes;
|
||||||
|
//uint index = 0;
|
||||||
|
//InterlockedAdd(head, 1, index);
|
||||||
|
//waterPayload.descriptors[index] = payload;
|
||||||
|
//GroupMemoryBarrierWithGroupSync();
|
||||||
DispatchMesh(numMeshes, numMeshes, 1, payload);
|
DispatchMesh(numMeshes, numMeshes, 1, payload);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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 ((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 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 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()
|
uint32_t cbt_size()
|
||||||
{
|
{
|
||||||
@@ -174,9 +174,7 @@ uint get_heap_element(uint id)
|
|||||||
uint32_t slot = first_bit / 64;
|
uint32_t slot = first_bit / 64;
|
||||||
uint32_t local_id = first_bit % 64;
|
uint32_t local_id = first_bit % 64;
|
||||||
uint64_t target_bits = (pParams.bitFieldBuffer[slot] >> local_id) & OCBT_bit_mask[depth];
|
uint64_t target_bits = (pParams.bitFieldBuffer[slot] >> local_id) & OCBT_bit_mask[depth];
|
||||||
uint32_t high = uint(target_bits >> 32);
|
return countbits(uint(target_bits >> 32)) + countbits(uint(target_bits));
|
||||||
uint32_t low = uint(target_bits);
|
|
||||||
return countbits(high) + countbits(low);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -298,15 +296,11 @@ void reduce_prepass(uint dispatchThreadID)
|
|||||||
{
|
{
|
||||||
// First element of the pair
|
// First element of the pair
|
||||||
uint64_t target_bits = pParams.bitFieldBuffer[dispatchThreadID * 8 + 2 * pairIdx];
|
uint64_t target_bits = pParams.bitFieldBuffer[dispatchThreadID * 8 + 2 * pairIdx];
|
||||||
uint32_t high = uint(target_bits >> 32);
|
uint elementC = countbits(uint(target_bits >> 32)) + countbits(uint(target_bits));
|
||||||
uint32_t low = uint(target_bits);
|
|
||||||
uint elementC = countbits(high) + countbits(low);
|
|
||||||
|
|
||||||
// Second element of the pair
|
// Second element of the pair
|
||||||
target_bits = pParams.bitFieldBuffer[dispatchThreadID * 8 + 2 * pairIdx + 1];
|
target_bits = pParams.bitFieldBuffer[dispatchThreadID * 8 + 2 * pairIdx + 1];
|
||||||
high = uint(target_bits >> 32);
|
elementC += countbits(uint(target_bits >> 32)) + countbits(uint(target_bits));
|
||||||
low = uint(target_bits);
|
|
||||||
elementC += countbits(high) + countbits(low);
|
|
||||||
|
|
||||||
// Store in the right bits
|
// Store in the right bits
|
||||||
packedSum |= (elementC << pairIdx * 8);
|
packedSum |= (elementC << pairIdx * 8);
|
||||||
@@ -396,9 +390,11 @@ void reduce_second_pass(uint groupIndex)
|
|||||||
GroupMemoryBarrierWithGroupSync();
|
GroupMemoryBarrierWithGroupSync();
|
||||||
|
|
||||||
// Load the bitfield to the LDS
|
// 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];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -10,15 +10,19 @@ void Reset()
|
|||||||
ResetBuffers();
|
ResetBuffers();
|
||||||
}
|
}
|
||||||
|
|
||||||
[numthreads(WORKGROUP_SIZE, 1, 1)]
|
[numthreads(1, 1, 1)]
|
||||||
void Classify(uint currentID : SV_DispatchThreadID)
|
void Classify(uint dispatchID : SV_DispatchThreadID)
|
||||||
|
{
|
||||||
|
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
|
// This thread doesn't have any work to do, we're done
|
||||||
if (currentID >= pParams.indirectDrawBuffer[9])
|
//if (currentID >= pParams.indirectDrawBuffer[9])
|
||||||
return;
|
// return;
|
||||||
|
|
||||||
// Operate the indirection
|
// Operate the indirection
|
||||||
currentID = pParams.indexedBisectorBuffer[currentID];
|
uint currentID = pParams.indexedBisectorBuffer[i];
|
||||||
|
|
||||||
// Read the current geometry data
|
// Read the current geometry data
|
||||||
BisectorGeometry bis;
|
BisectorGeometry bis;
|
||||||
@@ -30,12 +34,17 @@ void Classify(uint currentID : SV_DispatchThreadID)
|
|||||||
// Classify the element
|
// Classify the element
|
||||||
ClassifyElement(currentID, bis, pParams.geometry.totalNumElements, pParams.geometry.baseDepth);
|
ClassifyElement(currentID, bis, pParams.geometry.totalNumElements, pParams.geometry.baseDepth);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
[numthreads(WORKGROUP_SIZE, 1, 1)]
|
[numthreads(1, 1, 1)]
|
||||||
void Split(uint dispatchID : SV_DispatchThreadID)
|
void Split(uint dispatchID : SV_DispatchThreadID)
|
||||||
{
|
{
|
||||||
if (dispatchID >= pParams.classificationBuffer[SPLIT_COUNTER])
|
if(dispatchID > 0)
|
||||||
return;
|
return;
|
||||||
|
for(dispatchID = 0; dispatchID < pParams.classificationBuffer[SPLIT_COUNTER]; ++dispatchID)
|
||||||
|
{
|
||||||
|
//if (dispatchID >= pParams.classificationBuffer[SPLIT_COUNTER])
|
||||||
|
// return;
|
||||||
|
|
||||||
// Grab the real elementID
|
// Grab the real elementID
|
||||||
uint currentID = pParams.classificationBuffer[CLASSIFY_COUNTER_OFFSET + dispatchID];
|
uint currentID = pParams.classificationBuffer[CLASSIFY_COUNTER_OFFSET + dispatchID];
|
||||||
@@ -43,6 +52,7 @@ void Split(uint dispatchID : SV_DispatchThreadID)
|
|||||||
// Split the element
|
// Split the element
|
||||||
SplitElement(currentID, pParams.geometry.baseDepth);
|
SplitElement(currentID, pParams.geometry.baseDepth);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
[numthreads(1, 1, 1)]
|
[numthreads(1, 1, 1)]
|
||||||
void PrepareIndirect(uint currentID : SV_DispatchThreadID)
|
void PrepareIndirect(uint currentID : SV_DispatchThreadID)
|
||||||
@@ -52,74 +62,102 @@ void PrepareIndirect(uint currentID : SV_DispatchThreadID)
|
|||||||
pParams.indirectDispatchBuffer[currentID * 3 + 2] = 1;
|
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)
|
void Allocate(uint groupIndex : SV_GroupIndex, uint dispatchID : SV_DispatchThreadID)
|
||||||
{
|
{
|
||||||
// Load the CBT to the LDS
|
if(dispatchID > 0)
|
||||||
load_buffer_to_shared_memory(groupIndex);
|
|
||||||
|
|
||||||
// If this element doesn't need to be processed, we're done
|
|
||||||
if (dispatchID >= pParams.allocateBuffer[0])
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Allocate the required bits
|
for(uint i = 0; i < 64; ++i)
|
||||||
AllocateElement(pParams.allocateBuffer[1 + dispatchID]);
|
{
|
||||||
|
// Load the CBT to the LDS
|
||||||
|
load_buffer_to_shared_memory(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
[numthreads(WORKGROUP_SIZE, 1, 1)]
|
// 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(1, 1, 1)]
|
||||||
void Bisect(uint groupIndex : SV_GroupIndex, uint dispatchID : SV_DispatchThreadID)
|
void Bisect(uint groupIndex : SV_GroupIndex, uint dispatchID : SV_DispatchThreadID)
|
||||||
{
|
{
|
||||||
// If this element doesn't need to be processed, we're done
|
if(dispatchID > 0)
|
||||||
if (dispatchID >= pParams.allocateBuffer[0])
|
|
||||||
return;
|
return;
|
||||||
|
// 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
|
// Operation the bisection of this element
|
||||||
BisectElement(pParams.allocateBuffer[1 + dispatchID], dispatchID);
|
BisectElement(pParams.allocateBuffer[1 + i], i);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[numthreads(WORKGROUP_SIZE, 1, 1)]
|
[numthreads(1, 1, 1)]
|
||||||
void PropagateBisect(uint dispatchID : SV_DispatchThreadID)
|
void PropagateBisect(uint dispatchID : SV_DispatchThreadID)
|
||||||
{
|
{
|
||||||
// If this element doesn't need to be processed, we're done
|
if(dispatchID > 0)
|
||||||
if (dispatchID >= pParams.propagateBuffer[0])
|
|
||||||
return;
|
return;
|
||||||
|
// If this element doesn't need to be processed, we're done
|
||||||
PropagateBisectElement(pParams.propagateBuffer[2 + dispatchID]);
|
//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)
|
void PrepareSimplify(uint dispatchID : SV_DispatchThreadID)
|
||||||
{
|
{
|
||||||
// If this element doesn't need to be processed, we're done
|
if(dispatchID > 0)
|
||||||
if (dispatchID >= pParams.classificationBuffer[SIMPLIFY_COUNTER])
|
|
||||||
return;
|
return;
|
||||||
|
// If this element doesn't need to be processed, we're done
|
||||||
|
//if (dispatchID >= pParams.classificationBuffer[SIMPLIFY_COUNTER])
|
||||||
|
// return;
|
||||||
|
for(uint i = 0; i < pParams.classificationBuffer[SIMPLIFY_COUNTER]; ++i)
|
||||||
|
{
|
||||||
// Grab the real elementID
|
// Grab the real elementID
|
||||||
uint currentID = pParams.classificationBuffer[CLASSIFY_COUNTER_OFFSET + pParams.geometry.totalNumElements + dispatchID];
|
uint currentID = pParams.classificationBuffer[CLASSIFY_COUNTER_OFFSET + pParams.geometry.totalNumElements + i];
|
||||||
|
|
||||||
// Simplify an element
|
// Simplify an element
|
||||||
PrepareSimplifyElement(currentID);
|
PrepareSimplifyElement(currentID);
|
||||||
}
|
}
|
||||||
|
|
||||||
[numthreads(WORKGROUP_SIZE, 1, 1)]
|
|
||||||
void Simplify(uint currentID : SV_DispatchThreadID)
|
|
||||||
{
|
|
||||||
// This thread doesn't have any work to do, we're done
|
|
||||||
if (currentID >= pParams.simplifyBuffer[0])
|
|
||||||
return;
|
|
||||||
|
|
||||||
// Simplify an element
|
|
||||||
SimplifyElement(pParams.simplifyBuffer[1 + currentID]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[numthreads(WORKGROUP_SIZE, 1, 1)]
|
[numthreads(1, 1, 1)]
|
||||||
|
void Simplify(uint dispatchID : SV_DispatchThreadID)
|
||||||
|
{
|
||||||
|
if(dispatchID > 0)
|
||||||
|
return;
|
||||||
|
// 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(1, 1, 1)]
|
||||||
void PropagateSimplify(uint dispatchID : SV_DispatchThreadID)
|
void PropagateSimplify(uint dispatchID : SV_DispatchThreadID)
|
||||||
{
|
{
|
||||||
// If this element doesn't need to be processed, we're done
|
if(dispatchID > 0)
|
||||||
if (dispatchID >= pParams.propagateBuffer[1])
|
|
||||||
return;
|
return;
|
||||||
|
// If this element doesn't need to be processed, we're done
|
||||||
PropagateElementSimplify(pParams.propagateBuffer[2 + dispatchID]);
|
//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)]
|
[numthreads(WORKGROUP_SIZE, 1, 1)]
|
||||||
@@ -142,15 +180,20 @@ void ReduceSecondPass(uint groupIndex : SV_GroupIndex)
|
|||||||
reduce_second_pass(groupIndex);
|
reduce_second_pass(groupIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
[numthreads(WORKGROUP_SIZE, 1, 1)]
|
[numthreads(1, 1, 1)]
|
||||||
void BisectorIndexation(uint currentID : SV_DispatchThreadID)
|
void BisectorIndexation(uint currentID : SV_DispatchThreadID)
|
||||||
{
|
{
|
||||||
// This thread doesn't have any work to do, we're done
|
if(currentID > 0)
|
||||||
if (currentID >= pParams.geometry.totalNumElements)
|
|
||||||
return;
|
return;
|
||||||
|
// This thread doesn't have any work to do, we're done
|
||||||
|
//if (currentID >= pParams.geometry.totalNumElements)
|
||||||
|
// return;
|
||||||
|
|
||||||
|
for(uint i = 0; i < pParams.geometry.totalNumElements; ++i)
|
||||||
|
{
|
||||||
// Indexate this bisector
|
// Indexate this bisector
|
||||||
BisectorElementIndexation(currentID);
|
BisectorElementIndexation(i);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[numthreads(1, 1, 1)]
|
[numthreads(1, 1, 1)]
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -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)]
|
[numthreads(64, 1, 1)]
|
||||||
void GetHeap(uint groupIndex : SV_GroupIndex, uint dispatchID : SV_DispatchThreadID)
|
void GetHeap(uint groupIndex : SV_GroupIndex, uint dispatchID : SV_DispatchThreadID)
|
||||||
{
|
{
|
||||||
load_buffer_to_shared_memory(groupIndex);
|
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);
|
||||||
}
|
}
|
||||||
@@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
Binary file not shown.
Reference in New Issue
Block a user