diff --git a/src/Ryujinx.Graphics.Vulkan/HardwareCapabilities.cs b/src/Ryujinx.Graphics.Vulkan/HardwareCapabilities.cs index bd17867b1..484ffe577 100644 --- a/src/Ryujinx.Graphics.Vulkan/HardwareCapabilities.cs +++ b/src/Ryujinx.Graphics.Vulkan/HardwareCapabilities.cs @@ -54,6 +54,7 @@ namespace Ryujinx.Graphics.Vulkan public readonly uint VertexBufferAlignment; public readonly uint SubTexelPrecisionBits; public readonly ulong MinResourceAlignment; + public readonly ulong MinTexelBufferAlignment; public HardwareCapabilities( bool supportsIndexTypeUint8, @@ -93,7 +94,8 @@ namespace Ryujinx.Graphics.Vulkan PortabilitySubsetFlags portabilitySubset, uint vertexBufferAlignment, uint subTexelPrecisionBits, - ulong minResourceAlignment) + ulong minResourceAlignment, + ulong minTexelBufferAlignment) { SupportsIndexTypeUint8 = supportsIndexTypeUint8; SupportsCustomBorderColor = supportsCustomBorderColor; @@ -133,6 +135,7 @@ namespace Ryujinx.Graphics.Vulkan VertexBufferAlignment = vertexBufferAlignment; SubTexelPrecisionBits = subTexelPrecisionBits; MinResourceAlignment = minResourceAlignment; + MinTexelBufferAlignment = minTexelBufferAlignment; } } } diff --git a/src/Ryujinx.Graphics.Vulkan/TextureBuffer.cs b/src/Ryujinx.Graphics.Vulkan/TextureBuffer.cs index 8a2cd2102..6745690ff 100644 --- a/src/Ryujinx.Graphics.Vulkan/TextureBuffer.cs +++ b/src/Ryujinx.Graphics.Vulkan/TextureBuffer.cs @@ -54,6 +54,13 @@ namespace Ryujinx.Graphics.Vulkan public PinnedSpan GetData() { + int minTexelBufferOffsetAlignment = (int)_gd.Capabilities.MinTexelBufferAlignment; + + if (_offset % minTexelBufferOffsetAlignment != 0) + { + _offset += (minTexelBufferOffsetAlignment - (_offset % minTexelBufferOffsetAlignment)); + } + return _gd.GetBufferData(_bufferHandle, _offset, _size); } @@ -84,6 +91,13 @@ namespace Ryujinx.Graphics.Vulkan /// public void SetData(MemoryOwner data) { + int minTexelBufferOffsetAlignment = (int)_gd.Capabilities.MinTexelBufferAlignment; + + if (_offset % minTexelBufferOffsetAlignment != 0) + { + _offset += (minTexelBufferOffsetAlignment - (_offset % minTexelBufferOffsetAlignment)); + } + _gd.SetBufferData(_bufferHandle, _offset, data.Span); data.Dispose(); } @@ -102,8 +116,16 @@ namespace Ryujinx.Graphics.Vulkan public void SetStorage(BufferRange buffer) { + int minTexelBufferOffsetAlignment = (int)_gd.Capabilities.MinTexelBufferAlignment; + int bufferOffset = buffer.Offset; + + if (bufferOffset % minTexelBufferOffsetAlignment != 0) + { + bufferOffset += (minTexelBufferOffsetAlignment - (bufferOffset % minTexelBufferOffsetAlignment)); + } + if (_bufferHandle == buffer.Handle && - _offset == buffer.Offset && + _offset == bufferOffset && _size == buffer.Size && _bufferCount == _gd.BufferManager.BufferCount) { @@ -111,7 +133,7 @@ namespace Ryujinx.Graphics.Vulkan } _bufferHandle = buffer.Handle; - _offset = buffer.Offset; + _offset = bufferOffset; _size = buffer.Size; _bufferCount = _gd.BufferManager.BufferCount; @@ -120,6 +142,13 @@ namespace Ryujinx.Graphics.Vulkan public BufferView GetBufferView(CommandBufferScoped cbs, bool write) { + int minTexelBufferOffsetAlignment = (int)_gd.Capabilities.MinTexelBufferAlignment; + + if (_offset % minTexelBufferOffsetAlignment != 0) + { + _offset += (minTexelBufferOffsetAlignment - (_offset % minTexelBufferOffsetAlignment)); + } + _bufferView ??= _gd.BufferManager.CreateView(_bufferHandle, VkFormat, _offset, _size, ReleaseImpl); return _bufferView?.Get(cbs, _offset, _size, write).Value ?? default; diff --git a/src/Ryujinx.Graphics.Vulkan/VulkanRenderer.cs b/src/Ryujinx.Graphics.Vulkan/VulkanRenderer.cs index 4875b9265..5a50dd6c3 100644 --- a/src/Ryujinx.Graphics.Vulkan/VulkanRenderer.cs +++ b/src/Ryujinx.Graphics.Vulkan/VulkanRenderer.cs @@ -446,7 +446,8 @@ namespace Ryujinx.Graphics.Vulkan portabilityFlags, vertexBufferAlignment, properties.Limits.SubTexelPrecisionBits, - minResourceAlignment); + minResourceAlignment, + _physicalDevice.PhysicalDeviceProperties.Limits.MinTexelBufferOffsetAlignment); IsSharedMemory = MemoryAllocator.IsDeviceMemoryShared(_physicalDevice);