mirror of
https://github.com/encounter/dawn-cmake.git
synced 2025-12-16 08:27:05 +00:00
Revert "Remove VK_DEFINE_NON_DISPATCHABLE_HANDLE magic, use explicit VkHandle wrapper"
This reverts commit 4e17d5c248.
Reason for revert: broken on chromeos
Original change's description:
> Remove VK_DEFINE_NON_DISPATCHABLE_HANDLE magic, use explicit VkHandle wrapper
>
> Overriding VK_DEFINE_NON_DISPATCHABLE_HANDLE changes the function
> signatures of Vulkan functions, changing their ABI and making us
> incompatible with real drivers. This removes that magic, and replaces it
> with an explicit wrapper, VkHandle, which has much of the same
> functionality as the original VkNonDispatchableHandle.
>
> It adds definitions for dawn_native::vulkan::VkBuffer et al, which
> shadow the native ::VkBuffer et al. This retains type safety throughout
> the Vulkan backend without changing every single usage.
>
> Notably, the following things had to change:
> - An explicit conversion from VkBuffer* to ::VkBuffer* is needed for
> arrays. This is implemented as a reinterpret_cast, which is still
> safe as the new VkHandle still has the same memory layout properties
> as VkNonDispatchableHandle did.
> - When pointing to a VkHandle as an output pointer, it's now necessary
> to explicitly get the native ::VkBuffer (via operator*) and point to it.
>
> Bug: chromium:1046362
> Change-Id: I9c5691b6e295aca1b46d4e3d0203956e4d570285
> Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/15580
> Reviewed-by: Austin Eng <enga@chromium.org>
> Reviewed-by: Kai Ninomiya <kainino@chromium.org>
> Commit-Queue: Kai Ninomiya <kainino@chromium.org>
TBR=cwallez@chromium.org,kainino@chromium.org,enga@chromium.org
Change-Id: I500df2e34fd0f245ad04c517ff028ddd7bb5a2bf
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Bug: chromium:1046362
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/15620
Reviewed-by: Kai Ninomiya <kainino@chromium.org>
Commit-Queue: Kai Ninomiya <kainino@chromium.org>
This commit is contained in:
committed by
Commit Bot service account
parent
4e17d5c248
commit
f28d0ae614
@@ -18,9 +18,6 @@
|
||||
#if !defined(DAWN_ENABLE_BACKEND_VULKAN)
|
||||
# error "vulkan_platform.h included without the Vulkan backend enabled"
|
||||
#endif
|
||||
#if defined(VULKAN_CORE_H_)
|
||||
# error "vulkan.h included before vulkan_platform.h"
|
||||
#endif
|
||||
|
||||
#include "common/Platform.h"
|
||||
|
||||
@@ -36,9 +33,10 @@
|
||||
// (like vulkan.h on 64 bit) but makes sure the types are different on 32 bit architectures.
|
||||
|
||||
#if defined(DAWN_PLATFORM_64_BIT)
|
||||
# define DAWN_DEFINE_NATIVE_NON_DISPATCHABLE_HANDLE(object) using object = struct object##_T*;
|
||||
# define DAWN_DEFINE_NATIVE_NON_DISPATCHABLE_HANDLE(object) \
|
||||
using object##Native = struct object##_T*;
|
||||
#elif defined(DAWN_PLATFORM_32_BIT)
|
||||
# define DAWN_DEFINE_NATIVE_NON_DISPATCHABLE_HANDLE(object) using object = uint64_t;
|
||||
# define DAWN_DEFINE_NATIVE_NON_DISPATCHABLE_HANDLE(object) using object##Native = uint64_t;
|
||||
#else
|
||||
# error "Unsupported platform"
|
||||
#endif
|
||||
@@ -55,106 +53,105 @@ DAWN_DEFINE_NATIVE_NON_DISPATCHABLE_HANDLE(VkSomeHandle)
|
||||
// One way to get the alignment inside structures of a type is to look at the alignment of it
|
||||
// wrapped in a structure. Hence VkSameHandleNativeWrappe
|
||||
|
||||
namespace dawn_native { namespace vulkan {
|
||||
template <typename T>
|
||||
struct WrapperStruct {
|
||||
T member;
|
||||
};
|
||||
|
||||
namespace detail {
|
||||
template <typename T>
|
||||
struct WrapperStruct {
|
||||
T member;
|
||||
};
|
||||
template <typename T>
|
||||
static constexpr size_t AlignOfInStruct = alignof(WrapperStruct<T>);
|
||||
|
||||
template <typename T>
|
||||
static constexpr size_t AlignOfInStruct = alignof(WrapperStruct<T>);
|
||||
static constexpr size_t kNativeVkHandleAlignment = AlignOfInStruct<VkSomeHandleNative>;
|
||||
static constexpr size_t kUint64Alignment = AlignOfInStruct<VkSomeHandleNative>;
|
||||
|
||||
static constexpr size_t kNativeVkHandleAlignment = AlignOfInStruct<VkSomeHandle>;
|
||||
static constexpr size_t kUint64Alignment = AlignOfInStruct<uint64_t>;
|
||||
|
||||
// Simple handle types that supports "nullptr_t" as a 0 value.
|
||||
template <typename Tag, typename HandleType>
|
||||
class alignas(detail::kNativeVkHandleAlignment) VkHandle {
|
||||
public:
|
||||
// Default constructor and assigning of VK_NULL_HANDLE
|
||||
VkHandle() = default;
|
||||
VkHandle(std::nullptr_t) {
|
||||
}
|
||||
|
||||
// Use default copy constructor/assignment
|
||||
VkHandle(const VkHandle<Tag, HandleType>& other) = default;
|
||||
VkHandle& operator=(const VkHandle<Tag, HandleType>&) = default;
|
||||
|
||||
// Comparisons between handles
|
||||
bool operator==(VkHandle<Tag, HandleType> other) const {
|
||||
return mHandle == other.mHandle;
|
||||
}
|
||||
bool operator!=(VkHandle<Tag, HandleType> other) const {
|
||||
return mHandle != other.mHandle;
|
||||
}
|
||||
|
||||
// Comparisons between handles and VK_NULL_HANDLE
|
||||
bool operator==(std::nullptr_t) const {
|
||||
return mHandle == 0;
|
||||
}
|
||||
bool operator!=(std::nullptr_t) const {
|
||||
return mHandle != 0;
|
||||
}
|
||||
|
||||
// Implicit conversion to real Vulkan types.
|
||||
operator HandleType() const {
|
||||
return GetHandle();
|
||||
}
|
||||
|
||||
HandleType GetHandle() const {
|
||||
return mHandle;
|
||||
}
|
||||
|
||||
HandleType& operator*() {
|
||||
return mHandle;
|
||||
}
|
||||
|
||||
static VkHandle<Tag, HandleType> CreateFromHandle(HandleType handle) {
|
||||
return VkHandle{handle};
|
||||
}
|
||||
|
||||
private:
|
||||
explicit VkHandle(HandleType handle) : mHandle(handle) {
|
||||
}
|
||||
|
||||
HandleType mHandle = 0;
|
||||
};
|
||||
} // namespace detail
|
||||
|
||||
static constexpr std::nullptr_t VK_NULL_HANDLE = nullptr;
|
||||
|
||||
template <typename Tag, typename HandleType>
|
||||
HandleType* AsVkArray(detail::VkHandle<Tag, HandleType>* handle) {
|
||||
return reinterpret_cast<HandleType*>(handle);
|
||||
// Simple handle types that supports "nullptr_t" as a 0 value.
|
||||
template <typename Tag, typename HandleType>
|
||||
class alignas(kNativeVkHandleAlignment) VkNonDispatchableHandle {
|
||||
public:
|
||||
// Default constructor and assigning of VK_NULL_HANDLE
|
||||
VkNonDispatchableHandle() = default;
|
||||
VkNonDispatchableHandle(std::nullptr_t) : mHandle(0) {
|
||||
}
|
||||
|
||||
}} // namespace dawn_native::vulkan
|
||||
// Use default copy constructor/assignment
|
||||
VkNonDispatchableHandle(const VkNonDispatchableHandle<Tag, HandleType>& other) = default;
|
||||
VkNonDispatchableHandle& operator=(const VkNonDispatchableHandle<Tag, HandleType>&) = default;
|
||||
|
||||
#define VK_DEFINE_NON_DISPATCHABLE_HANDLE(object) \
|
||||
DAWN_DEFINE_NATIVE_NON_DISPATCHABLE_HANDLE(object) \
|
||||
namespace dawn_native { namespace vulkan { \
|
||||
using object = detail::VkHandle<struct VkTag##object, ::object>; \
|
||||
static_assert(sizeof(object) == sizeof(uint64_t), ""); \
|
||||
static_assert(alignof(object) == detail::kUint64Alignment, ""); \
|
||||
static_assert(sizeof(object) == sizeof(::object), ""); \
|
||||
static_assert(alignof(object) == detail::kNativeVkHandleAlignment, ""); \
|
||||
} \
|
||||
} // namespace dawn_native::vulkan
|
||||
// Comparisons between handles
|
||||
bool operator==(VkNonDispatchableHandle<Tag, HandleType> other) const {
|
||||
return mHandle == other.mHandle;
|
||||
}
|
||||
bool operator!=(VkNonDispatchableHandle<Tag, HandleType> other) const {
|
||||
return mHandle != other.mHandle;
|
||||
}
|
||||
|
||||
#include <vulkan/vulkan.h>
|
||||
// Comparisons between handles and VK_NULL_HANDLE
|
||||
bool operator==(std::nullptr_t) const {
|
||||
return mHandle == 0;
|
||||
}
|
||||
bool operator!=(std::nullptr_t) const {
|
||||
return mHandle != 0;
|
||||
}
|
||||
|
||||
// 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<Tag, HandleType> CreateFromU64(uint64_t handle) {
|
||||
return {handle};
|
||||
}
|
||||
|
||||
uint64_t GetU64() const {
|
||||
return mHandle;
|
||||
}
|
||||
|
||||
// Redefine VK_NULL_HANDLE for better type safety where possible.
|
||||
#undef VK_NULL_HANDLE
|
||||
#if defined(DAWN_PLATFORM_64_BIT)
|
||||
static constexpr nullptr_t VK_NULL_HANDLE = nullptr;
|
||||
static VkNonDispatchableHandle<Tag, HandleType> CreateFromHandle(HandleType handle) {
|
||||
return CreateFromU64(static_cast<uint64_t>(reinterpret_cast<intptr_t>(handle)));
|
||||
}
|
||||
|
||||
HandleType GetHandle() const {
|
||||
return mHandle;
|
||||
}
|
||||
#elif defined(DAWN_PLATFORM_32_BIT)
|
||||
static constexpr uint64_t VK_NULL_HANDLE = 0;
|
||||
static VkNonDispatchableHandle<Tag, HandleType> CreateFromHandle(HandleType handle) {
|
||||
return {handle};
|
||||
}
|
||||
|
||||
HandleType GetHandle() const {
|
||||
return mHandle;
|
||||
}
|
||||
#else
|
||||
# error "Unsupported platform"
|
||||
#endif
|
||||
|
||||
private:
|
||||
VkNonDispatchableHandle(uint64_t handle) : mHandle(handle) {
|
||||
}
|
||||
|
||||
uint64_t mHandle = 0;
|
||||
};
|
||||
|
||||
#define VK_DEFINE_NON_DISPATCHABLE_HANDLE(object) \
|
||||
struct VkTag##object; \
|
||||
DAWN_DEFINE_NATIVE_NON_DISPATCHABLE_HANDLE(object) \
|
||||
using object = VkNonDispatchableHandle<VkTag##object, object##Native>; \
|
||||
static_assert(sizeof(object) == sizeof(uint64_t), ""); \
|
||||
static_assert(alignof(object) == kUint64Alignment, ""); \
|
||||
static_assert(sizeof(object) == sizeof(object##Native), ""); \
|
||||
static_assert(alignof(object) == kNativeVkHandleAlignment, "");
|
||||
|
||||
# include <vulkan/vulkan.h>
|
||||
|
||||
// VK_NULL_HANDLE is defined to 0 but we don't want our handle type to compare to arbitrary
|
||||
// integers. Redefine VK_NULL_HANDLE to nullptr that has its own type.
|
||||
# undef VK_NULL_HANDLE
|
||||
# define VK_NULL_HANDLE nullptr
|
||||
|
||||
// Remove windows.h macros after vulkan_platform's include of windows.h
|
||||
#if defined(DAWN_PLATFORM_WINDOWS)
|
||||
# include "common/windows_with_undefs.h"
|
||||
|
||||
Reference in New Issue
Block a user