On GPUs gen < 8 that don't support ETC2 sampling/rendering we now fake the support using 2 mipmap trees: one (the main) that stores the compressed data for the Get* functions to work and one (the shadow) that stores the same data decompressed for the render/sampling to work.
Added the intel_update_decompressed_shadow function to update the shadow tree with the decompressed data whenever the main miptree with the compressed is changing. --- .../drivers/dri/i965/brw_wm_surface_state.c | 1 + src/mesa/drivers/dri/i965/intel_mipmap_tree.c | 70 ++++++++++++++++++- src/mesa/drivers/dri/i965/intel_mipmap_tree.h | 3 + 3 files changed, 71 insertions(+), 3 deletions(-) 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 4d1eafac91..2e6d85e1fe 100644 --- a/src/mesa/drivers/dri/i965/brw_wm_surface_state.c +++ b/src/mesa/drivers/dri/i965/brw_wm_surface_state.c @@ -579,6 +579,7 @@ static void brw_update_texture_surface(struct gl_context *ctx, if (obj->StencilSampling && firstImage->_BaseFormat == GL_DEPTH_STENCIL) { if (devinfo->gen <= 7) { + assert(!intel_obj->mt->needs_fake_etc); assert(mt->shadow_mt && !mt->stencil_mt->shadow_needs_update); mt = mt->shadow_mt; } else { diff --git a/src/mesa/drivers/dri/i965/intel_mipmap_tree.c b/src/mesa/drivers/dri/i965/intel_mipmap_tree.c index b24332ff67..ef3e2c33d3 100644 --- a/src/mesa/drivers/dri/i965/intel_mipmap_tree.c +++ b/src/mesa/drivers/dri/i965/intel_mipmap_tree.c @@ -3740,12 +3740,15 @@ intel_miptree_map(struct brw_context *brw, assert(mt->surf.samples == 1); if (mt->needs_fake_etc) { - if (!(mode & BRW_MAP_ETC_BIT)) { + if (!(mode & BRW_MAP_ETC_BIT) && !(mode & GL_MAP_READ_BIT)) { assert(mt->shadow_mt); - mt->is_shadow_mapped = true; + if (mt->shadow_needs_update) { + intel_update_decompressed_shadow(brw, mt); + mt->shadow_needs_update = false; + } - mt->shadow_needs_update = false; + mt->is_shadow_mapped = true; mt = miptree->shadow_mt; } else { mt->is_shadow_mapped = false; @@ -3762,6 +3765,8 @@ intel_miptree_map(struct brw_context *brw, map = intel_miptree_attach_map(mt, level, slice, x, y, w, h, mode); if (!map){ + miptree->is_shadow_mapped = false; + *out_ptr = NULL; *out_stride = 0; return; @@ -3942,3 +3947,62 @@ intel_miptree_get_clear_color(const struct gen_device_info *devinfo, return mt->fast_clear_color; } } + +void +intel_update_decompressed_shadow(struct brw_context *brw, + struct intel_mipmap_tree *mt) +{ + struct intel_mipmap_tree *smt = mt->shadow_mt; + + assert(smt); + assert(mt->needs_fake_etc); + assert(mt->surf.size_B > 0); + + int img_w = smt->surf.logical_level0_px.width; + int img_h = smt->surf.logical_level0_px.height; + int img_d = smt->surf.logical_level0_px.depth; + + ptrdiff_t shadow_stride = _mesa_format_row_stride(smt->format, img_w); + + for (int level = smt->first_level; level <= smt->last_level; level++) { + struct compressed_pixelstore store; + _mesa_compute_compressed_pixelstore(mt->surf.dim, + mt->format, + img_w, img_h, img_d, + &brw->ctx.Unpack, + &store); + for (unsigned int slice = 0; slice < img_d; slice++) { + GLbitfield mmode = GL_MAP_READ_BIT | BRW_MAP_DIRECT_BIT | + BRW_MAP_ETC_BIT; + GLbitfield smode = GL_MAP_WRITE_BIT | + GL_MAP_INVALIDATE_RANGE_BIT | + BRW_MAP_DIRECT_BIT; + + uint32_t img_x, img_y; + intel_miptree_get_image_offset(smt, level, slice, &img_x, &img_y); + + void *mptr = intel_miptree_map_raw(brw, mt, mmode) + mt->offset + + img_y * store.TotalBytesPerRow + + img_x * store.TotalBytesPerRow / img_w; + + void *sptr; + intel_miptree_map(brw, smt, level, slice, img_x, img_y, img_w, img_h, + smode, &sptr, &shadow_stride); + + if (mt->format == MESA_FORMAT_ETC1_RGB8) { + _mesa_etc1_unpack_rgba8888(sptr, shadow_stride, + mptr, store.TotalBytesPerRow, + img_w, img_h); + } else { + _mesa_unpack_etc2_format(sptr, shadow_stride, + mptr, store.TotalBytesPerRow, + img_w, img_h, mt->format, true); + } + + intel_miptree_unmap_raw(mt); + intel_miptree_unmap(brw, smt, level, slice); + } + } + + mt->shadow_needs_update = false; +} diff --git a/src/mesa/drivers/dri/i965/intel_mipmap_tree.h b/src/mesa/drivers/dri/i965/intel_mipmap_tree.h index aca45cfaa4..02c98c80ca 100644 --- a/src/mesa/drivers/dri/i965/intel_mipmap_tree.h +++ b/src/mesa/drivers/dri/i965/intel_mipmap_tree.h @@ -733,6 +733,9 @@ intel_miptree_get_clear_color(const struct gen_device_info *devinfo, struct brw_bo **clear_color_bo, uint32_t *clear_color_offset); +void +intel_update_decompressed_shadow(struct brw_context *brw, + struct intel_mipmap_tree *mt); static inline int intel_miptree_blt_pitch(struct intel_mipmap_tree *mt) -- 2.19.0 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev