Merge branch 'master' of github.com:fleroviux/Panda3DS into pica-tev-emulation

This commit is contained in:
fleroviux 2023-06-20 22:47:47 +02:00
commit 4cb7e3625b
13 changed files with 427 additions and 412 deletions

View file

@ -8,6 +8,7 @@
#include "opengl.hpp"
#include "surface_cache.hpp"
#include "textures.hpp"
#include "PICA/regs.hpp"
// More circular dependencies!
class GPU;
@ -59,12 +60,12 @@ class Renderer {
OpenGL::uvec2 fbSize; // The size of the framebuffer (ie both the colour and depth buffer)'
u32 colourBufferLoc; // Location in 3DS VRAM for the colour buffer
ColourBuffer::Formats colourBufferFormat; // Format of the colours stored in the colour buffer
u32 colourBufferLoc; // Location in 3DS VRAM for the colour buffer
PICA::ColorFmt colourBufferFormat; // Format of the colours stored in the colour buffer
// Same for the depth/stencil buffer
u32 depthBufferLoc;
DepthBuffer::Formats depthBufferFormat;
PICA::DepthFmt depthBufferFormat;
// Dummy VAO/VBO for blitting the final output
OpenGL::VertexArray dummyVAO;
@ -93,23 +94,19 @@ class Renderer {
void getGraphicsContext(); // Set up graphics context for rendering
void clearBuffer(u32 startAddress, u32 endAddress, u32 value, u32 control); // Clear a GPU buffer in VRAM
void displayTransfer(u32 inputAddr, u32 outputAddr, u32 inputSize, u32 outputSize, u32 flags); // Perform display transfer
void drawVertices(OpenGL::Primitives primType, std::span<const Vertex> vertices); // Draw the given vertices
void drawVertices(PICA::PrimType primType, std::span<const Vertex> vertices); // Draw the given vertices
void setFBSize(u32 width, u32 height) {
fbSize.x() = width;
fbSize.y() = height;
}
void setColourFormat(ColourBuffer::Formats format) { colourBufferFormat = format; }
void setColourFormat(u32 format) { colourBufferFormat = static_cast<ColourBuffer::Formats>(format); }
void setDepthFormat(DepthBuffer::Formats format) { depthBufferFormat = format; }
void setDepthFormat(u32 format) {
if (format == 1) {
void setColourFormat(PICA::ColorFmt format) { colourBufferFormat = format; }
void setDepthFormat(PICA::DepthFmt format) {
if (format == PICA::DepthFmt::Unknown1) {
Helpers::panic("[PICA] Undocumented depth-stencil mode!");
}
depthBufferFormat = static_cast<DepthBuffer::Formats>(format);
depthBufferFormat = format;
}
void setColourBufferLoc(u32 loc) { colourBufferLoc = loc; }

View file

@ -1,4 +1,5 @@
#pragma once
#include "PICA/regs.hpp"
#include "boost/icl/interval.hpp"
#include "helpers.hpp"
#include "opengl.hpp"
@ -7,18 +8,8 @@ template <typename T>
using Interval = boost::icl::right_open_interval<T>;
struct ColourBuffer {
enum class Formats : u32 {
RGBA8 = 0,
BGR8 = 1,
RGB5A1 = 2,
RGB565 = 3,
RGBA4 = 4,
Trash1 = 5, Trash2 = 6, Trash3 = 7 // Technically selectable, but their function is unknown
};
u32 location;
Formats format;
PICA::ColorFmt format;
OpenGL::uvec2 size;
bool valid;
@ -30,7 +21,7 @@ struct ColourBuffer {
ColourBuffer() : valid(false) {}
ColourBuffer(u32 loc, Formats format, u32 x, u32 y, bool valid = true)
ColourBuffer(u32 loc, PICA::ColorFmt format, u32 x, u32 y, bool valid = true)
: location(loc), format(format), size({x, y}), valid(valid) {
u64 endLoc = (u64)loc + sizeInBytes();
@ -78,31 +69,14 @@ struct ColourBuffer {
size.x() == other.size.x() && size.y() == other.size.y();
}
// Size occupied by each pixel in bytes
// All formats are 16BPP except for RGBA8 (32BPP) and BGR8 (24BPP)
size_t sizePerPixel() {
switch (format) {
case Formats::BGR8: return 3;
case Formats::RGBA8: return 4;
default: return 2;
}
}
size_t sizeInBytes() {
return (size_t)size.x() * (size_t)size.y() * sizePerPixel();
return (size_t)size.x() * (size_t)size.y() * PICA::sizePerPixel(format);
}
};
struct DepthBuffer {
enum class Formats : u32 {
Depth16 = 0,
Garbage = 1,
Depth24 = 2,
Depth24Stencil8 = 3
};
u32 location;
Formats format;
PICA::DepthFmt format;
OpenGL::uvec2 size; // Implicitly set to the size of the framebuffer
bool valid;
@ -113,7 +87,7 @@ struct DepthBuffer {
DepthBuffer() : valid(false) {}
DepthBuffer(u32 loc, Formats format, u32 x, u32 y, bool valid = true) :
DepthBuffer(u32 loc, PICA::DepthFmt format, u32 x, u32 y, bool valid = true) :
location(loc), format(format), size({x, y}), valid(valid) {
u64 endLoc = (u64)loc + sizeInBytes();
@ -121,10 +95,6 @@ struct DepthBuffer {
range = Interval<u32>(loc, (u32)endLoc);
}
bool hasStencil() {
return format == Formats::Depth24Stencil8;
}
void allocate() {
// 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.
@ -167,18 +137,7 @@ struct DepthBuffer {
size.x() == other.size.x() && size.y() == other.size.y();
}
// Size occupied by each pixel in bytes
size_t sizePerPixel() {
switch (format) {
case Formats::Depth16: return 2;
case Formats::Depth24: return 3;
case Formats::Depth24Stencil8: return 4;
default: return 1; // Invalid format
}
}
size_t sizeInBytes() {
return (size_t)size.x() * (size_t)size.y() * sizePerPixel();
return (size_t)size.x() * (size_t)size.y() * PICA::sizePerPixel(format);
}
};

View file

@ -1,6 +1,7 @@
#pragma once
#include <array>
#include <string>
#include "PICA/regs.hpp"
#include "boost/icl/interval.hpp"
#include "helpers.hpp"
#include "opengl.hpp"
@ -9,28 +10,9 @@ template <typename T>
using Interval = boost::icl::right_open_interval<T>;
struct Texture {
enum class Formats : u32 {
RGBA8 = 0,
RGB8 = 1,
RGBA5551 = 2,
RGB565 = 3,
RGBA4 = 4,
IA8 = 5,
RG8 = 6,
I8 = 7,
A8 = 8,
IA4 = 9,
I4 = 10,
A4 = 11,
ETC1 = 12,
ETC1A4 = 13,
Trash1 = 14, Trash2 = 15 // TODO: What are these?
};
u32 location;
u32 config; // Magnification/minification filter, wrapping configs, etc
Formats format;
PICA::TextureFmt format;
OpenGL::uvec2 size;
bool valid;
@ -41,7 +23,7 @@ struct Texture {
Texture() : valid(false) {}
Texture(u32 loc, Formats format, u32 x, u32 y, u32 config, bool valid = true)
Texture(u32 loc, PICA::TextureFmt format, u32 x, u32 y, u32 config, bool valid = true)
: location(loc), format(format), size({x, y}), config(config), valid(valid) {
u64 endLoc = (u64)loc + sizeInBytes();
@ -62,7 +44,7 @@ struct Texture {
void free();
u64 sizeInBytes();
u32 decodeTexel(u32 u, u32 v, Formats fmt, const void* data);
u32 decodeTexel(u32 u, u32 v, PICA::TextureFmt fmt, const void* data);
// Get the morton interleave offset of a texel based on its U and V values
static u32 mortonInterleave(u32 u, u32 v);
@ -70,12 +52,9 @@ struct Texture {
static u32 getSwizzledOffset(u32 u, u32 v, u32 width, u32 bytesPerPixel);
static u32 getSwizzledOffset_4bpp(u32 u, u32 v, u32 width);
// Returns the string representation of a texture format
static std::string textureFormatToString(Formats fmt);
// Returns the format of this texture as a string
std::string formatToString() {
return textureFormatToString(format);
return PICA::textureFormatToString(format);
}
// Returns the texel at coordinates (u, v) of an ETC1(A4) texture