mirror of
https://github.com/libretro/ppsspp.git
synced 2024-12-04 07:00:51 +00:00
Merge pull request #3057 from unknownbrackets/gpu-thread
Prep work for GE and CPU on separate threads
This commit is contained in:
commit
73d7f491ca
@ -34,9 +34,6 @@ enum GPUCore {
|
||||
struct CoreParameter
|
||||
{
|
||||
CoreParameter() : collectEmuLog(0), unthrottle(false), fpsLimit(0), updateRecent(true) {}
|
||||
// 0 = Interpreter
|
||||
// 1 = Jit
|
||||
// 2 = JitIL
|
||||
CPUCore cpuCore;
|
||||
GPUCore gpuCore;
|
||||
bool enableSound; // there aren't multiple sound cores.
|
||||
|
@ -150,6 +150,14 @@ void PSP_Shutdown()
|
||||
currentCPU = 0;
|
||||
}
|
||||
|
||||
void PSP_RunLoopUntil(u64 globalticks) {
|
||||
mipsr4k.RunLoopUntil(globalticks);
|
||||
}
|
||||
|
||||
void PSP_RunLoopFor(int cycles) {
|
||||
PSP_RunLoopUntil(CoreTiming::GetTicks() + cycles);
|
||||
}
|
||||
|
||||
CoreParameter &PSP_CoreParameter()
|
||||
{
|
||||
return coreParameter;
|
||||
|
@ -41,8 +41,8 @@ extern GlobalUIState globalUIState;
|
||||
bool PSP_Init(const CoreParameter &coreParam, std::string *error_string);
|
||||
bool PSP_IsInited();
|
||||
void PSP_Shutdown();
|
||||
void PSP_HWAdvance(int cycles);
|
||||
void PSP_SWI();
|
||||
void PSP_RunLoopUntil(u64 globalticks);
|
||||
void PSP_RunLoopFor(int cycles);
|
||||
|
||||
void GetSysDirectories(std::string &memstickpath, std::string &flash0path);
|
||||
|
||||
|
@ -235,7 +235,7 @@ void GLES_GPU::BuildReportingInfo() {
|
||||
|
||||
void GLES_GPU::DeviceLost() {
|
||||
// Simply drop all caches and textures.
|
||||
// FBO:s appear to survive? Or no?
|
||||
// FBOs appear to survive? Or no?
|
||||
shaderManager_->ClearCache(false);
|
||||
textureCache_.Clear(false);
|
||||
framebufferManager_.DeviceLost();
|
||||
|
@ -470,6 +470,46 @@ inline void GPUCommon::UpdatePC(u32 currentPC, u32 newPC)
|
||||
downcount = 0;
|
||||
}
|
||||
|
||||
void GPUCommon::ReapplyGfxState()
|
||||
{
|
||||
// ShaderManager_DirtyShader();
|
||||
// The commands are embedded in the command memory so we can just reexecute the words. Convenient.
|
||||
// To be safe we pass 0xFFFFFFF as the diff.
|
||||
/*
|
||||
ExecuteOp(gstate.cmdmem[GE_CMD_ALPHABLENDENABLE], 0xFFFFFFFF);
|
||||
ExecuteOp(gstate.cmdmem[GE_CMD_ALPHATESTENABLE], 0xFFFFFFFF);
|
||||
ExecuteOp(gstate.cmdmem[GE_CMD_BLENDMODE], 0xFFFFFFFF);
|
||||
ExecuteOp(gstate.cmdmem[GE_CMD_ZTEST], 0xFFFFFFFF);
|
||||
ExecuteOp(gstate.cmdmem[GE_CMD_ZTESTENABLE], 0xFFFFFFFF);
|
||||
ExecuteOp(gstate.cmdmem[GE_CMD_CULL], 0xFFFFFFFF);
|
||||
ExecuteOp(gstate.cmdmem[GE_CMD_CULLFACEENABLE], 0xFFFFFFFF);
|
||||
ExecuteOp(gstate.cmdmem[GE_CMD_SCISSOR1], 0xFFFFFFFF);
|
||||
ExecuteOp(gstate.cmdmem[GE_CMD_SCISSOR2], 0xFFFFFFFF);
|
||||
*/
|
||||
|
||||
for (int i = GE_CMD_VERTEXTYPE; i < GE_CMD_BONEMATRIXNUMBER; i++)
|
||||
{
|
||||
if (i != GE_CMD_ORIGIN)
|
||||
ExecuteOp(gstate.cmdmem[i], 0xFFFFFFFF);
|
||||
}
|
||||
|
||||
// Can't write to bonematrixnumber here
|
||||
|
||||
for (int i = GE_CMD_MORPHWEIGHT0; i < GE_CMD_PATCHFACING; i++)
|
||||
{
|
||||
ExecuteOp(gstate.cmdmem[i], 0xFFFFFFFF);
|
||||
}
|
||||
|
||||
// There are a few here in the middle that we shouldn't execute...
|
||||
|
||||
for (int i = GE_CMD_VIEWPORTX1; i < GE_CMD_TRANSFERSTART; i++)
|
||||
{
|
||||
ExecuteOp(gstate.cmdmem[i], 0xFFFFFFFF);
|
||||
}
|
||||
|
||||
// TODO: there's more...
|
||||
}
|
||||
|
||||
inline void GPUCommon::UpdateState(GPUState state)
|
||||
{
|
||||
gpuState = state;
|
||||
@ -477,34 +517,35 @@ inline void GPUCommon::UpdateState(GPUState state)
|
||||
downcount = 0;
|
||||
}
|
||||
|
||||
bool GPUCommon::ProcessDLQueue()
|
||||
{
|
||||
int GPUCommon::GetNextListIndex() {
|
||||
auto iter = dlQueue.begin();
|
||||
if (iter != dlQueue.end()) {
|
||||
return *iter;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
bool GPUCommon::ProcessDLQueue() {
|
||||
startingTicks = CoreTiming::GetTicks();
|
||||
cyclesExecuted = 0;
|
||||
|
||||
if (startingTicks < busyTicks)
|
||||
{
|
||||
if (startingTicks < busyTicks) {
|
||||
DEBUG_LOG(HLE, "Can't execute a list yet, still busy for %lld ticks", busyTicks - startingTicks);
|
||||
return false;
|
||||
}
|
||||
|
||||
DisplayListQueue::iterator iter = dlQueue.begin();
|
||||
while (iter != dlQueue.end())
|
||||
{
|
||||
DisplayList &l = dls[*iter];
|
||||
DEBUG_LOG(G3D,"Okay, starting DL execution at %08x - stall = %08x", l.pc, l.stall);
|
||||
if (!InterpretList(l))
|
||||
{
|
||||
for (int listIndex = GetNextListIndex(); listIndex != -1; listIndex = GetNextListIndex()) {
|
||||
DisplayList &l = dls[listIndex];
|
||||
DEBUG_LOG(G3D, "Okay, starting DL execution at %08x - stall = %08x", l.pc, l.stall);
|
||||
if (!InterpretList(l)) {
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
//At the end, we can remove it from the queue and continue
|
||||
dlQueue.erase(iter);
|
||||
//this invalidated the iterator, let's fix it
|
||||
iter = dlQueue.begin();
|
||||
} else {
|
||||
// At the end, we can remove it from the queue and continue.
|
||||
dlQueue.erase(std::remove(dlQueue.begin(), dlQueue.end(), listIndex), dlQueue.end());
|
||||
}
|
||||
}
|
||||
|
||||
currentList = NULL;
|
||||
|
||||
drawCompleteTicks = startingTicks + cyclesExecuted;
|
||||
|
@ -28,6 +28,7 @@ public:
|
||||
virtual bool FramebufferDirty() { return true; }
|
||||
virtual u32 Continue();
|
||||
virtual u32 Break(int mode);
|
||||
virtual void ReapplyGfxState();
|
||||
|
||||
protected:
|
||||
// To avoid virtual calls to PreExecuteOp().
|
||||
@ -37,6 +38,7 @@ protected:
|
||||
void UpdateState(GPUState state);
|
||||
void PopDLQueue();
|
||||
void CheckDrawSync();
|
||||
int GetNextListIndex();
|
||||
|
||||
typedef std::list<int> DisplayListQueue;
|
||||
|
||||
|
@ -192,6 +192,7 @@ public:
|
||||
|
||||
virtual void DeviceLost() = 0;
|
||||
virtual void Flush() = 0;
|
||||
virtual void ReapplyGfxState() = 0;
|
||||
virtual void DoState(PointerWrap &p) = 0;
|
||||
|
||||
// Called by the window system if the window size changed. This will be reflected in PSPCoreParam.pixel*.
|
||||
|
@ -82,40 +82,5 @@ void ReapplyGfxState()
|
||||
{
|
||||
if (!gpu)
|
||||
return;
|
||||
// ShaderManager_DirtyShader();
|
||||
// The commands are embedded in the command memory so we can just reexecute the words. Convenient.
|
||||
// To be safe we pass 0xFFFFFFF as the diff.
|
||||
/*
|
||||
gpu->ExecuteOp(gstate.cmdmem[GE_CMD_ALPHABLENDENABLE], 0xFFFFFFFF);
|
||||
gpu->ExecuteOp(gstate.cmdmem[GE_CMD_ALPHATESTENABLE], 0xFFFFFFFF);
|
||||
gpu->ExecuteOp(gstate.cmdmem[GE_CMD_BLENDMODE], 0xFFFFFFFF);
|
||||
gpu->ExecuteOp(gstate.cmdmem[GE_CMD_ZTEST], 0xFFFFFFFF);
|
||||
gpu->ExecuteOp(gstate.cmdmem[GE_CMD_ZTESTENABLE], 0xFFFFFFFF);
|
||||
gpu->ExecuteOp(gstate.cmdmem[GE_CMD_CULL], 0xFFFFFFFF);
|
||||
gpu->ExecuteOp(gstate.cmdmem[GE_CMD_CULLFACEENABLE], 0xFFFFFFFF);
|
||||
gpu->ExecuteOp(gstate.cmdmem[GE_CMD_SCISSOR1], 0xFFFFFFFF);
|
||||
gpu->ExecuteOp(gstate.cmdmem[GE_CMD_SCISSOR2], 0xFFFFFFFF);
|
||||
*/
|
||||
|
||||
for (int i = GE_CMD_VERTEXTYPE; i < GE_CMD_BONEMATRIXNUMBER; i++)
|
||||
{
|
||||
if(i != GE_CMD_ORIGIN)
|
||||
gpu->ExecuteOp(gstate.cmdmem[i], 0xFFFFFFFF);
|
||||
}
|
||||
|
||||
// Can't write to bonematrixnumber here
|
||||
|
||||
for (int i = GE_CMD_MORPHWEIGHT0; i < GE_CMD_PATCHFACING; i++)
|
||||
{
|
||||
gpu->ExecuteOp(gstate.cmdmem[i], 0xFFFFFFFF);
|
||||
}
|
||||
|
||||
// There are a few here in the middle that we shouldn't execute...
|
||||
|
||||
for (int i = GE_CMD_VIEWPORTX1; i < GE_CMD_TRANSFERSTART; i++)
|
||||
{
|
||||
gpu->ExecuteOp(gstate.cmdmem[i], 0xFFFFFFFF);
|
||||
}
|
||||
|
||||
// TODO: there's more...
|
||||
gpu->ReapplyGfxState();
|
||||
}
|
||||
|
@ -34,7 +34,6 @@
|
||||
#include "Core/Core.h"
|
||||
#include "Core/Host.h"
|
||||
#include "Core/System.h"
|
||||
#include "Core/MIPS/MIPS.h"
|
||||
#include "GPU/GPUState.h"
|
||||
#include "GPU/GPUInterface.h"
|
||||
#include "Core/HLE/sceCtrl.h"
|
||||
@ -477,8 +476,7 @@ void EmuScreen::render() {
|
||||
|
||||
// Run until CORE_NEXTFRAME
|
||||
while (coreState == CORE_RUNNING) {
|
||||
u64 nowTicks = CoreTiming::GetTicks();
|
||||
mipsr4k.RunLoopUntil(nowTicks + blockTicks);
|
||||
PSP_RunLoopFor(blockTicks);
|
||||
}
|
||||
// Hopefully coreState is now CORE_NEXTFRAME
|
||||
if (coreState == CORE_NEXTFRAME) {
|
||||
|
@ -99,8 +99,7 @@ void RunTests()
|
||||
while (true) {
|
||||
int blockTicks = usToCycles(1000000 / 10);
|
||||
while (coreState == CORE_RUNNING) {
|
||||
u64 nowTicks = CoreTiming::GetTicks();
|
||||
mipsr4k.RunLoopUntil(nowTicks + blockTicks);
|
||||
PSP_RunLoopFor(blockTicks);
|
||||
}
|
||||
// Hopefully coreState is now CORE_NEXTFRAME
|
||||
if (coreState == CORE_NEXTFRAME) {
|
||||
|
@ -9,7 +9,6 @@
|
||||
#include "Core/CoreTiming.h"
|
||||
#include "Core/System.h"
|
||||
#include "Core/HLE/sceUtility.h"
|
||||
#include "Core/MIPS/MIPS.h"
|
||||
#include "Core/Host.h"
|
||||
#include "Log.h"
|
||||
#include "LogManager.h"
|
||||
@ -229,10 +228,8 @@ int main(int argc, const char* argv[])
|
||||
coreState = CORE_RUNNING;
|
||||
while (coreState == CORE_RUNNING)
|
||||
{
|
||||
// Run for a frame at a time, just because.
|
||||
u64 nowTicks = CoreTiming::GetTicks();
|
||||
u64 frameTicks = usToCycles(1000000/60);
|
||||
mipsr4k.RunLoopUntil(nowTicks + frameTicks);
|
||||
int blockTicks = usToCycles(1000000 / 10);
|
||||
PSP_RunLoopFor(blockTicks);
|
||||
|
||||
// If we were rendering, this might be a nice time to do something about it.
|
||||
if (coreState == CORE_NEXTFRAME) {
|
||||
|
Loading…
Reference in New Issue
Block a user