summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--source/slang/check.cpp6
-rw-r--r--source/slang/compiler.cpp16
-rw-r--r--source/slang/diagnostics.cpp30
-rw-r--r--source/slang/diagnostics.h6
-rw-r--r--source/slang/emit.cpp74
-rw-r--r--source/slang/lower.cpp80
-rw-r--r--source/slang/modifier-defs.h17
-rw-r--r--source/slang/parser.cpp11
-rw-r--r--source/slang/slang-stdlib.cpp12
9 files changed, 236 insertions, 16 deletions
diff --git a/source/slang/check.cpp b/source/slang/check.cpp
index b87f7c6bc..b175b7f86 100644
--- a/source/slang/check.cpp
+++ b/source/slang/check.cpp
@@ -2540,7 +2540,11 @@ namespace Slang
if (!type.IsLeftValue)
{
- if (!isRewriteMode())
+ if (type->As<ErrorType>())
+ {
+ // Don't report an l-value issue on an errorneous expression
+ }
+ else if (!isRewriteMode())
{
getSink()->diagnose(expr, Diagnostics::assignNonLValue);
}
diff --git a/source/slang/compiler.cpp b/source/slang/compiler.cpp
index 7df978707..284bb200a 100644
--- a/source/slang/compiler.cpp
+++ b/source/slang/compiler.cpp
@@ -236,15 +236,14 @@ namespace Slang
// TODO(tfoley): need a better policy for how we translate diagnostics
// back into the Slang world (although we should always try to generate
// HLSL that doesn't produce any diagnostics...)
- String diagnostics = (char const*) diagnosticsBlob->GetBufferPointer();
- fprintf(stderr, "%s", diagnostics.begin());
- OutputDebugStringA(diagnostics.begin());
+ entryPoint->compileRequest->mSink.diagnoseRaw(
+ FAILED(hr) ? Severity::Error : Severity::Warning,
+ (char const*) diagnosticsBlob->GetBufferPointer());
diagnosticsBlob->Release();
}
if (FAILED(hr))
{
- // TODO(tfoley): What to do on failure?
- exit(1);
+ return List<uint8_t>();
}
return data;
}
@@ -376,9 +375,10 @@ namespace Slang
if (err)
{
- OutputDebugStringA(diagnosticOutput.Buffer());
- fprintf(stderr, "%s", diagnosticOutput.Buffer());
- exit(1);
+ entryPoint->compileRequest->mSink.diagnoseRaw(
+ Severity::Error,
+ diagnosticOutput.begin());
+ return err;
}
return 0;
diff --git a/source/slang/diagnostics.cpp b/source/slang/diagnostics.cpp
index 0c55a94bd..870e6d172 100644
--- a/source/slang/diagnostics.cpp
+++ b/source/slang/diagnostics.cpp
@@ -194,6 +194,36 @@ void DiagnosticSink::diagnoseImpl(CodePosition const& pos, DiagnosticInfo const&
}
}
+void DiagnosticSink::diagnoseRaw(
+ Severity severity,
+ char const* message)
+{
+ if (severity >= Severity::Error)
+ {
+ errorCount++;
+ }
+
+ // Did the client supply a callback for us to use?
+ if( callback )
+ {
+ // If so, pass the error string along to them
+ callback(message, callbackUserData);
+ }
+ else
+ {
+ // If the user doesn't have a callback, then just
+ // collect our diagnostic messages into a buffer
+ outputBuffer.append(message);
+ }
+
+ if (severity >= Severity::Fatal)
+ {
+ // TODO: figure out a better policy for aborting compilation
+ throw InvalidOperationException();
+ }
+}
+
+
namespace Diagnostics
{
#define DIAGNOSTIC(id, severity, name, messageFormat) const DiagnosticInfo name = { id, Severity::severity, messageFormat };
diff --git a/source/slang/diagnostics.h b/source/slang/diagnostics.h
index 8834f1a6e..6957fc763 100644
--- a/source/slang/diagnostics.h
+++ b/source/slang/diagnostics.h
@@ -185,6 +185,12 @@ namespace Slang
}
void diagnoseImpl(CodePosition const& pos, DiagnosticInfo const& info, int argCount, DiagnosticArg const* const* args);
+
+ // Add a diagnostic with raw text
+ // (used when we get errors from a downstream compiler)
+ void diagnoseRaw(
+ Severity severity,
+ char const* message);
};
namespace Diagnostics
diff --git a/source/slang/emit.cpp b/source/slang/emit.cpp
index 03cc7d8aa..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
@@ -450,7 +454,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;
@@ -1584,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,
@@ -1698,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);
@@ -2546,6 +2584,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<InterpolationModeModifier*>(modifier))
+ {
+ if (auto fieldDecl = dynamic_cast<StructField*>(decl))
+ {
+ return true;
+ }
+ }
+
+ }
+ break;
+ }
+
+
+ return false;
+ }
+
// Emit any modifiers that should go in front of a declaration
void EmitModifiers(RefPtr<Decl> decl)
{
@@ -2577,6 +2644,9 @@ struct EmitVisitor
for (auto mod = decl->modifiers.first; mod; mod = mod->next)
{
+ if (shouldSkipModifierForDecl(mod, decl))
+ continue;
+
advanceToSourceLocation(mod->Position);
if (0) {}
@@ -3508,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/lower.cpp b/source/slang/lower.cpp
index 02da47ccb..c7278201a 100644
--- a/source/slang/lower.cpp
+++ b/source/slang/lower.cpp
@@ -631,6 +631,69 @@ struct LoweringVisitor
return loweredExpr;
}
+ RefPtr<ExpressionSyntaxNode> createAssignExpr(
+ RefPtr<ExpressionSyntaxNode> leftExpr,
+ RefPtr<ExpressionSyntaxNode> rightExpr)
+ {
+ auto leftTuple = leftExpr.As<TupleExpr>();
+ auto rightTuple = rightExpr.As<TupleExpr>();
+ if (leftTuple && rightTuple)
+ {
+ RefPtr<TupleExpr> resultTuple = new TupleExpr();
+ resultTuple->Type = leftExpr->Type;
+
+ if (leftTuple->primaryExpr)
+ {
+ assert(rightTuple->primaryExpr);
+
+ resultTuple->primaryExpr = createAssignExpr(
+ leftTuple->primaryExpr,
+ rightTuple->primaryExpr);
+ }
+
+ auto elementCount = leftTuple->tupleElements.Count();
+ assert(elementCount == rightTuple->tupleElements.Count());
+ for (UInt ee = 0; ee < elementCount; ++ee)
+ {
+ auto leftElement = leftTuple->tupleElements[ee];
+ auto rightElement = rightTuple->tupleElements[ee];
+
+ TupleExpr::Element resultElement;
+
+ resultElement.tupleFieldDeclRef = leftElement.tupleFieldDeclRef;
+ resultElement.expr = createAssignExpr(
+ leftElement.expr,
+ rightElement.expr);
+
+ resultTuple->tupleElements.Add(resultElement);
+ }
+
+ return resultTuple;
+ }
+ else
+ {
+ assert(!leftTuple && !rightTuple);
+ }
+
+
+ RefPtr<AssignExpr> loweredExpr = new AssignExpr();
+ loweredExpr->Type = leftExpr->Type;
+ loweredExpr->left = leftExpr;
+ loweredExpr->right = rightExpr;
+ return loweredExpr;
+ }
+
+ RefPtr<ExpressionSyntaxNode> visitAssignExpr(
+ AssignExpr* expr)
+ {
+ auto leftExpr = lowerExpr(expr->left);
+ auto rightExpr = lowerExpr(expr->right);
+
+ auto loweredExpr = createAssignExpr(leftExpr, rightExpr);
+ lowerExprCommon(loweredExpr, expr);
+ return loweredExpr;
+ }
+
void addArgs(
InvokeExpressionSyntaxNode* callExpr,
RefPtr<ExpressionSyntaxNode> argExpr)
@@ -917,8 +980,21 @@ struct LoweringVisitor
void addExprStmt(
RefPtr<ExpressionSyntaxNode> expr)
{
- // TODO: handle cases where the `expr` cannot be directly
- // represented as a single statement
+ // Desugar tuples in statement position
+ if (auto tupleExpr = expr.As<TupleExpr>())
+ {
+ if (tupleExpr->primaryExpr)
+ {
+ addExprStmt(tupleExpr->primaryExpr);
+ }
+ for (auto ee : tupleExpr->tupleElements)
+ {
+ addExprStmt(ee.expr);
+ }
+ return;
+ }
+
+ // TODO: could also desugar "operator comma" here
RefPtr<ExpressionStatementSyntaxNode> stmt = new ExpressionStatementSyntaxNode();
stmt->Expression = expr;
diff --git a/source/slang/modifier-defs.h b/source/slang/modifier-defs.h
index c401b3353..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
@@ -208,17 +214,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)
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);