From b65861fc32a54d28b3fbbaf0d31bb1d71889f570 Mon Sep 17 00:00:00 2001 From: Tim Foley Date: Wed, 12 Jul 2017 13:32:24 -0700 Subject: Use C-style line directives, even for GLSL - As long as we are always going to pass GLSL through glslang, there should be no harm in this - Eventually we may need to re-enable the old style --- source/slang/emit.cpp | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'source/slang/emit.cpp') diff --git a/source/slang/emit.cpp b/source/slang/emit.cpp index 03cc7d8aa..3a5acd024 100644 --- a/source/slang/emit.cpp +++ b/source/slang/emit.cpp @@ -450,7 +450,17 @@ struct EmitVisitor emitRawText(" "); - if(context->shared->target == CodeGenTarget::GLSL) + bool shouldUseGLSLStyleLineDirective = false; + + // Let's not do this +#if 0 + if (context->shared->target == CodeGenTarget::GLSL) + { + shouldUseGLSLStyleLineDirective = true; + } +#endif + + if(shouldUseGLSLStyleLineDirective) { auto path = sourceLocation.FileName; -- cgit v1.2.3 From aca34e771d0ad76d396415e45c5f3cbf294709c9 Mon Sep 17 00:00:00 2001 From: Tim Foley Date: Wed, 12 Jul 2017 13:40:30 -0700 Subject: Don't emit interpolation modifiers on struct fields when outputting GLSL HLSL (and thus Slang) commonly puts interpolation modifiers like `sample` on the fields of `struct` types used as stage input/output, while GLSL only allows them on global-scope `in` and `out` variables (or ones in blocks). This change emits a really hacky filtering step to skip over certain modifiers when emitting a declaration. This lets us skip interpolation-mode modifiers when outputting a struct field to GLSL. Note: this probably gets the `in` or `out` block case wrong... --- source/slang/emit.cpp | 32 ++++++++++++++++++++++++++++++++ source/slang/modifier-defs.h | 11 +++++++---- 2 files changed, 39 insertions(+), 4 deletions(-) (limited to 'source/slang/emit.cpp') diff --git a/source/slang/emit.cpp b/source/slang/emit.cpp index 3a5acd024..f5b4a8b56 100644 --- a/source/slang/emit.cpp +++ b/source/slang/emit.cpp @@ -2556,6 +2556,35 @@ struct EmitVisitor Emit(";\n"); } + bool shouldSkipModifierForDecl( + Modifier* modifier, + Decl* decl) + { + switch(context->shared->target) + { + default: + break; + + case CodeGenTarget::GLSL: + { + // Don't emit interpolation mode modifiers on `struct` fields + // (only allowed on global or block `in`/`out`) + if (auto interpolationMod = dynamic_cast(modifier)) + { + if (auto fieldDecl = dynamic_cast(decl)) + { + return true; + } + } + + } + break; + } + + + return false; + } + // Emit any modifiers that should go in front of a declaration void EmitModifiers(RefPtr decl) { @@ -2587,6 +2616,9 @@ struct EmitVisitor for (auto mod = decl->modifiers.first; mod; mod = mod->next) { + if (shouldSkipModifierForDecl(mod, decl)) + continue; + advanceToSourceLocation(mod->Position); if (0) {} diff --git a/source/slang/modifier-defs.h b/source/slang/modifier-defs.h index c401b3353..2b5c77d86 100644 --- a/source/slang/modifier-defs.h +++ b/source/slang/modifier-defs.h @@ -208,17 +208,20 @@ SIMPLE_SYNTAX_CLASS(GLSLColumnMajorLayoutModifier, RowMajorLayoutModifier) // More HLSL Keyword +ABSTRACT_SYNTAX_CLASS(InterpolationModeModifier, Modifier) +END_SYNTAX_CLASS() + // HLSL `nointerpolation` modifier -SIMPLE_SYNTAX_CLASS(HLSLNoInterpolationModifier, Modifier) +SIMPLE_SYNTAX_CLASS(HLSLNoInterpolationModifier, InterpolationModeModifier) // HLSL `linear` modifier -SIMPLE_SYNTAX_CLASS(HLSLLinearModifier, Modifier) +SIMPLE_SYNTAX_CLASS(HLSLLinearModifier, InterpolationModeModifier) // HLSL `sample` modifier -SIMPLE_SYNTAX_CLASS(HLSLSampleModifier, Modifier) +SIMPLE_SYNTAX_CLASS(HLSLSampleModifier, InterpolationModeModifier) // HLSL `centroid` modifier -SIMPLE_SYNTAX_CLASS(HLSLCentroidModifier, Modifier) +SIMPLE_SYNTAX_CLASS(HLSLCentroidModifier, InterpolationModeModifier) // HLSL `precise` modifier SIMPLE_SYNTAX_CLASS(HLSLPreciseModifier, Modifier) -- cgit v1.2.3 From 02f77bbf12981abe376b2d5987684224a50ae4b2 Mon Sep 17 00:00:00 2001 From: Tim Foley Date: Wed, 12 Jul 2017 14:21:52 -0700 Subject: Add ability for intrinsics to require GLSL extensions When cross-compiling, we need to detect when an intrinsic is used that required non-default GLSL capabilities and emit an appropriate `#extension ... : require` line. I'm handling this by attaching a custom modifier to declarations that require an extension in order to be callable. --- source/slang/emit.cpp | 30 ++++++++++++++++++++++++++++++ source/slang/modifier-defs.h | 6 ++++++ source/slang/parser.cpp | 11 +++++++++++ source/slang/slang-stdlib.cpp | 12 ++++++++++++ 4 files changed, 59 insertions(+) (limited to 'source/slang/emit.cpp') diff --git a/source/slang/emit.cpp b/source/slang/emit.cpp index f5b4a8b56..6905a8a76 100644 --- a/source/slang/emit.cpp +++ b/source/slang/emit.cpp @@ -52,6 +52,10 @@ struct SharedEmitContext ProgramSyntaxNode* program; bool needHackSamplerForTexelFetch = false; + + // Record the GLSL extnsions we have already emitted a `#extension` for + HashSet glslExtensionsRequired; + StringBuilder glslExtensionRequireLines; }; struct EmitContext @@ -1594,6 +1598,19 @@ struct EmitVisitor } } + void requireGLSLExtension(String const& name) + { + if (context->shared->glslExtensionsRequired.Contains(name)) + return; + + StringBuilder& sb = context->shared->glslExtensionRequireLines; + + sb.append("#extension "); + sb.append(name); + sb.append(" : require\n"); + + context->shared->glslExtensionsRequired.Add(name); + } void visitInvokeExpressionSyntaxNode( RefPtr callExpr, @@ -1708,6 +1725,17 @@ struct EmitVisitor } else if(auto targetIntrinsicModifier = findTargetIntrinsicModifier(funcDecl)) { + if (context->shared->target == CodeGenTarget::GLSL) + { + // Does this intrinsic requie a particular GLSL extension that wouldn't be available by default? + if (auto requiredGLSLExtensionModifier = funcDecl->FindModifier()) + { + // If so, we had better request the extension. + requireGLSLExtension(requiredGLSLExtensionModifier->extensionNameToken.Content); + } + } + + if(targetIntrinsicModifier->definitionToken.Type != TokenType::Unknown) { auto name = getStringOrIdentifierTokenValue(targetIntrinsicModifier->definitionToken); @@ -3550,6 +3578,8 @@ String emitEntryPoint( StringBuilder finalResultBuilder; finalResultBuilder << prefix; + finalResultBuilder << sharedContext.glslExtensionRequireLines.ProduceString(); + if (sharedContext.needHackSamplerForTexelFetch) { finalResultBuilder << "layout(set = 0, binding = 0) uniform sampler SLANG_hack_samplerForTexelFetch;\n"; diff --git a/source/slang/modifier-defs.h b/source/slang/modifier-defs.h index 2b5c77d86..9806a12a5 100644 --- a/source/slang/modifier-defs.h +++ b/source/slang/modifier-defs.h @@ -53,6 +53,12 @@ SYNTAX_CLASS(TargetIntrinsicModifier, IntrinsicModifierBase) FIELD(Token, definitionToken) END_SYNTAX_CLASS() +// A modifier to tag something as an intrinsic that requires +// a certain GLSL extension to be enabled when used +SYNTAX_CLASS(RequiredGLSLExtensionModifier, Modifier) + FIELD(Token, extensionNameToken) +END_SYNTAX_CLASS() + SIMPLE_SYNTAX_CLASS(InOutModifier, OutModifier) // This is a special sentinel modifier that gets added diff --git a/source/slang/parser.cpp b/source/slang/parser.cpp index de63793b1..8314b0930 100644 --- a/source/slang/parser.cpp +++ b/source/slang/parser.cpp @@ -717,6 +717,17 @@ namespace Slang AddModifier(&modifierLink, modifier); } + else if (AdvanceIf(parser, "__glsl_extension")) + { + auto modifier = new RequiredGLSLExtensionModifier(); + modifier->Position = loc; + + parser->ReadToken(TokenType::LParent); + modifier->extensionNameToken = parser->ReadToken(TokenType::Identifier); + parser->ReadToken(TokenType::RParent); + + AddModifier(&modifierLink, modifier); + } else if (AdvanceIf(parser, "layout")) { diff --git a/source/slang/slang-stdlib.cpp b/source/slang/slang-stdlib.cpp index bcc87b201..563f5a015 100644 --- a/source/slang/slang-stdlib.cpp +++ b/source/slang/slang-stdlib.cpp @@ -413,27 +413,33 @@ __intrinsic matrix ddx(matrix x); __generic +__glsl_extension(GL_ARB_derivative_control) __intrinsic(glsl, dFdxCoarse) __intrinsic T ddx_coarse(T x); __generic +__glsl_extension(GL_ARB_derivative_control) __intrinsic(glsl, dFdxCoarse) __intrinsic vector ddx_coarse(vector x); __generic +__glsl_extension(GL_ARB_derivative_control) __intrinsic(glsl, dFdxCoarse) __intrinsic matrix ddx_coarse(matrix x); __generic +__glsl_extension(GL_ARB_derivative_control) __intrinsic(glsl, dFdxFine) __intrinsic T ddx_fine(T x); __generic +__glsl_extension(GL_ARB_derivative_control) __intrinsic(glsl, dFdxFine) __intrinsic vector ddx_fine(vector x); __generic +__glsl_extension(GL_ARB_derivative_control) __intrinsic(glsl, dFdxFine) __intrinsic matrix ddx_fine(matrix x); @@ -452,27 +458,33 @@ __intrinsic matrix ddy(matrix x); __generic +__glsl_extension(GL_ARB_derivative_control) __intrinsic(glsl, dFdyCoarse) __intrinsic T ddy_coarse(T x); __generic +__glsl_extension(GL_ARB_derivative_control) __intrinsic(glsl, dFdyCoarse) __intrinsic vector ddy_coarse(vector x); __generic +__glsl_extension(GL_ARB_derivative_control) __intrinsic(glsl, dFdyCoarse) __intrinsic matrix ddy_coarse(matrix x); __generic +__glsl_extension(GL_ARB_derivative_control) __intrinsic(glsl, dFdyFine) __intrinsic T ddy_fine(T x); __generic +__glsl_extension(GL_ARB_derivative_control) __intrinsic(glsl, dFdyFine) __intrinsic vector ddy_fine(vector x); __generic +__glsl_extension(GL_ARB_derivative_control) __intrinsic(glsl, dFdyFine) __intrinsic matrix ddy_fine(matrix x); -- cgit v1.2.3