* [VideoOut] Add an internal render resolution scale option Adds the host-side setting an internal-resolution implementation needs: --render-scale on the command line, SHARPEMU_RENDER_SCALE for scripted runs, and a global and per-game choice in the GUI. The value is a host resolution multiplier of the guest render targets, normalized to a hundredth in [0.25, 2] so the command line, the GUI and the environment agree bit for bit; the renderer compares scales when it decides whether two views of the same guest memory match. RenderScalePolicy holds the decision rule. It is a pure function of the guest image description, so every view, alias, copy and descriptor of one guest range reaches the same answer without consulting the cache. Only screen-class, single-level, single-sample, uncompressed 2D render and depth targets scale; block grids, multisample footprints, HTile and DCC coverage, mip chains, cube and array faces, asset tilings and small surfaces (shadow maps, lookup tables, eye-adaptation readbacks) keep their guest resolution. The environment variable wins over the stored setting so test runs do not depend on the user's configuration. No renderer consumes the scale yet; a scale of one is the current behaviour everywhere. * [GPU] Hold scalable guest images at a host render resolution The backing of an image the scaling rules accept is created at ceil(guest * scale) while its ImageDescription keeps the guest geometry, so the cache, the overlap rules and the page tracker go on reasoning in guest bytes. Everything that moves guest bytes now goes through a guest-resolution twin of the scaled image: an upload fills the twin from the copy regions the tiler built and blits into the backing, a download blits the backing into the twin and copies out of it. A copy whose two images disagree on host resolution runs at guest resolution the same way, so callers keep describing rectangles in guest pixels; the destination seeds its twin first because a partial copy is blitted back whole. The multisample depth conversion takes a guest-sized source for the same reason, and the resolve region crosses into the destination's resolution instead of silently resolving the top-left corner. Two fallbacks keep correctness ahead of the saving. A format that cannot blit keeps its guest resolution, since the twin could never reach it. A storage image drops back to guest resolution the first time a compute shader binds it: the dispatch grid does not shrink with the host image, so the shader would write it with holes above 1.0 and redundantly below. The guest range is remembered, so every later image over that memory is created unscaled too. * [GPU] Scale the render area, viewport and scissor with the attachments A resolved target now reports the host extent of its attachment beside the guest one, and the three places that size rasterization follow it: the dynamic rendering area, which also bounds every load-op clear; the guest viewport transform; and the guest scissor, whose edges round outward so no guest pixel the game asked for loses host coverage. All attachments of a pass share one rule, so the first bound target decides the factor. The clip-disable path needs care because the vertex program bakes the viewport transform against a reference extent. Dividing that reference by an upscale keeps the host viewport (reference x scale) inside the device limit while the baked transform stays scale independent, so the same program maps guest pixels onto host positions at either resolution. At a scale of one the reference is the device limit, exactly as before. * [SpirvTranslator] Translate pixel positions and image coordinates across the render scale A program expresses its pixel position, its integer image coordinates and the sizes it queries in guest pixels, but the host may hold the image behind any of them at another size. Which images are scaled is a per-draw fact, so the factors travel in shader data rather than in a permutation: the coordinate factor, its reciprocal, a 64-bit mask of scaled image resources and the factor the pixel position is divided by. With that: - gl_FragCoord is divided by the attachments' factor as it is loaded, so POS_X/POS_Y, POS_FIXED_PT and everything derived from them - screen UVs above all - stay in guest pixels. - An integer image coordinate is mapped onto host texels through the bound image's factor. Only the two scaled axes move; an array layer or a volume slice is not a pixel. - A resource-info query reports the guest size, because the program derives coordinates and loop bounds from it. A select against the mask makes an unscaled binding cost one instruction, and the layout only carries the dwords when the scale is not one, so nothing changes at native resolution. * [GPU] Keep one host resolution across the attachments of a pass A rendering scope has one render area, one viewport and one scissor, so its attachments have to agree on a host resolution. They disagree when one of them cannot be scaled at all - a depth target with a stencil plane next to a scalable colour target, say - and the pass then renders a fraction of its area. The draw now drops every scaled attachment back to guest resolution and resolves its targets again; the guest ranges are remembered, so the decision converges after one draw and cannot oscillate. That fallback only works if the executor knows what the cache actually gave it, which is not what the scaling rules would answer: a demoted range still looks scalable to them. The resolved targets therefore carry the image's own factor, and the render area, viewport, scissor and the depth/stencil copy extent read it from there. Two rules change with it. DCC only describes guest bytes the host never stores, so a colour target that carries it can still be scaled; HTile encodes guest depth blocks the renderer reads back as clear state and stays native. And a storage image only drops back when the program actually writes it, since a read-only load is mapped correctly. Scaling now also requires a backend that installed the format predicate - the Vulkan device - so the Metal host is unaffected. * [Docs] Describe internal resolution scaling and its limits Replaces the note saying arbitrary internal resolution scaling is not implemented: it is, for screen-class render and depth targets. Records what the renderer translates (rasterization, shader coordinates, guest transfers, presentation), the exact rule for what scales, every case that falls back to guest resolution, the artefacts measured on Silent Hill, and the per-scope GPU times at 50, 100 and 200 percent. * [SpirvTranslator] Preserve guest texel offsets at scaled resolutions |
||
|---|---|---|
| .github | ||
| LICENSES | ||
| assets/images | ||
| docs | ||
| scripts | ||
| src | ||
| tests | ||
| tools | ||
| .editorconfig | ||
| .gitignore | ||
| CONTRIBUTING.md | ||
| Directory.Build.props | ||
| Directory.Packages.props | ||
| LICENSE.txt | ||
| README.md | ||
| REUSE.toml | ||
| SharpEmu.slnx | ||
| global.json | ||
| nuget.config | ||
README.md
SharpEmu
An experimental PlayStation 5 emulator for Windows, Linux and macOS.
Join our official Discord server for development updates, compatibility discussions, support, and community chat.
[!IMPORTANT] Official channels: Only sharpemu.app and the links listed in this GitHub repository are affiliated with SharpEmu. Any other websites, accounts, or donation pages are unofficial and unauthorized.
[!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
| Demon's Souls Remake | ASTRO BOT |
|---|---|
![]() |
![]() |
| ASTRO's PLAYROOM | Dead Cells |
|---|---|
![]() |
![]() |
| God of War: Sons of Sparta | Tomb Raider V Remastered |
|---|---|
![]() |
![]() |
Status
The emulator can currently load the eboot.bin of real games, execute native CPU instructions, and partially handle gpu-related functionality. Included 3D games.
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.
Or command line;
Windows PowerShell:
.\SharpEmu.exe "C:\path\to\game\eboot.bin" --log-to-file
Linux and macOS:
chmod +x ./SharpEmu
./SharpEmu "/path/to/game/eboot.bin" --log-to-file
SharpEmu supports environment variables that can be configured from the GUI. Undocumented variables are listed here: docs/sharpemu-gui-undocumented-env-vars.md
You can set them per game or globally in the GUI, or pass them directly through the CLI.
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
- Install the .NET SDK version specified in
global.json. - Clone the repository:
git clone https://github.com/sharpemu/sharpemu.git - Open the solution file (
SharpEmu.slnx) in VSCode. - Build the project:
dotnet buildordotnet publish - Build artifacts will be located in the
artifactsdirectory.
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:
The guide covers:
- Coding style and formatting
- AI-assisted contributions
- Pull request expectations
- Testing guidelines
- Legal and reverse engineering policy





