Spec-Zone.ru › Qt 5.13

Класс QVulkanInstance

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

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

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

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

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

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

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

QVulkanInstance()
~QVulkanInstance()
QVersionNumber apiVersion() const
bool create()
void destroy()
QVulkanDeviceFunctions * deviceFunctions(int device)
int errorCode() const
QByteArrayList extensions() const
QVulkanInstance::Flags flags() const
QVulkanFunctions * functions() const
PFN_vkVoidFunction getInstanceProcAddr(const char *name)
bool isValid() const
QByteArrayList layers() const
void presentQueued(QWindow *window)
void resetDeviceFunctions(int device)
void setApiVersion(const QVersionNumber &vulkanVersion)
void setExtensions(const QByteArrayList &extensions)
void setFlags(QVulkanInstance::Flags flags)
void setLayers(const QByteArrayList &layers)
void setVkInstance(int existingVkInstance)
QVulkanInfoVector<QVulkanExtension> supportedExtensions()
QVulkanInfoVector<QVulkanLayer> supportedLayers()
bool supportsPresent(int physicalDevice, uint32_t queueFamilyIndex, QWindow *window)
int vkInstance() 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(). Затем объект остаётся активным до выхода из приложения.

Каждое окно 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.

END_OF_DOCUMENT_MARKER

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

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

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

Получение нативного Vulkan Surface для окна

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

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

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

Отладка

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

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

Пример

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

    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.

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

enum 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(int device)

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

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

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

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

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

int 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().

bool QVulkanInstance::isValid() const

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

QByteArrayList QVulkanInstance::layers() const

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

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

void QVulkanInstance::presentQueued(QWindow *window)

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

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

void QVulkanInstance::resetDeviceFunctions(int 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(int 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(int physicalDevice, uint32_t queueFamilyIndex, QWindow *window)

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

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

VkSurfaceKHR QVulkanInstance::surfaceForWindow(QWindow *window)

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

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

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

Spec-Zone.ru

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