debug.c revision cdc920a0
17117f1b4Smrg/* 27117f1b4Smrg * Mesa 3-D graphics library 37117f1b4Smrg * Version: 6.5 47117f1b4Smrg * 57117f1b4Smrg * Copyright (C) 1999-2005 Brian Paul All Rights Reserved. 64a49301eSmrg * Copyright (C) 2009 VMware, Inc. All Rights Reserved. 77117f1b4Smrg * 87117f1b4Smrg * Permission is hereby granted, free of charge, to any person obtaining a 97117f1b4Smrg * copy of this software and associated documentation files (the "Software"), 107117f1b4Smrg * to deal in the Software without restriction, including without limitation 117117f1b4Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 127117f1b4Smrg * and/or sell copies of the Software, and to permit persons to whom the 137117f1b4Smrg * Software is furnished to do so, subject to the following conditions: 147117f1b4Smrg * 157117f1b4Smrg * The above copyright notice and this permission notice shall be included 167117f1b4Smrg * in all copies or substantial portions of the Software. 177117f1b4Smrg * 187117f1b4Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 197117f1b4Smrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 207117f1b4Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 217117f1b4Smrg * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 227117f1b4Smrg * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 237117f1b4Smrg * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 247117f1b4Smrg */ 257117f1b4Smrg 267117f1b4Smrg#include "mtypes.h" 274a49301eSmrg#include "attrib.h" 284a49301eSmrg#include "colormac.h" 294a49301eSmrg#include "enums.h" 304a49301eSmrg#include "formats.h" 314a49301eSmrg#include "hash.h" 327117f1b4Smrg#include "imports.h" 337117f1b4Smrg#include "debug.h" 347117f1b4Smrg#include "get.h" 354a49301eSmrg#include "pixelstore.h" 364a49301eSmrg#include "readpix.h" 374a49301eSmrg#include "texobj.h" 384a49301eSmrg 397117f1b4Smrg 407117f1b4Smrg/** 417117f1b4Smrg * Primitive names 427117f1b4Smrg */ 437117f1b4Smrgconst char *_mesa_prim_name[GL_POLYGON+4] = { 447117f1b4Smrg "GL_POINTS", 457117f1b4Smrg "GL_LINES", 467117f1b4Smrg "GL_LINE_LOOP", 477117f1b4Smrg "GL_LINE_STRIP", 487117f1b4Smrg "GL_TRIANGLES", 497117f1b4Smrg "GL_TRIANGLE_STRIP", 507117f1b4Smrg "GL_TRIANGLE_FAN", 517117f1b4Smrg "GL_QUADS", 527117f1b4Smrg "GL_QUAD_STRIP", 537117f1b4Smrg "GL_POLYGON", 547117f1b4Smrg "outside begin/end", 554a49301eSmrg "inside unknown primitive", 567117f1b4Smrg "unknown state" 577117f1b4Smrg}; 587117f1b4Smrg 594a49301eSmrg 604a49301eSmrgstatic const char * 614a49301eSmrgtex_target_name(GLenum tgt) 624a49301eSmrg{ 634a49301eSmrg static const struct { 644a49301eSmrg GLenum target; 654a49301eSmrg const char *name; 664a49301eSmrg } tex_targets[] = { 674a49301eSmrg { GL_TEXTURE_1D, "GL_TEXTURE_1D" }, 684a49301eSmrg { GL_TEXTURE_2D, "GL_TEXTURE_2D" }, 694a49301eSmrg { GL_TEXTURE_3D, "GL_TEXTURE_3D" }, 704a49301eSmrg { GL_TEXTURE_CUBE_MAP, "GL_TEXTURE_CUBE_MAP" }, 714a49301eSmrg { GL_TEXTURE_RECTANGLE, "GL_TEXTURE_RECTANGLE" }, 724a49301eSmrg { GL_TEXTURE_1D_ARRAY_EXT, "GL_TEXTURE_1D_ARRAY" }, 734a49301eSmrg { GL_TEXTURE_2D_ARRAY_EXT, "GL_TEXTURE_2D_ARRAY" } 744a49301eSmrg }; 754a49301eSmrg GLuint i; 764a49301eSmrg for (i = 0; i < Elements(tex_targets); i++) { 774a49301eSmrg if (tex_targets[i].target == tgt) 784a49301eSmrg return tex_targets[i].name; 794a49301eSmrg } 804a49301eSmrg return "UNKNOWN TEX TARGET"; 814a49301eSmrg} 824a49301eSmrg 834a49301eSmrg 847117f1b4Smrgvoid 857117f1b4Smrg_mesa_print_state( const char *msg, GLuint state ) 867117f1b4Smrg{ 877117f1b4Smrg _mesa_debug(NULL, 887117f1b4Smrg "%s: (0x%x) %s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n", 897117f1b4Smrg msg, 907117f1b4Smrg state, 917117f1b4Smrg (state & _NEW_MODELVIEW) ? "ctx->ModelView, " : "", 927117f1b4Smrg (state & _NEW_PROJECTION) ? "ctx->Projection, " : "", 937117f1b4Smrg (state & _NEW_TEXTURE_MATRIX) ? "ctx->TextureMatrix, " : "", 947117f1b4Smrg (state & _NEW_COLOR_MATRIX) ? "ctx->ColorMatrix, " : "", 957117f1b4Smrg (state & _NEW_ACCUM) ? "ctx->Accum, " : "", 967117f1b4Smrg (state & _NEW_COLOR) ? "ctx->Color, " : "", 977117f1b4Smrg (state & _NEW_DEPTH) ? "ctx->Depth, " : "", 987117f1b4Smrg (state & _NEW_EVAL) ? "ctx->Eval/EvalMap, " : "", 997117f1b4Smrg (state & _NEW_FOG) ? "ctx->Fog, " : "", 1007117f1b4Smrg (state & _NEW_HINT) ? "ctx->Hint, " : "", 1017117f1b4Smrg (state & _NEW_LIGHT) ? "ctx->Light, " : "", 1027117f1b4Smrg (state & _NEW_LINE) ? "ctx->Line, " : "", 1037117f1b4Smrg (state & _NEW_PIXEL) ? "ctx->Pixel, " : "", 1047117f1b4Smrg (state & _NEW_POINT) ? "ctx->Point, " : "", 1057117f1b4Smrg (state & _NEW_POLYGON) ? "ctx->Polygon, " : "", 1067117f1b4Smrg (state & _NEW_POLYGONSTIPPLE) ? "ctx->PolygonStipple, " : "", 1077117f1b4Smrg (state & _NEW_SCISSOR) ? "ctx->Scissor, " : "", 1087117f1b4Smrg (state & _NEW_TEXTURE) ? "ctx->Texture, " : "", 1097117f1b4Smrg (state & _NEW_TRANSFORM) ? "ctx->Transform, " : "", 1107117f1b4Smrg (state & _NEW_VIEWPORT) ? "ctx->Viewport, " : "", 1117117f1b4Smrg (state & _NEW_PACKUNPACK) ? "ctx->Pack/Unpack, " : "", 1127117f1b4Smrg (state & _NEW_ARRAY) ? "ctx->Array, " : "", 1137117f1b4Smrg (state & _NEW_RENDERMODE) ? "ctx->RenderMode, " : "", 1147117f1b4Smrg (state & _NEW_BUFFERS) ? "ctx->Visual, ctx->DrawBuffer,, " : ""); 1157117f1b4Smrg} 1167117f1b4Smrg 1177117f1b4Smrg 1187117f1b4Smrg 1197117f1b4Smrgvoid 1207117f1b4Smrg_mesa_print_tri_caps( const char *name, GLuint flags ) 1217117f1b4Smrg{ 1227117f1b4Smrg _mesa_debug(NULL, 1237117f1b4Smrg "%s: (0x%x) %s%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n", 1247117f1b4Smrg name, 1257117f1b4Smrg flags, 1267117f1b4Smrg (flags & DD_FLATSHADE) ? "flat-shade, " : "", 1277117f1b4Smrg (flags & DD_SEPARATE_SPECULAR) ? "separate-specular, " : "", 1287117f1b4Smrg (flags & DD_TRI_LIGHT_TWOSIDE) ? "tri-light-twoside, " : "", 1297117f1b4Smrg (flags & DD_TRI_TWOSTENCIL) ? "tri-twostencil, " : "", 1307117f1b4Smrg (flags & DD_TRI_UNFILLED) ? "tri-unfilled, " : "", 1317117f1b4Smrg (flags & DD_TRI_STIPPLE) ? "tri-stipple, " : "", 1327117f1b4Smrg (flags & DD_TRI_OFFSET) ? "tri-offset, " : "", 1337117f1b4Smrg (flags & DD_TRI_SMOOTH) ? "tri-smooth, " : "", 1347117f1b4Smrg (flags & DD_LINE_SMOOTH) ? "line-smooth, " : "", 1357117f1b4Smrg (flags & DD_LINE_STIPPLE) ? "line-stipple, " : "", 1367117f1b4Smrg (flags & DD_LINE_WIDTH) ? "line-wide, " : "", 1377117f1b4Smrg (flags & DD_POINT_SMOOTH) ? "point-smooth, " : "", 1387117f1b4Smrg (flags & DD_POINT_SIZE) ? "point-size, " : "", 1397117f1b4Smrg (flags & DD_POINT_ATTEN) ? "point-atten, " : "", 1407117f1b4Smrg (flags & DD_TRI_CULL_FRONT_BACK) ? "cull-all, " : "" 1417117f1b4Smrg ); 1427117f1b4Smrg} 1437117f1b4Smrg 1447117f1b4Smrg 1457117f1b4Smrg/** 1467117f1b4Smrg * Print information about this Mesa version and build options. 1477117f1b4Smrg */ 1487117f1b4Smrgvoid _mesa_print_info( void ) 1497117f1b4Smrg{ 1507117f1b4Smrg _mesa_debug(NULL, "Mesa GL_VERSION = %s\n", 1517117f1b4Smrg (char *) _mesa_GetString(GL_VERSION)); 1527117f1b4Smrg _mesa_debug(NULL, "Mesa GL_RENDERER = %s\n", 1537117f1b4Smrg (char *) _mesa_GetString(GL_RENDERER)); 1547117f1b4Smrg _mesa_debug(NULL, "Mesa GL_VENDOR = %s\n", 1557117f1b4Smrg (char *) _mesa_GetString(GL_VENDOR)); 1567117f1b4Smrg _mesa_debug(NULL, "Mesa GL_EXTENSIONS = %s\n", 1577117f1b4Smrg (char *) _mesa_GetString(GL_EXTENSIONS)); 1587117f1b4Smrg#if defined(THREADS) 1597117f1b4Smrg _mesa_debug(NULL, "Mesa thread-safe: YES\n"); 1607117f1b4Smrg#else 1617117f1b4Smrg _mesa_debug(NULL, "Mesa thread-safe: NO\n"); 1627117f1b4Smrg#endif 1637117f1b4Smrg#if defined(USE_X86_ASM) 1647117f1b4Smrg _mesa_debug(NULL, "Mesa x86-optimized: YES\n"); 1657117f1b4Smrg#else 1667117f1b4Smrg _mesa_debug(NULL, "Mesa x86-optimized: NO\n"); 1677117f1b4Smrg#endif 1687117f1b4Smrg#if defined(USE_SPARC_ASM) 1697117f1b4Smrg _mesa_debug(NULL, "Mesa sparc-optimized: YES\n"); 1707117f1b4Smrg#else 1717117f1b4Smrg _mesa_debug(NULL, "Mesa sparc-optimized: NO\n"); 1727117f1b4Smrg#endif 1737117f1b4Smrg} 1747117f1b4Smrg 1757117f1b4Smrg 1767117f1b4Smrg/** 1777117f1b4Smrg * Set the debugging flags. 1787117f1b4Smrg * 1797117f1b4Smrg * \param debug debug string 1807117f1b4Smrg * 1817117f1b4Smrg * If compiled with debugging support then search for keywords in \p debug and 1827117f1b4Smrg * enables the verbose debug output of the respective feature. 1837117f1b4Smrg */ 1847117f1b4Smrgstatic void add_debug_flags( const char *debug ) 1857117f1b4Smrg{ 1867117f1b4Smrg#ifdef DEBUG 187c1f859d4Smrg struct debug_option { 188c1f859d4Smrg const char *name; 189c1f859d4Smrg GLbitfield flag; 190c1f859d4Smrg }; 191c1f859d4Smrg static const struct debug_option debug_opt[] = { 192c1f859d4Smrg { "varray", VERBOSE_VARRAY }, 193c1f859d4Smrg { "tex", VERBOSE_TEXTURE }, 1944a49301eSmrg { "mat", VERBOSE_MATERIAL }, 195c1f859d4Smrg { "pipe", VERBOSE_PIPELINE }, 196c1f859d4Smrg { "driver", VERBOSE_DRIVER }, 197c1f859d4Smrg { "state", VERBOSE_STATE }, 198c1f859d4Smrg { "api", VERBOSE_API }, 199c1f859d4Smrg { "list", VERBOSE_DISPLAY_LIST }, 200c1f859d4Smrg { "lighting", VERBOSE_LIGHTING }, 201c1f859d4Smrg { "disassem", VERBOSE_DISASSEM }, 2024a49301eSmrg { "draw", VERBOSE_DRAW }, 2034a49301eSmrg { "swap", VERBOSE_SWAPBUFFERS } 204c1f859d4Smrg }; 205c1f859d4Smrg GLuint i; 206c1f859d4Smrg 207c1f859d4Smrg MESA_VERBOSE = 0x0; 208c1f859d4Smrg for (i = 0; i < Elements(debug_opt); i++) { 209cdc920a0Smrg if (strstr(debug, debug_opt[i].name)) 210c1f859d4Smrg MESA_VERBOSE |= debug_opt[i].flag; 211c1f859d4Smrg } 2127117f1b4Smrg 2137117f1b4Smrg /* Debug flag: 2147117f1b4Smrg */ 215cdc920a0Smrg if (strstr(debug, "flush")) 2167117f1b4Smrg MESA_DEBUG_FLAGS |= DEBUG_ALWAYS_FLUSH; 2177117f1b4Smrg 2187117f1b4Smrg#if defined(_FPU_GETCW) && defined(_FPU_SETCW) 219cdc920a0Smrg if (strstr(debug, "fpexceptions")) { 2207117f1b4Smrg /* raise FP exceptions */ 2217117f1b4Smrg fpu_control_t mask; 2227117f1b4Smrg _FPU_GETCW(mask); 2237117f1b4Smrg mask &= ~(_FPU_MASK_IM | _FPU_MASK_DM | _FPU_MASK_ZM 2247117f1b4Smrg | _FPU_MASK_OM | _FPU_MASK_UM); 2257117f1b4Smrg _FPU_SETCW(mask); 2267117f1b4Smrg } 2277117f1b4Smrg#endif 2287117f1b4Smrg 2297117f1b4Smrg#else 2307117f1b4Smrg (void) debug; 2317117f1b4Smrg#endif 2327117f1b4Smrg} 2337117f1b4Smrg 2347117f1b4Smrg 2357117f1b4Smrgvoid 2367117f1b4Smrg_mesa_init_debug( GLcontext *ctx ) 2377117f1b4Smrg{ 2387117f1b4Smrg char *c; 2397117f1b4Smrg 2407117f1b4Smrg /* Dither disable */ 2417117f1b4Smrg ctx->NoDither = _mesa_getenv("MESA_NO_DITHER") ? GL_TRUE : GL_FALSE; 2427117f1b4Smrg if (ctx->NoDither) { 2437117f1b4Smrg if (_mesa_getenv("MESA_DEBUG")) { 2447117f1b4Smrg _mesa_debug(ctx, "MESA_NO_DITHER set - dithering disabled\n"); 2457117f1b4Smrg } 2467117f1b4Smrg ctx->Color.DitherFlag = GL_FALSE; 2477117f1b4Smrg } 2487117f1b4Smrg 2497117f1b4Smrg c = _mesa_getenv("MESA_DEBUG"); 2507117f1b4Smrg if (c) 2517117f1b4Smrg add_debug_flags(c); 2527117f1b4Smrg 2537117f1b4Smrg c = _mesa_getenv("MESA_VERBOSE"); 2547117f1b4Smrg if (c) 2557117f1b4Smrg add_debug_flags(c); 2567117f1b4Smrg} 2577117f1b4Smrg 2584a49301eSmrg 2594a49301eSmrg/* 2604a49301eSmrg * Write ppm file 2614a49301eSmrg */ 2624a49301eSmrgstatic void 2634a49301eSmrgwrite_ppm(const char *filename, const GLubyte *buffer, int width, int height, 2644a49301eSmrg int comps, int rcomp, int gcomp, int bcomp, GLboolean invert) 2654a49301eSmrg{ 2664a49301eSmrg FILE *f = fopen( filename, "w" ); 2674a49301eSmrg if (f) { 2684a49301eSmrg int x, y; 2694a49301eSmrg const GLubyte *ptr = buffer; 2704a49301eSmrg fprintf(f,"P6\n"); 2714a49301eSmrg fprintf(f,"# ppm-file created by osdemo.c\n"); 2724a49301eSmrg fprintf(f,"%i %i\n", width,height); 2734a49301eSmrg fprintf(f,"255\n"); 2744a49301eSmrg fclose(f); 2754a49301eSmrg f = fopen( filename, "ab" ); /* reopen in binary append mode */ 2764a49301eSmrg for (y=0; y < height; y++) { 2774a49301eSmrg for (x = 0; x < width; x++) { 2784a49301eSmrg int yy = invert ? (height - 1 - y) : y; 2794a49301eSmrg int i = (yy * width + x) * comps; 2804a49301eSmrg fputc(ptr[i+rcomp], f); /* write red */ 2814a49301eSmrg fputc(ptr[i+gcomp], f); /* write green */ 2824a49301eSmrg fputc(ptr[i+bcomp], f); /* write blue */ 2834a49301eSmrg } 2844a49301eSmrg } 2854a49301eSmrg fclose(f); 2864a49301eSmrg } 2874a49301eSmrg} 2884a49301eSmrg 2894a49301eSmrg 2904a49301eSmrg/** 2914a49301eSmrg * Write a texture image to a ppm file. 2924a49301eSmrg * \param face cube face in [0,5] 2934a49301eSmrg * \param level mipmap level 2944a49301eSmrg */ 2954a49301eSmrgstatic void 2964a49301eSmrgwrite_texture_image(struct gl_texture_object *texObj, 2974a49301eSmrg GLuint face, GLuint level) 2984a49301eSmrg{ 2994a49301eSmrg struct gl_texture_image *img = texObj->Image[face][level]; 3004a49301eSmrg if (img) { 3014a49301eSmrg GET_CURRENT_CONTEXT(ctx); 3024a49301eSmrg struct gl_pixelstore_attrib store; 3034a49301eSmrg GLubyte *buffer; 3044a49301eSmrg char s[100]; 3054a49301eSmrg 306cdc920a0Smrg buffer = (GLubyte *) malloc(img->Width * img->Height 3074a49301eSmrg * img->Depth * 4); 3084a49301eSmrg 3094a49301eSmrg store = ctx->Pack; /* save */ 3104a49301eSmrg ctx->Pack = ctx->DefaultPacking; 3114a49301eSmrg 3124a49301eSmrg ctx->Driver.GetTexImage(ctx, texObj->Target, level, 3134a49301eSmrg GL_RGBA, GL_UNSIGNED_BYTE, 3144a49301eSmrg buffer, texObj, img); 3154a49301eSmrg 3164a49301eSmrg /* make filename */ 317cdc920a0Smrg sprintf(s, "/tmp/tex%u.l%u.f%u.ppm", texObj->Name, level, face); 3184a49301eSmrg 319cdc920a0Smrg printf(" Writing image level %u to %s\n", level, s); 3204a49301eSmrg write_ppm(s, buffer, img->Width, img->Height, 4, 0, 1, 2, GL_FALSE); 3214a49301eSmrg 3224a49301eSmrg ctx->Pack = store; /* restore */ 3234a49301eSmrg 324cdc920a0Smrg free(buffer); 3254a49301eSmrg } 3264a49301eSmrg} 3274a49301eSmrg 3284a49301eSmrg 3294a49301eSmrg/** 3304a49301eSmrg * Write renderbuffer image to a ppm file. 3314a49301eSmrg */ 3324a49301eSmrgstatic void 3334a49301eSmrgwrite_renderbuffer_image(const struct gl_renderbuffer *rb) 3344a49301eSmrg{ 3354a49301eSmrg GET_CURRENT_CONTEXT(ctx); 3364a49301eSmrg GLubyte *buffer; 3374a49301eSmrg char s[100]; 3384a49301eSmrg GLenum format, type; 3394a49301eSmrg 3404a49301eSmrg if (rb->_BaseFormat == GL_RGB || 3414a49301eSmrg rb->_BaseFormat == GL_RGBA) { 3424a49301eSmrg format = GL_RGBA; 3434a49301eSmrg type = GL_UNSIGNED_BYTE; 3444a49301eSmrg } 3454a49301eSmrg else if (rb->_BaseFormat == GL_DEPTH_STENCIL) { 3464a49301eSmrg format = GL_DEPTH_STENCIL; 3474a49301eSmrg type = GL_UNSIGNED_INT_24_8; 3484a49301eSmrg } 3494a49301eSmrg else { 3504a49301eSmrg return; 3514a49301eSmrg } 3524a49301eSmrg 353cdc920a0Smrg buffer = (GLubyte *) malloc(rb->Width * rb->Height * 4); 3544a49301eSmrg 3554a49301eSmrg ctx->Driver.ReadPixels(ctx, 0, 0, rb->Width, rb->Height, 3564a49301eSmrg format, type, &ctx->DefaultPacking, buffer); 3574a49301eSmrg 3584a49301eSmrg /* make filename */ 359cdc920a0Smrg sprintf(s, "/tmp/renderbuffer%u.ppm", rb->Name); 3604a49301eSmrg 361cdc920a0Smrg printf(" Writing renderbuffer image to %s\n", s); 3624a49301eSmrg write_ppm(s, buffer, rb->Width, rb->Height, 4, 0, 1, 2, GL_TRUE); 3634a49301eSmrg 364cdc920a0Smrg free(buffer); 3654a49301eSmrg} 3664a49301eSmrg 3674a49301eSmrg 3684a49301eSmrg/** How many texture images (mipmap levels, faces) to write to files */ 3694a49301eSmrg#define WRITE_NONE 0 3704a49301eSmrg#define WRITE_ONE 1 3714a49301eSmrg#define WRITE_ALL 2 3724a49301eSmrg 3734a49301eSmrgstatic GLuint WriteImages; 3744a49301eSmrg 3754a49301eSmrg 3764a49301eSmrgstatic void 3774a49301eSmrgdump_texture(struct gl_texture_object *texObj, GLuint writeImages) 3784a49301eSmrg{ 3794a49301eSmrg const GLuint numFaces = texObj->Target == GL_TEXTURE_CUBE_MAP ? 6 : 1; 3804a49301eSmrg GLboolean written = GL_FALSE; 3814a49301eSmrg GLuint i, j; 3824a49301eSmrg 383cdc920a0Smrg printf("Texture %u\n", texObj->Name); 384cdc920a0Smrg printf(" Target %s\n", tex_target_name(texObj->Target)); 3854a49301eSmrg for (i = 0; i < MAX_TEXTURE_LEVELS; i++) { 3864a49301eSmrg for (j = 0; j < numFaces; j++) { 3874a49301eSmrg struct gl_texture_image *texImg = texObj->Image[j][i]; 3884a49301eSmrg if (texImg) { 389cdc920a0Smrg printf(" Face %u level %u: %d x %d x %d, format %s at %p\n", 390cdc920a0Smrg j, i, 391cdc920a0Smrg texImg->Width, texImg->Height, texImg->Depth, 392cdc920a0Smrg _mesa_get_format_name(texImg->TexFormat), 393cdc920a0Smrg texImg->Data); 3944a49301eSmrg if (writeImages == WRITE_ALL || 3954a49301eSmrg (writeImages == WRITE_ONE && !written)) { 3964a49301eSmrg write_texture_image(texObj, j, i); 3974a49301eSmrg written = GL_TRUE; 3984a49301eSmrg } 3994a49301eSmrg } 4004a49301eSmrg } 4014a49301eSmrg } 4024a49301eSmrg} 4034a49301eSmrg 4044a49301eSmrg 4054a49301eSmrg/** 4064a49301eSmrg * Dump a single texture. 4074a49301eSmrg */ 4084a49301eSmrgvoid 4094a49301eSmrg_mesa_dump_texture(GLuint texture, GLuint writeImages) 4104a49301eSmrg{ 4114a49301eSmrg GET_CURRENT_CONTEXT(ctx); 4124a49301eSmrg struct gl_texture_object *texObj = _mesa_lookup_texture(ctx, texture); 4134a49301eSmrg if (texObj) { 4144a49301eSmrg dump_texture(texObj, writeImages); 4154a49301eSmrg } 4164a49301eSmrg} 4174a49301eSmrg 4184a49301eSmrg 4194a49301eSmrgstatic void 4204a49301eSmrgdump_texture_cb(GLuint id, void *data, void *userData) 4214a49301eSmrg{ 4224a49301eSmrg struct gl_texture_object *texObj = (struct gl_texture_object *) data; 4234a49301eSmrg (void) userData; 4244a49301eSmrg dump_texture(texObj, WriteImages); 4254a49301eSmrg} 4264a49301eSmrg 4274a49301eSmrg 4284a49301eSmrg/** 4294a49301eSmrg * Print basic info about all texture objext to stdout. 4304a49301eSmrg * If dumpImages is true, write PPM of level[0] image to a file. 4314a49301eSmrg */ 4324a49301eSmrgvoid 4334a49301eSmrg_mesa_dump_textures(GLuint writeImages) 4344a49301eSmrg{ 4354a49301eSmrg GET_CURRENT_CONTEXT(ctx); 4364a49301eSmrg WriteImages = writeImages; 4374a49301eSmrg _mesa_HashWalk(ctx->Shared->TexObjects, dump_texture_cb, ctx); 4384a49301eSmrg} 4394a49301eSmrg 4404a49301eSmrg 4414a49301eSmrgstatic void 4424a49301eSmrgdump_renderbuffer(const struct gl_renderbuffer *rb, GLboolean writeImage) 4434a49301eSmrg{ 444cdc920a0Smrg printf("Renderbuffer %u: %u x %u IntFormat = %s\n", 445cdc920a0Smrg rb->Name, rb->Width, rb->Height, 446cdc920a0Smrg _mesa_lookup_enum_by_nr(rb->InternalFormat)); 4474a49301eSmrg if (writeImage) { 4484a49301eSmrg write_renderbuffer_image(rb); 4494a49301eSmrg } 4504a49301eSmrg} 4514a49301eSmrg 4524a49301eSmrg 4534a49301eSmrgstatic void 4544a49301eSmrgdump_renderbuffer_cb(GLuint id, void *data, void *userData) 4554a49301eSmrg{ 4564a49301eSmrg const struct gl_renderbuffer *rb = (const struct gl_renderbuffer *) data; 4574a49301eSmrg (void) userData; 4584a49301eSmrg dump_renderbuffer(rb, WriteImages); 4594a49301eSmrg} 4604a49301eSmrg 4614a49301eSmrg 4624a49301eSmrg/** 4634a49301eSmrg * Print basic info about all renderbuffers to stdout. 4644a49301eSmrg * If dumpImages is true, write PPM of level[0] image to a file. 4654a49301eSmrg */ 4664a49301eSmrgvoid 4674a49301eSmrg_mesa_dump_renderbuffers(GLboolean writeImages) 4684a49301eSmrg{ 4694a49301eSmrg GET_CURRENT_CONTEXT(ctx); 4704a49301eSmrg WriteImages = writeImages; 4714a49301eSmrg _mesa_HashWalk(ctx->Shared->RenderBuffers, dump_renderbuffer_cb, ctx); 4724a49301eSmrg} 4734a49301eSmrg 4744a49301eSmrg 4754a49301eSmrg 4764a49301eSmrgvoid 4774a49301eSmrg_mesa_dump_color_buffer(const char *filename) 4784a49301eSmrg{ 4794a49301eSmrg GET_CURRENT_CONTEXT(ctx); 4804a49301eSmrg const GLuint w = ctx->DrawBuffer->Width; 4814a49301eSmrg const GLuint h = ctx->DrawBuffer->Height; 4824a49301eSmrg GLubyte *buf; 4834a49301eSmrg 484cdc920a0Smrg buf = (GLubyte *) malloc(w * h * 4); 4854a49301eSmrg 4864a49301eSmrg _mesa_PushClientAttrib(GL_CLIENT_PIXEL_STORE_BIT); 4874a49301eSmrg _mesa_PixelStorei(GL_PACK_ALIGNMENT, 1); 4884a49301eSmrg _mesa_PixelStorei(GL_PACK_INVERT_MESA, GL_TRUE); 4894a49301eSmrg 4904a49301eSmrg _mesa_ReadPixels(0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, buf); 4914a49301eSmrg 492cdc920a0Smrg printf("ReadBuffer %p 0x%x DrawBuffer %p 0x%x\n", 493cdc920a0Smrg (void *) ctx->ReadBuffer->_ColorReadBuffer, 494cdc920a0Smrg ctx->ReadBuffer->ColorReadBuffer, 495cdc920a0Smrg (void *) ctx->DrawBuffer->_ColorDrawBuffers[0], 496cdc920a0Smrg ctx->DrawBuffer->ColorDrawBuffer[0]); 497cdc920a0Smrg printf("Writing %d x %d color buffer to %s\n", w, h, filename); 4984a49301eSmrg write_ppm(filename, buf, w, h, 4, 0, 1, 2, GL_TRUE); 4994a49301eSmrg 5004a49301eSmrg _mesa_PopClientAttrib(); 5014a49301eSmrg 502cdc920a0Smrg free(buf); 5034a49301eSmrg} 5044a49301eSmrg 5054a49301eSmrg 5064a49301eSmrgvoid 5074a49301eSmrg_mesa_dump_depth_buffer(const char *filename) 5084a49301eSmrg{ 5094a49301eSmrg GET_CURRENT_CONTEXT(ctx); 5104a49301eSmrg const GLuint w = ctx->DrawBuffer->Width; 5114a49301eSmrg const GLuint h = ctx->DrawBuffer->Height; 5124a49301eSmrg GLuint *buf; 5134a49301eSmrg GLubyte *buf2; 5144a49301eSmrg GLuint i; 5154a49301eSmrg 516cdc920a0Smrg buf = (GLuint *) malloc(w * h * 4); /* 4 bpp */ 517cdc920a0Smrg buf2 = (GLubyte *) malloc(w * h * 3); /* 3 bpp */ 5184a49301eSmrg 5194a49301eSmrg _mesa_PushClientAttrib(GL_CLIENT_PIXEL_STORE_BIT); 5204a49301eSmrg _mesa_PixelStorei(GL_PACK_ALIGNMENT, 1); 5214a49301eSmrg _mesa_PixelStorei(GL_PACK_INVERT_MESA, GL_TRUE); 5224a49301eSmrg 5234a49301eSmrg _mesa_ReadPixels(0, 0, w, h, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, buf); 5244a49301eSmrg 5254a49301eSmrg /* spread 24 bits of Z across R, G, B */ 5264a49301eSmrg for (i = 0; i < w * h; i++) { 5274a49301eSmrg buf2[i*3+0] = (buf[i] >> 24) & 0xff; 5284a49301eSmrg buf2[i*3+1] = (buf[i] >> 16) & 0xff; 5294a49301eSmrg buf2[i*3+2] = (buf[i] >> 8) & 0xff; 5304a49301eSmrg } 5314a49301eSmrg 532cdc920a0Smrg printf("Writing %d x %d depth buffer to %s\n", w, h, filename); 5334a49301eSmrg write_ppm(filename, buf2, w, h, 3, 0, 1, 2, GL_TRUE); 5344a49301eSmrg 5354a49301eSmrg _mesa_PopClientAttrib(); 5364a49301eSmrg 537cdc920a0Smrg free(buf); 538cdc920a0Smrg free(buf2); 5394a49301eSmrg} 5404a49301eSmrg 5414a49301eSmrg 5424a49301eSmrgvoid 5434a49301eSmrg_mesa_dump_stencil_buffer(const char *filename) 5444a49301eSmrg{ 5454a49301eSmrg GET_CURRENT_CONTEXT(ctx); 5464a49301eSmrg const GLuint w = ctx->DrawBuffer->Width; 5474a49301eSmrg const GLuint h = ctx->DrawBuffer->Height; 5484a49301eSmrg GLubyte *buf; 5494a49301eSmrg GLubyte *buf2; 5504a49301eSmrg GLuint i; 5514a49301eSmrg 552cdc920a0Smrg buf = (GLubyte *) malloc(w * h); /* 1 bpp */ 553cdc920a0Smrg buf2 = (GLubyte *) malloc(w * h * 3); /* 3 bpp */ 5544a49301eSmrg 5554a49301eSmrg _mesa_PushClientAttrib(GL_CLIENT_PIXEL_STORE_BIT); 5564a49301eSmrg _mesa_PixelStorei(GL_PACK_ALIGNMENT, 1); 5574a49301eSmrg _mesa_PixelStorei(GL_PACK_INVERT_MESA, GL_TRUE); 5584a49301eSmrg 5594a49301eSmrg _mesa_ReadPixels(0, 0, w, h, GL_STENCIL_INDEX, GL_UNSIGNED_BYTE, buf); 5604a49301eSmrg 5614a49301eSmrg for (i = 0; i < w * h; i++) { 5624a49301eSmrg buf2[i*3+0] = buf[i]; 5634a49301eSmrg buf2[i*3+1] = (buf[i] & 127) * 2; 5644a49301eSmrg buf2[i*3+2] = (buf[i] - 128) * 2; 5654a49301eSmrg } 5664a49301eSmrg 567cdc920a0Smrg printf("Writing %d x %d stencil buffer to %s\n", w, h, filename); 5684a49301eSmrg write_ppm(filename, buf2, w, h, 3, 0, 1, 2, GL_TRUE); 5694a49301eSmrg 5704a49301eSmrg _mesa_PopClientAttrib(); 5714a49301eSmrg 572cdc920a0Smrg free(buf); 573cdc920a0Smrg free(buf2); 5744a49301eSmrg} 5754a49301eSmrg 5764a49301eSmrg 5774a49301eSmrg/** 5784a49301eSmrg * Quick and dirty function to "print" a texture to stdout. 5794a49301eSmrg */ 5804a49301eSmrgvoid 5814a49301eSmrg_mesa_print_texture(GLcontext *ctx, const struct gl_texture_image *img) 5824a49301eSmrg{ 5834a49301eSmrg#if CHAN_TYPE != GL_UNSIGNED_BYTE 5844a49301eSmrg _mesa_problem(NULL, "PrintTexture not supported"); 5854a49301eSmrg#else 5864a49301eSmrg GLuint i, j, c; 5874a49301eSmrg const GLubyte *data = (const GLubyte *) img->Data; 5884a49301eSmrg 5894a49301eSmrg if (!data) { 590cdc920a0Smrg printf("No texture data\n"); 5914a49301eSmrg return; 5924a49301eSmrg } 5934a49301eSmrg 5944a49301eSmrg /* XXX add more formats or make into a new format utility function */ 5954a49301eSmrg switch (img->TexFormat) { 5964a49301eSmrg case MESA_FORMAT_A8: 5974a49301eSmrg case MESA_FORMAT_L8: 5984a49301eSmrg case MESA_FORMAT_I8: 5994a49301eSmrg case MESA_FORMAT_CI8: 6004a49301eSmrg c = 1; 6014a49301eSmrg break; 6024a49301eSmrg case MESA_FORMAT_AL88: 6034a49301eSmrg case MESA_FORMAT_AL88_REV: 6044a49301eSmrg c = 2; 6054a49301eSmrg break; 6064a49301eSmrg case MESA_FORMAT_RGB888: 6074a49301eSmrg case MESA_FORMAT_BGR888: 6084a49301eSmrg c = 3; 6094a49301eSmrg break; 6104a49301eSmrg case MESA_FORMAT_RGBA8888: 6114a49301eSmrg case MESA_FORMAT_ARGB8888: 6124a49301eSmrg c = 4; 6134a49301eSmrg break; 6144a49301eSmrg default: 6154a49301eSmrg _mesa_problem(NULL, "error in PrintTexture\n"); 6164a49301eSmrg return; 6174a49301eSmrg } 6184a49301eSmrg 6194a49301eSmrg for (i = 0; i < img->Height; i++) { 6204a49301eSmrg for (j = 0; j < img->Width; j++) { 6214a49301eSmrg if (c==1) 622cdc920a0Smrg printf("%02x ", data[0]); 6234a49301eSmrg else if (c==2) 624cdc920a0Smrg printf("%02x%02x ", data[0], data[1]); 6254a49301eSmrg else if (c==3) 626cdc920a0Smrg printf("%02x%02x%02x ", data[0], data[1], data[2]); 6274a49301eSmrg else if (c==4) 628cdc920a0Smrg printf("%02x%02x%02x%02x ", data[0], data[1], data[2], data[3]); 6294a49301eSmrg data += (img->RowStride - img->Width) * c; 6304a49301eSmrg } 6314a49301eSmrg /* XXX use img->ImageStride here */ 632cdc920a0Smrg printf("\n"); 6334a49301eSmrg } 6344a49301eSmrg#endif 6354a49301eSmrg} 636