GPU: Clear fragment enable bit on draw
In a few games, depth only draws seem to have random fragment shaders attached to them. In PLA, this isn't too much of an issue as it has rasterize discard enabled, though it still binds resources for an unused fragment stage. However, in Assassin's Creed 2, an alpha testing shader is left bound during the majority of the occlusion culling pass, leading pretty much every fragment to fail and all geometry to be culled out. This PR clears the fragment stage enable bit after each draw, as the commands set by the guest should re-enable it if it's being used. This means that stale fragment shader bindings are removed during depth-only draws, which can avoid incorrect results if the fragment shader could discard. All guest GPU drivers seem to religiously set the enable bit for the fragment shader, other stages are better managed (they never stay accidentally enabled). I traced all the registers AC2 wrote when it did the incorrect draws, and this is the only conclusion I could come to. It's worth testing this in a large number of games. It's entirely possible that this flag is reset in another place, or under specific conditions. OpenGL games are a good one to make sure still work.
This commit is contained in:
parent
6dcb867816
commit
53ee267ba9
@ -319,6 +319,9 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
|
||||
_context.Renderer.Pipeline.BeginTransformFeedback(_drawState.Topology);
|
||||
_prevTfEnable = true;
|
||||
}
|
||||
|
||||
// Unset fragment enable bits for shader, as they need to be reset each draw.
|
||||
_state.State.ShaderState[(int)ShaderStage.Fragment].Control &= ~(uint)1;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -1398,7 +1401,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
|
||||
|
||||
for (int index = 0; index < 6; index++)
|
||||
{
|
||||
var shader = _state.State.ShaderState[index];
|
||||
ref var shader = ref _state.State.ShaderState[index];
|
||||
if (!shader.UnpackEnable() && index != 1)
|
||||
{
|
||||
continue;
|
||||
|
Loading…
Reference in New Issue
Block a user