![]() |
libdragon
|
RDP command macros. More...
Go to the source code of this file.
Macros | |
#define | RDPQ_COMB0_MASK ((cast64(0xF)<<52)|(cast64(0x1F)<<47)|(cast64(0x7)<<44)|(cast64(0x7)<<41)|(cast64(0xF)<<28)|(cast64(0x7)<<15)|(cast64(0x7)<<12)|(cast64(0x7)<<9)) |
Combiner: mask to isolate settings related to cycle 0. | |
#define | RDPQ_COMB1_MASK (~RDPQ_COMB0_MASK & cast64(0x00FFFFFFFFFFFFFF)) |
Combiner: mask to isolate settings related to cycle 1. | |
#define | RDPQ_COMBINER_2PASS (cast64(1)<<63) |
Flag to mark the combiner as requiring two passes. More... | |
#define | RDPQ_COMBINER1(rgb, alpha) |
Build a 1-pass combiner formula. More... | |
#define | RDPQ_COMBINER2(rgb0, alpha0, rgb1, alpha1) |
Build a 2-pass combiner formula. More... | |
#define | RDPQ_BLENDER(bl) |
Build a 1-pass blender formula. More... | |
#define | RDPQ_BLENDER2(bl0, bl1) |
Build a 2-pass blender formula. More... | |
Standard color combiners | |
These macros offer some standard color combiner configuration that can be used to implement common render modes. | |
#define | RDPQ_COMBINER_FLAT RDPQ_COMBINER1((0,0,0,PRIM), (0,0,0,PRIM)) |
Draw a flat color. Configure the color via rdpq_set_prim_color. | |
#define | RDPQ_COMBINER_SHADE RDPQ_COMBINER1((0,0,0,SHADE), (0,0,0,SHADE)) |
Draw an interpolated color. This can be used for solid, non-textured triangles with per-vertex lighting (gouraud shading). The colors must be specified on each vertex. Only triangles allow to specify a per-vertex color, so you cannot draw rectangles with this. | |
#define | RDPQ_COMBINER_TEX RDPQ_COMBINER1((0,0,0,TEX0), (0,0,0,TEX0)) |
Draw with a texture. This is standard texture mapping, without any lights. It can be used for rectangles (rdpq_texture_rectangle) or triangles (rdpq_triangle). | |
#define | RDPQ_COMBINER_TEX_FLAT RDPQ_COMBINER1((TEX0,0,PRIM,0), (TEX0,0,PRIM,0)) |
Draw with a texture modulated with a flat color. Configure the color via rdpq_set_prim_color. More... | |
#define | RDPQ_COMBINER_TEX_SHADE RDPQ_COMBINER1((TEX0,0,SHADE,0), (TEX0,0,SHADE,0)) |
Draw with a texture modulated with an interpolated color. This does texturing with gouraud shading, and can be used for textured triangles with per-vertex lighting. More... | |
SET_OTHER_MODES bit macros | |
These macros can be used to assemble a raw rdpq stores some special flag within unused bits of this register. These flags are defined using the prefix | |
#define | SOMX_NUMLODS_MASK ((cast64(7))<<59) |
Rdpq extension: number of LODs. | |
#define | SOMX_NUMLODS_SHIFT 59 |
Rdpq extension: number of LODs shift. | |
#define | SOM_ATOMIC_PRIM ((cast64(1))<<55) |
Atomic: serialize command execution. | |
#define | SOM_CYCLE_1 ((cast64(0))<<52) |
Set cycle-type: 1cyc. | |
#define | SOM_CYCLE_2 ((cast64(1))<<52) |
Set cycle-type: 2cyc. | |
#define | SOM_CYCLE_COPY ((cast64(2))<<52) |
Set cycle-type: copy. | |
#define | SOM_CYCLE_FILL ((cast64(3))<<52) |
Set cycle-type: fill. | |
#define | SOM_CYCLE_MASK ((cast64(3))<<52) |
Cycle-type mask. | |
#define | SOM_CYCLE_SHIFT 52 |
Cycle-type shift. | |
#define | SOM_TEXTURE_PERSP (cast64(1)<<51) |
Texture: enable perspective correction. | |
#define | SOM_TEXTURE_DETAIL (cast64(1)<<50) |
Texture: enable "detail". | |
#define | SOM_TEXTURE_SHARPEN (cast64(1)<<49) |
Texture: enable "sharpen". | |
#define | SOM_TEXTURE_LOD (cast64(1)<<48) |
Texture: enable LODs. | |
#define | SOM_TEXTURE_LOD_SHIFT 48 |
Texture: LODs shift. | |
#define | SOM_TLUT_NONE (cast64(0)<<46) |
TLUT: no palettes. | |
#define | SOM_TLUT_RGBA16 (cast64(2)<<46) |
TLUT: draw with palettes in format RGB16. | |
#define | SOM_TLUT_IA16 (cast64(3)<<46) |
TLUT: draw with palettes in format IA16. | |
#define | SOM_TLUT_MASK (cast64(3)<<46) |
TLUT mask. | |
#define | SOM_TLUT_SHIFT 46 |
TLUT mask shift. | |
#define | SOM_SAMPLE_POINT (cast64(0)<<44) |
Texture sampling: point sampling (1x1) | |
#define | SOM_SAMPLE_BILINEAR (cast64(2)<<44) |
Texture sampling: bilinear interpolation (2x2) | |
#define | SOM_SAMPLE_MEDIAN (cast64(3)<<44) |
Texture sampling: mid-texel average (2x2) | |
#define | SOM_SAMPLE_MASK (cast64(3)<<44) |
Texture sampling mask. | |
#define | SOM_SAMPLE_SHIFT 44 |
Texture sampling mask shift. | |
#define | SOM_TF0_RGB (cast64(1)<<43) |
Texture Filter, cycle 0 (TEX0): standard fetching (for RGB) | |
#define | SOM_TF0_YUV (cast64(0)<<43) |
Texture Filter, cycle 0 (TEX0): fetch nearest and do first step of color conversion (for YUV) | |
#define | SOM_TF1_RGB (cast64(2)<<41) |
Texture Filter, cycle 1 (TEX1): standard fetching (for RGB) | |
#define | SOM_TF1_YUV (cast64(0)<<41) |
Texture Filter, cycle 1 (TEX1): fetch nearest and do first step of color conversion (for YUV) | |
#define | SOM_TF1_YUVTEX0 (cast64(1)<<41) |
Texture Filter, cycle 1 (TEX1): don't fetch, and instead do color conversion on TEX0 (allows YUV with bilinear filtering) | |
#define | SOM_TF_MASK (cast64(7)<<41) |
Texture Filter mask. | |
#define | SOM_TF_SHIFT 41 |
Texture filter mask shift. | |
#define | SOM_RGBDITHER_SQUARE ((cast64(0))<<38) |
RGB Dithering: square filter. | |
#define | SOM_RGBDITHER_BAYER ((cast64(1))<<38) |
RGB Dithering: bayer filter. | |
#define | SOM_RGBDITHER_NOISE ((cast64(2))<<38) |
RGB Dithering: noise. | |
#define | SOM_RGBDITHER_NONE ((cast64(3))<<38) |
RGB Dithering: none. | |
#define | SOM_RGBDITHER_MASK ((cast64(3))<<38) |
RGB Dithering mask. | |
#define | SOM_RGBDITHER_SHIFT 38 |
RGB Dithering mask shift. | |
#define | SOM_ALPHADITHER_SAME ((cast64(0))<<36) |
Alpha Dithering: same as RGB. | |
#define | SOM_ALPHADITHER_INVERT ((cast64(1))<<36) |
Alpha Dithering: invert pattern compared to RG. | |
#define | SOM_ALPHADITHER_NOISE ((cast64(2))<<36) |
Alpha Dithering: noise. | |
#define | SOM_ALPHADITHER_NONE ((cast64(3))<<36) |
Alpha Dithering: none. | |
#define | SOM_ALPHADITHER_MASK ((cast64(3))<<36) |
Alpha Dithering mask. | |
#define | SOM_ALPHADITHER_SHIFT 36 |
Alpha Dithering mask shift. | |
#define | SOMX_FOG ((cast64(1))<<32) |
RDPQ special state: fogging is enabled. | |
#define | SOMX_UPDATE_FREEZE ((cast64(1))<<33) |
RDPQ special state: render mode update is frozen (see rdpq_mode_begin) | |
#define | SOMX_AA_REDUCED ((cast64(1))<<34) |
RDPQ special state: reduced antialiasing is enabled. | |
#define | SOMX_LOD_INTERPOLATE ((cast64(1))<<35) |
RDPQ special state: mimap interpolation (aka trilinear) requested. | |
#define | SOM_BLEND0_MASK (cast64(0xCCCC0000) | SOM_BLENDING | SOM_READ_ENABLE | SOMX_BLEND_2PASS) |
Blender: mask of settings related to pass 0. | |
#define | SOM_BLEND1_MASK (cast64(0x33330000) | SOM_BLENDING | SOM_READ_ENABLE | SOMX_BLEND_2PASS) |
Blender: mask of settings related to pass 1. | |
#define | SOM_BLEND_MASK (SOM_BLEND0_MASK | SOM_BLEND1_MASK) |
Blender: mask of all settings. | |
#define | SOMX_BLEND_2PASS ((cast64(1))<<15) |
RDPQ special state: record that the blender is made of 2 passes. | |
#define | SOM_BLENDING ((cast64(1))<<14) |
Activate blending for all pixels. | |
#define | SOM_BLALPHA_CC ((cast64(0))<<12) |
Blender IN_ALPHA is the output of the combiner output (default) | |
#define | SOM_BLALPHA_CVG ((cast64(2))<<12) |
Blender IN_ALPHA is the coverage of the current pixel. | |
#define | SOM_BLALPHA_CVG_TIMES_CC ((cast64(3))<<12) |
Blender IN_ALPHA is the product of the combiner output and the coverage. | |
#define | SOM_BLALPHA_MASK ((cast64(3))<<12) |
Blender alpha configuration mask. | |
#define | SOM_BLALPHA_SHIFT 12 |
Blender alpha configuration shift. | |
#define | SOM_ZMODE_OPAQUE ((cast64(0))<<10) |
Z-mode: opaque surface. | |
#define | SOM_ZMODE_INTERPENETRATING ((cast64(1))<<10) |
Z-mode: interprenating surfaces. | |
#define | SOM_ZMODE_TRANSPARENT ((cast64(2))<<10) |
Z-mode: transparent surface. | |
#define | SOM_ZMODE_DECAL ((cast64(3))<<10) |
Z-mode: decal surface. | |
#define | SOM_ZMODE_MASK ((cast64(3))<<10) |
Z-mode mask. | |
#define | SOM_ZMODE_SHIFT 10 |
Z-mode mask shift. | |
#define | SOM_Z_WRITE ((cast64(1))<<5) |
Activate Z-buffer write. | |
#define | SOM_Z_WRITE_SHIFT 5 |
Z-buffer write bit shift. | |
#define | SOM_Z_COMPARE ((cast64(1))<<4) |
Activate Z-buffer compare. | |
#define | SOM_Z_COMPARE_SHIFT 4 |
Z-buffer compare bit shift. | |
#define | SOM_ZSOURCE_PIXEL ((cast64(0))<<2) |
Z-source: per-pixel Z. | |
#define | SOM_ZSOURCE_PRIM ((cast64(1))<<2) |
Z-source: fixed value. | |
#define | SOM_ZSOURCE_MASK ((cast64(1))<<2) |
Z-source mask. | |
#define | SOM_ZSOURCE_SHIFT 2 |
Z-source mask shift. | |
#define | SOM_ALPHACOMPARE_NONE ((cast64(0))<<0) |
Alpha Compare: disable. | |
#define | SOM_ALPHACOMPARE_THRESHOLD ((cast64(1))<<0) |
Alpha Compare: use blend alpha as threshold. | |
#define | SOM_ALPHACOMPARE_NOISE ((cast64(3))<<0) |
Alpha Compare: use noise as threshold. | |
#define | SOM_ALPHACOMPARE_MASK ((cast64(3))<<0) |
Alpha Compare mask. | |
#define | SOM_ALPHACOMPARE_SHIFT 0 |
Alpha Compare mask shift. | |
#define | SOM_READ_ENABLE ((cast64(1)) << 6) |
Enable reads from framebuffer. | |
#define | SOM_AA_ENABLE ((cast64(1)) << 3) |
Enable anti-alias. | |
#define | SOM_COVERAGE_DEST_CLAMP ((cast64(0)) << 8) |
Coverage: add and clamp to 7 (full) | |
#define | SOM_COVERAGE_DEST_WRAP ((cast64(1)) << 8) |
Coverage: add and wrap from 0. | |
#define | SOM_COVERAGE_DEST_ZAP ((cast64(2)) << 8) |
Coverage: force 7 (full) | |
#define | SOM_COVERAGE_DEST_SAVE ((cast64(3)) << 8) |
Coverage: save (don't write) | |
#define | SOM_COVERAGE_DEST_MASK ((cast64(3)) << 8) |
Coverage mask. | |
#define | SOM_COVERAGE_DEST_SHIFT 8 |
Coverage mask shift. | |
#define | SOM_COLOR_ON_CVG_OVERFLOW ((cast64(1)) << 7) |
Update color buffer only on coverage overflow. | |
Typedefs | |
typedef uint64_t | rdpq_combiner_t |
A combiner formula, created by RDPQ_COMBINER1 or RDPQ_COMBINER2. | |
typedef uint32_t | rdpq_blender_t |
A blender formula, created by RDPQ_BLENDER or RDPQ_BLENDER2. | |
RDP command macros.
This file contains macros that can be used to assembly some complex RDP commands: the blender and the color combiner configurations.
The file is meant to be included also from RSP assembly code, for readability while manipulating these commands.
#define RDPQ_COMBINER_2PASS (cast64(1)<<63) |
Flag to mark the combiner as requiring two passes.
This is an internal flag used by rdpq to mark combiner configurations that require 2 passes to be executed, and differentiate them from 1 pass configurations.
It is used by rdpq to automatically switch to 2cycle mode when such a combiner is configured.
Application code should not use this macro directly.
#define RDPQ_COMBINER1 | ( | rgb, | |
alpha | |||
) |
Build a 1-pass combiner formula.
This macro allows to build a 1-pass color combiner formula. In general, the color combiner is able to execute the following per-pixel formula:
(A - B) * C + D
where A, B, C, D can be configured picking several possible inputs called "slots". Two different formulas (with the same structure but different inputs) must be configured: one for the RGB channels and for the alpha channel.
The macro must be invoked as:
RDPQ_COMBINER1((A1, B1, C1, D1), (A2, B2, C2, D2))
where A1
, B1
, C1
, D1
define the formula used for RGB channels, while A2
, B2
, C2
, D2
define the formula for the alpha channel. Please notice the double parenthesis.
For example, this macro:
RDPQ_COMBINER1((TEX0, 0, SHADE, 0), (0, 0, 0, TEX0))
configures the formulas:
RGB = (TEX0 - 0) * SHADE + 0 = TEX0 * SHADE ALPHA = (0 - 0) * 0 + TEX0 = TEX0
In the RGB channels, the texel color is multiplied by the shade color (which is the per-pixel interpolated vertex color), basically applying gouraud shading. The alpha channel of the texel is instead passed through with no modifications.
The output of the combiner goes into the blender unit, that allows for further operations on the RGB channels, especially allowing to blend it with the framebuffer contents. See RDPQ_BLENDER for information on how to configure the blender.
The values created by RDPQ_COMBINER1 are of type rdpq_combiner_t. They can be used in two different ways:
This is the list of all possible slots. Not all slots are available for the four variables (see the table below).
TEX0
: texel of the texture being drawn.SHADE
: per-pixel interpolated color. This can be set on each vertex of a triangle, and is interpolated across each pixel. It cannot be used while drawing rectangles.PRIM
: value of the PRIM register (set via rdpq_set_prim_color)ENV
: value of the ENV register (set via rdpq_set_env_color)NOISE
: a random value1
: the constant value 1.00
: the constant value 0.0K4
: the constant value configured as k4
as part of YUV parameters (via rdpq_set_yuv_parms).K5
: the constant value configured as k5
as part of YUV parameters (via rdpq_set_yuv_parms).TEX0_ALPHA
: alpha of the text of the texture being drawn.SHADE_ALPHA
: alpha of the per-pixel interpolated color.PRIM_ALPHA
: alpha of the PRIM register (set via rdpq_set_prim_color)ENV_ALPHA
: alpha of the ENV register (set via rdpq_set_env_color)LOD_FRAC
: the LOD fraction, that is the fractional value that can be used as interpolation value between different mipmaps. It basically says how much the texture is being scaled down.PRIM_LOD_FRAC
KEYCENTER
KEYSCALE
These tables show, for each possible variable of the RGB and ALPHA formula, which slots are allowed:
RGB | A | TEX0 , SHADE , PRIM , ENV , NOISE , 1 , 0 |
---|---|---|
B | TEX0 , SHADE , PRIM , ENV , KEYCENTER , K4 , 0 | |
C | TEX0 , SHADE , PRIM , ENV , TEX0_ALPHA , SHADE_ALPHA , PRIM_ALPHA , ENV_ALPHA , LOD_FRAC , PRIM_LOD_FRAC , K5 , 'KEYSCALE', 0 | |
D | TEX0 , SHADE , PRIM , ENV , 1 , 0 |
ALPHA | A | TEX0 , SHADE , PRIM , ENV , 1 , 0 |
---|---|---|
B | TEX0 , SHADE , PRIM , ENV , 1 , 0 | |
C | TEX0 , SHADE , PRIM , ENV , LOD_FRAC , PRIM_LOD_FRAC , 0 | |
D | TEX0 , SHADE , PRIM , ENV , 1 , 0 |
For instance, to draw a gouraud-shaded textured triangle, one might want to calculate the following combiner formula:
RGB = TEX0 * SHADE ALPHA = TEX0 * SHADE
which means that for all channels, we multiply the value sampled from the texture with the per-pixel interpolated color coming from the triangle vertex. To do so, we need to adapt the formula to the 4-variable combiner structure:
RGB = (TEX0 - 0) * SHADE + 0 ALPHA = (TEX0 - 0) * SHADE + 0
To program this into the combiner, we can issue the following command:
rdpq_mode_combiner(RDPQ1_COMBINER((TEX0, 0, SHADE, 0), (TEX0, 0, SHADE, 0)));
Notice that this is just a way to obtain the formula above. Another possibility is:
rdpq_mode_combiner(RDPQ1_COMBINER((1, 0, SHADE, TEX0), (1, 0, SHADE, TEX0)));
which will obtain exactly the same result.
A complete example drawing a textured rectangle with a fixed semi-transparency of 0.7:
[in] | rgb | The RGB formula as (A, B, C, D) |
[in] | alpha | The ALPHA formula as (A, B, C, D) |
#define RDPQ_COMBINER2 | ( | rgb0, | |
alpha0, | |||
rgb1, | |||
alpha1 | |||
) |
Build a 2-pass combiner formula.
This is similar to RDPQ_COMBINER1, but it creates a two-passes combiner. The combiner unit in RDP in fact allows up to two sequential combiner formulas that can be applied to each pixel.
In the second pass, you can refer to the output of the first pass using the COMBINED
slot (not available in the first pass).
Refer to RDPQ_COMBINER1 for more information.
#define RDPQ_COMBINER_TEX_FLAT RDPQ_COMBINER1((TEX0,0,PRIM,0), (TEX0,0,PRIM,0)) |
Draw with a texture modulated with a flat color. Configure the color via rdpq_set_prim_color.
Among other uses, this mode is the correct one to colorize a FMT_IA8 and FMT_IA4 texture with a fixed color.
#define RDPQ_COMBINER_TEX_SHADE RDPQ_COMBINER1((TEX0,0,SHADE,0), (TEX0,0,SHADE,0)) |
Draw with a texture modulated with an interpolated color. This does texturing with gouraud shading, and can be used for textured triangles with per-vertex lighting.
This mode makes sense only for triangles with per-vertex colors. It should not be used with rectangles.
#define RDPQ_BLENDER | ( | bl | ) |
Build a 1-pass blender formula.
This macro allows to build a 1-pass blender formula. In general, the blender is able to execute the following per-pixel formula:
(P * A) + (Q * B)
where P and Q are usually pixel inputs, while A and B are blending factors. P
, Q
, A
, B
can be configured picking several possible inputs called "slots".
The macro must be invoked as:
RDPQ_BLENDER((P, A, Q, B))
where P
, A
, Q
, B
can be any of the values described below. Please notice the double parenthesis.
For example, this macro:
RDPQ_BLENDER((IN_RGB, IN_ALPHA, MEMORY_RGB, 1))
configures the formula:
(IN_RGB * IN_ALPHA) + (MEMORY_RGB * 1.0)
The value created is of type rdpq_blender_t. They can be used in two different ways:
SOM_*
macros to create the final value to pass to the function. If a two-pass blender must be configured, use RDPQ_BLENDER2 instead.Pre-made formulas for common scenarios are available: see RDPQ_BLENDER_MULTIPLY, RDPQ_BLENDER_ADDITIVE, RDPQ_FOG_STANDARD.
These are all possible inputs for P
and Q
:
IN_RGB
: The RGB channels of the pixel being drawn. This is actually the output of the color combiner (that can be configured via rdpq_mode_combiner, RDPQ_COMBINER1, and RDPQ_COMBINER2).MEMORY_RGB
: Current contents of the framebuffer, where the current pixel will be drawn. Reading the framebuffer contents and using them in the formula allows to create the typical blending effect.BLEND_RGB
: A fixed RGB value programmed into the BLEND register. This can be configured via rdpq_set_blend_color.FOG_RGB
: A fixed RGB value programmed into the FOG register. This can be configured via rdpq_set_fog_color.These are all possible inputs for A
:
IN_ALPHA
: The alpha channel of the pixel being drawn. This is actually the output of the color combiner (that can be configured via rdpq_mode_combiner, RDPQ_COMBINER1, and RDPQ_COMBINER2).FOG_ALPHA
: The alpha channel of the FOG register. This can be configured via rdpq_set_fog_color.SHADE_ALPHA
: The alpha channel of the shade color. The shade component is the color optionally set on each vertex when drawing a triangle (see rdpq_triangle). The RDP interpolates it on each pixel.0
: the constant value 0.These are all possible inputs for B
:
INV_MUX_ALPHA
: This value is the inverse of whatever input was selected for A
. For instance, if A
was configured as FOG_ALPHA
, setting B
to INV_MUX_ALPHA
means using 1.0 - FOG_ALPHA
in the calculation. This basically allows to do a linear interpolation between P
and Q
where A
is the interpolation factor.MEMORY_CVG
: This is the subpixel coverage value stored in the framebuffer at the position where the current pixel will be drawn. The coverage is normally stored as a value in the range 0-7, but the blender normalizes in the range 0.0-1.0.1
: the constant value 1.0
: the constant value 0.The blender uses the framebuffer precision for the RGB channels: when drawing to a 32-bit framebuffer, P
and Q
will have 8-bit precision per channel, whilst when drawing to a 16-bit framebuffer, P
and Q
will be 5-bit. You can add dithering if needed, via rdpq_mode_dithering.
On the other hand, A
and B
always have a reduced 5-bit precision, even on 32-bit framebuffers. This means that the alpha values will be quantized during the blending, possibly creating mach banding. Consider using dithering via rdpq_mode_dithering to improve the quality of the picture.
Notice that the blender formula only works on RGB channels. Alpha channels can be used as input (as multiplicative factor), but the blender does not produce an alpha channel as output. In fact, the RGB output will be written to the framebuffer after the blender, while the bits normally used for alpha in each framebuffer pixel will contain information about subpixel coverage (that will be then used by VI for doing antialiasing as a post-process filter – see rdpq_mode_antialias for a brief explanation).
#define RDPQ_BLENDER2 | ( | bl0, | |
bl1 | |||
) |
Build a 2-pass blender formula.
This macro is similar to RDPQ_BLENDER, but it can be used to build a two-passes blender formula. This formula can be then configured using the mode API via rdpq_mode_blender, or using the lower-level API via rdpq_change_other_modes_raw.
Refer to RDPQ_BLENDER for information on how to build a blender formula.
In two-passes mode, there are a few differences and gotchas in the way the formula must be constructed:
B
must be INV_MUX_ALPHA
(any other value is invalid and will result in a compile-time error).MEMORY_RGB
is not available.IN_RGB
is not available, but you can instead use CYCLE1_RGB
to refer to the output of the first cycle. IN_ALPHA
is still available (as the blender does not produce a alpha output, so the input alpha is available also in the second pass).SHADE_ALPHA
will actually refer to the alpha color of the next pixel in the scanline (the pixel to the right). On the last pixel of the triangle in each scanline, the value read as SHADE_ALPHA
is mostly undefined. Given this hardware bug, avoid using SHADE_ALPHA
in the second pass if possible.