From 3fb0b56c1081a2666986bd4a162224bd7d62d834 Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Mon, 15 Mar 2021 15:47:54 +0100 Subject: [PATCH] Add Vulkan support on Switch --- Source/Engine/Graphics/Graphics.Build.cs | 2 +- Source/Engine/Graphics/Graphics.cpp | 8 ++++++++ .../GraphicsDevice/Vulkan/CmdBufferVulkan.cpp | 6 +++++- .../GraphicsDevice/Vulkan/GPUDeviceVulkan.cpp | 20 +++++++++++++++++-- .../Vulkan/GraphicsDeviceVulkan.Build.cs | 10 +++++++++- .../Vulkan/IncludeVulkanHeaders.h | 15 ++++++++++++++ .../Vulkan/RenderToolsVulkan.cpp | 2 ++ .../GraphicsDevice/Vulkan/VulkanPlatform.h | 2 ++ 8 files changed, 60 insertions(+), 5 deletions(-) diff --git a/Source/Engine/Graphics/Graphics.Build.cs b/Source/Engine/Graphics/Graphics.Build.cs index 7d7f49d3d..82e279360 100644 --- a/Source/Engine/Graphics/Graphics.Build.cs +++ b/Source/Engine/Graphics/Graphics.Build.cs @@ -76,7 +76,7 @@ public class Graphics : EngineModule options.PrivateDependencies.Add("GraphicsDeviceVulkan"); break; case TargetPlatform.Switch: - options.PrivateDependencies.Add("GraphicsDeviceNull"); // TODO: use Vulkan on Switch + options.PrivateDependencies.Add("GraphicsDeviceVulkan"); break; default: throw new InvalidPlatformException(options.Platform.Target); } diff --git a/Source/Engine/Graphics/Graphics.cpp b/Source/Engine/Graphics/Graphics.cpp index 69170dca0..292e6c570 100644 --- a/Source/Engine/Graphics/Graphics.cpp +++ b/Source/Engine/Graphics/Graphics.cpp @@ -171,6 +171,14 @@ bool GraphicsService::Init() device = CreateGPUDeviceVulkan(); #endif +#elif PLATFORM_SWITCH + + // Switch +#if GRAPHICS_API_VULKAN + if (!device) + device = CreateGPUDeviceVulkan(); +#endif + #elif !defined(GRAPHICS_API_NULL) #error "Platform does not support GPU devices." diff --git a/Source/Engine/GraphicsDevice/Vulkan/CmdBufferVulkan.cpp b/Source/Engine/GraphicsDevice/Vulkan/CmdBufferVulkan.cpp index f9a39574c..ac56a2a9f 100644 --- a/Source/Engine/GraphicsDevice/Vulkan/CmdBufferVulkan.cpp +++ b/Source/Engine/GraphicsDevice/Vulkan/CmdBufferVulkan.cpp @@ -43,7 +43,7 @@ void CmdBufferVulkan::End() { ASSERT(IsOutsideRenderPass()); -#if GPU_ALLOW_PROFILE_EVENTS +#if GPU_ALLOW_PROFILE_EVENTS && VK_EXT_debug_utils // End remaining events while (_eventsBegin--) vkCmdEndDebugUtilsLabelEXT(GetHandle()); @@ -89,6 +89,7 @@ void CmdBufferVulkan::AcquirePoolSet() void CmdBufferVulkan::BeginEvent(const Char* name) { +#if VK_EXT_debug_utils if (!vkCmdBeginDebugUtilsLabelEXT) return; @@ -108,15 +109,18 @@ void CmdBufferVulkan::BeginEvent(const Char* name) RenderToolsVulkan::ZeroStruct(label, VK_STRUCTURE_TYPE_DEBUG_UTILS_LABEL_EXT); label.pLabelName = buffer; vkCmdBeginDebugUtilsLabelEXT(GetHandle(), &label); +#endif } void CmdBufferVulkan::EndEvent() { +#if VK_EXT_debug_utils if (_eventsBegin == 0 || !vkCmdEndDebugUtilsLabelEXT) return; _eventsBegin--; vkCmdEndDebugUtilsLabelEXT(GetHandle()); +#endif } #endif diff --git a/Source/Engine/GraphicsDevice/Vulkan/GPUDeviceVulkan.cpp b/Source/Engine/GraphicsDevice/Vulkan/GPUDeviceVulkan.cpp index aa169e8f5..498fd3491 100644 --- a/Source/Engine/GraphicsDevice/Vulkan/GPUDeviceVulkan.cpp +++ b/Source/Engine/GraphicsDevice/Vulkan/GPUDeviceVulkan.cpp @@ -52,6 +52,8 @@ VkDebugReportCallbackEXT MsgCallback = VK_NULL_HANDLE; extern VulkanValidationLevel ValidationLevel; +#if VK_EXT_debug_report + static VKAPI_ATTR VkBool32 VKAPI_PTR DebugReportFunction(VkDebugReportFlagsEXT msgFlags, VkDebugReportObjectTypeEXT objType, uint64_t srcObject, size_t location, int32 msgCode, const char* layerPrefix, const char* msg, void* userData) { const Char* msgPrefix = TEXT("UNKNOWN"); @@ -126,6 +128,8 @@ static VKAPI_ATTR VkBool32 VKAPI_PTR DebugReportFunction(VkDebugReportFlagsEXT m return VK_FALSE; } +#endif + #if VK_EXT_debug_utils static VKAPI_ATTR VkBool32 VKAPI_PTR DebugUtilsCallback(VkDebugUtilsMessageSeverityFlagBitsEXT msgSeverity, VkDebugUtilsMessageTypeFlagsEXT msgType, const VkDebugUtilsMessengerCallbackDataEXT* callbackData, void* userData) @@ -270,6 +274,7 @@ void SetupDebugLayerCallback() if (SupportsDebugCallbackExt) #endif { +#if VK_EXT_debug_report if (vkCreateDebugReportCallbackEXT) { VkDebugReportCallbackCreateInfoEXT createInfo; @@ -303,6 +308,7 @@ void SetupDebugLayerCallback() { LOG(Warning, "GetProcAddr: Unable to find vkDbgCreateMsgCallback; debug reporting skipped!"); } +#endif } else { @@ -324,8 +330,10 @@ void RemoveDebugLayerCallback() if (MsgCallback != VK_NULL_HANDLE) #endif { +#if VK_EXT_debug_report if (vkDestroyDebugReportCallbackEXT) vkDestroyDebugReportCallbackEXT(GPUDeviceVulkan::Instance, MsgCallback, nullptr); +#endif MsgCallback = VK_NULL_HANDLE; } } @@ -1085,13 +1093,17 @@ GPUDevice* GPUDeviceVulkan::Create() } #endif + VkResult result; + +#if !PLATFORM_SWITCH // Initialize bindings - VkResult result = volkInitialize(); + result = volkInitialize(); if (result != VK_SUCCESS) { LOG(Warning, "Graphics Device init failed with error {0}", RenderToolsVulkan::GetVkErrorString(result)); return nullptr; } +#endif // Engine registration const StringAsANSI<256> appName(*Globals::ProductName); @@ -1170,10 +1182,12 @@ GPUDevice* GPUDeviceVulkan::Create() return nullptr; } +#if !PLATFORM_SWITCH // Setup bindings volkLoadInstance(Instance); +#endif - // Setup debug layer +// Setup debug layer #if VULKAN_USE_DEBUG_LAYER SetupDebugLayerCallback(); #endif @@ -1658,8 +1672,10 @@ bool GPUDeviceVulkan::Init() // Create the device VALIDATE_VULKAN_RESULT(vkCreateDevice(gpu, &deviceInfo, nullptr, &Device)); +#if !PLATFORM_SWITCH // Optimize bindings volkLoadDevice(Device); +#endif // Create queues if (graphicsQueueFamilyIndex == -1) diff --git a/Source/Engine/GraphicsDevice/Vulkan/GraphicsDeviceVulkan.Build.cs b/Source/Engine/GraphicsDevice/Vulkan/GraphicsDeviceVulkan.Build.cs index 68eb5ffcc..4779beb4f 100644 --- a/Source/Engine/GraphicsDevice/Vulkan/GraphicsDeviceVulkan.Build.cs +++ b/Source/Engine/GraphicsDevice/Vulkan/GraphicsDeviceVulkan.Build.cs @@ -108,7 +108,15 @@ public class GraphicsDeviceVulkan : GraphicsDeviceBaseModule options.PublicDefinitions.Add("GRAPHICS_API_VULKAN"); - options.PrivateDependencies.Add("volk"); options.PrivateDependencies.Add("VulkanMemoryAllocator"); + + if (options.Platform.Target == TargetPlatform.Switch) + { + options.SourcePaths.Add(Path.Combine(Globals.EngineRoot, "Source", "Platforms", "Switch", "Engine", "GraphicsDevice", "Vulkan")); + } + else + { + options.PrivateDependencies.Add("volk"); + } } } diff --git a/Source/Engine/GraphicsDevice/Vulkan/IncludeVulkanHeaders.h b/Source/Engine/GraphicsDevice/Vulkan/IncludeVulkanHeaders.h index 3e00a9e87..fec251eca 100644 --- a/Source/Engine/GraphicsDevice/Vulkan/IncludeVulkanHeaders.h +++ b/Source/Engine/GraphicsDevice/Vulkan/IncludeVulkanHeaders.h @@ -8,6 +8,19 @@ #include "Engine/Core/Math/Math.h" +#if PLATFORM_SWITCH + +#define VK_USE_PLATFORM_VI_NN 1 +#include +#undef VK_EXT_debug_utils +#undef VK_EXT_debug_report +#undef VK_EXT_validation_cache +#define VMA_DEDICATED_ALLOCATION 0 +#pragma clang diagnostic ignored "-Wpointer-bool-conversion" +#pragma clang diagnostic ignored "-Wtautological-pointer-compare" + +#else + #if PLATFORM_WIN32 #include "Engine/Platform/Win32/IncludeWindowsHeaders.h" #endif @@ -17,6 +30,8 @@ // License: MIT #include +#endif + // Use Vulkan Memory Allocator for buffer and image memory allocations // Source: https://github.com/GPUOpen-LibrariesAndSDKs/VulkanMemoryAllocator/ // License: MIT diff --git a/Source/Engine/GraphicsDevice/Vulkan/RenderToolsVulkan.cpp b/Source/Engine/GraphicsDevice/Vulkan/RenderToolsVulkan.cpp index e974396a4..d24c5742d 100644 --- a/Source/Engine/GraphicsDevice/Vulkan/RenderToolsVulkan.cpp +++ b/Source/Engine/GraphicsDevice/Vulkan/RenderToolsVulkan.cpp @@ -241,7 +241,9 @@ String RenderToolsVulkan::GetVkErrorString(VkResult result) VKERR(VK_ERROR_INCOMPATIBLE_DISPLAY_KHR); VKERR(VK_ERROR_VALIDATION_FAILED_EXT); VKERR(VK_ERROR_INVALID_SHADER_NV); +#if VK_HEADER_VERSION >= 89 VKERR(VK_ERROR_INVALID_DRM_FORMAT_MODIFIER_PLANE_LAYOUT_EXT); +#endif VKERR(VK_ERROR_FRAGMENTATION_EXT); VKERR(VK_ERROR_NOT_PERMITTED_EXT); #if VK_HEADER_VERSION < 140 diff --git a/Source/Engine/GraphicsDevice/Vulkan/VulkanPlatform.h b/Source/Engine/GraphicsDevice/Vulkan/VulkanPlatform.h index 8e585c78e..bc216190b 100644 --- a/Source/Engine/GraphicsDevice/Vulkan/VulkanPlatform.h +++ b/Source/Engine/GraphicsDevice/Vulkan/VulkanPlatform.h @@ -8,4 +8,6 @@ #include "Linux/LinuxVulkanPlatform.h" #elif PLATFORM_ANDROID #include "Android/AndroidVulkanPlatform.h" +#elif PLATFORM_SWITCH +#include "Platforms/Switch/Engine/GraphicsDevice/Vulkan/SwitchVulkanPlatform.h" #endif