extern "C" { #include "dxc.h" #include "arena.h" #include "string.h" } #pragma clang diagnostic ignored "-Wlanguage-extension-token" #include #include #include #include #pragma comment(lib, "d3dcompiler") #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) { __prof; struct arena_temp scratch = scratch_begin(arena); struct dxc_compile_result res = ZI; wchar_t **wstr_args = arena_push_array(scratch.arena, wchar_t *, num_args); for (i32 i = 0; i < num_args; ++i) { wstr_args[i] = wstr_from_string(scratch.arena, args[i]); } DxcBuffer dxc_src_buffer = ZI; dxc_src_buffer.Ptr = shader_source.text; dxc_src_buffer.Size = shader_source.len; dxc_src_buffer.Encoding = DXC_CP_UTF8; /* Init compiler */ CComPtr dxc_utils; CComPtr dxc_compiler; CComPtr dxc_include_handler; DxcCreateInstance(CLSID_DxcUtils, IID_PPV_ARGS(&dxc_utils)); DxcCreateInstance(CLSID_DxcCompiler, IID_PPV_ARGS(&dxc_compiler)); dxc_utils->CreateDefaultIncludeHandler(&dxc_include_handler); /* Compile */ CComPtr compile_results = 0; dxc_compiler->Compile(&dxc_src_buffer, (LPCWSTR *)wstr_args, num_args, dxc_include_handler, IID_PPV_ARGS(&compile_results)); /* Copy errors */ CComPtr dxc_errors = 0; compile_results->GetOutput(DXC_OUT_ERRORS, IID_PPV_ARGS(&dxc_errors), 0); if (dxc_errors != 0) { res.errors = string_copy(arena, STRING(dxc_errors->GetStringLength(), (u8 *)dxc_errors->GetBufferPointer())); } /* Get status */ HRESULT dxc_hr = 0; compile_results->GetStatus(&dxc_hr); res.success = SUCCEEDED(dxc_hr); /* Copy shader output */ if (res.success) { CComPtr dxc_shader = 0; compile_results->GetOutput(DXC_OUT_OBJECT, IID_PPV_ARGS(&dxc_shader), 0); if (dxc_shader != 0) { res.dxc = string_copy(arena, STRING(dxc_shader->GetBufferSize(), (u8 *)dxc_shader->GetBufferPointer())); } } scratch_end(scratch); return res; }