compiling shaders

This commit is contained in:
Kevin Trogant 2024-04-04 08:51:48 +02:00
parent e93847b187
commit e7971e7bad
9 changed files with 129 additions and 12 deletions

View File

@ -0,0 +1,89 @@
#include <d3dcompiler.h>
#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;
}

View File

@ -62,6 +62,9 @@ static char *GenerateShaderName(rt_shader_type type,
case RT_SHADER_TYPE_VULKAN: case RT_SHADER_TYPE_VULKAN:
type_str = ":vk"; type_str = ":vk";
break; break;
case RT_SHADER_TYPE_DX11:
type_str = ":dx11";
break;
default: default:
return NULL; return NULL;
} }
@ -135,6 +138,8 @@ static rt_result ParseShader(rt_parse_state *state,
rt_shader_type in_file_type = RT_SHADER_TYPE_INVALID; rt_shader_type in_file_type = RT_SHADER_TYPE_INVALID;
if (rtCompareSpanToString(shader->attribute, "vk") == 0) { if (rtCompareSpanToString(shader->attribute, "vk") == 0) {
in_file_type = RT_SHADER_TYPE_VULKAN; in_file_type = RT_SHADER_TYPE_VULKAN;
} else if (rtCompareSpanToString(shader->attribute, "dx11") == 0) {
in_file_type = RT_SHADER_TYPE_DX11;
} else { } else {
rtReportError("GFX", rtReportError("GFX",
"Invalid renderer backend" "Invalid renderer backend"
@ -230,6 +235,8 @@ static rt_result ParsePipeline(rt_parse_state *state,
rt_shader_type type = RT_SHADER_TYPE_INVALID; rt_shader_type type = RT_SHADER_TYPE_INVALID;
if (strcmp(rt_Renderer.s, "vk") == 0) if (strcmp(rt_Renderer.s, "vk") == 0)
type = RT_SHADER_TYPE_VULKAN; type = RT_SHADER_TYPE_VULKAN;
else if (strcmp(rt_Renderer.s, "dx11") == 0)
type = RT_SHADER_TYPE_DX11;
if (type == RT_SHADER_TYPE_INVALID) { if (type == RT_SHADER_TYPE_INVALID) {
result = RT_ASSET_PROCESSING_FAILED; result = RT_ASSET_PROCESSING_FAILED;

View File

@ -39,6 +39,13 @@ if get_option('enable_dxc_shader_compiler')
ac_cargs += '-DRT_BUILD_DXC_SHADER_COMPILER' ac_cargs += '-DRT_BUILD_DXC_SHADER_COMPILER'
endif 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 = static_library('asset_compiler',
'asset_compiler.h', 'asset_compiler.h',
'description_parser.h', 'description_parser.h',

View File

@ -8,10 +8,18 @@ extern rt_shader_bytecode CompileVulkanShader(rt_shader_stage stage,
rt_arena *arena); rt_arena *arena);
#endif #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, static rt_shader_bytecode CompileNullShader(rt_shader_stage stage,
rt_shader_optimization_level optimization, rt_shader_optimization_level optimization,
rt_text_span code, rt_text_span code,
const char *file_path, const char *file_path,
rt_arena *arena) { rt_arena *arena) {
RT_UNUSED(stage); RT_UNUSED(stage);
RT_UNUSED(optimization); RT_UNUSED(optimization);
@ -24,8 +32,11 @@ static rt_shader_bytecode CompileNullShader(rt_shader_stage stage,
}; };
} }
typedef rt_shader_bytecode typedef rt_shader_bytecode shader_compiler_fn(rt_shader_stage,
shader_compiler_fn(rt_shader_stage, rt_shader_optimization_level, rt_text_span, const char *, rt_arena *); rt_shader_optimization_level,
rt_text_span,
const char *,
rt_arena *);
static shader_compiler_fn *_compiler_funcs[RT_SHADER_TYPE_count] = { static shader_compiler_fn *_compiler_funcs[RT_SHADER_TYPE_count] = {
CompileNullShader, CompileNullShader,
@ -36,6 +47,11 @@ static shader_compiler_fn *_compiler_funcs[RT_SHADER_TYPE_count] = {
CompileNullShader, CompileNullShader,
#endif #endif
#ifdef RT_BUILD_DX11_SHADER_COMPILER
CompileDX11Shader,
#else
CompileNullShader,
#endif
}; };
rt_shader_bytecode CompileShader(rt_shader_type type, rt_shader_bytecode CompileShader(rt_shader_type type,

View File

@ -25,7 +25,7 @@ static bool _renderer_loaded = false;
RT_DLLEXPORT RT_DLLEXPORT
RT_CVAR_S(rt_Renderer, RT_CVAR_S(rt_Renderer,
"Select the render backend. Available options: [vk, null], Default: vk", "Select the render backend. Available options: [vk, null], Default: vk",
"vk"); "dx11");
#ifdef RT_STATIC_LIB #ifdef RT_STATIC_LIB
extern void RT_RENDERER_API_FN(RegisterCVars)(void); extern void RT_RENDERER_API_FN(RegisterCVars)(void);

View File

@ -87,6 +87,7 @@ typedef struct {
typedef enum { typedef enum {
RT_SHADER_TYPE_INVALID, RT_SHADER_TYPE_INVALID,
RT_SHADER_TYPE_VULKAN, RT_SHADER_TYPE_VULKAN,
RT_SHADER_TYPE_DX11,
RT_SHADER_TYPE_count, RT_SHADER_TYPE_count,
} rt_shader_type; } rt_shader_type;

View File

@ -2,12 +2,6 @@
#pragma warning Building DX11 on non - windows is probably a mistake #pragma warning Building DX11 on non - windows is probably a mistake
#endif #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 <d3d11.h> #include <d3d11.h>
#include <dxgi1_3.h> #include <dxgi1_3.h>
#include <wrl.h> #include <wrl.h>

View File

@ -1,4 +1,6 @@
if get_option('build_dx11') if get_option('build_dx11')
dx11_dep = declare_dependency(link_args: ['-ld3d11', '-ldxgi', '-lwinmm', '-ldxguid'])
dx11_renderer_lib = library('rtdx11', dx11_renderer_lib = library('rtdx11',
# Project Sources # Project Sources
'device_objects.hpp', 'device_objects.hpp',
@ -11,7 +13,7 @@ if get_option('build_dx11')
'init.cpp', 'init.cpp',
'render_targets.cpp', 'render_targets.cpp',
dependencies : [m_dep, windowing_dep], dependencies : [m_dep, windowing_dep, dx11_dep],
include_directories : [engine_incdir, contrib_incdir], include_directories : [engine_incdir, contrib_incdir],
link_with : [runtime_lib], link_with : [runtime_lib],
cpp_pch : 'pch/dx11_pch.h', cpp_pch : 'pch/dx11_pch.h',

View File

@ -42,7 +42,8 @@ rt_result InitRenderTargetManagement() {
} }
void ShutdownRenderTargetManagement() { 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) if (_render_targets[i].rtv)
_render_targets[i].rtv->Release(); _render_targets[i].rtv->Release();
if (_render_targets[i].dsv) if (_render_targets[i].dsv)