From 26a64ce1eb4a62f3139cbd2e5f9fa76617a80969 Mon Sep 17 00:00:00 2001 From: jacob Date: Fri, 25 Jul 2025 20:39:46 -0500 Subject: [PATCH] full bindless --- build.c | 20 +- src/dxc.cpp | 2 +- src/gp.h | 2 +- src/gp_dx12.c | 476 +++++++++++++++++++--------------------- src/sh/blit.hlsl_rs | 37 +--- src/sh/common.hlsl | 23 +- src/sh/flood.hlsl_cs | 35 +-- src/sh/material.hlsl_rs | 41 +--- src/sh/sh_common.h | 44 ++-- src/sh/shade.hlsl_cs | 53 ++--- src/sh/shape.hlsl_rs | 16 +- src/sh/ui.hlsl_rs | 35 +-- src/sys_win32.c | 2 +- src/user.c | 2 +- 14 files changed, 341 insertions(+), 447 deletions(-) diff --git a/build.c b/build.c index e71793cf..10f23b45 100644 --- a/build.c +++ b/build.c @@ -449,6 +449,8 @@ void OnBuild(StringList cli_args) * Determine compiler args * ========================== */ + String dxc_args_format = { 0 }; + StringList c_compile_args = { 0 }; StringList cpp_compile_args = { 0 }; StringList pch_c_compile_args = { 0 }; @@ -519,12 +521,6 @@ void OnBuild(StringList cli_args) StringListAppend(&perm, &link_warnings, warnings); } - /* DXC */ - { - StringListAppend(&perm, &dxc_compile_args, Lit("dxc %F -Fo %F -E %F -T %F -H")); - } - - /* RTC */ if (arg_rtc) { if (!arg_crtlib) { @@ -631,6 +627,13 @@ void OnBuild(StringList cli_args) String incbin_dir = StringReplace(&perm, out_inc_dir_path, Lit("\\"), Lit("/")); StringListAppend(&perm, &compile_args, StringF(&perm, Lit("-DINCBIN_DIR_RAW=\"%F\""), FmtStr(incbin_dir))); } + + /* DXC */ + { + StringListAppend(&perm, &dxc_compile_args, Lit("-H -WX -Ges")); + String dxc_args_define = StringFromStringList(&perm, Lit(" "), dxc_compile_args); + StringListAppend(&perm, &compile_args, StringF(&perm, Lit("-DDXC_ARGS=\"%F\""), FmtStr(dxc_args_define))); + } } /* ========================== * @@ -699,7 +702,8 @@ void OnBuild(StringList cli_args) { AddSyncPoint(); - String dxc_compile_args_fmt = StringFromStringLists(&perm, Lit(" "), dxc_compile_args); + String dxc_args_bare = StringFromStringLists(&perm, Lit(" "), dxc_compile_args); + String dxc_compile_args_fmt = StringF(&perm, Lit("dxc %%F -E %%F -T %%F -Fo %%F %F"), FmtStr(dxc_args_bare)); for (D_TagListNode *n = src_input_files.first; n; n = n->next) { D_Tag file = n->tag; String path = file.full_path; @@ -747,7 +751,7 @@ void OnBuild(StringList cli_args) String step_name = StringF(&perm, Lit("%F -> %F"), FmtStr(name), FmtStr(D_GetName(dxc_file))); { BuildStepSimpleCommandArg *bs_arg = ArenaPush(&perm, BuildStepSimpleCommandArg); - bs_arg->cmd = StringF(&perm, dxc_compile_args_fmt, FmtStr(file.full_path), FmtStr(dxc_file.full_path), FmtStr(entry), FmtStr(profile)); + bs_arg->cmd = StringF(&perm, dxc_compile_args_fmt, FmtStr(file.full_path), FmtStr(entry), FmtStr(profile), FmtStr(dxc_file.full_path)); bs_arg->failure_flag = &shader_success_flag; bs_arg->delete_file_on_failure = dxc_file; bs_arg->dxc_depfile_dependent = dxc_file; diff --git a/src/dxc.cpp b/src/dxc.cpp index 555994a7..60397c5e 100644 --- a/src/dxc.cpp +++ b/src/dxc.cpp @@ -15,7 +15,7 @@ extern "C" #pragma comment(lib, "dxcompiler") /* https://github.com/microsoft/DirectXShaderCompiler/wiki/Using-dxc.exe-and-dxcompiler.dll */ -struct dxc_compile_result dxc_compile(struct arena *arena, string shader_source, i32 num_args, struct string *args) +struct dxc_compile_result dxc_compile(struct arena *arena, struct string shader_source, i32 num_args, struct string *args) { __prof; struct arena_temp scratch = scratch_begin(arena); diff --git a/src/gp.h b/src/gp.h index 622152a6..8a604005 100644 --- a/src/gp.h +++ b/src/gp.h @@ -116,7 +116,7 @@ struct gp_render_sig *gp_render_sig_alloc(void); /* Returns a cmd id internal to the sig */ i32 gp_push_render_cmd(struct gp_render_sig *render_sig, struct gp_render_cmd_desc *desc); -struct gp_resource *gp_run_render(struct gp_render_sig *render_sig, struct gp_render_params render_params); +struct gp_resource *gp_run_render(struct gp_render_sig *gp_render_sig, struct gp_render_params render_params); /* ========================== * * Memory info diff --git a/src/gp_dx12.c b/src/gp_dx12.c index 0afdc67d..f0b30069 100644 --- a/src/gp_dx12.c +++ b/src/gp_dx12.c @@ -106,6 +106,7 @@ struct pipeline { struct string name; u64 hash; b32 success; + b32 is_gfx; struct string error; i64 compilation_time_ns; @@ -173,6 +174,8 @@ struct command_list { struct ID3D12GraphicsCommandList *cl; struct snc_lock global_record_lock; + struct pipeline *cur_pipeline; + struct command_descriptor_heap *first_command_descriptor_heap; struct command_buffer *first_command_buffer; @@ -225,14 +228,6 @@ struct descriptor { struct descriptor *next_free; }; -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) -}; - struct dx12_resource { enum D3D12_RESOURCE_STATES state; ID3D12Resource *resource; @@ -312,7 +307,9 @@ INTERNAL SYS_JOB_DEF(dx12_evictor_job, _); INTERNAL void fenced_release(void *data, enum fenced_release_kind kind); -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, i32 view_flags); +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); + +INTERNAL struct descriptor *descriptor_alloc(struct cpu_descriptor_heap *dh); struct command_queue_alloc_job_sig { struct command_queue_desc *descs_in; struct command_queue **cqs_out; }; INTERNAL SYS_JOB_DEF(command_queue_alloc_job, job); @@ -826,8 +823,6 @@ INTERNAL void dx12_init_noise(void) FMT_UINT(expected_size), FMT_UINT(data.len))); } { - 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; @@ -847,7 +842,9 @@ INTERNAL void dx12_init_noise(void) desc.SampleDesc.Count = 1; desc.SampleDesc.Quality = 0; - struct dx12_resource *r = dx12_resource_alloc(heap_props, heap_flags, desc, D3D12_RESOURCE_STATE_COPY_DEST, view_flags); + struct dx12_resource *r = dx12_resource_alloc(heap_props, heap_flags, desc, D3D12_RESOURCE_STATE_COPY_DEST); + r->srv_descriptor = descriptor_alloc(G.cbv_srv_uav_heap); + ID3D12Device_CreateShaderResourceView(G.device, r->resource, 0, r->srv_descriptor->handle); /* Upload texture */ { @@ -907,15 +904,24 @@ INTERNAL SYS_JOB_DEF(shader_compile_job, job) { __profn("Compile shader"); logf_info("Compiling shader \"%F:%F\"", FMT_STR(desc->friendly_name), FMT_STR(desc->entry)); - struct string args[] = { + /* NOTE: `DXC_ARGS` is supplied by build system at compile time */ + char *dxc_args_cstr = STRINGIZE(DXC_ARGS); + struct string dxc_args_str = string_from_cstr_no_limit(dxc_args_cstr); + struct string_array dxc_args_array = string_split(scratch.arena, dxc_args_str, LIT(" ")); + struct string shader_args[] = { desc->friendly_name, LIT("-E"), desc->entry, LIT("-T"), desc->target, - LIT("-D SH_CPU=0"), - LIT("-Zi"), - LIT("-Qembed_debug") }; - dxc_result = dxc_compile(arena, desc->src, countof(args), args); + u32 num_args = countof(shader_args) + dxc_args_array.count; + struct string *args = arena_push_array(scratch.arena, struct string, num_args); + for (u32 i = 0; i < countof(shader_args); ++i) { + args[i] = shader_args[i]; + } + for (u32 i = 0; i < dxc_args_array.count; ++i) { + args[i + countof(shader_args)] = dxc_args_array.strings[i]; + } + dxc_result = dxc_compile(arena, desc->src, num_args, args); } result->success = dxc_result.success; result->dxc = dxc_result.dxc; @@ -1191,6 +1197,7 @@ INTERNAL SYS_JOB_DEF(pipeline_alloc_job, job) pipeline->rootsig = rootsig; pipeline->compilation_time_ns = sys_time_ns() - start_ns; pipeline->success = success; + pipeline->is_gfx = cs_dxc.len == 0; pipeline->error = error_str; if (rootsig_blob) { @@ -1624,7 +1631,7 @@ INTERNAL void fenced_release(void *data, enum fenced_release_kind kind) * Resource * ========================== */ -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, i32 view_flags) +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) { __prof; struct dx12_resource *r = 0; @@ -1654,28 +1661,6 @@ INTERNAL struct dx12_resource *dx12_resource_alloc(D3D12_HEAP_PROPERTIES heap_pr r->gpu_address = ID3D12Resource_GetGPUVirtualAddress(r->resource); } - if (view_flags & DX12_RESOURCE_VIEW_FLAG_CBV) { - r->cbv_descriptor = 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 = KIBI(64); - ID3D12Device_CreateConstantBufferView(G.device, &cbv_desc, r->cbv_descriptor->handle); - } - if (view_flags & DX12_RESOURCE_VIEW_FLAG_SRV) { - r->srv_descriptor = descriptor_alloc(G.cbv_srv_uav_heap); - ID3D12Device_CreateShaderResourceView(G.device, r->resource, 0, r->srv_descriptor->handle); - } - if (view_flags & DX12_RESOURCE_VIEW_FLAG_UAV) { - r->uav_descriptor = descriptor_alloc(G.cbv_srv_uav_heap); - ID3D12Device_CreateUnorderedAccessView(G.device, r->resource, 0, 0, r->uav_descriptor->handle); - } - if (view_flags & DX12_RESOURCE_VIEW_FLAG_RTV) { - r->rtv_descriptor = descriptor_alloc(G.rtv_heap); - ID3D12Device_CreateRenderTargetView(G.device, r->resource, 0, r->rtv_descriptor->handle); - } - return r; } @@ -2100,17 +2085,21 @@ INTERNAL u64 align_up_pow2(u64 v) return res; } -INTERNAL struct command_buffer *command_list_push_buffer(struct command_list *cl, struct string data) +#define command_list_push_buffer(cl, count, elems) _command_list_push_buffer((cl), count * ((elems) ? sizeof(*(elems)) : 0), (elems), (elems) ? sizeof(*(elems)) : 1) +INTERNAL struct command_buffer *_command_list_push_buffer(struct command_list *cl, u64 data_len, void *data, u64 data_stride) { __prof; + /* Data length should be a multiple of stride */ + ASSERT(data_len % data_stride == 0); + /* Determine size */ - u64 size = max_u64(DX12_COMMAND_BUFFER_MIN_SIZE, align_up_pow2(data.len)); + u64 size = max_u64(DX12_COMMAND_BUFFER_MIN_SIZE, align_up_pow2(data_len)); /* Allocate buffer */ struct command_buffer_group *cb_group = 0; struct command_buffer *cb = 0; - struct dx12_resource *resource = 0; + struct dx12_resource *r = 0; { struct snc_lock lock = snc_lock_e(&G.command_buffers_mutex); @@ -2135,7 +2124,7 @@ INTERNAL struct command_buffer *command_list_push_buffer(struct command_list *cl } if (cb) { /* Remove from submitted list */ - resource = cb->resource; + r = cb->resource; struct command_buffer *prev = cb->prev_submitted; struct command_buffer *next = cb->next_submitted; if (prev) { @@ -2156,14 +2145,10 @@ INTERNAL struct command_buffer *command_list_push_buffer(struct command_list *cl } MEMZERO_STRUCT(cb); cb->group = cb_group; - cb->size = data.len; + cb->size = data_len; /* Create upload heap */ - if (resource) { - cb->resource = resource; - } else { - enum dx12_resource_view_flags view_flags = DX12_RESOURCE_VIEW_FLAG_NONE; - + if (!r) { D3D12_HEAP_PROPERTIES heap_props = { .Type = D3D12_HEAP_TYPE_UPLOAD }; heap_props.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN; heap_props.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN; @@ -2171,6 +2156,7 @@ INTERNAL struct command_buffer *command_list_push_buffer(struct command_list *cl D3D12_HEAP_FLAGS heap_flags = D3D12_HEAP_FLAG_CREATE_NOT_ZEROED; D3D12_RESOURCE_DESC desc = ZI; + desc.Flags = 0; desc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER; desc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR; desc.Format = DXGI_FORMAT_UNKNOWN; @@ -2183,10 +2169,24 @@ INTERNAL struct command_buffer *command_list_push_buffer(struct command_list *cl desc.SampleDesc.Quality = 0; D3D12_RESOURCE_STATES initial_state = D3D12_RESOURCE_STATE_GENERIC_READ; - cb->resource = dx12_resource_alloc(heap_props, heap_flags, desc, initial_state, view_flags); + r = dx12_resource_alloc(heap_props, heap_flags, desc, initial_state); + r->srv_descriptor = descriptor_alloc(G.cbv_srv_uav_heap); + } + cb->resource = r; + + { + struct D3D12_SHADER_RESOURCE_VIEW_DESC desc = ZI; + desc.Format = DXGI_FORMAT_UNKNOWN; + desc.ViewDimension = D3D12_SRV_DIMENSION_BUFFER; + desc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING; + desc.Buffer.FirstElement = 0; + desc.Buffer.NumElements = max_u32(data_len / data_stride, 1); + desc.Buffer.StructureByteStride = data_stride; + desc.Buffer.Flags = D3D12_BUFFER_SRV_FLAG_NONE; + ID3D12Device_CreateShaderResourceView(G.device, r->resource, &desc, r->srv_descriptor->handle); } - /* Copy data to resource */ + /* Write data to resource */ { D3D12_RANGE read_range = ZI; void *dst = 0; @@ -2195,7 +2195,7 @@ INTERNAL struct command_buffer *command_list_push_buffer(struct command_list *cl /* TODO: Don't panic */ sys_panic(LIT("Failed to map command buffer resource")); } - MEMCPY(dst, data.text, data.len); + MEMCPY(dst, data, data_len); ID3D12Resource_Unmap(cb->resource->resource, 0, 0); } @@ -2255,8 +2255,6 @@ struct gp_resource *gp_texture_alloc(enum gp_texture_format format, u32 flags, s 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; @@ -2274,15 +2272,20 @@ struct gp_resource *gp_texture_alloc(enum gp_texture_format format, u32 flags, s desc.MipLevels = 1; desc.SampleDesc.Count = 1; desc.SampleDesc.Quality = 0; - if (flags & GP_TEXTURE_FLAG_TARGETABLE) { - desc.Flags |= D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET | D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS; - view_flags |= DX12_RESOURCE_VIEW_FLAG_RTV | DX12_RESOURCE_VIEW_FLAG_UAV; - } 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); + struct dx12_resource *r = dx12_resource_alloc(heap_props, heap_flags, desc, initial_state); r->texture_size = size; + r->srv_descriptor = descriptor_alloc(G.cbv_srv_uav_heap); + ID3D12Device_CreateShaderResourceView(G.device, r->resource, 0, r->srv_descriptor->handle); + if (flags & GP_TEXTURE_FLAG_TARGETABLE) { + desc.Flags |= D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET | D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS; + r->uav_descriptor = descriptor_alloc(G.cbv_srv_uav_heap); + r->rtv_descriptor = descriptor_alloc(G.rtv_heap); + ID3D12Device_CreateUnorderedAccessView(G.device, r->resource, 0, 0, r->uav_descriptor->handle); + ID3D12Device_CreateRenderTargetView(G.device, r->resource, 0, r->rtv_descriptor->handle); + } /* Upload texture */ if (initial_data) { @@ -2330,8 +2333,6 @@ INTERNAL SYS_JOB_DEF(dx12_upload_job, job) /* Create upload heap */ struct dx12_resource *upload = 0; { - enum dx12_resource_view_flags upload_view_flags = DX12_RESOURCE_VIEW_FLAG_NONE; - D3D12_HEAP_PROPERTIES upload_heap_props = { .Type = D3D12_HEAP_TYPE_UPLOAD }; upload_heap_props.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN; upload_heap_props.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN; @@ -2351,7 +2352,7 @@ INTERNAL SYS_JOB_DEF(dx12_upload_job, job) upload_desc.SampleDesc.Quality = 0; D3D12_RESOURCE_STATES upload_initial_state = D3D12_RESOURCE_STATE_GENERIC_READ; - upload = dx12_resource_alloc(upload_heap_props, upload_heap_flags, upload_desc, upload_initial_state, upload_view_flags); + upload = dx12_resource_alloc(upload_heap_props, upload_heap_flags, upload_desc, upload_initial_state); } struct command_queue *cq = G.command_queues[DX12_QUEUE_COPY_BACKGROUND]; @@ -2418,35 +2419,32 @@ INTERNAL SYS_JOB_DEF(dx12_upload_job, job) * Run utils * ========================== */ -INTERNAL void command_list_set_graphics_root_constant(struct command_list *cl, void *src, u32 size) +INTERNAL void command_list_set_pipeline(struct command_list *cl, struct pipeline *pipeline) { - __prof; - if (size % 4 == 0) { - u32 num32bit = size / 4; - for (u32 i = 0; i < num32bit; ++i) { - u32 val = 0; - MEMCPY(&val, (((u32 *)src) + i), 4); - ID3D12GraphicsCommandList_SetGraphicsRoot32BitConstant(cl->cl, 0, val, i); - } + ID3D12GraphicsCommandList_SetPipelineState(cl->cl, pipeline->pso); + if (pipeline->is_gfx) { + ID3D12GraphicsCommandList_SetGraphicsRootSignature(cl->cl, pipeline->rootsig); } else { - /* Root constant structs must pad to 32 bits */ - ASSERT(0); + ID3D12GraphicsCommandList_SetComputeRootSignature(cl->cl, pipeline->rootsig); } + cl->cur_pipeline = pipeline; } -INTERNAL void command_list_set_compute_root_constant(struct command_list *cl, void *src, u32 size) +INTERNAL void command_list_set_sig(struct command_list *cl, void *src, u32 size) { __prof; - if (size % 4 == 0) { - u32 num32bit = size / 4; - for (u32 i = 0; i < num32bit; ++i) { - u32 val = 0; - MEMCPY(&val, (((u32 *)src) + i), 4); + ASSERT(size % 16 == 0); /* Root constant structs must pad to 16 bytes */ + ASSERT(size <= 256); /* Only 64 32-bit root constants allowed in signature */ + u32 num32bit = size / 4; + b32 is_gfx = cl->cur_pipeline->is_gfx; + for (u32 i = 0; i < num32bit; ++i) { + u32 val = 0; + MEMCPY(&val, (((u32 *)src) + i), 4); + if (is_gfx) { + ID3D12GraphicsCommandList_SetGraphicsRoot32BitConstant(cl->cl, 0, val, i); + } else { ID3D12GraphicsCommandList_SetComputeRoot32BitConstant(cl->cl, 0, val, i); } - } else { - /* Root constant structs must pad to 32 bits */ - ASSERT(0); } } @@ -2512,7 +2510,14 @@ INTERNAL struct dx12_resource *gbuff_alloc(DXGI_FORMAT format, struct v2i32 size desc.SampleDesc.Quality = 0; desc.Flags = D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET | D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS; - struct dx12_resource *r = dx12_resource_alloc(heap_props, heap_flags, desc, initial_state, DX12_RESOURCE_VIEW_FLAG_SRV | DX12_RESOURCE_VIEW_FLAG_UAV | DX12_RESOURCE_VIEW_FLAG_RTV); + struct dx12_resource *r = dx12_resource_alloc(heap_props, heap_flags, desc, initial_state); + r->srv_descriptor = descriptor_alloc(G.cbv_srv_uav_heap); + r->uav_descriptor = descriptor_alloc(G.cbv_srv_uav_heap); + r->rtv_descriptor = descriptor_alloc(G.rtv_heap); + ID3D12Device_CreateShaderResourceView(G.device, r->resource, 0, r->srv_descriptor->handle); + ID3D12Device_CreateUnorderedAccessView(G.device, r->resource, 0, 0, r->uav_descriptor->handle); + ID3D12Device_CreateRenderTargetView(G.device, r->resource, 0, r->rtv_descriptor->handle); + r->texture_size = size; return r; } @@ -2715,12 +2720,12 @@ i32 gp_push_render_cmd(struct gp_render_sig *render_sig, struct gp_render_cmd_de * Render * ========================== */ -struct gp_resource *gp_run_render(struct gp_render_sig *render_sig, struct gp_render_params params) +struct gp_resource *gp_run_render(struct gp_render_sig *gp_render_sig, struct gp_render_params params) { __prof; struct arena_temp scratch = scratch_begin_no_conflict(); - struct render_sig *sig = (struct render_sig *)render_sig; - ++sig->frame_index; + struct render_sig *rsig = (struct render_sig *)gp_render_sig; + ++rsig->frame_index; struct v2i32 ui_size = V2I32(max_i32(params.ui_size.x, 1), max_i32(params.ui_size.y, 1)); struct v2i32 render_size = V2I32(max_i32(params.render_size.x, 1), max_i32(params.render_size.y, 1)); @@ -2732,33 +2737,33 @@ struct gp_resource *gp_run_render(struct gp_render_sig *render_sig, struct gp_re /* Allocate render buffers */ - if (sig->shade_target && !v2i32_eq(render_size, sig->shade_target->texture_size)) { + if (rsig->shade_target && !v2i32_eq(render_size, rsig->shade_target->texture_size)) { __profn("Release sig resources"); - fenced_release(sig->albedo, FENCED_RELEASE_KIND_RESOURCE); - fenced_release(sig->emittance, FENCED_RELEASE_KIND_RESOURCE); - fenced_release(sig->emittance_flood_read, FENCED_RELEASE_KIND_RESOURCE); - fenced_release(sig->emittance_flood_target, FENCED_RELEASE_KIND_RESOURCE); - fenced_release(sig->shade_read, FENCED_RELEASE_KIND_RESOURCE); - fenced_release(sig->shade_target, FENCED_RELEASE_KIND_RESOURCE); - sig->shade_target = 0; + fenced_release(rsig->albedo, FENCED_RELEASE_KIND_RESOURCE); + fenced_release(rsig->emittance, FENCED_RELEASE_KIND_RESOURCE); + fenced_release(rsig->emittance_flood_read, FENCED_RELEASE_KIND_RESOURCE); + fenced_release(rsig->emittance_flood_target, FENCED_RELEASE_KIND_RESOURCE); + fenced_release(rsig->shade_read, FENCED_RELEASE_KIND_RESOURCE); + fenced_release(rsig->shade_target, FENCED_RELEASE_KIND_RESOURCE); + rsig->shade_target = 0; } - if (!sig->shade_target) { + if (!rsig->shade_target) { __profn("Allocate sig resources"); - sig->albedo = gbuff_alloc(DXGI_FORMAT_R8G8B8A8_UNORM, render_size, D3D12_RESOURCE_STATE_RENDER_TARGET); - sig->emittance = gbuff_alloc(DXGI_FORMAT_R16G16B16A16_FLOAT, render_size, D3D12_RESOURCE_STATE_RENDER_TARGET); - sig->emittance_flood_read = gbuff_alloc(DXGI_FORMAT_R16G16_UINT, render_size, D3D12_RESOURCE_STATE_UNORDERED_ACCESS); - sig->emittance_flood_target = gbuff_alloc(DXGI_FORMAT_R16G16_UINT, render_size, D3D12_RESOURCE_STATE_UNORDERED_ACCESS); - sig->shade_read = gbuff_alloc(DXGI_FORMAT_R16G16B16A16_FLOAT, render_size, D3D12_RESOURCE_STATE_UNORDERED_ACCESS); - sig->shade_target = gbuff_alloc(DXGI_FORMAT_R16G16B16A16_FLOAT, render_size, D3D12_RESOURCE_STATE_UNORDERED_ACCESS); + rsig->albedo = gbuff_alloc(DXGI_FORMAT_R8G8B8A8_UNORM, render_size, D3D12_RESOURCE_STATE_RENDER_TARGET); + rsig->emittance = gbuff_alloc(DXGI_FORMAT_R16G16B16A16_FLOAT, render_size, D3D12_RESOURCE_STATE_RENDER_TARGET); + rsig->emittance_flood_read = gbuff_alloc(DXGI_FORMAT_R16G16_UINT, render_size, D3D12_RESOURCE_STATE_UNORDERED_ACCESS); + rsig->emittance_flood_target = gbuff_alloc(DXGI_FORMAT_R16G16_UINT, render_size, D3D12_RESOURCE_STATE_UNORDERED_ACCESS); + rsig->shade_read = gbuff_alloc(DXGI_FORMAT_R16G16B16A16_FLOAT, render_size, D3D12_RESOURCE_STATE_UNORDERED_ACCESS); + rsig->shade_target = gbuff_alloc(DXGI_FORMAT_R16G16B16A16_FLOAT, render_size, D3D12_RESOURCE_STATE_UNORDERED_ACCESS); } /* Allocate ui buffers */ - if (sig->ui_target && !v2i32_eq(ui_size, sig->ui_target->texture_size)) { - fenced_release(sig->ui_target, FENCED_RELEASE_KIND_RESOURCE); - sig->ui_target = 0; + if (rsig->ui_target && !v2i32_eq(ui_size, rsig->ui_target->texture_size)) { + fenced_release(rsig->ui_target, FENCED_RELEASE_KIND_RESOURCE); + rsig->ui_target = 0; } - if (!sig->ui_target) { - sig->ui_target = gbuff_alloc(DXGI_FORMAT_R8G8B8A8_UNORM, ui_size, D3D12_RESOURCE_STATE_RENDER_TARGET); + if (!rsig->ui_target) { + rsig->ui_target = gbuff_alloc(DXGI_FORMAT_R8G8B8A8_UNORM, ui_size, D3D12_RESOURCE_STATE_RENDER_TARGET); } struct sprite_scope *sprite_scope = sprite_scope_begin(); @@ -2788,21 +2793,21 @@ struct gp_resource *gp_run_render(struct gp_render_sig *render_sig, struct gp_re /* TODO: Make these static */ /* Dummy vertex buffer */ LOCAL_PERSIST u16 quad_indices[6] = { 0, 1, 2, 0, 2, 3 }; - struct command_buffer *dummy_vertex_buffer = command_list_push_buffer(cl, STRING(0, 0)); - struct command_buffer *quad_index_buffer = command_list_push_buffer(cl, STRING_FROM_ARRAY(quad_indices)); + struct command_buffer *dummy_vertex_buffer = command_list_push_buffer(cl, 0, (u8 *)0); + struct command_buffer *quad_index_buffer = command_list_push_buffer(cl, countof(quad_indices), quad_indices); /* Process sig data into uploadable data */ - struct sh_material_instance *material_instances = arena_push_array_no_zero(scratch.arena, struct sh_material_instance, sig->num_material_instance_descs); - struct sh_ui_instance *ui_rect_instances = arena_push_array_no_zero(scratch.arena, struct sh_ui_instance, sig->num_ui_rect_instance_descs); - struct sh_material_grid *grids = arena_push_array_no_zero(scratch.arena, struct sh_material_grid, sig->num_material_grid_descs); + struct sh_material_instance *material_instances = arena_push_array_no_zero(scratch.arena, struct sh_material_instance, rsig->num_material_instance_descs); + struct sh_ui_instance *ui_rect_instances = arena_push_array_no_zero(scratch.arena, struct sh_ui_instance, rsig->num_ui_rect_instance_descs); + struct sh_material_grid *grids = arena_push_array_no_zero(scratch.arena, struct sh_material_grid, rsig->num_material_grid_descs); { __profn("Process sig data"); /* Process material instances */ { __profn("Process material instances"); - for (u32 i = 0; i < sig->num_material_instance_descs; ++i) { - struct material_instance_desc *desc = &((struct material_instance_desc *)arena_base(sig->material_instance_descs_arena))[i]; + for (u32 i = 0; i < rsig->num_material_instance_descs; ++i) { + struct material_instance_desc *desc = &((struct material_instance_desc *)arena_base(rsig->material_instance_descs_arena))[i]; struct sh_material_instance *instance = &material_instances[i]; i32 texture_id = -1; if (desc->texture != 0) { @@ -2828,8 +2833,8 @@ struct gp_resource *gp_run_render(struct gp_render_sig *render_sig, struct gp_re /* Process ui rect instances */ { __profn("Process ui rect instances"); - for (u32 i = 0; i < sig->num_ui_rect_instance_descs; ++i) { - struct ui_rect_instance_desc *desc = &((struct ui_rect_instance_desc *)arena_base(sig->ui_rect_instance_descs_arena))[i]; + for (u32 i = 0; i < rsig->num_ui_rect_instance_descs; ++i) { + struct ui_rect_instance_desc *desc = &((struct ui_rect_instance_desc *)arena_base(rsig->ui_rect_instance_descs_arena))[i]; struct sh_ui_instance *instance = &ui_rect_instances[i]; i32 texture_id = -1; if (desc->texture != 0) { @@ -2852,8 +2857,8 @@ struct gp_resource *gp_run_render(struct gp_render_sig *render_sig, struct gp_re /* Process grids */ { __profn("Process grids"); - for (u32 i = 0; i < sig->num_material_grid_descs; ++i) { - struct material_grid_desc *desc = &((struct material_grid_desc *)arena_base(sig->material_grid_descs_arena))[i]; + for (u32 i = 0; i < rsig->num_material_grid_descs; ++i) { + struct material_grid_desc *desc = &((struct material_grid_desc *)arena_base(rsig->material_grid_descs_arena))[i]; struct sh_material_grid *grid = &grids[i]; grid->line_thickness = sh_float_from_f32(desc->line_thickness); grid->line_spacing = sh_float_from_f32(desc->line_spacing); @@ -2868,11 +2873,13 @@ struct gp_resource *gp_run_render(struct gp_render_sig *render_sig, struct gp_re } /* Upload buffers */ - struct command_buffer *material_instance_buffer = command_list_push_buffer(cl, STRING(sizeof(*material_instances) * sig->num_material_instance_descs, (u8 *)material_instances)); - struct command_buffer *ui_rect_instance_buffer = command_list_push_buffer(cl, STRING(sizeof(*ui_rect_instances) * sig->num_ui_rect_instance_descs, (u8 *)ui_rect_instances)); - struct command_buffer *ui_shape_verts_buffer = command_list_push_buffer(cl, STRING_FROM_ARENA(sig->ui_shape_verts_arena)); - struct command_buffer *ui_shape_indices_buffer = command_list_push_buffer(cl, STRING_FROM_ARENA(sig->ui_shape_indices_arena)); - struct command_buffer *grid_buffer = command_list_push_buffer(cl, STRING(sizeof(*grids) * sig->num_material_grid_descs, (u8 *)grids)); + u64 num_ui_shape_verts = rsig->ui_shape_verts_arena->pos / sizeof(struct sh_shape_vert); + u64 num_ui_shape_indices = rsig->ui_shape_indices_arena->pos / sizeof(u16); + struct command_buffer *material_instance_buffer = command_list_push_buffer(cl, rsig->num_material_instance_descs, material_instances); + struct command_buffer *ui_rect_instance_buffer = command_list_push_buffer(cl, rsig->num_ui_rect_instance_descs, ui_rect_instances); + struct command_buffer *ui_shape_verts_buffer = command_list_push_buffer(cl, num_ui_shape_verts, (struct sh_shape_vert *)arena_base(rsig->ui_shape_verts_arena)); + struct command_buffer *ui_shape_indices_buffer = command_list_push_buffer(cl, num_ui_shape_indices, (u16 *)arena_base(rsig->ui_shape_indices_arena)); + struct command_buffer *grid_buffer = command_list_push_buffer(cl, rsig->num_material_grid_descs, grids); /* Upload descriptor heap */ struct command_descriptor_heap *descriptor_heap = command_list_push_descriptor_heap(cl, G.cbv_srv_uav_heap); @@ -2884,12 +2891,12 @@ struct gp_resource *gp_run_render(struct gp_render_sig *render_sig, struct gp_re /* Barrier */ { struct dx12_resource_barrier_desc barriers[] = { - { D3D12_RESOURCE_BARRIER_TYPE_TRANSITION, sig->albedo, D3D12_RESOURCE_STATE_RENDER_TARGET }, - { D3D12_RESOURCE_BARRIER_TYPE_TRANSITION, sig->emittance, D3D12_RESOURCE_STATE_RENDER_TARGET } + { D3D12_RESOURCE_BARRIER_TYPE_TRANSITION, rsig->albedo, D3D12_RESOURCE_STATE_RENDER_TARGET }, + { D3D12_RESOURCE_BARRIER_TYPE_TRANSITION, rsig->emittance, D3D12_RESOURCE_STATE_RENDER_TARGET } }; D3D12_CPU_DESCRIPTOR_HANDLE rtvs[] = { - sig->albedo->rtv_descriptor->handle, - sig->emittance->rtv_descriptor->handle, + rsig->albedo->rtv_descriptor->handle, + rsig->emittance->rtv_descriptor->handle, }; dx12_resource_barriers(cl->cl, countof(barriers), barriers); ID3D12GraphicsCommandList_OMSetRenderTargets(cl->cl, countof(rtvs), rtvs, 0, 0); @@ -2899,8 +2906,8 @@ struct gp_resource *gp_run_render(struct gp_render_sig *render_sig, struct gp_re __profn("Clear gbuffers"); __profnc_dx12(cl->cq->prof, cl->cl, "Clear gbuffers", RGB32_F(0.5, 0.2, 0.2)); f32 clear_color[] = { 0.0f, 0.0f, 0.0f, 0.0f }; - ID3D12GraphicsCommandList_ClearRenderTargetView(cl->cl, sig->albedo->rtv_descriptor->handle, clear_color, 0, 0); - ID3D12GraphicsCommandList_ClearRenderTargetView(cl->cl, sig->emittance->rtv_descriptor->handle, clear_color, 0, 0); + ID3D12GraphicsCommandList_ClearRenderTargetView(cl->cl, rsig->albedo->rtv_descriptor->handle, clear_color, 0, 0); + ID3D12GraphicsCommandList_ClearRenderTargetView(cl->cl, rsig->emittance->rtv_descriptor->handle, clear_color, 0, 0); } } @@ -2910,8 +2917,7 @@ struct gp_resource *gp_run_render(struct gp_render_sig *render_sig, struct gp_re __profnc_dx12(cl->cq->prof, cl->cl, "Material pass", RGB32_F(0.5, 0.2, 0.2)); /* Bind pipeline */ - ID3D12GraphicsCommandList_SetPipelineState(cl->cl, material_pipeline->pso); - ID3D12GraphicsCommandList_SetGraphicsRootSignature(cl->cl, material_pipeline->rootsig); + command_list_set_pipeline(cl, material_pipeline); /* Set Rasterizer State */ D3D12_VIEWPORT viewport = viewport_from_rect(render_viewport); @@ -2919,15 +2925,12 @@ struct gp_resource *gp_run_render(struct gp_render_sig *render_sig, struct gp_re ID3D12GraphicsCommandList_RSSetViewports(cl->cl, 1, &viewport); ID3D12GraphicsCommandList_RSSetScissorRects(cl->cl, 1, &scissor); - /* Set constants */ - struct sh_material_constants constants = ZI; - constants.projection = sh_float4x4_from_mat4x4(world_to_render_vp_matrix); - - /* Set parameters */ - command_list_set_graphics_root_constant(cl, &constants, sizeof(constants)); - ID3D12GraphicsCommandList_SetGraphicsRootDescriptorTable(cl->cl, 1, descriptor_heap->start_gpu_handle); - ID3D12GraphicsCommandList_SetGraphicsRootShaderResourceView(cl->cl, 2, material_instance_buffer->resource->gpu_address); - ID3D12GraphicsCommandList_SetGraphicsRootShaderResourceView(cl->cl, 3, grid_buffer->resource->gpu_address); + /* Set sig */ + struct sh_material_sig sig = ZI; + sig.projection = sh_float4x4_from_mat4x4(world_to_render_vp_matrix); + sig.instances_urid = sh_uint_from_u32(material_instance_buffer->resource->srv_descriptor->index); + sig.grids_urid = sh_uint_from_u32(grid_buffer->resource->srv_descriptor->index); + command_list_set_sig(cl, &sig, sizeof(sig)); /* Draw */ u32 instance_count = material_instance_buffer->size / sizeof(struct sh_material_instance); @@ -2944,12 +2947,12 @@ struct gp_resource *gp_run_render(struct gp_render_sig *render_sig, struct gp_re /* Barrier */ { struct dx12_resource_barrier_desc barriers[] = { - { D3D12_RESOURCE_BARRIER_TYPE_TRANSITION, sig->emittance, D3D12_RESOURCE_STATE_ALL_SHADER_RESOURCE }, + { D3D12_RESOURCE_BARRIER_TYPE_TRANSITION, rsig->emittance, D3D12_RESOURCE_STATE_ALL_SHADER_RESOURCE }, - { D3D12_RESOURCE_BARRIER_TYPE_TRANSITION, sig->emittance_flood_read, D3D12_RESOURCE_STATE_UNORDERED_ACCESS }, - { D3D12_RESOURCE_BARRIER_TYPE_UAV, sig->emittance_flood_read, 0 }, + { D3D12_RESOURCE_BARRIER_TYPE_TRANSITION, rsig->emittance_flood_read, D3D12_RESOURCE_STATE_UNORDERED_ACCESS }, + { D3D12_RESOURCE_BARRIER_TYPE_UAV, rsig->emittance_flood_read, 0 }, - { D3D12_RESOURCE_BARRIER_TYPE_TRANSITION, sig->emittance_flood_target, D3D12_RESOURCE_STATE_UNORDERED_ACCESS } + { D3D12_RESOURCE_BARRIER_TYPE_TRANSITION, rsig->emittance_flood_target, D3D12_RESOURCE_STATE_UNORDERED_ACCESS } }; dx12_resource_barriers(cl->cl, countof(barriers), barriers); } @@ -2961,8 +2964,7 @@ struct gp_resource *gp_run_render(struct gp_render_sig *render_sig, struct gp_re __profnc_dx12(cl->cq->prof, cl->cl, "Flood pass", RGB32_F(0.5, 0.2, 0.2)); /* Bind pipeline */ - ID3D12GraphicsCommandList_SetPipelineState(cl->cl, flood_pipeline->pso); - ID3D12GraphicsCommandList_SetComputeRootSignature(cl->cl, flood_pipeline->rootsig); + command_list_set_pipeline(cl, flood_pipeline); i32 step_length = -1; @@ -2976,32 +2978,28 @@ struct gp_resource *gp_run_render(struct gp_render_sig *render_sig, struct gp_re /* UAV barrier */ { struct dx12_resource_barrier_desc barriers[] = { - { D3D12_RESOURCE_BARRIER_TYPE_UAV, sig->emittance_flood_read, 0 } + { D3D12_RESOURCE_BARRIER_TYPE_UAV, rsig->emittance_flood_read, 0 } }; dx12_resource_barriers(cl->cl, countof(barriers), barriers); } - /* Set constants */ - struct sh_flood_constants constants = ZI; - constants.step_len = sh_int_from_i32(step_length); - constants.emittance_tex_urid = sh_uint_from_u32(sig->emittance->srv_descriptor->index); - constants.read_flood_tex_urid = sh_uint_from_u32(sig->emittance_flood_read->uav_descriptor->index); - constants.target_flood_tex_urid = sh_uint_from_u32(sig->emittance_flood_target->uav_descriptor->index); - constants.tex_width = sh_uint_from_u32(render_size.x); - constants.tex_height = sh_uint_from_u32(render_size.y); - - /* Set parameters */ - command_list_set_compute_root_constant(cl, &constants, sizeof(constants)); - ID3D12GraphicsCommandList_SetComputeRootDescriptorTable(cl->cl, 1, descriptor_heap->start_gpu_handle); - ID3D12GraphicsCommandList_SetComputeRootDescriptorTable(cl->cl, 2, descriptor_heap->start_gpu_handle); + /* Set sig */ + struct sh_flood_sig sig = ZI; + sig.step_len = sh_int_from_i32(step_length); + sig.emittance_tex_urid = sh_uint_from_u32(rsig->emittance->srv_descriptor->index); + sig.read_flood_tex_urid = sh_uint_from_u32(rsig->emittance_flood_read->uav_descriptor->index); + sig.target_flood_tex_urid = sh_uint_from_u32(rsig->emittance_flood_target->uav_descriptor->index); + sig.tex_width = sh_uint_from_u32(render_size.x); + sig.tex_height = sh_uint_from_u32(render_size.y); + command_list_set_sig(cl, &sig, sizeof(sig)); /* Dispatch */ ID3D12GraphicsCommandList_Dispatch(cl->cl, (render_size.x + 7) / 8, (render_size.y + 7) / 8, 1); /* Swap buffers */ - struct dx12_resource *swp = sig->emittance_flood_read; - sig->emittance_flood_read = sig->emittance_flood_target; - sig->emittance_flood_target = swp; + struct dx12_resource *swp = rsig->emittance_flood_read; + rsig->emittance_flood_read = rsig->emittance_flood_target; + rsig->emittance_flood_target = swp; /* Update step */ if (step_length == -1) { @@ -3018,16 +3016,16 @@ struct gp_resource *gp_run_render(struct gp_render_sig *render_sig, struct gp_re /* Barrier */ { struct dx12_resource_barrier_desc barriers[] = { - { D3D12_RESOURCE_BARRIER_TYPE_TRANSITION, sig->albedo, D3D12_RESOURCE_STATE_ALL_SHADER_RESOURCE }, - { D3D12_RESOURCE_BARRIER_TYPE_TRANSITION, sig->emittance, D3D12_RESOURCE_STATE_ALL_SHADER_RESOURCE }, + { D3D12_RESOURCE_BARRIER_TYPE_TRANSITION, rsig->albedo, D3D12_RESOURCE_STATE_ALL_SHADER_RESOURCE }, + { D3D12_RESOURCE_BARRIER_TYPE_TRANSITION, rsig->emittance, D3D12_RESOURCE_STATE_ALL_SHADER_RESOURCE }, - { D3D12_RESOURCE_BARRIER_TYPE_TRANSITION, sig->emittance_flood_read, D3D12_RESOURCE_STATE_UNORDERED_ACCESS }, - { D3D12_RESOURCE_BARRIER_TYPE_UAV, sig->emittance_flood_read, 0 }, + { D3D12_RESOURCE_BARRIER_TYPE_TRANSITION, rsig->emittance_flood_read, D3D12_RESOURCE_STATE_UNORDERED_ACCESS }, + { D3D12_RESOURCE_BARRIER_TYPE_UAV, rsig->emittance_flood_read, 0 }, - { D3D12_RESOURCE_BARRIER_TYPE_TRANSITION, sig->shade_read, D3D12_RESOURCE_STATE_UNORDERED_ACCESS }, - { D3D12_RESOURCE_BARRIER_TYPE_UAV, sig->shade_read, 0 }, + { D3D12_RESOURCE_BARRIER_TYPE_TRANSITION, rsig->shade_read, D3D12_RESOURCE_STATE_UNORDERED_ACCESS }, + { D3D12_RESOURCE_BARRIER_TYPE_UAV, rsig->shade_read, 0 }, - { D3D12_RESOURCE_BARRIER_TYPE_TRANSITION, sig->shade_target, D3D12_RESOURCE_STATE_UNORDERED_ACCESS } + { D3D12_RESOURCE_BARRIER_TYPE_TRANSITION, rsig->shade_target, D3D12_RESOURCE_STATE_UNORDERED_ACCESS } }; dx12_resource_barriers(cl->cl, countof(barriers), barriers); } @@ -3036,7 +3034,7 @@ struct gp_resource *gp_run_render(struct gp_render_sig *render_sig, struct gp_re __profn("Clear shade target"); __profnc_dx12(cl->cq->prof, cl->cl, "Clear shade target", RGB32_F(0.5, 0.2, 0.2)); f32 clear_color[] = { 0.0f, 0.0f, 0.0f, 0.0f }; - ID3D12GraphicsCommandList_ClearUnorderedAccessViewFloat(cl->cl, gpu_handle_from_descriptor(sig->shade_target->uav_descriptor, descriptor_heap), sig->shade_target->uav_descriptor->handle, sig->shade_target->resource, clear_color, 0, 0); + ID3D12GraphicsCommandList_ClearUnorderedAccessViewFloat(cl->cl, gpu_handle_from_descriptor(rsig->shade_target->uav_descriptor, descriptor_heap), rsig->shade_target->uav_descriptor->handle, rsig->shade_target->resource, clear_color, 0, 0); } } @@ -3046,45 +3044,38 @@ struct gp_resource *gp_run_render(struct gp_render_sig *render_sig, struct gp_re __profnc_dx12(cl->cq->prof, cl->cl, "Shade pass", RGB32_F(0.5, 0.2, 0.2)); /* Bind pipeline */ - ID3D12GraphicsCommandList_SetPipelineState(cl->cl, shade_pipeline->pso); - ID3D12GraphicsCommandList_SetComputeRootSignature(cl->cl, shade_pipeline->rootsig); + command_list_set_pipeline(cl, shade_pipeline); u32 shade_flags = SH_SHADE_FLAG_NONE; if (params.effects_disabled) { shade_flags |= SH_SHADE_FLAG_DISABLE_EFFECTS; } - /* Set constants */ - struct sh_shade_constants constants = ZI; - constants.flags = sh_uint_from_u32(shade_flags); - constants.tex_width = sh_uint_from_u32(render_size.x); - constants.tex_height = sh_uint_from_u32(render_size.y); - constants.frame_seed = sh_uint4_from_u32((u32)(rand_u64_from_state(&sig->rand) & 0xFFFFFFFF), - (u32)(rand_u64_from_state(&sig->rand) & 0xFFFFFFFF), - (u32)(rand_u64_from_state(&sig->rand) & 0xFFFFFFFF), - (u32)(rand_u64_from_state(&sig->rand) & 0xFFFFFFFF)); - constants.frame_index = sh_uint_from_u32(sig->frame_index); - constants.camera_offset = sh_float2_from_v2(world_to_render_xf.og); - constants.albedo_tex_urid = sh_uint_from_u32(sig->albedo->srv_descriptor->index); - constants.emittance_tex_urid = sh_uint_from_u32(sig->emittance->srv_descriptor->index); - constants.emittance_flood_tex_urid = sh_uint_from_u32(sig->emittance_flood_read->srv_descriptor->index); - constants.read_tex_urid = sh_uint_from_u32(sig->shade_read->uav_descriptor->index); - constants.target_tex_urid = sh_uint_from_u32(sig->shade_target->uav_descriptor->index); - - /* Set parameters */ - command_list_set_compute_root_constant(cl, &constants, sizeof(constants)); - ID3D12GraphicsCommandList_SetComputeRootDescriptorTable(cl->cl, 1, descriptor_heap->start_gpu_handle); - ID3D12GraphicsCommandList_SetComputeRootDescriptorTable(cl->cl, 2, descriptor_heap->start_gpu_handle); - ID3D12GraphicsCommandList_SetComputeRootDescriptorTable(cl->cl, 3, descriptor_heap->start_gpu_handle); - ID3D12GraphicsCommandList_SetComputeRootDescriptorTable(cl->cl, 4, descriptor_heap->start_gpu_handle); + /* Set sig */ + struct sh_shade_sig sig = ZI; + sig.flags = sh_uint_from_u32(shade_flags); + sig.tex_width = sh_uint_from_u32(render_size.x); + sig.tex_height = sh_uint_from_u32(render_size.y); + sig.frame_seed = sh_uint4_from_u32((u32)(rand_u64_from_state(&rsig->rand) & 0xFFFFFFFF), + (u32)(rand_u64_from_state(&rsig->rand) & 0xFFFFFFFF), + (u32)(rand_u64_from_state(&rsig->rand) & 0xFFFFFFFF), + (u32)(rand_u64_from_state(&rsig->rand) & 0xFFFFFFFF)); + sig.frame_index = sh_uint_from_u32(rsig->frame_index); + sig.camera_offset = sh_float2_from_v2(world_to_render_xf.og); + sig.albedo_tex_urid = sh_uint_from_u32(rsig->albedo->srv_descriptor->index); + sig.emittance_tex_urid = sh_uint_from_u32(rsig->emittance->srv_descriptor->index); + sig.emittance_flood_tex_urid = sh_uint_from_u32(rsig->emittance_flood_read->srv_descriptor->index); + sig.read_tex_urid = sh_uint_from_u32(rsig->shade_read->uav_descriptor->index); + sig.target_tex_urid = sh_uint_from_u32(rsig->shade_target->uav_descriptor->index); + command_list_set_sig(cl, &sig, sizeof(sig)); /* Dispatch */ ID3D12GraphicsCommandList_Dispatch(cl->cl, (render_size.x + 7) / 8, (render_size.y + 7) / 8, 1); /* Swap */ - struct dx12_resource *swp = sig->shade_read; - sig->shade_read = sig->shade_target; - sig->shade_target = swp; + struct dx12_resource *swp = rsig->shade_read; + rsig->shade_read = rsig->shade_target; + rsig->shade_target = swp; } /* Prep for UI pass */ @@ -3092,19 +3083,19 @@ struct gp_resource *gp_run_render(struct gp_render_sig *render_sig, struct gp_re /* Barrier */ { struct dx12_resource_barrier_desc barriers[] = { - { D3D12_RESOURCE_BARRIER_TYPE_TRANSITION, sig->shade_read, D3D12_RESOURCE_STATE_UNORDERED_ACCESS }, - { D3D12_RESOURCE_BARRIER_TYPE_UAV, sig->shade_read, 0 }, - { D3D12_RESOURCE_BARRIER_TYPE_TRANSITION, sig->ui_target, D3D12_RESOURCE_STATE_RENDER_TARGET } + { D3D12_RESOURCE_BARRIER_TYPE_TRANSITION, rsig->shade_read, D3D12_RESOURCE_STATE_UNORDERED_ACCESS }, + { D3D12_RESOURCE_BARRIER_TYPE_UAV, rsig->shade_read, 0 }, + { D3D12_RESOURCE_BARRIER_TYPE_TRANSITION, rsig->ui_target, D3D12_RESOURCE_STATE_RENDER_TARGET } }; dx12_resource_barriers(cl->cl, countof(barriers), barriers); - ID3D12GraphicsCommandList_OMSetRenderTargets(cl->cl, 1, &sig->ui_target->rtv_descriptor->handle, 0, 0); + ID3D12GraphicsCommandList_OMSetRenderTargets(cl->cl, 1, &rsig->ui_target->rtv_descriptor->handle, 0, 0); } /* Clear */ { __profn("Clear ui target"); __profnc_dx12(cl->cq->prof, cl->cl, "Clear ui target", RGB32_F(0.5, 0.2, 0.2)); f32 clear_color[] = { 0.0f, 0.0f, 0.0f, 0.0f }; - ID3D12GraphicsCommandList_ClearRenderTargetView(cl->cl, sig->ui_target->rtv_descriptor->handle, clear_color, 0, 0); + ID3D12GraphicsCommandList_ClearRenderTargetView(cl->cl, rsig->ui_target->rtv_descriptor->handle, clear_color, 0, 0); } } @@ -3114,8 +3105,7 @@ struct gp_resource *gp_run_render(struct gp_render_sig *render_sig, struct gp_re __profnc_dx12(cl->cq->prof, cl->cl, "UI blit pass", RGB32_F(0.5, 0.2, 0.2)); /* Bind pipeline */ - ID3D12GraphicsCommandList_SetPipelineState(cl->cl, blit_pipeline->pso); - ID3D12GraphicsCommandList_SetGraphicsRootSignature(cl->cl, blit_pipeline->rootsig); + command_list_set_pipeline(cl, blit_pipeline); /* Set Rasterizer State */ D3D12_VIEWPORT viewport = viewport_from_rect(ui_viewport); @@ -3123,17 +3113,14 @@ struct gp_resource *gp_run_render(struct gp_render_sig *render_sig, struct gp_re ID3D12GraphicsCommandList_RSSetViewports(cl->cl, 1, &viewport); ID3D12GraphicsCommandList_RSSetScissorRects(cl->cl, 1, &scissor); - /* Set constants */ - struct sh_blit_constants constants = ZI; - constants.projection = sh_float4x4_from_mat4x4(blit_vp_matrix); - constants.flags = sh_uint_from_u32(SH_BLIT_FLAG_TONE_MAP | SH_BLIT_FLAG_GAMMA_CORRECT); - constants.exposure = sh_float_from_f32(2.0); - constants.gamma = sh_float_from_f32((f32)2.2); - constants.tex_urid = sh_uint_from_u32(sig->shade_read->uav_descriptor->index); - - /* Set parameters */ - command_list_set_graphics_root_constant(cl, &constants, sizeof(constants)); - ID3D12GraphicsCommandList_SetGraphicsRootDescriptorTable(cl->cl, 1, descriptor_heap->start_gpu_handle); + /* Set sig */ + struct sh_blit_sig sig = ZI; + sig.projection = sh_float4x4_from_mat4x4(blit_vp_matrix); + sig.flags = sh_uint_from_u32(SH_BLIT_FLAG_TONE_MAP | SH_BLIT_FLAG_GAMMA_CORRECT); + sig.exposure = sh_float_from_f32(2.0); + sig.gamma = sh_float_from_f32((f32)2.2); + sig.tex_urid = sh_uint_from_u32(rsig->shade_read->uav_descriptor->index); + command_list_set_sig(cl, &sig, sizeof(sig)); /* Draw */ D3D12_VERTEX_BUFFER_VIEW vbv = vbv_from_command_buffer(dummy_vertex_buffer, 0); @@ -3150,8 +3137,7 @@ struct gp_resource *gp_run_render(struct gp_render_sig *render_sig, struct gp_re __profnc_dx12(cl->cq->prof, cl->cl, "UI rect pass", RGB32_F(0.5, 0.2, 0.2)); /* Bind pipeline */ - ID3D12GraphicsCommandList_SetPipelineState(cl->cl, ui_pipeline->pso); - ID3D12GraphicsCommandList_SetGraphicsRootSignature(cl->cl, ui_pipeline->rootsig); + command_list_set_pipeline(cl, ui_pipeline); /* Set Rasterizer State */ D3D12_VIEWPORT viewport = viewport_from_rect(ui_viewport); @@ -3159,14 +3145,11 @@ struct gp_resource *gp_run_render(struct gp_render_sig *render_sig, struct gp_re ID3D12GraphicsCommandList_RSSetViewports(cl->cl, 1, &viewport); ID3D12GraphicsCommandList_RSSetScissorRects(cl->cl, 1, &scissor); - /* Set constants */ - struct sh_ui_constants constants = ZI; - constants.projection = sh_float4x4_from_mat4x4(ui_vp_matrix); - - /* Set parameters */ - command_list_set_graphics_root_constant(cl, &constants, sizeof(constants)); - ID3D12GraphicsCommandList_SetGraphicsRootDescriptorTable(cl->cl, 1, descriptor_heap->start_gpu_handle); - ID3D12GraphicsCommandList_SetGraphicsRootShaderResourceView(cl->cl, 2, ui_rect_instance_buffer->resource->gpu_address); + /* Set sig */ + struct sh_ui_sig sig = ZI; + sig.projection = sh_float4x4_from_mat4x4(ui_vp_matrix); + sig.instances_urid = sh_uint_from_u32(ui_rect_instance_buffer->resource->srv_descriptor->index); + command_list_set_sig(cl, &sig, sizeof(sig)); /* Draw */ u32 instance_count = ui_rect_instance_buffer->size / sizeof(struct sh_ui_instance); @@ -3184,8 +3167,7 @@ struct gp_resource *gp_run_render(struct gp_render_sig *render_sig, struct gp_re __profnc_dx12(cl->cq->prof, cl->cl, "UI shape pass", RGB32_F(0.5, 0.2, 0.2)); /* Bind pipeline */ - ID3D12GraphicsCommandList_SetPipelineState(cl->cl, shape_pipeline->pso); - ID3D12GraphicsCommandList_SetGraphicsRootSignature(cl->cl, shape_pipeline->rootsig); + command_list_set_pipeline(cl, shape_pipeline); /* Set Rasterizer State */ D3D12_VIEWPORT viewport = viewport_from_rect(ui_viewport); @@ -3193,12 +3175,10 @@ struct gp_resource *gp_run_render(struct gp_render_sig *render_sig, struct gp_re ID3D12GraphicsCommandList_RSSetViewports(cl->cl, 1, &viewport); ID3D12GraphicsCommandList_RSSetScissorRects(cl->cl, 1, &scissor); - /* Set constants */ - struct sh_shape_constants constants = ZI; - constants.projection = sh_float4x4_from_mat4x4(ui_vp_matrix); - - /* Set parameters */ - command_list_set_graphics_root_constant(cl, &constants, sizeof(constants)); + /* Set sig */ + struct sh_shape_sig sig = ZI; + sig.projection = sh_float4x4_from_mat4x4(ui_vp_matrix); + command_list_set_sig(cl, &sig, sizeof(sig)); /* Draw */ u32 index_count = ui_shape_indices_buffer->size / sizeof(u32); @@ -3214,10 +3194,10 @@ struct gp_resource *gp_run_render(struct gp_render_sig *render_sig, struct gp_re pipeline_scope_end(pipeline_scope); sprite_scope_end(sprite_scope); - render_sig_reset(sig); + render_sig_reset(rsig); scratch_end(scratch); - return (struct gp_resource *)sig->ui_target; + return (struct gp_resource *)rsig->ui_target; } /* ========================== * @@ -3425,8 +3405,8 @@ INTERNAL void present_blit(struct swapchain_buffer *dst, struct dx12_resource *s /* TODO: Make these static */ /* Dummy vertex buffer */ LOCAL_PERSIST u16 quad_indices[6] = { 0, 1, 2, 0, 2, 3 }; - struct command_buffer *dummy_vertex_buffer = command_list_push_buffer(cl, STRING(0, 0)); - struct command_buffer *quad_index_buffer = command_list_push_buffer(cl, STRING_FROM_ARRAY(quad_indices)); + struct command_buffer *dummy_vertex_buffer = command_list_push_buffer(cl, 0, (u8 *)0); + struct command_buffer *quad_index_buffer = command_list_push_buffer(cl, countof(quad_indices), quad_indices); /* Upload descriptor heap */ struct command_descriptor_heap *descriptor_heap = command_list_push_descriptor_heap(cl, G.cbv_srv_uav_heap); @@ -3466,22 +3446,18 @@ INTERNAL void present_blit(struct swapchain_buffer *dst, struct dx12_resource *s ID3D12GraphicsCommandList_ClearRenderTargetView(cl->cl, dst->rtv_descriptor->handle, clear_color, 0, 0); /* Bind pipeline */ - ID3D12GraphicsCommandList_SetPipelineState(cl->cl, blit_pipeline->pso); - ID3D12GraphicsCommandList_SetGraphicsRootSignature(cl->cl, blit_pipeline->rootsig); + command_list_set_pipeline(cl, blit_pipeline); /* Set Rasterizer State */ ID3D12GraphicsCommandList_RSSetViewports(cl->cl, 1, &viewport); ID3D12GraphicsCommandList_RSSetScissorRects(cl->cl, 1, &scissor); - /* Set constants */ - struct sh_blit_constants constants = ZI; - constants.projection = sh_float4x4_from_mat4x4(vp_matrix); - constants.flags = sh_uint_from_u32(SH_BLIT_FLAG_NONE); - constants.tex_urid = sh_uint_from_u32(src->srv_descriptor->index); - - /* Set parameters */ - command_list_set_graphics_root_constant(cl, &constants, sizeof(constants)); - ID3D12GraphicsCommandList_SetGraphicsRootDescriptorTable(cl->cl, 1, descriptor_heap->start_gpu_handle); + /* Set sig */ + struct sh_blit_sig sig = ZI; + sig.projection = sh_float4x4_from_mat4x4(vp_matrix); + sig.flags = sh_uint_from_u32(SH_BLIT_FLAG_NONE); + sig.tex_urid = sh_uint_from_u32(src->srv_descriptor->index); + command_list_set_sig(cl, &sig, sizeof(sig)); /* Draw */ D3D12_VERTEX_BUFFER_VIEW vbv = vbv_from_command_buffer(dummy_vertex_buffer, 0); diff --git a/src/sh/blit.hlsl_rs b/src/sh/blit.hlsl_rs index 99a9717c..a131ca0e 100644 --- a/src/sh/blit.hlsl_rs +++ b/src/sh/blit.hlsl_rs @@ -1,24 +1,6 @@ #include "common.hlsl" -/* ========================== * - * Root signature - * ========================== */ - -#define ROOTSIG \ - "RootConstants(num32BitConstants = 20, b0), " \ - "DescriptorTable(SRV(t0, space = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE)), " \ - \ - "StaticSampler(s0, " \ - "filter = FILTER_MIN_MAG_MIP_POINT, " \ - "addressU = TEXTURE_ADDRESS_CLAMP, " \ - "addressV = TEXTURE_ADDRESS_CLAMP, " \ - "addressW = TEXTURE_ADDRESS_CLAMP, " \ - "maxAnisotropy = 1)" - -ConstantBuffer g_constants : register(b0); -Texture2D g_textures[] : register(t0); - -SamplerState g_sampler : register(s0); +ConstantBuffer sig : register(b0); /* ========================== * * Vertex shader @@ -33,7 +15,7 @@ struct vs_output { DECLS(float2, uv); }; -SH_ENTRY(ROOTSIG) struct vs_output vs(struct vs_input input) +SH_ENTRY struct vs_output vs(struct vs_input input) { static const float2 unit_quad_verts[4] = { float2(-0.5f, -0.5f), @@ -45,7 +27,7 @@ SH_ENTRY(ROOTSIG) struct vs_output vs(struct vs_input input) float2 vert = unit_quad_verts[input.SV_VertexID]; struct vs_output output; - output.SV_Position = mul(g_constants.projection, float4(vert, 0, 1)); + output.SV_Position = mul(sig.projection, float4(vert, 0, 1)); output.uv = vert + 0.5; return output; } @@ -73,21 +55,22 @@ struct ps_output { DECLS(float4, SV_Target); }; -SH_ENTRY(ROOTSIG) struct ps_output ps(struct ps_input input) +SH_ENTRY struct ps_output ps(struct ps_input input) { struct ps_output output; - float4 color = g_textures[g_constants.tex_urid].Sample(g_sampler, input.vs.uv); + Texture2D tex = resource_from_urid(sig.tex_urid); + float4 color = tex.Sample(s_point_clamp, input.vs.uv); /* Apply tone map */ - if (g_constants.flags & SH_BLIT_FLAG_TONE_MAP) { + if (sig.flags & SH_BLIT_FLAG_TONE_MAP) { /* TODO: Dynamic exposure based on average scene luminance */ - color.rgb *= g_constants.exposure; + color.rgb *= sig.exposure; color.rgb = tone_map(color.rgb); } /* Apply gamma correction */ - if (g_constants.flags & SH_BLIT_FLAG_GAMMA_CORRECT) { - color = pow(abs(color), 1/g_constants.gamma); + if (sig.flags & SH_BLIT_FLAG_GAMMA_CORRECT) { + color = pow(abs(color), 1/sig.gamma); } output.SV_Target = color; diff --git a/src/sh/common.hlsl b/src/sh/common.hlsl index 61119ae7..d35c95f5 100644 --- a/src/sh/common.hlsl +++ b/src/sh/common.hlsl @@ -5,7 +5,9 @@ #define GOLDEN 1.61803398875 #define DECLS(t, n) t n : n -#define NURID(i) NonUniformResourceIndex(i) + +#define resource_from_urid(urid) ResourceDescriptorHeap[(urid)] +#define resource_from_nurid(nurid) ResourceDescriptorHeap[NonUniformResourceIndex(nurid)] #if !SH_CPU # define INLINE /* For intellisense */ @@ -32,3 +34,22 @@ INLINE float4 linear_from_srgb32(uint srgb32) { return linear_from_srgb(float4_norm_from_uint(srgb32)); } + +/* ========================== * + * Root signature + * ========================== */ + +#define ROOTSIG \ + "RootFlags(CBV_SRV_UAV_HEAP_DIRECTLY_INDEXED | SAMPLER_HEAP_DIRECTLY_INDEXED | ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT), " \ + "RootConstants(b0, num32BitConstants = 64), " \ + \ + "StaticSampler(s0, " \ + "filter = FILTER_MIN_MAG_MIP_POINT, " \ + "addressU = TEXTURE_ADDRESS_CLAMP, " \ + "addressV = TEXTURE_ADDRESS_CLAMP, " \ + "addressW = TEXTURE_ADDRESS_CLAMP, " \ + "maxAnisotropy = 1)" + +SamplerState s_point_clamp: register(s0); + +#define SH_ENTRY [RootSignature(ROOTSIG)] diff --git a/src/sh/flood.hlsl_cs b/src/sh/flood.hlsl_cs index 38fc3d8b..b361d674 100644 --- a/src/sh/flood.hlsl_cs +++ b/src/sh/flood.hlsl_cs @@ -1,27 +1,6 @@ #include "common.hlsl" -/* ========================== * - * Root signature - * ========================== */ - -#define ROOTSIG \ - "RootConstants(num32BitConstants = 8, b0), " \ - "DescriptorTable(SRV(t0, space = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE)), " \ - "DescriptorTable(UAV(u0, space = 1, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE)), " \ - \ - \ - "StaticSampler(s0, " \ - "filter = FILTER_MIN_MAG_MIP_POINT, " \ - "addressU = TEXTURE_ADDRESS_CLAMP, " \ - "addressV = TEXTURE_ADDRESS_CLAMP, " \ - "addressW = TEXTURE_ADDRESS_CLAMP, " \ - "maxAnisotropy = 1)" - -ConstantBuffer g_constants : register(b0); -Texture2D g_emittance_textures[] : register(t0, space0); -RWTexture2D g_flood_textures[]: register(u0, space1); - -SamplerState g_sampler : register(s0); +ConstantBuffer sig : register(b0); /* ========================== * * Entry point @@ -32,15 +11,15 @@ struct cs_input { }; [numthreads(8, 8, 1)] -SH_ENTRY(ROOTSIG) void cs(struct cs_input input) +SH_ENTRY void cs(struct cs_input input) { uint2 id = input.SV_DispatchThreadID.xy; - uint2 tex_size = uint2(g_constants.tex_width, g_constants.tex_height); + uint2 tex_size = uint2(sig.tex_width, sig.tex_height); if (id.x < tex_size.x && id.y < tex_size.y) { - Texture2D emittance_tex = g_emittance_textures[g_constants.emittance_tex_urid]; - RWTexture2D read_flood_tex = g_flood_textures[g_constants.read_flood_tex_urid]; - RWTexture2D target_flood_tex = g_flood_textures[g_constants.target_flood_tex_urid]; - int step_len = g_constants.step_len; + Texture2D emittance_tex = resource_from_urid(sig.emittance_tex_urid); + RWTexture2D read_flood_tex = resource_from_urid(sig.read_flood_tex_urid); + RWTexture2D target_flood_tex = resource_from_urid(sig.target_flood_tex_urid); + int step_len = sig.step_len; if (step_len == -1) { /* Seed */ float4 emittance = emittance_tex[id]; diff --git a/src/sh/material.hlsl_rs b/src/sh/material.hlsl_rs index e7285a00..c0effae7 100644 --- a/src/sh/material.hlsl_rs +++ b/src/sh/material.hlsl_rs @@ -1,28 +1,6 @@ #include "common.hlsl" -/* ========================== * - * Root signature - * ========================== */ - -#define ROOTSIG \ - "RootConstants(num32BitConstants = 16, b0), " \ - "DescriptorTable(SRV(t0, space = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE)), " \ - "SRV(t0, space = 1), " \ - "SRV(t0, space = 2), " \ - \ - "StaticSampler(s0, " \ - "filter = FILTER_MIN_MAG_MIP_POINT, " \ - "addressU = TEXTURE_ADDRESS_CLAMP, " \ - "addressV = TEXTURE_ADDRESS_CLAMP, " \ - "addressW = TEXTURE_ADDRESS_CLAMP, " \ - "maxAnisotropy = 1)" - -ConstantBuffer g_constants : register(b0); -Texture2D g_textures[] : register(t0, space0); -StructuredBuffer g_instances : register(t0, space1); -StructuredBuffer g_grids : register(t0, space2); - -SamplerState g_sampler : register(s0); +ConstantBuffer sig : register(b0); /* ========================== * * Vertex shader @@ -42,7 +20,7 @@ struct vs_output { DECLS(float4, SV_Position); }; -SH_ENTRY(ROOTSIG) struct vs_output vs(struct vs_input input) +SH_ENTRY struct vs_output vs(struct vs_input input) { static const float2 unit_quad_verts[4] = { float2(-0.5f, -0.5f), @@ -50,12 +28,12 @@ SH_ENTRY(ROOTSIG) struct vs_output vs(struct vs_input input) float2(0.5f, 0.5f), float2(-0.5f, 0.5f) }; - - struct sh_material_instance instance = g_instances[input.SV_InstanceID]; + StructuredBuffer instances = resource_from_urid(sig.instances_urid); + struct sh_material_instance instance = instances[input.SV_InstanceID]; float2 vert = unit_quad_verts[input.SV_VertexID]; float2 world_pos = mul(instance.xf, float3(vert, 1)).xy; struct vs_output output; - output.SV_Position = mul(g_constants.projection, float4(world_pos, 0, 1)); + output.SV_Position = mul(sig.projection, float4(world_pos, 0, 1)); output.tex_nurid = instance.tex_nurid; output.grid_id = instance.grid_id; output.uv = instance.uv0 + ((vert + 0.5) * (instance.uv1 - instance.uv0)); @@ -77,20 +55,21 @@ struct ps_output { DECLS(float4, SV_Target1); /* Emittance */ }; -SH_ENTRY(ROOTSIG) struct ps_output ps(struct ps_input input) +SH_ENTRY struct ps_output ps(struct ps_input input) { struct ps_output output; float4 albedo = input.vs.tint_lin; /* Texture */ if (input.vs.tex_nurid >= 0) { - Texture2D tex = g_textures[NURID(input.vs.tex_nurid)]; - albedo *= tex.Sample(g_sampler, input.vs.uv); + Texture2D tex = resource_from_nurid(input.vs.tex_nurid); + albedo *= tex.Sample(s_point_clamp, input.vs.uv); } /* Grid */ if (input.vs.grid_id >= 0) { - struct sh_material_grid grid = g_grids[input.vs.grid_id]; + StructuredBuffer grids = resource_from_urid(sig.grids_urid); + struct sh_material_grid grid = grids[input.vs.grid_id]; float2 grid_pos = input.vs.SV_Position.xy + grid.offset; float half_thickness = grid.line_thickness / 2; float spacing = grid.line_spacing; diff --git a/src/sh/sh_common.h b/src/sh/sh_common.h index f75f6567..5d3f0542 100644 --- a/src/sh/sh_common.h +++ b/src/sh/sh_common.h @@ -3,10 +3,6 @@ #define SH_STRUCT(s) PACK(struct s) #define SH_DECL(t, n) struct CAT(sh_, t) n #define SH_DECLS(t, n) SH_DECL(t, n) -#define SH_ENTRY(rootsig) static -#define SH_ASSERT_ROOT_CONST(s, n) STATIC_ASSERT((sizeof(s) % 16 == 0) && /* Root constant struct should pad to 16 byte alignment */ \ - ((sizeof(s) / 4) == n) && /* Root constant struct size should match the specified 32-bit-constant count */ \ - (sizeof(s) <= 256)) /* Root constant struct can only fit 64 DWORDS */ struct sh_uint { u32 v; }; INLINE struct sh_uint sh_uint_from_u32(u32 v) @@ -79,8 +75,6 @@ INLINE struct sh_float2x3 sh_float2x3_from_xform(struct xform v) #define SH_STRUCT(s) struct s #define SH_DECL(t, n) t n #define SH_DECLS(t, n) t n : n -#define SH_ENTRY(rootsig) [RootSignature(rootsig)] -#define SH_ASSERT_ROOT_CONST(s, n) #endif @@ -95,16 +89,18 @@ INLINE struct sh_float2x3 sh_float2x3_from_xform(struct xform v) #define SH_BLUE_NOISE_TEX_DEPTH 64 /* ========================== * - * Material shader structures + * Material shader structs * ========================== */ -SH_STRUCT(sh_material_constants { +SH_STRUCT(sh_material_sig { /* ---------------------------------------------------- */ SH_DECL(float4x4, projection); /* 16 consts */ /* ---------------------------------------------------- */ - + SH_DECL(uint, instances_urid); /* 01 consts */ + SH_DECL(uint, grids_urid); /* 01 consts */ + SH_DECL(uint2, _pad0); /* 02 consts (padding) */ + /* ---------------------------------------------------- */ }); -SH_ASSERT_ROOT_CONST(struct sh_material_constants, 16); /* Expected to match num32BitConstants in shader's root signature */ SH_STRUCT(sh_material_instance { SH_DECL(int, tex_nurid); @@ -129,10 +125,10 @@ SH_STRUCT(sh_material_grid { }); /* ========================== * - * Flood shader structures + * Flood shader structs * ========================== */ -SH_STRUCT(sh_flood_constants { +SH_STRUCT(sh_flood_sig { /* ---------------------------------------------------- */ SH_DECL(int, step_len); /* 01 consts */ SH_DECL(uint, emittance_tex_urid); /* 01 consts */ @@ -144,16 +140,15 @@ SH_STRUCT(sh_flood_constants { SH_DECL(uint2, _pad0); /* 02 consts (padding) */ /* ---------------------------------------------------- */ }); -SH_ASSERT_ROOT_CONST(struct sh_flood_constants, 8); /* Expected to match num32BitConstants in shader's root signature */ /* ========================== * - * Shade shader structures + * Shade shader structs * ========================== */ #define SH_SHADE_FLAG_NONE (0 << 0) #define SH_SHADE_FLAG_DISABLE_EFFECTS (1 << 0) -SH_STRUCT(sh_shade_constants { +SH_STRUCT(sh_shade_sig { /* ---------------------------------------------------- */ SH_DECL(uint4, frame_seed); /* 04 consts */ /* ---------------------------------------------------- */ @@ -172,18 +167,16 @@ SH_STRUCT(sh_shade_constants { SH_DECL(uint, target_tex_urid); /* 01 consts */ /* ---------------------------------------------------- */ }); -SH_ASSERT_ROOT_CONST(struct sh_shade_constants, 16); /* Expected to match num32BitConstants in shader's root signature */ /* ========================== * - * Shape shader structures + * Shape shader structs * ========================== */ -SH_STRUCT(sh_shape_constants { +SH_STRUCT(sh_shape_sig { /* ---------------------------------------------------- */ SH_DECL(float4x4, projection); /* 16 consts */ /* ---------------------------------------------------- */ }); -SH_ASSERT_ROOT_CONST(struct sh_shape_constants, 16); /* Expected to match num32BitConstants in shader's root signature */ SH_STRUCT(sh_shape_vert { SH_DECLS(float2, pos); @@ -191,15 +184,17 @@ SH_STRUCT(sh_shape_vert { }); /* ========================== * - * UI shader structures + * UI shader structs * ========================== */ -SH_STRUCT(sh_ui_constants { +SH_STRUCT(sh_ui_sig { /* ---------------------------------------------------- */ SH_DECL(float4x4, projection); /* 16 consts */ /* ---------------------------------------------------- */ + SH_DECL(uint, instances_urid); /* 01 consts */ + SH_DECL(uint3, _pad0); /* 03 consts (padding) */ + /* ---------------------------------------------------- */ }); -SH_ASSERT_ROOT_CONST(struct sh_ui_constants, 16); /* Expected to match num32BitConstants in shader's root signature */ SH_STRUCT(sh_ui_instance { SH_DECL(int, tex_nurid); @@ -211,14 +206,14 @@ SH_STRUCT(sh_ui_instance { }); /* ========================== * - * Blit shader structures + * Blit shader structs * ========================== */ #define SH_BLIT_FLAG_NONE (0 << 0) #define SH_BLIT_FLAG_TONE_MAP (1 << 0) #define SH_BLIT_FLAG_GAMMA_CORRECT (1 << 1) -SH_STRUCT(sh_blit_constants { +SH_STRUCT(sh_blit_sig { /* ---------------------------------------------------- */ SH_DECL(float4x4, projection); /* 16 consts */ /* ---------------------------------------------------- */ @@ -228,4 +223,3 @@ SH_STRUCT(sh_blit_constants { SH_DECL(float, gamma); /* 01 consts */ /* ---------------------------------------------------- */ }); -SH_ASSERT_ROOT_CONST(struct sh_blit_constants, 20); /* Expected to match num32BitConstants in shader's root signature */ diff --git a/src/sh/shade.hlsl_cs b/src/sh/shade.hlsl_cs index 1ed4d0ec..b1f6c6a6 100644 --- a/src/sh/shade.hlsl_cs +++ b/src/sh/shade.hlsl_cs @@ -1,25 +1,6 @@ #include "common.hlsl" -/* ========================== * - * Root signature - * ========================== */ - -#define ROOTSIG \ - "RootConstants(num32BitConstants = 16, b0), " \ - "DescriptorTable(SRV(t0, space = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE)), " \ - "DescriptorTable(SRV(t0, space = 1, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE)), " \ - "DescriptorTable(SRV(t0, space = 2, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE)), " \ - "DescriptorTable(UAV(u0, space = 3, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE)), " - -ConstantBuffer g_constants : register(b0); -Texture2D g_textures_float4[] : register(t0, space0); -Texture2D g_textures_uint2[] : register(t0, space1); -Texture3D g_noise_textures[] : register(t0, space2); -RWTexture2D g_target_textures[]: register(u0, space3); - -struct cs_input { - DECLS(uint3, SV_DispatchThreadID); -}; +ConstantBuffer sig : register(b0); /* ========================== * * Lighting @@ -30,12 +11,12 @@ struct cs_input { #define EDGE_FALLOFF 100 float rand_angle(uint2 pos, uint ray_index) { - Texture3D noise_tex = g_noise_textures[SH_BLUE_NOISE_TEX_ID]; + Texture3D noise_tex = resource_from_urid(SH_BLUE_NOISE_TEX_ID); int3 noise_coord = int3(1, 1, 1); noise_coord += int3(pos.xy, ray_index); - noise_coord.xyz += g_constants.frame_seed.xyz; - // noise_coord.xy -= g_constants.camera_offset; + noise_coord.xyz += sig.frame_seed.xyz; + // noise_coord.xy -= sig.camera_offset; uint noise = noise_tex[noise_coord % uint3(SH_BLUE_NOISE_TEX_WIDTH, SH_BLUE_NOISE_TEX_HEIGHT, SH_BLUE_NOISE_TEX_DEPTH)]; return ((float)noise / (float)0xFFFF) * TAU; @@ -43,8 +24,8 @@ float rand_angle(uint2 pos, uint ray_index) { INLINE float3 get_light_in_dir(uint2 ray_start, float2 ray_dir) { - Texture2D flood_tex = g_textures_uint2[g_constants.emittance_flood_tex_urid]; - Texture2D emittance_tex = g_textures_float4[g_constants.emittance_tex_urid]; + Texture2D flood_tex = resource_from_urid(sig.emittance_flood_tex_urid); + Texture2D emittance_tex = resource_from_urid(sig.emittance_tex_urid); float3 result = float3(0, 0, 0); float2 at_float = ray_start; @@ -55,15 +36,15 @@ INLINE float3 get_light_in_dir(uint2 ray_start, float2 ray_dir) float dist = length(dist_vec); if (dist < 1) { /* Scale light by distance from edge so that offscreen-lights fade in/out rather than popping in */ - float dist_x = min(abs(g_constants.tex_width - at_float.x), at_float.x); - float dist_y = min(abs(g_constants.tex_height - at_float.y), at_float.y); + float dist_x = min(abs(sig.tex_width - at_float.x), at_float.x); + float dist_y = min(abs(sig.tex_height - at_float.y), at_float.y); float dist_scale = min(min(dist_x, dist_y) / EDGE_FALLOFF, 1); result = emittance_tex[flood].rgb * dist_scale; break; } else { at_float += ray_dir * dist; at_uint = round(at_float); - if (at_uint.x < 0 || at_uint.x >= g_constants.tex_width || at_uint.y < 0 || at_uint.y >= g_constants.tex_height) { + if (at_uint.x < 0 || at_uint.x >= sig.tex_width || at_uint.y < 0 || at_uint.y >= sig.tex_height) { /* Ray hit edge of screen */ break; } @@ -89,21 +70,25 @@ INLINE float3 get_light_at_pos(uint2 pos) * Entry point * ========================== */ +struct cs_input { + DECLS(uint3, SV_DispatchThreadID); +}; + [numthreads(8, 8, 1)] -SH_ENTRY(ROOTSIG) void cs(struct cs_input input) +SH_ENTRY void cs(struct cs_input input) { uint2 id = input.SV_DispatchThreadID.xy; - if (id.x < g_constants.tex_width && id.y < g_constants.tex_height) { - Texture2D albedo_tex = g_textures_float4[g_constants.albedo_tex_urid]; - Texture2D read_tex = g_textures_float4[g_constants.read_tex_urid]; - RWTexture2D target_tex = g_target_textures[g_constants.target_tex_urid]; + if (id.x < sig.tex_width && id.y < sig.tex_height) { + Texture2D albedo_tex = resource_from_urid(sig.albedo_tex_urid); + Texture2D read_tex = resource_from_urid(sig.read_tex_urid); + RWTexture2D target_tex = resource_from_urid(sig.target_tex_urid); float4 color = float4(1, 1, 1, 1); /* Apply albedo */ color *= albedo_tex[id]; /* Apply lighting */ - if (!(g_constants.flags & SH_SHADE_FLAG_DISABLE_EFFECTS)) { + if (!(sig.flags & SH_SHADE_FLAG_DISABLE_EFFECTS)) { color.rgb *= get_light_at_pos(id); } diff --git a/src/sh/shape.hlsl_rs b/src/sh/shape.hlsl_rs index 8907b85c..810147b7 100644 --- a/src/sh/shape.hlsl_rs +++ b/src/sh/shape.hlsl_rs @@ -1,14 +1,6 @@ #include "common.hlsl" -/* ========================== * - * Root signature - * ========================== */ - -#define ROOTSIG \ - "RootFlags(ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT), " \ - "RootConstants(num32BitConstants=16, b0)" - -ConstantBuffer g_constants : register(b0); +ConstantBuffer sig : register(b0); /* ========================== * * Vertex shader @@ -24,10 +16,10 @@ struct vs_output { DECLS(float4, color_srgb); }; -SH_ENTRY(ROOTSIG) struct vs_output vs(struct vs_input input) +SH_ENTRY struct vs_output vs(struct vs_input input) { struct vs_output output; - output.SV_Position = mul(g_constants.projection, float4(input.pos.xy, 0, 1)); + output.SV_Position = mul(sig.projection, float4(input.pos.xy, 0, 1)); output.color_srgb = input.color_srgb; return output; } @@ -44,7 +36,7 @@ struct ps_output { DECLS(float4, SV_Target); }; -SH_ENTRY(ROOTSIG) struct ps_output ps(struct ps_input input) +SH_ENTRY struct ps_output ps(struct ps_input input) { struct ps_output output; output.SV_Target = input.vs.color_srgb; diff --git a/src/sh/ui.hlsl_rs b/src/sh/ui.hlsl_rs index fb0463f0..cacae341 100644 --- a/src/sh/ui.hlsl_rs +++ b/src/sh/ui.hlsl_rs @@ -1,26 +1,6 @@ #include "common.hlsl" -/* ========================== * - * Root signature - * ========================== */ - -#define ROOTSIG \ - "RootConstants(num32BitConstants = 16, b0), " \ - "DescriptorTable(SRV(t0, space = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE)), " \ - "SRV(t0, space = 1), " \ - \ - "StaticSampler(s0, " \ - "filter = FILTER_MIN_MAG_MIP_POINT, " \ - "addressU = TEXTURE_ADDRESS_CLAMP, " \ - "addressV = TEXTURE_ADDRESS_CLAMP, " \ - "addressW = TEXTURE_ADDRESS_CLAMP, " \ - "maxAnisotropy = 1)" - -ConstantBuffer g_constants : register(b0); -Texture2D g_textures[] : register(t0, space0); -StructuredBuffer g_instances : register(t0, space1); - -SamplerState g_sampler : register(s0); +ConstantBuffer sig : register(b0); /* ========================== * * Vertex shader @@ -38,7 +18,7 @@ struct vs_output { DECLS(float4, SV_Position); }; -SH_ENTRY(ROOTSIG) struct vs_output vs(struct vs_input input) +SH_ENTRY struct vs_output vs(struct vs_input input) { static const float2 unit_quad_verts[4] = { float2(-0.5f, -0.5f), @@ -47,12 +27,13 @@ SH_ENTRY(ROOTSIG) struct vs_output vs(struct vs_input input) float2(-0.5f, 0.5f) }; - struct sh_ui_instance instance = g_instances[input.SV_InstanceID]; + StructuredBuffer instances = resource_from_urid(sig.instances_urid); + struct sh_ui_instance instance = instances[input.SV_InstanceID]; float2 vert = unit_quad_verts[input.SV_VertexID]; float2 world_pos = mul(instance.xf, float3(vert, 1)).xy; struct vs_output output; - output.SV_Position = mul(g_constants.projection, float4(world_pos, 0, 1)); + output.SV_Position = mul(sig.projection, float4(world_pos, 0, 1)); output.tex_nurid = instance.tex_nurid; output.uv = instance.uv0 + ((vert + 0.5) * (instance.uv1 - instance.uv0)); output.tint_srgb = float4_norm_from_uint(instance.tint_srgb); @@ -71,15 +52,15 @@ struct ps_output { DECLS(float4, SV_Target0); }; -SH_ENTRY(ROOTSIG) struct ps_output ps(struct ps_input input) +SH_ENTRY struct ps_output ps(struct ps_input input) { struct ps_output output; float4 color = input.vs.tint_srgb; /* Texture */ if (input.vs.tex_nurid >= 0) { - Texture2D tex = g_textures[NURID(input.vs.tex_nurid)]; - color *= tex.Sample(g_sampler, input.vs.uv); + Texture2D tex = resource_from_nurid(input.vs.tex_nurid); + color *= tex.Sample(s_point_clamp, input.vs.uv); } output.SV_Target0 = color; diff --git a/src/sys_win32.c b/src/sys_win32.c index 283369d3..6ba7caa9 100644 --- a/src/sys_win32.c +++ b/src/sys_win32.c @@ -1375,7 +1375,7 @@ INTERNAL THREAD_DEF(job_worker_entry, worker_ctx_arg) //__profnc("Wait for job", RGB32_F(0.75, 0.75, 0)); tm_lock(&pool->workers_wake_lock); { - i64 num_jobs_in_queue = atomic64_fetch(&pool->num_jobs_in_queue.v); + num_jobs_in_queue = atomic64_fetch(&pool->num_jobs_in_queue.v); shutdown = atomic32_fetch(&pool->workers_shutdown.v); while (num_jobs_in_queue <= 0 && !shutdown) { { diff --git a/src/user.c b/src/user.c index a3c0c15b..6fbe1b2b 100644 --- a/src/user.c +++ b/src/user.c @@ -176,7 +176,7 @@ GLOBAL READONLY enum user_bind_kind g_binds[SYS_BTN_COUNT] = { [SYS_BTN_F1] = USER_BIND_KIND_DEBUG_PAUSE, [SYS_BTN_F2] = USER_BIND_KIND_DEBUG_CAMERA, [SYS_BTN_F3] = USER_BIND_KIND_DEBUG_DRAW, - [SYS_BTN_F5] = USER_BIND_KIND_DEBUG_TOGGLE_TOPMOST, + [SYS_BTN_F4] = USER_BIND_KIND_DEBUG_TOGGLE_TOPMOST, [SYS_BTN_GRAVE_ACCENT] = USER_BIND_KIND_DEBUG_CONSOLE, [SYS_BTN_ALT] = USER_BIND_KIND_FULLSCREEN_MOD, [SYS_BTN_ENTER] = USER_BIND_KIND_FULLSCREEN,