summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjsmall-nvidia <jsmall@nvidia.com>2022-05-17 17:27:12 -0400
committerGitHub <noreply@github.com>2022-05-17 17:27:12 -0400
commit05c4c2679ae979cfcb61e4c2acdb432c34384ddb (patch)
treeda146d2f90a28319a32bcb27ea33acec21537265
parent39fb45484996f9d71b6551239dbf55eaaaf8db1f (diff)
Refactor prelude emit (#2236)
* #include an absolute path didn't work - because paths were taken to always be relative. * Refactor how prelude output works in emit. * Small improvement to emit output. * Move around comment on target specific language directives based on review. Co-authored-by: Theresa Foley <10618364+tangent-vector@users.noreply.github.com>
-rw-r--r--source/slang/slang-emit-c-like.cpp25
-rw-r--r--source/slang/slang-emit-c-like.h28
-rw-r--r--source/slang/slang-emit-cpp.cpp15
-rw-r--r--source/slang/slang-emit-cpp.h2
-rw-r--r--source/slang/slang-emit-cuda.cpp10
-rw-r--r--source/slang/slang-emit-cuda.h7
-rw-r--r--source/slang/slang-emit-glsl.cpp104
-rw-r--r--source/slang/slang-emit-glsl.h4
-rw-r--r--source/slang/slang-emit-hlsl.cpp35
-rw-r--r--source/slang/slang-emit-hlsl.h7
-rw-r--r--source/slang/slang-emit.cpp73
11 files changed, 157 insertions, 153 deletions
diff --git a/source/slang/slang-emit-c-like.cpp b/source/slang/slang-emit-c-like.cpp
index a6edc0a1f..895421783 100644
--- a/source/slang/slang-emit-c-like.cpp
+++ b/source/slang/slang-emit-c-like.cpp
@@ -106,6 +106,11 @@ SlangResult CLikeSourceEmitter::init()
return SLANG_OK;
}
+void CLikeSourceEmitter::emitFrontMatterImpl(TargetRequest* targetReq)
+{
+ SLANG_UNUSED(targetReq);
+}
+
//
// Types
//
@@ -534,26 +539,6 @@ UInt CLikeSourceEmitter::getBindingSpace(EmitVarChain* chain, LayoutResourceKind
return space;
}
-void CLikeSourceEmitter::emitLayoutDirectives(TargetRequest* targetReq)
-{
- // We are going to emit the target-language-specific directives
- // needed to get the default matrix layout to match what was requested
- // for the given target.
- //
- // Note: we do not rely on the defaults for the target language,
- // because a user could take the HLSL/GLSL generated by Slang and pass
- // it to another compiler with non-default options specified on
- // the command line, leading to all kinds of trouble.
- //
- // TODO: We need an approach to "global" layout directives that will work
- // in the presence of multiple modules. If modules A and B were each
- // compiled with different assumptions about how layout is performed,
- // then types/variables defined in those modules should be emitted in
- // a way that is consistent with that layout...
-
- emitLayoutDirectivesImpl(targetReq);
-}
-
UInt CLikeSourceEmitter::allocateUniqueID()
{
return m_uniqueIDCounter++;
diff --git a/source/slang/slang-emit-c-like.h b/source/slang/slang-emit-c-like.h
index 51e54611e..ddda94e84 100644
--- a/source/slang/slang-emit-c-like.h
+++ b/source/slang/slang-emit-c-like.h
@@ -261,9 +261,6 @@ public:
UInt getBindingOffset(EmitVarChain* chain, LayoutResourceKind kind);
UInt getBindingSpace(EmitVarChain* chain, LayoutResourceKind kind);
- /// Emit directives to control overall layout computation for the emitted code.
- void emitLayoutDirectives(TargetRequest* targetReq);
-
// Utility code for generating unique IDs as needed
// during the emit process (e.g., for declarations
// that didn't originally have names, but now need to).
@@ -398,17 +395,15 @@ public:
void executeEmitActions(List<EmitAction> const& actions);
+ // Emits front matter, that occurs before the prelude
+ // Doesn't emit generated function/types that's handled by emitPreModule
+ void emitFrontMatter(TargetRequest* targetReq) { emitFrontMatterImpl(targetReq); }
+
+ void emitPreModule() { emitPreModuleImpl(); }
+
void emitModule(IRModule* module, DiagnosticSink* sink)
{ m_irModule = module; emitModuleImpl(module, sink); }
- /// Emit any preprocessor directives that should come *before* the prelude code
- ///
- /// These are directives that are intended to customize some aspect(s) of the
- /// prelude's behavior.
- ///
- void emitPreludeDirectives() { emitPreludeDirectivesImpl(); }
-
- void emitPreprocessorDirectives() { emitPreprocessorDirectivesImpl(); }
void emitSimpleType(IRType* type);
void emitVectorTypeName(IRType* elementType, IRIntegerValue elementCount) { emitVectorTypeNameImpl(elementType, elementCount); }
@@ -438,9 +433,14 @@ public:
virtual void emitImageFormatModifierImpl(IRInst* varDecl, IRType* varType) { SLANG_UNUSED(varDecl); SLANG_UNUSED(varType); }
virtual void emitLayoutQualifiersImpl(IRVarLayout* layout) { SLANG_UNUSED(layout); }
- virtual void emitPreludeDirectivesImpl() {}
- virtual void emitPreprocessorDirectivesImpl() {}
- virtual void emitLayoutDirectivesImpl(TargetRequest* targetReq) { SLANG_UNUSED(targetReq); }
+
+ /// Emit front matter inserting prelude where appropriate
+ virtual void emitFrontMatterImpl(TargetRequest* targetReq);
+ /// Emit any declarations, and other material that is needed before the modules contents
+ /// For example on targets that don't have built in vector/matrix support, this is where
+ /// the appropriate generated declarations occur.
+ virtual void emitPreModuleImpl() {}
+
virtual void emitRateQualifiersImpl(IRRate* rate) { SLANG_UNUSED(rate); }
virtual void emitSemanticsImpl(IRInst* inst) { SLANG_UNUSED(inst); }
virtual void emitSimpleFuncParamImpl(IRParam* param);
diff --git a/source/slang/slang-emit-cpp.cpp b/source/slang/slang-emit-cpp.cpp
index 81d32c297..9887f1ba6 100644
--- a/source/slang/slang-emit-cpp.cpp
+++ b/source/slang/slang-emit-cpp.cpp
@@ -2459,15 +2459,13 @@ static Index _calcTypeOrder(IRType* a)
}
}
-void CPPSourceEmitter::emitPreprocessorDirectivesImpl()
+void CPPSourceEmitter::emitPreModuleImpl()
{
- SourceWriter* writer = getSourceWriter();
-
- writer->emit("\n");
-
-
if (m_target == CodeGenTarget::CPPSource)
{
+ // NOTE, that this opens an anonymous scope.
+ // The scope is closed in `emitModuleImpl`
+
// When generating kernel code in C++, put all into an anonymous namespace
// This includes any generated types, and generated intrinsics.
m_writer->emit("namespace { // anonymous \n\n");
@@ -2476,6 +2474,8 @@ void CPPSourceEmitter::emitPreprocessorDirectivesImpl()
m_writer->emit("#endif\n\n");
}
+ // Emit generated functions and types
+
if (m_target == CodeGenTarget::CSource)
{
// For C output we need to emit type definitions.
@@ -2507,7 +2507,7 @@ void CPPSourceEmitter::emitPreprocessorDirectivesImpl()
m_intrinsicSet.getIntrinsics(intrinsics);
// Emit all the intrinsics that were used
- for (auto intrinsic: intrinsics)
+ for (auto intrinsic : intrinsics)
{
_maybeEmitSpecializedOperationDefinition(intrinsic);
}
@@ -2757,7 +2757,6 @@ void CPPSourceEmitter::emitModuleImpl(IRModule* module, DiagnosticSink* sink)
_emitForwardDeclarations(actions);
-
{
// Output all the thread locals
for (auto action : actions)
diff --git a/source/slang/slang-emit-cpp.h b/source/slang/slang-emit-cpp.h
index dc9f78df2..0d9327b9e 100644
--- a/source/slang/slang-emit-cpp.h
+++ b/source/slang/slang-emit-cpp.h
@@ -59,7 +59,7 @@ protected:
virtual void _emitType(IRType* type, DeclaratorInfo* declarator) SLANG_OVERRIDE;
virtual void emitVectorTypeNameImpl(IRType* elementType, IRIntegerValue elementCount) SLANG_OVERRIDE;
virtual bool tryEmitInstExprImpl(IRInst* inst, const EmitOpInfo& inOuterPrec) SLANG_OVERRIDE;
- virtual void emitPreprocessorDirectivesImpl() SLANG_OVERRIDE;
+ virtual void emitPreModuleImpl() SLANG_OVERRIDE;
virtual void emitSimpleValueImpl(IRInst* value) SLANG_OVERRIDE;
virtual void emitSimpleFuncParamImpl(IRParam* param) SLANG_OVERRIDE;
virtual void emitModuleImpl(IRModule* module, DiagnosticSink* sink) SLANG_OVERRIDE;
diff --git a/source/slang/slang-emit-cuda.cpp b/source/slang/slang-emit-cuda.cpp
index f7850179d..eda30b956 100644
--- a/source/slang/slang-emit-cuda.cpp
+++ b/source/slang/slang-emit-cuda.cpp
@@ -840,11 +840,6 @@ void CUDASourceEmitter::handleRequiredCapabilitiesImpl(IRInst* inst)
}
}
-void CUDASourceEmitter::emitLayoutDirectivesImpl(TargetRequest* targetReq)
-{
- SLANG_UNUSED(targetReq);
-}
-
void CUDASourceEmitter::emitVectorTypeNameImpl(IRType* elementType, IRIntegerValue elementCount)
{
m_writer->emit(getVectorPrefix(elementType->getOp()));
@@ -933,10 +928,12 @@ void CUDASourceEmitter::emitMatrixLayoutModifiersImpl(IRVarLayout* layout)
Super::emitMatrixLayoutModifiersImpl(layout);
}
-void CUDASourceEmitter::emitPreprocessorDirectivesImpl()
+void CUDASourceEmitter::emitPreModuleImpl()
{
SourceWriter* writer = getSourceWriter();
+ // Emit generated types/functions
+
writer->emit("\n");
{
@@ -961,6 +958,7 @@ void CUDASourceEmitter::emitPreprocessorDirectivesImpl()
}
}
+
bool CUDASourceEmitter::tryEmitGlobalParamImpl(IRGlobalParam* varDecl, IRType* varType)
{
// A global shader parameter in the IR for CUDA output will
diff --git a/source/slang/slang-emit-cuda.h b/source/slang/slang-emit-cuda.h
index 8bd2d33c4..ff947fe58 100644
--- a/source/slang/slang-emit-cuda.h
+++ b/source/slang/slang-emit-cuda.h
@@ -65,7 +65,9 @@ protected:
virtual void emitLayoutSemanticsImpl(IRInst* inst, char const* uniformSemanticSpelling) SLANG_OVERRIDE;
virtual void emitParameterGroupImpl(IRGlobalParam* varDecl, IRUniformParameterGroupType* type) SLANG_OVERRIDE;
virtual void emitEntryPointAttributesImpl(IRFunc* irFunc, IREntryPointDecoration* entryPointDecor) SLANG_OVERRIDE;
- virtual void emitLayoutDirectivesImpl(TargetRequest* targetReq) SLANG_OVERRIDE;
+
+ virtual void emitPreModuleImpl() SLANG_OVERRIDE;
+
virtual void emitRateQualifiersImpl(IRRate* rate) SLANG_OVERRIDE;
virtual void emitSemanticsImpl(IRInst* inst) SLANG_OVERRIDE;
virtual void emitSimpleFuncImpl(IRFunc* func) SLANG_OVERRIDE;
@@ -91,8 +93,7 @@ protected:
virtual bool tryEmitGlobalParamImpl(IRGlobalParam* varDecl, IRType* varType) SLANG_OVERRIDE;
virtual bool tryEmitInstExprImpl(IRInst* inst, const EmitOpInfo& inOuterPrec) SLANG_OVERRIDE;
- virtual void emitPreprocessorDirectivesImpl() SLANG_OVERRIDE;
-
+
virtual void emitModuleImpl(IRModule* module, DiagnosticSink* sink) SLANG_OVERRIDE;
// CPPSourceEmitter overrides
diff --git a/source/slang/slang-emit-glsl.cpp b/source/slang/slang-emit-glsl.cpp
index 7578a2dd5..d9c81f14b 100644
--- a/source/slang/slang-emit-glsl.cpp
+++ b/source/slang/slang-emit-glsl.cpp
@@ -12,6 +12,10 @@
namespace Slang {
+void trackGLSLTargetCaps(
+ GLSLExtensionTracker* extensionTracker,
+ CapabilitySet const& caps);
+
GLSLSourceEmitter::GLSLSourceEmitter(const Desc& desc) :
Super(desc)
{
@@ -1740,7 +1744,33 @@ void GLSLSourceEmitter::handleRequiredCapabilitiesImpl(IRInst* inst)
}
}
-void GLSLSourceEmitter::emitPreprocessorDirectivesImpl()
+static Index _getGLSLVersion(ProfileVersion profile)
+{
+ switch (profile)
+ {
+#define CASE(TAG, VALUE) case ProfileVersion::TAG: return VALUE;
+ CASE(GLSL_110, 110);
+ CASE(GLSL_120, 120);
+ CASE(GLSL_130, 130);
+ CASE(GLSL_140, 140);
+ CASE(GLSL_150, 150);
+ CASE(GLSL_330, 330);
+ CASE(GLSL_400, 400);
+ CASE(GLSL_410, 410);
+ CASE(GLSL_420, 420);
+ CASE(GLSL_430, 430);
+ CASE(GLSL_440, 440);
+ CASE(GLSL_450, 450);
+ CASE(GLSL_460, 460);
+#undef CASE
+
+ default:
+ break;
+ }
+ return -1;
+}
+
+void GLSLSourceEmitter::emitFrontMatterImpl(TargetRequest* targetReq)
{
auto effectiveProfile = m_effectiveProfile;
if (effectiveProfile.getFamily() == ProfileFamily::GLSL)
@@ -1759,44 +1789,34 @@ void GLSLSourceEmitter::emitPreprocessorDirectivesImpl()
// the user to specify a version as part of the target.
m_glslExtensionTracker->requireVersion(ProfileVersion::GLSL_450);
- auto requiredProfileVersion = m_glslExtensionTracker->getRequiredProfileVersion();
- switch (requiredProfileVersion)
+ Index glslVersion = _getGLSLVersion(m_glslExtensionTracker->getRequiredProfileVersion());
+ if (glslVersion < 0)
{
-#define CASE(TAG, VALUE) \
-case ProfileVersion::TAG: m_writer->emit("#version " #VALUE "\n"); return
-
- CASE(GLSL_110, 110);
- CASE(GLSL_120, 120);
- CASE(GLSL_130, 130);
- CASE(GLSL_140, 140);
- CASE(GLSL_150, 150);
- CASE(GLSL_330, 330);
- CASE(GLSL_400, 400);
- CASE(GLSL_410, 410);
- CASE(GLSL_420, 420);
- CASE(GLSL_430, 430);
- CASE(GLSL_440, 440);
- CASE(GLSL_450, 450);
- CASE(GLSL_460, 460);
-#undef CASE
+ // No information is available for us to guess a profile,
+ // so it seems like we need to pick one out of thin air.
+ //
+ // Ideally we should infer a minimum required version based
+ // on the constructs we have seen used in the user's code
+ //
+ // For now we just fall back to a reasonably recent version.
- default:
- break;
+ glslVersion = 420;
}
- // No information is available for us to guess a profile,
- // so it seems like we need to pick one out of thin air.
- //
- // Ideally we should infer a minimum required version based
- // on the constructs we have seen used in the user's code
- //
- // For now we just fall back to a reasonably recent version.
+ m_writer->emit("#version ");
+ m_writer->emit(glslVersion);
+ m_writer->emit("\n");
- m_writer->emit("#version 420\n");
-}
+ // Output the extensions
+ if (m_glslExtensionTracker)
+ {
+ trackGLSLTargetCaps(m_glslExtensionTracker, targetReq->getTargetCaps());
+
+ StringBuilder builder;
+ m_glslExtensionTracker->appendExtensionRequireLines(builder);
+ m_writer->emit(builder.getUnownedSlice());
+ }
-void GLSLSourceEmitter::emitLayoutDirectivesImpl(TargetRequest* targetReq)
-{
// Reminder: the meaning of row/column major layout
// in our semantics is the *opposite* of what GLSL
// calls them, because what they call "columns"
@@ -1804,16 +1824,16 @@ void GLSLSourceEmitter::emitLayoutDirectivesImpl(TargetRequest* targetReq)
//
switch (targetReq->getDefaultMatrixLayoutMode())
{
- case kMatrixLayoutMode_RowMajor:
- default:
- m_writer->emit("layout(column_major) uniform;\n");
- m_writer->emit("layout(column_major) buffer;\n");
- break;
+ case kMatrixLayoutMode_RowMajor:
+ default:
+ m_writer->emit("layout(column_major) uniform;\n");
+ m_writer->emit("layout(column_major) buffer;\n");
+ break;
- case kMatrixLayoutMode_ColumnMajor:
- m_writer->emit("layout(row_major) uniform;\n");
- m_writer->emit("layout(row_major) buffer;\n");
- break;
+ case kMatrixLayoutMode_ColumnMajor:
+ m_writer->emit("layout(row_major) uniform;\n");
+ m_writer->emit("layout(row_major) buffer;\n");
+ break;
}
}
diff --git a/source/slang/slang-emit-glsl.h b/source/slang/slang-emit-glsl.h
index 481efed63..3edf7bec7 100644
--- a/source/slang/slang-emit-glsl.h
+++ b/source/slang/slang-emit-glsl.h
@@ -29,8 +29,8 @@ protected:
virtual void emitTextureOrTextureSamplerTypeImpl(IRTextureTypeBase* type, char const* baseName) SLANG_OVERRIDE { _emitGLSLTextureOrTextureSamplerType(type, baseName); }
- virtual void emitPreprocessorDirectivesImpl() SLANG_OVERRIDE;
- virtual void emitLayoutDirectivesImpl(TargetRequest* targetReq) SLANG_OVERRIDE;
+ virtual void emitFrontMatterImpl(TargetRequest* targetReq) SLANG_OVERRIDE;
+
virtual void emitRateQualifiersImpl(IRRate* rate) SLANG_OVERRIDE;
virtual void emitInterpolationModifiersImpl(IRInst* varInst, IRType* valueType, IRVarLayout* layout) SLANG_OVERRIDE;
virtual void emitSimpleTypeImpl(IRType* type) SLANG_OVERRIDE;
diff --git a/source/slang/slang-emit-hlsl.cpp b/source/slang/slang-emit-hlsl.cpp
index c319f2738..2d42aef83 100644
--- a/source/slang/slang-emit-hlsl.cpp
+++ b/source/slang/slang-emit-hlsl.cpp
@@ -665,20 +665,6 @@ bool HLSLSourceEmitter::tryEmitInstExprImpl(IRInst* inst, const EmitOpInfo& inOu
return false;
}
-void HLSLSourceEmitter::emitLayoutDirectivesImpl(TargetRequest* targetReq)
-{
- switch (targetReq->getDefaultMatrixLayoutMode())
- {
- case kMatrixLayoutMode_RowMajor:
- default:
- m_writer->emit("#pragma pack_matrix(row_major)\n");
- break;
- case kMatrixLayoutMode_ColumnMajor:
- m_writer->emit("#pragma pack_matrix(column_major)\n");
- break;
- }
-}
-
void HLSLSourceEmitter::emitVectorTypeNameImpl(IRType* elementType, IRIntegerValue elementCount)
{
// In some cases we *need* to use the built-in syntax sugar for vector types,
@@ -1133,9 +1119,9 @@ void HLSLSourceEmitter::handleRequiredCapabilitiesImpl(IRInst* inst)
}
}
-void HLSLSourceEmitter::emitPreludeDirectivesImpl()
+void HLSLSourceEmitter::emitFrontMatterImpl(TargetRequest* targetReq)
{
- if( m_extensionTracker->m_requiresNVAPI )
+ if (m_extensionTracker->m_requiresNVAPI)
{
// If the generated code includes implicit NVAPI use,
// then we need to ensure that NVAPI support is included
@@ -1159,7 +1145,7 @@ void HLSLSourceEmitter::emitPreludeDirectivesImpl()
// they could pass in these `#define`s using command-line
// or API options.
//
- if( auto decor = m_irModule->getModuleInst()->findDecoration<IRNVAPISlotDecoration>() )
+ if (auto decor = m_irModule->getModuleInst()->findDecoration<IRNVAPISlotDecoration>())
{
m_writer->emit("#define NV_SHADER_EXTN_SLOT ");
m_writer->emit(decor->getRegisterName());
@@ -1171,7 +1157,7 @@ void HLSLSourceEmitter::emitPreludeDirectivesImpl()
// understanding of `space`s).
//
auto spaceName = decor->getSpaceName();
- if( spaceName != "space0" )
+ if (spaceName != "space0")
{
m_writer->emit("#define NV_SHADER_EXTN_REGISTER_SPACE ");
m_writer->emit(spaceName);
@@ -1179,6 +1165,19 @@ void HLSLSourceEmitter::emitPreludeDirectivesImpl()
}
}
}
+
+ // Emit any layout declarations
+
+ switch (targetReq->getDefaultMatrixLayoutMode())
+ {
+ case kMatrixLayoutMode_RowMajor:
+ default:
+ m_writer->emit("#pragma pack_matrix(row_major)\n");
+ break;
+ case kMatrixLayoutMode_ColumnMajor:
+ m_writer->emit("#pragma pack_matrix(column_major)\n");
+ break;
+ }
}
void HLSLSourceEmitter::emitGlobalInstImpl(IRInst* inst)
diff --git a/source/slang/slang-emit-hlsl.h b/source/slang/slang-emit-hlsl.h
index bbd8ad15e..763b63277 100644
--- a/source/slang/slang-emit-hlsl.h
+++ b/source/slang/slang-emit-hlsl.h
@@ -32,7 +32,9 @@ protected:
virtual void emitLayoutSemanticsImpl(IRInst* inst, char const* uniformSemanticSpelling) SLANG_OVERRIDE;
virtual void emitParameterGroupImpl(IRGlobalParam* varDecl, IRUniformParameterGroupType* type) SLANG_OVERRIDE;
virtual void emitEntryPointAttributesImpl(IRFunc* irFunc, IREntryPointDecoration* entryPointDecor) SLANG_OVERRIDE;
- virtual void emitLayoutDirectivesImpl(TargetRequest* targetReq) SLANG_OVERRIDE;
+
+ virtual void emitFrontMatterImpl(TargetRequest* targetReq) SLANG_OVERRIDE;
+
virtual void emitRateQualifiersImpl(IRRate* rate) SLANG_OVERRIDE;
virtual void emitSemanticsImpl(IRInst* inst) SLANG_OVERRIDE;
virtual void emitSimpleFuncParamImpl(IRParam* param) SLANG_OVERRIDE;
@@ -49,8 +51,7 @@ protected:
virtual void emitFuncDecorationsImpl(IRFunc* func) SLANG_OVERRIDE;
virtual void handleRequiredCapabilitiesImpl(IRInst* inst) SLANG_OVERRIDE;
- virtual void emitPreludeDirectivesImpl() SLANG_OVERRIDE;
-
+
virtual void emitGlobalInstImpl(IRInst* inst) SLANG_OVERRIDE;
virtual void emitPostKeywordTypeAttributesImpl(IRInst* inst) SLANG_OVERRIDE;
diff --git a/source/slang/slang-emit.cpp b/source/slang/slang-emit.cpp
index baf0949bb..d231acf14 100644
--- a/source/slang/slang-emit.cpp
+++ b/source/slang/slang-emit.cpp
@@ -821,16 +821,11 @@ Result linkAndOptimizeIR(
return SLANG_OK;
}
-void trackGLSLTargetCaps(
- GLSLExtensionTracker* extensionTracker,
- CapabilitySet const& caps);
-
SlangResult CodeGenContext::emitEntryPointsSourceFromIR(
String& outSource)
{
outSource = String();
- auto extensionTracker = getExtensionTracker();
auto session = getSession();
auto sink = getSink();
auto sourceManager = getSourceManager();
@@ -950,51 +945,57 @@ SlangResult CodeGenContext::emitEntryPointsSourceFromIR(
// Now that we've emitted the code for all the declarations in the file,
// it is time to stitch together the final output.
- sourceEmitter->emitPreludeDirectives();
-
- if (isHeterogeneousTarget(target))
- {
- sourceWriter.emit(get_slang_cpp_host_prelude());
- }
- else
- {
- // If there is a prelude emit it
- const auto& prelude = session->getPreludeForLanguage(sourceLanguage);
- if (prelude.getLength() > 0)
- {
- sourceWriter.emit(prelude.getUnownedSlice());
- }
- }
-
// There may be global-scope modifiers that we should emit now
// Supress emitting line directives when emitting preprocessor directives since
// these preprocessor directives may be required to appear in the first line
// of the output. An example is that the "#version" line in a GLSL source must
// appear before anything else.
sourceWriter.supressLineDirective();
- sourceEmitter->emitPreprocessorDirectives();
- sourceWriter.resumeLineDirective();
+
+ // When emitting front matter we can emit the target-language-specific directives
+ // needed to get the default matrix layout to match what was requested
+ // for the given target.
+ //
+ // Note: we do not rely on the defaults for the target language,
+ // because a user could take the HLSL/GLSL generated by Slang and pass
+ // it to another compiler with non-default options specified on
+ // the command line, leading to all kinds of trouble.
+ //
+ // TODO: We need an approach to "global" layout directives that will work
+ // in the presence of multiple modules. If modules A and B were each
+ // compiled with different assumptions about how layout is performed,
+ // then types/variables defined in those modules should be emitted in
+ // a way that is consistent with that layout...
- if (auto glslExtensionTracker = as<GLSLExtensionTracker>(extensionTracker))
- {
- trackGLSLTargetCaps(glslExtensionTracker, targetRequest->getTargetCaps());
+ // Emit any front matter
+ sourceEmitter->emitFrontMatter(targetRequest);
- StringBuilder builder;
- glslExtensionTracker->appendExtensionRequireLines(builder);
- sourceWriter.emit(builder.getUnownedSlice());
+ // If heterogeneous we output the prelude before everything else
+ if (isHeterogeneousTarget(target))
+ {
+ sourceWriter.emit(get_slang_cpp_host_prelude());
+ }
+ else
+ {
+ // Get the prelude
+ String prelude = session->getPreludeForLanguage(sourceLanguage);
+ sourceWriter.emit(prelude);
}
- sourceEmitter->emitLayoutDirectives(targetRequest);
+ // Emit anything that goes before the contents of the code generated for the module
+ sourceEmitter->emitPreModule();
- String prefix = sourceWriter.getContent();
-
- StringBuilder finalResultBuilder;
- finalResultBuilder << prefix;
+ sourceWriter.resumeLineDirective();
+
+ // Get the content built so far from the front matter/prelude/preModule
+ // By getting in this way, the content is no longer referenced by the sourceWriter.
+ String finalResult = sourceWriter.getContentAndClear();
- finalResultBuilder << code;
+ // Append the modules output code
+ finalResult.append(code);
// Write out the result
- outSource = finalResultBuilder.ProduceString();
+ outSource = finalResult;
return SLANG_OK;
}