Skip to content

Commit f4c16d2

Browse files
committed
CommandBuffer::beginRenderPassWithFramebuffer convenience method.
1 parent d1d3b2c commit f4c16d2

4 files changed

Lines changed: 84 additions & 10 deletions

File tree

Sources/ObjectivelyGPU/CommandBuffer.c

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
#include "ComputePass.h"
2828
#include "CopyPass.h"
2929
#include "Fence.h"
30+
#include "Framebuffer.h"
3031
#include "RenderDevice.h"
3132
#include "RenderPass.h"
3233

@@ -125,6 +126,29 @@ static RenderPass *beginRenderPass(CommandBuffer *self, const SDL_GPUColorTarget
125126
return renderPass;
126127
}
127128

129+
/**
130+
* @fn RenderPass *CommandBuffer::beginRenderPassWithFramebuffer(CommandBuffer *self, const Framebuffer *framebuffer, SDL_GPULoadOp loadOp, SDL_GPUStoreOp storeOp)
131+
* @memberof CommandBuffer
132+
*/
133+
static RenderPass *beginRenderPassWithFramebuffer(CommandBuffer *self, const Framebuffer *framebuffer, SDL_GPULoadOp loadOp, SDL_GPUStoreOp storeOp) {
134+
135+
assert(framebuffer);
136+
137+
SDL_GPUColorTargetInfo color[GPU_MAX_COLOR_TARGETS];
138+
for (Uint32 i = 0; i < framebuffer->numColorTargets; i++) {
139+
color[i] = $(framebuffer, colorTargetInfo, i, loadOp, storeOp, NULL);
140+
}
141+
142+
SDL_GPUDepthStencilTargetInfo depth;
143+
const SDL_GPUDepthStencilTargetInfo *depthStencil = NULL;
144+
if (framebuffer->depthFormat != SDL_GPU_TEXTUREFORMAT_INVALID) {
145+
depth = $(framebuffer, depthTargetInfo, loadOp, storeOp, framebuffer->clearDepth);
146+
depthStencil = &depth;
147+
}
148+
149+
return beginRenderPass(self, framebuffer->numColorTargets ? color : NULL, framebuffer->numColorTargets, depthStencil);
150+
}
151+
128152
/**
129153
* @fn void CommandBuffer::blitTexture(const CommandBuffer *self, const SDL_GPUBlitInfo *info)
130154
* @memberof CommandBuffer
@@ -302,6 +326,7 @@ static void initialize(Class *clazz) {
302326
((CommandBufferInterface *) clazz->interface)->beginComputePass = beginComputePass;
303327
((CommandBufferInterface *) clazz->interface)->beginCopyPass = beginCopyPass;
304328
((CommandBufferInterface *) clazz->interface)->beginRenderPass = beginRenderPass;
329+
((CommandBufferInterface *) clazz->interface)->beginRenderPassWithFramebuffer = beginRenderPassWithFramebuffer;
305330
((CommandBufferInterface *) clazz->interface)->blitTexture = blitTexture;
306331
((CommandBufferInterface *) clazz->interface)->cancel = cancel;
307332
((CommandBufferInterface *) clazz->interface)->generateMipmaps = generateMipmaps;

Sources/ObjectivelyGPU/CommandBuffer.h

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
typedef struct ComputePass ComputePass;
3636
typedef struct CopyPass CopyPass;
3737
typedef struct Fence Fence;
38+
typedef struct Framebuffer Framebuffer;
3839
typedef struct RenderPass RenderPass;
3940
typedef struct RenderDevice RenderDevice;
4041
typedef struct CommandBuffer CommandBuffer;
@@ -183,6 +184,25 @@ struct CommandBufferInterface {
183184
*/
184185
RenderPass *(*beginRenderPass)(CommandBuffer *self, const SDL_GPUColorTargetInfo *colorTargets, Uint32 numColorTargets, const SDL_GPUDepthStencilTargetInfo *depthStencil);
185186

187+
/**
188+
* @fn RenderPass *CommandBuffer::beginRenderPassWithFramebuffer(CommandBuffer *self, const Framebuffer *framebuffer, SDL_GPULoadOp loadOp, SDL_GPUStoreOp storeOp)
189+
* @brief Begins a render pass over all of @p framebuffer's color targets and its
190+
* depth target (if any), using its own clear color(s) and clear depth when @p loadOp
191+
* is `SDL_GPU_LOADOP_CLEAR`.
192+
* @details Convenience for the common case of "render into this framebuffer" with a
193+
* single load/store op shared by every target. For a mix of load ops across targets,
194+
* per-target clear overrides, a query pool, or a subset of a framebuffer's targets
195+
* (e.g. a depth-only pass), build the target infos yourself via
196+
* `Framebuffer::colorTargetInfo`/`depthTargetInfo` and call `beginRenderPass` directly.
197+
* @param self The CommandBuffer.
198+
* @param framebuffer The Framebuffer to render into.
199+
* @param loadOp Load operation applied uniformly to every target.
200+
* @param storeOp Store operation applied uniformly to every target.
201+
* @return A new RenderPass, retained. Must be released by the caller.
202+
* @memberof CommandBuffer
203+
*/
204+
RenderPass *(*beginRenderPassWithFramebuffer)(CommandBuffer *self, const Framebuffer *framebuffer, SDL_GPULoadOp loadOp, SDL_GPUStoreOp storeOp);
205+
186206
/**
187207
* @fn void CommandBuffer::blitTexture(const CommandBuffer *self, const SDL_GPUBlitInfo *info)
188208
* @brief Blits a region of one texture to another.

Sources/ObjectivelyGPU/Framebuffer.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ static SDL_GPUColorTargetInfo colorTargetInfo(const Framebuffer *self, Uint32 in
6565
.texture = self->colorTextures[index]->texture,
6666
.load_op = loadOp,
6767
.store_op = storeOp,
68-
.clear_color = clearColor ? *clearColor : (SDL_FColor) { 0.f, 0.f, 0.f, 1.f },
68+
.clear_color = clearColor ? *clearColor : self->clearColors[index],
6969
};
7070

7171
if (self->sampleCount > SDL_GPU_SAMPLECOUNT_1) {
@@ -117,8 +117,10 @@ static Framebuffer *initWithDevice(Framebuffer *self, RenderDevice *device, cons
117117
self->numColorTargets = info->numColorTargets;
118118
for (Uint32 i = 0; i < info->numColorTargets; i++) {
119119
self->colorFormats[i] = info->colorFormats[i];
120+
self->clearColors[i] = info->clearColors[i];
120121
}
121122
self->depthFormat = info->depthFormat;
123+
self->clearDepth = info->clearDepth;
122124
self->sampleCount = info->sampleCount;
123125

124126
$(self, resize, &info->size);

Sources/ObjectivelyGPU/Framebuffer.h

Lines changed: 36 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,23 @@ typedef struct GPU_FramebufferCreateInfo {
8787
*/
8888
SDL_GPUSampleCount sampleCount;
8989

90+
/**
91+
* @brief The clear color for each color attachment, indices `[0, numColorTargets)`.
92+
* @details Stashed on the Framebuffer and used as the default `clearColor` by
93+
* `colorTargetInfo` (when passed `NULL`) and by
94+
* `CommandBuffer::beginRenderPassWithFramebuffer`. Omitted entries default to
95+
* opaque black.
96+
*/
97+
SDL_FColor clearColors[GPU_MAX_COLOR_TARGETS];
98+
99+
/**
100+
* @brief The clear depth value for the depth attachment, if any.
101+
* @details Stashed on the Framebuffer and used by
102+
* `CommandBuffer::beginRenderPassWithFramebuffer`. Typically `1.f` (the far plane);
103+
* omitted defaults to `0.f`.
104+
*/
105+
float clearDepth;
106+
90107
} GPU_FramebufferCreateInfo;
91108

92109
/**
@@ -105,18 +122,15 @@ typedef struct GPU_FramebufferCreateInfo {
105122
* .size = { 1920, 1080 },
106123
* .colorFormats = { SDL_GPU_TEXTUREFORMAT_R16G16B16A16_FLOAT },
107124
* .numColorTargets = 1,
125+
* .clearColors = { { 0.f, 0.f, 0.f, 1.f } },
108126
* .depthFormat = SDL_GPU_TEXTUREFORMAT_D32_FLOAT,
127+
* .clearDepth = 1.f,
109128
* .sampleCount = SDL_GPU_SAMPLECOUNT_1,
110129
* });
111130
*
112-
* SDL_GPUColorTargetInfo color = $(fb, colorTargetInfo, 0,
113-
* SDL_GPU_LOADOP_CLEAR, SDL_GPU_STOREOP_STORE,
114-
* &(SDL_FColor) { 0, 0, 0, 1 });
115-
*
116-
* SDL_GPUDepthStencilTargetInfo depth = $(fb, depthTargetInfo,
117-
* SDL_GPU_LOADOP_CLEAR, SDL_GPU_STOREOP_DONT_CARE, 1.f);
118-
*
119-
* RenderPass *pass = $(commands, beginRenderPass, &color, 1, &depth);
131+
* // Renders into all of fb's targets, clearing to its own clearColors/clearDepth.
132+
* RenderPass *pass = $(commands, beginRenderPassWithFramebuffer, fb,
133+
* SDL_GPU_LOADOP_CLEAR, SDL_GPU_STOREOP_STORE);
120134
* // ...
121135
* release(pass);
122136
* release(fb);
@@ -180,6 +194,19 @@ struct Framebuffer {
180194
*/
181195
SDL_GPUTextureFormat depthFormat;
182196

197+
/**
198+
* @brief The clear color for each color attachment, indices `[0, numColorTargets)`.
199+
* @details Used as the default `clearColor` by `colorTargetInfo` (when passed `NULL`)
200+
* and by `CommandBuffer::beginRenderPassWithFramebuffer`.
201+
*/
202+
SDL_FColor clearColors[GPU_MAX_COLOR_TARGETS];
203+
204+
/**
205+
* @brief The clear depth value for the depth attachment, if any.
206+
* @details Used by `CommandBuffer::beginRenderPassWithFramebuffer`.
207+
*/
208+
float clearDepth;
209+
183210
/**
184211
* @brief The depth attachment texture, or `NULL` if `depthFormat` is invalid.
185212
* @details Single-sample depth also carries `SAMPLER` and is returned directly by
@@ -230,7 +257,7 @@ struct FramebufferInterface {
230257
* @param index The color attachment index, in `[0, numColorTargets)`.
231258
* @param loadOp Load operation at the start of the pass.
232259
* @param storeOp Store operation at the end of the pass.
233-
* @param clearColor Clear color used when `loadOp` is `SDL_GPU_LOADOP_CLEAR`, or NULL for black.
260+
* @param clearColor Clear color used when `loadOp` is `SDL_GPU_LOADOP_CLEAR`, or NULL to use the framebuffer's own `clearColors[index]`.
234261
* @return A stack-allocated `SDL_GPUColorTargetInfo`.
235262
* @memberof Framebuffer
236263
*/

0 commit comments

Comments
 (0)