CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!
CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!
Path: blob/master/GPU/GPUCommon.h
Views: 1401
#pragma once12#include "ppsspp_config.h"3#include "Common/Common.h"4#include "Common/MemoryUtil.h"5#include "GPU/GPUInterface.h"6#include "GPU/GPUState.h"7#include "GPU/Common/GPUDebugInterface.h"89#if defined(__ANDROID__)10#include <atomic>11#endif1213class FramebufferManagerCommon;14class TextureCacheCommon;15class DrawEngineCommon;16class GraphicsContext;17struct VirtualFramebuffer;1819namespace Draw {20class DrawContext;21}2223enum DrawType {24DRAW_UNKNOWN,25DRAW_PRIM,26DRAW_SPLINE,27DRAW_BEZIER,28};2930enum {31FLAG_FLUSHBEFOREONCHANGE = 2,32FLAG_EXECUTE = 4,33FLAG_EXECUTEONCHANGE = 8,34FLAG_READS_PC = 16,35FLAG_WRITES_PC = 32,36FLAG_DIRTYONCHANGE = 64, // NOTE: Either this or FLAG_EXECUTE*, not both!37};3839struct TransformedVertex {40union {41struct {42float x, y, z, pos_w; // in case of morph, preblend during decode43};44float pos[4];45};46union {47struct {48float u; float v; float uv_w; // scaled by uscale, vscale, if there49};50float uv[3];51};52float fog;53union {54u8 color0[4]; // prelit55u32 color0_32;56};57union {58u8 color1[4]; // prelit59u32 color1_32;60};6162void CopyFromWithOffset(const TransformedVertex &other, float xoff, float yoff) {63this->x = other.x + xoff;64this->y = other.y + yoff;65memcpy(&this->z, &other.z, sizeof(*this) - sizeof(float) * 2);66}67};6869inline bool IsTrianglePrim(GEPrimitiveType prim) {70// TODO: KEEP_PREVIOUS is mistakenly treated as TRIANGLE here... This isn't new.71//72// Interesting optimization, but not confident in performance:73// static const bool p[8] = { false, false, false, true, true, true, false, true };74// 10111000 = 0xB8;75// return (0xB8U >> (u8)prim) & 1;7677return prim > GE_PRIM_LINE_STRIP && prim != GE_PRIM_RECTANGLES;78}798081class GPUCommon : public GPUInterface, public GPUDebugInterface {82public:83GPUCommon(GraphicsContext *gfxCtx, Draw::DrawContext *draw);8485Draw::DrawContext *GetDrawContext() override {86return draw_;87}88virtual u32 CheckGPUFeatures() const = 0;8990virtual void UpdateCmdInfo() = 0;9192bool IsStarted() override {93return true;94}95void Reinitialize() override;9697void BeginHostFrame() override;98void EndHostFrame() override;99100void InterruptStart(int listid) override;101void InterruptEnd(int listid) override;102void SyncEnd(GPUSyncType waitType, int listid, bool wokeThreads) override;103void EnableInterrupts(bool enable) override {104interruptsEnabled_ = enable;105}106107void NotifyDisplayResized() override;108void NotifyRenderResized() override;109void NotifyConfigChanged() override;110111void DumpNextFrame() override;112113virtual void PreExecuteOp(u32 op, u32 diff) {}114115bool InterpretList(DisplayList &list);116void ProcessDLQueue();117u32 UpdateStall(int listid, u32 newstall) override;118u32 EnqueueList(u32 listpc, u32 stall, int subIntrBase, PSPPointer<PspGeListArgs> args, bool head) override;119u32 DequeueList(int listid) override;120int ListSync(int listid, int mode) override;121u32 DrawSync(int mode) override;122int GetStack(int index, u32 stackPtr) override;123bool GetMatrix24(GEMatrixType type, u32_le *result, u32 cmdbits) override;124void ResetMatrices() override;125void DoState(PointerWrap &p) override;126bool BusyDrawing() override;127u32 Continue() override;128u32 Break(int mode) override;129void ReapplyGfxState() override;130uint32_t SetAddrTranslation(uint32_t value) override;131uint32_t GetAddrTranslation() override;132133void CopyDisplayToOutput(bool reallyDirty) override = 0;134bool PerformMemoryCopy(u32 dest, u32 src, int size, GPUCopyFlag flags = GPUCopyFlag::NONE) override;135bool PerformMemorySet(u32 dest, u8 v, int size) override;136bool PerformReadbackToMemory(u32 dest, int size) override;137bool PerformWriteColorFromMemory(u32 dest, int size) override;138139void PerformWriteFormattedFromMemory(u32 addr, int size, int width, GEBufferFormat format) override;140bool PerformWriteStencilFromMemory(u32 dest, int size, WriteStencil flags) override;141142void Execute_OffsetAddr(u32 op, u32 diff);143void Execute_Vaddr(u32 op, u32 diff);144void Execute_Iaddr(u32 op, u32 diff);145void Execute_Origin(u32 op, u32 diff);146void Execute_Jump(u32 op, u32 diff);147void Execute_BJump(u32 op, u32 diff);148void Execute_Call(u32 op, u32 diff);149void Execute_Ret(u32 op, u32 diff);150void Execute_End(u32 op, u32 diff);151152void Execute_BoundingBox(u32 op, u32 diff);153154void Execute_MorphWeight(u32 op, u32 diff);155156void Execute_ImmVertexAlphaPrim(u32 op, u32 diff);157158void Execute_Unknown(u32 op, u32 diff);159160static int EstimatePerVertexCost();161162// Note: Not virtual!163void Flush();164void DispatchFlush() override;165166#ifdef USE_CRT_DBG167#undef new168#endif169void *operator new(size_t s) {170return AllocateAlignedMemory(s, 16);171}172void operator delete(void *p) {173FreeAlignedMemory(p);174}175#ifdef USE_CRT_DBG176#define new DBG_NEW177#endif178179// From GPUDebugInterface.180bool GetCurrentDisplayList(DisplayList &list) override;181bool GetCurrentSimpleVertices(int count, std::vector<GPUDebugVertex> &vertices, std::vector<u16> &indices) override;182183std::vector<std::string> DebugGetShaderIDs(DebugShaderType shader) override { return std::vector<std::string>(); };184std::string DebugGetShaderString(std::string id, DebugShaderType shader, DebugShaderStringType stringType) override {185return "N/A";186}187bool DescribeCodePtr(const u8 *ptr, std::string &name) override;188189std::vector<DisplayList> ActiveDisplayLists() override;190void ResetListPC(int listID, u32 pc) override;191void ResetListStall(int listID, u32 stall) override;192void ResetListState(int listID, DisplayListState state) override;193194GPUDebugOp DissassembleOp(u32 pc, u32 op) override;195std::vector<GPUDebugOp> DissassembleOpRange(u32 startpc, u32 endpc) override;196197void NotifySteppingEnter() override;198void NotifySteppingExit() override;199200u32 GetRelativeAddress(u32 data) override;201u32 GetVertexAddress() override;202u32 GetIndexAddress() override;203GPUgstate GetGState() override;204void SetCmdValue(u32 op) override;205206DisplayList* getList(int listid) override {207return &dls[listid];208}209210const std::list<int>& GetDisplayLists() override {211return dlQueue;212}213214s64 GetListTicks(int listid) const override {215if (listid >= 0 && listid < DisplayListMaxCount) {216return dls[listid].waitTicks;217}218return -1;219}220221void GetReportingInfo(std::string &primaryInfo, std::string &fullInfo) override {222primaryInfo = reportingPrimaryInfo_;223fullInfo = reportingFullInfo_;224}225226bool PresentedThisFrame() const override;227228protected:229void ClearCacheNextFrame() override {}230231virtual void CheckRenderResized() {}232233void SetDrawType(DrawType type, GEPrimitiveType prim) {234if (type != lastDraw_) {235// We always flush when drawing splines/beziers so no need to do so here236gstate_c.Dirty(DIRTY_UVSCALEOFFSET | DIRTY_VERTEXSHADER_STATE | DIRTY_GEOMETRYSHADER_STATE);237lastDraw_ = type;238}239// Prim == RECTANGLES can cause CanUseHardwareTransform to flip, so we need to dirty.240// Also, culling may be affected so dirty the raster state.241if (IsTrianglePrim(prim) != IsTrianglePrim(lastPrim_)) {242Flush();243gstate_c.Dirty(DIRTY_RASTER_STATE | DIRTY_VERTEXSHADER_STATE | DIRTY_GEOMETRYSHADER_STATE);244lastPrim_ = prim;245}246}247248void PSPFrame() override;249250virtual void CheckDepthUsage(VirtualFramebuffer *vfb) {}251virtual void FastRunLoop(DisplayList &list) = 0;252253void SlowRunLoop(DisplayList &list);254void UpdatePC(u32 currentPC, u32 newPC);255void UpdateState(GPURunState state);256void FastLoadBoneMatrix(u32 target);257void FlushImm();258void DoBlockTransfer(u32 skipDrawReason);259260// TODO: Unify this. Vulkan and OpenGL are different due to how they buffer data.261virtual void FinishDeferred() {}262263void AdvanceVerts(u32 vertType, int count, int bytesRead) {264if ((vertType & GE_VTYPE_IDX_MASK) != GE_VTYPE_IDX_NONE) {265int indexShift = ((vertType & GE_VTYPE_IDX_MASK) >> GE_VTYPE_IDX_SHIFT) - 1;266gstate_c.indexAddr += count << indexShift;267} else {268gstate_c.vertexAddr += bytesRead;269}270}271272virtual void BuildReportingInfo() = 0;273274virtual void UpdateMSAALevel(Draw::DrawContext *draw) {}275276DrawEngineCommon *drawEngineCommon_ = nullptr;277278// TODO: These should live in GPUCommonHW.279FramebufferManagerCommon *framebufferManager_ = nullptr;280TextureCacheCommon *textureCache_ = nullptr;281282bool flushOnParams_ = true;283284GraphicsContext *gfxCtx_;285Draw::DrawContext *draw_;286287typedef std::list<int> DisplayListQueue;288289int nextListID;290DisplayList dls[DisplayListMaxCount];291DisplayList *currentList;292DisplayListQueue dlQueue;293294bool interruptRunning = false;295GPURunState gpuState = GPUSTATE_RUNNING;296bool isbreak;297u64 drawCompleteTicks;298u64 busyTicks;299300int downcount;301u64 startingTicks;302u32 cycleLastPC;303int cyclesExecuted;304305bool dumpNextFrame_ = false;306bool dumpThisFrame_ = false;307bool debugRecording_;308bool interruptsEnabled_;309bool displayResized_ = false;310bool renderResized_ = false;311bool configChanged_ = false;312DrawType lastDraw_ = DRAW_UNKNOWN;313GEPrimitiveType lastPrim_ = GE_PRIM_INVALID;314315int vertexCost_ = 0;316317// No idea how big this buffer needs to be.318enum {319MAX_IMMBUFFER_SIZE = 32,320};321322TransformedVertex immBuffer_[MAX_IMMBUFFER_SIZE];323int immCount_ = 0;324GEPrimitiveType immPrim_ = GE_PRIM_INVALID;325uint32_t immFlags_ = 0;326bool immFirstSent_ = false;327328uint32_t edramTranslation_ = 0x400;329330// When matrix data overflows, the CPU visible values wrap and bleed between matrices.331// But this doesn't actually change the values used by rendering.332// The CPU visible values affect the GPU when list contexts are restored.333// Note: not maintained by all backends, here for save stating.334union {335struct {336u32 bone[12 * 8];337u32 world[12];338u32 view[12];339u32 proj[16];340u32 tgen[12];341};342u32 all[12 * 8 + 12 + 12 + 16 + 12];343} matrixVisible;344345std::string reportingPrimaryInfo_;346std::string reportingFullInfo_;347348private:349void DoExecuteCall(u32 target);350void PopDLQueue();351void CheckDrawSync();352int GetNextListIndex();353354// Debug stats.355double timeSteppingStarted_;356double timeSpentStepping_;357};358359360