ngscopeclient v0.2.1
Loading...
Searching...
No Matches
ComputePipeline.h
Go to the documentation of this file.
1/***********************************************************************************************************************
2* *
3* libscopeprotocols *
4* *
5* Copyright (c) 2012-2026 Andrew D. Zonenberg and contributors *
6* All rights reserved. *
7* *
8* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the *
9* following conditions are met: *
10* *
11* * Redistributions of source code must retain the above copyright notice, this list of conditions, and the *
12* following disclaimer. *
13* *
14* * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the *
15* following disclaimer in the documentation and/or other materials provided with the distribution. *
16* *
17* * Neither the name of the author nor the names of any contributors may be used to endorse or promote products *
18* derived from this software without specific prior written permission. *
19* *
20* THIS SOFTWARE IS PROVIDED BY THE AUTHORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
21* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL *
22* THE AUTHORS BE HELD LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES *
23* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR *
24* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT *
25* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE *
26* POSSIBILITY OF SUCH DAMAGE. *
27* *
28***********************************************************************************************************************/
29
36#ifndef ComputePipeline_h
37#define ComputePipeline_h
38
39#include "scopehal.h"
40#include "AcceleratorBuffer.h"
41
55{
56public:
58 const std::string& shaderPath,
59 size_t numSSBOs,
60 size_t pushConstantSize,
61 size_t numStorageImages = 0,
62 size_t numSampledImages = 0);
63 virtual ~ComputePipeline();
64
65 void Reinitialize(
66 const std::string& shaderPath,
67 size_t numSSBOs,
68 size_t pushConstantSize,
69 size_t numStorageImages = 0,
70 size_t numSampledImages = 0);
71
82 template<class T>
83 void BindBuffer(size_t i, AcceleratorBuffer<T>& buf, bool outputOnly = false)
84 {
85 if(m_computePipeline == nullptr)
87
88 buf.PrepareForGpuAccess(outputOnly);
89
90 m_bufferInfo[i] = buf.GetBufferInfo();
92 {
94 vk::WriteDescriptorSet(nullptr, i, 0, vk::DescriptorType::eStorageBuffer, {}, m_bufferInfo[i]);
95 }
96 else
97 {
99 vk::WriteDescriptorSet(**m_descriptorSet, i, 0, vk::DescriptorType::eStorageBuffer, {}, m_bufferInfo[i]);
100 }
101 }
102
111 void BindStorageImage(size_t i, vk::Sampler sampler, vk::ImageView view, vk::ImageLayout layout)
112 {
113 if(m_computePipeline == nullptr)
114 DeferredInit();
115
116 size_t numImage = i - m_numSSBOs;
117 m_storageImageInfo[numImage] = vk::DescriptorImageInfo(sampler, view, layout);
118
120 {
121 m_writeDescriptors[i] = vk::WriteDescriptorSet(
122 nullptr, i, 0, vk::DescriptorType::eStorageImage, m_storageImageInfo[numImage]);
123 }
124 else
125 {
126 m_writeDescriptors[i] = vk::WriteDescriptorSet(
127 **m_descriptorSet, i, 0, vk::DescriptorType::eStorageImage, m_storageImageInfo[numImage]);
128 }
129 }
130
139 void BindSampledImage(size_t i, vk::Sampler sampler, vk::ImageView view, vk::ImageLayout layout)
140 {
141 if(m_computePipeline == nullptr)
142 DeferredInit();
143
145 m_sampledImageInfo[numImage] = vk::DescriptorImageInfo(sampler, view, layout);
146
148 {
149 m_writeDescriptors[i] = vk::WriteDescriptorSet(
150 nullptr, i, 0, vk::DescriptorType::eCombinedImageSampler, m_sampledImageInfo[numImage]);
151 }
152 else
153 {
154 m_writeDescriptors[i] = vk::WriteDescriptorSet(
155 **m_descriptorSet, i, 0, vk::DescriptorType::eCombinedImageSampler, m_sampledImageInfo[numImage]);
156 }
157 }
158
170 template<class T>
172 size_t i, AcceleratorBuffer<T>& buf, vk::raii::CommandBuffer& cmdBuf, bool outputOnly = false)
173 {
174 if(buf.empty())
175 {
176 LogWarning("Attempted to bind an empty buffer\n");
177 return;
178 }
179
180 if(m_computePipeline == nullptr)
181 DeferredInit();
182
183 buf.PrepareForGpuAccessNonblocking(outputOnly, cmdBuf);
184
185 m_bufferInfo[i] = buf.GetBufferInfo();
187 {
189 vk::WriteDescriptorSet(nullptr, i, 0, vk::DescriptorType::eStorageBuffer, {}, m_bufferInfo[i]);
190 }
191 else
192 {
194 vk::WriteDescriptorSet(**m_descriptorSet, i, 0, vk::DescriptorType::eStorageBuffer, {}, m_bufferInfo[i]);
195 }
196 }
197
203 static void AddComputeMemoryBarrier(vk::raii::CommandBuffer& cmdBuf)
204 {
205 cmdBuf.pipelineBarrier(
206 vk::PipelineStageFlagBits::eComputeShader,
207 vk::PipelineStageFlagBits::eComputeShader,
208 {},
209 vk::MemoryBarrier(
210 vk::AccessFlagBits::eShaderWrite,
211 vk::AccessFlagBits::eShaderRead),
212 {},
213 {});
214 }
215
221 void Bind(vk::raii::CommandBuffer& cmdBuf)
222 {
223 if(m_computePipeline == nullptr)
224 DeferredInit();
225 cmdBuf.bindPipeline(vk::PipelineBindPoint::eCompute, **m_computePipeline);
226 }
227
243 template<class T>
244 void Dispatch(vk::raii::CommandBuffer& cmdBuf, T pushConstants, uint32_t x, uint32_t y=1, uint32_t z=1)
245 {
247 g_vkComputeDevice->updateDescriptorSets(m_writeDescriptors, nullptr);
248
249 Bind(cmdBuf);
250 cmdBuf.pushConstants<T>(
252 vk::ShaderStageFlagBits::eCompute,
253 0,
255
257 {
258 cmdBuf.pushDescriptorSetKHR(
259 vk::PipelineBindPoint::eCompute,
261 0,
263 );
264 }
265 else
266 {
267 cmdBuf.bindDescriptorSets(
268 vk::PipelineBindPoint::eCompute,
270 0,
272 {});
273 }
274 cmdBuf.dispatch(x, y, z);
275 }
276
292 template<class T>
293 void DispatchNoRebind(vk::raii::CommandBuffer& cmdBuf, T pushConstants, uint32_t x, uint32_t y=1, uint32_t z=1)
294 {
296 {
297 cmdBuf.pushDescriptorSetKHR(
298 vk::PipelineBindPoint::eCompute,
300 0,
302 );
303 }
304
305 cmdBuf.pushConstants<T>(
307 vk::ShaderStageFlagBits::eCompute,
308 0,
310 cmdBuf.dispatch(x, y, z);
311 }
312
313protected:
314 void DeferredInit();
315
317 std::string m_shaderPath;
318
321
324
327
330
332 std::unique_ptr<vk::raii::ShaderModule> m_shaderModule;
333
335 std::unique_ptr<vk::raii::Pipeline> m_computePipeline;
336
338 std::unique_ptr<vk::raii::PipelineLayout> m_pipelineLayout;
339
341 std::unique_ptr<vk::raii::DescriptorSetLayout> m_descriptorSetLayout;
342
344 std::unique_ptr<vk::raii::DescriptorPool> m_descriptorPool;
345
347 std::unique_ptr<vk::raii::DescriptorSet> m_descriptorSet;
348
350 std::vector<vk::WriteDescriptorSet> m_writeDescriptors;
351
353 std::vector<vk::DescriptorBufferInfo> m_bufferInfo;
354
356 std::vector<vk::DescriptorImageInfo> m_storageImageInfo;
357
359 std::vector<vk::DescriptorImageInfo> m_sampledImageInfo;
360};
361
362#endif
Declaration of AcceleratorBuffer.
Definition AcceleratorBuffer.h:204
Encapsulates a Vulkan compute pipeline and all necessary resources to use it.
Definition ComputePipeline.h:55
std::unique_ptr< vk::raii::DescriptorPool > m_descriptorPool
Pool for allocating m_descriptorSet from.
Definition ComputePipeline.h:344
size_t m_numStorageImages
Number of output image bindings in the shader.
Definition ComputePipeline.h:323
size_t m_numSampledImages
Number of input image bindings in the shader.
Definition ComputePipeline.h:326
void BindBuffer(size_t i, AcceleratorBuffer< T > &buf, bool outputOnly=false)
Binds an input or output SSBO to a descriptor slot.
Definition ComputePipeline.h:83
std::unique_ptr< vk::raii::DescriptorSetLayout > m_descriptorSetLayout
Layout of our descriptor set.
Definition ComputePipeline.h:341
std::string m_shaderPath
Filesystem path to the compiled SPIR-V shader binary.
Definition ComputePipeline.h:317
size_t m_pushConstantSize
Size of the push constants, in bytes.
Definition ComputePipeline.h:329
std::vector< vk::WriteDescriptorSet > m_writeDescriptors
Set of bindings to be written to m_descriptorSet.
Definition ComputePipeline.h:350
void BindStorageImage(size_t i, vk::Sampler sampler, vk::ImageView view, vk::ImageLayout layout)
Binds a storage (output) image to a descriptor slot.
Definition ComputePipeline.h:111
std::unique_ptr< vk::raii::PipelineLayout > m_pipelineLayout
Layout of the compute pipeline.
Definition ComputePipeline.h:338
std::unique_ptr< vk::raii::Pipeline > m_computePipeline
Handle to the Vulkan compute pipeline.
Definition ComputePipeline.h:335
void BindBufferNonblocking(size_t i, AcceleratorBuffer< T > &buf, vk::raii::CommandBuffer &cmdBuf, bool outputOnly=false)
Binds an input or output SSBO to a descriptor slot.
Definition ComputePipeline.h:171
void DispatchNoRebind(vk::raii::CommandBuffer &cmdBuf, T pushConstants, uint32_t x, uint32_t y=1, uint32_t z=1)
Similar to Dispatch() but does not bind descriptor sets.
Definition ComputePipeline.h:293
static void AddComputeMemoryBarrier(vk::raii::CommandBuffer &cmdBuf)
Helper function to insert a shader write-to-read memory barrier in a command buffer.
Definition ComputePipeline.h:203
std::vector< vk::DescriptorBufferInfo > m_bufferInfo
Details about our SSBOs.
Definition ComputePipeline.h:353
void BindSampledImage(size_t i, vk::Sampler sampler, vk::ImageView view, vk::ImageLayout layout)
Binds a sampled (input) image to a descriptor slot.
Definition ComputePipeline.h:139
std::unique_ptr< vk::raii::DescriptorSet > m_descriptorSet
The actual descriptor set storing our inputs and outputs.
Definition ComputePipeline.h:347
void Dispatch(vk::raii::CommandBuffer &cmdBuf, T pushConstants, uint32_t x, uint32_t y=1, uint32_t z=1)
Adds a vkCmdDispatch operation to a command buffer to execute the compute shader.
Definition ComputePipeline.h:244
std::unique_ptr< vk::raii::ShaderModule > m_shaderModule
Handle to the shader module object.
Definition ComputePipeline.h:332
void Bind(vk::raii::CommandBuffer &cmdBuf)
Binds the pipeline to a command buffer.
Definition ComputePipeline.h:221
std::vector< vk::DescriptorImageInfo > m_sampledImageInfo
Details about our input images.
Definition ComputePipeline.h:359
void Reinitialize(const std::string &shaderPath, size_t numSSBOs, size_t pushConstantSize, size_t numStorageImages=0, size_t numSampledImages=0)
Wipes the state of this object and recreates it with a new shader binary and configuration.
Definition ComputePipeline.cpp:86
size_t m_numSSBOs
Number of SSBO bindings in the shader.
Definition ComputePipeline.h:320
std::vector< vk::DescriptorImageInfo > m_storageImageInfo
Details about our output images.
Definition ComputePipeline.h:356
void DeferredInit()
Performs deferred initialization of the compute pipeline the first time the object is used.
Definition ComputePipeline.cpp:128
bool g_hasPushDescriptor
Indicates whether the VK_KHR_push_descriptor extension is available.
Definition VulkanInit.cpp:213
std::shared_ptr< vk::raii::Device > g_vkComputeDevice
The Vulkan device selected for compute operations (may or may not be same device as rendering)
Definition VulkanInit.cpp:71
Main library include file.