mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-07-23 22:29:39 -06:00
Support frame and video dumping from VideoCommon
This commit is contained in:
@ -507,23 +507,6 @@ void Renderer::SwapImpl(AbstractTexture* texture, const EFBRectangle& rc, u64 ti
|
||||
// are determined by guest state. Currently, the only way to catch these is to update every frame.
|
||||
UpdateDrawRectangle();
|
||||
|
||||
// Render the frame dump image if enabled.
|
||||
if (IsFrameDumping())
|
||||
{
|
||||
// If we haven't dumped a single frame yet, set up frame dumping.
|
||||
if (!m_frame_dumping_active)
|
||||
StartFrameDumping();
|
||||
|
||||
/* DrawFrameDump(scaled_efb_rect, xfb_addr, xfb_sources, xfb_count, fb_width, fb_stride, fb_height,
|
||||
ticks);*/
|
||||
}
|
||||
else
|
||||
{
|
||||
// If frame dumping was previously enabled, flush all frames and remove the fence callback.
|
||||
if (m_frame_dumping_active)
|
||||
EndFrameDumping();
|
||||
}
|
||||
|
||||
// Ensure the worker thread is not still submitting a previous command buffer.
|
||||
// In other words, the last frame has been submitted (otherwise the next call would
|
||||
// be a race, as the image may not have been consumed yet).
|
||||
@ -856,7 +839,7 @@ void Renderer::OnFrameDumpImageReady(VkFence fence)
|
||||
|
||||
void Renderer::WriteFrameDumpImage(size_t index)
|
||||
{
|
||||
FrameDumpImage& frame = m_frame_dump_images[index];
|
||||
/*FrameDumpImage& frame = m_frame_dump_images[index];
|
||||
_assert_(frame.pending);
|
||||
|
||||
// Check fence has been signaled.
|
||||
@ -873,14 +856,14 @@ void Renderer::WriteFrameDumpImage(size_t index)
|
||||
static_cast<int>(frame.readback_texture->GetHeight()),
|
||||
static_cast<int>(frame.readback_texture->GetRowStride()), frame.dump_state);
|
||||
|
||||
frame.pending = false;
|
||||
frame.pending = false;*/
|
||||
}
|
||||
|
||||
StagingTexture2D* Renderer::PrepareFrameDumpImage(u32 width, u32 height, u64 ticks)
|
||||
{
|
||||
// Ensure the last frame that was sent to the frame dump has completed encoding before we send
|
||||
// the next image to it.
|
||||
FinishFrameData();
|
||||
//FinishFrameData();
|
||||
|
||||
// If the last image hasn't been written to the frame dump yet, write it now.
|
||||
// This is necessary so that the worker thread is no more than one frame behind, and the pointer
|
||||
|
@ -113,23 +113,17 @@ void VKTexture::Bind(unsigned int stage)
|
||||
StateTracker::GetInstance()->SetTexture(stage, m_texture->GetView());
|
||||
}
|
||||
|
||||
bool VKTexture::Save(const std::string& filename, unsigned int level)
|
||||
std::optional<AbstractTexture::RawTextureInfo> VKTexture::MapFullImpl()
|
||||
{
|
||||
_assert_(level < m_config.levels);
|
||||
// No support for optimization of full copy
|
||||
return MapRegionImpl(0, 0, 0, m_config.width, m_config.height);
|
||||
}
|
||||
|
||||
// We can't dump compressed textures currently (it would mean drawing them to a RGBA8
|
||||
// framebuffer, and saving that). TextureCache does not call Save for custom textures
|
||||
// anyway, so this is fine for now.
|
||||
_assert_(m_config.format == AbstractTextureFormat::RGBA8);
|
||||
|
||||
// Determine dimensions of image we want to save.
|
||||
u32 level_width = std::max(1u, m_config.width >> level);
|
||||
u32 level_height = std::max(1u, m_config.height >> level);
|
||||
|
||||
// Use a temporary staging texture for the download. Certainly not optimal,
|
||||
// but since we have to idle the GPU anyway it doesn't really matter.
|
||||
std::unique_ptr<StagingTexture2D> staging_texture = StagingTexture2D::Create(
|
||||
STAGING_BUFFER_TYPE_READBACK, level_width, level_height, TEXTURECACHE_TEXTURE_FORMAT);
|
||||
std::optional<AbstractTexture::RawTextureInfo> VKTexture::MapRegionImpl(u32 level, u32 x, u32 y,
|
||||
u32 width, u32 height)
|
||||
{
|
||||
m_staging_texture = StagingTexture2D::Create(STAGING_BUFFER_TYPE_READBACK, width, height,
|
||||
TEXTURECACHE_TEXTURE_FORMAT);
|
||||
|
||||
// Transition image to transfer source, and invalidate the current state,
|
||||
// since we'll be executing the command buffer.
|
||||
@ -138,9 +132,9 @@ bool VKTexture::Save(const std::string& filename, unsigned int level)
|
||||
StateTracker::GetInstance()->EndRenderPass();
|
||||
|
||||
// Copy to download buffer.
|
||||
staging_texture->CopyFromImage(g_command_buffer_mgr->GetCurrentCommandBuffer(),
|
||||
m_texture->GetImage(), VK_IMAGE_ASPECT_COLOR_BIT, 0, 0,
|
||||
level_width, level_height, level, 0);
|
||||
m_staging_texture->CopyFromImage(g_command_buffer_mgr->GetCurrentCommandBuffer(),
|
||||
m_texture->GetImage(), VK_IMAGE_ASPECT_COLOR_BIT, x, y, width,
|
||||
height, level, 0);
|
||||
|
||||
// Restore original state of texture.
|
||||
m_texture->TransitionToLayout(g_command_buffer_mgr->GetCurrentCommandBuffer(),
|
||||
@ -150,21 +144,23 @@ bool VKTexture::Save(const std::string& filename, unsigned int level)
|
||||
Util::ExecuteCurrentCommandsAndRestoreState(false, true);
|
||||
|
||||
// Map the staging texture so we can copy the contents out.
|
||||
if (!staging_texture->Map())
|
||||
if (!m_staging_texture->Map())
|
||||
{
|
||||
PanicAlert("Failed to map staging texture");
|
||||
return false;
|
||||
return {};
|
||||
}
|
||||
|
||||
// Write texture out to file.
|
||||
// It's okay to throw this texture away immediately, since we're done with it, and
|
||||
// we blocked until the copy completed on the GPU anyway.
|
||||
bool result = TextureToPng(reinterpret_cast<u8*>(staging_texture->GetMapPointer()),
|
||||
static_cast<u32>(staging_texture->GetRowStride()), filename,
|
||||
level_width, level_height);
|
||||
return AbstractTexture::RawTextureInfo{reinterpret_cast<u8*>(m_staging_texture->GetMapPointer()),
|
||||
static_cast<u32>(m_staging_texture->GetRowStride()), width,
|
||||
height};
|
||||
}
|
||||
|
||||
staging_texture->Unmap();
|
||||
return result;
|
||||
void VKTexture::Unmap()
|
||||
{
|
||||
if (!m_staging_texture)
|
||||
return;
|
||||
|
||||
m_staging_texture->Unmap();
|
||||
}
|
||||
|
||||
void VKTexture::CopyTextureRectangle(const MathUtil::Rectangle<int>& dst_rect,
|
||||
|
@ -20,7 +20,7 @@ public:
|
||||
~VKTexture();
|
||||
|
||||
void Bind(unsigned int stage) override;
|
||||
bool Save(const std::string& filename, unsigned int level) override;
|
||||
void Unmap() override;
|
||||
|
||||
void CopyRectangleFromTexture(const AbstractTexture* source,
|
||||
const MathUtil::Rectangle<int>& srcrect,
|
||||
@ -47,7 +47,12 @@ private:
|
||||
void ScaleTextureRectangle(const MathUtil::Rectangle<int>& dst_rect, Texture2D* src_texture,
|
||||
const MathUtil::Rectangle<int>& src_rect);
|
||||
|
||||
std::optional<RawTextureInfo> MapFullImpl() override;
|
||||
std::optional<RawTextureInfo> MapRegionImpl(u32 level, u32 x, u32 y, u32 width,
|
||||
u32 height) override;
|
||||
|
||||
std::unique_ptr<Texture2D> m_texture;
|
||||
std::unique_ptr<StagingTexture2D> m_staging_texture;
|
||||
VkFramebuffer m_framebuffer;
|
||||
};
|
||||
|
||||
|
Reference in New Issue
Block a user