From 71897876f193282dd49d3eb37f277377a3ec8bb2 Mon Sep 17 00:00:00 2001 From: Gareth Hughes Date: Thu, 4 Jan 2001 19:59:46 +0000 Subject: - Fix subpixel precision errors. - Fix software alpha buffer initialization. - Clean up depth clears, fixes SoF and H2 bugs. --- linux-core/radeon_drv.c | 2 +- linux/radeon_cp.c | 52 ++++++++++++++++++++++++++-- linux/radeon_drv.c | 2 +- linux/radeon_drv.h | 16 +++++++-- linux/radeon_state.c | 91 +++++++++++-------------------------------------- 5 files changed, 86 insertions(+), 77 deletions(-) diff --git a/linux-core/radeon_drv.c b/linux-core/radeon_drv.c index c9bb3eeaf..0113ed97c 100644 --- a/linux-core/radeon_drv.c +++ b/linux-core/radeon_drv.c @@ -34,7 +34,7 @@ #define RADEON_NAME "radeon" #define RADEON_DESC "ATI Radeon" -#define RADEON_DATE "20010103" +#define RADEON_DATE "20010105" #define RADEON_MAJOR 1 #define RADEON_MINOR 0 #define RADEON_PATCHLEVEL 0 diff --git a/linux/radeon_cp.c b/linux/radeon_cp.c index 0df883c67..5d662bc08 100644 --- a/linux/radeon_cp.c +++ b/linux/radeon_cp.c @@ -667,13 +667,29 @@ static int radeon_do_init_cp( drm_device_t *dev, drm_radeon_init_t *init ) return -EINVAL; } - dev_priv->fb_bpp = init->fb_bpp; + switch ( init->fb_bpp ) { + case 16: + dev_priv->color_fmt = RADEON_COLOR_FORMAT_RGB565; + break; + case 32: + default: + dev_priv->color_fmt = RADEON_COLOR_FORMAT_ARGB8888; + break; + } dev_priv->front_offset = init->front_offset; dev_priv->front_pitch = init->front_pitch; dev_priv->back_offset = init->back_offset; dev_priv->back_pitch = init->back_pitch; - dev_priv->depth_bpp = init->depth_bpp; + switch ( init->depth_bpp ) { + case 16: + dev_priv->depth_fmt = RADEON_DEPTH_FORMAT_16BIT_INT_Z; + break; + case 32: + default: + dev_priv->depth_fmt = RADEON_DEPTH_FORMAT_24BIT_INT_Z; + break; + } dev_priv->depth_offset = init->depth_offset; dev_priv->depth_pitch = init->depth_pitch; @@ -684,6 +700,38 @@ static int radeon_do_init_cp( drm_device_t *dev, drm_radeon_init_t *init ) dev_priv->depth_pitch_offset = (((dev_priv->depth_pitch/64) << 22) | (dev_priv->depth_offset >> 10)); + /* Hardware state for depth clears. Remove this if/when we no + * longer clear the depth buffer with a 3D rectangle. Hard-code + * all values to prevent unwanted 3D state from slipping through + * and screwing with the clear operation. + */ + dev_priv->depth_clear.rb3d_cntl = (RADEON_PLANE_MASK_ENABLE | + RADEON_Z_ENABLE | + (dev_priv->color_fmt << 10) | + RADEON_ZBLOCK16); + + dev_priv->depth_clear.rb3d_zstencilcntl = (dev_priv->depth_fmt | + RADEON_Z_TEST_ALWAYS | + RADEON_STENCIL_TEST_ALWAYS | + RADEON_STENCIL_S_FAIL_KEEP | + RADEON_STENCIL_ZPASS_KEEP | + RADEON_STENCIL_ZFAIL_KEEP | + RADEON_Z_WRITE_ENABLE); + + dev_priv->depth_clear.se_cntl = (RADEON_FFACE_CULL_CW | + RADEON_BFACE_SOLID | + RADEON_FFACE_SOLID | + RADEON_FLAT_SHADE_VTX_LAST | + + RADEON_DIFFUSE_SHADE_FLAT | + RADEON_ALPHA_SHADE_FLAT | + RADEON_SPECULAR_SHADE_FLAT | + RADEON_FOG_SHADE_FLAT | + + RADEON_VTX_PIX_CENTER_OGL | + RADEON_ROUND_MODE_TRUNC | + RADEON_ROUND_PREC_8TH_PIX); + /* FIXME: We want multiple shared areas, including one shared * only by the X Server and kernel module. */ diff --git a/linux/radeon_drv.c b/linux/radeon_drv.c index c9bb3eeaf..0113ed97c 100644 --- a/linux/radeon_drv.c +++ b/linux/radeon_drv.c @@ -34,7 +34,7 @@ #define RADEON_NAME "radeon" #define RADEON_DESC "ATI Radeon" -#define RADEON_DATE "20010103" +#define RADEON_DATE "20010105" #define RADEON_MAJOR 1 #define RADEON_MINOR 0 #define RADEON_PATCHLEVEL 0 diff --git a/linux/radeon_drv.h b/linux/radeon_drv.h index 985ebc7ed..06b541991 100644 --- a/linux/radeon_drv.h +++ b/linux/radeon_drv.h @@ -52,6 +52,12 @@ typedef struct drm_radeon_ring_buffer { int space; } drm_radeon_ring_buffer_t; +typedef struct drm_radeon_depth_clear_t { + u32 rb3d_cntl; + u32 rb3d_zstencilcntl; + u32 se_cntl; +} drm_radeon_depth_clear_t; + typedef struct drm_radeon_private { drm_radeon_ring_buffer_t ring; drm_radeon_sarea_t *sarea_priv; @@ -85,13 +91,13 @@ typedef struct drm_radeon_private { u32 crtc_offset; u32 crtc_offset_cntl; - unsigned int fb_bpp; + unsigned int color_fmt; unsigned int front_offset; unsigned int front_pitch; unsigned int back_offset; unsigned int back_pitch; - unsigned int depth_bpp; + unsigned int depth_fmt; unsigned int depth_offset; unsigned int depth_pitch; @@ -99,6 +105,8 @@ typedef struct drm_radeon_private { u32 back_pitch_offset; u32 depth_pitch_offset; + drm_radeon_depth_clear_t depth_clear; + drm_map_t *sarea; drm_map_t *fb; drm_map_t *mmio; @@ -353,9 +361,13 @@ extern int radeon_context_switch_complete(drm_device_t *dev, int new); # define RADEON_BFACE_SOLID (3 << 1) # define RADEON_FFACE_SOLID (3 << 3) # define RADEON_FLAT_SHADE_VTX_LAST (3 << 6) +# define RADEON_DIFFUSE_SHADE_FLAT (1 << 8) # define RADEON_DIFFUSE_SHADE_GOURAUD (2 << 8) +# define RADEON_ALPHA_SHADE_FLAT (1 << 10) # define RADEON_ALPHA_SHADE_GOURAUD (2 << 10) +# define RADEON_SPECULAR_SHADE_FLAT (1 << 12) # define RADEON_SPECULAR_SHADE_GOURAUD (2 << 12) +# define RADEON_FOG_SHADE_FLAT (1 << 14) # define RADEON_FOG_SHADE_GOURAUD (2 << 14) # define RADEON_VPORT_XY_XFORM_ENABLE (1 << 24) # define RADEON_VPORT_Z_XFORM_ENABLE (1 << 25) diff --git a/linux/radeon_state.c b/linux/radeon_state.c index a7bbaf074..12bd6c796 100644 --- a/linux/radeon_state.c +++ b/linux/radeon_state.c @@ -411,19 +411,17 @@ static void radeon_clear_box( drm_radeon_private_t *dev_priv, int r, int g, int b ) { u32 pitch, offset; - u32 fb_bpp, color; + u32 color; RING_LOCALS; - switch ( dev_priv->fb_bpp ) { - case 16: - fb_bpp = RADEON_GMC_DST_16BPP; + switch ( dev_priv->color_fmt ) { + case RADEON_COLOR_FORMAT_RGB565: color = (((r & 0xf8) << 8) | ((g & 0xfc) << 3) | ((b & 0xf8) >> 3)); break; - case 32: + case RADEON_COLOR_FORMAT_ARGB8888: default: - fb_bpp = RADEON_GMC_DST_32BPP; color = (((0xff) << 24) | (r << 16) | (g << 8) | b); break; } @@ -436,7 +434,7 @@ static void radeon_clear_box( drm_radeon_private_t *dev_priv, OUT_RING( CP_PACKET3( RADEON_CNTL_PAINT_MULTI, 4 ) ); OUT_RING( RADEON_GMC_DST_PITCH_OFFSET_CNTL | RADEON_GMC_BRUSH_SOLID_COLOR | - fb_bpp | + (dev_priv->color_fmt << 8) | RADEON_GMC_SRC_DATATYPE_COLOR | RADEON_ROP3_P | RADEON_GMC_CLR_CMP_CNTL_DIS ); @@ -495,33 +493,12 @@ static void radeon_cp_dispatch_clear( drm_device_t *dev, int nbox = sarea_priv->nbox; drm_clip_rect_t *pbox = sarea_priv->boxes; unsigned int flags = clear->flags; - u32 fb_bpp, depth_bpp; int i; RING_LOCALS; DRM_DEBUG( "%s\n", __FUNCTION__ ); radeon_update_ring_snapshot( dev_priv ); - switch ( dev_priv->fb_bpp ) { - case 16: - fb_bpp = RADEON_GMC_DST_16BPP; - break; - case 32: - default: - fb_bpp = RADEON_GMC_DST_32BPP; - break; - } - switch ( dev_priv->depth_bpp ) { - case 16: - depth_bpp = RADEON_GMC_DST_16BPP; - break; - case 32: - depth_bpp = RADEON_GMC_DST_32BPP; - break; - default: - return; - } - if ( dev_priv->page_flipping && dev_priv->current_page == 1 ) { unsigned int tmp = flags; @@ -537,8 +514,7 @@ static void radeon_cp_dispatch_clear( drm_device_t *dev, int h = pbox[i].y2 - y; DRM_DEBUG( "dispatch clear %d,%d-%d,%d flags 0x%x\n", - pbox[i].x1, pbox[i].y1, pbox[i].x2, - pbox[i].y2, flags ); + x, y, w, h, flags ); if ( flags & (RADEON_FRONT | RADEON_BACK) ) { BEGIN_RING( 4 ); @@ -565,7 +541,7 @@ static void radeon_cp_dispatch_clear( drm_device_t *dev, OUT_RING( CP_PACKET3( RADEON_CNTL_PAINT_MULTI, 4 ) ); OUT_RING( RADEON_GMC_DST_PITCH_OFFSET_CNTL | RADEON_GMC_BRUSH_SOLID_COLOR | - fb_bpp | + (dev_priv->color_fmt << 8) | RADEON_GMC_SRC_DATATYPE_COLOR | RADEON_ROP3_P | RADEON_GMC_CLR_CMP_CNTL_DIS ); @@ -585,7 +561,7 @@ static void radeon_cp_dispatch_clear( drm_device_t *dev, OUT_RING( CP_PACKET3( RADEON_CNTL_PAINT_MULTI, 4 ) ); OUT_RING( RADEON_GMC_DST_PITCH_OFFSET_CNTL | RADEON_GMC_BRUSH_SOLID_COLOR | - fb_bpp | + (dev_priv->color_fmt << 8) | RADEON_GMC_SRC_DATATYPE_COLOR | RADEON_ROP3_P | RADEON_GMC_CLR_CMP_CNTL_DIS ); @@ -597,49 +573,33 @@ static void radeon_cp_dispatch_clear( drm_device_t *dev, OUT_RING( (w << 16) | h ); ADVANCE_RING(); + } if ( flags & RADEON_DEPTH ) { - drm_radeon_context_regs_t *ctx = - &sarea_priv->context_state; - u32 rb3d_cntl = ctx->rb3d_cntl; - u32 rb3d_zstencilcntl = ctx->rb3d_zstencilcntl; - u32 se_cntl = ctx->se_cntl; + drm_radeon_depth_clear_t *depth_clear = + &dev_priv->depth_clear; if ( sarea_priv->dirty & ~RADEON_UPLOAD_CLIPRECTS ) { radeon_emit_state( dev_priv ); } - /* FIXME: Do re really need to do this? Why - * not just precalculate all the values? - */ - rb3d_cntl |= (RADEON_PLANE_MASK_ENABLE | - RADEON_Z_ENABLE); - - rb3d_zstencilcntl |= (RADEON_Z_TEST_ALWAYS | - RADEON_Z_WRITE_ENABLE); - - se_cntl &= ~(RADEON_VPORT_XY_XFORM_ENABLE | - RADEON_VPORT_Z_XFORM_ENABLE); - se_cntl |= (RADEON_FFACE_SOLID | - RADEON_BFACE_SOLID); - /* FIXME: Render a rectangle to clear the depth * buffer. So much for those "fast Z clears"... */ - BEGIN_RING( 22 ); + BEGIN_RING( 23 ); RADEON_WAIT_UNTIL_2D_IDLE(); OUT_RING( CP_PACKET0( RADEON_PP_CNTL, 1 ) ); OUT_RING( 0x00000000 ); - OUT_RING( rb3d_cntl ); + OUT_RING( depth_clear->rb3d_cntl ); OUT_RING( CP_PACKET0( RADEON_RB3D_ZSTENCILCNTL, 0 ) ); - OUT_RING( rb3d_zstencilcntl ); + 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( se_cntl ); + OUT_RING( depth_clear->se_cntl ); OUT_RING( CP_PACKET3( RADEON_3D_DRAW_IMMD, 10 ) ); OUT_RING( RADEON_VTX_Z_PRESENT ); @@ -691,7 +651,6 @@ static void radeon_cp_dispatch_swap( drm_device_t *dev ) drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; int nbox = sarea_priv->nbox; drm_clip_rect_t *pbox = sarea_priv->boxes; - u32 fb_bpp; int i; RING_LOCALS; DRM_DEBUG( "%s\n", __FUNCTION__ ); @@ -704,19 +663,6 @@ static void radeon_cp_dispatch_swap( drm_device_t *dev ) radeon_cp_performance_boxes( dev_priv ); #endif - switch ( dev_priv->fb_bpp ) { - case 16: - fb_bpp = RADEON_GMC_DST_16BPP; - break; - case 24: - fb_bpp = RADEON_GMC_DST_24BPP; - break; - case 32: - default: - fb_bpp = RADEON_GMC_DST_32BPP; - break; - } - /* Wait for the 3D stream to idle before dispatching the bitblt. * This will prevent data corruption between the two streams. */ @@ -732,13 +678,16 @@ static void radeon_cp_dispatch_swap( drm_device_t *dev ) 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 | - fb_bpp | + (dev_priv->color_fmt << 8) | RADEON_GMC_SRC_DATATYPE_COLOR | RADEON_ROP3_S | RADEON_DP_SRC_SOURCE_MEMORY | @@ -1139,7 +1088,7 @@ static void radeon_cp_dispatch_stipple( drm_device_t *dev, u32 *stipple ) drm_radeon_private_t *dev_priv = dev->dev_private; int i; RING_LOCALS; - DRM_INFO( "%s\n", __FUNCTION__ ); + DRM_DEBUG( "%s\n", __FUNCTION__ ); radeon_update_ring_snapshot( dev_priv ); -- cgit v1.2.3