}
}
+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)
{
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:
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:
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: