blob: c79b10904a4feb75886eff060299a198587db47d [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
Chia-I Wu8ef66972011-11-03 01:19:46 +0800112 print 'struct tracer_context {'
113 print ' bool user_arrays;'
114 print ' bool user_arrays_arb;'
115 print ' bool user_arrays_nv;'
116 print '};'
José Fonseca25ebe542011-04-24 10:08:22 +0100117 print
José Fonseca5a568a92011-06-29 16:43:36 +0100118
119 # Which glVertexAttrib* variant to use
120 print 'enum vertex_attrib {'
121 print ' VERTEX_ATTRIB,'
122 print ' VERTEX_ATTRIB_ARB,'
123 print ' VERTEX_ATTRIB_NV,'
124 print '};'
125 print
Chia-I Wu8ef66972011-11-03 01:19:46 +0800126 print 'static tracer_context *__get_context(void)'
127 print '{'
128 print ' // TODO return the context set by other APIs (GLX, EGL, and etc.)'
129 print ' static tracer_context __ctx = { false, false, false };'
130 print ' return &__ctx;'
131 print '}'
132 print
José Fonseca5a568a92011-06-29 16:43:36 +0100133 print 'static vertex_attrib __get_vertex_attrib(void) {'
Chia-I Wu8ef66972011-11-03 01:19:46 +0800134 print ' tracer_context *ctx = __get_context();'
135 print ' if (ctx->user_arrays_arb || ctx->user_arrays_nv) {'
José Fonseca5a568a92011-06-29 16:43:36 +0100136 print ' GLboolean __vertex_program = GL_FALSE;'
137 print ' __glGetBooleanv(GL_VERTEX_PROGRAM_ARB, &__vertex_program);'
138 print ' if (__vertex_program) {'
Chia-I Wu8ef66972011-11-03 01:19:46 +0800139 print ' if (ctx->user_arrays_nv) {'
José Fonseca5a568a92011-06-29 16:43:36 +0100140 print ' GLint __vertex_program_binding_nv = 0;'
141 print ' __glGetIntegerv(GL_VERTEX_PROGRAM_BINDING_NV, &__vertex_program_binding_nv);'
142 print ' if (__vertex_program_binding_nv) {'
143 print ' return VERTEX_ATTRIB_NV;'
144 print ' }'
145 print ' }'
146 print ' return VERTEX_ATTRIB_ARB;'
147 print ' }'
148 print ' }'
149 print ' return VERTEX_ATTRIB;'
150 print '}'
151 print
152
José Fonseca8a6c6cb2011-03-23 16:44:30 +0000153 # Whether we need user arrays
154 print 'static inline bool __need_user_arrays(void)'
155 print '{'
Chia-I Wu8ef66972011-11-03 01:19:46 +0800156 print ' tracer_context *ctx = __get_context();'
157 print ' if (!ctx->user_arrays) {'
José Fonseca25ebe542011-04-24 10:08:22 +0100158 print ' return false;'
159 print ' }'
160 print
José Fonseca1a2fdd22011-04-01 00:55:09 +0100161
José Fonseca8a6c6cb2011-03-23 16:44:30 +0000162 for camelcase_name, uppercase_name in self.arrays:
163 function_name = 'gl%sPointer' % camelcase_name
164 enable_name = 'GL_%s_ARRAY' % uppercase_name
165 binding_name = 'GL_%s_ARRAY_BUFFER_BINDING' % uppercase_name
166 print ' // %s' % function_name
José Fonsecafb6744f2011-04-15 11:18:37 +0100167 self.array_prolog(api, uppercase_name)
José Fonseca7f5163e2011-03-31 23:37:26 +0100168 print ' if (__glIsEnabled(%s)) {' % enable_name
169 print ' GLint __binding = 0;'
170 print ' __glGetIntegerv(%s, &__binding);' % binding_name
171 print ' if (!__binding) {'
José Fonsecafb6744f2011-04-15 11:18:37 +0100172 self.array_cleanup(api, uppercase_name)
José Fonseca7f5163e2011-03-31 23:37:26 +0100173 print ' return true;'
José Fonseca8a6c6cb2011-03-23 16:44:30 +0000174 print ' }'
175 print ' }'
José Fonsecafb6744f2011-04-15 11:18:37 +0100176 self.array_epilog(api, uppercase_name)
José Fonseca8a6c6cb2011-03-23 16:44:30 +0000177 print
José Fonseca7f5163e2011-03-31 23:37:26 +0100178
José Fonseca5a568a92011-06-29 16:43:36 +0100179 print ' vertex_attrib __vertex_attrib = __get_vertex_attrib();'
180 print
181 print ' // glVertexAttribPointer'
182 print ' if (__vertex_attrib == VERTEX_ATTRIB) {'
183 print ' GLint __max_vertex_attribs = 0;'
184 print ' __glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &__max_vertex_attribs);'
185 print ' for (GLint index = 0; index < __max_vertex_attribs; ++index) {'
186 print ' GLint __enabled = 0;'
187 print ' __glGetVertexAttribiv(index, GL_VERTEX_ATTRIB_ARRAY_ENABLED, &__enabled);'
188 print ' if (__enabled) {'
189 print ' GLint __binding = 0;'
190 print ' __glGetVertexAttribiv(index, GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING, &__binding);'
191 print ' if (!__binding) {'
192 print ' return true;'
193 print ' }'
194 print ' }'
195 print ' }'
196 print ' }'
197 print
198 print ' // glVertexAttribPointerARB'
199 print ' if (__vertex_attrib == VERTEX_ATTRIB_ARB) {'
José Fonsecad94aaac2011-06-28 20:50:49 +0100200 print ' GLint __max_vertex_attribs = 0;'
201 print ' __glGetIntegerv(GL_MAX_VERTEX_ATTRIBS_ARB, &__max_vertex_attribs);'
202 print ' for (GLint index = 0; index < __max_vertex_attribs; ++index) {'
203 print ' GLint __enabled = 0;'
204 print ' __glGetVertexAttribivARB(index, GL_VERTEX_ATTRIB_ARRAY_ENABLED_ARB, &__enabled);'
205 print ' if (__enabled) {'
206 print ' GLint __binding = 0;'
207 print ' __glGetVertexAttribivARB(index, GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING_ARB, &__binding);'
208 print ' if (!__binding) {'
209 print ' return true;'
210 print ' }'
211 print ' }'
212 print ' }'
José Fonseca5a568a92011-06-29 16:43:36 +0100213 print ' }'
214 print
215 print ' // glVertexAttribPointerNV'
216 print ' if (__vertex_attrib == VERTEX_ATTRIB_NV) {'
217 print ' for (GLint index = 0; index < 16; ++index) {'
José Fonsecad94aaac2011-06-28 20:50:49 +0100218 print ' GLint __enabled = 0;'
José Fonseca5a568a92011-06-29 16:43:36 +0100219 print ' __glGetIntegerv(GL_VERTEX_ATTRIB_ARRAY0_NV + index, &__enabled);'
José Fonsecad94aaac2011-06-28 20:50:49 +0100220 print ' if (__enabled) {'
José Fonseca5a568a92011-06-29 16:43:36 +0100221 print ' return true;'
José Fonseca1a2fdd22011-04-01 00:55:09 +0100222 print ' }'
223 print ' }'
224 print ' }'
225 print
226
José Fonseca8a6c6cb2011-03-23 16:44:30 +0000227 print ' return false;'
228 print '}'
229 print
José Fonseca669b1222011-02-20 09:05:10 +0000230
José Fonseca8a6c6cb2011-03-23 16:44:30 +0000231 print 'static void __trace_user_arrays(GLuint maxindex);'
José Fonseca14c21bc2011-02-20 23:32:22 +0000232 print
José Fonseca867b1b72011-04-24 11:58:04 +0100233
234 print 'struct buffer_mapping {'
235 print ' void *map;'
236 print ' GLint length;'
237 print ' bool write;'
José Fonseca73373602011-05-20 17:45:26 +0100238 print ' bool explicit_flush;'
José Fonseca867b1b72011-04-24 11:58:04 +0100239 print '};'
240 print
241 for target in self.buffer_targets:
242 print 'struct buffer_mapping __%s_mapping;' % target.lower();
243 print
244 print 'static inline struct buffer_mapping *'
245 print 'get_buffer_mapping(GLenum target) {'
José Fonseca06e85192011-10-16 14:15:36 +0100246 print ' switch (target) {'
José Fonseca867b1b72011-04-24 11:58:04 +0100247 for target in self.buffer_targets:
248 print ' case GL_%s:' % target
249 print ' return & __%s_mapping;' % target.lower()
250 print ' default:'
José Fonseca559d5342011-10-27 08:10:56 +0100251 print ' os::log("apitrace: warning: unknown buffer target 0x%04X\\n", target);'
José Fonseca867b1b72011-04-24 11:58:04 +0100252 print ' return NULL;'
253 print ' }'
254 print '}'
255 print
256
José Fonsecaa3f89ae2011-04-26 08:50:32 +0100257 # Generate a helper function to determine whether a parameter name
258 # refers to a symbolic value or not
259 print 'static bool'
260 print 'is_symbolic_pname(GLenum pname) {'
José Fonseca06e85192011-10-16 14:15:36 +0100261 print ' switch (pname) {'
José Fonseca5ea91872011-05-04 09:41:55 +0100262 for function, type, count, name in glparams.parameters:
José Fonsecaa3f89ae2011-04-26 08:50:32 +0100263 if type is glapi.GLenum:
José Fonseca4c938c22011-04-30 22:44:38 +0100264 print ' case %s:' % name
265 print ' return true;'
266 print ' default:'
267 print ' return false;'
José Fonsecaa3f89ae2011-04-26 08:50:32 +0100268 print ' }'
269 print '}'
270 print
271
272 # Generate a helper function to determine whether a parameter value is
273 # potentially symbolic or not; i.e., if the value can be represented in
274 # an enum or not
275 print 'template<class T>'
276 print 'static inline bool'
277 print 'is_symbolic_param(T param) {'
278 print ' return static_cast<T>(static_cast<GLenum>(param)) == param;'
279 print '}'
280 print
José Fonseca4c938c22011-04-30 22:44:38 +0100281
282 # Generate a helper function to know how many elements a parameter has
283 print 'static size_t'
José Fonsecaf4aca5d2011-05-08 08:29:30 +0100284 print '__gl_param_size(GLenum pname) {'
José Fonseca06e85192011-10-16 14:15:36 +0100285 print ' switch (pname) {'
José Fonseca5ea91872011-05-04 09:41:55 +0100286 for function, type, count, name in glparams.parameters:
José Fonseca4c938c22011-04-30 22:44:38 +0100287 if type is not None:
288 print ' case %s: return %u;' % (name, count)
289 print ' case GL_COMPRESSED_TEXTURE_FORMATS: {'
290 print ' GLint num_compressed_texture_formats = 0;'
291 print ' __glGetIntegerv(GL_NUM_COMPRESSED_TEXTURE_FORMATS, &num_compressed_texture_formats);'
292 print ' return num_compressed_texture_formats;'
293 print ' }'
294 print ' default:'
José Fonseca559d5342011-10-27 08:10:56 +0100295 print r' os::log("apitrace: warning: %s: unknown GLenum 0x%04X\n", __FUNCTION__, pname);'
José Fonseca4c938c22011-04-30 22:44:38 +0100296 print ' return 1;'
297 print ' }'
298 print '}'
299 print
300
José Fonseca99221832011-03-22 22:15:46 +0000301 array_pointer_function_names = set((
302 "glVertexPointer",
303 "glNormalPointer",
304 "glColorPointer",
305 "glIndexPointer",
306 "glTexCoordPointer",
307 "glEdgeFlagPointer",
308 "glFogCoordPointer",
309 "glSecondaryColorPointer",
José Fonseca7f5163e2011-03-31 23:37:26 +0100310
José Fonsecaac5285b2011-05-04 11:09:08 +0100311 "glInterleavedArrays",
312
José Fonseca7e0bfd92011-04-30 23:09:03 +0100313 "glVertexPointerEXT",
314 "glNormalPointerEXT",
315 "glColorPointerEXT",
316 "glIndexPointerEXT",
317 "glTexCoordPointerEXT",
318 "glEdgeFlagPointerEXT",
319 "glFogCoordPointerEXT",
320 "glSecondaryColorPointerEXT",
José Fonseca99221832011-03-22 22:15:46 +0000321
José Fonseca7f5163e2011-03-31 23:37:26 +0100322 "glVertexAttribPointer",
323 "glVertexAttribPointerARB",
324 "glVertexAttribPointerNV",
José Fonsecaac5285b2011-05-04 11:09:08 +0100325 "glVertexAttribIPointer",
326 "glVertexAttribIPointerEXT",
José Fonseca7f5163e2011-03-31 23:37:26 +0100327 "glVertexAttribLPointer",
328 "glVertexAttribLPointerEXT",
José Fonseca99221832011-03-22 22:15:46 +0000329
330 #"glMatrixIndexPointerARB",
331 ))
332
333 draw_function_names = set((
334 'glDrawArrays',
335 'glDrawElements',
336 'glDrawRangeElements',
José Fonseca5c749e32011-05-09 11:11:37 +0100337 'glMultiDrawArrays',
338 'glMultiDrawElements',
339 'glDrawArraysInstanced',
José Fonsecaff8848b2011-10-09 01:04:17 +0100340 "glDrawArraysInstancedBaseInstance",
José Fonseca5c749e32011-05-09 11:11:37 +0100341 'glDrawElementsInstanced',
342 'glDrawArraysInstancedARB',
343 'glDrawElementsInstancedARB',
344 'glDrawElementsBaseVertex',
345 'glDrawRangeElementsBaseVertex',
346 'glDrawElementsInstancedBaseVertex',
José Fonsecaff8848b2011-10-09 01:04:17 +0100347 "glDrawElementsInstancedBaseInstance",
348 "glDrawElementsInstancedBaseVertexBaseInstance",
José Fonseca5c749e32011-05-09 11:11:37 +0100349 'glMultiDrawElementsBaseVertex',
350 'glDrawArraysIndirect',
351 'glDrawElementsIndirect',
352 'glDrawArraysEXT',
José Fonseca7e0bfd92011-04-30 23:09:03 +0100353 'glDrawRangeElementsEXT',
José Fonseca5c749e32011-05-09 11:11:37 +0100354 'glDrawRangeElementsEXT_size',
355 'glMultiDrawArraysEXT',
356 'glMultiDrawElementsEXT',
357 'glMultiModeDrawArraysIBM',
358 'glMultiModeDrawElementsIBM',
359 'glDrawArraysInstancedEXT',
360 'glDrawElementsInstancedEXT',
José Fonseca99221832011-03-22 22:15:46 +0000361 ))
362
José Fonsecac9f12232011-03-25 20:07:42 +0000363 interleaved_formats = [
364 'GL_V2F',
365 'GL_V3F',
366 'GL_C4UB_V2F',
367 'GL_C4UB_V3F',
368 'GL_C3F_V3F',
369 'GL_N3F_V3F',
370 'GL_C4F_N3F_V3F',
371 'GL_T2F_V3F',
372 'GL_T4F_V4F',
373 'GL_T2F_C4UB_V3F',
374 'GL_T2F_C3F_V3F',
375 'GL_T2F_N3F_V3F',
376 'GL_T2F_C4F_N3F_V3F',
377 'GL_T4F_C4F_N3F_V4F',
378 ]
379
José Fonseca14c21bc2011-02-20 23:32:22 +0000380 def trace_function_impl_body(self, function):
José Fonseca8a6c6cb2011-03-23 16:44:30 +0000381 # Defer tracing of user array pointers...
José Fonseca99221832011-03-22 22:15:46 +0000382 if function.name in self.array_pointer_function_names:
383 print ' GLint __array_buffer = 0;'
384 print ' __glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &__array_buffer);'
385 print ' if (!__array_buffer) {'
Chia-I Wu8ef66972011-11-03 01:19:46 +0800386 print ' tracer_context *ctx = __get_context();'
387 print ' ctx->user_arrays = true;'
José Fonseca5a568a92011-06-29 16:43:36 +0100388 if function.name == "glVertexAttribPointerARB":
Chia-I Wu8ef66972011-11-03 01:19:46 +0800389 print ' ctx->user_arrays_arb = true;'
José Fonseca5a568a92011-06-29 16:43:36 +0100390 if function.name == "glVertexAttribPointerNV":
Chia-I Wu8ef66972011-11-03 01:19:46 +0800391 print ' ctx->user_arrays_nv = true;'
José Fonseca14c21bc2011-02-20 23:32:22 +0000392 self.dispatch_function(function)
José Fonsecaac5285b2011-05-04 11:09:08 +0100393
394 # And also break down glInterleavedArrays into the individual calls
395 if function.name == 'glInterleavedArrays':
396 print
397
398 # Initialize the enable flags
399 for camelcase_name, uppercase_name in self.arrays:
400 flag_name = '__' + uppercase_name.lower()
401 print ' GLboolean %s = GL_FALSE;' % flag_name
402 print
403
404 # Switch for the interleaved formats
405 print ' switch (format) {'
406 for format in self.interleaved_formats:
407 print ' case %s:' % format
408 for camelcase_name, uppercase_name in self.arrays:
409 flag_name = '__' + uppercase_name.lower()
410 if format.find('_' + uppercase_name[0]) >= 0:
411 print ' %s = GL_TRUE;' % flag_name
412 print ' break;'
413 print ' default:'
414 print ' return;'
415 print ' }'
416 print
417
418 # Emit fake glEnableClientState/glDisableClientState flags
419 for camelcase_name, uppercase_name in self.arrays:
420 flag_name = '__' + uppercase_name.lower()
421 enable_name = 'GL_%s_ARRAY' % uppercase_name
422
423 # Emit a fake function
424 print ' {'
José Fonsecab4a3d142011-10-27 07:43:19 +0100425 print ' static const trace::FunctionSig &__sig = %s ? __glEnableClientState_sig : __glDisableClientState_sig;' % flag_name
426 print ' unsigned __call = trace::localWriter.beginEnter(&__sig);'
427 print ' trace::localWriter.beginArg(0);'
José Fonsecaac5285b2011-05-04 11:09:08 +0100428 dump_instance(glapi.GLenum, enable_name)
José Fonsecab4a3d142011-10-27 07:43:19 +0100429 print ' trace::localWriter.endArg();'
430 print ' trace::localWriter.endEnter();'
431 print ' trace::localWriter.beginLeave(__call);'
432 print ' trace::localWriter.endLeave();'
José Fonsecaac5285b2011-05-04 11:09:08 +0100433 print ' }'
434
José Fonseca99221832011-03-22 22:15:46 +0000435 print ' return;'
436 print ' }'
José Fonseca14c21bc2011-02-20 23:32:22 +0000437
José Fonseca8a6c6cb2011-03-23 16:44:30 +0000438 # ... to the draw calls
José Fonseca99221832011-03-22 22:15:46 +0000439 if function.name in self.draw_function_names:
José Fonseca8a6c6cb2011-03-23 16:44:30 +0000440 print ' if (__need_user_arrays()) {'
José Fonseca99221832011-03-22 22:15:46 +0000441 arg_names = ', '.join([arg.name for arg in function.args[1:]])
José Fonseca8a6c6cb2011-03-23 16:44:30 +0000442 print ' GLuint maxindex = __%s_maxindex(%s);' % (function.name, arg_names)
443 print ' __trace_user_arrays(maxindex);'
444 print ' }'
José Fonseca14c21bc2011-02-20 23:32:22 +0000445
José Fonseca73373602011-05-20 17:45:26 +0100446 # Emit a fake memcpy on buffer uploads
447 if function.name in ('glUnmapBuffer', 'glUnmapBufferARB', ):
José Fonseca867b1b72011-04-24 11:58:04 +0100448 print ' struct buffer_mapping *mapping = get_buffer_mapping(target);'
José Fonseca73373602011-05-20 17:45:26 +0100449 print ' if (mapping && mapping->write && !mapping->explicit_flush) {'
450 self.emit_memcpy('mapping->map', 'mapping->map', 'mapping->length')
José Fonseca867b1b72011-04-24 11:58:04 +0100451 print ' }'
José Fonseca73373602011-05-20 17:45:26 +0100452 if function.name in ('glFlushMappedBufferRange', 'glFlushMappedBufferRangeAPPLE'):
José Fonseca73373602011-05-20 17:45:26 +0100453 print ' struct buffer_mapping *mapping = get_buffer_mapping(target);'
454 print ' if (mapping) {'
455 if function.name.endswith('APPLE'):
456 print ' GLsizeiptr length = size;'
457 print ' mapping->explicit_flush = true;'
458 print ' //assert(offset + length <= mapping->length);'
José Fonseca46a48392011-10-14 11:34:27 +0100459 self.emit_memcpy('(char *)mapping->map + offset', '(const char *)mapping->map + offset', 'length')
José Fonseca73373602011-05-20 17:45:26 +0100460 print ' }'
461 # FIXME: glFlushMappedNamedBufferRangeEXT
José Fonseca867b1b72011-04-24 11:58:04 +0100462
José Fonseca91492d22011-05-23 21:20:31 +0100463 # Don't leave vertex attrib locations to chance. Instead emit fake
464 # glBindAttribLocation calls to ensure that the same locations will be
465 # used when retracing. Trying to remap locations after the fact would
466 # be an herculian task given that vertex attrib locations appear in
467 # many entry-points, including non-shader related ones.
468 if function.name == 'glLinkProgram':
469 Tracer.dispatch_function(self, function)
470 print ' GLint active_attributes = 0;'
471 print ' __glGetProgramiv(program, GL_ACTIVE_ATTRIBUTES, &active_attributes);'
José Fonseca7525e6f2011-09-28 09:04:56 +0100472 print ' for (GLint attrib = 0; attrib < active_attributes; ++attrib) {'
José Fonseca91492d22011-05-23 21:20:31 +0100473 print ' GLint size = 0;'
474 print ' GLenum type = 0;'
475 print ' GLchar name[256];'
476 # TODO: Use ACTIVE_ATTRIBUTE_MAX_LENGTH instead of 256
477 print ' __glGetActiveAttrib(program, attrib, sizeof name, NULL, &size, &type, name);'
José Fonseca2a794f52011-05-26 20:54:29 +0100478 print " if (name[0] != 'g' || name[1] != 'l' || name[2] != '_') {"
479 print ' GLint location = __glGetAttribLocation(program, name);'
480 print ' if (location >= 0) {'
José Fonseca91492d22011-05-23 21:20:31 +0100481 bind_function = glapi.glapi.get_function_by_name('glBindAttribLocation')
482 self.fake_call(bind_function, ['program', 'location', 'name'])
José Fonseca2a794f52011-05-26 20:54:29 +0100483 print ' }'
José Fonseca91492d22011-05-23 21:20:31 +0100484 print ' }'
485 print ' }'
486 if function.name == 'glLinkProgramARB':
487 Tracer.dispatch_function(self, function)
488 print ' GLint active_attributes = 0;'
489 print ' __glGetObjectParameterivARB(programObj, GL_OBJECT_ACTIVE_ATTRIBUTES_ARB, &active_attributes);'
José Fonseca7525e6f2011-09-28 09:04:56 +0100490 print ' for (GLint attrib = 0; attrib < active_attributes; ++attrib) {'
José Fonseca91492d22011-05-23 21:20:31 +0100491 print ' GLint size = 0;'
492 print ' GLenum type = 0;'
493 print ' GLcharARB name[256];'
494 # TODO: Use ACTIVE_ATTRIBUTE_MAX_LENGTH instead of 256
495 print ' __glGetActiveAttribARB(programObj, attrib, sizeof name, NULL, &size, &type, name);'
José Fonseca2a794f52011-05-26 20:54:29 +0100496 print " if (name[0] != 'g' || name[1] != 'l' || name[2] != '_') {"
497 print ' GLint location = __glGetAttribLocationARB(programObj, name);'
498 print ' if (location >= 0) {'
José Fonseca91492d22011-05-23 21:20:31 +0100499 bind_function = glapi.glapi.get_function_by_name('glBindAttribLocationARB')
500 self.fake_call(bind_function, ['programObj', 'location', 'name'])
José Fonseca2a794f52011-05-26 20:54:29 +0100501 print ' }'
José Fonseca91492d22011-05-23 21:20:31 +0100502 print ' }'
503 print ' }'
504
José Fonseca14c21bc2011-02-20 23:32:22 +0000505 Tracer.trace_function_impl_body(self, function)
José Fonseca73373602011-05-20 17:45:26 +0100506
José Fonseca8f34d342011-07-15 20:16:40 +0100507 gremedy_functions = [
508 'glStringMarkerGREMEDY',
509 'glFrameTerminatorGREMEDY',
510 ]
511
José Fonseca91492d22011-05-23 21:20:31 +0100512 def dispatch_function(self, function):
513 if function.name in ('glLinkProgram', 'glLinkProgramARB'):
514 # These functions have been dispatched already
515 return
516
José Fonseca1b3d3752011-07-15 10:15:19 +0100517 # We implement the GREMEDY extensions, not the driver
José Fonseca8f34d342011-07-15 20:16:40 +0100518 if function.name in self.gremedy_functions:
519 return
520
521 if function.name in ('glXGetProcAddress', 'glXGetProcAddressARB', 'wglGetProcAddress'):
522 if_ = 'if'
523 for gremedy_function in self.gremedy_functions:
524 print ' %s (strcmp("%s", (const char *)%s) == 0) {' % (if_, gremedy_function, function.args[0].name)
525 print ' __result = (%s)&%s;' % (function.type, gremedy_function)
526 print ' }'
527 if_ = 'else if'
528 print ' else {'
529 Tracer.dispatch_function(self, function)
530 print ' }'
José Fonseca1b3d3752011-07-15 10:15:19 +0100531 return
532
José Fonsecaa08d2752011-08-25 13:26:43 +0100533 # Override GL extensions
534 if function.name in ('glGetString', 'glGetIntegerv', 'glGetStringi'):
535 Tracer.dispatch_function(self, function, prefix = 'gltrace::__', suffix = '_override')
536 return
537
José Fonseca91492d22011-05-23 21:20:31 +0100538 Tracer.dispatch_function(self, function)
539
José Fonseca73373602011-05-20 17:45:26 +0100540 def emit_memcpy(self, dest, src, length):
José Fonsecab4a3d142011-10-27 07:43:19 +0100541 print ' unsigned __call = trace::localWriter.beginEnter(&trace::memcpy_sig);'
542 print ' trace::localWriter.beginArg(0);'
543 print ' trace::localWriter.writeOpaque(%s);' % dest
544 print ' trace::localWriter.endArg();'
545 print ' trace::localWriter.beginArg(1);'
546 print ' trace::localWriter.writeBlob(%s, %s);' % (src, length)
547 print ' trace::localWriter.endArg();'
548 print ' trace::localWriter.beginArg(2);'
549 print ' trace::localWriter.writeUInt(%s);' % length
550 print ' trace::localWriter.endArg();'
551 print ' trace::localWriter.endEnter();'
552 print ' trace::localWriter.beginLeave(__call);'
553 print ' trace::localWriter.endLeave();'
José Fonseca867b1b72011-04-24 11:58:04 +0100554
555 buffer_targets = [
556 'ARRAY_BUFFER',
557 'ELEMENT_ARRAY_BUFFER',
558 'PIXEL_PACK_BUFFER',
559 'PIXEL_UNPACK_BUFFER',
560 ]
561
562 def wrap_ret(self, function, instance):
563 Tracer.wrap_ret(self, function, instance)
José Fonseca1b3d3752011-07-15 10:15:19 +0100564
José Fonseca867b1b72011-04-24 11:58:04 +0100565
566 if function.name in ('glMapBuffer', 'glMapBufferARB'):
567 print ' struct buffer_mapping *mapping = get_buffer_mapping(target);'
568 print ' if (mapping) {'
569 print ' mapping->map = %s;' % (instance)
570 print ' mapping->length = 0;'
571 print ' __glGetBufferParameteriv(target, GL_BUFFER_SIZE, &mapping->length);'
572 print ' mapping->write = (access != GL_READ_ONLY);'
José Fonseca73373602011-05-20 17:45:26 +0100573 print ' mapping->explicit_flush = false;'
José Fonseca867b1b72011-04-24 11:58:04 +0100574 print ' }'
575
576 if function.name == 'glMapBufferRange':
577 print ' struct buffer_mapping *mapping = get_buffer_mapping(target);'
578 print ' if (mapping) {'
579 print ' mapping->map = %s;' % (instance)
580 print ' mapping->length = length;'
581 print ' mapping->write = access & GL_MAP_WRITE_BIT;'
José Fonseca73373602011-05-20 17:45:26 +0100582 print ' mapping->explicit_flush = access & GL_MAP_FLUSH_EXPLICIT_BIT;'
José Fonseca867b1b72011-04-24 11:58:04 +0100583 print ' }'
José Fonseca669b1222011-02-20 09:05:10 +0000584
José Fonsecac9f12232011-03-25 20:07:42 +0000585 boolean_names = [
586 'GL_FALSE',
587 'GL_TRUE',
588 ]
589
590 def gl_boolean(self, value):
591 return self.boolean_names[int(bool(value))]
592
José Fonsecac29f4f12011-06-11 12:19:05 +0100593 # Names of the functions that unpack from a pixel buffer object. See the
594 # ARB_pixel_buffer_object specification.
José Fonsecae97bab92011-06-02 23:15:11 +0100595 unpack_function_names = set([
596 'glBitmap',
José Fonsecac29f4f12011-06-11 12:19:05 +0100597 'glColorSubTable',
598 'glColorTable',
599 'glCompressedTexImage1D',
600 'glCompressedTexImage2D',
601 'glCompressedTexImage3D',
602 'glCompressedTexSubImage1D',
603 'glCompressedTexSubImage2D',
604 'glCompressedTexSubImage3D',
605 'glConvolutionFilter1D',
606 'glConvolutionFilter2D',
José Fonsecae97bab92011-06-02 23:15:11 +0100607 'glDrawPixels',
608 'glMultiTexImage1DEXT',
609 'glMultiTexImage2DEXT',
610 'glMultiTexImage3DEXT',
611 'glMultiTexSubImage1DEXT',
612 'glMultiTexSubImage2DEXT',
613 'glMultiTexSubImage3DEXT',
José Fonsecac29f4f12011-06-11 12:19:05 +0100614 'glPixelMapfv',
615 'glPixelMapuiv',
616 'glPixelMapusv',
José Fonsecae97bab92011-06-02 23:15:11 +0100617 'glPolygonStipple',
José Fonsecac29f4f12011-06-11 12:19:05 +0100618 'glSeparableFilter2D',
José Fonsecae97bab92011-06-02 23:15:11 +0100619 'glTexImage1D',
620 'glTexImage1DEXT',
621 'glTexImage2D',
622 'glTexImage2DEXT',
623 'glTexImage3D',
624 'glTexImage3DEXT',
625 'glTexSubImage1D',
626 'glTexSubImage1DEXT',
627 'glTexSubImage2D',
628 'glTexSubImage2DEXT',
629 'glTexSubImage3D',
630 'glTexSubImage3DEXT',
631 'glTextureImage1DEXT',
632 'glTextureImage2DEXT',
633 'glTextureImage3DEXT',
634 'glTextureSubImage1DEXT',
635 'glTextureSubImage2DEXT',
636 'glTextureSubImage3DEXT',
637 ])
638
José Fonseca99221832011-03-22 22:15:46 +0000639 def dump_arg_instance(self, function, arg):
640 if function.name in self.draw_function_names and arg.name == 'indices':
José Fonseca8a6c6cb2011-03-23 16:44:30 +0000641 print ' GLint __element_array_buffer = 0;'
642 print ' __glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &__element_array_buffer);'
643 print ' if (!__element_array_buffer) {'
José Fonseca5c749e32011-05-09 11:11:37 +0100644 if isinstance(arg.type, stdapi.Array):
José Fonsecab4a3d142011-10-27 07:43:19 +0100645 print ' trace::localWriter.beginArray(%s);' % arg.type.length
José Fonseca5c749e32011-05-09 11:11:37 +0100646 print ' for(GLsizei i = 0; i < %s; ++i) {' % arg.type.length
José Fonsecab4a3d142011-10-27 07:43:19 +0100647 print ' trace::localWriter.beginElement();'
648 print ' trace::localWriter.writeBlob(%s[i], count[i]*__gl_type_size(type));' % (arg.name)
649 print ' trace::localWriter.endElement();'
José Fonseca5c749e32011-05-09 11:11:37 +0100650 print ' }'
José Fonsecab4a3d142011-10-27 07:43:19 +0100651 print ' trace::localWriter.endArray();'
José Fonseca5c749e32011-05-09 11:11:37 +0100652 else:
José Fonsecab4a3d142011-10-27 07:43:19 +0100653 print ' trace::localWriter.writeBlob(%s, count*__gl_type_size(type));' % (arg.name)
José Fonseca8a6c6cb2011-03-23 16:44:30 +0000654 print ' } else {'
José Fonseca5c749e32011-05-09 11:11:37 +0100655 Tracer.dump_arg_instance(self, function, arg)
José Fonseca8a6c6cb2011-03-23 16:44:30 +0000656 print ' }'
657 return
658
José Fonsecae97bab92011-06-02 23:15:11 +0100659 # Recognize offsets instead of blobs when a PBO is bound
660 if function.name in self.unpack_function_names \
661 and (isinstance(arg.type, stdapi.Blob) \
662 or (isinstance(arg.type, stdapi.Const) \
663 and isinstance(arg.type.type, stdapi.Blob))):
José Fonsecac29f4f12011-06-11 12:19:05 +0100664 print ' {'
665 print ' GLint __unpack_buffer = 0;'
666 print ' __glGetIntegerv(GL_PIXEL_UNPACK_BUFFER_BINDING, &__unpack_buffer);'
667 print ' if (__unpack_buffer) {'
José Fonsecab4a3d142011-10-27 07:43:19 +0100668 print ' trace::localWriter.writeOpaque(%s);' % arg.name
José Fonsecac29f4f12011-06-11 12:19:05 +0100669 print ' } else {'
José Fonsecae97bab92011-06-02 23:15:11 +0100670 Tracer.dump_arg_instance(self, function, arg)
José Fonsecac29f4f12011-06-11 12:19:05 +0100671 print ' }'
José Fonsecae97bab92011-06-02 23:15:11 +0100672 print ' }'
673 return
674
José Fonsecaa3f89ae2011-04-26 08:50:32 +0100675 # Several GL state functions take GLenum symbolic names as
676 # integer/floats; so dump the symbolic name whenever possible
José Fonseca3bcb33c2011-05-27 20:14:31 +0100677 if function.name.startswith('gl') \
José Fonsecae3571092011-10-13 08:26:27 +0100678 and arg.type in (glapi.GLint, glapi.GLfloat, glapi.GLdouble) \
José Fonseca3bcb33c2011-05-27 20:14:31 +0100679 and arg.name == 'param':
José Fonsecaa3f89ae2011-04-26 08:50:32 +0100680 assert arg.index > 0
681 assert function.args[arg.index - 1].name == 'pname'
682 assert function.args[arg.index - 1].type == glapi.GLenum
683 print ' if (is_symbolic_pname(pname) && is_symbolic_param(%s)) {' % arg.name
684 dump_instance(glapi.GLenum, arg.name)
685 print ' } else {'
686 Tracer.dump_arg_instance(self, function, arg)
687 print ' }'
688 return
689
José Fonseca8a6c6cb2011-03-23 16:44:30 +0000690 Tracer.dump_arg_instance(self, function, arg)
José Fonseca99221832011-03-22 22:15:46 +0000691
José Fonseca4c938c22011-04-30 22:44:38 +0100692 def footer(self, api):
693 Tracer.footer(self, api)
José Fonseca669b1222011-02-20 09:05:10 +0000694
José Fonseca4c938c22011-04-30 22:44:38 +0100695 # A simple state tracker to track the pointer values
José Fonseca669b1222011-02-20 09:05:10 +0000696 # update the state
José Fonseca8a6c6cb2011-03-23 16:44:30 +0000697 print 'static void __trace_user_arrays(GLuint maxindex)'
José Fonseca669b1222011-02-20 09:05:10 +0000698 print '{'
José Fonseca1a2fdd22011-04-01 00:55:09 +0100699
José Fonseca99221832011-03-22 22:15:46 +0000700 for camelcase_name, uppercase_name in self.arrays:
701 function_name = 'gl%sPointer' % camelcase_name
702 enable_name = 'GL_%s_ARRAY' % uppercase_name
703 binding_name = 'GL_%s_ARRAY_BUFFER_BINDING' % uppercase_name
José Fonseca14c21bc2011-02-20 23:32:22 +0000704 function = api.get_function_by_name(function_name)
José Fonseca99221832011-03-22 22:15:46 +0000705
José Fonseca06e85192011-10-16 14:15:36 +0100706 print ' // %s' % function.prototype()
José Fonsecafb6744f2011-04-15 11:18:37 +0100707 self.array_trace_prolog(api, uppercase_name)
708 self.array_prolog(api, uppercase_name)
709 print ' if (__glIsEnabled(%s)) {' % enable_name
José Fonseca7f5163e2011-03-31 23:37:26 +0100710 print ' GLint __binding = 0;'
711 print ' __glGetIntegerv(%s, &__binding);' % binding_name
712 print ' if (!__binding) {'
José Fonseca99221832011-03-22 22:15:46 +0000713
714 # Get the arguments via glGet*
715 for arg in function.args:
716 arg_get_enum = 'GL_%s_ARRAY_%s' % (uppercase_name, arg.name.upper())
717 arg_get_function, arg_type = TypeGetter().visit(arg.type)
José Fonseca7f5163e2011-03-31 23:37:26 +0100718 print ' %s %s = 0;' % (arg_type, arg.name)
719 print ' __%s(%s, &%s);' % (arg_get_function, arg_get_enum, arg.name)
José Fonseca99221832011-03-22 22:15:46 +0000720
721 arg_names = ', '.join([arg.name for arg in function.args[:-1]])
José Fonseca7f5163e2011-03-31 23:37:26 +0100722 print ' size_t __size = __%s_size(%s, maxindex);' % (function.name, arg_names)
José Fonseca99221832011-03-22 22:15:46 +0000723
724 # Emit a fake function
José Fonsecafb6744f2011-04-15 11:18:37 +0100725 self.array_trace_intermezzo(api, uppercase_name)
José Fonsecab4a3d142011-10-27 07:43:19 +0100726 print ' unsigned __call = trace::localWriter.beginEnter(&__%s_sig);' % (function.name,)
José Fonseca669b1222011-02-20 09:05:10 +0000727 for arg in function.args:
728 assert not arg.output
José Fonsecab4a3d142011-10-27 07:43:19 +0100729 print ' trace::localWriter.beginArg(%u);' % (arg.index,)
José Fonseca14c21bc2011-02-20 23:32:22 +0000730 if arg.name != 'pointer':
José Fonseca99221832011-03-22 22:15:46 +0000731 dump_instance(arg.type, arg.name)
José Fonseca14c21bc2011-02-20 23:32:22 +0000732 else:
José Fonsecab4a3d142011-10-27 07:43:19 +0100733 print ' trace::localWriter.writeBlob((const void *)%s, __size);' % (arg.name)
734 print ' trace::localWriter.endArg();'
José Fonseca99221832011-03-22 22:15:46 +0000735
José Fonsecab4a3d142011-10-27 07:43:19 +0100736 print ' trace::localWriter.endEnter();'
737 print ' trace::localWriter.beginLeave(__call);'
738 print ' trace::localWriter.endLeave();'
José Fonseca99221832011-03-22 22:15:46 +0000739 print ' }'
José Fonseca669b1222011-02-20 09:05:10 +0000740 print ' }'
José Fonsecafb6744f2011-04-15 11:18:37 +0100741 self.array_epilog(api, uppercase_name)
742 self.array_trace_epilog(api, uppercase_name)
José Fonseca99221832011-03-22 22:15:46 +0000743 print
José Fonseca1a2fdd22011-04-01 00:55:09 +0100744
José Fonseca1601c412011-05-10 10:38:19 +0100745 # Samething, but for glVertexAttribPointer*
746 #
747 # Some variants of glVertexAttribPointer alias conventional and generic attributes:
748 # - glVertexAttribPointer: no
749 # - glVertexAttribPointerARB: implementation dependent
750 # - glVertexAttribPointerNV: yes
751 #
752 # This means that the implementations of these functions do not always
753 # alias, and they need to be considered independently.
754 #
José Fonseca5a568a92011-06-29 16:43:36 +0100755 print ' vertex_attrib __vertex_attrib = __get_vertex_attrib();'
756 print
757 for suffix in ['', 'ARB', 'NV']:
758 if suffix:
José Fonsecad94aaac2011-06-28 20:50:49 +0100759 SUFFIX = '_' + suffix
José Fonsecad94aaac2011-06-28 20:50:49 +0100760 else:
José Fonseca5a568a92011-06-29 16:43:36 +0100761 SUFFIX = suffix
José Fonseca1601c412011-05-10 10:38:19 +0100762 function_name = 'glVertexAttribPointer' + suffix
José Fonseca06e85192011-10-16 14:15:36 +0100763 function = api.get_function_by_name(function_name)
764
765 print ' // %s' % function.prototype()
José Fonseca5a568a92011-06-29 16:43:36 +0100766 print ' if (__vertex_attrib == VERTEX_ATTRIB%s) {' % SUFFIX
767 if suffix == 'NV':
768 print ' GLint __max_vertex_attribs = 16;'
769 else:
770 print ' GLint __max_vertex_attribs = 0;'
771 print ' __glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &__max_vertex_attribs);'
772 print ' for (GLint index = 0; index < __max_vertex_attribs; ++index) {'
773 print ' GLint __enabled = 0;'
774 if suffix == 'NV':
775 print ' __glGetIntegerv(GL_VERTEX_ATTRIB_ARRAY0_NV + index, &__enabled);'
776 else:
777 print ' __glGetVertexAttribiv%s(index, GL_VERTEX_ATTRIB_ARRAY_ENABLED%s, &__enabled);' % (suffix, SUFFIX)
778 print ' if (__enabled) {'
779 print ' GLint __binding = 0;'
780 if suffix != 'NV':
781 # It doesn't seem possible to use VBOs with NV_vertex_program.
782 print ' __glGetVertexAttribiv%s(index, GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING%s, &__binding);' % (suffix, SUFFIX)
783 print ' if (!__binding) {'
José Fonseca1a2fdd22011-04-01 00:55:09 +0100784
José Fonseca1601c412011-05-10 10:38:19 +0100785 # Get the arguments via glGet*
786 for arg in function.args[1:]:
José Fonseca5a568a92011-06-29 16:43:36 +0100787 if suffix == 'NV':
788 arg_get_enum = 'GL_ATTRIB_ARRAY_%s%s' % (arg.name.upper(), SUFFIX)
789 else:
790 arg_get_enum = 'GL_VERTEX_ATTRIB_ARRAY_%s%s' % (arg.name.upper(), SUFFIX)
José Fonsecac493e3e2011-06-29 12:57:06 +0100791 arg_get_function, arg_type = TypeGetter('glGetVertexAttrib', False, suffix).visit(arg.type)
José Fonseca5a568a92011-06-29 16:43:36 +0100792 print ' %s %s = 0;' % (arg_type, arg.name)
793 print ' __%s(index, %s, &%s);' % (arg_get_function, arg_get_enum, arg.name)
José Fonseca1601c412011-05-10 10:38:19 +0100794
795 arg_names = ', '.join([arg.name for arg in function.args[1:-1]])
José Fonseca5a568a92011-06-29 16:43:36 +0100796 print ' size_t __size = __%s_size(%s, maxindex);' % (function.name, arg_names)
José Fonseca1a2fdd22011-04-01 00:55:09 +0100797
José Fonseca1601c412011-05-10 10:38:19 +0100798 # Emit a fake function
José Fonsecab4a3d142011-10-27 07:43:19 +0100799 print ' unsigned __call = trace::localWriter.beginEnter(&__%s_sig);' % (function.name,)
José Fonseca1601c412011-05-10 10:38:19 +0100800 for arg in function.args:
801 assert not arg.output
José Fonsecab4a3d142011-10-27 07:43:19 +0100802 print ' trace::localWriter.beginArg(%u);' % (arg.index,)
José Fonseca1601c412011-05-10 10:38:19 +0100803 if arg.name != 'pointer':
804 dump_instance(arg.type, arg.name)
805 else:
José Fonsecab4a3d142011-10-27 07:43:19 +0100806 print ' trace::localWriter.writeBlob((const void *)%s, __size);' % (arg.name)
807 print ' trace::localWriter.endArg();'
José Fonseca1601c412011-05-10 10:38:19 +0100808
José Fonsecab4a3d142011-10-27 07:43:19 +0100809 print ' trace::localWriter.endEnter();'
810 print ' trace::localWriter.beginLeave(__call);'
811 print ' trace::localWriter.endLeave();'
José Fonseca1601c412011-05-10 10:38:19 +0100812 print ' }'
813 print ' }'
814 print ' }'
815 print ' }'
816 print
José Fonseca1a2fdd22011-04-01 00:55:09 +0100817
José Fonseca669b1222011-02-20 09:05:10 +0000818 print '}'
819 print
820
José Fonsecafb6744f2011-04-15 11:18:37 +0100821 #
822 # Hooks for glTexCoordPointer, which is identical to the other array
823 # pointers except the fact that it is indexed by glClientActiveTexture.
824 #
825
826 def array_prolog(self, api, uppercase_name):
827 if uppercase_name == 'TEXTURE_COORD':
828 print ' GLint client_active_texture = 0;'
829 print ' __glGetIntegerv(GL_CLIENT_ACTIVE_TEXTURE, &client_active_texture);'
830 print ' GLint max_texture_coords = 0;'
831 print ' __glGetIntegerv(GL_MAX_TEXTURE_COORDS, &max_texture_coords);'
832 print ' for (GLint unit = 0; unit < max_texture_coords; ++unit) {'
José Fonseca7525e6f2011-09-28 09:04:56 +0100833 print ' GLint texture = GL_TEXTURE0 + unit;'
José Fonsecafb6744f2011-04-15 11:18:37 +0100834 print ' __glClientActiveTexture(texture);'
835
836 def array_trace_prolog(self, api, uppercase_name):
837 if uppercase_name == 'TEXTURE_COORD':
838 print ' bool client_active_texture_dirty = false;'
839
840 def array_epilog(self, api, uppercase_name):
841 if uppercase_name == 'TEXTURE_COORD':
842 print ' }'
843 self.array_cleanup(api, uppercase_name)
844
845 def array_cleanup(self, api, uppercase_name):
846 if uppercase_name == 'TEXTURE_COORD':
847 print ' __glClientActiveTexture(client_active_texture);'
848
849 def array_trace_intermezzo(self, api, uppercase_name):
850 if uppercase_name == 'TEXTURE_COORD':
851 print ' if (texture != client_active_texture || client_active_texture_dirty) {'
852 print ' client_active_texture_dirty = true;'
853 self.fake_glClientActiveTexture_call(api, "texture");
854 print ' }'
855
856 def array_trace_epilog(self, api, uppercase_name):
857 if uppercase_name == 'TEXTURE_COORD':
858 print ' if (client_active_texture_dirty) {'
859 self.fake_glClientActiveTexture_call(api, "client_active_texture");
860 print ' }'
861
862 def fake_glClientActiveTexture_call(self, api, texture):
863 function = api.get_function_by_name('glClientActiveTexture')
864 self.fake_call(function, [texture])
865
866 def fake_call(self, function, args):
José Fonsecab4a3d142011-10-27 07:43:19 +0100867 print ' unsigned __fake_call = trace::localWriter.beginEnter(&__%s_sig);' % (function.name,)
José Fonsecafb6744f2011-04-15 11:18:37 +0100868 for arg, instance in zip(function.args, args):
869 assert not arg.output
José Fonsecab4a3d142011-10-27 07:43:19 +0100870 print ' trace::localWriter.beginArg(%u);' % (arg.index,)
José Fonsecafb6744f2011-04-15 11:18:37 +0100871 dump_instance(arg.type, instance)
José Fonsecab4a3d142011-10-27 07:43:19 +0100872 print ' trace::localWriter.endArg();'
873 print ' trace::localWriter.endEnter();'
874 print ' trace::localWriter.beginLeave(__fake_call);'
875 print ' trace::localWriter.endLeave();'
José Fonsecafb6744f2011-04-15 11:18:37 +0100876
877
878
879
880
José Fonseca669b1222011-02-20 09:05:10 +0000881
882
883
884
885
886