gallium: fixes for srgb, new srgb formats
[mesa.git] / src / gallium / auxiliary / util / p_debug.c
index d56449e7ec6f4f9a9ef2787f61fff6cd2c60e4fd..acdfa211c84e8cb4635bad0ea97aebf196a261a4 100644 (file)
@@ -1,6 +1,7 @@
 /**************************************************************************
  * 
  * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * Copyright (c) 2008 VMware, Inc.
  * All Rights Reserved.
  * 
  * Permission is hereby granted, free of charge, to any person obtaining a
 #include <windows.h>
 #include <winddi.h>
 
+#elif defined(PIPE_SUBSYSTEM_WINDOWS_CE)
+
+#include <stdio.h> 
+#include <stdlib.h> 
+#include <windows.h> 
+#include <types.h> 
+
 #elif defined(PIPE_SUBSYSTEM_WINDOWS_USER)
 
 #ifndef WIN32_LEAN_AND_MEAN
 #include "pipe/p_format.h" 
 #include "pipe/p_state.h" 
 #include "pipe/p_inlines.h" 
+#include "util/u_memory.h" 
 #include "util/u_string.h" 
+#include "util/u_stream.h" 
+#include "util/u_math.h" 
+#include "util/u_tile.h" 
 
 
 #ifdef PIPE_SUBSYSTEM_WINDOWS_DISPLAY
@@ -94,11 +106,41 @@ void _debug_vprintf(const char *format, va_list ap)
       OutputDebugStringA(buf);
       buf[0] = '\0';
    }
-#elif defined(PIPE_SUBSYSTEM_WINDOWS_CE) || defined(PIPE_SUBSYSTEM_WINDOWS_MINIPORT) 
+#elif defined(PIPE_SUBSYSTEM_WINDOWS_CE)
+   wchar_t *wide_format;
+   long wide_str_len;   
+   char buf[512];   
+   int ret;   
+#if (_WIN32_WCE < 600)
+   ret = vsprintf(buf, format, ap);   
+   if(ret < 0){   
+       sprintf(buf, "Cant handle debug print!");   
+       ret = 25;
+   }
+#else
+   ret = vsprintf_s(buf, 512, format, ap);   
+   if(ret < 0){   
+       sprintf_s(buf, 512, "Cant handle debug print!");   
+       ret = 25;
+   }
+#endif
+   buf[ret] = '\0';   
+   /* Format is ascii - needs to be converted to wchar_t for printing */   
+   wide_str_len = MultiByteToWideChar(CP_ACP, 0, (const char *) buf, -1, NULL, 0);   
+   wide_format = (wchar_t *) malloc((wide_str_len+1) * sizeof(wchar_t));   
+   if (wide_format) {   
+      MultiByteToWideChar(CP_ACP, 0, (const char *) buf, -1,   
+            wide_format, wide_str_len);   
+      NKDbgPrintfW(wide_format, wide_format);   
+      free(wide_format);   
+   } 
+#elif defined(PIPE_SUBSYSTEM_WINDOWS_MINIPORT)
    /* TODO */
 #else /* !PIPE_SUBSYSTEM_WINDOWS */
+#ifdef DEBUG
    vfprintf(stderr, format, ap);
 #endif
+#endif
 }
 
 
@@ -302,6 +344,13 @@ debug_get_flags_option(const char *name,
    str = _debug_get_option(name);
    if(!str)
       result = dfault;
+   else if (!util_strcmp(str, "help")) {
+      result = dfault;
+      while (flags->name) {
+         debug_printf("%s: help for %s: %s [0x%lx]\n", __FUNCTION__, name, flags->name, flags->value);
+         flags++;
+      }
+   }
    else {
       result = 0;
       while( flags->name ) {
@@ -311,7 +360,12 @@ debug_get_flags_option(const char *name,
       }
    }
 
-   debug_printf("%s: %s = 0x%lx\n", __FUNCTION__, name, result);
+   if (str) {
+      debug_printf("%s: %s = 0x%lx (%s)\n", __FUNCTION__, name, result, str);
+   }
+   else {
+      debug_printf("%s: %s = 0x%lx\n", __FUNCTION__, name, result);
+   }
 
    return result;
 }
@@ -323,7 +377,7 @@ void _debug_assert_fail(const char *expr,
                         const char *function) 
 {
    _debug_printf("%s:%u:%s: Assertion `%s' failed.\n", file, line, function, expr);
-#if defined(PIPE_OS_WINDOWS)
+#if defined(PIPE_OS_WINDOWS) && !defined(PIPE_SUBSYSTEM_WINDOWS_USER)
    if (debug_get_bool_option("GALLIUM_ABORT_ON_ASSERT", FALSE))
 #else
    if (debug_get_bool_option("GALLIUM_ABORT_ON_ASSERT", TRUE))
@@ -480,16 +534,24 @@ static const struct debug_named_value pipe_format_names[] = {
    DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8B8A8_SSCALED),
    DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8B8X8_SSCALED),
    DEBUG_NAMED_VALUE(PIPE_FORMAT_L8_SRGB),
-   DEBUG_NAMED_VALUE(PIPE_FORMAT_A8_L8_SRGB),
+   DEBUG_NAMED_VALUE(PIPE_FORMAT_A8L8_SRGB),
    DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8B8_SRGB),
    DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8B8A8_SRGB),
    DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8B8X8_SRGB),
+   DEBUG_NAMED_VALUE(PIPE_FORMAT_A8R8G8B8_SRGB),
+   DEBUG_NAMED_VALUE(PIPE_FORMAT_X8R8G8B8_SRGB),
+   DEBUG_NAMED_VALUE(PIPE_FORMAT_B8G8R8A8_SRGB),
+   DEBUG_NAMED_VALUE(PIPE_FORMAT_B8G8R8X8_SRGB),
    DEBUG_NAMED_VALUE(PIPE_FORMAT_X8UB8UG8SR8S_NORM),
    DEBUG_NAMED_VALUE(PIPE_FORMAT_B6UG5SR5S_NORM),
    DEBUG_NAMED_VALUE(PIPE_FORMAT_DXT1_RGB),
    DEBUG_NAMED_VALUE(PIPE_FORMAT_DXT1_RGBA),
    DEBUG_NAMED_VALUE(PIPE_FORMAT_DXT3_RGBA),
    DEBUG_NAMED_VALUE(PIPE_FORMAT_DXT5_RGBA),
+   DEBUG_NAMED_VALUE(PIPE_FORMAT_DXT1_SRGB),
+   DEBUG_NAMED_VALUE(PIPE_FORMAT_DXT1_SRGBA),
+   DEBUG_NAMED_VALUE(PIPE_FORMAT_DXT3_SRGBA),
+   DEBUG_NAMED_VALUE(PIPE_FORMAT_DXT5_SRGBA),
 #endif
    DEBUG_NAMED_VALUE_END
 };
@@ -584,4 +646,111 @@ error2:
 error1:
    ;
 }
+
+
+#pragma pack(push,2)
+struct bmp_file_header {
+   uint16_t bfType;
+   uint32_t bfSize;
+   uint16_t bfReserved1;
+   uint16_t bfReserved2;
+   uint32_t bfOffBits;
+};
+#pragma pack(pop)
+
+struct bmp_info_header {
+   uint32_t biSize;
+   int32_t biWidth;
+   int32_t biHeight;
+   uint16_t biPlanes;
+   uint16_t biBitCount;
+   uint32_t biCompression;
+   uint32_t biSizeImage;
+   int32_t biXPelsPerMeter;
+   int32_t biYPelsPerMeter;
+   uint32_t biClrUsed;
+   uint32_t biClrImportant;
+};
+
+struct bmp_rgb_quad {
+   uint8_t rgbBlue;
+   uint8_t rgbGreen;
+   uint8_t rgbRed;
+   uint8_t rgbAlpha;
+};
+
+void 
+debug_dump_surface_bmp(const char *filename,
+                       struct pipe_surface *surface)
+{
+#ifndef PIPE_SUBSYSTEM_WINDOWS_MINIPORT
+   struct util_stream *stream;
+   unsigned surface_usage;
+   struct bmp_file_header bmfh;
+   struct bmp_info_header bmih;
+   float *rgba;
+   unsigned x, y;
+
+   if (!surface)
+      goto error1;
+
+   rgba = MALLOC(surface->width*4*sizeof(float));
+   if(!rgba)
+      goto error1;
+   
+   bmfh.bfType = 0x4d42;
+   bmfh.bfSize = 14 + 40 + surface->height*surface->width*4;
+   bmfh.bfReserved1 = 0;
+   bmfh.bfReserved2 = 0;
+   bmfh.bfOffBits = 14 + 40;
+   
+   bmih.biSize = 40;
+   bmih.biWidth = surface->width;
+   bmih.biHeight = surface->height;
+   bmih.biPlanes = 1;
+   bmih.biBitCount = 32;
+   bmih.biCompression = 0;
+   bmih.biSizeImage = surface->height*surface->width*4;
+   bmih.biXPelsPerMeter = 0;
+   bmih.biYPelsPerMeter = 0;
+   bmih.biClrUsed = 0;
+   bmih.biClrImportant = 0;
+   
+   stream = util_stream_create(filename, bmfh.bfSize);
+   if(!stream)
+      goto error2;
+   
+   util_stream_write(stream, &bmfh, 14);
+   util_stream_write(stream, &bmih, 40);
+   
+   /* XXX: force mappable surface */
+   surface_usage = surface->usage;
+   surface->usage |= PIPE_BUFFER_USAGE_CPU_READ;
+
+   y = surface->height;
+   while(y--) {
+      pipe_get_tile_rgba(surface,
+                         0, y, surface->width, 1,
+                         rgba);
+      for(x = 0; x < surface->width; ++x)
+      {
+         struct bmp_rgb_quad pixel;
+         pixel.rgbRed   = float_to_ubyte(rgba[x*4 + 0]);
+         pixel.rgbGreen = float_to_ubyte(rgba[x*4 + 1]);
+         pixel.rgbBlue  = float_to_ubyte(rgba[x*4 + 2]);
+         pixel.rgbAlpha = float_to_ubyte(rgba[x*4 + 3]);
+         util_stream_write(stream, &pixel, 4);
+      }  
+   }
+   
+   surface->usage = surface_usage;
+
+   util_stream_close(stream);
+error2:
+   FREE(rgba);
+error1:
+   ;
+#endif
+}
+
 #endif