X-Git-Url: https://git.cworth.org/git?a=blobdiff_plain;f=wrappers%2Fgltrace.py;h=7bf2a3507a4169dec9b56c8ef5cdcf055fb09408;hb=0b5b75e507df681260ea9c43b142ee48fff780c5;hp=96da4e85c576e25af119696f9c849ae2ecbb3724;hpb=4647f208f5a2b87391281e0f1202f66c23943bd9;p=apitrace diff --git a/wrappers/gltrace.py b/wrappers/gltrace.py index 96da4e8..7bf2a35 100644 --- a/wrappers/gltrace.py +++ b/wrappers/gltrace.py @@ -298,12 +298,7 @@ class GlTracer(Tracer): print ' switch (pname) {' for function, type, count, name in glparams.parameters: if type is not None: - print ' case %s: return %u;' % (name, count) - print ' case GL_COMPRESSED_TEXTURE_FORMATS: {' - print ' GLint num_compressed_texture_formats = 0;' - print ' _glGetIntegerv(GL_NUM_COMPRESSED_TEXTURE_FORMATS, &num_compressed_texture_formats);' - print ' return num_compressed_texture_formats;' - print ' }' + print ' case %s: return %s;' % (name, count) print ' default:' print r' os::log("apitrace: warning: %s: unknown GLenum 0x%04X\n", __FUNCTION__, pname);' print ' return 1;' @@ -334,10 +329,22 @@ class GlTracer(Tracer): Tracer.traceApi(self, api) print 'static %s _wrapProcAddress(%s procName, %s procPtr) {' % (retType, argType, retType) + + # Provide fallback functions to missing debug functions print ' if (!procPtr) {' - print ' return procPtr;' + else_ = '' + for function_name in self.debug_functions: + if self.api.getFunctionByName(function_name): + print ' %sif (strcmp("%s", (const char *)procName) == 0) {' % (else_, function_name) + print ' return (%s)&%s;' % (retType, function_name) + print ' }' + else_ = 'else ' + print ' %s{' % else_ + print ' return NULL;' + print ' }' print ' }' - for function in api.functions: + + for function in api.getAllFunctions(): ptype = function_pointer_type(function) pvalue = function_pointer_value(function) print ' if (strcmp("%s", (const char *)procName) == 0) {' % function.name @@ -355,14 +362,14 @@ class GlTracer(Tracer): print 'void _shadow_glGetBufferSubData(GLenum target, GLintptr offset,' print ' GLsizeiptr size, GLvoid *data)' print '{' - print ' struct gltrace::Context *ctx = gltrace::getContext();' + print ' gltrace::Context *ctx = gltrace::getContext();' print ' if (!ctx->needsShadowBuffers() || target != GL_ELEMENT_ARRAY_BUFFER) {' print ' _glGetBufferSubData(target, offset, size, data);' print ' return;' print ' }' print print ' GLint buffer_binding = 0;' - print ' _glGetIntegerv(target, &buffer_binding);' + print ' _glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &buffer_binding);' print ' if (buffer_binding > 0) {' print ' gltrace::Buffer & buf = ctx->buffers[buffer_binding];' print ' buf.getSubData(offset, size, data);' @@ -448,6 +455,10 @@ class GlTracer(Tracer): 'glMultiDrawElementsBaseVertex', 'glDrawArraysIndirect', 'glDrawElementsIndirect', + 'glMultiDrawArraysIndirect', + 'glMultiDrawArraysIndirectAMD', + 'glMultiDrawElementsIndirect', + 'glMultiDrawElementsIndirectAMD', 'glDrawArraysEXT', 'glDrawRangeElementsEXT', 'glDrawRangeElementsEXT_size', @@ -685,6 +696,8 @@ class GlTracer(Tracer): Tracer.traceFunctionImplBody(self, function) + # These entrypoints are only expected to be implemented by tools; + # drivers will probably not implement them. marker_functions = [ # GL_GREMEDY_string_marker 'glStringMarkerGREMEDY', @@ -696,17 +709,55 @@ class GlTracer(Tracer): 'glPopGroupMarkerEXT', ] + # These entrypoints may be implemented by drivers, but are also very useful + # for debugging / analysis tools. + debug_functions = [ + # GL_KHR_debug + 'glDebugMessageControl', + 'glDebugMessageInsert', + 'glDebugMessageCallback', + 'glGetDebugMessageLog', + 'glPushDebugGroup', + 'glPopDebugGroup', + 'glObjectLabel', + 'glGetObjectLabel', + 'glObjectPtrLabel', + 'glGetObjectPtrLabel', + # GL_ARB_debug_output + 'glDebugMessageControlARB', + 'glDebugMessageInsertARB', + 'glDebugMessageCallbackARB', + 'glGetDebugMessageLogARB', + # GL_AMD_debug_output + 'glDebugMessageEnableAMD', + 'glDebugMessageInsertAMD', + 'glDebugMessageCallbackAMD', + 'glGetDebugMessageLogAMD', + ] + def invokeFunction(self, function): if function.name in ('glLinkProgram', 'glLinkProgramARB'): # These functions have been dispatched already return + Tracer.invokeFunction(self, function) + + def doInvokeFunction(self, function): + # Same as invokeFunction() but called both when trace is enabled or disabled. + # + # Used to modify the behavior of GL entry-points. + + # Override GL extensions + if function.name in ('glGetString', 'glGetIntegerv', 'glGetStringi'): + Tracer.doInvokeFunction(self, function, prefix = 'gltrace::_', suffix = '_override') + 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'): + if function.name in self.getProcAddressFunctionNames: else_ = '' for marker_function in self.marker_functions: if self.api.getFunctionByName(marker_function): @@ -715,16 +766,19 @@ class GlTracer(Tracer): print ' }' else_ = 'else ' print ' %s{' % else_ - Tracer.invokeFunction(self, function) - print ' }' - return + Tracer.doInvokeFunction(self, function) - # Override GL extensions - if function.name in ('glGetString', 'glGetIntegerv', 'glGetStringi'): - Tracer.invokeFunction(self, function, prefix = 'gltrace::_', suffix = '_override') + # Replace function addresses with ours + # XXX: Doing this here instead of wrapRet means that the trace will + # contain the addresses of the wrapper functions, and not the real + # functions, but in practice this should make no difference. + if function.name in self.getProcAddressFunctionNames: + print ' _result = _wrapProcAddress(%s, _result);' % (function.args[0].name,) + + print ' }' return - Tracer.invokeFunction(self, function) + Tracer.doInvokeFunction(self, function) buffer_targets = [ 'ARRAY_BUFFER', @@ -743,10 +797,6 @@ class GlTracer(Tracer): def wrapRet(self, function, instance): Tracer.wrapRet(self, function, instance) - # Replace function addresses with ours - if function.name in self.getProcAddressFunctionNames: - print ' %s = _wrapProcAddress(%s, %s);' % (instance, function.args[0].name, instance) - # Keep track of buffer mappings if function.name in ('glMapBuffer', 'glMapBufferARB'): print ' struct buffer_mapping *mapping = get_buffer_mapping(target);' @@ -783,12 +833,24 @@ class GlTracer(Tracer): 'glBitmap', 'glColorSubTable', 'glColorTable', + 'glCompressedMultiTexImage1DEXT', + 'glCompressedMultiTexImage2DEXT', + 'glCompressedMultiTexImage3DEXT', + 'glCompressedMultiTexSubImage1DEXT', + 'glCompressedMultiTexSubImage2DEXT', + 'glCompressedMultiTexSubImage3DEXT', 'glCompressedTexImage1D', 'glCompressedTexImage2D', 'glCompressedTexImage3D', 'glCompressedTexSubImage1D', 'glCompressedTexSubImage2D', 'glCompressedTexSubImage3D', + 'glCompressedTextureImage1DEXT', + 'glCompressedTextureImage2DEXT', + 'glCompressedTextureImage3DEXT', + 'glCompressedTextureSubImage1DEXT', + 'glCompressedTextureSubImage2DEXT', + 'glCompressedTextureSubImage3DEXT', 'glConvolutionFilter1D', 'glConvolutionFilter2D', 'glDrawPixels', @@ -824,25 +886,6 @@ class GlTracer(Tracer): ]) def serializeArgValue(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.serializeArgValue(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) \ @@ -1067,6 +1110,16 @@ class GlTracer(Tracer): function = api.getFunctionByName('glClientActiveTexture') self.fake_call(function, [texture]) + def emitFakeTexture2D(self): + function = glapi.glapi.getFunctionByName('glTexImage2D') + instances = function.argNames() + print ' unsigned _fake_call = trace::localWriter.beginEnter(&_%s_sig);' % (function.name,) + for arg in function.args: + assert not arg.output + self.serializeArg(function, arg) + print ' trace::localWriter.endEnter();' + print ' trace::localWriter.beginLeave(_fake_call);' + print ' trace::localWriter.endLeave();'