diff --git a/src/video_core/renderer_vulkan/vk_compute_pipeline.cpp b/src/video_core/renderer_vulkan/vk_compute_pipeline.cpp index 7d1a980c..0d59d13f 100644 --- a/src/video_core/renderer_vulkan/vk_compute_pipeline.cpp +++ b/src/video_core/renderer_vulkan/vk_compute_pipeline.cpp @@ -95,8 +95,9 @@ void ComputePipeline::BindResources(Core::MemoryManager* memory, StreamBuffer& s const u32 size = vsharp.GetSize(); const VAddr addr = vsharp.base_address.Value(); texture_cache.OnCpuWrite(addr); - const u32 offset = - staging.Copy(addr, size, buffer.is_storage ? 4 : instance.UniformMinAlignment()); + const u32 offset = staging.Copy(addr, size, + buffer.is_storage ? instance.StorageMinAlignment() + : instance.UniformMinAlignment()); // const auto [vk_buffer, offset] = memory->GetVulkanBuffer(addr); buffer_infos.emplace_back(staging.Handle(), offset, size); set_writes.push_back({ diff --git a/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp b/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp index 4a811eba..8a74b7d1 100644 --- a/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp +++ b/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp @@ -327,7 +327,8 @@ void GraphicsPipeline::BindResources(Core::MemoryManager* memory, StreamBuffer& const auto vsharp = stage.ReadUd(buffer.sgpr_base, buffer.dword_offset); const u32 size = vsharp.GetSize(); const u32 offset = staging.Copy(vsharp.base_address.Value(), size, - buffer.is_storage ? 4 : instance.UniformMinAlignment()); + buffer.is_storage ? instance.StorageMinAlignment() + : instance.UniformMinAlignment()); buffer_infos.emplace_back(staging.Handle(), offset, size); set_writes.push_back({ .dstSet = VK_NULL_HANDLE, diff --git a/src/video_core/renderer_vulkan/vk_instance.cpp b/src/video_core/renderer_vulkan/vk_instance.cpp index 06a47675..afaf3005 100644 --- a/src/video_core/renderer_vulkan/vk_instance.cpp +++ b/src/video_core/renderer_vulkan/vk_instance.cpp @@ -213,6 +213,7 @@ bool Instance::CreateDevice() { }, vk::PhysicalDeviceVulkan12Features{ .scalarBlockLayout = true, + .uniformBufferStandardLayout = true, .hostQueryReset = true, .timelineSemaphore = true, }, diff --git a/src/video_core/renderer_vulkan/vk_instance.h b/src/video_core/renderer_vulkan/vk_instance.h index f8e3c2e9..ad6196ab 100644 --- a/src/video_core/renderer_vulkan/vk_instance.h +++ b/src/video_core/renderer_vulkan/vk_instance.h @@ -169,6 +169,11 @@ public: return properties.limits.minUniformBufferOffsetAlignment; } + /// Returns the minimum required alignment for storage buffers + vk::DeviceSize StorageMinAlignment() const { + return properties.limits.minStorageBufferOffsetAlignment; + } + /// Returns the minimum alignemt required for accessing host-mapped device memory vk::DeviceSize NonCoherentAtomSize() const { return properties.limits.nonCoherentAtomSize; diff --git a/src/video_core/texture_cache/tile_manager.cpp b/src/video_core/texture_cache/tile_manager.cpp index 36e1d1e1..723487a6 100644 --- a/src/video_core/texture_cache/tile_manager.cpp +++ b/src/video_core/texture_cache/tile_manager.cpp @@ -315,7 +315,8 @@ bool TileManager::TryDetile(Image& image) { return false; } - const auto offset = staging.Copy(image.cpu_addr, image.info.guest_size_bytes, 4); + const auto offset = + staging.Copy(image.cpu_addr, image.info.guest_size_bytes, instance.StorageMinAlignment()); image.Transit(vk::ImageLayout::eGeneral, vk::AccessFlagBits::eShaderWrite); auto cmdbuf = scheduler.CommandBuffer();