all: glwrap.so gldump gldbg
-glwrap.so: source/glwrap.o
+glwrap.so: source/glwrap.o source/arraysize.o
$(CC) -shared -o $@ $^ $(LIBS) $(LDFLAGS)
-gldump: source/gldecoder.o source/gldump.o source/glprint.o source/enums.o
+gldump: source/gldecoder.o source/gldump.o source/glprint.o source/enums.o source/arraysize.o source/tmpalloc.o
$(CC) -o $@ $^ $(LIBS) $(LDFLAGS)
-gldbg: source/gldbg.o source/gldecoder.o source/glprint.o source/commandinterpreter.o source/tracer.o source/process.o source/enums.o
+gldbg: source/gldbg.o source/gldecoder.o source/glprint.o source/commandinterpreter.o source/tracer.o source/process.o source/enums.o source/arraysize.o source/tmpalloc.o
$(CXX) -o $@ $^ $(LIBS_gldbg) $(LIBS) $(LDFLAGS)
source/glwrap.o: source/functions.h gensrc/functions.enum gensrc/glwrap.funcs
source/gldecoder.o: source/functions.h gensrc/gldecoder.struct gensrc/gldecoder.funcs gensrc/gldecoder.funcs
source/gldump.o: source/gldecoder.h gensrc/gldecoder.struct source/glprint.h
-source/glprint.o: gensrc/glprint.funcs gensrc/gldecoder.struct
+source/glprint.o: source/arraysize.h gensrc/glprint.funcs gensrc/gldecoder.struct
source/enums.o: gensrc/enums.table
source/gldbg.o: source/gldbg.cpp source/gldbg.h source/gldecoder.h source/tracer.h
if self.kind=="value":
if self.base_ctype.startswith("const "):
self.base_ctype = self.base_ctype[6:]
- self.io = iomap[self.base_ctype]
else:
if self.direction=="in":
self.ctype = "const "+self.ctype
self.ctype = self.ctype+" *"
+ self.io = iomap[self.base_ctype]
def derive_csize(self):
if self.kind=="array" and self.size is not None:
self.csize = "%d*sizeof(%s)"%(self.size, self.base_ctype)
elif self.size.startswith("COMPSIZE("):
self.csize = self.func.compsize(self.size[9:-1], self.base_ctype)
+ elif self.size=="pname":
+ self.csize = "paramsize(pname)*sizeof(%s)"%self.base_ctype
else:
s = self.func.get_param(self.size.split('*')[0])
if (s.type=="SizeI" or s.type.endswith("Int32") or s.type.startswith("BufferSize")) and s.kind=="value":
have_type = True
elif cn.endswith("Format"):
res += "formatsize(%s)"%param.name
- elif cn.endswith(("Parameter", "ParameterPName", "ParameterName")) or cn=="GetPName":
+ elif param.name=="pname" or cn.endswith("Parameter"):
res += "paramsize(%s)"%param.name
elif cn=="MapTarget":
res += "mapsize(%s)"%param.name
intptr, int, %i
sizeiptr, int, %i
handle, int, %i
+int64, longlong, %lli
uint64, longlong, %llu
half, short, %#x
float, float, %g
ubyte *, string, \"%s\"
char *, string, \"%s\"
void *, pointer, %p
+void* const, pointer, %p
+boolean *, pointer, %p
int, int, %i
uint, int, %u
unsigned int, int, %u
+int32_t, int, %i
+long, long, %li
unsigned long, long, %lu
int64_t, longlong, %lli
sizei, int, %i
GLfunction,*,*, GLfunction,*,*
GLint,*,*, GLint,*,*
GLsizei,*,*, GLsizei,*,*
-GLubyte,*,reference, GLubyte *,*,value
+GLubyte,*,reference, GLubyte *,*,value
GLuint,*,*, GLuint,*,*
Pixmap,*,*, Pixmap,*,*
Status,*,*, Status,*,*
VLServer,*,*, VLServer,*,*
Window,*,*, Window,*,*
Font,*,*, Font,*,*
-XVisualInfo,*,*, XVisualInfo,*,*
+XVisualInfo,*,reference, XVisualInfo *,*,value
XVisualInfoPointer,*,*, XVisualInfo *,*,*
float,*,*, float,*,*
int,*,*, int,*,*
--- /dev/null
+/* $Id$
+
+This file is part of gldbg
+Copyright © 2009 Mikko Rasa, Mikkosoft Productions
+Distributed under the GPL
+*/
+
+#include "arraysize.h"
+
+int typesize(GLenum type)
+{
+ switch(type)
+ {
+ case GL_BYTE: return sizeof(GLbyte);
+ case GL_SHORT: return sizeof(GLshort);
+ case GL_INT: return sizeof(GLint);
+ case GL_UNSIGNED_BYTE: return sizeof(GLubyte);
+ case GL_UNSIGNED_SHORT: return sizeof(GLushort);
+ case GL_UNSIGNED_INT: return sizeof(GLuint);
+ case GL_FLOAT: return sizeof(GLfloat);
+ case GL_DOUBLE: return sizeof(GLdouble);
+ // Short and byte packed types are broken
+ default: return 1;
+ }
+}
+
+int formatsize(GLenum format)
+{
+ switch(format)
+ {
+ case GL_COLOR_INDEX: return 1;
+ case GL_STENCIL_INDEX: return 1;
+ case GL_DEPTH_COMPONENT: return 1;
+ case GL_RED: return 1;
+ case GL_GREEN: return 1;
+ case GL_BLUE: return 1;
+ case GL_ALPHA: return 1;
+ case GL_RGB: return 3;
+ case GL_RGBA: return 4;
+ case GL_BGR: return 3;
+ case GL_BGRA: return 4;
+ case GL_LUMINANCE: return 1;
+ case GL_LUMINANCE_ALPHA: return 2;
+ default: return 1;
+ }
+}
+
+int paramsize(GLenum pname)
+{
+ switch(pname)
+ {
+ // Lighting and material
+ case GL_AMBIENT: return 4;
+ case GL_DIFFUSE: return 4;
+ case GL_AMBIENT_AND_DIFFUSE: return 4;
+ case GL_SPECULAR: return 4;
+ case GL_EMISSION: return 4;
+ case GL_SHININESS: return 1;
+ case GL_COLOR_INDEXES: return 3;
+ case GL_POSITION: return 4;
+ case GL_SPOT_DIRECTION: return 3;
+ case GL_SPOT_EXPONENT: return 1;
+ case GL_SPOT_CUTOFF: return 1;
+ case GL_CONSTANT_ATTENUATION: return 1;
+ case GL_LINEAR_ATTENUATION: return 1;
+ case GL_QUADRATIC_ATTENUATION: return 1;
+ case GL_LIGHT_MODEL_AMBIENT: return 4;
+ case GL_LIGHT_MODEL_LOCAL_VIEWER: return 1;
+ case GL_LIGHT_MODEL_TWO_SIDE: return 1;
+ case GL_LIGHT_MODEL_COLOR_CONTROL: return 1;
+
+ // Texture
+ case GL_TEXTURE_WRAP_S: return 1;
+ case GL_TEXTURE_WRAP_T: return 1;
+ case GL_TEXTURE_WRAP_R: return 1;
+ case GL_TEXTURE_MIN_FILTER: return 1;
+ case GL_TEXTURE_MAG_FILTER: return 1;
+ case GL_TEXTURE_BORDER_COLOR: return 4;
+ case GL_TEXTURE_MIN_LOD: return 1;
+ case GL_TEXTURE_MAX_LOD: return 1;
+ case GL_TEXTURE_BASE_LEVEL: return 1;
+ case GL_TEXTURE_MAX_LEVEL: return 1;
+ case GL_TEXTURE_LOD_BIAS: return 1;
+ case GL_DEPTH_TEXTURE_MODE: return 1;
+ case GL_TEXTURE_COMPARE_MODE: return 1;
+ case GL_TEXTURE_COMPARE_FUNC: return 1;
+ case GL_GENERATE_MIPMAP: return 1;
+ default: return 1;
+ }
+}
+
+int mapsize(GLenum target)
+{
+ // XXX Implement this
+ return 1;
+}
--- /dev/null
+/* $Id$
+
+This file is part of gldbg
+Copyright © 2009 Mikko Rasa, Mikkosoft Productions
+Distributed under the GPL
+*/
+
+#ifndef ARRAYSIZE_H_
+#define ARRAYSIZE_H_
+
+#include <GL/gl.h>
+
+extern int typesize(GLenum);
+extern int formatsize(GLenum);
+extern int paramsize(GLenum);
+extern int mapsize(GLenum);
+
+#endif
#include <stdio.h>
#include <stdlib.h>
#include "enums.h"
+#include "tmpalloc.h"
typedef struct sEnumInfo
{
#include "enums.table"
-char *buffer = 0;
-unsigned buf_pos = 0;
-
-static char *buf_reserve(unsigned size)
-{
- char *ptr;
- if(!buffer)
- buffer = (char *)malloc(2048);
- if(buf_pos+size>2048)
- buf_pos = 0;
- ptr = buffer+buf_pos;
- buf_pos += size;
- return ptr;
-}
-
const char *describe_enum(GLenum value, const char *categ)
{
unsigned low = 0;
if(enums[high].value==value)
return enums[high].name;
- ptr = buf_reserve(20);
+ ptr = (char *)tmpalloc(20);
snprintf(ptr, 20, "GLenum(0x%X)", value);
return ptr;
}
const char *describe_bitfield(int mask, const char *categ)
{
int bit;
- char *buf = buf_reserve(200);
+ char *buf = (char *)tmpalloc(200);
char *ptr = buf;
for(bit=1; bit; bit<<=1)
return read_data((const void **)v, data);
}
+static unsigned read_string_array(const unsigned char ***v, const char *data)
+{
+ int count;
+ unsigned pos = 0;
+ int i;
+ pos += read_int(&count, data);
+ *v = (const unsigned char **)tmpalloc(count*sizeof(const unsigned char *));
+ for(i=0; i<count; ++i)
+ pos += read_string(*v+i, data+pos);
+ return pos;
+}
+
#include "gldecoder.funcs"
static int decode_gldError(GlDecoder *dec, const char *data)
for p in params:
if p.kind=="value":
wl(' pos += read_%s(&p_%s, data+pos);', p.io[0], p.name)
+ elif p.kind=="array" and p.io and p.io[0]=="string":
+ wl(' pos += read_string_array(&p_%s, data+pos);', p.name)
elif p.csize:
wl(' pos += read_data((const void **)&p_%s, data+pos);', p.name)
else:
#include <stdlib.h>
#include <stdio.h>
+#include <string.h>
+#include "arraysize.h"
#include "enums.h"
#include "glprint.h"
+#include "tmpalloc.h"
typedef struct sGlPrintData
{
char *buffer;
unsigned bufsize;
+ int free_buf;
} GlPrintData;
static void init_print(GlDecoder *);
-static void glprint_data_free(void *);
+static void glprint_free(void *);
static void print_gldError(void *, GLenum);
GlDecoder *glprint_new(char *buffer, unsigned bufsize)
gpd = (GlPrintData *)malloc(sizeof(GlPrintData));
gpd->buffer = buffer;
gpd->bufsize = bufsize;
+ gpd->free_buf = 0;
if(!gpd->buffer)
{
if(!gpd->bufsize)
gpd->bufsize = 1024;
gpd->buffer = (char *)malloc(gpd->bufsize);
- dec = gldecoder_new(gpd, glprint_data_free);
+ gpd->free_buf = 1;
}
- else
- dec = gldecoder_new(gpd, free);
+ dec = gldecoder_new(gpd, glprint_free);
init_print(dec);
dec->gldError = print_gldError;
return ((GlPrintData *)dec->user_data)->buffer;
}
-static void glprint_data_free(void *data)
+static void glprint_free(void *data)
{
GlPrintData *gpd = (GlPrintData *)data;
- free(gpd->buffer);
- free(gpd);
+ if(gpd->free_buf)
+ {
+ free(gpd->buffer);
+ free(gpd);
+ }
+ tmpfree();
}
+static const char *print_array(const char *fmt, const void *data, unsigned elem_size, unsigned count)
+{
+ const char *cptr;
+ char type = 0;
+ char *buffer;
+ unsigned buf_size;
+ char *ptr;
+ unsigned i;
+
+ for(cptr=fmt; (type<2 && *cptr); ++cptr)
+ {
+ if(*cptr=='%')
+ type = 1;
+ else if(type==1 && isalpha(*cptr))
+ type = *cptr;
+ }
+
+ count /= elem_size;
+ buf_size = count*20;
+ if(type=='s')
+ buf_size *= 50;
+ buffer = tmpalloc(buf_size);
+ ptr = buffer;
+ *ptr++ = '{';
+ for(i=0; i<count; ++i)
+ {
+ long long element = 0;
+ unsigned len;
+
+ if(i>0)
+ {
+ *ptr++ = ',';
+ *ptr++ = ' ';
+ }
+ memcpy(&element, (const char *)data+i*elem_size, elem_size);
+ if(type>='e' && type<='g' && elem_size==sizeof(float))
+ *(double *)&element = *(float *)&element;
+ len = snprintf(ptr, buf_size, fmt, element);
+ ptr += len;
+ buf_size -= len;
+ }
+ *ptr++ = '}';
+ *ptr = 0;
+
+ return buffer;
+}
+
+static const char *print_data(const void *data, unsigned size)
+{
+ if(!data)
+ return "NULL";
+ else if(!size)
+ return "/* data */";
+ else
+ {
+ char *buffer = tmpalloc(50);
+ snprintf(buffer, 50, "/* data: %d bytes */", size);
+ return buffer;
+ }
+}
+
+#include "glprint.funcs"
+
static void print_gldError(void *user_data, GLenum code)
{
GlPrintData *gpd = (GlPrintData *)user_data;
snprintf(gpd->buffer, gpd->bufsize, "ERROR: %s", describe_enum(code, "ErrorCode"));
}
-
-#include "glprint.funcs"
if not first:
w(', ')
if p.kind=="value":
- w("%s", p.io[1])
- else:
- w("%%p")
+ w('%s', p.io[1])
+ elif p.kind=="reference":
+ if p.io:
+ w('{%s}', p.io[1])
+ else:
+ w('<ref:%s>', p.type)
+ elif p.kind=="array":
+ w('%%s')
first = False
w(')')
if ret.ctype!="void":
w('"')
for p in params+[ret]:
if p.ctype!="void":
- if p.io and len(p.io)>=3 and p.io[2]:
- f = p.io[2].split(':')
- w(', %s(%s)', f[0], ", ".join(eval(x) for x in f[1:]))
- else:
- w(', %s', p.name)
+ if p.kind=="value":
+ if len(p.io)>=3 and p.io[2]:
+ f = p.io[2].split(':')
+ w(', %s(%s)', f[0], ", ".join(eval(x) for x in f[1:]))
+ else:
+ w(', %s', p.name)
+ elif p.kind=="reference":
+ if p.io:
+ w(', *%s', p.name)
+ elif p.kind=="array":
+ if not p.csize:
+ w(', print_data(%s, 0)', p.name)
+ elif p.base_ctype=="GLvoid" or p.base_ctype=="void":
+ w(', print_data(%s, %s)', p.name, p.csize)
+ else:
+ w(', print_array("%s", %s, sizeof(%s), %s)', p.io[1], p.name, p.base_ctype, p.csize)
wl(');')
wl('}')
:static void init_print(GlDecoder *dec)
#include <X11/Xlib.h>
#include <GL/gl.h>
#include <GL/glx.h>
+#include "arraysize.h"
#include "functions.h"
static inline void *glsym(const char *sym)
write_data(s, strlen(s)+1);
}
+static inline void write_string_array(const unsigned char **sa, unsigned size)
+{
+ unsigned i;
+ size /= sizeof(const unsigned char *);
+ write_int(size);
+ for(i=0; i<size; ++i)
+ write_string(sa[i]);
+}
+
static inline void begin_packet(int func)
{
if(!buffer)
writev(fd, iovecs, cur_vec-iovecs);
}
-static inline int typesize(GLenum type)
-{
- switch(type)
- {
- case GL_BYTE: return sizeof(GLbyte);
- case GL_SHORT: return sizeof(GLshort);
- case GL_INT: return sizeof(GLint);
- case GL_UNSIGNED_BYTE: return sizeof(GLubyte);
- case GL_UNSIGNED_SHORT: return sizeof(GLushort);
- case GL_UNSIGNED_INT: return sizeof(GLuint);
- case GL_FLOAT: return sizeof(GLfloat);
- case GL_DOUBLE: return sizeof(GLdouble);
- // Short and byte packed types are broken
- default: return 1;
- }
-}
-
-static inline int formatsize(GLenum format)
-{
- switch(format)
- {
- case GL_COLOR_INDEX: return 1;
- case GL_STENCIL_INDEX: return 1;
- case GL_DEPTH_COMPONENT: return 1;
- case GL_RED: return 1;
- case GL_GREEN: return 1;
- case GL_BLUE: return 1;
- case GL_ALPHA: return 1;
- case GL_RGB: return 3;
- case GL_RGBA: return 4;
- case GL_BGR: return 3;
- case GL_BGRA: return 4;
- case GL_LUMINANCE: return 1;
- case GL_LUMINANCE_ALPHA: return 2;
- default: return 1;
- }
-}
-
-static inline int paramsize(GLenum pname)
-{
- switch(pname)
- {
- // Lighting and material
- case GL_AMBIENT: return 4;
- case GL_DIFFUSE: return 4;
- case GL_AMBIENT_AND_DIFFUSE: return 4;
- case GL_SPECULAR: return 4;
- case GL_EMISSION: return 4;
- case GL_SHININESS: return 1;
- case GL_COLOR_INDEXES: return 3;
- case GL_POSITION: return 4;
- case GL_SPOT_DIRECTION: return 3;
- case GL_SPOT_EXPONENT: return 1;
- case GL_SPOT_CUTOFF: return 1;
- case GL_CONSTANT_ATTENUATION: return 1;
- case GL_LINEAR_ATTENUATION: return 1;
- case GL_QUADRATIC_ATTENUATION: return 1;
- case GL_LIGHT_MODEL_AMBIENT: return 4;
- case GL_LIGHT_MODEL_LOCAL_VIEWER: return 1;
- case GL_LIGHT_MODEL_TWO_SIDE: return 1;
- case GL_LIGHT_MODEL_COLOR_CONTROL: return 1;
-
- // Texture
- case GL_TEXTURE_WRAP_S: return 1;
- case GL_TEXTURE_WRAP_T: return 1;
- case GL_TEXTURE_WRAP_R: return 1;
- case GL_TEXTURE_MIN_FILTER: return 1;
- case GL_TEXTURE_MAG_FILTER: return 1;
- case GL_TEXTURE_BORDER_COLOR: return 4;
- case GL_TEXTURE_MIN_LOD: return 1;
- case GL_TEXTURE_MAX_LOD: return 1;
- case GL_TEXTURE_BASE_LEVEL: return 1;
- case GL_TEXTURE_MAX_LEVEL: return 1;
- case GL_TEXTURE_LOD_BIAS: return 1;
- case GL_DEPTH_TEXTURE_MODE: return 1;
- case GL_TEXTURE_COMPARE_MODE: return 1;
- case GL_TEXTURE_COMPARE_FUNC: return 1;
- case GL_GENERATE_MIPMAP: return 1;
- default: return 1;
- }
-}
-
-static inline int mapsize(GLenum target)
-{
- return 1;
-}
-
GLenum cur_error = GL_NO_ERROR;
static void check_error()
for p in params:
if p.kind=="value":
wl(' write_%s(%s);', p.io[0], p.name)
+ elif p.kind=="array" and p.io and p.io[0]=="string":
+ wl(' write_string_array(%s, %s);', p.name, p.csize)
elif p.csize:
wl(' write_data(%s, %s);', p.name, p.csize)
else:
--- /dev/null
+/* $Id$
+
+This file is part of gldbg
+Copyright © 2009 Mikko Rasa, Mikkosoft Productions
+Distributed under the GPL
+*/
+
+#include <stdlib.h>
+#include "tmpalloc.h"
+
+void *buffer = 0;
+unsigned buf_size = 8192;
+unsigned offset = 0;
+
+void *tmpalloc(unsigned size)
+{
+ void *ptr;
+ if(!buffer)
+ buffer = malloc(buf_size);
+ if(offset+size>buf_size)
+ offset = 0;
+ ptr = (char *)buffer+offset;
+ offset += size;
+ return ptr;
+}
+
+void tmpfree()
+{
+ free(buffer);
+ buffer = 0;
+ offset = 0;
+}
--- /dev/null
+/* $Id$
+
+This file is part of gldbg
+Copyright © 2009 Mikko Rasa, Mikkosoft Productions
+Distributed under the GPL
+*/
+
+#ifndef TMPALLOC_H_
+#define TMPALLOC_H_
+
+/**
+Allocates a temporary memory region. The returned memory comes from a shared
+pool and will get reused eventually.
+*/
+extern void *tmpalloc(unsigned);
+
+/**
+Frees the shared pool used by tmpalloc. It will be recreated if tmpalloc is
+called again.
+*/
+extern void tmpfree();
+
+#endif