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>
29 * $FreeBSD: src/sys/dev/drm/r128_state.c,v 1.6.2.1 2003/04/26 07:05:29 anholt Exp $
30 * $DragonFly: src/sys/dev/drm/r128/Attic/r128_state.c,v 1.4 2005/02/17 13:59:36 joerg Exp $
34 #include "dev/drm/drmP.h"
35 #include "dev/drm/drm.h"
40 /* ================================================================
41 * CCE hardware state programming functions
44 static void r128_emit_clip_rects( drm_r128_private_t *dev_priv,
45 drm_clip_rect_t *boxes, int count )
47 u32 aux_sc_cntl = 0x00000000;
49 DRM_DEBUG( " %s\n", __func__ );
54 OUT_RING( CCE_PACKET0( R128_AUX1_SC_LEFT, 3 ) );
55 OUT_RING( boxes[0].x1 );
56 OUT_RING( boxes[0].x2 - 1 );
57 OUT_RING( boxes[0].y1 );
58 OUT_RING( boxes[0].y2 - 1 );
60 aux_sc_cntl |= (R128_AUX1_SC_EN | R128_AUX1_SC_MODE_OR);
63 OUT_RING( CCE_PACKET0( R128_AUX2_SC_LEFT, 3 ) );
64 OUT_RING( boxes[1].x1 );
65 OUT_RING( boxes[1].x2 - 1 );
66 OUT_RING( boxes[1].y1 );
67 OUT_RING( boxes[1].y2 - 1 );
69 aux_sc_cntl |= (R128_AUX2_SC_EN | R128_AUX2_SC_MODE_OR);
72 OUT_RING( CCE_PACKET0( R128_AUX3_SC_LEFT, 3 ) );
73 OUT_RING( boxes[2].x1 );
74 OUT_RING( boxes[2].x2 - 1 );
75 OUT_RING( boxes[2].y1 );
76 OUT_RING( boxes[2].y2 - 1 );
78 aux_sc_cntl |= (R128_AUX3_SC_EN | R128_AUX3_SC_MODE_OR);
81 OUT_RING( CCE_PACKET0( R128_AUX_SC_CNTL, 0 ) );
82 OUT_RING( aux_sc_cntl );
87 static __inline__ void r128_emit_core( drm_r128_private_t *dev_priv )
89 drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv;
90 drm_r128_context_regs_t *ctx = &sarea_priv->context_state;
92 DRM_DEBUG( " %s\n", __func__ );
96 OUT_RING( CCE_PACKET0( R128_SCALE_3D_CNTL, 0 ) );
97 OUT_RING( ctx->scale_3d_cntl );
102 static __inline__ void r128_emit_context( drm_r128_private_t *dev_priv )
104 drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv;
105 drm_r128_context_regs_t *ctx = &sarea_priv->context_state;
107 DRM_DEBUG( " %s\n", __func__ );
111 OUT_RING( CCE_PACKET0( R128_DST_PITCH_OFFSET_C, 11 ) );
112 OUT_RING( ctx->dst_pitch_offset_c );
113 OUT_RING( ctx->dp_gui_master_cntl_c );
114 OUT_RING( ctx->sc_top_left_c );
115 OUT_RING( ctx->sc_bottom_right_c );
116 OUT_RING( ctx->z_offset_c );
117 OUT_RING( ctx->z_pitch_c );
118 OUT_RING( ctx->z_sten_cntl_c );
119 OUT_RING( ctx->tex_cntl_c );
120 OUT_RING( ctx->misc_3d_state_cntl_reg );
121 OUT_RING( ctx->texture_clr_cmp_clr_c );
122 OUT_RING( ctx->texture_clr_cmp_msk_c );
123 OUT_RING( ctx->fog_color_c );
128 static __inline__ void r128_emit_setup( drm_r128_private_t *dev_priv )
130 drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv;
131 drm_r128_context_regs_t *ctx = &sarea_priv->context_state;
133 DRM_DEBUG( " %s\n", __func__ );
137 OUT_RING( CCE_PACKET1( R128_SETUP_CNTL, R128_PM4_VC_FPU_SETUP ) );
138 OUT_RING( ctx->setup_cntl );
139 OUT_RING( ctx->pm4_vc_fpu_setup );
144 static __inline__ void r128_emit_masks( drm_r128_private_t *dev_priv )
146 drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv;
147 drm_r128_context_regs_t *ctx = &sarea_priv->context_state;
149 DRM_DEBUG( " %s\n", __func__ );
153 OUT_RING( CCE_PACKET0( R128_DP_WRITE_MASK, 0 ) );
154 OUT_RING( ctx->dp_write_mask );
156 OUT_RING( CCE_PACKET0( R128_STEN_REF_MASK_C, 1 ) );
157 OUT_RING( ctx->sten_ref_mask_c );
158 OUT_RING( ctx->plane_3d_mask_c );
163 static __inline__ void r128_emit_window( drm_r128_private_t *dev_priv )
165 drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv;
166 drm_r128_context_regs_t *ctx = &sarea_priv->context_state;
168 DRM_DEBUG( " %s\n", __func__ );
172 OUT_RING( CCE_PACKET0( R128_WINDOW_XY_OFFSET, 0 ) );
173 OUT_RING( ctx->window_xy_offset );
178 static __inline__ void r128_emit_tex0( drm_r128_private_t *dev_priv )
180 drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv;
181 drm_r128_context_regs_t *ctx = &sarea_priv->context_state;
182 drm_r128_texture_regs_t *tex = &sarea_priv->tex_state[0];
185 DRM_DEBUG( " %s\n", __func__ );
187 BEGIN_RING( 7 + R128_MAX_TEXTURE_LEVELS );
189 OUT_RING( CCE_PACKET0( R128_PRIM_TEX_CNTL_C,
190 2 + R128_MAX_TEXTURE_LEVELS ) );
191 OUT_RING( tex->tex_cntl );
192 OUT_RING( tex->tex_combine_cntl );
193 OUT_RING( ctx->tex_size_pitch_c );
194 for ( i = 0 ; i < R128_MAX_TEXTURE_LEVELS ; i++ ) {
195 OUT_RING( tex->tex_offset[i] );
198 OUT_RING( CCE_PACKET0( R128_CONSTANT_COLOR_C, 1 ) );
199 OUT_RING( ctx->constant_color_c );
200 OUT_RING( tex->tex_border_color );
205 static __inline__ void r128_emit_tex1( drm_r128_private_t *dev_priv )
207 drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv;
208 drm_r128_texture_regs_t *tex = &sarea_priv->tex_state[1];
211 DRM_DEBUG( " %s\n", __func__ );
213 BEGIN_RING( 5 + R128_MAX_TEXTURE_LEVELS );
215 OUT_RING( CCE_PACKET0( R128_SEC_TEX_CNTL_C,
216 1 + R128_MAX_TEXTURE_LEVELS ) );
217 OUT_RING( tex->tex_cntl );
218 OUT_RING( tex->tex_combine_cntl );
219 for ( i = 0 ; i < R128_MAX_TEXTURE_LEVELS ; i++ ) {
220 OUT_RING( tex->tex_offset[i] );
223 OUT_RING( CCE_PACKET0( R128_SEC_TEXTURE_BORDER_COLOR_C, 0 ) );
224 OUT_RING( tex->tex_border_color );
229 static __inline__ void r128_emit_state( drm_r128_private_t *dev_priv )
231 drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv;
232 unsigned int dirty = sarea_priv->dirty;
234 DRM_DEBUG( "%s: dirty=0x%08x\n", __func__, dirty );
236 if ( dirty & R128_UPLOAD_CORE ) {
237 r128_emit_core( dev_priv );
238 sarea_priv->dirty &= ~R128_UPLOAD_CORE;
241 if ( dirty & R128_UPLOAD_CONTEXT ) {
242 r128_emit_context( dev_priv );
243 sarea_priv->dirty &= ~R128_UPLOAD_CONTEXT;
246 if ( dirty & R128_UPLOAD_SETUP ) {
247 r128_emit_setup( dev_priv );
248 sarea_priv->dirty &= ~R128_UPLOAD_SETUP;
251 if ( dirty & R128_UPLOAD_MASKS ) {
252 r128_emit_masks( dev_priv );
253 sarea_priv->dirty &= ~R128_UPLOAD_MASKS;
256 if ( dirty & R128_UPLOAD_WINDOW ) {
257 r128_emit_window( dev_priv );
258 sarea_priv->dirty &= ~R128_UPLOAD_WINDOW;
261 if ( dirty & R128_UPLOAD_TEX0 ) {
262 r128_emit_tex0( dev_priv );
263 sarea_priv->dirty &= ~R128_UPLOAD_TEX0;
266 if ( dirty & R128_UPLOAD_TEX1 ) {
267 r128_emit_tex1( dev_priv );
268 sarea_priv->dirty &= ~R128_UPLOAD_TEX1;
271 /* Turn off the texture cache flushing */
272 sarea_priv->context_state.tex_cntl_c &= ~R128_TEX_CACHE_FLUSH;
274 sarea_priv->dirty &= ~R128_REQUIRE_QUIESCENCE;
278 #if R128_PERFORMANCE_BOXES
279 /* ================================================================
280 * Performance monitoring functions
283 static void r128_clear_box( drm_r128_private_t *dev_priv,
284 int x, int y, int w, int h,
285 int r, int g, int b )
291 switch ( dev_priv->fb_bpp ) {
293 fb_bpp = R128_GMC_DST_16BPP;
294 color = (((r & 0xf8) << 8) |
299 fb_bpp = R128_GMC_DST_24BPP;
300 color = ((r << 16) | (g << 8) | b);
303 fb_bpp = R128_GMC_DST_32BPP;
304 color = (((0xff) << 24) | (r << 16) | (g << 8) | b);
310 offset = dev_priv->back_offset;
311 pitch = dev_priv->back_pitch >> 3;
315 OUT_RING( CCE_PACKET3( R128_CNTL_PAINT_MULTI, 4 ) );
316 OUT_RING( R128_GMC_DST_PITCH_OFFSET_CNTL |
317 R128_GMC_BRUSH_SOLID_COLOR |
319 R128_GMC_SRC_DATATYPE_COLOR |
321 R128_GMC_CLR_CMP_CNTL_DIS |
322 R128_GMC_AUX_CLIP_DIS );
324 OUT_RING( (pitch << 21) | (offset >> 5) );
327 OUT_RING( (x << 16) | y );
328 OUT_RING( (w << 16) | h );
333 static void r128_cce_performance_boxes( drm_r128_private_t *dev_priv )
335 if ( atomic_read( &dev_priv->idle_count ) == 0 ) {
336 r128_clear_box( dev_priv, 64, 4, 8, 8, 0, 255, 0 );
338 atomic_set( &dev_priv->idle_count, 0 );
345 /* ================================================================
346 * CCE command dispatch functions
349 static void r128_print_dirty( const char *msg, unsigned int flags )
351 DRM_INFO( "%s: (0x%x) %s%s%s%s%s%s%s%s%s\n",
354 (flags & R128_UPLOAD_CORE) ? "core, " : "",
355 (flags & R128_UPLOAD_CONTEXT) ? "context, " : "",
356 (flags & R128_UPLOAD_SETUP) ? "setup, " : "",
357 (flags & R128_UPLOAD_TEX0) ? "tex0, " : "",
358 (flags & R128_UPLOAD_TEX1) ? "tex1, " : "",
359 (flags & R128_UPLOAD_MASKS) ? "masks, " : "",
360 (flags & R128_UPLOAD_WINDOW) ? "window, " : "",
361 (flags & R128_UPLOAD_CLIPRECTS) ? "cliprects, " : "",
362 (flags & R128_REQUIRE_QUIESCENCE) ? "quiescence, " : "" );
365 static void r128_cce_dispatch_clear( drm_device_t *dev,
366 drm_r128_clear_t *clear )
368 drm_r128_private_t *dev_priv = dev->dev_private;
369 drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv;
370 int nbox = sarea_priv->nbox;
371 drm_clip_rect_t *pbox = sarea_priv->boxes;
372 unsigned int flags = clear->flags;
375 DRM_DEBUG( "%s\n", __func__ );
377 if ( dev_priv->page_flipping && dev_priv->current_page == 1 ) {
378 unsigned int tmp = flags;
380 flags &= ~(R128_FRONT | R128_BACK);
381 if ( tmp & R128_FRONT ) flags |= R128_BACK;
382 if ( tmp & R128_BACK ) flags |= R128_FRONT;
385 for ( i = 0 ; i < nbox ; i++ ) {
388 int w = pbox[i].x2 - x;
389 int h = pbox[i].y2 - y;
391 DRM_DEBUG( "dispatch clear %d,%d-%d,%d flags 0x%x\n",
392 pbox[i].x1, pbox[i].y1, pbox[i].x2,
395 if ( flags & (R128_FRONT | R128_BACK) ) {
398 OUT_RING( CCE_PACKET0( R128_DP_WRITE_MASK, 0 ) );
399 OUT_RING( clear->color_mask );
404 if ( flags & R128_FRONT ) {
407 OUT_RING( CCE_PACKET3( R128_CNTL_PAINT_MULTI, 4 ) );
408 OUT_RING( R128_GMC_DST_PITCH_OFFSET_CNTL |
409 R128_GMC_BRUSH_SOLID_COLOR |
410 (dev_priv->color_fmt << 8) |
411 R128_GMC_SRC_DATATYPE_COLOR |
413 R128_GMC_CLR_CMP_CNTL_DIS |
414 R128_GMC_AUX_CLIP_DIS );
416 OUT_RING( dev_priv->front_pitch_offset_c );
417 OUT_RING( clear->clear_color );
419 OUT_RING( (x << 16) | y );
420 OUT_RING( (w << 16) | h );
425 if ( flags & R128_BACK ) {
428 OUT_RING( CCE_PACKET3( R128_CNTL_PAINT_MULTI, 4 ) );
429 OUT_RING( R128_GMC_DST_PITCH_OFFSET_CNTL |
430 R128_GMC_BRUSH_SOLID_COLOR |
431 (dev_priv->color_fmt << 8) |
432 R128_GMC_SRC_DATATYPE_COLOR |
434 R128_GMC_CLR_CMP_CNTL_DIS |
435 R128_GMC_AUX_CLIP_DIS );
437 OUT_RING( dev_priv->back_pitch_offset_c );
438 OUT_RING( clear->clear_color );
440 OUT_RING( (x << 16) | y );
441 OUT_RING( (w << 16) | h );
446 if ( flags & R128_DEPTH ) {
449 OUT_RING( CCE_PACKET3( R128_CNTL_PAINT_MULTI, 4 ) );
450 OUT_RING( R128_GMC_DST_PITCH_OFFSET_CNTL |
451 R128_GMC_BRUSH_SOLID_COLOR |
452 (dev_priv->depth_fmt << 8) |
453 R128_GMC_SRC_DATATYPE_COLOR |
455 R128_GMC_CLR_CMP_CNTL_DIS |
456 R128_GMC_AUX_CLIP_DIS |
457 R128_GMC_WR_MSK_DIS );
459 OUT_RING( dev_priv->depth_pitch_offset_c );
460 OUT_RING( clear->clear_depth );
462 OUT_RING( (x << 16) | y );
463 OUT_RING( (w << 16) | h );
470 static void r128_cce_dispatch_swap( drm_device_t *dev )
472 drm_r128_private_t *dev_priv = dev->dev_private;
473 drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv;
474 int nbox = sarea_priv->nbox;
475 drm_clip_rect_t *pbox = sarea_priv->boxes;
478 DRM_DEBUG( "%s\n", __func__ );
480 #if R128_PERFORMANCE_BOXES
481 /* Do some trivial performance monitoring...
483 r128_cce_performance_boxes( dev_priv );
486 for ( i = 0 ; i < nbox ; i++ ) {
489 int w = pbox[i].x2 - x;
490 int h = pbox[i].y2 - y;
494 OUT_RING( CCE_PACKET3( R128_CNTL_BITBLT_MULTI, 5 ) );
495 OUT_RING( R128_GMC_SRC_PITCH_OFFSET_CNTL |
496 R128_GMC_DST_PITCH_OFFSET_CNTL |
497 R128_GMC_BRUSH_NONE |
498 (dev_priv->color_fmt << 8) |
499 R128_GMC_SRC_DATATYPE_COLOR |
501 R128_DP_SRC_SOURCE_MEMORY |
502 R128_GMC_CLR_CMP_CNTL_DIS |
503 R128_GMC_AUX_CLIP_DIS |
504 R128_GMC_WR_MSK_DIS );
506 OUT_RING( dev_priv->back_pitch_offset_c );
507 OUT_RING( dev_priv->front_pitch_offset_c );
509 OUT_RING( (x << 16) | y );
510 OUT_RING( (x << 16) | y );
511 OUT_RING( (w << 16) | h );
516 /* Increment the frame counter. The client-side 3D driver must
517 * throttle the framerate by waiting for this value before
518 * performing the swapbuffer ioctl.
520 dev_priv->sarea_priv->last_frame++;
524 OUT_RING( CCE_PACKET0( R128_LAST_FRAME_REG, 0 ) );
525 OUT_RING( dev_priv->sarea_priv->last_frame );
530 static void r128_cce_dispatch_flip( drm_device_t *dev )
532 drm_r128_private_t *dev_priv = dev->dev_private;
534 DRM_DEBUG( "page=%d\n", dev_priv->current_page );
536 #if R128_PERFORMANCE_BOXES
537 /* Do some trivial performance monitoring...
539 r128_cce_performance_boxes( dev_priv );
544 R128_WAIT_UNTIL_PAGE_FLIPPED();
545 OUT_RING( CCE_PACKET0( R128_CRTC_OFFSET, 0 ) );
547 if ( dev_priv->current_page == 0 ) {
548 OUT_RING( dev_priv->back_offset );
549 dev_priv->current_page = 1;
551 OUT_RING( dev_priv->front_offset );
552 dev_priv->current_page = 0;
557 /* Increment the frame counter. The client-side 3D driver must
558 * throttle the framerate by waiting for this value before
559 * performing the swapbuffer ioctl.
561 dev_priv->sarea_priv->last_frame++;
565 OUT_RING( CCE_PACKET0( R128_LAST_FRAME_REG, 0 ) );
566 OUT_RING( dev_priv->sarea_priv->last_frame );
571 static void r128_cce_dispatch_vertex( drm_device_t *dev,
574 drm_r128_private_t *dev_priv = dev->dev_private;
575 drm_r128_buf_priv_t *buf_priv = buf->dev_private;
576 drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv;
577 int format = sarea_priv->vc_format;
578 int offset = buf->bus_address;
579 int size = buf->used;
580 int prim = buf_priv->prim;
583 DRM_DEBUG( "buf=%d nbox=%d\n", buf->idx, sarea_priv->nbox );
586 r128_print_dirty( "dispatch_vertex", sarea_priv->dirty );
589 buf_priv->dispatched = 1;
591 if ( sarea_priv->dirty & ~R128_UPLOAD_CLIPRECTS ) {
592 r128_emit_state( dev_priv );
596 /* Emit the next set of up to three cliprects */
597 if ( i < sarea_priv->nbox ) {
598 r128_emit_clip_rects( dev_priv,
599 &sarea_priv->boxes[i],
600 sarea_priv->nbox - i );
603 /* Emit the vertex buffer rendering commands */
606 OUT_RING( CCE_PACKET3( R128_3D_RNDR_GEN_INDX_PRIM, 3 ) );
610 OUT_RING( prim | R128_CCE_VC_CNTL_PRIM_WALK_LIST |
611 (size << R128_CCE_VC_CNTL_NUM_SHIFT) );
616 } while ( i < sarea_priv->nbox );
619 if ( buf_priv->discard ) {
620 buf_priv->age = dev_priv->sarea_priv->last_dispatch;
622 /* Emit the vertex buffer age */
625 OUT_RING( CCE_PACKET0( R128_LAST_DISPATCH_REG, 0 ) );
626 OUT_RING( buf_priv->age );
632 /* FIXME: Check dispatched field */
633 buf_priv->dispatched = 0;
636 dev_priv->sarea_priv->last_dispatch++;
638 sarea_priv->dirty &= ~R128_UPLOAD_CLIPRECTS;
639 sarea_priv->nbox = 0;
642 static void r128_cce_dispatch_indirect( drm_device_t *dev,
646 drm_r128_private_t *dev_priv = dev->dev_private;
647 drm_r128_buf_priv_t *buf_priv = buf->dev_private;
649 DRM_DEBUG( "indirect: buf=%d s=0x%x e=0x%x\n",
650 buf->idx, start, end );
652 if ( start != end ) {
653 int offset = buf->bus_address + start;
654 int dwords = (end - start + 3) / sizeof(u32);
656 /* Indirect buffer data must be an even number of
657 * dwords, so if we've been given an odd number we must
658 * pad the data with a Type-2 CCE packet.
662 ((char *)dev_priv->buffers->handle
663 + buf->offset + start);
664 data[dwords++] = cpu_to_le32( R128_CCE_PACKET2 );
667 buf_priv->dispatched = 1;
669 /* Fire off the indirect buffer */
672 OUT_RING( CCE_PACKET0( R128_PM4_IW_INDOFF, 1 ) );
679 if ( buf_priv->discard ) {
680 buf_priv->age = dev_priv->sarea_priv->last_dispatch;
682 /* Emit the indirect buffer age */
685 OUT_RING( CCE_PACKET0( R128_LAST_DISPATCH_REG, 0 ) );
686 OUT_RING( buf_priv->age );
692 /* FIXME: Check dispatched field */
693 buf_priv->dispatched = 0;
696 dev_priv->sarea_priv->last_dispatch++;
699 static void r128_cce_dispatch_indices( drm_device_t *dev,
704 drm_r128_private_t *dev_priv = dev->dev_private;
705 drm_r128_buf_priv_t *buf_priv = buf->dev_private;
706 drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv;
707 int format = sarea_priv->vc_format;
708 int offset = dev_priv->buffers->offset - dev_priv->cce_buffers_offset;
709 int prim = buf_priv->prim;
714 DRM_DEBUG( "indices: s=%d e=%d c=%d\n", start, end, count );
717 r128_print_dirty( "dispatch_indices", sarea_priv->dirty );
719 if ( start != end ) {
720 buf_priv->dispatched = 1;
722 if ( sarea_priv->dirty & ~R128_UPLOAD_CLIPRECTS ) {
723 r128_emit_state( dev_priv );
726 dwords = (end - start + 3) / sizeof(u32);
728 data = (u32 *)((char *)dev_priv->buffers->handle
729 + buf->offset + start);
731 data[0] = cpu_to_le32( CCE_PACKET3( R128_3D_RNDR_GEN_INDX_PRIM,
734 data[1] = cpu_to_le32( offset );
735 data[2] = cpu_to_le32( R128_MAX_VB_VERTS );
736 data[3] = cpu_to_le32( format );
737 data[4] = cpu_to_le32( (prim | R128_CCE_VC_CNTL_PRIM_WALK_IND |
741 #ifdef __LITTLE_ENDIAN
742 data[dwords-1] &= 0x0000ffff;
744 data[dwords-1] &= 0xffff0000;
749 /* Emit the next set of up to three cliprects */
750 if ( i < sarea_priv->nbox ) {
751 r128_emit_clip_rects( dev_priv,
752 &sarea_priv->boxes[i],
753 sarea_priv->nbox - i );
756 r128_cce_dispatch_indirect( dev, buf, start, end );
759 } while ( i < sarea_priv->nbox );
762 if ( buf_priv->discard ) {
763 buf_priv->age = dev_priv->sarea_priv->last_dispatch;
765 /* Emit the vertex buffer age */
768 OUT_RING( CCE_PACKET0( R128_LAST_DISPATCH_REG, 0 ) );
769 OUT_RING( buf_priv->age );
774 /* FIXME: Check dispatched field */
775 buf_priv->dispatched = 0;
778 dev_priv->sarea_priv->last_dispatch++;
780 sarea_priv->dirty &= ~R128_UPLOAD_CLIPRECTS;
781 sarea_priv->nbox = 0;
784 static int r128_cce_dispatch_blit( DRMFILE filp,
786 drm_r128_blit_t *blit )
788 drm_r128_private_t *dev_priv = dev->dev_private;
789 drm_device_dma_t *dma = dev->dma;
791 drm_r128_buf_priv_t *buf_priv;
793 int dword_shift, dwords;
797 /* The compiler won't optimize away a division by a variable,
798 * even if the only legal values are powers of two. Thus, we'll
799 * use a shift instead.
801 switch ( blit->format ) {
802 case R128_DATATYPE_ARGB8888:
805 case R128_DATATYPE_ARGB1555:
806 case R128_DATATYPE_RGB565:
807 case R128_DATATYPE_ARGB4444:
810 case R128_DATATYPE_CI8:
811 case R128_DATATYPE_RGB8:
815 DRM_ERROR( "invalid blit format %d\n", blit->format );
816 return DRM_ERR(EINVAL);
819 /* Flush the pixel cache, and mark the contents as Read Invalid.
820 * This ensures no pixel data gets mixed up with the texture
821 * data from the host data blit, otherwise part of the texture
822 * image may be corrupted.
826 OUT_RING( CCE_PACKET0( R128_PC_GUI_CTLSTAT, 0 ) );
827 OUT_RING( R128_PC_RI_GUI | R128_PC_FLUSH_GUI );
831 /* Dispatch the indirect buffer.
833 buf = dma->buflist[blit->idx];
834 buf_priv = buf->dev_private;
836 if ( buf->filp != filp ) {
837 DRM_ERROR( "process %d using buffer owned by %p\n",
838 DRM_CURRENTPID, buf->filp );
839 return DRM_ERR(EINVAL);
841 if ( buf->pending ) {
842 DRM_ERROR( "sending pending buffer %d\n", blit->idx );
843 return DRM_ERR(EINVAL);
846 buf_priv->discard = 1;
848 dwords = (blit->width * blit->height) >> dword_shift;
850 data = (u32 *)((char *)dev_priv->buffers->handle + buf->offset);
852 data[0] = cpu_to_le32( CCE_PACKET3( R128_CNTL_HOSTDATA_BLT, dwords + 6 ) );
853 data[1] = cpu_to_le32( (R128_GMC_DST_PITCH_OFFSET_CNTL |
854 R128_GMC_BRUSH_NONE |
855 (blit->format << 8) |
856 R128_GMC_SRC_DATATYPE_COLOR |
858 R128_DP_SRC_SOURCE_HOST_DATA |
859 R128_GMC_CLR_CMP_CNTL_DIS |
860 R128_GMC_AUX_CLIP_DIS |
861 R128_GMC_WR_MSK_DIS) );
863 data[2] = cpu_to_le32( (blit->pitch << 21) | (blit->offset >> 5) );
864 data[3] = cpu_to_le32( 0xffffffff );
865 data[4] = cpu_to_le32( 0xffffffff );
866 data[5] = cpu_to_le32( (blit->y << 16) | blit->x );
867 data[6] = cpu_to_le32( (blit->height << 16) | blit->width );
868 data[7] = cpu_to_le32( dwords );
870 buf->used = (dwords + 8) * sizeof(u32);
872 r128_cce_dispatch_indirect( dev, buf, 0, buf->used );
874 /* Flush the pixel cache after the blit completes. This ensures
875 * the texture data is written out to memory before rendering
880 OUT_RING( CCE_PACKET0( R128_PC_GUI_CTLSTAT, 0 ) );
881 OUT_RING( R128_PC_FLUSH_GUI );
889 /* ================================================================
890 * Tiled depth buffer management
892 * FIXME: These should all set the destination write mask for when we
893 * have hardware stencil support.
896 static int r128_cce_dispatch_write_span( drm_device_t *dev,
897 drm_r128_depth_t *depth )
899 drm_r128_private_t *dev_priv = dev->dev_private;
903 int i, buffer_size, mask_size;
908 if ( DRM_COPY_FROM_USER( &x, depth->x, sizeof(x) ) ) {
909 return DRM_ERR(EFAULT);
911 if ( DRM_COPY_FROM_USER( &y, depth->y, sizeof(y) ) ) {
912 return DRM_ERR(EFAULT);
915 buffer_size = depth->n * sizeof(u32);
916 buffer = DRM_MALLOC( buffer_size );
917 if ( buffer == NULL )
918 return DRM_ERR(ENOMEM);
919 if ( DRM_COPY_FROM_USER( buffer, depth->buffer, buffer_size ) ) {
920 DRM_FREE( buffer, buffer_size);
921 return DRM_ERR(EFAULT);
924 mask_size = depth->n * sizeof(u8);
926 mask = DRM_MALLOC( mask_size );
927 if ( mask == NULL ) {
928 DRM_FREE( buffer, buffer_size );
929 return DRM_ERR(ENOMEM);
931 if ( DRM_COPY_FROM_USER( mask, depth->mask, mask_size ) ) {
932 DRM_FREE( buffer, buffer_size );
933 DRM_FREE( mask, mask_size );
934 return DRM_ERR(EFAULT);
937 for ( i = 0 ; i < count ; i++, x++ ) {
941 OUT_RING( CCE_PACKET3( R128_CNTL_PAINT_MULTI, 4 ) );
942 OUT_RING( R128_GMC_DST_PITCH_OFFSET_CNTL |
943 R128_GMC_BRUSH_SOLID_COLOR |
944 (dev_priv->depth_fmt << 8) |
945 R128_GMC_SRC_DATATYPE_COLOR |
947 R128_GMC_CLR_CMP_CNTL_DIS |
948 R128_GMC_WR_MSK_DIS );
950 OUT_RING( dev_priv->depth_pitch_offset_c );
951 OUT_RING( buffer[i] );
953 OUT_RING( (x << 16) | y );
954 OUT_RING( (1 << 16) | 1 );
960 DRM_FREE( mask, mask_size );
962 for ( i = 0 ; i < count ; i++, x++ ) {
965 OUT_RING( CCE_PACKET3( R128_CNTL_PAINT_MULTI, 4 ) );
966 OUT_RING( R128_GMC_DST_PITCH_OFFSET_CNTL |
967 R128_GMC_BRUSH_SOLID_COLOR |
968 (dev_priv->depth_fmt << 8) |
969 R128_GMC_SRC_DATATYPE_COLOR |
971 R128_GMC_CLR_CMP_CNTL_DIS |
972 R128_GMC_WR_MSK_DIS );
974 OUT_RING( dev_priv->depth_pitch_offset_c );
975 OUT_RING( buffer[i] );
977 OUT_RING( (x << 16) | y );
978 OUT_RING( (1 << 16) | 1 );
984 DRM_FREE( buffer, buffer_size );
989 static int r128_cce_dispatch_write_pixels( drm_device_t *dev,
990 drm_r128_depth_t *depth )
992 drm_r128_private_t *dev_priv = dev->dev_private;
996 int i, xbuf_size, ybuf_size, buffer_size, mask_size;
1002 xbuf_size = count * sizeof(*x);
1003 ybuf_size = count * sizeof(*y);
1004 x = DRM_MALLOC( xbuf_size );
1006 return DRM_ERR(ENOMEM);
1008 y = DRM_MALLOC( ybuf_size );
1010 DRM_FREE( x, xbuf_size );
1011 return DRM_ERR(ENOMEM);
1013 if ( DRM_COPY_FROM_USER( x, depth->x, xbuf_size ) ) {
1014 DRM_FREE( x, xbuf_size );
1015 DRM_FREE( y, ybuf_size );
1016 return DRM_ERR(EFAULT);
1018 if ( DRM_COPY_FROM_USER( y, depth->y, xbuf_size ) ) {
1019 DRM_FREE( x, xbuf_size );
1020 DRM_FREE( y, ybuf_size );
1021 return DRM_ERR(EFAULT);
1024 buffer_size = depth->n * sizeof(u32);
1025 buffer = DRM_MALLOC( buffer_size );
1026 if ( buffer == NULL ) {
1027 DRM_FREE( x, xbuf_size );
1028 DRM_FREE( y, ybuf_size );
1029 return DRM_ERR(ENOMEM);
1031 if ( DRM_COPY_FROM_USER( buffer, depth->buffer, buffer_size ) ) {
1032 DRM_FREE( x, xbuf_size );
1033 DRM_FREE( y, ybuf_size );
1034 DRM_FREE( buffer, buffer_size );
1035 return DRM_ERR(EFAULT);
1038 if ( depth->mask ) {
1039 mask_size = depth->n * sizeof(u8);
1040 mask = DRM_MALLOC( mask_size );
1041 if ( mask == NULL ) {
1042 DRM_FREE( x, xbuf_size );
1043 DRM_FREE( y, ybuf_size );
1044 DRM_FREE( buffer, buffer_size );
1045 return DRM_ERR(ENOMEM);
1047 if ( DRM_COPY_FROM_USER( mask, depth->mask, mask_size ) ) {
1048 DRM_FREE( x, xbuf_size );
1049 DRM_FREE( y, ybuf_size );
1050 DRM_FREE( buffer, buffer_size );
1051 DRM_FREE( mask, mask_size );
1052 return DRM_ERR(EFAULT);
1055 for ( i = 0 ; i < count ; i++ ) {
1059 OUT_RING( CCE_PACKET3( R128_CNTL_PAINT_MULTI, 4 ) );
1060 OUT_RING( R128_GMC_DST_PITCH_OFFSET_CNTL |
1061 R128_GMC_BRUSH_SOLID_COLOR |
1062 (dev_priv->depth_fmt << 8) |
1063 R128_GMC_SRC_DATATYPE_COLOR |
1065 R128_GMC_CLR_CMP_CNTL_DIS |
1066 R128_GMC_WR_MSK_DIS );
1068 OUT_RING( dev_priv->depth_pitch_offset_c );
1069 OUT_RING( buffer[i] );
1071 OUT_RING( (x[i] << 16) | y[i] );
1072 OUT_RING( (1 << 16) | 1 );
1078 DRM_FREE( mask, mask_size );
1080 for ( i = 0 ; i < count ; i++ ) {
1083 OUT_RING( CCE_PACKET3( R128_CNTL_PAINT_MULTI, 4 ) );
1084 OUT_RING( R128_GMC_DST_PITCH_OFFSET_CNTL |
1085 R128_GMC_BRUSH_SOLID_COLOR |
1086 (dev_priv->depth_fmt << 8) |
1087 R128_GMC_SRC_DATATYPE_COLOR |
1089 R128_GMC_CLR_CMP_CNTL_DIS |
1090 R128_GMC_WR_MSK_DIS );
1092 OUT_RING( dev_priv->depth_pitch_offset_c );
1093 OUT_RING( buffer[i] );
1095 OUT_RING( (x[i] << 16) | y[i] );
1096 OUT_RING( (1 << 16) | 1 );
1102 DRM_FREE( x, xbuf_size );
1103 DRM_FREE( y, ybuf_size );
1104 DRM_FREE( buffer, buffer_size );
1109 static int r128_cce_dispatch_read_span( drm_device_t *dev,
1110 drm_r128_depth_t *depth )
1112 drm_r128_private_t *dev_priv = dev->dev_private;
1118 if ( DRM_COPY_FROM_USER( &x, depth->x, sizeof(x) ) ) {
1119 return DRM_ERR(EFAULT);
1121 if ( DRM_COPY_FROM_USER( &y, depth->y, sizeof(y) ) ) {
1122 return DRM_ERR(EFAULT);
1127 OUT_RING( CCE_PACKET3( R128_CNTL_BITBLT_MULTI, 5 ) );
1128 OUT_RING( R128_GMC_SRC_PITCH_OFFSET_CNTL |
1129 R128_GMC_DST_PITCH_OFFSET_CNTL |
1130 R128_GMC_BRUSH_NONE |
1131 (dev_priv->depth_fmt << 8) |
1132 R128_GMC_SRC_DATATYPE_COLOR |
1134 R128_DP_SRC_SOURCE_MEMORY |
1135 R128_GMC_CLR_CMP_CNTL_DIS |
1136 R128_GMC_WR_MSK_DIS );
1138 OUT_RING( dev_priv->depth_pitch_offset_c );
1139 OUT_RING( dev_priv->span_pitch_offset_c );
1141 OUT_RING( (x << 16) | y );
1142 OUT_RING( (0 << 16) | 0 );
1143 OUT_RING( (count << 16) | 1 );
1150 static int r128_cce_dispatch_read_pixels( drm_device_t *dev,
1151 drm_r128_depth_t *depth )
1153 drm_r128_private_t *dev_priv = dev->dev_private;
1155 int i, xbuf_size, ybuf_size;
1157 DRM_DEBUG( "%s\n", __func__ );
1160 if ( count > dev_priv->depth_pitch ) {
1161 count = dev_priv->depth_pitch;
1164 xbuf_size = count * sizeof(*x);
1165 ybuf_size = count * sizeof(*y);
1166 x = DRM_MALLOC( xbuf_size );
1168 return DRM_ERR(ENOMEM);
1170 y = DRM_MALLOC( ybuf_size );
1172 DRM_FREE( x, xbuf_size );
1173 return DRM_ERR(ENOMEM);
1175 if ( DRM_COPY_FROM_USER( x, depth->x, xbuf_size ) ) {
1176 DRM_FREE( x, xbuf_size );
1177 DRM_FREE( y, ybuf_size );
1178 return DRM_ERR(EFAULT);
1180 if ( DRM_COPY_FROM_USER( y, depth->y, ybuf_size ) ) {
1181 DRM_FREE( x, xbuf_size );
1182 DRM_FREE( y, ybuf_size );
1183 return DRM_ERR(EFAULT);
1186 for ( i = 0 ; i < count ; i++ ) {
1189 OUT_RING( CCE_PACKET3( R128_CNTL_BITBLT_MULTI, 5 ) );
1190 OUT_RING( R128_GMC_SRC_PITCH_OFFSET_CNTL |
1191 R128_GMC_DST_PITCH_OFFSET_CNTL |
1192 R128_GMC_BRUSH_NONE |
1193 (dev_priv->depth_fmt << 8) |
1194 R128_GMC_SRC_DATATYPE_COLOR |
1196 R128_DP_SRC_SOURCE_MEMORY |
1197 R128_GMC_CLR_CMP_CNTL_DIS |
1198 R128_GMC_WR_MSK_DIS );
1200 OUT_RING( dev_priv->depth_pitch_offset_c );
1201 OUT_RING( dev_priv->span_pitch_offset_c );
1203 OUT_RING( (x[i] << 16) | y[i] );
1204 OUT_RING( (i << 16) | 0 );
1205 OUT_RING( (1 << 16) | 1 );
1210 DRM_FREE( x, xbuf_size );
1211 DRM_FREE( y, ybuf_size );
1217 /* ================================================================
1221 static void r128_cce_dispatch_stipple( drm_device_t *dev, u32 *stipple )
1223 drm_r128_private_t *dev_priv = dev->dev_private;
1226 DRM_DEBUG( "%s\n", __func__ );
1230 OUT_RING( CCE_PACKET0( R128_BRUSH_DATA0, 31 ) );
1231 for ( i = 0 ; i < 32 ; i++ ) {
1232 OUT_RING( stipple[i] );
1239 /* ================================================================
1243 int r128_cce_clear( DRM_IOCTL_ARGS )
1246 drm_r128_private_t *dev_priv = dev->dev_private;
1247 drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv;
1248 drm_r128_clear_t clear;
1251 LOCK_TEST_WITH_RETURN( dev, filp );
1253 DRM_COPY_FROM_USER_IOCTL( clear, (drm_r128_clear_t *) data,
1256 RING_SPACE_TEST_WITH_RETURN( dev_priv );
1258 if ( sarea_priv->nbox > R128_NR_SAREA_CLIPRECTS )
1259 sarea_priv->nbox = R128_NR_SAREA_CLIPRECTS;
1261 r128_cce_dispatch_clear( dev, &clear );
1263 /* Make sure we restore the 3D state next time.
1265 dev_priv->sarea_priv->dirty |= R128_UPLOAD_CONTEXT | R128_UPLOAD_MASKS;
1270 int r128_cce_swap( DRM_IOCTL_ARGS )
1273 drm_r128_private_t *dev_priv = dev->dev_private;
1274 drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv;
1275 DRM_DEBUG( "%s\n", __func__ );
1277 LOCK_TEST_WITH_RETURN( dev, filp );
1279 RING_SPACE_TEST_WITH_RETURN( dev_priv );
1281 if ( sarea_priv->nbox > R128_NR_SAREA_CLIPRECTS )
1282 sarea_priv->nbox = R128_NR_SAREA_CLIPRECTS;
1284 if ( !dev_priv->page_flipping ) {
1285 r128_cce_dispatch_swap( dev );
1286 dev_priv->sarea_priv->dirty |= (R128_UPLOAD_CONTEXT |
1289 r128_cce_dispatch_flip( dev );
1295 int r128_cce_vertex( DRM_IOCTL_ARGS )
1298 drm_r128_private_t *dev_priv = dev->dev_private;
1299 drm_device_dma_t *dma = dev->dma;
1301 drm_r128_buf_priv_t *buf_priv;
1302 drm_r128_vertex_t vertex;
1304 LOCK_TEST_WITH_RETURN( dev, filp );
1307 DRM_ERROR( "%s called with no initialization\n", __func__ );
1308 return DRM_ERR(EINVAL);
1311 DRM_COPY_FROM_USER_IOCTL( vertex, (drm_r128_vertex_t *) data,
1314 DRM_DEBUG( "pid=%d index=%d count=%d discard=%d\n",
1316 vertex.idx, vertex.count, vertex.discard );
1318 if ( vertex.idx < 0 || vertex.idx >= dma->buf_count ) {
1319 DRM_ERROR( "buffer index %d (of %d max)\n",
1320 vertex.idx, dma->buf_count - 1 );
1321 return DRM_ERR(EINVAL);
1323 if ( vertex.prim < 0 ||
1324 vertex.prim > R128_CCE_VC_CNTL_PRIM_TYPE_TRI_TYPE2 ) {
1325 DRM_ERROR( "buffer prim %d\n", vertex.prim );
1326 return DRM_ERR(EINVAL);
1329 RING_SPACE_TEST_WITH_RETURN( dev_priv );
1330 VB_AGE_TEST_WITH_RETURN( dev_priv );
1332 buf = dma->buflist[vertex.idx];
1333 buf_priv = buf->dev_private;
1335 if ( buf->filp != filp ) {
1336 DRM_ERROR( "process %d using buffer owned by %p\n",
1337 DRM_CURRENTPID, buf->filp );
1338 return DRM_ERR(EINVAL);
1340 if ( buf->pending ) {
1341 DRM_ERROR( "sending pending buffer %d\n", vertex.idx );
1342 return DRM_ERR(EINVAL);
1345 buf->used = vertex.count;
1346 buf_priv->prim = vertex.prim;
1347 buf_priv->discard = vertex.discard;
1349 r128_cce_dispatch_vertex( dev, buf );
1354 int r128_cce_indices( DRM_IOCTL_ARGS )
1357 drm_r128_private_t *dev_priv = dev->dev_private;
1358 drm_device_dma_t *dma = dev->dma;
1360 drm_r128_buf_priv_t *buf_priv;
1361 drm_r128_indices_t elts;
1364 LOCK_TEST_WITH_RETURN( dev, filp );
1367 DRM_ERROR( "%s called with no initialization\n", __func__ );
1368 return DRM_ERR(EINVAL);
1371 DRM_COPY_FROM_USER_IOCTL( elts, (drm_r128_indices_t *) data,
1374 DRM_DEBUG( "pid=%d buf=%d s=%d e=%d d=%d\n", DRM_CURRENTPID,
1375 elts.idx, elts.start, elts.end, elts.discard );
1377 if ( elts.idx < 0 || elts.idx >= dma->buf_count ) {
1378 DRM_ERROR( "buffer index %d (of %d max)\n",
1379 elts.idx, dma->buf_count - 1 );
1380 return DRM_ERR(EINVAL);
1382 if ( elts.prim < 0 ||
1383 elts.prim > R128_CCE_VC_CNTL_PRIM_TYPE_TRI_TYPE2 ) {
1384 DRM_ERROR( "buffer prim %d\n", elts.prim );
1385 return DRM_ERR(EINVAL);
1388 RING_SPACE_TEST_WITH_RETURN( dev_priv );
1389 VB_AGE_TEST_WITH_RETURN( dev_priv );
1391 buf = dma->buflist[elts.idx];
1392 buf_priv = buf->dev_private;
1394 if ( buf->filp != filp ) {
1395 DRM_ERROR( "process %d using buffer owned by %p\n",
1396 DRM_CURRENTPID, buf->filp );
1397 return DRM_ERR(EINVAL);
1399 if ( buf->pending ) {
1400 DRM_ERROR( "sending pending buffer %d\n", elts.idx );
1401 return DRM_ERR(EINVAL);
1404 count = (elts.end - elts.start) / sizeof(u16);
1405 elts.start -= R128_INDEX_PRIM_OFFSET;
1407 if ( elts.start & 0x7 ) {
1408 DRM_ERROR( "misaligned buffer 0x%x\n", elts.start );
1409 return DRM_ERR(EINVAL);
1411 if ( elts.start < buf->used ) {
1412 DRM_ERROR( "no header 0x%x - 0x%x\n", elts.start, buf->used );
1413 return DRM_ERR(EINVAL);
1416 buf->used = elts.end;
1417 buf_priv->prim = elts.prim;
1418 buf_priv->discard = elts.discard;
1420 r128_cce_dispatch_indices( dev, buf, elts.start, elts.end, count );
1425 int r128_cce_blit( DRM_IOCTL_ARGS )
1428 drm_device_dma_t *dma = dev->dma;
1429 drm_r128_private_t *dev_priv = dev->dev_private;
1430 drm_r128_blit_t blit;
1432 LOCK_TEST_WITH_RETURN( dev, filp );
1434 DRM_COPY_FROM_USER_IOCTL( blit, (drm_r128_blit_t *) data,
1437 DRM_DEBUG( "pid=%d index=%d\n", DRM_CURRENTPID, blit.idx );
1439 if ( blit.idx < 0 || blit.idx >= dma->buf_count ) {
1440 DRM_ERROR( "buffer index %d (of %d max)\n",
1441 blit.idx, dma->buf_count - 1 );
1442 return DRM_ERR(EINVAL);
1445 RING_SPACE_TEST_WITH_RETURN( dev_priv );
1446 VB_AGE_TEST_WITH_RETURN( dev_priv );
1448 return r128_cce_dispatch_blit( filp, dev, &blit );
1451 int r128_cce_depth( DRM_IOCTL_ARGS )
1454 drm_r128_private_t *dev_priv = dev->dev_private;
1455 drm_r128_depth_t depth;
1457 LOCK_TEST_WITH_RETURN( dev, filp );
1459 DRM_COPY_FROM_USER_IOCTL( depth, (drm_r128_depth_t *) data,
1462 RING_SPACE_TEST_WITH_RETURN( dev_priv );
1464 switch ( depth.func ) {
1465 case R128_WRITE_SPAN:
1466 return r128_cce_dispatch_write_span( dev, &depth );
1467 case R128_WRITE_PIXELS:
1468 return r128_cce_dispatch_write_pixels( dev, &depth );
1469 case R128_READ_SPAN:
1470 return r128_cce_dispatch_read_span( dev, &depth );
1471 case R128_READ_PIXELS:
1472 return r128_cce_dispatch_read_pixels( dev, &depth );
1475 return DRM_ERR(EINVAL);
1478 int r128_cce_stipple( DRM_IOCTL_ARGS )
1481 drm_r128_private_t *dev_priv = dev->dev_private;
1482 drm_r128_stipple_t stipple;
1485 LOCK_TEST_WITH_RETURN( dev, filp );
1487 DRM_COPY_FROM_USER_IOCTL( stipple, (drm_r128_stipple_t *) data,
1490 if ( DRM_COPY_FROM_USER( &mask, stipple.mask,
1491 32 * sizeof(u32) ) )
1492 return DRM_ERR( EFAULT );
1494 RING_SPACE_TEST_WITH_RETURN( dev_priv );
1496 r128_cce_dispatch_stipple( dev, mask );
1501 int r128_cce_indirect( DRM_IOCTL_ARGS )
1504 drm_r128_private_t *dev_priv = dev->dev_private;
1505 drm_device_dma_t *dma = dev->dma;
1507 drm_r128_buf_priv_t *buf_priv;
1508 drm_r128_indirect_t indirect;
1513 LOCK_TEST_WITH_RETURN( dev, filp );
1516 DRM_ERROR( "%s called with no initialization\n", __func__ );
1517 return DRM_ERR(EINVAL);
1520 DRM_COPY_FROM_USER_IOCTL( indirect, (drm_r128_indirect_t *) data,
1523 DRM_DEBUG( "indirect: idx=%d s=%d e=%d d=%d\n",
1524 indirect.idx, indirect.start,
1525 indirect.end, indirect.discard );
1527 if ( indirect.idx < 0 || indirect.idx >= dma->buf_count ) {
1528 DRM_ERROR( "buffer index %d (of %d max)\n",
1529 indirect.idx, dma->buf_count - 1 );
1530 return DRM_ERR(EINVAL);
1533 buf = dma->buflist[indirect.idx];
1534 buf_priv = buf->dev_private;
1536 if ( buf->filp != filp ) {
1537 DRM_ERROR( "process %d using buffer owned by %p\n",
1538 DRM_CURRENTPID, buf->filp );
1539 return DRM_ERR(EINVAL);
1541 if ( buf->pending ) {
1542 DRM_ERROR( "sending pending buffer %d\n", indirect.idx );
1543 return DRM_ERR(EINVAL);
1546 if ( indirect.start < buf->used ) {
1547 DRM_ERROR( "reusing indirect: start=0x%x actual=0x%x\n",
1548 indirect.start, buf->used );
1549 return DRM_ERR(EINVAL);
1552 RING_SPACE_TEST_WITH_RETURN( dev_priv );
1553 VB_AGE_TEST_WITH_RETURN( dev_priv );
1555 buf->used = indirect.end;
1556 buf_priv->discard = indirect.discard;
1559 /* Wait for the 3D stream to idle before the indirect buffer
1560 * containing 2D acceleration commands is processed.
1563 RADEON_WAIT_UNTIL_3D_IDLE();
1567 /* Dispatch the indirect buffer full of commands from the
1568 * X server. This is insecure and is thus only available to
1569 * privileged clients.
1571 r128_cce_dispatch_indirect( dev, buf, indirect.start, indirect.end );
1576 int r128_getparam( DRM_IOCTL_ARGS )
1579 drm_r128_private_t *dev_priv = dev->dev_private;
1580 drm_r128_getparam_t param;
1584 DRM_ERROR( "%s called with no initialization\n", __func__ );
1585 return DRM_ERR(EINVAL);
1588 DRM_COPY_FROM_USER_IOCTL( param, (drm_r128_getparam_t *)data,
1591 DRM_DEBUG( "pid=%d\n", DRM_CURRENTPID );
1593 switch( param.param ) {
1594 case R128_PARAM_IRQ_NR:
1598 return DRM_ERR(EINVAL);
1601 if ( DRM_COPY_TO_USER( param.value, &value, sizeof(int) ) ) {
1602 DRM_ERROR( "copy_to_user\n" );
1603 return DRM_ERR(EFAULT);