<div dir="ltr">On 13 September 2013 23:10, Kenneth Graunke <span dir="ltr"><<a href="mailto:kenneth@whitecape.org" target="_blank">kenneth@whitecape.org</a>></span> wrote:<br><div class="gmail_extra"><div class="gmail_quote">
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">The SURFACE_STATE entries for textures and renderbuffers share almost<br>
all of the same fields.  Only a couple are specific to one or the other.<br>
<br>
Thus, it makes sense to have a single shared function that takes care of<br>
all the bit-shifting required to assemble the SURFACE_STATE structure.<br>
<br>
This removes a lot of complicated cut and pasted code.<br>
<br>
One change is that we now specify cube face enables for render targets,<br>
but as far as I can tell this is harmless.<br>
<br>
Signed-off-by: Kenneth Graunke <<a href="mailto:kenneth@whitecape.org">kenneth@whitecape.org</a>><br>
---<br>
 src/mesa/drivers/dri/i965/gen7_wm_surface_state.c | 210 ++++++++++------------<br>
 1 file changed, 99 insertions(+), 111 deletions(-)<br>
<br>
diff --git a/src/mesa/drivers/dri/i965/gen7_wm_surface_state.c b/src/mesa/drivers/dri/i965/gen7_wm_surface_state.c<br>
index 8413308..8f95abe 100644<br>
--- a/src/mesa/drivers/dri/i965/gen7_wm_surface_state.c<br>
+++ b/src/mesa/drivers/dri/i965/gen7_wm_surface_state.c<br>
@@ -257,6 +257,70 @@ gen7_emit_buffer_surface_state(struct brw_context *brw,<br>
 }<br>
<br>
 static void<br>
+gen7_emit_image_surface_state(struct brw_context *brw,<br>
+                              uint32_t *out_offset,<br>
+                              const struct intel_mipmap_tree *mt,<br>
+                              unsigned bo_offset,<br>
+                              unsigned surface_type,<br>
+                              unsigned surface_format,<br>
+                              bool is_array,<br>
+                              unsigned depth,<br>
+                              unsigned min_array_element,<br>
+                              unsigned rt_view_extent,<br>
+                              unsigned mocs,<br>
+                              unsigned mip_count,<br>
+                              int swizzle,<br>
+                              bool is_render_target)<br>
+{<br>
+   uint32_t *surf = brw_state_batch(brw, AUB_TRACE_SURFACE_STATE,<br>
+                                    8 * 4, 32, out_offset);<br>
+   surf[0] = surface_type << BRW_SURFACE_TYPE_SHIFT |<br>
+             surface_format << BRW_SURFACE_FORMAT_SHIFT |<br>
+             gen7_surface_tiling_mode(mt->region->tiling) |<br>
+             BRW_SURFACE_CUBEFACE_ENABLES |<br>
+             (mt->align_h == 4 ? GEN7_SURFACE_VALIGN_4 : GEN7_SURFACE_VALIGN_2) |<br>
+             (mt->align_w == 8 ? GEN7_SURFACE_HALIGN_8 : GEN7_SURFACE_HALIGN_4) |<br>
+             (is_array ? GEN7_SURFACE_IS_ARRAY : 0) |<br>
+             (mt->array_spacing_lod0 ? GEN7_SURFACE_ARYSPC_LOD0<br>
+                                     : GEN7_SURFACE_ARYSPC_FULL);<br>
+   surf[1] = mt->region->bo->offset + bo_offset; /* reloc */<br>
+   surf[2] = SET_FIELD(mt->logical_width0 - 1, GEN7_SURFACE_WIDTH) |<br>
+             SET_FIELD(mt->logical_height0 - 1, GEN7_SURFACE_HEIGHT);<br>
+   surf[3] = SET_FIELD(depth - 1, BRW_SURFACE_DEPTH) |<br>
+             (mt->region->pitch - 1);<br>
+   surf[4] = min_array_element << GEN7_SURFACE_MIN_ARRAY_ELEMENT_SHIFT |<br>
+             rt_view_extent << GEN7_SURFACE_RENDER_TARGET_VIEW_EXTENT_SHIFT |<br>
+             gen7_surface_msaa_bits(mt->num_samples, mt->msaa_layout);<br>
+   surf[5] = SET_FIELD(mocs, GEN7_SURFACE_MOCS) | mip_count;<br>
+<br>
+   if (mt->mcs_mt) {<br>
+      gen7_set_surface_mcs_info(brw, surf, *out_offset, mt->mcs_mt, true);<br>
+   } else {<br>
+      surf[6] = 0;<br>
+   }<br>
+<br>
+   surf[7] = mt->fast_clear_color_value;<br>
+<br>
+   if (brw->is_haswell) {<br>
+      surf[7] |=<br>
+         SET_FIELD(swizzle_to_scs(GET_SWZ(swizzle, 0)), GEN7_SURFACE_SCS_R) |<br>
+         SET_FIELD(swizzle_to_scs(GET_SWZ(swizzle, 1)), GEN7_SURFACE_SCS_G) |<br>
+         SET_FIELD(swizzle_to_scs(GET_SWZ(swizzle, 2)), GEN7_SURFACE_SCS_B) |<br>
+         SET_FIELD(swizzle_to_scs(GET_SWZ(swizzle, 3)), GEN7_SURFACE_SCS_A);<br>
+   }<br>
+<br>
+   uint32_t read_domain =<br>
+      is_render_target ? I915_GEM_DOMAIN_RENDER : I915_GEM_DOMAIN_SAMPLER;<br>
+<br>
+   /* Emit relocation to surface contents */<br>
+   drm_intel_bo_emit_reloc(brw-><a href="http://batch.bo" target="_blank">batch.bo</a>, *out_offset + 4,<br>
+                          mt->region->bo, bo_offset,<br>
+                           read_domain, 0);<br>
+<br>
+   gen7_check_surface_setup(surf, is_render_target);<br>
+}<br>
+<br>
+static void<br>
 gen7_update_buffer_texture_surface(struct gl_context *ctx,<br>
                                    unsigned unit,<br>
                                    uint32_t *surf_offset)<br>
@@ -305,43 +369,14 @@ gen7_update_texture_surface(struct gl_context *ctx,<br>
       return;<br>
    }<br>
<br>
-   uint32_t *surf = brw_state_batch(brw, AUB_TRACE_SURFACE_STATE,<br>
-                                    8 * 4, 32, surf_offset);<br>
-   memset(surf, 0, 8 * 4);<br>
-<br>
-   uint32_t tex_format = translate_tex_format(brw,<br>
+   bool is_array = mt->logical_depth0 > 1 && tObj->Target != GL_TEXTURE_3D;<br>
+   unsigned mip_count = intelObj->_MaxLevel - intel_image->mt->first_level;<br>
+   uint32_t brw_format = translate_tex_format(brw,<br>
                                               mt->format,<br>
                                               tObj->DepthMode,<br>
                                               sampler->sRGBDecode);<br>
<br>
-   surf[0] = translate_tex_target(tObj->Target) << BRW_SURFACE_TYPE_SHIFT |<br>
-             tex_format << BRW_SURFACE_FORMAT_SHIFT |<br>
-             gen7_surface_tiling_mode(mt->region->tiling) |<br>
-             BRW_SURFACE_CUBEFACE_ENABLES;<br>
-<br>
-   if (mt->align_h == 4)<br>
-      surf[0] |= GEN7_SURFACE_VALIGN_4;<br>
-   if (mt->align_w == 8)<br>
-      surf[0] |= GEN7_SURFACE_HALIGN_8;<br>
-<br>
-   if (mt->logical_depth0 > 1 && tObj->Target != GL_TEXTURE_3D)<br>
-      surf[0] |= GEN7_SURFACE_IS_ARRAY;<br>
-<br>
-   if (mt->array_spacing_lod0)<br>
-      surf[0] |= GEN7_SURFACE_ARYSPC_LOD0;<br>
-<br>
-   surf[1] = mt->region->bo->offset + mt->offset; /* reloc */<br>
-<br>
-   surf[2] = SET_FIELD(mt->logical_width0 - 1, GEN7_SURFACE_WIDTH) |<br>
-             SET_FIELD(mt->logical_height0 - 1, GEN7_SURFACE_HEIGHT);<br>
-   surf[3] = SET_FIELD(mt->logical_depth0 - 1, BRW_SURFACE_DEPTH) |<br>
-             ((intelObj->mt->region->pitch) - 1);<br>
-<br>
-   surf[4] = gen7_surface_msaa_bits(mt->num_samples, mt->msaa_layout);<br>
-<br>
-   surf[5] = (SET_FIELD(GEN7_MOCS_L3, GEN7_SURFACE_MOCS) |<br>
-              /* mip count */<br>
-              (intelObj->_MaxLevel - intel_image->mt->first_level));<br>
+   int swizzle = SWIZZLE_XYZW;<br>
<br>
    if (brw->is_haswell) {<br>
       /* Handling GL_ALPHA as a surface format override breaks 1.30+ style<br>
@@ -352,24 +387,24 @@ gen7_update_texture_surface(struct gl_context *ctx,<br>
          (firstImage->_BaseFormat == GL_DEPTH_COMPONENT ||<br>
           firstImage->_BaseFormat == GL_DEPTH_STENCIL);<br>
<br>
-      const int swizzle = unlikely(alpha_depth)<br>
-         ? SWIZZLE_XYZW : brw_get_texture_swizzle(ctx, tObj);<br>
-<br>
-      surf[7] =<br>
-         SET_FIELD(swizzle_to_scs(GET_SWZ(swizzle, 0)), GEN7_SURFACE_SCS_R) |<br>
-         SET_FIELD(swizzle_to_scs(GET_SWZ(swizzle, 1)), GEN7_SURFACE_SCS_G) |<br>
-         SET_FIELD(swizzle_to_scs(GET_SWZ(swizzle, 2)), GEN7_SURFACE_SCS_B) |<br>
-         SET_FIELD(swizzle_to_scs(GET_SWZ(swizzle, 3)), GEN7_SURFACE_SCS_A);<br>
+      if (likely(!alpha_depth))<br>
+         swizzle = brw_get_texture_swizzle(ctx, tObj);<br>
    }<br>
<br>
-   /* Emit relocation to surface contents */<br>
-   drm_intel_bo_emit_reloc(brw-><a href="http://batch.bo" target="_blank">batch.bo</a>,<br>
-                          *surf_offset + 4,<br>
-                          intelObj->mt->region->bo,<br>
-                           surf[1] - intelObj->mt->region->bo->offset,<br>
-                          I915_GEM_DOMAIN_SAMPLER, 0);<br>
-<br>
-   gen7_check_surface_setup(surf, false /* is_render_target */);<br>
+   gen7_emit_image_surface_state(brw,<br>
+                                 surf_offset,<br>
+                                 mt,<br>
+                                 mt->offset,<br>
+                                 translate_tex_target(tObj->Target),<br>
+                                 brw_format,<br>
+                                 is_array,<br>
+                                 mt->logical_depth0,<br>
+                                 0, /* min_array_element */<br>
+                                 0, /* render target view extent */<br>
+                                 GEN7_MOCS_L3,<br>
+                                 mip_count,<br>
+                                 swizzle,<br>
+                                 false /* is_render_target */);<br>
 }<br>
<br>
 /**<br>
@@ -467,31 +502,24 @@ gen7_update_renderbuffer_surface(struct brw_context *brw,<br>
 {<br>
    struct gl_context *ctx = &brw->ctx;<br>
    struct intel_renderbuffer *irb = intel_renderbuffer(rb);<br>
-   struct intel_region *region = irb->mt->region;<br>
-   uint32_t format;<br>
    /* _NEW_BUFFERS */<br>
    gl_format rb_format = _mesa_get_render_format(ctx, intel_rb_format(irb));<br>
    uint32_t surftype;<br>
    bool is_array = false;<br>
    int depth = MAX2(rb->Depth, 1);<br>
    int min_array_element;<br>
-   const uint8_t mocs = GEN7_MOCS_L3;<br>
    GLenum gl_target = rb->TexImage ?<br>
                          rb->TexImage->TexObject->Target : GL_TEXTURE_2D;<br>
<br>
    uint32_t surf_index = SURF_INDEX_DRAW(unit);<br>
<br>
-   uint32_t *surf = brw_state_batch(brw, AUB_TRACE_SURFACE_STATE, 8 * 4, 32,<br>
-                                    &brw->wm.base.surf_offset[surf_index]);<br>
-   memset(surf, 0, 8 * 4);<br>
-<br>
    intel_miptree_used_for_rendering(irb->mt);<br>
<br>
    /* Render targets can't use IMS layout */<br>
    assert(irb->mt->msaa_layout != INTEL_MSAA_LAYOUT_IMS);<br>
<br>
    assert(brw_render_target_supported(brw, rb));<br>
-   format = brw->render_target_format[rb_format];<br>
+   uint32_t brw_format = brw->render_target_format[rb_format];<br>
    if (unlikely(!brw->format_supported_as_render_target[rb_format])) {<br>
       _mesa_problem(ctx, "%s: renderbuffer format %s unsupported\n",<br>
                     __FUNCTION__, _mesa_get_format_name(rb_format));<br>
@@ -518,60 +546,20 @@ gen7_update_renderbuffer_surface(struct brw_context *brw,<br>
       min_array_element = irb->mt_layer;<br>
    }<br>
<br>
-   surf[0] = surftype << BRW_SURFACE_TYPE_SHIFT |<br>
-             format << BRW_SURFACE_FORMAT_SHIFT |<br>
-             (irb->mt->array_spacing_lod0 ? GEN7_SURFACE_ARYSPC_LOD0<br>
-                                          : GEN7_SURFACE_ARYSPC_FULL) |<br>
-             gen7_surface_tiling_mode(region->tiling);<br>
-<br>
-   if (irb->mt->align_h == 4)<br>
-      surf[0] |= GEN7_SURFACE_VALIGN_4;<br>
-   if (irb->mt->align_w == 8)<br>
-      surf[0] |= GEN7_SURFACE_HALIGN_8;<br>
-<br>
-   if (is_array) {<br>
-      surf[0] |= GEN7_SURFACE_IS_ARRAY;<br>
-   }<br>
-<br>
-   surf[1] = region->bo->offset;<br>
-<br>
-   assert(brw->has_surface_tile_offset);<br>
-<br>
-   surf[5] = SET_FIELD(mocs, GEN7_SURFACE_MOCS) |<br>
-             (irb->mt_level - irb->mt->first_level);<br>
-<br>
-   surf[2] = SET_FIELD(irb->mt->logical_width0 - 1, GEN7_SURFACE_WIDTH) |<br>
-             SET_FIELD(irb->mt->logical_height0 - 1, GEN7_SURFACE_HEIGHT);<br>
-<br>
-   surf[3] = ((depth - 1) << BRW_SURFACE_DEPTH_SHIFT) |<br>
-             (region->pitch - 1);<br>
-<br>
-   surf[4] = gen7_surface_msaa_bits(irb->mt->num_samples, irb->mt->msaa_layout) |<br>
-             min_array_element << GEN7_SURFACE_MIN_ARRAY_ELEMENT_SHIFT |<br>
-             (depth - 1) << GEN7_SURFACE_RENDER_TARGET_VIEW_EXTENT_SHIFT;<br>
-<br>
-   if (irb->mt->mcs_mt) {<br>
-      gen7_set_surface_mcs_info(brw, surf, brw->wm.base.surf_offset[surf_index],<br>
-                                irb->mt->mcs_mt, true /* is RT */);<br>
-   }<br>
-<br>
-   surf[7] = irb->mt->fast_clear_color_value;<br>
-<br>
-   if (brw->is_haswell) {<br>
-      surf[7] |= (SET_FIELD(HSW_SCS_RED,   GEN7_SURFACE_SCS_R) |<br>
-                  SET_FIELD(HSW_SCS_GREEN, GEN7_SURFACE_SCS_G) |<br>
-                  SET_FIELD(HSW_SCS_BLUE,  GEN7_SURFACE_SCS_B) |<br>
-                  SET_FIELD(HSW_SCS_ALPHA, GEN7_SURFACE_SCS_A));<br>
-   }<br>
-<br>
-   drm_intel_bo_emit_reloc(brw-><a href="http://batch.bo" target="_blank">batch.bo</a>,<br>
-                          brw->wm.base.surf_offset[surf_index] + 4,<br>
-                          region->bo,<br>
-                          surf[1] - region->bo->offset,<br>
-                          I915_GEM_DOMAIN_RENDER,<br>
-                          I915_GEM_DOMAIN_RENDER);<br></blockquote><div><br></div><div>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?<br>
</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
-<br>
-   gen7_check_surface_setup(surf, true /* is_render_target */);<br>
+   gen7_emit_image_surface_state(brw,<br>
+                                 &brw->wm.base.surf_offset[surf_index],<br>
+                                 irb->mt,<br>
+                                 0,<br></blockquote><div><br></div><div>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.)<br>
<br></div><div>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.<br><br></div><div>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:<br>
<br></div><div>Reviewed-by: Paul Berry <<a href="mailto:stereotype441@gmail.com">stereotype441@gmail.com</a>><br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">

+                                 surftype,<br>
+                                 brw_format,<br>
+                                 is_array,<br>
+                                 depth,<br>
+                                 min_array_element,<br>
+                                 depth - 1, /* render target view extent */<br>
+                                 GEN7_MOCS_L3,<br>
+                                 irb->mt_level - irb->mt->first_level,<br>
+                                 SWIZZLE_XYZW,<br>
+                                 true);<br>
 }<br>
<br>
 void<br>
<span class=""><font color="#888888">--<br>
1.8.3.4<br>
<br>
_______________________________________________<br>
mesa-dev mailing list<br>
<a href="mailto:mesa-dev@lists.freedesktop.org">mesa-dev@lists.freedesktop.org</a><br>
<a href="http://lists.freedesktop.org/mailman/listinfo/mesa-dev" target="_blank">http://lists.freedesktop.org/mailman/listinfo/mesa-dev</a><br>
</font></span></blockquote></div><br></div></div>