Skip to content

Commit b89799d

Browse files
authored
[SPIR-V][vk::SampledTexture] #6. Add remaining .Gather...() methods for vk::SampledTexture2D type. (microsoft#8149)
Part of microsoft#7979 ```hlsl TemplateType GatherRed(float2 Location, int2 Offset1, int2 Offset2, int2 Offset3, int2 Offset4, uint Status); TemplateType GatherGreen(float2 Location, int2 Offset1, int2 Offset2, int2 Offset3, int2 Offset4, uint Status); TemplateType GatherBlue(float2 Location, int2 Offset1, int2 Offset2, int2 Offset3, int2 Offset4, uint Status); TemplateType GatherAlpha(float2 Location, int2 Offset1, int2 Offset2, int2 Offset3, int2 Offset4, uint Status); TemplateType GatherCmp(float Location, float CompareValue, int2 Offset, uint Status); TemplateType GatherCmpRed(float Location, float CompareValue, int2 Offset1, int2 Offset2, int2 Offset3, int2 Offset4, uint Status); ``` GatherCmpGreen, GatherCmpBlue, GatherCmpAlpha, GatherRaw are not supported.
1 parent 1195122 commit b89799d

11 files changed

Lines changed: 442 additions & 21 deletions

tools/clang/lib/SPIRV/SpirvEmitter.cpp

Lines changed: 56 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -4551,44 +4551,60 @@ SpirvInstruction *SpirvEmitter::processTextureGatherRGBACmpRGBA(
45514551
// * SamplerState s, float2 location, float compare_value, out uint status
45524552
//
45534553
// Return type is always a 4-component vector.
4554+
//
4555+
// SampledTexture variants have the same signatures without the SamplerState
4556+
// parameter.
45544557
const FunctionDecl *callee = expr->getDirectCallee();
45554558
const auto numArgs = expr->getNumArgs();
45564559
const auto *imageExpr = expr->getImplicitObjectArgument();
45574560
const auto loc = expr->getCallee()->getExprLoc();
45584561
const QualType imageType = imageExpr->getType();
45594562
const QualType retType = callee->getReturnType();
4563+
const bool isImageSampledTexture = isSampledTexture(imageType);
45604564

45614565
// If the last arg is an unsigned integer, it must be the status.
45624566
const bool hasStatusArg =
45634567
expr->getArg(numArgs - 1)->getType()->isUnsignedIntegerType();
45644568

45654569
// Subtract 1 for status arg (if it exists), subtract 1 for compare_value (if
45664570
// it exists), and subtract 2 for SamplerState and location.
4567-
const auto numOffsetArgs = numArgs - hasStatusArg - isCmp - 2;
4571+
int offsetStartIndex = (isImageSampledTexture ? 1 : 2) + isCmp;
4572+
const auto numOffsetArgs = numArgs - hasStatusArg - offsetStartIndex;
45684573
// No offset args for TextureCube, 1 or 4 offset args for the rest.
45694574
assert(numOffsetArgs == 0 || numOffsetArgs == 1 || numOffsetArgs == 4);
45704575

4576+
int samplerIndex, coordIndex, compareValIndex;
4577+
if (isImageSampledTexture) {
4578+
samplerIndex = -1; // non-existant
4579+
coordIndex = 0;
4580+
compareValIndex = 1;
4581+
} else {
4582+
samplerIndex = 0;
4583+
coordIndex = 1;
4584+
compareValIndex = 2;
4585+
}
45714586
auto *image = loadIfGLValue(imageExpr);
4572-
auto *sampler = doExpr(expr->getArg(0));
4573-
auto *coordinate = doExpr(expr->getArg(1));
4574-
auto *compareVal = isCmp ? doExpr(expr->getArg(2)) : nullptr;
4587+
auto *sampler =
4588+
samplerIndex >= 0 ? doExpr(expr->getArg(samplerIndex)) : nullptr;
4589+
auto *coordinate = doExpr(expr->getArg(coordIndex));
4590+
auto *compareVal = isCmp ? doExpr(expr->getArg(compareValIndex)) : nullptr;
45754591

45764592
// Handle offsets (if any).
45774593
bool needsEmulation = false;
45784594
SpirvInstruction *constOffset = nullptr, *varOffset = nullptr,
45794595
*constOffsets = nullptr;
45804596
if (numOffsetArgs == 1) {
45814597
// The offset arg is not optional.
4582-
handleOffsetInMethodCall(expr, 2 + isCmp, &constOffset, &varOffset);
4598+
handleOffsetInMethodCall(expr, offsetStartIndex, &constOffset, &varOffset);
45834599
} else if (numOffsetArgs == 4) {
4584-
auto *offset0 = constEvaluator.tryToEvaluateAsConst(expr->getArg(2 + isCmp),
4585-
isSpecConstantMode);
4586-
auto *offset1 = constEvaluator.tryToEvaluateAsConst(expr->getArg(3 + isCmp),
4587-
isSpecConstantMode);
4588-
auto *offset2 = constEvaluator.tryToEvaluateAsConst(expr->getArg(4 + isCmp),
4589-
isSpecConstantMode);
4590-
auto *offset3 = constEvaluator.tryToEvaluateAsConst(expr->getArg(5 + isCmp),
4591-
isSpecConstantMode);
4600+
auto *offset0 = constEvaluator.tryToEvaluateAsConst(
4601+
expr->getArg(offsetStartIndex), isSpecConstantMode);
4602+
auto *offset1 = constEvaluator.tryToEvaluateAsConst(
4603+
expr->getArg(offsetStartIndex + 1), isSpecConstantMode);
4604+
auto *offset2 = constEvaluator.tryToEvaluateAsConst(
4605+
expr->getArg(offsetStartIndex + 2), isSpecConstantMode);
4606+
auto *offset3 = constEvaluator.tryToEvaluateAsConst(
4607+
expr->getArg(offsetStartIndex + 3), isSpecConstantMode);
45924608

45934609
// If any of the offsets is not constant, we then need to emulate the call
45944610
// using 4 OpImageGather instructions. Otherwise, we can leverage the
@@ -4611,7 +4627,7 @@ SpirvInstruction *SpirvEmitter::processTextureGatherRGBACmpRGBA(
46114627

46124628
SpirvInstruction *texels[4];
46134629
for (uint32_t i = 0; i < 4; ++i) {
4614-
varOffset = doExpr(expr->getArg(2 + isCmp + i));
4630+
varOffset = doExpr(expr->getArg(offsetStartIndex + i));
46154631
auto *gatherRet = spvBuilder.createImageGather(
46164632
retType, imageType, image, sampler, coordinate,
46174633
spvBuilder.getConstantInt(astContext.IntTy,
@@ -4656,25 +4672,44 @@ SpirvEmitter::processTextureGatherCmp(const CXXMemberCallExpr *expr) {
46564672
// );
46574673
//
46584674
// Other Texture types do not have the GatherCmp method.
4675+
//
4676+
// SampledTexture variants have the same signatures without the SamplerState
4677+
// parameter.
46594678

46604679
const FunctionDecl *callee = expr->getDirectCallee();
46614680
const auto numArgs = expr->getNumArgs();
46624681
const auto loc = expr->getExprLoc();
46634682
const bool hasStatusArg =
46644683
expr->getArg(numArgs - 1)->getType()->isUnsignedIntegerType();
4665-
const bool hasOffsetArg = (numArgs == 5) || (numArgs == 4 && !hasStatusArg);
4666-
46674684
const auto *imageExpr = expr->getImplicitObjectArgument();
4685+
4686+
const QualType imageType = imageExpr->getType();
4687+
const bool isImageSampledTexture = isSampledTexture(imageType);
4688+
4689+
int samplerIndex, coordIndex, compareValIndex;
4690+
if (isImageSampledTexture) {
4691+
samplerIndex = -1; // non-existant
4692+
coordIndex = 0;
4693+
compareValIndex = 1;
4694+
} else {
4695+
samplerIndex = 0;
4696+
coordIndex = 1;
4697+
compareValIndex = 2;
4698+
}
4699+
46684700
auto *image = loadIfGLValue(imageExpr);
4669-
auto *sampler = doExpr(expr->getArg(0));
4670-
auto *coordinate = doExpr(expr->getArg(1));
4671-
auto *comparator = doExpr(expr->getArg(2));
4701+
auto *sampler =
4702+
samplerIndex >= 0 ? doExpr(expr->getArg(samplerIndex)) : nullptr;
4703+
auto *coordinate = doExpr(expr->getArg(coordIndex));
4704+
auto *comparator = doExpr(expr->getArg(compareValIndex));
4705+
4706+
const bool hasOffsetArg = numArgs - hasStatusArg - compareValIndex > 1;
46724707
SpirvInstruction *constOffset = nullptr, *varOffset = nullptr;
46734708
if (hasOffsetArg)
4674-
handleOffsetInMethodCall(expr, 3, &constOffset, &varOffset);
4709+
handleOffsetInMethodCall(expr, compareValIndex + 1, &constOffset,
4710+
&varOffset);
46754711

46764712
const auto retType = callee->getReturnType();
4677-
const auto imageType = imageExpr->getType();
46784713
const auto status =
46794714
hasStatusArg ? doExpr(expr->getArg(numArgs - 1)) : nullptr;
46804715

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
// RUN: %dxc -T ps_6_0 -E main -fcgl %s -spirv | FileCheck %s
2+
3+
// CHECK: OpCapability SparseResidency
4+
5+
// CHECK: [[v2fc:%[0-9]+]] = OpConstantComposite %v2float %float_0_5 %float_0_25
6+
// CHECK: [[v2ic:%[0-9]+]] = OpConstantComposite %v2int %int_2 %int_3
7+
8+
// CHECK: [[type_2d_image_1:%[a-zA-Z0-9_]+]] = OpTypeImage %float 2D 0 0 0 1 Unknown
9+
// CHECK: [[type_sampled_image_1:%[a-zA-Z0-9_]+]] = OpTypeSampledImage [[type_2d_image_1]]
10+
// CHECK: [[ptr_type_1:%[a-zA-Z0-9_]+]] = OpTypePointer UniformConstant [[type_sampled_image_1]]
11+
12+
// CHECK: [[type_struct_result:%[a-zA-Z0-9_]+]] = OpTypeStruct %uint %v4float
13+
14+
// CHECK: [[tex1:%[a-zA-Z0-9_]+]] = OpVariable [[ptr_type_1]] UniformConstant
15+
16+
vk::SampledTexture2D<float4> tex1 : register(t1);
17+
18+
float4 main() : SV_Target {
19+
uint status;
20+
float4 val = 0;
21+
22+
// CHECK: [[tex1_load:%[a-zA-Z0-9_]+]] = OpLoad [[type_sampled_image_1]] [[tex1]]
23+
// CHECK: [[val_alpha:%[a-zA-Z0-9_]+]] = OpImageGather %v4float [[tex1_load]] [[v2fc]] %int_3
24+
// CHECK: OpStore %val [[val_alpha]]
25+
val = tex1.GatherAlpha(float2(0.5, 0.25));
26+
27+
// CHECK: [[tex1_load:%[a-zA-Z0-9_]+]] = OpLoad [[type_sampled_image_1]] [[tex1]]
28+
// CHECK: [[val_alpha_o:%[a-zA-Z0-9_]+]] = OpImageGather %v4float [[tex1_load]] [[v2fc]] %int_3 ConstOffset [[v2ic]]
29+
// CHECK: OpStore %val [[val_alpha_o]]
30+
val = tex1.GatherAlpha(float2(0.5, 0.25), int2(2, 3));
31+
32+
// CHECK: [[tex1_load:%[a-zA-Z0-9_]+]] = OpLoad [[type_sampled_image_1]] [[tex1]]
33+
// CHECK: [[val_alpha_o4:%[a-zA-Z0-9_]+]] = OpImageGather %v4float [[tex1_load]] [[v2fc]] %int_3 ConstOffsets [[const_offsets:%[a-zA-Z0-9_]+]]
34+
// CHECK: OpStore %val [[val_alpha_o4]]
35+
val = tex1.GatherAlpha(float2(0.5, 0.25), int2(1, 2), int2(3, 4), int2(5, 6), int2(7, 8));
36+
37+
// CHECK: [[tex1_load:%[a-zA-Z0-9_]+]] = OpLoad [[type_sampled_image_1]] [[tex1]]
38+
// CHECK: [[val_alpha_s:%[a-zA-Z0-9_]+]] = OpImageSparseGather [[type_struct_result]] [[tex1_load]] [[v2fc]] %int_3 ConstOffset [[v2ic]]
39+
// CHECK: [[status_alpha_s:%[a-zA-Z0-9_]+]] = OpCompositeExtract %uint [[val_alpha_s]] 0
40+
// CHECK: OpStore %status [[status_alpha_s]]
41+
// CHECK: [[res_alpha_s:%[a-zA-Z0-9_]+]] = OpCompositeExtract %v4float [[val_alpha_s]] 1
42+
// CHECK: OpStore %val [[res_alpha_s]]
43+
val = tex1.GatherAlpha(float2(0.5, 0.25), int2(2, 3), status);
44+
45+
// CHECK: [[tex1_load:%[a-zA-Z0-9_]+]] = OpLoad [[type_sampled_image_1]] [[tex1]]
46+
// CHECK: [[val_alpha_o4_s:%[a-zA-Z0-9_]+]] = OpImageSparseGather [[type_struct_result]] [[tex1_load]] [[v2fc]] %int_3 ConstOffsets [[const_offsets]]
47+
// CHECK: [[status_alpha_o4_s:%[a-zA-Z0-9_]+]] = OpCompositeExtract %uint [[val_alpha_o4_s]] 0
48+
// CHECK: OpStore %status [[status_alpha_o4_s]]
49+
// CHECK: [[res_alpha_o4_s:%[a-zA-Z0-9_]+]] = OpCompositeExtract %v4float [[val_alpha_o4_s]] 1
50+
// CHECK: OpStore %val [[res_alpha_o4_s]]
51+
val = tex1.GatherAlpha(float2(0.5, 0.25), int2(1, 2), int2(3, 4), int2(5, 6), int2(7, 8), status);
52+
53+
return val;
54+
}
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
// RUN: %dxc -T ps_6_0 -E main -fcgl %s -spirv | FileCheck %s
2+
3+
// CHECK: OpCapability SparseResidency
4+
5+
// CHECK: [[v2fc:%[0-9]+]] = OpConstantComposite %v2float %float_0_5 %float_0_25
6+
// CHECK: [[v2ic:%[0-9]+]] = OpConstantComposite %v2int %int_2 %int_3
7+
8+
// CHECK: [[type_2d_image_1:%[a-zA-Z0-9_]+]] = OpTypeImage %float 2D 0 0 0 1 Unknown
9+
// CHECK: [[type_sampled_image_1:%[a-zA-Z0-9_]+]] = OpTypeSampledImage [[type_2d_image_1]]
10+
// CHECK: [[ptr_type_1:%[a-zA-Z0-9_]+]] = OpTypePointer UniformConstant [[type_sampled_image_1]]
11+
12+
// CHECK: [[type_struct_result:%[a-zA-Z0-9_]+]] = OpTypeStruct %uint %v4float
13+
14+
// CHECK: [[tex1:%[a-zA-Z0-9_]+]] = OpVariable [[ptr_type_1]] UniformConstant
15+
16+
vk::SampledTexture2D<float4> tex1 : register(t1);
17+
18+
float4 main() : SV_Target {
19+
uint status;
20+
float4 val = 0;
21+
22+
// CHECK: [[tex1_load:%[a-zA-Z0-9_]+]] = OpLoad [[type_sampled_image_1]] [[tex1]]
23+
// CHECK: [[val_blue:%[a-zA-Z0-9_]+]] = OpImageGather %v4float [[tex1_load]] [[v2fc]] %int_2
24+
// CHECK: OpStore %val [[val_blue]]
25+
val = tex1.GatherBlue(float2(0.5, 0.25));
26+
27+
// CHECK: [[tex1_load:%[a-zA-Z0-9_]+]] = OpLoad [[type_sampled_image_1]] [[tex1]]
28+
// CHECK: [[val_blue_o:%[a-zA-Z0-9_]+]] = OpImageGather %v4float [[tex1_load]] [[v2fc]] %int_2 ConstOffset [[v2ic]]
29+
// CHECK: OpStore %val [[val_blue_o]]
30+
val = tex1.GatherBlue(float2(0.5, 0.25), int2(2, 3));
31+
32+
// CHECK: [[tex1_load:%[a-zA-Z0-9_]+]] = OpLoad [[type_sampled_image_1]] [[tex1]]
33+
// CHECK: [[val_blue_o4:%[a-zA-Z0-9_]+]] = OpImageGather %v4float [[tex1_load]] [[v2fc]] %int_2 ConstOffsets [[const_offsets:%[a-zA-Z0-9_]+]]
34+
// CHECK: OpStore %val [[val_blue_o4]]
35+
val = tex1.GatherBlue(float2(0.5, 0.25), int2(1, 2), int2(3, 4), int2(5, 6), int2(7, 8));
36+
37+
// CHECK: [[tex1_load:%[a-zA-Z0-9_]+]] = OpLoad [[type_sampled_image_1]] [[tex1]]
38+
// CHECK: [[val_blue_s:%[a-zA-Z0-9_]+]] = OpImageSparseGather [[type_struct_result]] [[tex1_load]] [[v2fc]] %int_2 ConstOffset [[v2ic]]
39+
// CHECK: [[status_blue_s:%[a-zA-Z0-9_]+]] = OpCompositeExtract %uint [[val_blue_s]] 0
40+
// CHECK: OpStore %status [[status_blue_s]]
41+
// CHECK: [[res_blue_s:%[a-zA-Z0-9_]+]] = OpCompositeExtract %v4float [[val_blue_s]] 1
42+
// CHECK: OpStore %val [[res_blue_s]]
43+
val = tex1.GatherBlue(float2(0.5, 0.25), int2(2, 3), status);
44+
45+
// CHECK: [[tex1_load:%[a-zA-Z0-9_]+]] = OpLoad [[type_sampled_image_1]] [[tex1]]
46+
// CHECK: [[val_blue_o4_s:%[a-zA-Z0-9_]+]] = OpImageSparseGather [[type_struct_result]] [[tex1_load]] [[v2fc]] %int_2 ConstOffsets [[const_offsets]]
47+
// CHECK: [[status_blue_o4_s:%[a-zA-Z0-9_]+]] = OpCompositeExtract %uint [[val_blue_o4_s]] 0
48+
// CHECK: OpStore %status [[status_blue_o4_s]]
49+
// CHECK: [[res_blue_o4_s:%[a-zA-Z0-9_]+]] = OpCompositeExtract %v4float [[val_blue_o4_s]] 1
50+
// CHECK: OpStore %val [[res_blue_o4_s]]
51+
val = tex1.GatherBlue(float2(0.5, 0.25), int2(1, 2), int2(3, 4), int2(5, 6), int2(7, 8), status);
52+
53+
return val;
54+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// RUN: not %dxc -T ps_6_0 -E main -fcgl %s -spirv 2>&1 | FileCheck %s
2+
3+
SamplerComparisonState gSampler : register(s5);
4+
5+
Texture2D<float4> myTexture : register(t1);
6+
7+
float4 main(float2 location: A, float comparator: B) : SV_Target {
8+
return myTexture.GatherCmpAlpha(gSampler, location, comparator, int2(1, 2));
9+
}
10+
11+
// CHECK: :8:22: error: no equivalent for GatherCmpAlpha intrinsic method in Vulkan
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// RUN: not %dxc -T ps_6_0 -E main -fcgl %s -spirv 2>&1 | FileCheck %s
2+
3+
SamplerComparisonState gSampler : register(s5);
4+
5+
Texture2D<float4> myTexture : register(t1);
6+
7+
float4 main(float2 location: A, float comparator: B) : SV_Target {
8+
return myTexture.GatherCmpBlue(gSampler, location, comparator, int2(1, 2));
9+
}
10+
11+
// CHECK: :8:22: error: no equivalent for GatherCmpBlue intrinsic method in Vulkan
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// RUN: not %dxc -T ps_6_0 -E main -fcgl %s -spirv 2>&1 | FileCheck %s
2+
3+
SamplerComparisonState gSampler : register(s5);
4+
5+
Texture2D<float4> myTexture : register(t1);
6+
7+
float4 main(float2 location: A, float comparator: B) : SV_Target {
8+
return myTexture.GatherCmpGreen(gSampler, location, comparator, int2(1, 2));
9+
}
10+
11+
// CHECK: :8:22: error: no equivalent for GatherCmpGreen intrinsic method in Vulkan
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
// RUN: %dxc -T ps_6_0 -E main -fcgl %s -spirv | FileCheck %s
2+
3+
// CHECK: OpCapability SparseResidency
4+
5+
// CHECK: [[v2fc:%[0-9]+]] = OpConstantComposite %v2float %float_0_5 %float_0_25
6+
// CHECK: [[v2ic:%[0-9]+]] = OpConstantComposite %v2int %int_2 %int_3
7+
8+
// CHECK: [[type_2d_image_1:%[a-zA-Z0-9_]+]] = OpTypeImage %float 2D 0 0 0 1 Unknown
9+
// CHECK: [[type_sampled_image_1:%[a-zA-Z0-9_]+]] = OpTypeSampledImage [[type_2d_image_1]]
10+
// CHECK: [[ptr_type_1:%[a-zA-Z0-9_]+]] = OpTypePointer UniformConstant [[type_sampled_image_1]]
11+
12+
// CHECK: [[type_struct_result:%[a-zA-Z0-9_]+]] = OpTypeStruct %uint %v4float
13+
14+
// CHECK: [[tex1:%[a-zA-Z0-9_]+]] = OpVariable [[ptr_type_1]] UniformConstant
15+
16+
vk::SampledTexture2D<float4> tex1 : register(t1);
17+
18+
float4 main() : SV_Target {
19+
uint status;
20+
float4 val = 0;
21+
22+
// CHECK: [[tex1_load:%[a-zA-Z0-9_]+]] = OpLoad [[type_sampled_image_1]] [[tex1]]
23+
// CHECK: [[val_red:%[a-zA-Z0-9_]+]] = OpImageDrefGather %v4float [[tex1_load]] [[v2fc]] %float_0_5 None
24+
// CHECK: OpStore %val [[val_red]]
25+
val = tex1.GatherCmpRed(float2(0.5, 0.25), 0.5);
26+
27+
// CHECK: [[tex1_load:%[a-zA-Z0-9_]+]] = OpLoad [[type_sampled_image_1]] [[tex1]]
28+
// CHECK: [[val_red_o:%[a-zA-Z0-9_]+]] = OpImageDrefGather %v4float [[tex1_load]] [[v2fc]] %float_0_5 ConstOffset [[v2ic]]
29+
// CHECK: OpStore %val [[val_red_o]]
30+
val = tex1.GatherCmpRed(float2(0.5, 0.25), 0.5, int2(2, 3));
31+
32+
// CHECK: [[tex1_load:%[a-zA-Z0-9_]+]] = OpLoad [[type_sampled_image_1]] [[tex1]]
33+
// CHECK: [[val_red_o4:%[a-zA-Z0-9_]+]] = OpImageDrefGather %v4float [[tex1_load]] [[v2fc]] %float_0_5 ConstOffsets [[const_offsets:%[a-zA-Z0-9_]+]]
34+
// CHECK: OpStore %val [[val_red_o4]]
35+
val = tex1.GatherCmpRed(float2(0.5, 0.25), 0.5, int2(1, 2), int2(3, 4), int2(5, 6), int2(7, 8));
36+
37+
// CHECK: [[tex1_load:%[a-zA-Z0-9_]+]] = OpLoad [[type_sampled_image_1]] [[tex1]]
38+
// CHECK: [[val_cmp_s:%[a-zA-Z0-9_]+]] = OpImageSparseDrefGather [[type_struct_result]] [[tex1_load]] [[v2fc]] %float_0_5 ConstOffset [[v2ic]]
39+
// CHECK: [[status_cmp_s:%[a-zA-Z0-9_]+]] = OpCompositeExtract %uint [[val_cmp_s]] 0
40+
// CHECK: OpStore %status [[status_cmp_s]]
41+
// CHECK: [[res_cmp_s:%[a-zA-Z0-9_]+]] = OpCompositeExtract %v4float [[val_cmp_s]] 1
42+
// CHECK: OpStore %val [[res_cmp_s]]
43+
val = tex1.GatherCmpRed(float2(0.5, 0.25), 0.5, int2(2, 3), status);
44+
45+
// CHECK: [[tex1_load:%[a-zA-Z0-9_]+]] = OpLoad [[type_sampled_image_1]] [[tex1]]
46+
// CHECK: [[val_cmp_o4_s:%[a-zA-Z0-9_]+]] = OpImageSparseDrefGather [[type_struct_result]] [[tex1_load]] [[v2fc]] %float_0_5 ConstOffsets [[const_offsets]]
47+
// CHECK: [[status_cmp_o4_s:%[a-zA-Z0-9_]+]] = OpCompositeExtract %uint [[val_cmp_o4_s]] 0
48+
// CHECK: OpStore %status [[status_cmp_o4_s]]
49+
// CHECK: [[res_cmp_o4_s:%[a-zA-Z0-9_]+]] = OpCompositeExtract %v4float [[val_cmp_o4_s]] 1
50+
// CHECK: OpStore %val [[res_cmp_o4_s]]
51+
val = tex1.GatherCmpRed(float2(0.5, 0.25), 0.5, int2(1, 2), int2(3, 4), int2(5, 6), int2(7, 8), status);
52+
53+
return val;
54+
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
// RUN: %dxc -T ps_6_0 -E main -fcgl %s -spirv | FileCheck %s
2+
3+
// CHECK: OpCapability SparseResidency
4+
5+
// CHECK: [[v2fc:%[0-9]+]] = OpConstantComposite %v2float %float_0_5 %float_0_25
6+
// CHECK: [[v2ic:%[0-9]+]] = OpConstantComposite %v2int %int_1 %int_2
7+
8+
// CHECK: [[type_2d_image_1:%[a-zA-Z0-9_]+]] = OpTypeImage %float 2D 0 0 0 1 Unknown
9+
// CHECK: [[type_sampled_image_1:%[a-zA-Z0-9_]+]] = OpTypeSampledImage [[type_2d_image_1]]
10+
// CHECK: [[ptr_type_1:%[a-zA-Z0-9_]+]] = OpTypePointer UniformConstant [[type_sampled_image_1]]
11+
// CHECK: [[type_struct_result:%[a-zA-Z0-9_]+]] = OpTypeStruct %uint %v4float
12+
13+
// CHECK: [[tex1:%[a-zA-Z0-9_]+]] = OpVariable [[ptr_type_1]] UniformConstant
14+
15+
vk::SampledTexture2D<float4> tex1 : register(t1);
16+
17+
float4 main() : SV_Target {
18+
uint status;
19+
float4 val = 0;
20+
21+
// CHECK: [[tex1_load_1:%[a-zA-Z0-9_]+]] = OpLoad [[type_sampled_image_1]] [[tex1]]
22+
// CHECK: [[val_1:%[a-zA-Z0-9_]+]] = OpImageDrefGather %v4float [[tex1_load_1]] [[v2fc]] %float_0_5
23+
// CHECK: OpStore %val [[val_1]]
24+
val = tex1.GatherCmp(float2(0.5, 0.25), 0.5);
25+
26+
// CHECK: [[tex1_load_2:%[a-zA-Z0-9_]+]] = OpLoad [[type_sampled_image_1]] [[tex1]]
27+
// CHECK: [[val_2:%[a-zA-Z0-9_]+]] = OpImageDrefGather %v4float [[tex1_load_2]] [[v2fc]] %float_0_5 ConstOffset [[v2ic]]
28+
// CHECK: OpStore %val [[val_2]]
29+
val = tex1.GatherCmp(float2(0.5, 0.25), 0.5, int2(1, 2));
30+
31+
// CHECK: [[tex1_load_3:%[a-zA-Z0-9_]+]] = OpLoad [[type_sampled_image_1]] [[tex1]]
32+
// CHECK: [[val_struct:%[a-zA-Z0-9_]+]] = OpImageSparseDrefGather [[type_struct_result]] [[tex1_load_3]] [[v2fc]] %float_0_5 ConstOffset [[v2ic]]
33+
// CHECK: [[status_1:%[a-zA-Z0-9_]+]] = OpCompositeExtract %uint [[val_struct]] 0
34+
// CHECK: OpStore %status [[status_1]]
35+
// CHECK: [[res_1:%[a-zA-Z0-9_]+]] = OpCompositeExtract %v4float [[val_struct]] 1
36+
// CHECK: OpStore %val [[res_1]]
37+
val = tex1.GatherCmp(float2(0.5, 0.25), 0.5, int2(1, 2), status);
38+
39+
return val;
40+
}

0 commit comments

Comments
 (0)