diff options
| author | daoge_cmd <3523206925@qq.com> | 2026-03-01 12:16:08 +0800 |
|---|---|---|
| committer | daoge_cmd <3523206925@qq.com> | 2026-03-01 12:16:08 +0800 |
| commit | b691c43c44ff180d10e7d4a9afc83b98551ff586 (patch) | |
| tree | 3e9849222cbc6ba49f2f1fc6e5fe7179632c7390 /Minecraft.Client/PS3/PS3Extras/EdgeZLib.cpp | |
| parent | def8cb415354ac390b7e89052a50605285f1aca9 (diff) | |
Initial commit
Diffstat (limited to 'Minecraft.Client/PS3/PS3Extras/EdgeZLib.cpp')
| -rw-r--r-- | Minecraft.Client/PS3/PS3Extras/EdgeZLib.cpp | 419 |
1 files changed, 419 insertions, 0 deletions
diff --git a/Minecraft.Client/PS3/PS3Extras/EdgeZLib.cpp b/Minecraft.Client/PS3/PS3Extras/EdgeZLib.cpp new file mode 100644 index 00000000..2b0a523f --- /dev/null +++ b/Minecraft.Client/PS3/PS3Extras/EdgeZLib.cpp @@ -0,0 +1,419 @@ +#include "stdafx.h" +#include <stdlib.h> +#include "EdgeZLib.h" +#include "edge/zlib/edgezlib_ppu.h" + +static CellSpurs* s_pSpurs = NULL; + +//Set this to 5 if you want deflate/inflate to run in parallel on 5 SPUs. + +const uint32_t kNumDeflateTasks = 1; +const uint32_t kMaxNumDeflateQueueEntries = 64; +static CellSpursEventFlag s_eventFlagDeflate; //Cannot be on stack +static CellSpursTaskset s_taskSetDeflate; //Cannot be on stack +static EdgeZlibDeflateQHandle s_deflateQueue; +static void* s_pDeflateQueueBuffer = NULL; +static void* s_pDeflateTaskContext[kNumDeflateTasks]; +static uint32_t s_numElementsToCompress; //Cannot be on stack + + +const uint32_t kNumInflateTasks = 1; +const uint32_t kMaxNumInflateQueueEntries = 64; +static CellSpursEventFlag s_eventFlagInflate; //Cannot be on stack +static CellSpursTaskset s_taskSetInflate; //Cannot be on stack +static EdgeZlibInflateQHandle s_inflateQueue; +static void* s_pInflateQueueBuffer = NULL; +static void* s_pInflateTaskContext[kNumInflateTasks]; +static uint32_t s_numElementsToDecompress; //Cannot be on stack + + +static CRITICAL_SECTION s_critSect; + +static const bool sc_verbose = false; + +#define printf_verbose(...) { if(sc_verbose){ printf(__VA_ARGS__);} } + + + +void EdgeZLib::Init(CellSpurs* pSpurs) +{ + s_pSpurs = pSpurs; + InitializeCriticalSection(&s_critSect); + + ////////////////////////////////////////////////////////////////////////// + // + // Initialize Deflate Queue. + // This will hold the queue of work that the Deflate Task(s) on SPU will + // pull work from. + // + ////////////////////////////////////////////////////////////////////////// + { + + // register taskSet + CellSpursTasksetAttribute taskSetAttribute; + uint8_t prios[8] = {15, 15, 15, 15, 15, 15, 0, 0}; + int ret = cellSpursTasksetAttributeInitialize( &taskSetAttribute, 0, prios, 8 ); + PS3_ASSERT_CELL_ERROR(ret); + ret = cellSpursTasksetAttributeSetName(&taskSetAttribute, "edgeZlibDeflateTaskSet"); + PS3_ASSERT_CELL_ERROR(ret); + ret = cellSpursCreateTasksetWithAttribute( pSpurs, &s_taskSetDeflate, &taskSetAttribute ); + PS3_ASSERT_CELL_ERROR(ret); + + ret = cellSpursEventFlagInitializeIWL( pSpurs, + &s_eventFlagDeflate, + CELL_SPURS_EVENT_FLAG_CLEAR_AUTO, + CELL_SPURS_EVENT_FLAG_SPU2PPU ); + PS3_ASSERT_CELL_ERROR(ret); + + ret = cellSpursEventFlagAttachLv2EventQueue( &s_eventFlagDeflate ); + PS3_ASSERT_CELL_ERROR(ret); +#ifndef _CONTENT_PACKAGE + printf_verbose( "PPU: Event flag created\n" ); +#endif + + uint32_t deflateQueueBuffSize = edgeZlibGetDeflateQueueSize( kMaxNumDeflateQueueEntries ); + s_pDeflateQueueBuffer = memalign( EDGE_ZLIB_DEFLATE_QUEUE_ALIGN, deflateQueueBuffSize ); + s_deflateQueue = edgeZlibCreateDeflateQueue( + s_pSpurs, + kMaxNumDeflateQueueEntries, + s_pDeflateQueueBuffer, + deflateQueueBuffSize ); +#ifndef _CONTENT_PACKAGE + printf_verbose( "PPU: Deflate Queue created\n" ); +#endif + + ////////////////////////////////////////////////////////////////////////// + // + // Build Deflate Tasks. + // We want the compression to be able to run in parallel on multiple + // SPUs so we create as many tasks as SPUs that we want it to run + // on (kNumDeflateTasks). + // + ////////////////////////////////////////////////////////////////////////// + + s_pDeflateTaskContext[kNumDeflateTasks]; + for( uint32_t taskNum = 0 ; taskNum < kNumDeflateTasks ; taskNum++ ) + { + uint32_t contextSaveSize = edgeZlibGetDeflateTaskContextSaveSize(); + s_pDeflateTaskContext[taskNum] = memalign( CELL_SPURS_TASK_CONTEXT_ALIGN, contextSaveSize ); + edgeZlibCreateDeflateTask( &s_taskSetDeflate, s_pDeflateTaskContext[taskNum], s_deflateQueue ); + } +#ifndef _CONTENT_PACKAGE + printf_verbose( "PPU: %d Deflate Task(s) started\n", kNumDeflateTasks ); +#endif + } + + + + { + + + + ////////////////////////////////////////////////////////////////////////// + // + // Initialize taskset and event flag + // + ////////////////////////////////////////////////////////////////////////// + + // register taskSet + CellSpursTasksetAttribute taskSetAttribute; + uint8_t prios[8] = {15, 15, 15, 15, 15, 15, 0, 0}; + int ret = cellSpursTasksetAttributeInitialize( &taskSetAttribute, 0, prios, 8 ); + PS3_ASSERT_CELL_ERROR(ret); + ret = cellSpursTasksetAttributeSetName(&taskSetAttribute, "edgeZlibInflateTaskSet"); + PS3_ASSERT_CELL_ERROR(ret); + ret = cellSpursCreateTasksetWithAttribute( s_pSpurs, &s_taskSetInflate, &taskSetAttribute ); + PS3_ASSERT_CELL_ERROR(ret); +#ifndef _CONTENT_PACKAGE + printf_verbose( "PPU: Inflate Taskset created\n" ); +#endif + + ret = cellSpursEventFlagInitializeIWL( s_pSpurs, + &s_eventFlagInflate, + CELL_SPURS_EVENT_FLAG_CLEAR_AUTO, + CELL_SPURS_EVENT_FLAG_SPU2PPU ); + PS3_ASSERT_CELL_ERROR(ret); + + ret = cellSpursEventFlagAttachLv2EventQueue( &s_eventFlagInflate ); + PS3_ASSERT_CELL_ERROR(ret); +#ifndef _CONTENT_PACKAGE + printf_verbose( "PPU: Event flag created\n" ); +#endif + + ////////////////////////////////////////////////////////////////////////// + // + // Initialize Inflate Queue. + // This will hold the queue of work that the Inflate Task(s) on SPU will + // pull work from. + // + ////////////////////////////////////////////////////////////////////////// + + uint32_t inflateQueueBuffSize = edgeZlibGetInflateQueueSize( kMaxNumInflateQueueEntries ); + s_pInflateQueueBuffer = memalign( EDGE_ZLIB_INFLATE_QUEUE_ALIGN, inflateQueueBuffSize ); + s_inflateQueue = edgeZlibCreateInflateQueue( + s_pSpurs, + kMaxNumInflateQueueEntries, + s_pInflateQueueBuffer, + inflateQueueBuffSize ); +#ifndef _CONTENT_PACKAGE + printf_verbose( "PPU: Inflate Queue created\n" ); +#endif + ////////////////////////////////////////////////////////////////////////// + // + // Build Inflate Tasks. + // We want the compression to be able to run in parallel on multiple + // SPUs so we create as many tasks as SPUs that we want it to run + // on (kNumInflateTasks). + // + ////////////////////////////////////////////////////////////////////////// + + for( uint32_t taskNum = 0 ; taskNum < kNumInflateTasks ; taskNum++ ) + { + uint32_t contextSaveSize = edgeZlibGetInflateTaskContextSaveSize(); + s_pInflateTaskContext[taskNum] = memalign( CELL_SPURS_TASK_CONTEXT_ALIGN, contextSaveSize ); + edgeZlibCreateInflateTask( &s_taskSetInflate, s_pInflateTaskContext[taskNum], s_inflateQueue ); + } +#ifndef _CONTENT_PACKAGE + printf_verbose( "PPU: %d Inflate Task(s) started\n", kNumInflateTasks ); +#endif + } + +} + + + + + + +bool EdgeZLib::Compress(void* pDestination, uint32_t* pDestSize, const void* pSource, uint32_t SrcSize) +{ + EnterCriticalSection(&s_critSect); + + ////////////////////////////////////////////////////////////////////////// + // + // Add one item to the Deflate Queue. + // The Deflate Task will wake up and process this work. + // + ////////////////////////////////////////////////////////////////////////// + uint32_t* pDst = NULL; + bool findingSizeOnly = false; + if(pDestination == NULL && *pDestSize == 0) + { + pDst = (uint32_t*)malloc(SrcSize); + findingSizeOnly = true; + *pDestSize = SrcSize; + } + else + { + pDst = ((uint32_t*)pDestination); + } + + pDst[0] = SrcSize; // 4 byte header added for source size + + + s_numElementsToCompress = 1; //Must be set correctly before any elements are added + + uint16_t eventFlagBits = 1; + + uint32_t compressionLevel = 9; + static uint32_t s_compressedSize; //Cannot be on stack + + // create one task queue entry (max 64K deflate per entry) + edgeZlibAddDeflateQueueElement( s_deflateQueue, + pSource, SrcSize, + &pDst[1], *pDestSize, + &s_compressedSize, + &s_numElementsToCompress, //This will be decremented by 1 when this element is compressed + &s_eventFlagDeflate, //When s_numElementsToCompress decrements to zero, this event will be triggered + eventFlagBits, + compressionLevel, + kEdgeZlibDeflateTask_DeflateStoreCompressed + ); + +#ifndef _CONTENT_PACKAGE + printf_verbose( "PPU: Deflate element(s) added to queue\n" ); + + printf_verbose( "PPU: Wait for event flag acknowledgment\n" ); +#endif + + ////////////////////////////////////////////////////////////////////////// + // + // Wait for the event flag to be acknowledged in order to tell us the + // work is done. + // + ////////////////////////////////////////////////////////////////////////// + + int ret = cellSpursEventFlagWait( &s_eventFlagDeflate, &eventFlagBits, CELL_SPURS_EVENT_FLAG_AND ); + PS3_ASSERT_CELL_ERROR(ret ); + assert( s_numElementsToCompress == 0 ); //Should have reached zero by now + +#ifndef _CONTENT_PACKAGE + printf_verbose( "PPU: Edge Zlib event acknowledged\n" ); +#endif + // ensure Deflate task told us it stored the compressed data + assert( (s_compressedSize & kEdgeZlibDeflateTask_HowStoredMask) == kEdgeZlibDeflateTask_CompressedWasStored ); + // remove bit from s_compressedSize + s_compressedSize &= ~kEdgeZlibDeflateTask_HowStoredMask; + + + + + ////////////////////////////////////////////////////////////////////////// + // + // Print stats + // + ////////////////////////////////////////////////////////////////////////// + +#ifndef _CONTENT_PACKAGE + printf_verbose( "\n uncompSiz compSiz compress%% numTasks\n" ); + printf_verbose( "___________________________________________\n" ); +#endif + float compressionPercent = (1.f - (float)s_compressedSize / (float)SrcSize) * 100.f; + +#ifndef _CONTENT_PACKAGE + printf_verbose( " 0x%05x 0x%05x %8.2f%% %d\n\n", + (int)SrcSize, (int)s_compressedSize, compressionPercent, kNumDeflateTasks ); +#endif + + *pDestSize = s_compressedSize + 4; // 4 byte header for size + if(findingSizeOnly) + free(pDst); + LeaveCriticalSection(&s_critSect); + + return true; +} + +void EdgeZLib::Shutdown() +{ + ////////////////////////////////////////////////////////////////////////// + // + // Shutdown Deflate Queue, event flag and taskset. + // + ////////////////////////////////////////////////////////////////////////// + +#ifndef _CONTENT_PACKAGE + printf_verbose( "PPU: Shutdown Deflate Queue...\n" ); +#endif + edgeZlibShutdownDeflateQueue( s_deflateQueue ); + + int ret = cellSpursEventFlagDetachLv2EventQueue( &s_eventFlagDeflate ); + PS3_ASSERT_CELL_ERROR(ret); + + // shutdown taskSet +#ifndef _CONTENT_PACKAGE + printf_verbose( "PPU: Wait for taskset shutdown...\n" ); +#endif + ret = cellSpursShutdownTaskset( &s_taskSetDeflate ); + PS3_ASSERT_CELL_ERROR(ret); + // wait for all tasks to finish + ret = cellSpursJoinTaskset( &s_taskSetDeflate ); + PS3_ASSERT_CELL_ERROR(ret); +#ifndef _CONTENT_PACKAGE + printf_verbose( "PPU: Shutdown taskset completed.\n" ); +#endif + // free alloc'd buffers + for( uint32_t taskNum = 0 ; taskNum < kNumDeflateTasks ; taskNum++ ) + { + free( s_pDeflateTaskContext[taskNum] ); + } + free( s_pDeflateQueueBuffer ); + + + ////////////////////////////////////////////////////////////////////////// + // + // Shutdown Inflate Queue, event flag and taskset. + // + ////////////////////////////////////////////////////////////////////////// + +#ifndef _CONTENT_PACKAGE + printf_verbose( "PPU: Shutdown Inflate Queue...\n" ); +#endif + edgeZlibShutdownInflateQueue( s_inflateQueue ); + + ret = cellSpursEventFlagDetachLv2EventQueue( &s_eventFlagInflate ); + PS3_ASSERT_CELL_ERROR(ret); + + // shutdown taskSet +#ifndef _CONTENT_PACKAGE + printf_verbose( "PPU: Wait for taskset shutdown...\n" ); +#endif + ret = cellSpursShutdownTaskset( &s_taskSetInflate ); + PS3_ASSERT_CELL_ERROR(ret); + // wait for all tasks to finish + ret = cellSpursJoinTaskset( &s_taskSetInflate ); + PS3_ASSERT_CELL_ERROR(ret); +#ifndef _CONTENT_PACKAGE + printf_verbose( "PPU: Shutdown taskset completed.\n" ); +#endif + + // free alloc'd buffers + for( uint32_t taskNum = 0 ; taskNum < kNumInflateTasks ; taskNum++ ) + { + free( s_pInflateTaskContext[taskNum] ); + } + free( s_pInflateQueueBuffer ); + + +} + +bool EdgeZLib::Decompress(void* pDestination, uint32_t* pDestSize, const void* pSource, uint32_t SrcSize) +{ + +#if 1 + EnterCriticalSection(&s_critSect); + + const uint32_t* pSrc = (uint32_t*)pSource; + uint32_t uncompressedSize = pSrc[0]; + assert(uncompressedSize <= (*pDestSize)); + + + + ////////////////////////////////////////////////////////////////////////// + // + // Add one item to the Inflate Queue. + // The Inflate Task will wake up and process this work. + // + ////////////////////////////////////////////////////////////////////////// + + s_numElementsToDecompress = 1; //Must be set correctly before any elements are added + + uint16_t eventFlagBits = 1; + + // create one task queue entry (max 64K inflate per entry) + edgeZlibAddInflateQueueElement( s_inflateQueue, + &pSrc[1], SrcSize, + pDestination, uncompressedSize, + &s_numElementsToDecompress, //This will be decremented by 1 when this element is compressed + &s_eventFlagInflate, //When s_numElementsToDecompress decrements to zero, this event will be triggered + eventFlagBits, + kEdgeZlibInflateTask_Inflate + ); + +#ifndef _CONTENT_PACKAGE + printf_verbose( "PPU: Inflate element(s) added to queue\n" ); + + printf_verbose( "PPU: Wait for event flag acknowledgment\n" ); +#endif + + ////////////////////////////////////////////////////////////////////////// + // + // Wait for the event flag to be acknowledged in order to tell us the + // work is done. + // + ////////////////////////////////////////////////////////////////////////// + + int ret = cellSpursEventFlagWait( &s_eventFlagInflate, &eventFlagBits, CELL_SPURS_EVENT_FLAG_AND ); + PS3_ASSERT_CELL_ERROR(ret); + assert( s_numElementsToDecompress == 0 ); //Should have reached zero by now + +#ifndef _CONTENT_PACKAGE + printf_verbose( "PPU: Edge Zlib event acknowledged\n" ); +#endif + + *pDestSize = uncompressedSize; + LeaveCriticalSection(&s_critSect); + + return true; + +#endif // 0 +}
\ No newline at end of file |
