Nugget
Classes | Public Types | Public Member Functions | Static Public Member Functions | Static Public Attributes | Friends | List of all members
psyqo::GPU Class Reference

The singleton GPU class. More...

#include <gpu.hh>

Classes

struct  Configuration
 

Public Types

enum class  Resolution {
  W256 , W320 , W368 , W512 ,
  W640
}
 
enum class  VideoMode { AUTO , NTSC , PAL }
 
enum class  ColorMode { C15BITS , C24BITS }
 
enum class  Interlace { PROGRESSIVE , INTERLACED }
 

Public Member Functions

void initialize (const Configuration &config)
 
unsigned getRefreshRate () const
 Returns the refresh rate of the GPU. More...
 
uint32_t getFrameCount () const
 Returns the number of frames rendered by the GPU so far. More...
 
void clear (Color bg={{0, 0, 0}})
 Immediately clears the drawing buffer. More...
 
void getClear (Prim::FastFill &ff, Color bg={{0, 0, 0}}) const
 Sets a FastFill primitive to clear the current drawing buffer. More...
 
void getNextClear (Prim::FastFill &ff, Color bg={{0, 0, 0}}) const
 Sets a FastFill primitive to clear the next drawing buffer. More...
 
void uploadToVRAM (const uint16_t *data, Rect region)
 Uploads a buffer to the VRAM as a blocking call. More...
 
void uploadToVRAM (const uint16_t *data, Rect region, eastl::function< void()> &&callback, DMA::DmaCallback dmaCallback=DMA::FROM_MAIN_LOOP)
 Uploads a buffer to the VRAM as a non-blocking call. More...
 
template<typename Fragment >
void sendFragment (const Fragment &fragment)
 Immediately sends a fragment to the GPU. This is a blocking operation. See the fragments.hh file for more information. More...
 
template<typename Fragment >
void sendFragment (const Fragment &fragment, eastl::function< void()> &&callback, DMA::DmaCallback dmaCallback=DMA::FROM_MAIN_LOOP)
 Sends a fragment to the GPU as a non-blocking call. More...
 
void disableScissor ()
 Immediately disables the scissoring of the VRAM.
 
void enableScissor ()
 Enables the scissoring of the VRAM. More...
 
void getScissor (Prim::Scissor &scissor)
 Gets the current scissoring region. More...
 
void getNextScissor (Prim::Scissor &scissor)
 Gets the next scissoring region. More...
 
template<typename Fragment >
void chain (Fragment &fragment)
 Chains a fragment to the next DMA chain transfer. More...
 
void sendChain ()
 Immediately sends the current DMA chain. More...
 
void sendChain (eastl::function< void()> &&callback, DMA::DmaCallback dmaCallback=DMA::FROM_MAIN_LOOP)
 Initiates the transfer of the current DMA chain. More...
 
bool isChainIdle () const
 Gets the status of the background DMA transfer operation when initiated by a frame flip. More...
 
bool isChainTransferring () const
 Gets the status of the background DMA transfer operation when initiated by a frame flip. More...
 
bool isChainTransferred () const
 Gets the status of the background DMA transfer operation when initiated by a frame flip. More...
 
uint32_t now () const
 Gets the current timestamp in microseconds. More...
 
uintptr_t armTimer (uint32_t deadline, eastl::function< void(uint32_t)> &&callback)
 Creates a single-use timer. More...
 
unsigned armPeriodicTimer (uint32_t period, eastl::function< void(uint32_t)> &&callback)
 Creates a periodic timer. More...
 
void changeTimerPeriod (uintptr_t id, uint32_t period, bool reset=false)
 Changes the period of a periodic timer. More...
 
void pauseTimer (uintptr_t id)
 Pauses a timer. More...
 
void resumeTimer (uintptr_t id)
 Resumes a paused timer. More...
 
void cancelTimer (uintptr_t id)
 Cancels a timer. More...
 
void pumpCallbacks ()
 Runs one round of event processing. More...
 

Static Public Member Functions

static void waitReady ()
 Waits until the GPU is ready to send a command.
 
static void sendRaw (uint32_t data)
 Sends a raw 32 bits value to the GP0 register of the GPU.
 
template<typename Primitive >
static void sendPrimitive (const Primitive &primitive)
 Sends a primitive to the GPU. This is a blocking call. More...
 

Static Public Attributes

static constexpr uint32_t US_PER_HBLANK = 64
 

Friends

class Application
 

Detailed Description

The singleton GPU class.

This class shouldn't be instantiated directly. It is a singleton instantiated within the Application class, and accessed using the gpu method. It contains the current state of the psyqo renderer, and provides various helpers for rendering.

Member Function Documentation

◆ armPeriodicTimer()

uintptr_t psyqo::GPU::armPeriodicTimer ( uint32_t  period,
eastl::function< void(uint32_t)> &&  callback 
)

Creates a periodic timer.

This method will create a periodic timer. The timer will fire every period microseconds. See the armTimer method for more information about timers in general. Periodic timers will first fire at now() + period microseconds, and then every period microseconds thereafter. They will never be canceled automatically.

Parameters
periodThe period of the timer in microseconds.
callbackThe callback function to be called when the timer expires.
Returns
The id of the created timer.

◆ armTimer()

uintptr_t psyqo::GPU::armTimer ( uint32_t  deadline,
eastl::function< void(uint32_t)> &&  callback 
)

Creates a single-use timer.

This method will create a single-use timer. The timer will fire after the specified deadline has passed. Timers will only fire during the idle period of the CPU, between calls to the frame method of the current scene. If the scene takes too long to complete, timers may significantly be delayed past their set deadline. The deadline can be computed based on the return value of the now() method. It is okay if the deadline rolls over their 32 bits span. Simply doing gpu().now() + DELAY_IN_MICROSECONDS will still work, as long as the delay isn't greater than 30 minutes. Single-use timers will automatically be disabled upon being fired, and their id will no longer be valid. The returned id is guaranteed to be unique across active timers, but may collision with the id of timers that got canceled or got disabled on their own.

Parameters
deadlineThe deadline of the timer in microseconds.
callbackThe callback function to be called when the timer expires.
Returns
The id of the created timer.

◆ cancelTimer()

void psyqo::GPU::cancelTimer ( uintptr_t  id)

Cancels a timer.

This method will cancel an active timer. The timer will no longer fire. Its id will no longer be valid.

Parameters
idThe id of the timer to cancel.

◆ chain()

template<typename Fragment >
void psyqo::GPU::chain ( Fragment &  fragment)
inline

Chains a fragment to the next DMA chain transfer.

This method will chain a fragment to the next DMA chain transfer. DMA Chaining is a complex operation, and it is recommended that you use the sendFragment method instead if you are unsure. This can be used while a DMA chain is being sent. Use the sendChain method to transfer the DMA chain during the current frame, or simply return from the current scene's frame method to transfer the DMA chain automatically during the frame flip operation. Note that the latter means the DMA chain will render on the next rendered frame, thus creating a sort of triple buffering system. The constructed DMA chain will thus need to be using the Next variants of the primitive constructors, if applicable.

Parameters
fragmentThe fragment to chain.

◆ changeTimerPeriod()

void psyqo::GPU::changeTimerPeriod ( uintptr_t  id,
uint32_t  period,
bool  reset = false 
)

Changes the period of a periodic timer.

This method will change the period of a periodic timer. The timer now will fire every period microseconds instead of its previous period. When the reset argument is false, the next deadline for the timer will be adjusted according to the difference between the new period and the previous one. If the new period is shorter, and the deadline goes in the past, the timer will fire as soon as possible. When the reset argument is true, the new deadline will simply be set to the new period. This method has no effect if the timer is not periodic.

Parameters
idThe id of the timer to change.
periodThe new period of the timer.
resetThe timer's deadline will be adjusted to the new period if false.

◆ clear()

void psyqo::GPU::clear ( Color  bg = {{0, 0, 0}})

Immediately clears the drawing buffer.

This method will immediately clear the drawing buffer with the specified color.

Parameters
bgThe color to fill the drawing buffer with.

◆ enableScissor()

void psyqo::GPU::enableScissor ( )

Enables the scissoring of the VRAM.

This method will enable the scissoring of the VRAM, and will clip the drawing to the currently active buffer.

◆ getClear()

void psyqo::GPU::getClear ( Prim::FastFill ff,
Color  bg = {{0, 0, 0}} 
) const

Sets a FastFill primitive to clear the current drawing buffer.

This method will set the FastFill primitive passed as an argument in a way to completely clear the current drawing buffer with the specified color. This will be done in accordance to the current drawing buffer settings.

Parameters
ffThe FastFill primitive to set.
endThe color to issue.

◆ getFrameCount()

uint32_t psyqo::GPU::getFrameCount ( ) const
inline

Returns the number of frames rendered by the GPU so far.

This returns the internal frame counter being kept by the GPU class. The 32 bits value will wrap around when it reaches 2^32 frames, which is 2 years, 3 months, 7 days, 6 hours, 6 minutes and 28.27 seconds when running constantly at a 60Hz refresh rate.

◆ getNextClear()

void psyqo::GPU::getNextClear ( Prim::FastFill ff,
Color  bg = {{0, 0, 0}} 
) const

Sets a FastFill primitive to clear the next drawing buffer.

This method will set the FastFill primitive passed as an argument in a way to completely clear the next drawing buffer with the specified color. This will be done in accordance to the next drawing buffer settings, after a flip. This is useful for clearing the buffer within a dma chain to be sent during the frame flip.

Parameters
ffThe FastFill primitive to set.
endThe color to issue.

◆ getNextScissor()

void psyqo::GPU::getNextScissor ( Prim::Scissor scissor)

Gets the next scissoring region.

This method will set the scissor primitive to the next active drawing buffer. This is useful for setting the scissor within a dma chain to be sent during the frame flip.

Parameters
scissorThe scissor primitive to set.

◆ getRefreshRate()

unsigned psyqo::GPU::getRefreshRate ( ) const
inline

Returns the refresh rate of the GPU.

This method will return either 60 or 50, depending on the current video mode.

◆ getScissor()

void psyqo::GPU::getScissor ( Prim::Scissor scissor)

Gets the current scissoring region.

This method will set the scissor primitive to the currently active drawing buffer.

Parameters
scissorThe scissor primitive to set.

◆ isChainIdle()

bool psyqo::GPU::isChainIdle ( ) const

Gets the status of the background DMA transfer operation when initiated by a frame flip.

Returns
true if no background DMA transfer is in progress nor completed.

◆ isChainTransferred()

bool psyqo::GPU::isChainTransferred ( ) const

Gets the status of the background DMA transfer operation when initiated by a frame flip.

Returns
true if a background DMA transfer has completed, and is now waiting for a frame flip.

◆ isChainTransferring()

bool psyqo::GPU::isChainTransferring ( ) const

Gets the status of the background DMA transfer operation when initiated by a frame flip.

Returns
true if a background DMA transfer is in progress.

◆ now()

uint32_t psyqo::GPU::now ( ) const
inline

Gets the current timestamp in microseconds.

The current timestamp is in microseconds. It will wrap around after a bit more than an hour, so it shouldn't be used for deadlines that are more than 30 minutes away. This relies on root counter 1 set in hsync mode without any target value. The value will be updated during the idle moments of the page flip, without relying on interrupts. The precision isn't really good, as it assumes one scanline runs at 64ms, but it should be good enough for most purposes. Creating a stopwatch out of it should show that it's running a bit too fast, approximately 1 second too fast every minute or so. Its monotonicity should be proper however.

The method now() should be reserved for interacting with timers. If longer span is required, with more accuracy but less precision, for something that's not related with timers, then the current amount of time in seconds since the application started can simply be obtained using getFrameCount() / getRefreshRate().

Returns
The current timestamp in microseconds.

◆ pauseTimer()

void psyqo::GPU::pauseTimer ( uintptr_t  id)

Pauses a timer.

This method will pause a timer. It will not fire anymore, even if its deadline had already passed at the moment of this call, but it will remain active, and its id will remain valid. The remainder of the deadline will be remembered, for when the timer is resumed. This method has no effect if the timer is already paused.

Parameters
idThe id of the timer to pause.

◆ pumpCallbacks()

void psyqo::GPU::pumpCallbacks ( )

Runs one round of event processing.

While this method is technically for internal use, it is exposed here for convenience. It will run one round of event processing, including the processing of timers. This method should be called in a loop when waiting for other events to be processed.

◆ resumeTimer()

void psyqo::GPU::resumeTimer ( uintptr_t  id)

Resumes a paused timer.

This method will resume a paused timer. The timer will be able to fire again, according to its original settings. The new deadline will be calculated from the remainder of the time left when it was paused. This method will have no effect if the timer is not paused.

Parameters
idThe id of the timer to resume.

◆ sendChain() [1/2]

void psyqo::GPU::sendChain ( )

Immediately sends the current DMA chain.

This method will immediately send the current DMA chain to the GPU, and block until completion.

◆ sendChain() [2/2]

void psyqo::GPU::sendChain ( eastl::function< void()> &&  callback,
DMA::DmaCallback  dmaCallback = DMA::FROM_MAIN_LOOP 
)

Initiates the transfer of the current DMA chain.

See the non-blocking variant of uploadToVRAM for more information about asynchronous transfers.

Parameters
callbackThe callback to call upon completion.
dmaCallbackDMA::FROM_MAIN_LOOP or DMA::FROM_ISR.

◆ sendFragment() [1/2]

template<typename Fragment >
void psyqo::GPU::sendFragment ( const Fragment &  fragment)
inline

Immediately sends a fragment to the GPU. This is a blocking operation. See the fragments.hh file for more information.

Parameters
fragmentThe fragment to send to the GPU.

◆ sendFragment() [2/2]

template<typename Fragment >
void psyqo::GPU::sendFragment ( const Fragment &  fragment,
eastl::function< void()> &&  callback,
DMA::DmaCallback  dmaCallback = DMA::FROM_MAIN_LOOP 
)
inline

Sends a fragment to the GPU as a non-blocking call.

See the non-blocking variant of uploadToVRAM for more information about asynchronous transfers.

Parameters
fragmentThe fragment to send to the GPU.
callbackThe callback to call upon completion.
dmaCallbackDMA::FROM_MAIN_LOOP or DMA::FROM_ISR.

◆ sendPrimitive()

template<typename Primitive >
static void psyqo::GPU::sendPrimitive ( const Primitive &  primitive)
inlinestatic

Sends a primitive to the GPU. This is a blocking call.

This method will immediately send the specified primitive to the GPU.

Parameters
primitiveThe primitive to send to the GPU.

◆ uploadToVRAM() [1/2]

void psyqo::GPU::uploadToVRAM ( const uint16_t *  data,
Rect  region 
)

Uploads a buffer to the VRAM as a blocking call.

This method will immediately upload the specified set of pixels to the VRAM, at the specified location and size. The GPU cache will be flushed. It will block until completion of the upload.

Parameters
dataThe pixels to upload. Must be a contiguous array of 16-bpp pixels, with the number of pixels being equal to the area specified by the region parameter.
regionThe region in VRAM to upload the pixels to.

◆ uploadToVRAM() [2/2]

void psyqo::GPU::uploadToVRAM ( const uint16_t *  data,
Rect  region,
eastl::function< void()> &&  callback,
DMA::DmaCallback  dmaCallback = DMA::FROM_MAIN_LOOP 
)

Uploads a buffer to the VRAM as a non-blocking call.

This method will initiate an upload of the specified set of pixels to the VRAM, at the specified location and size. The GPU cache will be flushed. It will return immediately, and the upload will be performed in the background. Upon completion, the specified callback will be called. If dmaCallback is set to FROM_ISR, the callback will be called from the interrupt handler, and care must be taken to properly synchronize variable changes. Please use the EASTL's atomic_signal_fence function for this purpose. If dmaCallback is set to FROM_MAIN_LOOP, the callback will be called in the same execution context as the main loop, and it is therefore safe to access variables there. The callback will thus be called between calls to the current scene's frame method, or during Kernel::pumpCallbacks(). Note that during the upload, no GPU operation should be performed.

Parameters
dataThe pixels to upload. Must be a contiguous array of 16-bpp pixels, with the number of pixels being equal to the area specified by the region parameter.
regionThe region in VRAM to upload the pixels to.
callbackThe callback to call upon completion.
dmaCallbackDMA::FROM_MAIN_LOOP or DMA::FROM_ISR.

The documentation for this class was generated from the following files: