#ifndef GDEV_VULKAN_HPP #define GDEV_VULKAN_HPP #if BOO_HAS_VULKAN #include "IGraphicsDataFactory.hpp" #include "IGraphicsCommandQueue.hpp" #include "boo/IGraphicsContext.hpp" #include "GLSLMacros.hpp" #include #include #include #include #include #include "boo/graphicsdev/VulkanDispatchTable.hpp" namespace boo { struct BaseGraphicsData; struct VulkanContext { struct LayerProperties { VkLayerProperties properties; std::vector extensions; }; std::vector m_instanceLayerProperties; std::vector m_layerNames; std::vector m_instanceExtensionNames; VkInstance m_instance = VK_NULL_HANDLE; std::vector m_deviceExtensionNames; std::vector m_gpus; VkPhysicalDeviceFeatures m_features; VkPhysicalDeviceProperties m_gpuProps; VkPhysicalDeviceMemoryProperties m_memoryProperties; VkDevice m_dev; uint32_t m_queueCount; uint32_t m_graphicsQueueFamilyIndex = UINT32_MAX; std::vector m_queueProps; VkQueue m_queue = VK_NULL_HANDLE; std::mutex m_queueLock; VkDescriptorSetLayout m_descSetLayout; VkPipelineLayout m_pipelinelayout; VkRenderPass m_pass; VkCommandPool m_loadPool; VkCommandBuffer m_loadCmdBuf; VkSampler m_linearSamplers[3]; VkFormat m_displayFormat; struct Window { struct SwapChain { VkFormat m_format = VK_FORMAT_UNDEFINED; VkSwapchainKHR m_swapChain = VK_NULL_HANDLE; struct Buffer { VkImage m_image = VK_NULL_HANDLE; VkImageLayout m_layout = VK_IMAGE_LAYOUT_UNDEFINED; }; std::vector m_bufs; uint32_t m_backBuf = 0; void destroy(VkDevice dev) { m_bufs.clear(); if (m_swapChain) { vk::DestroySwapchainKHR(dev, m_swapChain, nullptr); m_swapChain = VK_NULL_HANDLE; } m_backBuf = 0; } } m_swapChains[2]; uint32_t m_activeSwapChain = 0; #if _WIN32 HWND m_hwnd = 0; bool m_fs = false; LONG m_fsStyle; LONG m_fsExStyle; RECT m_fsRect; int m_fsCountDown = 0; #endif }; std::unordered_map> m_windows; bool initVulkan(std::string_view appName); bool enumerateDevices(); void initDevice(); void initSwapChain(Window& windowCtx, VkSurfaceKHR surface, VkFormat format, VkColorSpaceKHR colorspace); struct SwapChainResize { Window& m_windowCtx; VkSurfaceKHR m_surface; VkFormat m_format; VkColorSpaceKHR m_colorspace; SWindowRect m_rect; SwapChainResize(Window& windowCtx, VkSurfaceKHR surface, VkFormat format, VkColorSpaceKHR colorspace, const SWindowRect& rect) : m_windowCtx(windowCtx), m_surface(surface), m_format(format), m_colorspace(colorspace), m_rect(rect) {} }; std::queue m_deferredResizes; std::mutex m_resizeLock; void resizeSwapChain(Window& windowCtx, VkSurfaceKHR surface, VkFormat format, VkColorSpaceKHR colorspace, const SWindowRect& rect); bool _resizeSwapChains(); }; extern VulkanContext g_VulkanContext; class VulkanDataFactory : public IGraphicsDataFactory { public: class Context : public IGraphicsDataFactory::Context { friend class VulkanDataFactoryImpl; VulkanDataFactory& m_parent; boo::ObjToken m_data; Context(VulkanDataFactory& parent); ~Context(); public: Platform platform() const {return Platform::Vulkan;} const SystemChar* platformName() const {return _S("Vulkan");} boo::ObjToken newStaticBuffer(BufferUse use, const void* data, size_t stride, size_t count); boo::ObjToken newDynamicBuffer(BufferUse use, size_t stride, size_t count); boo::ObjToken newStaticTexture(size_t width, size_t height, size_t mips, TextureFormat fmt, TextureClampMode clampMode, const void* data, size_t sz); boo::ObjToken newStaticArrayTexture(size_t width, size_t height, size_t layers, size_t mips, TextureFormat fmt, TextureClampMode clampMode, const void* data, size_t sz); boo::ObjToken newDynamicTexture(size_t width, size_t height, TextureFormat fmt, TextureClampMode clampMode); boo::ObjToken newRenderTexture(size_t width, size_t height, TextureClampMode clampMode, size_t colorBindCount, size_t depthBindCount); bool bindingNeedsVertexFormat() const {return false;} boo::ObjToken newVertexFormat(size_t elementCount, const VertexElementDescriptor* elements, size_t baseVert = 0, size_t baseInst = 0); boo::ObjToken newShaderPipeline(const char* vertSource, const char* fragSource, std::vector* vertBlobOut, std::vector* fragBlobOut, std::vector* pipelineBlob, const boo::ObjToken& vtxFmt, BlendFactor srcFac, BlendFactor dstFac, Primitive prim, ZTest depthTest, bool depthWrite, bool colorWrite, bool alphaWrite, CullMode culling); boo::ObjToken newShaderPipeline(const char* vertSource, const char* fragSource, const boo::ObjToken& vtxFmt, BlendFactor srcFac, BlendFactor dstFac, Primitive prim, ZTest depthTest, bool depthWrite, bool colorWrite, bool alphaWrite, CullMode culling) { return newShaderPipeline(vertSource, fragSource, nullptr, nullptr, nullptr, vtxFmt, srcFac, dstFac, prim, depthTest, depthWrite, colorWrite, alphaWrite, culling); } boo::ObjToken newShaderDataBinding(const boo::ObjToken& pipeline, const boo::ObjToken& vtxFormat, const boo::ObjToken& vbo, const boo::ObjToken& instVbo, const boo::ObjToken& ibo, size_t ubufCount, const boo::ObjToken* ubufs, const PipelineStage* ubufStages, const size_t* ubufOffs, const size_t* ubufSizes, size_t texCount, const boo::ObjToken* texs, const int* bindIdxs, const bool* bindDepth, size_t baseVert = 0, size_t baseInst = 0); }; }; } #endif #endif // GDEV_VULKAN_HPP