15f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset/*
25f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset * Copyright 2011 Christoph Bumiller
35f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset * Copyright 2015 Samuel Pitoiset
45f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset *
55f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset * Permission is hereby granted, free of charge, to any person obtaining a
65f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset * copy of this software and associated documentation files (the "Software"),
75f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset * to deal in the Software without restriction, including without limitation
85f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset * the rights to use, copy, modify, merge, publish, distribute, sublicense,
95f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset * and/or sell copies of the Software, and to permit persons to whom the
105f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset * Software is furnished to do so, subject to the following conditions:
115f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset *
125f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset * The above copyright notice and this permission notice shall be included in
135f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset * all copies or substantial portions of the Software.
145f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset *
155f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
165f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
175f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
185f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
195f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
205f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
215f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset * OTHER DEALINGS IN THE SOFTWARE.
225f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset */
235f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset
245f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset#define NV50_PUSH_EXPLICIT_SPACE_CHECKING
255f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset
265f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset#include "nv50/nv50_context.h"
275f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset#include "nv50/nv50_query_hw.h"
28848fa3101d5077b1aecfb0886c69a7d0dd7f75bcSamuel Pitoiset#include "nv50/nv50_query_hw_metric.h"
296a9c151dbb87a10b6d51c451a5a277d646d08857Samuel Pitoiset#include "nv50/nv50_query_hw_sm.h"
305f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset#include "nv_object.xml.h"
315f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset
325f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset#define NV50_HW_QUERY_STATE_READY   0
335f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset#define NV50_HW_QUERY_STATE_ACTIVE  1
345f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset#define NV50_HW_QUERY_STATE_ENDED   2
355f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset#define NV50_HW_QUERY_STATE_FLUSHED 3
365f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset
375f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset/* XXX: Nested queries, and simultaneous queries on multiple gallium contexts
385f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset * (since we use only a single GPU channel per screen) will not work properly.
395f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset *
405f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset * The first is not that big of an issue because OpenGL does not allow nested
415f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset * queries anyway.
425f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset */
435f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset
445f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset#define NV50_HW_QUERY_ALLOC_SPACE 256
455f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset
466a9c151dbb87a10b6d51c451a5a277d646d08857Samuel Pitoisetbool
475f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoisetnv50_hw_query_allocate(struct nv50_context *nv50, struct nv50_query *q,
485f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset                       int size)
495f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset{
505f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset   struct nv50_screen *screen = nv50->screen;
515f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset   struct nv50_hw_query *hq = nv50_hw_query(q);
525f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset   int ret;
535f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset
545f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset   if (hq->bo) {
555f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset      nouveau_bo_ref(NULL, &hq->bo);
565f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset      if (hq->mm) {
575f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset         if (hq->state == NV50_HW_QUERY_STATE_READY)
585f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset            nouveau_mm_free(hq->mm);
595f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset         else
605f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset            nouveau_fence_work(screen->base.fence.current,
615f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset                               nouveau_mm_free_work, hq->mm);
625f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset      }
635f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset   }
645f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset   if (size) {
655f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset      hq->mm = nouveau_mm_allocate(screen->base.mm_GART, size,
665f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset                                   &hq->bo, &hq->base_offset);
675f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset      if (!hq->bo)
685f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset         return false;
695f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset      hq->offset = hq->base_offset;
705f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset
715f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset      ret = nouveau_bo_map(hq->bo, 0, screen->base.client);
725f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset      if (ret) {
735f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset         nv50_hw_query_allocate(nv50, q, 0);
745f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset         return false;
755f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset      }
765f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset      hq->data = (uint32_t *)((uint8_t *)hq->bo->map + hq->base_offset);
775f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset   }
785f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset   return true;
795f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset}
805f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset
815f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoisetstatic void
825f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoisetnv50_hw_query_get(struct nouveau_pushbuf *push, struct nv50_query *q,
835f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset               unsigned offset, uint32_t get)
845f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset{
855f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset   struct nv50_hw_query *hq = nv50_hw_query(q);
865f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset
875f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset   offset += hq->offset;
885f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset
895f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset   PUSH_SPACE(push, 5);
905f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset   PUSH_REFN (push, hq->bo, NOUVEAU_BO_GART | NOUVEAU_BO_WR);
915f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset   BEGIN_NV04(push, NV50_3D(QUERY_ADDRESS_HIGH), 4);
925f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset   PUSH_DATAh(push, hq->bo->offset + offset);
935f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset   PUSH_DATA (push, hq->bo->offset + offset);
945f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset   PUSH_DATA (push, hq->sequence);
955f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset   PUSH_DATA (push, get);
965f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset}
975f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset
985f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoisetstatic inline void
995f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoisetnv50_hw_query_update(struct nv50_query *q)
1005f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset{
1015f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset   struct nv50_hw_query *hq = nv50_hw_query(q);
1025f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset
1035f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset   if (hq->is64bit) {
1045f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset      if (nouveau_fence_signalled(hq->fence))
1055f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset         hq->state = NV50_HW_QUERY_STATE_READY;
1065f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset   } else {
1075f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset      if (hq->data[0] == hq->sequence)
1085f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset         hq->state = NV50_HW_QUERY_STATE_READY;
1095f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset   }
1105f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset}
1115f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset
1125f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoisetstatic void
1135f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoisetnv50_hw_destroy_query(struct nv50_context *nv50, struct nv50_query *q)
1145f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset{
1155f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset   struct nv50_hw_query *hq = nv50_hw_query(q);
116aeee7f2a4dc7ceddace91ef5e91790483f4597e0Samuel Pitoiset
117aeee7f2a4dc7ceddace91ef5e91790483f4597e0Samuel Pitoiset   if (hq->funcs && hq->funcs->destroy_query) {
118aeee7f2a4dc7ceddace91ef5e91790483f4597e0Samuel Pitoiset      hq->funcs->destroy_query(nv50, hq);
119aeee7f2a4dc7ceddace91ef5e91790483f4597e0Samuel Pitoiset      return;
120aeee7f2a4dc7ceddace91ef5e91790483f4597e0Samuel Pitoiset   }
121aeee7f2a4dc7ceddace91ef5e91790483f4597e0Samuel Pitoiset
1225f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset   nv50_hw_query_allocate(nv50, q, 0);
1235f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset   nouveau_fence_ref(NULL, &hq->fence);
1245f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset   FREE(hq);
1255f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset}
1265f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset
1275f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoisetstatic boolean
1285f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoisetnv50_hw_begin_query(struct nv50_context *nv50, struct nv50_query *q)
1295f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset{
1305f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset   struct nouveau_pushbuf *push = nv50->base.pushbuf;
1315f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset   struct nv50_hw_query *hq = nv50_hw_query(q);
1325f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset
1336a9c151dbb87a10b6d51c451a5a277d646d08857Samuel Pitoiset   if (hq->funcs && hq->funcs->begin_query)
1346a9c151dbb87a10b6d51c451a5a277d646d08857Samuel Pitoiset      return hq->funcs->begin_query(nv50, hq);
1356a9c151dbb87a10b6d51c451a5a277d646d08857Samuel Pitoiset
1365f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset   /* For occlusion queries we have to change the storage, because a previous
1375f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset    * query might set the initial render condition to false even *after* we re-
1385f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset    * initialized it to true.
1395f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset    */
1400d0329df8fc95754a8edd76d1da0b32e2aaf83dfSamuel Pitoiset   if (hq->rotate) {
1410d0329df8fc95754a8edd76d1da0b32e2aaf83dfSamuel Pitoiset      hq->offset += hq->rotate;
1420d0329df8fc95754a8edd76d1da0b32e2aaf83dfSamuel Pitoiset      hq->data += hq->rotate / sizeof(*hq->data);
1435f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset      if (hq->offset - hq->base_offset == NV50_HW_QUERY_ALLOC_SPACE)
1445f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset         nv50_hw_query_allocate(nv50, q, NV50_HW_QUERY_ALLOC_SPACE);
1455f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset
1465f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset      /* XXX: can we do this with the GPU, and sync with respect to a previous
1475f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset       *  query ?
1485f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset       */
1495f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset      hq->data[0] = hq->sequence; /* initialize sequence */
1505f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset      hq->data[1] = 1; /* initial render condition = true */
1515f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset      hq->data[4] = hq->sequence + 1; /* for comparison COND_MODE */
1525f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset      hq->data[5] = 0;
1535f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset   }
1545f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset   if (!hq->is64bit)
1555f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset      hq->data[0] = hq->sequence++; /* the previously used one */
1565f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset
1575f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset   switch (q->type) {
1585f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset   case PIPE_QUERY_OCCLUSION_COUNTER:
15950235ab3ab9f22565aed596e5a915831d099314dIlia Mirkin   case PIPE_QUERY_OCCLUSION_PREDICATE:
1605f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset      hq->nesting = nv50->screen->num_occlusion_queries_active++;
1615f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset      if (hq->nesting) {
1625f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset         nv50_hw_query_get(push, q, 0x10, 0x0100f002);
1635f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset      } else {
1645f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset         PUSH_SPACE(push, 4);
1655f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset         BEGIN_NV04(push, NV50_3D(COUNTER_RESET), 1);
1665f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset         PUSH_DATA (push, NV50_3D_COUNTER_RESET_SAMPLECNT);
1675f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset         BEGIN_NV04(push, NV50_3D(SAMPLECNT_ENABLE), 1);
1685f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset         PUSH_DATA (push, 1);
1695f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset      }
1705f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset      break;
1715f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset   case PIPE_QUERY_PRIMITIVES_GENERATED:
1725f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset      nv50_hw_query_get(push, q, 0x10, 0x06805002);
1735f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset      break;
1745f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset   case PIPE_QUERY_PRIMITIVES_EMITTED:
1755f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset      nv50_hw_query_get(push, q, 0x10, 0x05805002);
1765f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset      break;
1775f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset   case PIPE_QUERY_SO_STATISTICS:
1785f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset      nv50_hw_query_get(push, q, 0x20, 0x05805002);
1795f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset      nv50_hw_query_get(push, q, 0x30, 0x06805002);
1805f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset      break;
1815f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset   case PIPE_QUERY_PIPELINE_STATISTICS:
1825f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset      nv50_hw_query_get(push, q, 0x80, 0x00801002); /* VFETCH, VERTICES */
1835f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset      nv50_hw_query_get(push, q, 0x90, 0x01801002); /* VFETCH, PRIMS */
1845f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset      nv50_hw_query_get(push, q, 0xa0, 0x02802002); /* VP, LAUNCHES */
1855f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset      nv50_hw_query_get(push, q, 0xb0, 0x03806002); /* GP, LAUNCHES */
1865f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset      nv50_hw_query_get(push, q, 0xc0, 0x04806002); /* GP, PRIMS_OUT */
1875f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset      nv50_hw_query_get(push, q, 0xd0, 0x07804002); /* RAST, PRIMS_IN */
1885f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset      nv50_hw_query_get(push, q, 0xe0, 0x08804002); /* RAST, PRIMS_OUT */
1895f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset      nv50_hw_query_get(push, q, 0xf0, 0x0980a002); /* ROP, PIXELS */
1905f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset      break;
1915f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset   case PIPE_QUERY_TIME_ELAPSED:
1925f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset      nv50_hw_query_get(push, q, 0x10, 0x00005002);
1935f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset      break;
1945f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset   default:
1955f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset      assert(0);
1965f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset      return false;
1975f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset   }
1985f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset   hq->state = NV50_HW_QUERY_STATE_ACTIVE;
1995f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset   return true;
2005f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset}
2015f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset
2025f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoisetstatic void
2035f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoisetnv50_hw_end_query(struct nv50_context *nv50, struct nv50_query *q)
2045f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset{
2055f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset   struct nouveau_pushbuf *push = nv50->base.pushbuf;
2065f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset   struct nv50_hw_query *hq = nv50_hw_query(q);
2075f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset
2086a9c151dbb87a10b6d51c451a5a277d646d08857Samuel Pitoiset   if (hq->funcs && hq->funcs->end_query) {
2096a9c151dbb87a10b6d51c451a5a277d646d08857Samuel Pitoiset      hq->funcs->end_query(nv50, hq);
2106a9c151dbb87a10b6d51c451a5a277d646d08857Samuel Pitoiset      return;
2116a9c151dbb87a10b6d51c451a5a277d646d08857Samuel Pitoiset   }
2126a9c151dbb87a10b6d51c451a5a277d646d08857Samuel Pitoiset
2135f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset   hq->state = NV50_HW_QUERY_STATE_ENDED;
2145f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset
2155f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset   switch (q->type) {
2165f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset   case PIPE_QUERY_OCCLUSION_COUNTER:
21750235ab3ab9f22565aed596e5a915831d099314dIlia Mirkin   case PIPE_QUERY_OCCLUSION_PREDICATE:
2185f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset      nv50_hw_query_get(push, q, 0, 0x0100f002);
2195f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset      if (--nv50->screen->num_occlusion_queries_active == 0) {
2205f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset         PUSH_SPACE(push, 2);
2215f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset         BEGIN_NV04(push, NV50_3D(SAMPLECNT_ENABLE), 1);
2225f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset         PUSH_DATA (push, 0);
2235f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset      }
2245f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset      break;
2255f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset   case PIPE_QUERY_PRIMITIVES_GENERATED:
2265f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset      nv50_hw_query_get(push, q, 0, 0x06805002);
2275f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset      break;
2285f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset   case PIPE_QUERY_PRIMITIVES_EMITTED:
2295f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset      nv50_hw_query_get(push, q, 0, 0x05805002);
2305f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset      break;
2315f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset   case PIPE_QUERY_SO_STATISTICS:
2325f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset      nv50_hw_query_get(push, q, 0x00, 0x05805002);
2335f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset      nv50_hw_query_get(push, q, 0x10, 0x06805002);
2345f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset      break;
2355f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset   case PIPE_QUERY_PIPELINE_STATISTICS:
2365f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset      nv50_hw_query_get(push, q, 0x00, 0x00801002); /* VFETCH, VERTICES */
2375f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset      nv50_hw_query_get(push, q, 0x10, 0x01801002); /* VFETCH, PRIMS */
2385f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset      nv50_hw_query_get(push, q, 0x20, 0x02802002); /* VP, LAUNCHES */
2395f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset      nv50_hw_query_get(push, q, 0x30, 0x03806002); /* GP, LAUNCHES */
2405f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset      nv50_hw_query_get(push, q, 0x40, 0x04806002); /* GP, PRIMS_OUT */
2415f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset      nv50_hw_query_get(push, q, 0x50, 0x07804002); /* RAST, PRIMS_IN */
2425f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset      nv50_hw_query_get(push, q, 0x60, 0x08804002); /* RAST, PRIMS_OUT */
2435f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset      nv50_hw_query_get(push, q, 0x70, 0x0980a002); /* ROP, PIXELS */
2445f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset      break;
2455f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset   case PIPE_QUERY_TIMESTAMP:
2465f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset      hq->sequence++;
2475f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset      /* fall through */
2485f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset   case PIPE_QUERY_TIME_ELAPSED:
2495f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset      nv50_hw_query_get(push, q, 0, 0x00005002);
2505f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset      break;
2515f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset   case PIPE_QUERY_GPU_FINISHED:
2525f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset      hq->sequence++;
2535f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset      nv50_hw_query_get(push, q, 0, 0x1000f010);
2545f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset      break;
2555f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset   case NVA0_HW_QUERY_STREAM_OUTPUT_BUFFER_OFFSET:
2565f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset      hq->sequence++;
2575f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset      nv50_hw_query_get(push, q, 0, 0x0d005002 | (q->index << 5));
2585f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset      break;
2595f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset   case PIPE_QUERY_TIMESTAMP_DISJOINT:
2605f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset      /* This query is not issued on GPU because disjoint is forced to false */
2615f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset      hq->state = NV50_HW_QUERY_STATE_READY;
2625f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset      break;
2635f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset   default:
2645f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset      assert(0);
2655f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset      break;
2665f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset   }
2675f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset   if (hq->is64bit)
2685f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset      nouveau_fence_ref(nv50->screen->base.fence.current, &hq->fence);
2695f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset}
2705f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset
2715f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoisetstatic boolean
2725f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoisetnv50_hw_get_query_result(struct nv50_context *nv50, struct nv50_query *q,
2735f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset                         boolean wait, union pipe_query_result *result)
2745f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset{
2755f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset   struct nv50_hw_query *hq = nv50_hw_query(q);
2765f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset   uint64_t *res64 = (uint64_t *)result;
2775f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset   uint32_t *res32 = (uint32_t *)result;
2785f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset   uint8_t *res8 = (uint8_t *)result;
2795f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset   uint64_t *data64 = (uint64_t *)hq->data;
2805f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset   int i;
2815f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset
2826a9c151dbb87a10b6d51c451a5a277d646d08857Samuel Pitoiset   if (hq->funcs && hq->funcs->get_query_result)
2836a9c151dbb87a10b6d51c451a5a277d646d08857Samuel Pitoiset      return hq->funcs->get_query_result(nv50, hq, wait, result);
2846a9c151dbb87a10b6d51c451a5a277d646d08857Samuel Pitoiset
2855f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset   if (hq->state != NV50_HW_QUERY_STATE_READY)
2865f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset      nv50_hw_query_update(q);
2875f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset
2885f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset   if (hq->state != NV50_HW_QUERY_STATE_READY) {
2895f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset      if (!wait) {
2905f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset         /* for broken apps that spin on GL_QUERY_RESULT_AVAILABLE */
2915f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset         if (hq->state != NV50_HW_QUERY_STATE_FLUSHED) {
2925f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset            hq->state = NV50_HW_QUERY_STATE_FLUSHED;
2935f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset            PUSH_KICK(nv50->base.pushbuf);
2945f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset         }
2955f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset         return false;
2965f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset      }
2975f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset      if (nouveau_bo_wait(hq->bo, NOUVEAU_BO_RD, nv50->screen->base.client))
2985f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset         return false;
2995f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset   }
3005f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset   hq->state = NV50_HW_QUERY_STATE_READY;
3015f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset
3025f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset   switch (q->type) {
3035f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset   case PIPE_QUERY_GPU_FINISHED:
3045f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset      res8[0] = true;
3055f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset      break;
3065f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset   case PIPE_QUERY_OCCLUSION_COUNTER: /* u32 sequence, u32 count, u64 time */
3075f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset      res64[0] = hq->data[1] - hq->data[5];
3085f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset      break;
30950235ab3ab9f22565aed596e5a915831d099314dIlia Mirkin   case PIPE_QUERY_OCCLUSION_PREDICATE:
31050235ab3ab9f22565aed596e5a915831d099314dIlia Mirkin      res8[0] = hq->data[1] != hq->data[5];
31150235ab3ab9f22565aed596e5a915831d099314dIlia Mirkin      break;
3125f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset   case PIPE_QUERY_PRIMITIVES_GENERATED: /* u64 count, u64 time */
3135f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset   case PIPE_QUERY_PRIMITIVES_EMITTED: /* u64 count, u64 time */
3145f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset      res64[0] = data64[0] - data64[2];
3155f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset      break;
3165f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset   case PIPE_QUERY_SO_STATISTICS:
3175f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset      res64[0] = data64[0] - data64[4];
3185f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset      res64[1] = data64[2] - data64[6];
3195f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset      break;
3205f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset   case PIPE_QUERY_PIPELINE_STATISTICS:
3215f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset      for (i = 0; i < 8; ++i)
3225f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset         res64[i] = data64[i * 2] - data64[16 + i * 2];
3235f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset      break;
3245f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset   case PIPE_QUERY_TIMESTAMP:
3255f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset      res64[0] = data64[1];
3265f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset      break;
3275f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset   case PIPE_QUERY_TIMESTAMP_DISJOINT:
3285f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset      res64[0] = 1000000000;
3295f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset      res8[8] = false;
3305f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset      break;
3315f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset   case PIPE_QUERY_TIME_ELAPSED:
3325f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset      res64[0] = data64[1] - data64[3];
3335f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset      break;
3345f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset   case NVA0_HW_QUERY_STREAM_OUTPUT_BUFFER_OFFSET:
3355f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset      res32[0] = hq->data[1];
3365f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset      break;
3375f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset   default:
3385f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset      assert(0);
3395f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset      return false;
3405f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset   }
3415f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset
3425f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset   return true;
3435f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset}
3445f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset
3455f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoisetstatic const struct nv50_query_funcs hw_query_funcs = {
3465f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset   .destroy_query = nv50_hw_destroy_query,
3475f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset   .begin_query = nv50_hw_begin_query,
3485f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset   .end_query = nv50_hw_end_query,
3495f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset   .get_query_result = nv50_hw_get_query_result,
3505f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset};
3515f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset
3525f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoisetstruct nv50_query *
3535f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoisetnv50_hw_create_query(struct nv50_context *nv50, unsigned type, unsigned index)
3545f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset{
3555f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset   struct nv50_hw_query *hq;
3565f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset   struct nv50_query *q;
3575f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset
3586a9c151dbb87a10b6d51c451a5a277d646d08857Samuel Pitoiset   hq = nv50_hw_sm_create_query(nv50, type);
3596a9c151dbb87a10b6d51c451a5a277d646d08857Samuel Pitoiset   if (hq) {
3606a9c151dbb87a10b6d51c451a5a277d646d08857Samuel Pitoiset      hq->base.funcs = &hw_query_funcs;
3616a9c151dbb87a10b6d51c451a5a277d646d08857Samuel Pitoiset      return (struct nv50_query *)hq;
3626a9c151dbb87a10b6d51c451a5a277d646d08857Samuel Pitoiset   }
3636a9c151dbb87a10b6d51c451a5a277d646d08857Samuel Pitoiset
364848fa3101d5077b1aecfb0886c69a7d0dd7f75bcSamuel Pitoiset   hq = nv50_hw_metric_create_query(nv50, type);
365848fa3101d5077b1aecfb0886c69a7d0dd7f75bcSamuel Pitoiset   if (hq) {
366848fa3101d5077b1aecfb0886c69a7d0dd7f75bcSamuel Pitoiset      hq->base.funcs = &hw_query_funcs;
367848fa3101d5077b1aecfb0886c69a7d0dd7f75bcSamuel Pitoiset      return (struct nv50_query *)hq;
368848fa3101d5077b1aecfb0886c69a7d0dd7f75bcSamuel Pitoiset   }
369848fa3101d5077b1aecfb0886c69a7d0dd7f75bcSamuel Pitoiset
3705f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset   hq = CALLOC_STRUCT(nv50_hw_query);
3715f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset   if (!hq)
3725f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset      return NULL;
3735f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset
3745f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset   q = &hq->base;
3755f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset   q->funcs = &hw_query_funcs;
3765f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset   q->type = type;
3775f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset
3780d0329df8fc95754a8edd76d1da0b32e2aaf83dfSamuel Pitoiset   switch (q->type) {
3790d0329df8fc95754a8edd76d1da0b32e2aaf83dfSamuel Pitoiset   case PIPE_QUERY_OCCLUSION_COUNTER:
38050235ab3ab9f22565aed596e5a915831d099314dIlia Mirkin   case PIPE_QUERY_OCCLUSION_PREDICATE:
3810d0329df8fc95754a8edd76d1da0b32e2aaf83dfSamuel Pitoiset      hq->rotate = 32;
3820d0329df8fc95754a8edd76d1da0b32e2aaf83dfSamuel Pitoiset      break;
3830d0329df8fc95754a8edd76d1da0b32e2aaf83dfSamuel Pitoiset   case PIPE_QUERY_PRIMITIVES_GENERATED:
3840d0329df8fc95754a8edd76d1da0b32e2aaf83dfSamuel Pitoiset   case PIPE_QUERY_PRIMITIVES_EMITTED:
3850d0329df8fc95754a8edd76d1da0b32e2aaf83dfSamuel Pitoiset   case PIPE_QUERY_SO_STATISTICS:
3860d0329df8fc95754a8edd76d1da0b32e2aaf83dfSamuel Pitoiset   case PIPE_QUERY_PIPELINE_STATISTICS:
3870d0329df8fc95754a8edd76d1da0b32e2aaf83dfSamuel Pitoiset      hq->is64bit = true;
3880d0329df8fc95754a8edd76d1da0b32e2aaf83dfSamuel Pitoiset      break;
3890d0329df8fc95754a8edd76d1da0b32e2aaf83dfSamuel Pitoiset   case PIPE_QUERY_TIME_ELAPSED:
3900d0329df8fc95754a8edd76d1da0b32e2aaf83dfSamuel Pitoiset   case PIPE_QUERY_TIMESTAMP:
3910d0329df8fc95754a8edd76d1da0b32e2aaf83dfSamuel Pitoiset   case PIPE_QUERY_TIMESTAMP_DISJOINT:
3920d0329df8fc95754a8edd76d1da0b32e2aaf83dfSamuel Pitoiset   case PIPE_QUERY_GPU_FINISHED:
3930d0329df8fc95754a8edd76d1da0b32e2aaf83dfSamuel Pitoiset   case NVA0_HW_QUERY_STREAM_OUTPUT_BUFFER_OFFSET:
3940d0329df8fc95754a8edd76d1da0b32e2aaf83dfSamuel Pitoiset      break;
3950d0329df8fc95754a8edd76d1da0b32e2aaf83dfSamuel Pitoiset   default:
3960d0329df8fc95754a8edd76d1da0b32e2aaf83dfSamuel Pitoiset      debug_printf("invalid query type: %u\n", type);
3970d0329df8fc95754a8edd76d1da0b32e2aaf83dfSamuel Pitoiset      FREE(q);
3980d0329df8fc95754a8edd76d1da0b32e2aaf83dfSamuel Pitoiset      return NULL;
3990d0329df8fc95754a8edd76d1da0b32e2aaf83dfSamuel Pitoiset   }
4000d0329df8fc95754a8edd76d1da0b32e2aaf83dfSamuel Pitoiset
4015f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset   if (!nv50_hw_query_allocate(nv50, q, NV50_HW_QUERY_ALLOC_SPACE)) {
4025f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset      FREE(hq);
4035f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset      return NULL;
4045f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset   }
4055f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset
4060d0329df8fc95754a8edd76d1da0b32e2aaf83dfSamuel Pitoiset   if (hq->rotate) {
4075f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset      /* we advance before query_begin ! */
4080d0329df8fc95754a8edd76d1da0b32e2aaf83dfSamuel Pitoiset      hq->offset -= hq->rotate;
4090d0329df8fc95754a8edd76d1da0b32e2aaf83dfSamuel Pitoiset      hq->data -= hq->rotate / sizeof(*hq->data);
4105f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset   }
4115f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset
4125f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset   return q;
4135f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset}
4145f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset
4156a9c151dbb87a10b6d51c451a5a277d646d08857Samuel Pitoisetint
4166a9c151dbb87a10b6d51c451a5a277d646d08857Samuel Pitoisetnv50_hw_get_driver_query_info(struct nv50_screen *screen, unsigned id,
4176a9c151dbb87a10b6d51c451a5a277d646d08857Samuel Pitoiset                              struct pipe_driver_query_info *info)
4186a9c151dbb87a10b6d51c451a5a277d646d08857Samuel Pitoiset{
419848fa3101d5077b1aecfb0886c69a7d0dd7f75bcSamuel Pitoiset   int num_hw_sm_queries = 0, num_hw_metric_queries = 0;
4206a9c151dbb87a10b6d51c451a5a277d646d08857Samuel Pitoiset
4216a9c151dbb87a10b6d51c451a5a277d646d08857Samuel Pitoiset   num_hw_sm_queries = nv50_hw_sm_get_driver_query_info(screen, 0, NULL);
422848fa3101d5077b1aecfb0886c69a7d0dd7f75bcSamuel Pitoiset   num_hw_metric_queries =
423848fa3101d5077b1aecfb0886c69a7d0dd7f75bcSamuel Pitoiset      nv50_hw_metric_get_driver_query_info(screen, 0, NULL);
4246a9c151dbb87a10b6d51c451a5a277d646d08857Samuel Pitoiset
4256a9c151dbb87a10b6d51c451a5a277d646d08857Samuel Pitoiset   if (!info)
426848fa3101d5077b1aecfb0886c69a7d0dd7f75bcSamuel Pitoiset      return num_hw_sm_queries + num_hw_metric_queries;
427848fa3101d5077b1aecfb0886c69a7d0dd7f75bcSamuel Pitoiset
428848fa3101d5077b1aecfb0886c69a7d0dd7f75bcSamuel Pitoiset   if (id < num_hw_sm_queries)
429848fa3101d5077b1aecfb0886c69a7d0dd7f75bcSamuel Pitoiset      return nv50_hw_sm_get_driver_query_info(screen, id, info);
4306a9c151dbb87a10b6d51c451a5a277d646d08857Samuel Pitoiset
431848fa3101d5077b1aecfb0886c69a7d0dd7f75bcSamuel Pitoiset   return nv50_hw_metric_get_driver_query_info(screen,
432848fa3101d5077b1aecfb0886c69a7d0dd7f75bcSamuel Pitoiset                                               id - num_hw_sm_queries, info);
4336a9c151dbb87a10b6d51c451a5a277d646d08857Samuel Pitoiset}
4346a9c151dbb87a10b6d51c451a5a277d646d08857Samuel Pitoiset
4355f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoisetvoid
4365f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoisetnv50_hw_query_pushbuf_submit(struct nouveau_pushbuf *push, uint16_t method,
4375f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset                             struct nv50_query *q, unsigned result_offset)
4385f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset{
4395f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset   struct nv50_hw_query *hq = nv50_hw_query(q);
4405f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset
4415f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset   nv50_hw_query_update(q);
4425f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset   if (hq->state != NV50_HW_QUERY_STATE_READY)
4435f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset      nouveau_bo_wait(hq->bo, NOUVEAU_BO_RD, push->client);
4445f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset   hq->state = NV50_HW_QUERY_STATE_READY;
4455f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset
4465f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset   BEGIN_NV04(push, SUBC_3D(method), 1);
4475f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset   PUSH_DATA (push, hq->data[result_offset / 4]);
4485f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset}
4495f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset
4505f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoisetvoid
4515f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoisetnv84_hw_query_fifo_wait(struct nouveau_pushbuf *push, struct nv50_query *q)
4525f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset{
4535f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset   struct nv50_hw_query *hq = nv50_hw_query(q);
4545f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset   unsigned offset = hq->offset;
4555f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset
4565f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset   PUSH_SPACE(push, 5);
4575f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset   PUSH_REFN (push, hq->bo, NOUVEAU_BO_GART | NOUVEAU_BO_RD);
4585f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset   BEGIN_NV04(push, SUBC_3D(NV84_SUBCHAN_SEMAPHORE_ADDRESS_HIGH), 4);
4595f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset   PUSH_DATAh(push, hq->bo->offset + offset);
4605f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset   PUSH_DATA (push, hq->bo->offset + offset);
4615f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset   PUSH_DATA (push, hq->sequence);
4625f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset   PUSH_DATA (push, NV84_SUBCHAN_SEMAPHORE_TRIGGER_ACQUIRE_EQUAL);
4635f1eeb799bd9bcdb32382961e57ef74253701ed2Samuel Pitoiset}
464