- if (intel->gen >= 6) {
- BEGIN_BATCH(8);
- /* workaround: CS stall required before depth stall. */
- OUT_BATCH(_3DSTATE_PIPE_CONTROL);
- OUT_BATCH(PIPE_CONTROL_CS_STALL);
- OUT_BATCH(0); /* write address */
- OUT_BATCH(0); /* write data */
-
- OUT_BATCH(_3DSTATE_PIPE_CONTROL);
- OUT_BATCH(PIPE_CONTROL_DEPTH_STALL |
- PIPE_CONTROL_WRITE_DEPTH_COUNT);
- OUT_RELOC(brw->query.bo,
- I915_GEM_DOMAIN_INSTRUCTION, I915_GEM_DOMAIN_INSTRUCTION,
- PIPE_CONTROL_GLOBAL_GTT_WRITE |
- ((brw->query.index * 2 + 1) * sizeof(uint64_t)));
- OUT_BATCH(0);
- ADVANCE_BATCH();
-
- } else {
- BEGIN_BATCH(4);
- OUT_BATCH(_3DSTATE_PIPE_CONTROL |
- PIPE_CONTROL_DEPTH_STALL |
- PIPE_CONTROL_WRITE_DEPTH_COUNT);
- OUT_RELOC(brw->query.bo,
- I915_GEM_DOMAIN_INSTRUCTION, I915_GEM_DOMAIN_INSTRUCTION,
- PIPE_CONTROL_GLOBAL_GTT_WRITE |
- ((brw->query.index * 2 + 1) * sizeof(uint64_t)));
- OUT_BATCH(0);
- OUT_BATCH(0);
- ADVANCE_BATCH();
+ brw_write_depth_count(brw, query->bo, query->last_index * 2 + 1);
+
+ brw->query.begin_emitted = false;
+ query->last_index++;
+}
+
+/**
+ * Driver hook for glQueryCounter().
+ *
+ * This handles GL_TIMESTAMP queries, which perform a pipelined read of the
+ * current GPU time. This is unlike GL_TIME_ELAPSED, which measures the
+ * time while the query is active.
+ */
+void
+brw_query_counter(struct gl_context *ctx, struct gl_query_object *q)
+{
+ struct brw_context *brw = brw_context(ctx);
+ struct brw_query_object *query = (struct brw_query_object *) q;
+
+ assert(q->Target == GL_TIMESTAMP);
+
+ drm_intel_bo_unreference(query->bo);
+ query->bo = drm_intel_bo_alloc(brw->bufmgr, "timestamp query", 4096, 4096);
+ brw_write_timestamp(brw, query->bo, 0);
+
+ query->flushed = false;
+}
+
+/**
+ * Read the TIMESTAMP register immediately (in a non-pipelined fashion).
+ *
+ * This is used to implement the GetTimestamp() driver hook.
+ */
+static uint64_t
+brw_get_timestamp(struct gl_context *ctx)
+{
+ struct brw_context *brw = brw_context(ctx);
+ uint64_t result = 0;
+
+ switch (brw->intelScreen->hw_has_timestamp) {
+ case 3: /* New kernel, always full 36bit accuracy */
+ drm_intel_reg_read(brw->bufmgr, TIMESTAMP | 1, &result);
+ break;
+ case 2: /* 64bit kernel, result is left-shifted by 32bits, losing 4bits */
+ drm_intel_reg_read(brw->bufmgr, TIMESTAMP, &result);
+ result = result >> 32;
+ break;
+ case 1: /* 32bit kernel, result is 36bit wide but may be inaccurate! */
+ drm_intel_reg_read(brw->bufmgr, TIMESTAMP, &result);
+ break;