libdragon
Loading...
Searching...
No Matches
rdpq_rect.h
Go to the documentation of this file.
1
8#ifndef LIBDRAGON_RDPQ_RECT_H
9#define LIBDRAGON_RDPQ_RECT_H
10
11#include "rdpq.h"
12
13#ifdef __cplusplus
14extern "C" {
15#endif
16
17// Internal functions used for inline optimizations. Not part of the public API.
18// Do not call directly
20#define __UNLIKELY(x) __builtin_expect(!!(x), 0)
21
22__attribute__((always_inline))
23inline void __rdpq_fill_rectangle_inline(int32_t x0, int32_t y0, int32_t x1, int32_t y1) {
24 if (__UNLIKELY(x0 < 0)) x0 = 0;
25 if (__UNLIKELY(y0 < 0)) y0 = 0;
26 if (__UNLIKELY(x1 > 0xFFF)) x1 = 0xFFF;
27 if (__UNLIKELY(y1 > 0xFFF)) y1 = 0xFFF;
28 if (__UNLIKELY(x0+3 >= x1 || y0+3 >= y1)) return;
29
30 extern void __rdpq_fill_rectangle(uint32_t w0, uint32_t w1);
32 _carg(x1, 0xFFF, 12) | _carg(y1, 0xFFF, 0),
33 _carg(x0, 0xFFF, 12) | _carg(y0, 0xFFF, 0));
34}
35
36__attribute__((always_inline))
37inline void __rdpq_texture_rectangle_inline(rdpq_tile_t tile,
38 int32_t x0, int32_t y0, int32_t x1, int32_t y1,
39 int32_t s0, int32_t t0)
40{
41 if (__UNLIKELY(x1 == x0 || y1 == y0)) return;
42 int32_t dsdx = 1<<10, dtdy = 1<<10;
43
44 if (__UNLIKELY(x0 > x1)) {
45 int32_t tmp = x0; x0 = x1; x1 = tmp;
46 x0 += 4; x1 += 4;
47 s0 += (x1 - x0 - 4) << 3;
48 dsdx = -dsdx;
49 }
50 if (__UNLIKELY(y0 > y1)) {
51 int32_t tmp = y0; y0 = y1; y1 = tmp;
52 y0 += 4; y1 += 4;
53 t0 += (y1 - y0 - 4) << 3;
54 dtdy = -dtdy;
55 }
56 if (__UNLIKELY(x0 < 0)) {
57 s0 -= (x0 * dsdx) >> 7;
58 x0 = 0;
59 if (__UNLIKELY(x0 >= x1)) return;
60 }
61 if (__UNLIKELY(y0 < 0)) {
62 t0 -= (y0 * dtdy) >> 7;
63 y0 = 0;
64 if (__UNLIKELY(y0 >= y1)) return;
65 }
66 if (__UNLIKELY(x1 > 1024*4-1)) {
67 x1 = 1024*4-1;
68 if (__UNLIKELY(x0 >= x1)) return;
69 }
70 if (__UNLIKELY(y1 > 1024*4-1)) {
71 y1 = 1024*4-1;
72 if (__UNLIKELY(y0 >= y1)) return;
73 }
74
75 extern void __rdpq_texture_rectangle(uint32_t w0, uint32_t w1, uint32_t w2, uint32_t w3);
77 _carg(x1, 0xFFF, 12) | _carg(y1, 0xFFF, 0),
78 _carg(tile, 0x7, 24) | _carg(x0, 0xFFF, 12) | _carg(y0, 0xFFF, 0),
79 _carg(s0, 0xFFFF, 16) | _carg(t0, 0xFFFF, 0),
80 _carg(dsdx, 0xFFFF, 16) | _carg(dtdy, 0xFFFF, 0));
81}
82
83__attribute__((always_inline))
84inline void __rdpq_texture_rectangle_scaled_inline(rdpq_tile_t tile,
85 int32_t x0, int32_t y0, int32_t x1, int32_t y1,
86 int32_t s0, int32_t t0, int32_t s1, int32_t t1)
87{
88 if (__UNLIKELY(x1 == x0 || y1 == y0)) return;
89 int32_t dsdx = ((s1 - s0) << 7) / (x1 - x0), dtdy = ((t1 - t0) << 7) / (y1 - y0);
90
91 if (__UNLIKELY(x0 > x1)) {
92 int32_t tmp = x0; x0 = x1; x1 = tmp;
93 s0 += ((x0 - x1 - 4) * dsdx) >> 7;
94 }
95 if (__UNLIKELY(y0 > y1)) {
96 int32_t tmp = y0; y0 = y1; y1 = tmp;
97 t0 += ((y0 - y1 - 4) * dtdy) >> 7;
98 }
99 if (__UNLIKELY(x0 < 0)) {
100 s0 -= (x0 * dsdx) >> 7;
101 x0 = 0;
102 if (__UNLIKELY(x0 >= x1)) return;
103 }
104 if (__UNLIKELY(y0 < 0)) {
105 t0 -= (y0 * dtdy) >> 7;
106 y0 = 0;
107 if (__UNLIKELY(y0 >= y1)) return;
108 }
109 if (__UNLIKELY(x1 > 1024*4-1)) {
110 s1 -= ((x1 - 1024*4-1) * dsdx) >> 7;
111 x1 = 1024*4-1;
112 if (__UNLIKELY(x0 >= x1)) return;
113 }
114 if (__UNLIKELY(y1 > 1024*4-1)) {
115 t1 -= ((y1 - 1024*4-1) * dtdy) >> 7;
116 y1 = 1024*4-1;
117 if (__UNLIKELY(y0 >= y1)) return;
118 }
119
120 extern void __rdpq_texture_rectangle(uint32_t w0, uint32_t w1, uint32_t w2, uint32_t w3);
122 _carg(x1, 0xFFF, 12) | _carg(y1, 0xFFF, 0),
123 _carg(tile, 0x7, 24) | _carg(x0, 0xFFF, 12) | _carg(y0, 0xFFF, 0),
124 _carg(s0, 0xFFFF, 16) | _carg(t0, 0xFFFF, 0),
125 _carg(dsdx, 0xFFFF, 16) | _carg(dtdy, 0xFFFF, 0));
126}
127
128inline void __rdpq_fill_rectangle_fx(int32_t x0, int32_t y0, int32_t x1, int32_t y1)
129{
130 if (__builtin_constant_p(x0) && __builtin_constant_p(y0) && __builtin_constant_p(x1) && __builtin_constant_p(y1)) {
131 __rdpq_fill_rectangle_inline(x0, y0, x1, y1);
132 } else {
133 extern void __rdpq_fill_rectangle_offline(int32_t x0, int32_t y0, int32_t x1, int32_t y1);
134 __rdpq_fill_rectangle_offline(x0, y0, x1, y1);
135 }
136}
137
138inline void __rdpq_texture_rectangle_fx(rdpq_tile_t tile, int32_t x0, int32_t y0, int32_t x1, int32_t y1, int32_t s, int32_t t)
139{
140 if (__builtin_constant_p(x0) && __builtin_constant_p(y0) && __builtin_constant_p(x1) && __builtin_constant_p(y1)) {
141 __rdpq_texture_rectangle_inline(tile, x0, y0, x1, y1, s, t);
142 } else {
143 extern void __rdpq_texture_rectangle_offline(rdpq_tile_t tile, int32_t x0, int32_t y0, int32_t x1, int32_t y1, int32_t s0, int32_t t0);
144 __rdpq_texture_rectangle_offline(tile, x0, y0, x1, y1, s, t);
145 }
146}
147
148inline void __rdpq_texture_rectangle_scaled_fx(rdpq_tile_t tile, int32_t x0, int32_t y0, int32_t x1, int32_t y1, int32_t s0, int32_t t0, int32_t s1, int32_t t1)
149{
150 if (__builtin_constant_p(x0) && __builtin_constant_p(y0) && __builtin_constant_p(x1) && __builtin_constant_p(y1)) {
151 __rdpq_texture_rectangle_scaled_inline(tile, x0, y0, x1, y1, s0, t0, s1, t1);
152 } else {
153 extern void __rdpq_texture_rectangle_scaled_offline(rdpq_tile_t tile, int32_t x0, int32_t y0, int32_t x1, int32_t y1, int32_t s0, int32_t t0, int32_t s1, int32_t t1);
154 __rdpq_texture_rectangle_scaled_offline(tile, x0, y0, x1, y1, s0, t0, s1, t1);
155 }
156}
157
158inline void __rdpq_texture_rectangle_raw_fx(rdpq_tile_t tile, uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint16_t s0, uint16_t t0, int16_t dsdx, int16_t dtdy)
159{
160 extern void __rdpq_texture_rectangle(uint32_t w0, uint32_t w1, uint32_t w2, uint32_t w3);
162 _carg(x1, 0xFFF, 12) | _carg(y1, 0xFFF, 0),
163 _carg(tile, 0x7, 24) | _carg(x0, 0xFFF, 12) | _carg(y0, 0xFFF, 0),
164 _carg(s0, 0xFFFF, 16) | _carg(t0, 0xFFFF, 0),
165 _carg(dsdx, 0xFFFF, 16) | _carg(dtdy, 0xFFFF, 0));
166}
167
168inline void __rdpq_texture_rectangle_flip_raw_fx(rdpq_tile_t tile, uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, int16_t s, int16_t t, int16_t dsdy, int16_t dtdx)
169{
170 extern void __rdpq_write16_syncuse(uint32_t, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t);
171
172 // Note that this command is broken in copy mode, so it doesn't
173 // require any fixup. The RSP will trigger an assert if this
174 // is called in such a mode.
175 __rdpq_write16_syncuse(RDPQ_CMD_TEXTURE_RECTANGLE_FLIP,
176 _carg(x1, 0xFFF, 12) | _carg(y1, 0xFFF, 0),
177 _carg(tile, 0x7, 24) | _carg(x0, 0xFFF, 12) | _carg(y0, 0xFFF, 0),
178 _carg(s, 0xFFFF, 16) | _carg(t, 0xFFFF, 0),
179 _carg(dsdy, 0xFFFF, 16) | _carg(dtdx, 0xFFFF, 0),
180 AUTOSYNC_PIPE | AUTOSYNC_TILE(tile) | AUTOSYNC_TMEM(0));
181}
182#undef __UNLIKELY
184
250#define rdpq_fill_rectangle(x0, y0, x1, y1) ({ \
251 __rdpq_fill_rectangle_fx((x0)*4, (y0)*4, (x1)*4, (y1)*4); \
252})
253
309#define rdpq_texture_rectangle(tile, x0, y0, x1, y1, s, t) \
310 __rdpq_texture_rectangle_fx((tile), (x0)*4, (y0)*4, (x1)*4, (y1)*4, (s)*32, (t)*32)
311
333#define rdpq_texture_rectangle_scaled(tile, x0, y0, x1, y1, s0, t0, s1, t1) \
334 __rdpq_texture_rectangle_scaled_fx((tile), (x0)*4, (y0)*4, (x1)*4, (y1)*4, (s0)*32, (t0)*32, (s1)*32, (t1)*32)
335
336
377#define rdpq_texture_rectangle_raw(tile, x0, y0, x1, y1, s0, t0, dsdx, dtdy) \
378 __rdpq_texture_rectangle_raw_fx(tile, (x0)*4, (y0)*4, (x1)*4, (y1)*4, (s0)*32, (t0)*32, (dsdx)*1024, (dtdy)*1024)
379
380
406#define rdpq_texture_rectangle_flip_raw(tile, x0, y0, x1, y1, s, t, dsdy, dtdx) ({ \
407 __rdpq_texture_rectangle_flip_raw_fx((tile), (x0)*4, (y0)*4, (x1)*4, (y1)*4, (s)*32, (t)*32, (dsdy)*1024, (dtdx)*1024); \
408})
409
410
415#ifdef __cplusplus
416}
417#endif
418
419#endif
void __rdpq_write16_syncuse(uint32_t cmd_id, uint32_t arg0, uint32_t arg1, uint32_t arg2, uint32_t arg3, uint32_t autosync)
Write a standard 16-byte RDP command, which uses some autosync resources
Definition rdpq.c:944
RDP Command queue.
rdpq_tile_t
Tile descriptors.
Definition rdpq.h:250
void __rdpq_fill_rectangle(uint32_t w0, uint32_t w1)
Out-of-line implementation of rdpq_texture_rectangle.
Definition rdpq_rect.c:23
void __rdpq_texture_rectangle_offline(rdpq_tile_t tile, int32_t x0, int32_t y0, int32_t x1, int32_t y1, int32_t s0, int32_t t0)
Out of line implementation of rdpq_texture_rectangle.
Definition rdpq_rect.c:62
void __rdpq_texture_rectangle_scaled_offline(rdpq_tile_t tile, int32_t x0, int32_t y0, int32_t x1, int32_t y1, int32_t s0, int32_t t0, int32_t s1, int32_t t1)
Out of line implementation of rdpq_texture_rectangle_scaled.
Definition rdpq_rect.c:67
void __rdpq_texture_rectangle(uint32_t w0, uint32_t w1, uint32_t w2, uint32_t w3)
Out-of-line implementation of rdpq_texture_rectangle.
Definition rdpq_rect.c:43
void __rdpq_fill_rectangle_offline(int32_t x0, int32_t y0, int32_t x1, int32_t y1)
Out of line implementation of rdpq_fill_rectangle.
Definition rdpq_rect.c:37