2 * Copyright (C) 2014 Rob Clark <robclark@freedesktop.org>
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24 * Rob Clark <robclark@freedesktop.org>
27 #include "freedreno_query_hw.h"
28 #include "freedreno_context.h"
29 #include "freedreno_util.h"
31 #include "fd3_query.h"
32 #include "fd3_format.h"
35 struct fd_rb_samp_ctrs
{
42 * OCCLUSION_COUNTER and OCCLUSION_PREDICATE differ only in how they
46 static struct fd_hw_sample
*
47 occlusion_get_sample(struct fd_batch
*batch
, struct fd_ringbuffer
*ring
)
49 struct fd_hw_sample
*samp
=
50 fd_hw_sample_init(batch
, sizeof(struct fd_rb_samp_ctrs
));
52 /* Set RB_SAMPLE_COUNT_ADDR to samp->offset plus value of
53 * HW_QUERY_BASE_REG register:
55 OUT_PKT3(ring
, CP_SET_CONSTANT
, 3);
56 OUT_RING(ring
, CP_REG(REG_A3XX_RB_SAMPLE_COUNT_ADDR
) | 0x80000000);
57 OUT_RING(ring
, HW_QUERY_BASE_REG
);
58 OUT_RING(ring
, samp
->offset
);
60 OUT_PKT0(ring
, REG_A3XX_RB_SAMPLE_COUNT_CONTROL
, 1);
61 OUT_RING(ring
, A3XX_RB_SAMPLE_COUNT_CONTROL_COPY
);
63 OUT_PKT3(ring
, CP_DRAW_INDX
, 3);
64 OUT_RING(ring
, 0x00000000);
65 OUT_RING(ring
, DRAW(DI_PT_POINTLIST_PSIZE
, DI_SRC_SEL_AUTO_INDEX
,
66 INDEX_SIZE_IGN
, USE_VISIBILITY
, 0));
67 OUT_RING(ring
, 0); /* NumIndices */
69 fd_event_write(batch
, ring
, ZPASS_DONE
);
71 OUT_PKT0(ring
, REG_A3XX_RBBM_PERFCTR_CTL
, 1);
72 OUT_RING(ring
, A3XX_RBBM_PERFCTR_CTL_ENABLE
);
74 OUT_PKT0(ring
, REG_A3XX_VBIF_PERF_CNT_EN
, 1);
75 OUT_RING(ring
, A3XX_VBIF_PERF_CNT_EN_CNT0
|
76 A3XX_VBIF_PERF_CNT_EN_CNT1
|
77 A3XX_VBIF_PERF_CNT_EN_PWRCNT0
|
78 A3XX_VBIF_PERF_CNT_EN_PWRCNT1
|
79 A3XX_VBIF_PERF_CNT_EN_PWRCNT2
);
85 count_samples(const struct fd_rb_samp_ctrs
*start
,
86 const struct fd_rb_samp_ctrs
*end
)
91 /* not quite sure what all of these are, possibly different
92 * counters for each MRT render target:
94 for (i
= 0; i
< 16; i
+= 4)
95 n
+= end
->ctr
[i
] - start
->ctr
[i
];
101 occlusion_counter_accumulate_result(struct fd_context
*ctx
,
102 const void *start
, const void *end
,
103 union pipe_query_result
*result
)
105 uint64_t n
= count_samples(start
, end
);
110 occlusion_predicate_accumulate_result(struct fd_context
*ctx
,
111 const void *start
, const void *end
,
112 union pipe_query_result
*result
)
114 uint64_t n
= count_samples(start
, end
);
115 result
->b
|= (n
> 0);
118 static const struct fd_hw_sample_provider occlusion_counter
= {
119 .query_type
= PIPE_QUERY_OCCLUSION_COUNTER
,
120 .active
= FD_STAGE_DRAW
,
121 .get_sample
= occlusion_get_sample
,
122 .accumulate_result
= occlusion_counter_accumulate_result
,
125 static const struct fd_hw_sample_provider occlusion_predicate
= {
126 .query_type
= PIPE_QUERY_OCCLUSION_PREDICATE
,
127 .active
= FD_STAGE_DRAW
,
128 .get_sample
= occlusion_get_sample
,
129 .accumulate_result
= occlusion_predicate_accumulate_result
,
132 static const struct fd_hw_sample_provider occlusion_predicate_conservative
= {
133 .query_type
= PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE
,
134 .active
= FD_STAGE_DRAW
,
135 .get_sample
= occlusion_get_sample
,
136 .accumulate_result
= occlusion_predicate_accumulate_result
,
139 void fd3_query_context_init(struct pipe_context
*pctx
)
141 struct fd_context
*ctx
= fd_context(pctx
);
143 ctx
->create_query
= fd_hw_create_query
;
144 ctx
->query_prepare
= fd_hw_query_prepare
;
145 ctx
->query_prepare_tile
= fd_hw_query_prepare_tile
;
146 ctx
->query_set_stage
= fd_hw_query_set_stage
;
148 fd_hw_query_register_provider(pctx
, &occlusion_counter
);
149 fd_hw_query_register_provider(pctx
, &occlusion_predicate
);
150 fd_hw_query_register_provider(pctx
, &occlusion_predicate_conservative
);