Spec-Zone.ru › Qt 5.15

Класс QVulkanInstance

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

Заголовок: #include <QVulkanInstance>
qmake: QT += gui
С момента: Qt 5.10

Этот класс был представлен в Qt 5.10.

  • Список всех членов, включая унаследованные

Публичные типы

typedef DebugFilter
перечисление Flag { NoDebugOutputRedirect }
флаги Flags

Публичные функции

… (rest of the table)
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
PFN_vkVoidFunction getInstanceProcAddr(const char *name)

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

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(). Объект затем остаётся активным до выхода из приложения.

Каждое окно QWindow на основе Vulkan должно быть связано с 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(). Большинство платформ создадут поверхность только через VK_KHR_*_surface при первом вызове 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.

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

typedef QVulkanInstance::DebugFilter

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

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

enum QVulkanInstance::Flagflags 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().

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() и она не оказывает никакого влияния, если вызывается после.

См. также 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-устройства, чтобы определить, какая очередь может использоваться для выполнения презентации.

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-5.15/qvulkaninstance.html

Spec-Zone.ru

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