virgl: honor DISCARD_WHOLE_RESOURCE in virgl_res_needs_readback
[mesa.git] / src / gallium / drivers / iris / iris_query.c
index ec9050b6390caa241b646c4ee0009a1d62f4f927..6d9659080a7b182fed8652c95663b8d96a989278 100644 (file)
 #define MI_ALU_STORE     0x180
 #define MI_ALU_STOREINV  0x580
 
-#define MI_ALU_R0        0x00
-#define MI_ALU_R1        0x01
-#define MI_ALU_R2        0x02
-#define MI_ALU_R3        0x03
-#define MI_ALU_R4        0x04
 #define MI_ALU_SRCA      0x20
 #define MI_ALU_SRCB      0x21
 #define MI_ALU_ACCU      0x31
 #define MI_ALU_ZF        0x32
 #define MI_ALU_CF        0x33
 
-#define _MI_ALU(op, x, y)  (((op) << 20) | ((x) << 10) | (y))
-
-#define _MI_ALU0(op)       _MI_ALU(MI_ALU_##op, 0, 0)
-#define _MI_ALU1(op, x)    _MI_ALU(MI_ALU_##op, x, 0)
-#define _MI_ALU2(op, x, y) _MI_ALU(MI_ALU_##op, x, y)
-
-#define MI_ALU0(op)        _MI_ALU0(op)
-#define MI_ALU1(op, x)     _MI_ALU1(op, MI_ALU_##x)
-#define MI_ALU2(op, x, y)  _MI_ALU2(op, MI_ALU_##x, MI_ALU_##y)
-
 #define emit_lri32 ice->vtbl.load_register_imm32
 #define emit_lri64 ice->vtbl.load_register_imm64
 #define emit_lrr32 ice->vtbl.load_register_reg32
@@ -117,8 +102,8 @@ struct iris_query {
 };
 
 struct iris_query_snapshots {
-   /** iris_render_condition's saved MI_PREDICATE_DATA value. */
-   uint64_t predicate_data;
+   /** iris_render_condition's saved MI_PREDICATE_RESULT value. */
+   uint64_t predicate_result;
 
    /** Have the start/end snapshots landed? */
    uint64_t snapshots_landed;
@@ -129,7 +114,7 @@ struct iris_query_snapshots {
 };
 
 struct iris_query_so_overflow {
-   uint64_t predicate_data;
+   uint64_t predicate_result;
    uint64_t snapshots_landed;
 
    struct {
@@ -503,6 +488,15 @@ iris_math_div32_gpr0(struct iris_context *ice,
    }
 }
 
+void
+iris_math_add32_gpr0(struct iris_context *ice,
+                     struct iris_batch *batch,
+                     uint32_t x)
+{
+   emit_lri32(batch, CS_GPR(1), x);
+   emit_alu_add(batch, MI_ALU_R0, MI_ALU_R0, MI_ALU_R1);
+}
+
 /*
  * GPR0 = (GPR0 == 0) ? 0 : 1;
  */
@@ -1048,12 +1042,12 @@ set_predicate_for_result(struct iris_context *ice,
    /* We immediately set the predicate on the render batch, as all the
     * counters come from 3D operations.  However, we may need to predicate
     * a compute dispatch, which executes in a different GEM context and has
-    * a different MI_PREDICATE_DATA register.  So, we save the result to
+    * a different MI_PREDICATE_RESULT register.  So, we save the result to
     * memory and reload it in iris_launch_grid.
     */
    unsigned offset = q->query_state_ref.offset +
-                     offsetof(struct iris_query_snapshots, predicate_data);
-   ice->vtbl.store_register_mem64(batch, MI_PREDICATE_DATA,
+                     offsetof(struct iris_query_snapshots, predicate_result);
+   ice->vtbl.store_register_mem64(batch, MI_PREDICATE_RESULT,
                                   bo, offset, false);
    ice->state.compute_predicate = bo;
 }
@@ -1069,6 +1063,8 @@ iris_render_condition(struct pipe_context *ctx,
 
    /* The old condition isn't relevant; we'll update it if necessary */
    ice->state.compute_predicate = NULL;
+   ice->condition.query = q;
+   ice->condition.condition = condition;
 
    if (!q) {
       ice->state.predicate = IRIS_PREDICATE_STATE_RENDER;
@@ -1089,6 +1085,23 @@ iris_render_condition(struct pipe_context *ctx,
    }
 }
 
+void
+iris_resolve_conditional_render(struct iris_context *ice)
+{
+   struct pipe_context *ctx = (void *) ice;
+   struct iris_query *q = ice->condition.query;
+   struct pipe_query *query = (void *) q;
+   union pipe_query_result result;
+
+   if (ice->state.predicate != IRIS_PREDICATE_STATE_USE_BIT)
+      return;
+
+   assert(q);
+
+   iris_get_query_result(ctx, query, true, &result);
+   set_predicate_enable(ice, (q->result != 0) ^ ice->condition.condition);
+}
+
 void
 iris_init_query_functions(struct pipe_context *ctx)
 {