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
;
130 (R300_ZS_ALWAYS
<< R300_RB3D_ZS1_DEPTH_FUNC_SHIFT
);
132 t1
|= R300_RB3D_Z_DISABLED_1
; // disable
135 if (flags
& CLEARBUFFER_STENCIL
) {
136 t1
|= R300_RB3D_STENCIL_ENABLE
;
139 R300_RB3D_ZS1_FRONT_FUNC_SHIFT
) |
141 R300_RB3D_ZS1_FRONT_FAIL_OP_SHIFT
) |
143 R300_RB3D_ZS1_FRONT_ZPASS_OP_SHIFT
) |
145 R300_RB3D_ZS1_FRONT_ZFAIL_OP_SHIFT
) |
147 R300_RB3D_ZS1_BACK_FUNC_SHIFT
) |
149 R300_RB3D_ZS1_BACK_FAIL_OP_SHIFT
) |
151 R300_RB3D_ZS1_BACK_ZPASS_OP_SHIFT
) |
153 R300_RB3D_ZS1_BACK_ZFAIL_OP_SHIFT
);
158 e32(r300
->state
.stencil
.clear
);
161 cmd2
= (drm_r300_cmd_header_t
*) r300AllocCmdBuf(r300
, 9, __FUNCTION__
);
162 cmd2
[0].packet3
.cmd_type
= R300_CMD_PACKET3
;
163 cmd2
[0].packet3
.packet
= R300_CMD_PACKET3_CLEAR
;
164 cmd2
[1].u
= r300PackFloat32(dPriv
->w
/ 2.0);
165 cmd2
[2].u
= r300PackFloat32(dPriv
->h
/ 2.0);
166 cmd2
[3].u
= r300PackFloat32(ctx
->Depth
.Clear
);
167 cmd2
[4].u
= r300PackFloat32(1.0);
168 cmd2
[5].u
= r300PackFloat32(ctx
->Color
.ClearColor
[0]);
169 cmd2
[6].u
= r300PackFloat32(ctx
->Color
.ClearColor
[1]);
170 cmd2
[7].u
= r300PackFloat32(ctx
->Color
.ClearColor
[2]);
171 cmd2
[8].u
= r300PackFloat32(ctx
->Color
.ClearColor
[3]);
173 reg_start(R300_RB3D_DSTCACHE_CTLSTAT
, 0);
174 e32(R300_RB3D_DSTCACHE_UNKNOWN_0A
);
176 reg_start(R300_RB3D_ZCACHE_CTLSTAT
, 0);
177 e32(R300_RB3D_ZCACHE_UNKNOWN_03
);
178 cp_wait(rmesa
, R300_WAIT_3D
| R300_WAIT_3D_CLEAN
);
181 static void r300EmitClearState(GLcontext
* ctx
)
183 r300ContextPtr r300
= R300_CONTEXT(ctx
);
184 r300ContextPtr rmesa
= r300
;
185 __DRIdrawablePrivate
*dPriv
= r300
->radeon
.dri
.drawable
;
187 int cmd_reserved
= 0;
189 drm_radeon_cmd_header_t
*cmd
= NULL
;
192 if (!(r300
->radeon
.radeonScreen
->chip_flags
& RADEON_CHIPSET_TCL
))
195 R300_STATECHANGE(r300
, vir
[0]);
196 reg_start(R300_VAP_INPUT_ROUTE_0_0
, 0);
203 R300_STATECHANGE(r300
, fogs
);
204 reg_start(R300_RE_FOG_STATE
, 0);
207 R300_STATECHANGE(r300
, vir
[1]);
208 reg_start(R300_VAP_INPUT_ROUTE_1_0
, 0);
211 R300_STATECHANGE(r300
, vic
);
212 reg_start(R300_VAP_INPUT_CNTL_0
, 1);
217 R300_STATECHANGE(r300
, vte
);
218 /* comes from fglrx startup of clear */
219 reg_start(R300_SE_VTE_CNTL
, 1);
223 reg_start(0x21dc, 0);
227 R300_STATECHANGE(r300
, vof
);
228 reg_start(R300_VAP_OUTPUT_VTX_FMT_0
, 1);
229 e32(R300_VAP_OUTPUT_VTX_FMT_0__POS_PRESENT
|
230 R300_VAP_OUTPUT_VTX_FMT_0__COLOR_PRESENT
);
231 e32(0); /* no textures */
233 R300_STATECHANGE(r300
, txe
);
234 reg_start(R300_TX_ENABLE
, 0);
237 R300_STATECHANGE(r300
, vpt
);
238 reg_start(R300_SE_VPORT_XSCALE
, 5);
246 R300_STATECHANGE(r300
, at
);
247 reg_start(R300_PP_ALPHA_TEST
, 0);
250 R300_STATECHANGE(r300
, bld
);
251 reg_start(R300_RB3D_CBLEND
, 1);
255 R300_STATECHANGE(r300
, unk221C
);
256 reg_start(R300_VAP_UNKNOWN_221C
, 0);
257 e32(R300_221C_CLEAR
);
259 R300_STATECHANGE(r300
, ps
);
260 reg_start(R300_RE_POINTSIZE
, 0);
261 e32(((dPriv
->w
* 6) << R300_POINTSIZE_X_SHIFT
) |
262 ((dPriv
->h
* 6) << R300_POINTSIZE_Y_SHIFT
));
264 R300_STATECHANGE(r300
, ri
);
265 reg_start(R300_RS_INTERP_0
, 8);
266 for (i
= 0; i
< 8; ++i
) {
267 e32(R300_RS_INTERP_USED
);
270 R300_STATECHANGE(r300
, rc
);
271 /* The second constant is needed to get glxgears display anything .. */
272 reg_start(R300_RS_CNTL_0
, 1);
273 e32((1 << R300_RS_CNTL_CI_CNT_SHIFT
) | R300_RS_CNTL_0_UNKNOWN_18
);
276 R300_STATECHANGE(r300
, rr
);
277 reg_start(R300_RS_ROUTE_0
, 0);
280 R300_STATECHANGE(r300
, fp
);
281 reg_start(R300_PFS_CNTL_0
, 2);
285 reg_start(R300_PFS_NODE_0
, 3);
289 e32(R300_PFS_NODE_OUTPUT_COLOR
);
291 R300_STATECHANGE(r300
, fpi
[0]);
292 R300_STATECHANGE(r300
, fpi
[1]);
293 R300_STATECHANGE(r300
, fpi
[2]);
294 R300_STATECHANGE(r300
, fpi
[3]);
296 reg_start(R300_PFS_INSTR0_0
, 0);
297 e32(FP_INSTRC(MAD
, FP_ARGC(SRC0C_XYZ
), FP_ARGC(ONE
), FP_ARGC(ZERO
)));
299 reg_start(R300_PFS_INSTR1_0
, 0);
300 e32(FP_SELC(0, NO
, XYZ
, FP_TMP(0), 0, 0));
302 reg_start(R300_PFS_INSTR2_0
, 0);
303 e32(FP_INSTRA(MAD
, FP_ARGA(SRC0A
), FP_ARGA(ONE
), FP_ARGA(ZERO
)));
305 reg_start(R300_PFS_INSTR3_0
, 0);
306 e32(FP_SELA(0, NO
, W
, FP_TMP(0), 0, 0));
309 R300_STATECHANGE(r300
, pvs
);
310 reg_start(R300_VAP_PVS_CNTL_1
, 2);
311 e32((0 << R300_PVS_CNTL_1_PROGRAM_START_SHIFT
) |
312 (0 << R300_PVS_CNTL_1_POS_END_SHIFT
) |
313 (1 << R300_PVS_CNTL_1_PROGRAM_END_SHIFT
));
315 e32(1 << R300_PVS_CNTL_3_PROGRAM_UNKNOWN_SHIFT
);
317 R300_STATECHANGE(r300
, vpi
);
318 vsf_start_fragment(0x0, 8);
319 e32(VP_OUT(ADD
, OUT
, 0, XYZW
));
324 e32(VP_OUT(ADD
, OUT
, 1, XYZW
));
334 static void r300Clear(GLcontext
* ctx
, GLbitfield mask
)
336 r300ContextPtr r300
= R300_CONTEXT(ctx
);
337 __DRIdrawablePrivate
*dPriv
= r300
->radeon
.dri
.drawable
;
342 if (RADEON_DEBUG
& DEBUG_IOCTL
)
343 fprintf(stderr
, "r300Clear\n");
346 LOCK_HARDWARE(&r300
->radeon
);
347 UNLOCK_HARDWARE(&r300
->radeon
);
348 if (dPriv
->numClipRects
== 0)
352 if (mask
& BUFFER_BIT_FRONT_LEFT
) {
353 flags
|= BUFFER_BIT_FRONT_LEFT
;
354 mask
&= ~BUFFER_BIT_FRONT_LEFT
;
357 if (mask
& BUFFER_BIT_BACK_LEFT
) {
358 flags
|= BUFFER_BIT_BACK_LEFT
;
359 mask
&= ~BUFFER_BIT_BACK_LEFT
;
362 if (mask
& BUFFER_BIT_DEPTH
) {
363 bits
|= CLEARBUFFER_DEPTH
;
364 mask
&= ~BUFFER_BIT_DEPTH
;
367 if ((mask
& BUFFER_BIT_STENCIL
) && r300
->state
.stencil
.hw_stencil
) {
368 bits
|= CLEARBUFFER_STENCIL
;
369 mask
&= ~BUFFER_BIT_STENCIL
;
373 if (RADEON_DEBUG
& DEBUG_FALLBACKS
)
374 fprintf(stderr
, "%s: swrast clear, mask: %x\n",
376 _swrast_Clear(ctx
, mask
);
379 swapped
= r300
->radeon
.sarea
->pfCurrentPage
== 1;
381 /* Make sure it fits there. */
382 r300EnsureCmdBufSpace(r300
, 421 * 3, __FUNCTION__
);
384 r300EmitClearState(ctx
);
386 if (flags
& BUFFER_BIT_FRONT_LEFT
) {
387 r300ClearBuffer(r300
, bits
| CLEARBUFFER_COLOR
, swapped
);
391 if (flags
& BUFFER_BIT_BACK_LEFT
) {
392 r300ClearBuffer(r300
, bits
| CLEARBUFFER_COLOR
, swapped
^ 1);
397 r300ClearBuffer(r300
, bits
, 0);
401 void r300Flush(GLcontext
* ctx
)
403 r300ContextPtr r300
= R300_CONTEXT(ctx
);
405 if (RADEON_DEBUG
& DEBUG_IOCTL
)
406 fprintf(stderr
, "%s\n", __FUNCTION__
);
408 if (r300
->cmdbuf
.count_used
> r300
->cmdbuf
.count_reemit
)
409 r300FlushCmdBuf(r300
, __FUNCTION__
);
413 #include "r300_mem.h"
415 static void r300RefillCurrentDmaRegion(r300ContextPtr rmesa
, int size
)
417 struct r300_dma_buffer
*dmabuf
;
418 size
= MAX2(size
, RADEON_BUFFER_SIZE
* 16);
420 if (RADEON_DEBUG
& (DEBUG_IOCTL
| DEBUG_DMA
))
421 fprintf(stderr
, "%s\n", __FUNCTION__
);
423 if (rmesa
->dma
.flush
) {
424 rmesa
->dma
.flush(rmesa
);
427 if (rmesa
->dma
.current
.buf
)
428 r300ReleaseDmaRegion(rmesa
, &rmesa
->dma
.current
, __FUNCTION__
);
430 if (rmesa
->dma
.nr_released_bufs
> 4)
431 r300FlushCmdBuf(rmesa
, __FUNCTION__
);
433 dmabuf
= CALLOC_STRUCT(r300_dma_buffer
);
434 dmabuf
->buf
= (void *)1; /* hack */
435 dmabuf
->refcount
= 1;
437 dmabuf
->id
= r300_mem_alloc(rmesa
, 4, size
);
438 if (dmabuf
->id
== 0) {
439 LOCK_HARDWARE(&rmesa
->radeon
); /* no need to validate */
441 r300FlushCmdBufLocked(rmesa
, __FUNCTION__
);
442 radeonWaitForIdleLocked(&rmesa
->radeon
);
444 dmabuf
->id
= r300_mem_alloc(rmesa
, 4, size
);
446 UNLOCK_HARDWARE(&rmesa
->radeon
);
448 if (dmabuf
->id
== 0) {
450 "Error: Could not get dma buffer... exiting\n");
455 rmesa
->dma
.current
.buf
= dmabuf
;
456 rmesa
->dma
.current
.address
= r300_mem_ptr(rmesa
, dmabuf
->id
);
457 rmesa
->dma
.current
.end
= size
;
458 rmesa
->dma
.current
.start
= 0;
459 rmesa
->dma
.current
.ptr
= 0;
462 void r300ReleaseDmaRegion(r300ContextPtr rmesa
,
463 struct r300_dma_region
*region
, const char *caller
)
465 if (RADEON_DEBUG
& DEBUG_IOCTL
)
466 fprintf(stderr
, "%s from %s\n", __FUNCTION__
, caller
);
471 if (rmesa
->dma
.flush
)
472 rmesa
->dma
.flush(rmesa
);
474 if (--region
->buf
->refcount
== 0) {
475 r300_mem_free(rmesa
, region
->buf
->id
);
477 rmesa
->dma
.nr_released_bufs
++;
484 /* Allocates a region from rmesa->dma.current. If there isn't enough
485 * space in current, grab a new buffer (and discard what was left of current)
487 void r300AllocDmaRegion(r300ContextPtr rmesa
,
488 struct r300_dma_region
*region
,
489 int bytes
, int alignment
)
491 if (RADEON_DEBUG
& DEBUG_IOCTL
)
492 fprintf(stderr
, "%s %d\n", __FUNCTION__
, bytes
);
494 if (rmesa
->dma
.flush
)
495 rmesa
->dma
.flush(rmesa
);
498 r300ReleaseDmaRegion(rmesa
, region
, __FUNCTION__
);
501 rmesa
->dma
.current
.start
= rmesa
->dma
.current
.ptr
=
502 (rmesa
->dma
.current
.ptr
+ alignment
) & ~alignment
;
504 if (rmesa
->dma
.current
.ptr
+ bytes
> rmesa
->dma
.current
.end
)
505 r300RefillCurrentDmaRegion(rmesa
, (bytes
+ 0x7) & ~0x7);
507 region
->start
= rmesa
->dma
.current
.start
;
508 region
->ptr
= rmesa
->dma
.current
.start
;
509 region
->end
= rmesa
->dma
.current
.start
+ bytes
;
510 region
->address
= rmesa
->dma
.current
.address
;
511 region
->buf
= rmesa
->dma
.current
.buf
;
512 region
->buf
->refcount
++;
514 rmesa
->dma
.current
.ptr
+= bytes
; /* bug - if alignment > 7 */
515 rmesa
->dma
.current
.start
=
516 rmesa
->dma
.current
.ptr
= (rmesa
->dma
.current
.ptr
+ 0x7) & ~0x7;
518 assert(rmesa
->dma
.current
.ptr
<= rmesa
->dma
.current
.end
);
522 static void r300RefillCurrentDmaRegion(r300ContextPtr rmesa
)
524 struct r300_dma_buffer
*dmabuf
;
525 int fd
= rmesa
->radeon
.dri
.fd
;
531 if (RADEON_DEBUG
& (DEBUG_IOCTL
| DEBUG_DMA
))
532 fprintf(stderr
, "%s\n", __FUNCTION__
);
534 if (rmesa
->dma
.flush
) {
535 rmesa
->dma
.flush(rmesa
);
538 if (rmesa
->dma
.current
.buf
)
539 r300ReleaseDmaRegion(rmesa
, &rmesa
->dma
.current
, __FUNCTION__
);
541 if (rmesa
->dma
.nr_released_bufs
> 4)
542 r300FlushCmdBuf(rmesa
, __FUNCTION__
);
544 dma
.context
= rmesa
->radeon
.dri
.hwContext
;
546 dma
.send_list
= NULL
;
547 dma
.send_sizes
= NULL
;
549 dma
.request_count
= 1;
550 dma
.request_size
= RADEON_BUFFER_SIZE
;
551 dma
.request_list
= &index
;
552 dma
.request_sizes
= &size
;
553 dma
.granted_count
= 0;
555 LOCK_HARDWARE(&rmesa
->radeon
); /* no need to validate */
557 ret
= drmDMA(fd
, &dma
);
560 /* Try to release some buffers and wait until we can't get any more */
561 if (rmesa
->dma
.nr_released_bufs
) {
562 r300FlushCmdBufLocked(rmesa
, __FUNCTION__
);
565 if (RADEON_DEBUG
& DEBUG_DMA
)
566 fprintf(stderr
, "Waiting for buffers\n");
568 radeonWaitForIdleLocked(&rmesa
->radeon
);
569 ret
= drmDMA(fd
, &dma
);
572 UNLOCK_HARDWARE(&rmesa
->radeon
);
574 "Error: Could not get dma buffer... exiting\n");
579 UNLOCK_HARDWARE(&rmesa
->radeon
);
581 if (RADEON_DEBUG
& DEBUG_DMA
)
582 fprintf(stderr
, "Allocated buffer %d\n", index
);
584 dmabuf
= CALLOC_STRUCT(r300_dma_buffer
);
585 dmabuf
->buf
= &rmesa
->radeon
.radeonScreen
->buffers
->list
[index
];
586 dmabuf
->refcount
= 1;
588 rmesa
->dma
.current
.buf
= dmabuf
;
589 rmesa
->dma
.current
.address
= dmabuf
->buf
->address
;
590 rmesa
->dma
.current
.end
= dmabuf
->buf
->total
;
591 rmesa
->dma
.current
.start
= 0;
592 rmesa
->dma
.current
.ptr
= 0;
595 void r300ReleaseDmaRegion(r300ContextPtr rmesa
,
596 struct r300_dma_region
*region
, const char *caller
)
598 if (RADEON_DEBUG
& DEBUG_IOCTL
)
599 fprintf(stderr
, "%s from %s\n", __FUNCTION__
, caller
);
604 if (rmesa
->dma
.flush
)
605 rmesa
->dma
.flush(rmesa
);
607 if (--region
->buf
->refcount
== 0) {
608 drm_radeon_cmd_header_t
*cmd
;
610 if (RADEON_DEBUG
& (DEBUG_IOCTL
| DEBUG_DMA
))
611 fprintf(stderr
, "%s -- DISCARD BUF %d\n",
612 __FUNCTION__
, region
->buf
->buf
->idx
);
614 (drm_radeon_cmd_header_t
*) r300AllocCmdBuf(rmesa
,
618 cmd
->dma
.cmd_type
= R300_CMD_DMA_DISCARD
;
619 cmd
->dma
.buf_idx
= region
->buf
->buf
->idx
;
622 rmesa
->dma
.nr_released_bufs
++;
629 /* Allocates a region from rmesa->dma.current. If there isn't enough
630 * space in current, grab a new buffer (and discard what was left of current)
632 void r300AllocDmaRegion(r300ContextPtr rmesa
,
633 struct r300_dma_region
*region
,
634 int bytes
, int alignment
)
636 if (RADEON_DEBUG
& DEBUG_IOCTL
)
637 fprintf(stderr
, "%s %d\n", __FUNCTION__
, bytes
);
639 if (rmesa
->dma
.flush
)
640 rmesa
->dma
.flush(rmesa
);
643 r300ReleaseDmaRegion(rmesa
, region
, __FUNCTION__
);
646 rmesa
->dma
.current
.start
= rmesa
->dma
.current
.ptr
=
647 (rmesa
->dma
.current
.ptr
+ alignment
) & ~alignment
;
649 if (rmesa
->dma
.current
.ptr
+ bytes
> rmesa
->dma
.current
.end
)
650 r300RefillCurrentDmaRegion(rmesa
);
652 region
->start
= rmesa
->dma
.current
.start
;
653 region
->ptr
= rmesa
->dma
.current
.start
;
654 region
->end
= rmesa
->dma
.current
.start
+ bytes
;
655 region
->address
= rmesa
->dma
.current
.address
;
656 region
->buf
= rmesa
->dma
.current
.buf
;
657 region
->buf
->refcount
++;
659 rmesa
->dma
.current
.ptr
+= bytes
; /* bug - if alignment > 7 */
660 rmesa
->dma
.current
.start
=
661 rmesa
->dma
.current
.ptr
= (rmesa
->dma
.current
.ptr
+ 0x7) & ~0x7;
663 assert(rmesa
->dma
.current
.ptr
<= rmesa
->dma
.current
.end
);
668 /* Called via glXGetMemoryOffsetMESA() */
669 GLuint
r300GetMemoryOffsetMESA(__DRInativeDisplay
* dpy
, int scrn
,
670 const GLvoid
* pointer
)
672 GET_CURRENT_CONTEXT(ctx
);
673 r300ContextPtr rmesa
;
676 if (!ctx
|| !(rmesa
= R300_CONTEXT(ctx
))) {
677 fprintf(stderr
, "%s: no context\n", __FUNCTION__
);
681 if (!r300IsGartMemory(rmesa
, pointer
, 0))
684 card_offset
= r300GartOffsetFromVirtual(rmesa
, pointer
);
686 return card_offset
- rmesa
->radeon
.radeonScreen
->gart_base
;
689 GLboolean
r300IsGartMemory(r300ContextPtr rmesa
, const GLvoid
* pointer
,
694 (char *)rmesa
->radeon
.radeonScreen
->gartTextures
.map
;
695 int valid
= (size
>= 0 && offset
>= 0
697 rmesa
->radeon
.radeonScreen
->gartTextures
.size
);
699 if (RADEON_DEBUG
& DEBUG_IOCTL
)
700 fprintf(stderr
, "r300IsGartMemory( %p ) : %d\n", pointer
,
706 GLuint
r300GartOffsetFromVirtual(r300ContextPtr rmesa
, const GLvoid
* pointer
)
710 (char *)rmesa
->radeon
.radeonScreen
->gartTextures
.map
;
712 //fprintf(stderr, "offset=%08x\n", offset);
715 || offset
> rmesa
->radeon
.radeonScreen
->gartTextures
.size
)
718 return rmesa
->radeon
.radeonScreen
->gart_texture_offset
+ offset
;
721 void r300InitIoctlFuncs(struct dd_function_table
*functions
)
723 functions
->Clear
= r300Clear
;
724 functions
->Finish
= radeonFinish
;
725 functions
->Flush
= r300Flush
;