2012-11-06 16:05:27 +00:00
|
|
|
// Copyright (c) 2012- PPSSPP Project.
|
|
|
|
|
|
|
|
// This program is free software: you can redistribute it and/or modify
|
|
|
|
// it under the terms of the GNU General Public License as published by
|
|
|
|
// the Free Software Foundation, version 2.0 or later versions.
|
|
|
|
|
|
|
|
// This program is distributed in the hope that it will be useful,
|
|
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
// GNU General Public License 2.0 for more details.
|
|
|
|
|
|
|
|
// A copy of the GPL 2.0 should have been included with the program.
|
|
|
|
// If not, see http://www.gnu.org/licenses/
|
|
|
|
|
|
|
|
// Official git repository and contact information can be found at
|
|
|
|
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
|
|
|
|
|
|
|
|
#pragma once
|
|
|
|
|
2013-08-07 20:32:04 +00:00
|
|
|
#include "Globals.h"
|
|
|
|
#include "GPU/GPUState.h"
|
2013-04-08 14:40:47 +00:00
|
|
|
#include "Core/HLE/sceKernelThread.h"
|
2013-04-05 06:19:28 +00:00
|
|
|
#include <list>
|
2013-04-29 00:49:17 +00:00
|
|
|
#include <string>
|
2012-12-28 20:58:00 +00:00
|
|
|
|
2013-02-04 04:31:46 +00:00
|
|
|
class PointerWrap;
|
|
|
|
|
2013-08-07 20:32:04 +00:00
|
|
|
enum DisplayListStatus {
|
|
|
|
// The list has been completed
|
|
|
|
PSP_GE_LIST_COMPLETED = 0,
|
|
|
|
// The list is queued but not executed yet
|
|
|
|
PSP_GE_LIST_QUEUED = 1,
|
|
|
|
// The list is currently being executed
|
|
|
|
PSP_GE_LIST_DRAWING = 2,
|
|
|
|
// The list was stopped because it encountered stall address
|
|
|
|
PSP_GE_LIST_STALLING = 3,
|
|
|
|
// The list is paused because of a signal or sceGeBreak
|
|
|
|
PSP_GE_LIST_PAUSED = 4,
|
2013-04-04 06:05:54 +00:00
|
|
|
};
|
|
|
|
|
2013-08-07 20:32:04 +00:00
|
|
|
enum DisplayListState {
|
|
|
|
// No state assigned, the list is empty
|
|
|
|
PSP_GE_DL_STATE_NONE = 0,
|
|
|
|
// The list has been queued
|
|
|
|
PSP_GE_DL_STATE_QUEUED = 1,
|
|
|
|
// The list is being executed
|
|
|
|
PSP_GE_DL_STATE_RUNNING = 2,
|
|
|
|
// The list was completed and will be removed
|
|
|
|
PSP_GE_DL_STATE_COMPLETED = 3,
|
|
|
|
// The list has been paused by a signal
|
|
|
|
PSP_GE_DL_STATE_PAUSED = 4,
|
2012-12-28 20:58:00 +00:00
|
|
|
};
|
|
|
|
|
2013-04-02 06:54:19 +00:00
|
|
|
enum SignalBehavior
|
|
|
|
{
|
|
|
|
PSP_GE_SIGNAL_NONE = 0x00,
|
|
|
|
PSP_GE_SIGNAL_HANDLER_SUSPEND = 0x01,
|
|
|
|
PSP_GE_SIGNAL_HANDLER_CONTINUE = 0x02,
|
|
|
|
PSP_GE_SIGNAL_HANDLER_PAUSE = 0x03,
|
|
|
|
PSP_GE_SIGNAL_SYNC = 0x08,
|
|
|
|
PSP_GE_SIGNAL_JUMP = 0x10,
|
|
|
|
PSP_GE_SIGNAL_CALL = 0x11,
|
|
|
|
PSP_GE_SIGNAL_RET = 0x12,
|
|
|
|
PSP_GE_SIGNAL_RJUMP = 0x13,
|
|
|
|
PSP_GE_SIGNAL_RCALL = 0x14,
|
|
|
|
PSP_GE_SIGNAL_OJUMP = 0x15,
|
|
|
|
PSP_GE_SIGNAL_OCALL = 0x16,
|
|
|
|
|
|
|
|
PSP_GE_SIGNAL_RTBP0 = 0x20,
|
|
|
|
PSP_GE_SIGNAL_RTBP1 = 0x21,
|
|
|
|
PSP_GE_SIGNAL_RTBP2 = 0x22,
|
|
|
|
PSP_GE_SIGNAL_RTBP3 = 0x23,
|
|
|
|
PSP_GE_SIGNAL_RTBP4 = 0x24,
|
|
|
|
PSP_GE_SIGNAL_RTBP5 = 0x25,
|
|
|
|
PSP_GE_SIGNAL_RTBP6 = 0x26,
|
|
|
|
PSP_GE_SIGNAL_RTBP7 = 0x27,
|
|
|
|
PSP_GE_SIGNAL_OTBP0 = 0x28,
|
|
|
|
PSP_GE_SIGNAL_OTBP1 = 0x29,
|
|
|
|
PSP_GE_SIGNAL_OTBP2 = 0x2A,
|
|
|
|
PSP_GE_SIGNAL_OTBP3 = 0x2B,
|
|
|
|
PSP_GE_SIGNAL_OTBP4 = 0x2C,
|
|
|
|
PSP_GE_SIGNAL_OTBP5 = 0x2D,
|
|
|
|
PSP_GE_SIGNAL_OTBP6 = 0x2E,
|
|
|
|
PSP_GE_SIGNAL_OTBP7 = 0x2F,
|
|
|
|
PSP_GE_SIGNAL_RCBP = 0x30,
|
|
|
|
PSP_GE_SIGNAL_OCBP = 0x38,
|
|
|
|
PSP_GE_SIGNAL_BREAK1 = 0xF0,
|
|
|
|
PSP_GE_SIGNAL_BREAK2 = 0xFF,
|
|
|
|
};
|
|
|
|
|
2013-04-04 08:07:30 +00:00
|
|
|
enum GPUState
|
|
|
|
{
|
|
|
|
GPUSTATE_RUNNING = 0,
|
|
|
|
GPUSTATE_DONE = 1,
|
|
|
|
GPUSTATE_STALL = 2,
|
|
|
|
GPUSTATE_INTERRUPT = 3,
|
|
|
|
GPUSTATE_ERROR = 4,
|
|
|
|
};
|
2013-02-17 00:06:06 +00:00
|
|
|
|
|
|
|
// Used for debug
|
|
|
|
struct FramebufferInfo
|
|
|
|
{
|
|
|
|
u32 fb_address;
|
|
|
|
u32 z_address;
|
|
|
|
int format;
|
|
|
|
u32 width;
|
|
|
|
u32 height;
|
|
|
|
void* fbo;
|
|
|
|
};
|
|
|
|
|
2013-04-16 06:02:54 +00:00
|
|
|
struct DisplayListStackEntry
|
|
|
|
{
|
|
|
|
u32 pc;
|
|
|
|
u32 offsetAddr;
|
|
|
|
};
|
|
|
|
|
2012-12-28 20:58:00 +00:00
|
|
|
struct DisplayList
|
|
|
|
{
|
|
|
|
int id;
|
2013-02-10 15:36:06 +00:00
|
|
|
u32 startpc;
|
2012-12-28 20:58:00 +00:00
|
|
|
u32 pc;
|
|
|
|
u32 stall;
|
2013-04-04 06:05:54 +00:00
|
|
|
DisplayListState state;
|
2013-04-02 06:54:19 +00:00
|
|
|
SignalBehavior signal;
|
2012-12-22 06:50:35 +00:00
|
|
|
int subIntrBase;
|
2013-02-03 23:41:16 +00:00
|
|
|
u16 subIntrToken;
|
2013-04-16 06:02:54 +00:00
|
|
|
DisplayListStackEntry stack[32];
|
2013-04-01 06:28:35 +00:00
|
|
|
int stackptr;
|
2013-04-04 07:35:38 +00:00
|
|
|
bool interrupted;
|
2013-04-07 19:45:42 +00:00
|
|
|
u64 waitTicks;
|
2013-08-07 06:59:28 +00:00
|
|
|
bool interruptsEnabled;
|
2012-12-28 20:58:00 +00:00
|
|
|
};
|
2012-11-06 16:05:27 +00:00
|
|
|
|
2013-05-06 05:52:01 +00:00
|
|
|
enum GPUInvalidationType {
|
|
|
|
// Affects all memory. Not considered highly.
|
|
|
|
GPU_INVALIDATE_ALL,
|
|
|
|
// Indicates some memory may have changed.
|
|
|
|
GPU_INVALIDATE_HINT,
|
|
|
|
// Reliable invalidation (where any hashing, etc. is unneeded, it'll always invalidate.)
|
|
|
|
GPU_INVALIDATE_SAFE,
|
|
|
|
};
|
|
|
|
|
2013-08-08 06:59:32 +00:00
|
|
|
enum GPUEventType {
|
|
|
|
GPU_EVENT_INVALID,
|
|
|
|
GPU_EVENT_PROCESS_QUEUE,
|
|
|
|
GPU_EVENT_INIT_CLEAR,
|
|
|
|
GPU_EVENT_BEGIN_FRAME,
|
|
|
|
GPU_EVENT_COPY_DISPLAY_TO_OUTPUT,
|
|
|
|
GPU_EVENT_REAPPLY_GFX_STATE,
|
|
|
|
GPU_EVENT_INVALIDATE_CACHE,
|
2013-08-09 07:45:27 +00:00
|
|
|
GPU_EVENT_FINISH_EVENT_LOOP,
|
2013-08-10 05:40:51 +00:00
|
|
|
GPU_EVENT_SYNC_THREAD,
|
2013-08-08 06:59:32 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
struct GPUEvent {
|
|
|
|
GPUEvent(GPUEventType t) : type(t) {}
|
|
|
|
GPUEventType type;
|
|
|
|
union {
|
|
|
|
// GPU_EVENT_INVALIDATE_CACHE
|
|
|
|
struct {
|
|
|
|
u32 addr;
|
|
|
|
int size;
|
|
|
|
GPUInvalidationType type;
|
|
|
|
} invalidate_cache;
|
|
|
|
};
|
2013-08-10 10:33:09 +00:00
|
|
|
|
|
|
|
operator GPUEventType() const {
|
|
|
|
return type;
|
|
|
|
}
|
2013-08-08 06:59:32 +00:00
|
|
|
};
|
|
|
|
|
2012-11-06 16:05:27 +00:00
|
|
|
class GPUInterface
|
|
|
|
{
|
|
|
|
public:
|
2012-11-19 20:23:29 +00:00
|
|
|
virtual ~GPUInterface() {}
|
|
|
|
|
2013-04-05 06:19:28 +00:00
|
|
|
static const int DisplayListMaxCount = 64;
|
|
|
|
|
2012-11-19 20:23:29 +00:00
|
|
|
// Initialization
|
2012-11-20 09:59:23 +00:00
|
|
|
virtual void InitClear() = 0;
|
2012-11-19 20:23:29 +00:00
|
|
|
|
2013-08-08 06:59:32 +00:00
|
|
|
virtual void RunEventsUntil(u64 globalticks) = 0;
|
2013-08-09 07:45:27 +00:00
|
|
|
virtual void FinishEventLoop() = 0;
|
2013-08-08 06:59:32 +00:00
|
|
|
|
2012-11-19 20:23:29 +00:00
|
|
|
// Draw queue management
|
2013-02-03 23:41:16 +00:00
|
|
|
virtual DisplayList* getList(int listid) = 0;
|
2012-11-28 12:45:22 +00:00
|
|
|
// TODO: Much of this should probably be shared between the different GPU implementations.
|
2013-04-05 06:19:28 +00:00
|
|
|
virtual u32 EnqueueList(u32 listpc, u32 stall, int subIntrBase, bool head) = 0;
|
2013-04-01 06:23:03 +00:00
|
|
|
virtual u32 DequeueList(int listid) = 0;
|
2013-04-05 06:19:28 +00:00
|
|
|
virtual u32 UpdateStall(int listid, u32 newstall) = 0;
|
2013-04-01 06:23:03 +00:00
|
|
|
virtual u32 DrawSync(int mode) = 0;
|
2013-04-05 06:19:28 +00:00
|
|
|
virtual int ListSync(int listid, int mode) = 0;
|
2013-04-01 06:23:03 +00:00
|
|
|
virtual u32 Continue() = 0;
|
|
|
|
virtual u32 Break(int mode) = 0;
|
2012-12-25 12:47:59 +00:00
|
|
|
|
2013-04-06 15:19:54 +00:00
|
|
|
virtual void InterruptStart(int listid) = 0;
|
|
|
|
virtual void InterruptEnd(int listid) = 0;
|
2013-04-07 19:45:42 +00:00
|
|
|
virtual void SyncEnd(WaitType waitType, int listid, bool wokeThreads) = 0;
|
2013-02-03 23:41:16 +00:00
|
|
|
|
2012-12-29 01:10:29 +00:00
|
|
|
virtual void PreExecuteOp(u32 op, u32 diff) = 0;
|
2012-11-06 16:05:27 +00:00
|
|
|
virtual void ExecuteOp(u32 op, u32 diff) = 0;
|
2012-12-28 20:58:00 +00:00
|
|
|
virtual bool InterpretList(DisplayList& list) = 0;
|
2012-11-18 12:04:49 +00:00
|
|
|
|
2012-11-19 20:23:29 +00:00
|
|
|
// Framebuffer management
|
2013-07-30 06:05:59 +00:00
|
|
|
virtual void SetDisplayFramebuffer(u32 framebuf, u32 stride, GEBufferFormat format) = 0;
|
2012-11-19 20:23:29 +00:00
|
|
|
virtual void BeginFrame() = 0; // Can be a good place to draw the "memory" framebuffer for accelerated plugins
|
|
|
|
virtual void CopyDisplayToOutput() = 0;
|
|
|
|
|
2012-11-26 16:35:08 +00:00
|
|
|
// Tells the GPU to update the gpuStats structure.
|
|
|
|
virtual void UpdateStats() = 0;
|
|
|
|
|
2012-12-21 22:43:48 +00:00
|
|
|
// Invalidate any cached content sourced from the specified range.
|
|
|
|
// If size = -1, invalidate everything.
|
2013-05-06 05:52:01 +00:00
|
|
|
virtual void InvalidateCache(u32 addr, int size, GPUInvalidationType type) = 0;
|
2013-06-09 08:21:50 +00:00
|
|
|
// Update either RAM from VRAM, or VRAM from RAM... or even VRAM from VRAM.
|
|
|
|
virtual void UpdateMemory(u32 dest, u32 src, int size) = 0;
|
2012-12-21 22:43:48 +00:00
|
|
|
|
2013-04-30 15:20:28 +00:00
|
|
|
// Will cause the texture cache to be cleared at the start of the next frame.
|
|
|
|
virtual void ClearCacheNextFrame() = 0;
|
|
|
|
|
2012-11-18 12:04:49 +00:00
|
|
|
// Internal hack to avoid interrupts from "PPGe" drawing (utility UI, etc)
|
|
|
|
virtual void EnableInterrupts(bool enable) = 0;
|
2012-12-21 22:54:38 +00:00
|
|
|
|
2012-12-25 14:28:34 +00:00
|
|
|
virtual void DeviceLost() = 0;
|
2013-08-04 22:15:50 +00:00
|
|
|
virtual void ReapplyGfxState() = 0;
|
2013-08-08 07:10:30 +00:00
|
|
|
virtual void SyncThread() = 0;
|
2013-08-11 20:41:42 +00:00
|
|
|
virtual u64 GetTickEstimate() = 0;
|
2012-12-29 19:41:33 +00:00
|
|
|
virtual void DoState(PointerWrap &p) = 0;
|
2012-12-26 23:18:45 +00:00
|
|
|
|
2013-01-26 23:15:39 +00:00
|
|
|
// Called by the window system if the window size changed. This will be reflected in PSPCoreParam.pixel*.
|
|
|
|
virtual void Resized() = 0;
|
2013-03-03 12:00:21 +00:00
|
|
|
virtual bool FramebufferDirty() = 0;
|
2013-08-15 23:00:26 +00:00
|
|
|
virtual bool FramebufferReallyDirty() = 0;
|
2013-01-26 23:15:39 +00:00
|
|
|
|
2012-12-26 23:18:45 +00:00
|
|
|
// Debugging
|
|
|
|
virtual void DumpNextFrame() = 0;
|
2013-04-29 07:30:54 +00:00
|
|
|
virtual void GetReportingInfo(std::string &primaryInfo, std::string &fullInfo) = 0;
|
2013-04-05 06:19:28 +00:00
|
|
|
virtual const std::list<int>& GetDisplayLists() = 0;
|
2013-02-10 15:36:06 +00:00
|
|
|
virtual DisplayList* GetCurrentDisplayList() = 0;
|
2013-02-17 00:06:06 +00:00
|
|
|
virtual bool DecodeTexture(u8* dest, GPUgstate state) = 0;
|
|
|
|
virtual std::vector<FramebufferInfo> GetFramebufferList() = 0;
|
2012-11-06 16:05:27 +00:00
|
|
|
};
|