Add PICA texel-format and topology types

Slowly stepping the codebase towards having renderer-agnostic types and keeping the translation of PICA-types to OpenGL/VK/DX/Software/etc to the renderer-backend.
This commit is contained in:
Wunkolo 2023-06-17 11:59:45 -07:00
parent d0ae5f0546
commit 78a3f9fa23
6 changed files with 85 additions and 76 deletions

View file

@ -55,11 +55,12 @@ void GPU::drawArrays() {
// Configures the type of primitive and the number of vertex shader outputs
const u32 primConfig = regs[PICAInternalRegs::PrimitiveConfig];
const u32 primType = Helpers::getBits<8, 2>(primConfig);
if (primType != 0 && primType != 1 && primType != 3) Helpers::panic("[PICA] Tried to draw unimplemented shape %d\n", primType);
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);
if (vertexCount > Renderer::vertexBufferSize) Helpers::panic("[PICA] vertexCount > vertexBufferSize");
if ((primType == 0 && vertexCount % 3) || (primType == 1 && vertexCount < 3)) {
if ((primType == PICAPrimType::TriangleList && vertexCount % 3) ||
(primType == PICAPrimType::TriangleStrip && vertexCount < 3)) {
Helpers::panic("Invalid vertex count for primitive. Type: %d, vert count: %d\n", primType, vertexCount);
}
@ -203,12 +204,7 @@ void GPU::drawArrays() {
//printf("(u, v ) = (%f, %f)\n", vertices[i].UVs.u(), vertices[i].UVs.v());
}
// 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
};
const auto shape = primTypes[primType];
renderer.drawVertices(shape, std::span(vertices).first(vertexCount));
renderer.drawVertices(primType, std::span(vertices).first(vertexCount));
}
Vertex GPU::getImmediateModeVertex() {

View file

@ -68,7 +68,7 @@ void GPU::writeInternalReg(u32 index, u32 value, u32 mask) {
case ColourBufferFormat: {
u32 format = getBits<16, 3>(value);
renderer.setColourFormat(format);
renderer.setColourFormat(static_cast<PICAColorFmt>(format));
break;
}
@ -79,8 +79,8 @@ void GPU::writeInternalReg(u32 index, u32 value, u32 mask) {
}
case DepthBufferFormat: {
u32 fmt = value & 0x3;
renderer.setDepthFormat(fmt);
u32 format = value & 0x3;
renderer.setDepthFormat(static_cast<PICADepthFmt>(format));
break;
}
@ -157,7 +157,7 @@ void GPU::writeInternalReg(u32 index, u32 value, u32 mask) {
// If we've reached 3 verts, issue a draw call
// Handle rendering depending on the primitive type
if (immediateModeVertIndex == 3) {
renderer.drawVertices(OpenGL::Triangle, immediateModeVertices);
renderer.drawVertices(PICAPrimType::TriangleList, immediateModeVertices);
switch (primType) {
// Triangle or geometry primitive. Draw a triangle and discard all vertices

View file

@ -144,10 +144,10 @@ void Renderer::reset() {
// Init the colour/depth buffer settings to some random defaults on reset
colourBufferLoc = 0;
colourBufferFormat = ColourBuffer::Formats::RGBA8;
colourBufferFormat = PICAColorFmt::RGBA8;
depthBufferLoc = 0;
depthBufferFormat = DepthBuffer::Formats::Depth16;
depthBufferFormat = PICADepthFmt::Depth16;
if (triangleProgram.exists()) {
const auto oldProgram = OpenGL::getProgram();
@ -264,7 +264,13 @@ void Renderer::setupBlending() {
}
}
void Renderer::drawVertices(OpenGL::Primitives primType, std::span<const Vertex> vertices) {
void Renderer::drawVertices(PICAPrimType 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
};
const auto primitiveTopology = primTypes[static_cast<usize>(primType)];
// Adjust alpha test if necessary
const u32 alphaControl = regs[PICAInternalRegs::AlphaTestConfig];
if (alphaControl != oldAlphaControl) {
@ -352,7 +358,7 @@ void Renderer::drawVertices(OpenGL::Primitives primType, std::span<const Vertex>
}
vbo.bufferVertsSub(vertices);
OpenGL::draw(primType, vertices.size());
OpenGL::draw(primitiveTopology, vertices.size());
}
constexpr u32 topScreenBuffer = 0x1f000000;
@ -423,8 +429,8 @@ void Renderer::bindDepthBuffer() {
tex = depthBufferCache.add(sampleBuffer).texture.m_handle;
}
if (DepthBuffer::Formats::Depth24Stencil8 != depthBufferFormat) Helpers::panic("TODO: Should we remove stencil attachment?");
auto attachment = depthBufferFormat == DepthBuffer::Formats::Depth24Stencil8 ? GL_DEPTH_STENCIL_ATTACHMENT : GL_DEPTH_ATTACHMENT;
if (PICADepthFmt::Depth24Stencil8 != depthBufferFormat) Helpers::panic("TODO: Should we remove stencil attachment?");
auto attachment = depthBufferFormat == PICADepthFmt::Depth24Stencil8 ? GL_DEPTH_STENCIL_ATTACHMENT : GL_DEPTH_ATTACHMENT;
glFramebufferTexture2D(GL_FRAMEBUFFER, attachment, GL_TEXTURE_2D, tex, 0);
}