Skip to content
Open
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
23 changes: 19 additions & 4 deletions tools/clang/lib/SPIRV/SpirvEmitter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4693,9 +4693,11 @@ SpirvInstruction *SpirvEmitter::processBufferTextureLoad(
// The result type of an OpImageFetch must be a vec4 of float or int.
const auto type = object->getType();
assert(isBuffer(type) || isRWBuffer(type) || isTexture(type) ||
isRWTexture(type) || isSubpassInput(type) || isSubpassInputMS(type));
isRWTexture(type) || isSubpassInput(type) || isSubpassInputMS(type) ||
isSampledTexture(type));

const bool doFetch = isBuffer(type) || isTexture(type);
const bool doFetch =
isBuffer(type) || isTexture(type) || isSampledTexture(type);
const bool rasterizerOrdered = isRasterizerOrderedView(type);

if (rasterizerOrdered) {
Expand Down Expand Up @@ -4759,6 +4761,18 @@ SpirvInstruction *SpirvEmitter::processBufferTextureLoad(

// OpImageFetch and OpImageRead can only fetch a vector of 4 elements.
const QualType texelType = astContext.getExtVectorType(elemType, 4u);

if (isSampledTexture(type)) {
LowerTypeVisitor lowerTypeVisitor(astContext, spvContext, spirvOptions,
spvBuilder);
const SpirvType *spvType = lowerTypeVisitor.lowerType(
type, SpirvLayoutRule::Void, llvm::None, loc);
// Get image type based on type, assuming type is a sampledimage type
const auto *sampledImageType = cast<SampledImageType>(spvType);
const SpirvType *imgType = sampledImageType->getImageType();
objectInfo =
spvBuilder.createUnaryOp(spv::Op::OpImage, imgType, objectInfo, loc);
}
auto *texel = spvBuilder.createImageFetchOrRead(
doFetch, texelType, type, objectInfo, location, lod, constOffset,
/*constOffsets*/ nullptr, sampleNumber, residencyCode, loc, range);
Expand Down Expand Up @@ -6345,7 +6359,8 @@ SpirvEmitter::processTextureSampleCmpLevel(const CXXMemberCallExpr *expr) {
SpirvInstruction *
SpirvEmitter::processBufferTextureLoad(const CXXMemberCallExpr *expr) {
// Signature:
// For Texture1D, Texture1DArray, Texture2D, Texture2DArray, Texture3D:
// For Texture1D, Texture1DArray, Texture2D, Texture2DArray, Texture3D
// and their SampledTexture variants:
// ret Object.Load(int Location
// [, int Offset]
// [, uint status]);
Expand Down Expand Up @@ -6403,7 +6418,7 @@ SpirvEmitter::processBufferTextureLoad(const CXXMemberCallExpr *expr) {
// and 1 for location.
const bool hasOffsetArg = numArgs - hasStatusArg - textureMS - 1 > 0;

if (isTexture(objectType)) {
if (isTexture(objectType) || isSampledTexture(objectType)) {
// .Load() has a second optional paramter for offset.
SpirvInstruction *location = doExpr(locationArg);
SpirvInstruction *constOffset = nullptr, *varOffset = nullptr;
Expand Down
68 changes: 68 additions & 0 deletions tools/clang/test/CodeGenSPIRV/vk.sampledtexture.load.hlsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
// RUN: %dxc -T ps_6_7 -E main -fcgl %s -spirv | FileCheck %s

vk::SampledTexture2D<float4> tex2D_F4 : register(t1);
vk::SampledTexture2D<uint2> tex2D_U2 : register(t2);

// CHECK: OpCapability SparseResidency

// CHECK: [[v2ic:%[0-9]+]] = OpConstantComposite %v2int %int_1 %int_2

// CHECK: %type_2d_image = OpTypeImage %float 2D 0 0 0 1 Unknown
// CHECK: %type_sampled_image = OpTypeSampledImage %type_2d_image

// CHECK: %type_2d_image_0 = OpTypeImage %uint 2D 0 0 0 1 Unknown
// CHECK: %type_sampled_image_0 = OpTypeSampledImage %type_2d_image_0

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

float4 main(int3 location: A) : SV_Target {
uint status;

// CHECK: [[loc:%[0-9]+]] = OpLoad %v3int %location
// CHECK-NEXT: [[coord_0:%[0-9]+]] = OpVectorShuffle %v2int [[loc]] [[loc]] 0 1
// CHECK-NEXT: [[lod_0:%[0-9]+]] = OpCompositeExtract %int [[loc]] 2
// CHECK-NEXT: [[tex:%[0-9]+]] = OpLoad %type_sampled_image %tex2D_F4
// CHECK-NEXT: [[tex_img:%[0-9]+]] = OpImage %type_2d_image [[tex]]
// CHECK-NEXT: {{%[0-9]+}} = OpImageFetch %v4float [[tex_img]] [[coord_0]] Lod [[lod_0]]
float4 val1 = tex2D_F4.Load(location);

// CHECK: [[loc:%[0-9]+]] = OpLoad %v3int %location
// CHECK-NEXT: [[coord_0:%[0-9]+]] = OpVectorShuffle %v2int [[loc]] [[loc]] 0 1
// CHECK-NEXT: [[lod_0:%[0-9]+]] = OpCompositeExtract %int [[loc]] 2
// CHECK-NEXT: [[tex:%[0-9]+]] = OpLoad %type_sampled_image %tex2D_F4
// CHECK-NEXT: [[tex_img:%[0-9]+]] = OpImage %type_2d_image [[tex]]
// CHECK-NEXT: {{%[0-9]+}} = OpImageFetch %v4float [[tex_img]] [[coord_0]] Lod|ConstOffset [[lod_0]] [[v2ic]]
float4 val2 = tex2D_F4.Load(location, int2(1, 2));

/////////////////////////////////
/// Using the Status argument ///
/////////////////////////////////

// CHECK: [[loc:%[0-9]+]] = OpLoad %v3int %location
// CHECK-NEXT: [[coord_0:%[0-9]+]] = OpVectorShuffle %v2int [[loc]] [[loc]] 0 1
// CHECK-NEXT: [[lod_0:%[0-9]+]] = OpCompositeExtract %int [[loc]] 2
// CHECK-NEXT: [[tex:%[0-9]+]] = OpLoad %type_sampled_image %tex2D_F4
// CHECK-NEXT: [[tex_img:%[0-9]+]] = OpImage %type_2d_image [[tex]]
// CHECK-NEXT:[[structResult:%[0-9]+]] = OpImageSparseFetch %SparseResidencyStruct [[tex_img]] [[coord_0]] Lod|ConstOffset [[lod_0]] [[v2ic]]
// CHECK-NEXT: [[status:%[0-9]+]] = OpCompositeExtract %uint [[structResult]] 0
// CHECK-NEXT: OpStore %status [[status]]
// CHECK-NEXT: [[v4result:%[0-9]+]] = OpCompositeExtract %v4float [[structResult]] 1
// CHECK-NEXT: OpStore %val3 [[v4result]]
float4 val3 = tex2D_F4.Load(location, int2(1, 2), status);

// CHECK: [[loc:%[0-9]+]] = OpLoad %v3int %location
// CHECK-NEXT: [[coord_0:%[0-9]+]] = OpVectorShuffle %v2int [[loc]] [[loc]] 0 1
// CHECK-NEXT: [[lod_0:%[0-9]+]] = OpCompositeExtract %int [[loc]] 2
// CHECK-NEXT: [[tex:%[0-9]+]] = OpLoad %type_sampled_image_0 %tex2D_U2
// CHECK-NEXT: [[tex_img:%[0-9]+]] = OpImage %type_2d_image_0 [[tex]]
// CHECK-NEXT:[[structResult:%[0-9]+]] = OpImageSparseFetch %SparseResidencyStruct_0 [[tex_img]] [[coord_0]] Lod|ConstOffset [[lod_0]] [[v2ic]]
// CHECK-NEXT: [[status:%[0-9]+]] = OpCompositeExtract %uint [[structResult]] 0
// CHECK-NEXT: OpStore %status [[status]]
// CHECK-NEXT: [[v4result:%[0-9]+]] = OpCompositeExtract %v4uint [[structResult]] 1
// CHECK-NEXT: [[shuffle:%[0-9]+]] = OpVectorShuffle %v2uint [[v4result]] [[v4result]] 0 1
// CHECK-NEXT: OpStore %val4 [[shuffle]]
uint2 val4 = tex2D_U2.Load(location, int2(1, 2), status);

return 1.0;
}
3 changes: 3 additions & 0 deletions utils/hct/gen_intrin_main.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1247,4 +1247,7 @@ namespace VkSampledTexture2DMethods {
void [[]] GetDimensions(in uint x, out float_like width, out $type2 height, out $type2 levels) : resinfo;
void [[]] GetDimensions(out uint_only width, out $type1 height) : resinfo_uint_o;
void [[]] GetDimensions(out float_like width, out $type1 height) : resinfo_o;
$classT [[ro]] Load(in int<3> x) : tex2d_t_load;
$classT [[ro]] Load(in int<3> x, in int<2> o) : tex2d_t_load_o;
$classT [[]] Load(in int<3> x, in int<2> o, out uint_only status) : tex2d_t_load_o_s;
} namespace