📄 radeon_state.c
字号:
unsigned int flags = clear->flags; int i; RING_LOCALS; DRM_DEBUG( "%s\n", __FUNCTION__ ); if ( dev_priv->page_flipping && dev_priv->current_page == 1 ) { unsigned int tmp = flags; flags &= ~(RADEON_FRONT | RADEON_BACK); if ( tmp & RADEON_FRONT ) flags |= RADEON_BACK; if ( tmp & RADEON_BACK ) flags |= RADEON_FRONT; } 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", x, y, w, h, flags ); if ( flags & (RADEON_FRONT | RADEON_BACK) ) { BEGIN_RING( 4 ); /* Ensure the 3D stream is idle before doing a * 2D fill to clear the front or back buffer. */ RADEON_WAIT_UNTIL_3D_IDLE(); OUT_RING( CP_PACKET0( RADEON_DP_WRITE_MASK, 0 ) ); OUT_RING( clear->color_mask ); ADVANCE_RING(); /* Make sure we restore the 3D state next time. */ dev_priv->sarea_priv->dirty |= (RADEON_UPLOAD_CONTEXT | RADEON_UPLOAD_MASKS); } if ( flags & RADEON_FRONT ) { BEGIN_RING( 6 ); OUT_RING( CP_PACKET3( RADEON_CNTL_PAINT_MULTI, 4 ) ); OUT_RING( RADEON_GMC_DST_PITCH_OFFSET_CNTL | RADEON_GMC_BRUSH_SOLID_COLOR | (dev_priv->color_fmt << 8) | RADEON_GMC_SRC_DATATYPE_COLOR | RADEON_ROP3_P | RADEON_GMC_CLR_CMP_CNTL_DIS ); OUT_RING( dev_priv->front_pitch_offset ); OUT_RING( clear->clear_color ); OUT_RING( (x << 16) | y ); OUT_RING( (w << 16) | h ); ADVANCE_RING(); } if ( flags & RADEON_BACK ) { BEGIN_RING( 6 ); OUT_RING( CP_PACKET3( RADEON_CNTL_PAINT_MULTI, 4 ) ); OUT_RING( RADEON_GMC_DST_PITCH_OFFSET_CNTL | RADEON_GMC_BRUSH_SOLID_COLOR | (dev_priv->color_fmt << 8) | RADEON_GMC_SRC_DATATYPE_COLOR | RADEON_ROP3_P | RADEON_GMC_CLR_CMP_CNTL_DIS ); OUT_RING( dev_priv->back_pitch_offset ); OUT_RING( clear->clear_color ); OUT_RING( (x << 16) | y ); OUT_RING( (w << 16) | h ); ADVANCE_RING(); } if ( flags & RADEON_DEPTH ) { drm_radeon_depth_clear_t *depth_clear = &dev_priv->depth_clear; if ( sarea_priv->dirty & ~RADEON_UPLOAD_CLIPRECTS ) { radeon_emit_state( dev_priv ); } /* FIXME: Render a rectangle to clear the depth * buffer. So much for those "fast Z clears"... */ BEGIN_RING( 23 ); RADEON_WAIT_UNTIL_2D_IDLE(); OUT_RING( CP_PACKET0( RADEON_PP_CNTL, 1 ) ); OUT_RING( 0x00000000 ); OUT_RING( depth_clear->rb3d_cntl ); OUT_RING( CP_PACKET0( RADEON_RB3D_ZSTENCILCNTL, 0 ) ); OUT_RING( depth_clear->rb3d_zstencilcntl ); OUT_RING( CP_PACKET0( RADEON_RB3D_PLANEMASK, 0 ) ); OUT_RING( 0x00000000 ); OUT_RING( CP_PACKET0( RADEON_SE_CNTL, 0 ) ); OUT_RING( depth_clear->se_cntl ); OUT_RING( CP_PACKET3( RADEON_3D_DRAW_IMMD, 10 ) ); OUT_RING( RADEON_VTX_Z_PRESENT ); OUT_RING( (RADEON_PRIM_TYPE_RECT_LIST | RADEON_PRIM_WALK_RING | RADEON_MAOS_ENABLE | RADEON_VTX_FMT_RADEON_MODE | (3 << RADEON_NUM_VERTICES_SHIFT)) ); OUT_RING( depth_boxes[i].ui[CLEAR_X1] ); OUT_RING( depth_boxes[i].ui[CLEAR_Y1] ); OUT_RING( depth_boxes[i].ui[CLEAR_DEPTH] ); OUT_RING( depth_boxes[i].ui[CLEAR_X1] ); OUT_RING( depth_boxes[i].ui[CLEAR_Y2] ); OUT_RING( depth_boxes[i].ui[CLEAR_DEPTH] ); OUT_RING( depth_boxes[i].ui[CLEAR_X2] ); OUT_RING( depth_boxes[i].ui[CLEAR_Y2] ); OUT_RING( depth_boxes[i].ui[CLEAR_DEPTH] ); ADVANCE_RING(); /* Make sure we restore the 3D state next time. */ dev_priv->sarea_priv->dirty |= (RADEON_UPLOAD_CONTEXT | RADEON_UPLOAD_SETUP | RADEON_UPLOAD_MASKS); } } /* Increment the clear counter. The client-side 3D driver must * wait on this value before performing the clear ioctl. We * need this because the card's so damned fast... */ dev_priv->sarea_priv->last_clear++; BEGIN_RING( 4 ); RADEON_CLEAR_AGE( dev_priv->sarea_priv->last_clear ); RADEON_WAIT_UNTIL_IDLE(); ADVANCE_RING();}static void radeon_cp_dispatch_swap( drm_device_t *dev ){ drm_radeon_private_t *dev_priv = dev->dev_private; drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; int nbox = sarea_priv->nbox; drm_clip_rect_t *pbox = sarea_priv->boxes; int i; RING_LOCALS; DRM_DEBUG( "%s\n", __FUNCTION__ );#if RADEON_PERFORMANCE_BOXES /* Do some trivial performance monitoring... */ radeon_cp_performance_boxes( dev_priv );#endif /* Wait for the 3D stream to idle before dispatching the bitblt. * This will prevent data corruption between the two streams. */ BEGIN_RING( 2 ); RADEON_WAIT_UNTIL_3D_IDLE(); ADVANCE_RING(); 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 swap %d,%d-%d,%d\n", x, y, w, h ); BEGIN_RING( 7 ); OUT_RING( CP_PACKET3( RADEON_CNTL_BITBLT_MULTI, 5 ) ); OUT_RING( RADEON_GMC_SRC_PITCH_OFFSET_CNTL | RADEON_GMC_DST_PITCH_OFFSET_CNTL | RADEON_GMC_BRUSH_NONE | (dev_priv->color_fmt << 8) | RADEON_GMC_SRC_DATATYPE_COLOR | RADEON_ROP3_S | RADEON_DP_SRC_SOURCE_MEMORY | RADEON_GMC_CLR_CMP_CNTL_DIS | RADEON_GMC_WR_MSK_DIS ); OUT_RING( dev_priv->back_pitch_offset ); OUT_RING( dev_priv->front_pitch_offset ); OUT_RING( (x << 16) | y ); OUT_RING( (x << 16) | y ); OUT_RING( (w << 16) | h ); ADVANCE_RING(); } /* Increment the frame counter. The client-side 3D driver must * throttle the framerate by waiting for this value before * performing the swapbuffer ioctl. */ dev_priv->sarea_priv->last_frame++; BEGIN_RING( 4 ); RADEON_FRAME_AGE( dev_priv->sarea_priv->last_frame ); RADEON_WAIT_UNTIL_2D_IDLE(); ADVANCE_RING();}static void radeon_cp_dispatch_flip( drm_device_t *dev ){ drm_radeon_private_t *dev_priv = dev->dev_private; RING_LOCALS; DRM_DEBUG( "%s: page=%d\n", __FUNCTION__, dev_priv->current_page );#if RADEON_PERFORMANCE_BOXES /* Do some trivial performance monitoring... */ radeon_cp_performance_boxes( dev_priv );#endif BEGIN_RING( 6 ); RADEON_WAIT_UNTIL_3D_IDLE(); RADEON_WAIT_UNTIL_PAGE_FLIPPED(); OUT_RING( CP_PACKET0( RADEON_CRTC_OFFSET, 0 ) ); if ( dev_priv->current_page == 0 ) { OUT_RING( dev_priv->back_offset ); dev_priv->current_page = 1; } else { OUT_RING( dev_priv->front_offset ); dev_priv->current_page = 0; } ADVANCE_RING(); /* Increment the frame counter. The client-side 3D driver must * throttle the framerate by waiting for this value before * performing the swapbuffer ioctl. */ dev_priv->sarea_priv->last_frame++; BEGIN_RING( 2 ); RADEON_FRAME_AGE( dev_priv->sarea_priv->last_frame ); ADVANCE_RING();}static void radeon_cp_dispatch_vertex( drm_device_t *dev, drm_buf_t *buf ){ drm_radeon_private_t *dev_priv = dev->dev_private; drm_radeon_buf_priv_t *buf_priv = buf->dev_private; drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; int format = sarea_priv->vc_format; int offset = dev_priv->agp_buffers_offset + buf->offset; int size = buf->used; int prim = buf_priv->prim; int i = 0; RING_LOCALS; DRM_DEBUG( "%s: nbox=%d\n", __FUNCTION__, sarea_priv->nbox ); if ( 0 ) radeon_print_dirty( "dispatch_vertex", sarea_priv->dirty ); if ( buf->used ) { buf_priv->dispatched = 1; if ( sarea_priv->dirty & ~RADEON_UPLOAD_CLIPRECTS ) { radeon_emit_state( dev_priv ); } do { /* Emit the next set of up to three cliprects */ if ( i < sarea_priv->nbox ) { radeon_emit_clip_rect( dev_priv, &sarea_priv->boxes[i] ); } /* Emit the vertex buffer rendering commands */ BEGIN_RING( 5 ); OUT_RING( CP_PACKET3( RADEON_3D_RNDR_GEN_INDX_PRIM, 3 ) ); OUT_RING( offset ); OUT_RING( size ); OUT_RING( format ); OUT_RING( prim | RADEON_PRIM_WALK_LIST | RADEON_COLOR_ORDER_RGBA | RADEON_VTX_FMT_RADEON_MODE | (size << RADEON_NUM_VERTICES_SHIFT) ); ADVANCE_RING(); i++; } while ( i < sarea_priv->nbox ); } if ( buf_priv->discard ) { buf_priv->age = dev_priv->sarea_priv->last_dispatch; /* Emit the vertex buffer age */ BEGIN_RING( 2 ); RADEON_DISPATCH_AGE( buf_priv->age ); ADVANCE_RING(); buf->pending = 1; buf->used = 0; /* FIXME: Check dispatched field */ buf_priv->dispatched = 0; } dev_priv->sarea_priv->last_dispatch++; sarea_priv->dirty &= ~RADEON_UPLOAD_CLIPRECTS; sarea_priv->nbox = 0;}static void radeon_cp_dispatch_indirect( drm_device_t *dev, drm_buf_t *buf, int start, int end ){ drm_radeon_private_t *dev_priv = dev->dev_private; drm_radeon_buf_priv_t *buf_priv = buf->dev_private; RING_LOCALS; DRM_DEBUG( "indirect: buf=%d s=0x%x e=0x%x\n", buf->idx, start, end ); if ( start != end ) { int offset = (dev_priv->agp_buffers_offset + buf->offset + start); int dwords = (end - start + 3) / sizeof(u32); /* Indirect buffer data must be an even number of * dwords, so if we've been given an odd number we must * pad the data with a Type-2 CP packet. */ if ( dwords & 1 ) { u32 *data = (u32 *) ((char *)dev_priv->buffers->handle + buf->offset + start); data[dwords++] = RADEON_CP_PACKET2; } buf_priv->dispatched = 1; /* Fire off the indirect buffer */ BEGIN_RING( 3 ); OUT_RING( CP_PACKET0( RADEON_CP_IB_BASE, 1 ) ); OUT_RING( offset ); OUT_RING( dwords ); ADVANCE_RING(); } if ( buf_priv->discard ) { buf_priv->age = dev_priv->sarea_priv->last_dispatch; /* Emit the indirect buffer age */ BEGIN_RING( 2 ); RADEON_DISPATCH_AGE( buf_priv->age ); ADVANCE_RING(); buf->pending = 1; buf->used = 0; /* FIXME: Check dispatched field */ buf_priv->dispatched = 0; } dev_priv->sarea_priv->last_dispatch++;}static void radeon_cp_dispatch_indices( drm_device_t *dev, drm_buf_t *buf, int start, int end, int count ){ drm_radeon_private_t *dev_priv = dev->dev_private; drm_radeon_buf_priv_t *buf_priv = buf->dev_private; drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; int format = sarea_priv->vc_format; int offset = dev_priv->agp_buffers_offset; int prim = buf_priv->prim; u32 *data; int dwords; int i = 0; RING_LOCALS; DRM_DEBUG( "indices: s=%d e=%d c=%d\n", start, end, count ); if ( 0 ) radeon_print_dirty( "dispatch_indices", sarea_priv->dirty ); if ( start != end ) { buf_priv->dispatched = 1; if ( sarea_priv->dirty & ~RADEON_UPLOAD_CLIPRECTS ) { radeon_emit_state( dev_priv ); } dwords = (end - start + 3) / sizeof(u32); data = (u32 *)((char *)dev_priv->buffers->handle + buf->offset + start); data[0] = CP_PACKET3( RADEON_3D_RNDR_GEN_INDX_PRIM, dwords-2 ); data[1] = offset; data[2] = RADEON_MAX_VB_VERTS; data[3] = format; data[4] = (prim | RADEON_PRIM_WALK_IND | RADEON_COLOR_ORDER_RGBA | RADEON_VTX_FMT_RADEON_MODE | (count << RADEON_NUM_VERTICES_SHIFT) ); if ( count & 0x1 ) { data[dwords-1] &= 0x0000ffff; } do { /* Emit the next set of up to three cliprects */ if ( i < sarea_priv->nbox ) { radeon_emit_clip_rect( dev_priv, &sarea_priv->boxes[i] ); } radeon_cp_dispatch_indirect( dev, buf, start, end ); i++; } while ( i < sarea_priv->nbox ); } if ( buf_priv->discard ) { buf_priv->age = dev_priv->sarea_priv->last_dispatch; /* Emit the vertex buffer age */ BEGIN_RING( 2 ); RADEON_DISPATCH_AGE( buf_priv->age ); ADVANCE_RING(); buf->pending = 1; /* FIXME: Check dispatched field */ buf_priv->dispatched = 0; } dev_priv->sarea_priv->last_dispatch++; sarea_priv->dirty &= ~RADEON_UPLOAD_CLIPRECTS; sarea_priv->nbox = 0;}#define RADEON_MAX_TEXTURE_SIZE (RADEON_BUFFER_SIZE - 8 * sizeof(u32))static int radeon_cp_dispatch_texture( drm_device_t *dev, drm_radeon_texture_t *tex, drm_radeon_tex_image_t *image ){ drm_radeon_private_t *dev_priv = dev->dev_private; drm_buf_t *buf; drm_radeon_buf_priv_t *buf_priv; u32 format; u32 *buffer; u8 *data; int size, dwords, tex_width, blit_width; u32 y, height; int ret = 0, i; RING_LOCALS; /* FIXME: Be smarter about this... */ buf = radeon_freelist_get( dev ); if ( !buf ) return -EAGAIN; DRM_DEBUG( "tex: ofs=0x%x p=%d f=%d x=%hd y=%hd w=%hd h=%hd\n", tex->offset >> 10, tex->pitch, tex->format, image->x, image->y, image->width, image->height ); buf_priv = buf->dev_private;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -