1/*
2 * Copyright (c) 2008-2015, NVIDIA CORPORATION. All rights reserved.
3 *
4 * NVIDIA CORPORATION and its licensors retain all intellectual property
5 * and proprietary rights in and to this software, related documentation
6 * and any modifications thereto. Any use, reproduction, disclosure or
7 * distribution of this software and related documentation without an express
8 * license agreement from NVIDIA CORPORATION is strictly prohibited.
9 */
10
11#ifndef PX_CUDA_MEMORY_MANAGER_H
12#define PX_CUDA_MEMORY_MANAGER_H
13
14#include "foundation/PxSimpleTypes.h"
15
16// some macros to keep the source code more readable
17#define NV_ALLOC_INFO(name, ID) __FILE__, __LINE__, name, physx::PxAllocId::ID
18#define NV_ALLOC_INFO_PARAMS_DECL(p0, p1, p2, p3) const char* file = p0, int line = p1, const char* allocName = p2, physx::PxAllocId::Enum allocId = physx::PxAllocId::p3
19#define NV_ALLOC_INFO_PARAMS_DEF() const char* file, int line, const char* allocName, physx::PxAllocId::Enum allocId
20#define NV_ALLOC_INFO_PARAMS_INPUT() file, line, allocName, allocId
21#define NV_ALLOC_INFO_PARAMS_INPUT_INFO(info) info.getFileName(), info.getLine(), info.getAllocName(), info.getAllocId()
22
23#ifndef NULL // don't want to include <string.h>
24#define NULL 0
25#endif
26
27#ifndef PX_DOXYGEN
28namespace physx
29{
30#endif
31
32PX_PUSH_PACK_DEFAULT
33
34/** \brief ID of the Feature which owns/allocated memory from the heap
35 *
36 * Maximum of 64k IDs allowed.
37 */
38struct PxAllocId
39{
40 /**
41 * \brief ID of the Feature which owns/allocated memory from the heap
42 */
43 enum Enum
44 {
45 UNASSIGNED, //!< default
46 APEX, //!< APEX stuff not further classified
47 PARTICLES, //!< all particle related
48 GPU_UTIL, //!< e.g. RadixSort (used in SPH and deformable self collision)
49 CLOTH, //!< all cloth related
50 NUM_IDS //!< number of IDs, be aware that ApexHeapStats contains PxAllocIdStats[NUM_IDS]
51 };
52};
53
54/// \brief memory type managed by a heap
55struct PxCudaBufferMemorySpace
56{
57 /**
58 * \brief memory type managed by a heap
59 */
60 enum Enum
61 {
62 T_GPU,
63 T_PINNED_HOST,
64 T_WRITE_COMBINED,
65 T_HOST,
66 COUNT
67 };
68};
69
70/// \brief class to track allocation statistics, see PxgMirrored
71class PxAllocInfo
72{
73public:
74 /**
75 * \brief AllocInfo default constructor
76 */
77 PxAllocInfo() {}
78
79 /**
80 * \brief AllocInfo constructor that initializes all of the members
81 */
82 PxAllocInfo(const char* file, int line, const char* allocName, PxAllocId::Enum allocId)
83 : mFileName(file)
84 , mLine(line)
85 , mAllocName(allocName)
86 , mAllocId(allocId)
87 {}
88
89 /// \brief get the allocation file name
90 inline const char* getFileName() const
91 {
92 return mFileName;
93 }
94
95 /// \brief get the allocation line
96 inline int getLine() const
97 {
98 return mLine;
99 }
100
101 /// \brief get the allocation name
102 inline const char* getAllocName() const
103 {
104 return mAllocName;
105 }
106
107 /// \brief get the allocation ID
108 inline PxAllocId::Enum getAllocId() const
109 {
110 return mAllocId;
111 }
112
113private:
114 const char* mFileName;
115 int mLine;
116 const char* mAllocName;
117 PxAllocId::Enum mAllocId;
118};
119
120/// \brief statistics collected per AllocationId by HeapManager.
121struct PxAllocIdStats
122{
123 size_t size; //!< currently allocated memory by this ID
124 size_t maxSize; //!< max allocated memory by this ID
125 size_t elements; //!< number of current allocations by this ID
126 size_t maxElements; //!< max number of allocations by this ID
127};
128
129class PxCudaMemoryManager;
130typedef size_t PxCudaBufferPtr;
131
132/// \brief Hint flag to tell how the buffer will be used
133struct PxCudaBufferFlags
134{
135/// \brief Enumerations for the hint flag to tell how the buffer will be used
136 enum Enum
137 {
138 F_READ = (1 << 0),
139 F_WRITE = (1 << 1),
140 F_READ_WRITE = F_READ | F_WRITE
141 };
142};
143
144
145/// \brief Memory statistics struct returned by CudaMemMgr::getStats()
146struct PxCudaMemoryManagerStats
147{
148
149 size_t heapSize; //!< Size of all pages allocated for this memory type (allocated + free).
150 size_t totalAllocated; //!< Size occupied by the current allocations.
151 size_t maxAllocated; //!< High water mark of allocations since the SDK was created.
152 PxAllocIdStats allocIdStats[PxAllocId::NUM_IDS]; //!< Stats for each allocation ID, see PxAllocIdStats
153};
154
155
156/// \brief Buffer type: made of hint flags and the memory space (Device Memory, Pinned Host Memory, ...)
157struct PxCudaBufferType
158{
159 /// \brief PxCudaBufferType copy constructor
160 PX_INLINE PxCudaBufferType(const PxCudaBufferType& t)
161 : memorySpace(t.memorySpace)
162 , flags(t.flags)
163 {}
164
165 /// \brief PxCudaBufferType constructor to explicitely assign members
166 PX_INLINE PxCudaBufferType(PxCudaBufferMemorySpace::Enum _memSpace, PxCudaBufferFlags::Enum _flags)
167 : memorySpace(_memSpace)
168 , flags(_flags)
169 {}
170
171 PxCudaBufferMemorySpace::Enum memorySpace; //!< specifies which memory space for the buffer
172 PxCudaBufferFlags::Enum flags; //!< specifies the usage flags for the buffer
173};
174
175
176/// \brief Buffer which keeps informations about allocated piece of memory.
177class PxCudaBuffer
178{
179public:
180 /// Retrieves the manager over which the buffer was allocated.
181 virtual PxCudaMemoryManager* getCudaMemoryManager() const = 0;
182
183 /// Releases the buffer and the memory it used, returns true if successful.
184 virtual bool free() = 0;
185
186 /// Realloc memory. Use to shrink or resize the allocated chunk of memory of this buffer.
187 /// Returns true if successful. Fails if the operation would change the address and need a memcopy.
188 /// In that case the user has to allocate, copy and free the memory with separate steps.
189 /// Realloc to size 0 always returns false and doesn't change the state.
190 virtual bool realloc(size_t size, NV_ALLOC_INFO_PARAMS_DECL(NULL, 0, NULL, UNASSIGNED)) = 0;
191
192 /// Returns the type of the allocated memory.
193 virtual const PxCudaBufferType& getType() const = 0;
194
195 /// Returns the pointer to the allocated memory.
196 virtual PxCudaBufferPtr getPtr() const = 0;
197
198 /// Returns the size of the allocated memory.
199 virtual size_t getSize() const = 0;
200
201protected:
202 /// \brief protected destructor
203 virtual ~PxCudaBuffer() {}
204};
205
206
207/// \brief Allocator class for different kinds of CUDA related memory.
208class PxCudaMemoryManager
209{
210public:
211 /// Allocate memory of given type and size. Returns a CudaBuffer if successful. Returns NULL if failed.
212 virtual PxCudaBuffer* alloc(const PxCudaBufferType& type, size_t size, NV_ALLOC_INFO_PARAMS_DECL(NULL, 0, NULL, UNASSIGNED)) = 0;
213
214 /// Basic heap allocator without PxCudaBuffer
215 virtual PxCudaBufferPtr alloc(PxCudaBufferMemorySpace::Enum memorySpace, size_t size, NV_ALLOC_INFO_PARAMS_DECL(NULL, 0, NULL, UNASSIGNED)) = 0;
216
217 /// Basic heap deallocator without PxCudaBuffer
218 virtual bool free(PxCudaBufferMemorySpace::Enum memorySpace, PxCudaBufferPtr addr) = 0;
219
220 /// Basic heap realloc without PxCudaBuffer
221 virtual bool realloc(PxCudaBufferMemorySpace::Enum memorySpace, PxCudaBufferPtr addr, size_t size, NV_ALLOC_INFO_PARAMS_DECL(NULL, 0, NULL, UNASSIGNED)) = 0;
222
223 /// Retrieve stats for the memory of given type. See PxCudaMemoryManagerStats.
224 virtual void getStats(const PxCudaBufferType& type, PxCudaMemoryManagerStats& outStats) = 0;
225
226 /// Ensure that a given amount of free memory is available. Triggers CUDA allocations in size of (2^n * pageSize) if necessary.
227 /// Returns false if page allocations failed.
228 virtual bool reserve(const PxCudaBufferType& type, size_t size) = 0;
229
230 /// Set the page size. The managed memory grows by blocks 2^n * pageSize. Page allocations trigger CUDA driver allocations,
231 /// so the page size should be reasonably big. Returns false if input size was invalid, i.e. not power of two.
232 /// Default is 2 MB.
233 virtual bool setPageSize(const PxCudaBufferType& type, size_t size) = 0;
234
235 /// Set the upper limit until which pages of a given memory type can be allocated.
236 /// Reducing the max when it is already hit does not shrink the memory until it is deallocated by releasing the buffers which own the memory.
237 virtual bool setMaxMemorySize(const PxCudaBufferType& type, size_t size) = 0;
238
239 /// Returns the base size. The base memory block stays persistently allocated over the SDKs life time.
240 virtual size_t getBaseSize(const PxCudaBufferType& type) = 0;
241
242 /// Returns the currently set page size. The memory grows and shrinks in blocks of size (2^n pageSize)
243 virtual size_t getPageSize(const PxCudaBufferType& type) = 0;
244
245 /// Returns the upper limit until which the manager is allowed to allocate additional pages from the CUDA driver.
246 virtual size_t getMaxMemorySize(const PxCudaBufferType& type) = 0;
247
248 /// Get device mapped pinned host mem ptr. Operation only valid for memory space PxCudaBufferMemorySpace::T_PINNED_HOST.
249 virtual PxCudaBufferPtr getMappedPinnedPtr(PxCudaBufferPtr hostPtr) = 0;
250
251protected:
252 /// \brief protected destructor
253 virtual ~PxCudaMemoryManager() {}
254};
255
256PX_POP_PACK
257
258#ifndef PX_DOXYGEN
259} // end physx namespace
260#endif
261
262#endif
263