diff options
| author | Tim Foley <tfoley@nvidia.com> | 2017-07-13 09:12:50 -0700 |
|---|---|---|
| committer | Tim Foley <tfoley@nvidia.com> | 2017-07-13 09:17:27 -0700 |
| commit | 6da80f58ba8f51fc768f177f28a7d818b03c434e (patch) | |
| tree | 7bc2a09c412856951e036622f2b9d3a2742bcd4c /source/slang/emit.cpp | |
| parent | 72a3e97fe6bfdffee253ad008cab7cdd3b9e796f (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.cpp | 84 |
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; |
