Separate sub-channel state

This commit is contained in:
gdk 2019-11-21 23:46:14 -03:00 committed by Thog
parent 3ca675223a
commit 2437ccca0e
15 changed files with 213 additions and 198 deletions

View file

@ -10,13 +10,13 @@ namespace Ryujinx.Graphics.Gpu.Engine
{ {
partial class Methods partial class Methods
{ {
public void Dispatch(int argument) public void Dispatch(GpuState state, int argument)
{ {
uint dispatchParamsAddress = (uint)_context.State.Get<int>(MethodOffset.DispatchParamsAddress); uint dispatchParamsAddress = (uint)state.Get<int>(MethodOffset.DispatchParamsAddress);
var dispatchParams = _context.MemoryAccessor.Read<ComputeParams>((ulong)dispatchParamsAddress << 8); var dispatchParams = _context.MemoryAccessor.Read<ComputeParams>((ulong)dispatchParamsAddress << 8);
GpuVa shaderBaseAddress = _context.State.Get<GpuVa>(MethodOffset.ShaderBaseAddress); GpuVa shaderBaseAddress = state.Get<GpuVa>(MethodOffset.ShaderBaseAddress);
ulong shaderGpuVa = shaderBaseAddress.Pack() + (uint)dispatchParams.ShaderOffset; ulong shaderGpuVa = shaderBaseAddress.Pack() + (uint)dispatchParams.ShaderOffset;
@ -28,15 +28,15 @@ namespace Ryujinx.Graphics.Gpu.Engine
_context.Renderer.Pipeline.BindProgram(cs.HostProgram); _context.Renderer.Pipeline.BindProgram(cs.HostProgram);
var samplerPool = _context.State.Get<PoolState>(MethodOffset.SamplerPoolState); var samplerPool = state.Get<PoolState>(MethodOffset.SamplerPoolState);
_textureManager.SetComputeSamplerPool(samplerPool.Address.Pack(), samplerPool.MaximumId); _textureManager.SetComputeSamplerPool(samplerPool.Address.Pack(), samplerPool.MaximumId);
var texturePool = _context.State.Get<PoolState>(MethodOffset.TexturePoolState); var texturePool = state.Get<PoolState>(MethodOffset.TexturePoolState);
_textureManager.SetComputeTexturePool(texturePool.Address.Pack(), texturePool.MaximumId); _textureManager.SetComputeTexturePool(texturePool.Address.Pack(), texturePool.MaximumId);
_textureManager.SetComputeTextureBufferIndex(_context.State.Get<int>(MethodOffset.TextureBufferIndex)); _textureManager.SetComputeTextureBufferIndex(state.Get<int>(MethodOffset.TextureBufferIndex));
ShaderProgramInfo info = cs.Shader.Program.Info; ShaderProgramInfo info = cs.Shader.Program.Info;
@ -119,7 +119,7 @@ namespace Ryujinx.Graphics.Gpu.Engine
dispatchParams.UnpackGridSizeY(), dispatchParams.UnpackGridSizeY(),
dispatchParams.UnpackGridSizeZ()); dispatchParams.UnpackGridSizeZ());
UpdateShaderState(); UpdateShaderState(state);
} }
} }
} }

View file

@ -12,9 +12,9 @@ namespace Ryujinx.Graphics.Gpu.Engine
private int _offset; private int _offset;
private int _size; private int _size;
public void LaunchDma(int argument) public void LaunchDma(GpuState state, int argument)
{ {
_params = _context.State.Get<Inline2MemoryParams>(MethodOffset.I2mParams); _params = state.Get<Inline2MemoryParams>(MethodOffset.I2mParams);
_isLinear = (argument & 1) != 0; _isLinear = (argument & 1) != 0;
@ -22,7 +22,7 @@ namespace Ryujinx.Graphics.Gpu.Engine
_size = _params.LineLengthIn * _params.LineCount; _size = _params.LineLengthIn * _params.LineCount;
} }
public void LoadInlineData(int argument) public void LoadInlineData(GpuState state, int argument)
{ {
if (_isLinear) if (_isLinear)
{ {

View file

@ -5,9 +5,9 @@ namespace Ryujinx.Graphics.Gpu.Engine
{ {
partial class Methods partial class Methods
{ {
private void Clear(int argument) private void Clear(GpuState state, int argument)
{ {
UpdateRenderTargetStateIfNeeded(); UpdateRenderTargetStateIfNeeded(state);
_textureManager.CommitGraphicsBindings(); _textureManager.CommitGraphicsBindings();
@ -20,7 +20,7 @@ namespace Ryujinx.Graphics.Gpu.Engine
if (componentMask != 0) if (componentMask != 0)
{ {
var clearColor = _context.State.Get<ClearColors>(MethodOffset.ClearColors); var clearColor = state.Get<ClearColors>(MethodOffset.ClearColors);
ColorF color = new ColorF( ColorF color = new ColorF(
clearColor.Red, clearColor.Red,
@ -33,14 +33,14 @@ namespace Ryujinx.Graphics.Gpu.Engine
if (clearDepth || clearStencil) if (clearDepth || clearStencil)
{ {
float depthValue = _context.State.Get<float>(MethodOffset.ClearDepthValue); float depthValue = state.Get<float>(MethodOffset.ClearDepthValue);
int stencilValue = _context.State.Get<int> (MethodOffset.ClearStencilValue); int stencilValue = state.Get<int> (MethodOffset.ClearStencilValue);
int stencilMask = 0; int stencilMask = 0;
if (clearStencil) if (clearStencil)
{ {
stencilMask = _context.State.Get<StencilTestState>(MethodOffset.StencilTestState).FrontMask; stencilMask = state.Get<StencilTestState>(MethodOffset.StencilTestState).FrontMask;
} }
_context.Renderer.Pipeline.ClearRenderTargetDepthStencil( _context.Renderer.Pipeline.ClearRenderTargetDepthStencil(

View file

@ -6,11 +6,11 @@ namespace Ryujinx.Graphics.Gpu.Engine
{ {
partial class Methods partial class Methods
{ {
private void CopyBuffer(int argument) private void CopyBuffer(GpuState state, int argument)
{ {
var cbp = _context.State.Get<CopyBufferParams>(MethodOffset.CopyBufferParams); var cbp = state.Get<CopyBufferParams>(MethodOffset.CopyBufferParams);
var swizzle = _context.State.Get<CopyBufferSwizzle>(MethodOffset.CopyBufferSwizzle); var swizzle = state.Get<CopyBufferSwizzle>(MethodOffset.CopyBufferSwizzle);
bool srcLinear = (argument & (1 << 7)) != 0; bool srcLinear = (argument & (1 << 7)) != 0;
bool dstLinear = (argument & (1 << 8)) != 0; bool dstLinear = (argument & (1 << 8)) != 0;
@ -29,8 +29,8 @@ namespace Ryujinx.Graphics.Gpu.Engine
int srcBpp = swizzle.UnpackSrcComponentsCount() * swizzle.UnpackComponentSize(); int srcBpp = swizzle.UnpackSrcComponentsCount() * swizzle.UnpackComponentSize();
int dstBpp = swizzle.UnpackDstComponentsCount() * swizzle.UnpackComponentSize(); int dstBpp = swizzle.UnpackDstComponentsCount() * swizzle.UnpackComponentSize();
var dst = _context.State.Get<CopyBufferTexture>(MethodOffset.CopyBufferDstTexture); var dst = state.Get<CopyBufferTexture>(MethodOffset.CopyBufferDstTexture);
var src = _context.State.Get<CopyBufferTexture>(MethodOffset.CopyBufferSrcTexture); var src = state.Get<CopyBufferTexture>(MethodOffset.CopyBufferSrcTexture);
var srcCalculator = new OffsetCalculator( var srcCalculator = new OffsetCalculator(
src.Width, src.Width,

View file

@ -5,10 +5,10 @@ namespace Ryujinx.Graphics.Gpu.Engine
{ {
partial class Methods partial class Methods
{ {
private void CopyTexture(int argument) private void CopyTexture(GpuState state, int argument)
{ {
var dstCopyTexture = _context.State.Get<CopyTexture>(MethodOffset.CopyDstTexture); var dstCopyTexture = state.Get<CopyTexture>(MethodOffset.CopyDstTexture);
var srcCopyTexture = _context.State.Get<CopyTexture>(MethodOffset.CopySrcTexture); var srcCopyTexture = state.Get<CopyTexture>(MethodOffset.CopySrcTexture);
Image.Texture srcTexture = _textureManager.FindOrCreateTexture(srcCopyTexture); Image.Texture srcTexture = _textureManager.FindOrCreateTexture(srcCopyTexture);
@ -32,9 +32,9 @@ namespace Ryujinx.Graphics.Gpu.Engine
return; return;
} }
var control = _context.State.Get<CopyTextureControl>(MethodOffset.CopyTextureControl); var control = state.Get<CopyTextureControl>(MethodOffset.CopyTextureControl);
var region = _context.State.Get<CopyRegion>(MethodOffset.CopyRegion); var region = state.Get<CopyRegion>(MethodOffset.CopyRegion);
int srcX1 = (int)(region.SrcXF >> 32); int srcX1 = (int)(region.SrcXF >> 32);
int srcY1 = (int)(region.SrcYF >> 32); int srcY1 = (int)(region.SrcYF >> 32);

View file

@ -24,9 +24,9 @@ namespace Ryujinx.Graphics.Gpu.Engine
public PrimitiveType PrimitiveType { get; private set; } public PrimitiveType PrimitiveType { get; private set; }
private void DrawEnd(int argument) private void DrawEnd(GpuState state, int argument)
{ {
UpdateState(); UpdateState(state);
bool instanced = _vsUsesInstanceId || _isAnyVbInstanced; bool instanced = _vsUsesInstanceId || _isAnyVbInstanced;
@ -39,12 +39,12 @@ namespace Ryujinx.Graphics.Gpu.Engine
_instancedIndexed = _drawIndexed; _instancedIndexed = _drawIndexed;
_instancedFirstIndex = _firstIndex; _instancedFirstIndex = _firstIndex;
_instancedFirstVertex = _context.State.Get<int>(MethodOffset.FirstVertex); _instancedFirstVertex = state.Get<int>(MethodOffset.FirstVertex);
_instancedFirstInstance = _context.State.Get<int>(MethodOffset.FirstInstance); _instancedFirstInstance = state.Get<int>(MethodOffset.FirstInstance);
_instancedIndexCount = _indexCount; _instancedIndexCount = _indexCount;
var drawState = _context.State.Get<VertexBufferDrawState>(MethodOffset.VertexBufferDrawState); var drawState = state.Get<VertexBufferDrawState>(MethodOffset.VertexBufferDrawState);
_instancedDrawStateFirst = drawState.First; _instancedDrawStateFirst = drawState.First;
_instancedDrawStateCount = drawState.Count; _instancedDrawStateCount = drawState.Count;
@ -53,13 +53,13 @@ namespace Ryujinx.Graphics.Gpu.Engine
return; return;
} }
int firstInstance = _context.State.Get<int>(MethodOffset.FirstInstance); int firstInstance = state.Get<int>(MethodOffset.FirstInstance);
if (_drawIndexed) if (_drawIndexed)
{ {
_drawIndexed = false; _drawIndexed = false;
int firstVertex = _context.State.Get<int>(MethodOffset.FirstVertex); int firstVertex = state.Get<int>(MethodOffset.FirstVertex);
_context.Renderer.Pipeline.DrawIndexed( _context.Renderer.Pipeline.DrawIndexed(
_indexCount, _indexCount,
@ -70,7 +70,7 @@ namespace Ryujinx.Graphics.Gpu.Engine
} }
else else
{ {
var drawState = _context.State.Get<VertexBufferDrawState>(MethodOffset.VertexBufferDrawState); var drawState = state.Get<VertexBufferDrawState>(MethodOffset.VertexBufferDrawState);
_context.Renderer.Pipeline.Draw( _context.Renderer.Pipeline.Draw(
drawState.Count, drawState.Count,
@ -80,7 +80,7 @@ namespace Ryujinx.Graphics.Gpu.Engine
} }
} }
private void DrawBegin(int argument) private void DrawBegin(GpuState state, int argument)
{ {
PrimitiveType type = (PrimitiveType)(argument & 0xffff); PrimitiveType type = (PrimitiveType)(argument & 0xffff);
@ -98,7 +98,7 @@ namespace Ryujinx.Graphics.Gpu.Engine
} }
} }
private void SetIndexBufferCount(int argument) private void SetIndexBufferCount(GpuState state, int argument)
{ {
_drawIndexed = true; _drawIndexed = true;
} }

View file

@ -10,7 +10,7 @@ namespace Ryujinx.Graphics.Gpu.Engine
{ {
private ulong _runningCounter; private ulong _runningCounter;
private void Report(int argument) private void Report(GpuState state, int argument)
{ {
ReportMode mode = (ReportMode)(argument & 3); ReportMode mode = (ReportMode)(argument & 3);
@ -18,16 +18,16 @@ namespace Ryujinx.Graphics.Gpu.Engine
switch (mode) switch (mode)
{ {
case ReportMode.Semaphore: ReportSemaphore(); break; case ReportMode.Semaphore: ReportSemaphore(state); break;
case ReportMode.Counter: ReportCounter(type); break; case ReportMode.Counter: ReportCounter(state, type); break;
} }
} }
private void ReportSemaphore() private void ReportSemaphore(GpuState state)
{ {
var state = _context.State.Get<ReportState>(MethodOffset.ReportState); var rs = state.Get<ReportState>(MethodOffset.ReportState);
_context.MemoryAccessor.Write(state.Address.Pack(), state.Payload); _context.MemoryAccessor.Write(rs.Address.Pack(), rs.Payload);
_context.AdvanceSequence(); _context.AdvanceSequence();
} }
@ -38,7 +38,7 @@ namespace Ryujinx.Graphics.Gpu.Engine
public ulong Timestamp; public ulong Timestamp;
} }
private void ReportCounter(ReportCounterType type) private void ReportCounter(GpuState state, ReportCounterType type)
{ {
CounterData counterData = new CounterData(); CounterData counterData = new CounterData();
@ -78,9 +78,9 @@ namespace Ryujinx.Graphics.Gpu.Engine
Span<byte> data = MemoryMarshal.Cast<CounterData, byte>(counterDataSpan); Span<byte> data = MemoryMarshal.Cast<CounterData, byte>(counterDataSpan);
var state = _context.State.Get<ReportState>(MethodOffset.ReportState); var rs = state.Get<ReportState>(MethodOffset.ReportState);
_context.MemoryAccessor.Write(state.Address.Pack(), data); _context.MemoryAccessor.Write(rs.Address.Pack(), data);
} }
private static ulong ConvertNanosecondsToTicks(ulong nanoseconds) private static ulong ConvertNanosecondsToTicks(ulong nanoseconds)

View file

@ -5,7 +5,7 @@ namespace Ryujinx.Graphics.Gpu.Engine
{ {
partial class Methods partial class Methods
{ {
private void ResetCounter(int argument) private void ResetCounter(GpuState state, int argument)
{ {
ResetCounterType type = (ResetCounterType)argument; ResetCounterType type = (ResetCounterType)argument;

View file

@ -4,32 +4,32 @@ namespace Ryujinx.Graphics.Gpu.Engine
{ {
partial class Methods partial class Methods
{ {
private void UniformBufferBindVertex(int argument) private void UniformBufferBindVertex(GpuState state, int argument)
{ {
UniformBufferBind(argument, ShaderType.Vertex); UniformBufferBind(state, argument, ShaderType.Vertex);
} }
private void UniformBufferBindTessControl(int argument) private void UniformBufferBindTessControl(GpuState state, int argument)
{ {
UniformBufferBind(argument, ShaderType.TessellationControl); UniformBufferBind(state, argument, ShaderType.TessellationControl);
} }
private void UniformBufferBindTessEvaluation(int argument) private void UniformBufferBindTessEvaluation(GpuState state, int argument)
{ {
UniformBufferBind(argument, ShaderType.TessellationEvaluation); UniformBufferBind(state, argument, ShaderType.TessellationEvaluation);
} }
private void UniformBufferBindGeometry(int argument) private void UniformBufferBindGeometry(GpuState state, int argument)
{ {
UniformBufferBind(argument, ShaderType.Geometry); UniformBufferBind(state, argument, ShaderType.Geometry);
} }
private void UniformBufferBindFragment(int argument) private void UniformBufferBindFragment(GpuState state, int argument)
{ {
UniformBufferBind(argument, ShaderType.Fragment); UniformBufferBind(state, argument, ShaderType.Fragment);
} }
private void UniformBufferBind(int argument, ShaderType type) private void UniformBufferBind(GpuState state, int argument, ShaderType type)
{ {
bool enable = (argument & 1) != 0; bool enable = (argument & 1) != 0;
@ -37,7 +37,7 @@ namespace Ryujinx.Graphics.Gpu.Engine
if (enable) if (enable)
{ {
var uniformBuffer = _context.State.Get<UniformBufferState>(MethodOffset.UniformBufferState); var uniformBuffer = state.Get<UniformBufferState>(MethodOffset.UniformBufferState);
ulong address = uniformBuffer.Address.Pack(); ulong address = uniformBuffer.Address.Pack();

View file

@ -4,13 +4,13 @@ namespace Ryujinx.Graphics.Gpu.Engine
{ {
partial class Methods partial class Methods
{ {
private void UniformBufferUpdate(int argument) private void UniformBufferUpdate(GpuState state, int argument)
{ {
var uniformBuffer = _context.State.Get<UniformBufferState>(MethodOffset.UniformBufferState); var uniformBuffer = state.Get<UniformBufferState>(MethodOffset.UniformBufferState);
_context.MemoryAccessor.Write(uniformBuffer.Address.Pack() + (uint)uniformBuffer.Offset, argument); _context.MemoryAccessor.Write(uniformBuffer.Address.Pack() + (uint)uniformBuffer.Offset, argument);
_context.State.SetUniformBufferOffset(uniformBuffer.Offset + 4); state.SetUniformBufferOffset(uniformBuffer.Offset + 4);
_context.AdvanceSequence(); _context.AdvanceSequence();
} }

View file

@ -40,133 +40,131 @@ namespace Ryujinx.Graphics.Gpu.Engine
_bufferManager = new BufferManager(context); _bufferManager = new BufferManager(context);
_textureManager = new TextureManager(context); _textureManager = new TextureManager(context);
RegisterCallbacks();
} }
private void RegisterCallbacks() public void RegisterCallbacks(GpuState state)
{ {
_context.State.RegisterCallback(MethodOffset.LaunchDma, LaunchDma); state.RegisterCallback(MethodOffset.LaunchDma, LaunchDma);
_context.State.RegisterCallback(MethodOffset.LoadInlineData, LoadInlineData); state.RegisterCallback(MethodOffset.LoadInlineData, LoadInlineData);
_context.State.RegisterCallback(MethodOffset.Dispatch, Dispatch); state.RegisterCallback(MethodOffset.Dispatch, Dispatch);
_context.State.RegisterCallback(MethodOffset.CopyBuffer, CopyBuffer); state.RegisterCallback(MethodOffset.CopyBuffer, CopyBuffer);
_context.State.RegisterCallback(MethodOffset.CopyTexture, CopyTexture); state.RegisterCallback(MethodOffset.CopyTexture, CopyTexture);
_context.State.RegisterCallback(MethodOffset.TextureBarrier, TextureBarrier); state.RegisterCallback(MethodOffset.TextureBarrier, TextureBarrier);
_context.State.RegisterCallback(MethodOffset.InvalidateTextures, InvalidateTextures); state.RegisterCallback(MethodOffset.InvalidateTextures, InvalidateTextures);
_context.State.RegisterCallback(MethodOffset.TextureBarrierTiled, TextureBarrierTiled); state.RegisterCallback(MethodOffset.TextureBarrierTiled, TextureBarrierTiled);
_context.State.RegisterCallback(MethodOffset.ResetCounter, ResetCounter); state.RegisterCallback(MethodOffset.ResetCounter, ResetCounter);
_context.State.RegisterCallback(MethodOffset.DrawEnd, DrawEnd); state.RegisterCallback(MethodOffset.DrawEnd, DrawEnd);
_context.State.RegisterCallback(MethodOffset.DrawBegin, DrawBegin); state.RegisterCallback(MethodOffset.DrawBegin, DrawBegin);
_context.State.RegisterCallback(MethodOffset.IndexBufferCount, SetIndexBufferCount); state.RegisterCallback(MethodOffset.IndexBufferCount, SetIndexBufferCount);
_context.State.RegisterCallback(MethodOffset.Clear, Clear); state.RegisterCallback(MethodOffset.Clear, Clear);
_context.State.RegisterCallback(MethodOffset.Report, Report); state.RegisterCallback(MethodOffset.Report, Report);
_context.State.RegisterCallback(MethodOffset.UniformBufferUpdateData, 16, UniformBufferUpdate); state.RegisterCallback(MethodOffset.UniformBufferUpdateData, 16, UniformBufferUpdate);
_context.State.RegisterCallback(MethodOffset.UniformBufferBindVertex, UniformBufferBindVertex); state.RegisterCallback(MethodOffset.UniformBufferBindVertex, UniformBufferBindVertex);
_context.State.RegisterCallback(MethodOffset.UniformBufferBindTessControl, UniformBufferBindTessControl); state.RegisterCallback(MethodOffset.UniformBufferBindTessControl, UniformBufferBindTessControl);
_context.State.RegisterCallback(MethodOffset.UniformBufferBindTessEvaluation, UniformBufferBindTessEvaluation); state.RegisterCallback(MethodOffset.UniformBufferBindTessEvaluation, UniformBufferBindTessEvaluation);
_context.State.RegisterCallback(MethodOffset.UniformBufferBindGeometry, UniformBufferBindGeometry); state.RegisterCallback(MethodOffset.UniformBufferBindGeometry, UniformBufferBindGeometry);
_context.State.RegisterCallback(MethodOffset.UniformBufferBindFragment, UniformBufferBindFragment); state.RegisterCallback(MethodOffset.UniformBufferBindFragment, UniformBufferBindFragment);
} }
public Image.Texture GetTexture(ulong address) => _textureManager.Find2(address); public Image.Texture GetTexture(ulong address) => _textureManager.Find2(address);
private void UpdateState() private void UpdateState(GpuState state)
{ {
// Shaders must be the first one to be updated if modified, because // Shaders must be the first one to be updated if modified, because
// some of the other state depends on information from the currently // some of the other state depends on information from the currently
// bound shaders. // bound shaders.
if (_context.State.QueryModified(MethodOffset.ShaderBaseAddress, MethodOffset.ShaderState)) if (state.QueryModified(MethodOffset.ShaderBaseAddress, MethodOffset.ShaderState))
{ {
UpdateShaderState(); UpdateShaderState(state);
} }
UpdateRenderTargetStateIfNeeded(); UpdateRenderTargetStateIfNeeded(state);
if (_context.State.QueryModified(MethodOffset.DepthTestEnable, if (state.QueryModified(MethodOffset.DepthTestEnable,
MethodOffset.DepthWriteEnable, MethodOffset.DepthWriteEnable,
MethodOffset.DepthTestFunc)) MethodOffset.DepthTestFunc))
{ {
UpdateDepthTestState(); UpdateDepthTestState(state);
} }
if (_context.State.QueryModified(MethodOffset.ViewportTransform, MethodOffset.ViewportExtents)) if (state.QueryModified(MethodOffset.ViewportTransform, MethodOffset.ViewportExtents))
{ {
UpdateViewportTransform(); UpdateViewportTransform(state);
} }
if (_context.State.QueryModified(MethodOffset.DepthBiasState, if (state.QueryModified(MethodOffset.DepthBiasState,
MethodOffset.DepthBiasFactor, MethodOffset.DepthBiasFactor,
MethodOffset.DepthBiasUnits, MethodOffset.DepthBiasUnits,
MethodOffset.DepthBiasClamp)) MethodOffset.DepthBiasClamp))
{ {
UpdateDepthBiasState(); UpdateDepthBiasState(state);
} }
if (_context.State.QueryModified(MethodOffset.StencilBackMasks, if (state.QueryModified(MethodOffset.StencilBackMasks,
MethodOffset.StencilTestState, MethodOffset.StencilTestState,
MethodOffset.StencilBackTestState)) MethodOffset.StencilBackTestState))
{ {
UpdateStencilTestState(); UpdateStencilTestState(state);
} }
// Pools. // Pools.
if (_context.State.QueryModified(MethodOffset.SamplerPoolState)) if (state.QueryModified(MethodOffset.SamplerPoolState))
{ {
UpdateSamplerPoolState(); UpdateSamplerPoolState(state);
} }
if (_context.State.QueryModified(MethodOffset.TexturePoolState)) if (state.QueryModified(MethodOffset.TexturePoolState))
{ {
UpdateTexturePoolState(); UpdateTexturePoolState(state);
} }
// Input assembler state. // Input assembler state.
if (_context.State.QueryModified(MethodOffset.VertexAttribState)) if (state.QueryModified(MethodOffset.VertexAttribState))
{ {
UpdateVertexAttribState(); UpdateVertexAttribState(state);
} }
if (_context.State.QueryModified(MethodOffset.PrimitiveRestartState)) if (state.QueryModified(MethodOffset.PrimitiveRestartState))
{ {
UpdatePrimitiveRestartState(); UpdatePrimitiveRestartState(state);
} }
if (_context.State.QueryModified(MethodOffset.IndexBufferState)) if (state.QueryModified(MethodOffset.IndexBufferState))
{ {
UpdateIndexBufferState(); UpdateIndexBufferState(state);
} }
if (_context.State.QueryModified(MethodOffset.VertexBufferDrawState, if (state.QueryModified(MethodOffset.VertexBufferDrawState,
MethodOffset.VertexBufferInstanced, MethodOffset.VertexBufferInstanced,
MethodOffset.VertexBufferState, MethodOffset.VertexBufferState,
MethodOffset.VertexBufferEndAddress)) MethodOffset.VertexBufferEndAddress))
{ {
UpdateVertexBufferState(); UpdateVertexBufferState(state);
} }
if (_context.State.QueryModified(MethodOffset.FaceState)) if (state.QueryModified(MethodOffset.FaceState))
{ {
UpdateFaceState(); UpdateFaceState(state);
} }
if (_context.State.QueryModified(MethodOffset.RtColorMask)) if (state.QueryModified(MethodOffset.RtColorMask))
{ {
UpdateRtColorMask(); UpdateRtColorMask(state);
} }
if (_context.State.QueryModified(MethodOffset.BlendEnable, MethodOffset.BlendState)) if (state.QueryModified(MethodOffset.BlendEnable, MethodOffset.BlendState))
{ {
UpdateBlendState(); UpdateBlendState(state);
} }
CommitBindings(); CommitBindings();
@ -210,27 +208,27 @@ namespace Ryujinx.Graphics.Gpu.Engine
} }
} }
private void UpdateRenderTargetStateIfNeeded() private void UpdateRenderTargetStateIfNeeded(GpuState state)
{ {
if (_context.State.QueryModified(MethodOffset.RtColorState, if (state.QueryModified(MethodOffset.RtColorState,
MethodOffset.RtDepthStencilState, MethodOffset.RtDepthStencilState,
MethodOffset.RtDepthStencilSize, MethodOffset.RtDepthStencilSize,
MethodOffset.RtDepthStencilEnable)) MethodOffset.RtDepthStencilEnable))
{ {
UpdateRenderTargetState(); UpdateRenderTargetState(state);
} }
} }
private void UpdateRenderTargetState() private void UpdateRenderTargetState(GpuState state)
{ {
var msaaMode = _context.State.Get<TextureMsaaMode>(MethodOffset.RtMsaaMode); var msaaMode = state.Get<TextureMsaaMode>(MethodOffset.RtMsaaMode);
int samplesInX = msaaMode.SamplesInX(); int samplesInX = msaaMode.SamplesInX();
int samplesInY = msaaMode.SamplesInY(); int samplesInY = msaaMode.SamplesInY();
for (int index = 0; index < Constants.TotalRenderTargets; index++) for (int index = 0; index < Constants.TotalRenderTargets; index++)
{ {
var colorState = _context.State.Get<RtColorState>(MethodOffset.RtColorState, index); var colorState = state.Get<RtColorState>(MethodOffset.RtColorState, index);
if (!IsRtEnabled(colorState)) if (!IsRtEnabled(colorState))
{ {
@ -252,14 +250,14 @@ namespace Ryujinx.Graphics.Gpu.Engine
} }
} }
bool dsEnable = _context.State.Get<Boolean32>(MethodOffset.RtDepthStencilEnable); bool dsEnable = state.Get<Boolean32>(MethodOffset.RtDepthStencilEnable);
Image.Texture depthStencil = null; Image.Texture depthStencil = null;
if (dsEnable) if (dsEnable)
{ {
var dsState = _context.State.Get<RtDepthStencilState>(MethodOffset.RtDepthStencilState); var dsState = state.Get<RtDepthStencilState>(MethodOffset.RtDepthStencilState);
var dsSize = _context.State.Get<Size3D> (MethodOffset.RtDepthStencilSize); var dsSize = state.Get<Size3D> (MethodOffset.RtDepthStencilSize);
depthStencil = _textureManager.FindOrCreateTexture( depthStencil = _textureManager.FindOrCreateTexture(
dsState, dsState,
@ -282,22 +280,22 @@ namespace Ryujinx.Graphics.Gpu.Engine
return colorState.Format != 0 && colorState.WidthOrStride != 0; return colorState.Format != 0 && colorState.WidthOrStride != 0;
} }
private void UpdateDepthTestState() private void UpdateDepthTestState(GpuState state)
{ {
_context.Renderer.Pipeline.SetDepthTest(new DepthTestDescriptor( _context.Renderer.Pipeline.SetDepthTest(new DepthTestDescriptor(
_context.State.Get<Boolean32>(MethodOffset.DepthTestEnable), state.Get<Boolean32>(MethodOffset.DepthTestEnable),
_context.State.Get<Boolean32>(MethodOffset.DepthWriteEnable), state.Get<Boolean32>(MethodOffset.DepthWriteEnable),
_context.State.Get<CompareOp>(MethodOffset.DepthTestFunc))); state.Get<CompareOp>(MethodOffset.DepthTestFunc)));
} }
private void UpdateViewportTransform() private void UpdateViewportTransform(GpuState state)
{ {
Viewport[] viewports = new Viewport[Constants.TotalViewports]; Viewport[] viewports = new Viewport[Constants.TotalViewports];
for (int index = 0; index < Constants.TotalViewports; index++) for (int index = 0; index < Constants.TotalViewports; index++)
{ {
var transform = _context.State.Get<ViewportTransform>(MethodOffset.ViewportTransform, index); var transform = state.Get<ViewportTransform>(MethodOffset.ViewportTransform, index);
var extents = _context.State.Get<ViewportExtents> (MethodOffset.ViewportExtents, index); var extents = state.Get<ViewportExtents> (MethodOffset.ViewportExtents, index);
float x = transform.TranslateX - MathF.Abs(transform.ScaleX); float x = transform.TranslateX - MathF.Abs(transform.ScaleX);
float y = transform.TranslateY - MathF.Abs(transform.ScaleY); float y = transform.TranslateY - MathF.Abs(transform.ScaleY);
@ -320,13 +318,13 @@ namespace Ryujinx.Graphics.Gpu.Engine
_context.Renderer.Pipeline.SetViewports(0, viewports); _context.Renderer.Pipeline.SetViewports(0, viewports);
} }
private void UpdateDepthBiasState() private void UpdateDepthBiasState(GpuState state)
{ {
var depthBias = _context.State.Get<DepthBiasState>(MethodOffset.DepthBiasState); var depthBias = state.Get<DepthBiasState>(MethodOffset.DepthBiasState);
float factor = _context.State.Get<float>(MethodOffset.DepthBiasFactor); float factor = state.Get<float>(MethodOffset.DepthBiasFactor);
float units = _context.State.Get<float>(MethodOffset.DepthBiasUnits); float units = state.Get<float>(MethodOffset.DepthBiasUnits);
float clamp = _context.State.Get<float>(MethodOffset.DepthBiasClamp); float clamp = state.Get<float>(MethodOffset.DepthBiasClamp);
PolygonModeMask enables = 0; PolygonModeMask enables = 0;
@ -337,11 +335,11 @@ namespace Ryujinx.Graphics.Gpu.Engine
_context.Renderer.Pipeline.SetDepthBias(enables, factor, units, clamp); _context.Renderer.Pipeline.SetDepthBias(enables, factor, units, clamp);
} }
private void UpdateStencilTestState() private void UpdateStencilTestState(GpuState state)
{ {
var backMasks = _context.State.Get<StencilBackMasks> (MethodOffset.StencilBackMasks); var backMasks = state.Get<StencilBackMasks> (MethodOffset.StencilBackMasks);
var test = _context.State.Get<StencilTestState> (MethodOffset.StencilTestState); var test = state.Get<StencilTestState> (MethodOffset.StencilTestState);
var backTest = _context.State.Get<StencilBackTestState>(MethodOffset.StencilBackTestState); var backTest = state.Get<StencilBackTestState>(MethodOffset.StencilBackTestState);
CompareOp backFunc; CompareOp backFunc;
StencilOp backSFail; StencilOp backSFail;
@ -390,29 +388,29 @@ namespace Ryujinx.Graphics.Gpu.Engine
backMask)); backMask));
} }
private void UpdateSamplerPoolState() private void UpdateSamplerPoolState(GpuState state)
{ {
var samplerPool = _context.State.Get<PoolState>(MethodOffset.SamplerPoolState); var samplerPool = state.Get<PoolState>(MethodOffset.SamplerPoolState);
_textureManager.SetGraphicsSamplerPool(samplerPool.Address.Pack(), samplerPool.MaximumId); _textureManager.SetGraphicsSamplerPool(samplerPool.Address.Pack(), samplerPool.MaximumId);
} }
private void UpdateTexturePoolState() private void UpdateTexturePoolState(GpuState state)
{ {
var texturePool = _context.State.Get<PoolState>(MethodOffset.TexturePoolState); var texturePool = state.Get<PoolState>(MethodOffset.TexturePoolState);
_textureManager.SetGraphicsTexturePool(texturePool.Address.Pack(), texturePool.MaximumId); _textureManager.SetGraphicsTexturePool(texturePool.Address.Pack(), texturePool.MaximumId);
_textureManager.SetGraphicsTextureBufferIndex(_context.State.Get<int>(MethodOffset.TextureBufferIndex)); _textureManager.SetGraphicsTextureBufferIndex(state.Get<int>(MethodOffset.TextureBufferIndex));
} }
private void UpdateVertexAttribState() private void UpdateVertexAttribState(GpuState state)
{ {
VertexAttribDescriptor[] vertexAttribs = new VertexAttribDescriptor[16]; VertexAttribDescriptor[] vertexAttribs = new VertexAttribDescriptor[16];
for (int index = 0; index < 16; index++) for (int index = 0; index < 16; index++)
{ {
var vertexAttrib = _context.State.Get<VertexAttribState>(MethodOffset.VertexAttribState, index); var vertexAttrib = state.Get<VertexAttribState>(MethodOffset.VertexAttribState, index);
if (!FormatTable.TryGetAttribFormat(vertexAttrib.UnpackFormat(), out Format format)) if (!FormatTable.TryGetAttribFormat(vertexAttrib.UnpackFormat(), out Format format))
{ {
@ -430,18 +428,18 @@ namespace Ryujinx.Graphics.Gpu.Engine
_context.Renderer.Pipeline.BindVertexAttribs(vertexAttribs); _context.Renderer.Pipeline.BindVertexAttribs(vertexAttribs);
} }
private void UpdatePrimitiveRestartState() private void UpdatePrimitiveRestartState(GpuState state)
{ {
PrimitiveRestartState primitiveRestart = _context.State.Get<PrimitiveRestartState>(MethodOffset.PrimitiveRestartState); PrimitiveRestartState primitiveRestart = state.Get<PrimitiveRestartState>(MethodOffset.PrimitiveRestartState);
_context.Renderer.Pipeline.SetPrimitiveRestart( _context.Renderer.Pipeline.SetPrimitiveRestart(
primitiveRestart.Enable, primitiveRestart.Enable,
primitiveRestart.Index); primitiveRestart.Index);
} }
private void UpdateIndexBufferState() private void UpdateIndexBufferState(GpuState state)
{ {
var indexBuffer = _context.State.Get<IndexBufferState>(MethodOffset.IndexBufferState); var indexBuffer = state.Get<IndexBufferState>(MethodOffset.IndexBufferState);
_firstIndex = indexBuffer.First; _firstIndex = indexBuffer.First;
_indexCount = indexBuffer.Count; _indexCount = indexBuffer.Count;
@ -467,16 +465,16 @@ namespace Ryujinx.Graphics.Gpu.Engine
// The index buffer affects the vertex buffer size calculation, we // The index buffer affects the vertex buffer size calculation, we
// need to ensure that they are updated. // need to ensure that they are updated.
UpdateVertexBufferState(); UpdateVertexBufferState(state);
} }
private void UpdateVertexBufferState() private void UpdateVertexBufferState(GpuState state)
{ {
_isAnyVbInstanced = false; _isAnyVbInstanced = false;
for (int index = 0; index < 16; index++) for (int index = 0; index < 16; index++)
{ {
var vertexBuffer = _context.State.Get<VertexBufferState>(MethodOffset.VertexBufferState, index); var vertexBuffer = state.Get<VertexBufferState>(MethodOffset.VertexBufferState, index);
if (!vertexBuffer.UnpackEnable()) if (!vertexBuffer.UnpackEnable())
{ {
@ -485,13 +483,13 @@ namespace Ryujinx.Graphics.Gpu.Engine
continue; continue;
} }
GpuVa endAddress = _context.State.Get<GpuVa>(MethodOffset.VertexBufferEndAddress, index); GpuVa endAddress = state.Get<GpuVa>(MethodOffset.VertexBufferEndAddress, index);
ulong address = vertexBuffer.Address.Pack(); ulong address = vertexBuffer.Address.Pack();
int stride = vertexBuffer.UnpackStride(); int stride = vertexBuffer.UnpackStride();
bool instanced = _context.State.Get<Boolean32>(MethodOffset.VertexBufferInstanced + index); bool instanced = state.Get<Boolean32>(MethodOffset.VertexBufferInstanced + index);
int divisor = instanced ? vertexBuffer.Divisor : 0; int divisor = instanced ? vertexBuffer.Divisor : 0;
@ -509,9 +507,9 @@ namespace Ryujinx.Graphics.Gpu.Engine
{ {
// For non-indexed draws, we can guess the size from the vertex count // For non-indexed draws, we can guess the size from the vertex count
// and stride. // and stride.
int firstInstance = _context.State.Get<int>(MethodOffset.FirstInstance); int firstInstance = state.Get<int>(MethodOffset.FirstInstance);
var drawState = _context.State.Get<VertexBufferDrawState>(MethodOffset.VertexBufferDrawState); var drawState = state.Get<VertexBufferDrawState>(MethodOffset.VertexBufferDrawState);
size = (ulong)((firstInstance + drawState.First + drawState.Count) * stride); size = (ulong)((firstInstance + drawState.First + drawState.Count) * stride);
} }
@ -520,22 +518,22 @@ namespace Ryujinx.Graphics.Gpu.Engine
} }
} }
private void UpdateFaceState() private void UpdateFaceState(GpuState state)
{ {
var face = _context.State.Get<FaceState>(MethodOffset.FaceState); var face = state.Get<FaceState>(MethodOffset.FaceState);
_context.Renderer.Pipeline.SetFaceCulling(face.CullEnable, face.CullFace); _context.Renderer.Pipeline.SetFaceCulling(face.CullEnable, face.CullFace);
_context.Renderer.Pipeline.SetFrontFace(face.FrontFace); _context.Renderer.Pipeline.SetFrontFace(face.FrontFace);
} }
private void UpdateRtColorMask() private void UpdateRtColorMask(GpuState state)
{ {
uint[] componentMasks = new uint[Constants.TotalRenderTargets]; uint[] componentMasks = new uint[Constants.TotalRenderTargets];
for (int index = 0; index < Constants.TotalRenderTargets; index++) for (int index = 0; index < Constants.TotalRenderTargets; index++)
{ {
var colorMask = _context.State.Get<RtColorMask>(MethodOffset.RtColorMask, index); var colorMask = state.Get<RtColorMask>(MethodOffset.RtColorMask, index);
uint componentMask = 0; uint componentMask = 0;
@ -550,15 +548,15 @@ namespace Ryujinx.Graphics.Gpu.Engine
_context.Renderer.Pipeline.SetRenderTargetColorMasks(componentMasks); _context.Renderer.Pipeline.SetRenderTargetColorMasks(componentMasks);
} }
private void UpdateBlendState() private void UpdateBlendState(GpuState state)
{ {
BlendState[] blends = new BlendState[8]; BlendState[] blends = new BlendState[8];
for (int index = 0; index < 8; index++) for (int index = 0; index < 8; index++)
{ {
bool enable = _context.State.Get<Boolean32>(MethodOffset.BlendEnable, index); bool enable = state.Get<Boolean32>(MethodOffset.BlendEnable, index);
var blend = _context.State.Get<BlendState>(MethodOffset.BlendState, index); var blend = state.Get<BlendState>(MethodOffset.BlendState, index);
BlendDescriptor descriptor = new BlendDescriptor( BlendDescriptor descriptor = new BlendDescriptor(
enable, enable,
@ -586,7 +584,7 @@ namespace Ryujinx.Graphics.Gpu.Engine
} }
} }
private void UpdateShaderState() private void UpdateShaderState(GpuState state)
{ {
ShaderAddresses addresses = new ShaderAddresses(); ShaderAddresses addresses = new ShaderAddresses();
@ -594,11 +592,11 @@ namespace Ryujinx.Graphics.Gpu.Engine
Span<ulong> addressesArray = MemoryMarshal.Cast<ShaderAddresses, ulong>(addressesSpan); Span<ulong> addressesArray = MemoryMarshal.Cast<ShaderAddresses, ulong>(addressesSpan);
ulong baseAddress = _context.State.Get<GpuVa>(MethodOffset.ShaderBaseAddress).Pack(); ulong baseAddress = state.Get<GpuVa>(MethodOffset.ShaderBaseAddress).Pack();
for (int index = 0; index < 6; index++) for (int index = 0; index < 6; index++)
{ {
var shader = _context.State.Get<ShaderState>(MethodOffset.ShaderState, index); var shader = state.Get<ShaderState>(MethodOffset.ShaderState, index);
if (!shader.UnpackEnable() && index != 1) if (!shader.UnpackEnable() && index != 1)
{ {
@ -711,17 +709,17 @@ namespace Ryujinx.Graphics.Gpu.Engine
return Target.Texture2D; return Target.Texture2D;
} }
private void TextureBarrier(int argument) private void TextureBarrier(GpuState state, int argument)
{ {
_context.Renderer.Pipeline.TextureBarrier(); _context.Renderer.Pipeline.TextureBarrier();
} }
private void InvalidateTextures(int argument) private void InvalidateTextures(GpuState state, int argument)
{ {
_textureManager.Flush(); _textureManager.Flush();
} }
private void TextureBarrierTiled(int argument) private void TextureBarrierTiled(GpuState state, int argument)
{ {
_context.Renderer.Pipeline.TextureBarrierTiled(); _context.Renderer.Pipeline.TextureBarrierTiled();
} }

View file

@ -12,8 +12,6 @@ namespace Ryujinx.Graphics.Gpu
{ {
public IRenderer Renderer { get; } public IRenderer Renderer { get; }
internal GpuState State { get; }
internal IPhysicalMemory PhysicalMemory { get; private set; } internal IPhysicalMemory PhysicalMemory { get; private set; }
public MemoryManager MemoryManager { get; } public MemoryManager MemoryManager { get; }
@ -36,8 +34,6 @@ namespace Ryujinx.Graphics.Gpu
{ {
Renderer = renderer; Renderer = renderer;
State = new GpuState();
MemoryManager = new MemoryManager(); MemoryManager = new MemoryManager();
MemoryAccessor = new MemoryAccessor(this); MemoryAccessor = new MemoryAccessor(this);

View file

@ -1,4 +1,5 @@
using Ryujinx.Common.Logging; using Ryujinx.Common.Logging;
using Ryujinx.Graphics.Gpu.State;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
@ -70,7 +71,7 @@ namespace Ryujinx.Graphics.Gpu
_gprs = new int[8]; _gprs = new int[8];
} }
public void Execute(int[] mme, int position, int param) public void Execute(int[] mme, int position, int param, GpuState state)
{ {
Reset(); Reset();
@ -80,11 +81,11 @@ namespace Ryujinx.Graphics.Gpu
FetchOpCode(mme); FetchOpCode(mme);
while (Step(mme)); while (Step(mme, state));
// Due to the delay slot, we still need to execute // Due to the delay slot, we still need to execute
// one more instruction before we actually exit. // one more instruction before we actually exit.
Step(mme); Step(mme, state);
} }
private void Reset() private void Reset()
@ -100,7 +101,7 @@ namespace Ryujinx.Graphics.Gpu
_carry = false; _carry = false;
} }
private bool Step(int[] mme) private bool Step(int[] mme, GpuState state)
{ {
int baseAddr = _pc - 1; int baseAddr = _pc - 1;
@ -111,7 +112,7 @@ namespace Ryujinx.Graphics.Gpu
// Operation produces a value. // Operation produces a value.
AssignmentOperation asgOp = (AssignmentOperation)((_opCode >> 4) & 7); AssignmentOperation asgOp = (AssignmentOperation)((_opCode >> 4) & 7);
int result = GetAluResult(); int result = GetAluResult(state);
switch (asgOp) switch (asgOp)
{ {
@ -146,7 +147,7 @@ namespace Ryujinx.Graphics.Gpu
{ {
SetDstGpr(FetchParam()); SetDstGpr(FetchParam());
Send(result); Send(state, result);
break; break;
} }
@ -156,7 +157,7 @@ namespace Ryujinx.Graphics.Gpu
{ {
SetDstGpr(result); SetDstGpr(result);
Send(result); Send(state, result);
break; break;
} }
@ -178,7 +179,7 @@ namespace Ryujinx.Graphics.Gpu
SetMethAddr(result); SetMethAddr(result);
Send(FetchParam()); Send(state, FetchParam());
break; break;
} }
@ -190,7 +191,7 @@ namespace Ryujinx.Graphics.Gpu
SetMethAddr(result); SetMethAddr(result);
Send((result >> 12) & 0x3f); Send(state, (result >> 12) & 0x3f);
break; break;
} }
@ -231,7 +232,7 @@ namespace Ryujinx.Graphics.Gpu
_pipeOp = mme[_pc++]; _pipeOp = mme[_pc++];
} }
private int GetAluResult() private int GetAluResult(GpuState state)
{ {
AluOperation op = (AluOperation)(_opCode & 7); AluOperation op = (AluOperation)(_opCode & 7);
@ -295,7 +296,7 @@ namespace Ryujinx.Graphics.Gpu
case AluOperation.ReadImmediate: case AluOperation.ReadImmediate:
{ {
return Read(GetGprA() + GetImm()); return Read(state, GetGprA() + GetImm());
} }
} }
@ -398,16 +399,16 @@ namespace Ryujinx.Graphics.Gpu
return value; return value;
} }
private int Read(int reg) private int Read(GpuState state, int reg)
{ {
return _context.State.Read(reg); return state.Read(reg);
} }
private void Send(int value) private void Send(GpuState state, int value)
{ {
MethodParams meth = new MethodParams(_methAddr, value); MethodParams meth = new MethodParams(_methAddr, value);
_context.State.CallMethod(meth); state.CallMethod(meth);
_methAddr += _methIncr; _methAddr += _methIncr;
} }

View file

@ -1,3 +1,5 @@
using Ryujinx.Graphics.Gpu.State;
namespace Ryujinx.Graphics.Gpu namespace Ryujinx.Graphics.Gpu
{ {
class NvGpuFifo class NvGpuFifo
@ -37,13 +39,13 @@ namespace Ryujinx.Graphics.Gpu
_executionPending = true; _executionPending = true;
} }
public void Execute(int[] mme) public void Execute(int[] mme, GpuState state)
{ {
if (_executionPending) if (_executionPending)
{ {
_executionPending = false; _executionPending = false;
_interpreter?.Execute(mme, Position, _argument); _interpreter?.Execute(mme, Position, _argument, state);
} }
} }
@ -60,7 +62,18 @@ namespace Ryujinx.Graphics.Gpu
private int[] _mme; private int[] _mme;
private ClassId[] _subChannels; private class SubChannel
{
public GpuState State { get; }
public ClassId Class { get; set; }
public SubChannel()
{
State = new GpuState();
}
}
private SubChannel[] _subChannels;
public NvGpuFifo(GpuContext context) public NvGpuFifo(GpuContext context)
{ {
@ -70,14 +83,21 @@ namespace Ryujinx.Graphics.Gpu
_mme = new int[MmeWords]; _mme = new int[MmeWords];
_subChannels = new ClassId[8]; _subChannels = new SubChannel[8];
for (int index = 0; index < _subChannels.Length; index++)
{
_subChannels[index] = new SubChannel();
context.Methods.RegisterCallbacks(_subChannels[index].State);
}
} }
public void CallMethod(MethodParams meth) public void CallMethod(MethodParams meth)
{ {
if ((NvGpuFifoMeth)meth.Method == NvGpuFifoMeth.BindChannel) if ((NvGpuFifoMeth)meth.Method == NvGpuFifoMeth.BindChannel)
{ {
_subChannels[meth.SubChannel] = (ClassId)meth.Argument; _subChannels[meth.SubChannel].Class = (ClassId)meth.Argument;
} }
else if (meth.Method < 0x60) else if (meth.Method < 0x60)
{ {
@ -123,7 +143,7 @@ namespace Ryujinx.Graphics.Gpu
} }
else if (meth.Method < 0xe00) else if (meth.Method < 0xe00)
{ {
_context.State.CallMethod(meth); _subChannels[meth.SubChannel].State.CallMethod(meth);
} }
else else
{ {
@ -140,7 +160,7 @@ namespace Ryujinx.Graphics.Gpu
if (meth.IsLastCall) if (meth.IsLastCall)
{ {
_macros[macroIndex].Execute(_mme); _macros[macroIndex].Execute(_mme, _subChannels[meth.SubChannel].State);
_context.Methods.PerformDeferredDraws(); _context.Methods.PerformDeferredDraws();
} }

View file

@ -7,7 +7,7 @@ namespace Ryujinx.Graphics.Gpu.State
{ {
private const int RegistersCount = 0xe00; private const int RegistersCount = 0xe00;
public delegate void MethodCallback(int argument); public delegate void MethodCallback(GpuState state, int argument);
private int[] _backingMemory; private int[] _backingMemory;
@ -71,7 +71,7 @@ namespace Ryujinx.Graphics.Gpu.State
if (callback != null) if (callback != null)
{ {
callback(meth.Argument); callback(this, meth.Argument);
} }
} }