xref: /aosp_15_r20/external/mesa3d/src/gallium/drivers/etnaviv/etnaviv_query_acc_occlusion.c (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1 /*
2  * Copyright (c) 2017 Etnaviv Project
3  * Copyright (C) 2017 Zodiac Inflight Innovations
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining a
6  * copy of this software and associated documentation files (the "Software"),
7  * to deal in the Software without restriction, including without limitation
8  * the rights to use, copy, modify, merge, publish, distribute, sub license,
9  * and/or sell copies of the Software, and to permit persons to whom the
10  * Software is furnished to do so, subject to the following conditions:
11  *
12  * The above copyright notice and this permission notice (including the
13  * next paragraph) shall be included in all copies or substantial portions
14  * of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
19  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22  * DEALINGS IN THE SOFTWARE.
23  *
24  * Authors:
25  *    Rob Clark <[email protected]>
26  *    Christian Gmeiner <[email protected]>
27  */
28 
29 #include "util/compiler.h"
30 #include "util/u_inlines.h"
31 #include "util/u_memory.h"
32 
33 #include "etnaviv_context.h"
34 #include "etnaviv_debug.h"
35 #include "etnaviv_emit.h"
36 #include "etnaviv_query_acc.h"
37 #include "etnaviv_screen.h"
38 
39 #define MAX_OQ_SAMPLES 511 /* 4KB / 8Bytes/sample */
40 
41 /*
42  * Occlusion Query:
43  *
44  * OCCLUSION_COUNTER and OCCLUSION_PREDICATE differ only in how they
45  * interpret results
46  */
47 
48 static bool
occlusion_supports(unsigned query_type)49 occlusion_supports(unsigned query_type)
50 {
51    switch (query_type) {
52    case PIPE_QUERY_OCCLUSION_COUNTER:
53       FALLTHROUGH;
54    case PIPE_QUERY_OCCLUSION_PREDICATE:
55       FALLTHROUGH;
56    case PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE:
57       return true;
58    default:
59       return false;
60    }
61 }
62 
63 static struct etna_acc_query *
occlusion_allocate(struct etna_context * ctx,ASSERTED unsigned query_type)64 occlusion_allocate(struct etna_context *ctx, ASSERTED unsigned query_type)
65 {
66    return CALLOC_STRUCT(etna_acc_query);
67 }
68 
69 static void
occlusion_resume(struct etna_acc_query * aq,struct etna_context * ctx)70 occlusion_resume(struct etna_acc_query *aq, struct etna_context *ctx)
71 {
72    struct etna_resource *rsc = etna_resource(aq->prsc);
73    struct etna_reloc r = {
74       .bo = rsc->bo,
75       .flags = ETNA_RELOC_WRITE
76    };
77 
78    if (aq->samples > MAX_OQ_SAMPLES) {
79       aq->samples = MAX_OQ_SAMPLES;
80       BUG("samples overflow");
81    }
82 
83    r.offset = aq->samples * 8; /* 64bit value */
84 
85    etna_set_state_reloc(ctx->stream, VIVS_GL_OCCLUSION_QUERY_ADDR, &r);
86    resource_written(ctx, aq->prsc);
87 }
88 
89 static void
occlusion_suspend(struct etna_acc_query * aq,struct etna_context * ctx)90 occlusion_suspend(struct etna_acc_query *aq, struct etna_context *ctx)
91 {
92    /* 0x1DF5E76 is the value used by blob - but any random value will work */
93    etna_set_state(ctx->stream, VIVS_GL_OCCLUSION_QUERY_CONTROL, 0x1DF5E76);
94    resource_written(ctx, aq->prsc);
95    aq->samples++;
96 }
97 
98 static bool
occlusion_result(struct etna_acc_query * aq,void * buf,union pipe_query_result * result)99 occlusion_result(struct etna_acc_query *aq, void *buf,
100                  union pipe_query_result *result)
101 {
102    uint64_t sum = 0;
103    uint64_t *ptr = (uint64_t *)buf;
104 
105    for (unsigned i = 0; i < aq->samples; i++)
106       sum += *(ptr + i);
107 
108    if (aq->base.type == PIPE_QUERY_OCCLUSION_COUNTER)
109       result->u64 = sum;
110    else
111       result->b = !!sum;
112 
113    return true;
114 }
115 
116 const struct etna_acc_sample_provider occlusion_provider = {
117    .supports = occlusion_supports,
118    .allocate = occlusion_allocate,
119    .suspend = occlusion_suspend,
120    .resume = occlusion_resume,
121    .result = occlusion_result,
122 };
123