ppsspp/GPU/GPUInterface.h
Unknown W. Brackets 6d104edb5d Make sure not to leak any enabled vertex arrays.
When returning to EmuScreen, we need to reset any enabled vertex arrays or
we could crash in EmuScreen.  Also, when starting a frame / dirting the
shader, make sure also to toggle the vertex arrays.
2014-06-22 21:42:29 -07:00

287 lines
8.0 KiB
C++

// 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
#include <list>
#include <string>
#include "GPU/GPUState.h"
#include "Core/MemMap.h"
struct PspGeListArgs;
class PointerWrap;
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,
};
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,
};
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,
};
enum GPUState
{
GPUSTATE_RUNNING = 0,
GPUSTATE_DONE = 1,
GPUSTATE_STALL = 2,
GPUSTATE_INTERRUPT = 3,
GPUSTATE_ERROR = 4,
};
enum GPUSyncType
{
GPU_SYNC_DRAW,
GPU_SYNC_LIST,
};
// Used for debug
struct FramebufferInfo
{
u32 fb_address;
u32 z_address;
int format;
u32 width;
u32 height;
void* fbo;
};
struct DisplayListStackEntry
{
u32 pc;
u32 offsetAddr;
u32 baseAddr;
};
struct DisplayList
{
int id;
u32 startpc;
u32 pc;
u32 stall;
DisplayListState state;
SignalBehavior signal;
int subIntrBase;
u16 subIntrToken;
DisplayListStackEntry stack[32];
int stackptr;
bool interrupted;
u64 waitTicks;
bool interruptsEnabled;
bool pendingInterrupt;
bool started;
PSPPointer<u32_le> context;
u32 offsetAddr;
bool bboxResult;
};
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,
};
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,
GPU_EVENT_FINISH_EVENT_LOOP,
GPU_EVENT_SYNC_THREAD,
GPU_EVENT_FB_MEMCPY,
GPU_EVENT_FB_MEMSET,
GPU_EVENT_FB_STENCIL_UPLOAD,
};
struct GPUEvent {
GPUEvent(GPUEventType t) : type(t) {}
GPUEventType type;
union {
// GPU_EVENT_INVALIDATE_CACHE
struct {
u32 addr;
int size;
GPUInvalidationType type;
} invalidate_cache;
// GPU_EVENT_FB_MEMCPY
struct {
u32 dst;
u32 src;
int size;
} fb_memcpy;
// GPU_EVENT_FB_MEMSET
struct {
u32 dst;
u8 v;
int size;
} fb_memset;
// GPU_EVENT_FB_STENCIL_UPLOAD
struct {
u32 dst;
int size;
} fb_stencil_upload;
};
operator GPUEventType() const {
return type;
}
};
class GPUInterface {
public:
virtual ~GPUInterface() {}
static const int DisplayListMaxCount = 64;
// Initialization
virtual void InitClear() = 0;
virtual void Reinitialize() = 0;
virtual void RunEventsUntil(u64 globalticks) = 0;
virtual void FinishEventLoop() = 0;
// Draw queue management
virtual DisplayList* getList(int listid) = 0;
// TODO: Much of this should probably be shared between the different GPU implementations.
virtual u32 EnqueueList(u32 listpc, u32 stall, int subIntrBase, PSPPointer<PspGeListArgs> args, bool head) = 0;
virtual u32 DequeueList(int listid) = 0;
virtual u32 UpdateStall(int listid, u32 newstall) = 0;
virtual u32 DrawSync(int mode) = 0;
virtual int ListSync(int listid, int mode) = 0;
virtual u32 Continue() = 0;
virtual u32 Break(int mode) = 0;
virtual int GetStack(int index, u32 stackPtr) = 0;
virtual void InterruptStart(int listid) = 0;
virtual void InterruptEnd(int listid) = 0;
virtual void SyncEnd(GPUSyncType waitType, int listid, bool wokeThreads) = 0;
virtual void PreExecuteOp(u32 op, u32 diff) = 0;
virtual void ExecuteOp(u32 op, u32 diff) = 0;
virtual bool InterpretList(DisplayList& list) = 0;
// Framebuffer management
virtual void SetDisplayFramebuffer(u32 framebuf, u32 stride, GEBufferFormat format) = 0;
virtual void BeginFrame() = 0; // Can be a good place to draw the "memory" framebuffer for accelerated plugins
virtual void CopyDisplayToOutput() = 0;
// Tells the GPU to update the gpuStats structure.
virtual void UpdateStats() = 0;
// Invalidate any cached content sourced from the specified range.
// If size = -1, invalidate everything.
virtual void InvalidateCache(u32 addr, int size, GPUInvalidationType type) = 0;
// Update either RAM from VRAM, or VRAM from RAM... or even VRAM from VRAM.
virtual bool PerformMemoryCopy(u32 dest, u32 src, int size) = 0;
virtual bool PerformMemorySet(u32 dest, u8 v, int size) = 0;
virtual bool PerformMemoryDownload(u32 dest, int size) = 0;
virtual bool PerformMemoryUpload(u32 dest, int size) = 0;
virtual bool PerformStencilUpload(u32 dest, int size) = 0;
// Will cause the texture cache to be cleared at the start of the next frame.
virtual void ClearCacheNextFrame() = 0;
// Internal hack to avoid interrupts from "PPGe" drawing (utility UI, etc)
virtual void EnableInterrupts(bool enable) = 0;
virtual void DeviceLost() = 0;
virtual void ReapplyGfxState() = 0;
virtual void SyncThread(bool force = false) = 0;
virtual void SyncBeginFrame() = 0;
virtual u64 GetTickEstimate() = 0;
virtual void DoState(PointerWrap &p) = 0;
// Called by the window system if the window size changed. This will be reflected in PSPCoreParam.pixel*.
virtual void Resized() = 0;
virtual void ClearShaderCache() = 0;
virtual void CleanupBeforeUI() = 0;
virtual bool FramebufferDirty() = 0;
virtual bool FramebufferReallyDirty() = 0;
virtual bool BusyDrawing() = 0;
// If any jit is being used inside the GPU.
virtual bool DescribeCodePtr(const u8 *ptr, std::string &name) = 0;
// Debugging
virtual void DumpNextFrame() = 0;
virtual void GetReportingInfo(std::string &primaryInfo, std::string &fullInfo) = 0;
virtual const std::list<int>& GetDisplayLists() = 0;
virtual bool DecodeTexture(u8* dest, GPUgstate state) = 0;
virtual std::vector<FramebufferInfo> GetFramebufferList() = 0;
};