2 Copyright (C) The Weather Channel, Inc. 2002.
3 Copyright (C) 2004 Nicolai Haehnle.
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.
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:
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.
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.
30 **************************************************************************/
35 * \author Keith Whitwell <keith@tungstengraphics.com>
37 * \author Nicolai Haehnle <prefect_@gmx.net>
47 #include "swrast/swrast.h"
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"
60 #define CLEARBUFFER_COLOR 0x1
61 #define CLEARBUFFER_DEPTH 0x2
62 #define CLEARBUFFER_STENCIL 0x4
64 static void r300ClearBuffer(r300ContextPtr r300
, int flags
, int buffer
)
66 GLcontext
*ctx
= r300
->radeon
.glCtx
;
67 __DRIdrawablePrivate
*dPriv
= r300
->radeon
.dri
.drawable
;
68 GLuint cboffset
, cbpitch
;
69 drm_r300_cmd_header_t
*cmd2
;
72 drm_radeon_cmd_header_t
*cmd
= NULL
;
73 r300ContextPtr rmesa
= r300
;
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
);
81 cboffset
= r300
->radeon
.radeonScreen
->backOffset
;
82 cbpitch
= r300
->radeon
.radeonScreen
->backPitch
;
84 cboffset
= r300
->radeon
.radeonScreen
->frontOffset
;
85 cbpitch
= r300
->radeon
.radeonScreen
->frontPitch
;
88 cboffset
+= r300
->radeon
.radeonScreen
->fbLocation
;
90 cp_wait(r300
, R300_WAIT_3D
| R300_WAIT_3D_CLEAN
);
93 R300_STATECHANGE(r300
, cb
);
94 reg_start(R300_RB3D_COLOROFFSET0
, 0);
97 if (r300
->radeon
.radeonScreen
->cpp
== 4)
98 cbpitch
|= R300_COLOR_FORMAT_ARGB8888
;
100 cbpitch
|= R300_COLOR_FORMAT_RGB565
;
102 if (r300
->radeon
.sarea
->tiling_enabled
)
103 cbpitch
|= R300_COLOR_TILE_ENABLE
;
105 reg_start(R300_RB3D_COLORPITCH0
, 0);
108 R300_STATECHANGE(r300
, cmk
);
109 reg_start(R300_RB3D_COLORMASK
, 0);
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));
120 R300_STATECHANGE(r300
, zs
);
121 reg_start(R300_RB3D_ZSTENCIL_CNTL_0
, 2);
129 if (flags
& CLEARBUFFER_DEPTH
) {
130 t1
|= R300_RB3D_Z_WRITE_ONLY
;
132 (R300_ZS_ALWAYS
<< R300_RB3D_ZS1_DEPTH_FUNC_SHIFT
);
134 t1
|= R300_RB3D_Z_DISABLED_1
; // disable
137 if (flags
& CLEARBUFFER_STENCIL
) {
138 t1
|= R300_RB3D_STENCIL_ENABLE
;
141 R300_RB3D_ZS1_FRONT_FUNC_SHIFT
) |
143 R300_RB3D_ZS1_FRONT_FAIL_OP_SHIFT
) |
145 R300_RB3D_ZS1_FRONT_ZPASS_OP_SHIFT
) |
147 R300_RB3D_ZS1_FRONT_ZFAIL_OP_SHIFT
) |
149 R300_RB3D_ZS1_BACK_FUNC_SHIFT
) |
151 R300_RB3D_ZS1_BACK_FAIL_OP_SHIFT
) |
153 R300_RB3D_ZS1_BACK_ZPASS_OP_SHIFT
) |
155 R300_RB3D_ZS1_BACK_ZFAIL_OP_SHIFT
);
160 e32(r300
->state
.stencil
.clear
);
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]);
175 reg_start(R300_RB3D_DSTCACHE_CTLSTAT
, 0);
176 e32(R300_RB3D_DSTCACHE_UNKNOWN_0A
);
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
);
183 static void r300EmitClearState(GLcontext
* ctx
)
185 r300ContextPtr r300
= R300_CONTEXT(ctx
);
186 r300ContextPtr rmesa
= r300
;
187 __DRIdrawablePrivate
*dPriv
= r300
->radeon
.dri
.drawable
;
189 int cmd_reserved
= 0;
191 drm_radeon_cmd_header_t
*cmd
= NULL
;
194 if (!(r300
->radeon
.radeonScreen
->chip_flags
& RADEON_CHIPSET_TCL
))
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.
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.
205 R300_STATECHANGE(r300
, vir
[0]);
206 reg_start(R300_VAP_INPUT_ROUTE_0_0
, 0);
213 R300_STATECHANGE(r300
, fogs
);
214 reg_start(R300_RE_FOG_STATE
, 0);
217 R300_STATECHANGE(r300
, vir
[1]);
218 reg_start(R300_VAP_INPUT_ROUTE_1_0
, 0);
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
);
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
);
237 reg_start(0x21dc, 0);
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 */
247 R300_STATECHANGE(r300
, txe
);
248 reg_start(R300_TX_ENABLE
, 0);
251 R300_STATECHANGE(r300
, vpt
);
252 reg_start(R300_SE_VPORT_XSCALE
, 5);
260 R300_STATECHANGE(r300
, at
);
261 reg_start(R300_PP_ALPHA_TEST
, 0);
264 R300_STATECHANGE(r300
, bld
);
265 reg_start(R300_RB3D_CBLEND
, 1);
269 R300_STATECHANGE(r300
, unk221C
);
270 reg_start(R300_VAP_UNKNOWN_221C
, 0);
271 e32(R300_221C_CLEAR
);
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
));
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
);
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
);
290 R300_STATECHANGE(r300
, rr
);
291 reg_start(R300_RS_ROUTE_0
, 0);
292 e32(R300_RS_ROUTE_0_COLOR
);
294 R300_STATECHANGE(r300
, fp
);
295 reg_start(R300_PFS_CNTL_0
, 2);
299 reg_start(R300_PFS_NODE_0
, 3);
303 e32(R300_PFS_NODE_OUTPUT_COLOR
);
305 R300_STATECHANGE(r300
, fpi
[0]);
306 R300_STATECHANGE(r300
, fpi
[1]);
307 R300_STATECHANGE(r300
, fpi
[2]);
308 R300_STATECHANGE(r300
, fpi
[3]);
310 reg_start(R300_PFS_INSTR0_0
, 0);
311 e32(FP_INSTRC(MAD
, FP_ARGC(SRC0C_XYZ
), FP_ARGC(ONE
), FP_ARGC(ZERO
)));
313 reg_start(R300_PFS_INSTR1_0
, 0);
314 e32(FP_SELC(0, NO
, XYZ
, FP_TMP(0), 0, 0));
316 reg_start(R300_PFS_INSTR2_0
, 0);
317 e32(FP_INSTRA(MAD
, FP_ARGA(SRC0A
), FP_ARGA(ONE
), FP_ARGA(ZERO
)));
319 reg_start(R300_PFS_INSTR3_0
, 0);
320 e32(FP_SELA(0, NO
, W
, FP_TMP(0), 0, 0));
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
));
329 e32(1 << R300_PVS_CNTL_3_PROGRAM_UNKNOWN_SHIFT
);
331 R300_STATECHANGE(r300
, vpi
);
332 vsf_start_fragment(0x0, 8);
333 e32(VP_OUT(ADD
, OUT
, 0, XYZW
));
338 e32(VP_OUT(ADD
, OUT
, 1, XYZW
));
348 static void r300Clear(GLcontext
* ctx
, GLbitfield mask
)
350 r300ContextPtr r300
= R300_CONTEXT(ctx
);
351 __DRIdrawablePrivate
*dPriv
= r300
->radeon
.dri
.drawable
;
356 if (RADEON_DEBUG
& DEBUG_IOCTL
)
357 fprintf(stderr
, "r300Clear\n");
360 LOCK_HARDWARE(&r300
->radeon
);
361 UNLOCK_HARDWARE(&r300
->radeon
);
362 if (dPriv
->numClipRects
== 0)
366 if (mask
& BUFFER_BIT_FRONT_LEFT
) {
367 flags
|= BUFFER_BIT_FRONT_LEFT
;
368 mask
&= ~BUFFER_BIT_FRONT_LEFT
;
371 if (mask
& BUFFER_BIT_BACK_LEFT
) {
372 flags
|= BUFFER_BIT_BACK_LEFT
;
373 mask
&= ~BUFFER_BIT_BACK_LEFT
;
376 if (mask
& BUFFER_BIT_DEPTH
) {
377 bits
|= CLEARBUFFER_DEPTH
;
378 mask
&= ~BUFFER_BIT_DEPTH
;
381 if ((mask
& BUFFER_BIT_STENCIL
) && r300
->state
.stencil
.hw_stencil
) {
382 bits
|= CLEARBUFFER_STENCIL
;
383 mask
&= ~BUFFER_BIT_STENCIL
;
387 if (RADEON_DEBUG
& DEBUG_FALLBACKS
)
388 fprintf(stderr
, "%s: swrast clear, mask: %x\n",
390 _swrast_Clear(ctx
, mask
);
393 swapped
= r300
->radeon
.sarea
->pfCurrentPage
== 1;
395 /* Make sure it fits there. */
396 r300EnsureCmdBufSpace(r300
, 421 * 3, __FUNCTION__
);
398 r300EmitClearState(ctx
);
400 if (flags
& BUFFER_BIT_FRONT_LEFT
) {
401 r300ClearBuffer(r300
, bits
| CLEARBUFFER_COLOR
, swapped
);
405 if (flags
& BUFFER_BIT_BACK_LEFT
) {
406 r300ClearBuffer(r300
, bits
| CLEARBUFFER_COLOR
, swapped
^ 1);
411 r300ClearBuffer(r300
, bits
, 0);
415 void r300Flush(GLcontext
* ctx
)
417 r300ContextPtr r300
= R300_CONTEXT(ctx
);
419 if (RADEON_DEBUG
& DEBUG_IOCTL
)
420 fprintf(stderr
, "%s\n", __FUNCTION__
);
422 if (r300
->cmdbuf
.count_used
> r300
->cmdbuf
.count_reemit
)
423 r300FlushCmdBuf(r300
, __FUNCTION__
);
427 #include "r300_mem.h"
429 static void r300RefillCurrentDmaRegion(r300ContextPtr rmesa
, int size
)
431 struct r300_dma_buffer
*dmabuf
;
432 size
= MAX2(size
, RADEON_BUFFER_SIZE
* 16);
434 if (RADEON_DEBUG
& (DEBUG_IOCTL
| DEBUG_DMA
))
435 fprintf(stderr
, "%s\n", __FUNCTION__
);
437 if (rmesa
->dma
.flush
) {
438 rmesa
->dma
.flush(rmesa
);
441 if (rmesa
->dma
.current
.buf
)
442 r300ReleaseDmaRegion(rmesa
, &rmesa
->dma
.current
, __FUNCTION__
);
444 if (rmesa
->dma
.nr_released_bufs
> 4)
445 r300FlushCmdBuf(rmesa
, __FUNCTION__
);
447 dmabuf
= CALLOC_STRUCT(r300_dma_buffer
);
448 dmabuf
->buf
= (void *)1; /* hack */
449 dmabuf
->refcount
= 1;
451 dmabuf
->id
= r300_mem_alloc(rmesa
, 4, size
);
452 if (dmabuf
->id
== 0) {
453 LOCK_HARDWARE(&rmesa
->radeon
); /* no need to validate */
455 r300FlushCmdBufLocked(rmesa
, __FUNCTION__
);
456 radeonWaitForIdleLocked(&rmesa
->radeon
);
458 dmabuf
->id
= r300_mem_alloc(rmesa
, 4, size
);
460 UNLOCK_HARDWARE(&rmesa
->radeon
);
462 if (dmabuf
->id
== 0) {
464 "Error: Could not get dma buffer... exiting\n");
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;
476 void r300ReleaseDmaRegion(r300ContextPtr rmesa
,
477 struct r300_dma_region
*region
, const char *caller
)
479 if (RADEON_DEBUG
& DEBUG_IOCTL
)
480 fprintf(stderr
, "%s from %s\n", __FUNCTION__
, caller
);
485 if (rmesa
->dma
.flush
)
486 rmesa
->dma
.flush(rmesa
);
488 if (--region
->buf
->refcount
== 0) {
489 r300_mem_free(rmesa
, region
->buf
->id
);
491 rmesa
->dma
.nr_released_bufs
++;
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)
501 void r300AllocDmaRegion(r300ContextPtr rmesa
,
502 struct r300_dma_region
*region
,
503 int bytes
, int alignment
)
505 if (RADEON_DEBUG
& DEBUG_IOCTL
)
506 fprintf(stderr
, "%s %d\n", __FUNCTION__
, bytes
);
508 if (rmesa
->dma
.flush
)
509 rmesa
->dma
.flush(rmesa
);
512 r300ReleaseDmaRegion(rmesa
, region
, __FUNCTION__
);
515 rmesa
->dma
.current
.start
= rmesa
->dma
.current
.ptr
=
516 (rmesa
->dma
.current
.ptr
+ alignment
) & ~alignment
;
518 if (rmesa
->dma
.current
.ptr
+ bytes
> rmesa
->dma
.current
.end
)
519 r300RefillCurrentDmaRegion(rmesa
, (bytes
+ 0x7) & ~0x7);
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
++;
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;
532 assert(rmesa
->dma
.current
.ptr
<= rmesa
->dma
.current
.end
);
536 static void r300RefillCurrentDmaRegion(r300ContextPtr rmesa
)
538 struct r300_dma_buffer
*dmabuf
;
539 int fd
= rmesa
->radeon
.dri
.fd
;
545 if (RADEON_DEBUG
& (DEBUG_IOCTL
| DEBUG_DMA
))
546 fprintf(stderr
, "%s\n", __FUNCTION__
);
548 if (rmesa
->dma
.flush
) {
549 rmesa
->dma
.flush(rmesa
);
552 if (rmesa
->dma
.current
.buf
)
553 r300ReleaseDmaRegion(rmesa
, &rmesa
->dma
.current
, __FUNCTION__
);
555 if (rmesa
->dma
.nr_released_bufs
> 4)
556 r300FlushCmdBuf(rmesa
, __FUNCTION__
);
558 dma
.context
= rmesa
->radeon
.dri
.hwContext
;
560 dma
.send_list
= NULL
;
561 dma
.send_sizes
= NULL
;
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;
569 LOCK_HARDWARE(&rmesa
->radeon
); /* no need to validate */
571 ret
= drmDMA(fd
, &dma
);
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__
);
579 if (RADEON_DEBUG
& DEBUG_DMA
)
580 fprintf(stderr
, "Waiting for buffers\n");
582 radeonWaitForIdleLocked(&rmesa
->radeon
);
583 ret
= drmDMA(fd
, &dma
);
586 UNLOCK_HARDWARE(&rmesa
->radeon
);
588 "Error: Could not get dma buffer... exiting\n");
593 UNLOCK_HARDWARE(&rmesa
->radeon
);
595 if (RADEON_DEBUG
& DEBUG_DMA
)
596 fprintf(stderr
, "Allocated buffer %d\n", index
);
598 dmabuf
= CALLOC_STRUCT(r300_dma_buffer
);
599 dmabuf
->buf
= &rmesa
->radeon
.radeonScreen
->buffers
->list
[index
];
600 dmabuf
->refcount
= 1;
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;
609 void r300ReleaseDmaRegion(r300ContextPtr rmesa
,
610 struct r300_dma_region
*region
, const char *caller
)
612 if (RADEON_DEBUG
& DEBUG_IOCTL
)
613 fprintf(stderr
, "%s from %s\n", __FUNCTION__
, caller
);
618 if (rmesa
->dma
.flush
)
619 rmesa
->dma
.flush(rmesa
);
621 if (--region
->buf
->refcount
== 0) {
622 drm_radeon_cmd_header_t
*cmd
;
624 if (RADEON_DEBUG
& (DEBUG_IOCTL
| DEBUG_DMA
))
625 fprintf(stderr
, "%s -- DISCARD BUF %d\n",
626 __FUNCTION__
, region
->buf
->buf
->idx
);
628 (drm_radeon_cmd_header_t
*) r300AllocCmdBuf(rmesa
,
632 cmd
->dma
.cmd_type
= R300_CMD_DMA_DISCARD
;
633 cmd
->dma
.buf_idx
= region
->buf
->buf
->idx
;
636 rmesa
->dma
.nr_released_bufs
++;
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)
646 void r300AllocDmaRegion(r300ContextPtr rmesa
,
647 struct r300_dma_region
*region
,
648 int bytes
, int alignment
)
650 if (RADEON_DEBUG
& DEBUG_IOCTL
)
651 fprintf(stderr
, "%s %d\n", __FUNCTION__
, bytes
);
653 if (rmesa
->dma
.flush
)
654 rmesa
->dma
.flush(rmesa
);
657 r300ReleaseDmaRegion(rmesa
, region
, __FUNCTION__
);
660 rmesa
->dma
.current
.start
= rmesa
->dma
.current
.ptr
=
661 (rmesa
->dma
.current
.ptr
+ alignment
) & ~alignment
;
663 if (rmesa
->dma
.current
.ptr
+ bytes
> rmesa
->dma
.current
.end
)
664 r300RefillCurrentDmaRegion(rmesa
);
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
++;
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;
677 assert(rmesa
->dma
.current
.ptr
<= rmesa
->dma
.current
.end
);
682 GLboolean
r300IsGartMemory(r300ContextPtr rmesa
, const GLvoid
* pointer
,
687 (char *)rmesa
->radeon
.radeonScreen
->gartTextures
.map
;
688 int valid
= (size
>= 0 && offset
>= 0
690 rmesa
->radeon
.radeonScreen
->gartTextures
.size
);
692 if (RADEON_DEBUG
& DEBUG_IOCTL
)
693 fprintf(stderr
, "r300IsGartMemory( %p ) : %d\n", pointer
,
699 GLuint
r300GartOffsetFromVirtual(r300ContextPtr rmesa
, const GLvoid
* pointer
)
703 (char *)rmesa
->radeon
.radeonScreen
->gartTextures
.map
;
705 //fprintf(stderr, "offset=%08x\n", offset);
708 || offset
> rmesa
->radeon
.radeonScreen
->gartTextures
.size
)
711 return rmesa
->radeon
.radeonScreen
->gart_texture_offset
+ offset
;
714 void r300InitIoctlFuncs(struct dd_function_table
*functions
)
716 functions
->Clear
= r300Clear
;
717 functions
->Finish
= radeonFinish
;
718 functions
->Flush
= r300Flush
;