[spirv] do not accept variable for OpImage* Offset (#3456)

The new spirv-val rule reports an error if we use a variable (not
OpConst*) for OpImage* Offset:
https://github.com/KhronosGroup/SPIRV-Tools/pull/4118

This CL also let the DXC SPIR-V backend report an error if it checks
the HLSL code uses a variable for the `offset` operand of `Sample*`
built-in methods.

It aligns with the DXIL or FXC behavior. They do not accept a variable
for the `offset` operand of `Sample*` built-in methods.
This commit is contained in:
Jaebaek Seo 2021-02-18 10:43:16 -05:00 коммит произвёл GitHub
Родитель 650db999f9
Коммит cff993e0f8
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
18 изменённых файлов: 153 добавлений и 126 удалений

Просмотреть файл

@ -4398,6 +4398,13 @@ SpirvInstruction *SpirvEmitter::createImageSample(
SpirvInstruction *minLod, SpirvInstruction *residencyCodeId,
SourceLocation loc) {
if (varOffset) {
emitError("Use constant value for offset (SPIR-V spec does not accept a "
"variable offset for OpImage* instructions other than "
"OpImage*Gather)", loc);
return nullptr;
}
// SampleDref* instructions in SPIR-V always return a scalar.
// They also have the correct type in HLSL.
if (compareVal) {
@ -4830,6 +4837,14 @@ SpirvEmitter::processBufferTextureLoad(const CXXMemberCallExpr *expr) {
handleOffsetInMethodCall(expr, 1, &constOffset, &varOffset);
}
if (hasOffsetArg && varOffset) {
emitError("Use constant value for offset (SPIR-V spec does not accept a "
"variable offset for OpImage* instructions other than "
"OpImage*Gather)",
expr->getArg(textureMS ? 2 : 1)->getExprLoc());
return nullptr;
}
return processBufferTextureLoad(object, coordinate, constOffset, varOffset,
lod, status, loc);
}

Просмотреть файл

@ -10,7 +10,7 @@ Texture2D<float4> t : register(t1);
float4 main(int2 offset: A) : SV_Target {
uint status;
float clamp;
float4 val = t.Sample(gSampler, float2(0.1, 0.2), offset, clamp, status);
float4 val = t.Sample(gSampler, float2(0.1, 0.2), 1, clamp, status);
// CHECK: [[residency_code:%\d+]] = OpLoad %uint %status
// CHECK: [[success:%\d+]] = OpImageSparseTexelsResident %bool [[residency_code]]

Просмотреть файл

@ -10,12 +10,12 @@ TextureCubeArray <float4> t3 : register(t3);
Texture2DArray <float> t4 : register(t4);
TextureCubeArray <float3> t5 : register(t5);
// CHECK: OpCapability ImageGatherExtended
// CHECK: OpCapability MinLod
// CHECK: OpCapability SparseResidency
// CHECK: [[v2fc:%\d+]] = OpConstantComposite %v2float %float_1 %float_1
// CHECK: [[v3fc:%\d+]] = OpConstantComposite %v3float %float_1 %float_2 %float_1
// CHECK: [[v2ic:%\d+]] = OpConstantComposite %v2int %int_1 %int_1
// CHECK: [[v4fc:%\d+]] = OpConstantComposite %v4float %float_1 %float_2 %float_3 %float_1
// CHECK: %type_sampled_image = OpTypeSampledImage %type_1d_image_array
@ -32,10 +32,9 @@ float4 main(int2 offset : A) : SV_Target {
// CHECK: [[t2:%\d+]] = OpLoad %type_2d_image_array %t2
// CHECK-NEXT: [[gSampler:%\d+]] = OpLoad %type_sampler %gSampler
// CHECK-NEXT: [[offset:%\d+]] = OpLoad %v2int %offset
// CHECK-NEXT: [[sampledImg:%\d+]] = OpSampledImage %type_sampled_image_0 [[t2]] [[gSampler]]
// CHECK-NEXT: {{%\d+}} = OpImageSampleImplicitLod %v4float [[sampledImg]] [[v3fc]] Bias|Offset %float_0_5 [[offset]]
float4 val2 = t2.SampleBias(gSampler, float3(1, 2, 1), 0.5, offset);
// CHECK-NEXT: {{%\d+}} = OpImageSampleImplicitLod %v4float [[sampledImg]] [[v3fc]] Bias|ConstOffset %float_0_5 [[v2ic]]
float4 val2 = t2.SampleBias(gSampler, float3(1, 2, 1), 0.5, 1);
// CHECK: [[t3:%\d+]] = OpLoad %type_cube_image_array %t3
// CHECK-NEXT: [[gSampler:%\d+]] = OpLoad %type_sampler %gSampler
@ -84,9 +83,9 @@ float4 main(int2 offset : A) : SV_Target {
// Make sure OpImageSparseSampleImplicitLod returns a struct, in which the second member is a vec4.
/////////////////////////////////////////////////////////////////////////////////////////////////////////
// CHECK: [[v4result:%\d+]] = OpImageSampleImplicitLod %v4float {{%\d+}} {{%\d+}} Bias|Offset %float_0_5 {{%\d+}}
// CHECK: [[v4result:%\d+]] = OpImageSampleImplicitLod %v4float {{%\d+}} {{%\d+}} Bias|ConstOffset %float_0_5 {{%\w+}}
// CHECK: {{%\d+}} = OpCompositeExtract %float [[v4result]] 0
float val8 = t4.SampleBias(gSampler, float3(1, 2, 1), 0.5, offset);
float val8 = t4.SampleBias(gSampler, float3(1, 2, 1), 0.5, 1);
// CHECK: [[structResult:%\d+]] = OpImageSparseSampleImplicitLod %SparseResidencyStruct {{%\d+}} {{%\d+}} Bias|MinLod %float_0_5 %float_2_5
// CHECK: [[v4result:%\d+]] = OpCompositeExtract %v4float [[structResult]] 1

Просмотреть файл

@ -10,6 +10,7 @@ TextureCubeArray <float> t3 : register(t3);
// CHECK: [[v2fc:%\d+]] = OpConstantComposite %v2float %float_1 %float_1
// CHECK: [[v3fc:%\d+]] = OpConstantComposite %v3float %float_1 %float_2 %float_1
// CHECK: [[v2ic:%\d+]] = OpConstantComposite %v2int %int_1 %int_1
// CHECK: [[v4fc:%\d+]] = OpConstantComposite %v4float %float_1 %float_2 %float_3 %float_1
// CHECK: %SparseResidencyStruct = OpTypeStruct %uint %float
@ -25,10 +26,9 @@ float4 main(int2 offset: A, float comparator: B) : SV_Target {
// CHECK: [[t2:%\d+]] = OpLoad %type_2d_image_array %t2
// CHECK-NEXT: [[gSampler:%\d+]] = OpLoad %type_sampler %gSampler
// CHECK-NEXT: [[comparator:%\d+]] = OpLoad %float %comparator
// CHECK-NEXT: [[offset:%\d+]] = OpLoad %v2int %offset
// CHECK-NEXT: [[sampledImg:%\d+]] = OpSampledImage %type_sampled_image_0 [[t2]] [[gSampler]]
// CHECK-NEXT: {{%\d+}} = OpImageSampleDrefExplicitLod %float [[sampledImg]] [[v3fc]] [[comparator]] Lod|Offset %float_0 [[offset]]
float val2 = t2.SampleCmpLevelZero(gSampler, float3(1, 2, 1), comparator, offset);
// CHECK-NEXT: {{%\d+}} = OpImageSampleDrefExplicitLod %float [[sampledImg]] [[v3fc]] [[comparator]] Lod|ConstOffset %float_0 [[v2ic]]
float val2 = t2.SampleCmpLevelZero(gSampler, float3(1, 2, 1), comparator, 1);
// CHECK: [[t3:%\d+]] = OpLoad %type_cube_image_array %t3
// CHECK-NEXT: [[gSampler:%\d+]] = OpLoad %type_sampler %gSampler
@ -41,14 +41,13 @@ float4 main(int2 offset: A, float comparator: B) : SV_Target {
// CHECK: [[t2:%\d+]] = OpLoad %type_2d_image_array %t2
// CHECK-NEXT: [[gSampler:%\d+]] = OpLoad %type_sampler %gSampler
// CHECK-NEXT: [[comparator:%\d+]] = OpLoad %float %comparator
// CHECK-NEXT: [[offset:%\d+]] = OpLoad %v2int %offset
// CHECK-NEXT: [[sampledImg:%\d+]] = OpSampledImage %type_sampled_image_0 [[t2]] [[gSampler]]
// CHECK-NEXT: [[structResult:%\d+]] = OpImageSparseSampleDrefExplicitLod %SparseResidencyStruct [[sampledImg]] [[v3fc]] [[comparator]] Lod|Offset %float_0 [[offset]]
// CHECK-NEXT: [[structResult:%\d+]] = OpImageSparseSampleDrefExplicitLod %SparseResidencyStruct [[sampledImg]] [[v3fc]] [[comparator]] Lod|ConstOffset %float_0 [[v2ic]]
// CHECK-NEXT: [[status:%\d+]] = OpCompositeExtract %uint [[structResult]] 0
// CHECK-NEXT: OpStore %status [[status]]
// CHECK-NEXT: [[result:%\d+]] = OpCompositeExtract %float [[structResult]] 1
// CHECK-NEXT: OpStore %val4 [[result]]
float val4 = t2.SampleCmpLevelZero(gSampler, float3(1, 2, 1), comparator, offset, status);
float val4 = t2.SampleCmpLevelZero(gSampler, float3(1, 2, 1), comparator, 1, status);
// CHECK: [[t3:%\d+]] = OpLoad %type_cube_image_array %t3
// CHECK-NEXT: [[gSampler:%\d+]] = OpLoad %type_sampler %gSampler

Просмотреть файл

@ -11,6 +11,7 @@ TextureCubeArray <float> t3 : register(t3);
// CHECK: [[v2fc:%\d+]] = OpConstantComposite %v2float %float_1 %float_1
// CHECK: [[v3fc:%\d+]] = OpConstantComposite %v3float %float_1 %float_2 %float_1
// CHECK: [[v2ic:%\d+]] = OpConstantComposite %v2int %int_1 %int_1
// CHECK: [[v4fc:%\d+]] = OpConstantComposite %v4float %float_1 %float_2 %float_3 %float_1
// CHECK: %SparseResidencyStruct = OpTypeStruct %uint %float
@ -26,10 +27,9 @@ float4 main(int2 offset: A, float comparator: B) : SV_Target {
// CHECK: [[t2:%\d+]] = OpLoad %type_2d_image_array %t2
// CHECK-NEXT: [[gSampler:%\d+]] = OpLoad %type_sampler %gSampler
// CHECK-NEXT: [[comparator:%\d+]] = OpLoad %float %comparator
// CHECK-NEXT: [[offset:%\d+]] = OpLoad %v2int %offset
// CHECK-NEXT: [[sampledImg:%\d+]] = OpSampledImage %type_sampled_image_0 [[t2]] [[gSampler]]
// CHECK-NEXT: {{%\d+}} = OpImageSampleDrefImplicitLod %float [[sampledImg]] [[v3fc]] [[comparator]] Offset [[offset]]
float val2 = t2.SampleCmp(gSampler, float3(1, 2, 1), comparator, offset);
// CHECK-NEXT: {{%\d+}} = OpImageSampleDrefImplicitLod %float [[sampledImg]] [[v3fc]] [[comparator]] ConstOffset [[v2ic]]
float val2 = t2.SampleCmp(gSampler, float3(1, 2, 1), comparator, 1);
// CHECK: [[t3:%\d+]] = OpLoad %type_cube_image_array %t3
// CHECK-NEXT: [[gSampler:%\d+]] = OpLoad %type_sampler %gSampler
@ -43,10 +43,9 @@ float4 main(int2 offset: A, float comparator: B) : SV_Target {
// CHECK-NEXT: [[t2:%\d+]] = OpLoad %type_2d_image_array %t2
// CHECK-NEXT: [[gSampler:%\d+]] = OpLoad %type_sampler %gSampler
// CHECK-NEXT: [[comparator:%\d+]] = OpLoad %float %comparator
// CHECK-NEXT: [[offset:%\d+]] = OpLoad %v2int %offset
// CHECK-NEXT: [[sampledImg:%\d+]] = OpSampledImage %type_sampled_image_0 [[t2]] [[gSampler]]
// CHECK-NEXT: {{%\d+}} = OpImageSampleDrefImplicitLod %float [[sampledImg]] [[v3fc]] [[comparator]] Offset|MinLod [[offset]] [[clamp]]
float val4 = t2.SampleCmp(gSampler, float3(1, 2, 1), comparator, offset, clamp);
// CHECK-NEXT: {{%\d+}} = OpImageSampleDrefImplicitLod %float [[sampledImg]] [[v3fc]] [[comparator]] ConstOffset|MinLod [[v2ic]] [[clamp]]
float val4 = t2.SampleCmp(gSampler, float3(1, 2, 1), comparator, 1, clamp);
// CHECK: [[t3:%\d+]] = OpLoad %type_cube_image_array %t3
// CHECK-NEXT: [[gSampler:%\d+]] = OpLoad %type_sampler %gSampler
@ -60,14 +59,13 @@ float4 main(int2 offset: A, float comparator: B) : SV_Target {
// CHECK-NEXT: [[t2:%\d+]] = OpLoad %type_2d_image_array %t2
// CHECK-NEXT: [[gSampler:%\d+]] = OpLoad %type_sampler %gSampler
// CHECK-NEXT: [[comparator:%\d+]] = OpLoad %float %comparator
// CHECK-NEXT: [[offset:%\d+]] = OpLoad %v2int %offset
// CHECK-NEXT: [[sampledImg:%\d+]] = OpSampledImage %type_sampled_image_0 [[t2]] [[gSampler]]
// CHECK-NEXT: [[structResult:%\d+]] = OpImageSparseSampleDrefImplicitLod %SparseResidencyStruct [[sampledImg]] [[v3fc]] [[comparator]] Offset|MinLod [[offset]] [[clamp]]
// CHECK-NEXT: [[structResult:%\d+]] = OpImageSparseSampleDrefImplicitLod %SparseResidencyStruct [[sampledImg]] [[v3fc]] [[comparator]] ConstOffset|MinLod [[v2ic]] [[clamp]]
// CHECK-NEXT: [[status:%\d+]] = OpCompositeExtract %uint [[structResult]] 0
// CHECK-NEXT: OpStore %status [[status]]
// CHECK-NEXT: [[result:%\d+]] = OpCompositeExtract %float [[structResult]] 1
// CHECK-NEXT: OpStore %val6 [[result]]
float val6 = t2.SampleCmp(gSampler, float3(1, 2, 1), comparator, offset, clamp, status);
float val6 = t2.SampleCmp(gSampler, float3(1, 2, 1), comparator, 1, clamp, status);
// CHECK: [[t3:%\d+]] = OpLoad %type_cube_image_array %t3
// CHECK-NEXT: [[gSampler:%\d+]] = OpLoad %type_sampler %gSampler

Просмотреть файл

@ -11,7 +11,6 @@ Texture2DArray <float> t4 : register(t4);
TextureCubeArray <float2> t5 : register(t5);
// CHECK: OpCapability ImageGatherExtended
// CHECK: OpCapability MinLod
// CHECK: OpCapability SparseResidency
@ -19,6 +18,7 @@ TextureCubeArray <float2> t5 : register(t5);
// CHECK: [[v3f_1:%\d+]] = OpConstantComposite %v3float %float_1 %float_1 %float_1
// CHECK: [[v2f_2:%\d+]] = OpConstantComposite %v2float %float_2 %float_2
// CHECK: [[v2f_3:%\d+]] = OpConstantComposite %v2float %float_3 %float_3
// CHECK: [[v2i_1:%\d+]] = OpConstantComposite %v2int %int_1 %int_1
// CHECK: [[v4f_1:%\d+]] = OpConstantComposite %v4float %float_1 %float_1 %float_1 %float_1
// CHECK: [[v3f_2:%\d+]] = OpConstantComposite %v3float %float_2 %float_2 %float_2
// CHECK: [[v3f_3:%\d+]] = OpConstantComposite %v3float %float_3 %float_3 %float_3
@ -37,10 +37,9 @@ float4 main(int2 offset : A) : SV_Target {
// CHECK: [[t2:%\d+]] = OpLoad %type_2d_image_array %t2
// CHECK-NEXT: [[gSampler:%\d+]] = OpLoad %type_sampler %gSampler
// CHECK-NEXT: [[offset:%\d+]] = OpLoad %v2int %offset
// CHECK-NEXT: [[sampledImg:%\d+]] = OpSampledImage %type_sampled_image_0 [[t2]] [[gSampler]]
// CHECK-NEXT: {{%\d+}} = OpImageSampleExplicitLod %v4float [[sampledImg]] [[v3f_1]] Grad|Offset [[v2f_2]] [[v2f_3]] [[offset]]
float4 val2 = t2.SampleGrad(gSampler, float3(1, 1, 1), float2(2, 2), float2(3, 3), offset);
// CHECK-NEXT: {{%\d+}} = OpImageSampleExplicitLod %v4float [[sampledImg]] [[v3f_1]] Grad|ConstOffset [[v2f_2]] [[v2f_3]] [[v2i_1]]
float4 val2 = t2.SampleGrad(gSampler, float3(1, 1, 1), float2(2, 2), float2(3, 3), 1);
// CHECK: [[t3:%\d+]] = OpLoad %type_cube_image_array %t3
// CHECK-NEXT: [[gSampler:%\d+]] = OpLoad %type_sampler %gSampler
@ -50,10 +49,9 @@ float4 main(int2 offset : A) : SV_Target {
// CHECK: [[t2:%\d+]] = OpLoad %type_2d_image_array %t2
// CHECK-NEXT: [[gSampler:%\d+]] = OpLoad %type_sampler %gSampler
// CHECK-NEXT: [[offset:%\d+]] = OpLoad %v2int %offset
// CHECK-NEXT: [[sampledImg:%\d+]] = OpSampledImage %type_sampled_image_0 [[t2]] [[gSampler]]
// CHECK-NEXT: {{%\d+}} = OpImageSampleExplicitLod %v4float [[sampledImg]] [[v3f_1]] Grad|Offset|MinLod [[v2f_2]] [[v2f_3]] [[offset]] %float_2_5
float4 val4 = t2.SampleGrad(gSampler, float3(1, 1, 1), float2(2, 2), float2(3, 3), offset, /*clamp*/2.5);
// CHECK-NEXT: {{%\d+}} = OpImageSampleExplicitLod %v4float [[sampledImg]] [[v3f_1]] Grad|ConstOffset|MinLod [[v2f_2]] [[v2f_3]] [[v2i_1]] %float_2_5
float4 val4 = t2.SampleGrad(gSampler, float3(1, 1, 1), float2(2, 2), float2(3, 3), 1, /*clamp*/2.5);
float clamp;
// CHECK: [[clamp:%\d+]] = OpLoad %float %clamp
@ -66,14 +64,13 @@ float4 main(int2 offset : A) : SV_Target {
uint status;
// CHECK: [[t2:%\d+]] = OpLoad %type_2d_image_array %t2
// CHECK-NEXT: [[gSampler:%\d+]] = OpLoad %type_sampler %gSampler
// CHECK-NEXT: [[offset:%\d+]] = OpLoad %v2int %offset
// CHECK-NEXT: [[sampledImg:%\d+]] = OpSampledImage %type_sampled_image_0 [[t2]] [[gSampler]]
// CHECK-NEXT: [[structResult:%\d+]] = OpImageSparseSampleExplicitLod %SparseResidencyStruct [[sampledImg]] [[v3f_1]] Grad|Offset|MinLod [[v2f_2]] [[v2f_3]] [[offset]] %float_2_5
// CHECK-NEXT: [[structResult:%\d+]] = OpImageSparseSampleExplicitLod %SparseResidencyStruct [[sampledImg]] [[v3f_1]] Grad|ConstOffset|MinLod [[v2f_2]] [[v2f_3]] [[v2i_1]] %float_2_5
// CHECK-NEXT: [[status:%\d+]] = OpCompositeExtract %uint [[structResult]] 0
// CHECK-NEXT: OpStore %status [[status]]
// CHECK-NEXT: [[result:%\d+]] = OpCompositeExtract %v4float [[structResult]] 1
// CHECK-NEXT: OpStore %val6 [[result]]
float4 val6 = t2.SampleGrad(gSampler, float3(1, 1, 1), float2(2, 2), float2(3, 3), offset, /*clamp*/2.5, status);
float4 val6 = t2.SampleGrad(gSampler, float3(1, 1, 1), float2(2, 2), float2(3, 3), 1, /*clamp*/2.5, status);
// CHECK: [[clamp:%\d+]] = OpLoad %float %clamp
// CHECK-NEXT: [[t3:%\d+]] = OpLoad %type_cube_image_array %t3
@ -91,9 +88,9 @@ float4 main(int2 offset : A) : SV_Target {
// Make sure OpImageSparseSampleExplicitLod returns a struct, in which the second member is a vec4.
/////////////////////////////////////////////////////////////////////////////////////////////////////////
// CHECK: [[v4result:%\d+]] = OpImageSampleExplicitLod %v4float {{%\d+}} {{%\d+}} Grad|Offset {{%\d+}} {{%\d+}} {{%\d+}}
// CHECK: [[v4result:%\d+]] = OpImageSampleExplicitLod %v4float {{%\d+}} {{%\d+}} Grad|ConstOffset {{%\d+}} {{%\d+}} {{%\w+}}
// CHECK: {{%\d+}} = OpCompositeExtract %float [[v4result]] 0
float val8 = t4.SampleGrad(gSampler, float3(1, 1, 1), float2(2, 2), float2(3, 3), offset);
float val8 = t4.SampleGrad(gSampler, float3(1, 1, 1), float2(2, 2), float2(3, 3), 1);
// CHECK: [[structResult:%\d+]] = OpImageSparseSampleExplicitLod %SparseResidencyStruct {{%\d+}} {{%\d+}} Grad|MinLod {{%\d+}} {{%\d+}} {{%\d+}}
// CHECK: [[v4result:%\d+]] = OpCompositeExtract %v4float [[structResult]] 1

Просмотреть файл

@ -10,7 +10,6 @@ TextureCubeArray <float4> t3 : register(t3);
Texture2DArray <float> t4 : register(t4);
TextureCubeArray <float3> t5 : register(t5);
// CHECK: OpCapability ImageGatherExtended
// CHECK: OpCapability SparseResidency
// CHECK: [[v2fc:%\d+]] = OpConstantComposite %v2float %float_1 %float_1
@ -31,10 +30,9 @@ float4 main(int2 offset : A) : SV_Target {
// CHECK: [[t2:%\d+]] = OpLoad %type_2d_image_array %t2
// CHECK-NEXT: [[gSampler:%\d+]] = OpLoad %type_sampler %gSampler
// CHECK-NEXT: [[offset:%\d+]] = OpLoad %v2int %offset
// CHECK-NEXT: [[sampledImg:%\d+]] = OpSampledImage %type_sampled_image_0 [[t2]] [[gSampler]]
// CHECK-NEXT: {{%\d+}} = OpImageSampleExplicitLod %v4float [[sampledImg]] [[v3fc]] Lod|Offset %float_20 [[offset]]
float4 val2 = t2.SampleLevel(gSampler, float3(1, 2, 1), 20, offset);
// CHECK-NEXT: {{%\d+}} = OpImageSampleExplicitLod %v4float [[sampledImg]] [[v3fc]] Lod|ConstOffset %float_20
float4 val2 = t2.SampleLevel(gSampler, float3(1, 2, 1), 20, 1);
// CHECK: [[t3:%\d+]] = OpLoad %type_cube_image_array %t3
// CHECK-NEXT: [[gSampler:%\d+]] = OpLoad %type_sampler %gSampler
@ -45,14 +43,13 @@ float4 main(int2 offset : A) : SV_Target {
uint status;
// CHECK: [[t2:%\d+]] = OpLoad %type_2d_image_array %t2
// CHECK-NEXT: [[gSampler:%\d+]] = OpLoad %type_sampler %gSampler
// CHECK-NEXT: [[offset:%\d+]] = OpLoad %v2int %offset
// CHECK-NEXT: [[sampledImg:%\d+]] = OpSampledImage %type_sampled_image_0 [[t2]] [[gSampler]]
// CHECK-NEXT: [[structResult:%\d+]] = OpImageSparseSampleExplicitLod %SparseResidencyStruct [[sampledImg]] [[v3fc]] Lod|Offset %float_20 [[offset]]
// CHECK-NEXT: [[structResult:%\d+]] = OpImageSparseSampleExplicitLod %SparseResidencyStruct [[sampledImg]] [[v3fc]] Lod|ConstOffset %float_20
// CHECK-NEXT: [[status:%\d+]] = OpCompositeExtract %uint [[structResult]] 0
// CHECK-NEXT: OpStore %status [[status]]
// CHECK-NEXT: [[result:%\d+]] = OpCompositeExtract %v4float [[structResult]] 1
// CHECK-NEXT: OpStore %val4 [[result]]
float4 val4 = t2.SampleLevel(gSampler, float3(1, 2, 1), 20, offset, status);
float4 val4 = t2.SampleLevel(gSampler, float3(1, 2, 1), 20, 1, status);
// CHECK: [[t3:%\d+]] = OpLoad %type_cube_image_array %t3
// CHECK-NEXT: [[gSampler:%\d+]] = OpLoad %type_sampler %gSampler
@ -69,9 +66,9 @@ float4 main(int2 offset : A) : SV_Target {
// Make sure OpImageSparseSampleExplicitLod returns a struct, in which the second member is a vec4.
/////////////////////////////////////////////////////////////////////////////////////////////////////////
// CHECK: [[v4result:%\d+]] = OpImageSampleExplicitLod %v4float {{%\d+}} {{%\d+}} Lod|Offset %float_20 {{%\d+}}
// CHECK: [[v4result:%\d+]] = OpImageSampleExplicitLod %v4float {{%\d+}} {{%\d+}} Lod|ConstOffset %float_20
// CHECK: {{%\d+}} = OpCompositeExtract %float [[v4result]] 0
float val6 = t4.SampleLevel(gSampler, float3(1, 2, 1), 20, offset);
float val6 = t4.SampleLevel(gSampler, float3(1, 2, 1), 20, 1);
// CHECK: [[structResult:%\d+]] = OpImageSparseSampleExplicitLod %SparseResidencyStruct {{%\d+}} {{%\d+}} Lod %float_30
// CHECK: [[v4result:%\d+]] = OpCompositeExtract %v4float [[structResult]] 1

Просмотреть файл

@ -0,0 +1,20 @@
// Run: %dxc -T ps_6_0 -E main
Texture1D <float4> t1 : register(t1);
Texture2DMS <float> t2 : register(t2);
float4 main(int3 location: A, int offset: B) : SV_Target {
uint status;
// CHECK: Use constant value for offset (SPIR-V spec does not accept a variable offset for OpImage* instructions other than OpImage*Gather)
float4 val1 = t1.Load(int2(1, 2), offset);
int sampleIndex = 7;
int2 pos2 = int2(2, 3);
int2 offset2 = int2(1, 2);
// CHECK: Use constant value for offset (SPIR-V spec does not accept a variable offset for OpImage* instructions other than OpImage*Gather)
float val2 = t2.Load(pos2, sampleIndex, offset2);
return 1.0;
}

Просмотреть файл

@ -12,7 +12,6 @@ Texture3D <uint3> t6 : register(t6);
Texture2DMS <float> t7 : register(t7);
Texture2DMSArray<float3> t8 : register(t8);
// CHECK: OpCapability ImageGatherExtended
// CHECK: OpCapability SparseResidency
// CHECK: [[v2ic:%\d+]] = OpConstantComposite %v2int %int_1 %int_2
@ -28,10 +27,9 @@ float4 main(int3 location: A, int offset: B) : SV_Target {
// CHECK: [[coord:%\d+]] = OpCompositeExtract %int [[v2ic]] 0
// CHECK-NEXT: [[lod:%\d+]] = OpCompositeExtract %int [[v2ic]] 1
// CHECK-NEXT:[[offset:%\d+]] = OpLoad %int %offset
// CHECK-NEXT: [[t1:%\d+]] = OpLoad %type_1d_image %t1
// CHECK-NEXT: {{%\d+}} = OpImageFetch %v4float [[t1]] [[coord]] Lod|Offset [[lod]] [[offset]]
float4 val1 = t1.Load(int2(1, 2), offset);
// CHECK-NEXT: {{%\d+}} = OpImageFetch %v4float [[t1]] [[coord]] Lod|ConstOffset [[lod]] %int_1
float4 val1 = t1.Load(int2(1, 2), 1);
// CHECK: [[loc:%\d+]] = OpLoad %v3int %location
// CHECK-NEXT: [[coord:%\d+]] = OpVectorShuffle %v2int [[loc]] [[loc]] 0 1
@ -46,9 +44,9 @@ float4 main(int3 location: A, int offset: B) : SV_Target {
// CHECK-NEXT: {{%\d+}} = OpImageFetch %v4float [[t3]] [[coord]] Lod|ConstOffset [[lod]] [[v3ic]]
float4 val3 = t3.Load(int4(1, 2, 3, 4), 3);
// CHECK: [[f4:%\d+]] = OpImageFetch %v4float {{%\d+}} {{%\d+}} Lod|Offset {{%\d+}} {{%\d+}}
// CHECK: [[f4:%\d+]] = OpImageFetch %v4float {{%\d+}} {{%\d+}} Lod|ConstOffset {{%\d+}} %int_1
// CHECK-NEXT: {{%\d+}} = OpCompositeExtract %float [[f4]] 0
float val4 = t4.Load(int2(1,2), offset);
float val4 = t4.Load(int2(1,2), 1);
// CHECK: [[f5:%\d+]] = OpImageFetch %v4int {{%\d+}} {{%\d+}} Lod|ConstOffset {{%\d+}} {{%\d+}}
// CHECK-NEXT: {{%\d+}} = OpVectorShuffle %v2int [[f5]] [[f5]] 0 1
@ -74,11 +72,10 @@ float4 main(int3 location: A, int offset: B) : SV_Target {
// CHECK: [[pos1:%\d+]] = OpLoad %v2int %pos2
// CHECK-NEXT: [[si1:%\d+]] = OpLoad %int %sampleIndex
// CHECK-NEXT:[[offset2:%\d+]] = OpLoad %v2int %offset2
// CHECK-NEXT: [[t71:%\d+]] = OpLoad %type_2d_image_1 %t7
// CHECK-NEXT: [[f71:%\d+]] = OpImageFetch %v4float [[t71]] [[pos1]] Offset|Sample [[offset2]] [[si1]]
// CHECK-NEXT: [[f71:%\d+]] = OpImageFetch %v4float [[t71]] [[pos1]] ConstOffset|Sample [[v2ic]] [[si1]]
// CHECK-NEXT: {{%\d+}} = OpCompositeExtract %float [[f71]] 0
val7 = t7.Load(pos2, sampleIndex, offset2);
val7 = t7.Load(pos2, sampleIndex, int2(1, 2));
// CHECK: [[pos2:%\d+]] = OpLoad %v3int %pos3
// CHECK-NEXT: [[si2:%\d+]] = OpLoad %int %sampleIndex
@ -100,15 +97,14 @@ float4 main(int3 location: A, int offset: B) : SV_Target {
// CHECK: [[coord:%\d+]] = OpCompositeExtract %int [[v2ic]] 0
// CHECK-NEXT: [[lod:%\d+]] = OpCompositeExtract %int [[v2ic]] 1
// CHECK-NEXT: [[offset:%\d+]] = OpLoad %int %offset
// CHECK-NEXT: [[t4:%\d+]] = OpLoad %type_1d_image %t4
// CHECK-NEXT:[[structResult:%\d+]] = OpImageSparseFetch %SparseResidencyStruct [[t4]] [[coord]] Lod|Offset [[lod]] [[offset]]
// CHECK-NEXT:[[structResult:%\d+]] = OpImageSparseFetch %SparseResidencyStruct [[t4]] [[coord]] Lod|ConstOffset [[lod]] %int_1
// CHECK-NEXT: [[status:%\d+]] = OpCompositeExtract %uint [[structResult]] 0
// CHECK-NEXT: OpStore %status [[status]]
// CHECK-NEXT: [[v4result:%\d+]] = OpCompositeExtract %v4float [[structResult]] 1
// CHECK-NEXT: [[result:%\d+]] = OpCompositeExtract %float [[v4result]] 0
// CHECK-NEXT: OpStore %val14 [[result]]
float val14 = t4.Load(int2(1,2), offset, status);
float val14 = t4.Load(int2(1,2), 1, status);
// CHECK: [[loc:%\d+]] = OpLoad %v3int %location
// CHECK-NEXT: [[coord:%\d+]] = OpVectorShuffle %v2int [[loc]] [[loc]] 0 1
@ -135,15 +131,14 @@ float4 main(int3 location: A, int offset: B) : SV_Target {
// CHECK: [[pos1:%\d+]] = OpLoad %v2int %pos2
// CHECK-NEXT: [[si1:%\d+]] = OpLoad %int %sampleIndex
// CHECK-NEXT: [[offset2:%\d+]] = OpLoad %v2int %offset2
// CHECK-NEXT: [[t71:%\d+]] = OpLoad %type_2d_image_1 %t7
// CHECK-NEXT:[[structResult:%\d+]] = OpImageSparseFetch %SparseResidencyStruct [[t71]] [[pos1]] Offset|Sample [[offset2]] [[si1]]
// CHECK-NEXT:[[structResult:%\d+]] = OpImageSparseFetch %SparseResidencyStruct [[t71]] [[pos1]] ConstOffset|Sample [[v2ic]] [[si1]]
// CHECK-NEXT: [[status:%\d+]] = OpCompositeExtract %uint [[structResult]] 0
// CHECK-NEXT: OpStore %status [[status]]
// CHECK-NEXT: [[v4result:%\d+]] = OpCompositeExtract %v4float [[structResult]] 1
// CHECK-NEXT: [[result:%\d+]] = OpCompositeExtract %float [[v4result]] 0
// CHECK-NEXT: OpStore %val17 [[result]]
float val17 = t7.Load(pos2, sampleIndex, offset2, status);
float val17 = t7.Load(pos2, sampleIndex, int2(1,2), status);
// CHECK: [[pos3:%\d+]] = OpLoad %v3int %pos3
// CHECK-NEXT: [[si3:%\d+]] = OpLoad %int %sampleIndex

Просмотреть файл

@ -11,13 +11,13 @@ TextureCube <float4> t4 : register(t4);
Texture1D <float> t5 : register(t5);
Texture3D <float2> t6 : register(t6);
// CHECK: OpCapability ImageGatherExtended
// CHECK: OpCapability MinLod
// CHECK: OpCapability SparseResidency
// CHECK: [[v2fc:%\d+]] = OpConstantComposite %v2float %float_1 %float_2
// CHECK: [[v2ic:%\d+]] = OpConstantComposite %v2int %int_2 %int_2
// CHECK: [[v3fc:%\d+]] = OpConstantComposite %v3float %float_1 %float_2 %float_3
// CHECK: [[v3ic:%\d+]] = OpConstantComposite %v3int %int_1 %int_1 %int_1
// CHECK: %type_sampled_image = OpTypeSampledImage %type_1d_image
// CHECK: %type_sampled_image_0 = OpTypeSampledImage %type_2d_image
@ -40,10 +40,9 @@ float4 main(int3 offset: A) : SV_Target {
// CHECK: [[t3:%\d+]] = OpLoad %type_3d_image %t3
// CHECK-NEXT: [[gSampler:%\d+]] = OpLoad %type_sampler %gSampler
// CHECK-NEXT: [[offset:%\d+]] = OpLoad %v3int %offset
// CHECK-NEXT: [[sampledImg:%\d+]] = OpSampledImage %type_sampled_image_1 [[t3]] [[gSampler]]
// CHECK-NEXT: {{%\d+}} = OpImageSampleImplicitLod %v4float [[sampledImg]] [[v3fc]] Bias|Offset %float_0_5 [[offset]]
float4 val3 = t3.SampleBias(gSampler, float3(1, 2, 3), 0.5, offset);
// CHECK-NEXT: {{%\d+}} = OpImageSampleImplicitLod %v4float [[sampledImg]] [[v3fc]] Bias|ConstOffset %float_0_5 [[v3ic]]
float4 val3 = t3.SampleBias(gSampler, float3(1, 2, 3), 0.5, 1);
// CHECK: [[t4:%\d+]] = OpLoad %type_cube_image %t4
// CHECK-NEXT: [[gSampler:%\d+]] = OpLoad %type_sampler %gSampler
@ -55,10 +54,9 @@ float4 main(int3 offset: A) : SV_Target {
// CHECK: [[clamp:%\d+]] = OpLoad %float %clamp
// CHECK-NEXT: [[t3:%\d+]] = OpLoad %type_3d_image %t3
// CHECK-NEXT: [[gSampler:%\d+]] = OpLoad %type_sampler %gSampler
// CHECK-NEXT: [[offset:%\d+]] = OpLoad %v3int %offset
// CHECK-NEXT: [[sampledImg:%\d+]] = OpSampledImage %type_sampled_image_1 [[t3]] [[gSampler]]
// CHECK-NEXT: {{%\d+}} = OpImageSampleImplicitLod %v4float [[sampledImg]] [[v3fc]] Bias|Offset|MinLod %float_0_5 [[offset]] [[clamp]]
float4 val5 = t3.SampleBias(gSampler, float3(1, 2, 3), 0.5, offset, clamp);
// CHECK-NEXT: {{%\d+}} = OpImageSampleImplicitLod %v4float [[sampledImg]] [[v3fc]] Bias|ConstOffset|MinLod %float_0_5 [[v3ic]] [[clamp]]
float4 val5 = t3.SampleBias(gSampler, float3(1, 2, 3), 0.5, 1, clamp);
// CHECK: [[t4:%\d+]] = OpLoad %type_cube_image %t4
// CHECK-NEXT: [[gSampler:%\d+]] = OpLoad %type_sampler %gSampler
@ -70,14 +68,13 @@ float4 main(int3 offset: A) : SV_Target {
// CHECK: [[clamp:%\d+]] = OpLoad %float %clamp
// CHECK-NEXT: [[t3:%\d+]] = OpLoad %type_3d_image %t3
// CHECK-NEXT: [[gSampler:%\d+]] = OpLoad %type_sampler %gSampler
// CHECK-NEXT: [[offset:%\d+]] = OpLoad %v3int %offset
// CHECK-NEXT: [[sampledImg:%\d+]] = OpSampledImage %type_sampled_image_1 [[t3]] [[gSampler]]
// CHECK-NEXT: [[structResult:%\d+]] = OpImageSparseSampleImplicitLod %SparseResidencyStruct [[sampledImg]] [[v3fc]] Bias|Offset|MinLod %float_0_5 [[offset]] [[clamp]]
// CHECK-NEXT: [[structResult:%\d+]] = OpImageSparseSampleImplicitLod %SparseResidencyStruct [[sampledImg]] [[v3fc]] Bias|ConstOffset|MinLod %float_0_5 [[v3ic]] [[clamp]]
// CHECK-NEXT: [[status:%\d+]] = OpCompositeExtract %uint [[structResult]] 0
// CHECK-NEXT: OpStore %status [[status]]
// CHECK-NEXT: [[result:%\d+]] = OpCompositeExtract %v4float [[structResult]] 1
// CHECK-NEXT: OpStore %val7 [[result]]
float4 val7 = t3.SampleBias(gSampler, float3(1, 2, 3), 0.5, offset, clamp, status);
float4 val7 = t3.SampleBias(gSampler, float3(1, 2, 3), 0.5, 1, clamp, status);
// CHECK: [[t4:%\d+]] = OpLoad %type_cube_image %t4
// CHECK-NEXT: [[gSampler:%\d+]] = OpLoad %type_sampler %gSampler
@ -98,10 +95,10 @@ float4 main(int3 offset: A) : SV_Target {
// CHECK: {{%\d+}} = OpCompositeExtract %float [[v4result]] 0
float val9 = t5.SampleBias(gSampler, 1, 0.5);
// CHECK: [[structResult:%\d+]] = OpImageSparseSampleImplicitLod %SparseResidencyStruct {{%\d+}} {{%\d+}} Bias|Offset|MinLod %float_0_5 {{%\d+}} {{%\d+}}
// CHECK: [[structResult:%\d+]] = OpImageSparseSampleImplicitLod %SparseResidencyStruct {{%\d+}} {{%\d+}} Bias|ConstOffset|MinLod %float_0_5 {{%\d+}} {{%\d+}}
// CHECK: [[v4result:%\d+]] = OpCompositeExtract %v4float [[structResult]] 1
// CHECK: {{%\d+}} = OpVectorShuffle %v2float [[v4result]] [[v4result]] 0 1
float2 val10 = t6.SampleBias(gSampler, float3(1, 2, 3), 0.5, offset, clamp, status);
float2 val10 = t6.SampleBias(gSampler, float3(1, 2, 3), 0.5, 1, clamp, status);
return 1.0;
}

Просмотреть файл

@ -10,6 +10,7 @@ TextureCube <float> t4 : register(t4);
// CHECK: OpCapability SparseResidency
// CHECK: [[v2fc:%\d+]] = OpConstantComposite %v2float %float_1 %float_2
// CHECK: [[v2ic:%\d+]] = OpConstantComposite %v2int %int_1 %int_1
// CHECK: [[v3fc:%\d+]] = OpConstantComposite %v3float %float_1 %float_2 %float_3
// CHECK: %SparseResidencyStruct = OpTypeStruct %uint %float
@ -25,10 +26,9 @@ float4 main(int2 offset: A, float comparator: B) : SV_Target {
// CHECK: [[t2:%\d+]] = OpLoad %type_2d_image %t2
// CHECK-NEXT: [[gSampler:%\d+]] = OpLoad %type_sampler %gSampler
// CHECK-NEXT: [[comparator:%\d+]] = OpLoad %float %comparator
// CHECK-NEXT: [[offset:%\d+]] = OpLoad %v2int %offset
// CHECK-NEXT: [[sampledImg:%\d+]] = OpSampledImage %type_sampled_image_0 [[t2]] [[gSampler]]
// CHECK-NEXT: {{%\d+}} = OpImageSampleDrefExplicitLod %float [[sampledImg]] [[v2fc]] [[comparator]] Lod|Offset %float_0 [[offset]]
float val2 = t2.SampleCmpLevelZero(gSampler, float2(1, 2), comparator, offset);
// CHECK-NEXT: {{%\d+}} = OpImageSampleDrefExplicitLod %float [[sampledImg]] [[v2fc]] [[comparator]] Lod|ConstOffset %float_0 [[v2ic]]
float val2 = t2.SampleCmpLevelZero(gSampler, float2(1, 2), comparator, 1);
// CHECK: [[t4:%\d+]] = OpLoad %type_cube_image %t4
// CHECK-NEXT: [[gSampler:%\d+]] = OpLoad %type_sampler %gSampler
@ -41,14 +41,13 @@ float4 main(int2 offset: A, float comparator: B) : SV_Target {
// CHECK: [[t2:%\d+]] = OpLoad %type_2d_image %t2
// CHECK-NEXT: [[gSampler:%\d+]] = OpLoad %type_sampler %gSampler
// CHECK-NEXT: [[comparator:%\d+]] = OpLoad %float %comparator
// CHECK-NEXT: [[offset:%\d+]] = OpLoad %v2int %offset
// CHECK-NEXT: [[sampledImg:%\d+]] = OpSampledImage %type_sampled_image_0 [[t2]] [[gSampler]]
// CHECK-NEXT: [[structResult:%\d+]] = OpImageSparseSampleDrefExplicitLod %SparseResidencyStruct [[sampledImg]] [[v2fc]] [[comparator]] Lod|Offset %float_0 [[offset]]
// CHECK-NEXT: [[structResult:%\d+]] = OpImageSparseSampleDrefExplicitLod %SparseResidencyStruct [[sampledImg]] [[v2fc]] [[comparator]] Lod|ConstOffset %float_0 [[v2ic]]
// CHECK-NEXT: [[status:%\d+]] = OpCompositeExtract %uint [[structResult]] 0
// CHECK-NEXT: OpStore %status [[status]]
// CHECK-NEXT: [[result:%\d+]] = OpCompositeExtract %float [[structResult]] 1
// CHECK-NEXT: OpStore %val5 [[result]]
float val5 = t2.SampleCmpLevelZero(gSampler, float2(1, 2), comparator, offset, status);
float val5 = t2.SampleCmpLevelZero(gSampler, float2(1, 2), comparator, 1, status);
// CHECK: [[t4:%\d+]] = OpLoad %type_cube_image %t4
// CHECK-NEXT: [[gSampler:%\d+]] = OpLoad %type_sampler %gSampler

Просмотреть файл

@ -11,6 +11,7 @@ TextureCube <float> t4 : register(t4);
// CHECK: OpCapability SparseResidency
// CHECK: [[v2fc:%\d+]] = OpConstantComposite %v2float %float_1 %float_2
// CHECK: [[v2ic:%\d+]] = OpConstantComposite %v2int %int_1 %int_1
// CHECK: [[v3fc:%\d+]] = OpConstantComposite %v3float %float_1 %float_2 %float_3
// CHECK: %SparseResidencyStruct = OpTypeStruct %uint %float
@ -26,10 +27,9 @@ float4 main(int2 offset: A, float comparator: B) : SV_Target {
// CHECK: [[t2:%\d+]] = OpLoad %type_2d_image %t2
// CHECK-NEXT: [[gSampler:%\d+]] = OpLoad %type_sampler %gSampler
// CHECK-NEXT: [[comparator:%\d+]] = OpLoad %float %comparator
// CHECK-NEXT: [[offset:%\d+]] = OpLoad %v2int %offset
// CHECK-NEXT: [[sampledImg:%\d+]] = OpSampledImage %type_sampled_image_0 [[t2]] [[gSampler]]
// CHECK-NEXT: {{%\d+}} = OpImageSampleDrefImplicitLod %float [[sampledImg]] [[v2fc]] [[comparator]] Offset [[offset]]
float val2 = t2.SampleCmp(gSampler, float2(1, 2), comparator, offset);
// CHECK-NEXT: {{%\d+}} = OpImageSampleDrefImplicitLod %float [[sampledImg]] [[v2fc]] [[comparator]] ConstOffset [[v2ic]]
float val2 = t2.SampleCmp(gSampler, float2(1, 2), comparator, 1);
// CHECK: [[t4:%\d+]] = OpLoad %type_cube_image %t4
// CHECK-NEXT: [[gSampler:%\d+]] = OpLoad %type_sampler %gSampler
@ -43,10 +43,9 @@ float4 main(int2 offset: A, float comparator: B) : SV_Target {
// CHECK-NEXT: [[t2:%\d+]] = OpLoad %type_2d_image %t2
// CHECK-NEXT: [[gSampler:%\d+]] = OpLoad %type_sampler %gSampler
// CHECK-NEXT: [[comparator:%\d+]] = OpLoad %float %comparator
// CHECK-NEXT: [[offset:%\d+]] = OpLoad %v2int %offset
// CHECK-NEXT: [[sampledImg:%\d+]] = OpSampledImage %type_sampled_image_0 [[t2]] [[gSampler]]
// CHECK-NEXT: {{%\d+}} = OpImageSampleDrefImplicitLod %float [[sampledImg]] [[v2fc]] [[comparator]] Offset|MinLod [[offset]] [[clamp]]
float val5 = t2.SampleCmp(gSampler, float2(1, 2), comparator, offset, clamp);
// CHECK-NEXT: {{%\d+}} = OpImageSampleDrefImplicitLod %float [[sampledImg]] [[v2fc]] [[comparator]] ConstOffset|MinLod [[v2ic]] [[clamp]]
float val5 = t2.SampleCmp(gSampler, float2(1, 2), comparator, 1, clamp);
// CHECK: [[t4:%\d+]] = OpLoad %type_cube_image %t4
// CHECK-NEXT: [[gSampler:%\d+]] = OpLoad %type_sampler %gSampler
@ -60,14 +59,13 @@ float4 main(int2 offset: A, float comparator: B) : SV_Target {
// CHECK-NEXT: [[t2:%\d+]] = OpLoad %type_2d_image %t2
// CHECK-NEXT: [[gSampler:%\d+]] = OpLoad %type_sampler %gSampler
// CHECK-NEXT: [[comparator:%\d+]] = OpLoad %float %comparator
// CHECK-NEXT: [[offset:%\d+]] = OpLoad %v2int %offset
// CHECK-NEXT: [[sampledImg:%\d+]] = OpSampledImage %type_sampled_image_0 [[t2]] [[gSampler]]
// CHECK-NEXT: [[structResult:%\d+]] = OpImageSparseSampleDrefImplicitLod %SparseResidencyStruct [[sampledImg]] [[v2fc]] [[comparator]] Offset|MinLod [[offset]] [[clamp]]
// CHECK-NEXT: [[structResult:%\d+]] = OpImageSparseSampleDrefImplicitLod %SparseResidencyStruct [[sampledImg]] [[v2fc]] [[comparator]] ConstOffset|MinLod [[v2ic]] [[clamp]]
// CHECK-NEXT: [[status:%\d+]] = OpCompositeExtract %uint [[structResult]] 0
// CHECK-NEXT: OpStore %status [[status]]
// CHECK-NEXT: [[result:%\d+]] = OpCompositeExtract %float [[structResult]] 1
// CHECK-NEXT: OpStore %val7 [[result]]
float val7 = t2.SampleCmp(gSampler, float2(1, 2), comparator, offset, clamp, status);
float val7 = t2.SampleCmp(gSampler, float2(1, 2), comparator, 1, clamp, status);
// CHECK: [[t4:%\d+]] = OpLoad %type_cube_image %t4
// CHECK-NEXT: [[gSampler:%\d+]] = OpLoad %type_sampler %gSampler

Просмотреть файл

@ -11,13 +11,13 @@ TextureCube <float4> t4 : register(t4);
Texture1D <float> t5 : register(t5);
Texture2D <float2> t6 : register(t6);
// CHECK: OpCapability ImageGatherExtended
// CHECK: OpCapability MinLod
// CHECK: OpCapability SparseResidency
// CHECK: [[v2f_1:%\d+]] = OpConstantComposite %v2float %float_1 %float_1
// CHECK: [[v2f_2:%\d+]] = OpConstantComposite %v2float %float_2 %float_2
// CHECK: [[v2f_3:%\d+]] = OpConstantComposite %v2float %float_3 %float_3
// CHECK: [[v2i_3:%\d+]] = OpConstantComposite %v2int %int_3 %int_3
// CHECK: [[v3f_1:%\d+]] = OpConstantComposite %v3float %float_1 %float_1 %float_1
// CHECK: [[v3f_2:%\d+]] = OpConstantComposite %v3float %float_2 %float_2 %float_2
// CHECK: [[v3f_3:%\d+]] = OpConstantComposite %v3float %float_3 %float_3 %float_3
@ -38,10 +38,9 @@ float4 main(int2 offset : A) : SV_Target {
// CHECK: [[t2:%\d+]] = OpLoad %type_2d_image %t2
// CHECK-NEXT: [[gSampler:%\d+]] = OpLoad %type_sampler %gSampler
// CHECK-NEXT: [[offset:%\d+]] = OpLoad %v2int %offset
// CHECK-NEXT: [[sampledImg:%\d+]] = OpSampledImage %type_sampled_image_0 [[t2]] [[gSampler]]
// CHECK-NEXT: {{%\d+}} = OpImageSampleExplicitLod %v4float [[sampledImg]] [[v2f_1]] Grad|Offset [[v2f_2]] [[v2f_3]] [[offset]]
float4 val2 = t2.SampleGrad(gSampler, float2(1, 1), float2(2, 2), float2(3, 3), offset);
// CHECK-NEXT: {{%\d+}} = OpImageSampleExplicitLod %v4float [[sampledImg]] [[v2f_1]] Grad|ConstOffset [[v2f_2]] [[v2f_3]] [[v2i_3]]
float4 val2 = t2.SampleGrad(gSampler, float2(1, 1), float2(2, 2), float2(3, 3), 3);
// CHECK: [[t3:%\d+]] = OpLoad %type_3d_image %t3
// CHECK-NEXT: [[gSampler:%\d+]] = OpLoad %type_sampler %gSampler
@ -59,10 +58,9 @@ float4 main(int2 offset : A) : SV_Target {
// CHECK: [[clamp:%\d+]] = OpLoad %float %clamp
// CHECK-NEXT: [[t2:%\d+]] = OpLoad %type_2d_image %t2
// CHECK-NEXT: [[gSampler:%\d+]] = OpLoad %type_sampler %gSampler
// CHECK-NEXT: [[offset:%\d+]] = OpLoad %v2int %offset
// CHECK-NEXT: [[sampledImg:%\d+]] = OpSampledImage %type_sampled_image_0 [[t2]] [[gSampler]]
// CHECK-NEXT: {{%\d+}} = OpImageSampleExplicitLod %v4float [[sampledImg]] [[v2f_1]] Grad|Offset|MinLod [[v2f_2]] [[v2f_3]] [[offset]] [[clamp]]
float4 val5 = t2.SampleGrad(gSampler, float2(1, 1), float2(2, 2), float2(3, 3), offset, clamp);
// CHECK-NEXT: {{%\d+}} = OpImageSampleExplicitLod %v4float [[sampledImg]] [[v2f_1]] Grad|ConstOffset|MinLod [[v2f_2]] [[v2f_3]] [[v2i_3]] [[clamp]]
float4 val5 = t2.SampleGrad(gSampler, float2(1, 1), float2(2, 2), float2(3, 3), 3, clamp);
// CHECK: [[t4:%\d+]] = OpLoad %type_cube_image %t4
// CHECK-NEXT: [[gSampler:%\d+]] = OpLoad %type_sampler %gSampler
@ -74,14 +72,13 @@ float4 main(int2 offset : A) : SV_Target {
// CHECK: [[clamp:%\d+]] = OpLoad %float %clamp
// CHECK-NEXT: [[t2:%\d+]] = OpLoad %type_2d_image %t2
// CHECK-NEXT: [[gSampler:%\d+]] = OpLoad %type_sampler %gSampler
// CHECK-NEXT: [[offset:%\d+]] = OpLoad %v2int %offset
// CHECK-NEXT: [[sampledImg:%\d+]] = OpSampledImage %type_sampled_image_0 [[t2]] [[gSampler]]
// CHECK-NEXT: [[structResult:%\d+]] = OpImageSparseSampleExplicitLod %SparseResidencyStruct [[sampledImg]] [[v2f_1]] Grad|Offset|MinLod [[v2f_2]] [[v2f_3]] [[offset]] [[clamp]]
// CHECK-NEXT: [[structResult:%\d+]] = OpImageSparseSampleExplicitLod %SparseResidencyStruct [[sampledImg]] [[v2f_1]] Grad|ConstOffset|MinLod [[v2f_2]] [[v2f_3]] [[v2i_3]] [[clamp]]
// CHECK-NEXT: [[status:%\d+]] = OpCompositeExtract %uint [[structResult]] 0
// CHECK-NEXT: OpStore %status [[status]]
// CHECK-NEXT: [[result:%\d+]] = OpCompositeExtract %v4float [[structResult]] 1
// CHECK-NEXT: OpStore %val7 [[result]]
float4 val7 = t2.SampleGrad(gSampler, float2(1, 1), float2(2, 2), float2(3, 3), offset, clamp, status);
float4 val7 = t2.SampleGrad(gSampler, float2(1, 1), float2(2, 2), float2(3, 3), 3, clamp, status);
// CHECK: [[t4:%\d+]] = OpLoad %type_cube_image %t4
// CHECK-NEXT: [[gSampler:%\d+]] = OpLoad %type_sampler %gSampler
@ -102,10 +99,10 @@ float4 main(int2 offset : A) : SV_Target {
// CHECK: {{%\d+}} = OpCompositeExtract %float [[v4result]] 0
float val9 = t5.SampleGrad(gSampler, 1, 2, 3);
// CHECK: [[structResult:%\d+]] = OpImageSparseSampleExplicitLod %SparseResidencyStruct {{%\d+}} {{%\d+}} Grad|Offset|MinLod {{%\d+}} {{%\d+}} {{%\d+}} {{%\d+}}
// CHECK: [[structResult:%\d+]] = OpImageSparseSampleExplicitLod %SparseResidencyStruct {{%\d+}} {{%\d+}} Grad|ConstOffset|MinLod {{%\d+}} {{%\d+}} {{%\d+}} {{%\d+}}
// CHECK: [[v4result:%\d+]] = OpCompositeExtract %v4float [[structResult]] 1
// CHECK: {{%\d+}} = OpVectorShuffle %v2float [[v4result]] [[v4result]] 0 1
float2 val10 = t6.SampleGrad(gSampler, float2(1, 1), float2(2, 2), float2(3, 3), offset, clamp, status);
float2 val10 = t6.SampleGrad(gSampler, float2(1, 1), float2(2, 2), float2(3, 3), 3, clamp, status);
return 1.0;
}

Просмотреть файл

@ -13,26 +13,16 @@ float4 main(int2 offset: A) : SV_Position {
// CHECK: sampling with implicit lod is only allowed in fragment shaders
float4 val1 = t1.Sample(gSampler, 0.5);
// CHECK: sampling with implicit lod is only allowed in fragment shaders
float4 val2 = t2.Sample(gSampler, float2(0.5, 0.25), offset);
// CHECK: sampling with implicit lod is only allowed in fragment shaders
float4 val3 = t3.Sample(gSampler, float3(0.5, 0.25, 0.3), 3);
// CHECK: sampling with implicit lod is only allowed in fragment shaders
float4 val4 = t4.Sample(gSampler, float3(0.5, 0.25, 0.3));
float clamp;
// CHECK: sampling with implicit lod is only allowed in fragment shaders
float4 val5 = t2.Sample(gSampler, float2(0.5, 0.25), offset, clamp);
// CHECK: sampling with implicit lod is only allowed in fragment shaders
float4 val6 = t4.Sample(gSampler, float3(0.5, 0.25, 0.3), /*clamp*/ 2.0f);
uint status;
// CHECK: sampling with implicit lod is only allowed in fragment shaders
float4 val7 = t2.Sample(gSampler, float2(0.5, 0.25), offset, clamp, status);
// CHECK: sampling with implicit lod is only allowed in fragment shaders
float4 val8 = t4.Sample(gSampler, float3(0.5, 0.25, 0.3), /*clamp*/ 2.0f, status);

Просмотреть файл

@ -0,0 +1,25 @@
// Run: %dxc -T vs_6_0 -E main
SamplerState gSampler : register(s5);
// Note: The front end forbids sampling from non-floating-point texture formats.
Texture1D <float4> t1 : register(t1);
Texture2D <float4> t2 : register(t2);
Texture3D <float4> t3 : register(t3);
TextureCube <float4> t4 : register(t4);
float4 main(int2 offset: A) : SV_Position {
// CHECK: Use constant value for offset (SPIR-V spec does not accept a variable offset for OpImage* instructions other than OpImage*Gather)
float4 val2 = t2.Sample(gSampler, float2(0.5, 0.25), offset);
float clamp;
// CHECK: Use constant value for offset (SPIR-V spec does not accept a variable offset for OpImage* instructions other than OpImage*Gather)
float4 val5 = t2.Sample(gSampler, float2(0.5, 0.25), offset, clamp);
uint status;
// CHECK: Use constant value for offset (SPIR-V spec does not accept a variable offset for OpImage* instructions other than OpImage*Gather)
float4 val7 = t2.Sample(gSampler, float2(0.5, 0.25), offset, clamp, status);
return float4(0.0, 0.0, 0.0, 1.0);
}

Просмотреть файл

@ -11,12 +11,12 @@ TextureCube <float4> t4 : register(t4);
Texture3D <float> t5 : register(t5);
TextureCube <float2> t6 : register(t6);
// CHECK: OpCapability ImageGatherExtended
// CHECK: OpCapability SparseResidency
// CHECK: [[v2fc:%\d+]] = OpConstantComposite %v2float %float_1 %float_2
// CHECK: [[v2ic:%\d+]] = OpConstantComposite %v2int %int_2 %int_2
// CHECK: [[v3fc:%\d+]] = OpConstantComposite %v3float %float_1 %float_2 %float_3
// CHECK: [[v3ic:%\d+]] = OpConstantComposite %v3int %int_2 %int_2 %int_2
// CHECK: %type_sampled_image = OpTypeSampledImage %type_1d_image
// CHECK: %type_sampled_image_0 = OpTypeSampledImage %type_2d_image
@ -39,10 +39,9 @@ float4 main(int3 offset: A) : SV_Target {
// CHECK: [[t3:%\d+]] = OpLoad %type_3d_image %t3
// CHECK-NEXT: [[gSampler:%\d+]] = OpLoad %type_sampler %gSampler
// CHECK-NEXT: [[offset:%\d+]] = OpLoad %v3int %offset
// CHECK-NEXT: [[sampledImg:%\d+]] = OpSampledImage %type_sampled_image_1 [[t3]] [[gSampler]]
// CHECK-NEXT: {{%\d+}} = OpImageSampleExplicitLod %v4float [[sampledImg]] [[v3fc]] Lod|Offset %float_10 [[offset]]
float4 val3 = t3.SampleLevel(gSampler, float3(1, 2, 3), 10, offset);
// CHECK-NEXT: {{%\d+}} = OpImageSampleExplicitLod %v4float [[sampledImg]] [[v3fc]] Lod|ConstOffset %float_10 [[v3ic]]
float4 val3 = t3.SampleLevel(gSampler, float3(1, 2, 3), 10, 2);
// CHECK: [[t4:%\d+]] = OpLoad %type_cube_image %t4
// CHECK-NEXT: [[gSampler:%\d+]] = OpLoad %type_sampler %gSampler
@ -53,14 +52,13 @@ float4 main(int3 offset: A) : SV_Target {
uint status;
// CHECK: [[t3:%\d+]] = OpLoad %type_3d_image %t3
// CHECK-NEXT: [[gSampler:%\d+]] = OpLoad %type_sampler %gSampler
// CHECK-NEXT: [[offset:%\d+]] = OpLoad %v3int %offset
// CHECK-NEXT: [[sampledImg:%\d+]] = OpSampledImage %type_sampled_image_1 [[t3]] [[gSampler]]
// CHECK-NEXT: [[structResult:%\d+]] = OpImageSparseSampleExplicitLod %SparseResidencyStruct [[sampledImg]] [[v3fc]] Lod|Offset %float_10 [[offset]]
// CHECK-NEXT: [[structResult:%\d+]] = OpImageSparseSampleExplicitLod %SparseResidencyStruct [[sampledImg]] [[v3fc]] Lod|ConstOffset %float_10 [[v3ic]]
// CHECK-NEXT: [[status:%\d+]] = OpCompositeExtract %uint [[structResult]] 0
// CHECK-NEXT: OpStore %status [[status]]
// CHECK-NEXT: [[result:%\d+]] = OpCompositeExtract %v4float [[structResult]] 1
// CHECK-NEXT: OpStore %val5 [[result]]
float4 val5 = t3.SampleLevel(gSampler, float3(1, 2, 3), 10, offset, status);
float4 val5 = t3.SampleLevel(gSampler, float3(1, 2, 3), 10, 2, status);
// CHECK: [[t4:%\d+]] = OpLoad %type_cube_image %t4
// CHECK-NEXT: [[gSampler:%\d+]] = OpLoad %type_sampler %gSampler
@ -77,9 +75,9 @@ float4 main(int3 offset: A) : SV_Target {
// Make sure OpImageSparseSampleExplicitLod returns a struct, in which the second member is a vec4.
/////////////////////////////////////////////////////////////////////////////////////////////////////////
// CHECK: [[v4result:%\d+]] = OpImageSampleExplicitLod %v4float {{%\d+}} {{%\d+}} Lod|Offset %float_10 {{%\d+}}
// CHECK: [[v4result:%\d+]] = OpImageSampleExplicitLod %v4float {{%\d+}} {{%\d+}} Lod|ConstOffset %float_10 {{%\d+}}
// CHECK: {{%\d+}} = OpCompositeExtract %float [[v4result]] 0
float val7 = t5.SampleLevel(gSampler, float3(1, 2, 3), 10, offset);
float val7 = t5.SampleLevel(gSampler, float3(1, 2, 3), 10, 2);
// CHECK: [[structResult:%\d+]] = OpImageSparseSampleExplicitLod %SparseResidencyStruct {{%\d+}} {{%\d+}} Lod %float_10
// CHECK: [[v4result:%\d+]] = OpCompositeExtract %v4float [[structResult]] 1

Просмотреть файл

@ -11,11 +11,11 @@ TextureCube <float4> t4 : register(t4);
Texture1D <float> t5 : register(t5);
TextureCube <float3> t6 : register(t6);
// CHECK: OpCapability ImageGatherExtended
// CHECK: OpCapability MinLod
// CHECK: OpCapability SparseResidency
// CHECK: [[v2fc:%\d+]] = OpConstantComposite %v2float %float_0_5 %float_0_25
// CHECK: [[v2ic:%\d+]] = OpConstantComposite %v2int %int_2 %int_3
// CHECK: [[v3fc:%\d+]] = OpConstantComposite %v3float %float_0_5 %float_0_25 %float_0_3
// CHECK: [[v3ic:%\d+]] = OpConstantComposite %v3int %int_3 %int_3 %int_3
@ -34,10 +34,9 @@ float4 main(int2 offset: A) : SV_Target {
// CHECK: [[t2:%\d+]] = OpLoad %type_2d_image %t2
// CHECK-NEXT: [[gSampler:%\d+]] = OpLoad %type_sampler %gSampler
// CHECK-NEXT: [[offset:%\d+]] = OpLoad %v2int %offset
// CHECK-NEXT: [[sampledImg:%\d+]] = OpSampledImage %type_sampled_image_0 [[t2]] [[gSampler]]
// CHECK-NEXT: {{%\d+}} = OpImageSampleImplicitLod %v4float [[sampledImg]] [[v2fc]] Offset [[offset]]
float4 val2 = t2.Sample(gSampler, float2(0.5, 0.25), offset);
// CHECK-NEXT: {{%\d+}} = OpImageSampleImplicitLod %v4float [[sampledImg]] [[v2fc]] ConstOffset [[v2ic]]
float4 val2 = t2.Sample(gSampler, float2(0.5, 0.25), int2(2, 3));
// CHECK: [[t3:%\d+]] = OpLoad %type_3d_image %t3
// CHECK-NEXT: [[gSampler:%\d+]] = OpLoad %type_sampler %gSampler
@ -55,10 +54,9 @@ float4 main(int2 offset: A) : SV_Target {
// CHECK: [[clamp:%\d+]] = OpLoad %float %clamp
// CHECK-NEXT: [[t2:%\d+]] = OpLoad %type_2d_image %t2
// CHECK-NEXT: [[gSampler:%\d+]] = OpLoad %type_sampler %gSampler
// CHECK-NEXT: [[offset:%\d+]] = OpLoad %v2int %offset
// CHECK-NEXT: [[sampledImg:%\d+]] = OpSampledImage %type_sampled_image_0 [[t2]] [[gSampler]]
// CHECK-NEXT: {{%\d+}} = OpImageSampleImplicitLod %v4float [[sampledImg]] [[v2fc]] Offset|MinLod [[offset]] [[clamp]]
float4 val5 = t2.Sample(gSampler, float2(0.5, 0.25), offset, clamp);
// CHECK-NEXT: {{%\d+}} = OpImageSampleImplicitLod %v4float [[sampledImg]] [[v2fc]] ConstOffset|MinLod [[v2ic]] [[clamp]]
float4 val5 = t2.Sample(gSampler, float2(0.5, 0.25), int2(2, 3), clamp);
// CHECK: [[t4:%\d+]] = OpLoad %type_cube_image %t4
// CHECK-NEXT: [[gSampler:%\d+]] = OpLoad %type_sampler %gSampler
@ -70,14 +68,13 @@ float4 main(int2 offset: A) : SV_Target {
// CHECK: [[clamp:%\d+]] = OpLoad %float %clamp
// CHECK-NEXT: [[t2:%\d+]] = OpLoad %type_2d_image %t2
// CHECK-NEXT: [[gSampler:%\d+]] = OpLoad %type_sampler %gSampler
// CHECK-NEXT: [[offset:%\d+]] = OpLoad %v2int %offset
// CHECK-NEXT: [[sampledImg:%\d+]] = OpSampledImage %type_sampled_image_0 [[t2]] [[gSampler]]
// CHECK-NEXT: [[structResult:%\d+]] = OpImageSparseSampleImplicitLod %SparseResidencyStruct [[sampledImg]] [[v2fc]] Offset|MinLod [[offset]] [[clamp]]
// CHECK-NEXT: [[structResult:%\d+]] = OpImageSparseSampleImplicitLod %SparseResidencyStruct [[sampledImg]] [[v2fc]] ConstOffset|MinLod [[v2ic]] [[clamp]]
// CHECK-NEXT: [[status:%\d+]] = OpCompositeExtract %uint [[structResult]] 0
// CHECK-NEXT: OpStore %status [[status]]
// CHECK-NEXT: [[result:%\d+]] = OpCompositeExtract %v4float [[structResult]] 1
// CHECK-NEXT: OpStore %val7 [[result]]
float4 val7 = t2.Sample(gSampler, float2(0.5, 0.25), offset, clamp, status);
float4 val7 = t2.Sample(gSampler, float2(0.5, 0.25), int2(2, 3), clamp, status);
// CHECK: [[t4:%\d+]] = OpLoad %type_cube_image %t4
// CHECK-NEXT: [[gSampler:%\d+]] = OpLoad %type_sampler %gSampler

Просмотреть файл

@ -865,6 +865,9 @@ TEST_F(FileTest, TextureArraySample) {
}
TEST_F(FileTest, TextureLoad) { runFileTest("texture.load.hlsl"); }
TEST_F(FileTest, TextureArrayLoad) { runFileTest("texture.array.load.hlsl"); }
TEST_F(FileTest, TextureLoadInvalidOffsetOperand) {
runFileTest("texture.load-invalid-offset-operand.hlsl", Expect::Failure);
}
TEST_F(FileTest, TextureGetDimensions) {
runFileTest("texture.get-dimensions.hlsl");
}
@ -947,6 +950,9 @@ TEST_F(FileTest, TextureArraySampleCmpLevelZero) {
TEST_F(FileTest, TextureSampleInvalidImplicitLod) {
runFileTest("texture.sample-invalid-implicit-lod.hlsl", Expect::Failure);
}
TEST_F(FileTest, TextureSampleInvalidOffsetOperand) {
runFileTest("texture.sample-invalid-offset-operand.hlsl", Expect::Failure);
}
TEST_F(FileTest, TextureInvalidTex2D) {
runFileTest("texture.sample.invalid.tex2d.hlsl", Expect::Failure);
}