removed SpuRaycaster and SpuParallelSolver, both were obsolete: slow, broken and unsupported
This commit is contained in:
@@ -45,11 +45,6 @@ ADD_LIBRARY(BulletMultiThreaded
|
||||
SpuNarrowPhaseCollisionTask/SpuCollisionShapes.cpp
|
||||
SpuNarrowPhaseCollisionTask/SpuCollisionShapes.h
|
||||
|
||||
SpuParallelSolver.cpp
|
||||
SpuParallelSolver.h
|
||||
SpuSolverTask/SpuParallellSolverTask.cpp
|
||||
SpuSolverTask/SpuParallellSolverTask.h
|
||||
|
||||
|
||||
#Some GPU related stuff, mainly CUDA and perhaps OpenCL
|
||||
btGpu3DGridBroadphase.cpp
|
||||
|
||||
@@ -2,7 +2,7 @@ SubDir TOP src BulletMultiThreaded ;
|
||||
|
||||
#IncludeDir src/BulletMultiThreaded ;
|
||||
|
||||
Library bulletmultithreaded : [ Wildcard . : *.h *.cpp ] [ Wildcard MiniCLTask : *.h *.cpp ] [ Wildcard SpuNarrowPhaseCollisionTask : *.h *.cpp ] [ Wildcard SpuSolverTask : *.h *.cpp ] : noinstall ;
|
||||
Library bulletmultithreaded : [ Wildcard . : *.h *.cpp ] [ Wildcard MiniCLTask : *.h *.cpp ] [ Wildcard SpuNarrowPhaseCollisionTask : *.h *.cpp ] : noinstall ;
|
||||
CFlags bulletmultithreaded : [ FIncludes $(TOP)/src/BulletMultiThreaded ] [ FIncludes $(TOP)/src/BulletMultiThreaded/vectormath/scalar/cpp ] ;
|
||||
LibDepends bulletmultithreaded : ;
|
||||
|
||||
|
||||
@@ -1,151 +0,0 @@
|
||||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2003-2007 Erwin Coumans http://bulletphysics.com
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#include <new>
|
||||
#include "BulletCollision/CollisionShapes/btCollisionShape.h"
|
||||
#include "LinearMath/btAlignedAllocator.h"
|
||||
#include "SpuBatchRaycaster.h"
|
||||
|
||||
SpuBatchRaycaster::SpuBatchRaycaster (class btThreadSupportInterface* threadInterface, int maxNumOutstandingTasks)
|
||||
{
|
||||
m_threadInterface = threadInterface;
|
||||
|
||||
castUponObjectWrappers = NULL;
|
||||
numCastUponObjectWrappers = 0;
|
||||
|
||||
m_spuRaycastTaskProcess = new SpuRaycastTaskProcess(m_threadInterface,maxNumOutstandingTasks); // FIXME non constant
|
||||
}
|
||||
|
||||
SpuBatchRaycaster::~SpuBatchRaycaster ()
|
||||
{
|
||||
if (castUponObjectWrappers)
|
||||
{
|
||||
btAlignedFree (castUponObjectWrappers);
|
||||
castUponObjectWrappers = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
SpuBatchRaycaster::setCollisionObjects (btCollisionObjectArray& castUponObjects, int numCastUponObjects)
|
||||
{
|
||||
if (castUponObjectWrappers)
|
||||
{
|
||||
btAlignedFree (castUponObjectWrappers);
|
||||
castUponObjectWrappers = NULL;
|
||||
}
|
||||
|
||||
castUponObjectWrappers = (SpuCollisionObjectWrapper*)btAlignedAlloc (sizeof(SpuCollisionObjectWrapper) * numCastUponObjects,16);
|
||||
numCastUponObjectWrappers = numCastUponObjects;
|
||||
|
||||
for (int i = 0; i < numCastUponObjectWrappers; i++)
|
||||
{
|
||||
castUponObjectWrappers[i] = SpuCollisionObjectWrapper(castUponObjects[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
SpuBatchRaycaster::setCollisionObjectsSkipPE (btCollisionObjectArray& castUponObjects, int numCastUponObjects)
|
||||
{
|
||||
if (castUponObjectWrappers)
|
||||
{
|
||||
btAlignedFree (castUponObjectWrappers);
|
||||
castUponObjectWrappers = NULL;
|
||||
}
|
||||
|
||||
int numNonPEShapes = 0;
|
||||
for (int i = 0; i < numCastUponObjects; i++)
|
||||
{
|
||||
const btCollisionShape* shape = castUponObjects[i]->getCollisionShape();
|
||||
|
||||
if (shape->getShapeType () == BOX_SHAPE_PROXYTYPE ||
|
||||
shape->getShapeType () == SPHERE_SHAPE_PROXYTYPE ||
|
||||
shape->getShapeType () == CAPSULE_SHAPE_PROXYTYPE)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
numNonPEShapes++;
|
||||
}
|
||||
|
||||
castUponObjectWrappers = (SpuCollisionObjectWrapper*)btAlignedAlloc (sizeof(SpuCollisionObjectWrapper) * numNonPEShapes,16);
|
||||
numCastUponObjectWrappers = numNonPEShapes;
|
||||
|
||||
int index = 0;
|
||||
for (int i = 0; i < numCastUponObjects; i++)
|
||||
{
|
||||
const btCollisionShape* shape = castUponObjects[i]->getCollisionShape();
|
||||
|
||||
if (shape->getShapeType () == BOX_SHAPE_PROXYTYPE ||
|
||||
shape->getShapeType () == SPHERE_SHAPE_PROXYTYPE ||
|
||||
shape->getShapeType () == CAPSULE_SHAPE_PROXYTYPE)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
castUponObjectWrappers[index] = SpuCollisionObjectWrapper(castUponObjects[i]);
|
||||
index++;
|
||||
}
|
||||
|
||||
// printf("Number of shapes bullet is casting against: %d\n", numNonPEShapes);
|
||||
btAssert (index == numNonPEShapes);
|
||||
}
|
||||
|
||||
void
|
||||
SpuBatchRaycaster::addRay (const btVector3& rayFrom, const btVector3& rayTo, const btScalar hitFraction)
|
||||
{
|
||||
SpuRaycastTaskWorkUnitOut workUnitOut;
|
||||
workUnitOut.hitFraction = hitFraction;
|
||||
workUnitOut.hitNormal = btVector3(0.0, 1.0, 0.0);
|
||||
|
||||
rayBatchOutput.push_back (workUnitOut);
|
||||
|
||||
SpuRaycastTaskWorkUnit workUnit;
|
||||
workUnit.rayFrom = rayFrom;
|
||||
workUnit.rayTo = rayTo;
|
||||
rayBatch.push_back (workUnit);
|
||||
}
|
||||
|
||||
void
|
||||
SpuBatchRaycaster::clearRays ()
|
||||
{
|
||||
rayBatch.clear ();
|
||||
rayBatchOutput.clear ();
|
||||
}
|
||||
|
||||
void
|
||||
SpuBatchRaycaster::performBatchRaycast ()
|
||||
{
|
||||
m_spuRaycastTaskProcess->initialize2 (castUponObjectWrappers, numCastUponObjectWrappers);
|
||||
|
||||
for (int i = 0; i < rayBatch.size(); i++)
|
||||
{
|
||||
rayBatch[i].output = &rayBatchOutput[i]; // assign output memory location
|
||||
m_spuRaycastTaskProcess->addWorkToTask(rayBatch[i]);
|
||||
}
|
||||
|
||||
m_spuRaycastTaskProcess->flush2 ();
|
||||
}
|
||||
|
||||
const SpuRaycastTaskWorkUnitOut&
|
||||
SpuBatchRaycaster::operator [] (int i) const
|
||||
{
|
||||
return rayBatchOutput[i];
|
||||
}
|
||||
|
||||
int
|
||||
SpuBatchRaycaster::getNumRays () const
|
||||
{
|
||||
return rayBatchOutput.size();
|
||||
}
|
||||
@@ -1,49 +0,0 @@
|
||||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2003-2007 Erwin Coumans http://bulletphysics.com
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#ifndef SPU_BATCH_RAYCASTER_H
|
||||
#define SPU_BATCH_RAYCASTER_H
|
||||
|
||||
#include "LinearMath/btAlignedObjectArray.h"
|
||||
#include "BulletCollision/CollisionDispatch/btCollisionObject.h"
|
||||
#include "SpuRaycastTaskProcess.h"
|
||||
#include "SpuRaycastTask/SpuRaycastTask.h"
|
||||
#include "SpuCollisionObjectWrapper.h"
|
||||
|
||||
/* FIXME:
|
||||
* Need to decide how callbacks are performed...
|
||||
*/
|
||||
class SpuBatchRaycaster
|
||||
{
|
||||
protected:
|
||||
SpuCollisionObjectWrapper* castUponObjectWrappers;
|
||||
int numCastUponObjectWrappers;
|
||||
btAlignedObjectArray<SpuRaycastTaskWorkUnit> rayBatch;
|
||||
btAlignedObjectArray<SpuRaycastTaskWorkUnitOut> rayBatchOutput;
|
||||
SpuRaycastTaskProcess* m_spuRaycastTaskProcess;
|
||||
class btThreadSupportInterface* m_threadInterface;
|
||||
public:
|
||||
SpuBatchRaycaster (class btThreadSupportInterface* threadInterface, int maxNumOutstandingTasks);
|
||||
~SpuBatchRaycaster ();
|
||||
void setCollisionObjects (btCollisionObjectArray& castUponObjects, int numCastUponObjects);
|
||||
void setCollisionObjectsSkipPE (btCollisionObjectArray& castUponObjects, int numCastUponObjects);
|
||||
void addRay (const btVector3& rayFrom, const btVector3& rayTo, const btScalar hitFraction = 1.0);
|
||||
void clearRays ();
|
||||
void performBatchRaycast ();
|
||||
const SpuRaycastTaskWorkUnitOut& operator [] (int i) const;
|
||||
int getNumRays () const;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,643 +0,0 @@
|
||||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library - Parallel solver
|
||||
Copyright (c) 2007 Starbreeze Studios
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
|
||||
Written by: Marten Svanfeldt
|
||||
*/
|
||||
|
||||
#include "SpuParallelSolver.h"
|
||||
|
||||
//#include "SpuFakeDma.h"
|
||||
#include "SpuSync.h"
|
||||
|
||||
#include "LinearMath/btVector3.h"
|
||||
#include "BulletCollision/NarrowPhaseCollision/btPersistentManifold.h"
|
||||
#include "BulletDynamics/Dynamics/btRigidBody.h"
|
||||
#include "BulletDynamics/ConstraintSolver/btContactSolverInfo.h"
|
||||
#include "LinearMath/btMinMax.h"
|
||||
#include "BulletCollision/CollisionShapes/btCollisionShape.h"
|
||||
#include "BulletCollision/CollisionDispatch/btCollisionObject.h"
|
||||
#include "BulletDynamics/ConstraintSolver/btTypedConstraint.h"
|
||||
#include "LinearMath/btQuickprof.h"
|
||||
|
||||
#include "SpuSolverTask/SpuParallellSolverTask.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
enum
|
||||
{
|
||||
PARALLEL_SOLVER_BODIES_PER_TASK = 64,
|
||||
PARALLEL_SOLVER_CELLS_PER_TASK = SPU_HASH_NUMCELLS >> 3
|
||||
};
|
||||
|
||||
|
||||
//-- Hash handling
|
||||
static void recordDependency(SpuSolverHash* hash, unsigned int i, unsigned int j)
|
||||
{
|
||||
hash->m_dependencyMatrix[i][j >> 5] |= (1 << (j & 31));
|
||||
hash->m_dependencyMatrix[j][i >> 5] |= (1 << (i & 31));
|
||||
}
|
||||
|
||||
|
||||
// Clear the given hash
|
||||
static void clearHash (SpuSolverHash* hash)
|
||||
{
|
||||
size_t hashSize = sizeof(SpuSolverHash);
|
||||
memset(hash, 0, hashSize);
|
||||
int i;
|
||||
|
||||
// Setup basic dependency
|
||||
for ( i = 0; i < SPU_HASH_NUMCELLS; ++i)
|
||||
{
|
||||
hash->m_dependencyMatrix[i][i >> 5] |= (1 << (i & 31));
|
||||
}
|
||||
|
||||
// Set some ones to "unused cells"
|
||||
for ( i = SPU_HASH_WORDWIDTH-SPU_HASH_NUMUNUSEDBITS; i < SPU_HASH_WORDWIDTH; ++i)
|
||||
{
|
||||
hash->m_currentMask[0][SPU_HASH_NUMCELLDWORDS-1] |= (1 << i);
|
||||
}
|
||||
}
|
||||
/*
|
||||
static bool getDependency(SpuSolverHash* hash, unsigned int i, unsigned int j)
|
||||
{
|
||||
return (hash->m_dependencyMatrix[i][j >> 5] & (1 << (j & 31))) != 0;
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
static unsigned int getObjectIndex (btCollisionObject* object)
|
||||
{
|
||||
btVector3 center = object->getWorldTransform().getOrigin();
|
||||
int cx = (int)floorf(center.x() / SPU_HASH_PHYSSIZE);
|
||||
int cy = (int)floorf(center.y() / SPU_HASH_PHYSSIZE);
|
||||
int cz = (int)floorf(center.z() / SPU_HASH_PHYSSIZE);
|
||||
|
||||
return spuGetHashCellIndex(cx, cy, cz);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
btParallelSequentialImpulseSolver::btParallelSequentialImpulseSolver (btThreadSupportInterface* threadIf, int maxOutstandingTasks)
|
||||
: m_numberOfContacts(0), m_taskScheduler (threadIf, maxOutstandingTasks)
|
||||
{
|
||||
m_solverHash = new SpuSolverHash;
|
||||
clearHash(m_solverHash);
|
||||
}
|
||||
|
||||
btParallelSequentialImpulseSolver::~btParallelSequentialImpulseSolver ()
|
||||
{
|
||||
delete m_solverHash;
|
||||
}
|
||||
|
||||
|
||||
void btParallelSequentialImpulseSolver::prepareSolve(int numBodies, int numManifolds)
|
||||
{
|
||||
m_sortedManifolds.reserve(numManifolds);
|
||||
m_allObjects.reserve(numBodies);
|
||||
}
|
||||
|
||||
btScalar btParallelSequentialImpulseSolver::solveGroup(btCollisionObject** bodies,int numBodies,btPersistentManifold** manifold,int numManifolds,btTypedConstraint** constraints,int numConstraints, const btContactSolverInfo& info,class btIDebugDraw* debugDrawer, btStackAlloc* stackAlloc,btDispatcher* dispatcher)
|
||||
{
|
||||
BT_PROFILE("parallel_solveGroup");
|
||||
|
||||
if (!numManifolds && !numConstraints)
|
||||
return 0;
|
||||
int i;
|
||||
|
||||
///refresh contact points is not needed anymore, it has been moved into the processCollision detection part.
|
||||
#ifdef FORCE_REFESH_CONTACT_MANIFOLDS
|
||||
for ( i = 0; i < numManifolds; ++i)
|
||||
{
|
||||
btPersistentManifold* currManifold = manifold[i];
|
||||
btRigidBody* rb0 = (btRigidBody*)currManifold->getBody0();
|
||||
btRigidBody* rb1 = (btRigidBody*)currManifold->getBody1();
|
||||
|
||||
currManifold->refreshContactPoints(rb0->getCenterOfMassTransform(),rb1->getCenterOfMassTransform());
|
||||
}
|
||||
#endif //FORCE_REFESH_CONTACT_MANIFOLDS
|
||||
|
||||
// Record and mark the manifolds to the cells
|
||||
for ( i = 0; i < numManifolds; ++i)
|
||||
{
|
||||
// Compute a hash cell for this manifold
|
||||
btPersistentManifold* currManifold = manifold[i];
|
||||
|
||||
btCollisionObject *ownerObject, *otherObject;
|
||||
|
||||
btRigidBody* rb0 = (btRigidBody*)currManifold->getBody0();
|
||||
btRigidBody* rb1 = (btRigidBody*)currManifold->getBody1();
|
||||
|
||||
if (rb0->getIslandTag() >= 0)
|
||||
{
|
||||
ownerObject = rb0;
|
||||
otherObject = rb1;
|
||||
}
|
||||
else
|
||||
{
|
||||
ownerObject = rb1;
|
||||
otherObject = rb0;
|
||||
}
|
||||
|
||||
// Save the cell
|
||||
unsigned int ownerCellIdx = getObjectIndex(ownerObject);
|
||||
ManifoldCellHolder holder = {ownerCellIdx, currManifold};
|
||||
m_sortedManifolds.push_back(holder);
|
||||
m_solverHash->m_Hash[ownerCellIdx].m_numManifolds++;
|
||||
|
||||
// Record dependency
|
||||
if (rb0->getIslandTag() >= 0 && rb1->getIslandTag() >= 0)
|
||||
{
|
||||
unsigned int otherCellIdx = getObjectIndex(otherObject);
|
||||
recordDependency(m_solverHash, ownerCellIdx, otherCellIdx);
|
||||
}
|
||||
|
||||
// Save statistics
|
||||
int numContacts = currManifold->getNumContacts();
|
||||
m_solverHash->m_Hash[ownerCellIdx].m_numContacts += numContacts;
|
||||
m_numberOfContacts += numContacts;
|
||||
}
|
||||
|
||||
// Record and mark constraints to the cells
|
||||
for ( i = 0; i < numConstraints; ++i)
|
||||
{
|
||||
// Compute a hash cell for this manifold
|
||||
btTypedConstraint* currConstraint = constraints[i];
|
||||
|
||||
if (!constraintTypeSupported(currConstraint->getConstraintType()))
|
||||
continue;
|
||||
|
||||
btCollisionObject *ownerObject, *otherObject;
|
||||
|
||||
btRigidBody* rb0 = &currConstraint->getRigidBodyA();
|
||||
btRigidBody* rb1 = &currConstraint->getRigidBodyB();
|
||||
|
||||
if (rb0->getIslandTag() >= 0)
|
||||
{
|
||||
ownerObject = rb0;
|
||||
otherObject = rb1;
|
||||
}
|
||||
else
|
||||
{
|
||||
ownerObject = rb1;
|
||||
otherObject = rb0;
|
||||
}
|
||||
|
||||
// Save the cell
|
||||
unsigned int ownerCellIdx = getObjectIndex(ownerObject);
|
||||
ConstraintCellHolder holder = {ownerCellIdx, currConstraint->getConstraintType(), currConstraint};
|
||||
m_sortedConstraints.push_back(holder);
|
||||
m_solverHash->m_Hash[ownerCellIdx].m_numConstraints++;
|
||||
|
||||
// Record dependency
|
||||
if (rb0 && rb1 && rb0->getIslandTag() >= 0 && rb1->getIslandTag() >= 0)
|
||||
{
|
||||
unsigned int otherCellIdx = getObjectIndex(otherObject);
|
||||
recordDependency(m_solverHash, ownerCellIdx, otherCellIdx);
|
||||
}
|
||||
}
|
||||
|
||||
// Save all RBs
|
||||
for ( i = 0; i < numBodies; ++i)
|
||||
{
|
||||
btCollisionObject* obj = bodies[i];
|
||||
//unsigned int cellIdx = getObjectIndex(obj);
|
||||
|
||||
btRigidBody* rb = btRigidBody::upcast(obj);
|
||||
m_allObjects.push_back(rb);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
class CellHolderPredicate
|
||||
{
|
||||
public:
|
||||
SIMD_FORCE_INLINE bool operator() ( const T& lhs, const T& rhs )
|
||||
{
|
||||
return lhs.m_hashCellIndex < rhs.m_hashCellIndex;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/*static void printDependencyMatrix(SpuSolverHash* hash)
|
||||
{
|
||||
for (int r = 0; r < SPU_HASH_NUMCELLS; ++r)
|
||||
{
|
||||
for (int c = 0; c < SPU_HASH_NUMCELLS; ++c)
|
||||
{
|
||||
if (getDependency(hash, r, c))
|
||||
{
|
||||
printf("1");
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("0");
|
||||
}
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
}
|
||||
printf("\n");
|
||||
fflush(stdout);
|
||||
}
|
||||
*/
|
||||
|
||||
// Solver caches
|
||||
btAlignedObjectArray<btSolverBody> solverBodyPool_persist;
|
||||
btAlignedObjectArray<uint32_t> solverBodyOffsetList_persist;
|
||||
btAlignedObjectArray<btSolverConstraint> solverInternalConstraintPool_persist;
|
||||
btAlignedObjectArray<btSolverConstraint> solverConstraintPool_persist;
|
||||
|
||||
|
||||
void btParallelSequentialImpulseSolver::allSolved (const btContactSolverInfo& info,class btIDebugDraw* debugDrawer, btStackAlloc* stackAlloc)
|
||||
{
|
||||
BT_PROFILE("parallel_allSolved");
|
||||
|
||||
if (!m_numberOfContacts && !m_sortedConstraints.size())
|
||||
{
|
||||
m_sortedManifolds.clear();
|
||||
m_sortedConstraints.clear();
|
||||
m_allObjects.clear();
|
||||
clearHash(m_solverHash);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
//printDependencyMatrix(m_solverHash);
|
||||
|
||||
// Sort the manifolds list
|
||||
int numManifolds = m_sortedManifolds.size();
|
||||
m_sortedManifolds.quickSort(CellHolderPredicate<ManifoldCellHolder>());
|
||||
|
||||
// Sort the constraint list
|
||||
int numConstraints = m_sortedConstraints.size();
|
||||
m_sortedConstraints.quickSort(CellHolderPredicate<ConstraintCellHolder>());
|
||||
|
||||
|
||||
// Sort the body list
|
||||
int numBodies = m_allObjects.size();
|
||||
|
||||
// Reassign the hash offset
|
||||
uint32_t emptyCellMask[SPU_HASH_NUMCELLDWORDS] = {0};
|
||||
int numBodyOffsets = 0;
|
||||
{
|
||||
int manifoldRunner = 0;
|
||||
int bodyOffsetRunner = 0;
|
||||
int internalConstraintRunner = 0;
|
||||
int constraintRunner = 0;
|
||||
|
||||
for (int i = 0; i < SPU_HASH_NUMCELLS; ++i)
|
||||
{
|
||||
bool empty = true;
|
||||
|
||||
SpuSolverHashCell& hashCell = m_solverHash->m_Hash[i];
|
||||
hashCell.m_solverBodyOffsetListOffset = bodyOffsetRunner;
|
||||
|
||||
if (hashCell.m_numManifolds)
|
||||
{
|
||||
hashCell.m_manifoldListOffset = manifoldRunner;
|
||||
manifoldRunner += hashCell.m_numManifolds;
|
||||
|
||||
bodyOffsetRunner += hashCell.m_numManifolds*2;
|
||||
}
|
||||
if (hashCell.m_numContacts)
|
||||
{
|
||||
hashCell.m_internalConstraintListOffset = internalConstraintRunner*3;
|
||||
internalConstraintRunner += hashCell.m_numContacts;
|
||||
empty = false;
|
||||
}
|
||||
|
||||
if (hashCell.m_numConstraints)
|
||||
{
|
||||
hashCell.m_constraintListOffset = constraintRunner;
|
||||
constraintRunner += hashCell.m_numConstraints;
|
||||
|
||||
bodyOffsetRunner += hashCell.m_numConstraints*2;
|
||||
|
||||
empty = false;
|
||||
}
|
||||
|
||||
|
||||
emptyCellMask[i >> 5] |= (empty ? (1 << (i&31)) : 0);
|
||||
// Align the bodyOffsetRunner to a whole number of 4 for right alignment in the list
|
||||
bodyOffsetRunner = (bodyOffsetRunner+3)&~0x3;
|
||||
}
|
||||
|
||||
numBodyOffsets = bodyOffsetRunner;
|
||||
}
|
||||
|
||||
// Setup rigid bodies
|
||||
// Allocate temporary data
|
||||
solverBodyPool_persist.resize(numBodies + numManifolds + numConstraints);
|
||||
btSolverBody* solverBodyPool = &solverBodyPool_persist[0];
|
||||
|
||||
solverBodyOffsetList_persist.resize(numBodyOffsets);
|
||||
uint32_t* solverBodyOffsetList = &solverBodyOffsetList_persist[0];
|
||||
|
||||
solverInternalConstraintPool_persist.resize(m_numberOfContacts*3);
|
||||
btSolverConstraint* solverInternalConstraintPool = &solverInternalConstraintPool_persist[0];
|
||||
|
||||
solverConstraintPool_persist.resize(numConstraints);
|
||||
btSolverConstraint* solverConstraintPool = &solverConstraintPool_persist[0];
|
||||
|
||||
// Setup all the moving rigid bodies
|
||||
{
|
||||
BT_PROFILE("setup moving rigidbodies");
|
||||
|
||||
int bodiesPerTask = PARALLEL_SOLVER_BODIES_PER_TASK;
|
||||
int bodiesToSchedule = numBodies;
|
||||
int startBody = 0;
|
||||
|
||||
while (bodiesToSchedule > 0)
|
||||
{
|
||||
// Schedule a bunch of hash cells
|
||||
int numBodiesInTask = bodiesToSchedule > bodiesPerTask ? bodiesPerTask : bodiesToSchedule;
|
||||
|
||||
SpuSolverTaskDesc* desc = m_taskScheduler.getTask();
|
||||
|
||||
desc->m_solverCommand = CMD_SOLVER_SETUP_BODIES;
|
||||
desc->m_solverData.m_solverHash = m_solverHash;
|
||||
desc->m_solverData.m_solverBodyList = solverBodyPool;
|
||||
|
||||
desc->m_commandData.m_bodySetup.m_startBody = startBody;
|
||||
desc->m_commandData.m_bodySetup.m_numBodies = numBodiesInTask;
|
||||
desc->m_commandData.m_bodySetup.m_rbList = &m_allObjects[0];
|
||||
|
||||
m_taskScheduler.issueTask();
|
||||
bodiesToSchedule -= numBodiesInTask;
|
||||
startBody += numBodiesInTask;
|
||||
}
|
||||
|
||||
m_taskScheduler.flushTasks();
|
||||
}
|
||||
|
||||
// Manifold setup
|
||||
{
|
||||
int cellsPerTask = PARALLEL_SOLVER_CELLS_PER_TASK;
|
||||
int cellsToSchedule = SPU_HASH_NUMCELLS;
|
||||
int startCell = 0;
|
||||
|
||||
while (cellsToSchedule > 0)
|
||||
{
|
||||
int numCellsInTask = cellsToSchedule > cellsPerTask ? cellsPerTask : cellsToSchedule;
|
||||
|
||||
SpuSolverTaskDesc* desc = m_taskScheduler.getTask();
|
||||
|
||||
desc->m_solverCommand = CMD_SOLVER_MANIFOLD_SETUP;
|
||||
desc->m_solverData.m_solverHash = m_solverHash;
|
||||
desc->m_solverData.m_solverBodyList = solverBodyPool;
|
||||
desc->m_solverData.m_solverBodyOffsetList = solverBodyOffsetList;
|
||||
desc->m_solverData.m_solverInternalConstraintList = solverInternalConstraintPool;
|
||||
desc->m_solverData.m_solverConstraintList = solverConstraintPool;
|
||||
|
||||
desc->m_commandData.m_manifoldSetup.m_startCell = startCell;
|
||||
desc->m_commandData.m_manifoldSetup.m_numCells = numCellsInTask;
|
||||
desc->m_commandData.m_manifoldSetup.m_numBodies = numBodies;
|
||||
desc->m_commandData.m_manifoldSetup.m_numManifolds = numManifolds;
|
||||
desc->m_commandData.m_manifoldSetup.m_manifoldHolders = &m_sortedManifolds[0];
|
||||
desc->m_commandData.m_manifoldSetup.m_constraintHolders = &m_sortedConstraints[0];
|
||||
desc->m_commandData.m_manifoldSetup.m_solverInfo = info;
|
||||
|
||||
m_taskScheduler.issueTask();
|
||||
cellsToSchedule -= numCellsInTask;
|
||||
startCell += numCellsInTask;
|
||||
}
|
||||
m_taskScheduler.flushTasks();
|
||||
}
|
||||
|
||||
{
|
||||
BT_PROFILE("parallel_solve_iterations");
|
||||
|
||||
btSpinlock::SpinVariable* spinVar = (btSpinlock::SpinVariable*)btAlignedAlloc(sizeof(btSpinlock::SpinVariable), 128);
|
||||
for (int iter = 0; iter < info.m_numIterations; ++iter)
|
||||
{
|
||||
btSpinlock lock (spinVar);
|
||||
lock.Init();
|
||||
|
||||
// Clear the "processed cells" part of the hash
|
||||
memcpy(m_solverHash->m_currentMask[0], emptyCellMask, sizeof(uint32_t)*SPU_HASH_NUMCELLDWORDS);
|
||||
|
||||
for (int task = 0; task < m_taskScheduler.getMaxOutstandingTasks(); ++task)
|
||||
{
|
||||
SpuSolverTaskDesc* desc = m_taskScheduler.getTask();
|
||||
desc->m_solverCommand = CMD_SOLVER_SOLVE_ITERATE;
|
||||
|
||||
desc->m_solverData.m_solverHash = m_solverHash;
|
||||
desc->m_solverData.m_solverBodyList = solverBodyPool;
|
||||
desc->m_solverData.m_solverBodyOffsetList = solverBodyOffsetList;
|
||||
desc->m_solverData.m_solverInternalConstraintList = solverInternalConstraintPool;
|
||||
desc->m_solverData.m_solverConstraintList = solverConstraintPool;
|
||||
|
||||
desc->m_commandData.m_iterate.m_spinLockVar = spinVar;
|
||||
|
||||
m_taskScheduler.issueTask();
|
||||
}
|
||||
m_taskScheduler.flushTasks();
|
||||
|
||||
|
||||
}
|
||||
btAlignedFree((void*)spinVar);
|
||||
}
|
||||
|
||||
// Write back velocity
|
||||
{
|
||||
int bodiesPerTask = PARALLEL_SOLVER_BODIES_PER_TASK;
|
||||
int bodiesToSchedule = numBodies;
|
||||
int startBody = 0;
|
||||
|
||||
while (bodiesToSchedule > 0)
|
||||
{
|
||||
// Schedule a bunch of hash cells
|
||||
int numBodiesInTask = bodiesToSchedule > bodiesPerTask ? bodiesPerTask : bodiesToSchedule;
|
||||
|
||||
SpuSolverTaskDesc* desc = m_taskScheduler.getTask();
|
||||
|
||||
desc->m_solverCommand = CMD_SOLVER_COPYBACK_BODIES;
|
||||
desc->m_solverData.m_solverHash = m_solverHash;
|
||||
desc->m_solverData.m_solverBodyList = solverBodyPool;
|
||||
|
||||
desc->m_commandData.m_bodyCopyback.m_startBody = startBody;
|
||||
desc->m_commandData.m_bodyCopyback.m_numBodies = numBodiesInTask;
|
||||
desc->m_commandData.m_bodyCopyback.m_rbList = &m_allObjects[0];
|
||||
|
||||
m_taskScheduler.issueTask();
|
||||
bodiesToSchedule -= numBodiesInTask;
|
||||
startBody += numBodiesInTask;
|
||||
}
|
||||
|
||||
m_taskScheduler.flushTasks();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
{
|
||||
BT_PROFILE("warmstart_writeback");
|
||||
|
||||
btSpinlock::SpinVariable* spinVar = (btSpinlock::SpinVariable*)btAlignedAlloc(sizeof(btSpinlock::SpinVariable), 128);
|
||||
for (int iter = 0; iter < info.m_numIterations; ++iter)
|
||||
{
|
||||
btSpinlock lock (spinVar);
|
||||
lock.Init();
|
||||
|
||||
// Clear the "processed cells" part of the hash
|
||||
memcpy(m_solverHash->m_currentMask[0], emptyCellMask, sizeof(uint32_t)*SPU_HASH_NUMCELLDWORDS);
|
||||
|
||||
for (int task = 0; task < m_taskScheduler.getMaxOutstandingTasks(); ++task)
|
||||
{
|
||||
SpuSolverTaskDesc* desc = m_taskScheduler.getTask();
|
||||
desc->m_solverCommand = CMD_SOLVER_MANIFOLD_WARMSTART_WRITEBACK;
|
||||
desc->m_solverData.m_solverHash = m_solverHash;
|
||||
desc->m_solverData.m_solverInternalConstraintList = solverInternalConstraintPool;
|
||||
desc->m_solverData.m_solverConstraintList = solverConstraintPool;
|
||||
desc->m_commandData.m_manifoldSetup.m_manifoldHolders = &m_sortedManifolds[0];
|
||||
desc->m_commandData.m_iterate.m_spinLockVar = spinVar;
|
||||
|
||||
m_taskScheduler.issueTask();
|
||||
}
|
||||
m_taskScheduler.flushTasks();
|
||||
}
|
||||
btAlignedFree((void*)spinVar);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Clean up
|
||||
m_sortedManifolds.resize(0);
|
||||
m_sortedConstraints.resize(0);
|
||||
m_allObjects.resize(0);
|
||||
clearHash(m_solverHash);
|
||||
|
||||
|
||||
m_numberOfContacts = 0;
|
||||
}
|
||||
|
||||
void btParallelSequentialImpulseSolver::reset()
|
||||
{
|
||||
m_sortedManifolds.clear();
|
||||
m_allObjects.clear();
|
||||
m_numberOfContacts = 0;
|
||||
clearHash(m_solverHash);
|
||||
|
||||
solverBodyPool_persist.clear();
|
||||
solverBodyOffsetList_persist.clear();
|
||||
solverConstraintPool_persist.clear();
|
||||
solverInternalConstraintPool_persist.clear();
|
||||
}
|
||||
|
||||
|
||||
SolverTaskScheduler::SolverTaskScheduler(btThreadSupportInterface* threadIf, int maxOutstandingTasks)
|
||||
: m_threadInterface (threadIf), m_maxNumOutstandingTasks (maxOutstandingTasks > SPU_MAX_SPUS ? SPU_MAX_SPUS : maxOutstandingTasks),
|
||||
m_currentTask (0), m_numBusyTasks (0)
|
||||
{
|
||||
m_taskDescriptors.resize(m_maxNumOutstandingTasks);
|
||||
m_taskBusy.resize(m_maxNumOutstandingTasks);
|
||||
|
||||
m_threadInterface->startSPU();
|
||||
}
|
||||
|
||||
|
||||
SolverTaskScheduler::~SolverTaskScheduler()
|
||||
{
|
||||
m_threadInterface->stopSPU();
|
||||
}
|
||||
|
||||
SpuSolverTaskDesc* SolverTaskScheduler::getTask()
|
||||
{
|
||||
int taskIdx = -1;
|
||||
|
||||
if (m_taskBusy[m_currentTask])
|
||||
{
|
||||
//try to find a new one
|
||||
for (int i = 0; i < m_maxNumOutstandingTasks; ++i)
|
||||
{
|
||||
if (!m_taskBusy[i])
|
||||
{
|
||||
taskIdx = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (taskIdx < 0)
|
||||
{
|
||||
// Have to wait
|
||||
unsigned int taskId;
|
||||
unsigned int outputSize;
|
||||
|
||||
for (int i=0;i<m_maxNumOutstandingTasks;i++)
|
||||
{
|
||||
if (m_taskBusy[i])
|
||||
{
|
||||
taskId = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
m_threadInterface->waitForResponse(&taskId, &outputSize);
|
||||
|
||||
m_taskBusy[taskId] = false;
|
||||
m_numBusyTasks--;
|
||||
|
||||
taskIdx = taskId;
|
||||
}
|
||||
|
||||
m_currentTask = taskIdx;
|
||||
}
|
||||
|
||||
|
||||
SpuSolverTaskDesc* result = &m_taskDescriptors[m_currentTask];
|
||||
int so = sizeof(SpuSolverTaskDesc);
|
||||
|
||||
memset(result, 0, so);
|
||||
result->m_taskId = m_currentTask;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void SolverTaskScheduler::issueTask()
|
||||
{
|
||||
m_taskBusy[m_currentTask] = true;
|
||||
m_numBusyTasks++;
|
||||
|
||||
SpuSolverTaskDesc& desc = m_taskDescriptors[m_currentTask];
|
||||
|
||||
m_threadInterface->sendRequest(1, (ppu_address_t)&desc, m_currentTask);
|
||||
}
|
||||
|
||||
void SolverTaskScheduler::flushTasks()
|
||||
{
|
||||
while (m_numBusyTasks > 0)
|
||||
{
|
||||
unsigned int taskId;
|
||||
unsigned int outputSize;
|
||||
for (int i=0;i<m_maxNumOutstandingTasks;i++)
|
||||
{
|
||||
if (m_taskBusy[i])
|
||||
{
|
||||
taskId = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
m_threadInterface->waitForResponse(&taskId, &outputSize);
|
||||
|
||||
m_taskBusy[taskId] = false;
|
||||
m_numBusyTasks--;
|
||||
}
|
||||
}
|
||||
@@ -1,75 +0,0 @@
|
||||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library - Parallel solver
|
||||
Copyright (c) 2007 Starbreeze Studios
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
|
||||
Written by: Marten Svanfeldt
|
||||
*/
|
||||
|
||||
#ifndef SPU_PARALLELSOLVER_H
|
||||
#define SPU_PARALLELSOLVER_H
|
||||
|
||||
#include "BulletDynamics/ConstraintSolver/btConstraintSolver.h"
|
||||
#include "btThreadSupportInterface.h"
|
||||
#include "LinearMath/btAlignedObjectArray.h"
|
||||
|
||||
class SolverTaskScheduler
|
||||
{
|
||||
protected:
|
||||
class btThreadSupportInterface* m_threadInterface;
|
||||
int m_maxNumOutstandingTasks;
|
||||
|
||||
unsigned int m_currentTask;
|
||||
unsigned int m_numBusyTasks;
|
||||
|
||||
btAlignedObjectArray<struct SpuSolverTaskDesc> m_taskDescriptors;
|
||||
btAlignedObjectArray<bool> m_taskBusy;
|
||||
|
||||
public:
|
||||
SolverTaskScheduler (btThreadSupportInterface* threadIf, int maxOutstandingTasks);
|
||||
~SolverTaskScheduler ();
|
||||
|
||||
struct SpuSolverTaskDesc* getTask ();
|
||||
|
||||
void issueTask();
|
||||
void flushTasks();
|
||||
|
||||
int getMaxOutstandingTasks()
|
||||
{
|
||||
return m_maxNumOutstandingTasks;
|
||||
}
|
||||
};
|
||||
|
||||
class btParallelSequentialImpulseSolver : public btConstraintSolver
|
||||
{
|
||||
protected:
|
||||
|
||||
struct SpuSolverHash* m_solverHash;
|
||||
btAlignedObjectArray<struct ManifoldCellHolder> m_sortedManifolds;
|
||||
btAlignedObjectArray<struct ConstraintCellHolder> m_sortedConstraints;
|
||||
btAlignedObjectArray<class btRigidBody*> m_allObjects;
|
||||
|
||||
int m_numberOfContacts;
|
||||
|
||||
SolverTaskScheduler m_taskScheduler;
|
||||
|
||||
public:
|
||||
btParallelSequentialImpulseSolver (btThreadSupportInterface* threadIf, int maxOutstandingTasks);
|
||||
virtual ~btParallelSequentialImpulseSolver();
|
||||
|
||||
virtual void prepareSolve (int numBodies, int numManifolds);
|
||||
virtual btScalar solveGroup(btCollisionObject** bodies,int numBodies,btPersistentManifold** manifold,int numManifolds,btTypedConstraint** constraints,int numConstraints, const btContactSolverInfo& info,class btIDebugDraw* debugDrawer, btStackAlloc* stackAlloc,btDispatcher* dispatcher);
|
||||
virtual void allSolved (const btContactSolverInfo& info,class btIDebugDraw* debugDrawer, btStackAlloc* stackAlloc);
|
||||
virtual void reset ();
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,189 +0,0 @@
|
||||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2003-2007 Erwin Coumans http://bulletphysics.com
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#include "SpuRaycastTaskProcess.h"
|
||||
|
||||
|
||||
SpuRaycastTaskProcess::SpuRaycastTaskProcess(class btThreadSupportInterface* threadInterface, int maxNumOutstandingTasks)
|
||||
:m_threadInterface(threadInterface),
|
||||
m_maxNumOutstandingTasks(maxNumOutstandingTasks)
|
||||
{
|
||||
m_workUnitTaskBuffers = (unsigned char *)0;
|
||||
m_taskBusy.resize(m_maxNumOutstandingTasks);
|
||||
m_spuRaycastTaskDesc.resize(m_maxNumOutstandingTasks);
|
||||
|
||||
for (int i = 0; i < m_maxNumOutstandingTasks; i++)
|
||||
{
|
||||
m_taskBusy[i] = false;
|
||||
}
|
||||
m_numBusyTasks = 0;
|
||||
m_currentTask = 0;
|
||||
m_currentWorkUnitInTask = 0;
|
||||
|
||||
m_threadInterface->startSPU();
|
||||
|
||||
//printf("sizeof vec_float4: %d\n", sizeof(vec_float4));
|
||||
//printf("sizeof SpuGatherAndProcessWorkUnitInput: %d\n", sizeof(SpuGatherAndProcessWorkUnitInput));
|
||||
|
||||
}
|
||||
|
||||
SpuRaycastTaskProcess::~SpuRaycastTaskProcess()
|
||||
{
|
||||
|
||||
if (m_workUnitTaskBuffers != 0)
|
||||
{
|
||||
btAlignedFree(m_workUnitTaskBuffers);
|
||||
m_workUnitTaskBuffers = 0;
|
||||
}
|
||||
|
||||
m_threadInterface->stopSPU();
|
||||
}
|
||||
|
||||
|
||||
|
||||
void SpuRaycastTaskProcess::initialize2(void* spuCollisionObjectsWrappers, int numSpuCollisionObjectWrappers)
|
||||
{
|
||||
m_spuCollisionObjectWrappers = spuCollisionObjectsWrappers;
|
||||
m_numSpuCollisionObjectWrappers = numSpuCollisionObjectWrappers;
|
||||
for (int i = 0; i < m_maxNumOutstandingTasks; i++)
|
||||
{
|
||||
m_taskBusy[i] = false;
|
||||
}
|
||||
m_numBusyTasks = 0;
|
||||
m_currentTask = 0;
|
||||
m_currentWorkUnitInTask = 0;
|
||||
|
||||
#ifdef DEBUG_SpuRaycastTaskProcess
|
||||
m_initialized = true;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void SpuRaycastTaskProcess::issueTask2()
|
||||
{
|
||||
m_taskBusy[m_currentTask] = true;
|
||||
m_numBusyTasks++;
|
||||
|
||||
SpuRaycastTaskDesc& taskDesc = m_spuRaycastTaskDesc[m_currentTask];
|
||||
|
||||
taskDesc.taskId = m_currentTask;
|
||||
m_threadInterface->sendRequest(1, (ppu_address_t) &taskDesc,m_currentTask);
|
||||
//printf("send thread requested for task %d\n", m_currentTask);
|
||||
// if all tasks busy, wait for spu event to clear the task.
|
||||
if (m_numBusyTasks >= m_maxNumOutstandingTasks)
|
||||
{
|
||||
unsigned int taskId;
|
||||
unsigned int outputSize;
|
||||
|
||||
for (int i=0;i<m_maxNumOutstandingTasks;i++)
|
||||
{
|
||||
if (m_taskBusy[i])
|
||||
{
|
||||
taskId = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
m_threadInterface->waitForResponse(&taskId, &outputSize);
|
||||
|
||||
//printf("PPU: after issue, received event: %u %d\n", taskId, outputSize);
|
||||
|
||||
m_taskBusy[taskId] = false;
|
||||
|
||||
m_numBusyTasks--;
|
||||
} else {
|
||||
//printf("Sent request, not enough busy tasks\n");
|
||||
}
|
||||
}
|
||||
|
||||
void SpuRaycastTaskProcess::addWorkToTask(SpuRaycastTaskWorkUnit& workunit)
|
||||
{
|
||||
m_spuRaycastTaskDesc[m_currentTask].workUnits[m_currentWorkUnitInTask] = workunit;
|
||||
m_currentWorkUnitInTask++;
|
||||
if (m_currentWorkUnitInTask == SPU_RAYCAST_WORK_UNITS_PER_TASK)
|
||||
{
|
||||
m_spuRaycastTaskDesc[m_currentTask].numWorkUnits = m_currentWorkUnitInTask;
|
||||
m_spuRaycastTaskDesc[m_currentTask].numSpuCollisionObjectWrappers = m_numSpuCollisionObjectWrappers;
|
||||
m_spuRaycastTaskDesc[m_currentTask].spuCollisionObjectsWrappers = m_spuCollisionObjectWrappers;
|
||||
//printf("Task buffer full, issuing\n");
|
||||
issueTask2 ();
|
||||
//printf("Returned from issueTask2()\n");
|
||||
m_currentWorkUnitInTask = 0;
|
||||
|
||||
// find new task buffer
|
||||
for (int i = 0; i < m_maxNumOutstandingTasks; i++)
|
||||
{
|
||||
if (!m_taskBusy[i])
|
||||
{
|
||||
m_currentTask = i;
|
||||
//init the task data
|
||||
break;
|
||||
}
|
||||
}
|
||||
//printf("next task = %d\n", m_currentTask);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
SpuRaycastTaskProcess::flush2()
|
||||
{
|
||||
#ifdef DEBUG_SPU_TASK_SCHEDULING
|
||||
printf("\nSpuRaycastTaskProcess::flush()\n");
|
||||
#endif //DEBUG_SPU_TASK_SCHEDULING
|
||||
|
||||
// if there's a partially filled task buffer, submit that task
|
||||
//printf("Flushing... %d remaining\n", m_currentWorkUnitInTask);
|
||||
if (m_currentWorkUnitInTask > 0)
|
||||
{
|
||||
m_spuRaycastTaskDesc[m_currentTask].numWorkUnits = m_currentWorkUnitInTask;
|
||||
m_spuRaycastTaskDesc[m_currentTask].numSpuCollisionObjectWrappers = m_numSpuCollisionObjectWrappers;
|
||||
m_spuRaycastTaskDesc[m_currentTask].spuCollisionObjectsWrappers = m_spuCollisionObjectWrappers;
|
||||
issueTask2();
|
||||
m_currentWorkUnitInTask = 0;
|
||||
}
|
||||
|
||||
|
||||
// all tasks are issued, wait for all tasks to be complete
|
||||
while(m_numBusyTasks > 0)
|
||||
{
|
||||
// Consolidating SPU code
|
||||
unsigned int taskId;
|
||||
unsigned int outputSize;
|
||||
|
||||
for (int i=0;i<m_maxNumOutstandingTasks;i++)
|
||||
{
|
||||
if (m_taskBusy[i])
|
||||
{
|
||||
taskId = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//printf("Busy tasks... %d\n", m_numBusyTasks);
|
||||
|
||||
{
|
||||
// SPURS support.
|
||||
m_threadInterface->waitForResponse(&taskId, &outputSize);
|
||||
}
|
||||
|
||||
//printf("PPU: flushing, received event: %u %d\n", taskId, outputSize);
|
||||
|
||||
//postProcess(taskId, outputSize);
|
||||
|
||||
m_taskBusy[taskId] = false;
|
||||
|
||||
m_numBusyTasks--;
|
||||
}
|
||||
}
|
||||
@@ -1,72 +0,0 @@
|
||||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2003-2007 Erwin Coumans http://bulletphysics.com
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#ifndef SPU_RAY_TASK_PROCESS_H
|
||||
#define SPU_RAY_TASK_PROCESS_H
|
||||
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <LinearMath/btScalar.h>
|
||||
#include "BulletCollision/CollisionDispatch/btCollisionObject.h"
|
||||
#include <LinearMath/btAlignedAllocator.h>
|
||||
|
||||
#include "PlatformDefinitions.h"
|
||||
#include "LinearMath/btAlignedObjectArray.h"
|
||||
#include "SpuRaycastTask/SpuRaycastTask.h"
|
||||
|
||||
#include "btThreadSupportInterface.h"
|
||||
|
||||
/// SpuRaycastTaskProcess handles SPU processing of raycast requests
|
||||
class SpuRaycastTaskProcess
|
||||
{
|
||||
unsigned char *m_workUnitTaskBuffers;
|
||||
|
||||
// track task buffers that are being used, and total busy tasks
|
||||
btAlignedObjectArray<bool> m_taskBusy;
|
||||
btAlignedObjectArray<SpuRaycastTaskDesc> m_spuRaycastTaskDesc;
|
||||
|
||||
btThreadSupportInterface* m_threadInterface;
|
||||
|
||||
int m_maxNumOutstandingTasks;
|
||||
|
||||
int m_numBusyTasks;
|
||||
|
||||
// the current task and the current entry to insert a new work unit
|
||||
int m_currentTask;
|
||||
int m_currentWorkUnitInTask;
|
||||
int m_numSpuCollisionObjectWrappers;
|
||||
void* m_spuCollisionObjectWrappers;
|
||||
void issueTask2();
|
||||
//void postProcess(unsigned int taskId, int outputSize);
|
||||
|
||||
public:
|
||||
SpuRaycastTaskProcess(btThreadSupportInterface* threadInterface, int maxNumOutstandingTasks);
|
||||
|
||||
~SpuRaycastTaskProcess();
|
||||
|
||||
/// call initialize in the beginning of the frame, before addCollisionPairToTask
|
||||
void initialize2(void* spuCollisionObjectsWrappers, int numSpuCollisionObjectWrappers);
|
||||
|
||||
/// batch up additional work to a current task for SPU processing. When batch is full, it issues the task.
|
||||
void addWorkToTask(struct SpuRaycastTaskWorkUnit&);
|
||||
|
||||
/// call flush to submit potential outstanding work to SPUs and wait for all involved SPUs to be finished
|
||||
void flush2();
|
||||
};
|
||||
|
||||
|
||||
#endif // SPU_COLLISION_TASK_PROCESS_H
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,183 +0,0 @@
|
||||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library - Parallel solver
|
||||
Copyright (c) 2007 Starbreeze Studios
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
|
||||
Written by: Marten Svanfeldt
|
||||
*/
|
||||
|
||||
#ifndef SPU_PARALLELSOLVERTASK_H
|
||||
#define SPU_PARALLELSOLVERTASK_H
|
||||
|
||||
#include "../PlatformDefinitions.h"
|
||||
#include "LinearMath/btScalar.h"
|
||||
#include "LinearMath/btVector3.h"
|
||||
#include "LinearMath/btMatrix3x3.h"
|
||||
#include "BulletDynamics/ConstraintSolver/btContactSolverInfo.h"
|
||||
#include "../SpuSync.h"
|
||||
#include "BulletDynamics/ConstraintSolver/btTypedConstraint.h"
|
||||
#include "LinearMath/btAlignedAllocator.h"
|
||||
#include "BulletDynamics/ConstraintSolver/btSolverBody.h"
|
||||
#include "BulletDynamics/ConstraintSolver/btSolverConstraint.h"
|
||||
|
||||
ATTRIBUTE_ALIGNED16(struct) ManifoldCellHolder
|
||||
{
|
||||
BT_DECLARE_ALIGNED_ALLOCATOR();
|
||||
|
||||
uint32_t m_hashCellIndex;
|
||||
class btPersistentManifold* m_manifold;
|
||||
};
|
||||
|
||||
ATTRIBUTE_ALIGNED16(struct) ConstraintCellHolder
|
||||
{
|
||||
BT_DECLARE_ALIGNED_ALLOCATOR();
|
||||
|
||||
uint32_t m_hashCellIndex;
|
||||
uint32_t m_constraintType;
|
||||
class btTypedConstraint* m_constraint;
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
SPU_HASH_NUMCELLS = 128,
|
||||
SPU_HASH_WORDWIDTH = sizeof(uint32_t)*8,
|
||||
SPU_HASH_NUMCELLDWORDS = ((SPU_HASH_NUMCELLS + SPU_HASH_WORDWIDTH - 1) / SPU_HASH_WORDWIDTH),
|
||||
SPU_HASH_NUMUNUSEDBITS = (SPU_HASH_NUMCELLDWORDS * SPU_HASH_WORDWIDTH) - SPU_HASH_NUMCELLS,
|
||||
SPU_HASH_PHYSSIZE = 4, //TODO: MAKE CONFIGURABLE
|
||||
|
||||
SPU_MAX_BODIES_PER_CELL = 1024,
|
||||
|
||||
SPU_MAX_SPUS = 6
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
CMD_SOLVER_SETUP_BODIES = 1,
|
||||
CMD_SOLVER_MANIFOLD_SETUP,
|
||||
CMD_SOLVER_CONSTRAINT_SETUP,
|
||||
CMD_SOLVER_SOLVE_ITERATE,
|
||||
CMD_SOLVER_COPYBACK_BODIES,
|
||||
CMD_SOLVER_MANIFOLD_WARMSTART_WRITEBACK
|
||||
};
|
||||
|
||||
struct SpuSolverHashCell
|
||||
{
|
||||
uint16_t m_numLocalBodies;
|
||||
uint16_t m_solverBodyOffsetListOffset;
|
||||
|
||||
uint16_t m_numManifolds;
|
||||
uint16_t m_manifoldListOffset;
|
||||
|
||||
uint16_t m_numContacts;
|
||||
uint16_t m_internalConstraintListOffset;
|
||||
|
||||
uint16_t m_numConstraints;
|
||||
uint16_t m_constraintListOffset;
|
||||
};
|
||||
|
||||
// Shared data structures
|
||||
struct SpuSolverHash
|
||||
{
|
||||
// Dependency matrix
|
||||
ATTRIBUTE_ALIGNED16(uint32_t m_dependencyMatrix[SPU_HASH_NUMCELLS][SPU_HASH_NUMCELLDWORDS]);
|
||||
ATTRIBUTE_ALIGNED16(uint32_t m_currentMask[SPU_MAX_SPUS+1][SPU_HASH_NUMCELLDWORDS]);
|
||||
|
||||
// The hash itself
|
||||
ATTRIBUTE_ALIGNED16(SpuSolverHashCell m_Hash[SPU_HASH_NUMCELLS]);
|
||||
|
||||
// Hash meta-data
|
||||
};
|
||||
|
||||
inline unsigned int spuHash(unsigned int k) { return k*2654435769u; }
|
||||
inline unsigned int spuGetHashCellIndex(int x, int y, int z)
|
||||
{
|
||||
//int n = 0x8da6b343 * x + 0xd8163841 * y + 0xcb1ab31f * z;
|
||||
|
||||
int n = x ^ spuHash(y ^ spuHash (z));
|
||||
|
||||
return ((unsigned int)n) & (SPU_HASH_NUMCELLS-1);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
ATTRIBUTE_ALIGNED16(struct) SpuSolverDataDesc
|
||||
{
|
||||
BT_DECLARE_ALIGNED_ALLOCATOR();
|
||||
|
||||
SpuSolverHash* m_solverHash;
|
||||
btSolverBody* m_solverBodyList;
|
||||
btSolverConstraint* m_solverInternalConstraintList;
|
||||
btSolverConstraint* m_solverConstraintList;
|
||||
uint32_t* m_solverBodyOffsetList;
|
||||
};
|
||||
|
||||
|
||||
ATTRIBUTE_ALIGNED16(struct) SpuSolverTaskDesc
|
||||
{
|
||||
BT_DECLARE_ALIGNED_ALLOCATOR();
|
||||
|
||||
uint32_t m_solverCommand;
|
||||
uint32_t m_taskId;
|
||||
SpuSolverDataDesc m_solverData;
|
||||
|
||||
// command specific data
|
||||
union
|
||||
{
|
||||
// Body setup
|
||||
struct
|
||||
{
|
||||
uint32_t m_startBody;
|
||||
uint32_t m_numBodies;
|
||||
|
||||
class btRigidBody** m_rbList;
|
||||
} m_bodySetup, m_bodyCopyback;
|
||||
|
||||
struct
|
||||
{
|
||||
uint32_t m_startCell;
|
||||
uint32_t m_numCells;
|
||||
|
||||
uint32_t m_numBodies;
|
||||
uint32_t m_numManifolds;
|
||||
|
||||
ManifoldCellHolder* m_manifoldHolders;
|
||||
ConstraintCellHolder* m_constraintHolders;
|
||||
btContactSolverInfoData m_solverInfo;
|
||||
} m_manifoldSetup;
|
||||
|
||||
struct
|
||||
{
|
||||
btSpinlock::SpinVariable* m_spinLockVar;
|
||||
} m_iterate;
|
||||
} m_commandData;
|
||||
};
|
||||
|
||||
void processSolverTask(void* userPtr, void* lsMemory);
|
||||
void* createSolverLocalStoreMemory();
|
||||
|
||||
// Helper
|
||||
inline bool constraintTypeSupported(btTypedConstraintType type)
|
||||
{
|
||||
return type == POINT2POINT_CONSTRAINT_TYPE ||
|
||||
type == HINGE_CONSTRAINT_TYPE ||
|
||||
type == CONETWIST_CONSTRAINT_TYPE ||
|
||||
type == D6_CONSTRAINT_TYPE;
|
||||
}
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user