From 261d33c72095a2abd98177f88ebb24fe205a042f Mon Sep 17 00:00:00 2001 From: onelin Date: Wed, 17 Dec 2025 13:48:22 +0100 Subject: Rework buffer parameters --- src/include/daw/rendering.h | 80 ++++++++++++++++++++++---------------------- src/rendering.c | 81 +++++++++++++++++++++++---------------------- 2 files changed, 82 insertions(+), 79 deletions(-) diff --git a/src/include/daw/rendering.h b/src/include/daw/rendering.h index 42881a7..530a8e0 100644 --- a/src/include/daw/rendering.h +++ b/src/include/daw/rendering.h @@ -199,46 +199,59 @@ typedef struct { } RenderDrawCall; typedef enum { - BufferType_frame = 1, - BufferType_texture = 2, - BufferType_render = 3, - BufferType_buffer = 4, + BufferType_frame = 0, + BufferType_texture = 1, + BufferType_render = 2, + BufferType_buffer = 3, } BufferType; +// Gives a mask of N bits, used in shifting +#define MASK(N) ((1 << N) - 1) + /* Buffer set/get macros */ -// `buffer_definition` has the first 4 bits for the type, -#define BUFFERPARAMETER_MASK_TYPE ((1 << 4) - 1) -// next 16 bits for the type-specific parameters -#define BUFFERPARAMETER_MASK_PARAMETER (((1 << 16) - 1) << 4) +// `buffer_definition` uses the first 2 bits for the type, +#define BUFFERPARAMETER_MASK_TYPE MASK(2) +// next 14 bits for the type-specific parameters, offset by type mask-size +#define BUFFERPARAMETER_MASK_PARAMETER (MASK(14) << 2) #define BUFFERPARAMETER_GET_TYPE(bufferparam) \ (BufferType)(bufferparam & BUFFERPARAMETER_MASK_TYPE) #define BUFFERPARAMETER_GET_PARAMETER(bufferparam) \ - ((bufferparam & BUFFERPARAMETER_MASK_PARAMETER) >> 4) + ((bufferparam & BUFFERPARAMETER_MASK_PARAMETER) >> 2) // SET operations clear the masked bits that you're setting. Set multiple parameters by // OR'ing them. #define BUFFERPARAMETER_SET_TYPE(bufferparam, type) \ (BufferType)((bufferparam & ~BUFFERPARAMETER_MASK_TYPE) | type) #define BUFFERPARAMETER_SET_PARAMETER(bufferparam, param) \ - ((bufferparam & ~BUFFERPARAMETER_MASK_PARAMETER) | ((param) << 4)) + ((bufferparam & ~BUFFERPARAMETER_MASK_PARAMETER) | ((param) << 2)) + +// Textures and RenderBuffers can have different formats internally. Some of +// the available formats are available to both, some internal formats are only +// available to either. -// Textures and RenderBuffers can have different formats internally. These are -// mutually exclusive and shared between texture and renderbuffer buffers. +// The "color" formats are stored in the first 10 bits of the PARAMETER, the depth & stencil +// formats are stored in the following 3 bits. +// The last bit is currently unused. //TODO: More formats -#define BUFFERPARAMETER_FMT_RGBA8 ( 1 << 8) -#define BUFFERPARAMETER_FMT_RGB8 ( 2 << 8) -#define BUFFERPARAMETER_FMT_SRGB8 ( 3 << 8) -#define BUFFERPARAMETER_FMT_SRGBA8 ( 4 << 8) - -#define BUFFERPARAMETER_FMT_DEPTH24_STENCIL8 ( 5 << 8) -#define BUFFERPARAMETER_FMT_DEPTH16 ( 6 << 8) -#define BUFFERPARAMETER_FMT_DEPTH24 ( 7 << 8) -#define BUFFERPARAMETER_FMT_DEPTH32 ( 8 << 8) -#define BUFFERPARAMETER_FMT_DEPTH32F ( 9 << 8) -#define BUFFERPARAMETER_FMT_STENCIL8 (10 << 8) +#define BUFFERPARAMETER_FMT_COLOR_MASK MASK(10) + +#define BUFFERPARAMETER_FMT_RGBA8 (1) +#define BUFFERPARAMETER_FMT_RGB8 (2) +#define BUFFERPARAMETER_FMT_SRGB8 (3) +#define BUFFERPARAMETER_FMT_SRGBA8 (4) + +// Depth & stencil format(s) +#define BUFFERPARAMETER_FMT_DEPTH_STENCIL_MASK (MASK(3) << 10) + +#define BUFFERPARAMETER_FMT_DEPTH24_STENCIL8 (1 << 10) +#define BUFFERPARAMETER_FMT_DEPTH16 (2 << 10) +#define BUFFERPARAMETER_FMT_DEPTH24 (3 << 10) +#define BUFFERPARAMETER_FMT_DEPTH32 (4 << 10) +#define BUFFERPARAMETER_FMT_DEPTH32F (5 << 10) +#define BUFFERPARAMETER_FMT_STENCIL8 (6 << 10) // "Easy default" values #define BUFFERPARAMETER_FMT_DEPTH_STENCIL BUFFERPARAMETER_FMT_DEPTH24_STENCIL8 @@ -249,26 +262,15 @@ typedef enum { // identical, and we differentiate between them anyways wrt. dimensions, depth, // stencil, and depth+stencil. -// Buffer parameter: Frame buffer -// Buffer parameter: Texture buffer -#define BUFFERPARAMETER_TEXTURE_GET_DIMENSION(bufferparam) (BUFFERPARAMETER_GET_PARAMETER(bufferparam) & ((1 << 4) - 1)) -#define BUFFERPARAMETER_TEXTURE_1D 1 -#define BUFFERPARAMETER_TEXTURE_2D 2 -#define BUFFERPARAMETER_TEXTURE_3D 3 -#define BUFFERPARAMETER_TEXTURE_4D 4 // TODO: Change `2` once we add support for more formats -#define BUFFERPARAMETER_TEXTURE_GET_FORMAT(bufferparam) (BUFFERPARAMETER_GET_PARAMETER(bufferparam) & (((1 << 8) - 1) << 4)) +#define BUFFERPARAMETER_FMT_GET(bufferparam) (BUFFERPARAMETER_GET_PARAMETER(bufferparam) & (((1 << 8) - 1) << 2)) -// Buffer parameter: Buffer buffer -// A buffer can be either a depth and/or stencil buffer. Custom buffers could be -// implemented for this at some point. -// It is important that the types here are bitwise non-overlapping. -#define BUFFERPARAMETER_RENDERBUFFER_GET_TYPE(bufferparam) (BUFFERPARAMETER_GET_PARAMETER(bufferparam) & ((1 << 4) - 1)) -#define BUFFERPARAMETER_RENDERBUFFER_DEPTH 1 -#define BUFFERPARAMETER_RENDERBUFFER_STENCIL 2 +#define BUFFERPARAMETER_FMT_IS_COLOR(bufferparam) \ + ((BUFFERPARAMETER_GET_PARAMETER(bufferparam) & BUFFERPARAMETER_FMT_COLOR_MASK) != 0) -#define BUFFERPARAMETER_RENDERBUFFER_GET_FORMAT(bufferparam) (BUFFERPARAMETER_GET_PARAMETER(bufferparam) & (((1 << 8) - 1)) << 4) +#define BUFFERPARAMETER_FMT_IS_DEPTH_OR_STENCIL(bufferparam) \ + ((BUFFERPARAMETER_GET_PARAMETER(bufferparam) & BUFFERPARAMETER_FMT_DEPTH_STENCIL_MASK) != 0) typedef struct { i32 num_attached_buffers; diff --git a/src/rendering.c b/src/rendering.c index 02be7d1..0643c70 100644 --- a/src/rendering.c +++ b/src/rendering.c @@ -746,43 +746,44 @@ void r_create_textures(void* restrict ctx, u32* restrict texture_array, ivec3* restrict texture_size, usize num_targets) { const GladGLContext* gl = (GladGLContext*)ctx; - u32 texture_dim = BUFFERPARAMETER_TEXTURE_GET_DIMENSION(texture_parameters[0]); - u32 err; + i8 texture_dim = 2; + u32 err = 0; + ivec3 texture_sz; + ASSERT(texture_size != NULL); + glm_ivec3_copy(*texture_size, texture_sz); - for (usize i = 1; i < num_targets; i++) { - ASSERT(texture_dim == BUFFERPARAMETER_TEXTURE_GET_DIMENSION(texture_parameters[i])); + while (texture_dim > 0 && texture_sz[texture_dim] == 0) { + texture_dim--; } - // Convert the texturetype to GL texturetype + // Check that if texture_dim == 0 then texture_sz[0] > 0. + ASSERT(texture_sz[texture_dim] > 0); + switch (texture_dim) { - case BUFFERPARAMETER_TEXTURE_1D: + case 0: gl->CreateTextures(GL_TEXTURE_1D, num_targets, texture_array); ASSERT(!gl->GetError()); for (usize i = 0; i < num_targets; i++) { - gl->TextureStorage1D(texture_array[i], 1, gl_texture_format(BUFFERPARAMETER_TEXTURE_GET_FORMAT(texture_parameters[i])), (*texture_size)[0]); + gl->TextureStorage1D(texture_array[i], 1, gl_texture_format(BUFFERPARAMETER_FMT_GET(texture_parameters[i])), texture_sz[0]); } break; - case BUFFERPARAMETER_TEXTURE_2D: + case 1: gl->CreateTextures(GL_TEXTURE_2D, num_targets, texture_array); ASSERT(!gl->GetError()); for (usize i = 0; i < num_targets; i++) { - gl->TextureStorage2D(texture_array[i], 1, gl_texture_format(BUFFERPARAMETER_TEXTURE_GET_FORMAT(texture_parameters[i])), (*texture_size)[0], (*texture_size)[1]); + gl->TextureStorage2D(texture_array[i], 1, gl_texture_format(BUFFERPARAMETER_FMT_GET(texture_parameters[i])), texture_sz[0], texture_sz[1]); } break; - case BUFFERPARAMETER_TEXTURE_3D: + case 2: gl->CreateTextures(GL_TEXTURE_3D, num_targets, texture_array); ASSERT(!gl->GetError()); for (usize i = 0; i < num_targets; i++) { - gl->TextureStorage3D(texture_array[i], 1, gl_texture_format(BUFFERPARAMETER_TEXTURE_GET_FORMAT(texture_parameters[i])), (*texture_size)[0], (*texture_size)[1], (*texture_size)[2]); + gl->TextureStorage3D(texture_array[i], 1, gl_texture_format(BUFFERPARAMETER_FMT_GET(texture_parameters[i])), texture_sz[0], texture_sz[1], texture_sz[2]); } break; - case BUFFERPARAMETER_TEXTURE_4D: - ERROR("4D textures are unsupported!"); - exit(EXIT_FAILURE); - default: ERROR("Failed to convert dimensionality to GL_TEXTURE_XD"); exit(EXIT_FAILURE); @@ -833,7 +834,7 @@ void r_create_renderbuffers(void *restrict ctx, u32* restrict buffer_array, u32* for (usize i = 0; i < num_buffers; i++) { gl->NamedRenderbufferStorage( buffer_array[i], - gl_texture_format(BUFFERPARAMETER_RENDERBUFFER_GET_FORMAT(buffer_types[i])), + gl_texture_format(BUFFERPARAMETER_FMT_GET(buffer_types[i])), buffer_sizes[i][0], buffer_sizes[i][1] ); @@ -845,18 +846,24 @@ void r_destroy_renderbuffers(void *restrict ctx, u32* buffers, usize num_buffers ((GladGLContext *restrict)ctx)->DeleteRenderbuffers(num_buffers, buffers); } -static u32 gl_renderbuffer_type(u32 buffer_param) { - switch (BUFFERPARAMETER_RENDERBUFFER_GET_TYPE(buffer_param)) { - case BUFFERPARAMETER_RENDERBUFFER_DEPTH: +static u32 gl_format_attachment(u32 format) { + if ((format & BUFFERPARAMETER_FMT_COLOR_MASK) != 0) { + return GL_COLOR_ATTACHMENT0; + } + switch (format) { + case BUFFERPARAMETER_FMT_DEPTH24_STENCIL8: + return GL_DEPTH_STENCIL_ATTACHMENT; + case BUFFERPARAMETER_FMT_DEPTH16: + case BUFFERPARAMETER_FMT_DEPTH24: + case BUFFERPARAMETER_FMT_DEPTH32: + case BUFFERPARAMETER_FMT_DEPTH32F: return GL_DEPTH_ATTACHMENT; - case BUFFERPARAMETER_RENDERBUFFER_STENCIL: + case BUFFERPARAMETER_FMT_STENCIL8: return GL_STENCIL_ATTACHMENT; - case (BUFFERPARAMETER_RENDERBUFFER_DEPTH | BUFFERPARAMETER_RENDERBUFFER_STENCIL): - return GL_DEPTH_STENCIL_ATTACHMENT; default: UNIMPLEMENTED; + return 0; } - return -1; } void r_attach_buffers(void *restrict ctx, u32 fbo, u32* buffers, u32* buffer_parameters, i32 num_buffers) { @@ -866,31 +873,25 @@ void r_attach_buffers(void *restrict ctx, u32 fbo, u32* buffers, u32* buffer_par u32 err; + u32 color_ofst = 0; for (i32 i = 0; i < num_buffers; i++) { + u32 attachment = gl_format_attachment(BUFFERPARAMETER_GET_PARAMETER(buffer_parameters[i])); + ASSERT(attachment != 0); + switch (BUFFERPARAMETER_GET_TYPE(buffer_parameters[i])) { case BufferType_frame: UNIMPLEMENTED; case BufferType_texture: - switch (BUFFERPARAMETER_TEXTURE_GET_FORMAT(buffer_parameters[i])) { - case BUFFERPARAMETER_FMT_DEPTH24_STENCIL8: - gl->NamedFramebufferTexture(fbo, GL_DEPTH_STENCIL_ATTACHMENT, buffers[i], 0); - break; - case BUFFERPARAMETER_FMT_DEPTH16: - case BUFFERPARAMETER_FMT_DEPTH24: - case BUFFERPARAMETER_FMT_DEPTH32: - case BUFFERPARAMETER_FMT_DEPTH32F: - gl->NamedFramebufferTexture(fbo, GL_DEPTH_ATTACHMENT, buffers[i], 0); - break; - case BUFFERPARAMETER_FMT_STENCIL8: - gl->NamedFramebufferTexture(fbo, GL_STENCIL_ATTACHMENT, buffers[i], 0); - break; - default: - gl->NamedFramebufferTexture(fbo, GL_COLOR_ATTACHMENT0 + i, buffers[i], 0); - break; + if (attachment == GL_COLOR_ATTACHMENT0) { + gl->NamedFramebufferTexture(fbo, GL_COLOR_ATTACHMENT0 + color_ofst, buffers[i], 0); + color_ofst++; + } else { + gl->NamedFramebufferTexture(fbo, attachment, buffers[i], 0); } + break; case BufferType_render: - gl->NamedFramebufferRenderbuffer(fbo, gl_renderbuffer_type(buffer_parameters[i]), GL_RENDERBUFFER, buffers[i]); + gl->NamedFramebufferRenderbuffer(fbo, attachment, GL_RENDERBUFFER, buffers[i]); break; case BufferType_buffer: UNIMPLEMENTED; -- cgit v1.3