[Mesa-dev] [PATCH 4/5] i965: Share the draw x/y offset masking code between main/blorp and all gens.
Eric Anholt
eric at anholt.net
Fri Oct 12 15:30:37 PDT 2012
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.
---
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 0ad7c1b..79a3f3a 100644
--- a/src/mesa/drivers/dri/i965/brw_blorp.h
+++ b/src/mesa/drivers/dri/i965/brw_blorp.h
@@ -325,10 +325,6 @@ 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 3dac633..16bcb9c 100644
--- a/src/mesa/drivers/dri/i965/brw_context.h
+++ b/src/mesa/drivers/dri/i965/brw_context.h
@@ -1128,6 +1128,14 @@ bool brwCreateContext(int api,
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
*/
void brw_init_queryobj_functions(struct dd_function_table *functions);
diff --git a/src/mesa/drivers/dri/i965/brw_misc_state.c b/src/mesa/drivers/dri/i965/brw_misc_state.c
index 6dfa08e..be8dcc4 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 60c3ff1..13dbd30 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 eeeeabe..3175273 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 1d22448..337143c 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));
--
1.7.10.4
More information about the mesa-dev
mailing list