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