feat(agc): store pending storage-image results at each flip with APS5_STORE_AT_FLIP
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
d5c8e42dfd
commit
ef53b0614f
|
|
@ -2079,6 +2079,8 @@ FrameDumps& Dumps() {
|
|||
}
|
||||
|
||||
bool VulkanDevice::PresentDisplayBuffer(const DisplayBuffer& buffer) {
|
||||
static const bool storeAtFlip = std::getenv("APS5_STORE_AT_FLIP") != nullptr;
|
||||
if (storeAtFlip) Graphics::StorageTexture::FlushAllPending("flip");
|
||||
if (buffer.tilingMode == 1) {
|
||||
const auto pixels = ReadDisplayBuffer(buffer);
|
||||
return present(buffer.width, buffer.height, true, pixels);
|
||||
|
|
|
|||
|
|
@ -3002,6 +3002,8 @@ void metadataPassTests(const Device& device, Recorder& recorder) {
|
|||
std::memset(keys, 0x20, extent);
|
||||
RunColorMetadataPass(context, pass);
|
||||
Require(StorageTexture::FindPending(address, surfaceBytes) != nullptr && texels[0] == 0x55, "the register fast clear eliminate did not stay in the resident image");
|
||||
StorageTexture::FlushAllPending("test");
|
||||
Require(StorageTexture::FindPending(address, surfaceBytes) == nullptr, "storing every pending image left the eliminated target pending");
|
||||
Require(keysUncompressed(), "the register fast clear eliminate left the keys compressed");
|
||||
Require(CurrentDccKeys(color.dccAddress, surfaceBytes, extent) == DccKeys::Uncompressed, "the register fast clear eliminate did not store uncompressed keys over the target's console DCC extent");
|
||||
Require(memoryHolds({0x10, 0x20, 0x40, 0x80}), "the register fast clear eliminate did not store CB_COLOR_CLEAR_WORD");
|
||||
|
|
|
|||
|
|
@ -271,6 +271,7 @@ Throughout the project, every function at every stage either **does exactly what
|
|||
- a system call that writes into a protected page fails with `EFAULT` instead of faulting. `GuestArena::HostWrite` lifts the protection for the calls it brackets (the file reads); a host call that writes guest memory without it (sockets, `clock_gettime` and the like into a watched page) fails;
|
||||
- code that changes the protection of watched pages, or maps over them, has to call `GuestWriteWatchProtectionChanged`, and code that asks the kernel for a page's protection has to ask `GuestWriteWatchProtection` first, since a watched page is read-only between a collection and the next write. Nothing calls either yet: the macOS memory paths are not in the tree;
|
||||
- the handler is installed when libc loads and passes other faults to the handler installed before it. A handler installed later has to do the same.
|
||||
- [Pending storage-image results](../../core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp) (libSceAgcDriver) are stored when something reads their memory, not when the GPU work that wrote them completes. A title that waits for that work, frees the image and reuses its memory can have the new data overwritten by the late store (#1970). `APS5_STORE_AT_FLIP=1` stores every pending result at each flip; storing them at the title's GPU waits (labels, fences) is unimplemented.
|
||||
- Windows host-pointer imports of the guest mapping itself are compared instead of write-watched: a driver can mark imported pages dirty after the synchronous import window. Shared memory imported through a separate writable alias retains protection-based tracking on the guest views; driver access to the import alias does not disarm those views. [GuestMemory](../../core/libs/prx/libSceAgcDriver/Execution/src/GuestMemory.cpp) excludes every overlapping 64 KiB tracker block while its backing is retained. A full block replaced by fresh private backing regains tracking and gets a new generation; protection changes, partial replacements and shared remappings do not restore it. This preserves CPU edits through byte comparisons but disables snapshot reuse and unit shadows for excluded blocks; restoring tracking on import retirement without replacing the backing and measuring the comparison cost remain unimplemented.
|
||||
- [shm_open](../../core/libs/prx/libkernel/File/src/SharedMemory.cpp) (libkernel) creates only anonymous objects (`SHM_ANON`), each backed by a host anonymous file: a `memfd` on Linux, a delete-on-close temporary file on Windows. The flag checks follow FreeBSD 11's `kern_shm_open`; the mode is ignored. Named objects throw. The descriptor cannot be mapped yet: `mmap` accepts only private anonymous mappings and fails a descriptor mapping with `EOPNOTSUPP`, so the known caller (the bundled Mesa in PPSA59322, which truncates the object and maps it `MAP_SHARED`) gets that failure
|
||||
- [sceNetSendmsg and sceNetRecvmsg](../../core/libs/prx/libSceNet/Export.cpp) (libSceNet) copy the scatter/gather list through one host buffer and accept only the flags `sceNetSend`/`sceNetRecv` accept. Sending control data throws; a receive never returns control data (`msg_controllen` 0), since no socket option that queues it is supported
|
||||
|
|
|
|||
|
|
@ -108,6 +108,10 @@ Games that open the console's system font sets (`sceFontOpenFontSet`) need font
|
|||
|
||||
The game runs on the first Vulkan 1.1 device with graphics and compute queues and swapchain presentation, preferring a discrete GPU over an integrated one. Set `ANYPS5_GPU` to a part of a device name, compared without regard to case, to run on another device; the names are printed at start-up in the `Physical device candidate` lines. When no usable device contains the text, the start fails and the error lists the device names.
|
||||
|
||||
### Storing GPU results at each flip
|
||||
|
||||
GPU results in storage images and render targets stay on the GPU until something reads their memory. A title that frees such an image after waiting for its GPU work and reuses the memory can have its new data overwritten when the results are stored later ([TechnicalDebt](../dev/TechnicalDebt.md)). `APS5_STORE_AT_FLIP=1` stores every pending result when a display buffer is flipped, at the cost of one write-back per pending image and frame.
|
||||
|
||||
## Exit codes
|
||||
|
||||
`0`: conversion succeeded. `1`: invalid arguments. `2`: conversion failed; the error is printed to stderr. With `--autorun`, successful conversion returns the launched application's exit code.
|
||||
|
|
|
|||
Loading…
Reference in New Issue