InstanceVk.h#

The PVRVk Instance class.

Includes#

  • PVRVk/DebugReportCallbackVk.h

  • PVRVk/DebugUtilsMessengerVk.h

  • PVRVk/DebugUtilsVk.h

  • PVRVk/ExtensionsVk.h

  • PVRVk/ForwardDecObjectsVk.h

  • PVRVk/LayersVk.h

  • PVRVk/PVRVkObjectBaseVk.h

  • PVRVk/PhysicalDeviceVk.h

  • PVRVk/SurfaceVk.h

Included By#

Namespaces#

Classes#

Functions#

Source Code#

#pragma once
#include "PVRVk/ExtensionsVk.h"
#include "PVRVk/PVRVkObjectBaseVk.h"
#include "PVRVk/DebugReportCallbackVk.h"
#include "PVRVk/DebugUtilsMessengerVk.h"
#include "PVRVk/DebugUtilsVk.h"
#include "PVRVk/PhysicalDeviceVk.h"
#include "PVRVk/ForwardDecObjectsVk.h"
#include "PVRVk/LayersVk.h"
#include "PVRVk/SurfaceVk.h"

namespace pvrvk {

VkBindings& getVkBindings();

struct InstanceCreateInfo
{
private:
    InstanceCreateFlags flags;
    ApplicationInfo applicationInfo;
    pvrvk::VulkanLayerList layers;
    pvrvk::VulkanExtensionList extensions;

    DebugUtilsMessengerCreateInfo debugUtilsMessengerCreateInfo;
    ValidationFeatures validationFeatures;

    bool isSafetyCritical;

public:
    InstanceCreateInfo() : flags(InstanceCreateFlags(0)) {}

    explicit InstanceCreateInfo(const ApplicationInfo& applicationInfo, const VulkanExtensionList& extensions = VulkanExtensionList(),
        const VulkanLayerList& layers = VulkanLayerList(), InstanceCreateFlags flags = InstanceCreateFlags::e_NONE,
        pvrvk::DebugUtilsMessengerCreateInfo debugUtilsMessengerCreateInfo = pvrvk::DebugUtilsMessengerCreateInfo())
        : flags(InstanceCreateFlags(flags)), applicationInfo(applicationInfo), isSafetyCritical(false)
    {
        setExtensionList(extensions);
        setLayerList(layers);
        setDebugUtilsMessengerCreateInfo(debugUtilsMessengerCreateInfo);
    }

    inline const pvrvk::DebugUtilsMessengerCreateInfo getDebugUtilsMessengerCreateInfo() const { return debugUtilsMessengerCreateInfo; }
    inline void setDebugUtilsMessengerCreateInfo(pvrvk::DebugUtilsMessengerCreateInfo& createInfo) { debugUtilsMessengerCreateInfo = createInfo; }

    inline const pvrvk::ValidationFeatures getValidationFeatures() const { return validationFeatures; }
    inline void setValidationFeatures(pvrvk::ValidationFeatures& inValidationFeatures) { this->validationFeatures = inValidationFeatures; }

    inline const InstanceCreateFlags& getFlags() const { return flags; }
    inline void setFlags(const InstanceCreateFlags& inFlags) { this->flags = inFlags; }
    inline const ApplicationInfo& getApplicationInfo() const { return applicationInfo; }
    inline void setApplicationInfo(const ApplicationInfo& inApplicationInfo) { this->applicationInfo = inApplicationInfo; }
    inline const VulkanExtensionList& getExtensionList() const { return extensions; }
    inline void setExtensionList(const VulkanExtensionList& inExtensions) { this->extensions = inExtensions; }
    inline const VulkanLayerList& getLayerList() const { return layers; }
    inline void setLayerList(const VulkanLayerList& inLayers) { this->layers = inLayers; }
    inline const bool getIsSafetyCritical() const { return isSafetyCritical; }
    inline void setIsSafetyCritical(bool inIsSafetyCritical) { this->isSafetyCritical = inIsSafetyCritical; }
};

namespace impl {
class Instance_ : public PVRVkObjectBase<VkInstance, ObjectType::e_INSTANCE>, public std::enable_shared_from_this<Instance_>
{
private:
    friend class InstanceHelperFactory_;

    class make_shared_enabler
    {
    protected:
        make_shared_enabler() {}
        friend class Instance_;
    };

    static Instance constructShared(const InstanceCreateInfo& instanceCreateInfo) { return std::make_shared<Instance_>(make_shared_enabler{}, instanceCreateInfo); }

    InstanceCreateInfo _createInfo;
    VkInstanceBindings _vkBindings;
    InstanceExtensionTable _extensionTable;
    std::vector<PhysicalDevice> _physicalDevices;

public:
    DECLARE_NO_COPY_SEMANTICS(Instance_)
    explicit Instance_(make_shared_enabler, const InstanceCreateInfo& instanceCreateInfo);

    ~Instance_()
    {
        _physicalDevices.clear();
        if (getVkHandle() != VK_NULL_HANDLE)
        {
            _vkBindings.vkDestroyInstance(getVkHandle(), nullptr);
            _vkHandle = VK_NULL_HANDLE;
        }
    }

    void retrievePhysicalDevices();

    const InstanceCreateInfo& getCreateInfo() const { return _createInfo; }

#if defined(VK_USE_PLATFORM_ANDROID_KHR)
    AndroidSurface createAndroidSurface(ANativeWindow* window, AndroidSurfaceCreateFlagsKHR flags = AndroidSurfaceCreateFlagsKHR::e_NONE)
    {
        Instance instance = shared_from_this();
        return impl::AndroidSurface_::constructShared(instance, window, flags);
    }
#endif

#if defined(VK_USE_PLATFORM_WIN32_KHR)
    Win32Surface createWin32Surface(HINSTANCE hInstance, HWND hwnd, Win32SurfaceCreateFlagsKHR flags = Win32SurfaceCreateFlagsKHR::e_NONE)
    {
        Instance instance = shared_from_this();
        return impl::Win32Surface_::constructShared(instance, hInstance, hwnd, flags);
    }
#endif

#if defined(VK_USE_PLATFORM_XCB_KHR)
    XcbSurface createXcbSurface(xcb_connection_t* connection, xcb_window_t window, XcbSurfaceCreateFlagsKHR flags = XcbSurfaceCreateFlagsKHR::e_NONE)
    {
        Instance instance = shared_from_this();
        return impl::XcbSurface_::constructShared(instance, connection, window, flags);
    }
#endif

#if defined(VK_USE_PLATFORM_XLIB_KHR)
    XlibSurface createXlibSurface(::Display* dpy, Window window, XlibSurfaceCreateFlagsKHR flags = XlibSurfaceCreateFlagsKHR::e_NONE)
    {
        Instance instance = shared_from_this();
        return impl::XlibSurface_::constructShared(instance, dpy, window, flags);
    }
#endif

#if defined(VK_USE_PLATFORM_WAYLAND_KHR)
    WaylandSurface createWaylandSurface(wl_display* display, wl_surface* surface, WaylandSurfaceCreateFlagsKHR flags = WaylandSurfaceCreateFlagsKHR::e_NONE)
    {
        Instance instance = shared_from_this();
        return impl::WaylandSurface_::constructShared(instance, display, surface, flags);
    }
#endif

#if defined(VK_USE_PLATFORM_MACOS_MVK)
    MacOSSurface createMacOSSurface(void* view)
    {
        Instance instance = shared_from_this();
        return impl::MacOSSurface_::constructShared(instance, view);
    }
#endif

    DisplayPlaneSurface createDisplayPlaneSurface(const DisplayMode& displayMode, Extent2D imageExtent, const DisplaySurfaceCreateFlagsKHR flags = DisplaySurfaceCreateFlagsKHR::e_NONE,
        uint32_t planeIndex = 0, uint32_t planeStackIndex = 0, SurfaceTransformFlagsKHR transformFlags = SurfaceTransformFlagsKHR::e_IDENTITY_BIT_KHR, float globalAlpha = 0.0f,
        DisplayPlaneAlphaFlagsKHR alphaFlags = DisplayPlaneAlphaFlagsKHR::e_PER_PIXEL_BIT_KHR)
    {
        Instance instance = shared_from_this();
        return impl::DisplayPlaneSurface_::constructShared(instance, displayMode, imageExtent, flags, planeIndex, planeStackIndex, transformFlags, globalAlpha, alphaFlags);
    }

    const VulkanExtensionList& getEnabledExtensionsList() { return _createInfo.getExtensionList(); }

    const VulkanLayerList& getEnabledLayersList() { return _createInfo.getLayerList(); }

    const InstanceExtensionTable& getEnabledExtensionTable() const { return _extensionTable; }

    inline DebugUtilsMessenger createDebugUtilsMessenger(const DebugUtilsMessengerCreateInfo& createInfo)
    {
        Instance instance = shared_from_this();
        return impl::DebugUtilsMessenger_::constructShared(instance, createInfo);
    }

    inline DebugReportCallback createDebugReportCallback(const DebugReportCallbackCreateInfo& createInfo)
    {
        Instance instance = shared_from_this();
        return impl::DebugReportCallback_::constructShared(instance, createInfo);
    }

    inline void debugReportMessage(DebugReportFlagsEXT flags, DebugReportObjectTypeEXT objectType, uint64_t object, size_t location, int32_t messageCode,
        const std::string& layerPrefix, const std::string& message)
    {
        _vkBindings.vkDebugReportMessageEXT(getVkHandle(), static_cast<VkDebugReportFlagsEXT>(flags), static_cast<VkDebugReportObjectTypeEXT>(objectType), object, location,
            messageCode, layerPrefix.c_str(), message.c_str());
    }

    inline void debugReportMessage(DebugReportFlagsEXT flags, PVRVkObjectBase object, size_t location, int32_t messageCode, const std::string& layerPrefix, const std::string& message)
    {
        debugReportMessage(flags, pvrvk::convertObjectTypeToDebugReportObjectType(object.getObjectType()),
            *static_cast<const uint64_t*>(static_cast<const void*>(object.getVkHandle())), location, messageCode, layerPrefix, message);
    }

    inline void submitDebugUtilsMessage(
        DebugUtilsMessageSeverityFlagsEXT inMessageSeverity, DebugUtilsMessageTypeFlagsEXT inMessageTypes, const DebugUtilsMessengerCallbackData& inCallbackData)
    {
        VkDebugUtilsMessengerCallbackDataEXT vkCallbackData = {};
        vkCallbackData.sType = static_cast<VkStructureType>(StructureType::e_DEBUG_UTILS_MESSENGER_CALLBACK_DATA_EXT);
        vkCallbackData.flags = static_cast<VkDebugUtilsMessengerCallbackDataFlagsEXT>(inCallbackData.getFlags());
        vkCallbackData.pMessageIdName = inCallbackData.getMessageIdName().c_str();
        vkCallbackData.messageIdNumber = inCallbackData.getMessageIdNumber();
        vkCallbackData.pMessage = inCallbackData.getMessage().c_str();

        pvrvk::ArrayOrVector<VkDebugUtilsLabelEXT, 4> vkQueueLabels(inCallbackData.getNumQueueLabels());
        pvrvk::ArrayOrVector<VkDebugUtilsLabelEXT, 4> vkCmdBufLabels(inCallbackData.getNumCmdBufLabels());
        pvrvk::ArrayOrVector<VkDebugUtilsObjectNameInfoEXT, 4> vkObjectNames(inCallbackData.getNumObjects());

        // Add queue labels
        if (inCallbackData.getNumQueueLabels())
        {
            vkCallbackData.queueLabelCount = inCallbackData.getNumQueueLabels();
            for (uint32_t i = 0; i < inCallbackData.getNumQueueLabels(); ++i)
            {
                DebugUtilsLabel queueLabel = inCallbackData.getQueueLabel(i);

                vkQueueLabels[i].sType = static_cast<VkStructureType>(StructureType::e_DEBUG_UTILS_LABEL_EXT);
                vkQueueLabels[i].pLabelName = queueLabel.getLabelName().c_str();
                vkQueueLabels[i].color[0] = queueLabel.getR();
                vkQueueLabels[i].color[1] = queueLabel.getG();
                vkQueueLabels[i].color[2] = queueLabel.getB();
                vkQueueLabels[i].color[3] = queueLabel.getA();
            }

            vkCallbackData.pQueueLabels = vkQueueLabels.get();
        }

        // Add command buffer labels
        if (inCallbackData.getNumCmdBufLabels())
        {
            vkCallbackData.cmdBufLabelCount = inCallbackData.getNumCmdBufLabels();
            for (uint32_t i = 0; i < inCallbackData.getNumCmdBufLabels(); ++i)
            {
                DebugUtilsLabel cmdBufLabel = inCallbackData.getCmdBufLabel(i);

                vkCmdBufLabels[i].sType = static_cast<VkStructureType>(StructureType::e_DEBUG_UTILS_LABEL_EXT);
                vkCmdBufLabels[i].pLabelName = cmdBufLabel.getLabelName().c_str();
                vkCmdBufLabels[i].color[0] = cmdBufLabel.getR();
                vkCmdBufLabels[i].color[1] = cmdBufLabel.getG();
                vkCmdBufLabels[i].color[2] = cmdBufLabel.getB();
                vkCmdBufLabels[i].color[3] = cmdBufLabel.getA();
            }

            vkCallbackData.pCmdBufLabels = vkCmdBufLabels.get();
        }

        // Add object names
        if (inCallbackData.getNumObjects())
        {
            vkCallbackData.objectCount = inCallbackData.getNumObjects();
            for (uint32_t i = 0; i < inCallbackData.getNumObjects(); ++i)
            {
                DebugUtilsObjectNameInfo objectName = inCallbackData.getObject(i);

                vkObjectNames[i].sType = static_cast<VkStructureType>(StructureType::e_DEBUG_UTILS_OBJECT_NAME_INFO_EXT);
                vkObjectNames[i].pObjectName = objectName.getObjectName().c_str();
                vkObjectNames[i].objectType = static_cast<VkObjectType>(objectName.getObjectType());
                vkObjectNames[i].objectHandle = objectName.getObjectHandle();
            }

            vkCallbackData.pObjects = vkObjectNames.get();
        }

        _vkBindings.vkSubmitDebugUtilsMessageEXT(
            getVkHandle(), static_cast<VkDebugUtilsMessageSeverityFlagBitsEXT>(inMessageSeverity), static_cast<VkDebugUtilsMessageTypeFlagsEXT>(inMessageTypes), &vkCallbackData);
    }

    inline const VkInstanceBindings& getVkBindings() const { return _vkBindings; }

    const std::vector<PhysicalDevice>& getPhysicalDevices() const;

    const PhysicalDevice& getPhysicalDevice(uint32_t id) const;

    PhysicalDevice& getPhysicalDevice(uint32_t id);

    uint32_t getNumPhysicalDevices() const { return static_cast<uint32_t>(_physicalDevices.size()); }
};
} // namespace impl

Instance createInstance(const InstanceCreateInfo& createInfo);
} // namespace pvrvk