move shader structs into shared header

This commit is contained in:
jacob 2025-06-18 20:48:09 -05:00
parent 1e06520d99
commit 99431ebdfa
5 changed files with 145 additions and 165 deletions

View File

@ -1,3 +1,5 @@
#include "sh/sh_common.h"
#define DECL(t, n) t n : n
#define PI 3.14159265359

View File

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

73
res/sh/sh_common.h Normal file
View File

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

View File

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

View File

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