Update framework to match vulkan.h at 15aa048
[platform/upstream/VK-GL-CTS.git] / external / vulkancts / framework / vulkan / vkAllocationCallbackUtil.hpp
1 #ifndef _VKALLOCATIONCALLBACKUTIL_HPP
2 #define _VKALLOCATIONCALLBACKUTIL_HPP
3 /*-------------------------------------------------------------------------
4  * Vulkan CTS Framework
5  * --------------------
6  *
7  * Copyright (c) 2015 Google Inc.
8  *
9  * Licensed under the Apache License, Version 2.0 (the "License");
10  * you may not use this file except in compliance with the License.
11  * You may obtain a copy of the License at
12  *
13  *      http://www.apache.org/licenses/LICENSE-2.0
14  *
15  * Unless required by applicable law or agreed to in writing, software
16  * distributed under the License is distributed on an "AS IS" BASIS,
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  * See the License for the specific language governing permissions and
19  * limitations under the License.
20  *
21  *//*!
22  * \file
23  * \brief Memory allocation callback utilities.
24  *//*--------------------------------------------------------------------*/
25
26 #include "vkDefs.hpp"
27 #include "deAppendList.hpp"
28
29 #include <vector>
30 #include <ostream>
31
32 namespace tcu
33 {
34 class TestLog;
35 }
36
37 namespace vk
38 {
39
40 class AllocationCallbacks
41 {
42 public:
43                                                                         AllocationCallbacks             (void);
44         virtual                                                 ~AllocationCallbacks    (void);
45
46         virtual void*                                   allocate                                (size_t size, size_t alignment, VkSystemAllocationScope allocationScope) = 0;
47         virtual void*                                   reallocate                              (void* original, size_t size, size_t alignment, VkSystemAllocationScope allocationScope) = 0;
48         virtual void                                    free                                    (void* mem) = 0;
49
50         virtual void                                    notifyInternalAllocation(size_t size, VkInternalAllocationType allocationType, VkSystemAllocationScope allocationScope) = 0;
51         virtual void                                    notifyInternalFree              (size_t size, VkInternalAllocationType allocationType, VkSystemAllocationScope allocationScope) = 0;
52
53         const VkAllocationCallbacks*    getCallbacks                    (void) const { return &m_callbacks;     }
54
55 private:
56         const VkAllocationCallbacks             m_callbacks;
57 };
58
59 struct AllocationCallbackRecord
60 {
61         enum Type
62         {
63                 TYPE_ALLOCATION         = 0,            //! Call to pfnAllocation
64                 TYPE_REALLOCATION,                              //! Call to pfnReallocation
65                 TYPE_FREE,                                              //! Call to pfnFree
66                 TYPE_INTERNAL_ALLOCATION,               //! Call to pfnInternalAllocation
67                 TYPE_INTERNAL_FREE,                             //! Call to pfnInternalFree
68
69                 TYPE_LAST
70         };
71
72         Type    type;
73
74         union
75         {
76                 struct
77                 {
78                         size_t                                          size;
79                         size_t                                          alignment;
80                         VkSystemAllocationScope         scope;
81                         void*                                           returnedPtr;
82                 } allocation;
83
84                 struct
85                 {
86                         void*                                           original;
87                         size_t                                          size;
88                         size_t                                          alignment;
89                         VkSystemAllocationScope         scope;
90                         void*                                           returnedPtr;
91                 } reallocation;
92
93                 struct
94                 {
95                         void*                                           mem;
96                 } free;
97
98                 // \note Used for both INTERNAL_ALLOCATION and INTERNAL_FREE
99                 struct
100                 {
101                         size_t                                          size;
102                         VkInternalAllocationType        type;
103                         VkSystemAllocationScope         scope;
104                 } internalAllocation;
105         } data;
106
107                                                                         AllocationCallbackRecord        (void) : type(TYPE_LAST) {}
108
109         static AllocationCallbackRecord allocation                                      (size_t size, size_t alignment, VkSystemAllocationScope scope, void* returnedPtr);
110         static AllocationCallbackRecord reallocation                            (void* original, size_t size, size_t alignment, VkSystemAllocationScope scope, void* returnedPtr);
111         static AllocationCallbackRecord free                                            (void* mem);
112         static AllocationCallbackRecord internalAllocation                      (size_t size, VkInternalAllocationType type, VkSystemAllocationScope scope);
113         static AllocationCallbackRecord internalFree                            (size_t size, VkInternalAllocationType type, VkSystemAllocationScope scope);
114 };
115
116 class ChainedAllocator : public AllocationCallbacks
117 {
118 public:
119                                                                         ChainedAllocator                (const VkAllocationCallbacks* nextAllocator);
120                                                                         ~ChainedAllocator               (void);
121
122         void*                                                   allocate                                (size_t size, size_t alignment, VkSystemAllocationScope allocationScope);
123         void*                                                   reallocate                              (void* original, size_t size, size_t alignment, VkSystemAllocationScope allocationScope);
124         void                                                    free                                    (void* mem);
125
126         void                                                    notifyInternalAllocation(size_t size, VkInternalAllocationType allocationType, VkSystemAllocationScope allocationScope);
127         void                                                    notifyInternalFree              (size_t size, VkInternalAllocationType allocationType, VkSystemAllocationScope allocationScope);
128
129 private:
130         const VkAllocationCallbacks*    m_nextAllocator;
131 };
132
133 class AllocationCallbackRecorder : public ChainedAllocator
134 {
135 public:
136                                                         AllocationCallbackRecorder      (const VkAllocationCallbacks* allocator, deUint32 callCountHint = 1024);
137                                                         ~AllocationCallbackRecorder     (void);
138
139         void*                                   allocate                                        (size_t size, size_t alignment, VkSystemAllocationScope allocationScope);
140         void*                                   reallocate                                      (void* original, size_t size, size_t alignment, VkSystemAllocationScope allocationScope);
141         void                                    free                                            (void* mem);
142
143         void                                    notifyInternalAllocation        (size_t size, VkInternalAllocationType allocationType, VkSystemAllocationScope allocationScope);
144         void                                    notifyInternalFree                      (size_t size, VkInternalAllocationType allocationType, VkSystemAllocationScope allocationScope);
145
146         typedef de::AppendList<AllocationCallbackRecord>::const_iterator        RecordIterator;
147
148         RecordIterator                  getRecordsBegin                         (void) const { return m_records.begin();        }
149         RecordIterator                  getRecordsEnd                           (void) const { return m_records.end();          }
150
151 private:
152         typedef de::AppendList<AllocationCallbackRecord> Records;
153
154         Records                                 m_records;
155 };
156
157 //! Allocator that starts returning null after N allocs
158 class DeterministicFailAllocator : public ChainedAllocator
159 {
160 public:
161                                                         DeterministicFailAllocator      (const VkAllocationCallbacks* allocator, deUint32 numPassingAllocs);
162                                                         ~DeterministicFailAllocator     (void);
163
164         void*                                   allocate                                        (size_t size, size_t alignment, VkSystemAllocationScope allocationScope);
165         void*                                   reallocate                                      (void* original, size_t size, size_t alignment, VkSystemAllocationScope allocationScope);
166
167 private:
168         const deUint32                  m_numPassingAllocs;
169         volatile deUint32               m_allocationNdx;
170 };
171
172 struct AllocationCallbackViolation
173 {
174         enum Reason
175         {
176                 REASON_DOUBLE_FREE = 0,
177                 REASON_FREE_NOT_ALLOCATED_PTR,
178                 REASON_REALLOC_NOT_ALLOCATED_PTR,
179                 REASON_REALLOC_FREED_PTR,
180                 REASON_NEGATIVE_INTERNAL_ALLOCATION_TOTAL,
181                 REASON_INVALID_ALLOCATION_SCOPE,
182                 REASON_INVALID_INTERNAL_ALLOCATION_TYPE,
183                 REASON_INVALID_ALIGNMENT,
184                 REASON_REALLOC_DIFFERENT_ALIGNMENT,
185
186                 REASON_LAST
187         };
188
189         AllocationCallbackRecord        record;
190         Reason                                          reason;
191
192         AllocationCallbackViolation (void)
193                 : reason(REASON_LAST)
194         {}
195
196         AllocationCallbackViolation (const AllocationCallbackRecord& record_, Reason reason_)
197                 : record(record_)
198                 , reason(reason_)
199         {}
200 };
201
202 struct AllocationCallbackValidationResults
203 {
204         std::vector<AllocationCallbackRecord>           liveAllocations;
205         size_t                                                                          internalAllocationTotal[VK_INTERNAL_ALLOCATION_TYPE_LAST][VK_SYSTEM_ALLOCATION_SCOPE_LAST];
206         std::vector<AllocationCallbackViolation>        violations;
207
208                                                                                                 AllocationCallbackValidationResults     (void);
209
210         void                                                                            clear                                                           (void);
211 };
212
213 void                                                    validateAllocationCallbacks             (const AllocationCallbackRecorder& recorder, AllocationCallbackValidationResults* results);
214 bool                                                    checkAndLog                                             (tcu::TestLog& log, const AllocationCallbackValidationResults& results, deUint32 allowedLiveAllocScopeBits);
215 bool                                                    validateAndLog                                  (tcu::TestLog& log, const AllocationCallbackRecorder& recorder, deUint32 allowedLiveAllocScopeBits);
216
217 size_t                                                  getLiveSystemAllocationTotal    (const AllocationCallbackValidationResults& validationResults);
218
219 std::ostream&                                   operator<<                                              (std::ostream& str, const AllocationCallbackRecord& record);
220 std::ostream&                                   operator<<                                              (std::ostream& str, const AllocationCallbackViolation& violation);
221
222 const VkAllocationCallbacks*    getSystemAllocator                              (void);
223
224 } // vk
225
226 #endif // _VKALLOCATIONCALLBACKUTIL_HPP