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