the game where you go into mines and start crafting! but for consoles (forked directly from smartcmd's github)
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//