[Mesa-dev] [PATCH 02/12] intel: Create intel_miptree_get_region() to prepare for fast color clear.

Ian Romanick idr at freedesktop.org
Wed May 22 12:21:01 PDT 2013


On 05/21/2013 04:52 PM, Paul Berry wrote:
> With the advent of fast color clears, it will no longer be safe for
> the driver to access the data stored in a miptree with impunity.  For
> example, sometimes a resolve will need to be performed first (to
> ensure that deferred writes due to a fast clear are performed before
> the buffer is accessed).  Other times, fast clear will need to be
> disabled for the miptree, so that its contents can be safely shared
> with an entity that Mesa can't synchronize with easily.
>
> To prepare for that, this patch renames intel_mipmap_tree::region to
> intel_mipmap_tree::region_private and creates an accessor function,
> intel_miptree_get_region().  At the moment, the accessor function
> simply returns region_private.  Later in the patch series, this
> function will be expanded to take appropriate actions to maintain the
> proper fast color clear state.
>
> As much as possible, I've tried to restrict the functions which
> directly access region_private to low-level miptree functions
> (e.g. miptree initialization functions), so that it will be easy to
> verify that those functions access the miptree contents safely.
> ---
>   src/mesa/drivers/dri/i915/i830_texstate.c         |  12 +-
>   src/mesa/drivers/dri/i915/i830_vtbl.c             |  28 ++++-
>   src/mesa/drivers/dri/i915/i915_texstate.c         |  12 +-
>   src/mesa/drivers/dri/i915/i915_vtbl.c             |  13 +-
>   src/mesa/drivers/dri/i915/intel_clear.c           |   8 +-
>   src/mesa/drivers/dri/i965/brw_blorp.cpp           |   6 +-
>   src/mesa/drivers/dri/i965/brw_blorp.h             |   3 +-
>   src/mesa/drivers/dri/i965/brw_blorp_clear.cpp     |   4 +-
>   src/mesa/drivers/dri/i965/brw_context.h           |   3 +-
>   src/mesa/drivers/dri/i965/brw_misc_state.c        |  57 ++++++---
>   src/mesa/drivers/dri/i965/brw_state.h             |   2 +-
>   src/mesa/drivers/dri/i965/brw_wm_surface_state.c  |  17 +--
>   src/mesa/drivers/dri/i965/gen6_blorp.cpp          |  29 +++--
>   src/mesa/drivers/dri/i965/gen7_blorp.cpp          |  30 +++--
>   src/mesa/drivers/dri/i965/gen7_misc_state.c       |  21 +++-
>   src/mesa/drivers/dri/i965/gen7_wm_surface_state.c |  31 +++--
>   src/mesa/drivers/dri/intel/intel_blit.c           |   9 +-
>   src/mesa/drivers/dri/intel/intel_buffer_objects.c |  34 +++--
>   src/mesa/drivers/dri/intel/intel_buffers.c        |  10 +-
>   src/mesa/drivers/dri/intel/intel_buffers.h        |   9 +-
>   src/mesa/drivers/dri/intel/intel_context.c        |   8 +-
>   src/mesa/drivers/dri/intel/intel_fbo.c            |  16 ++-
>   src/mesa/drivers/dri/intel/intel_fbo.h            |   8 +-
>   src/mesa/drivers/dri/intel/intel_mipmap_tree.c    | 145 ++++++++++++++--------
>   src/mesa/drivers/dri/intel/intel_mipmap_tree.h    |  72 ++++++++++-
>   src/mesa/drivers/dri/intel/intel_pixel_bitmap.c   |   3 +-
>   src/mesa/drivers/dri/intel/intel_pixel_copy.c     |  14 ++-
>   src/mesa/drivers/dri/intel/intel_pixel_read.c     |   3 +-
>   src/mesa/drivers/dri/intel/intel_screen.c         |  21 ++--
>   src/mesa/drivers/dri/intel/intel_tex_copy.c       |  14 ++-
>   src/mesa/drivers/dri/intel/intel_tex_image.c      |  21 ++--
>   src/mesa/drivers/dri/intel/intel_tex_subimage.c   |  27 ++--
>   32 files changed, 480 insertions(+), 210 deletions(-)
>
> diff --git a/src/mesa/drivers/dri/i915/i830_texstate.c b/src/mesa/drivers/dri/i915/i830_texstate.c
> index f186fac..b2eb724 100644
> --- a/src/mesa/drivers/dri/i915/i830_texstate.c
> +++ b/src/mesa/drivers/dri/i915/i830_texstate.c
> @@ -148,9 +148,11 @@ i830_update_tex_unit(struct intel_context *intel, GLuint unit, GLuint ss3)
>      intel_miptree_get_image_offset(intelObj->mt, tObj->BaseLevel, 0,
>   				  &dst_x, &dst_y);
>
> -   drm_intel_bo_reference(intelObj->mt->region->bo);
> -   i830->state.tex_buffer[unit] = intelObj->mt->region->bo;
> -   pitch = intelObj->mt->region->pitch;
> +   struct intel_region *region =
> +      intel_miptree_get_region(intel, intelObj->mt, INTEL_MIPTREE_ACCESS_TEX);
> +   drm_intel_bo_reference(region->bo);
> +   i830->state.tex_buffer[unit] = region->bo;
> +   pitch = region->pitch;
>
>      /* XXX: This calculation is probably broken for tiled images with
>       * a non-page-aligned offset.
> @@ -166,9 +168,9 @@ i830_update_tex_unit(struct intel_context *intel, GLuint unit, GLuint ss3)
>         (((firstImage->Height - 1) << TM0S1_HEIGHT_SHIFT) |
>          ((firstImage->Width - 1) << TM0S1_WIDTH_SHIFT) | format);
>
> -   if (intelObj->mt->region->tiling != I915_TILING_NONE) {
> +   if (region->tiling != I915_TILING_NONE) {
>         state[I830_TEXREG_TM0S1] |= TM0S1_TILED_SURFACE;
> -      if (intelObj->mt->region->tiling == I915_TILING_Y)
> +      if (region->tiling == I915_TILING_Y)
>   	 state[I830_TEXREG_TM0S1] |= TM0S1_TILE_WALK;
>      }
>
> diff --git a/src/mesa/drivers/dri/i915/i830_vtbl.c b/src/mesa/drivers/dri/i915/i830_vtbl.c
> index b30f45e..a35f58b 100644
> --- a/src/mesa/drivers/dri/i915/i830_vtbl.c
> +++ b/src/mesa/drivers/dri/i915/i830_vtbl.c
> @@ -760,7 +760,13 @@ i830_update_draw_buffer(struct intel_context *intel)
>
>          for (i = 0; i < fb->_NumColorDrawBuffers; i++) {
>              irb = intel_renderbuffer(fb->_ColorDrawBuffers[i]);
> -           colorRegions[i] = (irb && irb->mt) ? irb->mt->region : NULL;
> +           if (irb && irb->mt) {
> +              colorRegions[i] =
> +                 intel_miptree_get_region(intel, irb->mt,
> +                                          INTEL_MIPTREE_ACCESS_RENDER);
> +           } else {
> +              colorRegions[i] = NULL;
> +           }

This idiom appears several places.  Would it be better to pass irb and 
let intel_miptree_get_region return NULL?  Or have a wrapper function? 
Just thinking out loud...

>          }
>      }
>      else {
> @@ -770,15 +776,23 @@ i830_update_draw_buffer(struct intel_context *intel)
>         if (_mesa_is_winsys_fbo(fb)) {
>   	 /* drawing to window system buffer */
>   	 if (fb->_ColorDrawBufferIndexes[0] == BUFFER_FRONT_LEFT)
> -	    colorRegions[0] = intel_get_rb_region(fb, BUFFER_FRONT_LEFT);
> +	    colorRegions[0] = intel_get_rb_region(intel, fb, BUFFER_FRONT_LEFT,
> +                                                  INTEL_MIPTREE_ACCESS_RENDER);
>   	 else
> -	    colorRegions[0] = intel_get_rb_region(fb, BUFFER_BACK_LEFT);
> +	    colorRegions[0] = intel_get_rb_region(intel, fb, BUFFER_BACK_LEFT,
> +                                                  INTEL_MIPTREE_ACCESS_RENDER);
>         }
>         else {
>   	 /* drawing to user-created FBO */
>   	 struct intel_renderbuffer *irb;
>   	 irb = intel_renderbuffer(fb->_ColorDrawBuffers[0]);
> -	 colorRegions[0] = (irb && irb->mt->region) ? irb->mt->region : NULL;
> +         if (irb && irb->mt) {
> +            colorRegions[0] =
> +               intel_miptree_get_region(intel, irb->mt,
> +                                        INTEL_MIPTREE_ACCESS_RENDER);
> +         } else {
> +            colorRegions[0] = NULL;
> +         }
>         }
>      }
>
> @@ -792,7 +806,8 @@ i830_update_draw_buffer(struct intel_context *intel)
>      /* Check for depth fallback. */
>      if (irbDepth && irbDepth->mt) {
>         FALLBACK(intel, INTEL_FALLBACK_DEPTH_BUFFER, false);
> -      depthRegion = irbDepth->mt->region;
> +      depthRegion = intel_miptree_get_region(intel, irbDepth->mt,
> +                                             INTEL_MIPTREE_ACCESS_RENDER);
>      } else if (irbDepth && !irbDepth->mt) {
>         FALLBACK(intel, INTEL_FALLBACK_DEPTH_BUFFER, true);
>         depthRegion = NULL;
> @@ -818,7 +833,8 @@ i830_update_draw_buffer(struct intel_context *intel)
>       */
>      if (depthRegion == NULL && irbStencil && irbStencil->mt
>          && intel_rb_format(irbStencil) == MESA_FORMAT_S8_Z24) {
> -      depthRegion = irbStencil->mt->region;
> +      depthRegion = intel_miptree_get_region(intel, irbStencil->mt,
> +                                             INTEL_MIPTREE_ACCESS_RENDER);
>      }
>
>      /*
> diff --git a/src/mesa/drivers/dri/i915/i915_texstate.c b/src/mesa/drivers/dri/i915/i915_texstate.c
> index 43c802b..d186e77 100644
> --- a/src/mesa/drivers/dri/i915/i915_texstate.c
> +++ b/src/mesa/drivers/dri/i915/i915_texstate.c
> @@ -168,8 +168,10 @@ i915_update_tex_unit(struct intel_context *intel, GLuint unit, GLuint ss3)
>       */
>      firstImage = tObj->Image[0][tObj->BaseLevel];
>
> -   drm_intel_bo_reference(intelObj->mt->region->bo);
> -   i915->state.tex_buffer[unit] = intelObj->mt->region->bo;
> +   struct intel_region *region =
> +      intel_miptree_get_region(intel, intelObj->mt, INTEL_MIPTREE_ACCESS_TEX);
> +   drm_intel_bo_reference(region->bo);
> +   i915->state.tex_buffer[unit] = region->bo;
>      i915->state.tex_offset[unit] = intelObj->mt->offset;
>
>      format = translate_texture_format(firstImage->TexFormat,
> @@ -179,9 +181,9 @@ i915_update_tex_unit(struct intel_context *intel, GLuint unit, GLuint ss3)
>         (((firstImage->Height - 1) << MS3_HEIGHT_SHIFT) |
>          ((firstImage->Width - 1) << MS3_WIDTH_SHIFT) | format);
>
> -   if (intelObj->mt->region->tiling != I915_TILING_NONE) {
> +   if (region->tiling != I915_TILING_NONE) {
>         state[I915_TEXREG_MS3] |= MS3_TILED_SURFACE;
> -      if (intelObj->mt->region->tiling == I915_TILING_Y)
> +      if (region->tiling == I915_TILING_Y)
>   	 state[I915_TEXREG_MS3] |= MS3_TILE_WALK;
>      }
>
> @@ -191,7 +193,7 @@ i915_update_tex_unit(struct intel_context *intel, GLuint unit, GLuint ss3)
>       */
>      maxlod = MIN2(sampler->MaxLod, tObj->_MaxLevel - tObj->BaseLevel);
>      state[I915_TEXREG_MS4] =
> -      ((((intelObj->mt->region->pitch / 4) - 1) << MS4_PITCH_SHIFT) |
> +      ((((region->pitch / 4) - 1) << MS4_PITCH_SHIFT) |
>          MS4_CUBE_FACE_ENA_MASK |
>          (U_FIXED(CLAMP(maxlod, 0.0, 11.0), 2) << MS4_MAX_LOD_SHIFT) |
>          ((firstImage->Depth - 1) << MS4_VOLUME_DEPTH_SHIFT));
> diff --git a/src/mesa/drivers/dri/i915/i915_vtbl.c b/src/mesa/drivers/dri/i915/i915_vtbl.c
> index 91fde55..94939e6 100644
> --- a/src/mesa/drivers/dri/i915/i915_vtbl.c
> +++ b/src/mesa/drivers/dri/i915/i915_vtbl.c
> @@ -758,14 +758,20 @@ i915_update_draw_buffer(struct intel_context *intel)
>      } else {
>         struct intel_renderbuffer *irb;
>         irb = intel_renderbuffer(fb->_ColorDrawBuffers[0]);
> -      colorRegion = (irb && irb->mt) ? irb->mt->region : NULL;
> +      if (irb && irb->mt) {
> +         colorRegion = intel_miptree_get_region(intel, irb->mt,
> +                                                INTEL_MIPTREE_ACCESS_RENDER);
> +      } else {
> +         colorRegion = NULL;
> +      }
>         FALLBACK(intel, INTEL_FALLBACK_DRAW_BUFFER, false);
>      }
>
>      /* Check for depth fallback. */
>      if (irbDepth && irbDepth->mt) {
>         FALLBACK(intel, INTEL_FALLBACK_DEPTH_BUFFER, false);
> -      depthRegion = irbDepth->mt->region;
> +      depthRegion = intel_miptree_get_region(intel, irbDepth->mt,
> +                                             INTEL_MIPTREE_ACCESS_RENDER);
>      } else if (irbDepth && !irbDepth->mt) {
>         FALLBACK(intel, INTEL_FALLBACK_DEPTH_BUFFER, true);
>         depthRegion = NULL;
> @@ -791,7 +797,8 @@ i915_update_draw_buffer(struct intel_context *intel)
>       */
>      if (depthRegion == NULL && irbStencil && irbStencil->mt
>          && intel_rb_format(irbStencil) == MESA_FORMAT_S8_Z24) {
> -      depthRegion = irbStencil->mt->region;
> +      depthRegion = intel_miptree_get_region(intel, irbStencil->mt,
> +                                             INTEL_MIPTREE_ACCESS_RENDER);
>      }
>
>      /*
> diff --git a/src/mesa/drivers/dri/i915/intel_clear.c b/src/mesa/drivers/dri/i915/intel_clear.c
> index ebac0f5..b397241 100644
> --- a/src/mesa/drivers/dri/i915/intel_clear.c
> +++ b/src/mesa/drivers/dri/i915/intel_clear.c
> @@ -37,6 +37,7 @@
>   #include "intel_clear.h"
>   #include "intel_fbo.h"
>   #include "intel_regions.h"
> +#include "intel_mipmap_tree.h"
>
>   #define FILE_DEBUG_FLAG DEBUG_BLIT
>
> @@ -129,7 +130,8 @@ intelClear(struct gl_context *ctx, GLbitfield mask)
>      /* HW stencil */
>      if (mask & BUFFER_BIT_STENCIL) {
>         const struct intel_region *stencilRegion
> -         = intel_get_rb_region(fb, BUFFER_STENCIL);
> +         = intel_get_rb_region(intel, fb, BUFFER_STENCIL,
> +                               INTEL_MIPTREE_ACCESS_NONE);
>         if (stencilRegion) {
>            /* have hw stencil */
>            if (stencilRegion->tiling == I915_TILING_Y ||
> @@ -149,7 +151,9 @@ intelClear(struct gl_context *ctx, GLbitfield mask)
>
>      /* HW depth */
>      if (mask & BUFFER_BIT_DEPTH) {
> -      const struct intel_region *irb = intel_get_rb_region(fb, BUFFER_DEPTH);
> +      const struct intel_region *irb =
> +         intel_get_rb_region(intel, fb, BUFFER_DEPTH,
> +                             INTEL_MIPTREE_ACCESS_NONE);
>
>         /* clear depth with whatever method is used for stencil (see above) */
>         if (irb->tiling == I915_TILING_Y || tri_mask & BUFFER_BIT_STENCIL)
> diff --git a/src/mesa/drivers/dri/i965/brw_blorp.cpp b/src/mesa/drivers/dri/i965/brw_blorp.cpp
> index a2d02bf..20f7153 100644
> --- a/src/mesa/drivers/dri/i965/brw_blorp.cpp
> +++ b/src/mesa/drivers/dri/i965/brw_blorp.cpp
> @@ -120,10 +120,12 @@ brw_blorp_surface_info::set(struct brw_context *brw,
>    * directly from the adjusted offsets.
>    */
>   uint32_t
> -brw_blorp_surface_info::compute_tile_offsets(uint32_t *tile_x,
> +brw_blorp_surface_info::compute_tile_offsets(struct intel_context *intel,
> +                                             uint32_t *tile_x,
>                                                uint32_t *tile_y) const
>   {
> -   struct intel_region *region = mt->region;
> +   struct intel_region *region =
> +      intel_miptree_get_region(intel, mt, INTEL_MIPTREE_ACCESS_NONE);
>      uint32_t mask_x, mask_y;
>
>      intel_region_get_tile_masks(region, &mask_x, &mask_y,
> diff --git a/src/mesa/drivers/dri/i965/brw_blorp.h b/src/mesa/drivers/dri/i965/brw_blorp.h
> index 8915080..6360a62 100644
> --- a/src/mesa/drivers/dri/i965/brw_blorp.h
> +++ b/src/mesa/drivers/dri/i965/brw_blorp.h
> @@ -118,7 +118,8 @@ public:
>               struct intel_mipmap_tree *mt,
>               unsigned int level, unsigned int layer);
>
> -   uint32_t compute_tile_offsets(uint32_t *tile_x, uint32_t *tile_y) const;
> +   uint32_t compute_tile_offsets(struct intel_context *intel,
> +                                 uint32_t *tile_x, uint32_t *tile_y) const;
>
>      /* Setting this flag indicates that the buffer's contents are W-tiled
>       * stencil data, but the surface state should be set up for Y tiled
> diff --git a/src/mesa/drivers/dri/i965/brw_blorp_clear.cpp b/src/mesa/drivers/dri/i965/brw_blorp_clear.cpp
> index b626659..28d7ad0 100644
> --- a/src/mesa/drivers/dri/i965/brw_blorp_clear.cpp
> +++ b/src/mesa/drivers/dri/i965/brw_blorp_clear.cpp
> @@ -149,7 +149,9 @@ brw_blorp_clear_params::brw_blorp_clear_params(struct brw_context *brw,
>       *      accessing tiled memory.  Using this Message Type to access linear
>       *      (untiled) memory is UNDEFINED."
>       */
> -   if (irb->mt->region->tiling == I915_TILING_NONE)
> +   struct intel_region *region =
> +      intel_miptree_get_region(intel, irb->mt, INTEL_MIPTREE_ACCESS_NONE);
> +   if (region->tiling == I915_TILING_NONE)
>         wm_prog_key.use_simd16_replicated_data = false;
>
>      /* Constant color writes ignore everyting in blend and color calculator
> diff --git a/src/mesa/drivers/dri/i965/brw_context.h b/src/mesa/drivers/dri/i965/brw_context.h
> index fbff10b..a25eca8 100644
> --- a/src/mesa/drivers/dri/i965/brw_context.h
> +++ b/src/mesa/drivers/dri/i965/brw_context.h
> @@ -1153,7 +1153,8 @@ bool brwCreateContext(int api,
>   /*======================================================================
>    * brw_misc_state.c
>    */
> -void brw_get_depthstencil_tile_masks(struct intel_mipmap_tree *depth_mt,
> +void brw_get_depthstencil_tile_masks(struct intel_context *intel,
> +                                     struct intel_mipmap_tree *depth_mt,
>                                        uint32_t depth_level,
>                                        uint32_t depth_layer,
>                                        struct intel_mipmap_tree *stencil_mt,
> diff --git a/src/mesa/drivers/dri/i965/brw_misc_state.c b/src/mesa/drivers/dri/i965/brw_misc_state.c
> index 6b61929..d78d445 100644
> --- a/src/mesa/drivers/dri/i965/brw_misc_state.c
> +++ b/src/mesa/drivers/dri/i965/brw_misc_state.c
> @@ -270,7 +270,8 @@ brw_depthbuffer_format(struct brw_context *brw)
>    * mask, then we're in trouble.
>    */
>   void
> -brw_get_depthstencil_tile_masks(struct intel_mipmap_tree *depth_mt,
> +brw_get_depthstencil_tile_masks(struct intel_context *intel,
> +                                struct intel_mipmap_tree *depth_mt,
>                                   uint32_t depth_level,
>                                   uint32_t depth_layer,
>                                   struct intel_mipmap_tree *stencil_mt,
> @@ -280,12 +281,17 @@ brw_get_depthstencil_tile_masks(struct intel_mipmap_tree *depth_mt,
>      uint32_t tile_mask_x = 0, tile_mask_y = 0;
>
>      if (depth_mt) {
> -      intel_region_get_tile_masks(depth_mt->region,
> +      struct intel_region *depth_region =
> +         intel_miptree_get_region(intel, depth_mt, INTEL_MIPTREE_ACCESS_NONE);
> +      struct intel_region *hiz_region =
> +         intel_miptree_get_region(intel, depth_mt->hiz_mt,
> +                                  INTEL_MIPTREE_ACCESS_NONE);
> +      intel_region_get_tile_masks(depth_region,
>                                     &tile_mask_x, &tile_mask_y, false);
>
>         if (intel_miptree_slice_has_hiz(depth_mt, depth_level, depth_layer)) {
>            uint32_t hiz_tile_mask_x, hiz_tile_mask_y;
> -         intel_region_get_tile_masks(depth_mt->hiz_mt->region,
> +         intel_region_get_tile_masks(hiz_region,
>                                        &hiz_tile_mask_x, &hiz_tile_mask_y, false);
>
>            /* Each HiZ row represents 2 rows of pixels */
> @@ -305,8 +311,11 @@ brw_get_depthstencil_tile_masks(struct intel_mipmap_tree *depth_mt,
>            tile_mask_x |= 63;
>            tile_mask_y |= 63;
>         } else {
> +         struct intel_region *stencil_region =
> +            intel_miptree_get_region(intel, stencil_mt,
> +                                     INTEL_MIPTREE_ACCESS_NONE);
>            uint32_t stencil_tile_mask_x, stencil_tile_mask_y;
> -         intel_region_get_tile_masks(stencil_mt->region,
> +         intel_region_get_tile_masks(stencil_region,
>                                        &stencil_tile_mask_x,
>                                        &stencil_tile_mask_y, false);
>
> @@ -368,7 +377,7 @@ brw_workaround_depthstencil_alignment(struct brw_context *brw,
>      }
>
>      uint32_t tile_mask_x, tile_mask_y;
> -   brw_get_depthstencil_tile_masks(depth_mt,
> +   brw_get_depthstencil_tile_masks(intel, depth_mt,
>                                      depth_mt ? depth_irb->mt_level : 0,
>                                      depth_mt ? depth_irb->mt_layer : 0,
>                                      stencil_mt,
> @@ -532,15 +541,17 @@ brw_workaround_depthstencil_alignment(struct brw_context *brw,
>      brw->depthstencil.stencil_mt = NULL;
>      if (depth_irb) {
>         depth_mt = depth_irb->mt;
> +      struct intel_region *depth_region =
> +         intel_miptree_get_region(intel, depth_mt, INTEL_MIPTREE_ACCESS_NONE);
>         brw->depthstencil.depth_mt = depth_mt;
>         brw->depthstencil.depth_offset =
> -         intel_region_get_aligned_offset(depth_mt->region,
> +         intel_region_get_aligned_offset(depth_region,
>                                            depth_irb->draw_x & ~tile_mask_x,
>                                            depth_irb->draw_y & ~tile_mask_y,
>                                            false);
>         if (intel_renderbuffer_has_hiz(depth_irb)) {
>            brw->depthstencil.hiz_offset =
> -            intel_region_get_aligned_offset(depth_mt->region,
> +            intel_region_get_aligned_offset(depth_region,
>                                               depth_irb->draw_x & ~tile_mask_x,
>                                               (depth_irb->draw_y & ~tile_mask_y) /
>                                               2,
> @@ -556,8 +567,11 @@ brw_workaround_depthstencil_alignment(struct brw_context *brw,
>             * intel_region_get_aligned_offset(), because stencil_region claims
>             * that the region is untiled even though it's W tiled.
>             */
> +         struct intel_region *stencil_region =
> +            intel_miptree_get_region(intel, stencil_mt,
> +                                     INTEL_MIPTREE_ACCESS_NONE);
>            brw->depthstencil.stencil_offset =
> -            (stencil_draw_y & ~tile_mask_y) * stencil_mt->region->pitch +
> +            (stencil_draw_y & ~tile_mask_y) * stencil_region->pitch +
>               (stencil_draw_x & ~tile_mask_x) * 64;
>         }
>      }
> @@ -614,8 +628,10 @@ brw_emit_depthbuffer(struct brw_context *brw)
>         /* Prior to Gen7, if using separate stencil, hiz must be enabled. */
>         assert(intel->gen >= 7 || !separate_stencil || hiz);
>
> -      assert(intel->gen < 6 || depth_mt->region->tiling == I915_TILING_Y);
> -      assert(!hiz || depth_mt->region->tiling == I915_TILING_Y);
> +      struct intel_region *depth_region =
> +         intel_miptree_get_region(intel, depth_mt, INTEL_MIPTREE_ACCESS_NONE);
> +      assert(intel->gen < 6 || depth_region->tiling == I915_TILING_Y);
> +      assert(!hiz || depth_region->tiling == I915_TILING_Y);
>
>         depthbuffer_format = brw_depthbuffer_format(brw);
>         depth_surface_type = BRW_SURFACE_2D;
> @@ -670,6 +686,10 @@ brw_emit_depth_stencil_hiz(struct brw_context *brw,
>       */
>      bool enable_hiz_ss = hiz || separate_stencil;
>
> +   struct intel_region *depth_region = depth_mt ?
> +      intel_miptree_get_region(intel, depth_mt, INTEL_MIPTREE_ACCESS_RENDER) :
> +      NULL;
> +
>
>      /* 3DSTATE_DEPTH_BUFFER, 3DSTATE_STENCIL_BUFFER are both
>       * non-pipelined state that will need the PIPE_CONTROL workaround.
> @@ -689,17 +709,17 @@ brw_emit_depth_stencil_hiz(struct brw_context *brw,
>
>      BEGIN_BATCH(len);
>      OUT_BATCH(_3DSTATE_DEPTH_BUFFER << 16 | (len - 2));
> -   OUT_BATCH((depth_mt ? depth_mt->region->pitch - 1 : 0) |
> +   OUT_BATCH((depth_mt ? depth_region->pitch - 1 : 0) |
>                (depthbuffer_format << 18) |
>                ((enable_hiz_ss ? 1 : 0) << 21) | /* separate stencil enable */
>                ((enable_hiz_ss ? 1 : 0) << 22) | /* hiz enable */
>                (BRW_TILEWALK_YMAJOR << 26) |
> -             ((depth_mt ? depth_mt->region->tiling != I915_TILING_NONE : 1)
> +             ((depth_mt ? depth_region->tiling != I915_TILING_NONE : 1)
>                 << 27) |
>                (depth_surface_type << 29));
>
>      if (depth_mt) {
> -      OUT_RELOC(depth_mt->region->bo,
> +      OUT_RELOC(depth_region->bo,
>   		I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER,
>   		depth_offset);
>      } else {
> @@ -732,10 +752,13 @@ brw_emit_depth_stencil_hiz(struct brw_context *brw,
>         /* Emit hiz buffer. */
>         if (hiz) {
>            struct intel_mipmap_tree *hiz_mt = depth_mt->hiz_mt;
> +         struct intel_region *hiz_region =
> +            intel_miptree_get_region(intel, hiz_mt,
> +                                     INTEL_MIPTREE_ACCESS_RENDER);
>   	 BEGIN_BATCH(3);
>   	 OUT_BATCH((_3DSTATE_HIER_DEPTH_BUFFER << 16) | (3 - 2));
> -	 OUT_BATCH(hiz_mt->region->pitch - 1);
> -	 OUT_RELOC(hiz_mt->region->bo,
> +	 OUT_BATCH(hiz_region->pitch - 1);
> +	 OUT_RELOC(hiz_region->bo,
>   		   I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER,
>   		   brw->depthstencil.hiz_offset);
>   	 ADVANCE_BATCH();
> @@ -749,7 +772,9 @@ brw_emit_depth_stencil_hiz(struct brw_context *brw,
>
>         /* Emit stencil buffer. */
>         if (separate_stencil) {
> -	 struct intel_region *region = stencil_mt->region;
> +	 struct intel_region *region =
> +            intel_miptree_get_region(intel, stencil_mt,
> +                                     INTEL_MIPTREE_ACCESS_RENDER);
>
>   	 BEGIN_BATCH(3);
>   	 OUT_BATCH((_3DSTATE_STENCIL_BUFFER << 16) | (3 - 2));
> diff --git a/src/mesa/drivers/dri/i965/brw_state.h b/src/mesa/drivers/dri/i965/brw_state.h
> index 9c956f8..ff17b39 100644
> --- a/src/mesa/drivers/dri/i965/brw_state.h
> +++ b/src/mesa/drivers/dri/i965/brw_state.h
> @@ -206,7 +206,7 @@ uint32_t gen7_surface_msaa_bits(unsigned num_samples, enum intel_msaa_layout l);
>   void gen7_set_surface_mcs_info(struct brw_context *brw,
>                                  uint32_t *surf,
>                                  uint32_t surf_offset,
> -                               const struct intel_mipmap_tree *mcs_mt,
> +                               struct intel_mipmap_tree *mcs_mt,
>                                  bool is_render_target);
>   void gen7_check_surface_setup(uint32_t *surf, bool is_render_target);
>   void gen7_init_vtable_surface_functions(struct brw_context *brw);
> diff --git a/src/mesa/drivers/dri/i965/brw_wm_surface_state.c b/src/mesa/drivers/dri/i965/brw_wm_surface_state.c
> index bbe8579..0173ba6 100644
> --- a/src/mesa/drivers/dri/i965/brw_wm_surface_state.c
> +++ b/src/mesa/drivers/dri/i965/brw_wm_surface_state.c
> @@ -985,15 +985,17 @@ brw_update_texture_surface(struct gl_context *ctx,
>   				    sampler->sRGBDecode) <<
>   	       BRW_SURFACE_FORMAT_SHIFT));
>
> -   surf[1] = intelObj->mt->region->bo->offset + intelObj->mt->offset; /* reloc */
> +   struct intel_region *region =
> +      intel_miptree_get_region(intel, intelObj->mt, INTEL_MIPTREE_ACCESS_TEX);
> +   surf[1] = region->bo->offset + intelObj->mt->offset; /* reloc */
>
>      surf[2] = ((intelObj->_MaxLevel - tObj->BaseLevel) << BRW_SURFACE_LOD_SHIFT |
>   	      (width - 1) << BRW_SURFACE_WIDTH_SHIFT |
>   	      (height - 1) << BRW_SURFACE_HEIGHT_SHIFT);
>
> -   surf[3] = (brw_get_surface_tiling_bits(intelObj->mt->region->tiling) |
> +   surf[3] = (brw_get_surface_tiling_bits(region->tiling) |
>   	      (depth - 1) << BRW_SURFACE_DEPTH_SHIFT |
> -	      (intelObj->mt->region->pitch - 1) <<
> +	      (region->pitch - 1) <<
>   	      BRW_SURFACE_PITCH_SHIFT);
>
>      surf[4] = brw_get_surface_num_multisamples(intelObj->mt->num_samples);
> @@ -1013,7 +1015,7 @@ brw_update_texture_surface(struct gl_context *ctx,
>      /* Emit relocation to surface contents */
>      drm_intel_bo_emit_reloc(brw->intel.batch.bo,
>   			   binding_table[surf_index] + 4,
> -			   intelObj->mt->region->bo,
> +			   region->bo,
>                              intelObj->mt->offset,
>   			   I915_GEM_DOMAIN_SAMPLER, 0);
>   }
> @@ -1329,7 +1331,7 @@ brw_update_renderbuffer_surface(struct brw_context *brw,
>      gl_format rb_format = _mesa_get_render_format(ctx, intel_rb_format(irb));
>
>      if (rb->TexImage && !brw->has_surface_tile_offset) {
> -      intel_renderbuffer_tile_offsets(irb, &tile_x, &tile_y);
> +      intel_renderbuffer_tile_offsets(intel, irb, &tile_x, &tile_y);
>
>         if (tile_x != 0 || tile_y != 0) {
>   	 /* Original gen4 hardware couldn't draw to a non-tile-aligned
> @@ -1343,7 +1345,8 @@ brw_update_renderbuffer_surface(struct brw_context *brw,
>         }
>      }
>
> -   region = irb->mt->region;
> +   region = intel_miptree_get_region(intel, irb->mt,
> +                                     INTEL_MIPTREE_ACCESS_RENDER);
>
>      surf = brw_state_batch(brw, AUB_TRACE_SURFACE_STATE,
>   			  6 * 4, 32, &brw->wm.surf_offset[unit]);
> @@ -1358,7 +1361,7 @@ brw_update_renderbuffer_surface(struct brw_context *brw,
>   	      format << BRW_SURFACE_FORMAT_SHIFT);
>
>      /* reloc */
> -   surf[1] = (intel_renderbuffer_tile_offsets(irb, &tile_x, &tile_y) +
> +   surf[1] = (intel_renderbuffer_tile_offsets(intel, irb, &tile_x, &tile_y) +
>   	      region->bo->offset);
>
>      surf[2] = ((rb->Width - 1) << BRW_SURFACE_WIDTH_SHIFT |
> diff --git a/src/mesa/drivers/dri/i965/gen6_blorp.cpp b/src/mesa/drivers/dri/i965/gen6_blorp.cpp
> index c7bb815..7217212 100644
> --- a/src/mesa/drivers/dri/i965/gen6_blorp.cpp
> +++ b/src/mesa/drivers/dri/i965/gen6_blorp.cpp
> @@ -405,7 +405,8 @@ static uint32_t
>   gen6_blorp_emit_surface_state(struct brw_context *brw,
>                                 const brw_blorp_params *params,
>                                 const brw_blorp_surface_info *surface,
> -                              uint32_t read_domains, uint32_t write_domain)
> +                              uint32_t read_domains, uint32_t write_domain,
> +                              enum intel_miptree_access_type access_type)
>   {
>      uint32_t wm_surf_offset;
>      uint32_t width = surface->width;
> @@ -418,7 +419,8 @@ gen6_blorp_emit_surface_state(struct brw_context *brw,
>         width /= 2;
>         height /= 2;
>      }
> -   struct intel_region *region = surface->mt->region;
> +   struct intel_region *region =
> +      intel_miptree_get_region(&brw->intel, surface->mt, access_type);
>      uint32_t tile_x, tile_y;
>
>      uint32_t *surf = (uint32_t *)
> @@ -431,7 +433,7 @@ gen6_blorp_emit_surface_state(struct brw_context *brw,
>                 surface->brw_surfaceformat << BRW_SURFACE_FORMAT_SHIFT);
>
>      /* reloc */
> -   surf[1] = (surface->compute_tile_offsets(&tile_x, &tile_y) +
> +   surf[1] = (surface->compute_tile_offsets(&brw->intel, &tile_x, &tile_y) +
>                 region->bo->offset);
>
>      surf[2] = (0 << BRW_SURFACE_LOD_SHIFT |
> @@ -862,7 +864,7 @@ gen6_blorp_emit_depth_stencil_config(struct brw_context *brw,
>      uint32_t draw_y = params->depth.y_offset;
>      uint32_t tile_mask_x, tile_mask_y;
>
> -   brw_get_depthstencil_tile_masks(params->depth.mt,
> +   brw_get_depthstencil_tile_masks(intel, params->depth.mt,
>                                      params->depth.level,
>                                      params->depth.layer,
>                                      NULL,
> @@ -870,10 +872,13 @@ gen6_blorp_emit_depth_stencil_config(struct brw_context *brw,
>
>      /* 3DSTATE_DEPTH_BUFFER */
>      {
> +      struct intel_region *depth_region =
> +         intel_miptree_get_region(intel, params->depth.mt,
> +                                  INTEL_MIPTREE_ACCESS_RENDER);
>         uint32_t tile_x = draw_x & tile_mask_x;
>         uint32_t tile_y = draw_y & tile_mask_y;
>         uint32_t offset =
> -         intel_region_get_aligned_offset(params->depth.mt->region,
> +         intel_region_get_aligned_offset(depth_region,
>                                            draw_x & ~tile_mask_x,
>                                            draw_y & ~tile_mask_y, false);
>
> @@ -903,14 +908,14 @@ gen6_blorp_emit_depth_stencil_config(struct brw_context *brw,
>
>         BEGIN_BATCH(7);
>         OUT_BATCH(_3DSTATE_DEPTH_BUFFER << 16 | (7 - 2));
> -      OUT_BATCH((params->depth.mt->region->pitch - 1) |
> +      OUT_BATCH((depth_region->pitch - 1) |
>                   params->depth_format << 18 |
>                   1 << 21 | /* separate stencil enable */
>                   1 << 22 | /* hiz enable */
>                   BRW_TILEWALK_YMAJOR << 26 |
>                   1 << 27 | /* y-tiled */
>                   BRW_SURFACE_2D << 29);
> -      OUT_RELOC(params->depth.mt->region->bo,
> +      OUT_RELOC(depth_region->bo,
>                   I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER,
>                   offset);
>         OUT_BATCH(BRW_SURFACE_MIPMAPLAYOUT_BELOW << 1 |
> @@ -925,7 +930,9 @@ gen6_blorp_emit_depth_stencil_config(struct brw_context *brw,
>
>      /* 3DSTATE_HIER_DEPTH_BUFFER */
>      {
> -      struct intel_region *hiz_region = params->depth.mt->hiz_mt->region;
> +      struct intel_region *hiz_region =
> +         intel_miptree_get_region(intel, params->depth.mt->hiz_mt,
> +                                  INTEL_MIPTREE_ACCESS_RENDER);
>         uint32_t hiz_offset =
>            intel_region_get_aligned_offset(hiz_region,
>                                            draw_x & ~tile_mask_x,
> @@ -1097,11 +1104,13 @@ gen6_blorp_exec(struct intel_context *intel,
>         wm_surf_offset_renderbuffer =
>            gen6_blorp_emit_surface_state(brw, params, &params->dst,
>                                          I915_GEM_DOMAIN_RENDER,
> -                                       I915_GEM_DOMAIN_RENDER);
> +                                       I915_GEM_DOMAIN_RENDER,
> +                                       INTEL_MIPTREE_ACCESS_RENDER);
>         if (params->src.mt) {
>            wm_surf_offset_texture =
>               gen6_blorp_emit_surface_state(brw, params, &params->src,
> -                                          I915_GEM_DOMAIN_SAMPLER, 0);
> +                                          I915_GEM_DOMAIN_SAMPLER, 0,
> +                                          INTEL_MIPTREE_ACCESS_TEX);
>         }
>         wm_bind_bo_offset =
>            gen6_blorp_emit_binding_table(brw, params,
> diff --git a/src/mesa/drivers/dri/i965/gen7_blorp.cpp b/src/mesa/drivers/dri/i965/gen7_blorp.cpp
> index f83c7f2..f9eda63 100644
> --- a/src/mesa/drivers/dri/i965/gen7_blorp.cpp
> +++ b/src/mesa/drivers/dri/i965/gen7_blorp.cpp
> @@ -137,7 +137,8 @@ gen7_blorp_emit_surface_state(struct brw_context *brw,
>                                 const brw_blorp_params *params,
>                                 const brw_blorp_surface_info *surface,
>                                 uint32_t read_domains, uint32_t write_domain,
> -                              bool is_render_target)
> +                              bool is_render_target,
> +                              enum intel_miptree_access_type access_type)
>   {
>      struct intel_context *intel = &brw->intel;
>
> @@ -149,7 +150,8 @@ gen7_blorp_emit_surface_state(struct brw_context *brw,
>       * to divide them by 2 as we do for Gen6 (see
>       * gen6_blorp_emit_surface_state).
>       */
> -   struct intel_region *region = surface->mt->region;
> +   struct intel_region *region =
> +      intel_miptree_get_region(intel, surface->mt, access_type);
>      uint32_t tile_x, tile_y;
>
>      uint32_t tiling = surface->map_stencil_as_y_tiled
> @@ -175,7 +177,8 @@ gen7_blorp_emit_surface_state(struct brw_context *brw,
>
>      /* reloc */
>      surf[1] =
> -      surface->compute_tile_offsets(&tile_x, &tile_y) + region->bo->offset;
> +      surface->compute_tile_offsets(intel, &tile_x, &tile_y) +
> +      region->bo->offset;
>
>      /* Note that the low bits of these fields are missing, so
>       * there's the possibility of getting in trouble.
> @@ -680,7 +683,7 @@ gen7_blorp_emit_depth_stencil_config(struct brw_context *brw,
>      uint32_t draw_y = params->depth.y_offset;
>      uint32_t tile_mask_x, tile_mask_y;
>
> -   brw_get_depthstencil_tile_masks(params->depth.mt,
> +   brw_get_depthstencil_tile_masks(intel, params->depth.mt,
>                                      params->depth.level,
>                                      params->depth.layer,
>                                      NULL,
> @@ -688,10 +691,13 @@ gen7_blorp_emit_depth_stencil_config(struct brw_context *brw,
>
>      /* 3DSTATE_DEPTH_BUFFER */
>      {
> +      struct intel_region *depth_region =
> +         intel_miptree_get_region(intel, params->depth.mt,
> +                                  INTEL_MIPTREE_ACCESS_RENDER);
>         uint32_t tile_x = draw_x & tile_mask_x;
>         uint32_t tile_y = draw_y & tile_mask_y;
>         uint32_t offset =
> -         intel_region_get_aligned_offset(params->depth.mt->region,
> +         intel_region_get_aligned_offset(depth_region,
>                                            draw_x & ~tile_mask_x,
>                                            draw_y & ~tile_mask_y, false);
>
> @@ -720,12 +726,12 @@ gen7_blorp_emit_depth_stencil_config(struct brw_context *brw,
>
>         BEGIN_BATCH(7);
>         OUT_BATCH(GEN7_3DSTATE_DEPTH_BUFFER << 16 | (7 - 2));
> -      OUT_BATCH((params->depth.mt->region->pitch - 1) |
> +      OUT_BATCH((depth_region->pitch - 1) |
>                   params->depth_format << 18 |
>                   1 << 22 | /* hiz enable */
>                   1 << 28 | /* depth write */
>                   BRW_SURFACE_2D << 29);
> -      OUT_RELOC(params->depth.mt->region->bo,
> +      OUT_RELOC(depth_region->bo,
>                   I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER,
>                   offset);
>         OUT_BATCH((params->depth.width + tile_x - 1) << 4 |
> @@ -739,7 +745,9 @@ gen7_blorp_emit_depth_stencil_config(struct brw_context *brw,
>
>      /* 3DSTATE_HIER_DEPTH_BUFFER */
>      {
> -      struct intel_region *hiz_region = params->depth.mt->hiz_mt->region;
> +      struct intel_region *hiz_region =
> +         intel_miptree_get_region(intel, params->depth.mt->hiz_mt,
> +                                  INTEL_MIPTREE_ACCESS_RENDER);
>         uint32_t hiz_offset =
>            intel_region_get_aligned_offset(hiz_region,
>                                            draw_x & ~tile_mask_x,
> @@ -867,12 +875,14 @@ gen7_blorp_exec(struct intel_context *intel,
>            gen7_blorp_emit_surface_state(brw, params, &params->dst,
>                                          I915_GEM_DOMAIN_RENDER,
>                                          I915_GEM_DOMAIN_RENDER,
> -                                       true /* is_render_target */);
> +                                       true /* is_render_target */,
> +                                       INTEL_MIPTREE_ACCESS_RENDER);
>         if (params->src.mt) {
>            wm_surf_offset_texture =
>               gen7_blorp_emit_surface_state(brw, params, &params->src,
>                                             I915_GEM_DOMAIN_SAMPLER, 0,
> -                                          false /* is_render_target */);
> +                                          false /* is_render_target */,
> +                                          INTEL_MIPTREE_ACCESS_TEX);
>         }
>         wm_bind_bo_offset =
>            gen6_blorp_emit_binding_table(brw, params,
> diff --git a/src/mesa/drivers/dri/i965/gen7_misc_state.c b/src/mesa/drivers/dri/i965/gen7_misc_state.c
> index 12b752c..11fbe18 100644
> --- a/src/mesa/drivers/dri/i965/gen7_misc_state.c
> +++ b/src/mesa/drivers/dri/i965/gen7_misc_state.c
> @@ -42,12 +42,16 @@ gen7_emit_depth_stencil_hiz(struct brw_context *brw,
>      struct intel_context *intel = &brw->intel;
>      struct gl_context *ctx = &intel->ctx;
>
> +   struct intel_region *depth_region = depth_mt ?
> +      intel_miptree_get_region(intel, depth_mt, INTEL_MIPTREE_ACCESS_RENDER) :
> +      NULL;
> +
>      intel_emit_depth_stall_flushes(intel);
>
>      /* _NEW_DEPTH, _NEW_STENCIL */
>      BEGIN_BATCH(7);
>      OUT_BATCH(GEN7_3DSTATE_DEPTH_BUFFER << 16 | (7 - 2));
> -   OUT_BATCH((depth_mt ? depth_mt->region->pitch - 1 : 0) |
> +   OUT_BATCH((depth_mt ? depth_region->pitch - 1 : 0) |
>                (depthbuffer_format << 18) |
>                ((hiz ? 1 : 0) << 22) |
>                ((stencil_mt != NULL && ctx->Stencil._WriteEnabled) << 27) |
> @@ -55,7 +59,7 @@ gen7_emit_depth_stencil_hiz(struct brw_context *brw,
>                (depth_surface_type << 29));
>
>      if (depth_mt) {
> -      OUT_RELOC(depth_mt->region->bo,
> +      OUT_RELOC(depth_region->bo,
>   	        I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER,
>   		depth_offset);
>      } else {
> @@ -77,10 +81,12 @@ gen7_emit_depth_stencil_hiz(struct brw_context *brw,
>         ADVANCE_BATCH();
>      } else {
>         struct intel_mipmap_tree *hiz_mt = depth_mt->hiz_mt;
> +      struct intel_region *hiz_region =
> +         intel_miptree_get_region(intel, hiz_mt, INTEL_MIPTREE_ACCESS_RENDER);
>         BEGIN_BATCH(3);
>         OUT_BATCH(GEN7_3DSTATE_HIER_DEPTH_BUFFER << 16 | (3 - 2));
> -      OUT_BATCH(hiz_mt->region->pitch - 1);
> -      OUT_RELOC(hiz_mt->region->bo,
> +      OUT_BATCH(hiz_region->pitch - 1);
> +      OUT_RELOC(hiz_region->bo,
>                   I915_GEM_DOMAIN_RENDER,
>                   I915_GEM_DOMAIN_RENDER,
>                   brw->depthstencil.hiz_offset);
> @@ -94,6 +100,9 @@ gen7_emit_depth_stencil_hiz(struct brw_context *brw,
>         OUT_BATCH(0);
>         ADVANCE_BATCH();
>      } else {
> +      struct intel_region *stencil_region =
> +         intel_miptree_get_region(intel, stencil_mt,
> +                                  INTEL_MIPTREE_ACCESS_RENDER);
>         const int enabled = intel->is_haswell ? HSW_STENCIL_ENABLED : 0;
>
>         BEGIN_BATCH(3);
> @@ -113,8 +122,8 @@ gen7_emit_depth_stencil_hiz(struct brw_context *brw,
>          * indicate that it does.
>          */
>         OUT_BATCH(enabled |
> -	        (2 * stencil_mt->region->pitch - 1));
> -      OUT_RELOC(stencil_mt->region->bo,
> +	        (2 * stencil_region->pitch - 1));
> +      OUT_RELOC(stencil_region->bo,
>   	        I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER,
>   		brw->depthstencil.stencil_offset);
>         ADVANCE_BATCH();
> 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 435f9dc..ea818f4 100644
> --- a/src/mesa/drivers/dri/i965/gen7_wm_surface_state.c
> +++ b/src/mesa/drivers/dri/i965/gen7_wm_surface_state.c
> @@ -101,19 +101,22 @@ void
>   gen7_set_surface_mcs_info(struct brw_context *brw,
>                             uint32_t *surf,
>                             uint32_t surf_offset,
> -                          const struct intel_mipmap_tree *mcs_mt,
> +                          struct intel_mipmap_tree *mcs_mt,
>                             bool is_render_target)
>   {
> +   struct intel_region *region =
> +      intel_miptree_get_region(&brw->intel, mcs_mt, INTEL_MIPTREE_ACCESS_MCS);
> +
>      /* From the Ivy Bridge PRM, Vol4 Part1 p76, "MCS Base Address":
>       *
>       *     "The MCS surface must be stored as Tile Y."
>       */
> -   assert(mcs_mt->region->tiling == I915_TILING_Y);
> +   assert(region->tiling == I915_TILING_Y);
>
>      /* Compute the pitch in units of tiles.  To do this we need to divide the
>       * pitch in bytes by 128, since a single Y-tile is 128 bytes wide.
>       */
> -   unsigned pitch_tiles = mcs_mt->region->pitch / 128;
> +   unsigned pitch_tiles = region->pitch / 128;
>
>      /* The upper 20 bits of surface state DWORD 6 are the upper 20 bits of the
>       * GPU address of the MCS buffer; the lower 12 bits contain other control
> @@ -121,15 +124,15 @@ gen7_set_surface_mcs_info(struct brw_context *brw,
>       * thus have their lower 12 bits zero), we can use an ordinary reloc to do
>       * the necessary address translation.
>       */
> -   assert ((mcs_mt->region->bo->offset & 0xfff) == 0);
> +   assert ((region->bo->offset & 0xfff) == 0);
>
>      surf[6] = GEN7_SURFACE_MCS_ENABLE |
>                SET_FIELD(pitch_tiles - 1, GEN7_SURFACE_MCS_PITCH) |
> -             mcs_mt->region->bo->offset;
> +             region->bo->offset;
>
>      drm_intel_bo_emit_reloc(brw->intel.batch.bo,
>                              surf_offset + 6 * 4,
> -                           mcs_mt->region->bo,
> +                           region->bo,
>                              surf[6] & 0xfff,
>                              is_render_target ? I915_GEM_DOMAIN_RENDER
>                              : I915_GEM_DOMAIN_SAMPLER,
> @@ -302,6 +305,9 @@ gen7_update_texture_surface(struct gl_context *ctx,
>         return;
>      }
>
> +   struct intel_region *region =
> +      intel_miptree_get_region(intel, mt, INTEL_MIPTREE_ACCESS_TEX);
> +
>      intel_miptree_get_dimensions_for_image(firstImage, &width, &height, &depth);
>
>      uint32_t *surf = brw_state_batch(brw, AUB_TRACE_SURFACE_STATE,
> @@ -316,7 +322,7 @@ gen7_update_texture_surface(struct gl_context *ctx,
>
>      surf[0] = translate_tex_target(tObj->Target) << BRW_SURFACE_TYPE_SHIFT |
>                tex_format << BRW_SURFACE_FORMAT_SHIFT |
> -             gen7_surface_tiling_mode(mt->region->tiling) |
> +             gen7_surface_tiling_mode(region->tiling) |
>                BRW_SURFACE_CUBEFACE_ENABLES;
>
>      if (mt->align_h == 4)
> @@ -330,12 +336,12 @@ gen7_update_texture_surface(struct gl_context *ctx,
>      if (mt->array_spacing_lod0)
>         surf[0] |= GEN7_SURFACE_ARYSPC_LOD0;
>
> -   surf[1] = mt->region->bo->offset + mt->offset; /* reloc */
> +   surf[1] = region->bo->offset + mt->offset; /* reloc */
>
>      surf[2] = SET_FIELD(width - 1, GEN7_SURFACE_WIDTH) |
>                SET_FIELD(height - 1, GEN7_SURFACE_HEIGHT);
>      surf[3] = SET_FIELD(depth - 1, BRW_SURFACE_DEPTH) |
> -             ((intelObj->mt->region->pitch) - 1);
> +             ((region->pitch) - 1);
>
>      surf[4] = gen7_surface_msaa_bits(mt->num_samples, mt->msaa_layout);
>
> @@ -372,7 +378,7 @@ gen7_update_texture_surface(struct gl_context *ctx,
>      /* Emit relocation to surface contents */
>      drm_intel_bo_emit_reloc(brw->intel.batch.bo,
>   			   binding_table[surf_index] + 4,
> -			   intelObj->mt->region->bo, intelObj->mt->offset,
> +			   region->bo, intelObj->mt->offset,
>   			   I915_GEM_DOMAIN_SAMPLER, 0);
>
>      gen7_check_surface_setup(surf, false /* is_render_target */);
> @@ -527,7 +533,8 @@ gen7_update_renderbuffer_surface(struct brw_context *brw,
>      struct intel_context *intel = &brw->intel;
>      struct gl_context *ctx = &intel->ctx;
>      struct intel_renderbuffer *irb = intel_renderbuffer(rb);
> -   struct intel_region *region = irb->mt->region;
> +   struct intel_region *region =
> +      intel_miptree_get_region(intel, irb->mt, INTEL_MIPTREE_ACCESS_RENDER);
>      uint32_t tile_x, tile_y;
>      uint32_t format;
>      /* _NEW_BUFFERS */
> @@ -559,7 +566,7 @@ gen7_update_renderbuffer_surface(struct brw_context *brw,
>         surf[0] |= GEN7_SURFACE_HALIGN_8;
>
>      /* reloc */
> -   surf[1] = intel_renderbuffer_tile_offsets(irb, &tile_x, &tile_y) +
> +   surf[1] = intel_renderbuffer_tile_offsets(intel, irb, &tile_x, &tile_y) +
>                region->bo->offset; /* reloc */
>
>      assert(brw->has_surface_tile_offset);
> diff --git a/src/mesa/drivers/dri/intel/intel_blit.c b/src/mesa/drivers/dri/intel/intel_blit.c
> index f9cba85..39c69c9 100644
> --- a/src/mesa/drivers/dri/intel/intel_blit.c
> +++ b/src/mesa/drivers/dri/intel/intel_blit.c
> @@ -313,7 +313,8 @@ intelClearWithBlit(struct gl_context *ctx, GLbitfield mask)
>
>         irb = intel_get_renderbuffer(fb, buf);
>         if (irb && irb->mt) {
> -	 region = irb->mt->region;
> +	 region = intel_miptree_get_region(intel, irb->mt,
> +                                           INTEL_MIPTREE_ACCESS_BLIT);
>   	 assert(region);
>   	 assert(region->bo);
>         } else {
> @@ -574,7 +575,9 @@ intel_set_teximage_alpha_to_one(struct gl_context *ctx,
>      uint32_t BR13, CMD;
>      int pitch, cpp;
>      drm_intel_bo *aper_array[2];
> -   struct intel_region *region = intel_image->mt->region;
> +   struct intel_region *region =
> +      intel_miptree_get_region(intel, intel_image->mt,
> +                               INTEL_MIPTREE_ACCESS_BLIT);
>      int width, height, depth;
>      BATCH_LOCALS;
>
> @@ -603,7 +606,7 @@ intel_set_teximage_alpha_to_one(struct gl_context *ctx,
>
>      DBG("%s dst:buf(%p)/%d %d,%d sz:%dx%d\n",
>          __FUNCTION__,
> -       intel_image->mt->region->bo, pitch,
> +       region->bo, pitch,
>          x1, y1, x2 - x1, y2 - y1);
>
>      BR13 = br13_for_cpp(cpp) | 0xf0 << 16;
> diff --git a/src/mesa/drivers/dri/intel/intel_buffer_objects.c b/src/mesa/drivers/dri/intel/intel_buffer_objects.c
> index f568864..c48520c 100644
> --- a/src/mesa/drivers/dri/intel/intel_buffer_objects.c
> +++ b/src/mesa/drivers/dri/intel/intel_buffer_objects.c
> @@ -746,14 +746,19 @@ intel_texture_object_purgeable(struct gl_context * ctx,
>   {
>      struct intel_texture_object *intel;
>
> -   (void) ctx;
>      (void) option;
>
>      intel = intel_texture_object(obj);
> -   if (intel->mt == NULL || intel->mt->region == NULL)
> +   if (intel->mt == NULL)
>         return GL_RELEASED_APPLE;
>
> -   return intel_buffer_purgeable(intel->mt->region->bo);
> +   struct intel_region *region =
> +      intel_miptree_get_region(intel_context(ctx), intel->mt,
> +                               INTEL_MIPTREE_ACCESS_NONE);
> +   if (region == NULL)
> +      return GL_RELEASED_APPLE;
> +
> +   return intel_buffer_purgeable(region->bo);
>   }
>
>   static GLenum
> @@ -763,14 +768,16 @@ intel_render_object_purgeable(struct gl_context * ctx,
>   {
>      struct intel_renderbuffer *intel;
>
> -   (void) ctx;
>      (void) option;
>
>      intel = intel_renderbuffer(obj);
>      if (intel->mt == NULL)
>         return GL_RELEASED_APPLE;
>
> -   return intel_buffer_purgeable(intel->mt->region->bo);
> +   struct intel_region *region =
> +      intel_miptree_get_region(intel_context(ctx), intel->mt,
> +                               INTEL_MIPTREE_ACCESS_NONE);
> +   return intel_buffer_purgeable(region->bo);
>   }
>
>   static GLenum
> @@ -803,14 +810,19 @@ intel_texture_object_unpurgeable(struct gl_context * ctx,
>   {
>      struct intel_texture_object *intel;
>
> -   (void) ctx;
>      (void) option;
>
>      intel = intel_texture_object(obj);
> -   if (intel->mt == NULL || intel->mt->region == NULL)
> +   if (intel->mt == NULL)
>         return GL_UNDEFINED_APPLE;
>
> -   return intel_buffer_unpurgeable(intel->mt->region->bo);
> +   struct intel_region *region =
> +      intel_miptree_get_region(intel_context(ctx), intel->mt,
> +                               INTEL_MIPTREE_ACCESS_NONE);
> +   if (region == NULL)
> +      return GL_UNDEFINED_APPLE;
> +
> +   return intel_buffer_unpurgeable(region->bo);
>   }
>
>   static GLenum
> @@ -820,14 +832,16 @@ intel_render_object_unpurgeable(struct gl_context * ctx,
>   {
>      struct intel_renderbuffer *intel;
>
> -   (void) ctx;
>      (void) option;
>
>      intel = intel_renderbuffer(obj);
>      if (intel->mt == NULL)
>         return GL_UNDEFINED_APPLE;
> +   struct intel_region *region =
> +      intel_miptree_get_region(intel_context(ctx), intel->mt,
> +                               INTEL_MIPTREE_ACCESS_NONE);
>
> -   return intel_buffer_unpurgeable(intel->mt->region->bo);
> +   return intel_buffer_unpurgeable(region->bo);
>   }
>
>   void
> diff --git a/src/mesa/drivers/dri/intel/intel_buffers.c b/src/mesa/drivers/dri/intel/intel_buffers.c
> index 9a9a259..b7cd840 100644
> --- a/src/mesa/drivers/dri/intel/intel_buffers.c
> +++ b/src/mesa/drivers/dri/intel/intel_buffers.c
> @@ -38,12 +38,13 @@
>    * Return pointer to current color drawing region, or NULL.
>    */
>   struct intel_region *
> -intel_drawbuf_region(struct intel_context *intel)
> +intel_drawbuf_region(struct intel_context *intel,
> +                     enum intel_miptree_access_type access_type)
>   {
>      struct intel_renderbuffer *irbColor =
>         intel_renderbuffer(intel->ctx.DrawBuffer->_ColorDrawBuffers[0]);
>      if (irbColor && irbColor->mt)
> -      return irbColor->mt->region;
> +      return intel_miptree_get_region(intel, irbColor->mt, access_type);
>      else
>         return NULL;
>   }
> @@ -52,12 +53,13 @@ intel_drawbuf_region(struct intel_context *intel)
>    * Return pointer to current color reading region, or NULL.
>    */
>   struct intel_region *
> -intel_readbuf_region(struct intel_context *intel)
> +intel_readbuf_region(struct intel_context *intel,
> +                     enum intel_miptree_access_type access_type)
>   {
>      struct intel_renderbuffer *irb
>         = intel_renderbuffer(intel->ctx.ReadBuffer->_ColorReadBuffer);
>      if (irb && irb->mt)
> -      return irb->mt->region;
> +      return intel_miptree_get_region(intel, irb->mt, access_type);
>      else
>         return NULL;
>   }
> diff --git a/src/mesa/drivers/dri/intel/intel_buffers.h b/src/mesa/drivers/dri/intel/intel_buffers.h
> index e68cc67..5ae546d 100644
> --- a/src/mesa/drivers/dri/intel/intel_buffers.h
> +++ b/src/mesa/drivers/dri/intel/intel_buffers.h
> @@ -35,10 +35,15 @@
>
>   struct intel_context;
>   struct intel_framebuffer;
> +enum intel_miptree_access_type;
>
> -extern struct intel_region *intel_readbuf_region(struct intel_context *intel);
> +extern struct intel_region *
> +intel_readbuf_region(struct intel_context *intel,
> +                     enum intel_miptree_access_type access_type);
>
> -extern struct intel_region *intel_drawbuf_region(struct intel_context *intel);
> +extern struct intel_region *
> +intel_drawbuf_region(struct intel_context *intel,
> +                     enum intel_miptree_access_type access_type);
>
>   extern void intel_check_front_buffer_rendering(struct intel_context *intel);
>
> diff --git a/src/mesa/drivers/dri/intel/intel_context.c b/src/mesa/drivers/dri/intel/intel_context.c
> index 88cc247..fab99c1 100644
> --- a/src/mesa/drivers/dri/intel/intel_context.c
> +++ b/src/mesa/drivers/dri/intel/intel_context.c
> @@ -1133,14 +1133,14 @@ intel_process_dri2_buffer(struct intel_context *intel,
>       */
>      if (num_samples == 0) {
>          if (rb->mt &&
> -           rb->mt->region &&
> -           rb->mt->region->name == buffer->name)
> +           rb->mt->region_private &&
> +           rb->mt->region_private->name == buffer->name)
>             return;
>      } else {
>          if (rb->mt &&
>              rb->mt->singlesample_mt &&
> -           rb->mt->singlesample_mt->region &&
> -           rb->mt->singlesample_mt->region->name == buffer->name)
> +           rb->mt->singlesample_mt->region_private &&
> +           rb->mt->singlesample_mt->region_private->name == buffer->name)
>             return;
>      }
>
> diff --git a/src/mesa/drivers/dri/intel/intel_fbo.c b/src/mesa/drivers/dri/intel/intel_fbo.c
> index 69f8629..1492d69 100644
> --- a/src/mesa/drivers/dri/intel/intel_fbo.c
> +++ b/src/mesa/drivers/dri/intel/intel_fbo.c
> @@ -58,14 +58,18 @@ static struct gl_renderbuffer *
>   intel_new_renderbuffer(struct gl_context * ctx, GLuint name);
>
>   struct intel_region*
> -intel_get_rb_region(struct gl_framebuffer *fb, GLuint attIndex)
> +intel_get_rb_region(struct intel_context *intel, struct gl_framebuffer *fb,
> +                    GLuint attIndex,
> +                    enum intel_miptree_access_type access_type)
>   {
>      struct intel_renderbuffer *irb = intel_get_renderbuffer(fb, attIndex);
>      if (irb && irb->mt) {
> +      struct intel_mipmap_tree *mt;
>         if (attIndex == BUFFER_STENCIL && irb->mt->stencil_mt)
> -	 return irb->mt->stencil_mt->region;
> +         mt = irb->mt->stencil_mt;
>         else
> -	 return irb->mt->region;
> +	 mt = irb->mt;
> +      return intel_miptree_get_region(intel, mt, access_type);
>      } else
>         return NULL;
>   }
> @@ -545,11 +549,13 @@ intel_renderbuffer_set_draw_offset(struct intel_renderbuffer *irb)
>    * from there.
>    */
>   uint32_t
> -intel_renderbuffer_tile_offsets(struct intel_renderbuffer *irb,
> +intel_renderbuffer_tile_offsets(struct intel_context *intel,
> +                                struct intel_renderbuffer *irb,
>   				uint32_t *tile_x,
>   				uint32_t *tile_y)
>   {
> -   struct intel_region *region = irb->mt->region;
> +   struct intel_region *region =
> +      intel_miptree_get_region(intel, irb->mt, INTEL_MIPTREE_ACCESS_NONE);
>      uint32_t mask_x, mask_y;
>
>      intel_region_get_tile_masks(region, &mask_x, &mask_y, false);
> diff --git a/src/mesa/drivers/dri/intel/intel_fbo.h b/src/mesa/drivers/dri/intel/intel_fbo.h
> index aa52b97..da40574 100644
> --- a/src/mesa/drivers/dri/intel/intel_fbo.h
> +++ b/src/mesa/drivers/dri/intel/intel_fbo.h
> @@ -34,6 +34,7 @@
>   #include "main/macros.h"
>   #include "intel_context.h"
>   #include "intel_screen.h"
> +#include "intel_mipmap_tree.h"
>
>   #ifdef __cplusplus
>   extern "C" {
> @@ -149,12 +150,15 @@ void
>   intel_renderbuffer_set_draw_offset(struct intel_renderbuffer *irb);
>
>   uint32_t
> -intel_renderbuffer_tile_offsets(struct intel_renderbuffer *irb,
> +intel_renderbuffer_tile_offsets(struct intel_context *intel,
> +                                struct intel_renderbuffer *irb,
>   				uint32_t *tile_x,
>   				uint32_t *tile_y);
>
>   struct intel_region*
> -intel_get_rb_region(struct gl_framebuffer *fb, GLuint attIndex);
> +intel_get_rb_region(struct intel_context *intel, struct gl_framebuffer *fb,
> +                    GLuint attIndex,
> +                    enum intel_miptree_access_type access_type);
>
>   void
>   intel_renderbuffer_set_needs_downsample(struct intel_renderbuffer *irb);
> diff --git a/src/mesa/drivers/dri/intel/intel_mipmap_tree.c b/src/mesa/drivers/dri/intel/intel_mipmap_tree.c
> index ad9e2b3..4440885 100644
> --- a/src/mesa/drivers/dri/intel/intel_mipmap_tree.c
> +++ b/src/mesa/drivers/dri/intel/intel_mipmap_tree.c
> @@ -444,33 +444,34 @@ intel_miptree_create(struct intel_context *intel,
>      bool y_or_x = tiling == (I915_TILING_Y | I915_TILING_X);
>
>      mt->etc_format = etc_format;
> -   mt->region = intel_region_alloc(intel->intelScreen,
> -				   y_or_x ? I915_TILING_Y : tiling,
> -				   mt->cpp,
> -				   total_width,
> -				   total_height,
> -				   expect_accelerated_upload);
> +   mt->region_private = intel_region_alloc(intel->intelScreen,
> +                                           y_or_x ? I915_TILING_Y : tiling,
> +                                           mt->cpp,
> +                                           total_width,
> +                                           total_height,
> +                                           expect_accelerated_upload);
>
>      /* If the region is too large to fit in the aperture, we need to use the
>       * BLT engine to support it.  The BLT paths can't currently handle Y-tiling,
>       * so we need to fall back to X.
>       */
> -   if (y_or_x && mt->region->bo->size >= intel->max_gtt_map_object_size) {
> +   if (y_or_x &&
> +       mt->region_private->bo->size >= intel->max_gtt_map_object_size) {
>         perf_debug("%dx%d miptree larger than aperture; falling back to X-tiled\n",
>                    mt->total_width, mt->total_height);
> -      intel_region_release(&mt->region);
> -
> -      mt->region = intel_region_alloc(intel->intelScreen,
> -                                      I915_TILING_X,
> -                                      mt->cpp,
> -                                      total_width,
> -                                      total_height,
> -                                      expect_accelerated_upload);
> +      intel_region_release(&mt->region_private);
> +
> +      mt->region_private = intel_region_alloc(intel->intelScreen,
> +                                              I915_TILING_X,
> +                                              mt->cpp,
> +                                              total_width,
> +                                              total_height,
> +                                              expect_accelerated_upload);
>      }
>
>      mt->offset = 0;
>
> -   if (!mt->region) {
> +   if (!mt->region_private) {
>          intel_miptree_release(&mt);
>          return NULL;
>      }
> @@ -493,7 +494,7 @@ intel_miptree_create_for_region(struct intel_context *intel,
>      if (!mt)
>         return mt;
>
> -   intel_region_reference(&mt->region, region);
> +   intel_region_reference(&mt->region_private, region);
>
>      return mt;
>   }
> @@ -621,7 +622,7 @@ intel_miptree_release(struct intel_mipmap_tree **mt)
>
>         DBG("%s deleting %p\n", __FUNCTION__, *mt);
>
> -      intel_region_release(&((*mt)->region));
> +      intel_region_release(&((*mt)->region_private));
>         intel_miptree_release(&(*mt)->stencil_mt);
>         intel_miptree_release(&(*mt)->hiz_mt);
>   #ifndef I915
> @@ -783,7 +784,7 @@ intel_miptree_get_tile_offsets(struct intel_mipmap_tree *mt,
>                                  uint32_t *tile_x,
>                                  uint32_t *tile_y)
>   {
> -   struct intel_region *region = mt->region;
> +   struct intel_region *region = mt->region_private;
>      uint32_t mask_x, mask_y;
>
>      intel_region_get_tile_masks(region, &mask_x, &mask_y, false);
> @@ -896,12 +897,16 @@ intel_miptree_copy_slice(struct intel_context *intel,
>      uint32_t dst_x, dst_y, src_x, src_y;
>      intel_miptree_get_image_offset(dst_mt, level, slice, &dst_x, &dst_y);
>      intel_miptree_get_image_offset(src_mt, level, slice, &src_x, &src_y);
> +   struct intel_region *src_region =
> +      intel_miptree_get_region(intel, src_mt, INTEL_MIPTREE_ACCESS_BLIT);
> +   struct intel_region *dst_region =
> +      intel_miptree_get_region(intel, dst_mt, INTEL_MIPTREE_ACCESS_BLIT);
>
>      DBG("validate blit mt %s %p %d,%d/%d -> mt %s %p %d,%d/%d (%dx%d)\n",
>          _mesa_get_format_name(src_mt->format),
> -       src_mt, src_x, src_y, src_mt->region->pitch,
> +       src_mt, src_x, src_y, src_region->pitch,
>          _mesa_get_format_name(dst_mt->format),
> -       dst_mt, dst_x, dst_y, dst_mt->region->pitch,
> +       dst_mt, dst_x, dst_y, dst_region->pitch,
>          width, height);
>
>      /* Since we are about to copy depth data using either the blitter or swrast
> @@ -911,11 +916,11 @@ intel_miptree_copy_slice(struct intel_context *intel,
>      intel_miptree_slice_resolve_depth(intel, dst_mt, level, slice);
>
>      if (!intelEmitCopyBlit(intel,
> -			  dst_mt->region->cpp,
> -			  src_mt->region->pitch, src_mt->region->bo,
> -			  0, src_mt->region->tiling,
> -			  dst_mt->region->pitch, dst_mt->region->bo,
> -			  0, dst_mt->region->tiling,
> +			  dst_region->cpp,
> +			  src_region->pitch, src_region->bo,
> +			  0, src_region->tiling,
> +			  dst_region->pitch, dst_region->bo,
> +			  0, dst_region->tiling,
>   			  src_x, src_y,
>   			  dst_x, dst_y,
>   			  width, height,
> @@ -1022,7 +1027,9 @@ intel_miptree_alloc_mcs(struct intel_context *intel,
>       * Note: the clear value for MCS buffers is all 1's, so we memset to 0xff.
>       */
>      void *data = intel_miptree_map_raw(intel, mt->mcs_mt);
> -   memset(data, 0xff, mt->mcs_mt->region->bo->size);
> +   struct intel_region *region =
> +      intel_miptree_get_region(intel, mt->mcs_mt, INTEL_MIPTREE_ACCESS_NONE);
> +   memset(data, 0xff, region->bo->size);
>      intel_miptree_unmap_raw(intel, mt->mcs_mt);
>
>      return mt->mcs_mt;
> @@ -1371,7 +1378,9 @@ intel_miptree_upsample(struct intel_context *intel,
>   void *
>   intel_miptree_map_raw(struct intel_context *intel, struct intel_mipmap_tree *mt)
>   {
> -   drm_intel_bo *bo = mt->region->bo;
> +   struct intel_region *region =
> +      intel_miptree_get_region(intel, mt, INTEL_MIPTREE_ACCESS_MAP);
> +   drm_intel_bo *bo = region->bo;
>
>      if (unlikely(INTEL_DEBUG & DEBUG_PERF)) {
>         if (drm_intel_bo_busy(bo)) {
> @@ -1381,7 +1390,7 @@ intel_miptree_map_raw(struct intel_context *intel, struct intel_mipmap_tree *mt)
>
>      intel_flush(&intel->ctx);
>
> -   if (mt->region->tiling != I915_TILING_NONE)
> +   if (region->tiling != I915_TILING_NONE)
>         drm_intel_gem_bo_map_gtt(bo);
>      else
>         drm_intel_bo_map(bo, true);
> @@ -1393,7 +1402,9 @@ void
>   intel_miptree_unmap_raw(struct intel_context *intel,
>                           struct intel_mipmap_tree *mt)
>   {
> -   drm_intel_bo_unmap(mt->region->bo);
> +   struct intel_region *region =
> +      intel_miptree_get_region(intel, mt, INTEL_MIPTREE_ACCESS_NONE);
> +   drm_intel_bo_unmap(region->bo);
>   }
>
>   static void
> @@ -1428,7 +1439,9 @@ intel_miptree_map_gtt(struct intel_context *intel,
>         x += image_x;
>         y += image_y;
>
> -      map->stride = mt->region->pitch;
> +      struct intel_region *region =
> +         intel_miptree_get_region(intel, mt, INTEL_MIPTREE_ACCESS_NONE);
> +      map->stride = region->pitch;
>         map->ptr = base + y * map->stride + x * mt->cpp;
>      }
>
> @@ -1458,9 +1471,11 @@ intel_miptree_map_blit(struct intel_context *intel,
>      int x = map->x;
>      int y = map->y;
>      int ret;
> +   struct intel_region *region =
> +      intel_miptree_get_region(intel, mt, INTEL_MIPTREE_ACCESS_BLIT);
>
>      /* The blitter requires the pitch to be aligned to 4. */
> -   map->stride = ALIGN(map->w * mt->region->cpp, 4);
> +   map->stride = ALIGN(map->w * region->cpp, 4);
>
>      map->bo = drm_intel_bo_alloc(intel->bufmgr, "intel_miptree_map_blit() temp",
>   				map->stride * map->h, 4096);
> @@ -1474,9 +1489,9 @@ intel_miptree_map_blit(struct intel_context *intel,
>      y += image_y;
>
>      if (!intelEmitCopyBlit(intel,
> -			  mt->region->cpp,
> -			  mt->region->pitch, mt->region->bo,
> -			  mt->offset, mt->region->tiling,
> +			  region->cpp,
> +			  region->pitch, region->bo,
> +			  mt->offset, region->tiling,
>   			  map->stride, map->bo,
>   			  0, I915_TILING_NONE,
>   			  x, y,
> @@ -1520,6 +1535,8 @@ intel_miptree_unmap_blit(struct intel_context *intel,
>      drm_intel_bo_unmap(map->bo);
>
>      if (map->mode & GL_MAP_WRITE_BIT) {
> +      struct intel_region *region =
> +         intel_miptree_get_region(intel, mt, INTEL_MIPTREE_ACCESS_BLIT);
>         unsigned int image_x, image_y;
>         int x = map->x;
>         int y = map->y;
> @@ -1528,11 +1545,11 @@ intel_miptree_unmap_blit(struct intel_context *intel,
>         y += image_y;
>
>         bool ok = intelEmitCopyBlit(intel,
> -                                  mt->region->cpp,
> +                                  region->cpp,
>                                     map->stride, map->bo,
>                                     0, I915_TILING_NONE,
> -                                  mt->region->pitch, mt->region->bo,
> -                                  mt->offset, mt->region->tiling,
> +                                  region->pitch, region->bo,
> +                                  mt->offset, region->tiling,
>                                     0, 0,
>                                     x, y,
>                                     map->w, map->h,
> @@ -1568,7 +1585,9 @@ intel_miptree_map_s8(struct intel_context *intel,
>
>         for (uint32_t y = 0; y < map->h; y++) {
>   	 for (uint32_t x = 0; x < map->w; x++) {
> -	    ptrdiff_t offset = intel_offset_S8(mt->region->pitch,
> +            struct intel_region *region =
> +               intel_miptree_get_region(intel, mt, INTEL_MIPTREE_ACCESS_NONE);
> +	    ptrdiff_t offset = intel_offset_S8(region->pitch,
>   	                                       x + image_x + map->x,
>   	                                       y + image_y + map->y,
>   					       intel->has_swizzling);
> @@ -1604,7 +1623,9 @@ intel_miptree_unmap_s8(struct intel_context *intel,
>
>         for (uint32_t y = 0; y < map->h; y++) {
>   	 for (uint32_t x = 0; x < map->w; x++) {
> -	    ptrdiff_t offset = intel_offset_S8(mt->region->pitch,
> +            struct intel_region *region =
> +               intel_miptree_get_region(intel, mt, INTEL_MIPTREE_ACCESS_NONE);
> +	    ptrdiff_t offset = intel_offset_S8(region->pitch,
>   	                                       x + map->x,
>   	                                       y + map->y,
>   					       intel->has_swizzling);
> @@ -1646,6 +1667,8 @@ intel_miptree_unmap_etc(struct intel_context *intel,
>                           unsigned int level,
>                           unsigned int slice)
>   {
> +   struct intel_region *region =
> +      intel_miptree_get_region(intel, mt, INTEL_MIPTREE_ACCESS_NONE);
>      uint32_t image_x;
>      uint32_t image_y;
>      intel_miptree_get_image_offset(mt, level, slice, &image_x, &image_y);
> @@ -1654,15 +1677,15 @@ intel_miptree_unmap_etc(struct intel_context *intel,
>      image_y += map->y;
>
>      uint8_t *dst = intel_miptree_map_raw(intel, mt)
> -                + image_y * mt->region->pitch
> -                + image_x * mt->region->cpp;
> +                + image_y * region->pitch
> +                + image_x * region->cpp;
>
>      if (mt->etc_format == MESA_FORMAT_ETC1_RGB8)
> -      _mesa_etc1_unpack_rgba8888(dst, mt->region->pitch,
> +      _mesa_etc1_unpack_rgba8888(dst, region->pitch,
>                                    map->ptr, map->stride,
>                                    map->w, map->h);
>      else
> -      _mesa_unpack_etc2_format(dst, mt->region->pitch,
> +      _mesa_unpack_etc2_format(dst, region->pitch,
>                                  map->ptr, map->stride,
>                                  map->w, map->h, mt->etc_format);
>
> @@ -1717,12 +1740,18 @@ intel_miptree_map_depthstencil(struct intel_context *intel,
>         for (uint32_t y = 0; y < map->h; y++) {
>   	 for (uint32_t x = 0; x < map->w; x++) {
>   	    int map_x = map->x + x, map_y = map->y + y;
> -	    ptrdiff_t s_offset = intel_offset_S8(s_mt->region->pitch,
> +            struct intel_region *s_region =
> +               intel_miptree_get_region(intel, s_mt,
> +                                        INTEL_MIPTREE_ACCESS_NONE);
> +	    ptrdiff_t s_offset = intel_offset_S8(s_region->pitch,
>   						 map_x + s_image_x,
>   						 map_y + s_image_y,
>   						 intel->has_swizzling);
> +            struct intel_region *z_region =
> +               intel_miptree_get_region(intel, z_mt,
> +                                        INTEL_MIPTREE_ACCESS_NONE);
>   	    ptrdiff_t z_offset = ((map_y + z_image_y) *
> -                                  (z_mt->region->pitch / 4) +
> +                                  (z_region->pitch / 4) +
>   				  (map_x + z_image_x));
>   	    uint8_t s = s_map[s_offset];
>   	    uint32_t z = z_map[z_offset];
> @@ -1777,12 +1806,18 @@ intel_miptree_unmap_depthstencil(struct intel_context *intel,
>
>         for (uint32_t y = 0; y < map->h; y++) {
>   	 for (uint32_t x = 0; x < map->w; x++) {
> -	    ptrdiff_t s_offset = intel_offset_S8(s_mt->region->pitch,
> +            struct intel_region *s_region =
> +               intel_miptree_get_region(intel, s_mt,
> +                                        INTEL_MIPTREE_ACCESS_NONE);
> +	    ptrdiff_t s_offset = intel_offset_S8(s_region->pitch,
>   						 x + s_image_x + map->x,
>   						 y + s_image_y + map->y,
>   						 intel->has_swizzling);
> +            struct intel_region *z_region =
> +               intel_miptree_get_region(intel, z_mt,
> +                                        INTEL_MIPTREE_ACCESS_NONE);
>   	    ptrdiff_t z_offset = ((y + z_image_y) *
> -                                  (z_mt->region->pitch / 4) +
> +                                  (z_region->pitch / 4) +
>   				  (x + z_image_x));
>
>   	    if (map_z32f_x24s8) {
> @@ -1885,6 +1920,8 @@ intel_miptree_map_singlesample(struct intel_context *intel,
>      if (map->mode & GL_MAP_WRITE_BIT) {
>         intel_miptree_slice_set_needs_hiz_resolve(mt, level, slice);
>      }
> +   struct intel_region *region =
> +      intel_miptree_get_region(intel, mt, INTEL_MIPTREE_ACCESS_NONE);
>
>      if (mt->format == MESA_FORMAT_S8) {
>         intel_miptree_map_s8(intel, mt, map, level, slice);
> @@ -1915,13 +1952,13 @@ intel_miptree_map_singlesample(struct intel_context *intel,
>      else if (intel->has_llc &&
>               !(mode & GL_MAP_WRITE_BIT) &&
>               !mt->compressed &&
> -            (mt->region->tiling == I915_TILING_X ||
> -             (intel->gen >= 6 && mt->region->tiling == I915_TILING_Y)) &&
> -            mt->region->pitch < 32768) {
> +            (region->tiling == I915_TILING_X ||
> +             (intel->gen >= 6 && region->tiling == I915_TILING_Y)) &&
> +            region->pitch < 32768) {
>         intel_miptree_map_blit(intel, mt, map, level, slice);
> -   } else if (mt->region->tiling != I915_TILING_NONE &&
> -              mt->region->bo->size >= intel->max_gtt_map_object_size) {
> -      assert(mt->region->pitch < 32768);
> +   } else if (region->tiling != I915_TILING_NONE &&
> +              region->bo->size >= intel->max_gtt_map_object_size) {
> +      assert(region->pitch < 32768);
>         intel_miptree_map_blit(intel, mt, map, level, slice);
>      } else {
>         intel_miptree_map_gtt(intel, mt, map, level, slice);
> diff --git a/src/mesa/drivers/dri/intel/intel_mipmap_tree.h b/src/mesa/drivers/dri/intel/intel_mipmap_tree.h
> index 0ec3c5e..81a3b69 100644
> --- a/src/mesa/drivers/dri/intel/intel_mipmap_tree.h
> +++ b/src/mesa/drivers/dri/intel/intel_mipmap_tree.h
> @@ -287,9 +287,13 @@ struct intel_mipmap_tree
>       */
>      struct intel_mipmap_level level[MAX_TEXTURE_LEVELS];
>
> -   /* The data is held here:
> +   /**
> +    * The data is held here.  Please don't access this field directly except
> +    * in low-level intel_mipmap_tree functions; instead, use
> +    * intel_miptree_get_region(), which takes care of updating fast color
> +    * clear state appropriately.
>       */
> -   struct intel_region *region;
> +   struct intel_region *region_private;
>
>      /* Offset into region bo where miptree starts:
>       */
> @@ -632,6 +636,70 @@ intel_miptree_unmap(struct intel_context *intel,
>   		    unsigned int level,
>   		    unsigned int slice);
>
> +
> +/**
> + * Enum describing possible ways in which a miptree's region can be accessed.
> + * This is used by intel_miptree_get_region() to update the fast color clear
> + * state appropriately for the type of access.
> + */
> +enum intel_miptree_access_type {
> +   /**
> +    * The contents of the region won't need to be accessed, just the metadata
> +    * (pitch, cpp, bo->size, etc.)
> +    */
> +   INTEL_MIPTREE_ACCESS_NONE,
> +
> +   /**
> +    * The contents of the region will be accessed by the hardware blitter.
> +    */
> +   INTEL_MIPTREE_ACCESS_BLIT,
> +
> +   /**
> +    * The contents of the region will be mapped into memory and accessed by
> +    * the CPU.
> +    */
> +   INTEL_MIPTREE_ACCESS_MAP,
> +
> +   /**
> +    * The contents of the region will be used as a source for texturing
> +    * operations.
> +    */
> +   INTEL_MIPTREE_ACCESS_TEX,
> +
> +   /**
> +    * The contents of the region will be shared between multiple miptrees, or
> +    * with an entity outside of Mesa (other than the display server or
> +    * compositor).
> +    */
> +   INTEL_MIPTREE_ACCESS_SHARED,
> +
> +   /**
> +    * The contents of the region will be used as a destination color buffer,
> +    * depth buffer, or stencil buffer for 3D rendering operations.
> +    */
> +   INTEL_MIPTREE_ACCESS_RENDER,
> +
> +   /**
> +    * The contents of the region will be used as an MCS buffer for some other
> +    * buffer.
> +    */
> +   INTEL_MIPTREE_ACCESS_MCS,
> +};
> +
> +
> +/**
> + * Obtain the intel_region corresponding to this miptree, updating fast color
> + * clear state as appropriate.
> + */
> +static inline struct intel_region *
> +intel_miptree_get_region(struct intel_context *intel,
> +                         struct intel_mipmap_tree *mt,
> +                         enum intel_miptree_access_type access_type)
> +{
> +   return mt->region_private;
> +}
> +
> +
>   #ifdef I915
>   static inline void
>   intel_hiz_exec(struct intel_context *intel, struct intel_mipmap_tree *mt,
> diff --git a/src/mesa/drivers/dri/intel/intel_pixel_bitmap.c b/src/mesa/drivers/dri/intel/intel_pixel_bitmap.c
> index 954dfc5..9580629 100644
> --- a/src/mesa/drivers/dri/intel/intel_pixel_bitmap.c
> +++ b/src/mesa/drivers/dri/intel/intel_pixel_bitmap.c
> @@ -49,6 +49,7 @@
>   #include "intel_buffers.h"
>   #include "intel_pixel.h"
>   #include "intel_reg.h"
> +#include "intel_mipmap_tree.h"
>
>
>   #define FILE_DEBUG_FLAG DEBUG_PIXEL
> @@ -200,7 +201,7 @@ do_blit_bitmap( struct gl_context *ctx,
>      }
>
>      intel_prepare_render(intel);
> -   dst = intel_drawbuf_region(intel);
> +   dst = intel_drawbuf_region(intel, INTEL_MIPTREE_ACCESS_BLIT);
>
>      if (!dst)
>          return false;
> diff --git a/src/mesa/drivers/dri/intel/intel_pixel_copy.c b/src/mesa/drivers/dri/intel/intel_pixel_copy.c
> index 34376ba..d470e74 100644
> --- a/src/mesa/drivers/dri/intel/intel_pixel_copy.c
> +++ b/src/mesa/drivers/dri/intel/intel_pixel_copy.c
> @@ -194,16 +194,20 @@ do_blit_copypixels(struct gl_context * ctx,
>      dstx += draw_irb->draw_x;
>      dsty += draw_irb->draw_y;
>
> -   uint32_t src_pitch = read_irb->mt->region->pitch;
> +   struct intel_region *read_region =
> +      intel_miptree_get_region(intel, read_irb->mt, INTEL_MIPTREE_ACCESS_BLIT);
> +   struct intel_region *draw_region =
> +      intel_miptree_get_region(intel, draw_irb->mt, INTEL_MIPTREE_ACCESS_BLIT);
> +   uint32_t src_pitch = read_region->pitch;
>      if (flip)
>         src_pitch = -src_pitch;
>
>      if (!intelEmitCopyBlit(intel,
>                             draw_irb->mt->cpp,
> -                          src_pitch, read_irb->mt->region->bo,
> -                          0, read_irb->mt->region->tiling,
> -                          draw_irb->mt->region->pitch, draw_irb->mt->region->bo,
> -                          0, draw_irb->mt->region->tiling,
> +                          src_pitch, read_region->bo,
> +                          0, read_region->tiling,
> +                          draw_region->pitch, draw_region->bo,
> +                          0, draw_region->tiling,
>                             srcx, srcy,
>                             dstx, dsty,
>                             width, height,
> diff --git a/src/mesa/drivers/dri/intel/intel_pixel_read.c b/src/mesa/drivers/dri/intel/intel_pixel_read.c
> index ebdc528..7334035 100644
> --- a/src/mesa/drivers/dri/intel/intel_pixel_read.c
> +++ b/src/mesa/drivers/dri/intel/intel_pixel_read.c
> @@ -76,7 +76,8 @@ do_blit_readpixels(struct gl_context * ctx,
>                      const struct gl_pixelstore_attrib *pack, GLvoid * pixels)
>   {
>      struct intel_context *intel = intel_context(ctx);
> -   struct intel_region *src = intel_readbuf_region(intel);
> +   struct intel_region *src =
> +      intel_readbuf_region(intel, INTEL_MIPTREE_ACCESS_BLIT);
>      struct intel_buffer_object *dst = intel_buffer_object(pack->BufferObj);
>      GLuint dst_offset;
>      drm_intel_bo *dst_buffer;
> diff --git a/src/mesa/drivers/dri/intel/intel_screen.c b/src/mesa/drivers/dri/intel/intel_screen.c
> index 325304d..cf1044c 100644
> --- a/src/mesa/drivers/dri/intel/intel_screen.c
> +++ b/src/mesa/drivers/dri/intel/intel_screen.c
> @@ -138,14 +138,17 @@ aub_dump_bmp(struct gl_context *ctx)
>   	    continue;
>   	 }
>
> -         assert(irb->mt->region->pitch % irb->mt->region->cpp == 0);
> -	 drm_intel_gem_bo_aub_dump_bmp(irb->mt->region->bo,
> +         struct intel_region *region =
> +            intel_miptree_get_region(intel_context(ctx), irb->mt,
> +                                     INTEL_MIPTREE_ACCESS_NONE);
> +         assert(region->pitch % region->cpp == 0);
> +	 drm_intel_gem_bo_aub_dump_bmp(region->bo,
>   				       irb->draw_x,
>   				       irb->draw_y,
>   				       irb->Base.Base.Width,
>   				       irb->Base.Base.Height,
>   				       format,
> -				       irb->mt->region->pitch,
> +				       region->pitch,
>   				       0);
>         }
>      }
> @@ -299,10 +302,12 @@ intel_setup_image_from_mipmap_tree(struct intel_context *intel, __DRIimage *imag
>   {
>      unsigned int draw_x, draw_y;
>      uint32_t mask_x, mask_y;
> +   struct intel_region *region =
> +      intel_miptree_get_region(intel, mt, INTEL_MIPTREE_ACCESS_SHARED);
>
>      intel_miptree_check_level_layer(mt, level, zoffset);
>
> -   intel_region_get_tile_masks(mt->region, &mask_x, &mask_y, false);
> +   intel_region_get_tile_masks(region, &mask_x, &mask_y, false);
>      intel_miptree_get_image_offset(mt, level, zoffset, &draw_x, &draw_y);
>
>      image->width = mt->level[level].width;
> @@ -310,12 +315,12 @@ intel_setup_image_from_mipmap_tree(struct intel_context *intel, __DRIimage *imag
>      image->tile_x = draw_x & mask_x;
>      image->tile_y = draw_y & mask_y;
>
> -   image->offset = intel_region_get_aligned_offset(mt->region,
> +   image->offset = intel_region_get_aligned_offset(region,
>                                                      draw_x & ~mask_x,
>                                                      draw_y & ~mask_y,
>                                                      false);
>
> -   intel_region_reference(&image->region, mt->region);
> +   intel_region_reference(&image->region, region);
>   }
>
>   static void
> @@ -404,7 +409,9 @@ intel_create_image_from_renderbuffer(__DRIcontext *context,
>      image->format = rb->Format;
>      image->offset = 0;
>      image->data = loaderPrivate;
> -   intel_region_reference(&image->region, irb->mt->region);
> +   struct intel_region *region =
> +      intel_miptree_get_region(intel, irb->mt, INTEL_MIPTREE_ACCESS_SHARED);
> +   intel_region_reference(&image->region, region);
>      intel_setup_image_from_dimensions(image);
>      image->dri_format = intel_dri_format(image->format);
>      image->has_depthstencil = irb->mt->stencil_mt? true : false;
> diff --git a/src/mesa/drivers/dri/intel/intel_tex_copy.c b/src/mesa/drivers/dri/intel/intel_tex_copy.c
> index 6043ed2..1571db6 100644
> --- a/src/mesa/drivers/dri/intel/intel_tex_copy.c
> +++ b/src/mesa/drivers/dri/intel/intel_tex_copy.c
> @@ -69,7 +69,8 @@ intel_copy_texsubimage(struct intel_context *intel,
>   		 __FUNCTION__, intelImage->mt, irb, internalFormat);
>         return false;
>      } else {
> -      region = irb->mt->region;
> +      region = intel_miptree_get_region(intel, irb->mt,
> +                                        INTEL_MIPTREE_ACCESS_BLIT);
>         assert(region);
>      }
>
> @@ -124,6 +125,9 @@ intel_copy_texsubimage(struct intel_context *intel,
>      {
>         GLuint image_x, image_y;
>         GLshort src_pitch;
> +      struct intel_region *image_region =
> +         intel_miptree_get_region(intel, intelImage->mt,
> +                                  INTEL_MIPTREE_ACCESS_BLIT);
>
>         /* get dest x/y in destination texture */
>         intel_miptree_get_image_offset(intelImage->mt,
> @@ -132,7 +136,7 @@ intel_copy_texsubimage(struct intel_context *intel,
>   				     &image_x, &image_y);
>
>         /* The blitter can't handle Y-tiled buffers. */
> -      if (intelImage->mt->region->tiling == I915_TILING_Y) {
> +      if (image_region->tiling == I915_TILING_Y) {
>   	 return false;
>         }
>
> @@ -152,10 +156,10 @@ intel_copy_texsubimage(struct intel_context *intel,
>   			     region->bo,
>   			     0,
>   			     region->tiling,
> -			     intelImage->mt->region->pitch,
> -			     intelImage->mt->region->bo,
> +			     image_region->pitch,
> +			     image_region->bo,
>   			     0,
> -			     intelImage->mt->region->tiling,
> +			     image_region->tiling,
>   			     irb->draw_x + x, irb->draw_y + y,
>   			     image_x + dstx, image_y + dsty,
>   			     width, height,
> diff --git a/src/mesa/drivers/dri/intel/intel_tex_image.c b/src/mesa/drivers/dri/intel/intel_tex_image.c
> index 4e307f8..ba59092 100644
> --- a/src/mesa/drivers/dri/intel/intel_tex_image.c
> +++ b/src/mesa/drivers/dri/intel/intel_tex_image.c
> @@ -153,7 +153,10 @@ try_pbo_upload(struct gl_context *ctx,
>         return false;
>      }
>
> -   dst_buffer = intelImage->mt->region->bo;
> +   struct intel_region *region =
> +      intel_miptree_get_region(intel, intelImage->mt,
> +                               INTEL_MIPTREE_ACCESS_BLIT);
> +   dst_buffer = region->bo;
>      src_buffer = intel_bufferobj_source(intel, pbo, 64, &src_offset);
>      /* note: potential 64-bit ptr to 32-bit int cast */
>      src_offset += (GLuint) (unsigned long) pixels;
> @@ -162,7 +165,7 @@ try_pbo_upload(struct gl_context *ctx,
>         src_stride = unpack->RowLength;
>      else
>         src_stride = image->Width;
> -   src_stride *= intelImage->mt->region->cpp;
> +   src_stride *= region->cpp;
>
>      intel_miptree_get_image_offset(intelImage->mt, intelImage->base.Base.Level,
>   				  intelImage->base.Base.Face,
> @@ -172,8 +175,8 @@ try_pbo_upload(struct gl_context *ctx,
>   			  intelImage->mt->cpp,
>   			  src_stride, src_buffer,
>   			  src_offset, false,
> -			  intelImage->mt->region->pitch, dst_buffer, 0,
> -			  intelImage->mt->region->tiling,
> +			  region->pitch, dst_buffer, 0,
> +			  region->tiling,
>   			  0, 0, dst_x, dst_y, image->Width, image->Height,
>   			  GL_COPY)) {
>         DBG("%s: blit failed\n", __FUNCTION__);
> @@ -260,7 +263,7 @@ intel_set_texture_image_region(struct gl_context *ctx,
>                                                    true, 0 /* num_samples */);
>      if (intel_image->mt == NULL)
>          return;
> -   intel_region_reference(&intel_image->mt->region, region);
> +   intel_region_reference(&intel_image->mt->region_private, region);
>      intel_image->mt->total_width = width;
>      intel_image->mt->total_height = height;
>      intel_image->mt->level[0].slice[0].x_offset = tile_x;
> @@ -340,10 +343,12 @@ intelSetTexBuffer2(__DRIcontext *pDRICtx, GLint target,
>
>      _mesa_lock_texture(&intel->ctx, texObj);
>      texImage = _mesa_get_tex_image(ctx, texObj, target, level);
> -   intel_set_texture_image_region(ctx, texImage, rb->mt->region, target,
> +   struct intel_region *region =
> +      intel_miptree_get_region(intel, rb->mt, INTEL_MIPTREE_ACCESS_SHARED);
> +   intel_set_texture_image_region(ctx, texImage, region, target,
>                                     internalFormat, texFormat, 0,
> -                                  rb->mt->region->width,
> -                                  rb->mt->region->height,
> +                                  region->width,
> +                                  region->height,
>                                     0, 0);
>      _mesa_unlock_texture(&intel->ctx, texObj);
>   }
> diff --git a/src/mesa/drivers/dri/intel/intel_tex_subimage.c b/src/mesa/drivers/dri/intel/intel_tex_subimage.c
> index 42cc739..258b135 100644
> --- a/src/mesa/drivers/dri/intel/intel_tex_subimage.c
> +++ b/src/mesa/drivers/dri/intel/intel_tex_subimage.c
> @@ -66,8 +66,12 @@ intel_blit_texsubimage(struct gl_context * ctx,
>      if (!intelImage->mt)
>         return false;
>
> +   struct intel_region *region =
> +      intel_miptree_get_region(intel, intelImage->mt,
> +                               INTEL_MIPTREE_ACCESS_BLIT);
> +
>      /* The blitter can't handle Y tiling */
> -   if (intelImage->mt->region->tiling == I915_TILING_Y)
> +   if (region->tiling == I915_TILING_Y)
>         return false;
>
>      if (texImage->TexObject->Target != GL_TEXTURE_2D)
> @@ -79,7 +83,7 @@ intel_blit_texsubimage(struct gl_context * ctx,
>      if (intel->gen >= 6)
>         return false;
>
> -   if (!drm_intel_bo_busy(intelImage->mt->region->bo))
> +   if (!drm_intel_bo_busy(region->bo))
>         return false;
>
>      DBG("BLT subimage %s target %s level %d offset %d,%d %dx%d\n",
> @@ -136,9 +140,9 @@ intel_blit_texsubimage(struct gl_context * ctx,
>   			   intelImage->mt->cpp,
>   			   dstRowStride,
>   			   temp_bo, 0, false,
> -			   intelImage->mt->region->pitch,
> -			   intelImage->mt->region->bo, 0,
> -			   intelImage->mt->region->tiling,
> +			   region->pitch,
> +			   region->bo, 0,
> +			   region->tiling,
>   			   0, 0, blit_x, blit_y, width, height,
>   			   GL_COPY);
>      assert(ret);
> @@ -217,13 +221,18 @@ intel_texsubimage_tiled_memcpy(struct gl_context * ctx,
>      if (for_glTexImage)
>         ctx->Driver.AllocTextureImageBuffer(ctx, texImage);
>
> -   if (!image->mt ||
> -       image->mt->region->tiling != I915_TILING_X) {
> +   if (!image->mt)
> +      return false;
> +
> +   struct intel_region *region =
> +      intel_miptree_get_region(intel, image->mt, INTEL_MIPTREE_ACCESS_MAP);
> +
> +   if (region->tiling != I915_TILING_X) {
>         /* The algorithm below is written only for X-tiled memory. */
>         return false;
>      }
>
> -   bo = image->mt->region->bo;
> +   bo = region->bo;
>
>      if (drm_intel_bo_references(intel->batch.bo, bo)) {
>         perf_debug("Flushing before mapping a referenced bo.\n");
> @@ -266,7 +275,7 @@ intel_texsubimage_tiled_memcpy(struct gl_context * ctx,
>      const uint32_t cpp = 4; /* chars per pixel of GL_BGRA */
>      const uint32_t swizzle_width_pixels = 16;
>
> -   const uint32_t stride_bytes = image->mt->region->pitch;
> +   const uint32_t stride_bytes = region->pitch;
>      const uint32_t width_tiles = stride_bytes / tile_width_bytes;
>
>      for (uint32_t y_pixels = yoffset; y_pixels < y_max_pixels; ++y_pixels) {
>



More information about the mesa-dev mailing list