#pragma once #include "Cafe/HW/Latte/ISA/LatteReg.h" #include "Cafe/HW/Espresso/Const.h" struct GX2WriteGatherPipeState { uint8* gxRingBuffer; // each core has it's own write gatherer and display list state (writing) std::atomic writeGatherPtrGxBuffer[Espresso::CORE_COUNT]; std::atomic* writeGatherPtrWrite[Espresso::CORE_COUNT]; std::atomic writeGatherPtrDisplayList[Espresso::CORE_COUNT]; MPTR displayListStart[Espresso::CORE_COUNT]; uint32 displayListMaxSize[Espresso::CORE_COUNT]; }; extern GX2WriteGatherPipeState gx2WriteGatherPipe; void GX2ReserveCmdSpace(uint32 reservedFreeSpaceInU32); // move to GX2 namespace eventually void gx2WriteGather_submitU32AsBE(uint32 v); void gx2WriteGather_submitU32AsLE(uint32 v); void gx2WriteGather_submitU32AsLEArray(uint32* v, uint32 numValues); uint32 PPCInterpreter_getCurrentCoreIndex(); // gx2WriteGather_submit functions template inline void gx2WriteGather_submit_(uint32 coreIndex, uint32be* writePtr) { (*gx2WriteGatherPipe.writeGatherPtrWrite[coreIndex]) = (uint8*)writePtr; } template inline void gx2WriteGather_submit_(uint32 coreIndex, uint32be* writePtr, const betype& arg, Targs... args) { static_assert(sizeof(betype) == sizeof(uint32be)); *(betype*)writePtr = arg; writePtr++; gx2WriteGather_submit_(coreIndex, writePtr, args...); } template inline typename std::enable_if< std::is_floating_point::value, void>::type gx2WriteGather_submit_(uint32 coreIndex, uint32be* writePtr, const T& arg, Targs... args) { static_assert(sizeof(T) == sizeof(uint32)); *writePtr = *(uint32*)&arg; writePtr++; gx2WriteGather_submit_(coreIndex, writePtr, args...); } template inline typename std::enable_if< std::is_base_of::value, void>::type gx2WriteGather_submit_(uint32 coreIndex, uint32be* writePtr, const T& arg, Targs... args) { static_assert(sizeof(Latte::LATTEREG) == sizeof(uint32be)); *writePtr = arg.getRawValue(); writePtr++; gx2WriteGather_submit_(coreIndex, writePtr, args...); } template inline typename std::enable_if< !std::is_base_of::value && !std::is_floating_point::value, void>::type gx2WriteGather_submit_(uint32 coreIndex, uint32be* writePtr, const T& arg, Targs... args) { *writePtr = arg; writePtr++; gx2WriteGather_submit_(coreIndex, writePtr, args...); } template inline void gx2WriteGather_submit(Targs... args) { uint32 coreIndex = PPCInterpreter_getCurrentCoreIndex(); if (*gx2WriteGatherPipe.writeGatherPtrWrite[coreIndex] == nullptr) return; uint32be* writePtr = (uint32be*)gx2WriteGatherPipe.writeGatherPtrWrite[coreIndex]->load(); gx2WriteGather_submit_(coreIndex, writePtr, std::forward(args)...); } namespace GX2 { uint32 GX2WriteGather_getReadWriteDistance(); void GX2WriteGather_checkAndInsertWrapAroundMark(); void GX2BeginDisplayList(MEMPTR displayListAddr, uint32 size); void GX2BeginDisplayListEx(MEMPTR displayListAddr, uint32 size, bool profiling); uint32 GX2EndDisplayList(MEMPTR displayListAddr); void GX2CallDisplayList(MPTR addr, uint32 size); void GX2DirectCallDisplayList(void* addr, uint32 size); bool GX2GetDisplayListWriteStatus(); void GX2Init_writeGather(); void GX2CommandInit(); void GX2CommandResetToDefaultState(); }