Ejemplo n.º 1
0
    def dump_arg_instance(self, function, arg):
        if function.name in self.draw_function_names and arg.name == 'indices':
            print '    GLint __element_array_buffer = 0;'
            print '    __glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &__element_array_buffer);'
            print '    if (!__element_array_buffer) {'
            print '        Trace::LiteralBlob((const void *)%s, count*__gl_type_size(type));' % (arg.name)
            print '    } else {'
            print '        Trace::LiteralOpaque((const void *)%s);' % (arg.name)
            print '    }'
            return

        # Several GL state functions take GLenum symbolic names as
        # integer/floats; so dump the symbolic name whenever possible
        if arg.type in (glapi.GLint, glapi.GLfloat) and arg.name == 'param':
            assert arg.index > 0
            assert function.args[arg.index - 1].name == 'pname'
            assert function.args[arg.index - 1].type == glapi.GLenum
            print '    if (is_symbolic_pname(pname) && is_symbolic_param(%s)) {' % arg.name
            dump_instance(glapi.GLenum, arg.name)
            print '    } else {'
            Tracer.dump_arg_instance(self, function, arg)
            print '    }'
            return

        Tracer.dump_arg_instance(self, function, arg)
Ejemplo n.º 2
0
    def dump_arg_instance(self, function, arg):
        if function.name in self.draw_function_names and arg.name == 'indices':
            print '    GLint __element_array_buffer = 0;'
            print '    __glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &__element_array_buffer);'
            print '    if (!__element_array_buffer) {'
            print '        Trace::LiteralBlob((const void *)%s, count*__gl_type_size(type));' % (arg.name)
            print '    } else {'
            print '        Trace::LiteralOpaque((const void *)%s);' % (arg.name)
            print '    }'
            return

        # Several GL state functions take GLenum symbolic names as
        # integer/floats; so dump the symbolic name whenever possible
        if arg.type in (glapi.GLint, glapi.GLfloat) and arg.name == 'param':
            assert arg.index > 0
            assert function.args[arg.index - 1].name == 'pname'
            assert function.args[arg.index - 1].type == glapi.GLenum
            print '    if (is_symbolic_pname(pname) && is_symbolic_param(%s)) {' % arg.name
            dump_instance(glapi.GLenum, arg.name)
            print '    } else {'
            Tracer.dump_arg_instance(self, function, arg)
            print '    }'
            return

        Tracer.dump_arg_instance(self, function, arg)
Ejemplo n.º 3
0
 def fake_call(self, function, args):
     print '            unsigned __fake_call = Trace::BeginEnter(__%s_sig);' % (function.name,)
     for arg, instance in zip(function.args, args):
         assert not arg.output
         print '            Trace::BeginArg(%u);' % (arg.index,)
         dump_instance(arg.type, instance)
         print '            Trace::EndArg();'
     print '            Trace::EndEnter();'
     print '            Trace::BeginLeave(__fake_call);'
     print '            Trace::EndLeave();'
Ejemplo n.º 4
0
 def fake_call(self, function, args):
     print '            unsigned __fake_call = Trace::BeginEnter(__%s_sig);' % (function.name,)
     for arg, instance in zip(function.args, args):
         assert not arg.output
         print '            Trace::BeginArg(%u);' % (arg.index,)
         dump_instance(arg.type, instance)
         print '            Trace::EndArg();'
     print '            Trace::EndEnter();'
     print '            Trace::BeginLeave(__fake_call);'
     print '            Trace::EndLeave();'
Ejemplo n.º 5
0
    def dump_arg_instance(self, function, arg):
        if function.name in self.draw_function_names and arg.name == 'indices':
            print '    GLint __element_array_buffer = 0;'
            print '    __glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &__element_array_buffer);'
            print '    if (!__element_array_buffer) {'
            if isinstance(arg.type, stdapi.Array):
                print '        trace::localWriter.beginArray(%s);' % arg.type.length
                print '        for(GLsizei i = 0; i < %s; ++i) {' % arg.type.length
                print '            trace::localWriter.beginElement();'
                print '            trace::localWriter.writeBlob(%s[i], count[i]*__gl_type_size(type));' % (arg.name)
                print '            trace::localWriter.endElement();'
                print '        }'
                print '        trace::localWriter.endArray();'
            else:
                print '        trace::localWriter.writeBlob(%s, count*__gl_type_size(type));' % (arg.name)
            print '    } else {'
            Tracer.dump_arg_instance(self, function, arg)
            print '    }'
            return

        # Recognize offsets instead of blobs when a PBO is bound
        if function.name in self.unpack_function_names \
           and (isinstance(arg.type, stdapi.Blob) \
                or (isinstance(arg.type, stdapi.Const) \
                    and isinstance(arg.type.type, stdapi.Blob))):
            print '    {'
            print '        tracer_context *ctx = __get_context();'
            print '        GLint __unpack_buffer = 0;'
            print '        if (ctx->profile == PROFILE_COMPAT)'
            print '            __glGetIntegerv(GL_PIXEL_UNPACK_BUFFER_BINDING, &__unpack_buffer);'
            print '        if (__unpack_buffer) {'
            print '            trace::localWriter.writeOpaque(%s);' % arg.name
            print '        } else {'
            Tracer.dump_arg_instance(self, function, arg)
            print '        }'
            print '    }'
            return

        # Several GL state functions take GLenum symbolic names as
        # integer/floats; so dump the symbolic name whenever possible
        if function.name.startswith('gl') \
           and arg.type in (glapi.GLint, glapi.GLfloat, glapi.GLdouble) \
           and arg.name == 'param':
            assert arg.index > 0
            assert function.args[arg.index - 1].name == 'pname'
            assert function.args[arg.index - 1].type == glapi.GLenum
            print '    if (is_symbolic_pname(pname) && is_symbolic_param(%s)) {' % arg.name
            dump_instance(glapi.GLenum, arg.name)
            print '    } else {'
            Tracer.dump_arg_instance(self, function, arg)
            print '    }'
            return

        Tracer.dump_arg_instance(self, function, arg)
Ejemplo n.º 6
0
    def footer(self, api):
        Tracer.footer(self, api)

        # A simple state tracker to track the pointer values
        # update the state
        print 'static void __trace_user_arrays(GLuint maxindex)'
        print '{'

        for camelcase_name, uppercase_name in self.arrays:
            function_name = 'gl%sPointer' % camelcase_name
            enable_name = 'GL_%s_ARRAY' % uppercase_name
            binding_name = 'GL_%s_ARRAY_BUFFER_BINDING' % uppercase_name
            function = api.get_function_by_name(function_name)

            print '    // %s' % function.name
            self.array_trace_prolog(api, uppercase_name)
            self.array_prolog(api, uppercase_name)
            print '    if (__glIsEnabled(%s)) {' % enable_name
            print '        GLint __binding = 0;'
            print '        __glGetIntegerv(%s, &__binding);' % binding_name
            print '        if (!__binding) {'

            # Get the arguments via glGet*
            for arg in function.args:
                arg_get_enum = 'GL_%s_ARRAY_%s' % (uppercase_name,
                                                   arg.name.upper())
                arg_get_function, arg_type = TypeGetter().visit(arg.type)
                print '            %s %s = 0;' % (arg_type, arg.name)
                print '            __%s(%s, &%s);' % (arg_get_function,
                                                      arg_get_enum, arg.name)

            arg_names = ', '.join([arg.name for arg in function.args[:-1]])
            print '            size_t __size = __%s_size(%s, maxindex);' % (
                function.name, arg_names)

            # Emit a fake function
            self.array_trace_intermezzo(api, uppercase_name)
            print '            unsigned __call = Trace::BeginEnter(__%s_sig);' % (
                function.name, )
            for arg in function.args:
                assert not arg.output
                print '            Trace::BeginArg(%u);' % (arg.index, )
                if arg.name != 'pointer':
                    dump_instance(arg.type, arg.name)
                else:
                    print '            Trace::LiteralBlob((const void *)%s, __size);' % (
                        arg.name)
                print '            Trace::EndArg();'

            print '            Trace::EndEnter();'
            print '            Trace::BeginLeave(__call);'
            print '            Trace::EndLeave();'
            print '        }'
            print '    }'
            self.array_epilog(api, uppercase_name)
            self.array_trace_epilog(api, uppercase_name)
            print

        # Samething, but for glVertexAttribPointer
        print '    // glVertexAttribPointer'
        print '    GLint __max_vertex_attribs = 0;'
        print '    __glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &__max_vertex_attribs);'
        print '    for (GLint index = 0; index < __max_vertex_attribs; ++index) {'
        print '        GLint __enabled = 0;'
        print '        __glGetVertexAttribiv(index, GL_VERTEX_ATTRIB_ARRAY_ENABLED, &__enabled);'
        print '        if (__enabled) {'
        print '            GLint __binding = 0;'
        print '            __glGetVertexAttribiv(index, GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING, &__binding);'
        print '            if (!__binding) {'

        function = api.get_function_by_name('glVertexAttribPointer')

        # Get the arguments via glGet*
        for arg in function.args[1:]:
            arg_get_enum = 'GL_VERTEX_ATTRIB_ARRAY_%s' % (arg.name.upper(), )
            arg_get_function, arg_type = TypeGetter('glGetVertexAttrib',
                                                    False).visit(arg.type)
            print '                %s %s = 0;' % (arg_type, arg.name)
            print '                __%s(index, %s, &%s);' % (
                arg_get_function, arg_get_enum, arg.name)

        arg_names = ', '.join([arg.name for arg in function.args[1:-1]])
        print '                size_t __size = __%s_size(%s, maxindex);' % (
            function.name, arg_names)

        # Emit a fake function
        print '                unsigned __call = Trace::BeginEnter(__%s_sig);' % (
            function.name, )
        for arg in function.args:
            assert not arg.output
            print '                Trace::BeginArg(%u);' % (arg.index, )
            if arg.name != 'pointer':
                dump_instance(arg.type, arg.name)
            else:
                print '                Trace::LiteralBlob((const void *)%s, __size);' % (
                    arg.name)
            print '                Trace::EndArg();'

        print '                Trace::EndEnter();'
        print '                Trace::BeginLeave(__call);'
        print '                Trace::EndLeave();'
        print '            }'
        print '        }'
        print '    }'
        print

        print '}'
        print
Ejemplo n.º 7
0
    def trace_function_impl_body(self, function):
        # Defer tracing of user array pointers...
        if function.name in self.array_pointer_function_names:
            print '    GLint __array_buffer = 0;'
            print '    __glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &__array_buffer);'
            print '    if (!__array_buffer) {'
            print '        __user_arrays = true;'
            self.dispatch_function(function)

            # And also break down glInterleavedArrays into the individual calls
            if function.name == 'glInterleavedArrays':
                print

                # Initialize the enable flags
                for camelcase_name, uppercase_name in self.arrays:
                    flag_name = '__' + uppercase_name.lower()
                    print '        GLboolean %s = GL_FALSE;' % flag_name
                print

                # Switch for the interleaved formats
                print '        switch (format) {'
                for format in self.interleaved_formats:
                    print '            case %s:' % format
                    for camelcase_name, uppercase_name in self.arrays:
                        flag_name = '__' + uppercase_name.lower()
                        if format.find('_' + uppercase_name[0]) >= 0:
                            print '                %s = GL_TRUE;' % flag_name
                    print '                break;'
                print '            default:'
                print '               return;'
                print '        }'
                print

                # Emit fake glEnableClientState/glDisableClientState flags
                for camelcase_name, uppercase_name in self.arrays:
                    flag_name = '__' + uppercase_name.lower()
                    enable_name = 'GL_%s_ARRAY' % uppercase_name

                    # Emit a fake function
                    print '        {'
                    print '            static const Trace::FunctionSig &__sig = %s ? __glEnableClientState_sig : __glDisableClientState_sig;' % flag_name
                    print '            unsigned __call = Trace::BeginEnter(__sig);'
                    print '            Trace::BeginArg(0);'
                    dump_instance(glapi.GLenum, enable_name)
                    print '            Trace::EndArg();'
                    print '            Trace::EndEnter();'
                    print '            Trace::BeginLeave(__call);'
                    print '            Trace::EndLeave();'
                    print '        }'

            print '        return;'
            print '    }'

        # ... to the draw calls
        if function.name in self.draw_function_names:
            print '    if (__need_user_arrays()) {'
            arg_names = ', '.join([arg.name for arg in function.args[1:]])
            print '        GLuint maxindex = __%s_maxindex(%s);' % (
                function.name, arg_names)
            print '        __trace_user_arrays(maxindex);'
            print '    }'

        # Emit a fake memcpy on buffer uploads
        if function.name in (
                'glUnmapBuffer',
                'glUnmapBufferARB',
        ):
            print '    struct buffer_mapping *mapping = get_buffer_mapping(target);'
            print '    if (mapping && mapping->write && !mapping->explicit_flush) {'
            self.emit_memcpy('mapping->map', 'mapping->map', 'mapping->length')
            print '    }'
        if function.name in ('glFlushMappedBufferRange',
                             'glFlushMappedBufferRangeAPPLE'):
            # TODO: avoid copying [0, offset] bytes
            print '    struct buffer_mapping *mapping = get_buffer_mapping(target);'
            print '    if (mapping) {'
            if function.name.endswith('APPLE'):
                print '        GLsizeiptr length = size;'
                print '        mapping->explicit_flush = true;'
            print '        //assert(offset + length <= mapping->length);'
            self.emit_memcpy('mapping->map', 'mapping->map', 'offset + length')
            print '    }'
        # FIXME: glFlushMappedNamedBufferRangeEXT

        # Don't leave vertex attrib locations to chance.  Instead emit fake
        # glBindAttribLocation calls to ensure that the same locations will be
        # used when retracing.  Trying to remap locations after the fact would
        # be an herculian task given that vertex attrib locations appear in
        # many entry-points, including non-shader related ones.
        if function.name == 'glLinkProgram':
            Tracer.dispatch_function(self, function)
            print '    GLint active_attributes = 0;'
            print '    __glGetProgramiv(program, GL_ACTIVE_ATTRIBUTES, &active_attributes);'
            print '    for (GLuint attrib = 0; attrib < active_attributes; ++attrib) {'
            print '        GLint size = 0;'
            print '        GLenum type = 0;'
            print '        GLchar name[256];'
            # TODO: Use ACTIVE_ATTRIBUTE_MAX_LENGTH instead of 256
            print '        __glGetActiveAttrib(program, attrib, sizeof name, NULL, &size, &type, name);'
            print '        GLint location = __glGetAttribLocation(program, name);'
            print '        if (location >= 0) {'
            bind_function = glapi.glapi.get_function_by_name(
                'glBindAttribLocation')
            self.fake_call(bind_function, ['program', 'location', 'name'])
            print '        }'
            print '    }'
        if function.name == 'glLinkProgramARB':
            Tracer.dispatch_function(self, function)
            print '    GLint active_attributes = 0;'
            print '    __glGetObjectParameterivARB(programObj, GL_OBJECT_ACTIVE_ATTRIBUTES_ARB, &active_attributes);'
            print '    for (GLuint attrib = 0; attrib < active_attributes; ++attrib) {'
            print '        GLint size = 0;'
            print '        GLenum type = 0;'
            print '        GLcharARB name[256];'
            # TODO: Use ACTIVE_ATTRIBUTE_MAX_LENGTH instead of 256
            print '        __glGetActiveAttribARB(programObj, attrib, sizeof name, NULL, &size, &type, name);'
            print '        GLint location = __glGetAttribLocationARB(programObj, name);'
            print '        if (location >= 0) {'
            bind_function = glapi.glapi.get_function_by_name(
                'glBindAttribLocationARB')
            self.fake_call(bind_function, ['programObj', 'location', 'name'])
            print '        }'
            print '    }'

        Tracer.trace_function_impl_body(self, function)
Ejemplo n.º 8
0
    def trace_function_impl_body(self, function):
        # Defer tracing of user array pointers...
        if function.name in self.array_pointer_function_names:
            print '    GLint __array_buffer = 0;'
            print '    __glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &__array_buffer);'
            print '    if (!__array_buffer) {'
            print '        __user_arrays = true;'
            self.dispatch_function(function)
            print '        return;'
            print '    }'

        # ... to the draw calls
        if function.name in self.draw_function_names:
            print '    if (__need_user_arrays()) {'
            arg_names = ', '.join([arg.name for arg in function.args[1:]])
            print '        GLuint maxindex = __%s_maxindex(%s);' % (function.name, arg_names)
            print '        __trace_user_arrays(maxindex);'
            print '    }'
        
        # And also break down glInterleavedArrays into the individual calls
        if function.name == 'glInterleavedArrays':
            print '    GLint __array_buffer = 0;'
            print '    __glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &__array_buffer);'
            print '    if (!__array_buffer) {'
            print '        __user_arrays = true;'
            self.dispatch_function(function)
            print

            # Initialize the enable flags
            for camelcase_name, uppercase_name in self.arrays:
                flag_name = '__' + uppercase_name.lower()
                print '        GLboolean %s = GL_FALSE;' % flag_name
            print

            # Swicth for the interleaved formats
            print '        switch (format) {'
            for format in self.interleaved_formats:
                print '            case %s:' % format
                for camelcase_name, uppercase_name in self.arrays:
                    flag_name = '__' + uppercase_name.lower()
                    if format.find('_' + uppercase_name[0]) >= 0:
                        print '                %s = GL_TRUE;' % flag_name
                print '                break;'
            print '            default:'
            print '               return;'
            print '        }'
            print

            # Emit fake glEnableClientState/glDisableClientState flags
            for camelcase_name, uppercase_name in self.arrays:
                flag_name = '__' + uppercase_name.lower()
                enable_name = 'GL_%s_ARRAY' % uppercase_name

                # Emit a fake function
                print '        {'
                print '            static const Trace::FunctionSig &__sig = %s ? __glEnableClientState_sig : __glDisableClientState_sig;' % flag_name
                print '            unsigned __call = Trace::BeginEnter(__sig);'
                print '            Trace::BeginArg(0);'
                dump_instance(glapi.GLenum, enable_name)
                print '            Trace::EndArg();'
                print '            Trace::EndEnter();'
                print '            Trace::BeginLeave(__call);'
                print '            Trace::EndLeave();'
                print '        }'

            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)
Ejemplo n.º 9
0
    def footer(self, api):
        Tracer.footer(self, api)

        # A simple state tracker to track the pointer values
        # update the state
        print 'static void __trace_user_arrays(GLuint maxindex)'
        print '{'

        for camelcase_name, uppercase_name in self.arrays:
            function_name = 'gl%sPointer' % camelcase_name
            enable_name = 'GL_%s_ARRAY' % uppercase_name
            binding_name = 'GL_%s_ARRAY_BUFFER_BINDING' % uppercase_name
            function = api.get_function_by_name(function_name)

            print '    // %s' % function.name
            self.array_trace_prolog(api, uppercase_name)
            self.array_prolog(api, uppercase_name)
            print '    if (__glIsEnabled(%s)) {' % enable_name
            print '        GLint __binding = 0;'
            print '        __glGetIntegerv(%s, &__binding);' % binding_name
            print '        if (!__binding) {'

            # Get the arguments via glGet*
            for arg in function.args:
                arg_get_enum = 'GL_%s_ARRAY_%s' % (uppercase_name, arg.name.upper())
                arg_get_function, arg_type = TypeGetter().visit(arg.type)
                print '            %s %s = 0;' % (arg_type, arg.name)
                print '            __%s(%s, &%s);' % (arg_get_function, arg_get_enum, arg.name)
            
            arg_names = ', '.join([arg.name for arg in function.args[:-1]])
            print '            size_t __size = __%s_size(%s, maxindex);' % (function.name, arg_names)

            # Emit a fake function
            self.array_trace_intermezzo(api, uppercase_name)
            print '            unsigned __call = Trace::BeginEnter(__%s_sig);' % (function.name,)
            for arg in function.args:
                assert not arg.output
                print '            Trace::BeginArg(%u);' % (arg.index,)
                if arg.name != 'pointer':
                    dump_instance(arg.type, arg.name)
                else:
                    print '            Trace::LiteralBlob((const void *)%s, __size);' % (arg.name)
                print '            Trace::EndArg();'
            
            print '            Trace::EndEnter();'
            print '            Trace::BeginLeave(__call);'
            print '            Trace::EndLeave();'
            print '        }'
            print '    }'
            self.array_epilog(api, uppercase_name)
            self.array_trace_epilog(api, uppercase_name)
            print

        # Samething, but for glVertexAttribPointer
        print '    // glVertexAttribPointer'
        print '    GLint __max_vertex_attribs = 0;'
        print '    __glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &__max_vertex_attribs);'
        print '    for (GLint index = 0; index < __max_vertex_attribs; ++index) {'
        print '        GLint __enabled = 0;'
        print '        __glGetVertexAttribiv(index, GL_VERTEX_ATTRIB_ARRAY_ENABLED, &__enabled);'
        print '        if (__enabled) {'
        print '            GLint __binding = 0;'
        print '            __glGetVertexAttribiv(index, GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING, &__binding);'
        print '            if (!__binding) {'

        function = api.get_function_by_name('glVertexAttribPointer')

        # Get the arguments via glGet*
        for arg in function.args[1:]:
            arg_get_enum = 'GL_VERTEX_ATTRIB_ARRAY_%s' % (arg.name.upper(),)
            arg_get_function, arg_type = TypeGetter('glGetVertexAttrib', False).visit(arg.type)
            print '                %s %s = 0;' % (arg_type, arg.name)
            print '                __%s(index, %s, &%s);' % (arg_get_function, arg_get_enum, arg.name)
        
        arg_names = ', '.join([arg.name for arg in function.args[1:-1]])
        print '                size_t __size = __%s_size(%s, maxindex);' % (function.name, arg_names)

        # Emit a fake function
        print '                unsigned __call = Trace::BeginEnter(__%s_sig);' % (function.name,)
        for arg in function.args:
            assert not arg.output
            print '                Trace::BeginArg(%u);' % (arg.index,)
            if arg.name != 'pointer':
                dump_instance(arg.type, arg.name)
            else:
                print '                Trace::LiteralBlob((const void *)%s, __size);' % (arg.name)
            print '                Trace::EndArg();'
        
        print '                Trace::EndEnter();'
        print '                Trace::BeginLeave(__call);'
        print '                Trace::EndLeave();'
        print '            }'
        print '        }'
        print '    }'
        print

        print '}'
        print
Ejemplo n.º 10
0
    def trace_function_impl_body(self, function):
        # Defer tracing of user array pointers...
        if function.name in self.array_pointer_function_names:
            print '    GLint __array_buffer = 0;'
            print '    __glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &__array_buffer);'
            print '    if (!__array_buffer) {'
            print '        __user_arrays = true;'
            self.dispatch_function(function)

            # And also break down glInterleavedArrays into the individual calls
            if function.name == 'glInterleavedArrays':
                print

                # Initialize the enable flags
                for camelcase_name, uppercase_name in self.arrays:
                    flag_name = '__' + uppercase_name.lower()
                    print '        GLboolean %s = GL_FALSE;' % flag_name
                print

                # Switch for the interleaved formats
                print '        switch (format) {'
                for format in self.interleaved_formats:
                    print '            case %s:' % format
                    for camelcase_name, uppercase_name in self.arrays:
                        flag_name = '__' + uppercase_name.lower()
                        if format.find('_' + uppercase_name[0]) >= 0:
                            print '                %s = GL_TRUE;' % flag_name
                    print '                break;'
                print '            default:'
                print '               return;'
                print '        }'
                print

                # Emit fake glEnableClientState/glDisableClientState flags
                for camelcase_name, uppercase_name in self.arrays:
                    flag_name = '__' + uppercase_name.lower()
                    enable_name = 'GL_%s_ARRAY' % uppercase_name

                    # Emit a fake function
                    print '        {'
                    print '            static const Trace::FunctionSig &__sig = %s ? __glEnableClientState_sig : __glDisableClientState_sig;' % flag_name
                    print '            unsigned __call = Trace::BeginEnter(__sig);'
                    print '            Trace::BeginArg(0);'
                    dump_instance(glapi.GLenum, enable_name)
                    print '            Trace::EndArg();'
                    print '            Trace::EndEnter();'
                    print '            Trace::BeginLeave(__call);'
                    print '            Trace::EndLeave();'
                    print '        }'

            print '        return;'
            print '    }'

        # ... to the draw calls
        if function.name in self.draw_function_names:
            print '    if (__need_user_arrays()) {'
            arg_names = ', '.join([arg.name for arg in function.args[1:]])
            print '        GLuint maxindex = __%s_maxindex(%s);' % (function.name, arg_names)
            print '        __trace_user_arrays(maxindex);'
            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)
Ejemplo n.º 11
0
    def state_tracker_impl(self, api):
        # A simple state tracker to track the pointer values

        # update the state
        print "static void __trace_user_arrays(GLuint maxindex)"
        print "{"

        for camelcase_name, uppercase_name in self.arrays:
            function_name = "gl%sPointer" % camelcase_name
            enable_name = "GL_%s_ARRAY" % uppercase_name
            binding_name = "GL_%s_ARRAY_BUFFER_BINDING" % uppercase_name
            function = api.get_function_by_name(function_name)

            print "    // %s" % function.name
            self.array_trace_prolog(api, uppercase_name)
            self.array_prolog(api, uppercase_name)
            print "    if (__glIsEnabled(%s)) {" % enable_name
            print "        GLint __binding = 0;"
            print "        __glGetIntegerv(%s, &__binding);" % binding_name
            print "        if (!__binding) {"

            # Get the arguments via glGet*
            for arg in function.args:
                arg_get_enum = "GL_%s_ARRAY_%s" % (uppercase_name, arg.name.upper())
                arg_get_function, arg_type = TypeGetter().visit(arg.type)
                print "            %s %s = 0;" % (arg_type, arg.name)
                print "            __%s(%s, &%s);" % (arg_get_function, arg_get_enum, arg.name)

            arg_names = ", ".join([arg.name for arg in function.args[:-1]])
            print "            size_t __size = __%s_size(%s, maxindex);" % (function.name, arg_names)

            # Emit a fake function
            self.array_trace_intermezzo(api, uppercase_name)
            print "            unsigned __call = Trace::BeginEnter(__%s_sig);" % (function.name,)
            for arg in function.args:
                assert not arg.output
                print "            Trace::BeginArg(%u);" % (arg.index,)
                if arg.name != "pointer":
                    dump_instance(arg.type, arg.name)
                else:
                    print "            Trace::LiteralBlob((const void *)%s, __size);" % (arg.name)
                print "            Trace::EndArg();"

            print "            Trace::EndEnter();"
            print "            Trace::BeginLeave(__call);"
            print "            Trace::EndLeave();"
            print "        }"
            print "    }"
            self.array_epilog(api, uppercase_name)
            self.array_trace_epilog(api, uppercase_name)
            print

        # Samething, but for glVertexAttribPointer
        print "    // glVertexAttribPointer"
        print "    GLint __max_vertex_attribs = 0;"
        print "    __glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &__max_vertex_attribs);"
        print "    for (GLint index = 0; index < __max_vertex_attribs; ++index) {"
        print "        GLint __enabled = 0;"
        print "        __glGetVertexAttribiv(index, GL_VERTEX_ATTRIB_ARRAY_ENABLED, &__enabled);"
        print "        if (__enabled) {"
        print "            GLint __binding = 0;"
        print "            __glGetVertexAttribiv(index, GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING, &__binding);"
        print "            if (!__binding) {"

        function = api.get_function_by_name("glVertexAttribPointer")

        # Get the arguments via glGet*
        for arg in function.args[1:]:
            arg_get_enum = "GL_VERTEX_ATTRIB_ARRAY_%s" % (arg.name.upper(),)
            arg_get_function, arg_type = TypeGetter("glGetVertexAttrib", False).visit(arg.type)
            print "                %s %s = 0;" % (arg_type, arg.name)
            print "                __%s(index, %s, &%s);" % (arg_get_function, arg_get_enum, arg.name)

        arg_names = ", ".join([arg.name for arg in function.args[1:-1]])
        print "                size_t __size = __%s_size(%s, maxindex);" % (function.name, arg_names)

        # Emit a fake function
        print "                unsigned __call = Trace::BeginEnter(__%s_sig);" % (function.name,)
        for arg in function.args:
            assert not arg.output
            print "                Trace::BeginArg(%u);" % (arg.index,)
            if arg.name != "pointer":
                dump_instance(arg.type, arg.name)
            else:
                print "                Trace::LiteralBlob((const void *)%s, __size);" % (arg.name)
            print "                Trace::EndArg();"

        print "                Trace::EndEnter();"
        print "                Trace::BeginLeave(__call);"
        print "                Trace::EndLeave();"
        print "            }"
        print "        }"
        print "    }"
        print

        print "}"
        print
Ejemplo n.º 12
0
    def trace_function_impl_body(self, function):
        # Defer tracing of user array pointers...
        if function.name in self.array_pointer_function_names:
            print "    GLint __array_buffer = 0;"
            print "    __glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &__array_buffer);"
            print "    if (!__array_buffer) {"
            print "        __user_arrays = true;"
            self.dispatch_function(function)
            print "        return;"
            print "    }"

        # ... to the draw calls
        if function.name in self.draw_function_names:
            print "    if (__need_user_arrays()) {"
            arg_names = ", ".join([arg.name for arg in function.args[1:]])
            print "        GLuint maxindex = __%s_maxindex(%s);" % (function.name, arg_names)
            print "        __trace_user_arrays(maxindex);"
            print "    }"

        # And also break down glInterleavedArrays into the individual calls
        if function.name == "glInterleavedArrays":
            print "    GLint __array_buffer = 0;"
            print "    __glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &__array_buffer);"
            print "    if (!__array_buffer) {"
            print "        __user_arrays = true;"
            self.dispatch_function(function)
            print

            # Initialize the enable flags
            for camelcase_name, uppercase_name in self.arrays:
                flag_name = "__" + uppercase_name.lower()
                print "        GLboolean %s = GL_FALSE;" % flag_name
            print

            # Swicth for the interleaved formats
            print "        switch (format) {"
            for format in self.interleaved_formats:
                print "            case %s:" % format
                for camelcase_name, uppercase_name in self.arrays:
                    flag_name = "__" + uppercase_name.lower()
                    if format.find("_" + uppercase_name[0]) >= 0:
                        print "                %s = GL_TRUE;" % flag_name
                print "                break;"
            print "            default:"
            print "               return;"
            print "        }"
            print

            # Emit fake glEnableClientState/glDisableClientState flags
            for camelcase_name, uppercase_name in self.arrays:
                flag_name = "__" + uppercase_name.lower()
                enable_name = "GL_%s_ARRAY" % uppercase_name

                # Emit a fake function
                print "        {"
                print "            static const Trace::FunctionSig &__sig = %s ? __glEnableClientState_sig : __glDisableClientState_sig;" % flag_name
                print "            unsigned __call = Trace::BeginEnter(__sig);"
                print "            Trace::BeginArg(0);"
                dump_instance(glapi.GLenum, enable_name)
                print "            Trace::EndArg();"
                print "            Trace::EndEnter();"
                print "            Trace::BeginLeave(__call);"
                print "            Trace::EndLeave();"
                print "        }"

            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)
Ejemplo n.º 13
0
    def footer(self, api):
        Tracer.footer(self, api)

        # A simple state tracker to track the pointer values
        # update the state
        print 'static void __trace_user_arrays(GLuint maxindex)'
        print '{'
        print '    tracer_context *ctx = __get_context();'

        for camelcase_name, uppercase_name in self.arrays:
            # in which profile is the array available?
            profile_check = 'ctx->profile == PROFILE_COMPAT'
            if camelcase_name in self.arrays_es1:
                profile_check = '(' + profile_check + ' || ctx->profile == PROFILE_ES1)';

            function_name = 'gl%sPointer' % camelcase_name
            enable_name = 'GL_%s_ARRAY' % uppercase_name
            binding_name = 'GL_%s_ARRAY_BUFFER_BINDING' % uppercase_name
            function = api.get_function_by_name(function_name)

            print '    // %s' % function.prototype()
            print '  if (%s) {' % profile_check
            self.array_trace_prolog(api, uppercase_name)
            self.array_prolog(api, uppercase_name)
            print '    if (__glIsEnabled(%s)) {' % enable_name
            print '        GLint __binding = 0;'
            print '        __glGetIntegerv(%s, &__binding);' % binding_name
            print '        if (!__binding) {'

            # Get the arguments via glGet*
            for arg in function.args:
                arg_get_enum = 'GL_%s_ARRAY_%s' % (uppercase_name, arg.name.upper())
                arg_get_function, arg_type = TypeGetter().visit(arg.type)
                print '            %s %s = 0;' % (arg_type, arg.name)
                print '            __%s(%s, &%s);' % (arg_get_function, arg_get_enum, arg.name)
            
            arg_names = ', '.join([arg.name for arg in function.args[:-1]])
            print '            size_t __size = __%s_size(%s, maxindex);' % (function.name, arg_names)

            # Emit a fake function
            self.array_trace_intermezzo(api, uppercase_name)
            print '            unsigned __call = trace::localWriter.beginEnter(&__%s_sig);' % (function.name,)
            for arg in function.args:
                assert not arg.output
                print '            trace::localWriter.beginArg(%u);' % (arg.index,)
                if arg.name != 'pointer':
                    dump_instance(arg.type, arg.name)
                else:
                    print '            trace::localWriter.writeBlob((const void *)%s, __size);' % (arg.name)
                print '            trace::localWriter.endArg();'
            
            print '            trace::localWriter.endEnter();'
            print '            trace::localWriter.beginLeave(__call);'
            print '            trace::localWriter.endLeave();'
            print '        }'
            print '    }'
            self.array_epilog(api, uppercase_name)
            self.array_trace_epilog(api, uppercase_name)
            print '  }'
            print

        # Samething, but for glVertexAttribPointer*
        #
        # Some variants of glVertexAttribPointer alias conventional and generic attributes:
        # - glVertexAttribPointer: no
        # - glVertexAttribPointerARB: implementation dependent
        # - glVertexAttribPointerNV: yes
        #
        # This means that the implementations of these functions do not always
        # alias, and they need to be considered independently.
        #
        print '    // ES1 does not support generic vertex attributes'
        print '    if (ctx->profile == PROFILE_ES1)'
        print '        return;'
        print
        print '    vertex_attrib __vertex_attrib = __get_vertex_attrib();'
        print
        for suffix in ['', 'ARB', 'NV']:
            if suffix:
                SUFFIX = '_' + suffix
            else:
                SUFFIX = suffix
            function_name = 'glVertexAttribPointer' + suffix
            function = api.get_function_by_name(function_name)

            print '    // %s' % function.prototype()
            print '    if (__vertex_attrib == VERTEX_ATTRIB%s) {' % SUFFIX
            if suffix == 'NV':
                print '        GLint __max_vertex_attribs = 16;'
            else:
                print '        GLint __max_vertex_attribs = 0;'
                print '        __glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &__max_vertex_attribs);'
            print '        for (GLint index = 0; index < __max_vertex_attribs; ++index) {'
            print '            GLint __enabled = 0;'
            if suffix == 'NV':
                print '            __glGetIntegerv(GL_VERTEX_ATTRIB_ARRAY0_NV + index, &__enabled);'
            else:
                print '            __glGetVertexAttribiv%s(index, GL_VERTEX_ATTRIB_ARRAY_ENABLED%s, &__enabled);' % (suffix, SUFFIX)
            print '            if (__enabled) {'
            print '                GLint __binding = 0;'
            if suffix != 'NV':
                # It doesn't seem possible to use VBOs with NV_vertex_program.
                print '                __glGetVertexAttribiv%s(index, GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING%s, &__binding);' % (suffix, SUFFIX)
            print '                if (!__binding) {'

            # Get the arguments via glGet*
            for arg in function.args[1:]:
                if suffix == 'NV':
                    arg_get_enum = 'GL_ATTRIB_ARRAY_%s%s' % (arg.name.upper(), SUFFIX)
                else:
                    arg_get_enum = 'GL_VERTEX_ATTRIB_ARRAY_%s%s' % (arg.name.upper(), SUFFIX)
                arg_get_function, arg_type = TypeGetter('glGetVertexAttrib', False, suffix).visit(arg.type)
                print '                    %s %s = 0;' % (arg_type, arg.name)
                print '                    __%s(index, %s, &%s);' % (arg_get_function, arg_get_enum, arg.name)
            
            arg_names = ', '.join([arg.name for arg in function.args[1:-1]])
            print '                    size_t __size = __%s_size(%s, maxindex);' % (function.name, arg_names)

            # Emit a fake function
            print '                    unsigned __call = trace::localWriter.beginEnter(&__%s_sig);' % (function.name,)
            for arg in function.args:
                assert not arg.output
                print '                    trace::localWriter.beginArg(%u);' % (arg.index,)
                if arg.name != 'pointer':
                    dump_instance(arg.type, arg.name)
                else:
                    print '                    trace::localWriter.writeBlob((const void *)%s, __size);' % (arg.name)
                print '                    trace::localWriter.endArg();'
            
            print '                    trace::localWriter.endEnter();'
            print '                    trace::localWriter.beginLeave(__call);'
            print '                    trace::localWriter.endLeave();'
            print '                }'
            print '            }'
            print '        }'
            print '    }'
            print

        print '}'
        print
Ejemplo n.º 14
0
    def trace_function_impl_body(self, function):
        # Defer tracing of user array pointers...
        if function.name in self.array_pointer_function_names:
            print '    GLint __array_buffer = 0;'
            print '    __glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &__array_buffer);'
            print '    if (!__array_buffer) {'
            print '        tracer_context *ctx = __get_context();'
            print '        ctx->user_arrays = true;'
            if function.name == "glVertexAttribPointerARB":
                print '        ctx->user_arrays_arb = true;'
            if function.name == "glVertexAttribPointerNV":
                print '        ctx->user_arrays_nv = true;'
            self.dispatch_function(function)

            # And also break down glInterleavedArrays into the individual calls
            if function.name == 'glInterleavedArrays':
                print

                # Initialize the enable flags
                for camelcase_name, uppercase_name in self.arrays:
                    flag_name = '__' + uppercase_name.lower()
                    print '        GLboolean %s = GL_FALSE;' % flag_name
                print

                # Switch for the interleaved formats
                print '        switch (format) {'
                for format in self.interleaved_formats:
                    print '            case %s:' % format
                    for camelcase_name, uppercase_name in self.arrays:
                        flag_name = '__' + uppercase_name.lower()
                        if format.find('_' + uppercase_name[0]) >= 0:
                            print '                %s = GL_TRUE;' % flag_name
                    print '                break;'
                print '            default:'
                print '               return;'
                print '        }'
                print

                # Emit fake glEnableClientState/glDisableClientState flags
                for camelcase_name, uppercase_name in self.arrays:
                    flag_name = '__' + uppercase_name.lower()
                    enable_name = 'GL_%s_ARRAY' % uppercase_name

                    # Emit a fake function
                    print '        {'
                    print '            static const trace::FunctionSig &__sig = %s ? __glEnableClientState_sig : __glDisableClientState_sig;' % flag_name
                    print '            unsigned __call = trace::localWriter.beginEnter(&__sig);'
                    print '            trace::localWriter.beginArg(0);'
                    dump_instance(glapi.GLenum, enable_name)
                    print '            trace::localWriter.endArg();'
                    print '            trace::localWriter.endEnter();'
                    print '            trace::localWriter.beginLeave(__call);'
                    print '            trace::localWriter.endLeave();'
                    print '        }'

            print '        return;'
            print '    }'

        # ... to the draw calls
        if function.name in self.draw_function_names:
            print '    if (__need_user_arrays()) {'
            arg_names = ', '.join([arg.name for arg in function.args[1:]])
            print '        GLuint maxindex = __%s_maxindex(%s);' % (function.name, arg_names)
            print '        __trace_user_arrays(maxindex);'
            print '    }'
        
        # Emit a fake memcpy on buffer uploads
        if function.name in ('glUnmapBuffer', 'glUnmapBufferARB', ):
            print '    struct buffer_mapping *mapping = get_buffer_mapping(target);'
            print '    if (mapping && mapping->write && !mapping->explicit_flush) {'
            self.emit_memcpy('mapping->map', 'mapping->map', 'mapping->length')
            print '    }'
        if function.name in ('glFlushMappedBufferRange', 'glFlushMappedBufferRangeAPPLE'):
            print '    struct buffer_mapping *mapping = get_buffer_mapping(target);'
            print '    if (mapping) {'
            if function.name.endswith('APPLE'):
                 print '        GLsizeiptr length = size;'
                 print '        mapping->explicit_flush = true;'
            print '        //assert(offset + length <= mapping->length);'
            self.emit_memcpy('(char *)mapping->map + offset', '(const char *)mapping->map + offset', 'length')
            print '    }'
        # FIXME: glFlushMappedNamedBufferRangeEXT

        # Don't leave vertex attrib locations to chance.  Instead emit fake
        # glBindAttribLocation calls to ensure that the same locations will be
        # used when retracing.  Trying to remap locations after the fact would
        # be an herculian task given that vertex attrib locations appear in
        # many entry-points, including non-shader related ones.
        if function.name == 'glLinkProgram':
            Tracer.dispatch_function(self, function)
            print '    GLint active_attributes = 0;'
            print '    __glGetProgramiv(program, GL_ACTIVE_ATTRIBUTES, &active_attributes);'
            print '    for (GLint attrib = 0; attrib < active_attributes; ++attrib) {'
            print '        GLint size = 0;'
            print '        GLenum type = 0;'
            print '        GLchar name[256];'
            # TODO: Use ACTIVE_ATTRIBUTE_MAX_LENGTH instead of 256
            print '        __glGetActiveAttrib(program, attrib, sizeof name, NULL, &size, &type, name);'
            print "        if (name[0] != 'g' || name[1] != 'l' || name[2] != '_') {"
            print '            GLint location = __glGetAttribLocation(program, name);'
            print '            if (location >= 0) {'
            bind_function = glapi.glapi.get_function_by_name('glBindAttribLocation')
            self.fake_call(bind_function, ['program', 'location', 'name'])
            print '            }'
            print '        }'
            print '    }'
        if function.name == 'glLinkProgramARB':
            Tracer.dispatch_function(self, function)
            print '    GLint active_attributes = 0;'
            print '    __glGetObjectParameterivARB(programObj, GL_OBJECT_ACTIVE_ATTRIBUTES_ARB, &active_attributes);'
            print '    for (GLint attrib = 0; attrib < active_attributes; ++attrib) {'
            print '        GLint size = 0;'
            print '        GLenum type = 0;'
            print '        GLcharARB name[256];'
            # TODO: Use ACTIVE_ATTRIBUTE_MAX_LENGTH instead of 256
            print '        __glGetActiveAttribARB(programObj, attrib, sizeof name, NULL, &size, &type, name);'
            print "        if (name[0] != 'g' || name[1] != 'l' || name[2] != '_') {"
            print '            GLint location = __glGetAttribLocationARB(programObj, name);'
            print '            if (location >= 0) {'
            bind_function = glapi.glapi.get_function_by_name('glBindAttribLocationARB')
            self.fake_call(bind_function, ['programObj', 'location', 'name'])
            print '            }'
            print '        }'
            print '    }'

        Tracer.trace_function_impl_body(self, function)