Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "SpuCollisionTaskProcess.h"
00023
00024
00025
00026
00027 void SpuCollisionTaskProcess::setNumTasks(int maxNumTasks)
00028 {
00029 if (int(m_maxNumOutstandingTasks) != maxNumTasks)
00030 {
00031 m_maxNumOutstandingTasks = maxNumTasks;
00032 m_taskBusy.resize(m_maxNumOutstandingTasks);
00033 m_spuGatherTaskDesc.resize(m_maxNumOutstandingTasks);
00034
00035 for (int i = 0; i < m_taskBusy.size(); i++)
00036 {
00037 m_taskBusy[i] = false;
00038 }
00039
00041 if (m_workUnitTaskBuffers != 0)
00042 {
00043 btAlignedFree(m_workUnitTaskBuffers);
00044 }
00045
00046 m_workUnitTaskBuffers = (unsigned char *)btAlignedAlloc(MIDPHASE_WORKUNIT_TASK_SIZE*m_maxNumOutstandingTasks, 128);
00047 }
00048
00049 }
00050
00051
00052
00053 SpuCollisionTaskProcess::SpuCollisionTaskProcess(class btThreadSupportInterface* threadInterface, unsigned int maxNumOutstandingTasks)
00054 :m_threadInterface(threadInterface),
00055 m_maxNumOutstandingTasks(0)
00056 {
00057 m_workUnitTaskBuffers = (unsigned char *)0;
00058 setNumTasks(maxNumOutstandingTasks);
00059 m_numBusyTasks = 0;
00060 m_currentTask = 0;
00061 m_currentPage = 0;
00062 m_currentPageEntry = 0;
00063
00064 #ifdef DEBUG_SpuCollisionTaskProcess
00065 m_initialized = false;
00066 #endif
00067
00068 m_threadInterface->startSPU();
00069
00070
00071 printf("sizeof SpuGatherAndProcessWorkUnitInput: %d\n", int(sizeof(SpuGatherAndProcessWorkUnitInput)));
00072
00073 }
00074
00075 SpuCollisionTaskProcess::~SpuCollisionTaskProcess()
00076 {
00077
00078 if (m_workUnitTaskBuffers != 0)
00079 {
00080 btAlignedFree(m_workUnitTaskBuffers);
00081 m_workUnitTaskBuffers = 0;
00082 }
00083
00084
00085
00086 m_threadInterface->stopSPU();
00087
00088 }
00089
00090
00091
00092 void SpuCollisionTaskProcess::initialize2(bool useEpa)
00093 {
00094
00095 #ifdef DEBUG_SPU_TASK_SCHEDULING
00096 printf("SpuCollisionTaskProcess::initialize()\n");
00097 #endif //DEBUG_SPU_TASK_SCHEDULING
00098
00099 for (int i = 0; i < int (m_maxNumOutstandingTasks); i++)
00100 {
00101 m_taskBusy[i] = false;
00102 }
00103 m_numBusyTasks = 0;
00104 m_currentTask = 0;
00105 m_currentPage = 0;
00106 m_currentPageEntry = 0;
00107 m_useEpa = useEpa;
00108
00109 #ifdef DEBUG_SpuCollisionTaskProcess
00110 m_initialized = true;
00111 btAssert(MIDPHASE_NUM_WORKUNITS_PER_TASK*sizeof(SpuGatherAndProcessWorkUnitInput) <= MIDPHASE_WORKUNIT_TASK_SIZE);
00112 #endif
00113 }
00114
00115
00116 void SpuCollisionTaskProcess::issueTask2()
00117 {
00118
00119 #ifdef DEBUG_SPU_TASK_SCHEDULING
00120 printf("SpuCollisionTaskProcess::issueTask (m_currentTask= %d\n)", m_currentTask);
00121 #endif //DEBUG_SPU_TASK_SCHEDULING
00122
00123 m_taskBusy[m_currentTask] = true;
00124 m_numBusyTasks++;
00125
00126
00127 SpuGatherAndProcessPairsTaskDesc& taskDesc = m_spuGatherTaskDesc[m_currentTask];
00128 taskDesc.m_useEpa = m_useEpa;
00129
00130 {
00131
00132
00133
00134
00135 taskDesc.m_inPairPtr = reinterpret_cast<uint64_t>(MIDPHASE_TASK_PTR(m_currentTask));
00136
00137 taskDesc.taskId = m_currentTask;
00138 taskDesc.numPages = m_currentPage+1;
00139 taskDesc.numOnLastPage = m_currentPageEntry;
00140 }
00141
00142
00143
00144 m_threadInterface->sendRequest(CMD_GATHER_AND_PROCESS_PAIRLIST, (ppu_address_t) &taskDesc,m_currentTask);
00145
00146
00147
00148
00149 if (m_numBusyTasks >= m_maxNumOutstandingTasks)
00150 {
00151 unsigned int taskId;
00152 unsigned int outputSize;
00153
00154
00155 for (int i=0;i<int (m_maxNumOutstandingTasks);i++)
00156 {
00157 if (m_taskBusy[i])
00158 {
00159 taskId = i;
00160 break;
00161 }
00162 }
00163
00164 btAssert(taskId>=0);
00165
00166
00167 m_threadInterface->waitForResponse(&taskId, &outputSize);
00168
00169
00170
00171
00172
00173
00174
00175 m_taskBusy[taskId] = false;
00176
00177 m_numBusyTasks--;
00178 }
00179
00180 }
00181
00182 void SpuCollisionTaskProcess::addWorkToTask(void* pairArrayPtr,int startIndex,int endIndex)
00183 {
00184 #ifdef DEBUG_SPU_TASK_SCHEDULING
00185 printf("#");
00186 #endif //DEBUG_SPU_TASK_SCHEDULING
00187
00188 #ifdef DEBUG_SpuCollisionTaskProcess
00189 btAssert(m_initialized);
00190 btAssert(m_workUnitTaskBuffers);
00191
00192 #endif
00193
00194 bool batch = true;
00195
00196 if (batch)
00197 {
00198 if (m_currentPageEntry == MIDPHASE_NUM_WORKUNITS_PER_PAGE)
00199 {
00200 if (m_currentPage == MIDPHASE_NUM_WORKUNIT_PAGES-1)
00201 {
00202
00203
00204 issueTask2();
00205
00206
00207 for (unsigned int i = 0; i < m_maxNumOutstandingTasks; i++)
00208 {
00209 if (!m_taskBusy[i])
00210 {
00211 m_currentTask = i;
00212
00213
00214 break;
00215 }
00216 }
00217
00218 m_currentPage = 0;
00219 }
00220 else
00221 {
00222 m_currentPage++;
00223 }
00224
00225 m_currentPageEntry = 0;
00226 }
00227 }
00228
00229 {
00230
00231
00232
00233 SpuGatherAndProcessWorkUnitInput &wuInput =
00234 *(reinterpret_cast<SpuGatherAndProcessWorkUnitInput*>
00235 (MIDPHASE_ENTRY_PTR(m_currentTask, m_currentPage, m_currentPageEntry)));
00236
00237 wuInput.m_pairArrayPtr = reinterpret_cast<uint64_t>(pairArrayPtr);
00238 wuInput.m_startIndex = startIndex;
00239 wuInput.m_endIndex = endIndex;
00240
00241
00242
00243 m_currentPageEntry++;
00244
00245 if (!batch)
00246 {
00247 issueTask2();
00248
00249
00250 for (unsigned int i = 0; i < m_maxNumOutstandingTasks; i++)
00251 {
00252 if (!m_taskBusy[i])
00253 {
00254 m_currentTask = i;
00255
00256
00257 break;
00258 }
00259 }
00260
00261 m_currentPage = 0;
00262 m_currentPageEntry =0;
00263 }
00264 }
00265 }
00266
00267
00268 void
00269 SpuCollisionTaskProcess::flush2()
00270 {
00271 #ifdef DEBUG_SPU_TASK_SCHEDULING
00272 printf("\nSpuCollisionTaskProcess::flush()\n");
00273 #endif //DEBUG_SPU_TASK_SCHEDULING
00274
00275
00276 if (m_currentPage > 0 || m_currentPageEntry > 0)
00277 {
00278 issueTask2();
00279 }
00280
00281
00282
00283 while(m_numBusyTasks > 0)
00284 {
00285
00286 unsigned int taskId=-1;
00287 unsigned int outputSize;
00288
00289 for (int i=0;i<int (m_maxNumOutstandingTasks);i++)
00290 {
00291 if (m_taskBusy[i])
00292 {
00293 taskId = i;
00294 break;
00295 }
00296 }
00297
00298 btAssert(taskId>=0);
00299
00300
00301 {
00302
00303
00304 m_threadInterface->waitForResponse(&taskId, &outputSize);
00305 }
00306
00307
00308
00309
00310
00311 m_taskBusy[taskId] = false;
00312
00313 m_numBusyTasks--;
00314 }
00315
00316
00317 }