From 29ec298b48a0ac252387ffe872752856b445aa8f Mon Sep 17 00:00:00 2001 From: jacob Date: Tue, 17 Jun 2025 15:21:26 -0500 Subject: [PATCH] dx12 progress --- build.c | 2 +- res/sh/material.hlsl | 22 +- src/app.c | 35 +- src/atomic.h | 4 +- src/common.h | 46 +-- src/config.h | 2 +- src/draw.h | 2 +- src/gpu.h | 2 +- src/gpu_dx11.c | 351 +++++++++---------- src/gpu_dx12.c | 795 +++++++++++++++++++++++++++++++++++------- src/incbin.c | 4 +- src/math.h | 4 +- src/memory.c | 2 - src/phys.c | 4 +- src/playback_wasapi.c | 17 + src/sim_step.c | 6 +- src/sprite.c | 16 +- src/tar.c | 6 +- src/ttf_dwrite.cpp | 6 +- src/user.c | 98 +++--- 20 files changed, 990 insertions(+), 434 deletions(-) diff --git a/build.c b/build.c index 67e0deaa..fadd0167 100644 --- a/build.c +++ b/build.c @@ -562,7 +562,7 @@ void OnBuild(StringList cli_args) if (arg_msvc) { StringListAppend(&perm, &compile_args, Lit("/fsanitize=address")); } else { - StringListAppend(&perm, &compile_and_link_args, Lit("-fsanitize=address -shared-libasan")); + StringListAppend(&perm, &compile_and_link_args, Lit("-fsanitize=address")); } } diff --git a/res/sh/material.hlsl b/res/sh/material.hlsl index 08c44e85..e5c4eb81 100644 --- a/res/sh/material.hlsl +++ b/res/sh/material.hlsl @@ -19,8 +19,14 @@ struct sh_material_instance { #define ROOTSIG \ "CBV(b0), " \ - "DescriptorTable(SRV(t0), SRV(t1)), " \ - "DescriptorTable(Sampler(s0))" + "SRV(t0), " \ + "DescriptorTable(SRV(t1, numDescriptors = unbounded)), " \ + "StaticSampler(s0, " \ + "filter = FILTER_MIN_MAG_MIP_POINT, " \ + "addressU = TEXTURE_ADDRESS_CLAMP, " \ + "addressV = TEXTURE_ADDRESS_CLAMP, " \ + "addressW = TEXTURE_ADDRESS_CLAMP, " \ + "maxAnisotropy = 1)" cbuffer cbuff : register(b0) { @@ -33,6 +39,8 @@ Texture2D g_texture : register(t1); SamplerState g_sampler : register(s0); +/* TODO: Ensure `NonUniformResourceIndex` is used once bindless */ + /* ========================== * * Vertex shader * ========================== */ @@ -60,16 +68,12 @@ struct vs_output vs(struct vs_input input) { struct sh_material_instance instance = g_instances[g_constants.instance_offset + input.SV_InstanceID]; float2 vert = g_quad_verts[input.SV_VertexID]; - float2 world_pos = mul(instance.xf, float3(vert, 1)).xy; - float4 clip_pos = mul(g_constants.projection, float4(world_pos, 0, 1)); - float2 uv = instance.uv0 + ((vert + 0.5) * (instance.uv1 - instance.uv0)); - float4 tint_lin = linear_from_srgb32(instance.tint_srgb); struct vs_output output; - output.SV_Position = clip_pos; - output.uv = uv; - output.tint_lin = tint_lin; + output.SV_Position = mul(g_constants.projection, float4(world_pos, 0, 1)); + output.uv = instance.uv0 + ((vert + 0.5) * (instance.uv1 - instance.uv0)); + output.tint_lin = linear_from_srgb32(instance.tint_srgb); return output; } diff --git a/src/app.c b/src/app.c index 48cf46a4..8ca50e68 100644 --- a/src/app.c +++ b/src/app.c @@ -29,7 +29,6 @@ struct exit_callback { app_exit_callback_func *func; struct exit_callback *next; - struct sys_thread thread; }; GLOBAL struct { @@ -105,12 +104,6 @@ INTERNAL struct sys_window_settings default_window_settings(struct sys_window *w * Exit callbacks * ========================== */ -INTERNAL SYS_THREAD_ENTRY_POINT_FUNC_DEF(exit_callback_thread_entry_point, vcallback) -{ - struct exit_callback *callback = (struct exit_callback *)vcallback; - callback->func(); -} - void app_register_exit_callback(app_exit_callback_func *func) { struct sys_lock lock = sys_mutex_lock_e(&G.exit_callbacks_mutex); @@ -351,36 +344,22 @@ void app_entry_point(struct string args_str) /* Wait for app_exit() */ sync_flag_wait(&G.exit_sf); - /* Call exit callbacks */ - /* FIXME: Only wait on threads for a certain period of time before + /* Run exit callbacks */ + /* FIXME: Only wait on shutdown for a certain period of time before * forcing process exit (to prevent process hanging in the background - * when a thread gets stuck) */ + * if something gets stuck) */ { + __profscope(Run exit callbacks); struct sys_lock lock = sys_mutex_lock_e(&G.exit_callbacks_mutex); - - /* Start callback threads */ - /* TODO: Create these threads when the callbacks are initially registered and have them wait on exit */ - { - __profscope(app_start_exit_callbacks); - for (struct exit_callback *callback = G.exit_callbacks_head; callback; callback = callback->next) { - callback->thread = sys_thread_alloc(&exit_callback_thread_entry_point, callback, LIT("[P1] Exit callback thread")); - } + for (struct exit_callback *callback = G.exit_callbacks_head; callback; callback = callback->next) { + callback->func(); } - - /* Wait on callback threads */ - { - __profscope(app_wait_on_exit_callbacks); - for (struct exit_callback *callback = G.exit_callbacks_head; callback; callback = callback->next) { - sys_thread_wait_release(&callback->thread); - } - } - sys_mutex_unlock(&lock); } /* Write window settings to file */ { - __profscope(app_write_to_settings_file); + __profscope(Write settings file); struct arena_temp temp = arena_temp_begin(scratch.arena); struct string window_settings_path = app_write_path_cat(temp.arena, settings_file_name); diff --git a/src/atomic.h b/src/atomic.h index 6187d05d..da229f82 100644 --- a/src/atomic.h +++ b/src/atomic.h @@ -20,14 +20,14 @@ FORCE_INLINE i64 atomic_i64_eval_add(struct atomic_i64 *x, i64 a) { return (i64) FORCE_INLINE u32 atomic_u32_eval(struct atomic_u32 *x) { return (u32)_InterlockedCompareExchange((volatile long *)&x->_v, 0, 0); } FORCE_INLINE u32 atomic_u32_eval_exchange(struct atomic_u32 *x, u32 e) { return (u32)_InterlockedExchange((volatile long *)&x->_v, (long)e); } FORCE_INLINE u32 atomic_u32_eval_compare_exchange(struct atomic_u32 *x, u32 c, u32 e) { return (u32)_InterlockedCompareExchange((volatile long *)&x->_v, (long)e, (long)c); } -FORCE_INLINE u32 atomic_u32_eval_xor(struct atomic_u32 *x, u32 c) { return (u32)_InterlockedXor((volatile long *)&x->_v, c); } +FORCE_INLINE u32 atomic_u32_eval_xor(struct atomic_u32 *x, u32 c) { return (u32)_InterlockedXor((volatile long *)&x->_v, (long)c); } FORCE_INLINE u32 atomic_u32_eval_add_u32(struct atomic_u32 *x, u32 a) { return (u32)_InterlockedExchangeAdd((volatile long *)&x->_v, (long)a); } FORCE_INLINE u32 atomic_u32_eval_add_i32(struct atomic_u32 *x, i32 a) { return (u32)_InterlockedExchangeAdd((volatile long *)&x->_v, (long)a); } FORCE_INLINE u64 atomic_u64_eval(struct atomic_u64 *x) { return (u64)_InterlockedCompareExchange64((volatile i64 *)&x->_v, 0, 0); } FORCE_INLINE u64 atomic_u64_eval_exchange(struct atomic_u64 *x, u64 e) { return (u64)_InterlockedExchange64((volatile i64 *)&x->_v, (i64)e); } FORCE_INLINE u64 atomic_u64_eval_compare_exchange(struct atomic_u64 *x, u64 c, u64 e) { return (u64)_InterlockedCompareExchange64((volatile i64 *)&x->_v, (i64)e, (i64)c); } -FORCE_INLINE u32 atomic_u64_eval_xor(struct atomic_u64 *x, u64 c) { return (u64)_InterlockedXor64((volatile i64 *)&x->_v, c); } +FORCE_INLINE u32 atomic_u64_eval_xor(struct atomic_u64 *x, u64 c) { return (u64)_InterlockedXor64((volatile i64 *)&x->_v, (i64)c); } FORCE_INLINE u64 atomic_u64_eval_add_u64(struct atomic_u64 *x, u64 a) { return (u64)_InterlockedExchangeAdd64((volatile i64 *)&x->_v, (i64)a); } FORCE_INLINE u64 atomic_u64_eval_add_i64(struct atomic_u64 *x, i64 a) { return (u64)_InterlockedExchangeAdd64((volatile i64 *)&x->_v, (i64)a); } diff --git a/src/common.h b/src/common.h index 73f89c6a..490e7563 100644 --- a/src/common.h +++ b/src/common.h @@ -154,8 +154,8 @@ extern "C" { #if ASAN void __asan_poison_memory_region(void const volatile *, size_t); void __asan_unpoison_memory_region(void const volatile *add, size_t); -# define ASAN_POISON(addr, size) __asan_poison_memory_region((addr), (size)); -# define ASAN_UNPOISON(addr, size) __asan_unpoison_memory_region((addr), (size)); +# define ASAN_POISON(addr, size) __asan_poison_memory_region((addr), (size)) +# define ASAN_UNPOISON(addr, size) __asan_unpoison_memory_region((addr), (size)) #else # define ASAN_POISON(addr, size) # define ASAN_UNPOISON(addr, size) @@ -281,25 +281,25 @@ void __asan_unpoison_memory_region(void const volatile *add, size_t); #endif /* Color */ -#define RGB(r, g, b) RGBA((r), (g), (b), 0xFF) -#define RGBA(r, g, b, a) (u32)((u32)(r) | ((u32)(g) << 8) | ((u32)(b) << 16) | ((u32)(a) << 24)) -#define BGR(rgb) ((((rgb >> 0) & 0xFF) << 16) | (((rgb >> 8) & 0xFF) << 8) | (((rgb >> 16) & 0xFF) << 0)) +#define RGB32(r, g, b) RGBA32((r), (g), (b), 0xFF) +#define RGBA32(r, g, b, a) (u32)((u32)(r) | ((u32)(g) << 8) | ((u32)(b) << 16) | ((u32)(a) << 24)) +#define BGR32(rgb) ((((rgb >> 0) & 0xFF) << 16) | (((rgb >> 8) & 0xFF) << 8) | (((rgb >> 16) & 0xFF) << 0)) -#define _RGB_U8_FROM_F(fl) ((u8)((fl * 255.0) + 0.5)) -#define RGBA_F(r, g, b, a) RGBA(_RGB_U8_FROM_F((r)), _RGB_U8_FROM_F((g)), _RGB_U8_FROM_F((b)), _RGB_U8_FROM_F((a))) -#define RGB_F(r, g, b) RGBA_F((r), (g), (b), 1.f) +#define _RGB32_U8_FROM_F(fl) ((u8)((fl * 255.0) + 0.5)) +#define RGBA32_F(r, g, b, a) RGBA32(_RGB32_U8_FROM_F((r)), _RGB32_U8_FROM_F((g)), _RGB32_U8_FROM_F((b)), _RGB32_U8_FROM_F((a))) +#define RGB32_F(r, g, b) RGBA32_F((r), (g), (b), 1.f) -#define ALPHA_F(color, a) ((color) & 0x00FFFFFF) | (_RGB_U8_FROM_F((a)) << 24) +#define ALPHA32_F(color, a) ((color) & 0x00FFFFFF) | (_RGB32_U8_FROM_F((a)) << 24) /* Color defines */ -#define COLOR_WHITE RGB(0xFF, 0xFF, 0xFF) -#define COLOR_BLACK RGB(0x00, 0x00, 0x00) -#define COLOR_RED RGB(0xFF, 0x00, 0x00) -#define COLOR_GREEN RGB(0x00, 0xFF, 0x00) -#define COLOR_BLUE RGB(0x00, 0x00, 0xFF) -#define COLOR_YELLOW RGB(0xFF, 0xFF, 0x00) -#define COLOR_ORANGE RGB(0xFF, 0xA5, 0x00) -#define COLOR_PURPLE RGB(0xFF, 0x00, 0XFF) +#define COLOR_WHITE RGB32(0xFF, 0xFF, 0xFF) +#define COLOR_BLACK RGB32(0x00, 0x00, 0x00) +#define COLOR_RED RGB32(0xFF, 0x00, 0x00) +#define COLOR_GREEN RGB32(0x00, 0xFF, 0x00) +#define COLOR_BLUE RGB32(0x00, 0x00, 0xFF) +#define COLOR_YELLOW RGB32(0xFF, 0xFF, 0x00) +#define COLOR_ORANGE RGB32(0xFF, 0xA5, 0x00) +#define COLOR_PURPLE RGB32(0xFF, 0x00, 0XFF) /* Barrier */ #if COMPILER_MSVC @@ -348,9 +348,9 @@ typedef i32 b32; #define I64_MAX (0x7FFFFFFFFFFFFFFFLL) #define I8_MIN ((i8)-0x80) -#define I16_MIN ((i16)-0x8000) -#define I32_MIN ((i32)-0x80000000) -#define I64_MIN ((i64)-0x8000000000000000ULL) +#define I16_MIN ((i16)0x8000) +#define I32_MIN ((i32)0x80000000) +#define I64_MIN ((i64)0x8000000000000000LL) GLOBAL const u32 _f32_infinity_u32 = 0x7f800000; GLOBAL const f32 *_f32_infinity = (f32 *)&_f32_infinity_u32; @@ -648,14 +648,14 @@ INLINE f64 clamp_f64(f64 v, f64 min, f64 max) { return v < min ? min : v > max ? # define __prof static const struct ___tracy_source_location_data CAT(__tracy_source_location,__LINE__) = { NULL, __func__, __FILE__, (uint32_t)__LINE__, 0 }; __attribute((cleanup(__prof_zone_cleanup_func))) TracyCZoneCtx __tracy_zone_ctx = ___tracy_emit_zone_begin_callstack( &CAT(__tracy_source_location,__LINE__), TRACY_CALLSTACK, true ); # define __profscope(name) static const struct ___tracy_source_location_data CAT(__tracy_source_location,__LINE__) = { #name, __func__, __FILE__, (uint32_t)__LINE__, 0 }; __attribute((cleanup(__prof_zone_cleanup_func))) TracyCZoneCtx __tracy_zone_ctx = ___tracy_emit_zone_begin_callstack( &CAT(__tracy_source_location,__LINE__), TRACY_CALLSTACK, true ); # endif -# define __profscope_dx11(dx11_ctx, name, color) static const struct ___tracy_source_location_data CAT(__tracy_gpu_d3d11_source_location,__LINE__) = { #name, __func__, __FILE__, (uint32_t)__LINE__, BGR(color) }; __attribute((cleanup(__prof_dx11_zone_cleanup_func))) TracyCD3D11ZoneCtx __tracy_d3d11_zone_ctx; ___tracy_d3d11_emit_zone_begin( dx11_ctx, &__tracy_d3d11_zone_ctx, &CAT(__tracy_gpu_d3d11_source_location,__LINE__), true); +# define __profscope_dx11(dx11_ctx, name, color) static const struct ___tracy_source_location_data CAT(__tracy_gpu_d3d11_source_location,__LINE__) = { #name, __func__, __FILE__, (uint32_t)__LINE__, BGR32(color) }; __attribute((cleanup(__prof_dx11_zone_cleanup_func))) TracyCD3D11ZoneCtx __tracy_d3d11_zone_ctx; ___tracy_d3d11_emit_zone_begin( dx11_ctx, &__tracy_d3d11_zone_ctx, &CAT(__tracy_gpu_d3d11_source_location,__LINE__), true); #endif INLINE void __prof_zone_cleanup_func(TracyCZoneCtx *ctx) { TracyCZoneEnd(*ctx); } INLINE void __prof_dx11_zone_cleanup_func(TracyCD3D11ZoneCtx *ctx) { ___tracy_d3d11_emit_zone_end(*ctx); } #define __profalloc(ptr, size) TracyCAlloc((ptr), (size)) #define __proffree(ptr) TracyCFree((ptr)) -#define __profmsg(txt, len, col) TracyCMessageC((txt), (len), BGR(col)); +#define __profmsg(txt, len, col) TracyCMessageC((txt), (len), BGR32(col)); #define __profframe(name) TracyCFrameMarkNamed((name)) #define __profthread(name) TracyCSetThreadName((name)) @@ -684,7 +684,7 @@ enum __prof_plot_type { __prof_plot_type_percentage = TracyPlotFormatPercentage, __prof_plot_type_watt = TracyPlotFormatWatt }; -#define __prof_plot_init(name, type, step, fill, color) TracyCPlotConfig(name, type, step, fill, BGR(color)) +#define __prof_plot_init(name, type, step, fill, color) TracyCPlotConfig(name, type, step, fill, BGR32(color)) #define __prof_plot(name, val) TracyCPlot(name, val) #define __prof_plot_i(name, val) TracyCPlotI(name, val) diff --git a/src/config.h b/src/config.h index 3b07856b..3496649b 100644 --- a/src/config.h +++ b/src/config.h @@ -80,7 +80,7 @@ -#define DX12_TEST 1 +#define DX12_TEST 0 diff --git a/src/draw.h b/src/draw.h index 5ead83e3..216a18b6 100644 --- a/src/draw.h +++ b/src/draw.h @@ -119,7 +119,7 @@ struct draw_text_params { u32 color; enum draw_text_alignment alignment; enum draw_text_offset_x offset_x; - enum draw_text_offset_x offset_y; + enum draw_text_offset_y offset_y; struct string str; }; diff --git a/src/gpu.h b/src/gpu.h index 0199264a..fb7db68f 100644 --- a/src/gpu.h +++ b/src/gpu.h @@ -124,7 +124,7 @@ void gpu_submit_plan(struct gpu_handle gpu_plan); * ========================== */ struct gpu_dispatch_params { - struct gpu_handle_array plans; + struct gpu_handle plan; struct gpu_handle draw_target; struct rect draw_target_viewport; }; diff --git a/src/gpu_dx11.c b/src/gpu_dx11.c index 1df984a7..4833c624 100644 --- a/src/gpu_dx11.c +++ b/src/gpu_dx11.c @@ -968,9 +968,9 @@ INTERNAL void reload_shader(struct dx11_shader *old_shader, struct dx11_shader_d *old_shader = new_shader; } else { error_msg = string_format(scratch.arena, - LIT("Failed to compile shader \"%F\":\n%F"), - FMT_STR(name), - FMT_STR(comp_error)); + LIT("Failed to compile shader \"%F\":\n%F"), + FMT_STR(name), + FMT_STR(comp_error)); shader_release(&new_shader); } } else { @@ -1153,9 +1153,9 @@ struct v2i32 gpu_texture_get_size(struct gpu_handle texture) * Dx11 buffer * ========================== */ -/* TODO: Buffer caching based on size */ + /* TODO: Buffer caching based on size */ -/* NOTE: If initial_data is not provided, then ByteWidth will be ignored (set dynamically when buffer grows) */ + /* NOTE: If initial_data is not provided, then ByteWidth will be ignored (set dynamically when buffer grows) */ INTERNAL struct dx11_buffer *dx11_buffer_alloc(struct D3D11_BUFFER_DESC desc, D3D11_SUBRESOURCE_DATA *initial_data) { __prof; @@ -1437,8 +1437,8 @@ void gpu_push_cmd(struct gpu_handle gpu_plan, struct gpu_cmd_params params) struct dx11_cmd *cmd = plan->cpu_last_cmd; if (cmd && ((cmd->kind != params.kind) || - (cmd->texture.sprite.hash != params.texture.sprite.hash) || - (cmd->texture.texture.v != params.texture.texture.v))) { + (cmd->texture.sprite.hash != params.texture.sprite.hash) || + (cmd->texture.texture.v != params.texture.texture.v))) { /* Cannot batch */ cmd = NULL; } @@ -1656,9 +1656,10 @@ INTERNAL void dx11_unbind(u32 flags) void gpu_dispatch(struct gpu_handle gpu_dispatch_state, struct gpu_dispatch_params params) { __prof; - __profscope_dx11(G.profiling_ctx, Dispatch, RGB_F(0.5, 0.2, 0.2)); + __profscope_dx11(G.profiling_ctx, Dispatch, RGB32_F(0.5, 0.2, 0.2)); struct sprite_scope *sprite_scope = sprite_scope_begin(); struct dx11_dispatch_state *state = (struct dx11_dispatch_state *)gpu_dispatch_state.v; + struct dx11_plan *plan = (struct dx11_plan *)params.plan.v; struct rect viewport = params.draw_target_viewport; @@ -1701,141 +1702,91 @@ void gpu_dispatch(struct gpu_handle gpu_dispatch_state, struct gpu_dispatch_para struct mat4x4 vp_matrix = calculate_vp(XFORM_IDENT, viewport.width, viewport.height); { __profscope(Regular pass); - __profscope_dx11(G.profiling_ctx, Regular pass, RGB_F(0.2, 0.5, 0.5)); - for (u64 handles_array_index = 0; handles_array_index < params.plans.count; ++handles_array_index) { - struct dx11_plan *plan = (struct dx11_plan *)params.plans.handles[handles_array_index]->v; - for (struct dx11_cmd *cmd = plan->gpu_first_cmd; cmd; cmd = cmd->next) { - enum gpu_cmd_kind cmd_kind = cmd->kind; + __profscope_dx11(G.profiling_ctx, Regular pass, RGB32_F(0.2, 0.5, 0.5)); + for (struct dx11_cmd *cmd = plan->gpu_first_cmd; cmd; cmd = cmd->next) { + enum gpu_cmd_kind cmd_kind = cmd->kind; - switch (cmd_kind) { - default: - { - /* Unknown cmd kind */ - ASSERT(false); - } break; + switch (cmd_kind) { + default: + { + /* Unknown cmd kind */ + ASSERT(false); + } break; - case GPU_CMD_KIND_DRAW_VIEW: - { - __profscope(Set draw view); - vp_matrix = calculate_vp(cmd->view.xf, viewport.width, viewport.height); - } break; + case GPU_CMD_KIND_DRAW_VIEW: + { + __profscope(Set draw view); + vp_matrix = calculate_vp(cmd->view.xf, viewport.width, viewport.height); + } break; - case GPU_CMD_KIND_DRAW_MESH: - { - __profscope(Draw mesh); - __profscope_dx11(G.profiling_ctx, Draw mesh, RGB_F(0.5, 0.2, 0.2)); - struct dx11_shader *shader = &G.shaders[DX11_SHADER_KIND_MESH]; - if (shader->valid) { - struct dx11_buffer *vertex_buffer = plan->buffers.mesh.vertex_buffer; - struct dx11_buffer *index_buffer = plan->buffers.mesh.index_buffer; + case GPU_CMD_KIND_DRAW_MESH: + { + __profscope(Draw mesh); + __profscope_dx11(G.profiling_ctx, Draw mesh, RGB32_F(0.5, 0.2, 0.2)); + struct dx11_shader *shader = &G.shaders[DX11_SHADER_KIND_MESH]; + if (shader->valid) { + struct dx11_buffer *vertex_buffer = plan->buffers.mesh.vertex_buffer; + struct dx11_buffer *index_buffer = plan->buffers.mesh.index_buffer; - u32 vertex_offset = cmd->mesh.vertex_offset; - u32 index_offset = cmd->mesh.index_offset; - u32 index_count = cmd->mesh.index_count; + u32 vertex_offset = cmd->mesh.vertex_offset; + u32 index_offset = cmd->mesh.index_offset; + u32 index_count = cmd->mesh.index_count; - /* Bind shader */ - ID3D11DeviceContext_VSSetShader(G.devcon, shader->vs, 0, 0); - ID3D11DeviceContext_PSSetShader(G.devcon, shader->ps, 0, 0); - ID3D11DeviceContext_IASetInputLayout(G.devcon, shader->input_layout); + /* Bind shader */ + ID3D11DeviceContext_VSSetShader(G.devcon, shader->vs, 0, 0); + ID3D11DeviceContext_PSSetShader(G.devcon, shader->ps, 0, 0); + ID3D11DeviceContext_IASetInputLayout(G.devcon, shader->input_layout); - /* Fill & bind constant buffer */ - { - struct dx11_mesh_uniform *uniform = dx11_buffer_push(constant_buffer, sizeof(struct dx11_mesh_uniform)); - uniform->vp = vp_matrix; - dx11_buffer_submit(constant_buffer); - } - ID3D11DeviceContext_VSSetConstantBuffers(G.devcon, 0, 1, &constant_buffer->gpu_buffer); - ID3D11DeviceContext_PSSetConstantBuffers(G.devcon, 0, 1, &constant_buffer->gpu_buffer); - - /* Bind vertex buffer */ - u32 zero = 0; - u32 stride = sizeof(struct dx11_mesh_vertex); - ID3D11DeviceContext_IASetVertexBuffers(G.devcon, 0, 1, &vertex_buffer->gpu_buffer, &stride, &zero); - ID3D11DeviceContext_IASetIndexBuffer(G.devcon, index_buffer->gpu_buffer, DXGI_FORMAT_R32_UINT, zero); - - /* Bind RTVs */ - ID3D11RenderTargetView *rtvs[] = { final_tex->rtv }; - ID3D11DeviceContext_OMSetRenderTargets(G.devcon, ARRAY_COUNT(rtvs), rtvs, NULL); - - /* Draw */ - ID3D11DeviceContext_IASetPrimitiveTopology(G.devcon, D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); - ID3D11DeviceContext_DrawIndexed(G.devcon, index_count, index_offset, vertex_offset); - - /* Unbind */ - dx11_unbind(DX11_UNBIND_VS | DX11_UNBIND_PS | DX11_UNBIND_IA | DX11_UNBIND_CBUFF | DX11_UNBIND_VBUFF | DX11_UNBIND_IBUFF | DX11_UNBIND_RTV); + /* Fill & bind constant buffer */ + { + struct dx11_mesh_uniform *uniform = dx11_buffer_push(constant_buffer, sizeof(struct dx11_mesh_uniform)); + uniform->vp = vp_matrix; + dx11_buffer_submit(constant_buffer); } - } break; + ID3D11DeviceContext_VSSetConstantBuffers(G.devcon, 0, 1, &constant_buffer->gpu_buffer); + ID3D11DeviceContext_PSSetConstantBuffers(G.devcon, 0, 1, &constant_buffer->gpu_buffer); - case GPU_CMD_KIND_DRAW_TEXTURE: - { - __profscope(Draw texture); - __profscope_dx11(G.profiling_ctx, Draw texture, RGB_F(0.2, 0.5, 0.2)); - struct dx11_shader *shader = &G.shaders[DX11_SHADER_KIND_TEXTURE]; - if (shader->valid) { - struct dx11_texture *texture = NULL; - if (cmd->texture.texture.v) { - /* Load texture if handle is set */ - texture = (struct dx11_texture *)cmd->texture.texture.v; - } else if (cmd->texture.sprite.hash) { - /* Otherwise load sprite */ - struct sprite_texture *sprite_texture = sprite_texture_from_tag_async(sprite_scope, cmd->texture.sprite); - if (sprite_texture->loaded) { - texture = (struct dx11_texture *)sprite_texture->texture.v; - } - } + /* Bind vertex buffer */ + u32 zero = 0; + u32 stride = sizeof(struct dx11_mesh_vertex); + ID3D11DeviceContext_IASetVertexBuffers(G.devcon, 0, 1, &vertex_buffer->gpu_buffer, &stride, &zero); + ID3D11DeviceContext_IASetIndexBuffer(G.devcon, index_buffer->gpu_buffer, DXGI_FORMAT_R32_UINT, zero); - if (texture && texture->srv) { - struct dx11_buffer *instance_buffer = plan->buffers.texture.instance_buffer; - u32 instance_offset = cmd->texture.instance_offset; - u32 instance_count = cmd->texture.instance_count; + /* Bind RTVs */ + ID3D11RenderTargetView *rtvs[] = { final_tex->rtv }; + ID3D11DeviceContext_OMSetRenderTargets(G.devcon, ARRAY_COUNT(rtvs), rtvs, NULL); - /* Bind shader */ - ID3D11DeviceContext_VSSetShader(G.devcon, shader->vs, 0, 0); - ID3D11DeviceContext_PSSetShader(G.devcon, shader->ps, 0, 0); + /* Draw */ + ID3D11DeviceContext_IASetPrimitiveTopology(G.devcon, D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); + ID3D11DeviceContext_DrawIndexed(G.devcon, index_count, index_offset, vertex_offset); - /* Fill & bind constant buffer */ - { - struct dx11_texture_uniform *uniform = dx11_buffer_push(constant_buffer, sizeof(struct dx11_texture_uniform)); - uniform->vp = vp_matrix; - uniform->instance_offset = instance_offset; - dx11_buffer_submit(constant_buffer); - } - ID3D11DeviceContext_VSSetConstantBuffers(G.devcon, 0, 1, &constant_buffer->gpu_buffer); - ID3D11DeviceContext_PSSetConstantBuffers(G.devcon, 0, 1, &constant_buffer->gpu_buffer); + /* Unbind */ + dx11_unbind(DX11_UNBIND_VS | DX11_UNBIND_PS | DX11_UNBIND_IA | DX11_UNBIND_CBUFF | DX11_UNBIND_VBUFF | DX11_UNBIND_IBUFF | DX11_UNBIND_RTV); + } + } break; - /* Bind dummy vertex buffer */ - u32 zero = 0; - ID3D11DeviceContext_IASetVertexBuffers(G.devcon, 0, 1, &G.dummy_vertex_buffer->gpu_buffer, &zero, &zero); - ID3D11DeviceContext_IASetIndexBuffer(G.devcon, G.quad_index_buffer->gpu_buffer, DXGI_FORMAT_R16_UINT, zero); - - /* Bind SRVs */ - ID3D11ShaderResourceView *srvs[] = { instance_buffer->srv, texture->srv }; - ID3D11DeviceContext_VSSetShaderResources(G.devcon, 0, ARRAY_COUNT(srvs), srvs); - ID3D11DeviceContext_PSSetShaderResources(G.devcon, 0, ARRAY_COUNT(srvs), srvs); - - /* Bind RTVs */ - ID3D11RenderTargetView *rtvs[] = { final_tex->rtv }; - ID3D11DeviceContext_OMSetRenderTargets(G.devcon, ARRAY_COUNT(rtvs), rtvs, NULL); - - /* Draw */ - ID3D11DeviceContext_IASetPrimitiveTopology(G.devcon, D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); - ID3D11DeviceContext_DrawIndexedInstanced(G.devcon, 6, instance_count, 0, 0, 0); - - /* Unbind */ - dx11_unbind(DX11_UNBIND_VS | DX11_UNBIND_PS | DX11_UNBIND_CBUFF | DX11_UNBIND_VBUFF | DX11_UNBIND_IBUFF | DX11_UNBIND_SRV | DX11_UNBIND_RTV); + case GPU_CMD_KIND_DRAW_TEXTURE: + { + __profscope(Draw texture); + __profscope_dx11(G.profiling_ctx, Draw texture, RGB32_F(0.2, 0.5, 0.2)); + struct dx11_shader *shader = &G.shaders[DX11_SHADER_KIND_TEXTURE]; + if (shader->valid) { + struct dx11_texture *texture = NULL; + if (cmd->texture.texture.v) { + /* Load texture if handle is set */ + texture = (struct dx11_texture *)cmd->texture.texture.v; + } else if (cmd->texture.sprite.hash) { + /* Otherwise load sprite */ + struct sprite_texture *sprite_texture = sprite_texture_from_tag_async(sprite_scope, cmd->texture.sprite); + if (sprite_texture->loaded) { + texture = (struct dx11_texture *)sprite_texture->texture.v; } } - } break; - case GPU_CMD_KIND_DRAW_GRID: - { - __profscope(Draw grid); - __profscope_dx11(G.profiling_ctx, Draw grid, RGB_F(0.2, 0.2, 0.5)); - struct dx11_shader *shader = &G.shaders[DX11_SHADER_KIND_GRID]; - if (shader->valid) { - struct dx11_buffer *instance_buffer = plan->buffers.grid.instance_buffer; - u32 instance_offset = cmd->grid.instance_offset; - u32 instance_count = cmd->grid.instance_count; + if (texture && texture->srv) { + struct dx11_buffer *instance_buffer = plan->buffers.texture.instance_buffer; + u32 instance_offset = cmd->texture.instance_offset; + u32 instance_count = cmd->texture.instance_count; /* Bind shader */ ID3D11DeviceContext_VSSetShader(G.devcon, shader->vs, 0, 0); @@ -1843,7 +1794,7 @@ void gpu_dispatch(struct gpu_handle gpu_dispatch_state, struct gpu_dispatch_para /* Fill & bind constant buffer */ { - struct dx11_grid_uniform *uniform = dx11_buffer_push(constant_buffer, sizeof(struct dx11_grid_uniform)); + struct dx11_texture_uniform *uniform = dx11_buffer_push(constant_buffer, sizeof(struct dx11_texture_uniform)); uniform->vp = vp_matrix; uniform->instance_offset = instance_offset; dx11_buffer_submit(constant_buffer); @@ -1857,7 +1808,7 @@ void gpu_dispatch(struct gpu_handle gpu_dispatch_state, struct gpu_dispatch_para ID3D11DeviceContext_IASetIndexBuffer(G.devcon, G.quad_index_buffer->gpu_buffer, DXGI_FORMAT_R16_UINT, zero); /* Bind SRVs */ - ID3D11ShaderResourceView *srvs[] = { instance_buffer->srv }; + ID3D11ShaderResourceView *srvs[] = { instance_buffer->srv, texture->srv }; ID3D11DeviceContext_VSSetShaderResources(G.devcon, 0, ARRAY_COUNT(srvs), srvs); ID3D11DeviceContext_PSSetShaderResources(G.devcon, 0, ARRAY_COUNT(srvs), srvs); @@ -1867,60 +1818,110 @@ void gpu_dispatch(struct gpu_handle gpu_dispatch_state, struct gpu_dispatch_para /* Draw */ ID3D11DeviceContext_IASetPrimitiveTopology(G.devcon, D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); + /* FIXME: Set StartInstanceLocation parameter here rather than passing instance_offset into CBV */ ID3D11DeviceContext_DrawIndexedInstanced(G.devcon, 6, instance_count, 0, 0, 0); /* Unbind */ dx11_unbind(DX11_UNBIND_VS | DX11_UNBIND_PS | DX11_UNBIND_CBUFF | DX11_UNBIND_VBUFF | DX11_UNBIND_IBUFF | DX11_UNBIND_SRV | DX11_UNBIND_RTV); } - } break; + } + } break; - case GPU_CMD_KIND_TEST: - { - __profscope(Test); - __profscope_dx11(G.profiling_ctx, Test, RGB_F(1, 0.2, 1)); - struct dx11_shader *shader = &G.shaders[DX11_SHADER_KIND_TEST]; - if (shader->valid) { - struct dx11_buffer *instance_buffer = plan->buffers.test.instance_buffer; - u32 instance_offset = cmd->test.instance_offset; - u32 instance_count = cmd->test.instance_count; + case GPU_CMD_KIND_DRAW_GRID: + { + __profscope(Draw grid); + __profscope_dx11(G.profiling_ctx, Draw grid, RGB32_F(0.2, 0.2, 0.5)); + struct dx11_shader *shader = &G.shaders[DX11_SHADER_KIND_GRID]; + if (shader->valid) { + struct dx11_buffer *instance_buffer = plan->buffers.grid.instance_buffer; + u32 instance_offset = cmd->grid.instance_offset; + u32 instance_count = cmd->grid.instance_count; - /* Bind shader */ - ID3D11DeviceContext_VSSetShader(G.devcon, shader->vs, 0, 0); - ID3D11DeviceContext_PSSetShader(G.devcon, shader->ps, 0, 0); + /* Bind shader */ + ID3D11DeviceContext_VSSetShader(G.devcon, shader->vs, 0, 0); + ID3D11DeviceContext_PSSetShader(G.devcon, shader->ps, 0, 0); - /* Fill & bind constant buffer */ - { - struct dx11_test_uniform *uniform = dx11_buffer_push(constant_buffer, sizeof(struct dx11_test_uniform)); - uniform->vp = vp_matrix; - uniform->instance_offset = instance_offset; - dx11_buffer_submit(constant_buffer); - } - ID3D11DeviceContext_VSSetConstantBuffers(G.devcon, 0, 1, &constant_buffer->gpu_buffer); - ID3D11DeviceContext_PSSetConstantBuffers(G.devcon, 0, 1, &constant_buffer->gpu_buffer); - - /* Bind dummy vertex buffer */ - u32 zero = 0; - ID3D11DeviceContext_IASetVertexBuffers(G.devcon, 0, 1, &G.dummy_vertex_buffer->gpu_buffer, &zero, &zero); - ID3D11DeviceContext_IASetIndexBuffer(G.devcon, G.quad_index_buffer->gpu_buffer, DXGI_FORMAT_R16_UINT, zero); - - /* Bind SRVs */ - ID3D11ShaderResourceView *srvs[] = { instance_buffer->srv }; - ID3D11DeviceContext_VSSetShaderResources(G.devcon, 0, ARRAY_COUNT(srvs), srvs); - ID3D11DeviceContext_PSSetShaderResources(G.devcon, 0, ARRAY_COUNT(srvs), srvs); - - /* Bind RTVs */ - ID3D11RenderTargetView *rtvs[] = { final_tex->rtv }; - ID3D11DeviceContext_OMSetRenderTargets(G.devcon, ARRAY_COUNT(rtvs), rtvs, NULL); - - /* Draw */ - ID3D11DeviceContext_IASetPrimitiveTopology(G.devcon, D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); - ID3D11DeviceContext_DrawIndexedInstanced(G.devcon, 6, instance_count, 0, 0, 0); - - /* Unbind */ - dx11_unbind(DX11_UNBIND_VS | DX11_UNBIND_PS | DX11_UNBIND_CBUFF | DX11_UNBIND_VBUFF | DX11_UNBIND_IBUFF | DX11_UNBIND_SRV | DX11_UNBIND_RTV); + /* Fill & bind constant buffer */ + { + struct dx11_grid_uniform *uniform = dx11_buffer_push(constant_buffer, sizeof(struct dx11_grid_uniform)); + uniform->vp = vp_matrix; + uniform->instance_offset = instance_offset; + dx11_buffer_submit(constant_buffer); } - } break; - } + ID3D11DeviceContext_VSSetConstantBuffers(G.devcon, 0, 1, &constant_buffer->gpu_buffer); + ID3D11DeviceContext_PSSetConstantBuffers(G.devcon, 0, 1, &constant_buffer->gpu_buffer); + + /* Bind dummy vertex buffer */ + u32 zero = 0; + ID3D11DeviceContext_IASetVertexBuffers(G.devcon, 0, 1, &G.dummy_vertex_buffer->gpu_buffer, &zero, &zero); + ID3D11DeviceContext_IASetIndexBuffer(G.devcon, G.quad_index_buffer->gpu_buffer, DXGI_FORMAT_R16_UINT, zero); + + /* Bind SRVs */ + ID3D11ShaderResourceView *srvs[] = { instance_buffer->srv }; + ID3D11DeviceContext_VSSetShaderResources(G.devcon, 0, ARRAY_COUNT(srvs), srvs); + ID3D11DeviceContext_PSSetShaderResources(G.devcon, 0, ARRAY_COUNT(srvs), srvs); + + /* Bind RTVs */ + ID3D11RenderTargetView *rtvs[] = { final_tex->rtv }; + ID3D11DeviceContext_OMSetRenderTargets(G.devcon, ARRAY_COUNT(rtvs), rtvs, NULL); + + /* Draw */ + ID3D11DeviceContext_IASetPrimitiveTopology(G.devcon, D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); + /* FIXME: Set StartInstanceLocation parameter here rather than passing instance_offset into CBV */ + ID3D11DeviceContext_DrawIndexedInstanced(G.devcon, 6, instance_count, 0, 0, 0); + + /* Unbind */ + dx11_unbind(DX11_UNBIND_VS | DX11_UNBIND_PS | DX11_UNBIND_CBUFF | DX11_UNBIND_VBUFF | DX11_UNBIND_IBUFF | DX11_UNBIND_SRV | DX11_UNBIND_RTV); + } + } break; + + case GPU_CMD_KIND_TEST: + { + __profscope(Test); + __profscope_dx11(G.profiling_ctx, Test, RGB32_F(1, 0.2, 1)); + struct dx11_shader *shader = &G.shaders[DX11_SHADER_KIND_TEST]; + if (shader->valid) { + struct dx11_buffer *instance_buffer = plan->buffers.test.instance_buffer; + u32 instance_offset = cmd->test.instance_offset; + u32 instance_count = cmd->test.instance_count; + + /* Bind shader */ + ID3D11DeviceContext_VSSetShader(G.devcon, shader->vs, 0, 0); + ID3D11DeviceContext_PSSetShader(G.devcon, shader->ps, 0, 0); + + /* Fill & bind constant buffer */ + { + struct dx11_test_uniform *uniform = dx11_buffer_push(constant_buffer, sizeof(struct dx11_test_uniform)); + uniform->vp = vp_matrix; + uniform->instance_offset = instance_offset; + dx11_buffer_submit(constant_buffer); + } + ID3D11DeviceContext_VSSetConstantBuffers(G.devcon, 0, 1, &constant_buffer->gpu_buffer); + ID3D11DeviceContext_PSSetConstantBuffers(G.devcon, 0, 1, &constant_buffer->gpu_buffer); + + /* Bind dummy vertex buffer */ + u32 zero = 0; + ID3D11DeviceContext_IASetVertexBuffers(G.devcon, 0, 1, &G.dummy_vertex_buffer->gpu_buffer, &zero, &zero); + ID3D11DeviceContext_IASetIndexBuffer(G.devcon, G.quad_index_buffer->gpu_buffer, DXGI_FORMAT_R16_UINT, zero); + + /* Bind SRVs */ + ID3D11ShaderResourceView *srvs[] = { instance_buffer->srv }; + ID3D11DeviceContext_VSSetShaderResources(G.devcon, 0, ARRAY_COUNT(srvs), srvs); + ID3D11DeviceContext_PSSetShaderResources(G.devcon, 0, ARRAY_COUNT(srvs), srvs); + + /* Bind RTVs */ + ID3D11RenderTargetView *rtvs[] = { final_tex->rtv }; + ID3D11DeviceContext_OMSetRenderTargets(G.devcon, ARRAY_COUNT(rtvs), rtvs, NULL); + + /* Draw */ + ID3D11DeviceContext_IASetPrimitiveTopology(G.devcon, D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); + /* FIXME: Set StartInstanceLocation parameter here rather than passing instance_offset into CBV */ + ID3D11DeviceContext_DrawIndexedInstanced(G.devcon, 6, instance_count, 0, 0, 0); + + /* Unbind */ + dx11_unbind(DX11_UNBIND_VS | DX11_UNBIND_PS | DX11_UNBIND_CBUFF | DX11_UNBIND_VBUFF | DX11_UNBIND_IBUFF | DX11_UNBIND_SRV | DX11_UNBIND_RTV); + } + } break; } } } diff --git a/src/gpu_dx12.c b/src/gpu_dx12.c index 8613d100..3587225c 100644 --- a/src/gpu_dx12.c +++ b/src/gpu_dx12.c @@ -39,6 +39,10 @@ #define DX12_SWAPCHAIN_FORMAT (DXGI_FORMAT_R8G8B8A8_UNORM) //#define DX12_SWAPCHAIN_RTV_FORMAT (DXGI_FORMAT_R8G8B8A8_UNORM_SRGB) +/* Arbitrary limits */ +#define DX12_NUM_CBV_SRV_UAV_DESCRIPTORS (1024 * 64) +#define DX12_NUM_RTV_DESCRIPTORS (1024 * 1) + #if RTC # define DX12_DEBUG 1 # define DX12_SHADER_DEBUG 1 @@ -76,14 +80,67 @@ struct pipeline_error { struct string msg; }; +struct dx12_descriptor { + struct dx12_cpu_descriptor_heap *heap; + D3D12_CPU_DESCRIPTOR_HANDLE handle; + + struct dx12_descriptor *next_free; +}; + struct dx12_resource { + ID3D12Resource *resource; enum D3D12_RESOURCE_STATES state; +#if 0 + D3D12_CPU_DESCRIPTOR_HANDLE cbv_handle; + D3D12_CPU_DESCRIPTOR_HANDLE srv_handle; + D3D12_CPU_DESCRIPTOR_HANDLE uav_handle; + D3D12_CPU_DESCRIPTOR_HANDLE rtv_handle; +#else + struct dx12_descriptor *cbv_descriptor; + struct dx12_descriptor *srv_descriptor; + struct dx12_descriptor *uav_descriptor; + struct dx12_descriptor *rtv_descriptor; +#endif + + D3D12_GPU_VIRTUAL_ADDRESS gpu_address; /* NOTE: 0 for textures */ + + struct dx12_resource *next_free; +}; + +struct dx12_cpu_descriptor_heap { + enum D3D12_DESCRIPTOR_HEAP_TYPE type; + struct arena arena; + struct sys_mutex mutex; + + u32 descriptor_size; + u32 num_descriptors_reserved; + u32 num_descriptors_capacity; + + struct dx12_descriptor *first_free_descriptor; + + ID3D12DescriptorHeap *heap; + struct D3D12_CPU_DESCRIPTOR_HANDLE handle; +}; + +struct dx12_gpu_descriptor_heap { + D3D12_DESCRIPTOR_HEAP_TYPE type; + ID3D12DescriptorHeap *heap; + D3D12_CPU_DESCRIPTOR_HANDLE cpu_handle; + D3D12_GPU_DESCRIPTOR_HANDLE gpu_handle; + + /* If free_fence < free_fence_value, then descriptor heap is in use by the GPU */ + ID3D12Fence *free_fence; + u64 free_fence_value; + + struct dx12_gpu_descriptor_heap *prev_free; + struct dx12_gpu_descriptor_heap *next_free; }; enum dx12_handle_kind { DX12_HANDLE_KIND_NONE, - DX12_HANDLE_KIND_TEXTURE, + DX12_HANDLE_KIND_RESOURCE, DX12_HANDLE_KIND_PLAN, + DX12_HANDLE_KIND_DISPATCH_STATE, NUM_DX12_HANDLE_KINDS }; @@ -97,10 +154,6 @@ struct dx12_handle_entry { struct dx12_handle_entry *next_free; }; -struct dx12_buffer { - i32 _; -}; - /* ========================== * * Global state * ========================== */ @@ -112,14 +165,50 @@ GLOBAL struct { struct dx12_handle_entry *first_free_handle_entry; u64 num_handle_entries_reserved; + /* Descriptor heaps pool */ + struct sys_mutex gpu_descriptor_heaps_mutex; + struct arena gpu_descriptor_heaps_arena; + struct dx12_gpu_descriptor_heap *first_free_gpu_descriptor_heap; + struct dx12_gpu_descriptor_heap *last_free_gpu_descriptor_heap; + + /* Resources pool */ + struct sys_mutex resources_mutex; + struct arena resources_arena; + struct dx12_resource *first_free_resource; + + + + + + + + + /* FIXME: Remove this (testing) */ + struct pipeline test_pipeline; + + + + + + + + + /* Factory */ + IDXGIFactory6 *factory; + /* Device */ ID3D12Device *device; - /* Desc sizes */ - u32 desc_size_rtv; + /* Descriptor sizes */ + u32 desc_sizes[D3D12_DESCRIPTOR_HEAP_TYPE_NUM_TYPES]; + u32 desc_counts[D3D12_DESCRIPTOR_HEAP_TYPE_NUM_TYPES]; + + /* Global descriptor heaps */ + struct dx12_cpu_descriptor_heap *cbv_srv_uav_heap; + struct dx12_cpu_descriptor_heap *rtv_heap; /* Command queues */ - /* TDOO: Add optional mode to route everything to direct queue */ + /* TODO: Add optional mode to route everything to direct queue */ ID3D12CommandQueue *cq_direct; ID3D12CommandQueue *cq_compute; ID3D12CommandQueue *cq_copy_critical; @@ -131,6 +220,12 @@ GLOBAL struct { IDXGISwapChain3 *swapchain; ID3D12DescriptorHeap *swapchain_rtv_heap; ID3D12Resource *swapchain_buffers[DX12_SWAPCHAIN_BUFFER_COUNT]; + + /* Dummy vertex buffer */ + struct dx12_resource *dummy_vertex_buffer; + struct dx12_resource *dummy_index_buffer; + D3D12_VERTEX_BUFFER_VIEW dummy_vertex_buffer_view; + D3D12_INDEX_BUFFER_VIEW quad_index_buffer_view; } G = ZI, DEBUG_ALIAS(G, G_gpu_dx12); /* ========================== * @@ -138,7 +233,10 @@ GLOBAL struct { * ========================== */ INTERNAL APP_EXIT_CALLBACK_FUNC_DEF(gpu_shutdown); -INTERNAL void dx12_init_base(struct sys_window *window); +INTERNAL struct dx12_cpu_descriptor_heap *dx12_cpu_descriptor_heap_alloc(enum D3D12_DESCRIPTOR_HEAP_TYPE type); +INTERNAL void dx12_init_device(void); +INTERNAL void dx12_init_objects(void); +INTERNAL void dx12_init_swapchain(struct sys_window *window); INTERNAL void dx12_init_pipelines(void); struct gpu_startup_receipt gpu_startup(struct work_startup_receipt *work_sr, struct sys_window *window) @@ -149,10 +247,83 @@ struct gpu_startup_receipt gpu_startup(struct work_startup_receipt *work_sr, str G.handle_entries_mutex = sys_mutex_alloc(); G.handle_entries_arena = arena_alloc(GIGABYTE(64)); + /* Initialize gpu descriptor heaps pool */ + G.gpu_descriptor_heaps_mutex = sys_mutex_alloc(); + G.gpu_descriptor_heaps_arena = arena_alloc(GIGABYTE(64)); + + /* Initialize resources pool */ + G.resources_mutex = sys_mutex_alloc(); + G.resources_arena = arena_alloc(GIGABYTE(64)); + /* Initialize dx12 */ - dx12_init_base(window); + dx12_init_device(); + dx12_init_objects(); + dx12_init_swapchain(window); dx12_init_pipelines(); + /* Init dummy buffers */ +#if 0 + { + LOCAL_PERSIST const DXGI_FORMAT formats[] = { + [GPU_TEXTURE_FORMAT_R8G8B8A8_UNORM] = DXGI_FORMAT_R8G8B8A8_UNORM, + [GPU_TEXTURE_FORMAT_R8G8B8A8_UNORM_SRGB] = DXGI_FORMAT_R8G8B8A8_UNORM_SRGB + }; + + enum dx12_resource_view_flags view_flags = DX12_RESOURCE_VIEW_FLAG_SRV; + + D3D12_HEAP_PROPERTIES heap_props = { .Type = D3D12_HEAP_TYPE_DEFAULT }; + heap_props.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN; + heap_props.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN; + + D3D12_HEAP_FLAGS heap_flags = D3D12_HEAP_FLAG_CREATE_NOT_ZEROED; + + D3D12_RESOURCE_DESC desc = ZI; + desc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D; + desc.Alignment = 0; + desc.Width = size.x; + desc.Height = size.y; + desc.DepthOrArraySize = 1; + desc.MipLevels = 1; + desc.SampleDesc.Count = 1; + desc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN; + if (flags & GPU_TEXTURE_FLAG_TARGETABLE) { + desc.Flags |= D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET; + view_flags |= DX12_RESOURCE_VIEW_FLAG_RTV; + } + + D3D12_RESOURCE_STATES initial_state = D3D12_RESOURCE_STATE_COPY_DEST; + + struct dx12_resource *r = dx12_resource_alloc(heap_props, heap_flags, desc, initial_state, view_flags); + + //G.dummy_vertex_buffer = dx12_resource_alloc( + + + + + + /* Dummy vertex buffer */ + u8 dummy_data[16] = ZI; + D3D11_BUFFER_DESC vdesc = ZI; + vdesc.Usage = D3D11_USAGE_IMMUTABLE; + vdesc.ByteWidth = sizeof(dummy_data); + vdesc.BindFlags = D3D11_BIND_VERTEX_BUFFER; + D3D11_SUBRESOURCE_DATA dummy_data_subres = ZI; + dummy_data_subres.pSysMem = dummy_data; + G.dummy_vertex_buffer = dx11_buffer_alloc(vdesc, &dummy_data_subres); + + /* Quad index buffer */ + LOCAL_PERSIST u16 quad_indices[6] = { 0, 1, 2, 0, 2, 3 }; + D3D11_BUFFER_DESC idesc = ZI; + idesc.Usage = D3D11_USAGE_IMMUTABLE; + idesc.ByteWidth = sizeof(quad_indices); + idesc.BindFlags = D3D11_BIND_INDEX_BUFFER; + D3D11_SUBRESOURCE_DATA idata = ZI; + idata.pSysMem = quad_indices; + G.quad_index_buffer = dx11_buffer_alloc(idesc, &idata); + } +#endif + + /* Register callbacks */ app_register_exit_callback(gpu_shutdown); @@ -183,7 +354,7 @@ INTERNAL APP_EXIT_CALLBACK_FUNC_DEF(gpu_shutdown) * Handle * ========================== */ -INTERNAL void dx12_buffer_release(struct dx12_buffer *t); +INTERNAL void dx12_resource_release(struct dx12_resource *t); INTERNAL struct gpu_handle handle_alloc(enum dx12_handle_kind kind, void *data) { @@ -249,7 +420,7 @@ INTERNAL void *handle_get_data(struct gpu_handle handle, enum dx12_handle_kind k * to ensure freed textures aren't being used in pending command lists. */ void gpu_release(struct gpu_handle handle) { - enum dx12_handle_kind kind = NULL; + enum dx12_handle_kind kind = 0; void *data = NULL; /* Release handle entry */ @@ -271,16 +442,16 @@ void gpu_release(struct gpu_handle handle) switch (kind) { default: break; - case DX12_HANDLE_KIND_TEXTURE: + case DX12_HANDLE_KIND_RESOURCE: { - dx12_buffer_release(data); + dx12_resource_release(data); } break; } } } /* ========================== * - * Dx12 base initialization + * Dx12 device initialization * ========================== */ INTERNAL void dx12_init_error(struct string error) @@ -291,7 +462,7 @@ INTERNAL void dx12_init_error(struct string error) scratch_end(scratch); } -INTERNAL void dx12_init_base(struct sys_window *window) +INTERNAL void dx12_init_device(void) { __prof; struct arena_temp scratch = scratch_begin_no_conflict(); @@ -325,21 +496,20 @@ INTERNAL void dx12_init_base(struct sys_window *window) #endif /* Create factory */ - IDXGIFactory6 *factory = NULL; - hr = CreateDXGIFactory2(dxgi_factory_flags, &IID_IDXGIFactory6, (void **)&factory); + hr = CreateDXGIFactory2(dxgi_factory_flags, &IID_IDXGIFactory6, (void **)&G.factory); if (FAILED(hr)) { dx12_init_error(LIT("Failed to initialize DXGI factory")); } /* Create device */ - ID3D12Device *device = NULL; { + ID3D12Device *device = NULL; struct string error = LIT("Could not initialize GPU device."); struct string first_gpu_name = ZI; u32 adapter_index = 0; while (true) { IDXGIAdapter1 *adapter = NULL; - hr = IDXGIFactory6_EnumAdapterByGpuPreference(factory, adapter_index, DXGI_GPU_PREFERENCE_HIGH_PERFORMANCE, &IID_IDXGIAdapter1, (void **)&adapter); + hr = IDXGIFactory6_EnumAdapterByGpuPreference(G.factory, adapter_index, DXGI_GPU_PREFERENCE_HIGH_PERFORMANCE, &IID_IDXGIAdapter1, (void **)&adapter); if (SUCCEEDED(hr)) { DXGI_ADAPTER_DESC1 desc; IDXGIAdapter1_GetDesc1(adapter, &desc); @@ -368,16 +538,14 @@ INTERNAL void dx12_init_base(struct sys_window *window) } dx12_init_error(error); } + G.device = device; } - /* Get desc sizes */ - u32 desc_size_rtv = ID3D12Device_GetDescriptorHandleIncrementSize(device, D3D12_DESCRIPTOR_HEAP_TYPE_RTV); - #if DX12_DEBUG /* Enable D3D12 Debug break */ { ID3D12InfoQueue *info = NULL; - hr = ID3D12Device_QueryInterface(device, &IID_ID3D12InfoQueue, (void **)&info); + hr = ID3D12Device_QueryInterface(G.device, &IID_ID3D12InfoQueue, (void **)&info); if (FAILED(hr)) { dx12_init_error(LIT("Failed to query ID3D12Device interface")); } @@ -399,67 +567,94 @@ INTERNAL void dx12_init_base(struct sys_window *window) } #endif + scratch_end(scratch); +} + +/* ========================== * + * Dx12 object initialization + * ========================== */ + +INTERNAL void dx12_init_objects(void) +{ + HRESULT hr = 0; + + /* Initialize desc sizes */ + G.desc_sizes[D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV] = ID3D12Device_GetDescriptorHandleIncrementSize(G.device, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); + G.desc_sizes[D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER] = ID3D12Device_GetDescriptorHandleIncrementSize(G.device, D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER); + G.desc_sizes[D3D12_DESCRIPTOR_HEAP_TYPE_RTV] = ID3D12Device_GetDescriptorHandleIncrementSize(G.device, D3D12_DESCRIPTOR_HEAP_TYPE_RTV); + G.desc_sizes[D3D12_DESCRIPTOR_HEAP_TYPE_DSV] = ID3D12Device_GetDescriptorHandleIncrementSize(G.device, D3D12_DESCRIPTOR_HEAP_TYPE_DSV); + + /* Initialize desc counts */ + G.desc_counts[D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV] = DX12_NUM_CBV_SRV_UAV_DESCRIPTORS; + G.desc_counts[D3D12_DESCRIPTOR_HEAP_TYPE_RTV] = DX12_NUM_RTV_DESCRIPTORS; + + /* Create global descriptor heaps */ + G.cbv_srv_uav_heap = dx12_cpu_descriptor_heap_alloc(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); + G.rtv_heap = dx12_cpu_descriptor_heap_alloc(D3D12_DESCRIPTOR_HEAP_TYPE_RTV); + /* Create direct command queue */ - ID3D12CommandQueue *cq_direct = NULL; { D3D12_COMMAND_QUEUE_DESC desc = ZI; desc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE; desc.Type = D3D12_COMMAND_LIST_TYPE_DIRECT; - hr = ID3D12Device_CreateCommandQueue(device, &desc, &IID_ID3D12CommandQueue, (void **)&cq_direct); + hr = ID3D12Device_CreateCommandQueue(G.device, &desc, &IID_ID3D12CommandQueue, (void **)&G.cq_direct); if (FAILED(hr)) { dx12_init_error(LIT("Failed to create direct command queue")); } } /* Create compute command queue */ - ID3D12CommandQueue *cq_compute = NULL; { D3D12_COMMAND_QUEUE_DESC desc = ZI; desc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE; desc.Type = D3D12_COMMAND_LIST_TYPE_COMPUTE; - hr = ID3D12Device_CreateCommandQueue(device, &desc, &IID_ID3D12CommandQueue, (void **)&cq_compute); + hr = ID3D12Device_CreateCommandQueue(G.device, &desc, &IID_ID3D12CommandQueue, (void **)&G.cq_compute); if (FAILED(hr)) { dx12_init_error(LIT("Failed to create compute command queue")); } } /* Create critical copy command queue */ - ID3D12CommandQueue *cq_copy_critical = NULL; { D3D12_COMMAND_QUEUE_DESC desc = ZI; desc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE; desc.Type = D3D12_COMMAND_LIST_TYPE_COPY; desc.Priority = D3D12_COMMAND_QUEUE_PRIORITY_HIGH; - hr = ID3D12Device_CreateCommandQueue(device, &desc, &IID_ID3D12CommandQueue, (void **)&cq_copy_critical); + hr = ID3D12Device_CreateCommandQueue(G.device, &desc, &IID_ID3D12CommandQueue, (void **)&G.cq_copy_critical); if (FAILED(hr)) { dx12_init_error(LIT("Failed to create critical copy command queue")); } } /* Create background copy command queue */ - ID3D12CommandQueue *cq_copy_background = NULL; { D3D12_COMMAND_QUEUE_DESC desc = ZI; desc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE; desc.Type = D3D12_COMMAND_LIST_TYPE_COPY; - hr = ID3D12Device_CreateCommandQueue(device, &desc, &IID_ID3D12CommandQueue, (void **)&cq_copy_background); + hr = ID3D12Device_CreateCommandQueue(G.device, &desc, &IID_ID3D12CommandQueue, (void **)&G.cq_copy_background); if (FAILED(hr)) { dx12_init_error(LIT("Failed to create background copy command queue")); } } +} + +/* ========================== * + * Dx12 swapchain initialization + * ========================== */ + +INTERNAL void dx12_init_swapchain(struct sys_window *window) +{ + HRESULT hr = 0; /* Create swapchain command allocator */ - ID3D12CommandAllocator *swapchain_ca = NULL; { - hr = ID3D12Device_CreateCommandAllocator(device, D3D12_COMMAND_LIST_TYPE_DIRECT, &IID_ID3D12CommandAllocator, (void **)&swapchain_ca); + hr = ID3D12Device_CreateCommandAllocator(G.device, D3D12_COMMAND_LIST_TYPE_DIRECT, &IID_ID3D12CommandAllocator, (void **)&G.swapchain_ca); if (FAILED(hr)) { dx12_init_error(LIT("Failed to create swapchain command allocator")); } } /* Create swapchain */ - IDXGISwapChain3 *swapchain = NULL; - u32 swapchain_frame_index = 0; { HWND hwnd = (HWND)sys_window_get_internal_handle(window); DXGI_SWAP_CHAIN_DESC1 desc = { @@ -475,69 +670,52 @@ INTERNAL void dx12_init_base(struct sys_window *window) /* Create swapchain1 */ IDXGISwapChain1 *swapchain1 = NULL; - hr = IDXGIFactory2_CreateSwapChainForHwnd(factory, (IUnknown *)cq_direct, hwnd, &desc, NULL, NULL, &swapchain1); + hr = IDXGIFactory2_CreateSwapChainForHwnd(G.factory, (IUnknown *)G.cq_direct, hwnd, &desc, NULL, NULL, &swapchain1); if (FAILED(hr)) { dx12_init_error(LIT("Failed to create IDXGISwapChain1")); } /* Upgrade to swapchain3 */ - hr = IDXGISwapChain1_QueryInterface(swapchain1, &IID_IDXGISwapChain3, (void **)&swapchain); + hr = IDXGISwapChain1_QueryInterface(swapchain1, &IID_IDXGISwapChain3, (void **)&G.swapchain); if (FAILED(hr)) { dx12_init_error(LIT("Failed to create IDXGISwapChain3")); } /* Disable Alt+Enter changing monitor resolution to match window size */ - IDXGIFactory_MakeWindowAssociation(factory, hwnd, DXGI_MWA_NO_ALT_ENTER); + IDXGIFactory_MakeWindowAssociation(G.factory, hwnd, DXGI_MWA_NO_ALT_ENTER); /* Get initial frame index */ - swapchain_frame_index = IDXGISwapChain3_GetCurrentBackBufferIndex(swapchain); + G.swapchain_frame_index = IDXGISwapChain3_GetCurrentBackBufferIndex(G.swapchain); IDXGISwapChain1_Release(swapchain1); } /* Create swapchain RTV heap */ - ID3D12DescriptorHeap *swapchain_rtv_heap = NULL; { D3D12_DESCRIPTOR_HEAP_DESC desc = ZI; desc.NumDescriptors = DX12_SWAPCHAIN_BUFFER_COUNT; desc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_RTV; desc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE; - hr = ID3D12Device_CreateDescriptorHeap(device, &desc, &IID_ID3D12DescriptorHeap, (void **)&swapchain_rtv_heap); + hr = ID3D12Device_CreateDescriptorHeap(G.device, &desc, &IID_ID3D12DescriptorHeap, (void **)&G.swapchain_rtv_heap); if (FAILED(hr)) { dx12_init_error(LIT("Failed to create swapchain RTV heap")); } } /* Create swacphain RTVs */ - ID3D12Resource *swapchain_buffers[DX12_SWAPCHAIN_BUFFER_COUNT] = ZI; { D3D12_CPU_DESCRIPTOR_HANDLE rtv_handle = ZI; - ID3D12DescriptorHeap_GetCPUDescriptorHandleForHeapStart(swapchain_rtv_heap, &rtv_handle); + ID3D12DescriptorHeap_GetCPUDescriptorHandleForHeapStart(G.swapchain_rtv_heap, &rtv_handle); for (u32 i = 0; i < DX12_SWAPCHAIN_BUFFER_COUNT; ++i) { - hr = IDXGISwapChain3_GetBuffer(swapchain, i, &IID_ID3D12Resource, (void **)&swapchain_buffers[i]); + hr = IDXGISwapChain3_GetBuffer(G.swapchain, i, &IID_ID3D12Resource, (void **)&G.swapchain_buffers[i]); if (FAILED(hr)) { dx12_init_error(LIT("Failed to get swapchain buffer")); } - ID3D12Device_CreateRenderTargetView(device, swapchain_buffers[i], NULL, rtv_handle); - rtv_handle.ptr += desc_size_rtv; + ID3D12Device_CreateRenderTargetView(G.device, G.swapchain_buffers[i], NULL, rtv_handle); + rtv_handle.ptr += G.desc_sizes[D3D12_DESCRIPTOR_HEAP_TYPE_RTV]; } } - - G.device = device; - G.desc_size_rtv = desc_size_rtv; - G.swapchain_frame_index = swapchain_frame_index; - G.cq_direct = cq_direct; - G.cq_compute = cq_compute; - G.cq_copy_critical = cq_copy_critical; - G.cq_copy_background = cq_copy_background; - G.swapchain_ca = swapchain_ca; - G.swapchain = swapchain; - G.swapchain_rtv_heap = swapchain_rtv_heap; - MEMCPY(&G.swapchain_buffers, swapchain_buffers, sizeof(G.swapchain_buffers)); - - IDXGIFactory6_Release(factory); - scratch_end(scratch); } /* ========================== * @@ -596,7 +774,8 @@ INTERNAL void dx12_init_pipelines(void) sys_panic(msg); pipeline_release(&result->pipeline); } else { - /* TODO */ + /* FIXME: remove this */ + G.test_pipeline = result->pipeline; } } @@ -1036,52 +1215,205 @@ INTERNAL void pipeline_release(struct pipeline *pipeline) } } +#if 1 + /* ========================== * - * Buffer + * CPU descriptor heap * ========================== */ -INTERNAL void dx12_buffer_release(struct dx12_buffer *t) +INTERNAL struct dx12_cpu_descriptor_heap *dx12_cpu_descriptor_heap_alloc(enum D3D12_DESCRIPTOR_HEAP_TYPE type) { - (UNUSED)t; + struct dx12_cpu_descriptor_heap *dh = NULL; + { + struct arena arena = arena_alloc(MEGABYTE(64)); + dh = arena_push(&arena, struct dx12_cpu_descriptor_heap); + dh->arena = arena; + } + dh->mutex = sys_mutex_alloc(); + + u32 num_descriptors = 0; + u32 descriptor_size = 0; + if (type < (i32)ARRAY_COUNT(G.desc_counts) && type < (i32)ARRAY_COUNT(G.desc_sizes)) { + num_descriptors = G.desc_counts[type]; + descriptor_size = G.desc_sizes[type]; + } + if (num_descriptors == 0 || descriptor_size == 0) { + sys_panic(LIT("Unsupported CPU descriptor type")); + } + + dh->num_descriptors_capacity = num_descriptors; + dh->descriptor_size = descriptor_size; + + D3D12_DESCRIPTOR_HEAP_DESC desc = ZI; + desc.Type = type; + desc.NumDescriptors = num_descriptors; + HRESULT hr = ID3D12Device_CreateDescriptorHeap(G.device, &desc, &IID_ID3D12DescriptorHeap, (void **)&dh->heap); + if (FAILED(hr)) { + sys_panic(LIT("Failed to create CPU descriptor heap")); + } + ID3D12DescriptorHeap_GetCPUDescriptorHandleForHeapStart(dh->heap, &dh->handle); + + return dh; +} + +#if 0 +INTERNAL void dx12_cpu_descriptor_heap_release(struct dx12_cpu_descriptor_heap *dh) +{ + /* TODO */ + (UNUSED)dh; +} +#endif + +/* ========================== * + * Descriptor + * ========================== */ + +INTERNAL struct dx12_descriptor *dx12_descriptor_alloc(struct dx12_cpu_descriptor_heap *dh) +{ + struct dx12_descriptor *d = NULL; + D3D12_CPU_DESCRIPTOR_HANDLE handle = ZI; + { + struct sys_lock lock = sys_mutex_lock_e(&dh->mutex); + if (dh->first_free_descriptor) { + d = dh->first_free_descriptor; + handle = d->handle; + } else { + if (dh->num_descriptors_reserved >= dh->num_descriptors_capacity) { + sys_panic(LIT("Max descriptors reached in heap")); + } + + d = arena_push_no_zero(&dh->arena, struct dx12_descriptor); + handle.ptr = dh->handle.ptr + (dh->num_descriptors_reserved * dh->descriptor_size); + ++dh->num_descriptors_reserved; + } + sys_mutex_unlock(&lock); + } + MEMZERO_STRUCT(d); + d->heap = dh; + d->handle = handle; + return d; } /* ========================== * - * Texture + * GPU (shader visible) descriptor heap * ========================== */ - -struct gpu_handle gpu_texture_alloc(enum gpu_texture_format format, u32 flags, struct v2i32 size, void *initial_data) +INTERNAL struct dx12_gpu_descriptor_heap *dx12_gpu_descriptor_heap_alloc(struct dx12_cpu_descriptor_heap *dh_cpu) { - (UNUSED)format; - (UNUSED)flags; - (UNUSED)size; - (UNUSED)initial_data; - struct dx12_buffer *t = NULL; + ASSERT(dh_cpu->type == D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); /* Src heap must have expected type */ - return handle_alloc(DX12_HANDLE_KIND_TEXTURE, t); + /* Allocate GPU heap */ + struct dx12_gpu_descriptor_heap *dh_gpu = NULL; + ID3D12DescriptorHeap *heap = NULL; + D3D12_CPU_DESCRIPTOR_HANDLE cpu_handle = ZI; + D3D12_GPU_DESCRIPTOR_HANDLE gpu_handle = ZI; + ID3D12Fence *free_fence = NULL; + u64 free_fence_value = 0; + { + struct sys_lock lock = sys_mutex_lock_e(&G.gpu_descriptor_heaps_mutex); + /* Find first free & ready heap for reuse */ + /* FIXME: Rather than storing fence per heap, store & increment fence per queue and check against it */ + for (struct dx12_gpu_descriptor_heap *tmp = G.first_free_gpu_descriptor_heap; tmp; tmp = tmp->next_free) { + if (ID3D12Fence_GetCompletedValue(tmp->free_fence) >= tmp->free_fence_value) { + dh_gpu = tmp; + break; + } + } + if (dh_gpu) { + /* Free & ready heap found */ + dh_gpu = G.first_free_gpu_descriptor_heap; + heap = dh_gpu->heap; + cpu_handle = dh_gpu->cpu_handle; + gpu_handle = dh_gpu->gpu_handle; + free_fence = dh_gpu->free_fence; + free_fence_value = dh_gpu->free_fence_value; + /* Remove from free list */ + struct dx12_gpu_descriptor_heap *prev = dh_gpu->prev_free; + struct dx12_gpu_descriptor_heap *next = dh_gpu->next_free; + if (prev) { + prev->next_free = next; + } else { + G.first_free_gpu_descriptor_heap = next; + } + if (next) { + next->prev_free = prev; + } else { + G.last_free_gpu_descriptor_heap = prev; + } + } else { + /* No available heap available for reuse, allocate new */ + dh_gpu = arena_push_no_zero(&G.gpu_descriptor_heaps_arena, struct dx12_gpu_descriptor_heap); + } + sys_mutex_unlock(&lock); + } + MEMZERO_STRUCT(dh_gpu); + if (!heap) { + D3D12_DESCRIPTOR_HEAP_DESC desc = ZI; + desc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV; + desc.NumDescriptors = DX12_NUM_CBV_SRV_UAV_DESCRIPTORS; + desc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE; + HRESULT hr = ID3D12Device_CreateDescriptorHeap(G.device, &desc, &IID_ID3D12DescriptorHeap, (void **)&heap); + if (FAILED(hr)) { + sys_panic(LIT("Failed to create GPU descriptor heap")); + } + ID3D12DescriptorHeap_GetCPUDescriptorHandleForHeapStart(heap, &cpu_handle); + ID3D12DescriptorHeap_GetGPUDescriptorHandleForHeapStart(heap, &gpu_handle); + hr = ID3D12Device_CreateFence(G.device, 0, 0, &IID_ID3D12Fence, (void **)&free_fence); + if (FAILED(hr)) { + sys_panic(LIT("Failed to create GPU descriptor heap fence")); + } + } + dh_gpu->heap = heap; + dh_gpu->cpu_handle = cpu_handle; + dh_gpu->gpu_handle = gpu_handle; + dh_gpu->free_fence = free_fence; + dh_gpu->free_fence_value = free_fence_value; + + /* Copy CPU heap */ + { + struct sys_lock lock = sys_mutex_lock_s(&dh_cpu->mutex); + ID3D12Device_CopyDescriptorsSimple(G.device, dh_cpu->num_descriptors_reserved, dh_gpu->cpu_handle, dh_cpu->handle, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); + sys_mutex_unlock(&lock); + } + + return dh_gpu; } -void gpu_texture_clear(struct gpu_handle target_texture, u32 clear_color) +INTERNAL void dx12_gpu_descriptor_heap_release(struct dx12_gpu_descriptor_heap *dh, ID3D12CommandQueue *cq) { - (UNUSED)target_texture; - (UNUSED)clear_color; -} - -struct v2i32 gpu_texture_get_size(struct gpu_handle texture) -{ - (UNUSED)texture; - struct v2i32 res = ZI; - return res; + /* Queue fence signal */ + ++dh->free_fence_value; + ID3D12CommandQueue_Signal(cq, dh->free_fence, dh->free_fence_value); + /* Add to free list */ + struct sys_lock lock = sys_mutex_lock_e(&G.gpu_descriptor_heaps_mutex); + dh->next_free = G.first_free_gpu_descriptor_heap; + if (G.last_free_gpu_descriptor_heap) { + G.last_free_gpu_descriptor_heap->next_free = dh; + } else { + G.first_free_gpu_descriptor_heap = dh; + } + G.last_free_gpu_descriptor_heap = dh; + G.first_free_gpu_descriptor_heap = dh; + sys_mutex_unlock(&lock); } /* ========================== * * Plan * ========================== */ +struct dx12_plan { + struct dx12_plan *next_free; +}; + +INTERNAL struct dx12_plan *dx12_plan_alloc(void) +{ + return NULL; +} + struct gpu_handle gpu_plan_alloc(void) { - struct gpu_handle res = ZI; - return res; + struct dx12_plan *plan = dx12_plan_alloc(); + return handle_alloc(DX12_HANDLE_KIND_PLAN, plan); } void gpu_push_cmd(struct gpu_handle gpu_plan, struct gpu_cmd_params params) @@ -1096,66 +1428,293 @@ void gpu_submit_plan(struct gpu_handle gpu_plan) } /* ========================== * - * Dispatch + * Resource * ========================== */ -struct gpu_handle gpu_dispatch_state_alloc(void) +enum dx12_resource_view_flags { + DX12_RESOURCE_VIEW_FLAG_NONE = 0, + DX12_RESOURCE_VIEW_FLAG_CBV = (1 << 1), + DX12_RESOURCE_VIEW_FLAG_SRV = (1 << 2), + DX12_RESOURCE_VIEW_FLAG_UAV = (1 << 3), + DX12_RESOURCE_VIEW_FLAG_RTV = (1 << 4) +}; + +INTERNAL struct dx12_resource *dx12_resource_alloc(D3D12_HEAP_PROPERTIES heap_props, D3D12_HEAP_FLAGS heap_flags, D3D12_RESOURCE_DESC desc, D3D12_RESOURCE_STATES initial_state, enum dx12_resource_view_flags view_flags) { - struct gpu_handle res = ZI; - return res; + struct dx12_resource *r = NULL; + { + struct sys_lock lock = sys_mutex_lock_e(&G.resources_mutex); + if (G.first_free_resource) { + r = G.first_free_resource; + G.first_free_resource = r->next_free; + } else { + r = arena_push_no_zero(&G.resources_arena, struct dx12_resource); + } + sys_mutex_unlock(&lock); + } + MEMZERO_STRUCT(r); + + HRESULT hr = ID3D12Device_CreateCommittedResource(G.device, &heap_props, heap_flags, &desc, initial_state, NULL, &IID_ID3D12Resource, (void **)&r->resource); + if (FAILED(hr)) { + /* TODO: Don't panic */ + sys_panic(LIT("Failed to create resource")); + } + + r->state = initial_state; + + if (desc.Dimension == D3D12_RESOURCE_DIMENSION_BUFFER) { + r->gpu_address = ID3D12Resource_GetGPUVirtualAddress(r->resource); + } + + if (view_flags & DX12_RESOURCE_VIEW_FLAG_CBV) { + r->cbv_descriptor = dx12_descriptor_alloc(G.cbv_srv_uav_heap); + D3D12_CONSTANT_BUFFER_VIEW_DESC cbv_desc = ZI; + cbv_desc.BufferLocation = r->gpu_address; + //cbv_desc.SizeInBytes = desc.ByteWidth; + /* FIXME: Get actual size */ + cbv_desc.SizeInBytes = KILOBYTE(64); + ID3D12Device_CreateConstantBufferView(G.device, &cbv_desc, r->cbv_descriptor->handle); + } + if (view_flags & DX12_RESOURCE_VIEW_FLAG_SRV) { + r->srv_descriptor = dx12_descriptor_alloc(G.cbv_srv_uav_heap); + ID3D12Device_CreateShaderResourceView(G.device, r->resource, NULL, r->srv_descriptor->handle); + } + if (view_flags & DX12_RESOURCE_VIEW_FLAG_UAV) { + r->uav_descriptor = dx12_descriptor_alloc(G.cbv_srv_uav_heap); + ID3D12Device_CreateUnorderedAccessView(G.device, r->resource, NULL, NULL, r->uav_descriptor->handle); + } + if (view_flags & DX12_RESOURCE_VIEW_FLAG_RTV) { + r->rtv_descriptor = dx12_descriptor_alloc(G.rtv_heap); + ID3D12Device_CreateRenderTargetView(G.device, r->resource, NULL, r->rtv_descriptor->handle); + } + + return r; } -#if 0 - -INTERNAL void dx12_barrier(ID3D12CommandList *cl, struct dx12_resource *resource, enum D3D12_RESOURCE_STATES state) +INTERNAL enum D3D12_RESOURCE_STATES dx12_resource_barrier(ID3D12GraphicsCommandList *cl, struct dx12_resource *resource, enum D3D12_RESOURCE_STATES state) { + enum D3D12_RESOURCE_STATES old_state = resource->state; if (state != resource->state) { struct D3D12_RESOURCE_TRANSITION_BARRIER rtb = ZI; - rtb.pResource = resource->res; + rtb.pResource = resource->resource; rtb.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES; rtb.StateBefore = resource->state; rtb.StateAfter = state; struct D3D12_RESOURCE_BARRIER rb = ZI; rb.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION; - rb.Flags = + rb.Flags = 0; + rb.Transition = rtb; + + ID3D12GraphicsCommandList_ResourceBarrier(cl, 1, &rb); resource->state = state; } + return old_state; +} + +INTERNAL void dx12_resource_release(struct dx12_resource *t) +{ + (UNUSED)t; +} + +struct gpu_handle gpu_texture_alloc(enum gpu_texture_format format, u32 flags, struct v2i32 size, void *initial_data) +{ + LOCAL_PERSIST const DXGI_FORMAT formats[] = { + [GPU_TEXTURE_FORMAT_R8G8B8A8_UNORM] = DXGI_FORMAT_R8G8B8A8_UNORM, + [GPU_TEXTURE_FORMAT_R8G8B8A8_UNORM_SRGB] = DXGI_FORMAT_R8G8B8A8_UNORM_SRGB + }; + + DXGI_FORMAT dxgi_format = 0; + if (format < (i32)ARRAY_COUNT(formats)) { + dxgi_format = formats[format]; + } + if (format == 0) { + /* TODO: Don't panic */ + sys_panic(LIT("Tried to create texture with unknown format")); + } + + enum dx12_resource_view_flags view_flags = DX12_RESOURCE_VIEW_FLAG_SRV; + + D3D12_HEAP_PROPERTIES heap_props = { .Type = D3D12_HEAP_TYPE_DEFAULT }; + heap_props.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN; + heap_props.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN; + + D3D12_HEAP_FLAGS heap_flags = D3D12_HEAP_FLAG_CREATE_NOT_ZEROED; + + D3D12_RESOURCE_DESC desc = ZI; + desc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D; + desc.Alignment = 0; + desc.Width = size.x; + desc.Height = size.y; + desc.DepthOrArraySize = 1; + desc.MipLevels = 1; + desc.Format = dxgi_format; + desc.SampleDesc.Count = 1; + desc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN; + if (flags & GPU_TEXTURE_FLAG_TARGETABLE) { + desc.Flags |= D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET; + view_flags |= DX12_RESOURCE_VIEW_FLAG_RTV; + } + + D3D12_RESOURCE_STATES initial_state = D3D12_RESOURCE_STATE_COPY_DEST; + + struct dx12_resource *r = dx12_resource_alloc(heap_props, heap_flags, desc, initial_state, view_flags); + + (UNUSED)initial_data; + + return handle_alloc(DX12_HANDLE_KIND_RESOURCE, r); +} + +void gpu_texture_clear(struct gpu_handle target_resource, u32 clear_color) +{ + (UNUSED)target_resource; + (UNUSED)clear_color; +} + +struct v2i32 gpu_texture_get_size(struct gpu_handle resource) +{ + (UNUSED)resource; + struct v2i32 res = ZI; + return res; +} + +/* ========================== * + * Dispatch + * ========================== */ + +/* TODO: Move command list off of dispatch state */ +struct dx12_dispatch_state { + struct arena arena; + ID3D12CommandAllocator *ca_direct; + ID3D12GraphicsCommandList *cl_direct; +}; + +INTERNAL struct dx12_dispatch_state *dx12_dispatch_state_alloc(void) +{ + HRESULT hr = 0; + struct dx12_dispatch_state *ds = NULL; + { + struct arena arena = arena_alloc(MEGABYTE(64)); + ds = arena_push(&arena, struct dx12_dispatch_state); + ds->arena = arena; + } + + hr = ID3D12Device_CreateCommandAllocator(G.device, D3D12_COMMAND_LIST_TYPE_DIRECT, &IID_ID3D12CommandAllocator, (void **)&ds->ca_direct); + if (FAILED(hr)) { + sys_panic(LIT("Failed to create command allocator")); + } + + hr = ID3D12Device_CreateCommandList(G.device, 0, D3D12_COMMAND_LIST_TYPE_DIRECT, ds->ca_direct, NULL, &IID_ID3D12GraphicsCommandList, (void **)&ds->cl_direct); + if (FAILED(hr)) { + sys_panic(LIT("Failed to create command list")); + } + + hr = ID3D12GraphicsCommandList_Close(ds->cl_direct); + if (FAILED(hr)) { + sys_panic(LIT("Failed to close command list during initialization")); + } + + return ds; +} + +struct gpu_handle gpu_dispatch_state_alloc(void) +{ + struct dx12_dispatch_state *ds = dx12_dispatch_state_alloc(); + return handle_alloc(DX12_HANDLE_KIND_DISPATCH_STATE, ds); } void gpu_dispatch(struct gpu_handle gpu_dispatch_state, struct gpu_dispatch_params params) { - (UNUSED)gpu_dispatch_state; - (UNUSED)params; + HRESULT hr = 0; - struct pipeline_scope *pipeline_scope = pipeline_scope_begin(); - struct dx12_dispatch_state *dispatch_state = handle_get_date(gpu_dispatch_state, DX12_HANDLE_KIND_DISPATCH_STATE); - struct dx12_plan *plan = handle_get_data(dispatch_state->plan, DX12_HANDLE_KIND_PLAN); + /* Viewport */ + struct rect viewport = params.draw_target_viewport; + struct D3D12_VIEWPORT d3d12_viewport = ZI; + d3d12_viewport.TopLeftX = viewport.x; + d3d12_viewport.TopLeftY = viewport.y; + d3d12_viewport.Width = viewport.width; + d3d12_viewport.Height = viewport.height; + d3d12_viewport.MinDepth = 0.0f; + d3d12_viewport.MaxDepth = 1.0f; + + /* Scissor */ + D3D12_RECT d3d12_scissor = ZI; + d3d12_scissor.left = viewport.x; + d3d12_scissor.top = viewport.y; + d3d12_scissor.right = viewport.x + viewport.width; + d3d12_scissor.bottom = viewport.y + viewport.height; + + struct dx12_dispatch_state *dispatch_state = handle_get_data(gpu_dispatch_state, DX12_HANDLE_KIND_DISPATCH_STATE); + struct dx12_plan *plan = handle_get_data(params.plan, DX12_HANDLE_KIND_PLAN); + struct dx12_resource *target = handle_get_data(params.draw_target, DX12_HANDLE_KIND_RESOURCE); + + ID3D12CommandQueue *cq = G.cq_direct; + ID3D12CommandAllocator *ca = dispatch_state->ca_direct; + ID3D12GraphicsCommandList *cl = dispatch_state->cl_direct; + + /* FIXME: Use fence to ensure command allocator has finished execution on GPU before resetting */ + hr = ID3D12CommandAllocator_Reset(ca); + if (FAILED(hr)) { + sys_panic(LIT("Failed to reset command allocator")); + } + + hr = ID3D12GraphicsCommandList_Reset(cl, ca, NULL); + if (FAILED(hr)) { + sys_panic(LIT("Failed to reset command list")); + } + + /* Create temporary srv heap */ + struct dx12_gpu_descriptor_heap *temp_descriptor_heap = dx12_gpu_descriptor_heap_alloc(G.cbv_srv_uav_heap); /* Material pass */ { - struct pipeline *pipeline = dx12_get_pipeline(pipeline_scope, LIT("material")); + u32 instance_count = 0; + (UNUSED)plan; + + //struct pipeline *pipeline = dx12_get_pipeline(pipeline_scope, LIT("material")); + struct pipeline *pipeline = &G.test_pipeline; /* Bind pipeline */ - ID3D12CommandList_SetPipelineState(command_list, pipeline->pso); - ID3D12CommandList_SetGraphicsRootSignature(command_list, pipeline->rs); + ID3D12GraphicsCommandList_SetPipelineState(cl, pipeline->pso); + ID3D12GraphicsCommandList_SetGraphicsRootSignature(cl, pipeline->rootsig); - /* Bind resources */ - cl->SetGraphicsRootDescriptorTable(0, m_srvHeap->GetGPUDescriptorHandleForHeapStart()); + /* Bind constant buffer */ + /* TODO */ - /* Setup RS */ - cl->RSSetViewports(1, &m_viewport); - cl->RSSetScissorRects(1, &m_scissorRect); + /* Bind srv heap */ + ID3D12DescriptorHeap *heaps[] = { temp_descriptor_heap->heap }; + ID3D12GraphicsCommandList_SetDescriptorHeaps(cl, ARRAY_COUNT(heaps), heaps); + ID3D12GraphicsCommandList_SetGraphicsRootDescriptorTable(cl, 2, temp_descriptor_heap->gpu_handle); - // Indicate that the texture will be used as a render target - dx12_barrier(cl, target, D3D12_RESOURCE_STATE_RENDER_TARGET); - D3D12_RESOURCE_BARRIER barrier_start = dx12_barrier(target, D3D12_RESOURCE_STATE_RENDER_TARGET); - cl->ResourceBarrier(1, barrier_start); + /* Setup Rasterizer State */ + ID3D12GraphicsCommandList_RSSetViewports(cl, 1, &d3d12_viewport); + ID3D12GraphicsCommandList_RSSetScissorRects(cl, 1, &d3d12_scissor); + + /* Transition render target */ + enum D3D12_RESOURCE_STATES old_state = dx12_resource_barrier(cl, target, D3D12_RESOURCE_STATE_RENDER_TARGET); + ID3D12GraphicsCommandList_OMSetRenderTargets(cl, 1, &target->rtv_descriptor->handle, false, NULL); + //f32 clear_color[] = { 0.0f, 0.0f, 0.0f, 0.0f }; + //ID3D12GraphicsCommandList_ClearRenderTargetView(cl, rtvHandle, clearColor, 0, nullptr); + + /* Draw */ + ID3D12GraphicsCommandList_IASetPrimitiveTopology(cl, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST); + ID3D12GraphicsCommandList_IASetVertexBuffers(cl, 0, 1, &G.dummy_vertex_buffer_view); + ID3D12GraphicsCommandList_IASetIndexBuffer(cl, &G.quad_index_buffer_view); + ID3D12GraphicsCommandList_DrawIndexedInstanced(cl, 6, instance_count, 0, 0, 0); + + /* Reset render target */ + dx12_resource_barrier(cl, target, old_state); } - pipeline_scope_end(pipeline_scope); + /* Execute command list */ + hr = ID3D12GraphicsCommandList_Close(cl); + if (FAILED(hr)) { + sys_panic(LIT("Failed to close command list before execution")); + } + + dx12_gpu_descriptor_heap_release(temp_descriptor_heap, cq); #if 0 __prof; @@ -1174,7 +1733,7 @@ void gpu_dispatch(struct gpu_handle gpu_dispatch_state, struct gpu_dispatch_para d3d11_viewport.TopLeftY = viewport.y; ID3D11DeviceContext_RSSetViewports(G.devcon, 1, &d3d11_viewport); - struct dx12_buffer *final_tex = (struct dx12_buffer *)params.draw_target.v; + struct dx12_resource *final_tex = (struct dx12_resource *)params.draw_target.v; struct v2i32 final_tex_size = final_tex->size; /* Texture pass */ @@ -1182,15 +1741,15 @@ void gpu_dispatch(struct gpu_handle gpu_dispatch_state, struct gpu_dispatch_para __profscope(Texture pass); struct dx11_shader *shader = &G.shaders[DX11_SHADER_KIND_TEXTURE]; if (shader->valid) { - struct dx12_buffer *texture = NULL; + struct dx12_resource *texture = NULL; if (cmd->texture.texture.v) { /* Load texture if handle is set */ - texture = (struct dx12_buffer *)cmd->texture.texture.v; + texture = (struct dx12_resource *)cmd->texture.texture.v; } else if (cmd->texture.sprite.hash) { /* Otherwise load sprite */ struct sprite_texture *sprite_texture = sprite_texture_from_tag_async(sprite_scope, cmd->texture.sprite); if (sprite_texture->loaded) { - texture = (struct dx12_buffer *)sprite_texture->texture.v; + texture = (struct dx12_resource *)sprite_texture->texture.v; } } diff --git a/src/incbin.c b/src/incbin.c index 5f27606e..75f140bc 100644 --- a/src/incbin.c +++ b/src/incbin.c @@ -47,12 +47,12 @@ INTERNAL BOOL CALLBACK enum_func(HMODULE module, LPCWSTR type, LPCWSTR wstr_entr struct string _incbin_get(struct _incbin_rc_resource *inc) { - enum inc_state state = atomic_i32_eval(&inc->state); + enum _incbin_state state = atomic_i32_eval(&inc->state); if (state != INCBIN_STATE_SEARCHED) { struct arena_temp scratch = scratch_begin_no_conflict(); if (state == INCBIN_STATE_UNSEARCHED) { - enum inc_state v = atomic_i32_eval_compare_exchange(&inc->state, state, INCBIN_STATE_SEARCHING); + enum _incbin_state v = atomic_i32_eval_compare_exchange(&inc->state, state, INCBIN_STATE_SEARCHING); if (v == state) { /* Search RC file for the resource name */ struct string name_lower = string_lower(scratch.arena, inc->rc_name); diff --git a/src/math.h b/src/math.h index 8b0f31e0..806b762b 100644 --- a/src/math.h +++ b/src/math.h @@ -136,12 +136,12 @@ INLINE i64 math_fsign64(f64 f) INLINE u32 math_abs_i32(i32 v) { - return v * ((v >= 0) - (v < 0)); + return (u32)(v * ((v >= 0) - (v < 0))); } INLINE u64 math_abs_i64(i64 v) { - return v * ((v >= 0) - (v < 0)); + return (u64)(v * ((v >= 0) - (v < 0))); } /* ========================== * diff --git a/src/memory.c b/src/memory.c index 499460ef..1960d336 100644 --- a/src/memory.c +++ b/src/memory.c @@ -5,7 +5,6 @@ __attribute((section(".text.memcpy"))) void *memcpy(void *__restrict dst, const void *__restrict src, u64 n) { - /* TODO: Faster memcpy */ for (u64 i = 0; i < n; ++i) { ((u8 *)dst)[i] = ((u8 *)src)[i]; } @@ -15,7 +14,6 @@ void *memcpy(void *__restrict dst, const void *__restrict src, u64 n) __attribute((section(".text.memset"))) void *memset(void *dst, i32 c, u64 n) { - /* TODO: Faster memset */ for (u64 i = 0; i < n; ++i) { ((u8 *)dst)[i] = c; } diff --git a/src/phys.c b/src/phys.c index 604ac1ac..b043ce6b 100644 --- a/src/phys.c +++ b/src/phys.c @@ -46,7 +46,7 @@ void phys_create_and_update_contacts(struct phys_step_ctx *ctx, f32 elapsed_dt, struct space_iter iter = space_iter_begin_aabb(space, aabb); struct space_entry *space_entry; - while ((space_entry = space_iter_next(&iter))) { + while ((space_entry = space_iter_next(&iter)) != NULL) { struct sim_ent *check1 = sim_ent_from_id(ss, space_entry->ent); if (!sim_ent_is_valid_and_active(check1)) continue; if (!(sim_ent_has_prop(check1, SEPROP_SOLID) || sim_ent_has_prop(check1, SEPROP_SENSOR))) continue; @@ -1191,7 +1191,7 @@ f32 phys_determine_earliest_toi(struct phys_step_ctx *ctx, f32 step_dt, f32 tole struct space_iter iter = space_iter_begin_aabb(space, combined_aabb); struct space_entry *entry; - while ((entry = space_iter_next(&iter))) { + while ((entry = space_iter_next(&iter)) != NULL) { struct sim_ent *e1 = sim_ent_from_id(ss, entry->ent); if (!sim_ent_should_simulate(e1)) continue; if (!(sim_ent_has_prop(e1, SEPROP_SOLID) || sim_ent_has_prop(e1, SEPROP_SENSOR))) continue; diff --git a/src/playback_wasapi.c b/src/playback_wasapi.c index 9e7d66c6..23ffcb34 100644 --- a/src/playback_wasapi.c +++ b/src/playback_wasapi.c @@ -12,6 +12,23 @@ #include "atomic.h" #include "app.h" + + + + + +void bla(void); +void bla(void) +{ + (UNUSED)bla; + DEBUGBREAKABLE; +} +#define NTDDI_WIN11_DT 0 + + + + + #define COBJMACROS #define WIN32_LEAN_AND_MEAN #define UNICODE diff --git a/src/sim_step.c b/src/sim_step.c index 29960493..8d54c610 100644 --- a/src/sim_step.c +++ b/src/sim_step.c @@ -262,7 +262,7 @@ INTERNAL void test_spawn_entities2(struct sim_ent *parent, struct v2 pos) e->sprite = sprite_tag_from_path(LIT("sprite/box.ase")); e->layer = SIM_LAYER_SHOULDERS; - e->sprite_tint = ALPHA_F(COLOR_BLUE, 0.75); + e->sprite_tint = ALPHA32_F(COLOR_BLUE, 0.75); sim_ent_enable_prop(e, SEPROP_SOLID); struct quad collider_quad = quad_from_rect(RECT(-0.5, -0.5, 1, 1)); @@ -344,7 +344,7 @@ INTERNAL void test_spawn_entities4(struct sim_ent *parent, struct v2 pos) sim_ent_enable_prop(e, SEPROP_LIGHT_TEST); - e->sprite_tint = RGB_F(1, 0, 1); + e->sprite_tint = RGB32_F(1, 0, 1); } INTERNAL void test_spawn_tile(struct sim_snapshot *world, struct v2 world_pos) @@ -740,7 +740,7 @@ INTERNAL PHYS_COLLISION_CALLBACK_FUNC_DEF(on_collision, data, step_ctx) struct xform xf = XFORM_TRS(.t = point, .r = rand_f64_from_state(&step_ctx->rand, 0, TAU)); struct sim_ent *decal = sim_ent_alloc_sync_src(root); decal->sprite = sprite_tag_from_path(LIT("sprite/blood.ase")); - decal->sprite_tint = RGBA_F(1, 1, 1, 0.25f); + decal->sprite_tint = RGBA32_F(1, 1, 1, 0.25f); decal->layer = SIM_LAYER_FLOOR_DECALS; sim_ent_set_xform(decal, xf); diff --git a/src/sprite.c b/src/sprite.c index 51617107..335e4fc0 100644 --- a/src/sprite.c +++ b/src/sprite.c @@ -463,7 +463,7 @@ INTERNAL struct sprite_sheet init_sheet_from_ase_result(struct arena *arena, str span->start = ase_span->start; span->end = ase_span->end; u64 hash = hash_fnv64(HASH_FNV64_BASIS, name); - dict_set(arena, &sheet.spans_dict, hash, span); + dict_set(arena, &sheet.spans_dict, hash, (u64)span); ++index; } } @@ -498,11 +498,11 @@ INTERNAL struct sprite_sheet init_sheet_from_ase_result(struct arena *arena, str for (struct ase_slice_key *ase_slice_key = ase.slice_key_head; ase_slice_key; ase_slice_key = ase_slice_key->next) { struct string name = ase_slice_key->name; u64 hash = hash_fnv64(HASH_FNV64_BASIS, name); - struct temp_slice_group_node *temp_slice_group_node = dict_get(&temp_slice_dict, hash); + struct temp_slice_group_node *temp_slice_group_node = (struct temp_slice_group_node *)dict_get(&temp_slice_dict, hash); if (!temp_slice_group_node) { temp_slice_group_node = arena_push(scratch.arena, struct temp_slice_group_node); temp_slice_group_node->name = name; - dict_set(scratch.arena, &temp_slice_dict, hash, temp_slice_group_node); + dict_set(scratch.arena, &temp_slice_dict, hash, (u64)temp_slice_group_node); ++num_temp_slice_group_nodes; temp_slice_group_node->next = temp_slice_group_head; @@ -586,7 +586,7 @@ INTERNAL struct sprite_sheet init_sheet_from_ase_result(struct arena *arena, str temp_slice_group_node->final_slice_group = slice_group; u64 hash = hash_fnv64(HASH_FNV64_BASIS, slice_group->name); - dict_set(arena, &sheet.slice_groups_dict, hash, slice_group); + dict_set(arena, &sheet.slice_groups_dict, hash, (u64)slice_group); ++index; } @@ -635,7 +635,7 @@ INTERNAL struct sprite_sheet init_sheet_from_ase_result(struct arena *arena, str struct string point_slice_name = ray_slice_name; point_slice_name.len -= ray_suffix.len; u64 hash = hash_fnv64(HASH_FNV64_BASIS, point_slice_name); - struct sprite_sheet_slice_group *point_slice_group = dict_get(&sheet.slice_groups_dict, hash); + struct sprite_sheet_slice_group *point_slice_group = (struct sprite_sheet_slice_group *)dict_get(&sheet.slice_groups_dict, hash); if (point_slice_group) { u32 point_slices_per_frame = point_slice_group->per_frame_count; @@ -1082,7 +1082,7 @@ struct sprite_sheet_span sprite_sheet_get_span(struct sprite_sheet *sheet, struc struct sprite_sheet_span res = ZI; if (sheet->spans_count > 0) { u64 hash = hash_fnv64(HASH_FNV64_BASIS, name); - struct sprite_sheet_span *entry = dict_get(&sheet->spans_dict, hash); + struct sprite_sheet_span *entry = (struct sprite_sheet_span *)dict_get(&sheet->spans_dict, hash); if (entry) { res = *entry; } @@ -1094,7 +1094,7 @@ struct sprite_sheet_slice sprite_sheet_get_slice(struct sprite_sheet *sheet, str { if (sheet->slice_groups_count > 0) { u64 hash = hash_fnv64(HASH_FNV64_BASIS, name); - struct sprite_sheet_slice_group *group = dict_get(&sheet->slice_groups_dict, hash); + struct sprite_sheet_slice_group *group = (struct sprite_sheet_slice_group *)dict_get(&sheet->slice_groups_dict, hash); if (group) { return group->frame_slices[frame_index * group->per_frame_count]; } @@ -1120,7 +1120,7 @@ struct sprite_sheet_slice_array sprite_sheet_get_slices(struct sprite_sheet *she struct sprite_sheet_slice_array res = ZI; if (sheet->slice_groups_count > 0) { u64 hash = hash_fnv64(HASH_FNV64_BASIS, name); - struct sprite_sheet_slice_group *group = dict_get(&sheet->slice_groups_dict, hash); + struct sprite_sheet_slice_group *group = (struct sprite_sheet_slice_group *)dict_get(&sheet->slice_groups_dict, hash); if (group) { res.count = group->per_frame_count; res.slices = &group->frame_slices[frame_index * group->per_frame_count]; diff --git a/src/tar.c b/src/tar.c index 8b296d80..ce7f34ce 100644 --- a/src/tar.c +++ b/src/tar.c @@ -133,7 +133,7 @@ struct tar_archive tar_parse(struct arena *arena, struct string data, struct str archive.lookup = dict_init(arena, (u64)((f64)num_files * ARCHIVE_LOOKUP_TABLE_CAPACITY_FACTOR)); for (struct tar_entry *entry = archive.head; entry; entry = entry->next) { u64 hash = hash_fnv64(HASH_FNV64_BASIS, entry->file_name); - dict_set(arena, &archive.lookup, hash, entry); + dict_set(arena, &archive.lookup, hash, (u64)entry); } /* Build hierarchy */ @@ -147,7 +147,7 @@ struct tar_archive tar_parse(struct arena *arena, struct string data, struct str for (struct string parent_dir_name = entry->file_name; parent_dir_name.len > 0; --parent_dir_name.len) { if (parent_dir_name.text[parent_dir_name.len - 1] == '/') { u64 hash = hash_fnv64(HASH_FNV64_BASIS, parent_dir_name); - parent_entry = dict_get(&archive.lookup, hash); + parent_entry = (struct tar_entry *)dict_get(&archive.lookup, hash); break; } } @@ -165,5 +165,5 @@ struct tar_archive tar_parse(struct arena *arena, struct string data, struct str struct tar_entry *tar_get(struct tar_archive *archive, struct string name) { u64 hash = hash_fnv64(HASH_FNV64_BASIS, name); - return dict_get(&archive->lookup, hash); + return (struct tar_entry *)dict_get(&archive->lookup, hash); } diff --git a/src/ttf_dwrite.cpp b/src/ttf_dwrite.cpp index 2f20e556..ed203016 100644 --- a/src/ttf_dwrite.cpp +++ b/src/ttf_dwrite.cpp @@ -76,8 +76,8 @@ struct ttf_startup_receipt ttf_startup(void) struct ttf_decode_result ttf_decode(struct arena *arena, struct string encoded, f32 point_size, u32 *cache_codes, u32 cache_codes_count) { - COLORREF bg_color = RGB(0,0,0); - COLORREF fg_color = RGB(255,255,255); + COLORREF bg_color = RGB32(0,0,0); + COLORREF fg_color = RGB32(255,255,255); IDWriteFactory5 *factory = G.factory; @@ -259,7 +259,7 @@ struct ttf_decode_result ttf_decode(struct arena *arena, struct string encoded, u64 in_x = (u64)bounding_box.left + x; u32 *out_pixel = out_data + (out_x + (out_y * atlas_w)); u32 *in_pixel = in_data + (in_x + (in_y * in_pitch)); - *out_pixel = RGBA(0xFF, 0xFF, 0xFF, *in_pixel & 0xFF); + *out_pixel = RGBA32(0xFF, 0xFF, 0xFF, *in_pixel & 0xFF); } } out_offset_x += tex_w; diff --git a/src/user.c b/src/user.c index 0d322b3b..b2c596ce 100644 --- a/src/user.c +++ b/src/user.c @@ -352,7 +352,7 @@ INTERNAL void debug_draw_xform(struct xform xf, u32 color_x, u32 color_y) draw_arrow_ray(G.user_gpu_plan, pos, x_ray, thickness, arrowhead_len, color_x); draw_arrow_ray(G.user_gpu_plan, pos, y_ray, thickness, arrowhead_len, color_y); - //u32 color_quad = RGBA_F(0, 1, 1, 0.3); + //u32 color_quad = RGBA32_F(0, 1, 1, 0.3); //struct quad quad = quad_from_rect(RECT(0, 0, 1, -1)); //quad = xform_mul_quad(xf, quad_scale(quad, 0.075f)); //draw_quad(G.user_gpu_plan, quad, color); @@ -506,16 +506,16 @@ INTERNAL void draw_debug_console(i32 level, b32 minimized) LOCAL_PERSIST u32 colors[LOG_LEVEL_COUNT][2] = ZI; MEMSET(colors, 0xFF, sizeof(colors)); #if 1 - colors[LOG_LEVEL_DEBUG][0] = RGB_F(0.4, 0.1, 0.4); colors[LOG_LEVEL_DEBUG][1] = RGB_F(0.5, 0.2, 0.5); - colors[LOG_LEVEL_INFO][0] = RGB_F(0.4, 0.4, 0.4); colors[LOG_LEVEL_INFO][1] = RGB_F(0.5, 0.5, 0.5); - colors[LOG_LEVEL_SUCCESS][0] = RGB_F(0.1, 0.3, 0.1); colors[LOG_LEVEL_SUCCESS][1] = RGB_F(0.2, 0.4, 0.2); - colors[LOG_LEVEL_WARNING][0] = RGB_F(0.4, 0.4, 0.1); colors[LOG_LEVEL_WARNING][1] = RGB_F(0.5, 0.5, 0.2); - colors[LOG_LEVEL_ERROR][0] = RGB_F(0.4, 0.1, 0.1); colors[LOG_LEVEL_ERROR][1] = RGB_F(0.5, 0.2, 0.2); + colors[LOG_LEVEL_DEBUG][0] = RGB32_F(0.4, 0.1, 0.4); colors[LOG_LEVEL_DEBUG][1] = RGB32_F(0.5, 0.2, 0.5); + colors[LOG_LEVEL_INFO][0] = RGB32_F(0.4, 0.4, 0.4); colors[LOG_LEVEL_INFO][1] = RGB32_F(0.5, 0.5, 0.5); + colors[LOG_LEVEL_SUCCESS][0] = RGB32_F(0.1, 0.3, 0.1); colors[LOG_LEVEL_SUCCESS][1] = RGB32_F(0.2, 0.4, 0.2); + colors[LOG_LEVEL_WARNING][0] = RGB32_F(0.4, 0.4, 0.1); colors[LOG_LEVEL_WARNING][1] = RGB32_F(0.5, 0.5, 0.2); + colors[LOG_LEVEL_ERROR][0] = RGB32_F(0.4, 0.1, 0.1); colors[LOG_LEVEL_ERROR][1] = RGB32_F(0.5, 0.2, 0.2); #else - u32 info_colors[2] = { RGB_F(0.4, 0.4, 0.4), RGB_F(0.5, 0.5, 0.5) }; - u32 success_colors[2] = { RGB_F(0.1, 0.3, 0.1), RGB_F(0.2, 0.4, 0.2) }; - u32 warning_colors[2] = { RGB_F(0.4, 0.4, 0.1), RGB_F(0.5, 0.5, 0.2) }; - u32 error_colors[2] = { RGB_F(0.4, 0.1, 0.1), RGB_F(0.5, 0.2, 0.2) }; + u32 info_colors[2] = { RGB32_F(0.4, 0.4, 0.4), RGB32_F(0.5, 0.5, 0.5) }; + u32 success_colors[2] = { RGB32_F(0.1, 0.3, 0.1), RGB32_F(0.2, 0.4, 0.2) }; + u32 warning_colors[2] = { RGB32_F(0.4, 0.4, 0.1), RGB32_F(0.5, 0.5, 0.2) }; + u32 error_colors[2] = { RGB32_F(0.4, 0.1, 0.1), RGB32_F(0.5, 0.2, 0.2) }; #endif struct v2 draw_pos = desired_start_pos; @@ -542,7 +542,7 @@ INTERNAL void draw_debug_console(i32 level, b32 minimized) if (log->level <= level) { /* Draw background */ u32 color = colors[log->level][log->color_index]; - draw_quad(G.user_gpu_plan, quad_from_rect(log->bounds), ALPHA_F(color, opacity)); + draw_quad(G.user_gpu_plan, quad_from_rect(log->bounds), ALPHA32_F(color, opacity)); /* Draw text */ struct string text = log->msg; @@ -558,7 +558,7 @@ INTERNAL void draw_debug_console(i32 level, b32 minimized) FMT_STR(text)); } - struct draw_text_params params = DRAW_TEXT_PARAMS(.font = font, .pos = draw_pos, .offset_y = DRAW_TEXT_OFFSET_Y_BOTTOM, .color = ALPHA_F(COLOR_WHITE, opacity), .str = text); + struct draw_text_params params = DRAW_TEXT_PARAMS(.font = font, .pos = draw_pos, .offset_y = DRAW_TEXT_OFFSET_Y_BOTTOM, .color = ALPHA32_F(COLOR_WHITE, opacity), .str = text); struct rect bounds = draw_text(G.user_gpu_plan, params); struct rect draw_bounds = bounds; @@ -832,7 +832,7 @@ INTERNAL void user_update(void) struct collider_shape mouse_shape = ZI; mouse_shape.points[0] = V2(0, 0); mouse_shape.count = 1; - mouse_shape.radius = 0.01; + mouse_shape.radius = 0.01f; for (u64 ent_index = 0; ent_index < G.ss_blended->num_ents_reserved; ++ent_index) { struct sim_ent *ent = &G.ss_blended->ents[ent_index]; if (!sim_ent_is_valid_and_active(ent)) continue; @@ -944,7 +944,7 @@ INTERNAL void user_update(void) G.user_screen_offset = V2(0, 0); } else { /* Determine ui size by camera & window dimensions */ - f32 aspect_ratio = DEFAULT_CAMERA_WIDTH / DEFAULT_CAMERA_HEIGHT; + f32 aspect_ratio = (f32)(DEFAULT_CAMERA_WIDTH / DEFAULT_CAMERA_HEIGHT); if (local_camera->valid) { struct xform quad_xf = xform_mul(sim_ent_get_xform(local_camera), local_camera->camera_quad_xform); struct v2 camera_size = xform_get_scale(quad_xf); @@ -1063,9 +1063,9 @@ INTERNAL void user_update(void) struct v2 pos = xform_invert_mul_v2(G.world_to_user_xf, V2(0, 0)); struct v2 size = xform_basis_invert_mul_v2(G.world_to_user_xf, G.user_size); - u32 color0 = RGBA_F(0.17f, 0.17f, 0.17f, 1.f); - u32 color1 = RGBA_F(0.15f, 0.15f, 0.15f, 1.f); - draw_grid(G.world_gpu_plan, xform_from_rect(RECT_FROM_V2(pos, size)), color0, color1, RGBA(0x3f, 0x3f, 0x3f, 0xFF), COLOR_RED, COLOR_GREEN, thickness, spacing, offset); + u32 color0 = RGBA32_F(0.17f, 0.17f, 0.17f, 1.f); + u32 color1 = RGBA32_F(0.15f, 0.15f, 0.15f, 1.f); + draw_grid(G.world_gpu_plan, xform_from_rect(RECT_FROM_V2(pos, size)), color0, color1, RGBA32(0x3f, 0x3f, 0x3f, 0xFF), COLOR_RED, COLOR_GREEN, thickness, spacing, offset); } /* ========================== * @@ -1256,8 +1256,8 @@ INTERNAL void user_update(void) } f32 thickness = 0.01f; - u32 color_start = RGBA_F(1, 0.5, 0, opacity_a); - u32 color_end = RGBA_F(1, 0.8, 0.4, opacity_b); + u32 color_start = RGBA32_F(1, 0.5, 0, opacity_a); + u32 color_end = RGBA32_F(1, 0.8, 0.4, opacity_b); if (opacity_b > 0.99f) { draw_circle(G.world_gpu_plan, b, thickness / 2, color_end, 20); @@ -1317,8 +1317,8 @@ INTERNAL void user_update(void) /* Draw xform */ if (!skip_debug_draw_transform) { - u32 color_x = RGBA_F(1, 0, 0, 0.5); - u32 color_y = RGBA_F(0, 1, 0, 0.5); + u32 color_x = RGBA32_F(1, 0, 0, 0.5); + u32 color_y = RGBA32_F(0, 1, 0, 0.5); debug_draw_xform(xf, color_x, color_y); } @@ -1326,7 +1326,7 @@ INTERNAL void user_update(void) if (ent->local_collider.count > 0) { struct aabb aabb = collider_aabb_from_collider(&ent->local_collider, xf); f32 thickness = 1; - u32 color = RGBA_F(1, 0, 1, 0.5); + u32 color = RGBA32_F(1, 0, 1, 0.5); struct quad quad = quad_from_aabb(aabb); quad = xform_mul_quad(G.world_to_user_xf, quad); draw_quad_line(G.user_gpu_plan, quad, thickness, color); @@ -1340,7 +1340,7 @@ INTERNAL void user_update(void) start = xform_mul_v2(G.world_to_user_xf, start); struct v2 end = v2_add(xf.og, ent->control.focus); end = xform_mul_v2(G.world_to_user_xf, end); - draw_arrow_line(G.user_gpu_plan, start, end, 3, 10, RGBA_F(1, 1, 1, 0.5)); + draw_arrow_line(G.user_gpu_plan, start, end, 3, 10, RGBA32_F(1, 1, 1, 0.5)); } #if 0 @@ -1348,9 +1348,9 @@ INTERNAL void user_update(void) if (!sprite_tag_is_nil(ent->sprite)) { struct sprite_sheet *sheet = sprite_sheet_from_tag_async(sprite_frame_scope, sprite); - u32 quad_color = RGBA_F(1, 0, 0.5, 1); - u32 point_color = RGBA_F(1, 0, 0, 1); - u32 ray_color = RGBA_F(1, 0, 0.5, 1); + u32 quad_color = RGBA32_F(1, 0, 0.5, 1); + u32 point_color = RGBA32_F(1, 0, 0, 1); + u32 ray_color = RGBA32_F(1, 0, 0.5, 1); for (u64 i = 0; i < sheet->slice_groups_count; ++i) { struct sprite_sheet_slice_group *group = &sheet->slice_groups[i]; @@ -1414,7 +1414,7 @@ INTERNAL void user_update(void) /* Draw collider */ if (ent->local_collider.count > 0) { struct collider_shape collider = ent->local_collider; - u32 color = RGBA_F(1, 1, 0, 0.5); + u32 color = RGBA32_F(1, 1, 0, 0.5); f32 thickness = 2; { /* Draw collider using support points */ @@ -1460,7 +1460,7 @@ INTERNAL void user_update(void) { f32 radius = 5; for (u32 i = 0; i < data->num_points; ++i) { - u32 color = (data->skip_solve || data->wrong_dir) ? ALPHA_F(COLOR_YELLOW, 0.3) : RGBA_F(0.8, 0.2, 0.2, 1); + u32 color = (data->skip_solve || data->wrong_dir) ? ALPHA32_F(COLOR_YELLOW, 0.3) : RGBA32_F(0.8, 0.2, 0.2, 1); struct phys_contact_point point = data->points[i]; struct v2 dbg_pt = point.dbg_pt; @@ -1531,7 +1531,7 @@ INTERNAL void user_update(void) #if 0 { f32 radius = 4; - u32 color = RGBA_F(1, 1, 0, 0.5); + u32 color = RGBA32_F(1, 1, 0, 0.5); struct v2 a = xform_mul_v2(G.world_to_user_xf, data->closest0); struct v2 b = xform_mul_v2(G.world_to_user_xf, data->closest1); draw_circle(G.user_gpu_plan, a, radius, color, 10); @@ -1543,12 +1543,12 @@ INTERNAL void user_update(void) { f32 thickness = 4; f32 radius = 4; - u32 color_line = RGBA_F(1, 0, 1, 0.75); - u32 color_a = RGBA_F(1, 0, 0, 0.25); - u32 color_b = RGBA_F(0, 1, 0, 0.25); - u32 color_line_clipped = RGBA_F(1, 0, 1, 1); - u32 color_a_clipped = RGBA_F(1, 0, 0, 1); - u32 color_b_clipped = RGBA_F(0, 1, 0, 1); + u32 color_line = RGBA32_F(1, 0, 1, 0.75); + u32 color_a = RGBA32_F(1, 0, 0, 0.25); + u32 color_b = RGBA32_F(0, 1, 0, 0.25); + u32 color_line_clipped = RGBA32_F(1, 0, 1, 1); + u32 color_a_clipped = RGBA32_F(1, 0, 0, 1); + u32 color_b_clipped = RGBA32_F(0, 1, 0, 1); { struct v2 a = xform_mul_v2(G.world_to_user_xf, collider_res.a0); struct v2 b = xform_mul_v2(G.world_to_user_xf, collider_res.b0); @@ -1622,7 +1622,7 @@ INTERNAL void user_update(void) /* Draw menkowski */ { - u32 color = collider_res.solved ? RGBA_F(0, 0, 0.25, 1) : RGBA_F(0, 0.25, 0.25, 1); + u32 color = collider_res.solved ? RGBA32_F(0, 0, 0.25, 1) : RGBA32_F(0, 0.25, 0.25, 1); f32 thickness = 2; u32 detail = 512; (UNUSED)thickness; @@ -1636,7 +1636,7 @@ INTERNAL void user_update(void) /* Draw cloud */ { - u32 color = RGBA_F(1, 1, 1, 1); + u32 color = RGBA32_F(1, 1, 1, 1); f32 radius = 2; struct v2_array m = cloud(temp.arena, &e0_collider, &e1_collider, e0_xf, e1_xf); @@ -1650,7 +1650,7 @@ INTERNAL void user_update(void) /* Draw prototype */ { f32 thickness = 2; - u32 color = RGBA_F(1, 1, 1, 0.25); + u32 color = RGBA32_F(1, 1, 1, 0.25); struct v2_array m = { .points = collider_res.prototype.points, @@ -1665,9 +1665,9 @@ INTERNAL void user_update(void) { f32 thickness = 2; u32 line_color = COLOR_YELLOW; - u32 color_first = RGBA_F(1, 0, 0, 0.75); - u32 color_second = RGBA_F(0, 1, 0, 0.75); - u32 color_third = RGBA_F(0, 0, 1, 0.75); + u32 color_first = RGBA32_F(1, 0, 0, 0.75); + u32 color_second = RGBA32_F(0, 1, 0, 0.75); + u32 color_third = RGBA32_F(0, 0, 1, 0.75); struct collider_menkowski_simplex simplex = collider_res.simplex; struct v2 simplex_points[] = { simplex.a.p, simplex.b.p, simplex.c.p }; @@ -1708,7 +1708,7 @@ INTERNAL void user_update(void) /* Draw hierarchy */ if (sim_ent_has_prop(parent, SEPROP_ACTIVE) && !parent->is_root) { - u32 color = RGBA_F(0.6, 0.6, 1, 0.75); + u32 color = RGBA32_F(0.6, 0.6, 1, 0.75); f32 thickness = 2; f32 arrow_height = 15; @@ -1719,7 +1719,7 @@ INTERNAL void user_update(void) /* Draw camera rect */ if (sim_ent_has_prop(ent, SEPROP_CAMERA)) { - u32 color = ent == local_camera ? RGBA_F(1, 1, 1, 0.5) : RGBA_F(0, 0.75, 0, 0.5); + u32 color = ent == local_camera ? RGBA32_F(1, 1, 1, 0.5) : RGBA32_F(0, 0.75, 0, 0.5); f32 thickness = 3; struct xform quad_xf = xform_mul(xf, ent->camera_quad_xform); @@ -2111,29 +2111,27 @@ INTERNAL void user_update(void) /* Clear textures */ gpu_texture_clear(G.user_texture, 0); - gpu_texture_clear(G.backbuffer_texture, RGBA_F(0, 0, 0, 1)); + gpu_texture_clear(G.backbuffer_texture, RGBA32_F(0, 0, 0, 1)); /* Render to user texture */ { - struct gpu_handle *plans[] = { &G.world_gpu_plan, &G.user_gpu_plan }; struct gpu_dispatch_params params = ZI; - params.plans.handles = plans; - params.plans.count = ARRAY_COUNT(plans); + params.plan = G.world_gpu_plan; params.draw_target = G.user_texture; params.draw_target_viewport = user_viewport; gpu_dispatch(G.user_dispatch_state, params); } +#if 0 /* Render to backbuffer texture */ { - struct gpu_handle *plans[] = { &G.backbuffer_gpu_plan }; struct gpu_dispatch_params params = ZI; - params.plans.handles = plans; - params.plans.count = ARRAY_COUNT(plans); + params.plan = G.backbuffer_gpu_plan; params.draw_target = G.backbuffer_texture; params.draw_target_viewport = backbuffer_viewport; gpu_dispatch(G.backbuffer_dispatch_state, params); } +#endif /* Swap backbuffer */ gpu_swap_backbuffer(VSYNC_ENABLED);