Commit 4a2d50c2 authored by Laszlo Agocs's avatar Laszlo Agocs

Introduce debug mark begin/end/msg and implement for Metal

Exercised in examplewindow. (run plainqwindow_metal in XCode)
parent a6da1449
......@@ -240,8 +240,11 @@ void ExampleWindow::render()
}
QRhiCommandBuffer *cb = m_sc->currentFrameCommandBuffer();
if (!m_onScreenOnly)
if (!m_onScreenOnly) {
cb->debugMarkBegin("Offscreen triangle pass");
m_liveTexCubeRenderer.queueOffscreenPass(cb);
cb->debugMarkEnd();
}
QRhiResourceUpdateBatch *u = m_r->nextResourceUpdateBatch();
m_triRenderer.queueResourceUpdates(u);
......@@ -253,13 +256,22 @@ void ExampleWindow::render()
m_liveTexCubeRenderer.queueResourceUpdates(u);
cb->beginPass(m_sc->currentFrameRenderTarget(), { 0.4f, 0.7f, 0.0f, 1.0f }, { 1.0f, 0 }, u);
cb->debugMarkBegin(QByteArrayLiteral("Triangle"));
m_triRenderer.queueDraw(cb, outputSize);
cb->debugMarkEnd();
if (!m_triangleOnly) {
cb->debugMarkBegin(QByteArrayLiteral("Quad"));
m_quadRenderer.queueDraw(cb, outputSize);
cb->debugMarkEnd();
cb->debugMarkBegin(QByteArrayLiteral("Cube"));
m_cubeRenderer.queueDraw(cb, outputSize);
cb->debugMarkEnd();
}
if (!m_onScreenOnly)
if (!m_onScreenOnly) {
cb->debugMarkBegin(QByteArrayLiteral("Cube with offscreen triangle"));
m_liveTexCubeRenderer.queueDraw(cb, outputSize);
cb->debugMarkEnd();
}
QRhiResourceUpdateBatch *passEndUpdates = nullptr;
#ifdef READBACK_SWAPCHAIN
......
......@@ -446,6 +446,7 @@ QRhi *QRhi::create(Implementation impl, QRhiInitParams *params, Flags flags)
profD->rhi = r.data();
profD->rhiD = r->d;
}
r->d->debugMarkers = flags.testFlag(EnableDebugMarkers);
if (r->d->create(flags))
return r.take();
}
......@@ -640,6 +641,21 @@ void QRhiCommandBuffer::drawIndexed(quint32 indexCount,
rhi->drawIndexed(this, indexCount, instanceCount, firstIndex, vertexOffset, firstInstance);
}
void QRhiCommandBuffer::debugMarkBegin(const QByteArray &name)
{
rhi->debugMarkBegin(this, name);
}
void QRhiCommandBuffer::debugMarkEnd()
{
rhi->debugMarkEnd(this);
}
void QRhiCommandBuffer::debugMarkMsg(const QByteArray &msg)
{
rhi->debugMarkMsg(this, msg);
}
int QRhi::ubufAligned(int v) const
{
const int byteAlign = ubufAlignment();
......
......@@ -992,6 +992,14 @@ public:
qint32 vertexOffset = 0,
quint32 firstInstance = 0);
// Ignored when EnableDebugMarkers is not set.
// May be silently ignored with some backends.
void debugMarkBegin(const QByteArray &name);
void debugMarkEnd();
// With some backends debugMarkMsg is only supported inside a pass and is
// ignored when called outside a begin/endPass.
void debugMarkMsg(const QByteArray &msg);
protected:
QRhiCommandBuffer(QRhiImplementation *rhi);
void *m_reserved;
......
......@@ -123,6 +123,10 @@ public:
quint32 instanceCount, quint32 firstIndex,
qint32 vertexOffset, quint32 firstInstance) = 0;
virtual void debugMarkBegin(QRhiCommandBuffer *cb, const QByteArray &name) = 0;
virtual void debugMarkEnd(QRhiCommandBuffer *cb) = 0;
virtual void debugMarkMsg(QRhiCommandBuffer *cb, const QByteArray &msg) = 0;
virtual QVector<int> supportedSampleCounts() const = 0;
virtual int ubufAlignment() const = 0;
virtual bool isYUpInFramebuffer() const = 0;
......@@ -152,6 +156,7 @@ protected:
QVector<QRhiResourceUpdateBatch *> resUpdPool;
QBitArray resUpdPoolMap;
QRhiProfiler profiler;
bool debugMarkers = false;
friend class QRhi;
friend struct QRhiResourceUpdateBatchPrivate;
......
......@@ -478,6 +478,32 @@ void QRhiD3D11::drawIndexed(QRhiCommandBuffer *cb, quint32 indexCount,
cbD->commands.append(cmd);
}
void QRhiD3D11::debugMarkBegin(QRhiCommandBuffer *cb, const QByteArray &name)
{
if (!debugMarkers)
return;
Q_UNUSED(cb);
Q_UNUSED(name);
}
void QRhiD3D11::debugMarkEnd(QRhiCommandBuffer *cb)
{
if (!debugMarkers)
return;
Q_UNUSED(cb);
}
void QRhiD3D11::debugMarkMsg(QRhiCommandBuffer *cb, const QByteArray &msg)
{
if (!debugMarkers)
return;
Q_UNUSED(cb);
Q_UNUSED(msg);
}
QRhi::FrameOpResult QRhiD3D11::beginFrame(QRhiSwapChain *swapChain)
{
Q_ASSERT(!inFrame);
......
......@@ -479,6 +479,10 @@ public:
quint32 instanceCount, quint32 firstIndex,
qint32 vertexOffset, quint32 firstInstance) override;
void debugMarkBegin(QRhiCommandBuffer *cb, const QByteArray &name) override;
void debugMarkEnd(QRhiCommandBuffer *cb) override;
void debugMarkMsg(QRhiCommandBuffer *cb, const QByteArray &msg) override;
QVector<int> supportedSampleCounts() const override;
int ubufAlignment() const override;
bool isYUpInFramebuffer() const override;
......
......@@ -451,6 +451,32 @@ void QRhiGles2::drawIndexed(QRhiCommandBuffer *cb, quint32 indexCount,
cbD->commands.append(cmd);
}
void QRhiGles2::debugMarkBegin(QRhiCommandBuffer *cb, const QByteArray &name)
{
if (!debugMarkers)
return;
Q_UNUSED(cb);
Q_UNUSED(name);
}
void QRhiGles2::debugMarkEnd(QRhiCommandBuffer *cb)
{
if (!debugMarkers)
return;
Q_UNUSED(cb);
}
void QRhiGles2::debugMarkMsg(QRhiCommandBuffer *cb, const QByteArray &msg)
{
if (!debugMarkers)
return;
Q_UNUSED(cb);
Q_UNUSED(msg);
}
QRhi::FrameOpResult QRhiGles2::beginFrame(QRhiSwapChain *swapChain)
{
Q_ASSERT(!inFrame);
......
......@@ -501,6 +501,10 @@ public:
quint32 instanceCount, quint32 firstIndex,
qint32 vertexOffset, quint32 firstInstance) override;
void debugMarkBegin(QRhiCommandBuffer *cb, const QByteArray &name) override;
void debugMarkEnd(QRhiCommandBuffer *cb) override;
void debugMarkMsg(QRhiCommandBuffer *cb, const QByteArray &msg) override;
QVector<int> supportedSampleCounts() const override;
int ubufAlignment() const override;
bool isYUpInFramebuffer() const override;
......
......@@ -580,6 +580,46 @@ void QRhiMetal::drawIndexed(QRhiCommandBuffer *cb, quint32 indexCount,
baseInstance: firstInstance];
}
void QRhiMetal::debugMarkBegin(QRhiCommandBuffer *cb, const QByteArray &name)
{
if (!debugMarkers)
return;
NSString *str = [NSString stringWithUTF8String: name.constData()];
QMetalCommandBuffer *cbD = QRHI_RES(QMetalCommandBuffer, cb);
if (inPass) {
[cbD->d->currentPassEncoder pushDebugGroup: str];
} else {
if (@available(macOS 10.13, iOS 11.0, *))
[cbD->d->cb pushDebugGroup: str];
}
}
void QRhiMetal::debugMarkEnd(QRhiCommandBuffer *cb)
{
if (!debugMarkers)
return;
QMetalCommandBuffer *cbD = QRHI_RES(QMetalCommandBuffer, cb);
if (inPass) {
[cbD->d->currentPassEncoder popDebugGroup];
} else {
if (@available(macOS 10.13, iOS 11.0, *))
[cbD->d->cb popDebugGroup];
}
}
void QRhiMetal::debugMarkMsg(QRhiCommandBuffer *cb, const QByteArray &msg)
{
if (!debugMarkers)
return;
if (inPass) {
QMetalCommandBuffer *cbD = QRHI_RES(QMetalCommandBuffer, cb);
[cbD->d->currentPassEncoder insertDebugSignpost: [NSString stringWithUTF8String: msg.constData()]];
}
}
QRhi::FrameOpResult QRhiMetal::beginFrame(QRhiSwapChain *swapChain)
{
Q_ASSERT(!inFrame);
......@@ -791,9 +831,12 @@ void QRhiMetal::enqueueResourceUpdates(QRhiCommandBuffer *cb, QRhiResourceUpdate
}
id<MTLBlitCommandEncoder> blitEnc = nil;
auto ensureBlit = [&blitEnc, cbD] {
if (!blitEnc)
auto ensureBlit = [&blitEnc, cbD, this] {
if (!blitEnc) {
blitEnc = [cbD->d->cb blitCommandEncoder];
if (debugMarkers)
[blitEnc pushDebugGroup: @"Texture upload/copy"];
}
};
for (const QRhiResourceUpdateBatchPrivate::TextureUpload &u : ud->textureUploads) {
......@@ -1007,8 +1050,11 @@ void QRhiMetal::enqueueResourceUpdates(QRhiCommandBuffer *cb, QRhiResourceUpdate
[blitEnc generateMipmapsForTexture: QRHI_RES(QMetalTexture, u.tex)->d->tex];
}
if (blitEnc)
if (blitEnc) {
if (debugMarkers)
[blitEnc popDebugGroup];
[blitEnc endEncoding];
}
ud->free();
}
......
......@@ -316,6 +316,10 @@ public:
quint32 instanceCount, quint32 firstIndex,
qint32 vertexOffset, quint32 firstInstance) override;
void debugMarkBegin(QRhiCommandBuffer *cb, const QByteArray &name) override;
void debugMarkEnd(QRhiCommandBuffer *cb) override;
void debugMarkMsg(QRhiCommandBuffer *cb, const QByteArray &msg) override;
QVector<int> supportedSampleCounts() const override;
int ubufAlignment() const override;
bool isYUpInFramebuffer() const override;
......
......@@ -2882,6 +2882,32 @@ void QRhiVulkan::drawIndexed(QRhiCommandBuffer *cb, quint32 indexCount,
df->vkCmdDrawIndexed(QRHI_RES(QVkCommandBuffer, cb)->cb, indexCount, instanceCount, firstIndex, vertexOffset, firstInstance);
}
void QRhiVulkan::debugMarkBegin(QRhiCommandBuffer *cb, const QByteArray &name)
{
if (!debugMarkers)
return;
Q_UNUSED(cb);
Q_UNUSED(name);
}
void QRhiVulkan::debugMarkEnd(QRhiCommandBuffer *cb)
{
if (!debugMarkers)
return;
Q_UNUSED(cb);
}
void QRhiVulkan::debugMarkMsg(QRhiCommandBuffer *cb, const QByteArray &msg)
{
if (!debugMarkers)
return;
Q_UNUSED(cb);
Q_UNUSED(msg);
}
static inline VkBufferUsageFlagBits toVkBufferUsage(QRhiBuffer::UsageFlags usage)
{
int u = 0;
......
......@@ -387,6 +387,10 @@ public:
quint32 instanceCount, quint32 firstIndex,
qint32 vertexOffset, quint32 firstInstance) override;
void debugMarkBegin(QRhiCommandBuffer *cb, const QByteArray &name) override;
void debugMarkEnd(QRhiCommandBuffer *cb) override;
void debugMarkMsg(QRhiCommandBuffer *cb, const QByteArray &msg) override;
QVector<int> supportedSampleCounts() const override;
int ubufAlignment() const override;
bool isYUpInFramebuffer() const override;
......
......@@ -3,7 +3,7 @@ prof api
vk, d3d, gl: tex and other prof
vk: memalloc stats to prof
vk, d3d, gl: debug: object names
debug: markers (begin, end, msg)
vk, d3d, gl: debug: markers (begin, end, msg)
max texture size?
multiwindow_threaded should demo pulling out the device and importing to another rhi
mtl: reduce set*
......@@ -54,6 +54,7 @@ dxc for d3d as an alternative to fxc?
hlsl -> dxc -> spirv -> spirv-cross hmmm...
+++ done
mtl: debug: markers (begin, end, msg)
mtl: debug: object names
mtl: buf/tex/rb/sc prof
mtl, gl, vk: texture import/export
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment