radeon_state.c
来自「优龙2410linux2.6.8内核源代码」· C语言 代码 · 共 2,403 行 · 第 1/5 页
C
2,403 行
/* New (1.3) state mechanism. 3 commands (packet, scalar, vector) in * 1.3 cmdbuffers allow all previous state to be updated as well as * the tcl scalar and vector areas. */static struct { int start; int len; const char *name;} packet[RADEON_MAX_STATE_PACKETS] = { { RADEON_PP_MISC,7,"RADEON_PP_MISC" }, { RADEON_PP_CNTL,3,"RADEON_PP_CNTL" }, { RADEON_RB3D_COLORPITCH,1,"RADEON_RB3D_COLORPITCH" }, { RADEON_RE_LINE_PATTERN,2,"RADEON_RE_LINE_PATTERN" }, { RADEON_SE_LINE_WIDTH,1,"RADEON_SE_LINE_WIDTH" }, { RADEON_PP_LUM_MATRIX,1,"RADEON_PP_LUM_MATRIX" }, { RADEON_PP_ROT_MATRIX_0,2,"RADEON_PP_ROT_MATRIX_0" }, { RADEON_RB3D_STENCILREFMASK,3,"RADEON_RB3D_STENCILREFMASK" }, { RADEON_SE_VPORT_XSCALE,6,"RADEON_SE_VPORT_XSCALE" }, { RADEON_SE_CNTL,2,"RADEON_SE_CNTL" }, { RADEON_SE_CNTL_STATUS,1,"RADEON_SE_CNTL_STATUS" }, { RADEON_RE_MISC,1,"RADEON_RE_MISC" }, { RADEON_PP_TXFILTER_0,6,"RADEON_PP_TXFILTER_0" }, { RADEON_PP_BORDER_COLOR_0,1,"RADEON_PP_BORDER_COLOR_0" }, { RADEON_PP_TXFILTER_1,6,"RADEON_PP_TXFILTER_1" }, { RADEON_PP_BORDER_COLOR_1,1,"RADEON_PP_BORDER_COLOR_1" }, { RADEON_PP_TXFILTER_2,6,"RADEON_PP_TXFILTER_2" }, { RADEON_PP_BORDER_COLOR_2,1,"RADEON_PP_BORDER_COLOR_2" }, { RADEON_SE_ZBIAS_FACTOR,2,"RADEON_SE_ZBIAS_FACTOR" }, { RADEON_SE_TCL_OUTPUT_VTX_FMT,11,"RADEON_SE_TCL_OUTPUT_VTX_FMT" }, { RADEON_SE_TCL_MATERIAL_EMMISSIVE_RED,17,"RADEON_SE_TCL_MATERIAL_EMMISSIVE_RED" }, { R200_PP_TXCBLEND_0, 4, "R200_PP_TXCBLEND_0" }, { R200_PP_TXCBLEND_1, 4, "R200_PP_TXCBLEND_1" }, { R200_PP_TXCBLEND_2, 4, "R200_PP_TXCBLEND_2" }, { R200_PP_TXCBLEND_3, 4, "R200_PP_TXCBLEND_3" }, { R200_PP_TXCBLEND_4, 4, "R200_PP_TXCBLEND_4" }, { R200_PP_TXCBLEND_5, 4, "R200_PP_TXCBLEND_5" }, { R200_PP_TXCBLEND_6, 4, "R200_PP_TXCBLEND_6" }, { R200_PP_TXCBLEND_7, 4, "R200_PP_TXCBLEND_7" }, { R200_SE_TCL_LIGHT_MODEL_CTL_0, 6, "R200_SE_TCL_LIGHT_MODEL_CTL_0" }, { R200_PP_TFACTOR_0, 6, "R200_PP_TFACTOR_0" }, { R200_SE_VTX_FMT_0, 4, "R200_SE_VTX_FMT_0" }, { R200_SE_VAP_CNTL, 1, "R200_SE_VAP_CNTL" }, { R200_SE_TCL_MATRIX_SEL_0, 5, "R200_SE_TCL_MATRIX_SEL_0" }, { R200_SE_TCL_TEX_PROC_CTL_2, 5, "R200_SE_TCL_TEX_PROC_CTL_2" }, { R200_SE_TCL_UCP_VERT_BLEND_CTL, 1, "R200_SE_TCL_UCP_VERT_BLEND_CTL" }, { R200_PP_TXFILTER_0, 6, "R200_PP_TXFILTER_0" }, { R200_PP_TXFILTER_1, 6, "R200_PP_TXFILTER_1" }, { R200_PP_TXFILTER_2, 6, "R200_PP_TXFILTER_2" }, { R200_PP_TXFILTER_3, 6, "R200_PP_TXFILTER_3" }, { R200_PP_TXFILTER_4, 6, "R200_PP_TXFILTER_4" }, { R200_PP_TXFILTER_5, 6, "R200_PP_TXFILTER_5" }, { R200_PP_TXOFFSET_0, 1, "R200_PP_TXOFFSET_0" }, { R200_PP_TXOFFSET_1, 1, "R200_PP_TXOFFSET_1" }, { R200_PP_TXOFFSET_2, 1, "R200_PP_TXOFFSET_2" }, { R200_PP_TXOFFSET_3, 1, "R200_PP_TXOFFSET_3" }, { R200_PP_TXOFFSET_4, 1, "R200_PP_TXOFFSET_4" }, { R200_PP_TXOFFSET_5, 1, "R200_PP_TXOFFSET_5" }, { R200_SE_VTE_CNTL, 1, "R200_SE_VTE_CNTL" }, { R200_SE_TCL_OUTPUT_VTX_COMP_SEL, 1, "R200_SE_TCL_OUTPUT_VTX_COMP_SEL" }, { R200_PP_TAM_DEBUG3, 1, "R200_PP_TAM_DEBUG3" }, { R200_PP_CNTL_X, 1, "R200_PP_CNTL_X" }, { R200_RB3D_DEPTHXY_OFFSET, 1, "R200_RB3D_DEPTHXY_OFFSET" }, { R200_RE_AUX_SCISSOR_CNTL, 1, "R200_RE_AUX_SCISSOR_CNTL" }, { R200_RE_SCISSOR_TL_0, 2, "R200_RE_SCISSOR_TL_0" }, { R200_RE_SCISSOR_TL_1, 2, "R200_RE_SCISSOR_TL_1" }, { R200_RE_SCISSOR_TL_2, 2, "R200_RE_SCISSOR_TL_2" }, { R200_SE_VAP_CNTL_STATUS, 1, "R200_SE_VAP_CNTL_STATUS" }, { R200_SE_VTX_STATE_CNTL, 1, "R200_SE_VTX_STATE_CNTL" }, { R200_RE_POINTSIZE, 1, "R200_RE_POINTSIZE" }, { R200_SE_TCL_INPUT_VTX_VECTOR_ADDR_0, 4, "R200_SE_TCL_INPUT_VTX_VECTOR_ADDR_0" }, { R200_PP_CUBIC_FACES_0, 1, "R200_PP_CUBIC_FACES_0" }, /* 61 */ { R200_PP_CUBIC_OFFSET_F1_0, 5, "R200_PP_CUBIC_OFFSET_F1_0" }, /* 62 */ { R200_PP_CUBIC_FACES_1, 1, "R200_PP_CUBIC_FACES_1" }, { R200_PP_CUBIC_OFFSET_F1_1, 5, "R200_PP_CUBIC_OFFSET_F1_1" }, { R200_PP_CUBIC_FACES_2, 1, "R200_PP_CUBIC_FACES_2" }, { R200_PP_CUBIC_OFFSET_F1_2, 5, "R200_PP_CUBIC_OFFSET_F1_2" }, { R200_PP_CUBIC_FACES_3, 1, "R200_PP_CUBIC_FACES_3" }, { R200_PP_CUBIC_OFFSET_F1_3, 5, "R200_PP_CUBIC_OFFSET_F1_3" }, { R200_PP_CUBIC_FACES_4, 1, "R200_PP_CUBIC_FACES_4" }, { R200_PP_CUBIC_OFFSET_F1_4, 5, "R200_PP_CUBIC_OFFSET_F1_4" }, { R200_PP_CUBIC_FACES_5, 1, "R200_PP_CUBIC_FACES_5" }, { R200_PP_CUBIC_OFFSET_F1_5, 5, "R200_PP_CUBIC_OFFSET_F1_5" }, { RADEON_PP_TEX_SIZE_0, 2, "RADEON_PP_TEX_SIZE_0" }, { RADEON_PP_TEX_SIZE_1, 2, "RADEON_PP_TEX_SIZE_1" }, { RADEON_PP_TEX_SIZE_2, 2, "RADEON_PP_TEX_SIZE_2" }, { R200_RB3D_BLENDCOLOR, 3, "R200_RB3D_BLENDCOLOR" },};/* ================================================================ * Performance monitoring functions */static void radeon_clear_box( drm_radeon_private_t *dev_priv, int x, int y, int w, int h, int r, int g, int b ){ u32 color; RING_LOCALS; x += dev_priv->sarea_priv->boxes[0].x1; y += dev_priv->sarea_priv->boxes[0].y1; switch ( dev_priv->color_fmt ) { case RADEON_COLOR_FORMAT_RGB565: color = (((r & 0xf8) << 8) | ((g & 0xfc) << 3) | ((b & 0xf8) >> 3)); break; case RADEON_COLOR_FORMAT_ARGB8888: default: color = (((0xff) << 24) | (r << 16) | (g << 8) | b); break; } BEGIN_RING( 4 ); RADEON_WAIT_UNTIL_3D_IDLE(); OUT_RING( CP_PACKET0( RADEON_DP_WRITE_MASK, 0 ) ); OUT_RING( 0xffffffff ); ADVANCE_RING(); 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 ); if ( dev_priv->page_flipping && dev_priv->current_page == 1 ) { OUT_RING( dev_priv->front_pitch_offset ); } else { OUT_RING( dev_priv->back_pitch_offset ); } OUT_RING( color ); OUT_RING( (x << 16) | y ); OUT_RING( (w << 16) | h ); ADVANCE_RING();}static void radeon_cp_performance_boxes( drm_radeon_private_t *dev_priv ){ /* Collapse various things into a wait flag -- trying to * guess if userspase slept -- better just to have them tell us. */ if (dev_priv->stats.last_frame_reads > 1 || dev_priv->stats.last_clear_reads > dev_priv->stats.clears) { dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE; } if (dev_priv->stats.freelist_loops) { dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE; } /* Purple box for page flipping */ if ( dev_priv->stats.boxes & RADEON_BOX_FLIP ) radeon_clear_box( dev_priv, 4, 4, 8, 8, 255, 0, 255 ); /* Red box if we have to wait for idle at any point */ if ( dev_priv->stats.boxes & RADEON_BOX_WAIT_IDLE ) radeon_clear_box( dev_priv, 16, 4, 8, 8, 255, 0, 0 ); /* Blue box: lost context? */ /* Yellow box for texture swaps */ if ( dev_priv->stats.boxes & RADEON_BOX_TEXTURE_LOAD ) radeon_clear_box( dev_priv, 40, 4, 8, 8, 255, 255, 0 ); /* Green box if hardware never idles (as far as we can tell) */ if ( !(dev_priv->stats.boxes & RADEON_BOX_DMA_IDLE) ) radeon_clear_box( dev_priv, 64, 4, 8, 8, 0, 255, 0 ); /* Draw bars indicating number of buffers allocated * (not a great measure, easily confused) */ if (dev_priv->stats.requested_bufs) { if (dev_priv->stats.requested_bufs > 100) dev_priv->stats.requested_bufs = 100; radeon_clear_box( dev_priv, 4, 16, dev_priv->stats.requested_bufs, 4, 196, 128, 128 ); } memset( &dev_priv->stats, 0, sizeof(dev_priv->stats) );}/* ================================================================ * CP command dispatch functions */static void radeon_cp_dispatch_clear( drm_device_t *dev, drm_radeon_clear_t *clear, drm_radeon_clear_rect_t *depth_boxes ){ drm_radeon_private_t *dev_priv = dev->dev_private; drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; drm_radeon_depth_clear_t *depth_clear = &dev_priv->depth_clear; int nbox = sarea_priv->nbox; drm_clip_rect_t *pbox = sarea_priv->boxes; unsigned int flags = clear->flags; u32 rb3d_cntl = 0, rb3d_stencilrefmask= 0; int i; RING_LOCALS; DRM_DEBUG( "flags = 0x%x\n", flags ); dev_priv->stats.clears++; 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; } 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->ctx_owner = 0; 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 ) { 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(); } } } /* We have to clear the depth and/or stencil buffers by * rendering a quad into just those buffers. Thus, we have to * make sure the 3D engine is configured correctly. */ if ( dev_priv->is_r200 && (flags & (RADEON_DEPTH | RADEON_STENCIL)) ) { int tempPP_CNTL; int tempRE_CNTL; int tempRB3D_CNTL; int tempRB3D_ZSTENCILCNTL; int tempRB3D_STENCILREFMASK; int tempRB3D_PLANEMASK; int tempSE_CNTL; int tempSE_VTE_CNTL; int tempSE_VTX_FMT_0; int tempSE_VTX_FMT_1; int tempSE_VAP_CNTL; int tempRE_AUX_SCISSOR_CNTL; tempPP_CNTL = 0; tempRE_CNTL = 0; tempRB3D_CNTL = depth_clear->rb3d_cntl; tempRB3D_CNTL &= ~(1<<15); /* unset radeon magic flag */ tempRB3D_ZSTENCILCNTL = depth_clear->rb3d_zstencilcntl; tempRB3D_STENCILREFMASK = 0x0; tempSE_CNTL = depth_clear->se_cntl; /* Disable TCL */ tempSE_VAP_CNTL = (/* SE_VAP_CNTL__FORCE_W_TO_ONE_MASK | */ (0x9 << SE_VAP_CNTL__VF_MAX_VTX_NUM__SHIFT)); tempRB3D_PLANEMASK = 0x0; tempRE_AUX_SCISSOR_CNTL = 0x0; tempSE_VTE_CNTL = SE_VTE_CNTL__VTX_XY_FMT_MASK | SE_VTE_CNTL__VTX_Z_FMT_MASK; /* Vertex format (X, Y, Z, W)*/ tempSE_VTX_FMT_0 = SE_VTX_FMT_0__VTX_Z0_PRESENT_MASK | SE_VTX_FMT_0__VTX_W0_PRESENT_MASK; tempSE_VTX_FMT_1 = 0x0; /* * Depth buffer specific enables */ if (flags & RADEON_DEPTH) { /* Enable depth buffer */ tempRB3D_CNTL |= RADEON_Z_ENABLE; } else { /* Disable depth buffer */ tempRB3D_CNTL &= ~RADEON_Z_ENABLE; } /* * Stencil buffer specific enables */ if ( flags & RADEON_STENCIL ) { tempRB3D_CNTL |= RADEON_STENCIL_ENABLE; tempRB3D_STENCILREFMASK = clear->depth_mask; } else { tempRB3D_CNTL &= ~RADEON_STENCIL_ENABLE; tempRB3D_STENCILREFMASK = 0x00000000; } BEGIN_RING( 26 ); RADEON_WAIT_UNTIL_2D_IDLE(); OUT_RING_REG( RADEON_PP_CNTL, tempPP_CNTL ); OUT_RING_REG( R200_RE_CNTL, tempRE_CNTL ); OUT_RING_REG( RADEON_RB3D_CNTL, tempRB3D_CNTL ); OUT_RING_REG( RADEON_RB3D_ZSTENCILCNTL, tempRB3D_ZSTENCILCNTL ); OUT_RING_REG( RADEON_RB3D_STENCILREFMASK, tempRB3D_STENCILREFMASK ); OUT_RING_REG( RADEON_RB3D_PLANEMASK, tempRB3D_PLANEMASK ); OUT_RING_REG( RADEON_SE_CNTL, tempSE_CNTL ); OUT_RING_REG( R200_SE_VTE_CNTL, tempSE_VTE_CNTL ); OUT_RING_REG( R200_SE_VTX_FMT_0, tempSE_VTX_FMT_0 ); OUT_RING_REG( R200_SE_VTX_FMT_1, tempSE_VTX_FMT_1 ); OUT_RING_REG( R200_SE_VAP_CNTL, tempSE_VAP_CNTL ); OUT_RING_REG( R200_RE_AUX_SCISSOR_CNTL, tempRE_AUX_SCISSOR_CNTL ); ADVANCE_RING(); /* Make sure we restore the 3D state next time. */ dev_priv->sarea_priv->ctx_owner = 0; for ( i = 0 ; i < nbox ; i++ ) { /* Funny that this should be required -- * sets top-left? */ radeon_emit_clip_rect( dev_priv, &sarea_priv->boxes[i] ); BEGIN_RING( 14 ); OUT_RING( CP_PACKET3( R200_3D_DRAW_IMMD_2, 12 ) ); OUT_RING( (RADEON_PRIM_TYPE_RECT_LIST | RADEON_PRIM_WALK_RING | (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( 0x3f800000 ); 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( 0x3f800000 ); OUT_RING( depth_boxes[i].ui[CLEAR_X2] ); OUT_RING( depth_boxes[i].ui[CLEAR_Y2] ); OUT_RING( depth_boxes[i].ui[CLEAR_DEPTH] ); OUT_RING( 0x3f800000 ); ADVANCE_RING(); } } else if ( (flags & (RADEON_DEPTH | RADEON_STENCIL)) ) { rb3d_cntl = depth_clear->rb3d_cntl; if ( flags & RADEON_DEPTH ) { rb3d_cntl |= RADEON_Z_ENABLE; } else { rb3d_cntl &= ~RADEON_Z_ENABLE; } if ( flags & RADEON_STENCIL ) { rb3d_cntl |= RADEON_STENCIL_ENABLE; rb3d_stencilrefmask = clear->depth_mask; /* misnamed field */ } else { rb3d_cntl &= ~RADEON_STENCIL_ENABLE; rb3d_stencilrefmask = 0x00000000; } BEGIN_RING( 13 ); RADEON_WAIT_UNTIL_2D_IDLE(); OUT_RING( CP_PACKET0( RADEON_PP_CNTL, 1 ) ); OUT_RING( 0x00000000 ); OUT_RING( rb3d_cntl ); OUT_RING_REG( RADEON_RB3D_ZSTENCILCNTL, depth_clear->rb3d_zstencilcntl ); OUT_RING_REG( RADEON_RB3D_STENCILREFMASK, rb3d_stencilrefmask ); OUT_RING_REG( RADEON_RB3D_PLANEMASK, 0x00000000 ); OUT_RING_REG( RADEON_SE_CNTL, depth_clear->se_cntl ); ADVANCE_RING(); /* Make sure we restore the 3D state next time. */ dev_priv->sarea_priv->ctx_owner = 0; for ( i = 0 ; i < nbox ; i++ ) { /* Funny that this should be required -- * sets top-left? */ radeon_emit_clip_rect( dev_priv, &sarea_priv->boxes[i] ); BEGIN_RING( 15 ); OUT_RING( CP_PACKET3( RADEON_3D_DRAW_IMMD, 13 ) ); OUT_RING( RADEON_VTX_Z_PRESENT | RADEON_VTX_PKCOLOR_PRESENT); OUT_RING( (RADEON_PRIM_TYPE_RECT_LIST | RADEON_PRIM_WALK_RING | RADEON_MAOS_ENABLE | RADEON_VTX_FMT_RADEON_MODE |
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?