Skip to content

Commit d7ee5e1

Browse files
authored
[spirv] set needsLegalization as true when variable offset is found (#3820)
When we find a variable offset used for the texture sampling, we have to - Run legalization if `-fcgl` is not enabled. - Enable `--before-legalize-hlsl` for spirv-val if `-fcgl` is enabled. to match the behavior of the DXIL backend. In order to do that, we set SpirvEmitter::needsLegalization as true when we find a variable offset used for the texture sampling. SpirvEmitter will determine enabling `--before-legalize-hlsl` or running the legalization depending on `-fcgl`.
1 parent cef61b5 commit d7ee5e1

5 files changed

Lines changed: 87 additions & 0 deletions

File tree

tools/clang/lib/SPIRV/SpirvEmitter.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4461,6 +4461,9 @@ SpirvInstruction *SpirvEmitter::createImageSample(
44614461
SpirvInstruction *minLod, SpirvInstruction *residencyCodeId,
44624462
SourceLocation loc) {
44634463

4464+
if (varOffset)
4465+
needsLegalization = true;
4466+
44644467
// SampleDref* instructions in SPIR-V always return a scalar.
44654468
// They also have the correct type in HLSL.
44664469
if (compareVal) {
@@ -4893,6 +4896,9 @@ SpirvEmitter::processBufferTextureLoad(const CXXMemberCallExpr *expr) {
48934896
handleOffsetInMethodCall(expr, 1, &constOffset, &varOffset);
48944897
}
48954898

4899+
if (varOffset)
4900+
needsLegalization = true;
4901+
48964902
return processBufferTextureLoad(object, coordinate, constOffset, varOffset,
48974903
lod, status, loc);
48984904
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// Run: %dxc -T ps_6_0 -E main
2+
3+
SamplerState gSampler : register(s5);
4+
Texture2D<float4> t : register(t1);
5+
6+
// This shader uses a variable offset for texture sampling that is supposed to
7+
// be converted to a constant value after the legalization. Since we set
8+
// needsLegalization as true when we find a variable offset for texture
9+
// sampling, `--before-legalize-hlsl` option for spirv-val should be enabled
10+
// because of `-fcgl`.
11+
12+
// CHECK: OpImageSparseSampleImplicitLod
13+
// CHECK-SAME: Offset
14+
15+
float4 sample(int offset, float clamp) {
16+
uint status;
17+
return t.Sample(gSampler, float2(0.1, 0.2), offset, clamp, status);
18+
}
19+
20+
float4 main(int2 offset: A) : SV_Target {
21+
float4 val = 0;
22+
[unroll] for (int i = 0; i < 3; ++i)
23+
val = sample(i, offset.x);
24+
return val;
25+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// Run: %dxc -T ps_6_0 -E main -O0
2+
3+
SamplerState gSampler : register(s5);
4+
Texture2D<float4> t : register(t1);
5+
6+
// This shader uses a variable offset for texture sampling that is supposed to
7+
// be converted to a constant value after the legalization.
8+
9+
// CHECK: OpImageSparseSampleImplicitLod
10+
// CHECK-SAME: ConstOffset
11+
12+
float4 sample(int offset, float clamp) {
13+
uint status;
14+
return t.Sample(gSampler, float2(0.1, 0.2), offset, clamp, status);
15+
}
16+
17+
float4 main(int2 offset: A) : SV_Target {
18+
float4 val = 0;
19+
[unroll] for (int i = 0; i < 3; ++i)
20+
val = sample(i, offset.x);
21+
return val;
22+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// Run: %dxc -T ps_6_0 -E main
2+
SamplerState gSampler : register(s5);
3+
Texture2D<float4> t : register(t1);
4+
5+
// This shader uses a variable offset for texture sampling, which is illegal.
6+
// Since we set needsLegalization as true when we find a variable offset for
7+
// texture sampling, `--before-legalize-hlsl` option for spirv-val should be
8+
// enabled because of `-fcgl`. Therefore, it must not generate any errors.
9+
10+
// CHECK: OpImageSparseSampleImplicitLod
11+
// CHECK-SAME: Offset
12+
13+
float4 sample(int2 offset, float clamp) {
14+
uint status;
15+
return t.Sample(gSampler, float2(0.1, 0.2), offset, clamp, status);
16+
}
17+
18+
float4 main(int2 offset: A) : SV_Target {
19+
float4 val = 0;
20+
for (int i = 0; i < 3; ++i)
21+
val = sample(offset, i);
22+
return val;
23+
}

tools/clang/unittests/SPIRV/CodeGenSpirvTest.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -980,6 +980,17 @@ TEST_F(FileTest, TextureInvalidTex2D) {
980980
TEST_F(FileTest, TextureSampleOffsetWithLoopUnroll) {
981981
runFileTest("texture.sample-offset.with.loop-unroll.hlsl");
982982
}
983+
TEST_F(FileTest, TextureSampleVariableOffsetBeforeLegalizeHLSL) {
984+
setBeforeHLSLLegalization();
985+
runFileTest("texture.sample.variable-offset.hlsl");
986+
}
987+
TEST_F(FileTest, TextureSampleOffsetNeedsLegalization) {
988+
setBeforeHLSLLegalization();
989+
runFileTest("texture.sample.offset.needs.legalization.hlsl");
990+
}
991+
TEST_F(FileTest, TextureSampleConstOffsetAfterLegalization) {
992+
runFileTest("texture.sample.offset.needs.legalization.o0.hlsl");
993+
}
983994

984995
// For structured buffer methods
985996
TEST_F(FileTest, StructuredBufferLoad) {

0 commit comments

Comments
 (0)