Skip to content

Commit e0e05ba

Browse files
jdolanCopilot
andcommitted
Move SwapchainTexture and acquireSwapchainTexture to CommandBuffer
SwapchainTexture belongs on CommandBuffer: SDL3 acquires the swapchain texture from a command buffer, and the texture is only valid until that buffer is submitted. RenderDevice::acquireSwapchainTexture was a thin wrapper that just forwarded to cmd->cmd — remove it entirely. Callers: Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent cdfd90e commit e0e05ba

7 files changed

Lines changed: 76 additions & 105 deletions

File tree

Examples/Hello-iOS/Hello-iOS.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -275,7 +275,7 @@ SDL_AppResult SDL_AppIterate(void *unused) {
275275
while (app.angleY >= 360.0f) app.angleY -= 360.0f;
276276

277277
CommandBuffer *cmd = $(app.renderDevice, acquireCommandBuffer);
278-
Swapchain swapchain = { 0 };
278+
SwapchainTexture swapchain = { 0 };
279279
if (!$(app.renderDevice, acquireSwapchainTexture, cmd, &swapchain)) {
280280
$(cmd, cancel);
281281
release(cmd);

Examples/Hello.c

Lines changed: 28 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -182,39 +182,35 @@ int main(int argc, char **argv) {
182182
}
183183

184184
CommandBuffer *cmd = $(renderDevice, acquireCommandBuffer);
185-
Swapchain swapchain = { 0 };
186185

187-
if (!$(renderDevice, acquireSwapchainTexture, cmd, &swapchain)) {
188-
$(cmd, cancel);
189-
release(cmd);
190-
continue;
191-
}
192-
193-
float4x4 modelView = float4x4_rotation(angleX, float3_new(1.f, 0.f, 0.f));
194-
modelView = float4x4_mul(float4x4_rotation(angleY, float3_new(0.f, 1.f, 0.f)), modelView);
195-
modelView = float4x4_mul(float4x4_translation(float3_new(0.f, 0.f, -2.5f)), modelView);
196-
const float4x4 projection = float4x4_perspective(45.f, (float) swapchain.size.w / (float) swapchain.size.h, 0.01f, 100.f);
197-
const float4x4 modelViewProjection = float4x4_mul(projection, modelView);
198-
199-
SDL_GPUColorTargetInfo colorTarget = {
200-
.texture = swapchain.texture,
201-
.clear_color = { 0.1f, 0.1f, 0.2f, 1.0f },
202-
.load_op = SDL_GPU_LOADOP_CLEAR,
203-
.store_op = SDL_GPU_STOREOP_STORE,
204-
};
205-
206-
SDL_GPUDepthStencilTargetInfo depthTarget = $(framebuffer, depthTargetInfo,
207-
SDL_GPU_LOADOP_CLEAR, SDL_GPU_STOREOP_DONT_CARE, 1.f);
208-
209-
RenderPass *renderPass = $(cmd, beginRenderPass, &colorTarget, 1, &depthTarget);
210-
$(renderPass, bindPipeline, pipeline);
211-
$(renderPass, bindVertexBuffers, 0, &(SDL_GPUBufferBinding) {
212-
.buffer = vertexBuffer,
213-
.offset = 0,
214-
}, 1);
215-
$(cmd, pushVertexUniformData, 0, modelViewProjection.f, sizeof(modelViewProjection));
216-
$(renderPass, drawPrimitives, (Uint32) SDL_arraysize(vertex_data), 1, 0, 0);
217-
release(renderPass);
186+
SwapchainTexture swapchain = { 0 };
187+
if ($(cmd, acquireSwapchainTexture, window, &swapchain)) {
188+
189+
float4x4 modelView = float4x4_rotation(angleX, float3_new(1.f, 0.f, 0.f));
190+
modelView = float4x4_mul(float4x4_rotation(angleY, float3_new(0.f, 1.f, 0.f)), modelView);
191+
modelView = float4x4_mul(float4x4_translation(float3_new(0.f, 0.f, -2.5f)), modelView);
192+
const float4x4 projection = float4x4_perspective(45.f, (float) swapchain.size.w / (float) swapchain.size.h, 0.01f, 100.f);
193+
const float4x4 modelViewProjection = float4x4_mul(projection, modelView);
194+
195+
SDL_GPUColorTargetInfo colorTarget = {
196+
.texture = swapchain.texture,
197+
.clear_color = { 0.1f, 0.1f, 0.2f, 1.0f },
198+
.load_op = SDL_GPU_LOADOP_CLEAR,
199+
.store_op = SDL_GPU_STOREOP_STORE,
200+
};
201+
202+
SDL_GPUDepthStencilTargetInfo depthTarget = $(framebuffer, depthTargetInfo, SDL_GPU_LOADOP_CLEAR, SDL_GPU_STOREOP_DONT_CARE, 1.f);
203+
204+
RenderPass *renderPass = $(cmd, beginRenderPass, &colorTarget, 1, &depthTarget);
205+
$(renderPass, bindPipeline, pipeline);
206+
$(renderPass, bindVertexBuffers, 0, &(SDL_GPUBufferBinding) {
207+
.buffer = vertexBuffer,
208+
.offset = 0,
209+
}, 1);
210+
$(cmd, pushVertexUniformData, 0, modelViewProjection.f, sizeof(modelViewProjection));
211+
$(renderPass, drawPrimitives, (Uint32) SDL_arraysize(vertex_data), 1, 0, 0);
212+
release(renderPass);
213+
}
218214

219215
$(cmd, submit);
220216
release(cmd);

Examples/HelloCompute.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -143,9 +143,9 @@ int main(int argc, char **argv) {
143143
}
144144

145145
CommandBuffer *cmd = $(renderDevice, acquireCommandBuffer);
146-
Swapchain swapchain = { 0 };
146+
SwapchainTexture swapchain = { 0 };
147147

148-
if (!$(renderDevice, acquireSwapchainTexture, cmd, &swapchain)) {
148+
if (!$(cmd, acquireSwapchainTexture, window, &swapchain)) {
149149
$(cmd, cancel);
150150
release(cmd);
151151
continue;

Sources/ObjectivelyGPU/CommandBuffer.c

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,16 @@
3333
#pragma mark - CommandBuffer
3434

3535
/**
36-
* @fn bool CommandBuffer::acquireSwapchainTexture(const CommandBuffer *self, SDL_Window *window, SDL_GPUTexture **texture, Uint32 *w, Uint32 *h)
36+
* @fn bool CommandBuffer::acquireSwapchainTexture(const CommandBuffer *self, SDL_Window *window, SwapchainTexture *swapchain)
3737
* @memberof CommandBuffer
3838
*/
39-
static bool acquireSwapchainTexture(const CommandBuffer *self, SDL_Window *window, SDL_GPUTexture **texture, Uint32 *w, Uint32 *h) {
40-
return SDL_AcquireGPUSwapchainTexture(self->cmd, window, texture, w, h);
39+
static bool acquireSwapchainTexture(const CommandBuffer *self, SDL_Window *window, SwapchainTexture *swapchain) {
40+
assert(swapchain);
41+
42+
Uint32 w = 0, h = 0;
43+
const bool ok = SDL_AcquireGPUSwapchainTexture(self->cmd, window, &swapchain->texture, &w, &h);
44+
swapchain->size = MakeSize(w, h);
45+
return ok && swapchain->texture;
4146
}
4247

4348
/**
@@ -194,14 +199,17 @@ static SDL_GPUFence *submitAndFence(const CommandBuffer *self) {
194199
}
195200

196201
/**
197-
* @fn bool CommandBuffer::waitAndAcquireSwapchainTexture(const CommandBuffer *self, SDL_Window *window, SDL_GPUTexture **texture, Uint32 *w, Uint32 *h)
202+
* @fn bool CommandBuffer::waitAndAcquireSwapchainTexture(const CommandBuffer *self, SDL_Window *window, SwapchainTexture *swapchain)
198203
* @memberof CommandBuffer
199204
*/
200-
static bool waitAndAcquireSwapchainTexture(const CommandBuffer *self, SDL_Window *window, SDL_GPUTexture **texture, Uint32 *w, Uint32 *h) {
205+
static bool waitAndAcquireSwapchainTexture(const CommandBuffer *self, SDL_Window *window, SwapchainTexture *swapchain) {
206+
assert(swapchain);
201207

202-
const bool ok = SDL_WaitAndAcquireGPUSwapchainTexture(self->cmd, window, texture, w, h);
208+
Uint32 w = 0, h = 0;
209+
const bool ok = SDL_WaitAndAcquireGPUSwapchainTexture(self->cmd, window, &swapchain->texture, &w, &h);
203210
GPU_Assert(ok, "SDL_WaitAndAcquireGPUSwapchainTexture");
204211

212+
swapchain->size = MakeSize(w, h);
205213
return ok;
206214
}
207215

Sources/ObjectivelyGPU/CommandBuffer.h

Lines changed: 31 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,25 @@ typedef struct CopyPass CopyPass;
3737
typedef struct RenderPass RenderPass;
3838
typedef struct CommandBuffer CommandBuffer;
3939
typedef struct CommandBufferInterface CommandBufferInterface;
40+
typedef struct SwapchainTexture SwapchainTexture;
41+
42+
/**
43+
* @brief The swapchain texture acquired for a single frame.
44+
* @details Valid only between a successful `acquireSwapchainTexture` call and
45+
* the `submit` of the same `CommandBuffer`. SDL3 reclaims the texture on submit.
46+
*/
47+
struct SwapchainTexture {
48+
49+
/**
50+
* @brief The swapchain render target for this frame.
51+
*/
52+
SDL_GPUTexture *texture;
53+
54+
/**
55+
* @brief The swapchain dimensions in pixels.
56+
*/
57+
SDL_Size size;
58+
};
4059

4160
/**
4261
* @brief A recorded sequence of GPU commands for a single frame.
@@ -87,17 +106,18 @@ struct CommandBufferInterface {
87106
ObjectInterface objectInterface;
88107

89108
/**
90-
* @fn bool CommandBuffer::acquireSwapchainTexture(const CommandBuffer *self, SDL_Window *window, SDL_GPUTexture **texture, Uint32 *w, Uint32 *h)
109+
* @fn bool CommandBuffer::acquireSwapchainTexture(const CommandBuffer *self, SDL_Window *window, SwapchainTexture *swapchain)
91110
* @brief Acquires the next swapchain texture for rendering.
111+
* @details Returns `false` (without asserting) when the window is minimised
112+
* or the swapchain is temporarily unavailable. The caller should skip
113+
* rendering for that frame.
92114
* @param self The CommandBuffer.
93115
* @param window The window whose swapchain to acquire.
94-
* @param texture Receives the swapchain texture, or NULL if unavailable this frame.
95-
* @param w Receives the swapchain width in pixels, or NULL.
96-
* @param h Receives the swapchain height in pixels, or NULL.
97-
* @return True on success, false on error.
116+
* @param swapchain Output structure populated with the texture and dimensions.
117+
* @return True on success, false when the swapchain is unavailable this frame.
98118
* @memberof CommandBuffer
99119
*/
100-
bool (*acquireSwapchainTexture)(const CommandBuffer *self, SDL_Window *window, SDL_GPUTexture **texture, Uint32 *w, Uint32 *h);
120+
bool (*acquireSwapchainTexture)(const CommandBuffer *self, SDL_Window *window, SwapchainTexture *swapchain);
101121

102122
/**
103123
* @fn ComputePass *CommandBuffer::beginComputePass(const CommandBuffer *self, ...)
@@ -239,18 +259,17 @@ struct CommandBufferInterface {
239259
SDL_GPUFence *(*submitAndFence)(const CommandBuffer *self);
240260

241261
/**
242-
* @fn bool CommandBuffer::waitAndAcquireSwapchainTexture(const CommandBuffer *self, SDL_Window *window, SDL_GPUTexture **texture, Uint32 *w, Uint32 *h)
262+
* @fn bool CommandBuffer::waitAndAcquireSwapchainTexture(const CommandBuffer *self, SDL_Window *window, SwapchainTexture *swapchain)
243263
* @brief Blocks until a swapchain texture is available, then acquires it.
244-
* @details Prefer `acquireSwapchainTexture` unless you must block.
264+
* @details Prefer `acquireSwapchainTexture` unless you must guarantee a
265+
* texture this frame (e.g. during resize).
245266
* @param self The CommandBuffer.
246267
* @param window The window whose swapchain to acquire.
247-
* @param texture Receives the swapchain texture.
248-
* @param w Receives the swapchain width in pixels, or NULL.
249-
* @param h Receives the swapchain height in pixels, or NULL.
268+
* @param swapchain Output structure populated with the texture and dimensions.
250269
* @return True on success, false on error.
251270
* @memberof CommandBuffer
252271
*/
253-
bool (*waitAndAcquireSwapchainTexture)(const CommandBuffer *self, SDL_Window *window, SDL_GPUTexture **texture, Uint32 *w, Uint32 *h);
272+
bool (*waitAndAcquireSwapchainTexture)(const CommandBuffer *self, SDL_Window *window, SwapchainTexture *swapchain);
254273
};
255274

256275
/**

Sources/ObjectivelyGPU/RenderDevice.c

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -78,21 +78,6 @@ static CommandBuffer *acquireCommandBuffer(const RenderDevice *self) {
7878
return buffer;
7979
}
8080

81-
/**
82-
* @fn bool RenderDevice::acquireSwapchainTexture(const RenderDevice *self, CommandBuffer *cmd, Swapchain *swapchain)
83-
* @memberof RenderDevice
84-
*/
85-
static bool acquireSwapchainTexture(const RenderDevice *self, CommandBuffer *cmd, Swapchain *swapchain) {
86-
87-
SDL_AcquireGPUSwapchainTexture(cmd->cmd,
88-
self->window,
89-
&swapchain->texture,
90-
(unsigned int *) &swapchain->size.w,
91-
(unsigned int *) &swapchain->size.h);
92-
93-
return swapchain->texture != NULL;
94-
}
95-
9681
/**
9782
* @fn SDL_GPUBuffer *RenderDevice::createBuffer(const RenderDevice *self, const SDL_GPUBufferCreateInfo *info)
9883
* @memberof RenderDevice
@@ -788,7 +773,6 @@ static void initialize(Class *clazz) {
788773
((ObjectInterface *) clazz->interface)->dealloc = dealloc;
789774

790775
((RenderDeviceInterface *) clazz->interface)->acquireCommandBuffer = acquireCommandBuffer;
791-
((RenderDeviceInterface *) clazz->interface)->acquireSwapchainTexture = acquireSwapchainTexture;
792776
((RenderDeviceInterface *) clazz->interface)->createBuffer = createBuffer;
793777
((RenderDeviceInterface *) clazz->interface)->createBufferWithConstMem = createBufferWithConstMem;
794778
((RenderDeviceInterface *) clazz->interface)->createBufferWithData = createBufferWithData;

Sources/ObjectivelyGPU/RenderDevice.h

Lines changed: 0 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -41,27 +41,6 @@
4141

4242
typedef struct CommandBuffer CommandBuffer;
4343
typedef struct RenderDevice RenderDevice;
44-
45-
/**
46-
* @brief The Swapchain (render target) type.
47-
*/
48-
struct Swapchain {
49-
50-
/**
51-
* @brief The current render target.
52-
* @private
53-
*/
54-
SDL_GPUTexture *texture;
55-
56-
/**
57-
* @brief The swapchain dimensions.
58-
* @private
59-
*/
60-
SDL_Size size;
61-
};
62-
63-
typedef struct Swapchain Swapchain;
64-
6544
typedef struct RenderDeviceInterface RenderDeviceInterface;
6645

6746
/**
@@ -140,21 +119,6 @@ struct RenderDeviceInterface {
140119
*/
141120
CommandBuffer *(*acquireCommandBuffer)(const RenderDevice *self);
142121

143-
/**
144-
* @fn bool RenderDevice::acquireSwapchainTexture(const RenderDevice *self, CommandBuffer *cmd, Swapchain *swapchain)
145-
* @brief Acquires the swapchain render target for the current frame.
146-
* @details Wraps `SDL_AcquireGPUSwapchainTexture` using `self->window`. On
147-
* success, fills `swapchain->texture` with the current back-buffer and
148-
* `swapchain->size` with its pixel dimensions. Returns `false` (without
149-
* asserting) when the window is minimised or the swapchain is unavailable.
150-
* @param self The RenderDevice.
151-
* @param cmd The active CommandBuffer for this frame.
152-
* @param swapchain Output structure to populate with the texture and dimensions.
153-
* @return `true` if a swapchain texture was acquired; `false` otherwise.
154-
* @memberof RenderDevice
155-
*/
156-
bool (*acquireSwapchainTexture)(const RenderDevice *self, CommandBuffer *cmd, Swapchain *swapchain);
157-
158122
/**
159123
* @fn SDL_GPUBuffer *RenderDevice::createBuffer(const RenderDevice *self, const SDL_GPUBufferCreateInfo *info)
160124
* @brief Creates a GPU-side buffer (vertex, index, indirect, etc.).

0 commit comments

Comments
 (0)