70 lines
2.3 KiB
C++
70 lines
2.3 KiB
C++
extern "C"
|
|
{
|
|
#include "dxc.h"
|
|
#include "arena.h"
|
|
#include "string.h"
|
|
}
|
|
|
|
#pragma clang diagnostic ignored "-Wlanguage-extension-token"
|
|
#include <Windows.h>
|
|
#include <atlbase.h>
|
|
#include <dxcapi.h>
|
|
#include <d3d12shader.h>
|
|
|
|
#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<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, 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) {
|
|
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<IDxcBlob> 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;
|
|
}
|