slang: initialize the context
[mesa.git] / src / mesa / drivers / dri / r300 / r300_emit.h
1 /*
2 * Copyright (C) 2005 Vladimir Dergachev.
3 *
4 * All Rights Reserved.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining
7 * a copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sublicense, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
13 *
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial
16 * portions of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
21 * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
22 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
23 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
24 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 *
26 */
27
28 /*
29 * Authors:
30 * Vladimir Dergachev <volodya@mindspring.com>
31 * Nicolai Haehnle <prefect_@gmx.net>
32 * Aapo Tahkola <aet@rasterburn.org>
33 * Ben Skeggs <darktama@iinet.net.au>
34 * Jerome Glisse <j.glisse@gmail.com>
35 */
36
37 /* This files defines functions for accessing R300 hardware.
38 */
39 #ifndef __R300_EMIT_H__
40 #define __R300_EMIT_H__
41
42 #include "main/glheader.h"
43 #include "r300_context.h"
44 #include "r300_cmdbuf.h"
45 #include "radeon_reg.h"
46
47 /* TODO: move these defines (and the ones from DRM) into r300_reg.h and sync up
48 * with DRM */
49 #define CP_PACKET0(reg, n) (RADEON_CP_PACKET0 | ((n)<<16) | ((reg)>>2))
50 #define CP_PACKET3( pkt, n ) \
51 (RADEON_CP_PACKET3 | (pkt) | ((n) << 16))
52
53 static INLINE uint32_t cmdpacket0(int reg, int count)
54 {
55 drm_r300_cmd_header_t cmd;
56
57 cmd.packet0.cmd_type = R300_CMD_PACKET0;
58 cmd.packet0.count = count;
59 cmd.packet0.reghi = ((unsigned int)reg & 0xFF00) >> 8;
60 cmd.packet0.reglo = ((unsigned int)reg & 0x00FF);
61
62 return cmd.u;
63 }
64
65 static INLINE uint32_t cmdvpu(int addr, int count)
66 {
67 drm_r300_cmd_header_t cmd;
68
69 cmd.vpu.cmd_type = R300_CMD_VPU;
70 cmd.vpu.count = count;
71 cmd.vpu.adrhi = ((unsigned int)addr & 0xFF00) >> 8;
72 cmd.vpu.adrlo = ((unsigned int)addr & 0x00FF);
73
74 return cmd.u;
75 }
76
77 static INLINE uint32_t cmdr500fp(int addr, int count, int type, int clamp)
78 {
79 drm_r300_cmd_header_t cmd;
80
81 cmd.r500fp.cmd_type = R300_CMD_R500FP;
82 cmd.r500fp.count = count;
83 cmd.r500fp.adrhi_flags = ((unsigned int)addr & 0x100) >> 8;
84 cmd.r500fp.adrhi_flags |= type ? R500FP_CONSTANT_TYPE : 0;
85 cmd.r500fp.adrhi_flags |= clamp ? R500FP_CONSTANT_CLAMP : 0;
86 cmd.r500fp.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 /**
131 * Prepare to write a register value to register at address reg.
132 * If num_extra > 0 then the following extra values are written
133 * to registers with address +4, +8 and so on..
134 */
135 #define reg_start(reg, num_extra) \
136 do { \
137 int _n; \
138 _n=(num_extra); \
139 cmd = (drm_radeon_cmd_header_t*) \
140 r300AllocCmdBuf(rmesa, \
141 (_n+2), \
142 __FUNCTION__); \
143 cmd_reserved=_n+2; \
144 cmd_written=1; \
145 cmd[0].i=cmdpacket0((reg), _n+1); \
146 } while (0);
147
148 /**
149 * Emit GLuint freestyle
150 */
151 #define e32(dword) \
152 do { \
153 if(cmd_written<cmd_reserved) { \
154 cmd[cmd_written].i=(dword); \
155 cmd_written++; \
156 } else { \
157 fprintf(stderr, \
158 "e32 but no previous packet " \
159 "declaration.\n" \
160 "Aborting! in %s::%s at line %d, " \
161 "cmd_written=%d cmd_reserved=%d\n", \
162 __FILE__, __FUNCTION__, __LINE__, \
163 cmd_written, cmd_reserved); \
164 _mesa_exit(-1); \
165 } \
166 } while(0)
167
168 #define efloat(f) e32(r300PackFloat32(f))
169
170 #define vsf_start_fragment(dest, length) \
171 do { \
172 int _n; \
173 _n = (length); \
174 cmd = (drm_radeon_cmd_header_t*) \
175 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 } while (0);
182
183 #define r500fp_start_fragment(dest, length) \
184 do { \
185 int _n; \
186 _n = (length); \
187 cmd = (drm_radeon_cmd_header_t*) \
188 r300AllocCmdBuf(rmesa, \
189 (_n+1), \
190 __FUNCTION__); \
191 cmd_reserved = _n+1; \
192 cmd_written =1; \
193 cmd[0].i = cmdr500fp((dest), _n/6, 0, 0); \
194 } while (0);
195
196 #define start_packet3(packet, count) \
197 { \
198 int _n; \
199 GLuint _p; \
200 _n = (count); \
201 _p = (packet); \
202 cmd = (drm_radeon_cmd_header_t*) \
203 r300AllocCmdBuf(rmesa, \
204 (_n+3), \
205 __FUNCTION__); \
206 cmd_reserved = _n+3; \
207 cmd_written = 2; \
208 if(_n > 0x3fff) { \
209 fprintf(stderr,"Too big packet3 %08x: cannot " \
210 "store %d dwords\n", \
211 _p, _n); \
212 _mesa_exit(-1); \
213 } \
214 cmd[0].i = cmdpacket3(R300_CMD_PACKET3_RAW); \
215 cmd[1].i = _p | ((_n & 0x3fff)<<16); \
216 }
217
218 /**
219 * Must be sent to switch to 2d commands
220 */
221 void static INLINE end_3d(r300ContextPtr rmesa)
222 {
223 drm_radeon_cmd_header_t *cmd = NULL;
224
225 cmd =
226 (drm_radeon_cmd_header_t *) r300AllocCmdBuf(rmesa, 1, __FUNCTION__);
227 cmd[0].header.cmd_type = R300_CMD_END3D;
228 }
229
230 void static INLINE cp_delay(r300ContextPtr rmesa, unsigned short count)
231 {
232 drm_radeon_cmd_header_t *cmd = NULL;
233
234 cmd =
235 (drm_radeon_cmd_header_t *) r300AllocCmdBuf(rmesa, 1, __FUNCTION__);
236 cmd[0].i = cmdcpdelay(count);
237 }
238
239 void static INLINE cp_wait(r300ContextPtr rmesa, unsigned char flags)
240 {
241 drm_radeon_cmd_header_t *cmd = NULL;
242
243 cmd =
244 (drm_radeon_cmd_header_t *) r300AllocCmdBuf(rmesa, 1, __FUNCTION__);
245 cmd[0].i = cmdwait(flags);
246 }
247
248 extern int r300EmitArrays(GLcontext * ctx);
249
250 #ifdef USER_BUFFERS
251 void r300UseArrays(GLcontext * ctx);
252 #endif
253
254 extern void r300ReleaseArrays(GLcontext * ctx);
255 extern int r300PrimitiveType(r300ContextPtr rmesa, int prim);
256 extern int r300NumVerts(r300ContextPtr rmesa, int num_verts, int prim);
257
258 extern void r300EmitCacheFlush(r300ContextPtr rmesa);
259
260 extern GLuint r300VAPInputRoute0(uint32_t * dst, GLvector4f ** attribptr,
261 int *inputs, GLint * tab, GLuint nr);
262 extern GLuint r300VAPInputRoute1(uint32_t * dst, int swizzle[][4], GLuint nr);
263 extern GLuint r300VAPInputCntl0(GLcontext * ctx, GLuint InputsRead);
264 extern GLuint r300VAPInputCntl1(GLcontext * ctx, GLuint InputsRead);
265 extern GLuint r300VAPOutputCntl0(GLcontext * ctx, GLuint OutputsWritten);
266 extern GLuint r300VAPOutputCntl1(GLcontext * ctx, GLuint OutputsWritten);
267
268 #endif