Commit b20d9229 authored by Laszlo Agocs's avatar Laszlo Agocs

vk: Make gpu timestamps work with rsh

Also enable and print some timings in multiwindow_threaded.

The included rsh doc update comes after varying experiences with
Vulkan implementations (e.g. NVIDIA 411, 417, and AMD something recent
all behaving slightly differently)
parent 3c397d2c
......@@ -66,6 +66,7 @@
#include <QBakedShader>
#include <QFile>
#include <QRhiProfiler>
#ifndef QT_NO_OPENGL
#include <QRhiGles2InitParams>
......@@ -283,6 +284,7 @@ struct Renderer
QMatrix4x4 m_proj;
float m_rotation = 0;
int m_frameCount = 0;
};
void Thread::run()
......@@ -345,6 +347,7 @@ void Renderer::createRhi()
return;
qDebug() << "renderer" << this << "creating rhi";
QRhi::Flags rhiFlags = QRhi::EnableProfiling;
if (useRsh) {
qDebug("Using QRhiResourceSharingHost");
......@@ -359,7 +362,7 @@ void Renderer::createRhi()
params.resourceSharingHost = rsh;
params.fallbackSurface = fallbackSurface;
params.window = window;
r = QRhi::create(QRhi::OpenGLES2, &params);
r = QRhi::create(QRhi::OpenGLES2, &params, rhiFlags);
}
#endif
......@@ -370,7 +373,7 @@ void Renderer::createRhi()
params.resourceSharingHost = rsh;
params.inst = instance;
params.window = window;
r = QRhi::create(QRhi::Vulkan, &params);
r = QRhi::create(QRhi::Vulkan, &params, rhiFlags);
}
#endif
......@@ -380,7 +383,7 @@ void Renderer::createRhi()
if (useRsh)
params.resourceSharingHost = rsh;
params.enableDebugLayer = true;
r = QRhi::create(QRhi::D3D11, &params);
r = QRhi::create(QRhi::D3D11, &params, rhiFlags);
}
#endif
......@@ -389,7 +392,7 @@ void Renderer::createRhi()
QRhiMetalInitParams params;
if (useRsh)
params.resourceSharingHost = rsh;
r = QRhi::create(QRhi::Metal, &params);
r = QRhi::create(QRhi::Metal, &params, rhiFlags);
}
#endif
......@@ -634,6 +637,28 @@ void Renderer::render(bool newlyExposed, bool wakeBeforePresent)
wakeUpIfNeeded();
r->endFrame(m_sc);
m_frameCount += 1;
if ((m_frameCount % 300) == 0) {
const QRhiProfiler::CpuTime ff = r->profiler()->frameToFrameTimes(m_sc);
const QRhiProfiler::CpuTime be = r->profiler()->frameBuildTimes(m_sc);
const QRhiProfiler::GpuTime gp = r->profiler()->gpuFrameTimes(m_sc);
if (r->isFeatureSupported(QRhi::Timestamps)) {
qDebug("[renderer %p] frame-to-frame: min %lld max %lld avg %f. "
"frame build: min %lld max %lld avg %f. "
"gpu frame time: min %f max %f avg %f",
this,
ff.minTime, ff.maxTime, ff.avgTime,
be.minTime, be.maxTime, be.avgTime,
gp.minTime, gp.maxTime, gp.avgTime);
} else {
qDebug("[renderer %p] frame-to-frame: min %lld max %lld avg %f. "
"frame build: min %lld max %lld avg %f. ",
this,
ff.minTime, ff.maxTime, ff.avgTime,
be.minTime, be.maxTime, be.avgTime);
}
}
}
void Renderer::sendInit()
......
......@@ -2630,6 +2630,15 @@ quint32 QRhiImplementation::approxByteSizeForTexture(QRhiTexture::Format format,
QRhiResourceSharingHost and so sharing the same device, queue, or device
context.
\note Resource sharing increases the chance of contention and inconsistent
frame rate due to sharing the same device and possibly command queue, and
due to the need for synchronization inside various QRhi calls. The results
can also vary based on the implementation of the underlying graphics API,
with potentially different results from different vendor's drivers or
different driver versions. Applications and libraries are advised to
consider offering resource sharing as an opt-in feature, combined with a
design that allows operating with fully independent QRhi instances as well.
To illustrate resource sharing, take the following code snippets.
In many cases an application will use a single QRhi. Resources created from it
......
......@@ -312,6 +312,14 @@ bool QRhiVulkan::create(QRhi::Flags flags)
}
}
QVector<VkQueueFamilyProperties> queueFamilyProps;
auto queryQueueFamilyProps = [this, &queueFamilyProps] {
uint32_t queueCount = 0;
f->vkGetPhysicalDeviceQueueFamilyProperties(physDev, &queueCount, nullptr);
queueFamilyProps.resize(queueCount);
f->vkGetPhysicalDeviceQueueFamilyProperties(physDev, &queueCount, queueFamilyProps.data());
};
if (!importedDevice && (!rsh || rshWantsDevice)) {
uint32_t devCount = 0;
f->vkEnumeratePhysicalDevices(inst->vkInstance(), &devCount, nullptr);
......@@ -329,10 +337,7 @@ bool QRhiVulkan::create(QRhi::Flags flags)
return false;
}
uint32_t queueCount = 0;
f->vkGetPhysicalDeviceQueueFamilyProperties(physDev, &queueCount, nullptr);
QVector<VkQueueFamilyProperties> queueFamilyProps(queueCount);
f->vkGetPhysicalDeviceQueueFamilyProperties(physDev, &queueCount, queueFamilyProps.data());
queryQueueFamilyProps();
gfxQueue = VK_NULL_HANDLE;
gfxQueueFamilyIdx = -1;
......@@ -361,8 +366,6 @@ bool QRhiVulkan::create(QRhi::Flags flags)
return false;
}
timestampValidBits = queueFamilyProps[gfxQueueFamilyIdx].timestampValidBits;
VkDeviceQueueCreateInfo queueInfo[2];
const float prio[] = { 0 };
memset(queueInfo, 0, sizeof(queueInfo));
......@@ -435,9 +438,16 @@ bool QRhiVulkan::create(QRhi::Flags flags)
}
}
if (gfxQueueFamilyIdx != -1 && !gfxQueue)
if (gfxQueueFamilyIdx != -1) {
if (!gfxQueue)
df->vkGetDeviceQueue(dev, gfxQueueFamilyIdx, 0, &gfxQueue);
if (queueFamilyProps.isEmpty())
queryQueueFamilyProps();
timestampValidBits = queueFamilyProps[gfxQueueFamilyIdx].timestampValidBits;
}
f->vkGetPhysicalDeviceProperties(physDev, &physDevProperties);
ubufAlign = physDevProperties.limits.minUniformBufferOffsetAlignment;
texbufAlign = physDevProperties.limits.optimalBufferCopyOffsetAlignment;
......
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