From 59c277bc6c39b66920837b65a8fba008cd7c85e1 Mon Sep 17 00:00:00 2001 From: sunshineinabox Date: Fri, 22 Nov 2024 06:48:08 -0800 Subject: [PATCH] Vulkan: Buffer alignment --- .../HardwareCapabilities.cs | 5 ++- src/Ryujinx.Graphics.Vulkan/TextureBuffer.cs | 33 +++++++++++++++++-- src/Ryujinx.Graphics.Vulkan/VulkanRenderer.cs | 3 +- 3 files changed, 37 insertions(+), 4 deletions(-) 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 9419b0825..bdb339bfc 100644 --- a/src/Ryujinx.Graphics.Vulkan/VulkanRenderer.cs +++ b/src/Ryujinx.Graphics.Vulkan/VulkanRenderer.cs @@ -455,7 +455,8 @@ namespace Ryujinx.Graphics.Vulkan portabilityFlags, vertexBufferAlignment, properties.Limits.SubTexelPrecisionBits, - minResourceAlignment); + minResourceAlignment, + _physicalDevice.PhysicalDeviceProperties.Limits.MinTexelBufferOffsetAlignment); IsSharedMemory = MemoryAllocator.IsDeviceMemoryShared(_physicalDevice);