GPU: Draw frames displayed from RAM in non-buffered mode

They were uploaded but never drawn, and the block transfer hack drew
whatever source was left over. Draw them straight into the backbuffer
pass, without post shaders, which would need to bind their own targets.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Henrik RydgårdandClaude Opus 5.5 committed 2026-09-29 13:17:01 -06:00
1 parent 4bfa4e14ec
commit b8789af997
3 files changed
+13 -9

No files matched your search

+10 -7
View File
@@ -1557,14 +1557,19 @@ bool FramebufferManagerCommon::DrawFramebufferToOutput(const DisplayLayoutConfig
if (needBackBufferYSwap_) {
flags |= OutputFlags::BACKBUFFER_FLIPPED;
}
if (!useBufferedRendering_) {
// We're inside the backbuffer pass, where nothing else will draw this image.
flags |= OutputFlags::NO_POST_SHADER;
}
constexpr float u0 = 0.0f, u1 = 1.0f;
constexpr float v0 = 0.0f, v1 = 1.0f;
if (useBufferedRendering_) {
presentation_->UpdateUniforms(gpu->VideoIsPlaying());
presentation_->SourceTexture(pixelsTex, 480, 272);
presentation_->RunPostshaderPasses(config, flags, uvRotation, u0, v0, u1, v1);
presentation_->UpdateUniforms(gpu->VideoIsPlaying());
presentation_->SourceTexture(pixelsTex, 480, 272);
presentation_->RunPostshaderPasses(config, flags, uvRotation, u0, v0, u1, v1);
if (!useBufferedRendering_) {
presentation_->CopyToOutput(config);
}
// PresentationCommon sets all kinds of state, we can't rely on anything.
@@ -2863,9 +2868,7 @@ void FramebufferManagerCommon::NotifyBlockTransferAfter(u32 dstBasePtr, int dstS
if (isPrevDisplayBuffer || isDisplayBuffer) {
FlushBeforeCopy();
// HACK
if (DrawFramebufferToOutput(displayLayoutConfigCopy_, Memory::GetPointerUnchecked(dstBasePtr), dstStride, displayFormat_)) {
presentation_->CopyToOutput(displayLayoutConfigCopy_);
}
DrawFramebufferToOutput(displayLayoutConfigCopy_, Memory::GetPointerUnchecked(dstBasePtr), dstStride, displayFormat_);
return;
}
}
+2 -2
View File
@@ -680,7 +680,7 @@ void PresentationCommon::RunPostshaderPasses(const DisplayLayoutConfig &config,
bool useNearest = flags & OutputFlags::NEAREST;
bool useStereo = gstate_c.Use(GPU_USE_SIMPLE_STEREO_PERSPECTIVE) && stereoPipeline_ != nullptr; // TODO: Also check that the backend has support for it.
const bool usePostShader = usePostShader_ && !useStereo && !(flags & OutputFlags::RB_SWIZZLE);
const bool usePostShader = usePostShader_ && !useStereo && !(flags & (OutputFlags::RB_SWIZZLE | OutputFlags::NO_POST_SHADER));
const bool isFinalAtOutputResolution = usePostShader && postShaderFramebuffers_.size() < postShaderPipelines_.size();
int lastWidth = srcWidth_;
int lastHeight = srcHeight_;
@@ -897,7 +897,7 @@ void PresentationCommon::CopyToOutput(const DisplayLayoutConfig &config) {
bool useNearest = outputFlags_ & OutputFlags::NEAREST;
bool useStereo = gstate_c.Use(GPU_USE_SIMPLE_STEREO_PERSPECTIVE) && stereoPipeline_ != nullptr; // TODO: Also check that the backend has support for it.
const bool usePostShader = usePostShader_ && !useStereo && !(outputFlags_ & OutputFlags::RB_SWIZZLE);
const bool usePostShader = usePostShader_ && !useStereo && !(outputFlags_ & (OutputFlags::RB_SWIZZLE | OutputFlags::NO_POST_SHADER));
const bool isFinalAtOutputResolution = usePostShader && postShaderFramebuffers_.size() < postShaderPipelines_.size();
int lastWidth = srcWidth_;
int lastHeight = srcHeight_;
+1
View File
@@ -75,6 +75,7 @@ enum class OutputFlags {
RB_SWIZZLE = 0x0002,
BACKBUFFER_FLIPPED = 0x0004, // Viewport/scissor coordinates are y-flipped.
PILLARBOX = 0x0010, // Squeeze the image horizontally. Used for the DarkStalkers hack.
NO_POST_SHADER = 0x0020, // Draw straight to the bound target, as post shaders would need to bind their own.
};
ENUM_CLASS_BITOPS(OutputFlags);