diff options
Diffstat (limited to 'source/slang/emit.cpp')
| -rw-r--r-- | source/slang/emit.cpp | 100 |
1 files changed, 96 insertions, 4 deletions
diff --git a/source/slang/emit.cpp b/source/slang/emit.cpp index aee19018a..ace8a1559 100644 --- a/source/slang/emit.cpp +++ b/source/slang/emit.cpp @@ -124,6 +124,10 @@ struct SharedEmitContext HashSet<String> irDeclsVisited; HashSet<String> irTupleTypes; + + // The "effective" profile that is being used to emit code, + // combining information from the target and entry point. + Profile effctiveProfile; }; struct EmitContext @@ -134,6 +138,7 @@ struct EmitContext // +#ifdef DEADCODE void requireGLSLVersion( EntryPointRequest* entryPoint, ProfileVersion version) @@ -155,6 +160,7 @@ void requireGLSLVersion( entryPoint->profile = profile; } } +#endif // @@ -2011,8 +2017,7 @@ struct EmitVisitor if (context->shared->target != CodeGenTarget::GLSL) return; - auto entryPoint = context->shared->entryPoint; - Slang::requireGLSLVersion(entryPoint, version); + Slang::requireGLSLVersionImpl(&context->shared->extensionUsageTracker, version); } void requireGLSLVersion(int version) @@ -2083,12 +2088,14 @@ struct EmitVisitor requireGLSLExtension(requiredGLSLExtensionModifier->extensionNameToken.Content); } +#ifdef DEADCODE // Does this intrinsic requie a particular GLSL extension that wouldn't be available by default? if (auto requiredGLSLVersionModifier = funcDecl->FindModifier<RequiredGLSLVersionModifier>()) { // If so, we had better request the extension. requireGLSLVersion((int) getIntegerLiteralValue(requiredGLSLVersionModifier->versionNumberToken)); } +#endif } @@ -2673,8 +2680,15 @@ struct EmitVisitor ExprVisitorWithArg::dispatch(derefExpr->base, arg); } - void visitConstantExpr(ConstantExpr* litExpr, ExprEmitArg const& arg) + void visitLiteralExpr(LiteralExpr*, ExprEmitArg const&) { + // Disabling because we no longer use the AST-based emit path. + // + // Note: I'm keeping this code around for a while just in case + // we want to borrow any of the logic here for how to apply + // suffixes to numeric literals we emit. + // +#if 0 auto outerPrec = arg.outerPrec; bool needClose = MaybeEmitParens(outerPrec, kEOp_Atomic); @@ -2736,6 +2750,7 @@ struct EmitVisitor break; } if(needClose) Emit(")"); +#endif } void visitTypeCastExpr(TypeCastExpr* castExpr, ExprEmitArg const& arg) @@ -4301,8 +4316,9 @@ struct EmitVisitor } void emitGLSLVersionDirective( - ModuleDecl* program) + ModuleDecl* /*program*/) { +#ifdef DEADCODE // Did the user provide an explicit `#version` directive in their code? if( auto versionDirective = program->FindModifier<GLSLVersionDirective>() ) { @@ -4350,6 +4366,48 @@ struct EmitVisitor break; } } +#endif + + auto effctiveProfile = context->shared->effctiveProfile; + if(effctiveProfile.getFamily() == ProfileFamily::GLSL) + { + requireGLSLVersion(effctiveProfile.GetVersion()); + } + + // HACK: We aren't picking GLSL versions carefully right now, + // and so we might end up only requiring the initial 1.10 version, + // even though even basic functionality needs a higher version. + // + // For now, we'll work around this by just setting the minimum required + // version to a high one: + // + // TODO: Either correctly compute a minimum required version, or require + // the user to specify a version as part of the target. + requireGLSLVersionImpl(&context->shared->extensionUsageTracker, ProfileVersion::GLSL_450); + + auto requiredProfileVersion = context->shared->extensionUsageTracker.profileVersion; + switch (requiredProfileVersion) + { +#define CASE(TAG, VALUE) \ + case ProfileVersion::TAG: 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); +#undef CASE + + default: + break; + } // No information is available for us to guess a profile, // so it seems like we need to pick one out of thin air. @@ -6694,6 +6752,32 @@ emitDeclImpl(decl, nullptr); auto profile = entryPointLayout->profile; auto stage = profile.GetStage(); + if(profile.getFamily() == ProfileFamily::DX) + { + if(profile.GetVersion() >= ProfileVersion::DX_6_1 ) + { + char const* stageName = nullptr; + switch(stage) + { + case Stage::Compute: stageName = "compute"; + case Stage::Vertex: stageName = "vertex"; + case Stage::Hull: stageName = "hull"; + case Stage::Domain: stageName = "domain"; + case Stage::Geometry: stageName = "geometry"; + case Stage::Fragment: stageName = "pixel"; + default: + break; + } + + if(stageName) + { + emit("[shader(\""); + emit(stageName); + emit("\")]"); + } + } + } + switch (stage) { case Stage::Compute: @@ -8061,6 +8145,13 @@ EntryPointLayout* findEntryPointLayout( if(entryPointLayout->entryPoint->getName() != entryPointRequest->name) continue; + // TODO: We need to be careful about this check, since it relies on + // the profile information in the layout matching that in the request. + // + // What we really seem to want here is some dictionary mapping the + // `EntryPointRequest` directly to the `EntryPointLayout`, and maybe + // that is precisely what we should build... + // if(entryPointLayout->profile != entryPointRequest->profile) continue; @@ -8139,6 +8230,7 @@ String emitEntryPoint( sharedContext.target = target; sharedContext.finalTarget = targetRequest->target; sharedContext.entryPoint = entryPoint; + sharedContext.effctiveProfile = getEffectiveProfile(entryPoint, targetRequest); if (entryPoint) { |
