summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYong He <yonghe@outlook.com>2024-03-13 18:35:42 -0700
committerGitHub <noreply@github.com>2024-03-13 18:35:42 -0700
commite4b01c4ba53c40ff0704e72615422e5a96f636e3 (patch)
treee339f84d7dba74d26e22cde9a296d8cd78d24bb7
parent25df6b868c2af58435bbd09d89e64d77bea87bc7 (diff)
Fix side effect checking around storage buffer type. (#3762)
-rw-r--r--source/slang/glsl.meta.slang34
-rw-r--r--source/slang/slang-check-decl.cpp2
-rw-r--r--source/slang/slang-check-shader.cpp2
-rw-r--r--source/slang/slang-ir-propagate-func-properties.cpp31
-rw-r--r--source/slang/slang-ir-util.cpp6
-rw-r--r--tests/glsl/storage-buffer-side-effect.slang24
6 files changed, 96 insertions, 3 deletions
diff --git a/source/slang/glsl.meta.slang b/source/slang/glsl.meta.slang
index d07233583..98b7fcd82 100644
--- a/source/slang/glsl.meta.slang
+++ b/source/slang/glsl.meta.slang
@@ -107,6 +107,40 @@ public in uvec3 gl_WorkGroupID : SV_GroupID;
public in uvec3 gl_LocalInvocationIndex : SV_GroupIndex;
public in uvec3 gl_LocalInvocationID : SV_GroupThreadID;
+[require(glsl)]
+[require(spirv)]
+public property uint3 gl_NumWorkGroups {
+
+ get {
+ __target_switch
+ {
+ case glsl:
+ __intrinsic_asm "(gl_NumWorkGroups)";
+ case spirv:
+ return spirv_asm {
+ result:$$uint3 = OpLoad builtin(NumWorkgroups:uint3);
+ };
+ }
+ }
+}
+
+[require(glsl)]
+[require(spirv)]
+public property uint3 gl_WorkGroupSize {
+
+ get {
+ __target_switch
+ {
+ case glsl:
+ __intrinsic_asm "(gl_WorkGroupSize)";
+ case spirv:
+ return spirv_asm {
+ result:$$uint3 = OpLoad builtin(WorkgroupSize:uint3);
+ };
+ }
+ }
+}
+
// TODO: define overload for tessellation control stage.
public in int gl_InvocationID : SV_GSInstanceID;
diff --git a/source/slang/slang-check-decl.cpp b/source/slang/slang-check-decl.cpp
index 3a11bd8ad..c08e8f7ef 100644
--- a/source/slang/slang-check-decl.cpp
+++ b/source/slang/slang-check-decl.cpp
@@ -1755,7 +1755,7 @@ namespace Slang
!varDecl->findModifier<OutModifier>() &&
!varDecl->findModifier<GLSLBufferModifier>())
{
- if (!as<ResourceType>(varDecl->type) && !as<PointerLikeType>(varDecl->type))
+ if (!isUniformParameterType(varDecl->type))
{
auto staticModifier = m_astBuilder->create<HLSLStaticModifier>();
addModifier(varDecl, staticModifier);
diff --git a/source/slang/slang-check-shader.cpp b/source/slang/slang-check-shader.cpp
index 731619908..dc466e40c 100644
--- a/source/slang/slang-check-shader.cpp
+++ b/source/slang/slang-check-shader.cpp
@@ -318,6 +318,8 @@ namespace Slang
return true;
if (as<UniformParameterGroupType>(type))
return true;
+ if (as< GLSLShaderStorageBufferType>(type))
+ return true;
if (as<SamplerStateType>(type))
return true;
return false;
diff --git a/source/slang/slang-ir-propagate-func-properties.cpp b/source/slang/slang-ir-propagate-func-properties.cpp
index f186a3a57..c5e8712f1 100644
--- a/source/slang/slang-ir-propagate-func-properties.cpp
+++ b/source/slang/slang-ir-propagate-func-properties.cpp
@@ -11,6 +11,7 @@ class FuncPropertyPropagationContext
{
public:
virtual bool canProcess(IRFunc* f) = 0;
+ virtual bool isInitialFunc(IRFunc* f) = 0;
virtual bool propagate(IRBuilder& builder, IRFunc* func) = 0;
};
@@ -53,6 +54,19 @@ static bool isKnownOpCodeWithSideEffect(IROp op)
class ReadNoneFuncPropertyPropagationContext : public FuncPropertyPropagationContext
{
public:
+ virtual bool isInitialFunc(IRFunc* f) override
+ {
+ // If the func has already been marked with any decorations, skip.
+ for (auto decoration : f->getDecorations())
+ {
+ switch (decoration->getOp())
+ {
+ case kIROp_ReadNoneDecoration:
+ return true;
+ }
+ }
+ return false;
+ }
virtual bool canProcess(IRFunc* f) override
{
// If the func has already been marked with any decorations, skip.
@@ -193,7 +207,7 @@ bool propagateFuncPropertiesImpl(IRModule* module, FuncPropertyPropagationContex
}
if (auto func = as<IRFunc>(inst))
{
- if (context->canProcess(func))
+ if (context->isInitialFunc(func))
{
addCallersToWorkList(func);
}
@@ -257,7 +271,20 @@ public:
}
return true;
}
-
+ virtual bool isInitialFunc(IRFunc* f) override
+ {
+ // If the func has already been marked with any decorations, skip.
+ for (auto decoration : f->getDecorations())
+ {
+ switch (decoration->getOp())
+ {
+ case kIROp_ReadNoneDecoration:
+ case kIROp_NoSideEffectDecoration:
+ return true;
+ }
+ }
+ return false;
+ }
virtual bool propagate(IRBuilder& builder, IRFunc* f) override
{
bool hasSideEffectCall = false;
diff --git a/source/slang/slang-ir-util.cpp b/source/slang/slang-ir-util.cpp
index 295fbd642..d66c8d0be 100644
--- a/source/slang/slang-ir-util.cpp
+++ b/source/slang/slang-ir-util.cpp
@@ -689,6 +689,7 @@ bool isPtrLikeOrHandleType(IRInst* type)
case kIROp_PtrType:
case kIROp_RefType:
case kIROp_ConstRefType:
+ case kIROp_GLSLShaderStorageBufferType:
return true;
}
return false;
@@ -1175,6 +1176,11 @@ bool isGlobalOrUnknownMutableAddress(IRGlobalValueWithCode* parentFunc, IRInst*
if (root)
{
+ if (as<IRGLSLShaderStorageBufferType>(root->getDataType()))
+ {
+ // A storage buffer is mutable, so we need to treat it as a mutable address.
+ return true;
+ }
// If this is a global readonly resource, it is not a mutable address.
if (as<IRParameterGroupType>(root->getDataType()))
{
diff --git a/tests/glsl/storage-buffer-side-effect.slang b/tests/glsl/storage-buffer-side-effect.slang
new file mode 100644
index 000000000..3209f763e
--- /dev/null
+++ b/tests/glsl/storage-buffer-side-effect.slang
@@ -0,0 +1,24 @@
+//TEST(compute, vulkan):COMPARE_COMPUTE(filecheck-buffer=BUF):-vk -compute -entry computeMain -allow-glsl
+#version 430
+precision highp float;
+precision highp int;
+
+//TEST_INPUT:ubuffer(data=[0], stride=4):out,name=outputBuffer
+
+buffer MyBlockName2
+{
+ uint data[1];
+} outputBuffer;
+
+layout(local_size_x = 4) in;
+
+void sideEffectInit(int val)
+{
+ outputBuffer.data[0] = val;
+}
+void computeMain()
+{
+ outputBuffer.data[0] = 1000;
+ sideEffectInit(4);
+ // BUF: 4
+}