From e7971e7bad60fc58c27f42e6bfd87160808f16fe Mon Sep 17 00:00:00 2001 From: Kevin Trogant Date: Thu, 4 Apr 2024 08:51:48 +0200 Subject: [PATCH] compiling shaders --- src/asset_compiler/dx11_shader_compiler.cpp | 89 +++++++++++++++++++++ src/asset_compiler/effect_processor.c | 7 ++ src/asset_compiler/meson.build | 7 ++ src/asset_compiler/shader_compiler.c | 22 ++++- src/gfx/gfx_main.c | 2 +- src/gfx/renderer_api.h | 1 + src/renderer/dx11/init.cpp | 6 -- src/renderer/dx11/meson.build | 4 +- src/renderer/dx11/render_targets.cpp | 3 +- 9 files changed, 129 insertions(+), 12 deletions(-) create mode 100644 src/asset_compiler/dx11_shader_compiler.cpp diff --git a/src/asset_compiler/dx11_shader_compiler.cpp b/src/asset_compiler/dx11_shader_compiler.cpp new file mode 100644 index 0000000..fca211d --- /dev/null +++ b/src/asset_compiler/dx11_shader_compiler.cpp @@ -0,0 +1,89 @@ +#include + +#include "shader_compiler.h" + +extern "C" rt_shader_bytecode CompileDX11Shader(rt_shader_stage stage, + rt_shader_optimization_level optimization, + rt_text_span code, + const char *file_path, + rt_arena *arena) { + rt_shader_bytecode bytecode = {}; + + D3D_SHADER_MACRO defines[] = { + {"RT_DX11", "1"}, + { NULL, NULL}, + }; + + LPCSTR target = NULL; + LPCSTR entrypoint = NULL; + switch (stage) { + case RT_SHADER_STAGE_VERTEX: + target = "vs_5_0"; + entrypoint = "VsMain"; + break; + case RT_SHADER_STAGE_FRAGMENT: + target = "ps_5_0"; + entrypoint = "PsMain"; + break; + case RT_SHADER_STAGE_COMPUTE: + target = "cs_5_0"; + entrypoint = "CsMain"; + break; + default: + rtLog("AC", "Tried to compile an invalid shader stage %u for %s", stage, file_path); + return bytecode; + } + + UINT flags = D3DCOMPILE_PARTIAL_PRECISION | D3DCOMPILE_WARNINGS_ARE_ERRORS; + switch (optimization) { + case RT_SHADER_OPTIMIZATION_NONE: + flags |= D3DCOMPILE_SKIP_OPTIMIZATION | D3DCOMPILE_OPTIMIZATION_LEVEL0; + break; + case RT_SHADER_OPTIMIZATION_SIZE: + flags |= D3DCOMPILE_OPTIMIZATION_LEVEL2; + break; + case RT_SHADER_OPTIMIZATION_SPEED: + flags |= D3DCOMPILE_OPTIMIZATION_LEVEL3; + break; + } +#ifdef RT_DEBUG + flags |= D3DCOMPILE_DEBUG; +#endif + ID3DBlob *bytes = nullptr, *error = nullptr; + if (FAILED(D3DCompile2(code.start, + code.length, + file_path, + defines, + D3D_COMPILE_STANDARD_FILE_INCLUDE, + entrypoint, + target, + flags, + 0, + 0, + nullptr, + 0, + &bytes, + &error))) { + if (error) { + rtLog("AC", + "Shader compilation failed (%s): %s",file_path, + (const char *)error->GetBufferPointer()); + error->Release(); + return bytecode; + } else { + rtLog("AC", "Shader compilation failed (%s): NO ERROR INFORMATION", file_path); + return bytecode; + } + } + + bytecode.bytes = rtArenaPush(arena, bytes->GetBufferSize()); + if (bytecode.bytes) { + bytecode.len = bytes->GetBufferSize(); + memcpy(bytecode.bytes, bytes->GetBufferPointer(), bytecode.len); + } else { + rtLog("AC", "Out of memory while compiling %s", file_path); + } + bytes->Release(); + + return bytecode; +} \ No newline at end of file diff --git a/src/asset_compiler/effect_processor.c b/src/asset_compiler/effect_processor.c index 0c23775..a220bed 100644 --- a/src/asset_compiler/effect_processor.c +++ b/src/asset_compiler/effect_processor.c @@ -62,6 +62,9 @@ static char *GenerateShaderName(rt_shader_type type, case RT_SHADER_TYPE_VULKAN: type_str = ":vk"; break; + case RT_SHADER_TYPE_DX11: + type_str = ":dx11"; + break; default: return NULL; } @@ -135,6 +138,8 @@ static rt_result ParseShader(rt_parse_state *state, rt_shader_type in_file_type = RT_SHADER_TYPE_INVALID; if (rtCompareSpanToString(shader->attribute, "vk") == 0) { in_file_type = RT_SHADER_TYPE_VULKAN; + } else if (rtCompareSpanToString(shader->attribute, "dx11") == 0) { + in_file_type = RT_SHADER_TYPE_DX11; } else { rtReportError("GFX", "Invalid renderer backend" @@ -230,6 +235,8 @@ static rt_result ParsePipeline(rt_parse_state *state, rt_shader_type type = RT_SHADER_TYPE_INVALID; if (strcmp(rt_Renderer.s, "vk") == 0) type = RT_SHADER_TYPE_VULKAN; + else if (strcmp(rt_Renderer.s, "dx11") == 0) + type = RT_SHADER_TYPE_DX11; if (type == RT_SHADER_TYPE_INVALID) { result = RT_ASSET_PROCESSING_FAILED; diff --git a/src/asset_compiler/meson.build b/src/asset_compiler/meson.build index 33f9b0d..50d417d 100644 --- a/src/asset_compiler/meson.build +++ b/src/asset_compiler/meson.build @@ -39,6 +39,13 @@ if get_option('enable_dxc_shader_compiler') ac_cargs += '-DRT_BUILD_DXC_SHADER_COMPILER' endif +if get_option('enable_dx11_shader_compiler') + ac_cargs += '-DRT_BUILD_DX11_SHADER_COMPILER' + ac_sources += ['dx11_shader_compiler.cpp'] + d3dcompiler_dep = declare_dependency(link_args : ['-lD3DCompiler']) + ac_deps += d3dcompiler_dep +endif + asset_compiler = static_library('asset_compiler', 'asset_compiler.h', 'description_parser.h', diff --git a/src/asset_compiler/shader_compiler.c b/src/asset_compiler/shader_compiler.c index ea90644..f2e3862 100644 --- a/src/asset_compiler/shader_compiler.c +++ b/src/asset_compiler/shader_compiler.c @@ -8,10 +8,18 @@ extern rt_shader_bytecode CompileVulkanShader(rt_shader_stage stage, rt_arena *arena); #endif +#ifdef RT_BUILD_DX11_SHADER_COMPILER +extern rt_shader_bytecode CompileDX11Shader(rt_shader_stage stage, + rt_shader_optimization_level optimization, + rt_text_span code, + const char *file_path, + rt_arena *arena); +#endif + static rt_shader_bytecode CompileNullShader(rt_shader_stage stage, rt_shader_optimization_level optimization, rt_text_span code, - const char *file_path, + const char *file_path, rt_arena *arena) { RT_UNUSED(stage); RT_UNUSED(optimization); @@ -24,8 +32,11 @@ static rt_shader_bytecode CompileNullShader(rt_shader_stage stage, }; } -typedef rt_shader_bytecode -shader_compiler_fn(rt_shader_stage, rt_shader_optimization_level, rt_text_span, const char *, rt_arena *); +typedef rt_shader_bytecode shader_compiler_fn(rt_shader_stage, + rt_shader_optimization_level, + rt_text_span, + const char *, + rt_arena *); static shader_compiler_fn *_compiler_funcs[RT_SHADER_TYPE_count] = { CompileNullShader, @@ -36,6 +47,11 @@ static shader_compiler_fn *_compiler_funcs[RT_SHADER_TYPE_count] = { CompileNullShader, #endif +#ifdef RT_BUILD_DX11_SHADER_COMPILER + CompileDX11Shader, +#else + CompileNullShader, +#endif }; rt_shader_bytecode CompileShader(rt_shader_type type, diff --git a/src/gfx/gfx_main.c b/src/gfx/gfx_main.c index fcebcfb..817c152 100644 --- a/src/gfx/gfx_main.c +++ b/src/gfx/gfx_main.c @@ -25,7 +25,7 @@ static bool _renderer_loaded = false; RT_DLLEXPORT RT_CVAR_S(rt_Renderer, "Select the render backend. Available options: [vk, null], Default: vk", - "vk"); + "dx11"); #ifdef RT_STATIC_LIB extern void RT_RENDERER_API_FN(RegisterCVars)(void); diff --git a/src/gfx/renderer_api.h b/src/gfx/renderer_api.h index fd14d43..77e1c2e 100644 --- a/src/gfx/renderer_api.h +++ b/src/gfx/renderer_api.h @@ -87,6 +87,7 @@ typedef struct { typedef enum { RT_SHADER_TYPE_INVALID, RT_SHADER_TYPE_VULKAN, + RT_SHADER_TYPE_DX11, RT_SHADER_TYPE_count, } rt_shader_type; diff --git a/src/renderer/dx11/init.cpp b/src/renderer/dx11/init.cpp index 25c2512..b10d76e 100644 --- a/src/renderer/dx11/init.cpp +++ b/src/renderer/dx11/init.cpp @@ -2,12 +2,6 @@ #pragma warning Building DX11 on non - windows is probably a mistake #endif -#pragma comment(lib, "d3d11.lib") -#pragma comment(lib, "dxgi.lib") -#pragma comment(lib, "d3dcompiler.lib") -#pragma comment(lib, "winmm.lib") -#pragma comment(lib, "dxguid.lib") - #include #include #include diff --git a/src/renderer/dx11/meson.build b/src/renderer/dx11/meson.build index e03fc5f..6f888d1 100644 --- a/src/renderer/dx11/meson.build +++ b/src/renderer/dx11/meson.build @@ -1,4 +1,6 @@ if get_option('build_dx11') + dx11_dep = declare_dependency(link_args: ['-ld3d11', '-ldxgi', '-lwinmm', '-ldxguid']) + dx11_renderer_lib = library('rtdx11', # Project Sources 'device_objects.hpp', @@ -11,7 +13,7 @@ if get_option('build_dx11') 'init.cpp', 'render_targets.cpp', - dependencies : [m_dep, windowing_dep], + dependencies : [m_dep, windowing_dep, dx11_dep], include_directories : [engine_incdir, contrib_incdir], link_with : [runtime_lib], cpp_pch : 'pch/dx11_pch.h', diff --git a/src/renderer/dx11/render_targets.cpp b/src/renderer/dx11/render_targets.cpp index 31cfe54..24c6bad 100644 --- a/src/renderer/dx11/render_targets.cpp +++ b/src/renderer/dx11/render_targets.cpp @@ -42,7 +42,8 @@ rt_result InitRenderTargetManagement() { } void ShutdownRenderTargetManagement() { - for (int i = 0; i < rt_Dx11MaxRenderTargets.i; ++i) { + // Swapchain rtv in slot 1 will be released elsewhere + for (int i = 2; i < rt_Dx11MaxRenderTargets.i; ++i) { if (_render_targets[i].rtv) _render_targets[i].rtv->Release(); if (_render_targets[i].dsv)