summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEvan Tang <etang@codeweavers.com>2023-05-17 16:50:41 -0500
committerEvan Tang <etang@codeweavers.com>2023-08-15 11:32:33 -0500
commit4405dd6b284c3c27e165be8f44b173b67db10f03 (patch)
tree32d0eae953ff69e20fe72515faf0dc5984074456
parentbccaa94db814af33d8ef05c153e7c34d8bd4d685 (diff)
downloadSPIRV-Cross-4405dd6b284c3c27e165be8f44b173b67db10f03.tar.gz
SPIRV-Cross-4405dd6b284c3c27e165be8f44b173b67db10f03.tar.bz2
SPIRV-Cross-4405dd6b284c3c27e165be8f44b173b67db10f03.zip
MSL: Prevent RAW hazards on read_write textures
-rw-r--r--reference/opt/shaders-msl/asm/comp/image-load-store-short-vector.invalid.asm.comp1
-rw-r--r--reference/opt/shaders-msl/desktop-only/frag/image-ms.desktop.frag1
-rw-r--r--reference/shaders-msl/asm/comp/image-load-store-short-vector.invalid.asm.comp1
-rw-r--r--reference/shaders-msl/desktop-only/frag/image-ms.desktop.frag1
-rw-r--r--spirv_msl.cpp6
5 files changed, 9 insertions, 1 deletions
diff --git a/reference/opt/shaders-msl/asm/comp/image-load-store-short-vector.invalid.asm.comp b/reference/opt/shaders-msl/asm/comp/image-load-store-short-vector.invalid.asm.comp
index 53655639..346f40ee 100644
--- a/reference/opt/shaders-msl/asm/comp/image-load-store-short-vector.invalid.asm.comp
+++ b/reference/opt/shaders-msl/asm/comp/image-load-store-short-vector.invalid.asm.comp
@@ -8,6 +8,7 @@ using namespace metal;
static inline __attribute__((always_inline))
void _main(thread const uint3& id, texture2d<float, access::read_write> TargetTexture)
{
+ TargetTexture.fence();
float2 loaded = TargetTexture.read(uint2(id.xy)).xy;
float2 storeTemp = loaded + float2(1.0);
TargetTexture.write(storeTemp.xyyy, uint2((id.xy + uint2(1u))));
diff --git a/reference/opt/shaders-msl/desktop-only/frag/image-ms.desktop.frag b/reference/opt/shaders-msl/desktop-only/frag/image-ms.desktop.frag
index 4083e4ea..30046a1f 100644
--- a/reference/opt/shaders-msl/desktop-only/frag/image-ms.desktop.frag
+++ b/reference/opt/shaders-msl/desktop-only/frag/image-ms.desktop.frag
@@ -5,6 +5,7 @@ using namespace metal;
fragment void main0(texture2d_ms<float> uImageMS [[texture(0)]], texture2d_array<float, access::read_write> uImageArray [[texture(1)]], texture2d<float, access::write> uImage [[texture(2)]])
{
+ uImageArray.fence();
uImage.write(uImageMS.read(uint2(int2(1, 2)), 2), uint2(int2(2, 3)));
uImageArray.write(uImageArray.read(uint2(int3(1, 2, 4).xy), uint(int3(1, 2, 4).z)), uint2(int3(2, 3, 7).xy), uint(int3(2, 3, 7).z));
}
diff --git a/reference/shaders-msl/asm/comp/image-load-store-short-vector.invalid.asm.comp b/reference/shaders-msl/asm/comp/image-load-store-short-vector.invalid.asm.comp
index 53655639..346f40ee 100644
--- a/reference/shaders-msl/asm/comp/image-load-store-short-vector.invalid.asm.comp
+++ b/reference/shaders-msl/asm/comp/image-load-store-short-vector.invalid.asm.comp
@@ -8,6 +8,7 @@ using namespace metal;
static inline __attribute__((always_inline))
void _main(thread const uint3& id, texture2d<float, access::read_write> TargetTexture)
{
+ TargetTexture.fence();
float2 loaded = TargetTexture.read(uint2(id.xy)).xy;
float2 storeTemp = loaded + float2(1.0);
TargetTexture.write(storeTemp.xyyy, uint2((id.xy + uint2(1u))));
diff --git a/reference/shaders-msl/desktop-only/frag/image-ms.desktop.frag b/reference/shaders-msl/desktop-only/frag/image-ms.desktop.frag
index 7957b209..d413563a 100644
--- a/reference/shaders-msl/desktop-only/frag/image-ms.desktop.frag
+++ b/reference/shaders-msl/desktop-only/frag/image-ms.desktop.frag
@@ -6,6 +6,7 @@ using namespace metal;
fragment void main0(texture2d_ms<float> uImageMS [[texture(0)]], texture2d_array<float, access::read_write> uImageArray [[texture(1)]], texture2d<float, access::write> uImage [[texture(2)]])
{
float4 a = uImageMS.read(uint2(int2(1, 2)), 2);
+ uImageArray.fence();
float4 b = uImageArray.read(uint2(int3(1, 2, 4).xy), uint(int3(1, 2, 4).z));
uImage.write(a, uint2(int2(2, 3)));
uImageArray.write(b, uint2(int3(2, 3, 7).xy), uint(int3(2, 3, 7).z));
diff --git a/spirv_msl.cpp b/spirv_msl.cpp
index 4ca4a04d..a8ed9b25 100644
--- a/spirv_msl.cpp
+++ b/spirv_msl.cpp
@@ -8675,9 +8675,9 @@ void CompilerMSL::emit_instruction(const Instruction &instruction)
// Mark that this shader reads from this image
uint32_t img_id = ops[2];
auto &type = expression_type(img_id);
+ auto *p_var = maybe_get_backing_variable(img_id);
if (type.image.dim != DimSubpassData)
{
- auto *p_var = maybe_get_backing_variable(img_id);
if (p_var && has_decoration(p_var->self, DecorationNonReadable))
{
unset_decoration(p_var->self, DecorationNonReadable);
@@ -8685,6 +8685,10 @@ void CompilerMSL::emit_instruction(const Instruction &instruction)
}
}
+ // Metal requires explicit fences to break up RAW hazards, even within the same shader invocation
+ if (p_var && !has_decoration(p_var->self, DecorationNonWritable))
+ statement(to_expression(img_id), ".fence();");
+
emit_texture_op(instruction, false);
break;
}