[D3D12] Dithered alpha to coverage

This commit is contained in:
Triang3l
2020-07-07 23:09:28 +03:00
parent 596f1691c0
commit 829c6ee2b0
30 changed files with 2470 additions and 2329 deletions

View File

@@ -398,7 +398,40 @@ union RB_COLORCONTROL {
uint32_t alpha_test_enable : 1; // +3
uint32_t alpha_to_mask_enable : 1; // +4
// Everything in between was added on Adreno.
uint32_t : 19; // +5
uint32_t : 19; // +5
// According to tests on an Adreno 200 device (LG Optimus L7), done by
// drawing 0.5x0.5 rectangles in different corners of four pixels in a quad
// to a multisampled GLSurfaceView, the coverage mask is the following for 4
// samples:
// 0.25) [0.25, 0.5) [0.5, 0.75) [0.75, 1) [1
// -- -- -- -- --
// | | | | | #| |##| |##|
// | | |# | |# | |# | |##|
// -- -- -- -- --
// (gl_FragCoord.y near 0 in the top, near 1 in the bottom here - D3D-like.)
// For 2 samples, the top sample (closer to gl_FragCoord.y 0) is covered
// when alpha is in [0.5, 1), the bottom sample is covered when the alpha is
// [1. With these thresholds, however, in Red Dead Redemption, almost all
// distant trees are transparent, this is asymmetric - fully transparent for
// a quarter of the range (or even half of the range for 2x and almost the
// entire range for 1x), but fully opaque only in one value.
// Though, 2, 2, 2, 2 offset values are commonly used for undithered alpha
// to coverage (in games such as Red Dead Redemption, and overall in AMD
// driver implementations) - it appears that 2, 2, 2, 2 offsets are supposed
// to make this symmetric.
// Both Red Dead Redemption and RADV (which used AMDVLK as a reference) use
// 3, 1, 0, 2 offsets for dithered alpha to mask.
// https://gitlab.freedesktop.org/nchery/mesa/commit/8a52e4cc4fad4f1c75acc0badd624778f9dfe202
// It appears that the offsets lower the thresholds by (offset / 4 /
// sample count). That's consistent with both 2, 2, 2, 2 making the test
// symmetric and 0, 0, 0, 0 (forgetting to set the offset values) resulting
// in what the official Adreno 200 driver for Android (which is pretty buggy
// overall) produces.
// According to Evergreen register reference:
// - offset0 is for pixel (0, 0) in each quad.
// - offset1 is for pixel (0, 1) in each quad.
// - offset2 is for pixel (1, 0) in each quad.
// - offset3 is for pixel (1, 1) in each quad.
uint32_t alpha_to_mask_offset0 : 2; // +24
uint32_t alpha_to_mask_offset1 : 2; // +26
uint32_t alpha_to_mask_offset2 : 2; // +28