diff options
| author | Tim Foley <tfoleyNV@users.noreply.github.com> | 2018-11-29 07:48:23 -0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2018-11-29 07:48:23 -0800 |
| commit | c3c34bf4ca78caff285fbf5f24c5f355ca040bd1 (patch) | |
| tree | 459e8a3b65fed29f597aa8a68e70f0b3e991cf54 | |
| parent | 7f0ccc5580faa43c2554d9d016c27ebe069362c5 (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.slang | 4 | ||||
| -rw-r--r-- | source/slang/core.meta.slang.h | 4 | ||||
| -rw-r--r-- | source/slang/emit.cpp | 17 | ||||
| -rw-r--r-- | source/slang/ir-insts.h | 5 | ||||
| -rw-r--r-- | source/slang/ir-serialize.cpp | 7 | ||||
| -rw-r--r-- | source/slang/ir.cpp | 10 | ||||
| -rw-r--r-- | source/slang/ir.h | 1 | ||||
| -rw-r--r-- | source/slang/lower-to-ir.cpp | 6 | ||||
| -rw-r--r-- | source/slang/modifier-defs.h | 1 | ||||
| -rw-r--r-- | tests/hlsl/simple/globallycoherent.hlsl | 20 |
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]; +} |
