From 4258d515e69d5f2d40301a1d1592304c12fd8126 Mon Sep 17 00:00:00 2001 From: Fernando Sahmkow Date: Sat, 29 Jan 2022 22:00:49 +0100 Subject: Rasterizer: Implement Inline2Memory Acceleration. --- src/video_core/buffer_cache/buffer_cache.h | 46 ++++++++++++++++++++++++++++-- 1 file changed, 43 insertions(+), 3 deletions(-) (limited to 'src/video_core/buffer_cache') diff --git a/src/video_core/buffer_cache/buffer_cache.h b/src/video_core/buffer_cache/buffer_cache.h index 048dba4f3..792c3820a 100644 --- a/src/video_core/buffer_cache/buffer_cache.h +++ b/src/video_core/buffer_cache/buffer_cache.h @@ -131,6 +131,8 @@ public: void DownloadMemory(VAddr cpu_addr, u64 size); + bool InlineMemory(VAddr dest_address, size_t copy_size, std::span inlined_buffer); + void BindGraphicsUniformBuffer(size_t stage, u32 index, GPUVAddr gpu_addr, u32 size); void DisableGraphicsUniformBuffer(size_t stage, u32 index); @@ -808,6 +810,8 @@ void BufferCache

::CommitAsyncFlushesHigh() { return; } MICROPROFILE_SCOPE(GPU_DownloadMemory); + const bool is_accuracy_normal = + Settings::values.gpu_accuracy.GetValue() == Settings::GPUAccuracy::Normal; boost::container::small_vector, 1> downloads; u64 total_size_bytes = 0; @@ -819,6 +823,9 @@ void BufferCache

::CommitAsyncFlushesHigh() { ForEachBufferInRange(cpu_addr, size, [&](BufferId buffer_id, Buffer& buffer) { buffer.ForEachDownloadRangeAndClear( cpu_addr, size, [&](u64 range_offset, u64 range_size) { + if (is_accuracy_normal) { + return; + } const VAddr buffer_addr = buffer.CpuAddr(); const auto add_download = [&](VAddr start, VAddr end) { const u64 new_offset = start - buffer_addr; @@ -1417,10 +1424,8 @@ void BufferCache

::MarkWrittenBuffer(BufferId buffer_id, VAddr cpu_addr, u32 s const IntervalType base_interval{cpu_addr, cpu_addr + size}; common_ranges.add(base_interval); - const bool is_accuracy_high = - Settings::values.gpu_accuracy.GetValue() == Settings::GPUAccuracy::High; const bool is_async = Settings::values.use_asynchronous_gpu_emulation.GetValue(); - if (!is_async && !is_accuracy_high) { + if (!is_async) { return; } uncommitted_ranges.add(base_interval); @@ -1643,6 +1648,41 @@ void BufferCache

::MappedUploadMemory(Buffer& buffer, u64 total_size_bytes, runtime.CopyBuffer(buffer, upload_staging.buffer, copies); } +template +bool BufferCache

::InlineMemory(VAddr dest_address, size_t copy_size, + std::span inlined_buffer) { + const bool is_dirty = IsRegionRegistered(dest_address, copy_size); + if (!is_dirty) { + return false; + } + if (!IsRegionGpuModified(dest_address, copy_size)) { + return false; + } + + const IntervalType subtract_interval{dest_address, dest_address + copy_size}; + ClearDownload(subtract_interval); + + BufferId buffer_id = FindBuffer(dest_address, static_cast(copy_size)); + auto& buffer = slot_buffers[buffer_id]; + SynchronizeBuffer(buffer, dest_address, static_cast(copy_size)); + + if constexpr (USE_MEMORY_MAPS) { + std::array copies{BufferCopy{ + .src_offset = 0, + .dst_offset = buffer.Offset(dest_address), + .size = copy_size, + }}; + auto upload_staging = runtime.UploadStagingBuffer(copy_size); + u8* const src_pointer = upload_staging.mapped_span.data(); + std::memcpy(src_pointer, inlined_buffer.data(), copy_size); + runtime.CopyBuffer(buffer, upload_staging.buffer, copies); + } else { + buffer.ImmediateUpload(buffer.Offset(dest_address), inlined_buffer); + } + + return true; +} + template void BufferCache

::DownloadBufferMemory(Buffer& buffer) { DownloadBufferMemory(buffer, buffer.CpuAddr(), buffer.SizeBytes()); -- cgit v1.2.3 From 8a6e6465a7bb4efe5d2925fcaf7e0df19f91e6de Mon Sep 17 00:00:00 2001 From: Fernando Sahmkow Date: Mon, 31 Jan 2022 23:41:29 +0100 Subject: Rasterizer: Refactor inlineToMemory. --- src/video_core/buffer_cache/buffer_cache.h | 3 ++- src/video_core/engines/engine_upload.cpp | 2 +- src/video_core/engines/maxwell_3d.h | 2 +- src/video_core/gpu.cpp | 6 ++---- src/video_core/rasterizer_interface.h | 4 ++-- src/video_core/renderer_opengl/gl_rasterizer.cpp | 4 ++-- src/video_core/renderer_opengl/gl_rasterizer.h | 3 ++- src/video_core/renderer_vulkan/vk_rasterizer.cpp | 4 ++-- src/video_core/renderer_vulkan/vk_rasterizer.h | 3 ++- 9 files changed, 16 insertions(+), 15 deletions(-) (limited to 'src/video_core/buffer_cache') diff --git a/src/video_core/buffer_cache/buffer_cache.h b/src/video_core/buffer_cache/buffer_cache.h index 792c3820a..fa26eb8b0 100644 --- a/src/video_core/buffer_cache/buffer_cache.h +++ b/src/video_core/buffer_cache/buffer_cache.h @@ -1661,6 +1661,7 @@ bool BufferCache

::InlineMemory(VAddr dest_address, size_t copy_size, const IntervalType subtract_interval{dest_address, dest_address + copy_size}; ClearDownload(subtract_interval); + common_ranges.subtract(subtract_interval); BufferId buffer_id = FindBuffer(dest_address, static_cast(copy_size)); auto& buffer = slot_buffers[buffer_id]; @@ -1677,7 +1678,7 @@ bool BufferCache

::InlineMemory(VAddr dest_address, size_t copy_size, std::memcpy(src_pointer, inlined_buffer.data(), copy_size); runtime.CopyBuffer(buffer, upload_staging.buffer, copies); } else { - buffer.ImmediateUpload(buffer.Offset(dest_address), inlined_buffer); + buffer.ImmediateUpload(buffer.Offset(dest_address), inlined_buffer.first(copy_size)); } return true; diff --git a/src/video_core/engines/engine_upload.cpp b/src/video_core/engines/engine_upload.cpp index 4eb9a094d..351b110fe 100644 --- a/src/video_core/engines/engine_upload.cpp +++ b/src/video_core/engines/engine_upload.cpp @@ -37,7 +37,7 @@ void State::ProcessData(const u32 data, const bool is_last_call) { } const GPUVAddr address{regs.dest.Address()}; if (is_linear) { - rasterizer->AccelerateInline2Memory(address, copy_size, inner_buffer); + rasterizer->AccelerateInlineToMemory(address, copy_size, inner_buffer); } else { UNIMPLEMENTED_IF(regs.dest.z != 0); UNIMPLEMENTED_IF(regs.dest.depth != 1); diff --git a/src/video_core/engines/maxwell_3d.h b/src/video_core/engines/maxwell_3d.h index e0a435c45..dc9df6c8b 100644 --- a/src/video_core/engines/maxwell_3d.h +++ b/src/video_core/engines/maxwell_3d.h @@ -1557,7 +1557,7 @@ private: static constexpr u32 null_cb_data = 0xFFFFFFFF; struct CBDataState { - static constexpr size_t inline_size = 0x8000; + static constexpr size_t inline_size = 0x4000; std::array, 16> buffer; u32 current{null_cb_data}; u32 id{null_cb_data}; diff --git a/src/video_core/gpu.cpp b/src/video_core/gpu.cpp index 191b97dbf..ba9ba082f 100644 --- a/src/video_core/gpu.cpp +++ b/src/video_core/gpu.cpp @@ -504,14 +504,12 @@ struct GPU::Impl { case BufferMethods::SemaphoreAddressLow: case BufferMethods::SemaphoreSequence: break; - case BufferMethods::UnkCacheFlush: { + case BufferMethods::UnkCacheFlush: rasterizer->SyncGuestHost(); break; - } - case BufferMethods::WrcacheFlush: { + case BufferMethods::WrcacheFlush: rasterizer->SignalReference(); break; - } case BufferMethods::FenceValue: break; case BufferMethods::RefCnt: diff --git a/src/video_core/rasterizer_interface.h b/src/video_core/rasterizer_interface.h index 78e6e566f..1f1f12291 100644 --- a/src/video_core/rasterizer_interface.h +++ b/src/video_core/rasterizer_interface.h @@ -123,8 +123,8 @@ public: [[nodiscard]] virtual Tegra::Engines::AccelerateDMAInterface& AccessAccelerateDMA() = 0; - virtual void AccelerateInline2Memory(GPUVAddr address, size_t copy_size, - std::span memory) = 0; + virtual void AccelerateInlineToMemory(GPUVAddr address, size_t copy_size, + std::span memory) = 0; /// Attempt to use a faster method to display the framebuffer to screen [[nodiscard]] virtual bool AccelerateDisplay(const Tegra::FramebufferConfig& config, diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index 57a6ff752..142412a8e 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -484,8 +484,8 @@ Tegra::Engines::AccelerateDMAInterface& RasterizerOpenGL::AccessAccelerateDMA() return accelerate_dma; } -void RasterizerOpenGL::AccelerateInline2Memory(GPUVAddr address, size_t copy_size, - std::span memory) { +void RasterizerOpenGL::AccelerateInlineToMemory(GPUVAddr address, size_t copy_size, + std::span memory) { auto cpu_addr = gpu_memory.GpuToCpuAddress(address); if (!cpu_addr) [[unlikely]] { gpu_memory.WriteBlock(address, memory.data(), copy_size); diff --git a/src/video_core/renderer_opengl/gl_rasterizer.h b/src/video_core/renderer_opengl/gl_rasterizer.h index dd97c279b..98f6fd342 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.h +++ b/src/video_core/renderer_opengl/gl_rasterizer.h @@ -106,7 +106,8 @@ public: const Tegra::Engines::Fermi2D::Surface& dst, const Tegra::Engines::Fermi2D::Config& copy_config) override; Tegra::Engines::AccelerateDMAInterface& AccessAccelerateDMA() override; - void AccelerateInline2Memory(GPUVAddr address, size_t copy_size, std::span memory) override; + void AccelerateInlineToMemory(GPUVAddr address, size_t copy_size, + std::span memory) override; bool AccelerateDisplay(const Tegra::FramebufferConfig& config, VAddr framebuffer_addr, u32 pixel_stride) override; void LoadDiskResources(u64 title_id, std::stop_token stop_loading, diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.cpp b/src/video_core/renderer_vulkan/vk_rasterizer.cpp index 65c5fd63f..2227d9197 100644 --- a/src/video_core/renderer_vulkan/vk_rasterizer.cpp +++ b/src/video_core/renderer_vulkan/vk_rasterizer.cpp @@ -548,8 +548,8 @@ Tegra::Engines::AccelerateDMAInterface& RasterizerVulkan::AccessAccelerateDMA() return accelerate_dma; } -void RasterizerVulkan::AccelerateInline2Memory(GPUVAddr address, size_t copy_size, - std::span memory) { +void RasterizerVulkan::AccelerateInlineToMemory(GPUVAddr address, size_t copy_size, + std::span memory) { auto cpu_addr = gpu_memory.GpuToCpuAddress(address); if (!cpu_addr) [[unlikely]] { gpu_memory.WriteBlock(address, memory.data(), copy_size); diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.h b/src/video_core/renderer_vulkan/vk_rasterizer.h index bbd79aae4..5af2e275b 100644 --- a/src/video_core/renderer_vulkan/vk_rasterizer.h +++ b/src/video_core/renderer_vulkan/vk_rasterizer.h @@ -99,7 +99,8 @@ public: const Tegra::Engines::Fermi2D::Surface& dst, const Tegra::Engines::Fermi2D::Config& copy_config) override; Tegra::Engines::AccelerateDMAInterface& AccessAccelerateDMA() override; - void AccelerateInline2Memory(GPUVAddr address, size_t copy_size, std::span memory) override; + void AccelerateInlineToMemory(GPUVAddr address, size_t copy_size, + std::span memory) override; bool AccelerateDisplay(const Tegra::FramebufferConfig& config, VAddr framebuffer_addr, u32 pixel_stride) override; void LoadDiskResources(u64 title_id, std::stop_token stop_loading, -- cgit v1.2.3