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