devkitPro/citro3d

Using GX / GXQueue functions while using Citro3D

DiscostewSM opened this issue · 2 comments

Perhaps this is more of a question than anything, but how would one go about using non-Citro3D GX functions while Citro3D is in use? I'm looking through the code of both ctrulib and Citro3D, and it's confusing me. On initialization, Citro3D binds a queue for its renderqueue and then runs it. In one sense it has nothing to run, but it does make the queue active. This led me to think that I could just add my commands because with the queue being active, it'll run them as I add them and all would be good. But then I began looking at the Safe functions and the onQueueFinish callback with regard to GX commands within a frame (that is, between FrameBegin and FrameEnd, which has the InFrame variable set).

They begin by waiting and clearing the queue (which stops the queue and makes it inactive, which is fine because they start them up again after the specific command is added), set the InSafeTransfer variable, add the command, then runs them. But, with how the callback is designed, the completion of the queue would cause it to become inactive, meaning later non-Citro3D GX commands would not run automatically. From my understanding, this is due to the queue being stopped in the callback (because both InSafeTransfer and InFrame are set as true in this case), and with no access to the bound queue to execute the gxCmdQueueRun function manually, the execution of these non-Citro3D GX commands would have to wait until Citro3D runs it itself. This creates another problem if another Safe call was made, if my understanding of the code is correct. If another call to a Safe function is done while non-Citro3D GX commands were added to the queue and the queue is not active, it would basically toss those commands out (via clearing the queue) to prep itself for the Safe command.

It seems like if I am wanting to use non-Citro3D GX functions within a frame, then I can't use the Safe functions whatsoever within the frame too unless they were at the very end. Or, maybe I'm just not understanding how the queue works, or how Citro3D utilizes it.

fincs commented

You are correct. The current C3D_Safe* functions break completely when used inside a frame. I have known about this for some time, and my (private) development branch deprecated the C3D_Safe* functions in favour of a new set of functions (C3D_Sync*) that correctly work regardless of being within a frame or not, and also additionally wait for the operation to complete in case they are called outside a frame (no more gspWaitForWhatever).

If you are interested in working with my development branch, you can hit me up with an IRC PM (on Blitzed.org, EFnet or Freenode). My IRC name is fincs on all three.

fincs commented

Fixed with v1.4.0.