Added few more stubs so that control reaches to DestroyDevice().
[mesa.git] / 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 r300EmitCacheFlush(rmesa);
176 cp_wait(rmesa, R300_WAIT_3D | R300_WAIT_3D_CLEAN);
177 }
178
179 static void r300EmitClearState(GLcontext * ctx)
180 {
181 r300ContextPtr r300 = R300_CONTEXT(ctx);
182 r300ContextPtr rmesa = r300;
183 __DRIdrawablePrivate *dPriv = r300->radeon.dri.drawable;
184 int i;
185 int cmd_reserved = 0;
186 int cmd_written = 0;
187 drm_radeon_cmd_header_t *cmd = NULL;
188 int has_tcl = 1;
189
190 if (!(r300->radeon.radeonScreen->chip_flags & RADEON_CHIPSET_TCL))
191 has_tcl = 0;
192
193 /* FIXME: the values written to R300_VAP_INPUT_ROUTE_0_0 and
194 * R300_VAP_INPUT_ROUTE_0_1 are in fact known, however, the values are
195 * quite complex; see the functions in r300_emit.c.
196 *
197 * I believe it would be a good idea to extend the functions in
198 * r300_emit.c so that they can be used to setup the default values for
199 * these registers, as well as the actual values used for rendering.
200 */
201 R300_STATECHANGE(r300, vir[0]);
202 reg_start(R300_VAP_INPUT_ROUTE_0_0, 0);
203 if (!has_tcl)
204 e32(0x22030003);
205 else
206 e32(0x21030003);
207
208 /* disable fog */
209 R300_STATECHANGE(r300, fogs);
210 reg_start(R300_RE_FOG_STATE, 0);
211 e32(0x0);
212
213 R300_STATECHANGE(r300, vir[1]);
214 reg_start(R300_VAP_INPUT_ROUTE_1_0, 0);
215 e32(0xF688F688);
216
217 /* R300_VAP_INPUT_CNTL_0, R300_VAP_INPUT_CNTL_1 */
218 R300_STATECHANGE(r300, vic);
219 reg_start(R300_VAP_INPUT_CNTL_0, 1);
220 e32(R300_INPUT_CNTL_0_COLOR);
221 e32(R300_INPUT_CNTL_POS | R300_INPUT_CNTL_COLOR | R300_INPUT_CNTL_TC0);
222
223 R300_STATECHANGE(r300, vte);
224 /* comes from fglrx startup of clear */
225 reg_start(R300_SE_VTE_CNTL, 1);
226 e32(R300_VTX_W0_FMT | R300_VPORT_X_SCALE_ENA |
227 R300_VPORT_X_OFFSET_ENA | R300_VPORT_Y_SCALE_ENA |
228 R300_VPORT_Y_OFFSET_ENA | R300_VPORT_Z_SCALE_ENA |
229 R300_VPORT_Z_OFFSET_ENA);
230 e32(0x8);
231
232 reg_start(0x21dc, 0);
233 e32(0xaaaaaaaa);
234
235 R300_STATECHANGE(r300, vof);
236 reg_start(R300_VAP_OUTPUT_VTX_FMT_0, 1);
237 e32(R300_VAP_OUTPUT_VTX_FMT_0__POS_PRESENT |
238 R300_VAP_OUTPUT_VTX_FMT_0__COLOR_PRESENT);
239 e32(0x0); /* no textures */
240
241 R300_STATECHANGE(r300, txe);
242 reg_start(R300_TX_ENABLE, 0);
243 e32(0x0);
244
245 R300_STATECHANGE(r300, vpt);
246 reg_start(R300_SE_VPORT_XSCALE, 5);
247 efloat(1.0);
248 efloat(dPriv->x);
249 efloat(1.0);
250 efloat(dPriv->y);
251 efloat(1.0);
252 efloat(0.0);
253
254 R300_STATECHANGE(r300, at);
255 reg_start(R300_PP_ALPHA_TEST, 0);
256 e32(0x0);
257
258 R300_STATECHANGE(r300, bld);
259 reg_start(R300_RB3D_CBLEND, 1);
260 e32(0x0);
261 e32(0x0);
262
263 R300_STATECHANGE(r300, unk221C);
264 reg_start(R300_VAP_UNKNOWN_221C, 0);
265 e32(R300_221C_CLEAR);
266
267 R300_STATECHANGE(r300, ps);
268 reg_start(R300_RE_POINTSIZE, 0);
269 e32(((dPriv->w * 6) << R300_POINTSIZE_X_SHIFT) |
270 ((dPriv->h * 6) << R300_POINTSIZE_Y_SHIFT));
271
272 R300_STATECHANGE(r300, ri);
273 reg_start(R300_RS_INTERP_0, 8);
274 for (i = 0; i < 8; ++i) {
275 e32(R300_RS_INTERP_USED);
276 }
277
278 R300_STATECHANGE(r300, rc);
279 /* The second constant is needed to get glxgears display anything .. */
280 reg_start(R300_RS_CNTL_0, 1);
281 e32((1 << R300_RS_CNTL_CI_CNT_SHIFT) | R300_RS_CNTL_0_UNKNOWN_18);
282 e32(0x0);
283
284 R300_STATECHANGE(r300, rr);
285 reg_start(R300_RS_ROUTE_0, 0);
286 e32(R300_RS_ROUTE_0_COLOR);
287
288 R300_STATECHANGE(r300, fp);
289 reg_start(R300_PFS_CNTL_0, 2);
290 e32(0x0);
291 e32(0x0);
292 e32(0x0);
293 reg_start(R300_PFS_NODE_0, 3);
294 e32(0x0);
295 e32(0x0);
296 e32(0x0);
297 e32(R300_PFS_NODE_OUTPUT_COLOR);
298
299 R300_STATECHANGE(r300, fpi[0]);
300 R300_STATECHANGE(r300, fpi[1]);
301 R300_STATECHANGE(r300, fpi[2]);
302 R300_STATECHANGE(r300, fpi[3]);
303
304 reg_start(R300_PFS_INSTR0_0, 0);
305 e32(FP_INSTRC(MAD, FP_ARGC(SRC0C_XYZ), FP_ARGC(ONE), FP_ARGC(ZERO)));
306
307 reg_start(R300_PFS_INSTR1_0, 0);
308 e32(FP_SELC(0, NO, XYZ, FP_TMP(0), 0, 0));
309
310 reg_start(R300_PFS_INSTR2_0, 0);
311 e32(FP_INSTRA(MAD, FP_ARGA(SRC0A), FP_ARGA(ONE), FP_ARGA(ZERO)));
312
313 reg_start(R300_PFS_INSTR3_0, 0);
314 e32(FP_SELA(0, NO, W, FP_TMP(0), 0, 0));
315
316 if (has_tcl) {
317 R300_STATECHANGE(r300, pvs);
318 reg_start(R300_VAP_PVS_CNTL_1, 2);
319 e32((0 << R300_PVS_CNTL_1_PROGRAM_START_SHIFT) |
320 (0 << R300_PVS_CNTL_1_POS_END_SHIFT) |
321 (1 << R300_PVS_CNTL_1_PROGRAM_END_SHIFT));
322 e32(0x0);
323 e32(1 << R300_PVS_CNTL_3_PROGRAM_UNKNOWN_SHIFT);
324
325 R300_STATECHANGE(r300, vpi);
326 vsf_start_fragment(0x0, 8);
327 e32(VP_OUT(ADD, OUT, 0, XYZW));
328 e32(VP_IN(IN, 0));
329 e32(VP_ZERO());
330 e32(0x0);
331
332 e32(VP_OUT(ADD, OUT, 1, XYZW));
333 e32(VP_IN(IN, 1));
334 e32(VP_ZERO());
335 e32(0x0);
336 }
337 }
338
339 /**
340 * Buffer clear
341 */
342 static void r300Clear(GLcontext * ctx, GLbitfield mask)
343 {
344 r300ContextPtr r300 = R300_CONTEXT(ctx);
345 __DRIdrawablePrivate *dPriv = r300->radeon.dri.drawable;
346 int flags = 0;
347 int bits = 0;
348 int swapped;
349
350 if (RADEON_DEBUG & DEBUG_IOCTL)
351 fprintf(stderr, "r300Clear\n");
352
353 {
354 LOCK_HARDWARE(&r300->radeon);
355 UNLOCK_HARDWARE(&r300->radeon);
356 if (dPriv->numClipRects == 0)
357 return;
358 }
359
360 if (mask & BUFFER_BIT_FRONT_LEFT) {
361 flags |= BUFFER_BIT_FRONT_LEFT;
362 mask &= ~BUFFER_BIT_FRONT_LEFT;
363 }
364
365 if (mask & BUFFER_BIT_BACK_LEFT) {
366 flags |= BUFFER_BIT_BACK_LEFT;
367 mask &= ~BUFFER_BIT_BACK_LEFT;
368 }
369
370 if (mask & BUFFER_BIT_DEPTH) {
371 bits |= CLEARBUFFER_DEPTH;
372 mask &= ~BUFFER_BIT_DEPTH;
373 }
374
375 if ((mask & BUFFER_BIT_STENCIL) && r300->state.stencil.hw_stencil) {
376 bits |= CLEARBUFFER_STENCIL;
377 mask &= ~BUFFER_BIT_STENCIL;
378 }
379
380 if (mask) {
381 if (RADEON_DEBUG & DEBUG_FALLBACKS)
382 fprintf(stderr, "%s: swrast clear, mask: %x\n",
383 __FUNCTION__, mask);
384 _swrast_Clear(ctx, mask);
385 }
386
387 swapped = r300->radeon.sarea->pfCurrentPage == 1;
388
389 /* Make sure it fits there. */
390 r300EnsureCmdBufSpace(r300, 421 * 3, __FUNCTION__);
391 if (flags || bits)
392 r300EmitClearState(ctx);
393
394 if (flags & BUFFER_BIT_FRONT_LEFT) {
395 r300ClearBuffer(r300, bits | CLEARBUFFER_COLOR, swapped);
396 bits = 0;
397 }
398
399 if (flags & BUFFER_BIT_BACK_LEFT) {
400 r300ClearBuffer(r300, bits | CLEARBUFFER_COLOR, swapped ^ 1);
401 bits = 0;
402 }
403
404 if (bits)
405 r300ClearBuffer(r300, bits, 0);
406
407 }
408
409 void r300Flush(GLcontext * ctx)
410 {
411 r300ContextPtr rmesa = R300_CONTEXT(ctx);
412
413 if (RADEON_DEBUG & DEBUG_IOCTL)
414 fprintf(stderr, "%s\n", __FUNCTION__);
415
416 if (rmesa->dma.flush)
417 rmesa->dma.flush( rmesa );
418
419 if (rmesa->cmdbuf.count_used > rmesa->cmdbuf.count_reemit)
420 r300FlushCmdBuf(rmesa, __FUNCTION__);
421 }
422
423 #ifdef USER_BUFFERS
424 #include "r300_mem.h"
425
426 void r300RefillCurrentDmaRegion(r300ContextPtr rmesa, int size)
427 {
428 struct r300_dma_buffer *dmabuf;
429 size = MAX2(size, RADEON_BUFFER_SIZE * 16);
430
431 if (RADEON_DEBUG & (DEBUG_IOCTL | DEBUG_DMA))
432 fprintf(stderr, "%s\n", __FUNCTION__);
433
434 if (rmesa->dma.flush) {
435 rmesa->dma.flush(rmesa);
436 }
437
438 if (rmesa->dma.current.buf) {
439 #ifdef USER_BUFFERS
440 r300_mem_use(rmesa, rmesa->dma.current.buf->id);
441 #endif
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 }