diff options
| author | Tim Foley <tfoleyNV@users.noreply.github.com> | 2017-07-13 09:54:47 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2017-07-13 09:54:47 -0700 |
| commit | c963b44aa48a4349e20a0afcd423b55b1996d2fa (patch) | |
| tree | 88f7f0b51d679cc308437461b8c210e828efeda0 /source/slang | |
| parent | 9058358792fa393e0e92af80f24a54a037aa9691 (diff) | |
| parent | c51fd4ee8f478aa3d3b7e6208a3a4e9c00e2413a (diff) | |
Merge pull request #85 from tfoleyNV/working
Various bug fixes
Diffstat (limited to 'source/slang')
| -rw-r--r-- | source/slang/compiler.cpp | 2 | ||||
| -rw-r--r-- | source/slang/emit.cpp | 102 | ||||
| -rw-r--r-- | source/slang/profile-defs.h | 100 | ||||
| -rw-r--r-- | source/slang/profile.h | 1 | ||||
| -rw-r--r-- | source/slang/slang-stdlib.cpp | 41 | ||||
| -rw-r--r-- | source/slang/slang.cpp | 25 |
6 files changed, 230 insertions, 41 deletions
diff --git a/source/slang/compiler.cpp b/source/slang/compiler.cpp index 284bb200a..4c3885ebf 100644 --- a/source/slang/compiler.cpp +++ b/source/slang/compiler.cpp @@ -72,7 +72,7 @@ namespace Slang Profile Profile::LookUp(char const* name) { #define PROFILE(TAG, NAME, STAGE, VERSION) if(strcmp(name, #NAME) == 0) return Profile::TAG; - #define PROFILE_ALIAS(TAG, NAME) if(strcmp(name, #NAME) == 0) return Profile::TAG; + #define PROFILE_ALIAS(TAG, DEF, NAME) if(strcmp(name, #NAME) == 0) return Profile::TAG; #include "profile-defs.h" return Profile::Unknown; diff --git a/source/slang/emit.cpp b/source/slang/emit.cpp index 6905a8a76..21c91a5c0 100644 --- a/source/slang/emit.cpp +++ b/source/slang/emit.cpp @@ -18,9 +18,17 @@ 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; + // The final code generation target + // + // For example, `target` might be `GLSL`, while `finalTarget` might be `SPIRV` + CodeGenTarget finalTarget; + // The string of code we've built so far StringBuilder sb; @@ -456,13 +464,17 @@ struct EmitVisitor bool shouldUseGLSLStyleLineDirective = false; - // Let's not do this -#if 0 - if (context->shared->target == CodeGenTarget::GLSL) + // TODO: Eventually we should give he user a proper API + // and command-line mechanism to control what kind of line + // directives we output (and to turn the feature off + // completely), but for now we always emit C-style line + // directives *unless* the final target language is raw + // GLSL code (all other targets will eventually pass + // through glslang, which supports C-style line directives). + if (context->shared->finalTarget == CodeGenTarget::GLSL) { shouldUseGLSLStyleLineDirective = true; } -#endif if(shouldUseGLSLStyleLineDirective) { @@ -3387,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... @@ -3412,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 - Emit("#version 420\n"); + 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; + + 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. @@ -3479,6 +3531,8 @@ String emitEntryPoint( SharedEmitContext sharedContext; sharedContext.target = target; + sharedContext.finalTarget = entryPoint->compileRequest->Target; + sharedContext.entryPoint = entryPoint; sharedContext.programLayout = programLayout; diff --git a/source/slang/profile-defs.h b/source/slang/profile-defs.h index 76ba476bb..84153ee46 100644 --- a/source/slang/profile-defs.h +++ b/source/slang/profile-defs.h @@ -32,7 +32,7 @@ #endif #ifndef PROFILE_ALIAS -#define PROFILE_ALIAS(TAG, NAME) /* empty */ +#define PROFILE_ALIAS(TAG, DEF, NAME) /* empty */ #endif // Source and destination languages @@ -78,7 +78,18 @@ PROFILE_VERSION(DX_4_0_Level_9_3, DX) PROFILE_VERSION(DX_4_1, DX) PROFILE_VERSION(DX_5_0, DX) -PROFILE_VERSION(GLSL, GLSL) +PROFILE_VERSION(GLSL_110, GLSL) +PROFILE_VERSION(GLSL_120, GLSL) +PROFILE_VERSION(GLSL_130, GLSL) +PROFILE_VERSION(GLSL_140, GLSL) +PROFILE_VERSION(GLSL_150, GLSL) +PROFILE_VERSION(GLSL_330, GLSL) +PROFILE_VERSION(GLSL_400, GLSL) +PROFILE_VERSION(GLSL_410, GLSL) +PROFILE_VERSION(GLSL_420, GLSL) +PROFILE_VERSION(GLSL_430, GLSL) +PROFILE_VERSION(GLSL_440, GLSL) +PROFILE_VERSION(GLSL_450, GLSL) // Specific profiles @@ -104,14 +115,83 @@ PROFILE(DX_Vertex_4_0_Level_9_3, vs_4_0_level_9_3, Vertex, DX_4_0_Level_9_3) PROFILE(DX_Vertex_4_1, vs_4_1, Vertex, DX_4_1) PROFILE(DX_Vertex_5_0, vs_5_0, Vertex, DX_5_0) -// - -PROFILE(GLSL_Compute, glsl_compute, Compute, GLSL) -PROFILE(GLSL_Vertex, glsl_vertex, Vertex, GLSL) -PROFILE(GLSL_Fragment, glsl_fragment, Fragment, GLSL) -PROFILE(GLSL_Geometry, glsl_geometry, Geometry, GLSL) -PROFILE(GLSL_TessControl, glsl_tess_control, Hull, GLSL) -PROFILE(GLSL_TessEval, glsl_tess_eval, Domain, GLSL) +// Define all the GLSL profiles + +#define P(UPPER, LOWER, VERSION) \ +PROFILE(GLSL_##UPPER##_##VERSION, glsl_##LOWER##_##VERSION, UPPER, GLSL_##VERSION) + +P(Vertex, vertex, 110) +P(Vertex, vertex, 120) +P(Vertex, vertex, 130) +P(Vertex, vertex, 140) +P(Vertex, vertex, 150) +P(Vertex, vertex, 330) +P(Vertex, vertex, 400) +P(Vertex, vertex, 410) +P(Vertex, vertex, 420) +P(Vertex, vertex, 430) +P(Vertex, vertex, 440) +P(Vertex, vertex, 450) + +P(Fragment, fragment, 110) +P(Fragment, fragment, 120) +P(Fragment, fragment, 130) +P(Fragment, fragment, 140) +P(Fragment, fragment, 150) +P(Fragment, fragment, 330) +P(Fragment, fragment, 400) +P(Fragment, fragment, 410) +P(Fragment, fragment, 420) +P(Fragment, fragment, 430) +P(Fragment, fragment, 440) +P(Fragment, fragment, 450) + +P(Geometry, geometry, 150) +P(Geometry, geometry, 330) +P(Geometry, geometry, 400) +P(Geometry, geometry, 410) +P(Geometry, geometry, 420) +P(Geometry, geometry, 430) +P(Geometry, geometry, 440) +P(Geometry, geometry, 450) + +P(Compute, compute, 430) +P(Compute, compute, 440) +P(Compute, compute, 450) + +#undef P +#define P(UPPER, LOWER, STAGE, VERSION) \ +PROFILE(GLSL_##UPPER##_##VERSION, glsl_##LOWER##_##VERSION, STAGE, GLSL_##VERSION) + +P(TessControl, tess_control, Hull, 400) +P(TessControl, tess_control, Hull, 410) +P(TessControl, tess_control, Hull, 420) +P(TessControl, tess_control, Hull, 430) +P(TessControl, tess_control, Hull, 440) +P(TessControl, tess_control, Hull, 450) + +P(TessEval, tess_eval, Domain, 400) +P(TessEval, tess_eval, Domain, 410) +P(TessEval, tess_eval, Domain, 420) +P(TessEval, tess_eval, Domain, 430) +P(TessEval, tess_eval, Domain, 440) +P(TessEval, tess_eval, Domain, 450) + +#undef P + +// Define a default profile for each GLSL stage that just +// uses the latest language version we know of + +PROFILE_ALIAS(GLSL_Vertex, GLSL_Vertex_450, glsl_vertex) +PROFILE_ALIAS(GLSL_Fragment, GLSL_Fragment_450, glsl_fragment) +PROFILE_ALIAS(GLSL_Geometry, GLSL_Geometry_450, glsl_geometry) +PROFILE_ALIAS(GLSL_TessControl, GLSL_TessControl_450, glsl_tess_control) +PROFILE_ALIAS(GLSL_TessEval, GLSL_TessEval_450, glsl_tess_eval) +PROFILE_ALIAS(GLSL_Compute, GLSL_Compute_450, glsl_compute) + +// TODO: define a profile for each GLSL *version* that we can +// use as a catch-all when the stage can be inferred from +// something else #undef LANGUAGE #undef LANGUAGE_ALIAS diff --git a/source/slang/profile.h b/source/slang/profile.h index f8839be84..6d55d3195 100644 --- a/source/slang/profile.h +++ b/source/slang/profile.h @@ -54,6 +54,7 @@ namespace Slang Unknown, #define PROFILE(TAG, NAME, STAGE, VERSION) TAG = (uint32_t(Stage::STAGE) << 16) | uint32_t(ProfileVersion::VERSION), +#define PROFILE_ALIAS(TAG, DEF, NAME) TAG = DEF, #include "profile-defs.h" }; diff --git a/source/slang/slang-stdlib.cpp b/source/slang/slang-stdlib.cpp index 563f5a015..3450e72d7 100644 --- a/source/slang/slang-stdlib.cpp +++ b/source/slang/slang-stdlib.cpp @@ -2073,13 +2073,46 @@ namespace Slang sb << "__magic_type(GLSLInputAttachmentType) struct subpassInput {};"; // Define additional keywords + sb << "__modifier(GLSLBufferModifier) buffer;\n"; - sb << "__modifier(GLSLWriteOnlyModifier) writeonly;\n"; - sb << "__modifier(GLSLReadOnlyModifier) readonly;\n"; + + // [GLSL 4.3] Storage Qualifiers + + // TODO: need to support `shared` here with its GLSL meaning + sb << "__modifier(GLSLPatchModifier) patch;\n"; + // `centroid` and `sample` handled centrally + + // [GLSL 4.5] Interpolation Qualifiers + sb << "__modifier(SimpleModifier) smooth;\n"; + sb << "__modifier(SimpleModifier) flat;\n"; + sb << "__modifier(SimpleModifier) noperspective;\n"; + + + // [GLSL 4.3.2] Constant Qualifier + + // We need to handle GLSL `const` separately from HLSL `const`, + // since they mean such different things. + + // [GLSL 4.7.2] Precision Qualifiers + sb << "__modifier(SimpleModifier) highp;\n"; + sb << "__modifier(SimpleModifier) mediump;\n"; + sb << "__modifier(SimpleModifier) lowp;\n"; + + // [GLSL 4.8.1] The Invariant Qualifier + + sb << "__modifier(GLSLWriteOnlyModifier) invariant;\n"; + + // [GLSL 4.10] Memory Qualifiers + + sb << "__modifier(SimpleModifier) coherent;\n"; + sb << "__modifier(SimpleModifier) volatile;\n"; + sb << "__modifier(SimpleModifier) restrict;\n"; + sb << "__modifier(GLSLReadOnlyModifier) readonly;\n"; + sb << "__modifier(GLSLWriteOnlyModifier) writeonly;\n"; - sb << "__modifier(SimpleModifier) flat;\n"; - sb << "__modifier(SimpleModifier) highp;\n"; + // We will treat `subroutine` as a qualifier + sb << "__modifier(SimpleModifier) subroutine;\n"; glslLibraryCode = sb.ProduceString(); return glslLibraryCode; diff --git a/source/slang/slang.cpp b/source/slang/slang.cpp index 0561f30a9..bfc499c1b 100644 --- a/source/slang/slang.cpp +++ b/source/slang/slang.cpp @@ -880,8 +880,29 @@ SLANG_API void const* spGetEntryPointCode( { auto req = REQ(request); Slang::CompileResult& result = req->entryPoints[entryPointIndex]->result; - if(outSize) *outSize = result.outputBinary.Count(); - return result.outputBinary.Buffer(); + + void const* data = nullptr; + size_t size = 0; + + switch (result.format) + { + case Slang::ResultFormat::None: + default: + break; + + case Slang::ResultFormat::Binary: + data = result.outputBinary.Buffer(); + size = result.outputBinary.Count(); + break; + + case Slang::ResultFormat::Text: + data = result.outputString.Buffer(); + size = result.outputString.Length(); + break; + } + + if(outSize) *outSize = size; + return data; } // Reflection API |
