From 5d313225ff76894005e0206d5f24a64cb7729d1a Mon Sep 17 00:00:00 2001 From: Corentin Wallez Date: Wed, 25 Jul 2018 13:44:28 +0200 Subject: [PATCH] Make the Vulkan backend interface use native Vulkan types This extends our Vulkan handle wrapper to have conversions from uint64_t as well as the native Vulkan types: - The dawn_wsi interface uses the uint64_t version. - The backend interface uses the native Vulkan version --- src/common/vulkan_platform.h | 67 +++++++++++++++---- src/dawn_native/vulkan/DeviceVk.cpp | 3 +- .../vulkan/NativeSwapChainImplVk.cpp | 2 +- src/dawn_native/vulkan/SwapChainVk.cpp | 2 +- src/utils/VulkanBinding.cpp | 4 +- 5 files changed, 61 insertions(+), 17 deletions(-) diff --git a/src/common/vulkan_platform.h b/src/common/vulkan_platform.h index 742c805b75..69a3dd9415 100644 --- a/src/common/vulkan_platform.h +++ b/src/common/vulkan_platform.h @@ -19,6 +19,8 @@ # error "vulkan_platform.h included without the Vulkan backend enabled" #endif +#include "common/Platform.h" + #include #include @@ -31,7 +33,7 @@ // (like vulkan.h on 64 bit) but makes sure the types are different on 32 bit architectures. // Simple handle types that supports "nullptr_t" as a 0 value. -template +template class VkNonDispatchableHandle { public: // Default constructor and assigning of VK_NULL_HANDLE @@ -40,14 +42,14 @@ class VkNonDispatchableHandle { } // Use default copy constructor/assignment - VkNonDispatchableHandle(const VkNonDispatchableHandle& other) = default; - VkNonDispatchableHandle& operator=(const VkNonDispatchableHandle&) = default; + VkNonDispatchableHandle(const VkNonDispatchableHandle& other) = default; + VkNonDispatchableHandle& operator=(const VkNonDispatchableHandle&) = default; // Comparisons between handles - bool operator==(VkNonDispatchableHandle other) { + bool operator==(VkNonDispatchableHandle other) { return mHandle == other.mHandle; } - bool operator!=(VkNonDispatchableHandle other) { + bool operator!=(VkNonDispatchableHandle other) { return mHandle != other.mHandle; } @@ -59,14 +61,42 @@ class VkNonDispatchableHandle { return mHandle != 0; } - static VkNonDispatchableHandle CreateFromHandle(uint64_t handle) { + // The regular Vulkan handle type depends on the pointer width but is always 64 bits wide. + // - On 64bit it is an opaque pointer type, probably to help with type safety + // - On 32bit it is a uint64_t because pointers aren't wide enough (and non dispatchable + // handles can be optimized to not be pointer but contain GPU virtual addresses or the + // data in a packed form). + // Because of this we need two types of conversions from our handle type: to uint64_t and to + // the "native" Vulkan type that may not be an uint64_t + + static VkNonDispatchableHandle CreateFromU64(uint64_t handle) { return {handle}; } - uint64_t GetHandle() const { + uint64_t GetU64() const { return mHandle; } +#if DAWN_PLATFORM_64_BIT + static VkNonDispatchableHandle CreateFromHandle(HandleType handle) { + return CreateFromU64(static_cast(reinterpret_cast(handle))); + } + + HandleType GetHandle() const { + return mHandle; + } +#elif DAWN_PLATFORM_32_BIT + static VkNonDispatchableHandle CreateFromHandle(HandleType handle) { + return {handle}; + } + + HandleType GetHandle() const { + return mHandle; + } +#else +# error "Unsupported platform" +#endif + private: VkNonDispatchableHandle(uint64_t handle) : mHandle(handle) { } @@ -74,11 +104,23 @@ class VkNonDispatchableHandle { uint64_t mHandle = 0; }; -# define VK_DEFINE_NON_DISPATCHABLE_HANDLE(object) \ - struct VkTag##object; \ - using object = VkNonDispatchableHandle; \ - static_assert(sizeof(object) == sizeof(uint64_t), ""); \ - static_assert(alignof(object) == alignof(uint64_t), ""); +#if DAWN_PLATFORM_64_BIT +# define DAWN_DEFINE_NATIVE_NON_DISPATCHABLE_HANDLE(object) \ + using object##Native = struct object##_T*; +#elif DAWN_PLATFORM_32_BIT +# define DAWN_DEFINE_NATIVE_NON_DISPATCHABLE_HANDLE(object) using object##Native = uint64_t; +#else +# error "Unsupported platform" +#endif + +#define VK_DEFINE_NON_DISPATCHABLE_HANDLE(object) \ + struct VkTag##object; \ + DAWN_DEFINE_NATIVE_NON_DISPATCHABLE_HANDLE(object) \ + using object = VkNonDispatchableHandle; \ + static_assert(sizeof(object) == sizeof(uint64_t), ""); \ + static_assert(alignof(object) == alignof(uint64_t), ""); \ + static_assert(sizeof(object) == sizeof(object##Native), ""); \ + static_assert(alignof(object) == alignof(object##Native), ""); # include @@ -88,7 +130,6 @@ class VkNonDispatchableHandle { # define VK_NULL_HANDLE nullptr // Remove windows.h macros after vulkan_platform's include of windows.h -#include "common/Platform.h" #if defined(DAWN_PLATFORM_WINDOWS) # include "common/windows_with_undefs.h" #endif diff --git a/src/dawn_native/vulkan/DeviceVk.cpp b/src/dawn_native/vulkan/DeviceVk.cpp index 75eb4a38e4..0c186f5d5b 100644 --- a/src/dawn_native/vulkan/DeviceVk.cpp +++ b/src/dawn_native/vulkan/DeviceVk.cpp @@ -67,8 +67,9 @@ namespace dawn_native { namespace vulkan { return backendDevice->GetInstance(); } - dawnSwapChainImplementation CreateNativeSwapChainImpl(dawnDevice device, VkSurfaceKHR surface) { + dawnSwapChainImplementation CreateNativeSwapChainImpl(dawnDevice device, VkSurfaceKHRNative surfaceNative) { Device* backendDevice = reinterpret_cast(device); + VkSurfaceKHR surface = VkSurfaceKHR::CreateFromHandle(surfaceNative); dawnSwapChainImplementation impl; impl = CreateSwapChainImplementation(new NativeSwapChainImpl(backendDevice, surface)); diff --git a/src/dawn_native/vulkan/NativeSwapChainImplVk.cpp b/src/dawn_native/vulkan/NativeSwapChainImplVk.cpp index f5271348c1..a49aaffde9 100644 --- a/src/dawn_native/vulkan/NativeSwapChainImplVk.cpp +++ b/src/dawn_native/vulkan/NativeSwapChainImplVk.cpp @@ -171,7 +171,7 @@ namespace dawn_native { namespace vulkan { ASSERT(false); } - nextTexture->texture.u64 = mSwapChainImages[mLastImageIndex].GetHandle(); + nextTexture->texture.u64 = mSwapChainImages[mLastImageIndex].GetU64(); mDevice->AddWaitSemaphore(semaphore); return DAWN_SWAP_CHAIN_NO_ERROR; diff --git a/src/dawn_native/vulkan/SwapChainVk.cpp b/src/dawn_native/vulkan/SwapChainVk.cpp index 9e4293ee3f..658479c68a 100644 --- a/src/dawn_native/vulkan/SwapChainVk.cpp +++ b/src/dawn_native/vulkan/SwapChainVk.cpp @@ -41,7 +41,7 @@ namespace dawn_native { namespace vulkan { return nullptr; } - VkImage nativeTexture = VkImage::CreateFromHandle(next.texture.u64); + VkImage nativeTexture = VkImage::CreateFromU64(next.texture.u64); return new Texture(builder, nativeTexture); } diff --git a/src/utils/VulkanBinding.cpp b/src/utils/VulkanBinding.cpp index 58f25c7ab9..1aece25740 100644 --- a/src/utils/VulkanBinding.cpp +++ b/src/utils/VulkanBinding.cpp @@ -15,9 +15,11 @@ #include "utils/BackendBinding.h" #include "common/Assert.h" -#include "common/vulkan_platform.h" #include "dawn/dawn_wsi.h" +#include + +// Include GLFW after Vulkan so that it declares the Vulkan-specific functions #include "GLFW/glfw3.h" #include