}
static struct pipe_query *
-nvc0_query_create(struct pipe_context *pipe, unsigned type)
+nvc0_query_create(struct pipe_context *pipe, unsigned type, unsigned index)
{
struct nvc0_context *nvc0 = nvc0_context(pipe);
struct nvc0_query *q;
case PIPE_QUERY_PRIMITIVES_GENERATED:
case PIPE_QUERY_PRIMITIVES_EMITTED:
q->is64bit = TRUE;
+ q->index = index;
space = 32;
break;
case PIPE_QUERY_TIME_ELAPSED:
/* indexed by TFB buffer instead of by vertex stream */
nvc0_query_get(push, q, 0x00, 0x0d005002 | (q->index << 5));
break;
+ case PIPE_QUERY_TIMESTAMP_DISJOINT:
+ /* This query is not issued on GPU because disjoint is forced to FALSE */
+ q->state = NVC0_QUERY_STATE_READY;
+ break;
default:
#ifdef NOUVEAU_ENABLE_DRIVER_STATISTICS
if (q->type >= NVC0_QUERY_DRV_STAT(0) &&
struct nouveau_pushbuf *push = nvc0->base.pushbuf;
struct nvc0_query *q;
uint32_t cond;
- boolean negated = FALSE;
boolean wait =
mode != PIPE_RENDER_COND_NO_WAIT &&
mode != PIPE_RENDER_COND_BY_REGION_NO_WAIT;
+ if (!pq) {
+ cond = NVC0_3D_COND_MODE_ALWAYS;
+ }
+ else {
+ q = nvc0_query(pq);
+ /* NOTE: comparison of 2 queries only works if both have completed */
+ switch (q->type) {
+ case PIPE_QUERY_SO_OVERFLOW_PREDICATE:
+ cond = condition ? NVC0_3D_COND_MODE_EQUAL :
+ NVC0_3D_COND_MODE_NOT_EQUAL;
+ wait = TRUE;
+ break;
+ case PIPE_QUERY_OCCLUSION_COUNTER:
+ case PIPE_QUERY_OCCLUSION_PREDICATE:
+ if (likely(!condition)) {
+ if (unlikely(q->nesting))
+ cond = wait ? NVC0_3D_COND_MODE_NOT_EQUAL :
+ NVC0_3D_COND_MODE_ALWAYS;
+ else
+ cond = NVC0_3D_COND_MODE_RES_NON_ZERO;
+ } else {
+ cond = wait ? NVC0_3D_COND_MODE_EQUAL : NVC0_3D_COND_MODE_ALWAYS;
+ }
+ break;
+ default:
+ assert(!"render condition query not a predicate");
+ cond = NVC0_3D_COND_MODE_ALWAYS;
+ break;
+ }
+ }
+
nvc0->cond_query = pq;
nvc0->cond_cond = condition;
+ nvc0->cond_condmode = cond;
nvc0->cond_mode = mode;
if (!pq) {
PUSH_SPACE(push, 1);
- IMMED_NVC0(push, NVC0_3D(COND_MODE), NVC0_3D_COND_MODE_ALWAYS);
+ IMMED_NVC0(push, NVC0_3D(COND_MODE), cond);
return;
}
- q = nvc0_query(pq);
-
- /* NOTE: comparison of 2 queries only works if both have completed */
- switch (q->type) {
- case PIPE_QUERY_SO_OVERFLOW_PREDICATE:
- cond = negated ? NVC0_3D_COND_MODE_EQUAL :
- NVC0_3D_COND_MODE_NOT_EQUAL;
- wait = TRUE;
- break;
- case PIPE_QUERY_OCCLUSION_COUNTER:
- case PIPE_QUERY_OCCLUSION_PREDICATE:
- if (likely(!negated)) {
- if (unlikely(q->nesting))
- cond = wait ? NVC0_3D_COND_MODE_NOT_EQUAL :
- NVC0_3D_COND_MODE_ALWAYS;
- else
- cond = NVC0_3D_COND_MODE_RES_NON_ZERO;
- } else {
- cond = wait ? NVC0_3D_COND_MODE_EQUAL : NVC0_3D_COND_MODE_ALWAYS;
- }
- break;
- default:
- assert(!"render condition query not a predicate");
- mode = NVC0_3D_COND_MODE_ALWAYS;
- break;
- }
if (wait)
nvc0_query_fifo_wait(push, pq);
- PUSH_SPACE(push, 4);
+ PUSH_SPACE(push, 7);
PUSH_REFN (push, q->bo, NOUVEAU_BO_GART | NOUVEAU_BO_RD);
BEGIN_NVC0(push, NVC0_3D(COND_ADDRESS_HIGH), 3);
PUSH_DATAh(push, q->bo->offset + q->offset);
PUSH_DATA (push, q->bo->offset + q->offset);
PUSH_DATA (push, cond);
+ BEGIN_NVC0(push, NVC0_2D(COND_ADDRESS_HIGH), 2);
+ PUSH_DATAh(push, q->bo->offset + q->offset);
+ PUSH_DATA (push, q->bo->offset + q->offset);
}
void
{
struct nvc0_screen *screen = nvc0->screen;
struct nouveau_pushbuf *push = nvc0->base.pushbuf;
+ const boolean is_nve4 = screen->base.class_3d >= NVE4_3D_CLASS;
const struct nvc0_mp_pm_query_cfg *cfg;
unsigned i, c;
unsigned num_ab[2] = { 0, 0 };
}
assert(cfg->num_counters <= 4);
- PUSH_SPACE(push, 4 * 8 + 6);
+ PUSH_SPACE(push, 4 * 8 * (is_nve4 ? 1 : 6) + 6);
if (!screen->pm.mp_counters_enabled) {
screen->pm.mp_counters_enabled = TRUE;
assert(c <= (d * 4 + 3)); /* must succeed, already checked for space */
/* configure and reset the counter(s) */
- if (screen->base.class_3d >= NVE4_3D_CLASS) {
+ if (is_nve4) {
if (d == 0)
BEGIN_NVC0(push, NVE4_COMPUTE(MP_PM_A_SIGSEL(c & 3)), 1);
else
for (c = 0; c < cfg->num_counters; ++c)
for (p = 0; p < mp_count; ++p)
v |= count[p][c];
- value = (v * cfg->norm[0]) / cfg->norm[1];
+ value = ((uint64_t)v * cfg->norm[0]) / cfg->norm[1];
} else
if (cfg->op == NVC0_COUNTER_OPn_AND) {
uint32_t v = ~0;
for (c = 0; c < cfg->num_counters; ++c)
for (p = 0; p < mp_count; ++p)
v &= count[p][c];
- value = (v * cfg->norm[0]) / cfg->norm[1];
+ value = ((uint64_t)v * cfg->norm[0]) / cfg->norm[1];
} else
if (cfg->op == NVC0_COUNTER_OP2_REL_SUM_MM) {
uint64_t v[2] = { 0, 0 };
if (count[p][1])
value += (count[p][0] * cfg->norm[0]) / count[p][1];
if (mp_used)
- value /= mp_used * cfg->norm[1];
+ value /= (uint64_t)mp_used * cfg->norm[1];
} else
if (cfg->op == NVC0_COUNTER_OP2_AVG_DIV_M0) {
unsigned mp_used = 0;
value += count[p][0];
if (count[0][1] && mp_used) {
value *= cfg->norm[0];
- value /= count[0][1] * mp_used * cfg->norm[1];
+ value /= (uint64_t)count[0][1] * mp_used * cfg->norm[1];
} else {
value = 0;
}