i965/blorp: Account for offsets when emitting SURFACE_STATE.
authorPaul Berry <stereotype441@gmail.com>
Wed, 29 Aug 2012 23:04:15 +0000 (16:04 -0700)
committerPaul Berry <stereotype441@gmail.com>
Wed, 12 Sep 2012 21:44:12 +0000 (14:44 -0700)
Fixes piglit tests "framebuffer-blit-levels {read,draw} depth".

NOTE: This is a candidate for stable release branches.

Reviewed-by: Eric Anholt <eric@anholt.net>
src/mesa/drivers/dri/i965/brw_blorp.cpp
src/mesa/drivers/dri/i965/brw_blorp.h
src/mesa/drivers/dri/i965/gen6_blorp.cpp
src/mesa/drivers/dri/i965/gen7_blorp.cpp

index af1156c39b147af8e19be7a31e7b4abfab529725..3368907e1b830e22f1824a0f898c37ba7799e209 100644 (file)
@@ -107,6 +107,31 @@ brw_blorp_surface_info::set(struct brw_context *brw,
    }
 }
 
+
+/**
+ * Split x_offset and y_offset into a base offset (in bytes) and a remaining
+ * x/y offset (in pixels).  Note: we can't do this by calling
+ * intel_renderbuffer_tile_offsets(), because the offsets may have been
+ * adjusted to account for Y vs. W tiling differences.  So we compute it
+ * directly from the adjusted offsets.
+ */
+uint32_t
+brw_blorp_surface_info::compute_tile_offsets(uint32_t *tile_x,
+                                             uint32_t *tile_y) const
+{
+   struct intel_region *region = mt->region;
+   uint32_t mask_x, mask_y;
+
+   intel_region_get_tile_masks(region, &mask_x, &mask_y);
+
+   *tile_x = x_offset & mask_x;
+   *tile_y = y_offset & mask_y;
+
+   return intel_region_get_aligned_offset(region, x_offset & ~mask_x,
+                                          y_offset & ~mask_y);
+}
+
+
 brw_blorp_params::brw_blorp_params()
    : x0(0),
      y0(0),
index ef0c27491e14f38e2a59932a3004dfdc06c8fef2..0ad7c1b61cfdbe88b7c6600e738c6843dff420f3 100644 (file)
@@ -104,6 +104,8 @@ public:
             struct intel_mipmap_tree *mt,
             unsigned int level, unsigned int layer);
 
+   uint32_t compute_tile_offsets(uint32_t *tile_x, uint32_t *tile_y) const;
+
    /* Setting this flag indicates that the buffer's contents are W-tiled
     * stencil data, but the surface state should be set up for Y tiled
     * MESA_FORMAT_R8 data (this is necessary because surface states don't
index d5d65c635f2d78fe987880ae255606dd0541e4fc..baf3fa4531cf37470294f49ea310d960e49b791e 100644 (file)
@@ -424,6 +424,7 @@ gen6_blorp_emit_surface_state(struct brw_context *brw,
       height /= 2;
    }
    struct intel_region *region = surface->mt->region;
+   uint32_t tile_x, tile_y;
 
    uint32_t *surf = (uint32_t *)
       brw_state_batch(brw, AUB_TRACE_SURFACE_STATE, 6 * 4, 32,
@@ -435,7 +436,8 @@ gen6_blorp_emit_surface_state(struct brw_context *brw,
               surface->brw_surfaceformat << BRW_SURFACE_FORMAT_SHIFT);
 
    /* reloc */
-   surf[1] = region->bo->offset; /* No tile offsets needed */
+   surf[1] = (surface->compute_tile_offsets(&tile_x, &tile_y) +
+              region->bo->offset);
 
    surf[2] = (0 << BRW_SURFACE_LOD_SHIFT |
               (width - 1) << BRW_SURFACE_WIDTH_SHIFT |
@@ -453,8 +455,13 @@ gen6_blorp_emit_surface_state(struct brw_context *brw,
 
    surf[4] = brw_get_surface_num_multisamples(surface->num_samples);
 
-   surf[5] = (0 << BRW_SURFACE_X_OFFSET_SHIFT |
-              0 << BRW_SURFACE_Y_OFFSET_SHIFT |
+   /* Note that the low bits of these fields are missing, so
+    * there's the possibility of getting in trouble.
+    */
+   assert(tile_x % 4 == 0);
+   assert(tile_y % 2 == 0);
+   surf[5] = ((tile_x / 4) << BRW_SURFACE_X_OFFSET_SHIFT |
+              (tile_y / 2) << BRW_SURFACE_Y_OFFSET_SHIFT |
               (surface->mt->align_h == 4 ?
                BRW_SURFACE_VERTICAL_ALIGN_ENABLE : 0));
 
index 3520ff60265acb8c512334b72bd68e86cbd102e3..00f13a532128aaf5a38200764bf43d257ebf06f5 100644 (file)
@@ -150,6 +150,7 @@ gen7_blorp_emit_surface_state(struct brw_context *brw,
     * gen6_blorp_emit_surface_state).
     */
    struct intel_region *region = surface->mt->region;
+   uint32_t tile_x, tile_y;
 
    struct gen7_surface_state *surf = (struct gen7_surface_state *)
       brw_state_batch(brw, AUB_TRACE_SURFACE_STATE, sizeof(*surf), 32,
@@ -167,7 +168,16 @@ gen7_blorp_emit_surface_state(struct brw_context *brw,
       GEN7_SURFACE_ARYSPC_LOD0 : GEN7_SURFACE_ARYSPC_FULL;
 
    /* reloc */
-   surf->ss1.base_addr = region->bo->offset; /* No tile offsets needed */
+   surf->ss1.base_addr = surface->compute_tile_offsets(&tile_x, &tile_y);
+   surf->ss1.base_addr += region->bo->offset;
+
+   /* Note that the low bits of these fields are missing, so
+    * there's the possibility of getting in trouble.
+    */
+   assert(tile_x % 4 == 0);
+   assert(tile_y % 2 == 0);
+   surf->ss5.x_offset = tile_x / 4;
+   surf->ss5.y_offset = tile_y / 2;
 
    surf->ss2.width = width - 1;
    surf->ss2.height = height - 1;