Add a convenience function to issue CP delays.
[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_3D_DRAW_VBUF_2 0xC0003400
25 #define RADEON_CP_PACKET3_3D_DRAW_IMMD_2 0xC0003500
26 #define RADEON_CP_PACKET3_3D_DRAW_INDX_2 0xC0003600
27 #define RADEON_CP_PACKET3_3D_LOAD_VBPNTR 0xC0002F00
28 #define RADEON_CP_PACKET3_CNTL_PAINT 0xC0009100
29 #define RADEON_CP_PACKET3_CNTL_BITBLT 0xC0009200
30 #define RADEON_CP_PACKET3_CNTL_SMALLTEXT 0xC0009300
31 #define RADEON_CP_PACKET3_CNTL_HOSTDATA_BLT 0xC0009400
32 #define RADEON_CP_PACKET3_CNTL_POLYLINE 0xC0009500
33 #define RADEON_CP_PACKET3_CNTL_POLYSCANLINES 0xC0009800
34 #define RADEON_CP_PACKET3_CNTL_PAINT_MULTI 0xC0009A00
35 #define RADEON_CP_PACKET3_CNTL_BITBLT_MULTI 0xC0009B00
36 #define RADEON_CP_PACKET3_CNTL_TRANS_BITBLT 0xC0009C00
37 #define RADEON_CP_PACKET3_3D_CLEAR_ZMASK 0xC0003202
38 #define RADEON_CP_PACKET3_3D_CLEAR_CMASK 0xC0003802
39 #define RADEON_CP_PACKET3_3D_CLEAR_HIZ 0xC0003702
40
41 #define CP_PACKET0(reg, n) (RADEON_CP_PACKET0 | ((n)<<16) | ((reg)>>2))
42
43 /* Glue to R300 Mesa driver */
44 #define LOCAL_VARS int cmd_reserved=0;\
45 int cmd_written=0; \
46 drm_radeon_cmd_header_t *cmd=NULL;
47
48 #define PREFIX_VOID r300ContextPtr rmesa
49
50 #define PREFIX PREFIX_VOID ,
51
52 #define PASS_PREFIX_VOID rmesa
53 #define PASS_PREFIX rmesa ,
54
55 typedef GLuint CARD32;
56
57 /* This files defines functions for accessing R300 hardware.
58 It needs to be customized to whatever code r300_lib.c is used
59 in */
60
61 void static inline check_space(int dwords)
62 {
63 }
64
65 static __inline__ uint32_t cmducs(int reg, int count)
66 {
67 drm_r300_cmd_header_t cmd;
68
69 cmd.unchecked_state.cmd_type = R300_CMD_UNCHECKED_STATE;
70 cmd.unchecked_state.count = count;
71 cmd.unchecked_state.reghi = ((unsigned int)reg & 0xFF00) >> 8;
72 cmd.unchecked_state.reglo = ((unsigned int)reg & 0x00FF);
73
74 return cmd.u;
75 }
76
77 static __inline__ uint32_t cmdvpu(int addr, int count)
78 {
79 drm_r300_cmd_header_t cmd;
80
81 cmd.vpu.cmd_type = R300_CMD_VPU;
82 cmd.vpu.count = count;
83 cmd.vpu.adrhi = ((unsigned int)addr & 0xFF00) >> 8;
84 cmd.vpu.adrlo = ((unsigned int)addr & 0x00FF);
85
86 return cmd.u;
87 }
88
89 static __inline__ uint32_t cmdpacket3(int packet)
90 {
91 drm_r300_cmd_header_t cmd;
92
93 cmd.packet3.cmd_type = R300_CMD_PACKET3;
94 cmd.packet3.packet = packet;
95
96 return cmd.u;
97 }
98
99 static __inline__ uint32_t cmdcpdelay(unsigned short count)
100 {
101 drm_r300_cmd_header_t cmd;
102
103 cmd.delay.cmd_type = R300_CMD_CP_DELAY;
104 cmd.delay.count = count;
105
106 return cmd.u;
107 }
108
109 /* Prepare to write a register value to register at address reg.
110 If num_extra > 0 then the following extra values are written
111 to registers with address +4, +8 and so on.. */
112 #define reg_start(reg, num_extra) \
113 { \
114 int _n; \
115 _n=(num_extra); \
116 cmd=(drm_radeon_cmd_header_t *) r300AllocCmdBuf(rmesa, \
117 (_n+2), \
118 __FUNCTION__); \
119 cmd_reserved=_n+2; \
120 cmd_written=1; \
121 cmd[0].i=cmducs((reg), _n+1); \
122 }
123
124 /* Prepare to write a register value to register at address reg.
125 If num_extra > 0 then the following extra values are written
126 into the same register. */
127 /* It is here to permit r300_lib to compile and link anyway, but
128 complain if actually called */
129 #define reg_start_pump(reg, num_extra) \
130 { \
131 fprintf(stderr, "I am not defined.. Error ! in %s::%s at line %d\n", \
132 __FILE__, __FUNCTION__, __LINE__); \
133 exit(-1); \
134 }
135
136 /* Emit CARD32 freestyle*/
137 #define e32(dword) { \
138 if(cmd_written<cmd_reserved){\
139 cmd[cmd_written].i=(dword); \
140 cmd_written++; \
141 } else { \
142 fprintf(stderr, "e32 but no previous packet declaration.. Aborting! in %s::%s at line %d\n", \
143 __FILE__, __FUNCTION__, __LINE__); \
144 exit(-1); \
145 } \
146 }
147
148 #define efloat(f) e32(r300PackFloat32(f))
149
150 #define vsf_start_fragment(dest, length) \
151 { \
152 int _n; \
153 _n=(length); \
154 cmd=(drm_radeon_cmd_header_t *) r300AllocCmdBuf(rmesa, \
155 (_n+1), \
156 __FUNCTION__); \
157 cmd_reserved=_n+2; \
158 cmd_written=1; \
159 cmd[0].i=cmdvpu((dest), _n/4); \
160 }
161
162 #define start_packet3(packet, count) \
163 { \
164 int _n; \
165 CARD32 _p; \
166 _n=(count); \
167 _p=(packet); \
168 cmd=(drm_radeon_cmd_header_t *) r300AllocCmdBuf(rmesa, \
169 (_n+3), \
170 __FUNCTION__); \
171 cmd_reserved=_n+3; \
172 cmd_written=2; \
173 if(_n>0x3fff) {\
174 fprintf(stderr,"Too big packet3 %08x: cannot store %d dwords\n", \
175 _p, _n); \
176 exit(-1); \
177 } \
178 cmd[0].i=cmdpacket3(R300_CMD_PACKET3_RAW); \
179 cmd[1].i=_p | ((_n & 0x3fff)<<16); \
180 }
181
182 /* must be sent to switch to 2d commands */
183 void static inline end_3d(PREFIX_VOID)
184 {
185 LOCAL_VARS
186
187 cmd=(drm_radeon_cmd_header_t *) r300AllocCmdBuf(rmesa, \
188 0, \
189 __FUNCTION__); \
190
191 cmd[0].header.cmd_type=R300_CMD_END3D;
192 }
193
194 void static inline cp_delay(PREFIX unsigned short count)
195 {
196 LOCAL_VARS
197
198 cmd=(drm_radeon_cmd_header_t *) r300AllocCmdBuf(rmesa, \
199 0, \
200 __FUNCTION__); \
201
202 cmd[0].i=cmdcpdelay(count);
203 }
204
205 #endif