q->funcs->destroy_query(nvc0_context(pipe), q);
}
-static boolean
+static bool
nvc0_begin_query(struct pipe_context *pipe, struct pipe_query *pq)
{
struct nvc0_query *q = nvc0_query(pq);
return q->funcs->begin_query(nvc0_context(pipe), q);
}
-static void
+static bool
nvc0_end_query(struct pipe_context *pipe, struct pipe_query *pq)
{
struct nvc0_query *q = nvc0_query(pq);
q->funcs->end_query(nvc0_context(pipe), q);
+ return true;
}
-static boolean
+static bool
nvc0_get_query_result(struct pipe_context *pipe, struct pipe_query *pq,
- boolean wait, union pipe_query_result *result)
+ bool wait, union pipe_query_result *result)
{
struct nvc0_query *q = nvc0_query(pq);
return q->funcs->get_query_result(nvc0_context(pipe), q, wait, result);
}
+static void
+nvc0_get_query_result_resource(struct pipe_context *pipe,
+ struct pipe_query *pq,
+ bool wait,
+ enum pipe_query_value_type result_type,
+ int index,
+ struct pipe_resource *resource,
+ unsigned offset)
+{
+ struct nvc0_query *q = nvc0_query(pq);
+ if (!q->funcs->get_query_result_resource) {
+ assert(!"Unexpected lack of get_query_result_resource");
+ return;
+ }
+ q->funcs->get_query_result_resource(nvc0_context(pipe), q, wait, result_type,
+ index, resource, offset);
+}
+
static void
nvc0_render_condition(struct pipe_context *pipe,
struct pipe_query *pq,
- boolean condition, uint mode)
+ bool condition, enum pipe_render_cond_flag mode)
{
struct nvc0_context *nvc0 = nvc0_context(pipe);
struct nouveau_pushbuf *push = nvc0->base.pushbuf;
/* NOTE: comparison of 2 queries only works if both have completed */
switch (q->type) {
case PIPE_QUERY_SO_OVERFLOW_PREDICATE:
+ case PIPE_QUERY_SO_OVERFLOW_ANY_PREDICATE:
cond = condition ? NVC0_3D_COND_MODE_EQUAL :
- NVC0_3D_COND_MODE_NOT_EQUAL;
+ NVC0_3D_COND_MODE_NOT_EQUAL;
wait = true;
break;
case PIPE_QUERY_OCCLUSION_COUNTER:
case PIPE_QUERY_OCCLUSION_PREDICATE:
+ case PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE:
+ if (hq->state == NVC0_HW_QUERY_STATE_READY)
+ wait = true;
if (likely(!condition)) {
- if (unlikely(hq->nesting))
- cond = wait ? NVC0_3D_COND_MODE_NOT_EQUAL :
- NVC0_3D_COND_MODE_ALWAYS;
- else
- cond = NVC0_3D_COND_MODE_RES_NON_ZERO;
+ cond = wait ? NVC0_3D_COND_MODE_NOT_EQUAL : NVC0_3D_COND_MODE_ALWAYS;
} else {
cond = wait ? NVC0_3D_COND_MODE_EQUAL : NVC0_3D_COND_MODE_ALWAYS;
}
nvc0->cond_mode = mode;
if (!pq) {
- PUSH_SPACE(push, 1);
+ PUSH_SPACE(push, 2);
IMMED_NVC0(push, NVC0_3D(COND_MODE), cond);
+ if (nvc0->screen->compute)
+ IMMED_NVC0(push, NVC0_CP(COND_MODE), cond);
return;
}
- if (wait)
- nvc0_hw_query_fifo_wait(push, q);
+ if (wait && hq->state != NVC0_HW_QUERY_STATE_READY)
+ nvc0_hw_query_fifo_wait(nvc0, q);
- PUSH_SPACE(push, 7);
+ PUSH_SPACE(push, 10);
PUSH_REFN (push, hq->bo, NOUVEAU_BO_GART | NOUVEAU_BO_RD);
BEGIN_NVC0(push, NVC0_3D(COND_ADDRESS_HIGH), 3);
PUSH_DATAh(push, hq->bo->offset + hq->offset);
BEGIN_NVC0(push, NVC0_2D(COND_ADDRESS_HIGH), 2);
PUSH_DATAh(push, hq->bo->offset + hq->offset);
PUSH_DATA (push, hq->bo->offset + hq->offset);
+ if (nvc0->screen->compute) {
+ BEGIN_NVC0(push, NVC0_CP(COND_ADDRESS_HIGH), 3);
+ PUSH_DATAh(push, hq->bo->offset + hq->offset);
+ PUSH_DATA (push, hq->bo->offset + hq->offset);
+ PUSH_DATA (push, cond);
+ }
}
int
if (screen->base.drm->version >= 0x01000101) {
if (screen->compute) {
- if (screen->base.class_3d == NVE4_3D_CLASS) {
- count += 2;
- } else
- if (screen->base.class_3d < NVE4_3D_CLASS) {
+ if (screen->base.class_3d <= GM200_3D_CLASS) {
count += 2;
}
}
if (screen->compute) {
info->name = "MP counters";
- /* Because we can't expose the number of hardware counters needed for
- * each different query, we don't want to allow more than one active
- * query simultaneously to avoid failure when the maximum number of
- * counters is reached. Note that these groups of GPU counters are
- * currently only used by AMD_performance_monitor.
- */
- info->max_active_queries = 1;
-
- if (screen->base.class_3d == NVE4_3D_CLASS) {
- info->num_queries = NVE4_HW_SM_QUERY_COUNT;
- return 1;
- } else
- if (screen->base.class_3d < NVE4_3D_CLASS) {
- info->num_queries = NVC0_HW_SM_QUERY_COUNT;
- return 1;
- }
+ /* Expose the maximum number of hardware counters available, although
+ * some queries use more than one counter. Expect failures in that
+ * case but as performance counters are for developers, this should
+ * not have a real impact. */
+ info->max_active_queries = 8;
+ info->num_queries = nvc0_hw_sm_get_num_queries(screen);
+ return 1;
}
} else
if (id == NVC0_HW_METRIC_QUERY_GROUP) {
if (screen->compute) {
- if (screen->base.class_3d == NVE4_3D_CLASS) {
- info->name = "Performance metrics";
- info->max_active_queries = 1;
- info->num_queries = NVE4_HW_METRIC_QUERY_COUNT;
- return 1;
- } else
- if (screen->base.class_3d < NVE4_3D_CLASS) {
+ if (screen->base.class_3d <= GM200_3D_CLASS) {
info->name = "Performance metrics";
- info->max_active_queries = 1;
- info->num_queries = NVC0_HW_METRIC_QUERY_COUNT;
+ info->max_active_queries = 4; /* A metric uses at least 2 queries */
+ info->num_queries = nvc0_hw_metric_get_num_queries(screen);
return 1;
}
}
return 0;
}
+static void
+nvc0_set_active_query_state(struct pipe_context *pipe, bool enable)
+{
+}
+
void
nvc0_init_query_functions(struct nvc0_context *nvc0)
{
pipe->begin_query = nvc0_begin_query;
pipe->end_query = nvc0_end_query;
pipe->get_query_result = nvc0_get_query_result;
+ pipe->get_query_result_resource = nvc0_get_query_result_resource;
+ pipe->set_active_query_state = nvc0_set_active_query_state;
pipe->render_condition = nvc0_render_condition;
nvc0->cond_condmode = NVC0_3D_COND_MODE_ALWAYS;
}