• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2018 The SwiftShader Authors. All Rights Reserved.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //    http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #ifndef VK_OBJECT_HPP_
16 #define VK_OBJECT_HPP_
17 
18 #include "VkConfig.h"
19 #include "VkMemory.h"
20 
21 #include "System/Debug.hpp"
22 
23 #include <Vulkan/VulkanPlatform.h>
24 #include <vulkan/vk_icd.h>
25 #include <new>
26 
27 namespace vk {
28 
29 template<typename T, typename VkT>
VkTtoT(VkT vkObject)30 static inline T *VkTtoT(VkT vkObject)
31 {
32 	return static_cast<T *>(static_cast<void *>(vkObject));
33 }
34 
35 template<typename T, typename VkT>
TtoVkT(T * object)36 static inline VkT TtoVkT(T *object)
37 {
38 	return { static_cast<uint64_t>(reinterpret_cast<uintptr_t>(object)) };
39 }
40 
41 // For use in the placement new to make it verbose that we're allocating an object using device memory
42 static constexpr VkAllocationCallbacks *DEVICE_MEMORY = nullptr;
43 
44 template<typename T, typename VkT, typename CreateInfo, typename... ExtendedInfo>
Create(const VkAllocationCallbacks * pAllocator,const CreateInfo * pCreateInfo,VkT * outObject,ExtendedInfo...extendedInfo)45 static VkResult Create(const VkAllocationCallbacks *pAllocator, const CreateInfo *pCreateInfo, VkT *outObject, ExtendedInfo... extendedInfo)
46 {
47 	*outObject = VK_NULL_HANDLE;
48 
49 	size_t size = T::ComputeRequiredAllocationSize(pCreateInfo);
50 	void *memory = nullptr;
51 	if(size)
52 	{
53 		memory = vk::allocate(size, REQUIRED_MEMORY_ALIGNMENT, pAllocator, T::GetAllocationScope());
54 		if(!memory)
55 		{
56 			return VK_ERROR_OUT_OF_HOST_MEMORY;
57 		}
58 	}
59 
60 	void *objectMemory = vk::allocate(sizeof(T), alignof(T), pAllocator, T::GetAllocationScope());
61 	if(!objectMemory)
62 	{
63 		vk::deallocate(memory, pAllocator);
64 		return VK_ERROR_OUT_OF_HOST_MEMORY;
65 	}
66 
67 	auto object = new(objectMemory) T(pCreateInfo, memory, extendedInfo...);
68 
69 	if(!object)
70 	{
71 		vk::deallocate(memory, pAllocator);
72 		return VK_ERROR_OUT_OF_HOST_MEMORY;
73 	}
74 
75 	*outObject = *object;
76 
77 	// Assert that potential v-table offsets from multiple inheritance aren't causing an offset on the handle
78 	ASSERT(*outObject == objectMemory);
79 
80 	return VK_SUCCESS;
81 }
82 
83 template<typename T, typename VkT>
84 class ObjectBase
85 {
86 public:
87 	using VkType = VkT;
88 
destroy(const VkAllocationCallbacks * pAllocator)89 	void destroy(const VkAllocationCallbacks *pAllocator) {}  // Method defined by objects to delete their content, if necessary
90 
91 	template<typename CreateInfo, typename... ExtendedInfo>
Create(const VkAllocationCallbacks * pAllocator,const CreateInfo * pCreateInfo,VkT * outObject,ExtendedInfo...extendedInfo)92 	static VkResult Create(const VkAllocationCallbacks *pAllocator, const CreateInfo *pCreateInfo, VkT *outObject, ExtendedInfo... extendedInfo)
93 	{
94 		return vk::Create<T, VkT, CreateInfo>(pAllocator, pCreateInfo, outObject, extendedInfo...);
95 	}
96 
GetAllocationScope()97 	static constexpr VkSystemAllocationScope GetAllocationScope() { return VK_SYSTEM_ALLOCATION_SCOPE_OBJECT; }
98 };
99 
100 template<typename T, typename VkT>
101 class Object : public ObjectBase<T, VkT>
102 {
103 public:
operator VkT()104 	operator VkT()
105 	{
106 		// The static_cast<T*> is used to make sure the returned pointer points to the
107 		// beginning of the object, even if the derived class uses multiple inheritance
108 		return vk::TtoVkT<T, VkT>(static_cast<T *>(this));
109 	}
110 
Cast(VkT vkObject)111 	static inline T *Cast(VkT vkObject)
112 	{
113 		return vk::VkTtoT<T, VkT>(vkObject);
114 	}
115 };
116 
117 template<typename T, typename VkT>
118 class DispatchableObject
119 {
120 	VK_LOADER_DATA loaderData = { ICD_LOADER_MAGIC };
121 
122 	T object;
123 
124 public:
GetAllocationScope()125 	static constexpr VkSystemAllocationScope GetAllocationScope() { return T::GetAllocationScope(); }
126 
127 	template<typename... Args>
DispatchableObject(Args...args)128 	DispatchableObject(Args... args)
129 	    : object(args...)
130 	{
131 	}
132 
133 	~DispatchableObject() = delete;
134 
destroy(const VkAllocationCallbacks * pAllocator)135 	void destroy(const VkAllocationCallbacks *pAllocator)
136 	{
137 		object.destroy(pAllocator);
138 	}
139 
operator delete(void * ptr,const VkAllocationCallbacks * pAllocator)140 	void operator delete(void *ptr, const VkAllocationCallbacks *pAllocator)
141 	{
142 		// Should never happen
143 		ASSERT(false);
144 	}
145 
146 	template<typename CreateInfo, typename... ExtendedInfo>
Create(const VkAllocationCallbacks * pAllocator,const CreateInfo * pCreateInfo,VkT * outObject,ExtendedInfo...extendedInfo)147 	static VkResult Create(const VkAllocationCallbacks *pAllocator, const CreateInfo *pCreateInfo, VkT *outObject, ExtendedInfo... extendedInfo)
148 	{
149 		return vk::Create<DispatchableObject<T, VkT>, VkT, CreateInfo>(pAllocator, pCreateInfo, outObject, extendedInfo...);
150 	}
151 
152 	template<typename CreateInfo>
ComputeRequiredAllocationSize(const CreateInfo * pCreateInfo)153 	static size_t ComputeRequiredAllocationSize(const CreateInfo *pCreateInfo)
154 	{
155 		return T::ComputeRequiredAllocationSize(pCreateInfo);
156 	}
157 
Cast(VkT vkObject)158 	static inline T *Cast(VkT vkObject)
159 	{
160 		return (vkObject == VK_NULL_HANDLE) ? nullptr : &(reinterpret_cast<DispatchableObject<T, VkT> *>(vkObject)->object);
161 	}
162 
operator VkT()163 	operator VkT()
164 	{
165 		return reinterpret_cast<VkT>(this);
166 	}
167 };
168 
169 }  // namespace vk
170 
171 #endif  // VK_OBJECT_HPP_
172