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 **************************************************************************/
34 * Keith Whitwell <keith@tungstengraphics.com>
35 * Nicolai Haehnle <prefect_@gmx.net>
45 #include "swrast/swrast.h"
47 #include "r300_context.h"
48 #include "radeon_ioctl.h"
49 #include "r300_ioctl.h"
50 #include "r300_cmdbuf.h"
51 #include "r300_state.h"
52 #include "r300_program.h"
53 #include "radeon_reg.h"
54 #include "r300_emit.h"
58 #define CLEARBUFFER_COLOR 0x1
59 #define CLEARBUFFER_DEPTH 0x2
60 #define CLEARBUFFER_STENCIL 0x4
62 static void r300ClearBuffer(r300ContextPtr r300
, int flags
, int buffer
)
64 GLcontext
* ctx
= r300
->radeon
.glCtx
;
65 __DRIdrawablePrivate
*dPriv
= r300
->radeon
.dri
.drawable
;
66 GLuint cboffset
, cbpitch
;
67 drm_r300_cmd_header_t
* cmd2
;
70 drm_radeon_cmd_header_t
*cmd
= NULL
;
71 r300ContextPtr rmesa
=r300
;
73 if (RADEON_DEBUG
& DEBUG_IOCTL
)
74 fprintf(stderr
, "%s: %s buffer (%i,%i %ix%i)\n",
75 __FUNCTION__
, buffer
? "back" : "front",
76 dPriv
->x
, dPriv
->y
, dPriv
->w
, dPriv
->h
);
79 cboffset
= r300
->radeon
.radeonScreen
->backOffset
;
80 cbpitch
= r300
->radeon
.radeonScreen
->backPitch
;
82 cboffset
= r300
->radeon
.radeonScreen
->frontOffset
;
83 cbpitch
= r300
->radeon
.radeonScreen
->frontPitch
;
86 cboffset
+= r300
->radeon
.radeonScreen
->fbLocation
;
88 cp_wait(r300
, R300_WAIT_3D
| R300_WAIT_3D_CLEAN
);
91 R300_STATECHANGE(r300
, cb
);
92 reg_start(R300_RB3D_COLOROFFSET0
, 0);
95 if (r300
->radeon
.radeonScreen
->cpp
== 4)
96 cbpitch
|= R300_COLOR_FORMAT_ARGB8888
;
98 cbpitch
|= R300_COLOR_FORMAT_RGB565
;
100 if (r300
->radeon
.sarea
->tiling_enabled
)
101 cbpitch
|= R300_COLOR_TILE_ENABLE
;
103 reg_start(R300_RB3D_COLORPITCH0
, 0);
106 R300_STATECHANGE(r300
, cmk
);
107 reg_start(R300_RB3D_COLORMASK
, 0);
109 if (flags
& CLEARBUFFER_COLOR
) {
110 e32((ctx
->Color
.ColorMask
[BCOMP
] ? R300_COLORMASK0_B
: 0) |
111 (ctx
->Color
.ColorMask
[GCOMP
] ? R300_COLORMASK0_G
: 0) |
112 (ctx
->Color
.ColorMask
[RCOMP
] ? R300_COLORMASK0_R
: 0) |
113 (ctx
->Color
.ColorMask
[ACOMP
] ? R300_COLORMASK0_A
: 0));
118 R300_STATECHANGE(r300
, zs
);
119 reg_start(R300_RB3D_ZSTENCIL_CNTL_0
, 2);
127 if (flags
& CLEARBUFFER_DEPTH
) {
128 t1
|= R300_RB3D_Z_WRITE_ONLY
;
129 t2
|= (R300_ZS_ALWAYS
<< R300_RB3D_ZS1_DEPTH_FUNC_SHIFT
);
131 t1
|= R300_RB3D_Z_DISABLED_1
; // disable
134 if (flags
& CLEARBUFFER_STENCIL
) {
135 t1
|= R300_RB3D_STENCIL_ENABLE
;
137 (R300_ZS_ALWAYS
<<R300_RB3D_ZS1_FRONT_FUNC_SHIFT
) |
138 (R300_ZS_REPLACE
<<R300_RB3D_ZS1_FRONT_FAIL_OP_SHIFT
) |
139 (R300_ZS_REPLACE
<<R300_RB3D_ZS1_FRONT_ZPASS_OP_SHIFT
) |
140 (R300_ZS_REPLACE
<<R300_RB3D_ZS1_FRONT_ZFAIL_OP_SHIFT
) |
141 (R300_ZS_ALWAYS
<<R300_RB3D_ZS1_BACK_FUNC_SHIFT
) |
142 (R300_ZS_REPLACE
<<R300_RB3D_ZS1_BACK_FAIL_OP_SHIFT
) |
143 (R300_ZS_REPLACE
<<R300_RB3D_ZS1_BACK_ZPASS_OP_SHIFT
) |
144 (R300_ZS_REPLACE
<<R300_RB3D_ZS1_BACK_ZFAIL_OP_SHIFT
) ;
149 e32(r300
->state
.stencil
.clear
);
152 cmd2
= (drm_r300_cmd_header_t
*)r300AllocCmdBuf(r300
, 9, __FUNCTION__
);
153 cmd2
[0].packet3
.cmd_type
= R300_CMD_PACKET3
;
154 cmd2
[0].packet3
.packet
= R300_CMD_PACKET3_CLEAR
;
155 cmd2
[1].u
= r300PackFloat32(dPriv
->w
/ 2.0);
156 cmd2
[2].u
= r300PackFloat32(dPriv
->h
/ 2.0);
157 cmd2
[3].u
= r300PackFloat32(ctx
->Depth
.Clear
);
158 cmd2
[4].u
= r300PackFloat32(1.0);
159 cmd2
[5].u
= r300PackFloat32(ctx
->Color
.ClearColor
[0]);
160 cmd2
[6].u
= r300PackFloat32(ctx
->Color
.ClearColor
[1]);
161 cmd2
[7].u
= r300PackFloat32(ctx
->Color
.ClearColor
[2]);
162 cmd2
[8].u
= r300PackFloat32(ctx
->Color
.ClearColor
[3]);
164 reg_start(R300_RB3D_DSTCACHE_CTLSTAT
,0);
165 e32(R300_RB3D_DSTCACHE_UNKNOWN_0A
);
168 reg_start(R300_RB3D_ZCACHE_CTLSTAT
,0);
169 e32(R300_RB3D_ZCACHE_UNKNOWN_03
);
170 cp_wait(rmesa
, R300_WAIT_3D
| R300_WAIT_3D_CLEAN
);
173 static void r300EmitClearState(GLcontext
* ctx
)
175 r300ContextPtr r300
= R300_CONTEXT(ctx
);
176 r300ContextPtr rmesa
=r300
;
177 __DRIdrawablePrivate
*dPriv
= r300
->radeon
.dri
.drawable
;
179 int cmd_reserved
= 0;
181 drm_radeon_cmd_header_t
*cmd
= NULL
;
184 if (!(r300
->radeon
.radeonScreen
->chip_flags
& RADEON_CHIPSET_TCL
))
187 R300_STATECHANGE(r300
, vir
[0]);
188 reg_start(R300_VAP_INPUT_ROUTE_0_0
, 0);
195 R300_STATECHANGE(r300
, fogs
);
196 reg_start(R300_RE_FOG_STATE
, 0);
199 R300_STATECHANGE(r300
, vir
[1]);
200 reg_start(R300_VAP_INPUT_ROUTE_1_0
, 0);
203 R300_STATECHANGE(r300
, vic
);
204 reg_start(R300_VAP_INPUT_CNTL_0
, 1);
209 R300_STATECHANGE(r300
, vte
);
210 /* comes from fglrx startup of clear */
211 reg_start(R300_SE_VTE_CNTL
, 1);
215 reg_start(0x21dc, 0);
219 R300_STATECHANGE(r300
, vof
);
220 reg_start(R300_VAP_OUTPUT_VTX_FMT_0
, 1);
221 e32(R300_VAP_OUTPUT_VTX_FMT_0__POS_PRESENT
| R300_VAP_OUTPUT_VTX_FMT_0__COLOR_PRESENT
);
222 e32(0); /* no textures */
225 R300_STATECHANGE(r300
, txe
);
226 reg_start(R300_TX_ENABLE
, 0);
229 R300_STATECHANGE(r300
, vpt
);
230 reg_start(R300_SE_VPORT_XSCALE
, 5);
238 R300_STATECHANGE(r300
, at
);
239 reg_start(R300_PP_ALPHA_TEST
, 0);
242 R300_STATECHANGE(r300
, bld
);
243 reg_start(R300_RB3D_CBLEND
, 1);
247 R300_STATECHANGE(r300
, unk221C
);
248 reg_start(R300_VAP_UNKNOWN_221C
, 0);
249 e32(R300_221C_CLEAR
);
251 R300_STATECHANGE(r300
, ps
);
252 reg_start(R300_RE_POINTSIZE
, 0);
253 e32(((dPriv
->w
* 6) << R300_POINTSIZE_X_SHIFT
) |
254 ((dPriv
->h
* 6) << R300_POINTSIZE_Y_SHIFT
));
256 R300_STATECHANGE(r300
, ri
);
257 reg_start(R300_RS_INTERP_0
, 8);
258 for(i
= 0; i
< 8; ++i
){
259 e32(R300_RS_INTERP_USED
);
262 R300_STATECHANGE(r300
, rc
);
263 /* The second constant is needed to get glxgears display anything .. */
264 reg_start(R300_RS_CNTL_0
, 1);
265 e32((1 << R300_RS_CNTL_CI_CNT_SHIFT
) | R300_RS_CNTL_0_UNKNOWN_18
);
268 R300_STATECHANGE(r300
, rr
);
269 reg_start(R300_RS_ROUTE_0
, 0);
272 R300_STATECHANGE(r300
, fp
);
273 reg_start(R300_PFS_CNTL_0
, 2);
277 reg_start(R300_PFS_NODE_0
, 3);
281 e32(R300_PFS_NODE_OUTPUT_COLOR
);
283 R300_STATECHANGE(r300
, fpi
[0]);
284 R300_STATECHANGE(r300
, fpi
[1]);
285 R300_STATECHANGE(r300
, fpi
[2]);
286 R300_STATECHANGE(r300
, fpi
[3]);
288 reg_start(R300_PFS_INSTR0_0
, 0);
289 e32(FP_INSTRC(MAD
, FP_ARGC(SRC0C_XYZ
), FP_ARGC(ONE
), FP_ARGC(ZERO
)));
291 reg_start(R300_PFS_INSTR1_0
, 0);
292 e32(FP_SELC(0,NO
,XYZ
,FP_TMP(0),0,0));
294 reg_start(R300_PFS_INSTR2_0
, 0);
295 e32(FP_INSTRA(MAD
, FP_ARGA(SRC0A
), FP_ARGA(ONE
), FP_ARGA(ZERO
)));
297 reg_start(R300_PFS_INSTR3_0
, 0);
298 e32(FP_SELA(0,NO
,W
,FP_TMP(0),0,0));
301 R300_STATECHANGE(r300
, pvs
);
302 reg_start(R300_VAP_PVS_CNTL_1
, 2);
303 e32((0 << R300_PVS_CNTL_1_PROGRAM_START_SHIFT
) |
304 (0 << R300_PVS_CNTL_1_POS_END_SHIFT
) |
305 (1 << R300_PVS_CNTL_1_PROGRAM_END_SHIFT
));
307 e32(1 << R300_PVS_CNTL_3_PROGRAM_UNKNOWN_SHIFT
);
309 R300_STATECHANGE(r300
, vpi
);
310 vsf_start_fragment(0x0, 8);
311 e32(VP_OUT(ADD
,OUT
,0,XYZW
));
316 e32(VP_OUT(ADD
,OUT
,1,XYZW
));
322 /*reg_start(0x4500,0);
329 static void r300Clear(GLcontext
* ctx
, GLbitfield mask
)
331 r300ContextPtr r300
= R300_CONTEXT(ctx
);
332 __DRIdrawablePrivate
*dPriv
= r300
->radeon
.dri
.drawable
;
337 if (RADEON_DEBUG
& DEBUG_IOCTL
)
338 fprintf(stderr
, "r300Clear\n");
341 LOCK_HARDWARE(&r300
->radeon
);
342 UNLOCK_HARDWARE(&r300
->radeon
);
343 if (dPriv
->numClipRects
== 0)
347 if (mask
& BUFFER_BIT_FRONT_LEFT
) {
348 flags
|= BUFFER_BIT_FRONT_LEFT
;
349 mask
&= ~BUFFER_BIT_FRONT_LEFT
;
352 if (mask
& BUFFER_BIT_BACK_LEFT
) {
353 flags
|= BUFFER_BIT_BACK_LEFT
;
354 mask
&= ~BUFFER_BIT_BACK_LEFT
;
357 if (mask
& BUFFER_BIT_DEPTH
) {
358 bits
|= CLEARBUFFER_DEPTH
;
359 mask
&= ~BUFFER_BIT_DEPTH
;
362 if ( (mask
& BUFFER_BIT_STENCIL
) && r300
->state
.stencil
.hw_stencil
) {
363 bits
|= CLEARBUFFER_STENCIL
;
364 mask
&= ~BUFFER_BIT_STENCIL
;
368 if (RADEON_DEBUG
& DEBUG_FALLBACKS
)
369 fprintf(stderr
, "%s: swrast clear, mask: %x\n",
371 _swrast_Clear(ctx
, mask
);
374 swapped
= r300
->radeon
.sarea
->pfCurrentPage
== 1;
376 /* Make sure it fits there. */
377 r300EnsureCmdBufSpace(r300
, 421*3, __FUNCTION__
);
379 r300EmitClearState(ctx
);
381 if (flags
& BUFFER_BIT_FRONT_LEFT
) {
382 r300ClearBuffer(r300
, bits
| CLEARBUFFER_COLOR
, swapped
);
386 if (flags
& BUFFER_BIT_BACK_LEFT
) {
387 r300ClearBuffer(r300
, bits
| CLEARBUFFER_COLOR
, swapped
^ 1);
392 r300ClearBuffer(r300
, bits
, 0);
397 void r300Flush(GLcontext
* ctx
)
399 r300ContextPtr r300
= R300_CONTEXT(ctx
);
401 if (RADEON_DEBUG
& DEBUG_IOCTL
)
402 fprintf(stderr
, "%s\n", __FUNCTION__
);
404 if (r300
->cmdbuf
.count_used
> r300
->cmdbuf
.count_reemit
)
405 r300FlushCmdBuf(r300
, __FUNCTION__
);
409 #include "radeon_mm.h"
411 static void r300RefillCurrentDmaRegion(r300ContextPtr rmesa
, int size
)
413 struct r300_dma_buffer
*dmabuf
;
414 size
= MAX2(size
, RADEON_BUFFER_SIZE
*16);
416 if (RADEON_DEBUG
& (DEBUG_IOCTL
| DEBUG_DMA
))
417 fprintf(stderr
, "%s\n", __FUNCTION__
);
419 if (rmesa
->dma
.flush
) {
420 rmesa
->dma
.flush(rmesa
);
423 if (rmesa
->dma
.current
.buf
)
424 r300ReleaseDmaRegion(rmesa
, &rmesa
->dma
.current
, __FUNCTION__
);
426 if (rmesa
->dma
.nr_released_bufs
> 4)
427 r300FlushCmdBuf(rmesa
, __FUNCTION__
);
429 dmabuf
= CALLOC_STRUCT(r300_dma_buffer
);
430 dmabuf
->buf
= (void *)1; /* hack */
431 dmabuf
->refcount
= 1;
433 dmabuf
->id
= radeon_mm_alloc(rmesa
, 4, size
);
434 if (dmabuf
->id
== 0) {
435 LOCK_HARDWARE(&rmesa
->radeon
); /* no need to validate */
437 r300FlushCmdBufLocked(rmesa
, __FUNCTION__
);
438 radeonWaitForIdleLocked(&rmesa
->radeon
);
440 dmabuf
->id
= radeon_mm_alloc(rmesa
, 4, size
);
443 if (dmabuf
->id
== 0) {
445 r300_evict_vbos(rmesa
->radeon
.glCtx
, /*RADEON_BUFFER_SIZE*16*/1<<30);
446 dmabuf
->id
= radeon_mm_alloc(rmesa
, 4, size
);
449 UNLOCK_HARDWARE(&rmesa
->radeon
);
451 if (dmabuf
->id
== 0) {
452 fprintf(stderr
, "Error: Could not get dma buffer... exiting\n");
457 rmesa
->dma
.current
.buf
= dmabuf
;
458 rmesa
->dma
.current
.address
= radeon_mm_ptr(rmesa
, dmabuf
->id
);
459 rmesa
->dma
.current
.end
= size
;
460 rmesa
->dma
.current
.start
= 0;
461 rmesa
->dma
.current
.ptr
= 0;
464 void r300ReleaseDmaRegion(r300ContextPtr rmesa
,
465 struct r300_dma_region
*region
, const char *caller
)
467 if (RADEON_DEBUG
& DEBUG_IOCTL
)
468 fprintf(stderr
, "%s from %s\n", __FUNCTION__
, caller
);
473 if (rmesa
->dma
.flush
)
474 rmesa
->dma
.flush(rmesa
);
476 if (--region
->buf
->refcount
== 0) {
477 radeon_mm_free(rmesa
, region
->buf
->id
);
479 rmesa
->dma
.nr_released_bufs
++;
486 /* Allocates a region from rmesa->dma.current. If there isn't enough
487 * space in current, grab a new buffer (and discard what was left of current)
489 void r300AllocDmaRegion(r300ContextPtr rmesa
,
490 struct r300_dma_region
*region
,
491 int bytes
, int alignment
)
493 if (RADEON_DEBUG
& DEBUG_IOCTL
)
494 fprintf(stderr
, "%s %d\n", __FUNCTION__
, bytes
);
496 if (rmesa
->dma
.flush
)
497 rmesa
->dma
.flush(rmesa
);
500 r300ReleaseDmaRegion(rmesa
, region
, __FUNCTION__
);
503 rmesa
->dma
.current
.start
= rmesa
->dma
.current
.ptr
=
504 (rmesa
->dma
.current
.ptr
+ alignment
) & ~alignment
;
506 if (rmesa
->dma
.current
.ptr
+ bytes
> rmesa
->dma
.current
.end
)
507 r300RefillCurrentDmaRegion(rmesa
,
508 (bytes
+ 0x7) & ~0x7);
510 region
->start
= rmesa
->dma
.current
.start
;
511 region
->ptr
= rmesa
->dma
.current
.start
;
512 region
->end
= rmesa
->dma
.current
.start
+ bytes
;
513 region
->address
= rmesa
->dma
.current
.address
;
514 region
->buf
= rmesa
->dma
.current
.buf
;
515 region
->buf
->refcount
++;
517 rmesa
->dma
.current
.ptr
+= bytes
; /* bug - if alignment > 7 */
518 rmesa
->dma
.current
.start
=
519 rmesa
->dma
.current
.ptr
= (rmesa
->dma
.current
.ptr
+ 0x7) & ~0x7;
521 assert(rmesa
->dma
.current
.ptr
<= rmesa
->dma
.current
.end
);
525 static void r300RefillCurrentDmaRegion(r300ContextPtr rmesa
)
527 struct r300_dma_buffer
*dmabuf
;
528 int fd
= rmesa
->radeon
.dri
.fd
;
534 if (RADEON_DEBUG
& (DEBUG_IOCTL
| DEBUG_DMA
))
535 fprintf(stderr
, "%s\n", __FUNCTION__
);
537 if (rmesa
->dma
.flush
) {
538 rmesa
->dma
.flush(rmesa
);
541 if (rmesa
->dma
.current
.buf
)
542 r300ReleaseDmaRegion(rmesa
, &rmesa
->dma
.current
, __FUNCTION__
);
544 if (rmesa
->dma
.nr_released_bufs
> 4)
545 r300FlushCmdBuf(rmesa
, __FUNCTION__
);
547 dma
.context
= rmesa
->radeon
.dri
.hwContext
;
549 dma
.send_list
= NULL
;
550 dma
.send_sizes
= NULL
;
552 dma
.request_count
= 1;
553 dma
.request_size
= RADEON_BUFFER_SIZE
;
554 dma
.request_list
= &index
;
555 dma
.request_sizes
= &size
;
556 dma
.granted_count
= 0;
558 LOCK_HARDWARE(&rmesa
->radeon
); /* no need to validate */
560 ret
= drmDMA(fd
, &dma
);
563 /* Try to release some buffers and wait until we can't get any more */
564 if (rmesa
->dma
.nr_released_bufs
) {
565 r300FlushCmdBufLocked(rmesa
, __FUNCTION__
);
568 if (RADEON_DEBUG
& DEBUG_DMA
)
569 fprintf(stderr
, "Waiting for buffers\n");
571 radeonWaitForIdleLocked(&rmesa
->radeon
);
572 ret
= drmDMA(fd
, &dma
);
575 UNLOCK_HARDWARE(&rmesa
->radeon
);
576 fprintf(stderr
, "Error: Could not get dma buffer... exiting\n");
581 UNLOCK_HARDWARE(&rmesa
->radeon
);
583 if (RADEON_DEBUG
& DEBUG_DMA
)
584 fprintf(stderr
, "Allocated buffer %d\n", index
);
586 dmabuf
= CALLOC_STRUCT(r300_dma_buffer
);
587 dmabuf
->buf
= &rmesa
->radeon
.radeonScreen
->buffers
->list
[index
];
588 dmabuf
->refcount
= 1;
590 rmesa
->dma
.current
.buf
= dmabuf
;
591 rmesa
->dma
.current
.address
= dmabuf
->buf
->address
;
592 rmesa
->dma
.current
.end
= dmabuf
->buf
->total
;
593 rmesa
->dma
.current
.start
= 0;
594 rmesa
->dma
.current
.ptr
= 0;
597 void r300ReleaseDmaRegion(r300ContextPtr rmesa
,
598 struct r300_dma_region
*region
, const char *caller
)
600 if (RADEON_DEBUG
& DEBUG_IOCTL
)
601 fprintf(stderr
, "%s from %s\n", __FUNCTION__
, caller
);
606 if (rmesa
->dma
.flush
)
607 rmesa
->dma
.flush(rmesa
);
609 if (--region
->buf
->refcount
== 0) {
610 drm_radeon_cmd_header_t
*cmd
;
612 if (RADEON_DEBUG
& (DEBUG_IOCTL
| DEBUG_DMA
))
613 fprintf(stderr
, "%s -- DISCARD BUF %d\n", __FUNCTION__
,
614 region
->buf
->buf
->idx
);
616 (drm_radeon_cmd_header_t
*) r300AllocCmdBuf(rmesa
,
619 cmd
->dma
.cmd_type
= R300_CMD_DMA_DISCARD
;
620 cmd
->dma
.buf_idx
= region
->buf
->buf
->idx
;
623 rmesa
->dma
.nr_released_bufs
++;
630 /* Allocates a region from rmesa->dma.current. If there isn't enough
631 * space in current, grab a new buffer (and discard what was left of current)
633 void r300AllocDmaRegion(r300ContextPtr rmesa
,
634 struct r300_dma_region
*region
,
635 int bytes
, int alignment
)
637 if (RADEON_DEBUG
& DEBUG_IOCTL
)
638 fprintf(stderr
, "%s %d\n", __FUNCTION__
, bytes
);
640 if (rmesa
->dma
.flush
)
641 rmesa
->dma
.flush(rmesa
);
644 r300ReleaseDmaRegion(rmesa
, region
, __FUNCTION__
);
647 rmesa
->dma
.current
.start
= rmesa
->dma
.current
.ptr
=
648 (rmesa
->dma
.current
.ptr
+ alignment
) & ~alignment
;
650 if (rmesa
->dma
.current
.ptr
+ bytes
> rmesa
->dma
.current
.end
)
651 r300RefillCurrentDmaRegion(rmesa
);
653 region
->start
= rmesa
->dma
.current
.start
;
654 region
->ptr
= rmesa
->dma
.current
.start
;
655 region
->end
= rmesa
->dma
.current
.start
+ bytes
;
656 region
->address
= rmesa
->dma
.current
.address
;
657 region
->buf
= rmesa
->dma
.current
.buf
;
658 region
->buf
->refcount
++;
660 rmesa
->dma
.current
.ptr
+= bytes
; /* bug - if alignment > 7 */
661 rmesa
->dma
.current
.start
=
662 rmesa
->dma
.current
.ptr
= (rmesa
->dma
.current
.ptr
+ 0x7) & ~0x7;
664 assert(rmesa
->dma
.current
.ptr
<= rmesa
->dma
.current
.end
);
669 /* Called via glXGetMemoryOffsetMESA() */
670 GLuint
r300GetMemoryOffsetMESA(__DRInativeDisplay
* dpy
, int scrn
,
671 const GLvoid
* pointer
)
673 GET_CURRENT_CONTEXT(ctx
);
674 r300ContextPtr rmesa
;
677 if (!ctx
|| !(rmesa
= R300_CONTEXT(ctx
))) {
678 fprintf(stderr
, "%s: no context\n", __FUNCTION__
);
682 if (!r300IsGartMemory(rmesa
, pointer
, 0))
685 card_offset
= r300GartOffsetFromVirtual(rmesa
, pointer
);
687 return card_offset
- rmesa
->radeon
.radeonScreen
->gart_base
;
690 GLboolean
r300IsGartMemory(r300ContextPtr rmesa
, const GLvoid
* pointer
,
694 (char *)pointer
- (char *)rmesa
->radeon
.radeonScreen
->gartTextures
.map
;
695 int valid
= (size
>= 0 && offset
>= 0
696 && offset
+ size
< rmesa
->radeon
.radeonScreen
->gartTextures
.size
);
698 if (RADEON_DEBUG
& DEBUG_IOCTL
)
699 fprintf(stderr
, "r300IsGartMemory( %p ) : %d\n", pointer
,
705 GLuint
r300GartOffsetFromVirtual(r300ContextPtr rmesa
, const GLvoid
* pointer
)
708 (char *)pointer
- (char *)rmesa
->radeon
.radeonScreen
->gartTextures
.map
;
710 //fprintf(stderr, "offset=%08x\n", offset);
712 if (offset
< 0 || offset
> rmesa
->radeon
.radeonScreen
->gartTextures
.size
)
715 return rmesa
->radeon
.radeonScreen
->gart_texture_offset
+ offset
;
718 void r300InitIoctlFuncs(struct dd_function_table
*functions
)
720 functions
->Clear
= r300Clear
;
721 functions
->Finish
= radeonFinish
;
722 functions
->Flush
= r300Flush
;