libdragon
|
Video interface system for configuring video output modes and displaying rendered graphics. More...
Modules | |
(Deprecated) Old RDP library | |
Interface to the hardware sprite/triangle rasterizer (RDP). | |
Console Support | |
Software console emulation for debugging and simple text output. | |
2D Graphics | |
Software routines for manipulating graphics in a display context. | |
RDPQ: Hardware-accelerated drawing API | |
Interface to the RDP (graphics hardware) for 2D/3D rasterization. | |
Files | |
file | display.c |
Display Subsystem. | |
file | vi.h |
Video Interface Subsystem. | |
file | display.h |
Display Subsystem. | |
Data Structures | |
struct | vi_config_t |
Video Interface register structure. More... | |
struct | resolution_t |
Video resolution structure. More... | |
Macros | |
#define | VI_REGISTERS_ADDR 0xA4400000 |
Register uncached location in memory of VI. | |
#define | VI_REGISTERS_COUNT 14 |
Number of useful 32-bit registers at the register base. | |
#define | VI_REGISTERS ((volatile uint32_t*)VI_REGISTERS_ADDR) |
Base pointer to hardware Video interface registers that control various aspects of VI configuration. Shouldn't be used by itself, use VI_ registers to get/set their values. | |
#define | VI_CTRL (&VI_REGISTERS[0]) |
VI Index register of controlling general display filters/bitdepth configuration. | |
#define | VI_ORIGIN (&VI_REGISTERS[1]) |
VI Index register of RDRAM base address of the video output Frame Buffer. This can be changed as needed to implement double or triple buffering. | |
#define | VI_WIDTH (&VI_REGISTERS[2]) |
VI Index register of width in pixels of the frame buffer. | |
#define | VI_V_INTR (&VI_REGISTERS[3]) |
VI Index register of vertical interrupt. | |
#define | VI_V_CURRENT (&VI_REGISTERS[4]) |
VI Index register of the current half line, sampled once per line. | |
#define | VI_BURST (&VI_REGISTERS[5]) |
VI Index register of sync/burst values. | |
#define | VI_V_SYNC (&VI_REGISTERS[6]) |
VI Index register of total visible and non-visible lines. This should match either NTSC (non-interlaced: 0x20D, interlaced: 0x20C) or PAL (non-interlaced: 0x271, interlaced: 0x270) | |
#define | VI_H_SYNC (&VI_REGISTERS[7]) |
VI Index register of total width of a line. | |
#define | VI_H_SYNC_LEAP (&VI_REGISTERS[8]) |
VI Index register of an alternate scanline length for one scanline during vsync. | |
#define | VI_H_VIDEO (&VI_REGISTERS[9]) |
VI Index register of start/end of the active video image, in screen pixels. | |
#define | VI_V_VIDEO (&VI_REGISTERS[10]) |
VI Index register of start/end of the active video image, in screen half-lines. | |
#define | VI_V_BURST (&VI_REGISTERS[11]) |
VI Index register of start/end of the color burst enable, in half-lines. | |
#define | VI_X_SCALE (&VI_REGISTERS[12]) |
VI Index register of horizontal subpixel offset and 1/horizontal scale up factor. | |
#define | VI_Y_SCALE (&VI_REGISTERS[13]) |
VI Index register of vertical subpixel offset and 1/vertical scale up factor. | |
#define | VI_TO_REGISTER(index) (((index) >= 0 && (index) <= VI_REGISTERS_COUNT)? &VI_REGISTERS[index] : NULL) |
VI register by index (0-13) | |
#define | VI_TO_INDEX(reg) ((reg) - VI_REGISTERS) |
VI index from register. | |
#define | VI_DEDITHER_FILTER_ENABLE (1<<16) |
VI_CTRL Register setting: enable dedither filter. | |
#define | VI_PIXEL_ADVANCE_DEFAULT (0b0011 << 12) |
VI_CTRL Register setting: default value for pixel advance. | |
#define | VI_PIXEL_ADVANCE_BBPLAYER (0b0001 << 12) |
VI_CTRL Register setting: default value for pixel advance on iQue. | |
#define | VI_AA_MODE_NONE (0b11 << 8) |
VI_CTRL Register setting: disable AA / resamp. | |
#define | VI_AA_MODE_RESAMPLE (0b10 << 8) |
VI_CTRL Register setting: disable AA / enable resamp. | |
#define | VI_AA_MODE_RESAMPLE_FETCH_NEEDED (0b01 << 8) |
VI_CTRL Register setting: enable AA / enable resamp, fetch pixels when needed. | |
#define | VI_AA_MODE_RESAMPLE_FETCH_ALWAYS (0b00 << 8) |
VI_CTRL Register setting: enable AA / enable resamp, fetch pixels always. | |
#define | VI_CTRL_SERRATE (1<<6) |
VI_CTRL Register setting: enable interlaced output. | |
#define | VI_DIVOT_ENABLE (1<<4) |
VI_CTRL Register setting: enable divot filter (fixes 1 pixel holes after AA). | |
#define | VI_GAMMA_ENABLE (1<<3) |
VI_CTRL Register setting: enable gamma correction filter. | |
#define | VI_GAMMA_DITHER_ENABLE (1<<2) |
VI_CTRL Register setting: enable gamma correction filter and hardware dither the least significant color bit on output. | |
#define | VI_CTRL_TYPE (0b11) |
VI_CTRL Register setting: framebuffer source format. | |
#define | VI_CTRL_TYPE_32_BPP (0b11) |
VI_CTRL Register setting: set the framebuffer source as 32-bit. | |
#define | VI_CTRL_TYPE_16_BPP (0b10) |
VI_CTRL Register setting: set the framebuffer source as 16-bit (5-5-5-3). | |
#define | VI_CTRL_TYPE_BLANK (0b00) |
VI_CTRL Register setting: set the framebuffer source as blank (no data and no sync, TV screens will either show static or nothing). | |
#define | VI_ORIGIN_SET(value) ((value & 0xFFFFFF) << 0) |
VI_ORIGIN Register: set the address of a framebuffer. | |
#define | VI_WIDTH_SET(value) ((value & 0xFFF) << 0) |
VI_ORIGIN Register: set the width of a framebuffer. | |
#define | VI_V_CURRENT_VBLANK 2 |
VI_V_CURRENT Register: default value for vblank begin line. | |
#define | VI_V_INTR_SET(value) ((value & 0x3FF) << 0) |
VI_V_INTR Register: set value for vertical interrupt. | |
#define | VI_V_INTR_DEFAULT 0x3FF |
VI_V_INTR Register: default value for vertical interrupt. | |
#define | VI_BURST_START(value) ((value & 0x3F) << 20) |
VI_BURST Register: set start of color burst in pixels from hsync. | |
#define | VI_VSYNC_WIDTH(value) ((value & 0x7) << 16) |
VI_BURST Register: set vertical sync width in half lines. | |
#define | VI_BURST_WIDTH(value) ((value & 0xFF) << 8) |
VI_BURST Register: set color burst width in pixels. | |
#define | VI_HSYNC_WIDTH(value) ((value & 0xFF) << 0) |
VI_BURST Register: set horizontal sync width in pixels. | |
#define | VI_BURST_START_NTSC 62 |
VI_BURST Register: NTSC default start of color burst in pixels from hsync. | |
#define | VI_VSYNC_WIDTH_NTSC 5 |
VI_BURST Register: NTSC default vertical sync width in half lines. | |
#define | VI_BURST_WIDTH_NTSC 34 |
VI_BURST Register: NTSC default color burst width in pixels. | |
#define | VI_HSYNC_WIDTH_NTSC 57 |
VI_BURST Register: NTSC default horizontal sync width in pixels. | |
#define | VI_BURST_START_PAL 64 |
VI_BURST Register: PAL default start of color burst in pixels from hsync. | |
#define | VI_VSYNC_WIDTH_PAL 4 |
VI_BURST Register: PAL default vertical sync width in half lines. | |
#define | VI_BURST_WIDTH_PAL 35 |
VI_BURST Register: PAL default color burst width in pixels. | |
#define | VI_HSYNC_WIDTH_PAL 58 |
VI_BURST Register: PAL default horizontal sync width in pixels. | |
#define | VI_X_SCALE_SET(value) (( 1024*(value) + 320 ) / 640) |
VI_X_SCALE Register: set 1/horizontal scale up factor (value is converted to 2.10 format) | |
#define | VI_Y_SCALE_SET(value) (( 1024*(value) + 120 ) / 240) |
VI_Y_SCALE Register: set 1/vertical scale up factor (value is converted to 2.10 format) | |
Typedefs | |
typedef surface_t * | display_context_t |
Display context (DEPRECATED: Use surface_t instead) | |
Enumerations | |
enum | bitdepth_t { DEPTH_16_BPP , DEPTH_32_BPP } |
Valid bit depths. More... | |
enum | gamma_t { GAMMA_NONE , GAMMA_CORRECT , GAMMA_CORRECT_DITHER } |
Valid gamma correction settings. More... | |
enum | filter_options_t { FILTERS_DISABLED , FILTERS_RESAMPLE , FILTERS_DEDITHER , FILTERS_RESAMPLE_ANTIALIAS , FILTERS_RESAMPLE_ANTIALIAS_DEDITHER } |
Valid display filter options. More... | |
Functions | |
void | vi_write_safe (volatile uint32_t *reg, uint32_t value) |
Write a set of video registers to the VI. | |
void | vi_write_config (const vi_config_t *config) |
Write a set of video registers to the VI. | |
void | display_init (resolution_t res, bitdepth_t bit, uint32_t num_buffers, gamma_t gamma, filter_options_t filters) |
Initialize the display to a particular resolution and bit depth. | |
void | display_close () |
Close the display. | |
surface_t * | display_get (void) |
Get a display buffer for rendering. | |
surface_t * | display_try_get (void) |
Try getting a display surface. | |
void | display_show (surface_t *surf) |
Display a buffer on the screen. | |
uint32_t | display_get_width (void) |
Get the currently configured width of the display in pixels. | |
uint32_t | display_get_height (void) |
Get the currently configured height of the display in pixels. | |
uint32_t | display_get_bitdepth (void) |
Get the currently configured bitdepth of the display (in bytes per pixels) | |
uint32_t | display_get_num_buffers (void) |
Get the currently configured number of buffers. | |
float | display_get_fps (void) |
Get the current number of frames per second being rendered. | |
Variables | |
const resolution_t | RESOLUTION_256x240 = {256, 240, false} |
256x240 mode | |
const resolution_t | RESOLUTION_320x240 = {320, 240, false} |
320x240 mode | |
const resolution_t | RESOLUTION_512x240 = {512, 240, false} |
512x240 mode, high-res progressive | |
const resolution_t | RESOLUTION_640x240 = {640, 240, false} |
640x240 mode, high-res progressive | |
const resolution_t | RESOLUTION_512x480 = {512, 480, true} |
512x480 mode, interlaced | |
const resolution_t | RESOLUTION_640x480 = {640, 480, true} |
640x480 mode, interlaced | |
Video interface system for configuring video output modes and displaying rendered graphics.
The display subsystem handles interfacing with the video interface (VI) and the hardware rasterizer (RDP) to allow software and hardware graphics operations. It consists of the Display Subsystem, the 2D Graphics and the (Deprecated) Old RDP library modules. A separate module, the Console Support, provides a rudimentary console for developers. Only the display subsystem or the console can be used at the same time. However, commands to draw console text to the display subsystem are available.
The display subsystem module is responsible for initializing the proper video mode for displaying 2D, 3D and software graphics. To set up video on the N64, code should call display_init with the appropriate options. Once the display has been set, a surface can be requested from the display subsystem using display_get. To draw to the acquired surface, code should use functions present in the 2D Graphics and the (Deprecated) Old RDP library modules. Once drawing to a surface is complete, the rendered graphic can be displayed to the screen using display_show. Once code has finished rendering all graphics, display_close can be used to shut down the display subsystem.
struct vi_config_t |
Video Interface register structure.
Whenever trying to configure VI registers, this struct and its index definitions below can be very useful in writing comprehensive and verbose code.
Data Fields | ||
---|---|---|
uint32_t | regs[VI_REGISTERS_COUNT] |
struct resolution_t |
Video resolution structure.
You can either use one of the pre-defined constants (such as RESOLUTION_320x240) or define a custom resolution.
Data Fields | ||
---|---|---|
int32_t | width | Screen width (must be between 2 and 800) |
int32_t | height | Screen height (must be between 1 and 720) |
bool | interlaced | True if interlaced mode enabled. |
#define VI_DEDITHER_FILTER_ENABLE (1<<16) |
VI_CTRL Register setting: enable dedither filter.
Under VI_CTRL
#define VI_ORIGIN_SET | ( | value | ) | ((value & 0xFFFFFF) << 0) |
VI_ORIGIN Register: set the address of a framebuffer.
Under VI_ORIGIN
#define VI_WIDTH_SET | ( | value | ) | ((value & 0xFFF) << 0) |
VI_ORIGIN Register: set the width of a framebuffer.
Under VI_WIDTH
#define VI_V_CURRENT_VBLANK 2 |
VI_V_CURRENT Register: default value for vblank begin line.
Under VI_V_CURRENT
#define VI_V_INTR_SET | ( | value | ) | ((value & 0x3FF) << 0) |
VI_V_INTR Register: set value for vertical interrupt.
Under VI_V_INTR
#define VI_BURST_START | ( | value | ) | ((value & 0x3F) << 20) |
VI_BURST Register: set start of color burst in pixels from hsync.
Under VI_BURST
#define VI_X_SCALE_SET | ( | value | ) | (( 1024*(value) + 320 ) / 640) |
VI_X_SCALE Register: set 1/horizontal scale up factor (value is converted to 2.10 format)
Under VI_X_SCALE
#define VI_Y_SCALE_SET | ( | value | ) | (( 1024*(value) + 120 ) / 240) |
VI_Y_SCALE Register: set 1/vertical scale up factor (value is converted to 2.10 format)
Under VI_Y_SCALE
typedef surface_t* display_context_t |
enum bitdepth_t |
enum gamma_t |
Valid gamma correction settings.
enum filter_options_t |
Valid display filter options.
Libdragon uses preconfigured options for enabling certain combinations of Video Interface filters due to a large number of wrong/invalid configurations with very strict conditions, and to simplify the options for the user.
Like for example antialiasing requiring resampling; dedithering not working with resampling, unless always fetching; always enabling divot filter under AA etc.
The options below provide all possible configurations that are deemed useful in development.
Enumerator | |
---|---|
FILTERS_DISABLED | All display filters are disabled. |
FILTERS_RESAMPLE | Resize the output image with a bilinear filter. In general, VI is in charge of resizing the framebuffer to fit the TV resolution (which is always NTSC 640x480 or PAL 640x512). This option enables a bilinear interpolation that can be used during this resize. |
FILTERS_DEDITHER | Reconstruct a 32-bit output from dithered 16-bit framebuffer. |
FILTERS_RESAMPLE_ANTIALIAS | Resize the output image with a bilinear filter (see FILTERS_RESAMPLE). Add a video interface anti-aliasing pass with a divot filter. To be able to see correct anti-aliased output, this display filter must be enabled, along with anti-aliased rendering of surfaces. |
FILTERS_RESAMPLE_ANTIALIAS_DEDITHER | Resize the output image with a bilinear filter (see FILTERS_RESAMPLE). Add a video interface anti-aliasing pass with a divot filter (see FILTERS_RESAMPLE_ANTIALIAS). Reconstruct a 32-bit output from dithered 16-bit framebuffer. |
|
inline |
Write a set of video registers to the VI.
[in] | reg | A pointer to a register to be written |
[in] | value | Value to be written to the register |
|
inline |
Write a set of video registers to the VI.
[in] | config | A pointer to a set of register values to be written |
void display_init | ( | resolution_t | res, |
bitdepth_t | bit, | ||
uint32_t | num_buffers, | ||
gamma_t | gamma, | ||
filter_options_t | filters | ||
) |
Initialize the display to a particular resolution and bit depth.
Initialize video system. This sets up a double, triple, or multiple buffered drawing surface which can be blitted or rendered to using software or hardware.
[in] | res | The requested resolution. Use either one of the pre-defined resolution (such as RESOLUTION_320x240) or define a custom one. |
[in] | bit | The requested bit depth (DEPTH_16_BPP or DEPTH_32_BPP) |
[in] | num_buffers | Number of buffers, usually 2 or 3, but can be more. Triple buffering is recommended in case the application cannot hold a steady full framerate, so that slowdowns don't impact too much. |
[in] | gamma | The requested gamma setting |
[in] | filters | The requested display filtering options, see filter_options_t |
void display_close | ( | ) |
Close the display.
Close a display and free buffer memory associated with it.
surface_t * display_get | ( | void | ) |
Get a display buffer for rendering.
Grab a surface that is safe for drawing, spin-waiting until one is available.
When you are done drawing on the buffer, use display_show to schedule the buffer to be displayed on the screen during next vblank.
It is possible to get more than a display buffer at the same time, for instance to begin working on a new frame while the previous one is still being rendered in parallel through RDP. It is important to notice that surfaces will always be shown on the screen in the order they were gotten, irrespective of the order display_show is called.
surface_t * display_try_get | ( | void | ) |
Try getting a display surface.
This is similar to display_get, but it does not block if no display is available and return NULL instead.
void display_show | ( | surface_t * | surf | ) |
Display a buffer on the screen.
Display a surface to the screen on the next vblank.
Notice that this function does not accept any arbitrary surface, but only those returned by display_get, which are owned by the display module.
[in] | surf | A surface to show (previously retrieved using display_get) |
float display_get_fps | ( | void | ) |
Get the current number of frames per second being rendered.