diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/core/hle/kernel/svc.cpp | 2 | ||||
| -rw-r--r-- | src/video_core/buffer_cache/buffer_cache.h | 47 | ||||
| -rw-r--r-- | src/video_core/engines/engine_upload.cpp | 7 | ||||
| -rw-r--r-- | src/video_core/engines/engine_upload.h | 8 | ||||
| -rw-r--r-- | src/video_core/engines/kepler_compute.cpp | 1 | ||||
| -rw-r--r-- | src/video_core/engines/kepler_memory.cpp | 4 | ||||
| -rw-r--r-- | src/video_core/engines/kepler_memory.h | 7 | ||||
| -rw-r--r-- | src/video_core/engines/maxwell_3d.cpp | 1 | ||||
| -rw-r--r-- | src/video_core/engines/maxwell_3d.h | 3 | ||||
| -rw-r--r-- | src/video_core/gpu.cpp | 8 | ||||
| -rw-r--r-- | src/video_core/memory_manager.h | 4 | ||||
| -rw-r--r-- | src/video_core/rasterizer_interface.h | 3 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer.cpp | 22 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer.h | 2 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_rasterizer.cpp | 22 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_rasterizer.h | 2 | ||||
| -rw-r--r-- | src/video_core/shader_cache.cpp | 4 | ||||
| -rw-r--r-- | src/video_core/shader_cache.h | 3 |
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 | ||
| 1646 | template <class P> | 1651 | template <class P> |
| 1652 | bool 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 | |||
| 1687 | template <class P> | ||
| 1647 | void BufferCache<P>::DownloadBufferMemory(Buffer& buffer) { | 1688 | void 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 | ||
| 12 | namespace Tegra::Engines::Upload { | 13 | namespace Tegra::Engines::Upload { |
| @@ -16,6 +17,10 @@ State::State(MemoryManager& memory_manager_, Registers& regs_) | |||
| 16 | 17 | ||
| 17 | State::~State() = default; | 18 | State::~State() = default; |
| 18 | 19 | ||
| 20 | void State::BindRasterizer(VideoCore::RasterizerInterface* rasterizer_) { | ||
| 21 | rasterizer = rasterizer_; | ||
| 22 | } | ||
| 23 | |||
| 19 | void State::ProcessExec(const bool is_linear_) { | 24 | void 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 { | |||
| 12 | class MemoryManager; | 12 | class MemoryManager; |
| 13 | } | 13 | } |
| 14 | 14 | ||
| 15 | namespace VideoCore { | ||
| 16 | class RasterizerInterface; | ||
| 17 | } | ||
| 18 | |||
| 15 | namespace Tegra::Engines::Upload { | 19 | namespace Tegra::Engines::Upload { |
| 16 | 20 | ||
| 17 | struct Registers { | 21 | struct 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 | |||
| 63 | private: | 70 | private: |
| 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 | ||
| 23 | void KeplerCompute::BindRasterizer(VideoCore::RasterizerInterface* rasterizer_) { | 23 | void KeplerCompute::BindRasterizer(VideoCore::RasterizerInterface* rasterizer_) { |
| 24 | rasterizer = rasterizer_; | 24 | rasterizer = rasterizer_; |
| 25 | upload_state.BindRasterizer(rasterizer); | ||
| 25 | } | 26 | } |
| 26 | 27 | ||
| 27 | void KeplerCompute::CallMethod(u32 method, u32 method_argument, bool is_last_call) { | 28 | void 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 | ||
| 20 | KeplerMemory::~KeplerMemory() = default; | 20 | KeplerMemory::~KeplerMemory() = default; |
| 21 | 21 | ||
| 22 | void KeplerMemory::BindRasterizer(VideoCore::RasterizerInterface* rasterizer_) { | ||
| 23 | upload_state.BindRasterizer(rasterizer_); | ||
| 24 | } | ||
| 25 | |||
| 22 | void KeplerMemory::CallMethod(u32 method, u32 method_argument, bool is_last_call) { | 26 | void 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 { | |||
| 22 | class MemoryManager; | 22 | class MemoryManager; |
| 23 | } | 23 | } |
| 24 | 24 | ||
| 25 | namespace VideoCore { | ||
| 26 | class RasterizerInterface; | ||
| 27 | } | ||
| 28 | |||
| 25 | namespace Tegra::Engines { | 29 | namespace 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 | ||
| 32 | void Maxwell3D::BindRasterizer(VideoCore::RasterizerInterface* rasterizer_) { | 32 | void Maxwell3D::BindRasterizer(VideoCore::RasterizerInterface* rasterizer_) { |
| 33 | rasterizer = rasterizer_; | 33 | rasterizer = rasterizer_; |
| 34 | upload_state.BindRasterizer(rasterizer_); | ||
| 34 | } | 35 | } |
| 35 | 36 | ||
| 36 | void Maxwell3D::InitializeRegisterDefaults() { | 37 | void 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 | |||
| 146 | private: | 148 | private: |
| 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 | ||
| 487 | void 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 | |||
| 487 | bool RasterizerOpenGL::AccelerateDisplay(const Tegra::FramebufferConfig& config, | 509 | bool 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 | ||
| 551 | void 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 | |||
| 551 | bool RasterizerVulkan::AccelerateDisplay(const Tegra::FramebufferConfig& config, | 573 | bool 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 | ||
| 216 | void ShaderCache::RemoveShadersFromStorage(std::vector<ShaderInfo*> removed_shaders) { | 216 | void 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 |