Camadas de validação e logs
Como mencionado anteriormente, a API Vulkan é projetada em torno da ideia de sobrecarga mínima de driver e uma das manifestações disso é que há uma verificação de erros muito limitada na API por padrão. Se passarmos um parâmetro inválido para uma função da API Vulkan, o aplicativo pode falhar silenciosamente ou funcionar de maneira inconsistente.
No entanto, isso não significa que essas verificações não possam ser adicionadas à API. Para isso, Vulkan apresenta um sistema elegante conhecido como camadas de validação. Camadas de validação são componentes opcionais que se ligam a chamadas de função Vulkan para aplicar operações adicionais. Operações comuns em camadas de validação são:
- Verificação dos valores dos parâmetros em relação à especificação para detectar uso indevido;
- Acompanhamento da criação e destruição de objetos para encontrar vazamentos de recursos;
- Verificação da segurança do thread, rastreando os threads de origem das chamadas;
- Registro de todas as chamadas e seus parâmetros para a saída padrão.
Neste projeto iremos habilitar as camadas de diagnóstico padrão fornecidas pelo SDK Vulkan. Em vez de especificar explicitamente todas as camadas úteis, o SDK nos permite solicitar a camada VK_LAYER_LUNARG_standard_validation
que habilita implicitamente toda uma série de camadas úteis de diagnóstico. Podemos fazer isso chamando setLayers()
no objeto de instância antes de chamar create()
:
...
m_instance.setLayers(QByteArrayList() << "VK_LAYER_LUNARG_standard_validation");
if (!m_instance.create())
qFatal("Failed to create Vulkan instance: %d", m_instance.errorCode());
setVulkanInstance(&m_instance);
O Qt recebe automaticamente mensagens da biblioteca Vulkan e as coloca no sistema de registro do próprio Qt. Os erros críticos serão passados para qWarning()
e aparecerão na saída padrão da aplicação. No entanto, o Qt também registra informações adicionais que podem ser usadas durante a depuração. Esta informação está oculta por padrão, mas podemos torná-la visível adicionando a seguinte linha à função main()
logo após a construção do QGuiApplication
:
...
#include <QLoggingCategory>
int main(int argc, char *argv[]) {
QApplication a(argc, argv);
MainWindow w;
QLoggingCategory::setFilterRules(
QStringLiteral("qt.vulkan=true"));
w.show();
return a.exec();
}