mirror of
https://github.com/ryujinx-mirror/ryujinx.git
synced 2024-12-23 08:05:48 +00:00
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 PageMask = PageSize - 1;
|
||||
|
||||
private const long PteFlagNotModified = 1;
|
||||
|
||||
internal const long PteFlagsMask = 7;
|
||||
|
||||
public IntPtr Ram { get; private set; }
|
||||
|
@ -106,6 +104,11 @@ namespace ARMeilleure.Memory
|
|||
ptr = (byte*)ptrUlong;
|
||||
}
|
||||
|
||||
if (ptr == null)
|
||||
{
|
||||
return IntPtr.Zero;
|
||||
}
|
||||
|
||||
return new IntPtr(ptr + (position & PageMask));
|
||||
}
|
||||
|
||||
|
@ -122,10 +125,7 @@ namespace ARMeilleure.Memory
|
|||
|
||||
if ((ptrUlong & PteFlagsMask) != 0)
|
||||
{
|
||||
if ((ptrUlong & PteFlagNotModified) != 0)
|
||||
{
|
||||
ClearPtEntryFlag(position, PteFlagNotModified);
|
||||
}
|
||||
ClearPtEntryFlag(position, PteFlagsMask);
|
||||
|
||||
ptrUlong &= ~(ulong)PteFlagsMask;
|
||||
|
||||
|
@ -253,8 +253,10 @@ namespace ARMeilleure.Memory
|
|||
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)>();
|
||||
|
||||
ulong endAddress = (address + size + PageMask) & ~(ulong)PageMask;
|
||||
|
@ -272,12 +274,12 @@ namespace ARMeilleure.Memory
|
|||
|
||||
ulong ptrUlong = (ulong)ptr;
|
||||
|
||||
if ((ptrUlong & PteFlagNotModified) == 0)
|
||||
if ((ptrUlong & idMask) == 0)
|
||||
{
|
||||
// Modified.
|
||||
currSize += PageSize;
|
||||
|
||||
SetPtEntryFlag((long)address, PteFlagNotModified);
|
||||
SetPtEntryFlag((long)address, (long)idMask);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -27,15 +27,15 @@ namespace Ryujinx.Graphics.Gpu.Engine
|
|||
|
||||
_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);
|
||||
|
||||
PoolState texturePool = _context.State.GetTexturePoolState();
|
||||
var texturePool = _context.State.Get<PoolState>(MethodOffset.TexturePoolState);
|
||||
|
||||
_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;
|
||||
|
||||
|
@ -117,6 +117,8 @@ namespace Ryujinx.Graphics.Gpu.Engine
|
|||
dispatchParams.UnpackGridSizeX(),
|
||||
dispatchParams.UnpackGridSizeY(),
|
||||
dispatchParams.UnpackGridSizeZ());
|
||||
|
||||
UpdateShaderState();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -12,9 +12,9 @@ namespace Ryujinx.Graphics.Gpu.Engine
|
|||
private int _offset;
|
||||
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;
|
||||
|
||||
|
@ -22,7 +22,7 @@ namespace Ryujinx.Graphics.Gpu.Engine
|
|||
_size = _params.LineLengthIn * _params.LineCount;
|
||||
}
|
||||
|
||||
public void PushData(int argument)
|
||||
public void LoadInlineData(int argument)
|
||||
{
|
||||
if (_isLinear)
|
||||
{
|
||||
|
|
|
@ -7,7 +7,9 @@ namespace Ryujinx.Graphics.Gpu.Engine
|
|||
{
|
||||
private void Clear(int argument)
|
||||
{
|
||||
UpdateState();
|
||||
UpdateRenderTargetStateIfNeeded();
|
||||
|
||||
_textureManager.CommitGraphicsBindings();
|
||||
|
||||
bool clearDepth = (argument & 1) != 0;
|
||||
bool clearStencil = (argument & 2) != 0;
|
||||
|
@ -18,7 +20,7 @@ namespace Ryujinx.Graphics.Gpu.Engine
|
|||
|
||||
if (componentMask != 0)
|
||||
{
|
||||
ClearColors clearColor = _context.State.GetClearColors();
|
||||
var clearColor = _context.State.Get<ClearColors>(MethodOffset.ClearColors);
|
||||
|
||||
ColorF color = new ColorF(
|
||||
clearColor.Red,
|
||||
|
@ -26,22 +28,19 @@ namespace Ryujinx.Graphics.Gpu.Engine
|
|||
clearColor.Blue,
|
||||
clearColor.Alpha);
|
||||
|
||||
_context.Renderer.Pipeline.ClearRenderTargetColor(
|
||||
index,
|
||||
componentMask,
|
||||
color);
|
||||
_context.Renderer.Pipeline.ClearRenderTargetColor(index, componentMask, color);
|
||||
}
|
||||
|
||||
if (clearDepth || clearStencil)
|
||||
{
|
||||
float depthValue = _context.State.GetClearDepthValue();
|
||||
int stencilValue = _context.State.GetClearStencilValue();
|
||||
float depthValue = _context.State.Get<float>(MethodOffset.ClearDepthValue);
|
||||
int stencilValue = _context.State.Get<int> (MethodOffset.ClearStencilValue);
|
||||
|
||||
int stencilMask = 0;
|
||||
|
||||
if (clearStencil)
|
||||
{
|
||||
stencilMask = _context.State.GetStencilTestState().FrontMask;
|
||||
stencilMask = _context.State.Get<StencilTestState>(MethodOffset.StencilTestState).FrontMask;
|
||||
}
|
||||
|
||||
_context.Renderer.Pipeline.ClearRenderTargetDepthStencil(
|
||||
|
|
|
@ -7,8 +7,8 @@ namespace Ryujinx.Graphics.Gpu.Engine
|
|||
{
|
||||
private void CopyTexture(int argument)
|
||||
{
|
||||
CopyTexture dstCopyTexture = _context.State.GetCopyDstTexture();
|
||||
CopyTexture srcCopyTexture = _context.State.GetCopySrcTexture();
|
||||
var dstCopyTexture = _context.State.Get<CopyTexture>(MethodOffset.CopyDstTexture);
|
||||
var srcCopyTexture = _context.State.Get<CopyTexture>(MethodOffset.CopySrcTexture);
|
||||
|
||||
Image.Texture srcTexture = _textureManager.FindOrCreateTexture(srcCopyTexture);
|
||||
|
||||
|
@ -32,9 +32,9 @@ namespace Ryujinx.Graphics.Gpu.Engine
|
|||
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 srcY1 = (int)(region.SrcYF >> 32);
|
||||
|
|
|
@ -39,12 +39,12 @@ namespace Ryujinx.Graphics.Gpu.Engine
|
|||
_instancedIndexed = _drawIndexed;
|
||||
|
||||
_instancedFirstIndex = _firstIndex;
|
||||
_instancedFirstVertex = _context.State.GetBaseVertex();
|
||||
_instancedFirstInstance = _context.State.GetBaseInstance();
|
||||
_instancedFirstVertex = _context.State.Get<int>(MethodOffset.FirstVertex);
|
||||
_instancedFirstInstance = _context.State.Get<int>(MethodOffset.FirstInstance);
|
||||
|
||||
_instancedIndexCount = _indexCount;
|
||||
|
||||
VertexBufferDrawState drawState = _context.State.GetVertexBufferDrawState();
|
||||
var drawState = _context.State.Get<VertexBufferDrawState>(MethodOffset.VertexBufferDrawState);
|
||||
|
||||
_instancedDrawStateFirst = drawState.First;
|
||||
_instancedDrawStateCount = drawState.Count;
|
||||
|
@ -53,13 +53,13 @@ namespace Ryujinx.Graphics.Gpu.Engine
|
|||
return;
|
||||
}
|
||||
|
||||
int firstInstance = _context.State.GetBaseInstance();
|
||||
int firstInstance = _context.State.Get<int>(MethodOffset.FirstInstance);
|
||||
|
||||
if (_drawIndexed)
|
||||
{
|
||||
_drawIndexed = false;
|
||||
|
||||
int firstVertex = _context.State.GetBaseVertex();
|
||||
int firstVertex = _context.State.Get<int>(MethodOffset.FirstVertex);
|
||||
|
||||
_context.Renderer.Pipeline.DrawIndexed(
|
||||
_indexCount,
|
||||
|
@ -70,7 +70,7 @@ namespace Ryujinx.Graphics.Gpu.Engine
|
|||
}
|
||||
else
|
||||
{
|
||||
VertexBufferDrawState drawState = _context.State.GetVertexBufferDrawState();
|
||||
var drawState = _context.State.Get<VertexBufferDrawState>(MethodOffset.VertexBufferDrawState);
|
||||
|
||||
_context.Renderer.Pipeline.Draw(
|
||||
drawState.Count,
|
||||
|
@ -98,7 +98,7 @@ namespace Ryujinx.Graphics.Gpu.Engine
|
|||
}
|
||||
}
|
||||
|
||||
private void SetIndexCount(int argument)
|
||||
private void SetIndexBufferCount(int argument)
|
||||
{
|
||||
_drawIndexed = true;
|
||||
}
|
||||
|
|
|
@ -25,7 +25,7 @@ namespace Ryujinx.Graphics.Gpu.Engine
|
|||
|
||||
private void ReportSemaphore()
|
||||
{
|
||||
ReportState state = _context.State.GetReportState();
|
||||
var state = _context.State.Get<ReportState>(MethodOffset.ReportState);
|
||||
|
||||
_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);
|
||||
|
||||
ReportState state = _context.State.GetReportState();
|
||||
var state = _context.State.Get<ReportState>(MethodOffset.ReportState);
|
||||
|
||||
_context.MemoryAccessor.Write(state.Address.Pack(), data);
|
||||
}
|
||||
|
|
|
@ -4,27 +4,27 @@ namespace Ryujinx.Graphics.Gpu.Engine
|
|||
{
|
||||
partial class Methods
|
||||
{
|
||||
private void UniformBufferBind0(int argument)
|
||||
private void UniformBufferBindVertex(int argument)
|
||||
{
|
||||
UniformBufferBind(argument, ShaderType.Vertex);
|
||||
}
|
||||
|
||||
private void UniformBufferBind1(int argument)
|
||||
private void UniformBufferBindTessControl(int argument)
|
||||
{
|
||||
UniformBufferBind(argument, ShaderType.TessellationControl);
|
||||
}
|
||||
|
||||
private void UniformBufferBind2(int argument)
|
||||
private void UniformBufferBindTessEvaluation(int argument)
|
||||
{
|
||||
UniformBufferBind(argument, ShaderType.TessellationEvaluation);
|
||||
}
|
||||
|
||||
private void UniformBufferBind3(int argument)
|
||||
private void UniformBufferBindGeometry(int argument)
|
||||
{
|
||||
UniformBufferBind(argument, ShaderType.Geometry);
|
||||
}
|
||||
|
||||
private void UniformBufferBind4(int argument)
|
||||
private void UniformBufferBindFragment(int argument)
|
||||
{
|
||||
UniformBufferBind(argument, ShaderType.Fragment);
|
||||
}
|
||||
|
@ -37,7 +37,7 @@ namespace Ryujinx.Graphics.Gpu.Engine
|
|||
|
||||
if (enable)
|
||||
{
|
||||
UniformBufferState uniformBuffer = _context.State.GetUniformBufferState();
|
||||
var uniformBuffer = _context.State.Get<UniformBufferState>(MethodOffset.UniformBufferState);
|
||||
|
||||
ulong address = uniformBuffer.Address.Pack();
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@ namespace Ryujinx.Graphics.Gpu.Engine
|
|||
{
|
||||
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);
|
||||
|
||||
|
|
|
@ -18,6 +18,8 @@ namespace Ryujinx.Graphics.Gpu.Engine
|
|||
|
||||
private ShaderCache _shaderCache;
|
||||
|
||||
private ShaderProgramInfo[] _currentProgramInfo;
|
||||
|
||||
private BufferManager _bufferManager;
|
||||
private TextureManager _textureManager;
|
||||
|
||||
|
@ -33,6 +35,8 @@ namespace Ryujinx.Graphics.Gpu.Engine
|
|||
|
||||
_shaderCache = new ShaderCache(_context);
|
||||
|
||||
_currentProgramInfo = new ShaderProgramInfo[Constants.TotalShaderStages];
|
||||
|
||||
_bufferManager = new BufferManager(context);
|
||||
_textureManager = new TextureManager(context);
|
||||
|
||||
|
@ -41,128 +45,184 @@ namespace Ryujinx.Graphics.Gpu.Engine
|
|||
|
||||
private void RegisterCallbacks()
|
||||
{
|
||||
_context.State.RegisterCopyBufferCallback(CopyBuffer);
|
||||
_context.State.RegisterCopyTextureCallback(CopyTexture);
|
||||
_context.State.RegisterCallback(MethodOffset.LaunchDma, LaunchDma);
|
||||
_context.State.RegisterCallback(MethodOffset.LoadInlineData, LoadInlineData);
|
||||
|
||||
_context.State.RegisterDrawEndCallback(DrawEnd);
|
||||
_context.State.RegisterCallback(MethodOffset.Dispatch, Dispatch);
|
||||
|
||||
_context.State.RegisterDrawBeginCallback(DrawBegin);
|
||||
|
||||
_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.CopyBuffer, CopyBuffer);
|
||||
_context.State.RegisterCallback(MethodOffset.CopyTexture, CopyTexture);
|
||||
|
||||
_context.State.RegisterCallback(MethodOffset.TextureBarrier, TextureBarrier);
|
||||
_context.State.RegisterCallback(MethodOffset.InvalidateTextures, InvalidateTextures);
|
||||
_context.State.RegisterCallback(MethodOffset.TextureBarrierTiled, TextureBarrierTiled);
|
||||
|
||||
|
||||
_context.State.RegisterCallback(MethodOffset.ResetCounter, ResetCounter);
|
||||
|
||||
_context.State.RegisterCallback(MethodOffset.Inline2MemoryExecute, Execute);
|
||||
_context.State.RegisterCallback(MethodOffset.Inline2MemoryPushData, PushData);
|
||||
_context.State.RegisterCallback(MethodOffset.DrawEnd, DrawEnd);
|
||||
_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);
|
||||
|
||||
private void UpdateState()
|
||||
{
|
||||
if ((_context.State.StateWriteFlags & StateWriteFlags.Any) == 0)
|
||||
{
|
||||
CommitBindings();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Shaders must be the first one to be updated if modified, because
|
||||
// some of the other state depends on information from the currently
|
||||
// bound shaders.
|
||||
if ((_context.State.StateWriteFlags & StateWriteFlags.ShaderState) != 0)
|
||||
if (_context.State.QueryModified(MethodOffset.ShaderBaseAddress, MethodOffset.ShaderState))
|
||||
{
|
||||
UpdateShaderState();
|
||||
}
|
||||
|
||||
if ((_context.State.StateWriteFlags & StateWriteFlags.RenderTargetGroup) != 0)
|
||||
{
|
||||
UpdateRenderTargetGroupState();
|
||||
}
|
||||
UpdateRenderTargetStateIfNeeded();
|
||||
|
||||
if ((_context.State.StateWriteFlags & StateWriteFlags.DepthTestState) != 0)
|
||||
if (_context.State.QueryModified(MethodOffset.DepthTestEnable,
|
||||
MethodOffset.DepthWriteEnable,
|
||||
MethodOffset.DepthTestFunc))
|
||||
{
|
||||
UpdateDepthTestState();
|
||||
}
|
||||
|
||||
if ((_context.State.StateWriteFlags & StateWriteFlags.ViewportTransform) != 0)
|
||||
if (_context.State.QueryModified(MethodOffset.ViewportTransform, MethodOffset.ViewportExtents))
|
||||
{
|
||||
UpdateViewportTransform();
|
||||
}
|
||||
|
||||
if ((_context.State.StateWriteFlags & StateWriteFlags.DepthBiasState) != 0)
|
||||
if (_context.State.QueryModified(MethodOffset.DepthBiasState,
|
||||
MethodOffset.DepthBiasFactor,
|
||||
MethodOffset.DepthBiasUnits,
|
||||
MethodOffset.DepthBiasClamp))
|
||||
{
|
||||
UpdateDepthBiasState();
|
||||
}
|
||||
|
||||
if ((_context.State.StateWriteFlags & StateWriteFlags.StencilTestState) != 0)
|
||||
if (_context.State.QueryModified(MethodOffset.StencilBackMasks,
|
||||
MethodOffset.StencilTestState,
|
||||
MethodOffset.StencilBackTestState))
|
||||
{
|
||||
UpdateStencilTestState();
|
||||
}
|
||||
|
||||
if ((_context.State.StateWriteFlags & StateWriteFlags.SamplerPoolState) != 0)
|
||||
// Pools.
|
||||
if (_context.State.QueryModified(MethodOffset.SamplerPoolState))
|
||||
{
|
||||
UpdateSamplerPoolState();
|
||||
}
|
||||
|
||||
if ((_context.State.StateWriteFlags & StateWriteFlags.TexturePoolState) != 0)
|
||||
if (_context.State.QueryModified(MethodOffset.TexturePoolState))
|
||||
{
|
||||
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();
|
||||
}
|
||||
|
||||
if ((_context.State.StateWriteFlags & StateWriteFlags.RtColorMask) != 0)
|
||||
if (_context.State.QueryModified(MethodOffset.RtColorMask))
|
||||
{
|
||||
UpdateRtColorMask();
|
||||
}
|
||||
|
||||
if ((_context.State.StateWriteFlags & StateWriteFlags.BlendState) != 0)
|
||||
if (_context.State.QueryModified(MethodOffset.BlendEnable, MethodOffset.BlendState))
|
||||
{
|
||||
UpdateBlendState();
|
||||
}
|
||||
|
||||
_context.State.StateWriteFlags &= ~StateWriteFlags.Any;
|
||||
|
||||
CommitBindings();
|
||||
}
|
||||
|
||||
private void CommitBindings()
|
||||
{
|
||||
UpdateStorageBuffers();
|
||||
|
||||
_bufferManager.CommitBindings();
|
||||
_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 samplesInY = msaaMode.SamplesInY();
|
||||
|
@ -173,7 +233,7 @@ namespace Ryujinx.Graphics.Gpu.Engine
|
|||
{
|
||||
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))
|
||||
{
|
||||
|
@ -189,9 +249,12 @@ namespace Ryujinx.Graphics.Gpu.Engine
|
|||
|
||||
_textureManager.SetRenderTargetColor(index, color);
|
||||
|
||||
if (color != null)
|
||||
{
|
||||
color.Modified = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_textureManager.SetRenderTargetColor3D(color3D);
|
||||
|
@ -199,14 +262,14 @@ namespace Ryujinx.Graphics.Gpu.Engine
|
|||
color3D.Modified = true;
|
||||
}
|
||||
|
||||
bool dsEnable = _context.State.Get<bool>(MethodOffset.RtDepthStencilEnable);
|
||||
bool dsEnable = _context.State.Get<Boolean32>(MethodOffset.RtDepthStencilEnable);
|
||||
|
||||
Image.Texture depthStencil = null;
|
||||
|
||||
if (dsEnable)
|
||||
{
|
||||
var dsState = _context.State.GetRtDepthStencilState();
|
||||
var dsSize = _context.State.GetRtDepthStencilSize();
|
||||
var dsState = _context.State.Get<RtDepthStencilState>(MethodOffset.RtDepthStencilState);
|
||||
var dsSize = _context.State.Get<Size3D> (MethodOffset.RtDepthStencilSize);
|
||||
|
||||
depthStencil = _textureManager.FindOrCreateTexture(
|
||||
dsState,
|
||||
|
@ -216,11 +279,16 @@ namespace Ryujinx.Graphics.Gpu.Engine
|
|||
}
|
||||
|
||||
_textureManager.SetRenderTargetDepthStencil(depthStencil);
|
||||
|
||||
if (depthStencil != null)
|
||||
{
|
||||
depthStencil.Modified = true;
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
|
@ -232,7 +300,7 @@ namespace Ryujinx.Graphics.Gpu.Engine
|
|||
|
||||
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))
|
||||
{
|
||||
|
@ -266,9 +334,9 @@ namespace Ryujinx.Graphics.Gpu.Engine
|
|||
private void UpdateDepthTestState()
|
||||
{
|
||||
_context.Renderer.Pipeline.SetDepthTest(new DepthTestDescriptor(
|
||||
_context.State.GetDepthTestEnable().IsTrue(),
|
||||
_context.State.GetDepthWriteEnable().IsTrue(),
|
||||
_context.State.GetDepthTestFunc()));
|
||||
_context.State.Get<Boolean32>(MethodOffset.DepthTestEnable),
|
||||
_context.State.Get<Boolean32>(MethodOffset.DepthWriteEnable),
|
||||
_context.State.Get<CompareOp>(MethodOffset.DepthTestFunc)));
|
||||
}
|
||||
|
||||
private void UpdateViewportTransform()
|
||||
|
@ -277,8 +345,8 @@ namespace Ryujinx.Graphics.Gpu.Engine
|
|||
|
||||
for (int index = 0; index < Constants.TotalViewports; index++)
|
||||
{
|
||||
var transform = _context.State.Get<ViewportTransform>(MethodOffset.ViewportTransform + index * 8);
|
||||
var extents = _context.State.Get<ViewportExtents> (MethodOffset.ViewportExtents + index * 4);
|
||||
var transform = _context.State.Get<ViewportTransform>(MethodOffset.ViewportTransform, index);
|
||||
var extents = _context.State.Get<ViewportExtents> (MethodOffset.ViewportExtents, index);
|
||||
|
||||
float x = transform.TranslateX - MathF.Abs(transform.ScaleX);
|
||||
float y = transform.TranslateY - MathF.Abs(transform.ScaleY);
|
||||
|
@ -303,7 +371,7 @@ namespace Ryujinx.Graphics.Gpu.Engine
|
|||
|
||||
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 units = _context.State.Get<float>(MethodOffset.DepthBiasUnits);
|
||||
|
@ -311,18 +379,18 @@ namespace Ryujinx.Graphics.Gpu.Engine
|
|||
|
||||
PolygonModeMask enables = 0;
|
||||
|
||||
enables = (polygonOffset.PointEnable.IsTrue() ? PolygonModeMask.Point : 0);
|
||||
enables |= (polygonOffset.LineEnable.IsTrue() ? PolygonModeMask.Line : 0);
|
||||
enables |= (polygonOffset.FillEnable.IsTrue() ? PolygonModeMask.Fill : 0);
|
||||
enables = (depthBias.PointEnable ? PolygonModeMask.Point : 0);
|
||||
enables |= (depthBias.LineEnable ? PolygonModeMask.Line : 0);
|
||||
enables |= (depthBias.FillEnable ? PolygonModeMask.Fill : 0);
|
||||
|
||||
_context.Renderer.Pipeline.SetDepthBias(enables, factor, units, clamp);
|
||||
}
|
||||
|
||||
private void UpdateStencilTestState()
|
||||
{
|
||||
StencilBackMasks backMasks = _context.State.GetStencilBackMasks();
|
||||
StencilTestState test = _context.State.GetStencilTestState();
|
||||
StencilBackTestState backTest = _context.State.GetStencilBackTestState();
|
||||
var backMasks = _context.State.Get<StencilBackMasks> (MethodOffset.StencilBackMasks);
|
||||
var test = _context.State.Get<StencilTestState> (MethodOffset.StencilTestState);
|
||||
var backTest = _context.State.Get<StencilBackTestState>(MethodOffset.StencilBackTestState);
|
||||
|
||||
CompareOp backFunc;
|
||||
StencilOp backSFail;
|
||||
|
@ -332,7 +400,7 @@ namespace Ryujinx.Graphics.Gpu.Engine
|
|||
int backFuncMask;
|
||||
int backMask;
|
||||
|
||||
if (backTest.TwoSided.IsTrue())
|
||||
if (backTest.TwoSided)
|
||||
{
|
||||
backFunc = backTest.BackFunc;
|
||||
backSFail = backTest.BackSFail;
|
||||
|
@ -354,7 +422,7 @@ namespace Ryujinx.Graphics.Gpu.Engine
|
|||
}
|
||||
|
||||
_context.Renderer.Pipeline.SetStencilTest(new StencilTestDescriptor(
|
||||
test.Enable.IsTrue(),
|
||||
test.Enable,
|
||||
test.FrontFunc,
|
||||
test.FrontSFail,
|
||||
test.FrontDpPass,
|
||||
|
@ -373,42 +441,18 @@ namespace Ryujinx.Graphics.Gpu.Engine
|
|||
|
||||
private void UpdateSamplerPoolState()
|
||||
{
|
||||
PoolState samplerPool = _context.State.GetSamplerPoolState();
|
||||
var samplerPool = _context.State.Get<PoolState>(MethodOffset.SamplerPoolState);
|
||||
|
||||
_textureManager.SetGraphicsSamplerPool(samplerPool.Address.Pack(), samplerPool.MaximumId);
|
||||
}
|
||||
|
||||
private void UpdateTexturePoolState()
|
||||
{
|
||||
PoolState texturePool = _context.State.GetTexturePoolState();
|
||||
var texturePool = _context.State.Get<PoolState>(MethodOffset.TexturePoolState);
|
||||
|
||||
_textureManager.SetGraphicsTexturePool(texturePool.Address.Pack(), texturePool.MaximumId);
|
||||
|
||||
_textureManager.SetGraphicsTextureBufferIndex(_context.State.GetTextureBufferIndex());
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
_textureManager.SetGraphicsTextureBufferIndex(_context.State.Get<int>(MethodOffset.TextureBufferIndex));
|
||||
}
|
||||
|
||||
private void UpdateVertexAttribState()
|
||||
|
@ -417,7 +461,7 @@ namespace Ryujinx.Graphics.Gpu.Engine
|
|||
|
||||
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))
|
||||
{
|
||||
|
@ -446,7 +490,7 @@ namespace Ryujinx.Graphics.Gpu.Engine
|
|||
|
||||
private void UpdateIndexBufferState()
|
||||
{
|
||||
IndexBufferState indexBuffer = _context.State.GetIndexBufferState();
|
||||
var indexBuffer = _context.State.Get<IndexBufferState>(MethodOffset.IndexBufferState);
|
||||
|
||||
_firstIndex = indexBuffer.First;
|
||||
_indexCount = indexBuffer.Count;
|
||||
|
@ -475,70 +519,13 @@ namespace Ryujinx.Graphics.Gpu.Engine
|
|||
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()
|
||||
{
|
||||
_isAnyVbInstanced = false;
|
||||
|
||||
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())
|
||||
{
|
||||
|
@ -547,13 +534,13 @@ namespace Ryujinx.Graphics.Gpu.Engine
|
|||
continue;
|
||||
}
|
||||
|
||||
GpuVa endAddress = _context.State.GetVertexBufferEndAddress(index);
|
||||
GpuVa endAddress = _context.State.Get<GpuVa>(MethodOffset.VertexBufferEndAddress, index);
|
||||
|
||||
ulong address = vertexBuffer.Address.Pack();
|
||||
|
||||
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;
|
||||
|
||||
|
@ -571,9 +558,9 @@ namespace Ryujinx.Graphics.Gpu.Engine
|
|||
{
|
||||
// For non-indexed draws, we can guess the size from the vertex count
|
||||
// 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);
|
||||
}
|
||||
|
@ -584,9 +571,9 @@ namespace Ryujinx.Graphics.Gpu.Engine
|
|||
|
||||
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);
|
||||
}
|
||||
|
@ -597,7 +584,7 @@ namespace Ryujinx.Graphics.Gpu.Engine
|
|||
|
||||
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;
|
||||
|
||||
|
@ -618,12 +605,12 @@ namespace Ryujinx.Graphics.Gpu.Engine
|
|||
|
||||
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(
|
||||
blendEnable,
|
||||
enable,
|
||||
blend.ColorOp,
|
||||
blend.ColorSrcFactor,
|
||||
blend.ColorDstFactor,
|
||||
|
@ -656,11 +643,11 @@ namespace Ryujinx.Graphics.Gpu.Engine
|
|||
|
||||
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++)
|
||||
{
|
||||
ShaderState shader = _context.State.GetShaderState(index);
|
||||
var shader = _context.State.Get<ShaderState>(MethodOffset.ShaderState, index);
|
||||
|
||||
if (!shader.UnpackEnable() && index != 1)
|
||||
{
|
||||
|
@ -678,6 +665,8 @@ namespace Ryujinx.Graphics.Gpu.Engine
|
|||
{
|
||||
ShaderProgramInfo info = gs.Shader[stage]?.Info;
|
||||
|
||||
_currentProgramInfo[stage] = info;
|
||||
|
||||
if (info == null)
|
||||
{
|
||||
continue;
|
||||
|
@ -714,21 +703,7 @@ namespace Ryujinx.Graphics.Gpu.Engine
|
|||
|
||||
for (int index = 0; index < info.SBuffers.Count; index++)
|
||||
{
|
||||
BufferDescriptor sb = info.SBuffers[index];
|
||||
|
||||
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);
|
||||
sbEnableMask |= 1u << info.SBuffers[index].Slot;
|
||||
}
|
||||
|
||||
for (int index = 0; index < info.CBuffers.Count; index++)
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
using Ryujinx.Graphics.Gpu.Memory;
|
||||
using System;
|
||||
|
||||
namespace Ryujinx.Graphics.Gpu.Image
|
||||
|
@ -31,7 +32,7 @@ namespace Ryujinx.Graphics.Gpu.Image
|
|||
|
||||
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++)
|
||||
{
|
||||
|
|
|
@ -202,7 +202,7 @@ namespace Ryujinx.Graphics.Gpu.Image
|
|||
|
||||
_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)
|
||||
{
|
||||
|
|
|
@ -114,7 +114,7 @@ namespace Ryujinx.Graphics.Gpu.Image
|
|||
|
||||
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.
|
||||
// Since compute work happens less often, we always do that
|
||||
// before and after the compute dispatch.
|
||||
|
|
|
@ -69,7 +69,7 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
|||
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++)
|
||||
{
|
||||
|
|
|
@ -116,11 +116,15 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
|||
|
||||
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;
|
||||
}
|
||||
|
||||
_gpStorageBuffers[stage].Bind(index, address, size);
|
||||
}
|
||||
|
||||
public void SetComputeUniformBuffer(int index, ulong gpuVa, ulong size)
|
||||
{
|
||||
ulong address = TranslateAndCreateBuffer(gpuVa, size);
|
||||
|
|
|
@ -10,6 +10,6 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
|||
|
||||
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 PtLvl1Bits = 14;
|
||||
private const int PtPageBits = 12;
|
||||
public const int PtPageBits = 12;
|
||||
|
||||
private const ulong PtLvl0Size = 1UL << PtLvl0Bits;
|
||||
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
|
||||
{
|
||||
public Bool SeparateAlpha;
|
||||
public Boolean32 SeparateAlpha;
|
||||
public BlendOp ColorOp;
|
||||
public BlendFactor ColorSrcFactor;
|
||||
public BlendFactor ColorDstFactor;
|
||||
public BlendOp AlphaOp;
|
||||
public BlendFactor AlphaSrcFactor;
|
||||
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
|
||||
{
|
||||
public RtFormat Format;
|
||||
public bool LinearLayout;
|
||||
public Boolean32 LinearLayout;
|
||||
public MemoryLayout MemoryLayout;
|
||||
public int Depth;
|
||||
public int Layer;
|
||||
|
|
|
@ -2,8 +2,8 @@ namespace Ryujinx.Graphics.Gpu.State
|
|||
{
|
||||
struct DepthBiasState
|
||||
{
|
||||
public Bool PointEnable;
|
||||
public Bool LineEnable;
|
||||
public Bool FillEnable;
|
||||
public Boolean32 PointEnable;
|
||||
public Boolean32 LineEnable;
|
||||
public Boolean32 FillEnable;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@ namespace Ryujinx.Graphics.Gpu.State
|
|||
{
|
||||
struct FaceState
|
||||
{
|
||||
public Bool CullEnable;
|
||||
public Boolean32 CullEnable;
|
||||
public FrontFace FrontFace;
|
||||
public Face CullFace;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
using Ryujinx.Graphics.GAL;
|
||||
using Ryujinx.Graphics.Gpu.Image;
|
||||
using System;
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Ryujinx.Graphics.Gpu.State
|
||||
|
@ -17,39 +15,54 @@ namespace Ryujinx.Graphics.Gpu.State
|
|||
{
|
||||
public MethodCallback Callback;
|
||||
|
||||
public StateWriteFlags WriteFlag;
|
||||
public MethodOffset BaseOffset;
|
||||
|
||||
public int Stride;
|
||||
public int Count;
|
||||
|
||||
public bool Modified;
|
||||
}
|
||||
|
||||
private Register[] _registers;
|
||||
|
||||
public StateWriteFlags StateWriteFlags { get; set; }
|
||||
|
||||
public GpuState()
|
||||
{
|
||||
_backingMemory = new int[RegistersCount];
|
||||
|
||||
_registers = new Register[RegistersCount];
|
||||
|
||||
StateWriteFlags = StateWriteFlags.Any;
|
||||
|
||||
InitializeDefaultState();
|
||||
InitializeStateWatchers();
|
||||
for (int index = 0; index < _registers.Length; index++)
|
||||
{
|
||||
_registers[index].BaseOffset = (MethodOffset)index;
|
||||
_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)
|
||||
{
|
||||
if (ExitEarly)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Register register = _registers[meth.Method];
|
||||
|
||||
if (_backingMemory[meth.Method] != meth.Argument)
|
||||
{
|
||||
StateWriteFlags |= register.WriteFlag;
|
||||
_registers[(int)register.BaseOffset].Modified = true;
|
||||
}
|
||||
|
||||
_backingMemory[meth.Method] = meth.Argument;
|
||||
|
@ -67,264 +80,11 @@ namespace Ryujinx.Graphics.Gpu.State
|
|||
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)
|
||||
{
|
||||
_backingMemory[(int)MethodOffset.UniformBufferState + 3] = offset;
|
||||
}
|
||||
|
||||
public int GetTextureBufferIndex()
|
||||
{
|
||||
return _backingMemory[(int)MethodOffset.TextureBufferIndex];
|
||||
}
|
||||
|
||||
private void InitializeDefaultState()
|
||||
{
|
||||
// Depth ranges.
|
||||
|
@ -341,69 +101,11 @@ namespace Ryujinx.Graphics.Gpu.State
|
|||
_backingMemory[(int)MethodOffset.RtColorMask] = 0x1111;
|
||||
}
|
||||
|
||||
private void InitializeStateWatchers()
|
||||
public void RegisterCallback(MethodOffset offset, int count, MethodCallback callback)
|
||||
{
|
||||
SetWriteStateFlag(MethodOffset.RtColorState, StateWriteFlags.RtColorState, 16 * 8);
|
||||
|
||||
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)
|
||||
for (int index = 0; index < count; index++)
|
||||
{
|
||||
SetWriteStateFlag(offset, flag, Marshal.SizeOf<T>());
|
||||
}
|
||||
|
||||
private void SetWriteStateFlag(MethodOffset offset, StateWriteFlags flag, int size)
|
||||
{
|
||||
for (int index = 0; index < size; index++)
|
||||
{
|
||||
_registers[(int)offset + index].WriteFlag = flag;
|
||||
_registers[(int)offset + index].Callback = callback;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -412,9 +114,37 @@ namespace Ryujinx.Graphics.Gpu.State
|
|||
_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
|
||||
|
|
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);
|
||||
}
|
||||
|
||||
public bool IsNullPtr()
|
||||
{
|
||||
return (Low | High) == 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,13 +2,14 @@ namespace Ryujinx.Graphics.Gpu.State
|
|||
{
|
||||
enum MethodOffset
|
||||
{
|
||||
Inline2MemoryParams = 0x60,
|
||||
Inline2MemoryExecute = 0x6c,
|
||||
Inline2MemoryPushData = 0x6d,
|
||||
I2mParams = 0x60,
|
||||
LaunchDma = 0x6c,
|
||||
LoadInlineData = 0x6d,
|
||||
CopyDstTexture = 0x80,
|
||||
CopySrcTexture = 0x8c,
|
||||
DispatchParamsAddress = 0xad,
|
||||
Dispatch = 0xaf,
|
||||
CopyBuffer = 0xc0,
|
||||
CopyBufferParams = 0x100,
|
||||
CopyBufferSwizzle = 0x1c2,
|
||||
CopyBufferDstTexture = 0x1c3,
|
||||
|
@ -16,6 +17,7 @@ namespace Ryujinx.Graphics.Gpu.State
|
|||
RtColorState = 0x200,
|
||||
CopyTextureControl = 0x223,
|
||||
CopyRegion = 0x22c,
|
||||
CopyTexture = 0x237,
|
||||
ViewportTransform = 0x280,
|
||||
ViewportExtents = 0x300,
|
||||
VertexBufferDrawState = 0x35d,
|
||||
|
@ -47,18 +49,29 @@ namespace Ryujinx.Graphics.Gpu.State
|
|||
DepthBiasUnits = 0x56f,
|
||||
RtMsaaMode = 0x574,
|
||||
ShaderBaseAddress = 0x582,
|
||||
DrawEnd = 0x585,
|
||||
DrawBegin = 0x586,
|
||||
PrimitiveRestartState = 0x591,
|
||||
IndexBufferState = 0x5f2,
|
||||
IndexBufferCount = 0x5f8,
|
||||
DepthBiasClamp = 0x61f,
|
||||
VertexBufferInstanced = 0x620,
|
||||
FaceState = 0x646,
|
||||
Clear = 0x674,
|
||||
RtColorMask = 0x680,
|
||||
ReportState = 0x6c0,
|
||||
Report = 0x6c3,
|
||||
VertexBufferState = 0x700,
|
||||
BlendState = 0x780,
|
||||
VertexBufferEndAddress = 0x7c0,
|
||||
ShaderState = 0x800,
|
||||
UniformBufferState = 0x8e0,
|
||||
UniformBufferUpdateData = 0x8e4,
|
||||
UniformBufferBindVertex = 0x904,
|
||||
UniformBufferBindTessControl = 0x90c,
|
||||
UniformBufferBindTessEvaluation = 0x914,
|
||||
UniformBufferBindGeometry = 0x91c,
|
||||
UniformBufferBindFragment = 0x924,
|
||||
TextureBufferIndex = 0x982
|
||||
}
|
||||
}
|
|
@ -2,7 +2,7 @@ namespace Ryujinx.Graphics.Gpu.State
|
|||
{
|
||||
struct PrimitiveRestartState
|
||||
{
|
||||
public bool Enable;
|
||||
public Boolean32 Enable;
|
||||
public int Index;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,5 +9,13 @@ namespace Ryujinx.Graphics.Gpu.State
|
|||
public MemoryLayout MemoryLayout;
|
||||
public int Depth;
|
||||
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,
|
||||
D16Unorm = 0x13,
|
||||
D24UnormS8Uint = 0x14,
|
||||
D24Unorm = 0x15,
|
||||
S8UintD24Unorm = 0x16,
|
||||
S8Uint = 0x17,
|
||||
D32FloatS8Uint = 0x19,
|
||||
R32G32B32A32Float = 0xc0,
|
||||
|
@ -74,6 +76,8 @@ namespace Ryujinx.Graphics.Gpu.State
|
|||
case RtFormat.D32Float: return new FormatInfo(Format.D32Float, 1, 1, 4);
|
||||
case RtFormat.D16Unorm: return new FormatInfo(Format.D16Unorm, 1, 1, 2);
|
||||
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.D32FloatS8Uint: return new FormatInfo(Format.D32FloatS8Uint, 1, 1, 8);
|
||||
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 Unknown0x18;
|
||||
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()
|
||||
{
|
||||
|
|
|
@ -5,7 +5,7 @@ namespace Ryujinx.Graphics.Gpu.State
|
|||
{
|
||||
struct StencilBackTestState
|
||||
{
|
||||
public Bool TwoSided;
|
||||
public Boolean32 TwoSided;
|
||||
public StencilOp BackSFail;
|
||||
public StencilOp BackDpFail;
|
||||
public StencilOp BackDpPass;
|
||||
|
|
|
@ -5,7 +5,7 @@ namespace Ryujinx.Graphics.Gpu.State
|
|||
{
|
||||
struct StencilTestState
|
||||
{
|
||||
public Bool Enable;
|
||||
public Boolean32 Enable;
|
||||
public StencilOp FrontSFail;
|
||||
public StencilOp FrontDpFail;
|
||||
public StencilOp FrontDpPass;
|
||||
|
|
|
@ -905,6 +905,8 @@ namespace Ryujinx.Graphics.OpenGL
|
|||
}
|
||||
|
||||
private void RestoreComponentMask(int index)
|
||||
{
|
||||
if (_componentMasks != null)
|
||||
{
|
||||
GL.ColorMask(
|
||||
index,
|
||||
|
@ -913,6 +915,7 @@ namespace Ryujinx.Graphics.OpenGL
|
|||
(_componentMasks[index] & 4u) != 0,
|
||||
(_componentMasks[index] & 8u) != 0);
|
||||
}
|
||||
}
|
||||
|
||||
public void RebindProgram()
|
||||
{
|
||||
|
|
|
@ -6,6 +6,5 @@ namespace Ryujinx.Graphics.Shader.Decoders
|
|||
Green = 1 << 1,
|
||||
Blue = 1 << 2,
|
||||
Alpha = 1 << 3
|
||||
|
||||
}
|
||||
}
|
|
@ -2,6 +2,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
|
|||
{
|
||||
enum SystemRegister
|
||||
{
|
||||
ThreadId = 0x20,
|
||||
ThreadIdX = 0x21,
|
||||
ThreadIdY = 0x22,
|
||||
ThreadIdZ = 0x23,
|
||||
|
|
|
@ -27,6 +27,20 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||
|
||||
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.ThreadIdY: src = Attribute(AttributeConsts.ThreadIdY); 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.Floor, 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.LoadAttribute, 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)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -59,9 +59,9 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostAsGpu.Types
|
|||
_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()
|
||||
|
|
Loading…
Reference in a new issue