Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fifo overflow fix #1536

Merged
merged 3 commits into from
Nov 19, 2014
Merged

Fifo overflow fix #1536

merged 3 commits into from
Nov 19, 2014

Conversation

skidau
Copy link
Contributor

@skidau skidau commented Nov 14, 2014

No description provided.

@MayImilae
Copy link
Contributor

No description? :(

@skidau skidau force-pushed the fifo-overflow branch 2 times, most recently from e061c85 to 94022e7 Compare November 14, 2014 06:15
@comex
Copy link
Contributor

comex commented Nov 14, 2014

For the record, fixing the issue I identified would involve having the threadsafe event re-check the conditions on the CPU thread (i.e. calling SetCPStatusFromCPU or whatever rather than going straight to UpdateInterrupts) in case they changed since the GPU sent it. I am somewhat skeptical this is the actual culprit, but it is definitely possible for it to cause incorrect behavior.

@skidau skidau force-pushed the fifo-overflow branch 2 times, most recently from 60b8ed2 to c5763b5 Compare November 15, 2014 01:43
@comex
Copy link
Contributor

comex commented Nov 15, 2014

My comments on the previous commits appear to be gone, so:

  • "Separated out the CPU and GPU thread path to avoid clobbering." Does separating them like this do anything other than slightly affect timing? I don't see any different logic.
  • "Flush the regcache before each FIFO write check. Fixes the FIFO overflow that occurs in NBA2K11." Why would this do anything other than, again, slightly affect timing, by forcing the JIT to reload registers for no reason?
  • "Update CPStatus before processing the FIFO events and force an exception check on interrupts." There are multiple changes here, but I don't understand why changing the order of the function calls is appropriate.
  • "Added a wait state if the CPU thread is running ahead of the GPU thread" I guess this will avoid the symptom, but it looks like a hack to me - makes sense if some emulated code is really fundamentally depending on timing of the GPU to avoid overflow, but I wouldn't be surprised if Dolphin is doing something wrong instead.

@skidau skidau force-pushed the fifo-overflow branch 2 times, most recently from bb8a5ca to ad65239 Compare November 15, 2014 04:27
@MayImilae
Copy link
Contributor

Kazuma tested it and found that The Last Story doesn't encounter fifo overflow errors in OpenGL (during the fifo overflow nasty lazulis attack). I confirmed his findings and tested in D3D as well. No fifo overflows.

@FioraAeterna
Copy link
Contributor

since my comments keep getting removed, I agree with comex on the flushing bit, that doesn't make sense to me at all

@skidau skidau force-pushed the fifo-overflow branch 9 times, most recently from 46b63ac to ab1e0b7 Compare November 18, 2014 23:07
@skidau
Copy link
Contributor Author

skidau commented Nov 18, 2014

I tried adding a SetCPStatusFromCPU call in UpdateInterrupts_Wrapper and as pointed out (in irc), that was not the best place for it and it did not have any effect that I noticed.

The idea behind separating the CPU and GPU thread path is to prevent two threads executing the same function (SetCPStatusFromCPU) at the same time. The CPU thread gets to that function via GetherPipeBursted and the GPU thread gets there via SetCPStatusFromGPU. I wrote the original (factored) version as I like to keep code duplication to a minimum. This worked most of the time but not all of the time. It was a good move to separate it to a GPU version and a CPU version, but then the GPU version called the CPU version at the tail end. Removing the call (as in this PR) prevents the FIFO overflow in Starfox Adventures.

Flushing the regcache is a strange one. I thought there was a bug in FLUSH_MAINTAIN_STATE, but I could not find it. The FLUSH_MAINTAIN_STATE code is quite simple and is correct. My next guess is that there is a regcache leakage somewhere. Force flushing the regcache prevents FIFO unknown opcodes in the intro of NBA2K11.

The "Updating the CPStatus before FIFO events" change is simply there to keep the DC code path and the SC code path consistent in the !GPLinked scenario. The SC code path does the same thing when !GPLinked via RunGPU. Putting the SetCPStatus call before the !GPLinked state changes the DC code path to do the same thing. The more we keep the DC and SC code paths consistent, the better.

Forcing the exception check on interrupts is the change for The Last Story. It makes the emulator process interrupts more responsively on CP interrupts.

I have removed the "Added a wait state" change as that code is a little too late if the user is hitting that case. It has been replaced with the HiWatermark check which is something that old (pre-2010) versions of Dolphin used to do. Games like Battalion Wars 2 do not expect the GPU to run so slowly and do not have the code to react to that situation, so this change makes the emulator extra careful in those situations.

@JMC47
Copy link
Contributor

JMC47 commented Nov 19, 2014

It seems slightly slower (4 - 5%) than Master in a lot of situations. That's probably worth the stability + accuracy, but we should make it known in the progress report/blog post that it should be expected to be slower.

@comex
Copy link
Contributor

comex commented Nov 19, 2014

These changes probably should not be affecting performance, except for the regcache one, which is just a hack and should not be merged without figuring out what the real problem is. Might be a JIT bug that has little to do with the FIFO as such...

Removed the Eternal Darkness check as it is no longer required.

Fixes issue 7835.
…ion check on interrupts.

Added more information into the FIFO unknown opcode error message.
… the fifo overflow that occurs in Battalion Wars 2.

Changed the CPEnd loop check to an exact match.
@skidau
Copy link
Contributor Author

skidau commented Nov 19, 2014

Have removed the flushing of the regcache change.

skidau added a commit that referenced this pull request Nov 19, 2014
Fifo overflow fix

The idea behind separating the CPU and GPU thread path is to prevent two threads executing the same function (SetCPStatusFromCPU) at the same time. The CPU thread gets to that function via GetherPipeBursted and the GPU thread gets there via SetCPStatusFromGPU. I wrote the original (factored) version as I like to keep code duplication to a minimum. This worked most of the time but not all of the time. It was a good move to separate it to a GPU version and a CPU version, but then the GPU version called the CPU version at the tail end. Removing the call (as in this PR) prevents the FIFO overflow in Starfox Adventures.

The "Updating the CPStatus before FIFO events" change is simply there to keep the DC code path and the SC code path consistent in the !GPLinked scenario. The SC code path does the same thing when !GPLinked via RunGPU. Putting the SetCPStatus call before the !GPLinked state changes the DC code path to do the same thing. The more we keep the DC and SC code paths consistent, the better.

Forcing the exception check on interrupts is the change for The Last Story. It makes the emulator process interrupts more responsively on CP interrupts.

The HiWatermark check is something that old (pre-2010) versions of Dolphin used to do. Games like Battalion Wars 2 do not expect the GPU to run so slowly and do not have the code to react to that situation, so this change makes the emulator extra careful in those situations.
@skidau skidau merged commit 1d1942d into dolphin-emu:master Nov 19, 2014
This pull request was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

5 participants