radeon/vcn: add decode message for hevc codec
[mesa.git] / src / gallium / drivers / ddebug / dd_screen.c
1 /**************************************************************************
2 *
3 * Copyright 2015 Advanced Micro Devices, Inc.
4 * Copyright 2008 VMware, Inc.
5 * All Rights Reserved.
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * on the rights to use, copy, modify, merge, publish, distribute, sub
11 * license, and/or sell copies of the Software, and to permit persons to whom
12 * the Software is furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice (including the next
15 * paragraph) shall be included in all copies or substantial portions of the
16 * Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
21 * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
22 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
23 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
24 * USE OR OTHER DEALINGS IN THE SOFTWARE.
25 *
26 **************************************************************************/
27
28 #include "dd_pipe.h"
29 #include "dd_public.h"
30 #include "util/u_memory.h"
31 #include <stdio.h>
32
33
34 static const char *
35 dd_screen_get_name(struct pipe_screen *_screen)
36 {
37 struct pipe_screen *screen = dd_screen(_screen)->screen;
38
39 return screen->get_name(screen);
40 }
41
42 static const char *
43 dd_screen_get_vendor(struct pipe_screen *_screen)
44 {
45 struct pipe_screen *screen = dd_screen(_screen)->screen;
46
47 return screen->get_vendor(screen);
48 }
49
50 static const char *
51 dd_screen_get_device_vendor(struct pipe_screen *_screen)
52 {
53 struct pipe_screen *screen = dd_screen(_screen)->screen;
54
55 return screen->get_device_vendor(screen);
56 }
57
58 static struct disk_cache *
59 dd_screen_get_disk_shader_cache(struct pipe_screen *_screen)
60 {
61 struct pipe_screen *screen = dd_screen(_screen)->screen;
62
63 return screen->get_disk_shader_cache(screen);
64 }
65
66 static int
67 dd_screen_get_param(struct pipe_screen *_screen,
68 enum pipe_cap param)
69 {
70 struct pipe_screen *screen = dd_screen(_screen)->screen;
71
72 return screen->get_param(screen, param);
73 }
74
75 static float
76 dd_screen_get_paramf(struct pipe_screen *_screen,
77 enum pipe_capf param)
78 {
79 struct pipe_screen *screen = dd_screen(_screen)->screen;
80
81 return screen->get_paramf(screen, param);
82 }
83
84 static int
85 dd_screen_get_compute_param(struct pipe_screen *_screen,
86 enum pipe_shader_ir ir_type,
87 enum pipe_compute_cap param,
88 void *ret)
89 {
90 struct pipe_screen *screen = dd_screen(_screen)->screen;
91
92 return screen->get_compute_param(screen, ir_type, param, ret);
93 }
94
95 static int
96 dd_screen_get_shader_param(struct pipe_screen *_screen,
97 enum pipe_shader_type shader,
98 enum pipe_shader_cap param)
99 {
100 struct pipe_screen *screen = dd_screen(_screen)->screen;
101
102 return screen->get_shader_param(screen, shader, param);
103 }
104
105 static uint64_t
106 dd_screen_get_timestamp(struct pipe_screen *_screen)
107 {
108 struct pipe_screen *screen = dd_screen(_screen)->screen;
109
110 return screen->get_timestamp(screen);
111 }
112
113 static void dd_screen_query_memory_info(struct pipe_screen *_screen,
114 struct pipe_memory_info *info)
115 {
116 struct pipe_screen *screen = dd_screen(_screen)->screen;
117
118 return screen->query_memory_info(screen, info);
119 }
120
121 static struct pipe_context *
122 dd_screen_context_create(struct pipe_screen *_screen, void *priv,
123 unsigned flags)
124 {
125 struct dd_screen *dscreen = dd_screen(_screen);
126 struct pipe_screen *screen = dscreen->screen;
127
128 flags |= PIPE_CONTEXT_DEBUG;
129
130 return dd_context_create(dscreen,
131 screen->context_create(screen, priv, flags));
132 }
133
134 static boolean
135 dd_screen_is_format_supported(struct pipe_screen *_screen,
136 enum pipe_format format,
137 enum pipe_texture_target target,
138 unsigned sample_count,
139 unsigned tex_usage)
140 {
141 struct pipe_screen *screen = dd_screen(_screen)->screen;
142
143 return screen->is_format_supported(screen, format, target, sample_count,
144 tex_usage);
145 }
146
147 static boolean
148 dd_screen_can_create_resource(struct pipe_screen *_screen,
149 const struct pipe_resource *templat)
150 {
151 struct pipe_screen *screen = dd_screen(_screen)->screen;
152
153 return screen->can_create_resource(screen, templat);
154 }
155
156 static void
157 dd_screen_flush_frontbuffer(struct pipe_screen *_screen,
158 struct pipe_resource *resource,
159 unsigned level, unsigned layer,
160 void *context_private,
161 struct pipe_box *sub_box)
162 {
163 struct pipe_screen *screen = dd_screen(_screen)->screen;
164
165 screen->flush_frontbuffer(screen, resource, level, layer, context_private,
166 sub_box);
167 }
168
169 static int
170 dd_screen_get_driver_query_info(struct pipe_screen *_screen,
171 unsigned index,
172 struct pipe_driver_query_info *info)
173 {
174 struct pipe_screen *screen = dd_screen(_screen)->screen;
175
176 return screen->get_driver_query_info(screen, index, info);
177 }
178
179 static int
180 dd_screen_get_driver_query_group_info(struct pipe_screen *_screen,
181 unsigned index,
182 struct pipe_driver_query_group_info *info)
183 {
184 struct pipe_screen *screen = dd_screen(_screen)->screen;
185
186 return screen->get_driver_query_group_info(screen, index, info);
187 }
188
189
190 /********************************************************************
191 * resource
192 */
193
194 static struct pipe_resource *
195 dd_screen_resource_create(struct pipe_screen *_screen,
196 const struct pipe_resource *templat)
197 {
198 struct pipe_screen *screen = dd_screen(_screen)->screen;
199 struct pipe_resource *res = screen->resource_create(screen, templat);
200
201 if (!res)
202 return NULL;
203 res->screen = _screen;
204 return res;
205 }
206
207 static struct pipe_resource *
208 dd_screen_resource_from_handle(struct pipe_screen *_screen,
209 const struct pipe_resource *templ,
210 struct winsys_handle *handle,
211 unsigned usage)
212 {
213 struct pipe_screen *screen = dd_screen(_screen)->screen;
214 struct pipe_resource *res =
215 screen->resource_from_handle(screen, templ, handle, usage);
216
217 if (!res)
218 return NULL;
219 res->screen = _screen;
220 return res;
221 }
222
223 static struct pipe_resource *
224 dd_screen_resource_from_user_memory(struct pipe_screen *_screen,
225 const struct pipe_resource *templ,
226 void *user_memory)
227 {
228 struct pipe_screen *screen = dd_screen(_screen)->screen;
229 struct pipe_resource *res =
230 screen->resource_from_user_memory(screen, templ, user_memory);
231
232 if (!res)
233 return NULL;
234 res->screen = _screen;
235 return res;
236 }
237
238 static void
239 dd_screen_resource_changed(struct pipe_screen *_screen,
240 struct pipe_resource *res)
241 {
242 struct pipe_screen *screen = dd_screen(_screen)->screen;
243
244 screen->resource_changed(screen, res);
245 }
246
247 static void
248 dd_screen_resource_destroy(struct pipe_screen *_screen,
249 struct pipe_resource *res)
250 {
251 struct pipe_screen *screen = dd_screen(_screen)->screen;
252
253 screen->resource_destroy(screen, res);
254 }
255
256 static boolean
257 dd_screen_resource_get_handle(struct pipe_screen *_screen,
258 struct pipe_context *_pipe,
259 struct pipe_resource *resource,
260 struct winsys_handle *handle,
261 unsigned usage)
262 {
263 struct pipe_screen *screen = dd_screen(_screen)->screen;
264 struct pipe_context *pipe = _pipe ? dd_context(_pipe)->pipe : NULL;
265
266 return screen->resource_get_handle(screen, pipe, resource, handle, usage);
267 }
268
269
270 /********************************************************************
271 * fence
272 */
273
274 static void
275 dd_screen_fence_reference(struct pipe_screen *_screen,
276 struct pipe_fence_handle **pdst,
277 struct pipe_fence_handle *src)
278 {
279 struct pipe_screen *screen = dd_screen(_screen)->screen;
280
281 screen->fence_reference(screen, pdst, src);
282 }
283
284 static boolean
285 dd_screen_fence_finish(struct pipe_screen *_screen,
286 struct pipe_context *_ctx,
287 struct pipe_fence_handle *fence,
288 uint64_t timeout)
289 {
290 struct pipe_screen *screen = dd_screen(_screen)->screen;
291 struct pipe_context *ctx = _ctx ? dd_context(_ctx)->pipe : NULL;
292
293 return screen->fence_finish(screen, ctx, fence, timeout);
294 }
295
296
297 /********************************************************************
298 * screen
299 */
300
301 static void
302 dd_screen_destroy(struct pipe_screen *_screen)
303 {
304 struct dd_screen *dscreen = dd_screen(_screen);
305 struct pipe_screen *screen = dscreen->screen;
306
307 screen->destroy(screen);
308 FREE(dscreen);
309 }
310
311 struct pipe_screen *
312 ddebug_screen_create(struct pipe_screen *screen)
313 {
314 struct dd_screen *dscreen;
315 const char *option;
316 bool no_flush;
317 unsigned timeout = 0;
318 unsigned apitrace_dump_call = 0;
319 enum dd_mode mode;
320
321 option = debug_get_option("GALLIUM_DDEBUG", NULL);
322 if (!option)
323 return screen;
324
325 if (!strcmp(option, "help")) {
326 puts("Gallium driver debugger");
327 puts("");
328 puts("Usage:");
329 puts("");
330 puts(" GALLIUM_DDEBUG=\"always [noflush] [verbose]\"");
331 puts(" Flush and dump context and driver information after every draw call into");
332 puts(" $HOME/"DD_DIR"/.");
333 puts("");
334 puts(" GALLIUM_DDEBUG=\"[timeout in ms] [noflush] [verbose]\"");
335 puts(" Flush and detect a device hang after every draw call based on the given");
336 puts(" fence timeout and dump context and driver information into");
337 puts(" $HOME/"DD_DIR"/ when a hang is detected.");
338 puts("");
339 puts(" GALLIUM_DDEBUG=\"pipelined [timeout in ms] [verbose]\"");
340 puts(" Detect a device hang after every draw call based on the given fence");
341 puts(" timeout without flushes and dump context and driver information into");
342 puts(" $HOME/"DD_DIR"/ when a hang is detected.");
343 puts("");
344 puts(" GALLIUM_DDEBUG=\"apitrace [call#] [verbose]\"");
345 puts(" Dump apitrace draw call information into $HOME/"DD_DIR"/. Implies 'noflush'.");
346 puts("");
347 puts(" If 'noflush' is specified, do not flush on every draw call. In hang");
348 puts(" detection mode, this only detect hangs in pipe->flush.");
349 puts(" If 'verbose' is specified, additional information is written to stderr.");
350 puts("");
351 puts(" GALLIUM_DDEBUG_SKIP=[count]");
352 puts(" Skip flush and hang detection for the given initial number of draw calls.");
353 puts("");
354 exit(0);
355 }
356
357 no_flush = strstr(option, "noflush") != NULL;
358
359 if (!strncmp(option, "always", 6)) {
360 mode = DD_DUMP_ALL_CALLS;
361 } else if (!strncmp(option, "apitrace", 8)) {
362 mode = DD_DUMP_APITRACE_CALL;
363 no_flush = true;
364
365 if (sscanf(option+8, "%u", &apitrace_dump_call) != 1)
366 return screen;
367 } else if (!strncmp(option, "pipelined", 8)) {
368 mode = DD_DETECT_HANGS_PIPELINED;
369
370 if (sscanf(option+10, "%u", &timeout) != 1)
371 return screen;
372 } else {
373 mode = DD_DETECT_HANGS;
374
375 if (sscanf(option, "%u", &timeout) != 1)
376 return screen;
377 }
378
379 dscreen = CALLOC_STRUCT(dd_screen);
380 if (!dscreen)
381 return NULL;
382
383 #define SCR_INIT(_member) \
384 dscreen->base._member = screen->_member ? dd_screen_##_member : NULL
385
386 dscreen->base.destroy = dd_screen_destroy;
387 dscreen->base.get_name = dd_screen_get_name;
388 dscreen->base.get_vendor = dd_screen_get_vendor;
389 dscreen->base.get_device_vendor = dd_screen_get_device_vendor;
390 SCR_INIT(get_disk_shader_cache);
391 dscreen->base.get_param = dd_screen_get_param;
392 dscreen->base.get_paramf = dd_screen_get_paramf;
393 dscreen->base.get_compute_param = dd_screen_get_compute_param;
394 dscreen->base.get_shader_param = dd_screen_get_shader_param;
395 dscreen->base.query_memory_info = dd_screen_query_memory_info;
396 /* get_video_param */
397 /* get_compute_param */
398 SCR_INIT(get_timestamp);
399 dscreen->base.context_create = dd_screen_context_create;
400 dscreen->base.is_format_supported = dd_screen_is_format_supported;
401 /* is_video_format_supported */
402 SCR_INIT(can_create_resource);
403 dscreen->base.resource_create = dd_screen_resource_create;
404 dscreen->base.resource_from_handle = dd_screen_resource_from_handle;
405 SCR_INIT(resource_from_user_memory);
406 dscreen->base.resource_get_handle = dd_screen_resource_get_handle;
407 SCR_INIT(resource_changed);
408 dscreen->base.resource_destroy = dd_screen_resource_destroy;
409 SCR_INIT(flush_frontbuffer);
410 SCR_INIT(fence_reference);
411 SCR_INIT(fence_finish);
412 SCR_INIT(get_driver_query_info);
413 SCR_INIT(get_driver_query_group_info);
414
415 #undef SCR_INIT
416
417 dscreen->screen = screen;
418 dscreen->timeout_ms = timeout;
419 dscreen->mode = mode;
420 dscreen->no_flush = no_flush;
421 dscreen->verbose = strstr(option, "verbose") != NULL;
422 dscreen->apitrace_dump_call = apitrace_dump_call;
423
424 switch (dscreen->mode) {
425 case DD_DUMP_ALL_CALLS:
426 fprintf(stderr, "Gallium debugger active. Logging all calls.\n");
427 break;
428 case DD_DETECT_HANGS:
429 case DD_DETECT_HANGS_PIPELINED:
430 fprintf(stderr, "Gallium debugger active. "
431 "The hang detection timeout is %i ms.\n", timeout);
432 break;
433 case DD_DUMP_APITRACE_CALL:
434 fprintf(stderr, "Gallium debugger active. Going to dump an apitrace call.\n");
435 break;
436 default:
437 assert(0);
438 }
439
440 dscreen->skip_count = debug_get_num_option("GALLIUM_DDEBUG_SKIP", 0);
441 if (dscreen->skip_count > 0) {
442 fprintf(stderr, "Gallium debugger skipping the first %u draw calls.\n",
443 dscreen->skip_count);
444 }
445
446 return &dscreen->base;
447 }