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 r300EmitCacheFlush(rmesa
);
176 cp_wait(rmesa
, R300_WAIT_3D
| R300_WAIT_3D_CLEAN
);
179 static void r300EmitClearState(GLcontext
* ctx
)
181 r300ContextPtr r300
= R300_CONTEXT(ctx
);
182 r300ContextPtr rmesa
= r300
;
183 __DRIdrawablePrivate
*dPriv
= r300
->radeon
.dri
.drawable
;
185 int cmd_reserved
= 0;
187 drm_radeon_cmd_header_t
*cmd
= NULL
;
190 if (!(r300
->radeon
.radeonScreen
->chip_flags
& RADEON_CHIPSET_TCL
))
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.
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.
201 R300_STATECHANGE(r300
, vir
[0]);
202 reg_start(R300_VAP_INPUT_ROUTE_0_0
, 0);
209 R300_STATECHANGE(r300
, fogs
);
210 reg_start(R300_RE_FOG_STATE
, 0);
213 R300_STATECHANGE(r300
, vir
[1]);
214 reg_start(R300_VAP_INPUT_ROUTE_1_0
, 0);
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
);
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
);
232 reg_start(0x21dc, 0);
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 */
241 R300_STATECHANGE(r300
, txe
);
242 reg_start(R300_TX_ENABLE
, 0);
245 R300_STATECHANGE(r300
, vpt
);
246 reg_start(R300_SE_VPORT_XSCALE
, 5);
254 R300_STATECHANGE(r300
, at
);
255 reg_start(R300_PP_ALPHA_TEST
, 0);
258 R300_STATECHANGE(r300
, bld
);
259 reg_start(R300_RB3D_CBLEND
, 1);
263 R300_STATECHANGE(r300
, unk221C
);
264 reg_start(R300_VAP_UNKNOWN_221C
, 0);
265 e32(R300_221C_CLEAR
);
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
));
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
);
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
);
284 R300_STATECHANGE(r300
, rr
);
285 reg_start(R300_RS_ROUTE_0
, 0);
286 e32(R300_RS_ROUTE_0_COLOR
);
288 R300_STATECHANGE(r300
, fp
);
289 reg_start(R300_PFS_CNTL_0
, 2);
293 reg_start(R300_PFS_NODE_0
, 3);
297 e32(R300_PFS_NODE_OUTPUT_COLOR
);
299 R300_STATECHANGE(r300
, fpi
[0]);
300 R300_STATECHANGE(r300
, fpi
[1]);
301 R300_STATECHANGE(r300
, fpi
[2]);
302 R300_STATECHANGE(r300
, fpi
[3]);
304 reg_start(R300_PFS_INSTR0_0
, 0);
305 e32(FP_INSTRC(MAD
, FP_ARGC(SRC0C_XYZ
), FP_ARGC(ONE
), FP_ARGC(ZERO
)));
307 reg_start(R300_PFS_INSTR1_0
, 0);
308 e32(FP_SELC(0, NO
, XYZ
, FP_TMP(0), 0, 0));
310 reg_start(R300_PFS_INSTR2_0
, 0);
311 e32(FP_INSTRA(MAD
, FP_ARGA(SRC0A
), FP_ARGA(ONE
), FP_ARGA(ZERO
)));
313 reg_start(R300_PFS_INSTR3_0
, 0);
314 e32(FP_SELA(0, NO
, W
, FP_TMP(0), 0, 0));
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
));
323 e32(1 << R300_PVS_CNTL_3_PROGRAM_UNKNOWN_SHIFT
);
325 R300_STATECHANGE(r300
, vpi
);
326 vsf_start_fragment(0x0, 8);
327 e32(VP_OUT(ADD
, OUT
, 0, XYZW
));
332 e32(VP_OUT(ADD
, OUT
, 1, XYZW
));
342 static void r300Clear(GLcontext
* ctx
, GLbitfield mask
)
344 r300ContextPtr r300
= R300_CONTEXT(ctx
);
345 __DRIdrawablePrivate
*dPriv
= r300
->radeon
.dri
.drawable
;
350 if (RADEON_DEBUG
& DEBUG_IOCTL
)
351 fprintf(stderr
, "r300Clear\n");
354 LOCK_HARDWARE(&r300
->radeon
);
355 UNLOCK_HARDWARE(&r300
->radeon
);
356 if (dPriv
->numClipRects
== 0)
360 if (mask
& BUFFER_BIT_FRONT_LEFT
) {
361 flags
|= BUFFER_BIT_FRONT_LEFT
;
362 mask
&= ~BUFFER_BIT_FRONT_LEFT
;
365 if (mask
& BUFFER_BIT_BACK_LEFT
) {
366 flags
|= BUFFER_BIT_BACK_LEFT
;
367 mask
&= ~BUFFER_BIT_BACK_LEFT
;
370 if (mask
& BUFFER_BIT_DEPTH
) {
371 bits
|= CLEARBUFFER_DEPTH
;
372 mask
&= ~BUFFER_BIT_DEPTH
;
375 if ((mask
& BUFFER_BIT_STENCIL
) && r300
->state
.stencil
.hw_stencil
) {
376 bits
|= CLEARBUFFER_STENCIL
;
377 mask
&= ~BUFFER_BIT_STENCIL
;
381 if (RADEON_DEBUG
& DEBUG_FALLBACKS
)
382 fprintf(stderr
, "%s: swrast clear, mask: %x\n",
384 _swrast_Clear(ctx
, mask
);
387 swapped
= r300
->radeon
.sarea
->pfCurrentPage
== 1;
389 /* Make sure it fits there. */
390 r300EnsureCmdBufSpace(r300
, 421 * 3, __FUNCTION__
);
392 r300EmitClearState(ctx
);
394 if (flags
& BUFFER_BIT_FRONT_LEFT
) {
395 r300ClearBuffer(r300
, bits
| CLEARBUFFER_COLOR
, swapped
);
399 if (flags
& BUFFER_BIT_BACK_LEFT
) {
400 r300ClearBuffer(r300
, bits
| CLEARBUFFER_COLOR
, swapped
^ 1);
405 r300ClearBuffer(r300
, bits
, 0);
409 void r300Flush(GLcontext
* ctx
)
411 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
413 if (RADEON_DEBUG
& DEBUG_IOCTL
)
414 fprintf(stderr
, "%s\n", __FUNCTION__
);
416 if (rmesa
->dma
.flush
)
417 rmesa
->dma
.flush( rmesa
);
419 if (rmesa
->cmdbuf
.count_used
> rmesa
->cmdbuf
.count_reemit
)
420 r300FlushCmdBuf(rmesa
, __FUNCTION__
);
424 #include "r300_mem.h"
426 void r300RefillCurrentDmaRegion(r300ContextPtr rmesa
, int size
)
428 struct r300_dma_buffer
*dmabuf
;
429 size
= MAX2(size
, RADEON_BUFFER_SIZE
* 16);
431 if (RADEON_DEBUG
& (DEBUG_IOCTL
| DEBUG_DMA
))
432 fprintf(stderr
, "%s\n", __FUNCTION__
);
434 if (rmesa
->dma
.flush
) {
435 rmesa
->dma
.flush(rmesa
);
438 if (rmesa
->dma
.current
.buf
) {
440 r300_mem_use(rmesa
, rmesa
->dma
.current
.buf
->id
);
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
;