Add Vulkan support on Switch

This commit is contained in:
Wojtek Figat
2021-03-15 15:47:54 +01:00
parent c930d32b2b
commit 3fb0b56c10
8 changed files with 60 additions and 5 deletions

View File

@@ -76,7 +76,7 @@ public class Graphics : EngineModule
options.PrivateDependencies.Add("GraphicsDeviceVulkan"); options.PrivateDependencies.Add("GraphicsDeviceVulkan");
break; break;
case TargetPlatform.Switch: case TargetPlatform.Switch:
options.PrivateDependencies.Add("GraphicsDeviceNull"); // TODO: use Vulkan on Switch options.PrivateDependencies.Add("GraphicsDeviceVulkan");
break; break;
default: throw new InvalidPlatformException(options.Platform.Target); default: throw new InvalidPlatformException(options.Platform.Target);
} }

View File

@@ -171,6 +171,14 @@ bool GraphicsService::Init()
device = CreateGPUDeviceVulkan(); device = CreateGPUDeviceVulkan();
#endif #endif
#elif PLATFORM_SWITCH
// Switch
#if GRAPHICS_API_VULKAN
if (!device)
device = CreateGPUDeviceVulkan();
#endif
#elif !defined(GRAPHICS_API_NULL) #elif !defined(GRAPHICS_API_NULL)
#error "Platform does not support GPU devices." #error "Platform does not support GPU devices."

View File

@@ -43,7 +43,7 @@ void CmdBufferVulkan::End()
{ {
ASSERT(IsOutsideRenderPass()); ASSERT(IsOutsideRenderPass());
#if GPU_ALLOW_PROFILE_EVENTS #if GPU_ALLOW_PROFILE_EVENTS && VK_EXT_debug_utils
// End remaining events // End remaining events
while (_eventsBegin--) while (_eventsBegin--)
vkCmdEndDebugUtilsLabelEXT(GetHandle()); vkCmdEndDebugUtilsLabelEXT(GetHandle());
@@ -89,6 +89,7 @@ void CmdBufferVulkan::AcquirePoolSet()
void CmdBufferVulkan::BeginEvent(const Char* name) void CmdBufferVulkan::BeginEvent(const Char* name)
{ {
#if VK_EXT_debug_utils
if (!vkCmdBeginDebugUtilsLabelEXT) if (!vkCmdBeginDebugUtilsLabelEXT)
return; return;
@@ -108,15 +109,18 @@ void CmdBufferVulkan::BeginEvent(const Char* name)
RenderToolsVulkan::ZeroStruct(label, VK_STRUCTURE_TYPE_DEBUG_UTILS_LABEL_EXT); RenderToolsVulkan::ZeroStruct(label, VK_STRUCTURE_TYPE_DEBUG_UTILS_LABEL_EXT);
label.pLabelName = buffer; label.pLabelName = buffer;
vkCmdBeginDebugUtilsLabelEXT(GetHandle(), &label); vkCmdBeginDebugUtilsLabelEXT(GetHandle(), &label);
#endif
} }
void CmdBufferVulkan::EndEvent() void CmdBufferVulkan::EndEvent()
{ {
#if VK_EXT_debug_utils
if (_eventsBegin == 0 || !vkCmdEndDebugUtilsLabelEXT) if (_eventsBegin == 0 || !vkCmdEndDebugUtilsLabelEXT)
return; return;
_eventsBegin--; _eventsBegin--;
vkCmdEndDebugUtilsLabelEXT(GetHandle()); vkCmdEndDebugUtilsLabelEXT(GetHandle());
#endif
} }
#endif #endif

View File

@@ -52,6 +52,8 @@ VkDebugReportCallbackEXT MsgCallback = VK_NULL_HANDLE;
extern VulkanValidationLevel ValidationLevel; 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) 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"); const Char* msgPrefix = TEXT("UNKNOWN");
@@ -126,6 +128,8 @@ static VKAPI_ATTR VkBool32 VKAPI_PTR DebugReportFunction(VkDebugReportFlagsEXT m
return VK_FALSE; return VK_FALSE;
} }
#endif
#if VK_EXT_debug_utils #if VK_EXT_debug_utils
static VKAPI_ATTR VkBool32 VKAPI_PTR DebugUtilsCallback(VkDebugUtilsMessageSeverityFlagBitsEXT msgSeverity, VkDebugUtilsMessageTypeFlagsEXT msgType, const VkDebugUtilsMessengerCallbackDataEXT* callbackData, void* userData) static VKAPI_ATTR VkBool32 VKAPI_PTR DebugUtilsCallback(VkDebugUtilsMessageSeverityFlagBitsEXT msgSeverity, VkDebugUtilsMessageTypeFlagsEXT msgType, const VkDebugUtilsMessengerCallbackDataEXT* callbackData, void* userData)
@@ -270,6 +274,7 @@ void SetupDebugLayerCallback()
if (SupportsDebugCallbackExt) if (SupportsDebugCallbackExt)
#endif #endif
{ {
#if VK_EXT_debug_report
if (vkCreateDebugReportCallbackEXT) if (vkCreateDebugReportCallbackEXT)
{ {
VkDebugReportCallbackCreateInfoEXT createInfo; VkDebugReportCallbackCreateInfoEXT createInfo;
@@ -303,6 +308,7 @@ void SetupDebugLayerCallback()
{ {
LOG(Warning, "GetProcAddr: Unable to find vkDbgCreateMsgCallback; debug reporting skipped!"); LOG(Warning, "GetProcAddr: Unable to find vkDbgCreateMsgCallback; debug reporting skipped!");
} }
#endif
} }
else else
{ {
@@ -324,8 +330,10 @@ void RemoveDebugLayerCallback()
if (MsgCallback != VK_NULL_HANDLE) if (MsgCallback != VK_NULL_HANDLE)
#endif #endif
{ {
#if VK_EXT_debug_report
if (vkDestroyDebugReportCallbackEXT) if (vkDestroyDebugReportCallbackEXT)
vkDestroyDebugReportCallbackEXT(GPUDeviceVulkan::Instance, MsgCallback, nullptr); vkDestroyDebugReportCallbackEXT(GPUDeviceVulkan::Instance, MsgCallback, nullptr);
#endif
MsgCallback = VK_NULL_HANDLE; MsgCallback = VK_NULL_HANDLE;
} }
} }
@@ -1085,13 +1093,17 @@ GPUDevice* GPUDeviceVulkan::Create()
} }
#endif #endif
VkResult result;
#if !PLATFORM_SWITCH
// Initialize bindings // Initialize bindings
VkResult result = volkInitialize(); result = volkInitialize();
if (result != VK_SUCCESS) if (result != VK_SUCCESS)
{ {
LOG(Warning, "Graphics Device init failed with error {0}", RenderToolsVulkan::GetVkErrorString(result)); LOG(Warning, "Graphics Device init failed with error {0}", RenderToolsVulkan::GetVkErrorString(result));
return nullptr; return nullptr;
} }
#endif
// Engine registration // Engine registration
const StringAsANSI<256> appName(*Globals::ProductName); const StringAsANSI<256> appName(*Globals::ProductName);
@@ -1170,10 +1182,12 @@ GPUDevice* GPUDeviceVulkan::Create()
return nullptr; return nullptr;
} }
#if !PLATFORM_SWITCH
// Setup bindings // Setup bindings
volkLoadInstance(Instance); volkLoadInstance(Instance);
#endif
// Setup debug layer // Setup debug layer
#if VULKAN_USE_DEBUG_LAYER #if VULKAN_USE_DEBUG_LAYER
SetupDebugLayerCallback(); SetupDebugLayerCallback();
#endif #endif
@@ -1658,8 +1672,10 @@ bool GPUDeviceVulkan::Init()
// Create the device // Create the device
VALIDATE_VULKAN_RESULT(vkCreateDevice(gpu, &deviceInfo, nullptr, &Device)); VALIDATE_VULKAN_RESULT(vkCreateDevice(gpu, &deviceInfo, nullptr, &Device));
#if !PLATFORM_SWITCH
// Optimize bindings // Optimize bindings
volkLoadDevice(Device); volkLoadDevice(Device);
#endif
// Create queues // Create queues
if (graphicsQueueFamilyIndex == -1) if (graphicsQueueFamilyIndex == -1)

View File

@@ -108,7 +108,15 @@ public class GraphicsDeviceVulkan : GraphicsDeviceBaseModule
options.PublicDefinitions.Add("GRAPHICS_API_VULKAN"); options.PublicDefinitions.Add("GRAPHICS_API_VULKAN");
options.PrivateDependencies.Add("volk");
options.PrivateDependencies.Add("VulkanMemoryAllocator"); 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");
}
} }
} }

View File

@@ -8,6 +8,19 @@
#include "Engine/Core/Math/Math.h" #include "Engine/Core/Math/Math.h"
#if PLATFORM_SWITCH
#define VK_USE_PLATFORM_VI_NN 1
#include <vulkan/vulkan.h>
#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 #if PLATFORM_WIN32
#include "Engine/Platform/Win32/IncludeWindowsHeaders.h" #include "Engine/Platform/Win32/IncludeWindowsHeaders.h"
#endif #endif
@@ -17,6 +30,8 @@
// License: MIT // License: MIT
#include <ThirdParty/volk/volk.h> #include <ThirdParty/volk/volk.h>
#endif
// Use Vulkan Memory Allocator for buffer and image memory allocations // Use Vulkan Memory Allocator for buffer and image memory allocations
// Source: https://github.com/GPUOpen-LibrariesAndSDKs/VulkanMemoryAllocator/ // Source: https://github.com/GPUOpen-LibrariesAndSDKs/VulkanMemoryAllocator/
// License: MIT // License: MIT

View File

@@ -241,7 +241,9 @@ String RenderToolsVulkan::GetVkErrorString(VkResult result)
VKERR(VK_ERROR_INCOMPATIBLE_DISPLAY_KHR); VKERR(VK_ERROR_INCOMPATIBLE_DISPLAY_KHR);
VKERR(VK_ERROR_VALIDATION_FAILED_EXT); VKERR(VK_ERROR_VALIDATION_FAILED_EXT);
VKERR(VK_ERROR_INVALID_SHADER_NV); VKERR(VK_ERROR_INVALID_SHADER_NV);
#if VK_HEADER_VERSION >= 89
VKERR(VK_ERROR_INVALID_DRM_FORMAT_MODIFIER_PLANE_LAYOUT_EXT); VKERR(VK_ERROR_INVALID_DRM_FORMAT_MODIFIER_PLANE_LAYOUT_EXT);
#endif
VKERR(VK_ERROR_FRAGMENTATION_EXT); VKERR(VK_ERROR_FRAGMENTATION_EXT);
VKERR(VK_ERROR_NOT_PERMITTED_EXT); VKERR(VK_ERROR_NOT_PERMITTED_EXT);
#if VK_HEADER_VERSION < 140 #if VK_HEADER_VERSION < 140

View File

@@ -8,4 +8,6 @@
#include "Linux/LinuxVulkanPlatform.h" #include "Linux/LinuxVulkanPlatform.h"
#elif PLATFORM_ANDROID #elif PLATFORM_ANDROID
#include "Android/AndroidVulkanPlatform.h" #include "Android/AndroidVulkanPlatform.h"
#elif PLATFORM_SWITCH
#include "Platforms/Switch/Engine/GraphicsDevice/Vulkan/SwitchVulkanPlatform.h"
#endif #endif