mirror of
https://github.com/KhronosGroup/SPIRV-Cross.git
synced 2024-09-19 22:30:03 +00:00
MSL: Prevent RAW hazards on read_write textures
This commit is contained in:
parent
bccaa94db8
commit
4405dd6b28
@ -8,6 +8,7 @@ using namespace metal;
|
|||||||
static inline __attribute__((always_inline))
|
static inline __attribute__((always_inline))
|
||||||
void _main(thread const uint3& id, texture2d<float, access::read_write> TargetTexture)
|
void _main(thread const uint3& id, texture2d<float, access::read_write> TargetTexture)
|
||||||
{
|
{
|
||||||
|
TargetTexture.fence();
|
||||||
float2 loaded = TargetTexture.read(uint2(id.xy)).xy;
|
float2 loaded = TargetTexture.read(uint2(id.xy)).xy;
|
||||||
float2 storeTemp = loaded + float2(1.0);
|
float2 storeTemp = loaded + float2(1.0);
|
||||||
TargetTexture.write(storeTemp.xyyy, uint2((id.xy + uint2(1u))));
|
TargetTexture.write(storeTemp.xyyy, uint2((id.xy + uint2(1u))));
|
||||||
|
@ -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)]])
|
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)));
|
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));
|
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));
|
||||||
}
|
}
|
||||||
|
@ -8,6 +8,7 @@ using namespace metal;
|
|||||||
static inline __attribute__((always_inline))
|
static inline __attribute__((always_inline))
|
||||||
void _main(thread const uint3& id, texture2d<float, access::read_write> TargetTexture)
|
void _main(thread const uint3& id, texture2d<float, access::read_write> TargetTexture)
|
||||||
{
|
{
|
||||||
|
TargetTexture.fence();
|
||||||
float2 loaded = TargetTexture.read(uint2(id.xy)).xy;
|
float2 loaded = TargetTexture.read(uint2(id.xy)).xy;
|
||||||
float2 storeTemp = loaded + float2(1.0);
|
float2 storeTemp = loaded + float2(1.0);
|
||||||
TargetTexture.write(storeTemp.xyyy, uint2((id.xy + uint2(1u))));
|
TargetTexture.write(storeTemp.xyyy, uint2((id.xy + uint2(1u))));
|
||||||
|
@ -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)]])
|
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);
|
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));
|
float4 b = uImageArray.read(uint2(int3(1, 2, 4).xy), uint(int3(1, 2, 4).z));
|
||||||
uImage.write(a, uint2(int2(2, 3)));
|
uImage.write(a, uint2(int2(2, 3)));
|
||||||
uImageArray.write(b, uint2(int3(2, 3, 7).xy), uint(int3(2, 3, 7).z));
|
uImageArray.write(b, uint2(int3(2, 3, 7).xy), uint(int3(2, 3, 7).z));
|
||||||
|
@ -8675,9 +8675,9 @@ void CompilerMSL::emit_instruction(const Instruction &instruction)
|
|||||||
// Mark that this shader reads from this image
|
// Mark that this shader reads from this image
|
||||||
uint32_t img_id = ops[2];
|
uint32_t img_id = ops[2];
|
||||||
auto &type = expression_type(img_id);
|
auto &type = expression_type(img_id);
|
||||||
|
auto *p_var = maybe_get_backing_variable(img_id);
|
||||||
if (type.image.dim != DimSubpassData)
|
if (type.image.dim != DimSubpassData)
|
||||||
{
|
{
|
||||||
auto *p_var = maybe_get_backing_variable(img_id);
|
|
||||||
if (p_var && has_decoration(p_var->self, DecorationNonReadable))
|
if (p_var && has_decoration(p_var->self, DecorationNonReadable))
|
||||||
{
|
{
|
||||||
unset_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);
|
emit_texture_op(instruction, false);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user