From: Marek Olšák Date: Fri, 28 Jan 2011 00:01:01 +0000 (+0100) Subject: r300g: fix and re-enable 8x8 zbuffer compression mode X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=2050f2ab96f923112d3475a655b31c8f5145a800;p=mesa.git r300g: fix and re-enable 8x8 zbuffer compression mode Also cleanup the whole thing. --- diff --git a/src/gallium/drivers/r300/r300_blit.c b/src/gallium/drivers/r300/r300_blit.c index f24d5582e17..d0eb21c8924 100644 --- a/src/gallium/drivers/r300/r300_blit.c +++ b/src/gallium/drivers/r300/r300_blit.c @@ -114,16 +114,7 @@ static boolean r300_fast_zclear_allowed(struct r300_context *r300) struct pipe_framebuffer_state *fb = (struct pipe_framebuffer_state*)r300->fb_state.state; - /* Cannot decompress zmask with a 16-bit zbuffer. - * Also compression causes a hung. */ - if (util_format_get_blocksizebits(fb->zsbuf->texture->format) == 16) - return FALSE; - - /* Cannot use compression with a linear zbuffer. */ - if (!r300_texture(fb->zsbuf->texture)->desc.microtile) - return FALSE; - - return TRUE; + return r300_texture(fb->zsbuf->texture)->desc.zmask_dwords[fb->zsbuf->u.tex.level]; } static uint32_t r300_depth_clear_value(enum pipe_format format, diff --git a/src/gallium/drivers/r300/r300_chipset.c b/src/gallium/drivers/r300/r300_chipset.c index 15dc6d09eeb..593eadb9c7d 100644 --- a/src/gallium/drivers/r300/r300_chipset.c +++ b/src/gallium/drivers/r300/r300_chipset.c @@ -424,7 +424,6 @@ void r300_parse_chipset(struct r300_capabilities* caps) } caps->is_rv350 = caps->family >= CHIP_FAMILY_RV350; - /* XXX The 8x8 compression mode doesn't always work (piglit/fbo-depth fails). */ - caps->z_compress = /*caps->is_rv350 ? R300_ZCOMP_8X8 :*/ R300_ZCOMP_4X4; + caps->z_compress = caps->is_rv350 ? R300_ZCOMP_8X8 : R300_ZCOMP_4X4; caps->dxtc_swizzle = caps->is_r400 || caps->is_r500; } diff --git a/src/gallium/drivers/r300/r300_context.h b/src/gallium/drivers/r300/r300_context.h index 6e96ae85ffd..57ecfb168f8 100644 --- a/src/gallium/drivers/r300/r300_context.h +++ b/src/gallium/drivers/r300/r300_context.h @@ -387,6 +387,11 @@ struct r300_texture_desc { /* Whether CBZB fast color clear is allowed on the miplevel. */ boolean cbzb_allowed[R300_MAX_TEXTURE_LEVELS]; + + /* Zbuffer compression info for each miplevel. */ + boolean zcomp8x8[R300_MAX_TEXTURE_LEVELS]; + /* If zero, then disable compression. */ + unsigned zmask_dwords[R300_MAX_TEXTURE_LEVELS]; }; struct r300_texture { diff --git a/src/gallium/drivers/r300/r300_emit.c b/src/gallium/drivers/r300/r300_emit.c index 54e263436bd..2157cb3ede7 100644 --- a/src/gallium/drivers/r300/r300_emit.c +++ b/src/gallium/drivers/r300/r300_emit.c @@ -1141,42 +1141,14 @@ void r300_emit_zmask_clear(struct r300_context *r300, unsigned size, void *state struct pipe_framebuffer_state *fb = (struct pipe_framebuffer_state*)r300->fb_state.state; struct r300_texture *tex; - unsigned numdw, pipes; - unsigned compsize = r300->screen->caps.z_compress; - /* The tile size of 1 DWORD is: - * - * GPU Pipes 4x4 mode 8x8 mode - * ------------------------------------------ - * R580 4P/1Z 32x32 64x64 - * RV570 3P/1Z 48x16 96x32 - * RV530 1P/2Z 32x16 64x32 - */ - static unsigned num_blocks_x_per_dw[4] = {4, 8, 12, 8}; - static unsigned num_blocks_y_per_dw[4] = {4, 4, 4, 8}; CS_LOCALS(r300); - if (r300->screen->caps.family == CHIP_FAMILY_RV530) { - pipes = r300->screen->caps.num_z_pipes; - } else { - pipes = r300->screen->caps.num_frag_pipes; - } - tex = r300_texture(fb->zsbuf->texture); - /* Get the zbuffer size (with the aligned width and height). */ - numdw = align(tex->desc.stride_in_pixels[fb->zsbuf->u.tex.level], - num_blocks_x_per_dw[pipes-1] * compsize) * - align(fb->zsbuf->height, - num_blocks_y_per_dw[pipes-1] * compsize); - - /* Convert pixels -> dwords. */ - numdw = ALIGN_DIVUP(numdw, num_blocks_x_per_dw[pipes-1] * compsize * - num_blocks_y_per_dw[pipes-1] * compsize); - BEGIN_CS(size); OUT_CS_PKT3(R300_PACKET3_3D_CLEAR_ZMASK, 2); OUT_CS(0); - OUT_CS(numdw); + OUT_CS(tex->desc.zmask_dwords[fb->zsbuf->u.tex.level]); OUT_CS(0); END_CS; diff --git a/src/gallium/drivers/r300/r300_hyperz.c b/src/gallium/drivers/r300/r300_hyperz.c index d996d191755..7767275e67e 100644 --- a/src/gallium/drivers/r300/r300_hyperz.c +++ b/src/gallium/drivers/r300/r300_hyperz.c @@ -168,10 +168,10 @@ static void r300_update_hyperz(struct r300_context* r300) if (!r300->zmask_decompress) { z->zb_bw_cntl |= R300_WR_COMP_ENABLE; } + } - if (r300->screen->caps.z_compress == R300_ZCOMP_8X8) { - z->gb_z_peq_config |= R300_GB_Z_PEQ_CONFIG_Z_PEQ_SIZE_8_8; - } + if (zstex->desc.zcomp8x8[fb->zsbuf->u.tex.level]) { + z->gb_z_peq_config |= R300_GB_Z_PEQ_CONFIG_Z_PEQ_SIZE_8_8; } if (hiz_in_use && r300_can_hiz(r300)) { diff --git a/src/gallium/drivers/r300/r300_texture_desc.c b/src/gallium/drivers/r300/r300_texture_desc.c index bc33871565b..83469f720bc 100644 --- a/src/gallium/drivers/r300/r300_texture_desc.c +++ b/src/gallium/drivers/r300/r300_texture_desc.c @@ -334,6 +334,63 @@ static void r300_setup_cbzb_flags(struct r300_screen *rscreen, desc->cbzb_allowed[i] = first_level_valid && desc->macrotile[i]; } +#define ALIGN_DIVUP(x, y) (((x) + (y) - 1) / (y)) + +static void r300_setup_zmask_flags(struct r300_screen *screen, + struct r300_texture_desc *desc) +{ + /* The tile size of 1 DWORD is: + * + * GPU Pipes 4x4 mode 8x8 mode + * ------------------------------------------ + * R580 4P/1Z 32x32 64x64 + * RV570 3P/1Z 48x16 96x32 + * RV530 1P/2Z 32x16 64x32 + * 1P/1Z 16x16 32x32 + */ + static unsigned num_blocks_x_per_dw[4] = {4, 8, 12, 8}; + static unsigned num_blocks_y_per_dw[4] = {4, 4, 4, 8}; + + if (util_format_is_depth_or_stencil(desc->b.b.format) && + util_format_get_blocksizebits(desc->b.b.format) == 32 && + desc->microtile) { + unsigned i, pipes; + + if (screen->caps.family == CHIP_FAMILY_RV530) { + pipes = screen->caps.num_z_pipes; + } else { + pipes = screen->caps.num_frag_pipes; + } + + for (i = 0; i <= desc->b.b.last_level; i++) { + unsigned numdw, compsize; + + /* The 8x8 compression mode needs macrotiling. */ + compsize = screen->caps.z_compress == R300_ZCOMP_8X8 && + desc->macrotile[i] ? 8 : 4; + + /* Get the zbuffer size (with the aligned width and height). */ + numdw = align(desc->stride_in_pixels[i], + num_blocks_x_per_dw[pipes-1] * compsize) * + align(u_minify(desc->b.b.height0, i), + num_blocks_y_per_dw[pipes-1] * compsize); + + /* Convert pixels -> dwords. */ + numdw = ALIGN_DIVUP(numdw, num_blocks_x_per_dw[pipes-1] * compsize * + num_blocks_y_per_dw[pipes-1] * compsize); + + /* Check that we have enough ZMASK memory. */ + if (numdw <= screen->caps.zmask_ram * pipes) { + desc->zmask_dwords[i] = numdw; + desc->zcomp8x8[i] = compsize == 8; + } else { + desc->zmask_dwords[i] = 0; + desc->zcomp8x8[i] = FALSE; + } + } + } +} + static void r300_setup_tiling(struct r300_screen *screen, struct r300_texture_desc *desc) { @@ -439,6 +496,7 @@ boolean r300_texture_desc_init(struct r300_screen *rscreen, } r300_texture_3d_fix_mipmapping(rscreen, desc); + r300_setup_zmask_flags(rscreen, desc); if (max_buffer_size) { /* Make sure the buffer we got is large enough. */