[Mesa-dev] [PATCH 4/8] i965: Update the shadow miptree from the main to fake the ETC2 compression
Eleni Maria Stea
estea at igalia.com
Mon Nov 19 08:54:08 UTC 2018
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
More information about the mesa-dev
mailing list