blob: 69be821ed15f67a1aad27d16eae76be3ea29a0ed [file] [log] [blame]
José Fonseca669b1222011-02-20 09:05:10 +00001##########################################################################
2#
3# Copyright 2008-2010 VMware, Inc.
4# All Rights Reserved.
5#
6# Permission is hereby granted, free of charge, to any person obtaining a copy
7# of this software and associated documentation files (the "Software"), to deal
8# in the Software without restriction, including without limitation the rights
9# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10# copies of the Software, and to permit persons to whom the Software is
11# furnished to do so, subject to the following conditions:
12#
13# The above copyright notice and this permission notice shall be included in
14# all copies or substantial portions of the Software.
15#
16# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22# THE SOFTWARE.
23#
24##########################################################################/
25
26
27"""GL tracing generator."""
28
29
José Fonsecabd86a222011-09-27 09:21:38 +010030import specs.stdapi as stdapi
31import specs.glapi as glapi
32import specs.glparams as glparams
33from specs.glxapi import glxapi
José Fonseca669b1222011-02-20 09:05:10 +000034from trace import Tracer, dump_instance
35
36
José Fonseca99221832011-03-22 22:15:46 +000037class TypeGetter(stdapi.Visitor):
38 '''Determine which glGet*v function that matches the specified type.'''
39
José Fonsecac493e3e2011-06-29 12:57:06 +010040 def __init__(self, prefix = 'glGet', long_suffix = True, ext_suffix = ''):
José Fonseca1a2fdd22011-04-01 00:55:09 +010041 self.prefix = prefix
42 self.long_suffix = long_suffix
José Fonsecac493e3e2011-06-29 12:57:06 +010043 self.ext_suffix = ext_suffix
José Fonseca1a2fdd22011-04-01 00:55:09 +010044
José Fonseca99221832011-03-22 22:15:46 +000045 def visit_const(self, const):
46 return self.visit(const.type)
47
48 def visit_alias(self, alias):
49 if alias.expr == 'GLboolean':
José Fonseca1a2fdd22011-04-01 00:55:09 +010050 if self.long_suffix:
José Fonsecac493e3e2011-06-29 12:57:06 +010051 suffix = 'Booleanv'
52 arg_type = alias.expr
José Fonseca1a2fdd22011-04-01 00:55:09 +010053 else:
José Fonsecac493e3e2011-06-29 12:57:06 +010054 suffix = 'iv'
55 arg_type = 'GLint'
José Fonseca99221832011-03-22 22:15:46 +000056 elif alias.expr == 'GLdouble':
José Fonseca1a2fdd22011-04-01 00:55:09 +010057 if self.long_suffix:
José Fonsecac493e3e2011-06-29 12:57:06 +010058 suffix = 'Doublev'
59 arg_type = alias.expr
José Fonseca1a2fdd22011-04-01 00:55:09 +010060 else:
José Fonsecac493e3e2011-06-29 12:57:06 +010061 suffix = 'dv'
62 arg_type = alias.expr
José Fonseca99221832011-03-22 22:15:46 +000063 elif alias.expr == 'GLfloat':
José Fonseca1a2fdd22011-04-01 00:55:09 +010064 if self.long_suffix:
José Fonsecac493e3e2011-06-29 12:57:06 +010065 suffix = 'Floatv'
66 arg_type = alias.expr
José Fonseca1a2fdd22011-04-01 00:55:09 +010067 else:
José Fonsecac493e3e2011-06-29 12:57:06 +010068 suffix = 'fv'
69 arg_type = alias.expr
José Fonseca7f5163e2011-03-31 23:37:26 +010070 elif alias.expr in ('GLint', 'GLuint', 'GLsizei'):
José Fonseca1a2fdd22011-04-01 00:55:09 +010071 if self.long_suffix:
José Fonsecac493e3e2011-06-29 12:57:06 +010072 suffix = 'Integerv'
73 arg_type = 'GLint'
José Fonseca1a2fdd22011-04-01 00:55:09 +010074 else:
José Fonsecac493e3e2011-06-29 12:57:06 +010075 suffix = 'iv'
76 arg_type = 'GLint'
José Fonseca99221832011-03-22 22:15:46 +000077 else:
78 print alias.expr
79 assert False
José Fonsecac493e3e2011-06-29 12:57:06 +010080 function_name = self.prefix + suffix + self.ext_suffix
81 return function_name, arg_type
José Fonseca99221832011-03-22 22:15:46 +000082
83 def visit_enum(self, enum):
José Fonseca1a2fdd22011-04-01 00:55:09 +010084 return self.visit(glapi.GLint)
José Fonseca99221832011-03-22 22:15:46 +000085
86 def visit_bitmask(self, bitmask):
José Fonseca1a2fdd22011-04-01 00:55:09 +010087 return self.visit(glapi.GLint)
José Fonseca99221832011-03-22 22:15:46 +000088
89 def visit_opaque(self, pointer):
José Fonsecac493e3e2011-06-29 12:57:06 +010090 return self.prefix + 'Pointerv' + self.ext_suffix, 'GLvoid *'
José Fonseca99221832011-03-22 22:15:46 +000091
92
José Fonseca669b1222011-02-20 09:05:10 +000093class GlTracer(Tracer):
94
José Fonseca99221832011-03-22 22:15:46 +000095 arrays = [
96 ("Vertex", "VERTEX"),
97 ("Normal", "NORMAL"),
98 ("Color", "COLOR"),
99 ("Index", "INDEX"),
100 ("TexCoord", "TEXTURE_COORD"),
101 ("EdgeFlag", "EDGE_FLAG"),
102 ("FogCoord", "FOG_COORD"),
103 ("SecondaryColor", "SECONDARY_COLOR"),
José Fonseca14c21bc2011-02-20 23:32:22 +0000104 ]
José Fonsecac9f12232011-03-25 20:07:42 +0000105 arrays.reverse()
José Fonseca669b1222011-02-20 09:05:10 +0000106
José Fonseca4c938c22011-04-30 22:44:38 +0100107 def header(self, api):
108 Tracer.header(self, api)
109
José Fonseca1b3d3752011-07-15 10:15:19 +0100110 print '#include "gltrace.hpp"'
111 print
José Fonseca25ebe542011-04-24 10:08:22 +0100112 print '// Whether user arrays were used'
113 print 'static bool __user_arrays = false;'
José Fonseca5a568a92011-06-29 16:43:36 +0100114 print 'static bool __user_arrays_arb = false;'
115 print 'static bool __user_arrays_nv = false;'
José Fonseca25ebe542011-04-24 10:08:22 +0100116 print
José Fonseca5a568a92011-06-29 16:43:36 +0100117
118 # Which glVertexAttrib* variant to use
119 print 'enum vertex_attrib {'
120 print ' VERTEX_ATTRIB,'
121 print ' VERTEX_ATTRIB_ARB,'
122 print ' VERTEX_ATTRIB_NV,'
123 print '};'
124 print
125 print 'static vertex_attrib __get_vertex_attrib(void) {'
José Fonsecad5b95b32011-06-29 17:41:02 +0100126 print ' if (__user_arrays_arb || __user_arrays_nv) {'
José Fonseca5a568a92011-06-29 16:43:36 +0100127 print ' GLboolean __vertex_program = GL_FALSE;'
128 print ' __glGetBooleanv(GL_VERTEX_PROGRAM_ARB, &__vertex_program);'
129 print ' if (__vertex_program) {'
130 print ' if (__user_arrays_nv) {'
131 print ' GLint __vertex_program_binding_nv = 0;'
132 print ' __glGetIntegerv(GL_VERTEX_PROGRAM_BINDING_NV, &__vertex_program_binding_nv);'
133 print ' if (__vertex_program_binding_nv) {'
134 print ' return VERTEX_ATTRIB_NV;'
135 print ' }'
136 print ' }'
137 print ' return VERTEX_ATTRIB_ARB;'
138 print ' }'
139 print ' }'
140 print ' return VERTEX_ATTRIB;'
141 print '}'
142 print
143
José Fonseca8a6c6cb2011-03-23 16:44:30 +0000144 # Whether we need user arrays
145 print 'static inline bool __need_user_arrays(void)'
146 print '{'
José Fonseca25ebe542011-04-24 10:08:22 +0100147 print ' if (!__user_arrays) {'
148 print ' return false;'
149 print ' }'
150 print
José Fonseca1a2fdd22011-04-01 00:55:09 +0100151
José Fonseca8a6c6cb2011-03-23 16:44:30 +0000152 for camelcase_name, uppercase_name in self.arrays:
153 function_name = 'gl%sPointer' % camelcase_name
154 enable_name = 'GL_%s_ARRAY' % uppercase_name
155 binding_name = 'GL_%s_ARRAY_BUFFER_BINDING' % uppercase_name
156 print ' // %s' % function_name
José Fonsecafb6744f2011-04-15 11:18:37 +0100157 self.array_prolog(api, uppercase_name)
José Fonseca7f5163e2011-03-31 23:37:26 +0100158 print ' if (__glIsEnabled(%s)) {' % enable_name
159 print ' GLint __binding = 0;'
160 print ' __glGetIntegerv(%s, &__binding);' % binding_name
161 print ' if (!__binding) {'
José Fonsecafb6744f2011-04-15 11:18:37 +0100162 self.array_cleanup(api, uppercase_name)
José Fonseca7f5163e2011-03-31 23:37:26 +0100163 print ' return true;'
José Fonseca8a6c6cb2011-03-23 16:44:30 +0000164 print ' }'
165 print ' }'
José Fonsecafb6744f2011-04-15 11:18:37 +0100166 self.array_epilog(api, uppercase_name)
José Fonseca8a6c6cb2011-03-23 16:44:30 +0000167 print
José Fonseca7f5163e2011-03-31 23:37:26 +0100168
José Fonseca5a568a92011-06-29 16:43:36 +0100169 print ' vertex_attrib __vertex_attrib = __get_vertex_attrib();'
170 print
171 print ' // glVertexAttribPointer'
172 print ' if (__vertex_attrib == VERTEX_ATTRIB) {'
173 print ' GLint __max_vertex_attribs = 0;'
174 print ' __glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &__max_vertex_attribs);'
175 print ' for (GLint index = 0; index < __max_vertex_attribs; ++index) {'
176 print ' GLint __enabled = 0;'
177 print ' __glGetVertexAttribiv(index, GL_VERTEX_ATTRIB_ARRAY_ENABLED, &__enabled);'
178 print ' if (__enabled) {'
179 print ' GLint __binding = 0;'
180 print ' __glGetVertexAttribiv(index, GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING, &__binding);'
181 print ' if (!__binding) {'
182 print ' return true;'
183 print ' }'
184 print ' }'
185 print ' }'
186 print ' }'
187 print
188 print ' // glVertexAttribPointerARB'
189 print ' if (__vertex_attrib == VERTEX_ATTRIB_ARB) {'
José Fonsecad94aaac2011-06-28 20:50:49 +0100190 print ' GLint __max_vertex_attribs = 0;'
191 print ' __glGetIntegerv(GL_MAX_VERTEX_ATTRIBS_ARB, &__max_vertex_attribs);'
192 print ' for (GLint index = 0; index < __max_vertex_attribs; ++index) {'
193 print ' GLint __enabled = 0;'
194 print ' __glGetVertexAttribivARB(index, GL_VERTEX_ATTRIB_ARRAY_ENABLED_ARB, &__enabled);'
195 print ' if (__enabled) {'
196 print ' GLint __binding = 0;'
197 print ' __glGetVertexAttribivARB(index, GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING_ARB, &__binding);'
198 print ' if (!__binding) {'
199 print ' return true;'
200 print ' }'
201 print ' }'
202 print ' }'
José Fonseca5a568a92011-06-29 16:43:36 +0100203 print ' }'
204 print
205 print ' // glVertexAttribPointerNV'
206 print ' if (__vertex_attrib == VERTEX_ATTRIB_NV) {'
207 print ' for (GLint index = 0; index < 16; ++index) {'
José Fonsecad94aaac2011-06-28 20:50:49 +0100208 print ' GLint __enabled = 0;'
José Fonseca5a568a92011-06-29 16:43:36 +0100209 print ' __glGetIntegerv(GL_VERTEX_ATTRIB_ARRAY0_NV + index, &__enabled);'
José Fonsecad94aaac2011-06-28 20:50:49 +0100210 print ' if (__enabled) {'
José Fonseca5a568a92011-06-29 16:43:36 +0100211 print ' return true;'
José Fonseca1a2fdd22011-04-01 00:55:09 +0100212 print ' }'
213 print ' }'
214 print ' }'
215 print
216
José Fonseca8a6c6cb2011-03-23 16:44:30 +0000217 print ' return false;'
218 print '}'
219 print
José Fonseca669b1222011-02-20 09:05:10 +0000220
José Fonseca8a6c6cb2011-03-23 16:44:30 +0000221 print 'static void __trace_user_arrays(GLuint maxindex);'
José Fonseca14c21bc2011-02-20 23:32:22 +0000222 print
José Fonseca867b1b72011-04-24 11:58:04 +0100223
224 print 'struct buffer_mapping {'
225 print ' void *map;'
226 print ' GLint length;'
227 print ' bool write;'
José Fonseca73373602011-05-20 17:45:26 +0100228 print ' bool explicit_flush;'
José Fonseca867b1b72011-04-24 11:58:04 +0100229 print '};'
230 print
231 for target in self.buffer_targets:
232 print 'struct buffer_mapping __%s_mapping;' % target.lower();
233 print
234 print 'static inline struct buffer_mapping *'
235 print 'get_buffer_mapping(GLenum target) {'
236 print ' switch(target) {'
237 for target in self.buffer_targets:
238 print ' case GL_%s:' % target
239 print ' return & __%s_mapping;' % target.lower()
240 print ' default:'
José Fonsecacbd225f2011-06-09 00:07:18 +0100241 print ' OS::DebugMessage("apitrace: warning: unknown buffer target 0x%04X\\n", target);'
José Fonseca867b1b72011-04-24 11:58:04 +0100242 print ' return NULL;'
243 print ' }'
244 print '}'
245 print
246
247 # Generate memcpy's signature
248 self.trace_function_decl(glapi.memcpy)
José Fonsecaa3f89ae2011-04-26 08:50:32 +0100249
250 # Generate a helper function to determine whether a parameter name
251 # refers to a symbolic value or not
252 print 'static bool'
253 print 'is_symbolic_pname(GLenum pname) {'
254 print ' switch(pname) {'
José Fonseca5ea91872011-05-04 09:41:55 +0100255 for function, type, count, name in glparams.parameters:
José Fonsecaa3f89ae2011-04-26 08:50:32 +0100256 if type is glapi.GLenum:
José Fonseca4c938c22011-04-30 22:44:38 +0100257 print ' case %s:' % name
258 print ' return true;'
259 print ' default:'
260 print ' return false;'
José Fonsecaa3f89ae2011-04-26 08:50:32 +0100261 print ' }'
262 print '}'
263 print
264
265 # Generate a helper function to determine whether a parameter value is
266 # potentially symbolic or not; i.e., if the value can be represented in
267 # an enum or not
268 print 'template<class T>'
269 print 'static inline bool'
270 print 'is_symbolic_param(T param) {'
271 print ' return static_cast<T>(static_cast<GLenum>(param)) == param;'
272 print '}'
273 print
José Fonseca4c938c22011-04-30 22:44:38 +0100274
275 # Generate a helper function to know how many elements a parameter has
276 print 'static size_t'
José Fonsecaf4aca5d2011-05-08 08:29:30 +0100277 print '__gl_param_size(GLenum pname) {'
José Fonseca4c938c22011-04-30 22:44:38 +0100278 print ' switch(pname) {'
José Fonseca5ea91872011-05-04 09:41:55 +0100279 for function, type, count, name in glparams.parameters:
José Fonseca4c938c22011-04-30 22:44:38 +0100280 if type is not None:
281 print ' case %s: return %u;' % (name, count)
282 print ' case GL_COMPRESSED_TEXTURE_FORMATS: {'
283 print ' GLint num_compressed_texture_formats = 0;'
284 print ' __glGetIntegerv(GL_NUM_COMPRESSED_TEXTURE_FORMATS, &num_compressed_texture_formats);'
285 print ' return num_compressed_texture_formats;'
286 print ' }'
287 print ' default:'
José Fonsecacbd225f2011-06-09 00:07:18 +0100288 print r' OS::DebugMessage("apitrace: warning: %s: unknown GLenum 0x%04X\n", __FUNCTION__, pname);'
José Fonseca4c938c22011-04-30 22:44:38 +0100289 print ' return 1;'
290 print ' }'
291 print '}'
292 print
293
José Fonseca99221832011-03-22 22:15:46 +0000294 array_pointer_function_names = set((
295 "glVertexPointer",
296 "glNormalPointer",
297 "glColorPointer",
298 "glIndexPointer",
299 "glTexCoordPointer",
300 "glEdgeFlagPointer",
301 "glFogCoordPointer",
302 "glSecondaryColorPointer",
José Fonseca7f5163e2011-03-31 23:37:26 +0100303
José Fonsecaac5285b2011-05-04 11:09:08 +0100304 "glInterleavedArrays",
305
José Fonseca7e0bfd92011-04-30 23:09:03 +0100306 "glVertexPointerEXT",
307 "glNormalPointerEXT",
308 "glColorPointerEXT",
309 "glIndexPointerEXT",
310 "glTexCoordPointerEXT",
311 "glEdgeFlagPointerEXT",
312 "glFogCoordPointerEXT",
313 "glSecondaryColorPointerEXT",
José Fonseca99221832011-03-22 22:15:46 +0000314
José Fonseca7f5163e2011-03-31 23:37:26 +0100315 "glVertexAttribPointer",
316 "glVertexAttribPointerARB",
317 "glVertexAttribPointerNV",
José Fonsecaac5285b2011-05-04 11:09:08 +0100318 "glVertexAttribIPointer",
319 "glVertexAttribIPointerEXT",
José Fonseca7f5163e2011-03-31 23:37:26 +0100320 "glVertexAttribLPointer",
321 "glVertexAttribLPointerEXT",
José Fonseca99221832011-03-22 22:15:46 +0000322
323 #"glMatrixIndexPointerARB",
324 ))
325
326 draw_function_names = set((
327 'glDrawArrays',
328 'glDrawElements',
329 'glDrawRangeElements',
José Fonseca5c749e32011-05-09 11:11:37 +0100330 'glMultiDrawArrays',
331 'glMultiDrawElements',
332 'glDrawArraysInstanced',
José Fonsecaff8848b2011-10-09 01:04:17 +0100333 "glDrawArraysInstancedBaseInstance",
José Fonseca5c749e32011-05-09 11:11:37 +0100334 'glDrawElementsInstanced',
335 'glDrawArraysInstancedARB',
336 'glDrawElementsInstancedARB',
337 'glDrawElementsBaseVertex',
338 'glDrawRangeElementsBaseVertex',
339 'glDrawElementsInstancedBaseVertex',
José Fonsecaff8848b2011-10-09 01:04:17 +0100340 "glDrawElementsInstancedBaseInstance",
341 "glDrawElementsInstancedBaseVertexBaseInstance",
José Fonseca5c749e32011-05-09 11:11:37 +0100342 'glMultiDrawElementsBaseVertex',
343 'glDrawArraysIndirect',
344 'glDrawElementsIndirect',
345 'glDrawArraysEXT',
José Fonseca7e0bfd92011-04-30 23:09:03 +0100346 'glDrawRangeElementsEXT',
José Fonseca5c749e32011-05-09 11:11:37 +0100347 'glDrawRangeElementsEXT_size',
348 'glMultiDrawArraysEXT',
349 'glMultiDrawElementsEXT',
350 'glMultiModeDrawArraysIBM',
351 'glMultiModeDrawElementsIBM',
352 'glDrawArraysInstancedEXT',
353 'glDrawElementsInstancedEXT',
José Fonseca99221832011-03-22 22:15:46 +0000354 ))
355
José Fonsecac9f12232011-03-25 20:07:42 +0000356 interleaved_formats = [
357 'GL_V2F',
358 'GL_V3F',
359 'GL_C4UB_V2F',
360 'GL_C4UB_V3F',
361 'GL_C3F_V3F',
362 'GL_N3F_V3F',
363 'GL_C4F_N3F_V3F',
364 'GL_T2F_V3F',
365 'GL_T4F_V4F',
366 'GL_T2F_C4UB_V3F',
367 'GL_T2F_C3F_V3F',
368 'GL_T2F_N3F_V3F',
369 'GL_T2F_C4F_N3F_V3F',
370 'GL_T4F_C4F_N3F_V4F',
371 ]
372
José Fonseca14c21bc2011-02-20 23:32:22 +0000373 def trace_function_impl_body(self, function):
José Fonseca8a6c6cb2011-03-23 16:44:30 +0000374 # Defer tracing of user array pointers...
José Fonseca99221832011-03-22 22:15:46 +0000375 if function.name in self.array_pointer_function_names:
376 print ' GLint __array_buffer = 0;'
377 print ' __glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &__array_buffer);'
378 print ' if (!__array_buffer) {'
José Fonseca25ebe542011-04-24 10:08:22 +0100379 print ' __user_arrays = true;'
José Fonseca5a568a92011-06-29 16:43:36 +0100380 if function.name == "glVertexAttribPointerARB":
381 print ' __user_arrays_arb = true;'
382 if function.name == "glVertexAttribPointerNV":
383 print ' __user_arrays_nv = true;'
José Fonseca14c21bc2011-02-20 23:32:22 +0000384 self.dispatch_function(function)
José Fonsecaac5285b2011-05-04 11:09:08 +0100385
386 # And also break down glInterleavedArrays into the individual calls
387 if function.name == 'glInterleavedArrays':
388 print
389
390 # Initialize the enable flags
391 for camelcase_name, uppercase_name in self.arrays:
392 flag_name = '__' + uppercase_name.lower()
393 print ' GLboolean %s = GL_FALSE;' % flag_name
394 print
395
396 # Switch for the interleaved formats
397 print ' switch (format) {'
398 for format in self.interleaved_formats:
399 print ' case %s:' % format
400 for camelcase_name, uppercase_name in self.arrays:
401 flag_name = '__' + uppercase_name.lower()
402 if format.find('_' + uppercase_name[0]) >= 0:
403 print ' %s = GL_TRUE;' % flag_name
404 print ' break;'
405 print ' default:'
406 print ' return;'
407 print ' }'
408 print
409
410 # Emit fake glEnableClientState/glDisableClientState flags
411 for camelcase_name, uppercase_name in self.arrays:
412 flag_name = '__' + uppercase_name.lower()
413 enable_name = 'GL_%s_ARRAY' % uppercase_name
414
415 # Emit a fake function
416 print ' {'
417 print ' static const Trace::FunctionSig &__sig = %s ? __glEnableClientState_sig : __glDisableClientState_sig;' % flag_name
José Fonseca0ad465c2011-08-24 16:58:13 +0100418 print ' unsigned __call = Trace::localWriter.beginEnter(&__sig);'
419 print ' Trace::localWriter.beginArg(0);'
José Fonsecaac5285b2011-05-04 11:09:08 +0100420 dump_instance(glapi.GLenum, enable_name)
José Fonseca0ad465c2011-08-24 16:58:13 +0100421 print ' Trace::localWriter.endArg();'
422 print ' Trace::localWriter.endEnter();'
423 print ' Trace::localWriter.beginLeave(__call);'
424 print ' Trace::localWriter.endLeave();'
José Fonsecaac5285b2011-05-04 11:09:08 +0100425 print ' }'
426
José Fonseca99221832011-03-22 22:15:46 +0000427 print ' return;'
428 print ' }'
José Fonseca14c21bc2011-02-20 23:32:22 +0000429
José Fonseca8a6c6cb2011-03-23 16:44:30 +0000430 # ... to the draw calls
José Fonseca99221832011-03-22 22:15:46 +0000431 if function.name in self.draw_function_names:
José Fonseca8a6c6cb2011-03-23 16:44:30 +0000432 print ' if (__need_user_arrays()) {'
José Fonseca99221832011-03-22 22:15:46 +0000433 arg_names = ', '.join([arg.name for arg in function.args[1:]])
José Fonseca8a6c6cb2011-03-23 16:44:30 +0000434 print ' GLuint maxindex = __%s_maxindex(%s);' % (function.name, arg_names)
435 print ' __trace_user_arrays(maxindex);'
436 print ' }'
José Fonseca14c21bc2011-02-20 23:32:22 +0000437
José Fonseca73373602011-05-20 17:45:26 +0100438 # Emit a fake memcpy on buffer uploads
439 if function.name in ('glUnmapBuffer', 'glUnmapBufferARB', ):
José Fonseca867b1b72011-04-24 11:58:04 +0100440 print ' struct buffer_mapping *mapping = get_buffer_mapping(target);'
José Fonseca73373602011-05-20 17:45:26 +0100441 print ' if (mapping && mapping->write && !mapping->explicit_flush) {'
442 self.emit_memcpy('mapping->map', 'mapping->map', 'mapping->length')
José Fonseca867b1b72011-04-24 11:58:04 +0100443 print ' }'
José Fonseca73373602011-05-20 17:45:26 +0100444 if function.name in ('glFlushMappedBufferRange', 'glFlushMappedBufferRangeAPPLE'):
445 # TODO: avoid copying [0, offset] bytes
446 print ' struct buffer_mapping *mapping = get_buffer_mapping(target);'
447 print ' if (mapping) {'
448 if function.name.endswith('APPLE'):
449 print ' GLsizeiptr length = size;'
450 print ' mapping->explicit_flush = true;'
451 print ' //assert(offset + length <= mapping->length);'
452 self.emit_memcpy('mapping->map', 'mapping->map', 'offset + length')
453 print ' }'
454 # FIXME: glFlushMappedNamedBufferRangeEXT
José Fonseca867b1b72011-04-24 11:58:04 +0100455
José Fonseca91492d22011-05-23 21:20:31 +0100456 # Don't leave vertex attrib locations to chance. Instead emit fake
457 # glBindAttribLocation calls to ensure that the same locations will be
458 # used when retracing. Trying to remap locations after the fact would
459 # be an herculian task given that vertex attrib locations appear in
460 # many entry-points, including non-shader related ones.
461 if function.name == 'glLinkProgram':
462 Tracer.dispatch_function(self, function)
463 print ' GLint active_attributes = 0;'
464 print ' __glGetProgramiv(program, GL_ACTIVE_ATTRIBUTES, &active_attributes);'
José Fonseca7525e6f2011-09-28 09:04:56 +0100465 print ' for (GLint attrib = 0; attrib < active_attributes; ++attrib) {'
José Fonseca91492d22011-05-23 21:20:31 +0100466 print ' GLint size = 0;'
467 print ' GLenum type = 0;'
468 print ' GLchar name[256];'
469 # TODO: Use ACTIVE_ATTRIBUTE_MAX_LENGTH instead of 256
470 print ' __glGetActiveAttrib(program, attrib, sizeof name, NULL, &size, &type, name);'
José Fonseca2a794f52011-05-26 20:54:29 +0100471 print " if (name[0] != 'g' || name[1] != 'l' || name[2] != '_') {"
472 print ' GLint location = __glGetAttribLocation(program, name);'
473 print ' if (location >= 0) {'
José Fonseca91492d22011-05-23 21:20:31 +0100474 bind_function = glapi.glapi.get_function_by_name('glBindAttribLocation')
475 self.fake_call(bind_function, ['program', 'location', 'name'])
José Fonseca2a794f52011-05-26 20:54:29 +0100476 print ' }'
José Fonseca91492d22011-05-23 21:20:31 +0100477 print ' }'
478 print ' }'
479 if function.name == 'glLinkProgramARB':
480 Tracer.dispatch_function(self, function)
481 print ' GLint active_attributes = 0;'
482 print ' __glGetObjectParameterivARB(programObj, GL_OBJECT_ACTIVE_ATTRIBUTES_ARB, &active_attributes);'
José Fonseca7525e6f2011-09-28 09:04:56 +0100483 print ' for (GLint attrib = 0; attrib < active_attributes; ++attrib) {'
José Fonseca91492d22011-05-23 21:20:31 +0100484 print ' GLint size = 0;'
485 print ' GLenum type = 0;'
486 print ' GLcharARB name[256];'
487 # TODO: Use ACTIVE_ATTRIBUTE_MAX_LENGTH instead of 256
488 print ' __glGetActiveAttribARB(programObj, attrib, sizeof name, NULL, &size, &type, name);'
José Fonseca2a794f52011-05-26 20:54:29 +0100489 print " if (name[0] != 'g' || name[1] != 'l' || name[2] != '_') {"
490 print ' GLint location = __glGetAttribLocationARB(programObj, name);'
491 print ' if (location >= 0) {'
José Fonseca91492d22011-05-23 21:20:31 +0100492 bind_function = glapi.glapi.get_function_by_name('glBindAttribLocationARB')
493 self.fake_call(bind_function, ['programObj', 'location', 'name'])
José Fonseca2a794f52011-05-26 20:54:29 +0100494 print ' }'
José Fonseca91492d22011-05-23 21:20:31 +0100495 print ' }'
496 print ' }'
497
José Fonseca14c21bc2011-02-20 23:32:22 +0000498 Tracer.trace_function_impl_body(self, function)
José Fonseca73373602011-05-20 17:45:26 +0100499
José Fonseca8f34d342011-07-15 20:16:40 +0100500 gremedy_functions = [
501 'glStringMarkerGREMEDY',
502 'glFrameTerminatorGREMEDY',
503 ]
504
José Fonseca91492d22011-05-23 21:20:31 +0100505 def dispatch_function(self, function):
506 if function.name in ('glLinkProgram', 'glLinkProgramARB'):
507 # These functions have been dispatched already
508 return
509
José Fonseca1b3d3752011-07-15 10:15:19 +0100510 # We implement the GREMEDY extensions, not the driver
José Fonseca8f34d342011-07-15 20:16:40 +0100511 if function.name in self.gremedy_functions:
512 return
513
514 if function.name in ('glXGetProcAddress', 'glXGetProcAddressARB', 'wglGetProcAddress'):
515 if_ = 'if'
516 for gremedy_function in self.gremedy_functions:
517 print ' %s (strcmp("%s", (const char *)%s) == 0) {' % (if_, gremedy_function, function.args[0].name)
518 print ' __result = (%s)&%s;' % (function.type, gremedy_function)
519 print ' }'
520 if_ = 'else if'
521 print ' else {'
522 Tracer.dispatch_function(self, function)
523 print ' }'
José Fonseca1b3d3752011-07-15 10:15:19 +0100524 return
525
José Fonsecaa08d2752011-08-25 13:26:43 +0100526 # Override GL extensions
527 if function.name in ('glGetString', 'glGetIntegerv', 'glGetStringi'):
528 Tracer.dispatch_function(self, function, prefix = 'gltrace::__', suffix = '_override')
529 return
530
José Fonseca91492d22011-05-23 21:20:31 +0100531 Tracer.dispatch_function(self, function)
532
José Fonseca73373602011-05-20 17:45:26 +0100533 def emit_memcpy(self, dest, src, length):
José Fonseca0ad465c2011-08-24 16:58:13 +0100534 print ' unsigned __call = Trace::localWriter.beginEnter(&__memcpy_sig);'
535 print ' Trace::localWriter.beginArg(0);'
536 print ' Trace::localWriter.writeOpaque(%s);' % dest
537 print ' Trace::localWriter.endArg();'
538 print ' Trace::localWriter.beginArg(1);'
539 print ' Trace::localWriter.writeBlob(%s, %s);' % (src, length)
540 print ' Trace::localWriter.endArg();'
541 print ' Trace::localWriter.beginArg(2);'
542 print ' Trace::localWriter.writeUInt(%s);' % length
543 print ' Trace::localWriter.endArg();'
544 print ' Trace::localWriter.endEnter();'
545 print ' Trace::localWriter.beginLeave(__call);'
546 print ' Trace::localWriter.endLeave();'
José Fonseca867b1b72011-04-24 11:58:04 +0100547
548 buffer_targets = [
549 'ARRAY_BUFFER',
550 'ELEMENT_ARRAY_BUFFER',
551 'PIXEL_PACK_BUFFER',
552 'PIXEL_UNPACK_BUFFER',
553 ]
554
555 def wrap_ret(self, function, instance):
556 Tracer.wrap_ret(self, function, instance)
José Fonseca1b3d3752011-07-15 10:15:19 +0100557
José Fonseca867b1b72011-04-24 11:58:04 +0100558
559 if function.name in ('glMapBuffer', 'glMapBufferARB'):
560 print ' struct buffer_mapping *mapping = get_buffer_mapping(target);'
561 print ' if (mapping) {'
562 print ' mapping->map = %s;' % (instance)
563 print ' mapping->length = 0;'
564 print ' __glGetBufferParameteriv(target, GL_BUFFER_SIZE, &mapping->length);'
565 print ' mapping->write = (access != GL_READ_ONLY);'
José Fonseca73373602011-05-20 17:45:26 +0100566 print ' mapping->explicit_flush = false;'
José Fonseca867b1b72011-04-24 11:58:04 +0100567 print ' }'
568
569 if function.name == 'glMapBufferRange':
570 print ' struct buffer_mapping *mapping = get_buffer_mapping(target);'
571 print ' if (mapping) {'
572 print ' mapping->map = %s;' % (instance)
573 print ' mapping->length = length;'
574 print ' mapping->write = access & GL_MAP_WRITE_BIT;'
José Fonseca73373602011-05-20 17:45:26 +0100575 print ' mapping->explicit_flush = access & GL_MAP_FLUSH_EXPLICIT_BIT;'
José Fonseca867b1b72011-04-24 11:58:04 +0100576 print ' }'
José Fonseca669b1222011-02-20 09:05:10 +0000577
José Fonsecac9f12232011-03-25 20:07:42 +0000578 boolean_names = [
579 'GL_FALSE',
580 'GL_TRUE',
581 ]
582
583 def gl_boolean(self, value):
584 return self.boolean_names[int(bool(value))]
585
José Fonsecac29f4f12011-06-11 12:19:05 +0100586 # Names of the functions that unpack from a pixel buffer object. See the
587 # ARB_pixel_buffer_object specification.
José Fonsecae97bab92011-06-02 23:15:11 +0100588 unpack_function_names = set([
589 'glBitmap',
José Fonsecac29f4f12011-06-11 12:19:05 +0100590 'glColorSubTable',
591 'glColorTable',
592 'glCompressedTexImage1D',
593 'glCompressedTexImage2D',
594 'glCompressedTexImage3D',
595 'glCompressedTexSubImage1D',
596 'glCompressedTexSubImage2D',
597 'glCompressedTexSubImage3D',
598 'glConvolutionFilter1D',
599 'glConvolutionFilter2D',
José Fonsecae97bab92011-06-02 23:15:11 +0100600 'glDrawPixels',
601 'glMultiTexImage1DEXT',
602 'glMultiTexImage2DEXT',
603 'glMultiTexImage3DEXT',
604 'glMultiTexSubImage1DEXT',
605 'glMultiTexSubImage2DEXT',
606 'glMultiTexSubImage3DEXT',
José Fonsecac29f4f12011-06-11 12:19:05 +0100607 'glPixelMapfv',
608 'glPixelMapuiv',
609 'glPixelMapusv',
José Fonsecae97bab92011-06-02 23:15:11 +0100610 'glPolygonStipple',
José Fonsecac29f4f12011-06-11 12:19:05 +0100611 'glSeparableFilter2D',
José Fonsecae97bab92011-06-02 23:15:11 +0100612 'glTexImage1D',
613 'glTexImage1DEXT',
614 'glTexImage2D',
615 'glTexImage2DEXT',
616 'glTexImage3D',
617 'glTexImage3DEXT',
618 'glTexSubImage1D',
619 'glTexSubImage1DEXT',
620 'glTexSubImage2D',
621 'glTexSubImage2DEXT',
622 'glTexSubImage3D',
623 'glTexSubImage3DEXT',
624 'glTextureImage1DEXT',
625 'glTextureImage2DEXT',
626 'glTextureImage3DEXT',
627 'glTextureSubImage1DEXT',
628 'glTextureSubImage2DEXT',
629 'glTextureSubImage3DEXT',
630 ])
631
José Fonseca99221832011-03-22 22:15:46 +0000632 def dump_arg_instance(self, function, arg):
633 if function.name in self.draw_function_names and arg.name == 'indices':
José Fonseca8a6c6cb2011-03-23 16:44:30 +0000634 print ' GLint __element_array_buffer = 0;'
635 print ' __glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &__element_array_buffer);'
636 print ' if (!__element_array_buffer) {'
José Fonseca5c749e32011-05-09 11:11:37 +0100637 if isinstance(arg.type, stdapi.Array):
José Fonseca0ad465c2011-08-24 16:58:13 +0100638 print ' Trace::localWriter.beginArray(%s);' % arg.type.length
José Fonseca5c749e32011-05-09 11:11:37 +0100639 print ' for(GLsizei i = 0; i < %s; ++i) {' % arg.type.length
José Fonseca0ad465c2011-08-24 16:58:13 +0100640 print ' Trace::localWriter.beginElement();'
641 print ' Trace::localWriter.writeBlob(%s[i], count[i]*__gl_type_size(type));' % (arg.name)
642 print ' Trace::localWriter.endElement();'
José Fonseca5c749e32011-05-09 11:11:37 +0100643 print ' }'
José Fonseca0ad465c2011-08-24 16:58:13 +0100644 print ' Trace::localWriter.endArray();'
José Fonseca5c749e32011-05-09 11:11:37 +0100645 else:
José Fonseca0ad465c2011-08-24 16:58:13 +0100646 print ' Trace::localWriter.writeBlob(%s, count*__gl_type_size(type));' % (arg.name)
José Fonseca8a6c6cb2011-03-23 16:44:30 +0000647 print ' } else {'
José Fonseca5c749e32011-05-09 11:11:37 +0100648 Tracer.dump_arg_instance(self, function, arg)
José Fonseca8a6c6cb2011-03-23 16:44:30 +0000649 print ' }'
650 return
651
José Fonsecae97bab92011-06-02 23:15:11 +0100652 # Recognize offsets instead of blobs when a PBO is bound
653 if function.name in self.unpack_function_names \
654 and (isinstance(arg.type, stdapi.Blob) \
655 or (isinstance(arg.type, stdapi.Const) \
656 and isinstance(arg.type.type, stdapi.Blob))):
José Fonsecac29f4f12011-06-11 12:19:05 +0100657 print ' {'
658 print ' GLint __unpack_buffer = 0;'
659 print ' __glGetIntegerv(GL_PIXEL_UNPACK_BUFFER_BINDING, &__unpack_buffer);'
660 print ' if (__unpack_buffer) {'
José Fonseca0ad465c2011-08-24 16:58:13 +0100661 print ' Trace::localWriter.writeOpaque(%s);' % arg.name
José Fonsecac29f4f12011-06-11 12:19:05 +0100662 print ' } else {'
José Fonsecae97bab92011-06-02 23:15:11 +0100663 Tracer.dump_arg_instance(self, function, arg)
José Fonsecac29f4f12011-06-11 12:19:05 +0100664 print ' }'
José Fonsecae97bab92011-06-02 23:15:11 +0100665 print ' }'
666 return
667
José Fonsecaa3f89ae2011-04-26 08:50:32 +0100668 # Several GL state functions take GLenum symbolic names as
669 # integer/floats; so dump the symbolic name whenever possible
José Fonseca3bcb33c2011-05-27 20:14:31 +0100670 if function.name.startswith('gl') \
671 and arg.type in (glapi.GLint, glapi.GLfloat) \
672 and arg.name == 'param':
José Fonsecaa3f89ae2011-04-26 08:50:32 +0100673 assert arg.index > 0
674 assert function.args[arg.index - 1].name == 'pname'
675 assert function.args[arg.index - 1].type == glapi.GLenum
676 print ' if (is_symbolic_pname(pname) && is_symbolic_param(%s)) {' % arg.name
677 dump_instance(glapi.GLenum, arg.name)
678 print ' } else {'
679 Tracer.dump_arg_instance(self, function, arg)
680 print ' }'
681 return
682
José Fonseca8a6c6cb2011-03-23 16:44:30 +0000683 Tracer.dump_arg_instance(self, function, arg)
José Fonseca99221832011-03-22 22:15:46 +0000684
José Fonseca4c938c22011-04-30 22:44:38 +0100685 def footer(self, api):
686 Tracer.footer(self, api)
José Fonseca669b1222011-02-20 09:05:10 +0000687
José Fonseca4c938c22011-04-30 22:44:38 +0100688 # A simple state tracker to track the pointer values
José Fonseca669b1222011-02-20 09:05:10 +0000689 # update the state
José Fonseca8a6c6cb2011-03-23 16:44:30 +0000690 print 'static void __trace_user_arrays(GLuint maxindex)'
José Fonseca669b1222011-02-20 09:05:10 +0000691 print '{'
José Fonseca1a2fdd22011-04-01 00:55:09 +0100692
José Fonseca99221832011-03-22 22:15:46 +0000693 for camelcase_name, uppercase_name in self.arrays:
694 function_name = 'gl%sPointer' % camelcase_name
695 enable_name = 'GL_%s_ARRAY' % uppercase_name
696 binding_name = 'GL_%s_ARRAY_BUFFER_BINDING' % uppercase_name
José Fonseca14c21bc2011-02-20 23:32:22 +0000697 function = api.get_function_by_name(function_name)
José Fonseca99221832011-03-22 22:15:46 +0000698
699 print ' // %s' % function.name
José Fonsecafb6744f2011-04-15 11:18:37 +0100700 self.array_trace_prolog(api, uppercase_name)
701 self.array_prolog(api, uppercase_name)
702 print ' if (__glIsEnabled(%s)) {' % enable_name
José Fonseca7f5163e2011-03-31 23:37:26 +0100703 print ' GLint __binding = 0;'
704 print ' __glGetIntegerv(%s, &__binding);' % binding_name
705 print ' if (!__binding) {'
José Fonseca99221832011-03-22 22:15:46 +0000706
707 # Get the arguments via glGet*
708 for arg in function.args:
709 arg_get_enum = 'GL_%s_ARRAY_%s' % (uppercase_name, arg.name.upper())
710 arg_get_function, arg_type = TypeGetter().visit(arg.type)
José Fonseca7f5163e2011-03-31 23:37:26 +0100711 print ' %s %s = 0;' % (arg_type, arg.name)
712 print ' __%s(%s, &%s);' % (arg_get_function, arg_get_enum, arg.name)
José Fonseca99221832011-03-22 22:15:46 +0000713
714 arg_names = ', '.join([arg.name for arg in function.args[:-1]])
José Fonseca7f5163e2011-03-31 23:37:26 +0100715 print ' size_t __size = __%s_size(%s, maxindex);' % (function.name, arg_names)
José Fonseca99221832011-03-22 22:15:46 +0000716
717 # Emit a fake function
José Fonsecafb6744f2011-04-15 11:18:37 +0100718 self.array_trace_intermezzo(api, uppercase_name)
José Fonseca0ad465c2011-08-24 16:58:13 +0100719 print ' unsigned __call = Trace::localWriter.beginEnter(&__%s_sig);' % (function.name,)
José Fonseca669b1222011-02-20 09:05:10 +0000720 for arg in function.args:
721 assert not arg.output
José Fonseca0ad465c2011-08-24 16:58:13 +0100722 print ' Trace::localWriter.beginArg(%u);' % (arg.index,)
José Fonseca14c21bc2011-02-20 23:32:22 +0000723 if arg.name != 'pointer':
José Fonseca99221832011-03-22 22:15:46 +0000724 dump_instance(arg.type, arg.name)
José Fonseca14c21bc2011-02-20 23:32:22 +0000725 else:
José Fonseca0ad465c2011-08-24 16:58:13 +0100726 print ' Trace::localWriter.writeBlob((const void *)%s, __size);' % (arg.name)
727 print ' Trace::localWriter.endArg();'
José Fonseca99221832011-03-22 22:15:46 +0000728
José Fonseca0ad465c2011-08-24 16:58:13 +0100729 print ' Trace::localWriter.endEnter();'
730 print ' Trace::localWriter.beginLeave(__call);'
731 print ' Trace::localWriter.endLeave();'
José Fonseca99221832011-03-22 22:15:46 +0000732 print ' }'
José Fonseca669b1222011-02-20 09:05:10 +0000733 print ' }'
José Fonsecafb6744f2011-04-15 11:18:37 +0100734 self.array_epilog(api, uppercase_name)
735 self.array_trace_epilog(api, uppercase_name)
José Fonseca99221832011-03-22 22:15:46 +0000736 print
José Fonseca1a2fdd22011-04-01 00:55:09 +0100737
José Fonseca1601c412011-05-10 10:38:19 +0100738 # Samething, but for glVertexAttribPointer*
739 #
740 # Some variants of glVertexAttribPointer alias conventional and generic attributes:
741 # - glVertexAttribPointer: no
742 # - glVertexAttribPointerARB: implementation dependent
743 # - glVertexAttribPointerNV: yes
744 #
745 # This means that the implementations of these functions do not always
746 # alias, and they need to be considered independently.
747 #
José Fonseca5a568a92011-06-29 16:43:36 +0100748 print ' vertex_attrib __vertex_attrib = __get_vertex_attrib();'
749 print
750 for suffix in ['', 'ARB', 'NV']:
751 if suffix:
José Fonsecad94aaac2011-06-28 20:50:49 +0100752 SUFFIX = '_' + suffix
José Fonsecad94aaac2011-06-28 20:50:49 +0100753 else:
José Fonseca5a568a92011-06-29 16:43:36 +0100754 SUFFIX = suffix
José Fonseca1601c412011-05-10 10:38:19 +0100755 function_name = 'glVertexAttribPointer' + suffix
José Fonseca5a568a92011-06-29 16:43:36 +0100756 print ' // %s' % function_name
757 print ' if (__vertex_attrib == VERTEX_ATTRIB%s) {' % SUFFIX
758 if suffix == 'NV':
759 print ' GLint __max_vertex_attribs = 16;'
760 else:
761 print ' GLint __max_vertex_attribs = 0;'
762 print ' __glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &__max_vertex_attribs);'
763 print ' for (GLint index = 0; index < __max_vertex_attribs; ++index) {'
764 print ' GLint __enabled = 0;'
765 if suffix == 'NV':
766 print ' __glGetIntegerv(GL_VERTEX_ATTRIB_ARRAY0_NV + index, &__enabled);'
767 else:
768 print ' __glGetVertexAttribiv%s(index, GL_VERTEX_ATTRIB_ARRAY_ENABLED%s, &__enabled);' % (suffix, SUFFIX)
769 print ' if (__enabled) {'
770 print ' GLint __binding = 0;'
771 if suffix != 'NV':
772 # It doesn't seem possible to use VBOs with NV_vertex_program.
773 print ' __glGetVertexAttribiv%s(index, GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING%s, &__binding);' % (suffix, SUFFIX)
774 print ' if (!__binding) {'
José Fonseca1a2fdd22011-04-01 00:55:09 +0100775
José Fonseca1601c412011-05-10 10:38:19 +0100776 function = api.get_function_by_name(function_name)
José Fonseca1a2fdd22011-04-01 00:55:09 +0100777
José Fonseca1601c412011-05-10 10:38:19 +0100778 # Get the arguments via glGet*
779 for arg in function.args[1:]:
José Fonseca5a568a92011-06-29 16:43:36 +0100780 if suffix == 'NV':
781 arg_get_enum = 'GL_ATTRIB_ARRAY_%s%s' % (arg.name.upper(), SUFFIX)
782 else:
783 arg_get_enum = 'GL_VERTEX_ATTRIB_ARRAY_%s%s' % (arg.name.upper(), SUFFIX)
José Fonsecac493e3e2011-06-29 12:57:06 +0100784 arg_get_function, arg_type = TypeGetter('glGetVertexAttrib', False, suffix).visit(arg.type)
José Fonseca5a568a92011-06-29 16:43:36 +0100785 print ' %s %s = 0;' % (arg_type, arg.name)
786 print ' __%s(index, %s, &%s);' % (arg_get_function, arg_get_enum, arg.name)
José Fonseca1601c412011-05-10 10:38:19 +0100787
788 arg_names = ', '.join([arg.name for arg in function.args[1:-1]])
José Fonseca5a568a92011-06-29 16:43:36 +0100789 print ' size_t __size = __%s_size(%s, maxindex);' % (function.name, arg_names)
José Fonseca1a2fdd22011-04-01 00:55:09 +0100790
José Fonseca1601c412011-05-10 10:38:19 +0100791 # Emit a fake function
José Fonseca0ad465c2011-08-24 16:58:13 +0100792 print ' unsigned __call = Trace::localWriter.beginEnter(&__%s_sig);' % (function.name,)
José Fonseca1601c412011-05-10 10:38:19 +0100793 for arg in function.args:
794 assert not arg.output
José Fonseca0ad465c2011-08-24 16:58:13 +0100795 print ' Trace::localWriter.beginArg(%u);' % (arg.index,)
José Fonseca1601c412011-05-10 10:38:19 +0100796 if arg.name != 'pointer':
797 dump_instance(arg.type, arg.name)
798 else:
José Fonseca0ad465c2011-08-24 16:58:13 +0100799 print ' Trace::localWriter.writeBlob((const void *)%s, __size);' % (arg.name)
800 print ' Trace::localWriter.endArg();'
José Fonseca1601c412011-05-10 10:38:19 +0100801
José Fonseca0ad465c2011-08-24 16:58:13 +0100802 print ' Trace::localWriter.endEnter();'
803 print ' Trace::localWriter.beginLeave(__call);'
804 print ' Trace::localWriter.endLeave();'
José Fonseca1601c412011-05-10 10:38:19 +0100805 print ' }'
806 print ' }'
807 print ' }'
808 print ' }'
809 print
José Fonseca1a2fdd22011-04-01 00:55:09 +0100810
José Fonseca669b1222011-02-20 09:05:10 +0000811 print '}'
812 print
813
José Fonsecafb6744f2011-04-15 11:18:37 +0100814 #
815 # Hooks for glTexCoordPointer, which is identical to the other array
816 # pointers except the fact that it is indexed by glClientActiveTexture.
817 #
818
819 def array_prolog(self, api, uppercase_name):
820 if uppercase_name == 'TEXTURE_COORD':
821 print ' GLint client_active_texture = 0;'
822 print ' __glGetIntegerv(GL_CLIENT_ACTIVE_TEXTURE, &client_active_texture);'
823 print ' GLint max_texture_coords = 0;'
824 print ' __glGetIntegerv(GL_MAX_TEXTURE_COORDS, &max_texture_coords);'
825 print ' for (GLint unit = 0; unit < max_texture_coords; ++unit) {'
José Fonseca7525e6f2011-09-28 09:04:56 +0100826 print ' GLint texture = GL_TEXTURE0 + unit;'
José Fonsecafb6744f2011-04-15 11:18:37 +0100827 print ' __glClientActiveTexture(texture);'
828
829 def array_trace_prolog(self, api, uppercase_name):
830 if uppercase_name == 'TEXTURE_COORD':
831 print ' bool client_active_texture_dirty = false;'
832
833 def array_epilog(self, api, uppercase_name):
834 if uppercase_name == 'TEXTURE_COORD':
835 print ' }'
836 self.array_cleanup(api, uppercase_name)
837
838 def array_cleanup(self, api, uppercase_name):
839 if uppercase_name == 'TEXTURE_COORD':
840 print ' __glClientActiveTexture(client_active_texture);'
841
842 def array_trace_intermezzo(self, api, uppercase_name):
843 if uppercase_name == 'TEXTURE_COORD':
844 print ' if (texture != client_active_texture || client_active_texture_dirty) {'
845 print ' client_active_texture_dirty = true;'
846 self.fake_glClientActiveTexture_call(api, "texture");
847 print ' }'
848
849 def array_trace_epilog(self, api, uppercase_name):
850 if uppercase_name == 'TEXTURE_COORD':
851 print ' if (client_active_texture_dirty) {'
852 self.fake_glClientActiveTexture_call(api, "client_active_texture");
853 print ' }'
854
855 def fake_glClientActiveTexture_call(self, api, texture):
856 function = api.get_function_by_name('glClientActiveTexture')
857 self.fake_call(function, [texture])
858
859 def fake_call(self, function, args):
José Fonseca0ad465c2011-08-24 16:58:13 +0100860 print ' unsigned __fake_call = Trace::localWriter.beginEnter(&__%s_sig);' % (function.name,)
José Fonsecafb6744f2011-04-15 11:18:37 +0100861 for arg, instance in zip(function.args, args):
862 assert not arg.output
José Fonseca0ad465c2011-08-24 16:58:13 +0100863 print ' Trace::localWriter.beginArg(%u);' % (arg.index,)
José Fonsecafb6744f2011-04-15 11:18:37 +0100864 dump_instance(arg.type, instance)
José Fonseca0ad465c2011-08-24 16:58:13 +0100865 print ' Trace::localWriter.endArg();'
866 print ' Trace::localWriter.endEnter();'
867 print ' Trace::localWriter.beginLeave(__fake_call);'
868 print ' Trace::localWriter.endLeave();'
José Fonsecafb6744f2011-04-15 11:18:37 +0100869
870
871
872
873
José Fonseca669b1222011-02-20 09:05:10 +0000874
875
876
877
878
879