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,327 @@
// 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.
// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
#ifndef PXG_AABBMANAGER_H
#define PXG_AABBMANAGER_H
#include "BpAABBManagerBase.h"
#include "PxgCudaBuffer.h"
#include "PxgAggregate.h"
#include "CmIDPool.h"
#include "PxgBroadPhasePairReport.h"
#include "PxgAggregateDesc.h"
#include "CmTask.h"
#include "foundation/PxPinnedArray.h"
namespace physx
{
class PxgCudaKernelWranglerManager;
class PxCudaContextManager;
class PxgCudaBroadPhaseSap;
struct PxGpuDynamicsMemoryConfig;
class PxgAABBManager;
class PxSceneDesc;
struct PxBoundTransformUpdate
{
PxU32 indexTo;
PxU32 indexFrom; //MSB stores info if the bound is new. New is copied from cpu array, not new - from gpu array
};
class PxgProcessFoundPairTask : public Cm::Task
{
PxgAABBManager* mManager;
public:
PxgProcessFoundPairTask(PxgAABBManager* manager) : Cm::Task(0), mManager(manager)
{
}
virtual void runInternal();
virtual const char* getName() const { return "PxgProcessFoundPairTask"; }
};
class PxgProcessLostPairTask : public Cm::Task
{
PxgAABBManager* mManager;
public:
PxgProcessLostPairTask(PxgAABBManager* manager) : Cm::Task(0), mManager(manager)
{
}
virtual void runInternal();
virtual const char* getName() const { return "PxgProcessLostPairTask"; }
};
class PxgAABBManager : public Bp::AABBManagerBase
{
public:
PxgAABBManager(PxgCudaKernelWranglerManager* gpuKernelWrangler,
PxCudaContextManager* cudaContextManager,
PxgHeapMemoryAllocatorManager* heapMemoryManager,
const PxGpuDynamicsMemoryConfig& config,
Bp::BroadPhase& bp, Bp::BoundsArray& boundsArray, PxFloatArrayPinned& contactDistance,
PxU32 maxNbAggregates, PxU32 maxNbShapes, PxVirtualAllocator& allocator, PxU64 contextID,
PxPairFilteringMode::Enum kineKineFilteringMode, PxPairFilteringMode::Enum staticKineFilteringMode);
virtual ~PxgAABBManager() {}
// AABBManagerBase
virtual void destroy() PX_OVERRIDE;
virtual Bp::AggregateHandle createAggregate(Bp::BoundsIndex index, Bp::FilterGroup::Enum group, void* userData, PxU32 maxNumShapes, PxAggregateFilterHint filterHint, PxU32 envID) PX_OVERRIDE;
virtual bool destroyAggregate(Bp::BoundsIndex& index, Bp::FilterGroup::Enum& group, Bp::AggregateHandle aggregateHandle) PX_OVERRIDE;
virtual bool addBounds(Bp::BoundsIndex index, PxReal contactDistance, Bp::FilterGroup::Enum group, void* userData, Bp::AggregateHandle aggregateHandle, Bp::ElementType::Enum volumeType, PxU32 envID) PX_OVERRIDE;
virtual bool removeBounds(Bp::BoundsIndex index) PX_OVERRIDE;
virtual void updateBPFirstPass(PxU32 numCpuTasks, Cm::FlushPool& flushPool, bool hasContactDistanceUpdated, PxBaseTask* continuation) PX_OVERRIDE;
virtual void updateBPSecondPass(PxcScratchAllocator* scratchAllocator, PxBaseTask* continuation) PX_OVERRIDE;
virtual void postBroadPhase(PxBaseTask*, Cm::FlushPool& flushPool) PX_OVERRIDE;
virtual void reallocateChangedAABBMgActorHandleMap(const PxU32 size) PX_OVERRIDE;
virtual void visualize(PxRenderOutput& out) PX_OVERRIDE;
virtual void releaseDeferredAggregateIds() PX_OVERRIDE;
virtual void setGPUStateChanged() PX_OVERRIDE { mGPUStateChanged = true; }
virtual void setPersistentStateChanged() PX_OVERRIDE { mPersistentStateChanged = true; }
//~AABBManagerBase
PxgCudaBuffer mVolumDataBuf;
void markAggregateBoundsBitmap();
void processFoundPairs();
void processLostPairs();
// PX_FORCE_INLINE PxBitMapPinned& getAggregatedBoundMap() { return mAggregatedBoundMap; }
PX_FORCE_INLINE CUdeviceptr getAggregatedBounds() { return mAggregatedBoundsBuf.getDevicePtr(); }
PX_FORCE_INLINE CUdeviceptr getAddedHandles() { return mAddedHandleBuf.getDevicePtr(); }
PX_FORCE_INLINE CUdeviceptr getRemovedHandles() { return mRemovedHandleBuf.getDevicePtr(); }
PX_FORCE_INLINE CUdeviceptr getChangedAABBMgrHandles() { return mChangedAABBMgrHandlesBuf.getDevicePtr(); }
PX_FORCE_INLINE PxU32 getChangedAABBMgrHandlesWordCount() { return mChangedHandleMap.getWordCount(); }
private:
void preBpUpdate_GPU();
void gpuDmaDataUp();
void clearDirtyAggs();
void resizeFoundAndLostPairs();
void computeAggregateBounds();
void updateDescriptor(CUstream bpStream);
PxgCudaKernelWranglerManager* mGpuKernelWranglerManager;
PxCudaContextManager* mCudaContextManager;
PxCudaContext* mCudaContext;
PxgHeapMemoryAllocatorManager* mHeapMemoryManager;
PxArray<PxgAggregate> mAggregates; //cpu mirror
PxPinnedArray<PxgAggregatePair> mAggregatePairs;
PxPinnedArray<Bp::AggregateHandle> mDirtyAggregateIndices;
PxPinnedArray<PxgAggregate> mDirtyAggregates;
//found and lost pairs for agg vs agg and agg vs actor
PxPinnedArray<PxgBroadPhasePair> mFoundPairs;
PxPinnedArray<PxgBroadPhasePair> mLostPairs;
PxInt32ArrayPinned mDirtyBoundIndices;
PxInt32ArrayPinned mDirtyBoundStartIndices; //start index of each aggregate in the dirty bound indices list
PxInt32ArrayPinned mRemovedAggregatedBounds;
PxInt32ArrayPinned mAddedAggregatedBounds;
Cm::DeferredIDPool mAggregatesIdPool; //generate the remap id between pxgbodysim and pxgaggregate
PxBitMap mDirtyAggregateBitMap;
PxBitMapPinned mAggregatedBoundMap;
PxArray<PxgAggregateBuffer*> mAggregateBufferArray;
PxgAggregateDesc* mAggregateDesc;
PxgCudaBuffer mAggregateBuf;
PxgCudaBuffer mAggregatePairsBuf;
PxgCudaBuffer mDirtyAggregateIndiceBuf;
PxgCudaBuffer mDirtyAggregateBuf;
PxgCudaBuffer mDirtyBoundIndicesBuf;
PxgCudaBuffer mDirtyBoundStartIndicesBuf;
PxgCudaBuffer mRemovedAggregatedBoundsBuf;
PxgCudaBuffer mAddedAggregatedBoundsBuf;
PxgCudaBuffer mAggPairBuf; //persistent pairs
PxgCudaBuffer mNumAggPairBuf; // number of app pairs
PxgCudaBuffer mAggregateDescBuf;
PxgCudaBuffer mFoundPairsBuf;
PxgCudaBuffer mLostPairsBuf;
PxgCudaBuffer mFreeIDPool;
PxgCudaBuffer mFreeIDs;
PxgCudaBuffer mRemoveBitmap;
PxgCudaBuffer mRemoveHistogram;
PxgCudaBuffer mAggregatedBoundsBuf;
PxgCudaBuffer mAddedHandleBuf;
PxgCudaBuffer mRemovedHandleBuf;
PxgCudaBuffer mChangedAABBMgrHandlesBuf;
PxU32 mNumAggregatesSlots;
PxU32 mMaxFoundLostPairs;
PxU32 mMaxAggPairs;
PxgProcessFoundPairTask mFoundPairTask;
PxgProcessLostPairTask mLostPairTask;
// PT: this flag is set:
// - via setGPUStateChanged():
// - in PxgSimulationCore::applyActorData() when body data is changed
// - in FEMClothShapeSim::updateBoundsInAABBMgr()
// - in ParticleSystemShapeSim::updateBoundsInAABBMgr
// - in SoftBodyShapeSim::updateBoundsInAABBMgr()
// - when mOriginShifted is false and hasActive is true in PxgAABBManager::updateBPFirstPass
//
// It is unclear whether we need to set the flag in all of these cases.
//
// The flag is used:
// - in PxgAABBManager::preBpUpdate_GPU
// - to skip DMA of mChangedHandleMap
// - in PxgAABBManager::updateBPSecondPass
// - in the GPU broadphase (passed there as part of the updateData structure)
// - TODO: investigate what happens there
// - to skip kernel launches of AGG_ADD_AGGPAIRS_STAGE_1/AGG_ADD_AGGPAIRS_STAGE_2
bool mGPUStateChanged; //non-rigid body, direct API calls
// PT: this flag is set:
// - via setPersistentStateChanged():
// - when a contact distance changes
// - when an aggregate is removed (PxgAABBManager::destroyAggregate)
// - when an object is added (PxgAABBManager::addBounds)
// - when an aggregated is added (PxgAABBManager::addBounds)
// - when an object is removed (PxgAABBManager::removeBounds)
// - when an aggregated is removed (PxgAABBManager::removeBounds)
// - in PxgAABBManager::updateBPFirstPass if hasContactDistanceUpdated is true
// - when mOriginShifted is true, during PxgAABBManager::updateBPFirstPass
//
// It is unclear whether we need to set the flag in all of these cases.
//
// The flag is used:
// - in PxgAABBManager::preBpUpdate_GPU
// - to skip DMAs of mAddedHandleMap/mRemovedHandleMap
// - to skip DMA of mAggregatedBoundMap / mVolumeData
// - to skip the preBroadphase call
// - to skip DMA of mChangedHandleMap
// - in PxgAABBManager::updateBPSecondPass
// - in the GPU broadphase (passed there as part of the updateData structure)
// - TODO: investigate what happens there
// - to skip kernel launches of AGG_ADD_AGGPAIRS_STAGE_1/AGG_ADD_AGGPAIRS_STAGE_2
bool mPersistentStateChanged;
};
class PxgBoundsArray : public Bp::BoundsArray
{
PX_NOCOPY(PxgBoundsArray)
public:
PxgBoundsArray(PxVirtualAllocator& allocator)
: BoundsArray(allocator)
, mIsFirstCopy(true)
, mChanges(allocator)
{
}
virtual ~PxgBoundsArray() PX_OVERRIDE
{
mChanges.clear();
}
void updateBounds(const PxTransform& transform, const PxGeometry& geom, PxU32 index,
PxU32 indexFrom) PX_OVERRIDE PX_FINAL
{
if(indexFrom == index) // new, needs to be copied from CPU
{
Gu::computeBounds(mBounds[index], geom, transform, 0.0f, 1.0f);
updateChanges(index, indexFrom, true);
}
else
{
updateChanges(index, indexFrom, false);
}
}
void setBounds(const PxBounds3& bounds, PxU32 index) PX_OVERRIDE PX_FINAL
{
mBounds[index] = bounds;
updateChanges(index, index, true);
}
PX_FORCE_INLINE PxU32 getNumberOfChanges()
{
return mChanges.size();
}
PX_FORCE_INLINE PxArray<PxBoundTransformUpdate, PxVirtualAllocator>& getStagingBuffer()
{
return mChanges;
}
PX_FORCE_INLINE void resetChanges()
{
mChanges.reset();
}
PX_FORCE_INLINE bool isFirstCopy()
{
return mIsFirstCopy;
}
PX_FORCE_INLINE void setCopied()
{
mIsFirstCopy = false;
}
private:
PX_FORCE_INLINE void updateChanges(PxU32 indexTo, PxU32 indexFrom, bool isNew)
{
if(!mIsFirstCopy)
{
PxBoundTransformUpdate update;
update.indexTo = indexTo;
update.indexFrom = indexFrom & 0x7FFFFFFF;
if(isNew)
{
update.indexFrom |= (1U << 31);
}
mChanges.pushBack(update);
}
}
bool mIsFirstCopy;
PxArray<PxBoundTransformUpdate, PxVirtualAllocator> mChanges;
};
}
#endif

View File

@@ -0,0 +1,124 @@
// 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.
// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
#ifndef PXG_AGGREGATE_H
#define PXG_AGGREGATE_H
#include "foundation/PxPreprocessor.h"
#include "foundation/PxSimpleTypes.h"
#include "PxgCudaBuffer.h"
#include "foundation/PxUserAllocated.h"
namespace physx
{
class PxgHeapMemoryAllocatorManager;
class PxgSapBox1D;
// PT: TODO:
// - fix/unify class member names (m prefix)
// - figure out why we don't initialize all members in ctor
// - check that all of these are still needed
struct PxgAggregate
{
public:
PxgAggregate() : updateBoundIndices(NULL)
{
initValues();
}
PX_FORCE_INLINE void initValues()
{
prevComparisons = 0;
prevSize = 0;
mIndex = 0xFFFFFFFF;
size = 0;
filterHint = 0;
mEnvID = PX_INVALID_U32;
isNew = true;
}
PX_CUDA_CALLABLE PX_FORCE_INLINE bool isValid() { return (size > 0) && (mIndex != 0xFFFFFFFF); }
// resetting back to constructor values.
PX_FORCE_INLINE void reset()
{
PX_FREE(updateBoundIndices);
initValues();
}
PxU32* updateBoundIndices; // list of bound indices for this aggregate, used for CPU->GPU transfer.
// pointers to device mem containing a list of shape bound indices belong to this aggregate, double-buffered.
// Will contain the previous and current list, we flip these pointers each time the aggregate is processed and sorted.
PxU32* boundIndices[2];
//A list of the shape projections. There are 2x sorted lists (the prev sorted list, and the current). We flip these pointers
//each time the pair is processed and sorted...
PxU32* sortedProjections[2];
PxU32* sortedHandles[2];
PxgSapBox1D* sapBox1D[2]; //Prev/curr sapBox...
PxU32* startMasks[2]; //Prev/curr start masks. This is a bitmask so we require nbProjections/32 PxU32s.
PxU32* comparisons[2];
PxU32 prevComparisons;
PxU32 prevSize; //Can be different from size. Copied to every frame...
PxU32 mIndex; //aggregate bound index
PxU32 size;
PxU32 filterHint; //PxAggregateFilterHint
PxU32 mEnvID; // PT: environment ID
bool isNew;
};
struct PxgAggregatePair
{
public:
PxU32 actorHandle0;
PxU32 actorHandle1;
bool isNew;
bool isDead;
PxU16 pad;
};
class PxgAggregateBuffer : public PxUserAllocated
{
public:
PxgAggregateBuffer(PxgHeapMemoryAllocatorManager* heapMemoryManager);
PxgCudaBuffer updateBoundIndices;
PxgCudaBufferN<2> boundIndices;
PxgCudaBufferN<2> sortedProjections;
PxgCudaBufferN<2> sortedHandles;
PxgCudaBufferN<2> sapBox1D;
PxgCudaBufferN<2> startMasks;
PxgCudaBufferN<2> comparisons;
};
}
#endif

View File

@@ -0,0 +1,83 @@
// 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.
// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
#ifndef PXG_AGGREGATE_DESC_H
#define PXG_AGGREGATE_DESC_H
#include "foundation/PxSimpleTypes.h"
namespace physx
{
struct PxgBroadPhasePair;
struct PxgAggregate;
struct PxgFreeBufferList;
struct PxgAggregatePair;
struct PxgFreeBufferList
{
PxU32 numFreeIndices;
PxU32 maxIndex;
};
struct PxgAggregateDesc
{
public:
PxgBroadPhasePair* foundPairReport;
PxgBroadPhasePair* lostPairReport;
PxgBroadPhasePair* foundPairReportMap;
PxgBroadPhasePair* lostPairReportMap;
PxU32 sharedFoundPairIndex;
PxU32 sharedLostPairIndex;
PxgAggregate* aggregates;
PxU32 numAgregates;
PxgFreeBufferList* freeBufferList;
PxU32* freeIndices;
PxU32* removeBitmap;
PxU32* removeHistogram;
PxU32 nbRemoved;
PxgAggregatePair* aggPairs;
PxU32* aggPairCount;
PxU32 max_found_lost_pairs;
PxU32 max_agg_pairs;
PxU32 aggPairOverflowCount;
PxU32 foundCandidatePairOverflowCount;
bool found_pairs_overflow_flags;
bool lost_pairs_overflow_flags;
bool agg_pairs_overflow_flags;
};
}
#endif

View File

@@ -0,0 +1,40 @@
// 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.
// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
#ifndef PXG_BROADPHASE_H
#define PXG_BROADPHASE_H
namespace physx
{
//this is needed to force PhysXBroadphaseGpu linkage as Static Library!
void createPxgBroadphase();
}
#endif

View File

@@ -0,0 +1,40 @@
// 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.
// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
#ifndef PXG_BROADPHASE_COMMON_DEFINES_H
#define PXG_BROADPHASE_COMMON_DEFINES_H
#include "foundation/PxSimpleTypes.h"
#define PXG_INVALID_BP_PROJECTION 0xffffffff
#define PXG_INVALID_BP_SAP_BOX 0xffffffff
#define PXG_INVALID_BP_HANDLE 0x3fffffff
#endif

View File

@@ -0,0 +1,188 @@
// 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.
// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
#ifndef PXG_BROADPHASE_DESC_H
#define PXG_BROADPHASE_DESC_H
#include "foundation/PxSimpleTypes.h"
// PT: the GPU AABB manager apparently DMAs the updated handles' *bitmap* to the GPU directly, bypassing the
// BP API. This creates coupling between the GPU BP and the GPU AABB manager, i.e. the GPU BP cannot be used
// outside of the SDK as a standalone BP. The code controlled by this define tries to undo that and support
// a "regular" update handles array (not a bitmap), like the CPU implementations do.
#define SUPPORT_UPDATE_HANDLES_ARRAY_FOR_GPU
namespace physx
{
class PxgIntegerAABB;
class PxgSapBox1D;
struct PxgBroadPhasePair;
struct PxgHandleRegion;
struct PxgIntegerRegion;
class PxBounds3;
namespace Bp
{
struct VolumeData;
}
typedef PxU64 regionOverlapType;
struct PxgBroadPhaseDesc
{
PxU32* updateData_createdHandles; // PT: copy of updateData buffer in device memory
PxU32 numCreatedHandles;
PxU32* updateData_removedHandles; // PT: copy of updateData buffer in device memory
PxU32 numRemovedHandles;
#ifdef SUPPORT_UPDATE_HANDLES_ARRAY_FOR_GPU
PxU32* updateData_updatedHandles; // PT: copy of updateData buffer in device memory
PxU32 numUpdatedHandles;
#endif
PxU32* aabbMngr_changedHandleMap; // PT: data coming from the AABB manager, creating all the coupling problems
PxU32 aabbMngr_changedHandleBitMapWordCounts; // PT: data coming from the AABB manager, creating all the coupling problems
PxU32* aabbMngr_addedHandleMap; // PT: data coming from the AABB manager, creating all the coupling problems
PxU32* aabbMngr_removedHandleMap; // PT: data coming from the AABB manager, creating all the coupling problems
PxU32* aabbMngr_aggregatedBoundHandles; // PT: data coming from the AABB manager, creating all the coupling problems
PxBounds3* updateData_fpBounds; // PT: copy of updateData buffer in device memory
PxReal* updateData_contactDistances; // PT: copy of updateData buffer in device memory
PxgIntegerAABB* newIntegerBounds; // PT: computed by translateAABBsLaunch kernel.
PxU32* updateData_groups; // PT: copy of updateData buffer in device memory TODO: type could be better
PxU32* updateData_envIDs; // PT: copy of updateData buffer in device memory
PxgIntegerAABB* oldIntegerBounds;
PxgSapBox1D* boxSapBox1D[3];
PxgSapBox1D* boxNewSapBox1D[3];
PxU32* boxProjections[3];
PxU32* boxHandles[2][3];
PxU32 numPreviousHandles;
PxU32 sharedFoundPairIndex;
PxU32 sharedLostPairIndex;
PxU32 sharedFoundAggPairIndex;
PxU32 sharedLostAggPairIndex;
PxgBroadPhasePair* foundPairReport; //device memory for GPU foundReport (include actors and aggregates)
PxgBroadPhasePair* lostPairReport; //device memory for GPU lostReport (include actors and aggregates)
PxgBroadPhasePair* foundAggPairReport; //device memory for GPU aggregate foundReport
PxgBroadPhasePair* lostAggPairReport; //device memory for GPU aggregate lostReport
PxgBroadPhasePair* foundActorPairReport; //device memory for GPU actor foundReport
PxgBroadPhasePair* lostActorPairReport; //device memory for GPU actor lostReport
PxgBroadPhasePair* foundPairReportMap; //mapped address in the GPU for the cpu foundReport for actor pairs (not include aggregate);
PxgBroadPhasePair* lostPairReportMap; //mapped address in the GPU for the cpu lostReport for actor pairs(not include aggregate);
Bp::VolumeData* aabbMngr_volumeData; // PT: data coming from the AABB manager, creating all the coupling problems
PxU32* activeRegionsHistogram; //! Histogram used for active handles, 64 regions and each regions has nbProjections(multiply of 4) elements
PxU32* startRegionsHistogram; //! Histogram for all start handles
PxU32* orderedActiveRegionHandles; //! An ordered list of active handles
PxU32* orderedStartRegionHandles; //! An ordered list of start handles
regionOverlapType* blockOverlapChecksRegion;
regionOverlapType* overlapChecksRegion; //this variable is to store the exclusive scan add overlap checks for each objects
regionOverlapType overlapChecksTotalRegion; //this variable is to store the total number of overlap checks for all objects
PxgHandleRegion* overlapChecksHandleRegiones;
PxgIntegerRegion* regionRange;
PxU32* startRegionAccum;
PxU32* blockStartRegionAccum;
PxU32 startRegionAccumTotal;
PxU32* regionAccum;
PxU32* blockRegionAccum;
PxU32 regionAccumTotal;
PxU32* endPtHistogram[2][3];
PxU32* blockEndPtHistogram[2][3];
PxU32* endPointHandles[2][3];
PxU32* totalEndPtHistogram[3];
PxU32* blockTotalEndPtHistogram[3];
PxU32* startPtHistogram[2][3];
PxU32* blockStartPtHistogram[2][3];
PxU32* startPointHandles[2][3];
PxU32* boxProjectionRanks[3];
PxU32* incrementalComparisons[3];
PxU32* incrementalBlockComparisons[3];
PxU32* aggReportBlock[2];
PxU32* actorReportBlock[2];
PxU32 totalIncrementalComparisons[3];
PxU32 max_found_lost_pairs;
PxU32 max_found_lost_agg_pairs;
bool found_lost_pairs_overflow_flags;
};
PX_FORCE_INLINE PX_CUDA_CALLABLE PxU32 createHandle(const PxU32 handle, const bool isStart, const bool isNew)
{
return (handle << 3) | (PxU32)isStart | (PxU32)isNew << 1;
}
PX_FORCE_INLINE PX_CUDA_CALLABLE PxU32 markDeleted(const PxU32 handle)
{
return handle | (1 << 2);
}
PX_FORCE_INLINE PX_CUDA_CALLABLE PxU32 getHandle(const PxU32 sortedHandle)
{
return sortedHandle >> 3;
}
PX_FORCE_INLINE PX_CUDA_CALLABLE bool isStartProjection(const PxU32 sortedHandle)
{
return !!(sortedHandle & 1);
}
PX_FORCE_INLINE PX_CUDA_CALLABLE bool isNewProjection(const PxU32 sortedHandle)
{
return !!((sortedHandle >> 1) & 1);
}
PX_FORCE_INLINE PX_CUDA_CALLABLE bool isDeletedProjection(const PxU32 sortedHandle)
{
return !!((sortedHandle) & (1 << 2));
}
}
#endif

View File

@@ -0,0 +1,128 @@
// 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.
// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
#ifndef PXG_BP_KERNEL_INDICES_H
#define PXG_BP_KERNEL_INDICES_H
namespace physx
{
struct PxgBPKernelBlockDim
{
enum
{
BP_TRANSLATE_AABBS = 256,
BP_UPDATE_DELETEDPAIRS = 256,
BP_UPDATE_UPDATEDPAIRS = 256,
BP_UPDATE_UPDATEDPAIRS2 = 256,
BP_UPDATE_CREATEDPAIRS = 256,
BP_INITIALIZE_SAPBOX = 256,
BP_COMPUTE_ENDPT_HISTOGRAM = 256,
BP_OUTPUT_ENDPT_HISTOGRAM = 256,
BP_CREATE_REGIONS = 256,
BP_COMPUTE_START_REGION_HISTOGRAM = 256,
BP_OUTPUT_START_REGION_HISTOGRAM = 256,
BP_COMPUTE_REGION_HISTOGRAM = 256,
BP_OUTPUT_REGION_HISTOGRAM = 256,
BP_WRITEOUT_ACTIVE_HISTOGRAM = 256,
BP_COMPUTE_ACTIVE_HISTOGRAM = 512,
BP_OUTPUT_ACTIVE_HISTOGRAM = 256,
BP_COMPUTE_OVERLAPCHECKS_HISTOGRAM = 256,
BP_OUTPUT_OVERLAPCHECKS_HISTOGRAM = 256,
BP_CLEAR_NEWFLAG = 256,
BP_INITIALIZE_RANKS = 256,
BP_UDPATE_HANDLES = 256,
BP_COMPUTE_INCREMENTAL_CMP_COUNTS1 = 256,
BP_COMPUTE_INCREMENTAL_CMP_COUNTS2 = 256,
BP_INCREMENTAL_SAP = 256,
BP_GENERATE_FOUNDPAIR_NEWBOUNDS = 256,
BP_WRITEOUT_OVERLAPCHECKS_HISTOGRAM_NEWBOUNDS =256,
BP_COPY_REPORTS = 256,
BP_AGGREGATE_SORT = 64,
BP_AGGREGATE_REMOVE = 1024
};
};
struct PxgBPKernelGridDim
{
enum
{
// BP_TRANSLATE_AABBS = 64, // PT: not used?
BP_UPDATE_DELETEDPAIRS = 32,
BP_UPDATE_UPDATEDPAIRS = 32,
BP_UPDATE_UPDATEDPAIRS2 = 32,
BP_UPDATE_CREATEDPAIRS = 32,
// BP_INITIALIZE_SAPBOX = 64, // PT: not used?
BP_COMPUTE_ENDPT_HISTOGRAM = 32,
BP_OUTPUT_ENDPT_HISTOGRAM = 32,
BP_CREATE_REGIONS = 32,
BP_COMPUTE_START_REGION_HISTOGRAM = 32,
BP_OUTPUT_START_REGION_HISTOGRAM = 32,
BP_COMPUTE_REGION_HISTOGRAM = 32,
BP_OUTPUT_REGION_HISTOGRAM = 32,
BP_WRITEOUT_ACTIVE_HISTOGRAM = 32,
BP_COMPUTE_ACTIVE_HISTOGRAM = 64,
BP_OUTPUT_ACTIVE_HISTOGRAM = 64,
BP_COMPUTE_OVERLAPCHECKS_HISTOGRAM = 32,
BP_OUTPUT_OVERLAPCHECKS_HISTOGRAM = 32,
BP_CLEAR_NEWFLAG = 32,
BP_INITIALIZE_RANKS = 64,
BP_UDPATE_HANDLES = 64,
BP_COMPUTE_INCREMENTAL_CMP_COUNTS1 = 32,
BP_COMPUTE_INCREMENTAL_CMP_COUNTS2 = 32,
BP_INCREMENTAL_SAP = 256,
BP_GENERATE_FOUNDPAIR_NEWBOUNDS = 64,
BP_WRITEOUT_OVERLAPCHECKS_HISTOGRAM_NEWBOUNDS = 32,
BP_COPY_REPORTS = 64,
BP_AGGREGATE_REMOVE = 32
};
};
}
#endif

View File

@@ -0,0 +1,65 @@
// 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.
// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
#ifndef PXG_BROADPHASE_PAIR_REPORT_H
#define PXG_BROADPHASE_PAIR_REPORT_H
#include "PxgBroadPhaseCommonDefines.h"
#include "foundation/PxMath.h"
namespace physx
{
/*
\brief Structure used to report created and deleted broadphase pairs
\note The indices mVolA and mVolB correspond to the bounds indices
BroadPhaseUpdateData::mCreated used by BroadPhase::update
\see BroadPhase::getCreatedPairs, BroadPhase::getDeletedPairs
*/
struct PxgBroadPhasePair
{
PX_CUDA_CALLABLE PxgBroadPhasePair(PxU32 volA, PxU32 volB)
{
mVolA=PxMin(volA,volB);
mVolB=PxMax(volA,volB);
}
PX_CUDA_CALLABLE PxgBroadPhasePair()
: mVolA(PXG_INVALID_BP_HANDLE),
mVolB(PXG_INVALID_BP_HANDLE)
{
}
PxU32 mVolA; // NB: mVolA < mVolB
PxU32 mVolB;
};
}
#endif

View File

@@ -0,0 +1,275 @@
// 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.
// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
#ifndef PXG_CUDA_BROADPHASE_SAP_H
#define PXG_CUDA_BROADPHASE_SAP_H
#include "foundation/PxPinnedArray.h"
#include "BpBroadPhase.h"
#include "PxgCudaBuffer.h"
#include "PxgCudaMemoryAllocator.h"
#include "PxgBroadPhasePairReport.h"
#include "PxgHeapMemAllocator.h"
// PT: for SUPPORT_UPDATE_HANDLES_ARRAY_FOR_GPU
#include "PxgBroadPhaseDesc.h"
#include "foundation/PxPreprocessor.h"
#include "foundation/PxSimpleTypes.h"
namespace physx
{
class KernelWrangler;
class PxgBpCudaMemoryAllocator;
class PxgSapPairManager;
struct PxGpuDynamicsMemoryConfig;
class PxgAABBManager;
struct PxgBroadPhaseDesc;
struct PxgRadixSortDesc;
class PxgCudaKernelWranglerManager;
class PxSceneDesc;
namespace Bp
{
class BroadPhaseUpdateData;
}
class PxgCudaBroadPhaseSap : public Bp::BroadPhase
{
PX_NOCOPY(PxgCudaBroadPhaseSap)
public:
PxgCudaBroadPhaseSap(const PxGpuBroadPhaseDesc& desc, PxgCudaKernelWranglerManager* gpuKernelWrangler, PxCudaContextManager* cudaContextManager, const PxGpuDynamicsMemoryConfig& init, PxgHeapMemoryAllocatorManager* heapMemoryManager, PxU64 contextID);
~PxgCudaBroadPhaseSap();
// Bp::BroadPhase
virtual PxBroadPhaseType::Enum getType() const PX_OVERRIDE { return PxBroadPhaseType::eGPU; }
virtual void release() PX_OVERRIDE;
virtual void update(PxcScratchAllocator* scratchAllocator, const Bp::BroadPhaseUpdateData& updateData, PxBaseTask* continuation) PX_OVERRIDE;
virtual void preBroadPhase(const Bp::BroadPhaseUpdateData& updateData) PX_OVERRIDE;
virtual void fetchBroadPhaseResults() PX_OVERRIDE;
virtual const Bp::BroadPhasePair* getCreatedPairs(PxU32& nbCreatedPairs) const PX_OVERRIDE
{
nbCreatedPairs = mFoundActorPairs.size();
return reinterpret_cast<const Bp::BroadPhasePair*>(mFoundActorPairs.begin());
}
virtual const Bp::BroadPhasePair* getDeletedPairs(PxU32& nbDeletedPairs) const PX_OVERRIDE
{
nbDeletedPairs = mLostActorPairs.size();
return reinterpret_cast<const Bp::BroadPhasePair*>(mLostActorPairs.begin());
}
virtual void freeBuffers() PX_OVERRIDE;
// PT: TODO: shift origin for GPU BP?
virtual void shiftOrigin(const PxVec3& /*shift*/, const PxBounds3* /*boundsArray*/, const PxReal* /*contactDistances*/) PX_OVERRIDE {}
#if PX_CHECKED
virtual bool isValid(const Bp::BroadPhaseUpdateData& updateData) const PX_OVERRIDE { PX_UNUSED(updateData); return true; }
#endif
//~Bp::BroadPhase
PX_FORCE_INLINE PxgTypedCudaBuffer<PxBounds3>& getBoundsBuffer() { return mBoxFpBoundsBuf; }
PX_FORCE_INLINE PxgTypedCudaBuffer<PxReal>& getContactDistBuffer() { return mBoxContactDistancesBuf; }
// PX_FORCE_INLINE PxCudaContextManager* getCudaContextManager() { return mCudaContextManager; }
PX_FORCE_INLINE CUstream getBpStream() { return mStream; }
PX_FORCE_INLINE PxgDevicePointer<PxgBroadPhaseDesc> getBroadPhaseDescDevicePtr() { return mBPDescBuf.getTypedDevicePtr();}
// PX_FORCE_INLINE CUdeviceptr getFoundPairsDevicePtr() { return mFoundPairsBuf.getDevicePtr(); }
// PX_FORCE_INLINE CUdeviceptr getLostPairsDevicePtr() { return mLostPairsBuf.getDevicePtr(); }
PX_FORCE_INLINE PxgAABBManager* getAABBManager() { return mAABBManager; }
void purgeDuplicateFoundPairs();
void purgeDuplicateLostPairs();
// PT: TODO: wait, why is this in the BP?
PX_FORCE_INLINE void sortPairs(PxPinnedArray<PxgBroadPhasePair>& pairs) { sortBuffer(pairs.begin(), pairs.size()); }
PX_FORCE_INLINE void setGPUAABBManager(PxgAABBManager* manager) { mAABBManager = manager; }
#if PX_ENABLE_SIM_STATS
PX_FORCE_INLINE PxU32 getFoundLostPairsStats() { return mFoundLostPairsStats; }
#else
PX_CATCH_UNDEFINED_ENABLE_SIM_STATS
#endif
private:
void gpuDMAUp(const Bp::BroadPhaseUpdateData& updateData, PxgBroadPhaseDesc& desc, PxgRadixSortDesc* rsDescs);
void gpuDMABack(const PxgBroadPhaseDesc& desc);
void createGpuStreamsAndEvents();
void releaseGpuStreamsAndEvents();
void translateAABBsKernel();
void markRemovedPairsKernel();
void markRemovedPairsProjectionsKernel();
void markUpdatedPairsKernel();
void markCreatedPairsKernel();
void sortProjectionAndHandlesWRKernel(PxU32 previousNumOfBoxes);
void sortProjectionAndHandlesWORKernel(PxU32 previousNumOfBoxes);
void initializeSapBoxKernel(const PxU32 numHandles, bool isNew);
void calculateEndPtHistogramKernel(const bool isIncremental);
void computeRegionHistogramKernel();
void computeStartAndActiveHistogramKernel();
void performIncrementalSapKernel();
void generateNewPairsKernel();
void clearNewFlagKernel();
void updateDescriptor(PxgBroadPhaseDesc& bpDesc);
void updateRadixSortDesc(PxgRadixSortDesc* rsDesc);
void runRadixSort(const PxU32 numOfKeys, CUdeviceptr radixSortDescBuf);
void purgeDuplicates(PxPinnedArray<PxgBroadPhasePair>& pairs);
void runCopyResultsKernel(PxgBroadPhaseDesc& desc);
void sortBuffer(PxgBroadPhasePair* reportBuffer, PxU32 size);
PxU64 mContextID;
PxGpuBroadPhaseDesc mDesc;
// PT: from PxgBroadPhaseSap
PxU32 mNumOfBoxes; //total number of boxes in the scene
PxU32 mUpdateData_CreatedHandleSize;
PxU32 mUpdateData_RemovedHandleSize;
#ifdef SUPPORT_UPDATE_HANDLES_ARRAY_FOR_GPU
PxU32 mUpdateData_UpdatedHandleSize;
#endif
PxU32 mUpdateData_BoxesCapacity;
PxgCudaKernelWranglerManager* mGpuKernelWranglerManager;
PxCudaContextManager* mCudaContextManager;
PxCudaContext* mCudaContext;
PxgHeapMemoryAllocatorManager* mHeapMemoryManager;
PxgTypedCudaBuffer<PxU32> mCreatedHandlesBuf;
PxgTypedCudaBuffer<PxU32> mRemovedHandlesBuf;
#ifdef SUPPORT_UPDATE_HANDLES_ARRAY_FOR_GPU
PxgTypedCudaBuffer<PxU32> mUpdatedHandlesBuf;
#endif
//..................................................................// PT: Description: |Comes from: |Passed to kernels as:
//..................................................................//------------------------------------------|-------------------------------------------|------------------------------
PxgTypedCudaBuffer<PxBounds3> mBoxFpBoundsBuf; // box bounds in device memory |BroadPhaseUpdateData::getAABBs() |updateData_fpBounds
PxgTypedCudaBuffer<PxReal> mBoxContactDistancesBuf; // contact distances in device memory |BroadPhaseUpdateData::getContactDistance() |updateData_contactDistances
PxgTypedCudaBuffer<PxU32> mBoxGroupsBuf; // box groups in device memory |BroadPhaseUpdateData::getGroups |updateData_groups
PxgTypedCudaBuffer<PxU32> mBoxEnvIDsBuf; // box env IDs in device memory |BroadPhaseUpdateData::getEnvIDs |updateData_envIDs
PxgTypedCudaBuffer<PxgIntegerAABB> mNewIntegerBoundsBuf; // integer bounds in device memory |translateAABBsLaunch kernel |newIntegerBounds
PxgTypedCudaBuffer<PxgIntegerAABB> mOldIntegerBoundsBuf; // integer bounds in device memory |- |oldIntegerBounds
PxgCudaBufferN<3> mBoxPtProjectionsBuf; // integer bounds in device memory |markCreatedPairsLaunch kernel |boxProjections
PxgCudaBufferN<3> mBoxProjectionRanksBuf;
PxgCudaBufferN<6> mBoxPtHandlesBuf; //double buffer
PxgCudaBufferN<3> mTempBoxPtProjectionBuf;
PxgCudaBufferN<3> mTempBoxPtHandlesBuf;
PxgCudaBufferN<3> mRadixCountBuf;
PxgCudaBufferN<3> mBoxSapBox1DBuf; //PxgSapBox1D, the size should be the same as handles
PxgCudaBufferN<3> mNewBoxSapBox1DBuf; //PxgSapBox1D, the size should be the same as handles
PxgCudaBufferN<6> mEndPtHistogramBuf; //! Histogram for all start handles
PxgCudaBufferN<6> mBlockEndPtHistogramBuf;
PxgCudaBufferN<6> mEndPtHandleBuf;
PxgCudaBufferN<6> mStartPtHistogramBuf;
PxgCudaBufferN<6> mBlockStartPtHistogramBuf;
PxgCudaBufferN<6> mStartPtHandleBuf;
PxgCudaBufferN<6> mTotalEndPtHistogramBuf;
PxgCudaBufferN<6> mBlockTotalEndPtHistogramBuf;
PxgTypedCudaBuffer<int> mActiveRegionTotalBuf;
PxgTypedCudaBuffer<int> mStartRegionsTotalBuf;
PxgTypedCudaBuffer<int> mOrderedActiveRegionHandlesTotalBuf;
PxgTypedCudaBuffer<int> mOrderedStartRegionHandlesTotalBuf;
PxgTypedCudaBuffer<regionOverlapType> mOverlapChecksRegionBuf;
PxgTypedCudaBuffer<regionOverlapType> mBlockOverlapChecksRegionBuf;
regionOverlapType mOverlapChecksTotalRegion;
PxgTypedCudaBuffer<PxgHandleRegion> mOverlapChecksHandleRegionBuf;
PxgCudaBufferN<3> mIncrementalComparisons;
PxgCudaBufferN<3> mIncrementalBlockComparisons;
PxgCudaBufferN<2> mAggregateReportBlockBuf;
PxgCudaBufferN<2> mActorReportBlockBuf;
PxgTypedCudaBuffer<PxgIntegerRegion> mRegionRangeBuf;
PxgTypedCudaBuffer<int> mStartRegionAccumBuf;
PxgTypedCudaBuffer<int> mBlockStartRegionAccumBuf;
PxU32 mStartRegionAccumTotal; //need to write back to cpu every frame
PxgTypedCudaBuffer<int> mRegionAccumBuf;
PxgTypedCudaBuffer<int> mBlockRegionAccumBuf;
PxU32 mRegionAccumTotal; //need to write back to cpu every frame
PxgTypedCudaBuffer<PxgBroadPhasePair> mFoundPairsBuf; //total found pairs(include actors and aggregates)
PxgTypedCudaBuffer<PxgBroadPhasePair> mLostPairsBuf; //total lost pairs(include actors and aggregates)
PxgTypedCudaBuffer<PxgBroadPhasePair> mFoundAggregateBuf;
PxgTypedCudaBuffer<PxgBroadPhasePair> mLostAggregateBuf;
PxgTypedCudaBuffer<PxgBroadPhasePair> mFoundActorBuf;
PxgTypedCudaBuffer<PxgBroadPhasePair> mLostActorBuf;
PxgTypedCudaBuffer<PxgBroadPhaseDesc> mBPDescBuf;
PxgTypedCudaBuffer<PxgRadixSortDesc> mRadixSortDescBuf;
PxgTypedCudaBuffer<PxgRadixSortDesc> mRadixSortWORDescBuf;
CUstream mStream;
CUevent mEvent;
PxU32* mPinnedEvent;
PxgBroadPhaseDesc* mBpDesc;
PxgRadixSortDesc* mRSDesc;
PxgRadixSortDesc* mRSDescWOR; //wor :: without ranks
PxPinnedArray<PxgBroadPhasePair> mFoundActorPairs;
PxPinnedArray<PxgBroadPhasePair> mLostActorPairs;
//PxArray<PxU32> mHistogramBuffer;
//PxArray<PxgBroadPhasePair> mTempPairBuffer;
PxU32 mMaxFoundLostPairs;
PxU32 mMaxAggFoundLostPairs;
PxgAABBManager* mAABBManager;
#if PX_ENABLE_SIM_STATS
PxU32 mFoundLostPairsStats; // keeps track of max lost found pairs value to tune preallocated buffer size.
#else
PX_CATCH_UNDEFINED_ENABLE_SIM_STATS
#endif
bool mForceUpdate;
};
}
#endif

View File

@@ -0,0 +1,225 @@
// 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.
// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
#ifndef PXG_INTEGER_AABB_H
#define PXG_INTEGER_AABB_H
#include "foundation/PxSimpleTypes.h"
#include "foundation/PxBounds3.h"
#include "vector_types.h"
namespace physx
{
class PxgIntegerAABB
{
public:
enum
{
MIN_X = 0,
MIN_Y,
MIN_Z,
MAX_X,
MAX_Y,
MAX_Z
};
/*
\brief Return the minimum along a specified axis
\param[in] i is the axis
*/
PX_CUDA_CALLABLE PX_FORCE_INLINE PxU32 getMin(PxU32 i) const { return (mMinMax)[MIN_X+i]; }
/*
\brief Return the maximum along a specified axis
\param[in] i is the axis
*/
PX_CUDA_CALLABLE PX_FORCE_INLINE PxU32 getMax(PxU32 i) const { return (mMinMax)[MAX_X+i]; }
/*
\brief Encode float bounds so they are stored as integer bounds
\param[in] bounds is the bounds to be encoded
\note The integer values of minima are always even, while the integer values of maxima are always odd
\note The encoding process masks off the last four bits for minima and masks on the last four bits for maxima.
This keeps the bounds constant when its shape is subjected to small global pose perturbations. In turn, this helps
reduce computational effort in the broadphase update by reducing the amount of sorting required on near-stationary
bodies that are aligned along one or more axis.
\see decode
*/
PX_FORCE_INLINE void encode(const PxBounds3& bounds)
{
const PxU32* PX_RESTRICT min = reinterpret_cast<const PxU32*>(&bounds.minimum.x);
const PxU32* PX_RESTRICT max = reinterpret_cast<const PxU32*>(&bounds.maximum.x);
//Avoid min=max by enforcing the rule that mins are even and maxs are odd.
mMinMax[MIN_X] = (encodeFloatMin(min[0]) + 1) & ~1;
mMinMax[MIN_Y] = (encodeFloatMin(min[1]) + 1) & ~1;
mMinMax[MIN_Z] = (encodeFloatMin(min[2]) + 1) & ~1;
mMinMax[MAX_X] = encodeFloatMax(max[0]) | 1;
mMinMax[MAX_Y] = encodeFloatMax(max[1]) | 1;
mMinMax[MAX_Z] = encodeFloatMax(max[2]) | 1;
}
/*
\brief Decode from integer bounds to float bounds
\param[out] bounds is the decoded float bounds
\note Encode followed by decode will produce a float bound larger than the original
due to the masking in encode.
\see encode
*/
PX_CUDA_CALLABLE PX_FORCE_INLINE void decode(PxBounds3& bounds) const
{
PxU32* PX_RESTRICT min = reinterpret_cast<PxU32*>(&bounds.minimum.x);
PxU32* PX_RESTRICT max = reinterpret_cast<PxU32*>(&bounds.maximum.x);
min[0] = decodeFloat(mMinMax[MIN_X]);
min[1] = decodeFloat(mMinMax[MIN_Y]);
min[2] = decodeFloat(mMinMax[MIN_Z]);
max[0] = decodeFloat(mMinMax[MAX_X]);
max[1] = decodeFloat(mMinMax[MAX_Y]);
max[2] = decodeFloat(mMinMax[MAX_Z]);
}
/*
\brief Encode a single minimum value from integer bounds to float bounds
\note The encoding process masks off the last four bits for minima
\see encode
*/
static PX_CUDA_CALLABLE PX_FORCE_INLINE PxU32 encodeFloatMin(PxU32 source)
{
return ((encodeFloat(source) >> eGRID_SNAP_VAL) - 1) << eGRID_SNAP_VAL;
}
/*
\brief Encode a single maximum value from integer bounds to float bounds
\note The encoding process masks on the last four bits for maxima
\see encode
*/
static PX_CUDA_CALLABLE PX_FORCE_INLINE PxU32 encodeFloatMax(PxU32 source)
{
return ((encodeFloat(source) >> eGRID_SNAP_VAL) + 1) << eGRID_SNAP_VAL;
}
/*
\brief Encode a single float value with lossless encoding to integer
*/
PX_CUDA_CALLABLE static PX_FORCE_INLINE PxU32 encodeFloat(PxU32 newPos)
{
//we may need to check on -0 and 0
//But it should make no practical difference.
if(newPos & PX_SIGN_BITMASK) //negative?
return ~newPos;//reverse sequence of negative numbers
else
return newPos | PX_SIGN_BITMASK; // flip sign
}
/*
\brief Encode a single float value with lossless encoding to integer
*/
PX_CUDA_CALLABLE static PX_FORCE_INLINE PxU32 decodeFloat(PxU32 ir)
{
if(ir & PX_SIGN_BITMASK) //positive?
return ir & ~PX_SIGN_BITMASK; //flip sign
else
return ~ir; //undo reversal
}
/*
\brief Shift the encoded bounds by a specified vector
\param[in] shift is the vector used to shift the bounds
*/
PX_FORCE_INLINE void shift(const PxVec3& shift)
{
::physx::PxBounds3 elemBounds;
decode(elemBounds);
elemBounds.minimum -= shift;
elemBounds.maximum -= shift;
encode(elemBounds);
}
/*
\brief Test if this aabb and another intersect
\param[in] b is the other box
\return True if this aabb and b intersect
*/
PX_CUDA_CALLABLE PX_FORCE_INLINE bool intersects(const PxgIntegerAABB& b) const
{
return !(b.mMinMax[MIN_X] > mMinMax[MAX_X] || mMinMax[MIN_X] > b.mMinMax[MAX_X] ||
b.mMinMax[MIN_Y] > mMinMax[MAX_Y] || mMinMax[MIN_Y] > b.mMinMax[MAX_Y] ||
b.mMinMax[MIN_Z] > mMinMax[MAX_Z] || mMinMax[MIN_Z] > b.mMinMax[MAX_Z]);
}
PX_CUDA_CALLABLE PX_FORCE_INLINE bool intersects1D(const PxgIntegerAABB& b, const PxU32 axis) const
{
const PxU32 maxAxis = axis + 3;
return !(b.mMinMax[axis] > mMinMax[maxAxis] || mMinMax[axis] > b.mMinMax[maxAxis]);
}
/*
\brief Set the bounds to (max, max, max), (min, min, min)
*/
PX_CUDA_CALLABLE PX_INLINE void setEmpty()
{
mMinMax[MIN_X] = mMinMax[MIN_Y] = mMinMax[MIN_Z] = 0xff7fffff; //PX_IR(PX_MAX_F32);
mMinMax[MAX_X] = mMinMax[MAX_Y] = mMinMax[MAX_Z] = 0x00800000; ///PX_IR(0.0f);
}
PX_CUDA_CALLABLE PX_INLINE bool isEmpty() const
{
return mMinMax[MIN_X] == 0xff7fffff && mMinMax[MIN_Y] == 0xff7fffff && mMinMax[MIN_Z] == 0xff7fffff && //PX_IR(PX_MAX_F32);
mMinMax[MAX_X] == 0x00800000 && mMinMax[MAX_Y] == 0x00800000 && mMinMax[MAX_Z] == 0x00800000; ///PX_IR(0.0f);
}
PxU32 mMinMax[6];
private:
enum
{
eGRID_SNAP_VAL = 4
};
};
//This is used for the total overlap checks
struct PxgHandleRegion
{
PxU32 handleIndex;
PxU32 regionIndex;
};
struct PxgIntegerRegion
{
uint4 minRange;
uint4 maxRange;
};
}
#endif

View File

@@ -0,0 +1,56 @@
// 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.
// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
#ifndef PXG_SAPBOX_1D_H
#define PXG_SAPBOX_1D_H
#include "PxgBroadPhaseCommonDefines.h"
namespace physx
{
class PxgSapBox1D
{
public:
PX_CUDA_CALLABLE PX_FORCE_INLINE PxgSapBox1D() { mMinMax[0] = PXG_INVALID_BP_HANDLE; mMinMax[1]=PXG_INVALID_BP_HANDLE; }
PX_CUDA_CALLABLE PX_FORCE_INLINE ~PxgSapBox1D() {}
PX_CUDA_CALLABLE bool validHandle() const
{
return (mMinMax[0] != PXG_INVALID_BP_HANDLE) && (mMinMax[1]!=PXG_INVALID_BP_HANDLE);
}
PxU32 mMinMax[2];//mMinMax[0]=min, mMinMax[1]=max
};
}
#endif