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:
Kai Ninomiya 2020-01-31 02:09:06 +00:00 committed by Commit Bot service account
parent 4e17d5c248
commit f28d0ae614
24 changed files with 1058 additions and 1083 deletions

View File

@ -18,9 +18,6 @@
#if !defined(DAWN_ENABLE_BACKEND_VULKAN) #if !defined(DAWN_ENABLE_BACKEND_VULKAN)
# error "vulkan_platform.h included without the Vulkan backend enabled" # error "vulkan_platform.h included without the Vulkan backend enabled"
#endif #endif
#if defined(VULKAN_CORE_H_)
# error "vulkan.h included before vulkan_platform.h"
#endif
#include "common/Platform.h" #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. // (like vulkan.h on 64 bit) but makes sure the types are different on 32 bit architectures.
#if defined(DAWN_PLATFORM_64_BIT) #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) #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 #else
# error "Unsupported platform" # error "Unsupported platform"
#endif #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 // 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 // wrapped in a structure. Hence VkSameHandleNativeWrappe
namespace dawn_native { namespace vulkan { template <typename T>
struct WrapperStruct {
T member;
};
namespace detail { template <typename T>
template <typename T> static constexpr size_t AlignOfInStruct = alignof(WrapperStruct<T>);
struct WrapperStruct {
T member;
};
template <typename T> static constexpr size_t kNativeVkHandleAlignment = AlignOfInStruct<VkSomeHandleNative>;
static constexpr size_t AlignOfInStruct = alignof(WrapperStruct<T>); static constexpr size_t kUint64Alignment = AlignOfInStruct<VkSomeHandleNative>;
static constexpr size_t kNativeVkHandleAlignment = AlignOfInStruct<VkSomeHandle>; // Simple handle types that supports "nullptr_t" as a 0 value.
static constexpr size_t kUint64Alignment = AlignOfInStruct<uint64_t>; template <typename Tag, typename HandleType>
class alignas(kNativeVkHandleAlignment) VkNonDispatchableHandle {
// Simple handle types that supports "nullptr_t" as a 0 value. public:
template <typename Tag, typename HandleType> // Default constructor and assigning of VK_NULL_HANDLE
class alignas(detail::kNativeVkHandleAlignment) VkHandle { VkNonDispatchableHandle() = default;
public: VkNonDispatchableHandle(std::nullptr_t) : mHandle(0) {
// 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);
} }
}} // 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) \ // Comparisons between handles
DAWN_DEFINE_NATIVE_NON_DISPATCHABLE_HANDLE(object) \ bool operator==(VkNonDispatchableHandle<Tag, HandleType> other) const {
namespace dawn_native { namespace vulkan { \ return mHandle == other.mHandle;
using object = detail::VkHandle<struct VkTag##object, ::object>; \ }
static_assert(sizeof(object) == sizeof(uint64_t), ""); \ bool operator!=(VkNonDispatchableHandle<Tag, HandleType> other) const {
static_assert(alignof(object) == detail::kUint64Alignment, ""); \ return mHandle != other.mHandle;
static_assert(sizeof(object) == sizeof(::object), ""); \ }
static_assert(alignof(object) == detail::kNativeVkHandleAlignment, ""); \
} \
} // namespace dawn_native::vulkan
#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) #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) #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 #else
# error "Unsupported platform" # error "Unsupported platform"
#endif #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 // Remove windows.h macros after vulkan_platform's include of windows.h
#if defined(DAWN_PLATFORM_WINDOWS) #if defined(DAWN_PLATFORM_WINDOWS)
# include "common/windows_with_undefs.h" # include "common/windows_with_undefs.h"

View File

@ -272,7 +272,7 @@ namespace dawn_native { namespace vulkan {
createInfo.pUserData = this; createInfo.pUserData = this;
return CheckVkSuccess(mFunctions.CreateDebugReportCallbackEXT( return CheckVkSuccess(mFunctions.CreateDebugReportCallbackEXT(
mInstance, &createInfo, nullptr, &*mDebugReportCallback), mInstance, &createInfo, nullptr, &mDebugReportCallback),
"vkCreateDebugReportcallback"); "vkCreateDebugReportcallback");
} }

View File

@ -105,7 +105,7 @@ namespace dawn_native { namespace vulkan {
Device* device = ToBackend(GetDevice()); Device* device = ToBackend(GetDevice());
DAWN_TRY(CheckVkSuccess(device->fn.CreateDescriptorSetLayout( DAWN_TRY(CheckVkSuccess(device->fn.CreateDescriptorSetLayout(
device->GetVkDevice(), &createInfo, nullptr, &*mHandle), device->GetVkDevice(), &createInfo, nullptr, &mHandle),
"CreateDescriptorSetLayout")); "CreateDescriptorSetLayout"));
// Compute the size of descriptor pools used for this layout. // Compute the size of descriptor pools used for this layout.
@ -171,7 +171,7 @@ namespace dawn_native { namespace vulkan {
VkDescriptorPool descriptorPool; VkDescriptorPool descriptorPool;
DAWN_TRY(CheckVkSuccess(device->fn.CreateDescriptorPool(device->GetVkDevice(), &createInfo, DAWN_TRY(CheckVkSuccess(device->fn.CreateDescriptorPool(device->GetVkDevice(), &createInfo,
nullptr, &*descriptorPool), nullptr, &descriptorPool),
"CreateDescriptorPool")); "CreateDescriptorPool"));
// Allocate our single set. // Allocate our single set.
@ -180,13 +180,12 @@ namespace dawn_native { namespace vulkan {
allocateInfo.pNext = nullptr; allocateInfo.pNext = nullptr;
allocateInfo.descriptorPool = descriptorPool; allocateInfo.descriptorPool = descriptorPool;
allocateInfo.descriptorSetCount = 1; allocateInfo.descriptorSetCount = 1;
allocateInfo.pSetLayouts = &*mHandle; allocateInfo.pSetLayouts = &mHandle;
VkDescriptorSet descriptorSet; VkDescriptorSet descriptorSet;
MaybeError result = MaybeError result = CheckVkSuccess(
CheckVkSuccess(device->fn.AllocateDescriptorSets(device->GetVkDevice(), &allocateInfo, device->fn.AllocateDescriptorSets(device->GetVkDevice(), &allocateInfo, &descriptorSet),
&*descriptorSet), "AllocateDescriptorSets");
"AllocateDescriptorSets");
if (result.IsError()) { if (result.IsError()) {
// On an error we can destroy the pool immediately because no command references it. // On an error we can destroy the pool immediately because no command references it.

View File

@ -17,7 +17,6 @@
#include "dawn_native/BindGroup.h" #include "dawn_native/BindGroup.h"
#include "common/vulkan_platform.h"
#include "dawn_native/vulkan/BindGroupLayoutVk.h" #include "dawn_native/vulkan/BindGroupLayoutVk.h"
namespace dawn_native { namespace vulkan { namespace dawn_native { namespace vulkan {

View File

@ -147,7 +147,7 @@ namespace dawn_native { namespace vulkan {
Device* device = ToBackend(GetDevice()); Device* device = ToBackend(GetDevice());
DAWN_TRY(CheckVkSuccess( DAWN_TRY(CheckVkSuccess(
device->fn.CreateBuffer(device->GetVkDevice(), &createInfo, nullptr, &*mHandle), device->fn.CreateBuffer(device->GetVkDevice(), &createInfo, nullptr, &mHandle),
"vkCreateBuffer")); "vkCreateBuffer"));
VkMemoryRequirements requirements; VkMemoryRequirements requirements;

View File

@ -106,7 +106,7 @@ namespace dawn_native { namespace vulkan {
? dynamicOffsets[dirtyIndex].data() ? dynamicOffsets[dirtyIndex].data()
: nullptr; : nullptr;
device->fn.CmdBindDescriptorSets(commands, bindPoint, pipelineLayout, dirtyIndex, 1, device->fn.CmdBindDescriptorSets(commands, bindPoint, pipelineLayout, dirtyIndex, 1,
&*set, dynamicOffsetCounts[dirtyIndex], &set, dynamicOffsetCounts[dirtyIndex],
dynamicOffset); dynamicOffset);
} }
} }
@ -255,14 +255,14 @@ namespace dawn_native { namespace vulkan {
createInfo.flags = 0; createInfo.flags = 0;
createInfo.renderPass = renderPassVK; createInfo.renderPass = renderPassVK;
createInfo.attachmentCount = attachmentCount; createInfo.attachmentCount = attachmentCount;
createInfo.pAttachments = AsVkArray(attachments.data()); createInfo.pAttachments = attachments.data();
createInfo.width = renderPass->width; createInfo.width = renderPass->width;
createInfo.height = renderPass->height; createInfo.height = renderPass->height;
createInfo.layers = 1; createInfo.layers = 1;
DAWN_TRY( DAWN_TRY(
CheckVkSuccess(device->fn.CreateFramebuffer(device->GetVkDevice(), &createInfo, CheckVkSuccess(device->fn.CreateFramebuffer(device->GetVkDevice(), &createInfo,
nullptr, &*framebuffer), nullptr, &framebuffer),
"CreateFramebuffer")); "CreateFramebuffer"));
// We don't reuse VkFramebuffers so mark the framebuffer for deletion as soon as the // We don't reuse VkFramebuffers so mark the framebuffer for deletion as soon as the
@ -827,7 +827,7 @@ namespace dawn_native { namespace vulkan {
VkBuffer buffer = ToBackend(cmd->buffer)->GetHandle(); VkBuffer buffer = ToBackend(cmd->buffer)->GetHandle();
VkDeviceSize offset = static_cast<VkDeviceSize>(cmd->offset); VkDeviceSize offset = static_cast<VkDeviceSize>(cmd->offset);
device->fn.CmdBindVertexBuffers(commands, cmd->slot, 1, &*buffer, &offset); device->fn.CmdBindVertexBuffers(commands, cmd->slot, 1, &buffer, &offset);
} break; } break;
default: default:

View File

@ -38,7 +38,7 @@ namespace dawn_native { namespace vulkan {
createInfo.pNext = nullptr; createInfo.pNext = nullptr;
createInfo.flags = 0; createInfo.flags = 0;
createInfo.layout = ToBackend(descriptor->layout)->GetHandle(); createInfo.layout = ToBackend(descriptor->layout)->GetHandle();
createInfo.basePipelineHandle = ::VK_NULL_HANDLE; createInfo.basePipelineHandle = VK_NULL_HANDLE;
createInfo.basePipelineIndex = -1; createInfo.basePipelineIndex = -1;
createInfo.stage.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; createInfo.stage.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
@ -51,8 +51,8 @@ namespace dawn_native { namespace vulkan {
Device* device = ToBackend(GetDevice()); Device* device = ToBackend(GetDevice());
return CheckVkSuccess( return CheckVkSuccess(
device->fn.CreateComputePipelines(device->GetVkDevice(), ::VK_NULL_HANDLE, 1, device->fn.CreateComputePipelines(device->GetVkDevice(), VK_NULL_HANDLE, 1, &createInfo,
&createInfo, nullptr, &*mHandle), nullptr, &mHandle),
"CreateComputePipeline"); "CreateComputePipeline");
} }

View File

@ -272,13 +272,13 @@ namespace dawn_native { namespace vulkan {
submitInfo.pNext = nullptr; submitInfo.pNext = nullptr;
submitInfo.waitSemaphoreCount = submitInfo.waitSemaphoreCount =
static_cast<uint32_t>(mRecordingContext.waitSemaphores.size()); static_cast<uint32_t>(mRecordingContext.waitSemaphores.size());
submitInfo.pWaitSemaphores = AsVkArray(mRecordingContext.waitSemaphores.data()); submitInfo.pWaitSemaphores = mRecordingContext.waitSemaphores.data();
submitInfo.pWaitDstStageMask = dstStageMasks.data(); submitInfo.pWaitDstStageMask = dstStageMasks.data();
submitInfo.commandBufferCount = 1; submitInfo.commandBufferCount = 1;
submitInfo.pCommandBuffers = &mRecordingContext.commandBuffer; submitInfo.pCommandBuffers = &mRecordingContext.commandBuffer;
submitInfo.signalSemaphoreCount = submitInfo.signalSemaphoreCount =
static_cast<uint32_t>(mRecordingContext.signalSemaphores.size()); static_cast<uint32_t>(mRecordingContext.signalSemaphores.size());
submitInfo.pSignalSemaphores = AsVkArray(mRecordingContext.signalSemaphores.data()); submitInfo.pSignalSemaphores = mRecordingContext.signalSemaphores.data();
VkFence fence = VK_NULL_HANDLE; VkFence fence = VK_NULL_HANDLE;
DAWN_TRY_ASSIGN(fence, GetUnusedFence()); DAWN_TRY_ASSIGN(fence, GetUnusedFence());
@ -474,7 +474,7 @@ namespace dawn_native { namespace vulkan {
ResultOrError<VkFence> Device::GetUnusedFence() { ResultOrError<VkFence> Device::GetUnusedFence() {
if (!mUnusedFences.empty()) { if (!mUnusedFences.empty()) {
VkFence fence = mUnusedFences.back(); VkFence fence = mUnusedFences.back();
DAWN_TRY(CheckVkSuccess(fn.ResetFences(mVkDevice, 1, &*fence), "vkResetFences")); DAWN_TRY(CheckVkSuccess(fn.ResetFences(mVkDevice, 1, &fence), "vkResetFences"));
mUnusedFences.pop_back(); mUnusedFences.pop_back();
return fence; return fence;
@ -486,7 +486,7 @@ namespace dawn_native { namespace vulkan {
createInfo.flags = 0; createInfo.flags = 0;
VkFence fence = VK_NULL_HANDLE; VkFence fence = VK_NULL_HANDLE;
DAWN_TRY(CheckVkSuccess(fn.CreateFence(mVkDevice, &createInfo, nullptr, &*fence), DAWN_TRY(CheckVkSuccess(fn.CreateFence(mVkDevice, &createInfo, nullptr, &fence),
"vkCreateFence")); "vkCreateFence"));
return fence; return fence;
@ -539,7 +539,7 @@ namespace dawn_native { namespace vulkan {
createInfo.queueFamilyIndex = mQueueFamily; createInfo.queueFamilyIndex = mQueueFamily;
DAWN_TRY(CheckVkSuccess(fn.CreateCommandPool(mVkDevice, &createInfo, nullptr, DAWN_TRY(CheckVkSuccess(fn.CreateCommandPool(mVkDevice, &createInfo, nullptr,
&*mRecordingContext.commandPool), &mRecordingContext.commandPool),
"vkCreateCommandPool")); "vkCreateCommandPool"));
VkCommandBufferAllocateInfo allocateInfo; VkCommandBufferAllocateInfo allocateInfo;
@ -756,7 +756,7 @@ namespace dawn_native { namespace vulkan {
VkResult result = VkResult::WrapUnsafe(VK_TIMEOUT); VkResult result = VkResult::WrapUnsafe(VK_TIMEOUT);
do { do {
result = VkResult::WrapUnsafe( result = VkResult::WrapUnsafe(
INJECT_ERROR_OR_RUN(fn.WaitForFences(mVkDevice, 1, &*fence, true, UINT64_MAX), INJECT_ERROR_OR_RUN(fn.WaitForFences(mVkDevice, 1, &fence, true, UINT64_MAX),
VK_ERROR_DEVICE_LOST)); VK_ERROR_DEVICE_LOST));
} while (result == VK_TIMEOUT); } while (result == VK_TIMEOUT);

View File

@ -136,7 +136,7 @@ namespace dawn_native { namespace vulkan {
createInfo.oldSwapchain = oldSwapchain; createInfo.oldSwapchain = oldSwapchain;
if (mDevice->fn.CreateSwapchainKHR(mDevice->GetVkDevice(), &createInfo, nullptr, if (mDevice->fn.CreateSwapchainKHR(mDevice->GetVkDevice(), &createInfo, nullptr,
&*mSwapChain) != VK_SUCCESS) { &mSwapChain) != VK_SUCCESS) {
ASSERT(false); ASSERT(false);
} }
@ -151,7 +151,7 @@ namespace dawn_native { namespace vulkan {
ASSERT(count >= mConfig.minImageCount); ASSERT(count >= mConfig.minImageCount);
mSwapChainImages.resize(count); mSwapChainImages.resize(count);
if (mDevice->fn.GetSwapchainImagesKHR(mDevice->GetVkDevice(), mSwapChain, &count, if (mDevice->fn.GetSwapchainImagesKHR(mDevice->GetVkDevice(), mSwapChain, &count,
AsVkArray(mSwapChainImages.data())) != VK_SUCCESS) { mSwapChainImages.data()) != VK_SUCCESS) {
ASSERT(false); ASSERT(false);
} }
@ -168,7 +168,7 @@ namespace dawn_native { namespace vulkan {
barrier.newLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR; barrier.newLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
barrier.srcQueueFamilyIndex = 0; barrier.srcQueueFamilyIndex = 0;
barrier.dstQueueFamilyIndex = 0; barrier.dstQueueFamilyIndex = 0;
barrier.image = *image; barrier.image = image;
barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
barrier.subresourceRange.baseMipLevel = 0; barrier.subresourceRange.baseMipLevel = 0;
barrier.subresourceRange.levelCount = 1; barrier.subresourceRange.levelCount = 1;
@ -197,22 +197,18 @@ namespace dawn_native { namespace vulkan {
createInfo.pNext = nullptr; createInfo.pNext = nullptr;
createInfo.flags = 0; createInfo.flags = 0;
if (mDevice->fn.CreateSemaphore(mDevice->GetVkDevice(), &createInfo, nullptr, if (mDevice->fn.CreateSemaphore(mDevice->GetVkDevice(), &createInfo, nullptr,
&*semaphore) != VK_SUCCESS) { &semaphore) != VK_SUCCESS) {
ASSERT(false); ASSERT(false);
} }
} }
if (mDevice->fn.AcquireNextImageKHR(mDevice->GetVkDevice(), mSwapChain, if (mDevice->fn.AcquireNextImageKHR(mDevice->GetVkDevice(), mSwapChain,
std::numeric_limits<uint64_t>::max(), semaphore, std::numeric_limits<uint64_t>::max(), semaphore,
VkFence{}, &mLastImageIndex) != VK_SUCCESS) { VK_NULL_HANDLE, &mLastImageIndex) != VK_SUCCESS) {
ASSERT(false); ASSERT(false);
} }
nextTexture->texture.u64 = nextTexture->texture.u64 = mSwapChainImages[mLastImageIndex].GetU64();
#if defined(DAWN_PLATFORM_64_BIT)
reinterpret_cast<uint64_t>
#endif
(*mSwapChainImages[mLastImageIndex]);
mDevice->GetPendingRecordingContext()->waitSemaphores.push_back(semaphore); mDevice->GetPendingRecordingContext()->waitSemaphores.push_back(semaphore);
return DAWN_SWAP_CHAIN_NO_ERROR; return DAWN_SWAP_CHAIN_NO_ERROR;
@ -231,7 +227,7 @@ namespace dawn_native { namespace vulkan {
presentInfo.waitSemaphoreCount = 0; presentInfo.waitSemaphoreCount = 0;
presentInfo.pWaitSemaphores = nullptr; presentInfo.pWaitSemaphores = nullptr;
presentInfo.swapchainCount = 1; presentInfo.swapchainCount = 1;
presentInfo.pSwapchains = &*mSwapChain; presentInfo.pSwapchains = &mSwapChain;
presentInfo.pImageIndices = &mLastImageIndex; presentInfo.pImageIndices = &mLastImageIndex;
presentInfo.pResults = nullptr; presentInfo.pResults = nullptr;

View File

@ -48,13 +48,13 @@ namespace dawn_native { namespace vulkan {
createInfo.pNext = nullptr; createInfo.pNext = nullptr;
createInfo.flags = 0; createInfo.flags = 0;
createInfo.setLayoutCount = numSetLayouts; createInfo.setLayoutCount = numSetLayouts;
createInfo.pSetLayouts = AsVkArray(setLayouts.data()); createInfo.pSetLayouts = setLayouts.data();
createInfo.pushConstantRangeCount = 0; createInfo.pushConstantRangeCount = 0;
createInfo.pPushConstantRanges = nullptr; createInfo.pPushConstantRanges = nullptr;
Device* device = ToBackend(GetDevice()); Device* device = ToBackend(GetDevice());
return CheckVkSuccess( return CheckVkSuccess(
device->fn.CreatePipelineLayout(device->GetVkDevice(), &createInfo, nullptr, &*mHandle), device->fn.CreatePipelineLayout(device->GetVkDevice(), &createInfo, nullptr, &mHandle),
"CreatePipelineLayout"); "CreatePipelineLayout");
} }

View File

@ -191,9 +191,9 @@ namespace dawn_native { namespace vulkan {
// Create the render pass from the zillion parameters // Create the render pass from the zillion parameters
VkRenderPass renderPass; VkRenderPass renderPass;
DAWN_TRY(CheckVkSuccess(mDevice->fn.CreateRenderPass(mDevice->GetVkDevice(), &createInfo, DAWN_TRY(CheckVkSuccess(
nullptr, &*renderPass), mDevice->fn.CreateRenderPass(mDevice->GetVkDevice(), &createInfo, nullptr, &renderPass),
"CreateRenderPass")); "CreateRenderPass"));
return renderPass; return renderPass;
} }

View File

@ -495,12 +495,12 @@ namespace dawn_native { namespace vulkan {
createInfo.layout = ToBackend(GetLayout())->GetHandle(); createInfo.layout = ToBackend(GetLayout())->GetHandle();
createInfo.renderPass = renderPass; createInfo.renderPass = renderPass;
createInfo.subpass = 0; createInfo.subpass = 0;
createInfo.basePipelineHandle = VkPipeline{}; createInfo.basePipelineHandle = VK_NULL_HANDLE;
createInfo.basePipelineIndex = -1; createInfo.basePipelineIndex = -1;
return CheckVkSuccess( return CheckVkSuccess(
device->fn.CreateGraphicsPipelines(device->GetVkDevice(), VkPipelineCache{}, 1, device->fn.CreateGraphicsPipelines(device->GetVkDevice(), VK_NULL_HANDLE, 1,
&createInfo, nullptr, &*mHandle), &createInfo, nullptr, &mHandle),
"CreateGraphicsPipeline"); "CreateGraphicsPipeline");
} }

View File

@ -73,7 +73,7 @@ namespace dawn_native { namespace vulkan {
// First check OOM that we want to surface to the application. // First check OOM that we want to surface to the application.
DAWN_TRY(CheckVkOOMThenSuccess( DAWN_TRY(CheckVkOOMThenSuccess(
mDevice->fn.AllocateMemory(mDevice->GetVkDevice(), &allocateInfo, nullptr, mDevice->fn.AllocateMemory(mDevice->GetVkDevice(), &allocateInfo, nullptr,
&*allocatedMemory), &allocatedMemory),
"vkAllocateMemory")); "vkAllocateMemory"));
ASSERT(allocatedMemory != VK_NULL_HANDLE); ASSERT(allocatedMemory != VK_NULL_HANDLE);

View File

@ -87,7 +87,7 @@ namespace dawn_native { namespace vulkan {
Device* device = ToBackend(GetDevice()); Device* device = ToBackend(GetDevice());
return CheckVkSuccess( return CheckVkSuccess(
device->fn.CreateSampler(device->GetVkDevice(), &createInfo, nullptr, &*mHandle), device->fn.CreateSampler(device->GetVkDevice(), &createInfo, nullptr, &mHandle),
"CreateSampler"); "CreateSampler");
} }

View File

@ -74,7 +74,7 @@ namespace dawn_native { namespace vulkan {
Device* device = ToBackend(GetDevice()); Device* device = ToBackend(GetDevice());
return CheckVkSuccess( return CheckVkSuccess(
device->fn.CreateShaderModule(device->GetVkDevice(), &createInfo, nullptr, &*mHandle), device->fn.CreateShaderModule(device->GetVkDevice(), &createInfo, nullptr, &mHandle),
"CreateShaderModule"); "CreateShaderModule");
} }

View File

@ -36,7 +36,7 @@ namespace dawn_native { namespace vulkan {
createInfo.pQueueFamilyIndices = 0; createInfo.pQueueFamilyIndices = 0;
DAWN_TRY(CheckVkSuccess( DAWN_TRY(CheckVkSuccess(
mDevice->fn.CreateBuffer(mDevice->GetVkDevice(), &createInfo, nullptr, &*mBuffer), mDevice->fn.CreateBuffer(mDevice->GetVkDevice(), &createInfo, nullptr, &mBuffer),
"vkCreateBuffer")); "vkCreateBuffer"));
VkMemoryRequirements requirements; VkMemoryRequirements requirements;

View File

@ -47,8 +47,7 @@ namespace dawn_native { namespace vulkan {
return nullptr; return nullptr;
} }
VkImage nativeTexture = VkImage nativeTexture = VkImage::CreateFromU64(next.texture.u64);
VkImage::CreateFromHandle(reinterpret_cast<::VkImage>(next.texture.u64));
return new Texture(ToBackend(GetDevice()), descriptor, nativeTexture); return new Texture(ToBackend(GetDevice()), descriptor, nativeTexture);
} }

View File

@ -460,7 +460,7 @@ namespace dawn_native { namespace vulkan {
createInfo.usage |= VK_IMAGE_USAGE_TRANSFER_DST_BIT; createInfo.usage |= VK_IMAGE_USAGE_TRANSFER_DST_BIT;
DAWN_TRY(CheckVkSuccess( DAWN_TRY(CheckVkSuccess(
device->fn.CreateImage(device->GetVkDevice(), &createInfo, nullptr, &*mHandle), device->fn.CreateImage(device->GetVkDevice(), &createInfo, nullptr, &mHandle),
"CreateImage")); "CreateImage"));
// Create the image memory and associate it with the container // Create the image memory and associate it with the container
@ -806,7 +806,7 @@ namespace dawn_native { namespace vulkan {
createInfo.subresourceRange.layerCount = descriptor->arrayLayerCount; createInfo.subresourceRange.layerCount = descriptor->arrayLayerCount;
return CheckVkSuccess( return CheckVkSuccess(
device->fn.CreateImageView(device->GetVkDevice(), &createInfo, nullptr, &*mHandle), device->fn.CreateImageView(device->GetVkDevice(), &createInfo, nullptr, &mHandle),
"CreateImageView"); "CreateImageView");
} }

View File

@ -42,7 +42,7 @@ namespace dawn_native { namespace vulkan {
// Explicitly export this function because it uses the "native" type for surfaces while the // Explicitly export this function because it uses the "native" type for surfaces while the
// header as seen in this file uses the wrapped type. // header as seen in this file uses the wrapped type.
DAWN_NATIVE_EXPORT DawnSwapChainImplementation DAWN_NATIVE_EXPORT DawnSwapChainImplementation
CreateNativeSwapChainImpl(WGPUDevice device, ::VkSurfaceKHR surfaceNative) { CreateNativeSwapChainImpl(WGPUDevice device, VkSurfaceKHRNative surfaceNative) {
Device* backendDevice = reinterpret_cast<Device*>(device); Device* backendDevice = reinterpret_cast<Device*>(device);
VkSurfaceKHR surface = VkSurfaceKHR::CreateFromHandle(surfaceNative); VkSurfaceKHR surface = VkSurfaceKHR::CreateFromHandle(surfaceNative);

View File

@ -130,7 +130,7 @@ namespace dawn_native { namespace vulkan { namespace external_memory {
VkDeviceMemory allocatedMemory = VK_NULL_HANDLE; VkDeviceMemory allocatedMemory = VK_NULL_HANDLE;
DAWN_TRY(CheckVkSuccess(mDevice->fn.AllocateMemory(mDevice->GetVkDevice(), &allocateInfo, DAWN_TRY(CheckVkSuccess(mDevice->fn.AllocateMemory(mDevice->GetVkDevice(), &allocateInfo,
nullptr, &*allocatedMemory), nullptr, &allocatedMemory),
"vkAllocateMemory")); "vkAllocateMemory"));
return allocatedMemory; return allocatedMemory;
} }
@ -146,7 +146,7 @@ namespace dawn_native { namespace vulkan { namespace external_memory {
VkImage image; VkImage image;
DAWN_TRY(CheckVkSuccess( DAWN_TRY(CheckVkSuccess(
mDevice->fn.CreateImage(mDevice->GetVkDevice(), &createInfo, nullptr, &*image), mDevice->fn.CreateImage(mDevice->GetVkDevice(), &createInfo, nullptr, &image),
"CreateImage")); "CreateImage"));
return image; return image;
} }

View File

@ -72,7 +72,7 @@ namespace dawn_native { namespace vulkan { namespace external_semaphore {
info.flags = 0; info.flags = 0;
DAWN_TRY(CheckVkSuccess( DAWN_TRY(CheckVkSuccess(
mDevice->fn.CreateSemaphore(mDevice->GetVkDevice(), &info, nullptr, &*semaphore), mDevice->fn.CreateSemaphore(mDevice->GetVkDevice(), &info, nullptr, &semaphore),
"vkCreateSemaphore")); "vkCreateSemaphore"));
VkImportSemaphoreFdInfoKHR importSemaphoreFdInfo; VkImportSemaphoreFdInfoKHR importSemaphoreFdInfo;
@ -109,7 +109,7 @@ namespace dawn_native { namespace vulkan { namespace external_semaphore {
VkSemaphore signalSemaphore; VkSemaphore signalSemaphore;
DAWN_TRY( DAWN_TRY(
CheckVkSuccess(mDevice->fn.CreateSemaphore(mDevice->GetVkDevice(), &semaphoreCreateInfo, CheckVkSuccess(mDevice->fn.CreateSemaphore(mDevice->GetVkDevice(), &semaphoreCreateInfo,
nullptr, &*signalSemaphore), nullptr, &signalSemaphore),
"vkCreateSemaphore")); "vkCreateSemaphore"));
return signalSemaphore; return signalSemaphore;
} }

View File

@ -47,8 +47,8 @@ namespace dawn_native { namespace vulkan {
DAWN_NATIVE_EXPORT PFN_vkVoidFunction GetInstanceProcAddr(WGPUDevice device, const char* pName); DAWN_NATIVE_EXPORT PFN_vkVoidFunction GetInstanceProcAddr(WGPUDevice device, const char* pName);
DAWN_NATIVE_EXPORT DawnSwapChainImplementation DAWN_NATIVE_EXPORT DawnSwapChainImplementation CreateNativeSwapChainImpl(WGPUDevice device,
CreateNativeSwapChainImpl(WGPUDevice device, ::VkSurfaceKHR surface); VkSurfaceKHR surface);
DAWN_NATIVE_EXPORT WGPUTextureFormat DAWN_NATIVE_EXPORT WGPUTextureFormat
GetNativeSwapChainPreferredFormat(const DawnSwapChainImplementation* swapChain); GetNativeSwapChainPreferredFormat(const DawnSwapChainImplementation* swapChain);

View File

@ -32,30 +32,30 @@
// them. // them.
#define EXPECT_BUFFER_U32_EQ(expected, buffer, offset) \ #define EXPECT_BUFFER_U32_EQ(expected, buffer, offset) \
AddBufferExpectation(__FILE__, __LINE__, buffer, offset, sizeof(uint32_t), \ AddBufferExpectation(__FILE__, __LINE__, buffer, offset, sizeof(uint32_t), \
new ::detail::ExpectEq<uint32_t>(expected)) new detail::ExpectEq<uint32_t>(expected))
#define EXPECT_BUFFER_U32_RANGE_EQ(expected, buffer, offset, count) \ #define EXPECT_BUFFER_U32_RANGE_EQ(expected, buffer, offset, count) \
AddBufferExpectation(__FILE__, __LINE__, buffer, offset, sizeof(uint32_t) * count, \ AddBufferExpectation(__FILE__, __LINE__, buffer, offset, sizeof(uint32_t) * count, \
new ::detail::ExpectEq<uint32_t>(expected, count)) new detail::ExpectEq<uint32_t>(expected, count))
// Test a pixel of the mip level 0 of a 2D texture. // Test a pixel of the mip level 0 of a 2D texture.
#define EXPECT_PIXEL_RGBA8_EQ(expected, texture, x, y) \ #define EXPECT_PIXEL_RGBA8_EQ(expected, texture, x, y) \
AddTextureExpectation(__FILE__, __LINE__, texture, x, y, 1, 1, 0, 0, sizeof(RGBA8), \ AddTextureExpectation(__FILE__, __LINE__, texture, x, y, 1, 1, 0, 0, sizeof(RGBA8), \
new ::detail::ExpectEq<RGBA8>(expected)) new detail::ExpectEq<RGBA8>(expected))
#define EXPECT_TEXTURE_RGBA8_EQ(expected, texture, x, y, width, height, level, slice) \ #define EXPECT_TEXTURE_RGBA8_EQ(expected, texture, x, y, width, height, level, slice) \
AddTextureExpectation(__FILE__, __LINE__, texture, x, y, width, height, level, slice, \ AddTextureExpectation(__FILE__, __LINE__, texture, x, y, width, height, level, slice, \
sizeof(RGBA8), \ sizeof(RGBA8), \
new ::detail::ExpectEq<RGBA8>(expected, (width) * (height))) new detail::ExpectEq<RGBA8>(expected, (width) * (height)))
#define EXPECT_PIXEL_FLOAT_EQ(expected, texture, x, y) \ #define EXPECT_PIXEL_FLOAT_EQ(expected, texture, x, y) \
AddTextureExpectation(__FILE__, __LINE__, texture, x, y, 1, 1, 0, 0, sizeof(float), \ AddTextureExpectation(__FILE__, __LINE__, texture, x, y, 1, 1, 0, 0, sizeof(float), \
new ::detail::ExpectEq<float>(expected)) new detail::ExpectEq<float>(expected))
#define EXPECT_TEXTURE_FLOAT_EQ(expected, texture, x, y, width, height, level, slice) \ #define EXPECT_TEXTURE_FLOAT_EQ(expected, texture, x, y, width, height, level, slice) \
AddTextureExpectation(__FILE__, __LINE__, texture, x, y, width, height, level, slice, \ AddTextureExpectation(__FILE__, __LINE__, texture, x, y, width, height, level, slice, \
sizeof(float), \ sizeof(float), \
new ::detail::ExpectEq<float>(expected, (width) * (height))) new detail::ExpectEq<float>(expected, (width) * (height)))
// Should only be used to test validation of function that can't be tested by regular validation // Should only be used to test validation of function that can't be tested by regular validation
// tests; // tests;

File diff suppressed because it is too large Load Diff