1 /**************************************************************************
3 Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and
4 VA Linux Systems Inc., Fremont, California.
8 Permission is hereby granted, free of charge, to any person obtaining
9 a copy of this software and associated documentation files (the
10 "Software"), to deal in the Software without restriction, including
11 without limitation the rights to use, copy, modify, merge, publish,
12 distribute, sublicense, and/or sell copies of the Software, and to
13 permit persons to whom the Software is furnished to do so, subject to
14 the following conditions:
16 The above copyright notice and this permission notice (including the
17 next paragraph) shall be included in all copies or substantial
18 portions of the Software.
20 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
23 IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
24 LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25 OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28 **************************************************************************/
32 * Kevin E. Martin <martin@valinux.com>
33 * Gareth Hughes <gareth@valinux.com>
34 * Keith Whitwell <keith@tungstengraphics.com>
40 #include "main/glheader.h"
41 #include "main/imports.h"
42 #include "main/simple_list.h"
43 #include "swrast/swrast.h"
45 #include "radeon_context.h"
46 #include "common_cmdbuf.h"
47 #include "radeon_cs.h"
48 #include "radeon_state.h"
49 #include "radeon_ioctl.h"
50 #include "radeon_tcl.h"
51 #include "radeon_sanity.h"
53 #define STANDALONE_MMIO
54 #include "radeon_macros.h" /* for INREG() */
56 #include "drirenderbuffer.h"
59 #define RADEON_TIMEOUT 512
60 #define RADEON_IDLE_RETRY 16
62 #define DEBUG_CMDBUF 1
64 static void radeonSaveHwState( r100ContextPtr rmesa
)
66 struct radeon_state_atom
*atom
;
67 char * dest
= rmesa
->backup_store
.cmd_buf
;
69 if (RADEON_DEBUG
& DEBUG_STATE
)
70 fprintf(stderr
, "%s\n", __FUNCTION__
);
72 rmesa
->backup_store
.cmd_used
= 0;
74 foreach( atom
, &rmesa
->hw
.atomlist
) {
75 if ( atom
->check( rmesa
->radeon
.glCtx
, 0 ) ) {
76 int size
= atom
->cmd_size
* 4;
77 memcpy( dest
, atom
->cmd
, size
);
79 rmesa
->backup_store
.cmd_used
+= size
;
80 if (RADEON_DEBUG
& DEBUG_STATE
)
81 radeon_print_state_atom( atom
);
85 assert( rmesa
->backup_store
.cmd_used
<= RADEON_CMD_BUF_SZ
);
86 if (RADEON_DEBUG
& DEBUG_STATE
)
87 fprintf(stderr
, "Returning to radeonEmitState\n");
90 /* At this point we were in FlushCmdBufLocked but we had lost our context, so
91 * we need to unwire our current cmdbuf, hook the one with the saved state in
92 * it, flush it, and then put the current one back. This is so commands at the
93 * start of a cmdbuf can rely on the state being kept from the previous one.
95 static void radeonBackUpAndEmitLostStateLocked( r100ContextPtr rmesa
)
97 GLuint nr_released_bufs
;
98 struct radeon_store saved_store
;
100 if (rmesa
->backup_store
.cmd_used
== 0)
103 if (RADEON_DEBUG
& DEBUG_STATE
)
104 fprintf(stderr
, "Emitting backup state on lost context\n");
106 rmesa
->radeon
.lost_context
= GL_FALSE
;
108 nr_released_bufs
= rmesa
->radeon
.dma
.nr_released_bufs
;
109 saved_store
= rmesa
->store
;
110 rmesa
->radeon
.dma
.nr_released_bufs
= 0;
111 rmesa
->store
= rmesa
->backup_store
;
112 rcommonFlushCmdBufLocked( &rmesa
->radeon
, __FUNCTION__
);
113 rmesa
->radeon
.dma
.nr_released_bufs
= nr_released_bufs
;
114 rmesa
->store
= saved_store
;
117 /* =============================================================
118 * Kernel command buffer handling
121 /* The state atoms will be emitted in the order they appear in the atom list,
122 * so this step is important.
124 void radeonSetUpAtomList( r100ContextPtr rmesa
)
126 int i
, mtu
= rmesa
->radeon
.glCtx
->Const
.MaxTextureUnits
;
128 make_empty_list(&rmesa
->hw
.atomlist
);
129 rmesa
->hw
.atomlist
.name
= "atom-list";
131 insert_at_tail(&rmesa
->hw
.atomlist
, &rmesa
->hw
.ctx
);
132 insert_at_tail(&rmesa
->hw
.atomlist
, &rmesa
->hw
.set
);
133 insert_at_tail(&rmesa
->hw
.atomlist
, &rmesa
->hw
.lin
);
134 insert_at_tail(&rmesa
->hw
.atomlist
, &rmesa
->hw
.msk
);
135 insert_at_tail(&rmesa
->hw
.atomlist
, &rmesa
->hw
.vpt
);
136 insert_at_tail(&rmesa
->hw
.atomlist
, &rmesa
->hw
.tcl
);
137 insert_at_tail(&rmesa
->hw
.atomlist
, &rmesa
->hw
.msc
);
138 for (i
= 0; i
< mtu
; ++i
) {
139 insert_at_tail(&rmesa
->hw
.atomlist
, &rmesa
->hw
.tex
[i
]);
140 insert_at_tail(&rmesa
->hw
.atomlist
, &rmesa
->hw
.txr
[i
]);
141 insert_at_tail(&rmesa
->hw
.atomlist
, &rmesa
->hw
.cube
[i
]);
143 insert_at_tail(&rmesa
->hw
.atomlist
, &rmesa
->hw
.zbs
);
144 insert_at_tail(&rmesa
->hw
.atomlist
, &rmesa
->hw
.mtl
);
145 for (i
= 0; i
< 3 + mtu
; ++i
)
146 insert_at_tail(&rmesa
->hw
.atomlist
, &rmesa
->hw
.mat
[i
]);
147 for (i
= 0; i
< 8; ++i
)
148 insert_at_tail(&rmesa
->hw
.atomlist
, &rmesa
->hw
.lit
[i
]);
149 for (i
= 0; i
< 6; ++i
)
150 insert_at_tail(&rmesa
->hw
.atomlist
, &rmesa
->hw
.ucp
[i
]);
151 insert_at_tail(&rmesa
->hw
.atomlist
, &rmesa
->hw
.eye
);
152 insert_at_tail(&rmesa
->hw
.atomlist
, &rmesa
->hw
.grd
);
153 insert_at_tail(&rmesa
->hw
.atomlist
, &rmesa
->hw
.fog
);
154 insert_at_tail(&rmesa
->hw
.atomlist
, &rmesa
->hw
.glt
);
157 static INLINE
void radeonEmitAtoms(r100ContextPtr r100
, GLboolean dirty
)
159 BATCH_LOCALS(&r100
->radeon
);
160 struct radeon_state_atom
*atom
;
163 /* Emit actual atoms */
164 foreach(atom
, &r100
->hw
.atomlist
) {
165 if ((atom
->dirty
|| r100
->hw
.all_dirty
) == dirty
) {
166 dwords
= (*atom
->check
) (r100
->radeon
.glCtx
, atom
);
168 if (DEBUG_CMDBUF
&& RADEON_DEBUG
& DEBUG_STATE
) {
169 radeon_print_state_atom(atom
);
172 (*atom
->emit
)(r100
->radeon
.glCtx
, atom
);
174 BEGIN_BATCH_NO_AUTOSTATE(dwords
);
175 OUT_BATCH_TABLE(atom
->cmd
, dwords
);
178 atom
->dirty
= GL_FALSE
;
180 if (DEBUG_CMDBUF
&& RADEON_DEBUG
& DEBUG_STATE
) {
181 fprintf(stderr
, " skip state %s\n",
191 void radeonEmitState( r100ContextPtr rmesa
)
193 if (RADEON_DEBUG
& (DEBUG_STATE
|DEBUG_PRIMS
))
194 fprintf(stderr
, "%s\n", __FUNCTION__
);
196 if (rmesa
->save_on_next_emit
) {
197 radeonSaveHwState(rmesa
);
198 rmesa
->save_on_next_emit
= GL_FALSE
;
201 /* this code used to return here but now it emits zbs */
203 /* To avoid going across the entire set of states multiple times, just check
204 * for enough space for the case of emitting all state, and inline the
205 * radeonAllocCmdBuf code here without all the checks.
207 rcommonEnsureCmdBufSpace(&rmesa
->radeon
, rmesa
->hw
.max_state_size
, __FUNCTION__
);
209 /* We always always emit zbs, this is due to a bug found by keithw in
210 the hardware and rediscovered after Erics changes by me.
211 if you ever touch this code make sure you emit zbs otherwise
212 you get tcl lockups on at least M7/7500 class of chips - airlied */
213 rmesa
->hw
.zbs
.dirty
=1;
215 if (!rmesa
->radeon
.cmdbuf
.cs
->cdw
) {
216 if (RADEON_DEBUG
& DEBUG_STATE
)
217 fprintf(stderr
, "Begin reemit state\n");
219 radeonEmitAtoms(rmesa
, GL_FALSE
);
222 if (RADEON_DEBUG
& DEBUG_STATE
)
223 fprintf(stderr
, "Begin dirty state\n");
225 radeonEmitAtoms(rmesa
, GL_TRUE
);
226 rmesa
->hw
.is_dirty
= GL_FALSE
;
227 rmesa
->hw
.all_dirty
= GL_FALSE
;
231 /* Fire a section of the retained (indexed_verts) buffer as a regular
234 extern void radeonEmitVbufPrim( r100ContextPtr rmesa
,
235 GLuint vertex_format
,
239 BATCH_LOCALS(&rmesa
->radeon
);
241 assert(!(primitive
& RADEON_CP_VC_CNTL_PRIM_WALK_IND
));
243 radeonEmitState( rmesa
);
245 #if RADEON_OLD_PACKETS
247 OUT_BATCH_PACKET3_CLIP(RADEON_CP_PACKET3_3D_RNDR_GEN_INDX_PRIM
, 3);
248 OUT_BATCH_RELOC(rmesa
->ioctl
.vertex_offset
, rmesa
->ioctl
.bo
, rmesa
->ioctl
.vertex_offset
, RADEON_GEM_DOMAIN_GTT
, 0, 0);
249 OUT_BATCH(vertex_nr
);
250 OUT_BATCH(vertex_format
);
251 OUT_BATCH(primitive
| RADEON_CP_VC_CNTL_PRIM_WALK_LIST
|
252 RADEON_CP_VC_CNTL_COLOR_ORDER_RGBA
|
253 RADEON_CP_VC_CNTL_VTX_FMT_RADEON_MODE
|
254 (vertex_nr
<< RADEON_CP_VC_CNTL_NUM_SHIFT
));
259 OUT_BATCH_PACKET3_CLIP(RADEON_CP_PACKET3_3D_DRAW_VBUF
, 1);
260 OUT_BATCH(vertex_format
);
261 OUT_BATCH(primitive
|
262 RADEON_CP_VC_CNTL_PRIM_WALK_LIST
|
263 RADEON_CP_VC_CNTL_COLOR_ORDER_RGBA
|
264 RADEON_CP_VC_CNTL_MAOS_ENABLE
|
265 RADEON_CP_VC_CNTL_VTX_FMT_RADEON_MODE
|
266 (vertex_nr
<< RADEON_CP_VC_CNTL_NUM_SHIFT
));
271 void radeonFlushElts( GLcontext
*ctx
)
273 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
274 BATCH_LOCALS(&rmesa
->radeon
);
276 uint32_t *cmd
= (uint32_t *)(rmesa
->radeon
.cmdbuf
.cs
->packets
+ rmesa
->tcl
.elt_cmd_start
);
277 int dwords
= (rmesa
->radeon
.cmdbuf
.cs
->section_ndw
- rmesa
->radeon
.cmdbuf
.cs
->section_cdw
);
279 if (RADEON_DEBUG
& DEBUG_IOCTL
)
280 fprintf(stderr
, "%s\n", __FUNCTION__
);
282 assert( rmesa
->radeon
.dma
.flush
== radeonFlushElts
);
283 rmesa
->radeon
.dma
.flush
= NULL
;
285 nr
= rmesa
->tcl
.elt_used
;
287 rmesa
->radeon
.cmdbuf
.cs
->cdw
+= dwords
;
289 #if RADEON_OLD_PACKETS
290 cmd
[1] |= (dwords
+ 3) << 16;
291 cmd
[5] |= nr
<< RADEON_CP_VC_CNTL_NUM_SHIFT
;
293 cmd
[1] |= (dwords
+ 2) << 16;
294 cmd
[3] |= nr
<< RADEON_CP_VC_CNTL_NUM_SHIFT
;
297 rmesa
->radeon
.cmdbuf
.cs
->section_cdw
+= dwords
;
300 if (RADEON_DEBUG
& DEBUG_SYNC
) {
301 fprintf(stderr
, "%s: Syncing\n", __FUNCTION__
);
302 radeonFinish( rmesa
->radeon
.glCtx
);
307 GLushort
*radeonAllocEltsOpenEnded( r100ContextPtr rmesa
,
308 GLuint vertex_format
,
314 BATCH_LOCALS(&rmesa
->radeon
);
316 if (RADEON_DEBUG
& DEBUG_IOCTL
)
317 fprintf(stderr
, "%s %d prim %x\n", __FUNCTION__
, min_nr
, primitive
);
319 assert((primitive
& RADEON_CP_VC_CNTL_PRIM_WALK_IND
));
321 radeonEmitState( rmesa
);
323 rmesa
->tcl
.elt_cmd_start
= rmesa
->radeon
.cmdbuf
.cs
->cdw
;
325 /* round up min_nr to align the state */
326 align_min_nr
= (min_nr
+ 1) & ~1;
328 #if RADEON_OLD_PACKETS
329 BEGIN_BATCH_NO_AUTOSTATE(2+ELTS_BUFSZ(align_min_nr
)/4);
330 OUT_BATCH_PACKET3_CLIP(RADEON_CP_PACKET3_3D_RNDR_GEN_INDX_PRIM
, 0);
331 OUT_BATCH_RELOC(rmesa
->ioctl
.vertex_offset
, rmesa
->ioctl
.bo
, rmesa
->ioctl
.vertex_offset
, RADEON_GEM_DOMAIN_GTT
, 0, 0);
333 OUT_BATCH(vertex_format
);
334 OUT_BATCH(primitive
|
335 RADEON_CP_VC_CNTL_PRIM_WALK_IND
|
336 RADEON_CP_VC_CNTL_COLOR_ORDER_RGBA
|
337 RADEON_CP_VC_CNTL_VTX_FMT_RADEON_MODE
);
340 BEGIN_BATCH_NO_AUTOSTATE(ELTS_BUFSZ(align_min_nr
)/4);
341 OUT_BATCH_PACKET3_CLIP(RADEON_CP_PACKET3_DRAW_INDX
, 0);
342 OUT_BATCH(vertex_format
);
343 OUT_BATCH(primitive
|
344 RADEON_CP_VC_CNTL_PRIM_WALK_IND
|
345 RADEON_CP_VC_CNTL_COLOR_ORDER_RGBA
|
346 RADEON_CP_VC_CNTL_MAOS_ENABLE
|
347 RADEON_CP_VC_CNTL_VTX_FMT_RADEON_MODE
);
351 rmesa
->tcl
.elt_cmd_offset
= rmesa
->radeon
.cmdbuf
.cs
->cdw
;
352 rmesa
->tcl
.elt_used
= min_nr
;
354 retval
= (GLushort
*)(rmesa
->radeon
.cmdbuf
.cs
->packets
+ rmesa
->tcl
.elt_cmd_offset
);
356 if (RADEON_DEBUG
& DEBUG_PRIMS
)
357 fprintf(stderr
, "%s: header prim %x \n",
358 __FUNCTION__
, primitive
);
360 assert(!rmesa
->radeon
.dma
.flush
);
361 rmesa
->radeon
.glCtx
->Driver
.NeedFlush
|= FLUSH_STORED_VERTICES
;
362 rmesa
->radeon
.dma
.flush
= radeonFlushElts
;
367 void radeonEmitVertexAOS( r100ContextPtr rmesa
,
369 struct radeon_bo
*bo
,
372 #if RADEON_OLD_PACKETS
373 rmesa
->ioctl
.vertex_offset
= offset
;
374 rmesa
->ioctl
.bo
= bo
;
376 BATCH_LOCALS(&rmesa
->radeon
);
378 if (RADEON_DEBUG
& (DEBUG_PRIMS
|DEBUG_IOCTL
))
379 fprintf(stderr
, "%s: vertex_size 0x%x offset 0x%x \n",
380 __FUNCTION__
, vertex_size
, offset
);
383 OUT_BATCH_PACKET3(RADEON_CP_PACKET3_3D_LOAD_VBPNTR
, 2);
385 OUT_BATCH(vertex_size
| (vertex_size
<< 8));
386 OUT_BATCH_RELOC(offset
, bo
, offset
, RADEON_GEM_DOMAIN_GTT
, 0, 0);
393 void radeonEmitAOS( r100ContextPtr rmesa
,
397 #if RADEON_OLD_PACKETS
399 rmesa
->ioctl
.bo
= rmesa
->tcl
.aos
[0].bo
;
400 rmesa
->ioctl
.vertex_offset
=
401 (rmesa
->tcl
.aos
[0].offset
+ offset
* rmesa
->tcl
.aos
[0].stride
* 4);
403 BATCH_LOCALS(&rmesa
->radeon
);
405 // int sz = AOS_BUFSZ(nr);
406 int sz
= 1 + (nr
>> 1) * 3 + (nr
& 1) * 2;
409 if (RADEON_DEBUG
& DEBUG_IOCTL
)
410 fprintf(stderr
, "%s\n", __FUNCTION__
);
412 BEGIN_BATCH(sz
+2+(nr
* 2));
413 OUT_BATCH_PACKET3(RADEON_CP_PACKET3_3D_LOAD_VBPNTR
, sz
- 1);
416 if (!rmesa
->radeon
.radeonScreen
->kernel_mm
) {
417 for (i
= 0; i
+ 1 < nr
; i
+= 2) {
418 OUT_BATCH((rmesa
->tcl
.aos
[i
].components
<< 0) |
419 (rmesa
->tcl
.aos
[i
].stride
<< 8) |
420 (rmesa
->tcl
.aos
[i
+ 1].components
<< 16) |
421 (rmesa
->tcl
.aos
[i
+ 1].stride
<< 24));
423 voffset
= rmesa
->tcl
.aos
[i
+ 0].offset
+
424 offset
* 4 * rmesa
->tcl
.aos
[i
+ 0].stride
;
425 OUT_BATCH_RELOC(voffset
,
426 rmesa
->tcl
.aos
[i
].bo
,
428 RADEON_GEM_DOMAIN_GTT
,
430 voffset
= rmesa
->tcl
.aos
[i
+ 1].offset
+
431 offset
* 4 * rmesa
->tcl
.aos
[i
+ 1].stride
;
432 OUT_BATCH_RELOC(voffset
,
433 rmesa
->tcl
.aos
[i
+1].bo
,
435 RADEON_GEM_DOMAIN_GTT
,
440 OUT_BATCH((rmesa
->tcl
.aos
[nr
- 1].components
<< 0) |
441 (rmesa
->tcl
.aos
[nr
- 1].stride
<< 8));
442 voffset
= rmesa
->tcl
.aos
[nr
- 1].offset
+
443 offset
* 4 * rmesa
->tcl
.aos
[nr
- 1].stride
;
444 OUT_BATCH_RELOC(voffset
,
445 rmesa
->tcl
.aos
[nr
- 1].bo
,
447 RADEON_GEM_DOMAIN_GTT
,
451 for (i
= 0; i
+ 1 < nr
; i
+= 2) {
452 OUT_BATCH((rmesa
->tcl
.aos
[i
].components
<< 0) |
453 (rmesa
->tcl
.aos
[i
].stride
<< 8) |
454 (rmesa
->tcl
.aos
[i
+ 1].components
<< 16) |
455 (rmesa
->tcl
.aos
[i
+ 1].stride
<< 24));
457 voffset
= rmesa
->tcl
.aos
[i
+ 0].offset
+
458 offset
* 4 * rmesa
->tcl
.aos
[i
+ 0].stride
;
460 voffset
= rmesa
->tcl
.aos
[i
+ 1].offset
+
461 offset
* 4 * rmesa
->tcl
.aos
[i
+ 1].stride
;
466 OUT_BATCH((rmesa
->tcl
.aos
[nr
- 1].components
<< 0) |
467 (rmesa
->tcl
.aos
[nr
- 1].stride
<< 8));
468 voffset
= rmesa
->tcl
.aos
[nr
- 1].offset
+
469 offset
* 4 * rmesa
->tcl
.aos
[nr
- 1].stride
;
472 for (i
= 0; i
+ 1 < nr
; i
+= 2) {
473 voffset
= rmesa
->tcl
.aos
[i
+ 0].offset
+
474 offset
* 4 * rmesa
->tcl
.aos
[i
+ 0].stride
;
475 radeon_cs_write_reloc(rmesa
->radeon
.cmdbuf
.cs
,
476 rmesa
->tcl
.aos
[i
+0].bo
,
477 RADEON_GEM_DOMAIN_GTT
,
479 voffset
= rmesa
->tcl
.aos
[i
+ 1].offset
+
480 offset
* 4 * rmesa
->tcl
.aos
[i
+ 1].stride
;
481 radeon_cs_write_reloc(rmesa
->radeon
.cmdbuf
.cs
,
482 rmesa
->tcl
.aos
[i
+1].bo
,
483 RADEON_GEM_DOMAIN_GTT
,
487 voffset
= rmesa
->tcl
.aos
[nr
- 1].offset
+
488 offset
* 4 * rmesa
->tcl
.aos
[nr
- 1].stride
;
489 radeon_cs_write_reloc(rmesa
->radeon
.cmdbuf
.cs
,
490 rmesa
->tcl
.aos
[nr
-1].bo
,
491 RADEON_GEM_DOMAIN_GTT
,
500 /* ================================================================
503 #define RADEON_MAX_CLEARS 256
505 static void radeonClear( GLcontext
*ctx
, GLbitfield mask
)
507 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
508 __DRIdrawablePrivate
*dPriv
= rmesa
->radeon
.dri
.drawable
;
509 drm_radeon_sarea_t
*sarea
= rmesa
->radeon
.sarea
;
512 GLuint color_mask
= 0;
514 GLint cx
, cy
, cw
, ch
;
516 if ( RADEON_DEBUG
& DEBUG_IOCTL
) {
517 fprintf( stderr
, "radeonClear\n");
521 LOCK_HARDWARE( &rmesa
->radeon
);
522 UNLOCK_HARDWARE( &rmesa
->radeon
);
523 if ( dPriv
->numClipRects
== 0 )
529 if ( mask
& BUFFER_BIT_FRONT_LEFT
) {
530 flags
|= RADEON_FRONT
;
531 color_mask
= rmesa
->hw
.msk
.cmd
[MSK_RB3D_PLANEMASK
];
532 mask
&= ~BUFFER_BIT_FRONT_LEFT
;
535 if ( mask
& BUFFER_BIT_BACK_LEFT
) {
536 flags
|= RADEON_BACK
;
537 color_mask
= rmesa
->hw
.msk
.cmd
[MSK_RB3D_PLANEMASK
];
538 mask
&= ~BUFFER_BIT_BACK_LEFT
;
541 if ( mask
& BUFFER_BIT_DEPTH
) {
542 flags
|= RADEON_DEPTH
;
543 mask
&= ~BUFFER_BIT_DEPTH
;
546 if ( (mask
& BUFFER_BIT_STENCIL
) && rmesa
->radeon
.state
.stencil
.hwBuffer
) {
547 flags
|= RADEON_STENCIL
;
548 mask
&= ~BUFFER_BIT_STENCIL
;
552 if (RADEON_DEBUG
& DEBUG_FALLBACKS
)
553 fprintf(stderr
, "%s: swrast clear, mask: %x\n", __FUNCTION__
, mask
);
554 _swrast_Clear( ctx
, mask
);
560 if (rmesa
->using_hyperz
) {
561 flags
|= RADEON_USE_COMP_ZBUF
;
562 /* if (rmesa->radeon.radeonScreen->chipset & RADEON_CHIPSET_TCL)
563 flags |= RADEON_USE_HIERZ; */
564 if (!(rmesa
->radeon
.state
.stencil
.hwBuffer
) ||
565 ((flags
& RADEON_DEPTH
) && (flags
& RADEON_STENCIL
) &&
566 ((rmesa
->radeon
.state
.stencil
.clear
& RADEON_STENCIL_WRITE_MASK
) == RADEON_STENCIL_WRITE_MASK
))) {
567 flags
|= RADEON_CLEAR_FASTZ
;
571 LOCK_HARDWARE( &rmesa
->radeon
);
573 /* compute region after locking: */
574 cx
= ctx
->DrawBuffer
->_Xmin
;
575 cy
= ctx
->DrawBuffer
->_Ymin
;
576 cw
= ctx
->DrawBuffer
->_Xmax
- cx
;
577 ch
= ctx
->DrawBuffer
->_Ymax
- cy
;
579 /* Flip top to bottom */
581 cy
= dPriv
->y
+ dPriv
->h
- cy
- ch
;
583 /* Throttle the number of clear ioctls we do.
587 drm_radeon_getparam_t gp
;
589 gp
.param
= RADEON_PARAM_LAST_CLEAR
;
590 gp
.value
= (int *)&clear
;
591 ret
= drmCommandWriteRead( rmesa
->radeon
.dri
.fd
,
592 DRM_RADEON_GETPARAM
, &gp
, sizeof(gp
) );
595 fprintf( stderr
, "%s: drm_radeon_getparam_t: %d\n", __FUNCTION__
, ret
);
599 if ( sarea
->last_clear
- clear
<= RADEON_MAX_CLEARS
) {
603 if ( rmesa
->radeon
.do_usleeps
) {
604 UNLOCK_HARDWARE( &rmesa
->radeon
);
606 LOCK_HARDWARE( &rmesa
->radeon
);
610 /* Send current state to the hardware */
611 rcommonFlushCmdBufLocked( &rmesa
->radeon
, __FUNCTION__
);
613 for ( i
= 0 ; i
< dPriv
->numClipRects
; ) {
614 GLint nr
= MIN2( i
+ RADEON_NR_SAREA_CLIPRECTS
, dPriv
->numClipRects
);
615 drm_clip_rect_t
*box
= dPriv
->pClipRects
;
616 drm_clip_rect_t
*b
= rmesa
->radeon
.sarea
->boxes
;
617 drm_radeon_clear_t clear
;
618 drm_radeon_clear_rect_t depth_boxes
[RADEON_NR_SAREA_CLIPRECTS
];
621 if (cw
!= dPriv
->w
|| ch
!= dPriv
->h
) {
622 /* clear subregion */
623 for ( ; i
< nr
; i
++ ) {
626 GLint w
= box
[i
].x2
- x
;
627 GLint h
= box
[i
].y2
- y
;
629 if ( x
< cx
) w
-= cx
- x
, x
= cx
;
630 if ( y
< cy
) h
-= cy
- y
, y
= cy
;
631 if ( x
+ w
> cx
+ cw
) w
= cx
+ cw
- x
;
632 if ( y
+ h
> cy
+ ch
) h
= cy
+ ch
- y
;
633 if ( w
<= 0 ) continue;
634 if ( h
<= 0 ) continue;
644 /* clear whole buffer */
645 for ( ; i
< nr
; i
++ ) {
651 rmesa
->radeon
.sarea
->nbox
= n
;
654 clear
.clear_color
= rmesa
->radeon
.state
.color
.clear
;
655 clear
.clear_depth
= rmesa
->radeon
.state
.depth
.clear
;
656 clear
.color_mask
= rmesa
->hw
.msk
.cmd
[MSK_RB3D_PLANEMASK
];
657 clear
.depth_mask
= rmesa
->radeon
.state
.stencil
.clear
;
658 clear
.depth_boxes
= depth_boxes
;
661 b
= rmesa
->radeon
.sarea
->boxes
;
662 for ( ; n
>= 0 ; n
-- ) {
663 depth_boxes
[n
].f
[CLEAR_X1
] = (float)b
[n
].x1
;
664 depth_boxes
[n
].f
[CLEAR_Y1
] = (float)b
[n
].y1
;
665 depth_boxes
[n
].f
[CLEAR_X2
] = (float)b
[n
].x2
;
666 depth_boxes
[n
].f
[CLEAR_Y2
] = (float)b
[n
].y2
;
667 depth_boxes
[n
].f
[CLEAR_DEPTH
] =
668 (float)rmesa
->radeon
.state
.depth
.clear
;
671 ret
= drmCommandWrite( rmesa
->radeon
.dri
.fd
, DRM_RADEON_CLEAR
,
672 &clear
, sizeof(drm_radeon_clear_t
));
675 UNLOCK_HARDWARE( &rmesa
->radeon
);
676 fprintf( stderr
, "DRM_RADEON_CLEAR: return = %d\n", ret
);
681 UNLOCK_HARDWARE( &rmesa
->radeon
);
682 rmesa
->hw
.all_dirty
= GL_TRUE
;
685 void radeonFlush( GLcontext
*ctx
)
687 r100ContextPtr rmesa
= R100_CONTEXT( ctx
);
689 if (RADEON_DEBUG
& DEBUG_IOCTL
)
690 fprintf(stderr
, "%s\n", __FUNCTION__
);
692 if (rmesa
->radeon
.dma
.flush
)
693 rmesa
->radeon
.dma
.flush( ctx
);
695 radeonEmitState( rmesa
);
697 if (rmesa
->radeon
.cmdbuf
.cs
->cdw
)
698 rcommonFlushCmdBuf( &rmesa
->radeon
, __FUNCTION__
);
701 /* Make sure all commands have been sent to the hardware and have
702 * completed processing.
704 void radeonFinish( GLcontext
*ctx
)
707 radeon_common_finish(ctx
);
711 void radeonInitIoctlFuncs( GLcontext
*ctx
)
713 ctx
->Driver
.Clear
= radeonClear
;
714 ctx
->Driver
.Finish
= radeonFinish
;
715 ctx
->Driver
.Flush
= radeonFlush
;