diff options
Diffstat (limited to 'src/video_core')
6 files changed, 29 insertions, 5 deletions
diff --git a/src/video_core/buffer_cache/buffer_cache.h b/src/video_core/buffer_cache/buffer_cache.h index 90dbd352f..6d1fc3887 100644 --- a/src/video_core/buffer_cache/buffer_cache.h +++ b/src/video_core/buffer_cache/buffer_cache.h @@ -1753,15 +1753,25 @@ Binding BufferCache<P>::StorageBufferBinding(GPUVAddr ssbo_addr, u32 cbuf_index,          const u32 memory_layout_size = static_cast<u32>(gpu_memory->GetMemoryLayoutSize(gpu_addr));          return std::min(memory_layout_size, static_cast<u32>(8_MiB));      }(); -    const std::optional<VAddr> cpu_addr = gpu_memory->GpuToCpuAddress(gpu_addr); -    if (!cpu_addr || size == 0) { +    // Alignment only applies to the offset of the buffer +    const u32 alignment = runtime.GetStorageBufferAlignment(); +    const GPUVAddr aligned_gpu_addr = Common::AlignDown(gpu_addr, alignment); +    const u32 aligned_size = static_cast<u32>(gpu_addr - aligned_gpu_addr) + size; + +    const std::optional<VAddr> aligned_cpu_addr = gpu_memory->GpuToCpuAddress(aligned_gpu_addr); +    if (!aligned_cpu_addr || size == 0) {          LOG_WARNING(HW_GPU, "Failed to find storage buffer for cbuf index {}", cbuf_index);          return NULL_BINDING;      } -    const VAddr cpu_end = Common::AlignUp(*cpu_addr + size, YUZU_PAGESIZE); +    const std::optional<VAddr> cpu_addr = gpu_memory->GpuToCpuAddress(gpu_addr); +    ASSERT_MSG(cpu_addr, "Unaligned storage buffer address not found for cbuf index {}", +               cbuf_index); +    // The end address used for size calculation does not need to be aligned +    const VAddr cpu_end = Common::AlignUp(*cpu_addr + size, Core::Memory::YUZU_PAGESIZE); +      const Binding binding{ -        .cpu_addr = *cpu_addr, -        .size = is_written ? size : static_cast<u32>(cpu_end - *cpu_addr), +        .cpu_addr = *aligned_cpu_addr, +        .size = is_written ? aligned_size : static_cast<u32>(cpu_end - *aligned_cpu_addr),          .buffer_id = BufferId{},      };      return binding; diff --git a/src/video_core/renderer_opengl/gl_buffer_cache.h b/src/video_core/renderer_opengl/gl_buffer_cache.h index feccf06f9..000f29a82 100644 --- a/src/video_core/renderer_opengl/gl_buffer_cache.h +++ b/src/video_core/renderer_opengl/gl_buffer_cache.h @@ -191,6 +191,10 @@ public:          return device.CanReportMemoryUsage();      } +    u32 GetStorageBufferAlignment() const { +        return static_cast<u32>(device.GetShaderStorageBufferAlignment()); +    } +  private:      static constexpr std::array PABO_LUT{          GL_VERTEX_PROGRAM_PARAMETER_BUFFER_NV,          GL_TESS_CONTROL_PROGRAM_PARAMETER_BUFFER_NV, diff --git a/src/video_core/renderer_opengl/gl_shader_cache.cpp b/src/video_core/renderer_opengl/gl_shader_cache.cpp index 2888e0238..26f2d0ea7 100644 --- a/src/video_core/renderer_opengl/gl_shader_cache.cpp +++ b/src/video_core/renderer_opengl/gl_shader_cache.cpp @@ -232,6 +232,7 @@ ShaderCache::ShaderCache(RasterizerOpenGL& rasterizer_, Core::Frontend::EmuWindo            .has_gl_bool_ref_bug = device.HasBoolRefBug(),            .ignore_nan_fp_comparisons = true,            .gl_max_compute_smem_size = device.GetMaxComputeSharedMemorySize(), +          .min_ssbo_alignment = device.GetShaderStorageBufferAlignment(),        },        host_info{            .support_float64 = true, @@ -240,6 +241,7 @@ ShaderCache::ShaderCache(RasterizerOpenGL& rasterizer_, Core::Frontend::EmuWindo            .needs_demote_reorder = device.IsAmd(),            .support_snorm_render_buffer = false,            .support_viewport_index_layer = device.HasVertexViewportLayer(), +          .min_ssbo_alignment = static_cast<u32>(device.GetShaderStorageBufferAlignment()),            .support_geometry_shader_passthrough = device.HasGeometryShaderPassthrough(),            .support_conditional_barrier = device.SupportsConditionalBarriers(),        } { diff --git a/src/video_core/renderer_vulkan/vk_buffer_cache.cpp b/src/video_core/renderer_vulkan/vk_buffer_cache.cpp index 7691cc2ba..5958f52f7 100644 --- a/src/video_core/renderer_vulkan/vk_buffer_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_buffer_cache.cpp @@ -355,6 +355,10 @@ bool BufferCacheRuntime::CanReportMemoryUsage() const {      return device.CanReportMemoryUsage();  } +u32 BufferCacheRuntime::GetStorageBufferAlignment() const { +    return static_cast<u32>(device.GetStorageBufferAlignment()); +} +  void BufferCacheRuntime::TickFrame(VideoCommon::SlotVector<Buffer>& slot_buffers) noexcept {      for (auto it = slot_buffers.begin(); it != slot_buffers.end(); it++) {          it->ResetUsageTracking(); diff --git a/src/video_core/renderer_vulkan/vk_buffer_cache.h b/src/video_core/renderer_vulkan/vk_buffer_cache.h index 4416a902f..0b3fbd6d0 100644 --- a/src/video_core/renderer_vulkan/vk_buffer_cache.h +++ b/src/video_core/renderer_vulkan/vk_buffer_cache.h @@ -91,6 +91,8 @@ public:      bool CanReportMemoryUsage() const; +    u32 GetStorageBufferAlignment() const; +      [[nodiscard]] StagingBufferRef UploadStagingBuffer(size_t size);      [[nodiscard]] StagingBufferRef DownloadStagingBuffer(size_t size, bool deferred = false); diff --git a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp index 89b455bff..2a13b2a72 100644 --- a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp @@ -373,6 +373,7 @@ PipelineCache::PipelineCache(RasterizerVulkan& rasterizer_, const Device& device              driver_id == VK_DRIVER_ID_QUALCOMM_PROPRIETARY,          .has_broken_robust =              device.IsNvidia() && device.GetNvidiaArch() <= NvidiaArchitecture::Arch_Pascal, +        .min_ssbo_alignment = device.GetStorageBufferAlignment(),      };      host_info = Shader::HostTranslateInfo{ @@ -383,6 +384,7 @@ PipelineCache::PipelineCache(RasterizerVulkan& rasterizer_, const Device& device              driver_id == VK_DRIVER_ID_AMD_PROPRIETARY || driver_id == VK_DRIVER_ID_AMD_OPEN_SOURCE,          .support_snorm_render_buffer = true,          .support_viewport_index_layer = device.IsExtShaderViewportIndexLayerSupported(), +        .min_ssbo_alignment = static_cast<u32>(device.GetStorageBufferAlignment()),          .support_geometry_shader_passthrough = device.IsNvGeometryShaderPassthroughSupported(),          .support_conditional_barrier = device.SupportsConditionalBarriers(),      };  | 
