Skip to content

Commit

Permalink
gpu: Somewhat handle writes to full GXPIPE and GXFIFO
Browse files Browse the repository at this point in the history
  • Loading branch information
fleroviux committed Jan 11, 2024
1 parent ba2f779 commit 2eecb0d
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ namespace dual::nds::gpu {
void UnpackNextCommands();

void ProcessCommands();
void ProcessCommandsImpl();
void ExecuteCommand(u8 command);

void cmdMatrixMode();
Expand Down Expand Up @@ -154,6 +155,7 @@ namespace dual::nds::gpu {

FIFO<u64, 4> m_cmd_pipe;
FIFO<u64, 256> m_cmd_fifo;
Scheduler::Event* m_cmd_event{};

// Matrix Engine
int m_mtx_mode{};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ namespace dual::nds::gpu {
m_unpack = {};
m_cmd_pipe.Reset();
m_cmd_fifo.Reset();
m_cmd_event = nullptr;
m_mtx_mode = 0;
m_projection_mtx_index = 0;
m_coordinate_mtx_index = 0;
Expand Down Expand Up @@ -57,8 +58,17 @@ namespace dual::nds::gpu {
if(m_cmd_fifo.IsEmpty() && !m_cmd_pipe.IsFull()) {
m_cmd_pipe.Write(entry);
} else {
/* HACK: before we drop any command or argument data,
* execute the next command early.
* In hardware enqueueing into full queue would stall the CPU or DMA,
* but this is difficult to emulate accurately.
*/
if(m_cmd_fifo.IsFull()) {
ATOM_PANIC("gpu: Attempted to write to full GXFIFO, busy={}", m_gxstat.busy);
m_gxstat.busy = false;
if(m_cmd_event) {
m_scheduler.Cancel(m_cmd_event);
}
ProcessCommandsImpl();
}

m_cmd_fifo.Write(entry);
Expand Down Expand Up @@ -161,7 +171,10 @@ namespace dual::nds::gpu {
m_gxstat.busy = false;
return;
}
ProcessCommandsImpl();
}

void CommandProcessor::ProcessCommandsImpl() {
const u8 command = (u8)(m_cmd_pipe.Peek() >> 32);
const size_t number_of_entries = m_cmd_pipe.Count() + m_cmd_fifo.Count();

Expand All @@ -172,11 +185,14 @@ namespace dual::nds::gpu {

ExecuteCommand(command);

m_gxstat.busy = true;
// @todo: think of a more efficient solution.
m_scheduler.Add(1, [this](int _) {
ProcessCommands();
});
if(!m_swap_buffers_pending) {
// @todo: think of a more efficient solution.
m_gxstat.busy = true;
m_cmd_event = m_scheduler.Add(1, [this](int _) {
m_cmd_event = nullptr;
ProcessCommands();
});
}
}

void CommandProcessor::ExecuteCommand(u8 command) {
Expand Down

0 comments on commit 2eecb0d

Please sign in to comment.