Compare commits

...

4 Commits

Author SHA1 Message Date
riperiperi
089b7d41a7
Merge 53ee267ba9 into 7d158acc3b 2024-09-30 23:02:06 +03:00
gdkchan
7d158acc3b
Do not try to create a texture pool if shader does not use textures (#7379) 2024-09-30 11:41:07 -03:00
riperiperi
53ee267ba9 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.
2024-02-03 14:01:00 +00:00
Gabriel A
6dcb867816 Limit remote closed session removal to SM service 2024-02-03 01:17:12 -03:00
2 changed files with 5 additions and 2 deletions

View File

@ -322,6 +322,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>
@ -1420,7 +1423,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;

View File

@ -743,7 +743,7 @@ namespace Ryujinx.Graphics.Gpu.Shader
constantBufferUsePerStageMask &= ~(1 << index);
}
if (checkTextures)
if (checkTextures && _allTextures.Length > 0)
{
TexturePool pool = channel.TextureManager.GetTexturePool(poolState.TexturePoolGpuVa, poolState.TexturePoolMaximumId);