Skip to content

Commit ee1f013

Browse files
authored
[SPIR-V] Fix bad OpLoad on loaded texture (microsoft#6985)
This code path always added an OpLoad since it expected either an OpAccessChain or a variable. This is wrong if we get the texture from a called function. There is one thing I do find weird is the OpAccessChain result is considered to be an L-value. But I'd expect this to be an r-value. Fixes microsoft#4136 Signed-off-by: Nathan Gauër <[email protected]>
1 parent e090984 commit ee1f013

File tree

2 files changed

+38
-2
lines changed

2 files changed

+38
-2
lines changed

tools/clang/lib/SPIRV/SpirvEmitter.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7900,8 +7900,12 @@ SpirvInstruction *SpirvEmitter::tryToAssignToRWBufferRWTexture(
79007900
beginInvocationInterlock(baseExpr->getExprLoc(), range);
79017901
}
79027902

7903-
auto *image = spvBuilder.createLoad(imageType, baseInfo,
7904-
baseExpr->getExprLoc(), range);
7903+
SpirvInstruction *image = baseInfo;
7904+
// If the base is an L-value (OpVariable, OpAccessChain to OpVariable), we
7905+
// need a load.
7906+
if (baseInfo->isLValue())
7907+
image = spvBuilder.createLoad(imageType, baseInfo, baseExpr->getExprLoc(),
7908+
range);
79057909
spvBuilder.createImageWrite(imageType, image, loc, rhs, lhs->getExprLoc(),
79067910
range);
79077911

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
// RUN: %dxc -T cs_6_7 -E main -spirv -fspv-target-env=vulkan1.1 %s -fcgl | FileCheck %s
2+
3+
RWTexture2D<float2> textures[];
4+
5+
cbuffer CB {
6+
uint index;
7+
}
8+
9+
RWTexture2D<float2> GetTexture() {
10+
return textures[index];
11+
}
12+
13+
[numthreads(1, 1, 1)]
14+
void main(uint3 tid : SV_DispatchThreadID)
15+
{
16+
// We need to make sure there is no OpLoad on the already loaded texture.
17+
// CHECK: [[img:%[0-9]+]] = OpFunctionCall %type_2d_image %GetTexture
18+
// CHECK: OpImageWrite [[img]] {{.*}} {{.*}} None
19+
GetTexture()[tid.xy] = float2(1.0, 0.0);
20+
21+
// CHECK: [[ptr:%[0-9]+]] = OpAccessChain %_ptr_UniformConstant_type_2d_image %textures %int_0
22+
// CHECK: [[tmp:%[0-9]+]] = OpLoad %type_2d_image [[ptr]]
23+
// CHECK: OpImageWrite [[tmp]] {{.*}} {{.*}} None
24+
textures[0][tid.xy] = float2(1.0, 0.0);
25+
26+
// CHECK: [[img:%[0-9]+]] = OpFunctionCall %type_2d_image %GetTexture
27+
// CHECK: OpStore %tex [[img]]
28+
// CHECK: [[tmp:%[0-9]+]] = OpLoad %type_2d_image %tex
29+
// CHECK: OpImageWrite [[tmp]] {{.*}} {{.*}} None
30+
RWTexture2D<float2> tex = GetTexture();
31+
tex[tid.xy] = float2(1.0, 0.0);
32+
}

0 commit comments

Comments
 (0)