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_GPU_COPY_DESC_QUEUE_H |
12 | #define PX_GPU_COPY_DESC_QUEUE_H |
13 | |
14 | #include "foundation/PxAssert.h" |
15 | #include "pxtask/PxGpuCopyDesc.h" |
16 | #include "pxtask/PxGpuDispatcher.h" |
17 | #include "pxtask/PxCudaContextManager.h" |
18 | |
19 | #ifndef PX_DOXYGEN |
20 | namespace physx |
21 | { |
22 | #endif |
23 | |
24 | PX_PUSH_PACK_DEFAULT |
25 | |
26 | /// \brief Container class for queueing PxGpuCopyDesc instances in pinned (non-pageable) CPU memory |
27 | class PxGpuCopyDescQueue |
28 | { |
29 | public: |
30 | /// \brief PxGpuCopyDescQueue constructor |
31 | PxGpuCopyDescQueue(PxGpuDispatcher& d) |
32 | : mDispatcher(d) |
33 | , mBuffer(0) |
34 | , mStream(0) |
35 | , mReserved(0) |
36 | , mOccupancy(0) |
37 | , mFlushed(0) |
38 | { |
39 | } |
40 | |
41 | /// \brief PxGpuCopyDescQueue destructor |
42 | ~PxGpuCopyDescQueue() |
43 | { |
44 | if (mBuffer) |
45 | { |
46 | mDispatcher.getCudaContextManager()->getMemoryManager()->free(PxCudaBufferMemorySpace::T_PINNED_HOST, (size_t) mBuffer); |
47 | } |
48 | } |
49 | |
50 | /// \brief Reset the enqueued copy descriptor list |
51 | /// |
52 | /// Must be called at least once before any copies are enqueued, and each time the launched |
53 | /// copies are known to have been completed. The recommended use case is to call this at the |
54 | /// start of each simulation step. |
55 | void reset(CUstream stream, PxU32 reserveSize) |
56 | { |
57 | if (reserveSize > mReserved) |
58 | { |
59 | if (mBuffer) |
60 | { |
61 | mDispatcher.getCudaContextManager()->getMemoryManager()->free( |
62 | PxCudaBufferMemorySpace::T_PINNED_HOST, |
63 | (size_t) mBuffer); |
64 | mReserved = 0; |
65 | } |
66 | mBuffer = (PxGpuCopyDesc*) mDispatcher.getCudaContextManager()->getMemoryManager()->alloc( |
67 | PxCudaBufferMemorySpace::T_PINNED_HOST, |
68 | reserveSize * sizeof(PxGpuCopyDesc), |
69 | NV_ALLOC_INFO("PxGpuCopyDescQueue" , GPU_UTIL)); |
70 | if (mBuffer) |
71 | { |
72 | mReserved = reserveSize; |
73 | } |
74 | } |
75 | |
76 | mOccupancy = 0; |
77 | mFlushed = 0; |
78 | mStream = stream; |
79 | } |
80 | |
81 | /// \brief Enqueue the specified copy descriptor, or launch immediately if no room is available |
82 | void enqueue(PxGpuCopyDesc& desc) |
83 | { |
84 | PX_ASSERT(desc.isValid()); |
85 | if (desc.bytes == 0) |
86 | { |
87 | return; |
88 | } |
89 | |
90 | if (mOccupancy < mReserved) |
91 | { |
92 | mBuffer[ mOccupancy++ ] = desc; |
93 | } |
94 | else |
95 | { |
96 | mDispatcher.launchCopyKernel(&desc, 1, mStream); |
97 | } |
98 | } |
99 | |
100 | /// \brief Launch all copies queued since the last flush or reset |
101 | void flushEnqueued() |
102 | { |
103 | if (mOccupancy > mFlushed) |
104 | { |
105 | mDispatcher.launchCopyKernel(mBuffer + mFlushed, mOccupancy - mFlushed, mStream); |
106 | mFlushed = mOccupancy; |
107 | } |
108 | } |
109 | |
110 | private: |
111 | PxGpuDispatcher& mDispatcher; |
112 | PxGpuCopyDesc* mBuffer; |
113 | CUstream mStream; |
114 | PxU32 mReserved; |
115 | PxU32 mOccupancy; |
116 | PxU32 mFlushed; |
117 | |
118 | void operator=(const PxGpuCopyDescQueue&); // prevent a warning... |
119 | }; |
120 | |
121 | PX_POP_PACK |
122 | |
123 | #ifndef PX_DOXYGEN |
124 | } // end physx namespace |
125 | #endif |
126 | |
127 | #endif |
128 | |