diff --git a/src/Ryujinx.Graphics.Gpu/Engine/Threed/ComputeDraw/VtgAsComputeState.cs b/src/Ryujinx.Graphics.Gpu/Engine/Threed/ComputeDraw/VtgAsComputeState.cs
index 13186ef409..25f20e28a8 100644
--- a/src/Ryujinx.Graphics.Gpu/Engine/Threed/ComputeDraw/VtgAsComputeState.cs
+++ b/src/Ryujinx.Graphics.Gpu/Engine/Threed/ComputeDraw/VtgAsComputeState.cs
@@ -3,6 +3,7 @@ using Ryujinx.Common.Logging;
using Ryujinx.Graphics.GAL;
using Ryujinx.Graphics.Gpu.Engine.Types;
using Ryujinx.Graphics.Gpu.Image;
+using Ryujinx.Graphics.Gpu.Memory;
using Ryujinx.Graphics.Gpu.Shader;
using Ryujinx.Graphics.Shader;
using Ryujinx.Graphics.Shader.Translation;
@@ -370,7 +371,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed.ComputeDraw
{
var memoryManager = _channel.MemoryManager;
- BufferRange range = memoryManager.Physical.BufferCache.GetBufferRange(memoryManager.GetPhysicalRegions(address, size), Gpu.Memory.BufferStage.VertexBuffer);
+ BufferRange range = memoryManager.Physical.BufferCache.GetBufferRange(memoryManager.GetPhysicalRegions(address, size), BufferStage.VertexBuffer);
ITexture bufferTexture = _vacContext.EnsureBufferTexture(index + 2, format);
bufferTexture.SetStorage(range);
diff --git a/src/Ryujinx.Graphics.Gpu/Memory/Buffer.cs b/src/Ryujinx.Graphics.Gpu/Memory/Buffer.cs
index 64b1dbddc6..aaeaa472a1 100644
--- a/src/Ryujinx.Graphics.Gpu/Memory/Buffer.cs
+++ b/src/Ryujinx.Graphics.Gpu/Memory/Buffer.cs
@@ -178,6 +178,10 @@ namespace Ryujinx.Graphics.Gpu.Memory
_virtualDependenciesLock = new ReaderWriterLockSlim();
}
+ ///
+ /// Recreates the backing buffer based on the desired access type
+ /// reported by the backing state struct.
+ ///
private void ChangeBacking()
{
BufferAccess access = BackingState.SwitchAccess(this);
@@ -193,6 +197,8 @@ namespace Ryujinx.Graphics.Gpu.Memory
_preFlush = null;
Handle = newHandle;
+
+ _physicalMemory.BufferCache.BufferBackingChanged(this);
}
///
@@ -381,8 +387,6 @@ namespace Ryujinx.Graphics.Gpu.Memory
if (BackingState.ShouldChangeBacking())
{
ChangeBacking();
-
- _physicalMemory.BufferCache.BufferBackingChanged(this);
}
if (BackingState.IsDeviceLocal)
diff --git a/src/Ryujinx.Graphics.Gpu/Memory/BufferBackingState.cs b/src/Ryujinx.Graphics.Gpu/Memory/BufferBackingState.cs
index ee6d3a072a..591d937db4 100644
--- a/src/Ryujinx.Graphics.Gpu/Memory/BufferBackingState.cs
+++ b/src/Ryujinx.Graphics.Gpu/Memory/BufferBackingState.cs
@@ -57,7 +57,7 @@ namespace Ryujinx.Graphics.Gpu.Memory
if (_canSwap)
{
// Might want to start certain buffers as being device local,
- // and the usage might also _lock_ those buffers into being device local.
+ // and the usage might also lock those buffers into being device local.
BufferStage storageFlags = stage & BufferStage.StorageMask;
@@ -86,7 +86,7 @@ namespace Ryujinx.Graphics.Gpu.Memory
}
}
- // TODO: atomic access should likely always be device local
+ // TODO: Might be nice to force atomic access to be device local for any stage.
}
if (baseBuffers != null)
@@ -99,7 +99,7 @@ namespace Ryujinx.Graphics.Gpu.Memory
}
}
- private BufferBackingType CombineTypes(BufferBackingType left, BufferBackingType right)
+ private static BufferBackingType CombineTypes(BufferBackingType left, BufferBackingType right)
{
return (BufferBackingType)Math.Max((int)left, (int)right);
}
@@ -192,7 +192,7 @@ namespace Ryujinx.Graphics.Gpu.Memory
_desiredType = CombineTypes(_desiredType, BufferBackingType.DeviceMemory);
_deviceLocalForceCount = DeviceLocalForceExpiry;
- // TODO: atomic access should likely always be device local
+ // TODO: Might be nice to force atomic access to be device local for any stage.
}
}
diff --git a/src/Ryujinx.Graphics.Gpu/Memory/BufferStage.cs b/src/Ryujinx.Graphics.Gpu/Memory/BufferStage.cs
index e6ddf991d6..4a37da62ee 100644
--- a/src/Ryujinx.Graphics.Gpu/Memory/BufferStage.cs
+++ b/src/Ryujinx.Graphics.Gpu/Memory/BufferStage.cs
@@ -3,6 +3,10 @@ using System.Runtime.CompilerServices;
namespace Ryujinx.Graphics.Gpu.Memory
{
+ ///
+ /// Pipeline stages that can modify buffer data, as well as flags indicating storage usage.
+ /// Must match ShaderStage for the shader stages, though anything after that can be in any order.
+ ///
internal enum BufferStage : byte
{
Compute,
@@ -31,6 +35,9 @@ namespace Ryujinx.Graphics.Gpu.Memory
#pragma warning restore CA1069 // Enums values should not be duplicated
}
+ ///
+ /// Utility methods to convert shader stages and binding flags into buffer stages.
+ ///
internal static class BufferStageUtils
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
diff --git a/src/Ryujinx.Graphics.OpenGL/OpenGLRenderer.cs b/src/Ryujinx.Graphics.OpenGL/OpenGLRenderer.cs
index d605560471..8483e1d77b 100644
--- a/src/Ryujinx.Graphics.OpenGL/OpenGLRenderer.cs
+++ b/src/Ryujinx.Graphics.OpenGL/OpenGLRenderer.cs
@@ -61,7 +61,9 @@ namespace Ryujinx.Graphics.OpenGL
{
BufferCount++;
- if (access.HasFlag(GAL.BufferAccess.HostMemory))
+ var memType = access & GAL.BufferAccess.MemoryTypeMask;
+
+ if (memType == GAL.BufferAccess.HostMemory)
{
BufferHandle handle = Buffer.CreatePersistent(size);