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
,
152 struct pipe_screen
*screen
= dd_screen(_screen
)->screen
;
154 return screen
->is_format_supported(screen
, format
, target
, sample_count
,
159 dd_screen_can_create_resource(struct pipe_screen
*_screen
,
160 const struct pipe_resource
*templat
)
162 struct pipe_screen
*screen
= dd_screen(_screen
)->screen
;
164 return screen
->can_create_resource(screen
, templat
);
168 dd_screen_flush_frontbuffer(struct pipe_screen
*_screen
,
169 struct pipe_resource
*resource
,
170 unsigned level
, unsigned layer
,
171 void *context_private
,
172 struct pipe_box
*sub_box
)
174 struct pipe_screen
*screen
= dd_screen(_screen
)->screen
;
176 screen
->flush_frontbuffer(screen
, resource
, level
, layer
, context_private
,
181 dd_screen_get_driver_query_info(struct pipe_screen
*_screen
,
183 struct pipe_driver_query_info
*info
)
185 struct pipe_screen
*screen
= dd_screen(_screen
)->screen
;
187 return screen
->get_driver_query_info(screen
, index
, info
);
191 dd_screen_get_driver_query_group_info(struct pipe_screen
*_screen
,
193 struct pipe_driver_query_group_info
*info
)
195 struct pipe_screen
*screen
= dd_screen(_screen
)->screen
;
197 return screen
->get_driver_query_group_info(screen
, index
, info
);
202 dd_screen_get_driver_uuid(struct pipe_screen
*_screen
, char *uuid
)
204 struct pipe_screen
*screen
= dd_screen(_screen
)->screen
;
206 screen
->get_driver_uuid(screen
, uuid
);
210 dd_screen_get_device_uuid(struct pipe_screen
*_screen
, char *uuid
)
212 struct pipe_screen
*screen
= dd_screen(_screen
)->screen
;
214 screen
->get_device_uuid(screen
, uuid
);
217 /********************************************************************
221 static struct pipe_resource
*
222 dd_screen_resource_create(struct pipe_screen
*_screen
,
223 const struct pipe_resource
*templat
)
225 struct pipe_screen
*screen
= dd_screen(_screen
)->screen
;
226 struct pipe_resource
*res
= screen
->resource_create(screen
, templat
);
230 res
->screen
= _screen
;
234 static struct pipe_resource
*
235 dd_screen_resource_from_handle(struct pipe_screen
*_screen
,
236 const struct pipe_resource
*templ
,
237 struct winsys_handle
*handle
,
240 struct pipe_screen
*screen
= dd_screen(_screen
)->screen
;
241 struct pipe_resource
*res
=
242 screen
->resource_from_handle(screen
, templ
, handle
, usage
);
246 res
->screen
= _screen
;
250 static struct pipe_resource
*
251 dd_screen_resource_from_user_memory(struct pipe_screen
*_screen
,
252 const struct pipe_resource
*templ
,
255 struct pipe_screen
*screen
= dd_screen(_screen
)->screen
;
256 struct pipe_resource
*res
=
257 screen
->resource_from_user_memory(screen
, templ
, user_memory
);
261 res
->screen
= _screen
;
265 static struct pipe_resource
*
266 dd_screen_resource_from_memobj(struct pipe_screen
*_screen
,
267 const struct pipe_resource
*templ
,
268 struct pipe_memory_object
*memobj
,
271 struct pipe_screen
*screen
= dd_screen(_screen
)->screen
;
272 struct pipe_resource
*res
=
273 screen
->resource_from_memobj(screen
, templ
, memobj
, offset
);
277 res
->screen
= _screen
;
282 dd_screen_resource_changed(struct pipe_screen
*_screen
,
283 struct pipe_resource
*res
)
285 struct pipe_screen
*screen
= dd_screen(_screen
)->screen
;
287 screen
->resource_changed(screen
, res
);
291 dd_screen_resource_destroy(struct pipe_screen
*_screen
,
292 struct pipe_resource
*res
)
294 struct pipe_screen
*screen
= dd_screen(_screen
)->screen
;
296 screen
->resource_destroy(screen
, res
);
300 dd_screen_resource_get_handle(struct pipe_screen
*_screen
,
301 struct pipe_context
*_pipe
,
302 struct pipe_resource
*resource
,
303 struct winsys_handle
*handle
,
306 struct pipe_screen
*screen
= dd_screen(_screen
)->screen
;
307 struct pipe_context
*pipe
= _pipe
? dd_context(_pipe
)->pipe
: NULL
;
309 return screen
->resource_get_handle(screen
, pipe
, resource
, handle
, usage
);
313 dd_screen_check_resource_capability(struct pipe_screen
*_screen
,
314 struct pipe_resource
*resource
,
317 struct pipe_screen
*screen
= dd_screen(_screen
)->screen
;
319 return screen
->check_resource_capability(screen
, resource
, bind
);
323 /********************************************************************
328 dd_screen_fence_reference(struct pipe_screen
*_screen
,
329 struct pipe_fence_handle
**pdst
,
330 struct pipe_fence_handle
*src
)
332 struct pipe_screen
*screen
= dd_screen(_screen
)->screen
;
334 screen
->fence_reference(screen
, pdst
, src
);
338 dd_screen_fence_finish(struct pipe_screen
*_screen
,
339 struct pipe_context
*_ctx
,
340 struct pipe_fence_handle
*fence
,
343 struct pipe_screen
*screen
= dd_screen(_screen
)->screen
;
344 struct pipe_context
*ctx
= _ctx
? dd_context(_ctx
)->pipe
: NULL
;
346 return screen
->fence_finish(screen
, ctx
, fence
, timeout
);
349 /********************************************************************
353 static struct pipe_memory_object
*
354 dd_screen_memobj_create_from_handle(struct pipe_screen
*_screen
,
355 struct winsys_handle
*handle
,
358 struct pipe_screen
*screen
= dd_screen(_screen
)->screen
;
360 return screen
->memobj_create_from_handle(screen
, handle
, dedicated
);
364 dd_screen_memobj_destroy(struct pipe_screen
*_screen
,
365 struct pipe_memory_object
*memobj
)
367 struct pipe_screen
*screen
= dd_screen(_screen
)->screen
;
369 screen
->memobj_destroy(screen
, memobj
);
371 /********************************************************************
376 dd_screen_destroy(struct pipe_screen
*_screen
)
378 struct dd_screen
*dscreen
= dd_screen(_screen
);
379 struct pipe_screen
*screen
= dscreen
->screen
;
381 screen
->destroy(screen
);
386 skip_space(const char **p
)
393 match_word(const char **cur
, const char *word
)
395 size_t len
= strlen(word
);
396 if (strncmp(*cur
, word
, len
) != 0)
399 const char *p
= *cur
+ len
;
413 match_uint(const char **cur
, unsigned *value
)
416 unsigned v
= strtoul(*cur
, &end
, 0);
417 if (end
== *cur
|| (*end
&& !isspace(*end
)))
425 ddebug_screen_create(struct pipe_screen
*screen
)
427 struct dd_screen
*dscreen
;
430 bool verbose
= false;
431 bool transfers
= false;
432 unsigned timeout
= 1000;
433 unsigned apitrace_dump_call
= 0;
434 enum dd_dump_mode mode
= DD_DUMP_ONLY_HANGS
;
436 option
= debug_get_option("GALLIUM_DDEBUG", NULL
);
440 if (!strcmp(option
, "help")) {
441 puts("Gallium driver debugger");
445 puts(" GALLIUM_DDEBUG=\"[<timeout in ms>] [(always|apitrace <call#)] [flush] [transfers] [verbose]\"");
446 puts(" GALLIUM_DDEBUG_SKIP=[count]");
448 puts("Dump context and driver information of draw calls into");
449 puts("$HOME/"DD_DIR
"/. By default, watch for GPU hangs and only dump information");
450 puts("about draw calls related to the hang.");
452 puts("<timeout in ms>");
453 puts(" Change the default timeout for GPU hang detection (default=1000ms).");
454 puts(" Setting this to 0 will disable GPU hang detection entirely.");
457 puts(" Dump information about all draw calls.");
460 puts(" Also dump and do hang detection on transfers.");
462 puts("apitrace <call#>");
463 puts(" Dump information about the draw call corresponding to the given");
464 puts(" apitrace call number and exit.");
467 puts(" Flush after every draw call.");
470 puts(" Write additional information to stderr.");
472 puts("GALLIUM_DDEBUG_SKIP=count");
473 puts(" Skip dumping on the first count draw calls (only relevant with 'always').");
483 if (match_word(&option
, "always")) {
484 if (mode
== DD_DUMP_APITRACE_CALL
) {
485 printf("ddebug: both 'always' and 'apitrace' specified\n");
489 mode
= DD_DUMP_ALL_CALLS
;
490 } else if (match_word(&option
, "flush")) {
492 } else if (match_word(&option
, "transfers")) {
494 } else if (match_word(&option
, "verbose")) {
496 } else if (match_word(&option
, "apitrace")) {
497 if (mode
!= DD_DUMP_ONLY_HANGS
) {
498 printf("ddebug: 'apitrace' can only appear once and not mixed with 'always'\n");
502 if (!match_uint(&option
, &apitrace_dump_call
)) {
503 printf("ddebug: expected call number after 'apitrace'\n");
507 mode
= DD_DUMP_APITRACE_CALL
;
508 } else if (match_uint(&option
, &timeout
)) {
511 printf("ddebug: bad options: %s\n", option
);
516 dscreen
= CALLOC_STRUCT(dd_screen
);
520 #define SCR_INIT(_member) \
521 dscreen->base._member = screen->_member ? dd_screen_##_member : NULL
523 dscreen
->base
.destroy
= dd_screen_destroy
;
524 dscreen
->base
.get_name
= dd_screen_get_name
;
525 dscreen
->base
.get_vendor
= dd_screen_get_vendor
;
526 dscreen
->base
.get_device_vendor
= dd_screen_get_device_vendor
;
527 SCR_INIT(get_disk_shader_cache
);
528 dscreen
->base
.get_param
= dd_screen_get_param
;
529 dscreen
->base
.get_paramf
= dd_screen_get_paramf
;
530 dscreen
->base
.get_compute_param
= dd_screen_get_compute_param
;
531 dscreen
->base
.get_shader_param
= dd_screen_get_shader_param
;
532 dscreen
->base
.query_memory_info
= dd_screen_query_memory_info
;
533 /* get_video_param */
534 /* get_compute_param */
535 SCR_INIT(get_timestamp
);
536 dscreen
->base
.context_create
= dd_screen_context_create
;
537 dscreen
->base
.is_format_supported
= dd_screen_is_format_supported
;
538 /* is_video_format_supported */
539 SCR_INIT(can_create_resource
);
540 dscreen
->base
.resource_create
= dd_screen_resource_create
;
541 dscreen
->base
.resource_from_handle
= dd_screen_resource_from_handle
;
542 SCR_INIT(resource_from_memobj
);
543 SCR_INIT(resource_from_user_memory
);
544 SCR_INIT(check_resource_capability
);
545 dscreen
->base
.resource_get_handle
= dd_screen_resource_get_handle
;
546 SCR_INIT(resource_changed
);
547 dscreen
->base
.resource_destroy
= dd_screen_resource_destroy
;
548 SCR_INIT(flush_frontbuffer
);
549 SCR_INIT(fence_reference
);
550 SCR_INIT(fence_finish
);
551 SCR_INIT(memobj_create_from_handle
);
552 SCR_INIT(memobj_destroy
);
553 SCR_INIT(get_driver_query_info
);
554 SCR_INIT(get_driver_query_group_info
);
555 SCR_INIT(get_compiler_options
);
556 SCR_INIT(get_driver_uuid
);
557 SCR_INIT(get_device_uuid
);
561 dscreen
->screen
= screen
;
562 dscreen
->timeout_ms
= timeout
;
563 dscreen
->dump_mode
= mode
;
564 dscreen
->flush_always
= flush
;
565 dscreen
->transfers
= transfers
;
566 dscreen
->verbose
= verbose
;
567 dscreen
->apitrace_dump_call
= apitrace_dump_call
;
569 switch (dscreen
->dump_mode
) {
570 case DD_DUMP_ALL_CALLS
:
571 fprintf(stderr
, "Gallium debugger active. Logging all calls.\n");
573 case DD_DUMP_APITRACE_CALL
:
574 fprintf(stderr
, "Gallium debugger active. Going to dump an apitrace call.\n");
577 fprintf(stderr
, "Gallium debugger active.\n");
581 if (dscreen
->timeout_ms
> 0)
582 fprintf(stderr
, "Hang detection timeout is %ums.\n", dscreen
->timeout_ms
);
584 fprintf(stderr
, "Hang detection is disabled.\n");
586 dscreen
->skip_count
= debug_get_num_option("GALLIUM_DDEBUG_SKIP", 0);
587 if (dscreen
->skip_count
> 0) {
588 fprintf(stderr
, "Gallium debugger skipping the first %u draw calls.\n",
589 dscreen
->skip_count
);
592 return &dscreen
->base
;