kuba 82c2c7f48c fix(gpu): reflect guest CPU writes into large and render-target-aliased images (#722)
Ports the still-applicable half of the archived fork's stale-texture fix
(a42ccae) onto current main. Silent Hill: The Short Message (PPSA10112)
shows both faces: black title-screen UI (glyph atlas frozen at its first
upload) and stale/garbage rows on the brightness screen (a 3840x2160 UI
sheet whose backing bytes were never re-read).

1. Write tracking is armed under a byte budget, not a resolution cap.

   GetOrCreateGuestImage armed GuestImageWriteTracker only when
   target.Width <= 1920 && target.Height <= 1080. Silent Hill renders at
   3840x2160, so every one of its render targets was excluded from
   CPU-write tracking and no guest rewrite of one could ever invalidate
   it: SyncCpuWrittenGuestImages (the flip / ACQUIRE_MEM re-upload path)
   only ever visits ranges the tracker armed.

   The cap presumably existed as a perf guard, but resolution is the
   wrong proxy for the cost. Arming is one mprotect over the range, and
   the fault handler unprotects the whole range on the first store, so a
   write burst costs one fault regardless of size. What actually scales
   with the surface is the dirty re-upload: one byte[byteCount]
   allocation plus a full guest-memory read per dirty flip. So the guard
   is now a byte budget, set equal to the 128 MiB limit that
   SyncCpuWrittenGuestImages itself enforces before re-uploading. Above
   that, arming can only cost faults; it can never produce a re-upload.
   That is generous for 4K (RGBA8 32 MiB, RGBA16F 63 MiB, RGBA32F
   127 MiB all fit) while still excluding volume textures that a
   resolution cap could not see at all (512^3 RGBA8 is 512 MiB behind a
   "512x512" surface).

   Both sites now also arm the exact extent recorded in
   _guestImageExtents (GetTextureByteCount) instead of
   Width*Height*depth*GetTextureBytesPerPixel, so the armed range and
   the range the sync path reads back are the same bytes; the old
   expression over-counted block-compressed and unknown formats.

2. The CPU-texture refresh path no longer gates on IsCpuBacked alone.

   TryCreateCpuTextureRefreshResource bailed on !guestImage.IsCpuBacked.
   That flag is a latch: it flips false the first time an address is
   used as a render target and never flips back. A surface that was
   rendered into once and is afterwards rewritten by the guest CPU was
   therefore frozen at its last GPU content forever, even when the parse
   thread had already shipped fresh texels for it.

   The gate is replaced by ShouldRefreshGuestImageFromCpu: CPU-backed,
   or the parse-time write generation is above zero and differs from the
   generation recorded by the last upload. Keeping the positive-
   generation requirement preserves the pure GPU-feedback case (render
   into an image, then sample it) that IsCpuBacked used to protect: such
   a surface is now tracked (change 1) but never CPU-written, so its
   generation stays zero and its live image is left alone. This matters
   more than it did in the fork, precisely because change 1 arms
   tracking on far more render targets. Dropping the gate outright, as
   the fork did, would let a target sampled under a format tag that the
   availability map does not match be overwritten once with whatever
   sits in guest memory.

   The existing content fingerprint still suppresses redundant uploads,
   and MarkSampledImagesInitialized records the uploaded generation, so
   a rewritten surface re-uploads exactly once per guest write burst.

Not ported: the fork's third part added a PeekDirty guard to the
parse-time snapshot fast path in AgcExports. It is superseded. That path
now calls IsGuestImageUploadKnown, which already compares
_cpuBackedUploadGenerations against the tracker's write generation - a
monotonic value that survives another owner consuming the dirty flag,
unlike PeekDirty, which both EvictDirtyCachedTextures and
SyncCpuWrittenGuestImages clear. Guest images with no generation entry
are covered instead by SyncCpuWrittenGuestImages. Adding a non-consuming
PeekDirty there would also make every draw between a CPU write and the
next flip fall through to a full texel re-read of the surface (33 MiB
for a 4K sheet), since Track re-arms without clearing the dirty flag.
The fork's promotion-path Track ("vulkan.cpu-backed-image") is likewise
superseded: AgcExports already arms every sampled texture's backing
extent as "agc.decoded-texture" before reading its texels.

Both decisions are extracted as pure internal predicates so they can be
unit-tested; the Vulkan device code around them needs a real device.
2026-07-31 12:12:54 +03:00
2026-07-28 03:33:26 +03:00
2026-07-19 01:26:01 +03:00
2026-03-11 15:48:28 +03:00
2026-07-30 12:58:22 +03:00
2026-07-28 03:33:26 +03:00

SharpEmu

An experimental PlayStation 5 emulator for Windows, Linux and macOS.


Support SharpEmu


Note

SharpEmu supports Windows x64, Linux x64, and macOS x64. Apple Silicon Macs can run the macOS x64 build through Rosetta 2, and Windows on ARM devices (e.g. Snapdragon) can run the Windows x64 build through Windows' built-in x64 emulation.

Warning

SharpEmu is an experimental PS5 emulator developed from scratch in C#. The current focus is on accuracy and infrastructure setup rather than game-specific compatibility.

Info

SharpEmu is an emulator project currently in its early stages of development.

This project is developed purely for research and educational purposes. There are no commercial goals associated with it. We enjoy learning about system architecture and reverse engineering.

SharpEmu focuses exclusively on the PlayStation 5.
Our goal is not to emulate PS4 games, as there is already an excellent emulator dedicated to that platform: ShadPS4.

Games Tested

Demons Souls Remake Dreaming Sarah
Bloodborne screenshot Dreaming Sarah
Void Terrarium Dead Cells
Void Terrarium Dead Cells

Status

The emulator can currently load the eboot.bin of real games, execute native CPU instructions, and partially handle kernel-related functionality. However, several critical components are still missing.

Current capabilities include:

  • Loading eboot.bin and .elf files
  • Executing native CPU instructions
  • Reading basic game metadata (title, version, etc.)
  • Loading system modules (prx / sys_module)
  • Partial support for some kernel functions
  • Fiber and AMPR exports
  • PlayGo scenarios
  • Initial loading game files
  • Shader/resource submits and AGC initial
  • Video outputs in some games

Some games have reached like sceVideoOut and AGC stages.

SharpEmu supports Windows, Linux, and macOS hosts. Video output uses Vulkan on Windows and Linux, and MoltenVK on macOS. Platform support is still experimental, so compatibility and performance vary by game, operating system, and GPU driver.

Using

Download the release archive for your operating system, extract it, and launch SharpEmu with the path to a legally obtained game's eboot.bin.

Windows PowerShell:

.\SharpEmu.exe "C:\path\to\game\eboot.bin" 2>&1 |
  Tee-Object -FilePath "SharpEmu.log"

Linux and macOS:

chmod +x ./SharpEmu

./SharpEmu "/path/to/game/eboot.bin" 2>&1 |
  tee SharpEmu.log

A Vulkan-capable GPU and current graphics driver are required. The macOS release includes the MoltenVK Vulkan implementation.

Important

This project does not support or condone piracy.
All games used during development and testing are dumped from consoles that we personally own.
Users are expected to use legally obtained copies of their games.

Build

  1. Install the .NET SDK version specified in global.json.
  2. Clone the repository: git clone https://github.com/sharpemu/sharpemu.git
  3. Open the solution file (SharpEmu.slnx) in VSCode.
  4. Build the project: dotnet build or dotnet publish
  5. Build artifacts will be located in the artifacts directory.

Disclaimer

SharpEmu is an experimental emulator intended for research and educational purposes.

This project does not contain any copyrighted system firmware, game data, or proprietary PlayStation assets.

Special Thanks

The following projects were extremely helpful during development:

  • ShadPS4
    Helped with understanding the basic architecture of the PlayStation 4.

  • Kyty
    One of the few PS5 emulator projects available and very useful for studying native code execution.

  • Ryujinx
    Provided valuable references for filesystem handling and low-level C# implementation patterns.

License

Support

Support SharpEmu via GitHub Sponsors or cryptocurrency. Every contribution helps fund ongoing development and long-term maintenance. GitHub Sponsors is the preferred way to support the project, but cryptocurrency donations are also appreciated.

ETH/USDT

0xF315F5d986c790bB3A58DbE60F1B2760997dEd82

BTC

bc1qmr9k8899njys5ny63xsues4jgmkk96erslrkmv

Contributing

Before opening an issue or pull request, please read our contribution guidelines:

CONTRIBUTING.md

The guide covers:

  • Coding style and formatting
  • AI-assisted contributions
  • Pull request expectations
  • Testing guidelines
  • Legal and reverse engineering policy
S
Description
Languages
C# 98%
Python 1.1%
JavaScript 0.3%
CSS 0.3%
HTML 0.2%