From 8da15d75442c94adc1bc087fe164a1fa13c3c0f3 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Tue, 8 Oct 2013 00:19:23 -0700 Subject: [PATCH] i965: Fix 3D texture layout by more literally copying from the spec. Fixes 3 texelFetch tests in piglit all.tests on ivb, and cubemap npot on gm45. v2: Don't forget the gen4 DL=6 cubemap behavior. Cc: "9.1 9.2" Reviewed-by: Chad Versace (v1) --- src/mesa/drivers/dri/i965/brw_tex_layout.c | 75 ++++++++---------------------- 1 file changed, 20 insertions(+), 55 deletions(-) diff --git a/src/mesa/drivers/dri/i965/brw_tex_layout.c b/src/mesa/drivers/dri/i965/brw_tex_layout.c index e9128a3..d912862 100644 --- a/src/mesa/drivers/dri/i965/brw_tex_layout.c +++ b/src/mesa/drivers/dri/i965/brw_tex_layout.c @@ -240,69 +240,34 @@ static void brw_miptree_layout_texture_3d(struct brw_context *brw, struct intel_mipmap_tree *mt) { - unsigned width = mt->physical_width0; - unsigned height = mt->physical_height0; - unsigned depth = mt->physical_depth0; - unsigned pack_x_pitch, pack_x_nr; - unsigned pack_y_pitch; + unsigned yscale = mt->compressed ? 4 : 1; + mt->total_width = 0; mt->total_height = 0; - if (mt->compressed) { - mt->total_width = ALIGN(width, mt->align_w); - pack_y_pitch = (height + 3) / 4; - } else { - mt->total_width = mt->physical_width0; - pack_y_pitch = ALIGN(mt->physical_height0, mt->align_h); - } - - pack_x_pitch = width; - pack_x_nr = 1; - + unsigned ysum = 0; for (unsigned level = mt->first_level; level <= mt->last_level; level++) { - int x = 0; - int y = 0; - - intel_miptree_set_level_info(mt, level, - 0, mt->total_height, - width, height, depth); - - for (int q = 0; q < depth; /* empty */) { - for (int j = 0; j < pack_x_nr && q < depth; j++, q++) { - intel_miptree_set_image_offset(mt, level, q, x, y); - x += pack_x_pitch; - } - if (x > mt->total_width) - mt->total_width = x; - - x = 0; - y += pack_y_pitch; - } + unsigned WL = MAX2(mt->physical_width0 >> level, 1); + unsigned HL = MAX2(mt->physical_height0 >> level, 1); + unsigned DL = MAX2(mt->physical_depth0 >> level, 1); + unsigned wL = ALIGN(WL, mt->align_w); + unsigned hL = ALIGN(HL, mt->align_h); - mt->total_height += y; - width = minify(width, 1); - height = minify(height, 1); - if (mt->target == GL_TEXTURE_3D) - depth = minify(depth, 1); + if (mt->target == GL_TEXTURE_CUBE_MAP) + DL = 6; - if (mt->compressed) { - pack_y_pitch = (height + 3) / 4; + intel_miptree_set_level_info(mt, level, 0, 0, WL, HL, DL); - if (pack_x_pitch > ALIGN(width, mt->align_w)) { - pack_x_pitch = ALIGN(width, mt->align_w); - pack_x_nr <<= 1; - } - } else { - pack_x_nr <<= 1; - if (pack_x_pitch > 4) { - pack_x_pitch >>= 1; - } - - if (pack_y_pitch > 2) { - pack_y_pitch >>= 1; - pack_y_pitch = ALIGN(pack_y_pitch, mt->align_h); - } + for (unsigned q = 0; q < DL; q++) { + unsigned x = (q % (1 << level)) * wL; + unsigned y = ysum + (q >> level) * hL; + + intel_miptree_set_image_offset(mt, level, q, x, y / yscale); + mt->total_width = MAX2(mt->total_width, x + wL); + mt->total_height = MAX2(mt->total_height, (y + hL) / yscale); } + + ysum += ALIGN(DL, 1 << level) / (1 << level) * hL; } align_cube(mt); -- 2.7.4