1bf215546Sopenharmony_ci/*
2bf215546Sopenharmony_ci * Copyright © 2012-2017 Intel Corporation
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
21bf215546Sopenharmony_ci * DEALINGS IN THE SOFTWARE.
22bf215546Sopenharmony_ci */
23bf215546Sopenharmony_ci
24bf215546Sopenharmony_ci/**
25bf215546Sopenharmony_ci * \file performance_query.c
26bf215546Sopenharmony_ci * Core Mesa support for the INTEL_performance_query extension.
27bf215546Sopenharmony_ci */
28bf215546Sopenharmony_ci
29bf215546Sopenharmony_ci#include <stdbool.h>
30bf215546Sopenharmony_ci#include "glheader.h"
31bf215546Sopenharmony_ci#include "context.h"
32bf215546Sopenharmony_ci#include "enums.h"
33bf215546Sopenharmony_ci#include "hash.h"
34bf215546Sopenharmony_ci#include "macros.h"
35bf215546Sopenharmony_ci#include "mtypes.h"
36bf215546Sopenharmony_ci#include "performance_query.h"
37bf215546Sopenharmony_ci#include "util/ralloc.h"
38bf215546Sopenharmony_ci#include "api_exec_decl.h"
39bf215546Sopenharmony_ci
40bf215546Sopenharmony_ci#include "pipe/p_context.h"
41bf215546Sopenharmony_ci
42bf215546Sopenharmony_ci#include "state_tracker/st_cb_flush.h"
43bf215546Sopenharmony_ci
44bf215546Sopenharmony_civoid
45bf215546Sopenharmony_ci_mesa_init_performance_queries(struct gl_context *ctx)
46bf215546Sopenharmony_ci{
47bf215546Sopenharmony_ci   ctx->PerfQuery.Objects = _mesa_NewHashTable();
48bf215546Sopenharmony_ci}
49bf215546Sopenharmony_ci
50bf215546Sopenharmony_cistatic void
51bf215546Sopenharmony_cifree_performance_query(void *data, void *user)
52bf215546Sopenharmony_ci{
53bf215546Sopenharmony_ci   struct gl_perf_query_object *m = data;
54bf215546Sopenharmony_ci   struct gl_context *ctx = user;
55bf215546Sopenharmony_ci
56bf215546Sopenharmony_ci   /* Don't confuse the implementation by deleting an active query. We can
57bf215546Sopenharmony_ci    * toggle Active/Used to false because we're tearing down the GL context
58bf215546Sopenharmony_ci    * and it's already idle (see _mesa_free_context_data).
59bf215546Sopenharmony_ci    */
60bf215546Sopenharmony_ci   m->Active = false;
61bf215546Sopenharmony_ci   m->Used = false;
62bf215546Sopenharmony_ci   ctx->pipe->delete_intel_perf_query(ctx->pipe, (struct pipe_query *)m);
63bf215546Sopenharmony_ci}
64bf215546Sopenharmony_ci
65bf215546Sopenharmony_civoid
66bf215546Sopenharmony_ci_mesa_free_performance_queries(struct gl_context *ctx)
67bf215546Sopenharmony_ci{
68bf215546Sopenharmony_ci   _mesa_HashDeleteAll(ctx->PerfQuery.Objects,
69bf215546Sopenharmony_ci                       free_performance_query, ctx);
70bf215546Sopenharmony_ci   _mesa_DeleteHashTable(ctx->PerfQuery.Objects);
71bf215546Sopenharmony_ci}
72bf215546Sopenharmony_ci
73bf215546Sopenharmony_cistatic inline struct gl_perf_query_object *
74bf215546Sopenharmony_cilookup_object(struct gl_context *ctx, GLuint id)
75bf215546Sopenharmony_ci{
76bf215546Sopenharmony_ci   return _mesa_HashLookup(ctx->PerfQuery.Objects, id);
77bf215546Sopenharmony_ci}
78bf215546Sopenharmony_ci
79bf215546Sopenharmony_cistatic GLuint
80bf215546Sopenharmony_ciinit_performance_query_info(struct gl_context *ctx)
81bf215546Sopenharmony_ci{
82bf215546Sopenharmony_ci   return ctx->pipe->init_intel_perf_query_info(ctx->pipe);
83bf215546Sopenharmony_ci}
84bf215546Sopenharmony_ci
85bf215546Sopenharmony_ci/* For INTEL_performance_query, query id 0 is reserved to be invalid. */
86bf215546Sopenharmony_cistatic inline unsigned
87bf215546Sopenharmony_ciqueryid_to_index(GLuint queryid)
88bf215546Sopenharmony_ci{
89bf215546Sopenharmony_ci   return queryid - 1;
90bf215546Sopenharmony_ci}
91bf215546Sopenharmony_ci
92bf215546Sopenharmony_cistatic inline GLuint
93bf215546Sopenharmony_ciindex_to_queryid(unsigned index)
94bf215546Sopenharmony_ci{
95bf215546Sopenharmony_ci   return index + 1;
96bf215546Sopenharmony_ci}
97bf215546Sopenharmony_ci
98bf215546Sopenharmony_cistatic inline bool
99bf215546Sopenharmony_ciqueryid_valid(const struct gl_context *ctx, unsigned numQueries, GLuint queryid)
100bf215546Sopenharmony_ci{
101bf215546Sopenharmony_ci   /* The GL_INTEL_performance_query spec says:
102bf215546Sopenharmony_ci    *
103bf215546Sopenharmony_ci    *  "Performance counter ids values start with 1. Performance counter id 0
104bf215546Sopenharmony_ci    *  is reserved as an invalid counter."
105bf215546Sopenharmony_ci    */
106bf215546Sopenharmony_ci   return queryid != 0 && queryid_to_index(queryid) < numQueries;
107bf215546Sopenharmony_ci}
108bf215546Sopenharmony_ci
109bf215546Sopenharmony_cistatic inline GLuint
110bf215546Sopenharmony_cicounterid_to_index(GLuint counterid)
111bf215546Sopenharmony_ci{
112bf215546Sopenharmony_ci   return counterid - 1;
113bf215546Sopenharmony_ci}
114bf215546Sopenharmony_ci
115bf215546Sopenharmony_cistatic void
116bf215546Sopenharmony_cioutput_clipped_string(GLchar *stringRet,
117bf215546Sopenharmony_ci                      GLuint stringMaxLen,
118bf215546Sopenharmony_ci                      const char *string)
119bf215546Sopenharmony_ci{
120bf215546Sopenharmony_ci   if (!stringRet)
121bf215546Sopenharmony_ci      return;
122bf215546Sopenharmony_ci
123bf215546Sopenharmony_ci   strncpy(stringRet, string ? string : "", stringMaxLen);
124bf215546Sopenharmony_ci
125bf215546Sopenharmony_ci   /* No specification given about whether returned strings needs
126bf215546Sopenharmony_ci    * to be zero-terminated. Zero-terminate the string always as we
127bf215546Sopenharmony_ci    * don't otherwise communicate the length of the returned
128bf215546Sopenharmony_ci    * string.
129bf215546Sopenharmony_ci    */
130bf215546Sopenharmony_ci   if (stringMaxLen > 0)
131bf215546Sopenharmony_ci      stringRet[stringMaxLen - 1] = '\0';
132bf215546Sopenharmony_ci}
133bf215546Sopenharmony_ci
134bf215546Sopenharmony_ci/*****************************************************************************/
135bf215546Sopenharmony_ci
136bf215546Sopenharmony_ciextern void GLAPIENTRY
137bf215546Sopenharmony_ci_mesa_GetFirstPerfQueryIdINTEL(GLuint *queryId)
138bf215546Sopenharmony_ci{
139bf215546Sopenharmony_ci   GET_CURRENT_CONTEXT(ctx);
140bf215546Sopenharmony_ci
141bf215546Sopenharmony_ci   unsigned numQueries;
142bf215546Sopenharmony_ci
143bf215546Sopenharmony_ci   /* The GL_INTEL_performance_query spec says:
144bf215546Sopenharmony_ci    *
145bf215546Sopenharmony_ci    *    "If queryId pointer is equal to 0, INVALID_VALUE error is generated."
146bf215546Sopenharmony_ci    */
147bf215546Sopenharmony_ci   if (!queryId) {
148bf215546Sopenharmony_ci      _mesa_error(ctx, GL_INVALID_VALUE,
149bf215546Sopenharmony_ci                  "glGetFirstPerfQueryIdINTEL(queryId == NULL)");
150bf215546Sopenharmony_ci      return;
151bf215546Sopenharmony_ci   }
152bf215546Sopenharmony_ci
153bf215546Sopenharmony_ci   numQueries = init_performance_query_info(ctx);
154bf215546Sopenharmony_ci
155bf215546Sopenharmony_ci   /* The GL_INTEL_performance_query spec says:
156bf215546Sopenharmony_ci    *
157bf215546Sopenharmony_ci    *    "If the given hardware platform doesn't support any performance
158bf215546Sopenharmony_ci    *    queries, then the value of 0 is returned and INVALID_OPERATION error
159bf215546Sopenharmony_ci    *    is raised."
160bf215546Sopenharmony_ci    */
161bf215546Sopenharmony_ci   if (numQueries == 0) {
162bf215546Sopenharmony_ci      *queryId = 0;
163bf215546Sopenharmony_ci      _mesa_error(ctx, GL_INVALID_OPERATION,
164bf215546Sopenharmony_ci                  "glGetFirstPerfQueryIdINTEL(no queries supported)");
165bf215546Sopenharmony_ci      return;
166bf215546Sopenharmony_ci   }
167bf215546Sopenharmony_ci
168bf215546Sopenharmony_ci   *queryId = index_to_queryid(0);
169bf215546Sopenharmony_ci}
170bf215546Sopenharmony_ci
171bf215546Sopenharmony_ciextern void GLAPIENTRY
172bf215546Sopenharmony_ci_mesa_GetNextPerfQueryIdINTEL(GLuint queryId, GLuint *nextQueryId)
173bf215546Sopenharmony_ci{
174bf215546Sopenharmony_ci   GET_CURRENT_CONTEXT(ctx);
175bf215546Sopenharmony_ci
176bf215546Sopenharmony_ci   unsigned numQueries;
177bf215546Sopenharmony_ci
178bf215546Sopenharmony_ci   /* The GL_INTEL_performance_query spec says:
179bf215546Sopenharmony_ci    *
180bf215546Sopenharmony_ci    *    "The result is passed in location pointed by nextQueryId. If query
181bf215546Sopenharmony_ci    *    identified by queryId is the last query available the value of 0 is
182bf215546Sopenharmony_ci    *    returned. If the specified performance query identifier is invalid
183bf215546Sopenharmony_ci    *    then INVALID_VALUE error is generated. If nextQueryId pointer is
184bf215546Sopenharmony_ci    *    equal to 0, an INVALID_VALUE error is generated.  Whenever error is
185bf215546Sopenharmony_ci    *    generated, the value of 0 is returned."
186bf215546Sopenharmony_ci    */
187bf215546Sopenharmony_ci
188bf215546Sopenharmony_ci   if (!nextQueryId) {
189bf215546Sopenharmony_ci      _mesa_error(ctx, GL_INVALID_VALUE,
190bf215546Sopenharmony_ci                  "glGetNextPerfQueryIdINTEL(nextQueryId == NULL)");
191bf215546Sopenharmony_ci      return;
192bf215546Sopenharmony_ci   }
193bf215546Sopenharmony_ci
194bf215546Sopenharmony_ci   numQueries = init_performance_query_info(ctx);
195bf215546Sopenharmony_ci
196bf215546Sopenharmony_ci   if (!queryid_valid(ctx, numQueries, queryId)) {
197bf215546Sopenharmony_ci      _mesa_error(ctx, GL_INVALID_VALUE,
198bf215546Sopenharmony_ci                  "glGetNextPerfQueryIdINTEL(invalid query)");
199bf215546Sopenharmony_ci      return;
200bf215546Sopenharmony_ci   }
201bf215546Sopenharmony_ci
202bf215546Sopenharmony_ci   if (queryid_valid(ctx, numQueries, ++queryId))
203bf215546Sopenharmony_ci      *nextQueryId = queryId;
204bf215546Sopenharmony_ci   else
205bf215546Sopenharmony_ci      *nextQueryId = 0;
206bf215546Sopenharmony_ci}
207bf215546Sopenharmony_ci
208bf215546Sopenharmony_ciextern void GLAPIENTRY
209bf215546Sopenharmony_ci_mesa_GetPerfQueryIdByNameINTEL(char *queryName, GLuint *queryId)
210bf215546Sopenharmony_ci{
211bf215546Sopenharmony_ci   GET_CURRENT_CONTEXT(ctx);
212bf215546Sopenharmony_ci
213bf215546Sopenharmony_ci   unsigned numQueries;
214bf215546Sopenharmony_ci   unsigned i;
215bf215546Sopenharmony_ci
216bf215546Sopenharmony_ci   /* The GL_INTEL_performance_query spec says:
217bf215546Sopenharmony_ci    *
218bf215546Sopenharmony_ci    *    "If queryName does not reference a valid query name, an INVALID_VALUE
219bf215546Sopenharmony_ci    *    error is generated."
220bf215546Sopenharmony_ci    */
221bf215546Sopenharmony_ci   if (!queryName) {
222bf215546Sopenharmony_ci      _mesa_error(ctx, GL_INVALID_VALUE,
223bf215546Sopenharmony_ci                  "glGetPerfQueryIdByNameINTEL(queryName == NULL)");
224bf215546Sopenharmony_ci      return;
225bf215546Sopenharmony_ci   }
226bf215546Sopenharmony_ci
227bf215546Sopenharmony_ci   /* The specification does not state that this produces an error but
228bf215546Sopenharmony_ci    * to be consistent with glGetFirstPerfQueryIdINTEL we generate an
229bf215546Sopenharmony_ci    * INVALID_VALUE error
230bf215546Sopenharmony_ci    */
231bf215546Sopenharmony_ci   if (!queryId) {
232bf215546Sopenharmony_ci      _mesa_error(ctx, GL_INVALID_VALUE,
233bf215546Sopenharmony_ci                  "glGetPerfQueryIdByNameINTEL(queryId == NULL)");
234bf215546Sopenharmony_ci      return;
235bf215546Sopenharmony_ci   }
236bf215546Sopenharmony_ci
237bf215546Sopenharmony_ci   numQueries = init_performance_query_info(ctx);
238bf215546Sopenharmony_ci
239bf215546Sopenharmony_ci   for (i = 0; i < numQueries; ++i) {
240bf215546Sopenharmony_ci      const GLchar *name;
241bf215546Sopenharmony_ci      GLuint ignore;
242bf215546Sopenharmony_ci
243bf215546Sopenharmony_ci      ctx->pipe->get_intel_perf_query_info(ctx->pipe, i, &name,
244bf215546Sopenharmony_ci                                           &ignore, &ignore, &ignore);
245bf215546Sopenharmony_ci
246bf215546Sopenharmony_ci      if (strcmp(name, queryName) == 0) {
247bf215546Sopenharmony_ci         *queryId = index_to_queryid(i);
248bf215546Sopenharmony_ci         return;
249bf215546Sopenharmony_ci      }
250bf215546Sopenharmony_ci   }
251bf215546Sopenharmony_ci
252bf215546Sopenharmony_ci   _mesa_error(ctx, GL_INVALID_VALUE,
253bf215546Sopenharmony_ci               "glGetPerfQueryIdByNameINTEL(invalid query name)");
254bf215546Sopenharmony_ci}
255bf215546Sopenharmony_ci
256bf215546Sopenharmony_ciextern void GLAPIENTRY
257bf215546Sopenharmony_ci_mesa_GetPerfQueryInfoINTEL(GLuint queryId,
258bf215546Sopenharmony_ci                            GLuint nameLength, GLchar *name,
259bf215546Sopenharmony_ci                            GLuint *dataSize,
260bf215546Sopenharmony_ci                            GLuint *numCounters,
261bf215546Sopenharmony_ci                            GLuint *numActive,
262bf215546Sopenharmony_ci                            GLuint *capsMask)
263bf215546Sopenharmony_ci{
264bf215546Sopenharmony_ci   GET_CURRENT_CONTEXT(ctx);
265bf215546Sopenharmony_ci
266bf215546Sopenharmony_ci   unsigned numQueries = init_performance_query_info(ctx);
267bf215546Sopenharmony_ci   unsigned queryIndex = queryid_to_index(queryId);
268bf215546Sopenharmony_ci   const char *queryName;
269bf215546Sopenharmony_ci   GLuint queryDataSize;
270bf215546Sopenharmony_ci   GLuint queryNumCounters;
271bf215546Sopenharmony_ci   GLuint queryNumActive;
272bf215546Sopenharmony_ci
273bf215546Sopenharmony_ci   if (!queryid_valid(ctx, numQueries, queryId)) {
274bf215546Sopenharmony_ci      /* The GL_INTEL_performance_query spec says:
275bf215546Sopenharmony_ci       *
276bf215546Sopenharmony_ci       *    "If queryId does not reference a valid query type, an
277bf215546Sopenharmony_ci       *    INVALID_VALUE error is generated."
278bf215546Sopenharmony_ci       */
279bf215546Sopenharmony_ci      _mesa_error(ctx, GL_INVALID_VALUE,
280bf215546Sopenharmony_ci                  "glGetPerfQueryInfoINTEL(invalid query)");
281bf215546Sopenharmony_ci      return;
282bf215546Sopenharmony_ci   }
283bf215546Sopenharmony_ci
284bf215546Sopenharmony_ci   ctx->pipe->get_intel_perf_query_info(ctx->pipe, queryIndex, &queryName,
285bf215546Sopenharmony_ci                                        &queryDataSize, &queryNumCounters,
286bf215546Sopenharmony_ci                                        &queryNumActive);
287bf215546Sopenharmony_ci
288bf215546Sopenharmony_ci   output_clipped_string(name, nameLength, queryName);
289bf215546Sopenharmony_ci
290bf215546Sopenharmony_ci   if (dataSize)
291bf215546Sopenharmony_ci      *dataSize = queryDataSize;
292bf215546Sopenharmony_ci
293bf215546Sopenharmony_ci   if (numCounters)
294bf215546Sopenharmony_ci      *numCounters = queryNumCounters;
295bf215546Sopenharmony_ci
296bf215546Sopenharmony_ci   /* The GL_INTEL_performance_query spec says:
297bf215546Sopenharmony_ci    *
298bf215546Sopenharmony_ci    *    "-- the actual number of already created query instances in
299bf215546Sopenharmony_ci    *    maxInstances location"
300bf215546Sopenharmony_ci    *
301bf215546Sopenharmony_ci    * 1) Typo in the specification, should be noActiveInstances.
302bf215546Sopenharmony_ci    * 2) Another typo in the specification, maxInstances parameter is not listed
303bf215546Sopenharmony_ci    *    in the declaration of this function in the list of new functions.
304bf215546Sopenharmony_ci    */
305bf215546Sopenharmony_ci   if (numActive)
306bf215546Sopenharmony_ci      *numActive = queryNumActive;
307bf215546Sopenharmony_ci
308bf215546Sopenharmony_ci   /* Assume for now that all queries are per-context */
309bf215546Sopenharmony_ci   if (capsMask)
310bf215546Sopenharmony_ci      *capsMask = GL_PERFQUERY_SINGLE_CONTEXT_INTEL;
311bf215546Sopenharmony_ci}
312bf215546Sopenharmony_ci
313bf215546Sopenharmony_cistatic uint32_t
314bf215546Sopenharmony_cipipe_counter_type_enum_to_gl_type(enum pipe_perf_counter_type type)
315bf215546Sopenharmony_ci{
316bf215546Sopenharmony_ci   switch (type) {
317bf215546Sopenharmony_ci   case PIPE_PERF_COUNTER_TYPE_EVENT: return GL_PERFQUERY_COUNTER_EVENT_INTEL;
318bf215546Sopenharmony_ci   case PIPE_PERF_COUNTER_TYPE_DURATION_NORM: return GL_PERFQUERY_COUNTER_DURATION_NORM_INTEL;
319bf215546Sopenharmony_ci   case PIPE_PERF_COUNTER_TYPE_DURATION_RAW: return GL_PERFQUERY_COUNTER_DURATION_RAW_INTEL;
320bf215546Sopenharmony_ci   case PIPE_PERF_COUNTER_TYPE_THROUGHPUT: return GL_PERFQUERY_COUNTER_THROUGHPUT_INTEL;
321bf215546Sopenharmony_ci   case PIPE_PERF_COUNTER_TYPE_RAW: return GL_PERFQUERY_COUNTER_RAW_INTEL;
322bf215546Sopenharmony_ci   case PIPE_PERF_COUNTER_TYPE_TIMESTAMP: return GL_PERFQUERY_COUNTER_TIMESTAMP_INTEL;
323bf215546Sopenharmony_ci   default:
324bf215546Sopenharmony_ci      unreachable("Unknown counter type");
325bf215546Sopenharmony_ci   }
326bf215546Sopenharmony_ci}
327bf215546Sopenharmony_ci
328bf215546Sopenharmony_cistatic uint32_t
329bf215546Sopenharmony_cipipe_counter_data_type_to_gl_type(enum pipe_perf_counter_data_type type)
330bf215546Sopenharmony_ci{
331bf215546Sopenharmony_ci   switch (type) {
332bf215546Sopenharmony_ci   case PIPE_PERF_COUNTER_DATA_TYPE_BOOL32: return GL_PERFQUERY_COUNTER_DATA_BOOL32_INTEL;
333bf215546Sopenharmony_ci   case PIPE_PERF_COUNTER_DATA_TYPE_UINT32: return GL_PERFQUERY_COUNTER_DATA_UINT32_INTEL;
334bf215546Sopenharmony_ci   case PIPE_PERF_COUNTER_DATA_TYPE_UINT64: return GL_PERFQUERY_COUNTER_DATA_UINT64_INTEL;
335bf215546Sopenharmony_ci   case PIPE_PERF_COUNTER_DATA_TYPE_FLOAT: return GL_PERFQUERY_COUNTER_DATA_FLOAT_INTEL;
336bf215546Sopenharmony_ci   case PIPE_PERF_COUNTER_DATA_TYPE_DOUBLE: return GL_PERFQUERY_COUNTER_DATA_DOUBLE_INTEL;
337bf215546Sopenharmony_ci   default:
338bf215546Sopenharmony_ci      unreachable("Unknown counter data type");
339bf215546Sopenharmony_ci   }
340bf215546Sopenharmony_ci}
341bf215546Sopenharmony_ci
342bf215546Sopenharmony_cistatic void
343bf215546Sopenharmony_ciget_perf_counter_info(struct gl_context *ctx,
344bf215546Sopenharmony_ci                      unsigned query_index,
345bf215546Sopenharmony_ci                      unsigned counter_index,
346bf215546Sopenharmony_ci                      const char **name,
347bf215546Sopenharmony_ci                      const char **desc,
348bf215546Sopenharmony_ci                      GLuint *offset,
349bf215546Sopenharmony_ci                      GLuint *data_size,
350bf215546Sopenharmony_ci                      GLuint *type_enum,
351bf215546Sopenharmony_ci                      GLuint *data_type_enum,
352bf215546Sopenharmony_ci                      GLuint64 *raw_max)
353bf215546Sopenharmony_ci{
354bf215546Sopenharmony_ci   struct pipe_context *pipe = ctx->pipe;
355bf215546Sopenharmony_ci   uint32_t pipe_type_enum;
356bf215546Sopenharmony_ci   uint32_t pipe_data_type_enum;
357bf215546Sopenharmony_ci
358bf215546Sopenharmony_ci   pipe->get_intel_perf_query_counter_info(pipe, query_index, counter_index,
359bf215546Sopenharmony_ci                                           name, desc, offset, data_size,
360bf215546Sopenharmony_ci                                           &pipe_type_enum, &pipe_data_type_enum, raw_max);
361bf215546Sopenharmony_ci   *type_enum = pipe_counter_type_enum_to_gl_type(pipe_type_enum);
362bf215546Sopenharmony_ci   *data_type_enum = pipe_counter_data_type_to_gl_type(pipe_data_type_enum);
363bf215546Sopenharmony_ci}
364bf215546Sopenharmony_ci
365bf215546Sopenharmony_ciextern void GLAPIENTRY
366bf215546Sopenharmony_ci_mesa_GetPerfCounterInfoINTEL(GLuint queryId, GLuint counterId,
367bf215546Sopenharmony_ci                              GLuint nameLength, GLchar *name,
368bf215546Sopenharmony_ci                              GLuint descLength, GLchar *desc,
369bf215546Sopenharmony_ci                              GLuint *offset,
370bf215546Sopenharmony_ci                              GLuint *dataSize,
371bf215546Sopenharmony_ci                              GLuint *typeEnum,
372bf215546Sopenharmony_ci                              GLuint *dataTypeEnum,
373bf215546Sopenharmony_ci                              GLuint64 *rawCounterMaxValue)
374bf215546Sopenharmony_ci{
375bf215546Sopenharmony_ci   GET_CURRENT_CONTEXT(ctx);
376bf215546Sopenharmony_ci
377bf215546Sopenharmony_ci   unsigned numQueries = init_performance_query_info(ctx);
378bf215546Sopenharmony_ci   unsigned queryIndex = queryid_to_index(queryId);
379bf215546Sopenharmony_ci   const char *queryName;
380bf215546Sopenharmony_ci   GLuint queryDataSize;
381bf215546Sopenharmony_ci   GLuint queryNumCounters;
382bf215546Sopenharmony_ci   GLuint queryNumActive;
383bf215546Sopenharmony_ci   unsigned counterIndex;
384bf215546Sopenharmony_ci   const char *counterName;
385bf215546Sopenharmony_ci   const char *counterDesc;
386bf215546Sopenharmony_ci   GLuint counterOffset;
387bf215546Sopenharmony_ci   GLuint counterDataSize;
388bf215546Sopenharmony_ci   GLuint counterTypeEnum;
389bf215546Sopenharmony_ci   GLuint counterDataTypeEnum;
390bf215546Sopenharmony_ci   GLuint64 counterRawMax;
391bf215546Sopenharmony_ci
392bf215546Sopenharmony_ci   if (!queryid_valid(ctx, numQueries, queryId)) {
393bf215546Sopenharmony_ci      /* The GL_INTEL_performance_query spec says:
394bf215546Sopenharmony_ci       *
395bf215546Sopenharmony_ci       *    "If the pair of queryId and counterId does not reference a valid
396bf215546Sopenharmony_ci       *    counter, an INVALID_VALUE error is generated."
397bf215546Sopenharmony_ci       */
398bf215546Sopenharmony_ci      _mesa_error(ctx, GL_INVALID_VALUE,
399bf215546Sopenharmony_ci                  "glGetPerfCounterInfoINTEL(invalid queryId)");
400bf215546Sopenharmony_ci      return;
401bf215546Sopenharmony_ci   }
402bf215546Sopenharmony_ci
403bf215546Sopenharmony_ci   ctx->pipe->get_intel_perf_query_info(ctx->pipe, queryIndex, &queryName,
404bf215546Sopenharmony_ci                                        &queryDataSize, &queryNumCounters,
405bf215546Sopenharmony_ci                                        &queryNumActive);
406bf215546Sopenharmony_ci
407bf215546Sopenharmony_ci   counterIndex = counterid_to_index(counterId);
408bf215546Sopenharmony_ci
409bf215546Sopenharmony_ci   if (counterIndex >= queryNumCounters) {
410bf215546Sopenharmony_ci      _mesa_error(ctx, GL_INVALID_VALUE,
411bf215546Sopenharmony_ci                  "glGetPerfCounterInfoINTEL(invalid counterId)");
412bf215546Sopenharmony_ci      return;
413bf215546Sopenharmony_ci   }
414bf215546Sopenharmony_ci
415bf215546Sopenharmony_ci   get_perf_counter_info(ctx, queryIndex, counterIndex,
416bf215546Sopenharmony_ci                         &counterName,
417bf215546Sopenharmony_ci                         &counterDesc,
418bf215546Sopenharmony_ci                         &counterOffset,
419bf215546Sopenharmony_ci                         &counterDataSize,
420bf215546Sopenharmony_ci                         &counterTypeEnum,
421bf215546Sopenharmony_ci                         &counterDataTypeEnum,
422bf215546Sopenharmony_ci                         &counterRawMax);
423bf215546Sopenharmony_ci
424bf215546Sopenharmony_ci   output_clipped_string(name, nameLength, counterName);
425bf215546Sopenharmony_ci   output_clipped_string(desc, descLength, counterDesc);
426bf215546Sopenharmony_ci
427bf215546Sopenharmony_ci   if (offset)
428bf215546Sopenharmony_ci      *offset = counterOffset;
429bf215546Sopenharmony_ci
430bf215546Sopenharmony_ci   if (dataSize)
431bf215546Sopenharmony_ci      *dataSize = counterDataSize;
432bf215546Sopenharmony_ci
433bf215546Sopenharmony_ci   if (typeEnum)
434bf215546Sopenharmony_ci      *typeEnum = counterTypeEnum;
435bf215546Sopenharmony_ci
436bf215546Sopenharmony_ci   if (dataTypeEnum)
437bf215546Sopenharmony_ci      *dataTypeEnum = counterDataTypeEnum;
438bf215546Sopenharmony_ci
439bf215546Sopenharmony_ci   if (rawCounterMaxValue)
440bf215546Sopenharmony_ci      *rawCounterMaxValue = counterRawMax;
441bf215546Sopenharmony_ci
442bf215546Sopenharmony_ci   if (rawCounterMaxValue) {
443bf215546Sopenharmony_ci      /* The GL_INTEL_performance_query spec says:
444bf215546Sopenharmony_ci       *
445bf215546Sopenharmony_ci       *    "for some raw counters for which the maximal value is
446bf215546Sopenharmony_ci       *    deterministic, the maximal value of the counter in 1 second is
447bf215546Sopenharmony_ci       *    returned in the location pointed by rawCounterMaxValue, otherwise,
448bf215546Sopenharmony_ci       *    the location is written with the value of 0."
449bf215546Sopenharmony_ci       *
450bf215546Sopenharmony_ci       *    Since it's very useful to be able to report a maximum value for
451bf215546Sopenharmony_ci       *    more that just counters using the _COUNTER_RAW_INTEL or
452bf215546Sopenharmony_ci       *    _COUNTER_DURATION_RAW_INTEL enums (e.g. for a _THROUGHPUT tools
453bf215546Sopenharmony_ci       *    want to be able to visualize the absolute throughput with respect
454bf215546Sopenharmony_ci       *    to the theoretical maximum that's possible) and there doesn't seem
455bf215546Sopenharmony_ci       *    to be any reason not to allow _THROUGHPUT counters to also be
456bf215546Sopenharmony_ci       *    considerer "raw" here, we always leave it up to the backend to
457bf215546Sopenharmony_ci       *    decide when it's appropriate to report a maximum counter value or 0
458bf215546Sopenharmony_ci       *    if not.
459bf215546Sopenharmony_ci       */
460bf215546Sopenharmony_ci      *rawCounterMaxValue = counterRawMax;
461bf215546Sopenharmony_ci   }
462bf215546Sopenharmony_ci}
463bf215546Sopenharmony_ci
464bf215546Sopenharmony_ciextern void GLAPIENTRY
465bf215546Sopenharmony_ci_mesa_CreatePerfQueryINTEL(GLuint queryId, GLuint *queryHandle)
466bf215546Sopenharmony_ci{
467bf215546Sopenharmony_ci   GET_CURRENT_CONTEXT(ctx);
468bf215546Sopenharmony_ci
469bf215546Sopenharmony_ci   unsigned numQueries = init_performance_query_info(ctx);
470bf215546Sopenharmony_ci   GLuint id;
471bf215546Sopenharmony_ci   struct gl_perf_query_object *obj;
472bf215546Sopenharmony_ci
473bf215546Sopenharmony_ci   /* The GL_INTEL_performance_query spec says:
474bf215546Sopenharmony_ci    *
475bf215546Sopenharmony_ci    *    "If queryId does not reference a valid query type, an INVALID_VALUE
476bf215546Sopenharmony_ci    *    error is generated."
477bf215546Sopenharmony_ci    */
478bf215546Sopenharmony_ci   if (!queryid_valid(ctx, numQueries, queryId)) {
479bf215546Sopenharmony_ci      _mesa_error(ctx, GL_INVALID_VALUE,
480bf215546Sopenharmony_ci                  "glCreatePerfQueryINTEL(invalid queryId)");
481bf215546Sopenharmony_ci      return;
482bf215546Sopenharmony_ci   }
483bf215546Sopenharmony_ci
484bf215546Sopenharmony_ci   /* This is not specified in the extension, but is the only sane thing to
485bf215546Sopenharmony_ci    * do.
486bf215546Sopenharmony_ci    */
487bf215546Sopenharmony_ci   if (queryHandle == NULL) {
488bf215546Sopenharmony_ci      _mesa_error(ctx, GL_INVALID_VALUE,
489bf215546Sopenharmony_ci                  "glCreatePerfQueryINTEL(queryHandle == NULL)");
490bf215546Sopenharmony_ci      return;
491bf215546Sopenharmony_ci   }
492bf215546Sopenharmony_ci
493bf215546Sopenharmony_ci   id = _mesa_HashFindFreeKeyBlock(ctx->PerfQuery.Objects, 1);
494bf215546Sopenharmony_ci   if (!id) {
495bf215546Sopenharmony_ci      /* The GL_INTEL_performance_query spec says:
496bf215546Sopenharmony_ci       *
497bf215546Sopenharmony_ci       *    "If the query instance cannot be created due to exceeding the
498bf215546Sopenharmony_ci       *    number of allowed instances or driver fails query creation due to
499bf215546Sopenharmony_ci       *    an insufficient memory reason, an OUT_OF_MEMORY error is
500bf215546Sopenharmony_ci       *    generated, and the location pointed by queryHandle returns NULL."
501bf215546Sopenharmony_ci       */
502bf215546Sopenharmony_ci      _mesa_error_no_memory(__func__);
503bf215546Sopenharmony_ci      return;
504bf215546Sopenharmony_ci   }
505bf215546Sopenharmony_ci
506bf215546Sopenharmony_ci   obj = (struct gl_perf_query_object *)ctx->pipe->new_intel_perf_query_obj(ctx->pipe,
507bf215546Sopenharmony_ci                                                                            queryid_to_index(queryId));
508bf215546Sopenharmony_ci   if (obj == NULL) {
509bf215546Sopenharmony_ci      _mesa_error_no_memory(__func__);
510bf215546Sopenharmony_ci      return;
511bf215546Sopenharmony_ci   }
512bf215546Sopenharmony_ci
513bf215546Sopenharmony_ci   obj->Id = id;
514bf215546Sopenharmony_ci   obj->Active = false;
515bf215546Sopenharmony_ci   obj->Ready = false;
516bf215546Sopenharmony_ci
517bf215546Sopenharmony_ci   _mesa_HashInsert(ctx->PerfQuery.Objects, id, obj, true);
518bf215546Sopenharmony_ci   *queryHandle = id;
519bf215546Sopenharmony_ci}
520bf215546Sopenharmony_ci
521bf215546Sopenharmony_ciextern void GLAPIENTRY
522bf215546Sopenharmony_ci_mesa_DeletePerfQueryINTEL(GLuint queryHandle)
523bf215546Sopenharmony_ci{
524bf215546Sopenharmony_ci   GET_CURRENT_CONTEXT(ctx);
525bf215546Sopenharmony_ci
526bf215546Sopenharmony_ci   struct gl_perf_query_object *obj = lookup_object(ctx, queryHandle);
527bf215546Sopenharmony_ci
528bf215546Sopenharmony_ci   /* The GL_INTEL_performance_query spec says:
529bf215546Sopenharmony_ci    *
530bf215546Sopenharmony_ci    *    "If a query handle doesn't reference a previously created performance
531bf215546Sopenharmony_ci    *    query instance, an INVALID_VALUE error is generated."
532bf215546Sopenharmony_ci    */
533bf215546Sopenharmony_ci   if (obj == NULL) {
534bf215546Sopenharmony_ci      _mesa_error(ctx, GL_INVALID_VALUE,
535bf215546Sopenharmony_ci                  "glDeletePerfQueryINTEL(invalid queryHandle)");
536bf215546Sopenharmony_ci      return;
537bf215546Sopenharmony_ci   }
538bf215546Sopenharmony_ci
539bf215546Sopenharmony_ci   /* To avoid complications in the backend we never ask the backend to
540bf215546Sopenharmony_ci    * delete an active query or a query object while we are still
541bf215546Sopenharmony_ci    * waiting for data.
542bf215546Sopenharmony_ci    */
543bf215546Sopenharmony_ci
544bf215546Sopenharmony_ci   if (obj->Active)
545bf215546Sopenharmony_ci      _mesa_EndPerfQueryINTEL(queryHandle);
546bf215546Sopenharmony_ci
547bf215546Sopenharmony_ci   if (obj->Used && !obj->Ready) {
548bf215546Sopenharmony_ci      ctx->pipe->wait_intel_perf_query(ctx->pipe, (struct pipe_query *)obj);
549bf215546Sopenharmony_ci      obj->Ready = true;
550bf215546Sopenharmony_ci   }
551bf215546Sopenharmony_ci
552bf215546Sopenharmony_ci   _mesa_HashRemove(ctx->PerfQuery.Objects, queryHandle);
553bf215546Sopenharmony_ci   ctx->pipe->delete_intel_perf_query(ctx->pipe, (struct pipe_query *)obj);
554bf215546Sopenharmony_ci}
555bf215546Sopenharmony_ci
556bf215546Sopenharmony_ciextern void GLAPIENTRY
557bf215546Sopenharmony_ci_mesa_BeginPerfQueryINTEL(GLuint queryHandle)
558bf215546Sopenharmony_ci{
559bf215546Sopenharmony_ci   GET_CURRENT_CONTEXT(ctx);
560bf215546Sopenharmony_ci
561bf215546Sopenharmony_ci   struct gl_perf_query_object *obj = lookup_object(ctx, queryHandle);
562bf215546Sopenharmony_ci
563bf215546Sopenharmony_ci   /* The GL_INTEL_performance_query spec says:
564bf215546Sopenharmony_ci    *
565bf215546Sopenharmony_ci    *    "If a query handle doesn't reference a previously created performance
566bf215546Sopenharmony_ci    *    query instance, an INVALID_VALUE error is generated."
567bf215546Sopenharmony_ci    */
568bf215546Sopenharmony_ci   if (obj == NULL) {
569bf215546Sopenharmony_ci      _mesa_error(ctx, GL_INVALID_VALUE,
570bf215546Sopenharmony_ci                  "glBeginPerfQueryINTEL(invalid queryHandle)");
571bf215546Sopenharmony_ci      return;
572bf215546Sopenharmony_ci   }
573bf215546Sopenharmony_ci
574bf215546Sopenharmony_ci   /* The GL_INTEL_performance_query spec says:
575bf215546Sopenharmony_ci    *
576bf215546Sopenharmony_ci    *    "Note that some query types, they cannot be collected in the same
577bf215546Sopenharmony_ci    *    time. Therefore calls of BeginPerfQueryINTEL() cannot be nested if
578bf215546Sopenharmony_ci    *    they refer to queries of such different types. In such case
579bf215546Sopenharmony_ci    *    INVALID_OPERATION error is generated."
580bf215546Sopenharmony_ci    *
581bf215546Sopenharmony_ci    * We also generate an INVALID_OPERATION error if the driver can't begin
582bf215546Sopenharmony_ci    * a query for its own reasons, and for nesting the same query.
583bf215546Sopenharmony_ci    */
584bf215546Sopenharmony_ci   if (obj->Active) {
585bf215546Sopenharmony_ci      _mesa_error(ctx, GL_INVALID_OPERATION,
586bf215546Sopenharmony_ci                  "glBeginPerfQueryINTEL(already active)");
587bf215546Sopenharmony_ci      return;
588bf215546Sopenharmony_ci   }
589bf215546Sopenharmony_ci
590bf215546Sopenharmony_ci   /* To avoid complications in the backend we never ask the backend to
591bf215546Sopenharmony_ci    * reuse a query object and begin a new query while we are still
592bf215546Sopenharmony_ci    * waiting for data on that object.
593bf215546Sopenharmony_ci    */
594bf215546Sopenharmony_ci   if (obj->Used && !obj->Ready) {
595bf215546Sopenharmony_ci      ctx->pipe->wait_intel_perf_query(ctx->pipe, (struct pipe_query *)obj);
596bf215546Sopenharmony_ci      obj->Ready = true;
597bf215546Sopenharmony_ci   }
598bf215546Sopenharmony_ci
599bf215546Sopenharmony_ci   if (ctx->pipe->begin_intel_perf_query(ctx->pipe, (struct pipe_query *)obj)) {
600bf215546Sopenharmony_ci      obj->Used = true;
601bf215546Sopenharmony_ci      obj->Active = true;
602bf215546Sopenharmony_ci      obj->Ready = false;
603bf215546Sopenharmony_ci   } else {
604bf215546Sopenharmony_ci      _mesa_error(ctx, GL_INVALID_OPERATION,
605bf215546Sopenharmony_ci                  "glBeginPerfQueryINTEL(driver unable to begin query)");
606bf215546Sopenharmony_ci   }
607bf215546Sopenharmony_ci}
608bf215546Sopenharmony_ci
609bf215546Sopenharmony_ciextern void GLAPIENTRY
610bf215546Sopenharmony_ci_mesa_EndPerfQueryINTEL(GLuint queryHandle)
611bf215546Sopenharmony_ci{
612bf215546Sopenharmony_ci   GET_CURRENT_CONTEXT(ctx);
613bf215546Sopenharmony_ci
614bf215546Sopenharmony_ci   struct gl_perf_query_object *obj = lookup_object(ctx, queryHandle);
615bf215546Sopenharmony_ci
616bf215546Sopenharmony_ci   /* Not explicitly covered in the spec, but for consistency... */
617bf215546Sopenharmony_ci   if (obj == NULL) {
618bf215546Sopenharmony_ci      _mesa_error(ctx, GL_INVALID_VALUE,
619bf215546Sopenharmony_ci                  "glEndPerfQueryINTEL(invalid queryHandle)");
620bf215546Sopenharmony_ci      return;
621bf215546Sopenharmony_ci   }
622bf215546Sopenharmony_ci
623bf215546Sopenharmony_ci   /* The GL_INTEL_performance_query spec says:
624bf215546Sopenharmony_ci    *
625bf215546Sopenharmony_ci    *    "If a performance query is not currently started, an
626bf215546Sopenharmony_ci    *    INVALID_OPERATION error will be generated."
627bf215546Sopenharmony_ci    */
628bf215546Sopenharmony_ci
629bf215546Sopenharmony_ci   if (!obj->Active) {
630bf215546Sopenharmony_ci      _mesa_error(ctx, GL_INVALID_OPERATION,
631bf215546Sopenharmony_ci                  "glEndPerfQueryINTEL(not active)");
632bf215546Sopenharmony_ci      return;
633bf215546Sopenharmony_ci   }
634bf215546Sopenharmony_ci
635bf215546Sopenharmony_ci   ctx->pipe->end_intel_perf_query(ctx->pipe, (struct pipe_query *)obj);
636bf215546Sopenharmony_ci
637bf215546Sopenharmony_ci   obj->Active = false;
638bf215546Sopenharmony_ci   obj->Ready = false;
639bf215546Sopenharmony_ci}
640bf215546Sopenharmony_ci
641bf215546Sopenharmony_ciextern void GLAPIENTRY
642bf215546Sopenharmony_ci_mesa_GetPerfQueryDataINTEL(GLuint queryHandle, GLuint flags,
643bf215546Sopenharmony_ci                            GLsizei dataSize, void *data, GLuint *bytesWritten)
644bf215546Sopenharmony_ci{
645bf215546Sopenharmony_ci   GET_CURRENT_CONTEXT(ctx);
646bf215546Sopenharmony_ci
647bf215546Sopenharmony_ci   struct gl_perf_query_object *obj = lookup_object(ctx, queryHandle);
648bf215546Sopenharmony_ci
649bf215546Sopenharmony_ci   /* Not explicitly covered in the spec, but for consistency... */
650bf215546Sopenharmony_ci   if (obj == NULL) {
651bf215546Sopenharmony_ci      _mesa_error(ctx, GL_INVALID_VALUE,
652bf215546Sopenharmony_ci                  "glEndPerfQueryINTEL(invalid queryHandle)");
653bf215546Sopenharmony_ci      return;
654bf215546Sopenharmony_ci   }
655bf215546Sopenharmony_ci
656bf215546Sopenharmony_ci   /* The GL_INTEL_performance_query spec says:
657bf215546Sopenharmony_ci    *
658bf215546Sopenharmony_ci    *    "If bytesWritten or data pointers are NULL then an INVALID_VALUE
659bf215546Sopenharmony_ci    *    error is generated."
660bf215546Sopenharmony_ci    */
661bf215546Sopenharmony_ci   if (!bytesWritten || !data) {
662bf215546Sopenharmony_ci      _mesa_error(ctx, GL_INVALID_VALUE,
663bf215546Sopenharmony_ci                  "glGetPerfQueryDataINTEL(bytesWritten or data is NULL)");
664bf215546Sopenharmony_ci      return;
665bf215546Sopenharmony_ci   }
666bf215546Sopenharmony_ci
667bf215546Sopenharmony_ci   /* Just for good measure in case a lazy application is only
668bf215546Sopenharmony_ci    * checking this and not checking for errors...
669bf215546Sopenharmony_ci    */
670bf215546Sopenharmony_ci   *bytesWritten = 0;
671bf215546Sopenharmony_ci
672bf215546Sopenharmony_ci   /* Not explicitly covered in the spec but a query that was never started
673bf215546Sopenharmony_ci    * cannot return any data.
674bf215546Sopenharmony_ci    */
675bf215546Sopenharmony_ci   if (!obj->Used) {
676bf215546Sopenharmony_ci      _mesa_error(ctx, GL_INVALID_OPERATION,
677bf215546Sopenharmony_ci                  "glGetPerfQueryDataINTEL(query never began)");
678bf215546Sopenharmony_ci      return;
679bf215546Sopenharmony_ci   }
680bf215546Sopenharmony_ci
681bf215546Sopenharmony_ci   /* Not explicitly covered in the spec but to be consistent with
682bf215546Sopenharmony_ci    * EndPerfQuery which validates that an application only ends an
683bf215546Sopenharmony_ci    * active query we also validate that an application doesn't try
684bf215546Sopenharmony_ci    * and get the data for a still active query...
685bf215546Sopenharmony_ci    */
686bf215546Sopenharmony_ci   if (obj->Active) {
687bf215546Sopenharmony_ci      _mesa_error(ctx, GL_INVALID_OPERATION,
688bf215546Sopenharmony_ci                  "glGetPerfQueryDataINTEL(query still active)");
689bf215546Sopenharmony_ci      return;
690bf215546Sopenharmony_ci   }
691bf215546Sopenharmony_ci
692bf215546Sopenharmony_ci   if (!obj->Ready)
693bf215546Sopenharmony_ci      obj->Ready = ctx->pipe->is_intel_perf_query_ready(ctx->pipe,
694bf215546Sopenharmony_ci                                                        (struct pipe_query *)obj);
695bf215546Sopenharmony_ci
696bf215546Sopenharmony_ci   if (!obj->Ready) {
697bf215546Sopenharmony_ci      if (flags == GL_PERFQUERY_FLUSH_INTEL) {
698bf215546Sopenharmony_ci         st_glFlush(ctx, 0);
699bf215546Sopenharmony_ci      } else if (flags == GL_PERFQUERY_WAIT_INTEL) {
700bf215546Sopenharmony_ci         ctx->pipe->wait_intel_perf_query(ctx->pipe, (struct pipe_query *)obj);
701bf215546Sopenharmony_ci         obj->Ready = true;
702bf215546Sopenharmony_ci      }
703bf215546Sopenharmony_ci   }
704bf215546Sopenharmony_ci
705bf215546Sopenharmony_ci   if (obj->Ready) {
706bf215546Sopenharmony_ci      if (!ctx->pipe->get_intel_perf_query_data(ctx->pipe, (struct pipe_query *)obj,
707bf215546Sopenharmony_ci                                                dataSize, data, bytesWritten)) {
708bf215546Sopenharmony_ci         memset(data, 0, dataSize);
709bf215546Sopenharmony_ci         *bytesWritten = 0;
710bf215546Sopenharmony_ci
711bf215546Sopenharmony_ci         _mesa_error(ctx, GL_INVALID_OPERATION,
712bf215546Sopenharmony_ci                     "glGetPerfQueryDataINTEL(deferred begin query failure)");
713bf215546Sopenharmony_ci      }
714bf215546Sopenharmony_ci   }
715bf215546Sopenharmony_ci}
716