1 /**************************************************************************
3 * Copyright 2015 Advanced Micro Devices, Inc.
4 * Copyright 2008 VMware, Inc.
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:
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
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.
26 **************************************************************************/
29 #include "dd_public.h"
30 #include "util/u_memory.h"
35 dd_screen_get_name(struct pipe_screen
*_screen
)
37 struct pipe_screen
*screen
= dd_screen(_screen
)->screen
;
39 return screen
->get_name(screen
);
43 dd_screen_get_vendor(struct pipe_screen
*_screen
)
45 struct pipe_screen
*screen
= dd_screen(_screen
)->screen
;
47 return screen
->get_vendor(screen
);
51 dd_screen_get_device_vendor(struct pipe_screen
*_screen
)
53 struct pipe_screen
*screen
= dd_screen(_screen
)->screen
;
55 return screen
->get_device_vendor(screen
);
59 dd_screen_get_compiler_options(struct pipe_screen
*_screen
,
60 enum pipe_shader_ir ir
,
61 enum pipe_shader_type shader
)
63 struct pipe_screen
*screen
= dd_screen(_screen
)->screen
;
65 return screen
->get_compiler_options(screen
, ir
, shader
);
68 static struct disk_cache
*
69 dd_screen_get_disk_shader_cache(struct pipe_screen
*_screen
)
71 struct pipe_screen
*screen
= dd_screen(_screen
)->screen
;
73 return screen
->get_disk_shader_cache(screen
);
77 dd_screen_get_param(struct pipe_screen
*_screen
,
80 struct pipe_screen
*screen
= dd_screen(_screen
)->screen
;
82 return screen
->get_param(screen
, param
);
86 dd_screen_get_paramf(struct pipe_screen
*_screen
,
89 struct pipe_screen
*screen
= dd_screen(_screen
)->screen
;
91 return screen
->get_paramf(screen
, param
);
95 dd_screen_get_compute_param(struct pipe_screen
*_screen
,
96 enum pipe_shader_ir ir_type
,
97 enum pipe_compute_cap param
,
100 struct pipe_screen
*screen
= dd_screen(_screen
)->screen
;
102 return screen
->get_compute_param(screen
, ir_type
, param
, ret
);
106 dd_screen_get_shader_param(struct pipe_screen
*_screen
,
107 enum pipe_shader_type shader
,
108 enum pipe_shader_cap param
)
110 struct pipe_screen
*screen
= dd_screen(_screen
)->screen
;
112 return screen
->get_shader_param(screen
, shader
, param
);
116 dd_screen_get_timestamp(struct pipe_screen
*_screen
)
118 struct pipe_screen
*screen
= dd_screen(_screen
)->screen
;
120 return screen
->get_timestamp(screen
);
123 static void dd_screen_query_memory_info(struct pipe_screen
*_screen
,
124 struct pipe_memory_info
*info
)
126 struct pipe_screen
*screen
= dd_screen(_screen
)->screen
;
128 return screen
->query_memory_info(screen
, info
);
131 static struct pipe_context
*
132 dd_screen_context_create(struct pipe_screen
*_screen
, void *priv
,
135 struct dd_screen
*dscreen
= dd_screen(_screen
);
136 struct pipe_screen
*screen
= dscreen
->screen
;
138 flags
|= PIPE_CONTEXT_DEBUG
;
140 return dd_context_create(dscreen
,
141 screen
->context_create(screen
, priv
, flags
));
145 dd_screen_is_format_supported(struct pipe_screen
*_screen
,
146 enum pipe_format format
,
147 enum pipe_texture_target target
,
148 unsigned sample_count
,
151 struct pipe_screen
*screen
= dd_screen(_screen
)->screen
;
153 return screen
->is_format_supported(screen
, format
, target
, sample_count
,
158 dd_screen_can_create_resource(struct pipe_screen
*_screen
,
159 const struct pipe_resource
*templat
)
161 struct pipe_screen
*screen
= dd_screen(_screen
)->screen
;
163 return screen
->can_create_resource(screen
, templat
);
167 dd_screen_flush_frontbuffer(struct pipe_screen
*_screen
,
168 struct pipe_resource
*resource
,
169 unsigned level
, unsigned layer
,
170 void *context_private
,
171 struct pipe_box
*sub_box
)
173 struct pipe_screen
*screen
= dd_screen(_screen
)->screen
;
175 screen
->flush_frontbuffer(screen
, resource
, level
, layer
, context_private
,
180 dd_screen_get_driver_query_info(struct pipe_screen
*_screen
,
182 struct pipe_driver_query_info
*info
)
184 struct pipe_screen
*screen
= dd_screen(_screen
)->screen
;
186 return screen
->get_driver_query_info(screen
, index
, info
);
190 dd_screen_get_driver_query_group_info(struct pipe_screen
*_screen
,
192 struct pipe_driver_query_group_info
*info
)
194 struct pipe_screen
*screen
= dd_screen(_screen
)->screen
;
196 return screen
->get_driver_query_group_info(screen
, index
, info
);
201 dd_screen_get_driver_uuid(struct pipe_screen
*_screen
, char *uuid
)
203 struct pipe_screen
*screen
= dd_screen(_screen
)->screen
;
205 screen
->get_driver_uuid(screen
, uuid
);
209 dd_screen_get_device_uuid(struct pipe_screen
*_screen
, char *uuid
)
211 struct pipe_screen
*screen
= dd_screen(_screen
)->screen
;
213 screen
->get_device_uuid(screen
, uuid
);
216 /********************************************************************
220 static struct pipe_resource
*
221 dd_screen_resource_create(struct pipe_screen
*_screen
,
222 const struct pipe_resource
*templat
)
224 struct pipe_screen
*screen
= dd_screen(_screen
)->screen
;
225 struct pipe_resource
*res
= screen
->resource_create(screen
, templat
);
229 res
->screen
= _screen
;
233 static struct pipe_resource
*
234 dd_screen_resource_from_handle(struct pipe_screen
*_screen
,
235 const struct pipe_resource
*templ
,
236 struct winsys_handle
*handle
,
239 struct pipe_screen
*screen
= dd_screen(_screen
)->screen
;
240 struct pipe_resource
*res
=
241 screen
->resource_from_handle(screen
, templ
, handle
, usage
);
245 res
->screen
= _screen
;
249 static struct pipe_resource
*
250 dd_screen_resource_from_user_memory(struct pipe_screen
*_screen
,
251 const struct pipe_resource
*templ
,
254 struct pipe_screen
*screen
= dd_screen(_screen
)->screen
;
255 struct pipe_resource
*res
=
256 screen
->resource_from_user_memory(screen
, templ
, user_memory
);
260 res
->screen
= _screen
;
264 static struct pipe_resource
*
265 dd_screen_resource_from_memobj(struct pipe_screen
*_screen
,
266 const struct pipe_resource
*templ
,
267 struct pipe_memory_object
*memobj
,
270 struct pipe_screen
*screen
= dd_screen(_screen
)->screen
;
271 struct pipe_resource
*res
=
272 screen
->resource_from_memobj(screen
, templ
, memobj
, offset
);
276 res
->screen
= _screen
;
281 dd_screen_resource_changed(struct pipe_screen
*_screen
,
282 struct pipe_resource
*res
)
284 struct pipe_screen
*screen
= dd_screen(_screen
)->screen
;
286 screen
->resource_changed(screen
, res
);
290 dd_screen_resource_destroy(struct pipe_screen
*_screen
,
291 struct pipe_resource
*res
)
293 struct pipe_screen
*screen
= dd_screen(_screen
)->screen
;
295 screen
->resource_destroy(screen
, res
);
299 dd_screen_resource_get_handle(struct pipe_screen
*_screen
,
300 struct pipe_context
*_pipe
,
301 struct pipe_resource
*resource
,
302 struct winsys_handle
*handle
,
305 struct pipe_screen
*screen
= dd_screen(_screen
)->screen
;
306 struct pipe_context
*pipe
= _pipe
? dd_context(_pipe
)->pipe
: NULL
;
308 return screen
->resource_get_handle(screen
, pipe
, resource
, handle
, usage
);
312 /********************************************************************
317 dd_screen_fence_reference(struct pipe_screen
*_screen
,
318 struct pipe_fence_handle
**pdst
,
319 struct pipe_fence_handle
*src
)
321 struct pipe_screen
*screen
= dd_screen(_screen
)->screen
;
323 screen
->fence_reference(screen
, pdst
, src
);
327 dd_screen_fence_finish(struct pipe_screen
*_screen
,
328 struct pipe_context
*_ctx
,
329 struct pipe_fence_handle
*fence
,
332 struct pipe_screen
*screen
= dd_screen(_screen
)->screen
;
333 struct pipe_context
*ctx
= _ctx
? dd_context(_ctx
)->pipe
: NULL
;
335 return screen
->fence_finish(screen
, ctx
, fence
, timeout
);
338 /********************************************************************
342 static struct pipe_memory_object
*
343 dd_screen_memobj_create_from_handle(struct pipe_screen
*_screen
,
344 struct winsys_handle
*handle
,
347 struct pipe_screen
*screen
= dd_screen(_screen
)->screen
;
349 return screen
->memobj_create_from_handle(screen
, handle
, dedicated
);
353 dd_screen_memobj_destroy(struct pipe_screen
*_screen
,
354 struct pipe_memory_object
*memobj
)
356 struct pipe_screen
*screen
= dd_screen(_screen
)->screen
;
358 screen
->memobj_destroy(screen
, memobj
);
360 /********************************************************************
365 dd_screen_destroy(struct pipe_screen
*_screen
)
367 struct dd_screen
*dscreen
= dd_screen(_screen
);
368 struct pipe_screen
*screen
= dscreen
->screen
;
370 screen
->destroy(screen
);
375 ddebug_screen_create(struct pipe_screen
*screen
)
377 struct dd_screen
*dscreen
;
380 unsigned timeout
= 0;
381 unsigned apitrace_dump_call
= 0;
384 option
= debug_get_option("GALLIUM_DDEBUG", NULL
);
388 if (!strcmp(option
, "help")) {
389 puts("Gallium driver debugger");
393 puts(" GALLIUM_DDEBUG=\"always [noflush] [verbose]\"");
394 puts(" Flush and dump context and driver information after every draw call into");
395 puts(" $HOME/"DD_DIR
"/.");
397 puts(" GALLIUM_DDEBUG=\"[timeout in ms] [noflush] [verbose]\"");
398 puts(" Flush and detect a device hang after every draw call based on the given");
399 puts(" fence timeout and dump context and driver information into");
400 puts(" $HOME/"DD_DIR
"/ when a hang is detected.");
402 puts(" GALLIUM_DDEBUG=\"pipelined [timeout in ms] [verbose]\"");
403 puts(" Detect a device hang after every draw call based on the given fence");
404 puts(" timeout without flushes and dump context and driver information into");
405 puts(" $HOME/"DD_DIR
"/ when a hang is detected.");
407 puts(" GALLIUM_DDEBUG=\"apitrace [call#] [verbose]\"");
408 puts(" Dump apitrace draw call information into $HOME/"DD_DIR
"/. Implies 'noflush'.");
410 puts(" If 'noflush' is specified, do not flush on every draw call. In hang");
411 puts(" detection mode, this only detect hangs in pipe->flush.");
412 puts(" If 'verbose' is specified, additional information is written to stderr.");
414 puts(" GALLIUM_DDEBUG_SKIP=[count]");
415 puts(" Skip flush and hang detection for the given initial number of draw calls.");
420 no_flush
= strstr(option
, "noflush") != NULL
;
422 if (!strncmp(option
, "always", 6)) {
423 mode
= DD_DUMP_ALL_CALLS
;
424 } else if (!strncmp(option
, "apitrace", 8)) {
425 mode
= DD_DUMP_APITRACE_CALL
;
428 if (sscanf(option
+8, "%u", &apitrace_dump_call
) != 1)
430 } else if (!strncmp(option
, "pipelined", 9)) {
431 mode
= DD_DETECT_HANGS_PIPELINED
;
433 if (sscanf(option
+10, "%u", &timeout
) != 1)
436 mode
= DD_DETECT_HANGS
;
438 if (sscanf(option
, "%u", &timeout
) != 1)
442 dscreen
= CALLOC_STRUCT(dd_screen
);
446 #define SCR_INIT(_member) \
447 dscreen->base._member = screen->_member ? dd_screen_##_member : NULL
449 dscreen
->base
.destroy
= dd_screen_destroy
;
450 dscreen
->base
.get_name
= dd_screen_get_name
;
451 dscreen
->base
.get_vendor
= dd_screen_get_vendor
;
452 dscreen
->base
.get_device_vendor
= dd_screen_get_device_vendor
;
453 SCR_INIT(get_disk_shader_cache
);
454 dscreen
->base
.get_param
= dd_screen_get_param
;
455 dscreen
->base
.get_paramf
= dd_screen_get_paramf
;
456 dscreen
->base
.get_compute_param
= dd_screen_get_compute_param
;
457 dscreen
->base
.get_shader_param
= dd_screen_get_shader_param
;
458 dscreen
->base
.query_memory_info
= dd_screen_query_memory_info
;
459 /* get_video_param */
460 /* get_compute_param */
461 SCR_INIT(get_timestamp
);
462 dscreen
->base
.context_create
= dd_screen_context_create
;
463 dscreen
->base
.is_format_supported
= dd_screen_is_format_supported
;
464 /* is_video_format_supported */
465 SCR_INIT(can_create_resource
);
466 dscreen
->base
.resource_create
= dd_screen_resource_create
;
467 dscreen
->base
.resource_from_handle
= dd_screen_resource_from_handle
;
468 SCR_INIT(resource_from_memobj
);
469 SCR_INIT(resource_from_user_memory
);
470 dscreen
->base
.resource_get_handle
= dd_screen_resource_get_handle
;
471 SCR_INIT(resource_changed
);
472 dscreen
->base
.resource_destroy
= dd_screen_resource_destroy
;
473 SCR_INIT(flush_frontbuffer
);
474 SCR_INIT(fence_reference
);
475 SCR_INIT(fence_finish
);
476 SCR_INIT(memobj_create_from_handle
);
477 SCR_INIT(memobj_destroy
);
478 SCR_INIT(get_driver_query_info
);
479 SCR_INIT(get_driver_query_group_info
);
480 SCR_INIT(get_compiler_options
);
481 SCR_INIT(get_driver_uuid
);
482 SCR_INIT(get_device_uuid
);
486 dscreen
->screen
= screen
;
487 dscreen
->timeout_ms
= timeout
;
488 dscreen
->mode
= mode
;
489 dscreen
->no_flush
= no_flush
;
490 dscreen
->verbose
= strstr(option
, "verbose") != NULL
;
491 dscreen
->apitrace_dump_call
= apitrace_dump_call
;
493 switch (dscreen
->mode
) {
494 case DD_DUMP_ALL_CALLS
:
495 fprintf(stderr
, "Gallium debugger active. Logging all calls.\n");
497 case DD_DETECT_HANGS
:
498 case DD_DETECT_HANGS_PIPELINED
:
499 fprintf(stderr
, "Gallium debugger active. "
500 "The hang detection timeout is %i ms.\n", timeout
);
502 case DD_DUMP_APITRACE_CALL
:
503 fprintf(stderr
, "Gallium debugger active. Going to dump an apitrace call.\n");
509 dscreen
->skip_count
= debug_get_num_option("GALLIUM_DDEBUG_SKIP", 0);
510 if (dscreen
->skip_count
> 0) {
511 fprintf(stderr
, "Gallium debugger skipping the first %u draw calls.\n",
512 dscreen
->skip_count
);
515 return &dscreen
->base
;