<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/234053>234053</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
[HLSL][DirectX][SPIRV] Add SampleCmpLevel, SampleCmpGrad and SampleCmpBias in Clang
</td>
</tr>
<tr>
<th>Labels</th>
<td>
backend:DirectX,
HLSL,
backend:SPIR-V
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
Icohedron
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
Icohedron
</td>
</tr>
</table>
<pre>
Add SampleCmpLevel, SampleCmpGrad and SampleCmpBias to Clang with DirectX and SPIR-V lowering and DXIL sampling feature flags. Test Level and Grad in vertex and pixel shaders, and Bias in pixel shaders.
## Acceptance Criteria
### Implement methods
- [ ] Add the methods in `Overloads` to the six comparison-capable textures, starting in [clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp], [clang/lib/Sema/HLSLExternalSemaSource.cpp] and [clang/include/clang/Basic/Builtins.td].
- [ ] Emit the methods as intrinsics in [clang/lib/CodeGen/CGHLSLBuiltins.cpp], declaring them in [llvm/include/llvm/IR/IntrinsicsDirectX.td] and [llvm/include/llvm/IR/IntrinsicsSPIRV.td]; mark the `SampleCmpBias` intrinsics `IntrConvergent`.
- [ ] Lower the intrinsics to the DXIL operations in `DirectX`, starting in [llvm/lib/Target/DirectX/DXIL.td] and [llvm/lib/Target/DirectX/DXILOpLowering.cpp].
- [ ] Lower the intrinsics to the SPIR-V operations in `SPIR-V` in [llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp].
### Feature flags
- [ ] Set `AdvancedTextureOps` and `SampleCmpWithGradientOrBias` by the rules in `Sampling feature triggers` in [llvm/lib/Target/DirectX/DXILShaderFlags.cpp].
### Compiler tests
- [ ] Test accepted overloads and the rejections in `Availability and limits` in `clang/test/SemaHLSL/Resources/Textures-SampleCmpLevel.hlsl`, `clang/test/SemaHLSL/Resources/Textures-SampleCmpGrad.hlsl` and `clang/test/SemaHLSL/Resources/Textures-SampleCmpBias.hlsl` (new).
- [ ] Write CodeGen tests for the new methods, including the `SampleCmpBias` convergent call attribute, in `clang/test/CodeGenHLSL/resources/Textures-SampleCmpLevel.hlsl`, `clang/test/CodeGenHLSL/resources/Textures-SampleCmpGrad.hlsl` and `clang/test/CodeGenHLSL/resources/Textures-SampleCmpBias.hlsl` (new).
- [ ] Test DXIL lowering for each `Overloads` shape in `llvm/test/CodeGen/DirectX/SampleCmpLevel.ll`, `llvm/test/CodeGen/DirectX/SampleCmpGrad.ll` and `llvm/test/CodeGen/DirectX/SampleCmpBias.ll` (new).
- [ ] Test SPIR-V lowering for each `Overloads` shape in `llvm/test/CodeGen/SPIRV/hlsl-resources/SampleCmpLevel.ll`, `llvm/test/CodeGen/SPIRV/hlsl-resources/SampleCmpGrad.ll` and `llvm/test/CodeGen/SPIRV/hlsl-resources/SampleCmpBias.ll` (new).
- [ ] Test `SampleCmpBias` pixel acceptance and unsupported noncompute-stage rejection in [clang/test/SemaHLSL/Resources/Textures-derivative-availability.hlsl].
- [ ] Test every row of `Sampling feature triggers` in [llvm/test/CodeGen/DirectX/ShaderFlags/advanced-texture-ops.ll].
## DirectX
[docs/DXIL.rst][dxil-expanded-opcodes] identifies `SampleCmpLevel` (opcode 224), `SampleCmpGrad` (opcode 254) and `SampleCmpBias` (opcode 255), and [proposals/0014-expanded-comparison-sampling.md][expanded-dxil] specifies the `sampleCmpGrad` and `sampleCmpBias` operands.
### Sampling feature triggers
Bits are shader-property/SFI0. Check analysis output, `dx.entryPoints` tag 0 and SFI0.
| Flag | Set when | Not set by |
| --- | --- | --- |
| `AdvancedTextureOps` (34/29) | Every `SampleCmpLevel`, with or without offsets. | — |
| `AdvancedTextureOps` (34/29) | `SampleCmp`, `SampleCmpLevelZero`, `SampleCmpGrad` or `SampleCmpBias` has an offset that stays nonconstant after simplification. The existing `Sample`, `SampleBias`, `SampleLevel` and `SampleGrad` rule already does this. | Omitted, constant or folded offsets; dynamic non-offset operands. |
| `SampleCmpWithGradientOrBias` (37/31) | Every `SampleCmpGrad` and `SampleCmpBias`, including constant gradients, bias and offsets. | Ordinary `SampleGrad` and `SampleBias`; other comparison methods. |
[docs/DXIL.rst][dxil-flags] defines the shader-flag encodings.
## SPIR-V
[OpImageSampleDrefExplicitLod] with `Lod` or `Grad` implements `SampleCmpLevel` and `SampleCmpGrad`, and [OpImageSampleDrefImplicitLod] with `Bias` implements `SampleCmpBias`; [SPIR-V image operands] defines those operands.
## HLSL
### Overloads
`s` is `SamplerComparisonState`, `p` is the location, `r` is the float comparison reference, `o` is the constant spatial offset, `c` is the float minimum-LOD clamp, `lod` is the float LOD, `gx` and `gy` are spatial gradients and `b` is the float bias. Every overload returns scalar `float`. `Receiver shapes` gives the location, gradient and offset types.
| Method | `Texture1D`, `Texture1DArray`, `Texture2D`, `Texture2DArray` | `TextureCube`, `TextureCubeArray` |
| --- | --- | --- |
| `SampleCmpLevel` | `(s,p,r,lod)`, `(s,p,r,lod,o)` | `(s,p,r,lod)` |
| `SampleCmpGrad` | `(s,p,r,gx,gy)`, `(s,p,r,gx,gy,o)`, `(s,p,r,gx,gy,o,c)` | `(s,p,r,gx,gy)`, `(s,p,r,gx,gy,c)` |
| `SampleCmpBias` | `(s,p,r,b)`, `(s,p,r,b,o)`, `(s,p,r,b,o,c)` | `(s,p,r,b)`, `(s,p,r,b,c)` |
### Receiver shapes
| Receivers | Location | Spatial gradient | Constant spatial offset |
| --- | --- | --- | --- |
| `Texture1D<T>`, `Texture1DArray<T>` | `float`, `float2` | `float` | `int` |
| `Texture2D<T>`, `Texture2DArray<T>` | `float2`, `float3` | `float2` | `int2` |
| `TextureCube<T>`, `TextureCubeArray<T>` | `float3`, `float4` | `float3` | None |
### Availability and limits
| Subject | Rule |
| --- | --- |
| `SampleCmpLevel` | SM6.7/DXIL1.7; all stages. |
| `SampleCmpGrad`, `SampleCmpBias` | SM6.8/DXIL1.8; `SampleCmpGrad` in all stages, `SampleCmpBias` in pixel shaders. |
| Stages exercised here | `SampleCmpLevel` and `SampleCmpGrad` in vertex and pixel shaders; `SampleCmpBias` in pixel shaders. |
| Element types | Floating scalar or vector elements; native-half elements need SM6.2/DXIL1.2. |
| Bias and offsets | Shader bias may be dynamic, and DXIL limits it to [-16,15.99]; before SM6.7, offsets are immediates in [-8,7]. |
| Rejected sources | Ordinary samplers; integer, unsigned, double, bool and aggregate elements; `Texture3D`, multisampled and read-write receivers; status outputs. |
| Compatibility | Support scalar-float `TextureCubeArray.SampleCmpGrad`, although the proposal excludes it. |
[SM6.7 SampleCmpLevel] defines `SampleCmpLevel`; [proposals/0014-expanded-comparison-sampling.md][expanded-hlsl] defines `SampleCmpGrad` and `SampleCmpBias`, and its validation section, [proposals/0014-expanded-comparison-sampling.md][expanded-validation], gives the model and bias rules.
[clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp]: https://github.com/llvm/llvm-project/blob/1b4e7f41268eb3db5300e79256764140e509e3f5/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp
[clang/include/clang/Basic/Builtins.td]: https://github.com/llvm/llvm-project/blob/1b4e7f41268eb3db5300e79256764140e509e3f5/clang/include/clang/Basic/Builtins.td
[clang/lib/Sema/HLSLExternalSemaSource.cpp]: https://github.com/llvm/llvm-project/blob/1b4e7f41268eb3db5300e79256764140e509e3f5/clang/lib/Sema/HLSLExternalSemaSource.cpp
[clang/lib/CodeGen/CGHLSLBuiltins.cpp]: https://github.com/llvm/llvm-project/blob/1b4e7f41268eb3db5300e79256764140e509e3f5/clang/lib/CodeGen/CGHLSLBuiltins.cpp
[llvm/include/llvm/IR/IntrinsicsDirectX.td]: https://github.com/llvm/llvm-project/blob/1b4e7f41268eb3db5300e79256764140e509e3f5/llvm/include/llvm/IR/IntrinsicsDirectX.td
[llvm/include/llvm/IR/IntrinsicsSPIRV.td]: https://github.com/llvm/llvm-project/blob/1b4e7f41268eb3db5300e79256764140e509e3f5/llvm/include/llvm/IR/IntrinsicsSPIRV.td
[llvm/lib/Target/DirectX/DXILOpLowering.cpp]: https://github.com/llvm/llvm-project/blob/1b4e7f41268eb3db5300e79256764140e509e3f5/llvm/lib/Target/DirectX/DXILOpLowering.cpp
[llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp]: https://github.com/llvm/llvm-project/blob/1b4e7f41268eb3db5300e79256764140e509e3f5/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
[clang/test/SemaHLSL/Resources/Textures-derivative-availability.hlsl]: https://github.com/llvm/llvm-project/blob/1b4e7f41268eb3db5300e79256764140e509e3f5/clang/test/SemaHLSL/Resources/Textures-derivative-availability.hlsl
[llvm/lib/Target/DirectX/DXILShaderFlags.cpp]: https://github.com/llvm/llvm-project/blob/1b4e7f41268eb3db5300e79256764140e509e3f5/llvm/lib/Target/DirectX/DXILShaderFlags.cpp
[llvm/test/CodeGen/DirectX/ShaderFlags/advanced-texture-ops.ll]: https://github.com/llvm/llvm-project/blob/1b4e7f41268eb3db5300e79256764140e509e3f5/llvm/test/CodeGen/DirectX/ShaderFlags/advanced-texture-ops.ll
[dxil-expanded-opcodes]: https://github.com/microsoft/DirectXShaderCompiler/blob/791e06620e6eccad215440ff2af6f37620589115/docs/DXIL.rst#L2363-L2394
[expanded-dxil]: https://github.com/microsoft/hlsl-specs/blob/5c1aae7ef249efba8a993ca50d69430c379ac1a1/proposals/0014-expanded-comparison-sampling.md#dxil-additions
[dxil-flags]: https://github.com/microsoft/DirectXShaderCompiler/blob/791e06620e6eccad215440ff2af6f37620589115/docs/DXIL.rst#shader-flags
[OpImageSampleDrefImplicitLod]: https://registry.khronos.org/SPIR-V/specs/unified1/SPIRV.html#OpImageSampleDrefImplicitLod
[OpImageSampleDrefExplicitLod]: https://registry.khronos.org/SPIR-V/specs/unified1/SPIRV.html#OpImageSampleDrefExplicitLod
[SPIR-V image operands]: https://registry.khronos.org/SPIR-V/specs/unified1/SPIRV.html#Image_Operands
[SM6.7 SampleCmpLevel]: https://microsoft.github.io/DirectX-Specs/d3d/HLSL_SM_6_7_Advanced_Texture_Ops.html#samplecmplevel
[expanded-hlsl]: https://github.com/microsoft/hlsl-specs/blob/5c1aae7ef249efba8a993ca50d69430c379ac1a1/proposals/0014-expanded-comparison-sampling.md#hlsl-additions
[expanded-validation]: https://github.com/microsoft/hlsl-specs/blob/5c1aae7ef249efba8a993ca50d69430c379ac1a1/proposals/0014-expanded-comparison-sampling.md#validation-changes
[llvm/lib/Target/DirectX/DXIL.td]: https://github.com/llvm/llvm-project/blob/1b4e7f41268eb3db5300e79256764140e509e3f5/llvm/lib/Target/DirectX/DXIL.td
_Disclaimer: This issue was written with the help of AI and may contain some inaccuracies._
</pre>
<img width="1" height="1" alt="" src="http://email.email.llvm.org/o/eJzMWltv27jy_zTKC2FDpiw7fshD4tT7D5D9Z9EUu4vzElDSyOIpRQok7cTf_oAXyZIs39qiLVDEFTXk_ObKIUdEKbrmAHdB_BBg_JSKAjIpeIBxED_ekI0uhLxrhm8Ske3u7rMMvZKyYrAsq2fYAgvwcj_yhyQZIrxF80CJQlqgJSN8jd6pLtAjlZDqfx3dX0-fR38jJt5BUr62Y4__Pj0jZRYwIzkQvZGAckbWaoy-gNLIMra0liHlaAtSw4cdqugHMKQKkoFUBp0ZtDAo774cB-G9-YejAEfoPk2h0oSngJaSapCUtN8bkicjVAlcoxJ0ITLlCEYoiB9QED8iox5dQP3acAxm4csWJBMkU8EsNLowFIp-oFSUFZFUCT5KSUUSBkjDh5HW4laaSG1UYFaJH1KjwQCvGE0CvHqFkgR49X_Pr88PG8o05V92FTxCysxjBnKcVlUQP5qFTk3-9KFBcsLM0KvYyBT8RKu21kzKU7bJIMCreuSBKJqaX8dfjXUWxI_jjkI-lVR3NGLNoCXliqZqULKlyOAP4OZ_f7TEUy2BMkgZsf6iCyj9Koxtyw5OP_D02fxpeHrvc2BrIS-ca7z1bzcziB5QSeRXK1wwCzsOb-zckjKYhWaNpeBbkGvgOpiFXTU9G_-3S7WmeU-x4SAqkERTwWuf8mIEs3DAVTx6p88vRK5BB3hVT8Ers-SgAk7OeKmefZh6U1wugw_zAyncuFPXcRhW7fXvE1dablKzyiswSLWQLTidcF21U0c_VF9BGwT32daEfPbFBd5LZY1ntdIy6j9UFybVUOD6RdYmTnZWOLlh0AjUT1ta0vXaJKIzMnZV_WoT1MqmvCPCLUVZUWY0DkofSGfTJLEZDTIk6gRkBbOY4b-Qti1xvyWUkYQyqneWitGS6gb2LKyD1LDzKcREZ4BXn0HZxKGMPD5_jbqbxLhginlf_Y61jAnqpWobfetaxojNWgG-5fAe4EXXpf8x-wDyCckpGuXCOTmH92YXwEvkUodPSYMJIW3CH6WEMUS0ljTZaHDTB2TxjL048nvVfM1yF2j6muUuUbZ1WZvsmmrA6BpIWhxsoqogFXil-XjqoupEVE9JrKWiKyZblbC2Qq6YbBXAzorfL4e-SwF12jR6H7Xt8w36OL_W5eo5v9aF2hqKMlfgkX0tZ8BsuNpUlZAmF3LBTd210TBSmqxbqbBXjVyYUDKQdEs03cKItHKo8_b-HmlhwxbkDknxjkR-3Z5xytP2O0aAV8TvaiNfT45EZRXa20fqUtyPxQ-ZSFVdH0ilTZ0TP2QflI3goyI8g2wkqlRkoIw0NAOuaU5BdUzhjgXOdo4aYTwN8ML7WMdlenSxoTvYfmvjtgljv6AvYCopKqEIM_DDcDLdA25V2fWhYlxmTrSGyMhoRFIVpE4in8ZVH6zHpvrYbG3DM3WwUR83ryV8oFohIsEfSkZGEJB6Z2y6egrHaFlA-hURTthOUYXERlcb7VWZfYyBa7n7S1DuNmtN1siBtLM9mPkSGddA5j-m8HkvgNuH_xcaKdCmlAnmS086Go3QwK9_e7RoCvBtNA3wythlYSd-sp4-5BsGvz0MCml_xUYjkecKtBrbqcEnHNyGwWL6bZzbPPfZrQvjPyDFwLva0EIO-mBBTBXlwSJdEG2q751yiYUrTbhGJNcgkaLG8jlNbc07Rl8KQPBBla3Um7X7EDyjzlgTUp3IqJGaAhQRJoFkO5QJ67zU6_GlpFpDZlZr0AmJcsEyUxg6lZvDTLbjpKSpEWPkhWtcumuDM1WxMcY8wKtoctwNesHUV3K3oGpwrz0vW3AllLhytuM2LzKjnLS5DbKq-UQPSOgCZOsoXhd1jdBnEqM7XMSPKIOccp84fCybdwh4KowcvesGf_SpGbxUTyVZg4P3KCH_9FExmlL9LOw5zQZLMAvNY-OctWy0vpc4koj7avbzWunzgP1TOci-Od0Oc2zpNYgffDVDzcqNM3VVJRQMZ05k99xeKt2XQO7FLHRgWiDksrHkqya6FV2VJzX2YcLFpH8lW69yJohu-4OEHCTwFDyxaBE3rqkqoilh3hnr-vtg2ZJyWm7K0fPLI0oZKau67HJW7dA-vzz6t-uPlhHXO_tgNgzPswmLmiQ5WMsEy9jHYX0YRBL0RnKFVEoYsf5kiYNZODYPnyEFujVpzNSaVtFruoVDBdb8W9GI9K4C1dp9_rRBVadmn70nj3vrNEP3UpLdwTg-JMUNaW_Z5SaBA2oz2Ka_dKsbqGrciwDfmjxkLCgDvDQWxIs926HXS-FIzi1xBEFTLg3OXn-YP7tTIBqSGsgFZMv0JOaruKYnxWv2j0FGySkWyTmRkouEOcujJ0A7NfWjpfH8-oWyTJ993LhKrBfAdnA5nFLO--yh7-7DLFp-CaJPR6OteV0rpk4Entw-4oH39TPl-sCw-8g9wh2f5I577KMhghZ_fAyATQdHIOyzwjCIqAdiOkTgC2kOQ35x7F6t8Y_XTWLOn3aRz6aQO2roc0np9c_ZeO6LlMl4bjZhwhiyp9yjNVyrFDgWjGbd22bdW7u5D6Qlylvsjq130IJpwXq1MxF8gEypggwVIOGgmj9X1JzsBvWgX4Lqk-_42B0NuZOUILaE9xunkGhr76ER-JrI8OHuTqAgLG_GEQfIrD5xo0_cZvbQK2qd_i0oV_CWZIcSqIv1uoBzt2bWsRDVSAtTfY0mswAvJ_F4sfD9igRyIaH2k2XDxBQTtCwho0RD3ZQZ3QZ4OQ_ixza-z_auBDLkL0K6Nbc7Ezs1U65hDSZxog23jUZ7BsnEJmG2kkqEcC08sl5LWBMNHfXtYzSqt_5ywzR1PFyT0Rx4Ru_2jlbWWdbMVZroTX1S7hjTFoea-nB04WcvhrwtR65cGkgQ48HimZmT67qwJVF9A4Hgw3aRjCm6hwir-H77tFUODx6UXSn9ndcb_jJqkNMFZzHzyvjWljCauf1LuTsz3178Tnj7dX2Db19oliLzrV7r_7bXMm40-o090egeFVpXKojuA7wK8GpNdbFJxqko970_8zOqpDAeH-BVwoThMUmmMM-nEzy7hSTKkjgKQ5gvcDybz6aTaQhxuIAoj1t90mvAdaS6tOX6k-W5DNZp-xxtO_9q2xwBNiDNuT71rxDkJCYrw7d0yX-SKNdDu0aiTu_-d5KnAdaW5rpG_M8V6BpsJ2S6sKv_S2W7CGMnN_yYrtFPTh4_AvTF3nv4bcNv5L59cG2pfkD37edK-t2A3dX3kfbfGVlKmkqhRN7SsWNaf7iyl2y-mEA4m-EQZpCmJMOTeDoN8xyTfJZH8xkO49vFZGIk69_D4-gZR7No9IyjxdTh7ff0rsBpO9KqAsvDg4vTCSEwhxxPF5An5JYsFlFK4jCbLaZRmEbzBUknZBLg1dVVMI6sckmWUfstTkvhdVvhN9Fyq6GhjjQsuh2DQ9wS1lRpuRt_LaTgQo2FXPvUOjI5ttb7htOcQjap0-640CULcHSS4SU9lJ8Aqc3QHfmOtEB-PBaL5O2lZnHqwHnIvHGjsfcuKvYONXr1rLMo81Xy2-ufb7O3-Vvdjn3ze8TbS6VqQO6knpo_hm03Ni_b535tbFqOvdg8cmT9ncXYIx2lBeFrUJfv1b-iXj4LyB7-3x6pShmhJUgD70tBFaJKbQC9E4XeJdUauGtb6gJQAaxCIkf3T_YuoSQ7lAquCeVIiRIQ5SRNN5KkFNT4LQjvb7K7KFtEC3IDdxODdzqfLaKb4i5JMIZFNodwOk1n03gSkiie55MwIwC3t-SG3uEQzyYhnoSTeBpHYxzilCTZJIqn80UeZcE0hJJQNjYCmzC_scDvcDQN4-iGkQSY8l_lJyT9CjwLovtGDzjAywBjV6j5hz1ZnS_sN_zyzhol2axVMA0ZVVrtmWqqmf34365kL2RqHvbB1b7-o_brv_mn3H3zf7OR7O5q77EaMU7ulbK9w_8LAAD__-1KXUY">