Merge branch 'master' into i915-unification
[mesa.git] / src / mesa / drivers / dri / r300 / r300_ioctl.c
1 /*
2 Copyright (C) The Weather Channel, Inc. 2002.
3 Copyright (C) 2004 Nicolai Haehnle.
4 All Rights Reserved.
5
6 The Weather Channel (TM) funded Tungsten Graphics to develop the
7 initial release of the Radeon 8500 driver under the XFree86 license.
8 This notice must be preserved.
9
10 Permission is hereby granted, free of charge, to any person obtaining
11 a copy of this software and associated documentation files (the
12 "Software"), to deal in the Software without restriction, including
13 without limitation the rights to use, copy, modify, merge, publish,
14 distribute, sublicense, and/or sell copies of the Software, and to
15 permit persons to whom the Software is furnished to do so, subject to
16 the following conditions:
17
18 The above copyright notice and this permission notice (including the
19 next paragraph) shall be included in all copies or substantial
20 portions of the Software.
21
22 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
25 IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
26 LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
27 OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29
30 **************************************************************************/
31
32 /**
33 * \file
34 *
35 * \author Keith Whitwell <keith@tungstengraphics.com>
36 *
37 * \author Nicolai Haehnle <prefect_@gmx.net>
38 */
39
40 #include <sched.h>
41 #include <errno.h>
42
43 #include "glheader.h"
44 #include "imports.h"
45 #include "macros.h"
46 #include "context.h"
47 #include "swrast/swrast.h"
48
49 #include "r300_context.h"
50 #include "radeon_ioctl.h"
51 #include "r300_ioctl.h"
52 #include "r300_cmdbuf.h"
53 #include "r300_state.h"
54 #include "r300_program.h"
55 #include "radeon_reg.h"
56 #include "r300_emit.h"
57
58 #include "vblank.h"
59
60 #define CLEARBUFFER_COLOR 0x1
61 #define CLEARBUFFER_DEPTH 0x2
62 #define CLEARBUFFER_STENCIL 0x4
63
64 static void r300ClearBuffer(r300ContextPtr r300, int flags, int buffer)
65 {
66 GLcontext *ctx = r300->radeon.glCtx;
67 __DRIdrawablePrivate *dPriv = r300->radeon.dri.drawable;
68 GLuint cboffset, cbpitch;
69 drm_r300_cmd_header_t *cmd2;
70 int cmd_reserved = 0;
71 int cmd_written = 0;
72 drm_radeon_cmd_header_t *cmd = NULL;
73 r300ContextPtr rmesa = r300;
74
75 if (RADEON_DEBUG & DEBUG_IOCTL)
76 fprintf(stderr, "%s: %s buffer (%i,%i %ix%i)\n",
77 __FUNCTION__, buffer ? "back" : "front",
78 dPriv->x, dPriv->y, dPriv->w, dPriv->h);
79
80 if (buffer) {
81 cboffset = r300->radeon.radeonScreen->backOffset;
82 cbpitch = r300->radeon.radeonScreen->backPitch;
83 } else {
84 cboffset = r300->radeon.radeonScreen->frontOffset;
85 cbpitch = r300->radeon.radeonScreen->frontPitch;
86 }
87
88 cboffset += r300->radeon.radeonScreen->fbLocation;
89
90 cp_wait(r300, R300_WAIT_3D | R300_WAIT_3D_CLEAN);
91 end_3d(rmesa);
92
93 R300_STATECHANGE(r300, cb);
94 reg_start(R300_RB3D_COLOROFFSET0, 0);
95 e32(cboffset);
96
97 if (r300->radeon.radeonScreen->cpp == 4)
98 cbpitch |= R300_COLOR_FORMAT_ARGB8888;
99 else
100 cbpitch |= R300_COLOR_FORMAT_RGB565;
101
102 if (r300->radeon.sarea->tiling_enabled)
103 cbpitch |= R300_COLOR_TILE_ENABLE;
104
105 reg_start(R300_RB3D_COLORPITCH0, 0);
106 e32(cbpitch);
107
108 R300_STATECHANGE(r300, cmk);
109 reg_start(R300_RB3D_COLORMASK, 0);
110
111 if (flags & CLEARBUFFER_COLOR) {
112 e32((ctx->Color.ColorMask[BCOMP] ? R300_COLORMASK0_B : 0) |
113 (ctx->Color.ColorMask[GCOMP] ? R300_COLORMASK0_G : 0) |
114 (ctx->Color.ColorMask[RCOMP] ? R300_COLORMASK0_R : 0) |
115 (ctx->Color.ColorMask[ACOMP] ? R300_COLORMASK0_A : 0));
116 } else {
117 e32(0x0);
118 }
119
120 R300_STATECHANGE(r300, zs);
121 reg_start(R300_RB3D_ZSTENCIL_CNTL_0, 2);
122
123 {
124 uint32_t t1, t2;
125
126 t1 = 0x0;
127 t2 = 0x0;
128
129 if (flags & CLEARBUFFER_DEPTH) {
130 t1 |= R300_RB3D_Z_WRITE_ONLY;
131 t2 |=
132 (R300_ZS_ALWAYS << R300_RB3D_ZS1_DEPTH_FUNC_SHIFT);
133 } else {
134 t1 |= R300_RB3D_Z_DISABLED_1; // disable
135 }
136
137 if (flags & CLEARBUFFER_STENCIL) {
138 t1 |= R300_RB3D_STENCIL_ENABLE;
139 t2 |=
140 (R300_ZS_ALWAYS <<
141 R300_RB3D_ZS1_FRONT_FUNC_SHIFT) |
142 (R300_ZS_REPLACE <<
143 R300_RB3D_ZS1_FRONT_FAIL_OP_SHIFT) |
144 (R300_ZS_REPLACE <<
145 R300_RB3D_ZS1_FRONT_ZPASS_OP_SHIFT) |
146 (R300_ZS_REPLACE <<
147 R300_RB3D_ZS1_FRONT_ZFAIL_OP_SHIFT) |
148 (R300_ZS_ALWAYS <<
149 R300_RB3D_ZS1_BACK_FUNC_SHIFT) |
150 (R300_ZS_REPLACE <<
151 R300_RB3D_ZS1_BACK_FAIL_OP_SHIFT) |
152 (R300_ZS_REPLACE <<
153 R300_RB3D_ZS1_BACK_ZPASS_OP_SHIFT) |
154 (R300_ZS_REPLACE <<
155 R300_RB3D_ZS1_BACK_ZFAIL_OP_SHIFT);
156 }
157
158 e32(t1);
159 e32(t2);
160 e32(r300->state.stencil.clear);
161 }
162
163 cmd2 = (drm_r300_cmd_header_t *) r300AllocCmdBuf(r300, 9, __FUNCTION__);
164 cmd2[0].packet3.cmd_type = R300_CMD_PACKET3;
165 cmd2[0].packet3.packet = R300_CMD_PACKET3_CLEAR;
166 cmd2[1].u = r300PackFloat32(dPriv->w / 2.0);
167 cmd2[2].u = r300PackFloat32(dPriv->h / 2.0);
168 cmd2[3].u = r300PackFloat32(ctx->Depth.Clear);
169 cmd2[4].u = r300PackFloat32(1.0);
170 cmd2[5].u = r300PackFloat32(ctx->Color.ClearColor[0]);
171 cmd2[6].u = r300PackFloat32(ctx->Color.ClearColor[1]);
172 cmd2[7].u = r300PackFloat32(ctx->Color.ClearColor[2]);
173 cmd2[8].u = r300PackFloat32(ctx->Color.ClearColor[3]);
174
175 reg_start(R300_RB3D_DSTCACHE_CTLSTAT, 0);
176 e32(R300_RB3D_DSTCACHE_UNKNOWN_0A);
177
178 reg_start(R300_RB3D_ZCACHE_CTLSTAT, 0);
179 e32(R300_RB3D_ZCACHE_UNKNOWN_03);
180 cp_wait(rmesa, R300_WAIT_3D | R300_WAIT_3D_CLEAN);
181 }
182
183 static void r300EmitClearState(GLcontext * ctx)
184 {
185 r300ContextPtr r300 = R300_CONTEXT(ctx);
186 r300ContextPtr rmesa = r300;
187 __DRIdrawablePrivate *dPriv = r300->radeon.dri.drawable;
188 int i;
189 int cmd_reserved = 0;
190 int cmd_written = 0;
191 drm_radeon_cmd_header_t *cmd = NULL;
192 int has_tcl = 1;
193
194 if (!(r300->radeon.radeonScreen->chip_flags & RADEON_CHIPSET_TCL))
195 has_tcl = 0;
196
197 /* FIXME: the values written to R300_VAP_INPUT_ROUTE_0_0 and
198 * R300_VAP_INPUT_ROUTE_0_1 are in fact known, however, the values are
199 * quite complex; see the functions in r300_emit.c.
200 *
201 * I believe it would be a good idea to extend the functions in
202 * r300_emit.c so that they can be used to setup the default values for
203 * these registers, as well as the actual values used for rendering.
204 */
205 R300_STATECHANGE(r300, vir[0]);
206 reg_start(R300_VAP_INPUT_ROUTE_0_0, 0);
207 if (!has_tcl)
208 e32(0x22030003);
209 else
210 e32(0x21030003);
211
212 /* disable fog */
213 R300_STATECHANGE(r300, fogs);
214 reg_start(R300_RE_FOG_STATE, 0);
215 e32(0x0);
216
217 R300_STATECHANGE(r300, vir[1]);
218 reg_start(R300_VAP_INPUT_ROUTE_1_0, 0);
219 e32(0xF688F688);
220
221 /* R300_VAP_INPUT_CNTL_0, R300_VAP_INPUT_CNTL_1 */
222 R300_STATECHANGE(r300, vic);
223 reg_start(R300_VAP_INPUT_CNTL_0, 1);
224 e32(R300_INPUT_CNTL_0_COLOR);
225 e32(R300_INPUT_CNTL_POS | R300_INPUT_CNTL_COLOR | R300_INPUT_CNTL_TC0);
226
227 if (!has_tcl) {
228 R300_STATECHANGE(r300, vte);
229 /* comes from fglrx startup of clear */
230 reg_start(R300_SE_VTE_CNTL, 1);
231 e32(R300_VTX_W0_FMT | R300_VPORT_X_SCALE_ENA |
232 R300_VPORT_X_OFFSET_ENA | R300_VPORT_Y_SCALE_ENA |
233 R300_VPORT_Y_OFFSET_ENA | R300_VPORT_Z_SCALE_ENA |
234 R300_VPORT_Z_OFFSET_ENA);
235 e32(0x8);
236
237 reg_start(0x21dc, 0);
238 e32(0xaaaaaaaa);
239 }
240
241 R300_STATECHANGE(r300, vof);
242 reg_start(R300_VAP_OUTPUT_VTX_FMT_0, 1);
243 e32(R300_VAP_OUTPUT_VTX_FMT_0__POS_PRESENT |
244 R300_VAP_OUTPUT_VTX_FMT_0__COLOR_PRESENT);
245 e32(0x0); /* no textures */
246
247 R300_STATECHANGE(r300, txe);
248 reg_start(R300_TX_ENABLE, 0);
249 e32(0x0);
250
251 R300_STATECHANGE(r300, vpt);
252 reg_start(R300_SE_VPORT_XSCALE, 5);
253 efloat(1.0);
254 efloat(dPriv->x);
255 efloat(1.0);
256 efloat(dPriv->y);
257 efloat(1.0);
258 efloat(0.0);
259
260 R300_STATECHANGE(r300, at);
261 reg_start(R300_PP_ALPHA_TEST, 0);
262 e32(0x0);
263
264 R300_STATECHANGE(r300, bld);
265 reg_start(R300_RB3D_CBLEND, 1);
266 e32(0x0);
267 e32(0x0);
268
269 R300_STATECHANGE(r300, unk221C);
270 reg_start(R300_VAP_UNKNOWN_221C, 0);
271 e32(R300_221C_CLEAR);
272
273 R300_STATECHANGE(r300, ps);
274 reg_start(R300_RE_POINTSIZE, 0);
275 e32(((dPriv->w * 6) << R300_POINTSIZE_X_SHIFT) |
276 ((dPriv->h * 6) << R300_POINTSIZE_Y_SHIFT));
277
278 R300_STATECHANGE(r300, ri);
279 reg_start(R300_RS_INTERP_0, 8);
280 for (i = 0; i < 8; ++i) {
281 e32(R300_RS_INTERP_USED);
282 }
283
284 R300_STATECHANGE(r300, rc);
285 /* The second constant is needed to get glxgears display anything .. */
286 reg_start(R300_RS_CNTL_0, 1);
287 e32((1 << R300_RS_CNTL_CI_CNT_SHIFT) | R300_RS_CNTL_0_UNKNOWN_18);
288 e32(0x0);
289
290 R300_STATECHANGE(r300, rr);
291 reg_start(R300_RS_ROUTE_0, 0);
292 e32(R300_RS_ROUTE_0_COLOR);
293
294 R300_STATECHANGE(r300, fp);
295 reg_start(R300_PFS_CNTL_0, 2);
296 e32(0x0);
297 e32(0x0);
298 e32(0x0);
299 reg_start(R300_PFS_NODE_0, 3);
300 e32(0x0);
301 e32(0x0);
302 e32(0x0);
303 e32(R300_PFS_NODE_OUTPUT_COLOR);
304
305 R300_STATECHANGE(r300, fpi[0]);
306 R300_STATECHANGE(r300, fpi[1]);
307 R300_STATECHANGE(r300, fpi[2]);
308 R300_STATECHANGE(r300, fpi[3]);
309
310 reg_start(R300_PFS_INSTR0_0, 0);
311 e32(FP_INSTRC(MAD, FP_ARGC(SRC0C_XYZ), FP_ARGC(ONE), FP_ARGC(ZERO)));
312
313 reg_start(R300_PFS_INSTR1_0, 0);
314 e32(FP_SELC(0, NO, XYZ, FP_TMP(0), 0, 0));
315
316 reg_start(R300_PFS_INSTR2_0, 0);
317 e32(FP_INSTRA(MAD, FP_ARGA(SRC0A), FP_ARGA(ONE), FP_ARGA(ZERO)));
318
319 reg_start(R300_PFS_INSTR3_0, 0);
320 e32(FP_SELA(0, NO, W, FP_TMP(0), 0, 0));
321
322 if (has_tcl) {
323 R300_STATECHANGE(r300, pvs);
324 reg_start(R300_VAP_PVS_CNTL_1, 2);
325 e32((0 << R300_PVS_CNTL_1_PROGRAM_START_SHIFT) |
326 (0 << R300_PVS_CNTL_1_POS_END_SHIFT) |
327 (1 << R300_PVS_CNTL_1_PROGRAM_END_SHIFT));
328 e32(0x0);
329 e32(1 << R300_PVS_CNTL_3_PROGRAM_UNKNOWN_SHIFT);
330
331 R300_STATECHANGE(r300, vpi);
332 vsf_start_fragment(0x0, 8);
333 e32(VP_OUT(ADD, OUT, 0, XYZW));
334 e32(VP_IN(IN, 0));
335 e32(VP_ZERO());
336 e32(0x0);
337
338 e32(VP_OUT(ADD, OUT, 1, XYZW));
339 e32(VP_IN(IN, 1));
340 e32(VP_ZERO());
341 e32(0x0);
342 }
343 }
344
345 /**
346 * Buffer clear
347 */
348 static void r300Clear(GLcontext * ctx, GLbitfield mask)
349 {
350 r300ContextPtr r300 = R300_CONTEXT(ctx);
351 __DRIdrawablePrivate *dPriv = r300->radeon.dri.drawable;
352 int flags = 0;
353 int bits = 0;
354 int swapped;
355
356 if (RADEON_DEBUG & DEBUG_IOCTL)
357 fprintf(stderr, "r300Clear\n");
358
359 {
360 LOCK_HARDWARE(&r300->radeon);
361 UNLOCK_HARDWARE(&r300->radeon);
362 if (dPriv->numClipRects == 0)
363 return;
364 }
365
366 if (mask & BUFFER_BIT_FRONT_LEFT) {
367 flags |= BUFFER_BIT_FRONT_LEFT;
368 mask &= ~BUFFER_BIT_FRONT_LEFT;
369 }
370
371 if (mask & BUFFER_BIT_BACK_LEFT) {
372 flags |= BUFFER_BIT_BACK_LEFT;
373 mask &= ~BUFFER_BIT_BACK_LEFT;
374 }
375
376 if (mask & BUFFER_BIT_DEPTH) {
377 bits |= CLEARBUFFER_DEPTH;
378 mask &= ~BUFFER_BIT_DEPTH;
379 }
380
381 if ((mask & BUFFER_BIT_STENCIL) && r300->state.stencil.hw_stencil) {
382 bits |= CLEARBUFFER_STENCIL;
383 mask &= ~BUFFER_BIT_STENCIL;
384 }
385
386 if (mask) {
387 if (RADEON_DEBUG & DEBUG_FALLBACKS)
388 fprintf(stderr, "%s: swrast clear, mask: %x\n",
389 __FUNCTION__, mask);
390 _swrast_Clear(ctx, mask);
391 }
392
393 swapped = r300->radeon.sarea->pfCurrentPage == 1;
394
395 /* Make sure it fits there. */
396 r300EnsureCmdBufSpace(r300, 421 * 3, __FUNCTION__);
397 if (flags || bits)
398 r300EmitClearState(ctx);
399
400 if (flags & BUFFER_BIT_FRONT_LEFT) {
401 r300ClearBuffer(r300, bits | CLEARBUFFER_COLOR, swapped);
402 bits = 0;
403 }
404
405 if (flags & BUFFER_BIT_BACK_LEFT) {
406 r300ClearBuffer(r300, bits | CLEARBUFFER_COLOR, swapped ^ 1);
407 bits = 0;
408 }
409
410 if (bits)
411 r300ClearBuffer(r300, bits, 0);
412
413 }
414
415 void r300Flush(GLcontext * ctx)
416 {
417 r300ContextPtr r300 = R300_CONTEXT(ctx);
418
419 if (RADEON_DEBUG & DEBUG_IOCTL)
420 fprintf(stderr, "%s\n", __FUNCTION__);
421
422 if (r300->cmdbuf.count_used > r300->cmdbuf.count_reemit)
423 r300FlushCmdBuf(r300, __FUNCTION__);
424 }
425
426 #ifdef USER_BUFFERS
427 #include "r300_mem.h"
428
429 static void r300RefillCurrentDmaRegion(r300ContextPtr rmesa, int size)
430 {
431 struct r300_dma_buffer *dmabuf;
432 size = MAX2(size, RADEON_BUFFER_SIZE * 16);
433
434 if (RADEON_DEBUG & (DEBUG_IOCTL | DEBUG_DMA))
435 fprintf(stderr, "%s\n", __FUNCTION__);
436
437 if (rmesa->dma.flush) {
438 rmesa->dma.flush(rmesa);
439 }
440
441 if (rmesa->dma.current.buf)
442 r300ReleaseDmaRegion(rmesa, &rmesa->dma.current, __FUNCTION__);
443
444 if (rmesa->dma.nr_released_bufs > 4)
445 r300FlushCmdBuf(rmesa, __FUNCTION__);
446
447 dmabuf = CALLOC_STRUCT(r300_dma_buffer);
448 dmabuf->buf = (void *)1; /* hack */
449 dmabuf->refcount = 1;
450
451 dmabuf->id = r300_mem_alloc(rmesa, 4, size);
452 if (dmabuf->id == 0) {
453 LOCK_HARDWARE(&rmesa->radeon); /* no need to validate */
454
455 r300FlushCmdBufLocked(rmesa, __FUNCTION__);
456 radeonWaitForIdleLocked(&rmesa->radeon);
457
458 dmabuf->id = r300_mem_alloc(rmesa, 4, size);
459
460 UNLOCK_HARDWARE(&rmesa->radeon);
461
462 if (dmabuf->id == 0) {
463 fprintf(stderr,
464 "Error: Could not get dma buffer... exiting\n");
465 _mesa_exit(-1);
466 }
467 }
468
469 rmesa->dma.current.buf = dmabuf;
470 rmesa->dma.current.address = r300_mem_ptr(rmesa, dmabuf->id);
471 rmesa->dma.current.end = size;
472 rmesa->dma.current.start = 0;
473 rmesa->dma.current.ptr = 0;
474 }
475
476 void r300ReleaseDmaRegion(r300ContextPtr rmesa,
477 struct r300_dma_region *region, const char *caller)
478 {
479 if (RADEON_DEBUG & DEBUG_IOCTL)
480 fprintf(stderr, "%s from %s\n", __FUNCTION__, caller);
481
482 if (!region->buf)
483 return;
484
485 if (rmesa->dma.flush)
486 rmesa->dma.flush(rmesa);
487
488 if (--region->buf->refcount == 0) {
489 r300_mem_free(rmesa, region->buf->id);
490 FREE(region->buf);
491 rmesa->dma.nr_released_bufs++;
492 }
493
494 region->buf = 0;
495 region->start = 0;
496 }
497
498 /* Allocates a region from rmesa->dma.current. If there isn't enough
499 * space in current, grab a new buffer (and discard what was left of current)
500 */
501 void r300AllocDmaRegion(r300ContextPtr rmesa,
502 struct r300_dma_region *region,
503 int bytes, int alignment)
504 {
505 if (RADEON_DEBUG & DEBUG_IOCTL)
506 fprintf(stderr, "%s %d\n", __FUNCTION__, bytes);
507
508 if (rmesa->dma.flush)
509 rmesa->dma.flush(rmesa);
510
511 if (region->buf)
512 r300ReleaseDmaRegion(rmesa, region, __FUNCTION__);
513
514 alignment--;
515 rmesa->dma.current.start = rmesa->dma.current.ptr =
516 (rmesa->dma.current.ptr + alignment) & ~alignment;
517
518 if (rmesa->dma.current.ptr + bytes > rmesa->dma.current.end)
519 r300RefillCurrentDmaRegion(rmesa, (bytes + 0x7) & ~0x7);
520
521 region->start = rmesa->dma.current.start;
522 region->ptr = rmesa->dma.current.start;
523 region->end = rmesa->dma.current.start + bytes;
524 region->address = rmesa->dma.current.address;
525 region->buf = rmesa->dma.current.buf;
526 region->buf->refcount++;
527
528 rmesa->dma.current.ptr += bytes; /* bug - if alignment > 7 */
529 rmesa->dma.current.start =
530 rmesa->dma.current.ptr = (rmesa->dma.current.ptr + 0x7) & ~0x7;
531
532 assert(rmesa->dma.current.ptr <= rmesa->dma.current.end);
533 }
534
535 #else
536 static void r300RefillCurrentDmaRegion(r300ContextPtr rmesa)
537 {
538 struct r300_dma_buffer *dmabuf;
539 int fd = rmesa->radeon.dri.fd;
540 int index = 0;
541 int size = 0;
542 drmDMAReq dma;
543 int ret;
544
545 if (RADEON_DEBUG & (DEBUG_IOCTL | DEBUG_DMA))
546 fprintf(stderr, "%s\n", __FUNCTION__);
547
548 if (rmesa->dma.flush) {
549 rmesa->dma.flush(rmesa);
550 }
551
552 if (rmesa->dma.current.buf)
553 r300ReleaseDmaRegion(rmesa, &rmesa->dma.current, __FUNCTION__);
554
555 if (rmesa->dma.nr_released_bufs > 4)
556 r300FlushCmdBuf(rmesa, __FUNCTION__);
557
558 dma.context = rmesa->radeon.dri.hwContext;
559 dma.send_count = 0;
560 dma.send_list = NULL;
561 dma.send_sizes = NULL;
562 dma.flags = 0;
563 dma.request_count = 1;
564 dma.request_size = RADEON_BUFFER_SIZE;
565 dma.request_list = &index;
566 dma.request_sizes = &size;
567 dma.granted_count = 0;
568
569 LOCK_HARDWARE(&rmesa->radeon); /* no need to validate */
570
571 ret = drmDMA(fd, &dma);
572
573 if (ret != 0) {
574 /* Try to release some buffers and wait until we can't get any more */
575 if (rmesa->dma.nr_released_bufs) {
576 r300FlushCmdBufLocked(rmesa, __FUNCTION__);
577 }
578
579 if (RADEON_DEBUG & DEBUG_DMA)
580 fprintf(stderr, "Waiting for buffers\n");
581
582 radeonWaitForIdleLocked(&rmesa->radeon);
583 ret = drmDMA(fd, &dma);
584
585 if (ret != 0) {
586 UNLOCK_HARDWARE(&rmesa->radeon);
587 fprintf(stderr,
588 "Error: Could not get dma buffer... exiting\n");
589 _mesa_exit(-1);
590 }
591 }
592
593 UNLOCK_HARDWARE(&rmesa->radeon);
594
595 if (RADEON_DEBUG & DEBUG_DMA)
596 fprintf(stderr, "Allocated buffer %d\n", index);
597
598 dmabuf = CALLOC_STRUCT(r300_dma_buffer);
599 dmabuf->buf = &rmesa->radeon.radeonScreen->buffers->list[index];
600 dmabuf->refcount = 1;
601
602 rmesa->dma.current.buf = dmabuf;
603 rmesa->dma.current.address = dmabuf->buf->address;
604 rmesa->dma.current.end = dmabuf->buf->total;
605 rmesa->dma.current.start = 0;
606 rmesa->dma.current.ptr = 0;
607 }
608
609 void r300ReleaseDmaRegion(r300ContextPtr rmesa,
610 struct r300_dma_region *region, const char *caller)
611 {
612 if (RADEON_DEBUG & DEBUG_IOCTL)
613 fprintf(stderr, "%s from %s\n", __FUNCTION__, caller);
614
615 if (!region->buf)
616 return;
617
618 if (rmesa->dma.flush)
619 rmesa->dma.flush(rmesa);
620
621 if (--region->buf->refcount == 0) {
622 drm_radeon_cmd_header_t *cmd;
623
624 if (RADEON_DEBUG & (DEBUG_IOCTL | DEBUG_DMA))
625 fprintf(stderr, "%s -- DISCARD BUF %d\n",
626 __FUNCTION__, region->buf->buf->idx);
627 cmd =
628 (drm_radeon_cmd_header_t *) r300AllocCmdBuf(rmesa,
629 sizeof
630 (*cmd) / 4,
631 __FUNCTION__);
632 cmd->dma.cmd_type = R300_CMD_DMA_DISCARD;
633 cmd->dma.buf_idx = region->buf->buf->idx;
634
635 FREE(region->buf);
636 rmesa->dma.nr_released_bufs++;
637 }
638
639 region->buf = 0;
640 region->start = 0;
641 }
642
643 /* Allocates a region from rmesa->dma.current. If there isn't enough
644 * space in current, grab a new buffer (and discard what was left of current)
645 */
646 void r300AllocDmaRegion(r300ContextPtr rmesa,
647 struct r300_dma_region *region,
648 int bytes, int alignment)
649 {
650 if (RADEON_DEBUG & DEBUG_IOCTL)
651 fprintf(stderr, "%s %d\n", __FUNCTION__, bytes);
652
653 if (rmesa->dma.flush)
654 rmesa->dma.flush(rmesa);
655
656 if (region->buf)
657 r300ReleaseDmaRegion(rmesa, region, __FUNCTION__);
658
659 alignment--;
660 rmesa->dma.current.start = rmesa->dma.current.ptr =
661 (rmesa->dma.current.ptr + alignment) & ~alignment;
662
663 if (rmesa->dma.current.ptr + bytes > rmesa->dma.current.end)
664 r300RefillCurrentDmaRegion(rmesa);
665
666 region->start = rmesa->dma.current.start;
667 region->ptr = rmesa->dma.current.start;
668 region->end = rmesa->dma.current.start + bytes;
669 region->address = rmesa->dma.current.address;
670 region->buf = rmesa->dma.current.buf;
671 region->buf->refcount++;
672
673 rmesa->dma.current.ptr += bytes; /* bug - if alignment > 7 */
674 rmesa->dma.current.start =
675 rmesa->dma.current.ptr = (rmesa->dma.current.ptr + 0x7) & ~0x7;
676
677 assert(rmesa->dma.current.ptr <= rmesa->dma.current.end);
678 }
679
680 #endif
681
682 GLboolean r300IsGartMemory(r300ContextPtr rmesa, const GLvoid * pointer,
683 GLint size)
684 {
685 int offset =
686 (char *)pointer -
687 (char *)rmesa->radeon.radeonScreen->gartTextures.map;
688 int valid = (size >= 0 && offset >= 0
689 && offset + size <
690 rmesa->radeon.radeonScreen->gartTextures.size);
691
692 if (RADEON_DEBUG & DEBUG_IOCTL)
693 fprintf(stderr, "r300IsGartMemory( %p ) : %d\n", pointer,
694 valid);
695
696 return valid;
697 }
698
699 GLuint r300GartOffsetFromVirtual(r300ContextPtr rmesa, const GLvoid * pointer)
700 {
701 int offset =
702 (char *)pointer -
703 (char *)rmesa->radeon.radeonScreen->gartTextures.map;
704
705 //fprintf(stderr, "offset=%08x\n", offset);
706
707 if (offset < 0
708 || offset > rmesa->radeon.radeonScreen->gartTextures.size)
709 return ~0;
710 else
711 return rmesa->radeon.radeonScreen->gart_texture_offset + offset;
712 }
713
714 void r300InitIoctlFuncs(struct dd_function_table *functions)
715 {
716 functions->Clear = r300Clear;
717 functions->Finish = radeonFinish;
718 functions->Flush = r300Flush;
719 }