power_play/src/dxc/dxc_core_win32.cpp
2025-07-29 20:01:35 -05:00

94 lines
2.7 KiB
C++

#if !RESOURCE_RELOADING
DXC_Result dxc_compile(Arena *arena, String shader_source, i32 num_args, String *args)
{
(UNUSED)arena;
(UNUSED)shader_source;
(UNUSED)num_args;
(UNUSED)args;
DXC_Result res = ZI;
return res;
}
#else
#if COMPILER_CLANG
# pragma clang diagnostic ignored "-Wlanguage-extension-token"
#endif
#define _ALLOW_RTCc_IN_STL
#pragma warning(push, 0)
# define WIN32_LEAN_AND_MEAN
# define UNICODE
# include <Windows.h>
# include <atlbase.h>
# include <dxcapi.h>
# include <d3d12shader.h>
#pragma warning(pop)
#pragma comment(lib, "d3dcompiler")
#pragma comment(lib, "dxcompiler")
/* https://github.com/microsoft/DirectXShaderCompiler/wiki/Using-dxc.exe-and-dxcompiler.dll */
DXC_Result dxc_compile(Arena *arena, String shader_source, i32 num_args, String *args)
{
__prof;
TempArena scratch = BeginScratch(arena);
DXC_Result res = ZI;
wchar_t **wstr_args = PushArray(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<IDxcUtils> dxc_utils;
CComPtr<IDxcCompiler3> dxc_compiler;
CComPtr<IDxcIncludeHandler> 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<IDxcResult> compile_results = 0;
dxc_compiler->Compile(&dxc_src_buffer, (LPCWSTR *)wstr_args, (u32)num_args, dxc_include_handler, IID_PPV_ARGS(&compile_results));
/* Copy errors */
CComPtr<IDxcBlobUtf8> dxc_errors = 0;
compile_results->GetOutput(DXC_OUT_ERRORS, IID_PPV_ARGS(&dxc_errors), 0);
if (dxc_errors != 0) {
String blob_str = ZI;
blob_str.len = dxc_errors->GetBufferSize();
blob_str.text = (u8 *)dxc_errors->GetBufferPointer();
res.errors = string_copy(arena, blob_str);
}
/* Get status */
HRESULT dxc_hr = 0;
compile_results->GetStatus(&dxc_hr);
res.success = SUCCEEDED(dxc_hr);
/* Copy shader output */
if (res.success) {
CComPtr<IDxcBlob> dxc_shader = 0;
compile_results->GetOutput(DXC_OUT_OBJECT, IID_PPV_ARGS(&dxc_shader), 0);
if (dxc_shader != 0) {
String blob_str = ZI;
blob_str.len = dxc_shader->GetBufferSize();
blob_str.text = (u8 *)dxc_shader->GetBufferPointer();
res.dxc = string_copy(arena, blob_str);
}
}
EndScratch(scratch);
return res;
}
#endif