From f3da711bea8637d1ad7e0113cb663667ba198c26 Mon Sep 17 00:00:00 2001 From: Chia-I Wu Date: Wed, 22 May 2013 13:00:30 +0800 Subject: [PATCH] ilo: correctly set view extent in SURFACE_STATE The view extent was set to be the same as the depth while it should be set to the number of layers. It makes a difference for 3D textures. Also use this as a chance to clean up the code. --- src/gallium/drivers/ilo/ilo_gpe_gen6.c | 100 +++++++++++++++---------- src/gallium/drivers/ilo/ilo_gpe_gen7.c | 100 ++++++++++++++----------- 2 files changed, 115 insertions(+), 85 deletions(-) diff --git a/src/gallium/drivers/ilo/ilo_gpe_gen6.c b/src/gallium/drivers/ilo/ilo_gpe_gen6.c index bb261695ce8..4102b2149a3 100644 --- a/src/gallium/drivers/ilo/ilo_gpe_gen6.c +++ b/src/gallium/drivers/ilo/ilo_gpe_gen6.c @@ -3692,14 +3692,11 @@ gen6_fill_normal_SURFACE_STATE(const struct ilo_dev_info *dev, width = tex->base.width0; height = tex->base.height0; + depth = (tex->base.target == PIPE_TEXTURE_3D) ? + tex->base.depth0 : num_layers; pitch = tex->bo_stride; - switch (tex->base.target) { - case PIPE_TEXTURE_3D: - depth = tex->base.depth0; - break; - case PIPE_TEXTURE_CUBE: - case PIPE_TEXTURE_CUBE_ARRAY: + if (surface_type == BRW_SURFACE_CUBE) { /* * From the Sandy Bridge PRM, volume 4 part 1, page 81: * @@ -3708,17 +3705,17 @@ gen6_fill_normal_SURFACE_STATE(const struct ilo_dev_info *dev, * cube array elements (equal to the number of underlying 2D array * elements divided by 6). For other surfaces, this field must be * zero." + * + * When is_rt is true, we treat the texture as a 2D one to avoid the + * restriction. */ - if (!is_rt) { + if (is_rt) { + surface_type = BRW_SURFACE_2D; + } + else { assert(num_layers % 6 == 0); depth = num_layers / 6; - break; } - assert(num_layers == 1); - /* fall through */ - default: - depth = num_layers; - break; } /* sanity check the size */ @@ -3726,16 +3723,24 @@ gen6_fill_normal_SURFACE_STATE(const struct ilo_dev_info *dev, switch (surface_type) { case BRW_SURFACE_1D: assert(width <= 8192 && height == 1 && depth <= 512); + assert(first_layer < 512 && num_layers <= 512); break; case BRW_SURFACE_2D: assert(width <= 8192 && height <= 8192 && depth <= 512); + assert(first_layer < 512 && num_layers <= 512); break; case BRW_SURFACE_3D: assert(width <= 2048 && height <= 2048 && depth <= 2048); + assert(first_layer < 2048 && num_layers <= 512); + if (!is_rt) + assert(first_layer == 0); break; case BRW_SURFACE_CUBE: assert(width <= 8192 && height <= 8192 && depth <= 85); assert(width == height); + assert(first_layer < 512 && num_layers <= 512); + if (is_rt) + assert(first_layer == 0); break; default: assert(!"unexpected surface type"); @@ -3748,39 +3753,52 @@ gen6_fill_normal_SURFACE_STATE(const struct ilo_dev_info *dev, if (tex->base.nr_samples > 1) assert(tex->interleaved); - /* - * Compute the offset to the layer manually. - * - * For rendering, the hardware requires LOD to be the same for all render - * targets and the depth buffer. We need to compute the offset to the - * layer manually and always set LOD to 0. - */ if (is_rt) { - /* we lose the capability for layered rendering */ - assert(num_levels == 1 && num_layers == 1); - - layer_offset = ilo_texture_get_slice_offset(tex, - first_level, first_layer, &x_offset, &y_offset); - - assert(x_offset % 4 == 0); - assert(y_offset % 2 == 0); - x_offset /= 4; - y_offset /= 2; - - /* derive the size for the LOD */ - width = u_minify(tex->base.width0, first_level); - height = u_minify(tex->base.height0, first_level); - if (surface_type == BRW_SURFACE_3D) - depth = u_minify(tex->base.depth0, first_level); - - first_level = 0; - first_layer = 0; - lod = 0; + /* + * Compute the offset to the layer manually. + * + * For rendering, the hardware requires LOD to be the same for all + * render targets and the depth buffer. We need to compute the offset + * to the layer manually and always set LOD to 0. + */ + if (true) { + /* we lose the capability for layered rendering */ + assert(num_layers == 1); + + layer_offset = ilo_texture_get_slice_offset(tex, + first_level, first_layer, &x_offset, &y_offset); + + assert(x_offset % 4 == 0); + assert(y_offset % 2 == 0); + x_offset /= 4; + y_offset /= 2; + + /* derive the size for the LOD */ + width = u_minify(width, first_level); + height = u_minify(height, first_level); + if (surface_type == BRW_SURFACE_3D) + depth = u_minify(depth, first_level); + else + depth = 1; + + first_level = 0; + first_layer = 0; + lod = 0; + } + else { + layer_offset = 0; + x_offset = 0; + y_offset = 0; + } + + assert(num_levels == 1); + lod = first_level; } else { layer_offset = 0; x_offset = 0; y_offset = 0; + lod = num_levels - 1; } @@ -3836,7 +3854,7 @@ gen6_fill_normal_SURFACE_STATE(const struct ilo_dev_info *dev, dw[4] = first_level << BRW_SURFACE_MIN_LOD_SHIFT | first_layer << 17 | - (depth - 1) << 8 | + (num_layers - 1) << 8 | ((tex->base.nr_samples > 1) ? BRW_SURFACE_MULTISAMPLECOUNT_4 : BRW_SURFACE_MULTISAMPLECOUNT_1); diff --git a/src/gallium/drivers/ilo/ilo_gpe_gen7.c b/src/gallium/drivers/ilo/ilo_gpe_gen7.c index 4e773c2fa62..0a3474dad0a 100644 --- a/src/gallium/drivers/ilo/ilo_gpe_gen7.c +++ b/src/gallium/drivers/ilo/ilo_gpe_gen7.c @@ -1435,39 +1435,34 @@ gen7_fill_normal_SURFACE_STATE(const struct ilo_dev_info *dev, width = tex->base.width0; height = tex->base.height0; + depth = (tex->base.target == PIPE_TEXTURE_3D) ? + tex->base.depth0 : num_layers; pitch = tex->bo_stride; - switch (tex->base.target) { - case PIPE_TEXTURE_3D: - depth = tex->base.depth0; - break; - case PIPE_TEXTURE_CUBE: - case PIPE_TEXTURE_CUBE_ARRAY: + if (surface_type == BRW_SURFACE_CUBE) { /* * From the Ivy Bridge PRM, volume 4 part 1, page 70: * - * "For SURFTYPE_CUBE: For Sampling Engine Surfaces, the range of + * "For SURFTYPE_CUBE:For Sampling Engine Surfaces, the range of * this field is [0,340], indicating the number of cube array * elements (equal to the number of underlying 2D array elements * divided by 6). For other surfaces, this field must be zero." * - * "Errata: For SURFTYPE_CUBE sampling engine surfaces, the range of - * this field is limited to [0,85]." + * When is_rt is true, we treat the texture as a 2D one to avoid the + * restriction. */ - if (!is_rt) { + if (is_rt) { + surface_type = BRW_SURFACE_2D; + } + else { assert(num_layers % 6 == 0); depth = num_layers / 6; - break; } - assert(num_layers == 1); - /* fall through */ - default: - depth = num_layers; - break; } /* sanity check the size */ assert(width >= 1 && height >= 1 && depth >= 1 && pitch >= 1); + assert(first_layer < 2048 && num_layers <= 2048); switch (surface_type) { case BRW_SURFACE_1D: assert(width <= 16384 && height == 1 && depth <= 2048); @@ -1477,49 +1472,66 @@ gen7_fill_normal_SURFACE_STATE(const struct ilo_dev_info *dev, break; case BRW_SURFACE_3D: assert(width <= 2048 && height <= 2048 && depth <= 2048); + if (!is_rt) + assert(first_layer == 0); break; case BRW_SURFACE_CUBE: assert(width <= 16384 && height <= 16384 && depth <= 86); assert(width == height); + if (is_rt) + assert(first_layer == 0); break; default: assert(!"unexpected surface type"); break; } - /* - * Compute the offset to the layer manually. - * - * For rendering, the hardware requires LOD to be the same for all render - * targets and the depth buffer. We need to compute the offset to the - * layer manually and always set LOD to 0. - */ if (is_rt) { - /* we lose the capability for layered rendering */ - assert(num_levels == 1 && num_layers == 1); - - layer_offset = ilo_texture_get_slice_offset(tex, - first_level, first_layer, &x_offset, &y_offset); - - assert(x_offset % 4 == 0); - assert(y_offset % 2 == 0); - x_offset /= 4; - y_offset /= 2; - - /* derive the size for the LOD */ - width = u_minify(tex->base.width0, first_level); - height = u_minify(tex->base.height0, first_level); - if (surface_type == BRW_SURFACE_3D) - depth = u_minify(tex->base.depth0, first_level); - - first_level = 0; - first_layer = 0; - lod = 0; + /* + * Compute the offset to the layer manually. + * + * For rendering, the hardware requires LOD to be the same for all + * render targets and the depth buffer. We need to compute the offset + * to the layer manually and always set LOD to 0. + */ + if (true) { + /* we lose the capability for layered rendering */ + assert(num_layers == 1); + + layer_offset = ilo_texture_get_slice_offset(tex, + first_level, first_layer, &x_offset, &y_offset); + + assert(x_offset % 4 == 0); + assert(y_offset % 2 == 0); + x_offset /= 4; + y_offset /= 2; + + /* derive the size for the LOD */ + width = u_minify(width, first_level); + height = u_minify(height, first_level); + if (surface_type == BRW_SURFACE_3D) + depth = u_minify(depth, first_level); + else + depth = 1; + + first_level = 0; + first_layer = 0; + lod = 0; + } + else { + layer_offset = 0; + x_offset = 0; + y_offset = 0; + } + + assert(num_levels == 1); + lod = first_level; } else { layer_offset = 0; x_offset = 0; y_offset = 0; + lod = num_levels - 1; } @@ -1589,7 +1601,7 @@ gen7_fill_normal_SURFACE_STATE(const struct ilo_dev_info *dev, (pitch - 1); dw[4] = first_layer << 18 | - (depth - 1) << 7; + (num_layers - 1) << 7; /* * MSFMT_MSS means the samples are not interleaved and MSFMT_DEPTH_STENCIL -- 2.30.2