Support glTexImage through blobs.
authorJosé Fonseca <jfonseca@vmware.com>
Sat, 20 Nov 2010 11:22:25 +0000 (11:22 +0000)
committerJosé Fonseca <jfonseca@vmware.com>
Sat, 20 Nov 2010 11:22:25 +0000 (11:22 +0000)
base.py
glhelpers.hpp [new file with mode: 0644]
glretrace.py
glx.py
log.cpp
log.hpp
trace_model.cpp
trace_model.hpp
trace_parser.hpp

diff --git a/base.py b/base.py
index 2f2b1d0..c6be245 100644 (file)
--- a/base.py
+++ b/base.py
@@ -54,6 +54,9 @@ class Visitor:
     def visit_array(self, type, *args, **kwargs):
         raise NotImplementedError
 
+    def visit_blob(self, type, *args, **kwargs):
+        raise NotImplementedError
+
     def visit_enum(self, type, *args, **kwargs):
         raise NotImplementedError
 
@@ -89,6 +92,10 @@ class Rebuilder(Visitor):
         type = self.visit(array.type)
         return Array(type, array.length)
 
+    def visit_blob(self, blob):
+        type = self.visit(blob.type)
+        return Blob(type, blob.size)
+
     def visit_enum(self, enum):
         return enum
 
@@ -308,7 +315,7 @@ Flags = Bitmask
 class Array(Type):
 
     def __init__(self, type, length):
-        Type.__init__(self, type.expr + " *", 'P' + type.id)
+        Type.__init__(self, type.expr + " *")
         self.type = type
         self.length = length
 
@@ -338,6 +345,20 @@ class OutArray(Array):
         return True
 
 
+class Blob(Type):
+
+    def __init__(self, type, size):
+        Type.__init__(self, type.expr + ' *')
+        self.type = type
+        self.size = size
+
+    def visit(self, visitor, *args, **kwargs):
+        return visitor.visit_blob(self, *args, **kwargs)
+
+    def dump(self, instance):
+        print '    Log::LiteralBlob(%s, %s);' % (instance, self.size)
+
+
 class Struct(Concrete):
 
     def __init__(self, name, members):
diff --git a/glhelpers.hpp b/glhelpers.hpp
new file mode 100644 (file)
index 0000000..757c334
--- /dev/null
@@ -0,0 +1,63 @@
+/**************************************************************************
+ *
+ * Copyright 2010 VMware, Inc.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ **************************************************************************/
+
+#ifndef _GL_HELPERS_HPP_
+#define _GL_HELPERS_HPP_
+
+
+#include <cassert>
+
+static inline size_t
+__gl_image_size(GLenum format, GLenum type, GLsizei width, GLsizei height, GLsizei depth, GLint border) {
+   size_t bits_per_channel;
+   switch (type) {
+   case GL_UNSIGNED_BYTE:
+      bits_per_channel = 8;
+      break;
+   default:
+      assert(0);
+      bits_per_channel = 0;
+      break;
+   }
+
+   size_t bits_per_pixel;
+   switch (format) {
+   case GL_RGB:
+      bits_per_pixel = bits_per_channel * 3;
+      break;
+   default:
+      assert(0);
+      bits_per_pixel = 0;
+      break;
+   }
+
+   size_t row_stride = (width*bits_per_pixel + 7)/8;
+
+   size_t slice_stride = height*row_stride;
+
+   return depth*slice_stride;
+}
+
+#endif /* _GL_HELPERS_HPP_ */
index a689cc1..d8a3861 100644 (file)
@@ -56,6 +56,9 @@ class ValueExtractor(base.Visitor):
         self.visit(array.type, '%s[%s]' % (lvalue, index), '%s[%s]' % (rvalue, index))
         print '    }'
 
+    def visit_blob(self, type, lvalue, rvalue):
+        print '    %s = %s;' % (lvalue, rvalue)
+
 
 
 def retrace_function(function):
diff --git a/glx.py b/glx.py
index 12708d3..30ae7b9 100644 (file)
--- a/glx.py
+++ b/glx.py
@@ -210,8 +210,8 @@ libgl.functions += [
     DllFunction(Void, "glTexParameterfv", [(GLenum, "target"), (GLenum, "pname"), (Pointer(Const(GLfloat)), "params")]),
     DllFunction(Void, "glTexParameteri", [(GLenum, "target"), (GLenum, "pname"), (GLint, "param")]),
     DllFunction(Void, "glTexParameteriv", [(GLenum, "target"), (GLenum, "pname"), (Pointer(Const(GLint)), "params")]),
-    DllFunction(Void, "glTexImage1D", [(GLenum, "target"), (GLint, "level"), (GLint, "internalformat"), (GLsizei, "width"), (GLint, "border"), (GLenum, "format"), (GLenum, "type"), (Pointer(Const(GLvoid)), "pixels")]),
-    DllFunction(Void, "glTexImage2D", [(GLenum, "target"), (GLint, "level"), (GLint, "internalformat"), (GLsizei, "width"), (GLsizei, "height"), (GLint, "border"), (GLenum, "format"), (GLenum, "type"), (Pointer(Const(GLvoid)), "pixels")]),
+    DllFunction(Void, "glTexImage1D", [(GLenum, "target"), (GLint, "level"), (GLint, "internalformat"), (GLsizei, "width"), (GLint, "border"), (GLenum, "format"), (GLenum, "type"), (Blob(Const(GLvoid), "__gl_image_size(format, type, width, 1, 1, border)"), "pixels")]),
+    DllFunction(Void, "glTexImage2D", [(GLenum, "target"), (GLint, "level"), (GLint, "internalformat"), (GLsizei, "width"), (GLsizei, "height"), (GLint, "border"), (GLenum, "format"), (GLenum, "type"), (Blob(Const(GLvoid), "__gl_image_size(format, type, width, height, 1, border)"), "pixels")]),
     DllFunction(Void, "glTexEnvf", [(GLenum, "target"), (GLenum, "pname"), (GLfloat, "param")]),
     DllFunction(Void, "glTexEnvfv", [(GLenum, "target"), (GLenum, "pname"), (Pointer(Const(GLfloat)), "params")]),
     DllFunction(Void, "glTexEnvi", [(GLenum, "target"), (GLenum, "pname"), (GLint, "param")]),
@@ -399,7 +399,7 @@ libgl.functions += [
     DllFunction(Void, "glMinmax", [(GLenum, "target"), (GLenum, "internalformat"), (GLboolean, "sink")]),
     DllFunction(Void, "glResetHistogram", [(GLenum, "target")]),
     DllFunction(Void, "glResetMinmax", [(GLenum, "target")]),
-    DllFunction(Void, "glTexImage3D", [(GLenum, "target"), (GLint, "level"), (GLint, "internalformat"), (GLsizei, "width"), (GLsizei, "height"), (GLsizei, "depth"), (GLint, "border"), (GLenum, "format"), (GLenum, "type"), (Pointer(Const(GLvoid)), "pixels")]),
+    DllFunction(Void, "glTexImage3D", [(GLenum, "target"), (GLint, "level"), (GLint, "internalformat"), (GLsizei, "width"), (GLsizei, "height"), (GLsizei, "depth"), (GLint, "border"), (GLenum, "format"), (GLenum, "type"), (Blob(Const(GLvoid), "__gl_image_size(format, type, width, height, depth, border)"), "pixels")]),
     DllFunction(Void, "glTexSubImage3D", [(GLenum, "target"), (GLint, "level"), (GLint, "xoffset"), (GLint, "yoffset"), (GLint, "zoffset"), (GLsizei, "width"), (GLsizei, "height"), (GLsizei, "depth"), (GLenum, "format"), (GLenum, "type"), (Pointer(Const(GLvoid)), "pixels")]),
     DllFunction(Void, "glCopyTexSubImage3D", [(GLenum, "target"), (GLint, "level"), (GLint, "xoffset"), (GLint, "yoffset"), (GLint, "zoffset"), (GLint, "x"), (GLint, "y"), (GLsizei, "width"), (GLsizei, "height")]),
     DllFunction(Void, "glActiveTextureARB", [(GLenum, "texture")]),
@@ -868,6 +868,7 @@ if __name__ == '__main__':
     print '#include <GL/glxext.h>'
     print
     print '#include "log.hpp"'
+    print '#include "glhelpers.hpp"'
     print
     print 'extern "C" {'
     print
diff --git a/log.cpp b/log.cpp
index a78ba53..5ffc372 100644 (file)
--- a/log.cpp
+++ b/log.cpp
@@ -79,7 +79,7 @@ static void _Open(const char *szName, const char *szExtension) {
    g_gzFile = gzopen(szFileName, "wb");
 }
 
-static inline void Write(const char *sBuffer, size_t dwBytesToWrite) {
+static inline void Write(const void *sBuffer, size_t dwBytesToWrite) {
    if(g_gzFile == NULL)
       return;
    
@@ -243,7 +243,6 @@ void LiteralString(const char *str) {
 }
 
 void LiteralWString(const wchar_t *str) {
-
    if (!str) {
       LiteralNull();
       return;
@@ -252,6 +251,18 @@ void LiteralWString(const wchar_t *str) {
    WriteString("<wide-string>");
 }
    
+void LiteralBlob(const void *data, size_t size) {
+   if (!data) {
+      LiteralNull();
+      return;
+   }
+   WriteByte(Trace::TYPE_BLOB);
+   WriteUInt(size);
+   if (size) {
+      Write(data, size);
+   }
+}
+
 void LiteralNamedConstant(const char *name, long long value) {
    WriteByte(Trace::TYPE_CONST);
    WriteString(name);
diff --git a/log.hpp b/log.hpp
index fa1f91e..1652965 100644 (file)
--- a/log.hpp
+++ b/log.hpp
@@ -65,6 +65,7 @@ namespace Log {
     void LiteralFloat(double value);
     void LiteralString(const char *str);
     void LiteralWString(const wchar_t *str);
+    void LiteralBlob(const void *data, size_t size);
     void LiteralNamedConstant(const char *name, long long value);
     void LiteralNull(void);
     void LiteralOpaque(void);
index b832587..be2293d 100644 (file)
@@ -62,6 +62,10 @@ void Array::visit(Visitor &visitor) {
    visitor.visit(this);
 }
 
+void Blob::visit(Visitor &visitor) {
+   visitor.visit(this);
+}
+
 
 class Dumper : public Visitor
 {
@@ -109,6 +113,10 @@ public:
       }
       os << "}";
    }
+   
+   void visit(Blob *blob) {
+      os << "... " << blob->size;
+   }
 };
 
 
@@ -167,6 +175,12 @@ const Value & Value::operator[](size_t index) const {
     return void_;
 }
 
+Value::operator void *(void) const {
+   const Blob *blob = dynamic_cast<const Blob *>(unwrap(this));
+   assert(blob);
+   return blob->buf;
+}
+
 Value & Call::arg(const char *name) {
    for (std::list<Arg>::iterator it = args.begin(); it != args.end(); ++it) {
       if (it->first == name) {
index 26a378d..8089880 100644 (file)
@@ -52,6 +52,7 @@ public:
    operator signed long long (void) const;
    operator unsigned long long (void) const;
    operator double (void) const;
+   operator void * (void) const;
 
    inline operator signed char (void) const { 
       return static_cast<signed long long>(*this);
@@ -178,6 +179,25 @@ public:
 };
 
 
+class Blob : public Value
+{
+public:
+   Blob(size_t _size) {
+       size = size;
+       buf = new char[_size];
+   }
+
+   ~Blob() {
+       delete [] buf;
+   }
+
+   void visit(Visitor &visitor);
+
+   size_t size;
+   char *buf;
+};
+
+
 class Visitor
 {
 public:
@@ -189,6 +209,7 @@ public:
    virtual void visit(String *) {assert(0);}
    virtual void visit(Const *) {assert(0);}
    virtual void visit(Array *) {assert(0);}
+   virtual void visit(Blob *) {assert(0);}
 };
 
 
index 221957b..674ee8e 100644 (file)
@@ -89,8 +89,8 @@ public:
             call.ret = parse_value();
             break;
          default:
-            assert(0);
             std::cerr << "error: unknown call detail " << c << "\n";
+            assert(0);
             break;
          }
       } while(true);
@@ -129,6 +129,8 @@ public:
          return parse_bitmask();
       case Trace::TYPE_ARRAY:
          return parse_array();
+      case Trace::TYPE_BLOB:
+         return parse_blob();
       case Trace::TYPE_POINTER:
          return parse_pointer();
       case Trace::TYPE_VOID:
@@ -203,7 +205,7 @@ done:
       return new UInt(value);
    }
 
-   Value *parse_array() {
+   Value *parse_array(void) {
       size_t len = read_uint();
       Array *array = new Array(len);
       for (size_t i = 0; i < len; ++i) {
@@ -212,6 +214,15 @@ done:
       return array;
    }
    
+   Value *parse_blob(void) {
+      size_t size = read_uint();
+      Blob *blob = new Blob(size);
+      if (size) {
+          gzread(file, blob->buf, size);
+      }
+      return blob;
+   }
+   
    Value *parse_pointer() {
       unsigned long long addr;
       Value *value;