diff --git a/include/PICA/regs.hpp b/include/PICA/regs.hpp index 55b3e20b..70cecf7b 100644 --- a/include/PICA/regs.hpp +++ b/include/PICA/regs.hpp @@ -22,6 +22,7 @@ namespace PICA { ShaderOutputCount = 0x4F, ShaderOutmap0 = 0x50, + ViewportXY = 0x68, DepthmapEnable = 0x6D, // Texture registers diff --git a/src/core/renderer_gl/renderer_gl.cpp b/src/core/renderer_gl/renderer_gl.cpp index e99e3196..8b2c31bb 100644 --- a/src/core/renderer_gl/renderer_gl.cpp +++ b/src/core/renderer_gl/renderer_gl.cpp @@ -369,8 +369,8 @@ void RendererGL::drawVertices(PICA::PrimType primType, std::span v } setupBlending(); - OpenGL::Framebuffer poop = getColourFBO(); - poop.bind(OpenGL::DrawAndReadFramebuffer); + auto poop = getColourBuffer(colourBufferLoc, colourBufferFormat, fbSize[0], fbSize[1]); + poop->fbo.bind(OpenGL::DrawAndReadFramebuffer); const u32 depthControl = regs[PICA::InternalRegs::DepthAndColorMask]; const bool depthWrite = regs[PICA::InternalRegs::DepthBufferWrite]; @@ -413,10 +413,12 @@ void RendererGL::drawVertices(PICA::PrimType primType, std::span v updateLightingLUT(); } - // TODO: Actually use this - GLsizei viewportWidth = GLsizei(f24::fromRaw(regs[PICA::InternalRegs::ViewportWidth] & 0xffffff).toFloat32() * 2.0f); - GLsizei viewportHeight = GLsizei(f24::fromRaw(regs[PICA::InternalRegs::ViewportHeight] & 0xffffff).toFloat32() * 2.0f); - OpenGL::setViewport(viewportWidth, viewportHeight); + const GLsizei viewportX = regs[PICA::InternalRegs::ViewportXY] & 0x3ff; + const GLsizei viewportY = (regs[PICA::InternalRegs::ViewportXY] >> 16) & 0x3ff; + const GLsizei viewportWidth = GLsizei(f24::fromRaw(regs[PICA::InternalRegs::ViewportWidth] & 0xffffff).toFloat32() * 2.0f); + const GLsizei viewportHeight = GLsizei(f24::fromRaw(regs[PICA::InternalRegs::ViewportHeight] & 0xffffff).toFloat32() * 2.0f); + const auto rect = poop->getSubRect(colourBufferLoc, fbSize[0], fbSize[1]); + OpenGL::setViewport(rect.left + viewportX, rect.bottom + viewportY, viewportWidth, viewportHeight); const u32 stencilConfig = regs[PICA::InternalRegs::StencilTest]; const bool stencilEnable = getBit<0>(stencilConfig); @@ -598,17 +600,22 @@ void RendererGL::displayTransfer(u32 inputAddr, u32 outputAddr, u32 inputSize, u const u32 inputHeight = inputSize >> 16; const auto inputFormat = ToColorFmt(Helpers::getBits<8, 3>(flags)); const auto outputFormat = ToColorFmt(Helpers::getBits<12, 3>(flags)); + const bool verticalFlip = flags & 1; const PICA::Scaling scaling = static_cast(Helpers::getBits<24, 2>(flags)); u32 outputWidth = outputSize & 0xffff; u32 outputHeight = outputSize >> 16; - OpenGL::DebugScope scope("DisplayTransfer inputAddr 0x%08X outputAddr 0x%08X inputWidth %d outputWidth %d inputWidth %d outputHeight %d", + OpenGL::DebugScope scope("DisplayTransfer inputAddr 0x%08X outputAddr 0x%08X inputWidth %d outputWidth %d inputHeight %d outputHeight %d", inputAddr, outputAddr, inputWidth, outputWidth, inputHeight, outputHeight); auto srcFramebuffer = getColourBuffer(inputAddr, inputFormat, inputWidth, outputHeight); Math::Rect srcRect = srcFramebuffer->getSubRect(inputAddr, outputWidth, outputHeight); + if (verticalFlip) { + std::swap(srcRect.bottom, srcRect.top); + } + // Apply scaling for the destination rectangle. if (scaling == PICA::Scaling::X || scaling == PICA::Scaling::XY) { outputWidth >>= 1; @@ -628,8 +635,10 @@ void RendererGL::displayTransfer(u32 inputAddr, u32 outputAddr, u32 inputSize, u // Blit the framebuffers srcFramebuffer->fbo.bind(OpenGL::ReadFramebuffer); destFramebuffer->fbo.bind(OpenGL::DrawFramebuffer); + gl.disableScissor(); + glBlitFramebuffer( - srcRect.left, srcRect.top, srcRect.right, srcRect.bottom, destRect.left, destRect.top, destRect.right, destRect.bottom, GL_COLOR_BUFFER_BIT, + srcRect.left, srcRect.bottom, srcRect.right, srcRect.top, destRect.left, destRect.bottom, destRect.right, destRect.top, GL_COLOR_BUFFER_BIT, GL_LINEAR ); } @@ -652,10 +661,10 @@ void RendererGL::textureCopy(u32 inputAddr, u32 outputAddr, u32 totalBytes, u32 inputAddr, outputAddr, totalBytes, inputWidth, inputGap, outputWidth, outputGap); if (inputGap != 0 || outputGap != 0) { - Helpers::warn("Strided texture copy\n"); + //Helpers::warn("Strided texture copy\n"); } if (inputWidth != outputWidth) { - Helpers::warn("Input width does not match output width, cannot accelerate texture copy!\n"); + Helpers::warn("Input width does not match output width, cannot accelerate texture copy!"); return; } @@ -694,8 +703,10 @@ void RendererGL::textureCopy(u32 inputAddr, u32 outputAddr, u32 totalBytes, u32 // Blit the framebuffers srcFramebuffer->fbo.bind(OpenGL::ReadFramebuffer); destFramebuffer->fbo.bind(OpenGL::DrawFramebuffer); + gl.disableScissor(); + glBlitFramebuffer( - srcRect.left, srcRect.top, srcRect.right, srcRect.bottom, destRect.left, destRect.top, destRect.right, destRect.bottom, GL_COLOR_BUFFER_BIT, + srcRect.left, srcRect.bottom, srcRect.right, srcRect.top, destRect.left, destRect.bottom, destRect.right, destRect.top, GL_COLOR_BUFFER_BIT, GL_LINEAR ); }