From a2f9f581436db289fc1ca4dc5416d6f787d01ed4 Mon Sep 17 00:00:00 2001 From: jacob Date: Mon, 20 Jan 2025 12:03:09 -0600 Subject: [PATCH] retrieve texture size dynamically --- src/common.h | 6 ++++ src/draw.c | 2 +- src/font.c | 2 +- src/math.h | 14 ++++++++ src/renderer.h | 5 +-- src/renderer_d3d11.c | 26 +++++++++----- src/sprite.c | 4 +-- src/user.c | 80 ++++++++++++++++++++------------------------ 8 files changed, 82 insertions(+), 57 deletions(-) diff --git a/src/common.h b/src/common.h index 78fa6b8b..14f0636a 100644 --- a/src/common.h +++ b/src/common.h @@ -543,6 +543,7 @@ struct sprite_tag { * ========================== */ #define V2(x, y) ((struct v2) { (x), (y) }) +#define V2_FROM_V2I32(v) V2((v).x, (v).y) struct v2 { f32 x, y; }; @@ -572,6 +573,11 @@ struct v4_array { u64 count; }; +#define V2I32(x, y) ((struct v2i32) { (x), (y) }) +struct v2i32 { + i32 x, y; +}; + struct xform { struct v2 bx; /* X basis vector (x axis) */ struct v2 by; /* Y basis vector (y axis)*/ diff --git a/src/draw.c b/src/draw.c index 3de47fbb..8aae2f9f 100644 --- a/src/draw.c +++ b/src/draw.c @@ -20,7 +20,7 @@ struct draw_startup_receipt draw_startup(struct renderer_startup_receipt *render (UNUSED)renderer_sr; (UNUSED)font_sr; u32 pixel_white = 0xFFFFFFFF; - G.solid_white = renderer_texture_alloc(RENDERER_TEXTURE_FORMAT_R8G8B8A8_UNORM, 0, 1, 1, &pixel_white); + G.solid_white = renderer_texture_alloc(RENDERER_TEXTURE_FORMAT_R8G8B8A8_UNORM, 0, V2I32(1, 1), &pixel_white); return (struct draw_startup_receipt) { 0 }; } diff --git a/src/font.c b/src/font.c index d7bbc80c..f8dc5a03 100644 --- a/src/font.c +++ b/src/font.c @@ -120,7 +120,7 @@ INTERNAL WORK_TASK_FUNC_DEF(font_load_asset_task, vparams) resource_close(res); /* Send texture to GPU */ - struct renderer_texture texture = renderer_texture_alloc(RENDERER_TEXTURE_FORMAT_R8G8B8A8_UNORM, 0, result.image_data.width, result.image_data.height, result.image_data.pixels); + struct renderer_texture texture = renderer_texture_alloc(RENDERER_TEXTURE_FORMAT_R8G8B8A8_UNORM, 0, V2I32(result.image_data.width, result.image_data.height), result.image_data.pixels); /* Allocate store memory */ struct font *font = NULL; diff --git a/src/math.h b/src/math.h index 546cd3a7..4108dbaf 100644 --- a/src/math.h +++ b/src/math.h @@ -725,6 +725,11 @@ INLINE struct v2 v2_round(struct v2 a) return V2(math_round(a.x), math_round(a.y)); } +INLINE struct v2i32 v2_round_to_int(struct v2 a) +{ + return V2I32(math_round_to_int(a.x), math_round_to_int(a.y)); +} + INLINE struct v2 v2_floor(struct v2 a) { return V2(math_floor(a.x), math_floor(a.y)); @@ -801,6 +806,15 @@ INLINE struct v2 v2_slerp(struct v2 val0, struct v2 val1, f32 t) return v2_mul(v2_from_angle(rot), len); } +/* ========================== * + * V2I32 + * ========================== */ + +INLINE b32 v2i32_eq(struct v2i32 a, struct v2i32 b) +{ + return a.x == b.x && a.y == b.y; +} + /* ========================== * * Mat4x4 * ========================== */ diff --git a/src/renderer.h b/src/renderer.h index e8719f40..852cbebd 100644 --- a/src/renderer.h +++ b/src/renderer.h @@ -73,11 +73,12 @@ enum renderer_texture_format { #define RENDERER_TEXTURE_FLAG_NONE (0) #define RENDERER_TEXTURE_FLAG_TARGET (1<<0) -struct renderer_texture renderer_texture_alloc(enum renderer_texture_format format, u32 flags, u32 width, u32 height, void *initial_data); +struct renderer_texture renderer_texture_alloc(enum renderer_texture_format format, u32 flags, struct v2i32 size, void *initial_data); void renderer_texture_release(struct renderer_texture t); void renderer_texture_clear(struct renderer_texture target_texture, u32 clear_color); void renderer_texture_render(struct renderer_texture texture, struct renderer_cmd_buffer *cmdbuff, struct xform view, struct rect viewport, struct sprite_scope *sprite_scope); +struct v2i32 renderer_texture_get_size(struct renderer_texture texture); /* ========================== * * Backbuffer @@ -86,7 +87,7 @@ void renderer_texture_render(struct renderer_texture texture, struct renderer_cm /* Returns a texture linking to the internal backbuffer. Lifetime is managed by renderer. */ struct renderer_texture renderer_get_backbuffer_texture(void); -void renderer_backbuffer_resize(u32 width, u32 height); +void renderer_backbuffer_resize(struct v2i32 size); void renderer_backbuffer_present(i32 vsync); diff --git a/src/renderer_d3d11.c b/src/renderer_d3d11.c index b1c4ca23..d0ca1eee 100644 --- a/src/renderer_d3d11.c +++ b/src/renderer_d3d11.c @@ -668,7 +668,7 @@ INTERNAL struct dx11_format dx11_format_from_renderer_format(enum renderer_textu return res; } -INTERNAL struct dx11_texture *dx11_texture_alloc(enum renderer_texture_format format, u32 flags, u32 width, u32 height, void *initial_data) +INTERNAL struct dx11_texture *dx11_texture_alloc(enum renderer_texture_format format, u32 flags, struct v2i32 size, void *initial_data) { struct dx11_texture *t = NULL; { @@ -703,8 +703,8 @@ INTERNAL struct dx11_texture *dx11_texture_alloc(enum renderer_texture_format fo } D3D11_TEXTURE2D_DESC desc = ZI; - desc.Width = width; - desc.Height = height; + desc.Width = size.x; + desc.Height = size.y; desc.MipLevels = 1; desc.ArraySize = 1; desc.SampleDesc.Count = 1; @@ -715,7 +715,7 @@ INTERNAL struct dx11_texture *dx11_texture_alloc(enum renderer_texture_format fo ID3D11Texture2D *texture = NULL; if (initial_data) { - D3D11_SUBRESOURCE_DATA subresource_data = { .pSysMem = initial_data, .SysMemPitch = width * dx11_format.pixel_size, .SysMemSlicePitch = 0 }; + D3D11_SUBRESOURCE_DATA subresource_data = { .pSysMem = initial_data, .SysMemPitch = size.x * dx11_format.pixel_size, .SysMemSlicePitch = 0 }; ID3D11Device_CreateTexture2D(G.dev, &desc, &subresource_data, &texture); } else { ID3D11Device_CreateTexture2D(G.dev, &desc, NULL, &texture); @@ -756,11 +756,11 @@ INTERNAL void dx11_texture_release(struct dx11_texture *t) } } -struct renderer_texture renderer_texture_alloc(enum renderer_texture_format format, u32 flags, u32 width, u32 height, void *initial_data) +struct renderer_texture renderer_texture_alloc(enum renderer_texture_format format, u32 flags, struct v2i32 size, void *initial_data) { __prof; struct renderer_texture res = ZI; - struct dx11_texture *t = dx11_texture_alloc(format, flags, width, height, initial_data); + struct dx11_texture *t = dx11_texture_alloc(format, flags, size, initial_data); res.handle = (u64)t; return res; } @@ -810,6 +810,16 @@ void renderer_texture_render(struct renderer_texture texture, struct renderer_cm } } +struct v2i32 renderer_texture_get_size(struct renderer_texture texture) +{ + struct v2i32 res = ZI; + D3D11_TEXTURE2D_DESC desc; + ID3D11Texture2D_GetDesc(((struct dx11_texture *)texture.handle)->texture, &desc); + res.x = desc.Width; + res.y = desc.Height; + return res; +} + /* ========================== * * Backbuffer * ========================== */ @@ -821,11 +831,11 @@ struct renderer_texture renderer_get_backbuffer_texture(void) return res; } -void renderer_backbuffer_resize(u32 width, u32 height) +void renderer_backbuffer_resize(struct v2i32 size) { __prof; ID3D11Texture2D_Release(G.backbuffer_texture.texture); - IDXGISwapChain_ResizeBuffers(G.swapchain, 0, width, height, DXGI_FORMAT_UNKNOWN, 0); + IDXGISwapChain_ResizeBuffers(G.swapchain, 0, size.x, size.y, DXGI_FORMAT_UNKNOWN, 0); IDXGISwapChain_GetBuffer(G.swapchain, 0, &IID_ID3D11Texture2D, (LPVOID *)&G.backbuffer_texture.texture); } diff --git a/src/sprite.c b/src/sprite.c index 4419db44..ff116105 100644 --- a/src/sprite.c +++ b/src/sprite.c @@ -229,7 +229,7 @@ struct sprite_startup_receipt sprite_startup(struct renderer_startup_receipt *re { struct temp_arena scratch = scratch_begin_no_conflict(); struct image_rgba purple_black_image = generate_purple_black_image(scratch.arena, 64, 64); - G.nil_texture->texture = renderer_texture_alloc(RENDERER_TEXTURE_FORMAT_R8G8B8A8_UNORM, 0, purple_black_image.width, purple_black_image.height, purple_black_image.pixels); + G.nil_texture->texture = renderer_texture_alloc(RENDERER_TEXTURE_FORMAT_R8G8B8A8_UNORM, 0, V2I32(purple_black_image.width, purple_black_image.height), purple_black_image.pixels); scratch_end(scratch); } @@ -365,7 +365,7 @@ INTERNAL void cache_node_load_texture(struct cache_node *n, struct sprite_tag ta n->texture = arena_push(&n->arena, struct sprite_texture); n->texture->width = decoded.image.width; n->texture->height = decoded.image.height; - n->texture->texture = renderer_texture_alloc(RENDERER_TEXTURE_FORMAT_R8G8B8A8_UNORM, 0, decoded.image.width, decoded.image.height, decoded.image.pixels); + n->texture->texture = renderer_texture_alloc(RENDERER_TEXTURE_FORMAT_R8G8B8A8_UNORM, 0, V2I32(decoded.image.width, decoded.image.height), decoded.image.pixels); n->texture->valid = true; n->texture->loaded = true; /* TODO: Query renderer for more accurate texture size in VRAM */ diff --git a/src/user.c b/src/user.c index 44b33d50..37d5b59e 100644 --- a/src/user.c +++ b/src/user.c @@ -42,19 +42,16 @@ GLOBAL struct { struct sys_window *window; /* Render targets */ - struct renderer_texture final_rt; - struct renderer_texture world_rt; - struct renderer_texture ui_rt; - struct renderer_texture backbuffer_rt; - - struct v2 ui_rt_resolution; - struct v2 world_rt_resolution; - struct v2 backbuffer_rt_resolution; + struct renderer_texture final_texture; + struct renderer_texture world_texture; + struct renderer_texture ui_texture; + struct renderer_texture backbuffer_texture; struct renderer_cmd_buffer *world_cmd_buffer; struct renderer_cmd_buffer *ui_cmd_buffer; struct renderer_cmd_buffer *final_cmd_buffer; struct renderer_cmd_buffer *backbuffer_cmd_buffer; + struct xform world_to_ui_xf; struct blend_tick *head_free_blend_tick; @@ -1605,60 +1602,57 @@ INTERNAL void user_update(void) struct rect backbuffer_viewport = RECT_FROM_V2(V2(0, 0), G.screen_size); /* Allocate rt textures */ - struct v2 backbuffer_rt_resolution = G.screen_size; - struct v2 ui_rt_resolution = G.ui_size; - struct v2 world_rt_resolution = V2(target_viewport.width + target_viewport.x, target_viewport.height + target_viewport.y); + struct v2i32 ui_rt_resolution = v2_round_to_int(V2(target_viewport.width + target_viewport.x, target_viewport.height + target_viewport.y)); + struct v2i32 world_rt_resolution = ui_rt_resolution; + struct v2i32 backbuffer_rt_resolution = v2_round_to_int(G.screen_size); { /* World rt */ - if (!G.world_rt.handle || !v2_eq(G.world_rt_resolution, world_rt_resolution)) { - if (G.world_rt.handle) { - renderer_texture_release(G.world_rt); + if (!G.world_texture.handle || !v2i32_eq(renderer_texture_get_size(G.world_texture), world_rt_resolution)) { + if (G.world_texture.handle) { + renderer_texture_release(G.world_texture); } - G.world_rt = renderer_texture_alloc(RENDERER_TEXTURE_FORMAT_R8G8B8A8_UNORM, RENDERER_TEXTURE_FLAG_TARGET, math_round_to_int(world_rt_resolution.x), math_round_to_int(world_rt_resolution.y), NULL); + G.world_texture = renderer_texture_alloc(RENDERER_TEXTURE_FORMAT_R8G8B8A8_UNORM, RENDERER_TEXTURE_FLAG_TARGET, world_rt_resolution, NULL); } /* Ui rt */ - if (!G.ui_rt.handle || !v2_eq(G.ui_rt_resolution, ui_rt_resolution)) { - if (G.ui_rt.handle) { - renderer_texture_release(G.ui_rt); + if (!G.ui_texture.handle || !v2i32_eq(renderer_texture_get_size(G.ui_texture), ui_rt_resolution)) { + if (G.ui_texture.handle) { + renderer_texture_release(G.ui_texture); } - G.ui_rt = renderer_texture_alloc(RENDERER_TEXTURE_FORMAT_R8G8B8A8_UNORM, RENDERER_TEXTURE_FLAG_TARGET, math_round_to_int(ui_rt_resolution.x), math_round_to_int(ui_rt_resolution.y), NULL); + G.ui_texture = renderer_texture_alloc(RENDERER_TEXTURE_FORMAT_R8G8B8A8_UNORM, RENDERER_TEXTURE_FLAG_TARGET, ui_rt_resolution, NULL); } /* Final rt */ - if (!G.final_rt.handle || !v2_eq(G.ui_rt_resolution, ui_rt_resolution)) { - if (G.final_rt.handle) { - renderer_texture_release(G.final_rt); + if (!G.final_texture.handle || !v2i32_eq(renderer_texture_get_size(G.final_texture), ui_rt_resolution)) { + if (G.final_texture.handle) { + renderer_texture_release(G.final_texture); } - G.final_rt = renderer_texture_alloc(RENDERER_TEXTURE_FORMAT_R8G8B8A8_UNORM, RENDERER_TEXTURE_FLAG_TARGET, math_round_to_int(ui_rt_resolution.x), math_round_to_int(ui_rt_resolution.y), NULL); + G.final_texture = renderer_texture_alloc(RENDERER_TEXTURE_FORMAT_R8G8B8A8_UNORM, RENDERER_TEXTURE_FLAG_TARGET, ui_rt_resolution, NULL); } /* Backbuffer rt */ - if (!G.backbuffer_rt.handle || !v2_eq(G.backbuffer_rt_resolution, backbuffer_rt_resolution)) { - renderer_backbuffer_resize(math_round_to_int(backbuffer_rt_resolution.x), math_round_to_int(backbuffer_rt_resolution.y)); - G.backbuffer_rt = renderer_get_backbuffer_texture(); + if (!G.backbuffer_texture.handle || !v2i32_eq(renderer_texture_get_size(G.backbuffer_texture), backbuffer_rt_resolution)) { + renderer_backbuffer_resize(backbuffer_rt_resolution); + G.backbuffer_texture = renderer_get_backbuffer_texture(); } - G.backbuffer_rt_resolution = backbuffer_rt_resolution; - G.ui_rt_resolution = ui_rt_resolution; - G.world_rt_resolution = world_rt_resolution; } { /* Draw world texture to final */ { - struct draw_texture_params params = DRAW_TEXTURE_PARAMS(.texture = G.world_rt); - struct quad quad = quad_from_rect(RECT_FROM_V2(V2(0, 0), ui_rt_resolution)); + struct draw_texture_params params = DRAW_TEXTURE_PARAMS(.texture = G.world_texture); + struct quad quad = quad_from_rect(RECT_FROM_V2(V2(0, 0), V2_FROM_V2I32(ui_rt_resolution))); draw_quad_texture(G.final_cmd_buffer, params, quad); } /* Draw ui texture to final */ { - struct draw_texture_params params = DRAW_TEXTURE_PARAMS(.texture = G.ui_rt); - struct quad quad = quad_from_rect(RECT_FROM_V2(V2(0, 0), ui_rt_resolution)); + struct draw_texture_params params = DRAW_TEXTURE_PARAMS(.texture = G.ui_texture); + struct quad quad = quad_from_rect(RECT_FROM_V2(V2(0, 0), V2_FROM_V2I32(ui_rt_resolution))); draw_quad_texture(G.final_cmd_buffer, params, quad); } /* Draw final texture to backbuffer */ { - struct draw_texture_params params = DRAW_TEXTURE_PARAMS(.texture = G.final_rt); - struct quad quad = quad_from_rect(RECT_FROM_V2(G.ui_screen_offset, G.ui_size)); + struct draw_texture_params params = DRAW_TEXTURE_PARAMS(.texture = G.final_texture); + struct quad quad = quad_from_rect(RECT_FROM_V2(G.ui_screen_offset, V2_FROM_V2I32(G.ui_size))); draw_quad_texture(G.backbuffer_cmd_buffer, params, quad); } } @@ -1672,22 +1666,22 @@ INTERNAL void user_update(void) /* Execute render cmds */ { /* Clear textures */ - renderer_texture_clear(G.world_rt, RGBA_32_F(0.2f, 0.2f, 0.2f, 1.f)); - renderer_texture_clear(G.ui_rt, RGBA_32_F(0, 0, 0, 0)); - renderer_texture_clear(G.final_rt, RGBA_32_F(0, 0, 0, 0)); - renderer_texture_clear(G.backbuffer_rt, RGBA_32_F(0, 0, 0, 1)); + renderer_texture_clear(G.world_texture, RGBA_32_F(0.2f, 0.2f, 0.2f, 1.f)); + renderer_texture_clear(G.ui_texture, RGBA_32_F(0, 0, 0, 0)); + renderer_texture_clear(G.final_texture, RGBA_32_F(0, 0, 0, 0)); + renderer_texture_clear(G.backbuffer_texture, RGBA_32_F(0, 0, 0, 1)); /* Render to world texture */ - renderer_texture_render(G.world_rt, G.world_cmd_buffer, G.world_to_ui_xf, target_viewport, sprite_frame_scope); + renderer_texture_render(G.world_texture, G.world_cmd_buffer, G.world_to_ui_xf, target_viewport, sprite_frame_scope); /* Render to UI texture */ - renderer_texture_render(G.ui_rt, G.ui_cmd_buffer, XFORM_IDENT, target_viewport, sprite_frame_scope); + renderer_texture_render(G.ui_texture, G.ui_cmd_buffer, XFORM_IDENT, target_viewport, sprite_frame_scope); /* Render to final texture */ - renderer_texture_render(G.final_rt, G.final_cmd_buffer, XFORM_IDENT, target_viewport, sprite_frame_scope); + renderer_texture_render(G.final_texture, G.final_cmd_buffer, XFORM_IDENT, target_viewport, sprite_frame_scope); /* Render to backbuffer */ - renderer_texture_render(G.backbuffer_rt, G.backbuffer_cmd_buffer, XFORM_IDENT, backbuffer_viewport, sprite_frame_scope); + renderer_texture_render(G.backbuffer_texture, G.backbuffer_cmd_buffer, XFORM_IDENT, backbuffer_viewport, sprite_frame_scope); } /* Present */