summaryrefslogtreecommitdiff
path: root/Source/Core/VideoCommon/Fifo.cpp
AgeCommit message (Collapse)Author
2016-04-10Alternative fix: promote cycleslate to an s64 everywhere.Scott Mansell
Also changed a few functions to be static.
2016-01-25Fifo: Make g_use_deterministic_gpu_thread a TU-local variableLioncash
2016-01-25Fifo: Make g_bSkipCurrentFrame a TU-local variableLioncash
This is only ever queried, making it a global isn't necessary.
2016-01-25Merge pull request #3530 from degasus/syncgpufixPierre Bourdon
Fifo: Fix SyncGPU.
2016-01-24Fifo: More comments for SyncGPU functions.degasus
2016-01-24Fifo: Fix SyncGPU.degasus
CBoot::BootUp() did call CoreTiming::Advance which itself blocks on the GPU, but the GPU thread wasn't started already. This commit moves the SyncGPU initialization into the Fifo.cpp file and call it after BootUp().
2016-01-24OpcodeDecoder: Add namespaceLioncash
2016-01-17VideoCommon: Header cleanupLioncash
Also remedies places where the video backends and core rely on things being indirectly included.
2016-01-12Fifo: Create a "Fifo" namespace.degasus
2015-12-25Fifo: Convert define into constantLioncash
Also moves it to the cpp file where it's used.
2015-11-02VideoCommon: VertexManager -> VertexManagerBaseTillmann Karras
It may be a bit weird to see calls to static functions in VertexManagerBase now, but at least it's easier to see what's going on.
2015-09-11Partially revert "General: Toss out PRI macro usage"Lioncash
2015-06-12Options: merge SCoreStartupParameter into SConfigdegasus
2015-06-08Fifo: Rewrite SyncGpudegasus
The new implementation has 3 options: SyncGpuMaxDistance SyncGpuMinDistance SyncGpuOverclock The MaxDistance controlls how many CPU cycles the CPU is allowed to be in front of the GPU. Too low values will slow down extremly, too high values are as unsynchronized and half of the games will crash. The -MinDistance (negative) set how many cycles the GPU is allowed to be in front of the CPU. As we are used to emulate an infinitiv fast GPU, this may be set to any high (negative) number. The last parameter is to hack a faster (>1.0) or slower(<1.0) GPU. As we don't emulate GPU timing very well (eg skip the timings of the pixel stage completely), an overclock factor of ~0.5 is often much more accurate than 1.0
2015-05-30Common: Update BlockingLoop to only use one atomic.degasus
This merges two atomic<bool> into one atomic<int>. We did move the bit from one bool to another, now we can use operator--.
2015-05-30Fifo: Extract syncing loopdegasus
It's now a new helper function within common.
2015-05-27CommandProcessor: Replace volatile usages with atomicsLioncash
Also remove said variables from being globals.
2015-05-27Fifo: Replace usages of volatile with atomicsLioncash
2015-05-25Set copyright year to when a file was createdTillmann Karras
2015-05-25Update license headers to GPLv2+Tillmann Karras
2015-04-21Exit ReadDataFromFifoOnCPU, PushFifoAuxBuffer early if shutting down ↵comex
(GpuRunningState=false) This was causing a race condition where the "absurdly large aux buffer" panic alert would be triggered in the last bit of fifo processing on the CPU thread in deterministic mode (i.e. netplay). SyncGPU is supposed to move the auxiliary queue data to the beginning of the containing buffer so we don't have to deal with wraparound; if GpuRunningState is false, however, it just returns, because it's set to false by another thread - thus it doesn't know whether RunGpuLoop is still executing (in which case it can't just reset the pointers, because it may still be using the buffer) or not (in which case the condition variable it normally waits for to avoid the previous problem will never be signaled). However, SyncGPU's caller PushFifoAuxBuffer wasn't aware of this, so if the buffer was filling at just the right time, it'd stay full and that function would complain that it was about to overflow it. Similar problem with ReadDataFromFifoOnCPU afaik. Fix this by returning early from those as well; other callers of SyncGPU should be safe. A *slightly* cleaner alternative would be giving the CPU thread a way to tell when RunGpuLoop has actually exited, but whatever, this works.
2015-04-06Fifo: rewrite Fifo_PauseAndLockdegasus
This lock isn't required any more as our FlushGpu garanty to block until the GPU is idle
2015-04-06Fifo: only touch the SIMD state once in the single core loopdegasus
2015-04-06Fifo: only sleep once within every ms of emulated timedegasus
2015-04-06Fifo: rewrite sync on idle skipping hackdegasus
Now it's done without a busy loop
2015-04-06Fifo: use the outer loop on sync GPUdegasus
2015-04-06Fifo: Replace busy loop with condition variabledegasus
2015-02-28Fifo: small cleanupTillmann Karras
2015-02-28Fifo: drop unused functionsTillmann Karras
2015-02-22VideoCommon: perf querys by async eventsdegasus
2015-02-22VideoCommon: implement swap requests in the full async waydegasus
2015-02-22VideoCommon: use a new async event system for efb accessdegasus
2014-12-10FIFO: allocate slightly more for SIMD vertex loader overreadsFiora
May fix crashes in rare cases.
2014-12-09VideoCommon: cleanup OpcodeDecoderdegasus
2014-12-09VideoCommon: fifo cleanupsdegasus
2014-12-07Idle loop in GPU loop on dual core systems.Ryan Houdek
Previously we had decided to busy loop on systems due to Windows' scheduler being terrible and moving us around CPU cores when we yielded. Along with context switching being a hot spot. We had decided to busy loop in these situations instead, which allows us greater CPU performance on the video thread. This can be attributed to multiple things, CPU not downclocking while busy looping, context switches happening less often, yielding taking more time than a busy loop, etc. One thing we had considered when moving over to a busy loop is the issues that dual core systems would now face due to Dolphin eating all of their CPU resources. Effectively we are starving a dual core system of any time to do anything else due to the CPU thread always being pinned at 100% and then the GPU thread also always at 100% just spinning around. We noted the potential for a performance regression, but dismissed it as most computers are now becoming quad core or higher. This change in particular has performance advantages on the dual core Nvidia Denver due to its architecture being nonstandard. If both CPU cores are maxed out, the CPU can't effectively take any idle time to recompile host code blocks to its native VLIW architecture. It can still do so, but it does less frequently which results in performance issues in Dolphin due to most code just running through the in-order instruction decoder instead of the native VLIW architecture. In one particular example, yielding moves the performance from 35-40FPS to 50-55FPS. So it is far more noticeable on Denver than any other system. Of course once a triple or quad core Denver system comes out this will no longer be an issue on this architecture since it'll have a free core to do all of this work.
2014-11-15OpcodeDecoder: Skip recursiv display listsdegasus
2014-11-01VideoCommon: Remove GetPointer in fifo codedegasus
2014-09-30VideoCommon: Silence -Wmaybe-uninitialized warnings.Rohit Nirmal
2014-09-29ReadDataFromFifo is always called with len = 32. Remove the parameter to ↵comex
enable optimizations. And rename some variables around it to be less confusing.
2014-09-28Add the override config option.comex
I hate the config code, but now is not the time to fix it...
2014-09-28Add a central variable g_want_determinism which controls whether to try to ↵comex
make things deterministic. It now affects the GPU determinism mode as well as some miscellaneous things that were calling IsNetPlayRunning. Probably incomplete. Notably, this can change while paused, if the user starts recording a movie. The movie code appears to have been missing locking between setting g_playMode and doing other things, which probably had a small chance of causing crashes or even desynced movies; fix that with PauseAndLock. The next commit will add a hidden config variable to override GPU determinism mode.
2014-09-28Add the 'desynced GPU thread' mode.comex
It's a relatively big commit (less big with -w), but it's hard to test any of this separately... The basic problem is that in netplay or movies, the state of the CPU must be deterministic, including when the game receives notification that the GPU has processed FIFO data. Dual core mode notifies the game whenever the GPU thread actually gets around to doing the work, so it isn't deterministic. Single core mode is because it notifies the game 'instantly' (after processing the data synchronously), but it's too slow for many systems and games. My old dc-netplay branch worked as follows: everything worked as normal except the state of the CP registers was a lie, and the CPU thread only delivered results when idle detection triggered (waiting for the GPU if they weren't ready at that point). Usually, a game is idle iff all the work for the frame has been done, except for a small amount of work depending on the GPU result, so neither the CPU or the GPU waiting on the other affected performance much. However, it's possible that the game could be waiting for some earlier interrupt, and any of several games which, for whatever reason, never went into a detectable idle (even when I tried to improve the detection) would never receive results at all. (The current method should have better compatibility, but it also has slightly higher overhead and breaks some other things, so I want to reimplement this, hopefully with less impact on the code, in the future.) With this commit, the basic idea is that the CPU thread acts as if the work has been done instantly, like single core mode, but actually hands it off asynchronously to the GPU thread (after backing up some data that the game might change in memory before it's actually done). Since the work isn't done, any feedback from the GPU to the CPU, such as real XFB/EFB copies (virtual are OK), EFB pokes, performance queries, etc. is broken; but most games work with these options disabled, and there is no need to try to detect what the CPU thread is doing. Technically: when the flag g_use_deterministic_gpu_thread (currently stuck on) is on, the CPU thread calls RunGpu like in single core mode. This function synchronously copies the data from the FIFO to the internal video buffer and updates the CP registers, interrupts, etc. However, instead of the regular ReadDataFromFifo followed by running the opcode decoder, it runs ReadDataFromFifoOnCPU -> OpcodeDecoder_Preprocess, which relatively quickly scans through the FIFO data, detects SetFinish calls etc., which are immediately fired, and saves certain associated data from memory (e.g. display lists) in AuxBuffers (a parallel stream to the main FIFO, which is a bit slow at the moment), before handing the data off to the GPU thread to actually render. That makes up the bulk of this commit. In various circumstances, including the aforementioned EFB pokes and performance queries as well as swap requests (i.e. the end of a frame - we don't want the CPU potentially pumping out frames too quickly and the GPU falling behind*), SyncGPU is called to wait for actual completion. The overhead mainly comes from OpcodeDecoder_Preprocess (which is, again, synchronous), as well as the actual copying. Currently, display lists and such are escrowed from main memory even though they usually won't change over the course of a frame, and textures are not even though they might, resulting in a small chance of graphical glitches. When the texture locking (i.e. fault on write) code lands, I can make this all correct and maybe a little faster. * This suggests an alternate determinism method of just delaying results until a short time before the end of each frame. For all I know this might mostly work - I haven't tried it - but if any significant work hinges on the competion of render to texture etc., the frame will be missed.
2014-09-28Make ReadDataFromFifo static.comex
2014-09-28Rejigger some FIFO buffer variables to be more rational.comex
videoBuffer -> s_video_buffer size -> s_video_buffer_write_ptr g_pVideoData -> g_video_buffer_read_ptr (impl moved to Fifo.cpp) This eradicates the wonderful use of 'size' as a global name, and makes it clear that s_video_buffer_write_ptr and g_video_buffer_read_ptr are the two ends of the FIFO buffer s_video_buffer. Oh, and remove a useless namespace {}.
2014-09-09Kill Core::g_CoreStartupParameter.Rachel Bryk
2014-09-05Merge pull request #967 from skidau/SyncGPU-SaveStateskidau
Added the EmuRunningState check to the GPU thread's FIFO loop
2014-09-04VideoCommon: rewrite frame skipping codedegasus
2014-09-04Added the EmuRunningState check to the GPU thread's FIFO loop so that the ↵skidau
GPU thread services any waiting save states. This is needed for games that have the Sync GPU option enabled.
2014-09-01Refactor opcode decoding a bit to kill FifoCommandRunnable.comex
Separated out from my gpu-determinism branch by request. It's not a big commit; I just like to write long commit messages. The main reason to kill it is hopefully a slight performance improvement from avoiding the double switch (especially in single core mode); however, this also improves cycle calculation, as described below. - FifoCommandRunnable is removed; in its stead, Decode returns the number of cycles (which only matters for "sync" GPU mode), or 0 if there was not enough data, and is also responsible for unknown opcode alerts. Decode and DecodeSemiNop are almost identical, so the latter is replaced with a skipped_frame parameter to Decode. Doesn't mean we can't improve skipped_frame mode to do less work; if, at such a point, branching on it has too much overhead (it certainly won't now), it can always be changed to a template parameter. - FifoCommandRunnable used a fixed, large cycle count for display lists, regardless of the contents. Presumably the actual hardware's processing time is mostly the processing time of whatever commands are in the list, and with this change InterpretDisplayList can just return the list's cycle count to be added to the total. (Since the calculation for this is part of Decode, it didn't seem easy to split this change up.) To facilitate this, Decode also gains an explicit 'end' parameter in lieu of FifoCommandRunnable's call to GetVideoBufferEndPtr, which can point to there or to the end of a display list (or elsewhere in gpu-determinism, but that's another story). Also, as a small optimization, InterpretDisplayList now calls OpcodeDecoder_Run rather than having its own Decode loop, to allow Decode to be inlined (haven't checked whether this actually happens though). skipped_frame mode still does not traverse display lists and uses the old fake value of 45 cycles. degasus has suggested that this hack is not essential for performance and can be removed, but I want to separate any potential performance impact of that from this commit.