X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;ds=sidebyside;f=src%2Fgallium%2Fdrivers%2Fr300%2Fr300_hyperz.c;h=0f021e9f4e8ae8d077b959b982aab85adc6cd919;hb=d64c6d2ffc086bde7a025269b80c0980f7d908f1;hp=75e6e535519cac34140b39a0f7f6729a4c3794bc;hpb=790c73140939fb60c1b702215bb6afa09f401a8e;p=mesa.git diff --git a/src/gallium/drivers/r300/r300_hyperz.c b/src/gallium/drivers/r300/r300_hyperz.c index 75e6e535519..0f021e9f4e8 100644 --- a/src/gallium/drivers/r300/r300_hyperz.c +++ b/src/gallium/drivers/r300/r300_hyperz.c @@ -24,7 +24,6 @@ #include "r300_context.h" #include "r300_reg.h" #include "r300_fs.h" -#include "r300_winsys.h" #include "util/u_format.h" #include "util/u_mm.h" @@ -44,16 +43,13 @@ static enum r300_hiz_func r300_get_hiz_func(struct r300_context *r300) { struct r300_dsa_state *dsa = r300->dsa_state.state; - if (!dsa->dsa.depth.enabled || !dsa->dsa.depth.writemask) - return HIZ_FUNC_NONE; - switch (dsa->dsa.depth.func) { case PIPE_FUNC_NEVER: case PIPE_FUNC_EQUAL: case PIPE_FUNC_NOTEQUAL: case PIPE_FUNC_ALWAYS: - return HIZ_FUNC_NONE; - + default: + /* Guess MAX for uncertain cases. */ case PIPE_FUNC_LESS: case PIPE_FUNC_LEQUAL: return HIZ_FUNC_MAX; @@ -100,18 +96,21 @@ static boolean r300_dsa_stencil_op_not_keep(struct pipe_stencil_state *s) s->zfail_op != PIPE_STENCIL_OP_KEEP); } -static boolean r300_can_hiz(struct r300_context *r300) +static boolean r300_hiz_allowed(struct r300_context *r300) { struct r300_dsa_state *dsa = r300->dsa_state.state; struct r300_screen *r300screen = r300->screen; - /* shader writes depth - no HiZ */ - if (r300_fragment_shader_writes_depth(r300_fs(r300))) /* (5) */ + if (r300_fragment_shader_writes_depth(r300_fs(r300))) return FALSE; if (r300->query_current) return FALSE; + /* If the depth function is inverted, HiZ must be disabled. */ + if (!r300_is_hiz_func_valid(r300)) + return FALSE; + /* if stencil fail/zfail op is not KEEP */ if (r300_dsa_stencil_op_not_keep(&dsa->dsa.stencil[0]) || r300_dsa_stencil_op_not_keep(&dsa->dsa.stencil[1])) @@ -135,6 +134,7 @@ static void r300_update_hyperz(struct r300_context* r300) (struct r300_hyperz_state*)r300->hyperz_state.state; struct pipe_framebuffer_state *fb = (struct pipe_framebuffer_state*)r300->fb_state.state; + struct r300_dsa_state *dsa = r300->dsa_state.state; struct r300_resource *zstex = fb->zsbuf ? r300_resource(fb->zsbuf->texture) : NULL; @@ -148,55 +148,71 @@ static void r300_update_hyperz(struct r300_context* r300) return; } - if (!zstex || - !r300->rws->get_value(r300->rws, R300_CAN_HYPERZ)) + if (!zstex || !r300->hyperz_enabled) return; - /* Zbuffer compression. */ - if (r300->zmask_in_use && !r300->hyperz_locked) { + /* Set the size of ZMASK tiles. */ + if (zstex->tex.zcomp8x8[fb->zsbuf->u.tex.level]) { + z->gb_z_peq_config |= R300_GB_Z_PEQ_CONFIG_Z_PEQ_SIZE_8_8; + } + + /* R500-specific features and optimizations. */ + if (r300->screen->caps.is_r500) { + z->zb_bw_cntl |= R500_PEQ_PACKING_ENABLE | + R500_COVERED_PTR_MASKING_ENABLE; + } + + /* Setup decompression if needed. No other HyperZ setting is required. */ + if (r300->zmask_decompress) { z->zb_bw_cntl |= R300_FAST_FILL_ENABLE | - /*R300_FORCE_COMPRESSED_STENCIL_VALUE_ENABLE |*/ R300_RD_COMP_ENABLE; + return; + } - if (!r300->zmask_decompress) { - z->zb_bw_cntl |= R300_WR_COMP_ENABLE; - } + /* Do not set anything if depth and stencil tests are off. */ + if (!dsa->dsa.depth.enabled && + !dsa->dsa.stencil[0].enabled && + !dsa->dsa.stencil[1].enabled) { + assert(!dsa->dsa.depth.writemask); + return; } - if (zstex->tex.zcomp8x8[fb->zsbuf->u.tex.level]) { - z->gb_z_peq_config |= R300_GB_Z_PEQ_CONFIG_Z_PEQ_SIZE_8_8; + /* Zbuffer compression. */ + if (r300->zmask_in_use && !r300->locked_zbuffer) { + z->zb_bw_cntl |= R300_FAST_FILL_ENABLE | + R300_RD_COMP_ENABLE | + R300_WR_COMP_ENABLE; } /* HiZ. */ - if (r300->hiz_in_use && !r300->hyperz_locked) { + if (r300->hiz_in_use && !r300->locked_zbuffer) { + /* HiZ cannot be used under some circumstances. */ + if (!r300_hiz_allowed(r300)) { + /* If writemask is disabled, the HiZ memory will not be changed, + * so we can keep its content for later. */ + if (dsa->dsa.depth.writemask) { + r300->hiz_in_use = FALSE; + } + return; + } + DBG(r300, DBG_HYPERZ, "r300: Z-func: %i\n", dsa->dsa.depth.func); + /* Set the HiZ function if needed. */ if (r300->hiz_func == HIZ_FUNC_NONE) { r300->hiz_func = r300_get_hiz_func(r300); } - /* If the depth function is inverted, HiZ must be disabled. */ - if (!r300_is_hiz_func_valid(r300)) { - r300->hiz_in_use = FALSE; - } else if (r300_can_hiz(r300)) { - /* Setup the HiZ bits. */ - z->zb_bw_cntl |= - R300_HIZ_ENABLE | + /* Setup the HiZ bits. */ + z->zb_bw_cntl |= R300_HIZ_ENABLE | (r300->hiz_func == HIZ_FUNC_MIN ? R300_HIZ_MIN : R300_HIZ_MAX); - z->sc_hyperz |= R300_SC_HYPERZ_ENABLE | - r300_get_sc_hz_max(r300); + z->sc_hyperz |= R300_SC_HYPERZ_ENABLE | + r300_get_sc_hz_max(r300); - if (r300->screen->caps.is_r500) { - z->zb_bw_cntl |= R500_HIZ_EQUAL_REJECT_ENABLE; - } + if (r300->screen->caps.is_r500) { + z->zb_bw_cntl |= R500_HIZ_EQUAL_REJECT_ENABLE; } } - - /* R500-specific features and optimizations. */ - if (r300->screen->caps.is_r500) { - z->zb_bw_cntl |= R500_PEQ_PACKING_ENABLE | - R500_COVERED_PTR_MASKING_ENABLE; - } } /*****************************************************************************/