add an option to capture GPU frame

This commit is contained in:
Samuliak 2025-01-04 12:42:06 +01:00
parent 40dab1e212
commit 1d8806cf06
No known key found for this signature in database
3 changed files with 71 additions and 0 deletions

View File

@ -303,6 +303,17 @@ void MetalRenderer::SwapBuffers(bool swapTV, bool swapDRC)
// Debug
m_performanceMonitor.ResetPerFrameData();
// GPU capture
if (m_capturing)
{
EndCapture();
}
else if (m_captureFrame)
{
StartCapture();
m_captureFrame = false;
}
}
void MetalRenderer::HandleScreenshotRequest(LatteTextureView* texView, bool padView) {
@ -2161,3 +2172,27 @@ void MetalRenderer::EnsureImGuiBackend()
//ImGui_ImplMetal_CreateFontsTexture(m_device);
}
}
void MetalRenderer::StartCapture()
{
auto captureManager = MTL::CaptureManager::sharedCaptureManager();
auto desc = MTL::CaptureDescriptor::alloc()->init();
desc->setCaptureObject(m_device);
NS::Error* error = nullptr;
captureManager->startCapture(desc, &error);
if (error)
{
cemuLog_log(LogType::Force, "Failed to start GPU capture: {}", error->localizedDescription()->utf8String());
}
m_capturing = true;
}
void MetalRenderer::EndCapture()
{
auto captureManager = MTL::CaptureManager::sharedCaptureManager();
captureManager->stopCapture();
m_capturing = false;
}

View File

@ -460,6 +460,12 @@ public:
m_occlusionQuery.m_lastCommandBuffer = GetAndRetainCurrentCommandBufferIfNotCompleted();
}
// GPU capture
void CaptureFrame()
{
m_captureFrame = true;
}
private:
MetalLayerHandle m_mainLayer;
MetalLayerHandle m_padLayer;
@ -533,6 +539,11 @@ private:
// State
MetalState m_state;
// GPU capture
bool m_captureFrame = false;
bool m_capturing = false;
// Helpers
MetalLayerHandle& GetLayer(bool mainWindow)
{
return (mainWindow ? m_mainLayer : m_padLayer);
@ -541,4 +552,8 @@ private:
void SwapBuffer(bool mainWindow);
void EnsureImGuiBackend();
// GPU capture
void StartCapture();
void EndCapture();
};

View File

@ -1,3 +1,5 @@
#include "Cafe/HW/Latte/Renderer/Metal/MetalRenderer.h"
#include "Cafe/HW/Latte/Renderer/Renderer.h"
#include "gui/wxgui.h"
#include "gui/MainWindow.h"
#include "gui/guiWrapper.h"
@ -137,6 +139,7 @@ enum
MAINFRAME_MENU_ID_DEBUG_VIEW_TEXTURE_RELATIONS,
MAINFRAME_MENU_ID_DEBUG_AUDIO_AUX_ONLY,
MAINFRAME_MENU_ID_DEBUG_VK_ACCURATE_BARRIERS,
MAINFRAME_MENU_ID_DEBUG_GPU_CAPTURE,
// debug->logging
MAINFRAME_MENU_ID_DEBUG_LOGGING0 = 21500,
@ -212,6 +215,7 @@ EVT_MENU(MAINFRAME_MENU_ID_DEBUG_DUMP_CURL_REQUESTS, MainWindow::OnDebugSetting)
EVT_MENU(MAINFRAME_MENU_ID_DEBUG_RENDER_UPSIDE_DOWN, MainWindow::OnDebugSetting)
EVT_MENU(MAINFRAME_MENU_ID_DEBUG_AUDIO_AUX_ONLY, MainWindow::OnDebugSetting)
EVT_MENU(MAINFRAME_MENU_ID_DEBUG_VK_ACCURATE_BARRIERS, MainWindow::OnDebugSetting)
EVT_MENU(MAINFRAME_MENU_ID_DEBUG_GPU_CAPTURE, MainWindow::OnDebugSetting)
EVT_MENU(MAINFRAME_MENU_ID_DEBUG_DUMP_RAM, MainWindow::OnDebugSetting)
EVT_MENU(MAINFRAME_MENU_ID_DEBUG_DUMP_FST, MainWindow::OnDebugSetting)
// debug -> View ...
@ -1007,6 +1011,20 @@ void MainWindow::OnDebugSetting(wxCommandEvent& event)
if(!GetConfig().vk_accurate_barriers)
wxMessageBox(_("Warning: Disabling the accurate barriers option will lead to flickering graphics but may improve performance. It is highly recommended to leave it turned on."), _("Accurate barriers are off"), wxOK);
}
else if (event.GetId() == MAINFRAME_MENU_ID_DEBUG_GPU_CAPTURE)
{
#if ENABLE_METAL
if (g_renderer->GetType() == RendererAPI::Metal)
{
static_cast<MetalRenderer*>(g_renderer.get())->CaptureFrame();
}
else
{
wxMessageBox(_("GPU capture is only supported on Metal."), _("Error"), wxOK | wxCENTRE | wxICON_ERROR);
return;
}
#endif
}
else if (event.GetId() == MAINFRAME_MENU_ID_DEBUG_AUDIO_AUX_ONLY)
ActiveSettings::EnableAudioOnlyAux(event.IsChecked());
else if (event.GetId() == MAINFRAME_MENU_ID_DEBUG_DUMP_RAM)
@ -2254,6 +2272,9 @@ void MainWindow::RecreateMenu()
auto accurateBarriers = debugMenu->AppendCheckItem(MAINFRAME_MENU_ID_DEBUG_VK_ACCURATE_BARRIERS, _("&Accurate barriers (Vulkan)"), wxEmptyString);
accurateBarriers->Check(GetConfig().vk_accurate_barriers);
auto gpuCapture = debugMenu->Append(MAINFRAME_MENU_ID_DEBUG_VK_ACCURATE_BARRIERS, _("&GPU capture (Metal)"), wxEmptyString);
gpuCapture->Enable(m_game_launched && g_renderer->GetType() == RendererAPI::Metal);
debugMenu->AppendSeparator();
#ifdef CEMU_DEBUG_ASSERT