static struct pipe_query *
nv50_query_create(struct pipe_context *pipe, unsigned type, unsigned index)
{
   struct nv50_context *nv50 = nv50_context(pipe);
   struct nv50_query *q;

   q = CALLOC_STRUCT(nv50_query);
   if (!q)
      return NULL;

   if (!nv50_query_allocate(nv50, q, NV50_QUERY_ALLOC_SPACE)) {
      FREE(q);
      return NULL;
   }

   q->is64bit = (type == PIPE_QUERY_PRIMITIVES_GENERATED ||
                 type == PIPE_QUERY_PRIMITIVES_EMITTED ||
                 type == PIPE_QUERY_SO_STATISTICS);
   q->type = type;

   if (q->type == PIPE_QUERY_OCCLUSION_COUNTER) {
      q->offset -= 32;
      q->data -= 32 / sizeof(*q->data); /* we advance before query_begin ! */
   }

   return (struct pipe_query *)q;
}
static boolean
nv50_query_allocate(struct nv50_context *nv50, struct nv50_query *q, int size)
{
   struct nv50_screen *screen = nv50->screen;
   int ret;

   if (q->bo) {
      nouveau_bo_ref(NULL, &q->bo);
      if (q->mm) {
         if (q->ready)
            nouveau_mm_free(q->mm);
         else
            nouveau_fence_work(screen->base.fence.current, nouveau_mm_free_work,
                               q->mm);
      }
   }
   if (size) {
      q->mm = nouveau_mm_allocate(screen->base.mm_GART, size, &q->bo, &q->base);
      if (!q->bo)
         return FALSE;
      q->offset = q->base;

      ret = nouveau_bo_map(q->bo, 0, screen->base.client);
      if (ret) {
         nv50_query_allocate(nv50, q, 0);
         return FALSE;
      }
      q->data = (uint32_t *)((uint8_t *)q->bo->map + q->base);
   }
   return TRUE;
}
예제 #3
0
파일: nv50_query.c 프로젝트: krnowak/mesa
static void
nv50_query_destroy(struct pipe_context *pipe, struct pipe_query *pq)
{
   nv50_query_allocate(nv50_context(pipe), nv50_query(pq), 0);
   nouveau_fence_ref(NULL, &nv50_query(pq)->fence);
   FREE(nv50_query(pq));
}
예제 #4
0
파일: nv50_query.c 프로젝트: curro/mesa
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[1] = 1; /* initial render condition = TRUE */
   }
   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: /* store before & after instead ? */
      PUSH_SPACE(push, 2);
      BEGIN_NV04(push, NV50_3D(COUNTER_RESET), 1);
      PUSH_DATA (push, NV50_3D_COUNTER_RESET_GENERATED_PRIMITIVES);
      break;
   case PIPE_QUERY_PRIMITIVES_EMITTED:
      PUSH_SPACE(push, 2);
      BEGIN_NV04(push, NV50_3D(COUNTER_RESET), 1);
      PUSH_DATA (push, NV50_3D_COUNTER_RESET_TRANSFORM_FEEDBACK);
      break;
   case PIPE_QUERY_SO_STATISTICS:
      PUSH_SPACE(push, 3);
      BEGIN_NI04(push, NV50_3D(COUNTER_RESET), 2);
      PUSH_DATA (push, NV50_3D_COUNTER_RESET_TRANSFORM_FEEDBACK);
      PUSH_DATA (push, NV50_3D_COUNTER_RESET_GENERATED_PRIMITIVES);
      break;
   case PIPE_QUERY_TIMESTAMP_DISJOINT:
   case PIPE_QUERY_TIME_ELAPSED:
      nv50_query_get(push, q, 0x10, 0x00005002);
      break;
   default:
      break;
   }
   q->ready = FALSE;
}
static void
nv50_query_destroy(struct pipe_context *pipe, struct pipe_query *pq)
{
   nv50_query_allocate(nv50_context(pipe), nv50_query(pq), 0);
   FREE(nv50_query(pq));
}
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:
      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->ready = FALSE;
   return true;
}