[Mesa-dev] [PATCH 1/5] i965: define astc5x5 workaround infrastructure

kevin.rogovin at intel.com kevin.rogovin at intel.com
Fri Dec 1 17:19:18 UTC 2017


From: Kevin Rogovin <kevin.rogovin at intel.com>

Some GEN's have a bug in the sample where if the sampler accesses
a texture with an auxialry surface and an ASTC5x5 texture without
having the texture cache invalidated between such accesses, then
the GPU will hang. This patch defines the infrastructure to
implement the needed workaround for such hardware.

Signed-off-by: Kevin Rogovin <kevin.rogovin at intel.com>
---
 src/mesa/drivers/dri/i965/brw_context.c       | 63 +++++++++++++++++++++++++++
 src/mesa/drivers/dri/i965/brw_context.h       | 23 ++++++++++
 src/mesa/drivers/dri/i965/intel_batchbuffer.c |  1 +
 3 files changed, 87 insertions(+)

diff --git a/src/mesa/drivers/dri/i965/brw_context.c b/src/mesa/drivers/dri/i965/brw_context.c
index dd55b43669..f2e9b9779a 100644
--- a/src/mesa/drivers/dri/i965/brw_context.c
+++ b/src/mesa/drivers/dri/i965/brw_context.c
@@ -1060,6 +1060,12 @@ brwCreateContext(gl_api api,
    if (ctx->Extensions.INTEL_performance_query)
       brw_init_performance_queries(brw);
 
+   brw->astc5x5_wa.required = (devinfo->gen == 9);
+   brw->astc5x5_wa.mode = BRW_ASTC5x5_WA_MODE_NONE;
+   brw->astc5x5_wa.texture_astc5x5_present = false;
+   brw->astc5x5_wa.texture_with_auxilary_present = false;
+   brw->astc5x5_wa.blorp_sampling_from_astc5x5 = false;
+
    vbo_use_buffer_objects(ctx);
    vbo_always_unmap_buffers(ctx);
 
@@ -1134,6 +1140,63 @@ intelDestroyContext(__DRIcontext * driContextPriv)
    driContextPriv->driverPrivate = NULL;
 }
 
+void
+brw_set_astc5x5_wa_mode(struct brw_context *brw,
+                        enum brw_astc5x5_wa_mode_t mode)
+{
+   if (!brw->astc5x5_wa.required ||
+       mode == BRW_ASTC5x5_WA_MODE_NONE ||
+       brw->astc5x5_wa.mode == mode) {
+      return;
+   }
+
+   if (brw->astc5x5_wa.mode != BRW_ASTC5x5_WA_MODE_NONE) {
+      brw_emit_pipe_control_flush(brw, PIPE_CONTROL_TEXTURE_CACHE_INVALIDATE);
+   }
+
+   brw->astc5x5_wa.mode = mode;
+}
+
+static void
+resolve_to_disable_aux_on_samplers(struct brw_context *brw)
+{
+   struct gl_context *ctx = &brw->ctx;
+   const int max_enabled_unit = ctx->Texture._MaxEnabledTexImageUnit;
+
+   for (int unit = 0; unit <= max_enabled_unit; unit++) {
+      struct gl_texture_unit *tex_unit = &ctx->Texture.Unit[unit];
+      struct gl_texture_object *tex_obj = tex_unit->_Current;
+      if (tex_obj) {
+         struct intel_mipmap_tree *mt = intel_texture_object(tex_obj)->mt;
+         if (mt && mt->aux_usage != ISL_AUX_USAGE_NONE) {
+            intel_miptree_prepare_access(brw, mt,
+                                         0, INTEL_REMAINING_LEVELS,
+                                         0, INTEL_REMAINING_LAYERS,
+                                         ISL_AUX_USAGE_NONE, false);
+         }
+      }
+   }
+}
+
+void
+brw_astc5x5_perform_wa(struct brw_context *brw)
+{
+   if (!brw->astc5x5_wa.required) {
+      return;
+   }
+
+   if (brw->astc5x5_wa.texture_astc5x5_present) {
+      if (brw->astc5x5_wa.texture_with_auxilary_present) {
+         /* resolve so that auxilary buffers are not needed
+          * by any sampler */
+         resolve_to_disable_aux_on_samplers(brw);
+      }
+      brw_set_astc5x5_wa_mode(brw, BRW_ASTC5x5_WA_MODE_HAS_ASTC5x5);
+   } else if (brw->astc5x5_wa.texture_with_auxilary_present) {
+      brw_set_astc5x5_wa_mode(brw, BRW_ASTC5x5_WA_MODE_HAS_AUX);
+   }
+}
+
 GLboolean
 intelUnbindContext(__DRIcontext * driContextPriv)
 {
diff --git a/src/mesa/drivers/dri/i965/brw_context.h b/src/mesa/drivers/dri/i965/brw_context.h
index b3d7c6baf8..37dfe45592 100644
--- a/src/mesa/drivers/dri/i965/brw_context.h
+++ b/src/mesa/drivers/dri/i965/brw_context.h
@@ -165,6 +165,12 @@ enum brw_cache_id {
    BRW_MAX_CACHE
 };
 
+enum brw_astc5x5_wa_mode_t {
+   BRW_ASTC5x5_WA_MODE_NONE,
+   BRW_ASTC5x5_WA_MODE_HAS_ASTC5x5,
+   BRW_ASTC5x5_WA_MODE_HAS_AUX,
+};
+
 enum brw_state_id {
    /* brw_cache_ids must come first - see brw_program_cache.c */
    BRW_STATE_URB_FENCE = BRW_MAX_CACHE,
@@ -1230,6 +1236,18 @@ struct brw_context
     */
    bool draw_aux_buffer_disabled[MAX_DRAW_BUFFERS];
 
+   /* Certain GEN's have a hardware bug where the sampler hangs if it attempts
+    * to access auxilary buffers and an ASTC5x5 compressed buffer. The workaround
+    * is to invalidate the texture cache between such access.
+    */
+   struct {
+      bool required;
+      enum brw_astc5x5_wa_mode_t mode;
+      bool texture_astc5x5_present;
+      bool texture_with_auxilary_present;
+      bool blorp_sampling_from_astc5x5;
+   } astc5x5_wa;
+
    __DRIcontext *driContext;
    struct intel_screen *screen;
 };
@@ -1663,6 +1681,11 @@ void brw_query_internal_format(struct gl_context *ctx, GLenum target,
                                GLenum internalFormat, GLenum pname,
                                GLint *params);
 
+/* brw_context::astc5x5_wa */
+void brw_set_astc5x5_wa_mode(struct brw_context *brw,
+                             enum brw_astc5x5_wa_mode_t mode);
+void brw_astc5x5_perform_wa(struct brw_context *brw);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/src/mesa/drivers/dri/i965/intel_batchbuffer.c b/src/mesa/drivers/dri/i965/intel_batchbuffer.c
index 216073129b..042ed1fe62 100644
--- a/src/mesa/drivers/dri/i965/intel_batchbuffer.c
+++ b/src/mesa/drivers/dri/i965/intel_batchbuffer.c
@@ -618,6 +618,7 @@ brw_new_batch(struct brw_context *brw)
 
    /* Create a new batchbuffer and reset the associated state: */
    intel_batchbuffer_reset_and_clear_render_cache(brw);
+   brw->astc5x5_wa.mode = BRW_ASTC5x5_WA_MODE_NONE;
 
    /* If the kernel supports hardware contexts, then most hardware state is
     * preserved between batches; we only need to re-emit state that is required
-- 
2.14.2



More information about the mesa-dev mailing list