1 /**************************************************************************
3 * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sub license, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial portions
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21 * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
22 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 **************************************************************************/
29 #include "pipe/p_config.h"
33 #ifdef PIPE_SUBSYSTEM_WINDOWS_DISPLAY
41 #include "pipe/p_compiler.h"
42 #include "pipe/p_util.h"
43 #include "pipe/p_debug.h"
44 #include "pipe/p_format.h"
45 #include "util/u_string.h"
48 #ifdef PIPE_SUBSYSTEM_WINDOWS_DISPLAY
50 _EngDebugPrint(const char *format
, ...)
54 EngDebugPrint("", (PCHAR
)format
, ap
);
60 void _debug_vprintf(const char *format
, va_list ap
)
62 #ifdef PIPE_SUBSYSTEM_WINDOWS_DISPLAY
64 /* EngDebugPrint does not handle float point arguments, so we need to use
65 * our own vsnprintf implementation. It is also very slow, so buffer until
66 * we find a newline. */
67 static char buf
[512 + 1] = {'\0'};
68 size_t len
= strlen(buf
);
69 int ret
= util_vsnprintf(buf
+ len
, sizeof(buf
) - len
, format
, ap
);
70 if(ret
> (int)(sizeof(buf
) - len
- 1) || util_strchr(buf
+ len
, '\n')) {
71 _EngDebugPrint("%s", buf
);
75 /* TODO: Implement debug print for WINCE */
78 vfprintf(stderr
, format
, ap
);
84 void debug_print_blob( const char *name
,
88 const unsigned *ublob
= (const unsigned *)blob
;
91 debug_printf("%s (%d dwords%s)\n", name
, size
/4,
92 size
%4 ? "... plus a few bytes" : "");
94 for (i
= 0; i
< size
/4; i
++) {
95 debug_printf("%d:\t%08x\n", i
, ublob
[i
]);
101 void _debug_break(void)
103 #if (defined(__i386__) || defined(__386__)) && defined(__GNUC__)
105 #elif (defined(__i386__) || defined(__386__)) && defined(__MSC__)
107 #elif defined(PIPE_SUBSYSTEM_WINDOWS_DISPLAY)
115 #ifdef PIPE_SUBSYSTEM_WINDOWS_DISPLAY
117 find(const char *start
, const char *end
, char c
)
120 for(p
= start
; !end
|| p
!= end
; ++p
) {
130 compare(const char *start
, const char *end
, const char *s
)
133 for(p
= start
, q
= s
; p
!= end
&& *q
!= '\0'; ++p
, ++q
) {
137 return p
== end
&& *q
== '\0';
141 copy(char *dst
, const char *start
, const char *end
, size_t n
)
145 for(p
= start
, q
= dst
, n
= n
- 1; p
!= end
&& n
; ++p
, ++q
, --n
)
153 debug_get_option(const char *name
, const char *dfault
)
156 #ifdef PIPE_SUBSYSTEM_WINDOWS_DISPLAY
159 const void *pMap
= NULL
;
160 const char *sol
, *eol
, *sep
;
161 static char output
[1024];
164 /* XXX: this creates the file if it does not exists, so it must either be
165 * disabled on release versions, or put in a less conspicuous place.
167 pMap
= EngMapFile(L
"\\??\\c:\\gallium.cfg", 0, &iFile
);
169 sol
= (const char *)pMap
;
171 /* TODO: handle LF line endings */
172 eol
= find(sol
, NULL
, '\r');
173 if(!eol
|| eol
== sol
)
175 sep
= find(sol
, eol
, '=');
178 if(compare(sol
, sep
, name
)) {
179 copy(output
, sep
+ 1, eol
, sizeof(output
));
192 result
= getenv(name
);
197 debug_printf("%s: %s = %s\n", __FUNCTION__
, name
, result
? result
: "(null)");
203 debug_get_bool_option(const char *name
, boolean dfault
)
205 const char *str
= debug_get_option(name
, NULL
);
210 else if(!util_strcmp(str
, "n"))
212 else if(!util_strcmp(str
, "no"))
214 else if(!util_strcmp(str
, "0"))
216 else if(!util_strcmp(str
, "f"))
218 else if(!util_strcmp(str
, "false"))
223 debug_printf("%s: %s = %s\n", __FUNCTION__
, name
, result
? "TRUE" : "FALSE");
230 debug_get_num_option(const char *name
, long dfault
)
238 debug_get_flags_option(const char *name
,
239 const struct debug_named_value
*flags
,
240 unsigned long dfault
)
242 unsigned long result
;
245 str
= debug_get_option(name
, NULL
);
250 while( flags
->name
) {
251 if (!util_strcmp(str
, "all") || util_strstr(str
, flags
->name
))
252 result
|= flags
->value
;
257 debug_printf("%s: %s = 0x%lx\n", __FUNCTION__
, name
, result
);
263 void _debug_assert_fail(const char *expr
,
266 const char *function
)
268 _debug_printf("%s:%u:%s: Assertion `%s' failed.\n", file
, line
, function
, expr
);
269 if (debug_get_bool_option("GALLIUM_ABORT_ON_ASSERT", TRUE
))
272 _debug_printf("continuing...\n");
277 debug_dump_enum(const struct debug_named_value
*names
,
280 static char rest
[256];
283 if(names
->value
== value
)
288 util_snprintf(rest
, sizeof(rest
), "0x%08lx", value
);
294 debug_dump_flags(const struct debug_named_value
*names
,
297 static char output
[4096];
298 static char rest
[256];
304 if((names
->value
& value
) == names
->value
) {
306 util_strncat(output
, "|", sizeof(output
));
309 util_strncat(output
, names
->name
, sizeof(output
));
310 value
&= ~names
->value
;
317 util_strncat(output
, "|", sizeof(output
));
321 util_snprintf(rest
, sizeof(rest
), "0x%08lx", value
);
322 util_strncat(output
, rest
, sizeof(output
));
332 static const struct debug_named_value pipe_format_names
[] = {
334 DEBUG_NAMED_VALUE(PIPE_FORMAT_NONE
),
335 DEBUG_NAMED_VALUE(PIPE_FORMAT_A8R8G8B8_UNORM
),
336 DEBUG_NAMED_VALUE(PIPE_FORMAT_X8R8G8B8_UNORM
),
337 DEBUG_NAMED_VALUE(PIPE_FORMAT_B8G8R8A8_UNORM
),
338 DEBUG_NAMED_VALUE(PIPE_FORMAT_B8G8R8X8_UNORM
),
339 DEBUG_NAMED_VALUE(PIPE_FORMAT_A1R5G5B5_UNORM
),
340 DEBUG_NAMED_VALUE(PIPE_FORMAT_A4R4G4B4_UNORM
),
341 DEBUG_NAMED_VALUE(PIPE_FORMAT_R5G6B5_UNORM
),
342 DEBUG_NAMED_VALUE(PIPE_FORMAT_L8_UNORM
),
343 DEBUG_NAMED_VALUE(PIPE_FORMAT_A8_UNORM
),
344 DEBUG_NAMED_VALUE(PIPE_FORMAT_I8_UNORM
),
345 DEBUG_NAMED_VALUE(PIPE_FORMAT_A8L8_UNORM
),
346 DEBUG_NAMED_VALUE(PIPE_FORMAT_YCBCR
),
347 DEBUG_NAMED_VALUE(PIPE_FORMAT_YCBCR_REV
),
348 DEBUG_NAMED_VALUE(PIPE_FORMAT_Z16_UNORM
),
349 DEBUG_NAMED_VALUE(PIPE_FORMAT_Z32_UNORM
),
350 DEBUG_NAMED_VALUE(PIPE_FORMAT_Z32_FLOAT
),
351 DEBUG_NAMED_VALUE(PIPE_FORMAT_S8Z24_UNORM
),
352 DEBUG_NAMED_VALUE(PIPE_FORMAT_Z24S8_UNORM
),
353 DEBUG_NAMED_VALUE(PIPE_FORMAT_X8Z24_UNORM
),
354 DEBUG_NAMED_VALUE(PIPE_FORMAT_Z24X8_UNORM
),
355 DEBUG_NAMED_VALUE(PIPE_FORMAT_S8_UNORM
),
356 DEBUG_NAMED_VALUE(PIPE_FORMAT_R64_FLOAT
),
357 DEBUG_NAMED_VALUE(PIPE_FORMAT_R64G64_FLOAT
),
358 DEBUG_NAMED_VALUE(PIPE_FORMAT_R64G64B64_FLOAT
),
359 DEBUG_NAMED_VALUE(PIPE_FORMAT_R64G64B64A64_FLOAT
),
360 DEBUG_NAMED_VALUE(PIPE_FORMAT_R32_FLOAT
),
361 DEBUG_NAMED_VALUE(PIPE_FORMAT_R32G32_FLOAT
),
362 DEBUG_NAMED_VALUE(PIPE_FORMAT_R32G32B32_FLOAT
),
363 DEBUG_NAMED_VALUE(PIPE_FORMAT_R32G32B32A32_FLOAT
),
364 DEBUG_NAMED_VALUE(PIPE_FORMAT_R32_UNORM
),
365 DEBUG_NAMED_VALUE(PIPE_FORMAT_R32G32_UNORM
),
366 DEBUG_NAMED_VALUE(PIPE_FORMAT_R32G32B32_UNORM
),
367 DEBUG_NAMED_VALUE(PIPE_FORMAT_R32G32B32A32_UNORM
),
368 DEBUG_NAMED_VALUE(PIPE_FORMAT_R32_USCALED
),
369 DEBUG_NAMED_VALUE(PIPE_FORMAT_R32G32_USCALED
),
370 DEBUG_NAMED_VALUE(PIPE_FORMAT_R32G32B32_USCALED
),
371 DEBUG_NAMED_VALUE(PIPE_FORMAT_R32G32B32A32_USCALED
),
372 DEBUG_NAMED_VALUE(PIPE_FORMAT_R32_SNORM
),
373 DEBUG_NAMED_VALUE(PIPE_FORMAT_R32G32_SNORM
),
374 DEBUG_NAMED_VALUE(PIPE_FORMAT_R32G32B32_SNORM
),
375 DEBUG_NAMED_VALUE(PIPE_FORMAT_R32G32B32A32_SNORM
),
376 DEBUG_NAMED_VALUE(PIPE_FORMAT_R32_SSCALED
),
377 DEBUG_NAMED_VALUE(PIPE_FORMAT_R32G32_SSCALED
),
378 DEBUG_NAMED_VALUE(PIPE_FORMAT_R32G32B32_SSCALED
),
379 DEBUG_NAMED_VALUE(PIPE_FORMAT_R32G32B32A32_SSCALED
),
380 DEBUG_NAMED_VALUE(PIPE_FORMAT_R16_UNORM
),
381 DEBUG_NAMED_VALUE(PIPE_FORMAT_R16G16_UNORM
),
382 DEBUG_NAMED_VALUE(PIPE_FORMAT_R16G16B16_UNORM
),
383 DEBUG_NAMED_VALUE(PIPE_FORMAT_R16G16B16A16_UNORM
),
384 DEBUG_NAMED_VALUE(PIPE_FORMAT_R16_USCALED
),
385 DEBUG_NAMED_VALUE(PIPE_FORMAT_R16G16_USCALED
),
386 DEBUG_NAMED_VALUE(PIPE_FORMAT_R16G16B16_USCALED
),
387 DEBUG_NAMED_VALUE(PIPE_FORMAT_R16G16B16A16_USCALED
),
388 DEBUG_NAMED_VALUE(PIPE_FORMAT_R16_SNORM
),
389 DEBUG_NAMED_VALUE(PIPE_FORMAT_R16G16_SNORM
),
390 DEBUG_NAMED_VALUE(PIPE_FORMAT_R16G16B16_SNORM
),
391 DEBUG_NAMED_VALUE(PIPE_FORMAT_R16G16B16A16_SNORM
),
392 DEBUG_NAMED_VALUE(PIPE_FORMAT_R16_SSCALED
),
393 DEBUG_NAMED_VALUE(PIPE_FORMAT_R16G16_SSCALED
),
394 DEBUG_NAMED_VALUE(PIPE_FORMAT_R16G16B16_SSCALED
),
395 DEBUG_NAMED_VALUE(PIPE_FORMAT_R16G16B16A16_SSCALED
),
396 DEBUG_NAMED_VALUE(PIPE_FORMAT_R8_UNORM
),
397 DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8_UNORM
),
398 DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8B8_UNORM
),
399 DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8B8A8_UNORM
),
400 DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8B8X8_UNORM
),
401 DEBUG_NAMED_VALUE(PIPE_FORMAT_R8_USCALED
),
402 DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8_USCALED
),
403 DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8B8_USCALED
),
404 DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8B8A8_USCALED
),
405 DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8B8X8_USCALED
),
406 DEBUG_NAMED_VALUE(PIPE_FORMAT_R8_SNORM
),
407 DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8_SNORM
),
408 DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8B8_SNORM
),
409 DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8B8A8_SNORM
),
410 DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8B8X8_SNORM
),
411 DEBUG_NAMED_VALUE(PIPE_FORMAT_R8_SSCALED
),
412 DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8_SSCALED
),
413 DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8B8_SSCALED
),
414 DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8B8A8_SSCALED
),
415 DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8B8X8_SSCALED
),
416 DEBUG_NAMED_VALUE(PIPE_FORMAT_L8_SRGB
),
417 DEBUG_NAMED_VALUE(PIPE_FORMAT_A8_L8_SRGB
),
418 DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8B8_SRGB
),
419 DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8B8A8_SRGB
),
420 DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8B8X8_SRGB
),
421 DEBUG_NAMED_VALUE(PIPE_FORMAT_DXT1_RGB
),
422 DEBUG_NAMED_VALUE(PIPE_FORMAT_DXT1_RGBA
),
423 DEBUG_NAMED_VALUE(PIPE_FORMAT_DXT3_RGBA
),
424 DEBUG_NAMED_VALUE(PIPE_FORMAT_DXT5_RGBA
),
426 DEBUG_NAMED_VALUE_END
430 void debug_print_format(const char *msg
, unsigned fmt
)
432 debug_printf("%s: %s\n", msg
, debug_dump_enum(pipe_format_names
, fmt
));
436 char *pf_sprint_name( char *str
, enum pipe_format format
)
438 strcpy( str
, debug_dump_enum(pipe_format_names
, format
) );
444 void debug_dump_image(const char *prefix
,
445 unsigned format
, unsigned cpp
,
446 unsigned width
, unsigned height
,
450 #ifdef PIPE_SUBSYSTEM_WINDOWS_DISPLAY
451 static unsigned no
= 0;
453 WCHAR wfilename
[sizeof(filename
)];
461 unsigned char *pMap
= NULL
;
464 util_snprintf(filename
, sizeof(filename
), "\\??\\c:\\%03u%s.raw", ++no
, prefix
);
465 for(i
= 0; i
< sizeof(filename
); ++i
)
466 wfilename
[i
] = (WCHAR
)filename
[i
];
468 pMap
= (unsigned char *)EngMapFile(wfilename
, sizeof(header
) + cpp
*width
*height
, &iFile
);
472 header
.format
= format
;
474 header
.width
= width
;
475 header
.height
= height
;
476 memcpy(pMap
, &header
, sizeof(header
));
477 pMap
+= sizeof(header
);
479 for(i
= 0; i
< height
; ++i
) {
480 memcpy(pMap
, (unsigned char *)data
+ cpp
*pitch
*i
, cpp
*width
);