aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ARMeilleure/Memory/MemoryManager.cs20
-rw-r--r--Ryujinx.Graphics.Gpu/Engine/Compute.cs8
-rw-r--r--Ryujinx.Graphics.Gpu/Engine/Inline2Memory.cs6
-rw-r--r--Ryujinx.Graphics.Gpu/Engine/MethodClear.cs17
-rw-r--r--Ryujinx.Graphics.Gpu/Engine/MethodCopyTexture.cs8
-rw-r--r--Ryujinx.Graphics.Gpu/Engine/MethodDraw.cs14
-rw-r--r--Ryujinx.Graphics.Gpu/Engine/MethodReport.cs4
-rw-r--r--Ryujinx.Graphics.Gpu/Engine/MethodUniformBufferBind.cs12
-rw-r--r--Ryujinx.Graphics.Gpu/Engine/MethodUniformBufferUpdate.cs2
-rw-r--r--Ryujinx.Graphics.Gpu/Engine/Methods.cs343
-rw-r--r--Ryujinx.Graphics.Gpu/Image/Pool.cs3
-rw-r--r--Ryujinx.Graphics.Gpu/Image/Texture.cs2
-rw-r--r--Ryujinx.Graphics.Gpu/Image/TextureManager.cs2
-rw-r--r--Ryujinx.Graphics.Gpu/Memory/Buffer.cs2
-rw-r--r--Ryujinx.Graphics.Gpu/Memory/BufferManager.cs8
-rw-r--r--Ryujinx.Graphics.Gpu/Memory/IPhysicalMemory.cs2
-rw-r--r--Ryujinx.Graphics.Gpu/Memory/MemoryManager.cs2
-rw-r--r--Ryujinx.Graphics.Gpu/Memory/ResourceName.cs10
-rw-r--r--Ryujinx.Graphics.Gpu/State/BlendState.cs3
-rw-r--r--Ryujinx.Graphics.Gpu/State/Bool.cs17
-rw-r--r--Ryujinx.Graphics.Gpu/State/Boolean32.cs12
-rw-r--r--Ryujinx.Graphics.Gpu/State/CopyTexture.cs2
-rw-r--r--Ryujinx.Graphics.Gpu/State/DepthBiasState.cs6
-rw-r--r--Ryujinx.Graphics.Gpu/State/FaceState.cs2
-rw-r--r--Ryujinx.Graphics.Gpu/State/GpuState.cs386
-rw-r--r--Ryujinx.Graphics.Gpu/State/GpuStateTable.cs56
-rw-r--r--Ryujinx.Graphics.Gpu/State/GpuVa.cs5
-rw-r--r--Ryujinx.Graphics.Gpu/State/MethodOffset.cs129
-rw-r--r--Ryujinx.Graphics.Gpu/State/PrimitiveRestartState.cs4
-rw-r--r--Ryujinx.Graphics.Gpu/State/RtColorState.cs8
-rw-r--r--Ryujinx.Graphics.Gpu/State/RtFormat.cs4
-rw-r--r--Ryujinx.Graphics.Gpu/State/ShaderState.cs8
-rw-r--r--Ryujinx.Graphics.Gpu/State/StencilBackTestState.cs2
-rw-r--r--Ryujinx.Graphics.Gpu/State/StencilTestState.cs2
-rw-r--r--Ryujinx.Graphics.OpenGL/Pipeline.cs15
-rw-r--r--Ryujinx.Graphics.Shader/Decoders/ImageComponents.cs1
-rw-r--r--Ryujinx.Graphics.Shader/Decoders/SystemRegister.cs1
-rw-r--r--Ryujinx.Graphics.Shader/Instructions/InstEmitMove.cs14
-rw-r--r--Ryujinx.Graphics.Shader/StructuredIr/InstructionInfo.cs8
-rw-r--r--Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostAsGpu/Types/AddressSpaceContext.cs4
40 files changed, 490 insertions, 664 deletions
diff --git a/ARMeilleure/Memory/MemoryManager.cs b/ARMeilleure/Memory/MemoryManager.cs
index 2bdbc309..c3f586aa 100644
--- a/ARMeilleure/Memory/MemoryManager.cs
+++ b/ARMeilleure/Memory/MemoryManager.cs
@@ -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
{
diff --git a/Ryujinx.Graphics.Gpu/Engine/Compute.cs b/Ryujinx.Graphics.Gpu/Engine/Compute.cs
index b5acca1c..588825d0 100644
--- a/Ryujinx.Graphics.Gpu/Engine/Compute.cs
+++ b/Ryujinx.Graphics.Gpu/Engine/Compute.cs
@@ -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();
}
}
} \ No newline at end of file
diff --git a/Ryujinx.Graphics.Gpu/Engine/Inline2Memory.cs b/Ryujinx.Graphics.Gpu/Engine/Inline2Memory.cs
index d2816ac5..355b7394 100644
--- a/Ryujinx.Graphics.Gpu/Engine/Inline2Memory.cs
+++ b/Ryujinx.Graphics.Gpu/Engine/Inline2Memory.cs
@@ -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)
{
diff --git a/Ryujinx.Graphics.Gpu/Engine/MethodClear.cs b/Ryujinx.Graphics.Gpu/Engine/MethodClear.cs
index 2072f3fc..b50a1766 100644
--- a/Ryujinx.Graphics.Gpu/Engine/MethodClear.cs
+++ b/Ryujinx.Graphics.Gpu/Engine/MethodClear.cs
@@ -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(
diff --git a/Ryujinx.Graphics.Gpu/Engine/MethodCopyTexture.cs b/Ryujinx.Graphics.Gpu/Engine/MethodCopyTexture.cs
index e2c40805..887f520d 100644
--- a/Ryujinx.Graphics.Gpu/Engine/MethodCopyTexture.cs
+++ b/Ryujinx.Graphics.Gpu/Engine/MethodCopyTexture.cs
@@ -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);
diff --git a/Ryujinx.Graphics.Gpu/Engine/MethodDraw.cs b/Ryujinx.Graphics.Gpu/Engine/MethodDraw.cs
index c340aeb8..ee07ca76 100644
--- a/Ryujinx.Graphics.Gpu/Engine/MethodDraw.cs
+++ b/Ryujinx.Graphics.Gpu/Engine/MethodDraw.cs
@@ -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;
}
diff --git a/Ryujinx.Graphics.Gpu/Engine/MethodReport.cs b/Ryujinx.Graphics.Gpu/Engine/MethodReport.cs
index fd0a31a1..dd022eb2 100644
--- a/Ryujinx.Graphics.Gpu/Engine/MethodReport.cs
+++ b/Ryujinx.Graphics.Gpu/Engine/MethodReport.cs
@@ -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);
}
diff --git a/Ryujinx.Graphics.Gpu/Engine/MethodUniformBufferBind.cs b/Ryujinx.Graphics.Gpu/Engine/MethodUniformBufferBind.cs
index a9ebce83..823d156e 100644
--- a/Ryujinx.Graphics.Gpu/Engine/MethodUniformBufferBind.cs
+++ b/Ryujinx.Graphics.Gpu/Engine/MethodUniformBufferBind.cs
@@ -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();
diff --git a/Ryujinx.Graphics.Gpu/Engine/MethodUniformBufferUpdate.cs b/Ryujinx.Graphics.Gpu/Engine/MethodUniformBufferUpdate.cs
index f0b8e2d7..229e79a8 100644
--- a/Ryujinx.Graphics.Gpu/Engine/MethodUniformBufferUpdate.cs
+++ b/Ryujinx.Graphics.Gpu/Engine/MethodUniformBufferUpdate.cs
@@ -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);
diff --git a/Ryujinx.Graphics.Gpu/Engine/Methods.cs b/Ryujinx.Graphics.Gpu/Engine/Methods.cs
index c35d6634..5d90573c 100644
--- a/Ryujinx.Graphics.Gpu/Engine/Methods.cs
+++ b/Ryujinx.Graphics.Gpu/Engine/Methods.cs
@@ -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.RegisterDrawEndCallback(DrawEnd);
-
- _context.State.RegisterDrawBeginCallback(DrawBegin);
-
- _context.State.RegisterSetIndexCountCallback(SetIndexCount);
+ _context.State.RegisterCallback(MethodOffset.LaunchDma, LaunchDma);
+ _context.State.RegisterCallback(MethodOffset.LoadInlineData, LoadInlineData);
- _context.State.RegisterClearCallback(Clear);
-
- _context.State.RegisterReportCallback(Report);
-
- _context.State.RegisterUniformBufferUpdateCallback(UniformBufferUpdate);
+ _context.State.RegisterCallback(MethodOffset.Dispatch, Dispatch);
- _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.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.StateWriteFlags & StateWriteFlags.FaceState) != 0)
+ 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()
+ {
+ 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()
{
- TextureMsaaMode msaaMode = _context.State.GetRtMsaaMode();
+ 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,7 +249,10 @@ namespace Ryujinx.Graphics.Gpu.Engine
_textureManager.SetRenderTargetColor(index, color);
- color.Modified = true;
+ if (color != null)
+ {
+ color.Modified = true;
+ }
}
}
else
@@ -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++)
diff --git a/Ryujinx.Graphics.Gpu/Image/Pool.cs b/Ryujinx.Graphics.Gpu/Image/Pool.cs
index 196fc137..7457de19 100644
--- a/Ryujinx.Graphics.Gpu/Image/Pool.cs
+++ b/Ryujinx.Graphics.Gpu/Image/Pool.cs
@@ -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++)
{
diff --git a/Ryujinx.Graphics.Gpu/Image/Texture.cs b/Ryujinx.Graphics.Gpu/Image/Texture.cs
index 7ebf01b8..8da1041b 100644
--- a/Ryujinx.Graphics.Gpu/Image/Texture.cs
+++ b/Ryujinx.Graphics.Gpu/Image/Texture.cs
@@ -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)
{
diff --git a/Ryujinx.Graphics.Gpu/Image/TextureManager.cs b/Ryujinx.Graphics.Gpu/Image/TextureManager.cs
index 91a9cfd1..7cf79d0f 100644
--- a/Ryujinx.Graphics.Gpu/Image/TextureManager.cs
+++ b/Ryujinx.Graphics.Gpu/Image/TextureManager.cs
@@ -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.
diff --git a/Ryujinx.Graphics.Gpu/Memory/Buffer.cs b/Ryujinx.Graphics.Gpu/Memory/Buffer.cs
index 30bd1ac0..6f904d0f 100644
--- a/Ryujinx.Graphics.Gpu/Memory/Buffer.cs
+++ b/Ryujinx.Graphics.Gpu/Memory/Buffer.cs
@@ -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++)
{
diff --git a/Ryujinx.Graphics.Gpu/Memory/BufferManager.cs b/Ryujinx.Graphics.Gpu/Memory/BufferManager.cs
index 3ceee206..6d7fab68 100644
--- a/Ryujinx.Graphics.Gpu/Memory/BufferManager.cs
+++ b/Ryujinx.Graphics.Gpu/Memory/BufferManager.cs
@@ -116,9 +116,13 @@ 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;
+ }
- _gpStorageBuffersDirty = true;
+ _gpStorageBuffers[stage].Bind(index, address, size);
}
public void SetComputeUniformBuffer(int index, ulong gpuVa, ulong size)
diff --git a/Ryujinx.Graphics.Gpu/Memory/IPhysicalMemory.cs b/Ryujinx.Graphics.Gpu/Memory/IPhysicalMemory.cs
index 5f21704d..73b3a9e1 100644
--- a/Ryujinx.Graphics.Gpu/Memory/IPhysicalMemory.cs
+++ b/Ryujinx.Graphics.Gpu/Memory/IPhysicalMemory.cs
@@ -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);
}
} \ No newline at end of file
diff --git a/Ryujinx.Graphics.Gpu/Memory/MemoryManager.cs b/Ryujinx.Graphics.Gpu/Memory/MemoryManager.cs
index d1a3e69c..59319a47 100644
--- a/Ryujinx.Graphics.Gpu/Memory/MemoryManager.cs
+++ b/Ryujinx.Graphics.Gpu/Memory/MemoryManager.cs
@@ -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;
diff --git a/Ryujinx.Graphics.Gpu/Memory/ResourceName.cs b/Ryujinx.Graphics.Gpu/Memory/ResourceName.cs
new file mode 100644
index 00000000..9476a384
--- /dev/null
+++ b/Ryujinx.Graphics.Gpu/Memory/ResourceName.cs
@@ -0,0 +1,10 @@
+namespace Ryujinx.Graphics.Gpu.Memory
+{
+ public enum ResourceName
+ {
+ Buffer,
+ Texture,
+ TexturePool,
+ SamplerPool
+ }
+} \ No newline at end of file
diff --git a/Ryujinx.Graphics.Gpu/State/BlendState.cs b/Ryujinx.Graphics.Gpu/State/BlendState.cs
index cf22dc1b..7029ed6c 100644
--- a/Ryujinx.Graphics.Gpu/State/BlendState.cs
+++ b/Ryujinx.Graphics.Gpu/State/BlendState.cs
@@ -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;
}
}
diff --git a/Ryujinx.Graphics.Gpu/State/Bool.cs b/Ryujinx.Graphics.Gpu/State/Bool.cs
deleted file mode 100644
index 8aadcfcc..00000000
--- a/Ryujinx.Graphics.Gpu/State/Bool.cs
+++ /dev/null
@@ -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;
- }
- }
-}
diff --git a/Ryujinx.Graphics.Gpu/State/Boolean32.cs b/Ryujinx.Graphics.Gpu/State/Boolean32.cs
new file mode 100644
index 00000000..3db912d4
--- /dev/null
+++ b/Ryujinx.Graphics.Gpu/State/Boolean32.cs
@@ -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;
+ }
+ }
+}
diff --git a/Ryujinx.Graphics.Gpu/State/CopyTexture.cs b/Ryujinx.Graphics.Gpu/State/CopyTexture.cs
index 363d84a2..83e7e430 100644
--- a/Ryujinx.Graphics.Gpu/State/CopyTexture.cs
+++ b/Ryujinx.Graphics.Gpu/State/CopyTexture.cs
@@ -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;
diff --git a/Ryujinx.Graphics.Gpu/State/DepthBiasState.cs b/Ryujinx.Graphics.Gpu/State/DepthBiasState.cs
index c88d27dd..45d9c93f 100644
--- a/Ryujinx.Graphics.Gpu/State/DepthBiasState.cs
+++ b/Ryujinx.Graphics.Gpu/State/DepthBiasState.cs
@@ -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;
}
}
diff --git a/Ryujinx.Graphics.Gpu/State/FaceState.cs b/Ryujinx.Graphics.Gpu/State/FaceState.cs
index 53763032..2e62968c 100644
--- a/Ryujinx.Graphics.Gpu/State/FaceState.cs
+++ b/Ryujinx.Graphics.Gpu/State/FaceState.cs
@@ -4,7 +4,7 @@ namespace Ryujinx.Graphics.Gpu.State
{
struct FaceState
{
- public Bool CullEnable;
+ public Boolean32 CullEnable;
public FrontFace FrontFace;
public Face CullFace;
}
diff --git a/Ryujinx.Graphics.Gpu/State/GpuState.cs b/Ryujinx.Graphics.Gpu/State/GpuState.cs
index 4e4241ca..6c603f30 100644
--- a/Ryujinx.Graphics.Gpu/State/GpuState.cs
+++ b/Ryujinx.Graphics.Gpu/State/GpuState.cs
@@ -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;
+ 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;
+ }
+
+ 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();
- InitializeStateWatchers();
}
- public bool ExitEarly;
-
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,80 +101,50 @@ 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);
+ for (int index = 0; index < count; index++)
+ {
+ _registers[(int)offset + index].Callback = callback;
+ }
}
- private void SetWriteStateFlag<T>(MethodOffset offset, StateWriteFlags flag)
+ public void RegisterCallback(MethodOffset offset, MethodCallback callback)
{
- SetWriteStateFlag(offset, flag, Marshal.SizeOf<T>());
+ _registers[(int)offset].Callback = callback;
}
- private void SetWriteStateFlag(MethodOffset offset, StateWriteFlags flag, int size)
+ public bool QueryModified(params MethodOffset[] offsets)
{
- for (int index = 0; index < size; index++)
+ bool modified = false;
+
+ for (int index = 0; index < offsets.Length; index++)
{
- _registers[(int)offset + index].WriteFlag = flag;
+ modified |= QueryModified(offsets[index]);
}
+
+ return modified;
}
- public void RegisterCallback(MethodOffset offset, MethodCallback callback)
+ public bool QueryModified(MethodOffset offset)
{
- _registers[(int)offset].Callback = callback;
+ bool modified = _registers[(int)offset].Modified;
+
+ _registers[(int)offset].Modified = false;
+
+ return modified;
}
- private void RegisterCallback(int offset, MethodCallback callback)
+ public T Get<T>(MethodOffset offset, int index) where T : struct
{
- _registers[offset].Callback = callback;
+ 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
diff --git a/Ryujinx.Graphics.Gpu/State/GpuStateTable.cs b/Ryujinx.Graphics.Gpu/State/GpuStateTable.cs
new file mode 100644
index 00000000..268b1fdc
--- /dev/null
+++ b/Ryujinx.Graphics.Gpu/State/GpuStateTable.cs
@@ -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),
+ };
+ }
+} \ No newline at end of file
diff --git a/Ryujinx.Graphics.Gpu/State/GpuVa.cs b/Ryujinx.Graphics.Gpu/State/GpuVa.cs
index 01ad70b7..4bb56a10 100644
--- a/Ryujinx.Graphics.Gpu/State/GpuVa.cs
+++ b/Ryujinx.Graphics.Gpu/State/GpuVa.cs
@@ -9,10 +9,5 @@ namespace Ryujinx.Graphics.Gpu.State
{
return Low | ((ulong)High << 32);
}
-
- public bool IsNullPtr()
- {
- return (Low | High) == 0;
- }
}
}
diff --git a/Ryujinx.Graphics.Gpu/State/MethodOffset.cs b/Ryujinx.Graphics.Gpu/State/MethodOffset.cs
index 3637d874..4c5e0beb 100644
--- a/Ryujinx.Graphics.Gpu/State/MethodOffset.cs
+++ b/Ryujinx.Graphics.Gpu/State/MethodOffset.cs
@@ -2,63 +2,76 @@ namespace Ryujinx.Graphics.Gpu.State
{
enum MethodOffset
{
- Inline2MemoryParams = 0x60,
- Inline2MemoryExecute = 0x6c,
- Inline2MemoryPushData = 0x6d,
- CopyDstTexture = 0x80,
- CopySrcTexture = 0x8c,
- DispatchParamsAddress = 0xad,
- Dispatch = 0xaf,
- CopyBufferParams = 0x100,
- CopyBufferSwizzle = 0x1c2,
- CopyBufferDstTexture = 0x1c3,
- CopyBufferSrcTexture = 0x1ca,
- RtColorState = 0x200,
- CopyTextureControl = 0x223,
- CopyRegion = 0x22c,
- ViewportTransform = 0x280,
- ViewportExtents = 0x300,
- VertexBufferDrawState = 0x35d,
- ClearColors = 0x360,
- ClearDepthValue = 0x364,
- ClearStencilValue = 0x368,
- DepthBiasState = 0x370,
- TextureBarrier = 0x378,
- StencilBackMasks = 0x3d5,
- InvalidateTextures = 0x3dd,
- TextureBarrierTiled = 0x3df,
- RtDepthStencilState = 0x3f8,
- VertexAttribState = 0x458,
- RtDepthStencilSize = 0x48a,
- DepthTestEnable = 0x4b3,
- DepthWriteEnable = 0x4ba,
- DepthTestFunc = 0x4c3,
- BlendEnable = 0x4d8,
- StencilTestState = 0x4e0,
- FirstVertex = 0x50d,
- FirstInstance = 0x50e,
- ResetCounter = 0x54c,
- RtDepthStencilEnable = 0x54e,
- ConditionState = 0x554,
- SamplerPoolState = 0x557,
- DepthBiasFactor = 0x55b,
- TexturePoolState = 0x55d,
- StencilBackTestState = 0x565,
- DepthBiasUnits = 0x56f,
- RtMsaaMode = 0x574,
- ShaderBaseAddress = 0x582,
- PrimitiveRestartState = 0x591,
- IndexBufferState = 0x5f2,
- DepthBiasClamp = 0x61f,
- VertexBufferInstanced = 0x620,
- FaceState = 0x646,
- RtColorMask = 0x680,
- ReportState = 0x6c0,
- VertexBufferState = 0x700,
- BlendState = 0x780,
- VertexBufferEndAddress = 0x7c0,
- ShaderState = 0x800,
- UniformBufferState = 0x8e0,
- TextureBufferIndex = 0x982
+ I2mParams = 0x60,
+ LaunchDma = 0x6c,
+ LoadInlineData = 0x6d,
+ CopyDstTexture = 0x80,
+ CopySrcTexture = 0x8c,
+ DispatchParamsAddress = 0xad,
+ Dispatch = 0xaf,
+ CopyBuffer = 0xc0,
+ CopyBufferParams = 0x100,
+ CopyBufferSwizzle = 0x1c2,
+ CopyBufferDstTexture = 0x1c3,
+ CopyBufferSrcTexture = 0x1ca,
+ RtColorState = 0x200,
+ CopyTextureControl = 0x223,
+ CopyRegion = 0x22c,
+ CopyTexture = 0x237,
+ ViewportTransform = 0x280,
+ ViewportExtents = 0x300,
+ VertexBufferDrawState = 0x35d,
+ ClearColors = 0x360,
+ ClearDepthValue = 0x364,
+ ClearStencilValue = 0x368,
+ DepthBiasState = 0x370,
+ TextureBarrier = 0x378,
+ StencilBackMasks = 0x3d5,
+ InvalidateTextures = 0x3dd,
+ TextureBarrierTiled = 0x3df,
+ RtDepthStencilState = 0x3f8,
+ VertexAttribState = 0x458,
+ RtDepthStencilSize = 0x48a,
+ DepthTestEnable = 0x4b3,
+ DepthWriteEnable = 0x4ba,
+ DepthTestFunc = 0x4c3,
+ BlendEnable = 0x4d8,
+ StencilTestState = 0x4e0,
+ FirstVertex = 0x50d,
+ FirstInstance = 0x50e,
+ ResetCounter = 0x54c,
+ RtDepthStencilEnable = 0x54e,
+ ConditionState = 0x554,
+ SamplerPoolState = 0x557,
+ DepthBiasFactor = 0x55b,
+ TexturePoolState = 0x55d,
+ StencilBackTestState = 0x565,
+ 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
}
} \ No newline at end of file
diff --git a/Ryujinx.Graphics.Gpu/State/PrimitiveRestartState.cs b/Ryujinx.Graphics.Gpu/State/PrimitiveRestartState.cs
index 21405be7..0b4e1024 100644
--- a/Ryujinx.Graphics.Gpu/State/PrimitiveRestartState.cs
+++ b/Ryujinx.Graphics.Gpu/State/PrimitiveRestartState.cs
@@ -2,7 +2,7 @@ namespace Ryujinx.Graphics.Gpu.State
{
struct PrimitiveRestartState
{
- public bool Enable;
- public int Index;
+ public Boolean32 Enable;
+ public int Index;
}
}
diff --git a/Ryujinx.Graphics.Gpu/State/RtColorState.cs b/Ryujinx.Graphics.Gpu/State/RtColorState.cs
index bb6ae208..beec2593 100644
--- a/Ryujinx.Graphics.Gpu/State/RtColorState.cs
+++ b/Ryujinx.Graphics.Gpu/State/RtColorState.cs
@@ -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;
}
}
diff --git a/Ryujinx.Graphics.Gpu/State/RtFormat.cs b/Ryujinx.Graphics.Gpu/State/RtFormat.cs
index 960da445..7f9ad63d 100644
--- a/Ryujinx.Graphics.Gpu/State/RtFormat.cs
+++ b/Ryujinx.Graphics.Gpu/State/RtFormat.cs
@@ -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);
diff --git a/Ryujinx.Graphics.Gpu/State/ShaderState.cs b/Ryujinx.Graphics.Gpu/State/ShaderState.cs
index 536d7dcf..e5c9c35a 100644
--- a/Ryujinx.Graphics.Gpu/State/ShaderState.cs
+++ b/Ryujinx.Graphics.Gpu/State/ShaderState.cs
@@ -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()
{
diff --git a/Ryujinx.Graphics.Gpu/State/StencilBackTestState.cs b/Ryujinx.Graphics.Gpu/State/StencilBackTestState.cs
index 18b31eaa..f9f47b40 100644
--- a/Ryujinx.Graphics.Gpu/State/StencilBackTestState.cs
+++ b/Ryujinx.Graphics.Gpu/State/StencilBackTestState.cs
@@ -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;
diff --git a/Ryujinx.Graphics.Gpu/State/StencilTestState.cs b/Ryujinx.Graphics.Gpu/State/StencilTestState.cs
index b60f002f..1169a358 100644
--- a/Ryujinx.Graphics.Gpu/State/StencilTestState.cs
+++ b/Ryujinx.Graphics.Gpu/State/StencilTestState.cs
@@ -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;
diff --git a/Ryujinx.Graphics.OpenGL/Pipeline.cs b/Ryujinx.Graphics.OpenGL/Pipeline.cs
index e804eff5..5df801f8 100644
--- a/Ryujinx.Graphics.OpenGL/Pipeline.cs
+++ b/Ryujinx.Graphics.OpenGL/Pipeline.cs
@@ -906,12 +906,15 @@ namespace Ryujinx.Graphics.OpenGL
private void RestoreComponentMask(int index)
{
- GL.ColorMask(
- index,
- (_componentMasks[index] & 1u) != 0,
- (_componentMasks[index] & 2u) != 0,
- (_componentMasks[index] & 4u) != 0,
- (_componentMasks[index] & 8u) != 0);
+ if (_componentMasks != null)
+ {
+ GL.ColorMask(
+ index,
+ (_componentMasks[index] & 1u) != 0,
+ (_componentMasks[index] & 2u) != 0,
+ (_componentMasks[index] & 4u) != 0,
+ (_componentMasks[index] & 8u) != 0);
+ }
}
public void RebindProgram()
diff --git a/Ryujinx.Graphics.Shader/Decoders/ImageComponents.cs b/Ryujinx.Graphics.Shader/Decoders/ImageComponents.cs
index b8a4f6d5..348a4768 100644
--- a/Ryujinx.Graphics.Shader/Decoders/ImageComponents.cs
+++ b/Ryujinx.Graphics.Shader/Decoders/ImageComponents.cs
@@ -6,6 +6,5 @@ namespace Ryujinx.Graphics.Shader.Decoders
Green = 1 << 1,
Blue = 1 << 2,
Alpha = 1 << 3
-
}
} \ No newline at end of file
diff --git a/Ryujinx.Graphics.Shader/Decoders/SystemRegister.cs b/Ryujinx.Graphics.Shader/Decoders/SystemRegister.cs
index 3948c899..1f51d93c 100644
--- a/Ryujinx.Graphics.Shader/Decoders/SystemRegister.cs
+++ b/Ryujinx.Graphics.Shader/Decoders/SystemRegister.cs
@@ -2,6 +2,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
enum SystemRegister
{
+ ThreadId = 0x20,
ThreadIdX = 0x21,
ThreadIdY = 0x22,
ThreadIdZ = 0x23,
diff --git a/Ryujinx.Graphics.Shader/Instructions/InstEmitMove.cs b/Ryujinx.Graphics.Shader/Instructions/InstEmitMove.cs
index f66ebc9f..b9bb18d9 100644
--- a/Ryujinx.Graphics.Shader/Instructions/InstEmitMove.cs
+++ b/Ryujinx.Graphics.Shader/Instructions/InstEmitMove.cs
@@ -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;
diff --git a/Ryujinx.Graphics.Shader/StructuredIr/InstructionInfo.cs b/Ryujinx.Graphics.Shader/StructuredIr/InstructionInfo.cs
index cb08a213..d6ce76db 100644
--- a/Ryujinx.Graphics.Shader/StructuredIr/InstructionInfo.cs
+++ b/Ryujinx.Graphics.Shader/StructuredIr/InstructionInfo.cs
@@ -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;
}
diff --git a/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostAsGpu/Types/AddressSpaceContext.cs b/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostAsGpu/Types/AddressSpaceContext.cs
index 5238645e..bca9ba7c 100644
--- a/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostAsGpu/Types/AddressSpaceContext.cs
+++ b/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostAsGpu/Types/AddressSpaceContext.cs
@@ -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()