SpuSampleTask.cpp

Go to the documentation of this file.
00001 /*
00002 Bullet Continuous Collision Detection and Physics Library, Copyright (c) 2007 Erwin Coumans
00003 
00004 This software is provided 'as-is', without any express or implied warranty.
00005 In no event will the authors be held liable for any damages arising from the use of this software.
00006 Permission is granted to anyone to use this software for any purpose, 
00007 including commercial applications, and to alter it and redistribute it freely, 
00008 subject to the following restrictions:
00009 
00010 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.
00011 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
00012 3. This notice may not be removed or altered from any source distribution.
00013 
00014 */
00015 
00016 
00017 #include "SpuSampleTask.h"
00018 #include "BulletDynamics/Dynamics/btRigidBody.h"
00019 #include "../PlatformDefinitions.h"
00020 #include "../SpuFakeDma.h"
00021 #include "LinearMath/btMinMax.h"
00022 
00023 #ifdef __SPU__
00024 #include <spu_printf.h>
00025 #else
00026 #include <stdio.h>
00027 #define spu_printf printf
00028 #endif
00029 
00030 #define MAX_NUM_BODIES 8192
00031 
00032 struct SampleTask_LocalStoreMemory
00033 {
00034         ATTRIBUTE_ALIGNED16(char gLocalRigidBody [sizeof(btRigidBody)+16]);
00035         ATTRIBUTE_ALIGNED16(void* gPointerArray[MAX_NUM_BODIES]);
00036 
00037 };
00038 
00039 
00040 
00041 
00042 //-- MAIN METHOD
00043 void processSampleTask(void* userPtr, void* lsMemory)
00044 {
00045         //      BT_PROFILE("processSampleTask");
00046 
00047         SampleTask_LocalStoreMemory* localMemory = (SampleTask_LocalStoreMemory*)lsMemory;
00048 
00049         SpuSampleTaskDesc* taskDescPtr = (SpuSampleTaskDesc*)userPtr;
00050         SpuSampleTaskDesc& taskDesc = *taskDescPtr;
00051 
00052         switch (taskDesc.m_sampleCommand)
00053         {
00054         case CMD_SAMPLE_INTEGRATE_BODIES:
00055                 {
00056                         btTransform predictedTrans;
00057                         btCollisionObject** eaPtr = (btCollisionObject**)taskDesc.m_mainMemoryPtr;
00058 
00059                         int batchSize = taskDesc.m_sampleValue;
00060                         if (batchSize>MAX_NUM_BODIES)
00061                         {
00062                                 spu_printf("SPU Error: exceed number of bodies, see MAX_NUM_BODIES in SpuSampleTask.cpp\n");
00063                                 break;
00064                         }
00065                         int dmaArraySize = batchSize*sizeof(void*);
00066 
00067                         uint64_t ppuArrayAddress = reinterpret_cast<uint64_t>(eaPtr);
00068 
00069                         //                      spu_printf("array location is at %llx, batchSize = %d, DMA size = %d\n",ppuArrayAddress,batchSize,dmaArraySize);
00070 
00071                         if (dmaArraySize>=16)
00072                         {
00073                                 cellDmaLargeGet((void*)&localMemory->gPointerArray[0], ppuArrayAddress  , dmaArraySize, DMA_TAG(1), 0, 0);      
00074                                 cellDmaWaitTagStatusAll(DMA_MASK(1));
00075                         } else
00076                         {
00077                                 stallingUnalignedDmaSmallGet((void*)&localMemory->gPointerArray[0], ppuArrayAddress  , dmaArraySize);
00078                         }
00079 
00080 
00081                         for ( int i=0;i<batchSize;i++)
00082                         {
00084 
00085                                 void* localPtr = &localMemory->gLocalRigidBody[0];
00086                                 void* shortAdd = localMemory->gPointerArray[i];
00087                                 uint64_t ppuRigidBodyAddress = reinterpret_cast<uint64_t>(shortAdd);
00088 
00089                                 //      spu_printf("cellDmaGet at CMD_SAMPLE_INTEGRATE_BODIES from %llx to %llx\n",ppuRigidBodyAddress,localPtr);
00090 
00091                                 int dmaBodySize = sizeof(btRigidBody);
00092 
00093                                 cellDmaGet((void*)localPtr, ppuRigidBodyAddress  , dmaBodySize, DMA_TAG(1), 0, 0);      
00094                                 cellDmaWaitTagStatusAll(DMA_MASK(1));
00095 
00096 
00097                                 float timeStep = 1.f/60.f;
00098 
00099                                 btRigidBody* body = (btRigidBody*) localPtr;//btRigidBody::upcast(colObj);
00100                                 if (body)
00101                                 {
00102                                         if (body->isActive() && (!body->isStaticOrKinematicObject()))
00103                                         {
00104                                                 body->predictIntegratedTransform(timeStep, predictedTrans);
00105                                                 body->proceedToTransform( predictedTrans);
00106                                                 void* ptr = (void*)localPtr;
00107                                                 //      spu_printf("cellDmaLargePut from %llx to LS %llx\n",ptr,ppuRigidBodyAddress);
00108 
00109                                                 cellDmaLargePut(ptr, ppuRigidBodyAddress  , dmaBodySize, DMA_TAG(1), 0, 0);
00110                                                 cellDmaWaitTagStatusAll(DMA_MASK(1));
00111 
00112                                         }
00113                                 }
00114 
00115                         }
00116                         break;
00117                 }
00118 
00119 
00120         case CMD_SAMPLE_PREDICT_MOTION_BODIES:
00121                 {
00122                         btTransform predictedTrans;
00123                         btCollisionObject** eaPtr = (btCollisionObject**)taskDesc.m_mainMemoryPtr;
00124 
00125                         int batchSize = taskDesc.m_sampleValue;
00126                         int dmaArraySize = batchSize*sizeof(void*);
00127 
00128                         if (batchSize>MAX_NUM_BODIES)
00129                         {
00130                                 spu_printf("SPU Error: exceed number of bodies, see MAX_NUM_BODIES in SpuSampleTask.cpp\n");
00131                                 break;
00132                         }
00133 
00134                         uint64_t ppuArrayAddress = reinterpret_cast<uint64_t>(eaPtr);
00135 
00136                         //                      spu_printf("array location is at %llx, batchSize = %d, DMA size = %d\n",ppuArrayAddress,batchSize,dmaArraySize);
00137 
00138                         if (dmaArraySize>=16)
00139                         {
00140                                 cellDmaLargeGet((void*)&localMemory->gPointerArray[0], ppuArrayAddress  , dmaArraySize, DMA_TAG(1), 0, 0);      
00141                                 cellDmaWaitTagStatusAll(DMA_MASK(1));
00142                         } else
00143                         {
00144                                 stallingUnalignedDmaSmallGet((void*)&localMemory->gPointerArray[0], ppuArrayAddress  , dmaArraySize);
00145                         }
00146 
00147 
00148                         for ( int i=0;i<batchSize;i++)
00149                         {
00151 
00152                                 void* localPtr = &localMemory->gLocalRigidBody[0];
00153                                 void* shortAdd = localMemory->gPointerArray[i];
00154                                 uint64_t ppuRigidBodyAddress = reinterpret_cast<uint64_t>(shortAdd);
00155 
00156                                 //      spu_printf("cellDmaGet at CMD_SAMPLE_INTEGRATE_BODIES from %llx to %llx\n",ppuRigidBodyAddress,localPtr);
00157 
00158                                 int dmaBodySize = sizeof(btRigidBody);
00159 
00160                                 cellDmaGet((void*)localPtr, ppuRigidBodyAddress  , dmaBodySize, DMA_TAG(1), 0, 0);      
00161                                 cellDmaWaitTagStatusAll(DMA_MASK(1));
00162 
00163 
00164                                 float timeStep = 1.f/60.f;
00165 
00166                                 btRigidBody* body = (btRigidBody*) localPtr;//btRigidBody::upcast(colObj);
00167                                 if (body)
00168                                 {
00169                                         if (!body->isStaticOrKinematicObject())
00170                                         {
00171                                                 if (body->isActive())
00172                                                 {
00173                                                         body->integrateVelocities( timeStep);
00174                                                         //damping
00175                                                         body->applyDamping(timeStep);
00176 
00177                                                         body->predictIntegratedTransform(timeStep,body->getInterpolationWorldTransform());
00178 
00179                                                         void* ptr = (void*)localPtr;
00180                                                         cellDmaLargePut(ptr, ppuRigidBodyAddress  , dmaBodySize, DMA_TAG(1), 0, 0);
00181                                                         cellDmaWaitTagStatusAll(DMA_MASK(1));
00182                                                 }
00183                                         }
00184                                 }
00185 
00186                         }
00187                         break;
00188                 }
00189         
00190 
00191 
00192         default:
00193                 {
00194 
00195                 }
00196         };
00197 }
00198 
00199 
00200 #if defined(__CELLOS_LV2__) || defined (LIBSPE2)
00201 
00202 ATTRIBUTE_ALIGNED16(SampleTask_LocalStoreMemory gLocalStoreMemory);
00203 
00204 void* createSampleLocalStoreMemory()
00205 {
00206         return &gLocalStoreMemory;
00207 }
00208 #else
00209 void* createSampleLocalStoreMemory()
00210 {
00211         return new SampleTask_LocalStoreMemory;
00212 };
00213 
00214 #endif