2012-11-06 17:05:27 +01: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-12-30 10:49:05 +01:00
|
|
|
#include <list>
|
|
|
|
|
#include <string>
|
2015-07-29 11:48:20 +02:00
|
|
|
#include <vector>
|
2013-12-30 10:49:05 +01:00
|
|
|
|
2022-08-06 21:18:48 -07:00
|
|
|
#include "Common/Common.h"
|
2017-08-31 17:13:18 +02:00
|
|
|
#include "Common/Swap.h"
|
2015-07-26 22:38:40 +02:00
|
|
|
#include "GPU/GPU.h"
|
2014-03-29 16:51:38 -07:00
|
|
|
#include "Core/MemMap.h"
|
2015-07-29 11:48:20 +02:00
|
|
|
#include "GPU/ge_constants.h"
|
2015-10-14 17:45:21 +02:00
|
|
|
#include "GPU/Common/ShaderCommon.h"
|
2012-12-28 21:58:00 +01:00
|
|
|
|
2014-03-29 16:51:38 -07:00
|
|
|
struct PspGeListArgs;
|
2015-07-29 11:48:20 +02:00
|
|
|
struct GPUgstate;
|
2013-02-03 20:31:46 -08:00
|
|
|
class PointerWrap;
|
2023-12-02 13:56:18 +01:00
|
|
|
struct VirtualFramebuffer;
|
2013-02-03 20:31:46 -08:00
|
|
|
|
2013-08-07 22:32:04 +02: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-03 23:05:54 -07:00
|
|
|
};
|
|
|
|
|
|
2013-08-07 22:32:04 +02: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 21:58:00 +01:00
|
|
|
};
|
|
|
|
|
|
2015-07-26 22:38:40 +02:00
|
|
|
enum SignalBehavior {
|
2013-04-01 23:54:19 -07:00
|
|
|
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,
|
|
|
|
|
};
|
|
|
|
|
|
2015-07-26 22:38:40 +02:00
|
|
|
enum GPURunState {
|
2013-04-04 01:07:30 -07:00
|
|
|
GPUSTATE_RUNNING = 0,
|
|
|
|
|
GPUSTATE_DONE = 1,
|
|
|
|
|
GPUSTATE_STALL = 2,
|
|
|
|
|
GPUSTATE_INTERRUPT = 3,
|
|
|
|
|
GPUSTATE_ERROR = 4,
|
|
|
|
|
};
|
2013-02-17 01:06:06 +01:00
|
|
|
|
2015-07-26 22:38:40 +02:00
|
|
|
enum GPUSyncType {
|
2014-03-29 16:51:38 -07:00
|
|
|
GPU_SYNC_DRAW,
|
|
|
|
|
GPU_SYNC_LIST,
|
|
|
|
|
};
|
|
|
|
|
|
2022-10-09 13:49:41 -07:00
|
|
|
enum class WriteStencil {
|
2022-08-06 21:18:48 -07:00
|
|
|
NEEDS_CLEAR = 1,
|
|
|
|
|
STENCIL_IS_ZERO = 2,
|
|
|
|
|
IGNORE_ALPHA = 4,
|
2022-08-06 21:12:42 -07:00
|
|
|
};
|
2022-10-09 13:49:41 -07:00
|
|
|
ENUM_CLASS_BITOPS(WriteStencil);
|
2022-08-06 21:12:42 -07:00
|
|
|
|
2022-10-03 20:17:25 -07:00
|
|
|
enum class GPUCopyFlag {
|
|
|
|
|
NONE = 0,
|
2023-03-25 23:25:42 -07:00
|
|
|
FORCE_SRC_MATCH_MEM = 1,
|
|
|
|
|
FORCE_DST_MATCH_MEM = 2,
|
|
|
|
|
// Note: implies src == dst and FORCE_SRC_MATCH_MEM.
|
2022-10-03 20:17:25 -07:00
|
|
|
MEMSET = 4,
|
2022-10-09 00:50:45 -07:00
|
|
|
DEPTH_REQUESTED = 8,
|
|
|
|
|
DEBUG_NOTIFIED = 16,
|
2023-03-25 23:19:21 -07:00
|
|
|
DISALLOW_CREATE_VFB = 32,
|
2022-10-03 20:17:25 -07:00
|
|
|
};
|
|
|
|
|
ENUM_CLASS_BITOPS(GPUCopyFlag);
|
|
|
|
|
|
2015-07-26 22:38:40 +02:00
|
|
|
struct DisplayListStackEntry {
|
2013-04-15 23:02:54 -07:00
|
|
|
u32 pc;
|
|
|
|
|
u32 offsetAddr;
|
2013-09-21 00:07:49 -07:00
|
|
|
u32 baseAddr;
|
2013-04-15 23:02:54 -07:00
|
|
|
};
|
|
|
|
|
|
2015-07-26 22:38:40 +02:00
|
|
|
struct DisplayList {
|
2012-12-28 21:58:00 +01:00
|
|
|
int id;
|
2013-02-10 16:36:06 +01:00
|
|
|
u32 startpc;
|
2012-12-28 21:58:00 +01:00
|
|
|
u32 pc;
|
|
|
|
|
u32 stall;
|
2013-04-03 23:05:54 -07:00
|
|
|
DisplayListState state;
|
2013-04-01 23:54:19 -07:00
|
|
|
SignalBehavior signal;
|
2012-12-21 22:50:35 -08:00
|
|
|
int subIntrBase;
|
2013-02-04 00:41:16 +01:00
|
|
|
u16 subIntrToken;
|
2013-04-15 23:02:54 -07:00
|
|
|
DisplayListStackEntry stack[32];
|
2013-03-31 23:28:35 -07:00
|
|
|
int stackptr;
|
2013-04-04 00:35:38 -07:00
|
|
|
bool interrupted;
|
2013-04-07 12:45:42 -07:00
|
|
|
u64 waitTicks;
|
2013-08-06 23:59:28 -07:00
|
|
|
bool interruptsEnabled;
|
2013-09-01 10:16:29 -07:00
|
|
|
bool pendingInterrupt;
|
2013-09-20 09:42:09 -07:00
|
|
|
bool started;
|
2013-10-06 22:07:57 -07:00
|
|
|
PSPPointer<u32_le> context;
|
2013-09-21 20:47:35 -07:00
|
|
|
u32 offsetAddr;
|
2013-09-24 12:59:34 +02:00
|
|
|
bool bboxResult;
|
2014-08-17 16:52:06 +08:00
|
|
|
u32 stackAddr;
|
2015-10-11 14:38:26 +02:00
|
|
|
|
|
|
|
|
u32 padding; // Android x86-32 does not round the structure size up to the closest multiple of 8 like the other platforms.
|
2012-12-28 21:58:00 +01:00
|
|
|
};
|
2012-11-06 17:05:27 +01:00
|
|
|
|
2013-05-05 22:52:01 -07: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,
|
2021-02-07 09:02:28 -08:00
|
|
|
// Forced invalidation for when the texture hash may not catch changes.
|
|
|
|
|
GPU_INVALIDATE_FORCE,
|
2013-05-05 22:52:01 -07:00
|
|
|
};
|
|
|
|
|
|
2017-02-06 11:55:54 +01:00
|
|
|
namespace Draw {
|
|
|
|
|
class DrawContext;
|
|
|
|
|
}
|
|
|
|
|
|
2013-10-22 14:34:16 +02:00
|
|
|
class GPUInterface {
|
2012-11-06 17:05:27 +01:00
|
|
|
public:
|
2012-11-19 21:23:29 +01:00
|
|
|
virtual ~GPUInterface() {}
|
|
|
|
|
|
2013-04-04 23:19:28 -07:00
|
|
|
static const int DisplayListMaxCount = 64;
|
|
|
|
|
|
2017-02-06 11:55:54 +01:00
|
|
|
virtual Draw::DrawContext *GetDrawContext() = 0;
|
|
|
|
|
|
2012-11-19 21:23:29 +01:00
|
|
|
// Initialization
|
2023-01-01 06:59:14 -08:00
|
|
|
virtual bool IsStarted() = 0;
|
2013-11-28 15:34:41 -08:00
|
|
|
virtual void Reinitialize() = 0;
|
2012-11-19 21:23:29 +01:00
|
|
|
|
2016-01-06 23:53:21 +01:00
|
|
|
// Frame managment
|
|
|
|
|
virtual void BeginHostFrame() = 0;
|
|
|
|
|
virtual void EndHostFrame() = 0;
|
2022-11-21 17:59:56 +01:00
|
|
|
|
|
|
|
|
virtual void CheckDisplayResized() = 0;
|
2022-11-22 23:29:50 +01:00
|
|
|
virtual void CheckConfigChanged() = 0;
|
2016-01-06 23:53:21 +01:00
|
|
|
|
2012-11-19 21:23:29 +01:00
|
|
|
// Draw queue management
|
2013-02-04 00:41:16 +01:00
|
|
|
virtual DisplayList* getList(int listid) = 0;
|
2012-11-28 13:45:22 +01:00
|
|
|
// TODO: Much of this should probably be shared between the different GPU implementations.
|
2013-09-20 09:42:09 -07:00
|
|
|
virtual u32 EnqueueList(u32 listpc, u32 stall, int subIntrBase, PSPPointer<PspGeListArgs> args, bool head) = 0;
|
2013-03-31 23:23:03 -07:00
|
|
|
virtual u32 DequeueList(int listid) = 0;
|
2013-04-04 23:19:28 -07:00
|
|
|
virtual u32 UpdateStall(int listid, u32 newstall) = 0;
|
2013-03-31 23:23:03 -07:00
|
|
|
virtual u32 DrawSync(int mode) = 0;
|
2013-04-04 23:19:28 -07:00
|
|
|
virtual int ListSync(int listid, int mode) = 0;
|
2013-03-31 23:23:03 -07:00
|
|
|
virtual u32 Continue() = 0;
|
|
|
|
|
virtual u32 Break(int mode) = 0;
|
2013-09-21 10:03:49 -07:00
|
|
|
virtual int GetStack(int index, u32 stackPtr) = 0;
|
2022-09-27 22:29:55 -07:00
|
|
|
virtual bool GetMatrix24(GEMatrixType type, u32_le *result, u32 cmdbits) = 0;
|
|
|
|
|
virtual void ResetMatrices() = 0;
|
2022-10-01 23:18:42 -07:00
|
|
|
virtual uint32_t SetAddrTranslation(uint32_t value) = 0;
|
2012-12-25 13:47:59 +01:00
|
|
|
|
2013-04-06 08:19:54 -07:00
|
|
|
virtual void InterruptStart(int listid) = 0;
|
|
|
|
|
virtual void InterruptEnd(int listid) = 0;
|
2014-03-29 16:51:38 -07:00
|
|
|
virtual void SyncEnd(GPUSyncType waitType, int listid, bool wokeThreads) = 0;
|
2013-02-04 00:41:16 +01:00
|
|
|
|
2012-11-06 17:05:27 +01:00
|
|
|
virtual void ExecuteOp(u32 op, u32 diff) = 0;
|
2012-11-18 13:04:49 +01:00
|
|
|
|
2012-11-19 21:23:29 +01:00
|
|
|
// Framebuffer management
|
2013-07-29 23:05:59 -07:00
|
|
|
virtual void SetDisplayFramebuffer(u32 framebuf, u32 stride, GEBufferFormat format) = 0;
|
2023-12-11 23:05:37 +01:00
|
|
|
virtual void PSPFrame() = 0;
|
2020-03-01 13:55:28 -08:00
|
|
|
virtual void CopyDisplayToOutput(bool reallyDirty) = 0;
|
2012-11-19 21:23:29 +01:00
|
|
|
|
2012-11-26 17:35:08 +01:00
|
|
|
// Tells the GPU to update the gpuStats structure.
|
2016-03-31 10:17:02 +02:00
|
|
|
virtual void GetStats(char *buffer, size_t bufsize) = 0;
|
2012-11-26 17:35:08 +01:00
|
|
|
|
2012-12-21 23:43:48 +01:00
|
|
|
// Invalidate any cached content sourced from the specified range.
|
|
|
|
|
// If size = -1, invalidate everything.
|
2013-05-05 22:52:01 -07:00
|
|
|
virtual void InvalidateCache(u32 addr, int size, GPUInvalidationType type) = 0;
|
2022-10-09 13:49:41 -07:00
|
|
|
// Clear caches, update hardware framebuffers, or similar based on written pixels of known format (typically video.)
|
|
|
|
|
virtual void PerformWriteFormattedFromMemory(u32 addr, int size, int width, GEBufferFormat format) = 0;
|
2013-06-09 01:21:50 -07:00
|
|
|
// Update either RAM from VRAM, or VRAM from RAM... or even VRAM from VRAM.
|
2022-10-03 20:17:25 -07:00
|
|
|
virtual bool PerformMemoryCopy(u32 dest, u32 src, int size, GPUCopyFlag flags = GPUCopyFlag::NONE) = 0;
|
2014-05-27 01:14:29 -07:00
|
|
|
virtual bool PerformMemorySet(u32 dest, u8 v, int size) = 0;
|
2022-10-09 13:49:41 -07:00
|
|
|
// Update PSP memory with render results.
|
|
|
|
|
virtual bool PerformReadbackToMemory(u32 dest, int size) = 0;
|
|
|
|
|
// Update rendering data (i.e. hardware framebuffers) with data in PSP memory. Format unspecified.
|
|
|
|
|
virtual bool PerformWriteColorFromMemory(u32 dest, int size) = 0;
|
|
|
|
|
virtual bool PerformWriteStencilFromMemory(u32 dest, int size, WriteStencil flags = WriteStencil::NEEDS_CLEAR) = 0;
|
2012-12-21 23:43:48 +01:00
|
|
|
|
2022-12-02 14:32:27 +01:00
|
|
|
// Will cause the texture cache to be cleared at the start of the next frame.
|
|
|
|
|
virtual void ClearCacheNextFrame() = 0;
|
|
|
|
|
|
2012-11-18 13:04:49 +01:00
|
|
|
// Internal hack to avoid interrupts from "PPGe" drawing (utility UI, etc)
|
|
|
|
|
virtual void EnableInterrupts(bool enable) = 0;
|
2012-12-21 23:54:38 +01:00
|
|
|
|
2012-12-25 15:28:34 +01:00
|
|
|
virtual void DeviceLost() = 0;
|
2023-02-25 23:04:27 +01:00
|
|
|
virtual void DeviceRestore(Draw::DrawContext *draw) = 0;
|
2013-08-04 15:15:50 -07:00
|
|
|
virtual void ReapplyGfxState() = 0;
|
2012-12-29 11:41:33 -08:00
|
|
|
virtual void DoState(PointerWrap &p) = 0;
|
2012-12-27 00:18:45 +01:00
|
|
|
|
2013-01-27 00:15:39 +01:00
|
|
|
// Called by the window system if the window size changed. This will be reflected in PSPCoreParam.pixel*.
|
2022-11-21 15:14:20 +01:00
|
|
|
virtual void NotifyDisplayResized() = 0;
|
|
|
|
|
virtual void NotifyRenderResized() = 0;
|
|
|
|
|
virtual void NotifyConfigChanged() = 0;
|
|
|
|
|
|
2013-03-03 13:00:21 +01:00
|
|
|
virtual bool FramebufferDirty() = 0;
|
2013-08-16 01:00:26 +02:00
|
|
|
virtual bool FramebufferReallyDirty() = 0;
|
2013-09-21 19:31:54 -07:00
|
|
|
virtual bool BusyDrawing() = 0;
|
2023-12-11 13:06:15 +01:00
|
|
|
virtual bool PresentedThisFrame() const = 0;
|
2013-01-27 00:15:39 +01:00
|
|
|
|
2013-11-30 18:39:16 -08:00
|
|
|
// If any jit is being used inside the GPU.
|
|
|
|
|
virtual bool DescribeCodePtr(const u8 *ptr, std::string &name) = 0;
|
|
|
|
|
|
2012-12-27 00:18:45 +01:00
|
|
|
// Debugging
|
|
|
|
|
virtual void DumpNextFrame() = 0;
|
2013-04-29 00:30:54 -07:00
|
|
|
virtual void GetReportingInfo(std::string &primaryInfo, std::string &fullInfo) = 0;
|
2013-04-04 23:19:28 -07:00
|
|
|
virtual const std::list<int>& GetDisplayLists() = 0;
|
2018-06-03 11:09:18 -07:00
|
|
|
// TODO: Currently Qt only, needs to be cleaned up.
|
2023-12-02 13:56:18 +01:00
|
|
|
virtual std::vector<const VirtualFramebuffer *> GetFramebufferList() const = 0;
|
2022-08-16 10:55:44 +02:00
|
|
|
virtual s64 GetListTicks(int listid) const = 0;
|
2015-10-14 17:45:21 +02:00
|
|
|
|
|
|
|
|
// For debugging. The IDs returned are opaque, do not poke in them or display them in any way.
|
|
|
|
|
virtual std::vector<std::string> DebugGetShaderIDs(DebugShaderType type) = 0;
|
|
|
|
|
virtual std::string DebugGetShaderString(std::string id, DebugShaderType type, DebugShaderStringType stringType) = 0;
|
2012-11-06 17:05:27 +01:00
|
|
|
};
|