blob: d4fb4a9be24aa68fd33297694fea7cf64e1d5fec [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 Wu9da53de2011-11-03 01:32:35 +0800112 print 'enum gl_context_profile {'
113 print ' PROFILE_COMPAT,'
114 print '};'
115 print
Chia-I Wu8ef66972011-11-03 01:19:46 +0800116 print 'struct tracer_context {'
Chia-I Wu9da53de2011-11-03 01:32:35 +0800117 print ' enum gl_context_profile profile;'
Chia-I Wu8ef66972011-11-03 01:19:46 +0800118 print ' bool user_arrays;'
119 print ' bool user_arrays_arb;'
120 print ' bool user_arrays_nv;'
121 print '};'
José Fonseca25ebe542011-04-24 10:08:22 +0100122 print
José Fonseca5a568a92011-06-29 16:43:36 +0100123
124 # Which glVertexAttrib* variant to use
125 print 'enum vertex_attrib {'
126 print ' VERTEX_ATTRIB,'
127 print ' VERTEX_ATTRIB_ARB,'
128 print ' VERTEX_ATTRIB_NV,'
129 print '};'
130 print
Chia-I Wu8ef66972011-11-03 01:19:46 +0800131 print 'static tracer_context *__get_context(void)'
132 print '{'
133 print ' // TODO return the context set by other APIs (GLX, EGL, and etc.)'
Chia-I Wu9da53de2011-11-03 01:32:35 +0800134 print ' static tracer_context __ctx = { PROFILE_COMPAT, false, false, false };'
Chia-I Wu8ef66972011-11-03 01:19:46 +0800135 print ' return &__ctx;'
136 print '}'
137 print
José Fonseca5a568a92011-06-29 16:43:36 +0100138 print 'static vertex_attrib __get_vertex_attrib(void) {'
Chia-I Wu8ef66972011-11-03 01:19:46 +0800139 print ' tracer_context *ctx = __get_context();'
140 print ' if (ctx->user_arrays_arb || ctx->user_arrays_nv) {'
José Fonseca5a568a92011-06-29 16:43:36 +0100141 print ' GLboolean __vertex_program = GL_FALSE;'
142 print ' __glGetBooleanv(GL_VERTEX_PROGRAM_ARB, &__vertex_program);'
143 print ' if (__vertex_program) {'
Chia-I Wu8ef66972011-11-03 01:19:46 +0800144 print ' if (ctx->user_arrays_nv) {'
José Fonseca5a568a92011-06-29 16:43:36 +0100145 print ' GLint __vertex_program_binding_nv = 0;'
146 print ' __glGetIntegerv(GL_VERTEX_PROGRAM_BINDING_NV, &__vertex_program_binding_nv);'
147 print ' if (__vertex_program_binding_nv) {'
148 print ' return VERTEX_ATTRIB_NV;'
149 print ' }'
150 print ' }'
151 print ' return VERTEX_ATTRIB_ARB;'
152 print ' }'
153 print ' }'
154 print ' return VERTEX_ATTRIB;'
155 print '}'
156 print
157
José Fonseca8a6c6cb2011-03-23 16:44:30 +0000158 # Whether we need user arrays
159 print 'static inline bool __need_user_arrays(void)'
160 print '{'
Chia-I Wu8ef66972011-11-03 01:19:46 +0800161 print ' tracer_context *ctx = __get_context();'
162 print ' if (!ctx->user_arrays) {'
José Fonseca25ebe542011-04-24 10:08:22 +0100163 print ' return false;'
164 print ' }'
165 print
José Fonseca1a2fdd22011-04-01 00:55:09 +0100166
José Fonseca8a6c6cb2011-03-23 16:44:30 +0000167 for camelcase_name, uppercase_name in self.arrays:
168 function_name = 'gl%sPointer' % camelcase_name
169 enable_name = 'GL_%s_ARRAY' % uppercase_name
170 binding_name = 'GL_%s_ARRAY_BUFFER_BINDING' % uppercase_name
171 print ' // %s' % function_name
José Fonsecafb6744f2011-04-15 11:18:37 +0100172 self.array_prolog(api, uppercase_name)
José Fonseca7f5163e2011-03-31 23:37:26 +0100173 print ' if (__glIsEnabled(%s)) {' % enable_name
174 print ' GLint __binding = 0;'
175 print ' __glGetIntegerv(%s, &__binding);' % binding_name
176 print ' if (!__binding) {'
José Fonsecafb6744f2011-04-15 11:18:37 +0100177 self.array_cleanup(api, uppercase_name)
José Fonseca7f5163e2011-03-31 23:37:26 +0100178 print ' return true;'
José Fonseca8a6c6cb2011-03-23 16:44:30 +0000179 print ' }'
180 print ' }'
José Fonsecafb6744f2011-04-15 11:18:37 +0100181 self.array_epilog(api, uppercase_name)
José Fonseca8a6c6cb2011-03-23 16:44:30 +0000182 print
José Fonseca7f5163e2011-03-31 23:37:26 +0100183
José Fonseca5a568a92011-06-29 16:43:36 +0100184 print ' vertex_attrib __vertex_attrib = __get_vertex_attrib();'
185 print
186 print ' // glVertexAttribPointer'
187 print ' if (__vertex_attrib == VERTEX_ATTRIB) {'
188 print ' GLint __max_vertex_attribs = 0;'
189 print ' __glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &__max_vertex_attribs);'
190 print ' for (GLint index = 0; index < __max_vertex_attribs; ++index) {'
191 print ' GLint __enabled = 0;'
192 print ' __glGetVertexAttribiv(index, GL_VERTEX_ATTRIB_ARRAY_ENABLED, &__enabled);'
193 print ' if (__enabled) {'
194 print ' GLint __binding = 0;'
195 print ' __glGetVertexAttribiv(index, GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING, &__binding);'
196 print ' if (!__binding) {'
197 print ' return true;'
198 print ' }'
199 print ' }'
200 print ' }'
201 print ' }'
202 print
203 print ' // glVertexAttribPointerARB'
204 print ' if (__vertex_attrib == VERTEX_ATTRIB_ARB) {'
José Fonsecad94aaac2011-06-28 20:50:49 +0100205 print ' GLint __max_vertex_attribs = 0;'
206 print ' __glGetIntegerv(GL_MAX_VERTEX_ATTRIBS_ARB, &__max_vertex_attribs);'
207 print ' for (GLint index = 0; index < __max_vertex_attribs; ++index) {'
208 print ' GLint __enabled = 0;'
209 print ' __glGetVertexAttribivARB(index, GL_VERTEX_ATTRIB_ARRAY_ENABLED_ARB, &__enabled);'
210 print ' if (__enabled) {'
211 print ' GLint __binding = 0;'
212 print ' __glGetVertexAttribivARB(index, GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING_ARB, &__binding);'
213 print ' if (!__binding) {'
214 print ' return true;'
215 print ' }'
216 print ' }'
217 print ' }'
José Fonseca5a568a92011-06-29 16:43:36 +0100218 print ' }'
219 print
220 print ' // glVertexAttribPointerNV'
221 print ' if (__vertex_attrib == VERTEX_ATTRIB_NV) {'
222 print ' for (GLint index = 0; index < 16; ++index) {'
José Fonsecad94aaac2011-06-28 20:50:49 +0100223 print ' GLint __enabled = 0;'
José Fonseca5a568a92011-06-29 16:43:36 +0100224 print ' __glGetIntegerv(GL_VERTEX_ATTRIB_ARRAY0_NV + index, &__enabled);'
José Fonsecad94aaac2011-06-28 20:50:49 +0100225 print ' if (__enabled) {'
José Fonseca5a568a92011-06-29 16:43:36 +0100226 print ' return true;'
José Fonseca1a2fdd22011-04-01 00:55:09 +0100227 print ' }'
228 print ' }'
229 print ' }'
230 print
231
José Fonseca8a6c6cb2011-03-23 16:44:30 +0000232 print ' return false;'
233 print '}'
234 print
José Fonseca669b1222011-02-20 09:05:10 +0000235
José Fonseca8a6c6cb2011-03-23 16:44:30 +0000236 print 'static void __trace_user_arrays(GLuint maxindex);'
José Fonseca14c21bc2011-02-20 23:32:22 +0000237 print
José Fonseca867b1b72011-04-24 11:58:04 +0100238
239 print 'struct buffer_mapping {'
240 print ' void *map;'
241 print ' GLint length;'
242 print ' bool write;'
José Fonseca73373602011-05-20 17:45:26 +0100243 print ' bool explicit_flush;'
José Fonseca867b1b72011-04-24 11:58:04 +0100244 print '};'
245 print
246 for target in self.buffer_targets:
247 print 'struct buffer_mapping __%s_mapping;' % target.lower();
248 print
249 print 'static inline struct buffer_mapping *'
250 print 'get_buffer_mapping(GLenum target) {'
José Fonseca06e85192011-10-16 14:15:36 +0100251 print ' switch (target) {'
José Fonseca867b1b72011-04-24 11:58:04 +0100252 for target in self.buffer_targets:
253 print ' case GL_%s:' % target
254 print ' return & __%s_mapping;' % target.lower()
255 print ' default:'
José Fonseca559d5342011-10-27 08:10:56 +0100256 print ' os::log("apitrace: warning: unknown buffer target 0x%04X\\n", target);'
José Fonseca867b1b72011-04-24 11:58:04 +0100257 print ' return NULL;'
258 print ' }'
259 print '}'
260 print
261
José Fonsecaa3f89ae2011-04-26 08:50:32 +0100262 # Generate a helper function to determine whether a parameter name
263 # refers to a symbolic value or not
264 print 'static bool'
265 print 'is_symbolic_pname(GLenum pname) {'
José Fonseca06e85192011-10-16 14:15:36 +0100266 print ' switch (pname) {'
José Fonseca5ea91872011-05-04 09:41:55 +0100267 for function, type, count, name in glparams.parameters:
José Fonsecaa3f89ae2011-04-26 08:50:32 +0100268 if type is glapi.GLenum:
José Fonseca4c938c22011-04-30 22:44:38 +0100269 print ' case %s:' % name
270 print ' return true;'
271 print ' default:'
272 print ' return false;'
José Fonsecaa3f89ae2011-04-26 08:50:32 +0100273 print ' }'
274 print '}'
275 print
276
277 # Generate a helper function to determine whether a parameter value is
278 # potentially symbolic or not; i.e., if the value can be represented in
279 # an enum or not
280 print 'template<class T>'
281 print 'static inline bool'
282 print 'is_symbolic_param(T param) {'
283 print ' return static_cast<T>(static_cast<GLenum>(param)) == param;'
284 print '}'
285 print
José Fonseca4c938c22011-04-30 22:44:38 +0100286
287 # Generate a helper function to know how many elements a parameter has
288 print 'static size_t'
José Fonsecaf4aca5d2011-05-08 08:29:30 +0100289 print '__gl_param_size(GLenum pname) {'
José Fonseca06e85192011-10-16 14:15:36 +0100290 print ' switch (pname) {'
José Fonseca5ea91872011-05-04 09:41:55 +0100291 for function, type, count, name in glparams.parameters:
José Fonseca4c938c22011-04-30 22:44:38 +0100292 if type is not None:
293 print ' case %s: return %u;' % (name, count)
294 print ' case GL_COMPRESSED_TEXTURE_FORMATS: {'
295 print ' GLint num_compressed_texture_formats = 0;'
296 print ' __glGetIntegerv(GL_NUM_COMPRESSED_TEXTURE_FORMATS, &num_compressed_texture_formats);'
297 print ' return num_compressed_texture_formats;'
298 print ' }'
299 print ' default:'
José Fonseca559d5342011-10-27 08:10:56 +0100300 print r' os::log("apitrace: warning: %s: unknown GLenum 0x%04X\n", __FUNCTION__, pname);'
José Fonseca4c938c22011-04-30 22:44:38 +0100301 print ' return 1;'
302 print ' }'
303 print '}'
304 print
305
José Fonseca99221832011-03-22 22:15:46 +0000306 array_pointer_function_names = set((
307 "glVertexPointer",
308 "glNormalPointer",
309 "glColorPointer",
310 "glIndexPointer",
311 "glTexCoordPointer",
312 "glEdgeFlagPointer",
313 "glFogCoordPointer",
314 "glSecondaryColorPointer",
José Fonseca7f5163e2011-03-31 23:37:26 +0100315
José Fonsecaac5285b2011-05-04 11:09:08 +0100316 "glInterleavedArrays",
317
José Fonseca7e0bfd92011-04-30 23:09:03 +0100318 "glVertexPointerEXT",
319 "glNormalPointerEXT",
320 "glColorPointerEXT",
321 "glIndexPointerEXT",
322 "glTexCoordPointerEXT",
323 "glEdgeFlagPointerEXT",
324 "glFogCoordPointerEXT",
325 "glSecondaryColorPointerEXT",
José Fonseca99221832011-03-22 22:15:46 +0000326
José Fonseca7f5163e2011-03-31 23:37:26 +0100327 "glVertexAttribPointer",
328 "glVertexAttribPointerARB",
329 "glVertexAttribPointerNV",
José Fonsecaac5285b2011-05-04 11:09:08 +0100330 "glVertexAttribIPointer",
331 "glVertexAttribIPointerEXT",
José Fonseca7f5163e2011-03-31 23:37:26 +0100332 "glVertexAttribLPointer",
333 "glVertexAttribLPointerEXT",
José Fonseca99221832011-03-22 22:15:46 +0000334
335 #"glMatrixIndexPointerARB",
336 ))
337
338 draw_function_names = set((
339 'glDrawArrays',
340 'glDrawElements',
341 'glDrawRangeElements',
José Fonseca5c749e32011-05-09 11:11:37 +0100342 'glMultiDrawArrays',
343 'glMultiDrawElements',
344 'glDrawArraysInstanced',
José Fonsecaff8848b2011-10-09 01:04:17 +0100345 "glDrawArraysInstancedBaseInstance",
José Fonseca5c749e32011-05-09 11:11:37 +0100346 'glDrawElementsInstanced',
347 'glDrawArraysInstancedARB',
348 'glDrawElementsInstancedARB',
349 'glDrawElementsBaseVertex',
350 'glDrawRangeElementsBaseVertex',
351 'glDrawElementsInstancedBaseVertex',
José Fonsecaff8848b2011-10-09 01:04:17 +0100352 "glDrawElementsInstancedBaseInstance",
353 "glDrawElementsInstancedBaseVertexBaseInstance",
José Fonseca5c749e32011-05-09 11:11:37 +0100354 'glMultiDrawElementsBaseVertex',
355 'glDrawArraysIndirect',
356 'glDrawElementsIndirect',
357 'glDrawArraysEXT',
José Fonseca7e0bfd92011-04-30 23:09:03 +0100358 'glDrawRangeElementsEXT',
José Fonseca5c749e32011-05-09 11:11:37 +0100359 'glDrawRangeElementsEXT_size',
360 'glMultiDrawArraysEXT',
361 'glMultiDrawElementsEXT',
362 'glMultiModeDrawArraysIBM',
363 'glMultiModeDrawElementsIBM',
364 'glDrawArraysInstancedEXT',
365 'glDrawElementsInstancedEXT',
José Fonseca99221832011-03-22 22:15:46 +0000366 ))
367
José Fonsecac9f12232011-03-25 20:07:42 +0000368 interleaved_formats = [
369 'GL_V2F',
370 'GL_V3F',
371 'GL_C4UB_V2F',
372 'GL_C4UB_V3F',
373 'GL_C3F_V3F',
374 'GL_N3F_V3F',
375 'GL_C4F_N3F_V3F',
376 'GL_T2F_V3F',
377 'GL_T4F_V4F',
378 'GL_T2F_C4UB_V3F',
379 'GL_T2F_C3F_V3F',
380 'GL_T2F_N3F_V3F',
381 'GL_T2F_C4F_N3F_V3F',
382 'GL_T4F_C4F_N3F_V4F',
383 ]
384
José Fonseca14c21bc2011-02-20 23:32:22 +0000385 def trace_function_impl_body(self, function):
José Fonseca8a6c6cb2011-03-23 16:44:30 +0000386 # Defer tracing of user array pointers...
José Fonseca99221832011-03-22 22:15:46 +0000387 if function.name in self.array_pointer_function_names:
388 print ' GLint __array_buffer = 0;'
389 print ' __glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &__array_buffer);'
390 print ' if (!__array_buffer) {'
Chia-I Wu8ef66972011-11-03 01:19:46 +0800391 print ' tracer_context *ctx = __get_context();'
392 print ' ctx->user_arrays = true;'
José Fonseca5a568a92011-06-29 16:43:36 +0100393 if function.name == "glVertexAttribPointerARB":
Chia-I Wu8ef66972011-11-03 01:19:46 +0800394 print ' ctx->user_arrays_arb = true;'
José Fonseca5a568a92011-06-29 16:43:36 +0100395 if function.name == "glVertexAttribPointerNV":
Chia-I Wu8ef66972011-11-03 01:19:46 +0800396 print ' ctx->user_arrays_nv = true;'
José Fonseca14c21bc2011-02-20 23:32:22 +0000397 self.dispatch_function(function)
José Fonsecaac5285b2011-05-04 11:09:08 +0100398
399 # And also break down glInterleavedArrays into the individual calls
400 if function.name == 'glInterleavedArrays':
401 print
402
403 # Initialize the enable flags
404 for camelcase_name, uppercase_name in self.arrays:
405 flag_name = '__' + uppercase_name.lower()
406 print ' GLboolean %s = GL_FALSE;' % flag_name
407 print
408
409 # Switch for the interleaved formats
410 print ' switch (format) {'
411 for format in self.interleaved_formats:
412 print ' case %s:' % format
413 for camelcase_name, uppercase_name in self.arrays:
414 flag_name = '__' + uppercase_name.lower()
415 if format.find('_' + uppercase_name[0]) >= 0:
416 print ' %s = GL_TRUE;' % flag_name
417 print ' break;'
418 print ' default:'
419 print ' return;'
420 print ' }'
421 print
422
423 # Emit fake glEnableClientState/glDisableClientState flags
424 for camelcase_name, uppercase_name in self.arrays:
425 flag_name = '__' + uppercase_name.lower()
426 enable_name = 'GL_%s_ARRAY' % uppercase_name
427
428 # Emit a fake function
429 print ' {'
José Fonsecab4a3d142011-10-27 07:43:19 +0100430 print ' static const trace::FunctionSig &__sig = %s ? __glEnableClientState_sig : __glDisableClientState_sig;' % flag_name
431 print ' unsigned __call = trace::localWriter.beginEnter(&__sig);'
432 print ' trace::localWriter.beginArg(0);'
José Fonsecaac5285b2011-05-04 11:09:08 +0100433 dump_instance(glapi.GLenum, enable_name)
José Fonsecab4a3d142011-10-27 07:43:19 +0100434 print ' trace::localWriter.endArg();'
435 print ' trace::localWriter.endEnter();'
436 print ' trace::localWriter.beginLeave(__call);'
437 print ' trace::localWriter.endLeave();'
José Fonsecaac5285b2011-05-04 11:09:08 +0100438 print ' }'
439
José Fonseca99221832011-03-22 22:15:46 +0000440 print ' return;'
441 print ' }'
José Fonseca14c21bc2011-02-20 23:32:22 +0000442
José Fonseca8a6c6cb2011-03-23 16:44:30 +0000443 # ... to the draw calls
José Fonseca99221832011-03-22 22:15:46 +0000444 if function.name in self.draw_function_names:
José Fonseca8a6c6cb2011-03-23 16:44:30 +0000445 print ' if (__need_user_arrays()) {'
José Fonseca99221832011-03-22 22:15:46 +0000446 arg_names = ', '.join([arg.name for arg in function.args[1:]])
José Fonseca8a6c6cb2011-03-23 16:44:30 +0000447 print ' GLuint maxindex = __%s_maxindex(%s);' % (function.name, arg_names)
448 print ' __trace_user_arrays(maxindex);'
449 print ' }'
José Fonseca14c21bc2011-02-20 23:32:22 +0000450
José Fonseca73373602011-05-20 17:45:26 +0100451 # Emit a fake memcpy on buffer uploads
452 if function.name in ('glUnmapBuffer', 'glUnmapBufferARB', ):
José Fonseca867b1b72011-04-24 11:58:04 +0100453 print ' struct buffer_mapping *mapping = get_buffer_mapping(target);'
José Fonseca73373602011-05-20 17:45:26 +0100454 print ' if (mapping && mapping->write && !mapping->explicit_flush) {'
455 self.emit_memcpy('mapping->map', 'mapping->map', 'mapping->length')
José Fonseca867b1b72011-04-24 11:58:04 +0100456 print ' }'
José Fonseca73373602011-05-20 17:45:26 +0100457 if function.name in ('glFlushMappedBufferRange', 'glFlushMappedBufferRangeAPPLE'):
José Fonseca73373602011-05-20 17:45:26 +0100458 print ' struct buffer_mapping *mapping = get_buffer_mapping(target);'
459 print ' if (mapping) {'
460 if function.name.endswith('APPLE'):
461 print ' GLsizeiptr length = size;'
462 print ' mapping->explicit_flush = true;'
463 print ' //assert(offset + length <= mapping->length);'
José Fonseca46a48392011-10-14 11:34:27 +0100464 self.emit_memcpy('(char *)mapping->map + offset', '(const char *)mapping->map + offset', 'length')
José Fonseca73373602011-05-20 17:45:26 +0100465 print ' }'
466 # FIXME: glFlushMappedNamedBufferRangeEXT
José Fonseca867b1b72011-04-24 11:58:04 +0100467
José Fonseca91492d22011-05-23 21:20:31 +0100468 # Don't leave vertex attrib locations to chance. Instead emit fake
469 # glBindAttribLocation calls to ensure that the same locations will be
470 # used when retracing. Trying to remap locations after the fact would
471 # be an herculian task given that vertex attrib locations appear in
472 # many entry-points, including non-shader related ones.
473 if function.name == 'glLinkProgram':
474 Tracer.dispatch_function(self, function)
475 print ' GLint active_attributes = 0;'
476 print ' __glGetProgramiv(program, GL_ACTIVE_ATTRIBUTES, &active_attributes);'
José Fonseca7525e6f2011-09-28 09:04:56 +0100477 print ' for (GLint attrib = 0; attrib < active_attributes; ++attrib) {'
José Fonseca91492d22011-05-23 21:20:31 +0100478 print ' GLint size = 0;'
479 print ' GLenum type = 0;'
480 print ' GLchar name[256];'
481 # TODO: Use ACTIVE_ATTRIBUTE_MAX_LENGTH instead of 256
482 print ' __glGetActiveAttrib(program, attrib, sizeof name, NULL, &size, &type, name);'
José Fonseca2a794f52011-05-26 20:54:29 +0100483 print " if (name[0] != 'g' || name[1] != 'l' || name[2] != '_') {"
484 print ' GLint location = __glGetAttribLocation(program, name);'
485 print ' if (location >= 0) {'
José Fonseca91492d22011-05-23 21:20:31 +0100486 bind_function = glapi.glapi.get_function_by_name('glBindAttribLocation')
487 self.fake_call(bind_function, ['program', 'location', 'name'])
José Fonseca2a794f52011-05-26 20:54:29 +0100488 print ' }'
José Fonseca91492d22011-05-23 21:20:31 +0100489 print ' }'
490 print ' }'
491 if function.name == 'glLinkProgramARB':
492 Tracer.dispatch_function(self, function)
493 print ' GLint active_attributes = 0;'
494 print ' __glGetObjectParameterivARB(programObj, GL_OBJECT_ACTIVE_ATTRIBUTES_ARB, &active_attributes);'
José Fonseca7525e6f2011-09-28 09:04:56 +0100495 print ' for (GLint attrib = 0; attrib < active_attributes; ++attrib) {'
José Fonseca91492d22011-05-23 21:20:31 +0100496 print ' GLint size = 0;'
497 print ' GLenum type = 0;'
498 print ' GLcharARB name[256];'
499 # TODO: Use ACTIVE_ATTRIBUTE_MAX_LENGTH instead of 256
500 print ' __glGetActiveAttribARB(programObj, attrib, sizeof name, NULL, &size, &type, name);'
José Fonseca2a794f52011-05-26 20:54:29 +0100501 print " if (name[0] != 'g' || name[1] != 'l' || name[2] != '_') {"
502 print ' GLint location = __glGetAttribLocationARB(programObj, name);'
503 print ' if (location >= 0) {'
José Fonseca91492d22011-05-23 21:20:31 +0100504 bind_function = glapi.glapi.get_function_by_name('glBindAttribLocationARB')
505 self.fake_call(bind_function, ['programObj', 'location', 'name'])
José Fonseca2a794f52011-05-26 20:54:29 +0100506 print ' }'
José Fonseca91492d22011-05-23 21:20:31 +0100507 print ' }'
508 print ' }'
509
José Fonseca14c21bc2011-02-20 23:32:22 +0000510 Tracer.trace_function_impl_body(self, function)
José Fonseca73373602011-05-20 17:45:26 +0100511
José Fonseca8f34d342011-07-15 20:16:40 +0100512 gremedy_functions = [
513 'glStringMarkerGREMEDY',
514 'glFrameTerminatorGREMEDY',
515 ]
516
José Fonseca91492d22011-05-23 21:20:31 +0100517 def dispatch_function(self, function):
518 if function.name in ('glLinkProgram', 'glLinkProgramARB'):
519 # These functions have been dispatched already
520 return
521
José Fonseca1b3d3752011-07-15 10:15:19 +0100522 # We implement the GREMEDY extensions, not the driver
José Fonseca8f34d342011-07-15 20:16:40 +0100523 if function.name in self.gremedy_functions:
524 return
525
526 if function.name in ('glXGetProcAddress', 'glXGetProcAddressARB', 'wglGetProcAddress'):
527 if_ = 'if'
528 for gremedy_function in self.gremedy_functions:
529 print ' %s (strcmp("%s", (const char *)%s) == 0) {' % (if_, gremedy_function, function.args[0].name)
530 print ' __result = (%s)&%s;' % (function.type, gremedy_function)
531 print ' }'
532 if_ = 'else if'
533 print ' else {'
534 Tracer.dispatch_function(self, function)
535 print ' }'
José Fonseca1b3d3752011-07-15 10:15:19 +0100536 return
537
José Fonsecaa08d2752011-08-25 13:26:43 +0100538 # Override GL extensions
539 if function.name in ('glGetString', 'glGetIntegerv', 'glGetStringi'):
540 Tracer.dispatch_function(self, function, prefix = 'gltrace::__', suffix = '_override')
541 return
542
José Fonseca91492d22011-05-23 21:20:31 +0100543 Tracer.dispatch_function(self, function)
544
José Fonseca73373602011-05-20 17:45:26 +0100545 def emit_memcpy(self, dest, src, length):
José Fonsecab4a3d142011-10-27 07:43:19 +0100546 print ' unsigned __call = trace::localWriter.beginEnter(&trace::memcpy_sig);'
547 print ' trace::localWriter.beginArg(0);'
548 print ' trace::localWriter.writeOpaque(%s);' % dest
549 print ' trace::localWriter.endArg();'
550 print ' trace::localWriter.beginArg(1);'
551 print ' trace::localWriter.writeBlob(%s, %s);' % (src, length)
552 print ' trace::localWriter.endArg();'
553 print ' trace::localWriter.beginArg(2);'
554 print ' trace::localWriter.writeUInt(%s);' % length
555 print ' trace::localWriter.endArg();'
556 print ' trace::localWriter.endEnter();'
557 print ' trace::localWriter.beginLeave(__call);'
558 print ' trace::localWriter.endLeave();'
José Fonseca867b1b72011-04-24 11:58:04 +0100559
560 buffer_targets = [
561 'ARRAY_BUFFER',
562 'ELEMENT_ARRAY_BUFFER',
563 'PIXEL_PACK_BUFFER',
564 'PIXEL_UNPACK_BUFFER',
565 ]
566
567 def wrap_ret(self, function, instance):
568 Tracer.wrap_ret(self, function, instance)
José Fonseca1b3d3752011-07-15 10:15:19 +0100569
José Fonseca867b1b72011-04-24 11:58:04 +0100570
571 if function.name in ('glMapBuffer', 'glMapBufferARB'):
572 print ' struct buffer_mapping *mapping = get_buffer_mapping(target);'
573 print ' if (mapping) {'
574 print ' mapping->map = %s;' % (instance)
575 print ' mapping->length = 0;'
576 print ' __glGetBufferParameteriv(target, GL_BUFFER_SIZE, &mapping->length);'
577 print ' mapping->write = (access != GL_READ_ONLY);'
José Fonseca73373602011-05-20 17:45:26 +0100578 print ' mapping->explicit_flush = false;'
José Fonseca867b1b72011-04-24 11:58:04 +0100579 print ' }'
580
581 if function.name == 'glMapBufferRange':
582 print ' struct buffer_mapping *mapping = get_buffer_mapping(target);'
583 print ' if (mapping) {'
584 print ' mapping->map = %s;' % (instance)
585 print ' mapping->length = length;'
586 print ' mapping->write = access & GL_MAP_WRITE_BIT;'
José Fonseca73373602011-05-20 17:45:26 +0100587 print ' mapping->explicit_flush = access & GL_MAP_FLUSH_EXPLICIT_BIT;'
José Fonseca867b1b72011-04-24 11:58:04 +0100588 print ' }'
José Fonseca669b1222011-02-20 09:05:10 +0000589
José Fonsecac9f12232011-03-25 20:07:42 +0000590 boolean_names = [
591 'GL_FALSE',
592 'GL_TRUE',
593 ]
594
595 def gl_boolean(self, value):
596 return self.boolean_names[int(bool(value))]
597
José Fonsecac29f4f12011-06-11 12:19:05 +0100598 # Names of the functions that unpack from a pixel buffer object. See the
599 # ARB_pixel_buffer_object specification.
José Fonsecae97bab92011-06-02 23:15:11 +0100600 unpack_function_names = set([
601 'glBitmap',
José Fonsecac29f4f12011-06-11 12:19:05 +0100602 'glColorSubTable',
603 'glColorTable',
604 'glCompressedTexImage1D',
605 'glCompressedTexImage2D',
606 'glCompressedTexImage3D',
607 'glCompressedTexSubImage1D',
608 'glCompressedTexSubImage2D',
609 'glCompressedTexSubImage3D',
610 'glConvolutionFilter1D',
611 'glConvolutionFilter2D',
José Fonsecae97bab92011-06-02 23:15:11 +0100612 'glDrawPixels',
613 'glMultiTexImage1DEXT',
614 'glMultiTexImage2DEXT',
615 'glMultiTexImage3DEXT',
616 'glMultiTexSubImage1DEXT',
617 'glMultiTexSubImage2DEXT',
618 'glMultiTexSubImage3DEXT',
José Fonsecac29f4f12011-06-11 12:19:05 +0100619 'glPixelMapfv',
620 'glPixelMapuiv',
621 'glPixelMapusv',
José Fonsecae97bab92011-06-02 23:15:11 +0100622 'glPolygonStipple',
José Fonsecac29f4f12011-06-11 12:19:05 +0100623 'glSeparableFilter2D',
José Fonsecae97bab92011-06-02 23:15:11 +0100624 'glTexImage1D',
625 'glTexImage1DEXT',
626 'glTexImage2D',
627 'glTexImage2DEXT',
628 'glTexImage3D',
629 'glTexImage3DEXT',
630 'glTexSubImage1D',
631 'glTexSubImage1DEXT',
632 'glTexSubImage2D',
633 'glTexSubImage2DEXT',
634 'glTexSubImage3D',
635 'glTexSubImage3DEXT',
636 'glTextureImage1DEXT',
637 'glTextureImage2DEXT',
638 'glTextureImage3DEXT',
639 'glTextureSubImage1DEXT',
640 'glTextureSubImage2DEXT',
641 'glTextureSubImage3DEXT',
642 ])
643
José Fonseca99221832011-03-22 22:15:46 +0000644 def dump_arg_instance(self, function, arg):
645 if function.name in self.draw_function_names and arg.name == 'indices':
José Fonseca8a6c6cb2011-03-23 16:44:30 +0000646 print ' GLint __element_array_buffer = 0;'
647 print ' __glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &__element_array_buffer);'
648 print ' if (!__element_array_buffer) {'
José Fonseca5c749e32011-05-09 11:11:37 +0100649 if isinstance(arg.type, stdapi.Array):
José Fonsecab4a3d142011-10-27 07:43:19 +0100650 print ' trace::localWriter.beginArray(%s);' % arg.type.length
José Fonseca5c749e32011-05-09 11:11:37 +0100651 print ' for(GLsizei i = 0; i < %s; ++i) {' % arg.type.length
José Fonsecab4a3d142011-10-27 07:43:19 +0100652 print ' trace::localWriter.beginElement();'
653 print ' trace::localWriter.writeBlob(%s[i], count[i]*__gl_type_size(type));' % (arg.name)
654 print ' trace::localWriter.endElement();'
José Fonseca5c749e32011-05-09 11:11:37 +0100655 print ' }'
José Fonsecab4a3d142011-10-27 07:43:19 +0100656 print ' trace::localWriter.endArray();'
José Fonseca5c749e32011-05-09 11:11:37 +0100657 else:
José Fonsecab4a3d142011-10-27 07:43:19 +0100658 print ' trace::localWriter.writeBlob(%s, count*__gl_type_size(type));' % (arg.name)
José Fonseca8a6c6cb2011-03-23 16:44:30 +0000659 print ' } else {'
José Fonseca5c749e32011-05-09 11:11:37 +0100660 Tracer.dump_arg_instance(self, function, arg)
José Fonseca8a6c6cb2011-03-23 16:44:30 +0000661 print ' }'
662 return
663
José Fonsecae97bab92011-06-02 23:15:11 +0100664 # Recognize offsets instead of blobs when a PBO is bound
665 if function.name in self.unpack_function_names \
666 and (isinstance(arg.type, stdapi.Blob) \
667 or (isinstance(arg.type, stdapi.Const) \
668 and isinstance(arg.type.type, stdapi.Blob))):
José Fonsecac29f4f12011-06-11 12:19:05 +0100669 print ' {'
670 print ' GLint __unpack_buffer = 0;'
671 print ' __glGetIntegerv(GL_PIXEL_UNPACK_BUFFER_BINDING, &__unpack_buffer);'
672 print ' if (__unpack_buffer) {'
José Fonsecab4a3d142011-10-27 07:43:19 +0100673 print ' trace::localWriter.writeOpaque(%s);' % arg.name
José Fonsecac29f4f12011-06-11 12:19:05 +0100674 print ' } else {'
José Fonsecae97bab92011-06-02 23:15:11 +0100675 Tracer.dump_arg_instance(self, function, arg)
José Fonsecac29f4f12011-06-11 12:19:05 +0100676 print ' }'
José Fonsecae97bab92011-06-02 23:15:11 +0100677 print ' }'
678 return
679
José Fonsecaa3f89ae2011-04-26 08:50:32 +0100680 # Several GL state functions take GLenum symbolic names as
681 # integer/floats; so dump the symbolic name whenever possible
José Fonseca3bcb33c2011-05-27 20:14:31 +0100682 if function.name.startswith('gl') \
José Fonsecae3571092011-10-13 08:26:27 +0100683 and arg.type in (glapi.GLint, glapi.GLfloat, glapi.GLdouble) \
José Fonseca3bcb33c2011-05-27 20:14:31 +0100684 and arg.name == 'param':
José Fonsecaa3f89ae2011-04-26 08:50:32 +0100685 assert arg.index > 0
686 assert function.args[arg.index - 1].name == 'pname'
687 assert function.args[arg.index - 1].type == glapi.GLenum
688 print ' if (is_symbolic_pname(pname) && is_symbolic_param(%s)) {' % arg.name
689 dump_instance(glapi.GLenum, arg.name)
690 print ' } else {'
691 Tracer.dump_arg_instance(self, function, arg)
692 print ' }'
693 return
694
José Fonseca8a6c6cb2011-03-23 16:44:30 +0000695 Tracer.dump_arg_instance(self, function, arg)
José Fonseca99221832011-03-22 22:15:46 +0000696
José Fonseca4c938c22011-04-30 22:44:38 +0100697 def footer(self, api):
698 Tracer.footer(self, api)
José Fonseca669b1222011-02-20 09:05:10 +0000699
José Fonseca4c938c22011-04-30 22:44:38 +0100700 # A simple state tracker to track the pointer values
José Fonseca669b1222011-02-20 09:05:10 +0000701 # update the state
José Fonseca8a6c6cb2011-03-23 16:44:30 +0000702 print 'static void __trace_user_arrays(GLuint maxindex)'
José Fonseca669b1222011-02-20 09:05:10 +0000703 print '{'
José Fonseca1a2fdd22011-04-01 00:55:09 +0100704
José Fonseca99221832011-03-22 22:15:46 +0000705 for camelcase_name, uppercase_name in self.arrays:
706 function_name = 'gl%sPointer' % camelcase_name
707 enable_name = 'GL_%s_ARRAY' % uppercase_name
708 binding_name = 'GL_%s_ARRAY_BUFFER_BINDING' % uppercase_name
José Fonseca14c21bc2011-02-20 23:32:22 +0000709 function = api.get_function_by_name(function_name)
José Fonseca99221832011-03-22 22:15:46 +0000710
José Fonseca06e85192011-10-16 14:15:36 +0100711 print ' // %s' % function.prototype()
José Fonsecafb6744f2011-04-15 11:18:37 +0100712 self.array_trace_prolog(api, uppercase_name)
713 self.array_prolog(api, uppercase_name)
714 print ' if (__glIsEnabled(%s)) {' % enable_name
José Fonseca7f5163e2011-03-31 23:37:26 +0100715 print ' GLint __binding = 0;'
716 print ' __glGetIntegerv(%s, &__binding);' % binding_name
717 print ' if (!__binding) {'
José Fonseca99221832011-03-22 22:15:46 +0000718
719 # Get the arguments via glGet*
720 for arg in function.args:
721 arg_get_enum = 'GL_%s_ARRAY_%s' % (uppercase_name, arg.name.upper())
722 arg_get_function, arg_type = TypeGetter().visit(arg.type)
José Fonseca7f5163e2011-03-31 23:37:26 +0100723 print ' %s %s = 0;' % (arg_type, arg.name)
724 print ' __%s(%s, &%s);' % (arg_get_function, arg_get_enum, arg.name)
José Fonseca99221832011-03-22 22:15:46 +0000725
726 arg_names = ', '.join([arg.name for arg in function.args[:-1]])
José Fonseca7f5163e2011-03-31 23:37:26 +0100727 print ' size_t __size = __%s_size(%s, maxindex);' % (function.name, arg_names)
José Fonseca99221832011-03-22 22:15:46 +0000728
729 # Emit a fake function
José Fonsecafb6744f2011-04-15 11:18:37 +0100730 self.array_trace_intermezzo(api, uppercase_name)
José Fonsecab4a3d142011-10-27 07:43:19 +0100731 print ' unsigned __call = trace::localWriter.beginEnter(&__%s_sig);' % (function.name,)
José Fonseca669b1222011-02-20 09:05:10 +0000732 for arg in function.args:
733 assert not arg.output
José Fonsecab4a3d142011-10-27 07:43:19 +0100734 print ' trace::localWriter.beginArg(%u);' % (arg.index,)
José Fonseca14c21bc2011-02-20 23:32:22 +0000735 if arg.name != 'pointer':
José Fonseca99221832011-03-22 22:15:46 +0000736 dump_instance(arg.type, arg.name)
José Fonseca14c21bc2011-02-20 23:32:22 +0000737 else:
José Fonsecab4a3d142011-10-27 07:43:19 +0100738 print ' trace::localWriter.writeBlob((const void *)%s, __size);' % (arg.name)
739 print ' trace::localWriter.endArg();'
José Fonseca99221832011-03-22 22:15:46 +0000740
José Fonsecab4a3d142011-10-27 07:43:19 +0100741 print ' trace::localWriter.endEnter();'
742 print ' trace::localWriter.beginLeave(__call);'
743 print ' trace::localWriter.endLeave();'
José Fonseca99221832011-03-22 22:15:46 +0000744 print ' }'
José Fonseca669b1222011-02-20 09:05:10 +0000745 print ' }'
José Fonsecafb6744f2011-04-15 11:18:37 +0100746 self.array_epilog(api, uppercase_name)
747 self.array_trace_epilog(api, uppercase_name)
José Fonseca99221832011-03-22 22:15:46 +0000748 print
José Fonseca1a2fdd22011-04-01 00:55:09 +0100749
José Fonseca1601c412011-05-10 10:38:19 +0100750 # Samething, but for glVertexAttribPointer*
751 #
752 # Some variants of glVertexAttribPointer alias conventional and generic attributes:
753 # - glVertexAttribPointer: no
754 # - glVertexAttribPointerARB: implementation dependent
755 # - glVertexAttribPointerNV: yes
756 #
757 # This means that the implementations of these functions do not always
758 # alias, and they need to be considered independently.
759 #
José Fonseca5a568a92011-06-29 16:43:36 +0100760 print ' vertex_attrib __vertex_attrib = __get_vertex_attrib();'
761 print
762 for suffix in ['', 'ARB', 'NV']:
763 if suffix:
José Fonsecad94aaac2011-06-28 20:50:49 +0100764 SUFFIX = '_' + suffix
José Fonsecad94aaac2011-06-28 20:50:49 +0100765 else:
José Fonseca5a568a92011-06-29 16:43:36 +0100766 SUFFIX = suffix
José Fonseca1601c412011-05-10 10:38:19 +0100767 function_name = 'glVertexAttribPointer' + suffix
José Fonseca06e85192011-10-16 14:15:36 +0100768 function = api.get_function_by_name(function_name)
769
770 print ' // %s' % function.prototype()
José Fonseca5a568a92011-06-29 16:43:36 +0100771 print ' if (__vertex_attrib == VERTEX_ATTRIB%s) {' % SUFFIX
772 if suffix == 'NV':
773 print ' GLint __max_vertex_attribs = 16;'
774 else:
775 print ' GLint __max_vertex_attribs = 0;'
776 print ' __glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &__max_vertex_attribs);'
777 print ' for (GLint index = 0; index < __max_vertex_attribs; ++index) {'
778 print ' GLint __enabled = 0;'
779 if suffix == 'NV':
780 print ' __glGetIntegerv(GL_VERTEX_ATTRIB_ARRAY0_NV + index, &__enabled);'
781 else:
782 print ' __glGetVertexAttribiv%s(index, GL_VERTEX_ATTRIB_ARRAY_ENABLED%s, &__enabled);' % (suffix, SUFFIX)
783 print ' if (__enabled) {'
784 print ' GLint __binding = 0;'
785 if suffix != 'NV':
786 # It doesn't seem possible to use VBOs with NV_vertex_program.
787 print ' __glGetVertexAttribiv%s(index, GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING%s, &__binding);' % (suffix, SUFFIX)
788 print ' if (!__binding) {'
José Fonseca1a2fdd22011-04-01 00:55:09 +0100789
José Fonseca1601c412011-05-10 10:38:19 +0100790 # Get the arguments via glGet*
791 for arg in function.args[1:]:
José Fonseca5a568a92011-06-29 16:43:36 +0100792 if suffix == 'NV':
793 arg_get_enum = 'GL_ATTRIB_ARRAY_%s%s' % (arg.name.upper(), SUFFIX)
794 else:
795 arg_get_enum = 'GL_VERTEX_ATTRIB_ARRAY_%s%s' % (arg.name.upper(), SUFFIX)
José Fonsecac493e3e2011-06-29 12:57:06 +0100796 arg_get_function, arg_type = TypeGetter('glGetVertexAttrib', False, suffix).visit(arg.type)
José Fonseca5a568a92011-06-29 16:43:36 +0100797 print ' %s %s = 0;' % (arg_type, arg.name)
798 print ' __%s(index, %s, &%s);' % (arg_get_function, arg_get_enum, arg.name)
José Fonseca1601c412011-05-10 10:38:19 +0100799
800 arg_names = ', '.join([arg.name for arg in function.args[1:-1]])
José Fonseca5a568a92011-06-29 16:43:36 +0100801 print ' size_t __size = __%s_size(%s, maxindex);' % (function.name, arg_names)
José Fonseca1a2fdd22011-04-01 00:55:09 +0100802
José Fonseca1601c412011-05-10 10:38:19 +0100803 # Emit a fake function
José Fonsecab4a3d142011-10-27 07:43:19 +0100804 print ' unsigned __call = trace::localWriter.beginEnter(&__%s_sig);' % (function.name,)
José Fonseca1601c412011-05-10 10:38:19 +0100805 for arg in function.args:
806 assert not arg.output
José Fonsecab4a3d142011-10-27 07:43:19 +0100807 print ' trace::localWriter.beginArg(%u);' % (arg.index,)
José Fonseca1601c412011-05-10 10:38:19 +0100808 if arg.name != 'pointer':
809 dump_instance(arg.type, arg.name)
810 else:
José Fonsecab4a3d142011-10-27 07:43:19 +0100811 print ' trace::localWriter.writeBlob((const void *)%s, __size);' % (arg.name)
812 print ' trace::localWriter.endArg();'
José Fonseca1601c412011-05-10 10:38:19 +0100813
José Fonsecab4a3d142011-10-27 07:43:19 +0100814 print ' trace::localWriter.endEnter();'
815 print ' trace::localWriter.beginLeave(__call);'
816 print ' trace::localWriter.endLeave();'
José Fonseca1601c412011-05-10 10:38:19 +0100817 print ' }'
818 print ' }'
819 print ' }'
820 print ' }'
821 print
José Fonseca1a2fdd22011-04-01 00:55:09 +0100822
José Fonseca669b1222011-02-20 09:05:10 +0000823 print '}'
824 print
825
José Fonsecafb6744f2011-04-15 11:18:37 +0100826 #
827 # Hooks for glTexCoordPointer, which is identical to the other array
828 # pointers except the fact that it is indexed by glClientActiveTexture.
829 #
830
831 def array_prolog(self, api, uppercase_name):
832 if uppercase_name == 'TEXTURE_COORD':
833 print ' GLint client_active_texture = 0;'
834 print ' __glGetIntegerv(GL_CLIENT_ACTIVE_TEXTURE, &client_active_texture);'
835 print ' GLint max_texture_coords = 0;'
836 print ' __glGetIntegerv(GL_MAX_TEXTURE_COORDS, &max_texture_coords);'
837 print ' for (GLint unit = 0; unit < max_texture_coords; ++unit) {'
José Fonseca7525e6f2011-09-28 09:04:56 +0100838 print ' GLint texture = GL_TEXTURE0 + unit;'
José Fonsecafb6744f2011-04-15 11:18:37 +0100839 print ' __glClientActiveTexture(texture);'
840
841 def array_trace_prolog(self, api, uppercase_name):
842 if uppercase_name == 'TEXTURE_COORD':
843 print ' bool client_active_texture_dirty = false;'
844
845 def array_epilog(self, api, uppercase_name):
846 if uppercase_name == 'TEXTURE_COORD':
847 print ' }'
848 self.array_cleanup(api, uppercase_name)
849
850 def array_cleanup(self, api, uppercase_name):
851 if uppercase_name == 'TEXTURE_COORD':
852 print ' __glClientActiveTexture(client_active_texture);'
853
854 def array_trace_intermezzo(self, api, uppercase_name):
855 if uppercase_name == 'TEXTURE_COORD':
856 print ' if (texture != client_active_texture || client_active_texture_dirty) {'
857 print ' client_active_texture_dirty = true;'
858 self.fake_glClientActiveTexture_call(api, "texture");
859 print ' }'
860
861 def array_trace_epilog(self, api, uppercase_name):
862 if uppercase_name == 'TEXTURE_COORD':
863 print ' if (client_active_texture_dirty) {'
864 self.fake_glClientActiveTexture_call(api, "client_active_texture");
865 print ' }'
866
867 def fake_glClientActiveTexture_call(self, api, texture):
868 function = api.get_function_by_name('glClientActiveTexture')
869 self.fake_call(function, [texture])
870
871 def fake_call(self, function, args):
José Fonsecab4a3d142011-10-27 07:43:19 +0100872 print ' unsigned __fake_call = trace::localWriter.beginEnter(&__%s_sig);' % (function.name,)
José Fonsecafb6744f2011-04-15 11:18:37 +0100873 for arg, instance in zip(function.args, args):
874 assert not arg.output
José Fonsecab4a3d142011-10-27 07:43:19 +0100875 print ' trace::localWriter.beginArg(%u);' % (arg.index,)
José Fonsecafb6744f2011-04-15 11:18:37 +0100876 dump_instance(arg.type, instance)
José Fonsecab4a3d142011-10-27 07:43:19 +0100877 print ' trace::localWriter.endArg();'
878 print ' trace::localWriter.endEnter();'
879 print ' trace::localWriter.beginLeave(__fake_call);'
880 print ' trace::localWriter.endLeave();'
José Fonsecafb6744f2011-04-15 11:18:37 +0100881
882
883
884
885
José Fonseca669b1222011-02-20 09:05:10 +0000886
887
888
889
890
891