Changed BulletMultiThreaded Thread Support to be passed in, rather then global 'Win32ThreadSupport'/'Libspe2ThreadSupport' etc.

This allows developer to hookup Bullet to a custom task scheduler, by deriving from btThreadSupportInterface.
This commit is contained in:
ejcoumans
2007-07-09 03:21:33 +00:00
parent 2508cef2cf
commit 121fd7808e
12 changed files with 201 additions and 66 deletions

View File

@@ -19,6 +19,7 @@ subject to the following restrictions:
//#define CHECK_MEMORY_LEAKS 1
//#define USE_PARALLEL_DISPATCHER 1
//#define USE_SIMPLE_DYNAMICS_WORLD 1
int gNumObjects = 120;
@@ -35,6 +36,8 @@ btScalar gCollisionMargin = btScalar(0.05);
#ifdef USE_PARALLEL_DISPATCHER
#include "../../Extras/BulletMultiThreaded/SpuGatheringCollisionDispatcher.h"
#include "../../Extras/BulletMultiThreaded/Win32ThreadSupport.h"
#include "../../Extras/BulletMultiThreaded/SpuNarrowPhaseCollisionTask/SpuGatheringCollisionTask.h"
#endif//USE_PARALLEL_DISPATCHER
@@ -120,11 +123,31 @@ void BasicDemo::displayCallback(void) {
void BasicDemo::initPhysics()
{
#ifdef USE_PARALLEL_DISPATCHER
m_dispatcher = new SpuGatheringCollisionDispatcher();
#ifdef USE_WIN32_THREADING
int maxNumOutstandingTasks = 4;//number of maximum outstanding tasks
Win32ThreadSupport* threadSupport = new Win32ThreadSupport(Win32ThreadSupport::Win32ThreadConstructionInfo(
"collision",
processCollisionTask,
createCollisionLocalStoreMemory,
maxNumOutstandingTasks));
#else
///todo other platform threading
///Playstation 3 SPU (SPURS) version is available through PS3 Devnet
///Libspe2 SPU support will be available soon
///pthreads version
///you can hook it up to your custom task scheduler by deriving from btThreadSupportInterface
#endif
m_dispatcher = new SpuGatheringCollisionDispatcher(threadSupport,maxNumOutstandingTasks);
#else
m_dispatcher = new btCollisionDispatcher(true);
#endif //USE_PARALLEL_DISPATCHER

View File

@@ -23,6 +23,8 @@ subject to the following restrictions:
//#define USE_PARALLEL_DISPATCHER 1
#ifdef USE_PARALLEL_DISPATCHER
#include "../../Extras/BulletMultiThreaded/SpuGatheringCollisionDispatcher.h"
#include "../../Extras/BulletMultiThreaded/Win32ThreadSupport.h"
#include "../../Extras/BulletMultiThreaded/SpuNarrowPhaseCollisionTask/SpuGatheringCollisionTask.h"
#endif//USE_PARALLEL_DISPATCHER
@@ -193,9 +195,27 @@ void ConcaveDemo::initPhysics()
// btCollisionShape* groundShape = new btBoxShape(btVector3(50,3,50));
#ifdef USE_PARALLEL_DISPATCHER
btCollisionDispatcher* dispatcher = new SpuGatheringCollisionDispatcher();
#ifdef USE_WIN32_THREADING
int maxNumOutstandingTasks = 4;//number of maximum outstanding tasks
Win32ThreadSupport* threadSupport = new Win32ThreadSupport(Win32ThreadSupport::Win32ThreadConstructionInfo(
"collision",
processCollisionTask,
createCollisionLocalStoreMemory,
maxNumOutstandingTasks));
#else
///todo other platform threading
///Playstation 3 SPU (SPURS) version is available through PS3 Devnet
///Libspe2 SPU support will be available soon
///pthreads version
///you can hook it up to your custom task scheduler by deriving from btThreadSupportInterface
#endif
btCollisionDispatcher* dispatcher = new SpuGatheringCollisionDispatcher(threadSupport,maxNumOutstandingTasks);
#else
btCollisionDispatcher* dispatcher = new btCollisionDispatcher();
#endif//USE_PARALLEL_DISPATCHER

View File

@@ -22,12 +22,17 @@ subject to the following restrictions:
#include "LinearMath/btIDebugDraw.h"
#include "LinearMath/btGeometryUtil.h"
//#define USE_PARALLEL_DISPATCHER 1
#ifdef USE_PARALLEL_DISPATCHER
#include "../../Extras/BulletMultiThreaded/SpuGatheringCollisionDispatcher.h"
#include "../../Extras/BulletMultiThreaded/Win32ThreadSupport.h"
#include "../../Extras/BulletMultiThreaded/SpuNarrowPhaseCollisionTask/SpuGatheringCollisionTask.h"
#endif//USE_PARALLEL_DISPATCHER
#include "GLDebugDrawer.h"
#include "BMF_Api.h"
@@ -91,7 +96,23 @@ void ConvexDecompositionDemo::initPhysics(const char* filename)
}
#ifdef USE_PARALLEL_DISPATCHER
btCollisionDispatcher* dispatcher = new SpuGatheringCollisionDispatcher();
#ifdef USE_WIN32_THREADING
int maxNumOutstandingTasks = 4;//number of maximum outstanding tasks
Win32ThreadSupport* threadSupport = new Win32ThreadSupport(Win32ThreadSupport::Win32ThreadConstructionInfo(
"collision",
processCollisionTask,
createCollisionLocalStoreMemory,
maxNumOutstandingTasks));
#else
///todo other platform threading
///Playstation 3 SPU (SPURS) version is available through PS3 Devnet
///Libspe2 SPU support will be available soon
///pthreads version
///you can hook it up to your custom task scheduler by deriving from btThreadSupportInterface
#endif
btCollisionDispatcher* dispatcher = new SpuGatheringCollisionDispatcher(threadSupport,maxNumOutstandingTasks);
#else
btCollisionDispatcher* dispatcher = new btCollisionDispatcher();
#endif//USE_PARALLEL_DISPATCHER

View File

@@ -13,12 +13,10 @@ subject to the following restrictions:
3. This notice may not be removed or altered from any source distribution.
*/
//#define __CELLOS_LV2__ 1
//#define DEBUG_SPU_TASK_SCHEDULING 1
#include "SpuLibspe2Support.h"
#include "Win32ThreadSupport.h"
#include "btThreadSupportInterface.h"
//#include "SPUAssert.h"
#include <string.h>
@@ -36,30 +34,21 @@ subject to the following restrictions:
#include <stdio.h>
#ifdef USE_WIN32_THREADING
Win32ThreadSupport gMidphaseSPU(Win32ThreadSupport::Win32ThreadConstructionInfo("collision",
processCollisionTask,
createCollisionLocalStoreMemory,
MIDPHASE_NUM_WORKUNIT_TASKS));
#elif defined(USE_LIBSPE2)
SpuLibspe2Support gMidphaseSPU(SPU_ELF_COLLISION_DETECTION,MIDPHASE_NUM_WORKUNIT_TASKS);
#elif defined (__CELLOS_LV2__)
#include "CellSPURSSupport.ppu.h"
CellSPURSSupport gMidphaseSPU(SPU_ELF_MID_PHASE);
#endif
SpuGatherAndProcessPairsTaskDesc g_spuGatherTaskDesc[MIDPHASE_NUM_WORKUNIT_TASKS];
SpuCollisionTaskProcess::SpuCollisionTaskProcess()
SpuCollisionTaskProcess::SpuCollisionTaskProcess(class btThreadSupportInterface* threadInterface, unsigned int maxNumOutstandingTasks)
:m_threadInterface(threadInterface),
m_maxNumOutstandingTasks(maxNumOutstandingTasks)
{
m_workUnitTaskBuffers = (unsigned char *)0;
m_taskBusy.resize(m_maxNumOutstandingTasks);
m_spuGatherTaskDesc.resize(m_maxNumOutstandingTasks);
for (int i = 0; i < MIDPHASE_NUM_WORKUNIT_TASKS; i++)
for (int i = 0; i < m_maxNumOutstandingTasks; i++)
{
m_taskBusy[i] = false;
}
@@ -72,11 +61,7 @@ SpuCollisionTaskProcess::SpuCollisionTaskProcess()
m_initialized = false;
#endif
#ifdef __CELLOS_LV2__
// adding SPURS support.
gMidphaseSPU.startSPU();
#endif
m_threadInterface->startSPU();
//printf("sizeof vec_float4: %d\n", sizeof(vec_float4));
printf("sizeof SpuGatherAndProcessWorkUnitInput: %d\n", sizeof(SpuGatherAndProcessWorkUnitInput));
@@ -91,12 +76,10 @@ SpuCollisionTaskProcess::~SpuCollisionTaskProcess()
m_workUnitTaskBuffers = 0;
}
#ifdef __CELLOS_LV2__
// Consolidating SPU code
gMidphaseSPU.stopSPU();
m_threadInterface->stopSPU();
#endif
}
@@ -109,10 +92,10 @@ SpuCollisionTaskProcess::initialize2()
#endif //DEBUG_SPU_TASK_SCHEDULING
if (!m_workUnitTaskBuffers)
{
m_workUnitTaskBuffers = (unsigned char *)memalign(128, MIDPHASE_WORKUNIT_TASK_SIZE*MIDPHASE_NUM_WORKUNIT_TASKS);
m_workUnitTaskBuffers = (unsigned char *)memalign(128, MIDPHASE_WORKUNIT_TASK_SIZE*m_maxNumOutstandingTasks);
}
for (int i = 0; i < MIDPHASE_NUM_WORKUNIT_TASKS; i++)
for (int i = 0; i < m_maxNumOutstandingTasks; i++)
{
m_taskBusy[i] = false;
}
@@ -141,7 +124,7 @@ void SpuCollisionTaskProcess::issueTask2()
m_numBusyTasks++;
SpuGatherAndProcessPairsTaskDesc& taskDesc = g_spuGatherTaskDesc[m_currentTask];
SpuGatherAndProcessPairsTaskDesc& taskDesc = m_spuGatherTaskDesc[m_currentTask];
{
// send task description in event message
// no error checking here...
@@ -156,17 +139,17 @@ void SpuCollisionTaskProcess::issueTask2()
gMidphaseSPU.sendRequest(CMD_GATHER_AND_PROCESS_PAIRLIST, (uint32_t) &taskDesc,m_currentTask);
m_threadInterface->sendRequest(CMD_GATHER_AND_PROCESS_PAIRLIST, (uint32_t) &taskDesc,m_currentTask);
// if all tasks busy, wait for spu event to clear the task.
if (m_numBusyTasks >= MIDPHASE_NUM_WORKUNIT_TASKS)
if (m_numBusyTasks >= m_maxNumOutstandingTasks)
{
unsigned int taskId;
unsigned int outputSize;
gMidphaseSPU.waitForResponse(&taskId, &outputSize);
m_threadInterface->waitForResponse(&taskId, &outputSize);
//printf("PPU: after issue, received event: %u %d\n", taskId, outputSize);
@@ -204,7 +187,7 @@ void SpuCollisionTaskProcess::addWorkToTask(void* pairArrayPtr,int startIndex,in
issueTask2();
// find new task buffer
for (unsigned int i = 0; i < MIDPHASE_NUM_WORKUNIT_TASKS; i++)
for (unsigned int i = 0; i < m_maxNumOutstandingTasks; i++)
{
if (!m_taskBusy[i])
{
@@ -247,7 +230,7 @@ void SpuCollisionTaskProcess::addWorkToTask(void* pairArrayPtr,int startIndex,in
issueTask2();
// find new task buffer
for (unsigned int i = 0; i < MIDPHASE_NUM_WORKUNIT_TASKS; i++)
for (unsigned int i = 0; i < m_maxNumOutstandingTasks; i++)
{
if (!m_taskBusy[i])
{
@@ -289,7 +272,7 @@ SpuCollisionTaskProcess::flush2()
{
// SPURS support.
gMidphaseSPU.waitForResponse(&taskId, &outputSize);
m_threadInterface->waitForResponse(&taskId, &outputSize);
}
//printf("PPU: flushing, received event: %u %d\n", taskId, outputSize);

View File

@@ -21,13 +21,10 @@ subject to the following restrictions:
#include <LinearMath/btScalar.h>
#include "PlatformDefinitions.h"
#include "LinearMath/btAlignedObjectArray.h"
#define DEBUG_SpuCollisionTaskProcess 1
//#define MIDPHASE_NUM_WORKUNIT_TASKS 4 //attempt for multi-core
#define MIDPHASE_NUM_WORKUNIT_TASKS 12 //attempt for multi-core
//#define MIDPHASE_NUM_WORKUNIT_TASKS 6 //for SPUs
#define CMD_GATHER_AND_PROCESS_PAIRLIST 1
@@ -82,7 +79,13 @@ class SpuCollisionTaskProcess
// track task buffers that are being used, and total busy tasks
bool m_taskBusy[MIDPHASE_NUM_WORKUNIT_TASKS];
btAlignedObjectArray<bool> m_taskBusy;
btAlignedObjectArray<SpuGatherAndProcessPairsTaskDesc> m_spuGatherTaskDesc;
class btThreadSupportInterface* m_threadInterface;
unsigned int m_maxNumOutstandingTasks;
unsigned int m_numBusyTasks;
// the current task and the current entry to insert a new work unit
@@ -97,7 +100,7 @@ class SpuCollisionTaskProcess
//void postProcess(unsigned int taskId, int outputSize);
public:
SpuCollisionTaskProcess();
SpuCollisionTaskProcess(btThreadSupportInterface* threadInterface, unsigned int maxNumOutstandingTasks);
~SpuCollisionTaskProcess();

View File

@@ -26,8 +26,10 @@ subject to the following restrictions:
SpuGatheringCollisionDispatcher::SpuGatheringCollisionDispatcher()
:m_spuCollisionTaskProcess(0)
SpuGatheringCollisionDispatcher::SpuGatheringCollisionDispatcher(class btThreadSupportInterface* threadInterface, unsigned int maxNumOutstandingTasks)
:m_spuCollisionTaskProcess(0),
m_threadInterface(threadInterface),
m_maxNumOutstandingTasks(maxNumOutstandingTasks)
{
}
@@ -144,7 +146,7 @@ void SpuGatheringCollisionDispatcher::dispatchAllCollisionPairs(btOverlappingPai
if (dispatchInfo.m_enableSPU)
{
if (!m_spuCollisionTaskProcess)
m_spuCollisionTaskProcess = new SpuCollisionTaskProcess();
m_spuCollisionTaskProcess = new SpuCollisionTaskProcess(m_threadInterface,m_maxNumOutstandingTasks);
m_spuCollisionTaskProcess->initialize2();

View File

@@ -34,6 +34,12 @@ class SpuGatheringCollisionDispatcher : public btCollisionDispatcher
SpuCollisionTaskProcess* m_spuCollisionTaskProcess;
protected:
class btThreadSupportInterface* m_threadInterface;
unsigned int m_maxNumOutstandingTasks;
public:
@@ -43,8 +49,8 @@ public:
return m_spuCollisionTaskProcess;
}
SpuGatheringCollisionDispatcher ();
SpuGatheringCollisionDispatcher (class btThreadSupportInterface* threadInterface, unsigned int maxNumOutstandingTasks);
virtual ~SpuGatheringCollisionDispatcher();
bool supportsDispatchPairOnSpu(int proxyType0,int proxyType1);

View File

@@ -14,6 +14,7 @@ subject to the following restrictions:
*/
//#define __CELLOS_LV2__ 1
#ifdef USE_SAMPLE_PROCESS
@@ -56,6 +57,8 @@ CellSPURSSupport gSampleSPU(SPU_ELF_SAMPLE);
#endif
extern "C" {
extern char SPU_SAMPLE_ELF_SYMBOL[];
};
@@ -64,7 +67,7 @@ extern "C" {
SpuSampleTaskDesc g_spuSampleTaskDesc[SAMPLE_NUM_WORKUNIT_TASKS];
//SpuSampleTaskDesc g_spuSampleTaskDesc[SAMPLE_NUM_WORKUNIT_TASKS];
@@ -80,6 +83,8 @@ SpuSampleTaskProcess::SpuSampleTaskProcess()
m_initialized = false;
m_threadInterface->startSPU();
#ifdef WIN32
Win32ThreadSupport::Win32ThreadConstructionInfo threadConstructionInfo(
"sample",SampleThreadFunc,SamplelsMemoryFunc);
@@ -209,3 +214,4 @@ void SpuSampleTaskProcess::flush()
}
#endif //USE_SAMPLE_PROCESS

View File

@@ -26,7 +26,7 @@ subject to the following restrictions:
///Setup and initialize SPU/CELL/Libspe2
Win32ThreadSupport::Win32ThreadSupport(Win32ThreadConstructionInfo& threadConstructionInfo)
{
startSPU(threadConstructionInfo);
startThreads(threadConstructionInfo);
}
///cleanup/shutdown Libspe2
@@ -122,6 +122,7 @@ void Win32ThreadSupport::sendRequest(uint32_t uiCommand, uint32_t uiArgument0, u
}
///check for messages from SPUs
void Win32ThreadSupport::waitForResponse(unsigned int *puiArgument0, unsigned int *puiArgument1)
{
@@ -170,8 +171,8 @@ void Win32ThreadSupport::waitForResponse(unsigned int *puiArgument0, unsigned in
}
///start the spus group (can be called at the beginning of each frame, to make sure that the right SPU program is loaded)
void Win32ThreadSupport::startSPU(Win32ThreadConstructionInfo& threadConstructionInfo)
void Win32ThreadSupport::startThreads(Win32ThreadConstructionInfo& threadConstructionInfo)
{
m_activeSpuStatus.resize(threadConstructionInfo.m_numThreads);
@@ -214,6 +215,11 @@ void Win32ThreadSupport::startSPU(Win32ThreadConstructionInfo& threadConstructio
}
void Win32ThreadSupport::startSPU()
{
}
///tell the task scheduler we are done with the SPU tasks
void Win32ThreadSupport::stopSPU()
{

View File

@@ -23,10 +23,7 @@ subject to the following restrictions:
#include "LinearMath/btAlignedObjectArray.h"
#include <LinearMath/btScalar.h> //for uint32_t etc.
#include "btThreadSupportInterface.h"
typedef void (*Win32ThreadFunc)(void* userPtr,void* lsMemory);
@@ -58,10 +55,12 @@ struct btSpuStatus
///Win32ThreadSupport helps to initialize/shutdown libspe2, start/stop SPU tasks and communication
class Win32ThreadSupport {
class Win32ThreadSupport : public btThreadSupportInterface
{
btAlignedObjectArray<btSpuStatus> m_activeSpuStatus;
public:
///Setup and initialize SPU/CELL/Libspe2
@@ -95,19 +94,22 @@ public:
Win32ThreadSupport(Win32ThreadConstructionInfo& threadConstructionInfo);
///cleanup/shutdown Libspe2
~Win32ThreadSupport();
virtual ~Win32ThreadSupport();
void startThreads(Win32ThreadConstructionInfo& threadInfo);
///send messages to SPUs
void sendRequest(uint32_t uiCommand, uint32_t uiArgument0, uint32_t uiArgument1);
virtual void sendRequest(uint32_t uiCommand, uint32_t uiArgument0, uint32_t uiArgument1);
///check for messages from SPUs
void waitForResponse(unsigned int *puiArgument0, unsigned int *puiArgument1);
virtual void waitForResponse(unsigned int *puiArgument0, unsigned int *puiArgument1);
///start the spus (can be called at the beginning of each frame, to make sure that the right SPU program is loaded)
void startSPU(Win32ThreadConstructionInfo& threadConstructionInfo);
virtual void startSPU();
///tell the task scheduler we are done with the SPU tasks
void stopSPU();
virtual void stopSPU();
};

View File

@@ -0,0 +1,21 @@
/*
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 "btThreadSupportInterface.h"
btThreadSupportInterface::~btThreadSupportInterface()
{
}

View File

@@ -0,0 +1,42 @@
/*
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 THREAD_SUPPORT_INTERFACE_H
#define THREAD_SUPPORT_INTERFACE_H
//#include <LinearMath/btScalar.h> //for uint32_t etc.
#include "PlatformDefinitions.h"
class btThreadSupportInterface
{
public:
virtual ~btThreadSupportInterface();
///send messages to SPUs
virtual void sendRequest(uint32_t uiCommand, uint32_t uiArgument0, uint32_t uiArgument1) =0;
///check for messages from SPUs
virtual void waitForResponse(unsigned int *puiArgument0, unsigned int *puiArgument1) =0;
///start the spus (can be called at the beginning of each frame, to make sure that the right SPU program is loaded)
virtual void startSPU() =0;
///tell the task scheduler we are done with the SPU tasks
virtual void stopSPU()=0;
};
#endif //THREAD_SUPPORT_INTERFACE_H