Vulkan dispatchable objects Vulkan has a few dispatchable objects: Instance, Device, Physical Device, Command Buffer and Queue. These objects, when loaded through an ICD, are constrained to have a bit of memory allocated at the beginning of these objects to contain loader data. In order to do this, a wrapper class, DispatchableObject, was created to handle pointing directly to the loader data when casting to the associated VK handle and similarly back to a pointer to the internal object. Note that Queue, being allocated within another object, and not directly through the API, simply have the loader data at the beginning of the class, without requiring a wrapper class. Also, since all these object are allocated through a custom placement new operator, they have to be deallocated through an associated destroy() function, so the DispatchableObject destructor is deleted, in order to prevent these objects from being released any other way. Bug b/116336664 Change-Id: Iac749f6adcba0eaf7557f0df876ac0474081d9cc Reviewed-on: https://swiftshader-review.googlesource.com/c/20948 Tested-by: Alexis Hétu <sugoi@google.com> Reviewed-by: Nicolas Capens <nicolascapens@google.com>
diff --git a/src/Vulkan/VkDevice.hpp b/src/Vulkan/VkDevice.hpp new file mode 100644 index 0000000..d2188a4 --- /dev/null +++ b/src/Vulkan/VkDevice.hpp
@@ -0,0 +1,57 @@ +// Copyright 2018 The SwiftShader Authors. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef VK_DEVICE_HPP_ +#define VK_DEVICE_HPP_ + +#include "VkObject.hpp" +#include "VkQueue.hpp" + +namespace vk +{ + +class Device +{ +public: + struct CreateInfo + { + const VkDeviceCreateInfo* pCreateInfo; + VkPhysicalDevice pPhysicalDevice; + }; + + static constexpr VkSystemAllocationScope GetAllocationScope() { return VK_SYSTEM_ALLOCATION_SCOPE_DEVICE; } + + Device(const CreateInfo* info, void* mem); + void destroy(const VkAllocationCallbacks* pAllocator); + + static size_t ComputeRequiredAllocationSize(const CreateInfo* info); + + VkQueue getQueue(uint32_t queueFamilyIndex, uint32_t queueIndex) const; + +private: + VkPhysicalDevice physicalDevice = VK_NULL_HANDLE; + Queue* queues = nullptr; + uint32_t queueCount = 0; +}; + +using DispatchableDevice = DispatchableObject<Device, VkDevice>; + +static inline Device* Cast(VkDevice object) +{ + return DispatchableDevice::Cast(object); +} + +} // namespace vk + +#endif // VK_DEVICE_HPP_