mesa: Remove unnecessary header.
[mesa.git] / src / mesa / main / debug.c
index 1c8c44fcb96630d2397bf8b0dd0d795ad57d215b..9bcfc1008a8852f402733053645ceecfdd279c35 100644 (file)
@@ -26,7 +26,8 @@
 #include "mtypes.h"
 #include "attrib.h"
 #include "colormac.h"
-#include "context.h"
+#include "enums.h"
+#include "formats.h"
 #include "hash.h"
 #include "imports.h"
 #include "debug.h"
@@ -34,7 +35,6 @@
 #include "pixelstore.h"
 #include "readpix.h"
 #include "texobj.h"
-#include "texformat.h"
 
 
 /**
@@ -52,15 +52,40 @@ const char *_mesa_prim_name[GL_POLYGON+4] = {
    "GL_QUAD_STRIP",
    "GL_POLYGON",
    "outside begin/end",
-   "inside unkown primitive",
+   "inside unknown primitive",
    "unknown state"
 };
 
+
+static const char *
+tex_target_name(GLenum tgt)
+{
+   static const struct {
+      GLenum target;
+      const char *name;
+   } tex_targets[] = {
+      { GL_TEXTURE_1D, "GL_TEXTURE_1D" },
+      { GL_TEXTURE_2D, "GL_TEXTURE_2D" },
+      { GL_TEXTURE_3D, "GL_TEXTURE_3D" },
+      { GL_TEXTURE_CUBE_MAP, "GL_TEXTURE_CUBE_MAP" },
+      { GL_TEXTURE_RECTANGLE, "GL_TEXTURE_RECTANGLE" },
+      { GL_TEXTURE_1D_ARRAY_EXT, "GL_TEXTURE_1D_ARRAY" },
+      { GL_TEXTURE_2D_ARRAY_EXT, "GL_TEXTURE_2D_ARRAY" }
+   };
+   GLuint i;
+   for (i = 0; i < Elements(tex_targets); i++) {
+      if (tex_targets[i].target == tgt)
+         return tex_targets[i].name;
+   }
+   return "UNKNOWN TEX TARGET";
+}
+
+
 void
 _mesa_print_state( const char *msg, GLuint state )
 {
    _mesa_debug(NULL,
-          "%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",
+          "%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%s\n",
           msg,
           state,
           (state & _NEW_MODELVIEW)       ? "ctx->ModelView, " : "",
@@ -80,6 +105,7 @@ _mesa_print_state( const char *msg, GLuint state )
           (state & _NEW_POLYGON)         ? "ctx->Polygon, " : "",
           (state & _NEW_POLYGONSTIPPLE)  ? "ctx->PolygonStipple, " : "",
           (state & _NEW_SCISSOR)         ? "ctx->Scissor, " : "",
+          (state & _NEW_STENCIL)         ? "ctx->Stencil, " : "",
           (state & _NEW_TEXTURE)         ? "ctx->Texture, " : "",
           (state & _NEW_TRANSFORM)       ? "ctx->Transform, " : "",
           (state & _NEW_VIEWPORT)        ? "ctx->Viewport, " : "",
@@ -166,30 +192,32 @@ static void add_debug_flags( const char *debug )
    static const struct debug_option debug_opt[] = {
       { "varray",    VERBOSE_VARRAY },
       { "tex",       VERBOSE_TEXTURE },
-      { "imm",       VERBOSE_IMMEDIATE },
+      { "mat",       VERBOSE_MATERIAL },
       { "pipe",      VERBOSE_PIPELINE },
       { "driver",    VERBOSE_DRIVER },
       { "state",     VERBOSE_STATE },
       { "api",       VERBOSE_API },
       { "list",      VERBOSE_DISPLAY_LIST },
       { "lighting",  VERBOSE_LIGHTING },
-      { "disassem",  VERBOSE_DISASSEM }
+      { "disassem",  VERBOSE_DISASSEM },
+      { "draw",      VERBOSE_DRAW },
+      { "swap",      VERBOSE_SWAPBUFFERS }
    };
    GLuint i;
 
    MESA_VERBOSE = 0x0;
    for (i = 0; i < Elements(debug_opt); i++) {
-      if (_mesa_strstr(debug, debug_opt[i].name))
+      if (strstr(debug, debug_opt[i].name))
          MESA_VERBOSE |= debug_opt[i].flag;
    }
 
    /* Debug flag:
     */
-   if (_mesa_strstr(debug, "flush")) 
+   if (strstr(debug, "flush"))
       MESA_DEBUG_FLAGS |= DEBUG_ALWAYS_FLUSH;
 
 #if defined(_FPU_GETCW) && defined(_FPU_SETCW)
-   if (_mesa_strstr(debug, "fpexceptions")) {
+   if (strstr(debug, "fpexceptions")) {
       /* raise FP exceptions */
       fpu_control_t mask;
       _FPU_GETCW(mask);
@@ -234,11 +262,11 @@ _mesa_init_debug( GLcontext *ctx )
  */
 static void
 write_ppm(const char *filename, const GLubyte *buffer, int width, int height,
-          int comps, int rcomp, int gcomp, int bcomp)
+          int comps, int rcomp, int gcomp, int bcomp, GLboolean invert)
 {
    FILE *f = fopen( filename, "w" );
    if (f) {
-      int i, x, y;
+      int x, y;
       const GLubyte *ptr = buffer;
       fprintf(f,"P6\n");
       fprintf(f,"# ppm-file created by osdemo.c\n");
@@ -246,10 +274,11 @@ write_ppm(const char *filename, const GLubyte *buffer, int width, int height,
       fprintf(f,"255\n");
       fclose(f);
       f = fopen( filename, "ab" );  /* reopen in binary append mode */
-      for (y=height-1; y>=0; y--) {
-         for (x=0; x<width; x++) {
-            i = (y*width + x) * comps;
-            fputc(ptr[i+rcomp], f);   /* write red */
+      for (y=0; y < height; y++) {
+         for (x = 0; x < width; x++) {
+            int yy = invert ? (height - 1 - y) : y;
+            int i = (yy * width + x) * comps;
+            fputc(ptr[i+rcomp], f); /* write red */
             fputc(ptr[i+gcomp], f); /* write green */
             fputc(ptr[i+bcomp], f); /* write blue */
          }
@@ -260,92 +289,191 @@ write_ppm(const char *filename, const GLubyte *buffer, int width, int height,
 
 
 /**
- * Write level[0] image to a ppm file.
+ * Write a texture image to a ppm file.
+ * \param face  cube face in [0,5]
+ * \param level  mipmap level
  */
 static void
-write_texture_image(struct gl_texture_object *texObj)
+write_texture_image(struct gl_texture_object *texObj,
+                    GLuint face, GLuint level)
 {
-   const struct gl_texture_image *img = texObj->Image[0][0];
-   if (img && img->Data) {
+   struct gl_texture_image *img = texObj->Image[face][level];
+   if (img) {
+      GET_CURRENT_CONTEXT(ctx);
+      struct gl_pixelstore_attrib store;
+      GLubyte *buffer;
       char s[100];
 
+      buffer = (GLubyte *) malloc(img->Width * img->Height
+                                        * img->Depth * 4);
+
+      store = ctx->Pack; /* save */
+      ctx->Pack = ctx->DefaultPacking;
+
+      ctx->Driver.GetTexImage(ctx, texObj->Target, level,
+                              GL_RGBA, GL_UNSIGNED_BYTE,
+                              buffer, texObj, img);
+
       /* make filename */
-      sprintf(s, "/tmp/teximage%u.ppm", texObj->Name);
+      sprintf(s, "/tmp/tex%u.l%u.f%u.ppm", texObj->Name, level, face);
 
-      switch (img->TexFormat->MesaFormat) {
-      case MESA_FORMAT_RGBA8888:
-         write_ppm(s, img->Data, img->Width, img->Height, 4, 3, 2, 1);
-         break;
-      case MESA_FORMAT_ARGB8888:
-         write_ppm(s, img->Data, img->Width, img->Height, 4, 2, 1, 0);
-         break;
-      case MESA_FORMAT_RGB888:
-         write_ppm(s, img->Data, img->Width, img->Height, 3, 2, 1, 0);
-         break;
-      case MESA_FORMAT_RGB565:
-         {
-            GLubyte *buf2 = (GLubyte *) _mesa_malloc(img->Width * img->Height * 3);
-            GLuint i;
-            for (i = 0; i < img->Width * img->Height; i++) {
-               GLint r, g, b;
-               GLushort s = ((GLushort *) img->Data)[i];
-               r = UBYTE_TO_CHAN( ((s >> 8) & 0xf8) | ((s >> 13) & 0x7) );
-               g = UBYTE_TO_CHAN( ((s >> 3) & 0xfc) | ((s >>  9) & 0x3) );
-               b = UBYTE_TO_CHAN( ((s << 3) & 0xf8) | ((s >>  2) & 0x7) );
-               buf2[i*3+1] = r;
-               buf2[i*3+2] = g;
-               buf2[i*3+3] = b;
-            }
-            write_ppm(s, buf2, img->Width, img->Height, 3, 2, 1, 0);
-            _mesa_free(buf2);
-         }
-         break;
-      default:
-         printf("XXXX unsupported mesa tex format %d in %s\n",
-                img->TexFormat->MesaFormat, __FUNCTION__);
-      }
+      printf("  Writing image level %u to %s\n", level, s);
+      write_ppm(s, buffer, img->Width, img->Height, 4, 0, 1, 2, GL_FALSE);
+
+      ctx->Pack = store; /* restore */
+
+      free(buffer);
    }
 }
 
 
-static GLboolean DumpImages;
+/**
+ * Write renderbuffer image to a ppm file.
+ */
+static void
+write_renderbuffer_image(const struct gl_renderbuffer *rb)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   GLubyte *buffer;
+   char s[100];
+   GLenum format, type;
+
+   if (rb->_BaseFormat == GL_RGB || 
+       rb->_BaseFormat == GL_RGBA) {
+      format = GL_RGBA;
+      type = GL_UNSIGNED_BYTE;
+   }
+   else if (rb->_BaseFormat == GL_DEPTH_STENCIL) {
+      format = GL_DEPTH_STENCIL;
+      type = GL_UNSIGNED_INT_24_8;
+   }
+   else {
+      return;
+   }
+
+   buffer = (GLubyte *) malloc(rb->Width * rb->Height * 4);
+
+   ctx->Driver.ReadPixels(ctx, 0, 0, rb->Width, rb->Height,
+                          format, type, &ctx->DefaultPacking, buffer);
+
+   /* make filename */
+   sprintf(s, "/tmp/renderbuffer%u.ppm", rb->Name);
+
+   printf("  Writing renderbuffer image to %s\n", s);
+   write_ppm(s, buffer, rb->Width, rb->Height, 4, 0, 1, 2, GL_TRUE);
+
+   free(buffer);
+}
+
+
+/** How many texture images (mipmap levels, faces) to write to files */
+#define WRITE_NONE 0
+#define WRITE_ONE  1
+#define WRITE_ALL  2
+
+static GLuint WriteImages;
 
 
 static void
-dump_texture_cb(GLuint id, void *data, void *userData)
+dump_texture(struct gl_texture_object *texObj, GLuint writeImages)
 {
-   struct gl_texture_object *texObj = (struct gl_texture_object *) data;
-   int i;
-   (void) userData;
+   const GLuint numFaces = texObj->Target == GL_TEXTURE_CUBE_MAP ? 6 : 1;
+   GLboolean written = GL_FALSE;
+   GLuint i, j;
 
    printf("Texture %u\n", texObj->Name);
-   printf("  Target 0x%x\n", texObj->Target);
+   printf("  Target %s\n", tex_target_name(texObj->Target));
    for (i = 0; i < MAX_TEXTURE_LEVELS; i++) {
-      struct gl_texture_image *texImg = texObj->Image[0][i];
-      if (texImg) {
-         printf("  Image %u: %d x %d x %d at %p\n", i,
-                texImg->Width, texImg->Height, texImg->Depth, texImg->Data);
-         if (DumpImages && i == 0) {
-            write_texture_image(texObj);
+      for (j = 0; j < numFaces; j++) {
+         struct gl_texture_image *texImg = texObj->Image[j][i];
+         if (texImg) {
+            printf("  Face %u level %u: %d x %d x %d, format %s at %p\n",
+                  j, i,
+                  texImg->Width, texImg->Height, texImg->Depth,
+                  _mesa_get_format_name(texImg->TexFormat),
+                  texImg->Data);
+            if (writeImages == WRITE_ALL ||
+                (writeImages == WRITE_ONE && !written)) {
+               write_texture_image(texObj, j, i);
+               written = GL_TRUE;
+            }
          }
       }
    }
 }
 
 
+/**
+ * Dump a single texture.
+ */
+void
+_mesa_dump_texture(GLuint texture, GLuint writeImages)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   struct gl_texture_object *texObj = _mesa_lookup_texture(ctx, texture);
+   if (texObj) {
+      dump_texture(texObj, writeImages);
+   }
+}
+
+
+static void
+dump_texture_cb(GLuint id, void *data, void *userData)
+{
+   struct gl_texture_object *texObj = (struct gl_texture_object *) data;
+   (void) userData;
+   dump_texture(texObj, WriteImages);
+}
+
+
 /**
  * Print basic info about all texture objext to stdout.
  * If dumpImages is true, write PPM of level[0] image to a file.
  */
 void
-_mesa_dump_textures(GLboolean dumpImages)
+_mesa_dump_textures(GLuint writeImages)
 {
    GET_CURRENT_CONTEXT(ctx);
-   DumpImages = dumpImages;
+   WriteImages = writeImages;
    _mesa_HashWalk(ctx->Shared->TexObjects, dump_texture_cb, ctx);
 }
 
 
+static void
+dump_renderbuffer(const struct gl_renderbuffer *rb, GLboolean writeImage)
+{
+   printf("Renderbuffer %u: %u x %u  IntFormat = %s\n",
+         rb->Name, rb->Width, rb->Height,
+         _mesa_lookup_enum_by_nr(rb->InternalFormat));
+   if (writeImage) {
+      write_renderbuffer_image(rb);
+   }
+}
+
+
+static void
+dump_renderbuffer_cb(GLuint id, void *data, void *userData)
+{
+   const struct gl_renderbuffer *rb = (const struct gl_renderbuffer *) data;
+   (void) userData;
+   dump_renderbuffer(rb, WriteImages);
+}
+
+
+/**
+ * Print basic info about all renderbuffers to stdout.
+ * If dumpImages is true, write PPM of level[0] image to a file.
+ */
+void
+_mesa_dump_renderbuffers(GLboolean writeImages)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   WriteImages = writeImages;
+   _mesa_HashWalk(ctx->Shared->RenderBuffers, dump_renderbuffer_cb, ctx);
+}
+
+
+
 void
 _mesa_dump_color_buffer(const char *filename)
 {
@@ -354,7 +482,7 @@ _mesa_dump_color_buffer(const char *filename)
    const GLuint h = ctx->DrawBuffer->Height;
    GLubyte *buf;
 
-   buf = (GLubyte *) _mesa_malloc(w * h * 4);
+   buf = (GLubyte *) malloc(w * h * 4);
 
    _mesa_PushClientAttrib(GL_CLIENT_PIXEL_STORE_BIT);
    _mesa_PixelStorei(GL_PACK_ALIGNMENT, 1);
@@ -362,17 +490,17 @@ _mesa_dump_color_buffer(const char *filename)
 
    _mesa_ReadPixels(0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, buf);
 
-   _mesa_printf("ReadBuffer %p 0x%x  DrawBuffer %p 0x%x\n",
-                ctx->ReadBuffer->_ColorReadBuffer,
-                ctx->ReadBuffer->ColorReadBuffer,
-                ctx->DrawBuffer->_ColorDrawBuffers[0],
-                ctx->DrawBuffer->ColorDrawBuffer[0]);
-   _mesa_printf("Writing %d x %d color buffer to %s\n", w, h, filename);
-   write_ppm(filename, buf, w, h, 4, 0, 1, 2);
+   printf("ReadBuffer %p 0x%x  DrawBuffer %p 0x%x\n",
+         (void *) ctx->ReadBuffer->_ColorReadBuffer,
+         ctx->ReadBuffer->ColorReadBuffer,
+         (void *) ctx->DrawBuffer->_ColorDrawBuffers[0],
+         ctx->DrawBuffer->ColorDrawBuffer[0]);
+   printf("Writing %d x %d color buffer to %s\n", w, h, filename);
+   write_ppm(filename, buf, w, h, 4, 0, 1, 2, GL_TRUE);
 
    _mesa_PopClientAttrib();
 
-   _mesa_free(buf);
+   free(buf);
 }
 
 
@@ -386,8 +514,8 @@ _mesa_dump_depth_buffer(const char *filename)
    GLubyte *buf2;
    GLuint i;
 
-   buf = (GLuint *) _mesa_malloc(w * h * 4);  /* 4 bpp */
-   buf2 = (GLubyte *) _mesa_malloc(w * h * 3); /* 3 bpp */
+   buf = (GLuint *) malloc(w * h * 4);  /* 4 bpp */
+   buf2 = (GLubyte *) malloc(w * h * 3); /* 3 bpp */
 
    _mesa_PushClientAttrib(GL_CLIENT_PIXEL_STORE_BIT);
    _mesa_PixelStorei(GL_PACK_ALIGNMENT, 1);
@@ -402,13 +530,13 @@ _mesa_dump_depth_buffer(const char *filename)
       buf2[i*3+2] = (buf[i] >>  8) & 0xff;
    }
 
-   _mesa_printf("Writing %d x %d depth buffer to %s\n", w, h, filename);
-   write_ppm(filename, buf2, w, h, 3, 0, 1, 2);
+   printf("Writing %d x %d depth buffer to %s\n", w, h, filename);
+   write_ppm(filename, buf2, w, h, 3, 0, 1, 2, GL_TRUE);
 
    _mesa_PopClientAttrib();
 
-   _mesa_free(buf);
-   _mesa_free(buf2);
+   free(buf);
+   free(buf2);
 }
 
 
@@ -422,8 +550,8 @@ _mesa_dump_stencil_buffer(const char *filename)
    GLubyte *buf2;
    GLuint i;
 
-   buf = (GLubyte *) _mesa_malloc(w * h);  /* 1 bpp */
-   buf2 = (GLubyte *) _mesa_malloc(w * h * 3); /* 3 bpp */
+   buf = (GLubyte *) malloc(w * h);  /* 1 bpp */
+   buf2 = (GLubyte *) malloc(w * h * 3); /* 3 bpp */
 
    _mesa_PushClientAttrib(GL_CLIENT_PIXEL_STORE_BIT);
    _mesa_PixelStorei(GL_PACK_ALIGNMENT, 1);
@@ -437,11 +565,72 @@ _mesa_dump_stencil_buffer(const char *filename)
       buf2[i*3+2] = (buf[i] - 128) * 2;
    }
 
-   _mesa_printf("Writing %d x %d stencil buffer to %s\n", w, h, filename);
-   write_ppm(filename, buf2, w, h, 3, 0, 1, 2);
+   printf("Writing %d x %d stencil buffer to %s\n", w, h, filename);
+   write_ppm(filename, buf2, w, h, 3, 0, 1, 2, GL_TRUE);
 
    _mesa_PopClientAttrib();
 
-   _mesa_free(buf);
-   _mesa_free(buf2);
+   free(buf);
+   free(buf2);
+}
+
+
+/**
+ * Quick and dirty function to "print" a texture to stdout.
+ */
+void
+_mesa_print_texture(GLcontext *ctx, const struct gl_texture_image *img)
+{
+#if CHAN_TYPE != GL_UNSIGNED_BYTE
+   _mesa_problem(NULL, "PrintTexture not supported");
+#else
+   GLuint i, j, c;
+   const GLubyte *data = (const GLubyte *) img->Data;
+
+   if (!data) {
+      printf("No texture data\n");
+      return;
+   }
+
+   /* XXX add more formats or make into a new format utility function */
+   switch (img->TexFormat) {
+      case MESA_FORMAT_A8:
+      case MESA_FORMAT_L8:
+      case MESA_FORMAT_I8:
+      case MESA_FORMAT_CI8:
+         c = 1;
+         break;
+      case MESA_FORMAT_AL88:
+      case MESA_FORMAT_AL88_REV:
+         c = 2;
+         break;
+      case MESA_FORMAT_RGB888:
+      case MESA_FORMAT_BGR888:
+         c = 3;
+         break;
+      case MESA_FORMAT_RGBA8888:
+      case MESA_FORMAT_ARGB8888:
+         c = 4;
+         break;
+      default:
+         _mesa_problem(NULL, "error in PrintTexture\n");
+         return;
+   }
+
+   for (i = 0; i < img->Height; i++) {
+      for (j = 0; j < img->Width; j++) {
+         if (c==1)
+            printf("%02x  ", data[0]);
+         else if (c==2)
+            printf("%02x%02x  ", data[0], data[1]);
+         else if (c==3)
+            printf("%02x%02x%02x  ", data[0], data[1], data[2]);
+         else if (c==4)
+            printf("%02x%02x%02x%02x  ", data[0], data[1], data[2], data[3]);
+         data += (img->RowStride - img->Width) * c;
+      }
+      /* XXX use img->ImageStride here */
+      printf("\n");
+   }
+#endif
 }