r300_hyperz.c revision f9e8cdc145fc0ba1f6c47e20860add6528387c7c
1/* 2 * Copyright 2008 Corbin Simpson <MostAwesomeDude@gmail.com> 3 * Copyright 2009 Marek Olšák <maraeo@gmail.com> 4 * 5 * Permission is hereby granted, free of charge, to any person obtaining a 6 * copy of this software and associated documentation files (the "Software"), 7 * to deal in the Software without restriction, including without limitation 8 * on the rights to use, copy, modify, merge, publish, distribute, sub 9 * license, and/or sell copies of the Software, and to permit persons to whom 10 * the Software is furnished to do so, subject to the following conditions: 11 * 12 * The above copyright notice and this permission notice (including the next 13 * paragraph) shall be included in all copies or substantial portions of the 14 * Software. 15 * 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 19 * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, 20 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 21 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 22 * USE OR OTHER DEALINGS IN THE SOFTWARE. */ 23 24#include "r300_context.h" 25#include "r300_hyperz.h" 26#include "r300_reg.h" 27#include "r300_fs.h" 28 29/*****************************************************************************/ 30/* The ZTOP state */ 31/*****************************************************************************/ 32 33static boolean r300_dsa_writes_stencil( 34 struct pipe_stencil_state *s) 35{ 36 return s->enabled && s->writemask && 37 (s->fail_op != PIPE_STENCIL_OP_KEEP || 38 s->zfail_op != PIPE_STENCIL_OP_KEEP || 39 s->zpass_op != PIPE_STENCIL_OP_KEEP); 40} 41 42static boolean r300_dsa_writes_depth_stencil( 43 struct pipe_depth_stencil_alpha_state *dsa) 44{ 45 /* We are interested only in the cases when a depth or stencil value 46 * can be changed. */ 47 48 if (dsa->depth.enabled && dsa->depth.writemask && 49 dsa->depth.func != PIPE_FUNC_NEVER) 50 return TRUE; 51 52 if (r300_dsa_writes_stencil(&dsa->stencil[0]) || 53 r300_dsa_writes_stencil(&dsa->stencil[1])) 54 return TRUE; 55 56 return FALSE; 57} 58 59static boolean r300_dsa_alpha_test_enabled( 60 struct pipe_depth_stencil_alpha_state *dsa) 61{ 62 /* We are interested only in the cases when alpha testing can kill 63 * a fragment. */ 64 65 return dsa->alpha.enabled && dsa->alpha.func != PIPE_FUNC_ALWAYS; 66} 67 68static void r300_update_ztop(struct r300_context* r300) 69{ 70 struct r300_ztop_state* ztop_state = 71 (struct r300_ztop_state*)r300->ztop_state.state; 72 uint32_t old_ztop = ztop_state->z_buffer_top; 73 74 /* This is important enough that I felt it warranted a comment. 75 * 76 * According to the docs, these are the conditions where ZTOP must be 77 * disabled: 78 * 1) Alpha testing enabled 79 * 2) Texture kill instructions in fragment shader 80 * 3) Chroma key culling enabled 81 * 4) W-buffering enabled 82 * 83 * The docs claim that for the first three cases, if no ZS writes happen, 84 * then ZTOP can be used. 85 * 86 * (3) will never apply since we do not support chroma-keyed operations. 87 * (4) will need to be re-examined (and this comment updated) if/when 88 * Hyper-Z becomes supported. 89 * 90 * Additionally, the following conditions require disabled ZTOP: 91 * 5) Depth writes in fragment shader 92 * 6) Outstanding occlusion queries 93 * 94 * This register causes stalls all the way from SC to CB when changed, 95 * but it is buffered on-chip so it does not hurt to write it if it has 96 * not changed. 97 * 98 * ~C. 99 */ 100 101 /* ZS writes */ 102 if (r300_dsa_writes_depth_stencil(r300->dsa_state.state) && 103 (r300_dsa_alpha_test_enabled(r300->dsa_state.state) || /* (1) */ 104 r300_fs(r300)->shader->info.uses_kill)) { /* (2) */ 105 ztop_state->z_buffer_top = R300_ZTOP_DISABLE; 106 } else if (r300_fragment_shader_writes_depth(r300_fs(r300))) { /* (5) */ 107 ztop_state->z_buffer_top = R300_ZTOP_DISABLE; 108 } else if (r300->query_current) { /* (6) */ 109 ztop_state->z_buffer_top = R300_ZTOP_DISABLE; 110 } else { 111 ztop_state->z_buffer_top = R300_ZTOP_ENABLE; 112 } 113 114 if (ztop_state->z_buffer_top != old_ztop) 115 r300->ztop_state.dirty = TRUE; 116} 117 118void r300_update_hyperz_state(struct r300_context* r300) 119{ 120 r300_update_ztop(r300); 121} 122