diff options
| author | Tim Foley <tfoleyNV@users.noreply.github.com> | 2018-12-12 10:15:33 -0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2018-12-12 10:15:33 -0800 |
| commit | 24c34cbeaa9d6a44caf7abba4a1a8e196002df1b (patch) | |
| tree | 69daa997dfab553dba15f112ab5eb04cd9a27a27 | |
| parent | 49ed6b60d662906f290578f802f80b0ead1a2b9d (diff) | |
Make shader parameters not writable (#750)
There was already logic in place to make `const` variables not be writable, and this change extends it to also consider global shader parameters (in HLSL, any global variable that is *not* marked `static` or `groupshared`) to be rvalues instead of lvalues.
As noted in the comments on this change, we could lift that restriction later on, if we have good handling of global variables with resource types in the back-end, but for now it is safer to just rule this out in the front-end.
| -rw-r--r-- | source/slang/check.cpp | 45 |
1 files changed, 34 insertions, 11 deletions
diff --git a/source/slang/check.cpp b/source/slang/check.cpp index 4f914ee1f..38a79f1b7 100644 --- a/source/slang/check.cpp +++ b/source/slang/check.cpp @@ -78,6 +78,28 @@ namespace Slang return isEffectivelyStatic(decl, parentDecl); } + /// Is `decl` a global shader parameter declaration? + bool isGlobalShaderParameter(VarDeclBase* decl) + { + // A global shader parameter must be declared at global (module) scope. + // + if(!dynamic_cast<ModuleDecl*>(decl->ParentDecl)) return false; + + // A global variable marked `static` indicates a traditional + // global variable (albeit one that is implicitly local to + // the translation unit) + // + if(decl->HasModifier<HLSLStaticModifier>()) return false; + + // The `groupshared` modifier indicates that a variable cannot + // be a shader parameters, but is instead transient storage + // allocated for the duration of a thread-group's execution. + // + if(decl->HasModifier<HLSLGroupSharedModifier>()) return false; + + return true; + } + // A flat representation of basic types (scalars, vectors and matrices) // that can be used as lookup key in caches struct BasicTypeKey @@ -4218,17 +4240,6 @@ namespace Slang if (function || checkingPhase == CheckingPhase::Header) { TypeExp typeExp = CheckUsableType(varDecl->type); -#if 0 - if (typeExp.type->GetBindableResourceType() != BindableResourceType::NonBindable) - { - // We don't want to allow bindable resource types as local variables (at least for now). - auto parentDecl = varDecl->ParentDecl; - if (auto parentScopeDecl = dynamic_cast<ScopeDecl*>(parentDecl)) - { - getSink()->diagnose(varDecl->type, Diagnostics::invalidTypeForLocalVariable); - } - } -#endif varDecl->type = typeExp; if (varDecl->type.Equals(getSession()->getVoidType())) { @@ -9015,6 +9026,18 @@ namespace Slang if(varDeclRef.getDecl()->FindModifier<ConstModifier>()) isLValue = false; + // Global-scope shader parameters should not be writable, + // since they are effectively program inputs. + // + // TODO: We could eventually treat a mutable global shader + // parameter as a shorthand for an immutable parameter and + // a global variable that gets initialized from that parameter, + // but in order to do so we'd need to support global variables + // with resource types better in the back-end. + // + if(isGlobalShaderParameter(varDeclRef.getDecl())) + isLValue = false; + qualType.IsLeftValue = isLValue; return qualType; } |
