Add per-source type memory change tracking, simplified state change tracking, other fixes
This commit is contained in:
parent
1b7d955195
commit
8cba252b23
40 changed files with 494 additions and 668 deletions
|
@ -14,8 +14,6 @@ namespace ARMeilleure.Memory
|
||||||
public const int PageSize = 1 << PageBits;
|
public const int PageSize = 1 << PageBits;
|
||||||
public const int PageMask = PageSize - 1;
|
public const int PageMask = PageSize - 1;
|
||||||
|
|
||||||
private const long PteFlagNotModified = 1;
|
|
||||||
|
|
||||||
internal const long PteFlagsMask = 7;
|
internal const long PteFlagsMask = 7;
|
||||||
|
|
||||||
public IntPtr Ram { get; private set; }
|
public IntPtr Ram { get; private set; }
|
||||||
|
@ -106,6 +104,11 @@ namespace ARMeilleure.Memory
|
||||||
ptr = (byte*)ptrUlong;
|
ptr = (byte*)ptrUlong;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ptr == null)
|
||||||
|
{
|
||||||
|
return IntPtr.Zero;
|
||||||
|
}
|
||||||
|
|
||||||
return new IntPtr(ptr + (position & PageMask));
|
return new IntPtr(ptr + (position & PageMask));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -122,10 +125,7 @@ namespace ARMeilleure.Memory
|
||||||
|
|
||||||
if ((ptrUlong & PteFlagsMask) != 0)
|
if ((ptrUlong & PteFlagsMask) != 0)
|
||||||
{
|
{
|
||||||
if ((ptrUlong & PteFlagNotModified) != 0)
|
ClearPtEntryFlag(position, PteFlagsMask);
|
||||||
{
|
|
||||||
ClearPtEntryFlag(position, PteFlagNotModified);
|
|
||||||
}
|
|
||||||
|
|
||||||
ptrUlong &= ~(ulong)PteFlagsMask;
|
ptrUlong &= ~(ulong)PteFlagsMask;
|
||||||
|
|
||||||
|
@ -253,8 +253,10 @@ namespace ARMeilleure.Memory
|
||||||
return ptePtr;
|
return ptePtr;
|
||||||
}
|
}
|
||||||
|
|
||||||
public unsafe (ulong, ulong)[] GetModifiedRanges(ulong address, ulong size)
|
public unsafe (ulong, ulong)[] GetModifiedRanges(ulong address, ulong size, int id)
|
||||||
{
|
{
|
||||||
|
ulong idMask = 1UL << id;
|
||||||
|
|
||||||
List<(ulong, ulong)> ranges = new List<(ulong, ulong)>();
|
List<(ulong, ulong)> ranges = new List<(ulong, ulong)>();
|
||||||
|
|
||||||
ulong endAddress = (address + size + PageMask) & ~(ulong)PageMask;
|
ulong endAddress = (address + size + PageMask) & ~(ulong)PageMask;
|
||||||
|
@ -272,12 +274,12 @@ namespace ARMeilleure.Memory
|
||||||
|
|
||||||
ulong ptrUlong = (ulong)ptr;
|
ulong ptrUlong = (ulong)ptr;
|
||||||
|
|
||||||
if ((ptrUlong & PteFlagNotModified) == 0)
|
if ((ptrUlong & idMask) == 0)
|
||||||
{
|
{
|
||||||
// Modified.
|
// Modified.
|
||||||
currSize += PageSize;
|
currSize += PageSize;
|
||||||
|
|
||||||
SetPtEntryFlag((long)address, PteFlagNotModified);
|
SetPtEntryFlag((long)address, (long)idMask);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -27,15 +27,15 @@ namespace Ryujinx.Graphics.Gpu.Engine
|
||||||
|
|
||||||
_context.Renderer.Pipeline.BindProgram(cs.Interface);
|
_context.Renderer.Pipeline.BindProgram(cs.Interface);
|
||||||
|
|
||||||
PoolState samplerPool = _context.State.GetSamplerPoolState();
|
var samplerPool = _context.State.Get<PoolState>(MethodOffset.SamplerPoolState);
|
||||||
|
|
||||||
_textureManager.SetComputeSamplerPool(samplerPool.Address.Pack(), samplerPool.MaximumId);
|
_textureManager.SetComputeSamplerPool(samplerPool.Address.Pack(), samplerPool.MaximumId);
|
||||||
|
|
||||||
PoolState texturePool = _context.State.GetTexturePoolState();
|
var texturePool = _context.State.Get<PoolState>(MethodOffset.TexturePoolState);
|
||||||
|
|
||||||
_textureManager.SetComputeTexturePool(texturePool.Address.Pack(), texturePool.MaximumId);
|
_textureManager.SetComputeTexturePool(texturePool.Address.Pack(), texturePool.MaximumId);
|
||||||
|
|
||||||
_textureManager.SetComputeTextureBufferIndex(_context.State.GetTextureBufferIndex());
|
_textureManager.SetComputeTextureBufferIndex(_context.State.Get<int>(MethodOffset.TextureBufferIndex));
|
||||||
|
|
||||||
ShaderProgramInfo info = cs.Shader.Info;
|
ShaderProgramInfo info = cs.Shader.Info;
|
||||||
|
|
||||||
|
@ -117,6 +117,8 @@ namespace Ryujinx.Graphics.Gpu.Engine
|
||||||
dispatchParams.UnpackGridSizeX(),
|
dispatchParams.UnpackGridSizeX(),
|
||||||
dispatchParams.UnpackGridSizeY(),
|
dispatchParams.UnpackGridSizeY(),
|
||||||
dispatchParams.UnpackGridSizeZ());
|
dispatchParams.UnpackGridSizeZ());
|
||||||
|
|
||||||
|
UpdateShaderState();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -12,9 +12,9 @@ namespace Ryujinx.Graphics.Gpu.Engine
|
||||||
private int _offset;
|
private int _offset;
|
||||||
private int _size;
|
private int _size;
|
||||||
|
|
||||||
public void Execute(int argument)
|
public void LaunchDma(int argument)
|
||||||
{
|
{
|
||||||
_params = _context.State.Get<Inline2MemoryParams>(MethodOffset.Inline2MemoryParams);
|
_params = _context.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 PushData(int argument)
|
public void LoadInlineData(int argument)
|
||||||
{
|
{
|
||||||
if (_isLinear)
|
if (_isLinear)
|
||||||
{
|
{
|
||||||
|
|
|
@ -7,7 +7,9 @@ namespace Ryujinx.Graphics.Gpu.Engine
|
||||||
{
|
{
|
||||||
private void Clear(int argument)
|
private void Clear(int argument)
|
||||||
{
|
{
|
||||||
UpdateState();
|
UpdateRenderTargetStateIfNeeded();
|
||||||
|
|
||||||
|
_textureManager.CommitGraphicsBindings();
|
||||||
|
|
||||||
bool clearDepth = (argument & 1) != 0;
|
bool clearDepth = (argument & 1) != 0;
|
||||||
bool clearStencil = (argument & 2) != 0;
|
bool clearStencil = (argument & 2) != 0;
|
||||||
|
@ -18,7 +20,7 @@ namespace Ryujinx.Graphics.Gpu.Engine
|
||||||
|
|
||||||
if (componentMask != 0)
|
if (componentMask != 0)
|
||||||
{
|
{
|
||||||
ClearColors clearColor = _context.State.GetClearColors();
|
var clearColor = _context.State.Get<ClearColors>(MethodOffset.ClearColors);
|
||||||
|
|
||||||
ColorF color = new ColorF(
|
ColorF color = new ColorF(
|
||||||
clearColor.Red,
|
clearColor.Red,
|
||||||
|
@ -26,22 +28,19 @@ namespace Ryujinx.Graphics.Gpu.Engine
|
||||||
clearColor.Blue,
|
clearColor.Blue,
|
||||||
clearColor.Alpha);
|
clearColor.Alpha);
|
||||||
|
|
||||||
_context.Renderer.Pipeline.ClearRenderTargetColor(
|
_context.Renderer.Pipeline.ClearRenderTargetColor(index, componentMask, color);
|
||||||
index,
|
|
||||||
componentMask,
|
|
||||||
color);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (clearDepth || clearStencil)
|
if (clearDepth || clearStencil)
|
||||||
{
|
{
|
||||||
float depthValue = _context.State.GetClearDepthValue();
|
float depthValue = _context.State.Get<float>(MethodOffset.ClearDepthValue);
|
||||||
int stencilValue = _context.State.GetClearStencilValue();
|
int stencilValue = _context.State.Get<int> (MethodOffset.ClearStencilValue);
|
||||||
|
|
||||||
int stencilMask = 0;
|
int stencilMask = 0;
|
||||||
|
|
||||||
if (clearStencil)
|
if (clearStencil)
|
||||||
{
|
{
|
||||||
stencilMask = _context.State.GetStencilTestState().FrontMask;
|
stencilMask = _context.State.Get<StencilTestState>(MethodOffset.StencilTestState).FrontMask;
|
||||||
}
|
}
|
||||||
|
|
||||||
_context.Renderer.Pipeline.ClearRenderTargetDepthStencil(
|
_context.Renderer.Pipeline.ClearRenderTargetDepthStencil(
|
||||||
|
|
|
@ -7,8 +7,8 @@ namespace Ryujinx.Graphics.Gpu.Engine
|
||||||
{
|
{
|
||||||
private void CopyTexture(int argument)
|
private void CopyTexture(int argument)
|
||||||
{
|
{
|
||||||
CopyTexture dstCopyTexture = _context.State.GetCopyDstTexture();
|
var dstCopyTexture = _context.State.Get<CopyTexture>(MethodOffset.CopyDstTexture);
|
||||||
CopyTexture srcCopyTexture = _context.State.GetCopySrcTexture();
|
var srcCopyTexture = _context.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;
|
||||||
}
|
}
|
||||||
|
|
||||||
CopyTextureControl control = _context.State.GetCopyTextureControl();
|
var control = _context.State.Get<CopyTextureControl>(MethodOffset.CopyTextureControl);
|
||||||
|
|
||||||
CopyRegion region = _context.State.GetCopyRegion();
|
var region = _context.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);
|
||||||
|
|
|
@ -39,12 +39,12 @@ namespace Ryujinx.Graphics.Gpu.Engine
|
||||||
_instancedIndexed = _drawIndexed;
|
_instancedIndexed = _drawIndexed;
|
||||||
|
|
||||||
_instancedFirstIndex = _firstIndex;
|
_instancedFirstIndex = _firstIndex;
|
||||||
_instancedFirstVertex = _context.State.GetBaseVertex();
|
_instancedFirstVertex = _context.State.Get<int>(MethodOffset.FirstVertex);
|
||||||
_instancedFirstInstance = _context.State.GetBaseInstance();
|
_instancedFirstInstance = _context.State.Get<int>(MethodOffset.FirstInstance);
|
||||||
|
|
||||||
_instancedIndexCount = _indexCount;
|
_instancedIndexCount = _indexCount;
|
||||||
|
|
||||||
VertexBufferDrawState drawState = _context.State.GetVertexBufferDrawState();
|
var drawState = _context.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.GetBaseInstance();
|
int firstInstance = _context.State.Get<int>(MethodOffset.FirstInstance);
|
||||||
|
|
||||||
if (_drawIndexed)
|
if (_drawIndexed)
|
||||||
{
|
{
|
||||||
_drawIndexed = false;
|
_drawIndexed = false;
|
||||||
|
|
||||||
int firstVertex = _context.State.GetBaseVertex();
|
int firstVertex = _context.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
|
||||||
{
|
{
|
||||||
VertexBufferDrawState drawState = _context.State.GetVertexBufferDrawState();
|
var drawState = _context.State.Get<VertexBufferDrawState>(MethodOffset.VertexBufferDrawState);
|
||||||
|
|
||||||
_context.Renderer.Pipeline.Draw(
|
_context.Renderer.Pipeline.Draw(
|
||||||
drawState.Count,
|
drawState.Count,
|
||||||
|
@ -98,7 +98,7 @@ namespace Ryujinx.Graphics.Gpu.Engine
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SetIndexCount(int argument)
|
private void SetIndexBufferCount(int argument)
|
||||||
{
|
{
|
||||||
_drawIndexed = true;
|
_drawIndexed = true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,7 +25,7 @@ namespace Ryujinx.Graphics.Gpu.Engine
|
||||||
|
|
||||||
private void ReportSemaphore()
|
private void ReportSemaphore()
|
||||||
{
|
{
|
||||||
ReportState state = _context.State.GetReportState();
|
var state = _context.State.Get<ReportState>(MethodOffset.ReportState);
|
||||||
|
|
||||||
_context.MemoryAccessor.Write(state.Address.Pack(), state.Payload);
|
_context.MemoryAccessor.Write(state.Address.Pack(), state.Payload);
|
||||||
|
|
||||||
|
@ -78,7 +78,7 @@ namespace Ryujinx.Graphics.Gpu.Engine
|
||||||
|
|
||||||
Span<byte> data = MemoryMarshal.Cast<CounterData, byte>(counterDataSpan);
|
Span<byte> data = MemoryMarshal.Cast<CounterData, byte>(counterDataSpan);
|
||||||
|
|
||||||
ReportState state = _context.State.GetReportState();
|
var state = _context.State.Get<ReportState>(MethodOffset.ReportState);
|
||||||
|
|
||||||
_context.MemoryAccessor.Write(state.Address.Pack(), data);
|
_context.MemoryAccessor.Write(state.Address.Pack(), data);
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,27 +4,27 @@ namespace Ryujinx.Graphics.Gpu.Engine
|
||||||
{
|
{
|
||||||
partial class Methods
|
partial class Methods
|
||||||
{
|
{
|
||||||
private void UniformBufferBind0(int argument)
|
private void UniformBufferBindVertex(int argument)
|
||||||
{
|
{
|
||||||
UniformBufferBind(argument, ShaderType.Vertex);
|
UniformBufferBind(argument, ShaderType.Vertex);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void UniformBufferBind1(int argument)
|
private void UniformBufferBindTessControl(int argument)
|
||||||
{
|
{
|
||||||
UniformBufferBind(argument, ShaderType.TessellationControl);
|
UniformBufferBind(argument, ShaderType.TessellationControl);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void UniformBufferBind2(int argument)
|
private void UniformBufferBindTessEvaluation(int argument)
|
||||||
{
|
{
|
||||||
UniformBufferBind(argument, ShaderType.TessellationEvaluation);
|
UniformBufferBind(argument, ShaderType.TessellationEvaluation);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void UniformBufferBind3(int argument)
|
private void UniformBufferBindGeometry(int argument)
|
||||||
{
|
{
|
||||||
UniformBufferBind(argument, ShaderType.Geometry);
|
UniformBufferBind(argument, ShaderType.Geometry);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void UniformBufferBind4(int argument)
|
private void UniformBufferBindFragment(int argument)
|
||||||
{
|
{
|
||||||
UniformBufferBind(argument, ShaderType.Fragment);
|
UniformBufferBind(argument, ShaderType.Fragment);
|
||||||
}
|
}
|
||||||
|
@ -37,7 +37,7 @@ namespace Ryujinx.Graphics.Gpu.Engine
|
||||||
|
|
||||||
if (enable)
|
if (enable)
|
||||||
{
|
{
|
||||||
UniformBufferState uniformBuffer = _context.State.GetUniformBufferState();
|
var uniformBuffer = _context.State.Get<UniformBufferState>(MethodOffset.UniformBufferState);
|
||||||
|
|
||||||
ulong address = uniformBuffer.Address.Pack();
|
ulong address = uniformBuffer.Address.Pack();
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@ namespace Ryujinx.Graphics.Gpu.Engine
|
||||||
{
|
{
|
||||||
private void UniformBufferUpdate(int argument)
|
private void UniformBufferUpdate(int argument)
|
||||||
{
|
{
|
||||||
UniformBufferState uniformBuffer = _context.State.GetUniformBufferState();
|
var uniformBuffer = _context.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);
|
||||||
|
|
||||||
|
|
|
@ -18,6 +18,8 @@ namespace Ryujinx.Graphics.Gpu.Engine
|
||||||
|
|
||||||
private ShaderCache _shaderCache;
|
private ShaderCache _shaderCache;
|
||||||
|
|
||||||
|
private ShaderProgramInfo[] _currentProgramInfo;
|
||||||
|
|
||||||
private BufferManager _bufferManager;
|
private BufferManager _bufferManager;
|
||||||
private TextureManager _textureManager;
|
private TextureManager _textureManager;
|
||||||
|
|
||||||
|
@ -33,6 +35,8 @@ namespace Ryujinx.Graphics.Gpu.Engine
|
||||||
|
|
||||||
_shaderCache = new ShaderCache(_context);
|
_shaderCache = new ShaderCache(_context);
|
||||||
|
|
||||||
|
_currentProgramInfo = new ShaderProgramInfo[Constants.TotalShaderStages];
|
||||||
|
|
||||||
_bufferManager = new BufferManager(context);
|
_bufferManager = new BufferManager(context);
|
||||||
_textureManager = new TextureManager(context);
|
_textureManager = new TextureManager(context);
|
||||||
|
|
||||||
|
@ -41,128 +45,184 @@ namespace Ryujinx.Graphics.Gpu.Engine
|
||||||
|
|
||||||
private void RegisterCallbacks()
|
private void RegisterCallbacks()
|
||||||
{
|
{
|
||||||
_context.State.RegisterCopyBufferCallback(CopyBuffer);
|
_context.State.RegisterCallback(MethodOffset.LaunchDma, LaunchDma);
|
||||||
_context.State.RegisterCopyTextureCallback(CopyTexture);
|
_context.State.RegisterCallback(MethodOffset.LoadInlineData, LoadInlineData);
|
||||||
|
|
||||||
_context.State.RegisterDrawEndCallback(DrawEnd);
|
_context.State.RegisterCallback(MethodOffset.Dispatch, Dispatch);
|
||||||
|
|
||||||
_context.State.RegisterDrawBeginCallback(DrawBegin);
|
_context.State.RegisterCallback(MethodOffset.CopyBuffer, CopyBuffer);
|
||||||
|
_context.State.RegisterCallback(MethodOffset.CopyTexture, CopyTexture);
|
||||||
_context.State.RegisterSetIndexCountCallback(SetIndexCount);
|
|
||||||
|
|
||||||
_context.State.RegisterClearCallback(Clear);
|
|
||||||
|
|
||||||
_context.State.RegisterReportCallback(Report);
|
|
||||||
|
|
||||||
_context.State.RegisterUniformBufferUpdateCallback(UniformBufferUpdate);
|
|
||||||
|
|
||||||
_context.State.RegisterUniformBufferBind0Callback(UniformBufferBind0);
|
|
||||||
_context.State.RegisterUniformBufferBind1Callback(UniformBufferBind1);
|
|
||||||
_context.State.RegisterUniformBufferBind2Callback(UniformBufferBind2);
|
|
||||||
_context.State.RegisterUniformBufferBind3Callback(UniformBufferBind3);
|
|
||||||
_context.State.RegisterUniformBufferBind4Callback(UniformBufferBind4);
|
|
||||||
|
|
||||||
_context.State.RegisterCallback(MethodOffset.TextureBarrier, TextureBarrier);
|
_context.State.RegisterCallback(MethodOffset.TextureBarrier, TextureBarrier);
|
||||||
_context.State.RegisterCallback(MethodOffset.InvalidateTextures, InvalidateTextures);
|
_context.State.RegisterCallback(MethodOffset.InvalidateTextures, InvalidateTextures);
|
||||||
_context.State.RegisterCallback(MethodOffset.TextureBarrierTiled, TextureBarrierTiled);
|
_context.State.RegisterCallback(MethodOffset.TextureBarrierTiled, TextureBarrierTiled);
|
||||||
|
|
||||||
|
|
||||||
_context.State.RegisterCallback(MethodOffset.ResetCounter, ResetCounter);
|
_context.State.RegisterCallback(MethodOffset.ResetCounter, ResetCounter);
|
||||||
|
|
||||||
_context.State.RegisterCallback(MethodOffset.Inline2MemoryExecute, Execute);
|
_context.State.RegisterCallback(MethodOffset.DrawEnd, DrawEnd);
|
||||||
_context.State.RegisterCallback(MethodOffset.Inline2MemoryPushData, PushData);
|
_context.State.RegisterCallback(MethodOffset.DrawBegin, DrawBegin);
|
||||||
|
|
||||||
_context.State.RegisterCallback(MethodOffset.Dispatch, Dispatch);
|
_context.State.RegisterCallback(MethodOffset.IndexBufferCount, SetIndexBufferCount);
|
||||||
|
|
||||||
|
_context.State.RegisterCallback(MethodOffset.Clear, Clear);
|
||||||
|
|
||||||
|
_context.State.RegisterCallback(MethodOffset.Report, Report);
|
||||||
|
|
||||||
|
_context.State.RegisterCallback(MethodOffset.UniformBufferUpdateData, 16, UniformBufferUpdate);
|
||||||
|
|
||||||
|
_context.State.RegisterCallback(MethodOffset.UniformBufferBindVertex, UniformBufferBindVertex);
|
||||||
|
_context.State.RegisterCallback(MethodOffset.UniformBufferBindTessControl, UniformBufferBindTessControl);
|
||||||
|
_context.State.RegisterCallback(MethodOffset.UniformBufferBindTessEvaluation, UniformBufferBindTessEvaluation);
|
||||||
|
_context.State.RegisterCallback(MethodOffset.UniformBufferBindGeometry, UniformBufferBindGeometry);
|
||||||
|
_context.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()
|
||||||
{
|
{
|
||||||
if ((_context.State.StateWriteFlags & StateWriteFlags.Any) == 0)
|
|
||||||
{
|
|
||||||
CommitBindings();
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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.StateWriteFlags & StateWriteFlags.ShaderState) != 0)
|
if (_context.State.QueryModified(MethodOffset.ShaderBaseAddress, MethodOffset.ShaderState))
|
||||||
{
|
{
|
||||||
UpdateShaderState();
|
UpdateShaderState();
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((_context.State.StateWriteFlags & StateWriteFlags.RenderTargetGroup) != 0)
|
UpdateRenderTargetStateIfNeeded();
|
||||||
{
|
|
||||||
UpdateRenderTargetGroupState();
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((_context.State.StateWriteFlags & StateWriteFlags.DepthTestState) != 0)
|
if (_context.State.QueryModified(MethodOffset.DepthTestEnable,
|
||||||
|
MethodOffset.DepthWriteEnable,
|
||||||
|
MethodOffset.DepthTestFunc))
|
||||||
{
|
{
|
||||||
UpdateDepthTestState();
|
UpdateDepthTestState();
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((_context.State.StateWriteFlags & StateWriteFlags.ViewportTransform) != 0)
|
if (_context.State.QueryModified(MethodOffset.ViewportTransform, MethodOffset.ViewportExtents))
|
||||||
{
|
{
|
||||||
UpdateViewportTransform();
|
UpdateViewportTransform();
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((_context.State.StateWriteFlags & StateWriteFlags.DepthBiasState) != 0)
|
if (_context.State.QueryModified(MethodOffset.DepthBiasState,
|
||||||
|
MethodOffset.DepthBiasFactor,
|
||||||
|
MethodOffset.DepthBiasUnits,
|
||||||
|
MethodOffset.DepthBiasClamp))
|
||||||
{
|
{
|
||||||
UpdateDepthBiasState();
|
UpdateDepthBiasState();
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((_context.State.StateWriteFlags & StateWriteFlags.StencilTestState) != 0)
|
if (_context.State.QueryModified(MethodOffset.StencilBackMasks,
|
||||||
|
MethodOffset.StencilTestState,
|
||||||
|
MethodOffset.StencilBackTestState))
|
||||||
{
|
{
|
||||||
UpdateStencilTestState();
|
UpdateStencilTestState();
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((_context.State.StateWriteFlags & StateWriteFlags.SamplerPoolState) != 0)
|
// Pools.
|
||||||
|
if (_context.State.QueryModified(MethodOffset.SamplerPoolState))
|
||||||
{
|
{
|
||||||
UpdateSamplerPoolState();
|
UpdateSamplerPoolState();
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((_context.State.StateWriteFlags & StateWriteFlags.TexturePoolState) != 0)
|
if (_context.State.QueryModified(MethodOffset.TexturePoolState))
|
||||||
{
|
{
|
||||||
UpdateTexturePoolState();
|
UpdateTexturePoolState();
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((_context.State.StateWriteFlags & StateWriteFlags.InputAssemblerGroup) != 0)
|
// Input assembler state.
|
||||||
|
if (_context.State.QueryModified(MethodOffset.VertexAttribState))
|
||||||
{
|
{
|
||||||
UpdateInputAssemblerGroupState();
|
UpdateVertexAttribState();
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((_context.State.StateWriteFlags & StateWriteFlags.FaceState) != 0)
|
if (_context.State.QueryModified(MethodOffset.PrimitiveRestartState))
|
||||||
|
{
|
||||||
|
UpdatePrimitiveRestartState();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_context.State.QueryModified(MethodOffset.IndexBufferState))
|
||||||
|
{
|
||||||
|
UpdateIndexBufferState();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_context.State.QueryModified(MethodOffset.VertexBufferDrawState,
|
||||||
|
MethodOffset.VertexBufferInstanced,
|
||||||
|
MethodOffset.VertexBufferState,
|
||||||
|
MethodOffset.VertexBufferEndAddress))
|
||||||
|
{
|
||||||
|
UpdateVertexBufferState();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_context.State.QueryModified(MethodOffset.FaceState))
|
||||||
{
|
{
|
||||||
UpdateFaceState();
|
UpdateFaceState();
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((_context.State.StateWriteFlags & StateWriteFlags.RtColorMask) != 0)
|
if (_context.State.QueryModified(MethodOffset.RtColorMask))
|
||||||
{
|
{
|
||||||
UpdateRtColorMask();
|
UpdateRtColorMask();
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((_context.State.StateWriteFlags & StateWriteFlags.BlendState) != 0)
|
if (_context.State.QueryModified(MethodOffset.BlendEnable, MethodOffset.BlendState))
|
||||||
{
|
{
|
||||||
UpdateBlendState();
|
UpdateBlendState();
|
||||||
}
|
}
|
||||||
|
|
||||||
_context.State.StateWriteFlags &= ~StateWriteFlags.Any;
|
|
||||||
|
|
||||||
CommitBindings();
|
CommitBindings();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void CommitBindings()
|
private void CommitBindings()
|
||||||
{
|
{
|
||||||
|
UpdateStorageBuffers();
|
||||||
|
|
||||||
_bufferManager.CommitBindings();
|
_bufferManager.CommitBindings();
|
||||||
_textureManager.CommitGraphicsBindings();
|
_textureManager.CommitGraphicsBindings();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void UpdateRenderTargetGroupState()
|
private void UpdateStorageBuffers()
|
||||||
{
|
{
|
||||||
TextureMsaaMode msaaMode = _context.State.GetRtMsaaMode();
|
for (int stage = 0; stage < _currentProgramInfo.Length; stage++)
|
||||||
|
{
|
||||||
|
ShaderProgramInfo info = _currentProgramInfo[stage];
|
||||||
|
|
||||||
|
if (info == null)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int index = 0; index < info.SBuffers.Count; index++)
|
||||||
|
{
|
||||||
|
BufferDescriptor sb = info.SBuffers[index];
|
||||||
|
|
||||||
|
ulong sbDescAddress = _bufferManager.GetGraphicsUniformBufferAddress(stage, 0);
|
||||||
|
|
||||||
|
int sbDescOffset = 0x110 + stage * 0x100 + sb.Slot * 0x10;
|
||||||
|
|
||||||
|
sbDescAddress += (ulong)sbDescOffset;
|
||||||
|
|
||||||
|
Span<byte> sbDescriptorData = _context.PhysicalMemory.Read(sbDescAddress, 0x10);
|
||||||
|
|
||||||
|
SbDescriptor sbDescriptor = MemoryMarshal.Cast<byte, SbDescriptor>(sbDescriptorData)[0];
|
||||||
|
|
||||||
|
_bufferManager.SetGraphicsStorageBuffer(stage, sb.Slot, sbDescriptor.PackAddress(), (uint)sbDescriptor.Size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateRenderTargetStateIfNeeded()
|
||||||
|
{
|
||||||
|
if (_context.State.QueryModified(MethodOffset.RtColorState,
|
||||||
|
MethodOffset.RtDepthStencilState,
|
||||||
|
MethodOffset.RtDepthStencilSize,
|
||||||
|
MethodOffset.RtDepthStencilEnable))
|
||||||
|
{
|
||||||
|
UpdateRenderTargetState();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateRenderTargetState()
|
||||||
|
{
|
||||||
|
var msaaMode = _context.State.Get<TextureMsaaMode>(MethodOffset.RtMsaaMode);
|
||||||
|
|
||||||
int samplesInX = msaaMode.SamplesInX();
|
int samplesInX = msaaMode.SamplesInX();
|
||||||
int samplesInY = msaaMode.SamplesInY();
|
int samplesInY = msaaMode.SamplesInY();
|
||||||
|
@ -173,7 +233,7 @@ namespace Ryujinx.Graphics.Gpu.Engine
|
||||||
{
|
{
|
||||||
for (int index = 0; index < Constants.TotalRenderTargets; index++)
|
for (int index = 0; index < Constants.TotalRenderTargets; index++)
|
||||||
{
|
{
|
||||||
RtColorState colorState = _context.State.GetRtColorState(index);
|
var colorState = _context.State.Get<RtColorState>(MethodOffset.RtColorState, index);
|
||||||
|
|
||||||
if (!IsRtEnabled(colorState))
|
if (!IsRtEnabled(colorState))
|
||||||
{
|
{
|
||||||
|
@ -189,9 +249,12 @@ namespace Ryujinx.Graphics.Gpu.Engine
|
||||||
|
|
||||||
_textureManager.SetRenderTargetColor(index, color);
|
_textureManager.SetRenderTargetColor(index, color);
|
||||||
|
|
||||||
|
if (color != null)
|
||||||
|
{
|
||||||
color.Modified = true;
|
color.Modified = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_textureManager.SetRenderTargetColor3D(color3D);
|
_textureManager.SetRenderTargetColor3D(color3D);
|
||||||
|
@ -199,14 +262,14 @@ namespace Ryujinx.Graphics.Gpu.Engine
|
||||||
color3D.Modified = true;
|
color3D.Modified = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool dsEnable = _context.State.Get<bool>(MethodOffset.RtDepthStencilEnable);
|
bool dsEnable = _context.State.Get<Boolean32>(MethodOffset.RtDepthStencilEnable);
|
||||||
|
|
||||||
Image.Texture depthStencil = null;
|
Image.Texture depthStencil = null;
|
||||||
|
|
||||||
if (dsEnable)
|
if (dsEnable)
|
||||||
{
|
{
|
||||||
var dsState = _context.State.GetRtDepthStencilState();
|
var dsState = _context.State.Get<RtDepthStencilState>(MethodOffset.RtDepthStencilState);
|
||||||
var dsSize = _context.State.GetRtDepthStencilSize();
|
var dsSize = _context.State.Get<Size3D> (MethodOffset.RtDepthStencilSize);
|
||||||
|
|
||||||
depthStencil = _textureManager.FindOrCreateTexture(
|
depthStencil = _textureManager.FindOrCreateTexture(
|
||||||
dsState,
|
dsState,
|
||||||
|
@ -216,11 +279,16 @@ namespace Ryujinx.Graphics.Gpu.Engine
|
||||||
}
|
}
|
||||||
|
|
||||||
_textureManager.SetRenderTargetDepthStencil(depthStencil);
|
_textureManager.SetRenderTargetDepthStencil(depthStencil);
|
||||||
|
|
||||||
|
if (depthStencil != null)
|
||||||
|
{
|
||||||
|
depthStencil.Modified = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Image.Texture Get3DRenderTarget(int samplesInX, int samplesInY)
|
private Image.Texture Get3DRenderTarget(int samplesInX, int samplesInY)
|
||||||
{
|
{
|
||||||
RtColorState colorState0 = _context.State.GetRtColorState(0);
|
var colorState0 = _context.State.Get<RtColorState>(MethodOffset.RtColorState, 0);
|
||||||
|
|
||||||
if (!IsRtEnabled(colorState0) || !colorState0.MemoryLayout.UnpackIsTarget3D() || colorState0.Depth != 1)
|
if (!IsRtEnabled(colorState0) || !colorState0.MemoryLayout.UnpackIsTarget3D() || colorState0.Depth != 1)
|
||||||
{
|
{
|
||||||
|
@ -232,7 +300,7 @@ namespace Ryujinx.Graphics.Gpu.Engine
|
||||||
|
|
||||||
for (int index = 1; index < Constants.TotalRenderTargets; index++)
|
for (int index = 1; index < Constants.TotalRenderTargets; index++)
|
||||||
{
|
{
|
||||||
RtColorState colorState = _context.State.GetRtColorState(index);
|
var colorState = _context.State.Get<RtColorState>(MethodOffset.RtColorState, index);
|
||||||
|
|
||||||
if (!IsRtEnabled(colorState))
|
if (!IsRtEnabled(colorState))
|
||||||
{
|
{
|
||||||
|
@ -266,9 +334,9 @@ namespace Ryujinx.Graphics.Gpu.Engine
|
||||||
private void UpdateDepthTestState()
|
private void UpdateDepthTestState()
|
||||||
{
|
{
|
||||||
_context.Renderer.Pipeline.SetDepthTest(new DepthTestDescriptor(
|
_context.Renderer.Pipeline.SetDepthTest(new DepthTestDescriptor(
|
||||||
_context.State.GetDepthTestEnable().IsTrue(),
|
_context.State.Get<Boolean32>(MethodOffset.DepthTestEnable),
|
||||||
_context.State.GetDepthWriteEnable().IsTrue(),
|
_context.State.Get<Boolean32>(MethodOffset.DepthWriteEnable),
|
||||||
_context.State.GetDepthTestFunc()));
|
_context.State.Get<CompareOp>(MethodOffset.DepthTestFunc)));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void UpdateViewportTransform()
|
private void UpdateViewportTransform()
|
||||||
|
@ -277,8 +345,8 @@ namespace Ryujinx.Graphics.Gpu.Engine
|
||||||
|
|
||||||
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 * 8);
|
var transform = _context.State.Get<ViewportTransform>(MethodOffset.ViewportTransform, index);
|
||||||
var extents = _context.State.Get<ViewportExtents> (MethodOffset.ViewportExtents + index * 4);
|
var extents = _context.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);
|
||||||
|
@ -303,7 +371,7 @@ namespace Ryujinx.Graphics.Gpu.Engine
|
||||||
|
|
||||||
private void UpdateDepthBiasState()
|
private void UpdateDepthBiasState()
|
||||||
{
|
{
|
||||||
var polygonOffset = _context.State.Get<DepthBiasState>(MethodOffset.DepthBiasState);
|
var depthBias = _context.State.Get<DepthBiasState>(MethodOffset.DepthBiasState);
|
||||||
|
|
||||||
float factor = _context.State.Get<float>(MethodOffset.DepthBiasFactor);
|
float factor = _context.State.Get<float>(MethodOffset.DepthBiasFactor);
|
||||||
float units = _context.State.Get<float>(MethodOffset.DepthBiasUnits);
|
float units = _context.State.Get<float>(MethodOffset.DepthBiasUnits);
|
||||||
|
@ -311,18 +379,18 @@ namespace Ryujinx.Graphics.Gpu.Engine
|
||||||
|
|
||||||
PolygonModeMask enables = 0;
|
PolygonModeMask enables = 0;
|
||||||
|
|
||||||
enables = (polygonOffset.PointEnable.IsTrue() ? PolygonModeMask.Point : 0);
|
enables = (depthBias.PointEnable ? PolygonModeMask.Point : 0);
|
||||||
enables |= (polygonOffset.LineEnable.IsTrue() ? PolygonModeMask.Line : 0);
|
enables |= (depthBias.LineEnable ? PolygonModeMask.Line : 0);
|
||||||
enables |= (polygonOffset.FillEnable.IsTrue() ? PolygonModeMask.Fill : 0);
|
enables |= (depthBias.FillEnable ? PolygonModeMask.Fill : 0);
|
||||||
|
|
||||||
_context.Renderer.Pipeline.SetDepthBias(enables, factor, units, clamp);
|
_context.Renderer.Pipeline.SetDepthBias(enables, factor, units, clamp);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void UpdateStencilTestState()
|
private void UpdateStencilTestState()
|
||||||
{
|
{
|
||||||
StencilBackMasks backMasks = _context.State.GetStencilBackMasks();
|
var backMasks = _context.State.Get<StencilBackMasks> (MethodOffset.StencilBackMasks);
|
||||||
StencilTestState test = _context.State.GetStencilTestState();
|
var test = _context.State.Get<StencilTestState> (MethodOffset.StencilTestState);
|
||||||
StencilBackTestState backTest = _context.State.GetStencilBackTestState();
|
var backTest = _context.State.Get<StencilBackTestState>(MethodOffset.StencilBackTestState);
|
||||||
|
|
||||||
CompareOp backFunc;
|
CompareOp backFunc;
|
||||||
StencilOp backSFail;
|
StencilOp backSFail;
|
||||||
|
@ -332,7 +400,7 @@ namespace Ryujinx.Graphics.Gpu.Engine
|
||||||
int backFuncMask;
|
int backFuncMask;
|
||||||
int backMask;
|
int backMask;
|
||||||
|
|
||||||
if (backTest.TwoSided.IsTrue())
|
if (backTest.TwoSided)
|
||||||
{
|
{
|
||||||
backFunc = backTest.BackFunc;
|
backFunc = backTest.BackFunc;
|
||||||
backSFail = backTest.BackSFail;
|
backSFail = backTest.BackSFail;
|
||||||
|
@ -354,7 +422,7 @@ namespace Ryujinx.Graphics.Gpu.Engine
|
||||||
}
|
}
|
||||||
|
|
||||||
_context.Renderer.Pipeline.SetStencilTest(new StencilTestDescriptor(
|
_context.Renderer.Pipeline.SetStencilTest(new StencilTestDescriptor(
|
||||||
test.Enable.IsTrue(),
|
test.Enable,
|
||||||
test.FrontFunc,
|
test.FrontFunc,
|
||||||
test.FrontSFail,
|
test.FrontSFail,
|
||||||
test.FrontDpPass,
|
test.FrontDpPass,
|
||||||
|
@ -373,42 +441,18 @@ namespace Ryujinx.Graphics.Gpu.Engine
|
||||||
|
|
||||||
private void UpdateSamplerPoolState()
|
private void UpdateSamplerPoolState()
|
||||||
{
|
{
|
||||||
PoolState samplerPool = _context.State.GetSamplerPoolState();
|
var samplerPool = _context.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()
|
||||||
{
|
{
|
||||||
PoolState texturePool = _context.State.GetTexturePoolState();
|
var texturePool = _context.State.Get<PoolState>(MethodOffset.TexturePoolState);
|
||||||
|
|
||||||
_textureManager.SetGraphicsTexturePool(texturePool.Address.Pack(), texturePool.MaximumId);
|
_textureManager.SetGraphicsTexturePool(texturePool.Address.Pack(), texturePool.MaximumId);
|
||||||
|
|
||||||
_textureManager.SetGraphicsTextureBufferIndex(_context.State.GetTextureBufferIndex());
|
_textureManager.SetGraphicsTextureBufferIndex(_context.State.Get<int>(MethodOffset.TextureBufferIndex));
|
||||||
}
|
|
||||||
|
|
||||||
private void UpdateInputAssemblerGroupState()
|
|
||||||
{
|
|
||||||
// Must be updated before the vertex buffer.
|
|
||||||
if ((_context.State.StateWriteFlags & StateWriteFlags.VertexAttribState) != 0)
|
|
||||||
{
|
|
||||||
UpdateVertexAttribState();
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((_context.State.StateWriteFlags & StateWriteFlags.PrimitiveRestartState) != 0)
|
|
||||||
{
|
|
||||||
UpdatePrimitiveRestartState();
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((_context.State.StateWriteFlags & StateWriteFlags.IndexBufferState) != 0)
|
|
||||||
{
|
|
||||||
UpdateIndexBufferState();
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((_context.State.StateWriteFlags & StateWriteFlags.VertexBufferState) != 0)
|
|
||||||
{
|
|
||||||
UpdateVertexBufferState();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void UpdateVertexAttribState()
|
private void UpdateVertexAttribState()
|
||||||
|
@ -417,7 +461,7 @@ namespace Ryujinx.Graphics.Gpu.Engine
|
||||||
|
|
||||||
for (int index = 0; index < 16; index++)
|
for (int index = 0; index < 16; index++)
|
||||||
{
|
{
|
||||||
VertexAttribState vertexAttrib = _context.State.GetVertexAttribState(index);
|
var vertexAttrib = _context.State.Get<VertexAttribState>(MethodOffset.VertexAttribState, index);
|
||||||
|
|
||||||
if (!FormatTable.TryGetAttribFormat(vertexAttrib.UnpackFormat(), out Format format))
|
if (!FormatTable.TryGetAttribFormat(vertexAttrib.UnpackFormat(), out Format format))
|
||||||
{
|
{
|
||||||
|
@ -446,7 +490,7 @@ namespace Ryujinx.Graphics.Gpu.Engine
|
||||||
|
|
||||||
private void UpdateIndexBufferState()
|
private void UpdateIndexBufferState()
|
||||||
{
|
{
|
||||||
IndexBufferState indexBuffer = _context.State.GetIndexBufferState();
|
var indexBuffer = _context.State.Get<IndexBufferState>(MethodOffset.IndexBufferState);
|
||||||
|
|
||||||
_firstIndex = indexBuffer.First;
|
_firstIndex = indexBuffer.First;
|
||||||
_indexCount = indexBuffer.Count;
|
_indexCount = indexBuffer.Count;
|
||||||
|
@ -475,70 +519,13 @@ namespace Ryujinx.Graphics.Gpu.Engine
|
||||||
UpdateVertexBufferState();
|
UpdateVertexBufferState();
|
||||||
}
|
}
|
||||||
|
|
||||||
private uint GetIndexBufferMaxIndex(ulong gpuVa, ulong size, IndexType type)
|
|
||||||
{
|
|
||||||
ulong address = _context.MemoryManager.Translate(gpuVa);
|
|
||||||
|
|
||||||
Span<byte> data = _context.PhysicalMemory.Read(address, size);
|
|
||||||
|
|
||||||
uint maxIndex = 0;
|
|
||||||
|
|
||||||
switch (type)
|
|
||||||
{
|
|
||||||
case IndexType.UByte:
|
|
||||||
{
|
|
||||||
for (int index = 0; index < data.Length; index++)
|
|
||||||
{
|
|
||||||
if (maxIndex < data[index])
|
|
||||||
{
|
|
||||||
maxIndex = data[index];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case IndexType.UShort:
|
|
||||||
{
|
|
||||||
Span<ushort> indices = MemoryMarshal.Cast<byte, ushort>(data);
|
|
||||||
|
|
||||||
for (int index = 0; index < indices.Length; index++)
|
|
||||||
{
|
|
||||||
if (maxIndex < indices[index])
|
|
||||||
{
|
|
||||||
maxIndex = indices[index];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case IndexType.UInt:
|
|
||||||
{
|
|
||||||
Span<uint> indices = MemoryMarshal.Cast<byte, uint>(data);
|
|
||||||
|
|
||||||
for (int index = 0; index < indices.Length; index++)
|
|
||||||
{
|
|
||||||
if (maxIndex < indices[index])
|
|
||||||
{
|
|
||||||
maxIndex = indices[index];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return maxIndex;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void UpdateVertexBufferState()
|
private void UpdateVertexBufferState()
|
||||||
{
|
{
|
||||||
_isAnyVbInstanced = false;
|
_isAnyVbInstanced = false;
|
||||||
|
|
||||||
for (int index = 0; index < 16; index++)
|
for (int index = 0; index < 16; index++)
|
||||||
{
|
{
|
||||||
VertexBufferState vertexBuffer = _context.State.GetVertexBufferState(index);
|
var vertexBuffer = _context.State.Get<VertexBufferState>(MethodOffset.VertexBufferState, index);
|
||||||
|
|
||||||
if (!vertexBuffer.UnpackEnable())
|
if (!vertexBuffer.UnpackEnable())
|
||||||
{
|
{
|
||||||
|
@ -547,13 +534,13 @@ namespace Ryujinx.Graphics.Gpu.Engine
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
GpuVa endAddress = _context.State.GetVertexBufferEndAddress(index);
|
GpuVa endAddress = _context.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<bool>(MethodOffset.VertexBufferInstanced + index);
|
bool instanced = _context.State.Get<Boolean32>(MethodOffset.VertexBufferInstanced + index);
|
||||||
|
|
||||||
int divisor = instanced ? vertexBuffer.Divisor : 0;
|
int divisor = instanced ? vertexBuffer.Divisor : 0;
|
||||||
|
|
||||||
|
@ -571,9 +558,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.GetBaseInstance();
|
int firstInstance = _context.State.Get<int>(MethodOffset.FirstInstance);
|
||||||
|
|
||||||
VertexBufferDrawState drawState = _context.State.GetVertexBufferDrawState();
|
var drawState = _context.State.Get<VertexBufferDrawState>(MethodOffset.VertexBufferDrawState);
|
||||||
|
|
||||||
size = (ulong)((firstInstance + drawState.First + drawState.Count) * stride);
|
size = (ulong)((firstInstance + drawState.First + drawState.Count) * stride);
|
||||||
}
|
}
|
||||||
|
@ -584,9 +571,9 @@ namespace Ryujinx.Graphics.Gpu.Engine
|
||||||
|
|
||||||
private void UpdateFaceState()
|
private void UpdateFaceState()
|
||||||
{
|
{
|
||||||
FaceState face = _context.State.GetFaceState();
|
var face = _context.State.Get<FaceState>(MethodOffset.FaceState);
|
||||||
|
|
||||||
_context.Renderer.Pipeline.SetFaceCulling(face.CullEnable.IsTrue(), face.CullFace);
|
_context.Renderer.Pipeline.SetFaceCulling(face.CullEnable, face.CullFace);
|
||||||
|
|
||||||
_context.Renderer.Pipeline.SetFrontFace(face.FrontFace);
|
_context.Renderer.Pipeline.SetFrontFace(face.FrontFace);
|
||||||
}
|
}
|
||||||
|
@ -597,7 +584,7 @@ namespace Ryujinx.Graphics.Gpu.Engine
|
||||||
|
|
||||||
for (int index = 0; index < Constants.TotalRenderTargets; index++)
|
for (int index = 0; index < Constants.TotalRenderTargets; index++)
|
||||||
{
|
{
|
||||||
RtColorMask colorMask = _context.State.Get<RtColorMask>(MethodOffset.RtColorMask + index);
|
var colorMask = _context.State.Get<RtColorMask>(MethodOffset.RtColorMask, index);
|
||||||
|
|
||||||
uint componentMask = 0;
|
uint componentMask = 0;
|
||||||
|
|
||||||
|
@ -618,12 +605,12 @@ namespace Ryujinx.Graphics.Gpu.Engine
|
||||||
|
|
||||||
for (int index = 0; index < 8; index++)
|
for (int index = 0; index < 8; index++)
|
||||||
{
|
{
|
||||||
bool blendEnable = _context.State.GetBlendEnable(index).IsTrue();
|
bool enable = _context.State.Get<Boolean32>(MethodOffset.BlendEnable, index);
|
||||||
|
|
||||||
BlendState blend = _context.State.GetBlendState(index);
|
var blend = _context.State.Get<BlendState>(MethodOffset.BlendState, index);
|
||||||
|
|
||||||
BlendDescriptor descriptor = new BlendDescriptor(
|
BlendDescriptor descriptor = new BlendDescriptor(
|
||||||
blendEnable,
|
enable,
|
||||||
blend.ColorOp,
|
blend.ColorOp,
|
||||||
blend.ColorSrcFactor,
|
blend.ColorSrcFactor,
|
||||||
blend.ColorDstFactor,
|
blend.ColorDstFactor,
|
||||||
|
@ -656,11 +643,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.GetShaderBaseAddress().Pack();
|
ulong baseAddress = _context.State.Get<GpuVa>(MethodOffset.ShaderBaseAddress).Pack();
|
||||||
|
|
||||||
for (int index = 0; index < 6; index++)
|
for (int index = 0; index < 6; index++)
|
||||||
{
|
{
|
||||||
ShaderState shader = _context.State.GetShaderState(index);
|
var shader = _context.State.Get<ShaderState>(MethodOffset.ShaderState, index);
|
||||||
|
|
||||||
if (!shader.UnpackEnable() && index != 1)
|
if (!shader.UnpackEnable() && index != 1)
|
||||||
{
|
{
|
||||||
|
@ -678,6 +665,8 @@ namespace Ryujinx.Graphics.Gpu.Engine
|
||||||
{
|
{
|
||||||
ShaderProgramInfo info = gs.Shader[stage]?.Info;
|
ShaderProgramInfo info = gs.Shader[stage]?.Info;
|
||||||
|
|
||||||
|
_currentProgramInfo[stage] = info;
|
||||||
|
|
||||||
if (info == null)
|
if (info == null)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
|
@ -714,21 +703,7 @@ namespace Ryujinx.Graphics.Gpu.Engine
|
||||||
|
|
||||||
for (int index = 0; index < info.SBuffers.Count; index++)
|
for (int index = 0; index < info.SBuffers.Count; index++)
|
||||||
{
|
{
|
||||||
BufferDescriptor sb = info.SBuffers[index];
|
sbEnableMask |= 1u << info.SBuffers[index].Slot;
|
||||||
|
|
||||||
sbEnableMask |= 1u << sb.Slot;
|
|
||||||
|
|
||||||
ulong sbDescAddress = _bufferManager.GetGraphicsUniformBufferAddress(stage, 0);
|
|
||||||
|
|
||||||
int sbDescOffset = 0x110 + stage * 0x100 + sb.Slot * 0x10;
|
|
||||||
|
|
||||||
sbDescAddress += (ulong)sbDescOffset;
|
|
||||||
|
|
||||||
Span<byte> sbDescriptorData = _context.PhysicalMemory.Read(sbDescAddress, 0x10);
|
|
||||||
|
|
||||||
SbDescriptor sbDescriptor = MemoryMarshal.Cast<byte, SbDescriptor>(sbDescriptorData)[0];
|
|
||||||
|
|
||||||
_bufferManager.SetGraphicsStorageBuffer(stage, sb.Slot, sbDescriptor.PackAddress(), (uint)sbDescriptor.Size);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int index = 0; index < info.CBuffers.Count; index++)
|
for (int index = 0; index < info.CBuffers.Count; index++)
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
using Ryujinx.Graphics.Gpu.Memory;
|
||||||
using System;
|
using System;
|
||||||
|
|
||||||
namespace Ryujinx.Graphics.Gpu.Image
|
namespace Ryujinx.Graphics.Gpu.Image
|
||||||
|
@ -31,7 +32,7 @@ namespace Ryujinx.Graphics.Gpu.Image
|
||||||
|
|
||||||
public void SynchronizeMemory()
|
public void SynchronizeMemory()
|
||||||
{
|
{
|
||||||
(ulong, ulong)[] modifiedRanges = Context.PhysicalMemory.GetModifiedRanges(Address, Size);
|
(ulong, ulong)[] modifiedRanges = Context.PhysicalMemory.GetModifiedRanges(Address, Size, ResourceName.TexturePool);
|
||||||
|
|
||||||
for (int index = 0; index < modifiedRanges.Length; index++)
|
for (int index = 0; index < modifiedRanges.Length; index++)
|
||||||
{
|
{
|
||||||
|
|
|
@ -202,7 +202,7 @@ namespace Ryujinx.Graphics.Gpu.Image
|
||||||
|
|
||||||
_sequenceNumber = _context.SequenceNumber;
|
_sequenceNumber = _context.SequenceNumber;
|
||||||
|
|
||||||
bool modified = _context.PhysicalMemory.GetModifiedRanges(Address, Size).Length != 0;
|
bool modified = _context.PhysicalMemory.GetModifiedRanges(Address, Size, ResourceName.Texture).Length != 0;
|
||||||
|
|
||||||
if (!modified && _hasData)
|
if (!modified && _hasData)
|
||||||
{
|
{
|
||||||
|
|
|
@ -114,7 +114,7 @@ namespace Ryujinx.Graphics.Gpu.Image
|
||||||
|
|
||||||
public void CommitComputeBindings()
|
public void CommitComputeBindings()
|
||||||
{
|
{
|
||||||
// Evert time we switch between graphics and compute work,
|
// Every time we switch between graphics and compute work,
|
||||||
// we must rebind everything.
|
// we must rebind everything.
|
||||||
// Since compute work happens less often, we always do that
|
// Since compute work happens less often, we always do that
|
||||||
// before and after the compute dispatch.
|
// before and after the compute dispatch.
|
||||||
|
|
|
@ -69,7 +69,7 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
(ulong, ulong)[] modifiedRanges = _context.PhysicalMemory.GetModifiedRanges(address, size);
|
(ulong, ulong)[] modifiedRanges = _context.PhysicalMemory.GetModifiedRanges(address, size, ResourceName.Buffer);
|
||||||
|
|
||||||
for (int index = 0; index < modifiedRanges.Length; index++)
|
for (int index = 0; index < modifiedRanges.Length; index++)
|
||||||
{
|
{
|
||||||
|
|
|
@ -116,11 +116,15 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
||||||
|
|
||||||
ulong address = TranslateAndCreateBuffer(gpuVa, size);
|
ulong address = TranslateAndCreateBuffer(gpuVa, size);
|
||||||
|
|
||||||
_gpStorageBuffers[stage].Bind(index, address, size);
|
if (_gpStorageBuffers[stage].Buffers[index].Address != address ||
|
||||||
|
_gpStorageBuffers[stage].Buffers[index].Size != size)
|
||||||
|
{
|
||||||
_gpStorageBuffersDirty = true;
|
_gpStorageBuffersDirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_gpStorageBuffers[stage].Bind(index, address, size);
|
||||||
|
}
|
||||||
|
|
||||||
public void SetComputeUniformBuffer(int index, ulong gpuVa, ulong size)
|
public void SetComputeUniformBuffer(int index, ulong gpuVa, ulong size)
|
||||||
{
|
{
|
||||||
ulong address = TranslateAndCreateBuffer(gpuVa, size);
|
ulong address = TranslateAndCreateBuffer(gpuVa, size);
|
||||||
|
|
|
@ -10,6 +10,6 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
||||||
|
|
||||||
void Write(ulong address, Span<byte> data);
|
void Write(ulong address, Span<byte> data);
|
||||||
|
|
||||||
(ulong, ulong)[] GetModifiedRanges(ulong address, ulong size);
|
(ulong, ulong)[] GetModifiedRanges(ulong address, ulong size, ResourceName name);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -8,7 +8,7 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
||||||
|
|
||||||
private const int PtLvl0Bits = 14;
|
private const int PtLvl0Bits = 14;
|
||||||
private const int PtLvl1Bits = 14;
|
private const int PtLvl1Bits = 14;
|
||||||
private const int PtPageBits = 12;
|
public const int PtPageBits = 12;
|
||||||
|
|
||||||
private const ulong PtLvl0Size = 1UL << PtLvl0Bits;
|
private const ulong PtLvl0Size = 1UL << PtLvl0Bits;
|
||||||
private const ulong PtLvl1Size = 1UL << PtLvl1Bits;
|
private const ulong PtLvl1Size = 1UL << PtLvl1Bits;
|
||||||
|
|
10
Ryujinx.Graphics.Gpu/Memory/ResourceName.cs
Normal file
10
Ryujinx.Graphics.Gpu/Memory/ResourceName.cs
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
namespace Ryujinx.Graphics.Gpu.Memory
|
||||||
|
{
|
||||||
|
public enum ResourceName
|
||||||
|
{
|
||||||
|
Buffer,
|
||||||
|
Texture,
|
||||||
|
TexturePool,
|
||||||
|
SamplerPool
|
||||||
|
}
|
||||||
|
}
|
|
@ -4,12 +4,13 @@ namespace Ryujinx.Graphics.Gpu.State
|
||||||
{
|
{
|
||||||
struct BlendState
|
struct BlendState
|
||||||
{
|
{
|
||||||
public Bool SeparateAlpha;
|
public Boolean32 SeparateAlpha;
|
||||||
public BlendOp ColorOp;
|
public BlendOp ColorOp;
|
||||||
public BlendFactor ColorSrcFactor;
|
public BlendFactor ColorSrcFactor;
|
||||||
public BlendFactor ColorDstFactor;
|
public BlendFactor ColorDstFactor;
|
||||||
public BlendOp AlphaOp;
|
public BlendOp AlphaOp;
|
||||||
public BlendFactor AlphaSrcFactor;
|
public BlendFactor AlphaSrcFactor;
|
||||||
public BlendFactor AlphaDstFactor;
|
public BlendFactor AlphaDstFactor;
|
||||||
|
public uint Padding;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,17 +0,0 @@
|
||||||
namespace Ryujinx.Graphics.Gpu.State
|
|
||||||
{
|
|
||||||
struct Bool
|
|
||||||
{
|
|
||||||
private uint _value;
|
|
||||||
|
|
||||||
public bool IsTrue()
|
|
||||||
{
|
|
||||||
return (_value & 1) != 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool IsFalse()
|
|
||||||
{
|
|
||||||
return (_value & 1) == 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
12
Ryujinx.Graphics.Gpu/State/Boolean32.cs
Normal file
12
Ryujinx.Graphics.Gpu/State/Boolean32.cs
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
namespace Ryujinx.Graphics.Gpu.State
|
||||||
|
{
|
||||||
|
struct Boolean32
|
||||||
|
{
|
||||||
|
private uint _value;
|
||||||
|
|
||||||
|
public static implicit operator bool(Boolean32 value)
|
||||||
|
{
|
||||||
|
return (value._value & 1) != 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -3,7 +3,7 @@ namespace Ryujinx.Graphics.Gpu.State
|
||||||
struct CopyTexture
|
struct CopyTexture
|
||||||
{
|
{
|
||||||
public RtFormat Format;
|
public RtFormat Format;
|
||||||
public bool LinearLayout;
|
public Boolean32 LinearLayout;
|
||||||
public MemoryLayout MemoryLayout;
|
public MemoryLayout MemoryLayout;
|
||||||
public int Depth;
|
public int Depth;
|
||||||
public int Layer;
|
public int Layer;
|
||||||
|
|
|
@ -2,8 +2,8 @@ namespace Ryujinx.Graphics.Gpu.State
|
||||||
{
|
{
|
||||||
struct DepthBiasState
|
struct DepthBiasState
|
||||||
{
|
{
|
||||||
public Bool PointEnable;
|
public Boolean32 PointEnable;
|
||||||
public Bool LineEnable;
|
public Boolean32 LineEnable;
|
||||||
public Bool FillEnable;
|
public Boolean32 FillEnable;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@ namespace Ryujinx.Graphics.Gpu.State
|
||||||
{
|
{
|
||||||
struct FaceState
|
struct FaceState
|
||||||
{
|
{
|
||||||
public Bool CullEnable;
|
public Boolean32 CullEnable;
|
||||||
public FrontFace FrontFace;
|
public FrontFace FrontFace;
|
||||||
public Face CullFace;
|
public Face CullFace;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,4 @@
|
||||||
using Ryujinx.Graphics.GAL;
|
using System;
|
||||||
using Ryujinx.Graphics.Gpu.Image;
|
|
||||||
using System;
|
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
namespace Ryujinx.Graphics.Gpu.State
|
namespace Ryujinx.Graphics.Gpu.State
|
||||||
|
@ -17,39 +15,54 @@ namespace Ryujinx.Graphics.Gpu.State
|
||||||
{
|
{
|
||||||
public MethodCallback Callback;
|
public MethodCallback Callback;
|
||||||
|
|
||||||
public StateWriteFlags WriteFlag;
|
public MethodOffset BaseOffset;
|
||||||
|
|
||||||
|
public int Stride;
|
||||||
|
public int Count;
|
||||||
|
|
||||||
|
public bool Modified;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Register[] _registers;
|
private Register[] _registers;
|
||||||
|
|
||||||
public StateWriteFlags StateWriteFlags { get; set; }
|
|
||||||
|
|
||||||
public GpuState()
|
public GpuState()
|
||||||
{
|
{
|
||||||
_backingMemory = new int[RegistersCount];
|
_backingMemory = new int[RegistersCount];
|
||||||
|
|
||||||
_registers = new Register[RegistersCount];
|
_registers = new Register[RegistersCount];
|
||||||
|
|
||||||
StateWriteFlags = StateWriteFlags.Any;
|
for (int index = 0; index < _registers.Length; index++)
|
||||||
|
{
|
||||||
InitializeDefaultState();
|
_registers[index].BaseOffset = (MethodOffset)index;
|
||||||
InitializeStateWatchers();
|
_registers[index].Stride = 1;
|
||||||
|
_registers[index].Count = 1;
|
||||||
|
_registers[index].Modified = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool ExitEarly;
|
foreach (var item in GpuStateTable.Table)
|
||||||
|
{
|
||||||
|
int totalRegs = item.Size * item.Count;
|
||||||
|
|
||||||
|
for (int regOffset = 0; regOffset < totalRegs; regOffset++)
|
||||||
|
{
|
||||||
|
int index = (int)item.Offset + regOffset;
|
||||||
|
|
||||||
|
_registers[index].BaseOffset = item.Offset;
|
||||||
|
_registers[index].Stride = item.Size;
|
||||||
|
_registers[index].Count = item.Count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
InitializeDefaultState();
|
||||||
|
}
|
||||||
|
|
||||||
public void CallMethod(MethodParams meth)
|
public void CallMethod(MethodParams meth)
|
||||||
{
|
{
|
||||||
if (ExitEarly)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Register register = _registers[meth.Method];
|
Register register = _registers[meth.Method];
|
||||||
|
|
||||||
if (_backingMemory[meth.Method] != meth.Argument)
|
if (_backingMemory[meth.Method] != meth.Argument)
|
||||||
{
|
{
|
||||||
StateWriteFlags |= register.WriteFlag;
|
_registers[(int)register.BaseOffset].Modified = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
_backingMemory[meth.Method] = meth.Argument;
|
_backingMemory[meth.Method] = meth.Argument;
|
||||||
|
@ -67,264 +80,11 @@ namespace Ryujinx.Graphics.Gpu.State
|
||||||
return _backingMemory[offset];
|
return _backingMemory[offset];
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RegisterCopyBufferCallback(MethodCallback callback)
|
|
||||||
{
|
|
||||||
RegisterCallback(0xc0, callback);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void RegisterCopyTextureCallback(MethodCallback callback)
|
|
||||||
{
|
|
||||||
RegisterCallback(0x237, callback);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void RegisterDrawEndCallback(MethodCallback callback)
|
|
||||||
{
|
|
||||||
RegisterCallback(0x585, callback);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void RegisterDrawBeginCallback(MethodCallback callback)
|
|
||||||
{
|
|
||||||
RegisterCallback(0x586, callback);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void RegisterSetIndexCountCallback(MethodCallback callback)
|
|
||||||
{
|
|
||||||
RegisterCallback(0x5f8, callback);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void RegisterClearCallback(MethodCallback callback)
|
|
||||||
{
|
|
||||||
RegisterCallback(0x674, callback);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void RegisterReportCallback(MethodCallback callback)
|
|
||||||
{
|
|
||||||
RegisterCallback(0x6c3, callback);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void RegisterUniformBufferUpdateCallback(MethodCallback callback)
|
|
||||||
{
|
|
||||||
for (int index = 0; index < 16; index++)
|
|
||||||
{
|
|
||||||
RegisterCallback(0x8e4 + index, callback);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void RegisterUniformBufferBind0Callback(MethodCallback callback)
|
|
||||||
{
|
|
||||||
RegisterCallback(0x904, callback);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void RegisterUniformBufferBind1Callback(MethodCallback callback)
|
|
||||||
{
|
|
||||||
RegisterCallback(0x90c, callback);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void RegisterUniformBufferBind2Callback(MethodCallback callback)
|
|
||||||
{
|
|
||||||
RegisterCallback(0x914, callback);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void RegisterUniformBufferBind3Callback(MethodCallback callback)
|
|
||||||
{
|
|
||||||
RegisterCallback(0x91c, callback);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void RegisterUniformBufferBind4Callback(MethodCallback callback)
|
|
||||||
{
|
|
||||||
RegisterCallback(0x924, callback);
|
|
||||||
}
|
|
||||||
|
|
||||||
public CopyTexture GetCopyDstTexture()
|
|
||||||
{
|
|
||||||
return Get<CopyTexture>(MethodOffset.CopyDstTexture);
|
|
||||||
}
|
|
||||||
|
|
||||||
public CopyTexture GetCopySrcTexture()
|
|
||||||
{
|
|
||||||
return Get<CopyTexture>(MethodOffset.CopySrcTexture);
|
|
||||||
}
|
|
||||||
|
|
||||||
public RtColorState GetRtColorState(int index)
|
|
||||||
{
|
|
||||||
return Get<RtColorState>(MethodOffset.RtColorState + 16 * index);
|
|
||||||
}
|
|
||||||
|
|
||||||
public CopyTextureControl GetCopyTextureControl()
|
|
||||||
{
|
|
||||||
return Get<CopyTextureControl>(MethodOffset.CopyTextureControl);
|
|
||||||
}
|
|
||||||
|
|
||||||
public CopyRegion GetCopyRegion()
|
|
||||||
{
|
|
||||||
return Get<CopyRegion>(MethodOffset.CopyRegion);
|
|
||||||
}
|
|
||||||
|
|
||||||
public ViewportTransform GetViewportTransform(int index)
|
|
||||||
{
|
|
||||||
return Get<ViewportTransform>(MethodOffset.ViewportTransform + 8 * index);
|
|
||||||
}
|
|
||||||
|
|
||||||
public ViewportExtents GetViewportExtents(int index)
|
|
||||||
{
|
|
||||||
return Get<ViewportExtents>(MethodOffset.ViewportExtents + 4 * index);
|
|
||||||
}
|
|
||||||
|
|
||||||
public VertexBufferDrawState GetVertexBufferDrawState()
|
|
||||||
{
|
|
||||||
return Get<VertexBufferDrawState>(MethodOffset.VertexBufferDrawState);
|
|
||||||
}
|
|
||||||
|
|
||||||
public ClearColors GetClearColors()
|
|
||||||
{
|
|
||||||
return Get<ClearColors>(MethodOffset.ClearColors);
|
|
||||||
}
|
|
||||||
|
|
||||||
public float GetClearDepthValue()
|
|
||||||
{
|
|
||||||
return Get<float>(MethodOffset.ClearDepthValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
public int GetClearStencilValue()
|
|
||||||
{
|
|
||||||
return _backingMemory[(int)MethodOffset.ClearStencilValue];
|
|
||||||
}
|
|
||||||
|
|
||||||
public StencilBackMasks GetStencilBackMasks()
|
|
||||||
{
|
|
||||||
return Get<StencilBackMasks>(MethodOffset.StencilBackMasks);
|
|
||||||
}
|
|
||||||
|
|
||||||
public RtDepthStencilState GetRtDepthStencilState()
|
|
||||||
{
|
|
||||||
return Get<RtDepthStencilState>(MethodOffset.RtDepthStencilState);
|
|
||||||
}
|
|
||||||
|
|
||||||
public VertexAttribState GetVertexAttribState(int index)
|
|
||||||
{
|
|
||||||
return Get<VertexAttribState>(MethodOffset.VertexAttribState + index);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Size3D GetRtDepthStencilSize()
|
|
||||||
{
|
|
||||||
return Get<Size3D>(MethodOffset.RtDepthStencilSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Bool GetDepthTestEnable()
|
|
||||||
{
|
|
||||||
return Get<Bool>(MethodOffset.DepthTestEnable);
|
|
||||||
}
|
|
||||||
|
|
||||||
public CompareOp GetDepthTestFunc()
|
|
||||||
{
|
|
||||||
return Get<CompareOp>(MethodOffset.DepthTestFunc);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Bool GetDepthWriteEnable()
|
|
||||||
{
|
|
||||||
return Get<Bool>(MethodOffset.DepthWriteEnable);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Bool GetBlendEnable(int index)
|
|
||||||
{
|
|
||||||
return Get<Bool>(MethodOffset.BlendEnable + index);
|
|
||||||
}
|
|
||||||
|
|
||||||
public StencilTestState GetStencilTestState()
|
|
||||||
{
|
|
||||||
return Get<StencilTestState>(MethodOffset.StencilTestState);
|
|
||||||
}
|
|
||||||
|
|
||||||
public int GetBaseVertex()
|
|
||||||
{
|
|
||||||
return _backingMemory[(int)MethodOffset.FirstVertex];
|
|
||||||
}
|
|
||||||
|
|
||||||
public int GetBaseInstance()
|
|
||||||
{
|
|
||||||
return _backingMemory[(int)MethodOffset.FirstInstance];
|
|
||||||
}
|
|
||||||
|
|
||||||
public PoolState GetSamplerPoolState()
|
|
||||||
{
|
|
||||||
return Get<PoolState>(MethodOffset.SamplerPoolState);
|
|
||||||
}
|
|
||||||
|
|
||||||
public PoolState GetTexturePoolState()
|
|
||||||
{
|
|
||||||
return Get<PoolState>(MethodOffset.TexturePoolState);
|
|
||||||
}
|
|
||||||
|
|
||||||
public StencilBackTestState GetStencilBackTestState()
|
|
||||||
{
|
|
||||||
return Get<StencilBackTestState>(MethodOffset.StencilBackTestState);
|
|
||||||
}
|
|
||||||
|
|
||||||
public TextureMsaaMode GetRtMsaaMode()
|
|
||||||
{
|
|
||||||
return Get<TextureMsaaMode>(MethodOffset.RtMsaaMode);
|
|
||||||
}
|
|
||||||
|
|
||||||
public GpuVa GetShaderBaseAddress()
|
|
||||||
{
|
|
||||||
return Get<GpuVa>(MethodOffset.ShaderBaseAddress);
|
|
||||||
}
|
|
||||||
|
|
||||||
public PrimitiveRestartState GetPrimitiveRestartState()
|
|
||||||
{
|
|
||||||
return Get<PrimitiveRestartState>(MethodOffset.PrimitiveRestartState);
|
|
||||||
}
|
|
||||||
|
|
||||||
public IndexBufferState GetIndexBufferState()
|
|
||||||
{
|
|
||||||
return Get<IndexBufferState>(MethodOffset.IndexBufferState);
|
|
||||||
}
|
|
||||||
|
|
||||||
public FaceState GetFaceState()
|
|
||||||
{
|
|
||||||
return Get<FaceState>(MethodOffset.FaceState);
|
|
||||||
}
|
|
||||||
|
|
||||||
public ReportState GetReportState()
|
|
||||||
{
|
|
||||||
return Get<ReportState>(MethodOffset.ReportState);
|
|
||||||
}
|
|
||||||
|
|
||||||
public VertexBufferState GetVertexBufferState(int index)
|
|
||||||
{
|
|
||||||
return Get<VertexBufferState>(MethodOffset.VertexBufferState + 4 * index);
|
|
||||||
}
|
|
||||||
|
|
||||||
public BlendState GetBlendState(int index)
|
|
||||||
{
|
|
||||||
return Get<BlendState>(MethodOffset.BlendState + 8 * index);
|
|
||||||
}
|
|
||||||
|
|
||||||
public GpuVa GetVertexBufferEndAddress(int index)
|
|
||||||
{
|
|
||||||
return Get<GpuVa>(MethodOffset.VertexBufferEndAddress + 2 * index);
|
|
||||||
}
|
|
||||||
|
|
||||||
public ShaderState GetShaderState(int index)
|
|
||||||
{
|
|
||||||
return Get<ShaderState>(MethodOffset.ShaderState + 16 * index);
|
|
||||||
}
|
|
||||||
|
|
||||||
public UniformBufferState GetUniformBufferState()
|
|
||||||
{
|
|
||||||
return Get<UniformBufferState>(MethodOffset.UniformBufferState);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SetUniformBufferOffset(int offset)
|
public void SetUniformBufferOffset(int offset)
|
||||||
{
|
{
|
||||||
_backingMemory[(int)MethodOffset.UniformBufferState + 3] = offset;
|
_backingMemory[(int)MethodOffset.UniformBufferState + 3] = offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int GetTextureBufferIndex()
|
|
||||||
{
|
|
||||||
return _backingMemory[(int)MethodOffset.TextureBufferIndex];
|
|
||||||
}
|
|
||||||
|
|
||||||
private void InitializeDefaultState()
|
private void InitializeDefaultState()
|
||||||
{
|
{
|
||||||
// Depth ranges.
|
// Depth ranges.
|
||||||
|
@ -341,69 +101,11 @@ namespace Ryujinx.Graphics.Gpu.State
|
||||||
_backingMemory[(int)MethodOffset.RtColorMask] = 0x1111;
|
_backingMemory[(int)MethodOffset.RtColorMask] = 0x1111;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void InitializeStateWatchers()
|
public void RegisterCallback(MethodOffset offset, int count, MethodCallback callback)
|
||||||
{
|
{
|
||||||
SetWriteStateFlag(MethodOffset.RtColorState, StateWriteFlags.RtColorState, 16 * 8);
|
for (int index = 0; index < count; index++)
|
||||||
|
|
||||||
SetWriteStateFlag(MethodOffset.ViewportTransform, StateWriteFlags.ViewportTransform, 8 * 8);
|
|
||||||
SetWriteStateFlag(MethodOffset.ViewportExtents, StateWriteFlags.ViewportTransform, 4 * 8);
|
|
||||||
|
|
||||||
SetWriteStateFlag<VertexBufferDrawState>(MethodOffset.VertexBufferDrawState, StateWriteFlags.VertexBufferState);
|
|
||||||
|
|
||||||
SetWriteStateFlag<DepthBiasState>(MethodOffset.DepthBiasState, StateWriteFlags.DepthBiasState);
|
|
||||||
|
|
||||||
SetWriteStateFlag(MethodOffset.DepthBiasFactor, StateWriteFlags.DepthBiasState, 1);
|
|
||||||
SetWriteStateFlag(MethodOffset.DepthBiasUnits, StateWriteFlags.DepthBiasState, 1);
|
|
||||||
SetWriteStateFlag(MethodOffset.DepthBiasClamp, StateWriteFlags.DepthBiasState, 1);
|
|
||||||
|
|
||||||
SetWriteStateFlag<RtDepthStencilState>(MethodOffset.RtDepthStencilState, StateWriteFlags.RtDepthStencilState);
|
|
||||||
SetWriteStateFlag<Size3D> (MethodOffset.RtDepthStencilSize, StateWriteFlags.RtDepthStencilState);
|
|
||||||
|
|
||||||
SetWriteStateFlag(MethodOffset.DepthTestEnable, StateWriteFlags.DepthTestState, 1);
|
|
||||||
SetWriteStateFlag(MethodOffset.DepthWriteEnable, StateWriteFlags.DepthTestState, 1);
|
|
||||||
SetWriteStateFlag(MethodOffset.DepthTestFunc, StateWriteFlags.DepthTestState, 1);
|
|
||||||
|
|
||||||
SetWriteStateFlag(MethodOffset.VertexAttribState, StateWriteFlags.VertexAttribState, 16);
|
|
||||||
|
|
||||||
SetWriteStateFlag<StencilBackMasks> (MethodOffset.StencilBackMasks, StateWriteFlags.StencilTestState);
|
|
||||||
SetWriteStateFlag<StencilTestState> (MethodOffset.StencilTestState, StateWriteFlags.StencilTestState);
|
|
||||||
SetWriteStateFlag<StencilBackTestState>(MethodOffset.StencilBackTestState, StateWriteFlags.StencilTestState);
|
|
||||||
|
|
||||||
SetWriteStateFlag<PoolState>(MethodOffset.SamplerPoolState, StateWriteFlags.SamplerPoolState);
|
|
||||||
SetWriteStateFlag<PoolState>(MethodOffset.TexturePoolState, StateWriteFlags.TexturePoolState);
|
|
||||||
|
|
||||||
SetWriteStateFlag<ShaderState>(MethodOffset.ShaderBaseAddress, StateWriteFlags.ShaderState);
|
|
||||||
|
|
||||||
SetWriteStateFlag<PrimitiveRestartState>(MethodOffset.PrimitiveRestartState, StateWriteFlags.PrimitiveRestartState);
|
|
||||||
|
|
||||||
SetWriteStateFlag<IndexBufferState>(MethodOffset.IndexBufferState, StateWriteFlags.IndexBufferState);
|
|
||||||
|
|
||||||
SetWriteStateFlag<FaceState>(MethodOffset.FaceState, StateWriteFlags.FaceState);
|
|
||||||
|
|
||||||
SetWriteStateFlag<RtColorMask>(MethodOffset.RtColorMask, StateWriteFlags.RtColorMask);
|
|
||||||
|
|
||||||
SetWriteStateFlag(MethodOffset.VertexBufferInstanced, StateWriteFlags.VertexBufferState, 16);
|
|
||||||
SetWriteStateFlag(MethodOffset.VertexBufferState, StateWriteFlags.VertexBufferState, 4 * 16);
|
|
||||||
SetWriteStateFlag(MethodOffset.VertexBufferEndAddress, StateWriteFlags.VertexBufferState, 2 * 16);
|
|
||||||
|
|
||||||
SetWriteStateFlag(MethodOffset.BlendEnable, StateWriteFlags.BlendState, 8);
|
|
||||||
SetWriteStateFlag(MethodOffset.BlendState, StateWriteFlags.BlendState, 8 * 8);
|
|
||||||
|
|
||||||
SetWriteStateFlag(MethodOffset.ShaderState, StateWriteFlags.ShaderState, 16 * 6);
|
|
||||||
|
|
||||||
SetWriteStateFlag(MethodOffset.TextureBufferIndex, StateWriteFlags.TexturePoolState, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void SetWriteStateFlag<T>(MethodOffset offset, StateWriteFlags flag)
|
|
||||||
{
|
{
|
||||||
SetWriteStateFlag(offset, flag, Marshal.SizeOf<T>());
|
_registers[(int)offset + index].Callback = callback;
|
||||||
}
|
|
||||||
|
|
||||||
private void SetWriteStateFlag(MethodOffset offset, StateWriteFlags flag, int size)
|
|
||||||
{
|
|
||||||
for (int index = 0; index < size; index++)
|
|
||||||
{
|
|
||||||
_registers[(int)offset + index].WriteFlag = flag;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -412,9 +114,37 @@ namespace Ryujinx.Graphics.Gpu.State
|
||||||
_registers[(int)offset].Callback = callback;
|
_registers[(int)offset].Callback = callback;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void RegisterCallback(int offset, MethodCallback callback)
|
public bool QueryModified(params MethodOffset[] offsets)
|
||||||
{
|
{
|
||||||
_registers[offset].Callback = callback;
|
bool modified = false;
|
||||||
|
|
||||||
|
for (int index = 0; index < offsets.Length; index++)
|
||||||
|
{
|
||||||
|
modified |= QueryModified(offsets[index]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return modified;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool QueryModified(MethodOffset offset)
|
||||||
|
{
|
||||||
|
bool modified = _registers[(int)offset].Modified;
|
||||||
|
|
||||||
|
_registers[(int)offset].Modified = false;
|
||||||
|
|
||||||
|
return modified;
|
||||||
|
}
|
||||||
|
|
||||||
|
public T Get<T>(MethodOffset offset, int index) where T : struct
|
||||||
|
{
|
||||||
|
Register register = _registers[(int)offset];
|
||||||
|
|
||||||
|
if ((uint)index >= register.Count)
|
||||||
|
{
|
||||||
|
throw new ArgumentOutOfRangeException(nameof(index));
|
||||||
|
}
|
||||||
|
|
||||||
|
return Get<T>(offset + index * register.Stride);
|
||||||
}
|
}
|
||||||
|
|
||||||
public T Get<T>(MethodOffset offset) where T : struct
|
public T Get<T>(MethodOffset offset) where T : struct
|
||||||
|
|
56
Ryujinx.Graphics.Gpu/State/GpuStateTable.cs
Normal file
56
Ryujinx.Graphics.Gpu/State/GpuStateTable.cs
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
using System;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
|
namespace Ryujinx.Graphics.Gpu.State
|
||||||
|
{
|
||||||
|
static class GpuStateTable
|
||||||
|
{
|
||||||
|
public struct TableItem
|
||||||
|
{
|
||||||
|
public MethodOffset Offset { get; }
|
||||||
|
|
||||||
|
public int Size { get; }
|
||||||
|
public int Count { get; }
|
||||||
|
|
||||||
|
public TableItem(MethodOffset offset, Type type, int count)
|
||||||
|
{
|
||||||
|
int sizeInBytes = Marshal.SizeOf(type);
|
||||||
|
|
||||||
|
Debug.Assert((sizeInBytes & 3) == 0);
|
||||||
|
|
||||||
|
Offset = offset;
|
||||||
|
Size = sizeInBytes / 4;
|
||||||
|
Count = count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static TableItem[] Table = new TableItem[]
|
||||||
|
{
|
||||||
|
new TableItem(MethodOffset.RtColorState, typeof(RtColorState), 8),
|
||||||
|
new TableItem(MethodOffset.ViewportTransform, typeof(ViewportTransform), 8),
|
||||||
|
new TableItem(MethodOffset.ViewportExtents, typeof(ViewportExtents), 8),
|
||||||
|
new TableItem(MethodOffset.VertexBufferDrawState, typeof(VertexBufferDrawState), 1),
|
||||||
|
new TableItem(MethodOffset.DepthBiasState, typeof(DepthBiasState), 1),
|
||||||
|
new TableItem(MethodOffset.StencilBackMasks, typeof(StencilBackMasks), 1),
|
||||||
|
new TableItem(MethodOffset.RtDepthStencilState, typeof(RtDepthStencilState), 1),
|
||||||
|
new TableItem(MethodOffset.VertexAttribState, typeof(VertexAttribState), 16),
|
||||||
|
new TableItem(MethodOffset.RtDepthStencilSize, typeof(Size3D), 1),
|
||||||
|
new TableItem(MethodOffset.BlendEnable, typeof(Boolean32), 8),
|
||||||
|
new TableItem(MethodOffset.StencilTestState, typeof(StencilTestState), 1),
|
||||||
|
new TableItem(MethodOffset.SamplerPoolState, typeof(PoolState), 1),
|
||||||
|
new TableItem(MethodOffset.TexturePoolState, typeof(PoolState), 1),
|
||||||
|
new TableItem(MethodOffset.StencilBackTestState, typeof(StencilBackTestState), 1),
|
||||||
|
new TableItem(MethodOffset.ShaderBaseAddress, typeof(GpuVa), 1),
|
||||||
|
new TableItem(MethodOffset.PrimitiveRestartState, typeof(PrimitiveRestartState), 1),
|
||||||
|
new TableItem(MethodOffset.IndexBufferState, typeof(IndexBufferState), 1),
|
||||||
|
new TableItem(MethodOffset.VertexBufferInstanced, typeof(Boolean32), 16),
|
||||||
|
new TableItem(MethodOffset.FaceState, typeof(FaceState), 1),
|
||||||
|
new TableItem(MethodOffset.RtColorMask, typeof(RtColorMask), 8),
|
||||||
|
new TableItem(MethodOffset.VertexBufferState, typeof(VertexBufferState), 16),
|
||||||
|
new TableItem(MethodOffset.BlendState, typeof(BlendState), 8),
|
||||||
|
new TableItem(MethodOffset.VertexBufferEndAddress, typeof(GpuVa), 16),
|
||||||
|
new TableItem(MethodOffset.ShaderState, typeof(ShaderState), 6),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
|
@ -9,10 +9,5 @@ namespace Ryujinx.Graphics.Gpu.State
|
||||||
{
|
{
|
||||||
return Low | ((ulong)High << 32);
|
return Low | ((ulong)High << 32);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool IsNullPtr()
|
|
||||||
{
|
|
||||||
return (Low | High) == 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,13 +2,14 @@ namespace Ryujinx.Graphics.Gpu.State
|
||||||
{
|
{
|
||||||
enum MethodOffset
|
enum MethodOffset
|
||||||
{
|
{
|
||||||
Inline2MemoryParams = 0x60,
|
I2mParams = 0x60,
|
||||||
Inline2MemoryExecute = 0x6c,
|
LaunchDma = 0x6c,
|
||||||
Inline2MemoryPushData = 0x6d,
|
LoadInlineData = 0x6d,
|
||||||
CopyDstTexture = 0x80,
|
CopyDstTexture = 0x80,
|
||||||
CopySrcTexture = 0x8c,
|
CopySrcTexture = 0x8c,
|
||||||
DispatchParamsAddress = 0xad,
|
DispatchParamsAddress = 0xad,
|
||||||
Dispatch = 0xaf,
|
Dispatch = 0xaf,
|
||||||
|
CopyBuffer = 0xc0,
|
||||||
CopyBufferParams = 0x100,
|
CopyBufferParams = 0x100,
|
||||||
CopyBufferSwizzle = 0x1c2,
|
CopyBufferSwizzle = 0x1c2,
|
||||||
CopyBufferDstTexture = 0x1c3,
|
CopyBufferDstTexture = 0x1c3,
|
||||||
|
@ -16,6 +17,7 @@ namespace Ryujinx.Graphics.Gpu.State
|
||||||
RtColorState = 0x200,
|
RtColorState = 0x200,
|
||||||
CopyTextureControl = 0x223,
|
CopyTextureControl = 0x223,
|
||||||
CopyRegion = 0x22c,
|
CopyRegion = 0x22c,
|
||||||
|
CopyTexture = 0x237,
|
||||||
ViewportTransform = 0x280,
|
ViewportTransform = 0x280,
|
||||||
ViewportExtents = 0x300,
|
ViewportExtents = 0x300,
|
||||||
VertexBufferDrawState = 0x35d,
|
VertexBufferDrawState = 0x35d,
|
||||||
|
@ -47,18 +49,29 @@ namespace Ryujinx.Graphics.Gpu.State
|
||||||
DepthBiasUnits = 0x56f,
|
DepthBiasUnits = 0x56f,
|
||||||
RtMsaaMode = 0x574,
|
RtMsaaMode = 0x574,
|
||||||
ShaderBaseAddress = 0x582,
|
ShaderBaseAddress = 0x582,
|
||||||
|
DrawEnd = 0x585,
|
||||||
|
DrawBegin = 0x586,
|
||||||
PrimitiveRestartState = 0x591,
|
PrimitiveRestartState = 0x591,
|
||||||
IndexBufferState = 0x5f2,
|
IndexBufferState = 0x5f2,
|
||||||
|
IndexBufferCount = 0x5f8,
|
||||||
DepthBiasClamp = 0x61f,
|
DepthBiasClamp = 0x61f,
|
||||||
VertexBufferInstanced = 0x620,
|
VertexBufferInstanced = 0x620,
|
||||||
FaceState = 0x646,
|
FaceState = 0x646,
|
||||||
|
Clear = 0x674,
|
||||||
RtColorMask = 0x680,
|
RtColorMask = 0x680,
|
||||||
ReportState = 0x6c0,
|
ReportState = 0x6c0,
|
||||||
|
Report = 0x6c3,
|
||||||
VertexBufferState = 0x700,
|
VertexBufferState = 0x700,
|
||||||
BlendState = 0x780,
|
BlendState = 0x780,
|
||||||
VertexBufferEndAddress = 0x7c0,
|
VertexBufferEndAddress = 0x7c0,
|
||||||
ShaderState = 0x800,
|
ShaderState = 0x800,
|
||||||
UniformBufferState = 0x8e0,
|
UniformBufferState = 0x8e0,
|
||||||
|
UniformBufferUpdateData = 0x8e4,
|
||||||
|
UniformBufferBindVertex = 0x904,
|
||||||
|
UniformBufferBindTessControl = 0x90c,
|
||||||
|
UniformBufferBindTessEvaluation = 0x914,
|
||||||
|
UniformBufferBindGeometry = 0x91c,
|
||||||
|
UniformBufferBindFragment = 0x924,
|
||||||
TextureBufferIndex = 0x982
|
TextureBufferIndex = 0x982
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -2,7 +2,7 @@ namespace Ryujinx.Graphics.Gpu.State
|
||||||
{
|
{
|
||||||
struct PrimitiveRestartState
|
struct PrimitiveRestartState
|
||||||
{
|
{
|
||||||
public bool Enable;
|
public Boolean32 Enable;
|
||||||
public int Index;
|
public int Index;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,5 +9,13 @@ namespace Ryujinx.Graphics.Gpu.State
|
||||||
public MemoryLayout MemoryLayout;
|
public MemoryLayout MemoryLayout;
|
||||||
public int Depth;
|
public int Depth;
|
||||||
public int LayerSize;
|
public int LayerSize;
|
||||||
|
public int BaseLayer;
|
||||||
|
public int Unknown0x24;
|
||||||
|
public int Padding0;
|
||||||
|
public int Padding1;
|
||||||
|
public int Padding2;
|
||||||
|
public int Padding3;
|
||||||
|
public int Padding4;
|
||||||
|
public int Padding5;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,8 @@ namespace Ryujinx.Graphics.Gpu.State
|
||||||
D32Float = 0xa,
|
D32Float = 0xa,
|
||||||
D16Unorm = 0x13,
|
D16Unorm = 0x13,
|
||||||
D24UnormS8Uint = 0x14,
|
D24UnormS8Uint = 0x14,
|
||||||
|
D24Unorm = 0x15,
|
||||||
|
S8UintD24Unorm = 0x16,
|
||||||
S8Uint = 0x17,
|
S8Uint = 0x17,
|
||||||
D32FloatS8Uint = 0x19,
|
D32FloatS8Uint = 0x19,
|
||||||
R32G32B32A32Float = 0xc0,
|
R32G32B32A32Float = 0xc0,
|
||||||
|
@ -74,6 +76,8 @@ namespace Ryujinx.Graphics.Gpu.State
|
||||||
case RtFormat.D32Float: return new FormatInfo(Format.D32Float, 1, 1, 4);
|
case RtFormat.D32Float: return new FormatInfo(Format.D32Float, 1, 1, 4);
|
||||||
case RtFormat.D16Unorm: return new FormatInfo(Format.D16Unorm, 1, 1, 2);
|
case RtFormat.D16Unorm: return new FormatInfo(Format.D16Unorm, 1, 1, 2);
|
||||||
case RtFormat.D24UnormS8Uint: return new FormatInfo(Format.D24UnormS8Uint, 1, 1, 4);
|
case RtFormat.D24UnormS8Uint: return new FormatInfo(Format.D24UnormS8Uint, 1, 1, 4);
|
||||||
|
case RtFormat.D24Unorm: return new FormatInfo(Format.D24UnormS8Uint, 1, 1, 4);
|
||||||
|
case RtFormat.S8UintD24Unorm: return new FormatInfo(Format.D24UnormS8Uint, 1, 1, 4);
|
||||||
case RtFormat.S8Uint: return new FormatInfo(Format.S8Uint, 1, 1, 1);
|
case RtFormat.S8Uint: return new FormatInfo(Format.S8Uint, 1, 1, 1);
|
||||||
case RtFormat.D32FloatS8Uint: return new FormatInfo(Format.D32FloatS8Uint, 1, 1, 8);
|
case RtFormat.D32FloatS8Uint: return new FormatInfo(Format.D32FloatS8Uint, 1, 1, 8);
|
||||||
case RtFormat.R32G32B32A32Float: return new FormatInfo(Format.R32G32B32A32Float, 1, 1, 16);
|
case RtFormat.R32G32B32A32Float: return new FormatInfo(Format.R32G32B32A32Float, 1, 1, 16);
|
||||||
|
|
|
@ -10,6 +10,14 @@ namespace Ryujinx.Graphics.Gpu.State
|
||||||
public uint Unknown0x14;
|
public uint Unknown0x14;
|
||||||
public uint Unknown0x18;
|
public uint Unknown0x18;
|
||||||
public uint Unknown0x1c;
|
public uint Unknown0x1c;
|
||||||
|
public uint Unknown0x20;
|
||||||
|
public uint Unknown0x24;
|
||||||
|
public uint Unknown0x28;
|
||||||
|
public uint Unknown0x2c;
|
||||||
|
public uint Unknown0x30;
|
||||||
|
public uint Unknown0x34;
|
||||||
|
public uint Unknown0x38;
|
||||||
|
public uint Unknown0x3c;
|
||||||
|
|
||||||
public bool UnpackEnable()
|
public bool UnpackEnable()
|
||||||
{
|
{
|
||||||
|
|
|
@ -5,7 +5,7 @@ namespace Ryujinx.Graphics.Gpu.State
|
||||||
{
|
{
|
||||||
struct StencilBackTestState
|
struct StencilBackTestState
|
||||||
{
|
{
|
||||||
public Bool TwoSided;
|
public Boolean32 TwoSided;
|
||||||
public StencilOp BackSFail;
|
public StencilOp BackSFail;
|
||||||
public StencilOp BackDpFail;
|
public StencilOp BackDpFail;
|
||||||
public StencilOp BackDpPass;
|
public StencilOp BackDpPass;
|
||||||
|
|
|
@ -5,7 +5,7 @@ namespace Ryujinx.Graphics.Gpu.State
|
||||||
{
|
{
|
||||||
struct StencilTestState
|
struct StencilTestState
|
||||||
{
|
{
|
||||||
public Bool Enable;
|
public Boolean32 Enable;
|
||||||
public StencilOp FrontSFail;
|
public StencilOp FrontSFail;
|
||||||
public StencilOp FrontDpFail;
|
public StencilOp FrontDpFail;
|
||||||
public StencilOp FrontDpPass;
|
public StencilOp FrontDpPass;
|
||||||
|
|
|
@ -905,6 +905,8 @@ namespace Ryujinx.Graphics.OpenGL
|
||||||
}
|
}
|
||||||
|
|
||||||
private void RestoreComponentMask(int index)
|
private void RestoreComponentMask(int index)
|
||||||
|
{
|
||||||
|
if (_componentMasks != null)
|
||||||
{
|
{
|
||||||
GL.ColorMask(
|
GL.ColorMask(
|
||||||
index,
|
index,
|
||||||
|
@ -913,6 +915,7 @@ namespace Ryujinx.Graphics.OpenGL
|
||||||
(_componentMasks[index] & 4u) != 0,
|
(_componentMasks[index] & 4u) != 0,
|
||||||
(_componentMasks[index] & 8u) != 0);
|
(_componentMasks[index] & 8u) != 0);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void RebindProgram()
|
public void RebindProgram()
|
||||||
{
|
{
|
||||||
|
|
|
@ -6,6 +6,5 @@ namespace Ryujinx.Graphics.Shader.Decoders
|
||||||
Green = 1 << 1,
|
Green = 1 << 1,
|
||||||
Blue = 1 << 2,
|
Blue = 1 << 2,
|
||||||
Alpha = 1 << 3
|
Alpha = 1 << 3
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -2,6 +2,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
|
||||||
{
|
{
|
||||||
enum SystemRegister
|
enum SystemRegister
|
||||||
{
|
{
|
||||||
|
ThreadId = 0x20,
|
||||||
ThreadIdX = 0x21,
|
ThreadIdX = 0x21,
|
||||||
ThreadIdY = 0x22,
|
ThreadIdY = 0x22,
|
||||||
ThreadIdZ = 0x23,
|
ThreadIdZ = 0x23,
|
||||||
|
|
|
@ -27,6 +27,20 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
||||||
|
|
||||||
switch (sysReg)
|
switch (sysReg)
|
||||||
{
|
{
|
||||||
|
case SystemRegister.ThreadId:
|
||||||
|
{
|
||||||
|
Operand tidX = Attribute(AttributeConsts.ThreadIdX);
|
||||||
|
Operand tidY = Attribute(AttributeConsts.ThreadIdY);
|
||||||
|
Operand tidZ = Attribute(AttributeConsts.ThreadIdZ);
|
||||||
|
|
||||||
|
tidY = context.ShiftLeft(tidY, Const(16));
|
||||||
|
tidZ = context.ShiftLeft(tidZ, Const(26));
|
||||||
|
|
||||||
|
src = context.BitwiseOr(tidX, context.BitwiseOr(tidY, tidZ));
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case SystemRegister.ThreadIdX: src = Attribute(AttributeConsts.ThreadIdX); break;
|
case SystemRegister.ThreadIdX: src = Attribute(AttributeConsts.ThreadIdX); break;
|
||||||
case SystemRegister.ThreadIdY: src = Attribute(AttributeConsts.ThreadIdY); break;
|
case SystemRegister.ThreadIdY: src = Attribute(AttributeConsts.ThreadIdY); break;
|
||||||
case SystemRegister.ThreadIdZ: src = Attribute(AttributeConsts.ThreadIdZ); break;
|
case SystemRegister.ThreadIdZ: src = Attribute(AttributeConsts.ThreadIdZ); break;
|
||||||
|
|
|
@ -59,6 +59,8 @@ namespace Ryujinx.Graphics.Shader.StructuredIr
|
||||||
Add(Instruction.ExponentB2, VariableType.Scalar, VariableType.Scalar);
|
Add(Instruction.ExponentB2, VariableType.Scalar, VariableType.Scalar);
|
||||||
Add(Instruction.Floor, VariableType.F32, VariableType.F32);
|
Add(Instruction.Floor, VariableType.F32, VariableType.F32);
|
||||||
Add(Instruction.FusedMultiplyAdd, VariableType.F32, VariableType.F32, VariableType.F32, VariableType.F32);
|
Add(Instruction.FusedMultiplyAdd, VariableType.F32, VariableType.F32, VariableType.F32, VariableType.F32);
|
||||||
|
Add(Instruction.ImageLoad, VariableType.F32);
|
||||||
|
Add(Instruction.ImageStore, VariableType.None);
|
||||||
Add(Instruction.IsNan, VariableType.Bool, VariableType.F32);
|
Add(Instruction.IsNan, VariableType.Bool, VariableType.F32);
|
||||||
Add(Instruction.LoadAttribute, VariableType.F32, VariableType.S32, VariableType.S32);
|
Add(Instruction.LoadAttribute, VariableType.F32, VariableType.S32, VariableType.S32);
|
||||||
Add(Instruction.LoadConstant, VariableType.F32, VariableType.S32, VariableType.S32);
|
Add(Instruction.LoadConstant, VariableType.F32, VariableType.S32, VariableType.S32);
|
||||||
|
@ -105,7 +107,11 @@ namespace Ryujinx.Graphics.Shader.StructuredIr
|
||||||
|
|
||||||
public static VariableType GetSrcVarType(Instruction inst, int index)
|
public static VariableType GetSrcVarType(Instruction inst, int index)
|
||||||
{
|
{
|
||||||
if (inst == Instruction.TextureSample)
|
// TODO: Return correct type depending on source index,
|
||||||
|
// that can improve the decompiler output.
|
||||||
|
if (inst == Instruction.TextureSample ||
|
||||||
|
inst == Instruction.ImageLoad ||
|
||||||
|
inst == Instruction.ImageStore)
|
||||||
{
|
{
|
||||||
return VariableType.F32;
|
return VariableType.F32;
|
||||||
}
|
}
|
||||||
|
|
|
@ -59,9 +59,9 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostAsGpu.Types
|
||||||
_cpuMemory.WriteBytes((long)address, data.ToArray());
|
_cpuMemory.WriteBytes((long)address, data.ToArray());
|
||||||
}
|
}
|
||||||
|
|
||||||
public (ulong, ulong)[] GetModifiedRanges(ulong address, ulong size)
|
public (ulong, ulong)[] GetModifiedRanges(ulong address, ulong size, ResourceName name)
|
||||||
{
|
{
|
||||||
return _cpuMemory.GetModifiedRanges(address, size);
|
return _cpuMemory.GetModifiedRanges(address, size, (int)name);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int GetPageSize()
|
public int GetPageSize()
|
||||||
|
|
Reference in a new issue