mirror of
https://github.com/boykopovar/AnyPS5.git
synced 2026-11-04 13:07:32 +00:00
Merge pull request #6475 from EagleBearerYS/fix/agc-guard-lazy-capture-pages
fix(agc): run the read guard over a shader capture's lazy pages and raw word reads
This commit is contained in:
4 files changed
+36
-3
No files matched your search
@@ -196,6 +196,7 @@ unsigned long long CodeOffset(const void* address);
|
||||
// calls FlushGpuWrites itself.
|
||||
void SetFlushHook(void (*hook)(std::uint64_t address, std::size_t bytes));
|
||||
void SetReadGuard(void (*guard)(std::uint64_t address, std::size_t bytes));
|
||||
void GuardRead(std::uint64_t address, std::size_t bytes);
|
||||
void FlushGpuWrites(std::uint64_t address, std::size_t bytes);
|
||||
// Moves with every ForgetPages call (the libc invalidator: memory unmapped or re-registered): odd
|
||||
// while the call stores its page states, moved past it after, so a reader that loads an even
|
||||
|
||||
@@ -2234,13 +2234,17 @@ void SetReadGuard(void (*guard)(std::uint64_t address, std::size_t bytes)) {
|
||||
GuestArena::GuestArenaSetHostReadHook_nid_no_patch(&PrepareHostRead);
|
||||
}
|
||||
|
||||
void GuardRead(std::uint64_t address, std::size_t bytes) {
|
||||
if (const auto guard = readGuard.load(std::memory_order_acquire)) guard(address, bytes);
|
||||
}
|
||||
|
||||
void FlushGpuWrites(std::uint64_t address, std::size_t bytes) {
|
||||
if (const auto hook = flushHook.load(std::memory_order_acquire)) hook(address, bytes);
|
||||
}
|
||||
|
||||
void Read(std::uint64_t address, std::span<std::byte> destination, std::size_t alignment) {
|
||||
if (destination.empty()) return;
|
||||
if (const auto guard = readGuard.load(std::memory_order_acquire)) guard(address, destination.size());
|
||||
GuardRead(address, destination.size());
|
||||
FlushGpuWrites(address, destination.size());
|
||||
const TimedAccess timed(CounterRead, destination.size());
|
||||
CountReadCaller(__builtin_return_address(0));
|
||||
@@ -2287,7 +2291,7 @@ void copyCommitted(std::uint64_t address, std::span<std::byte> destination) {
|
||||
|
||||
void ReadCommitted(std::uint64_t address, std::span<std::byte> destination) {
|
||||
if (destination.empty()) return;
|
||||
if (const auto guard = readGuard.load(std::memory_order_acquire)) guard(address, destination.size());
|
||||
GuardRead(address, destination.size());
|
||||
FlushGpuWrites(address, destination.size());
|
||||
const TimedAccess timed(CounterRead, destination.size());
|
||||
CountReadCaller(__builtin_return_address(0));
|
||||
@@ -2296,7 +2300,7 @@ void ReadCommitted(std::uint64_t address, std::span<std::byte> destination) {
|
||||
|
||||
void ReadCommittedUnsynced(std::uint64_t address, std::span<std::byte> destination) {
|
||||
if (destination.empty()) return;
|
||||
if (const auto guard = readGuard.load(std::memory_order_acquire)) guard(address, destination.size());
|
||||
GuardRead(address, destination.size());
|
||||
const TimedAccess timed(CounterRead, destination.size());
|
||||
CountReadCaller(__builtin_return_address(0));
|
||||
copyCommitted(address, destination);
|
||||
|
||||
@@ -228,6 +228,7 @@ ShaderMemory::Page& ShaderMemory::page(std::uint64_t base) {
|
||||
return page;
|
||||
}
|
||||
const auto started = CaptureProfiled() ? std::chrono::steady_clock::now() : std::chrono::steady_clock::time_point{};
|
||||
GuestMemory::GuardRead(base, PageBytes);
|
||||
GuestMemory::FlushGpuWrites(base, PageBytes);
|
||||
if (CaptureProfiled()) CaptureTotals().pageReadNanoseconds += NanosecondsSince(started);
|
||||
page.lazy = true;
|
||||
@@ -289,6 +290,7 @@ bool ShaderMemory::read(void* context, std::uint64_t address, std::uint32_t* val
|
||||
word = waited;
|
||||
}
|
||||
} else if (policy == PendingWrite::Raw || policy == PendingWrite::VerifyRaw) {
|
||||
GuestMemory::GuardRead(address, sizeof(word));
|
||||
std::memcpy(&word, reinterpret_cast<const void*>(address), sizeof(word));
|
||||
++CaptureTotals().wordsRaw;
|
||||
if (policy == PendingWrite::VerifyRaw) {
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
#include "VertexRange_vert_spv.h"
|
||||
#include "VertexRangeProducer_frag_spv.h"
|
||||
#include "prx/libSceAgcDriver/Graphics/include/ColorTargetTransfer.hpp"
|
||||
#include "BdaAbi.hpp"
|
||||
#include <SDL_loadso.h>
|
||||
#ifdef _WIN32
|
||||
#ifndef NOMINMAX
|
||||
@@ -7037,6 +7038,31 @@ void multisampleGuestAccessTests(const Device& device, Recorder& recorder) {
|
||||
refused([&] { AgcDriver::GuestMemory::ReadCommitted(address + 256u, texels); }, "a CPU read", "a committed CPU read");
|
||||
refused([&] { AgcDriver::GuestMemory::ReadCommittedUnsynced(address + 256u, texels); }, "a CPU read", "a committed CPU read without the flush hook");
|
||||
refused([&] { RequireNoMultisampleTarget(address, 64u, "a DMA copy"); }, "a DMA copy", "a DMA copy");
|
||||
const auto captureSrt = [](std::uint64_t srt, AgcDriver::ShaderMemory::PendingWriteQuery pendingWrite) {
|
||||
static constexpr std::array<std::uint32_t, 6> code{0xf4080100u, 0xfa000000u, 0xbf8cc07fu, 0xe0700000u, 0x80010000u, 0xbf810000u};
|
||||
const std::array<std::uint32_t, 2> userData{static_cast<std::uint32_t>(srt), static_cast<std::uint32_t>(srt >> 32u)};
|
||||
ShaderRecompiler::RecompileRequest request{};
|
||||
request.shader = {ShaderRecompiler::ShaderStage::Compute, 0x24000u, code, 0, {}};
|
||||
request.context.waveSize = 32u;
|
||||
request.context.userDataBaseRegister = 0;
|
||||
request.context.userData = userData;
|
||||
request.context.compute = ShaderRecompiler::ShaderComputeStageInfo{{32u, 1u, 1u}, 0u, {false, false, false}, false, 1u};
|
||||
request.target.vulkanVersion = 0x00401000u;
|
||||
request.target.spirvVersion = 0x00010300u;
|
||||
request.target.subgroupSize = 32;
|
||||
request.target.bdaAbiVersion = ShaderRecompiler::BdaAbi::Version;
|
||||
request.layout.pushConstantSizeBytes = 128;
|
||||
AgcDriver::ShaderMemory memory({}, pendingWrite);
|
||||
static_cast<void>(memory.Capture(request));
|
||||
};
|
||||
refused([&] { captureSrt(address + 256u, nullptr); }, "a CPU read", "a shader capture");
|
||||
captureSrt(address + 4u * 65536u + 256u, nullptr);
|
||||
refused([&] { captureSrt(address + 256u, nullptr); }, "a CPU read", "a shader capture on a pooled page");
|
||||
const auto raw = [](std::uint64_t, std::size_t, std::span<std::byte>) { return AgcDriver::ShaderMemory::PendingWrite::Raw; };
|
||||
const auto synced = [](std::uint64_t, std::size_t, std::span<std::byte>) { return AgcDriver::ShaderMemory::PendingWrite::Sync; };
|
||||
refused([&] { captureSrt(address + 256u, raw); }, "a CPU read", "a shader capture's raw word read");
|
||||
refused([&] { captureSrt(address + 256u, synced); }, "a CPU read", "a shader capture's synced word read");
|
||||
captureSrt(address + 4u * 65536u + 256u, raw);
|
||||
ShaderRecompiler::RecompileResult program;
|
||||
ShaderRecompiler::DescriptorBinding binding;
|
||||
binding.kind = ShaderRecompiler::DescriptorKind::SampledImage;
|
||||
|
||||
Reference in new issue
Block a user