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 if (screen
->resource_changed
)
288 screen
->resource_changed(screen
, res
);
292 dd_screen_resource_destroy(struct pipe_screen
*_screen
,
293 struct pipe_resource
*res
)
295 struct pipe_screen
*screen
= dd_screen(_screen
)->screen
;
297 screen
->resource_destroy(screen
, res
);
301 dd_screen_resource_get_handle(struct pipe_screen
*_screen
,
302 struct pipe_context
*_pipe
,
303 struct pipe_resource
*resource
,
304 struct winsys_handle
*handle
,
307 struct pipe_screen
*screen
= dd_screen(_screen
)->screen
;
308 struct pipe_context
*pipe
= _pipe
? dd_context(_pipe
)->pipe
: NULL
;
310 return screen
->resource_get_handle(screen
, pipe
, resource
, handle
, usage
);
314 dd_screen_check_resource_capability(struct pipe_screen
*_screen
,
315 struct pipe_resource
*resource
,
318 struct pipe_screen
*screen
= dd_screen(_screen
)->screen
;
320 return screen
->check_resource_capability(screen
, resource
, bind
);
324 /********************************************************************
329 dd_screen_fence_reference(struct pipe_screen
*_screen
,
330 struct pipe_fence_handle
**pdst
,
331 struct pipe_fence_handle
*src
)
333 struct pipe_screen
*screen
= dd_screen(_screen
)->screen
;
335 screen
->fence_reference(screen
, pdst
, src
);
339 dd_screen_fence_finish(struct pipe_screen
*_screen
,
340 struct pipe_context
*_ctx
,
341 struct pipe_fence_handle
*fence
,
344 struct pipe_screen
*screen
= dd_screen(_screen
)->screen
;
345 struct pipe_context
*ctx
= _ctx
? dd_context(_ctx
)->pipe
: NULL
;
347 return screen
->fence_finish(screen
, ctx
, fence
, timeout
);
350 /********************************************************************
354 static struct pipe_memory_object
*
355 dd_screen_memobj_create_from_handle(struct pipe_screen
*_screen
,
356 struct winsys_handle
*handle
,
359 struct pipe_screen
*screen
= dd_screen(_screen
)->screen
;
361 return screen
->memobj_create_from_handle(screen
, handle
, dedicated
);
365 dd_screen_memobj_destroy(struct pipe_screen
*_screen
,
366 struct pipe_memory_object
*memobj
)
368 struct pipe_screen
*screen
= dd_screen(_screen
)->screen
;
370 screen
->memobj_destroy(screen
, memobj
);
372 /********************************************************************
377 dd_screen_destroy(struct pipe_screen
*_screen
)
379 struct dd_screen
*dscreen
= dd_screen(_screen
);
380 struct pipe_screen
*screen
= dscreen
->screen
;
382 screen
->destroy(screen
);
387 skip_space(const char **p
)
394 match_word(const char **cur
, const char *word
)
396 size_t len
= strlen(word
);
397 if (strncmp(*cur
, word
, len
) != 0)
400 const char *p
= *cur
+ len
;
414 match_uint(const char **cur
, unsigned *value
)
417 unsigned v
= strtoul(*cur
, &end
, 0);
418 if (end
== *cur
|| (*end
&& !isspace(*end
)))
426 ddebug_screen_create(struct pipe_screen
*screen
)
428 struct dd_screen
*dscreen
;
431 bool verbose
= false;
432 bool transfers
= false;
433 unsigned timeout
= 1000;
434 unsigned apitrace_dump_call
= 0;
435 enum dd_dump_mode mode
= DD_DUMP_ONLY_HANGS
;
437 option
= debug_get_option("GALLIUM_DDEBUG", NULL
);
441 if (!strcmp(option
, "help")) {
442 puts("Gallium driver debugger");
446 puts(" GALLIUM_DDEBUG=\"[<timeout in ms>] [(always|apitrace <call#)] [flush] [transfers] [verbose]\"");
447 puts(" GALLIUM_DDEBUG_SKIP=[count]");
449 puts("Dump context and driver information of draw calls into");
450 puts("$HOME/"DD_DIR
"/. By default, watch for GPU hangs and only dump information");
451 puts("about draw calls related to the hang.");
453 puts("<timeout in ms>");
454 puts(" Change the default timeout for GPU hang detection (default=1000ms).");
455 puts(" Setting this to 0 will disable GPU hang detection entirely.");
458 puts(" Dump information about all draw calls.");
461 puts(" Also dump and do hang detection on transfers.");
463 puts("apitrace <call#>");
464 puts(" Dump information about the draw call corresponding to the given");
465 puts(" apitrace call number and exit.");
468 puts(" Flush after every draw call.");
471 puts(" Write additional information to stderr.");
473 puts("GALLIUM_DDEBUG_SKIP=count");
474 puts(" Skip dumping on the first count draw calls (only relevant with 'always').");
484 if (match_word(&option
, "always")) {
485 if (mode
== DD_DUMP_APITRACE_CALL
) {
486 printf("ddebug: both 'always' and 'apitrace' specified\n");
490 mode
= DD_DUMP_ALL_CALLS
;
491 } else if (match_word(&option
, "flush")) {
493 } else if (match_word(&option
, "transfers")) {
495 } else if (match_word(&option
, "verbose")) {
497 } else if (match_word(&option
, "apitrace")) {
498 if (mode
!= DD_DUMP_ONLY_HANGS
) {
499 printf("ddebug: 'apitrace' can only appear once and not mixed with 'always'\n");
503 if (!match_uint(&option
, &apitrace_dump_call
)) {
504 printf("ddebug: expected call number after 'apitrace'\n");
508 mode
= DD_DUMP_APITRACE_CALL
;
509 } else if (match_uint(&option
, &timeout
)) {
512 printf("ddebug: bad options: %s\n", option
);
517 dscreen
= CALLOC_STRUCT(dd_screen
);
521 #define SCR_INIT(_member) \
522 dscreen->base._member = screen->_member ? dd_screen_##_member : NULL
524 dscreen
->base
.destroy
= dd_screen_destroy
;
525 dscreen
->base
.get_name
= dd_screen_get_name
;
526 dscreen
->base
.get_vendor
= dd_screen_get_vendor
;
527 dscreen
->base
.get_device_vendor
= dd_screen_get_device_vendor
;
528 SCR_INIT(get_disk_shader_cache
);
529 dscreen
->base
.get_param
= dd_screen_get_param
;
530 dscreen
->base
.get_paramf
= dd_screen_get_paramf
;
531 dscreen
->base
.get_compute_param
= dd_screen_get_compute_param
;
532 dscreen
->base
.get_shader_param
= dd_screen_get_shader_param
;
533 dscreen
->base
.query_memory_info
= dd_screen_query_memory_info
;
534 /* get_video_param */
535 /* get_compute_param */
536 SCR_INIT(get_timestamp
);
537 dscreen
->base
.context_create
= dd_screen_context_create
;
538 dscreen
->base
.is_format_supported
= dd_screen_is_format_supported
;
539 /* is_video_format_supported */
540 SCR_INIT(can_create_resource
);
541 dscreen
->base
.resource_create
= dd_screen_resource_create
;
542 dscreen
->base
.resource_from_handle
= dd_screen_resource_from_handle
;
543 SCR_INIT(resource_from_memobj
);
544 SCR_INIT(resource_from_user_memory
);
545 SCR_INIT(check_resource_capability
);
546 dscreen
->base
.resource_get_handle
= dd_screen_resource_get_handle
;
547 SCR_INIT(resource_changed
);
548 dscreen
->base
.resource_destroy
= dd_screen_resource_destroy
;
549 SCR_INIT(flush_frontbuffer
);
550 SCR_INIT(fence_reference
);
551 SCR_INIT(fence_finish
);
552 SCR_INIT(memobj_create_from_handle
);
553 SCR_INIT(memobj_destroy
);
554 SCR_INIT(get_driver_query_info
);
555 SCR_INIT(get_driver_query_group_info
);
556 SCR_INIT(get_compiler_options
);
557 SCR_INIT(get_driver_uuid
);
558 SCR_INIT(get_device_uuid
);
562 dscreen
->screen
= screen
;
563 dscreen
->timeout_ms
= timeout
;
564 dscreen
->dump_mode
= mode
;
565 dscreen
->flush_always
= flush
;
566 dscreen
->transfers
= transfers
;
567 dscreen
->verbose
= verbose
;
568 dscreen
->apitrace_dump_call
= apitrace_dump_call
;
570 switch (dscreen
->dump_mode
) {
571 case DD_DUMP_ALL_CALLS
:
572 fprintf(stderr
, "Gallium debugger active. Logging all calls.\n");
574 case DD_DUMP_APITRACE_CALL
:
575 fprintf(stderr
, "Gallium debugger active. Going to dump an apitrace call.\n");
578 fprintf(stderr
, "Gallium debugger active.\n");
582 if (dscreen
->timeout_ms
> 0)
583 fprintf(stderr
, "Hang detection timeout is %ums.\n", dscreen
->timeout_ms
);
585 fprintf(stderr
, "Hang detection is disabled.\n");
587 dscreen
->skip_count
= debug_get_num_option("GALLIUM_DDEBUG_SKIP", 0);
588 if (dscreen
->skip_count
> 0) {
589 fprintf(stderr
, "Gallium debugger skipping the first %u draw calls.\n",
590 dscreen
->skip_count
);
593 return &dscreen
->base
;