From 1655d699cef7b7d76288875967146eea487b8430 Mon Sep 17 00:00:00 2001 From: jacob Date: Sun, 8 Jun 2025 19:36:30 -0500 Subject: [PATCH] validate shader source file exists --- res/gpu/{texture.hlsl => material.hlsl} | 0 src/gpu_dx12.c | 72 ++++++++++++++++--------- 2 files changed, 46 insertions(+), 26 deletions(-) rename res/gpu/{texture.hlsl => material.hlsl} (100%) diff --git a/res/gpu/texture.hlsl b/res/gpu/material.hlsl similarity index 100% rename from res/gpu/texture.hlsl rename to res/gpu/material.hlsl diff --git a/src/gpu_dx12.c b/src/gpu_dx12.c index a46a94de..66c5f790 100644 --- a/src/gpu_dx12.c +++ b/src/gpu_dx12.c @@ -64,6 +64,7 @@ struct pipeline { struct pipeline_result { struct pipeline pipeline; + i64 elapsed; u64 errors_text_len; u8 errors_text[KILOBYTE(16)]; }; @@ -536,6 +537,9 @@ INTERNAL void dx12_init_base(struct sys_window *window) * Dx12 pipeline initialization * ========================== */ +/* For shared C-HLSL headers */ +#define GPU 0 + /* TDOO: Rename 'mesh shader' to 'triangle shader' or something */ /* TODO: Move shader structs into shared file */ @@ -543,7 +547,7 @@ INTERNAL void dx12_init_base(struct sys_window *window) /* Mesh pipeline */ /* ============= */ -/* Texture pipeline */ +/* Material pipeline */ PACK(struct dx12_buffer_pipeline_uniform { struct mat4x4 vp; @@ -572,11 +576,11 @@ INTERNAL void dx12_init_pipelines(void) __prof; struct arena_temp scratch = scratch_begin_no_conflict(); struct pipeline_desc pipeline_descs[] = { - /* Texture pipeline */ + /* Material pipeline */ { - .name = "texture", - .vs = { "gpu/texture.hlsl", "vs" }, - .ps = { "gpu/texture.hlsl", "ps" } + .name = "material", + .vs = { "gpu/material.hlsl", "vs" }, + .ps = { "gpu/material.hlsl", "ps" } } }; @@ -685,6 +689,7 @@ struct shader_compile_task_arg { b32 success; ID3DBlob *blob; ID3DBlob *error_blob; + i64 elapsed; }; /* TODO: Compile shaders offline w/ dxc for performance & language features like static_assert */ @@ -699,6 +704,7 @@ INTERNAL WORK_TASK_FUNC_DEF(shader_compile_task, comp_arg_raw) struct arena_temp scratch = scratch_begin_no_conflict(); { + i64 start_ns = sys_time_ns(); b32 success = false; ID3DBlob *blob = NULL; ID3DBlob *error_blob = NULL; @@ -735,7 +741,11 @@ INTERNAL WORK_TASK_FUNC_DEF(shader_compile_task, comp_arg_raw) target = "ps_5_1"; } break; } - HRESULT hr = D3DCompile(shader_src.text, shader_src.len, friendly_name_cstr, NULL, (ID3DInclude *)&include_handler, shader_desc.func, target, d3d_compile_flags, 0, &blob, &error_blob); + D3D_SHADER_MACRO defines[] = { + { "GPU", "1" }, + { 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); success = SUCCEEDED(hr) && !error_blob; } @@ -751,11 +761,7 @@ INTERNAL WORK_TASK_FUNC_DEF(shader_compile_task, comp_arg_raw) comp_arg->success = success; comp_arg->blob = blob; comp_arg->error_blob = error_blob; - - #if 0 - shader->valid = true; - #endif - + comp_arg->elapsed = sys_time_ns() - start_ns; } scratch_end(scratch); } @@ -779,8 +785,10 @@ INTERNAL WORK_TASK_FUNC_DEF(pipeline_load_task, load_arg_raw) struct arena_temp scratch = scratch_begin_no_conflict(); { + i64 start_ns = sys_time_ns(); struct string pipeline_name = string_from_cstr_no_limit(desc.name); logf_info("Loading pipeline \"%F\"", FMT_STR(pipeline_name)); + b32 success = true; HRESULT hr = 0; struct string error_str = LIT("Unknown error"); @@ -795,6 +803,16 @@ INTERNAL WORK_TASK_FUNC_DEF(pipeline_load_task, load_arg_raw) ps_res = resource_open(ps_filename); } + if (success) { + if (!resource_exists(&vs_res)) { + error_str = string_format(scratch.arena, LIT("Shader source \"%F\" not found"), FMT_STR(vs_filename)); + success = false; + } else if (!resource_exists(&ps_res)) { + error_str = string_format(scratch.arena, LIT("Shader source \"%F\" not found"), FMT_STR(ps_filename)); + success = false; + } + } + struct shader_compile_task_arg vs = ZI; vs.kind = SHADER_COMPILE_TASK_KIND_VS; vs.pipeline = pipeline; @@ -808,18 +826,19 @@ INTERNAL WORK_TASK_FUNC_DEF(pipeline_load_task, load_arg_raw) ps.shader_res = &ps_res; /* Compile shaders */ - struct work_slate ws = work_slate_begin(); - work_slate_push_task(&ws, shader_compile_task, &vs); - work_slate_push_task(&ws, shader_compile_task, &ps); - struct work_handle work = work_slate_end_and_help(&ws, WORK_PRIORITY_NORMAL); - work_wait(work); - - b32 success = vs.success && ps.success; + if (success) { + struct work_slate ws = work_slate_begin(); + work_slate_push_task(&ws, shader_compile_task, &vs); + work_slate_push_task(&ws, shader_compile_task, &ps); + struct work_handle work = work_slate_end_and_help(&ws, WORK_PRIORITY_NORMAL); + work_wait(work); + success = vs.success && ps.success; + } /* Get root signature blob - * NOTE: This isn't necessary for creating the RS (since it can just - * take the shader blob), however we'd like to verify that the root - * signature exists and matches between shaders. */ + * NOTE: This isn't necessary for creating the root signature (since it + * could reuse the shader blob), however we'd like to verify that the + * root signature exists and matches between shaders. */ ID3D10Blob *rs_blob = NULL; if (success) { __profscope(Validate root signatures); @@ -839,14 +858,13 @@ INTERNAL WORK_TASK_FUNC_DEF(pipeline_load_task, load_arg_raw) ps_rs_data = ID3D10Blob_GetBufferPointer(ps_rs_blob); ps_rs_data_len = ID3D10Blob_GetBufferSize(ps_rs_blob); } - u32 cmp_len = min_u32(vs_rs_data_len, ps_rs_data_len); if (vs_rs_data_len == 0) { success = false; error_str = LIT("Vertex shader is missing root signature"); } else if (ps_rs_data_len == 0) { success = false; error_str = LIT("Pixel shader is missing root signature"); - } else if (!MEMEQ(vs_rs_data, ps_rs_data, cmp_len)) { + } else if (vs_rs_data_len != ps_rs_data_len || !MEMEQ(vs_rs_data, ps_rs_data, vs_rs_data_len)) { success = false; error_str = LIT("Root signature mismatch between vertex and pixel shader"); } else { @@ -955,6 +973,7 @@ INTERNAL WORK_TASK_FUNC_DEF(pipeline_load_task, load_arg_raw) pipeline->pso = pso; pipeline->rs = rs; + result->elapsed = sys_time_ns() - start_ns; resource_close(&vs_res); if (!ps_res_is_shared) { @@ -1083,7 +1102,7 @@ struct gpu_handle gpu_dispatch_state_alloc(void) } #if 0 -void gpu_dispatch(struct gpu_handle gpu_dispatch_state, struct gpu_dispatch_params params, struct gpu_handle gpu_command_list) +void gpu_dispatch(struct gpu_handle gpu_dispatch_state, struct gpu_dispatch_params params) { (UNUSED)gpu_dispatch_state; (UNUSED)params; @@ -1092,9 +1111,10 @@ void gpu_dispatch(struct gpu_handle gpu_dispatch_state, struct gpu_dispatch_para struct dx12_command_list *command_list = handle_get_data(gpu_command_list, DX12_HANDLE_KIND_COMMAND_LIST); - /* Texture pass */ + /* Material pass */ { - struct pipeline *pipeline = dx12_get_pipeline(pipeline_scope, LIT("gpu/texture.hlsl")); + struct pipeline *pipeline = dx12_get_pipeline(pipeline_scope, LIT("material")); + } pipeline_scope_end(pipeline_scope);