summaryrefslogtreecommitdiff
path: root/src/gallium/drivers/r300/r300_hyperz.c
diff options
context:
space:
mode:
authorMarek Olšák <maraeo@gmail.com>2011-01-25 05:37:52 +0100
committerMarek Olšák <maraeo@gmail.com>2011-01-27 18:12:01 +0100
commitdb299a9f8244d53d9041fcdbd396a77ebe1f9e3e (patch)
tree60adc94f4a132101be84579bf57988283e20ef90 /src/gallium/drivers/r300/r300_hyperz.c
parent7a4345fd83605695dc641af503f6e87b808b48d7 (diff)
r300g: fix some bugs with zbuffer compression (v4)
This drops the memblock manager for ZMASK. Instead, only one zbuffer can be compressed at a time. Note that this does not necessarily have to be slower. When there is a large number of zbuffers, compression might be used more often than it was before. It's also easier to debug. How it works: 1) 'clear' turns the compression on. 2) If some other zbuffer is set or the currently-bound zbuffer is used for texturing, the driver decompresses it and then turns the compression off. Notes: - The ZMASK clear has been refactored, so that only one packet3 is used to clear ZMASK. - The 8x8 compression mode is disabled. I couldn't make it work without issues. - Also removed driver-specific stuff from u_blitter. Driver status: - RV530 and R580 appear to just work (finally). - RV570 should work, but there may be an issue that we don't correctly calculate the number of dwords to clear, resulting in a partially uninitialized zbuffer. - RS690 misrenders as if no ZMASK clear happened. No idea what's going on. - RV350 may even hardlock. This issue was already present and this patch doesn't fix it. I think we are still missing some hardware info we need to make the zbuffer compression work fully. Note that there is also an issue with HiZ, resulting in a sort of blocky zigzagged corruption around some objects.
Diffstat (limited to 'src/gallium/drivers/r300/r300_hyperz.c')
-rw-r--r--src/gallium/drivers/r300/r300_hyperz.c120
1 files changed, 26 insertions, 94 deletions
diff --git a/src/gallium/drivers/r300/r300_hyperz.c b/src/gallium/drivers/r300/r300_hyperz.c
index c22e307c67..d996d19175 100644
--- a/src/gallium/drivers/r300/r300_hyperz.c
+++ b/src/gallium/drivers/r300/r300_hyperz.c
@@ -127,7 +127,7 @@ static boolean r300_can_hiz(struct r300_context *r300)
z->current_func, dsa_state->z_stencil_control);
return FALSE;
}
- }
+ }
return TRUE;
}
@@ -139,7 +139,6 @@ static void r300_update_hyperz(struct r300_context* r300)
(struct pipe_framebuffer_state*)r300->fb_state.state;
struct r300_texture *zstex =
fb->zsbuf ? r300_texture(fb->zsbuf->texture) : NULL;
- boolean zmask_in_use = FALSE;
boolean hiz_in_use = FALSE;
z->gb_z_peq_config = 0;
@@ -158,42 +157,40 @@ static void r300_update_hyperz(struct r300_context* r300)
if (!r300->rws->get_value(r300->rws, R300_CAN_HYPERZ))
return;
- zmask_in_use = zstex->zmask_in_use[fb->zsbuf->u.tex.level];
hiz_in_use = zstex->hiz_in_use[fb->zsbuf->u.tex.level];
- /* Z fastfill. */
- if (zmask_in_use) {
- z->zb_bw_cntl |= R300_FAST_FILL_ENABLE; /* | R300_FORCE_COMPRESSED_STENCIL_VALUE_ENABLE;*/
- }
-
/* Zbuffer compression. */
- if (zmask_in_use && r300->z_compression) {
- z->zb_bw_cntl |= R300_RD_COMP_ENABLE;
- if (r300->z_decomp_rd == false)
+ if (r300->zmask_in_use && !r300->zmask_locked) {
+ z->zb_bw_cntl |= R300_FAST_FILL_ENABLE |
+ /*R300_FORCE_COMPRESSED_STENCIL_VALUE_ENABLE |*/
+ R300_RD_COMP_ENABLE;
+
+ 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;
+ }
}
- /* RV350 and up optimizations. */
- /* The section 10.4.9 in the docs is a lie. */
- if (r300->z_compression == RV350_Z_COMPRESS_88)
- z->gb_z_peq_config |= R300_GB_Z_PEQ_CONFIG_Z_PEQ_SIZE_8_8;
-
- if (hiz_in_use) {
- bool can_hiz = r300_can_hiz(r300);
- if (can_hiz) {
- z->zb_bw_cntl |= R300_HIZ_ENABLE;
- z->sc_hyperz |= R300_SC_HYPERZ_ENABLE;
- z->sc_hyperz |= r300_get_sc_hz_max(r300);
- z->zb_bw_cntl |= r300_get_hiz_min(r300);
+
+ if (hiz_in_use && r300_can_hiz(r300)) {
+ z->zb_bw_cntl |= R300_HIZ_ENABLE |
+ r300_get_hiz_min(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_FP_EXP_BITS_3 |
+ R500_HIZ_EQUAL_REJECT_ENABLE;
}
}
/* R500-specific features and optimizations. */
if (r300->screen->caps.is_r500) {
- z->zb_bw_cntl |= R500_HIZ_FP_EXP_BITS_3;
- z->zb_bw_cntl |=
- R500_HIZ_EQUAL_REJECT_ENABLE |
- R500_PEQ_PACKING_ENABLE |
- R500_COVERED_PTR_MASKING_ENABLE;
+ z->zb_bw_cntl |= R500_PEQ_PACKING_ENABLE |
+ R500_COVERED_PTR_MASKING_ENABLE;
}
}
@@ -297,26 +294,10 @@ static void r300_update_hiz_clear(struct r300_context *r300)
r300->hiz_clear.size = height * 4;
}
-static void r300_update_zmask_clear(struct r300_context *r300)
-{
- struct pipe_framebuffer_state *fb =
- (struct pipe_framebuffer_state*)r300->fb_state.state;
- uint32_t height;
- int mult;
-
- if (r300->z_compression == RV350_Z_COMPRESS_88)
- mult = 8;
- else
- mult = 4;
-
- height = ALIGN_DIVUP(fb->zsbuf->height, mult);
-
- r300->zmask_clear.size = height * 4;
-}
-
void r300_update_hyperz_state(struct r300_context* r300)
{
r300_update_ztop(r300);
+
if (r300->hyperz_state.dirty) {
r300_update_hyperz(r300);
}
@@ -324,9 +305,6 @@ void r300_update_hyperz_state(struct r300_context* r300)
if (r300->hiz_clear.dirty) {
r300_update_hiz_clear(r300);
}
- if (r300->zmask_clear.dirty) {
- r300_update_zmask_clear(r300);
- }
}
void r300_hiz_alloc_block(struct r300_context *r300, struct r300_surface *surf)
@@ -345,43 +323,6 @@ void r300_hiz_alloc_block(struct r300_context *r300, struct r300_surface *surf)
ndw = ALIGN_DIVUP(zsize, 64);
tex->hiz_mem[level] = u_mmAllocMem(r300->hiz_mm, ndw, 0, 0);
- return;
-}
-
-void r300_zmask_alloc_block(struct r300_context *r300, struct r300_surface *surf, int compress)
-{
- int bsize = 256;
- uint32_t zsize, ndw;
- int level = surf->base.u.tex.level;
- struct r300_texture *tex;
-
- tex = r300_texture(surf->base.texture);
-
- /* We currently don't handle decompression for 3D textures and cubemaps
- * correctly. */
- if (tex->desc.b.b.target != PIPE_TEXTURE_1D &&
- tex->desc.b.b.target != PIPE_TEXTURE_2D &&
- tex->desc.b.b.target != PIPE_TEXTURE_RECT)
- return;
-
- /* Cannot flush zmask of 16-bit zbuffers. */
- if (util_format_get_blocksizebits(tex->desc.b.b.format) == 16)
- return;
-
- if (tex->zmask_mem[level])
- return;
-
- zsize = tex->desc.layer_size_in_bytes[level];
- zsize /= util_format_get_blocksize(tex->desc.b.b.format);
-
- /* each zmask dword represents 16 4x4 blocks - which is 256 pixels
- or 16 8x8 depending on the gb peq flag = 1024 pixels */
- if (compress == RV350_Z_COMPRESS_88)
- bsize = 1024;
-
- ndw = ALIGN_DIVUP(zsize, bsize);
- tex->zmask_mem[level] = u_mmAllocMem(r300->zmask_mm, ndw, 0, 0);
- return;
}
boolean r300_hyperz_init_mm(struct r300_context *r300)
@@ -389,15 +330,9 @@ boolean r300_hyperz_init_mm(struct r300_context *r300)
struct r300_screen* r300screen = r300->screen;
int frag_pipes = r300screen->caps.num_frag_pipes;
- r300->zmask_mm = u_mmInit(0, r300screen->caps.zmask_ram * frag_pipes);
- if (!r300->zmask_mm)
- return FALSE;
-
if (r300screen->caps.hiz_ram) {
r300->hiz_mm = u_mmInit(0, r300screen->caps.hiz_ram * frag_pipes);
if (!r300->hiz_mm) {
- u_mmDestroy(r300->zmask_mm);
- r300->zmask_mm = NULL;
return FALSE;
}
}
@@ -413,7 +348,4 @@ void r300_hyperz_destroy_mm(struct r300_context *r300)
u_mmDestroy(r300->hiz_mm);
r300->hiz_mm = NULL;
}
-
- u_mmDestroy(r300->zmask_mm);
- r300->zmask_mm = NULL;
}