📄 radeon_state.c
字号:
/* radeon_state.c -- State support for Radeon -*- linux-c -*- * * Copyright 2000 VA Linux Systems, Inc., Fremont, California. * All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. * * Authors: * Kevin E. Martin <martin@valinux.com> * Gareth Hughes <gareth@valinux.com> * */#define __NO_VERSION__#include "drmP.h"#include "radeon_drv.h"#include "drm.h"#include <linux/delay.h>/* ================================================================ * CP hardware state programming functions */static inline void radeon_emit_clip_rect( drm_radeon_private_t *dev_priv, drm_clip_rect_t *box ){ RING_LOCALS; DRM_DEBUG( " box: x1=%d y1=%d x2=%d y2=%d\n", box->x1, box->y1, box->x2, box->y2 ); BEGIN_RING( 4 ); OUT_RING( CP_PACKET0( RADEON_RE_TOP_LEFT, 0 ) ); OUT_RING( (box->y1 << 16) | box->x1 ); OUT_RING( CP_PACKET0( RADEON_RE_WIDTH_HEIGHT, 0 ) ); OUT_RING( ((box->y2 - 1) << 16) | (box->x2 - 1) ); ADVANCE_RING();}static inline void radeon_emit_context( drm_radeon_private_t *dev_priv ){ drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; drm_radeon_context_regs_t *ctx = &sarea_priv->context_state; RING_LOCALS; DRM_DEBUG( " %s\n", __FUNCTION__ ); 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();}static inline void radeon_emit_vertfmt( drm_radeon_private_t *dev_priv ){ drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; drm_radeon_context_regs_t *ctx = &sarea_priv->context_state; RING_LOCALS; DRM_DEBUG( " %s\n", __FUNCTION__ ); BEGIN_RING( 2 ); OUT_RING( CP_PACKET0( RADEON_SE_COORD_FMT, 0 ) ); OUT_RING( ctx->se_coord_fmt ); ADVANCE_RING();}static inline void radeon_emit_line( drm_radeon_private_t *dev_priv ){ drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; drm_radeon_context_regs_t *ctx = &sarea_priv->context_state; RING_LOCALS; DRM_DEBUG( " %s\n", __FUNCTION__ ); 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();}static inline void radeon_emit_bumpmap( drm_radeon_private_t *dev_priv ){ drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; drm_radeon_context_regs_t *ctx = &sarea_priv->context_state; RING_LOCALS; DRM_DEBUG( " %s\n", __FUNCTION__ ); 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();}static inline void radeon_emit_masks( drm_radeon_private_t *dev_priv ){ drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; drm_radeon_context_regs_t *ctx = &sarea_priv->context_state; RING_LOCALS; DRM_DEBUG( " %s\n", __FUNCTION__ ); 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();}static inline void radeon_emit_viewport( drm_radeon_private_t *dev_priv ){ drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; drm_radeon_context_regs_t *ctx = &sarea_priv->context_state; RING_LOCALS; DRM_DEBUG( " %s\n", __FUNCTION__ ); 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();}static inline void radeon_emit_setup( drm_radeon_private_t *dev_priv ){ drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; drm_radeon_context_regs_t *ctx = &sarea_priv->context_state; RING_LOCALS; DRM_DEBUG( " %s\n", __FUNCTION__ ); 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();}static inline void radeon_emit_tcl( drm_radeon_private_t *dev_priv ){#ifdef TCL_ENABLE drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; drm_radeon_context_regs_t *ctx = &sarea_priv->context_state; RING_LOCALS; DRM_DEBUG( " %s\n", __FUNCTION__ ); BEGIN_RING( 29 ); OUT_RING( CP_PACKET0( RADEON_SE_TCL_MATERIAL_EMMISSIVE_RED, 27 ) ); OUT_RING( ctx->se_tcl_material_emmissive.red ); OUT_RING( ctx->se_tcl_material_emmissive.green ); OUT_RING( ctx->se_tcl_material_emmissive.blue ); OUT_RING( ctx->se_tcl_material_emmissive.alpha ); OUT_RING( ctx->se_tcl_material_ambient.red ); OUT_RING( ctx->se_tcl_material_ambient.green ); OUT_RING( ctx->se_tcl_material_ambient.blue ); OUT_RING( ctx->se_tcl_material_ambient.alpha ); OUT_RING( ctx->se_tcl_material_diffuse.red ); OUT_RING( ctx->se_tcl_material_diffuse.green ); OUT_RING( ctx->se_tcl_material_diffuse.blue ); OUT_RING( ctx->se_tcl_material_diffuse.alpha ); OUT_RING( ctx->se_tcl_material_specular.red ); OUT_RING( ctx->se_tcl_material_specular.green ); OUT_RING( ctx->se_tcl_material_specular.blue ); OUT_RING( ctx->se_tcl_material_specular.alpha ); OUT_RING( ctx->se_tcl_shininess ); OUT_RING( ctx->se_tcl_output_vtx_fmt ); OUT_RING( ctx->se_tcl_output_vtx_sel ); OUT_RING( ctx->se_tcl_matrix_select_0 ); OUT_RING( ctx->se_tcl_matrix_select_1 ); OUT_RING( ctx->se_tcl_ucp_vert_blend_ctl ); OUT_RING( ctx->se_tcl_texture_proc_ctl ); OUT_RING( ctx->se_tcl_light_model_ctl ); for ( i = 0 ; i < 4 ; i++ ) { OUT_RING( ctx->se_tcl_per_light_ctl[i] ); } ADVANCE_RING();#else DRM_ERROR( "TCL not enabled!\n" );#endif}static inline void radeon_emit_misc( drm_radeon_private_t *dev_priv ){ drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; drm_radeon_context_regs_t *ctx = &sarea_priv->context_state; RING_LOCALS; DRM_DEBUG( " %s\n", __FUNCTION__ ); BEGIN_RING( 2 ); OUT_RING( CP_PACKET0( RADEON_RE_MISC, 0 ) ); OUT_RING( ctx->re_misc ); ADVANCE_RING();}static inline void radeon_emit_tex0( drm_radeon_private_t *dev_priv ){ drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; drm_radeon_texture_regs_t *tex = &sarea_priv->tex_state[0]; RING_LOCALS; DRM_DEBUG( " %s: offset=0x%x\n", __FUNCTION__, tex->pp_txoffset ); BEGIN_RING( 9 ); OUT_RING( CP_PACKET0( RADEON_PP_TXFILTER_0, 5 ) ); OUT_RING( tex->pp_txfilter ); OUT_RING( tex->pp_txformat ); OUT_RING( tex->pp_txoffset ); OUT_RING( tex->pp_txcblend ); OUT_RING( tex->pp_txablend ); OUT_RING( tex->pp_tfactor ); OUT_RING( CP_PACKET0( RADEON_PP_BORDER_COLOR_0, 0 ) ); OUT_RING( tex->pp_border_color ); ADVANCE_RING();}static inline void radeon_emit_tex1( drm_radeon_private_t *dev_priv ){ drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; drm_radeon_texture_regs_t *tex = &sarea_priv->tex_state[1]; RING_LOCALS; DRM_DEBUG( " %s: offset=0x%x\n", __FUNCTION__, tex->pp_txoffset ); BEGIN_RING( 9 ); OUT_RING( CP_PACKET0( RADEON_PP_TXFILTER_1, 5 ) ); OUT_RING( tex->pp_txfilter ); OUT_RING( tex->pp_txformat ); OUT_RING( tex->pp_txoffset ); OUT_RING( tex->pp_txcblend ); OUT_RING( tex->pp_txablend ); OUT_RING( tex->pp_tfactor ); OUT_RING( CP_PACKET0( RADEON_PP_BORDER_COLOR_1, 0 ) ); OUT_RING( tex->pp_border_color ); ADVANCE_RING();}static inline void radeon_emit_tex2( drm_radeon_private_t *dev_priv ){ drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; drm_radeon_texture_regs_t *tex = &sarea_priv->tex_state[2]; RING_LOCALS; DRM_DEBUG( " %s\n", __FUNCTION__ ); BEGIN_RING( 9 ); OUT_RING( CP_PACKET0( RADEON_PP_TXFILTER_2, 5 ) ); OUT_RING( tex->pp_txfilter ); OUT_RING( tex->pp_txformat ); OUT_RING( tex->pp_txoffset ); OUT_RING( tex->pp_txcblend ); OUT_RING( tex->pp_txablend ); OUT_RING( tex->pp_tfactor ); OUT_RING( CP_PACKET0( RADEON_PP_BORDER_COLOR_2, 0 ) ); OUT_RING( tex->pp_border_color ); ADVANCE_RING();}static inline void radeon_emit_state( drm_radeon_private_t *dev_priv ){ drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; unsigned int dirty = sarea_priv->dirty; DRM_DEBUG( "%s: dirty=0x%08x\n", __FUNCTION__, dirty ); if ( dirty & RADEON_UPLOAD_CONTEXT ) { radeon_emit_context( dev_priv ); sarea_priv->dirty &= ~RADEON_UPLOAD_CONTEXT; } if ( dirty & RADEON_UPLOAD_VERTFMT ) { radeon_emit_vertfmt( dev_priv ); sarea_priv->dirty &= ~RADEON_UPLOAD_VERTFMT; } if ( dirty & RADEON_UPLOAD_LINE ) { radeon_emit_line( dev_priv ); sarea_priv->dirty &= ~RADEON_UPLOAD_LINE; } if ( dirty & RADEON_UPLOAD_BUMPMAP ) { radeon_emit_bumpmap( dev_priv ); sarea_priv->dirty &= ~RADEON_UPLOAD_BUMPMAP; } if ( dirty & RADEON_UPLOAD_MASKS ) { radeon_emit_masks( dev_priv ); sarea_priv->dirty &= ~RADEON_UPLOAD_MASKS; } if ( dirty & RADEON_UPLOAD_VIEWPORT ) { radeon_emit_viewport( dev_priv ); sarea_priv->dirty &= ~RADEON_UPLOAD_VIEWPORT; } if ( dirty & RADEON_UPLOAD_SETUP ) { radeon_emit_setup( dev_priv ); sarea_priv->dirty &= ~RADEON_UPLOAD_SETUP; } if ( dirty & RADEON_UPLOAD_TCL ) {#ifdef TCL_ENABLE radeon_emit_tcl( dev_priv );#endif sarea_priv->dirty &= ~RADEON_UPLOAD_TCL; } if ( dirty & RADEON_UPLOAD_MISC ) { radeon_emit_misc( dev_priv ); sarea_priv->dirty &= ~RADEON_UPLOAD_MISC; } if ( dirty & RADEON_UPLOAD_TEX0 ) { radeon_emit_tex0( dev_priv ); sarea_priv->dirty &= ~RADEON_UPLOAD_TEX0; } if ( dirty & RADEON_UPLOAD_TEX1 ) { radeon_emit_tex1( dev_priv ); sarea_priv->dirty &= ~RADEON_UPLOAD_TEX1; } if ( dirty & RADEON_UPLOAD_TEX2 ) {#if 0 radeon_emit_tex2( dev_priv );#endif sarea_priv->dirty &= ~RADEON_UPLOAD_TEX2; } sarea_priv->dirty &= ~(RADEON_UPLOAD_TEX0IMAGES | RADEON_UPLOAD_TEX1IMAGES | RADEON_UPLOAD_TEX2IMAGES | RADEON_REQUIRE_QUIESCENCE);}#if RADEON_PERFORMANCE_BOXES/* ================================================================ * 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 pitch, offset; u32 color; RING_LOCALS; 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; } offset = dev_priv->back_offset; pitch = dev_priv->back_pitch >> 3; 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( (pitch << 22) | (offset >> 5) ); 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 ){ if ( atomic_read( &dev_priv->idle_count ) == 0 ) { radeon_clear_box( dev_priv, 64, 4, 8, 8, 0, 255, 0 ); } else { atomic_set( &dev_priv->idle_count, 0 ); }}#endif/* ================================================================ * CP command dispatch functions */static void radeon_print_dirty( const char *msg, unsigned int flags ){ DRM_DEBUG( "%s: (0x%x) %s%s%s%s%s%s%s%s%s%s%s%s%s%s\n", msg, flags, (flags & RADEON_UPLOAD_CONTEXT) ? "context, " : "", (flags & RADEON_UPLOAD_VERTFMT) ? "vertfmt, " : "", (flags & RADEON_UPLOAD_LINE) ? "line, " : "", (flags & RADEON_UPLOAD_BUMPMAP) ? "bumpmap, " : "", (flags & RADEON_UPLOAD_MASKS) ? "masks, " : "", (flags & RADEON_UPLOAD_VIEWPORT) ? "viewport, " : "", (flags & RADEON_UPLOAD_SETUP) ? "setup, " : "", (flags & RADEON_UPLOAD_TCL) ? "tcl, " : "", (flags & RADEON_UPLOAD_MISC) ? "misc, " : "", (flags & RADEON_UPLOAD_TEX0) ? "tex0, " : "", (flags & RADEON_UPLOAD_TEX1) ? "tex1, " : "", (flags & RADEON_UPLOAD_TEX2) ? "tex2, " : "",
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -