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

Enable logic op emulation in-shader #15960

Merged
merged 4 commits into from
Sep 4, 2022
Merged

Conversation

hrydgard
Copy link
Owner

@hrydgard hrydgard commented Sep 4, 2022

There was a problem with the combination of shader bitmasking and logic ops - even if some bits were masked away through shader trickery, since we used hardware logic ops where available, they would apply to all bits, not just the masked ones. This fixes that by moving logic operations into the shader in that case.

Requires integer ops in fragment shader, so will not work on old OpenGL ES devices or DX9. Also doesn't yet work in D3D11, but I'll fix that in a followup (need to force on logic-op-in-shader in some additional cases, as there are no native logic ops in D3D11).

Fixes #11928 (water effects in Outrun)
Fixes #13012 (water effects in DiRT 2)

Neither is fully fixed though, some precision or logic issue still causes us to miss some pixels, it's close though:
Scratch that, it's actually perfect at 1x resolution (or with "lower resolution for effects", which I guess we'll need to enforce here):

ULES00262_00023

2x res with texture upscaling:

image

GE dump: outrun water.zip

@hrydgard hrydgard added the GE emulation Backend-independent GPU issues label Sep 4, 2022
@hrydgard hrydgard added this to the v1.14.0 milestone Sep 4, 2022
@Panderner
Copy link
Contributor

How about Dirt 2?

@hrydgard
Copy link
Owner Author

hrydgard commented Sep 4, 2022

DiRT 2 is also fixed with this @Panderner

GEBlendSrcFactor replaceBlendFuncA = (GEBlendSrcFactor)id.Bits(FS_BIT_BLENDFUNC_A, 4);
GEBlendDstFactor replaceBlendFuncB = (GEBlendDstFactor)id.Bits(FS_BIT_BLENDFUNC_B, 4);
GEBlendMode replaceBlendEq = (GEBlendMode)id.Bits(FS_BIT_BLENDEQ, 3);
StencilValueType replaceAlphaWithStencilType = (StencilValueType)id.Bits(FS_BIT_REPLACE_ALPHA_WITH_STENCIL_TYPE, 4);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's a shame this isn't 3 bits. I think we could use the uniform more or merge STENCIL_VALUE_INVERT + STENCIL_VALUE_ONE for the purposes of the shader id. If it had one less value it could fit in 3 bits... well anyway, not related to this change really.

-[Unknown]

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, but we still aren't running out of frag id bits, so I'm inclined to just do that when we need to :) As you say unrelated anyway.

GPU/Common/FragmentShaderGenerator.cpp Outdated Show resolved Hide resolved
GPU/Common/FragmentShaderGenerator.cpp Show resolved Hide resolved
@unknownbrackets unknownbrackets merged commit 026040b into master Sep 4, 2022
@unknownbrackets unknownbrackets deleted the more-logic-op-work branch September 4, 2022 18:25
@unknownbrackets
Copy link
Collaborator

I was curious if the blocky effects in the water are really correct here. I double checked the framedump against a PSP, which more or less matches.

#11928_ULUS10064_outrun_water2

Looking at the frame dump, it's because of a 4444 texture at 0x040d4000 (245/825.) This is rendered to between 2/825 (mainly 107/825) and 132/825 as 5551, but then 565 at 135/825 to fill alpha. It ends up with this patchy texture:

Patchy texture with dot patterns

I guess it's maybe right (what can you do with a 1 bit stencil buffer...), but do we know if that's really how the game looked on a PSP?

-[Unknown]

@hrydgard
Copy link
Owner Author

Yes, I ran it on my real PSP when debugging the effect, and it does look exactly like that.

I chose that spot because it's one of very few places, if not the only place, in the game where you can get close enough to the water to see the square texels, mostly you just drive some distance from it, past it at high speed and it looks like a really advanced reflection effect that shouldn't normally be possible on the PSP. Don't think anything is wrong here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
GE emulation Backend-independent GPU issues
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Graphical Glitches in Colin McRae Dirt 2 (missing water) OutRun 2006 - Coast 2 Coast (USA) missing water
3 participants