summaryrefslogtreecommitdiffstats
path: root/source
diff options
context:
space:
mode:
authorTim Foley <tfoleyNV@users.noreply.github.com>2017-07-17 09:27:34 -0700
committerGitHub <noreply@github.com>2017-07-17 09:27:34 -0700
commitfdab35e93082d6da4f9dbb4b6ec7b4c6dbce831c (patch)
tree489534f470b3d2dcbb61660458bf473e0a2c0552 /source
parenteecb6c56da5792010e88f2a0d6d1503244b081a4 (diff)
parent15aba2fe81fea44969e036e181a4cf252ff41963 (diff)
Merge pull request #106 from tfoleyNV/varying-integer
Handle `flat` interpolation cases in cross compilation
Diffstat (limited to 'source')
-rw-r--r--source/slang/emit.cpp5
-rw-r--r--source/slang/lower.cpp99
2 files changed, 102 insertions, 2 deletions
diff --git a/source/slang/emit.cpp b/source/slang/emit.cpp
index 88b80589a..7ffce2acd 100644
--- a/source/slang/emit.cpp
+++ b/source/slang/emit.cpp
@@ -2667,11 +2667,12 @@ struct EmitVisitor
else if(auto mod_##TYPE = mod.As<TYPE>()) Emit(#KEYWORD " ")
#define CASE2(TYPE, HLSL_NAME, GLSL_NAME) \
- else if(auto mod_##TYPE = mod.As<TYPE>()) Emit((context->shared->target == CodeGenTarget::GLSL) ? GLSL_NAME : HLSL_NAME)
+ else if(auto mod_##TYPE = mod.As<TYPE>()) Emit((context->shared->target == CodeGenTarget::GLSL) ? (#GLSL_NAME " ") : (#HLSL_NAME " "))
CASE(RowMajorLayoutModifier, row_major);
CASE(ColumnMajorLayoutModifier, column_major);
- CASE(HLSLNoInterpolationModifier, nointerpolation);
+
+ CASE2(HLSLNoInterpolationModifier, nointerpolation, flat);
CASE(HLSLPreciseModifier, precise);
CASE(HLSLEffectSharedModifier, shared);
CASE(HLSLGroupSharedModifier, groupshared);
diff --git a/source/slang/lower.cpp b/source/slang/lower.cpp
index caa1ab075..856da9b6c 100644
--- a/source/slang/lower.cpp
+++ b/source/slang/lower.cpp
@@ -7,6 +7,19 @@
namespace Slang
{
+struct CloneVisitor
+ : ModifierVisitor<CloneVisitor, RefPtr<Modifier>>
+{
+#define ABSTRACT_SYNTAX_CLASS(NAME, BASE) /* empty */
+#define SYNTAX_CLASS(NAME, BASE, ...) \
+ RefPtr<NAME> visit ## NAME(NAME* obj) { return new NAME(*obj); }
+
+#include "object-meta-begin.h"
+#include "modifier-defs.h"
+#include "object-meta-end.h"
+
+};
+
//
template<typename V>
@@ -2244,11 +2257,40 @@ struct LoweringVisitor
IntVal* elementCount;
};
+ struct VaryingParameterVarChain
+ {
+ VaryingParameterVarChain* next = nullptr;
+ VarDeclBase* varDecl;
+ };
+
+ template<typename T>
+ T* findModifier(VaryingParameterVarChain* chain)
+ {
+ for (auto c = chain; c; c = c->next)
+ {
+ auto v = c->varDecl;
+ if (auto mod = v->FindModifier<T>())
+ return mod;
+ }
+ return nullptr;
+ }
+
+ RefPtr<Modifier> cloneModifier(Modifier* modifier)
+ {
+ if (!modifier) return nullptr;
+
+ // For now we just do a shallow copy of the modifier
+
+ CloneVisitor visitor;
+ return visitor.dispatch(modifier);
+ }
+
struct VaryingParameterInfo
{
String name;
VaryingParameterDirection direction;
VaryingParameterArraySpec* arraySpecs = nullptr;
+ VaryingParameterVarChain* varChain = nullptr;
};
RefPtr<ExpressionSyntaxNode> createGLSLBuiltinRef(
@@ -2259,6 +2301,33 @@ struct LoweringVisitor
return globalVarRef;
}
+ bool isIntegralType(
+ ExpressionType* type)
+ {
+ if (auto baseType = type->As<BasicExpressionType>())
+ {
+ switch (baseType->BaseType)
+ {
+ default:
+ return false;
+
+ case BaseType::Int:
+ case BaseType::UInt:
+ case BaseType::UInt64:
+ return true;
+ }
+ }
+ else if (auto vecType = type->As<VectorExpressionType>())
+ {
+ return isIntegralType(vecType->elementType);
+ }
+ else if (auto matType = type->As<MatrixExpressionType>())
+ {
+ return isIntegralType(matType->getElementType());
+ }
+
+ return false;
+ }
void lowerSimpleShaderParameterToGLSLGlobal(
VaryingParameterInfo const& info,
@@ -2449,6 +2518,26 @@ struct LoweringVisitor
break;
}
+ // We want to copy certain modifiers from the declaration as given,
+ // over to the newly created global variable. The most important
+ // of these is any interpolation-mode modifier.
+ //
+ // Note that a shader parameter could have been nested inside
+ // a `struct` type, so we will look for interpolation modifiers
+ // starting on the "deepest" field, and working out way out.
+
+ // Look for interpolation mode modifier
+ if (auto interpolationModeModifier = findModifier<InterpolationModeModifier>(info.varChain))
+ {
+ addModifier(globalVarDecl, cloneModifier(interpolationModeModifier));
+ }
+ // Otherwise, check if we need to add one:
+ else if (isIntegralType(varType))
+ {
+ auto mod = new HLSLNoInterpolationModifier();
+ addModifier(globalVarDecl, mod);
+ }
+
RefPtr<VarExpressionSyntaxNode> globalVarRef = new VarExpressionSyntaxNode();
globalVarRef->Position = globalVarDecl->Position;
@@ -2554,8 +2643,13 @@ struct LoweringVisitor
fieldExpr->declRef = fieldDeclRef;
fieldExpr->BaseExpression = varExpr;
+ VaryingParameterVarChain fieldVarChain;
+ fieldVarChain.next = info.varChain;
+ fieldVarChain.varDecl = fieldDeclRef.getDecl();
+
VaryingParameterInfo fieldInfo = info;
fieldInfo.name = info.name + "_" + fieldDeclRef.GetName();
+ fieldInfo.varChain = &fieldVarChain;
// Need to find the layout for the given field...
Decl* originalFieldDecl = nullptr;
@@ -2598,9 +2692,14 @@ struct LoweringVisitor
expr->declRef = declRef;
expr->Type.type = GetType(declRef);
+ VaryingParameterVarChain varChain;
+ varChain.next = nullptr;
+ varChain.varDecl = localVarDecl;
+
VaryingParameterInfo info;
info.name = name;
info.direction = direction;
+ info.varChain = &varChain;
// Ensure that we don't get name collisions on `inout` variables
switch (direction)