static void
nv50_query_begin(struct pipe_context *pipe, struct pipe_query *pq)
{
   struct nv50_context *nv50 = nv50_context(pipe);
   struct nouveau_pushbuf *push = nv50->base.pushbuf;
   struct nv50_query *q = nv50_query(pq);

   /* For occlusion queries we have to change the storage, because a previous
    * query might set the initial render conition to FALSE even *after* we re-
    * initialized it to TRUE.
    */
   if (q->type == PIPE_QUERY_OCCLUSION_COUNTER) {
      q->offset += 16;
      q->data += 16 / sizeof(*q->data);
      if (q->offset - q->base == NV50_QUERY_ALLOC_SPACE)
         nv50_query_allocate(nv50, q, NV50_QUERY_ALLOC_SPACE);

      /* XXX: can we do this with the GPU, and sync with respect to a previous
       *  query ?
       */
      q->data[0] = q->sequence; /* initialize sequence */
      q->data[1] = 1; /* initial render condition = TRUE */
      q->data[4] = q->sequence + 1; /* for comparison COND_MODE */
      q->data[5] = 0;
   }
   if (!q->is64bit)
      q->data[0] = q->sequence++; /* the previously used one */

   switch (q->type) {
   case PIPE_QUERY_OCCLUSION_COUNTER:
      PUSH_SPACE(push, 4);
      BEGIN_NV04(push, NV50_3D(COUNTER_RESET), 1);
      PUSH_DATA (push, NV50_3D_COUNTER_RESET_SAMPLECNT);
      BEGIN_NV04(push, NV50_3D(SAMPLECNT_ENABLE), 1);
      PUSH_DATA (push, 1);
      break;
   case PIPE_QUERY_PRIMITIVES_GENERATED:
      nv50_query_get(push, q, 0x10, 0x06805002);
      break;
   case PIPE_QUERY_PRIMITIVES_EMITTED:
      nv50_query_get(push, q, 0x10, 0x05805002);
      break;
   case PIPE_QUERY_SO_STATISTICS:
      nv50_query_get(push, q, 0x20, 0x05805002);
      nv50_query_get(push, q, 0x30, 0x06805002);
      break;
   case PIPE_QUERY_TIME_ELAPSED:
      nv50_query_get(push, q, 0x10, 0x00005002);
      break;
   default:
      break;
   }
   q->ready = FALSE;
}
Example #2
0
static void
nv50_query_end(struct pipe_context *pipe, struct pipe_query *pq)
{
    struct nv50_context *nv50 = nv50_context(pipe);
    struct nouveau_pushbuf *push = nv50->base.pushbuf;
    struct nv50_query *q = nv50_query(pq);

    switch (q->type) {
    case PIPE_QUERY_OCCLUSION_COUNTER:
        nv50_query_get(push, q, 0, 0x0100f002);
        PUSH_SPACE(push, 2);
        BEGIN_NV04(push, NV50_3D(SAMPLECNT_ENABLE), 1);
        PUSH_DATA (push, 0);
        break;
    case PIPE_QUERY_PRIMITIVES_GENERATED:
        nv50_query_get(push, q, 0, 0x06805002);
        break;
    case PIPE_QUERY_PRIMITIVES_EMITTED:
        nv50_query_get(push, q, 0, 0x05805002);
        break;
    case PIPE_QUERY_SO_STATISTICS:
        nv50_query_get(push, q, 0x00, 0x05805002);
        nv50_query_get(push, q, 0x10, 0x06805002);
        break;
    case PIPE_QUERY_TIMESTAMP:
        q->sequence++;
    /* fall through */
    case PIPE_QUERY_TIME_ELAPSED:
        nv50_query_get(push, q, 0, 0x00005002);
        break;
    case PIPE_QUERY_GPU_FINISHED:
        q->sequence++;
        nv50_query_get(push, q, 0, 0x1000f010);
        break;
    case NVA0_QUERY_STREAM_OUTPUT_BUFFER_OFFSET:
        nv50_query_get(push, q, 0, 0x0d005002 | (q->index << 5));
        break;
    case PIPE_QUERY_TIMESTAMP_DISJOINT:
        break;
    default:
        assert(0);
        break;
    }
    q->ready = q->flushed = FALSE;
}
static void
nv50_query_end(struct pipe_context *pipe, struct pipe_query *pq)
{
   struct nv50_context *nv50 = nv50_context(pipe);
   struct nouveau_pushbuf *push = nv50->base.pushbuf;
   struct nv50_query *q = nv50_query(pq);

   switch (q->type) {
   case PIPE_QUERY_OCCLUSION_COUNTER:
      nv50_query_get(push, q, 0, 0x0100f002);
      PUSH_SPACE(push, 2);
      BEGIN_NV04(push, NV50_3D(SAMPLECNT_ENABLE), 1);
      PUSH_DATA (push, 0);
      break;
   case PIPE_QUERY_PRIMITIVES_GENERATED:
      nv50_query_get(push, q, 0, 0x06805002);
      break;
   case PIPE_QUERY_PRIMITIVES_EMITTED:
      nv50_query_get(push, q, 0, 0x05805002);
      break;
   case PIPE_QUERY_SO_STATISTICS:
      nv50_query_get(push, q, 0x00, 0x05805002);
      nv50_query_get(push, q, 0x10, 0x06805002);
      break;
   case PIPE_QUERY_PIPELINE_STATISTICS:
      nv50_query_get(push, q, 0x00, 0x00801002); /* VFETCH, VERTICES */
      nv50_query_get(push, q, 0x10, 0x01801002); /* VFETCH, PRIMS */
      nv50_query_get(push, q, 0x20, 0x02802002); /* VP, LAUNCHES */
      nv50_query_get(push, q, 0x30, 0x03806002); /* GP, LAUNCHES */
      nv50_query_get(push, q, 0x40, 0x04806002); /* GP, PRIMS_OUT */
      nv50_query_get(push, q, 0x50, 0x07804002); /* RAST, PRIMS_IN */
      nv50_query_get(push, q, 0x60, 0x08804002); /* RAST, PRIMS_OUT */
      nv50_query_get(push, q, 0x70, 0x0980a002); /* ROP, PIXELS */
      break;
   case PIPE_QUERY_TIMESTAMP:
      q->sequence++;
      /* fall through */
   case PIPE_QUERY_TIME_ELAPSED:
      nv50_query_get(push, q, 0, 0x00005002);
      break;
   case PIPE_QUERY_GPU_FINISHED:
      q->sequence++;
      nv50_query_get(push, q, 0, 0x1000f010);
      break;
   case NVA0_QUERY_STREAM_OUTPUT_BUFFER_OFFSET:
      nv50_query_get(push, q, 0, 0x0d005002 | (q->index << 5));
      break;
   case PIPE_QUERY_TIMESTAMP_DISJOINT:
      /* This query is not issued on GPU because disjoint is forced to FALSE */
      q->ready = TRUE;
      break;
   default:
      assert(0);
      break;
   }
   q->ready = q->flushed = FALSE;
}
Example #4
0
static boolean
nv50_query_begin(struct pipe_context *pipe, struct pipe_query *pq)
{
   struct nv50_context *nv50 = nv50_context(pipe);
   struct nouveau_pushbuf *push = nv50->base.pushbuf;
   struct nv50_query *q = nv50_query(pq);

   /* For occlusion queries we have to change the storage, because a previous
    * query might set the initial render conition to false even *after* we re-
    * initialized it to true.
    */
   if (q->type == PIPE_QUERY_OCCLUSION_COUNTER) {
      q->offset += 32;
      q->data += 32 / sizeof(*q->data);
      if (q->offset - q->base == NV50_QUERY_ALLOC_SPACE)
         nv50_query_allocate(nv50, q, NV50_QUERY_ALLOC_SPACE);

      /* XXX: can we do this with the GPU, and sync with respect to a previous
       *  query ?
       */
      q->data[0] = q->sequence; /* initialize sequence */
      q->data[1] = 1; /* initial render condition = true */
      q->data[4] = q->sequence + 1; /* for comparison COND_MODE */
      q->data[5] = 0;
   }
   if (!q->is64bit)
      q->data[0] = q->sequence++; /* the previously used one */

   switch (q->type) {
   case PIPE_QUERY_OCCLUSION_COUNTER:
      q->nesting = nv50->screen->num_occlusion_queries_active++;
      if (q->nesting) {
         nv50_query_get(push, q, 0x10, 0x0100f002);
      } else {
         PUSH_SPACE(push, 4);
         BEGIN_NV04(push, NV50_3D(COUNTER_RESET), 1);
         PUSH_DATA (push, NV50_3D_COUNTER_RESET_SAMPLECNT);
         BEGIN_NV04(push, NV50_3D(SAMPLECNT_ENABLE), 1);
         PUSH_DATA (push, 1);
      }
      break;
   case PIPE_QUERY_PRIMITIVES_GENERATED:
      nv50_query_get(push, q, 0x10, 0x06805002);
      break;
   case PIPE_QUERY_PRIMITIVES_EMITTED:
      nv50_query_get(push, q, 0x10, 0x05805002);
      break;
   case PIPE_QUERY_SO_STATISTICS:
      nv50_query_get(push, q, 0x20, 0x05805002);
      nv50_query_get(push, q, 0x30, 0x06805002);
      break;
   case PIPE_QUERY_PIPELINE_STATISTICS:
      nv50_query_get(push, q, 0x80, 0x00801002); /* VFETCH, VERTICES */
      nv50_query_get(push, q, 0x90, 0x01801002); /* VFETCH, PRIMS */
      nv50_query_get(push, q, 0xa0, 0x02802002); /* VP, LAUNCHES */
      nv50_query_get(push, q, 0xb0, 0x03806002); /* GP, LAUNCHES */
      nv50_query_get(push, q, 0xc0, 0x04806002); /* GP, PRIMS_OUT */
      nv50_query_get(push, q, 0xd0, 0x07804002); /* RAST, PRIMS_IN */
      nv50_query_get(push, q, 0xe0, 0x08804002); /* RAST, PRIMS_OUT */
      nv50_query_get(push, q, 0xf0, 0x0980a002); /* ROP, PIXELS */
      break;
   case PIPE_QUERY_TIME_ELAPSED:
      nv50_query_get(push, q, 0x10, 0x00005002);
      break;
   default:
      break;
   }
   q->state = NV50_QUERY_STATE_ACTIVE;
   return true;
}