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"
36 dd_screen_get_name(struct pipe_screen
*_screen
)
38 struct pipe_screen
*screen
= dd_screen(_screen
)->screen
;
40 return screen
->get_name(screen
);
44 dd_screen_get_vendor(struct pipe_screen
*_screen
)
46 struct pipe_screen
*screen
= dd_screen(_screen
)->screen
;
48 return screen
->get_vendor(screen
);
52 dd_screen_get_device_vendor(struct pipe_screen
*_screen
)
54 struct pipe_screen
*screen
= dd_screen(_screen
)->screen
;
56 return screen
->get_device_vendor(screen
);
60 dd_screen_get_compiler_options(struct pipe_screen
*_screen
,
61 enum pipe_shader_ir ir
,
62 enum pipe_shader_type shader
)
64 struct pipe_screen
*screen
= dd_screen(_screen
)->screen
;
66 return screen
->get_compiler_options(screen
, ir
, shader
);
69 static struct disk_cache
*
70 dd_screen_get_disk_shader_cache(struct pipe_screen
*_screen
)
72 struct pipe_screen
*screen
= dd_screen(_screen
)->screen
;
74 return screen
->get_disk_shader_cache(screen
);
78 dd_screen_get_param(struct pipe_screen
*_screen
,
81 struct pipe_screen
*screen
= dd_screen(_screen
)->screen
;
83 return screen
->get_param(screen
, param
);
87 dd_screen_get_paramf(struct pipe_screen
*_screen
,
90 struct pipe_screen
*screen
= dd_screen(_screen
)->screen
;
92 return screen
->get_paramf(screen
, param
);
96 dd_screen_get_compute_param(struct pipe_screen
*_screen
,
97 enum pipe_shader_ir ir_type
,
98 enum pipe_compute_cap param
,
101 struct pipe_screen
*screen
= dd_screen(_screen
)->screen
;
103 return screen
->get_compute_param(screen
, ir_type
, param
, ret
);
107 dd_screen_get_shader_param(struct pipe_screen
*_screen
,
108 enum pipe_shader_type shader
,
109 enum pipe_shader_cap param
)
111 struct pipe_screen
*screen
= dd_screen(_screen
)->screen
;
113 return screen
->get_shader_param(screen
, shader
, param
);
117 dd_screen_get_timestamp(struct pipe_screen
*_screen
)
119 struct pipe_screen
*screen
= dd_screen(_screen
)->screen
;
121 return screen
->get_timestamp(screen
);
124 static void dd_screen_query_memory_info(struct pipe_screen
*_screen
,
125 struct pipe_memory_info
*info
)
127 struct pipe_screen
*screen
= dd_screen(_screen
)->screen
;
129 return screen
->query_memory_info(screen
, info
);
132 static struct pipe_context
*
133 dd_screen_context_create(struct pipe_screen
*_screen
, void *priv
,
136 struct dd_screen
*dscreen
= dd_screen(_screen
);
137 struct pipe_screen
*screen
= dscreen
->screen
;
139 flags
|= PIPE_CONTEXT_DEBUG
;
141 return dd_context_create(dscreen
,
142 screen
->context_create(screen
, priv
, flags
));
146 dd_screen_is_format_supported(struct pipe_screen
*_screen
,
147 enum pipe_format format
,
148 enum pipe_texture_target target
,
149 unsigned sample_count
,
150 unsigned storage_sample_count
,
153 struct pipe_screen
*screen
= dd_screen(_screen
)->screen
;
155 return screen
->is_format_supported(screen
, format
, target
, sample_count
,
156 storage_sample_count
, tex_usage
);
160 dd_screen_can_create_resource(struct pipe_screen
*_screen
,
161 const struct pipe_resource
*templat
)
163 struct pipe_screen
*screen
= dd_screen(_screen
)->screen
;
165 return screen
->can_create_resource(screen
, templat
);
169 dd_screen_flush_frontbuffer(struct pipe_screen
*_screen
,
170 struct pipe_resource
*resource
,
171 unsigned level
, unsigned layer
,
172 void *context_private
,
173 struct pipe_box
*sub_box
)
175 struct pipe_screen
*screen
= dd_screen(_screen
)->screen
;
177 screen
->flush_frontbuffer(screen
, resource
, level
, layer
, context_private
,
182 dd_screen_get_driver_query_info(struct pipe_screen
*_screen
,
184 struct pipe_driver_query_info
*info
)
186 struct pipe_screen
*screen
= dd_screen(_screen
)->screen
;
188 return screen
->get_driver_query_info(screen
, index
, info
);
192 dd_screen_get_driver_query_group_info(struct pipe_screen
*_screen
,
194 struct pipe_driver_query_group_info
*info
)
196 struct pipe_screen
*screen
= dd_screen(_screen
)->screen
;
198 return screen
->get_driver_query_group_info(screen
, index
, info
);
203 dd_screen_get_driver_uuid(struct pipe_screen
*_screen
, char *uuid
)
205 struct pipe_screen
*screen
= dd_screen(_screen
)->screen
;
207 screen
->get_driver_uuid(screen
, uuid
);
211 dd_screen_get_device_uuid(struct pipe_screen
*_screen
, char *uuid
)
213 struct pipe_screen
*screen
= dd_screen(_screen
)->screen
;
215 screen
->get_device_uuid(screen
, uuid
);
218 /********************************************************************
222 static struct pipe_resource
*
223 dd_screen_resource_create(struct pipe_screen
*_screen
,
224 const struct pipe_resource
*templat
)
226 struct pipe_screen
*screen
= dd_screen(_screen
)->screen
;
227 struct pipe_resource
*res
= screen
->resource_create(screen
, templat
);
231 res
->screen
= _screen
;
235 static struct pipe_resource
*
236 dd_screen_resource_from_handle(struct pipe_screen
*_screen
,
237 const struct pipe_resource
*templ
,
238 struct winsys_handle
*handle
,
241 struct pipe_screen
*screen
= dd_screen(_screen
)->screen
;
242 struct pipe_resource
*res
=
243 screen
->resource_from_handle(screen
, templ
, handle
, usage
);
247 res
->screen
= _screen
;
251 static struct pipe_resource
*
252 dd_screen_resource_from_user_memory(struct pipe_screen
*_screen
,
253 const struct pipe_resource
*templ
,
256 struct pipe_screen
*screen
= dd_screen(_screen
)->screen
;
257 struct pipe_resource
*res
=
258 screen
->resource_from_user_memory(screen
, templ
, user_memory
);
262 res
->screen
= _screen
;
266 static struct pipe_resource
*
267 dd_screen_resource_from_memobj(struct pipe_screen
*_screen
,
268 const struct pipe_resource
*templ
,
269 struct pipe_memory_object
*memobj
,
272 struct pipe_screen
*screen
= dd_screen(_screen
)->screen
;
273 struct pipe_resource
*res
=
274 screen
->resource_from_memobj(screen
, templ
, memobj
, offset
);
278 res
->screen
= _screen
;
283 dd_screen_resource_changed(struct pipe_screen
*_screen
,
284 struct pipe_resource
*res
)
286 struct pipe_screen
*screen
= dd_screen(_screen
)->screen
;
288 if (screen
->resource_changed
)
289 screen
->resource_changed(screen
, res
);
293 dd_screen_resource_destroy(struct pipe_screen
*_screen
,
294 struct pipe_resource
*res
)
296 struct pipe_screen
*screen
= dd_screen(_screen
)->screen
;
298 screen
->resource_destroy(screen
, res
);
302 dd_screen_resource_get_handle(struct pipe_screen
*_screen
,
303 struct pipe_context
*_pipe
,
304 struct pipe_resource
*resource
,
305 struct winsys_handle
*handle
,
308 struct pipe_screen
*screen
= dd_screen(_screen
)->screen
;
309 struct pipe_context
*pipe
= _pipe
? dd_context(_pipe
)->pipe
: NULL
;
311 return screen
->resource_get_handle(screen
, pipe
, resource
, handle
, usage
);
315 dd_screen_check_resource_capability(struct pipe_screen
*_screen
,
316 struct pipe_resource
*resource
,
319 struct pipe_screen
*screen
= dd_screen(_screen
)->screen
;
321 return screen
->check_resource_capability(screen
, resource
, bind
);
325 /********************************************************************
330 dd_screen_fence_reference(struct pipe_screen
*_screen
,
331 struct pipe_fence_handle
**pdst
,
332 struct pipe_fence_handle
*src
)
334 struct pipe_screen
*screen
= dd_screen(_screen
)->screen
;
336 screen
->fence_reference(screen
, pdst
, src
);
340 dd_screen_fence_finish(struct pipe_screen
*_screen
,
341 struct pipe_context
*_ctx
,
342 struct pipe_fence_handle
*fence
,
345 struct pipe_screen
*screen
= dd_screen(_screen
)->screen
;
346 struct pipe_context
*ctx
= _ctx
? dd_context(_ctx
)->pipe
: NULL
;
348 return screen
->fence_finish(screen
, ctx
, fence
, timeout
);
351 /********************************************************************
355 static struct pipe_memory_object
*
356 dd_screen_memobj_create_from_handle(struct pipe_screen
*_screen
,
357 struct winsys_handle
*handle
,
360 struct pipe_screen
*screen
= dd_screen(_screen
)->screen
;
362 return screen
->memobj_create_from_handle(screen
, handle
, dedicated
);
366 dd_screen_memobj_destroy(struct pipe_screen
*_screen
,
367 struct pipe_memory_object
*memobj
)
369 struct pipe_screen
*screen
= dd_screen(_screen
)->screen
;
371 screen
->memobj_destroy(screen
, memobj
);
373 /********************************************************************
378 dd_screen_destroy(struct pipe_screen
*_screen
)
380 struct dd_screen
*dscreen
= dd_screen(_screen
);
381 struct pipe_screen
*screen
= dscreen
->screen
;
383 screen
->destroy(screen
);
388 skip_space(const char **p
)
395 match_word(const char **cur
, const char *word
)
397 size_t len
= strlen(word
);
398 if (strncmp(*cur
, word
, len
) != 0)
401 const char *p
= *cur
+ len
;
415 match_uint(const char **cur
, unsigned *value
)
418 unsigned v
= strtoul(*cur
, &end
, 0);
419 if (end
== *cur
|| (*end
&& !isspace(*end
)))
427 ddebug_screen_create(struct pipe_screen
*screen
)
429 struct dd_screen
*dscreen
;
432 bool verbose
= false;
433 bool transfers
= false;
434 unsigned timeout
= 1000;
435 unsigned apitrace_dump_call
= 0;
436 enum dd_dump_mode mode
= DD_DUMP_ONLY_HANGS
;
438 option
= debug_get_option("GALLIUM_DDEBUG", NULL
);
442 if (!strcmp(option
, "help")) {
443 puts("Gallium driver debugger");
447 puts(" GALLIUM_DDEBUG=\"[<timeout in ms>] [(always|apitrace <call#)] [flush] [transfers] [verbose]\"");
448 puts(" GALLIUM_DDEBUG_SKIP=[count]");
450 puts("Dump context and driver information of draw calls into");
451 puts("$HOME/"DD_DIR
"/. By default, watch for GPU hangs and only dump information");
452 puts("about draw calls related to the hang.");
454 puts("<timeout in ms>");
455 puts(" Change the default timeout for GPU hang detection (default=1000ms).");
456 puts(" Setting this to 0 will disable GPU hang detection entirely.");
459 puts(" Dump information about all draw calls.");
462 puts(" Also dump and do hang detection on transfers.");
464 puts("apitrace <call#>");
465 puts(" Dump information about the draw call corresponding to the given");
466 puts(" apitrace call number and exit.");
469 puts(" Flush after every draw call.");
472 puts(" Write additional information to stderr.");
474 puts("GALLIUM_DDEBUG_SKIP=count");
475 puts(" Skip dumping on the first count draw calls (only relevant with 'always').");
485 if (match_word(&option
, "always")) {
486 if (mode
== DD_DUMP_APITRACE_CALL
) {
487 printf("ddebug: both 'always' and 'apitrace' specified\n");
491 mode
= DD_DUMP_ALL_CALLS
;
492 } else if (match_word(&option
, "flush")) {
494 } else if (match_word(&option
, "transfers")) {
496 } else if (match_word(&option
, "verbose")) {
498 } else if (match_word(&option
, "apitrace")) {
499 if (mode
!= DD_DUMP_ONLY_HANGS
) {
500 printf("ddebug: 'apitrace' can only appear once and not mixed with 'always'\n");
504 if (!match_uint(&option
, &apitrace_dump_call
)) {
505 printf("ddebug: expected call number after 'apitrace'\n");
509 mode
= DD_DUMP_APITRACE_CALL
;
510 } else if (match_uint(&option
, &timeout
)) {
513 printf("ddebug: bad options: %s\n", option
);
518 dscreen
= CALLOC_STRUCT(dd_screen
);
522 #define SCR_INIT(_member) \
523 dscreen->base._member = screen->_member ? dd_screen_##_member : NULL
525 dscreen
->base
.destroy
= dd_screen_destroy
;
526 dscreen
->base
.get_name
= dd_screen_get_name
;
527 dscreen
->base
.get_vendor
= dd_screen_get_vendor
;
528 dscreen
->base
.get_device_vendor
= dd_screen_get_device_vendor
;
529 SCR_INIT(get_disk_shader_cache
);
530 dscreen
->base
.get_param
= dd_screen_get_param
;
531 dscreen
->base
.get_paramf
= dd_screen_get_paramf
;
532 dscreen
->base
.get_compute_param
= dd_screen_get_compute_param
;
533 dscreen
->base
.get_shader_param
= dd_screen_get_shader_param
;
534 dscreen
->base
.query_memory_info
= dd_screen_query_memory_info
;
535 /* get_video_param */
536 /* get_compute_param */
537 SCR_INIT(get_timestamp
);
538 dscreen
->base
.context_create
= dd_screen_context_create
;
539 dscreen
->base
.is_format_supported
= dd_screen_is_format_supported
;
540 /* is_video_format_supported */
541 SCR_INIT(can_create_resource
);
542 dscreen
->base
.resource_create
= dd_screen_resource_create
;
543 dscreen
->base
.resource_from_handle
= dd_screen_resource_from_handle
;
544 SCR_INIT(resource_from_memobj
);
545 SCR_INIT(resource_from_user_memory
);
546 SCR_INIT(check_resource_capability
);
547 dscreen
->base
.resource_get_handle
= dd_screen_resource_get_handle
;
548 SCR_INIT(resource_changed
);
549 dscreen
->base
.resource_destroy
= dd_screen_resource_destroy
;
550 SCR_INIT(flush_frontbuffer
);
551 SCR_INIT(fence_reference
);
552 SCR_INIT(fence_finish
);
553 SCR_INIT(memobj_create_from_handle
);
554 SCR_INIT(memobj_destroy
);
555 SCR_INIT(get_driver_query_info
);
556 SCR_INIT(get_driver_query_group_info
);
557 SCR_INIT(get_compiler_options
);
558 SCR_INIT(get_driver_uuid
);
559 SCR_INIT(get_device_uuid
);
563 dscreen
->screen
= screen
;
564 dscreen
->timeout_ms
= timeout
;
565 dscreen
->dump_mode
= mode
;
566 dscreen
->flush_always
= flush
;
567 dscreen
->transfers
= transfers
;
568 dscreen
->verbose
= verbose
;
569 dscreen
->apitrace_dump_call
= apitrace_dump_call
;
571 switch (dscreen
->dump_mode
) {
572 case DD_DUMP_ALL_CALLS
:
573 fprintf(stderr
, "Gallium debugger active. Logging all calls.\n");
575 case DD_DUMP_APITRACE_CALL
:
576 fprintf(stderr
, "Gallium debugger active. Going to dump an apitrace call.\n");
579 fprintf(stderr
, "Gallium debugger active.\n");
583 if (dscreen
->timeout_ms
> 0)
584 fprintf(stderr
, "Hang detection timeout is %ums.\n", dscreen
->timeout_ms
);
586 fprintf(stderr
, "Hang detection is disabled.\n");
588 dscreen
->skip_count
= debug_get_num_option("GALLIUM_DDEBUG_SKIP", 0);
589 if (dscreen
->skip_count
> 0) {
590 fprintf(stderr
, "Gallium debugger skipping the first %u draw calls.\n",
591 dscreen
->skip_count
);
594 return &dscreen
->base
;