Split the display layout config between landscape and portrait orientations

This commit is contained in:
Henrik Rydgård committed 2025-10-31 10:43:44 +01:00
1 parent 174d45279c
commit 4994246c8b
61 files changed
+482 -317

No files matched your search

+31 -26
View File
@@ -76,7 +76,7 @@ FramebufferManagerCommon::~FramebufferManagerCommon() {
void FramebufferManagerCommon::Init(int msaaLevel) {
// We may need to override the render size if the shader is upscaling or SSAA.
NotifyDisplayResized();
NotifyRenderResized(msaaLevel);
NotifyRenderResized(displayLayoutConfigCopy_, msaaLevel);
}
// Returns true if we need to stop the render thread
@@ -110,17 +110,20 @@ bool FramebufferManagerCommon::UpdateRenderSize(int msaaLevel) {
return newRender || newSettings;
}
void FramebufferManagerCommon::CheckPostShaders() {
void FramebufferManagerCommon::CheckPostShaders(const DisplayLayoutConfig &config) {
if (updatePostShaders_) {
presentation_->UpdatePostShader();
presentation_->UpdatePostShader(config);
updatePostShaders_ = false;
}
}
void FramebufferManagerCommon::BeginFrame() {
void FramebufferManagerCommon::BeginFrame(const DisplayLayoutConfig &config) {
DecimateFBOs();
presentation_->BeginFrame();
presentation_->BeginFrame(config);
currentRenderVfb_ = nullptr;
// Hack.
displayLayoutConfigCopy_ = config;
}
bool FramebufferManagerCommon::PresentedThisFrame() const {
@@ -647,7 +650,7 @@ void FramebufferManagerCommon::SetDepthFrameBuffer(bool isClearingDepth) {
// Sanity check the depth buffer pointer.
if (Memory::IsValidRange(currentRenderVfb_->z_address, currentRenderVfb_->width * 2)) {
const u16 *src = (const u16 *)Memory::GetPointerUnchecked(currentRenderVfb_->z_address);
DrawPixels(currentRenderVfb_, 0, 0, (const u8 *)src, GE_FORMAT_DEPTH16, currentRenderVfb_->z_stride, currentRenderVfb_->width, currentRenderVfb_->height, RASTER_DEPTH, "Depth Upload");
DrawPixels(nullptr, currentRenderVfb_, 0, 0, (const u8 *)src, GE_FORMAT_DEPTH16, currentRenderVfb_->z_stride, currentRenderVfb_->width, currentRenderVfb_->height, RASTER_DEPTH, "Depth Upload");
}
}
}
@@ -1172,7 +1175,7 @@ void FramebufferManagerCommon::UpdateFromMemory(u32 addr, int size) {
// TODO: This doesn't seem quite right anymore.
fmt = displayFormat_;
}
DrawPixels(vfb, 0, 0, Memory::GetPointerUnchecked(addr), fmt, vfb->fb_stride, vfb->width, vfb->height, RASTER_COLOR, "UpdateFromMemory_DrawPixels");
DrawPixels(nullptr, vfb, 0, 0, Memory::GetPointerUnchecked(addr), fmt, vfb->fb_stride, vfb->width, vfb->height, RASTER_COLOR, "UpdateFromMemory_DrawPixels");
SetColorUpdated(vfb, gstate_c.skipDrawReason);
} else {
INFO_LOG(Log::FrameBuf, "Invalidating FBO for %08x (%dx%d %s)", vfb->fb_address, vfb->width, vfb->height, GeBufferFormatToString(vfb->fb_format));
@@ -1188,7 +1191,7 @@ void FramebufferManagerCommon::UpdateFromMemory(u32 addr, int size) {
gstate_c.Dirty(DIRTY_FRAGMENTSHADER_STATE);
}
void FramebufferManagerCommon::DrawPixels(VirtualFramebuffer *vfb, int dstX, int dstY, const u8 *srcPixels, GEBufferFormat srcPixelFormat, int srcStride, int width, int height, RasterChannel channel, const char *tag) {
void FramebufferManagerCommon::DrawPixels(const DisplayLayoutConfig *config, VirtualFramebuffer *vfb, int dstX, int dstY, const u8 *srcPixels, GEBufferFormat srcPixelFormat, int srcStride, int width, int height, RasterChannel channel, const char *tag) {
textureCache_->ForgetLastTexture();
shaderManager_->DirtyLastShader();
float u0 = 0.0f, u1 = 1.0f;
@@ -1206,15 +1209,16 @@ void FramebufferManagerCommon::DrawPixels(VirtualFramebuffer *vfb, int dstX, int
draw_->SetScissorRect(0, 0, vfb->renderWidth, vfb->renderHeight);
} else {
_dbg_assert_(channel == RASTER_COLOR);
_dbg_assert_(config);
// We are drawing directly to the back buffer so need to flip.
// Should more of this be handled by the presentation engine?
if (needBackBufferYSwap_)
std::swap(v0, v1);
flags = g_Config.iDisplayFilter == SCALE_LINEAR ? DRAWTEX_LINEAR : DRAWTEX_NEAREST;
flags = config->iDisplayFilter == SCALE_LINEAR ? DRAWTEX_LINEAR : DRAWTEX_NEAREST;
flags = flags | DRAWTEX_TO_BACKBUFFER;
FRect frame = GetScreenFrame(pixelWidth_, pixelHeight_);
FRect frame = GetScreenFrame(config ? config->bIgnoreScreenInsets : false, pixelWidth_, pixelHeight_);
FRect rc;
CalculateDisplayOutputRect(&rc, 480.0f, 272.0f, frame, ROTATION_LOCKED_HORIZONTAL);
CalculateDisplayOutputRect(*config, &rc, 480.0f, 272.0f, frame, ROTATION_LOCKED_HORIZONTAL);
SetViewport2D(rc.x, rc.y, rc.w, rc.h);
draw_->SetScissorRect(0, 0, pixelWidth_, pixelHeight_);
}
@@ -1512,7 +1516,7 @@ Draw::Texture *FramebufferManagerCommon::MakePixelTexture(const u8 *srcPixels, G
return tex;
}
bool FramebufferManagerCommon::DrawFramebufferToOutput(const u8 *srcPixels, int srcStride, GEBufferFormat srcPixelFormat) {
bool FramebufferManagerCommon::DrawFramebufferToOutput(const DisplayLayoutConfig &config, const u8 *srcPixels, int srcStride, GEBufferFormat srcPixelFormat) {
textureCache_->ForgetLastTexture();
shaderManager_->DirtyLastShader();
@@ -1522,8 +1526,8 @@ bool FramebufferManagerCommon::DrawFramebufferToOutput(const u8 *srcPixels, int
if (!pixelsTex)
return false;
int uvRotation = useBufferedRendering_ ? g_Config.iInternalScreenRotation : ROTATION_LOCKED_HORIZONTAL;
OutputFlags flags = g_Config.iDisplayFilter == SCALE_LINEAR ? OutputFlags::LINEAR : OutputFlags::NEAREST;
int uvRotation = useBufferedRendering_ ? config.iInternalScreenRotation : ROTATION_LOCKED_HORIZONTAL;
OutputFlags flags = config.iDisplayFilter == SCALE_LINEAR ? OutputFlags::LINEAR : OutputFlags::NEAREST;
if (needBackBufferYSwap_) {
flags |= OutputFlags::BACKBUFFER_FLIPPED;
}
@@ -1534,7 +1538,7 @@ bool FramebufferManagerCommon::DrawFramebufferToOutput(const u8 *srcPixels, int
presentation_->UpdateUniforms(textureCache_->VideoIsPlaying());
presentation_->SourceTexture(pixelsTex, 512, 272);
presentation_->CopyToOutput(flags, uvRotation, u0, v0, u1, v1);
presentation_->CopyToOutput(config, flags, uvRotation, u0, v0, u1, v1);
// PresentationCommon sets all kinds of state, we can't rely on anything.
gstate_c.Dirty(DIRTY_ALL);
@@ -1550,7 +1554,7 @@ void FramebufferManagerCommon::SetViewport2D(int x, int y, int w, int h) {
draw_->SetViewport(viewport);
}
void FramebufferManagerCommon::CopyDisplayToOutput(bool reallyDirty) {
void FramebufferManagerCommon::CopyDisplayToOutput(const DisplayLayoutConfig &config, bool reallyDirty) {
DownloadFramebufferOnSwitch(currentRenderVfb_);
shaderManager_->DirtyLastShader();
@@ -1625,7 +1629,7 @@ void FramebufferManagerCommon::CopyDisplayToOutput(bool reallyDirty) {
if (Memory::IsValidAddress(fbaddr)) {
// The game is displaying something directly from RAM. In GTA, it's decoded video.
// If successful, this effectively calls presentation_->NotifyPresent();
if (!DrawFramebufferToOutput(Memory::GetPointerUnchecked(fbaddr), displayStride_, displayFormat_)) {
if (!DrawFramebufferToOutput(config, Memory::GetPointerUnchecked(fbaddr), displayStride_, displayFormat_)) {
if (useBufferedRendering_) {
// Bind and clear the backbuffer. This should be the first time during the frame that it's bound.
draw_->BindFramebufferAsRenderTarget(nullptr, { Draw::RPAction::CLEAR, Draw::RPAction::CLEAR, Draw::RPAction::CLEAR }, "CopyDisplayToOutput_DrawError");
@@ -1689,8 +1693,8 @@ void FramebufferManagerCommon::CopyDisplayToOutput(bool reallyDirty) {
textureCache_->ForgetLastTexture();
int uvRotation = useBufferedRendering_ ? g_Config.iInternalScreenRotation : ROTATION_LOCKED_HORIZONTAL;
OutputFlags flags = g_Config.iDisplayFilter == SCALE_LINEAR ? OutputFlags::LINEAR : OutputFlags::NEAREST;
int uvRotation = useBufferedRendering_ ? config.iInternalScreenRotation : ROTATION_LOCKED_HORIZONTAL;
OutputFlags flags = config.iDisplayFilter == SCALE_LINEAR ? OutputFlags::LINEAR : OutputFlags::NEAREST;
if (needBackBufferYSwap_) {
flags |= OutputFlags::BACKBUFFER_FLIPPED;
}
@@ -1703,7 +1707,7 @@ void FramebufferManagerCommon::CopyDisplayToOutput(bool reallyDirty) {
int actualHeight = (vfb->bufferHeight * vfb->renderHeight) / vfb->height;
presentation_->UpdateUniforms(textureCache_->VideoIsPlaying());
presentation_->SourceFramebuffer(vfb->fbo, actualWidth, actualHeight);
presentation_->CopyToOutput(flags, uvRotation, u0, v0, u1, v1);
presentation_->CopyToOutput(config, flags, uvRotation, u0, v0, u1, v1);
} else if (useBufferedRendering_) {
WARN_LOG(Log::FrameBuf, "Using buffered rendering, and current VFB lacks an FBO: %08x", vfb->fb_address);
} else {
@@ -2179,7 +2183,7 @@ bool FramebufferManagerCommon::NotifyFramebufferCopy(u32 src, u32 dst, int size,
const u8 *srcBase = Memory::GetPointerUnchecked(src);
GEBufferFormat srcFormat = channel == RASTER_DEPTH ? GE_FORMAT_DEPTH16 : dstBuffer->fb_format;
int srcStride = channel == RASTER_DEPTH ? dstBuffer->z_stride : dstBuffer->fb_stride;
DrawPixels(dstBuffer, 0, dstY, srcBase, srcFormat, srcStride, dstBuffer->width, dstH, channel, "MemcpyFboUpload_DrawPixels");
DrawPixels(nullptr, dstBuffer, 0, dstY, srcBase, srcFormat, srcStride, dstBuffer->width, dstH, channel, "MemcpyFboUpload_DrawPixels");
SetColorUpdated(dstBuffer, skipDrawReason);
RebindFramebuffer("RebindFramebuffer - Memcpy fbo upload");
// This is a memcpy, let's still copy just in case.
@@ -2711,7 +2715,7 @@ bool FramebufferManagerCommon::NotifyBlockTransferBefore(u32 dstBasePtr, int dst
WARN_LOG_ONCE(btud, Log::G3D, "Block transfer upload %08x -> %08x (%dx%d %d,%d bpp=%d %s)", srcBasePtr, dstBasePtr, width, height, dstX, dstY, bpp, RasterChannelToString(dstRect.channel));
FlushBeforeCopy();
const u8 *srcBase = Memory::GetPointerUnchecked(srcBasePtr) + (srcX + srcY * srcStride) * bpp;
DrawPixels(dstRect.vfb, dstX, dstY, srcBase, dstRect.vfb->Format(dstRect.channel), srcStride * bpp / 2, (int)(dstRect.w_bytes / 2), dstRect.h, dstRect.channel, "BlockTransferCopy_DrawPixelsDepth");
DrawPixels(nullptr, dstRect.vfb, dstX, dstY, srcBase, dstRect.vfb->Format(dstRect.channel), srcStride * bpp / 2, (int)(dstRect.w_bytes / 2), dstRect.h, dstRect.channel, "BlockTransferCopy_DrawPixelsDepth");
RebindFramebuffer("RebindFramebuffer - UploadDepth");
return true;
}
@@ -2765,7 +2769,8 @@ void FramebufferManagerCommon::NotifyBlockTransferAfter(u32 dstBasePtr, int dstS
bool isDisplayBuffer = CurrentDisplayFramebufAddr() == dstBasePtr;
if (isPrevDisplayBuffer || isDisplayBuffer) {
FlushBeforeCopy();
DrawFramebufferToOutput(Memory::GetPointerUnchecked(dstBasePtr), dstStride, displayFormat_);
// HACK
DrawFramebufferToOutput(displayLayoutConfigCopy_, Memory::GetPointerUnchecked(dstBasePtr), dstStride, displayFormat_);
return;
}
}
@@ -2805,7 +2810,7 @@ void FramebufferManagerCommon::NotifyBlockTransferAfter(u32 dstBasePtr, int dstS
// Resizing may change the viewport/etc.
gstate_c.Dirty(DIRTY_VIEWPORTSCISSOR_STATE | DIRTY_CULLRANGE);
}
DrawPixels(dstRect.vfb, static_cast<int>(dstX * dstXFactor), dstY, srcBase, dstRect.vfb->fb_format, static_cast<int>(srcStride * dstXFactor), static_cast<int>(dstRect.w_bytes / bpp * dstXFactor), dstRect.h, RASTER_COLOR, "BlockTransferCopy_DrawPixels");
DrawPixels(nullptr, dstRect.vfb, static_cast<int>(dstX * dstXFactor), dstY, srcBase, dstRect.vfb->fb_format, static_cast<int>(srcStride * dstXFactor), static_cast<int>(dstRect.w_bytes / bpp * dstXFactor), dstRect.h, RASTER_COLOR, "BlockTransferCopy_DrawPixels");
SetColorUpdated(dstRect.vfb, skipDrawReason);
RebindFramebuffer("RebindFramebuffer - NotifyBlockTransferAfter");
}
@@ -2832,11 +2837,11 @@ void FramebufferManagerCommon::NotifyDisplayResized() {
updatePostShaders_ = true;
}
void FramebufferManagerCommon::NotifyRenderResized(int msaaLevel) {
void FramebufferManagerCommon::NotifyRenderResized(const DisplayLayoutConfig &config, int msaaLevel) {
gstate_c.skipDrawReason &= ~SKIPDRAW_NON_DISPLAYED_FB;
int w, h, scaleFactor;
presentation_->CalculateRenderResolution(&w, &h, &scaleFactor, &postShaderIsUpscalingFilter_, &postShaderIsSupersampling_);
presentation_->CalculateRenderResolution(config, &w, &h, &scaleFactor, &postShaderIsUpscalingFilter_, &postShaderIsSupersampling_);
PSP_CoreParameter().renderWidth = w;
PSP_CoreParameter().renderHeight = h;
PSP_CoreParameter().renderScaleFactor = scaleFactor;