From 885f265065244d05fd158d71d27b6fbaba5a2212 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Jos=C3=A9=20Fonseca?= Date: Sat, 20 Nov 2010 11:22:25 +0000 Subject: [PATCH] Support glTexImage through blobs. --- base.py | 23 +++++++++++++++++- glhelpers.hpp | 63 ++++++++++++++++++++++++++++++++++++++++++++++++ glretrace.py | 3 +++ glx.py | 7 +++--- log.cpp | 15 ++++++++++-- log.hpp | 1 + trace_model.cpp | 14 +++++++++++ trace_model.hpp | 21 ++++++++++++++++ trace_parser.hpp | 15 ++++++++++-- 9 files changed, 154 insertions(+), 8 deletions(-) create mode 100644 glhelpers.hpp diff --git a/base.py b/base.py index 2f2b1d0..c6be245 100644 --- 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 index 0000000..757c334 --- /dev/null +++ b/glhelpers.hpp @@ -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 + +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_ */ diff --git a/glretrace.py b/glretrace.py index a689cc1..d8a3861 100644 --- a/glretrace.py +++ b/glretrace.py @@ -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 --- 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 ' 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 --- 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(""); } +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 --- 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); diff --git a/trace_model.cpp b/trace_model.cpp index b832587..be2293d 100644 --- a/trace_model.cpp +++ b/trace_model.cpp @@ -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(unwrap(this)); + assert(blob); + return blob->buf; +} + Value & Call::arg(const char *name) { for (std::list::iterator it = args.begin(); it != args.end(); ++it) { if (it->first == name) { diff --git a/trace_model.hpp b/trace_model.hpp index 26a378d..8089880 100644 --- a/trace_model.hpp +++ b/trace_model.hpp @@ -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(*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);} }; diff --git a/trace_parser.hpp b/trace_parser.hpp index 221957b..674ee8e 100644 --- a/trace_parser.hpp +++ b/trace_parser.hpp @@ -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; -- 2.45.2