From: Chad Versace Date: Wed, 16 Nov 2011 22:04:25 +0000 (-0800) Subject: intel: Replace intel_renderbuffer::region with a miptree [v3] X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=da2816a45e6e3a33246a341fee72e6f893f315d9;p=mesa.git intel: Replace intel_renderbuffer::region with a miptree [v3] Essentially, this patch just globally substitutes `irb->region` with `irb->mt->region` and then does some minor cleanups to avoid segfaults and other problems. This is in preparation for 1. Fixing scatter/gather for mipmapped separate stencil textures. 2. Supporting HiZ for mipmapped depth textures. As a nice benefit, this lays down some preliminary groundwork for easily texturing from any renderbuffer, even those of the window system. A future commit will replace intel_mipmap_tree::hiz_region with a miptree. v2: - Return early in intel_process_dri2_buffer_*() if region allocation fails. - Fix double semicolon. - Fix miptree reference leaks in the following functions: intel_process_dri2_buffer_with_separate_stencil() intel_image_target_renderbuffer_storage() v3: - [anholt] Fix check for hiz allocation failure. Replace ``if (!irb->mt)` with ``if(!irb->mt->hiz_region)``. Reviewed-by: Eric Anholt Reviewed-by: Kenneth Graunke Signed-off-by: Chad Versace --- diff --git a/src/mesa/drivers/dri/i965/brw_misc_state.c b/src/mesa/drivers/dri/i965/brw_misc_state.c index 514c990ed25..4119afa4c49 100644 --- a/src/mesa/drivers/dri/i965/brw_misc_state.c +++ b/src/mesa/drivers/dri/i965/brw_misc_state.c @@ -33,6 +33,7 @@ #include "intel_batchbuffer.h" #include "intel_fbo.h" +#include "intel_mipmap_tree.h" #include "intel_regions.h" #include "brw_context.h" @@ -204,9 +205,14 @@ static void emit_depthbuffer(struct brw_context *brw) /* _NEW_BUFFERS */ struct intel_renderbuffer *depth_irb = intel_get_renderbuffer(fb, BUFFER_DEPTH); struct intel_renderbuffer *stencil_irb = intel_get_renderbuffer(fb, BUFFER_STENCIL); - struct intel_region *hiz_region = depth_irb ? depth_irb->hiz_region : NULL; + struct intel_region *hiz_region = NULL; unsigned int len; + if (depth_irb && + depth_irb->mt) { + hiz_region = depth_irb->mt->hiz_region; + } + /* 3DSTATE_DEPTH_BUFFER, 3DSTATE_STENCIL_BUFFER are both * non-pipelined state that will need the PIPE_CONTROL workaround. */ @@ -272,6 +278,8 @@ static void emit_depthbuffer(struct brw_context *brw) * [DevGT]: This field must be set to the same value (enabled or * disabled) as Hierarchical Depth Buffer Enable */ + struct intel_region *region = stencil_irb->mt->region; + assert(intel->has_separate_stencil); assert(stencil_irb->Base.Format == MESA_FORMAT_S8); @@ -283,8 +291,8 @@ static void emit_depthbuffer(struct brw_context *brw) (BRW_TILEWALK_YMAJOR << 26) | (BRW_SURFACE_2D << 29)); OUT_BATCH(0); - OUT_BATCH(((stencil_irb->region->width - 1) << 6) | - (2 * stencil_irb->region->height - 1) << 19); + OUT_BATCH(((region->width - 1) << 6) | + (2 * region->height - 1) << 19); OUT_BATCH(0); OUT_BATCH(0); @@ -294,7 +302,7 @@ static void emit_depthbuffer(struct brw_context *brw) ADVANCE_BATCH(); } else { - struct intel_region *region = depth_irb->region; + struct intel_region *region = depth_irb->mt->region; unsigned int format; uint32_t tile_x, tile_y, offset; @@ -379,10 +387,11 @@ static void emit_depthbuffer(struct brw_context *brw) /* Emit stencil buffer. */ if (stencil_irb) { + struct intel_region *region = stencil_irb->mt->region; BEGIN_BATCH(3); OUT_BATCH((_3DSTATE_STENCIL_BUFFER << 16) | (3 - 2)); - OUT_BATCH(stencil_irb->region->pitch * stencil_irb->region->cpp - 1); - OUT_RELOC(stencil_irb->region->bo, + OUT_BATCH(region->pitch * region->cpp - 1); + OUT_RELOC(region->bo, I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, 0); ADVANCE_BATCH(); diff --git a/src/mesa/drivers/dri/i965/brw_vtbl.c b/src/mesa/drivers/dri/i965/brw_vtbl.c index 7c23faa8fff..9302b276347 100644 --- a/src/mesa/drivers/dri/i965/brw_vtbl.c +++ b/src/mesa/drivers/dri/i965/brw_vtbl.c @@ -126,7 +126,7 @@ brw_update_draw_buffer(struct intel_context *intel) /* Check some stencil invariants. These should probably be in * emit_depthbuffer(). */ - if (irbStencil && irbStencil->region) { + if (irbStencil && irbStencil->mt) { if (!intel->has_separate_stencil) assert(irbStencil->Base.Format == MESA_FORMAT_S8_Z24); if (fb_has_hiz || intel->must_use_separate_stencil) 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 0cc62017cbe..0c2c804b133 100644 --- a/src/mesa/drivers/dri/i965/brw_wm_surface_state.c +++ b/src/mesa/drivers/dri/i965/brw_wm_surface_state.c @@ -447,7 +447,7 @@ brw_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->region; + struct intel_region *region = irb->mt->region; uint32_t *surf; uint32_t tile_x, tile_y; uint32_t format = 0; diff --git a/src/mesa/drivers/dri/i965/gen7_misc_state.c b/src/mesa/drivers/dri/i965/gen7_misc_state.c index 6a3c086ac96..25e1b1d0fe1 100644 --- a/src/mesa/drivers/dri/i965/gen7_misc_state.c +++ b/src/mesa/drivers/dri/i965/gen7_misc_state.c @@ -22,6 +22,7 @@ */ #include "intel_batchbuffer.h" +#include "intel_mipmap_tree.h" #include "intel_regions.h" #include "intel_fbo.h" #include "brw_context.h" @@ -38,7 +39,7 @@ gen7_depth_format(struct brw_context *brw) struct intel_region *region = NULL; if (drb) - region = drb->region; + region = drb->mt->region; else return BRW_DEPTHFORMAT_D32_FLOAT; @@ -78,7 +79,7 @@ static void emit_depthbuffer(struct brw_context *brw) if (srb == NULL) { dw1 |= (BRW_SURFACE_NULL << 29); } else { - struct intel_region *region = srb->region; + struct intel_region *region = srb->mt->region; /* _NEW_STENCIL: enable stencil buffer writes */ dw1 |= ((ctx->Stencil.WriteMask != 0) << 27); @@ -98,7 +99,7 @@ static void emit_depthbuffer(struct brw_context *brw) OUT_BATCH(0); ADVANCE_BATCH(); } else { - struct intel_region *region = drb->region; + struct intel_region *region = drb->mt->region; uint32_t tile_x, tile_y, offset; offset = intel_renderbuffer_tile_offsets(drb, &tile_x, &tile_y); @@ -140,8 +141,8 @@ static void emit_depthbuffer(struct brw_context *brw) } else { BEGIN_BATCH(3); OUT_BATCH(GEN7_3DSTATE_STENCIL_BUFFER << 16 | (3 - 2)); - OUT_BATCH(srb->region->pitch * srb->region->cpp - 1); - OUT_RELOC(srb->region->bo, + OUT_BATCH(srb->mt->region->pitch * srb->mt->region->cpp - 1); + OUT_RELOC(srb->mt->region->bo, I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, 0); 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 f74198b2468..e1c3910af95 100644 --- a/src/mesa/drivers/dri/i965/gen7_wm_surface_state.c +++ b/src/mesa/drivers/dri/i965/gen7_wm_surface_state.c @@ -192,7 +192,7 @@ 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->region; + struct intel_region *region = irb->mt->region; struct gen7_surface_state *surf; uint32_t tile_x, tile_y; diff --git a/src/mesa/drivers/dri/intel/intel_blit.c b/src/mesa/drivers/dri/intel/intel_blit.c index 8d7693d7b88..b1a839ac706 100644 --- a/src/mesa/drivers/dri/intel/intel_blit.c +++ b/src/mesa/drivers/dri/intel/intel_blit.c @@ -267,13 +267,18 @@ intelClearWithBlit(struct gl_context *ctx, GLbitfield mask) int x1, y1, x2, y2; uint32_t clear_val; uint32_t BR13, CMD; + struct intel_region *region; int pitch, cpp; drm_intel_bo *aper_array[2]; mask &= ~(1 << buf); irb = intel_get_renderbuffer(fb, buf); - if (irb == NULL || irb->region == NULL || irb->region->bo == NULL) { + if (irb && irb->mt) { + region = irb->mt->region; + assert(region); + assert(region->bo); + } else { fail_mask |= 1 << buf; continue; } @@ -284,12 +289,12 @@ intelClearWithBlit(struct gl_context *ctx, GLbitfield mask) x2 = cx + cw + irb->draw_x; y2 = cy + ch + irb->draw_y; - pitch = irb->region->pitch; - cpp = irb->region->cpp; + pitch = region->pitch; + cpp = region->cpp; DBG("%s dst:buf(%p)/%d %d,%d sz:%dx%d\n", __FUNCTION__, - irb->region->bo, (pitch * cpp), + region->bo, (pitch * cpp), x1, y1, x2 - x1, y2 - y1); BR13 = 0xf0 << 16; @@ -305,10 +310,10 @@ intelClearWithBlit(struct gl_context *ctx, GLbitfield mask) } } - assert(irb->region->tiling != I915_TILING_Y); + assert(region->tiling != I915_TILING_Y); #ifndef I915 - if (irb->region->tiling != I915_TILING_NONE) { + if (region->tiling != I915_TILING_NONE) { CMD |= XY_DST_TILED; pitch /= 4; } @@ -357,7 +362,7 @@ intelClearWithBlit(struct gl_context *ctx, GLbitfield mask) /* do space check before going any further */ aper_array[0] = intel->batch.bo; - aper_array[1] = irb->region->bo; + aper_array[1] = region->bo; if (drm_intel_bufmgr_check_aperture_space(aper_array, ARRAY_SIZE(aper_array)) != 0) { @@ -369,7 +374,7 @@ intelClearWithBlit(struct gl_context *ctx, GLbitfield mask) OUT_BATCH(BR13); OUT_BATCH((y1 << 16) | x1); OUT_BATCH((y2 << 16) | x2); - OUT_RELOC_FENCED(irb->region->bo, + OUT_RELOC_FENCED(region->bo, I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, 0); OUT_BATCH(clear_val); diff --git a/src/mesa/drivers/dri/intel/intel_buffer_objects.c b/src/mesa/drivers/dri/intel/intel_buffer_objects.c index 75d95b1fe70..4a1a8165be5 100644 --- a/src/mesa/drivers/dri/intel/intel_buffer_objects.c +++ b/src/mesa/drivers/dri/intel/intel_buffer_objects.c @@ -766,10 +766,10 @@ intel_render_object_purgeable(struct gl_context * ctx, (void) option; intel = intel_renderbuffer(obj); - if (intel->region == NULL) + if (intel->mt == NULL) return GL_RELEASED_APPLE; - return intel_buffer_purgeable(intel->region->bo); + return intel_buffer_purgeable(intel->mt->region->bo); } static GLenum @@ -823,10 +823,10 @@ intel_render_object_unpurgeable(struct gl_context * ctx, (void) option; intel = intel_renderbuffer(obj); - if (intel->region == NULL) + if (intel->mt == NULL) return GL_UNDEFINED_APPLE; - return intel_buffer_unpurgeable(intel->region->bo); + return intel_buffer_unpurgeable(intel->mt->region->bo); } #endif diff --git a/src/mesa/drivers/dri/intel/intel_buffers.c b/src/mesa/drivers/dri/intel/intel_buffers.c index 08f5c4decd3..4632751935a 100644 --- a/src/mesa/drivers/dri/intel/intel_buffers.c +++ b/src/mesa/drivers/dri/intel/intel_buffers.c @@ -28,6 +28,7 @@ #include "intel_context.h" #include "intel_buffers.h" #include "intel_fbo.h" +#include "intel_mipmap_tree.h" #include "main/framebuffer.h" #include "main/renderbuffer.h" @@ -40,8 +41,8 @@ intel_drawbuf_region(struct intel_context *intel) { struct intel_renderbuffer *irbColor = intel_renderbuffer(intel->ctx.DrawBuffer->_ColorDrawBuffers[0]); - if (irbColor) - return irbColor->region; + if (irbColor && irbColor->mt) + return irbColor->mt->region; else return NULL; } @@ -54,8 +55,8 @@ intel_readbuf_region(struct intel_context *intel) { struct intel_renderbuffer *irb = intel_renderbuffer(intel->ctx.ReadBuffer->_ColorReadBuffer); - if (irb) - return irb->region; + if (irb && irb->mt) + return irb->mt->region; else return NULL; } diff --git a/src/mesa/drivers/dri/intel/intel_context.c b/src/mesa/drivers/dri/intel/intel_context.c index d89b38875b8..3f55c512357 100644 --- a/src/mesa/drivers/dri/intel/intel_context.c +++ b/src/mesa/drivers/dri/intel/intel_context.c @@ -53,6 +53,7 @@ #include "intel_fbo.h" #include "intel_bufmgr.h" #include "intel_screen.h" +#include "intel_mipmap_tree.h" #include "utils.h" #include "../glsl/ralloc.h" @@ -1153,7 +1154,9 @@ intel_process_dri2_buffer_no_separate_stencil(struct intel_context *intel, if (!rb) return; - if (rb->region && rb->region->name == buffer->name) + if (rb->mt && + rb->mt->region && + rb->mt->region->name == buffer->name) return; if (unlikely(INTEL_DEBUG & DEBUG_DRI)) { @@ -1167,23 +1170,34 @@ intel_process_dri2_buffer_no_separate_stencil(struct intel_context *intel, if (buffer->attachment == __DRI_BUFFER_STENCIL) { struct intel_renderbuffer *depth_rb = intel_get_renderbuffer(fb, BUFFER_DEPTH); - identify_depth_and_stencil = depth_rb && depth_rb->region; + identify_depth_and_stencil = depth_rb && depth_rb->mt; } if (identify_depth_and_stencil) { if (unlikely(INTEL_DEBUG & DEBUG_DRI)) { fprintf(stderr, "(reusing depth buffer as stencil)\n"); } - intel_region_reference(&rb->region, depth_rb->region); + intel_miptree_reference(&rb->mt, depth_rb->mt); } else { - intel_region_release(&rb->region); - rb->region = intel_region_alloc_for_handle(intel->intelScreen, + intel_miptree_release(&rb->mt); + struct intel_region *region = + intel_region_alloc_for_handle(intel->intelScreen, buffer->cpp, drawable->w, drawable->h, buffer->pitch / buffer->cpp, buffer->name, buffer_name); + if (!region) + return; + + rb->mt = intel_miptree_create_for_region(intel, + GL_TEXTURE_2D, + rb->Base.Format, + region); + intel_region_release(®ion); + if (!rb->mt) + return; } if (buffer->attachment == __DRI_BUFFER_DEPTH_STENCIL) { @@ -1196,7 +1210,7 @@ intel_process_dri2_buffer_no_separate_stencil(struct intel_context *intel, /* The rb passed in is the BUFFER_DEPTH attachment, and we need * to associate this region to BUFFER_STENCIL as well. */ - intel_region_reference(&stencil_rb->region, rb->region); + intel_miptree_reference(&stencil_rb->mt, rb->mt); } } @@ -1338,11 +1352,13 @@ intel_process_dri2_buffer_with_separate_stencil(struct intel_context *intel, /* If the renderbuffer's and DRIbuffer's regions match, then continue. */ if ((buffer->attachment != __DRI_BUFFER_HIZ && - rb->region && - rb->region->name == buffer->name) || + rb->mt && + rb->mt->region && + rb->mt->region->name == buffer->name) || (buffer->attachment == __DRI_BUFFER_HIZ && - rb->hiz_region && - rb->hiz_region->name == buffer->name)) { + rb->mt && + rb->mt->hiz_region && + rb->mt->hiz_region->name == buffer->name)) { return; } @@ -1371,6 +1387,15 @@ intel_process_dri2_buffer_with_separate_stencil(struct intel_context *intel, buffer_height = drawable->h; } + /* Release the buffer storage now in case we have to return early + * due to region allocation failure. + */ + if (buffer->attachment == __DRI_BUFFER_HIZ) { + intel_region_release(&rb->mt->hiz_region); + } else { + intel_miptree_release(&rb->mt); + } + struct intel_region *region = intel_region_alloc_for_handle(intel->intelScreen, buffer->cpp, @@ -1379,14 +1404,19 @@ intel_process_dri2_buffer_with_separate_stencil(struct intel_context *intel, buffer->pitch / buffer->cpp, buffer->name, buffer_name); + if (!region) + return; + /* Associate buffer with new storage. */ if (buffer->attachment == __DRI_BUFFER_HIZ) { - intel_region_reference(&rb->hiz_region, region); + rb->mt->hiz_region = region; } else { - intel_region_reference(&rb->region, region); + rb->mt = intel_miptree_create_for_region(intel, + GL_TEXTURE_2D, + rb->Base.Format, + region); + intel_region_release(®ion); } - - intel_region_release(®ion); } /** @@ -1463,7 +1493,7 @@ intel_verify_dri2_has_hiz(struct intel_context *intel, assert(stencil_rb->Base.Format == MESA_FORMAT_S8); assert(depth_rb && depth_rb->Base.Format == MESA_FORMAT_X8_Z24); - if (stencil_rb->region->tiling == I915_TILING_NONE) { + if (stencil_rb->mt->region->tiling == I915_TILING_NONE) { /* * The stencil buffer is actually W tiled. The region's tiling is * I915_TILING_NONE, however, because the GTT is incapable of W @@ -1544,11 +1574,21 @@ intel_verify_dri2_has_hiz(struct intel_context *intel, / depth_stencil_buffer->cpp, depth_stencil_buffer->name, "dri2 depth / stencil buffer"); - intel_region_reference(&intel_get_renderbuffer(fb, BUFFER_DEPTH)->region, - region); - intel_region_reference(&intel_get_renderbuffer(fb, BUFFER_STENCIL)->region, - region); + if (!region) + return; + + struct intel_mipmap_tree *mt = + intel_miptree_create_for_region(intel, + GL_TEXTURE_2D, + depth_stencil_rb->Base.Format, + region); intel_region_release(®ion); + if (!mt) + return; + + intel_miptree_reference(&intel_get_renderbuffer(fb, BUFFER_DEPTH)->mt, mt); + intel_miptree_reference(&intel_get_renderbuffer(fb, BUFFER_STENCIL)->mt, mt); + intel_miptree_release(&mt); } } diff --git a/src/mesa/drivers/dri/intel/intel_fbo.c b/src/mesa/drivers/dri/intel/intel_fbo.c index 429529c81c4..e5328df2ff5 100644 --- a/src/mesa/drivers/dri/intel/intel_fbo.c +++ b/src/mesa/drivers/dri/intel/intel_fbo.c @@ -61,15 +61,15 @@ intel_framebuffer_has_hiz(struct gl_framebuffer *fb) struct intel_renderbuffer *rb = NULL; if (fb) rb = intel_get_renderbuffer(fb, BUFFER_DEPTH); - return rb && rb->hiz_region; + return rb && rb->mt && rb->mt->hiz_region; } struct intel_region* intel_get_rb_region(struct gl_framebuffer *fb, GLuint attIndex) { struct intel_renderbuffer *irb = intel_get_renderbuffer(fb, attIndex); - if (irb) - return irb->region; + if (irb && irb->mt) + return irb->mt->region; else return NULL; } @@ -95,8 +95,7 @@ intel_delete_renderbuffer(struct gl_renderbuffer *rb) ASSERT(irb); - intel_region_release(&irb->region); - intel_region_release(&irb->hiz_region); + intel_miptree_release(&irb->mt); _mesa_reference_renderbuffer(&irb->wrapped_depth, NULL); _mesa_reference_renderbuffer(&irb->wrapped_stencil, NULL); @@ -122,7 +121,7 @@ intel_map_renderbuffer_gtt(struct gl_context *ctx, GLubyte *map; int stride, flip_stride; - assert(irb->region); + assert(irb->mt); irb->map_mode = mode; irb->map_x = x; @@ -130,10 +129,10 @@ intel_map_renderbuffer_gtt(struct gl_context *ctx, irb->map_w = w; irb->map_h = h; - stride = irb->region->pitch * irb->region->cpp; + stride = irb->mt->region->pitch * irb->mt->region->cpp; if (rb->Name == 0) { - y = irb->region->height - 1 - y; + y = irb->mt->region->height - 1 - y; flip_stride = -stride; } else { x += irb->draw_x; @@ -141,14 +140,14 @@ intel_map_renderbuffer_gtt(struct gl_context *ctx, flip_stride = stride; } - if (drm_intel_bo_references(intel->batch.bo, irb->region->bo)) { + if (drm_intel_bo_references(intel->batch.bo, irb->mt->region->bo)) { intel_batchbuffer_flush(intel); } - drm_intel_gem_bo_map_gtt(irb->region->bo); + drm_intel_gem_bo_map_gtt(irb->mt->region->bo); - map = irb->region->bo->virtual; - map += x * irb->region->cpp; + map = irb->mt->region->bo->virtual; + map += x * irb->mt->region->cpp; map += (int)y * stride; *out_map = map; @@ -186,10 +185,10 @@ intel_map_renderbuffer_blit(struct gl_context *ctx, int src_x, src_y; int dst_stride; - assert(irb->region); + assert(irb->mt->region); assert(intel->gen >= 6); assert(!(mode & GL_MAP_WRITE_BIT)); - assert(irb->region->tiling == I915_TILING_X); + assert(irb->mt->region->tiling == I915_TILING_X); irb->map_mode = mode; irb->map_x = x; @@ -197,14 +196,14 @@ intel_map_renderbuffer_blit(struct gl_context *ctx, irb->map_w = w; irb->map_h = h; - dst_stride = ALIGN(w * irb->region->cpp, 4); + dst_stride = ALIGN(w * irb->mt->region->cpp, 4); if (rb->Name) { src_x = x + irb->draw_x; src_y = y + irb->draw_y; } else { src_x = x; - src_y = irb->region->height - y - h; + src_y = irb->mt->region->height - y - h; } irb->map_bo = drm_intel_bo_alloc(intel->bufmgr, "MapRenderbuffer() temp", @@ -215,10 +214,10 @@ intel_map_renderbuffer_blit(struct gl_context *ctx, */ if (irb->map_bo && intelEmitCopyBlit(intel, - irb->region->cpp, - irb->region->pitch, irb->region->bo, - 0, irb->region->tiling, - dst_stride / irb->region->cpp, irb->map_bo, + irb->mt->region->cpp, + irb->mt->region->pitch, irb->mt->region->bo, + 0, irb->mt->region->tiling, + dst_stride / irb->mt->region->cpp, irb->map_bo, 0, I915_TILING_NONE, src_x, src_y, 0, 0, @@ -277,7 +276,7 @@ intel_map_renderbuffer_s8(struct gl_context *ctx, uint8_t *untiled_s8_map; assert(rb->Format == MESA_FORMAT_S8); - assert(irb->region); + assert(irb->mt); irb->map_mode = mode; irb->map_x = x; @@ -291,12 +290,12 @@ intel_map_renderbuffer_s8(struct gl_context *ctx, irb->map_buffer = malloc(w * h); untiled_s8_map = irb->map_buffer; - tiled_s8_map = intel_region_map(intel, irb->region, mode); + tiled_s8_map = intel_region_map(intel, irb->mt->region, mode); for (uint32_t pix_y = 0; pix_y < h; pix_y++) { for (uint32_t pix_x = 0; pix_x < w; pix_x++) { uint32_t flipped_y = y_flip * (int32_t)(y + pix_y) + y_bias; - ptrdiff_t offset = intel_offset_S8(irb->region->pitch, + ptrdiff_t offset = intel_offset_S8(irb->mt->region->pitch, x + pix_x, flipped_y); untiled_s8_map[pix_y * w + pix_x] = tiled_s8_map[offset]; @@ -363,12 +362,12 @@ intel_map_renderbuffer_separate_s8z24(struct gl_context *ctx, &s8z24_map, &s8z24_stride); s8_irb = intel_renderbuffer(irb->wrapped_stencil); - s8_map = intel_region_map(intel, s8_irb->region, GL_MAP_READ_BIT); + s8_map = intel_region_map(intel, s8_irb->mt->region, GL_MAP_READ_BIT); /* Gather the stencil buffer into the depth buffer. */ for (uint32_t pix_y = 0; pix_y < h; ++pix_y) { for (uint32_t pix_x = 0; pix_x < w; ++pix_x) { - ptrdiff_t s8_offset = intel_offset_S8(s8_irb->region->pitch, + ptrdiff_t s8_offset = intel_offset_S8(s8_irb->mt->region->pitch, x + pix_x, y + pix_y); ptrdiff_t s8z24_offset = pix_y * s8z24_stride @@ -378,7 +377,7 @@ intel_map_renderbuffer_separate_s8z24(struct gl_context *ctx, } } - intel_region_unmap(intel, s8_irb->region); + intel_region_unmap(intel, s8_irb->mt->region); *out_map = s8z24_map; *out_stride = s8z24_stride; @@ -399,7 +398,7 @@ intel_map_renderbuffer(struct gl_context *ctx, struct intel_renderbuffer *irb = intel_renderbuffer(rb); /* We sometimes get called with this by our intel_span.c usage. */ - if (!irb->region && !irb->wrapped_depth) { + if (!irb->mt && !irb->wrapped_depth) { *out_map = NULL; *out_stride = 0; return; @@ -413,7 +412,7 @@ intel_map_renderbuffer(struct gl_context *ctx, out_map, out_stride); } else if (intel->gen >= 6 && !(mode & GL_MAP_WRITE_BIT) && - irb->region->tiling == I915_TILING_X) { + irb->mt->region->tiling == I915_TILING_X) { intel_map_renderbuffer_blit(ctx, rb, x, y, w, h, mode, out_map, out_stride); } else { @@ -445,7 +444,7 @@ intel_unmap_renderbuffer_s8(struct gl_context *ctx, * the real buffer. */ uint8_t *untiled_s8_map = irb->map_buffer; - uint8_t *tiled_s8_map = irb->region->bo->virtual; + uint8_t *tiled_s8_map = irb->mt->region->bo->virtual; /* Flip the Y axis for the default framebuffer. */ int y_flip = (rb->Name == 0) ? -1 : 1; @@ -454,7 +453,7 @@ intel_unmap_renderbuffer_s8(struct gl_context *ctx, for (uint32_t pix_y = 0; pix_y < irb->map_h; pix_y++) { for (uint32_t pix_x = 0; pix_x < irb->map_w; pix_x++) { uint32_t flipped_y = y_flip * (int32_t)(pix_y + irb->map_y) + y_bias; - ptrdiff_t offset = intel_offset_S8(irb->region->pitch, + ptrdiff_t offset = intel_offset_S8(irb->mt->region->pitch, pix_x + irb->map_x, flipped_y); tiled_s8_map[offset] = @@ -463,7 +462,7 @@ intel_unmap_renderbuffer_s8(struct gl_context *ctx, } } - intel_region_unmap(intel, irb->region); + intel_region_unmap(intel, irb->mt->region); free(irb->map_buffer); irb->map_buffer = NULL; } @@ -501,16 +500,16 @@ intel_unmap_renderbuffer_separate_s8z24(struct gl_context *ctx, uint8_t *s8_map; s8_irb = intel_renderbuffer(irb->wrapped_stencil); - s8_map = intel_region_map(intel, s8_irb->region, GL_MAP_WRITE_BIT); + s8_map = intel_region_map(intel, s8_irb->mt->region, GL_MAP_WRITE_BIT); - int32_t s8z24_stride = 4 * s8z24_irb->region->pitch; - uint8_t *s8z24_map = s8z24_irb->region->bo->virtual + int32_t s8z24_stride = 4 * s8z24_irb->mt->region->pitch; + uint8_t *s8z24_map = s8z24_irb->mt->region->bo->virtual + map_y * s8z24_stride + map_x * 4; for (uint32_t pix_y = 0; pix_y < map_h; ++pix_y) { for (uint32_t pix_x = 0; pix_x < map_w; ++pix_x) { - ptrdiff_t s8_offset = intel_offset_S8(s8_irb->region->pitch, + ptrdiff_t s8_offset = intel_offset_S8(s8_irb->mt->region->pitch, map_x + pix_x, map_y + pix_y); ptrdiff_t s8z24_offset = pix_y * s8z24_stride @@ -520,10 +519,10 @@ intel_unmap_renderbuffer_separate_s8z24(struct gl_context *ctx, } } - intel_region_unmap(intel, s8_irb->region); + intel_region_unmap(intel, s8_irb->mt->region); } - drm_intel_gem_bo_unmap_gtt(s8z24_irb->region->bo); + drm_intel_gem_bo_unmap_gtt(s8z24_irb->mt->region->bo); } /** @@ -549,11 +548,11 @@ intel_unmap_renderbuffer(struct gl_context *ctx, irb->map_bo = 0; } else { /* Paired with intel_map_renderbuffer_gtt(). */ - if (irb->region) { - /* The region may be null when intel_map_renderbuffer() is + if (irb->mt) { + /* The miptree may be null when intel_map_renderbuffer() is * called from intel_span.c. */ - drm_intel_gem_bo_unmap_gtt(irb->region->bo); + drm_intel_gem_bo_unmap_gtt(irb->mt->region->bo); } } } @@ -620,13 +619,7 @@ intel_alloc_renderbuffer_storage(struct gl_context * ctx, struct gl_renderbuffer intel_flush(ctx); - /* free old region */ - if (irb->region) { - intel_region_release(&irb->region); - } - if (irb->hiz_region) { - intel_region_release(&irb->hiz_region); - } + intel_miptree_release(&irb->mt); DBG("%s: %s: %s (%dx%d)\n", __FUNCTION__, _mesa_lookup_enum_by_nr(internalFormat), @@ -658,14 +651,15 @@ intel_alloc_renderbuffer_storage(struct gl_context * ctx, struct gl_renderbuffer * * If we neglect to double the pitch, then render corruption occurs. */ - irb->region = intel_region_alloc(intel->intelScreen, - I915_TILING_NONE, - cpp * 2, - ALIGN(width, 64), - ALIGN((height + 1) / 2, 64), - true); - if (!irb->region) - return false; + irb->mt = intel_miptree_create_for_renderbuffer( + intel, + rb->Format, + I915_TILING_NONE, + cpp * 2, + ALIGN(width, 64), + ALIGN((height + 1) / 2, 64)); + if (!irb->mt) + return false; } else if (irb->Base.Format == MESA_FORMAT_S8_Z24 && intel->must_use_separate_stencil) { @@ -702,20 +696,21 @@ intel_alloc_renderbuffer_storage(struct gl_context * ctx, struct gl_renderbuffer _mesa_reference_renderbuffer(&irb->wrapped_stencil, stencil_rb); } else { - irb->region = intel_region_alloc(intel->intelScreen, tiling, cpp, - width, height, true); - if (!irb->region) + irb->mt = intel_miptree_create_for_renderbuffer(intel, rb->Format, + tiling, cpp, + width, height); + if (!irb->mt) return false; if (intel->vtbl.is_hiz_depth_format(intel, rb->Format)) { - irb->hiz_region = intel_region_alloc(intel->intelScreen, - I915_TILING_Y, - irb->region->cpp, - irb->region->width, - irb->region->height, - true); - if (!irb->hiz_region) { - intel_region_release(&irb->region); + irb->mt->hiz_region = intel_region_alloc(intel->intelScreen, + I915_TILING_Y, + cpp, + rb->Width, + rb->Height, + true); + if (!irb->mt->hiz_region) { + intel_miptree_release(&irb->mt); return false; } } @@ -754,7 +749,13 @@ intel_image_target_renderbuffer_storage(struct gl_context *ctx, } irb = intel_renderbuffer(rb); - intel_region_reference(&irb->region, image->region); + intel_miptree_release(&irb->mt); + irb->mt = intel_miptree_create_for_region(intel, + GL_TEXTURE_2D, + image->format, + image->region); + if (!irb->mt) + return; rb->InternalFormat = image->internal_format; rb->Width = image->region->width; @@ -982,9 +983,8 @@ intel_update_wrapper(struct gl_context *ctx, struct intel_renderbuffer *irb, _mesa_reference_renderbuffer(&irb->wrapped_stencil, intel_image->stencil_rb); } else { - intel_region_reference(&irb->region, intel_image->mt->region); + intel_miptree_reference(&irb->mt, intel_image->mt); } - return true; } @@ -1050,20 +1050,21 @@ intel_renderbuffer_tile_offsets(struct intel_renderbuffer *irb, uint32_t *tile_x, uint32_t *tile_y) { - int cpp = irb->region->cpp; - uint32_t pitch = irb->region->pitch * cpp; + struct intel_region *region = irb->mt->region; + int cpp = region->cpp; + uint32_t pitch = region->pitch * cpp; - if (irb->region->tiling == I915_TILING_NONE) { + if (region->tiling == I915_TILING_NONE) { *tile_x = 0; *tile_y = 0; return irb->draw_x * cpp + irb->draw_y * pitch; - } else if (irb->region->tiling == I915_TILING_X) { + } else if (region->tiling == I915_TILING_X) { *tile_x = irb->draw_x % (512 / cpp); *tile_y = irb->draw_y % 8; return ((irb->draw_y / 8) * (8 * pitch) + (irb->draw_x - *tile_x) / (512 / cpp) * 4096); } else { - assert(irb->region->tiling == I915_TILING_Y); + assert(region->tiling == I915_TILING_Y); *tile_x = irb->draw_x % (128 / cpp); *tile_y = irb->draw_y % 32; return ((irb->draw_y / 32) * (32 * pitch) + @@ -1164,7 +1165,7 @@ intel_render_texture(struct gl_context * ctx, intel_miptree_copy_teximage(intel, intel_image, new_mt); intel_renderbuffer_set_draw_offset(irb, intel_image, att->Zoffset); - intel_region_reference(&irb->region, intel_image->mt->region); + intel_miptree_reference(&irb->mt, intel_image->mt); intel_miptree_release(&new_mt); } #endif diff --git a/src/mesa/drivers/dri/intel/intel_fbo.h b/src/mesa/drivers/dri/intel/intel_fbo.h index 63da6659296..34d2f9a61cf 100644 --- a/src/mesa/drivers/dri/intel/intel_fbo.h +++ b/src/mesa/drivers/dri/intel/intel_fbo.h @@ -35,6 +35,7 @@ #include "intel_screen.h" struct intel_context; +struct intel_mipmap_tree; struct intel_texture_image; /** @@ -43,15 +44,13 @@ struct intel_texture_image; struct intel_renderbuffer { struct gl_renderbuffer Base; - struct intel_region *region; + struct intel_mipmap_tree *mt; /**< The renderbuffer storage. */ drm_intel_bo *map_bo; + void *map_buffer; GLuint map_x, map_y, map_w, map_h; GLbitfield map_mode; - /** Only used by depth renderbuffers for which HiZ is enabled. */ - struct intel_region *hiz_region; - /** * \name Packed depth/stencil unwrappers * diff --git a/src/mesa/drivers/dri/intel/intel_pixel_copy.c b/src/mesa/drivers/dri/intel/intel_pixel_copy.c index 89d5c51ef15..2682e152abc 100644 --- a/src/mesa/drivers/dri/intel/intel_pixel_copy.c +++ b/src/mesa/drivers/dri/intel/intel_pixel_copy.c @@ -34,6 +34,7 @@ #include "intel_context.h" #include "intel_buffers.h" +#include "intel_mipmap_tree.h" #include "intel_regions.h" #include "intel_pixel.h" #include "intel_fbo.h" @@ -188,8 +189,8 @@ do_blit_copypixels(struct gl_context * ctx, dsty += draw_irb->draw_y; if (!intel_region_copy(intel, - draw_irb->region, 0, dstx, dsty, - read_irb->region, 0, srcx, srcy, + draw_irb->mt->region, 0, dstx, dsty, + read_irb->mt->region, 0, srcx, srcy, width, height, flip, ctx->Color.ColorLogicOpEnabled ? ctx->Color.LogicOp : GL_COPY)) { diff --git a/src/mesa/drivers/dri/intel/intel_screen.c b/src/mesa/drivers/dri/intel/intel_screen.c index 5a73030660f..67dccdf6006 100644 --- a/src/mesa/drivers/dri/intel/intel_screen.c +++ b/src/mesa/drivers/dri/intel/intel_screen.c @@ -86,6 +86,7 @@ const GLuint __driNConfigOptions = 11; #include "intel_bufmgr.h" #include "intel_chipset.h" #include "intel_fbo.h" +#include "intel_mipmap_tree.h" #include "intel_screen.h" #include "intel_tex.h" #include "intel_regions.h" @@ -201,7 +202,7 @@ intel_create_image_from_renderbuffer(__DRIcontext *context, image->format = rb->Format; image->data_type = rb->DataType; image->data = loaderPrivate; - intel_region_reference(&image->region, irb->region); + intel_region_reference(&image->region, irb->mt->region); return image; } diff --git a/src/mesa/drivers/dri/intel/intel_span.c b/src/mesa/drivers/dri/intel/intel_span.c index b103bbd9f7f..83676b9313d 100644 --- a/src/mesa/drivers/dri/intel/intel_span.c +++ b/src/mesa/drivers/dri/intel/intel_span.c @@ -39,6 +39,7 @@ #include "intel_buffers.h" #include "intel_fbo.h" +#include "intel_mipmap_tree.h" #include "intel_screen.h" #include "intel_span.h" #include "intel_regions.h" @@ -58,7 +59,7 @@ intel_set_span_functions(struct intel_context *intel, int minx = 0, miny = 0; \ int maxx = rb->Width; \ int maxy = rb->Height; \ - int pitch = rb->RowStride * irb->region->cpp; \ + int pitch = rb->RowStride * irb->mt->region->cpp; \ void *buf = rb->Data; \ GLuint p; \ (void) p; diff --git a/src/mesa/drivers/dri/intel/intel_tex_copy.c b/src/mesa/drivers/dri/intel/intel_tex_copy.c index 2df4ef6a7f6..543326a0580 100644 --- a/src/mesa/drivers/dri/intel/intel_tex_copy.c +++ b/src/mesa/drivers/dri/intel/intel_tex_copy.c @@ -71,6 +71,7 @@ intel_copy_texsubimage(struct intel_context *intel, { struct gl_context *ctx = &intel->ctx; struct intel_renderbuffer *irb; + struct intel_region *region; const GLenum internalFormat = intelImage->base.Base.InternalFormat; bool copy_supported = false; bool copy_supported_with_alpha_override = false; @@ -78,11 +79,14 @@ intel_copy_texsubimage(struct intel_context *intel, intel_prepare_render(intel); irb = get_teximage_readbuffer(intel, internalFormat); - if (!intelImage->mt || !irb || !irb->region) { + if (!intelImage->mt || !irb || !irb->mt) { if (unlikely(INTEL_DEBUG & DEBUG_FALLBACKS)) fprintf(stderr, "%s fail %p %p (0x%08x)\n", __FUNCTION__, intelImage->mt, irb, internalFormat); return false; + } else { + region = irb->mt->region; + assert(region); } copy_supported = intelImage->base.Base.TexFormat == irb->Base.Format; @@ -127,19 +131,19 @@ intel_copy_texsubimage(struct intel_context *intel, if (ctx->ReadBuffer->Name == 0) { /* Flip vertical orientation for system framebuffers */ y = ctx->ReadBuffer->Height - (y + height); - src_pitch = -irb->region->pitch; + src_pitch = -region->pitch; } else { /* reading from a FBO, y is already oriented the way we like */ - src_pitch = irb->region->pitch; + src_pitch = region->pitch; } /* blit from src buffer to texture */ if (!intelEmitCopyBlit(intel, intelImage->mt->cpp, src_pitch, - irb->region->bo, + region->bo, 0, - irb->region->tiling, + region->tiling, intelImage->mt->region->pitch, intelImage->mt->region->bo, 0, diff --git a/src/mesa/drivers/dri/intel/intel_tex_image.c b/src/mesa/drivers/dri/intel/intel_tex_image.c index 3fc2128536c..90e409094d5 100644 --- a/src/mesa/drivers/dri/intel/intel_tex_image.c +++ b/src/mesa/drivers/dri/intel/intel_tex_image.c @@ -306,7 +306,7 @@ intel_tex_image_s8z24_create_renderbuffers(struct intel_context *intel, idrb = intel_renderbuffer(drb); isrb = intel_renderbuffer(srb); - intel_region_reference(&idrb->region, image->mt->region); + intel_miptree_reference(&idrb->mt, image->mt); ok = intel_alloc_renderbuffer_storage(ctx, srb, GL_STENCIL_INDEX8, width, height); @@ -471,7 +471,7 @@ intelSetTexBuffer2(__DRIcontext *pDRICtx, GLint target, /* If the region isn't set, then intel_update_renderbuffers was unable * to get the buffers for the drawable. */ - if (rb->region == NULL) + if (!rb || !rb->mt) return; if (texture_format == __DRI_TEXTURE_FORMAT_RGB) { @@ -485,7 +485,7 @@ 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->region, target, + intel_set_texture_image_region(ctx, texImage, rb->mt->region, target, internalFormat, texFormat); _mesa_unlock_texture(&intel->ctx, texObj); }