Function execute
Synopsis
#include <Source/Falcor/Utils/Algorithm/BitonicSort.h>
bool execute(RenderContext *pRenderContext, Buffer::SharedPtr pData, uint32_t totalSize, uint32_t chunkSize, uint32_t groupSize=256)
Description
In-place bitonic sort in chunks of N elements. Each chunk is sorted in ascending order.
- Parameters
[ in ]
pRenderContext
- The render context.[ in ]
pData
- The data buffer to sort in-place.[ in ]
totalSize
- The total number of elements in the buffer. This does not have to be a multiple of chunkSize.[ in ]
chunkSize
- The number of elements per chunk. Each chunk is individually sorted. Must be a power-of-two in the range [1, groupSize].[ in ]
groupSize
- Thread group size. Must be a power-of-two in the range [1,1024]. The default group size of 256 is generally the fastest.- Returns
- True if successful, false if an error occured.
Source
Lines 56-92 in Source/Falcor/Utils/Algorithm/BitonicSort.cpp. Line 63 in Source/Falcor/Utils/Algorithm/BitonicSort.h.
bool BitonicSort::execute(RenderContext* pRenderContext, Buffer::SharedPtr pData, uint32_t totalSize, uint32_t chunkSize, uint32_t groupSize)
{
PROFILE("BitonicSort::execute");
// Validate inputs.
assert(pRenderContext);
assert(pData);
assert(chunkSize >= 1 && chunkSize <= groupSize && isPowerOf2(chunkSize));
assert(groupSize >= 1 && groupSize <= 1024 && isPowerOf2(groupSize));
// Early out if there is nothing to be done.
if (totalSize == 0 || chunkSize <= 1) return true;
// Configure the shader for the specified chunk size.
// This will trigger a re-compile if a new chunk size is encountered.
mSort.pProgram->addDefine("CHUNK_SIZE", std::to_string(chunkSize));
mSort.pProgram->addDefine("GROUP_SIZE", std::to_string(groupSize));
// Determine dispatch dimensions.
const uint32_t numGroups = div_round_up(totalSize, groupSize);
const uint32_t groupsX = std::max((uint32_t)sqrt(numGroups), 1u);
const uint32_t groupsY = div_round_up(numGroups, groupsX);
assert(groupsX * groupsY * groupSize >= totalSize);
// Constants. The buffer size as a runtime constant as it may be variable and we don't want to recompile each time it changes.
mSort.pVars["CB"]["gTotalSize"] = totalSize;
mSort.pVars["CB"]["gDispatchX"] = groupsX;
// Bind the data.
bool success = mSort.pVars->setBuffer("gData", pData);
assert(success);
// Execute.
pRenderContext->dispatch(mSort.pState.get(), mSort.pVars.get(), {groupsX, groupsY, 1});
return true;
}