summaryrefslogtreecommitdiff
path: root/linux/r128_state.c
diff options
context:
space:
mode:
Diffstat (limited to 'linux/r128_state.c')
-rw-r--r--linux/r128_state.c279
1 files changed, 272 insertions, 7 deletions
diff --git a/linux/r128_state.c b/linux/r128_state.c
index 124d9938..b9ea930b 100644
--- a/linux/r128_state.c
+++ b/linux/r128_state.c
@@ -181,7 +181,7 @@ static inline void r128_emit_tex0( drm_r128_private_t *dev_priv )
RING_LOCALS;
DRM_DEBUG( " %s\n", __FUNCTION__ );
- BEGIN_RING( 3 );
+ BEGIN_RING( 7 + R128_TEX_MAXLEVELS );
OUT_RING( CCE_PACKET0( R128_PRIM_TEX_CNTL_C,
2 + R128_TEX_MAXLEVELS ) );
@@ -207,7 +207,7 @@ static inline void r128_emit_tex1( drm_r128_private_t *dev_priv )
RING_LOCALS;
DRM_DEBUG( " %s\n", __FUNCTION__ );
- BEGIN_RING( 3 );
+ BEGIN_RING( 5 + R128_TEX_MAXLEVELS );
OUT_RING( CCE_PACKET0( R128_SEC_TEX_CNTL_C,
1 + R128_TEX_MAXLEVELS ) );
@@ -274,16 +274,214 @@ static inline void r128_emit_state( drm_r128_private_t *dev_priv )
* CCE command dispatch functions
*/
-static void r128_cce_dispatch_swap( drm_device_t *dev )
+static void r128_print_dirty( const char *msg, unsigned int flags )
{
-
+ DRM_INFO( "%s: (0x%x) %s%s%s%s%s%s%s%s%s\n",
+ msg,
+ flags,
+ (flags & R128_UPLOAD_CORE) ? "core, " : "",
+ (flags & R128_UPLOAD_CONTEXT) ? "context, " : "",
+ (flags & R128_UPLOAD_SETUP) ? "setup, " : "",
+ (flags & R128_UPLOAD_TEX0) ? "tex0, " : "",
+ (flags & R128_UPLOAD_TEX1) ? "tex1, " : "",
+ (flags & R128_UPLOAD_MASKS) ? "masks, " : "",
+ (flags & R128_UPLOAD_WINDOW) ? "window, " : "",
+ (flags & R128_UPLOAD_CLIPRECTS) ? "cliprects, " : "",
+ (flags & R128_REQUIRE_QUIESCENCE) ? "quiescence, " : "" );
}
-static void r128_cce_dispatch_clear( drm_device_t *dev, int flags,
+static void r128_cce_dispatch_clear( drm_device_t *dev,
+ unsigned int flags,
+ int cx, int cy, int cw, int ch,
unsigned int clear_color,
- unsigned int clear_depth )
+ unsigned int clear_depth,
+ unsigned int color_mask,
+ unsigned int depth_mask )
{
+ drm_r128_private_t *dev_priv = dev->dev_private;
+ drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv;
+ int nbox = sarea_priv->nbox;
+ drm_clip_rect_t *pbox = sarea_priv->boxes;
+ u32 fb_bpp, depth_bpp;
+ int i;
+ RING_LOCALS;
+ DRM_DEBUG( "%s\n", __FUNCTION__ );
+
+ switch ( dev_priv->fb_bpp ) {
+ case 16:
+ fb_bpp = R128_GMC_DST_16BPP;
+ break;
+ case 24:
+ fb_bpp = R128_GMC_DST_24BPP;
+ break;
+ case 32:
+ default:
+ fb_bpp = R128_GMC_DST_32BPP;
+ break;
+ }
+ switch ( dev_priv->depth_bpp ) {
+ case 16:
+ depth_bpp = R128_GMC_DST_16BPP;
+ break;
+ case 24:
+ depth_bpp = R128_GMC_DST_32BPP;
+ break;
+ case 32:
+ depth_bpp = R128_GMC_DST_32BPP;
+ break;
+ default:
+ return;
+ }
+
+ for ( i = 0 ; i < nbox ; i++ ) {
+ int x = pbox[i].x1;
+ int y = pbox[i].y1;
+ int w = pbox[i].x2 - x;
+ int h = pbox[i].y2 - y;
+
+ DRM_DEBUG( "dispatch clear %d,%d-%d,%d flags 0x%x\n",
+ pbox[i].x1, pbox[i].y1, pbox[i].x2,
+ pbox[i].y2, flags );
+
+ if ( flags & (R128_FRONT | R128_BACK) ) {
+ BEGIN_RING( 7 );
+
+ OUT_RING( CCE_PACKET0( R128_DP_WRITE_MASK, 0 ) );
+ OUT_RING( color_mask );
+
+ ADVANCE_RING();
+ }
+
+ if ( flags & R128_FRONT ) {
+ int fx = x + dev_priv->front_x;
+ int fy = y + dev_priv->front_y;
+
+ DRM_DEBUG( "clear front\n");
+ BEGIN_RING( 5 );
+
+ OUT_RING( CCE_PACKET3( R128_CNTL_PAINT_MULTI, 3 ) );
+ OUT_RING( R128_GMC_BRUSH_SOLID_COLOR
+ | fb_bpp
+ | R128_GMC_SRC_DATATYPE_COLOR
+ | R128_ROP3_P
+ | R128_GMC_CLR_CMP_CNTL_DIS
+ | R128_GMC_AUX_CLIP_DIS );
+ OUT_RING( clear_color );
+ OUT_RING( (fx << 16) | fy );
+ OUT_RING( (w << 16) | h );
+
+ ADVANCE_RING();
+ }
+
+ if ( flags & R128_BACK ) {
+ int bx = x + dev_priv->back_x;
+ int by = y + dev_priv->back_y;
+
+ DRM_DEBUG( "clear back\n" );
+ BEGIN_RING( 5 );
+
+ OUT_RING( CCE_PACKET3( R128_CNTL_PAINT_MULTI, 3 ) );
+ OUT_RING( R128_GMC_BRUSH_SOLID_COLOR
+ | fb_bpp
+ | R128_GMC_SRC_DATATYPE_COLOR
+ | R128_ROP3_P
+ | R128_GMC_CLR_CMP_CNTL_DIS
+ | R128_GMC_AUX_CLIP_DIS );
+ OUT_RING( clear_color );
+ OUT_RING( (bx << 16) | by );
+ OUT_RING( (w << 16) | h );
+
+ ADVANCE_RING();
+ }
+
+ if ( flags & R128_DEPTH ) {
+ int dx = x + dev_priv->depth_x;
+ int dy = y + dev_priv->depth_y;
+
+ DRM_DEBUG( "clear depth\n" );
+ BEGIN_RING( 7 );
+
+ OUT_RING( CCE_PACKET0( R128_DP_WRITE_MASK, 0 ) );
+ OUT_RING( depth_mask );
+
+ OUT_RING( CCE_PACKET3( R128_CNTL_PAINT_MULTI, 3 ) );
+ OUT_RING( R128_GMC_BRUSH_SOLID_COLOR
+ | depth_bpp
+ | R128_GMC_SRC_DATATYPE_COLOR
+ | R128_ROP3_P
+ | R128_GMC_CLR_CMP_CNTL_DIS
+ | R128_GMC_AUX_CLIP_DIS );
+ OUT_RING( clear_depth );
+ OUT_RING( (dx << 16) | dy );
+ OUT_RING( (w << 16) | h );
+
+ ADVANCE_RING();
+ }
+ }
+}
+
+static void r128_cce_dispatch_swap( drm_device_t *dev )
+{
+ drm_r128_private_t *dev_priv = dev->dev_private;
+ drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv;
+ int nbox = sarea_priv->nbox;
+ drm_clip_rect_t *pbox = sarea_priv->boxes;
+ u32 fb_bpp;
+ int i;
+ RING_LOCALS;
+ DRM_INFO( "%s\n", __FUNCTION__ );
+
+ switch ( dev_priv->fb_bpp ) {
+ case 16:
+ fb_bpp = R128_GMC_DST_16BPP;
+ break;
+ case 24:
+ fb_bpp = R128_GMC_DST_24BPP;
+ break;
+ case 32:
+ default:
+ fb_bpp = R128_GMC_DST_32BPP;
+ break;
+ }
+
+ for ( i = 0 ; i < nbox ; i++ ) {
+ int fx = pbox[i].x1;
+ int fy = pbox[i].y1;
+ int fw = pbox[i].x2 - fx;
+ int fh = pbox[i].y2 - fy;
+ int bx = fx + dev_priv->back_x;
+ int by = fy + dev_priv->back_y;
+
+ fx += dev_priv->front_x;
+ fy += dev_priv->front_x;
+
+ BEGIN_RING( 5 );
+
+ OUT_RING( CCE_PACKET3( R128_CNTL_BITBLT_MULTI, 3 ) );
+ OUT_RING( R128_GMC_BRUSH_NONE
+ | R128_GMC_SRC_DATATYPE_COLOR
+ | R128_DP_SRC_SOURCE_MEMORY
+ | fb_bpp
+ | R128_ROP3_S
+ | R128_GMC_CLR_CMP_CNTL_DIS
+ | R128_GMC_AUX_CLIP_DIS
+ | R128_GMC_WR_MSK_DIS );
+
+ OUT_RING( (bx << 16) | by );
+ OUT_RING( (fx << 16) | fy );
+ OUT_RING( (fw << 16) | fh );
+ ADVANCE_RING();
+ }
+
+#if 0
+ BEGIN_RING( 2 );
+
+ OUT_RING( CCE_PACKET0( R128_SWAP_AGE_REG, 0 ) );
+ OUT_RING( r128ctx->lastSwapAge );
+
+ ADVANCE_RING();
+#endif
}
static void r128_cce_dispatch_vertex( drm_device_t *dev,
@@ -295,7 +493,7 @@ static void r128_cce_dispatch_vertex( drm_device_t *dev,
int vertsize = sarea_priv->vertsize;
int format = sarea_priv->vc_format;
int index = buf->idx;
- int offset = dev_priv->agp_vertbufs->offset
+ int offset = dev_priv->vertex_buffers->offset
+ buf->offset - dev->agp->base;
int size = buf->used / (vertsize * sizeof(u32));
int prim;
@@ -309,6 +507,11 @@ static void r128_cce_dispatch_vertex( drm_device_t *dev,
DRM_DEBUG( "vertex size = %d\n", vertsize );
DRM_DEBUG( "vertex format = 0x%x\n", format );
+ r128_update_ring_snapshot( dev_priv );
+
+ if ( 0 )
+ r128_print_dirty( "dispatch_vertex", sarea_priv->dirty );
+
prim = R128_CCE_VC_CNTL_PRIM_TYPE_TRI_LIST;
if ( buf->used ) {
@@ -389,6 +592,68 @@ static void r128_get_vertex_buffer( drm_device_t *dev, drm_r128_vertex_t *v )
v->granted = 1;
}
+int r128_cce_clear( struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg )
+{
+ drm_file_t *priv = filp->private_data;
+ drm_device_t *dev = priv->dev;
+ drm_r128_private_t *dev_priv = dev->dev_private;
+ drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv;
+ drm_r128_clear_t clear;
+ DRM_DEBUG( "%s\n", __FUNCTION__ );
+
+ if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) ||
+ dev->lock.pid != current->pid ) {
+ DRM_ERROR( "r128_cce_clear called without lock held\n" );
+ return -EINVAL;
+ }
+
+ if ( copy_from_user( &clear, (drm_r128_clear_t *) arg,
+ sizeof(clear) ) )
+ return -EFAULT;
+
+ if ( sarea_priv->nbox > R128_NR_SAREA_CLIPRECTS )
+ sarea_priv->nbox = R128_NR_SAREA_CLIPRECTS;
+
+ r128_cce_dispatch_clear( dev, clear.flags,
+ clear.x, clear.y, clear.w, clear.h,
+ clear.clear_color, clear.clear_depth,
+ clear.color_mask, clear.depth_mask );
+
+ /* Make sure we restore the 3D state next time.
+ */
+ dev_priv->sarea_priv->dirty |= R128_UPLOAD_CONTEXT | R128_UPLOAD_MASKS;
+
+ return 0;
+}
+
+int r128_cce_swap( struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg )
+{
+ drm_file_t *priv = filp->private_data;
+ drm_device_t *dev = priv->dev;
+ drm_r128_private_t *dev_priv = dev->dev_private;
+ drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv;
+ DRM_DEBUG( "%s\n", __FUNCTION__ );
+
+ if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) ||
+ dev->lock.pid != current->pid ) {
+ DRM_ERROR( "r128_cce_swap called without lock held\n" );
+ return -EINVAL;
+ }
+
+ if ( sarea_priv->nbox > R128_NR_SAREA_CLIPRECTS )
+ sarea_priv->nbox = R128_NR_SAREA_CLIPRECTS;
+
+ r128_cce_dispatch_swap( dev );
+
+ /* Make sure we restore the 3D state next time.
+ */
+ dev_priv->sarea_priv->dirty |= R128_UPLOAD_CONTEXT | R128_UPLOAD_MASKS;
+
+ return 0;
+}
+
int r128_cce_vertex( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg )
{