On Mon, Nov 19, 2018 at 10:54:08AM +0200, Eleni Maria Stea wrote: > 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;
I don't think 3D ETC textures are possible. From the GL4.6 spec: An INVALID_OPERATION error is generated by CompressedTexImage3D if internalformat is one of the EAC, ETC2, or RGTC formats and either border is non-zero, or target is not TEXTURE_2D_ARRAY. > + > + ptrdiff_t shadow_stride = _mesa_format_row_stride(smt->format, img_w); > + This variable gets overwritten when calling intel_miptree_map(). > + for (int level = smt->first_level; level <= smt->last_level; level++) { Since we're already iterating levels here we should fold in patch 6 to get the right level dimensions. > + struct compressed_pixelstore store; > + _mesa_compute_compressed_pixelstore(mt->surf.dim, > + mt->format, > + img_w, img_h, img_d, > + &brw->ctx.Unpack, > + &store); store.TotalBytesPerRow will give you the pitch for a buffer allocated without padding. mt->surf->row_pitch_B gives you the actual pitch. > + 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; Due to the padding mentioned earlier, the pitch divided by the width won't always give you the bytes per pixel. If we reorder the patches a bit, we should be able to use intel_miptree_map() to get mptr and it's pitch. > + > + void *sptr; > + intel_miptree_map(brw, smt, level, slice, img_x, img_y, img_w, > img_h, > + smode, &sptr, &shadow_stride); img_x and img_y are offsets relative to the start of the image (level 0/slice 0). intel_miptree_map() is looking for the x and y offset relative to each level / slice. -Nanley > + > + 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 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev