mirror of
https://git.743378673.xyz/MeloNX/MeloNX.git
synced 2025-08-02 22:47:09 +02:00
GPU: Eliminate CB0 accesses when storage buffer accesses are resolved (#3847)
* Eliminate CB0 accesses Still some work to do, decouple from hle? * Forgot the important part somehow * Fix and improve alignment test * Address Feedback * Remove some complexity when checking storage buffer alignment * Update Ryujinx.Graphics.Shader/Translation/Optimizations/GlobalToStorage.cs Co-authored-by: gdkchan <gab.dark.100@gmail.com> Co-authored-by: gdkchan <gab.dark.100@gmail.com>
This commit is contained in:
parent
391e08dd27
commit
33a4d7d1ba
16 changed files with 317 additions and 68 deletions
|
@ -36,6 +36,7 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
|||
/// </summary>
|
||||
/// <param name="channel">GPU channel</param>
|
||||
/// <param name="poolState">Texture pool state</param>
|
||||
/// <param name="computeState">Compute state</param>
|
||||
/// <param name="gpuVa">GPU virtual address of the compute shader</param>
|
||||
/// <param name="program">Cached host program for the given state, if found</param>
|
||||
/// <param name="cachedGuestCode">Cached guest code, if any found</param>
|
||||
|
@ -43,6 +44,7 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
|||
public bool TryFind(
|
||||
GpuChannel channel,
|
||||
GpuChannelPoolState poolState,
|
||||
GpuChannelComputeState computeState,
|
||||
ulong gpuVa,
|
||||
out CachedShaderProgram program,
|
||||
out byte[] cachedGuestCode)
|
||||
|
@ -50,7 +52,7 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
|||
program = null;
|
||||
ShaderCodeAccessor codeAccessor = new ShaderCodeAccessor(channel.MemoryManager, gpuVa);
|
||||
bool hasSpecList = _cache.TryFindItem(codeAccessor, out var specList, out cachedGuestCode);
|
||||
return hasSpecList && specList.TryFindForCompute(channel, poolState, out program);
|
||||
return hasSpecList && specList.TryFindForCompute(channel, poolState, computeState, out program);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -225,6 +225,12 @@ namespace Ryujinx.Graphics.Gpu.Shader.DiskCache
|
|||
return _oldSpecState.GraphicsState.EarlyZForce;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public bool QueryHasUnalignedStorageBuffer()
|
||||
{
|
||||
return _oldSpecState.GraphicsState.HasUnalignedStorageBuffer || _oldSpecState.ComputeState.HasUnalignedStorageBuffer;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public bool QueryViewportTransformDisable()
|
||||
{
|
||||
|
|
|
@ -22,7 +22,7 @@ namespace Ryujinx.Graphics.Gpu.Shader.DiskCache
|
|||
private const ushort FileFormatVersionMajor = 1;
|
||||
private const ushort FileFormatVersionMinor = 2;
|
||||
private const uint FileFormatVersionPacked = ((uint)FileFormatVersionMajor << 16) | FileFormatVersionMinor;
|
||||
private const uint CodeGenVersion = 3747;
|
||||
private const uint CodeGenVersion = 3848;
|
||||
|
||||
private const string SharedTocFileName = "shared.toc";
|
||||
private const string SharedDataFileName = "shared.data";
|
||||
|
|
|
@ -145,6 +145,12 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
|||
return _state.GraphicsState.HasConstantBufferDrawParameters;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public bool QueryHasUnalignedStorageBuffer()
|
||||
{
|
||||
return _state.GraphicsState.HasUnalignedStorageBuffer || _state.ComputeState.HasUnalignedStorageBuffer;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public InputTopology QueryPrimitiveTopology()
|
||||
{
|
||||
|
|
|
@ -32,6 +32,11 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
|||
/// </summary>
|
||||
public readonly int SharedMemorySize;
|
||||
|
||||
/// <summary>
|
||||
/// Indicates that any storage buffer use is unaligned.
|
||||
/// </summary>
|
||||
public readonly bool HasUnalignedStorageBuffer;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new GPU compute state.
|
||||
/// </summary>
|
||||
|
@ -40,18 +45,21 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
|||
/// <param name="localSizeZ">Local group size Z of the compute shader</param>
|
||||
/// <param name="localMemorySize">Local memory size of the compute shader</param>
|
||||
/// <param name="sharedMemorySize">Shared memory size of the compute shader</param>
|
||||
/// <param name="hasUnalignedStorageBuffer">Indicates that any storage buffer use is unaligned</param>
|
||||
public GpuChannelComputeState(
|
||||
int localSizeX,
|
||||
int localSizeY,
|
||||
int localSizeZ,
|
||||
int localMemorySize,
|
||||
int sharedMemorySize)
|
||||
int sharedMemorySize,
|
||||
bool hasUnalignedStorageBuffer)
|
||||
{
|
||||
LocalSizeX = localSizeX;
|
||||
LocalSizeY = localSizeY;
|
||||
LocalSizeZ = localSizeZ;
|
||||
LocalMemorySize = localMemorySize;
|
||||
SharedMemorySize = sharedMemorySize;
|
||||
HasUnalignedStorageBuffer = hasUnalignedStorageBuffer;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -82,6 +82,11 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
|||
/// </summary>
|
||||
public readonly bool HasConstantBufferDrawParameters;
|
||||
|
||||
/// <summary>
|
||||
/// Indicates that any storage buffer use is unaligned.
|
||||
/// </summary>
|
||||
public readonly bool HasUnalignedStorageBuffer;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new GPU graphics state.
|
||||
/// </summary>
|
||||
|
@ -99,6 +104,7 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
|||
/// <param name="alphaTestReference">When alpha test is enabled, indicates the value to compare with the fragment output alpha</param>
|
||||
/// <param name="attributeTypes">Type of the vertex attributes consumed by the shader</param>
|
||||
/// <param name="hasConstantBufferDrawParameters">Indicates that the draw is writing the base vertex, base instance and draw index to Constant Buffer 0</param>
|
||||
/// <param name="hasUnalignedStorageBuffer">Indicates that any storage buffer use is unaligned</param>
|
||||
public GpuChannelGraphicsState(
|
||||
bool earlyZForce,
|
||||
PrimitiveTopology topology,
|
||||
|
@ -113,7 +119,8 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
|||
CompareOp alphaTestCompare,
|
||||
float alphaTestReference,
|
||||
ref Array32<AttributeType> attributeTypes,
|
||||
bool hasConstantBufferDrawParameters)
|
||||
bool hasConstantBufferDrawParameters,
|
||||
bool hasUnalignedStorageBuffer)
|
||||
{
|
||||
EarlyZForce = earlyZForce;
|
||||
Topology = topology;
|
||||
|
@ -129,6 +136,7 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
|||
AlphaTestReference = alphaTestReference;
|
||||
AttributeTypes = attributeTypes;
|
||||
HasConstantBufferDrawParameters = hasConstantBufferDrawParameters;
|
||||
HasUnalignedStorageBuffer = hasUnalignedStorageBuffer;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -203,12 +203,12 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
|||
GpuChannelComputeState computeState,
|
||||
ulong gpuVa)
|
||||
{
|
||||
if (_cpPrograms.TryGetValue(gpuVa, out var cpShader) && IsShaderEqual(channel, poolState, cpShader, gpuVa))
|
||||
if (_cpPrograms.TryGetValue(gpuVa, out var cpShader) && IsShaderEqual(channel, poolState, computeState, cpShader, gpuVa))
|
||||
{
|
||||
return cpShader;
|
||||
}
|
||||
|
||||
if (_computeShaderCache.TryFind(channel, poolState, gpuVa, out cpShader, out byte[] cachedGuestCode))
|
||||
if (_computeShaderCache.TryFind(channel, poolState, computeState, gpuVa, out cpShader, out byte[] cachedGuestCode))
|
||||
{
|
||||
_cpPrograms[gpuVa] = cpShader;
|
||||
return cpShader;
|
||||
|
@ -473,18 +473,20 @@ 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="computeState">GPU channel compute state to verify shader compatibility</param>
|
||||
/// <param name="cpShader">Cached compute shader</param>
|
||||
/// <param name="gpuVa">GPU virtual address of the shader code in memory</param>
|
||||
/// <returns>True if the code is different, false otherwise</returns>
|
||||
private static bool IsShaderEqual(
|
||||
GpuChannel channel,
|
||||
GpuChannelPoolState poolState,
|
||||
GpuChannelComputeState computeState,
|
||||
CachedShaderProgram cpShader,
|
||||
ulong gpuVa)
|
||||
{
|
||||
if (IsShaderEqual(channel.MemoryManager, cpShader.Shaders[0], gpuVa))
|
||||
{
|
||||
return cpShader.SpecializationState.MatchesCompute(channel, poolState, true);
|
||||
return cpShader.SpecializationState.MatchesCompute(channel, poolState, computeState, true);
|
||||
}
|
||||
|
||||
return false;
|
||||
|
|
|
@ -53,13 +53,14 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
|||
/// </summary>
|
||||
/// <param name="channel">GPU channel</param>
|
||||
/// <param name="poolState">Texture pool state</param>
|
||||
/// <param name="computeState">Compute state</param>
|
||||
/// <param name="program">Cached program, if found</param>
|
||||
/// <returns>True if a compatible program is found, false otherwise</returns>
|
||||
public bool TryFindForCompute(GpuChannel channel, GpuChannelPoolState poolState, out CachedShaderProgram program)
|
||||
public bool TryFindForCompute(GpuChannel channel, GpuChannelPoolState poolState, GpuChannelComputeState computeState, out CachedShaderProgram program)
|
||||
{
|
||||
foreach (var entry in _entries)
|
||||
{
|
||||
if (entry.SpecializationState.MatchesCompute(channel, poolState, true))
|
||||
if (entry.SpecializationState.MatchesCompute(channel, poolState, computeState, true))
|
||||
{
|
||||
program = entry;
|
||||
return true;
|
||||
|
|
|
@ -531,6 +531,11 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
|||
return false;
|
||||
}
|
||||
|
||||
if (graphicsState.HasUnalignedStorageBuffer != GraphicsState.HasUnalignedStorageBuffer)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return Matches(channel, poolState, checkTextures, isCompute: false);
|
||||
}
|
||||
|
||||
|
@ -539,10 +544,16 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
|||
/// </summary>
|
||||
/// <param name="channel">GPU channel</param>
|
||||
/// <param name="poolState">Texture pool state</param>
|
||||
/// <param name="computeState">Compute state</param>
|
||||
/// <param name="checkTextures">Indicates whether texture descriptors should be checked</param>
|
||||
/// <returns>True if the state matches, false otherwise</returns>
|
||||
public bool MatchesCompute(GpuChannel channel, GpuChannelPoolState poolState, bool checkTextures)
|
||||
public bool MatchesCompute(GpuChannel channel, GpuChannelPoolState poolState, GpuChannelComputeState computeState, bool checkTextures)
|
||||
{
|
||||
if (computeState.HasUnalignedStorageBuffer != ComputeState.HasUnalignedStorageBuffer)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return Matches(channel, poolState, checkTextures, isCompute: true);
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue