[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, ¶ms->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, ¶ms->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, ¶ms->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, ¶ms->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