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
);
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
);
236 reg_start(0x21dc, 0);
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 */
245 R300_STATECHANGE(r300
, txe
);
246 reg_start(R300_TX_ENABLE
, 0);
249 R300_STATECHANGE(r300
, vpt
);
250 reg_start(R300_SE_VPORT_XSCALE
, 5);
258 R300_STATECHANGE(r300
, at
);
259 reg_start(R300_PP_ALPHA_TEST
, 0);
262 R300_STATECHANGE(r300
, bld
);
263 reg_start(R300_RB3D_CBLEND
, 1);
267 R300_STATECHANGE(r300
, unk221C
);
268 reg_start(R300_VAP_UNKNOWN_221C
, 0);
269 e32(R300_221C_CLEAR
);
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
));
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
);
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
);
288 R300_STATECHANGE(r300
, rr
);
289 reg_start(R300_RS_ROUTE_0
, 0);
290 e32(R300_RS_ROUTE_0_COLOR
);
292 R300_STATECHANGE(r300
, fp
);
293 reg_start(R300_PFS_CNTL_0
, 2);
297 reg_start(R300_PFS_NODE_0
, 3);
301 e32(R300_PFS_NODE_OUTPUT_COLOR
);
303 R300_STATECHANGE(r300
, fpi
[0]);
304 R300_STATECHANGE(r300
, fpi
[1]);
305 R300_STATECHANGE(r300
, fpi
[2]);
306 R300_STATECHANGE(r300
, fpi
[3]);
308 reg_start(R300_PFS_INSTR0_0
, 0);
309 e32(FP_INSTRC(MAD
, FP_ARGC(SRC0C_XYZ
), FP_ARGC(ONE
), FP_ARGC(ZERO
)));
311 reg_start(R300_PFS_INSTR1_0
, 0);
312 e32(FP_SELC(0, NO
, XYZ
, FP_TMP(0), 0, 0));
314 reg_start(R300_PFS_INSTR2_0
, 0);
315 e32(FP_INSTRA(MAD
, FP_ARGA(SRC0A
), FP_ARGA(ONE
), FP_ARGA(ZERO
)));
317 reg_start(R300_PFS_INSTR3_0
, 0);
318 e32(FP_SELA(0, NO
, W
, FP_TMP(0), 0, 0));
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
));
327 e32(1 << R300_PVS_CNTL_3_PROGRAM_UNKNOWN_SHIFT
);
329 R300_STATECHANGE(r300
, vpi
);
330 vsf_start_fragment(0x0, 8);
331 e32(VP_OUT(ADD
, OUT
, 0, XYZW
));
336 e32(VP_OUT(ADD
, OUT
, 1, XYZW
));
346 static void r300Clear(GLcontext
* ctx
, GLbitfield mask
)
348 r300ContextPtr r300
= R300_CONTEXT(ctx
);
349 __DRIdrawablePrivate
*dPriv
= r300
->radeon
.dri
.drawable
;
354 if (RADEON_DEBUG
& DEBUG_IOCTL
)
355 fprintf(stderr
, "r300Clear\n");
358 LOCK_HARDWARE(&r300
->radeon
);
359 UNLOCK_HARDWARE(&r300
->radeon
);
360 if (dPriv
->numClipRects
== 0)
364 if (mask
& BUFFER_BIT_FRONT_LEFT
) {
365 flags
|= BUFFER_BIT_FRONT_LEFT
;
366 mask
&= ~BUFFER_BIT_FRONT_LEFT
;
369 if (mask
& BUFFER_BIT_BACK_LEFT
) {
370 flags
|= BUFFER_BIT_BACK_LEFT
;
371 mask
&= ~BUFFER_BIT_BACK_LEFT
;
374 if (mask
& BUFFER_BIT_DEPTH
) {
375 bits
|= CLEARBUFFER_DEPTH
;
376 mask
&= ~BUFFER_BIT_DEPTH
;
379 if ((mask
& BUFFER_BIT_STENCIL
) && r300
->state
.stencil
.hw_stencil
) {
380 bits
|= CLEARBUFFER_STENCIL
;
381 mask
&= ~BUFFER_BIT_STENCIL
;
385 if (RADEON_DEBUG
& DEBUG_FALLBACKS
)
386 fprintf(stderr
, "%s: swrast clear, mask: %x\n",
388 _swrast_Clear(ctx
, mask
);
391 swapped
= r300
->radeon
.sarea
->pfCurrentPage
== 1;
393 /* Make sure it fits there. */
394 r300EnsureCmdBufSpace(r300
, 421 * 3, __FUNCTION__
);
396 r300EmitClearState(ctx
);
398 if (flags
& BUFFER_BIT_FRONT_LEFT
) {
399 r300ClearBuffer(r300
, bits
| CLEARBUFFER_COLOR
, swapped
);
403 if (flags
& BUFFER_BIT_BACK_LEFT
) {
404 r300ClearBuffer(r300
, bits
| CLEARBUFFER_COLOR
, swapped
^ 1);
409 r300ClearBuffer(r300
, bits
, 0);
413 void r300Flush(GLcontext
* ctx
)
415 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
417 if (RADEON_DEBUG
& DEBUG_IOCTL
)
418 fprintf(stderr
, "%s\n", __FUNCTION__
);
420 if (rmesa
->dma
.flush
)
421 rmesa
->dma
.flush( rmesa
);
423 if (rmesa
->cmdbuf
.count_used
> rmesa
->cmdbuf
.count_reemit
)
424 r300FlushCmdBuf(rmesa
, __FUNCTION__
);
428 #include "r300_mem.h"
430 void r300RefillCurrentDmaRegion(r300ContextPtr rmesa
, int size
)
432 struct r300_dma_buffer
*dmabuf
;
433 size
= MAX2(size
, RADEON_BUFFER_SIZE
* 16);
435 if (RADEON_DEBUG
& (DEBUG_IOCTL
| DEBUG_DMA
))
436 fprintf(stderr
, "%s\n", __FUNCTION__
);
438 if (rmesa
->dma
.flush
) {
439 rmesa
->dma
.flush(rmesa
);
442 if (rmesa
->dma
.current
.buf
)
443 r300ReleaseDmaRegion(rmesa
, &rmesa
->dma
.current
, __FUNCTION__
);
445 if (rmesa
->dma
.nr_released_bufs
> 4)
446 r300FlushCmdBuf(rmesa
, __FUNCTION__
);
448 dmabuf
= CALLOC_STRUCT(r300_dma_buffer
);
449 dmabuf
->buf
= (void *)1; /* hack */
450 dmabuf
->refcount
= 1;
452 dmabuf
->id
= r300_mem_alloc(rmesa
, 4, size
);
453 if (dmabuf
->id
== 0) {
454 LOCK_HARDWARE(&rmesa
->radeon
); /* no need to validate */
456 r300FlushCmdBufLocked(rmesa
, __FUNCTION__
);
457 radeonWaitForIdleLocked(&rmesa
->radeon
);
459 dmabuf
->id
= r300_mem_alloc(rmesa
, 4, size
);
461 UNLOCK_HARDWARE(&rmesa
->radeon
);
463 if (dmabuf
->id
== 0) {
465 "Error: Could not get dma buffer... exiting\n");
470 rmesa
->dma
.current
.buf
= dmabuf
;
471 rmesa
->dma
.current
.address
= r300_mem_ptr(rmesa
, dmabuf
->id
);
472 rmesa
->dma
.current
.end
= size
;
473 rmesa
->dma
.current
.start
= 0;
474 rmesa
->dma
.current
.ptr
= 0;
477 void r300ReleaseDmaRegion(r300ContextPtr rmesa
,
478 struct r300_dma_region
*region
, const char *caller
)
480 if (RADEON_DEBUG
& DEBUG_IOCTL
)
481 fprintf(stderr
, "%s from %s\n", __FUNCTION__
, caller
);
486 if (rmesa
->dma
.flush
)
487 rmesa
->dma
.flush(rmesa
);
489 if (--region
->buf
->refcount
== 0) {
490 r300_mem_free(rmesa
, region
->buf
->id
);
492 rmesa
->dma
.nr_released_bufs
++;
499 /* Allocates a region from rmesa->dma.current. If there isn't enough
500 * space in current, grab a new buffer (and discard what was left of current)
502 void r300AllocDmaRegion(r300ContextPtr rmesa
,
503 struct r300_dma_region
*region
,
504 int bytes
, int alignment
)
506 if (RADEON_DEBUG
& DEBUG_IOCTL
)
507 fprintf(stderr
, "%s %d\n", __FUNCTION__
, bytes
);
509 if (rmesa
->dma
.flush
)
510 rmesa
->dma
.flush(rmesa
);
513 r300ReleaseDmaRegion(rmesa
, region
, __FUNCTION__
);
516 rmesa
->dma
.current
.start
= rmesa
->dma
.current
.ptr
=
517 (rmesa
->dma
.current
.ptr
+ alignment
) & ~alignment
;
519 if (rmesa
->dma
.current
.ptr
+ bytes
> rmesa
->dma
.current
.end
)
520 r300RefillCurrentDmaRegion(rmesa
, (bytes
+ 0x7) & ~0x7);
522 region
->start
= rmesa
->dma
.current
.start
;
523 region
->ptr
= rmesa
->dma
.current
.start
;
524 region
->end
= rmesa
->dma
.current
.start
+ bytes
;
525 region
->address
= rmesa
->dma
.current
.address
;
526 region
->buf
= rmesa
->dma
.current
.buf
;
527 region
->buf
->refcount
++;
529 rmesa
->dma
.current
.ptr
+= bytes
; /* bug - if alignment > 7 */
530 rmesa
->dma
.current
.start
=
531 rmesa
->dma
.current
.ptr
= (rmesa
->dma
.current
.ptr
+ 0x7) & ~0x7;
533 assert(rmesa
->dma
.current
.ptr
<= rmesa
->dma
.current
.end
);
537 static void r300RefillCurrentDmaRegion(r300ContextPtr rmesa
)
539 struct r300_dma_buffer
*dmabuf
;
540 int fd
= rmesa
->radeon
.dri
.fd
;
546 if (RADEON_DEBUG
& (DEBUG_IOCTL
| DEBUG_DMA
))
547 fprintf(stderr
, "%s\n", __FUNCTION__
);
549 if (rmesa
->dma
.flush
) {
550 rmesa
->dma
.flush(rmesa
);
553 if (rmesa
->dma
.current
.buf
)
554 r300ReleaseDmaRegion(rmesa
, &rmesa
->dma
.current
, __FUNCTION__
);
556 if (rmesa
->dma
.nr_released_bufs
> 4)
557 r300FlushCmdBuf(rmesa
, __FUNCTION__
);
559 dma
.context
= rmesa
->radeon
.dri
.hwContext
;
561 dma
.send_list
= NULL
;
562 dma
.send_sizes
= NULL
;
564 dma
.request_count
= 1;
565 dma
.request_size
= RADEON_BUFFER_SIZE
;
566 dma
.request_list
= &index
;
567 dma
.request_sizes
= &size
;
568 dma
.granted_count
= 0;
570 LOCK_HARDWARE(&rmesa
->radeon
); /* no need to validate */
572 ret
= drmDMA(fd
, &dma
);
575 /* Try to release some buffers and wait until we can't get any more */
576 if (rmesa
->dma
.nr_released_bufs
) {
577 r300FlushCmdBufLocked(rmesa
, __FUNCTION__
);
580 if (RADEON_DEBUG
& DEBUG_DMA
)
581 fprintf(stderr
, "Waiting for buffers\n");
583 radeonWaitForIdleLocked(&rmesa
->radeon
);
584 ret
= drmDMA(fd
, &dma
);
587 UNLOCK_HARDWARE(&rmesa
->radeon
);
589 "Error: Could not get dma buffer... exiting\n");
594 UNLOCK_HARDWARE(&rmesa
->radeon
);
596 if (RADEON_DEBUG
& DEBUG_DMA
)
597 fprintf(stderr
, "Allocated buffer %d\n", index
);
599 dmabuf
= CALLOC_STRUCT(r300_dma_buffer
);
600 dmabuf
->buf
= &rmesa
->radeon
.radeonScreen
->buffers
->list
[index
];
601 dmabuf
->refcount
= 1;
603 rmesa
->dma
.current
.buf
= dmabuf
;
604 rmesa
->dma
.current
.address
= dmabuf
->buf
->address
;
605 rmesa
->dma
.current
.end
= dmabuf
->buf
->total
;
606 rmesa
->dma
.current
.start
= 0;
607 rmesa
->dma
.current
.ptr
= 0;
610 void r300ReleaseDmaRegion(r300ContextPtr rmesa
,
611 struct r300_dma_region
*region
, const char *caller
)
613 if (RADEON_DEBUG
& DEBUG_IOCTL
)
614 fprintf(stderr
, "%s from %s\n", __FUNCTION__
, caller
);
619 if (rmesa
->dma
.flush
)
620 rmesa
->dma
.flush(rmesa
);
622 if (--region
->buf
->refcount
== 0) {
623 drm_radeon_cmd_header_t
*cmd
;
625 if (RADEON_DEBUG
& (DEBUG_IOCTL
| DEBUG_DMA
))
626 fprintf(stderr
, "%s -- DISCARD BUF %d\n",
627 __FUNCTION__
, region
->buf
->buf
->idx
);
629 (drm_radeon_cmd_header_t
*) r300AllocCmdBuf(rmesa
,
633 cmd
->dma
.cmd_type
= R300_CMD_DMA_DISCARD
;
634 cmd
->dma
.buf_idx
= region
->buf
->buf
->idx
;
637 rmesa
->dma
.nr_released_bufs
++;
644 /* Allocates a region from rmesa->dma.current. If there isn't enough
645 * space in current, grab a new buffer (and discard what was left of current)
647 void r300AllocDmaRegion(r300ContextPtr rmesa
,
648 struct r300_dma_region
*region
,
649 int bytes
, int alignment
)
651 if (RADEON_DEBUG
& DEBUG_IOCTL
)
652 fprintf(stderr
, "%s %d\n", __FUNCTION__
, bytes
);
654 if (rmesa
->dma
.flush
)
655 rmesa
->dma
.flush(rmesa
);
658 r300ReleaseDmaRegion(rmesa
, region
, __FUNCTION__
);
661 rmesa
->dma
.current
.start
= rmesa
->dma
.current
.ptr
=
662 (rmesa
->dma
.current
.ptr
+ alignment
) & ~alignment
;
664 if (rmesa
->dma
.current
.ptr
+ bytes
> rmesa
->dma
.current
.end
)
665 r300RefillCurrentDmaRegion(rmesa
);
667 region
->start
= rmesa
->dma
.current
.start
;
668 region
->ptr
= rmesa
->dma
.current
.start
;
669 region
->end
= rmesa
->dma
.current
.start
+ bytes
;
670 region
->address
= rmesa
->dma
.current
.address
;
671 region
->buf
= rmesa
->dma
.current
.buf
;
672 region
->buf
->refcount
++;
674 rmesa
->dma
.current
.ptr
+= bytes
; /* bug - if alignment > 7 */
675 rmesa
->dma
.current
.start
=
676 rmesa
->dma
.current
.ptr
= (rmesa
->dma
.current
.ptr
+ 0x7) & ~0x7;
678 assert(rmesa
->dma
.current
.ptr
<= rmesa
->dma
.current
.end
);
683 GLboolean
r300IsGartMemory(r300ContextPtr rmesa
, const GLvoid
* pointer
,
688 (char *)rmesa
->radeon
.radeonScreen
->gartTextures
.map
;
689 int valid
= (size
>= 0 && offset
>= 0
691 rmesa
->radeon
.radeonScreen
->gartTextures
.size
);
693 if (RADEON_DEBUG
& DEBUG_IOCTL
)
694 fprintf(stderr
, "r300IsGartMemory( %p ) : %d\n", pointer
,
700 GLuint
r300GartOffsetFromVirtual(r300ContextPtr rmesa
, const GLvoid
* pointer
)
704 (char *)rmesa
->radeon
.radeonScreen
->gartTextures
.map
;
706 //fprintf(stderr, "offset=%08x\n", offset);
709 || offset
> rmesa
->radeon
.radeonScreen
->gartTextures
.size
)
712 return rmesa
->radeon
.radeonScreen
->gart_texture_offset
+ offset
;
715 void r300InitIoctlFuncs(struct dd_function_table
*functions
)
717 functions
->Clear
= r300Clear
;
718 functions
->Finish
= radeonFinish
;
719 functions
->Flush
= r300Flush
;