Skip to content

Commit 67c569c

Browse files
committed
Unify frame-based ring buffering logic (swapchain, staging buffers, and GpuMemoryAllocator)
1 parent de54186 commit 67c569c

19 files changed

Lines changed: 85 additions & 76 deletions

demo/android/app/src/main/cpp/native_engine.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ void NativeEngine::draw_frame() {
1212
return;
1313
}
1414

15+
pf_device->begin_frame();
16+
1517
auto current_window_size = pf_window->get_logical_size();
1618

1719
if (current_window_size != pf_app->canvas_->get_dst_texture()->get_size() && current_window_size.area() != 0) {

demo/native/main.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@ int main() {
4949
continue;
5050
}
5151

52+
device->begin_frame();
53+
5254
auto current_window_size = window->get_physical_size();
5355

5456
if (current_window_size != app.canvas_->get_dst_texture()->get_size() && current_window_size.area() != 0) {

pathfinder/gpu/command_encoder.cpp

Lines changed: 0 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -214,11 +214,6 @@ void CommandEncoder::write_buffer(const std::shared_ptr<Buffer> &buffer,
214214
auto device = device_.lock();
215215
auto allocation = device->allocate_staging(data_size);
216216

217-
if (!used_staging_buffer_) {
218-
used_staging_buffer_ = true;
219-
device->increment_staging_encoder();
220-
}
221-
222217
void *mapped_ptr = device->map_staging(allocation);
223218
memcpy(mapped_ptr, data, data_size);
224219
device->unmap_staging(allocation);
@@ -255,11 +250,6 @@ void CommandEncoder::read_buffer(const std::shared_ptr<Buffer> &buffer,
255250
auto device = device_.lock();
256251
auto allocation = device->allocate_staging(data_size);
257252

258-
if (!used_staging_buffer_) {
259-
used_staging_buffer_ = true;
260-
device->increment_staging_encoder();
261-
}
262-
263253
Command cmd{};
264254
cmd.type = CommandType::WriteBuffer;
265255

@@ -298,11 +288,6 @@ void CommandEncoder::write_texture(const std::shared_ptr<Texture> &texture, Rect
298288
auto device = device_.lock();
299289
auto allocation = device->allocate_staging(data_size);
300290

301-
if (!used_staging_buffer_) {
302-
used_staging_buffer_ = true;
303-
device->increment_staging_encoder();
304-
}
305-
306291
void *mapped_ptr = device->map_staging(allocation);
307292
memcpy(mapped_ptr, src, data_size);
308293
device->unmap_staging(allocation);
@@ -340,11 +325,6 @@ void CommandEncoder::read_texture(const std::shared_ptr<Texture> &texture, RectI
340325
auto device = device_.lock();
341326
auto allocation = device->allocate_staging(data_size);
342327

343-
if (!used_staging_buffer_) {
344-
used_staging_buffer_ = true;
345-
device->increment_staging_encoder();
346-
}
347-
348328
Command cmd{};
349329
cmd.type = CommandType::ReadTexture;
350330

@@ -376,12 +356,6 @@ void CommandEncoder::invoke_callbacks() {
376356

377357
callbacks_.clear();
378358
temp_buffers_.clear();
379-
380-
if (used_staging_buffer_) {
381-
if (auto device = device_.lock()) {
382-
device_.lock()->decrement_staging_encoder();
383-
}
384-
}
385359
}
386360

387361
} // namespace Pathfinder

pathfinder/gpu/command_encoder.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -270,8 +270,6 @@ class CommandEncoder {
270270
std::weak_ptr<Device> device_;
271271

272272
std::vector<std::shared_ptr<Framebuffer>> framebuffers_;
273-
274-
bool used_staging_buffer_ = false;
275273
};
276274

277275
} // namespace Pathfinder

pathfinder/gpu/device.cpp

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,9 @@ StagingAllocation Device::allocate_staging(size_t size) {
1414
return alloc;
1515
}
1616

17-
for (auto &block : staging_blocks_) {
17+
auto &bucket = staging_buckets_[current_frame_index_ % frames_in_flight_];
18+
19+
for (auto &block : bucket.blocks) {
1820
size_t aligned_offset = (block.used_size + 15) & ~15;
1921

2022
if (aligned_offset + size <= STAGING_BLOCK_SIZE) {
@@ -34,7 +36,7 @@ StagingAllocation Device::allocate_staging(size_t size) {
3436
StagingBlock new_block;
3537
new_block.buffer = buffer;
3638
new_block.used_size = size;
37-
staging_blocks_.push_back(new_block);
39+
bucket.blocks.push_back(new_block);
3840

3941
StagingAllocation alloc;
4042
alloc.buffer = buffer;
@@ -46,8 +48,10 @@ StagingAllocation Device::allocate_staging(size_t size) {
4648
}
4749

4850
void Device::reset_staging() {
49-
for (auto &block : staging_blocks_) {
50-
block.used_size = 0;
51+
for (auto &bucket : staging_buckets_) {
52+
for (auto &block : bucket.blocks) {
53+
block.used_size = 0;
54+
}
5155
}
5256
}
5357

pathfinder/gpu/device.h

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -89,30 +89,46 @@ class Device : public std::enable_shared_from_this<Device> {
8989
}
9090

9191
public:
92-
void increment_staging_encoder() {
93-
pending_staging_encoders_++;
94-
}
92+
void begin_frame() {
93+
current_frame_index_++;
9594

96-
void decrement_staging_encoder() {
97-
pending_staging_encoders_--;
98-
if (pending_staging_encoders_ == 0) {
99-
reset_staging();
95+
auto &bucket = staging_buckets_[current_frame_index_ % frames_in_flight_];
96+
for (auto &block : bucket.blocks) {
97+
block.used_size = 0;
10098
}
10199
}
102100

101+
int get_frames_in_flight() const {
102+
return frames_in_flight_;
103+
}
104+
105+
uint32_t get_current_frame_index() const {
106+
return current_frame_index_;
107+
}
108+
103109
protected:
110+
Device(int frames_in_flight) : frames_in_flight_(frames_in_flight) {
111+
staging_buckets_.resize(frames_in_flight_);
112+
}
113+
104114
BackendType backend_type = BackendType::Vulkan;
105115

106116
struct StagingBlock {
107117
std::shared_ptr<Buffer> buffer;
108118
size_t used_size = 0;
109119
};
110120

121+
struct StagingBucket {
122+
std::vector<StagingBlock> blocks;
123+
};
124+
111125
const size_t STAGING_BLOCK_SIZE = 4 * 1024 * 1024;
112126

113-
std::vector<StagingBlock> staging_blocks_;
127+
std::vector<StagingBucket> staging_buckets_;
128+
129+
int frames_in_flight_;
114130

115-
uint32_t pending_staging_encoders_ = 0;
131+
uint32_t current_frame_index_ = 0;
116132

117133
virtual std::shared_ptr<Buffer> create_staging_buffer(size_t size) = 0;
118134
};

pathfinder/gpu/gl/device.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212

1313
namespace Pathfinder {
1414

15-
DeviceGl::DeviceGl() {
15+
DeviceGl::DeviceGl(int frames_in_flight) : Device(frames_in_flight) {
1616
backend_type = BackendType::Opengl;
1717

1818
glGetIntegerv(GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT, &min_uniform_alignment_);

pathfinder/gpu/gl/device.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ namespace Pathfinder {
1212

1313
class DeviceGl : public Device {
1414
public:
15-
DeviceGl();
15+
DeviceGl(int frames_in_flight);
1616

1717
std::shared_ptr<Framebuffer> create_framebuffer(const std::shared_ptr<RenderPass> &render_pass,
1818
const std::shared_ptr<Texture> &texture,

pathfinder/gpu/gl/window_builder.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -232,8 +232,10 @@ uint8_t WindowBuilderGl::create_window(const Vec2I &size, const std::string &tit
232232
#endif
233233
}
234234

235+
constexpr int MAX_FRAMES_IN_FLIGHT = 2;
236+
235237
std::shared_ptr<Device> WindowBuilderGl::request_device() {
236-
return std::make_shared<DeviceGl>();
238+
return std::make_shared<DeviceGl>(MAX_FRAMES_IN_FLIGHT);
237239
}
238240

239241
std::shared_ptr<Queue> WindowBuilderGl::create_queue() {

pathfinder/gpu/mtl/device.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ class QueueMtl;
1313

1414
class DeviceMtl final : public Device {
1515
public:
16-
DeviceMtl(id<MTLDevice> device, id<MTLCommandQueue> mtl_cmd_queue);
16+
DeviceMtl(id<MTLDevice> device, id<MTLCommandQueue> mtl_cmd_queue, int frames_in_flight);
1717

1818
~DeviceMtl() override;
1919

0 commit comments

Comments
 (0)