Skip to content

Commit 39d2527

Browse files
committed
2 parents 46872f9 + f402e09 commit 39d2527

4 files changed

Lines changed: 55 additions & 28 deletions

File tree

Sources/ObjectivelyGPU/Buffer.c

Lines changed: 3 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
#include "CommandBuffer.h"
2929
#include "CopyPass.h"
3030
#include "RenderDevice.h"
31+
#include "TransferBuffer.h"
3132

3233
#define _Class _Buffer
3334

@@ -129,30 +130,19 @@ static void upload(Buffer *self, const void *data, Uint32 size, Uint32 offset, b
129130
assert(data);
130131
assert(size);
131132

132-
SDL_GPUTransferBuffer *tbuf = SDL_CreateGPUTransferBuffer(self->device->device, &(SDL_GPUTransferBufferCreateInfo) {
133-
.usage = SDL_GPU_TRANSFERBUFFERUSAGE_UPLOAD,
134-
.size = size,
135-
});
136-
GPU_Assert(tbuf, "SDL_CreateGPUTransferBuffer");
137-
138-
void *mapped = SDL_MapGPUTransferBuffer(self->device->device, tbuf, cycle);
139-
GPU_Assert(mapped, "SDL_MapGPUTransferBuffer");
140-
141-
memcpy(mapped, data, size);
142-
SDL_UnmapGPUTransferBuffer(self->device->device, tbuf);
133+
const TransferBuffer *tbuf = $(self->device, stageData, data, size);
143134

144135
CommandBuffer *commands = $(self->device, acquireCommandBuffer);
145136
CopyPass *copyPass = $(commands, beginCopyPass);
146137

147138
$(copyPass, uploadBuffer,
148-
&(SDL_GPUTransferBufferLocation) { .transfer_buffer = tbuf },
139+
&(SDL_GPUTransferBufferLocation) { .transfer_buffer = tbuf->buffer },
149140
&(SDL_GPUBufferRegion) { .buffer = self->buffer, .offset = offset, .size = size },
150141
cycle);
151142

152143
release(copyPass);
153144
$(commands, submit);
154145
release(commands);
155-
SDL_ReleaseGPUTransferBuffer(self->device->device, tbuf);
156146
}
157147

158148
#pragma mark - Class lifecycle

Sources/ObjectivelyGPU/CopyPass.c

Lines changed: 3 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
#include "CopyPass.h"
2929
#include "QueryPool.h"
3030
#include "RenderDevice.h"
31+
#include "TransferBuffer.h"
3132

3233
#define _Class _CopyPass
3334

@@ -147,24 +148,12 @@ static void uploadData(const CopyPass *self, SDL_GPUBuffer *dst, const void *dat
147148
assert(data);
148149
assert(size);
149150

150-
SDL_GPUTransferBuffer *tbuf = SDL_CreateGPUTransferBuffer(self->commands->device->device, &(SDL_GPUTransferBufferCreateInfo) {
151-
.usage = SDL_GPU_TRANSFERBUFFERUSAGE_UPLOAD,
152-
.size = size,
153-
});
154-
GPU_Assert(tbuf, "SDL_CreateGPUTransferBuffer");
155-
156-
void *mapped = SDL_MapGPUTransferBuffer(self->commands->device->device, tbuf, cycle);
157-
GPU_Assert(mapped, "SDL_MapGPUTransferBuffer");
158-
159-
memcpy(mapped, data, size);
160-
SDL_UnmapGPUTransferBuffer(self->commands->device->device, tbuf);
151+
const TransferBuffer *tbuf = $(self->commands->device, stageData, data, size);
161152

162153
SDL_UploadToGPUBuffer(self->pass,
163-
&(SDL_GPUTransferBufferLocation) { .transfer_buffer = tbuf },
154+
&(SDL_GPUTransferBufferLocation) { .transfer_buffer = tbuf->buffer },
164155
&(SDL_GPUBufferRegion) { .buffer = dst, .offset = offset, .size = size },
165156
cycle);
166-
167-
SDL_ReleaseGPUTransferBuffer(self->commands->device->device, tbuf);
168157
}
169158

170159
/**

Sources/ObjectivelyGPU/RenderDevice.c

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,7 @@ static void dealloc(Object *self) {
118118

119119
RenderDevice *this = (RenderDevice *) self;
120120

121+
release(this->scratch);
121122
release(this->framebuffer);
122123

123124
if (this->window && this->device) {
@@ -610,6 +611,30 @@ static void setWindow(RenderDevice *self, SDL_Window *window) {
610611
}
611612
}
612613

614+
/**
615+
* @fn TransferBuffer *RenderDevice::stageData(RenderDevice *self, const void *data, Uint32 size)
616+
* @memberof RenderDevice
617+
*/
618+
static TransferBuffer *stageData(RenderDevice *self, const void *data, Uint32 size) {
619+
620+
assert(data);
621+
assert(size);
622+
623+
if (self->scratch == NULL || self->scratch->size < size) {
624+
release(self->scratch);
625+
self->scratch = $(self, createTransferBuffer, &(SDL_GPUTransferBufferCreateInfo) {
626+
.usage = SDL_GPU_TRANSFERBUFFERUSAGE_UPLOAD,
627+
.size = size,
628+
});
629+
}
630+
631+
void *mapped = $(self->scratch, map, true);
632+
memcpy(mapped, data, size);
633+
$(self->scratch, unmap);
634+
635+
return self->scratch;
636+
}
637+
613638
/**
614639
* @fn bool RenderDevice::supportsPresentMode(const RenderDevice *self, SDL_GPUPresentMode mode)
615640
* @memberof RenderDevice
@@ -701,6 +726,7 @@ static void initialize(Class *clazz) {
701726
((RenderDeviceInterface *) clazz->interface)->setFramebuffer = setFramebuffer;
702727
((RenderDeviceInterface *) clazz->interface)->setSwapchainParameters = setSwapchainParameters;
703728
((RenderDeviceInterface *) clazz->interface)->setWindow = setWindow;
729+
((RenderDeviceInterface *) clazz->interface)->stageData = stageData;
704730
((RenderDeviceInterface *) clazz->interface)->supportsPresentMode = supportsPresentMode;
705731
((RenderDeviceInterface *) clazz->interface)->supportsSwapchainComposition = supportsSwapchainComposition;
706732
((RenderDeviceInterface *) clazz->interface)->textureSupportsFormat = textureSupportsFormat;

Sources/ObjectivelyGPU/RenderDevice.h

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,14 @@ struct RenderDevice {
117117
* @private
118118
*/
119119
SwapchainTexture swapchain;
120-
120+
121+
/**
122+
* @brief The scratch upload transfer buffer shared by streaming uploads
123+
* (`stageData`), created and grown on demand and cycled thereafter.
124+
* @private
125+
*/
126+
TransferBuffer *scratch;
127+
121128
/**
122129
* @brief User data.
123130
*/
@@ -559,6 +566,21 @@ struct RenderDeviceInterface {
559566
*/
560567
void (*setWindow)(RenderDevice *self, SDL_Window *window);
561568

569+
/**
570+
* @fn TransferBuffer *RenderDevice::stageData(RenderDevice *self, const void *data, Uint32 size)
571+
* @brief Stages `size` bytes of `data` into this device's shared scratch
572+
* upload transfer buffer, which is created or grown on demand and mapped
573+
* with cycling thereafter -- back-to-back uploads neither stall on frames
574+
* in flight nor create and release a transfer buffer per call.
575+
* @param self The RenderDevice.
576+
* @param data The data to stage.
577+
* @param size The size of `data`, in bytes.
578+
* @return The scratch transfer buffer, ready to source an upload. Borrowed,
579+
* not retained; its contents are valid only until the next `stageData`.
580+
* @memberof RenderDevice
581+
*/
582+
TransferBuffer *(*stageData)(RenderDevice *self, const void *data, Uint32 size);
583+
562584
/**
563585
* @fn bool RenderDevice::supportsPresentMode(const RenderDevice *self, SDL_GPUPresentMode mode)
564586
* @brief Queries whether this device's swapchain supports the given present mode.

0 commit comments

Comments
 (0)