vulkan: Add debug message filtering
[ChangeLog][QtGui] Added support for filtering Vulkan debug messages in QVulkanInstance. This is especially useful for processing or suppressing messages from the validation layers. Change-Id: Idf0d7889085948daf5b1a53d2a9b11081e967609 Reviewed-by: Paul Olav Tvete <paul.tvete@qt.io>
This commit is contained in:
parent
548513a4bd
commit
e85aa551eb
@ -85,4 +85,9 @@ void QPlatformVulkanInstance::presentQueued(QWindow *window)
|
|||||||
Q_UNUSED(window);
|
Q_UNUSED(window);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void QPlatformVulkanInstance::setDebugFilters(const QVector<QVulkanInstance::DebugFilter> &filters)
|
||||||
|
{
|
||||||
|
Q_UNUSED(filters);
|
||||||
|
}
|
||||||
|
|
||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
|
@ -78,6 +78,7 @@ public:
|
|||||||
virtual PFN_vkVoidFunction getInstanceProcAddr(const char *name) = 0;
|
virtual PFN_vkVoidFunction getInstanceProcAddr(const char *name) = 0;
|
||||||
virtual bool supportsPresent(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex, QWindow *window) = 0;
|
virtual bool supportsPresent(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex, QWindow *window) = 0;
|
||||||
virtual void presentQueued(QWindow *window);
|
virtual void presentQueued(QWindow *window);
|
||||||
|
virtual void setDebugFilters(const QVector<QVulkanInstance::DebugFilter> &filters);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QScopedPointer<QPlatformVulkanInstancePrivate> d_ptr;
|
QScopedPointer<QPlatformVulkanInstancePrivate> d_ptr;
|
||||||
|
@ -269,6 +269,7 @@ public:
|
|||||||
VkResult errorCode;
|
VkResult errorCode;
|
||||||
QScopedPointer<QVulkanFunctions> funcs;
|
QScopedPointer<QVulkanFunctions> funcs;
|
||||||
QHash<VkDevice, QVulkanDeviceFunctions *> deviceFuncs;
|
QHash<VkDevice, QVulkanDeviceFunctions *> deviceFuncs;
|
||||||
|
QVector<QVulkanInstance::DebugFilter> debugFilters;
|
||||||
};
|
};
|
||||||
|
|
||||||
bool QVulkanInstancePrivate::ensureVulkan()
|
bool QVulkanInstancePrivate::ensureVulkan()
|
||||||
@ -570,6 +571,7 @@ bool QVulkanInstance::create()
|
|||||||
d_ptr->extensions = d_ptr->platformInst->enabledExtensions();
|
d_ptr->extensions = d_ptr->platformInst->enabledExtensions();
|
||||||
d_ptr->errorCode = VK_SUCCESS;
|
d_ptr->errorCode = VK_SUCCESS;
|
||||||
d_ptr->funcs.reset(new QVulkanFunctions(this));
|
d_ptr->funcs.reset(new QVulkanFunctions(this));
|
||||||
|
d_ptr->platformInst->setDebugFilters(d_ptr->debugFilters);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -785,6 +787,50 @@ void QVulkanInstance::presentQueued(QWindow *window)
|
|||||||
d_ptr->platformInst->presentQueued(window);
|
d_ptr->platformInst->presentQueued(window);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\typedef QVulkanInstance::DebugFilter
|
||||||
|
|
||||||
|
Typedef for debug filtering callback functions.
|
||||||
|
|
||||||
|
\sa installDebugOutputFilter(), removeDebugOutputFilter()
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Installs a \a filter function that is called for every Vulkan debug
|
||||||
|
message. When the callback returns \c true, the message is stopped (filtered
|
||||||
|
out) and will not appear on the debug output.
|
||||||
|
|
||||||
|
\note Filtering is only effective when NoDebugOutputRedirect is not
|
||||||
|
\l{setFlags()}{set}. Installing filters has no effect otherwise.
|
||||||
|
|
||||||
|
\note This function can be called before create().
|
||||||
|
|
||||||
|
\sa removeDebugOutputFilter()
|
||||||
|
*/
|
||||||
|
void QVulkanInstance::installDebugOutputFilter(DebugFilter filter)
|
||||||
|
{
|
||||||
|
if (!d_ptr->debugFilters.contains(filter)) {
|
||||||
|
d_ptr->debugFilters.append(filter);
|
||||||
|
if (d_ptr->platformInst)
|
||||||
|
d_ptr->platformInst->setDebugFilters(d_ptr->debugFilters);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Removes a \a filter function previously installed by
|
||||||
|
installDebugOutputFilter().
|
||||||
|
|
||||||
|
\note This function can be called before create().
|
||||||
|
|
||||||
|
\sa installDebugOutputFilter()
|
||||||
|
*/
|
||||||
|
void QVulkanInstance::removeDebugOutputFilter(DebugFilter filter)
|
||||||
|
{
|
||||||
|
d_ptr->debugFilters.removeOne(filter);
|
||||||
|
if (d_ptr->platformInst)
|
||||||
|
d_ptr->platformInst->setDebugFilters(d_ptr->debugFilters);
|
||||||
|
}
|
||||||
|
|
||||||
#ifndef QT_NO_DEBUG_STREAM
|
#ifndef QT_NO_DEBUG_STREAM
|
||||||
QDebug operator<<(QDebug dbg, const QVulkanLayer &layer)
|
QDebug operator<<(QDebug dbg, const QVulkanLayer &layer)
|
||||||
{
|
{
|
||||||
|
@ -188,6 +188,11 @@ public:
|
|||||||
|
|
||||||
void presentQueued(QWindow *window);
|
void presentQueued(QWindow *window);
|
||||||
|
|
||||||
|
typedef bool (*DebugFilter)(VkDebugReportFlagsEXT flags, VkDebugReportObjectTypeEXT objectType, uint64_t object,
|
||||||
|
size_t location, int32_t messageCode, const char *pLayerPrefix, const char *pMessage);
|
||||||
|
void installDebugOutputFilter(DebugFilter filter);
|
||||||
|
void removeDebugOutputFilter(DebugFilter filter);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QScopedPointer<QVulkanInstancePrivate> d_ptr;
|
QScopedPointer<QVulkanInstancePrivate> d_ptr;
|
||||||
Q_DISABLE_COPY(QVulkanInstance)
|
Q_DISABLE_COPY(QVulkanInstance)
|
||||||
|
@ -330,6 +330,11 @@ bool QBasicPlatformVulkanInstance::supportsPresent(VkPhysicalDevice physicalDevi
|
|||||||
return supported;
|
return supported;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void QBasicPlatformVulkanInstance::setDebugFilters(const QVector<QVulkanInstance::DebugFilter> &filters)
|
||||||
|
{
|
||||||
|
m_debugFilters = filters;
|
||||||
|
}
|
||||||
|
|
||||||
void QBasicPlatformVulkanInstance::destroySurface(VkSurfaceKHR surface) const
|
void QBasicPlatformVulkanInstance::destroySurface(VkSurfaceKHR surface) const
|
||||||
{
|
{
|
||||||
if (m_destroySurface && surface)
|
if (m_destroySurface && surface)
|
||||||
@ -345,11 +350,11 @@ static VKAPI_ATTR VkBool32 VKAPI_CALL defaultDebugCallbackFunc(VkDebugReportFlag
|
|||||||
const char *pMessage,
|
const char *pMessage,
|
||||||
void *pUserData)
|
void *pUserData)
|
||||||
{
|
{
|
||||||
Q_UNUSED(flags);
|
QBasicPlatformVulkanInstance *self = static_cast<QBasicPlatformVulkanInstance *>(pUserData);
|
||||||
Q_UNUSED(objectType);
|
for (QVulkanInstance::DebugFilter filter : *self->debugFilters()) {
|
||||||
Q_UNUSED(object);
|
if (filter(flags, objectType, object, location, messageCode, pLayerPrefix, pMessage))
|
||||||
Q_UNUSED(location);
|
return VK_FALSE;
|
||||||
Q_UNUSED(pUserData);
|
}
|
||||||
|
|
||||||
// not categorized, just route to plain old qDebug
|
// not categorized, just route to plain old qDebug
|
||||||
qDebug("vkDebug: %s: %d: %s", pLayerPrefix, messageCode, pMessage);
|
qDebug("vkDebug: %s: %d: %s", pLayerPrefix, messageCode, pMessage);
|
||||||
@ -374,6 +379,7 @@ void QBasicPlatformVulkanInstance::setupDebugOutput()
|
|||||||
| VK_DEBUG_REPORT_WARNING_BIT_EXT
|
| VK_DEBUG_REPORT_WARNING_BIT_EXT
|
||||||
| VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT;
|
| VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT;
|
||||||
dbgCallbackInfo.pfnCallback = defaultDebugCallbackFunc;
|
dbgCallbackInfo.pfnCallback = defaultDebugCallbackFunc;
|
||||||
|
dbgCallbackInfo.pUserData = this;
|
||||||
|
|
||||||
VkResult err = createDebugReportCallback(m_vkInst, &dbgCallbackInfo, nullptr, &m_debugCallback);
|
VkResult err = createDebugReportCallback(m_vkInst, &dbgCallbackInfo, nullptr, &m_debugCallback);
|
||||||
if (err != VK_SUCCESS)
|
if (err != VK_SUCCESS)
|
||||||
|
@ -73,7 +73,10 @@ public:
|
|||||||
QByteArrayList enabledExtensions() const override;
|
QByteArrayList enabledExtensions() const override;
|
||||||
PFN_vkVoidFunction getInstanceProcAddr(const char *name) override;
|
PFN_vkVoidFunction getInstanceProcAddr(const char *name) override;
|
||||||
bool supportsPresent(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex, QWindow *window) override;
|
bool supportsPresent(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex, QWindow *window) override;
|
||||||
|
void setDebugFilters(const QVector<QVulkanInstance::DebugFilter> &filters) override;
|
||||||
|
|
||||||
void destroySurface(VkSurfaceKHR surface) const;
|
void destroySurface(VkSurfaceKHR surface) const;
|
||||||
|
const QVector<QVulkanInstance::DebugFilter> *debugFilters() const { return &m_debugFilters; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void loadVulkanLibrary(const QString &defaultLibraryName);
|
void loadVulkanLibrary(const QString &defaultLibraryName);
|
||||||
@ -105,6 +108,7 @@ private:
|
|||||||
|
|
||||||
VkDebugReportCallbackEXT m_debugCallback;
|
VkDebugReportCallbackEXT m_debugCallback;
|
||||||
PFN_vkDestroyDebugReportCallbackEXT m_vkDestroyDebugReportCallbackEXT;
|
PFN_vkDestroyDebugReportCallbackEXT m_vkDestroyDebugReportCallbackEXT;
|
||||||
|
QVector<QVulkanInstance::DebugFilter> m_debugFilters;
|
||||||
};
|
};
|
||||||
|
|
||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
|
Loading…
x
Reference in New Issue
Block a user