<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/99153>99153</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
Implement the `refract` HLSL Function
</td>
</tr>
<tr>
<th>Labels</th>
<td>
metabug,
backend:DirectX,
HLSL,
backend:SPIR-V,
bot:HLSL
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
farzonl
</td>
</tr>
</table>
<pre>
- [ ] Implement `refract` clang builtin,
- [ ] Link `refract` clang builtin with `hlsl_intrinsics.h`
- [ ] Add sema checks for `refract` to `CheckHLSLBuiltinFunctionCall` in `SemaChecking.cpp`
- [ ] Add codegen for `refract` to `EmitHLSLBuiltinExpr` in `CGBuiltin.cpp`
- [ ] Add codegen tests to `clang/test/CodeGenHLSL/builtins/refract.hlsl`
- [ ] Add sema tests to `clang/test/SemaHLSL/BuiltIns/refract-errors.hlsl`
- [ ] Create the `int_dx_refract` intrinsic in `IntrinsicsDirectX.td`
- [ ] Create the `DXILOpMapping` of `int_dx_refract` to `56` in `DXIL.td`
- [ ] Create the `refract.ll` and `refract_errors.ll` tests in `llvm/test/CodeGen/DirectX/`
- [ ] Create the `int_spv_refract` intrinsic in `IntrinsicsSPIRV.td`
- [ ] In SPIRVInstructionSelector.cpp create the `refract` lowering and map it to `int_spv_refract` in `SPIRVInstructionSelector::selectIntrinsic`.
- [ ] Create SPIR-V backend test case in `llvm/test/CodeGen/SPIRV/hlsl-intrinsics/refract.ll`
## DirectX
| DXIL Opcode | DXIL OpName | Shader Model | Shader Stages |
| ----------- | ----------- | ------------ | ------------- |
| 56 | Dot4 | 6.0 | () |
## SPIR-V
# Refract:
## Description:
**Refract**
For the incident vector *I* and surface normal *N*, and the ratio of
indices of refraction *eta*, the result is the refraction vector. The
result is computed by
k = 1.0 - *eta* \* *eta* \* (1.0 - dot(*N*, *I*) \* dot(*N*, *I*))
if k \< 0.0 the result is 0.0
otherwise, the result is *eta* \* *I* - (*eta* \* dot(*N*, *I*) +
sqrt(k)) \* *N*
The input parameters for the incident vector *I* and the surface normal
*N* must already be normalized to get the desired results.
The type of *I* and *N* must be a scalar or vector with a floating-point
component type.
The type of *eta* must be a 16-bit or 32-bit floating-point scalar.
*Result Type*, the type of *I*, and the type of *N* must all be the same
type.
<table>
<colgroup>
<col style="width: 20%" />
<col style="width: 20%" />
<col style="width: 20%" />
<col style="width: 20%" />
<col style="width: 20%" />
</colgroup>
<thead>
<tr>
<th>Number</th>
<th>Operand 1</th>
<th>Operand 2</th>
<th>Operand 3</th>
<th>Operand 4</th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p>72</p></td>
<td
class="tableblock halign-left valign-top"><p><em><id></em><br />
<em>I</em></p></td>
<td
class="tableblock halign-left valign-top"><p><em><id></em><br />
<em>N</em></p></td>
<td
class="tableblock halign-left valign-top"><p><em><id></em><br />
<em>eta</em></p></td>
<td></td>
</tr>
</tbody>
</table>
## Test Case(s)
### Example 1
```hlsl
//dxc refract_test.hlsl -T lib_6_8 -enable-16bit-types -O0
export float4 fn(float4 p1, float4 p2, float p3) {
return refract(p1, p2, p3);
}
```
## HLSL:
Returns a refraction vector using an entering ray, a surface normal, and a refraction index.
| *ret* refract(*i*, *n*, ?) |
|----------------------------|
## Parameters
| Item | Description |
|--------------------------------------------------------|--------------------------------------------------------------|
| <span id="i"></span><span id="I"></span>*i*<br/> | \[in\] A floating-point, ray direction vector.<br/> |
| <span id="n"></span><span id="N"></span>*n*<br/> | \[in\] A floating-point, surface normal vector.<br/> |
| *?*<br/> | \[in\] A floating-point, refraction index scalar.<br/> |
## Return Value
A floating-point, refraction vector. If the angle between the entering ray i and the surface normal n is too great for a given refraction index ?, the return value is (0,0,0).
## Type Description
| Name | [**Template Type**](https://github.com/MicrosoftDocs/win32/blob/docs/desktop-src//direct3dhlsl/dx-graphics-hlsl-intrinsic-functions.md) | [**Component Type**](https://github.com/MicrosoftDocs/win32/blob/docs/desktop-src//direct3dhlsl/dx-graphics-hlsl-intrinsic-functions.md) | Size |
|-------------------|-------------------------------------------------------------------------------------|----------------------------------------------------------------|--------------------------------|
| *i* | [**vector**](https://github.com/MicrosoftDocs/win32/blob/docs/desktop-src//direct3dhlsl/dx-graphics-hlsl-intrinsic-functions.md) | [**float**](/windows/desktop/WinProg/windows-data-types) | any |
| *n* | [**vector**](https://github.com/MicrosoftDocs/win32/blob/docs/desktop-src//direct3dhlsl/dx-graphics-hlsl-intrinsic-functions.md) | [**float**](/windows/desktop/WinProg/windows-data-types) | same dimension(s) as input *i* |
| ? | [**scalar**](https://github.com/MicrosoftDocs/win32/blob/docs/desktop-src//direct3dhlsl/dx-graphics-hlsl-intrinsic-functions.md) | [**float**](/windows/desktop/WinProg/windows-data-types) | 1 |
| refraction vector | [**vector**](https://github.com/MicrosoftDocs/win32/blob/docs/desktop-src//direct3dhlsl/dx-graphics-hlsl-intrinsic-functions.md) | [**float**](/windows/desktop/WinProg/windows-data-types) | same dimension(s) as input *i* |
## Minimum Shader Model
This function is supported in the following shader models.
| Shader Model | Supported |
|------------------------------------------------------------------------------------|---------------------|
| [Shader Model 2 (DirectX HLSL)](https://github.com/MicrosoftDocs/win32/blob/docs/desktop-src//direct3dhlsl/dx-graphics-hlsl-sm2.md) and higher shader models | yes |
| [Shader Model 1 (DirectX HLSL)](https://github.com/MicrosoftDocs/win32/blob/docs/desktop-src//direct3dhlsl/dx-graphics-hlsl-sm1.md) | yes (vs\_1\_1 only) |
## See also
<dl> <dt>
[**Intrinsic Functions (DirectX HLSL)**](https://github.com/MicrosoftDocs/win32/blob/docs/desktop-src//direct3dhlsl/dx-graphics-hlsl-intrinsic-functions.md)
</dt> </dl>
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJzsWV9v47gR_zTMCyFDpmLHefCDI6-vBnazh02wvbeAksYyG4pUSTp_9tMXQ0qWZDvOdg9oU_QMJxY5w_nH4eg3ErdWlApgTiY3ZLK84Du31Wa-4eaHVvIi08XrPKJkckPJZEnXVS2hAuUomcYGNobnjkxjmkuuSprthHRCEZaSeNEt-izU4zl--izcFhm20soHoZwRyorcjrZkGg8kLYqCWqg4zbeQP1q60eZAsNM4kSL5b5_vPt8EDaudyp3QKuVSIpdQyHUHFfecQpWjvK5Pact1ASWoNzV9qoTrKfr0UptOQfpbM_2edAfW2UaiDw1hK5wjbJXqAn4DhToIWzURs4StGlNGGLQ343RGMHrfSPVWrvtSIzBGG3tSeGqAO6BuCyhVKPdQvDz0ArPfwCYK6_2GLoWB3P0xcsV5mcs_1p-_1l94XQtVoki9Oa3KaYqEybSLOa59V0Ebu5ANXBW9yYfG9UALAQyipXyqjjaGsFXjFmGr90Nl66efi9Xd7-tv3084slbUk9bKOrPzWX0HEnKnDWYZzU85iqqkfgYjVOndrXhNqXBNZpw0zJ-QNzSRZEGShfWjvclkGo9OeY9Cou804_kjqMJHlObcwjtR9boJW2EKRl1R6GW-bFITvywhLKHtToS5q5RiNtCvNZ4z2hvf8iqM77a8AEO_6AJkf-LO8RIszjSCou5D3xkfT0Q9QZNpMES7S38xHcX-l7AZYdct496jELz9FP3WbFGyGDoONjeixj1qSAy_LbcfUEri8G-ljU8QoXJRYDF_8rtKCVuskREzxO7MhudAlTYVl0i69WJST8XVhjuhqd6QeCFUIXKweE6bzRFa4RpwvFnlV4DdSUeFbUZ7zqB_RO-3QOJFx5brqt45KGj26g0n8eKRkmRJx6OYRp0CSiap_zmemAXWQjsf4b0Xja8-5oH3DAtyNfrFhj76FUlK41F84BfONIzabcE8CwvH3p-y2wc-CmlwQD1rO7sh8cL-0yDLY2NqJ_W23XcSL-79jtc7R2tueAUOTLiDvpcKSB-mQ0gwL7zaWUe5NMCLV5q1DOIHFFhcSnB-eQFWGCiaGNhRl4tolXutwdf4ntKB_AwopzbnkhuqTWujhw2cbqTmTqgyqrVQjsQLzBqt0BkU_LauJsqdhvE0yoRDDQnzV0PRjQU9gf6I-V29f62hl-kHHvWPTY_UD6BEE3ykeYWHwJvenPEkdTyTQJJPYZRrWRq9q_sT1LpXZFkSxp5F4bYkWVAWEzYhjFG8N_0vMxO2OnLabYEX3cj0CCT5dLurMjBhqZ_o0b7WYHA7xufJ7Dw5OU--PCLjyAxGQw8Qa5_0p0C8bG0IlE-FTOr8kW65FKWKJGwcfQrXTteEMVyapBiqq8aJOkyh0p7GAk_Lr4omSQoV_rKpdCS5EQVh0xKvgqJATNLMDLbST6-HLB_PwNuPbiAWr5818cTscS4Osg8neiUnHqKNe4RwKcdb28ziPccTfVUMHMj06YVjs0jHSJ3G4ev7CZSzImxVvOQtCHhA-Oe7DRrdUymyh-nDjEag0IhoPM2Ei7AiWhp9bSAfvNTaNCX6km4UYbPmuh5jvW0HbD-gdRIg1o2v35QacDujWhsIm4WVYYlnxq1A3LbsO9EFwvdPLRT75qVZyo-RDd3ZgLwpKBdQuOGv_q5weGdt7hQDIUIV8DIabIRHjAsDiO16DhC2EB1IUO1lsuphy6s0OvPpAOh-Uzt_f98Dh0Nj1g6qAGw7JPpzCt8x5leXDrzBaCWprbmioggnVexPImErpITBgGd9iqeJMJ7KcCgDfJ-kZHIjlP9d0sUhKmEp7jgtfIPSg7x9OZTSt-1VP2Hv7Wl71a_Ze9ABnDS4Zy_qWP1iZA5SvQVaB6Lezstw9Oh3LncQCO-oaRuO9cZjLq5KCTQD9wyg_Ez_nFLxBgymyvcyWtMSW10PpjktxROoY598dNpOwJv7hOaGfmAWE5Y2f9ejYbFFvNjv7w5Onu9lB58Q9ZvQ9d1DVUtsw_cIdUEmS8JmW-dqi8XL1-JSuO0uG-Uae_EvIjfa6o1bat9wPwuVMMJWmdQZ1u0wW4B9dLqOrMmbeu6TOyl8kcfyHpWG11uR22jYxEeb5nmcHVVFU5k6i9M9fP_oJt-JH3C2yP3p-vV2WfsPiBgcbuE7ybfzLJyoj7xbe1N9ZehbGiwo9HNPK2Grvwv1u9FlR40K7njAIa1Qrl7pmc8ghOqvEJ4KITa8tBAVKIvlLUBKym3zsKLNvf6tcXUq0J114fbxfxfI8blM7OfiMT79Kw__3Tw8DUS-CCWqXTV4rtw-fROWtr7gTd_uamxgoKAiQI6NllI_I-awYXWFq-0R7j9-Zr2X9KcB96_cMXoHc3IzMI4hsmmeyYdeiV3_txLKVqxJIMRyW1FuwQwD7WP5CvZcET9wcPyhHBz3Tgj6QdjsyZJJ-jD2_6hW8nX4juFEBt8BUC6t3j96LKSH30lauO5pQHv-9i9_aPuK1Z4KyccsJftHHd4z2lyjuxfFPCmuk2t-AfPxFRuPp3EyHl9s5xlLNnFyxTcQw6aYTvlsxqdXAJtLPs6yOL4Qcxazy_hqPGVxPImvR1eMXRUMgF1dzuJ8nJHLGCou5EjKp2qkTXkhrN3B_Pp6PEkuJM9AWv8unrEKHM92JTZ1LCWMNW_QSLLYv3FsKCHOR2zNy6M9QTuSLFreyfLCzNGIKNuVllzGUlhnO7OccBLm3Qv_4zeKKGm_7xc7I-dnNrd5zecV1kb_A3JH2Mr7jrsa3H-as38FAAD__2lzbNM">