Reality Display Processor/Commands: Difference between revisions

Hazard: Alpha compare in COPY mode targeting 16-bit framebuffers is only valid for RGBA5551 textures
(Set Combine Mode)
(Hazard: Alpha compare in COPY mode targeting 16-bit framebuffers is only valid for RGBA5551 textures)
 
(6 intermediate revisions by 2 users not shown)
Line 20:
|}
 
====<span style="display:none;">0x00 through 0x07, 0x10 through 0x23, 0x31 - No Operation ====
----
{| class="wikitable" style="text-align: center; white-space:nowrap;"
Line 41:
(TOVERIFY all of these command ids appear to behave as no-ops and take only 1 cycle to execute in testing so far, however this should be checked more extensively)
 
====<span style="display:none;">0x08 through 0x0F - Fill Triangle ====
----
 
The Fill Triangle command varies in length depending on whether shade, texture or depth is enabled in the first word. For any of these properties that are enabled, additional words are appended to the base command words in order of shading, texturing, z-buffering.
 
==== Base Command ====
 
Every triangle type begins with a common base that describes the type, shape and other small properties of the triangle.
 
{| class="wikitable" style="text-align: center; white-space:nowrap;"
! colspan="18"|Fill Triangle <code>0x08</code> through <code>0x0F</code> (base)
|-
| rowspan="4"|Word 0 || 63:48 || — || — || 0 || 0 || 1 || shade || texture || zbuffer || lmajor || — || colspan=3| level[2:0] || colspan=3| tile[2:0]
|-
| 47:32 || — || — || colspan=14| y.loyl[13:0]
|-
| 31:16 || — || — || colspan=14| y.mdym[13:0]
|-
| 15:0 || — || — || colspan=14| y.hiyh[13:0]
|-
| rowspan="4"|Word 1 || 63:48 || — || — || — || — || colspan=1612| x.lo.cxl.i[1511:0]
|-
| 47:32 || colspan=16| x.lo.cxl.f[15:0]
|-
| 31:16 || — || — || colspan=1614| x.lo.sdxldy.i[1513:0]
|-
| 15:0 || colspan=16| x.lo.sdxldy.f[15:0]
|-
| rowspan="4"|Word 2 || 63:48 || — || — || — || — || colspan=1612| x.hi.cxh.i[15:0]
|-
| 47:32 || colspan=16| x.hi.cxh.f[15:0]
|-
| 31:16 || — || — || colspan=1614| x.hi.sdxhdy.i[15:0]
|-
| 15:0 || colspan=16| x.hi.sdxhdy.f[15:0]
|-
| rowspan="4"|Word 3 || 63:48 || — || — || — || — || colspan=1612| x.md.cxm.i[15:0]
|-
| 47:32 || colspan=16| x.md.cxm.f[15:0]
|-
| 31:16 || — || — || colspan=1614| x.md.sdxmdy.i[15:0]
|-
| 15:0 || colspan=16| x.md.sdxmdy.f[15:0]
|}
'''Word 0'''
{{#invoke:Register table|definitions
| 61:56 | command | 0x08 through 0x0F depending on features specified
| 58 | shade | ifIf 1, command is followed by 8 words specifying shading instructionscoefficients
| 57 | texture | ifIf 1, command is followed by 8 words specifying texturing instructionscoefficients
| 56 | zbuffer | ifIf 1, command is followed by 2 words specifying zbufferingz-buffering instructionscoefficients
| 55 | lmajor | Left-major flag, if enabled rendering occurs from left-to-right, otherwise rendering occurs from right-to-left
| 55 | lmajor | ?
| 53:51 | level[2:0] | -Maximum LOD level
| 50:48 | tile[2:0] | -Base tile descriptor index
| 45:32 | yl[13:0] | Lowest y coordinate (largest value), rasterization ends at this height (s11.2 format)
| 45:32 | y.lo[13:0] | -
| 29:16 | ym[13:0] | Middle y coordinate (middle value), rasterization swaps dxmdy for dxldy (s11.2 format)
| 29:16 | y.md[13:0] | -
| 13:0 | yh[13:0] | Highest y coordinate (highest value), rasterization begins at this height (s11.2 format)
| 13:0 | y.hi[13:0] | -
}}
'''Word 1'''
{{#invoke:Register table|definitions
| 59:48 | xl.i[11:0] | Integer part of x coordinate on dxldy line at height ym (s11.16 format)
| 63:48 | x.lo.c.i[15:0] | -
| 47:32 | x.lo.cxl.f[15:0] | -Fractional part of x coordinate on dxldy line at height ym (s11.16 format)
| 29:16 | dxldy.i[13:0] | Integer part of change in x per change in y of line connecting middle and lowest vertices (s13.16 format)
| 31:16 | x.lo.s.i[15:0] | -
| 15:0 | dxldy.f[15:0] | Fractional part of change in x per change in y of line connecting middle and lowest vertices (s13.16 format)
| 15:0 | x.lo.s.f[15:0] | -
}}
'''Word 2'''
{{#invoke:Register table|definitions
| 59:48 | xh.i[11:0] | Integer part of x coordinate on dxhdy line at height floor(yh) (s11.16 format)
| 63:48 | x.hi.c.i[15:0] | -
| 47:32 | xh.f[15:0] | Fractional part of x coordinate on dxhdy line at height floor(yh) (s11.16 format)
| 47:32 | x.hi.c.f[15:0] | -
| 29:16 | dxhdy.i[13:0] | Integer part of change in x per change in y of line connecting highest and lowest vertices (s13.16 format)
| 31:16 | x.hi.s.i[15:0] | -
| 15:0 | dxhdy.f[15:0] | Fractional part of change in x per change in y of line connecting highest and lowest vertices (s13.16 format)
| 15:0 | x.hi.s.f[15:0] | -
}}
'''Word 3'''
{{#invoke:Register table|definitions
| 59:48 | xm.i[11:0] | Integer part of x coordinate on dxmdy line at height floor(yh) (s11.16 format)
| 63:48 | x.md.c.i[15:0] | -
| 47:32 | xm.f[15:0] | Fractional part of x coordinate on dxmdy line at height floor(yh) (s11.16 format)
| 47:32 | x.md.c.f[15:0] | -
| 29:16 | dxmdy.i[13:0] | Integer part of change in x per change in y of line connecting highest and middle vertices (s13.16 format)
| 31:16 | x.md.s.i[15:0] | -
| 15:0 | dxmdy.f[15:0] | Fractional part of change in x per change in y of line connecting highest and middle vertices (s13.16 format)
| 15:0 | x.md.s.f[15:0] | -
}}
 
====<span style="display:none;">0x0C through 0x0F - Shaded Triangle ====
----
 
After above 4 words describing a triangle, if requested by the command, these 8 words describing shading instructions:
==== Optional Shading Properties ====
 
If the '''shade''' bit was set in the base triangle description, the above words will be followed by these 8 words describing triangle shading properties:
 
{| class="wikitable" style="text-align: center; white-space:nowrap;"
! colspan="18"|Fill Shaded Triangle (suffix) <code>0x0C</code> … <code>0x0F</code>
|-
| rowspan="4"|Word 0 || 63:48 || - || - || - || - || - || - || - || colspan=169| r.c.i[158:0]
|-
| 47:32 || - || - || - || - || - || - || - || colspan=169| g.c.i[158:0]
|-
| 31:16 || - || - || - || - || - || - || - || colspan=169| b.c.i[158:0]
|-
| 15:0 || - || - || - || - || - || - || - || colspan=169| a.c.i[158:0]
|-
| rowspan="4"|Word 1 || 63:48 || colspan=16| r.xdrdx.i[15:0]
|-
| 47:32 || colspan=16| g.xdgdx.i[15:0]
|-
| 31:16 || colspan=16| b.xdbdx.i[15:0]
|-
| 15:0 || colspan=16| a.xdadx.i[15:0]
|-
| rowspan="4"|Word 2 || 63:48 || colspan=16| r.c.f[15:0]
|-
| 47:32 || colspan=16| g.c.f[15:0]
|-
| 31:16 || colspan=16| b.c.f[15:0]
|-
| 15:0 || colspan=16| a.c.f[15:0]
|-
| rowspan="4"|Word 3 || 63:48 || colspan=16| r.xdrdx.f[15:0]
|-
| 47:32 || colspan=16| g.xdgdx.f[15:0]
|-
| 31:16 || colspan=16| b.xdbdx.f[15:0]
|-
| 15:0 || colspan=16| a.xdadx.f[15:0]
|-
| rowspan="4"|Word 4 || 63:48 || colspan=16| r.edrde.i[15:0]
|-
| 47:32 || colspan=16| g.edgde.i[15:0]
|-
| 31:16 || colspan=16| b.edbde.i[15:0]
|-
| 15:0 || colspan=16| a.edade.i[15:0]
|-
| rowspan="4"|Word 5 || 63:48 || colspan=16| r.ydrdy.i[15:0]
|-
| 47:32 || colspan=16| g.ydgdy.i[15:0]
|-
| 31:16 || colspan=16| b.ydbdy.i[15:0]
|-
| 15:0 || colspan=16| a.ydady.i[15:0]
|-
| rowspan="4"|Word 6 || 63:48 || colspan=16| r.edrde.f[15:0]
|-
| 47:32 || colspan=16| g.edgde.f[15:0]
|-
| 31:16 || colspan=16| b.edbde.f[15:0]
|-
| 15:0 || colspan=16| a.edade.f[15:0]
|-
| rowspan="4"|Word 7 || 63:48 || colspan=16| r.ydrdy.f[15:0]
|-
| 47:32 || colspan=16| g.ydgdy.f[15:0]
|-
| 31:16 || colspan=16| b.ydbdy.f[15:0]
|-
| 15:0 || colspan=16| a.ydady.f[15:0]
|}
'''Word 0'''
{{#invoke:Register table|definitions
| 56:48 | r.i[8:0] | Integer part of red channel shade color at '''(xh, floor(yh))''' (s8.16 format)
| 63:48 | r.c.i[15:0] | -
| 40:32 | g.i[8:0] | Integer part of green channel shade color at '''(xh, floor(yh))''' (s8.16 format)
| 47:32 | g.c.i[15:0] | -
| 24:16 | b.i[8:0] | Integer part of blue channel shade color at '''(xh, floor(yh))''' (s8.16 format)
| 31:16 | b.c.i[15:0] | -
| 8:0 | a.i[8:0] | Integer part of alpha channel shade color at '''(xh, floor(yh))''' (s8.16 format)
| 15:0 | a.c.i[15:0] | -
}}
'''Word 1'''
{{#invoke:Register table|definitions
| 63:48 | drdx.i[15:0] | Integer part of change in red channel shade color horizontally along a scanline (s15.16 format)
| 63:48 | r.x.i[15:0] | -
| 47:32 | dgdx.i[15:0] | Integer part of change in green channel shade color horizontally along a scanline (s15.16 format)
| 47:32 | g.x.i[15:0] | -
| 31:16 | dbdx.i[15:0] | Integer part of change in blue channel shade color horizontally along a scanline (s15.16 format)
| 31:16 | b.x.i[15:0] | -
| 15:0 | dadx.i[15:0] | Integer part of change in alpha channel shade color horizontally along a scanline (s15.16 format)
| 15:0 | a.x.i[15:0] | -
}}
'''Word 2'''
{{#invoke:Register table|definitions
| 63:48 | r.c.f[15:0] | -Fractional part of red channel shade color at '''(xh, floor(yh))''' (s8.16 format)
| 47:32 | g.c.f[15:0] | -Fractional part of green channel shade color at '''(xh, floor(yh))''' (s8.16 format)
| 31:16 | b.c.f[15:0] | -Fractional part of blue channel shade color at '''(xh, floor(yh))''' (s8.16 format)
| 15:0 | a.f[15:0] | Fractional part of alpha channel shade color at '''(xh, floor(yh))''' (s8.16 format)
| 15:0 | a.c.f[15:0] | -
}}
'''Word 3'''
{{#invoke:Register table|definitions
| 63:48 | drdx.f[15:0] | Fractional part of change in red channel shade color horizontally along a scanline (s15.16 format)
| 63:48 | r.x.f[15:0] | -
| 47:32 | dgdx.f[15:0] | Fractional part of change in green channel shade color horizontally along a scanline (s15.16 format)
| 47:32 | g.x.f[15:0] | -
| 31:16 | dbdx.f[15:0] | Fractional part of change in blue channel shade color horizontally along a scanline (s15.16 format)
| 31:16 | b.x.f[15:0] | -
| 15:0 | dadx.f[15:0] | Fractional part of change in alpha channel shade color horizontally along a scanline (s15.16 format)
| 15:0 | a.x.f[15:0] | -
}}
'''Word 4'''
{{#invoke:Register table|definitions
| 63:48 | drde.i[15:0] | Integer part of change in red channel shade color along the major edge (s15.16 format)
| 63:48 | r.e.i[15:0] | -
| 47:32 | dgde.i[15:0] | Integer part of change in green channel shade color along the major edge (s15.16 format)
| 47:32 | g.e.i[15:0] | -
| 31:16 | dbde.i[15:0] | Integer part of change in blue channel shade color along the major edge (s15.16 format)
| 31:16 | b.e.i[15:0] | -
| 15:0 | dade.i[15:0] | Integer part of change in alpha channel shade color along the major edge (s15.16 format)
| 15:0 | a.e.i[15:0] | -
}}
'''Word 5'''
{{#invoke:Register table|definitions
| 63:48 | drdy.i[15:0] | Integer part of change in red channel shade color for each scanline (s15.16 format)
| 63:48 | r.y.i[15:0] | -
| 47:32 | dgdy.i[15:0] | Integer part of change in green channel shade color for each scanline (s15.16 format)
| 47:32 | g.y.i[15:0] | -
| 31:16 | dbdy.i[15:0] | Integer part of change in blue channel shade color for each scanline (s15.16 format)
| 31:16 | b.y.i[15:0] | -
| 15:0 | dady.i[15:0] | Integer part of change in alpha channel shade color for each scanline (s15.16 format)
| 15:0 | a.y.i[15:0] | -
}}
'''Word 6'''
{{#invoke:Register table|definitions
| 63:48 | drde.f[15:0] | Fractional part of change in red channel shade color along the major edge (s15.16 format)
| 63:48 | r.e.f[15:0] | -
| 47:32 | dgde.f[15:0] | Fractional part of change in green channel shade color along the major edge (s15.16 format)
| 47:32 | g.e.f[15:0] | -
| 31:16 | dbde.f[15:0] | Fractional part of change in blue channel shade color along the major edge (s15.16 format)
| 31:16 | b.e.f[15:0] | -
| 15:0 | dade.f[15:0] | Fractional part of change in alpha channel shade color along the major edge (s15.16 format)
| 15:0 | a.e.f[15:0] | -
}}
'''Word 7'''
{{#invoke:Register table|definitions
| 63:48 | drdy.f[15:0] | Fractional part of change in red channel shade color for each scanline (s15.16 format)
| 63:48 | r.y.f[15:0] | -
| 47:32 | dgdy.f[15:0] | Fractional part of change in green channel shade color for each scanline (s15.16 format)
| 47:32 | g.y.f[15:0] | -
| 31:16 | dbdy.f[15:0] | Fractional part of change in blue channel shade color for each scanline (s15.16 format)
| 31:16 | b.y.f[15:0] | -
| 15:0 | dady.f[15:0] | Fractional part of change in alpha channel shade color for each scanline (s15.16 format)
| 15:0 | a.y.f[15:0] | -
}}
 
====<span style="display:none;">0x0A, 0x0B, 0x0E, 0x0F - Textured Triangle ====
----
 
After above 4 words describing a triangle, and optional 8 words describing shading, these 8 words describing texturing instructions:
==== Optional Texturing Properties ====
 
If the '''texture''' bit was set in the base triangle description, the above words will be followed by these 8 words describing triangle texturing properties:
 
{| class="wikitable" style="text-align: center; white-space:nowrap;"
! colspan="18"|Fill Textured Triangle (A,B,E,Fsuffix)
|-
| rowspan="4"|Word 0 || 63:48 || colspan=16| s.c.i[15:0]
|-
| 47:32 || colspan=16| t.c.i[15:0]
|-
| 31:16 || colspan=16| w.c.i[15:0]
|-
| 15:0 || — || — || — || — || — || — || — || — || — || — || — || — || — || — || — || —
|-
| rowspan="4"|Word 1 || 63:48 || colspan=16| s.xdsdx.i[15:0]
|-
| 47:32 || colspan=16| t.xdtdx.i[15:0]
|-
| 31:16 || colspan=16| w.xdwdx.i[15:0]
|-
| 15:0 || — || — || — || — || — || — || — || — || — || — || — || — || — || — || — || —
|-
| rowspan="4"|Word 2 || 63:48 || colspan=16| s.c.f[15:0]
|-
| 47:32 || colspan=16| t.c.f[15:0]
|-
| 31:16 || colspan=16| w.c.f[15:0]
|-
| 15:0 || — || — || — || — || — || — || — || — || — || — || — || — || — || — || — || —
|-
| rowspan="4"|Word 3 || 63:48 || colspan=16| s.xdsdx.f[15:0]
|-
| 47:32 || colspan=16| t.xdtdx.f[15:0]
|-
| 31:16 || colspan=16| w.xdwdx.f[15:0]
|-
| 15:0 || — || — || — || — || — || — || — || — || — || — || — || — || — || — || — || —
|-
| rowspan="4"|Word 4 || 63:48 || colspan=16| s.edsde.i[15:0]
|-
| 47:32 || colspan=16| t.edtde.i[15:0]
|-
| 31:16 || colspan=16| w.edwde.i[15:0]
|-
| 15:0 || — || — || — || — || — || — || — || — || — || — || — || — || — || — || — || —
|-
| rowspan="4"|Word 5 || 63:48 || colspan=16| s.ydsdy.i[15:0]
|-
| 47:32 || colspan=16| t.ydtdy.i[15:0]
|-
| 31:16 || colspan=16| w.ydwdy.i[15:0]
|-
| 15:0 || — || — || — || — || — || — || — || — || — || — || — || — || — || — || — || —
|-
| rowspan="4"|Word 6 || 63:48 || colspan=16| s.edsde.f[15:0]
|-
| 47:32 || colspan=16| t.edtde.f[15:0]
|-
| 31:16 || colspan=16| w.edwde.f[15:0]
|-
| 15:0 || — || — || — || — || — || — || — || — || — || — || — || — || — || — || — || —
|-
| rowspan="4"|Word 7 || 63:48 || colspan=16| s.ydsdy.f[15:0]
|-
| 47:32 || colspan=16| t.ydtdy.f[15:0]
|-
| 31:16 || colspan=16| w.ydwdy.f[15:0]
|-
| 15:0 || — || — || — || — || — || — || — || — || — || — || — || — || — || — || — || —
Line 313 ⟶ 325:
'''Word 0'''
{{#invoke:Register table|definitions
| 63:48 | s.c.i[15:0] | Integer part of s-axis texture coordinate at '''(xh, floor(yh))'''
| 47:32 | t.c.i[15:0] | Integer part of t-axis texture coordinate at '''(xh, floor(yh))'''
| 31:16 | w.c.i[15:0] | -Integer part of perspective scale at '''(xh, floor(yh))'''
}}
'''Word 1'''
{{#invoke:Register table|definitions
| 63:48 | s.xdsdx.i[15:0] | Integer part of change in s-axis texture coordinate horizontally along a scanline
| 47:32 | t.xdtdx.i[15:0] | Integer part of change in t-axis texture coordinate horizontally along a scanline
| 31:16 | w.xdwdx.i[15:0] | -Integer part of change in perspective scale horizontally along a scanline
}}
'''Word 2'''
{{#invoke:Register table|definitions
| 63:48 | s.c.f[15:0] | Fractional part of s-axis texture coordinate at '''(xh, floor(yh))'''
| 47:32 | t.c.f[15:0] | Fractional part of t-axis texture coordinate at '''(xh, floor(yh))'''
| 31:16 | w.c.f[15:0] | -Fractional part of perspective scale at '''(xh, floor(yh))'''
}}
'''Word 3'''
{{#invoke:Register table|definitions
| 63:48 | s.xdsdx.f[15:0] | Fractional part of change in s-axis texture coordinate horizontally along a scanline
| 47:32 | t.xdtdx.f[15:0] | Fractional part of change in t-axis texture coordinate horizontally along a scanline
| 31:16 | w.xdwdx.f[15:0] | -Fractional part of change in perspective scale horizontally along a scanline
}}
'''Word 4'''
{{#invoke:Register table|definitions
| 63:48 | s.edsde.i[15:0] | Integer part of change in s-axis texture coordinate along the major edge
| 47:32 | t.edtde.i[15:0] | Integer part of change in t-axis texture coordinate along the major edge
| 31:16 | w.edwde.i[15:0] | -Integer part of change in perspective scale along the major edge
}}
'''Word 5'''
{{#invoke:Register table|definitions
| 63:48 | s.ydsdy.i[15:0] | Integer part of change in s-axis texture coordinate for each scanline
| 47:32 | t.ydtdy.i[15:0] | Integer part of change in t-axis texture coordinate for each scanline
| 31:16 | w.ydwdy.i[15:0] | -Integer part of change in perspective scale for each scanline
}}
'''Word 6'''
{{#invoke:Register table|definitions
| 63:48 | s.edsde.f[15:0] | Fractional part of change in s-axis texture coordinate along the major edge
| 47:32 | t.edtde.f[15:0] | Fractional part of change in t-axis texture coordinate along the major edge
| 31:16 | w.edwde.f[15:0] | -Fractional part of change in perspective scale along the major edge
}}
'''Word 7'''
{{#invoke:Register table|definitions
| 63:48 | s.ydsdy.f[15:0] | Fractional part of change in s-axis texture coordinate for each scanline
| 47:32 | t.ydtdy.f[15:0] | Fractional part of change in t-axis texture coordinate for each scanline
| 31:16 | w.ydwdy.f[15:0] | -Fractional part of change in perspective scale for each scanline
}}
 
====<span style="display:none;">0x09, 0x0B, 0x0D, 0x0F - Zbuffered Triangle ====
----
 
After above 4 words describing a triangle, optional 8 words describing shading, and optional 8 words describing texturing, these two words describing Zbuffering:
==== Optional Depth Properties ====
 
If the '''zbuffer''' bit was set in the base triangle description, the above words will be followed by these 2 words describing triangle depth properties:
 
{| class="wikitable" style="text-align: center; white-space:nowrap;"
! colspan="18"| ZbufferedFill Z-Buffered Triangle (9,B,D,Fsuffix)
|-
| rowspan="4"|Word 0 || 63:48 || colspan=16| dz.i[15:0]
|-
| 47:32 || colspan=16| dz.f[15:0]
|-
| 31:16 || colspan=16| xdzdx.i[15:0]
|-
| 15:0 || colspan=16| xdzdx.f[15:0]
|-
| rowspan="4"|Word 1 || 63:48 || colspan=16| edzde.i[15:0]
|-
| 47:32 || colspan=16| edzde.f[15:0]
|-
| 31:16 || colspan=16| ydzdy.i[15:0]
|-
| 15:0 || colspan=16| ydzdy.f[15:0]
|}
'''Word 0'''
{{#invoke:Register table|definitions
| 63:48 | dz.i[15:0] | -Integer part of depth at '''(xh, floor(yh))'''
| 47:32 | dz.f[15:0] | -Fractional part of depth at '''(xh, floor(yh))'''
| 31:16 | xdzdx.i[15:0] | -Integer part of change in depth horizontally along a scanline
| 15:0 | xdzdx.f[15:0] | -Fractional part of change in depth horizontally along a scanline
}}
'''Word 1'''
{{#invoke:Register table|definitions
| 63:48 | edzde.i[15:0] | -Integer part of change in depth along the major edge
| 47:32 | edzde.f[15:0] | -Fractional part of change in depth along the major edge
| 31:16 | ydzdy.i[15:0] | -Integer part of change in depth for each scanline
| 15:0 | ydzdy.f[15:0] | -Fractional part of change in depth for each scanline
}}
 
====<span style="display:none;">0x24 and 0x25 - Texture Rectangle ====
----
{| class="wikitable" style="text-align: center; white-space:nowrap;"
Line 449 ⟶ 464:
* In 1-Cycle and 2-Cycle mode using attributes such as shade color and per-pixel depth may be ill-defined. (TOVERIFY: It's either always 0 or uses the last value from previous primitives, check which)
 
====<span style="display:none;">0x26 - Sync Load ====
----
{| class="wikitable" style="text-align: center; white-space:nowrap;"
Line 470 ⟶ 485:
The stall is always 25 cycles and does not wait on any particular internal signal(s), if a Sync Load is queued when it is not needed it simply wastes the full length of time.
 
====<span style="display:none;">0x27 - Sync Pipe ====
----
{| class="wikitable" style="text-align: center; white-space:nowrap;"
Line 493 ⟶ 508:
(TOVERIFY/Speculation: Changing an attribute without a sync typically corrupts only up to at most 24 pixels of the last primitive, suggesting the RDP pixel pipeline is ~24 cycles deep. Can a tile sync account for all or at least almost all attribute changes?)
 
====<span style="display:none;">0x28 - Sync Tile ====
----
{| class="wikitable" style="text-align: center; white-space:nowrap;"
Line 514 ⟶ 529:
The stall is always 33 cycles and does not wait on any particular internal signal(s), if a Sync Tile is queued when it is not needed it simply wastes the full length of time.
 
====<span style="display:none;">0x29 - Sync Full ====
----
{| class="wikitable" style="text-align: center; white-space:nowrap;"
Line 535 ⟶ 550:
'''Hazards'''
* Ensure this is the final command consumed before hitting DP_END, otherwise the RDP may hang.
* Ensure no other commands are sent to RDP (via DP_START/DP_END) while a Sync Full is in progress, otherwise the RDP may hang.
 
====<span style="display:none;">0x2a0x2A - Set Key GB ====
----
{| class="wikitable" style="text-align: center; white-space:nowrap;"
Line 567 ⟶ 583:
Key center and scale are Color Combiner inputs, the expectation is that the Color Combiner is configured to <math>(X - \mathrm{Center}) \cdot \mathrm{Scale}</math> when chroma keying, where <math>X</math> is any color source. If not chroma keying, these may be used as general-purpose Color Combiner inputs.
 
====<span style="display:none;">0x2b0x2B - Set Key R ====
----
{| class="wikitable" style="text-align: center; white-space:nowrap;"
Line 589 ⟶ 605:
Sets Chroma Key parameters for the red color channel. See '''Set Key GB''' for discussion.
 
====<span style="display:none;">0x2c0x2C - Set Convert ====
----
{| class="wikitable" style="text-align: center; white-space:nowrap;"
Line 641 ⟶ 657:
K4 and K5 may also simply be used as additional general-purpose CC inputs.
 
====<span style="display:none;">0x2d0x2D - Set Scissor ====
----
{| class="wikitable" style="text-align: center; white-space:nowrap;"
Line 677 ⟶ 693:
* In FILL mode sometimes scissor works at the level of individual pixels while sometimes it only works at 4-pixel boundaries. (TODO understand this better, probably to do with memory alignment)
 
====<span style="display:none;">0x2e0x2E - Set Primitive Depth ====
----
{| class="wikitable" style="text-align: center; white-space:nowrap;"
Line 705 ⟶ 721:
* The dz value provided should be a power of 2 to ensure correct operation. RDP hardware uses a cheap integer log2 algorithm for computing log2(dz) that is only guaranteed to produce correct results when the input is a power of 2. Notably, the value 0xFFFF happens to work correctly.
 
=== 0x2F - Set Other Modes ===
====<span style="display:none;">0x2f - Set_Other_Modes ====
----
{| class="wikitable" style="text-align: center; white-space:nowrap;"
! colspan="17"|Set_Other_ModesSet Other Modes <code>0x2f</code>
|-
| 63:48 || — || — || colspan=6| command = 0x2f[5:0] || other.atomicPrimitiveatomic_prim || other.reserved1- || colspan=2| other.cycleTypecycle_type[1:0] || other.perspectivepersp_tex_en || other.detailTexturedetail_tex_en || other.sharpenTexturesharpen_tex_en || other.lodTexturetex_lod_en
|-
| 47:32 || other.tluttlut_en || other.tlutTypetlut_type || other.sampleTypesample_type || other.midTexelmid_texel || other.bilerp[0]bi_lerp_0 || other.bilerp[1]bi_lerp_1 || other.convertOneconvert_one || other.colorKeykey_en || colspan=2| other.colorDitherModergb_dither_sel[1:0] || colspan=2| other.alphaDitherModealpha_dither_sel[1:0] || colspan=4| other.reserved2[3:0]-
|-
| 31:16 || colspan=2| other.blend1a[0]bl_m1a_0[1:0] || colspan=2| other.blend1a[1]bl_m1a_1[1:0] || colspan=2| other.blend1b[0]bl_m1b_0[1:0] || colspan=2| other.blend1b[1]bl_m1b_1[1:0] || colspan=2| other.blend2a[0]bl_m2a_0[1:0] || colspan=2| other.blend2a[1]bl_m2a_1[1:0] || colspan=2| other.blend2b[0]bl_m2b_0[1:0] || colspan=2| other.blend2b[1]bl_m2b_1[1:0]
|-
| 15:0 || other.reserved3- || other.forceBlendforce_blend || other.alphaCoveragealpha_cvg_select || other.coverageXalphacvg_x_alpha || colspan=2| other.zModez_mode[1:0] || colspan=2| other.coverageModecvg_dest[1:0] || other.colorOnCoveragecolor_on_cvg || other.imageReadimage_read_en || other.zUpdatez_update_en || other.zComparez_compare_en || other.antialiasantialias_en || other.zSourcez_source_sel || other.ditherAlphadither_alpha_en || other.alphaComparealpha_compare_en
|}
{{#invoke:Register table|definitions
| 61:56 | command[5:0] | 0x2f
| 55 | atomic_prim | Enables span buffer coherency, forces active span segments to be written to the frame buffer before reading new span segments
| 55 | other.atomicPrimitive | ?
| 54 | other.reserved1- | ?
| 53:52 | cycle_type[1:0] | Determines pipeline mode. Either 1-Cycle (0), 2-Cycle (1), COPY (2), FILL (3)
| 53:52 | other.cycleType[1:0] | -
| 51 | persp_tex_en | Enables perspective correction of texture coordinates
| 51 | other.perspective | ?
| 50 | detail_tex_en | Enables "detail texture" mode in Texture LOD
| 50 | other.detailTexture | ?
| 49 | sharpen_tex_en | Enables "sharpen texture" mode in Texture LOD
| 49 | other.sharpenTexture | ?
| 48 | tex_lod_en | Enables Texture Level of Detail (LOD)
| 48 | other.lodTexture | ?
| 47 | tlut_en | Enables Texture Look-Up Table (TLUT) sampling. Texels are first fetched from low TMEM that are then used to index a palette in high TMEM to find the final color values.
| 47 | other.tlut | ?
| 46 | tlut_type | Determines TLUT texel format. Either RGBA16 (0) or IA16 (1)
| 46 | other.tlutType | ?
| 45 | sample_type | Determines texel sampling mode. Either point-sampled (0) or 2x2 bilinear (1)
| 45 | other.sampleType | ?
| 44 | mid_texel | Determines bilinear filter mode. Either 3-point (0) or average mode (1)
| 44 | other.midTexel | ?
| 43 | bi_lerp_0 | Determines texture filter mode for the first cycle. Either YUV to RGB conversion (See '''Set Convert''') (0) or bilinear filter (1)
| 43 | other.bilerp[0] | ?
| 42 | bi_lerp_1 | Determines texture filter mode for the second cycle. Either YUV to RGB conversion (See '''Set Convert''') (0) or bilinear filter (1)
| 42 | other.bilerp[1] | ?
| 41 | convert_one | Determines the input to the second texture filter stage. Either the sample from the second stage of texture sampling (0) or the result from the first texture filter cycle (1)
| 41 | other.convertOne | ?
| 40 | key_en | Enables chroma keying following the Color Combiner stage
| 40 | other.colorKey | ?
| 39:38 | other.colorDitherModergb_dither_sel[1:0] | -Set RGB dither mode
| 37:36 | other.alphaDitherModealpha_dither_sel[1:0] | -Set Alpha dither mode
| 35:32 | other.reserved2[3:0]- | -?
| 31:30 | other.blend1a[0]bl_m1a_0[1:0] | -Blender input P (first cycle)
| 29:28 | other.blend1a[1]bl_m1a_1[1:0] | -Blender input P (second cycle)
| 27:26 | other.blend1b[0]bl_m1b_0[1:0] | -Blender input A (first cycle)
| 25:24 | other.blend1b[1]bl_m1b_1[1:0] | -Blender input A (second cycle)
| 23:22 | other.blend2a[0]bl_m2a_0[1:0] | -Blender input M (first cycle)
| 21:20 | other.blend2a[1]bl_m2a_1[1:0] | -Blender input M (second cycle)
| 19:18 | other.blend2b[0]bl_m2b_0[1:0] | -Blender input B (first cycle)
| 17:16 | other.blend2b[1]bl_m2b_1[1:0] | -Blender input B (second cycle)
| 15 | other.reserved3- | ?
| 14 | force_blend | Enables blending for all pixels rather than only edge pixels
| 14 | other.forceBlend | ?
| 13 | alpha_cvg_select | Use coverage (or coverage multiplied by CC alpha) for alpha input to blender rather than alpha output from CC
| 13 | other.alphaCoverage | ?
| 12 | cvg_x_alpha | Multiply coverage and alpha from CC (used in conjunction with alpha_cvg_sel)
| 12 | other.coverageXalpha | ?
| 11:10 | other.zModez_mode[1:0] | Determines z-buffer comparator mode
| 9:8 | other.coverageModecvg_dest[1:0] | -Determines coverage output mode
| 7 | color_on_cvg | If enabled, writes the blender output only if coverage overflowed, otherwise write the 2B input verbatim
| 7 | other.colorOnCoverage | ?
| 6 | image_read_en | Enable color image reading
| 6 | other.imageRead | ?
| 5 | z_update_en | Enable z-buffer writing
| 5 | other.zUpdate | ?
| 4 | z_compare_en | Enable z-buffer reading and depth comparison
| 4 | other.zCompare | ?
| 3 | antialias_en | Enable anti-aliasing, which may enable blending on edge pixels
| 3 | other.antialias | ?
| 2 | z_source_sel | Selects either per-pixel (0) or primitive (1) depth as depth source to compare against the z-buffer
| 2 | other.zSource | ?
| 1 | dither_alpha_en | Determines alpha compare threshold source. (0 blend color register alpha, 1 random)
| 1 | other.ditherAlpha | ?
| 0 | alpha_compare_en | Enables alpha compare, pixels below the alpha threshold (compared against CC alpha output) are not written
| 0 | other.alphaCompare | ?
}}
 
Configures the RDP "Other Modes", a collection of global settings.
====<span style="display:none;">0x30 - Load_Texture_LUT ====
 
'''RGB dither modes'''
 
{| class="wikitable"
! Value !! Description
|-
| 0 || 4x4 Magic Square dither matrix
|-
| 1 || 4x4 Bayer dither matrix
|-
| 2 || Random noise
|-
| 3 || Disabled, no dithering applied
|}
 
'''Alpha dither modes'''
 
{| class="wikitable"
! Value !! Description
|-
| 0 || Same pattern as chosen in RGB. If noise was chosen, use magic square. If RGB dither was disabled, use bayer.
|-
| 1 || Inverse of the same pattern as chosen in RGB. Same rules as above if RGB was noise or disabled.
|-
| 2 || Random noise
|-
| 3 || Disabled, no dithering applied
|}
 
'''Z modes'''
 
{| class="wikitable"
! Value !! Description
|-
| 0 || Opaque surface mode.
|-
| 1 || Interpenetrating surface mode.
|-
| 2 || Transparent surface mode.
|-
| 3 || Decal surface mode.
|}
 
'''Coverage destination modes'''
 
{| class="wikitable"
! Value !! Description
|-
| 0 || Clamp. Sums new and old coverage, clamps to full if there is an overflow.
|-
| 1 || Wrap. Sums new and old coverage, writes this sum modulo 8.
|-
| 2 || Full. Always write full coverage.
|-
| 3 || Save. Always write old coverage, discard new coverage. Requires image_read_en, otherwise it will behave like Full.
|}
 
'''Blender Configuration'''
 
Other modes include the blender input configuration. The blender computes either
 
<math>p \cdot a + m \cdot b</math>
 
or
 
<math>\frac{p \cdot a + m \cdot b}{a + b}</math>
 
The latter is performed only when force_blend is disabled and anti-aliasing is enabled, where it is performed only on edge pixels.
 
'''Blender P and M Inputs'''
 
{| class="wikitable"
! Value !! Description
|-
| 0 || First cycle: output color from Color Combiner final stage; Second cycle: output color from first blender cycle
|-
| 1 || Memory color from framebuffer
|-
| 2 || Blend color register RGB
|-
| 3 || Fog color register RGB
|}
 
'''Blender A Inputs'''
 
{| class="wikitable"
! Value !! Description
|-
| 0 || Output alpha from Color Combiner final stage
|-
| 1 || Fog color register Alpha
|-
| 2 || Shade Alpha (interpolated per-pixel)
|-
| 3 || Fixed 0.0
|}
 
'''Blender B Inputs'''
 
{| class="wikitable"
! Value !! Description
|-
| 0 || 1.0 - A, where A is the other alpha input
|-
| 1 || Memory coverage from framebuffer
|-
| 2 || Fixed 1.0
|-
| 3 || Fixed 0.0
|}
 
'''Hazards'''
* This is a pipeline configuration command that requires pipeline synchronization before use, otherwise currently rendering primitives may be partially rendered using both the old other modes configuration and the new other modes configuration.
* Alpha compare in COPY mode targeting 16-bit framebuffers is only valid for RGBA5551 textures, it only considers the least-significant bit in the sampled texel for determining whether to write it.
* Blender hazards:
** If memory color was set as a blender input, image_read_en should be enabled for proper operation.
** If memory coverage was set as a blender input, image_read_en should be enabled for proper operation. If it is left disabled, memory coverage is set to full.
** 2-Cycle mode pipeline bug: In the first cycle of 2-cycle mode, memory color is read from the previous pixel.
** 2-Cycle mode pipeline bug: In the first cycle of 2-cycle mode, memory coverage is read from the previous pixel.
** 2-Cycle mode pipeline bug: In the second cycle of 2-cycle mode, shade alpha is read from the next pixel.
 
=== 0x30 - Load TLUT ===
----
{| class="wikitable" style="text-align: center; white-space:nowrap;"
! colspan="17"|Load_Texture_LUTLoad TLUT <code>0x30</code>
|-
| 63:48 || — || — || colspan=6| command = 0x300x34[5:0] || colspan=8| tlutupper_left.s.lo[11:4]
|-
| 47:32 || colspan=4| tlutupper_left.s.lo[3:0] || colspan=12| tlutupper_left.t.lo[11:0]
|-
| 31:16 || — || — || — || — || — || colspan=3| tlut.indextile[2:0] || colspan=8| tlutlower_right.s.hi[11:4]
|-
| 15:0 || colspan=4| tlutlower_right.s.hi[3:0] || colspan=12| tlutlower_right.t.hi[11:0]
|}
{{#invoke:Register table|definitions
| 61:56 | command[5:0] | 0x30
| 55:44 | tlutupper_left.s.lo[11:0] | Upper-left s coordinate (u10.2)
| 43:32 | tlutupper_left.t.lo[11:0] | Upper-left t coordinate (u10.2)
| 26:24 | tlut.indextile[2:0] | -Tile descriptor index
| 23:12 | tlutlower_right.s.hi[11:0] | Lower-right s coordinate (u10.2)
| 11:0 | tlutlower_right.t.hi[11:0] | Lower-right t coordinate (u10.2)
}}
 
Loads a Texture Look-Up Table (TLUT) into TMEM.
====<span style="display:none;">0x32 - Set Tile Size ====
 
When loading with Load TLUT, every texel loaded from RDRAM is quadrupled and placed adjacently in TMEM. A 256-color TLUT therefore takes up <math>\mathrm{256} \times \mathrm{2} \times \mathrm{4} = \mathrm{0x800}</math> bytes of TMEM, which is the maximum size of a TLUT as it must fit in high TMEM. A 16-color TLUT takes up only <math>\mathrm{16} \times \mathrm{2} \times \mathrm{4} = \mathrm{0x80}</math> bytes of TMEM, 16 of these may reside in high TMEM at the same time.
 
Typical usage of Load TLUT may resemble <code>(uls=0, ult=0, lrs=count-1, lrt=0)</code> where <code>count</code> is the number of texels making up the TLUT, e.g. 255 for a 256-color palette.
 
'''Hazards'''
* For correct sampling, the base TMEM address for a TLUT must reside in the upper half of TMEM, that is at TMEM word address 0x100 (byte address 0x800) or greater.
* For correct sampling, the base TMEM address for a TLUT must be aligned to 16 TMEM words or 128 bytes.
 
=== 0x32 - Set Tile Size ===
----
{| class="wikitable" style="text-align: center; white-space:nowrap;"
Line 799 ⟶ 947:
{{#invoke:Register table|definitions
| 61:56 | command[5:0] | 0x32
| 55:44 | upper_left.s[11:0] | Upper-left s coordinate (u10.2 format)
| 43:32 | upper_left.t[11:0] | Upper-left t coordinate (u10.2 format)
| 26:24 | index[2:0] | Tile descriptor index
| 23:12 | lower_right.s[11:0] | Lower-right s coordinate (u10.2 format)
| 11:0 | lower_right.t[11:0] | Lower-right t coordinate (u10.2 format)
}}
 
Line 812 ⟶ 960:
The lower-right coordinate specifies the upper extents for clamp/mask/mirror in texture sampling.
 
====<span style="display:none;">0x33 - Load_BlockLoad Block ====
----
{| class="wikitable" style="text-align: center; white-space:nowrap;"
! colspan="17"|Load_BlockLoad Block <code>0x33</code>
|-
| 63:48 || — || — || colspan=6| command = 0x33[5:0] || colspan=8| load_.blockupper_left.s.lo[11:4]
|-
| 47:32 || colspan=4| load_.blockupper_left.s.lo[3:0] || colspan=12| load_.blockupper_left.t.lo[11:0]
|-
| 31:16 || — || — || — || — || — || colspan=3| load_.block.indextile[2:0] || colspan=8| load_.blocklower_right.s.hi[11:4]
|-
| 15:0 || colspan=4| load_.blocklower_right.s.hi[3:0] || colspan=12| load_.block.t.hidxt[11:0]
|}
{{#invoke:Register table|definitions
| 61:56 | command[5:0] | 0x33
| 55:44 | load_.blockupper_left.s.lo[11:0] | Upper-left s coordinate (u10.2)
| 43:32 | load_.blockupper_left.t.lo[11:0] | Upper-left t coordinate (u10.2)
| 26:24 | load_.block.indextile[2:0] | -Tile descriptor index
| 23:12 | load_.blocklower_right.s.hi[11:0] | Lower-right s coordinate (u10.2)
| 11:0 | load_.block.t.hidxt[11:0] | -Change in x per t (u1.11)
}}
 
Load Block loads texels to the TMEM address specified by the selected tile descriptor from the RDRAM location pointed to by the current texture image (see '''Set Texture Image''').
====<span style="display:none;">0x34 - Load_Tile ====
 
Only 2048 texels of any size can be loaded at once, loads configured to read more than 2048 texels will fail resulting in nothing being written into TMEM. For 4 and 8 bit types the texture image texel size can be set to 16-bit to facilitate loading more than 2048 texels, it is not possible to use the 32-bit texel size in this way without advance preparation as 32-bit texels have a different TMEM layout. <code>lower_right.s - upper_left.s</code> determines the number of texels to load.
 
Load Block is the fastest way to move data from RDRAM into TMEM, however not all width/height combinations are valid. Texture lines loaded with Load Block must be a multiple of 64 bits in size, either naturally or by explicitly padding each line in RDRAM. Further, for a given width there is a maximum height based on imprecision in the dxt value. For each 64-bit TMEM word loaded with Load Block, an internal counter is incremented by dxt. This counter can be thought of as a 1.11 fixed-point value; when the counter holds a value greater than one the current word being loaded belongs to an odd-numbered line, otherwise it belongs to an even-numbered line. For texture sampling reasons odd lines must have their 32-bit words swapped when loaded from RDRAM, this is done automatically by the loading hardware hence why it tracks which lines are even or odd. However if dxt is sufficiently imprecise the counter may miss a word at the end of a line, leading to corruptions as that word will not be swapped correctly.
 
'''Hazards'''
* Some texture image addresses may hang the RDP if an attempt is made to load from it. See '''Set Texture Image''' hazards.
* Load Block sets the tile size for the associated tile descriptor to (upper_left.s, upper_left.t, lower_right.s, dxt). This is generally not a useful configuration for rendering the image.
 
=== 0x34 - Load Tile ===
----
{| class="wikitable" style="text-align: center; white-space:nowrap;"
! colspan="17"|Load_TileLoad Tile <code>0x34</code>
|-
| 63:48 || — || — || colspan=6| command = 0x34[5:0] || colspan=8| load_.tileupper_left.s.lo[11:4]
|-
| 47:32 || colspan=4| load_.tileupper_left.s.lo[3:0] || colspan=12| load_.tileupper_left.t.lo[11:0]
|-
| 31:16 || — || — || — || — || — || colspan=3| load_.tile.index[2:0] || colspan=8| load_.tilelower_right.s.hi[11:4]
|-
| 15:0 || colspan=4| load_.tilelower_right.s.hi[3:0] || colspan=12| load_.tilelower_right.t.hi[11:0]
|}
{{#invoke:Register table|definitions
| 61:56 | command[5:0] | 0x34
| 55:44 | load_.tileupper_left.s.lo[11:0] | Upper-left s coordinate (u10.2)
| 43:32 | load_.tileupper_left.t.lo[11:0] | Upper-left t coordinate (u10.2)
| 26:24 | load_.tile.index[2:0] | -Tile descriptor index
| 23:12 | load_.tilelower_right.s.hi[11:0] | Lower-right s coordinate (u10.2)
| 11:0 | load_.tilelower_right.t.hi[11:0] | Lower-right t coordinate (u10.2)
}}
 
Load Tile loads an arbitrary rectangle of texels to the TMEM address specified by the selected tile descriptor from the RDRAM location pointed to by the current texture image (see '''Set Texture Image'''). The rectangle in RDRAM to load from is specified by the provided upper_left and lower_right coordinates and the line parameter in the tile descriptor, the RDRAM width is <code>lower_right.s - upper_left.s</code> while the TMEM width is the tile line parameter. The upper_left location in RDRAM is mapped to the tile TMEM address.
====<span style="display:none;">0x35 - Set Tile ====
 
Load Tile is slower than Load Block, however it is more flexible as there is no need to explicitly pad texture lines in RDRAM to 8-byte boundaries, and there are no issues with word-swapping.
 
Load Tile updates the tile size for the selected tile descriptor to <code>(upper_left.s, upper_left.t, lower_right.s, lower_right.t)</code> which may be used for subsequent rendering.
 
'''Hazards'''
* The texel size specified in Set Texture Image should match the texel size in the tile descriptor used for loading, otherwise operation is not guaranteed.
* Loads that extend past the end of TMEM will wrap back to the start.
 
=== 0x35 - Set Tile ===
----
{| class="wikitable" style="text-align: center; white-space:nowrap;"
Line 965 ⟶ 1,133:
|}
 
====<span style="display:none;">0x36 - Fill Rectangle ====
----
{| class="wikitable" style="text-align: center; white-space:nowrap;"
Line 1,000 ⟶ 1,168:
* In COPY mode, fill rectangle behaves like texture rectangle with all texture attributes (tile, s, t, dsdx, dtdy) set to 0. (TOVERIFY: as above, is it always 0 or is it left over values from previous primitives?)
 
====<span style="display:none;">0x37 - Set Fill Color ====
----
{| class="wikitable" style="text-align: center; white-space:nowrap;"
Line 1,029 ⟶ 1,197:
* This is an attribute-setting command that requires pipeline synchronization before use, otherwise currently rendering primitives may be partially rendered using both the old fill color and the new fill color, if it was used.
 
====<span style="display:none;">0x38 - Set Fog Color ====
----
{| class="wikitable" style="text-align: center; white-space:nowrap;"
Line 1,057 ⟶ 1,225:
* This is an attribute-setting command that requires pipeline synchronization before use, otherwise currently rendering primitives may be partially rendered using both the old fog color and the new fog color, if it was used.
 
====<span style="display:none;">0x39 - Set Blend Color ====
----
{| class="wikitable" style="text-align: center; white-space:nowrap;"
Line 1,085 ⟶ 1,253:
* This is an attribute-setting command that requires pipeline synchronization before use, otherwise currently rendering primitives may be partially rendered using both the old blend color and the new blend color, if it was used.
 
====<span style="display:none;">0x3a0x3A - Set Primitive Color ====
----
{| class="wikitable" style="text-align: center; white-space:nowrap;"
Line 1,124 ⟶ 1,292:
Unlike the majority of other attribute-setters, primitive color operates correctly even in the absence of pipeline synchronizations. The primitive color may be changed between primitive rendering without corrupting prior primitives.
 
====<span style="display:none;">0x3b0x3B - Set Environment Color ====
----
{| class="wikitable" style="text-align: center; white-space:nowrap;"
Line 1,152 ⟶ 1,320:
* This is an attribute-setting command that requires pipeline synchronization before use, otherwise currently rendering primitives may be partially rendered using both the old environment color and the new environment color, if it was used.
 
====<span style="display:none;">0x3c0x3C - Set Combine Mode ====
----
{| class="wikitable" style="text-align: center; white-space:nowrap;"
Line 1,409 ⟶ 1,577:
* The 1 input is valued at 256, not 255. This may contribute to overflow issues.
 
====<span style="display:none;">0x3d0x3D - Set Texture Image ====
----
{| class="wikitable" style="text-align: center; white-space:nowrap;"
Line 1,467 ⟶ 1,635:
* Memory alignment should be 8-byte to guarantee operation. If the address falls into the range [1,7] mod 64, the RDP may hang when loading from it.
 
====<span style="display:none;">0x3e0x3E - Set Depth Image ====
----
{| class="wikitable" style="text-align: center; white-space:nowrap;"
Line 1,491 ⟶ 1,659:
* Memory alignment must be 64-byte for all rendering operations to behave as expected.
 
====<span style="display:none;">0x3f0x3F - Set Color Image ====
----
{| class="wikitable" style="text-align: center; white-space:nowrap;"
56

edits