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