diff options
| author | Tim Foley <tfoleyNV@users.noreply.github.com> | 2017-07-17 09:27:34 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2017-07-17 09:27:34 -0700 |
| commit | fdab35e93082d6da4f9dbb4b6ec7b4c6dbce831c (patch) | |
| tree | 489534f470b3d2dcbb61660458bf473e0a2c0552 /source | |
| parent | eecb6c56da5792010e88f2a0d6d1503244b081a4 (diff) | |
| parent | 15aba2fe81fea44969e036e181a4cf252ff41963 (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.cpp | 5 | ||||
| -rw-r--r-- | source/slang/lower.cpp | 99 |
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) |
