Home | History | Annotate | Download | only in nine
      1 /*
      2  * Copyright 2011 Joakim Sindholt <opensource (at) zhasha.com>
      3  *
      4  * Permission is hereby granted, free of charge, to any person obtaining a
      5  * copy of this software and associated documentation files (the "Software"),
      6  * to deal in the Software without restriction, including without limitation
      7  * on the rights to use, copy, modify, merge, publish, distribute, sub
      8  * license, and/or sell copies of the Software, and to permit persons to whom
      9  * the Software is furnished to do so, subject to the following conditions:
     10  *
     11  * The above copyright notice and this permission notice (including the next
     12  * paragraph) shall be included in all copies or substantial portions of the
     13  * Software.
     14  *
     15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     17  * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
     18  * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
     19  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
     20  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
     21  * USE OR OTHER DEALINGS IN THE SOFTWARE. */
     22 
     23 #include "nine_debug.h"
     24 
     25 #include <ctype.h>
     26 #include "c11/threads.h"
     27 
     28 static const struct debug_named_value nine_debug_flags[] = {
     29     { "unknown", DBG_UNKNOWN,              "IUnknown implementation." },
     30     { "adapter", DBG_ADAPTER,              "ID3D9Adapter implementation." },
     31     { "overlay", DBG_OVERLAYEXTENSION,     "IDirect3D9ExOverlayExtension implementation." },
     32     { "auth",    DBG_AUTHENTICATEDCHANNEL, "IDirect3DAuthenticatedChannel9 implementation." },
     33     { "basetex", DBG_BASETEXTURE,          "IDirect3DBaseTexture9 implementation." },
     34     { "crypto",  DBG_CRYPTOSESSION,        "IDirect3DCryptoSession9 implementation." },
     35     { "cubetex", DBG_CUBETEXTURE,          "IDirect3DCubeTexture9 implementation." },
     36     { "device",  DBG_DEVICE,               "IDirect3DDevice9(Ex) implementation." },
     37     { "video",   DBG_DEVICEVIDEO,          "IDirect3DDeviceVideo9 implementation." },
     38     { "ibuf",    DBG_INDEXBUFFER,          "IDirect3DIndexBuffer9 implementation." },
     39     { "ps",      DBG_PIXELSHADER,          "IDirect3DPixelShader9 implementation." },
     40     { "query",   DBG_QUERY,                "IDirect3DQuery9 implementation." },
     41     { "res",     DBG_RESOURCE,             "IDirect3DResource9 implementation." },
     42     { "state",   DBG_STATEBLOCK,           "IDirect3DStateBlock9 implementation." },
     43     { "surf",    DBG_SURFACE,              "IDirect3DSurface9 implementation." },
     44     { "swap",    DBG_SWAPCHAIN,            "IDirect3DSwapChain9(Ex) implementation." },
     45     { "tex",     DBG_TEXTURE,              "IDirect3DTexture9 implementation." },
     46     { "vbuf",    DBG_VERTEXBUFFER,         "IDirect3DVertexBuffer9 implementation." },
     47     { "vdecl",   DBG_VERTEXDECLARATION,    "IDirect3DVertexDeclaration9 implementation." },
     48     { "vs",      DBG_VERTEXSHADER,         "IDirect3DVertexShader9 implementation." },
     49     { "3dsurf",  DBG_VOLUME,               "IDirect3DVolume9 implementation." },
     50     { "3dtex",   DBG_VOLUMETEXTURE,        "IDirect3DVolumeTexture9 implementation." },
     51     { "shader",  DBG_SHADER,               "Shader token stream translator." },
     52     { "ff",      DBG_FF,                   "Fixed function emulation." },
     53     { "user",    DBG_USER,                 "User errors, both fixable and unfixable." },
     54     { "error",   DBG_ERROR,                "Driver errors, always visible." },
     55     { "warn",    DBG_WARN,                 "Driver warnings, always visible in debug builds." },
     56     { "tid",     DBG_TID,                  "Display thread-ids." },
     57     DEBUG_NAMED_VALUE_END
     58 };
     59 
     60 void
     61 _nine_debug_printf( unsigned long flag,
     62                     const char *func,
     63                     const char *fmt,
     64                     ... )
     65 {
     66     static boolean first = TRUE;
     67     static unsigned long dbg_flags = DBG_ERROR | DBG_WARN;
     68     unsigned long tid = 0;
     69 
     70     if (first) {
     71         first = FALSE;
     72         dbg_flags |= debug_get_flags_option("NINE_DEBUG", nine_debug_flags, 0);
     73     }
     74 
     75 #if defined(HAVE_PTHREAD)
     76 #  if defined(__GNU_LIBRARY__) && defined(__GLIBC__) && defined(__GLIBC_MINOR__) && \
     77       (__GLIBC__ >= 3 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 12))
     78     if (dbg_flags & DBG_TID)
     79         tid = pthread_self();
     80 #  endif
     81 #endif
     82 
     83     if (dbg_flags & flag) {
     84         const char *f = func ? strrchr(func, '_') : NULL;
     85         va_list ap;
     86         /* inside a class this will print nine:tid:classinlowercase:func: while
     87          * outside a class (rarely used) it will just print nine:tid:func
     88          * the reason for lower case is simply to match the filenames, as it
     89          * will also strip off the "Nine" */
     90         if (f && strncmp(func, "Nine", 4) == 0) {
     91             char klass[96]; /* no class name is this long */
     92             char *ptr = klass;
     93             for (func += 4; func != f; ++func) { *ptr++ = tolower(*func); }
     94             *ptr = '\0';
     95             if (tid)
     96                 debug_printf("nine:0x%08lx:%s:%s: ", tid, klass, ++f);
     97             else
     98                 debug_printf("nine:%s:%s: ", klass, ++f);
     99         } else if (func) {
    100             if (tid)
    101                 debug_printf("nine:0x%08lx:%s ", tid, func);
    102             else
    103                 debug_printf("nine:%s ", func);
    104         }
    105 
    106         va_start(ap, fmt);
    107         debug_vprintf(fmt, ap);
    108         va_end(ap);
    109     }
    110 }
    111 
    112 void
    113 _nine_stub( const char *file,
    114             const char *func,
    115             unsigned line )
    116 {
    117     const char *r = strrchr(file, '/');
    118     if (r == NULL) { r = strrchr(file, '\\'); }
    119     debug_printf("nine:%s:%d: %s STUB!\n", r ? ++r : file, line, func);
    120 }
    121