Skip to content

Commit 38b9f86

Browse files
committed
Rename ShaderBuffer to DescriptorBuffer
1 parent cb74b70 commit 38b9f86

File tree

6 files changed

+73
-71
lines changed

6 files changed

+73
-71
lines changed

guide/src/SUMMARY.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@
4545
- [Images](memory/images.md)
4646
- [Descriptor Sets](descriptor_sets/README.md)
4747
- [Pipeline Layout](descriptor_sets/pipeline_layout.md)
48-
- [Shader Buffer](descriptor_sets/shader_buffer.md)
48+
- [Descriptor Buffer](descriptor_sets/descriptor_buffer.md)
4949
- [Texture](descriptor_sets/texture.md)
5050
- [View Matrix](descriptor_sets/view_matrix.md)
5151
- [Instanced Rendering](descriptor_sets/instanced_rendering.md)

guide/src/descriptor_sets/shader_buffer.md renamed to guide/src/descriptor_sets/descriptor_buffer.md

+55-54
Original file line numberDiff line numberDiff line change
@@ -1,81 +1,82 @@
1-
# Shader Buffer
1+
# Descriptor Buffer
22

3-
Uniform and Storage buffers need to be N-buffered unless they are "GPU const", ie contents do not change after creation. Encapsulate a `vma::Buffer` per virtual frame in a `ShaderBuffer`:
3+
Uniform and Storage buffers need to be N-buffered unless they are "GPU const", ie contents do not change after creation. Encapsulate a `vma::Buffer` per virtual frame in a `DescriptorBuffer`:
44

55
```cpp
6-
class ShaderBuffer {
7-
public:
8-
explicit ShaderBuffer(VmaAllocator allocator, std::uint32_t queue_family,
9-
vk::BufferUsageFlags usage);
6+
class DescriptorBuffer {
7+
public:
8+
explicit DescriptorBuffer(VmaAllocator allocator,
9+
std::uint32_t queue_family,
10+
vk::BufferUsageFlags usage);
1011

11-
void write_at(std::size_t frame_index, std::span<std::byte const> bytes);
12+
void write_at(std::size_t frame_index, std::span<std::byte const> bytes);
1213

13-
[[nodiscard]] auto descriptor_info_at(std::size_t frame_index) const
14-
-> vk::DescriptorBufferInfo;
14+
[[nodiscard]] auto descriptor_info_at(std::size_t frame_index) const
15+
-> vk::DescriptorBufferInfo;
1516

16-
private:
17-
struct Buffer {
18-
vma::Buffer buffer{};
19-
vk::DeviceSize size{};
20-
};
17+
private:
18+
struct Buffer {
19+
vma::Buffer buffer{};
20+
vk::DeviceSize size{};
21+
};
2122

22-
void write_to(Buffer& out, std::span<std::byte const> bytes) const;
23+
void write_to(Buffer& out, std::span<std::byte const> bytes) const;
2324

24-
VmaAllocator m_allocator{};
25-
std::uint32_t m_queue_family{};
26-
vk::BufferUsageFlags m_usage{};
27-
Buffered<Buffer> m_buffers{};
25+
VmaAllocator m_allocator{};
26+
std::uint32_t m_queue_family{};
27+
vk::BufferUsageFlags m_usage{};
28+
Buffered<Buffer> m_buffers{};
2829
};
2930
```
3031
3132
The implementation is fairly straightforward, it reuses existing buffers if they are large enough, else recreates them before copying data. It also ensures buffers are always valid to be bound to descriptors.
3233
3334
```cpp
34-
ShaderBuffer::ShaderBuffer(VmaAllocator allocator,
35-
std::uint32_t const queue_family,
36-
vk::BufferUsageFlags const usage)
37-
: m_allocator(allocator), m_queue_family(queue_family), m_usage(usage) {
38-
// ensure buffers are created and can be bound after returning.
39-
for (auto& buffer : m_buffers) { write_to(buffer, {}); }
35+
DescriptorBuffer::DescriptorBuffer(VmaAllocator allocator,
36+
std::uint32_t const queue_family,
37+
vk::BufferUsageFlags const usage)
38+
: m_allocator(allocator), m_queue_family(queue_family), m_usage(usage) {
39+
// ensure buffers are created and can be bound after returning.
40+
for (auto& buffer : m_buffers) { write_to(buffer, {}); }
4041
}
4142
42-
void ShaderBuffer::write_at(std::size_t const frame_index,
43-
std::span<std::byte const> bytes) {
44-
write_to(m_buffers.at(frame_index), bytes);
43+
void DescriptorBuffer::write_at(std::size_t const frame_index,
44+
std::span<std::byte const> bytes) {
45+
write_to(m_buffers.at(frame_index), bytes);
4546
}
4647
47-
auto ShaderBuffer::descriptor_info_at(std::size_t const frame_index) const
48-
-> vk::DescriptorBufferInfo {
49-
auto const& buffer = m_buffers.at(frame_index);
50-
auto ret = vk::DescriptorBufferInfo{};
51-
ret.setBuffer(buffer.buffer.get().buffer).setRange(buffer.size);
52-
return ret;
48+
auto DescriptorBuffer::descriptor_info_at(std::size_t const frame_index) const
49+
-> vk::DescriptorBufferInfo {
50+
auto const& buffer = m_buffers.at(frame_index);
51+
auto ret = vk::DescriptorBufferInfo{};
52+
ret.setBuffer(buffer.buffer.get().buffer).setRange(buffer.size);
53+
return ret;
5354
}
5455
55-
void ShaderBuffer::write_to(Buffer& out,
56-
std::span<std::byte const> bytes) const {
57-
static constexpr auto blank_byte_v = std::array{std::byte{}};
58-
// fallback to an empty byte if bytes is empty.
59-
if (bytes.empty()) { bytes = blank_byte_v; }
60-
out.size = bytes.size();
61-
if (out.buffer.get().size < bytes.size()) {
62-
// size is too small (or buffer doesn't exist yet), recreate buffer.
63-
auto const buffer_ci = vma::BufferCreateInfo{
64-
.allocator = m_allocator,
65-
.usage = m_usage,
66-
.queue_family = m_queue_family,
67-
};
68-
out.buffer = vma::create_buffer(buffer_ci, vma::BufferMemoryType::Host,
69-
out.size);
70-
}
71-
std::memcpy(out.buffer.get().mapped, bytes.data(), bytes.size());
56+
void DescriptorBuffer::write_to(Buffer& out,
57+
std::span<std::byte const> bytes) const {
58+
static constexpr auto blank_byte_v = std::array{std::byte{}};
59+
// fallback to an empty byte if bytes is empty.
60+
if (bytes.empty()) { bytes = blank_byte_v; }
61+
out.size = bytes.size();
62+
if (out.buffer.get().size < bytes.size()) {
63+
// size is too small (or buffer doesn't exist yet), recreate buffer.
64+
auto const buffer_ci = vma::BufferCreateInfo{
65+
.allocator = m_allocator,
66+
.usage = m_usage,
67+
.queue_family = m_queue_family,
68+
};
69+
out.buffer = vma::create_buffer(buffer_ci, vma::BufferMemoryType::Host,
70+
out.size);
71+
}
72+
std::memcpy(out.buffer.get().mapped, bytes.data(), bytes.size());
7273
}
7374
```
7475

75-
Store a `ShaderBuffer` in `App` and rename `create_vertex_buffer()` to `create_shader_resources()`:
76+
Store a `DescriptorBuffer` in `App` and rename `create_vertex_buffer()` to `create_shader_resources()`:
7677

7778
```cpp
78-
std::optional<ShaderBuffer> m_view_ubo{};
79+
std::optional<DescriptorBuffer> m_view_ubo{};
7980

8081
// ...
8182
m_vbo = vma::create_device_buffer(buffer_ci, create_command_block(),
@@ -170,4 +171,4 @@ static constexpr auto vertices_v = std::array{
170171

171172
![View UBO](./view_ubo.png)
172173

173-
When such shader buffers are created and (more importantly) destroyed dynamically, they would need to store a `ScopedWaiter` to ensure all rendering with descriptor sets bound to them completes before destruction. Alternatively, the app can maintain a pool of scratch buffers (similar to small/dynamic vertex buffers) per virtual frame which get destroyed in a batch instead of individually.
174+
When such descriptor buffers are created and destroyed dynamically, they would need to store a `ScopedWaiter` to ensure all rendering with descriptor sets bound to them completes before destruction. Alternatively, the app can maintain a pool of scratch buffers (similar to small/dynamic vertex buffers) per virtual frame which get destroyed in a batch instead of individually.

guide/src/descriptor_sets/instanced_rendering.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ Store the SSBO and a buffer for instance matrices:
66

77
```cpp
88
std::vector<glm::mat4> m_instance_data{}; // model matrices.
9-
std::optional<ShaderBuffer> m_instance_ssbo{};
9+
std::optional<DescriptorBuffer> m_instance_ssbo{};
1010
```
1111

1212
Add two `Transform`s as the source of rendering instances, and a function to update the matrices:

src/app.hpp

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
#pragma once
22
#include <command_block.hpp>
33
#include <dear_imgui.hpp>
4+
#include <descriptor_buffer.hpp>
45
#include <gpu.hpp>
56
#include <resource_buffering.hpp>
67
#include <scoped_waiter.hpp>
7-
#include <shader_buffer.hpp>
88
#include <shader_program.hpp>
99
#include <swapchain.hpp>
1010
#include <texture.hpp>
@@ -101,10 +101,10 @@ class App {
101101
std::optional<ShaderProgram> m_shader{};
102102

103103
vma::Buffer m_vbo{};
104-
std::optional<ShaderBuffer> m_view_ubo{};
104+
std::optional<DescriptorBuffer> m_view_ubo{};
105105
std::optional<Texture> m_texture{};
106106
std::vector<glm::mat4> m_instance_data{}; // model matrices.
107-
std::optional<ShaderBuffer> m_instance_ssbo{};
107+
std::optional<DescriptorBuffer> m_instance_ssbo{};
108108
Buffered<std::vector<vk::DescriptorSet>> m_descriptor_sets{};
109109

110110
glm::ivec2 m_framebuffer_size{};

src/shader_buffer.cpp renamed to src/descriptor_buffer.cpp

+9-9
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,29 @@
1-
#include <shader_buffer.hpp>
1+
#include <descriptor_buffer.hpp>
22

33
namespace lvk {
4-
ShaderBuffer::ShaderBuffer(VmaAllocator allocator,
5-
std::uint32_t const queue_family,
6-
vk::BufferUsageFlags const usage)
4+
DescriptorBuffer::DescriptorBuffer(VmaAllocator allocator,
5+
std::uint32_t const queue_family,
6+
vk::BufferUsageFlags const usage)
77
: m_allocator(allocator), m_queue_family(queue_family), m_usage(usage) {
88
// ensure buffers are created and can be bound after returning.
99
for (auto& buffer : m_buffers) { write_to(buffer, {}); }
1010
}
1111

12-
void ShaderBuffer::write_at(std::size_t const frame_index,
13-
std::span<std::byte const> bytes) {
12+
void DescriptorBuffer::write_at(std::size_t const frame_index,
13+
std::span<std::byte const> bytes) {
1414
write_to(m_buffers.at(frame_index), bytes);
1515
}
1616

17-
auto ShaderBuffer::descriptor_info_at(std::size_t const frame_index) const
17+
auto DescriptorBuffer::descriptor_info_at(std::size_t const frame_index) const
1818
-> vk::DescriptorBufferInfo {
1919
auto const& buffer = m_buffers.at(frame_index);
2020
auto ret = vk::DescriptorBufferInfo{};
2121
ret.setBuffer(buffer.buffer.get().buffer).setRange(buffer.size);
2222
return ret;
2323
}
2424

25-
void ShaderBuffer::write_to(Buffer& out,
26-
std::span<std::byte const> bytes) const {
25+
void DescriptorBuffer::write_to(Buffer& out,
26+
std::span<std::byte const> bytes) const {
2727
static constexpr auto blank_byte_v = std::array{std::byte{}};
2828
// fallback to an empty byte if bytes is empty.
2929
if (bytes.empty()) { bytes = blank_byte_v; }

src/shader_buffer.hpp renamed to src/descriptor_buffer.hpp

+4-3
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,11 @@
44
#include <cstdint>
55

66
namespace lvk {
7-
class ShaderBuffer {
7+
class DescriptorBuffer {
88
public:
9-
explicit ShaderBuffer(VmaAllocator allocator, std::uint32_t queue_family,
10-
vk::BufferUsageFlags usage);
9+
explicit DescriptorBuffer(VmaAllocator allocator,
10+
std::uint32_t queue_family,
11+
vk::BufferUsageFlags usage);
1112

1213
void write_at(std::size_t frame_index, std::span<std::byte const> bytes);
1314

0 commit comments

Comments
 (0)