summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/core/hle/kernel/svc.cpp2
-rw-r--r--src/video_core/buffer_cache/buffer_cache.h47
-rw-r--r--src/video_core/engines/engine_upload.cpp7
-rw-r--r--src/video_core/engines/engine_upload.h8
-rw-r--r--src/video_core/engines/kepler_compute.cpp1
-rw-r--r--src/video_core/engines/kepler_memory.cpp4
-rw-r--r--src/video_core/engines/kepler_memory.h7
-rw-r--r--src/video_core/engines/maxwell_3d.cpp1
-rw-r--r--src/video_core/engines/maxwell_3d.h3
-rw-r--r--src/video_core/gpu.cpp8
-rw-r--r--src/video_core/memory_manager.h4
-rw-r--r--src/video_core/rasterizer_interface.h3
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.cpp22
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.h2
-rw-r--r--src/video_core/renderer_vulkan/vk_rasterizer.cpp22
-rw-r--r--src/video_core/renderer_vulkan/vk_rasterizer.h2
-rw-r--r--src/video_core/shader_cache.cpp4
-rw-r--r--src/video_core/shader_cache.h3
18 files changed, 137 insertions, 13 deletions
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp
index 40bb893ac..4f7aebf3f 100644
--- a/src/core/hle/kernel/svc.cpp
+++ b/src/core/hle/kernel/svc.cpp
@@ -2613,7 +2613,7 @@ static const FunctionDef SVC_Table_32[] = {
2613 {0x33, SvcWrap32<GetThreadContext32>, "GetThreadContext32"}, 2613 {0x33, SvcWrap32<GetThreadContext32>, "GetThreadContext32"},
2614 {0x34, SvcWrap32<WaitForAddress32>, "WaitForAddress32"}, 2614 {0x34, SvcWrap32<WaitForAddress32>, "WaitForAddress32"},
2615 {0x35, SvcWrap32<SignalToAddress32>, "SignalToAddress32"}, 2615 {0x35, SvcWrap32<SignalToAddress32>, "SignalToAddress32"},
2616 {0x36, nullptr, "Unknown"}, 2616 {0x36, SvcWrap32<SynchronizePreemptionState>, "SynchronizePreemptionState32"},
2617 {0x37, nullptr, "Unknown"}, 2617 {0x37, nullptr, "Unknown"},
2618 {0x38, nullptr, "Unknown"}, 2618 {0x38, nullptr, "Unknown"},
2619 {0x39, nullptr, "Unknown"}, 2619 {0x39, nullptr, "Unknown"},
diff --git a/src/video_core/buffer_cache/buffer_cache.h b/src/video_core/buffer_cache/buffer_cache.h
index 048dba4f3..fa26eb8b0 100644
--- a/src/video_core/buffer_cache/buffer_cache.h
+++ b/src/video_core/buffer_cache/buffer_cache.h
@@ -131,6 +131,8 @@ public:
131 131
132 void DownloadMemory(VAddr cpu_addr, u64 size); 132 void DownloadMemory(VAddr cpu_addr, u64 size);
133 133
134 bool InlineMemory(VAddr dest_address, size_t copy_size, std::span<u8> inlined_buffer);
135
134 void BindGraphicsUniformBuffer(size_t stage, u32 index, GPUVAddr gpu_addr, u32 size); 136 void BindGraphicsUniformBuffer(size_t stage, u32 index, GPUVAddr gpu_addr, u32 size);
135 137
136 void DisableGraphicsUniformBuffer(size_t stage, u32 index); 138 void DisableGraphicsUniformBuffer(size_t stage, u32 index);
@@ -808,6 +810,8 @@ void BufferCache<P>::CommitAsyncFlushesHigh() {
808 return; 810 return;
809 } 811 }
810 MICROPROFILE_SCOPE(GPU_DownloadMemory); 812 MICROPROFILE_SCOPE(GPU_DownloadMemory);
813 const bool is_accuracy_normal =
814 Settings::values.gpu_accuracy.GetValue() == Settings::GPUAccuracy::Normal;
811 815
812 boost::container::small_vector<std::pair<BufferCopy, BufferId>, 1> downloads; 816 boost::container::small_vector<std::pair<BufferCopy, BufferId>, 1> downloads;
813 u64 total_size_bytes = 0; 817 u64 total_size_bytes = 0;
@@ -819,6 +823,9 @@ void BufferCache<P>::CommitAsyncFlushesHigh() {
819 ForEachBufferInRange(cpu_addr, size, [&](BufferId buffer_id, Buffer& buffer) { 823 ForEachBufferInRange(cpu_addr, size, [&](BufferId buffer_id, Buffer& buffer) {
820 buffer.ForEachDownloadRangeAndClear( 824 buffer.ForEachDownloadRangeAndClear(
821 cpu_addr, size, [&](u64 range_offset, u64 range_size) { 825 cpu_addr, size, [&](u64 range_offset, u64 range_size) {
826 if (is_accuracy_normal) {
827 return;
828 }
822 const VAddr buffer_addr = buffer.CpuAddr(); 829 const VAddr buffer_addr = buffer.CpuAddr();
823 const auto add_download = [&](VAddr start, VAddr end) { 830 const auto add_download = [&](VAddr start, VAddr end) {
824 const u64 new_offset = start - buffer_addr; 831 const u64 new_offset = start - buffer_addr;
@@ -1417,10 +1424,8 @@ void BufferCache<P>::MarkWrittenBuffer(BufferId buffer_id, VAddr cpu_addr, u32 s
1417 const IntervalType base_interval{cpu_addr, cpu_addr + size}; 1424 const IntervalType base_interval{cpu_addr, cpu_addr + size};
1418 common_ranges.add(base_interval); 1425 common_ranges.add(base_interval);
1419 1426
1420 const bool is_accuracy_high =
1421 Settings::values.gpu_accuracy.GetValue() == Settings::GPUAccuracy::High;
1422 const bool is_async = Settings::values.use_asynchronous_gpu_emulation.GetValue(); 1427 const bool is_async = Settings::values.use_asynchronous_gpu_emulation.GetValue();
1423 if (!is_async && !is_accuracy_high) { 1428 if (!is_async) {
1424 return; 1429 return;
1425 } 1430 }
1426 uncommitted_ranges.add(base_interval); 1431 uncommitted_ranges.add(base_interval);
@@ -1644,6 +1649,42 @@ void BufferCache<P>::MappedUploadMemory(Buffer& buffer, u64 total_size_bytes,
1644} 1649}
1645 1650
1646template <class P> 1651template <class P>
1652bool BufferCache<P>::InlineMemory(VAddr dest_address, size_t copy_size,
1653 std::span<u8> inlined_buffer) {
1654 const bool is_dirty = IsRegionRegistered(dest_address, copy_size);
1655 if (!is_dirty) {
1656 return false;
1657 }
1658 if (!IsRegionGpuModified(dest_address, copy_size)) {
1659 return false;
1660 }
1661
1662 const IntervalType subtract_interval{dest_address, dest_address + copy_size};
1663 ClearDownload(subtract_interval);
1664 common_ranges.subtract(subtract_interval);
1665
1666 BufferId buffer_id = FindBuffer(dest_address, static_cast<u32>(copy_size));
1667 auto& buffer = slot_buffers[buffer_id];
1668 SynchronizeBuffer(buffer, dest_address, static_cast<u32>(copy_size));
1669
1670 if constexpr (USE_MEMORY_MAPS) {
1671 std::array copies{BufferCopy{
1672 .src_offset = 0,
1673 .dst_offset = buffer.Offset(dest_address),
1674 .size = copy_size,
1675 }};
1676 auto upload_staging = runtime.UploadStagingBuffer(copy_size);
1677 u8* const src_pointer = upload_staging.mapped_span.data();
1678 std::memcpy(src_pointer, inlined_buffer.data(), copy_size);
1679 runtime.CopyBuffer(buffer, upload_staging.buffer, copies);
1680 } else {
1681 buffer.ImmediateUpload(buffer.Offset(dest_address), inlined_buffer.first(copy_size));
1682 }
1683
1684 return true;
1685}
1686
1687template <class P>
1647void BufferCache<P>::DownloadBufferMemory(Buffer& buffer) { 1688void BufferCache<P>::DownloadBufferMemory(Buffer& buffer) {
1648 DownloadBufferMemory(buffer, buffer.CpuAddr(), buffer.SizeBytes()); 1689 DownloadBufferMemory(buffer, buffer.CpuAddr(), buffer.SizeBytes());
1649} 1690}
diff --git a/src/video_core/engines/engine_upload.cpp b/src/video_core/engines/engine_upload.cpp
index 71d7e1473..351b110fe 100644
--- a/src/video_core/engines/engine_upload.cpp
+++ b/src/video_core/engines/engine_upload.cpp
@@ -7,6 +7,7 @@
7#include "common/assert.h" 7#include "common/assert.h"
8#include "video_core/engines/engine_upload.h" 8#include "video_core/engines/engine_upload.h"
9#include "video_core/memory_manager.h" 9#include "video_core/memory_manager.h"
10#include "video_core/rasterizer_interface.h"
10#include "video_core/textures/decoders.h" 11#include "video_core/textures/decoders.h"
11 12
12namespace Tegra::Engines::Upload { 13namespace Tegra::Engines::Upload {
@@ -16,6 +17,10 @@ State::State(MemoryManager& memory_manager_, Registers& regs_)
16 17
17State::~State() = default; 18State::~State() = default;
18 19
20void State::BindRasterizer(VideoCore::RasterizerInterface* rasterizer_) {
21 rasterizer = rasterizer_;
22}
23
19void State::ProcessExec(const bool is_linear_) { 24void State::ProcessExec(const bool is_linear_) {
20 write_offset = 0; 25 write_offset = 0;
21 copy_size = regs.line_length_in * regs.line_count; 26 copy_size = regs.line_length_in * regs.line_count;
@@ -32,7 +37,7 @@ void State::ProcessData(const u32 data, const bool is_last_call) {
32 } 37 }
33 const GPUVAddr address{regs.dest.Address()}; 38 const GPUVAddr address{regs.dest.Address()};
34 if (is_linear) { 39 if (is_linear) {
35 memory_manager.WriteBlock(address, inner_buffer.data(), copy_size); 40 rasterizer->AccelerateInlineToMemory(address, copy_size, inner_buffer);
36 } else { 41 } else {
37 UNIMPLEMENTED_IF(regs.dest.z != 0); 42 UNIMPLEMENTED_IF(regs.dest.z != 0);
38 UNIMPLEMENTED_IF(regs.dest.depth != 1); 43 UNIMPLEMENTED_IF(regs.dest.depth != 1);
diff --git a/src/video_core/engines/engine_upload.h b/src/video_core/engines/engine_upload.h
index 1c7f1effa..c9c5ec8c3 100644
--- a/src/video_core/engines/engine_upload.h
+++ b/src/video_core/engines/engine_upload.h
@@ -12,6 +12,10 @@ namespace Tegra {
12class MemoryManager; 12class MemoryManager;
13} 13}
14 14
15namespace VideoCore {
16class RasterizerInterface;
17}
18
15namespace Tegra::Engines::Upload { 19namespace Tegra::Engines::Upload {
16 20
17struct Registers { 21struct Registers {
@@ -60,6 +64,9 @@ public:
60 void ProcessExec(bool is_linear_); 64 void ProcessExec(bool is_linear_);
61 void ProcessData(u32 data, bool is_last_call); 65 void ProcessData(u32 data, bool is_last_call);
62 66
67 /// Binds a rasterizer to this engine.
68 void BindRasterizer(VideoCore::RasterizerInterface* rasterizer);
69
63private: 70private:
64 u32 write_offset = 0; 71 u32 write_offset = 0;
65 u32 copy_size = 0; 72 u32 copy_size = 0;
@@ -68,6 +75,7 @@ private:
68 bool is_linear = false; 75 bool is_linear = false;
69 Registers& regs; 76 Registers& regs;
70 MemoryManager& memory_manager; 77 MemoryManager& memory_manager;
78 VideoCore::RasterizerInterface* rasterizer = nullptr;
71}; 79};
72 80
73} // namespace Tegra::Engines::Upload 81} // namespace Tegra::Engines::Upload
diff --git a/src/video_core/engines/kepler_compute.cpp b/src/video_core/engines/kepler_compute.cpp
index 492b4c5a3..5a1c12076 100644
--- a/src/video_core/engines/kepler_compute.cpp
+++ b/src/video_core/engines/kepler_compute.cpp
@@ -22,6 +22,7 @@ KeplerCompute::~KeplerCompute() = default;
22 22
23void KeplerCompute::BindRasterizer(VideoCore::RasterizerInterface* rasterizer_) { 23void KeplerCompute::BindRasterizer(VideoCore::RasterizerInterface* rasterizer_) {
24 rasterizer = rasterizer_; 24 rasterizer = rasterizer_;
25 upload_state.BindRasterizer(rasterizer);
25} 26}
26 27
27void KeplerCompute::CallMethod(u32 method, u32 method_argument, bool is_last_call) { 28void KeplerCompute::CallMethod(u32 method, u32 method_argument, bool is_last_call) {
diff --git a/src/video_core/engines/kepler_memory.cpp b/src/video_core/engines/kepler_memory.cpp
index 560551157..8aed16caa 100644
--- a/src/video_core/engines/kepler_memory.cpp
+++ b/src/video_core/engines/kepler_memory.cpp
@@ -19,6 +19,10 @@ KeplerMemory::KeplerMemory(Core::System& system_, MemoryManager& memory_manager)
19 19
20KeplerMemory::~KeplerMemory() = default; 20KeplerMemory::~KeplerMemory() = default;
21 21
22void KeplerMemory::BindRasterizer(VideoCore::RasterizerInterface* rasterizer_) {
23 upload_state.BindRasterizer(rasterizer_);
24}
25
22void KeplerMemory::CallMethod(u32 method, u32 method_argument, bool is_last_call) { 26void KeplerMemory::CallMethod(u32 method, u32 method_argument, bool is_last_call) {
23 ASSERT_MSG(method < Regs::NUM_REGS, 27 ASSERT_MSG(method < Regs::NUM_REGS,
24 "Invalid KeplerMemory register, increase the size of the Regs structure"); 28 "Invalid KeplerMemory register, increase the size of the Regs structure");
diff --git a/src/video_core/engines/kepler_memory.h b/src/video_core/engines/kepler_memory.h
index 0d8ea09a9..949e2fae1 100644
--- a/src/video_core/engines/kepler_memory.h
+++ b/src/video_core/engines/kepler_memory.h
@@ -22,6 +22,10 @@ namespace Tegra {
22class MemoryManager; 22class MemoryManager;
23} 23}
24 24
25namespace VideoCore {
26class RasterizerInterface;
27}
28
25namespace Tegra::Engines { 29namespace Tegra::Engines {
26 30
27/** 31/**
@@ -38,6 +42,9 @@ public:
38 explicit KeplerMemory(Core::System& system_, MemoryManager& memory_manager); 42 explicit KeplerMemory(Core::System& system_, MemoryManager& memory_manager);
39 ~KeplerMemory() override; 43 ~KeplerMemory() override;
40 44
45 /// Binds a rasterizer to this engine.
46 void BindRasterizer(VideoCore::RasterizerInterface* rasterizer);
47
41 /// Write the value to the register identified by method. 48 /// Write the value to the register identified by method.
42 void CallMethod(u32 method, u32 method_argument, bool is_last_call) override; 49 void CallMethod(u32 method, u32 method_argument, bool is_last_call) override;
43 50
diff --git a/src/video_core/engines/maxwell_3d.cpp b/src/video_core/engines/maxwell_3d.cpp
index c38ebd670..5d6d217bb 100644
--- a/src/video_core/engines/maxwell_3d.cpp
+++ b/src/video_core/engines/maxwell_3d.cpp
@@ -31,6 +31,7 @@ Maxwell3D::~Maxwell3D() = default;
31 31
32void Maxwell3D::BindRasterizer(VideoCore::RasterizerInterface* rasterizer_) { 32void Maxwell3D::BindRasterizer(VideoCore::RasterizerInterface* rasterizer_) {
33 rasterizer = rasterizer_; 33 rasterizer = rasterizer_;
34 upload_state.BindRasterizer(rasterizer_);
34} 35}
35 36
36void Maxwell3D::InitializeRegisterDefaults() { 37void Maxwell3D::InitializeRegisterDefaults() {
diff --git a/src/video_core/engines/maxwell_3d.h b/src/video_core/engines/maxwell_3d.h
index f22342dfb..dc9df6c8b 100644
--- a/src/video_core/engines/maxwell_3d.h
+++ b/src/video_core/engines/maxwell_3d.h
@@ -1557,7 +1557,8 @@ private:
1557 1557
1558 static constexpr u32 null_cb_data = 0xFFFFFFFF; 1558 static constexpr u32 null_cb_data = 0xFFFFFFFF;
1559 struct CBDataState { 1559 struct CBDataState {
1560 std::array<std::array<u32, 0x4000>, 16> buffer; 1560 static constexpr size_t inline_size = 0x4000;
1561 std::array<std::array<u32, inline_size>, 16> buffer;
1561 u32 current{null_cb_data}; 1562 u32 current{null_cb_data};
1562 u32 id{null_cb_data}; 1563 u32 id{null_cb_data};
1563 u32 start_pos{}; 1564 u32 start_pos{};
diff --git a/src/video_core/gpu.cpp b/src/video_core/gpu.cpp
index 705765c99..ba9ba082f 100644
--- a/src/video_core/gpu.cpp
+++ b/src/video_core/gpu.cpp
@@ -59,6 +59,7 @@ struct GPU::Impl {
59 maxwell_3d->BindRasterizer(rasterizer); 59 maxwell_3d->BindRasterizer(rasterizer);
60 fermi_2d->BindRasterizer(rasterizer); 60 fermi_2d->BindRasterizer(rasterizer);
61 kepler_compute->BindRasterizer(rasterizer); 61 kepler_compute->BindRasterizer(rasterizer);
62 kepler_memory->BindRasterizer(rasterizer);
62 maxwell_dma->BindRasterizer(rasterizer); 63 maxwell_dma->BindRasterizer(rasterizer);
63 } 64 }
64 65
@@ -502,8 +503,13 @@ struct GPU::Impl {
502 case BufferMethods::SemaphoreAddressHigh: 503 case BufferMethods::SemaphoreAddressHigh:
503 case BufferMethods::SemaphoreAddressLow: 504 case BufferMethods::SemaphoreAddressLow:
504 case BufferMethods::SemaphoreSequence: 505 case BufferMethods::SemaphoreSequence:
506 break;
505 case BufferMethods::UnkCacheFlush: 507 case BufferMethods::UnkCacheFlush:
508 rasterizer->SyncGuestHost();
509 break;
506 case BufferMethods::WrcacheFlush: 510 case BufferMethods::WrcacheFlush:
511 rasterizer->SignalReference();
512 break;
507 case BufferMethods::FenceValue: 513 case BufferMethods::FenceValue:
508 break; 514 break;
509 case BufferMethods::RefCnt: 515 case BufferMethods::RefCnt:
@@ -513,7 +519,7 @@ struct GPU::Impl {
513 ProcessFenceActionMethod(); 519 ProcessFenceActionMethod();
514 break; 520 break;
515 case BufferMethods::WaitForInterrupt: 521 case BufferMethods::WaitForInterrupt:
516 ProcessWaitForInterruptMethod(); 522 rasterizer->WaitForIdle();
517 break; 523 break;
518 case BufferMethods::SemaphoreTrigger: { 524 case BufferMethods::SemaphoreTrigger: {
519 ProcessSemaphoreTriggerMethod(); 525 ProcessSemaphoreTriggerMethod();
diff --git a/src/video_core/memory_manager.h b/src/video_core/memory_manager.h
index 38d8d9d74..61bfe47c7 100644
--- a/src/video_core/memory_manager.h
+++ b/src/video_core/memory_manager.h
@@ -143,6 +143,8 @@ public:
143 [[nodiscard]] GPUVAddr Allocate(std::size_t size, std::size_t align); 143 [[nodiscard]] GPUVAddr Allocate(std::size_t size, std::size_t align);
144 void Unmap(GPUVAddr gpu_addr, std::size_t size); 144 void Unmap(GPUVAddr gpu_addr, std::size_t size);
145 145
146 void FlushRegion(GPUVAddr gpu_addr, size_t size) const;
147
146private: 148private:
147 [[nodiscard]] PageEntry GetPageEntry(GPUVAddr gpu_addr) const; 149 [[nodiscard]] PageEntry GetPageEntry(GPUVAddr gpu_addr) const;
148 void SetPageEntry(GPUVAddr gpu_addr, PageEntry page_entry, std::size_t size = page_size); 150 void SetPageEntry(GPUVAddr gpu_addr, PageEntry page_entry, std::size_t size = page_size);
@@ -153,8 +155,6 @@ private:
153 void TryLockPage(PageEntry page_entry, std::size_t size); 155 void TryLockPage(PageEntry page_entry, std::size_t size);
154 void TryUnlockPage(PageEntry page_entry, std::size_t size); 156 void TryUnlockPage(PageEntry page_entry, std::size_t size);
155 157
156 void FlushRegion(GPUVAddr gpu_addr, size_t size) const;
157
158 void ReadBlockImpl(GPUVAddr gpu_src_addr, void* dest_buffer, std::size_t size, 158 void ReadBlockImpl(GPUVAddr gpu_src_addr, void* dest_buffer, std::size_t size,
159 bool is_safe) const; 159 bool is_safe) const;
160 void WriteBlockImpl(GPUVAddr gpu_dest_addr, const void* src_buffer, std::size_t size, 160 void WriteBlockImpl(GPUVAddr gpu_dest_addr, const void* src_buffer, std::size_t size,
diff --git a/src/video_core/rasterizer_interface.h b/src/video_core/rasterizer_interface.h
index b094fc064..1f1f12291 100644
--- a/src/video_core/rasterizer_interface.h
+++ b/src/video_core/rasterizer_interface.h
@@ -123,6 +123,9 @@ public:
123 123
124 [[nodiscard]] virtual Tegra::Engines::AccelerateDMAInterface& AccessAccelerateDMA() = 0; 124 [[nodiscard]] virtual Tegra::Engines::AccelerateDMAInterface& AccessAccelerateDMA() = 0;
125 125
126 virtual void AccelerateInlineToMemory(GPUVAddr address, size_t copy_size,
127 std::span<u8> memory) = 0;
128
126 /// Attempt to use a faster method to display the framebuffer to screen 129 /// Attempt to use a faster method to display the framebuffer to screen
127 [[nodiscard]] virtual bool AccelerateDisplay(const Tegra::FramebufferConfig& config, 130 [[nodiscard]] virtual bool AccelerateDisplay(const Tegra::FramebufferConfig& config,
128 VAddr framebuffer_addr, u32 pixel_stride) { 131 VAddr framebuffer_addr, u32 pixel_stride) {
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp
index 9b516c64f..142412a8e 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp
@@ -484,6 +484,28 @@ Tegra::Engines::AccelerateDMAInterface& RasterizerOpenGL::AccessAccelerateDMA()
484 return accelerate_dma; 484 return accelerate_dma;
485} 485}
486 486
487void RasterizerOpenGL::AccelerateInlineToMemory(GPUVAddr address, size_t copy_size,
488 std::span<u8> memory) {
489 auto cpu_addr = gpu_memory.GpuToCpuAddress(address);
490 if (!cpu_addr) [[unlikely]] {
491 gpu_memory.WriteBlock(address, memory.data(), copy_size);
492 return;
493 }
494 gpu_memory.WriteBlockUnsafe(address, memory.data(), copy_size);
495 {
496 std::unique_lock<std::mutex> lock{buffer_cache.mutex};
497 if (!buffer_cache.InlineMemory(*cpu_addr, copy_size, memory)) {
498 buffer_cache.WriteMemory(*cpu_addr, copy_size);
499 }
500 }
501 {
502 std::scoped_lock lock_texture{texture_cache.mutex};
503 texture_cache.WriteMemory(*cpu_addr, copy_size);
504 }
505 shader_cache.InvalidateRegion(*cpu_addr, copy_size);
506 query_cache.InvalidateRegion(*cpu_addr, copy_size);
507}
508
487bool RasterizerOpenGL::AccelerateDisplay(const Tegra::FramebufferConfig& config, 509bool RasterizerOpenGL::AccelerateDisplay(const Tegra::FramebufferConfig& config,
488 VAddr framebuffer_addr, u32 pixel_stride) { 510 VAddr framebuffer_addr, u32 pixel_stride) {
489 if (framebuffer_addr == 0) { 511 if (framebuffer_addr == 0) {
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.h b/src/video_core/renderer_opengl/gl_rasterizer.h
index d0397b745..98f6fd342 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.h
+++ b/src/video_core/renderer_opengl/gl_rasterizer.h
@@ -106,6 +106,8 @@ public:
106 const Tegra::Engines::Fermi2D::Surface& dst, 106 const Tegra::Engines::Fermi2D::Surface& dst,
107 const Tegra::Engines::Fermi2D::Config& copy_config) override; 107 const Tegra::Engines::Fermi2D::Config& copy_config) override;
108 Tegra::Engines::AccelerateDMAInterface& AccessAccelerateDMA() override; 108 Tegra::Engines::AccelerateDMAInterface& AccessAccelerateDMA() override;
109 void AccelerateInlineToMemory(GPUVAddr address, size_t copy_size,
110 std::span<u8> memory) override;
109 bool AccelerateDisplay(const Tegra::FramebufferConfig& config, VAddr framebuffer_addr, 111 bool AccelerateDisplay(const Tegra::FramebufferConfig& config, VAddr framebuffer_addr,
110 u32 pixel_stride) override; 112 u32 pixel_stride) override;
111 void LoadDiskResources(u64 title_id, std::stop_token stop_loading, 113 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 fd334a146..2227d9197 100644
--- a/src/video_core/renderer_vulkan/vk_rasterizer.cpp
+++ b/src/video_core/renderer_vulkan/vk_rasterizer.cpp
@@ -548,6 +548,28 @@ Tegra::Engines::AccelerateDMAInterface& RasterizerVulkan::AccessAccelerateDMA()
548 return accelerate_dma; 548 return accelerate_dma;
549} 549}
550 550
551void RasterizerVulkan::AccelerateInlineToMemory(GPUVAddr address, size_t copy_size,
552 std::span<u8> memory) {
553 auto cpu_addr = gpu_memory.GpuToCpuAddress(address);
554 if (!cpu_addr) [[unlikely]] {
555 gpu_memory.WriteBlock(address, memory.data(), copy_size);
556 return;
557 }
558 gpu_memory.WriteBlockUnsafe(address, memory.data(), copy_size);
559 {
560 std::unique_lock<std::mutex> lock{buffer_cache.mutex};
561 if (!buffer_cache.InlineMemory(*cpu_addr, copy_size, memory)) {
562 buffer_cache.WriteMemory(*cpu_addr, copy_size);
563 }
564 }
565 {
566 std::scoped_lock lock_texture{texture_cache.mutex};
567 texture_cache.WriteMemory(*cpu_addr, copy_size);
568 }
569 pipeline_cache.InvalidateRegion(*cpu_addr, copy_size);
570 query_cache.InvalidateRegion(*cpu_addr, copy_size);
571}
572
551bool RasterizerVulkan::AccelerateDisplay(const Tegra::FramebufferConfig& config, 573bool RasterizerVulkan::AccelerateDisplay(const Tegra::FramebufferConfig& config,
552 VAddr framebuffer_addr, u32 pixel_stride) { 574 VAddr framebuffer_addr, u32 pixel_stride) {
553 if (!framebuffer_addr) { 575 if (!framebuffer_addr) {
diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.h b/src/video_core/renderer_vulkan/vk_rasterizer.h
index 866827247..5af2e275b 100644
--- a/src/video_core/renderer_vulkan/vk_rasterizer.h
+++ b/src/video_core/renderer_vulkan/vk_rasterizer.h
@@ -99,6 +99,8 @@ public:
99 const Tegra::Engines::Fermi2D::Surface& dst, 99 const Tegra::Engines::Fermi2D::Surface& dst,
100 const Tegra::Engines::Fermi2D::Config& copy_config) override; 100 const Tegra::Engines::Fermi2D::Config& copy_config) override;
101 Tegra::Engines::AccelerateDMAInterface& AccessAccelerateDMA() override; 101 Tegra::Engines::AccelerateDMAInterface& AccessAccelerateDMA() override;
102 void AccelerateInlineToMemory(GPUVAddr address, size_t copy_size,
103 std::span<u8> memory) override;
102 bool AccelerateDisplay(const Tegra::FramebufferConfig& config, VAddr framebuffer_addr, 104 bool AccelerateDisplay(const Tegra::FramebufferConfig& config, VAddr framebuffer_addr,
103 u32 pixel_stride) override; 105 u32 pixel_stride) override;
104 void LoadDiskResources(u64 title_id, std::stop_token stop_loading, 106 void LoadDiskResources(u64 title_id, std::stop_token stop_loading,
diff --git a/src/video_core/shader_cache.cpp b/src/video_core/shader_cache.cpp
index 78bf90c48..87636857d 100644
--- a/src/video_core/shader_cache.cpp
+++ b/src/video_core/shader_cache.cpp
@@ -170,7 +170,7 @@ void ShaderCache::RemovePendingShaders() {
170 marked_for_removal.clear(); 170 marked_for_removal.clear();
171 171
172 if (!removed_shaders.empty()) { 172 if (!removed_shaders.empty()) {
173 RemoveShadersFromStorage(std::move(removed_shaders)); 173 RemoveShadersFromStorage(removed_shaders);
174 } 174 }
175} 175}
176 176
@@ -213,7 +213,7 @@ void ShaderCache::UnmarkMemory(Entry* entry) {
213 rasterizer.UpdatePagesCachedCount(addr, size, -1); 213 rasterizer.UpdatePagesCachedCount(addr, size, -1);
214} 214}
215 215
216void ShaderCache::RemoveShadersFromStorage(std::vector<ShaderInfo*> removed_shaders) { 216void ShaderCache::RemoveShadersFromStorage(std::span<ShaderInfo*> removed_shaders) {
217 // Remove them from the cache 217 // Remove them from the cache
218 std::erase_if(storage, [&removed_shaders](const std::unique_ptr<ShaderInfo>& shader) { 218 std::erase_if(storage, [&removed_shaders](const std::unique_ptr<ShaderInfo>& shader) {
219 return std::ranges::find(removed_shaders, shader.get()) != removed_shaders.end(); 219 return std::ranges::find(removed_shaders, shader.get()) != removed_shaders.end();
diff --git a/src/video_core/shader_cache.h b/src/video_core/shader_cache.h
index 136fe294c..8836bc8c6 100644
--- a/src/video_core/shader_cache.h
+++ b/src/video_core/shader_cache.h
@@ -4,7 +4,6 @@
4 4
5#pragma once 5#pragma once
6 6
7#include <algorithm>
8#include <array> 7#include <array>
9#include <memory> 8#include <memory>
10#include <mutex> 9#include <mutex>
@@ -138,7 +137,7 @@ private:
138 /// @param removed_shaders Shaders to be removed from the storage 137 /// @param removed_shaders Shaders to be removed from the storage
139 /// @pre invalidation_mutex is locked 138 /// @pre invalidation_mutex is locked
140 /// @pre lookup_mutex is locked 139 /// @pre lookup_mutex is locked
141 void RemoveShadersFromStorage(std::vector<ShaderInfo*> removed_shaders); 140 void RemoveShadersFromStorage(std::span<ShaderInfo*> removed_shaders);
142 141
143 /// @brief Creates a new entry in the lookup cache and returns its pointer 142 /// @brief Creates a new entry in the lookup cache and returns its pointer
144 /// @pre lookup_mutex is locked 143 /// @pre lookup_mutex is locked