Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions tools/clang/include/clang/SPIRV/SpirvBuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -339,6 +339,10 @@ class SpirvBuilder {

/// \brief Creates SPIR-V instructions for gathering the given image.
///
/// If the of `image` is a sampled image, then that image will be gathered.
/// In this case, `sampler` must be `nullptr`. If `image` is not a sampled
/// image, a sampled image will be created by combining `image` and `sampler`.
///
/// If compareVal is given a non-null value, OpImageDrefGather or
/// OpImageSparseDrefGather will be generated; otherwise, OpImageGather or
/// OpImageSparseGather will be generated.
Expand Down
11 changes: 9 additions & 2 deletions tools/clang/lib/SPIRV/SpirvBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -714,8 +714,15 @@ SpirvInstruction *SpirvBuilder::createImageGather(
assert(insertPoint && "null insert point");

// An OpSampledImage is required to do the image sampling.
auto *sampledImage =
createSampledImage(imageType, image, sampler, loc, range);
// Skip creating OpSampledImage if the imageType is a sampled texture.
SpirvInstruction *sampledImage = nullptr;
if (isSampledTexture(imageType)) {
assert(!sampler &&
"sampler must be null when sampling from a sampled texture");
sampledImage = image;
} else {
sampledImage = createSampledImage(imageType, image, sampler, loc, range);
}

// TODO: Update ImageGather to accept minLod if necessary.
const auto mask = composeImageOperandsMask(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// RUN: %dxc -T ps_6_8 -E main -fcgl %s -spirv | FileCheck %s

// CHECK: OpCapability ImageQuery

vk::SampledTexture2D<float4> t1 : register(t0);

// CHECK: %type_2d_image = OpTypeImage %float 2D 0 0 0 1 Unknown
// CHECK: %type_sampled_image = OpTypeSampledImage %type_2d_image
// CHECK: [[ptr:%[a-zA-Z0-9_]+]] = OpTypePointer UniformConstant %type_sampled_image

// CHECK: %t1 = OpVariable [[ptr]] UniformConstant

void main() {
float2 xy = float2(0.5, 0.5);

//CHECK: [[tex1:%[a-zA-Z0-9_]+]] = OpLoad %type_sampled_image %t1
//CHECK-NEXT: [[xy_load:%[a-zA-Z0-9_]+]] = OpLoad %v2float %xy
//CHECK-NEXT: [[query:%[a-zA-Z0-9_]+]] = OpImageQueryLod %v2float [[tex1]] [[xy_load]]
//CHECK-NEXT: {{%[0-9]+}} = OpCompositeExtract %float [[query]] 1
float lod1 = t1.CalculateLevelOfDetailUnclamped(xy);
}
42 changes: 42 additions & 0 deletions tools/clang/test/CodeGenSPIRV/vk.sampledtexture.gather.hlsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
// RUN: %dxc -T ps_6_7 -E main -fcgl %s -spirv | FileCheck %s

// CHECK: OpCapability SparseResidency

// CHECK: [[v2fc:%[0-9]+]] = OpConstantComposite %v2float %float_0_5 %float_0_25
// CHECK: [[v2ic:%[0-9]+]] = OpConstantComposite %v2int %int_2 %int_3

// CHECK: [[type_2d_image_1:%[a-zA-Z0-9_]+]] = OpTypeImage %float 2D 0 0 0 1 Unknown
// CHECK: [[type_sampled_image_1:%[a-zA-Z0-9_]+]] = OpTypeSampledImage [[type_2d_image_1]]
// CHECK: [[ptr_type_1:%[a-zA-Z0-9_]+]] = OpTypePointer UniformConstant [[type_sampled_image_1]]

// CHECK: [[type_2d_image_2:%[a-zA-Z0-9_]+]] = OpTypeImage %uint 2D 0 0 0 1 Unknown
// CHECK: [[type_sampled_image_2:%[a-zA-Z0-9_]+]] = OpTypeSampledImage [[type_2d_image_2]]
// CHECK: [[ptr_type_2:%[a-zA-Z0-9_]+]] = OpTypePointer UniformConstant [[type_sampled_image_2]]

// CHECK: %SparseResidencyStruct = OpTypeStruct %uint %v4float

// CHECK: [[tex1:%[a-zA-Z0-9_]+]] = OpVariable [[ptr_type_1]] UniformConstant
// CHECK: [[tex2:%[a-zA-Z0-9_]+]] = OpVariable [[ptr_type_2]] UniformConstant

vk::SampledTexture2D<float4> tex1 : register(t1);
vk::SampledTexture2D<uint> tex2 : register(t2);

float4 main() : SV_Target {

// CHECK: [[tex1_load:%[a-zA-Z0-9_]+]] = OpLoad [[type_sampled_image_1]] [[tex1]]
// CHECK: [[val1:%[a-zA-Z0-9_]+]] = OpImageGather %v4float [[tex1_load]] [[v2fc]] %int_0 None
float4 val1 = tex1.Gather(float2(0.5, 0.25));

// CHECK: [[tex2_load:%[a-zA-Z0-9_]+]] = OpLoad [[type_sampled_image_2]] [[tex2]]
// CHECK: [[val2:%[a-zA-Z0-9_]+]] = OpImageGather %v4uint [[tex2_load]] [[v2fc]] %int_0 ConstOffset [[v2ic]]
uint4 val2 = tex2.Gather(float2(0.5, 0.25), int2(2, 3));

// CHECK: [[tex3_load:%[a-zA-Z0-9_]+]] = OpLoad [[type_sampled_image_1]] [[tex1]]
// CHECK: [[val3:%[a-zA-Z0-9_]+]] = OpImageSparseGather %SparseResidencyStruct [[tex3_load]] [[v2fc]] %int_0 ConstOffset [[v2ic]]
// CHECK: [[status_0:%[a-zA-Z0-9_]+]] = OpCompositeExtract %uint [[val3]] 0
// CHECK: OpStore %status [[status_0]]
uint status;
float4 val3 = tex1.Gather(float2(0.5, 0.25), int2(2, 3), status);

return 1.0;
}
4 changes: 4 additions & 0 deletions utils/hct/gen_intrin_main.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1239,4 +1239,8 @@ namespace VkSampledTexture2DMethods {
$classT [[ro]] Sample(in float<2> x, in int<2> o, in float clamp) : tex2d_t_o_cl;
$classT [[]] Sample(in float<2> x, in int<2> o, in float clamp, out uint_only status) : tex2d_t_o_cl_s;
float [[ro]] CalculateLevelOfDetail(in float<2> x) : tex2d_t_calc_lod;
float [[ro]] CalculateLevelOfDetailUnclamped(in float<2> x) : tex2d_t_calc_lod_unclamped;
$match<0, -1> void<4> [[ro]] Gather(in float<2> x) : tex2d_t_gather;
$match<0, -1> void<4> [[ro]] Gather(in float<2> x, in int<2> o) : tex2d_t_gather_o;
$match<0, -1> void<4> [[]] Gather(in float<2> x, in int<2> o, out uint_only status) : tex2d_t_gather_o_s;
} namespace