[D3D12] Truncate depth to float24 in EDRAM range ownership transfers and resolves by default
Doesn't ruin the "greater or equal" depth test in subsequent rendering passes if precision is lost, unlike rounding to the nearest
This commit is contained in:
@@ -53,9 +53,9 @@ ushr [precise(y)] r0.y, r0.y, r0.z
|
||||
ult [precise(z)] r0.z, r0.x, l(0x38800000)
|
||||
iadd [precise(x)] r0.x, r0.x, l(0xc8000000)
|
||||
movc [precise(x)] r0.x, r0.z, r0.y, r0.x
|
||||
iadd [precise(y)] r0.y, r0.x, l(3)
|
||||
ubfe [precise(x)] r0.x, l(1), l(3), r0.x
|
||||
iadd [precise(x)] r0.x, r0.x, r0.y
|
||||
ubfe [precise(y)] r0.y, l(1), l(3), r0.x
|
||||
iadd [precise(x)] r0.x, r0.y, r0.x
|
||||
iadd [precise(x)] r0.x, r0.x, l(3)
|
||||
ubfe [precise(xyz)] r0.xyz, l(24, 20, 4, 0), l(3, 3, 23, 0), r0.xxxx
|
||||
firstbit_hi [precise(w)] r0.w, r0.y
|
||||
iadd [precise(w)] r0.w, r0.w, l(-11)
|
||||
@@ -76,10 +76,10 @@ ret
|
||||
|
||||
const BYTE float24_round_ps[] =
|
||||
{
|
||||
68, 88, 66, 67, 229, 54,
|
||||
46, 1, 194, 31, 164, 202,
|
||||
193, 71, 175, 129, 44, 52,
|
||||
218, 154, 1, 0, 0, 0,
|
||||
68, 88, 66, 67, 110, 79,
|
||||
84, 202, 151, 165, 237, 180,
|
||||
64, 17, 0, 132, 236, 126,
|
||||
142, 105, 1, 0, 0, 0,
|
||||
8, 7, 0, 0, 5, 0,
|
||||
0, 0, 52, 0, 0, 0,
|
||||
160, 0, 0, 0, 120, 2,
|
||||
@@ -259,22 +259,22 @@ const BYTE float24_round_ps[] =
|
||||
0, 0, 0, 0, 26, 0,
|
||||
16, 0, 0, 0, 0, 0,
|
||||
10, 0, 16, 0, 0, 0,
|
||||
0, 0, 30, 0, 16, 7,
|
||||
0, 0, 138, 0, 16, 9,
|
||||
34, 0, 16, 0, 0, 0,
|
||||
0, 0, 10, 0, 16, 0,
|
||||
0, 0, 0, 0, 1, 64,
|
||||
0, 0, 3, 0, 0, 0,
|
||||
138, 0, 8, 9, 18, 0,
|
||||
16, 0, 0, 0, 0, 0,
|
||||
1, 64, 0, 0, 1, 0,
|
||||
0, 0, 1, 64, 0, 0,
|
||||
3, 0, 0, 0, 10, 0,
|
||||
1, 0, 0, 0, 1, 64,
|
||||
0, 0, 3, 0, 0, 0,
|
||||
10, 0, 16, 0, 0, 0,
|
||||
0, 0, 30, 0, 8, 7,
|
||||
18, 0, 16, 0, 0, 0,
|
||||
0, 0, 26, 0, 16, 0,
|
||||
0, 0, 0, 0, 10, 0,
|
||||
16, 0, 0, 0, 0, 0,
|
||||
30, 0, 8, 7, 18, 0,
|
||||
16, 0, 0, 0, 0, 0,
|
||||
10, 0, 16, 0, 0, 0,
|
||||
0, 0, 26, 0, 16, 0,
|
||||
0, 0, 0, 0, 138, 0,
|
||||
0, 0, 1, 64, 0, 0,
|
||||
3, 0, 0, 0, 138, 0,
|
||||
56, 15, 114, 0, 16, 0,
|
||||
0, 0, 0, 0, 2, 64,
|
||||
0, 0, 24, 0, 0, 0,
|
||||
|
||||
@@ -12,5 +12,6 @@ precise float main(XePSInput xe_input) : SV_Depth {
|
||||
// allow for safe reinterpretation of any 24-bit value to and from float24
|
||||
// depth using depth output without unrestricted depth range.
|
||||
return asfloat(XeFloat20e4To32(
|
||||
XeFloat32To20e4(asuint(saturate(xe_input.position.z * 2.0f))), true));
|
||||
XeFloat32To20e4(asuint(saturate(xe_input.position.z * 2.0f)), true),
|
||||
true));
|
||||
}
|
||||
|
||||
@@ -587,14 +587,17 @@ xesl_uint4 XeRG16SNormToRG16Float(xesl_uint4 packed_texels) {
|
||||
// 6e4 has a different exponent bias allowing [0,512) values, 20e4 allows [0,2).
|
||||
// We also can't clamp the stored value to 1 as load->store->load must be exact.
|
||||
|
||||
uint XeFloat32To20e4(uint f32u32) {
|
||||
uint XeFloat32To20e4(uint f32u32, bool round_to_nearest_even) {
|
||||
// Keep only positive (high bit set means negative for both float and int) and
|
||||
// saturate to the maximum representable value near 2 (also dropping NaNs).
|
||||
f32u32 = min((f32u32 <= 0x7FFFFFFFu) ? f32u32 : 0u, 0x3FFFFFF8u);
|
||||
uint denormalized =
|
||||
((f32u32 & 0x7FFFFFu) | 0x800000u) >> min(113u - (f32u32 >> 23u), 24u);
|
||||
uint f24u32 = (f32u32 < 0x38800000u) ? denormalized : (f32u32 + 0xC8000000u);
|
||||
return ((f24u32 + 3u + ((f24u32 >> 3u) & 1u)) >> 3u) & 0xFFFFFFu;
|
||||
if (round_to_nearest_even) {
|
||||
f24u32 += 3u + ((f24u32 >> 3u) & 1u);
|
||||
}
|
||||
return (f24u32 >> 3u) & 0xFFFFFFu;
|
||||
}
|
||||
|
||||
uint XeFloat20e4To32(uint f24u32, bool remap_to_0_to_0_5) {
|
||||
|
||||
Reference in New Issue
Block a user