Skip to content

Commit

Permalink
Merge pull request #12665 from unknownbrackets/frameskip
Browse files Browse the repository at this point in the history
GPU: Use old frame when presenting a skip
  • Loading branch information
hrydgard authored Mar 1, 2020
2 parents 63f06cd + cebcfb1 commit c363c16
Show file tree
Hide file tree
Showing 17 changed files with 31 additions and 26 deletions.
2 changes: 1 addition & 1 deletion Core/HLE/sceDisplay.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -781,7 +781,7 @@ void __DisplayFlip(int cyclesLate) {
// Check first though, might've just quit / been paused.
if (coreState == CORE_RUNNING) {
coreState = CORE_NEXTFRAME;
gpu->CopyDisplayToOutput();
gpu->CopyDisplayToOutput(fbReallyDirty);
if (fbReallyDirty) {
actualFlips++;
}
Expand Down
16 changes: 10 additions & 6 deletions GPU/Common/FramebufferCommon.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -846,7 +846,7 @@ void FramebufferManagerCommon::SetViewport2D(int x, int y, int w, int h) {
draw_->SetViewports(1, &vp);
}

void FramebufferManagerCommon::CopyDisplayToOutput() {
void FramebufferManagerCommon::CopyDisplayToOutput(bool reallyDirty) {
DownloadFramebufferOnSwitch(currentRenderVfb_);
shaderManager_->DirtyLastShader();

Expand All @@ -869,12 +869,16 @@ void FramebufferManagerCommon::CopyDisplayToOutput() {
CardboardSettings cardboardSettings;
GetCardboardSettings(&cardboardSettings);

VirtualFramebuffer *vfb = GetVFBAt(displayFramebufPtr_);
// If it's not really dirty, we're probably frameskipping. Use the last working one.
u32 fbaddr = reallyDirty ? displayFramebufPtr_ : prevDisplayFramebufPtr_;
prevDisplayFramebufPtr_ = fbaddr;

VirtualFramebuffer *vfb = GetVFBAt(fbaddr);
if (!vfb) {
// Let's search for a framebuf within this range. Note that we also look for
// "framebuffers" sitting in RAM (created from block transfer or similar) so we only take off the kernel
// and uncached bits of the address when comparing.
const u32 addr = displayFramebufPtr_ & 0x3FFFFFFF;
const u32 addr = fbaddr & 0x3FFFFFFF;
for (size_t i = 0; i < vfbs_.size(); ++i) {
VirtualFramebuffer *v = vfbs_[i];
const u32 v_addr = v->fb_address & 0x3FFFFFFF;
Expand Down Expand Up @@ -912,7 +916,7 @@ void FramebufferManagerCommon::CopyDisplayToOutput() {
}

if (!vfb) {
if (Memory::IsValidAddress(displayFramebufPtr_)) {
if (Memory::IsValidAddress(fbaddr)) {
// The game is displaying something directly from RAM. In GTA, it's decoded video.
if (!vfb) {
shaderManager_->DirtyLastShader();
Expand All @@ -923,12 +927,12 @@ void FramebufferManagerCommon::CopyDisplayToOutput() {
// Just a pointer to plain memory to draw. We should create a framebuffer, then draw to it.
SetViewport2D(0, 0, pixelWidth_, pixelHeight_);
draw_->SetScissorRect(0, 0, pixelWidth_, pixelHeight_);
DrawFramebufferToOutput(Memory::GetPointer(displayFramebufPtr_), displayFormat_, displayStride_, true);
DrawFramebufferToOutput(Memory::GetPointer(fbaddr), displayFormat_, displayStride_, true);
gstate_c.Dirty(DIRTY_BLEND_STATE);
return;
}
} else {
DEBUG_LOG(FRAMEBUF, "Found no FBO to display! displayFBPtr = %08x", displayFramebufPtr_);
DEBUG_LOG(FRAMEBUF, "Found no FBO to display! displayFBPtr = %08x", fbaddr);
// No framebuffer to display! Clear to black.
if (useBufferedRendering_) {
shaderManager_->DirtyLastShader();
Expand Down
3 changes: 2 additions & 1 deletion GPU/Common/FramebufferCommon.h
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,7 @@ class FramebufferManagerCommon {
void RebindFramebuffer();
std::vector<FramebufferInfo> GetFramebufferList();

void CopyDisplayToOutput();
void CopyDisplayToOutput(bool reallyDirty);

bool NotifyFramebufferCopy(u32 src, u32 dest, int size, bool isMemset, u32 skipDrawReason);
void NotifyVideoUpload(u32 addr, int size, int width, GEBufferFormat fmt);
Expand Down Expand Up @@ -383,6 +383,7 @@ class FramebufferManagerCommon {
u32 displayFramebufPtr_ = 0;
u32 displayStride_ = 0;
GEBufferFormat displayFormat_;
u32 prevDisplayFramebufPtr_ = 0;

VirtualFramebuffer *displayFramebuf_ = nullptr;
VirtualFramebuffer *prevDisplayFramebuf_ = nullptr;
Expand Down
4 changes: 2 additions & 2 deletions GPU/D3D11/GPU_D3D11.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -262,13 +262,13 @@ void GPU_D3D11::SetDisplayFramebuffer(u32 framebuf, u32 stride, GEBufferFormat f
framebufferManagerD3D11_->SetDisplayFramebuffer(framebuf, stride, format);
}

void GPU_D3D11::CopyDisplayToOutput() {
void GPU_D3D11::CopyDisplayToOutput(bool reallyDirty) {
float blendColor[4]{};
context_->OMSetBlendState(stockD3D11.blendStateDisabledWithColorMask[0xF], blendColor, 0xFFFFFFFF);

drawEngine_.Flush();

framebufferManagerD3D11_->CopyDisplayToOutput();
framebufferManagerD3D11_->CopyDisplayToOutput(reallyDirty);
framebufferManagerD3D11_->EndFrame();

// shaderManager_->EndFrame();
Expand Down
2 changes: 1 addition & 1 deletion GPU/D3D11/GPU_D3D11.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ class GPU_D3D11 : public GPUCommon {

void InitClear() override;
void BeginFrame() override;
void CopyDisplayToOutput() override;
void CopyDisplayToOutput(bool reallyDirty) override;

ID3D11Device *device_;
ID3D11DeviceContext *context_;
Expand Down
4 changes: 2 additions & 2 deletions GPU/Directx9/GPU_DX9.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -299,13 +299,13 @@ void GPU_DX9::SetDisplayFramebuffer(u32 framebuf, u32 stride, GEBufferFormat for
framebufferManagerDX9_->SetDisplayFramebuffer(framebuf, stride, format);
}

void GPU_DX9::CopyDisplayToOutput() {
void GPU_DX9::CopyDisplayToOutput(bool reallyDirty) {
dxstate.depthWrite.set(true);
dxstate.colorMask.set(true, true, true, true);

drawEngine_.Flush();

framebufferManagerDX9_->CopyDisplayToOutput();
framebufferManagerDX9_->CopyDisplayToOutput(reallyDirty);
framebufferManagerDX9_->EndFrame();

// shaderManager_->EndFrame();
Expand Down
2 changes: 1 addition & 1 deletion GPU/Directx9/GPU_DX9.h
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ class GPU_DX9 : public GPUCommon {

void InitClear() override;
void BeginFrame() override;
void CopyDisplayToOutput() override;
void CopyDisplayToOutput(bool reallyDirty) override;

LPDIRECT3DDEVICE9 device_;
LPDIRECT3DDEVICE9EX deviceEx_;
Expand Down
4 changes: 2 additions & 2 deletions GPU/GLES/GPU_GLES.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -400,14 +400,14 @@ void GPU_GLES::SetDisplayFramebuffer(u32 framebuf, u32 stride, GEBufferFormat fo
framebufferManagerGL_->SetDisplayFramebuffer(framebuf, stride, format);
}

void GPU_GLES::CopyDisplayToOutput() {
void GPU_GLES::CopyDisplayToOutput(bool reallyDirty) {
// Flush anything left over.
framebufferManagerGL_->RebindFramebuffer();
drawEngine_.Flush();

shaderManagerGL_->DirtyLastShader();

framebufferManagerGL_->CopyDisplayToOutput();
framebufferManagerGL_->CopyDisplayToOutput(reallyDirty);
framebufferManagerGL_->EndFrame();

// If buffered, discard the depth buffer of the backbuffer. Don't even know if we need one.
Expand Down
2 changes: 1 addition & 1 deletion GPU/GLES/GPU_GLES.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ class GPU_GLES : public GPUCommon {

void InitClear() override;
void BeginFrame() override;
void CopyDisplayToOutput() override;
void CopyDisplayToOutput(bool reallyDirty) override;
void Reinitialize() override;

FramebufferManagerGLES *framebufferManagerGL_;
Expand Down
2 changes: 1 addition & 1 deletion GPU/GPUCommon.h
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ class GPUCommon : public GPUInterface, public GPUDebugInterface {
u32 Break(int mode) override;
void ReapplyGfxState() override;

void CopyDisplayToOutput() override = 0;
void CopyDisplayToOutput(bool reallyDirty) override = 0;
void InitClear() override = 0;
bool PerformMemoryCopy(u32 dest, u32 src, int size) override;
bool PerformMemorySet(u32 dest, u8 v, int size) override;
Expand Down
2 changes: 1 addition & 1 deletion GPU/GPUInterface.h
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,7 @@ class GPUInterface {
// Framebuffer management
virtual void SetDisplayFramebuffer(u32 framebuf, u32 stride, GEBufferFormat format) = 0;
virtual void BeginFrame() = 0; // Can be a good place to draw the "memory" framebuffer for accelerated plugins
virtual void CopyDisplayToOutput() = 0;
virtual void CopyDisplayToOutput(bool reallyDirty) = 0;

// Tells the GPU to update the gpuStats structure.
virtual void GetStats(char *buffer, size_t bufsize) = 0;
Expand Down
2 changes: 1 addition & 1 deletion GPU/Null/NullGpu.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ class NullGPU : public GPUCommon {
void ExecuteOp(u32 op, u32 diff) override;

void SetDisplayFramebuffer(u32 framebuf, u32 stride, GEBufferFormat format) override {}
void CopyDisplayToOutput() override {}
void CopyDisplayToOutput(bool reallyDirty) override {}
void GetStats(char *buffer, size_t bufsize) override;
void InvalidateCache(u32 addr, int size, GPUInvalidationType type) override;
void NotifyVideoUpload(u32 addr, int size, int width, int format) override;
Expand Down
2 changes: 1 addition & 1 deletion GPU/Software/SoftGpu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -353,7 +353,7 @@ void SoftGPU::CopyToCurrentFboFromDisplayRam(int srcwidth, int srcheight) {
draw_->BindIndexBuffer(nullptr, 0);
}

void SoftGPU::CopyDisplayToOutput() {
void SoftGPU::CopyDisplayToOutput(bool reallyDirty) {
// The display always shows 480x272.
CopyToCurrentFboFromDisplayRam(FB_WIDTH, FB_HEIGHT);
framebufferDirty_ = false;
Expand Down
2 changes: 1 addition & 1 deletion GPU/Software/SoftGpu.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ class SoftGPU : public GPUCommon {
void ExecuteOp(u32 op, u32 diff) override;

void SetDisplayFramebuffer(u32 framebuf, u32 stride, GEBufferFormat format) override;
void CopyDisplayToOutput() override;
void CopyDisplayToOutput(bool reallyDirty) override;
void GetStats(char *buffer, size_t bufsize) override;
void InvalidateCache(u32 addr, int size, GPUInvalidationType type) override;
void NotifyVideoUpload(u32 addr, int size, int width, int format) override;
Expand Down
4 changes: 2 additions & 2 deletions GPU/Vulkan/GPU_Vulkan.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -431,13 +431,13 @@ void GPU_Vulkan::SetDisplayFramebuffer(u32 framebuf, u32 stride, GEBufferFormat
framebufferManager_->SetDisplayFramebuffer(framebuf, stride, format);
}

void GPU_Vulkan::CopyDisplayToOutput() {
void GPU_Vulkan::CopyDisplayToOutput(bool reallyDirty) {
// Flush anything left over.
drawEngine_.Flush();

shaderManagerVulkan_->DirtyLastShader();

framebufferManagerVulkan_->CopyDisplayToOutput();
framebufferManagerVulkan_->CopyDisplayToOutput(reallyDirty);

gstate_c.Dirty(DIRTY_TEXTURE_IMAGE);
}
Expand Down
2 changes: 1 addition & 1 deletion GPU/Vulkan/GPU_Vulkan.h
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ class GPU_Vulkan : public GPUCommon {
void CheckFlushOp(int cmd, u32 diff);
void BuildReportingInfo();
void InitClear() override;
void CopyDisplayToOutput() override;
void CopyDisplayToOutput(bool reallyDirty) override;
void Reinitialize() override;

void InitDeviceObjects();
Expand Down
2 changes: 1 addition & 1 deletion UI/EmuScreen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1315,7 +1315,7 @@ void EmuScreen::render() {
thin3d->BindFramebufferAsRenderTarget(nullptr, { RPAction::CLEAR, RPAction::DONT_CARE, RPAction::DONT_CARE });
// Just to make sure.
if (PSP_IsInited()) {
gpu->CopyDisplayToOutput();
gpu->CopyDisplayToOutput(true);
}
} else {
// Didn't actually reach the end of the frame, ran out of the blockTicks cycles.
Expand Down

0 comments on commit c363c16

Please sign in to comment.