summaryrefslogtreecommitdiffstats
path: root/source/slang/emit.cpp
diff options
context:
space:
mode:
authorTim Foley <tfoley@nvidia.com>2017-07-13 09:12:50 -0700
committerTim Foley <tfoley@nvidia.com>2017-07-13 09:17:27 -0700
commit6da80f58ba8f51fc768f177f28a7d818b03c434e (patch)
tree7bc2a09c412856951e036622f2b9d3a2742bcd4c /source/slang/emit.cpp
parent72a3e97fe6bfdffee253ad008cab7cdd3b9e796f (diff)
Allow GLSL `#version` to be selected based on profile
Fixes #83 - The basic idea is that I added a bunch of more specific profile names line `glsl_vertex_430` which indicate the desired GLSL version the user wants. - An explicit `#version` line in the code always overrides one specified by profile, though
Diffstat (limited to 'source/slang/emit.cpp')
-rw-r--r--source/slang/emit.cpp84
1 files changed, 64 insertions, 20 deletions
diff --git a/source/slang/emit.cpp b/source/slang/emit.cpp
index 68c84a277..21c91a5c0 100644
--- a/source/slang/emit.cpp
+++ b/source/slang/emit.cpp
@@ -18,6 +18,9 @@ namespace Slang {
// Shared state for an entire emit session
struct SharedEmitContext
{
+ // The entry point we are being asked to compile
+ EntryPointRequest* entryPoint;
+
// The target language we want to generate code for
CodeGenTarget target;
@@ -3396,19 +3399,10 @@ struct EmitVisitor
}
}
- void emitGLSLPreprocessorDirectives(
- RefPtr<ProgramSyntaxNode> program)
+ void emitGLSLVersionDirective(
+ ProgramSyntaxNode* program)
{
- switch(context->shared->target)
- {
- // Don't emit this stuff unless we are targetting GLSL
- default:
- return;
-
- case CodeGenTarget::GLSL:
- break;
- }
-
+ // Did the user provide an explicit `#version` directive in their code?
if( auto versionDirective = program->FindModifier<GLSLVersionDirective>() )
{
// TODO(tfoley): Emit an appropriate `#line` directive...
@@ -3421,19 +3415,68 @@ struct EmitVisitor
emit(versionDirective->glslProfileToken.Content);
}
Emit("\n");
+ return;
}
- else
+
+ // No explicit version was given. This could be because we are cross-compiling,
+ // but it also might just be that they user wrote GLSL without thinking about
+ // versions.
+
+ // First, look and see if the target profile gives us a version to use:
+ auto profile = context->shared->entryPoint->profile;
+ if (profile.getFamily() == ProfileFamily::GLSL)
{
- // No explicit version was given (probably because we are cross-compiling).
- //
- // We need to pick an appropriate version, ideally based on the features
- // that the shader ends up using.
- //
- // For now we just fall back to a reasonably recent version.
+ switch (profile.GetVersion())
+ {
+#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.
+ //
+ // 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.
+
+ Emit("#version 420\n");
+ }
+
+ void emitGLSLPreprocessorDirectives(
+ RefPtr<ProgramSyntaxNode> program)
+ {
+ switch(context->shared->target)
+ {
+ // Don't emit this stuff unless we are targetting GLSL
+ default:
+ return;
- Emit("#version 420\n");
+ case CodeGenTarget::GLSL:
+ break;
}
+ emitGLSLVersionDirective(program);
+
+
// TODO: when cross-compiling we may need to output additional `#extension` directives
// based on the features that we have used.
@@ -3489,6 +3532,7 @@ String emitEntryPoint(
SharedEmitContext sharedContext;
sharedContext.target = target;
sharedContext.finalTarget = entryPoint->compileRequest->Target;
+ sharedContext.entryPoint = entryPoint;
sharedContext.programLayout = programLayout;