mirror of https://github.com/PCSX2/pcsx2.git
MTVU/MTGS: use a mutex free ring buffer
Most of the time the mutex was likely optimized. Now we have the guarantee that thread won't block.
This commit is contained in:
parent
e4f4350bb4
commit
7b3984059a
|
@ -17,6 +17,11 @@
|
||||||
#include <deque>
|
#include <deque>
|
||||||
#include "System/SysThreads.h"
|
#include "System/SysThreads.h"
|
||||||
#include "Gif.h"
|
#include "Gif.h"
|
||||||
|
#include "GS.h"
|
||||||
|
|
||||||
|
// FIXME common path ?
|
||||||
|
#include "../plugins/GSdx/boost_spsc_queue.hpp"
|
||||||
|
|
||||||
struct GS_Packet;
|
struct GS_Packet;
|
||||||
extern void Gif_MTGS_Wait(bool isMTVU);
|
extern void Gif_MTGS_Wait(bool isMTVU);
|
||||||
extern void Gif_FinishIRQ();
|
extern void Gif_FinishIRQ();
|
||||||
|
@ -147,10 +152,13 @@ static __fi void incTag(u32& offset, u32& size, u32 incAmount) {
|
||||||
struct Gif_Path_MTVU {
|
struct Gif_Path_MTVU {
|
||||||
u32 fakePackets; // Fake packets pending to be sent to MTGS
|
u32 fakePackets; // Fake packets pending to be sent to MTGS
|
||||||
GS_Packet fakePacket;
|
GS_Packet fakePacket;
|
||||||
Mutex gsPackMutex; // Used for atomic access to gsPackQueue
|
// Set a size based on MTGS but keep a factor 2 to avoid too waste to much
|
||||||
std::deque<GS_Packet> gsPackQueue; // VU1 programs' XGkick(s)
|
// memory overhead. Note the struct is instantied 3 times (for each gif
|
||||||
|
// path)
|
||||||
|
ringbuffer_base<GS_Packet, RingBufferSize / 2> gsPackQueue;
|
||||||
Gif_Path_MTVU() { Reset(); }
|
Gif_Path_MTVU() { Reset(); }
|
||||||
void Reset() { fakePackets = 0; gsPackQueue.clear();
|
void Reset() { fakePackets = 0;
|
||||||
|
gsPackQueue.reset();
|
||||||
fakePacket.Reset();
|
fakePacket.Reset();
|
||||||
fakePacket.done = 1; // Fake packets don't get processed by pcsx2
|
fakePacket.done = 1; // Fake packets don't get processed by pcsx2
|
||||||
fakePacket.size =~0u; // Used to indicate that its a fake packet
|
fakePacket.size =~0u; // Used to indicate that its a fake packet
|
||||||
|
@ -380,22 +388,21 @@ struct Gif_Path {
|
||||||
|
|
||||||
// MTVU: Gets called after VU1 execution on MTVU thread
|
// MTVU: Gets called after VU1 execution on MTVU thread
|
||||||
void FinishGSPacketMTVU() {
|
void FinishGSPacketMTVU() {
|
||||||
if (1) {
|
|
||||||
ScopedLock lock(mtvu.gsPackMutex);
|
|
||||||
readAmount.fetch_add(gsPack.size + gsPack.readAmount);
|
readAmount.fetch_add(gsPack.size + gsPack.readAmount);
|
||||||
mtvu.gsPackQueue.push_back(gsPack);
|
while (!mtvu.gsPackQueue.push(gsPack))
|
||||||
}
|
;
|
||||||
|
|
||||||
gsPack.Reset();
|
gsPack.Reset();
|
||||||
gsPack.offset = curOffset;
|
gsPack.offset = curOffset;
|
||||||
}
|
}
|
||||||
|
|
||||||
// MTVU: Gets called by MTGS thread
|
// MTVU: Gets called by MTGS thread
|
||||||
GS_Packet GetGSPacketMTVU() {
|
GS_Packet GetGSPacketMTVU() {
|
||||||
ScopedLock lock(mtvu.gsPackMutex);
|
// FIXME is the error path useful ?
|
||||||
if (mtvu.gsPackQueue.size()) {
|
if (!mtvu.gsPackQueue.empty()) {
|
||||||
GS_Packet t = mtvu.gsPackQueue[0];
|
return mtvu.gsPackQueue.front();
|
||||||
return t; // XGkick GS packet(s)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Console.Error("MTVU: Expected gsPackQueue to have elements!");
|
Console.Error("MTVU: Expected gsPackQueue to have elements!");
|
||||||
pxAssert(0);
|
pxAssert(0);
|
||||||
return GS_Packet(); // gsPack.size will be 0
|
return GS_Packet(); // gsPack.size will be 0
|
||||||
|
@ -403,18 +410,13 @@ struct Gif_Path {
|
||||||
|
|
||||||
// MTVU: Gets called by MTGS thread
|
// MTVU: Gets called by MTGS thread
|
||||||
void PopGSPacketMTVU() {
|
void PopGSPacketMTVU() {
|
||||||
ScopedLock lock(mtvu.gsPackMutex);
|
mtvu.gsPackQueue.pop();
|
||||||
if (mtvu.gsPackQueue.size()) {
|
|
||||||
mtvu.gsPackQueue.pop_front();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// MTVU: Returns the amount of pending
|
// MTVU: Returns the amount of pending
|
||||||
// GS Packets that MTGS hasn't yet processed
|
// GS Packets that MTGS hasn't yet processed
|
||||||
u32 GetPendingGSPackets() {
|
u32 GetPendingGSPackets() {
|
||||||
ScopedLock lock(mtvu.gsPackMutex);
|
return mtvu.gsPackQueue.size();
|
||||||
u32 t = mtvu.gsPackQueue.size();
|
|
||||||
return t;
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue