From 6a2d1a9edd84eecfcea9923bec63ad24c1c7a169 Mon Sep 17 00:00:00 2001 From: niki Date: Tue, 13 Sep 2022 14:11:24 +0200 Subject: [PATCH] vulkan: use dynamic loading If Vulkan ist not available on a system the program will still run, and it will fallback to opengl. --- CMakeLists.txt | 10 +-- src/modules/graphics/vulkan/Graphics.cpp | 98 +++++---------------- src/modules/graphics/vulkan/Graphics.h | 41 +-------- src/modules/graphics/vulkan/VulkanWrapper.h | 8 -- 4 files changed, 25 insertions(+), 132 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 94f403cea..8c984e8c2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -107,7 +107,6 @@ if(MEGA) ${MEGA_SDL2MAIN} ${MEGA_SDL2} ${MEGA_ZLIB} - ${Vulkan_LIBRARIES} ) # These DLLs are moved next to the love binary in a post-build step to @@ -202,7 +201,6 @@ Please see https://github.com/love2d/megasource ${LOVE_LUA_LIBRARY} ${OGG_LIBRARY} ${ZLIB_LIBRARY} - ${Vulkan_LIBRARIES} ) if(LOVE_JIT) @@ -613,16 +611,12 @@ set(LOVE_SRC_MODULE_GRAPHICS_VULKAN src/modules/graphics/vulkan/Texture.cpp src/modules/graphics/vulkan/Vulkan.h src/modules/graphics/vulkan/Vulkan.cpp + src/modules/graphics/vulkan/volk.h + src/modules/graphics/vulkan/volk.cpp src/modules/graphics/vulkan/vk_mem_alloc.h src/modules/graphics/vulkan/UseVMA.cpp src/modules/graphics/vulkan/VulkanWrapper.h) -if(ANDROID) - set(LOVE_SRC_MODULE_GRAPHICS_VULKAN ${LOVE_SRC_MODULE_GRAPHICS_VULKAN} - src/modules/graphics/vulkan/volk.h - src/modules/graphics/vulkan/volk.cpp) -endif() - set(LOVE_SRC_MODULE_GRAPHICS ${LOVE_SRC_MODULE_GRAPHICS_ROOT} ${LOVE_SRC_MODULE_GRAPHICS_OPENGL} diff --git a/src/modules/graphics/vulkan/Graphics.cpp b/src/modules/graphics/vulkan/Graphics.cpp index ff774e534..452d6d567 100644 --- a/src/modules/graphics/vulkan/Graphics.cpp +++ b/src/modules/graphics/vulkan/Graphics.cpp @@ -63,6 +63,13 @@ const VmaAllocator Graphics::getVmaAllocator() const return vmaAllocator; } +Graphics::Graphics() { + auto result = volkInitialize(); + if (result != VK_SUCCESS) { + throw love::Exception("could not initialize volk"); + } +} + Graphics::~Graphics() { // We already cleaned those up by clearing out batchedDrawBuffers. @@ -498,7 +505,7 @@ void Graphics::setFrontFaceWinding(Winding winding) states.back().winding = winding; if (optionalDeviceFeatures.extendedDynamicState) - ext.vkCmdSetFrontFaceEXT( + vkCmdSetFrontFaceEXT( commandBuffers.at(currentFrame), Vulkan::getFrontFace(winding)); } @@ -584,7 +591,7 @@ void Graphics::draw(const DrawIndexedCommand &cmd) commandBuffers.at(currentFrame), (VkBuffer)cmd.indexBuffer->getHandle(), static_cast(cmd.indexBufferOffset), - Vulkan::getVulkanIndexBufferType(cmd.indexType)) + Vulkan::getVulkanIndexBufferType(cmd.indexType)); vkCmdDrawIndexed( commandBuffers.at(currentFrame), static_cast(cmd.indexCount), @@ -718,7 +725,7 @@ void Graphics::setStencilMode(StencilAction action, CompareMode compare, int val vkCmdSetStencilReference(commandBuffers.at(currentFrame), VK_STENCIL_FACE_FRONT_AND_BACK, value); if (optionalDeviceFeatures.extendedDynamicState) - ext.vkCmdSetStencilOpEXT( + vkCmdSetStencilOpEXT( commandBuffers.at(currentFrame), VK_STENCIL_FACE_FRONT_AND_BACK, VK_STENCIL_OP_KEEP, Vulkan::getStencilOp(action), @@ -737,10 +744,10 @@ void Graphics::setDepthMode(CompareMode compare, bool write) if (optionalDeviceFeatures.extendedDynamicState) { - ext.vkCmdSetDepthCompareOpEXT( + vkCmdSetDepthCompareOpEXT( commandBuffers.at(currentFrame), Vulkan::getCompareOp(compare)); - ext.vkCmdSetDepthWriteEnableEXT( + vkCmdSetDepthWriteEnableEXT( commandBuffers.at(currentFrame), Vulkan::getBool(write)); } @@ -863,19 +870,19 @@ void Graphics::initDynamicState() if (optionalDeviceFeatures.extendedDynamicState) { - ext.vkCmdSetStencilOpEXT( + vkCmdSetStencilOpEXT( commandBuffers.at(currentFrame), VK_STENCIL_FACE_FRONT_AND_BACK, VK_STENCIL_OP_KEEP, Vulkan::getStencilOp(states.back().stencil.action), VK_STENCIL_OP_KEEP, Vulkan::getCompareOp(states.back().stencil.compare)); - ext.vkCmdSetDepthCompareOpEXT( + vkCmdSetDepthCompareOpEXT( commandBuffers.at(currentFrame), Vulkan::getCompareOp(states.back().depthTest)); - ext.vkCmdSetDepthWriteEnableEXT( + vkCmdSetDepthWriteEnableEXT( commandBuffers.at(currentFrame), Vulkan::getBool(states.back().depthWrite)); - ext.vkCmdSetFrontFaceEXT( + vkCmdSetFrontFaceEXT( commandBuffers.at(currentFrame), Vulkan::getFrontFace(states.back().winding)); } } @@ -1131,9 +1138,7 @@ void Graphics::createVulkanInstance() if (vkCreateInstance(&createInfo, nullptr, &instance) != VK_SUCCESS) throw love::Exception("couldn't create vulkan instance"); -#ifdef LOVE_ANDROID volkLoadInstance(instance); -#endif } bool Graphics::checkValidationSupport() @@ -1345,7 +1350,7 @@ void Graphics::createLogicalDevice() optionalDeviceFeatures.memoryBudget = false; if (optionalDeviceFeatures.spirv14 && !optionalDeviceFeatures.shaderFloatControls) optionalDeviceFeatures.spirv14 = false; - if (optionalDeviceFeatures.spirv14 && VK_API_VERSION_1_1 > vulkanApiVersion) + if (optionalDeviceFeatures.spirv14 && vulkanApiVersion < VK_API_VERSION_1_1) optionalDeviceFeatures.spirv14 = false; VkPhysicalDeviceFeatures deviceFeatures{}; @@ -1373,6 +1378,8 @@ void Graphics::createLogicalDevice() enabledExtensions.push_back(VK_KHR_SHADER_FLOAT_CONTROLS_EXTENSION_NAME); if (optionalDeviceFeatures.spirv14) enabledExtensions.push_back(VK_KHR_SPIRV_1_4_EXTENSION_NAME); + if (vulkanApiVersion >= VK_API_VERSION_1_1) + enabledExtensions.push_back(VK_KHR_BIND_MEMORY_2_EXTENSION_NAME); createInfo.enabledExtensionCount = static_cast(enabledExtensions.size()); createInfo.ppEnabledExtensionNames = enabledExtensions.data(); @@ -1395,67 +1402,10 @@ void Graphics::createLogicalDevice() if (vkCreateDevice(physicalDevice, &createInfo, nullptr, &device) != VK_SUCCESS) throw love::Exception("failed to create logical device"); -#ifdef LOVE_ANDROID volkLoadDevice(device); -#endif vkGetDeviceQueue(device, indices.graphicsFamily.value(), 0, &graphicsQueue); vkGetDeviceQueue(device, indices.presentFamily.value(), 0, &presentQueue); - - if (optionalDeviceFeatures.extendedDynamicState) - { -#ifdef LOVE_ANDROID - ext.vkCmdSetCullModeEXT = vkCmdSetCullModeEXT; - ext.vkCmdSetDepthBoundsTestEnableEXT = vkCmdSetDepthBoundsTestEnableEXT; - ext.vkCmdSetDepthBoundsTestEnableEXT = vkCmdSetCullModeEXT; - ext.vkCmdSetDepthTestEnableEXT = vkCmdSetDepthTestEnableEXT; - ext.vkCmdSetDepthWriteEnableEXT = vkCmdSetDepthWriteEnableEXT; - ext.vkCmdSetFrontFaceEXT = vkCmdSetFrontFaceEXT; - ext.vkCmdSetPrimitiveTopologyEXT = vkCmdSetPrimitiveTopologyEXT; - ext.vkCmdSetScissorWithCountEXT = vkCmdSetScissorWithCountEXT; - ext.vkCmdSetStencilOpEXT = vkCmdSetStencilOpEXT; - ext.vkCmdSetStencilTestEnableEXT = vkCmdSetStencilTestEnableEXT; - ext.vkCmdSetViewportWithCountEXT = vkCmdSetViewportWithCountEXT; -#else - ext.vkCmdSetCullModeEXT = (PFN_vkCmdSetCullModeEXT)vkGetDeviceProcAddr(device, "vkCmdSetCullModeEXT"); - ext.vkCmdSetDepthBoundsTestEnableEXT = (PFN_vkCmdSetDepthBoundsTestEnableEXT)vkGetDeviceProcAddr(device, "vkCmdSetDepthBoundsTestEnableEXT"); - ext.vkCmdSetDepthCompareOpEXT = (PFN_vkCmdSetDepthCompareOpEXT)vkGetDeviceProcAddr(device, "vkCmdSetDepthCompareOpEXT"); - ext.vkCmdSetDepthTestEnableEXT = (PFN_vkCmdSetDepthTestEnableEXT)vkGetDeviceProcAddr(device, "vkCmdSetDepthTestEnableEXT"); - ext.vkCmdSetDepthWriteEnableEXT = (PFN_vkCmdSetDepthWriteEnableEXT)vkGetDeviceProcAddr(device, "vkCmdSetDepthWriteEnableEXT"); - ext.vkCmdSetFrontFaceEXT = (PFN_vkCmdSetFrontFaceEXT)vkGetDeviceProcAddr(device, "vkCmdSetFrontFaceEXT"); - ext.vkCmdSetPrimitiveTopologyEXT = (PFN_vkCmdSetPrimitiveTopologyEXT)vkGetDeviceProcAddr(device, "vkCmdSetPrimitiveTopologyEXT"); - ext.vkCmdSetScissorWithCountEXT = (PFN_vkCmdSetScissorWithCountEXT)vkGetDeviceProcAddr(device, "vkCmdSetScissorWithCountEXT"); - ext.vkCmdSetStencilOpEXT = (PFN_vkCmdSetStencilOpEXT)vkGetDeviceProcAddr(device, "vkCmdSetStencilOpEXT"); - ext.vkCmdSetStencilTestEnableEXT = (PFN_vkCmdSetStencilTestEnableEXT)vkGetDeviceProcAddr(device, "vkCmdSetStencilTestEnableEXT"); - ext.vkCmdSetViewportWithCountEXT = (PFN_vkCmdSetViewportWithCountEXT)vkGetDeviceProcAddr(device, "vkCmdSetViewportWithCountEXT"); -#endif - } - - if (optionalDeviceFeatures.memoryRequirements2) - { -#ifdef LOVE_ANDROID - ext.vkGetBufferMemoryRequirements2KHR = vkGetBufferMemoryRequirements2KHR; - ext.vkGetImageMemoryRequirements2KHR = vkGetImageMemoryRequirements2KHR; - ext.vkGetImageSparseMemoryRequirements2KHR = vkGetImageSparseMemoryRequirements2KHR; -#else - ext.vkGetBufferMemoryRequirements2KHR = (PFN_vkGetBufferMemoryRequirements2KHR)vkGetDeviceProcAddr(device, "vkGetBufferMemoryRequirements2KHR"); - ext.vkGetImageMemoryRequirements2KHR = (PFN_vkGetImageMemoryRequirements2KHR)vkGetDeviceProcAddr(device, "vkGetImageMemoryRequirements2KHR"); - ext.vkGetImageSparseMemoryRequirements2KHR = (PFN_vkGetImageSparseMemoryRequirements2KHR)vkGetDeviceProcAddr(device, "vkGetImageSparseMemoryRequirements2KHR"); -#endif - } - - if (optionalDeviceFeatures.bufferDeviceAddress) - { -#ifdef LOVE_ANDROID - ext.vkGetBufferDeviceAddressKHR = vkGetBufferDeviceAddressKHR; - ext.vkGetBufferOpaqueCaptureAddressKHR = vkGetBufferOpaqueCaptureAddressKHR; - ext.vkGetDeviceMemoryOpaqueCaptureAddressKHR = vkGetDeviceMemoryOpaqueCaptureAddressKHR; -#else - ext.vkGetBufferDeviceAddressKHR = (PFN_vkGetBufferDeviceAddressKHR)vkGetDeviceProcAddr(device, "vkGetBufferDeviceAddressKHR"); - ext.vkGetBufferOpaqueCaptureAddressKHR = (PFN_vkGetBufferOpaqueCaptureAddressKHR)vkGetDeviceProcAddr(device, "vkGetBufferOpaqueCaptureAddressKHR"); - ext.vkGetDeviceMemoryOpaqueCaptureAddressKHR = (PFN_vkGetDeviceMemoryOpaqueCaptureAddressKHR)vkGetDeviceProcAddr(device, "vkGetDeviceMemoryOpaqueCaptureAddressKHR"); -#endif - } } void Graphics::initVMA() @@ -1465,7 +1415,7 @@ void Graphics::initVMA() allocatorCreateInfo.physicalDevice = physicalDevice; allocatorCreateInfo.device = device; allocatorCreateInfo.instance = instance; -#ifdef LOVE_ANDROID + VmaVulkanFunctions vulkanFunctions{}; vulkanFunctions.vkGetInstanceProcAddr = vkGetInstanceProcAddr; @@ -1498,12 +1448,6 @@ void Graphics::initVMA() vulkanFunctions.vkGetDeviceImageMemoryRequirements = vkGetDeviceImageMemoryRequirements; allocatorCreateInfo.pVulkanFunctions = &vulkanFunctions; -#else - VmaVulkanFunctions vulkanFunctions{}; - vulkanFunctions.vkGetInstanceProcAddr = &vkGetInstanceProcAddr; - vulkanFunctions.vkGetDeviceProcAddr = &vkGetDeviceProcAddr; - allocatorCreateInfo.pVulkanFunctions = &vulkanFunctions; -#endif if (vmaCreateAllocator(&allocatorCreateInfo, &vmaAllocator) != VK_SUCCESS) throw love::Exception("failed to create vma allocator"); @@ -2030,7 +1974,7 @@ void Graphics::prepareDraw(const VertexAttributes &attributes, const BufferBindi configuration.primitiveType = primitiveType; if (optionalDeviceFeatures.extendedDynamicState) - ext.vkCmdSetCullModeEXT(commandBuffers.at(currentFrame), Vulkan::getCullMode(cullmode)); + vkCmdSetCullModeEXT(commandBuffers.at(currentFrame), Vulkan::getCullMode(cullmode)); else { configuration.dynamicState.winding = states.back().winding; diff --git a/src/modules/graphics/vulkan/Graphics.h b/src/modules/graphics/vulkan/Graphics.h index 540c1874b..63b1c578f 100644 --- a/src/modules/graphics/vulkan/Graphics.h +++ b/src/modules/graphics/vulkan/Graphics.h @@ -132,32 +132,6 @@ struct OptionalDeviceFeatures bool spirv14 = false; }; -struct OptionalDeviceExtensionFunctions -{ - // VK_EXT_extended_dynamic_state - PFN_vkCmdSetCullModeEXT vkCmdSetCullModeEXT = nullptr; - PFN_vkCmdSetDepthBoundsTestEnableEXT vkCmdSetDepthBoundsTestEnableEXT = nullptr; - PFN_vkCmdSetDepthCompareOpEXT vkCmdSetDepthCompareOpEXT = nullptr; - PFN_vkCmdSetDepthTestEnableEXT vkCmdSetDepthTestEnableEXT = nullptr; - PFN_vkCmdSetDepthWriteEnableEXT vkCmdSetDepthWriteEnableEXT = nullptr; - PFN_vkCmdSetFrontFaceEXT vkCmdSetFrontFaceEXT = nullptr; - PFN_vkCmdSetPrimitiveTopologyEXT vkCmdSetPrimitiveTopologyEXT = nullptr; - PFN_vkCmdSetScissorWithCountEXT vkCmdSetScissorWithCountEXT = nullptr; - PFN_vkCmdSetStencilOpEXT vkCmdSetStencilOpEXT = nullptr; - PFN_vkCmdSetStencilTestEnableEXT vkCmdSetStencilTestEnableEXT = nullptr; - PFN_vkCmdSetViewportWithCountEXT vkCmdSetViewportWithCountEXT = nullptr; - - // VK_KHR_get_memory_requirements2 - PFN_vkGetBufferMemoryRequirements2KHR vkGetBufferMemoryRequirements2KHR = nullptr; - PFN_vkGetImageMemoryRequirements2KHR vkGetImageMemoryRequirements2KHR = nullptr; - PFN_vkGetImageSparseMemoryRequirements2KHR vkGetImageSparseMemoryRequirements2KHR = nullptr; - - // VK_KHR_buffer_device_address - PFN_vkGetBufferDeviceAddressKHR vkGetBufferDeviceAddressKHR = nullptr; - PFN_vkGetBufferOpaqueCaptureAddressKHR vkGetBufferOpaqueCaptureAddressKHR = nullptr; - PFN_vkGetDeviceMemoryOpaqueCaptureAddressKHR vkGetDeviceMemoryOpaqueCaptureAddressKHR = nullptr; -}; - struct GraphicsPipelineConfiguration { VkRenderPass renderPass; @@ -258,18 +232,8 @@ struct RenderpassState class Graphics final : public love::graphics::Graphics { public: -#ifdef LOVE_ANDROID - Graphics() { - auto result = volkInitialize(); - if (result != VK_SUCCESS) { - throw love::Exception("could not initialize volk"); - } - } -#else - Graphics() = default; -#endif - - virtual ~Graphics(); + Graphics(); + ~Graphics(); const char *getName() const override; const VkDevice getDevice() const; @@ -401,7 +365,6 @@ private: VkDevice device = VK_NULL_HANDLE; OptionalInstanceExtensions optionalInstanceExtensions; OptionalDeviceFeatures optionalDeviceFeatures; - OptionalDeviceExtensionFunctions ext; VkQueue graphicsQueue = VK_NULL_HANDLE; VkQueue presentQueue = VK_NULL_HANDLE; VkSurfaceKHR surface = VK_NULL_HANDLE; diff --git a/src/modules/graphics/vulkan/VulkanWrapper.h b/src/modules/graphics/vulkan/VulkanWrapper.h index 50bf1ee90..1775e4ddf 100644 --- a/src/modules/graphics/vulkan/VulkanWrapper.h +++ b/src/modules/graphics/vulkan/VulkanWrapper.h @@ -1,14 +1,6 @@ #pragma once -#include "common/config.h" - -#ifdef LOVE_ANDROID #include "volk.h" #define VMA_STATIC_VULKAN_FUNCTIONS 0 #define VMA_DYNAMIC_VULKAN_FUNCTIONS 0 -#else -#include -#define VMA_STATIC_VULKAN_FUNCTIONS 0 -#define VMA_DYNAMIC_VULKAN_FUNCTIONS 1 -#endif #include "vk_mem_alloc.h"