Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

D3D9 Depth bias Mega-issue #2892

Closed
K0bin opened this issue Sep 3, 2022 · 12 comments
Closed

D3D9 Depth bias Mega-issue #2892

K0bin opened this issue Sep 3, 2022 · 12 comments
Labels

Comments

@K0bin
Copy link
Collaborator

K0bin commented Sep 3, 2022

Depth bias in Vulkan:

m * depthBiasSlopeFactor + r * depthBiasConstantFactor

where r is:

The minimum resolvable difference r is a parameter that depends on the depth attachment representation. It is the smallest difference in framebuffer coordinate z values that is guaranteed toremain distinct throughout polygon rasterization and in the depth attachment. All pairs of fragments generated by the rasterization of two polygons with otherwise identical vertices, but zf
values that differ by r, will have distinct depth values.

Depth bias in D3D9:

m * depthBiasSlopeFactor + depthBiasConstantFactor

r-Value

The constant part of the final depth bias value is scaled by the smallest resolvable difference in Vulkan and unscaled in D3D9. There is no way to make the driver switch to an unscaled depth bias mode or query the factor.

Right now DXVK uses a hardcoded r-value for each depth image format. Microsofts d3d9on12 curiously uses the exact same values. While that seems to work for 9on12, testing shows that it doesn't for DXVK, leading to various issues listed below.

Wine does a few off screen draws when initializing the graphics device to determine the depth bias factor for each depth format.

Nine just falls back to an r-value of 1 << 23 when the underlying driver doesn't support the unscaled depth bias.

On my RTX 3090, the r-value for 16 bit formats is 1 << 15 and 1 << 23 for everything else according to Wine.

Floating point formats

For floating-point depth attachment, there is no single minimum resolvable difference. In this case, the minimum resolvable difference for a given polygon is dependent on the maximum exponent, e, in the range of z values spanned by the primitive. If n is the number of bits in the floating-point mantissa, the minimum resolvable difference, r, for the given primitive is
defined as r = 2^(e-n)

This adds the additional problem that we emulate D24 formats with D32 on AMD hardware. So the scaling behavior is different.
This also prevents us from simply doing a few quick draws to determine the scaling factor and then apply that.

@K0bin
Copy link
Collaborator Author

K0bin commented Sep 3, 2022

#1461

@K0bin
Copy link
Collaborator Author

K0bin commented Sep 3, 2022

#2642

@K0bin
Copy link
Collaborator Author

K0bin commented Sep 3, 2022

#1811

@K0bin
Copy link
Collaborator Author

K0bin commented Sep 3, 2022

#1329

@K0bin
Copy link
Collaborator Author

K0bin commented Sep 3, 2022

#1560

@K0bin K0bin added the d3d9 label Sep 3, 2022
@K0bin K0bin pinned this issue Sep 3, 2022
@K0bin
Copy link
Collaborator Author

K0bin commented Sep 3, 2022

According to Wine, Mass Effect 2 relies on it as well.

I haven't personally noticed that yet, maybe the current solution is good enough for that particular game.

@pchome
Copy link
Contributor

pchome commented Sep 3, 2022

On my RTX 3090, the r-value for 16 bit formats is 1 << 15 and 1 << 23 for everything else according to Wine.

So, guessing everything "-1" for NV it could be just separate detector

  inline float GetNVDepthBufferRValue(VkFormat Format) {
    switch (Format) {
      case VK_FORMAT_D16_UNORM_S8_UINT:
      case VK_FORMAT_D16_UNORM:
        return float(1 << 15);

      case VK_FORMAT_D32_SFLOAT_S8_UINT:
      case VK_FORMAT_D32_SFLOAT:
        return float(1 << 22);

      default:
      case VK_FORMAT_D24_UNORM_S8_UINT:
        return float(1 << 23);
    }
  }

@doitsujin
Copy link
Owner

That's not what was being said.

Also ideally we'd have a more generic, forward-looking fix rather than just hard-coding some random values that might break with any new hardware generation.

@K0bin
Copy link
Collaborator Author

K0bin commented Jun 20, 2023

Fixed by #3501

@K0bin K0bin closed this as completed Jun 20, 2023
@K0bin K0bin unpinned this issue Jun 20, 2023
@adolfintel
Copy link
Contributor

I don't know if this is related but Star Trek Resurgence (UE4, DX11) has a problem that looks a lot like this issue, some areas are worse than others. I can provide some captures if you want.

Here's a screenshot, notice the striped pattern on the uniform and face
Untitled

I looked at a playthrough on youtube and didn't see these artifacts, I also tried different dxvk settings without success so I thought I'd ask here.

@K0bin
Copy link
Collaborator Author

K0bin commented Jul 25, 2023

Depth bias issues are exceedingly rare in D3D11 games because depth bias in Vulkan works very similarly to D3D11 anyway, even without the extension. So I wouldn't expect that to be the issue.

@adolfintel
Copy link
Contributor

Alright, I'll do some captures and open a proper issue tomorrow so it can be investigated. Thanks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants