blob: 5933b9ecd7e6a9f8338c994aa396faa4c2baac5f [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) {'
José Fonseca06e85192011-10-16 14:15:36 +0100236 print ' switch (target) {'
José Fonseca867b1b72011-04-24 11:58:04 +0100237 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
José Fonsecaa3f89ae2011-04-26 08:50:32 +0100247 # Generate a helper function to determine whether a parameter name
248 # refers to a symbolic value or not
249 print 'static bool'
250 print 'is_symbolic_pname(GLenum pname) {'
José Fonseca06e85192011-10-16 14:15:36 +0100251 print ' switch (pname) {'
José Fonseca5ea91872011-05-04 09:41:55 +0100252 for function, type, count, name in glparams.parameters:
José Fonsecaa3f89ae2011-04-26 08:50:32 +0100253 if type is glapi.GLenum:
José Fonseca4c938c22011-04-30 22:44:38 +0100254 print ' case %s:' % name
255 print ' return true;'
256 print ' default:'
257 print ' return false;'
José Fonsecaa3f89ae2011-04-26 08:50:32 +0100258 print ' }'
259 print '}'
260 print
261
262 # Generate a helper function to determine whether a parameter value is
263 # potentially symbolic or not; i.e., if the value can be represented in
264 # an enum or not
265 print 'template<class T>'
266 print 'static inline bool'
267 print 'is_symbolic_param(T param) {'
268 print ' return static_cast<T>(static_cast<GLenum>(param)) == param;'
269 print '}'
270 print
José Fonseca4c938c22011-04-30 22:44:38 +0100271
272 # Generate a helper function to know how many elements a parameter has
273 print 'static size_t'
José Fonsecaf4aca5d2011-05-08 08:29:30 +0100274 print '__gl_param_size(GLenum pname) {'
José Fonseca06e85192011-10-16 14:15:36 +0100275 print ' switch (pname) {'
José Fonseca5ea91872011-05-04 09:41:55 +0100276 for function, type, count, name in glparams.parameters:
José Fonseca4c938c22011-04-30 22:44:38 +0100277 if type is not None:
278 print ' case %s: return %u;' % (name, count)
279 print ' case GL_COMPRESSED_TEXTURE_FORMATS: {'
280 print ' GLint num_compressed_texture_formats = 0;'
281 print ' __glGetIntegerv(GL_NUM_COMPRESSED_TEXTURE_FORMATS, &num_compressed_texture_formats);'
282 print ' return num_compressed_texture_formats;'
283 print ' }'
284 print ' default:'
José Fonsecacbd225f2011-06-09 00:07:18 +0100285 print r' OS::DebugMessage("apitrace: warning: %s: unknown GLenum 0x%04X\n", __FUNCTION__, pname);'
José Fonseca4c938c22011-04-30 22:44:38 +0100286 print ' return 1;'
287 print ' }'
288 print '}'
289 print
290
José Fonseca99221832011-03-22 22:15:46 +0000291 array_pointer_function_names = set((
292 "glVertexPointer",
293 "glNormalPointer",
294 "glColorPointer",
295 "glIndexPointer",
296 "glTexCoordPointer",
297 "glEdgeFlagPointer",
298 "glFogCoordPointer",
299 "glSecondaryColorPointer",
José Fonseca7f5163e2011-03-31 23:37:26 +0100300
José Fonsecaac5285b2011-05-04 11:09:08 +0100301 "glInterleavedArrays",
302
José Fonseca7e0bfd92011-04-30 23:09:03 +0100303 "glVertexPointerEXT",
304 "glNormalPointerEXT",
305 "glColorPointerEXT",
306 "glIndexPointerEXT",
307 "glTexCoordPointerEXT",
308 "glEdgeFlagPointerEXT",
309 "glFogCoordPointerEXT",
310 "glSecondaryColorPointerEXT",
José Fonseca99221832011-03-22 22:15:46 +0000311
José Fonseca7f5163e2011-03-31 23:37:26 +0100312 "glVertexAttribPointer",
313 "glVertexAttribPointerARB",
314 "glVertexAttribPointerNV",
José Fonsecaac5285b2011-05-04 11:09:08 +0100315 "glVertexAttribIPointer",
316 "glVertexAttribIPointerEXT",
José Fonseca7f5163e2011-03-31 23:37:26 +0100317 "glVertexAttribLPointer",
318 "glVertexAttribLPointerEXT",
José Fonseca99221832011-03-22 22:15:46 +0000319
320 #"glMatrixIndexPointerARB",
321 ))
322
323 draw_function_names = set((
324 'glDrawArrays',
325 'glDrawElements',
326 'glDrawRangeElements',
José Fonseca5c749e32011-05-09 11:11:37 +0100327 'glMultiDrawArrays',
328 'glMultiDrawElements',
329 'glDrawArraysInstanced',
José Fonsecaff8848b2011-10-09 01:04:17 +0100330 "glDrawArraysInstancedBaseInstance",
José Fonseca5c749e32011-05-09 11:11:37 +0100331 'glDrawElementsInstanced',
332 'glDrawArraysInstancedARB',
333 'glDrawElementsInstancedARB',
334 'glDrawElementsBaseVertex',
335 'glDrawRangeElementsBaseVertex',
336 'glDrawElementsInstancedBaseVertex',
José Fonsecaff8848b2011-10-09 01:04:17 +0100337 "glDrawElementsInstancedBaseInstance",
338 "glDrawElementsInstancedBaseVertexBaseInstance",
José Fonseca5c749e32011-05-09 11:11:37 +0100339 'glMultiDrawElementsBaseVertex',
340 'glDrawArraysIndirect',
341 'glDrawElementsIndirect',
342 'glDrawArraysEXT',
José Fonseca7e0bfd92011-04-30 23:09:03 +0100343 'glDrawRangeElementsEXT',
José Fonseca5c749e32011-05-09 11:11:37 +0100344 'glDrawRangeElementsEXT_size',
345 'glMultiDrawArraysEXT',
346 'glMultiDrawElementsEXT',
347 'glMultiModeDrawArraysIBM',
348 'glMultiModeDrawElementsIBM',
349 'glDrawArraysInstancedEXT',
350 'glDrawElementsInstancedEXT',
José Fonseca99221832011-03-22 22:15:46 +0000351 ))
352
José Fonsecac9f12232011-03-25 20:07:42 +0000353 interleaved_formats = [
354 'GL_V2F',
355 'GL_V3F',
356 'GL_C4UB_V2F',
357 'GL_C4UB_V3F',
358 'GL_C3F_V3F',
359 'GL_N3F_V3F',
360 'GL_C4F_N3F_V3F',
361 'GL_T2F_V3F',
362 'GL_T4F_V4F',
363 'GL_T2F_C4UB_V3F',
364 'GL_T2F_C3F_V3F',
365 'GL_T2F_N3F_V3F',
366 'GL_T2F_C4F_N3F_V3F',
367 'GL_T4F_C4F_N3F_V4F',
368 ]
369
José Fonseca14c21bc2011-02-20 23:32:22 +0000370 def trace_function_impl_body(self, function):
José Fonseca8a6c6cb2011-03-23 16:44:30 +0000371 # Defer tracing of user array pointers...
José Fonseca99221832011-03-22 22:15:46 +0000372 if function.name in self.array_pointer_function_names:
373 print ' GLint __array_buffer = 0;'
374 print ' __glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &__array_buffer);'
375 print ' if (!__array_buffer) {'
José Fonseca25ebe542011-04-24 10:08:22 +0100376 print ' __user_arrays = true;'
José Fonseca5a568a92011-06-29 16:43:36 +0100377 if function.name == "glVertexAttribPointerARB":
378 print ' __user_arrays_arb = true;'
379 if function.name == "glVertexAttribPointerNV":
380 print ' __user_arrays_nv = true;'
José Fonseca14c21bc2011-02-20 23:32:22 +0000381 self.dispatch_function(function)
José Fonsecaac5285b2011-05-04 11:09:08 +0100382
383 # And also break down glInterleavedArrays into the individual calls
384 if function.name == 'glInterleavedArrays':
385 print
386
387 # Initialize the enable flags
388 for camelcase_name, uppercase_name in self.arrays:
389 flag_name = '__' + uppercase_name.lower()
390 print ' GLboolean %s = GL_FALSE;' % flag_name
391 print
392
393 # Switch for the interleaved formats
394 print ' switch (format) {'
395 for format in self.interleaved_formats:
396 print ' case %s:' % format
397 for camelcase_name, uppercase_name in self.arrays:
398 flag_name = '__' + uppercase_name.lower()
399 if format.find('_' + uppercase_name[0]) >= 0:
400 print ' %s = GL_TRUE;' % flag_name
401 print ' break;'
402 print ' default:'
403 print ' return;'
404 print ' }'
405 print
406
407 # Emit fake glEnableClientState/glDisableClientState flags
408 for camelcase_name, uppercase_name in self.arrays:
409 flag_name = '__' + uppercase_name.lower()
410 enable_name = 'GL_%s_ARRAY' % uppercase_name
411
412 # Emit a fake function
413 print ' {'
414 print ' static const Trace::FunctionSig &__sig = %s ? __glEnableClientState_sig : __glDisableClientState_sig;' % flag_name
José Fonseca0ad465c2011-08-24 16:58:13 +0100415 print ' unsigned __call = Trace::localWriter.beginEnter(&__sig);'
416 print ' Trace::localWriter.beginArg(0);'
José Fonsecaac5285b2011-05-04 11:09:08 +0100417 dump_instance(glapi.GLenum, enable_name)
José Fonseca0ad465c2011-08-24 16:58:13 +0100418 print ' Trace::localWriter.endArg();'
419 print ' Trace::localWriter.endEnter();'
420 print ' Trace::localWriter.beginLeave(__call);'
421 print ' Trace::localWriter.endLeave();'
José Fonsecaac5285b2011-05-04 11:09:08 +0100422 print ' }'
423
José Fonseca99221832011-03-22 22:15:46 +0000424 print ' return;'
425 print ' }'
José Fonseca14c21bc2011-02-20 23:32:22 +0000426
José Fonseca8a6c6cb2011-03-23 16:44:30 +0000427 # ... to the draw calls
José Fonseca99221832011-03-22 22:15:46 +0000428 if function.name in self.draw_function_names:
José Fonseca8a6c6cb2011-03-23 16:44:30 +0000429 print ' if (__need_user_arrays()) {'
José Fonseca99221832011-03-22 22:15:46 +0000430 arg_names = ', '.join([arg.name for arg in function.args[1:]])
José Fonseca8a6c6cb2011-03-23 16:44:30 +0000431 print ' GLuint maxindex = __%s_maxindex(%s);' % (function.name, arg_names)
432 print ' __trace_user_arrays(maxindex);'
433 print ' }'
José Fonseca14c21bc2011-02-20 23:32:22 +0000434
José Fonseca73373602011-05-20 17:45:26 +0100435 # Emit a fake memcpy on buffer uploads
436 if function.name in ('glUnmapBuffer', 'glUnmapBufferARB', ):
José Fonseca867b1b72011-04-24 11:58:04 +0100437 print ' struct buffer_mapping *mapping = get_buffer_mapping(target);'
José Fonseca73373602011-05-20 17:45:26 +0100438 print ' if (mapping && mapping->write && !mapping->explicit_flush) {'
439 self.emit_memcpy('mapping->map', 'mapping->map', 'mapping->length')
José Fonseca867b1b72011-04-24 11:58:04 +0100440 print ' }'
José Fonseca73373602011-05-20 17:45:26 +0100441 if function.name in ('glFlushMappedBufferRange', 'glFlushMappedBufferRangeAPPLE'):
José Fonseca73373602011-05-20 17:45:26 +0100442 print ' struct buffer_mapping *mapping = get_buffer_mapping(target);'
443 print ' if (mapping) {'
444 if function.name.endswith('APPLE'):
445 print ' GLsizeiptr length = size;'
446 print ' mapping->explicit_flush = true;'
447 print ' //assert(offset + length <= mapping->length);'
José Fonseca46a48392011-10-14 11:34:27 +0100448 self.emit_memcpy('(char *)mapping->map + offset', '(const char *)mapping->map + offset', 'length')
José Fonseca73373602011-05-20 17:45:26 +0100449 print ' }'
450 # FIXME: glFlushMappedNamedBufferRangeEXT
José Fonseca867b1b72011-04-24 11:58:04 +0100451
José Fonseca91492d22011-05-23 21:20:31 +0100452 # Don't leave vertex attrib locations to chance. Instead emit fake
453 # glBindAttribLocation calls to ensure that the same locations will be
454 # used when retracing. Trying to remap locations after the fact would
455 # be an herculian task given that vertex attrib locations appear in
456 # many entry-points, including non-shader related ones.
457 if function.name == 'glLinkProgram':
458 Tracer.dispatch_function(self, function)
459 print ' GLint active_attributes = 0;'
460 print ' __glGetProgramiv(program, GL_ACTIVE_ATTRIBUTES, &active_attributes);'
José Fonseca7525e6f2011-09-28 09:04:56 +0100461 print ' for (GLint attrib = 0; attrib < active_attributes; ++attrib) {'
José Fonseca91492d22011-05-23 21:20:31 +0100462 print ' GLint size = 0;'
463 print ' GLenum type = 0;'
464 print ' GLchar name[256];'
465 # TODO: Use ACTIVE_ATTRIBUTE_MAX_LENGTH instead of 256
466 print ' __glGetActiveAttrib(program, attrib, sizeof name, NULL, &size, &type, name);'
José Fonseca2a794f52011-05-26 20:54:29 +0100467 print " if (name[0] != 'g' || name[1] != 'l' || name[2] != '_') {"
468 print ' GLint location = __glGetAttribLocation(program, name);'
469 print ' if (location >= 0) {'
José Fonseca91492d22011-05-23 21:20:31 +0100470 bind_function = glapi.glapi.get_function_by_name('glBindAttribLocation')
471 self.fake_call(bind_function, ['program', 'location', 'name'])
José Fonseca2a794f52011-05-26 20:54:29 +0100472 print ' }'
José Fonseca91492d22011-05-23 21:20:31 +0100473 print ' }'
474 print ' }'
475 if function.name == 'glLinkProgramARB':
476 Tracer.dispatch_function(self, function)
477 print ' GLint active_attributes = 0;'
478 print ' __glGetObjectParameterivARB(programObj, GL_OBJECT_ACTIVE_ATTRIBUTES_ARB, &active_attributes);'
José Fonseca7525e6f2011-09-28 09:04:56 +0100479 print ' for (GLint attrib = 0; attrib < active_attributes; ++attrib) {'
José Fonseca91492d22011-05-23 21:20:31 +0100480 print ' GLint size = 0;'
481 print ' GLenum type = 0;'
482 print ' GLcharARB name[256];'
483 # TODO: Use ACTIVE_ATTRIBUTE_MAX_LENGTH instead of 256
484 print ' __glGetActiveAttribARB(programObj, attrib, sizeof name, NULL, &size, &type, name);'
José Fonseca2a794f52011-05-26 20:54:29 +0100485 print " if (name[0] != 'g' || name[1] != 'l' || name[2] != '_') {"
486 print ' GLint location = __glGetAttribLocationARB(programObj, name);'
487 print ' if (location >= 0) {'
José Fonseca91492d22011-05-23 21:20:31 +0100488 bind_function = glapi.glapi.get_function_by_name('glBindAttribLocationARB')
489 self.fake_call(bind_function, ['programObj', 'location', 'name'])
José Fonseca2a794f52011-05-26 20:54:29 +0100490 print ' }'
José Fonseca91492d22011-05-23 21:20:31 +0100491 print ' }'
492 print ' }'
493
José Fonseca14c21bc2011-02-20 23:32:22 +0000494 Tracer.trace_function_impl_body(self, function)
José Fonseca73373602011-05-20 17:45:26 +0100495
José Fonseca8f34d342011-07-15 20:16:40 +0100496 gremedy_functions = [
497 'glStringMarkerGREMEDY',
498 'glFrameTerminatorGREMEDY',
499 ]
500
José Fonseca91492d22011-05-23 21:20:31 +0100501 def dispatch_function(self, function):
502 if function.name in ('glLinkProgram', 'glLinkProgramARB'):
503 # These functions have been dispatched already
504 return
505
José Fonseca1b3d3752011-07-15 10:15:19 +0100506 # We implement the GREMEDY extensions, not the driver
José Fonseca8f34d342011-07-15 20:16:40 +0100507 if function.name in self.gremedy_functions:
508 return
509
510 if function.name in ('glXGetProcAddress', 'glXGetProcAddressARB', 'wglGetProcAddress'):
511 if_ = 'if'
512 for gremedy_function in self.gremedy_functions:
513 print ' %s (strcmp("%s", (const char *)%s) == 0) {' % (if_, gremedy_function, function.args[0].name)
514 print ' __result = (%s)&%s;' % (function.type, gremedy_function)
515 print ' }'
516 if_ = 'else if'
517 print ' else {'
518 Tracer.dispatch_function(self, function)
519 print ' }'
José Fonseca1b3d3752011-07-15 10:15:19 +0100520 return
521
José Fonsecaa08d2752011-08-25 13:26:43 +0100522 # Override GL extensions
523 if function.name in ('glGetString', 'glGetIntegerv', 'glGetStringi'):
524 Tracer.dispatch_function(self, function, prefix = 'gltrace::__', suffix = '_override')
525 return
526
José Fonseca91492d22011-05-23 21:20:31 +0100527 Tracer.dispatch_function(self, function)
528
José Fonseca73373602011-05-20 17:45:26 +0100529 def emit_memcpy(self, dest, src, length):
José Fonseca46a48392011-10-14 11:34:27 +0100530 print ' unsigned __call = Trace::localWriter.beginEnter(&Trace::memcpy_sig);'
José Fonseca0ad465c2011-08-24 16:58:13 +0100531 print ' Trace::localWriter.beginArg(0);'
532 print ' Trace::localWriter.writeOpaque(%s);' % dest
533 print ' Trace::localWriter.endArg();'
534 print ' Trace::localWriter.beginArg(1);'
535 print ' Trace::localWriter.writeBlob(%s, %s);' % (src, length)
536 print ' Trace::localWriter.endArg();'
537 print ' Trace::localWriter.beginArg(2);'
538 print ' Trace::localWriter.writeUInt(%s);' % length
539 print ' Trace::localWriter.endArg();'
540 print ' Trace::localWriter.endEnter();'
541 print ' Trace::localWriter.beginLeave(__call);'
542 print ' Trace::localWriter.endLeave();'
José Fonseca867b1b72011-04-24 11:58:04 +0100543
544 buffer_targets = [
545 'ARRAY_BUFFER',
546 'ELEMENT_ARRAY_BUFFER',
547 'PIXEL_PACK_BUFFER',
548 'PIXEL_UNPACK_BUFFER',
549 ]
550
551 def wrap_ret(self, function, instance):
552 Tracer.wrap_ret(self, function, instance)
José Fonseca1b3d3752011-07-15 10:15:19 +0100553
José Fonseca867b1b72011-04-24 11:58:04 +0100554
555 if function.name in ('glMapBuffer', 'glMapBufferARB'):
556 print ' struct buffer_mapping *mapping = get_buffer_mapping(target);'
557 print ' if (mapping) {'
558 print ' mapping->map = %s;' % (instance)
559 print ' mapping->length = 0;'
560 print ' __glGetBufferParameteriv(target, GL_BUFFER_SIZE, &mapping->length);'
561 print ' mapping->write = (access != GL_READ_ONLY);'
José Fonseca73373602011-05-20 17:45:26 +0100562 print ' mapping->explicit_flush = false;'
José Fonseca867b1b72011-04-24 11:58:04 +0100563 print ' }'
564
565 if function.name == 'glMapBufferRange':
566 print ' struct buffer_mapping *mapping = get_buffer_mapping(target);'
567 print ' if (mapping) {'
568 print ' mapping->map = %s;' % (instance)
569 print ' mapping->length = length;'
570 print ' mapping->write = access & GL_MAP_WRITE_BIT;'
José Fonseca73373602011-05-20 17:45:26 +0100571 print ' mapping->explicit_flush = access & GL_MAP_FLUSH_EXPLICIT_BIT;'
José Fonseca867b1b72011-04-24 11:58:04 +0100572 print ' }'
José Fonseca669b1222011-02-20 09:05:10 +0000573
José Fonsecac9f12232011-03-25 20:07:42 +0000574 boolean_names = [
575 'GL_FALSE',
576 'GL_TRUE',
577 ]
578
579 def gl_boolean(self, value):
580 return self.boolean_names[int(bool(value))]
581
José Fonsecac29f4f12011-06-11 12:19:05 +0100582 # Names of the functions that unpack from a pixel buffer object. See the
583 # ARB_pixel_buffer_object specification.
José Fonsecae97bab92011-06-02 23:15:11 +0100584 unpack_function_names = set([
585 'glBitmap',
José Fonsecac29f4f12011-06-11 12:19:05 +0100586 'glColorSubTable',
587 'glColorTable',
588 'glCompressedTexImage1D',
589 'glCompressedTexImage2D',
590 'glCompressedTexImage3D',
591 'glCompressedTexSubImage1D',
592 'glCompressedTexSubImage2D',
593 'glCompressedTexSubImage3D',
594 'glConvolutionFilter1D',
595 'glConvolutionFilter2D',
José Fonsecae97bab92011-06-02 23:15:11 +0100596 'glDrawPixels',
597 'glMultiTexImage1DEXT',
598 'glMultiTexImage2DEXT',
599 'glMultiTexImage3DEXT',
600 'glMultiTexSubImage1DEXT',
601 'glMultiTexSubImage2DEXT',
602 'glMultiTexSubImage3DEXT',
José Fonsecac29f4f12011-06-11 12:19:05 +0100603 'glPixelMapfv',
604 'glPixelMapuiv',
605 'glPixelMapusv',
José Fonsecae97bab92011-06-02 23:15:11 +0100606 'glPolygonStipple',
José Fonsecac29f4f12011-06-11 12:19:05 +0100607 'glSeparableFilter2D',
José Fonsecae97bab92011-06-02 23:15:11 +0100608 'glTexImage1D',
609 'glTexImage1DEXT',
610 'glTexImage2D',
611 'glTexImage2DEXT',
612 'glTexImage3D',
613 'glTexImage3DEXT',
614 'glTexSubImage1D',
615 'glTexSubImage1DEXT',
616 'glTexSubImage2D',
617 'glTexSubImage2DEXT',
618 'glTexSubImage3D',
619 'glTexSubImage3DEXT',
620 'glTextureImage1DEXT',
621 'glTextureImage2DEXT',
622 'glTextureImage3DEXT',
623 'glTextureSubImage1DEXT',
624 'glTextureSubImage2DEXT',
625 'glTextureSubImage3DEXT',
626 ])
627
José Fonseca99221832011-03-22 22:15:46 +0000628 def dump_arg_instance(self, function, arg):
629 if function.name in self.draw_function_names and arg.name == 'indices':
José Fonseca8a6c6cb2011-03-23 16:44:30 +0000630 print ' GLint __element_array_buffer = 0;'
631 print ' __glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &__element_array_buffer);'
632 print ' if (!__element_array_buffer) {'
José Fonseca5c749e32011-05-09 11:11:37 +0100633 if isinstance(arg.type, stdapi.Array):
José Fonseca0ad465c2011-08-24 16:58:13 +0100634 print ' Trace::localWriter.beginArray(%s);' % arg.type.length
José Fonseca5c749e32011-05-09 11:11:37 +0100635 print ' for(GLsizei i = 0; i < %s; ++i) {' % arg.type.length
José Fonseca0ad465c2011-08-24 16:58:13 +0100636 print ' Trace::localWriter.beginElement();'
637 print ' Trace::localWriter.writeBlob(%s[i], count[i]*__gl_type_size(type));' % (arg.name)
638 print ' Trace::localWriter.endElement();'
José Fonseca5c749e32011-05-09 11:11:37 +0100639 print ' }'
José Fonseca0ad465c2011-08-24 16:58:13 +0100640 print ' Trace::localWriter.endArray();'
José Fonseca5c749e32011-05-09 11:11:37 +0100641 else:
José Fonseca0ad465c2011-08-24 16:58:13 +0100642 print ' Trace::localWriter.writeBlob(%s, count*__gl_type_size(type));' % (arg.name)
José Fonseca8a6c6cb2011-03-23 16:44:30 +0000643 print ' } else {'
José Fonseca5c749e32011-05-09 11:11:37 +0100644 Tracer.dump_arg_instance(self, function, arg)
José Fonseca8a6c6cb2011-03-23 16:44:30 +0000645 print ' }'
646 return
647
José Fonsecae97bab92011-06-02 23:15:11 +0100648 # Recognize offsets instead of blobs when a PBO is bound
649 if function.name in self.unpack_function_names \
650 and (isinstance(arg.type, stdapi.Blob) \
651 or (isinstance(arg.type, stdapi.Const) \
652 and isinstance(arg.type.type, stdapi.Blob))):
José Fonsecac29f4f12011-06-11 12:19:05 +0100653 print ' {'
654 print ' GLint __unpack_buffer = 0;'
655 print ' __glGetIntegerv(GL_PIXEL_UNPACK_BUFFER_BINDING, &__unpack_buffer);'
656 print ' if (__unpack_buffer) {'
José Fonseca0ad465c2011-08-24 16:58:13 +0100657 print ' Trace::localWriter.writeOpaque(%s);' % arg.name
José Fonsecac29f4f12011-06-11 12:19:05 +0100658 print ' } else {'
José Fonsecae97bab92011-06-02 23:15:11 +0100659 Tracer.dump_arg_instance(self, function, arg)
José Fonsecac29f4f12011-06-11 12:19:05 +0100660 print ' }'
José Fonsecae97bab92011-06-02 23:15:11 +0100661 print ' }'
662 return
663
José Fonsecaa3f89ae2011-04-26 08:50:32 +0100664 # Several GL state functions take GLenum symbolic names as
665 # integer/floats; so dump the symbolic name whenever possible
José Fonseca3bcb33c2011-05-27 20:14:31 +0100666 if function.name.startswith('gl') \
José Fonsecae3571092011-10-13 08:26:27 +0100667 and arg.type in (glapi.GLint, glapi.GLfloat, glapi.GLdouble) \
José Fonseca3bcb33c2011-05-27 20:14:31 +0100668 and arg.name == 'param':
José Fonsecaa3f89ae2011-04-26 08:50:32 +0100669 assert arg.index > 0
670 assert function.args[arg.index - 1].name == 'pname'
671 assert function.args[arg.index - 1].type == glapi.GLenum
672 print ' if (is_symbolic_pname(pname) && is_symbolic_param(%s)) {' % arg.name
673 dump_instance(glapi.GLenum, arg.name)
674 print ' } else {'
675 Tracer.dump_arg_instance(self, function, arg)
676 print ' }'
677 return
678
José Fonseca8a6c6cb2011-03-23 16:44:30 +0000679 Tracer.dump_arg_instance(self, function, arg)
José Fonseca99221832011-03-22 22:15:46 +0000680
José Fonseca4c938c22011-04-30 22:44:38 +0100681 def footer(self, api):
682 Tracer.footer(self, api)
José Fonseca669b1222011-02-20 09:05:10 +0000683
José Fonseca4c938c22011-04-30 22:44:38 +0100684 # A simple state tracker to track the pointer values
José Fonseca669b1222011-02-20 09:05:10 +0000685 # update the state
José Fonseca8a6c6cb2011-03-23 16:44:30 +0000686 print 'static void __trace_user_arrays(GLuint maxindex)'
José Fonseca669b1222011-02-20 09:05:10 +0000687 print '{'
José Fonseca1a2fdd22011-04-01 00:55:09 +0100688
José Fonseca99221832011-03-22 22:15:46 +0000689 for camelcase_name, uppercase_name in self.arrays:
690 function_name = 'gl%sPointer' % camelcase_name
691 enable_name = 'GL_%s_ARRAY' % uppercase_name
692 binding_name = 'GL_%s_ARRAY_BUFFER_BINDING' % uppercase_name
José Fonseca14c21bc2011-02-20 23:32:22 +0000693 function = api.get_function_by_name(function_name)
José Fonseca99221832011-03-22 22:15:46 +0000694
José Fonseca06e85192011-10-16 14:15:36 +0100695 print ' // %s' % function.prototype()
José Fonsecafb6744f2011-04-15 11:18:37 +0100696 self.array_trace_prolog(api, uppercase_name)
697 self.array_prolog(api, uppercase_name)
698 print ' if (__glIsEnabled(%s)) {' % enable_name
José Fonseca7f5163e2011-03-31 23:37:26 +0100699 print ' GLint __binding = 0;'
700 print ' __glGetIntegerv(%s, &__binding);' % binding_name
701 print ' if (!__binding) {'
José Fonseca99221832011-03-22 22:15:46 +0000702
703 # Get the arguments via glGet*
704 for arg in function.args:
705 arg_get_enum = 'GL_%s_ARRAY_%s' % (uppercase_name, arg.name.upper())
706 arg_get_function, arg_type = TypeGetter().visit(arg.type)
José Fonseca7f5163e2011-03-31 23:37:26 +0100707 print ' %s %s = 0;' % (arg_type, arg.name)
708 print ' __%s(%s, &%s);' % (arg_get_function, arg_get_enum, arg.name)
José Fonseca99221832011-03-22 22:15:46 +0000709
710 arg_names = ', '.join([arg.name for arg in function.args[:-1]])
José Fonseca7f5163e2011-03-31 23:37:26 +0100711 print ' size_t __size = __%s_size(%s, maxindex);' % (function.name, arg_names)
José Fonseca99221832011-03-22 22:15:46 +0000712
713 # Emit a fake function
José Fonsecafb6744f2011-04-15 11:18:37 +0100714 self.array_trace_intermezzo(api, uppercase_name)
José Fonseca0ad465c2011-08-24 16:58:13 +0100715 print ' unsigned __call = Trace::localWriter.beginEnter(&__%s_sig);' % (function.name,)
José Fonseca669b1222011-02-20 09:05:10 +0000716 for arg in function.args:
717 assert not arg.output
José Fonseca0ad465c2011-08-24 16:58:13 +0100718 print ' Trace::localWriter.beginArg(%u);' % (arg.index,)
José Fonseca14c21bc2011-02-20 23:32:22 +0000719 if arg.name != 'pointer':
José Fonseca99221832011-03-22 22:15:46 +0000720 dump_instance(arg.type, arg.name)
José Fonseca14c21bc2011-02-20 23:32:22 +0000721 else:
José Fonseca0ad465c2011-08-24 16:58:13 +0100722 print ' Trace::localWriter.writeBlob((const void *)%s, __size);' % (arg.name)
723 print ' Trace::localWriter.endArg();'
José Fonseca99221832011-03-22 22:15:46 +0000724
José Fonseca0ad465c2011-08-24 16:58:13 +0100725 print ' Trace::localWriter.endEnter();'
726 print ' Trace::localWriter.beginLeave(__call);'
727 print ' Trace::localWriter.endLeave();'
José Fonseca99221832011-03-22 22:15:46 +0000728 print ' }'
José Fonseca669b1222011-02-20 09:05:10 +0000729 print ' }'
José Fonsecafb6744f2011-04-15 11:18:37 +0100730 self.array_epilog(api, uppercase_name)
731 self.array_trace_epilog(api, uppercase_name)
José Fonseca99221832011-03-22 22:15:46 +0000732 print
José Fonseca1a2fdd22011-04-01 00:55:09 +0100733
José Fonseca1601c412011-05-10 10:38:19 +0100734 # Samething, but for glVertexAttribPointer*
735 #
736 # Some variants of glVertexAttribPointer alias conventional and generic attributes:
737 # - glVertexAttribPointer: no
738 # - glVertexAttribPointerARB: implementation dependent
739 # - glVertexAttribPointerNV: yes
740 #
741 # This means that the implementations of these functions do not always
742 # alias, and they need to be considered independently.
743 #
José Fonseca5a568a92011-06-29 16:43:36 +0100744 print ' vertex_attrib __vertex_attrib = __get_vertex_attrib();'
745 print
746 for suffix in ['', 'ARB', 'NV']:
747 if suffix:
José Fonsecad94aaac2011-06-28 20:50:49 +0100748 SUFFIX = '_' + suffix
José Fonsecad94aaac2011-06-28 20:50:49 +0100749 else:
José Fonseca5a568a92011-06-29 16:43:36 +0100750 SUFFIX = suffix
José Fonseca1601c412011-05-10 10:38:19 +0100751 function_name = 'glVertexAttribPointer' + suffix
José Fonseca06e85192011-10-16 14:15:36 +0100752 function = api.get_function_by_name(function_name)
753
754 print ' // %s' % function.prototype()
José Fonseca5a568a92011-06-29 16:43:36 +0100755 print ' if (__vertex_attrib == VERTEX_ATTRIB%s) {' % SUFFIX
756 if suffix == 'NV':
757 print ' GLint __max_vertex_attribs = 16;'
758 else:
759 print ' GLint __max_vertex_attribs = 0;'
760 print ' __glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &__max_vertex_attribs);'
761 print ' for (GLint index = 0; index < __max_vertex_attribs; ++index) {'
762 print ' GLint __enabled = 0;'
763 if suffix == 'NV':
764 print ' __glGetIntegerv(GL_VERTEX_ATTRIB_ARRAY0_NV + index, &__enabled);'
765 else:
766 print ' __glGetVertexAttribiv%s(index, GL_VERTEX_ATTRIB_ARRAY_ENABLED%s, &__enabled);' % (suffix, SUFFIX)
767 print ' if (__enabled) {'
768 print ' GLint __binding = 0;'
769 if suffix != 'NV':
770 # It doesn't seem possible to use VBOs with NV_vertex_program.
771 print ' __glGetVertexAttribiv%s(index, GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING%s, &__binding);' % (suffix, SUFFIX)
772 print ' if (!__binding) {'
José Fonseca1a2fdd22011-04-01 00:55:09 +0100773
José Fonseca1601c412011-05-10 10:38:19 +0100774 # Get the arguments via glGet*
775 for arg in function.args[1:]:
José Fonseca5a568a92011-06-29 16:43:36 +0100776 if suffix == 'NV':
777 arg_get_enum = 'GL_ATTRIB_ARRAY_%s%s' % (arg.name.upper(), SUFFIX)
778 else:
779 arg_get_enum = 'GL_VERTEX_ATTRIB_ARRAY_%s%s' % (arg.name.upper(), SUFFIX)
José Fonsecac493e3e2011-06-29 12:57:06 +0100780 arg_get_function, arg_type = TypeGetter('glGetVertexAttrib', False, suffix).visit(arg.type)
José Fonseca5a568a92011-06-29 16:43:36 +0100781 print ' %s %s = 0;' % (arg_type, arg.name)
782 print ' __%s(index, %s, &%s);' % (arg_get_function, arg_get_enum, arg.name)
José Fonseca1601c412011-05-10 10:38:19 +0100783
784 arg_names = ', '.join([arg.name for arg in function.args[1:-1]])
José Fonseca5a568a92011-06-29 16:43:36 +0100785 print ' size_t __size = __%s_size(%s, maxindex);' % (function.name, arg_names)
José Fonseca1a2fdd22011-04-01 00:55:09 +0100786
José Fonseca1601c412011-05-10 10:38:19 +0100787 # Emit a fake function
José Fonseca0ad465c2011-08-24 16:58:13 +0100788 print ' unsigned __call = Trace::localWriter.beginEnter(&__%s_sig);' % (function.name,)
José Fonseca1601c412011-05-10 10:38:19 +0100789 for arg in function.args:
790 assert not arg.output
José Fonseca0ad465c2011-08-24 16:58:13 +0100791 print ' Trace::localWriter.beginArg(%u);' % (arg.index,)
José Fonseca1601c412011-05-10 10:38:19 +0100792 if arg.name != 'pointer':
793 dump_instance(arg.type, arg.name)
794 else:
José Fonseca0ad465c2011-08-24 16:58:13 +0100795 print ' Trace::localWriter.writeBlob((const void *)%s, __size);' % (arg.name)
796 print ' Trace::localWriter.endArg();'
José Fonseca1601c412011-05-10 10:38:19 +0100797
José Fonseca0ad465c2011-08-24 16:58:13 +0100798 print ' Trace::localWriter.endEnter();'
799 print ' Trace::localWriter.beginLeave(__call);'
800 print ' Trace::localWriter.endLeave();'
José Fonseca1601c412011-05-10 10:38:19 +0100801 print ' }'
802 print ' }'
803 print ' }'
804 print ' }'
805 print
José Fonseca1a2fdd22011-04-01 00:55:09 +0100806
José Fonseca669b1222011-02-20 09:05:10 +0000807 print '}'
808 print
809
José Fonsecafb6744f2011-04-15 11:18:37 +0100810 #
811 # Hooks for glTexCoordPointer, which is identical to the other array
812 # pointers except the fact that it is indexed by glClientActiveTexture.
813 #
814
815 def array_prolog(self, api, uppercase_name):
816 if uppercase_name == 'TEXTURE_COORD':
817 print ' GLint client_active_texture = 0;'
818 print ' __glGetIntegerv(GL_CLIENT_ACTIVE_TEXTURE, &client_active_texture);'
819 print ' GLint max_texture_coords = 0;'
820 print ' __glGetIntegerv(GL_MAX_TEXTURE_COORDS, &max_texture_coords);'
821 print ' for (GLint unit = 0; unit < max_texture_coords; ++unit) {'
José Fonseca7525e6f2011-09-28 09:04:56 +0100822 print ' GLint texture = GL_TEXTURE0 + unit;'
José Fonsecafb6744f2011-04-15 11:18:37 +0100823 print ' __glClientActiveTexture(texture);'
824
825 def array_trace_prolog(self, api, uppercase_name):
826 if uppercase_name == 'TEXTURE_COORD':
827 print ' bool client_active_texture_dirty = false;'
828
829 def array_epilog(self, api, uppercase_name):
830 if uppercase_name == 'TEXTURE_COORD':
831 print ' }'
832 self.array_cleanup(api, uppercase_name)
833
834 def array_cleanup(self, api, uppercase_name):
835 if uppercase_name == 'TEXTURE_COORD':
836 print ' __glClientActiveTexture(client_active_texture);'
837
838 def array_trace_intermezzo(self, api, uppercase_name):
839 if uppercase_name == 'TEXTURE_COORD':
840 print ' if (texture != client_active_texture || client_active_texture_dirty) {'
841 print ' client_active_texture_dirty = true;'
842 self.fake_glClientActiveTexture_call(api, "texture");
843 print ' }'
844
845 def array_trace_epilog(self, api, uppercase_name):
846 if uppercase_name == 'TEXTURE_COORD':
847 print ' if (client_active_texture_dirty) {'
848 self.fake_glClientActiveTexture_call(api, "client_active_texture");
849 print ' }'
850
851 def fake_glClientActiveTexture_call(self, api, texture):
852 function = api.get_function_by_name('glClientActiveTexture')
853 self.fake_call(function, [texture])
854
855 def fake_call(self, function, args):
José Fonseca0ad465c2011-08-24 16:58:13 +0100856 print ' unsigned __fake_call = Trace::localWriter.beginEnter(&__%s_sig);' % (function.name,)
José Fonsecafb6744f2011-04-15 11:18:37 +0100857 for arg, instance in zip(function.args, args):
858 assert not arg.output
José Fonseca0ad465c2011-08-24 16:58:13 +0100859 print ' Trace::localWriter.beginArg(%u);' % (arg.index,)
José Fonsecafb6744f2011-04-15 11:18:37 +0100860 dump_instance(arg.type, instance)
José Fonseca0ad465c2011-08-24 16:58:13 +0100861 print ' Trace::localWriter.endArg();'
862 print ' Trace::localWriter.endEnter();'
863 print ' Trace::localWriter.beginLeave(__fake_call);'
864 print ' Trace::localWriter.endLeave();'
José Fonsecafb6744f2011-04-15 11:18:37 +0100865
866
867
868
869
José Fonseca669b1222011-02-20 09:05:10 +0000870
871
872
873
874
875