mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-02-16 01:09:20 +01:00
Merge pull request #4344 from degasus/framedump_ogl
OGL: Use PBO for framedump, with async readback.
This commit is contained in:
commit
363dec7bc7
@ -767,6 +767,9 @@ Renderer::Renderer()
|
|||||||
|
|
||||||
Renderer::~Renderer()
|
Renderer::~Renderer()
|
||||||
{
|
{
|
||||||
|
FlushFrameDump();
|
||||||
|
if (m_frame_dumping_pbo[0])
|
||||||
|
glDeleteBuffers(2, m_frame_dumping_pbo.data());
|
||||||
}
|
}
|
||||||
|
|
||||||
void Renderer::Shutdown()
|
void Renderer::Shutdown()
|
||||||
@ -1447,19 +1450,9 @@ void Renderer::SwapImpl(u32 xfbAddr, u32 fbWidth, u32 fbStride, u32 fbHeight,
|
|||||||
|
|
||||||
glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
|
glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
|
||||||
|
|
||||||
if (IsFrameDumping())
|
FlushFrameDump();
|
||||||
{
|
DumpFrame(flipped_trc, ticks);
|
||||||
std::vector<u8> image(flipped_trc.GetWidth() * flipped_trc.GetHeight() * 4);
|
|
||||||
|
|
||||||
glPixelStorei(GL_PACK_ALIGNMENT, 1);
|
|
||||||
glReadPixels(flipped_trc.left, flipped_trc.bottom, flipped_trc.GetWidth(),
|
|
||||||
flipped_trc.GetHeight(), GL_RGBA, GL_UNSIGNED_BYTE, image.data());
|
|
||||||
|
|
||||||
AVIDump::Frame state = AVIDump::FetchState(ticks);
|
|
||||||
DumpFrameData(image.data(), flipped_trc.GetWidth(), flipped_trc.GetHeight(),
|
|
||||||
flipped_trc.GetWidth() * 4, state, true);
|
|
||||||
FinishFrameData();
|
|
||||||
}
|
|
||||||
// Finish up the current frame, print some stats
|
// Finish up the current frame, print some stats
|
||||||
|
|
||||||
SetWindowSize(fbStride, fbHeight);
|
SetWindowSize(fbStride, fbHeight);
|
||||||
@ -1588,6 +1581,62 @@ void Renderer::SwapImpl(u32 xfbAddr, u32 fbWidth, u32 fbStride, u32 fbHeight,
|
|||||||
ClearEFBCache();
|
ClearEFBCache();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Renderer::FlushFrameDump()
|
||||||
|
{
|
||||||
|
if (!m_last_frame_exported)
|
||||||
|
return;
|
||||||
|
|
||||||
|
FinishFrameData();
|
||||||
|
glBindBuffer(GL_PIXEL_PACK_BUFFER, m_frame_dumping_pbo[0]);
|
||||||
|
m_frame_pbo_is_mapped[0] = true;
|
||||||
|
void* data = glMapBufferRange(
|
||||||
|
GL_PIXEL_PACK_BUFFER, 0, m_last_frame_width[0] * m_last_frame_height[0] * 4, GL_MAP_READ_BIT);
|
||||||
|
DumpFrameData(reinterpret_cast<u8*>(data), m_last_frame_width[0], m_last_frame_height[0],
|
||||||
|
m_last_frame_width[0] * 4, m_last_frame_state, true);
|
||||||
|
glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
|
||||||
|
m_last_frame_exported = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Renderer::DumpFrame(const TargetRectangle& flipped_trc, u64 ticks)
|
||||||
|
{
|
||||||
|
if (!IsFrameDumping())
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!m_frame_dumping_pbo[0])
|
||||||
|
{
|
||||||
|
glGenBuffers(2, m_frame_dumping_pbo.data());
|
||||||
|
glBindBuffer(GL_PIXEL_PACK_BUFFER, m_frame_dumping_pbo[0]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::swap(m_frame_dumping_pbo[0], m_frame_dumping_pbo[1]);
|
||||||
|
std::swap(m_frame_pbo_is_mapped[0], m_frame_pbo_is_mapped[1]);
|
||||||
|
std::swap(m_last_frame_width[0], m_last_frame_width[1]);
|
||||||
|
std::swap(m_last_frame_height[0], m_last_frame_height[1]);
|
||||||
|
glBindBuffer(GL_PIXEL_PACK_BUFFER, m_frame_dumping_pbo[0]);
|
||||||
|
if (m_frame_pbo_is_mapped[0])
|
||||||
|
glUnmapBuffer(GL_PIXEL_PACK_BUFFER);
|
||||||
|
m_frame_pbo_is_mapped[0] = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (flipped_trc.GetWidth() != m_last_frame_width[0] ||
|
||||||
|
flipped_trc.GetHeight() != m_last_frame_height[0])
|
||||||
|
{
|
||||||
|
m_last_frame_width[0] = flipped_trc.GetWidth();
|
||||||
|
m_last_frame_height[0] = flipped_trc.GetHeight();
|
||||||
|
glBufferData(GL_PIXEL_PACK_BUFFER, m_last_frame_width[0] * m_last_frame_height[0] * 4, nullptr,
|
||||||
|
GL_STREAM_READ);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_last_frame_state = AVIDump::FetchState(ticks);
|
||||||
|
m_last_frame_exported = true;
|
||||||
|
|
||||||
|
glPixelStorei(GL_PACK_ALIGNMENT, 1);
|
||||||
|
glReadPixels(flipped_trc.left, flipped_trc.bottom, m_last_frame_width[0], m_last_frame_height[0],
|
||||||
|
GL_RGBA, GL_UNSIGNED_BYTE, 0);
|
||||||
|
glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
|
||||||
|
}
|
||||||
|
|
||||||
// ALWAYS call RestoreAPIState for each ResetAPIState call you're doing
|
// ALWAYS call RestoreAPIState for each ResetAPIState call you're doing
|
||||||
void Renderer::ResetAPIState()
|
void Renderer::ResetAPIState()
|
||||||
{
|
{
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <array>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include "VideoCommon/RenderBase.h"
|
#include "VideoCommon/RenderBase.h"
|
||||||
|
|
||||||
@ -111,5 +112,16 @@ private:
|
|||||||
|
|
||||||
void BlitScreen(TargetRectangle src, TargetRectangle dst, GLuint src_texture, int src_width,
|
void BlitScreen(TargetRectangle src, TargetRectangle dst, GLuint src_texture, int src_width,
|
||||||
int src_height);
|
int src_height);
|
||||||
|
|
||||||
|
void FlushFrameDump();
|
||||||
|
void DumpFrame(const TargetRectangle& flipped_trc, u64 ticks);
|
||||||
|
|
||||||
|
// avi dumping state to delay one frame
|
||||||
|
std::array<u32, 2> m_frame_dumping_pbo = {};
|
||||||
|
std::array<bool, 2> m_frame_pbo_is_mapped = {};
|
||||||
|
std::array<int, 2> m_last_frame_width = {};
|
||||||
|
std::array<int, 2> m_last_frame_height = {};
|
||||||
|
bool m_last_frame_exported = false;
|
||||||
|
AVIDump::Frame m_last_frame_state;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user