📄 radeon_state.c
字号:
directly address/clear 4x4 tiles instead of 8x2 * 4x4 macro tiles, though would still need clear mask for right/bottom if truely 4x4 granularity is desired ? */ OUT_RING( tileoffset * 16 ); /* the number of tiles to clear */ OUT_RING( nrtilesx + 1 ); /* clear mask : chooses the clearing pattern. */ OUT_RING( clearmask ); ADVANCE_RING(); tileoffset += depthpixperline >> 5; } } else { /* rv 100 */ /* rv100 might not need 64 pix alignment, who knows */ /* offsets are, hmm, weird */ tileoffset = ((pbox[i].y1 >> 4) * depthpixperline + pbox[i].x1) >> 6; nrtilesx = ((pbox[i].x2 & ~63) - (pbox[i].x1 & ~63)) >> 4; nrtilesy = (pbox[i].y2 >> 4) - (pbox[i].y1 >> 4); for (j = 0; j <= nrtilesy; j++) { BEGIN_RING( 4 ); OUT_RING( CP_PACKET3( RADEON_3D_CLEAR_ZMASK, 2 ) ); OUT_RING( tileoffset * 128 ); /* the number of tiles to clear */ OUT_RING( nrtilesx + 4 ); /* clear mask : chooses the clearing pattern. */ OUT_RING( clearmask ); ADVANCE_RING(); tileoffset += depthpixperline >> 6; } } } /* TODO don't always clear all hi-level z tiles */ if ((dev_priv->flags & CHIP_HAS_HIERZ) && (dev_priv->microcode_version==UCODE_R200) && (flags & RADEON_USE_HIERZ)) /* r100 and cards without hierarchical z-buffer have no high-level z-buffer */ /* FIXME : the mask supposedly contains low-res z values. So can't set just to the max (0xff? or actually 0x3fff?), need to take z clear value into account? */ { BEGIN_RING( 4 ); OUT_RING( CP_PACKET3( RADEON_3D_CLEAR_HIZ, 2 ) ); OUT_RING( 0x0 ); /* First tile */ OUT_RING( 0x3cc0 ); OUT_RING( (0xff<<22)|(0xff<<6)| 0x003f003f); 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->microcode_version == UCODE_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_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; } if (flags & RADEON_USE_COMP_ZBUF) { tempRB3D_ZSTENCILCNTL |= RADEON_Z_COMPRESSION_ENABLE | RADEON_Z_DECOMPRESSION_ENABLE; } if (flags & RADEON_USE_HIERZ) { tempRB3D_ZSTENCILCNTL |= RADEON_Z_HIERARCHY_ENABLE; } 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)) ) { int tempRB3D_ZSTENCILCNTL = depth_clear->rb3d_zstencilcntl; 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; } if (flags & RADEON_USE_COMP_ZBUF) { tempRB3D_ZSTENCILCNTL |= RADEON_Z_COMPRESSION_ENABLE | RADEON_Z_DECOMPRESSION_ENABLE; } if (flags & RADEON_USE_HIERZ) { tempRB3D_ZSTENCILCNTL |= RADEON_Z_HIERARCHY_ENABLE; } 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, tempRB3D_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 | (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( 0x0 ); 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( 0x0 ); 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( 0x0 ); ADVANCE_RING(); } } /* 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( "\n" ); /* Do some trivial performance monitoring... */ if (dev_priv->do_boxes) radeon_cp_performance_boxes( dev_priv ); /* 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 ); /* Make this work even if front & back are flipped: */ if (dev_priv->current_page == 0) { OUT_RING( dev_priv->back_pitch_offset ); OUT_RING( dev_priv->front_pitch_offset ); } else { OUT_RING( dev_priv->front_pitch_offset ); OUT_RING( dev_priv->back_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; drm_sarea_t *sarea = (drm_sarea_t *)dev_priv->sarea->handle; int offset = (dev_priv->current_page == 1) ? dev_priv->front_offset : dev_priv->back_offset; RING_LOCALS; DRM_DEBUG( "%s: page=%d pfCurrentPage=%d\n", __FUNCTION__, dev_priv->current_page, dev_priv->sarea_priv->pfCurrentPage); /* Do some trivial performance monitoring... */ if (dev_priv->do_boxes) { dev_priv->stats.boxes |= RADEON_BOX_FLIP; radeon_cp_performance_boxes( dev_priv ); } /* Update the frame offsets for both CRTCs */ BEGIN_RING( 6 ); RADEON_WAIT_UNTIL_3D_IDLE(); OUT_RING_REG( RADEON_CRTC_OFFSET, ( ( sarea->frame.y * dev_priv->front_pitch + sarea->frame.x * ( dev_priv->color_fmt - 2 ) ) & ~7 ) + offset ); OUT_RING_REG( RADEON_CRTC2_OFFSET, dev_priv->sarea_priv->crtc2_base + offset ); 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++; dev_priv->sarea_priv->pfCurrentPage = dev_priv->current_page = 1 - dev_priv->current_page; BEGIN_RING( 2 ); RADEON_FRAME_AGE( dev_priv->sarea_priv->last_frame ); ADVANCE_RING();}static int bad_prim_vertex_nr( int primitive, int nr ){ switch (primitive & RADEON_PRIM_TYPE_MASK) { case RADEON_PRIM_TYPE_NONE: case RADEON_PRIM_TYPE_POINT: return nr < 1; case RADEON_PRIM_TYPE_LINE: return (nr & 1) || nr == 0; case RADEON_PRIM_TYPE_LINE_STRIP: return nr < 2; case RADEON_PRIM_TYPE_TRI_LIST: case RADEON_PRIM_TYPE_3VRT_POINT_LIST: case RADEON_PRIM_TYPE_3VRT_LINE_LIST: case RADEON_PRIM_TYPE_RECT_LIST: return nr % 3 || nr == 0; case RADEON_PRIM_TYPE_TRI_FAN: case RADEON_PRIM_TYPE_TRI_STRIP: return nr < 3; default: return 1; } }typedef struct { unsigned int start; unsigned int finish; unsigned int prim; unsigned int numverts; unsigned int offset;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -