From 05c4c2679ae979cfcb61e4c2acdb432c34384ddb Mon Sep 17 00:00:00 2001 From: jsmall-nvidia Date: Tue, 17 May 2022 17:27:12 -0400 Subject: 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> --- source/slang/slang-emit.cpp | 73 +++++++++++++++++++++++---------------------- 1 file changed, 37 insertions(+), 36 deletions(-) (limited to 'source/slang/slang-emit.cpp') 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(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; } -- cgit v1.2.3