@@ -5143,10 +5143,13 @@ SpirvEmitter::processIntrinsicMemberCall(const CXXMemberCallExpr *expr,
5143
5143
retVal = processTextureSampleGrad(expr);
5144
5144
break;
5145
5145
case IntrinsicOp::MOP_SampleCmp:
5146
- retVal = processTextureSampleCmpCmpLevelZero (expr, /*isCmp=*/true );
5146
+ retVal = processTextureSampleCmp (expr);
5147
5147
break;
5148
5148
case IntrinsicOp::MOP_SampleCmpLevelZero:
5149
- retVal = processTextureSampleCmpCmpLevelZero(expr, /*isCmp=*/false);
5149
+ retVal = processTextureSampleCmpLevelZero(expr);
5150
+ break;
5151
+ case IntrinsicOp::MOP_SampleCmpLevel:
5152
+ retVal = processTextureSampleCmpLevel(expr);
5150
5153
break;
5151
5154
case IntrinsicOp::MOP_GatherRed:
5152
5155
retVal = processTextureGatherRGBACmpRGBA(expr, /*isCmp=*/false, 0);
@@ -5573,8 +5576,7 @@ SpirvEmitter::processTextureSampleGrad(const CXXMemberCallExpr *expr) {
5573
5576
}
5574
5577
5575
5578
SpirvInstruction *
5576
- SpirvEmitter::processTextureSampleCmpCmpLevelZero(const CXXMemberCallExpr *expr,
5577
- const bool isCmp) {
5579
+ SpirvEmitter::processTextureSampleCmp(const CXXMemberCallExpr *expr) {
5578
5580
// .SampleCmp() Signature:
5579
5581
//
5580
5582
// For Texture1D, Texture1DArray, Texture2D, Texture2DArray:
@@ -5595,10 +5597,55 @@ SpirvEmitter::processTextureSampleCmpCmpLevelZero(const CXXMemberCallExpr *expr,
5595
5597
// [, float Clamp]
5596
5598
// [, out uint Status]
5597
5599
// );
5598
- //
5600
+
5601
+ const auto numArgs = expr->getNumArgs();
5602
+ const bool hasStatusArg =
5603
+ expr->getArg(numArgs - 1)->getType()->isUnsignedIntegerType();
5604
+ auto *status = hasStatusArg ? doExpr(expr->getArg(numArgs - 1)) : nullptr;
5605
+
5606
+ SpirvInstruction *clamp = nullptr;
5607
+ if (numArgs > 3 && expr->getArg(3)->getType()->isFloatingType())
5608
+ clamp = doExpr(expr->getArg(3));
5609
+ else if (numArgs > 4 && expr->getArg(4)->getType()->isFloatingType())
5610
+ clamp = doExpr(expr->getArg(4));
5611
+ const bool hasClampArg = clamp != nullptr;
5612
+
5613
+ const auto *imageExpr = expr->getImplicitObjectArgument();
5614
+ auto *image = loadIfGLValue(imageExpr);
5615
+ auto *sampler = doExpr(expr->getArg(0));
5616
+ auto *coordinate = doExpr(expr->getArg(1));
5617
+ auto *compareVal = doExpr(expr->getArg(2));
5618
+ // If offset is present in .SampleCmp(), it will be the fourth argument.
5619
+ SpirvInstruction *constOffset = nullptr, *varOffset = nullptr;
5620
+
5621
+ // Subtract 1 for clamp (if it exists), 1 for status (if it exists),
5622
+ // and 3 for sampler_state, location, and compare_value.
5623
+ const bool hasOffsetArg = numArgs - hasStatusArg - hasClampArg - 3 > 0;
5624
+ if (hasOffsetArg)
5625
+ handleOffsetInMethodCall(expr, 3, &constOffset, &varOffset);
5626
+
5627
+ const auto retType = expr->getDirectCallee()->getReturnType();
5628
+ const auto imageType = imageExpr->getType();
5629
+
5630
+ if (spvContext.isCS()) {
5631
+ addDerivativeGroupExecutionMode();
5632
+ }
5633
+
5634
+ return createImageSample(
5635
+ retType, imageType, image, sampler, coordinate, compareVal,
5636
+ /*bias*/ nullptr, /*lod*/ nullptr, std::make_pair(nullptr, nullptr),
5637
+ constOffset, varOffset, /*constOffsets*/ nullptr,
5638
+ /*sampleNumber*/ nullptr, /*minLod*/ clamp, status,
5639
+ expr->getCallee()->getLocStart(), expr->getSourceRange());
5640
+ }
5641
+
5642
+ SpirvInstruction *
5643
+ SpirvEmitter::processTextureSampleCmpLevelZero(const CXXMemberCallExpr *expr) {
5599
5644
// .SampleCmpLevelZero() is identical to .SampleCmp() on mipmap level 0 only.
5600
5645
// It never takes a clamp argument, which is good because lod and clamp may
5601
5646
// not be used together.
5647
+ // .SampleCmpLevel() is identical to .SampleCmpLevel, except the LOD level
5648
+ // is taken as a float argument.
5602
5649
//
5603
5650
// .SampleCmpLevelZero() Signature:
5604
5651
//
@@ -5624,46 +5671,82 @@ SpirvEmitter::processTextureSampleCmpCmpLevelZero(const CXXMemberCallExpr *expr,
5624
5671
expr->getArg(numArgs - 1)->getType()->isUnsignedIntegerType();
5625
5672
auto *status = hasStatusArg ? doExpr(expr->getArg(numArgs - 1)) : nullptr;
5626
5673
5627
- SpirvInstruction *clamp = nullptr;
5628
- // The .SampleCmpLevelZero() methods do not take the clamp argument.
5629
- if (isCmp) {
5630
- if (numArgs > 3 && expr->getArg(3)->getType()->isFloatingType())
5631
- clamp = doExpr(expr->getArg(3));
5632
- else if (numArgs > 4 && expr->getArg(4)->getType()->isFloatingType())
5633
- clamp = doExpr(expr->getArg(4));
5634
- }
5635
- const bool hasClampArg = clamp != nullptr;
5636
-
5637
- // Subtract 1 for clamp (if it exists), 1 for status (if it exists),
5638
- // and 3 for sampler_state, location, and compare_value.
5639
- const bool hasOffsetArg = numArgs - hasClampArg - hasStatusArg - 3 > 0;
5640
-
5641
5674
const auto *imageExpr = expr->getImplicitObjectArgument();
5642
5675
auto *image = loadIfGLValue(imageExpr);
5643
5676
auto *sampler = doExpr(expr->getArg(0));
5644
5677
auto *coordinate = doExpr(expr->getArg(1));
5645
5678
auto *compareVal = doExpr(expr->getArg(2));
5679
+ auto *lod =
5680
+ spvBuilder.getConstantFloat(astContext.FloatTy, llvm::APFloat(0.0f));
5681
+
5646
5682
// If offset is present in .SampleCmp(), it will be the fourth argument.
5647
5683
SpirvInstruction *constOffset = nullptr, *varOffset = nullptr;
5684
+ const bool hasOffsetArg = numArgs - hasStatusArg - 3 > 0;
5648
5685
if (hasOffsetArg)
5649
5686
handleOffsetInMethodCall(expr, 3, &constOffset, &varOffset);
5650
- auto *lod = isCmp ? nullptr
5651
- : spvBuilder.getConstantFloat(astContext.FloatTy,
5652
- llvm::APFloat(0.0f));
5653
5687
5654
5688
const auto retType = expr->getDirectCallee()->getReturnType();
5655
5689
const auto imageType = imageExpr->getType();
5656
5690
5657
- if (!lod && spvContext.isCS()) {
5658
- addDerivativeGroupExecutionMode();
5659
- }
5691
+ return createImageSample(
5692
+ retType, imageType, image, sampler, coordinate, compareVal,
5693
+ /*bias*/ nullptr, /*lod*/ lod, std::make_pair(nullptr, nullptr),
5694
+ constOffset, varOffset, /*constOffsets*/ nullptr,
5695
+ /*sampleNumber*/ nullptr, /*clamp*/ nullptr, status,
5696
+ expr->getCallee()->getLocStart(), expr->getSourceRange());
5697
+ }
5698
+
5699
+ SpirvInstruction *
5700
+ SpirvEmitter::processTextureSampleCmpLevel(const CXXMemberCallExpr *expr) {
5701
+ // .SampleCmpLevel() is identical to .SampleCmpLevel, except the LOD level
5702
+ // is taken as a float argument.
5703
+ //
5704
+ // For Texture1D, Texture1DArray, Texture2D, Texture2DArray:
5705
+ // float Object.SampleCmpLevel(
5706
+ // SamplerComparisonState S,
5707
+ // float Location,
5708
+ // float CompareValue,
5709
+ // float LOD,
5710
+ // [, int Offset]
5711
+ // [, out uint Status]
5712
+ // );
5713
+ //
5714
+ // For TextureCube and TextureCubeArray:
5715
+ // float Object.SampleCmpLevel(
5716
+ // SamplerComparisonState S,
5717
+ // float Location,
5718
+ // float CompareValue
5719
+ // float LOD,
5720
+ // [, out uint Status]
5721
+ // );
5722
+
5723
+ const auto numArgs = expr->getNumArgs();
5724
+ const bool hasStatusArg =
5725
+ expr->getArg(numArgs - 1)->getType()->isUnsignedIntegerType();
5726
+ auto *status = hasStatusArg ? doExpr(expr->getArg(numArgs - 1)) : nullptr;
5727
+
5728
+ const auto *imageExpr = expr->getImplicitObjectArgument();
5729
+ auto *image = loadIfGLValue(imageExpr);
5730
+ auto *sampler = doExpr(expr->getArg(0));
5731
+ auto *coordinate = doExpr(expr->getArg(1));
5732
+ auto *compareVal = doExpr(expr->getArg(2));
5733
+ auto *lod = doExpr(expr->getArg(3));
5734
+
5735
+ // If offset is present in .SampleCmp(), it will be the fourth argument.
5736
+ SpirvInstruction *constOffset = nullptr, *varOffset = nullptr;
5737
+ const bool hasOffsetArg = numArgs - hasStatusArg - 4 > 0;
5738
+ if (hasOffsetArg)
5739
+ handleOffsetInMethodCall(expr, 4, &constOffset, &varOffset);
5740
+
5741
+ const auto retType = expr->getDirectCallee()->getReturnType();
5742
+ const auto imageType = imageExpr->getType();
5660
5743
5661
5744
return createImageSample(
5662
5745
retType, imageType, image, sampler, coordinate, compareVal,
5663
- /*bias*/ nullptr, lod, std::make_pair(nullptr, nullptr), constOffset ,
5664
- varOffset,
5665
- /*constOffsets */ nullptr, /*sampleNumber */ nullptr, /*minLod*/ clamp ,
5666
- status, expr->getCallee()->getLocStart(), expr->getSourceRange());
5746
+ /*bias*/ nullptr, /* lod*/ lod , std::make_pair(nullptr, nullptr),
5747
+ constOffset, varOffset, /*constOffsets*/ nullptr ,
5748
+ /*sampleNumber */ nullptr, /*clamp */ nullptr, status ,
5749
+ expr->getCallee()->getLocStart(), expr->getSourceRange());
5667
5750
}
5668
5751
5669
5752
SpirvInstruction *
0 commit comments