From 99431ebdfa02ce0bb76f589ee1dfe425d02518bf Mon Sep 17 00:00:00 2001 From: jacob Date: Wed, 18 Jun 2025 20:48:09 -0500 Subject: [PATCH] move shader structs into shared header --- res/sh/common.hlsl | 2 + res/sh/material.hlsl | 13 --- res/sh/sh_common.h | 73 +++++++++++++++ src/gpu_dx11.c | 3 - src/gpu_dx12.c | 219 ++++++++++++++----------------------------- 5 files changed, 145 insertions(+), 165 deletions(-) create mode 100644 res/sh/sh_common.h diff --git a/res/sh/common.hlsl b/res/sh/common.hlsl index b220cf9a..a12dec72 100644 --- a/res/sh/common.hlsl +++ b/res/sh/common.hlsl @@ -1,3 +1,5 @@ +#include "sh/sh_common.h" + #define DECL(t, n) t n : n #define PI 3.14159265359 diff --git a/res/sh/material.hlsl b/res/sh/material.hlsl index e5c4eb81..6ede562f 100644 --- a/res/sh/material.hlsl +++ b/res/sh/material.hlsl @@ -1,18 +1,5 @@ #include "sh/common.hlsl" -struct sh_material_constants { - float4x4 projection; - uint instance_offset; -}; - -struct sh_material_instance { - float2x3 xf; - float2 uv0; - float2 uv1; - uint tint_srgb; - float emittance; -}; - /* ========================== * * Root Signature * ========================== */ diff --git a/res/sh/sh_common.h b/res/sh/sh_common.h new file mode 100644 index 00000000..ef254d85 --- /dev/null +++ b/res/sh/sh_common.h @@ -0,0 +1,73 @@ +#if SH_CPU + +/* ========================== * + * CPU + * ========================== */ + +#define SH_STRUCT(s) PACK(struct s) +#define SH_DECL(t, n) struct CAT(sh_, t) n + + +struct sh_uint { u32 v; }; +INLINE struct sh_uint sh_uint_from_u32(u32 v) +{ + return (struct sh_uint) { .v = v }; +} + +struct sh_float { f32 v; }; +INLINE struct sh_float sh_float_from_f32(f32 v) +{ + return (struct sh_float) { .v = v }; +} + +struct sh_float2 { f32 v[2]; }; +INLINE struct sh_float2 sh_float2_from_v2(struct v2 v) +{ + return (struct sh_float2) { .v[0] = v.x, .v[1] = v.y }; +} + +struct sh_float4x4 { f32 v[4][4]; }; +INLINE struct sh_float4x4 sh_float4x4_from_mat4x4(struct mat4x4 v) +{ + struct sh_float4x4 res; + CT_ASSERT(sizeof(res) == sizeof(v)); + MEMCPY(&res, v.e, sizeof(res)); + return res; +} + +struct sh_float2x3 { f32 v[2][3]; }; +INLINE struct sh_float2x3 sh_float2x3_from_xform(struct xform v) +{ + struct sh_float2x3 res; + CT_ASSERT(sizeof(res) == sizeof(v)); + MEMCPY(&res, &v, sizeof(res)); + return res; +} + +#else + +/* ========================== * + * GPU + * ========================== */ + +#define SH_STRUCT(s) struct s +#define SH_DECL(t, n) t n + +#endif + +/* ========================== * + * Material shader structs + * ========================== */ + +SH_STRUCT(sh_material_constants { + SH_DECL(float4x4, projection); + SH_DECL(uint, instance_offset); +}); + +SH_STRUCT(sh_material_instance { + SH_DECL(float2x3, xf); + SH_DECL(float2, uv0); + SH_DECL(float2, uv1); + SH_DECL(uint, tint_srgb); + SH_DECL(float, emittance); +}); diff --git a/src/gpu_dx11.c b/src/gpu_dx11.c index de1d0a05..e0bc51ce 100644 --- a/src/gpu_dx11.c +++ b/src/gpu_dx11.c @@ -1767,7 +1767,6 @@ void gpu_dispatch(struct gpu_dispatch_params params) /* 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 */ @@ -1816,7 +1815,6 @@ void gpu_dispatch(struct gpu_dispatch_params params) /* 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 */ @@ -1864,7 +1862,6 @@ void gpu_dispatch(struct gpu_dispatch_params params) /* 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 */ diff --git a/src/gpu_dx12.c b/src/gpu_dx12.c index 092dcba4..eeafbbd5 100644 --- a/src/gpu_dx12.c +++ b/src/gpu_dx12.c @@ -12,6 +12,10 @@ #include "resource.h" #include "atomic.h" +/* Include common shader types */ +#define SH_CPU 1 +#include "../res/sh/sh_common.h" + #pragma warning(push, 0) # define UNICODE # define COBJMACROS @@ -28,9 +32,6 @@ #pragma comment(lib, "dxguid") #pragma comment(lib, "d3dcompiler") -#define SH_CPU 1 -#define VT lpVtbl - //#define DX12_WAIT_FRAME_LATENCY 1 //#define DX12_SWAPCHAIN_FLAGS ((DX12_ALLOW_TEARING * DXGI_SWAP_CHAIN_FLAG_ALLOW_TEARING) | (DX12_WAIT_FRAME_LATENCY * DXGI_SWAP_CHAIN_FLAG_FRAME_LATENCY_WAITABLE_OBJECT)) @@ -242,10 +243,8 @@ GLOBAL struct { /* Swapchain */ u32 swapchain_frame_index; - ID3D12CommandAllocator *swapchain_ca; IDXGISwapChain3 *swapchain; - ID3D12DescriptorHeap *swapchain_rtv_heap; - ID3D12Resource *swapchain_buffers[DX12_SWAPCHAIN_BUFFER_COUNT]; + struct dx12_resource *swapchain_resources[DX12_SWAPCHAIN_BUFFER_COUNT]; /* Dummy vertex buffer */ struct dx12_resource *dummy_vertex_buffer; @@ -266,6 +265,8 @@ INTERNAL void dx12_init_pipelines(void); INTERNAL struct cpu_descriptor_heap *cpu_descriptor_heap_alloc(enum D3D12_DESCRIPTOR_HEAP_TYPE type); INTERNAL struct command_queue *command_queue_alloc(enum D3D12_COMMAND_LIST_TYPE type, enum D3D12_COMMAND_QUEUE_PRIORITY priority); INTERNAL void command_queue_release(struct command_queue *cq); +INTERNAL struct dx12_resource *dx12_resource_alloc_from_swapchain_buffer(ID3D12Resource *buff); +INTERNAL void dx12_resource_release(struct dx12_resource *resource); struct gpu_startup_receipt gpu_startup(struct work_startup_receipt *work_sr, struct sys_window *window) { @@ -364,12 +365,10 @@ INTERNAL APP_EXIT_CALLBACK_FUNC_DEF(gpu_shutdown) __prof; #if DX12_DEBUG /* Release objects to make live object reporting less noisy */ - for (u64 i = 0; i < ARRAY_COUNT(G.swapchain_buffers); ++i) { - ID3D12Resource_Release(G.swapchain_buffers[i]); + for (u64 i = 0; i < ARRAY_COUNT(G.swapchain_resources); ++i) { + dx12_resource_release(G.swapchain_resources[i]); } - ID3D12DescriptorHeap_Release(G.swapchain_rtv_heap); IDXGISwapChain3_Release(G.swapchain); - ID3D12CommandAllocator_Release(G.swapchain_ca); command_queue_release(G.cq_copy_background); command_queue_release(G.cq_copy_critical); command_queue_release(G.cq_compute); @@ -633,14 +632,6 @@ INTERNAL void dx12_init_swapchain(struct sys_window *window) { HRESULT hr = 0; - /* Create swapchain command allocator */ - { - 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 */ { HWND hwnd = (HWND)sys_window_get_internal_handle(window); @@ -677,30 +668,15 @@ INTERNAL void dx12_init_swapchain(struct sys_window *window) IDXGISwapChain1_Release(swapchain1); } - /* Create swapchain RTV heap */ - { - 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(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 */ { - D3D12_CPU_DESCRIPTOR_HANDLE rtv_handle = ZI; - ID3D12DescriptorHeap_GetCPUDescriptorHandleForHeapStart(G.swapchain_rtv_heap, &rtv_handle); for (u32 i = 0; i < DX12_SWAPCHAIN_BUFFER_COUNT; ++i) { - hr = IDXGISwapChain3_GetBuffer(G.swapchain, i, &IID_ID3D12Resource, (void **)&G.swapchain_buffers[i]); + ID3D12Resource *resource = NULL; + hr = IDXGISwapChain3_GetBuffer(G.swapchain, i, &IID_ID3D12Resource, (void **)&resource); if (FAILED(hr)) { dx12_init_error(LIT("Failed to get swapchain buffer")); } - ID3D12Device_CreateRenderTargetView(G.device, G.swapchain_buffers[i], NULL, rtv_handle); - rtv_handle.ptr += G.desc_sizes[D3D12_DESCRIPTOR_HEAP_TYPE_RTV]; + G.swapchain_resources[i] = dx12_resource_alloc_from_swapchain_buffer(resource); } } } @@ -718,6 +694,7 @@ INTERNAL void dx12_init_swapchain(struct sys_window *window) /* ============= */ /* Material pipeline */ +#if 0 PACK(struct fx_material_constant { struct mat4x4 vp; u32 instance_offset; @@ -730,6 +707,7 @@ PACK(struct fx_material_instance { u32 tint_srgb; f32 emittance; }); +#endif /* ============= */ /* Grid pipeline */ @@ -777,8 +755,8 @@ struct dx12_include_handler { ID3DInclude d3d_handler; ID3DIncludeVtbl vtbl; struct pipeline *pipeline; - b32 has_open_resource; - struct resource res; + u64 num_open_resources; + struct resource open_resources[1024]; }; INTERNAL HRESULT dx12_include_open(ID3DInclude *d3d_handler, D3D_INCLUDE_TYPE include_type, LPCSTR name_cstr, LPCVOID parent_data, LPCVOID *data_out, UINT *data_len_out) @@ -790,15 +768,15 @@ INTERNAL HRESULT dx12_include_open(ID3DInclude *d3d_handler, D3D_INCLUDE_TYPE in struct dx12_include_handler *handler = (struct dx12_include_handler *)d3d_handler; struct string name = string_from_cstr_no_limit((char *)name_cstr); - if (handler->has_open_resource) { - sys_panic(LIT("Dx11 include handler somehow already has a resource open")); + if (handler->num_open_resources >= ARRAY_COUNT(handler->open_resources)) { + sys_panic(LIT("Dx12 include handler resource overflow")); } - struct resource res = resource_open(name); - if (resource_exists(&res)) { - handler->res = res; - handler->has_open_resource = true; - struct string data = resource_get_data(&res); + struct resource *res = &handler->open_resources[handler->num_open_resources++]; + *res = resource_open(name); + if (resource_exists(res)) { + ++handler->num_open_resources; + struct string data = resource_get_data(res); *data_out = data.text; *data_len_out = data.len; result = S_OK; @@ -818,29 +796,32 @@ INTERNAL HRESULT dx12_include_close(ID3DInclude *d3d_handler, LPCVOID data) __prof; (UNUSED)data; struct dx12_include_handler *handler = (struct dx12_include_handler *)d3d_handler; - if (handler->has_open_resource) { - resource_close(&handler->res); - handler->has_open_resource = false; + for (u64 i = 0; i < handler->num_open_resources; ++i) { + struct resource *res = &handler->open_resources[i]; + resource_close(res); } + handler->num_open_resources = 0; return S_OK; } -INTERNAL struct dx12_include_handler dx12_include_handler_alloc(struct pipeline *pipeline) +INTERNAL struct dx12_include_handler *dx12_include_handler_alloc(struct arena *arena, struct pipeline *pipeline) { - struct dx12_include_handler handler = ZI; - handler.d3d_handler.lpVtbl = &handler.vtbl; - handler.vtbl.Open = dx12_include_open; - handler.vtbl.Close = dx12_include_close; - handler.pipeline = pipeline; + struct dx12_include_handler *handler = arena_push(arena, struct dx12_include_handler); + handler->d3d_handler.lpVtbl = &handler->vtbl; + handler->vtbl.Open = dx12_include_open; + handler->vtbl.Close = dx12_include_close; + handler->pipeline = pipeline; return handler; } INTERNAL void dx12_include_handler_release(struct dx12_include_handler *handler) { - if (handler->has_open_resource) { - ASSERT(false); /* Resource should have been closed by handler by now */ - resource_close(&handler->res); + for (u64 i = 0; i < handler->num_open_resources; ++i) { + ASSERT(false); /* Resource should have been closed by handler by now */ + struct resource *res = &handler->open_resources[i]; + resource_close(res); } + handler->num_open_resources = 0; } enum shader_compile_task_kind { @@ -883,7 +864,7 @@ INTERNAL WORK_TASK_FUNC_DEF(shader_compile_task, comp_arg_raw) struct string func_name = string_from_cstr_no_limit(shader_desc.func); if (resource_exists(shader_res)) { - struct dx12_include_handler include_handler = dx12_include_handler_alloc(pipeline); + struct dx12_include_handler *include_handler = dx12_include_handler_alloc(scratch.arena, pipeline); u32 d3d_compile_flags = 0; #if DX12_SHADER_DEBUG @@ -915,11 +896,11 @@ INTERNAL WORK_TASK_FUNC_DEF(shader_compile_task, comp_arg_raw) { "SH_CPU", "0" }, { NULL, NULL } }; - HRESULT hr = D3DCompile(shader_src.text, shader_src.len, friendly_name_cstr, defines, (ID3DInclude *)&include_handler, shader_desc.func, target, d3d_compile_flags, 0, &blob, &error_blob); + HRESULT hr = D3DCompile(shader_src.text, shader_src.len, friendly_name_cstr, defines, (ID3DInclude *)include_handler, shader_desc.func, target, d3d_compile_flags, 0, &blob, &error_blob); success = SUCCEEDED(hr) && !error_blob; } - dx12_include_handler_release(&include_handler); + dx12_include_handler_release(include_handler); } #if 0 @@ -1634,6 +1615,31 @@ INTERNAL struct dx12_resource *dx12_resource_alloc(D3D12_HEAP_PROPERTIES heap_pr return r; } +INTERNAL struct dx12_resource *dx12_resource_alloc_from_swapchain_buffer(ID3D12Resource *buff) +{ + 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); + + /* FIXME: Initialize dx12 resource struct here */ + + r->resource = buff; + + r->rtv_descriptor = descriptor_alloc(G.rtv_heap); + ID3D12Device_CreateRenderTargetView(G.device, r->resource, NULL, r->rtv_descriptor->handle); + + return r; +} + INTERNAL void dx12_resource_release(struct dx12_resource *t) { (UNUSED)t; @@ -1738,12 +1744,7 @@ void gpu_dispatch(struct gpu_dispatch_params params) struct command_queue *cq = G.cq_direct; struct command_list *cl = command_list_open(cq); - /* Push buffers */ -#if 0 - { - dx12_buffer_submit(plan->material_instances); - } -#endif + struct command_descriptor_heap *descriptor_heap = command_list_push_descriptor_heap(cl, G.cbv_srv_uav_heap); /* Viewport */ @@ -1784,6 +1785,9 @@ void gpu_dispatch(struct gpu_dispatch_params params) } #endif + /* Bind instance buffer */ + //ID3D12GraphicsCommandList_SetGraphicsRootShaderResourceView(cl->cl, 1, instance_buffer->gpu_handle); + /* Bind descriptor heap */ ID3D12DescriptorHeap *heaps[] = { descriptor_heap->heap }; ID3D12GraphicsCommandList_SetDescriptorHeaps(cl->cl, ARRAY_COUNT(heaps), heaps); @@ -1811,89 +1815,6 @@ void gpu_dispatch(struct gpu_dispatch_params params) /* Execute command list */ command_list_close(cl); - -#if 0 - __prof; - struct sprite_scope *sprite_scope = sprite_scope_begin(); - struct dx11_dispatch_state *state = (struct dx11_dispatch_state *)gpu_dispatch_state.v; - - struct rect viewport = params.draw_target_viewport; - - /* Set viewport */ - D3D11_VIEWPORT d3d11_viewport = ZI; - d3d11_viewport.Width = viewport.width; - d3d11_viewport.Height = viewport.height; - d3d11_viewport.MinDepth = 0.0f; - d3d11_viewport.MaxDepth = 1.0f; - d3d11_viewport.TopLeftX = viewport.x; - d3d11_viewport.TopLeftY = viewport.y; - ID3D11DeviceContext_RSSetViewports(G.devcon, 1, &d3d11_viewport); - - struct dx12_resource *final_tex = (struct dx12_resource *)params.draw_target.v; - struct v2i32 final_tex_size = final_tex->size; - - /* Texture pass */ - { - __profscope(Texture pass); - struct dx11_shader *shader = &G.shaders[DX11_SHADER_KIND_TEXTURE]; - if (shader->valid) { - struct dx12_resource *texture = NULL; - if (cmd->texture.texture.v) { - /* Load texture if handle is set */ - 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_resource *)sprite_texture->texture.v; - } - } - - if (texture && texture->srv) { - struct dx11_buffer *instance_buffer = list->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); - ID3D11DeviceContext_PSSetShader(G.devcon, shader->ps, 0, 0); - - /* 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); - - /* 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); - } - } - } - - sprite_scope_end(sprite_scope); -#endif } /* ========================== *