c7cb93d0ac221f5ae628fffd84f4e14a2d911e61
[mesa.git] / src / mesa / drivers / dri / r300 / r300_emit.h
1 #ifndef __EMIT_H__
2 #define __EMIT_H__
3 #include "glheader.h"
4 #include "r300_context.h"
5 #include "r300_cmdbuf.h"
6
7 /* convenience macros */
8 #define RADEON_CP_PACKET0 0x00000000
9 #define RADEON_CP_PACKET1 0x40000000
10 #define RADEON_CP_PACKET2 0x80000000
11 #define RADEON_CP_PACKET3 0xC0000000
12
13 #define RADEON_CP_PACKET3_NOP 0xC0001000
14 #define RADEON_CP_PACKET3_NEXT_CHAR 0xC0001900
15 #define RADEON_CP_PACKET3_UNK1B 0xC0001B00
16 #define RADEON_CP_PACKET3_PLY_NEXTSCAN 0xC0001D00
17 #define RADEON_CP_PACKET3_SET_SCISSORS 0xC0001E00
18 #define RADEON_CP_PACKET3_3D_RNDR_GEN_INDX_PRIM 0xC0002300
19 #define RADEON_CP_PACKET3_LOAD_MICROCODE 0xC0002400
20 #define RADEON_CP_PACKET3_WAIT_FOR_IDLE 0xC0002600
21 #define RADEON_CP_PACKET3_3D_DRAW_VBUF 0xC0002800
22 #define RADEON_CP_PACKET3_3D_DRAW_IMMD 0xC0002900
23 #define RADEON_CP_PACKET3_3D_DRAW_INDX 0xC0002A00
24 #define RADEON_CP_PACKET3_LOAD_PALETTE 0xC0002C00
25 #define RADEON_CP_PACKET3_INDX_BUFFER 0xC0003300
26 #define RADEON_CP_PACKET3_3D_DRAW_VBUF_2 0xC0003400
27 #define RADEON_CP_PACKET3_3D_DRAW_IMMD_2 0xC0003500
28 #define RADEON_CP_PACKET3_3D_DRAW_INDX_2 0xC0003600
29 #define RADEON_CP_PACKET3_3D_LOAD_VBPNTR 0xC0002F00
30 #define RADEON_CP_PACKET3_CNTL_PAINT 0xC0009100
31 #define RADEON_CP_PACKET3_CNTL_BITBLT 0xC0009200
32 #define RADEON_CP_PACKET3_CNTL_SMALLTEXT 0xC0009300
33 #define RADEON_CP_PACKET3_CNTL_HOSTDATA_BLT 0xC0009400
34 #define RADEON_CP_PACKET3_CNTL_POLYLINE 0xC0009500
35 #define RADEON_CP_PACKET3_CNTL_POLYSCANLINES 0xC0009800
36 #define RADEON_CP_PACKET3_CNTL_PAINT_MULTI 0xC0009A00
37 #define RADEON_CP_PACKET3_CNTL_BITBLT_MULTI 0xC0009B00
38 #define RADEON_CP_PACKET3_CNTL_TRANS_BITBLT 0xC0009C00
39 #define RADEON_CP_PACKET3_3D_CLEAR_ZMASK 0xC0003202
40 #define RADEON_CP_PACKET3_3D_CLEAR_CMASK 0xC0003802
41 #define RADEON_CP_PACKET3_3D_CLEAR_HIZ 0xC0003702
42
43 #define CP_PACKET0(reg, n) (RADEON_CP_PACKET0 | ((n)<<16) | ((reg)>>2))
44
45 /* Glue to R300 Mesa driver */
46 #define LOCAL_VARS int cmd_reserved=0;\
47 int cmd_written=0; \
48 drm_radeon_cmd_header_t *cmd=NULL;
49
50 #define PREFIX_VOID r300ContextPtr rmesa
51
52 #define PREFIX PREFIX_VOID ,
53
54 #define PASS_PREFIX_VOID rmesa
55 #define PASS_PREFIX rmesa ,
56
57 typedef GLuint CARD32;
58
59 /* This files defines functions for accessing R300 hardware.
60 It needs to be customized to whatever code r300_lib.c is used
61 in */
62
63 void static inline check_space(int dwords)
64 {
65 }
66
67 static __inline__ uint32_t cmdpacket0(int reg, int count)
68 {
69 drm_r300_cmd_header_t cmd;
70
71 cmd.packet0.cmd_type = R300_CMD_PACKET0;
72 cmd.packet0.count = count;
73 cmd.packet0.reghi = ((unsigned int)reg & 0xFF00) >> 8;
74 cmd.packet0.reglo = ((unsigned int)reg & 0x00FF);
75
76 return cmd.u;
77 }
78
79 static __inline__ uint32_t cmdvpu(int addr, int count)
80 {
81 drm_r300_cmd_header_t cmd;
82
83 cmd.vpu.cmd_type = R300_CMD_VPU;
84 cmd.vpu.count = count;
85 cmd.vpu.adrhi = ((unsigned int)addr & 0xFF00) >> 8;
86 cmd.vpu.adrlo = ((unsigned int)addr & 0x00FF);
87
88 return cmd.u;
89 }
90
91 static __inline__ uint32_t cmdpacket3(int packet)
92 {
93 drm_r300_cmd_header_t cmd;
94
95 cmd.packet3.cmd_type = R300_CMD_PACKET3;
96 cmd.packet3.packet = packet;
97
98 return cmd.u;
99 }
100
101 static __inline__ uint32_t cmdcpdelay(unsigned short count)
102 {
103 drm_r300_cmd_header_t cmd;
104
105 cmd.delay.cmd_type = R300_CMD_CP_DELAY;
106 cmd.delay.count = count;
107
108 return cmd.u;
109 }
110
111 static __inline__ uint32_t cmdwait(unsigned char flags)
112 {
113 drm_r300_cmd_header_t cmd;
114
115 cmd.wait.cmd_type = R300_CMD_WAIT;
116 cmd.wait.flags = flags;
117
118 return cmd.u;
119 }
120
121 static __inline__ uint32_t cmdpacify(void)
122 {
123 drm_r300_cmd_header_t cmd;
124
125 cmd.header.cmd_type = R300_CMD_END3D;
126
127 return cmd.u;
128 }
129
130 /* Prepare to write a register value to register at address reg.
131 If num_extra > 0 then the following extra values are written
132 to registers with address +4, +8 and so on.. */
133 #define reg_start(reg, num_extra) \
134 { \
135 int _n; \
136 _n=(num_extra); \
137 cmd=(drm_radeon_cmd_header_t *) r300AllocCmdBuf(rmesa, \
138 (_n+2), \
139 __FUNCTION__); \
140 cmd_reserved=_n+2; \
141 cmd_written=1; \
142 cmd[0].i=cmdpacket0((reg), _n+1); \
143 }
144
145 /* Prepare to write a register value to register at address reg.
146 If num_extra > 0 then the following extra values are written
147 into the same register. */
148 /* It is here to permit r300_lib to compile and link anyway, but
149 complain if actually called */
150 #define reg_start_pump(reg, num_extra) \
151 { \
152 fprintf(stderr, "I am not defined.. Error ! in %s::%s at line %d\n", \
153 __FILE__, __FUNCTION__, __LINE__); \
154 exit(-1); \
155 }
156
157 /* Emit CARD32 freestyle*/
158 #define e32(dword) { \
159 if(cmd_written<cmd_reserved){\
160 cmd[cmd_written].i=(dword); \
161 cmd_written++; \
162 } else { \
163 fprintf(stderr, "e32 but no previous packet declaration.. Aborting! in %s::%s at line %d, cmd_written=%d cmd_reserved=%d\n", \
164 __FILE__, __FUNCTION__, __LINE__, cmd_written, cmd_reserved); \
165 exit(-1); \
166 } \
167 }
168
169 #define efloat(f) e32(r300PackFloat32(f))
170
171 #define vsf_start_fragment(dest, length) \
172 { \
173 int _n; \
174 _n=(length); \
175 cmd=(drm_radeon_cmd_header_t *) r300AllocCmdBuf(rmesa, \
176 (_n+1), \
177 __FUNCTION__); \
178 cmd_reserved=_n+2; \
179 cmd_written=1; \
180 cmd[0].i=cmdvpu((dest), _n/4); \
181 }
182
183 #define start_packet3(packet, count) \
184 { \
185 int _n; \
186 CARD32 _p; \
187 _n=(count); \
188 _p=(packet); \
189 cmd=(drm_radeon_cmd_header_t *) r300AllocCmdBuf(rmesa, \
190 (_n+3), \
191 __FUNCTION__); \
192 cmd_reserved=_n+3; \
193 cmd_written=2; \
194 if(_n>0x3fff) {\
195 fprintf(stderr,"Too big packet3 %08x: cannot store %d dwords\n", \
196 _p, _n); \
197 exit(-1); \
198 } \
199 cmd[0].i=cmdpacket3(R300_CMD_PACKET3_RAW); \
200 cmd[1].i=_p | ((_n & 0x3fff)<<16); \
201 }
202
203 /* must be sent to switch to 2d commands */
204
205 void static inline end_3d(PREFIX_VOID)
206 {
207 LOCAL_VARS
208 (void)cmd_reserved; (void)cmd_written;
209
210 cmd=(drm_radeon_cmd_header_t *) r300AllocCmdBuf(rmesa, \
211 1, \
212 __FUNCTION__); \
213
214 cmd[0].header.cmd_type=R300_CMD_END3D;
215 }
216
217 void static inline cp_delay(PREFIX unsigned short count)
218 {
219 LOCAL_VARS
220 (void)cmd_reserved; (void)cmd_written;
221
222 cmd=(drm_radeon_cmd_header_t *) r300AllocCmdBuf(rmesa, \
223 1, \
224 __FUNCTION__); \
225
226 cmd[0].i=cmdcpdelay(count);
227 }
228
229 void static inline cp_wait(PREFIX unsigned char flags)
230 {
231 LOCAL_VARS
232 (void)cmd_reserved; (void)cmd_written;
233
234 cmd=(drm_radeon_cmd_header_t *) r300AllocCmdBuf(rmesa, \
235 1, \
236 __FUNCTION__); \
237
238 cmd[0].i=cmdwait(flags);
239 }
240
241 /* fire vertex buffer */
242 static void inline fire_AOS(PREFIX int vertex_count, int type)
243 {
244 LOCAL_VARS
245 check_space(9);
246
247 start_packet3(RADEON_CP_PACKET3_3D_DRAW_VBUF_2, 0);
248 /* e32(0x840c0024); */
249 e32(R300_VAP_VF_CNTL__PRIM_WALK_VERTEX_LIST | (vertex_count<<16) | type);
250 }
251
252 /* these are followed by the corresponding data */
253 #define start_index32_packet(vertex_count, type) \
254 {\
255 int _vc;\
256 _vc=(vertex_count); \
257 start_packet3(RADEON_CP_PACKET3_3D_DRAW_INDX_2, _vc); \
258 e32(R300_VAP_VF_CNTL__PRIM_WALK_INDICES | (_vc<<16) | type \
259 | R300_VAP_VF_CNTL__INDEX_SIZE_32bit); \
260 }
261
262 #define start_index16_packet(vertex_count, type) \
263 {\
264 int _vc, _n;\
265 _vc=(vertex_count); \
266 _n=(vertex_count+1)>>1; \
267 start_packet3(RADEON_CP_PACKET3_3D_DRAW_INDX_2, _n); \
268 e32(R300_VAP_VF_CNTL__PRIM_WALK_INDICES | (_vc<<16) | type); \
269 }
270
271 /* Interestingly enough this ones needs the call to setup_AOS, even thought
272 some of the data so setup is not needed and some is not as arbitrary
273 as when used by DRAW_VBUF_2 or DRAW_INDX_2 */
274 #define start_immediate_packet(vertex_count, type, vertex_size) \
275 {\
276 int _vc; \
277 _vc=(vertex_count); \
278 start_packet3(RADEON_CP_PACKET3_3D_DRAW_IMMD_2, _vc*(vertex_size)); \
279 e32(R300_VAP_VF_CNTL__PRIM_WALK_VERTEX_EMBEDDED | (_vc<<16) | type); \
280 }
281
282 #endif