1bf215546Sopenharmony_ci/* 2bf215546Sopenharmony_ci * Copyright © 2021 Raspberry Pi Ltd 3bf215546Sopenharmony_ci * 4bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a 5bf215546Sopenharmony_ci * copy of this software and associated documentation files (the "Software"), 6bf215546Sopenharmony_ci * to deal in the Software without restriction, including without limitation 7bf215546Sopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8bf215546Sopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the 9bf215546Sopenharmony_ci * Software is furnished to do so, subject to the following conditions: 10bf215546Sopenharmony_ci * 11bf215546Sopenharmony_ci * The above copyright notice and this permission notice (including the next 12bf215546Sopenharmony_ci * paragraph) shall be included in all copies or substantial portions of the 13bf215546Sopenharmony_ci * Software. 14bf215546Sopenharmony_ci * 15bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16bf215546Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17bf215546Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18bf215546Sopenharmony_ci * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19bf215546Sopenharmony_ci * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20bf215546Sopenharmony_ci * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21bf215546Sopenharmony_ci * IN THE SOFTWARE. 22bf215546Sopenharmony_ci */ 23bf215546Sopenharmony_ci 24bf215546Sopenharmony_ci/** 25bf215546Sopenharmony_ci * Gallium query object support for performance counters 26bf215546Sopenharmony_ci * 27bf215546Sopenharmony_ci * This contains the performance V3D counters queries. 28bf215546Sopenharmony_ci */ 29bf215546Sopenharmony_ci 30bf215546Sopenharmony_ci#include "v3d_query.h" 31bf215546Sopenharmony_ci 32bf215546Sopenharmony_cistruct v3d_query_perfcnt 33bf215546Sopenharmony_ci{ 34bf215546Sopenharmony_ci struct v3d_query base; 35bf215546Sopenharmony_ci 36bf215546Sopenharmony_ci unsigned num_queries; 37bf215546Sopenharmony_ci struct v3d_perfmon_state *perfmon; 38bf215546Sopenharmony_ci}; 39bf215546Sopenharmony_ci 40bf215546Sopenharmony_cistatic const char *v3d_counter_names[] = { 41bf215546Sopenharmony_ci "FEP-valid-primitives-no-rendered-pixels", 42bf215546Sopenharmony_ci "FEP-valid-primitives-rendered-pixels", 43bf215546Sopenharmony_ci "FEP-clipped-quads", 44bf215546Sopenharmony_ci "FEP-valid-quads", 45bf215546Sopenharmony_ci "TLB-quads-not-passing-stencil-test", 46bf215546Sopenharmony_ci "TLB-quads-not-passing-z-and-stencil-test", 47bf215546Sopenharmony_ci "TLB-quads-passing-z-and-stencil-test", 48bf215546Sopenharmony_ci "TLB-quads-with-zero-coverage", 49bf215546Sopenharmony_ci "TLB-quads-with-non-zero-coverage", 50bf215546Sopenharmony_ci "TLB-quads-written-to-color-buffer", 51bf215546Sopenharmony_ci "PTB-primitives-discarded-outside-viewport", 52bf215546Sopenharmony_ci "PTB-primitives-need-clipping", 53bf215546Sopenharmony_ci "PTB-primitives-discared-reversed", 54bf215546Sopenharmony_ci "QPU-total-idle-clk-cycles", 55bf215546Sopenharmony_ci "QPU-total-active-clk-cycles-vertex-coord-shading", 56bf215546Sopenharmony_ci "QPU-total-active-clk-cycles-fragment-shading", 57bf215546Sopenharmony_ci "QPU-total-clk-cycles-executing-valid-instr", 58bf215546Sopenharmony_ci "QPU-total-clk-cycles-waiting-TMU", 59bf215546Sopenharmony_ci "QPU-total-clk-cycles-waiting-scoreboard", 60bf215546Sopenharmony_ci "QPU-total-clk-cycles-waiting-varyings", 61bf215546Sopenharmony_ci "QPU-total-instr-cache-hit", 62bf215546Sopenharmony_ci "QPU-total-instr-cache-miss", 63bf215546Sopenharmony_ci "QPU-total-uniform-cache-hit", 64bf215546Sopenharmony_ci "QPU-total-uniform-cache-miss", 65bf215546Sopenharmony_ci "TMU-total-text-quads-access", 66bf215546Sopenharmony_ci "TMU-total-text-cache-miss", 67bf215546Sopenharmony_ci "VPM-total-clk-cycles-VDW-stalled", 68bf215546Sopenharmony_ci "VPM-total-clk-cycles-VCD-stalled", 69bf215546Sopenharmony_ci "CLE-bin-thread-active-cycles", 70bf215546Sopenharmony_ci "CLE-render-thread-active-cycles", 71bf215546Sopenharmony_ci "L2T-total-cache-hit", 72bf215546Sopenharmony_ci "L2T-total-cache-miss", 73bf215546Sopenharmony_ci "cycle-count", 74bf215546Sopenharmony_ci "QPU-total-clk-cycles-waiting-vertex-coord-shading", 75bf215546Sopenharmony_ci "QPU-total-clk-cycles-waiting-fragment-shading", 76bf215546Sopenharmony_ci "PTB-primitives-binned", 77bf215546Sopenharmony_ci "AXI-writes-seen-watch-0", 78bf215546Sopenharmony_ci "AXI-reads-seen-watch-0", 79bf215546Sopenharmony_ci "AXI-writes-stalled-seen-watch-0", 80bf215546Sopenharmony_ci "AXI-reads-stalled-seen-watch-0", 81bf215546Sopenharmony_ci "AXI-write-bytes-seen-watch-0", 82bf215546Sopenharmony_ci "AXI-read-bytes-seen-watch-0", 83bf215546Sopenharmony_ci "AXI-writes-seen-watch-1", 84bf215546Sopenharmony_ci "AXI-reads-seen-watch-1", 85bf215546Sopenharmony_ci "AXI-writes-stalled-seen-watch-1", 86bf215546Sopenharmony_ci "AXI-reads-stalled-seen-watch-1", 87bf215546Sopenharmony_ci "AXI-write-bytes-seen-watch-1", 88bf215546Sopenharmony_ci "AXI-read-bytes-seen-watch-1", 89bf215546Sopenharmony_ci "TLB-partial-quads-written-to-color-buffer", 90bf215546Sopenharmony_ci "TMU-total-config-access", 91bf215546Sopenharmony_ci "L2T-no-id-stalled", 92bf215546Sopenharmony_ci "L2T-command-queue-stalled", 93bf215546Sopenharmony_ci "L2T-TMU-writes", 94bf215546Sopenharmony_ci "TMU-active-cycles", 95bf215546Sopenharmony_ci "TMU-stalled-cycles", 96bf215546Sopenharmony_ci "CLE-thread-active-cycles", 97bf215546Sopenharmony_ci "L2T-TMU-reads", 98bf215546Sopenharmony_ci "L2T-CLE-reads", 99bf215546Sopenharmony_ci "L2T-VCD-reads", 100bf215546Sopenharmony_ci "L2T-TMU-config-reads", 101bf215546Sopenharmony_ci "L2T-SLC0-reads", 102bf215546Sopenharmony_ci "L2T-SLC1-reads", 103bf215546Sopenharmony_ci "L2T-SLC2-reads", 104bf215546Sopenharmony_ci "L2T-TMU-write-miss", 105bf215546Sopenharmony_ci "L2T-TMU-read-miss", 106bf215546Sopenharmony_ci "L2T-CLE-read-miss", 107bf215546Sopenharmony_ci "L2T-VCD-read-miss", 108bf215546Sopenharmony_ci "L2T-TMU-config-read-miss", 109bf215546Sopenharmony_ci "L2T-SLC0-read-miss", 110bf215546Sopenharmony_ci "L2T-SLC1-read-miss", 111bf215546Sopenharmony_ci "L2T-SLC2-read-miss", 112bf215546Sopenharmony_ci "core-memory-writes", 113bf215546Sopenharmony_ci "L2T-memory-writes", 114bf215546Sopenharmony_ci "PTB-memory-writes", 115bf215546Sopenharmony_ci "TLB-memory-writes", 116bf215546Sopenharmony_ci "core-memory-reads", 117bf215546Sopenharmony_ci "L2T-memory-reads", 118bf215546Sopenharmony_ci "PTB-memory-reads", 119bf215546Sopenharmony_ci "PSE-memory-reads", 120bf215546Sopenharmony_ci "TLB-memory-reads", 121bf215546Sopenharmony_ci "GMP-memory-reads", 122bf215546Sopenharmony_ci "PTB-memory-words-writes", 123bf215546Sopenharmony_ci "TLB-memory-words-writes", 124bf215546Sopenharmony_ci "PSE-memory-words-reads", 125bf215546Sopenharmony_ci "TLB-memory-words-reads", 126bf215546Sopenharmony_ci "TMU-MRU-hits", 127bf215546Sopenharmony_ci "compute-active-cycles", 128bf215546Sopenharmony_ci}; 129bf215546Sopenharmony_ci 130bf215546Sopenharmony_cistatic void 131bf215546Sopenharmony_cikperfmon_destroy(struct v3d_context *v3d, struct v3d_perfmon_state *perfmon) 132bf215546Sopenharmony_ci{ 133bf215546Sopenharmony_ci struct drm_v3d_perfmon_destroy destroyreq; 134bf215546Sopenharmony_ci 135bf215546Sopenharmony_ci destroyreq.id = perfmon->kperfmon_id; 136bf215546Sopenharmony_ci int ret = v3d_ioctl(v3d->fd, DRM_IOCTL_V3D_PERFMON_DESTROY, &destroyreq); 137bf215546Sopenharmony_ci if (ret != 0) 138bf215546Sopenharmony_ci fprintf(stderr, "failed to destroy perfmon %d: %s\n", 139bf215546Sopenharmony_ci perfmon->kperfmon_id, strerror(errno)); 140bf215546Sopenharmony_ci} 141bf215546Sopenharmony_ci 142bf215546Sopenharmony_ciint 143bf215546Sopenharmony_civ3d_get_driver_query_group_info_perfcnt(struct v3d_screen *screen, unsigned index, 144bf215546Sopenharmony_ci struct pipe_driver_query_group_info *info) 145bf215546Sopenharmony_ci{ 146bf215546Sopenharmony_ci if (!screen->has_perfmon) 147bf215546Sopenharmony_ci return 0; 148bf215546Sopenharmony_ci 149bf215546Sopenharmony_ci if (!info) 150bf215546Sopenharmony_ci return 1; 151bf215546Sopenharmony_ci 152bf215546Sopenharmony_ci if (index > 0) 153bf215546Sopenharmony_ci return 0; 154bf215546Sopenharmony_ci 155bf215546Sopenharmony_ci info->name = "V3D counters"; 156bf215546Sopenharmony_ci info->max_active_queries = DRM_V3D_MAX_PERF_COUNTERS; 157bf215546Sopenharmony_ci info->num_queries = ARRAY_SIZE(v3d_counter_names); 158bf215546Sopenharmony_ci 159bf215546Sopenharmony_ci return 1; 160bf215546Sopenharmony_ci} 161bf215546Sopenharmony_ci 162bf215546Sopenharmony_ciint 163bf215546Sopenharmony_civ3d_get_driver_query_info_perfcnt(struct v3d_screen *screen, unsigned index, 164bf215546Sopenharmony_ci struct pipe_driver_query_info *info) 165bf215546Sopenharmony_ci{ 166bf215546Sopenharmony_ci if (!screen->has_perfmon) 167bf215546Sopenharmony_ci return 0; 168bf215546Sopenharmony_ci 169bf215546Sopenharmony_ci if (!info) 170bf215546Sopenharmony_ci return ARRAY_SIZE(v3d_counter_names); 171bf215546Sopenharmony_ci 172bf215546Sopenharmony_ci if (index >= ARRAY_SIZE(v3d_counter_names)) 173bf215546Sopenharmony_ci return 0; 174bf215546Sopenharmony_ci 175bf215546Sopenharmony_ci info->group_id = 0; 176bf215546Sopenharmony_ci info->name = v3d_counter_names[index]; 177bf215546Sopenharmony_ci info->query_type = PIPE_QUERY_DRIVER_SPECIFIC + index; 178bf215546Sopenharmony_ci info->result_type = PIPE_DRIVER_QUERY_RESULT_TYPE_CUMULATIVE; 179bf215546Sopenharmony_ci info->type = PIPE_DRIVER_QUERY_TYPE_UINT64; 180bf215546Sopenharmony_ci info->flags = PIPE_DRIVER_QUERY_FLAG_BATCH; 181bf215546Sopenharmony_ci 182bf215546Sopenharmony_ci return 1; 183bf215546Sopenharmony_ci} 184bf215546Sopenharmony_ci 185bf215546Sopenharmony_cistatic void 186bf215546Sopenharmony_civ3d_destroy_query_perfcnt(struct v3d_context *v3d, struct v3d_query *query) 187bf215546Sopenharmony_ci{ 188bf215546Sopenharmony_ci struct v3d_query_perfcnt *pquery = (struct v3d_query_perfcnt *)query; 189bf215546Sopenharmony_ci 190bf215546Sopenharmony_ci assert(pquery->perfmon); 191bf215546Sopenharmony_ci 192bf215546Sopenharmony_ci if (v3d->active_perfmon == pquery->perfmon) { 193bf215546Sopenharmony_ci fprintf(stderr, "Query is active; end query before destroying\n"); 194bf215546Sopenharmony_ci return; 195bf215546Sopenharmony_ci } 196bf215546Sopenharmony_ci if (pquery->perfmon->kperfmon_id) 197bf215546Sopenharmony_ci kperfmon_destroy(v3d, pquery->perfmon); 198bf215546Sopenharmony_ci 199bf215546Sopenharmony_ci v3d_fence_unreference(&pquery->perfmon->last_job_fence); 200bf215546Sopenharmony_ci free(pquery->perfmon); 201bf215546Sopenharmony_ci free(query); 202bf215546Sopenharmony_ci} 203bf215546Sopenharmony_ci 204bf215546Sopenharmony_cistatic bool 205bf215546Sopenharmony_civ3d_begin_query_perfcnt(struct v3d_context *v3d, struct v3d_query *query) 206bf215546Sopenharmony_ci{ 207bf215546Sopenharmony_ci struct v3d_query_perfcnt *pquery = (struct v3d_query_perfcnt *)query; 208bf215546Sopenharmony_ci struct drm_v3d_perfmon_create createreq = { 0 }; 209bf215546Sopenharmony_ci int i, ret; 210bf215546Sopenharmony_ci 211bf215546Sopenharmony_ci /* Only one perfmon can be activated per context */ 212bf215546Sopenharmony_ci if (v3d->active_perfmon) { 213bf215546Sopenharmony_ci fprintf(stderr, 214bf215546Sopenharmony_ci "Another query is already active; " 215bf215546Sopenharmony_ci "finish it before starting a new one\n"); 216bf215546Sopenharmony_ci return false; 217bf215546Sopenharmony_ci } 218bf215546Sopenharmony_ci 219bf215546Sopenharmony_ci assert(pquery->perfmon); 220bf215546Sopenharmony_ci 221bf215546Sopenharmony_ci /* Reset the counters by destroying the previously allocated perfmon */ 222bf215546Sopenharmony_ci if (pquery->perfmon->kperfmon_id) 223bf215546Sopenharmony_ci kperfmon_destroy(v3d, pquery->perfmon); 224bf215546Sopenharmony_ci 225bf215546Sopenharmony_ci for (i = 0; i < pquery->num_queries; i++) 226bf215546Sopenharmony_ci createreq.counters[i] = pquery->perfmon->counters[i]; 227bf215546Sopenharmony_ci 228bf215546Sopenharmony_ci createreq.ncounters = pquery->num_queries; 229bf215546Sopenharmony_ci ret = v3d_ioctl(v3d->fd, DRM_IOCTL_V3D_PERFMON_CREATE, &createreq); 230bf215546Sopenharmony_ci if (ret != 0) 231bf215546Sopenharmony_ci return false; 232bf215546Sopenharmony_ci 233bf215546Sopenharmony_ci pquery->perfmon->kperfmon_id = createreq.id; 234bf215546Sopenharmony_ci pquery->perfmon->job_submitted = false; 235bf215546Sopenharmony_ci v3d_fence_unreference(&pquery->perfmon->last_job_fence); 236bf215546Sopenharmony_ci 237bf215546Sopenharmony_ci /* Ensure all pending jobs are flushed before activating the 238bf215546Sopenharmony_ci * perfmon 239bf215546Sopenharmony_ci */ 240bf215546Sopenharmony_ci v3d_flush((struct pipe_context *)v3d); 241bf215546Sopenharmony_ci v3d->active_perfmon = pquery->perfmon; 242bf215546Sopenharmony_ci 243bf215546Sopenharmony_ci return true; 244bf215546Sopenharmony_ci} 245bf215546Sopenharmony_ci 246bf215546Sopenharmony_cistatic bool 247bf215546Sopenharmony_civ3d_end_query_perfcnt(struct v3d_context *v3d, struct v3d_query *query) 248bf215546Sopenharmony_ci{ 249bf215546Sopenharmony_ci struct v3d_query_perfcnt *pquery = (struct v3d_query_perfcnt *)query; 250bf215546Sopenharmony_ci 251bf215546Sopenharmony_ci assert(pquery->perfmon); 252bf215546Sopenharmony_ci 253bf215546Sopenharmony_ci if (v3d->active_perfmon != pquery->perfmon) { 254bf215546Sopenharmony_ci fprintf(stderr, "This query is not active\n"); 255bf215546Sopenharmony_ci return false; 256bf215546Sopenharmony_ci } 257bf215546Sopenharmony_ci 258bf215546Sopenharmony_ci /* Ensure all pending jobs are flushed before deactivating the 259bf215546Sopenharmony_ci * perfmon 260bf215546Sopenharmony_ci */ 261bf215546Sopenharmony_ci v3d_flush((struct pipe_context *)v3d); 262bf215546Sopenharmony_ci 263bf215546Sopenharmony_ci /* Get a copy of latest submitted job's fence to wait for its 264bf215546Sopenharmony_ci * completion 265bf215546Sopenharmony_ci */ 266bf215546Sopenharmony_ci if (v3d->active_perfmon->job_submitted) 267bf215546Sopenharmony_ci v3d->active_perfmon->last_job_fence = v3d_fence_create(v3d); 268bf215546Sopenharmony_ci 269bf215546Sopenharmony_ci v3d->active_perfmon = NULL; 270bf215546Sopenharmony_ci 271bf215546Sopenharmony_ci return true; 272bf215546Sopenharmony_ci} 273bf215546Sopenharmony_ci 274bf215546Sopenharmony_cistatic bool 275bf215546Sopenharmony_civ3d_get_query_result_perfcnt(struct v3d_context *v3d, struct v3d_query *query, 276bf215546Sopenharmony_ci bool wait, union pipe_query_result *vresult) 277bf215546Sopenharmony_ci{ 278bf215546Sopenharmony_ci struct v3d_query_perfcnt *pquery = (struct v3d_query_perfcnt *)query; 279bf215546Sopenharmony_ci struct drm_v3d_perfmon_get_values req = { 0 }; 280bf215546Sopenharmony_ci int i, ret; 281bf215546Sopenharmony_ci 282bf215546Sopenharmony_ci assert(pquery->perfmon); 283bf215546Sopenharmony_ci 284bf215546Sopenharmony_ci if (pquery->perfmon->job_submitted) { 285bf215546Sopenharmony_ci if (!v3d_fence_wait(v3d->screen, 286bf215546Sopenharmony_ci pquery->perfmon->last_job_fence, 287bf215546Sopenharmony_ci wait ? PIPE_TIMEOUT_INFINITE : 0)) 288bf215546Sopenharmony_ci return false; 289bf215546Sopenharmony_ci 290bf215546Sopenharmony_ci req.id = pquery->perfmon->kperfmon_id; 291bf215546Sopenharmony_ci req.values_ptr = (uintptr_t)pquery->perfmon->values; 292bf215546Sopenharmony_ci ret = v3d_ioctl(v3d->fd, DRM_IOCTL_V3D_PERFMON_GET_VALUES, &req); 293bf215546Sopenharmony_ci if (ret != 0) { 294bf215546Sopenharmony_ci fprintf(stderr, "Can't request perfmon counters values\n"); 295bf215546Sopenharmony_ci return false; 296bf215546Sopenharmony_ci } 297bf215546Sopenharmony_ci } 298bf215546Sopenharmony_ci 299bf215546Sopenharmony_ci for (i = 0; i < pquery->num_queries; i++) 300bf215546Sopenharmony_ci vresult->batch[i].u64 = pquery->perfmon->values[i]; 301bf215546Sopenharmony_ci 302bf215546Sopenharmony_ci return true; 303bf215546Sopenharmony_ci} 304bf215546Sopenharmony_ci 305bf215546Sopenharmony_cistatic const struct v3d_query_funcs perfcnt_query_funcs = { 306bf215546Sopenharmony_ci .destroy_query = v3d_destroy_query_perfcnt, 307bf215546Sopenharmony_ci .begin_query = v3d_begin_query_perfcnt, 308bf215546Sopenharmony_ci .end_query = v3d_end_query_perfcnt, 309bf215546Sopenharmony_ci .get_query_result = v3d_get_query_result_perfcnt, 310bf215546Sopenharmony_ci}; 311bf215546Sopenharmony_ci 312bf215546Sopenharmony_cistruct pipe_query * 313bf215546Sopenharmony_civ3d_create_batch_query_perfcnt(struct v3d_context *v3d, unsigned num_queries, 314bf215546Sopenharmony_ci unsigned *query_types) 315bf215546Sopenharmony_ci{ 316bf215546Sopenharmony_ci struct v3d_query_perfcnt *pquery = NULL; 317bf215546Sopenharmony_ci struct v3d_query *query; 318bf215546Sopenharmony_ci struct v3d_perfmon_state *perfmon = NULL; 319bf215546Sopenharmony_ci int i; 320bf215546Sopenharmony_ci 321bf215546Sopenharmony_ci /* Validate queries */ 322bf215546Sopenharmony_ci for (i = 0; i < num_queries; i++) { 323bf215546Sopenharmony_ci if (query_types[i] < PIPE_QUERY_DRIVER_SPECIFIC || 324bf215546Sopenharmony_ci query_types[i] >= PIPE_QUERY_DRIVER_SPECIFIC + 325bf215546Sopenharmony_ci ARRAY_SIZE(v3d_counter_names)) { 326bf215546Sopenharmony_ci fprintf(stderr, "Invalid query type\n"); 327bf215546Sopenharmony_ci return NULL; 328bf215546Sopenharmony_ci } 329bf215546Sopenharmony_ci } 330bf215546Sopenharmony_ci 331bf215546Sopenharmony_ci pquery = calloc(1, sizeof(*pquery)); 332bf215546Sopenharmony_ci if (!pquery) 333bf215546Sopenharmony_ci return NULL; 334bf215546Sopenharmony_ci 335bf215546Sopenharmony_ci perfmon = calloc(1, sizeof(*perfmon)); 336bf215546Sopenharmony_ci if (!perfmon) { 337bf215546Sopenharmony_ci free(pquery); 338bf215546Sopenharmony_ci return NULL; 339bf215546Sopenharmony_ci } 340bf215546Sopenharmony_ci 341bf215546Sopenharmony_ci for (i = 0; i < num_queries; i++) 342bf215546Sopenharmony_ci perfmon->counters[i] = query_types[i] - PIPE_QUERY_DRIVER_SPECIFIC; 343bf215546Sopenharmony_ci 344bf215546Sopenharmony_ci pquery->perfmon = perfmon; 345bf215546Sopenharmony_ci pquery->num_queries = num_queries; 346bf215546Sopenharmony_ci 347bf215546Sopenharmony_ci query = &pquery->base; 348bf215546Sopenharmony_ci query->funcs = &perfcnt_query_funcs; 349bf215546Sopenharmony_ci 350bf215546Sopenharmony_ci /* Note that struct pipe_query isn't actually defined anywhere. */ 351bf215546Sopenharmony_ci return (struct pipe_query *)query; 352bf215546Sopenharmony_ci} 353