pm4::Buffer * flushCommandBuffer(pm4::Buffer *cb) { auto core = coreinit::OSGetCoreId(); if (!cb) { cb = gActiveBuffer[core]; } else if (cb != gActiveBuffer[core]) { throw std::logic_error("Attempting to flush non-active buffer"); } if (!cb) { return nullptr; } if (cb->userBuffer) { void *newList = nullptr; uint32_t newSize = 0; // End the active display list GX2EndDisplayList(cb->buffer); // Ask user to allocate new display list std::tie(newList, newSize) = displayListOverrun(cb->buffer, cb->curSize * 4); if (!newList || !newSize) { throw std::logic_error("Unable to handle display list overrun"); } // Begin new display list, it will update gActiveBuffer GX2BeginDisplayList(newList, newSize); } else { // Send buffer to our driver! gpu::queueCommandBuffer(cb); // Allocate new buffer gActiveBuffer[core] = allocateCommandBuffer(); } return gActiveBuffer[core]; }
pm4::Buffer * flushCommandBuffer(uint32_t neededSize) { auto core = coreinit::OSGetCoreId(); auto cb = sActiveBuffer[core]; decaf_check(cb); if (cb->displayList) { void *newList = nullptr; uint32_t newSize = 0; // End the active display list padCommandBuffer(cb); // Ask user to allocate new display list std::tie(newList, newSize) = displayListOverrun(cb->buffer, cb->curSize * 4, neededSize * 4); if (!newList || !newSize) { decaf_abort("Unable to handle display list overrun"); } // Record the new information returned from the application cb->buffer = reinterpret_cast<uint32_t *>(newList); cb->curSize = 0; cb->maxSize = newSize / 4; return cb; } // Flush the existing buffer flushActiveCommandBuffer(); // Allocate new buffer sActiveBuffer[core] = allocateCommandBuffer(neededSize); return sActiveBuffer[core]; }