Imported Upstream version 2.81
[platform/upstream/libbullet.git] / src / BulletMultiThreaded / SpuSampleTask / SpuSampleTask.cpp
1 /*
2 Bullet Continuous Collision Detection and Physics Library, Copyright (c) 2007 Erwin Coumans
3
4 This software is provided 'as-is', without any express or implied warranty.
5 In no event will the authors be held liable for any damages arising from the use of this software.
6 Permission is granted to anyone to use this software for any purpose, 
7 including commercial applications, and to alter it and redistribute it freely, 
8 subject to the following restrictions:
9
10 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.
11 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
12 3. This notice may not be removed or altered from any source distribution.
13
14 */
15
16
17 #include "SpuSampleTask.h"
18 #include "BulletDynamics/Dynamics/btRigidBody.h"
19 #include "../PlatformDefinitions.h"
20 #include "../SpuFakeDma.h"
21 #include "LinearMath/btMinMax.h"
22
23 #ifdef __SPU__
24 #include <spu_printf.h>
25 #else
26 #include <stdio.h>
27 #define spu_printf printf
28 #endif
29
30 #define MAX_NUM_BODIES 8192
31
32 struct SampleTask_LocalStoreMemory
33 {
34         ATTRIBUTE_ALIGNED16(char gLocalRigidBody [sizeof(btRigidBody)+16]);
35         ATTRIBUTE_ALIGNED16(void* gPointerArray[MAX_NUM_BODIES]);
36
37 };
38
39
40
41
42 //-- MAIN METHOD
43 void processSampleTask(void* userPtr, void* lsMemory)
44 {
45         //      BT_PROFILE("processSampleTask");
46
47         SampleTask_LocalStoreMemory* localMemory = (SampleTask_LocalStoreMemory*)lsMemory;
48
49         SpuSampleTaskDesc* taskDescPtr = (SpuSampleTaskDesc*)userPtr;
50         SpuSampleTaskDesc& taskDesc = *taskDescPtr;
51
52         switch (taskDesc.m_sampleCommand)
53         {
54         case CMD_SAMPLE_INTEGRATE_BODIES:
55                 {
56                         btTransform predictedTrans;
57                         btCollisionObject** eaPtr = (btCollisionObject**)taskDesc.m_mainMemoryPtr;
58
59                         int batchSize = taskDesc.m_sampleValue;
60                         if (batchSize>MAX_NUM_BODIES)
61                         {
62                                 spu_printf("SPU Error: exceed number of bodies, see MAX_NUM_BODIES in SpuSampleTask.cpp\n");
63                                 break;
64                         }
65                         int dmaArraySize = batchSize*sizeof(void*);
66
67                         uint64_t ppuArrayAddress = reinterpret_cast<uint64_t>(eaPtr);
68
69                         //                      spu_printf("array location is at %llx, batchSize = %d, DMA size = %d\n",ppuArrayAddress,batchSize,dmaArraySize);
70
71                         if (dmaArraySize>=16)
72                         {
73                                 cellDmaLargeGet((void*)&localMemory->gPointerArray[0], ppuArrayAddress  , dmaArraySize, DMA_TAG(1), 0, 0);      
74                                 cellDmaWaitTagStatusAll(DMA_MASK(1));
75                         } else
76                         {
77                                 stallingUnalignedDmaSmallGet((void*)&localMemory->gPointerArray[0], ppuArrayAddress  , dmaArraySize);
78                         }
79
80
81                         for ( int i=0;i<batchSize;i++)
82                         {
83                                 ///DMA rigid body
84
85                                 void* localPtr = &localMemory->gLocalRigidBody[0];
86                                 void* shortAdd = localMemory->gPointerArray[i];
87                                 uint64_t ppuRigidBodyAddress = reinterpret_cast<uint64_t>(shortAdd);
88
89                                 //      spu_printf("cellDmaGet at CMD_SAMPLE_INTEGRATE_BODIES from %llx to %llx\n",ppuRigidBodyAddress,localPtr);
90
91                                 int dmaBodySize = sizeof(btRigidBody);
92
93                                 cellDmaGet((void*)localPtr, ppuRigidBodyAddress  , dmaBodySize, DMA_TAG(1), 0, 0);      
94                                 cellDmaWaitTagStatusAll(DMA_MASK(1));
95
96
97                                 float timeStep = 1.f/60.f;
98
99                                 btRigidBody* body = (btRigidBody*) localPtr;//btRigidBody::upcast(colObj);
100                                 if (body)
101                                 {
102                                         if (body->isActive() && (!body->isStaticOrKinematicObject()))
103                                         {
104                                                 body->predictIntegratedTransform(timeStep, predictedTrans);
105                                                 body->proceedToTransform( predictedTrans);
106                                                 void* ptr = (void*)localPtr;
107                                                 //      spu_printf("cellDmaLargePut from %llx to LS %llx\n",ptr,ppuRigidBodyAddress);
108
109                                                 cellDmaLargePut(ptr, ppuRigidBodyAddress  , dmaBodySize, DMA_TAG(1), 0, 0);
110                                                 cellDmaWaitTagStatusAll(DMA_MASK(1));
111
112                                         }
113                                 }
114
115                         }
116                         break;
117                 }
118
119
120         case CMD_SAMPLE_PREDICT_MOTION_BODIES:
121                 {
122                         btTransform predictedTrans;
123                         btCollisionObject** eaPtr = (btCollisionObject**)taskDesc.m_mainMemoryPtr;
124
125                         int batchSize = taskDesc.m_sampleValue;
126                         int dmaArraySize = batchSize*sizeof(void*);
127
128                         if (batchSize>MAX_NUM_BODIES)
129                         {
130                                 spu_printf("SPU Error: exceed number of bodies, see MAX_NUM_BODIES in SpuSampleTask.cpp\n");
131                                 break;
132                         }
133
134                         uint64_t ppuArrayAddress = reinterpret_cast<uint64_t>(eaPtr);
135
136                         //                      spu_printf("array location is at %llx, batchSize = %d, DMA size = %d\n",ppuArrayAddress,batchSize,dmaArraySize);
137
138                         if (dmaArraySize>=16)
139                         {
140                                 cellDmaLargeGet((void*)&localMemory->gPointerArray[0], ppuArrayAddress  , dmaArraySize, DMA_TAG(1), 0, 0);      
141                                 cellDmaWaitTagStatusAll(DMA_MASK(1));
142                         } else
143                         {
144                                 stallingUnalignedDmaSmallGet((void*)&localMemory->gPointerArray[0], ppuArrayAddress  , dmaArraySize);
145                         }
146
147
148                         for ( int i=0;i<batchSize;i++)
149                         {
150                                 ///DMA rigid body
151
152                                 void* localPtr = &localMemory->gLocalRigidBody[0];
153                                 void* shortAdd = localMemory->gPointerArray[i];
154                                 uint64_t ppuRigidBodyAddress = reinterpret_cast<uint64_t>(shortAdd);
155
156                                 //      spu_printf("cellDmaGet at CMD_SAMPLE_INTEGRATE_BODIES from %llx to %llx\n",ppuRigidBodyAddress,localPtr);
157
158                                 int dmaBodySize = sizeof(btRigidBody);
159
160                                 cellDmaGet((void*)localPtr, ppuRigidBodyAddress  , dmaBodySize, DMA_TAG(1), 0, 0);      
161                                 cellDmaWaitTagStatusAll(DMA_MASK(1));
162
163
164                                 float timeStep = 1.f/60.f;
165
166                                 btRigidBody* body = (btRigidBody*) localPtr;//btRigidBody::upcast(colObj);
167                                 if (body)
168                                 {
169                                         if (!body->isStaticOrKinematicObject())
170                                         {
171                                                 if (body->isActive())
172                                                 {
173                                                         body->integrateVelocities( timeStep);
174                                                         //damping
175                                                         body->applyDamping(timeStep);
176
177                                                         body->predictIntegratedTransform(timeStep,body->getInterpolationWorldTransform());
178
179                                                         void* ptr = (void*)localPtr;
180                                                         cellDmaLargePut(ptr, ppuRigidBodyAddress  , dmaBodySize, DMA_TAG(1), 0, 0);
181                                                         cellDmaWaitTagStatusAll(DMA_MASK(1));
182                                                 }
183                                         }
184                                 }
185
186                         }
187                         break;
188                 }
189         
190
191
192         default:
193                 {
194
195                 }
196         };
197 }
198
199
200 #if defined(__CELLOS_LV2__) || defined (LIBSPE2)
201
202 ATTRIBUTE_ALIGNED16(SampleTask_LocalStoreMemory gLocalStoreMemory);
203
204 void* createSampleLocalStoreMemory()
205 {
206         return &gLocalStoreMemory;
207 }
208 #else
209 void* createSampleLocalStoreMemory()
210 {
211         return new SampleTask_LocalStoreMemory;
212 };
213
214 #endif