feat(physics): wire physx sdk into build

This commit is contained in:
2026-04-15 12:22:15 +08:00
parent 5bf258df6d
commit 31f40e2cbb
2044 changed files with 752623 additions and 1 deletions

View File

@@ -0,0 +1,82 @@
// 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-2025 NVIDIA Corporation. All rights reserved.
#ifndef PX_CPU_DISPATCHER_H
#define PX_CPU_DISPATCHER_H
#include "foundation/PxSimpleTypes.h"
#if !PX_DOXYGEN
namespace physx
{
#endif
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.
After the task has been run, it should call the release() method and
discard its 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() {}
};
#if !PX_DOXYGEN
} // namespace physx
#endif
#endif

View File

@@ -0,0 +1,331 @@
// 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-2025 NVIDIA Corporation. All rights reserved.
#ifndef PX_TASK_H
#define PX_TASK_H
#include "task/PxTaskManager.h"
#include "task/PxCpuDispatcher.h"
#include "foundation/PxAssert.h"
#if !PX_DOXYGEN
namespace physx
{
#endif
/**
* \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 Tells the scheduler if a task is high priority or not.
*
* This function is a hint to the scheduler, to let it know that some tasks are
* higher priority than others. The scheduler should try to execute high priority
* tasks first, but there is no guarantee that it does (some schedulers can ignore
* this information).
*
* \return True for high priority task, false for regular tasks
*/
virtual bool isHighPriority() const { return false; }
/**
* \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_OVERRIDE
{
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.
*/
virtual void addReference() PX_OVERRIDE
{
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.
*/
virtual void removeReference() PX_OVERRIDE
{
PX_ASSERT(mTm);
mTm->decrReference(mTaskID);
}
/**
* \brief Return the ref-count for this task
*/
virtual int32_t getReference() const PX_OVERRIDE
{
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()
{
}
protected:
PxTaskID mTaskID; //!< ID assigned at submission
friend class PxTaskMgr;
};
/**
* \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(c)
c->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(c)
{
c->addReference();
mTm = c->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.
*/
virtual void removeReference() PX_OVERRIDE
{
mTm->decrReference(*this);
}
/** \brief Return the ref-count for this task */
virtual int32_t getReference() const PX_OVERRIDE
{
return mRefCount;
}
/**
* \brief Manually increment this task's reference count. The task will
* not be allowed to run until removeReference() is called.
*/
virtual void addReference() PX_OVERRIDE
{
mTm->addReference(*this);
}
/**
* \brief called by CpuDispatcher after run method has completed
*
* Decrements the continuation task's reference count, if specified.
*/
virtual void release() PX_OVERRIDE
{
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;
};
#if !PX_DOXYGEN
} // namespace physx
#endif
#endif

View File

@@ -0,0 +1,203 @@
// 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-2025 NVIDIA Corporation. All rights reserved.
#ifndef PX_TASK_MANAGER_H
#define PX_TASK_MANAGER_H
#include "foundation/PxSimpleTypes.h"
#include "foundation/PxErrorCallback.h"
#if !PX_DOXYGEN
namespace physx
{
#endif
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 objects, PxLightCpuTasks do not use this enum.
\see PxTask
\see PxLightCpuTask
*/
struct PxTaskType
{
/**
* \brief Identifies the type of each heavyweight PxTask object
*/
enum Enum
{
eCPU, //!< PxTask will be run on the CPU
eNOT_PRESENT, //!< Return code when attempting to find a task that does not exist
eCOMPLETED //!< PxTask execution has been completed
};
};
class PxCpuDispatcher;
/**
\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 its own concrete PxTaskManager object
per-scene which users can configure by passing dispatcher objects into the PxSceneDesc.
\see PxCpuDispatcher
*/
class PxTaskManager
{
public:
/**
\brief Set the user-provided dispatcher object for CPU tasks
\param[in] ref The dispatcher object.
\see PxCpuDispatcher
*/
virtual void setCpuDispatcher(PxCpuDispatcher& ref) = 0;
/**
\brief Get the user-provided dispatcher object for CPU tasks
\return The CPU dispatcher object.
\see PxCpuDispatcher
*/
virtual PxCpuDispatcher* getCpuDispatcher() 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 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.
*/
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 eNOT_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 eCPU)
\return The ID of the task with that name, or eNOT_PRESENT if not found
*/
virtual PxTaskID submitNamedTask(PxTask* task, const char* name, PxTaskType::Enum type = PxTaskType::eCPU) = 0;
/**
\brief Submit an unnamed task.
\param[in] task The task to be executed
\param[in] type The type of the task (default eCPU)
\return The ID of the task with that name, or eNOT_PRESENT if not found
*/
virtual PxTaskID submitUnnamedTask(PxTask& task, PxTaskType::Enum type = PxTaskType::eCPU) = 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* = NULL);
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;
};
#if !PX_DOXYGEN
} // namespace physx
#endif
#endif