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

Fix D3D Forced Anisotropy #3672

Merged
merged 2 commits into from
Mar 26, 2016
Merged

Conversation

EmptyChaos
Copy link
Contributor

The D3D backend is known to force anisotropic filtering on all textures when enabled which results in glitches that don't occur in the OpenGL backend under the same anisotropy level. I tried to trace the difference between the 2 implementations to find what was causing this and it seems to actually be an implementation-defined interaction between the anisotropy level and the texture min/mag filter setting in OpenGL. The Anisotropy specification says that the min/mag filters have an implementation-defined effect on the anisotropic filter; only the combination of GL_LINEAR+GL_LINEAR_MIPMAP_LINEAR has a clearly defined behavior as being "best effort". I guessed that nVidia's OpenGL drivers were implicitly disabling anisotropy when using GL_NEAREST as the filter so I patched D3D with that assumption to see what would happen and got this:
tospatch
(Left is master; right is with this patch applied. Both are 16x Anisotropic in D3D11. The right image matches OpenGL)

I don't know anything about Flipper so this is just a proof of concept.

Review on Reviewable

@JMC47
Copy link
Contributor

JMC47 commented Feb 25, 2016

Considering that this is a fix to an enhancement and brings it to parity with OpenGL, this should be considered for 5.0. As long as anisotropic filtering off stays the same, I don't see any issue with at least giving this a good, hard look.

@CrossVR CrossVR added this to the Dolphin Release 5.0 milestone Feb 25, 2016
@degasus
Copy link
Member

degasus commented Feb 25, 2016

Sounds fine, but please do the same for OGL, also if this change has no effect.
https://github.com/dolphin-emu/dolphin/blob/master/Source/Core/VideoBackends/OGL/SamplerCache.cpp#L137

@Mullin
Copy link
Contributor

Mullin commented Feb 25, 2016

This should fix Broken Sunrays in ZTP when using anisotropic filter.

https://wiki.dolphin-emu.org/images/7/72/TwilightPrincessGC_Sunrays_Broken.jpg

@BhaaLseN
Copy link
Member

Did we ask fifoci for its opinion yet?

@dolphin-emu-bot rebuild

@delroth
Copy link
Member

delroth commented Feb 25, 2016

FifoCI doesn't run with anisotropic filtering enabled.

@EmptyChaos
Copy link
Contributor Author

@Mullin I've taken a look at those and I don't think I can do anything about it. The way the game implements them is just not compatible with Anisotropic filtering; you'd need an Action Replay code to modify its implementation. The game sets TexMode0 to 0x00019A (ie. min_filter=4,mag_filter=1 = LINEAR+LINEAR) on the rays so it wants maximum filtering, but the angles on the geometry causes Anisotropic filtering to "correct" the image in an undesirable way giving that misrender. Maybe it's possible to do something in the shaders but I'm not an expert.

[The idea of this PR is to bring D3D to parity with OpenGL. If OpenGL w/ Anisotropic filtering was drawing correctly then this fixes it so D3D will also draw it correctly now. If OpenGL was drawing it wrong then nothing has changed either way.]

@BhaaLseN The non-anisotropic code paths are unchanged from master, FifoCI results should be identical.

@Mullin
Copy link
Contributor

Mullin commented Feb 25, 2016

@EmptyChaos Okay, so sad :(

// Only use anisotropic filtering if one or both of the filters are set to Linear.
// If both filters are set to Point then using anisotropy is equivalent
// to "forced filtering" which will cause visual glitches.
if (state.max_anisotropy > 1 && (state.min_filter & 4 || state.mag_filter))

This comment was marked as off-topic.

@EmptyChaos EmptyChaos force-pushed the d3d-anisotropy branch 4 times, most recently from 6e29742 to f22981f Compare February 26, 2016 03:14
@EmptyChaos
Copy link
Contributor Author

Review status: 0 of 7 files reviewed at latest revision, 1 unresolved discussion, some commit checks failed.


Source/Core/VideoBackends/D3D/D3DState.cpp, line 265 [r1] (raw file):
Done.


Comments from the review on Reviewable.io

@jroberts2010
Copy link

Would this fix the text in Mario Party 4-7 with AF enabled?

@EmptyChaos
Copy link
Contributor Author

@straightflushin Possibly? Does it display correctly in OpenGL w/ Anisotropy (on an nVidia GPU, I don't know about AMD/Intel)? I don't have any Mario Partys to test, but I can take a look at a FIFO Log if you want to upload one.

@jroberts2010
Copy link

Sorry, it looks like that bug only happens now with Force Texture Filtering enabled (on both backends).
Anisotropy is fine on those titles.

// Letting the game set other combinations will have varying arbitrary results;
// possibly being interpreted as equal to bilinear/trilinear, implicitly
// disabling anisotropy, or changing the anisotropic algorithm employed.
min_filter = (tm0.min_filter & 3) == TexMode0::TEXF_NONE ? GL_LINEAR : GL_LINEAR_MIPMAP_LINEAR;

This comment was marked as off-topic.

This comment was marked as off-topic.

@delroth
Copy link
Member

delroth commented Feb 28, 2016

@dolphin-emu-bot rebuild

@EmptyChaos EmptyChaos changed the title [RFC] D3D Forced Anisotropy Fix D3D Forced Anisotropy Feb 29, 2016
@EmptyChaos
Copy link
Contributor Author

I don't think I have any further changes to make. This is ready to be reviewed for merging.

@JMC47
Copy link
Contributor

JMC47 commented Mar 2, 2016

LGTM in terms of what it fixes.

@RisingFog
Copy link
Member

Can this PR be rebased to latest master?

@EmptyChaos
Copy link
Contributor Author

Rebased on master.

@RisingFog
Copy link
Member

Anything left holding this PR up?

@degasus
Copy link
Member

degasus commented Mar 23, 2016

Reviewed 1 of 4 files at r1, 2 of 6 files at r2, 4 of 8 files at r4, 4 of 4 files at r5.
Review status: all files reviewed at latest revision, 1 unresolved discussion.


Source/Core/VideoBackends/OGL/SamplerCache.cpp, line 63 [r5] (raw file):
Is this line still fine?


Comments from the review on Reviewable.io

The D3D backend was always forcing Anisotropic filtering when that is enabled regardless of how the game chose to configure the texture filtering registers; this causes the same issues as "Force Filtering" without Anisotropy, such as causing game UI elements to no longer line up adjacent correctly. Historically, OpenGL's Anisotropy support has always worked "better" than D3D's due to seeming to not have this problem; unfortunately, OpenGL's Anisotropy specification only gives GL_LINEAR based filtering modes defined behavior, with only the mipmap setting being required to be considered. Some OpenGL implementations were implicitly disabling Anisotropy when the min/mag filters were set to GL_NEAREST, but this behavior is not required by the spec so cannot be relied on.
@EmptyChaos
Copy link
Contributor Author

Review status: 2 of 11 files reviewed at latest revision, 1 unresolved discussion.


Source/Core/VideoBackends/OGL/SamplerCache.cpp, line 63 [r5] (raw file):
Probably not. min_filter should be 6 or 4, but that can produce 5 as well. I'll fix it.


Comments from the review on Reviewable.io

@delroth
Copy link
Member

delroth commented Mar 26, 2016

@EmptyChaos any progress?

@EmptyChaos
Copy link
Contributor Author

@delroth I've already made the change. I screwed up the Reviewable by not clicking Publish.

@delroth delroth merged commit 2fd0884 into dolphin-emu:master Mar 26, 2016
@Nucleoprotein
Copy link

So neobrain and/or MaJoRoesch wasn't correct about this, I reported this issue long time ago : https://bugs.dolphin-emu.org/issues/7724 Thanks EmptyChaos.

@delroth
Copy link
Member

delroth commented Mar 26, 2016

neobrain is correct, this is in some sense a hack to disable anisotropy in
some situations to avoid unwanted effects.

On Sat, Mar 26, 2016 at 11:57 PM Robert Krawczyk notifications@github.com
wrote:

So neobrain and/or MaJoRoesch wasn't correct about this, I reported this
issue long time ago : https://bugs.dolphin-emu.org/issues/7724 Thanks
EmptyChaos.


You are receiving this because you modified the open/close state.

Reply to this email directly or view it on GitHub
#3672 (comment)

@EmptyChaos
Copy link
Contributor Author

@delroth Not really. The screenshot I posted at the top actually also occurs with Anisotropic Filtering set to 1x (off) and Forced Texture Filtering set to On. The problem is specifically caused by forcing texture filtering when it is meant to be disabled, it isn't directly related to anisotropic filtering itself. You can cause similar issues in some commercial PC games by forcing Anisotropic Filtering from the Nvidia/Catalyst control panel.

Also, I think "fundamental difference between the APIs" may be overstating things a little.

A texture's maximum degree of anisotropy is specified independent
from the texture's minification and magnification filter (as
opposed to being supported as an entirely new filtering mode).
...  Implementations are also
permitted to ignore the minification or magnification filter and
implement the highest quality of anisotropic filtering possible.

"Implementations are also permitted to ignore ..." means this has always been broken in OpenGL as well.

@EmptyChaos EmptyChaos deleted the d3d-anisotropy branch March 27, 2016 02:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet