Skip to content

Commit f08a43c

Browse files
committed
add include/nbl/system/json.h and wipe nlohmann/json_fwd.hpp from public header interface
1 parent de16092 commit f08a43c

File tree

5 files changed

+269
-212
lines changed

5 files changed

+269
-212
lines changed

3rdparty/CMakeLists.txt

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -543,9 +543,6 @@ nbl_install_dir(imath/src/Imath)
543543

544544
nbl_install_file(blake/c/blake3.h)
545545

546-
nbl_install_file_spec(nlohmann_json/include/nlohmann/json_fwd.hpp nlohmann)
547-
nbl_install_file_spec(nlohmann_json/include/nlohmann/detail/abi_macros.hpp nlohmann/detail)
548-
549546
nbl_install_dir(boost/superproject/libs/preprocessor/include/boost)
550547

551548
nbl_install_file_spec(renderdoc/renderdoc_app.h renderdoc)

include/nbl/asset/utils/IShaderCompiler.h

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,7 @@
1212

1313
#include "nbl/asset/IShader.h"
1414
#include "nbl/asset/utils/ISPIRVOptimizer.h"
15-
16-
// Less leakage than "nlohmann/json.hpp" only forward declarations
17-
#include "nlohmann/json_fwd.hpp"
15+
#include "nbl/system/json.h"
1816

1917
#include "nbl/builtin/hlsl/enums.hlsl"
2018

@@ -111,11 +109,10 @@ class NBL_API2 IShaderCompiler : public core::IReferenceCounted
111109
//
112110
struct SMacroDefinition
113111
{
114-
friend void to_json(nlohmann::json&, const SMacroDefinition&);
115-
friend void from_json(const nlohmann::json&, SMacroDefinition&);
116-
117112
std::string_view identifier;
118113
std::string_view definition;
114+
115+
friend struct system::json::adl_serializer<SMacroDefinition>;
119116
};
120117

121118
//
@@ -216,9 +213,8 @@ class NBL_API2 IShaderCompiler : public core::IReferenceCounted
216213
inline SPreprocessingDependency() {}
217214

218215
private:
219-
friend void to_json(nlohmann::json& j, const SEntry::SPreprocessingDependency& dependency);
220-
friend void from_json(const nlohmann::json& j, SEntry::SPreprocessingDependency& dependency);
221216
friend class CCache;
217+
friend struct system::json::adl_serializer<SEntry::SPreprocessingDependency>;
222218

223219
// path or identifier
224220
system::path requestingSourceDir = "";
@@ -252,8 +248,7 @@ class NBL_API2 IShaderCompiler : public core::IReferenceCounted
252248
friend class SCompilerArgs;
253249
friend class SEntry;
254250
friend class CCache;
255-
friend void to_json(nlohmann::json&, const SPreprocessorArgs&);
256-
friend void from_json(const nlohmann::json&, SPreprocessorArgs&);
251+
friend struct system::json::adl_serializer<SPreprocessorArgs>;
257252

258253
// Default constructor needed for json serialization of SCompilerArgs
259254
SPreprocessorArgs() {};
@@ -295,8 +290,7 @@ class NBL_API2 IShaderCompiler : public core::IReferenceCounted
295290
private:
296291
friend class SEntry;
297292
friend class CCache;
298-
friend void to_json(nlohmann::json&, const SCompilerArgs&);
299-
friend void from_json(const nlohmann::json&, SCompilerArgs&);
293+
friend struct system::json::adl_serializer<SCompilerArgs>;
300294

301295
// Default constructor needed for json serialization of SEntry
302296
SCompilerArgs() {}

include/nbl/system/json.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
#ifndef _NBL_SYSTEM_JSON_H_INCLUDED_
2+
#define _NBL_SYSTEM_JSON_H_INCLUDED_
3+
4+
namespace nbl::system::json {
5+
template<typename T, typename SFINAE = void> struct adl_serializer;
6+
}
7+
8+
#define NBL_JSON_IMPL_BIND_ADL_SERIALIZER(T) \
9+
namespace nlohmann { \
10+
template<> \
11+
struct adl_serializer<typename T::value_t> \
12+
: T {}; \
13+
}
14+
15+
#endif // _NBL_SYSTEM_JSON_H_INCLUDED_

src/nbl/asset/utils/IShaderCompiler.cpp

Lines changed: 248 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,265 @@
33
// For conditions of distribution and use, see copyright notice in nabla.h
44
#include "nbl/asset/utils/IShaderCompiler.h"
55
#include "nbl/asset/utils/shadercUtils.h"
6-
#include "nbl/asset/utils/shaderCompiler_serialization.h"
76

87
#include <sstream>
98
#include <regex>
109
#include <iterator>
1110

1211
#include <lzma/C/LzmaEnc.h>
1312
#include <lzma/C/LzmaDec.h>
13+
#include "nlohmann/json.hpp"
14+
15+
using json = nlohmann::json;
16+
using SEntry = nbl::asset::IShaderCompiler::CCache::SEntry;
1417

1518
using namespace nbl;
1619
using namespace nbl::asset;
1720

21+
// -> serialization
22+
// SMacroData, simple container used in SPreprocessorArgs
23+
namespace nbl::system::json {
24+
template<>
25+
struct adl_serializer<IShaderCompiler::SMacroDefinition>
26+
{
27+
using value_t = IShaderCompiler::SMacroDefinition;
28+
29+
static inline void to_json(::json& j, const value_t& p)
30+
{
31+
j = ::json{
32+
{ "identifier", p.identifier },
33+
{ "definition", p.definition },
34+
};
35+
}
36+
37+
static inline void from_json(const ::json& j, value_t& p)
38+
{
39+
j.at("identifier").get_to(p.identifier);
40+
j.at("definition").get_to(p.definition);
41+
}
42+
};
43+
}
44+
NBL_JSON_IMPL_BIND_ADL_SERIALIZER(::nbl::system::json::adl_serializer<IShaderCompiler::SMacroDefinition>)
45+
46+
// SPreprocessorData, holds serialized info for Preprocessor options used during compilation
47+
namespace nbl::system::json {
48+
template<>
49+
struct adl_serializer<SEntry::SPreprocessorArgs>
50+
{
51+
using value_t = SEntry::SPreprocessorArgs;
52+
53+
static inline void to_json(::json& j, const value_t& p)
54+
{
55+
j = ::json{
56+
{ "sourceIdentifier", p.sourceIdentifier },
57+
{ "extraDefines", p.extraDefines},
58+
};
59+
}
60+
61+
static inline void from_json(const ::json& j, value_t& p)
62+
{
63+
j.at("sourceIdentifier").get_to(p.sourceIdentifier);
64+
j.at("extraDefines").get_to(p.extraDefines);
65+
}
66+
};
67+
}
68+
NBL_JSON_IMPL_BIND_ADL_SERIALIZER(::nbl::system::json::adl_serializer<SEntry::SPreprocessorArgs>)
69+
70+
// Optimizer pass has its own method for easier vector serialization
71+
namespace nbl::system::json {
72+
template<>
73+
struct adl_serializer<ISPIRVOptimizer::E_OPTIMIZER_PASS>
74+
{
75+
using value_t = ISPIRVOptimizer::E_OPTIMIZER_PASS;
76+
77+
static inline void to_json(::json& j, const value_t& p)
78+
{
79+
uint32_t value = static_cast<uint32_t>(p);
80+
j = ::json{
81+
{ "optPass", value },
82+
};
83+
}
84+
85+
static inline void from_json(const ::json& j, value_t& p)
86+
{
87+
uint32_t aux;
88+
j.at("optPass").get_to(aux);
89+
p = static_cast<ISPIRVOptimizer::E_OPTIMIZER_PASS>(aux);
90+
}
91+
};
92+
}
93+
NBL_JSON_IMPL_BIND_ADL_SERIALIZER(::nbl::system::json::adl_serializer<ISPIRVOptimizer::E_OPTIMIZER_PASS>)
94+
95+
// SCompilerArgs, holds serialized info for all Compilation options
96+
namespace nbl::system::json {
97+
template<>
98+
struct adl_serializer<SEntry::SCompilerArgs>
99+
{
100+
using value_t = SEntry::SCompilerArgs;
101+
102+
static inline void to_json(::json& j, const value_t& p)
103+
{
104+
uint32_t shaderStage = static_cast<uint32_t>(p.stage);
105+
uint32_t spirvVersion = static_cast<uint32_t>(p.targetSpirvVersion);
106+
uint32_t debugFlags = static_cast<uint32_t>(p.debugInfoFlags.value);
107+
108+
j = ::json{
109+
{ "shaderStage", shaderStage },
110+
{ "spirvVersion", spirvVersion },
111+
{ "optimizerPasses", p.optimizerPasses },
112+
{ "debugFlags", debugFlags },
113+
{ "preprocessorArgs", p.preprocessorArgs },
114+
};
115+
}
116+
117+
static inline void from_json(const ::json& j, value_t& p)
118+
{
119+
uint32_t shaderStage, spirvVersion, debugFlags;
120+
j.at("shaderStage").get_to(shaderStage);
121+
j.at("spirvVersion").get_to(spirvVersion);
122+
j.at("optimizerPasses").get_to(p.optimizerPasses);
123+
j.at("debugFlags").get_to(debugFlags);
124+
j.at("preprocessorArgs").get_to(p.preprocessorArgs);
125+
p.stage = static_cast<IShader::E_SHADER_STAGE>(shaderStage);
126+
p.targetSpirvVersion = static_cast<IShaderCompiler::E_SPIRV_VERSION>(spirvVersion);
127+
p.debugInfoFlags = core::bitflag<IShaderCompiler::E_DEBUG_INFO_FLAGS>(debugFlags);
128+
}
129+
};
130+
}
131+
NBL_JSON_IMPL_BIND_ADL_SERIALIZER(::nbl::system::json::adl_serializer<SEntry::SCompilerArgs>)
132+
133+
// Serialize clock's time point
134+
using time_point_t = nbl::system::IFileBase::time_point_t;
135+
namespace nbl::system::json {
136+
template<>
137+
struct adl_serializer<time_point_t>
138+
{
139+
using value_t = time_point_t;
140+
141+
static inline void to_json(::json& j, const value_t& p)
142+
{
143+
auto ticks = p.time_since_epoch().count();
144+
j = ::json{
145+
{ "ticks", ticks },
146+
};
147+
}
148+
149+
static inline void from_json(const ::json& j, value_t& p)
150+
{
151+
uint64_t ticks;
152+
j.at("ticks").get_to(ticks);
153+
p = time_point_t(time_point_t::clock::duration(ticks));
154+
}
155+
};
156+
}
157+
NBL_JSON_IMPL_BIND_ADL_SERIALIZER(::nbl::system::json::adl_serializer<time_point_t>)
158+
159+
// SDependency serialization. Dependencies will be saved in a vector for easier vectorization
160+
namespace nbl::system::json {
161+
template<>
162+
struct adl_serializer<SEntry::SPreprocessingDependency>
163+
{
164+
using value_t = SEntry::SPreprocessingDependency;
165+
166+
static inline void to_json(::json& j, const value_t& p)
167+
{
168+
j = ::json{
169+
{ "requestingSourceDir", p.requestingSourceDir },
170+
{ "identifier", p.identifier },
171+
{ "hash", p.hash.data },
172+
{ "standardInclude", p.standardInclude },
173+
};
174+
}
175+
176+
static inline void from_json(const ::json& j, value_t& p)
177+
{
178+
j.at("requestingSourceDir").get_to(p.requestingSourceDir);
179+
j.at("identifier").get_to(p.identifier);
180+
j.at("hash").get_to(p.hash.data);
181+
j.at("standardInclude").get_to(p.standardInclude);
182+
}
183+
};
184+
}
185+
NBL_JSON_IMPL_BIND_ADL_SERIALIZER(::nbl::system::json::adl_serializer<SEntry::SPreprocessingDependency>)
186+
187+
// We serialize shader creation parameters into a json, along with indexing info into the .bin buffer where the cache is serialized
188+
struct CPUShaderCreationParams {
189+
IShader::E_SHADER_STAGE stage;
190+
std::string filepathHint;
191+
uint64_t codeByteSize = 0;
192+
uint64_t offset = 0; // Offset into the serialized .bin for the Cache where code starts
193+
194+
CPUShaderCreationParams(IShader::E_SHADER_STAGE _stage, std::string_view _filepathHint, uint64_t _codeByteSize, uint64_t _offset)
195+
: stage(_stage), filepathHint(_filepathHint), codeByteSize(_codeByteSize), offset(_offset) {}
196+
CPUShaderCreationParams() {};
197+
};
198+
199+
namespace nbl::system::json {
200+
template<>
201+
struct adl_serializer<CPUShaderCreationParams>
202+
{
203+
using value_t = CPUShaderCreationParams;
204+
205+
static inline void to_json(::json& j, const value_t& p)
206+
{
207+
uint32_t stage = static_cast<uint32_t>(p.stage);
208+
j = ::json{
209+
{ "stage", stage },
210+
{ "filepathHint", p.filepathHint },
211+
{ "codeByteSize", p.codeByteSize },
212+
{ "offset", p.offset },
213+
};
214+
}
215+
216+
static inline void from_json(const ::json& j, value_t& p)
217+
{
218+
uint32_t stage;
219+
j.at("stage").get_to(stage);
220+
j.at("filepathHint").get_to(p.filepathHint);
221+
j.at("codeByteSize").get_to(p.codeByteSize);
222+
j.at("offset").get_to(p.offset);
223+
p.stage = static_cast<IShader::E_SHADER_STAGE>(stage);
224+
}
225+
};
226+
}
227+
NBL_JSON_IMPL_BIND_ADL_SERIALIZER(::nbl::system::json::adl_serializer<CPUShaderCreationParams>)
228+
229+
// Serialize SEntry, keeping some fields as extra serialization to keep them separate on disk
230+
namespace nbl::system::json {
231+
template<>
232+
struct adl_serializer<SEntry>
233+
{
234+
using value_t = SEntry;
235+
236+
static inline void to_json(::json& j, const value_t& p)
237+
{
238+
j = ::json{
239+
{ "mainFileContents", p.mainFileContents },
240+
{ "compilerArgs", p.compilerArgs },
241+
{ "hash", p.hash.data },
242+
{ "lookupHash", p.lookupHash },
243+
{ "dependencies", p.dependencies },
244+
{ "uncompressedContentHash", p.uncompressedContentHash.data },
245+
{ "uncompressedSize", p.uncompressedSize },
246+
};
247+
}
248+
249+
static inline void from_json(const ::json& j, value_t& p)
250+
{
251+
j.at("mainFileContents").get_to(p.mainFileContents);
252+
j.at("compilerArgs").get_to(p.compilerArgs);
253+
j.at("hash").get_to(p.hash.data);
254+
j.at("lookupHash").get_to(p.lookupHash);
255+
j.at("dependencies").get_to(p.dependencies);
256+
j.at("uncompressedContentHash").get_to(p.uncompressedContentHash.data);
257+
j.at("uncompressedSize").get_to(p.uncompressedSize);
258+
p.spirv = nullptr;
259+
}
260+
};
261+
}
262+
NBL_JSON_IMPL_BIND_ADL_SERIALIZER(::nbl::system::json::adl_serializer<SEntry>)
263+
// <- serialization
264+
18265
IShaderCompiler::IShaderCompiler(core::smart_refctd_ptr<system::ISystem>&& system)
19266
: m_system(std::move(system))
20267
{

0 commit comments

Comments
 (0)