From 5c8dd6cf7995ae52a5482c1209c218f0b9a7b1c1 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Tue, 7 Aug 2012 16:53:24 -0700 Subject: [PATCH] i965: Share the draw x/y offset masking code between main/blorp and all gens. This code is twisty, and the comment before most of the blocks was actually giving me the opposite impression from its intention: We want to apply as much of our offset as possible through coarse tile-aligned adjustment, since we can do so independently per buffer, and apply the minimum we can through fine-grained drawing offset x/y, since it has to agree between all buffers. Reviewed-by: Kenneth Graunke --- src/mesa/drivers/dri/i965/brw_blorp.h | 4 - src/mesa/drivers/dri/i965/brw_context.h | 8 ++ src/mesa/drivers/dri/i965/brw_misc_state.c | 111 ++++++++++++-------- src/mesa/drivers/dri/i965/gen6_blorp.cpp | 28 +---- src/mesa/drivers/dri/i965/gen7_blorp.cpp | 5 +- src/mesa/drivers/dri/i965/gen7_misc_state.c | 41 +------- 6 files changed, 89 insertions(+), 108 deletions(-) diff --git a/src/mesa/drivers/dri/i965/brw_blorp.h b/src/mesa/drivers/dri/i965/brw_blorp.h index 0ad7c1b61cf..79a3f3ae79f 100644 --- a/src/mesa/drivers/dri/i965/brw_blorp.h +++ b/src/mesa/drivers/dri/i965/brw_blorp.h @@ -324,10 +324,6 @@ private: void gen6_blorp_init(struct brw_context *brw); -void -gen6_blorp_compute_tile_masks(const brw_blorp_params *params, - uint32_t *tile_mask_x, uint32_t *tile_mask_y); - void gen6_blorp_emit_batch_head(struct brw_context *brw, const brw_blorp_params *params); diff --git a/src/mesa/drivers/dri/i965/brw_context.h b/src/mesa/drivers/dri/i965/brw_context.h index 3dac6339b48..16bcb9cecc7 100644 --- a/src/mesa/drivers/dri/i965/brw_context.h +++ b/src/mesa/drivers/dri/i965/brw_context.h @@ -1127,6 +1127,14 @@ bool brwCreateContext(int api, unsigned *error, void *sharedContextPrivate); +/*====================================================================== + * brw_misc_state.c + */ +void brw_get_depthstencil_tile_masks(struct intel_mipmap_tree *depth_mt, + struct intel_mipmap_tree *stencil_mt, + uint32_t *out_tile_mask_x, + uint32_t *out_tile_mask_y); + /*====================================================================== * brw_queryobj.c */ diff --git a/src/mesa/drivers/dri/i965/brw_misc_state.c b/src/mesa/drivers/dri/i965/brw_misc_state.c index 6dfa08e01af..be8dcc45274 100644 --- a/src/mesa/drivers/dri/i965/brw_misc_state.c +++ b/src/mesa/drivers/dri/i965/brw_misc_state.c @@ -253,6 +253,70 @@ brw_depthbuffer_format(struct brw_context *brw) } } +/** + * Returns the mask of how many bits of x and y must be handled through the + * depthbuffer's draw offset x and y fields. + * + * The draw offset x/y field of the depthbuffer packet is unfortunately shared + * between the depth, hiz, and stencil buffers. Because it can be hard to get + * all 3 to agree on this value, we want to do as much drawing offset + * adjustment as possible by moving the base offset of the 3 buffers, which is + * restricted to tile boundaries. + * + * For each buffer, the remainder must be applied through the x/y draw offset. + * This returns the worst-case mask of the low bits that have to go into the + * packet. If the 3 buffers don't agree on the drawing offset ANDed with this + * mask, then we're in trouble. + */ +void +brw_get_depthstencil_tile_masks(struct intel_mipmap_tree *depth_mt, + struct intel_mipmap_tree *stencil_mt, + uint32_t *out_tile_mask_x, + uint32_t *out_tile_mask_y) +{ + uint32_t tile_mask_x = 0, tile_mask_y = 0; + + if (depth_mt) { + intel_region_get_tile_masks(depth_mt->region, + &tile_mask_x, &tile_mask_y, false); + + struct intel_mipmap_tree *hiz_mt = depth_mt->hiz_mt; + if (hiz_mt) { + uint32_t hiz_tile_mask_x, hiz_tile_mask_y; + intel_region_get_tile_masks(hiz_mt->region, + &hiz_tile_mask_x, &hiz_tile_mask_y, false); + + /* Each HiZ row represents 2 rows of pixels */ + hiz_tile_mask_y = hiz_tile_mask_y << 1 | 1; + + tile_mask_x |= hiz_tile_mask_x; + tile_mask_y |= hiz_tile_mask_y; + } + } + + if (stencil_mt) { + if (stencil_mt->stencil_mt) + stencil_mt = stencil_mt->stencil_mt; + + if (stencil_mt->format == MESA_FORMAT_S8) { + /* Separate stencil buffer uses 64x64 tiles. */ + tile_mask_x |= 63; + tile_mask_y |= 63; + } else { + uint32_t stencil_tile_mask_x, stencil_tile_mask_y; + intel_region_get_tile_masks(stencil_mt->region, + &stencil_tile_mask_x, + &stencil_tile_mask_y, false); + + tile_mask_x |= stencil_tile_mask_x; + tile_mask_y |= stencil_tile_mask_y; + } + } + + *out_tile_mask_x = tile_mask_x; + *out_tile_mask_y = tile_mask_y; +} + static void emit_depthbuffer(struct brw_context *brw) { struct intel_context *intel = &brw->intel; @@ -261,6 +325,7 @@ static void emit_depthbuffer(struct brw_context *brw) /* _NEW_BUFFERS */ struct intel_renderbuffer *depth_irb = intel_get_renderbuffer(fb, BUFFER_DEPTH); struct intel_renderbuffer *stencil_irb = intel_get_renderbuffer(fb, BUFFER_STENCIL); + struct intel_mipmap_tree *depth_mt = NULL; struct intel_mipmap_tree *stencil_mt = NULL; struct intel_region *hiz_region = NULL; unsigned int len; @@ -272,39 +337,11 @@ static void emit_depthbuffer(struct brw_context *brw) */ uint32_t draw_x = 0, draw_y = 0; - /* Masks used to determine how much of the draw_x and draw_y offsets should - * be performed using the fine adjustment of "depth coordinate offset X/Y" - * (dw5 of 3DSTATE_DEPTH_BUFFER). Any remaining coarse adjustment will be - * performed by changing the base addresses of the buffers. - * - * Since the HiZ, depth, and stencil buffers all use the same "depth - * coordinate offset X/Y" values, we need to make sure that the coarse - * adjustment will be possible to apply to all three buffers. Since coarse - * adjustment can only be applied in multiples of the tile size, we will OR - * together the tile masks of all the buffers to determine which offsets to - * perform as fine adjustments. - */ - uint32_t tile_mask_x = 0, tile_mask_y = 0; - - if (depth_irb) { - intel_region_get_tile_masks(depth_irb->mt->region, - &tile_mask_x, &tile_mask_y, false); - } - if (depth_irb && depth_irb->mt && depth_irb->mt->hiz_mt) { + depth_mt = depth_irb->mt; hiz_region = depth_irb->mt->hiz_mt->region; - - uint32_t hiz_tile_mask_x, hiz_tile_mask_y; - intel_region_get_tile_masks(hiz_region, - &hiz_tile_mask_x, &hiz_tile_mask_y, false); - - /* Each HiZ row represents 2 rows of pixels */ - hiz_tile_mask_y = hiz_tile_mask_y << 1 | 1; - - tile_mask_x |= hiz_tile_mask_x; - tile_mask_y |= hiz_tile_mask_y; } /* 3DSTATE_DEPTH_BUFFER, 3DSTATE_STENCIL_BUFFER are both @@ -323,21 +360,13 @@ static void emit_depthbuffer(struct brw_context *brw) if (stencil_mt->format == MESA_FORMAT_S8) { separate_stencil = true; - - /* Separate stencil buffer uses 64x64 tiles. */ - tile_mask_x |= 63; - tile_mask_y |= 63; - } else { - uint32_t stencil_tile_mask_x, stencil_tile_mask_y; - intel_region_get_tile_masks(stencil_mt->region, - &stencil_tile_mask_x, - &stencil_tile_mask_y, false); - - tile_mask_x |= stencil_tile_mask_x; - tile_mask_y |= stencil_tile_mask_y; } } + uint32_t tile_mask_x, tile_mask_y; + brw_get_depthstencil_tile_masks(depth_mt, stencil_mt, + &tile_mask_x, &tile_mask_y); + /* If there's a packed depth/stencil bound to stencil only, we need to * emit the packed depth/stencil buffer packet. */ diff --git a/src/mesa/drivers/dri/i965/gen6_blorp.cpp b/src/mesa/drivers/dri/i965/gen6_blorp.cpp index 60c3ff1674e..13dbd30d71f 100644 --- a/src/mesa/drivers/dri/i965/gen6_blorp.cpp +++ b/src/mesa/drivers/dri/i965/gen6_blorp.cpp @@ -45,31 +45,6 @@ * sizeof(float)) /** \} */ - -/** - * Compute masks to determine how much of draw_x and draw_y should be - * performed using the fine adjustment of "depth coordinate offset X/Y" - * (dw5 of 3DSTATE_DEPTH_BUFFER). See the emit_depthbuffer() function for - * details. - */ -void -gen6_blorp_compute_tile_masks(const brw_blorp_params *params, - uint32_t *tile_mask_x, uint32_t *tile_mask_y) -{ - uint32_t depth_mask_x, depth_mask_y, hiz_mask_x, hiz_mask_y; - intel_region_get_tile_masks(params->depth.mt->region, - &depth_mask_x, &depth_mask_y, false); - intel_region_get_tile_masks(params->depth.mt->hiz_mt->region, - &hiz_mask_x, &hiz_mask_y, false); - - /* Each HiZ row represents 2 rows of pixels */ - hiz_mask_y = hiz_mask_y << 1 | 1; - - *tile_mask_x = depth_mask_x | hiz_mask_x; - *tile_mask_y = depth_mask_y | hiz_mask_y; -} - - void gen6_blorp_emit_batch_head(struct brw_context *brw, const brw_blorp_params *params) @@ -834,7 +809,8 @@ gen6_blorp_emit_depth_stencil_config(struct brw_context *brw, uint32_t draw_y = params->depth.y_offset; uint32_t tile_mask_x, tile_mask_y; - gen6_blorp_compute_tile_masks(params, &tile_mask_x, &tile_mask_y); + brw_get_depthstencil_tile_masks(params->depth.mt, NULL, + &tile_mask_x, &tile_mask_y); /* 3DSTATE_DEPTH_BUFFER */ { diff --git a/src/mesa/drivers/dri/i965/gen7_blorp.cpp b/src/mesa/drivers/dri/i965/gen7_blorp.cpp index eeeeabe2c64..317527396e3 100644 --- a/src/mesa/drivers/dri/i965/gen7_blorp.cpp +++ b/src/mesa/drivers/dri/i965/gen7_blorp.cpp @@ -582,7 +582,10 @@ gen7_blorp_emit_depth_stencil_config(struct brw_context *brw, uint32_t draw_y = params->depth.y_offset; uint32_t tile_mask_x, tile_mask_y; - gen6_blorp_compute_tile_masks(params, &tile_mask_x, &tile_mask_y); + if (params->depth.mt) { + brw_get_depthstencil_tile_masks(params->depth.mt, NULL, + &tile_mask_x, &tile_mask_y); + } /* 3DSTATE_DEPTH_BUFFER */ { diff --git a/src/mesa/drivers/dri/i965/gen7_misc_state.c b/src/mesa/drivers/dri/i965/gen7_misc_state.c index 1d22448459f..337143c58cf 100644 --- a/src/mesa/drivers/dri/i965/gen7_misc_state.c +++ b/src/mesa/drivers/dri/i965/gen7_misc_state.c @@ -48,55 +48,24 @@ static void emit_depthbuffer(struct brw_context *brw) */ uint32_t draw_x = 0, draw_y = 0; - /* Masks used to determine how much of the draw_x and draw_y offsets should - * be performed using the fine adjustment of "depth coordinate offset X/Y" - * (dw5 of 3DSTATE_DEPTH_BUFFER). Any remaining coarse adjustment will be - * performed by changing the base addresses of the buffers. - * - * Since the HiZ, depth, and stencil buffers all use the same "depth - * coordinate offset X/Y" values, we need to make sure that the coarse - * adjustment will be possible to apply to all three buffers. Since coarse - * adjustment can only be applied in multiples of the tile size, we will OR - * together the tile masks of all the buffers to determine which offsets to - * perform as fine adjustments. - */ - uint32_t tile_mask_x = 0, tile_mask_y = 0; - if (drb) depth_mt = drb->mt; - if (depth_mt) { + if (depth_mt) hiz_mt = depth_mt->hiz_mt; - intel_region_get_tile_masks(depth_mt->region, - &tile_mask_x, &tile_mask_y, false); - - if (hiz_mt) { - uint32_t hiz_tile_mask_x, hiz_tile_mask_y; - intel_region_get_tile_masks(hiz_mt->region, - &hiz_tile_mask_x, &hiz_tile_mask_y, - false); - - /* Each HiZ row represents 2 rows of pixels */ - hiz_tile_mask_y = hiz_tile_mask_y << 1 | 1; - - tile_mask_x |= hiz_tile_mask_x; - tile_mask_y |= hiz_tile_mask_y; - } - } - if (srb) { stencil_mt = srb->mt; if (stencil_mt->stencil_mt) stencil_mt = stencil_mt->stencil_mt; assert(stencil_mt->format == MESA_FORMAT_S8); - - /* Stencil buffer uses 64x64 tiles. */ - tile_mask_x |= 63; - tile_mask_y |= 63; } + uint32_t tile_mask_x, tile_mask_y; + brw_get_depthstencil_tile_masks(depth_mt, stencil_mt, + &tile_mask_x, &tile_mask_y); + /* Gen7 doesn't support packed depth/stencil */ assert(stencil_mt == NULL || depth_mt != stencil_mt); assert(!depth_mt || !_mesa_is_format_packed_depth_stencil(depth_mt->format)); -- 2.30.2