the game where you go into mines and start crafting! but for consoles (forked directly from smartcmd's github)
at main 409 lines 12 kB view raw
1#include "stdafx.h" 2 3 4#include <stdio.h> 5#include <stdlib.h> 6#include <string.h> 7#include <cell/spurs.h> 8#include "C4JSpursJob.h" 9#include "C4JThread_SPU.h" 10// #include "PS3\SPU_Tasks\SPUMemTools\SPUMemTools.h" 11 12 13using namespace cell::Spurs::JobQueue; 14 15static const unsigned int NUM_SUBMIT_JOBS = 128; 16#define DMA_ALIGNMENT (128) 17#define JOBHEADER_SYMBOL(JobName) _binary_jqjob_##JobName##_jobbin2_jobheader 18 19C4JSpursJobQueue* C4JSpursJobQueue::m_pMainJobQueue = NULL; 20 21uint16_t C4JSpursJobQueue::Port::s_jobTagBitmask = 0; 22C4JSpursJobQueue::Port* C4JSpursJobQueue::Port::s_allocatedPorts[16] = {NULL,NULL,NULL,NULL, 23 NULL,NULL,NULL,NULL, 24 NULL,NULL,NULL,NULL, 25 NULL,NULL,NULL,NULL }; 26bool C4JSpursJobQueue::Port::s_initialised; 27CRITICAL_SECTION C4JSpursJobQueue::Port::s_lock; 28 29 30C4JSpursJobQueue::C4JSpursJobQueue() 31{ 32 int ret; 33 cell::Spurs::Spurs* spurs = C4JThread_SPU::getSpurs2(); 34 35 //E create job descriptor pool 36 const CellSpursJobQueueJobDescriptorPool poolDescriptor = { 37 0, 0, NUM_SUBMIT_JOBS, 0, 0, 0, 0, 0 38 }; 39 unsigned int sizeOfJobDescriptorPool = 40 CELL_SPURS_JOBQUEUE_JOB_DESCRIPTOR_POOL_SIZE(0, 0, NUM_SUBMIT_JOBS, 0, 0, 0, 0, 0); 41 42 pPool = (uint8_t*)memalign(DMA_ALIGNMENT, sizeOfJobDescriptorPool); 43 44 //E create jobQueue 45 pJobQueue = (JobQueue<JOB_QUEUE_DEPTH>*)memalign(CELL_SPURS_JOBQUEUE_ALIGN, sizeof(JobQueue<JOB_QUEUE_DEPTH>)); 46 assert(pJobQueue != NULL); 47 48 ret = JobQueue<JOB_QUEUE_DEPTH>::create( pJobQueue, 49 spurs, 50 "SampleJobQueue", 51 5, //numSpus 52 8, // priority 53 (void*)pPool, 54 &poolDescriptor, 55 4, // maxGrab 56 false, // submitWithEntryLock 57 false, // doBusyWaiting 58 false, //isHaltOnError 59 true, // autoPrxLoad 60 1 ); //uint8_t maxNumJobsOnASpu = CELL_SPURS_JOBQUEUE_DEFAULT_MAX_NUM_JOBS_ON_SPU, 61 62 63 64 assert(ret == CELL_OK); 65 (void)ret; 66} 67 68 69C4JSpursJobQueue::Port::Port(const char* portName) 70{ 71 m_portName = portName; 72 if(!s_initialised) 73 InitializeCriticalSection(&s_lock); 74 s_initialised = true; 75 76 EnterCriticalSection(&s_lock); 77 78 m_pPort2 = (Port2*)memalign(CELL_SPURS_JOBQUEUE_PORT2_ALIGN, CELL_SPURS_JOBQUEUE_PORT2_SIZE); 79 assert(m_pPort2); 80 int ret = Port2::create(m_pPort2, C4JSpursJobQueue::getMainJobQueue().pJobQueue); 81 assert(ret == CELL_OK); 82 83 84 m_jobTag = getFreeJobTag(); 85 m_bDestroyed = false; 86 LeaveCriticalSection(&s_lock); 87} 88 89C4JSpursJobQueue::Port::~Port() 90{ 91 EnterCriticalSection(&s_lock); 92 releaseJobTag(m_jobTag); 93 if(!m_bDestroyed) 94 { 95 int ret = m_pPort2->destroy(); 96 assert(ret == CELL_OK); 97 } 98 free(m_pPort2); 99 LeaveCriticalSection(&s_lock); 100 101} 102 103 104void C4JSpursJobQueue::Port::submitJob(C4JSpursJob* pJob) 105{ 106 if(m_bDestroyed) 107 return; 108 int ret; 109 //E submit job 110 ret = m_pPort2->copyPushJob(&pJob->m_job256.header, sizeof(CellSpursJob256), sizeof(CellSpursJob256), m_jobTag, 111 CELL_SPURS_JOBQUEUE_FLAG_SYNC_JOB); 112 if(ret != CELL_OK) 113 app.DebugPrintf("copyPushJob failed with error 0x%08x\n", ret); 114 assert(ret == CELL_OK); 115 116} 117 118void C4JSpursJobQueue::Port::waitForCompletion() 119{ 120 if(m_bDestroyed) 121 return; 122 int ret; 123 ret = m_pPort2->sync(0); 124 assert(ret == CELL_OK); 125 (void)ret; // remove unused var warning 126} 127 128bool C4JSpursJobQueue::Port::hasCompleted() 129{ 130 if(m_bDestroyed) 131 return true; 132 133 int ret; 134 ret = m_pPort2->sync(CELL_SPURS_JOBQUEUE_FLAG_NON_BLOCKING); 135 if(ret == CELL_SPURS_JOB_ERROR_AGAIN) 136 return false; 137 assert(ret == CELL_OK); 138 return true; 139} 140 141 142void C4JSpursJobQueue::Port::submitSync() 143{ 144 if(m_bDestroyed) 145 return; 146 147 int status; 148 status = m_pPort2->pushSync(1u << m_jobTag, 0); 149 assert(status == CELL_OK); 150 (void)status; // remove unused var warning 151} 152 153int C4JSpursJobQueue::Port::getFreeJobTag() 154{ 155 for(int i=0;i<16;i++) 156 { 157 if((s_jobTagBitmask & (1<<i)) == 0) 158 { 159 s_jobTagBitmask |= (1<<i); 160 s_allocatedPorts[i] = this; 161 return i; 162 } 163 } 164 assert(0); 165 return 0; 166} 167 168void C4JSpursJobQueue::Port::releaseJobTag( int tag ) 169{ 170 s_jobTagBitmask &= ~(1<<tag); 171 s_allocatedPorts[tag] = NULL; 172} 173 174void C4JSpursJobQueue::Port::destroyAll() 175{ 176 // bit hacky, but the texture blit port seems to stall on destroy if we don't have this 177 // presumably because it uses a non-blocking sync 178 extern C4JSpursJobQueue::Port* g_texBlitJobQueuePort; 179 if(g_texBlitJobQueuePort) 180 { 181 g_texBlitJobQueuePort->waitForCompletion(); 182 } 183 184 for(int i=0;i<16;i++) 185 { 186 if(s_allocatedPorts[i]) 187 { 188 s_allocatedPorts[i]->m_bDestroyed = true; 189 int ret = s_allocatedPorts[i]->m_pPort2->destroy(); 190 assert(ret == CELL_OK); 191 } 192 } 193#ifndef _CONTENT_PACKAGE 194 printf("C4JSpursJobQueue::Port::destroyAll\n"); 195#endif 196} 197 198 199 200 201void C4JSpursJobQueue::shutdown() 202{ 203 Port::destroyAll(); 204 int ret = pJobQueue->shutdown(); 205 assert(ret == CELL_OK); 206 int exitCode; 207 ret = pJobQueue->join(&exitCode); 208 assert(ret == CELL_OK && exitCode == CELL_OK); 209 210 free(pJobQueue); 211 free(pPool); 212#ifndef _CONTENT_PACKAGE 213 printf("C4JSpursJobQueue::shutdown\n"); 214#endif 215} 216 217 218 219C4JSpursJob::C4JSpursJob() 220{ 221 __builtin_memset(&m_job256, 0, sizeof(CellSpursJob256)); 222} 223 224 225 226C4JSpursJob_CompressedTile::C4JSpursJob_CompressedTile(TileCompressData_SPU* pDataIn, unsigned char* pDataOut) 227 : C4JSpursJob() 228{ 229 extern const CellSpursJobHeader JOBHEADER_SYMBOL(CompressedTile); 230 //E create job 231 m_job256.header = JOBHEADER_SYMBOL(CompressedTile); 232 m_job256.header.sizeStack = (64*1024)>>4; 233 m_job256.workArea.userData[0] = (uintptr_t)pDataIn; 234 m_job256.workArea.userData[1] = (uintptr_t)pDataOut; 235 236} 237 238 239C4JSpursJob_ChunkUpdate::C4JSpursJob_ChunkUpdate(ChunkRebuildData* pDataIn, ChunkRebuildData* pDataOut) 240: C4JSpursJob() 241{ 242 extern const CellSpursJobHeader JOBHEADER_SYMBOL(ChunkUpdate); 243 //E create job 244 m_job256.header = JOBHEADER_SYMBOL(ChunkUpdate); 245 m_job256.header.sizeStack = (60*1024)>>4; 246 m_job256.workArea.userData[0] = (uintptr_t)pDataIn; 247 m_job256.workArea.userData[1] = (uintptr_t)pDataOut; 248 assert(cellSpursJobQueueCheckJob(&m_job256, 256, 256) == CELL_OK); 249 250} 251 252C4JSpursJob_LevelRenderer_cull::C4JSpursJob_LevelRenderer_cull(LevelRenderer_cull_DataIn* pDataIn) 253 : C4JSpursJob() 254{ 255 extern const CellSpursJobHeader JOBHEADER_SYMBOL(LevelRenderer_cull); 256 //E create job 257 m_job256.header = JOBHEADER_SYMBOL(LevelRenderer_cull); 258 m_job256.header.sizeStack = (200*1024)>>4; // this is extremely tight, global flags take up 164K 259 m_job256.workArea.userData[0] = (uintptr_t)pDataIn; 260 261 assert(cellSpursJobQueueCheckJob(&m_job256, 256, 256) == CELL_OK); 262 263} 264 265C4JSpursJob_LevelRenderer_zSort::C4JSpursJob_LevelRenderer_zSort(LevelRenderer_cull_DataIn* pDataIn) 266 : C4JSpursJob() 267{ 268 extern const CellSpursJobHeader JOBHEADER_SYMBOL(LevelRenderer_zSort); 269 //E create job 270 m_job256.header = JOBHEADER_SYMBOL(LevelRenderer_zSort); 271 m_job256.header.sizeStack = (200*1024)>>4; // this is extremely tight, global flags take up 164K 272 m_job256.workArea.userData[0] = (uintptr_t)pDataIn; 273 274 assert(cellSpursJobQueueCheckJob(&m_job256, 256, 256) == CELL_OK); 275 276} 277 278C4JSpursJob_LevelRenderer_FindNearestChunk::C4JSpursJob_LevelRenderer_FindNearestChunk(LevelRenderer_FindNearestChunk_DataIn* pDataIn) 279 : C4JSpursJob() 280{ 281 extern const CellSpursJobHeader JOBHEADER_SYMBOL(LevelRenderer_FindNearestChunk); 282 //E create job 283 m_job256.header = JOBHEADER_SYMBOL(LevelRenderer_FindNearestChunk); 284 m_job256.header.sizeStack = (200*1024)>>4; // this is extremely tight, global flags take up 164K 285 m_job256.workArea.userData[0] = (uintptr_t)pDataIn; 286 287 assert(cellSpursJobQueueCheckJob(&m_job256, 256, 256) == CELL_OK); 288 289} 290 291 292 293// C4JSpursJob_Renderer_TextureUpdate::C4JSpursJob_Renderer_TextureUpdate(Renderer_TextureUpdate_DataIn* pDataIn) 294// : C4JSpursJob() 295// { 296// extern const CellSpursJobHeader JOBHEADER_SYMBOL(Renderer_TextureUpdate); 297// int ret; 298// //E create job 299// m_job256.header = JOBHEADER_SYMBOL(Renderer_TextureUpdate); 300// m_job256.header.sizeStack = (200*1024)>>4; 301// m_job256.workArea.userData[0] = (uintptr_t)pDataIn; 302// 303// assert(cellSpursJobQueueCheckJob(&m_job256, 256, 256) == CELL_OK); 304// 305// } 306// 307 308C4JSpursJob_Texture_blit::C4JSpursJob_Texture_blit(Texture_blit_DataIn* pDataIn) 309 : C4JSpursJob() 310{ 311 extern const CellSpursJobHeader JOBHEADER_SYMBOL(Texture_blit); 312 //E create job 313 m_job256.header = JOBHEADER_SYMBOL(Texture_blit); 314 m_job256.header.sizeStack = (200*1024)>>4; 315 m_job256.workArea.userData[0] = (uintptr_t)pDataIn; 316 317 assert(cellSpursJobQueueCheckJob(&m_job256, 256, 256) == CELL_OK); 318 319} 320 321C4JSpursJob_CompressedTileStorage_compress::C4JSpursJob_CompressedTileStorage_compress(CompressedTileStorage_compress_dataIn* pDataIn) 322 : C4JSpursJob() 323{ 324 extern const CellSpursJobHeader JOBHEADER_SYMBOL(CompressedTileStorage_compress); 325 //E create job 326 m_job256.header = JOBHEADER_SYMBOL(CompressedTileStorage_compress); 327 m_job256.header.sizeStack = (200*1024)>>4; 328 m_job256.workArea.userData[0] = (uintptr_t)pDataIn; 329 330 assert(cellSpursJobQueueCheckJob(&m_job256, 256, 256) == CELL_OK); 331 332} 333 334/* 335C4JSpursJob_CompressedTileStorage_getData::C4JSpursJob_CompressedTileStorage_getData(unsigned char* pIdxAndData, int dataSize, unsigned char* pDst, unsigned int retOffset) 336 : C4JSpursJob() 337{ 338 extern const CellSpursJobHeader JOBHEADER_SYMBOL(CompressedTileStorage_getData); 339 int ret; 340 //E create job 341 m_job256.header = JOBHEADER_SYMBOL(CompressedTileStorage_getData); 342 m_job256.header.sizeStack = (200*1024)>>4; 343 m_job256.workArea.userData[0] = (uintptr_t)pIdxAndData; 344 m_job256.workArea.userData[1] = (uintptr_t)dataSize; 345 m_job256.workArea.userData[2] = (uintptr_t)pDst; 346 m_job256.workArea.userData[3] = (uintptr_t)retOffset; 347 348 assert(cellSpursJobQueueCheckJob(&m_job256, 256, 256) == CELL_OK); 349 350} */ 351 352// C4JSpursJob_GameRenderer_updateLightTexture::C4JSpursJob_GameRenderer_updateLightTexture(GameRenderer_updateLightTexture_dataIn* pDataIn) 353// : C4JSpursJob() 354// { 355// extern const CellSpursJobHeader JOBHEADER_SYMBOL(GameRenderer_updateLightTexture); 356// int ret; 357// //E create job 358// m_job256.header = JOBHEADER_SYMBOL(GameRenderer_updateLightTexture); 359// m_job256.header.sizeStack = (200*1024)>>4; 360// m_job256.workArea.userData[0] = (uintptr_t)pDataIn; 361// 362// assert(cellSpursJobQueueCheckJob(&m_job256, 256, 256) == CELL_OK); 363// 364// } 365 366C4JSpursJob_PerlinNoise::C4JSpursJob_PerlinNoise(PerlinNoise_DataIn* pDataIn) 367 : C4JSpursJob() 368{ 369 extern const CellSpursJobHeader JOBHEADER_SYMBOL(PerlinNoise); 370 //E create job 371 m_job256.header = JOBHEADER_SYMBOL(PerlinNoise); 372 m_job256.header.sizeStack = (200*1024)>>4; 373 m_job256.workArea.userData[0] = (uintptr_t)pDataIn; 374 375 assert(cellSpursJobQueueCheckJob(&m_job256, 256, 256) == CELL_OK); 376} 377 378// C4JSpursJob_MemSet::C4JSpursJob_MemSet(void* pMem, int numBytes, uint8_t val) 379// : C4JSpursJob() 380// { 381// extern const CellSpursJobHeader JOBHEADER_SYMBOL(SPUMemTools); 382// int ret; 383// //E create job 384// m_job256.header = JOBHEADER_SYMBOL(SPUMemTools); 385// m_job256.header.sizeStack = (200*1024)>>4; 386// m_job256.workArea.userData[0] = (uintptr_t)e_SPUMemToolsFunc_MemSet; 387// m_job256.workArea.userData[1] = (uintptr_t)pMem; 388// m_job256.workArea.userData[2] = (uintptr_t)numBytes; 389// m_job256.workArea.userData[3] = (uintptr_t)val; 390// 391// assert(cellSpursJobQueueCheckJob(&m_job256, 256, 256) == CELL_OK); 392// } 393 394// C4JSpursJob_RLECompress::C4JSpursJob_RLECompress(void* pSrc, int srcSize, void* pDst, int* pDstSize) 395// : C4JSpursJob() 396// { 397// extern const CellSpursJobHeader JOBHEADER_SYMBOL(RLECompress); 398// int ret; 399// //E create job 400// m_job256.header = JOBHEADER_SYMBOL(RLECompress); 401// m_job256.header.sizeStack = (200*1024)>>4; 402// m_job256.workArea.userData[0] = (uintptr_t)pSrc; 403// m_job256.workArea.userData[1] = (uintptr_t)srcSize; 404// m_job256.workArea.userData[2] = (uintptr_t)pDst; 405// m_job256.workArea.userData[3] = (uintptr_t)pDstSize; 406// 407// assert(cellSpursJobQueueCheckJob(&m_job256, 256, 256) == CELL_OK); 408// } 409//