Merge branch 'i915-unification' of git+ssh://people.freedesktop.org/~anholt/mesa...
[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 R300_STATECHANGE(r300, vte);
228 /* comes from fglrx startup of clear */
229 reg_start(R300_SE_VTE_CNTL, 1);
230 e32(R300_VTX_W0_FMT | R300_VPORT_X_SCALE_ENA |
231 R300_VPORT_X_OFFSET_ENA | R300_VPORT_Y_SCALE_ENA |
232 R300_VPORT_Y_OFFSET_ENA | R300_VPORT_Z_SCALE_ENA |
233 R300_VPORT_Z_OFFSET_ENA);
234 e32(0x8);
235
236 reg_start(0x21dc, 0);
237 e32(0xaaaaaaaa);
238
239 R300_STATECHANGE(r300, vof);
240 reg_start(R300_VAP_OUTPUT_VTX_FMT_0, 1);
241 e32(R300_VAP_OUTPUT_VTX_FMT_0__POS_PRESENT |
242 R300_VAP_OUTPUT_VTX_FMT_0__COLOR_PRESENT);
243 e32(0x0); /* no textures */
244
245 R300_STATECHANGE(r300, txe);
246 reg_start(R300_TX_ENABLE, 0);
247 e32(0x0);
248
249 R300_STATECHANGE(r300, vpt);
250 reg_start(R300_SE_VPORT_XSCALE, 5);
251 efloat(1.0);
252 efloat(dPriv->x);
253 efloat(1.0);
254 efloat(dPriv->y);
255 efloat(1.0);
256 efloat(0.0);
257
258 R300_STATECHANGE(r300, at);
259 reg_start(R300_PP_ALPHA_TEST, 0);
260 e32(0x0);
261
262 R300_STATECHANGE(r300, bld);
263 reg_start(R300_RB3D_CBLEND, 1);
264 e32(0x0);
265 e32(0x0);
266
267 R300_STATECHANGE(r300, unk221C);
268 reg_start(R300_VAP_UNKNOWN_221C, 0);
269 e32(R300_221C_CLEAR);
270
271 R300_STATECHANGE(r300, ps);
272 reg_start(R300_RE_POINTSIZE, 0);
273 e32(((dPriv->w * 6) << R300_POINTSIZE_X_SHIFT) |
274 ((dPriv->h * 6) << R300_POINTSIZE_Y_SHIFT));
275
276 R300_STATECHANGE(r300, ri);
277 reg_start(R300_RS_INTERP_0, 8);
278 for (i = 0; i < 8; ++i) {
279 e32(R300_RS_INTERP_USED);
280 }
281
282 R300_STATECHANGE(r300, rc);
283 /* The second constant is needed to get glxgears display anything .. */
284 reg_start(R300_RS_CNTL_0, 1);
285 e32((1 << R300_RS_CNTL_CI_CNT_SHIFT) | R300_RS_CNTL_0_UNKNOWN_18);
286 e32(0x0);
287
288 R300_STATECHANGE(r300, rr);
289 reg_start(R300_RS_ROUTE_0, 0);
290 e32(R300_RS_ROUTE_0_COLOR);
291
292 R300_STATECHANGE(r300, fp);
293 reg_start(R300_PFS_CNTL_0, 2);
294 e32(0x0);
295 e32(0x0);
296 e32(0x0);
297 reg_start(R300_PFS_NODE_0, 3);
298 e32(0x0);
299 e32(0x0);
300 e32(0x0);
301 e32(R300_PFS_NODE_OUTPUT_COLOR);
302
303 R300_STATECHANGE(r300, fpi[0]);
304 R300_STATECHANGE(r300, fpi[1]);
305 R300_STATECHANGE(r300, fpi[2]);
306 R300_STATECHANGE(r300, fpi[3]);
307
308 reg_start(R300_PFS_INSTR0_0, 0);
309 e32(FP_INSTRC(MAD, FP_ARGC(SRC0C_XYZ), FP_ARGC(ONE), FP_ARGC(ZERO)));
310
311 reg_start(R300_PFS_INSTR1_0, 0);
312 e32(FP_SELC(0, NO, XYZ, FP_TMP(0), 0, 0));
313
314 reg_start(R300_PFS_INSTR2_0, 0);
315 e32(FP_INSTRA(MAD, FP_ARGA(SRC0A), FP_ARGA(ONE), FP_ARGA(ZERO)));
316
317 reg_start(R300_PFS_INSTR3_0, 0);
318 e32(FP_SELA(0, NO, W, FP_TMP(0), 0, 0));
319
320 if (has_tcl) {
321 R300_STATECHANGE(r300, pvs);
322 reg_start(R300_VAP_PVS_CNTL_1, 2);
323 e32((0 << R300_PVS_CNTL_1_PROGRAM_START_SHIFT) |
324 (0 << R300_PVS_CNTL_1_POS_END_SHIFT) |
325 (1 << R300_PVS_CNTL_1_PROGRAM_END_SHIFT));
326 e32(0x0);
327 e32(1 << R300_PVS_CNTL_3_PROGRAM_UNKNOWN_SHIFT);
328
329 R300_STATECHANGE(r300, vpi);
330 vsf_start_fragment(0x0, 8);
331 e32(VP_OUT(ADD, OUT, 0, XYZW));
332 e32(VP_IN(IN, 0));
333 e32(VP_ZERO());
334 e32(0x0);
335
336 e32(VP_OUT(ADD, OUT, 1, XYZW));
337 e32(VP_IN(IN, 1));
338 e32(VP_ZERO());
339 e32(0x0);
340 }
341 }
342
343 /**
344 * Buffer clear
345 */
346 static void r300Clear(GLcontext * ctx, GLbitfield mask)
347 {
348 r300ContextPtr r300 = R300_CONTEXT(ctx);
349 __DRIdrawablePrivate *dPriv = r300->radeon.dri.drawable;
350 int flags = 0;
351 int bits = 0;
352 int swapped;
353
354 if (RADEON_DEBUG & DEBUG_IOCTL)
355 fprintf(stderr, "r300Clear\n");
356
357 {
358 LOCK_HARDWARE(&r300->radeon);
359 UNLOCK_HARDWARE(&r300->radeon);
360 if (dPriv->numClipRects == 0)
361 return;
362 }
363
364 if (mask & BUFFER_BIT_FRONT_LEFT) {
365 flags |= BUFFER_BIT_FRONT_LEFT;
366 mask &= ~BUFFER_BIT_FRONT_LEFT;
367 }
368
369 if (mask & BUFFER_BIT_BACK_LEFT) {
370 flags |= BUFFER_BIT_BACK_LEFT;
371 mask &= ~BUFFER_BIT_BACK_LEFT;
372 }
373
374 if (mask & BUFFER_BIT_DEPTH) {
375 bits |= CLEARBUFFER_DEPTH;
376 mask &= ~BUFFER_BIT_DEPTH;
377 }
378
379 if ((mask & BUFFER_BIT_STENCIL) && r300->state.stencil.hw_stencil) {
380 bits |= CLEARBUFFER_STENCIL;
381 mask &= ~BUFFER_BIT_STENCIL;
382 }
383
384 if (mask) {
385 if (RADEON_DEBUG & DEBUG_FALLBACKS)
386 fprintf(stderr, "%s: swrast clear, mask: %x\n",
387 __FUNCTION__, mask);
388 _swrast_Clear(ctx, mask);
389 }
390
391 swapped = r300->radeon.sarea->pfCurrentPage == 1;
392
393 /* Make sure it fits there. */
394 r300EnsureCmdBufSpace(r300, 421 * 3, __FUNCTION__);
395 if (flags || bits)
396 r300EmitClearState(ctx);
397
398 if (flags & BUFFER_BIT_FRONT_LEFT) {
399 r300ClearBuffer(r300, bits | CLEARBUFFER_COLOR, swapped);
400 bits = 0;
401 }
402
403 if (flags & BUFFER_BIT_BACK_LEFT) {
404 r300ClearBuffer(r300, bits | CLEARBUFFER_COLOR, swapped ^ 1);
405 bits = 0;
406 }
407
408 if (bits)
409 r300ClearBuffer(r300, bits, 0);
410
411 }
412
413 void r300Flush(GLcontext * ctx)
414 {
415 r300ContextPtr r300 = R300_CONTEXT(ctx);
416
417 if (RADEON_DEBUG & DEBUG_IOCTL)
418 fprintf(stderr, "%s\n", __FUNCTION__);
419
420 if (r300->cmdbuf.count_used > r300->cmdbuf.count_reemit)
421 r300FlushCmdBuf(r300, __FUNCTION__);
422 }
423
424 #ifdef USER_BUFFERS
425 #include "r300_mem.h"
426
427 static void r300RefillCurrentDmaRegion(r300ContextPtr rmesa, int size)
428 {
429 struct r300_dma_buffer *dmabuf;
430 size = MAX2(size, RADEON_BUFFER_SIZE * 16);
431
432 if (RADEON_DEBUG & (DEBUG_IOCTL | DEBUG_DMA))
433 fprintf(stderr, "%s\n", __FUNCTION__);
434
435 if (rmesa->dma.flush) {
436 rmesa->dma.flush(rmesa);
437 }
438
439 if (rmesa->dma.current.buf)
440 r300ReleaseDmaRegion(rmesa, &rmesa->dma.current, __FUNCTION__);
441
442 if (rmesa->dma.nr_released_bufs > 4)
443 r300FlushCmdBuf(rmesa, __FUNCTION__);
444
445 dmabuf = CALLOC_STRUCT(r300_dma_buffer);
446 dmabuf->buf = (void *)1; /* hack */
447 dmabuf->refcount = 1;
448
449 dmabuf->id = r300_mem_alloc(rmesa, 4, size);
450 if (dmabuf->id == 0) {
451 LOCK_HARDWARE(&rmesa->radeon); /* no need to validate */
452
453 r300FlushCmdBufLocked(rmesa, __FUNCTION__);
454 radeonWaitForIdleLocked(&rmesa->radeon);
455
456 dmabuf->id = r300_mem_alloc(rmesa, 4, size);
457
458 UNLOCK_HARDWARE(&rmesa->radeon);
459
460 if (dmabuf->id == 0) {
461 fprintf(stderr,
462 "Error: Could not get dma buffer... exiting\n");
463 _mesa_exit(-1);
464 }
465 }
466
467 rmesa->dma.current.buf = dmabuf;
468 rmesa->dma.current.address = r300_mem_ptr(rmesa, dmabuf->id);
469 rmesa->dma.current.end = size;
470 rmesa->dma.current.start = 0;
471 rmesa->dma.current.ptr = 0;
472 }
473
474 void r300ReleaseDmaRegion(r300ContextPtr rmesa,
475 struct r300_dma_region *region, const char *caller)
476 {
477 if (RADEON_DEBUG & DEBUG_IOCTL)
478 fprintf(stderr, "%s from %s\n", __FUNCTION__, caller);
479
480 if (!region->buf)
481 return;
482
483 if (rmesa->dma.flush)
484 rmesa->dma.flush(rmesa);
485
486 if (--region->buf->refcount == 0) {
487 r300_mem_free(rmesa, region->buf->id);
488 FREE(region->buf);
489 rmesa->dma.nr_released_bufs++;
490 }
491
492 region->buf = 0;
493 region->start = 0;
494 }
495
496 /* Allocates a region from rmesa->dma.current. If there isn't enough
497 * space in current, grab a new buffer (and discard what was left of current)
498 */
499 void r300AllocDmaRegion(r300ContextPtr rmesa,
500 struct r300_dma_region *region,
501 int bytes, int alignment)
502 {
503 if (RADEON_DEBUG & DEBUG_IOCTL)
504 fprintf(stderr, "%s %d\n", __FUNCTION__, bytes);
505
506 if (rmesa->dma.flush)
507 rmesa->dma.flush(rmesa);
508
509 if (region->buf)
510 r300ReleaseDmaRegion(rmesa, region, __FUNCTION__);
511
512 alignment--;
513 rmesa->dma.current.start = rmesa->dma.current.ptr =
514 (rmesa->dma.current.ptr + alignment) & ~alignment;
515
516 if (rmesa->dma.current.ptr + bytes > rmesa->dma.current.end)
517 r300RefillCurrentDmaRegion(rmesa, (bytes + 0x7) & ~0x7);
518
519 region->start = rmesa->dma.current.start;
520 region->ptr = rmesa->dma.current.start;
521 region->end = rmesa->dma.current.start + bytes;
522 region->address = rmesa->dma.current.address;
523 region->buf = rmesa->dma.current.buf;
524 region->buf->refcount++;
525
526 rmesa->dma.current.ptr += bytes; /* bug - if alignment > 7 */
527 rmesa->dma.current.start =
528 rmesa->dma.current.ptr = (rmesa->dma.current.ptr + 0x7) & ~0x7;
529
530 assert(rmesa->dma.current.ptr <= rmesa->dma.current.end);
531 }
532
533 #else
534 static void r300RefillCurrentDmaRegion(r300ContextPtr rmesa)
535 {
536 struct r300_dma_buffer *dmabuf;
537 int fd = rmesa->radeon.dri.fd;
538 int index = 0;
539 int size = 0;
540 drmDMAReq dma;
541 int ret;
542
543 if (RADEON_DEBUG & (DEBUG_IOCTL | DEBUG_DMA))
544 fprintf(stderr, "%s\n", __FUNCTION__);
545
546 if (rmesa->dma.flush) {
547 rmesa->dma.flush(rmesa);
548 }
549
550 if (rmesa->dma.current.buf)
551 r300ReleaseDmaRegion(rmesa, &rmesa->dma.current, __FUNCTION__);
552
553 if (rmesa->dma.nr_released_bufs > 4)
554 r300FlushCmdBuf(rmesa, __FUNCTION__);
555
556 dma.context = rmesa->radeon.dri.hwContext;
557 dma.send_count = 0;
558 dma.send_list = NULL;
559 dma.send_sizes = NULL;
560 dma.flags = 0;
561 dma.request_count = 1;
562 dma.request_size = RADEON_BUFFER_SIZE;
563 dma.request_list = &index;
564 dma.request_sizes = &size;
565 dma.granted_count = 0;
566
567 LOCK_HARDWARE(&rmesa->radeon); /* no need to validate */
568
569 ret = drmDMA(fd, &dma);
570
571 if (ret != 0) {
572 /* Try to release some buffers and wait until we can't get any more */
573 if (rmesa->dma.nr_released_bufs) {
574 r300FlushCmdBufLocked(rmesa, __FUNCTION__);
575 }
576
577 if (RADEON_DEBUG & DEBUG_DMA)
578 fprintf(stderr, "Waiting for buffers\n");
579
580 radeonWaitForIdleLocked(&rmesa->radeon);
581 ret = drmDMA(fd, &dma);
582
583 if (ret != 0) {
584 UNLOCK_HARDWARE(&rmesa->radeon);
585 fprintf(stderr,
586 "Error: Could not get dma buffer... exiting\n");
587 _mesa_exit(-1);
588 }
589 }
590
591 UNLOCK_HARDWARE(&rmesa->radeon);
592
593 if (RADEON_DEBUG & DEBUG_DMA)
594 fprintf(stderr, "Allocated buffer %d\n", index);
595
596 dmabuf = CALLOC_STRUCT(r300_dma_buffer);
597 dmabuf->buf = &rmesa->radeon.radeonScreen->buffers->list[index];
598 dmabuf->refcount = 1;
599
600 rmesa->dma.current.buf = dmabuf;
601 rmesa->dma.current.address = dmabuf->buf->address;
602 rmesa->dma.current.end = dmabuf->buf->total;
603 rmesa->dma.current.start = 0;
604 rmesa->dma.current.ptr = 0;
605 }
606
607 void r300ReleaseDmaRegion(r300ContextPtr rmesa,
608 struct r300_dma_region *region, const char *caller)
609 {
610 if (RADEON_DEBUG & DEBUG_IOCTL)
611 fprintf(stderr, "%s from %s\n", __FUNCTION__, caller);
612
613 if (!region->buf)
614 return;
615
616 if (rmesa->dma.flush)
617 rmesa->dma.flush(rmesa);
618
619 if (--region->buf->refcount == 0) {
620 drm_radeon_cmd_header_t *cmd;
621
622 if (RADEON_DEBUG & (DEBUG_IOCTL | DEBUG_DMA))
623 fprintf(stderr, "%s -- DISCARD BUF %d\n",
624 __FUNCTION__, region->buf->buf->idx);
625 cmd =
626 (drm_radeon_cmd_header_t *) r300AllocCmdBuf(rmesa,
627 sizeof
628 (*cmd) / 4,
629 __FUNCTION__);
630 cmd->dma.cmd_type = R300_CMD_DMA_DISCARD;
631 cmd->dma.buf_idx = region->buf->buf->idx;
632
633 FREE(region->buf);
634 rmesa->dma.nr_released_bufs++;
635 }
636
637 region->buf = 0;
638 region->start = 0;
639 }
640
641 /* Allocates a region from rmesa->dma.current. If there isn't enough
642 * space in current, grab a new buffer (and discard what was left of current)
643 */
644 void r300AllocDmaRegion(r300ContextPtr rmesa,
645 struct r300_dma_region *region,
646 int bytes, int alignment)
647 {
648 if (RADEON_DEBUG & DEBUG_IOCTL)
649 fprintf(stderr, "%s %d\n", __FUNCTION__, bytes);
650
651 if (rmesa->dma.flush)
652 rmesa->dma.flush(rmesa);
653
654 if (region->buf)
655 r300ReleaseDmaRegion(rmesa, region, __FUNCTION__);
656
657 alignment--;
658 rmesa->dma.current.start = rmesa->dma.current.ptr =
659 (rmesa->dma.current.ptr + alignment) & ~alignment;
660
661 if (rmesa->dma.current.ptr + bytes > rmesa->dma.current.end)
662 r300RefillCurrentDmaRegion(rmesa);
663
664 region->start = rmesa->dma.current.start;
665 region->ptr = rmesa->dma.current.start;
666 region->end = rmesa->dma.current.start + bytes;
667 region->address = rmesa->dma.current.address;
668 region->buf = rmesa->dma.current.buf;
669 region->buf->refcount++;
670
671 rmesa->dma.current.ptr += bytes; /* bug - if alignment > 7 */
672 rmesa->dma.current.start =
673 rmesa->dma.current.ptr = (rmesa->dma.current.ptr + 0x7) & ~0x7;
674
675 assert(rmesa->dma.current.ptr <= rmesa->dma.current.end);
676 }
677
678 #endif
679
680 GLboolean r300IsGartMemory(r300ContextPtr rmesa, const GLvoid * pointer,
681 GLint size)
682 {
683 int offset =
684 (char *)pointer -
685 (char *)rmesa->radeon.radeonScreen->gartTextures.map;
686 int valid = (size >= 0 && offset >= 0
687 && offset + size <
688 rmesa->radeon.radeonScreen->gartTextures.size);
689
690 if (RADEON_DEBUG & DEBUG_IOCTL)
691 fprintf(stderr, "r300IsGartMemory( %p ) : %d\n", pointer,
692 valid);
693
694 return valid;
695 }
696
697 GLuint r300GartOffsetFromVirtual(r300ContextPtr rmesa, const GLvoid * pointer)
698 {
699 int offset =
700 (char *)pointer -
701 (char *)rmesa->radeon.radeonScreen->gartTextures.map;
702
703 //fprintf(stderr, "offset=%08x\n", offset);
704
705 if (offset < 0
706 || offset > rmesa->radeon.radeonScreen->gartTextures.size)
707 return ~0;
708 else
709 return rmesa->radeon.radeonScreen->gart_texture_offset + offset;
710 }
711
712 void r300InitIoctlFuncs(struct dd_function_table *functions)
713 {
714 functions->Clear = r300Clear;
715 functions->Finish = radeonFinish;
716 functions->Flush = r300Flush;
717 }