summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTim Foley <tfoleyNV@users.noreply.github.com>2018-12-12 10:15:33 -0800
committerGitHub <noreply@github.com>2018-12-12 10:15:33 -0800
commit24c34cbeaa9d6a44caf7abba4a1a8e196002df1b (patch)
tree69daa997dfab553dba15f112ab5eb04cd9a27a27
parent49ed6b60d662906f290578f802f80b0ead1a2b9d (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.cpp45
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;
}