def invokeFunction(self, function): if function.name in ('glLinkProgram', 'glLinkProgramARB'): # These functions have been dispatched already return # We implement GL_EXT_debug_marker, GL_GREMEDY_*, etc., and not the # driver if function.name in self.marker_functions: return if function.name in ('glXGetProcAddress', 'glXGetProcAddressARB', 'wglGetProcAddress'): else_ = '' for marker_function in self.marker_functions: if self.api.get_function_by_name(marker_function): print ' %sif (strcmp("%s", (const char *)%s) == 0) {' % (else_, marker_function, function.args[0].name) print ' __result = (%s)&%s;' % (function.type, marker_function) print ' }' else_ = 'else ' print ' %s{' % else_ Tracer.invokeFunction(self, function) print ' }' return # Override GL extensions if function.name in ('glGetString', 'glGetIntegerv', 'glGetStringi'): Tracer.invokeFunction(self, function, prefix = 'gltrace::__', suffix = '_override') return Tracer.invokeFunction(self, function)
def invokeFunction(self, function): if function.name in ('glLinkProgram', 'glLinkProgramARB'): # These functions have been dispatched already return # We implement GL_EXT_debug_marker, GL_GREMEDY_*, etc., and not the # driver if function.name in self.marker_functions: return if function.name in ('glXGetProcAddress', 'glXGetProcAddressARB', 'wglGetProcAddress'): else_ = '' for marker_function in self.marker_functions: if self.api.getFunctionByName(marker_function): print ' %sif (strcmp("%s", (const char *)%s) == 0) {' % ( else_, marker_function, function.args[0].name) print ' _result = (%s)&%s;' % (function.type, marker_function) print ' }' else_ = 'else ' print ' %s{' % else_ Tracer.invokeFunction(self, function) print ' }' return # Override GL extensions if function.name in ('glGetString', 'glGetIntegerv', 'glGetStringi'): Tracer.invokeFunction(self, function, prefix='gltrace::_', suffix='_override') return Tracer.invokeFunction(self, function)
def invokeFunction(self, function): if function.name in ('glLinkProgram', 'glLinkProgramARB'): # These functions have been dispatched already return # We implement the GREMEDY extensions, not the driver if function.name in self.gremedy_functions: return if function.name in ('glXGetProcAddress', 'glXGetProcAddressARB', 'wglGetProcAddress'): if_ = 'if' for gremedy_function in self.gremedy_functions: print ' %s (strcmp("%s", (const char *)%s) == 0) {' % (if_, gremedy_function, function.args[0].name) print ' __result = (%s)&%s;' % (function.type, gremedy_function) print ' }' if_ = 'else if' print ' else {' Tracer.invokeFunction(self, function) print ' }' return # Override GL extensions if function.name in ('glGetString', 'glGetIntegerv', 'glGetStringi'): Tracer.invokeFunction(self, function, prefix = 'gltrace::__', suffix = '_override') return Tracer.invokeFunction(self, function)
def invokeFunction(self, function): # We implement GL_EXT_debug_marker, GL_GREMEDY_*, etc., and not the # driver if function.name in self.marker_functions: return if function.name in self.getProcAddressFunctionNames: else_ = '' for marker_function in self.marker_functions: if self.api.getFunctionByName(marker_function): print ' %sif (strcmp("%s", (const char *)%s) == 0) {' % (else_, marker_function, function.args[0].name) print ' _result = (%s)&%s;' % (function.type, marker_function) print ' }' else_ = 'else ' print ' %s{' % else_ Tracer.invokeFunction(self, function) print ' _result = _wrapProcAddress(%s, _result);' % (function.args[0].name) print ' }' return # Override GL extensions if function.name in ('glGetString', 'glGetIntegerv', 'glGetStringi'): Tracer.invokeFunction(self, function, prefix = 'gltrace::_', suffix = '_override') return Tracer.invokeFunction(self, function)
def traceFunctionImplBody(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 ' gltrace::Context *ctx = gltrace::getContext();' 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.invokeFunction(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);' self.serializeValue(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', 'glUnmapBufferOES'): 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 == 'glUnmapNamedBufferEXT': print ' GLint access = 0;' print ' glGetNamedBufferParameterivEXT(buffer, GL_BUFFER_ACCESS, &access);' print ' if ((access & GL_MAP_WRITE_BIT) & !(access & GL_MAP_FLUSH_EXPLICIT_BIT)) {' print ' GLvoid *map = NULL;' print ' glGetNamedBufferPointervEXT(buffer, GL_BUFFER_MAP_POINTER, &map);' print ' GLint length = 0;' print ' glGetNamedBufferParameterivEXT(buffer, GL_BUFFER_MAP_LENGTH, &length);' self.emit_memcpy('map', 'map', '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 ' }' if function.name == 'glFlushMappedNamedBufferRangeEXT': print ' GLvoid *map = NULL;' print ' glGetNamedBufferPointervEXT(buffer, GL_BUFFER_MAP_POINTER, &map);' print ' if (map) {' self.emit_memcpy('(char *)map + offset', '(const char *)map + offset', 'length') print ' }' # 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.invokeFunction(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.invokeFunction(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.traceFunctionImplBody(self, function)
def traceFunctionImplBody(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 ' gltrace::Context *ctx = gltrace::getContext();' 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.invokeFunction(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);' self.serializeValue(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 _count = _%s_count(%s);' % (function.name, arg_names) print ' _trace_user_arrays(_count);' print ' }' # Emit a fake memcpy on buffer uploads if function.name == 'glBufferParameteriAPPLE': print ' if (pname == GL_BUFFER_FLUSHING_UNMAP_APPLE && param == GL_FALSE) {' print ' _checkBufferFlushingUnmapAPPLE = true;' print ' }' if function.name in ('glUnmapBuffer', 'glUnmapBufferARB'): if function.name.endswith('ARB'): suffix = 'ARB' else: suffix = '' print ' GLint access = 0;' print ' _glGetBufferParameteriv%s(target, GL_BUFFER_ACCESS, &access);' % suffix print ' if (access != GL_READ_ONLY) {' print ' GLvoid *map = NULL;' print ' _glGetBufferPointerv%s(target, GL_BUFFER_MAP_POINTER, &map);' % suffix print ' if (map) {' print ' GLint length = -1;' print ' bool flush = true;' print ' if (_checkBufferMapRange) {' print ' _glGetBufferParameteriv%s(target, GL_BUFFER_MAP_LENGTH, &length);' % suffix print ' GLint access_flags = 0;' print ' _glGetBufferParameteriv(target, GL_BUFFER_ACCESS_FLAGS, &access_flags);' print ' flush = flush && !(access_flags & GL_MAP_FLUSH_EXPLICIT_BIT);' print ' if (length == -1) {' print ' // Mesa drivers refuse GL_BUFFER_MAP_LENGTH without GL 3.0' print ' static bool warned = false;' print ' if (!warned) {' print ' os::log("apitrace: warning: glGetBufferParameteriv%s(GL_BUFFER_MAP_LENGTH) failed\\n");' % suffix print ' warned = true;' print ' }' print ' struct buffer_mapping *mapping = get_buffer_mapping(target);' print ' if (mapping) {' print ' length = mapping->length;' print ' flush = flush && !mapping->explicit_flush;' print ' } else {' print ' length = 0;' print ' flush = false;' print ' }' print ' }' print ' } else {' print ' length = 0;' print ' _glGetBufferParameteriv%s(target, GL_BUFFER_SIZE, &length);' % suffix print ' }' print ' if (_checkBufferFlushingUnmapAPPLE) {' print ' GLint flushing_unmap = GL_TRUE;' print ' _glGetBufferParameteriv%s(target, GL_BUFFER_FLUSHING_UNMAP_APPLE, &flushing_unmap);' % suffix print ' flush = flush && flushing_unmap;' print ' }' print ' if (flush && length > 0) {' self.emit_memcpy('map', 'map', 'length') print ' }' print ' }' print ' }' if function.name == 'glUnmapBufferOES': print ' GLint access = 0;' print ' _glGetBufferParameteriv(target, GL_BUFFER_ACCESS_OES, &access);' print ' if (access == GL_WRITE_ONLY_OES) {' print ' GLvoid *map = NULL;' print ' _glGetBufferPointervOES(target, GL_BUFFER_MAP_POINTER_OES, &map);' print ' GLint size = 0;' print ' _glGetBufferParameteriv(target, GL_BUFFER_SIZE, &size);' print ' if (map && size > 0) {' self.emit_memcpy('map', 'map', 'size') self.shadowBufferMethod('bufferSubData(0, size, map)') print ' }' print ' }' if function.name == 'glUnmapNamedBufferEXT': print ' GLint access_flags = 0;' print ' _glGetNamedBufferParameterivEXT(buffer, GL_BUFFER_ACCESS_FLAGS, &access_flags);' print ' if ((access_flags & GL_MAP_WRITE_BIT) && !(access_flags & GL_MAP_FLUSH_EXPLICIT_BIT)) {' print ' GLvoid *map = NULL;' print ' _glGetNamedBufferPointervEXT(buffer, GL_BUFFER_MAP_POINTER, &map);' print ' GLint length = 0;' print ' _glGetNamedBufferParameterivEXT(buffer, GL_BUFFER_MAP_LENGTH, &length);' print ' if (map && length > 0) {' self.emit_memcpy('map', 'map', 'length') print ' }' print ' }' if function.name == 'glFlushMappedBufferRange': print ' GLvoid *map = NULL;' print ' _glGetBufferPointerv(target, GL_BUFFER_MAP_POINTER, &map);' print ' if (map && length > 0) {' self.emit_memcpy('(char *)map + offset', '(const char *)map + offset', 'length') print ' }' if function.name == 'glFlushMappedBufferRangeAPPLE': print ' GLvoid *map = NULL;' print ' _glGetBufferPointerv(target, GL_BUFFER_MAP_POINTER, &map);' print ' if (map && size > 0) {' self.emit_memcpy('(char *)map + offset', '(const char *)map + offset', 'size') print ' }' if function.name == 'glFlushMappedNamedBufferRangeEXT': print ' GLvoid *map = NULL;' print ' _glGetNamedBufferPointervEXT(buffer, GL_BUFFER_MAP_POINTER, &map);' print ' if (map && length > 0) {' self.emit_memcpy('(char *)map + offset', '(const char *)map + offset', 'length') print ' }' # 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.invokeFunction(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.getFunctionByName( 'glBindAttribLocation') self.fake_call(bind_function, ['program', 'location', 'name']) print ' }' print ' }' print ' }' if function.name == 'glLinkProgramARB': Tracer.invokeFunction(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.getFunctionByName( 'glBindAttribLocationARB') self.fake_call(bind_function, ['programObj', 'location', 'name']) print ' }' print ' }' print ' }' self.shadowBufferProlog(function) Tracer.traceFunctionImplBody(self, function)
def invokeFunction(self, function): if function.name in ('glLinkProgram', 'glLinkProgramARB'): # These functions have been dispatched already return Tracer.invokeFunction(self, function)
def traceFunctionImplBody(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 ' gltrace::Context *ctx = gltrace::getContext();' 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.invokeFunction(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);' self.serializeValue(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 _count = _%s_count(%s);' % (function.name, arg_names) print ' _trace_user_arrays(_count);' print ' }' # Emit a fake memcpy on buffer uploads if function.name == 'glBufferParameteriAPPLE': print ' if (pname == GL_BUFFER_FLUSHING_UNMAP_APPLE && param == GL_FALSE) {' print ' _checkBufferFlushingUnmapAPPLE = true;' print ' }' if function.name in ('glUnmapBuffer', 'glUnmapBufferARB'): if function.name.endswith('ARB'): suffix = 'ARB' else: suffix = '' print ' GLint access = 0;' print ' _glGetBufferParameteriv%s(target, GL_BUFFER_ACCESS, &access);' % suffix print ' if (access != GL_READ_ONLY) {' print ' GLvoid *map = NULL;' print ' _glGetBufferPointerv%s(target, GL_BUFFER_MAP_POINTER, &map);' % suffix print ' if (map) {' print ' GLint length = -1;' print ' bool flush = true;' print ' if (_checkBufferMapRange) {' print ' _glGetBufferParameteriv%s(target, GL_BUFFER_MAP_LENGTH, &length);' % suffix print ' GLint access_flags = 0;' print ' _glGetBufferParameteriv(target, GL_BUFFER_ACCESS_FLAGS, &access_flags);' print ' flush = flush && !(access_flags & GL_MAP_FLUSH_EXPLICIT_BIT);' print ' if (length == -1) {' print ' // Mesa drivers refuse GL_BUFFER_MAP_LENGTH without GL 3.0 up-to' print ' // http://cgit.freedesktop.org/mesa/mesa/commit/?id=ffee498fb848b253a7833373fe5430f8c7ca0c5f' print ' static bool warned = false;' print ' if (!warned) {' print ' os::log("apitrace: warning: glGetBufferParameteriv%s(GL_BUFFER_MAP_LENGTH) failed\\n");' % suffix print ' warned = true;' print ' }' print ' struct buffer_mapping *mapping = get_buffer_mapping(target);' print ' if (mapping) {' print ' length = mapping->length;' print ' flush = flush && !mapping->explicit_flush;' print ' } else {' print ' length = 0;' print ' flush = false;' print ' }' print ' }' print ' } else {' print ' length = 0;' print ' _glGetBufferParameteriv%s(target, GL_BUFFER_SIZE, &length);' % suffix print ' }' print ' if (_checkBufferFlushingUnmapAPPLE) {' print ' GLint flushing_unmap = GL_TRUE;' print ' _glGetBufferParameteriv%s(target, GL_BUFFER_FLUSHING_UNMAP_APPLE, &flushing_unmap);' % suffix print ' flush = flush && flushing_unmap;' print ' }' print ' if (flush && length > 0) {' self.emit_memcpy('map', 'map', 'length') print ' }' print ' }' print ' }' if function.name == 'glUnmapBufferOES': print ' GLint access = 0;' print ' _glGetBufferParameteriv(target, GL_BUFFER_ACCESS_OES, &access);' print ' if (access == GL_WRITE_ONLY_OES) {' print ' GLvoid *map = NULL;' print ' _glGetBufferPointervOES(target, GL_BUFFER_MAP_POINTER_OES, &map);' print ' GLint size = 0;' print ' _glGetBufferParameteriv(target, GL_BUFFER_SIZE, &size);' print ' if (map && size > 0) {' self.emit_memcpy('map', 'map', 'size') self.shadowBufferMethod('bufferSubData(0, size, map)') print ' }' print ' }' if function.name == 'glUnmapNamedBufferEXT': print ' GLint access_flags = 0;' print ' _glGetNamedBufferParameterivEXT(buffer, GL_BUFFER_ACCESS_FLAGS, &access_flags);' print ' if ((access_flags & GL_MAP_WRITE_BIT) && !(access_flags & GL_MAP_FLUSH_EXPLICIT_BIT)) {' print ' GLvoid *map = NULL;' print ' _glGetNamedBufferPointervEXT(buffer, GL_BUFFER_MAP_POINTER, &map);' print ' GLint length = 0;' print ' _glGetNamedBufferParameterivEXT(buffer, GL_BUFFER_MAP_LENGTH, &length);' print ' if (map && length > 0) {' self.emit_memcpy('map', 'map', 'length') print ' }' print ' }' if function.name == 'glFlushMappedBufferRange': print ' GLvoid *map = NULL;' print ' _glGetBufferPointerv(target, GL_BUFFER_MAP_POINTER, &map);' print ' if (map && length > 0) {' self.emit_memcpy('(char *)map + offset', '(const char *)map + offset', 'length') print ' }' if function.name == 'glFlushMappedBufferRangeAPPLE': print ' GLvoid *map = NULL;' print ' _glGetBufferPointerv(target, GL_BUFFER_MAP_POINTER, &map);' print ' if (map && size > 0) {' self.emit_memcpy('(char *)map + offset', '(const char *)map + offset', 'size') print ' }' if function.name == 'glFlushMappedNamedBufferRangeEXT': print ' GLvoid *map = NULL;' print ' _glGetNamedBufferPointervEXT(buffer, GL_BUFFER_MAP_POINTER, &map);' print ' if (map && length > 0) {' self.emit_memcpy('(char *)map + offset', '(const char *)map + offset', 'length') print ' }' # 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.invokeFunction(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.getFunctionByName('glBindAttribLocation') self.fake_call(bind_function, ['program', 'location', 'name']) print ' }' print ' }' print ' }' if function.name == 'glLinkProgramARB': Tracer.invokeFunction(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.getFunctionByName('glBindAttribLocationARB') self.fake_call(bind_function, ['programObj', 'location', 'name']) print ' }' print ' }' print ' }' self.shadowBufferProlog(function) Tracer.traceFunctionImplBody(self, function)