Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/physics/src/bullet/BulletMultiThreaded/SpuRaycastTaskProcess.cpp @ 1967

Last change on this file since 1967 was 1966, checked in by rgrieder, 16 years ago

Let's go for multithreaded physics!

  • Property svn:eol-style set to native
File size: 5.3 KB
Line 
1/*
2Bullet Continuous Collision Detection and Physics Library
3Copyright (c) 2003-2007 Erwin Coumans  http://bulletphysics.com
4
5This software is provided 'as-is', without any express or implied warranty.
6In no event will the authors be held liable for any damages arising from the use of this software.
7Permission is granted to anyone to use this software for any purpose,
8including commercial applications, and to alter it and redistribute it freely,
9subject to the following restrictions:
10
111. 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.
122. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
133. This notice may not be removed or altered from any source distribution.
14*/
15
16#include "SpuRaycastTaskProcess.h"
17
18
19SpuRaycastTaskProcess::SpuRaycastTaskProcess(class      btThreadSupportInterface*       threadInterface,  int   maxNumOutstandingTasks)
20:m_threadInterface(threadInterface),
21m_maxNumOutstandingTasks(maxNumOutstandingTasks)
22{
23        m_workUnitTaskBuffers = (unsigned char *)0;
24        m_taskBusy.resize(m_maxNumOutstandingTasks);
25        m_spuRaycastTaskDesc.resize(m_maxNumOutstandingTasks);
26
27        for (int i = 0; i < m_maxNumOutstandingTasks; i++)
28        {
29                m_taskBusy[i] = false;
30        }
31        m_numBusyTasks = 0;
32        m_currentTask = 0;
33        m_currentWorkUnitInTask = 0;
34
35        m_threadInterface->startSPU();
36
37        //printf("sizeof vec_float4: %d\n", sizeof(vec_float4));
38        //printf("sizeof SpuGatherAndProcessWorkUnitInput: %d\n", sizeof(SpuGatherAndProcessWorkUnitInput));
39
40}
41
42SpuRaycastTaskProcess::~SpuRaycastTaskProcess()
43{
44       
45        if (m_workUnitTaskBuffers != 0)
46        {
47                btAlignedFree(m_workUnitTaskBuffers);
48                m_workUnitTaskBuffers = 0;
49        }
50       
51        m_threadInterface->stopSPU();   
52}
53
54
55
56void SpuRaycastTaskProcess::initialize2(void* spuCollisionObjectsWrappers, int numSpuCollisionObjectWrappers)
57{
58        m_spuCollisionObjectWrappers = spuCollisionObjectsWrappers;
59        m_numSpuCollisionObjectWrappers = numSpuCollisionObjectWrappers;
60        for (int i = 0; i < m_maxNumOutstandingTasks; i++)
61        {
62                m_taskBusy[i] = false;
63        }
64        m_numBusyTasks = 0;
65        m_currentTask = 0;
66        m_currentWorkUnitInTask = 0;
67
68#ifdef DEBUG_SpuRaycastTaskProcess
69        m_initialized = true;
70#endif
71}
72
73
74void SpuRaycastTaskProcess::issueTask2()
75{
76        m_taskBusy[m_currentTask] = true;
77        m_numBusyTasks++;
78
79        SpuRaycastTaskDesc& taskDesc = m_spuRaycastTaskDesc[m_currentTask];
80
81        taskDesc.taskId = m_currentTask;
82        m_threadInterface->sendRequest(1, (uint32_t) &taskDesc,m_currentTask);
83        //printf("send thread requested for task %d\n", m_currentTask);
84        // if all tasks busy, wait for spu event to clear the task.
85        if (m_numBusyTasks >= m_maxNumOutstandingTasks)
86        {
87                unsigned int taskId;
88                unsigned int outputSize;
89
90                for (int i=0;i<m_maxNumOutstandingTasks;i++)
91          {
92                  if (m_taskBusy[i])
93                  {
94                          taskId = i;
95                          break;
96                  }
97          }
98                m_threadInterface->waitForResponse(&taskId, &outputSize);
99
100                //printf("PPU: after issue, received event: %u %d\n", taskId, outputSize);
101
102                m_taskBusy[taskId] = false;
103
104                m_numBusyTasks--;
105        } else {
106                //printf("Sent request, not enough busy tasks\n");
107        }
108}
109
110void SpuRaycastTaskProcess::addWorkToTask(SpuRaycastTaskWorkUnit& workunit)
111{
112        m_spuRaycastTaskDesc[m_currentTask].workUnits[m_currentWorkUnitInTask] = workunit;
113        m_currentWorkUnitInTask++;
114        if (m_currentWorkUnitInTask == SPU_RAYCAST_WORK_UNITS_PER_TASK)
115        {
116                m_spuRaycastTaskDesc[m_currentTask].numWorkUnits = m_currentWorkUnitInTask;
117                m_spuRaycastTaskDesc[m_currentTask].numSpuCollisionObjectWrappers = m_numSpuCollisionObjectWrappers;
118                m_spuRaycastTaskDesc[m_currentTask].spuCollisionObjectsWrappers = m_spuCollisionObjectWrappers;
119                //printf("Task buffer full, issuing\n");
120                issueTask2 ();
121                //printf("Returned from issueTask2()\n");
122                m_currentWorkUnitInTask = 0;
123
124                // find new task buffer
125                for (int i = 0; i < m_maxNumOutstandingTasks; i++)
126                {
127                        if (!m_taskBusy[i])
128                        {
129                                m_currentTask = i;
130                                //init the task data
131                                break;
132                        }
133                }
134                //printf("next task = %d\n", m_currentTask);
135        }
136}
137
138
139void 
140SpuRaycastTaskProcess::flush2()
141{
142#ifdef DEBUG_SPU_TASK_SCHEDULING
143        printf("\nSpuRaycastTaskProcess::flush()\n");
144#endif //DEBUG_SPU_TASK_SCHEDULING
145       
146        // if there's a partially filled task buffer, submit that task
147        //printf("Flushing... %d remaining\n", m_currentWorkUnitInTask);
148        if (m_currentWorkUnitInTask > 0)
149        {
150                m_spuRaycastTaskDesc[m_currentTask].numWorkUnits = m_currentWorkUnitInTask;
151                m_spuRaycastTaskDesc[m_currentTask].numSpuCollisionObjectWrappers = m_numSpuCollisionObjectWrappers;
152                m_spuRaycastTaskDesc[m_currentTask].spuCollisionObjectsWrappers = m_spuCollisionObjectWrappers;
153                issueTask2();
154                m_currentWorkUnitInTask = 0;
155        }
156
157
158        // all tasks are issued, wait for all tasks to be complete
159        while(m_numBusyTasks > 0)
160        {
161          // Consolidating SPU code
162          unsigned int taskId;
163          unsigned int outputSize;
164         
165          for (int i=0;i<m_maxNumOutstandingTasks;i++)
166          {
167                  if (m_taskBusy[i])
168                  {
169                          taskId = i;
170                          break;
171                  }
172          }
173
174          //printf("Busy tasks... %d\n", m_numBusyTasks);
175
176          {
177                        // SPURS support.
178                        m_threadInterface->waitForResponse(&taskId, &outputSize);
179                }
180
181                //printf("PPU: flushing, received event: %u %d\n", taskId, outputSize);
182
183                //postProcess(taskId, outputSize);
184
185                m_taskBusy[taskId] = false;
186
187                m_numBusyTasks--;
188        }
189}
Note: See TracBrowser for help on using the repository browser.