[SPIRV-V] Implement Shader Model 6.8 Expanded Comparison Sampling (#6854)
Compile `SampleCmpBias` using `OpImage*SampleDrefImplicitLod` and `SampleCmpGrad` using `OpImage*SampleDrefExplicitLod`. The existing handlers for `CalculateLevelOfDetail` and `CalculateLevelOfDetailUnclamped` work for the `SamplerComparisonSampler` overload, so no new code is needed other than tests.
This commit is contained in:
Родитель
937c8c8811
Коммит
ca2e67d29e
|
@ -2890,6 +2890,30 @@ If an output unsigned integer ``status`` argument is present,
|
|||
``OpImageSparseSampleDrefExplicitLod`` is used instead. The resulting SPIR-V
|
||||
``Residency Code`` will be written to ``status``.
|
||||
|
||||
``.SampleCmpBias(sampler, location, bias, comparator[, offset][, clamp][, Status])``
|
||||
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
|
||||
Not available to ``Texture3D``, ``Texture2DMS``, and ``Texture2DMSArray``.
|
||||
|
||||
The translation is similar to ``.SampleBias()``, but the
|
||||
``OpImageSampleDrefImplicitLod`` instruction is used.
|
||||
|
||||
If an output unsigned integer ``status`` argument is present,
|
||||
``OpImageSparseSampleDrefImplicitLod`` is used instead. The resulting SPIR-V
|
||||
``Residency Code`` will be written to ``status``.
|
||||
|
||||
``.SampleCmpGrad(sampler, location, ddx, ddy, comparator[, offset][, clamp][, Status])``
|
||||
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
|
||||
Not available to ``Texture3D``, ``Texture2DMS``, and ``Texture2DMSArray``.
|
||||
|
||||
The translation is similar to ``.SampleGrad()``, but the
|
||||
``OpImageSampleDrefExplicitLod`` instruction are used.
|
||||
|
||||
If an output unsigned integer ``status`` argument is present,
|
||||
``OpImageSparseSampleDrefExplicitLod`` is used instead. The resulting SPIR-V
|
||||
``Residency Code`` will be written to ``status``.
|
||||
|
||||
``.Gather()``
|
||||
+++++++++++++
|
||||
|
||||
|
@ -2983,10 +3007,11 @@ Not available to ``Texture2DMS`` and ``Texture2DMSArray``.
|
|||
|
||||
Since texture types are represented as ``OpTypeImage``, the ``OpImageQueryLod``
|
||||
instruction is used for translation. An ``OpSampledImage`` is created based on
|
||||
the ``SamplerState`` passed to the function. The resulting sampled image and
|
||||
the coordinate passed to the function are used to invoke ``OpImageQueryLod``.
|
||||
The result of ``OpImageQueryLod`` is a ``float2``. The first element contains
|
||||
the mipmap array layer. The second element contains the unclamped level of detail.
|
||||
the ``SamplerState`` or ``SamplerComparisonState`` passed to the function. The
|
||||
resulting sampled image and the coordinate passed to the function are used to
|
||||
invoke ``OpImageQueryLod``. The result of ``OpImageQueryLod`` is a ``float2``.
|
||||
The first element contains the mipmap array layer. The second element contains
|
||||
the unclamped level of detail.
|
||||
|
||||
``Texture1D``
|
||||
~~~~~~~~~~~~~
|
||||
|
|
|
@ -5259,6 +5259,12 @@ SpirvEmitter::processIntrinsicMemberCall(const CXXMemberCallExpr *expr,
|
|||
case IntrinsicOp::MOP_SampleCmp:
|
||||
retVal = processTextureSampleCmp(expr);
|
||||
break;
|
||||
case IntrinsicOp::MOP_SampleCmpBias:
|
||||
retVal = processTextureSampleCmpBias(expr);
|
||||
break;
|
||||
case IntrinsicOp::MOP_SampleCmpGrad:
|
||||
retVal = processTextureSampleCmpGrad(expr);
|
||||
break;
|
||||
case IntrinsicOp::MOP_SampleCmpLevelZero:
|
||||
retVal = processTextureSampleCmpLevelZero(expr);
|
||||
break;
|
||||
|
@ -5468,6 +5474,32 @@ SpirvInstruction *SpirvEmitter::createImageSample(
|
|||
return retVal;
|
||||
}
|
||||
|
||||
void SpirvEmitter::handleOptionalTextureSampleArgs(
|
||||
const CXXMemberCallExpr *expr, uint32_t index,
|
||||
SpirvInstruction **constOffset, SpirvInstruction **varOffset,
|
||||
SpirvInstruction **clamp, SpirvInstruction **status) {
|
||||
uint32_t numArgs = expr->getNumArgs();
|
||||
|
||||
bool hasOffsetArg = index < numArgs &&
|
||||
(expr->getArg(index)->getType()->isSignedIntegerType() ||
|
||||
hlsl::IsHLSLVecType(expr->getArg(index)->getType()));
|
||||
if (hasOffsetArg) {
|
||||
handleOffsetInMethodCall(expr, index, constOffset, varOffset);
|
||||
index++;
|
||||
}
|
||||
|
||||
if (index >= numArgs)
|
||||
return;
|
||||
|
||||
*clamp = doExpr(expr->getArg(index));
|
||||
index++;
|
||||
|
||||
if (index >= numArgs)
|
||||
return;
|
||||
|
||||
*status = doExpr(expr->getArg(index));
|
||||
}
|
||||
|
||||
SpirvInstruction *
|
||||
SpirvEmitter::processTextureSampleGather(const CXXMemberCallExpr *expr,
|
||||
const bool isSample) {
|
||||
|
@ -5753,6 +5785,108 @@ SpirvEmitter::processTextureSampleCmp(const CXXMemberCallExpr *expr) {
|
|||
expr->getCallee()->getLocStart(), expr->getSourceRange());
|
||||
}
|
||||
|
||||
SpirvInstruction *
|
||||
SpirvEmitter::processTextureSampleCmpBias(const CXXMemberCallExpr *expr) {
|
||||
// .SampleCmpBias() Signature:
|
||||
//
|
||||
// For Texture1D, Texture1DArray, Texture2D, Texture2DArray:
|
||||
// float Object.SampleCmpBias(
|
||||
// SamplerComparisonState S,
|
||||
// float Location,
|
||||
// float CompareValue,
|
||||
// float Bias
|
||||
// [, int Offset]
|
||||
// [, float Clamp]
|
||||
// [, out uint Status]
|
||||
// );
|
||||
//
|
||||
// For TextureCube and TextureCubeArray:
|
||||
// float Object.SampleCmpBias(
|
||||
// SamplerComparisonState S,
|
||||
// float Location,
|
||||
// float CompareValue,
|
||||
// float Bias
|
||||
// [, float Clamp]
|
||||
// [, out uint Status]
|
||||
// );
|
||||
|
||||
const auto *imageExpr = expr->getImplicitObjectArgument();
|
||||
auto *image = loadIfGLValue(imageExpr);
|
||||
|
||||
auto *sampler = doExpr(expr->getArg(0));
|
||||
auto *coordinate = doExpr(expr->getArg(1));
|
||||
auto *compareVal = doExpr(expr->getArg(2));
|
||||
auto *bias = doExpr(expr->getArg(3));
|
||||
|
||||
SpirvInstruction *constOffset = nullptr, *varOffset = nullptr;
|
||||
SpirvInstruction *clamp = nullptr;
|
||||
SpirvInstruction *status = nullptr;
|
||||
|
||||
handleOptionalTextureSampleArgs(expr, 4, &constOffset, &varOffset, &clamp,
|
||||
&status);
|
||||
|
||||
const auto retType = expr->getDirectCallee()->getReturnType();
|
||||
const auto imageType = imageExpr->getType();
|
||||
|
||||
if (spvContext.isCS()) {
|
||||
addDerivativeGroupExecutionMode();
|
||||
}
|
||||
|
||||
return createImageSample(
|
||||
retType, imageType, image, sampler, coordinate, compareVal, bias,
|
||||
/*lod*/ nullptr, std::make_pair(nullptr, nullptr), constOffset, varOffset,
|
||||
/*constOffsets*/ nullptr, /*sampleNumber*/ nullptr, /*minLod*/ clamp,
|
||||
status, expr->getCallee()->getLocStart(), expr->getSourceRange());
|
||||
}
|
||||
|
||||
SpirvInstruction *
|
||||
SpirvEmitter::processTextureSampleCmpGrad(const CXXMemberCallExpr *expr) {
|
||||
// Signature:
|
||||
// For Texture1D, Texture1DArray, Texture2D, Texture2DArray, and Texture3D:
|
||||
// DXGI_FORMAT Object.SampleGrad(sampler_state S,
|
||||
// float Location,
|
||||
// float CompareValue,
|
||||
// float DDX,
|
||||
// float DDY
|
||||
// [, int Offset]
|
||||
// [, float Clamp]
|
||||
// [, out uint Status]);
|
||||
//
|
||||
// For TextureCube and TextureCubeArray:
|
||||
// DXGI_FORMAT Object.SampleGrad(sampler_state S,
|
||||
// float Location,
|
||||
// float CompareValue,
|
||||
// float DDX,
|
||||
// float DDY
|
||||
// [, float Clamp]
|
||||
// [, out uint Status]);
|
||||
|
||||
const auto *imageExpr = expr->getImplicitObjectArgument();
|
||||
const QualType imageType = imageExpr->getType();
|
||||
auto *image = loadIfGLValue(imageExpr);
|
||||
|
||||
auto *sampler = doExpr(expr->getArg(0));
|
||||
auto *coordinate = doExpr(expr->getArg(1));
|
||||
auto *compareVal = doExpr(expr->getArg(2));
|
||||
auto *ddx = doExpr(expr->getArg(3));
|
||||
auto *ddy = doExpr(expr->getArg(4));
|
||||
|
||||
SpirvInstruction *constOffset = nullptr, *varOffset = nullptr;
|
||||
SpirvInstruction *clamp = nullptr;
|
||||
SpirvInstruction *status = nullptr;
|
||||
|
||||
handleOptionalTextureSampleArgs(expr, 5, &constOffset, &varOffset, &clamp,
|
||||
&status);
|
||||
|
||||
const auto retType = expr->getDirectCallee()->getReturnType();
|
||||
return createImageSample(
|
||||
retType, imageType, image, sampler, coordinate, compareVal,
|
||||
/*bias*/ nullptr, /*lod*/ nullptr, std::make_pair(ddx, ddy), constOffset,
|
||||
varOffset, /*constOffsets*/ nullptr, /*sampleNumber*/ nullptr,
|
||||
/*minLod*/ clamp, status, expr->getCallee()->getLocStart(),
|
||||
expr->getSourceRange());
|
||||
}
|
||||
|
||||
SpirvInstruction *
|
||||
SpirvEmitter::processTextureSampleCmpLevelZero(const CXXMemberCallExpr *expr) {
|
||||
// .SampleCmpLevelZero() is identical to .SampleCmp() on mipmap level 0 only.
|
||||
|
|
|
@ -979,6 +979,13 @@ private:
|
|||
SpirvInstruction **constOffset,
|
||||
SpirvInstruction **varOffset);
|
||||
|
||||
void handleOptionalTextureSampleArgs(const CXXMemberCallExpr *expr,
|
||||
uint32_t index,
|
||||
SpirvInstruction **constOffset,
|
||||
SpirvInstruction **varOffset,
|
||||
SpirvInstruction **clamp,
|
||||
SpirvInstruction **status);
|
||||
|
||||
/// \brief Processes .Load() method call for Buffer/RWBuffer and texture
|
||||
/// objects.
|
||||
SpirvInstruction *processBufferTextureLoad(const CXXMemberCallExpr *);
|
||||
|
@ -1009,6 +1016,12 @@ private:
|
|||
/// \brief Processes .SampleCmp() method call for texture objects.
|
||||
SpirvInstruction *processTextureSampleCmp(const CXXMemberCallExpr *expr);
|
||||
|
||||
/// \brief Processes .SampleCmpBias() method call for texture objects.
|
||||
SpirvInstruction *processTextureSampleCmpBias(const CXXMemberCallExpr *expr);
|
||||
|
||||
/// \brief Processes .SampleCmpGrad() method call for texture objects.
|
||||
SpirvInstruction *processTextureSampleCmpGrad(const CXXMemberCallExpr *expr);
|
||||
|
||||
/// \brief Processes .SampleCmpLevelZero() method call for texture objects.
|
||||
SpirvInstruction *
|
||||
processTextureSampleCmpLevelZero(const CXXMemberCallExpr *expr);
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
// RUN: %dxc -T ps_6_8 -E main -fcgl %s -spirv | FileCheck %s
|
||||
|
||||
// CHECK: OpCapability ImageQuery
|
||||
|
||||
SamplerComparisonState scs : register(s2);
|
||||
|
||||
Texture1D <float> t1;
|
||||
|
||||
// CHECK: %type_sampled_image = OpTypeSampledImage %type_1d_image
|
||||
|
||||
void main() {
|
||||
float x = 0.5;
|
||||
|
||||
//CHECK: [[t1:%[0-9]+]] = OpLoad %type_1d_image %t1
|
||||
//CHECK-NEXT: [[ss1:%[0-9]+]] = OpLoad %type_sampler %scs
|
||||
//CHECK-NEXT: [[x1:%[0-9]+]] = OpLoad %float %x
|
||||
//CHECK-NEXT: [[si1:%[0-9]+]] = OpSampledImage %type_sampled_image [[t1]] [[ss1]]
|
||||
//CHECK-NEXT: [[query1:%[0-9]+]] = OpImageQueryLod %v2float [[si1]] [[x1]]
|
||||
//CHECK-NEXT: {{%[0-9]+}} = OpCompositeExtract %float [[query1]] 1
|
||||
float lod1 = t1.CalculateLevelOfDetailUnclamped(scs, x);
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
// RUN: %dxc -T ps_6_8 -E main -fcgl %s -spirv | FileCheck %s
|
||||
|
||||
// CHECK: OpCapability ImageQuery
|
||||
|
||||
SamplerComparisonState scs : register(s2);
|
||||
|
||||
Texture1D <float> t1;
|
||||
|
||||
// CHECK: %type_sampled_image = OpTypeSampledImage %type_1d_image
|
||||
|
||||
void main() {
|
||||
float x = 0.5;
|
||||
|
||||
//CHECK: [[t1:%[0-9]+]] = OpLoad %type_1d_image %t1
|
||||
//CHECK-NEXT: [[ss1:%[0-9]+]] = OpLoad %type_sampler %scs
|
||||
//CHECK-NEXT: [[x1:%[0-9]+]] = OpLoad %float %x
|
||||
//CHECK-NEXT: [[si1:%[0-9]+]] = OpSampledImage %type_sampled_image [[t1]] [[ss1]]
|
||||
//CHECK-NEXT: [[query1:%[0-9]+]] = OpImageQueryLod %v2float [[si1]] [[x1]]
|
||||
//CHECK-NEXT: {{%[0-9]+}} = OpCompositeExtract %float [[query1]] 0
|
||||
float lod1 = t1.CalculateLevelOfDetail(scs, x);
|
||||
}
|
|
@ -0,0 +1,64 @@
|
|||
// RUN: %dxc -T ps_6_8 -E main -fcgl %s -spirv | FileCheck %s
|
||||
|
||||
SamplerComparisonState s;
|
||||
|
||||
Texture1D<float4> t1;
|
||||
Texture1DArray<float4> t1_array;
|
||||
Texture2D<float4> t2;
|
||||
TextureCube<float4> tcube;
|
||||
|
||||
// CHECK: OpCapability MinLod
|
||||
// CHECK: OpCapability SparseResidency
|
||||
|
||||
// CHECK: [[v2fc:%[0-9]+]] = OpConstantComposite %v2float %float_1 %float_2
|
||||
// CHECK: [[v2ic:%[0-9]+]] = OpConstantComposite %v2int %int_n5 %int_7
|
||||
// CHECK: [[v3fc:%[0-9]+]] = OpConstantComposite %v3float %float_1 %float_2 %float_3
|
||||
|
||||
// CHECK: %SparseResidencyStruct = OpTypeStruct %uint %float
|
||||
|
||||
void main() {
|
||||
float cmpVal;
|
||||
float bias;
|
||||
|
||||
float clamp;
|
||||
|
||||
// CHECK: [[t1:%[0-9]+]] = OpLoad %type_1d_image %t1
|
||||
// CHECK-NEXT: [[sampler:%[0-9]+]] = OpLoad %type_sampler %s
|
||||
// CHECK-NEXT: [[cmpVal:%[0-9]+]] = OpLoad %float %cmpVal
|
||||
// CHECK-NEXT: [[bias:%[0-9]+]] = OpLoad %float %bias
|
||||
// CHECK-NEXT: [[sampledImg:%[0-9]+]] = OpSampledImage %type_sampled_image [[t1]] [[sampler]]
|
||||
// CHECK-NEXT: {{%[0-9]+}} = OpImageSampleDrefImplicitLod %float [[sampledImg]] %float_1 [[cmpVal]] Bias [[bias]]
|
||||
float val1 = t1.SampleCmpBias(s, 1, cmpVal, bias);
|
||||
|
||||
// CHECK: [[t1Array:%[0-9]+]] = OpLoad %type_1d_image_array %t1_array
|
||||
// CHECK-NEXT: [[sampler:%[0-9]+]] = OpLoad %type_sampler %s
|
||||
// CHECK-NEXT: [[cmpVal:%[0-9]+]] = OpLoad %float %cmpVal
|
||||
// CHECK-NEXT: [[bias:%[0-9]+]] = OpLoad %float %bias
|
||||
// CHECK-NEXT: [[sampledImg:%[0-9]+]] = OpSampledImage %type_sampled_image_0 [[t1Array]] [[sampler]]
|
||||
// CHECK-NEXT: {{%[0-9]+}} = OpImageSampleDrefImplicitLod %float [[sampledImg]] [[v2fc]] [[cmpVal]] Bias|ConstOffset [[bias]] %int_n5
|
||||
float val2 = t1_array.SampleCmpBias(s, float2(1, 2), cmpVal, bias, -5);
|
||||
|
||||
// CHECK: [[t2:%[0-9]+]] = OpLoad %type_2d_image %t2
|
||||
// CHECK-NEXT: [[sampler:%[0-9]+]] = OpLoad %type_sampler %s
|
||||
// CHECK-NEXT: [[cmpVal:%[0-9]+]] = OpLoad %float %cmpVal
|
||||
// CHECK-NEXT: [[bias:%[0-9]+]] = OpLoad %float %bias
|
||||
// CHECK-NEXT: [[clamp:%[0-9]+]] = OpLoad %float %clamp
|
||||
// CHECK-NEXT: [[sampledImg:%[0-9]+]] = OpSampledImage %type_sampled_image_1 [[t2]] [[sampler]]
|
||||
// CHECK-NEXT: {{%[0-9]+}} = OpImageSampleDrefImplicitLod %float [[sampledImg]] [[v2fc]] [[cmpVal]] Bias|ConstOffset|MinLod [[bias]] [[v2ic]] [[clamp]]
|
||||
float val3 = t2.SampleCmpBias(s, float2(1, 2), cmpVal, bias, uint2(-5, 7), clamp);
|
||||
|
||||
uint status;
|
||||
|
||||
// CHECK: [[tcube:%[0-9]+]] = OpLoad %type_cube_image %tcube
|
||||
// CHECK-NEXT: [[sampler:%[0-9]+]] = OpLoad %type_sampler %s
|
||||
// CHECK-NEXT: [[cmpVal:%[0-9]+]] = OpLoad %float %cmpVal
|
||||
// CHECK-NEXT: [[bias:%[0-9]+]] = OpLoad %float %bias
|
||||
// CHECK-NEXT: [[clamp:%[0-9]+]] = OpLoad %float %clamp
|
||||
// CHECK-NEXT: [[sampledImg:%[0-9]+]] = OpSampledImage %type_sampled_image_2 [[tcube]] [[sampler]]
|
||||
// CHECK-NEXT: [[structResult:%[0-9]+]] = OpImageSparseSampleDrefImplicitLod %SparseResidencyStruct [[sampledImg]] [[v3fc]] [[cmpVal]] Bias|MinLod [[bias]] [[clamp]]
|
||||
// CHECK-NEXT: [[status:%[0-9]+]] = OpCompositeExtract %uint [[structResult]] 0
|
||||
// CHECK-NEXT: OpStore %status [[status]]
|
||||
// CHECK-NEXT: [[result:%[0-9]+]] = OpCompositeExtract %float [[structResult]] 1
|
||||
// CHECK-NEXT: OpStore %val4 [[result]]
|
||||
float val4 = tcube.SampleCmpBias(s, float3(1, 2, 3), cmpVal, bias, clamp, status);
|
||||
}
|
|
@ -0,0 +1,65 @@
|
|||
// RUN: %dxc -T ps_6_8 -E main -fcgl %s -spirv | FileCheck %s
|
||||
|
||||
SamplerComparisonState s;
|
||||
|
||||
Texture1D<float4> t1;
|
||||
Texture1DArray<float4> t1_array;
|
||||
Texture2D<float4> t2;
|
||||
TextureCube<float4> tcube;
|
||||
|
||||
// CHECK: OpCapability MinLod
|
||||
// CHECK: OpCapability SparseResidency
|
||||
|
||||
// CHECK: [[v2fc:%[0-9]+]] = OpConstantComposite %v2float %float_1 %float_2
|
||||
// CHECK: [[v2f_2:%[0-9]+]] = OpConstantComposite %v2float %float_2 %float_2
|
||||
// CHECK: [[v2f_3:%[0-9]+]] = OpConstantComposite %v2float %float_3 %float_3
|
||||
// CHECK: [[v2ic:%[0-9]+]] = OpConstantComposite %v2int %int_n5 %int_7
|
||||
// CHECK: [[v3fc:%[0-9]+]] = OpConstantComposite %v3float %float_1 %float_2 %float_3
|
||||
// CHECK: [[v3f_1:%[0-9]+]] = OpConstantComposite %v3float %float_1 %float_1 %float_1
|
||||
// CHECK: [[v3f_2:%[0-9]+]] = OpConstantComposite %v3float %float_2 %float_2 %float_2
|
||||
|
||||
|
||||
// CHECK: %SparseResidencyStruct = OpTypeStruct %uint %float
|
||||
|
||||
void main() {
|
||||
float cmpVal;
|
||||
|
||||
float clamp;
|
||||
|
||||
// CHECK: [[t1:%[0-9]+]] = OpLoad %type_1d_image %t1
|
||||
// CHECK-NEXT: [[sampler:%[0-9]+]] = OpLoad %type_sampler %s
|
||||
// CHECK-NEXT: [[cmpVal:%[0-9]+]] = OpLoad %float %cmpVal
|
||||
// CHECK-NEXT: [[sampledImg:%[0-9]+]] = OpSampledImage %type_sampled_image [[t1]] [[sampler]]
|
||||
// CHECK-NEXT: {{%[0-9]+}} = OpImageSampleDrefExplicitLod %float [[sampledImg]] %float_1 [[cmpVal]] Grad %float_2 %float_3
|
||||
float val1 = t1.SampleCmpGrad(s, 1, cmpVal, 2, 3);
|
||||
|
||||
// CHECK: [[t1Array:%[0-9]+]] = OpLoad %type_1d_image_array %t1_array
|
||||
// CHECK-NEXT: [[sampler:%[0-9]+]] = OpLoad %type_sampler %s
|
||||
// CHECK-NEXT: [[cmpVal:%[0-9]+]] = OpLoad %float %cmpVal
|
||||
// CHECK-NEXT: [[sampledImg:%[0-9]+]] = OpSampledImage %type_sampled_image_0 [[t1Array]] [[sampler]]
|
||||
// CHECK-NEXT: {{%[0-9]+}} = OpImageSampleDrefExplicitLod %float [[sampledImg]] [[v2fc]] [[cmpVal]] Grad|ConstOffset %float_2 %float_3 %int_n5
|
||||
float val2 = t1_array.SampleCmpGrad(s, float2(1, 2), cmpVal, 2, 3, -5);
|
||||
|
||||
|
||||
// CHECK: [[t2:%[0-9]+]] = OpLoad %type_2d_image %t2
|
||||
// CHECK-NEXT: [[sampler:%[0-9]+]] = OpLoad %type_sampler %s
|
||||
// CHECK-NEXT: [[cmpVal:%[0-9]+]] = OpLoad %float %cmpVal
|
||||
// CHECK-NEXT: [[clamp:%[0-9]+]] = OpLoad %float %clamp
|
||||
// CHECK-NEXT: [[sampledImg:%[0-9]+]] = OpSampledImage %type_sampled_image_1 [[t2]] [[sampler]]
|
||||
// CHECK-NEXT: {{%[0-9]+}} = OpImageSampleDrefExplicitLod %float [[sampledImg]] [[v2fc]] [[cmpVal]] Grad|ConstOffset|MinLod [[v2f_2]] [[v2f_3]] [[v2ic]] [[clamp]]
|
||||
float val3 = t2.SampleCmpGrad(s, float2(1, 2), cmpVal, float2(2, 2), float2(3, 3), uint2(-5, 7), clamp);
|
||||
|
||||
uint status;
|
||||
|
||||
// CHECK: [[tcube:%[0-9]+]] = OpLoad %type_cube_image %tcube
|
||||
// CHECK-NEXT: [[sampler:%[0-9]+]] = OpLoad %type_sampler %s
|
||||
// CHECK-NEXT: [[cmpVal:%[0-9]+]] = OpLoad %float %cmpVal
|
||||
// CHECK-NEXT: [[clamp:%[0-9]+]] = OpLoad %float %clamp
|
||||
// CHECK-NEXT: [[sampledImg:%[0-9]+]] = OpSampledImage %type_sampled_image_2 [[tcube]] [[sampler]]
|
||||
// CHECK-NEXT: [[structResult:%[0-9]+]] = OpImageSparseSampleDrefExplicitLod %SparseResidencyStruct [[sampledImg]] [[v3fc]] [[cmpVal]] Grad|MinLod [[v3f_1]] [[v3f_2]] [[clamp]]
|
||||
// CHECK-NEXT: [[status:%[0-9]+]] = OpCompositeExtract %uint [[structResult]] 0
|
||||
// CHECK-NEXT: OpStore %status [[status]]
|
||||
// CHECK-NEXT: [[result:%[0-9]+]] = OpCompositeExtract %float [[structResult]] 1
|
||||
// CHECK-NEXT: OpStore %val4 [[result]]
|
||||
float val4 = tcube.SampleCmpGrad(s, float3(1, 2, 3), cmpVal, float3(1, 1, 1), float3(2, 2, 2), clamp, status);
|
||||
}
|
Загрузка…
Ссылка в новой задаче