Spec-Zone.ru › Qt 6.0

Класс QVulkanInstance

Класс QVulkanInstance представляет собой нативный экземпляр Vulkan, позволяющий выполнять рендеринг Vulkan на QSurface. Подробнее...

Заголовок: #include <QVulkanInstance>
CMake: find_package(Qt6 COMPONENTS Gui REQUIRED) target_link_libraries(mytarget PRIVATE Qt6::Gui)
qmake: QT += gui
С момента: Qt 5.10
  • Список всех членов, включая унаследованные

Типы публичного доступа

DebugFilter
Перечисление Флаг { NoDebugOutputRedirect }
Флаги Флаги

Функции публичного доступа

QVulkanInstance()
~QVulkanInstance()
QVersionNumber apiVersion() const
bool create()
void destroy()
QVulkanDeviceFunctions * deviceFunctions(VkDevice device)
VkResult errorCode() const
QByteArrayList extensions() const
QVulkanInstance::Flags flags() const
QVulkanFunctions * functions() const

Статические члены публичного доступа

VkSurfaceKHR surfaceForWindow(QWindow *window)

Подробное описание

Vulkan — кроссплатформенный явный графический и вычислительный API. Этот класс предоставляет поддержку загрузки библиотеки Vulkan и создания экземпляра instance кроссплатформенным способом. Для ознакомления с экземплярами Vulkan см. раздел 3.2 спецификации.

Примечание: Поддержка экземпляров Vulkan и окон с поверхностями, поддерживающими Vulkan, зависит от плагинов различных платформ. Однако не все они будут поддерживать Vulkan. При выполнении на такой платформе create() завершится ошибкой и всегда вернёт false.

Примечание: Поддержка Vulkan может быть автоматически отключена для данного сборки Qt из-за отсутствия необходимых заголовков Vulkan во время сборки. В этом случае, если вывод configure указывает, что поддержка Vulkan отключена, классы QVulkan* будут недоступны.

Примечание: Некоторые функции изменили свою сигнатуру между различными версиями заголовков Vulkan. Если при сборке Qt присутствуют заголовки только со старыми, конфликтующими сигнатурами, поддержка Vulkan будет отключена. Рекомендуется использовать заголовки Vulkan 1.0.39 или новее.

Инициализация

Аналогично QOpenGLContext, фактическое создание экземпляра Vulkan происходит только при вызове create(). Это позволяет использовать QVulkanInstance как обычную переменную-член, сохраняя контроль над тем, когда выполнять инициализацию.

Запрос поддерживаемых слоёв и расширений на уровне экземпляра возможен с помощью вызова supportedLayers() и supportedExtensions(). Это гарантирует загрузку библиотеки Vulkan и может быть безопасно вызвано до create().

Экземпляры хранят состояние Vulkan для каждого приложения, и создание объекта VkInstance инициализирует библиотеку Vulkan. На практике обычно будет создан один экземпляр в самом начале функции main(). Затем объект существует до выхода из приложения.

Каждый Vulkan-базированный QWindow должен быть связан с QVulkanInstance с помощью вызова QWindow::setVulkanInstance(). Таким образом, типичная схема приложения выглядит следующим образом:

    int main(int argc, char **argv)
    {
        QGuiApplication app(argc, argv);

        QVulkanInstance inst;
        if (!inst.create())
            return 1;

        // ...
        window->setVulkanInstance(&inst);
        window->show();

        return app.exec();
    }

Настройка

QVulkanInstance автоматически включает минимальный набор расширений, необходимый для нового экземпляра. На практике это означает расширения семейства VK_KHR_*_surface.

По умолчанию вывод отладки Vulkan, например, сообщения из слоев проверки, передаются в qDebug(). Это можно отключить, передав флаг NoDebugOutputRedirect в setFlags() *до* вызова create().

Для включения дополнительных слоёв и расширений укажите список через setLayers() и setExtensions() *до* вызова create(). Если указанный слой или расширение не указаны как доступные для экземпляра, запрос игнорируется. После успешного вызова create(), значения, возвращаемые такими функциями, как layers() и extensions(), отражают фактически включённые слои и расширения. При необходимости, например, для предотвращения запроса конфликтующих расширений, которые могут привести к ошибке создания экземпляра Vulkan, список фактически поддерживаемых слоёв и расширений можно проверить с помощью supportedLayers() и supportedExtensions() до вызова create().

Например, для включения стандартных слоёв проверки можно сделать следующее:

    QVulkanInstance inst;

    // Enable validation layer, if supported. Messages go to qDebug by default.
    inst.setLayers(QByteArrayList() << "VK_LAYER_LUNARG_standard_validation");

    bool ok = inst.create();
    if (!ok) {
        // ... Vulkan not available
    }

    if (!inst.layers().contains("VK_LAYER_LUNARG_standard_validation")) {
        // ... validation layer not available
    }

Или, как альтернатива, принять решения до попытки создания экземпляра Vulkan:

    QVulkanInstance inst;

    if (inst.supportedLayers().contains("VK_LAYER_LUNARG_standard_validation")) {
        // ...
    }
    bool ok = inst.create();
    // ...

Принятие существующего экземпляра

По умолчанию QVulkanInstance создаёт новый экземпляр Vulkan. При работе с внешними движками и рендерерами это может быть нежелательно. Если уже имеется обработчик VkInstance, вызовите setVkInstance() перед вызовом create(). Таким образом, новые экземпляры не будут создаваться, и QVulkanInstance не будет владеть этим обработчиком.

Примечание: Компоненту, создающему внешний экземпляр, необходимо убедиться, что на нём включены необходимые расширения. Это: VK_KHR_surface, WSI-специфическое расширение VK_KHR_*_surface, соответствующее данной платформе, и VK_EXT_debug_report, в случае, если требуется перенаправление отладочного вывода QVulkanInstance.

Доступ к основным командам Vulkan

Чтобы получить обработчик VkInstance, который обёртнут QVulkanInstance, вызовите vkInstance(). Для разрешения функций Vulkan вызовите getInstanceProcAddr(). Для основных команд Vulkan ручное разрешение не требуется, так как они предоставляются через объекты QVulkanFunctions и QVulkanDeviceFunctions, доступные через functions() и deviceFunctions().

Примечание: QVulkanFunctions и QVulkanDeviceFunctions генерируются из спецификаций XML API Vulkan при построении библиотек Qt. Поэтому для них нет документации. Они содержат функции Vulkan 1.0 с такими же сигнатурами, как описано в документации по API Vulkan.

Получение нативного Vulkan-поверхностного объекта для окна

Две распространённые операции, специфичные для системы окон, — это получение поверхностного объекта (обработчик VkSurfaceKHR для окна) и проверка, поддерживает ли заданная семейство очередей вывод на заданный поверхностный объект. Для того, чтобы избежать WSI-специфических деталей в приложениях, эти операции абстрагированы QVulkanInstance и базовыми слоями QPA.

Для создания Vulkan-поверхностного объекта для окна или получения существующего вызовите surfaceForWindow(). Большинство платформ создадут поверхностный объект только при первом вызове surfaceForWindow(), но внутреннее поведение может отличаться в зависимости от платформы. После создания последующие вызовы surfaceForWindow() просто возвращают тот же обработчик. Это хорошо согласуется со структурой типичных подклассов QWindow, поддерживающих Vulkan.

Для проверки, может ли заданное семейство очередей внутри физического устройства использоваться для вывода на заданный поверхностный объект, вызовите supportsPresent(). Эта функция объединяет как общие проверки vkGetPhysicalDeviceSurfaceSupportKHR, так и WSI-специфические проверки vkGetPhysicalDevice*PresentationSupportKHR.

Отладка

Помимо возвращения false от create() или 0 от surfaceForWindow(), критические ошибки также будут выводиться в отладочный вывод через qWarning(). Дополнительную регистрацию можно запросить, включив отладочный вывод для категории регистрации qt.vulkan. Фактический код ошибки Vulkan при создании экземпляра можно получить, вызвав errorCode() после неудачного вызова create().

В некоторых особых случаях может потребоваться переопределить имя библиотеки Vulkan. Это можно сделать, задав переменную среды QT_VULKAN_LIB.

Пример

Ниже приведён общий план создания QWindow, совместимого с Vulkan:

class VulkanWindow : public QWindow
{
public:
    VulkanWindow() {
        setSurfaceType(VulkanSurface);
    }

    void exposeEvent(QExposeEvent *) {
        if (isExposed()) {
            if (!m_initialized) {
                m_initialized = true;
                // initialize device, swapchain, etc.
                QVulkanInstance *inst = vulkanInstance();
                QVulkanFunctions *f = inst->functions();
                uint32_t devCount = 0;
                f->vkEnumeratePhysicalDevices(inst->vkInstance(), &devCount, nullptr);
                // ...
                // build the first frame
                render();
            }
        }
    }

    bool event(QEvent *e) {
        if (e->type() == QEvent::UpdateRequest)
            render();
        return QWindow::event(e);
    }

    void render() {
       // ...
       requestUpdate(); // render continuously
    }

private:
    bool m_initialized = false;
};

int main(int argc, char **argv)
{
    QGuiApplication app(argc, argv);

    QVulkanInstance inst;
    if (!inst.create()) {
        qWarning("Vulkan not available");
        return 1;
    }

    VulkanWindow window;
    window.showMaximized();

    return app.exec();

}

Примечание: Помимо экспонирования, реализация окна должна также обрабатывать дополнительные события, такие как изменение размера и QPlatformSurfaceEvent, чтобы обеспечить надлежащее управление цепочкой обмена. Кроме того, на некоторых платформах может потребоваться освобождение ресурсов, когда они больше не отображаются.

Использование C++ связывающих для Vulkan

Так же возможно объединение инструментов Qt для Vulkan с обёрткой C++ для Vulkan, например, Vulkan-Hpp. Предварительное условие здесь состоит в том, что C++ слой должен иметь возможность принимать нативные обработчики (VkInstance, VkSurfaceKHR) в своих классах без принятия владения (так как владение остаётся у QVulkanInstance и QWindow). Также обратите внимание на следующее:

  • Некоторые обёртки требуют включения поддержки исключений. Qt не использует исключения. Чтобы включить исключения для приложения, добавьте CONFIG += exceptions в файл .pro.
  • Некоторые обёртки вызывают функции Vulkan напрямую, предполагая, что vulkan.h предоставляет прототипы и приложение подключается к библиотеке Vulkan, экспортирующей все необходимые символы. Qt может не подключаться напрямую к библиотеке Vulkan. Поэтому на некоторых платформах может потребоваться добавить LIBS += -lvulkan или аналогичное в файл .pro приложения.
  • Заголовки для классов QVulkan могут включать vulkan.h с включённым VK_NO_PROTOTYPES. Это может вызвать проблемы в заголовках C++-обёрток, которые полагаются на прототипы. Поэтому в коде приложения может потребоваться включить vulkan.hpp или аналогичное перед любым из заголовков QVulkan.

См. также QVulkanFunctions и QSurface::SurfaceType.

Документация по типам членов

QVulkanInstance::DebugFilter

Тип-синоним для функций обратного вызова фильтра отладки.

См. также installDebugOutputFilter() и removeDebugOutputFilter().

[since 5.10] перечисление QVulkanInstance::Flagфлаги QVulkanInstance::Flags

Это перечисление описывает флаги, которые можно передать в setFlags(). Они контролируют поведение create().

Константа Значение Описание
QVulkanInstance::NoDebugOutputRedirect 0x01 Отключает перенаправление отладочного вывода Vulkan (VK_EXT_debug_report) в qDebug.

Это перечисление было введено или изменено в Qt 5.10.

Тип Flags является типом-синонимом для QFlags<Flag>. Он хранит логическое ИЛИ сочетание значений Flag.

Документация по функциям-членам

QVulkanInstance::QVulkanInstance()

Конструирует новый экземпляр.

Примечание: Инициализация Vulkan не выполняется в конструкторе.

QVulkanInstance::~QVulkanInstance()

Деструктор.

Примечание: current() вернёт nullptr после уничтожения экземпляра.

QVersionNumber QVulkanInstance::apiVersion() const

Возвращает запрашиваемую версию API Vulkan, с которой ожидается работа приложения, или нулевой номер версии, если setApiVersion() не вызывался до create().

См. также setApiVersion().

bool QVulkanInstance::create()

Инициализирует библиотеку Vulkan и создаёт новый или принимает существующий экземпляр Vulkan.

Возвращает true при успехе, false при ошибке или если Vulkan не поддерживается.

При успехе указатель на этот QVulkanInstance можно получить через статическую функцию current().

Экземпляр Vulkan и библиотека доступны до тех пор, пока существует этот QVulkanInstance или пока не вызывается destroy().

void QVulkanInstance::destroy()

Уничтожает базовый экземпляр платформы, тем самым уничтожая VkInstance (если он принадлежит). Объект QVulkanInstance можно повторно использовать, вызвав create() ещё раз.

QVulkanDeviceFunctions *QVulkanInstance::deviceFunctions(VkDevice device)

Возвращает объект QVulkanDeviceFunctions, который предоставляет набор команд Vulkan на уровне устройства и гарантированно работает на всех платформах.

Примечание: Функции Vulkan в возвращённом объекте должны вызываться только с device или дочерним объектом (VkQueue, VkCommandBuffer) device в качестве первого параметра. Это связано с тем, что эти функции разрешаются с помощью vkGetDeviceProcAddr, чтобы избежать потенциальной накладных расходов внутренней маршрутизации.

Примечание: Возвращаемый объект принадлежит и управляется QVulkanInstance. Не уничтожайте и не изменяйте его.

Примечание: Объект кэшируется, поэтому вызов этой функции с тем же device является быстрой операцией. Однако, когда устройство уничтожается, приложение должно уведомить QVulkanInstance об этом, вызвав resetDeviceFunctions().

См. также functions() и resetDeviceFunctions().

VkResult QVulkanInstance::errorCode() const

Возвращает код ошибки Vulkan после неудачного вызова create(), VK_SUCCESS в противном случае.

Значение обычно является возвращаемым значением из vkCreateInstance() (при создании нового экземпляра Vulkan вместо принятия существующего), но также может быть VK_NOT_READY , если плагин платформы не поддерживает Vulkan.

QByteArrayList QVulkanInstance::extensions() const

Возвращает включённые расширения экземпляра, если create() был вызван и завершился успешно. В противном случае возвращает запрошенные расширения.

См. также setExtensions().

QVulkanInstance::Flags QVulkanInstance::flags() const

Возвращает запрошенные флаги.

См. также setFlags().

QVulkanFunctions *QVulkanInstance::functions() const

Возвращает соответствующий объект QVulkanFunctions, который предоставляет набор команд ядра Vulkan, исключая функции уровня устройства, и гарантирует функциональность на всех платформах.

Примечание: Возвращаемый объект принадлежит и управляется объектом QVulkanInstance. Не уничтожайте и не изменяйте его.

См. также deviceFunctions().

PFN_vkVoidFunction QVulkanInstance::getInstanceProcAddr(const char *name)

Разрешает функцию Vulkan с заданным именем name.

Для основных команд Vulkan предпочтительнее использовать обертки функций, извлекаемые из functions() и deviceFunctions().

void QVulkanInstance::installDebugOutputFilter(QVulkanInstance::DebugFilter filter)

Устанавливает функцию filter, которая вызывается для каждого сообщения отладки Vulkan. Когда обратный вызов возвращает true, сообщение останавливается (отфильтровывается) и не отображается в выводе отладки.

Примечание: Фильтрация эффективна только тогда, когда NoDebugOutputRedirect не установлен. Установка фильтров не имеет эффекта в противном случае.

Примечание: Эту функцию можно вызвать до create().

См. также removeDebugOutputFilter().

bool QVulkanInstance::isValid() const

Возвращает true, если create() выполнилась успешно и экземпляр валиден.

QByteArrayList QVulkanInstance::layers() const

Возвращает включенные слои экземпляра, если create() был вызван и выполнен успешно. В противном случае возвращает запрошенные слои.

См. также setLayers().

[since 5.15] void QVulkanInstance::presentAboutToBeQueued(QWindow *window)

Эта функция должна вызываться рендерером приложения перед добавлением операции представления для window в очередь.

Хотя на некоторых платформах это будет пустой операцией, на некоторых платформах могут выполняться зависящие от системы окон синхронизации. Например, на Wayland это добавит запрос wl_surface.frame, чтобы предотвратить блокировку драйвера для сворачиваемых окон.

Эта функция была добавлена в Qt 5.15.

void QVulkanInstance::presentQueued(QWindow *window)

Эта функция должна вызываться рендерером приложения после добавления операции представления для window в очередь.

Хотя на некоторых платформах это будет пустой операцией, на некоторых платформах могут выполняться зависящие от системы окон синхронизации. Например, на X11 это обновит _NET_WM_SYNC_REQUEST_COUNTER.

void QVulkanInstance::removeDebugOutputFilter(QVulkanInstance::DebugFilter filter)

Удаляет функцию filter, ранее установленную функцией installDebugOutputFilter().

Примечание: Эту функцию можно вызвать до create().

См. также installDebugOutputFilter().

void QVulkanInstance::resetDeviceFunctions(VkDevice device)

Деактивирует и уничтожает объект QVulkanDeviceFunctions для данного устройства device.

Эта функция должна вызываться, когда VkDevice, для которого была вызвана функция deviceFunctions(), уничтожается, в то время как приложение продолжает работать, возможно, создавая новый логический Vulkan-устройство позже.

Нет необходимости вызывать это до уничтожения QVulkanInstance, так как очистка выполняется автоматически.

См. также deviceFunctions().

void QVulkanInstance::setApiVersion(const QVersionNumber &vulkanVersion)

Указывает API Vulkan, с которым приложение ожидает работать.

По умолчанию vulkanVersion не указан, и проверка версии во время создания экземпляра Vulkan не выполняется.

Примечание: Эту функцию можно вызвать только до create(), и она не имеет эффекта, если вызвана после неё.

Примечание: Имейте в виду, что Vulkan 1.1 изменяет поведение в отношении поля версии API Vulkan. В Vulkan 1.0 указание неподдерживаемой vulkanVersion приводило к отказу create() с VK_ERROR_INCOMPATIBLE_DRIVER, как предписывалось спецификацией. Начиная с Vulkan 1.1, спецификация запрещает это, драйвер должен принять любую версию, не отказываясь от создания экземпляра.

См. также apiVersion().

void QVulkanInstance::setExtensions(const QByteArrayList &extensions)

Указывает список дополнительных расширений экземпляра extensions для включения. Можно безопасно указывать и неподдерживаемые расширения, так как они будут проигнорированы, если не поддерживаются во время выполнения. Поверхностные расширения, необходимые Qt, всегда добавляются автоматически, нет необходимости включать их в этот список.

Примечание: Эту функцию можно вызвать только до create(), и она не имеет эффекта, если вызвана после неё.

См. также extensions().

void QVulkanInstance::setFlags(QVulkanInstance::Flags flags)

Настраивает поведение create() на основе предоставленных flags.

Примечание: Эту функцию можно вызвать только до create(), и она не имеет эффекта, если вызвана после неё.

См. также flags().

void QVulkanInstance::setLayers(const QByteArrayList &layers)

Указывает список слоёв экземпляра layers для включения. Можно безопасно указывать и неподдерживаемые слои, так как они будут проигнорированы, если не поддерживаются во время выполнения.

Примечание: Эту функцию можно вызвать только до create(), и она не имеет эффекта, если вызвана после неё.

См. также layers().

void QVulkanInstance::setVkInstance(VkInstance existingVkInstance)

Принуждает QVulkanInstance принять существующий дескриптор VkInstance вместо создания нового.

Примечание: existingVkInstance должен иметь как минимум VK_KHR_surface и соответствующие расширения, специфичные для WSI, VK_KHR_*_surface включенными. Для обеспечения функциональности перенаправления вывода отладки также требуется VK_EXT_debug_report.

Примечание: Эту функцию можно вызвать только до create(), и она не имеет эффекта, если вызвана после неё.

См. также vkInstance().

QVulkanInfoVector<QVulkanExtension> QVulkanInstance::supportedExtensions()

Возвращает список поддерживаемых расширений на уровне экземпляра.

Примечание: Эту функцию можно вызвать до create().

QVulkanInfoVector<QVulkanLayer> QVulkanInstance::supportedLayers()

Возвращает список поддерживаемых слоёв на уровне экземпляра.

Примечание: Эту функцию можно вызвать до create().

bool QVulkanInstance::supportsPresent(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex, QWindow *window)

Возвращает true, если семейство очередей с queueFamilyIndex внутри physicalDevice поддерживает представление для window.

Вызывайте эту функцию при исследовании очередей данного устройства Vulkan, чтобы определить, какая очередь может использоваться для выполнения представления.

[static] VkSurfaceKHR QVulkanInstance::surfaceForWindow(QWindow *window)

Создаёт или извлекает уже существующий VkSurfaceKHR дескриптор для данного window.

Возвращает дескриптор Vulkan-поверхности или 0 при ошибке.

VkInstance QVulkanInstance::vkInstance() const

Возвращает дескриптор VkInstance, который оборачивает этот QVulkanInstance, или nullptr если create() ещё не был успешно вызван и никакой существующий экземпляр не был предоставлен через setVkInstance().

См. также setVkInstance().

© The Qt Company Ltd
Licensed under the GNU Free Documentation License, Version 1.3.
https://doc.qt.io/qt-6.0/qvulkaninstance.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API