simias / rustation

Playstation emulator in the Rust programing language
Other
552 stars 21 forks source link

Visual GPU debugger #31

Open simias opened 8 years ago

simias commented 8 years ago

This a project I've been thinking about for a while but I have so much stuff on my todo list at the moment that I can't imagine tackling it anytime soon. I would like an external tool that could take PlayStation GPU command logs and lets me see what individual commands draw. I'd also like to be able to navigate the commands, go back in time etc... That would be a huge time saver when tracking down certain graphical bugs.

I'm posting this here in case somebody else wants to give it a try, it's a relatively simple, well bounded and, in my opinion, fun project for somebody who likes making user interfaces and wants to try their hands at emulation. It's not super performance-critical either so you can really use the language and environment of your choice (although portability is strongly encouraged...).

This tool would be useful in the development of Rustation but it need not be tied to it and could be used for other emulators or even a real console as long as you're able to dump incoming GPU command words.

Context

From a high level perspective the PlayStation GPU is fairly simple. It has 1Megabyte of VRAM laid out as a 1024x512 16bits-per-pixel video buffer. The GPU draws lines, triangles and quadrilaterals to this buffer and then sends a portion of it to the video output.

In order to control it the GPU has two 32bit registers called GP0 and GP1. The CPU and/or DMA sends command words through those registers and the GPU executes them.

Here's the GP0 decoding function in rustation https://github.com/simias/rustation/blob/master/src/gpu/mod.rs#L592-L659

And here's GP1's: https://github.com/simias/rustation/blob/master/src/gpu/mod.rs#L1220-L1252

No$ is also a good source for understanding the GPU and its commands: http://problemkaputt.de/psx-spx.htm#graphicsprocessingunitgpu

You can see that GP0 commands are mainly draw commands like "draw a triangle at these coordinates", "draw a line at these coordinates", "fill this rectangle in VRAM with this color" etc... It's relatively straightforward.

GP1 on the other hand is more for configuration, things like turning the video output on or off or configuring which part of the VRAM is displayed on the screen.

The problem

My current problem is that linking a visual glitch on the output with an actual individual GPU command in the emulator can be very tedious and time consuming without any kind of tool to assist me.

For instance here's the complete log of GP0 and GP1 commands during the first few seconds after boot.

That's 19162 individual command words making up 2756 GP0 and 2282 GP1 commands. And all it does is draw the little animation of the "Sony Computer Entertainment" logo on boot.

For instance if you dig into the log you'll find the following sequence:

GP0 0x300000b2
GP0 0x00f101bd
GP0 0xca008cb2
GP0 0x00740140
GP0 0xca008cb2
GP0 0x016e0140

This draws one of the shaded triangles. Took me a little while to extract it out. The general form of this command is:

GP0 0x30BBGGRR <- 0x30 is the command opcode, followed by the 24bit RGB color of the 1st vertex
GP0 0xYYYYXXXX <- 1st vertex X and Y coordinates
GP0 0xXXBBGGRR <- 2nd vertex 24bit RGB color (high byte is ignored)
GP0 0xYYYYXXXX <- 1st vertex X and Y coordinates
GP0 0xXXBBGGRR <- 3rd vertex 24bit RGB color (high byte is ignored)
GP0 0xYYYYXXXX <- 3rd vertex X and Y coordinates

Now you can go back to the previous command and manually decode it if you want. As you can see this is pretty time consuming.

Now here's an actual bug I'm trying to fix right now:

retroarch-0524-013225

Crash's shadow on the ground is made up of two triangles, and you can see that one of them has the wrong transparency applied.

In order to fix this I'd like to be able to track the individual draw command responsible for this particular triangle and figure out why I don't interpreted it correctly. Isolating a single command from the thousands of calls making up each Crash Bandicoot frame is very tedious. Parsing the log I posted above is already non-trivial and it's only drawing a dozen triangles in a simple animation.

What I'd like is a visual tool that would take this command stream and show me what they do directly on the screen. No$ seems to have something like that already:

psxdebug

You can see that the "Vram Viewer" window has a list of commands at the upper right and seems to highlight the selected quadrilateral in the main view. Using a tool like this I could track down the bogus command in my Crash Bandicoot screenshot in seconds. This looks like a great tool but unfortunately it's closed source as far as I know.

So if somebody wants to give this a try or wants more precisions don't hesitate to ask for my help.

ADormant commented 8 years ago

@simias Perhaps you can copy debugger from @iCatButler Peops fork, maybe he can help with it?

https://github.com/iCatButler/pcsxr/commit/b5a738748175a460f856a1ed8a2e29fa26ebfb14 https://github.com/iCatButler/pcsxr/commit/2a24b74c12c6d248409dc93b35edbc373d03b29c https://github.com/iCatButler/pcsxr/commit/a64d62be4b433fcad3804d3bb616bdf4f13504f4 https://github.com/iCatButler/pcsxr/commit/f84c6902b40b678b2027a95cb4a80bbfb3270f9f https://github.com/iCatButler/pcsxr/commit/f671d256e7c1a3365cf2bbc89270363a17d66a1b Overclocking https://github.com/iCatButler/pcsxr/commit/1a30cfb9510d4e46960010735d26a344f75cb328

simias commented 8 years ago

What does it look like exactly?

ADormant commented 8 years ago

You can test it with this https://drive.google.com/file/d/0Bz8IYcLfu84zSHNKb0hIOHpIT2M/view

simias commented 8 years ago

I'll give it a try, thanks.