Basic MapBuffer/MapBufferRange trace/retrace support.
authorJosé Fonseca <jose.r.fonseca@gmail.com>
Sun, 24 Apr 2011 10:58:04 +0000 (11:58 +0100)
committerJosé Fonseca <jose.r.fonseca@gmail.com>
Sun, 24 Apr 2011 10:58:04 +0000 (11:58 +0100)
Not thread-safe; but not much else is either ATM.

TODO
glapi.py
glretrace.py
gltrace.py
glxtrace.py
trace_model.cpp
wgltrace.py

diff --git a/TODO b/TODO
index ffa5a60..1457d65 100644 (file)
--- a/TODO
+++ b/TODO
@@ -19,8 +19,6 @@ Tracing:
 * Allow to distinguish between the calls really done by the program, vs the
   fakes one necessary to retrace correctly.
 
-* Trace writes done through glMapBuffer and glMapBufferRange correctly
-
 * Start tracing on demand (e.g., key-press, or by frame no), emitting calls
   that recreate all current state.
 
index e8261ed..3f2aebe 100644 (file)
--- a/glapi.py
+++ b/glapi.py
@@ -88,6 +88,7 @@ GLrenderbuffer = Handle("renderbuffer", GLuint)
 GLfragmentShaderATI = Handle("fragmentShaderATI", GLuint)
 GLvertexArray = Handle("vertexArrayAPPLE", GLuint)
 GLregion = Handle("region", GLuint)
+GLmap = Handle("map", OpaquePointer(GLvoid))
 
 # Some functions take GLenum disguised as GLint.  Apple noticed and fixed it in
 # the gl.h header.  Regardless, C++ typechecking rules force the wrappers to
@@ -611,10 +612,10 @@ glapi.add_functions([
     GlFunction(Void, "glBufferData", [(GLenum, "target"), (GLsizeiptr, "size"), (Blob(Const(GLvoid), "size"), "data"), (GLenum, "usage")]),
     GlFunction(Void, "glBufferSubData", [(GLenum, "target"), (GLintptr, "offset"), (GLsizeiptr, "size"), (Blob(Const(GLvoid), "size"), "data")]),
     GlFunction(Void, "glGetBufferSubData", [(GLenum, "target"), (GLintptr, "offset"), (GLsizeiptr, "size"), Out(Blob(GLvoid, "size"), "data")], sideeffects=False),
-    GlFunction(OpaquePointer(GLvoid), "glMapBuffer", [(GLenum, "target"), (GLenum, "access")]),
+    GlFunction(GLmap, "glMapBuffer", [(GLenum, "target"), (GLenum, "access")]),
     GlFunction(GLboolean, "glUnmapBuffer", [(GLenum, "target")]),
-    GlFunction(Void, "glGetBufferParameteriv", [(GLenum, "target"), (GLenum, "pname"), (OpaquePointer(GLint), "params")], sideeffects=False),
-    GlFunction(Void, "glGetBufferPointerv", [(GLenum, "target"), (GLenum, "pname"), (OpaquePointer(OpaquePointer(GLvoid)), "params")], sideeffects=False),
+    GlFunction(Void, "glGetBufferParameteriv", [(GLenum, "target"), (GLenum, "pname"), (Pointer(GLint), "params")], sideeffects=False),
+    GlFunction(Void, "glGetBufferPointerv", [(GLenum, "target"), (GLenum, "pname"), (Pointer(OpaquePointer(GLvoid)), "params")], sideeffects=False),
 
     # GL_VERSION_2_0
     GlFunction(Void, "glBlendEquationSeparate", [(GLenum, "modeRGB"), (GLenum, "modeAlpha")]),
@@ -967,10 +968,10 @@ glapi.add_functions([
     GlFunction(Void, "glBufferDataARB", [(GLenum, "target"), (GLsizeiptrARB, "size"), (Const(Blob(GLvoid, "size")), "data"), (GLenum, "usage")]),
     GlFunction(Void, "glBufferSubDataARB", [(GLenum, "target"), (GLintptrARB, "offset"), (GLsizeiptrARB, "size"), (Const(Blob(GLvoid, "size")), "data")]),
     GlFunction(Void, "glGetBufferSubDataARB", [(GLenum, "target"), (GLintptrARB, "offset"), (GLsizeiptrARB, "size"), Out(Blob(GLvoid, "size"), "data")], sideeffects=False),
-    GlFunction(OpaquePointer(GLvoid), "glMapBufferARB", [(GLenum, "target"), (GLenum, "access")]),
+    GlFunction(GLmap, "glMapBufferARB", [(GLenum, "target"), (GLenum, "access")]),
     GlFunction(GLboolean, "glUnmapBufferARB", [(GLenum, "target")]),
-    GlFunction(Void, "glGetBufferParameterivARB", [(GLenum, "target"), (GLenum, "pname"), Out(OpaquePointer(GLint), "params")], sideeffects=False),
-    GlFunction(Void, "glGetBufferPointervARB", [(GLenum, "target"), (GLenum, "pname"), Out(Array(OpaquePointer(GLvoid), "1"), "params")], sideeffects=False),
+    GlFunction(Void, "glGetBufferParameterivARB", [(GLenum, "target"), (GLenum, "pname"), Out(Pointer(GLint), "params")], sideeffects=False),
+    GlFunction(Void, "glGetBufferPointervARB", [(GLenum, "target"), (GLenum, "pname"), Out(Pointer(OpaquePointer(GLvoid)), "params")], sideeffects=False),
 
     # GL_ARB_occlusion_query
     GlFunction(Void, "glGenQueriesARB", [(GLsizei, "n"), Out(Array(GLquery, "n"), "ids")]),
@@ -1070,7 +1071,7 @@ glapi.add_functions([
     GlFunction(Void, "glVertexAttribDivisorARB", [(GLuint, "index"), (GLuint, "divisor")]),
 
     # GL_ARB_map_buffer_range
-    GlFunction(OpaquePointer(GLvoid), "glMapBufferRange", [(GLenum, "target"), (GLintptr, "offset"), (GLsizeiptr, "length"), (GLbitfield, "access")]),
+    GlFunction(GLmap, "glMapBufferRange", [(GLenum, "target"), (GLintptr, "offset"), (GLsizeiptr, "length"), (GLbitfield, "access")]),
     GlFunction(Void, "glFlushMappedBufferRange", [(GLenum, "target"), (GLintptr, "offset"), (GLsizeiptr, "length")]),
 
     # GL_ARB_texture_buffer_object
@@ -2302,3 +2303,5 @@ glapi.add_functions([
     GlFunction(GLuint, "glBufferRegionEnabled", [], sideeffects=False),
 ])
 
+
+memcpy = Function(Void, "memcpy", [(GLmap, "dest"), (Blob(Const(Void), "n"), "src"), (SizeT, "n")])
index 345e154..b3c8934 100644 (file)
@@ -169,11 +169,14 @@ class GlRetracer(Retracer):
 
 if __name__ == '__main__':
     print r'''
+#include <string.h>
+
 #include "glproc.hpp"
 #include "glretrace.hpp"
 
 
 '''
     api = glapi.glapi
+    api.add_function(glapi.memcpy)
     retracer = GlRetracer()
     retracer.retrace_api(glapi.glapi)
index 09d423e..4d81d2e 100644 (file)
@@ -151,6 +151,31 @@ class GlTracer(Tracer):
 
         print 'static void __trace_user_arrays(GLuint maxindex);'
         print
+
+        print 'struct buffer_mapping {'
+        print '    void *map;'
+        print '    GLint length;'
+        print '    bool write;'
+        print '};'
+        print
+        for target in self.buffer_targets:
+            print 'struct buffer_mapping __%s_mapping;' % target.lower();
+        print
+        print 'static inline struct buffer_mapping *'
+        print 'get_buffer_mapping(GLenum target) {'
+        print '    switch(target) {'
+        for target in self.buffer_targets:
+            print '    case GL_%s:' % target
+            print '        return & __%s_mapping;' % target.lower()
+        print '    default:'
+        print '        OS::DebugMessage("warning: unknown buffer target 0x%04X\\n", target);'
+        print '        return NULL;'
+        print '    }'
+        print '}'
+        print
+
+        # Generate memcpy's signature
+        self.trace_function_decl(glapi.memcpy)
     
     array_pointer_function_names = set((
         "glVertexPointer",
@@ -271,7 +296,53 @@ class GlTracer(Tracer):
             print '        return;'
             print '    }'
 
+        # Emit a fake memcpy on
+        if function.name in ('glUnmapBuffer', 'glUnmapBufferARB'):
+            print '    struct buffer_mapping *mapping = get_buffer_mapping(target);'
+            print '    if (mapping && mapping->write) {'
+            print '        unsigned __call = Trace::BeginEnter(__memcpy_sig);'
+            print '        Trace::BeginArg(0);'
+            print '        Trace::LiteralOpaque(mapping->map);'
+            print '        Trace::EndArg();'
+            print '        Trace::BeginArg(1);'
+            print '        Trace::LiteralBlob(mapping->map, mapping->length);'
+            print '        Trace::EndArg();'
+            print '        Trace::BeginArg(2);'
+            print '        Trace::LiteralUInt(mapping->length);'
+            print '        Trace::EndArg();'
+            print '        Trace::EndEnter();'
+            print '        Trace::BeginLeave(__call);'
+            print '        Trace::EndLeave();'
+            print '    }'
+
         Tracer.trace_function_impl_body(self, function)
+       
+    buffer_targets = [
+        'ARRAY_BUFFER',
+        'ELEMENT_ARRAY_BUFFER',
+        'PIXEL_PACK_BUFFER',
+        'PIXEL_UNPACK_BUFFER',
+    ]
+
+    def wrap_ret(self, function, instance):
+        Tracer.wrap_ret(self, function, instance)
+            
+        if function.name in ('glMapBuffer', 'glMapBufferARB'):
+            print '    struct buffer_mapping *mapping = get_buffer_mapping(target);'
+            print '    if (mapping) {'
+            print '        mapping->map = %s;' % (instance)
+            print '        mapping->length = 0;'
+            print '        __glGetBufferParameteriv(target, GL_BUFFER_SIZE, &mapping->length);'
+            print '        mapping->write = (access != GL_READ_ONLY);'
+            print '    }'
+
+        if function.name == 'glMapBufferRange':
+            print '    struct buffer_mapping *mapping = get_buffer_mapping(target);'
+            print '    if (mapping) {'
+            print '        mapping->map = %s;' % (instance)
+            print '        mapping->length = length;'
+            print '        mapping->write = access & GL_MAP_WRITE_BIT;'
+            print '    }'
 
     boolean_names = [
         'GL_FALSE',
index 78d6146..c6e88cd 100644 (file)
@@ -45,6 +45,8 @@ class GlxTracer(GlTracer):
         return '__%s' % (function.name,)
 
     def wrap_ret(self, function, instance):
+        GlTracer.wrap_ret(self, function, instance)
+
         if function.name in ("glXGetProcAddress", "glXGetProcAddressARB"):
             print '    %s = __unwrap_proc_addr(procName, %s);' % (instance, instance)
 
index b083186..a817b39 100644 (file)
@@ -110,7 +110,7 @@ Enum   ::operator double (void) const { return static_cast<unsigned long long>(*
 void * Value  ::blob(void) const { assert(0); return NULL; }
 void * Null   ::blob(void) const { return NULL; }
 void * Blob   ::blob(void) const { return buf; }
-void * Pointer::blob(void) const { assert(value < 0x100000ULL); return (void *)value; }
+void * Pointer::blob(void) const { return (void *)value; }
 
 
 // virtual Value::visit()
index 480ebcb..3c94604 100644 (file)
@@ -41,6 +41,8 @@ class WglTracer(GlTracer):
         return '__%s' % (function.name,)
 
     def wrap_ret(self, function, instance):
+        GlTracer.wrap_ret(self, function, instance)
+
         if function.name == "wglGetProcAddress":
             print '    if (%s) {' % instance