mirror of
https://github.com/wheremyfoodat/Panda3DS.git
synced 2025-06-03 12:27:21 +12:00
code: Better screen support
This commit is contained in:
parent
d28796fd3f
commit
f75a23b5a9
15 changed files with 305 additions and 66 deletions
|
@ -29,6 +29,7 @@ class GPU {
|
|||
static constexpr u32 vramSize = u32(6_MB);
|
||||
Registers regs; // GPU internal registers
|
||||
std::array<vec4f, 16> currentAttributes; // Vertex attributes before being passed to the shader
|
||||
std::array<u32, 0x1000> external_regs; // GPU external registers
|
||||
|
||||
std::array<vec4f, 16> immediateModeAttributes; // Vertex attributes uploaded via immediate mode submission
|
||||
std::array<PICA::Vertex, 3> immediateModeVertices;
|
||||
|
@ -97,6 +98,9 @@ class GPU {
|
|||
u32 readReg(u32 address);
|
||||
void writeReg(u32 address, u32 value);
|
||||
|
||||
u32 readExternalReg(u32 index);
|
||||
void writeExternalReg(u32 index, u32 value);
|
||||
|
||||
// Used when processing GPU command lists
|
||||
u32 readInternalReg(u32 index);
|
||||
void writeInternalReg(u32 index, u32 value, u32 mask);
|
||||
|
|
|
@ -178,6 +178,54 @@ namespace PICA {
|
|||
};
|
||||
}
|
||||
|
||||
namespace ExternalRegs {
|
||||
enum : u32 {
|
||||
MemFill1BufferStartPaddr = 0x3,
|
||||
MemFill1BufferEndPAddr = 0x4,
|
||||
MemFill1Value = 0x5,
|
||||
MemFill1Control = 0x6,
|
||||
MemFill2BufferStartPaddr = 0x7,
|
||||
MemFill2BufferEndPAddr = 0x8,
|
||||
MemFill2Value = 0x9,
|
||||
MemFill2Control = 0xA,
|
||||
VramBankControl = 0xB,
|
||||
GPUBusy = 0xC,
|
||||
BacklightControl = 0xBC,
|
||||
// TODO: Framebuffer regs
|
||||
Framebuffer0Size = 0x2F,
|
||||
Framebuffer0AFirstAddr = 0x119,
|
||||
Framebuffer0ASecondAddr = 0x11A,
|
||||
Framebuffer0Config = 0x11B,
|
||||
Framebuffer0Select = 0x11D,
|
||||
Framebuffer0Stride = 0x123,
|
||||
Framebuffer0BFirstAddr = 0x124,
|
||||
Framebuffer0BSecondAddr = 0x125,
|
||||
Framebuffer1Size = 0x156,
|
||||
Framebuffer1AFirstAddr = 0x159,
|
||||
Framebuffer1ASecondAddr = 0x15A,
|
||||
Framebuffer1Config = 0x15B,
|
||||
Framebuffer1Select = 0x15D,
|
||||
Framebuffer1Stride = 0x163,
|
||||
Framebuffer1BFirstAddr = 0x164,
|
||||
Framebuffer1BSecondAddr = 0x165,
|
||||
TransferInputPAddr = 0x2FF,
|
||||
TransferOutputPAddr = 0x300,
|
||||
DisplayTransferOutputDim = 0x301,
|
||||
DisplayTransferInputDim = 0x302,
|
||||
TransferFlags = 0x303,
|
||||
TransferTrigger = 0x305,
|
||||
TextureCopyTotalBytes = 0x307,
|
||||
TextureCopyInputLineGap = 0x308,
|
||||
TextureCopyOutputLineGap = 0x309,
|
||||
};
|
||||
}
|
||||
|
||||
enum class Scaling : u32 {
|
||||
None = 0,
|
||||
X = 1,
|
||||
XY = 2,
|
||||
};
|
||||
|
||||
namespace Lights {
|
||||
enum : u32 {
|
||||
LUT_D0 = 0,
|
||||
|
|
|
@ -248,4 +248,4 @@ public:
|
|||
|
||||
void setVRAM(u8* pointer) { vram = pointer; }
|
||||
bool allocateMainThreadStack(u32 size);
|
||||
};
|
||||
};
|
||||
|
|
|
@ -65,4 +65,4 @@ class Renderer {
|
|||
|
||||
void setColourBufferLoc(u32 loc) { colourBufferLoc = loc; }
|
||||
void setDepthBufferLoc(u32 loc) { depthBufferLoc = loc; }
|
||||
};
|
||||
};
|
||||
|
|
|
@ -213,4 +213,4 @@ struct GLStateManager {
|
|||
};
|
||||
|
||||
static_assert(std::is_trivially_constructible<GLStateManager>(), "OpenGL State Manager class is not trivially constructible!");
|
||||
static_assert(std::is_trivially_destructible<GLStateManager>(), "OpenGL State Manager class is not trivially destructible!");
|
||||
static_assert(std::is_trivially_destructible<GLStateManager>(), "OpenGL State Manager class is not trivially destructible!");
|
||||
|
|
|
@ -44,8 +44,8 @@ class RendererGL final : public Renderer {
|
|||
float oldDepthOffset = 0.0;
|
||||
bool oldDepthmapEnable = false;
|
||||
|
||||
SurfaceCache<DepthBuffer, 10, true> depthBufferCache;
|
||||
SurfaceCache<ColourBuffer, 10, true> colourBufferCache;
|
||||
SurfaceCache<DepthBuffer, 64, true> depthBufferCache;
|
||||
SurfaceCache<ColourBuffer, 64, true> colourBufferCache;
|
||||
SurfaceCache<Texture, 256, true> textureCache;
|
||||
|
||||
// Dummy VAO/VBO for blitting the final output
|
||||
|
@ -78,6 +78,8 @@ class RendererGL final : public Renderer {
|
|||
void displayTransfer(u32 inputAddr, u32 outputAddr, u32 inputSize, u32 outputSize, u32 flags) override; // Perform display transfer
|
||||
void drawVertices(PICA::PrimType primType, std::span<const PICA::Vertex> vertices) override; // Draw the given vertices
|
||||
|
||||
ColourBuffer getColourBuffer(u32 addr, PICA::ColorFmt format, u32 width, u32 height);
|
||||
|
||||
// Take a screenshot of the screen and store it in a file
|
||||
void screenshot(const std::string& name) override;
|
||||
};
|
||||
|
|
|
@ -19,6 +19,10 @@ struct ColourBuffer {
|
|||
OpenGL::Texture texture;
|
||||
OpenGL::Framebuffer fbo;
|
||||
|
||||
GLenum internalFormat;
|
||||
GLenum fmt;
|
||||
GLenum type;
|
||||
|
||||
ColourBuffer() : valid(false) {}
|
||||
|
||||
ColourBuffer(u32 loc, PICA::ColorFmt format, u32 x, u32 y, bool valid = true)
|
||||
|
@ -29,12 +33,32 @@ struct ColourBuffer {
|
|||
range = Interval<u32>(loc, (u32)endLoc);
|
||||
}
|
||||
|
||||
void allocate() {
|
||||
void allocate() {
|
||||
// Internal formats for the texture based on format
|
||||
static constexpr std::array<GLenum, 5> internalFormats = {
|
||||
GL_RGBA8, GL_RGB8, GL_RGB5_A1, GL_RGB565, GL_RGBA4
|
||||
};
|
||||
|
||||
// Format of the texture
|
||||
static constexpr std::array<GLenum, 5> formats = {
|
||||
GL_RGBA, GL_BGR, GL_RGBA, GL_RGB, GL_RGBA,
|
||||
};
|
||||
|
||||
static constexpr std::array<GLenum, 5> types = {
|
||||
GL_UNSIGNED_INT_8_8_8_8, GL_UNSIGNED_BYTE, GL_UNSIGNED_SHORT_5_5_5_1,
|
||||
GL_UNSIGNED_SHORT_5_6_5, GL_UNSIGNED_SHORT_4_4_4_4,
|
||||
};
|
||||
|
||||
internalFormat = internalFormats[(int)format];
|
||||
fmt = formats[(int)format];
|
||||
type = types[(int)format];
|
||||
|
||||
|
||||
// Create texture for the FBO, setting up filters and the like
|
||||
// Reading back the current texture is slow, but allocate calls should be few and far between.
|
||||
// If this becomes a bottleneck, we can fix it semi-easily
|
||||
auto prevTexture = OpenGL::getTex2D();
|
||||
texture.create(size.x(), size.y(), GL_RGBA8);
|
||||
texture.create(size.x(), size.y(), internalFormat);
|
||||
texture.bind();
|
||||
texture.setMinFilter(OpenGL::Linear);
|
||||
texture.setMagFilter(OpenGL::Linear);
|
||||
|
|
|
@ -53,7 +53,7 @@ struct Texture {
|
|||
static u32 getSwizzledOffset_4bpp(u32 u, u32 v, u32 width);
|
||||
|
||||
// Returns the format of this texture as a string
|
||||
std::string formatToString() {
|
||||
std::string_view formatToString() {
|
||||
return PICA::textureFormatToString(format);
|
||||
}
|
||||
|
||||
|
|
|
@ -14,4 +14,4 @@ class RendererNull final : public Renderer {
|
|||
void displayTransfer(u32 inputAddr, u32 outputAddr, u32 inputSize, u32 outputSize, u32 flags) override;
|
||||
void drawVertices(PICA::PrimType primType, std::span<const PICA::Vertex> vertices) override;
|
||||
void screenshot(const std::string& name) override;
|
||||
};
|
||||
};
|
||||
|
|
|
@ -18,6 +18,24 @@ enum class GPUInterrupt : u8 {
|
|||
DMA = 6
|
||||
};
|
||||
|
||||
struct FramebufferInfo {
|
||||
u32 activeFb;
|
||||
u32 leftFramebufferVaddr;
|
||||
u32 rightFramebufferVaddr;
|
||||
u32 stride;
|
||||
u32 format;
|
||||
u32 displayFb;
|
||||
u32 attribute;
|
||||
};
|
||||
|
||||
struct FrameBufferUpdate {
|
||||
u8 index;
|
||||
u8 dirtyFlag;
|
||||
u16 pad0;
|
||||
std::array<FramebufferInfo, 2> framebufferInfo;
|
||||
u32 pad1;
|
||||
};
|
||||
|
||||
// More circular dependencies
|
||||
class Kernel;
|
||||
|
||||
|
@ -45,6 +63,7 @@ class GPUService {
|
|||
void flushDataCache(u32 messagePointer);
|
||||
void registerInterruptRelayQueue(u32 messagePointer);
|
||||
void setAxiConfigQoSMode(u32 messagePointer);
|
||||
void setBufferSwap(u32 messagePointer);
|
||||
void setInternalPriorities(u32 messagePointer);
|
||||
void setLCDForceBlack(u32 messagePointer);
|
||||
void storeDataCache(u32 messagePointer);
|
||||
|
@ -60,6 +79,8 @@ class GPUService {
|
|||
void triggerTextureCopy(u32* cmd);
|
||||
void flushCacheRegions(u32* cmd);
|
||||
|
||||
void setBufferSwapImpl(u32 screen_id, const FramebufferInfo& info);
|
||||
|
||||
public:
|
||||
GPUService(Memory& mem, GPU& gpu, Kernel& kernel, u32& currentPID) : mem(mem), gpu(gpu),
|
||||
kernel(kernel), currentPID(currentPID) {}
|
||||
|
@ -72,4 +93,4 @@ public:
|
|||
std::memset(ptr, 0, 0x1000);
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue