diff options
| author | Marijn Tamis <[email protected]> | 2018-05-03 18:22:48 +0200 |
|---|---|---|
| committer | Marijn Tamis <[email protected]> | 2018-05-03 18:22:48 +0200 |
| commit | ca32c59a58d37c1822e185a2d5f3d0d3e8943593 (patch) | |
| tree | b06b9eec03f34344ef8fc31aa147b2714d3962ee /NvCloth/samples/SampleBase/task | |
| parent | Forced rename of platform folders in cmake dir. Git didn't pick this up before. (diff) | |
| download | nvcloth-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.h | 79 | ||||
| -rw-r--r-- | NvCloth/samples/SampleBase/task/PxGpuDispatcher.h | 248 | ||||
| -rw-r--r-- | NvCloth/samples/SampleBase/task/PxGpuTask.h | 118 | ||||
| -rw-r--r-- | NvCloth/samples/SampleBase/task/PxTask.h | 335 | ||||
| -rw-r--r-- | NvCloth/samples/SampleBase/task/PxTaskDefine.h | 37 | ||||
| -rw-r--r-- | NvCloth/samples/SampleBase/task/PxTaskManager.h | 231 |
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 |