5#include <QtCore/qcoreapplication.h>
6#include <QtCore/qfile.h>
7#include <QtCore/qlibrary.h>
8#include <QtCore/qmutex.h>
9#include "QtGui/rhi/qrhi.h"
10#include "QtGui/rhi/qrhi_platform.h"
11#include "QtGui/qopenglcontext.h"
15Q_LOGGING_CATEGORY(lcGraphicsFrameCapture,
"qt.gui.graphicsframecapture")
17RENDERDOC_API_1_6_0 *QGraphicsFrameCaptureRenderDoc::s_rdocApi =
nullptr;
19QBasicMutex QGraphicsFrameCaptureRenderDoc::s_frameCaptureMutex;
23static void *glNativeContext(QOpenGLContext *context) {
25 if (context !=
nullptr && context->isValid()) {
27 nctx = context->nativeInterface<QNativeInterface::QWGLContext>()->nativeContext();
32 QNativeInterface::QEGLContext *eglItf = context->nativeInterface<QNativeInterface::QEGLContext>();
34 nctx = eglItf->nativeContext();
37#if QT_CONFIG(xcb_glx_plugin)
38 QNativeInterface::QGLXContext *glxItf = context->nativeInterface<QNativeInterface::QGLXContext>();
40 nctx = glxItf->nativeContext();
45 nctx = context->nativeInterface<QNativeInterface::QCocoaGLContext>()->nativeContext();
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
89
90
91
92
93
94
97 : m_nativeHandlesSet(
false)
108 QRhi::Implementation backend = rhi->backend();
109 const QRhiNativeHandles *nh = rhi->nativeHandles();
112 case QRhi::Implementation::D3D11: {
114 const QRhiD3D11NativeHandles *d3d11nh =
static_cast<
const QRhiD3D11NativeHandles *>(nh);
115 m_nativeHandle = d3d11nh->dev;
118 qCWarning(lcGraphicsFrameCapture) <<
"Could not find valid handles for D3D11. Check platform support";
121 case QRhi::Implementation::D3D12: {
123 const QRhiD3D12NativeHandles *d3d12nh =
static_cast<
const QRhiD3D12NativeHandles *>(nh);
124 m_nativeHandle = d3d12nh->dev;
127 qCWarning(lcGraphicsFrameCapture) <<
"Could not find valid handles for D3D12. Check platform support";
130 case QRhi::Implementation::Vulkan: {
132 const QRhiVulkanNativeHandles *vknh =
static_cast<
const QRhiVulkanNativeHandles *>(nh);
133 m_nativeHandle = RENDERDOC_DEVICEPOINTER_FROM_VKINSTANCE(vknh->inst->vkInstance());
136 qCWarning(lcGraphicsFrameCapture) <<
"Could not find valid handles for Vulkan. Check platform support";
139 case QRhi::Implementation::OpenGLES2: {
141 const QRhiGles2NativeHandles *glnh =
static_cast<
const QRhiGles2NativeHandles *>(nh);
146 qCWarning(lcGraphicsFrameCapture) <<
"Could not find valid handles for OpenGL. Check platform support";
149 case QRhi::Implementation::Metal:
150 case QRhi::Implementation::Null:
151 qCWarning(lcGraphicsFrameCapture) <<
"Invalid handles were provided."
152 " Metal and Null backends are not supported with RenderDoc";
157 m_nativeHandlesSet =
true;
161
162
163
164
169 qCWarning(lcGraphicsFrameCapture) <<
"RenderDoc was not initialized."
170 " Starting capturing can not be done.";
176 QMutexLocker locker(&s_frameCaptureMutex);
178 if (s_rdocApi->IsFrameCapturing()) {
179 qCWarning(lcGraphicsFrameCapture) <<
"A frame capture is already in progress, "
180 "will not initiate another one until"
181 " QGraphicsFrameCapture::endCaptureFrame is called.";
185 qCInfo(lcGraphicsFrameCapture) <<
"A frame capture is going to start.";
186 updateCapturePathAndTemplate();
191
192
193
194
195
196
200 qCWarning(lcGraphicsFrameCapture) <<
"RenderDoc was not initialized."
201 " End capturing can not be done.";
207 QMutexLocker locker(&s_frameCaptureMutex);
209 if (!s_rdocApi->IsFrameCapturing()) {
210 qCWarning(lcGraphicsFrameCapture) <<
"A call to QGraphicsFrameCapture::endCaptureFrame can not be done"
211 " without a call to QGraphicsFrameCapture::startCaptureFrame";
215 qCInfo(lcGraphicsFrameCapture) <<
"A frame capture is going to end.";
216 uint32_t result = s_rdocApi->EndFrameCapture(
m_nativeHandle,
nullptr);
219 uint32_t count = s_rdocApi->GetNumCaptures();
220 uint32_t pathLength = 0;
221 s_rdocApi->GetCapture(count - 1,
nullptr, &pathLength,
nullptr);
222 if (pathLength > 0) {
223 QVarLengthArray<
char> name(pathLength, 0);
224 s_rdocApi->GetCapture(count - 1, name.data(), &pathLength,
nullptr);
225 m_capturedFilesNames.append(QString::fromUtf8(name.data(), -1));
233 qCWarning(lcGraphicsFrameCapture) <<
"RenderDoc was not initialized."
234 " Updating save location can not be done.";
239 QString rdocFilePathTemplate = m_capturePath + QStringLiteral(
"/") + m_capturePrefix;
240 s_rdocApi->SetCaptureFilePathTemplate(rdocFilePathTemplate.toUtf8().constData());
244
245
248 return s_rdocApi && m_nativeHandlesSet;
254 qCWarning(lcGraphicsFrameCapture) <<
"RenderDoc was not initialized."
255 " Can not query if capturing is in progress or not.";
259 return s_rdocApi->IsFrameCapturing();
265 qCWarning(lcGraphicsFrameCapture) <<
"RenderDoc was not initialized."
266 " Can not open RenderDoc UI tool.";
272 QMutexLocker locker(&s_frameCaptureMutex);
274 if (s_rdocApi->IsTargetControlConnected())
275 s_rdocApi->ShowReplayUI();
277 s_rdocApi->LaunchReplayUI(1,
nullptr);
284 QMutexLocker locker(&s_frameCaptureMutex);
287 QLibrary renderDocLib(QStringLiteral(
"renderdoc"));
288 pRENDERDOC_GetAPI RENDERDOC_GetAPI = (pRENDERDOC_GetAPI) renderDocLib.resolve(
"RENDERDOC_GetAPI");
289 if (!renderDocLib.isLoaded() || (RENDERDOC_GetAPI ==
nullptr)) {
290 qCWarning(lcGraphicsFrameCapture) << renderDocLib.errorString().toLatin1();
294 int ret = RENDERDOC_GetAPI(eRENDERDOC_API_Version_1_6_0,
static_cast<
void **>(
static_cast<
void *>(&s_rdocApi)));
297 qCWarning(lcGraphicsFrameCapture) <<
"The requested RenderDoc API is invalid or not supported";
301 s_rdocApi->MaskOverlayBits(RENDERDOC_OverlayBits::eRENDERDOC_Overlay_None,
302 RENDERDOC_OverlayBits::eRENDERDOC_Overlay_None);
303 s_rdocApi->SetCaptureKeys(
nullptr, 0);
304 s_rdocApi->SetFocusToggleKeys(
nullptr, 0);
306 QString rdocFilePathTemplate = m_capturePath + QStringLiteral(
"/") + m_capturePrefix;
307 s_rdocApi->SetCaptureFilePathTemplate(rdocFilePathTemplate.toUtf8().constData());
The QGraphicsFrameCaptureRenderDoc class provides a way to capture a record of draw calls for differe...
void setRhi(QRhi *rhi) override
bool initialized() const override
Returns true if the API is loaded and can capture frames or not.
void openCapture() override
QGraphicsFrameCaptureRenderDoc()
Creates a new object of this class.
void startCaptureFrame() override
Starts a frame capture using the set native handles provided through QGraphicsFrameCaptureRenderDoc::...
bool isCapturing() const override
void endCaptureFrame() override
Ends a frame capture started by a call to QGraphicsFrameCaptureRenderDoc::startCaptureFrame using the...
Combined button and popup list for selecting options.