2 * Copyright © 2019 Intel Corporation
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 shall be included
12 * in all copies or substantial portions of the Software.
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20 * DEALINGS IN THE SOFTWARE.
24 * Intel Performance query interface to gallium.
28 #include "st_context.h"
29 #include "st_cb_bitmap.h"
30 #include "st_cb_perfquery.h"
33 #include "util/bitset.h"
35 #include "pipe/p_context.h"
36 #include "pipe/p_screen.h"
37 #include "util/u_memory.h"
40 st_have_perfquery(struct st_context
*st
)
42 struct pipe_context
*pipe
= st
->pipe
;
44 return pipe
->init_intel_perf_query_info
&& pipe
->get_intel_perf_query_info
&&
45 pipe
->get_intel_perf_query_counter_info
&&
46 pipe
->new_intel_perf_query_obj
&& pipe
->begin_intel_perf_query
&&
47 pipe
->end_intel_perf_query
&& pipe
->delete_intel_perf_query
&&
48 pipe
->wait_intel_perf_query
&& pipe
->is_intel_perf_query_ready
&&
49 pipe
->get_intel_perf_query_data
;
53 st_InitPerfQueryInfo(struct gl_context
*ctx
)
55 struct pipe_context
*pipe
= st_context(ctx
)->pipe
;
57 return pipe
->init_intel_perf_query_info(pipe
);
61 st_GetPerfQueryInfo(struct gl_context
*ctx
,
68 struct pipe_context
*pipe
= st_context(ctx
)->pipe
;
70 pipe
->get_intel_perf_query_info(pipe
, query_index
, name
, data_size
,
71 n_counters
, n_active
);
75 pipe_counter_type_enum_to_gl_type(enum pipe_perf_counter_type type
)
78 case PIPE_PERF_COUNTER_TYPE_EVENT
: return GL_PERFQUERY_COUNTER_EVENT_INTEL
;
79 case PIPE_PERF_COUNTER_TYPE_DURATION_NORM
: return GL_PERFQUERY_COUNTER_DURATION_NORM_INTEL
;
80 case PIPE_PERF_COUNTER_TYPE_DURATION_RAW
: return GL_PERFQUERY_COUNTER_DURATION_RAW_INTEL
;
81 case PIPE_PERF_COUNTER_TYPE_THROUGHPUT
: return GL_PERFQUERY_COUNTER_THROUGHPUT_INTEL
;
82 case PIPE_PERF_COUNTER_TYPE_RAW
: return GL_PERFQUERY_COUNTER_RAW_INTEL
;
83 case PIPE_PERF_COUNTER_TYPE_TIMESTAMP
: return GL_PERFQUERY_COUNTER_TIMESTAMP_INTEL
;
85 unreachable("Unknown counter type");
90 pipe_counter_data_type_to_gl_type(enum pipe_perf_counter_data_type type
)
93 case PIPE_PERF_COUNTER_DATA_TYPE_BOOL32
: return GL_PERFQUERY_COUNTER_DATA_BOOL32_INTEL
;
94 case PIPE_PERF_COUNTER_DATA_TYPE_UINT32
: return GL_PERFQUERY_COUNTER_DATA_UINT32_INTEL
;
95 case PIPE_PERF_COUNTER_DATA_TYPE_UINT64
: return GL_PERFQUERY_COUNTER_DATA_UINT64_INTEL
;
96 case PIPE_PERF_COUNTER_DATA_TYPE_FLOAT
: return GL_PERFQUERY_COUNTER_DATA_FLOAT_INTEL
;
97 case PIPE_PERF_COUNTER_DATA_TYPE_DOUBLE
: return GL_PERFQUERY_COUNTER_DATA_DOUBLE_INTEL
;
99 unreachable("Unknown counter data type");
104 st_GetPerfCounterInfo(struct gl_context
*ctx
,
105 unsigned query_index
,
106 unsigned counter_index
,
112 GLuint
*data_type_enum
,
115 struct pipe_context
*pipe
= st_context(ctx
)->pipe
;
116 uint32_t pipe_type_enum
;
117 uint32_t pipe_data_type_enum
;
119 pipe
->get_intel_perf_query_counter_info(pipe
, query_index
, counter_index
,
120 name
, desc
, offset
, data_size
,
121 &pipe_type_enum
, &pipe_data_type_enum
, raw_max
);
122 *type_enum
= pipe_counter_type_enum_to_gl_type(pipe_type_enum
);
123 *data_type_enum
= pipe_counter_data_type_to_gl_type(pipe_data_type_enum
);
127 st_DeletePerfQuery(struct gl_context
*ctx
, struct gl_perf_query_object
*o
)
129 struct pipe_context
*pipe
= st_context(ctx
)->pipe
;
131 /* We can assume that the frontend waits for a query to complete
132 * before ever calling into here, so we don't have to worry about
133 * deleting an in-flight query object.
136 assert(!o
->Used
|| o
->Ready
);
138 pipe
->delete_intel_perf_query(pipe
, (struct pipe_query
*)o
);
142 st_BeginPerfQuery(struct gl_context
*ctx
, struct gl_perf_query_object
*o
)
144 struct pipe_context
*pipe
= st_context(ctx
)->pipe
;
146 /* We can assume the frontend hides mistaken attempts to Begin a
147 * query object multiple times before its End. Similarly if an
148 * application reuses a query object before results have arrived
149 * the frontend will wait for prior results so we don't need
150 * to support abandoning in-flight results.
153 assert(!o
->Used
|| o
->Ready
); /* no in-flight query to worry about */
155 pipe
->begin_intel_perf_query(pipe
, (struct pipe_query
*)o
);
161 st_EndPerfQuery(struct gl_context
*ctx
, struct gl_perf_query_object
*o
)
163 struct pipe_context
*pipe
= st_context(ctx
)->pipe
;
165 pipe
->end_intel_perf_query(pipe
, (struct pipe_query
*)o
);
169 st_WaitPerfQuery(struct gl_context
*ctx
, struct gl_perf_query_object
*o
)
171 struct pipe_context
*pipe
= st_context(ctx
)->pipe
;
175 pipe
->wait_intel_perf_query(pipe
, (struct pipe_query
*)o
);
179 st_IsPerfQueryReady(struct gl_context
*ctx
, struct gl_perf_query_object
*o
)
181 struct pipe_context
*pipe
= st_context(ctx
)->pipe
;
186 return pipe
->is_intel_perf_query_ready(pipe
, (struct pipe_query
*)o
);
190 st_GetPerfQueryData(struct gl_context
*ctx
,
191 struct gl_perf_query_object
*o
,
194 GLuint
*bytes_written
)
196 struct pipe_context
*pipe
= st_context(ctx
)->pipe
;
198 assert(st_IsPerfQueryReady(ctx
, o
));
200 /* We expect that the frontend only calls this hook when it knows
201 * that results are available.
205 pipe
->get_intel_perf_query_data(pipe
, (struct pipe_query
*)o
, data_size
, data
,
209 static struct gl_perf_query_object
*
210 st_NewPerfQueryObject(struct gl_context
*ctx
, unsigned query_index
)
212 struct pipe_context
*pipe
= st_context(ctx
)->pipe
;
213 struct pipe_query
*q
;
215 q
= pipe
->new_intel_perf_query_obj(pipe
, query_index
);
217 return (struct gl_perf_query_object
*)q
;
220 void st_init_perfquery_functions(struct dd_function_table
*functions
)
222 functions
->InitPerfQueryInfo
= st_InitPerfQueryInfo
;
223 functions
->GetPerfQueryInfo
= st_GetPerfQueryInfo
;
224 functions
->GetPerfCounterInfo
= st_GetPerfCounterInfo
;
225 functions
->NewPerfQueryObject
= st_NewPerfQueryObject
;
226 functions
->DeletePerfQuery
= st_DeletePerfQuery
;
227 functions
->BeginPerfQuery
= st_BeginPerfQuery
;
228 functions
->EndPerfQuery
= st_EndPerfQuery
;
229 functions
->WaitPerfQuery
= st_WaitPerfQuery
;
230 functions
->IsPerfQueryReady
= st_IsPerfQueryReady
;
231 functions
->GetPerfQueryData
= st_GetPerfQueryData
;