GCC Code Coverage Report


ernie/
Coverage:
low: ≥ 0%
medium: ≥ 75.0%
high: ≥ 90.0%
Lines:
42 / 42
100.0%
Branches:
-
-%
Functions:
14 / 14
100.0%

device/kernel.h
Line Branch Exec Source
1 // SPDX-License-Identifier: BSD-3-Clause
2 /// @file kernel.h
3 /// @brief A compute kernel: its pipeline, and the per-dispatch bytes it reads.
4 #pragma once
5
6 #include "ernie/device/bindless.h"
7 #include "ernie/device/context.h"
8
9 #include <glm/vec3.hpp>
10
11 #include <cstddef>
12 #include <cstdint>
13 #include <span>
14 #include <string>
15 #include <string_view>
16
17 namespace ernie {
18
19 /// @brief A compute pipeline from SPIR-V. Each dispatch passes a few bytes, the indices and
20 /// addresses it works on, as push constants on Vulkan (a small uniform on WebGPU, which has
21 /// none). Destroying one the GPU may still run is an error: retire it instead.
22 class ComputeKernel {
23 public:
24 /// @param parameterBytes The bytes each dispatch passes, at most the device's push-constant
25 /// limit (128 at least).
26 /// @param heap The bindless heap it reads images through, bound as set 0; none for kernels
27 /// that touch no images.
28 /// @throws DeviceError if the pipeline cannot be created or the bytes exceed the limit.
29 ComputeKernel(DeviceContext& context, std::span<const std::uint32_t> spirv,
30 std::string_view name, std::uint32_t parameterBytes = 0,
31 const BindlessHeap* heap = nullptr, std::string_view entryPoint = "main");
32 ~ComputeKernel();
33 ComputeKernel(const ComputeKernel&) = delete;
34 ComputeKernel& operator=(const ComputeKernel&) = delete;
35
36 /// @brief Records a dispatch of `groups` workgroups, passing `parameters`.
37 void Dispatch(VkCommandBuffer commands, glm::uvec3 groups,
38 std::span<const std::byte> parameters = {}) const;
39 template <typename T>
40 171 void Dispatch(VkCommandBuffer commands, glm::uvec3 groups, const T& parameters) const {
41 171 Dispatch(commands, groups, std::as_bytes(std::span(&parameters, 1)));
42 171 }
43
44 const std::string& Name() const {
45 return name_;
46 }
47
48 private:
49 VkDevice device_;
50 std::string name_;
51 std::uint32_t parameterBytes_;
52 VkDescriptorSet heap_ = VK_NULL_HANDLE;
53 VkPipelineLayout layout_ = VK_NULL_HANDLE;
54 VkPipeline pipeline_ = VK_NULL_HANDLE;
55 };
56
57 /// @brief Records a barrier ordering earlier dispatches' writes before later dispatches' reads
58 /// and writes. The frame graph places these between passes; this is for work recorded by hand.
59 void ComputeBarrier(VkCommandBuffer commands);
60
61 } // namespace ernie
62