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 r300
= R300_CONTEXT(ctx
);
417 if (RADEON_DEBUG
& DEBUG_IOCTL
)
418 fprintf(stderr
, "%s\n", __FUNCTION__
);
420 if (r300
->cmdbuf
.count_used
> r300
->cmdbuf
.count_reemit
)
421 r300FlushCmdBuf(r300
, __FUNCTION__
);
425 #include "r300_mem.h"
427 static void r300RefillCurrentDmaRegion(r300ContextPtr rmesa
, int size
)
429 struct r300_dma_buffer
*dmabuf
;
430 size
= MAX2(size
, RADEON_BUFFER_SIZE
* 16);
432 if (RADEON_DEBUG
& (DEBUG_IOCTL
| DEBUG_DMA
))
433 fprintf(stderr
, "%s\n", __FUNCTION__
);
435 if (rmesa
->dma
.flush
) {
436 rmesa
->dma
.flush(rmesa
);
439 if (rmesa
->dma
.current
.buf
)
440 r300ReleaseDmaRegion(rmesa
, &rmesa
->dma
.current
, __FUNCTION__
);
442 if (rmesa
->dma
.nr_released_bufs
> 4)
443 r300FlushCmdBuf(rmesa
, __FUNCTION__
);
445 dmabuf
= CALLOC_STRUCT(r300_dma_buffer
);
446 dmabuf
->buf
= (void *)1; /* hack */
447 dmabuf
->refcount
= 1;
449 dmabuf
->id
= r300_mem_alloc(rmesa
, 4, size
);
450 if (dmabuf
->id
== 0) {
451 LOCK_HARDWARE(&rmesa
->radeon
); /* no need to validate */
453 r300FlushCmdBufLocked(rmesa
, __FUNCTION__
);
454 radeonWaitForIdleLocked(&rmesa
->radeon
);
456 dmabuf
->id
= r300_mem_alloc(rmesa
, 4, size
);
458 UNLOCK_HARDWARE(&rmesa
->radeon
);
460 if (dmabuf
->id
== 0) {
462 "Error: Could not get dma buffer... exiting\n");
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;
474 void r300ReleaseDmaRegion(r300ContextPtr rmesa
,
475 struct r300_dma_region
*region
, const char *caller
)
477 if (RADEON_DEBUG
& DEBUG_IOCTL
)
478 fprintf(stderr
, "%s from %s\n", __FUNCTION__
, caller
);
483 if (rmesa
->dma
.flush
)
484 rmesa
->dma
.flush(rmesa
);
486 if (--region
->buf
->refcount
== 0) {
487 r300_mem_free(rmesa
, region
->buf
->id
);
489 rmesa
->dma
.nr_released_bufs
++;
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)
499 void r300AllocDmaRegion(r300ContextPtr rmesa
,
500 struct r300_dma_region
*region
,
501 int bytes
, int alignment
)
503 if (RADEON_DEBUG
& DEBUG_IOCTL
)
504 fprintf(stderr
, "%s %d\n", __FUNCTION__
, bytes
);
506 if (rmesa
->dma
.flush
)
507 rmesa
->dma
.flush(rmesa
);
510 r300ReleaseDmaRegion(rmesa
, region
, __FUNCTION__
);
513 rmesa
->dma
.current
.start
= rmesa
->dma
.current
.ptr
=
514 (rmesa
->dma
.current
.ptr
+ alignment
) & ~alignment
;
516 if (rmesa
->dma
.current
.ptr
+ bytes
> rmesa
->dma
.current
.end
)
517 r300RefillCurrentDmaRegion(rmesa
, (bytes
+ 0x7) & ~0x7);
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
++;
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;
530 assert(rmesa
->dma
.current
.ptr
<= rmesa
->dma
.current
.end
);
534 static void r300RefillCurrentDmaRegion(r300ContextPtr rmesa
)
536 struct r300_dma_buffer
*dmabuf
;
537 int fd
= rmesa
->radeon
.dri
.fd
;
543 if (RADEON_DEBUG
& (DEBUG_IOCTL
| DEBUG_DMA
))
544 fprintf(stderr
, "%s\n", __FUNCTION__
);
546 if (rmesa
->dma
.flush
) {
547 rmesa
->dma
.flush(rmesa
);
550 if (rmesa
->dma
.current
.buf
)
551 r300ReleaseDmaRegion(rmesa
, &rmesa
->dma
.current
, __FUNCTION__
);
553 if (rmesa
->dma
.nr_released_bufs
> 4)
554 r300FlushCmdBuf(rmesa
, __FUNCTION__
);
556 dma
.context
= rmesa
->radeon
.dri
.hwContext
;
558 dma
.send_list
= NULL
;
559 dma
.send_sizes
= NULL
;
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;
567 LOCK_HARDWARE(&rmesa
->radeon
); /* no need to validate */
569 ret
= drmDMA(fd
, &dma
);
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__
);
577 if (RADEON_DEBUG
& DEBUG_DMA
)
578 fprintf(stderr
, "Waiting for buffers\n");
580 radeonWaitForIdleLocked(&rmesa
->radeon
);
581 ret
= drmDMA(fd
, &dma
);
584 UNLOCK_HARDWARE(&rmesa
->radeon
);
586 "Error: Could not get dma buffer... exiting\n");
591 UNLOCK_HARDWARE(&rmesa
->radeon
);
593 if (RADEON_DEBUG
& DEBUG_DMA
)
594 fprintf(stderr
, "Allocated buffer %d\n", index
);
596 dmabuf
= CALLOC_STRUCT(r300_dma_buffer
);
597 dmabuf
->buf
= &rmesa
->radeon
.radeonScreen
->buffers
->list
[index
];
598 dmabuf
->refcount
= 1;
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;
607 void r300ReleaseDmaRegion(r300ContextPtr rmesa
,
608 struct r300_dma_region
*region
, const char *caller
)
610 if (RADEON_DEBUG
& DEBUG_IOCTL
)
611 fprintf(stderr
, "%s from %s\n", __FUNCTION__
, caller
);
616 if (rmesa
->dma
.flush
)
617 rmesa
->dma
.flush(rmesa
);
619 if (--region
->buf
->refcount
== 0) {
620 drm_radeon_cmd_header_t
*cmd
;
622 if (RADEON_DEBUG
& (DEBUG_IOCTL
| DEBUG_DMA
))
623 fprintf(stderr
, "%s -- DISCARD BUF %d\n",
624 __FUNCTION__
, region
->buf
->buf
->idx
);
626 (drm_radeon_cmd_header_t
*) r300AllocCmdBuf(rmesa
,
630 cmd
->dma
.cmd_type
= R300_CMD_DMA_DISCARD
;
631 cmd
->dma
.buf_idx
= region
->buf
->buf
->idx
;
634 rmesa
->dma
.nr_released_bufs
++;
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)
644 void r300AllocDmaRegion(r300ContextPtr rmesa
,
645 struct r300_dma_region
*region
,
646 int bytes
, int alignment
)
648 if (RADEON_DEBUG
& DEBUG_IOCTL
)
649 fprintf(stderr
, "%s %d\n", __FUNCTION__
, bytes
);
651 if (rmesa
->dma
.flush
)
652 rmesa
->dma
.flush(rmesa
);
655 r300ReleaseDmaRegion(rmesa
, region
, __FUNCTION__
);
658 rmesa
->dma
.current
.start
= rmesa
->dma
.current
.ptr
=
659 (rmesa
->dma
.current
.ptr
+ alignment
) & ~alignment
;
661 if (rmesa
->dma
.current
.ptr
+ bytes
> rmesa
->dma
.current
.end
)
662 r300RefillCurrentDmaRegion(rmesa
);
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
++;
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;
675 assert(rmesa
->dma
.current
.ptr
<= rmesa
->dma
.current
.end
);
680 GLboolean
r300IsGartMemory(r300ContextPtr rmesa
, const GLvoid
* pointer
,
685 (char *)rmesa
->radeon
.radeonScreen
->gartTextures
.map
;
686 int valid
= (size
>= 0 && offset
>= 0
688 rmesa
->radeon
.radeonScreen
->gartTextures
.size
);
690 if (RADEON_DEBUG
& DEBUG_IOCTL
)
691 fprintf(stderr
, "r300IsGartMemory( %p ) : %d\n", pointer
,
697 GLuint
r300GartOffsetFromVirtual(r300ContextPtr rmesa
, const GLvoid
* pointer
)
701 (char *)rmesa
->radeon
.radeonScreen
->gartTextures
.map
;
703 //fprintf(stderr, "offset=%08x\n", offset);
706 || offset
> rmesa
->radeon
.radeonScreen
->gartTextures
.size
)
709 return rmesa
->radeon
.radeonScreen
->gart_texture_offset
+ offset
;
712 void r300InitIoctlFuncs(struct dd_function_table
*functions
)
714 functions
->Clear
= r300Clear
;
715 functions
->Finish
= radeonFinish
;
716 functions
->Flush
= r300Flush
;