summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTim Foley <tfoley@nvidia.com>2017-07-12 14:21:52 -0700
committerTim Foley <tfoley@nvidia.com>2017-07-12 14:21:52 -0700
commit02f77bbf12981abe376b2d5987684224a50ae4b2 (patch)
tree156c36903426a4f18f0e4c857d9d9eb987459789
parentd43ee03c6101ce76331135cebdc57711cb3a2020 (diff)
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.
-rw-r--r--source/slang/emit.cpp30
-rw-r--r--source/slang/modifier-defs.h6
-rw-r--r--source/slang/parser.cpp11
-rw-r--r--source/slang/slang-stdlib.cpp12
4 files changed, 59 insertions, 0 deletions
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<String> 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<InvokeExpressionSyntaxNode> 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<RequiredGLSLExtensionModifier>())
+ {
+ // 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<T,N,M> ddx(matrix<T,N,M> x);
__generic<T : __BuiltinFloatingPointType>
+__glsl_extension(GL_ARB_derivative_control)
__intrinsic(glsl, dFdxCoarse)
__intrinsic
T ddx_coarse(T x);
__generic<T : __BuiltinFloatingPointType, let N : int>
+__glsl_extension(GL_ARB_derivative_control)
__intrinsic(glsl, dFdxCoarse)
__intrinsic
vector<T,N> ddx_coarse(vector<T,N> x);
__generic<T : __BuiltinFloatingPointType, let N : int, let M : int>
+__glsl_extension(GL_ARB_derivative_control)
__intrinsic(glsl, dFdxCoarse)
__intrinsic
matrix<T,N,M> ddx_coarse(matrix<T,N,M> x);
__generic<T : __BuiltinFloatingPointType>
+__glsl_extension(GL_ARB_derivative_control)
__intrinsic(glsl, dFdxFine)
__intrinsic
T ddx_fine(T x);
__generic<T : __BuiltinFloatingPointType, let N : int>
+__glsl_extension(GL_ARB_derivative_control)
__intrinsic(glsl, dFdxFine)
__intrinsic
vector<T,N> ddx_fine(vector<T,N> x);
__generic<T : __BuiltinFloatingPointType, let N : int, let M : int>
+__glsl_extension(GL_ARB_derivative_control)
__intrinsic(glsl, dFdxFine)
__intrinsic
matrix<T,N,M> ddx_fine(matrix<T,N,M> x);
@@ -452,27 +458,33 @@ __intrinsic
matrix<T,N,M> ddy(matrix<T,N,M> x);
__generic<T : __BuiltinFloatingPointType>
+__glsl_extension(GL_ARB_derivative_control)
__intrinsic(glsl, dFdyCoarse)
__intrinsic
T ddy_coarse(T x);
__generic<T : __BuiltinFloatingPointType, let N : int>
+__glsl_extension(GL_ARB_derivative_control)
__intrinsic(glsl, dFdyCoarse)
__intrinsic
vector<T,N> ddy_coarse(vector<T,N> x);
__generic<T : __BuiltinFloatingPointType, let N : int, let M : int>
+__glsl_extension(GL_ARB_derivative_control)
__intrinsic(glsl, dFdyCoarse)
__intrinsic
matrix<T,N,M> ddy_coarse(matrix<T,N,M> x);
__generic<T : __BuiltinFloatingPointType>
+__glsl_extension(GL_ARB_derivative_control)
__intrinsic(glsl, dFdyFine)
__intrinsic
T ddy_fine(T x);
__generic<T : __BuiltinFloatingPointType, let N : int>
+__glsl_extension(GL_ARB_derivative_control)
__intrinsic(glsl, dFdyFine)
__intrinsic
vector<T,N> ddy_fine(vector<T,N> x);
__generic<T : __BuiltinFloatingPointType, let N : int, let M : int>
+__glsl_extension(GL_ARB_derivative_control)
__intrinsic(glsl, dFdyFine)
__intrinsic
matrix<T,N,M> ddy_fine(matrix<T,N,M> x);