Skip to content

Commit a2d4d44

Browse files
authored
Feature/source downstream compiler (shader-slang#1153)
* CPPCompiler -> DownstreamCompiler * Added DownstreamCompileResult to start abstraction such that we don't need files. * * Split out slang-blob.cpp * Made CompileResult hold a DownstreamCompileResult - for access to binary or ISlangSharedLibrary * Keep temporary files in scope. * Add a hash to the hex dump stream. * Move all file tracking into DownstreamCompiler. * WIP support for nvrtc. * WIP: Adding support for nvrtc compiler. Adding enum types, wiring up the nvrtc into slang. * Fix remaining CPPCompiler references. * Fix order issue on target string matching. * Use ISlangSharedLibrary for nvrtc. * Use DownstreamCompiler for nvrtc. * WIP first pass at compilation win nvrtc. * Added testing if file is on file system into CommandLineDownstreamCompiler. Added sourceContentsPath. * Make test cuda-compile.cu work by just compiling not comparing output. * Genearlize DownstreamCompiler usage. * Fix warning on clang. * Remove CompilerType from DownstreamCompiler. * Use DownstreamCompiler interface for all compilers. NOTE for FXC, DXC and GLSLANG this doesn't mean using 'compile' - it's still extracting functions from shared library. * Replace DownstreamCompiler::SourceType -> SlangSourceLanguage * Replace _canCompile with something data driven. * Fix compiling on gcc/clang for DownstreamCompiler. * Moved some text conversions into DownstreamCompiler. * Fix problem on non-vc builds with not having return on locateCompilers for VS. * Change so no warning for code not reachable on locateCompilers for vs.
1 parent 1533554 commit a2d4d44

17 files changed

+206
-226
lines changed

slang.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -609,8 +609,8 @@ extern "C"
609609
SLANG_LINE_DIRECTIVE_MODE_GLSL, /**< Emit GLSL-style directives with file *number* instead of name */
610610
};
611611

612-
typedef int SlangSourceLanguage;
613-
enum
612+
typedef int SlangSourceLanguageIntegral;
613+
enum SlangSourceLanguage : SlangSourceLanguageIntegral
614614
{
615615
SLANG_SOURCE_LANGUAGE_UNKNOWN,
616616
SLANG_SOURCE_LANGUAGE_SLANG,

source/core/slang-downstream-compiler.cpp

+124-9
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,29 @@
2020
namespace Slang
2121
{
2222

23+
static DownstreamCompiler::Infos _calcInfos()
24+
{
25+
typedef DownstreamCompiler::Info Info;
26+
typedef DownstreamCompiler::SourceLanguageFlag SourceLanguageFlag;
27+
typedef DownstreamCompiler::SourceLanguageFlags SourceLanguageFlags;
28+
29+
DownstreamCompiler::Infos infos;
30+
31+
infos.infos[int(SLANG_PASS_THROUGH_CLANG)] = Info(SourceLanguageFlag::CPP | SourceLanguageFlag::C);
32+
infos.infos[int(SLANG_PASS_THROUGH_VISUAL_STUDIO)] = Info(SourceLanguageFlag::CPP | SourceLanguageFlag::C);
33+
infos.infos[int(SLANG_PASS_THROUGH_GCC)] = Info(SourceLanguageFlag::CPP | SourceLanguageFlag::C);
34+
35+
infos.infos[int(SLANG_PASS_THROUGH_NVRTC)] = Info(SourceLanguageFlag::CUDA);
36+
37+
infos.infos[int(SLANG_PASS_THROUGH_DXC)] = Info(SourceLanguageFlag::HLSL);
38+
infos.infos[int(SLANG_PASS_THROUGH_FXC)] = Info(SourceLanguageFlag::HLSL);
39+
infos.infos[int(SLANG_PASS_THROUGH_GLSLANG)] = Info(SourceLanguageFlag::GLSL);
40+
41+
return infos;
42+
}
43+
44+
/* static */DownstreamCompiler::Infos DownstreamCompiler::s_infos = _calcInfos();
45+
2346
/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! DownstreamCompiler::Desc !!!!!!!!!!!!!!!!!!!!!!*/
2447

2548
void DownstreamCompiler::Desc::appendAsText(StringBuilder& out) const
@@ -67,6 +90,98 @@ void DownstreamCompiler::Desc::appendAsText(StringBuilder& out) const
6790
}
6891
}
6992

93+
/* static */bool DownstreamCompiler::canCompile(SlangPassThrough compiler, SlangSourceLanguage sourceLanguage)
94+
{
95+
const auto& info = getInfo(compiler);
96+
return (info.sourceLanguageFlags & (SourceLanguageFlags(1) << int(sourceLanguage))) != 0;
97+
}
98+
99+
/* static */SlangSourceLanguage DownstreamCompiler::getSourceLanguageFromName(const UnownedStringSlice& text)
100+
{
101+
if (text == "c" || text == "C")
102+
{
103+
return SLANG_SOURCE_LANGUAGE_C;
104+
}
105+
else if (text == "cpp" || text == "c++" || text == "C++" || text == "cxx")
106+
{
107+
return SLANG_SOURCE_LANGUAGE_CPP;
108+
}
109+
else if (text == "slang")
110+
{
111+
return SLANG_SOURCE_LANGUAGE_SLANG;
112+
}
113+
else if (text == "glsl")
114+
{
115+
return SLANG_SOURCE_LANGUAGE_GLSL;
116+
}
117+
else if (text == "hlsl")
118+
{
119+
return SLANG_SOURCE_LANGUAGE_HLSL;
120+
}
121+
else if (text == "cu" || text == "cuda")
122+
{
123+
return SLANG_SOURCE_LANGUAGE_CUDA;
124+
}
125+
return SLANG_SOURCE_LANGUAGE_UNKNOWN;
126+
}
127+
128+
#define SLANG_PASS_THROUGH_TYPES(x) \
129+
x(none, NONE) \
130+
x(fxc, FXC) \
131+
x(dxc, DXC) \
132+
x(glslang, GLSLANG) \
133+
x(visualstudio, VISUAL_STUDIO) \
134+
x(clang, CLANG) \
135+
x(gcc, GCC) \
136+
x(genericcpp, GENERIC_C_CPP) \
137+
x(nvrtc, NVRTC)
138+
139+
140+
141+
/* static */SlangPassThrough DownstreamCompiler::getPassThroughFromName(const UnownedStringSlice& slice)
142+
{
143+
#define SLANG_PASS_THROUGH_NAME_TO_TYPE(x, y) \
144+
if (slice == UnownedStringSlice::fromLiteral(#x)) return SLANG_PASS_THROUGH_##y;
145+
146+
SLANG_PASS_THROUGH_TYPES(SLANG_PASS_THROUGH_NAME_TO_TYPE)
147+
148+
// Other options
149+
if (slice == "c" || slice == "cpp")
150+
{
151+
return SLANG_PASS_THROUGH_GENERIC_C_CPP;
152+
}
153+
else if (slice == "vs")
154+
{
155+
return SLANG_PASS_THROUGH_VISUAL_STUDIO;
156+
}
157+
158+
return SLANG_PASS_THROUGH_NONE;
159+
}
160+
161+
/* static */SlangResult DownstreamCompiler::getPassThroughFromName(const UnownedStringSlice& slice, SlangPassThrough& outPassThrough)
162+
{
163+
outPassThrough = getPassThroughFromName(slice);
164+
// It could be none on error - if it's not equal to "none" then it msut be an error
165+
if (outPassThrough == SLANG_PASS_THROUGH_NONE && slice != UnownedStringSlice::fromLiteral("none"))
166+
{
167+
return SLANG_FAIL;
168+
}
169+
return SLANG_OK;
170+
}
171+
172+
/* static */UnownedStringSlice DownstreamCompiler::getPassThroughName(SlangPassThrough passThru)
173+
{
174+
#define SLANG_PASS_THROUGH_TYPE_TO_NAME(x, y) \
175+
case SLANG_PASS_THROUGH_##y: return UnownedStringSlice::fromLiteral(#x);
176+
177+
switch (passThru)
178+
{
179+
SLANG_PASS_THROUGH_TYPES(SLANG_PASS_THROUGH_TYPE_TO_NAME)
180+
default: break;
181+
}
182+
return UnownedStringSlice::fromLiteral("unknown");
183+
}
184+
70185
/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! DownstreamDiagnostics !!!!!!!!!!!!!!!!!!!!!!*/
71186

72187
Index DownstreamDiagnostics::getCountByType(Diagnostic::Type type) const
@@ -284,7 +399,7 @@ SlangResult CommandLineDownstreamCompiler::compile(const CompileOptions& inOptio
284399
compileSourcePath.append("-src");
285400

286401
// Make the temporary filename have the appropriate extension.
287-
if (options.sourceType == DownstreamCompiler::SourceType::C)
402+
if (options.sourceLanguage == SLANG_SOURCE_LANGUAGE_C)
288403
{
289404
compileSourcePath.append(".c");
290405
}
@@ -515,19 +630,19 @@ const DownstreamCompiler::Desc& DownstreamCompilerUtil::getCompiledWithDesc()
515630
return findClosestCompiler(compilers, desc);
516631
}
517632

518-
/* static */void DownstreamCompilerUtil::updateDefault(DownstreamCompilerSet* set, DownstreamCompiler::SourceType type)
633+
/* static */void DownstreamCompilerUtil::updateDefault(DownstreamCompilerSet* set, SlangSourceLanguage sourceLanguage)
519634
{
520635
DownstreamCompiler* compiler = nullptr;
521636

522-
switch (type)
637+
switch (sourceLanguage)
523638
{
524-
case DownstreamCompiler::SourceType::CPP:
525-
case DownstreamCompiler::SourceType::C:
639+
case SLANG_SOURCE_LANGUAGE_CPP:
640+
case SLANG_SOURCE_LANGUAGE_C:
526641
{
527642
compiler = findClosestCompiler(set, getCompiledWithDesc());
528643
break;
529644
}
530-
case DownstreamCompiler::SourceType::CUDA:
645+
case SLANG_SOURCE_LANGUAGE_CUDA:
531646
{
532647
DownstreamCompiler::Desc desc;
533648
desc.type = SLANG_PASS_THROUGH_NVRTC;
@@ -537,14 +652,14 @@ const DownstreamCompiler::Desc& DownstreamCompilerUtil::getCompiledWithDesc()
537652
default: break;
538653
}
539654

540-
set->setDefaultCompiler(type, compiler);
655+
set->setDefaultCompiler(sourceLanguage, compiler);
541656
}
542657

543658
/* static */void DownstreamCompilerUtil::updateDefaults(DownstreamCompilerSet* set)
544659
{
545-
for (Index i = 0; i < Index(DownstreamCompiler::SourceType::CountOf); ++i)
660+
for (Index i = 0; i < Index(SLANG_SOURCE_LANGUAGE_COUNT_OF); ++i)
546661
{
547-
updateDefault(set, DownstreamCompiler::SourceType(i));
662+
updateDefault(set, SlangSourceLanguage(i));
548663
}
549664
}
550665

source/core/slang-downstream-compiler.h

+45-11
Original file line numberDiff line numberDiff line change
@@ -120,12 +120,33 @@ class DownstreamCompiler: public RefObject
120120

121121
typedef DownstreamCompileResult CompileResult;
122122

123-
enum class SourceType
123+
typedef uint32_t SourceLanguageFlags;
124+
struct SourceLanguageFlag
124125
{
125-
C, ///< C source
126-
CPP, ///< C++ source
127-
CUDA, ///< The CUDA language
128-
CountOf,
126+
enum Enum : SourceLanguageFlags
127+
{
128+
Unknown = SourceLanguageFlags(1) << SLANG_SOURCE_LANGUAGE_UNKNOWN,
129+
Slang = SourceLanguageFlags(1) << SLANG_SOURCE_LANGUAGE_SLANG,
130+
HLSL = SourceLanguageFlags(1) << SLANG_SOURCE_LANGUAGE_HLSL,
131+
GLSL = SourceLanguageFlags(1) << SLANG_SOURCE_LANGUAGE_GLSL,
132+
C = SourceLanguageFlags(1) << SLANG_SOURCE_LANGUAGE_C,
133+
CPP = SourceLanguageFlags(1) << SLANG_SOURCE_LANGUAGE_CPP,
134+
CUDA = SourceLanguageFlags(1) << SLANG_SOURCE_LANGUAGE_CUDA,
135+
};
136+
};
137+
138+
struct Info
139+
{
140+
Info():sourceLanguageFlags(0) {}
141+
142+
Info(SourceLanguageFlags inSourceLanguageFlags):
143+
sourceLanguageFlags(inSourceLanguageFlags)
144+
{}
145+
SourceLanguageFlags sourceLanguageFlags;
146+
};
147+
struct Infos
148+
{
149+
Info infos[int(SLANG_PASS_THROUGH_COUNT_OF)];
129150
};
130151

131152
struct Desc
@@ -202,7 +223,7 @@ class DownstreamCompiler: public RefObject
202223
OptimizationLevel optimizationLevel = OptimizationLevel::Default;
203224
DebugInfoType debugInfoType = DebugInfoType::Standard;
204225
TargetType targetType = TargetType::Executable;
205-
SourceType sourceType = SourceType::CPP;
226+
SlangSourceLanguage sourceLanguage = SLANG_SOURCE_LANGUAGE_CPP;
206227
FloatingPointMode floatingPointMode = FloatingPointMode::Default;
207228

208229
Flags flags = Flag::EnableExceptionHandling;
@@ -262,7 +283,21 @@ class DownstreamCompiler: public RefObject
262283
/// Return the compiler type as name
263284
static UnownedStringSlice getCompilerTypeAsText(SlangPassThrough type);
264285

286+
/// Get info for a compiler type
287+
static const Info& getInfo(SlangPassThrough compiler) { return s_infos.infos[int(compiler)]; }
288+
/// True if this compiler can compile the specified language
289+
static bool canCompile(SlangPassThrough compiler, SlangSourceLanguage sourceLanguage);
290+
291+
/// Given a source language name returns a source language. Name here is distinct from extension
292+
static SlangSourceLanguage getSourceLanguageFromName(const UnownedStringSlice& text);
293+
/// Given a name returns the pass through
294+
static SlangPassThrough getPassThroughFromName(const UnownedStringSlice& slice);
295+
static SlangResult getPassThroughFromName(const UnownedStringSlice& slice, SlangPassThrough& outPassThrough);
296+
/// Get the compilers name
297+
static UnownedStringSlice getPassThroughName(SlangPassThrough passThru);
298+
265299
protected:
300+
static Infos s_infos;
266301

267302
DownstreamCompiler(const Desc& desc) :
268303
m_desc(desc)
@@ -369,9 +404,9 @@ class DownstreamCompilerSet : public RefObject
369404
void addCompiler(DownstreamCompiler* compiler);
370405

371406
/// Get a default compiler
372-
DownstreamCompiler* getDefaultCompiler(DownstreamCompiler::SourceType sourceType) const { return m_defaultCompilers[int(sourceType)]; }
407+
DownstreamCompiler* getDefaultCompiler(SlangSourceLanguage sourceLanguage) const { return m_defaultCompilers[int(sourceLanguage)]; }
373408
/// Set the default compiler
374-
void setDefaultCompiler(DownstreamCompiler::SourceType sourceType, DownstreamCompiler* compiler) { m_defaultCompilers[int(sourceType)] = compiler; }
409+
void setDefaultCompiler(SlangSourceLanguage sourceLanguage, DownstreamCompiler* compiler) { m_defaultCompilers[int(sourceLanguage)] = compiler; }
375410

376411
/// True if has a compiler of the specified type
377412
bool hasCompiler(SlangPassThrough compilerType) const;
@@ -384,7 +419,7 @@ class DownstreamCompilerSet : public RefObject
384419

385420
Index _findIndex(const DownstreamCompiler::Desc& desc) const;
386421

387-
RefPtr<DownstreamCompiler> m_defaultCompilers[int(DownstreamCompiler::SourceType::CountOf)];
422+
RefPtr<DownstreamCompiler> m_defaultCompilers[int(SLANG_SOURCE_LANGUAGE_COUNT_OF)];
388423
// This could be a dictionary/map - but doing a linear search is going to be fine and it makes
389424
// somethings easier.
390425
List<RefPtr<DownstreamCompiler>> m_compilers;
@@ -399,7 +434,6 @@ struct DownstreamCompilerBaseUtil
399434
typedef DownstreamCompiler::OptimizationLevel OptimizationLevel;
400435
typedef DownstreamCompiler::TargetType TargetType;
401436
typedef DownstreamCompiler::DebugInfoType DebugInfoType;
402-
typedef DownstreamCompiler::SourceType SourceType;
403437

404438
typedef DownstreamDiagnostics::Diagnostic Diagnostic;
405439

@@ -428,7 +462,7 @@ struct DownstreamCompilerUtil: public DownstreamCompilerBaseUtil
428462
/// Get the information on the compiler used to compile this source
429463
static const DownstreamCompiler::Desc& getCompiledWithDesc();
430464

431-
static void updateDefault(DownstreamCompilerSet* set, DownstreamCompiler::SourceType type);
465+
static void updateDefault(DownstreamCompilerSet* set, SlangSourceLanguage sourceLanguage);
432466
static void updateDefaults(DownstreamCompilerSet* set);
433467

434468
static void setDefaultLocators(DownstreamCompilerLocatorFunc outFuncs[int(SLANG_PASS_THROUGH_COUNT_OF)]);

source/core/slang-gcc-compiler-util.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -406,7 +406,7 @@ static SlangResult _parseGCCFamilyLine(const UnownedStringSlice& line, LineParse
406406

407407
PlatformKind platformKind = (options.platform == PlatformKind::Unknown) ? PlatformUtil::getPlatformKind() : options.platform;
408408

409-
if (options.sourceType == SourceType::CPP)
409+
if (options.sourceLanguage == SLANG_SOURCE_LANGUAGE_CPP)
410410
{
411411
cmdLine.addArg("-fvisibility=hidden");
412412

@@ -570,7 +570,7 @@ static SlangResult _parseGCCFamilyLine(const UnownedStringSlice& line, LineParse
570570
cmdLine.addArg(libPath);
571571
}
572572

573-
if (options.sourceType == SourceType::CPP && !PlatformUtil::isFamily(PlatformFamily::Windows, platformKind))
573+
if (options.sourceLanguage == SLANG_SOURCE_LANGUAGE_CPP && !PlatformUtil::isFamily(PlatformFamily::Windows, platformKind))
574574
{
575575
// Make STD libs available
576576
cmdLine.addArg("-lstdc++");

source/core/slang-visual-studio-compiler-util.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ namespace Slang
9494

9595
if (options.flags & CompileOptions::Flag::EnableExceptionHandling)
9696
{
97-
if (options.sourceType == SourceType::CPP)
97+
if (options.sourceLanguage == SLANG_SOURCE_LANGUAGE_CPP)
9898
{
9999
// https://docs.microsoft.com/en-us/cpp/build/reference/eh-exception-handling-model?view=vs-2019
100100
// Assumes c functions cannot throw

source/slang/slang-check.cpp

+7-6
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ namespace Slang
114114

115115
if (type == PassThroughMode::GenericCCpp)
116116
{
117-
// try loading all C/C++ compilers
117+
// try testing for availablilty on all C/C++ compilers
118118
getOrLoadDownstreamCompiler(PassThroughMode::Clang, sink);
119119
getOrLoadDownstreamCompiler(PassThroughMode::Gcc, sink);
120120
getOrLoadDownstreamCompiler(PassThroughMode::VisualStudio, sink);
@@ -138,19 +138,20 @@ namespace Slang
138138

139139
DownstreamCompilerUtil::updateDefaults(m_downstreamCompilerSet);
140140

141+
DownstreamCompiler* compiler = nullptr;
142+
141143
if (type == PassThroughMode::GenericCCpp)
142144
{
143-
m_downstreamCompilers[int(type)] = m_downstreamCompilerSet->getDefaultCompiler(DownstreamCompiler::SourceType::CPP);
145+
compiler = m_downstreamCompilerSet->getDefaultCompiler(SLANG_SOURCE_LANGUAGE_CPP);
144146
}
145147
else
146148
{
147149
DownstreamCompiler::Desc desc;
148150
desc.type = SlangPassThrough(type);
149-
150-
m_downstreamCompilers[int(type)] = DownstreamCompilerUtil::findCompiler(m_downstreamCompilerSet, DownstreamCompilerUtil::MatchType::Newest, desc);
151+
compiler = DownstreamCompilerUtil::findCompiler(m_downstreamCompilerSet, DownstreamCompilerUtil::MatchType::Newest, desc);
151152
}
152-
153-
return m_downstreamCompilers[int(type)];
153+
m_downstreamCompilers[int(type)] = compiler;
154+
return compiler;
154155
}
155156

156157
SlangFuncPtr Session::getSharedLibraryFunc(SharedLibraryFuncType type, DiagnosticSink* sink)

source/slang/slang-compiler.cpp

+2-12
Original file line numberDiff line numberDiff line change
@@ -1395,18 +1395,8 @@ SlangResult dissassembleDXILUsingDXC(
13951395
}
13961396

13971397
// Set the source type
1398-
switch (rawSourceLanguage)
1399-
{
1400-
case SourceLanguage::C: options.sourceType = DownstreamCompiler::SourceType::C; break;
1401-
case SourceLanguage::CPP: options.sourceType = DownstreamCompiler::SourceType::CPP; break;
1402-
case SourceLanguage::CUDA: options.sourceType = DownstreamCompiler::SourceType::CUDA; break;
1403-
default:
1404-
{
1405-
SLANG_ASSERT(!"Unhandled source language");
1406-
return SLANG_FAIL;
1407-
}
1408-
}
1409-
1398+
options.sourceLanguage = SlangSourceLanguage(rawSourceLanguage);
1399+
14101400
// Disable exceptions and security checks
14111401
options.flags &= ~(CompileOptions::Flag::EnableExceptionHandling | CompileOptions::Flag::EnableSecurityChecks);
14121402

source/slang/slang-compiler.h

+3-2
Original file line numberDiff line numberDiff line change
@@ -1975,12 +1975,13 @@ namespace Slang
19751975
~Session();
19761976

19771977
ComPtr<ISlangSharedLibraryLoader> m_sharedLibraryLoader; ///< The shared library loader (never null)
1978+
19781979
SlangFuncPtr m_sharedLibraryFunctions[int(SharedLibraryFuncType::CountOf)]; ///< Functions from shared libraries
19791980

19801981
int m_downstreamCompilerInitialized = 0;
19811982

1982-
RefPtr<DownstreamCompilerSet> m_downstreamCompilerSet; ///< Information about all available downstream compilers.
1983-
RefPtr<DownstreamCompiler> m_downstreamCompilers[int(PassThroughMode::CountOf)]; ///< A downstream compiler for a pass through
1983+
RefPtr<DownstreamCompilerSet> m_downstreamCompilerSet; ///< Information about all available downstream compilers.
1984+
RefPtr<DownstreamCompiler> m_downstreamCompilers[int(PassThroughMode::CountOf)]; ///< A downstream compiler for a pass through
19841985
DownstreamCompilerLocatorFunc m_downstreamCompilerLocators[int(PassThroughMode::CountOf)];
19851986

19861987
private:

0 commit comments

Comments
 (0)