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

Remove the old style multithreading #10056

Merged
merged 10 commits into from
Nov 6, 2017
1 change: 0 additions & 1 deletion Core/Config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -406,7 +406,6 @@ static bool DefaultSasThread() {

static ConfigSetting cpuSettings[] = {
ReportedConfigSetting("CPUCore", &g_Config.iCpuCore, &DefaultCpuCore, true, true),
ReportedConfigSetting("SeparateCPUThread", &g_Config.bSeparateCPUThread, false, true, true),
ReportedConfigSetting("SeparateSASThread", &g_Config.bSeparateSASThread, &DefaultSasThread, true, true),
ReportedConfigSetting("SeparateIOThread", &g_Config.bSeparateIOThread, true, true, true),
ReportedConfigSetting("IOTimingMethod", &g_Config.iIOTimingMethod, IOTIMING_FAST, true, true),
Expand Down
2 changes: 0 additions & 2 deletions Core/Config.h
Original file line number Diff line number Diff line change
Expand Up @@ -132,8 +132,6 @@ struct Config {
bool bFuncReplacements;
bool bHideSlowWarnings;

// Definitely cannot be changed while game is running.
bool bSeparateCPUThread;
bool bSeparateSASThread;
bool bSeparateIOThread;
int iIOTimingMethod;
Expand Down
35 changes: 6 additions & 29 deletions Core/HLE/sceGe.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,10 +57,6 @@ static int geSyncEvent;
static int geInterruptEvent;
static int geCycleEvent;

// Let's try updating 10 times per vblank - this is the interval for geCycleEvent.
const int geIntervalUs = 1000000 / (60 * 10);
const int geBehindThresholdUs = 1000000 / (60 * 10);

class GeIntrHandler : public IntrHandler {
public:
GeIntrHandler() : IntrHandler(PSP_GE_INTR) {}
Expand Down Expand Up @@ -194,19 +190,7 @@ static void __GeExecuteInterrupt(u64 userdata, int cyclesLate) {
}

static void __GeCheckCycles(u64 userdata, int cyclesLate) {
u64 geTicks = gpu->GetTickEstimate();
if (geTicks != 0) {
if (CoreTiming::GetTicks() > geTicks + usToCycles(geBehindThresholdUs)) {
u64 diff = CoreTiming::GetTicks() - geTicks;
// Let the GPU thread catch up.
gpu->SyncThread();
CoreTiming::Advance();
}
}

// This may get out of step if we synced (because we don't correct for cyclesLate),
// but that's okay - __GeCheckCycles is a very rough way to synchronize anyway.
CoreTiming::ScheduleEvent(usToCycles(geIntervalUs), geCycleEvent, 0);
// Deprecated
}

void __GeInit() {
Expand All @@ -217,15 +201,12 @@ void __GeInit() {

geSyncEvent = CoreTiming::RegisterEvent("GeSyncEvent", &__GeExecuteSync);
geInterruptEvent = CoreTiming::RegisterEvent("GeInterruptEvent", &__GeExecuteInterrupt);

// Deprecated
geCycleEvent = CoreTiming::RegisterEvent("GeCycleEvent", &__GeCheckCycles);

listWaitingThreads.clear();
drawWaitingThreads.clear();

// When we're using separate CPU/GPU threads, we need to keep them in sync.
if (IsOnSeparateCPUThread()) {
CoreTiming::ScheduleEvent(usToCycles(geIntervalUs), geCycleEvent, 0);
}
}

struct GeInterruptData_v1 {
Expand Down Expand Up @@ -270,20 +251,18 @@ void __GeDoState(PointerWrap &p) {
void __GeShutdown() {
}

// Warning: may be called from the GPU thread, if there is a separate one (multithread mode).
bool __GeTriggerSync(GPUSyncType type, int id, u64 atTicks) {
u64 userdata = (u64)id << 32 | (u64)type;
s64 future = atTicks - CoreTiming::GetTicks();
if (type == GPU_SYNC_DRAW) {
s64 left = CoreTiming::UnscheduleThreadsafeEvent(geSyncEvent, userdata);
s64 left = CoreTiming::UnscheduleEvent(geSyncEvent, userdata);
if (left > future)
future = left;
}
CoreTiming::ScheduleEvent_Threadsafe(future, geSyncEvent, userdata);
CoreTiming::ScheduleEvent(future, geSyncEvent, userdata);
return true;
}

// Warning: may be called from the GPU thread, if there is a separate one (multithread mode).
bool __GeTriggerInterrupt(int listid, u32 pc, u64 atTicks) {
GeInterruptData intrdata;
intrdata.listid = listid;
Expand All @@ -293,7 +272,7 @@ bool __GeTriggerInterrupt(int listid, u32 pc, u64 atTicks) {
ge_pending_cb.push_back(intrdata);

u64 userdata = (u64)listid << 32 | (u64) pc;
CoreTiming::ScheduleEvent_Threadsafe(atTicks - CoreTiming::GetTicks(), geInterruptEvent, userdata);
CoreTiming::ScheduleEvent(atTicks - CoreTiming::GetTicks(), geInterruptEvent, userdata);
return true;
}

Expand Down Expand Up @@ -504,7 +483,6 @@ static int sceGeUnsetCallback(u32 cbID) {
// unless some insane game pokes it and relies on it...
u32 sceGeSaveContext(u32 ctxAddr) {
DEBUG_LOG(SCEGE, "sceGeSaveContext(%08x)", ctxAddr);
gpu->SyncThread();

if (gpu->BusyDrawing()) {
WARN_LOG(SCEGE, "sceGeSaveContext(%08x): lists in process, aborting", ctxAddr);
Expand All @@ -524,7 +502,6 @@ u32 sceGeSaveContext(u32 ctxAddr) {

u32 sceGeRestoreContext(u32 ctxAddr) {
DEBUG_LOG(SCEGE, "sceGeRestoreContext(%08x)", ctxAddr);
gpu->SyncThread();

if (gpu->BusyDrawing()) {
WARN_LOG(SCEGE, "sceGeRestoreContext(%08x): lists in process, aborting", ctxAddr);
Expand Down
49 changes: 18 additions & 31 deletions Core/System.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -328,7 +328,6 @@ void CPU_RunLoop() {
switch (cpuThreadState) {
case CPU_THREAD_EXECUTE:
mipsr4k.RunLoopUntil(cpuThreadUntil);
gpu->FinishEventLoop();
CPU_NextState(CPU_THREAD_EXECUTE, CPU_THREAD_RUNNING);
break;

Expand All @@ -354,12 +353,6 @@ void CPU_RunLoop() {
coreState = CORE_POWERDOWN;
}

// Let's make sure the gpu has already cleaned up before we start freeing memory.
if (gpu) {
gpu->FinishEventLoop();
gpu->SyncThread(true);
}

CPU_Shutdown();
CPU_SetState(CPU_THREAD_NOT_RUNNING);
}
Expand All @@ -384,18 +377,15 @@ static void Core_UpdateDebugStats(bool flag) {
void System_Wake() {
// Ping the threads so they check coreState.
CPU_NextStateNot(CPU_THREAD_NOT_RUNNING, CPU_THREAD_SHUTDOWN);
if (gpu) {
gpu->FinishEventLoop();
}
}

// Ugly!
static bool pspIsInited = false;
static bool pspIsIniting = false;
static bool pspIsQuiting = false;
static bool pspIsQuitting = false;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Derp, this is my typo. Thanks.

-[Unknown]


bool PSP_InitStart(const CoreParameter &coreParam, std::string *error_string) {
if (pspIsIniting || pspIsQuiting) {
if (pspIsIniting || pspIsQuitting) {
return false;
}

Expand All @@ -415,7 +405,9 @@ bool PSP_InitStart(const CoreParameter &coreParam, std::string *error_string) {
coreParameter.errorString = "";
pspIsIniting = true;

if (g_Config.bSeparateCPUThread) {
// Keeping this around because we might need it in the future.
const bool separateCPUThread = false;
if (separateCPUThread) {
Core_ListenShutdown(System_Wake);
CPU_SetState(CPU_THREAD_PENDING);
cpuThread = new std::thread(&CPU_RunLoop);
Expand All @@ -438,7 +430,7 @@ bool PSP_InitUpdate(std::string *error_string) {
return true;
}

if (g_Config.bSeparateCPUThread && !CPU_IsReady()) {
if (!CPU_IsReady()) {
return false;
}

Expand All @@ -459,7 +451,8 @@ bool PSP_InitUpdate(std::string *error_string) {
bool PSP_Init(const CoreParameter &coreParam, std::string *error_string) {
PSP_InitStart(coreParam, error_string);

if (g_Config.bSeparateCPUThread) {
// For a potential resurrection of separate CPU thread later.
if (false) {
CPU_WaitStatus(cpuThreadReplyCond, &CPU_IsReady);
}

Expand All @@ -472,12 +465,12 @@ bool PSP_IsIniting() {
}

bool PSP_IsInited() {
return pspIsInited && !pspIsQuiting;
return pspIsInited && !pspIsQuitting;
}

void PSP_Shutdown() {
// Do nothing if we never inited.
if (!pspIsInited && !pspIsIniting && !pspIsQuiting) {
if (!pspIsInited && !pspIsIniting && !pspIsQuitting) {
return;
}

Expand All @@ -488,7 +481,7 @@ void PSP_Shutdown() {
#endif

// Make sure things know right away that PSP memory, etc. is going away.
pspIsQuiting = true;
pspIsQuitting = true;
if (coreState == CORE_RUNNING)
Core_UpdateState(CORE_ERROR);
Core_NotifyShutdown();
Expand All @@ -507,7 +500,7 @@ void PSP_Shutdown() {
currentMIPS = 0;
pspIsInited = false;
pspIsIniting = false;
pspIsQuiting = false;
pspIsQuitting = false;
g_Config.unloadGameConfig();
}

Expand All @@ -532,40 +525,34 @@ void PSP_RunLoopUntil(u64 globalticks) {
return;
}

// Switch the CPU thread on or off, as the case may be.
bool useCPUThread = g_Config.bSeparateCPUThread;
// We no longer allow a separate CPU thread but if we add a render queue
// to GL we're gonna need it.
bool useCPUThread = false;
if (useCPUThread && cpuThread == nullptr) {
// Need to start the cpu thread.
Core_ListenShutdown(System_Wake);
CPU_SetState(CPU_THREAD_RESUME);
cpuThread = new std::thread(&CPU_RunLoop);
cpuThreadID = cpuThread->get_id();
cpuThread->detach();
if (gpu) {
gpu->SetThreadEnabled(true);
}
// Probably needs to tell the gpu that it will need to queue up its output
// on another thread.
CPU_WaitStatus(cpuThreadReplyCond, &CPU_IsReady);
} else if (!useCPUThread && cpuThread != nullptr) {
CPU_SetState(CPU_THREAD_QUIT);
CPU_WaitStatus(cpuThreadReplyCond, &CPU_IsShutdown);
delete cpuThread;
cpuThread = nullptr;
cpuThreadID = std::thread::id();
if (gpu) {
gpu->SetThreadEnabled(false);
}
}

if (cpuThread != nullptr) {
// Tell the gpu a new frame is about to begin, before we start the CPU.
gpu->SyncBeginFrame();

cpuThreadUntil = globalticks;
if (CPU_NextState(CPU_THREAD_RUNNING, CPU_THREAD_EXECUTE)) {
// The CPU doesn't actually respect cpuThreadUntil well, especially when skipping frames.
// TODO: Something smarter? Or force CPU to bail periodically?
while (!CPU_IsReady()) {
gpu->RunEventsUntil(CoreTiming::GetTicks() + msToCycles(1000));
// Have the GPU do stuff here.
if (coreState != CORE_RUNNING) {
CPU_WaitStatus(cpuThreadReplyCond, &CPU_IsReady);
}
Expand Down
1 change: 1 addition & 0 deletions GPU/Common/SoftwareTransformCommon.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -400,6 +400,7 @@ void SoftwareTransform(
// rectangle out of many. Quite a small optimization though.
// Experiment: Disable on PowerVR (see issue #6290)
// TODO: This bleeds outside the play area in non-buffered mode. Big deal? Probably not.
// TODO: Allow creating a depth clear and a color draw.
bool reallyAClear = false;
if (maxIndex > 1 && prim == GE_PRIM_RECTANGLES && gstate.isModeClear()) {
int scissorX2 = gstate.getScissorX2() + 1;
Expand Down
4 changes: 3 additions & 1 deletion GPU/D3D11/DrawEngineD3D11.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

#pragma once

#include <map>
#include <d3d11.h>
#include <d3d11_1.h>

Expand Down Expand Up @@ -190,7 +191,8 @@ class DrawEngineD3D11 : public DrawEngineCommon {
PushBufferD3D11 *pushVerts_;
PushBufferD3D11 *pushInds_;

// D3D11 state object caches
// D3D11 state object caches.
// TODO: Change them to DenseHashMaps.
std::map<uint64_t, ID3D11BlendState *> blendCache_;
std::map<uint64_t, ID3D11BlendState1 *> blendCache1_;
std::map<uint64_t, ID3D11DepthStencilState *> depthStencilCache_;
Expand Down
28 changes: 7 additions & 21 deletions GPU/D3D11/GPU_D3D11.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -286,7 +286,7 @@ void GPU_D3D11::DeviceRestore() {
// Nothing needed.
}

void GPU_D3D11::InitClearInternal() {
void GPU_D3D11::InitClear() {
bool useNonBufferedRendering = g_Config.iRenderingMode == FB_NON_BUFFERED_MODE;
if (useNonBufferedRendering) {
// device_->Clear(0, NULL, D3DCLEAR_STENCIL | D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0, 0, 0), 1.f, 0);
Expand All @@ -305,8 +305,8 @@ void GPU_D3D11::BeginHostFrame() {
}
}

void GPU_D3D11::ReapplyGfxStateInternal() {
GPUCommon::ReapplyGfxStateInternal();
void GPU_D3D11::ReapplyGfxState() {
GPUCommon::ReapplyGfxState();

// TODO: Dirty our caches for depth states etc
}
Expand All @@ -316,8 +316,8 @@ void GPU_D3D11::EndHostFrame() {
draw_->BindPipeline(nullptr);
}

void GPU_D3D11::BeginFrameInternal() {
GPUCommon::BeginFrameInternal();
void GPU_D3D11::BeginFrame() {
GPUCommon::BeginFrame();

textureCacheD3D11_->StartFrame();
drawEngine_.BeginFrame();
Expand All @@ -338,13 +338,6 @@ void GPU_D3D11::SetDisplayFramebuffer(u32 framebuf, u32 stride, GEBufferFormat f
}

bool GPU_D3D11::FramebufferDirty() {
// FIXME: Workaround for displaylists sometimes hanging unprocessed. Not yet sure of the cause.
if (ThreadEnabled()) {
// FIXME: Workaround for displaylists sometimes hanging unprocessed. Not yet sure of the cause.
ScheduleEvent(GPU_EVENT_PROCESS_QUEUE);
// Allow it to process fully before deciding if it's dirty.
SyncThread();
}
VirtualFramebuffer *vfb = framebufferManager_->GetDisplayVFB();
if (vfb) {
bool dirty = vfb->dirtyAfterDisplay;
Expand All @@ -353,15 +346,8 @@ bool GPU_D3D11::FramebufferDirty() {
}
return true;
}
bool GPU_D3D11::FramebufferReallyDirty() {
// FIXME: Workaround for displaylists sometimes hanging unprocessed. Not yet sure of the cause.
if (ThreadEnabled()) {
// FIXME: Workaround for displaylists sometimes hanging unprocessed. Not yet sure of the cause.
ScheduleEvent(GPU_EVENT_PROCESS_QUEUE);
// Allow it to process fully before deciding if it's dirty.
SyncThread();
}

bool GPU_D3D11::FramebufferReallyDirty() {
VirtualFramebuffer *vfb = framebufferManager_->GetDisplayVFB();
if (vfb) {
bool dirty = vfb->reallyDirtyAfterDisplay;
Expand All @@ -371,7 +357,7 @@ bool GPU_D3D11::FramebufferReallyDirty() {
return true;
}

void GPU_D3D11::CopyDisplayToOutputInternal() {
void GPU_D3D11::CopyDisplayToOutput() {
float blendColor[4]{};
context_->OMSetBlendState(stockD3D11.blendStateDisabledWithColorMask[0xF], blendColor, 0xFFFFFFFF);

Expand Down
8 changes: 4 additions & 4 deletions GPU/D3D11/GPU_D3D11.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ class GPU_D3D11 : public GPUCommon {
void PreExecuteOp(u32 op, u32 diff) override;
void ExecuteOp(u32 op, u32 diff) override;

void ReapplyGfxStateInternal() override;
void ReapplyGfxState() override;
void SetDisplayFramebuffer(u32 framebuf, u32 stride, GEBufferFormat format) override;
void GetStats(char *buffer, size_t bufsize) override;
void ClearCacheNextFrame() override;
Expand Down Expand Up @@ -96,9 +96,9 @@ class GPU_D3D11 : public GPUCommon {
void CheckFlushOp(int cmd, u32 diff);
void BuildReportingInfo();

void InitClearInternal() override;
void BeginFrameInternal() override;
void CopyDisplayToOutputInternal() override;
void InitClear() override;
void BeginFrame() override;
void CopyDisplayToOutput() override;

ID3D11Device *device_;
ID3D11DeviceContext *context_;
Expand Down
Loading