forked from Mirror/Ryujinx
Separate sub-channel state
This commit is contained in:
parent
3ca675223a
commit
2437ccca0e
15 changed files with 213 additions and 198 deletions
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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(
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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();
|
||||||
|
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue