Version
menu_open
link

include/AK/Plugin/PluginServices/PS3/MultiCoreServices.h

Go to the documentation of this file.
00001 
00002 //
00003 // MultiCoreServices.h
00004 //
00005 // PS3 implementation
00006 //
00007 // Copyright (c) 2006 Audiokinetic Inc. / All Rights Reserved
00008 //
00010 #ifndef MULTICORE_SERVICES_H_
00011 #define MULTICORE_SERVICES_H_
00012 
00013 #include <AK/SoundEngine/Common/AkTypes.h>
00014 
00015 #include <stdlib.h>
00016 #include <AK/Tools/Common/AkAssert.h>
00017 #include <string.h>
00018 
00019 #include <cell/spurs/job_chain.h>
00020 #include <cell/spurs/job_descriptor.h>
00021 #include <cell/spurs/job_commands.h>
00022 
00023 #if defined (__SPU__) && defined (_DEBUG)
00024 #include <spu_printf.h>
00025 #endif
00026 
00027 namespace AK
00028 {
00029 namespace MultiCoreServices
00030 {
00032     struct BinData
00033     {
00034         void*       pAddress;   
00035         AkUInt16    Size;       
00036     };
00037 
00038 #ifndef __SPU__
00039 
00040 
00041     static AkNoInline AkInt32 AddSpursJobDma(AkSpursJob& in_SpursJob, void *in_pSource, AkUInt32 uiLength)
00042     {
00043         // this must be __attribute__((aligned(16))) at least
00044         // __attribute__((aligned(128))) is recommended
00045         AKASSERT(((uintptr_t)in_pSource & 0x0000000F) == 0);
00046 
00047         // figure out how much we can take
00048         AkUInt16 MaxSize = sizeof(in_SpursJob.workArea.dmaList);
00049 
00050         // is there any space left ?
00051         if(in_SpursJob.header.sizeDmaList < MaxSize)
00052         {
00053             AkUInt32 NumDmas = 0;
00054             uintptr_t uiPointer = (uintptr_t) in_pSource;
00055             uint64_t uiSize = AK_ALIGN_SIZE_FOR_DMA(uiLength);
00056 
00057             AKASSERT(uiSize == uiLength);
00058 
00059             uint64_t uiSizeLeft = uiSize;
00060 
00061             // break the transfer in 16kB chunks if needed
00062             while(uiSizeLeft > 0)
00063             {
00064                 // still got some space left ?
00065                 if(in_SpursJob.header.sizeDmaList < MaxSize)
00066                 {
00067                     ++NumDmas;
00068 
00069                     // get 16kB at most
00070                     uint64_t uiChunkSize = (uiSizeLeft > 16384) ? 16384 : uiSizeLeft;
00071 
00072                     // build the dma list element
00073                     AkUInt64 DmaListElement = (0 & 1ULL) << 63 | (uiChunkSize & 0xffffULL) << 32 | ((uintptr_t) uiPointer  & 0xffffffffULL);
00074                     in_SpursJob.workArea.dmaList[in_SpursJob.header.sizeDmaList/8] = DmaListElement;
00075                     // update the dma list size
00076                     in_SpursJob.header.sizeDmaList += 8;
00077 
00078                     // keep track of what's goin on
00079                     uiSizeLeft -= uiChunkSize;
00080                     uiPointer += uiChunkSize;
00081                 }
00082                 else
00083                 {
00084                     // the whole transfer could not fit in the dma list
00085                     return -1;
00086                 }
00087             }
00088 
00089             // all is well the transfer fits in the dma list
00090             in_SpursJob.header.sizeInOrInOut += uiSize;
00091             return NumDmas;
00092         }
00093         // dma list is full
00094         return -1;
00095     }
00096 
00099     static AkForceInline void AddSpursJobSmallDma(AkSpursJob& in_SpursJob, const void *in_pSource, AkUInt32 uiLength)
00100     {
00101         // this must be __attribute__((aligned(16))) at least
00102         // __attribute__((aligned(128))) is recommended
00103         AKASSERT(uiLength <= (16*1024));
00104         AKASSERT(((uintptr_t)in_pSource & 0x0000000F) == 0);
00105         AKASSERT(uiLength== AK_ALIGN_SIZE_FOR_DMA(uiLength));
00106         AKASSERT( in_SpursJob.header.sizeDmaList < sizeof(in_SpursJob.workArea.dmaList) );
00107         AKASSERT( uiLength != 0 );
00108 
00109         AkUInt64 DmaListElement = (0 & 1ULL) << 63 | (uiLength & 0xffffULL) << 32 | ((uintptr_t) in_pSource  & 0xffffffffULL);
00110         in_SpursJob.workArea.dmaList[in_SpursJob.header.sizeDmaList/8] = DmaListElement;
00111         in_SpursJob.header.sizeDmaList += 8;
00112         in_SpursJob.header.sizeInOrInOut += uiLength;
00113     }
00114 #endif 
00115 
00116     struct DspProcess
00117     {
00118 #ifndef __SPU__
00119 
00120         inline void ResetDspProcess( 
00121             bool in_bIO     
00122             )
00123         {
00124             memset( &SpursJob, 0, sizeof( SpursJob ) ); // gets inlined into vector stores
00125             // should we use I/O buffers ?
00126             SpursJob.header.useInOutBuffer = in_bIO ? 1 : 0;
00127 #ifdef _DEBUG
00128             SpursJob.header.jobType =  CELL_SPURS_JOB_TYPE_MEMORY_CHECK;
00129 #endif
00130         }
00131 
00133         inline void SetOutputBufferSize( 
00134             AkUInt32 in_uSize   
00135             )
00136         {
00137             AKASSERT( !( in_uSize & 0xf ) ); // 16-byte aligned size
00138 
00139             SpursJob.header.sizeOut = in_uSize;
00140         }
00141 
00143         inline void SetScratchSize(
00144             AkUInt32 in_ScratchBytes    
00145             )
00146         {
00147             // convert to quads
00148             AkUInt16 ScratchSize = (in_ScratchBytes + 15) / 16;
00149             SpursJob.header.sizeScratch = ScratchSize;
00150         }
00151 
00154         inline void SetStackSize(
00155             AkUInt32 in_StackBytes  
00156             )
00157         {
00158             // convert to quads
00159             AkUInt16 StackSize = (in_StackBytes + 15) / 16;
00160             SpursJob.header.sizeStack = StackSize;
00161         }
00162 
00164         inline void SetDspProcess(BinData& in_BinData)
00165         {
00166             // this must be __attribute__((aligned(16)))
00167             AKASSERT(((uintptr_t)in_BinData.pAddress & 0x0000000F) == 0);
00168             // set the executable info
00169             SpursJob.header.eaBinary = (uintptr_t)in_BinData.pAddress;
00170             SpursJob.header.sizeBinary = in_BinData.Size;
00171         }
00172 
00174         inline int SetDspProcess( const void * in_jobbin2 )
00175         {
00176             return cellSpursJobHeaderSetJobbin2Param( &SpursJob.header, in_jobbin2 );
00177         }
00178 
00181         inline AkInt32 AddDspProcessDma(void *in_pSource, AkUInt32 uiLength)
00182         {
00183             return AddSpursJobDma(SpursJob,in_pSource,uiLength);
00184         }
00185 
00188         inline void AddDspProcessSmallDma(const void *in_pSource, AkUInt32 uiLength)
00189         {
00190             AddSpursJobSmallDma(SpursJob,in_pSource,uiLength);
00191         }
00192 
00197         inline void SetUserData( 
00198             AkUInt32 uIdx,      
00199             AkUInt64 uData      
00200             )
00201         {
00202             AKASSERT( uIdx*8 >= SpursJob.header.sizeDmaList );
00203             SpursJob.workArea.userData[ uIdx ] = uData;
00204         }
00205 
00207         inline AkUInt64 GetSpursJobCommand()
00208         {
00209             return CELL_SPURS_JOB_COMMAND_JOB(&SpursJob);
00210         }
00211 #endif
00212 
00213     private:
00214         AkSpursJob      SpursJob AK_ALIGN_FASTDMA;
00215     } AK_ALIGN_FASTDMA;
00216 
00217 #if defined(__SPU__) && defined(_DEBUG)
00218 
00219     AkForceInline void ShowContext(CellSpursJobContext2 *pContext,  CellSpursJob256 *pJob)
00220     {
00221         int NumIoBuffers = pContext->numIoBuffer;
00222         spu_printf("SPU =========> numIoBuffer      = %d\n",NumIoBuffers);
00223 
00224         // Get BufferList
00225         void *pBufferList[NumIoBuffers];
00226         int nGetBufferResult = cellSpursJobGetPointerList(pBufferList, &pJob->header, pContext);
00227 
00228         if ( nGetBufferResult == CELL_OK )
00229         {
00230             for(int Counter = 0 ; Counter < NumIoBuffers ; ++Counter)
00231             {
00232                 spu_printf("SPU =========> pBufferList[%2d] = 0x%8.8X\n",Counter, (unsigned int) pBufferList[Counter]);
00233             }
00234         }
00235         else
00236         {
00237             spu_printf("SPU =========> pBufferList : Error : Can't get buffer list. [%s%s]", nGetBufferResult == CELL_SPURS_JOB_ERROR_ALIGN ? "CELL_SPURS_JOB_ERROR_ALIGN" : "", nGetBufferResult == CELL_SPURS_JOB_ERROR_NULL_POINTER ? "CELL_SPURS_JOB_ERROR_NULL_POINTER" : "");
00238         }
00239         spu_printf("SPU =========> numCacheBuffer   = %d\n",pContext->numCacheBuffer);
00240         spu_printf("SPU =========> oBuffer          = 0x%8.8X\n",(unsigned int) pContext->oBuffer);
00241         spu_printf("SPU =========> sBuffer          = 0x%8.8X\n",(unsigned int) pContext->sBuffer);
00242         spu_printf("SPU =========> dmaTag           = %d\n",pContext->dmaTag);
00243         spu_printf("SPU =========> eaJobDescriptor  = 0x%llX\n",pContext->eaJobDescriptor);
00244     }
00245 
00247     AkForceInline void ShowJob(CellSpursJob256 *pJob)
00248     {
00249         spu_printf("SPU =========> eaBinary         = 0x%8.8X\n",(unsigned int) pJob->header.eaBinary);
00250         spu_printf("SPU =========> sizeBinary       = %d\n",pJob->header.sizeBinary);
00251         spu_printf("SPU =========> sizeDmaList      = %d\n",pJob->header.sizeDmaList);
00252         spu_printf("SPU =========> eaHighInput      = %d\n",pJob->header.eaHighInput);
00253         spu_printf("SPU =========> useInOutBuffer   = %d\n",pJob->header.useInOutBuffer);
00254         spu_printf("SPU =========> sizeInOrInOut    = %d\n",pJob->header.sizeInOrInOut);
00255         spu_printf("SPU =========> sizeOut          = %d\n",pJob->header.sizeOut);
00256         spu_printf("SPU =========> sizeStack        = %d\n",pJob->header.sizeStack);
00257         spu_printf("SPU =========> sizeScratch      = %d\n",pJob->header.sizeScratch);
00258         spu_printf("SPU =========> eaHighCache      = %d\n",pJob->header.eaHighCache);
00259         spu_printf("SPU =========> sizeCacheDmaList = %d\n",pJob->header.sizeCacheDmaList);
00260     //  CellSpursJobID idJob;
00261 
00262         uint64_t* pUserData = (uint64_t*)pJob->workArea.userData;
00263 
00264         for(int Counter = 0 ; Counter < 10 ; ++Counter)
00265         {
00266             uint64_t Data = *pUserData++;
00267             spu_printf("SPU =========> userData[%d]      = 0x%llX\n",Counter,Data);
00268         }
00269     }
00270     
00272     AkForceInline void PrintVectorHex(void* in_pVector)
00273     {
00274         spu_printf("SPU =========> 0x%8.8X 0x%8.8X 0x%8.8X 0x%8.8X\n",  *(unsigned int*)in_pVector,
00275                                                                         *((unsigned int*)in_pVector + 1),
00276                                                                         *((unsigned int*)in_pVector + 2),
00277                                                                         *((unsigned int*)in_pVector + 3));
00278     }
00279 
00281     AkForceInline void PrintVectorFloat(void* in_pVector)
00282     {
00283         spu_printf("SPU =========> %.3f %.3f %.3f %.3f\n",  *(float*)in_pVector,
00284                                                             *((float*)in_pVector + 1),
00285                                                             *((float*)in_pVector + 2),
00286                                                             *((float*)in_pVector + 3));
00287     }
00288 #endif // defined(__SPU__) && defined(_DEBUG)
00289 }
00290 }
00291 
00292 #endif // MULTICORE_SERVICES_H_

Was this page helpful?

Need Support?

Questions? Problems? Need more info? Contact us, and we can help!

Visit our Support page

Tell us about your project. We're here to help.

Register your project and we'll help you get started with no strings attached!

Get started with Wwise