i965: add plumbing for ARB_transform_feedback_overflow_query.
authorRafael Antognolli <rafael.antognolli@intel.com>
Fri, 20 Jan 2017 17:53:24 +0000 (09:53 -0800)
committerKenneth Graunke <kenneth@whitecape.org>
Wed, 22 Feb 2017 00:28:32 +0000 (16:28 -0800)
When querying for transform feedback overflow on one or all of the
streams, store information about number of generated and written
primitives. Then check whether generated == written.

v2:
    - use only SO_PRIM_STORAGE_NEEDED, do not fallback to
      CL_INVOCATION_COUNT. (Kenneth)

Signed-off-by: Rafael Antognolli <rafael.antognolli@intel.com>
Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
src/mesa/drivers/dri/i965/brw_queryobj.c
src/mesa/drivers/dri/i965/gen6_queryobj.c

index dda17de7157a79013eedb29cc2774989cacdfd4f..40b86a0f64bc7842f08afa1ee207fc337c5fd12f 100644 (file)
@@ -530,6 +530,8 @@ brw_is_query_pipelined(struct brw_query_object *query)
 
    case GL_PRIMITIVES_GENERATED:
    case GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN:
 
    case GL_PRIMITIVES_GENERATED:
    case GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN:
+   case GL_TRANSFORM_FEEDBACK_STREAM_OVERFLOW_ARB:
+   case GL_TRANSFORM_FEEDBACK_OVERFLOW_ARB:
    case GL_VERTICES_SUBMITTED_ARB:
    case GL_PRIMITIVES_SUBMITTED_ARB:
    case GL_VERTEX_SHADER_INVOCATIONS_ARB:
    case GL_VERTICES_SUBMITTED_ARB:
    case GL_PRIMITIVES_SUBMITTED_ARB:
    case GL_VERTEX_SHADER_INVOCATIONS_ARB:
index bbd3c44fb0f89d0430147fa9f14d08c3342a5810..98cbbff91401fd07c16168dccea75befa218de1f 100644 (file)
@@ -98,6 +98,54 @@ write_xfb_primitives_written(struct brw_context *brw,
    }
 }
 
    }
 }
 
+static void
+write_xfb_overflow_streams(struct gl_context *ctx,
+                           drm_intel_bo *bo, int stream, int count,
+                           int idx)
+{
+   struct brw_context *brw = brw_context(ctx);
+
+   brw_emit_mi_flush(brw);
+
+   for (int i = 0; i < count; i++) {
+      int w_idx = 4 * i + idx;
+      int g_idx = 4 * i + idx + 2;
+
+      if (brw->gen >= 7) {
+         brw_store_register_mem64(brw, bo,
+                                  GEN7_SO_NUM_PRIMS_WRITTEN(stream + i),
+                                  g_idx * sizeof(uint64_t));
+         brw_store_register_mem64(brw, bo,
+                                  GEN7_SO_PRIM_STORAGE_NEEDED(stream + i),
+                                  w_idx * sizeof(uint64_t));
+      } else {
+         brw_store_register_mem64(brw, bo,
+                                  GEN6_SO_NUM_PRIMS_WRITTEN,
+                                  g_idx * sizeof(uint64_t));
+         brw_store_register_mem64(brw, bo,
+                                  GEN6_SO_PRIM_STORAGE_NEEDED,
+                                  w_idx * sizeof(uint64_t));
+      }
+   }
+}
+
+static bool
+check_xfb_overflow_streams(uint64_t *results, int count)
+{
+   bool overflow = false;
+
+   for (int i = 0; i < count; i++) {
+      uint64_t *result_i = &results[4 * i];
+
+      if ((result_i[3] - result_i[2]) != (result_i[1] - result_i[0])) {
+         overflow = true;
+         break;
+      }
+   }
+
+   return overflow;
+}
+
 static inline int
 pipeline_target_to_index(int target)
 {
 static inline int
 pipeline_target_to_index(int target)
 {
@@ -225,6 +273,14 @@ gen6_queryobj_get_results(struct gl_context *ctx,
       query->Base.Result = results[1] - results[0];
       break;
 
       query->Base.Result = results[1] - results[0];
       break;
 
+   case GL_TRANSFORM_FEEDBACK_STREAM_OVERFLOW_ARB:
+      query->Base.Result = check_xfb_overflow_streams(results, 1);
+      break;
+
+   case GL_TRANSFORM_FEEDBACK_OVERFLOW_ARB:
+      query->Base.Result = check_xfb_overflow_streams(results, MAX_VERTEX_STREAMS);
+      break;
+
    case GL_FRAGMENT_SHADER_INVOCATIONS_ARB:
       query->Base.Result = (results[1] - results[0]);
       /* Implement the "WaDividePSInvocationCountBy4:HSW,BDW" workaround:
    case GL_FRAGMENT_SHADER_INVOCATIONS_ARB:
       query->Base.Result = (results[1] - results[0]);
       /* Implement the "WaDividePSInvocationCountBy4:HSW,BDW" workaround:
@@ -314,6 +370,14 @@ gen6_begin_query(struct gl_context *ctx, struct gl_query_object *q)
       write_xfb_primitives_written(brw, query->bo, query->Base.Stream, 0);
       break;
 
       write_xfb_primitives_written(brw, query->bo, query->Base.Stream, 0);
       break;
 
+   case GL_TRANSFORM_FEEDBACK_STREAM_OVERFLOW_ARB:
+      write_xfb_overflow_streams(ctx, query->bo, query->Base.Stream, 1, 0);
+      break;
+
+   case GL_TRANSFORM_FEEDBACK_OVERFLOW_ARB:
+      write_xfb_overflow_streams(ctx, query->bo, 0, MAX_VERTEX_STREAMS, 0);
+      break;
+
    case GL_VERTICES_SUBMITTED_ARB:
    case GL_PRIMITIVES_SUBMITTED_ARB:
    case GL_VERTEX_SHADER_INVOCATIONS_ARB:
    case GL_VERTICES_SUBMITTED_ARB:
    case GL_PRIMITIVES_SUBMITTED_ARB:
    case GL_VERTEX_SHADER_INVOCATIONS_ARB:
@@ -368,6 +432,15 @@ gen6_end_query(struct gl_context *ctx, struct gl_query_object *q)
       write_xfb_primitives_written(brw, query->bo, query->Base.Stream, 1);
       break;
 
       write_xfb_primitives_written(brw, query->bo, query->Base.Stream, 1);
       break;
 
+   case GL_TRANSFORM_FEEDBACK_STREAM_OVERFLOW_ARB:
+      write_xfb_overflow_streams(ctx, query->bo, query->Base.Stream, 1, 1);
+      break;
+
+   case GL_TRANSFORM_FEEDBACK_OVERFLOW_ARB:
+      write_xfb_overflow_streams(ctx, query->bo, 0, MAX_VERTEX_STREAMS, 1);
+      break;
+
+      /* calculate overflow here */
    case GL_VERTICES_SUBMITTED_ARB:
    case GL_PRIMITIVES_SUBMITTED_ARB:
    case GL_VERTEX_SHADER_INVOCATIONS_ARB:
    case GL_VERTICES_SUBMITTED_ARB:
    case GL_PRIMITIVES_SUBMITTED_ARB:
    case GL_VERTEX_SHADER_INVOCATIONS_ARB: