6#include <QtCore/qcoreapplication.h>
7#include <QtCore/qfile.h>
8#include <QtCore/qlibrary.h>
9#include <QtCore/qmutex.h>
10#include "QtGui/rhi/qrhi.h"
11#include "QtGui/rhi/qrhi_platform.h"
12#include "QtGui/qopenglcontext.h"
16Q_LOGGING_CATEGORY(lcGraphicsFrameCapture,
"qt.gui.graphicsframecapture")
18RENDERDOC_API_1_6_0 *QGraphicsFrameCaptureRenderDoc::s_rdocApi =
nullptr;
20QBasicMutex QGraphicsFrameCaptureRenderDoc::s_frameCaptureMutex;
24static void *glNativeContext(QOpenGLContext *context) {
26 if (context !=
nullptr && context->isValid()) {
28 nctx = context->nativeInterface<QNativeInterface::QWGLContext>()->nativeContext();
33 QNativeInterface::QEGLContext *eglItf = context->nativeInterface<QNativeInterface::QEGLContext>();
35 nctx = eglItf->nativeContext();
38#if QT_CONFIG(xcb_glx_plugin)
39 QNativeInterface::QGLXContext *glxItf = context->nativeInterface<QNativeInterface::QGLXContext>();
41 nctx = glxItf->nativeContext();
46 nctx = context->nativeInterface<QNativeInterface::QCocoaGLContext>()->nativeContext();
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
85
90
91
92
93
94
95
98 : m_nativeHandlesSet(
false)
109 QRhi::Implementation backend = rhi->backend();
110 const QRhiNativeHandles *nh = rhi->nativeHandles();
113 case QRhi::Implementation::D3D11: {
115 const QRhiD3D11NativeHandles *d3d11nh =
static_cast<
const QRhiD3D11NativeHandles *>(nh);
116 m_nativeHandle = d3d11nh->dev;
119 qCWarning(lcGraphicsFrameCapture) <<
"Could not find valid handles for D3D11. Check platform support";
122 case QRhi::Implementation::D3D12: {
124 const QRhiD3D12NativeHandles *d3d12nh =
static_cast<
const QRhiD3D12NativeHandles *>(nh);
125 m_nativeHandle = d3d12nh->dev;
128 qCWarning(lcGraphicsFrameCapture) <<
"Could not find valid handles for D3D12. Check platform support";
131 case QRhi::Implementation::Vulkan: {
133 const QRhiVulkanNativeHandles *vknh =
static_cast<
const QRhiVulkanNativeHandles *>(nh);
134 m_nativeHandle = RENDERDOC_DEVICEPOINTER_FROM_VKINSTANCE(vknh->inst->vkInstance());
137 qCWarning(lcGraphicsFrameCapture) <<
"Could not find valid handles for Vulkan. Check platform support";
140 case QRhi::Implementation::OpenGLES2: {
142 const QRhiGles2NativeHandles *glnh =
static_cast<
const QRhiGles2NativeHandles *>(nh);
147 qCWarning(lcGraphicsFrameCapture) <<
"Could not find valid handles for OpenGL. Check platform support";
150 case QRhi::Implementation::Metal:
151 case QRhi::Implementation::Null:
152 qCWarning(lcGraphicsFrameCapture) <<
"Invalid handles were provided."
153 " Metal and Null backends are not supported with RenderDoc";
158 m_nativeHandlesSet =
true;
162
163
164
165
170 qCWarning(lcGraphicsFrameCapture) <<
"RenderDoc was not initialized."
171 " Starting capturing can not be done.";
177 QMutexLocker locker(&s_frameCaptureMutex);
179 if (s_rdocApi->IsFrameCapturing()) {
180 qCWarning(lcGraphicsFrameCapture) <<
"A frame capture is already in progress, "
181 "will not initiate another one until"
182 " QGraphicsFrameCapture::endCaptureFrame is called.";
186 qCInfo(lcGraphicsFrameCapture) <<
"A frame capture is going to start.";
187 updateCapturePathAndTemplate();
192
193
194
195
196
197
201 qCWarning(lcGraphicsFrameCapture) <<
"RenderDoc was not initialized."
202 " End capturing can not be done.";
208 QMutexLocker locker(&s_frameCaptureMutex);
210 if (!s_rdocApi->IsFrameCapturing()) {
211 qCWarning(lcGraphicsFrameCapture) <<
"A call to QGraphicsFrameCapture::endCaptureFrame can not be done"
212 " without a call to QGraphicsFrameCapture::startCaptureFrame";
216 qCInfo(lcGraphicsFrameCapture) <<
"A frame capture is going to end.";
217 uint32_t result = s_rdocApi->EndFrameCapture(
m_nativeHandle,
nullptr);
220 uint32_t count = s_rdocApi->GetNumCaptures();
221 uint32_t pathLength = 0;
222 s_rdocApi->GetCapture(count - 1,
nullptr, &pathLength,
nullptr);
223 if (pathLength > 0) {
224 QVarLengthArray<
char> name(pathLength, 0);
225 s_rdocApi->GetCapture(count - 1, name.data(), &pathLength,
nullptr);
226 m_capturedFilesNames.append(QString::fromUtf8(name.data(), -1));
234 qCWarning(lcGraphicsFrameCapture) <<
"RenderDoc was not initialized."
235 " Updating save location can not be done.";
240 QString rdocFilePathTemplate = m_capturePath + QStringLiteral(
"/") + m_capturePrefix;
241 s_rdocApi->SetCaptureFilePathTemplate(rdocFilePathTemplate.toUtf8().constData());
245
246
249 return s_rdocApi && m_nativeHandlesSet;
255 qCWarning(lcGraphicsFrameCapture) <<
"RenderDoc was not initialized."
256 " Can not query if capturing is in progress or not.";
260 return s_rdocApi->IsFrameCapturing();
266 qCWarning(lcGraphicsFrameCapture) <<
"RenderDoc was not initialized."
267 " Can not open RenderDoc UI tool.";
273 QMutexLocker locker(&s_frameCaptureMutex);
275 if (s_rdocApi->IsTargetControlConnected())
276 s_rdocApi->ShowReplayUI();
278 s_rdocApi->LaunchReplayUI(1,
nullptr);
285 QMutexLocker locker(&s_frameCaptureMutex);
288 QLibrary renderDocLib(QStringLiteral(
"renderdoc"));
289 pRENDERDOC_GetAPI RENDERDOC_GetAPI = (pRENDERDOC_GetAPI) renderDocLib.resolve(
"RENDERDOC_GetAPI");
290 if (!renderDocLib.isLoaded() || (RENDERDOC_GetAPI ==
nullptr)) {
291 qCWarning(lcGraphicsFrameCapture) << renderDocLib.errorString().toLatin1();
295 int ret = RENDERDOC_GetAPI(eRENDERDOC_API_Version_1_6_0,
static_cast<
void **>(
static_cast<
void *>(&s_rdocApi)));
298 qCWarning(lcGraphicsFrameCapture) <<
"The requested RenderDoc API is invalid or not supported";
302 s_rdocApi->MaskOverlayBits(RENDERDOC_OverlayBits::eRENDERDOC_Overlay_None,
303 RENDERDOC_OverlayBits::eRENDERDOC_Overlay_None);
304 s_rdocApi->SetCaptureKeys(
nullptr, 0);
305 s_rdocApi->SetFocusToggleKeys(
nullptr, 0);
307 QString rdocFilePathTemplate = m_capturePath + QStringLiteral(
"/") + m_capturePrefix;
308 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...