1 /**************************************************************************
3 * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
4 * Copyright (c) 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
9 * "Software"), to deal in the Software without restriction, including
10 * without limitation the rights to use, copy, modify, merge, publish,
11 * distribute, sub license, and/or sell copies of the Software, and to
12 * permit persons to whom the Software is furnished to do so, subject to
13 * the following conditions:
15 * The above copyright notice and this permission notice (including the
16 * next paragraph) shall be included in all copies or substantial portions
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
22 * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
23 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
24 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
25 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 **************************************************************************/
30 #include "pipe/p_config.h"
35 #ifdef PIPE_SUBSYSTEM_WINDOWS_DISPLAY
40 #elif defined(PIPE_SUBSYSTEM_WINDOWS_CE)
47 #elif defined(PIPE_SUBSYSTEM_WINDOWS_USER)
49 #ifndef WIN32_LEAN_AND_MEAN
50 #define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
62 #include "pipe/p_compiler.h"
63 #include "util/u_debug.h"
64 #include "pipe/p_format.h"
65 #include "pipe/p_state.h"
66 #include "pipe/p_inlines.h"
67 #include "util/u_format.h"
68 #include "util/u_memory.h"
69 #include "util/u_string.h"
70 #include "util/u_stream.h"
71 #include "util/u_math.h"
72 #include "util/u_tile.h"
73 #include "util/u_prim.h"
76 #ifdef PIPE_SUBSYSTEM_WINDOWS_DISPLAY
78 _EngDebugPrint(const char *format
, ...)
82 EngDebugPrint("", (PCHAR
)format
, ap
);
88 void _debug_vprintf(const char *format
, va_list ap
)
90 #if defined(PIPE_SUBSYSTEM_WINDOWS_DISPLAY)
91 /* EngDebugPrint does not handle float point arguments, so we need to use
92 * our own vsnprintf implementation. It is also very slow, so buffer until
93 * we find a newline. */
94 static char buf
[512] = {'\0'};
95 size_t len
= strlen(buf
);
96 int ret
= util_vsnprintf(buf
+ len
, sizeof(buf
) - len
, format
, ap
);
97 if(ret
> (int)(sizeof(buf
) - len
- 1) || util_strchr(buf
+ len
, '\n')) {
98 _EngDebugPrint("%s", buf
);
101 #elif defined(PIPE_SUBSYSTEM_WINDOWS_USER)
102 /* OutputDebugStringA can be very slow, so buffer until we find a newline. */
103 static char buf
[4096] = {'\0'};
104 size_t len
= strlen(buf
);
105 int ret
= util_vsnprintf(buf
+ len
, sizeof(buf
) - len
, format
, ap
);
106 if(ret
> (int)(sizeof(buf
) - len
- 1) || util_strchr(buf
+ len
, '\n')) {
107 OutputDebugStringA(buf
);
111 if(GetConsoleWindow() && !IsDebuggerPresent()) {
113 vfprintf(stderr
, format
, ap
);
117 #elif defined(PIPE_SUBSYSTEM_WINDOWS_CE)
118 wchar_t *wide_format
;
122 #if (_WIN32_WCE < 600)
123 ret
= vsprintf(buf
, format
, ap
);
125 sprintf(buf
, "Cant handle debug print!");
129 ret
= vsprintf_s(buf
, 512, format
, ap
);
131 sprintf_s(buf
, 512, "Cant handle debug print!");
136 /* Format is ascii - needs to be converted to wchar_t for printing */
137 wide_str_len
= MultiByteToWideChar(CP_ACP
, 0, (const char *) buf
, -1, NULL
, 0);
138 wide_format
= (wchar_t *) malloc((wide_str_len
+1) * sizeof(wchar_t));
140 MultiByteToWideChar(CP_ACP
, 0, (const char *) buf
, -1,
141 wide_format
, wide_str_len
);
142 NKDbgPrintfW(wide_format
, wide_format
);
145 #elif defined(PIPE_SUBSYSTEM_WINDOWS_MINIPORT)
147 #else /* !PIPE_SUBSYSTEM_WINDOWS */
149 vfprintf(stderr
, format
, ap
);
155 void debug_print_blob( const char *name
,
159 const unsigned *ublob
= (const unsigned *)blob
;
162 debug_printf("%s (%d dwords%s)\n", name
, size
/4,
163 size
%4 ? "... plus a few bytes" : "");
165 for (i
= 0; i
< size
/4; i
++) {
166 debug_printf("%d:\t%08x\n", i
, ublob
[i
]);
173 void debug_break(void)
175 #if defined(PIPE_SUBSYSTEM_WINDOWS_USER)
177 #elif defined(PIPE_SUBSYSTEM_WINDOWS_DISPLAY)
186 #ifdef PIPE_SUBSYSTEM_WINDOWS_DISPLAY
188 find(const char *start
, const char *end
, char c
)
191 for(p
= start
; !end
|| p
!= end
; ++p
) {
201 compare(const char *start
, const char *end
, const char *s
)
204 for(p
= start
, q
= s
; p
!= end
&& *q
!= '\0'; ++p
, ++q
) {
208 return p
== end
&& *q
== '\0';
212 copy(char *dst
, const char *start
, const char *end
, size_t n
)
216 for(p
= start
, q
= dst
, n
= n
- 1; p
!= end
&& n
; ++p
, ++q
, --n
)
223 static INLINE
const char *
224 _debug_get_option(const char *name
)
226 #if defined(PIPE_SUBSYSTEM_WINDOWS_DISPLAY)
227 /* EngMapFile creates the file if it does not exists, so it must either be
228 * disabled on release versions (or put in a less conspicuous place). */
230 const char *result
= NULL
;
232 const void *pMap
= NULL
;
233 const char *sol
, *eol
, *sep
;
234 static char output
[1024];
236 pMap
= EngMapFile(L
"\\??\\c:\\gallium.cfg", 0, &iFile
);
238 sol
= (const char *)pMap
;
240 /* TODO: handle LF line endings */
241 eol
= find(sol
, NULL
, '\r');
242 if(!eol
|| eol
== sol
)
244 sep
= find(sol
, eol
, '=');
247 if(compare(sol
, sep
, name
)) {
248 copy(output
, sep
+ 1, eol
, sizeof(output
));
260 #elif defined(PIPE_SUBSYSTEM_WINDOWS_CE) || defined(PIPE_SUBSYSTEM_WINDOWS_MINIPORT)
261 /* TODO: implement */
269 debug_get_option(const char *name
, const char *dfault
)
273 result
= _debug_get_option(name
);
277 debug_printf("%s: %s = %s\n", __FUNCTION__
, name
, result
? result
: "(null)");
283 debug_get_bool_option(const char *name
, boolean dfault
)
285 const char *str
= _debug_get_option(name
);
290 else if(!util_strcmp(str
, "n"))
292 else if(!util_strcmp(str
, "no"))
294 else if(!util_strcmp(str
, "0"))
296 else if(!util_strcmp(str
, "f"))
298 else if(!util_strcmp(str
, "false"))
303 debug_printf("%s: %s = %s\n", __FUNCTION__
, name
, result
? "TRUE" : "FALSE");
310 debug_get_num_option(const char *name
, long dfault
)
315 str
= _debug_get_option(name
);
330 while('0' <= c
&& c
<= '9') {
331 result
= result
*10 + (c
- '0');
337 debug_printf("%s: %s = %li\n", __FUNCTION__
, name
, result
);
344 debug_get_flags_option(const char *name
,
345 const struct debug_named_value
*flags
,
346 unsigned long dfault
)
348 unsigned long result
;
351 str
= _debug_get_option(name
);
354 else if (!util_strcmp(str
, "help")) {
356 while (flags
->name
) {
357 debug_printf("%s: help for %s: %s [0x%lx]\n", __FUNCTION__
, name
, flags
->name
, flags
->value
);
363 while( flags
->name
) {
364 if (!util_strcmp(str
, "all") || util_strstr(str
, flags
->name
))
365 result
|= flags
->value
;
371 debug_printf("%s: %s = 0x%lx (%s)\n", __FUNCTION__
, name
, result
, str
);
374 debug_printf("%s: %s = 0x%lx\n", __FUNCTION__
, name
, result
);
381 void _debug_assert_fail(const char *expr
,
384 const char *function
)
386 _debug_printf("%s:%u:%s: Assertion `%s' failed.\n", file
, line
, function
, expr
);
387 #if defined(PIPE_OS_WINDOWS) && !defined(PIPE_SUBSYSTEM_WINDOWS_USER)
388 if (debug_get_bool_option("GALLIUM_ABORT_ON_ASSERT", FALSE
))
390 if (debug_get_bool_option("GALLIUM_ABORT_ON_ASSERT", TRUE
))
394 _debug_printf("continuing...\n");
399 debug_dump_enum(const struct debug_named_value
*names
,
402 static char rest
[64];
405 if(names
->value
== value
)
410 util_snprintf(rest
, sizeof(rest
), "0x%08lx", value
);
416 debug_dump_enum_noprefix(const struct debug_named_value
*names
,
420 static char rest
[64];
423 if(names
->value
== value
) {
424 const char *name
= names
->name
;
425 while (*name
== *prefix
) {
436 util_snprintf(rest
, sizeof(rest
), "0x%08lx", value
);
442 debug_dump_flags(const struct debug_named_value
*names
,
445 static char output
[4096];
446 static char rest
[256];
452 if((names
->value
& value
) == names
->value
) {
454 util_strncat(output
, "|", sizeof(output
));
457 util_strncat(output
, names
->name
, sizeof(output
) - 1);
458 output
[sizeof(output
) - 1] = '\0';
459 value
&= ~names
->value
;
466 util_strncat(output
, "|", sizeof(output
));
470 util_snprintf(rest
, sizeof(rest
), "0x%08lx", value
);
471 util_strncat(output
, rest
, sizeof(output
) - 1);
472 output
[sizeof(output
) - 1] = '\0';
482 static const struct debug_named_value pipe_format_names
[] = {
484 DEBUG_NAMED_VALUE(PIPE_FORMAT_NONE
),
485 DEBUG_NAMED_VALUE(PIPE_FORMAT_A8R8G8B8_UNORM
),
486 DEBUG_NAMED_VALUE(PIPE_FORMAT_X8R8G8B8_UNORM
),
487 DEBUG_NAMED_VALUE(PIPE_FORMAT_B8G8R8A8_UNORM
),
488 DEBUG_NAMED_VALUE(PIPE_FORMAT_B8G8R8X8_UNORM
),
489 DEBUG_NAMED_VALUE(PIPE_FORMAT_A1R5G5B5_UNORM
),
490 DEBUG_NAMED_VALUE(PIPE_FORMAT_A4R4G4B4_UNORM
),
491 DEBUG_NAMED_VALUE(PIPE_FORMAT_R5G6B5_UNORM
),
492 DEBUG_NAMED_VALUE(PIPE_FORMAT_A2B10G10R10_UNORM
),
493 DEBUG_NAMED_VALUE(PIPE_FORMAT_L8_UNORM
),
494 DEBUG_NAMED_VALUE(PIPE_FORMAT_A8_UNORM
),
495 DEBUG_NAMED_VALUE(PIPE_FORMAT_I8_UNORM
),
496 DEBUG_NAMED_VALUE(PIPE_FORMAT_A8L8_UNORM
),
497 DEBUG_NAMED_VALUE(PIPE_FORMAT_L16_UNORM
),
498 DEBUG_NAMED_VALUE(PIPE_FORMAT_YCBCR
),
499 DEBUG_NAMED_VALUE(PIPE_FORMAT_YCBCR_REV
),
500 DEBUG_NAMED_VALUE(PIPE_FORMAT_Z16_UNORM
),
501 DEBUG_NAMED_VALUE(PIPE_FORMAT_Z32_UNORM
),
502 DEBUG_NAMED_VALUE(PIPE_FORMAT_Z32_FLOAT
),
503 DEBUG_NAMED_VALUE(PIPE_FORMAT_S8Z24_UNORM
),
504 DEBUG_NAMED_VALUE(PIPE_FORMAT_Z24S8_UNORM
),
505 DEBUG_NAMED_VALUE(PIPE_FORMAT_X8Z24_UNORM
),
506 DEBUG_NAMED_VALUE(PIPE_FORMAT_Z24X8_UNORM
),
507 DEBUG_NAMED_VALUE(PIPE_FORMAT_S8_UNORM
),
508 DEBUG_NAMED_VALUE(PIPE_FORMAT_R64_FLOAT
),
509 DEBUG_NAMED_VALUE(PIPE_FORMAT_R64G64_FLOAT
),
510 DEBUG_NAMED_VALUE(PIPE_FORMAT_R64G64B64_FLOAT
),
511 DEBUG_NAMED_VALUE(PIPE_FORMAT_R64G64B64A64_FLOAT
),
512 DEBUG_NAMED_VALUE(PIPE_FORMAT_R32_FLOAT
),
513 DEBUG_NAMED_VALUE(PIPE_FORMAT_R32G32_FLOAT
),
514 DEBUG_NAMED_VALUE(PIPE_FORMAT_R32G32B32_FLOAT
),
515 DEBUG_NAMED_VALUE(PIPE_FORMAT_R32G32B32A32_FLOAT
),
516 DEBUG_NAMED_VALUE(PIPE_FORMAT_R32_UNORM
),
517 DEBUG_NAMED_VALUE(PIPE_FORMAT_R32G32_UNORM
),
518 DEBUG_NAMED_VALUE(PIPE_FORMAT_R32G32B32_UNORM
),
519 DEBUG_NAMED_VALUE(PIPE_FORMAT_R32G32B32A32_UNORM
),
520 DEBUG_NAMED_VALUE(PIPE_FORMAT_R32_USCALED
),
521 DEBUG_NAMED_VALUE(PIPE_FORMAT_R32G32_USCALED
),
522 DEBUG_NAMED_VALUE(PIPE_FORMAT_R32G32B32_USCALED
),
523 DEBUG_NAMED_VALUE(PIPE_FORMAT_R32G32B32A32_USCALED
),
524 DEBUG_NAMED_VALUE(PIPE_FORMAT_R32_SNORM
),
525 DEBUG_NAMED_VALUE(PIPE_FORMAT_R32G32_SNORM
),
526 DEBUG_NAMED_VALUE(PIPE_FORMAT_R32G32B32_SNORM
),
527 DEBUG_NAMED_VALUE(PIPE_FORMAT_R32G32B32A32_SNORM
),
528 DEBUG_NAMED_VALUE(PIPE_FORMAT_R32_SSCALED
),
529 DEBUG_NAMED_VALUE(PIPE_FORMAT_R32G32_SSCALED
),
530 DEBUG_NAMED_VALUE(PIPE_FORMAT_R32G32B32_SSCALED
),
531 DEBUG_NAMED_VALUE(PIPE_FORMAT_R32G32B32A32_SSCALED
),
532 DEBUG_NAMED_VALUE(PIPE_FORMAT_R16_UNORM
),
533 DEBUG_NAMED_VALUE(PIPE_FORMAT_R16G16_UNORM
),
534 DEBUG_NAMED_VALUE(PIPE_FORMAT_R16G16B16_UNORM
),
535 DEBUG_NAMED_VALUE(PIPE_FORMAT_R16G16B16A16_UNORM
),
536 DEBUG_NAMED_VALUE(PIPE_FORMAT_R16_USCALED
),
537 DEBUG_NAMED_VALUE(PIPE_FORMAT_R16G16_USCALED
),
538 DEBUG_NAMED_VALUE(PIPE_FORMAT_R16G16B16_USCALED
),
539 DEBUG_NAMED_VALUE(PIPE_FORMAT_R16G16B16A16_USCALED
),
540 DEBUG_NAMED_VALUE(PIPE_FORMAT_R16_SNORM
),
541 DEBUG_NAMED_VALUE(PIPE_FORMAT_R16G16_SNORM
),
542 DEBUG_NAMED_VALUE(PIPE_FORMAT_R16G16B16_SNORM
),
543 DEBUG_NAMED_VALUE(PIPE_FORMAT_R16G16B16A16_SNORM
),
544 DEBUG_NAMED_VALUE(PIPE_FORMAT_R16_SSCALED
),
545 DEBUG_NAMED_VALUE(PIPE_FORMAT_R16G16_SSCALED
),
546 DEBUG_NAMED_VALUE(PIPE_FORMAT_R16G16B16_SSCALED
),
547 DEBUG_NAMED_VALUE(PIPE_FORMAT_R16G16B16A16_SSCALED
),
548 DEBUG_NAMED_VALUE(PIPE_FORMAT_R8_UNORM
),
549 DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8_UNORM
),
550 DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8B8_UNORM
),
551 DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8B8A8_UNORM
),
552 DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8B8X8_UNORM
),
553 DEBUG_NAMED_VALUE(PIPE_FORMAT_R8_USCALED
),
554 DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8_USCALED
),
555 DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8B8_USCALED
),
556 DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8B8A8_USCALED
),
557 DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8B8X8_USCALED
),
558 DEBUG_NAMED_VALUE(PIPE_FORMAT_R8_SNORM
),
559 DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8_SNORM
),
560 DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8B8_SNORM
),
561 DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8B8A8_SNORM
),
562 DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8B8X8_SNORM
),
563 DEBUG_NAMED_VALUE(PIPE_FORMAT_B6G5R5_SNORM
),
564 DEBUG_NAMED_VALUE(PIPE_FORMAT_A8B8G8R8_SNORM
),
565 DEBUG_NAMED_VALUE(PIPE_FORMAT_X8B8G8R8_SNORM
),
566 DEBUG_NAMED_VALUE(PIPE_FORMAT_R8_SSCALED
),
567 DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8_SSCALED
),
568 DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8B8_SSCALED
),
569 DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8B8A8_SSCALED
),
570 DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8B8X8_SSCALED
),
571 DEBUG_NAMED_VALUE(PIPE_FORMAT_L8_SRGB
),
572 DEBUG_NAMED_VALUE(PIPE_FORMAT_A8L8_SRGB
),
573 DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8B8_SRGB
),
574 DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8B8A8_SRGB
),
575 DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8B8X8_SRGB
),
576 DEBUG_NAMED_VALUE(PIPE_FORMAT_A8R8G8B8_SRGB
),
577 DEBUG_NAMED_VALUE(PIPE_FORMAT_X8R8G8B8_SRGB
),
578 DEBUG_NAMED_VALUE(PIPE_FORMAT_B8G8R8A8_SRGB
),
579 DEBUG_NAMED_VALUE(PIPE_FORMAT_B8G8R8X8_SRGB
),
580 DEBUG_NAMED_VALUE(PIPE_FORMAT_X8UB8UG8SR8S_NORM
),
581 DEBUG_NAMED_VALUE(PIPE_FORMAT_B6UG5SR5S_NORM
),
582 DEBUG_NAMED_VALUE(PIPE_FORMAT_DXT1_RGB
),
583 DEBUG_NAMED_VALUE(PIPE_FORMAT_DXT1_RGBA
),
584 DEBUG_NAMED_VALUE(PIPE_FORMAT_DXT3_RGBA
),
585 DEBUG_NAMED_VALUE(PIPE_FORMAT_DXT5_RGBA
),
586 DEBUG_NAMED_VALUE(PIPE_FORMAT_DXT1_SRGB
),
587 DEBUG_NAMED_VALUE(PIPE_FORMAT_DXT1_SRGBA
),
588 DEBUG_NAMED_VALUE(PIPE_FORMAT_DXT3_SRGBA
),
589 DEBUG_NAMED_VALUE(PIPE_FORMAT_DXT5_SRGBA
),
591 DEBUG_NAMED_VALUE_END
595 void debug_print_format(const char *msg
, unsigned fmt
)
597 debug_printf("%s: %s\n", msg
, debug_dump_enum(pipe_format_names
, fmt
));
601 const char *pf_name( enum pipe_format format
)
603 return debug_dump_enum(pipe_format_names
, format
);
608 static const struct debug_named_value pipe_prim_names
[] = {
610 DEBUG_NAMED_VALUE(PIPE_PRIM_POINTS
),
611 DEBUG_NAMED_VALUE(PIPE_PRIM_LINES
),
612 DEBUG_NAMED_VALUE(PIPE_PRIM_LINE_LOOP
),
613 DEBUG_NAMED_VALUE(PIPE_PRIM_LINE_STRIP
),
614 DEBUG_NAMED_VALUE(PIPE_PRIM_TRIANGLES
),
615 DEBUG_NAMED_VALUE(PIPE_PRIM_TRIANGLE_STRIP
),
616 DEBUG_NAMED_VALUE(PIPE_PRIM_TRIANGLE_FAN
),
617 DEBUG_NAMED_VALUE(PIPE_PRIM_QUADS
),
618 DEBUG_NAMED_VALUE(PIPE_PRIM_QUAD_STRIP
),
619 DEBUG_NAMED_VALUE(PIPE_PRIM_POLYGON
),
621 DEBUG_NAMED_VALUE_END
625 const char *u_prim_name( unsigned prim
)
627 return debug_dump_enum(pipe_prim_names
, prim
);
634 void debug_dump_image(const char *prefix
,
635 unsigned format
, unsigned cpp
,
636 unsigned width
, unsigned height
,
640 #ifdef PIPE_SUBSYSTEM_WINDOWS_DISPLAY
641 static unsigned no
= 0;
643 WCHAR wfilename
[sizeof(filename
)];
651 unsigned char *pMap
= NULL
;
654 util_snprintf(filename
, sizeof(filename
), "\\??\\c:\\%03u%s.raw", ++no
, prefix
);
655 for(i
= 0; i
< sizeof(filename
); ++i
)
656 wfilename
[i
] = (WCHAR
)filename
[i
];
658 pMap
= (unsigned char *)EngMapFile(wfilename
, sizeof(header
) + height
*width
*cpp
, &iFile
);
662 header
.format
= format
;
664 header
.width
= width
;
665 header
.height
= height
;
666 memcpy(pMap
, &header
, sizeof(header
));
667 pMap
+= sizeof(header
);
669 for(i
= 0; i
< height
; ++i
) {
670 memcpy(pMap
, (unsigned char *)data
+ stride
*i
, cpp
*width
);
678 void debug_dump_surface(const char *prefix
,
679 struct pipe_surface
*surface
)
681 struct pipe_texture
*texture
;
682 struct pipe_screen
*screen
;
683 struct pipe_transfer
*transfer
;
689 texture
= surface
->texture
;
690 screen
= texture
->screen
;
692 transfer
= screen
->get_tex_transfer(screen
, texture
, surface
->face
,
693 surface
->level
, surface
->zslice
,
694 PIPE_TRANSFER_READ
, 0, 0, surface
->width
,
697 data
= screen
->transfer_map(screen
, transfer
);
701 debug_dump_image(prefix
,
703 util_format_get_blocksize(texture
->format
),
704 util_format_get_nblocksx(texture
->format
, transfer
->width
),
705 util_format_get_nblocksy(texture
->format
, transfer
->height
),
709 screen
->transfer_unmap(screen
, transfer
);
711 screen
->tex_transfer_destroy(transfer
);
716 struct bmp_file_header
{
719 uint16_t bfReserved1
;
720 uint16_t bfReserved2
;
725 struct bmp_info_header
{
731 uint32_t biCompression
;
732 uint32_t biSizeImage
;
733 int32_t biXPelsPerMeter
;
734 int32_t biYPelsPerMeter
;
736 uint32_t biClrImportant
;
739 struct bmp_rgb_quad
{
747 debug_dump_surface_bmp(const char *filename
,
748 struct pipe_surface
*surface
)
750 #ifndef PIPE_SUBSYSTEM_WINDOWS_MINIPORT
751 struct pipe_transfer
*transfer
;
752 struct pipe_texture
*texture
= surface
->texture
;
753 struct pipe_screen
*screen
= texture
->screen
;
755 transfer
= screen
->get_tex_transfer(screen
, texture
, surface
->face
,
756 surface
->level
, surface
->zslice
,
757 PIPE_TRANSFER_READ
, 0, 0, surface
->width
,
760 debug_dump_transfer_bmp(filename
, transfer
);
762 screen
->tex_transfer_destroy(transfer
);
767 debug_dump_transfer_bmp(const char *filename
,
768 struct pipe_transfer
*transfer
)
770 #ifndef PIPE_SUBSYSTEM_WINDOWS_MINIPORT
776 rgba
= MALLOC(transfer
->width
*transfer
->height
*4*sizeof(float));
780 pipe_get_tile_rgba(transfer
, 0, 0,
781 transfer
->width
, transfer
->height
,
784 debug_dump_float_rgba_bmp(filename
,
785 transfer
->width
, transfer
->height
,
786 rgba
, transfer
->width
);
795 debug_dump_float_rgba_bmp(const char *filename
,
796 unsigned width
, unsigned height
,
797 float *rgba
, unsigned stride
)
799 #ifndef PIPE_SUBSYSTEM_WINDOWS_MINIPORT
800 struct util_stream
*stream
;
801 struct bmp_file_header bmfh
;
802 struct bmp_info_header bmih
;
808 bmfh
.bfType
= 0x4d42;
809 bmfh
.bfSize
= 14 + 40 + height
*width
*4;
810 bmfh
.bfReserved1
= 0;
811 bmfh
.bfReserved2
= 0;
812 bmfh
.bfOffBits
= 14 + 40;
815 bmih
.biWidth
= width
;
816 bmih
.biHeight
= height
;
818 bmih
.biBitCount
= 32;
819 bmih
.biCompression
= 0;
820 bmih
.biSizeImage
= height
*width
*4;
821 bmih
.biXPelsPerMeter
= 0;
822 bmih
.biYPelsPerMeter
= 0;
824 bmih
.biClrImportant
= 0;
826 stream
= util_stream_create(filename
, bmfh
.bfSize
);
830 util_stream_write(stream
, &bmfh
, 14);
831 util_stream_write(stream
, &bmih
, 40);
835 float *ptr
= rgba
+ (stride
* y
* 4);
836 for(x
= 0; x
< width
; ++x
)
838 struct bmp_rgb_quad pixel
;
839 pixel
.rgbRed
= float_to_ubyte(ptr
[x
*4 + 0]);
840 pixel
.rgbGreen
= float_to_ubyte(ptr
[x
*4 + 1]);
841 pixel
.rgbBlue
= float_to_ubyte(ptr
[x
*4 + 2]);
842 pixel
.rgbAlpha
= 255;
843 util_stream_write(stream
, &pixel
, 4);
847 util_stream_close(stream
);