aboutsummaryrefslogtreecommitdiff
path: root/NvCloth/samples/SampleBase/task
diff options
context:
space:
mode:
authorMarijn Tamis <[email protected]>2018-05-03 18:22:48 +0200
committerMarijn Tamis <[email protected]>2018-05-03 18:22:48 +0200
commitca32c59a58d37c1822e185a2d5f3d0d3e8943593 (patch)
treeb06b9eec03f34344ef8fc31aa147b2714d3962ee /NvCloth/samples/SampleBase/task
parentForced rename of platform folders in cmake dir. Git didn't pick this up before. (diff)
downloadnvcloth-ca32c59a58d37c1822e185a2d5f3d0d3e8943593.tar.xz
nvcloth-ca32c59a58d37c1822e185a2d5f3d0d3e8943593.zip
NvCloth 1.1.4 Release. (24070740)
Diffstat (limited to 'NvCloth/samples/SampleBase/task')
-rw-r--r--NvCloth/samples/SampleBase/task/PxCpuDispatcher.h79
-rw-r--r--NvCloth/samples/SampleBase/task/PxGpuDispatcher.h248
-rw-r--r--NvCloth/samples/SampleBase/task/PxGpuTask.h118
-rw-r--r--NvCloth/samples/SampleBase/task/PxTask.h335
-rw-r--r--NvCloth/samples/SampleBase/task/PxTaskDefine.h37
-rw-r--r--NvCloth/samples/SampleBase/task/PxTaskManager.h231
6 files changed, 1048 insertions, 0 deletions
diff --git a/NvCloth/samples/SampleBase/task/PxCpuDispatcher.h b/NvCloth/samples/SampleBase/task/PxCpuDispatcher.h
new file mode 100644
index 0000000..ffd5cfd
--- /dev/null
+++ b/NvCloth/samples/SampleBase/task/PxCpuDispatcher.h
@@ -0,0 +1,79 @@
+// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// NVIDIA Corporation and its licensors retain all intellectual property and
+// proprietary rights in and to this software and related documentation and
+// any modifications thereto. Any use, reproduction, disclosure, or
+// distribution of this software and related documentation without an express
+// license agreement from NVIDIA Corporation is strictly prohibited.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2008-2017 NVIDIA Corporation. All rights reserved.
+
+#ifndef PXTASK_PXCPUDISPATCHER_H
+#define PXTASK_PXCPUDISPATCHER_H
+
+#include "task/PxTaskDefine.h"
+#include "foundation/PxSimpleTypes.h"
+
+namespace physx
+{
+
+class PxBaseTask;
+
+/**
+ \brief A CpuDispatcher is responsible for scheduling the execution of tasks passed to it by the SDK.
+
+ A typical implementation would for example use a thread pool with the dispatcher
+ pushing tasks onto worker thread queues or a global queue.
+
+ @see PxBaseTask
+ @see PxTask
+ @see PxTaskManager
+*/
+class PxCpuDispatcher
+{
+public:
+ /**
+ \brief Called by the TaskManager when a task is to be queued for execution.
+
+ Upon receiving a task, the dispatcher should schedule the task
+ to run when resource is available. After the task has been run,
+ it should call the release() method and discard it's pointer.
+
+ \param[in] task The task to be run.
+
+ @see PxBaseTask
+ */
+ virtual void submitTask( PxBaseTask& task ) = 0;
+
+ /**
+ \brief Returns the number of available worker threads for this dispatcher.
+
+ The SDK will use this count to control how many tasks are submitted. By
+ matching the number of tasks with the number of execution units task
+ overhead can be reduced.
+ */
+ virtual uint32_t getWorkerCount() const = 0;
+
+ virtual ~PxCpuDispatcher() {}
+};
+
+} // end physx namespace
+
+#endif // PXTASK_PXCPUDISPATCHER_H
diff --git a/NvCloth/samples/SampleBase/task/PxGpuDispatcher.h b/NvCloth/samples/SampleBase/task/PxGpuDispatcher.h
new file mode 100644
index 0000000..6cd4c3b
--- /dev/null
+++ b/NvCloth/samples/SampleBase/task/PxGpuDispatcher.h
@@ -0,0 +1,248 @@
+// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// NVIDIA Corporation and its licensors retain all intellectual property and
+// proprietary rights in and to this software and related documentation and
+// any modifications thereto. Any use, reproduction, disclosure, or
+// distribution of this software and related documentation without an express
+// license agreement from NVIDIA Corporation is strictly prohibited.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2008-2017 NVIDIA Corporation. All rights reserved.
+
+#ifndef PXTASK_PXGPUDISPATCHER_H
+#define PXTASK_PXGPUDISPATCHER_H
+
+#include "task/PxTaskDefine.h"
+#include "task/PxTask.h"
+
+/* forward decl to avoid including <cuda.h> */
+typedef struct CUstream_st* CUstream;
+
+namespace physx
+{
+
+struct PxGpuCopyDesc;
+class PxCudaContextManager;
+
+PX_PUSH_PACK_DEFAULT
+
+class PxTaskManager;
+
+/** \brief A GpuTask dispatcher
+ *
+ * A PxGpuDispatcher executes GpuTasks submitted by one or more TaskManagers (one
+ * or more scenes). It maintains a CPU worker thread which waits on GpuTask
+ * "groups" to be submitted. The submission API is explicitly sessioned so that
+ * GpuTasks are dispatched together as a group whenever possible to improve
+ * parallelism on the GPU.
+ *
+ * A PxGpuDispatcher cannot be allocated ad-hoc, they are created as a result of
+ * creating a PxCudaContextManager. Every PxCudaContextManager has a PxGpuDispatcher
+ * instance that can be queried. In this way, each PxGpuDispatcher is tied to
+ * exactly one CUDA context.
+ *
+ * A scene will use CPU fallback Tasks for GpuTasks if the PxTaskManager provided
+ * to it does not have a PxGpuDispatcher. For this reason, the PxGpuDispatcher must
+ * be assigned to the PxTaskManager before the PxTaskManager is given to a scene.
+ *
+ * Multiple TaskManagers may safely share a single PxGpuDispatcher instance, thus
+ * enabling scenes to share a CUDA context.
+ *
+ * Only failureDetected() is intended for use by the user. The rest of the
+ * nvGpuDispatcher public methods are reserved for internal use by only both
+ * TaskManagers and GpuTasks.
+ */
+class PxGpuDispatcher
+{
+public:
+ /** \brief Record the start of a simulation step
+ *
+ * A PxTaskManager calls this function to record the beginning of a simulation
+ * step. The PxGpuDispatcher uses this notification to initialize the
+ * profiler state.
+ */
+ virtual void startSimulation() = 0;
+
+ /** \brief Record the start of a GpuTask batch submission
+ *
+ * A PxTaskManager calls this function to notify the PxGpuDispatcher that one or
+ * more GpuTasks are about to be submitted for execution. The PxGpuDispatcher
+ * will not read the incoming task queue until it receives one finishGroup()
+ * call for each startGroup() call. This is to ensure as many GpuTasks as
+ * possible are executed together as a group, generating optimal parallelism
+ * on the GPU.
+ */
+ virtual void startGroup() = 0;
+
+ /** \brief Submit a GpuTask for execution
+ *
+ * Submitted tasks are pushed onto an incoming queue. The PxGpuDispatcher
+ * will take the contents of this queue every time the pending group count
+ * reaches 0 and run the group of submitted GpuTasks as an interleaved
+ * group.
+ */
+ virtual void submitTask(PxTask& task) = 0;
+
+ /** \brief Record the end of a GpuTask batch submission
+ *
+ * A PxTaskManager calls this function to notify the PxGpuDispatcher that it is
+ * done submitting a group of GpuTasks (GpuTasks which were all make ready
+ * to run by the same prerequisite dependency becoming resolved). If no
+ * other group submissions are in progress, the PxGpuDispatcher will execute
+ * the set of ready tasks.
+ */
+ virtual void finishGroup() = 0;
+
+ /** \brief Add a CUDA completion prerequisite dependency to a task
+ *
+ * A GpuTask calls this function to add a prerequisite dependency on another
+ * task (usually a CpuTask) preventing that task from starting until all of
+ * the CUDA kernels and copies already launched have been completed. The
+ * PxGpuDispatcher will increment that task's reference count, blocking its
+ * execution, until the CUDA work is complete.
+ *
+ * This is generally only required when a CPU task is expecting the results
+ * of the CUDA kernels to have been copied into host memory.
+ *
+ * This mechanism is not at all not required to ensure CUDA kernels and
+ * copies are issued in the correct order. Kernel issue order is determined
+ * by normal task dependencies. The rule of thumb is to only use a blocking
+ * completion prerequisite if the task in question depends on a completed
+ * GPU->Host DMA.
+ *
+ * The PxGpuDispatcher issues a blocking event record to CUDA for the purposes
+ * of tracking the already submitted CUDA work. When this event is
+ * resolved, the PxGpuDispatcher manually decrements the reference count of
+ * the specified task, allowing it to execute (assuming it does not have
+ * other pending prerequisites).
+ */
+ virtual void addCompletionPrereq(PxBaseTask& task) = 0;
+
+ /** \brief Retrieve the PxCudaContextManager associated with this
+ * PxGpuDispatcher
+ *
+ * Every PxCudaContextManager has one PxGpuDispatcher, and every PxGpuDispatcher
+ * has one PxCudaContextManager.
+ */
+ virtual PxCudaContextManager* getCudaContextManager() = 0;
+
+ /** \brief Record the end of a simulation frame
+ *
+ * A PxTaskManager calls this function to record the completion of its
+ * dependency graph. If profiling is enabled, the PxGpuDispatcher will
+ * trigger the retrieval of profiling data from the GPU at this point.
+ */
+ virtual void stopSimulation() = 0;
+
+ /** \brief Returns true if a CUDA call has returned a non-recoverable error
+ *
+ * A return value of true indicates a fatal error has occurred. To protect
+ * itself, the PxGpuDispatcher enters a fall through mode that allows GpuTasks
+ * to complete without being executed. This allows simulations to continue
+ * but leaves GPU content static or corrupted.
+ *
+ * The user may try to recover from these failures by deleting GPU content
+ * so the visual artifacts are minimized. But there is no way to recover
+ * the state of the GPU actors before the failure. Once a CUDA context is
+ * in this state, the only recourse is to create a new CUDA context, a new
+ * scene, and start over.
+ *
+ * This is our "Best Effort" attempt to not turn a soft failure into a hard
+ * failure because continued use of a CUDA context after it has returned an
+ * error will usually result in a driver reset. However if the initial
+ * failure was serious enough, a reset may have already occurred by the time
+ * we learn of it.
+ */
+ virtual bool failureDetected() const = 0;
+
+ /** \brief Force the PxGpuDispatcher into failure mode
+ *
+ * This API should be used if user code detects a non-recoverable CUDA
+ * error. This ensures the PxGpuDispatcher does not launch any further
+ * CUDA work. Subsequent calls to failureDetected() will return true.
+ */
+ virtual void forceFailureMode() = 0;
+
+ /** \brief Launch a copy kernel with arbitrary number of copy commands
+ *
+ * This method is intended to be called from Kernel GpuTasks, but it can
+ * function outside of that context as well.
+ *
+ * If count is 1, the descriptor is passed to the kernel as arguments, so it
+ * may be declared on the stack.
+ *
+ * If count is greater than 1, the kernel will read the descriptors out of
+ * host memory. Because of this, the descriptor array must be located in
+ * page locked (pinned) memory. The provided descriptors may be modified by
+ * this method (converting host pointers to their GPU mapped equivalents)
+ * and should be considered *owned* by CUDA until the current batch of work
+ * has completed, so descriptor arrays should not be freed or modified until
+ * you have received a completion notification.
+ *
+ * If your GPU does not support mapping of page locked memory (SM>=1.1),
+ * this function degrades to calling CUDA copy methods.
+ */
+ virtual void launchCopyKernel(PxGpuCopyDesc* desc, uint32_t count, CUstream stream) = 0;
+
+ /** \brief Query pre launch task that runs before launching gpu kernels.
+ *
+ * This is part of an optional feature to schedule multiple gpu features
+ * at the same time to get kernels to run in parallel.
+ * \note Do *not* set the continuation on the returned task, but use addPreLaunchDependent().
+ */
+ virtual PxBaseTask& getPreLaunchTask() = 0;
+
+ /** \brief Adds a gpu launch task that gets executed after the pre launch task.
+ *
+ * This is part of an optional feature to schedule multiple gpu features
+ * at the same time to get kernels to run in parallel.
+ * \note Each call adds a reference to the pre-launch task.
+ */
+ virtual void addPreLaunchDependent(PxBaseTask& dependent) = 0;
+
+ /** \brief Query post launch task that runs after the gpu is done.
+ *
+ * This is part of an optional feature to schedule multiple gpu features
+ * at the same time to get kernels to run in parallel.
+ * \note Do *not* set the continuation on the returned task, but use addPostLaunchDependent().
+ */
+ virtual PxBaseTask& getPostLaunchTask() = 0;
+
+ /** \brief Adds a task that gets executed after the post launch task.
+ *
+ * This is part of an optional feature to schedule multiple gpu features
+ * at the same time to get kernels to run in parallel.
+ * \note Each call adds a reference to the pre-launch task.
+ */
+ virtual void addPostLaunchDependent(PxBaseTask& dependent) = 0;
+
+protected:
+ /** \brief protected destructor
+ *
+ * GpuDispatchers are allocated and freed by their PxCudaContextManager.
+ */
+ virtual ~PxGpuDispatcher() {}
+};
+
+PX_POP_PACK
+
+} // end physx namespace
+
+
+#endif // PXTASK_PXGPUDISPATCHER_H
diff --git a/NvCloth/samples/SampleBase/task/PxGpuTask.h b/NvCloth/samples/SampleBase/task/PxGpuTask.h
new file mode 100644
index 0000000..197fc3d
--- /dev/null
+++ b/NvCloth/samples/SampleBase/task/PxGpuTask.h
@@ -0,0 +1,118 @@
+// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// NVIDIA Corporation and its licensors retain all intellectual property and
+// proprietary rights in and to this software and related documentation and
+// any modifications thereto. Any use, reproduction, disclosure, or
+// distribution of this software and related documentation without an express
+// license agreement from NVIDIA Corporation is strictly prohibited.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2008-2017 NVIDIA Corporation. All rights reserved.
+
+
+#ifndef PXTASK_PXGPUTASK_H
+#define PXTASK_PXGPUTASK_H
+
+#include "task/PxTaskDefine.h"
+#include "task/PxTask.h"
+#include "task/PxGpuDispatcher.h"
+
+namespace physx
+{
+
+PX_PUSH_PACK_DEFAULT
+
+/** \brief Define the 'flavor' of a PxGpuTask
+ *
+ * Each PxGpuTask should have a specific function; either copying data to the
+ * device, running kernels on that data, or copying data from the device.
+ *
+ * For optimal performance, the dispatcher should run all available HtoD tasks
+ * before running all Kernel tasks, and all Kernel tasks before running any DtoH
+ * tasks. This provides maximal kernel overlap and the least number of CUDA
+ * flushes.
+ */
+struct PxGpuTaskHint
+{
+ /// \brief Enums for the type of GPU task
+ enum Enum
+ {
+ HostToDevice,
+ Kernel,
+ DeviceToHost,
+
+ NUM_GPU_TASK_HINTS
+ };
+};
+
+/**
+ * \brief PxTask implementation for launching CUDA work
+ */
+class PxGpuTask : public PxTask
+{
+public:
+ PxGpuTask() : mComp(NULL) {}
+
+ /**
+ * \brief iterative "run" function for a PxGpuTask
+ *
+ * The GpuDispatcher acquires the CUDA context for the duration of this
+ * function call, and it is highly recommended that the PxGpuTask use the
+ * provided CUstream for all kernels.
+ *
+ * kernelIndex will be 0 for the initial call and incremented before each
+ * subsequent call. Once launchInstance() returns false, its PxGpuTask is
+ * considered completed and is released.
+ */
+ virtual bool launchInstance(CUstream stream, int kernelIndex) = 0;
+
+ /**
+ * \brief Returns a hint indicating the function of this task
+ */
+ virtual PxGpuTaskHint::Enum getTaskHint() const = 0;
+
+ /**
+ * \brief Specify a task that will have its reference count decremented
+ * when this task is released
+ */
+ void setCompletionTask(PxBaseTask& task)
+ {
+ mComp = &task;
+ }
+
+ void release()
+ {
+ if (mComp)
+ {
+ mComp->removeReference();
+ mComp = NULL;
+ }
+ PxTask::release();
+ }
+
+protected:
+ /// \brief A pointer to the completion task
+ PxBaseTask* mComp;
+};
+
+PX_POP_PACK
+
+} // end physx namespace
+
+#endif // PXTASK_PXGPUTASK_H
diff --git a/NvCloth/samples/SampleBase/task/PxTask.h b/NvCloth/samples/SampleBase/task/PxTask.h
new file mode 100644
index 0000000..85d91da
--- /dev/null
+++ b/NvCloth/samples/SampleBase/task/PxTask.h
@@ -0,0 +1,335 @@
+// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// NVIDIA Corporation and its licensors retain all intellectual property and
+// proprietary rights in and to this software and related documentation and
+// any modifications thereto. Any use, reproduction, disclosure, or
+// distribution of this software and related documentation without an express
+// license agreement from NVIDIA Corporation is strictly prohibited.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2008-2017 NVIDIA Corporation. All rights reserved.
+
+#ifndef PXTASK_PXTASK_H
+#define PXTASK_PXTASK_H
+
+#include "task/PxTaskDefine.h"
+#include "task/PxTaskManager.h"
+#include "task/PxCpuDispatcher.h"
+#include "task/PxGpuDispatcher.h"
+#include "foundation/PxAssert.h"
+
+namespace physx
+{
+
+/**
+ * \brief Base class of all task types
+ *
+ * PxBaseTask defines a runnable reference counted task with built-in profiling.
+ */
+class PxBaseTask
+{
+public:
+ PxBaseTask() : mContextID(0), mTm(NULL) {}
+ virtual ~PxBaseTask() {}
+
+ /**
+ * \brief The user-implemented run method where the task's work should be performed
+ *
+ * run() methods must be thread safe, stack friendly (no alloca, etc), and
+ * must never block.
+ */
+ virtual void run() = 0;
+
+ /**
+ * \brief Return a user-provided task name for profiling purposes.
+ *
+ * It does not have to be unique, but unique names are helpful.
+ *
+ * \return The name of this task
+ */
+ virtual const char* getName() const = 0;
+
+ //! \brief Implemented by derived implementation classes
+ virtual void addReference() = 0;
+ //! \brief Implemented by derived implementation classes
+ virtual void removeReference() = 0;
+ //! \brief Implemented by derived implementation classes
+ virtual int32_t getReference() const = 0;
+
+ /** \brief Implemented by derived implementation classes
+ *
+ * A task may assume in its release() method that the task system no longer holds
+ * references to it - so it may safely run its destructor, recycle itself, etc.
+ * provided no additional user references to the task exist
+ */
+ virtual void release() = 0;
+
+ /**
+ * \brief Return PxTaskManager to which this task was submitted
+ *
+ * Note, can return NULL if task was not submitted, or has been
+ * completed.
+ */
+ PX_FORCE_INLINE PxTaskManager* getTaskManager() const
+ {
+ return mTm;
+ }
+
+ PX_FORCE_INLINE void setContextId(PxU64 id) { mContextID = id; }
+ PX_FORCE_INLINE PxU64 getContextId() const { return mContextID; }
+
+protected:
+ PxU64 mContextID; //!< Context ID for profiler interface
+ PxTaskManager* mTm; //!< Owning PxTaskManager instance
+
+ friend class PxTaskMgr;
+};
+
+
+/**
+ * \brief A PxBaseTask implementation with deferred execution and full dependencies
+ *
+ * A PxTask must be submitted to a PxTaskManager to to be executed, Tasks may
+ * optionally be named when they are submitted.
+ */
+class PxTask : public PxBaseTask
+{
+public:
+ PxTask() : mTaskID(0) {}
+ virtual ~PxTask() {}
+
+ //! \brief Release method implementation
+ virtual void release()
+ {
+ PX_ASSERT(mTm);
+
+ // clear mTm before calling taskCompleted() for safety
+ PxTaskManager* save = mTm;
+ mTm = NULL;
+ save->taskCompleted( *this );
+ }
+
+ //! \brief Inform the PxTaskManager this task must finish before the given
+ // task is allowed to start.
+ PX_INLINE void finishBefore( PxTaskID taskID )
+ {
+ PX_ASSERT(mTm);
+ mTm->finishBefore( *this, taskID);
+ }
+
+ //! \brief Inform the PxTaskManager this task cannot start until the given
+ // task has completed.
+ PX_INLINE void startAfter( PxTaskID taskID )
+ {
+ PX_ASSERT(mTm);
+ mTm->startAfter( *this, taskID );
+ }
+
+ /**
+ * \brief Manually increment this task's reference count. The task will
+ * not be allowed to run until removeReference() is called.
+ */
+ PX_INLINE void addReference()
+ {
+ PX_ASSERT(mTm);
+ mTm->addReference( mTaskID );
+ }
+
+ /**
+ * \brief Manually decrement this task's reference count. If the reference
+ * count reaches zero, the task will be dispatched.
+ */
+ PX_INLINE void removeReference()
+ {
+ PX_ASSERT(mTm);
+ mTm->decrReference( mTaskID );
+ }
+
+ /**
+ * \brief Return the ref-count for this task
+ */
+ PX_INLINE int32_t getReference() const
+ {
+ return mTm->getReference( mTaskID );
+ }
+
+ /**
+ * \brief Return the unique ID for this task
+ */
+ PX_INLINE PxTaskID getTaskID() const
+ {
+ return mTaskID;
+ }
+
+ /**
+ * \brief Called by PxTaskManager at submission time for initialization
+ *
+ * Perform simulation step initialization here.
+ */
+ virtual void submitted()
+ {
+ mStreamIndex = 0;
+ mPreSyncRequired = false;
+ }
+
+ /**
+ * \brief Specify that the GpuTask sync flag be set
+ */
+ PX_INLINE void requestSyncPoint()
+ {
+ mPreSyncRequired = true;
+ }
+
+
+protected:
+ PxTaskID mTaskID; //!< ID assigned at submission
+ uint32_t mStreamIndex; //!< GpuTask CUDA stream index
+ bool mPreSyncRequired; //!< GpuTask sync flag
+
+ friend class PxTaskMgr;
+ friend class PxGpuWorkerThread;
+};
+
+
+/**
+ * \brief A PxBaseTask implementation with immediate execution and simple dependencies
+ *
+ * A PxLightCpuTask bypasses the PxTaskManager launch dependencies and will be
+ * submitted directly to your scene's CpuDispatcher. When the run() function
+ * completes, it will decrement the reference count of the specified
+ * continuation task.
+ *
+ * You must use a full-blown PxTask if you want your task to be resolved
+ * by another PxTask, or you need more than a single dependency to be
+ * resolved when your task completes, or your task will not run on the
+ * CpuDispatcher.
+ */
+class PxLightCpuTask : public PxBaseTask
+{
+public:
+ PxLightCpuTask()
+ : mCont( NULL )
+ , mRefCount( 0 )
+ {
+ }
+ virtual ~PxLightCpuTask()
+ {
+ mTm = NULL;
+ }
+
+ /**
+ * \brief Initialize this task and specify the task that will have its ref count decremented on completion.
+ *
+ * Submission is deferred until the task's mRefCount is decremented to zero.
+ * Note that we only use the PxTaskManager to query the appropriate dispatcher.
+ *
+ * \param[in] tm The PxTaskManager this task is managed by
+ * \param[in] c The task to be executed when this task has finished running
+ */
+ PX_INLINE void setContinuation(PxTaskManager& tm, PxBaseTask* c)
+ {
+ PX_ASSERT( mRefCount == 0 );
+ mRefCount = 1;
+ mCont = c;
+ mTm = &tm;
+ if( mCont )
+ {
+ mCont->addReference();
+ }
+ }
+
+ /**
+ * \brief Initialize this task and specify the task that will have its ref count decremented on completion.
+ *
+ * This overload of setContinuation() queries the PxTaskManager from the continuation
+ * task, which cannot be NULL.
+ * \param[in] c The task to be executed after this task has finished running
+ */
+ PX_INLINE void setContinuation( PxBaseTask* c )
+ {
+ PX_ASSERT( c );
+ PX_ASSERT( mRefCount == 0 );
+ mRefCount = 1;
+ mCont = c;
+ if( mCont )
+ {
+ mCont->addReference();
+ mTm = mCont->getTaskManager();
+ PX_ASSERT( mTm );
+ }
+ }
+
+ /**
+ * \brief Retrieves continuation task
+ */
+ PX_INLINE PxBaseTask* getContinuation() const
+ {
+ return mCont;
+ }
+
+ /**
+ * \brief Manually decrement this task's reference count. If the reference
+ * count reaches zero, the task will be dispatched.
+ */
+ PX_INLINE void removeReference()
+ {
+ mTm->decrReference(*this);
+ }
+
+ /** \brief Return the ref-count for this task */
+ PX_INLINE int32_t getReference() const
+ {
+ return mRefCount;
+ }
+
+ /**
+ * \brief Manually increment this task's reference count. The task will
+ * not be allowed to run until removeReference() is called.
+ */
+ PX_INLINE void addReference()
+ {
+ mTm->addReference(*this);
+ }
+
+ /**
+ * \brief called by CpuDispatcher after run method has completed
+ *
+ * Decrements the continuation task's reference count, if specified.
+ */
+ PX_INLINE void release()
+ {
+ if( mCont )
+ {
+ mCont->removeReference();
+ }
+ }
+
+protected:
+
+ PxBaseTask* mCont; //!< Continuation task, can be NULL
+ volatile int32_t mRefCount; //!< PxTask is dispatched when reaches 0
+
+ friend class PxTaskMgr;
+};
+
+
+}// end physx namespace
+
+
+#endif // PXTASK_PXTASK_H
diff --git a/NvCloth/samples/SampleBase/task/PxTaskDefine.h b/NvCloth/samples/SampleBase/task/PxTaskDefine.h
new file mode 100644
index 0000000..c1daea7
--- /dev/null
+++ b/NvCloth/samples/SampleBase/task/PxTaskDefine.h
@@ -0,0 +1,37 @@
+// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// NVIDIA Corporation and its licensors retain all intellectual property and
+// proprietary rights in and to this software and related documentation and
+// any modifications thereto. Any use, reproduction, disclosure, or
+// distribution of this software and related documentation without an express
+// license agreement from NVIDIA Corporation is strictly prohibited.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2008-2017 NVIDIA Corporation. All rights reserved.
+
+#ifndef PXTASK_PXTASKDEFINE_H
+#define PXTASK_PXTASKDEFINE_H
+
+#include "foundation/PxPreprocessor.h"
+
+#ifndef PX_SUPPORT_PXTASK_PROFILING
+#define PX_SUPPORT_PXTASK_PROFILING 1
+#endif
+
+#endif // PXTASK_PXTASKDEFINE_H
diff --git a/NvCloth/samples/SampleBase/task/PxTaskManager.h b/NvCloth/samples/SampleBase/task/PxTaskManager.h
new file mode 100644
index 0000000..f40f7b1
--- /dev/null
+++ b/NvCloth/samples/SampleBase/task/PxTaskManager.h
@@ -0,0 +1,231 @@
+// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// NVIDIA Corporation and its licensors retain all intellectual property and
+// proprietary rights in and to this software and related documentation and
+// any modifications thereto. Any use, reproduction, disclosure, or
+// distribution of this software and related documentation without an express
+// license agreement from NVIDIA Corporation is strictly prohibited.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2008-2017 NVIDIA Corporation. All rights reserved.
+
+#ifndef PXTASK_PXTASKMANAGER_H
+#define PXTASK_PXTASKMANAGER_H
+
+#include "task/PxTaskDefine.h"
+#include "foundation/PxSimpleTypes.h"
+#include "foundation/PxErrorCallback.h"
+
+namespace physx
+{
+
+PX_PUSH_PACK_DEFAULT
+
+class PxBaseTask;
+class PxTask;
+class PxLightCpuTask;
+typedef unsigned int PxTaskID;
+
+/**
+\brief Identifies the type of each heavyweight PxTask object
+
+\note This enum type is only used by PxTask and GpuTask objects, LightCpuTasks do not use this enum.
+
+@see PxTask
+@see PxLightCpuTask
+*/
+struct PxTaskType
+{
+ /**
+ * \brief Identifies the type of each heavyweight PxTask object
+ */
+ enum Enum
+ {
+ TT_CPU, //!< PxTask will be run on the CPU
+ TT_GPU, //!< PxTask will be run on the GPU
+ TT_NOT_PRESENT, //!< Return code when attempting to find a task that does not exist
+ TT_COMPLETED //!< PxTask execution has been completed
+ };
+};
+
+class PxCpuDispatcher;
+class PxGpuDispatcher;
+
+/**
+ \brief The PxTaskManager interface
+
+ A PxTaskManager instance holds references to user-provided dispatcher objects, when tasks are
+ submitted the PxTaskManager routes them to the appropriate dispatcher and handles task profiling if enabled.
+ Users should not implement the PxTaskManager interface, the SDK creates it's own concrete PxTaskManager object
+ per-scene which users can configure by passing dispatcher objects into the PxSceneDesc.
+
+
+ @see CpuDispatcher
+ @see PxGpuDispatcher
+
+*/
+class PxTaskManager
+{
+public:
+
+ /**
+ \brief Set the user-provided dispatcher object for CPU tasks
+
+ \param[in] ref The dispatcher object.
+
+ @see CpuDispatcher
+ */
+ virtual void setCpuDispatcher(PxCpuDispatcher& ref) = 0;
+
+ /**
+ \brief Set the user-provided dispatcher object for GPU tasks
+
+ \param[in] ref The dispatcher object.
+
+ @see PxGpuDispatcher
+ */
+ virtual void setGpuDispatcher(PxGpuDispatcher& ref) = 0;
+
+ /**
+ \brief Get the user-provided dispatcher object for CPU tasks
+
+ \return The CPU dispatcher object.
+
+ @see CpuDispatcher
+ */
+ virtual PxCpuDispatcher* getCpuDispatcher() const = 0;
+
+ /**
+ \brief Get the user-provided dispatcher object for GPU tasks
+
+ \return The GPU dispatcher object.
+
+ @see PxGpuDispatcher
+ */
+ virtual PxGpuDispatcher* getGpuDispatcher() const = 0;
+
+ /**
+ \brief Reset any dependencies between Tasks
+
+ \note Will be called at the start of every frame before tasks are submitted.
+
+ @see PxTask
+ */
+ virtual void resetDependencies() = 0;
+
+ /**
+ \brief Called by the owning scene to start the task graph.
+
+ \note All tasks with with ref count of 1 will be dispatched.
+
+ @see PxTask
+ */
+ virtual void startSimulation() = 0;
+
+ /**
+ \brief Called by the owning scene at the end of a simulation step to synchronize the PxGpuDispatcher
+
+ @see PxGpuDispatcher
+ */
+ virtual void stopSimulation() = 0;
+
+ /**
+ \brief Called by the worker threads to inform the PxTaskManager that a task has completed processing
+
+ \param[in] task The task which has been completed
+ */
+ virtual void taskCompleted(PxTask& task) = 0;
+
+ /**
+ \brief Retrieve a task by name
+
+ \param[in] name The unique name of a task
+ \return The ID of the task with that name, or TT_NOT_PRESENT if not found
+ */
+ virtual PxTaskID getNamedTask(const char* name) = 0;
+
+ /**
+ \brief Submit a task with a unique name.
+
+ \param[in] task The task to be executed
+ \param[in] name The unique name of a task
+ \param[in] type The type of the task (default TT_CPU)
+ \return The ID of the task with that name, or TT_NOT_PRESENT if not found
+
+ */
+ virtual PxTaskID submitNamedTask(PxTask* task, const char* name, PxTaskType::Enum type = PxTaskType::TT_CPU) = 0;
+
+ /**
+ \brief Submit an unnamed task.
+
+ \param[in] task The task to be executed
+ \param[in] type The type of the task (default TT_CPU)
+
+ \return The ID of the task with that name, or TT_NOT_PRESENT if not found
+ */
+ virtual PxTaskID submitUnnamedTask(PxTask& task, PxTaskType::Enum type = PxTaskType::TT_CPU) = 0;
+
+ /**
+ \brief Retrieve a task given a task ID
+
+ \param[in] id The ID of the task to return, a valid ID must be passed or results are undefined
+
+ \return The task associated with the ID
+ */
+ virtual PxTask* getTaskFromID(PxTaskID id) = 0;
+
+ /**
+ \brief Release the PxTaskManager object, referenced dispatchers will not be released
+ */
+ virtual void release() = 0;
+
+ /**
+ \brief Construct a new PxTaskManager instance with the given [optional] dispatchers
+ */
+ static PxTaskManager* createTaskManager(PxErrorCallback& errorCallback, PxCpuDispatcher* = 0, PxGpuDispatcher* = 0);
+
+protected:
+ virtual ~PxTaskManager() {}
+
+ /*! \cond PRIVATE */
+
+ virtual void finishBefore(PxTask& task, PxTaskID taskID) = 0;
+ virtual void startAfter(PxTask& task, PxTaskID taskID) = 0;
+
+ virtual void addReference(PxTaskID taskID) = 0;
+ virtual void decrReference(PxTaskID taskID) = 0;
+ virtual int32_t getReference(PxTaskID taskID) const = 0;
+
+ virtual void decrReference(PxLightCpuTask&) = 0;
+ virtual void addReference(PxLightCpuTask&) = 0;
+
+ /*! \endcond */
+
+ friend class PxBaseTask;
+ friend class PxTask;
+ friend class PxLightCpuTask;
+ friend class PxGpuWorkerThread;
+};
+
+PX_POP_PACK
+
+} // end physx namespace
+
+
+#endif // PXTASK_PXTASKMANAGER_H