retrieve texture size dynamically

This commit is contained in:
jacob 2025-01-20 12:03:09 -06:00
parent cebaed5aa5
commit a2f9f58143
8 changed files with 82 additions and 57 deletions

View File

@ -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)*/

View File

@ -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 };
}

View File

@ -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;

View File

@ -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
* ========================== */

View File

@ -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);

View File

@ -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);
}

View File

@ -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 */

View File

@ -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 */