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
20namespace physx
21{
22#endif
23
24PX_PUSH_PACK_DEFAULT
25
26/// \brief Container class for queueing PxGpuCopyDesc instances in pinned (non-pageable) CPU memory
27class PxGpuCopyDescQueue
28{
29public:
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
110private:
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
121PX_POP_PACK
122
123#ifndef PX_DOXYGEN
124} // end physx namespace
125#endif
126
127#endif
128