validate shader source file exists

This commit is contained in:
jacob 2025-06-08 19:36:30 -05:00
parent 54a8a45835
commit 1655d699ce
2 changed files with 46 additions and 26 deletions

View File

@ -64,6 +64,7 @@ struct pipeline {
struct pipeline_result { struct pipeline_result {
struct pipeline pipeline; struct pipeline pipeline;
i64 elapsed;
u64 errors_text_len; u64 errors_text_len;
u8 errors_text[KILOBYTE(16)]; u8 errors_text[KILOBYTE(16)];
}; };
@ -536,6 +537,9 @@ INTERNAL void dx12_init_base(struct sys_window *window)
* Dx12 pipeline initialization * Dx12 pipeline initialization
* ========================== */ * ========================== */
/* For shared C-HLSL headers */
#define GPU 0
/* TDOO: Rename 'mesh shader' to 'triangle shader' or something */ /* TDOO: Rename 'mesh shader' to 'triangle shader' or something */
/* TODO: Move shader structs into shared file */ /* TODO: Move shader structs into shared file */
@ -543,7 +547,7 @@ INTERNAL void dx12_init_base(struct sys_window *window)
/* Mesh pipeline */ /* Mesh pipeline */
/* ============= */ /* ============= */
/* Texture pipeline */ /* Material pipeline */
PACK(struct dx12_buffer_pipeline_uniform { PACK(struct dx12_buffer_pipeline_uniform {
struct mat4x4 vp; struct mat4x4 vp;
@ -572,11 +576,11 @@ INTERNAL void dx12_init_pipelines(void)
__prof; __prof;
struct arena_temp scratch = scratch_begin_no_conflict(); struct arena_temp scratch = scratch_begin_no_conflict();
struct pipeline_desc pipeline_descs[] = { struct pipeline_desc pipeline_descs[] = {
/* Texture pipeline */ /* Material pipeline */
{ {
.name = "texture", .name = "material",
.vs = { "gpu/texture.hlsl", "vs" }, .vs = { "gpu/material.hlsl", "vs" },
.ps = { "gpu/texture.hlsl", "ps" } .ps = { "gpu/material.hlsl", "ps" }
} }
}; };
@ -685,6 +689,7 @@ struct shader_compile_task_arg {
b32 success; b32 success;
ID3DBlob *blob; ID3DBlob *blob;
ID3DBlob *error_blob; ID3DBlob *error_blob;
i64 elapsed;
}; };
/* TODO: Compile shaders offline w/ dxc for performance & language features like static_assert */ /* 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(); struct arena_temp scratch = scratch_begin_no_conflict();
{ {
i64 start_ns = sys_time_ns();
b32 success = false; b32 success = false;
ID3DBlob *blob = NULL; ID3DBlob *blob = NULL;
ID3DBlob *error_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"; target = "ps_5_1";
} break; } 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; 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->success = success;
comp_arg->blob = blob; comp_arg->blob = blob;
comp_arg->error_blob = error_blob; comp_arg->error_blob = error_blob;
comp_arg->elapsed = sys_time_ns() - start_ns;
#if 0
shader->valid = true;
#endif
} }
scratch_end(scratch); 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(); 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); struct string pipeline_name = string_from_cstr_no_limit(desc.name);
logf_info("Loading pipeline \"%F\"", FMT_STR(pipeline_name)); logf_info("Loading pipeline \"%F\"", FMT_STR(pipeline_name));
b32 success = true;
HRESULT hr = 0; HRESULT hr = 0;
struct string error_str = LIT("Unknown error"); 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); 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; struct shader_compile_task_arg vs = ZI;
vs.kind = SHADER_COMPILE_TASK_KIND_VS; vs.kind = SHADER_COMPILE_TASK_KIND_VS;
vs.pipeline = pipeline; vs.pipeline = pipeline;
@ -808,18 +826,19 @@ INTERNAL WORK_TASK_FUNC_DEF(pipeline_load_task, load_arg_raw)
ps.shader_res = &ps_res; ps.shader_res = &ps_res;
/* Compile shaders */ /* Compile shaders */
struct work_slate ws = work_slate_begin(); if (success) {
work_slate_push_task(&ws, shader_compile_task, &vs); struct work_slate ws = work_slate_begin();
work_slate_push_task(&ws, shader_compile_task, &ps); work_slate_push_task(&ws, shader_compile_task, &vs);
struct work_handle work = work_slate_end_and_help(&ws, WORK_PRIORITY_NORMAL); work_slate_push_task(&ws, shader_compile_task, &ps);
work_wait(work); struct work_handle work = work_slate_end_and_help(&ws, WORK_PRIORITY_NORMAL);
work_wait(work);
b32 success = vs.success && ps.success; success = vs.success && ps.success;
}
/* Get root signature blob /* Get root signature blob
* NOTE: This isn't necessary for creating the RS (since it can just * NOTE: This isn't necessary for creating the root signature (since it
* take the shader blob), however we'd like to verify that the root * could reuse the shader blob), however we'd like to verify that the
* signature exists and matches between shaders. */ * root signature exists and matches between shaders. */
ID3D10Blob *rs_blob = NULL; ID3D10Blob *rs_blob = NULL;
if (success) { if (success) {
__profscope(Validate root signatures); __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 = ID3D10Blob_GetBufferPointer(ps_rs_blob);
ps_rs_data_len = ID3D10Blob_GetBufferSize(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) { if (vs_rs_data_len == 0) {
success = false; success = false;
error_str = LIT("Vertex shader is missing root signature"); error_str = LIT("Vertex shader is missing root signature");
} else if (ps_rs_data_len == 0) { } else if (ps_rs_data_len == 0) {
success = false; success = false;
error_str = LIT("Pixel shader is missing root signature"); 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; success = false;
error_str = LIT("Root signature mismatch between vertex and pixel shader"); error_str = LIT("Root signature mismatch between vertex and pixel shader");
} else { } else {
@ -955,6 +973,7 @@ INTERNAL WORK_TASK_FUNC_DEF(pipeline_load_task, load_arg_raw)
pipeline->pso = pso; pipeline->pso = pso;
pipeline->rs = rs; pipeline->rs = rs;
result->elapsed = sys_time_ns() - start_ns;
resource_close(&vs_res); resource_close(&vs_res);
if (!ps_res_is_shared) { if (!ps_res_is_shared) {
@ -1083,7 +1102,7 @@ struct gpu_handle gpu_dispatch_state_alloc(void)
} }
#if 0 #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)gpu_dispatch_state;
(UNUSED)params; (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); 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); pipeline_scope_end(pipeline_scope);