aboutsummaryrefslogtreecommitdiff
path: root/Minecraft.Client/PS3/PS3Extras/EdgeZLib.cpp
diff options
context:
space:
mode:
authordaoge_cmd <3523206925@qq.com>2026-03-01 12:16:08 +0800
committerdaoge_cmd <3523206925@qq.com>2026-03-01 12:16:08 +0800
commitb691c43c44ff180d10e7d4a9afc83b98551ff586 (patch)
tree3e9849222cbc6ba49f2f1fc6e5fe7179632c7390 /Minecraft.Client/PS3/PS3Extras/EdgeZLib.cpp
parentdef8cb415354ac390b7e89052a50605285f1aca9 (diff)
Initial commit
Diffstat (limited to 'Minecraft.Client/PS3/PS3Extras/EdgeZLib.cpp')
-rw-r--r--Minecraft.Client/PS3/PS3Extras/EdgeZLib.cpp419
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