shadps4-emu / shadPS4

PS4 emulator for Windows,Linux,MacOS
https://shadps4.net/
GNU General Public License v2.0
11.11k stars 707 forks source link

(Documentation request) Explain the emulator design #1512

Open hardBSDk opened 2 weeks ago

hardBSDk commented 2 weeks ago

I can't find a document explaining how this emulator is designed, based on what I saw on the README of the compatibility list it is a hybrid LLE/HLE emulator.

Each game is mocked to think that it is running on Orbis OS but translated to the host OS, thus there's no need for hardware emulation (which will have much lower overhead because PS4 uses a PC architecture).

Dr-42 commented 1 week ago

Does anyone know where actual main render loop is?

polybiusproxy commented 6 days ago

I believe that the best way of learning a program's flow is by reading its code. Though I can see there's people who still want to know yet don't have enough skill to understand the code, so it's true that it'd be great to have documentation on that. But to sum it up quickly:

  1. Main eboot (game executable) is loaded.
  2. System libraries are loaded.
  3. Start running the eboot. We lose 'control' of the thread now.
  4. The guest runs its code. (e.g. load game assets, initialize systems, game UI, etc.)
  5. The guest calls system functions (they can be LLE or HLE).
  6. The guest starts sending GPU command buffers.
  7. The emulator receives said command buffers and does proper rendering (shader compilation, rendering).
  8. Repeat on step 4.

Things worth noting:

[...] Where is the render loop at?

The emulator does not have a render loop. We do rendering when the guest wants to. The guest fills command buffers to send to the GPU. We also fill command buffers with a reimplementation of the GnmDriver system library [1].

Once the game finishes filling the GPU command buffers, it submits them and they're received by the emulator. This is where the GPU emulation starts. It works by going over the submitted PM4 packets; these can reset, set GPU registers, make draw and dispatch calls, move data over DMA, and so on.

Once a draw call packet is encountered, the graphics pipeline is compiled (if needed), and a Vulkan draw call is done. If the guest does not submit command buffers, none of the above happens.

You can find the relevant code here:

I hope I explained everything you wanted to know. Let me know if you have any other questions.

[1] Gnm is the name of the PS4's graphics API. It is similar to DirectX 11.

hardBSDk commented 6 days ago

@polybiusproxy Thanks a lot for your answer!

Interesting, the emulator also translate the Gnm API calls to Vulkan.

hardBSDk commented 6 days ago

@polybiusproxy Does the emulator just translate the Orbis OS system calls or parts of the kernel are implemented or translated?

polybiusproxy commented 6 days ago

Both system library calls and the kernel are reimplemented.

Dr-42 commented 6 days ago

Thanks. This is quite helpful.

hgh32 commented 3 days ago

@polybiusproxy Do you know about buffer memory alignment? I just know it's related to hardware and vulkan