PeriDyno 1.0.0
Loading...
Searching...
No Matches
VkScan.inl
Go to the documentation of this file.
1#include "VkTransfer.h"
2
3namespace dyno {
4 inline int ScanSizeOfNextLevel(int size, int localSize)
5 {
6 return (size + localSize) / localSize;
7 }
8
9 template<typename T>
10 void VkScan<T>::scan(std::vector<T>& inputData, uint ScanType) {
11 VkDeviceArray<T> input;
12 input.resize(inputData.size());
13 vkTransfer(input, inputData);
14
15 VkDeviceArray<T> output;
16 output.resize(inputData.size());
17
18 scan(output, input, ScanType);
19
20 vkTransfer(inputData, output);
21
22 output.clear();
23 }
24
25 template<typename T>
26 void VkScan<T>::scan(VkDeviceArray<T>& output, const VkDeviceArray<T>& input, uint _ScanType)
27 {
28 assert(input.size() > 0);
29 if (input.size() == 1) {
30 if(_ScanType == EXCLUSIVESCAN){
31 std::vector<T> tmp{ 0 };
32 vkTransfer(output, tmp);
33 return;
34 }
35 else if (_ScanType == INCLUSIVESCAN) {
36 vkTransfer(output, input);
37 return;
38 }
39 }
40
41 uint localSize = 256;
42 auto globalSize = input.size();
43
44 std::vector<VkDeviceArray<T>> buffers;
45
46 int n = globalSize;
47 while (n > 1)
48 {
49 buffers.push_back(VkDeviceArray<T>(n));
50 n = ScanSizeOfNextLevel(n, localSize);
51 }
52
53 buffers.push_back(VkDeviceArray<T>(1));
54
55 vkTransfer(buffers[0], input);
56
57 VkUniform<ScanParameters> uniformParam;
59 sp.n = buffers[0].size();
60 sp.ScanType = _ScanType;
61
62 dim3 groupSize = vkDispatchSize(sp.n, localSize);
63
64
65 uniformParam.setValue(sp);
66 mScan->flush(groupSize, &buffers[0], &buffers[0], &buffers[1], &uniformParam);
67
68 for (std::size_t i = 1; i < buffers.size() - 1; i++)
69 {
70 sp.n = buffers[i].size();
71 dim3 groupSizeScan = vkDispatchSize(sp.n, localSize);
73
74 uniformParam.setValue(sp);
75 mScan->flush(groupSizeScan, &buffers[i], &buffers[i], &buffers[i + 1], &uniformParam);
76 }
77
78 //TODO: check why the following code does not work properly
79// mScan->begin();
80// for (std::size_t i = 1; i < buffers.size() - 1; i++)
81// {
82// sp.n = buffers[i].size();
83// dim3 groupSizeScan = vkDispatchSize(sp.n, localSize);
84// sp.ScanType = INCLUSIVESCAN;
85//
86// uniformParam.setValue(sp);
87// mScan->enqueue(groupSizeScan, &buffers[i], &buffers[i], &buffers[i + 1], &uniformParam);
88// }
89// mScan->end();
90// mScan->update(true);
91// mScan->wait();
92
94 mAdd->begin();
95 //for (std::size_t i = 1; i < buffers.size(); i++)
96 for (std::size_t i = buffers.size() - 1; i > 0; i--)
97 {
98 num.setValue(buffers[i - 1].size());
99 dim3 groupSizeAdd = vkDispatchSize(num.getValue(), localSize);
100 mAdd->enqueue(groupSizeAdd, &buffers[i], &buffers[i - 1], &num);
101 }
102 mAdd->end();
103 mAdd->update(true);
104 mAdd->wait();
105
106 vkTransfer(output, buffers[0]);
107
108 if (_ScanType == EXCLUSIVESCAN) {
109 vkTransfer(buffers[0], input);
110 num.setValue(input.size());
111 mSub->flush(groupSize, &buffers[0], &output, &num);
112 }
113
114 for (std::size_t i = 0; i < buffers.size(); i++)
115 {
116 buffers[i].clear();
117 }
118 }
119
120 template<typename T>
122 mScan = std::make_shared<VkProgram>(
123 BUFFER(T),
124 BUFFER(T),
125 BUFFER(T),
127
128
129 mAdd = std::make_shared<VkProgram>(
130 BUFFER(T),
131 BUFFER(T),
132 CONSTANT(int));
133
134 mSub = std::make_shared<VkProgram>(
135 BUFFER(T),
136 BUFFER(T),
137 CONSTANT(int));
138
139 mAdd->load(getDynamicSpvFile<T>("shaders/glsl/core/Add.comp.spv"));
140 mScan->load(getDynamicSpvFile<T>("shaders/glsl/core/Scan.comp.spv"));
141 mSub->load(getDynamicSpvFile<T>("shaders/glsl/core/Sub.comp.spv"));
142 }
143
144 template<typename T>
146 mScan = nullptr;
147 mAdd = nullptr;
148 }
149}
#define UNIFORM(T)
Definition VkProgram.h:99
#define BUFFER(T)
Definition VkProgram.h:96
#define CONSTANT(T)
Definition VkProgram.h:100
#define EXCLUSIVESCAN
Definition VkScan.h:6
#define INCLUSIVESCAN
Definition VkScan.h:7
assert(queueCount >=1)
std::string getDynamicSpvFile(const std::string &fileName)
Definition VulkanTools.h:67
void setValue(const T val)
VkResizeType resize(uint32_t num, VkBufferUsageFlags usageFlags=0)
uint32_t size() const
std::shared_ptr< VkProgram > mSub
Definition VkScan.h:34
std::shared_ptr< VkProgram > mAdd
Definition VkScan.h:32
std::shared_ptr< VkProgram > mScan
Definition VkScan.h:30
void scan(std::vector< T > &input, uint ScanType)
Definition VkScan.inl:10
void setValue(T val)
Definition VkUniform.inl:32
#define T(t)
This is an implementation of AdditiveCCD based on peridyno.
Definition Array.h:25
static dim3 vkDispatchSize(uint totalSize, uint blockSize)
Definition VkProgram.h:34
int ScanSizeOfNextLevel(int size, int localSize)
Definition VkScan.inl:4
unsigned int uint
Definition VkProgram.h:14
bool vkTransfer(VkHostArray< T > &dst, const VkDeviceArray< T > &src)
Definition VkTransfer.inl:7
implement functions for computing prefix sums
Definition VkScan.h:15