Fix BitonicSort constant buffer size error on Vulkan due to structure padding

This commit is contained in:
Wojtek Figat
2021-04-28 15:51:54 +02:00
parent f3be30a55e
commit cf799c2198
4 changed files with 31 additions and 39 deletions

BIN
Content/Shaders/BitonicSort.flax (Stored with Git LFS)

Binary file not shown.

View File

@@ -6,10 +6,22 @@
#define INDIRECT_ARGS_STRIDE 12 #define INDIRECT_ARGS_STRIDE 12
BitonicSort::BitonicSort() // The sorting keys buffer item structure template. Matches the shader type.
: _dispatchArgsBuffer(nullptr) struct Item
{ {
} float Key;
uint32 Value;
};
PACK_STRUCT(struct Data {
Item NullItem;
uint32 CounterOffset;
uint32 MaxIterations;
uint32 LoopK;
float KeySign;
uint32 LoopJ;
float Dummy0;
});
String BitonicSort::ToString() const String BitonicSort::ToString() const
{ {

View File

@@ -7,36 +7,15 @@
/// <summary> /// <summary>
/// Bitonic Sort implementation using GPU compute shaders. /// Bitonic Sort implementation using GPU compute shaders.
/// It has a complexity of O(n*(log n)^2), which is inferior to most /// It has a complexity of O(n*(log n)^2), which is inferior to most traditional sorting algorithms, but because GPUs have so many threads,
/// traditional sorting algorithms, but because GPUs have so many threads, /// and because each thread can be utilized, the algorithm can fully load the GPU, taking advantage of its high ALU and bandwidth capabilities.
/// and because each thread can be utilized, the algorithm can fully load
/// the GPU, taking advantage of its high ALU and bandwidth capabilities.
/// </summary> /// </summary>
class BitonicSort : public RendererPass<BitonicSort> class BitonicSort : public RendererPass<BitonicSort>
{ {
public:
// The sorting keys buffer item structure template. Matches the shader type.
struct Item
{
float Key;
uint32 Value;
};
private: private:
PACK_STRUCT(struct Data {
Item NullItem;
uint32 CounterOffset;
uint32 MaxIterations;
uint32 LoopK;
float KeySign;
uint32 LoopJ;
float Dummy0;
});
AssetReference<Shader> _shader; AssetReference<Shader> _shader;
GPUBuffer* _dispatchArgsBuffer; GPUBuffer* _dispatchArgsBuffer = nullptr;
GPUConstantBuffer* _cb; GPUConstantBuffer* _cb;
GPUShaderProgramCS* _indirectArgsCS; GPUShaderProgramCS* _indirectArgsCS;
GPUShaderProgramCS* _preSortCS; GPUShaderProgramCS* _preSortCS;
@@ -44,13 +23,6 @@ private:
GPUShaderProgramCS* _outerSortCS; GPUShaderProgramCS* _outerSortCS;
GPUShaderProgramCS* _copyIndicesCS; GPUShaderProgramCS* _copyIndicesCS;
public:
/// <summary>
/// Initializes a new instance of the <see cref="BitonicSort"/> class.
/// </summary>
BitonicSort();
public: public:
/// <summary> /// <summary>

View File

@@ -10,7 +10,8 @@ struct Item
}; };
META_CB_BEGIN(0, Data) META_CB_BEGIN(0, Data)
Item NullItem; float NullItemKey;
uint NullItemValue;
uint CounterOffset; uint CounterOffset;
uint MaxIterations; uint MaxIterations;
uint LoopK; uint LoopK;
@@ -95,10 +96,17 @@ groupshared Item SortData[2048];
void LoadItem(uint element, uint count) void LoadItem(uint element, uint count)
{ {
// Unused elements must sort to the end // Unused elements must sort to the end
Item item;
if (element < count) if (element < count)
SortData[element & 2047] = SortBuffer[element]; {
item = SortBuffer[element];
}
else else
SortData[element & 2047] = NullItem; {
item.Key = NullItemKey;
item.Value = NullItemValue;
}
SortData[element & 2047] = item;
} }
void StoreItem(uint element, uint count) void StoreItem(uint element, uint count)