Separate GPU engines and make state follow official docs (part 1/2) (#2422)
* Use DeviceState for compute and i2m * Migrate 2D class, more comments * Migrate DMA copy engine * Remove now unused code * Replace GpuState by GpuAccessorState on GpuAcessor, since compute no longer has a GpuState * More comments * Add logging (disabled) * Add back i2m on 3D engine
This commit is contained in:
parent
31cbd09a75
commit
8b44eb1c98
30 changed files with 2599 additions and 460 deletions
|
@ -1,6 +1,5 @@
|
|||
using Ryujinx.Common.Logging;
|
||||
using Ryujinx.Graphics.GAL;
|
||||
using Ryujinx.Graphics.Gpu.State;
|
||||
using Ryujinx.Graphics.Shader;
|
||||
|
||||
namespace Ryujinx.Graphics.Gpu.Shader
|
||||
|
@ -11,7 +10,8 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
|||
class GpuAccessor : TextureDescriptorCapableGpuAccessor, IGpuAccessor
|
||||
{
|
||||
private readonly GpuContext _context;
|
||||
private readonly GpuState _state;
|
||||
private readonly GpuChannel _channel;
|
||||
private readonly GpuAccessorState _state;
|
||||
private readonly int _stageIndex;
|
||||
private readonly bool _compute;
|
||||
private readonly int _localSizeX;
|
||||
|
@ -24,11 +24,13 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
|||
/// Creates a new instance of the GPU state accessor for graphics shader translation.
|
||||
/// </summary>
|
||||
/// <param name="context">GPU context</param>
|
||||
/// <param name="channel">GPU channel</param>
|
||||
/// <param name="state">Current GPU state</param>
|
||||
/// <param name="stageIndex">Graphics shader stage index (0 = Vertex, 4 = Fragment)</param>
|
||||
public GpuAccessor(GpuContext context, GpuState state, int stageIndex)
|
||||
public GpuAccessor(GpuContext context, GpuChannel channel, GpuAccessorState state, int stageIndex)
|
||||
{
|
||||
_context = context;
|
||||
_channel = channel;
|
||||
_state = state;
|
||||
_stageIndex = stageIndex;
|
||||
}
|
||||
|
@ -37,6 +39,7 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
|||
/// Creates a new instance of the GPU state accessor for compute shader translation.
|
||||
/// </summary>
|
||||
/// <param name="context">GPU context</param>
|
||||
/// <param name="channel">GPU channel</param>
|
||||
/// <param name="state">Current GPU state</param>
|
||||
/// <param name="localSizeX">Local group size X of the compute shader</param>
|
||||
/// <param name="localSizeY">Local group size Y of the compute shader</param>
|
||||
|
@ -45,7 +48,8 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
|||
/// <param name="sharedMemorySize">Shared memory size of the compute shader</param>
|
||||
public GpuAccessor(
|
||||
GpuContext context,
|
||||
GpuState state,
|
||||
GpuChannel channel,
|
||||
GpuAccessorState state,
|
||||
int localSizeX,
|
||||
int localSizeY,
|
||||
int localSizeZ,
|
||||
|
@ -53,6 +57,7 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
|||
int sharedMemorySize)
|
||||
{
|
||||
_context = context;
|
||||
_channel = channel;
|
||||
_state = state;
|
||||
_compute = true;
|
||||
_localSizeX = localSizeX;
|
||||
|
@ -79,7 +84,7 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
|||
/// <returns>Data at the memory location</returns>
|
||||
public override T MemoryRead<T>(ulong address)
|
||||
{
|
||||
return _state.Channel.MemoryManager.Read<T>(address);
|
||||
return _channel.MemoryManager.Read<T>(address);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -89,7 +94,7 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
|||
/// <returns>True if the address is mapped, false otherwise</returns>
|
||||
public bool MemoryMapped(ulong address)
|
||||
{
|
||||
return _state.Channel.MemoryManager.IsMapped(address);
|
||||
return _channel.MemoryManager.IsMapped(address);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -129,8 +134,8 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
|||
public uint QueryConstantBufferUse()
|
||||
{
|
||||
return _compute
|
||||
? _state.Channel.BufferManager.GetComputeUniformBufferUseMask()
|
||||
: _state.Channel.BufferManager.GetGraphicsUniformBufferUseMask(_stageIndex);
|
||||
? _channel.BufferManager.GetComputeUniformBufferUseMask()
|
||||
: _channel.BufferManager.GetGraphicsUniformBufferUseMask(_stageIndex);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -196,11 +201,22 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
|||
{
|
||||
if (_compute)
|
||||
{
|
||||
return _state.Channel.TextureManager.GetComputeTextureDescriptor(_state, handle, cbufSlot);
|
||||
return _channel.TextureManager.GetComputeTextureDescriptor(
|
||||
_state.TexturePoolGpuVa,
|
||||
_state.TextureBufferIndex,
|
||||
_state.TexturePoolMaximumId,
|
||||
handle,
|
||||
cbufSlot);
|
||||
}
|
||||
else
|
||||
{
|
||||
return _state.Channel.TextureManager.GetGraphicsTextureDescriptor(_state, _stageIndex, handle, cbufSlot);
|
||||
return _channel.TextureManager.GetGraphicsTextureDescriptor(
|
||||
_state.TexturePoolGpuVa,
|
||||
_state.TextureBufferIndex,
|
||||
_state.TexturePoolMaximumId,
|
||||
_stageIndex,
|
||||
handle,
|
||||
cbufSlot);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -210,7 +226,7 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
|||
/// <returns>True if early depth testing is forced</returns>
|
||||
public bool QueryEarlyZForce()
|
||||
{
|
||||
return _state.Get<bool>(MethodOffset.EarlyZForce);
|
||||
return _state.EarlyZForce;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
43
Ryujinx.Graphics.Gpu/Shader/GpuAccessorState.cs
Normal file
43
Ryujinx.Graphics.Gpu/Shader/GpuAccessorState.cs
Normal file
|
@ -0,0 +1,43 @@
|
|||
namespace Ryujinx.Graphics.Gpu.Shader
|
||||
{
|
||||
/// <summary>
|
||||
/// State used by the <see cref="GpuAccessor"/>.
|
||||
/// </summary>
|
||||
struct GpuAccessorState
|
||||
{
|
||||
/// <summary>
|
||||
/// GPU virtual address of the texture pool.
|
||||
/// </summary>
|
||||
public ulong TexturePoolGpuVa { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Maximum ID of the texture pool.
|
||||
/// </summary>
|
||||
public int TexturePoolMaximumId { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Constant buffer slot where the texture handles are located.
|
||||
/// </summary>
|
||||
public int TextureBufferIndex { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Early Z force enable.
|
||||
/// </summary>
|
||||
public bool EarlyZForce { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of the GPU accessor state.
|
||||
/// </summary>
|
||||
/// <param name="texturePoolGpuVa">GPU virtual address of the texture pool</param>
|
||||
/// <param name="texturePoolMaximumId">Maximum ID of the texture pool</param>
|
||||
/// <param name="textureBufferIndex">Constant buffer slot where the texture handles are located</param>
|
||||
/// <param name="earlyZForce">Early Z force enable</param>
|
||||
public GpuAccessorState(ulong texturePoolGpuVa, int texturePoolMaximumId, int textureBufferIndex, bool earlyZForce)
|
||||
{
|
||||
TexturePoolGpuVa = texturePoolGpuVa;
|
||||
TexturePoolMaximumId = texturePoolMaximumId;
|
||||
TextureBufferIndex = textureBufferIndex;
|
||||
EarlyZForce = earlyZForce;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -475,7 +475,8 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
|||
/// <remarks>
|
||||
/// This automatically translates, compiles and adds the code to the cache if not present.
|
||||
/// </remarks>
|
||||
/// <param name="state">Current GPU state</param>
|
||||
/// <param name="channel">GPU channel</param>
|
||||
/// <param name="gas">GPU accessor state</param>
|
||||
/// <param name="gpuVa">GPU virtual address of the binary shader code</param>
|
||||
/// <param name="localSizeX">Local group size X of the computer shader</param>
|
||||
/// <param name="localSizeY">Local group size Y of the computer shader</param>
|
||||
|
@ -484,7 +485,8 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
|||
/// <param name="sharedMemorySize">Shared memory size of the compute shader</param>
|
||||
/// <returns>Compiled compute shader code</returns>
|
||||
public ShaderBundle GetComputeShader(
|
||||
GpuState state,
|
||||
GpuChannel channel,
|
||||
GpuAccessorState gas,
|
||||
ulong gpuVa,
|
||||
int localSizeX,
|
||||
int localSizeY,
|
||||
|
@ -498,7 +500,7 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
|||
{
|
||||
foreach (ShaderBundle cachedCpShader in list)
|
||||
{
|
||||
if (IsShaderEqual(state.Channel.MemoryManager, cachedCpShader, gpuVa))
|
||||
if (IsShaderEqual(channel.MemoryManager, cachedCpShader, gpuVa))
|
||||
{
|
||||
return cachedCpShader;
|
||||
}
|
||||
|
@ -508,7 +510,8 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
|||
TranslatorContext[] shaderContexts = new TranslatorContext[1];
|
||||
|
||||
shaderContexts[0] = DecodeComputeShader(
|
||||
state,
|
||||
channel,
|
||||
gas,
|
||||
gpuVa,
|
||||
localSizeX,
|
||||
localSizeY,
|
||||
|
@ -533,7 +536,7 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
|||
isShaderCacheReadOnly = _cacheManager.IsReadOnly;
|
||||
|
||||
// Compute hash and prepare data for shader disk cache comparison.
|
||||
shaderCacheEntries = CacheHelper.CreateShaderCacheEntries(state.Channel.MemoryManager, shaderContexts);
|
||||
shaderCacheEntries = CacheHelper.CreateShaderCacheEntries(channel.MemoryManager, shaderContexts);
|
||||
programCodeHash = CacheHelper.ComputeGuestHashFromCache(shaderCacheEntries);
|
||||
}
|
||||
|
||||
|
@ -548,7 +551,7 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
|||
}
|
||||
|
||||
// The shader isn't currently cached, translate it and compile it.
|
||||
ShaderCodeHolder shader = TranslateShader(state.Channel.MemoryManager, shaderContexts[0]);
|
||||
ShaderCodeHolder shader = TranslateShader(channel.MemoryManager, shaderContexts[0]);
|
||||
|
||||
shader.HostShader = _context.Renderer.CompileShader(ShaderStage.Compute, shader.Program.Code);
|
||||
|
||||
|
@ -832,7 +835,8 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
|||
/// <summary>
|
||||
/// Decode the binary Maxwell shader code to a translator context.
|
||||
/// </summary>
|
||||
/// <param name="state">Current GPU state</param>
|
||||
/// <param name="channel">GPU channel</param>
|
||||
/// <param name="gas">GPU accessor state</param>
|
||||
/// <param name="gpuVa">GPU virtual address of the binary shader code</param>
|
||||
/// <param name="localSizeX">Local group size X of the computer shader</param>
|
||||
/// <param name="localSizeY">Local group size Y of the computer shader</param>
|
||||
|
@ -841,7 +845,8 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
|||
/// <param name="sharedMemorySize">Shared memory size of the compute shader</param>
|
||||
/// <returns>The generated translator context</returns>
|
||||
private TranslatorContext DecodeComputeShader(
|
||||
GpuState state,
|
||||
GpuChannel channel,
|
||||
GpuAccessorState gas,
|
||||
ulong gpuVa,
|
||||
int localSizeX,
|
||||
int localSizeY,
|
||||
|
@ -854,7 +859,7 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
|||
return null;
|
||||
}
|
||||
|
||||
GpuAccessor gpuAccessor = new GpuAccessor(_context, state, localSizeX, localSizeY, localSizeZ, localMemorySize, sharedMemorySize);
|
||||
GpuAccessor gpuAccessor = new GpuAccessor(_context, channel, gas, localSizeX, localSizeY, localSizeZ, localMemorySize, sharedMemorySize);
|
||||
|
||||
var options = new TranslationOptions(TargetLanguage.Glsl, TargetApi.OpenGL, DefaultFlags | TranslationFlags.Compute);
|
||||
return Translator.CreateContext(gpuVa, gpuAccessor, options);
|
||||
|
@ -884,7 +889,13 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
|||
return null;
|
||||
}
|
||||
|
||||
GpuAccessor gpuAccessor = new GpuAccessor(_context, state, (int)stage - 1);
|
||||
GpuAccessorState gas = new GpuAccessorState(
|
||||
state.Get<PoolState>(MethodOffset.TexturePoolState).Address.Pack(),
|
||||
state.Get<PoolState>(MethodOffset.TexturePoolState).MaximumId,
|
||||
state.Get<int>(MethodOffset.TextureBufferIndex),
|
||||
state.Get<Boolean32>(MethodOffset.EarlyZForce));
|
||||
|
||||
GpuAccessor gpuAccessor = new GpuAccessor(_context, state.Channel, gas, (int)stage - 1);
|
||||
|
||||
var options = new TranslationOptions(TargetLanguage.Glsl, TargetApi.OpenGL, flags);
|
||||
return Translator.CreateContext(gpuVa, gpuAccessor, options, counts);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue