fix the usage of GLX_MESA_allocate_memory
[mesa.git] / src / mesa / drivers / dri / r200 / r200_cmdbuf.c
1 /* $XFree86: xc/lib/GL/mesa/src/drv/r200/r200_cmdbuf.c,v 1.1 2002/10/30 12:51:51 alanh Exp $ */
2 /*
3 Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved.
4
5 The Weather Channel (TM) funded Tungsten Graphics to develop the
6 initial release of the Radeon 8500 driver under the XFree86 license.
7 This notice must be preserved.
8
9 Permission is hereby granted, free of charge, to any person obtaining
10 a copy of this software and associated documentation files (the
11 "Software"), to deal in the Software without restriction, including
12 without limitation the rights to use, copy, modify, merge, publish,
13 distribute, sublicense, and/or sell copies of the Software, and to
14 permit persons to whom the Software is furnished to do so, subject to
15 the following conditions:
16
17 The above copyright notice and this permission notice (including the
18 next paragraph) shall be included in all copies or substantial
19 portions of the Software.
20
21 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
24 IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
25 LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
26 OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
27 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28 */
29
30 /*
31 * Authors:
32 * Keith Whitwell <keith@tungstengraphics.com>
33 */
34
35 #include "glheader.h"
36 #include "imports.h"
37 #include "macros.h"
38 #include "context.h"
39 #include "swrast/swrast.h"
40 #include "simple_list.h"
41
42 #include "r200_context.h"
43 #include "r200_state.h"
44 #include "r200_ioctl.h"
45 #include "r200_tcl.h"
46 #include "r200_sanity.h"
47 #include "radeon_reg.h"
48
49 static void print_state_atom( struct r200_state_atom *state )
50 {
51 int i;
52
53 fprintf(stderr, "emit %s/%d\n", state->name, state->cmd_size);
54
55 if (0 & R200_DEBUG & DEBUG_VERBOSE)
56 for (i = 0 ; i < state->cmd_size ; i++)
57 fprintf(stderr, "\t%s[%d]: %x\n", state->name, i, state->cmd[i]);
58
59 }
60
61 static void r200_emit_state_list( r200ContextPtr rmesa,
62 struct r200_state_atom *list )
63 {
64 struct r200_state_atom *state, *tmp;
65 char *dest;
66 int i, size;
67
68 size = 0;
69 foreach_s( state, tmp, list ) {
70 if (state->check( rmesa->glCtx, state->idx )) {
71 /* dest = r200AllocCmdBuf( rmesa, state->cmd_size * 4, __FUNCTION__);
72 memcpy( dest, state->cmd, state->cmd_size * 4);*/
73 size += state->cmd_size;
74 state->dirty = GL_TRUE;
75 move_to_head( &(rmesa->hw.clean), state );
76 if (R200_DEBUG & DEBUG_STATE)
77 print_state_atom( state );
78 }
79 else if (R200_DEBUG & DEBUG_STATE)
80 fprintf(stderr, "skip state %s\n", state->name);
81 }
82
83 if (!size)
84 return;
85
86 dest = r200AllocCmdBuf( rmesa, size * 4, __FUNCTION__);
87
88 #define EMIT_ATOM(ATOM) \
89 do { \
90 if (rmesa->hw.ATOM.dirty) { \
91 rmesa->hw.ATOM.dirty = GL_FALSE; \
92 memcpy( dest, rmesa->hw.ATOM.cmd, rmesa->hw.ATOM.cmd_size * 4); \
93 dest += rmesa->hw.ATOM.cmd_size * 4; \
94 } \
95 } while (0)
96
97 EMIT_ATOM (ctx);
98 EMIT_ATOM (set);
99 EMIT_ATOM (lin);
100 EMIT_ATOM (msk);
101 EMIT_ATOM (vpt);
102 EMIT_ATOM (vtx);
103 EMIT_ATOM (vap);
104 EMIT_ATOM (vte);
105 EMIT_ATOM (msc);
106 EMIT_ATOM (cst);
107 EMIT_ATOM (zbs);
108 EMIT_ATOM (tcl);
109 EMIT_ATOM (msl);
110 EMIT_ATOM (tcg);
111 EMIT_ATOM (grd);
112 EMIT_ATOM (fog);
113 EMIT_ATOM (tam);
114 EMIT_ATOM (tf);
115 for (i = 0; i < 2; ++i) {
116 EMIT_ATOM (tex[i]);
117 }
118 for (i = 0; i < 2; ++i) {
119 EMIT_ATOM (cube[i]);
120 }
121 for (i = 0; i < 5; ++i)
122 EMIT_ATOM (mat[i]);
123 EMIT_ATOM (eye);
124 EMIT_ATOM (glt);
125 for (i = 0; i < 2; ++i) {
126 EMIT_ATOM (mtl[i]);
127 }
128 for (i = 0; i < 8; ++i)
129 EMIT_ATOM (lit[i]);
130 for (i = 0; i < 6; ++i)
131 EMIT_ATOM (ucp[i]);
132 for (i = 0; i < 6; ++i)
133 EMIT_ATOM (pix[i]);
134
135 #undef EMIT_ATOM
136
137 }
138
139
140 void r200EmitState( r200ContextPtr rmesa )
141 {
142 struct r200_state_atom *state, *tmp;
143
144 if (R200_DEBUG & (DEBUG_STATE|DEBUG_PRIMS))
145 fprintf(stderr, "%s\n", __FUNCTION__);
146
147 /* Somewhat overkill:
148 */
149 if ( rmesa->lost_context) {
150 if (R200_DEBUG & (DEBUG_STATE|DEBUG_PRIMS|DEBUG_IOCTL))
151 fprintf(stderr, "%s - lost context\n", __FUNCTION__);
152
153 foreach_s( state, tmp, &(rmesa->hw.clean) )
154 move_to_tail(&(rmesa->hw.dirty), state );
155
156 rmesa->lost_context = 0;
157 }
158 /* else {
159 move_to_tail( &rmesa->hw.dirty, &rmesa->hw.mtl[0] );*/
160 /* odd bug? -- isosurf, cycle between reflect & lit */
161 /* }*/
162
163 r200_emit_state_list( rmesa, &rmesa->hw.dirty );
164 }
165
166
167
168 /* Fire a section of the retained (indexed_verts) buffer as a regular
169 * primtive.
170 */
171 extern void r200EmitVbufPrim( r200ContextPtr rmesa,
172 GLuint primitive,
173 GLuint vertex_nr )
174 {
175 drm_radeon_cmd_header_t *cmd;
176
177 assert(!(primitive & R200_VF_PRIM_WALK_IND));
178
179 r200EmitState( rmesa );
180
181 if (R200_DEBUG & (DEBUG_IOCTL|DEBUG_PRIMS))
182 fprintf(stderr, "%s cmd_used/4: %d prim %x nr %d\n", __FUNCTION__,
183 rmesa->store.cmd_used/4, primitive, vertex_nr);
184
185 cmd = (drm_radeon_cmd_header_t *)r200AllocCmdBuf( rmesa, 3 * sizeof(*cmd),
186 __FUNCTION__ );
187 cmd[0].i = 0;
188 cmd[0].header.cmd_type = RADEON_CMD_PACKET3_CLIP;
189 cmd[1].i = R200_CP_CMD_3D_DRAW_VBUF_2;
190 cmd[2].i = (primitive |
191 R200_VF_PRIM_WALK_LIST |
192 R200_VF_COLOR_ORDER_RGBA |
193 (vertex_nr << R200_VF_VERTEX_NUMBER_SHIFT));
194 }
195
196
197 void r200FlushElts( r200ContextPtr rmesa )
198 {
199 int *cmd = (int *)(rmesa->store.cmd_buf + rmesa->store.elts_start);
200 int dwords;
201 int nr = (rmesa->store.cmd_used - (rmesa->store.elts_start + 12)) / 2;
202
203 if (R200_DEBUG & (DEBUG_IOCTL|DEBUG_PRIMS))
204 fprintf(stderr, "%s\n", __FUNCTION__);
205
206 assert( rmesa->dma.flush == r200FlushElts );
207 rmesa->dma.flush = 0;
208
209 /* Cope with odd number of elts:
210 */
211 rmesa->store.cmd_used = (rmesa->store.cmd_used + 2) & ~2;
212 dwords = (rmesa->store.cmd_used - rmesa->store.elts_start) / 4;
213
214 cmd[1] |= (dwords - 3) << 16;
215 cmd[2] |= nr << R200_VF_VERTEX_NUMBER_SHIFT;
216
217 if (R200_DEBUG & DEBUG_SYNC) {
218 fprintf(stderr, "%s: Syncing\n", __FUNCTION__);
219 r200Finish( rmesa->glCtx );
220 }
221 }
222
223
224 GLushort *r200AllocEltsOpenEnded( r200ContextPtr rmesa,
225 GLuint primitive,
226 GLuint min_nr )
227 {
228 drm_radeon_cmd_header_t *cmd;
229 GLushort *retval;
230
231 if (R200_DEBUG & DEBUG_IOCTL)
232 fprintf(stderr, "%s %d prim %x\n", __FUNCTION__, min_nr, primitive);
233
234 assert((primitive & R200_VF_PRIM_WALK_IND));
235
236 r200EmitState( rmesa );
237
238 cmd = (drm_radeon_cmd_header_t *)r200AllocCmdBuf( rmesa,
239 12 + min_nr*2,
240 __FUNCTION__ );
241 cmd[0].i = 0;
242 cmd[0].header.cmd_type = RADEON_CMD_PACKET3_CLIP;
243 cmd[1].i = R200_CP_CMD_3D_DRAW_INDX_2;
244 cmd[2].i = (primitive |
245 R200_VF_PRIM_WALK_IND |
246 R200_VF_COLOR_ORDER_RGBA);
247
248
249 retval = (GLushort *)(cmd+3);
250
251 if (R200_DEBUG & DEBUG_PRIMS)
252 fprintf(stderr, "%s: header 0x%x prim %x \n",
253 __FUNCTION__,
254 cmd[1].i, primitive);
255
256 assert(!rmesa->dma.flush);
257 rmesa->glCtx->Driver.NeedFlush |= FLUSH_STORED_VERTICES;
258 rmesa->dma.flush = r200FlushElts;
259
260 rmesa->store.elts_start = ((char *)cmd) - rmesa->store.cmd_buf;
261
262 return retval;
263 }
264
265
266
267 void r200EmitVertexAOS( r200ContextPtr rmesa,
268 GLuint vertex_size,
269 GLuint offset )
270 {
271 drm_radeon_cmd_header_t *cmd;
272
273 if (R200_DEBUG & (DEBUG_PRIMS|DEBUG_IOCTL))
274 fprintf(stderr, "%s: vertex_size 0x%x offset 0x%x \n",
275 __FUNCTION__, vertex_size, offset);
276
277 cmd = (drm_radeon_cmd_header_t *)r200AllocCmdBuf( rmesa, 5 * sizeof(int),
278 __FUNCTION__ );
279
280 cmd[0].header.cmd_type = RADEON_CMD_PACKET3;
281 cmd[1].i = R200_CP_CMD_3D_LOAD_VBPNTR | (2 << 16);
282 cmd[2].i = 1;
283 cmd[3].i = vertex_size | (vertex_size << 8);
284 cmd[4].i = offset;
285 }
286
287
288 void r200EmitAOS( r200ContextPtr rmesa,
289 struct r200_dma_region **component,
290 GLuint nr,
291 GLuint offset )
292 {
293 drm_radeon_cmd_header_t *cmd;
294 int sz = 3 + ((nr/2)*3) + ((nr&1)*2);
295 int i;
296 int *tmp;
297
298 if (R200_DEBUG & DEBUG_IOCTL)
299 fprintf(stderr, "%s nr arrays: %d\n", __FUNCTION__, nr);
300
301 cmd = (drm_radeon_cmd_header_t *)r200AllocCmdBuf( rmesa, sz * sizeof(int),
302 __FUNCTION__ );
303 cmd[0].i = 0;
304 cmd[0].header.cmd_type = RADEON_CMD_PACKET3;
305 cmd[1].i = R200_CP_CMD_3D_LOAD_VBPNTR | ((sz-3) << 16);
306 cmd[2].i = nr;
307 tmp = &cmd[0].i;
308 cmd += 3;
309
310 for (i = 0 ; i < nr ; i++) {
311 if (i & 1) {
312 cmd[0].i |= ((component[i]->aos_stride << 24) |
313 (component[i]->aos_size << 16));
314 cmd[2].i = (component[i]->aos_start +
315 offset * component[i]->aos_stride * 4);
316 cmd += 3;
317 }
318 else {
319 cmd[0].i = ((component[i]->aos_stride << 8) |
320 (component[i]->aos_size << 0));
321 cmd[1].i = (component[i]->aos_start +
322 offset * component[i]->aos_stride * 4);
323 }
324 }
325
326 if (R200_DEBUG & DEBUG_VERTS) {
327 fprintf(stderr, "%s:\n", __FUNCTION__);
328 for (i = 0 ; i < sz ; i++)
329 fprintf(stderr, " %d: %x\n", i, tmp[i]);
330 }
331 }
332
333 void r200EmitBlit( r200ContextPtr rmesa,
334 GLuint color_fmt,
335 GLuint src_pitch,
336 GLuint src_offset,
337 GLuint dst_pitch,
338 GLuint dst_offset,
339 GLint srcx, GLint srcy,
340 GLint dstx, GLint dsty,
341 GLuint w, GLuint h )
342 {
343 drm_radeon_cmd_header_t *cmd;
344
345 if (R200_DEBUG & DEBUG_IOCTL)
346 fprintf(stderr, "%s src %x/%x %d,%d dst: %x/%x %d,%d sz: %dx%d\n",
347 __FUNCTION__,
348 src_pitch, src_offset, srcx, srcy,
349 dst_pitch, dst_offset, dstx, dsty,
350 w, h);
351
352 assert( (src_pitch & 63) == 0 );
353 assert( (dst_pitch & 63) == 0 );
354 assert( (src_offset & 1023) == 0 );
355 assert( (dst_offset & 1023) == 0 );
356 assert( w < (1<<16) );
357 assert( h < (1<<16) );
358
359 cmd = (drm_radeon_cmd_header_t *)r200AllocCmdBuf( rmesa, 8 * sizeof(int),
360 __FUNCTION__ );
361
362
363 cmd[0].header.cmd_type = RADEON_CMD_PACKET3;
364 cmd[1].i = R200_CP_CMD_BITBLT_MULTI | (5 << 16);
365 cmd[2].i = (RADEON_GMC_SRC_PITCH_OFFSET_CNTL |
366 RADEON_GMC_DST_PITCH_OFFSET_CNTL |
367 RADEON_GMC_BRUSH_NONE |
368 (color_fmt << 8) |
369 RADEON_GMC_SRC_DATATYPE_COLOR |
370 RADEON_ROP3_S |
371 RADEON_DP_SRC_SOURCE_MEMORY |
372 RADEON_GMC_CLR_CMP_CNTL_DIS |
373 RADEON_GMC_WR_MSK_DIS );
374
375 cmd[3].i = ((src_pitch/64)<<22) | (src_offset >> 10);
376 cmd[4].i = ((dst_pitch/64)<<22) | (dst_offset >> 10);
377 cmd[5].i = (srcx << 16) | srcy;
378 cmd[6].i = (dstx << 16) | dsty; /* dst */
379 cmd[7].i = (w << 16) | h;
380 }
381
382
383 void r200EmitWait( r200ContextPtr rmesa, GLuint flags )
384 {
385 if (rmesa->dri.drmMinor >= 6) {
386 drm_radeon_cmd_header_t *cmd;
387
388 assert( !(flags & ~(RADEON_WAIT_2D|RADEON_WAIT_3D)) );
389
390 cmd = (drm_radeon_cmd_header_t *)r200AllocCmdBuf( rmesa, 1 * sizeof(int),
391 __FUNCTION__ );
392 cmd[0].i = 0;
393 cmd[0].wait.cmd_type = RADEON_CMD_WAIT;
394 cmd[0].wait.flags = flags;
395 }
396 }