summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Vetter <daniel.vetter@ffwll.ch>2012-03-02 21:38:44 +0100
committerKenneth Graunke <kenneth@whitecape.org>2012-03-20 12:20:04 -0700
commite26aa8c660a025d448a6d297846940a225ed46ac (patch)
tree54a301253deaeaf9a85ced2c5be40fc286e4661f
parent2f5182cfcf2eaf214f2c2a14406d7849668809b8 (diff)
i965: fixup W-tile offset computation to take swizzling into account
There's even a comment in the code containing the right swizzling computations! Previously this has not been noticed because we need to manually enabled swizzling on snb/ivb (kernel 3.4 will do that) and we don't use the separate stencil on ilk (where the bios enables swizzling). This fixes piglit ./bin/fbo-stencil readpixels GL_DEPTH32F_STENCIL8 -auto on recent drm-intel-next kernels. Also remove the comment about ivb, it's stale now. Swizzling detection is done by allocating a temporary x-tiled buffer object. Unfortunately kernels before v3.2 lie on snb/ivb because they claim that swizzling is enable, but it isn't. The kernel commit that fixes this for backport to pre-v3.2 is commit acc83eb5a1e0ae7dbbf89ca2a1a943ade224bb84 Author: Daniel Vetter <daniel.vetter@ffwll.ch> Date: Mon Sep 12 20:49:16 2011 +0200 drm/i915: fix swizzling on gen6+ But if the kernel doesn't lie, this now works on swizzling and not swizzling machines. NOTE: This is a candidate for the 8.0 branch. Reviewed-by: Eric Anholt <eric@anholt.net> Reviewed-by: Kenneth Graunke <kenneth@whitecape.org> (cherry picked from commit f172eae8b23d0612865895c52af745021ae20a4c)
-rw-r--r--src/mesa/drivers/dri/intel/intel_context.c1
-rw-r--r--src/mesa/drivers/dri/intel/intel_context.h1
-rw-r--r--src/mesa/drivers/dri/intel/intel_mipmap_tree.c12
-rw-r--r--src/mesa/drivers/dri/intel/intel_screen.c26
-rw-r--r--src/mesa/drivers/dri/intel/intel_screen.h1
-rw-r--r--src/mesa/drivers/dri/intel/intel_span.c28
-rw-r--r--src/mesa/drivers/dri/intel/intel_span.h2
7 files changed, 49 insertions, 22 deletions
diff --git a/src/mesa/drivers/dri/intel/intel_context.c b/src/mesa/drivers/dri/intel/intel_context.c
index d4bb8c7d2a9..d3c0d705867 100644
--- a/src/mesa/drivers/dri/intel/intel_context.c
+++ b/src/mesa/drivers/dri/intel/intel_context.c
@@ -629,6 +629,7 @@ intelInitContext(struct intel_context *intel,
intel->must_use_separate_stencil = intel->intelScreen->hw_must_use_separate_stencil;
intel->has_hiz = intel->intelScreen->hw_has_hiz;
intel->has_llc = intel->intelScreen->hw_has_llc;
+ intel->has_swizzling = intel->intelScreen->hw_has_swizzling;
memset(&ctx->TextureFormatSupported,
0, sizeof(ctx->TextureFormatSupported));
diff --git a/src/mesa/drivers/dri/intel/intel_context.h b/src/mesa/drivers/dri/intel/intel_context.h
index 150e55f9797..ef024b10e96 100644
--- a/src/mesa/drivers/dri/intel/intel_context.h
+++ b/src/mesa/drivers/dri/intel/intel_context.h
@@ -214,6 +214,7 @@ struct intel_context
bool must_use_separate_stencil;
bool has_hiz;
bool has_llc;
+ bool has_swizzling;
int urb_size;
diff --git a/src/mesa/drivers/dri/intel/intel_mipmap_tree.c b/src/mesa/drivers/dri/intel/intel_mipmap_tree.c
index 5290da4d6f3..3601f5e8daf 100644
--- a/src/mesa/drivers/dri/intel/intel_mipmap_tree.c
+++ b/src/mesa/drivers/dri/intel/intel_mipmap_tree.c
@@ -830,7 +830,8 @@ intel_miptree_map_s8(struct intel_context *intel,
for (uint32_t x = 0; x < map->w; x++) {
ptrdiff_t offset = intel_offset_S8(mt->region->pitch,
x + image_x + map->x,
- y + image_y + map->y);
+ y + image_y + map->y,
+ intel->has_swizzling);
untiled_s8_map[y * map->w + x] = tiled_s8_map[offset];
}
}
@@ -865,7 +866,8 @@ intel_miptree_unmap_s8(struct intel_context *intel,
for (uint32_t x = 0; x < map->w; x++) {
ptrdiff_t offset = intel_offset_S8(mt->region->pitch,
x + map->x,
- y + map->y);
+ y + map->y,
+ intel->has_swizzling);
tiled_s8_map[offset] = untiled_s8_map[y * map->w + x];
}
}
@@ -925,7 +927,8 @@ intel_miptree_map_depthstencil(struct intel_context *intel,
int map_x = map->x + x, map_y = map->y + y;
ptrdiff_t s_offset = intel_offset_S8(s_mt->region->pitch,
map_x + s_image_x,
- map_y + s_image_y);
+ map_y + s_image_y,
+ intel->has_swizzling);
ptrdiff_t z_offset = ((map_y + z_image_y) * z_mt->region->pitch +
(map_x + z_image_x));
uint8_t s = s_map[s_offset];
@@ -983,7 +986,8 @@ intel_miptree_unmap_depthstencil(struct intel_context *intel,
for (uint32_t x = 0; x < map->w; x++) {
ptrdiff_t s_offset = intel_offset_S8(s_mt->region->pitch,
x + s_image_x + map->x,
- y + s_image_y + map->y);
+ y + s_image_y + map->y,
+ intel->has_swizzling);
ptrdiff_t z_offset = ((y + z_image_y) * z_mt->region->pitch +
(x + z_image_x));
diff --git a/src/mesa/drivers/dri/intel/intel_screen.c b/src/mesa/drivers/dri/intel/intel_screen.c
index e6b749aff60..e6e79ef5022 100644
--- a/src/mesa/drivers/dri/intel/intel_screen.c
+++ b/src/mesa/drivers/dri/intel/intel_screen.c
@@ -650,6 +650,30 @@ intel_override_separate_stencil(struct intel_screen *screen)
}
}
+static bool
+intel_detect_swizzling(struct intel_screen *screen)
+{
+ drm_intel_bo *buffer;
+ unsigned long flags = 0;
+ unsigned long aligned_pitch;
+ uint32_t tiling = I915_TILING_X;
+ uint32_t swizzle_mode = 0;
+
+ buffer = drm_intel_bo_alloc_tiled(screen->bufmgr, "swizzle test",
+ 64, 64, 4,
+ &tiling, &aligned_pitch, flags);
+ if (buffer == NULL)
+ return false;
+
+ drm_intel_bo_get_tiling(buffer, &tiling, &swizzle_mode);
+ drm_intel_bo_unreference(buffer);
+
+ if (swizzle_mode == I915_BIT_6_SWIZZLE_NONE)
+ return false;
+ else
+ return true;
+}
+
/**
* This is the driver specific part of the createNewScreen entry point.
* Called when using DRI2.
@@ -748,6 +772,8 @@ __DRIconfig **intelInitScreen2(__DRIscreen *psp)
if (!intel_init_bufmgr(intelScreen))
return false;
+ intelScreen->hw_has_swizzling = intel_detect_swizzling(intelScreen);
+
psp->extensions = intelScreenExtensions;
msaa_samples_array[0] = 0;
diff --git a/src/mesa/drivers/dri/intel/intel_screen.h b/src/mesa/drivers/dri/intel/intel_screen.h
index a6baf1601b5..1998f7eb675 100644
--- a/src/mesa/drivers/dri/intel/intel_screen.h
+++ b/src/mesa/drivers/dri/intel/intel_screen.h
@@ -117,6 +117,7 @@ struct intel_screen
bool kernel_has_gen7_sol_reset;
bool hw_has_llc;
+ bool hw_has_swizzling;
bool no_vbo;
dri_bufmgr *bufmgr;
diff --git a/src/mesa/drivers/dri/intel/intel_span.c b/src/mesa/drivers/dri/intel/intel_span.c
index 3645720c060..b0dc72023f3 100644
--- a/src/mesa/drivers/dri/intel/intel_span.c
+++ b/src/mesa/drivers/dri/intel/intel_span.c
@@ -65,7 +65,7 @@
* mesa: Fix return type of _mesa_get_format_bytes() (#37351)
*/
intptr_t
-intel_offset_S8(uint32_t stride, uint32_t x, uint32_t y)
+intel_offset_S8(uint32_t stride, uint32_t x, uint32_t y, bool swizzled)
{
uint32_t tile_size = 4096;
uint32_t tile_width = 64;
@@ -90,22 +90,16 @@ intel_offset_S8(uint32_t stride, uint32_t x, uint32_t y)
+ 2 * (byte_y % 2)
+ 1 * (byte_x % 2);
- /*
- * Errata for Gen5:
- *
- * An additional offset is needed which is not documented in the PRM.
- *
- * if ((byte_x / 8) % 2 == 1) {
- * if ((byte_y / 8) % 2) == 0) {
- * u += 64;
- * } else {
- * u -= 64;
- * }
- * }
- *
- * The offset is expressed more tersely as
- * u += ((int) x & 0x8) * (8 - (((int) y & 0x8) << 1));
- */
+ if (swizzled) {
+ /* adjust for bit6 swizzling */
+ if (((byte_x / 8) % 2) == 1) {
+ if (((byte_y / 8) % 2) == 0) {
+ u += 64;
+ } else {
+ u -= 64;
+ }
+ }
+ }
return u;
}
diff --git a/src/mesa/drivers/dri/intel/intel_span.h b/src/mesa/drivers/dri/intel/intel_span.h
index b2bd416412f..e5218691c65 100644
--- a/src/mesa/drivers/dri/intel/intel_span.h
+++ b/src/mesa/drivers/dri/intel/intel_span.h
@@ -38,6 +38,6 @@ extern void intelSpanRenderStart(struct gl_context * ctx);
void intel_map_vertex_shader_textures(struct gl_context *ctx);
void intel_unmap_vertex_shader_textures(struct gl_context *ctx);
-intptr_t intel_offset_S8(uint32_t stride, uint32_t x, uint32_t y);
+intptr_t intel_offset_S8(uint32_t stride, uint32_t x, uint32_t y, bool swizzled);
#endif