mirror of
https://github.com/wheremyfoodat/Panda3DS.git
synced 2025-04-11 08:39:48 +12:00
Migrate PICA-types into PICA
namespace
Rather than prefixing these types with `PICA`, a namespace is used instead.
This commit is contained in:
parent
78a3f9fa23
commit
838d3f27f9
7 changed files with 204 additions and 201 deletions
|
@ -47,7 +47,7 @@ class GPU {
|
|||
};
|
||||
|
||||
u64 getVertexShaderInputConfig() {
|
||||
return u64(regs[PICAInternalRegs::VertexShaderInputCfgLow]) | (u64(regs[PICAInternalRegs::VertexShaderInputCfgHigh]) << 32);
|
||||
return u64(regs[PICA::InternalRegs::VertexShaderInputCfgLow]) | (u64(regs[PICA::InternalRegs::VertexShaderInputCfgHigh]) << 32);
|
||||
}
|
||||
|
||||
std::array<AttribInfo, maxAttribCount> attributeInfo; // Info for each of the 12 attributes
|
||||
|
|
|
@ -1,177 +1,180 @@
|
|||
#pragma once
|
||||
#include "helpers.hpp"
|
||||
|
||||
namespace PICAInternalRegs {
|
||||
enum : u32 {
|
||||
// Rasterizer registers
|
||||
ViewportWidth = 0x41,
|
||||
ViewportInvw = 0x42,
|
||||
ViewportHeight = 0x43,
|
||||
ViewportInvh = 0x44,
|
||||
namespace PICA {
|
||||
namespace InternalRegs {
|
||||
enum : u32 {
|
||||
// Rasterizer registers
|
||||
ViewportWidth = 0x41,
|
||||
ViewportInvw = 0x42,
|
||||
ViewportHeight = 0x43,
|
||||
ViewportInvh = 0x44,
|
||||
|
||||
DepthScale = 0x4D,
|
||||
DepthOffset = 0x4E,
|
||||
ShaderOutputCount = 0x4F,
|
||||
DepthScale = 0x4D,
|
||||
DepthOffset = 0x4E,
|
||||
ShaderOutputCount = 0x4F,
|
||||
|
||||
DepthmapEnable = 0x6D,
|
||||
TexUnitCfg = 0x80,
|
||||
DepthmapEnable = 0x6D,
|
||||
TexUnitCfg = 0x80,
|
||||
|
||||
// Framebuffer registers
|
||||
ColourOperation = 0x100,
|
||||
BlendFunc = 0x101,
|
||||
BlendColour = 0x103,
|
||||
AlphaTestConfig = 0x104,
|
||||
DepthAndColorMask = 0x107,
|
||||
DepthBufferFormat = 0x116,
|
||||
ColourBufferFormat = 0x117,
|
||||
DepthBufferLoc = 0x11C,
|
||||
ColourBufferLoc = 0x11D,
|
||||
FramebufferSize = 0x11E,
|
||||
// Framebuffer registers
|
||||
ColourOperation = 0x100,
|
||||
BlendFunc = 0x101,
|
||||
BlendColour = 0x103,
|
||||
AlphaTestConfig = 0x104,
|
||||
DepthAndColorMask = 0x107,
|
||||
DepthBufferFormat = 0x116,
|
||||
ColourBufferFormat = 0x117,
|
||||
DepthBufferLoc = 0x11C,
|
||||
ColourBufferLoc = 0x11D,
|
||||
FramebufferSize = 0x11E,
|
||||
|
||||
// Geometry pipeline registers
|
||||
VertexAttribLoc = 0x200,
|
||||
AttribFormatLow = 0x201,
|
||||
AttribFormatHigh = 0x202,
|
||||
IndexBufferConfig = 0x227,
|
||||
VertexCountReg = 0x228,
|
||||
VertexOffsetReg = 0x22A,
|
||||
SignalDrawArrays = 0x22E,
|
||||
SignalDrawElements = 0x22F,
|
||||
// Geometry pipeline registers
|
||||
VertexAttribLoc = 0x200,
|
||||
AttribFormatLow = 0x201,
|
||||
AttribFormatHigh = 0x202,
|
||||
IndexBufferConfig = 0x227,
|
||||
VertexCountReg = 0x228,
|
||||
VertexOffsetReg = 0x22A,
|
||||
SignalDrawArrays = 0x22E,
|
||||
SignalDrawElements = 0x22F,
|
||||
|
||||
Attrib0Offset = 0x203,
|
||||
Attrib1Offset = 0x206,
|
||||
Attrib2Offset = 0x209,
|
||||
Attrib3Offset = 0x20C,
|
||||
Attrib4Offset = 0x20F,
|
||||
Attrib5Offset = 0x212,
|
||||
Attrib6Offset = 0x215,
|
||||
Attrib7Offset = 0x218,
|
||||
Attrib8Offset = 0x21B,
|
||||
Attrib9Offset = 0x21E,
|
||||
Attrib10Offset = 0x221,
|
||||
Attrib11Offset = 0x224,
|
||||
Attrib0Offset = 0x203,
|
||||
Attrib1Offset = 0x206,
|
||||
Attrib2Offset = 0x209,
|
||||
Attrib3Offset = 0x20C,
|
||||
Attrib4Offset = 0x20F,
|
||||
Attrib5Offset = 0x212,
|
||||
Attrib6Offset = 0x215,
|
||||
Attrib7Offset = 0x218,
|
||||
Attrib8Offset = 0x21B,
|
||||
Attrib9Offset = 0x21E,
|
||||
Attrib10Offset = 0x221,
|
||||
Attrib11Offset = 0x224,
|
||||
|
||||
Attrib0Config2 = 0x205,
|
||||
Attrib1Config2 = 0x208,
|
||||
Attrib2Config2 = 0x20B,
|
||||
Attrib3Config2 = 0x20E,
|
||||
Attrib4Config2 = 0x211,
|
||||
Attrib5Config2 = 0x214,
|
||||
Attrib6Config2 = 0x217,
|
||||
Attrib7Config2 = 0x21A,
|
||||
Attrib8Config2 = 0x21D,
|
||||
Attrib9Config2 = 0x220,
|
||||
Attrib10Config2 = 0x223,
|
||||
Attrib11Config2 = 0x226,
|
||||
Attrib0Config2 = 0x205,
|
||||
Attrib1Config2 = 0x208,
|
||||
Attrib2Config2 = 0x20B,
|
||||
Attrib3Config2 = 0x20E,
|
||||
Attrib4Config2 = 0x211,
|
||||
Attrib5Config2 = 0x214,
|
||||
Attrib6Config2 = 0x217,
|
||||
Attrib7Config2 = 0x21A,
|
||||
Attrib8Config2 = 0x21D,
|
||||
Attrib9Config2 = 0x220,
|
||||
Attrib10Config2 = 0x223,
|
||||
Attrib11Config2 = 0x226,
|
||||
|
||||
AttribInfoStart = Attrib0Offset,
|
||||
AttribInfoEnd = Attrib11Config2,
|
||||
AttribInfoStart = Attrib0Offset,
|
||||
AttribInfoEnd = Attrib11Config2,
|
||||
|
||||
// Fixed attribute registers
|
||||
FixedAttribIndex = 0x232,
|
||||
FixedAttribData0 = 0x233,
|
||||
FixedAttribData1 = 0x234,
|
||||
FixedAttribData2 = 0x235,
|
||||
// Fixed attribute registers
|
||||
FixedAttribIndex = 0x232,
|
||||
FixedAttribData0 = 0x233,
|
||||
FixedAttribData1 = 0x234,
|
||||
FixedAttribData2 = 0x235,
|
||||
|
||||
// Command processor registers
|
||||
CmdBufSize0 = 0x238,
|
||||
CmdBufSize1 = 0x239,
|
||||
CmdBufAddr0 = 0x23A,
|
||||
CmdBufAddr1 = 0x23B,
|
||||
CmdBufTrigger0 = 0x23C,
|
||||
CmdBufTrigger1 = 0x23D,
|
||||
// Command processor registers
|
||||
CmdBufSize0 = 0x238,
|
||||
CmdBufSize1 = 0x239,
|
||||
CmdBufAddr0 = 0x23A,
|
||||
CmdBufAddr1 = 0x23B,
|
||||
CmdBufTrigger0 = 0x23C,
|
||||
CmdBufTrigger1 = 0x23D,
|
||||
|
||||
PrimitiveConfig = 0x25E,
|
||||
PrimitiveRestart = 0x25F,
|
||||
PrimitiveConfig = 0x25E,
|
||||
PrimitiveRestart = 0x25F,
|
||||
|
||||
// Vertex shader registers
|
||||
VertexShaderAttrNum = 0x242,
|
||||
VertexBoolUniform = 0x2B0,
|
||||
VertexIntUniform0 = 0x2B1,
|
||||
VertexIntUniform1 = 0x2B2,
|
||||
VertexIntUniform2 = 0x2B3,
|
||||
VertexIntUniform3 = 0x2B4,
|
||||
// Vertex shader registers
|
||||
VertexShaderAttrNum = 0x242,
|
||||
VertexBoolUniform = 0x2B0,
|
||||
VertexIntUniform0 = 0x2B1,
|
||||
VertexIntUniform1 = 0x2B2,
|
||||
VertexIntUniform2 = 0x2B3,
|
||||
VertexIntUniform3 = 0x2B4,
|
||||
|
||||
VertexShaderEntrypoint = 0x2BA,
|
||||
VertexShaderTransferEnd = 0x2BF,
|
||||
VertexFloatUniformIndex = 0x2C0,
|
||||
VertexFloatUniformData0 = 0x2C1,
|
||||
VertexFloatUniformData1 = 0x2C2,
|
||||
VertexFloatUniformData2 = 0x2C3,
|
||||
VertexFloatUniformData3 = 0x2C4,
|
||||
VertexFloatUniformData4 = 0x2C5,
|
||||
VertexFloatUniformData5 = 0x2C6,
|
||||
VertexFloatUniformData6 = 0x2C7,
|
||||
VertexFloatUniformData7 = 0x2C8,
|
||||
VertexShaderEntrypoint = 0x2BA,
|
||||
VertexShaderTransferEnd = 0x2BF,
|
||||
VertexFloatUniformIndex = 0x2C0,
|
||||
VertexFloatUniformData0 = 0x2C1,
|
||||
VertexFloatUniformData1 = 0x2C2,
|
||||
VertexFloatUniformData2 = 0x2C3,
|
||||
VertexFloatUniformData3 = 0x2C4,
|
||||
VertexFloatUniformData4 = 0x2C5,
|
||||
VertexFloatUniformData5 = 0x2C6,
|
||||
VertexFloatUniformData6 = 0x2C7,
|
||||
VertexFloatUniformData7 = 0x2C8,
|
||||
|
||||
VertexShaderInputBufferCfg = 0x2B9,
|
||||
VertexShaderInputCfgLow = 0x2BB,
|
||||
VertexShaderInputCfgHigh = 0x2BC,
|
||||
VertexShaderInputBufferCfg = 0x2B9,
|
||||
VertexShaderInputCfgLow = 0x2BB,
|
||||
VertexShaderInputCfgHigh = 0x2BC,
|
||||
|
||||
VertexShaderTransferIndex = 0x2CB,
|
||||
VertexShaderData0 = 0x2CC,
|
||||
VertexShaderData1 = 0x2CD,
|
||||
VertexShaderData2 = 0x2CE,
|
||||
VertexShaderData3 = 0x2CF,
|
||||
VertexShaderData4 = 0x2D0,
|
||||
VertexShaderData5 = 0x2D1,
|
||||
VertexShaderData6 = 0x2D2,
|
||||
VertexShaderData7 = 0x2D3,
|
||||
VertexShaderOpDescriptorIndex = 0x2D5,
|
||||
VertexShaderOpDescriptorData0 = 0x2D6,
|
||||
VertexShaderOpDescriptorData1 = 0x2D7,
|
||||
VertexShaderOpDescriptorData2 = 0x2D8,
|
||||
VertexShaderOpDescriptorData3 = 0x2D9,
|
||||
VertexShaderOpDescriptorData4 = 0x2DA,
|
||||
VertexShaderOpDescriptorData5 = 0x2DB,
|
||||
VertexShaderOpDescriptorData6 = 0x2DC,
|
||||
VertexShaderOpDescriptorData7 = 0x2DD,
|
||||
VertexShaderTransferIndex = 0x2CB,
|
||||
VertexShaderData0 = 0x2CC,
|
||||
VertexShaderData1 = 0x2CD,
|
||||
VertexShaderData2 = 0x2CE,
|
||||
VertexShaderData3 = 0x2CF,
|
||||
VertexShaderData4 = 0x2D0,
|
||||
VertexShaderData5 = 0x2D1,
|
||||
VertexShaderData6 = 0x2D2,
|
||||
VertexShaderData7 = 0x2D3,
|
||||
VertexShaderOpDescriptorIndex = 0x2D5,
|
||||
VertexShaderOpDescriptorData0 = 0x2D6,
|
||||
VertexShaderOpDescriptorData1 = 0x2D7,
|
||||
VertexShaderOpDescriptorData2 = 0x2D8,
|
||||
VertexShaderOpDescriptorData3 = 0x2D9,
|
||||
VertexShaderOpDescriptorData4 = 0x2DA,
|
||||
VertexShaderOpDescriptorData5 = 0x2DB,
|
||||
VertexShaderOpDescriptorData6 = 0x2DC,
|
||||
VertexShaderOpDescriptorData7 = 0x2DD,
|
||||
};
|
||||
}
|
||||
|
||||
enum class ColorFmt : u32 {
|
||||
RGBA8 = 0,
|
||||
BGR8 = 1,
|
||||
RGB5A1 = 2,
|
||||
RGB565 = 3,
|
||||
RGBA4 = 4,
|
||||
|
||||
// Technically selectable, but their function is unknown
|
||||
Unknown5 = 5,
|
||||
Unknown6 = 6,
|
||||
Unknown7 = 7,
|
||||
};
|
||||
}
|
||||
|
||||
enum class PICAColorFmt : u32 {
|
||||
RGBA8 = 0,
|
||||
BGR8 = 1,
|
||||
RGB5A1 = 2,
|
||||
RGB565 = 3,
|
||||
RGBA4 = 4,
|
||||
enum class DepthFmt : u32 {
|
||||
Depth16 = 0,
|
||||
Unknown1 = 1, // Technically selectable, but function is unknown
|
||||
Depth24 = 2,
|
||||
Depth24Stencil8 = 3,
|
||||
};
|
||||
|
||||
// Technically selectable, but their function is unknown
|
||||
Unknown5 = 5,
|
||||
Unknown6 = 6,
|
||||
Unknown7 = 7,
|
||||
};
|
||||
// Size occupied by each pixel in bytes
|
||||
|
||||
enum class PICADepthFmt : u32 {
|
||||
Depth16 = 0,
|
||||
Unknown1 = 1, // Technically selectable, but function is unknown
|
||||
Depth24 = 2,
|
||||
Depth24Stencil8 = 3,
|
||||
};
|
||||
|
||||
// Size occupied by each pixel in bytes
|
||||
|
||||
// All formats are 16BPP except for RGBA8 (32BPP) and BGR8 (24BPP)
|
||||
inline constexpr usize sizePerPixel(PICAColorFmt format) {
|
||||
switch (format) {
|
||||
case PICAColorFmt::BGR8: return 3;
|
||||
case PICAColorFmt::RGBA8: return 4;
|
||||
default: return 2;
|
||||
// All formats are 16BPP except for RGBA8 (32BPP) and BGR8 (24BPP)
|
||||
inline constexpr usize sizePerPixel(ColorFmt format) {
|
||||
switch (format) {
|
||||
case ColorFmt::BGR8: return 3;
|
||||
case ColorFmt::RGBA8: return 4;
|
||||
default: return 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inline constexpr usize sizePerPixel(PICADepthFmt format) {
|
||||
switch (format) {
|
||||
case PICADepthFmt::Depth16: return 2;
|
||||
case PICADepthFmt::Depth24: return 3;
|
||||
case PICADepthFmt::Depth24Stencil8: return 4;
|
||||
default: return 1; // Invalid format
|
||||
inline constexpr usize sizePerPixel(DepthFmt format) {
|
||||
switch (format) {
|
||||
case DepthFmt::Depth16: return 2;
|
||||
case DepthFmt::Depth24: return 3;
|
||||
case DepthFmt::Depth24Stencil8: return 4;
|
||||
default: return 1; // Invalid format
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
enum class PICAPrimType : u32 {
|
||||
TriangleList = 0,
|
||||
TriangleStrip = 1,
|
||||
TriangleFan = 2,
|
||||
GeometryPrimitive = 3,
|
||||
};
|
||||
enum class PrimType : u32 {
|
||||
TriangleList = 0,
|
||||
TriangleStrip = 1,
|
||||
TriangleFan = 2,
|
||||
GeometryPrimitive = 3,
|
||||
};
|
||||
|
||||
} // namespace PICA
|
|
@ -47,11 +47,11 @@ 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
|
||||
PICAColorFmt colourBufferFormat; // Format of the colours stored in the colour buffer
|
||||
PICA::ColorFmt colourBufferFormat; // Format of the colours stored in the colour buffer
|
||||
|
||||
// Same for the depth/stencil buffer
|
||||
u32 depthBufferLoc;
|
||||
PICADepthFmt depthBufferFormat;
|
||||
PICA::DepthFmt depthBufferFormat;
|
||||
|
||||
// Dummy VAO/VBO for blitting the final output
|
||||
OpenGL::VertexArray dummyVAO;
|
||||
|
@ -76,16 +76,16 @@ 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(PICAPrimType 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(PICAColorFmt format) { colourBufferFormat = format; }
|
||||
void setDepthFormat(PICADepthFmt format) {
|
||||
if (format == PICADepthFmt::Unknown1) {
|
||||
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 = format;
|
||||
|
|
|
@ -9,7 +9,7 @@ using Interval = boost::icl::right_open_interval<T>;
|
|||
|
||||
struct ColourBuffer {
|
||||
u32 location;
|
||||
PICAColorFmt format;
|
||||
PICA::ColorFmt format;
|
||||
OpenGL::uvec2 size;
|
||||
bool valid;
|
||||
|
||||
|
@ -21,7 +21,7 @@ struct ColourBuffer {
|
|||
|
||||
ColourBuffer() : valid(false) {}
|
||||
|
||||
ColourBuffer(u32 loc, PICAColorFmt 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();
|
||||
|
@ -70,13 +70,13 @@ struct ColourBuffer {
|
|||
}
|
||||
|
||||
size_t sizeInBytes() {
|
||||
return (size_t)size.x() * (size_t)size.y() * sizePerPixel(format);
|
||||
return (size_t)size.x() * (size_t)size.y() * PICA::sizePerPixel(format);
|
||||
}
|
||||
};
|
||||
|
||||
struct DepthBuffer {
|
||||
u32 location;
|
||||
PICADepthFmt format;
|
||||
PICA::DepthFmt format;
|
||||
OpenGL::uvec2 size; // Implicitly set to the size of the framebuffer
|
||||
bool valid;
|
||||
|
||||
|
@ -87,7 +87,7 @@ struct DepthBuffer {
|
|||
|
||||
DepthBuffer() : valid(false) {}
|
||||
|
||||
DepthBuffer(u32 loc, PICADepthFmt 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();
|
||||
|
@ -96,7 +96,7 @@ struct DepthBuffer {
|
|||
}
|
||||
|
||||
bool hasStencil() {
|
||||
return format == PICADepthFmt::Depth24Stencil8;
|
||||
return format == PICA::DepthFmt::Depth24Stencil8;
|
||||
}
|
||||
|
||||
void allocate() {
|
||||
|
@ -142,6 +142,6 @@ struct DepthBuffer {
|
|||
}
|
||||
|
||||
size_t sizeInBytes() {
|
||||
return (size_t)size.x() * (size_t)size.y() * sizePerPixel(format);
|
||||
return (size_t)size.x() * (size_t)size.y() * PICA::sizePerPixel(format);
|
||||
}
|
||||
};
|
|
@ -50,45 +50,45 @@ template <bool indexed>
|
|||
void GPU::drawArrays() {
|
||||
// Base address for vertex attributes
|
||||
// The vertex base is always on a quadword boundary because the PICA does weird alignment shit any time possible
|
||||
const u32 vertexBase = ((regs[PICAInternalRegs::VertexAttribLoc] >> 1) & 0xfffffff) * 16;
|
||||
const u32 vertexCount = regs[PICAInternalRegs::VertexCountReg]; // Total # of vertices to transfer
|
||||
const u32 vertexBase = ((regs[PICA::InternalRegs::VertexAttribLoc] >> 1) & 0xfffffff) * 16;
|
||||
const u32 vertexCount = regs[PICA::InternalRegs::VertexCountReg]; // Total # of vertices to transfer
|
||||
|
||||
// Configures the type of primitive and the number of vertex shader outputs
|
||||
const u32 primConfig = regs[PICAInternalRegs::PrimitiveConfig];
|
||||
const PICAPrimType primType = static_cast<PICAPrimType>(Helpers::getBits<8, 2>(primConfig));
|
||||
if (primType == PICAPrimType::TriangleFan) Helpers::panic("[PICA] Tried to draw unimplemented shape %d\n", primType);
|
||||
const u32 primConfig = regs[PICA::InternalRegs::PrimitiveConfig];
|
||||
const PICA::PrimType primType = static_cast<PICA::PrimType>(Helpers::getBits<8, 2>(primConfig));
|
||||
if (primType == PICA::PrimType::TriangleFan) Helpers::panic("[PICA] Tried to draw unimplemented shape %d\n", primType);
|
||||
if (vertexCount > Renderer::vertexBufferSize) Helpers::panic("[PICA] vertexCount > vertexBufferSize");
|
||||
|
||||
if ((primType == PICAPrimType::TriangleList && vertexCount % 3) ||
|
||||
(primType == PICAPrimType::TriangleStrip && vertexCount < 3)) {
|
||||
if ((primType == PICA::PrimType::TriangleList && vertexCount % 3) ||
|
||||
(primType == PICA::PrimType::TriangleStrip && vertexCount < 3)) {
|
||||
Helpers::panic("Invalid vertex count for primitive. Type: %d, vert count: %d\n", primType, vertexCount);
|
||||
}
|
||||
|
||||
// Get the configuration for the index buffer, used only for indexed drawing
|
||||
u32 indexBufferConfig = regs[PICAInternalRegs::IndexBufferConfig];
|
||||
u32 indexBufferConfig = regs[PICA::InternalRegs::IndexBufferConfig];
|
||||
u32 indexBufferPointer = vertexBase + (indexBufferConfig & 0xfffffff);
|
||||
bool shortIndex = Helpers::getBit<31>(indexBufferConfig); // Indicates whether vert indices are 16-bit or 8-bit
|
||||
|
||||
// Stuff the global attribute config registers in one u64 to make attr parsing easier
|
||||
// TODO: Cache this when the vertex attribute format registers are written to
|
||||
u64 vertexCfg = u64(regs[PICAInternalRegs::AttribFormatLow]) | (u64(regs[PICAInternalRegs::AttribFormatHigh]) << 32);
|
||||
u64 vertexCfg = u64(regs[PICA::InternalRegs::AttribFormatLow]) | (u64(regs[PICA::InternalRegs::AttribFormatHigh]) << 32);
|
||||
|
||||
if constexpr (!indexed) {
|
||||
u32 offset = regs[PICAInternalRegs::VertexOffsetReg];
|
||||
u32 offset = regs[PICA::InternalRegs::VertexOffsetReg];
|
||||
log("PICA::DrawArrays(vertex count = %d, vertexOffset = %d)\n", vertexCount, offset);
|
||||
} else {
|
||||
log("PICA::DrawElements(vertex count = %d, index buffer config = %08X)\n", vertexCount, indexBufferConfig);
|
||||
}
|
||||
|
||||
// Total number of input attributes to shader. Differs between GS and VS. Currently stubbed to the VS one, as we don't have geometry shaders.
|
||||
const u32 inputAttrCount = (regs[PICAInternalRegs::VertexShaderInputBufferCfg] & 0xf) + 1;
|
||||
const u32 inputAttrCount = (regs[PICA::InternalRegs::VertexShaderInputBufferCfg] & 0xf) + 1;
|
||||
const u64 inputAttrCfg = getVertexShaderInputConfig();
|
||||
|
||||
for (u32 i = 0; i < vertexCount; i++) {
|
||||
u32 vertexIndex; // Index of the vertex in the VBO
|
||||
|
||||
if constexpr (!indexed) {
|
||||
vertexIndex = i + regs[PICAInternalRegs::VertexOffsetReg];
|
||||
vertexIndex = i + regs[PICA::InternalRegs::VertexOffsetReg];
|
||||
} else {
|
||||
if (shortIndex) {
|
||||
auto ptr = getPointerPhys<u16>(indexBufferPointer);
|
||||
|
@ -209,7 +209,7 @@ void GPU::drawArrays() {
|
|||
|
||||
Vertex GPU::getImmediateModeVertex() {
|
||||
Vertex v;
|
||||
const int totalAttrCount = (regs[PICAInternalRegs::VertexShaderAttrNum] & 0xf) + 1;
|
||||
const int totalAttrCount = (regs[PICA::InternalRegs::VertexShaderAttrNum] & 0xf) + 1;
|
||||
|
||||
// Copy immediate mode attributes to vertex shader unit
|
||||
for (int i = 0; i < totalAttrCount; i++) {
|
||||
|
|
|
@ -33,7 +33,7 @@ u32 GPU::readInternalReg(u32 index) {
|
|||
}
|
||||
|
||||
void GPU::writeInternalReg(u32 index, u32 value, u32 mask) {
|
||||
using namespace PICAInternalRegs;
|
||||
using namespace PICA::InternalRegs;
|
||||
|
||||
if (index > regNum) {
|
||||
Helpers::panic("Tried to write to invalid GPU register. Index: %X, value: %08X\n", index, value);
|
||||
|
@ -68,7 +68,7 @@ void GPU::writeInternalReg(u32 index, u32 value, u32 mask) {
|
|||
|
||||
case ColourBufferFormat: {
|
||||
u32 format = getBits<16, 3>(value);
|
||||
renderer.setColourFormat(static_cast<PICAColorFmt>(format));
|
||||
renderer.setColourFormat(static_cast<PICA::ColorFmt>(format));
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -80,7 +80,7 @@ void GPU::writeInternalReg(u32 index, u32 value, u32 mask) {
|
|||
|
||||
case DepthBufferFormat: {
|
||||
u32 format = value & 0x3;
|
||||
renderer.setDepthFormat(static_cast<PICADepthFmt>(format));
|
||||
renderer.setDepthFormat(static_cast<PICA::DepthFmt>(format));
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -137,7 +137,7 @@ void GPU::writeInternalReg(u32 index, u32 value, u32 mask) {
|
|||
if (fixedAttribIndex < 12) [[likely]] {
|
||||
shaderUnit.vs.fixedAttributes[fixedAttribIndex++] = attr;
|
||||
} else if (fixedAttribIndex == 15) { // Otherwise if it's 15, we're submitting an immediate mode vertex
|
||||
const uint totalAttrCount = (regs[PICAInternalRegs::VertexShaderAttrNum] & 0xf) + 1;
|
||||
const uint totalAttrCount = (regs[PICA::InternalRegs::VertexShaderAttrNum] & 0xf) + 1;
|
||||
if (totalAttrCount <= immediateModeAttrIndex) {
|
||||
printf("Broken state in the immediate mode vertex submission pipeline. Failing silently\n");
|
||||
immediateModeAttrIndex = 0;
|
||||
|
@ -151,13 +151,13 @@ void GPU::writeInternalReg(u32 index, u32 value, u32 mask) {
|
|||
immediateModeVertices[immediateModeVertIndex++] = v;
|
||||
|
||||
// Get primitive type
|
||||
const u32 primConfig = regs[PICAInternalRegs::PrimitiveConfig];
|
||||
const u32 primConfig = regs[PICA::InternalRegs::PrimitiveConfig];
|
||||
const u32 primType = getBits<8, 2>(primConfig);
|
||||
|
||||
// If we've reached 3 verts, issue a draw call
|
||||
// Handle rendering depending on the primitive type
|
||||
if (immediateModeVertIndex == 3) {
|
||||
renderer.drawVertices(PICAPrimType::TriangleList, immediateModeVertices);
|
||||
renderer.drawVertices(PICA::PrimType::TriangleList, immediateModeVertices);
|
||||
|
||||
switch (primType) {
|
||||
// Triangle or geometry primitive. Draw a triangle and discard all vertices
|
||||
|
|
|
@ -144,10 +144,10 @@ void Renderer::reset() {
|
|||
|
||||
// Init the colour/depth buffer settings to some random defaults on reset
|
||||
colourBufferLoc = 0;
|
||||
colourBufferFormat = PICAColorFmt::RGBA8;
|
||||
colourBufferFormat = PICA::ColorFmt::RGBA8;
|
||||
|
||||
depthBufferLoc = 0;
|
||||
depthBufferFormat = PICADepthFmt::Depth16;
|
||||
depthBufferFormat = PICA::DepthFmt::Depth16;
|
||||
|
||||
if (triangleProgram.exists()) {
|
||||
const auto oldProgram = OpenGL::getProgram();
|
||||
|
@ -221,7 +221,7 @@ void Renderer::getGraphicsContext() {
|
|||
|
||||
// Set up the OpenGL blending context to match the emulated PICA
|
||||
void Renderer::setupBlending() {
|
||||
const bool blendingEnabled = (regs[PICAInternalRegs::ColourOperation] & (1 << 8)) != 0;
|
||||
const bool blendingEnabled = (regs[PICA::InternalRegs::ColourOperation] & (1 << 8)) != 0;
|
||||
|
||||
// Map of PICA blending equations to OpenGL blending equations. The unused blending equations are equivalent to equation 0 (add)
|
||||
static constexpr std::array<GLenum, 8> blendingEquations = {
|
||||
|
@ -241,7 +241,7 @@ void Renderer::setupBlending() {
|
|||
OpenGL::enableBlend();
|
||||
|
||||
// Get blending equations
|
||||
const u32 blendControl = regs[PICAInternalRegs::BlendFunc];
|
||||
const u32 blendControl = regs[PICA::InternalRegs::BlendFunc];
|
||||
const u32 rgbEquation = blendControl & 0x7;
|
||||
const u32 alphaEquation = getBits<8, 3>(blendControl);
|
||||
|
||||
|
@ -251,7 +251,7 @@ void Renderer::setupBlending() {
|
|||
const u32 alphaSourceFunc = getBits<24, 4>(blendControl);
|
||||
const u32 alphaDestFunc = getBits<28, 4>(blendControl);
|
||||
|
||||
const u32 constantColor = regs[PICAInternalRegs::BlendColour];
|
||||
const u32 constantColor = regs[PICA::InternalRegs::BlendColour];
|
||||
const u32 r = constantColor & 0xff;
|
||||
const u32 g = getBits<8, 8>(constantColor);
|
||||
const u32 b = getBits<16, 8>(constantColor);
|
||||
|
@ -264,7 +264,7 @@ void Renderer::setupBlending() {
|
|||
}
|
||||
}
|
||||
|
||||
void Renderer::drawVertices(PICAPrimType primType, std::span<const Vertex> vertices) {
|
||||
void Renderer::drawVertices(PICA::PrimType primType, std::span<const Vertex> vertices) {
|
||||
// The fourth type is meant to be "Geometry primitive". TODO: Find out what that is
|
||||
static constexpr std::array<OpenGL::Primitives, 4> primTypes = {
|
||||
OpenGL::Triangle, OpenGL::TriangleStrip, OpenGL::TriangleFan, OpenGL::Triangle
|
||||
|
@ -272,7 +272,7 @@ void Renderer::drawVertices(PICAPrimType primType, std::span<const Vertex> verti
|
|||
const auto primitiveTopology = primTypes[static_cast<usize>(primType)];
|
||||
|
||||
// Adjust alpha test if necessary
|
||||
const u32 alphaControl = regs[PICAInternalRegs::AlphaTestConfig];
|
||||
const u32 alphaControl = regs[PICA::InternalRegs::AlphaTestConfig];
|
||||
if (alphaControl != oldAlphaControl) {
|
||||
oldAlphaControl = alphaControl;
|
||||
glUniform1ui(alphaControlLoc, alphaControl);
|
||||
|
@ -282,7 +282,7 @@ void Renderer::drawVertices(PICAPrimType primType, std::span<const Vertex> verti
|
|||
OpenGL::Framebuffer poop = getColourFBO();
|
||||
poop.bind(OpenGL::DrawAndReadFramebuffer);
|
||||
|
||||
const u32 depthControl = regs[PICAInternalRegs::DepthAndColorMask];
|
||||
const u32 depthControl = regs[PICA::InternalRegs::DepthAndColorMask];
|
||||
const bool depthEnable = depthControl & 1;
|
||||
const bool depthWriteEnable = getBit<12>(depthControl);
|
||||
const int depthFunc = getBits<4, 3>(depthControl);
|
||||
|
@ -293,9 +293,9 @@ void Renderer::drawVertices(PICAPrimType primType, std::span<const Vertex> verti
|
|||
GL_NEVER, GL_ALWAYS, GL_EQUAL, GL_NOTEQUAL, GL_LESS, GL_LEQUAL, GL_GREATER, GL_GEQUAL
|
||||
};
|
||||
|
||||
const float depthScale = f24::fromRaw(regs[PICAInternalRegs::DepthScale] & 0xffffff).toFloat32();
|
||||
const float depthOffset = f24::fromRaw(regs[PICAInternalRegs::DepthOffset] & 0xffffff).toFloat32();
|
||||
const bool depthMapEnable = regs[PICAInternalRegs::DepthmapEnable] & 1;
|
||||
const float depthScale = f24::fromRaw(regs[PICA::InternalRegs::DepthScale] & 0xffffff).toFloat32();
|
||||
const float depthOffset = f24::fromRaw(regs[PICA::InternalRegs::DepthOffset] & 0xffffff).toFloat32();
|
||||
const bool depthMapEnable = regs[PICA::InternalRegs::DepthmapEnable] & 1;
|
||||
|
||||
// Update depth uniforms
|
||||
if (oldDepthScale != depthScale) {
|
||||
|
@ -328,15 +328,15 @@ void Renderer::drawVertices(PICAPrimType primType, std::span<const Vertex> verti
|
|||
}
|
||||
|
||||
// Update the texture unit configuration uniform if it changed
|
||||
const u32 texUnitConfig = regs[PICAInternalRegs::TexUnitCfg];
|
||||
const u32 texUnitConfig = regs[PICA::InternalRegs::TexUnitCfg];
|
||||
if (oldTexUnitConfig != texUnitConfig) {
|
||||
oldTexUnitConfig = texUnitConfig;
|
||||
glUniform1ui(texUnitConfigLoc, texUnitConfig);
|
||||
}
|
||||
|
||||
// TODO: Actually use this
|
||||
float viewportWidth = f24::fromRaw(regs[PICAInternalRegs::ViewportWidth] & 0xffffff).toFloat32() * 2.0;
|
||||
float viewportHeight = f24::fromRaw(regs[PICAInternalRegs::ViewportHeight] & 0xffffff).toFloat32() * 2.0;
|
||||
float viewportWidth = f24::fromRaw(regs[PICA::InternalRegs::ViewportWidth] & 0xffffff).toFloat32() * 2.0;
|
||||
float viewportHeight = f24::fromRaw(regs[PICA::InternalRegs::ViewportHeight] & 0xffffff).toFloat32() * 2.0;
|
||||
OpenGL::setViewport(viewportWidth, viewportHeight);
|
||||
|
||||
// Note: The code below must execute after we've bound the colour buffer & its framebuffer
|
||||
|
@ -429,8 +429,8 @@ void Renderer::bindDepthBuffer() {
|
|||
tex = depthBufferCache.add(sampleBuffer).texture.m_handle;
|
||||
}
|
||||
|
||||
if (PICADepthFmt::Depth24Stencil8 != depthBufferFormat) Helpers::panic("TODO: Should we remove stencil attachment?");
|
||||
auto attachment = depthBufferFormat == PICADepthFmt::Depth24Stencil8 ? GL_DEPTH_STENCIL_ATTACHMENT : GL_DEPTH_ATTACHMENT;
|
||||
if (PICA::DepthFmt::Depth24Stencil8 != depthBufferFormat) Helpers::panic("TODO: Should we remove stencil attachment?");
|
||||
auto attachment = depthBufferFormat == PICA::DepthFmt::Depth24Stencil8 ? GL_DEPTH_STENCIL_ATTACHMENT : GL_DEPTH_ATTACHMENT;
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, attachment, GL_TEXTURE_2D, tex, 0);
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue