1 /* r128_state.c -- State support for r128 -*- linux-c -*-
2 * Created: Thu Jan 27 02:53:43 2000 by gareth@valinux.com
4 * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
14 * The above copyright notice and this permission notice (including the next
15 * paragraph) shall be included in all copies or substantial portions of the
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21 * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
22 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
23 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
24 * DEALINGS IN THE SOFTWARE.
27 * Gareth Hughes <gareth@valinux.com>
37 /* ================================================================
38 * CCE hardware state programming functions
41 static void r128_emit_clip_rects( drm_r128_private_t
*dev_priv
,
42 drm_clip_rect_t
*boxes
, int count
)
44 u32 aux_sc_cntl
= 0x00000000;
46 DRM_DEBUG( " %s\n", __FUNCTION__
);
51 OUT_RING( CCE_PACKET0( R128_AUX1_SC_LEFT
, 3 ) );
52 OUT_RING( boxes
[0].x1
);
53 OUT_RING( boxes
[0].x2
- 1 );
54 OUT_RING( boxes
[0].y1
);
55 OUT_RING( boxes
[0].y2
- 1 );
57 aux_sc_cntl
|= (R128_AUX1_SC_EN
| R128_AUX1_SC_MODE_OR
);
60 OUT_RING( CCE_PACKET0( R128_AUX2_SC_LEFT
, 3 ) );
61 OUT_RING( boxes
[1].x1
);
62 OUT_RING( boxes
[1].x2
- 1 );
63 OUT_RING( boxes
[1].y1
);
64 OUT_RING( boxes
[1].y2
- 1 );
66 aux_sc_cntl
|= (R128_AUX2_SC_EN
| R128_AUX2_SC_MODE_OR
);
69 OUT_RING( CCE_PACKET0( R128_AUX3_SC_LEFT
, 3 ) );
70 OUT_RING( boxes
[2].x1
);
71 OUT_RING( boxes
[2].x2
- 1 );
72 OUT_RING( boxes
[2].y1
);
73 OUT_RING( boxes
[2].y2
- 1 );
75 aux_sc_cntl
|= (R128_AUX3_SC_EN
| R128_AUX3_SC_MODE_OR
);
78 OUT_RING( CCE_PACKET0( R128_AUX_SC_CNTL
, 0 ) );
79 OUT_RING( aux_sc_cntl
);
84 static __inline__
void r128_emit_core( drm_r128_private_t
*dev_priv
)
86 drm_r128_sarea_t
*sarea_priv
= dev_priv
->sarea_priv
;
87 drm_r128_context_regs_t
*ctx
= &sarea_priv
->context_state
;
89 DRM_DEBUG( " %s\n", __FUNCTION__
);
93 OUT_RING( CCE_PACKET0( R128_SCALE_3D_CNTL
, 0 ) );
94 OUT_RING( ctx
->scale_3d_cntl
);
99 static __inline__
void r128_emit_context( drm_r128_private_t
*dev_priv
)
101 drm_r128_sarea_t
*sarea_priv
= dev_priv
->sarea_priv
;
102 drm_r128_context_regs_t
*ctx
= &sarea_priv
->context_state
;
104 DRM_DEBUG( " %s\n", __FUNCTION__
);
108 OUT_RING( CCE_PACKET0( R128_DST_PITCH_OFFSET_C
, 11 ) );
109 OUT_RING( ctx
->dst_pitch_offset_c
);
110 OUT_RING( ctx
->dp_gui_master_cntl_c
);
111 OUT_RING( ctx
->sc_top_left_c
);
112 OUT_RING( ctx
->sc_bottom_right_c
);
113 OUT_RING( ctx
->z_offset_c
);
114 OUT_RING( ctx
->z_pitch_c
);
115 OUT_RING( ctx
->z_sten_cntl_c
);
116 OUT_RING( ctx
->tex_cntl_c
);
117 OUT_RING( ctx
->misc_3d_state_cntl_reg
);
118 OUT_RING( ctx
->texture_clr_cmp_clr_c
);
119 OUT_RING( ctx
->texture_clr_cmp_msk_c
);
120 OUT_RING( ctx
->fog_color_c
);
125 static __inline__
void r128_emit_setup( drm_r128_private_t
*dev_priv
)
127 drm_r128_sarea_t
*sarea_priv
= dev_priv
->sarea_priv
;
128 drm_r128_context_regs_t
*ctx
= &sarea_priv
->context_state
;
130 DRM_DEBUG( " %s\n", __FUNCTION__
);
134 OUT_RING( CCE_PACKET1( R128_SETUP_CNTL
, R128_PM4_VC_FPU_SETUP
) );
135 OUT_RING( ctx
->setup_cntl
);
136 OUT_RING( ctx
->pm4_vc_fpu_setup
);
141 static __inline__
void r128_emit_masks( drm_r128_private_t
*dev_priv
)
143 drm_r128_sarea_t
*sarea_priv
= dev_priv
->sarea_priv
;
144 drm_r128_context_regs_t
*ctx
= &sarea_priv
->context_state
;
146 DRM_DEBUG( " %s\n", __FUNCTION__
);
150 OUT_RING( CCE_PACKET0( R128_DP_WRITE_MASK
, 0 ) );
151 OUT_RING( ctx
->dp_write_mask
);
153 OUT_RING( CCE_PACKET0( R128_STEN_REF_MASK_C
, 1 ) );
154 OUT_RING( ctx
->sten_ref_mask_c
);
155 OUT_RING( ctx
->plane_3d_mask_c
);
160 static __inline__
void r128_emit_window( drm_r128_private_t
*dev_priv
)
162 drm_r128_sarea_t
*sarea_priv
= dev_priv
->sarea_priv
;
163 drm_r128_context_regs_t
*ctx
= &sarea_priv
->context_state
;
165 DRM_DEBUG( " %s\n", __FUNCTION__
);
169 OUT_RING( CCE_PACKET0( R128_WINDOW_XY_OFFSET
, 0 ) );
170 OUT_RING( ctx
->window_xy_offset
);
175 static __inline__
void r128_emit_tex0( drm_r128_private_t
*dev_priv
)
177 drm_r128_sarea_t
*sarea_priv
= dev_priv
->sarea_priv
;
178 drm_r128_context_regs_t
*ctx
= &sarea_priv
->context_state
;
179 drm_r128_texture_regs_t
*tex
= &sarea_priv
->tex_state
[0];
182 DRM_DEBUG( " %s\n", __FUNCTION__
);
184 BEGIN_RING( 7 + R128_MAX_TEXTURE_LEVELS
);
186 OUT_RING( CCE_PACKET0( R128_PRIM_TEX_CNTL_C
,
187 2 + R128_MAX_TEXTURE_LEVELS
) );
188 OUT_RING( tex
->tex_cntl
);
189 OUT_RING( tex
->tex_combine_cntl
);
190 OUT_RING( ctx
->tex_size_pitch_c
);
191 for ( i
= 0 ; i
< R128_MAX_TEXTURE_LEVELS
; i
++ ) {
192 OUT_RING( tex
->tex_offset
[i
] );
195 OUT_RING( CCE_PACKET0( R128_CONSTANT_COLOR_C
, 1 ) );
196 OUT_RING( ctx
->constant_color_c
);
197 OUT_RING( tex
->tex_border_color
);
202 static __inline__
void r128_emit_tex1( drm_r128_private_t
*dev_priv
)
204 drm_r128_sarea_t
*sarea_priv
= dev_priv
->sarea_priv
;
205 drm_r128_texture_regs_t
*tex
= &sarea_priv
->tex_state
[1];
208 DRM_DEBUG( " %s\n", __FUNCTION__
);
210 BEGIN_RING( 5 + R128_MAX_TEXTURE_LEVELS
);
212 OUT_RING( CCE_PACKET0( R128_SEC_TEX_CNTL_C
,
213 1 + R128_MAX_TEXTURE_LEVELS
) );
214 OUT_RING( tex
->tex_cntl
);
215 OUT_RING( tex
->tex_combine_cntl
);
216 for ( i
= 0 ; i
< R128_MAX_TEXTURE_LEVELS
; i
++ ) {
217 OUT_RING( tex
->tex_offset
[i
] );
220 OUT_RING( CCE_PACKET0( R128_SEC_TEXTURE_BORDER_COLOR_C
, 0 ) );
221 OUT_RING( tex
->tex_border_color
);
226 static __inline__
void r128_emit_state( drm_r128_private_t
*dev_priv
)
228 drm_r128_sarea_t
*sarea_priv
= dev_priv
->sarea_priv
;
229 unsigned int dirty
= sarea_priv
->dirty
;
231 DRM_DEBUG( "%s: dirty=0x%08x\n", __FUNCTION__
, dirty
);
233 if ( dirty
& R128_UPLOAD_CORE
) {
234 r128_emit_core( dev_priv
);
235 sarea_priv
->dirty
&= ~R128_UPLOAD_CORE
;
238 if ( dirty
& R128_UPLOAD_CONTEXT
) {
239 r128_emit_context( dev_priv
);
240 sarea_priv
->dirty
&= ~R128_UPLOAD_CONTEXT
;
243 if ( dirty
& R128_UPLOAD_SETUP
) {
244 r128_emit_setup( dev_priv
);
245 sarea_priv
->dirty
&= ~R128_UPLOAD_SETUP
;
248 if ( dirty
& R128_UPLOAD_MASKS
) {
249 r128_emit_masks( dev_priv
);
250 sarea_priv
->dirty
&= ~R128_UPLOAD_MASKS
;
253 if ( dirty
& R128_UPLOAD_WINDOW
) {
254 r128_emit_window( dev_priv
);
255 sarea_priv
->dirty
&= ~R128_UPLOAD_WINDOW
;
258 if ( dirty
& R128_UPLOAD_TEX0
) {
259 r128_emit_tex0( dev_priv
);
260 sarea_priv
->dirty
&= ~R128_UPLOAD_TEX0
;
263 if ( dirty
& R128_UPLOAD_TEX1
) {
264 r128_emit_tex1( dev_priv
);
265 sarea_priv
->dirty
&= ~R128_UPLOAD_TEX1
;
268 /* Turn off the texture cache flushing */
269 sarea_priv
->context_state
.tex_cntl_c
&= ~R128_TEX_CACHE_FLUSH
;
271 sarea_priv
->dirty
&= ~R128_REQUIRE_QUIESCENCE
;
275 #if R128_PERFORMANCE_BOXES
276 /* ================================================================
277 * Performance monitoring functions
280 static void r128_clear_box( drm_r128_private_t
*dev_priv
,
281 int x
, int y
, int w
, int h
,
282 int r
, int g
, int b
)
288 switch ( dev_priv
->fb_bpp
) {
290 fb_bpp
= R128_GMC_DST_16BPP
;
291 color
= (((r
& 0xf8) << 8) |
296 fb_bpp
= R128_GMC_DST_24BPP
;
297 color
= ((r
<< 16) | (g
<< 8) | b
);
300 fb_bpp
= R128_GMC_DST_32BPP
;
301 color
= (((0xff) << 24) | (r
<< 16) | (g
<< 8) | b
);
307 offset
= dev_priv
->back_offset
;
308 pitch
= dev_priv
->back_pitch
>> 3;
312 OUT_RING( CCE_PACKET3( R128_CNTL_PAINT_MULTI
, 4 ) );
313 OUT_RING( R128_GMC_DST_PITCH_OFFSET_CNTL
|
314 R128_GMC_BRUSH_SOLID_COLOR
|
316 R128_GMC_SRC_DATATYPE_COLOR
|
318 R128_GMC_CLR_CMP_CNTL_DIS
|
319 R128_GMC_AUX_CLIP_DIS
);
321 OUT_RING( (pitch
<< 21) | (offset
>> 5) );
324 OUT_RING( (x
<< 16) | y
);
325 OUT_RING( (w
<< 16) | h
);
330 static void r128_cce_performance_boxes( drm_r128_private_t
*dev_priv
)
332 if ( atomic_read( &dev_priv
->idle_count
) == 0 ) {
333 r128_clear_box( dev_priv
, 64, 4, 8, 8, 0, 255, 0 );
335 atomic_set( &dev_priv
->idle_count
, 0 );
342 /* ================================================================
343 * CCE command dispatch functions
346 static void r128_print_dirty( const char *msg
, unsigned int flags
)
348 DRM_INFO( "%s: (0x%x) %s%s%s%s%s%s%s%s%s\n",
351 (flags
& R128_UPLOAD_CORE
) ? "core, " : "",
352 (flags
& R128_UPLOAD_CONTEXT
) ? "context, " : "",
353 (flags
& R128_UPLOAD_SETUP
) ? "setup, " : "",
354 (flags
& R128_UPLOAD_TEX0
) ? "tex0, " : "",
355 (flags
& R128_UPLOAD_TEX1
) ? "tex1, " : "",
356 (flags
& R128_UPLOAD_MASKS
) ? "masks, " : "",
357 (flags
& R128_UPLOAD_WINDOW
) ? "window, " : "",
358 (flags
& R128_UPLOAD_CLIPRECTS
) ? "cliprects, " : "",
359 (flags
& R128_REQUIRE_QUIESCENCE
) ? "quiescence, " : "" );
362 static void r128_cce_dispatch_clear( drm_device_t
*dev
,
363 drm_r128_clear_t
*clear
)
365 drm_r128_private_t
*dev_priv
= dev
->dev_private
;
366 drm_r128_sarea_t
*sarea_priv
= dev_priv
->sarea_priv
;
367 int nbox
= sarea_priv
->nbox
;
368 drm_clip_rect_t
*pbox
= sarea_priv
->boxes
;
369 unsigned int flags
= clear
->flags
;
372 DRM_DEBUG( "%s\n", __FUNCTION__
);
374 if ( dev_priv
->page_flipping
&& dev_priv
->current_page
== 1 ) {
375 unsigned int tmp
= flags
;
377 flags
&= ~(R128_FRONT
| R128_BACK
);
378 if ( tmp
& R128_FRONT
) flags
|= R128_BACK
;
379 if ( tmp
& R128_BACK
) flags
|= R128_FRONT
;
382 for ( i
= 0 ; i
< nbox
; i
++ ) {
385 int w
= pbox
[i
].x2
- x
;
386 int h
= pbox
[i
].y2
- y
;
388 DRM_DEBUG( "dispatch clear %d,%d-%d,%d flags 0x%x\n",
389 pbox
[i
].x1
, pbox
[i
].y1
, pbox
[i
].x2
,
392 if ( flags
& (R128_FRONT
| R128_BACK
) ) {
395 OUT_RING( CCE_PACKET0( R128_DP_WRITE_MASK
, 0 ) );
396 OUT_RING( clear
->color_mask
);
401 if ( flags
& R128_FRONT
) {
404 OUT_RING( CCE_PACKET3( R128_CNTL_PAINT_MULTI
, 4 ) );
405 OUT_RING( R128_GMC_DST_PITCH_OFFSET_CNTL
|
406 R128_GMC_BRUSH_SOLID_COLOR
|
407 (dev_priv
->color_fmt
<< 8) |
408 R128_GMC_SRC_DATATYPE_COLOR
|
410 R128_GMC_CLR_CMP_CNTL_DIS
|
411 R128_GMC_AUX_CLIP_DIS
);
413 OUT_RING( dev_priv
->front_pitch_offset_c
);
414 OUT_RING( clear
->clear_color
);
416 OUT_RING( (x
<< 16) | y
);
417 OUT_RING( (w
<< 16) | h
);
422 if ( flags
& R128_BACK
) {
425 OUT_RING( CCE_PACKET3( R128_CNTL_PAINT_MULTI
, 4 ) );
426 OUT_RING( R128_GMC_DST_PITCH_OFFSET_CNTL
|
427 R128_GMC_BRUSH_SOLID_COLOR
|
428 (dev_priv
->color_fmt
<< 8) |
429 R128_GMC_SRC_DATATYPE_COLOR
|
431 R128_GMC_CLR_CMP_CNTL_DIS
|
432 R128_GMC_AUX_CLIP_DIS
);
434 OUT_RING( dev_priv
->back_pitch_offset_c
);
435 OUT_RING( clear
->clear_color
);
437 OUT_RING( (x
<< 16) | y
);
438 OUT_RING( (w
<< 16) | h
);
443 if ( flags
& R128_DEPTH
) {
446 OUT_RING( CCE_PACKET3( R128_CNTL_PAINT_MULTI
, 4 ) );
447 OUT_RING( R128_GMC_DST_PITCH_OFFSET_CNTL
|
448 R128_GMC_BRUSH_SOLID_COLOR
|
449 (dev_priv
->depth_fmt
<< 8) |
450 R128_GMC_SRC_DATATYPE_COLOR
|
452 R128_GMC_CLR_CMP_CNTL_DIS
|
453 R128_GMC_AUX_CLIP_DIS
|
454 R128_GMC_WR_MSK_DIS
);
456 OUT_RING( dev_priv
->depth_pitch_offset_c
);
457 OUT_RING( clear
->clear_depth
);
459 OUT_RING( (x
<< 16) | y
);
460 OUT_RING( (w
<< 16) | h
);
467 static void r128_cce_dispatch_swap( drm_device_t
*dev
)
469 drm_r128_private_t
*dev_priv
= dev
->dev_private
;
470 drm_r128_sarea_t
*sarea_priv
= dev_priv
->sarea_priv
;
471 int nbox
= sarea_priv
->nbox
;
472 drm_clip_rect_t
*pbox
= sarea_priv
->boxes
;
475 DRM_DEBUG( "%s\n", __FUNCTION__
);
477 #if R128_PERFORMANCE_BOXES
478 /* Do some trivial performance monitoring...
480 r128_cce_performance_boxes( dev_priv
);
483 for ( i
= 0 ; i
< nbox
; i
++ ) {
486 int w
= pbox
[i
].x2
- x
;
487 int h
= pbox
[i
].y2
- y
;
491 OUT_RING( CCE_PACKET3( R128_CNTL_BITBLT_MULTI
, 5 ) );
492 OUT_RING( R128_GMC_SRC_PITCH_OFFSET_CNTL
|
493 R128_GMC_DST_PITCH_OFFSET_CNTL
|
494 R128_GMC_BRUSH_NONE
|
495 (dev_priv
->color_fmt
<< 8) |
496 R128_GMC_SRC_DATATYPE_COLOR
|
498 R128_DP_SRC_SOURCE_MEMORY
|
499 R128_GMC_CLR_CMP_CNTL_DIS
|
500 R128_GMC_AUX_CLIP_DIS
|
501 R128_GMC_WR_MSK_DIS
);
503 OUT_RING( dev_priv
->back_pitch_offset_c
);
504 OUT_RING( dev_priv
->front_pitch_offset_c
);
506 OUT_RING( (x
<< 16) | y
);
507 OUT_RING( (x
<< 16) | y
);
508 OUT_RING( (w
<< 16) | h
);
513 /* Increment the frame counter. The client-side 3D driver must
514 * throttle the framerate by waiting for this value before
515 * performing the swapbuffer ioctl.
517 dev_priv
->sarea_priv
->last_frame
++;
521 OUT_RING( CCE_PACKET0( R128_LAST_FRAME_REG
, 0 ) );
522 OUT_RING( dev_priv
->sarea_priv
->last_frame
);
527 static void r128_cce_dispatch_flip( drm_device_t
*dev
)
529 drm_r128_private_t
*dev_priv
= dev
->dev_private
;
531 DRM_DEBUG( "page=%d\n", dev_priv
->current_page
);
533 #if R128_PERFORMANCE_BOXES
534 /* Do some trivial performance monitoring...
536 r128_cce_performance_boxes( dev_priv
);
541 R128_WAIT_UNTIL_PAGE_FLIPPED();
542 OUT_RING( CCE_PACKET0( R128_CRTC_OFFSET
, 0 ) );
544 if ( dev_priv
->current_page
== 0 ) {
545 OUT_RING( dev_priv
->back_offset
);
546 dev_priv
->current_page
= 1;
548 OUT_RING( dev_priv
->front_offset
);
549 dev_priv
->current_page
= 0;
554 /* Increment the frame counter. The client-side 3D driver must
555 * throttle the framerate by waiting for this value before
556 * performing the swapbuffer ioctl.
558 dev_priv
->sarea_priv
->last_frame
++;
562 OUT_RING( CCE_PACKET0( R128_LAST_FRAME_REG
, 0 ) );
563 OUT_RING( dev_priv
->sarea_priv
->last_frame
);
568 static void r128_cce_dispatch_vertex( drm_device_t
*dev
,
571 drm_r128_private_t
*dev_priv
= dev
->dev_private
;
572 drm_r128_buf_priv_t
*buf_priv
= buf
->dev_private
;
573 drm_r128_sarea_t
*sarea_priv
= dev_priv
->sarea_priv
;
574 int format
= sarea_priv
->vc_format
;
575 int offset
= buf
->bus_address
;
576 int size
= buf
->used
;
577 int prim
= buf_priv
->prim
;
580 DRM_DEBUG( "buf=%d nbox=%d\n", buf
->idx
, sarea_priv
->nbox
);
583 r128_print_dirty( "dispatch_vertex", sarea_priv
->dirty
);
586 buf_priv
->dispatched
= 1;
588 if ( sarea_priv
->dirty
& ~R128_UPLOAD_CLIPRECTS
) {
589 r128_emit_state( dev_priv
);
593 /* Emit the next set of up to three cliprects */
594 if ( i
< sarea_priv
->nbox
) {
595 r128_emit_clip_rects( dev_priv
,
596 &sarea_priv
->boxes
[i
],
597 sarea_priv
->nbox
- i
);
600 /* Emit the vertex buffer rendering commands */
603 OUT_RING( CCE_PACKET3( R128_3D_RNDR_GEN_INDX_PRIM
, 3 ) );
607 OUT_RING( prim
| R128_CCE_VC_CNTL_PRIM_WALK_LIST
|
608 (size
<< R128_CCE_VC_CNTL_NUM_SHIFT
) );
613 } while ( i
< sarea_priv
->nbox
);
616 if ( buf_priv
->discard
) {
617 buf_priv
->age
= dev_priv
->sarea_priv
->last_dispatch
;
619 /* Emit the vertex buffer age */
622 OUT_RING( CCE_PACKET0( R128_LAST_DISPATCH_REG
, 0 ) );
623 OUT_RING( buf_priv
->age
);
629 /* FIXME: Check dispatched field */
630 buf_priv
->dispatched
= 0;
633 dev_priv
->sarea_priv
->last_dispatch
++;
635 sarea_priv
->dirty
&= ~R128_UPLOAD_CLIPRECTS
;
636 sarea_priv
->nbox
= 0;
639 static void r128_cce_dispatch_indirect( drm_device_t
*dev
,
643 drm_r128_private_t
*dev_priv
= dev
->dev_private
;
644 drm_r128_buf_priv_t
*buf_priv
= buf
->dev_private
;
646 DRM_DEBUG( "indirect: buf=%d s=0x%x e=0x%x\n",
647 buf
->idx
, start
, end
);
649 if ( start
!= end
) {
650 int offset
= buf
->bus_address
+ start
;
651 int dwords
= (end
- start
+ 3) / sizeof(u32
);
653 /* Indirect buffer data must be an even number of
654 * dwords, so if we've been given an odd number we must
655 * pad the data with a Type-2 CCE packet.
659 ((char *)dev_priv
->buffers
->handle
660 + buf
->offset
+ start
);
661 data
[dwords
++] = cpu_to_le32( R128_CCE_PACKET2
);
664 buf_priv
->dispatched
= 1;
666 /* Fire off the indirect buffer */
669 OUT_RING( CCE_PACKET0( R128_PM4_IW_INDOFF
, 1 ) );
676 if ( buf_priv
->discard
) {
677 buf_priv
->age
= dev_priv
->sarea_priv
->last_dispatch
;
679 /* Emit the indirect buffer age */
682 OUT_RING( CCE_PACKET0( R128_LAST_DISPATCH_REG
, 0 ) );
683 OUT_RING( buf_priv
->age
);
689 /* FIXME: Check dispatched field */
690 buf_priv
->dispatched
= 0;
693 dev_priv
->sarea_priv
->last_dispatch
++;
696 static void r128_cce_dispatch_indices( drm_device_t
*dev
,
701 drm_r128_private_t
*dev_priv
= dev
->dev_private
;
702 drm_r128_buf_priv_t
*buf_priv
= buf
->dev_private
;
703 drm_r128_sarea_t
*sarea_priv
= dev_priv
->sarea_priv
;
704 int format
= sarea_priv
->vc_format
;
705 int offset
= dev_priv
->buffers
->offset
- dev_priv
->cce_buffers_offset
;
706 int prim
= buf_priv
->prim
;
711 DRM_DEBUG( "indices: s=%d e=%d c=%d\n", start
, end
, count
);
714 r128_print_dirty( "dispatch_indices", sarea_priv
->dirty
);
716 if ( start
!= end
) {
717 buf_priv
->dispatched
= 1;
719 if ( sarea_priv
->dirty
& ~R128_UPLOAD_CLIPRECTS
) {
720 r128_emit_state( dev_priv
);
723 dwords
= (end
- start
+ 3) / sizeof(u32
);
725 data
= (u32
*)((char *)dev_priv
->buffers
->handle
726 + buf
->offset
+ start
);
728 data
[0] = cpu_to_le32( CCE_PACKET3( R128_3D_RNDR_GEN_INDX_PRIM
,
731 data
[1] = cpu_to_le32( offset
);
732 data
[2] = cpu_to_le32( R128_MAX_VB_VERTS
);
733 data
[3] = cpu_to_le32( format
);
734 data
[4] = cpu_to_le32( (prim
| R128_CCE_VC_CNTL_PRIM_WALK_IND
|
738 #ifdef __LITTLE_ENDIAN
739 data
[dwords
-1] &= 0x0000ffff;
741 data
[dwords
-1] &= 0xffff0000;
746 /* Emit the next set of up to three cliprects */
747 if ( i
< sarea_priv
->nbox
) {
748 r128_emit_clip_rects( dev_priv
,
749 &sarea_priv
->boxes
[i
],
750 sarea_priv
->nbox
- i
);
753 r128_cce_dispatch_indirect( dev
, buf
, start
, end
);
756 } while ( i
< sarea_priv
->nbox
);
759 if ( buf_priv
->discard
) {
760 buf_priv
->age
= dev_priv
->sarea_priv
->last_dispatch
;
762 /* Emit the vertex buffer age */
765 OUT_RING( CCE_PACKET0( R128_LAST_DISPATCH_REG
, 0 ) );
766 OUT_RING( buf_priv
->age
);
771 /* FIXME: Check dispatched field */
772 buf_priv
->dispatched
= 0;
775 dev_priv
->sarea_priv
->last_dispatch
++;
777 sarea_priv
->dirty
&= ~R128_UPLOAD_CLIPRECTS
;
778 sarea_priv
->nbox
= 0;
781 static int r128_cce_dispatch_blit( DRMFILE filp
,
783 drm_r128_blit_t
*blit
)
785 drm_r128_private_t
*dev_priv
= dev
->dev_private
;
786 drm_device_dma_t
*dma
= dev
->dma
;
788 drm_r128_buf_priv_t
*buf_priv
;
790 int dword_shift
, dwords
;
794 /* The compiler won't optimize away a division by a variable,
795 * even if the only legal values are powers of two. Thus, we'll
796 * use a shift instead.
798 switch ( blit
->format
) {
799 case R128_DATATYPE_ARGB8888
:
802 case R128_DATATYPE_ARGB1555
:
803 case R128_DATATYPE_RGB565
:
804 case R128_DATATYPE_ARGB4444
:
805 case R128_DATATYPE_YVYU422
:
806 case R128_DATATYPE_VYUY422
:
809 case R128_DATATYPE_CI8
:
810 case R128_DATATYPE_RGB8
:
814 DRM_ERROR( "invalid blit format %d\n", blit
->format
);
815 return DRM_ERR(EINVAL
);
818 /* Flush the pixel cache, and mark the contents as Read Invalid.
819 * This ensures no pixel data gets mixed up with the texture
820 * data from the host data blit, otherwise part of the texture
821 * image may be corrupted.
825 OUT_RING( CCE_PACKET0( R128_PC_GUI_CTLSTAT
, 0 ) );
826 OUT_RING( R128_PC_RI_GUI
| R128_PC_FLUSH_GUI
);
830 /* Dispatch the indirect buffer.
832 buf
= dma
->buflist
[blit
->idx
];
833 buf_priv
= buf
->dev_private
;
835 if ( buf
->filp
!= filp
) {
836 DRM_ERROR( "process %d using buffer owned by %p\n",
837 DRM_CURRENTPID
, buf
->filp
);
838 return DRM_ERR(EINVAL
);
840 if ( buf
->pending
) {
841 DRM_ERROR( "sending pending buffer %d\n", blit
->idx
);
842 return DRM_ERR(EINVAL
);
845 buf_priv
->discard
= 1;
847 dwords
= (blit
->width
* blit
->height
) >> dword_shift
;
849 data
= (u32
*)((char *)dev_priv
->buffers
->handle
+ buf
->offset
);
851 data
[0] = cpu_to_le32( CCE_PACKET3( R128_CNTL_HOSTDATA_BLT
, dwords
+ 6 ) );
852 data
[1] = cpu_to_le32( (R128_GMC_DST_PITCH_OFFSET_CNTL
|
853 R128_GMC_BRUSH_NONE
|
854 (blit
->format
<< 8) |
855 R128_GMC_SRC_DATATYPE_COLOR
|
857 R128_DP_SRC_SOURCE_HOST_DATA
|
858 R128_GMC_CLR_CMP_CNTL_DIS
|
859 R128_GMC_AUX_CLIP_DIS
|
860 R128_GMC_WR_MSK_DIS
) );
862 data
[2] = cpu_to_le32( (blit
->pitch
<< 21) | (blit
->offset
>> 5) );
863 data
[3] = cpu_to_le32( 0xffffffff );
864 data
[4] = cpu_to_le32( 0xffffffff );
865 data
[5] = cpu_to_le32( (blit
->y
<< 16) | blit
->x
);
866 data
[6] = cpu_to_le32( (blit
->height
<< 16) | blit
->width
);
867 data
[7] = cpu_to_le32( dwords
);
869 buf
->used
= (dwords
+ 8) * sizeof(u32
);
871 r128_cce_dispatch_indirect( dev
, buf
, 0, buf
->used
);
873 /* Flush the pixel cache after the blit completes. This ensures
874 * the texture data is written out to memory before rendering
879 OUT_RING( CCE_PACKET0( R128_PC_GUI_CTLSTAT
, 0 ) );
880 OUT_RING( R128_PC_FLUSH_GUI
);
888 /* ================================================================
889 * Tiled depth buffer management
891 * FIXME: These should all set the destination write mask for when we
892 * have hardware stencil support.
895 static int r128_cce_dispatch_write_span( drm_device_t
*dev
,
896 drm_r128_depth_t
*depth
)
898 drm_r128_private_t
*dev_priv
= dev
->dev_private
;
902 int i
, buffer_size
, mask_size
;
907 if ( DRM_COPY_FROM_USER( &x
, depth
->x
, sizeof(x
) ) ) {
908 return DRM_ERR(EFAULT
);
910 if ( DRM_COPY_FROM_USER( &y
, depth
->y
, sizeof(y
) ) ) {
911 return DRM_ERR(EFAULT
);
914 buffer_size
= depth
->n
* sizeof(u32
);
915 buffer
= DRM_MALLOC( buffer_size
);
916 if ( buffer
== NULL
)
917 return DRM_ERR(ENOMEM
);
918 if ( DRM_COPY_FROM_USER( buffer
, depth
->buffer
, buffer_size
) ) {
919 DRM_FREE( buffer
, buffer_size
);
920 return DRM_ERR(EFAULT
);
923 mask_size
= depth
->n
* sizeof(u8
);
925 mask
= DRM_MALLOC( mask_size
);
926 if ( mask
== NULL
) {
927 DRM_FREE( buffer
, buffer_size
);
928 return DRM_ERR(ENOMEM
);
930 if ( DRM_COPY_FROM_USER( mask
, depth
->mask
, mask_size
) ) {
931 DRM_FREE( buffer
, buffer_size
);
932 DRM_FREE( mask
, mask_size
);
933 return DRM_ERR(EFAULT
);
936 for ( i
= 0 ; i
< count
; i
++, x
++ ) {
940 OUT_RING( CCE_PACKET3( R128_CNTL_PAINT_MULTI
, 4 ) );
941 OUT_RING( R128_GMC_DST_PITCH_OFFSET_CNTL
|
942 R128_GMC_BRUSH_SOLID_COLOR
|
943 (dev_priv
->depth_fmt
<< 8) |
944 R128_GMC_SRC_DATATYPE_COLOR
|
946 R128_GMC_CLR_CMP_CNTL_DIS
|
947 R128_GMC_WR_MSK_DIS
);
949 OUT_RING( dev_priv
->depth_pitch_offset_c
);
950 OUT_RING( buffer
[i
] );
952 OUT_RING( (x
<< 16) | y
);
953 OUT_RING( (1 << 16) | 1 );
959 DRM_FREE( mask
, mask_size
);
961 for ( i
= 0 ; i
< count
; i
++, x
++ ) {
964 OUT_RING( CCE_PACKET3( R128_CNTL_PAINT_MULTI
, 4 ) );
965 OUT_RING( R128_GMC_DST_PITCH_OFFSET_CNTL
|
966 R128_GMC_BRUSH_SOLID_COLOR
|
967 (dev_priv
->depth_fmt
<< 8) |
968 R128_GMC_SRC_DATATYPE_COLOR
|
970 R128_GMC_CLR_CMP_CNTL_DIS
|
971 R128_GMC_WR_MSK_DIS
);
973 OUT_RING( dev_priv
->depth_pitch_offset_c
);
974 OUT_RING( buffer
[i
] );
976 OUT_RING( (x
<< 16) | y
);
977 OUT_RING( (1 << 16) | 1 );
983 DRM_FREE( buffer
, buffer_size
);
988 static int r128_cce_dispatch_write_pixels( drm_device_t
*dev
,
989 drm_r128_depth_t
*depth
)
991 drm_r128_private_t
*dev_priv
= dev
->dev_private
;
995 int i
, xbuf_size
, ybuf_size
, buffer_size
, mask_size
;
1001 xbuf_size
= count
* sizeof(*x
);
1002 ybuf_size
= count
* sizeof(*y
);
1003 x
= DRM_MALLOC( xbuf_size
);
1005 return DRM_ERR(ENOMEM
);
1007 y
= DRM_MALLOC( ybuf_size
);
1009 DRM_FREE( x
, xbuf_size
);
1010 return DRM_ERR(ENOMEM
);
1012 if ( DRM_COPY_FROM_USER( x
, depth
->x
, xbuf_size
) ) {
1013 DRM_FREE( x
, xbuf_size
);
1014 DRM_FREE( y
, ybuf_size
);
1015 return DRM_ERR(EFAULT
);
1017 if ( DRM_COPY_FROM_USER( y
, depth
->y
, xbuf_size
) ) {
1018 DRM_FREE( x
, xbuf_size
);
1019 DRM_FREE( y
, ybuf_size
);
1020 return DRM_ERR(EFAULT
);
1023 buffer_size
= depth
->n
* sizeof(u32
);
1024 buffer
= DRM_MALLOC( buffer_size
);
1025 if ( buffer
== NULL
) {
1026 DRM_FREE( x
, xbuf_size
);
1027 DRM_FREE( y
, ybuf_size
);
1028 return DRM_ERR(ENOMEM
);
1030 if ( DRM_COPY_FROM_USER( buffer
, depth
->buffer
, buffer_size
) ) {
1031 DRM_FREE( x
, xbuf_size
);
1032 DRM_FREE( y
, ybuf_size
);
1033 DRM_FREE( buffer
, buffer_size
);
1034 return DRM_ERR(EFAULT
);
1037 if ( depth
->mask
) {
1038 mask_size
= depth
->n
* sizeof(u8
);
1039 mask
= DRM_MALLOC( mask_size
);
1040 if ( mask
== NULL
) {
1041 DRM_FREE( x
, xbuf_size
);
1042 DRM_FREE( y
, ybuf_size
);
1043 DRM_FREE( buffer
, buffer_size
);
1044 return DRM_ERR(ENOMEM
);
1046 if ( DRM_COPY_FROM_USER( mask
, depth
->mask
, mask_size
) ) {
1047 DRM_FREE( x
, xbuf_size
);
1048 DRM_FREE( y
, ybuf_size
);
1049 DRM_FREE( buffer
, buffer_size
);
1050 DRM_FREE( mask
, mask_size
);
1051 return DRM_ERR(EFAULT
);
1054 for ( i
= 0 ; i
< count
; i
++ ) {
1058 OUT_RING( CCE_PACKET3( R128_CNTL_PAINT_MULTI
, 4 ) );
1059 OUT_RING( R128_GMC_DST_PITCH_OFFSET_CNTL
|
1060 R128_GMC_BRUSH_SOLID_COLOR
|
1061 (dev_priv
->depth_fmt
<< 8) |
1062 R128_GMC_SRC_DATATYPE_COLOR
|
1064 R128_GMC_CLR_CMP_CNTL_DIS
|
1065 R128_GMC_WR_MSK_DIS
);
1067 OUT_RING( dev_priv
->depth_pitch_offset_c
);
1068 OUT_RING( buffer
[i
] );
1070 OUT_RING( (x
[i
] << 16) | y
[i
] );
1071 OUT_RING( (1 << 16) | 1 );
1077 DRM_FREE( mask
, mask_size
);
1079 for ( i
= 0 ; i
< count
; i
++ ) {
1082 OUT_RING( CCE_PACKET3( R128_CNTL_PAINT_MULTI
, 4 ) );
1083 OUT_RING( R128_GMC_DST_PITCH_OFFSET_CNTL
|
1084 R128_GMC_BRUSH_SOLID_COLOR
|
1085 (dev_priv
->depth_fmt
<< 8) |
1086 R128_GMC_SRC_DATATYPE_COLOR
|
1088 R128_GMC_CLR_CMP_CNTL_DIS
|
1089 R128_GMC_WR_MSK_DIS
);
1091 OUT_RING( dev_priv
->depth_pitch_offset_c
);
1092 OUT_RING( buffer
[i
] );
1094 OUT_RING( (x
[i
] << 16) | y
[i
] );
1095 OUT_RING( (1 << 16) | 1 );
1101 DRM_FREE( x
, xbuf_size
);
1102 DRM_FREE( y
, ybuf_size
);
1103 DRM_FREE( buffer
, buffer_size
);
1108 static int r128_cce_dispatch_read_span( drm_device_t
*dev
,
1109 drm_r128_depth_t
*depth
)
1111 drm_r128_private_t
*dev_priv
= dev
->dev_private
;
1117 if ( DRM_COPY_FROM_USER( &x
, depth
->x
, sizeof(x
) ) ) {
1118 return DRM_ERR(EFAULT
);
1120 if ( DRM_COPY_FROM_USER( &y
, depth
->y
, sizeof(y
) ) ) {
1121 return DRM_ERR(EFAULT
);
1126 OUT_RING( CCE_PACKET3( R128_CNTL_BITBLT_MULTI
, 5 ) );
1127 OUT_RING( R128_GMC_SRC_PITCH_OFFSET_CNTL
|
1128 R128_GMC_DST_PITCH_OFFSET_CNTL
|
1129 R128_GMC_BRUSH_NONE
|
1130 (dev_priv
->depth_fmt
<< 8) |
1131 R128_GMC_SRC_DATATYPE_COLOR
|
1133 R128_DP_SRC_SOURCE_MEMORY
|
1134 R128_GMC_CLR_CMP_CNTL_DIS
|
1135 R128_GMC_WR_MSK_DIS
);
1137 OUT_RING( dev_priv
->depth_pitch_offset_c
);
1138 OUT_RING( dev_priv
->span_pitch_offset_c
);
1140 OUT_RING( (x
<< 16) | y
);
1141 OUT_RING( (0 << 16) | 0 );
1142 OUT_RING( (count
<< 16) | 1 );
1149 static int r128_cce_dispatch_read_pixels( drm_device_t
*dev
,
1150 drm_r128_depth_t
*depth
)
1152 drm_r128_private_t
*dev_priv
= dev
->dev_private
;
1154 int i
, xbuf_size
, ybuf_size
;
1156 DRM_DEBUG( "%s\n", __FUNCTION__
);
1159 if ( count
> dev_priv
->depth_pitch
) {
1160 count
= dev_priv
->depth_pitch
;
1163 xbuf_size
= count
* sizeof(*x
);
1164 ybuf_size
= count
* sizeof(*y
);
1165 x
= DRM_MALLOC( xbuf_size
);
1167 return DRM_ERR(ENOMEM
);
1169 y
= DRM_MALLOC( ybuf_size
);
1171 DRM_FREE( x
, xbuf_size
);
1172 return DRM_ERR(ENOMEM
);
1174 if ( DRM_COPY_FROM_USER( x
, depth
->x
, xbuf_size
) ) {
1175 DRM_FREE( x
, xbuf_size
);
1176 DRM_FREE( y
, ybuf_size
);
1177 return DRM_ERR(EFAULT
);
1179 if ( DRM_COPY_FROM_USER( y
, depth
->y
, ybuf_size
) ) {
1180 DRM_FREE( x
, xbuf_size
);
1181 DRM_FREE( y
, ybuf_size
);
1182 return DRM_ERR(EFAULT
);
1185 for ( i
= 0 ; i
< count
; i
++ ) {
1188 OUT_RING( CCE_PACKET3( R128_CNTL_BITBLT_MULTI
, 5 ) );
1189 OUT_RING( R128_GMC_SRC_PITCH_OFFSET_CNTL
|
1190 R128_GMC_DST_PITCH_OFFSET_CNTL
|
1191 R128_GMC_BRUSH_NONE
|
1192 (dev_priv
->depth_fmt
<< 8) |
1193 R128_GMC_SRC_DATATYPE_COLOR
|
1195 R128_DP_SRC_SOURCE_MEMORY
|
1196 R128_GMC_CLR_CMP_CNTL_DIS
|
1197 R128_GMC_WR_MSK_DIS
);
1199 OUT_RING( dev_priv
->depth_pitch_offset_c
);
1200 OUT_RING( dev_priv
->span_pitch_offset_c
);
1202 OUT_RING( (x
[i
] << 16) | y
[i
] );
1203 OUT_RING( (i
<< 16) | 0 );
1204 OUT_RING( (1 << 16) | 1 );
1209 DRM_FREE( x
, xbuf_size
);
1210 DRM_FREE( y
, ybuf_size
);
1216 /* ================================================================
1220 static void r128_cce_dispatch_stipple( drm_device_t
*dev
, u32
*stipple
)
1222 drm_r128_private_t
*dev_priv
= dev
->dev_private
;
1225 DRM_DEBUG( "%s\n", __FUNCTION__
);
1229 OUT_RING( CCE_PACKET0( R128_BRUSH_DATA0
, 31 ) );
1230 for ( i
= 0 ; i
< 32 ; i
++ ) {
1231 OUT_RING( stipple
[i
] );
1238 /* ================================================================
1242 int r128_cce_clear( DRM_IOCTL_ARGS
)
1245 drm_r128_private_t
*dev_priv
= dev
->dev_private
;
1246 drm_r128_sarea_t
*sarea_priv
= dev_priv
->sarea_priv
;
1247 drm_r128_clear_t clear
;
1250 LOCK_TEST_WITH_RETURN( dev
, filp
);
1252 DRM_COPY_FROM_USER_IOCTL( clear
, (drm_r128_clear_t
*) data
,
1255 RING_SPACE_TEST_WITH_RETURN( dev_priv
);
1257 if ( sarea_priv
->nbox
> R128_NR_SAREA_CLIPRECTS
)
1258 sarea_priv
->nbox
= R128_NR_SAREA_CLIPRECTS
;
1260 r128_cce_dispatch_clear( dev
, &clear
);
1262 /* Make sure we restore the 3D state next time.
1264 dev_priv
->sarea_priv
->dirty
|= R128_UPLOAD_CONTEXT
| R128_UPLOAD_MASKS
;
1269 int r128_cce_swap( DRM_IOCTL_ARGS
)
1272 drm_r128_private_t
*dev_priv
= dev
->dev_private
;
1273 drm_r128_sarea_t
*sarea_priv
= dev_priv
->sarea_priv
;
1274 DRM_DEBUG( "%s\n", __FUNCTION__
);
1276 LOCK_TEST_WITH_RETURN( dev
, filp
);
1278 RING_SPACE_TEST_WITH_RETURN( dev_priv
);
1280 if ( sarea_priv
->nbox
> R128_NR_SAREA_CLIPRECTS
)
1281 sarea_priv
->nbox
= R128_NR_SAREA_CLIPRECTS
;
1283 if ( !dev_priv
->page_flipping
) {
1284 r128_cce_dispatch_swap( dev
);
1285 dev_priv
->sarea_priv
->dirty
|= (R128_UPLOAD_CONTEXT
|
1288 r128_cce_dispatch_flip( dev
);
1294 int r128_cce_vertex( DRM_IOCTL_ARGS
)
1297 drm_r128_private_t
*dev_priv
= dev
->dev_private
;
1298 drm_device_dma_t
*dma
= dev
->dma
;
1300 drm_r128_buf_priv_t
*buf_priv
;
1301 drm_r128_vertex_t vertex
;
1303 LOCK_TEST_WITH_RETURN( dev
, filp
);
1306 DRM_ERROR( "%s called with no initialization\n", __FUNCTION__
);
1307 return DRM_ERR(EINVAL
);
1310 DRM_COPY_FROM_USER_IOCTL( vertex
, (drm_r128_vertex_t
*) data
,
1313 DRM_DEBUG( "pid=%d index=%d count=%d discard=%d\n",
1315 vertex
.idx
, vertex
.count
, vertex
.discard
);
1317 if ( vertex
.idx
< 0 || vertex
.idx
>= dma
->buf_count
) {
1318 DRM_ERROR( "buffer index %d (of %d max)\n",
1319 vertex
.idx
, dma
->buf_count
- 1 );
1320 return DRM_ERR(EINVAL
);
1322 if ( vertex
.prim
< 0 ||
1323 vertex
.prim
> R128_CCE_VC_CNTL_PRIM_TYPE_TRI_TYPE2
) {
1324 DRM_ERROR( "buffer prim %d\n", vertex
.prim
);
1325 return DRM_ERR(EINVAL
);
1328 RING_SPACE_TEST_WITH_RETURN( dev_priv
);
1329 VB_AGE_TEST_WITH_RETURN( dev_priv
);
1331 buf
= dma
->buflist
[vertex
.idx
];
1332 buf_priv
= buf
->dev_private
;
1334 if ( buf
->filp
!= filp
) {
1335 DRM_ERROR( "process %d using buffer owned by %p\n",
1336 DRM_CURRENTPID
, buf
->filp
);
1337 return DRM_ERR(EINVAL
);
1339 if ( buf
->pending
) {
1340 DRM_ERROR( "sending pending buffer %d\n", vertex
.idx
);
1341 return DRM_ERR(EINVAL
);
1344 buf
->used
= vertex
.count
;
1345 buf_priv
->prim
= vertex
.prim
;
1346 buf_priv
->discard
= vertex
.discard
;
1348 r128_cce_dispatch_vertex( dev
, buf
);
1353 int r128_cce_indices( DRM_IOCTL_ARGS
)
1356 drm_r128_private_t
*dev_priv
= dev
->dev_private
;
1357 drm_device_dma_t
*dma
= dev
->dma
;
1359 drm_r128_buf_priv_t
*buf_priv
;
1360 drm_r128_indices_t elts
;
1363 LOCK_TEST_WITH_RETURN( dev
, filp
);
1366 DRM_ERROR( "%s called with no initialization\n", __FUNCTION__
);
1367 return DRM_ERR(EINVAL
);
1370 DRM_COPY_FROM_USER_IOCTL( elts
, (drm_r128_indices_t
*) data
,
1373 DRM_DEBUG( "pid=%d buf=%d s=%d e=%d d=%d\n", DRM_CURRENTPID
,
1374 elts
.idx
, elts
.start
, elts
.end
, elts
.discard
);
1376 if ( elts
.idx
< 0 || elts
.idx
>= dma
->buf_count
) {
1377 DRM_ERROR( "buffer index %d (of %d max)\n",
1378 elts
.idx
, dma
->buf_count
- 1 );
1379 return DRM_ERR(EINVAL
);
1381 if ( elts
.prim
< 0 ||
1382 elts
.prim
> R128_CCE_VC_CNTL_PRIM_TYPE_TRI_TYPE2
) {
1383 DRM_ERROR( "buffer prim %d\n", elts
.prim
);
1384 return DRM_ERR(EINVAL
);
1387 RING_SPACE_TEST_WITH_RETURN( dev_priv
);
1388 VB_AGE_TEST_WITH_RETURN( dev_priv
);
1390 buf
= dma
->buflist
[elts
.idx
];
1391 buf_priv
= buf
->dev_private
;
1393 if ( buf
->filp
!= filp
) {
1394 DRM_ERROR( "process %d using buffer owned by %p\n",
1395 DRM_CURRENTPID
, buf
->filp
);
1396 return DRM_ERR(EINVAL
);
1398 if ( buf
->pending
) {
1399 DRM_ERROR( "sending pending buffer %d\n", elts
.idx
);
1400 return DRM_ERR(EINVAL
);
1403 count
= (elts
.end
- elts
.start
) / sizeof(u16
);
1404 elts
.start
-= R128_INDEX_PRIM_OFFSET
;
1406 if ( elts
.start
& 0x7 ) {
1407 DRM_ERROR( "misaligned buffer 0x%x\n", elts
.start
);
1408 return DRM_ERR(EINVAL
);
1410 if ( elts
.start
< buf
->used
) {
1411 DRM_ERROR( "no header 0x%x - 0x%x\n", elts
.start
, buf
->used
);
1412 return DRM_ERR(EINVAL
);
1415 buf
->used
= elts
.end
;
1416 buf_priv
->prim
= elts
.prim
;
1417 buf_priv
->discard
= elts
.discard
;
1419 r128_cce_dispatch_indices( dev
, buf
, elts
.start
, elts
.end
, count
);
1424 int r128_cce_blit( DRM_IOCTL_ARGS
)
1427 drm_device_dma_t
*dma
= dev
->dma
;
1428 drm_r128_private_t
*dev_priv
= dev
->dev_private
;
1429 drm_r128_blit_t blit
;
1431 LOCK_TEST_WITH_RETURN( dev
, filp
);
1433 DRM_COPY_FROM_USER_IOCTL( blit
, (drm_r128_blit_t
*) data
,
1436 DRM_DEBUG( "pid=%d index=%d\n", DRM_CURRENTPID
, blit
.idx
);
1438 if ( blit
.idx
< 0 || blit
.idx
>= dma
->buf_count
) {
1439 DRM_ERROR( "buffer index %d (of %d max)\n",
1440 blit
.idx
, dma
->buf_count
- 1 );
1441 return DRM_ERR(EINVAL
);
1444 RING_SPACE_TEST_WITH_RETURN( dev_priv
);
1445 VB_AGE_TEST_WITH_RETURN( dev_priv
);
1447 return r128_cce_dispatch_blit( filp
, dev
, &blit
);
1450 int r128_cce_depth( DRM_IOCTL_ARGS
)
1453 drm_r128_private_t
*dev_priv
= dev
->dev_private
;
1454 drm_r128_depth_t depth
;
1456 LOCK_TEST_WITH_RETURN( dev
, filp
);
1458 DRM_COPY_FROM_USER_IOCTL( depth
, (drm_r128_depth_t
*) data
,
1461 RING_SPACE_TEST_WITH_RETURN( dev_priv
);
1463 switch ( depth
.func
) {
1464 case R128_WRITE_SPAN
:
1465 return r128_cce_dispatch_write_span( dev
, &depth
);
1466 case R128_WRITE_PIXELS
:
1467 return r128_cce_dispatch_write_pixels( dev
, &depth
);
1468 case R128_READ_SPAN
:
1469 return r128_cce_dispatch_read_span( dev
, &depth
);
1470 case R128_READ_PIXELS
:
1471 return r128_cce_dispatch_read_pixels( dev
, &depth
);
1474 return DRM_ERR(EINVAL
);
1477 int r128_cce_stipple( DRM_IOCTL_ARGS
)
1480 drm_r128_private_t
*dev_priv
= dev
->dev_private
;
1481 drm_r128_stipple_t stipple
;
1484 LOCK_TEST_WITH_RETURN( dev
, filp
);
1486 DRM_COPY_FROM_USER_IOCTL( stipple
, (drm_r128_stipple_t
*) data
,
1489 if ( DRM_COPY_FROM_USER( &mask
, stipple
.mask
,
1490 32 * sizeof(u32
) ) )
1491 return DRM_ERR( EFAULT
);
1493 RING_SPACE_TEST_WITH_RETURN( dev_priv
);
1495 r128_cce_dispatch_stipple( dev
, mask
);
1500 int r128_cce_indirect( DRM_IOCTL_ARGS
)
1503 drm_r128_private_t
*dev_priv
= dev
->dev_private
;
1504 drm_device_dma_t
*dma
= dev
->dma
;
1506 drm_r128_buf_priv_t
*buf_priv
;
1507 drm_r128_indirect_t indirect
;
1512 LOCK_TEST_WITH_RETURN( dev
, filp
);
1515 DRM_ERROR( "%s called with no initialization\n", __FUNCTION__
);
1516 return DRM_ERR(EINVAL
);
1519 DRM_COPY_FROM_USER_IOCTL( indirect
, (drm_r128_indirect_t
*) data
,
1522 DRM_DEBUG( "indirect: idx=%d s=%d e=%d d=%d\n",
1523 indirect
.idx
, indirect
.start
,
1524 indirect
.end
, indirect
.discard
);
1526 if ( indirect
.idx
< 0 || indirect
.idx
>= dma
->buf_count
) {
1527 DRM_ERROR( "buffer index %d (of %d max)\n",
1528 indirect
.idx
, dma
->buf_count
- 1 );
1529 return DRM_ERR(EINVAL
);
1532 buf
= dma
->buflist
[indirect
.idx
];
1533 buf_priv
= buf
->dev_private
;
1535 if ( buf
->filp
!= filp
) {
1536 DRM_ERROR( "process %d using buffer owned by %p\n",
1537 DRM_CURRENTPID
, buf
->filp
);
1538 return DRM_ERR(EINVAL
);
1540 if ( buf
->pending
) {
1541 DRM_ERROR( "sending pending buffer %d\n", indirect
.idx
);
1542 return DRM_ERR(EINVAL
);
1545 if ( indirect
.start
< buf
->used
) {
1546 DRM_ERROR( "reusing indirect: start=0x%x actual=0x%x\n",
1547 indirect
.start
, buf
->used
);
1548 return DRM_ERR(EINVAL
);
1551 RING_SPACE_TEST_WITH_RETURN( dev_priv
);
1552 VB_AGE_TEST_WITH_RETURN( dev_priv
);
1554 buf
->used
= indirect
.end
;
1555 buf_priv
->discard
= indirect
.discard
;
1558 /* Wait for the 3D stream to idle before the indirect buffer
1559 * containing 2D acceleration commands is processed.
1562 RADEON_WAIT_UNTIL_3D_IDLE();
1566 /* Dispatch the indirect buffer full of commands from the
1567 * X server. This is insecure and is thus only available to
1568 * privileged clients.
1570 r128_cce_dispatch_indirect( dev
, buf
, indirect
.start
, indirect
.end
);
1575 int r128_getparam( DRM_IOCTL_ARGS
)
1578 drm_r128_private_t
*dev_priv
= dev
->dev_private
;
1579 drm_r128_getparam_t param
;
1583 DRM_ERROR( "%s called with no initialization\n", __FUNCTION__
);
1584 return DRM_ERR(EINVAL
);
1587 DRM_COPY_FROM_USER_IOCTL( param
, (drm_r128_getparam_t
*)data
,
1590 DRM_DEBUG( "pid=%d\n", DRM_CURRENTPID
);
1592 switch( param
.param
) {
1593 case R128_PARAM_IRQ_NR
:
1597 return DRM_ERR(EINVAL
);
1600 if ( DRM_COPY_TO_USER( param
.value
, &value
, sizeof(int) ) ) {
1601 DRM_ERROR( "copy_to_user\n" );
1602 return DRM_ERR(EFAULT
);