1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
|
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// * Neither the name of NVIDIA CORPORATION nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Copyright (c) 2008-2018 NVIDIA Corporation. All rights reserved.
#ifndef PXCUDACONTEXTMANAGER_PXCUDAMEMORYMANAGER_H
#define PXCUDACONTEXTMANAGER_PXCUDAMEMORYMANAGER_H
#include "foundation/PxPreprocessor.h"
#if PX_SUPPORT_GPU_PHYSX
#include "task/PxTaskDefine.h"
// some macros to keep the source code more readable
#define PX_ALLOC_INFO(name, ID) __FILE__, __LINE__, name, physx::PxAllocId::ID
#define PX_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
#define PX_ALLOC_INFO_PARAMS_DEF() const char* file, int line, const char* allocName, physx::PxAllocId::Enum allocId
#define PX_ALLOC_INFO_PARAMS_INPUT() file, line, allocName, allocId
#define PX_ALLOC_INFO_PARAMS_INPUT_INFO(info) info.getFileName(), info.getLine(), info.getAllocName(), info.getAllocId()
#ifndef NULL // don't want to include <string.h>
#define NULL 0
#endif
namespace physx
{
PX_PUSH_PACK_DEFAULT
/** \brief ID of the Feature which owns/allocated memory from the heap
*
* Maximum of 64k IDs allowed.
*/
struct PxAllocId
{
/**
* \brief ID of the Feature which owns/allocated memory from the heap
*/
enum Enum
{
UNASSIGNED, //!< default
APEX, //!< APEX stuff not further classified
PARTICLES, //!< all particle related
GPU_UTIL, //!< e.g. RadixSort (used in SPH and deformable self collision)
CLOTH, //!< all cloth related
NUM_IDS //!< number of IDs, be aware that ApexHeapStats contains PxAllocIdStats[NUM_IDS]
};
};
/// \brief memory type managed by a heap
struct PxCudaBufferMemorySpace
{
/**
* \brief memory type managed by a heap
*/
enum Enum
{
T_GPU,
T_PINNED_HOST,
T_WRITE_COMBINED,
T_HOST,
COUNT
};
};
/// \brief class to track allocation statistics, see PxgMirrored
class PxAllocInfo
{
public:
/**
* \brief AllocInfo default constructor
*/
PxAllocInfo() {}
/**
* \brief AllocInfo constructor that initializes all of the members
*/
PxAllocInfo(const char* file, int line, const char* allocName, PxAllocId::Enum allocId)
: mFileName(file)
, mLine(line)
, mAllocName(allocName)
, mAllocId(allocId)
{}
/// \brief get the allocation file name
inline const char* getFileName() const
{
return mFileName;
}
/// \brief get the allocation line
inline int getLine() const
{
return mLine;
}
/// \brief get the allocation name
inline const char* getAllocName() const
{
return mAllocName;
}
/// \brief get the allocation ID
inline PxAllocId::Enum getAllocId() const
{
return mAllocId;
}
private:
const char* mFileName;
int mLine;
const char* mAllocName;
PxAllocId::Enum mAllocId;
};
/// \brief statistics collected per AllocationId by HeapManager.
struct PxAllocIdStats
{
size_t size; //!< currently allocated memory by this ID
size_t maxSize; //!< max allocated memory by this ID
size_t elements; //!< number of current allocations by this ID
size_t maxElements; //!< max number of allocations by this ID
};
class PxCudaMemoryManager;
typedef size_t PxCudaBufferPtr;
/// \brief Hint flag to tell how the buffer will be used
struct PxCudaBufferFlags
{
/// \brief Enumerations for the hint flag to tell how the buffer will be used
enum Enum
{
F_READ = (1 << 0),
F_WRITE = (1 << 1),
F_READ_WRITE = F_READ | F_WRITE
};
};
/// \brief Memory statistics struct returned by CudaMemMgr::getStats()
struct PxCudaMemoryManagerStats
{
size_t heapSize; //!< Size of all pages allocated for this memory type (allocated + free).
size_t totalAllocated; //!< Size occupied by the current allocations.
size_t maxAllocated; //!< High water mark of allocations since the SDK was created.
PxAllocIdStats allocIdStats[PxAllocId::NUM_IDS]; //!< Stats for each allocation ID, see PxAllocIdStats
};
/// \brief Buffer type: made of hint flags and the memory space (Device Memory, Pinned Host Memory, ...)
struct PxCudaBufferType
{
/// \brief PxCudaBufferType copy constructor
PX_INLINE PxCudaBufferType(const PxCudaBufferType& t)
: memorySpace(t.memorySpace)
, flags(t.flags)
{}
/// \brief PxCudaBufferType constructor to explicitely assign members
PX_INLINE PxCudaBufferType(PxCudaBufferMemorySpace::Enum _memSpace, PxCudaBufferFlags::Enum _flags)
: memorySpace(_memSpace)
, flags(_flags)
{}
PxCudaBufferMemorySpace::Enum memorySpace; //!< specifies which memory space for the buffer
PxCudaBufferFlags::Enum flags; //!< specifies the usage flags for the buffer
};
/// \brief Buffer which keeps informations about allocated piece of memory.
class PxCudaBuffer
{
public:
/// Retrieves the manager over which the buffer was allocated.
virtual PxCudaMemoryManager* getCudaMemoryManager() const = 0;
/// Releases the buffer and the memory it used, returns true if successful.
virtual bool free() = 0;
/// Realloc memory. Use to shrink or resize the allocated chunk of memory of this buffer.
/// Returns true if successful. Fails if the operation would change the address and need a memcopy.
/// In that case the user has to allocate, copy and free the memory with separate steps.
/// Realloc to size 0 always returns false and doesn't change the state.
virtual bool realloc(size_t size, PX_ALLOC_INFO_PARAMS_DECL(NULL, 0, NULL, UNASSIGNED)) = 0;
/// Returns the type of the allocated memory.
virtual const PxCudaBufferType& getType() const = 0;
/// Returns the pointer to the allocated memory.
virtual PxCudaBufferPtr getPtr() const = 0;
/// Returns the size of the allocated memory.
virtual size_t getSize() const = 0;
protected:
/// \brief protected destructor
virtual ~PxCudaBuffer() {}
};
/// \brief Allocator class for different kinds of CUDA related memory.
class PxCudaMemoryManager
{
public:
/// Allocate memory of given type and size. Returns a CudaBuffer if successful. Returns NULL if failed.
virtual PxCudaBuffer* alloc(const PxCudaBufferType& type, size_t size, PX_ALLOC_INFO_PARAMS_DECL(NULL, 0, NULL, UNASSIGNED)) = 0;
/// Basic heap allocator without PxCudaBuffer
virtual PxCudaBufferPtr alloc(PxCudaBufferMemorySpace::Enum memorySpace, size_t size, PX_ALLOC_INFO_PARAMS_DECL(NULL, 0, NULL, UNASSIGNED)) = 0;
/// Basic heap deallocator without PxCudaBuffer
virtual bool free(PxCudaBufferMemorySpace::Enum memorySpace, PxCudaBufferPtr addr) = 0;
/// Basic heap realloc without PxCudaBuffer
virtual bool realloc(PxCudaBufferMemorySpace::Enum memorySpace, PxCudaBufferPtr addr, size_t size, PX_ALLOC_INFO_PARAMS_DECL(NULL, 0, NULL, UNASSIGNED)) = 0;
/// Retrieve stats for the memory of given type. See PxCudaMemoryManagerStats.
virtual void getStats(const PxCudaBufferType& type, PxCudaMemoryManagerStats& outStats) = 0;
/// Ensure that a given amount of free memory is available. Triggers CUDA allocations in size of (2^n * pageSize) if necessary.
/// Returns false if page allocations failed.
virtual bool reserve(const PxCudaBufferType& type, size_t size) = 0;
/// Set the page size. The managed memory grows by blocks 2^n * pageSize. Page allocations trigger CUDA driver allocations,
/// so the page size should be reasonably big. Returns false if input size was invalid, i.e. not power of two.
/// Default is 2 MB.
virtual bool setPageSize(const PxCudaBufferType& type, size_t size) = 0;
/// Set the upper limit until which pages of a given memory type can be allocated.
/// 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.
virtual bool setMaxMemorySize(const PxCudaBufferType& type, size_t size) = 0;
/// Returns the base size. The base memory block stays persistently allocated over the SDKs life time.
virtual size_t getBaseSize(const PxCudaBufferType& type) = 0;
/// Returns the currently set page size. The memory grows and shrinks in blocks of size (2^n pageSize)
virtual size_t getPageSize(const PxCudaBufferType& type) = 0;
/// Returns the upper limit until which the manager is allowed to allocate additional pages from the CUDA driver.
virtual size_t getMaxMemorySize(const PxCudaBufferType& type) = 0;
/// Get device mapped pinned host mem ptr. Operation only valid for memory space PxCudaBufferMemorySpace::T_PINNED_HOST.
virtual PxCudaBufferPtr getMappedPinnedPtr(PxCudaBufferPtr hostPtr) = 0;
protected:
/// \brief protected destructor
virtual ~PxCudaMemoryManager() {}
};
PX_POP_PACK
} // end physx namespace
#endif // PX_SUPPORT_GPU_PHYSX
#endif // PXCUDACONTEXTMANAGER_PXCUDAMEMORYMANAGER_H
|