Frame timing

Technical discussion for those interested in Supermodel development and Model 3 reverse engineering. Prospective contributors welcome.
Forum rules
Keep it classy!

  • No ROM requests or links.
  • Do not ask to be a play tester.
  • Do not ask about release dates.
  • No drama!

Re: Frame timing

Postby Bart » Thu Apr 06, 2017 2:01 pm

Also note that fixing this issue will fix crashes caused by rendering invalid scene data but it will not necessarily fix timing in most games. I would expect that game logic uses high resolution timers (the PPC bus clock) and VBL to actually time things. Frame rendering time would be non-deterministic.
User avatar
Bart
Site Admin
 
Posts: 3086
Joined: Thu Sep 01, 2011 2:13 pm
Location: Reno, Nevada

Re: Frame timing

Postby Shekel » Thu Apr 06, 2017 2:53 pm

This is a totally out there question. I don't even know what half of these things are that I'm reading. But when you talk of timing, I think of Sega Rally on the Model 2 Emulator. I don't know exactly what's wrong with it, the game seems to run fine except that the AI is behind and running slower than it should.

Then a dev said this about Virtua Racing on MAME (which is a Model 1 game). "Virtua Racing is also currently using code taken from Daytona (Model 2 game) instead of its own, because there is currently no method to dump the actual internal code on a VR, that could also be causing issues."

So do you think there's anything in Supermodel's code that could make the M2 emulation of Sega Rally better?
User avatar
Shekel
 
Posts: 345
Joined: Wed Mar 16, 2016 12:45 pm

Re: Frame timing

Postby Ian » Thu Apr 06, 2017 3:50 pm

Bart wrote:
Code: Select all
READ64_MEMBER(model3_state::real3d_status_r)
{
   m_real3d_status ^= 0xffffffffffffffffU;
   if (offset == 0)
   {
      /* pretty sure this is VBLANK */
      m_real3d_status &= ~0x0000000200000000U;
      if (m_screen->vblank())
         m_real3d_status |= 0x0000000200000000U;
      return m_real3d_status;
   }
   return m_real3d_status;
}


This is how I guessed it would work. It polls until vblank happens when loading. Then the hw uses the timing info to schedule when to write the graphic data every frame.
Ian
 
Posts: 2044
Joined: Tue Feb 23, 2016 9:23 am

Re: Frame timing

Postby Bart » Thu Apr 06, 2017 6:00 pm

If it waits until VBL to transfer memory and kick of rendering, seems like it would have a couple frames' worth of latency. I guess that's not a big deal and also occurs in triple-buffered systems.

But I don't think the status bit is tied to VBL. There is already a VBL interrupt, after all.
User avatar
Bart
Site Admin
 
Posts: 3086
Joined: Thu Sep 01, 2011 2:13 pm
Location: Reno, Nevada

Re: Frame timing

Postby Bart » Thu Apr 06, 2017 6:04 pm

Shekel wrote:This is a totally out there question. I don't even know what half of these things are that I'm reading. But when you talk of timing, I think of Sega Rally on the Model 2 Emulator. I don't know exactly what's wrong with it, the game seems to run fine except that the AI is behind and running slower than it should.

Then a dev said this about Virtua Racing on MAME (which is a Model 1 game). "Virtua Racing is also currently using code taken from Daytona (Model 2 game) instead of its own, because there is currently no method to dump the actual internal code on a VR, that could also be causing issues."

So do you think there's anything in Supermodel's code that could make the M2 emulation of Sega Rally better?


Nope. My understanding is that the Model 1 and some early versions of Model 2 used Fujitsu DSPs (MB86232, if I remember correctly) for which no documentation seems to exist. From this description, it sounds like VR also used some sort of internal ROMs that made it impossible to get at the ROMs themselves, whereas Daytona 2's were dumped somehow. The DSPs implemented various parts of the 3D rendering pipeline, namely math functions and transformations. When they initially got Model 1 and 2 games up and running, I think it was through "high level emulation" of the DSP functionality. In this case, apparently VR and Daytona were running similar code on their DSPs allowing one to be used with the other.
User avatar
Bart
Site Admin
 
Posts: 3086
Joined: Thu Sep 01, 2011 2:13 pm
Location: Reno, Nevada

Re: Frame timing

Postby Shekel » Thu Apr 06, 2017 6:43 pm

You're all geniuses.
User avatar
Shekel
 
Posts: 345
Joined: Wed Mar 16, 2016 12:45 pm

Re: Frame timing

Postby Ian » Fri Apr 07, 2017 1:14 am

Bart wrote:If it waits until VBL to transfer memory and kick of rendering, seems like it would have a couple frames' worth of latency. I guess that's not a big deal and also occurs in triple-buffered systems.

But I don't think the status bit is tied to VBL. There is already a VBL interrupt, after all.


If I recall it carries on polling until the bits flips back to the original state exactly once. So I guess that would be technically after vblank, assuming that is what it syncs with.
Ian
 
Posts: 2044
Joined: Tue Feb 23, 2016 9:23 am

Re: Frame timing

Postby Bart » Fri Apr 14, 2017 12:04 pm

I wanted to move the frame timing discussion from the Ocean Hunter thread back here. Ian, you said:

Bart when games sync with the status bit, they do this
00000001110
They keep polling until it flips back to 0 again. So when vblank ends.

This is impossible for us. The bit only flips back to 0 when a new 'frame' starts. I think this is why our timing is messed up.
Also we probably should swap our own buffers at that point when we say vblank happens.


Supermodel runs each frame something like this:

Begin VBL
Run PPC
End VBL
Run PPC for active frame cycles
Render

The status bit should be 1 between BeginVBL and EndVBL.

The Real3D presumably needs a lot of time to prepare a frame and while it is doing so, I would expect the game to be preparing the next frame. It seems highly unlikely that it can render a whole frame during VBL alone. I would suspect that the games are syncing to VBL for timing. I would expect that the GPU is spending at least 50% of a frame rendering, if not more. This means it cannot be done entirely during VBL.

When one syncs a game to VBL, usually what the main loop looks like is this:

1. Update game logic and physics
2. Draw to back buffer
3. Wait for VBL
4. Swap buffers

With a GPU, step [2] is performed on the GPU and step [4] takes no time at all.

I need to understand the precise order that these games read the status bit (which actually happens from an IRQ that may already be linked to VBL, so it seems to make little sense that this bit would also reflect VBL).

My guess is that writing to 0x88000000 does two things: swaps the back buffers (just-completed frame is now displayed) and swaps the ping pong memory so a new frame can begin rendering. In that case, the status bit could simply be a busy signal indicating rendering has not yet completed.

If that's correct, then the game loop would look like this:

1-0. Display period begins
1-1. Update game logic and physics for frame #1
1-2. Copy scene graph to ping pong buffer for frame #1
1-3. Wait for VBL
1-4. Swap buffers: frame 0 (empty for now) is shown, frame 1 begins rendering
2-0. Display period begins. Frame #0 is showing.
2-1. Update game logic and physics for frame #2
2-2. Copy scene graph to ping pong buffer for frame #2
2-3. Wait for VBL.
2-4. Swap buffers: frame 1 is shown, frame 2 begins rendering
3-0. DIsplay period begins. Frame #1 is showing.
3-1. Update game logic and physics for frame #3
...

This implies two frames of latency, by the way, which I think is correct? Check out this picture.

The double buffering case. In this example, "drawing" means writing to the back buffer. But that means doing two things: 1) updating game logic and 2) rendering it. As I see it, there are only two possibilities here depending on how intensive the scene is:

1. Game logic can be updated in less than half of an active frame (less than 8 ms), leaving the GPU about 6 ms to render a complete scene (less than half the active frame time), which would give a latency of a single frame.
2. Game logic and copying to the GPU takes an entire frame on the CPU, and the GPU will spend the entire next frame drawing it, which means it won't be displayed until t+2.

Either way, the drawing is not really dependent on VBL.

Do you think the timing is fundamentally different?
User avatar
Bart
Site Admin
 
Posts: 3086
Joined: Thu Sep 01, 2011 2:13 pm
Location: Reno, Nevada

Re: Frame timing

Postby Bart » Fri Apr 14, 2017 12:12 pm

Fighting Vipers 2 is probably the game we want to focus on for timing because it is very sensitive to it. I tried the following just as a test:

Sync the status bit to 0x88000000 being written. Instead of this occurring in BeginVBlank(), I set statusChange in CReal3D::Flush(). I discovered something interesting but puzzling for now: if I set statusChange to ppc_total_cycles() + 10000, the game runs generally okay (the intro is still wrong, though). Values of 1, 100, and 1000 cause the game to lock up during boot. I'm not sure what it's doing: it even stops reading the status bit!

Some of these games make extensive use of the time base and decrementer registers (which count cycles and are locked to the bus). It's possible they are trying to perform frame timing based on the VBL interrupts and the status bit. fvipers2 is pretty nasty to debug. It'll unfortunately take a lot of effort to sit down and find the main timing loop. Or at least the loop being executed at start-up. It also does some weird things in the IRQ handlers. For example, when it reads the status bit from the DMA registers, it does so 9 times in a row (in a loop), always overwriting the last value read. This is a hard-coded loop.
User avatar
Bart
Site Admin
 
Posts: 3086
Joined: Thu Sep 01, 2011 2:13 pm
Location: Reno, Nevada

Re: Frame timing

Postby Ian » Fri Apr 14, 2017 12:26 pm

I tried ..

GPU.BeginVBlank(statusCycles);

void CReal3D::BeginVBlank(int statusCycles)
{
statusChange = 1;
}

void CReal3D::EndVBlank(void)
{
error = false; // clear error (just needs to be done once per frame)
statusChange = 0;
}

That seems to work for most of the games, they all seem to boot. Virtua figther seems to run about 50% of the correct speed though. Daytona and scud and others seem fine.

I wonder if all the IRQs should be done at the beginning of the frame, and vblank put at the end, instead of the other way around.
Ian
 
Posts: 2044
Joined: Tue Feb 23, 2016 9:23 am

PreviousNext

Return to The Dark Room

Who is online

Users browsing this forum: No registered users and 1 guest

cron