SDEngine
Game Engine
Loading...
Searching...
No Matches
ShaderCompiler.hpp
Go to the documentation of this file.
1#pragma once
2
3// DXC
4#include <dxc/dxcapi.h>
5
6#include "SD/core/base.hpp"
8
9#ifdef _WIN32
10#include <wrl/client.h>
11using Microsoft::WRL::ComPtr;
12#else
13#include <dxc/WinAdapter.h>
14#endif
15
16namespace sd {
18public:
21 engine_abort("Failed to create DXC Utils");
23 engine_abort("Failed to create DXC Compiler");
24 }
25
26 // TODO: Add caching mechanism to avoid recompiling shaders if source hasn't changed
27 bool compile_shader(const std::string& source, std::vector<uint32_t>& output,
28 const std::string& profile) const {
29 if (!dxc_utils || !dxc_compiler) {
30 log::engine::error("Shader compiler not initialised");
31 return false;
32 }
33
35 if (FAILED(dxc_utils->LoadFile(CA2W(source.c_str()), nullptr, &p_source))) {
36 log::engine::error("Failed to load shader source: {}", source);
37 return false;
38 }
39
41 dxc_buffer.Ptr = p_source->GetBufferPointer();
42 dxc_buffer.Size = p_source->GetBufferSize();
44 UINT32 code_page = 0;
45 if (SUCCEEDED(p_source->GetEncoding(&known, &code_page))) {
46 dxc_buffer.Encoding = known ? code_page : DXC_CP_ACP;
47 } else {
48 dxc_buffer.Encoding = DXC_CP_ACP;
49 }
50
51 std::vector<std::wstring> args;
52 args.emplace_back(L"-E");
53 args.emplace_back(L"main");
54 args.emplace_back(L"-T");
55 args.emplace_back(CA2W(profile.c_str()));
56 args.emplace_back(L"-spirv");
57
58#if _DEBUG
59 args.emplace_back(L"-D_DEBUG");
60 args.emplace_back(L"-Zi");
61 args.emplace_back(L"-Qembed_debug");
62#endif
63
64 std::vector<LPCWSTR> psz_args;
65 psz_args.reserve(args.size());
66 for (const auto& arg : args)
67 psz_args.push_back(arg.c_str());
68
70 if (FAILED(dxc_compiler->Compile(&dxc_buffer, psz_args.data(), psz_args.size(), nullptr,
72 log::engine::error("Failed to compile shader");
73 return false;
74 }
75
78 if (dxc_blob_utf8 != nullptr && dxc_blob_utf8->GetStringLength() != 0) {
79 log::engine::error("Shader compilation errors/warnings:\n{}",
80 dxc_blob_utf8->GetStringPointer());
81 }
82
84 dxc_result->GetStatus(&hr_status);
85 if (FAILED(hr_status)) {
86 log::engine::error("Shader compilation failed");
87 return false;
88 }
89
91 if (FAILED(dxc_result->GetOutput(DXC_OUT_OBJECT, IID_PPV_ARGS(&dxc_blob), nullptr))) {
92 return false;
93 }
94
95 output.resize((dxc_blob->GetBufferSize() + 3) / 4);
96 memcpy(output.data(), dxc_blob->GetBufferPointer(), dxc_blob->GetBufferSize());
97
98 return true;
99 }
100
101private:
104};
107} // namespace sd
Definition ShaderCompiler.hpp:17
ShaderCompiler()
Definition ShaderCompiler.hpp:19
bool compile_shader(const std::string &source, std::vector< uint32_t > &output, const std::string &profile) const
Definition ShaderCompiler.hpp:27
CComPtr< IDxcUtils > dxc_utils
Definition ShaderCompiler.hpp:102
CComPtr< IDxcCompiler3 > dxc_compiler
Definition ShaderCompiler.hpp:103
Definition Application.hpp:28
void engine_abort()
Definition base.hpp:46
CComPtr< IDxcUtils > g_dxc_utils
Definition ShaderCompiler.hpp:105
CComPtr< IDxcCompiler3 > g_dxc_compiler
Definition ShaderCompiler.hpp:106
constexpr T g_type_max
Definition types.hpp:21