[Mesa-dev] [PATCH 2/4] i965: Share Gen7+ SURFACE_STATE setup for textures and renderbuffers.
Paul Berry
stereotype441 at gmail.com
Mon Sep 16 17:05:20 PDT 2013
On 13 September 2013 23:10, Kenneth Graunke <kenneth at whitecape.org> wrote:
> The SURFACE_STATE entries for textures and renderbuffers share almost
> all of the same fields. Only a couple are specific to one or the other.
>
> Thus, it makes sense to have a single shared function that takes care of
> all the bit-shifting required to assemble the SURFACE_STATE structure.
>
> This removes a lot of complicated cut and pasted code.
>
> One change is that we now specify cube face enables for render targets,
> but as far as I can tell this is harmless.
>
> Signed-off-by: Kenneth Graunke <kenneth at whitecape.org>
> ---
> src/mesa/drivers/dri/i965/gen7_wm_surface_state.c | 210
> ++++++++++------------
> 1 file changed, 99 insertions(+), 111 deletions(-)
>
> diff --git a/src/mesa/drivers/dri/i965/gen7_wm_surface_state.c
> b/src/mesa/drivers/dri/i965/gen7_wm_surface_state.c
> index 8413308..8f95abe 100644
> --- a/src/mesa/drivers/dri/i965/gen7_wm_surface_state.c
> +++ b/src/mesa/drivers/dri/i965/gen7_wm_surface_state.c
> @@ -257,6 +257,70 @@ gen7_emit_buffer_surface_state(struct brw_context
> *brw,
> }
>
> static void
> +gen7_emit_image_surface_state(struct brw_context *brw,
> + uint32_t *out_offset,
> + const struct intel_mipmap_tree *mt,
> + unsigned bo_offset,
> + unsigned surface_type,
> + unsigned surface_format,
> + bool is_array,
> + unsigned depth,
> + unsigned min_array_element,
> + unsigned rt_view_extent,
> + unsigned mocs,
> + unsigned mip_count,
> + int swizzle,
> + bool is_render_target)
> +{
> + uint32_t *surf = brw_state_batch(brw, AUB_TRACE_SURFACE_STATE,
> + 8 * 4, 32, out_offset);
> + surf[0] = surface_type << BRW_SURFACE_TYPE_SHIFT |
> + surface_format << BRW_SURFACE_FORMAT_SHIFT |
> + gen7_surface_tiling_mode(mt->region->tiling) |
> + BRW_SURFACE_CUBEFACE_ENABLES |
> + (mt->align_h == 4 ? GEN7_SURFACE_VALIGN_4 :
> GEN7_SURFACE_VALIGN_2) |
> + (mt->align_w == 8 ? GEN7_SURFACE_HALIGN_8 :
> GEN7_SURFACE_HALIGN_4) |
> + (is_array ? GEN7_SURFACE_IS_ARRAY : 0) |
> + (mt->array_spacing_lod0 ? GEN7_SURFACE_ARYSPC_LOD0
> + : GEN7_SURFACE_ARYSPC_FULL);
> + surf[1] = mt->region->bo->offset + bo_offset; /* reloc */
> + surf[2] = SET_FIELD(mt->logical_width0 - 1, GEN7_SURFACE_WIDTH) |
> + SET_FIELD(mt->logical_height0 - 1, GEN7_SURFACE_HEIGHT);
> + surf[3] = SET_FIELD(depth - 1, BRW_SURFACE_DEPTH) |
> + (mt->region->pitch - 1);
> + surf[4] = min_array_element << GEN7_SURFACE_MIN_ARRAY_ELEMENT_SHIFT |
> + rt_view_extent <<
> GEN7_SURFACE_RENDER_TARGET_VIEW_EXTENT_SHIFT |
> + gen7_surface_msaa_bits(mt->num_samples, mt->msaa_layout);
> + surf[5] = SET_FIELD(mocs, GEN7_SURFACE_MOCS) | mip_count;
> +
> + if (mt->mcs_mt) {
> + gen7_set_surface_mcs_info(brw, surf, *out_offset, mt->mcs_mt, true);
> + } else {
> + surf[6] = 0;
> + }
> +
> + surf[7] = mt->fast_clear_color_value;
> +
> + if (brw->is_haswell) {
> + surf[7] |=
> + SET_FIELD(swizzle_to_scs(GET_SWZ(swizzle, 0)),
> GEN7_SURFACE_SCS_R) |
> + SET_FIELD(swizzle_to_scs(GET_SWZ(swizzle, 1)),
> GEN7_SURFACE_SCS_G) |
> + SET_FIELD(swizzle_to_scs(GET_SWZ(swizzle, 2)),
> GEN7_SURFACE_SCS_B) |
> + SET_FIELD(swizzle_to_scs(GET_SWZ(swizzle, 3)),
> GEN7_SURFACE_SCS_A);
> + }
> +
> + uint32_t read_domain =
> + is_render_target ? I915_GEM_DOMAIN_RENDER : I915_GEM_DOMAIN_SAMPLER;
> +
> + /* Emit relocation to surface contents */
> + drm_intel_bo_emit_reloc(brw->batch.bo, *out_offset + 4,
> + mt->region->bo, bo_offset,
> + read_domain, 0);
> +
> + gen7_check_surface_setup(surf, is_render_target);
> +}
> +
> +static void
> gen7_update_buffer_texture_surface(struct gl_context *ctx,
> unsigned unit,
> uint32_t *surf_offset)
> @@ -305,43 +369,14 @@ gen7_update_texture_surface(struct gl_context *ctx,
> return;
> }
>
> - uint32_t *surf = brw_state_batch(brw, AUB_TRACE_SURFACE_STATE,
> - 8 * 4, 32, surf_offset);
> - memset(surf, 0, 8 * 4);
> -
> - uint32_t tex_format = translate_tex_format(brw,
> + bool is_array = mt->logical_depth0 > 1 && tObj->Target !=
> GL_TEXTURE_3D;
> + unsigned mip_count = intelObj->_MaxLevel -
> intel_image->mt->first_level;
> + uint32_t brw_format = translate_tex_format(brw,
> mt->format,
> tObj->DepthMode,
> sampler->sRGBDecode);
>
> - surf[0] = translate_tex_target(tObj->Target) << BRW_SURFACE_TYPE_SHIFT
> |
> - tex_format << BRW_SURFACE_FORMAT_SHIFT |
> - gen7_surface_tiling_mode(mt->region->tiling) |
> - BRW_SURFACE_CUBEFACE_ENABLES;
> -
> - if (mt->align_h == 4)
> - surf[0] |= GEN7_SURFACE_VALIGN_4;
> - if (mt->align_w == 8)
> - surf[0] |= GEN7_SURFACE_HALIGN_8;
> -
> - if (mt->logical_depth0 > 1 && tObj->Target != GL_TEXTURE_3D)
> - surf[0] |= GEN7_SURFACE_IS_ARRAY;
> -
> - if (mt->array_spacing_lod0)
> - surf[0] |= GEN7_SURFACE_ARYSPC_LOD0;
> -
> - surf[1] = mt->region->bo->offset + mt->offset; /* reloc */
> -
> - surf[2] = SET_FIELD(mt->logical_width0 - 1, GEN7_SURFACE_WIDTH) |
> - SET_FIELD(mt->logical_height0 - 1, GEN7_SURFACE_HEIGHT);
> - surf[3] = SET_FIELD(mt->logical_depth0 - 1, BRW_SURFACE_DEPTH) |
> - ((intelObj->mt->region->pitch) - 1);
> -
> - surf[4] = gen7_surface_msaa_bits(mt->num_samples, mt->msaa_layout);
> -
> - surf[5] = (SET_FIELD(GEN7_MOCS_L3, GEN7_SURFACE_MOCS) |
> - /* mip count */
> - (intelObj->_MaxLevel - intel_image->mt->first_level));
> + int swizzle = SWIZZLE_XYZW;
>
> if (brw->is_haswell) {
> /* Handling GL_ALPHA as a surface format override breaks 1.30+ style
> @@ -352,24 +387,24 @@ gen7_update_texture_surface(struct gl_context *ctx,
> (firstImage->_BaseFormat == GL_DEPTH_COMPONENT ||
> firstImage->_BaseFormat == GL_DEPTH_STENCIL);
>
> - const int swizzle = unlikely(alpha_depth)
> - ? SWIZZLE_XYZW : brw_get_texture_swizzle(ctx, tObj);
> -
> - surf[7] =
> - SET_FIELD(swizzle_to_scs(GET_SWZ(swizzle, 0)),
> GEN7_SURFACE_SCS_R) |
> - SET_FIELD(swizzle_to_scs(GET_SWZ(swizzle, 1)),
> GEN7_SURFACE_SCS_G) |
> - SET_FIELD(swizzle_to_scs(GET_SWZ(swizzle, 2)),
> GEN7_SURFACE_SCS_B) |
> - SET_FIELD(swizzle_to_scs(GET_SWZ(swizzle, 3)),
> GEN7_SURFACE_SCS_A);
> + if (likely(!alpha_depth))
> + swizzle = brw_get_texture_swizzle(ctx, tObj);
> }
>
> - /* Emit relocation to surface contents */
> - drm_intel_bo_emit_reloc(brw->batch.bo,
> - *surf_offset + 4,
> - intelObj->mt->region->bo,
> - surf[1] - intelObj->mt->region->bo->offset,
> - I915_GEM_DOMAIN_SAMPLER, 0);
> -
> - gen7_check_surface_setup(surf, false /* is_render_target */);
> + gen7_emit_image_surface_state(brw,
> + surf_offset,
> + mt,
> + mt->offset,
> + translate_tex_target(tObj->Target),
> + brw_format,
> + is_array,
> + mt->logical_depth0,
> + 0, /* min_array_element */
> + 0, /* render target view extent */
> + GEN7_MOCS_L3,
> + mip_count,
> + swizzle,
> + false /* is_render_target */);
> }
>
> /**
> @@ -467,31 +502,24 @@ gen7_update_renderbuffer_surface(struct brw_context
> *brw,
> {
> struct gl_context *ctx = &brw->ctx;
> struct intel_renderbuffer *irb = intel_renderbuffer(rb);
> - struct intel_region *region = irb->mt->region;
> - uint32_t format;
> /* _NEW_BUFFERS */
> gl_format rb_format = _mesa_get_render_format(ctx,
> intel_rb_format(irb));
> uint32_t surftype;
> bool is_array = false;
> int depth = MAX2(rb->Depth, 1);
> int min_array_element;
> - const uint8_t mocs = GEN7_MOCS_L3;
> GLenum gl_target = rb->TexImage ?
> rb->TexImage->TexObject->Target : GL_TEXTURE_2D;
>
> uint32_t surf_index = SURF_INDEX_DRAW(unit);
>
> - uint32_t *surf = brw_state_batch(brw, AUB_TRACE_SURFACE_STATE, 8 * 4,
> 32,
> -
> &brw->wm.base.surf_offset[surf_index]);
> - memset(surf, 0, 8 * 4);
> -
> intel_miptree_used_for_rendering(irb->mt);
>
> /* Render targets can't use IMS layout */
> assert(irb->mt->msaa_layout != INTEL_MSAA_LAYOUT_IMS);
>
> assert(brw_render_target_supported(brw, rb));
> - format = brw->render_target_format[rb_format];
> + uint32_t brw_format = brw->render_target_format[rb_format];
> if (unlikely(!brw->format_supported_as_render_target[rb_format])) {
> _mesa_problem(ctx, "%s: renderbuffer format %s unsupported\n",
> __FUNCTION__, _mesa_get_format_name(rb_format));
> @@ -518,60 +546,20 @@ gen7_update_renderbuffer_surface(struct brw_context
> *brw,
> min_array_element = irb->mt_layer;
> }
>
> - surf[0] = surftype << BRW_SURFACE_TYPE_SHIFT |
> - format << BRW_SURFACE_FORMAT_SHIFT |
> - (irb->mt->array_spacing_lod0 ? GEN7_SURFACE_ARYSPC_LOD0
> - : GEN7_SURFACE_ARYSPC_FULL) |
> - gen7_surface_tiling_mode(region->tiling);
> -
> - if (irb->mt->align_h == 4)
> - surf[0] |= GEN7_SURFACE_VALIGN_4;
> - if (irb->mt->align_w == 8)
> - surf[0] |= GEN7_SURFACE_HALIGN_8;
> -
> - if (is_array) {
> - surf[0] |= GEN7_SURFACE_IS_ARRAY;
> - }
> -
> - surf[1] = region->bo->offset;
> -
> - assert(brw->has_surface_tile_offset);
> -
> - surf[5] = SET_FIELD(mocs, GEN7_SURFACE_MOCS) |
> - (irb->mt_level - irb->mt->first_level);
> -
> - surf[2] = SET_FIELD(irb->mt->logical_width0 - 1, GEN7_SURFACE_WIDTH) |
> - SET_FIELD(irb->mt->logical_height0 - 1, GEN7_SURFACE_HEIGHT);
> -
> - surf[3] = ((depth - 1) << BRW_SURFACE_DEPTH_SHIFT) |
> - (region->pitch - 1);
> -
> - surf[4] = gen7_surface_msaa_bits(irb->mt->num_samples,
> irb->mt->msaa_layout) |
> - min_array_element << GEN7_SURFACE_MIN_ARRAY_ELEMENT_SHIFT |
> - (depth - 1) << GEN7_SURFACE_RENDER_TARGET_VIEW_EXTENT_SHIFT;
> -
> - if (irb->mt->mcs_mt) {
> - gen7_set_surface_mcs_info(brw, surf,
> brw->wm.base.surf_offset[surf_index],
> - irb->mt->mcs_mt, true /* is RT */);
> - }
> -
> - surf[7] = irb->mt->fast_clear_color_value;
> -
> - if (brw->is_haswell) {
> - surf[7] |= (SET_FIELD(HSW_SCS_RED, GEN7_SURFACE_SCS_R) |
> - SET_FIELD(HSW_SCS_GREEN, GEN7_SURFACE_SCS_G) |
> - SET_FIELD(HSW_SCS_BLUE, GEN7_SURFACE_SCS_B) |
> - SET_FIELD(HSW_SCS_ALPHA, GEN7_SURFACE_SCS_A));
> - }
> -
> - drm_intel_bo_emit_reloc(brw->batch.bo,
> - brw->wm.base.surf_offset[surf_index] + 4,
> - region->bo,
> - surf[1] - region->bo->offset,
> - I915_GEM_DOMAIN_RENDER,
> - I915_GEM_DOMAIN_RENDER);
>
The new gen7_emit_image_surface_state() function always passes 0 for the
last argument of drm_intel_bo_emit_reloc(), but the code you're removing
passed I915_GEM_DOMAIN_RENDER. Is this a problem?
> -
> - gen7_check_surface_setup(surf, true /* is_render_target */);
> + gen7_emit_image_surface_state(brw,
> + &brw->wm.base.surf_offset[surf_index],
> + irb->mt,
> + 0,
>
I see that you're passing 0 for bo_offset in this case because the old code
for gen7_update_renderbuffer_surface() didn't add any offset to the surface
address. But I believe that was a latent bug that luckily no one stumbled
upon (since the only way to get a miptree with a nonzero offset is via
lookupEGLImage*, and people generally use that mechanism only for images
that they texture from). (*technically there are a few other paths that
create temporary miptrees with nonzero offsets, but those miptrees are only
used for blitting.)
I'd rather see the bo_offset argument of gen7_emit_image_surface_state()
dropped, and have the function just refer to mt->offset internally.
I really like this patch. I think the latent bug with mt->offset is a
strong argument why doing this sort of refactoring is a good idea--if we
had never duplicated this code in the first place, the latent bug probably
would never have occurred. With the minor issues I've brought up here
addressed, the patch is:
Reviewed-by: Paul Berry <stereotype441 at gmail.com>
> + surftype,
> + brw_format,
> + is_array,
> + depth,
> + min_array_element,
> + depth - 1, /* render target view extent
> */
> + GEN7_MOCS_L3,
> + irb->mt_level - irb->mt->first_level,
> + SWIZZLE_XYZW,
> + true);
> }
>
> void
> --
> 1.8.3.4
>
> _______________________________________________
> mesa-dev mailing list
> mesa-dev at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/mesa-dev
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.freedesktop.org/archives/mesa-dev/attachments/20130916/f017ffdc/attachment-0001.html>
More information about the mesa-dev
mailing list