radeon_state.c
来自「linux 内核源代码」· C语言 代码 · 共 2,223 行 · 第 1/5 页
C
2,223 行
drm_radeon_context_regs_t * ctx, drm_radeon_texture_regs_t * tex, unsigned int dirty){ RING_LOCALS; DRM_DEBUG("dirty=0x%08x\n", dirty); if (dirty & RADEON_UPLOAD_CONTEXT) { if (radeon_check_and_fixup_offset(dev_priv, file_priv, &ctx->rb3d_depthoffset)) { DRM_ERROR("Invalid depth buffer offset\n"); return -EINVAL; } if (radeon_check_and_fixup_offset(dev_priv, file_priv, &ctx->rb3d_coloroffset)) { DRM_ERROR("Invalid depth buffer offset\n"); return -EINVAL; } BEGIN_RING(14); OUT_RING(CP_PACKET0(RADEON_PP_MISC, 6)); OUT_RING(ctx->pp_misc); OUT_RING(ctx->pp_fog_color); OUT_RING(ctx->re_solid_color); OUT_RING(ctx->rb3d_blendcntl); OUT_RING(ctx->rb3d_depthoffset); OUT_RING(ctx->rb3d_depthpitch); OUT_RING(ctx->rb3d_zstencilcntl); OUT_RING(CP_PACKET0(RADEON_PP_CNTL, 2)); OUT_RING(ctx->pp_cntl); OUT_RING(ctx->rb3d_cntl); OUT_RING(ctx->rb3d_coloroffset); OUT_RING(CP_PACKET0(RADEON_RB3D_COLORPITCH, 0)); OUT_RING(ctx->rb3d_colorpitch); ADVANCE_RING(); } if (dirty & RADEON_UPLOAD_VERTFMT) { BEGIN_RING(2); OUT_RING(CP_PACKET0(RADEON_SE_COORD_FMT, 0)); OUT_RING(ctx->se_coord_fmt); ADVANCE_RING(); } if (dirty & RADEON_UPLOAD_LINE) { BEGIN_RING(5); OUT_RING(CP_PACKET0(RADEON_RE_LINE_PATTERN, 1)); OUT_RING(ctx->re_line_pattern); OUT_RING(ctx->re_line_state); OUT_RING(CP_PACKET0(RADEON_SE_LINE_WIDTH, 0)); OUT_RING(ctx->se_line_width); ADVANCE_RING(); } if (dirty & RADEON_UPLOAD_BUMPMAP) { BEGIN_RING(5); OUT_RING(CP_PACKET0(RADEON_PP_LUM_MATRIX, 0)); OUT_RING(ctx->pp_lum_matrix); OUT_RING(CP_PACKET0(RADEON_PP_ROT_MATRIX_0, 1)); OUT_RING(ctx->pp_rot_matrix_0); OUT_RING(ctx->pp_rot_matrix_1); ADVANCE_RING(); } if (dirty & RADEON_UPLOAD_MASKS) { BEGIN_RING(4); OUT_RING(CP_PACKET0(RADEON_RB3D_STENCILREFMASK, 2)); OUT_RING(ctx->rb3d_stencilrefmask); OUT_RING(ctx->rb3d_ropcntl); OUT_RING(ctx->rb3d_planemask); ADVANCE_RING(); } if (dirty & RADEON_UPLOAD_VIEWPORT) { BEGIN_RING(7); OUT_RING(CP_PACKET0(RADEON_SE_VPORT_XSCALE, 5)); OUT_RING(ctx->se_vport_xscale); OUT_RING(ctx->se_vport_xoffset); OUT_RING(ctx->se_vport_yscale); OUT_RING(ctx->se_vport_yoffset); OUT_RING(ctx->se_vport_zscale); OUT_RING(ctx->se_vport_zoffset); ADVANCE_RING(); } if (dirty & RADEON_UPLOAD_SETUP) { BEGIN_RING(4); OUT_RING(CP_PACKET0(RADEON_SE_CNTL, 0)); OUT_RING(ctx->se_cntl); OUT_RING(CP_PACKET0(RADEON_SE_CNTL_STATUS, 0)); OUT_RING(ctx->se_cntl_status); ADVANCE_RING(); } if (dirty & RADEON_UPLOAD_MISC) { BEGIN_RING(2); OUT_RING(CP_PACKET0(RADEON_RE_MISC, 0)); OUT_RING(ctx->re_misc); ADVANCE_RING(); } if (dirty & RADEON_UPLOAD_TEX0) { if (radeon_check_and_fixup_offset(dev_priv, file_priv, &tex[0].pp_txoffset)) { DRM_ERROR("Invalid texture offset for unit 0\n"); return -EINVAL; } BEGIN_RING(9); OUT_RING(CP_PACKET0(RADEON_PP_TXFILTER_0, 5)); OUT_RING(tex[0].pp_txfilter); OUT_RING(tex[0].pp_txformat); OUT_RING(tex[0].pp_txoffset); OUT_RING(tex[0].pp_txcblend); OUT_RING(tex[0].pp_txablend); OUT_RING(tex[0].pp_tfactor); OUT_RING(CP_PACKET0(RADEON_PP_BORDER_COLOR_0, 0)); OUT_RING(tex[0].pp_border_color); ADVANCE_RING(); } if (dirty & RADEON_UPLOAD_TEX1) { if (radeon_check_and_fixup_offset(dev_priv, file_priv, &tex[1].pp_txoffset)) { DRM_ERROR("Invalid texture offset for unit 1\n"); return -EINVAL; } BEGIN_RING(9); OUT_RING(CP_PACKET0(RADEON_PP_TXFILTER_1, 5)); OUT_RING(tex[1].pp_txfilter); OUT_RING(tex[1].pp_txformat); OUT_RING(tex[1].pp_txoffset); OUT_RING(tex[1].pp_txcblend); OUT_RING(tex[1].pp_txablend); OUT_RING(tex[1].pp_tfactor); OUT_RING(CP_PACKET0(RADEON_PP_BORDER_COLOR_1, 0)); OUT_RING(tex[1].pp_border_color); ADVANCE_RING(); } if (dirty & RADEON_UPLOAD_TEX2) { if (radeon_check_and_fixup_offset(dev_priv, file_priv, &tex[2].pp_txoffset)) { DRM_ERROR("Invalid texture offset for unit 2\n"); return -EINVAL; } BEGIN_RING(9); OUT_RING(CP_PACKET0(RADEON_PP_TXFILTER_2, 5)); OUT_RING(tex[2].pp_txfilter); OUT_RING(tex[2].pp_txformat); OUT_RING(tex[2].pp_txoffset); OUT_RING(tex[2].pp_txcblend); OUT_RING(tex[2].pp_txablend); OUT_RING(tex[2].pp_tfactor); OUT_RING(CP_PACKET0(RADEON_PP_BORDER_COLOR_2, 0)); OUT_RING(tex[2].pp_border_color); ADVANCE_RING(); } return 0;}/* Emit 1.2 state */static int radeon_emit_state2(drm_radeon_private_t * dev_priv, struct drm_file *file_priv, drm_radeon_state_t * state){ RING_LOCALS; if (state->dirty & RADEON_UPLOAD_ZBIAS) { BEGIN_RING(3); OUT_RING(CP_PACKET0(RADEON_SE_ZBIAS_FACTOR, 1)); OUT_RING(state->context2.se_zbias_factor); OUT_RING(state->context2.se_zbias_constant); ADVANCE_RING(); } return radeon_emit_state(dev_priv, file_priv, &state->context, state->tex, state->dirty);}/* 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"}, {R200_SE_TCL_POINT_SPRITE_CNTL, 1, "R200_SE_TCL_POINT_SPRITE_CNTL"}, {RADEON_PP_CUBIC_FACES_0, 1, "RADEON_PP_CUBIC_FACES_0"}, {RADEON_PP_CUBIC_OFFSET_T0_0, 5, "RADEON_PP_CUBIC_OFFSET_T0_0"}, {RADEON_PP_CUBIC_FACES_1, 1, "RADEON_PP_CUBIC_FACES_1"}, {RADEON_PP_CUBIC_OFFSET_T1_0, 5, "RADEON_PP_CUBIC_OFFSET_T1_0"}, {RADEON_PP_CUBIC_FACES_2, 1, "RADEON_PP_CUBIC_FACES_2"}, {RADEON_PP_CUBIC_OFFSET_T2_0, 5, "RADEON_PP_CUBIC_OFFSET_T2_0"}, {R200_PP_TRI_PERF, 2, "R200_PP_TRI_PERF"}, {R200_PP_AFS_0, 32, "R200_PP_AFS_0"}, /* 85 */ {R200_PP_AFS_1, 32, "R200_PP_AFS_1"}, {R200_PP_TFACTOR_0, 8, "R200_ATF_TFACTOR"}, {R200_PP_TXFILTER_0, 8, "R200_PP_TXCTLALL_0"}, {R200_PP_TXFILTER_1, 8, "R200_PP_TXCTLALL_1"}, {R200_PP_TXFILTER_2, 8, "R200_PP_TXCTLALL_2"}, {R200_PP_TXFILTER_3, 8, "R200_PP_TXCTLALL_3"}, {R200_PP_TXFILTER_4, 8, "R200_PP_TXCTLALL_4"}, {R200_PP_TXFILTER_5, 8, "R200_PP_TXCTLALL_5"}, {R200_VAP_PVS_CNTL_1, 2, "R200_VAP_PVS_CNTL"},};/* ================================================================ * 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->sarea_priv->pfCurrentPage == 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(struct drm_device * 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; struct drm_clip_rect *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->sarea_priv->pfCurrentPage == 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();
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?