Files
ppsspp/GPU/Common/GPUDebugInterface.h
T
Unknown W. Brackets 48c39543af GE Debugger: Normalize framebuffer texture preview.
Previously, we would show the render-to-texture with its original
dimensions.  While useful, this skewed the preview coordinates and was
sometimes confusing.  Additionally, depth texturing didn't preview.

This pads and subsets the texture preview so it's the right size.
2022-10-10 21:54:24 -07:00

264 lines
7.1 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 <vector>
#include <string>
#include "Common/Math/expression_parser.h"
#include "Core/MemMap.h"
#include "GPU/GPU.h"
#include "GPU/GPUInterface.h"
struct GPUDebugOp {
u32 pc;
u8 cmd;
u32 op;
std::string desc;
};
enum GPUDebugBufferFormat {
// These match GEBufferFormat.
GPU_DBG_FORMAT_565 = 0,
GPU_DBG_FORMAT_5551 = 1,
GPU_DBG_FORMAT_4444 = 2,
GPU_DBG_FORMAT_8888 = 3,
GPU_DBG_FORMAT_INVALID = 0xFF,
// These are reversed versions.
GPU_DBG_FORMAT_REVERSE_FLAG = 4,
GPU_DBG_FORMAT_565_REV = 4,
GPU_DBG_FORMAT_5551_REV = 5,
GPU_DBG_FORMAT_4444_REV = 6,
// 565 is just reversed, the others have B and R swapped.
GPU_DBG_FORMAT_565_BGRA = 0x04,
GPU_DBG_FORMAT_BRSWAP_FLAG = 0x08,
GPU_DBG_FORMAT_5551_BGRA = 0x09,
GPU_DBG_FORMAT_4444_BGRA = 0x0A,
GPU_DBG_FORMAT_8888_BGRA = 0x0B,
// These don't, they're for depth/stencil buffers.
GPU_DBG_FORMAT_FLOAT = 0x10,
GPU_DBG_FORMAT_16BIT = 0x11,
GPU_DBG_FORMAT_8BIT = 0x12,
GPU_DBG_FORMAT_24BIT_8X = 0x13,
GPU_DBG_FORMAT_24X_8BIT = 0x14,
GPU_DBG_FORMAT_FLOAT_DIV_256 = 0x18,
GPU_DBG_FORMAT_24BIT_8X_DIV_256 = 0x1B,
// This is used for screenshots, mainly.
GPU_DBG_FORMAT_888_RGB = 0x20,
};
enum GPUDebugFramebufferType {
// The current render target.
GPU_DBG_FRAMEBUF_RENDER,
// The current display target (not the displayed screen, though.)
GPU_DBG_FRAMEBUF_DISPLAY,
};
inline GPUDebugBufferFormat &operator |=(GPUDebugBufferFormat &lhs, const GPUDebugBufferFormat &rhs) {
lhs = GPUDebugBufferFormat((int)lhs | (int)rhs);
return lhs;
}
struct GPUDebugBuffer {
GPUDebugBuffer() {
}
GPUDebugBuffer(void *data, u32 stride, u32 height, GEBufferFormat fmt, bool reversed = false)
: alloc_(false), data_((u8 *)data), stride_(stride), height_(height), fmt_(GPUDebugBufferFormat(fmt)), flipped_(false) {
if (reversed && fmt_ < GPU_DBG_FORMAT_8888) {
fmt_ |= GPU_DBG_FORMAT_REVERSE_FLAG;
}
}
GPUDebugBuffer(void *data, u32 stride, u32 height, GETextureFormat fmt, bool reversed = false)
: alloc_(false), data_((u8 *)data), stride_(stride), height_(height), fmt_(GPUDebugBufferFormat(fmt)), flipped_(false) {
if (reversed && fmt_ < GPU_DBG_FORMAT_8888) {
fmt_ |= GPU_DBG_FORMAT_REVERSE_FLAG;
}
}
GPUDebugBuffer(void *data, u32 stride, u32 height, GPUDebugBufferFormat fmt)
: alloc_(false), data_((u8 *)data), stride_(stride), height_(height), fmt_(fmt), flipped_(false) {
}
GPUDebugBuffer(GPUDebugBuffer &&other) noexcept {
alloc_ = other.alloc_;
data_ = other.data_;
height_ = other.height_;
stride_ = other.stride_;
flipped_ = other.flipped_;
fmt_ = other.fmt_;
other.alloc_ = false;
other.data_ = nullptr;
}
~GPUDebugBuffer() {
Free();
}
GPUDebugBuffer &operator = (GPUDebugBuffer &&other) noexcept {
if (this != &other) {
Free();
alloc_ = other.alloc_;
data_ = other.data_;
height_ = other.height_;
stride_ = other.stride_;
flipped_ = other.flipped_;
fmt_ = other.fmt_;
other.alloc_ = false;
other.data_ = nullptr;
}
return *this;
}
void Allocate(u32 stride, u32 height, GEBufferFormat fmt, bool flipped = false, bool reversed = false);
void Allocate(u32 stride, u32 height, GPUDebugBufferFormat fmt, bool flipped = false);
void Free();
void ZeroBytes();
u8 *GetData() {
return data_;
}
u32 GetRawPixel(int x, int y) const;
void SetRawPixel(int x, int y, u32 c);
const u8 *GetData() const {
return data_;
}
u32 GetHeight() const {
return height_;
}
u32 GetStride() const {
return stride_;
}
bool GetFlipped() const {
return flipped_;
}
GPUDebugBufferFormat GetFormat() const {
return fmt_;
}
u32 PixelSize() const;
private:
bool alloc_ = false;
u8 *data_ = nullptr;
u32 stride_ = 0;
u32 height_ = 0;
GPUDebugBufferFormat fmt_ = GPU_DBG_FORMAT_INVALID;
bool flipped_ = false;
};
struct GPUDebugVertex {
float u;
float v;
float x;
float y;
float z;
u8 c[4];
float nx;
float ny;
float nz;
};
class GPUDebugInterface {
public:
virtual bool GetCurrentDisplayList(DisplayList &list) = 0;
virtual std::vector<DisplayList> ActiveDisplayLists() = 0;
virtual void ResetListPC(int listID, u32 pc) = 0;
virtual void ResetListStall(int listID, u32 stall) = 0;
virtual void ResetListState(int listID, DisplayListState state) = 0;
GPUDebugOp DissassembleOp(u32 pc) {
return DissassembleOp(pc, Memory::Read_U32(pc));
}
virtual GPUDebugOp DissassembleOp(u32 pc, u32 op) = 0;
virtual std::vector<GPUDebugOp> DissassembleOpRange(u32 startpc, u32 endpc) = 0;
// Enter/exit stepping mode. Mainly for better debug stats on time taken.
virtual void NotifySteppingEnter() = 0;
virtual void NotifySteppingExit() = 0;
virtual u32 GetRelativeAddress(u32 data) = 0;
virtual u32 GetVertexAddress() = 0;
virtual u32 GetIndexAddress() = 0;
virtual GPUgstate GetGState() = 0;
// Needs to be called from the GPU thread.
// Calling from a separate thread (e.g. UI) may fail.
virtual void SetCmdValue(u32 op) = 0;
virtual void DispatchFlush() = 0;
virtual uint32_t SetAddrTranslation(uint32_t value) = 0;
virtual uint32_t GetAddrTranslation() = 0;
virtual bool GetCurrentSimpleVertices(int count, std::vector<GPUDebugVertex> &vertices, std::vector<u16> &indices) {
return false;
}
// Needs to be called from the GPU thread, so on the same thread as a notification is fine.
// Calling from a separate thread (e.g. UI) may fail.
virtual bool GetCurrentFramebuffer(GPUDebugBuffer &buffer, GPUDebugFramebufferType type, int maxRes = -1) {
// False means unsupported.
return false;
}
// Similar to GetCurrentFramebuffer().
virtual bool GetCurrentDepthbuffer(GPUDebugBuffer &buffer) {
return false;
}
// Similar to GetCurrentFramebuffer().
virtual bool GetCurrentStencilbuffer(GPUDebugBuffer &buffer) {
return false;
}
// Similar to GetCurrentFramebuffer(), with texture level specification.
virtual bool GetCurrentTexture(GPUDebugBuffer &buffer, int level) {
return false;
}
virtual bool GetCurrentClut(GPUDebugBuffer &buffer) {
return false;
}
virtual bool GetOutputFramebuffer(GPUDebugBuffer &buffer) {
return false;
}
// TODO:
// cached framebuffers / textures / vertices?
// get content of specific framebuffer / texture?
// vertex / texture decoding?
};
bool GPUDebugInitExpression(GPUDebugInterface *g, const char *str, PostfixExpression &exp);
bool GPUDebugExecExpression(GPUDebugInterface *g, PostfixExpression &exp, uint32_t &result);
bool GPUDebugExecExpression(GPUDebugInterface *g, const char *str, uint32_t &result);