summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTim Foley <tfoleyNV@users.noreply.github.com>2018-11-29 07:48:23 -0800
committerGitHub <noreply@github.com>2018-11-29 07:48:23 -0800
commitc3c34bf4ca78caff285fbf5f24c5f355ca040bd1 (patch)
tree459e8a3b65fed29f597aa8a68e70f0b3e991cf54
parent7f0ccc5580faa43c2554d9d016c27ebe069362c5 (diff)
Add support for globallycoherent modifier (#732)
The `globallycoherent` modifier indicates that resource might be read or written by threads outside of the current thread group, so that any memory barriers that affect it should guarantee coherency at the global memory scope, and not just thread-group scope. The equivalent GLSL modifier appears to be `coherent`. This change adds the front-end modifier, transforms it into an IR-level decoration during lowering, and then checks for the modifier during code emit. Note: this logic may not behave correctly when `globallycoherent` is added to a field in a `struct`, since the modifier would then need to be propagated to any variables created during type legalization. Checking up on that is left to future work. Note: it isn't entirely clear if `globallycoherent` should be treated as a declaration modifier or a type modifier. The point is moot for now because Slang doesn't have any support for type modifiers, but when we get around to that we will need to make a decision.
-rw-r--r--source/slang/core.meta.slang4
-rw-r--r--source/slang/core.meta.slang.h4
-rw-r--r--source/slang/emit.cpp17
-rw-r--r--source/slang/ir-insts.h5
-rw-r--r--source/slang/ir-serialize.cpp7
-rw-r--r--source/slang/ir.cpp10
-rw-r--r--source/slang/ir.h1
-rw-r--r--source/slang/lower-to-ir.cpp6
-rw-r--r--source/slang/modifier-defs.h1
-rw-r--r--tests/hlsl/simple/globallycoherent.hlsl20
10 files changed, 75 insertions, 0 deletions
diff --git a/source/slang/core.meta.slang b/source/slang/core.meta.slang
index 14254e99e..2ebc3e126 100644
--- a/source/slang/core.meta.slang
+++ b/source/slang/core.meta.slang
@@ -13,6 +13,10 @@ typedef uint uint32_t;
// as part of translation.
syntax constexpr : ConstExprModifier;
+// Modifier for variables that should have writes be made
+// visible at the global-memory scope
+syntax globallycoherent : GloballyCoherentModifier;
+
// A type that can be used as an operand for builtins
interface __BuiltinType {}
diff --git a/source/slang/core.meta.slang.h b/source/slang/core.meta.slang.h
index 9a2033384..b32d9454c 100644
--- a/source/slang/core.meta.slang.h
+++ b/source/slang/core.meta.slang.h
@@ -13,6 +13,10 @@ SLANG_RAW("// Modifier for variables that must resolve to compile-time constants
SLANG_RAW("// as part of translation.\n")
SLANG_RAW("syntax constexpr : ConstExprModifier;\n")
SLANG_RAW("\n")
+SLANG_RAW("// Modifier for variables that should have writes be made\n")
+SLANG_RAW("// visible at the global-memory scope\n")
+SLANG_RAW("syntax globallycoherent : GloballyCoherentModifier;\n")
+SLANG_RAW("\n")
SLANG_RAW("// A type that can be used as an operand for builtins\n")
SLANG_RAW("interface __BuiltinType {}\n")
SLANG_RAW("\n")
diff --git a/source/slang/emit.cpp b/source/slang/emit.cpp
index bf98a1b24..187ef29bc 100644
--- a/source/slang/emit.cpp
+++ b/source/slang/emit.cpp
@@ -5426,6 +5426,23 @@ struct EmitVisitor
emit("hitAttributeNV\n");
}
+ if(varDecl->findDecoration<IRGloballyCoherentDecoration>())
+ {
+ switch(getTarget(context))
+ {
+ default:
+ break;
+
+ case CodeGenTarget::HLSL:
+ emit("globallycoherent\n");
+ break;
+
+ case CodeGenTarget::GLSL:
+ emit("coherent\n");
+ break;
+ }
+ }
+
if (!layout)
return;
diff --git a/source/slang/ir-insts.h b/source/slang/ir-insts.h
index fc0c5f884..31bc11ca4 100644
--- a/source/slang/ir-insts.h
+++ b/source/slang/ir-insts.h
@@ -165,6 +165,11 @@ struct IREarlyDepthStencilDecoration : IRDecoration
enum { kDecorationOp = kIRDecorationOp_EarlyDepthStencil };
};
+struct IRGloballyCoherentDecoration : IRDecoration
+{
+ enum { kDecorationOp = kIRDecorationOp_GloballyCoherent };
+};
+
// An instruction that specializes another IR value
// (representing a generic) to a particular set of generic arguments
// (instructions representing types, witness tables, etc.)
diff --git a/source/slang/ir-serialize.cpp b/source/slang/ir-serialize.cpp
index d8a01fb56..03e10c8e2 100644
--- a/source/slang/ir-serialize.cpp
+++ b/source/slang/ir-serialize.cpp
@@ -708,6 +708,7 @@ Result IRSerialWriter::write(IRModule* module, SourceManager* sourceManager, Opt
case kIRDecorationOp_VulkanHitAttributes:
case kIRDecorationOp_EarlyDepthStencil:
case kIRDecorationOp_ReadNone:
+ case kIRDecorationOp_GloballyCoherent:
{
dstInst.m_payloadType = PayloadType::Empty;
break;
@@ -1574,6 +1575,12 @@ IRDecoration* IRSerialReader::_createDecoration(const Ser::Inst& srcInst)
SLANG_ASSERT(srcInst.m_payloadType == PayloadType::Empty);
return decor;
}
+ case kIRDecorationOp_GloballyCoherent:
+ {
+ auto decor = createEmptyDecoration<IRGloballyCoherentDecoration>(m_module);
+ SLANG_ASSERT(srcInst.m_payloadType == PayloadType::Empty);
+ return decor;
+ }
case kIRDecorationOp_VulkanHitAttributes:
{
auto decor = createEmptyDecoration<IRVulkanHitAttributesDecoration>(m_module);
diff --git a/source/slang/ir.cpp b/source/slang/ir.cpp
index 664927e8a..599b02ea7 100644
--- a/source/slang/ir.cpp
+++ b/source/slang/ir.cpp
@@ -2954,6 +2954,11 @@ namespace Slang
dump(context, "\n[earlydepthstencil]");
}
break;
+ case kIRDecorationOp_GloballyCoherent:
+ {
+ dump(context, "\n[globallycoherent]");
+ }
+ break;
}
}
}
@@ -5397,6 +5402,11 @@ namespace Slang
context->builder->addDecoration<IREarlyDepthStencilDecoration>(clonedValue);
}
break;
+ case kIRDecorationOp_GloballyCoherent:
+ {
+ context->builder->addDecoration<IRGloballyCoherentDecoration>(clonedValue);
+ }
+ break;
case kIRDecorationOp_VulkanHitAttributes:
{
context->builder->addDecoration<IRVulkanHitAttributesDecoration>(clonedValue);
diff --git a/source/slang/ir.h b/source/slang/ir.h
index b8c8e85f2..0b75a487f 100644
--- a/source/slang/ir.h
+++ b/source/slang/ir.h
@@ -161,6 +161,7 @@ enum IRDecorationOp : uint16_t
kIRDecorationOp_VulkanCallablePayload,
kIRDecorationOp_EarlyDepthStencil,
+ kIRDecorationOp_GloballyCoherent,
kIRDecorationOp_CountOf
};
diff --git a/source/slang/lower-to-ir.cpp b/source/slang/lower-to-ir.cpp
index 1390cddaf..09f463ab6 100644
--- a/source/slang/lower-to-ir.cpp
+++ b/source/slang/lower-to-ir.cpp
@@ -1268,6 +1268,10 @@ void addVarDecorations(
{
builder->addDecoration<IRVulkanHitAttributesDecoration>(inst);
}
+ else if(mod.As<GloballyCoherentModifier>())
+ {
+ builder->addDecoration<IRGloballyCoherentDecoration>(inst);
+ }
// TODO: what are other modifiers we need to propagate through?
}
@@ -3765,6 +3769,8 @@ struct DeclLoweringVisitor : DeclVisitor<DeclLoweringVisitor, LoweredValInfo>
maybeSetRate(context, irGlobal, decl);
+ addVarDecorations(context, irGlobal, decl);
+
if (decl)
{
builder->addHighLevelDeclDecoration(irGlobal, decl);
diff --git a/source/slang/modifier-defs.h b/source/slang/modifier-defs.h
index 5c86301ad..e8b3f0774 100644
--- a/source/slang/modifier-defs.h
+++ b/source/slang/modifier-defs.h
@@ -23,6 +23,7 @@ SIMPLE_MODIFIER(Prefix);
SIMPLE_MODIFIER(Postfix);
SIMPLE_MODIFIER(Exported);
SIMPLE_MODIFIER(ConstExpr);
+SIMPLE_MODIFIER(GloballyCoherent)
#undef SIMPLE_MODIFIER
diff --git a/tests/hlsl/simple/globallycoherent.hlsl b/tests/hlsl/simple/globallycoherent.hlsl
new file mode 100644
index 000000000..70b5cdb2b
--- /dev/null
+++ b/tests/hlsl/simple/globallycoherent.hlsl
@@ -0,0 +1,20 @@
+//TEST:COMPARE_HLSL:-profile cs_5_0
+
+// Check output for `globallycoherent`
+
+#ifndef __SLANG__
+#define gBuffer gBuffer_0
+#define SV_DispatchThreadID SV_DISPATCHTHREADID
+#endif
+
+globallycoherent
+RWStructuredBuffer<uint> gBuffer : register(u0);
+
+[numthreads(16,1,1)]
+void main(
+ uint tid : SV_DispatchThreadID)
+{
+ uint index = tid;
+
+ gBuffer[index] = gBuffer[index + 1];
+}