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