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 R300_STATECHANGE(r300
, vir
[0]);
198 reg_start(R300_VAP_INPUT_ROUTE_0_0
, 0);
205 R300_STATECHANGE(r300
, fogs
);
206 reg_start(R300_RE_FOG_STATE
, 0);
209 R300_STATECHANGE(r300
, vir
[1]);
210 reg_start(R300_VAP_INPUT_ROUTE_1_0
, 0);
213 R300_STATECHANGE(r300
, vic
);
214 reg_start(R300_VAP_INPUT_CNTL_0
, 1);
219 R300_STATECHANGE(r300
, vte
);
220 /* comes from fglrx startup of clear */
221 reg_start(R300_SE_VTE_CNTL
, 1);
225 reg_start(0x21dc, 0);
229 R300_STATECHANGE(r300
, vof
);
230 reg_start(R300_VAP_OUTPUT_VTX_FMT_0
, 1);
231 e32(R300_VAP_OUTPUT_VTX_FMT_0__POS_PRESENT
|
232 R300_VAP_OUTPUT_VTX_FMT_0__COLOR_PRESENT
);
233 e32(0); /* no textures */
235 R300_STATECHANGE(r300
, txe
);
236 reg_start(R300_TX_ENABLE
, 0);
239 R300_STATECHANGE(r300
, vpt
);
240 reg_start(R300_SE_VPORT_XSCALE
, 5);
248 R300_STATECHANGE(r300
, at
);
249 reg_start(R300_PP_ALPHA_TEST
, 0);
252 R300_STATECHANGE(r300
, bld
);
253 reg_start(R300_RB3D_CBLEND
, 1);
257 R300_STATECHANGE(r300
, unk221C
);
258 reg_start(R300_VAP_UNKNOWN_221C
, 0);
259 e32(R300_221C_CLEAR
);
261 R300_STATECHANGE(r300
, ps
);
262 reg_start(R300_RE_POINTSIZE
, 0);
263 e32(((dPriv
->w
* 6) << R300_POINTSIZE_X_SHIFT
) |
264 ((dPriv
->h
* 6) << R300_POINTSIZE_Y_SHIFT
));
266 R300_STATECHANGE(r300
, ri
);
267 reg_start(R300_RS_INTERP_0
, 8);
268 for (i
= 0; i
< 8; ++i
) {
269 e32(R300_RS_INTERP_USED
);
272 R300_STATECHANGE(r300
, rc
);
273 /* The second constant is needed to get glxgears display anything .. */
274 reg_start(R300_RS_CNTL_0
, 1);
275 e32((1 << R300_RS_CNTL_CI_CNT_SHIFT
) | R300_RS_CNTL_0_UNKNOWN_18
);
278 R300_STATECHANGE(r300
, rr
);
279 reg_start(R300_RS_ROUTE_0
, 0);
282 R300_STATECHANGE(r300
, fp
);
283 reg_start(R300_PFS_CNTL_0
, 2);
287 reg_start(R300_PFS_NODE_0
, 3);
291 e32(R300_PFS_NODE_OUTPUT_COLOR
);
293 R300_STATECHANGE(r300
, fpi
[0]);
294 R300_STATECHANGE(r300
, fpi
[1]);
295 R300_STATECHANGE(r300
, fpi
[2]);
296 R300_STATECHANGE(r300
, fpi
[3]);
298 reg_start(R300_PFS_INSTR0_0
, 0);
299 e32(FP_INSTRC(MAD
, FP_ARGC(SRC0C_XYZ
), FP_ARGC(ONE
), FP_ARGC(ZERO
)));
301 reg_start(R300_PFS_INSTR1_0
, 0);
302 e32(FP_SELC(0, NO
, XYZ
, FP_TMP(0), 0, 0));
304 reg_start(R300_PFS_INSTR2_0
, 0);
305 e32(FP_INSTRA(MAD
, FP_ARGA(SRC0A
), FP_ARGA(ONE
), FP_ARGA(ZERO
)));
307 reg_start(R300_PFS_INSTR3_0
, 0);
308 e32(FP_SELA(0, NO
, W
, FP_TMP(0), 0, 0));
311 R300_STATECHANGE(r300
, pvs
);
312 reg_start(R300_VAP_PVS_CNTL_1
, 2);
313 e32((0 << R300_PVS_CNTL_1_PROGRAM_START_SHIFT
) |
314 (0 << R300_PVS_CNTL_1_POS_END_SHIFT
) |
315 (1 << R300_PVS_CNTL_1_PROGRAM_END_SHIFT
));
317 e32(1 << R300_PVS_CNTL_3_PROGRAM_UNKNOWN_SHIFT
);
319 R300_STATECHANGE(r300
, vpi
);
320 vsf_start_fragment(0x0, 8);
321 e32(VP_OUT(ADD
, OUT
, 0, XYZW
));
326 e32(VP_OUT(ADD
, OUT
, 1, XYZW
));
336 static void r300Clear(GLcontext
* ctx
, GLbitfield mask
)
338 r300ContextPtr r300
= R300_CONTEXT(ctx
);
339 __DRIdrawablePrivate
*dPriv
= r300
->radeon
.dri
.drawable
;
344 if (RADEON_DEBUG
& DEBUG_IOCTL
)
345 fprintf(stderr
, "r300Clear\n");
348 LOCK_HARDWARE(&r300
->radeon
);
349 UNLOCK_HARDWARE(&r300
->radeon
);
350 if (dPriv
->numClipRects
== 0)
354 if (mask
& BUFFER_BIT_FRONT_LEFT
) {
355 flags
|= BUFFER_BIT_FRONT_LEFT
;
356 mask
&= ~BUFFER_BIT_FRONT_LEFT
;
359 if (mask
& BUFFER_BIT_BACK_LEFT
) {
360 flags
|= BUFFER_BIT_BACK_LEFT
;
361 mask
&= ~BUFFER_BIT_BACK_LEFT
;
364 if (mask
& BUFFER_BIT_DEPTH
) {
365 bits
|= CLEARBUFFER_DEPTH
;
366 mask
&= ~BUFFER_BIT_DEPTH
;
369 if ((mask
& BUFFER_BIT_STENCIL
) && r300
->state
.stencil
.hw_stencil
) {
370 bits
|= CLEARBUFFER_STENCIL
;
371 mask
&= ~BUFFER_BIT_STENCIL
;
375 if (RADEON_DEBUG
& DEBUG_FALLBACKS
)
376 fprintf(stderr
, "%s: swrast clear, mask: %x\n",
378 _swrast_Clear(ctx
, mask
);
381 swapped
= r300
->radeon
.sarea
->pfCurrentPage
== 1;
383 /* Make sure it fits there. */
384 r300EnsureCmdBufSpace(r300
, 421 * 3, __FUNCTION__
);
386 r300EmitClearState(ctx
);
388 if (flags
& BUFFER_BIT_FRONT_LEFT
) {
389 r300ClearBuffer(r300
, bits
| CLEARBUFFER_COLOR
, swapped
);
393 if (flags
& BUFFER_BIT_BACK_LEFT
) {
394 r300ClearBuffer(r300
, bits
| CLEARBUFFER_COLOR
, swapped
^ 1);
399 r300ClearBuffer(r300
, bits
, 0);
403 void r300Flush(GLcontext
* ctx
)
405 r300ContextPtr r300
= R300_CONTEXT(ctx
);
407 if (RADEON_DEBUG
& DEBUG_IOCTL
)
408 fprintf(stderr
, "%s\n", __FUNCTION__
);
410 if (r300
->cmdbuf
.count_used
> r300
->cmdbuf
.count_reemit
)
411 r300FlushCmdBuf(r300
, __FUNCTION__
);
415 #include "r300_mem.h"
417 static void r300RefillCurrentDmaRegion(r300ContextPtr rmesa
, int size
)
419 struct r300_dma_buffer
*dmabuf
;
420 size
= MAX2(size
, RADEON_BUFFER_SIZE
* 16);
422 if (RADEON_DEBUG
& (DEBUG_IOCTL
| DEBUG_DMA
))
423 fprintf(stderr
, "%s\n", __FUNCTION__
);
425 if (rmesa
->dma
.flush
) {
426 rmesa
->dma
.flush(rmesa
);
429 if (rmesa
->dma
.current
.buf
)
430 r300ReleaseDmaRegion(rmesa
, &rmesa
->dma
.current
, __FUNCTION__
);
432 if (rmesa
->dma
.nr_released_bufs
> 4)
433 r300FlushCmdBuf(rmesa
, __FUNCTION__
);
435 dmabuf
= CALLOC_STRUCT(r300_dma_buffer
);
436 dmabuf
->buf
= (void *)1; /* hack */
437 dmabuf
->refcount
= 1;
439 dmabuf
->id
= r300_mem_alloc(rmesa
, 4, size
);
440 if (dmabuf
->id
== 0) {
441 LOCK_HARDWARE(&rmesa
->radeon
); /* no need to validate */
443 r300FlushCmdBufLocked(rmesa
, __FUNCTION__
);
444 radeonWaitForIdleLocked(&rmesa
->radeon
);
446 dmabuf
->id
= r300_mem_alloc(rmesa
, 4, size
);
448 UNLOCK_HARDWARE(&rmesa
->radeon
);
450 if (dmabuf
->id
== 0) {
452 "Error: Could not get dma buffer... exiting\n");
457 rmesa
->dma
.current
.buf
= dmabuf
;
458 rmesa
->dma
.current
.address
= r300_mem_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 r300_mem_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
, (bytes
+ 0x7) & ~0x7);
509 region
->start
= rmesa
->dma
.current
.start
;
510 region
->ptr
= rmesa
->dma
.current
.start
;
511 region
->end
= rmesa
->dma
.current
.start
+ bytes
;
512 region
->address
= rmesa
->dma
.current
.address
;
513 region
->buf
= rmesa
->dma
.current
.buf
;
514 region
->buf
->refcount
++;
516 rmesa
->dma
.current
.ptr
+= bytes
; /* bug - if alignment > 7 */
517 rmesa
->dma
.current
.start
=
518 rmesa
->dma
.current
.ptr
= (rmesa
->dma
.current
.ptr
+ 0x7) & ~0x7;
520 assert(rmesa
->dma
.current
.ptr
<= rmesa
->dma
.current
.end
);
524 static void r300RefillCurrentDmaRegion(r300ContextPtr rmesa
)
526 struct r300_dma_buffer
*dmabuf
;
527 int fd
= rmesa
->radeon
.dri
.fd
;
533 if (RADEON_DEBUG
& (DEBUG_IOCTL
| DEBUG_DMA
))
534 fprintf(stderr
, "%s\n", __FUNCTION__
);
536 if (rmesa
->dma
.flush
) {
537 rmesa
->dma
.flush(rmesa
);
540 if (rmesa
->dma
.current
.buf
)
541 r300ReleaseDmaRegion(rmesa
, &rmesa
->dma
.current
, __FUNCTION__
);
543 if (rmesa
->dma
.nr_released_bufs
> 4)
544 r300FlushCmdBuf(rmesa
, __FUNCTION__
);
546 dma
.context
= rmesa
->radeon
.dri
.hwContext
;
548 dma
.send_list
= NULL
;
549 dma
.send_sizes
= NULL
;
551 dma
.request_count
= 1;
552 dma
.request_size
= RADEON_BUFFER_SIZE
;
553 dma
.request_list
= &index
;
554 dma
.request_sizes
= &size
;
555 dma
.granted_count
= 0;
557 LOCK_HARDWARE(&rmesa
->radeon
); /* no need to validate */
559 ret
= drmDMA(fd
, &dma
);
562 /* Try to release some buffers and wait until we can't get any more */
563 if (rmesa
->dma
.nr_released_bufs
) {
564 r300FlushCmdBufLocked(rmesa
, __FUNCTION__
);
567 if (RADEON_DEBUG
& DEBUG_DMA
)
568 fprintf(stderr
, "Waiting for buffers\n");
570 radeonWaitForIdleLocked(&rmesa
->radeon
);
571 ret
= drmDMA(fd
, &dma
);
574 UNLOCK_HARDWARE(&rmesa
->radeon
);
576 "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",
614 __FUNCTION__
, region
->buf
->buf
->idx
);
616 (drm_radeon_cmd_header_t
*) r300AllocCmdBuf(rmesa
,
620 cmd
->dma
.cmd_type
= R300_CMD_DMA_DISCARD
;
621 cmd
->dma
.buf_idx
= region
->buf
->buf
->idx
;
624 rmesa
->dma
.nr_released_bufs
++;
631 /* Allocates a region from rmesa->dma.current. If there isn't enough
632 * space in current, grab a new buffer (and discard what was left of current)
634 void r300AllocDmaRegion(r300ContextPtr rmesa
,
635 struct r300_dma_region
*region
,
636 int bytes
, int alignment
)
638 if (RADEON_DEBUG
& DEBUG_IOCTL
)
639 fprintf(stderr
, "%s %d\n", __FUNCTION__
, bytes
);
641 if (rmesa
->dma
.flush
)
642 rmesa
->dma
.flush(rmesa
);
645 r300ReleaseDmaRegion(rmesa
, region
, __FUNCTION__
);
648 rmesa
->dma
.current
.start
= rmesa
->dma
.current
.ptr
=
649 (rmesa
->dma
.current
.ptr
+ alignment
) & ~alignment
;
651 if (rmesa
->dma
.current
.ptr
+ bytes
> rmesa
->dma
.current
.end
)
652 r300RefillCurrentDmaRegion(rmesa
);
654 region
->start
= rmesa
->dma
.current
.start
;
655 region
->ptr
= rmesa
->dma
.current
.start
;
656 region
->end
= rmesa
->dma
.current
.start
+ bytes
;
657 region
->address
= rmesa
->dma
.current
.address
;
658 region
->buf
= rmesa
->dma
.current
.buf
;
659 region
->buf
->refcount
++;
661 rmesa
->dma
.current
.ptr
+= bytes
; /* bug - if alignment > 7 */
662 rmesa
->dma
.current
.start
=
663 rmesa
->dma
.current
.ptr
= (rmesa
->dma
.current
.ptr
+ 0x7) & ~0x7;
665 assert(rmesa
->dma
.current
.ptr
<= rmesa
->dma
.current
.end
);
670 /* Called via glXGetMemoryOffsetMESA() */
671 GLuint
r300GetMemoryOffsetMESA(__DRInativeDisplay
* dpy
, int scrn
,
672 const GLvoid
* pointer
)
674 GET_CURRENT_CONTEXT(ctx
);
675 r300ContextPtr rmesa
;
678 if (!ctx
|| !(rmesa
= R300_CONTEXT(ctx
))) {
679 fprintf(stderr
, "%s: no context\n", __FUNCTION__
);
683 if (!r300IsGartMemory(rmesa
, pointer
, 0))
686 card_offset
= r300GartOffsetFromVirtual(rmesa
, pointer
);
688 return card_offset
- rmesa
->radeon
.radeonScreen
->gart_base
;
691 GLboolean
r300IsGartMemory(r300ContextPtr rmesa
, const GLvoid
* pointer
,
696 (char *)rmesa
->radeon
.radeonScreen
->gartTextures
.map
;
697 int valid
= (size
>= 0 && offset
>= 0
699 rmesa
->radeon
.radeonScreen
->gartTextures
.size
);
701 if (RADEON_DEBUG
& DEBUG_IOCTL
)
702 fprintf(stderr
, "r300IsGartMemory( %p ) : %d\n", pointer
,
708 GLuint
r300GartOffsetFromVirtual(r300ContextPtr rmesa
, const GLvoid
* pointer
)
712 (char *)rmesa
->radeon
.radeonScreen
->gartTextures
.map
;
714 //fprintf(stderr, "offset=%08x\n", offset);
717 || offset
> rmesa
->radeon
.radeonScreen
->gartTextures
.size
)
720 return rmesa
->radeon
.radeonScreen
->gart_texture_offset
+ offset
;
723 void r300InitIoctlFuncs(struct dd_function_table
*functions
)
725 functions
->Clear
= r300Clear
;
726 functions
->Finish
= radeonFinish
;
727 functions
->Flush
= r300Flush
;