Implement Viewport Transform Disable (#3328)
* Initial implementation (no specialization) * Use specialization * Fix render scale, increase code gen version * Revert accidental change * Address Feedback
This commit is contained in:
parent
92ca1cb0cb
commit
43b4b34376
24 changed files with 200 additions and 26 deletions
|
@ -113,7 +113,8 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
|
|||
nameof(ThreedClassState.DepthMode),
|
||||
nameof(ThreedClassState.ViewportTransform),
|
||||
nameof(ThreedClassState.ViewportExtents),
|
||||
nameof(ThreedClassState.YControl)),
|
||||
nameof(ThreedClassState.YControl),
|
||||
nameof(ThreedClassState.ViewportTransformEnable)),
|
||||
|
||||
new StateUpdateCallbackEntry(UpdatePolygonMode,
|
||||
nameof(ThreedClassState.PolygonModeFront),
|
||||
|
@ -200,7 +201,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
|
|||
// of the shader for the new state.
|
||||
if (_shaderSpecState != null)
|
||||
{
|
||||
if (!_shaderSpecState.MatchesGraphics(_channel, GetPoolState()))
|
||||
if (!_shaderSpecState.MatchesGraphics(_channel, GetPoolState(), GetGraphicsState()))
|
||||
{
|
||||
ForceShaderUpdate();
|
||||
}
|
||||
|
@ -568,6 +569,8 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
|
|||
var yControl = _state.State.YControl;
|
||||
var face = _state.State.FaceState;
|
||||
|
||||
bool disableTransform = _state.State.ViewportTransformEnable == 0;
|
||||
|
||||
UpdateFrontFace(yControl, face.FrontFace);
|
||||
UpdateDepthMode();
|
||||
|
||||
|
@ -577,6 +580,17 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
|
|||
|
||||
for (int index = 0; index < Constants.TotalViewports; index++)
|
||||
{
|
||||
if (disableTransform)
|
||||
{
|
||||
ref var scissor = ref _state.State.ScreenScissorState;
|
||||
|
||||
float rScale = _channel.TextureManager.RenderTargetScale;
|
||||
var scissorRect = new RectangleF(0, 0, (scissor.X + scissor.Width) * rScale, (scissor.Y + scissor.Height) * rScale);
|
||||
|
||||
viewports[index] = new Viewport(scissorRect, ViewportSwizzle.PositiveX, ViewportSwizzle.PositiveY, ViewportSwizzle.PositiveZ, ViewportSwizzle.PositiveW, 0, 1);
|
||||
continue;
|
||||
}
|
||||
|
||||
ref var transform = ref _state.State.ViewportTransform[index];
|
||||
ref var extents = ref _state.State.ViewportExtents[index];
|
||||
|
||||
|
@ -628,7 +642,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
|
|||
viewports[index] = new Viewport(region, swizzleX, swizzleY, swizzleZ, swizzleW, depthNear, depthFar);
|
||||
}
|
||||
|
||||
_context.Renderer.Pipeline.SetViewports(0, viewports);
|
||||
_context.Renderer.Pipeline.SetViewports(0, viewports, disableTransform);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -1194,7 +1208,8 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
|
|||
return new GpuChannelGraphicsState(
|
||||
_state.State.EarlyZForce,
|
||||
_drawState.Topology,
|
||||
_state.State.TessMode);
|
||||
_state.State.TessMode,
|
||||
_state.State.ViewportTransformEnable == 0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -166,7 +166,8 @@ namespace Ryujinx.Graphics.Gpu.Shader.Cache
|
|||
GpuChannelGraphicsState graphicsState = new GpuChannelGraphicsState(
|
||||
accessorHeader.StateFlags.HasFlag(GuestGpuStateFlags.EarlyZForce),
|
||||
topology,
|
||||
tessMode);
|
||||
tessMode,
|
||||
false);
|
||||
|
||||
TransformFeedbackDescriptor[] tfdNew = null;
|
||||
|
||||
|
|
|
@ -185,6 +185,12 @@ namespace Ryujinx.Graphics.Gpu.Shader.DiskCache
|
|||
return _oldSpecState.GraphicsState.EarlyZForce;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public bool QueryViewportTransformDisable()
|
||||
{
|
||||
return _oldSpecState.GraphicsState.ViewportTransformDisable;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void RegisterTexture(int handle, int cbufSlot)
|
||||
{
|
||||
|
|
|
@ -21,7 +21,7 @@ namespace Ryujinx.Graphics.Gpu.Shader.DiskCache
|
|||
private const ushort FileFormatVersionMajor = 1;
|
||||
private const ushort FileFormatVersionMinor = 1;
|
||||
private const uint FileFormatVersionPacked = ((uint)FileFormatVersionMajor << 16) | FileFormatVersionMinor;
|
||||
private const uint CodeGenVersion = 0;
|
||||
private const uint CodeGenVersion = 1;
|
||||
|
||||
private const string SharedTocFileName = "shared.toc";
|
||||
private const string SharedDataFileName = "shared.data";
|
||||
|
|
|
@ -217,6 +217,12 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
|||
return _state.GraphicsState.EarlyZForce;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public bool QueryViewportTransformDisable()
|
||||
{
|
||||
return _state.GraphicsState.ViewportTransformDisable;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void RegisterTexture(int handle, int cbufSlot)
|
||||
{
|
||||
|
|
|
@ -25,17 +25,24 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
|||
/// </summary>
|
||||
public readonly TessMode TessellationMode;
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whenever the viewport transform is disabled.
|
||||
/// </summary>
|
||||
public readonly bool ViewportTransformDisable;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new GPU graphics state.
|
||||
/// </summary>
|
||||
/// <param name="earlyZForce">Early Z force enable</param>
|
||||
/// <param name="topology">Primitive topology</param>
|
||||
/// <param name="tessellationMode">Tessellation mode</param>
|
||||
public GpuChannelGraphicsState(bool earlyZForce, PrimitiveTopology topology, TessMode tessellationMode)
|
||||
/// <param name="viewportTransformDisable">Indicates whenever the viewport transform is disabled</param>
|
||||
public GpuChannelGraphicsState(bool earlyZForce, PrimitiveTopology topology, TessMode tessellationMode, bool viewportTransformDisable)
|
||||
{
|
||||
EarlyZForce = earlyZForce;
|
||||
Topology = topology;
|
||||
TessellationMode = tessellationMode;
|
||||
ViewportTransformDisable = viewportTransformDisable;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -249,12 +249,12 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
|||
GpuChannelGraphicsState graphicsState,
|
||||
ShaderAddresses addresses)
|
||||
{
|
||||
if (_gpPrograms.TryGetValue(addresses, out var gpShaders) && IsShaderEqual(channel, poolState, gpShaders, addresses))
|
||||
if (_gpPrograms.TryGetValue(addresses, out var gpShaders) && IsShaderEqual(channel, poolState, graphicsState, gpShaders, addresses))
|
||||
{
|
||||
return gpShaders;
|
||||
}
|
||||
|
||||
if (_graphicsShaderCache.TryFind(channel, poolState, addresses, out gpShaders, out var cachedGuestCode))
|
||||
if (_graphicsShaderCache.TryFind(channel, poolState, graphicsState, addresses, out gpShaders, out var cachedGuestCode))
|
||||
{
|
||||
_gpPrograms[addresses] = gpShaders;
|
||||
return gpShaders;
|
||||
|
@ -429,12 +429,14 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
|||
/// </summary>
|
||||
/// <param name="channel">GPU channel using the shader</param>
|
||||
/// <param name="poolState">GPU channel state to verify shader compatibility</param>
|
||||
/// <param name="graphicsState">GPU channel graphics state to verify shader compatibility</param>
|
||||
/// <param name="gpShaders">Cached graphics shaders</param>
|
||||
/// <param name="addresses">GPU virtual addresses of all enabled shader stages</param>
|
||||
/// <returns>True if the code is different, false otherwise</returns>
|
||||
private static bool IsShaderEqual(
|
||||
GpuChannel channel,
|
||||
GpuChannelPoolState poolState,
|
||||
GpuChannelGraphicsState graphicsState,
|
||||
CachedShaderProgram gpShaders,
|
||||
ShaderAddresses addresses)
|
||||
{
|
||||
|
@ -452,7 +454,7 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
|||
}
|
||||
}
|
||||
|
||||
return gpShaders.SpecializationState.MatchesGraphics(channel, poolState);
|
||||
return gpShaders.SpecializationState.MatchesGraphics(channel, poolState, graphicsState);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -208,6 +208,7 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
|||
/// </remarks>
|
||||
/// <param name="channel">GPU channel</param>
|
||||
/// <param name="poolState">Texture pool state</param>
|
||||
/// <param name="graphicsState">Graphics state</param>
|
||||
/// <param name="addresses">Guest addresses of the shaders to find</param>
|
||||
/// <param name="program">Cached host program for the given state, if found</param>
|
||||
/// <param name="guestCode">Cached guest code, if any found</param>
|
||||
|
@ -215,6 +216,7 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
|||
public bool TryFind(
|
||||
GpuChannel channel,
|
||||
GpuChannelPoolState poolState,
|
||||
GpuChannelGraphicsState graphicsState,
|
||||
ShaderAddresses addresses,
|
||||
out CachedShaderProgram program,
|
||||
out CachedGraphicsGuestCode guestCode)
|
||||
|
@ -234,7 +236,7 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
|||
|
||||
if (found && _shaderPrograms.TryGetValue(idTable, out ShaderSpecializationList specList))
|
||||
{
|
||||
return specList.TryFindForGraphics(channel, poolState, out program);
|
||||
return specList.TryFindForGraphics(channel, poolState, graphicsState, out program);
|
||||
}
|
||||
|
||||
return false;
|
||||
|
|
|
@ -24,13 +24,18 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
|||
/// </summary>
|
||||
/// <param name="channel">GPU channel</param>
|
||||
/// <param name="poolState">Texture pool state</param>
|
||||
/// <param name="graphicsState">Graphics state</param>
|
||||
/// <param name="program">Cached program, if found</param>
|
||||
/// <returns>True if a compatible program is found, false otherwise</returns>
|
||||
public bool TryFindForGraphics(GpuChannel channel, GpuChannelPoolState poolState, out CachedShaderProgram program)
|
||||
public bool TryFindForGraphics(
|
||||
GpuChannel channel,
|
||||
GpuChannelPoolState poolState,
|
||||
GpuChannelGraphicsState graphicsState,
|
||||
out CachedShaderProgram program)
|
||||
{
|
||||
foreach (var entry in _entries)
|
||||
{
|
||||
if (entry.SpecializationState.MatchesGraphics(channel, poolState))
|
||||
if (entry.SpecializationState.MatchesGraphics(channel, poolState, graphicsState))
|
||||
{
|
||||
program = entry;
|
||||
return true;
|
||||
|
|
|
@ -395,9 +395,15 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
|||
/// </summary>
|
||||
/// <param name="channel">GPU channel</param>
|
||||
/// <param name="poolState">Texture pool state</param>
|
||||
/// <param name="graphicsState">Graphics state</param>
|
||||
/// <returns>True if the state matches, false otherwise</returns>
|
||||
public bool MatchesGraphics(GpuChannel channel, GpuChannelPoolState poolState)
|
||||
public bool MatchesGraphics(GpuChannel channel, GpuChannelPoolState poolState, GpuChannelGraphicsState graphicsState)
|
||||
{
|
||||
if (graphicsState.ViewportTransformDisable != GraphicsState.ViewportTransformDisable)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return Matches(channel, poolState, isCompute: false);
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue