blob: 8c29a7bb0d833ec2591d1b0ae7e3ee86b183730b [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é Fonseca99221832011-03-22 22:15:46 +000030import stdapi
31import glapi
José Fonseca5ea91872011-05-04 09:41:55 +010032import glparams
José Fonseca669b1222011-02-20 09:05:10 +000033from glxapi import glxapi
34from 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é Fonseca25ebe542011-04-24 10:08:22 +0100110 print '// Whether user arrays were used'
111 print 'static bool __user_arrays = false;'
José Fonseca5a568a92011-06-29 16:43:36 +0100112 print 'static bool __user_arrays_arb = false;'
113 print 'static bool __user_arrays_nv = false;'
José Fonseca25ebe542011-04-24 10:08:22 +0100114 print
José Fonseca5a568a92011-06-29 16:43:36 +0100115
116 # Which glVertexAttrib* variant to use
117 print 'enum vertex_attrib {'
118 print ' VERTEX_ATTRIB,'
119 print ' VERTEX_ATTRIB_ARB,'
120 print ' VERTEX_ATTRIB_NV,'
121 print '};'
122 print
123 print 'static vertex_attrib __get_vertex_attrib(void) {'
José Fonsecad5b95b32011-06-29 17:41:02 +0100124 print ' if (__user_arrays_arb || __user_arrays_nv) {'
José Fonseca5a568a92011-06-29 16:43:36 +0100125 print ' GLboolean __vertex_program = GL_FALSE;'
126 print ' __glGetBooleanv(GL_VERTEX_PROGRAM_ARB, &__vertex_program);'
127 print ' if (__vertex_program) {'
128 print ' if (__user_arrays_nv) {'
129 print ' GLint __vertex_program_binding_nv = 0;'
130 print ' __glGetIntegerv(GL_VERTEX_PROGRAM_BINDING_NV, &__vertex_program_binding_nv);'
131 print ' if (__vertex_program_binding_nv) {'
132 print ' return VERTEX_ATTRIB_NV;'
133 print ' }'
134 print ' }'
135 print ' return VERTEX_ATTRIB_ARB;'
136 print ' }'
137 print ' }'
138 print ' return VERTEX_ATTRIB;'
139 print '}'
140 print
141
José Fonseca8a6c6cb2011-03-23 16:44:30 +0000142 # Whether we need user arrays
143 print 'static inline bool __need_user_arrays(void)'
144 print '{'
José Fonseca25ebe542011-04-24 10:08:22 +0100145 print ' if (!__user_arrays) {'
146 print ' return false;'
147 print ' }'
148 print
José Fonseca1a2fdd22011-04-01 00:55:09 +0100149
José Fonseca8a6c6cb2011-03-23 16:44:30 +0000150 for camelcase_name, uppercase_name in self.arrays:
151 function_name = 'gl%sPointer' % camelcase_name
152 enable_name = 'GL_%s_ARRAY' % uppercase_name
153 binding_name = 'GL_%s_ARRAY_BUFFER_BINDING' % uppercase_name
154 print ' // %s' % function_name
José Fonsecafb6744f2011-04-15 11:18:37 +0100155 self.array_prolog(api, uppercase_name)
José Fonseca7f5163e2011-03-31 23:37:26 +0100156 print ' if (__glIsEnabled(%s)) {' % enable_name
157 print ' GLint __binding = 0;'
158 print ' __glGetIntegerv(%s, &__binding);' % binding_name
159 print ' if (!__binding) {'
José Fonsecafb6744f2011-04-15 11:18:37 +0100160 self.array_cleanup(api, uppercase_name)
José Fonseca7f5163e2011-03-31 23:37:26 +0100161 print ' return true;'
José Fonseca8a6c6cb2011-03-23 16:44:30 +0000162 print ' }'
163 print ' }'
José Fonsecafb6744f2011-04-15 11:18:37 +0100164 self.array_epilog(api, uppercase_name)
José Fonseca8a6c6cb2011-03-23 16:44:30 +0000165 print
José Fonseca7f5163e2011-03-31 23:37:26 +0100166
José Fonseca5a568a92011-06-29 16:43:36 +0100167 print ' vertex_attrib __vertex_attrib = __get_vertex_attrib();'
168 print
169 print ' // glVertexAttribPointer'
170 print ' if (__vertex_attrib == VERTEX_ATTRIB) {'
171 print ' GLint __max_vertex_attribs = 0;'
172 print ' __glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &__max_vertex_attribs);'
173 print ' for (GLint index = 0; index < __max_vertex_attribs; ++index) {'
174 print ' GLint __enabled = 0;'
175 print ' __glGetVertexAttribiv(index, GL_VERTEX_ATTRIB_ARRAY_ENABLED, &__enabled);'
176 print ' if (__enabled) {'
177 print ' GLint __binding = 0;'
178 print ' __glGetVertexAttribiv(index, GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING, &__binding);'
179 print ' if (!__binding) {'
180 print ' return true;'
181 print ' }'
182 print ' }'
183 print ' }'
184 print ' }'
185 print
186 print ' // glVertexAttribPointerARB'
187 print ' if (__vertex_attrib == VERTEX_ATTRIB_ARB) {'
José Fonsecad94aaac2011-06-28 20:50:49 +0100188 print ' GLint __max_vertex_attribs = 0;'
189 print ' __glGetIntegerv(GL_MAX_VERTEX_ATTRIBS_ARB, &__max_vertex_attribs);'
190 print ' for (GLint index = 0; index < __max_vertex_attribs; ++index) {'
191 print ' GLint __enabled = 0;'
192 print ' __glGetVertexAttribivARB(index, GL_VERTEX_ATTRIB_ARRAY_ENABLED_ARB, &__enabled);'
193 print ' if (__enabled) {'
194 print ' GLint __binding = 0;'
195 print ' __glGetVertexAttribivARB(index, GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING_ARB, &__binding);'
196 print ' if (!__binding) {'
197 print ' return true;'
198 print ' }'
199 print ' }'
200 print ' }'
José Fonseca5a568a92011-06-29 16:43:36 +0100201 print ' }'
202 print
203 print ' // glVertexAttribPointerNV'
204 print ' if (__vertex_attrib == VERTEX_ATTRIB_NV) {'
205 print ' for (GLint index = 0; index < 16; ++index) {'
José Fonsecad94aaac2011-06-28 20:50:49 +0100206 print ' GLint __enabled = 0;'
José Fonseca5a568a92011-06-29 16:43:36 +0100207 print ' __glGetIntegerv(GL_VERTEX_ATTRIB_ARRAY0_NV + index, &__enabled);'
José Fonsecad94aaac2011-06-28 20:50:49 +0100208 print ' if (__enabled) {'
José Fonseca5a568a92011-06-29 16:43:36 +0100209 print ' return true;'
José Fonseca1a2fdd22011-04-01 00:55:09 +0100210 print ' }'
211 print ' }'
212 print ' }'
213 print
214
José Fonseca8a6c6cb2011-03-23 16:44:30 +0000215 print ' return false;'
216 print '}'
217 print
José Fonseca669b1222011-02-20 09:05:10 +0000218
José Fonseca8a6c6cb2011-03-23 16:44:30 +0000219 print 'static void __trace_user_arrays(GLuint maxindex);'
José Fonseca14c21bc2011-02-20 23:32:22 +0000220 print
José Fonseca867b1b72011-04-24 11:58:04 +0100221
222 print 'struct buffer_mapping {'
223 print ' void *map;'
224 print ' GLint length;'
225 print ' bool write;'
José Fonseca73373602011-05-20 17:45:26 +0100226 print ' bool explicit_flush;'
José Fonseca867b1b72011-04-24 11:58:04 +0100227 print '};'
228 print
229 for target in self.buffer_targets:
230 print 'struct buffer_mapping __%s_mapping;' % target.lower();
231 print
232 print 'static inline struct buffer_mapping *'
233 print 'get_buffer_mapping(GLenum target) {'
234 print ' switch(target) {'
235 for target in self.buffer_targets:
236 print ' case GL_%s:' % target
237 print ' return & __%s_mapping;' % target.lower()
238 print ' default:'
José Fonsecacbd225f2011-06-09 00:07:18 +0100239 print ' OS::DebugMessage("apitrace: warning: unknown buffer target 0x%04X\\n", target);'
José Fonseca867b1b72011-04-24 11:58:04 +0100240 print ' return NULL;'
241 print ' }'
242 print '}'
243 print
244
245 # Generate memcpy's signature
246 self.trace_function_decl(glapi.memcpy)
José Fonsecaa3f89ae2011-04-26 08:50:32 +0100247
248 # Generate a helper function to determine whether a parameter name
249 # refers to a symbolic value or not
250 print 'static bool'
251 print 'is_symbolic_pname(GLenum pname) {'
252 print ' switch(pname) {'
José Fonseca5ea91872011-05-04 09:41:55 +0100253 for function, type, count, name in glparams.parameters:
José Fonsecaa3f89ae2011-04-26 08:50:32 +0100254 if type is glapi.GLenum:
José Fonseca4c938c22011-04-30 22:44:38 +0100255 print ' case %s:' % name
256 print ' return true;'
257 print ' default:'
258 print ' return false;'
José Fonsecaa3f89ae2011-04-26 08:50:32 +0100259 print ' }'
260 print '}'
261 print
262
263 # Generate a helper function to determine whether a parameter value is
264 # potentially symbolic or not; i.e., if the value can be represented in
265 # an enum or not
266 print 'template<class T>'
267 print 'static inline bool'
268 print 'is_symbolic_param(T param) {'
269 print ' return static_cast<T>(static_cast<GLenum>(param)) == param;'
270 print '}'
271 print
José Fonseca4c938c22011-04-30 22:44:38 +0100272
273 # Generate a helper function to know how many elements a parameter has
274 print 'static size_t'
José Fonsecaf4aca5d2011-05-08 08:29:30 +0100275 print '__gl_param_size(GLenum pname) {'
José Fonseca4c938c22011-04-30 22:44:38 +0100276 print ' switch(pname) {'
José Fonseca5ea91872011-05-04 09:41:55 +0100277 for function, type, count, name in glparams.parameters:
José Fonseca4c938c22011-04-30 22:44:38 +0100278 if type is not None:
279 print ' case %s: return %u;' % (name, count)
280 print ' case GL_COMPRESSED_TEXTURE_FORMATS: {'
281 print ' GLint num_compressed_texture_formats = 0;'
282 print ' __glGetIntegerv(GL_NUM_COMPRESSED_TEXTURE_FORMATS, &num_compressed_texture_formats);'
283 print ' return num_compressed_texture_formats;'
284 print ' }'
285 print ' default:'
José Fonsecacbd225f2011-06-09 00:07:18 +0100286 print r' OS::DebugMessage("apitrace: warning: %s: unknown GLenum 0x%04X\n", __FUNCTION__, pname);'
José Fonseca4c938c22011-04-30 22:44:38 +0100287 print ' return 1;'
288 print ' }'
289 print '}'
290 print
291
José Fonseca99221832011-03-22 22:15:46 +0000292 array_pointer_function_names = set((
293 "glVertexPointer",
294 "glNormalPointer",
295 "glColorPointer",
296 "glIndexPointer",
297 "glTexCoordPointer",
298 "glEdgeFlagPointer",
299 "glFogCoordPointer",
300 "glSecondaryColorPointer",
José Fonseca7f5163e2011-03-31 23:37:26 +0100301
José Fonsecaac5285b2011-05-04 11:09:08 +0100302 "glInterleavedArrays",
303
José Fonseca7e0bfd92011-04-30 23:09:03 +0100304 "glVertexPointerEXT",
305 "glNormalPointerEXT",
306 "glColorPointerEXT",
307 "glIndexPointerEXT",
308 "glTexCoordPointerEXT",
309 "glEdgeFlagPointerEXT",
310 "glFogCoordPointerEXT",
311 "glSecondaryColorPointerEXT",
José Fonseca99221832011-03-22 22:15:46 +0000312
José Fonseca7f5163e2011-03-31 23:37:26 +0100313 "glVertexAttribPointer",
314 "glVertexAttribPointerARB",
315 "glVertexAttribPointerNV",
José Fonsecaac5285b2011-05-04 11:09:08 +0100316 "glVertexAttribIPointer",
317 "glVertexAttribIPointerEXT",
José Fonseca7f5163e2011-03-31 23:37:26 +0100318 "glVertexAttribLPointer",
319 "glVertexAttribLPointerEXT",
José Fonseca99221832011-03-22 22:15:46 +0000320
321 #"glMatrixIndexPointerARB",
322 ))
323
324 draw_function_names = set((
325 'glDrawArrays',
326 'glDrawElements',
327 'glDrawRangeElements',
José Fonseca5c749e32011-05-09 11:11:37 +0100328 'glMultiDrawArrays',
329 'glMultiDrawElements',
330 'glDrawArraysInstanced',
331 'glDrawElementsInstanced',
332 'glDrawArraysInstancedARB',
333 'glDrawElementsInstancedARB',
334 'glDrawElementsBaseVertex',
335 'glDrawRangeElementsBaseVertex',
336 'glDrawElementsInstancedBaseVertex',
337 'glMultiDrawElementsBaseVertex',
338 'glDrawArraysIndirect',
339 'glDrawElementsIndirect',
340 'glDrawArraysEXT',
José Fonseca7e0bfd92011-04-30 23:09:03 +0100341 'glDrawRangeElementsEXT',
José Fonseca5c749e32011-05-09 11:11:37 +0100342 'glDrawRangeElementsEXT_size',
343 'glMultiDrawArraysEXT',
344 'glMultiDrawElementsEXT',
345 'glMultiModeDrawArraysIBM',
346 'glMultiModeDrawElementsIBM',
347 'glDrawArraysInstancedEXT',
348 'glDrawElementsInstancedEXT',
José Fonseca99221832011-03-22 22:15:46 +0000349 ))
350
José Fonsecac9f12232011-03-25 20:07:42 +0000351 interleaved_formats = [
352 'GL_V2F',
353 'GL_V3F',
354 'GL_C4UB_V2F',
355 'GL_C4UB_V3F',
356 'GL_C3F_V3F',
357 'GL_N3F_V3F',
358 'GL_C4F_N3F_V3F',
359 'GL_T2F_V3F',
360 'GL_T4F_V4F',
361 'GL_T2F_C4UB_V3F',
362 'GL_T2F_C3F_V3F',
363 'GL_T2F_N3F_V3F',
364 'GL_T2F_C4F_N3F_V3F',
365 'GL_T4F_C4F_N3F_V4F',
366 ]
367
José Fonseca14c21bc2011-02-20 23:32:22 +0000368 def trace_function_impl_body(self, function):
José Fonseca8a6c6cb2011-03-23 16:44:30 +0000369 # Defer tracing of user array pointers...
José Fonseca99221832011-03-22 22:15:46 +0000370 if function.name in self.array_pointer_function_names:
371 print ' GLint __array_buffer = 0;'
372 print ' __glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &__array_buffer);'
373 print ' if (!__array_buffer) {'
José Fonseca25ebe542011-04-24 10:08:22 +0100374 print ' __user_arrays = true;'
José Fonseca5a568a92011-06-29 16:43:36 +0100375 if function.name == "glVertexAttribPointerARB":
376 print ' __user_arrays_arb = true;'
377 if function.name == "glVertexAttribPointerNV":
378 print ' __user_arrays_nv = true;'
José Fonseca14c21bc2011-02-20 23:32:22 +0000379 self.dispatch_function(function)
José Fonsecaac5285b2011-05-04 11:09:08 +0100380
381 # And also break down glInterleavedArrays into the individual calls
382 if function.name == 'glInterleavedArrays':
383 print
384
385 # Initialize the enable flags
386 for camelcase_name, uppercase_name in self.arrays:
387 flag_name = '__' + uppercase_name.lower()
388 print ' GLboolean %s = GL_FALSE;' % flag_name
389 print
390
391 # Switch for the interleaved formats
392 print ' switch (format) {'
393 for format in self.interleaved_formats:
394 print ' case %s:' % format
395 for camelcase_name, uppercase_name in self.arrays:
396 flag_name = '__' + uppercase_name.lower()
397 if format.find('_' + uppercase_name[0]) >= 0:
398 print ' %s = GL_TRUE;' % flag_name
399 print ' break;'
400 print ' default:'
401 print ' return;'
402 print ' }'
403 print
404
405 # Emit fake glEnableClientState/glDisableClientState flags
406 for camelcase_name, uppercase_name in self.arrays:
407 flag_name = '__' + uppercase_name.lower()
408 enable_name = 'GL_%s_ARRAY' % uppercase_name
409
410 # Emit a fake function
411 print ' {'
412 print ' static const Trace::FunctionSig &__sig = %s ? __glEnableClientState_sig : __glDisableClientState_sig;' % flag_name
José Fonseca466753b2011-05-28 13:25:55 +0100413 print ' unsigned __call = __writer.beginEnter(&__sig);'
José Fonsecaeced7472011-05-28 10:37:12 +0100414 print ' __writer.beginArg(0);'
José Fonsecaac5285b2011-05-04 11:09:08 +0100415 dump_instance(glapi.GLenum, enable_name)
José Fonsecaeced7472011-05-28 10:37:12 +0100416 print ' __writer.endArg();'
417 print ' __writer.endEnter();'
418 print ' __writer.beginLeave(__call);'
419 print ' __writer.endLeave();'
José Fonsecaac5285b2011-05-04 11:09:08 +0100420 print ' }'
421
José Fonseca99221832011-03-22 22:15:46 +0000422 print ' return;'
423 print ' }'
José Fonseca14c21bc2011-02-20 23:32:22 +0000424
José Fonseca8a6c6cb2011-03-23 16:44:30 +0000425 # ... to the draw calls
José Fonseca99221832011-03-22 22:15:46 +0000426 if function.name in self.draw_function_names:
José Fonseca8a6c6cb2011-03-23 16:44:30 +0000427 print ' if (__need_user_arrays()) {'
José Fonseca99221832011-03-22 22:15:46 +0000428 arg_names = ', '.join([arg.name for arg in function.args[1:]])
José Fonseca8a6c6cb2011-03-23 16:44:30 +0000429 print ' GLuint maxindex = __%s_maxindex(%s);' % (function.name, arg_names)
430 print ' __trace_user_arrays(maxindex);'
431 print ' }'
José Fonseca14c21bc2011-02-20 23:32:22 +0000432
José Fonseca73373602011-05-20 17:45:26 +0100433 # Emit a fake memcpy on buffer uploads
434 if function.name in ('glUnmapBuffer', 'glUnmapBufferARB', ):
José Fonseca867b1b72011-04-24 11:58:04 +0100435 print ' struct buffer_mapping *mapping = get_buffer_mapping(target);'
José Fonseca73373602011-05-20 17:45:26 +0100436 print ' if (mapping && mapping->write && !mapping->explicit_flush) {'
437 self.emit_memcpy('mapping->map', 'mapping->map', 'mapping->length')
José Fonseca867b1b72011-04-24 11:58:04 +0100438 print ' }'
José Fonseca73373602011-05-20 17:45:26 +0100439 if function.name in ('glFlushMappedBufferRange', 'glFlushMappedBufferRangeAPPLE'):
440 # TODO: avoid copying [0, offset] bytes
441 print ' struct buffer_mapping *mapping = get_buffer_mapping(target);'
442 print ' if (mapping) {'
443 if function.name.endswith('APPLE'):
444 print ' GLsizeiptr length = size;'
445 print ' mapping->explicit_flush = true;'
446 print ' //assert(offset + length <= mapping->length);'
447 self.emit_memcpy('mapping->map', 'mapping->map', 'offset + length')
448 print ' }'
449 # FIXME: glFlushMappedNamedBufferRangeEXT
José Fonseca867b1b72011-04-24 11:58:04 +0100450
José Fonseca91492d22011-05-23 21:20:31 +0100451 # Don't leave vertex attrib locations to chance. Instead emit fake
452 # glBindAttribLocation calls to ensure that the same locations will be
453 # used when retracing. Trying to remap locations after the fact would
454 # be an herculian task given that vertex attrib locations appear in
455 # many entry-points, including non-shader related ones.
456 if function.name == 'glLinkProgram':
457 Tracer.dispatch_function(self, function)
458 print ' GLint active_attributes = 0;'
459 print ' __glGetProgramiv(program, GL_ACTIVE_ATTRIBUTES, &active_attributes);'
460 print ' for (GLuint attrib = 0; attrib < active_attributes; ++attrib) {'
461 print ' GLint size = 0;'
462 print ' GLenum type = 0;'
463 print ' GLchar name[256];'
464 # TODO: Use ACTIVE_ATTRIBUTE_MAX_LENGTH instead of 256
465 print ' __glGetActiveAttrib(program, attrib, sizeof name, NULL, &size, &type, name);'
José Fonseca2a794f52011-05-26 20:54:29 +0100466 print " if (name[0] != 'g' || name[1] != 'l' || name[2] != '_') {"
467 print ' GLint location = __glGetAttribLocation(program, name);'
468 print ' if (location >= 0) {'
José Fonseca91492d22011-05-23 21:20:31 +0100469 bind_function = glapi.glapi.get_function_by_name('glBindAttribLocation')
470 self.fake_call(bind_function, ['program', 'location', 'name'])
José Fonseca2a794f52011-05-26 20:54:29 +0100471 print ' }'
José Fonseca91492d22011-05-23 21:20:31 +0100472 print ' }'
473 print ' }'
474 if function.name == 'glLinkProgramARB':
475 Tracer.dispatch_function(self, function)
476 print ' GLint active_attributes = 0;'
477 print ' __glGetObjectParameterivARB(programObj, GL_OBJECT_ACTIVE_ATTRIBUTES_ARB, &active_attributes);'
478 print ' for (GLuint attrib = 0; attrib < active_attributes; ++attrib) {'
479 print ' GLint size = 0;'
480 print ' GLenum type = 0;'
481 print ' GLcharARB name[256];'
482 # TODO: Use ACTIVE_ATTRIBUTE_MAX_LENGTH instead of 256
483 print ' __glGetActiveAttribARB(programObj, attrib, sizeof name, NULL, &size, &type, name);'
José Fonseca2a794f52011-05-26 20:54:29 +0100484 print " if (name[0] != 'g' || name[1] != 'l' || name[2] != '_') {"
485 print ' GLint location = __glGetAttribLocationARB(programObj, name);'
486 print ' if (location >= 0) {'
José Fonseca91492d22011-05-23 21:20:31 +0100487 bind_function = glapi.glapi.get_function_by_name('glBindAttribLocationARB')
488 self.fake_call(bind_function, ['programObj', 'location', 'name'])
José Fonseca2a794f52011-05-26 20:54:29 +0100489 print ' }'
José Fonseca91492d22011-05-23 21:20:31 +0100490 print ' }'
491 print ' }'
492
José Fonseca14c21bc2011-02-20 23:32:22 +0000493 Tracer.trace_function_impl_body(self, function)
José Fonseca73373602011-05-20 17:45:26 +0100494
José Fonseca91492d22011-05-23 21:20:31 +0100495 def dispatch_function(self, function):
496 if function.name in ('glLinkProgram', 'glLinkProgramARB'):
497 # These functions have been dispatched already
498 return
499
500 Tracer.dispatch_function(self, function)
501
José Fonseca73373602011-05-20 17:45:26 +0100502 def emit_memcpy(self, dest, src, length):
José Fonseca466753b2011-05-28 13:25:55 +0100503 print ' unsigned __call = __writer.beginEnter(&__memcpy_sig);'
José Fonsecaeced7472011-05-28 10:37:12 +0100504 print ' __writer.beginArg(0);'
505 print ' __writer.writeOpaque(%s);' % dest
506 print ' __writer.endArg();'
507 print ' __writer.beginArg(1);'
508 print ' __writer.writeBlob(%s, %s);' % (src, length)
509 print ' __writer.endArg();'
510 print ' __writer.beginArg(2);'
511 print ' __writer.writeUInt(%s);' % length
512 print ' __writer.endArg();'
513 print ' __writer.endEnter();'
514 print ' __writer.beginLeave(__call);'
515 print ' __writer.endLeave();'
José Fonseca867b1b72011-04-24 11:58:04 +0100516
517 buffer_targets = [
518 'ARRAY_BUFFER',
519 'ELEMENT_ARRAY_BUFFER',
520 'PIXEL_PACK_BUFFER',
521 'PIXEL_UNPACK_BUFFER',
522 ]
523
524 def wrap_ret(self, function, instance):
525 Tracer.wrap_ret(self, function, instance)
526
527 if function.name in ('glMapBuffer', 'glMapBufferARB'):
528 print ' struct buffer_mapping *mapping = get_buffer_mapping(target);'
529 print ' if (mapping) {'
530 print ' mapping->map = %s;' % (instance)
531 print ' mapping->length = 0;'
532 print ' __glGetBufferParameteriv(target, GL_BUFFER_SIZE, &mapping->length);'
533 print ' mapping->write = (access != GL_READ_ONLY);'
José Fonseca73373602011-05-20 17:45:26 +0100534 print ' mapping->explicit_flush = false;'
José Fonseca867b1b72011-04-24 11:58:04 +0100535 print ' }'
536
537 if function.name == 'glMapBufferRange':
538 print ' struct buffer_mapping *mapping = get_buffer_mapping(target);'
539 print ' if (mapping) {'
540 print ' mapping->map = %s;' % (instance)
541 print ' mapping->length = length;'
542 print ' mapping->write = access & GL_MAP_WRITE_BIT;'
José Fonseca73373602011-05-20 17:45:26 +0100543 print ' mapping->explicit_flush = access & GL_MAP_FLUSH_EXPLICIT_BIT;'
José Fonseca867b1b72011-04-24 11:58:04 +0100544 print ' }'
José Fonseca669b1222011-02-20 09:05:10 +0000545
José Fonsecac9f12232011-03-25 20:07:42 +0000546 boolean_names = [
547 'GL_FALSE',
548 'GL_TRUE',
549 ]
550
551 def gl_boolean(self, value):
552 return self.boolean_names[int(bool(value))]
553
José Fonsecac29f4f12011-06-11 12:19:05 +0100554 # Names of the functions that unpack from a pixel buffer object. See the
555 # ARB_pixel_buffer_object specification.
José Fonsecae97bab92011-06-02 23:15:11 +0100556 unpack_function_names = set([
557 'glBitmap',
José Fonsecac29f4f12011-06-11 12:19:05 +0100558 'glColorSubTable',
559 'glColorTable',
560 'glCompressedTexImage1D',
561 'glCompressedTexImage2D',
562 'glCompressedTexImage3D',
563 'glCompressedTexSubImage1D',
564 'glCompressedTexSubImage2D',
565 'glCompressedTexSubImage3D',
566 'glConvolutionFilter1D',
567 'glConvolutionFilter2D',
José Fonsecae97bab92011-06-02 23:15:11 +0100568 'glDrawPixels',
569 'glMultiTexImage1DEXT',
570 'glMultiTexImage2DEXT',
571 'glMultiTexImage3DEXT',
572 'glMultiTexSubImage1DEXT',
573 'glMultiTexSubImage2DEXT',
574 'glMultiTexSubImage3DEXT',
José Fonsecac29f4f12011-06-11 12:19:05 +0100575 'glPixelMapfv',
576 'glPixelMapuiv',
577 'glPixelMapusv',
José Fonsecae97bab92011-06-02 23:15:11 +0100578 'glPolygonStipple',
José Fonsecac29f4f12011-06-11 12:19:05 +0100579 'glSeparableFilter2D',
José Fonsecae97bab92011-06-02 23:15:11 +0100580 'glTexImage1D',
581 'glTexImage1DEXT',
582 'glTexImage2D',
583 'glTexImage2DEXT',
584 'glTexImage3D',
585 'glTexImage3DEXT',
586 'glTexSubImage1D',
587 'glTexSubImage1DEXT',
588 'glTexSubImage2D',
589 'glTexSubImage2DEXT',
590 'glTexSubImage3D',
591 'glTexSubImage3DEXT',
592 'glTextureImage1DEXT',
593 'glTextureImage2DEXT',
594 'glTextureImage3DEXT',
595 'glTextureSubImage1DEXT',
596 'glTextureSubImage2DEXT',
597 'glTextureSubImage3DEXT',
598 ])
599
José Fonseca99221832011-03-22 22:15:46 +0000600 def dump_arg_instance(self, function, arg):
601 if function.name in self.draw_function_names and arg.name == 'indices':
José Fonseca8a6c6cb2011-03-23 16:44:30 +0000602 print ' GLint __element_array_buffer = 0;'
603 print ' __glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &__element_array_buffer);'
604 print ' if (!__element_array_buffer) {'
José Fonseca5c749e32011-05-09 11:11:37 +0100605 if isinstance(arg.type, stdapi.Array):
José Fonsecaeced7472011-05-28 10:37:12 +0100606 print ' __writer.beginArray(%s);' % arg.type.length
José Fonseca5c749e32011-05-09 11:11:37 +0100607 print ' for(GLsizei i = 0; i < %s; ++i) {' % arg.type.length
José Fonsecaeced7472011-05-28 10:37:12 +0100608 print ' __writer.beginElement();'
José Fonsecafd34e4e2011-06-03 19:34:29 +0100609 print ' __writer.writeBlob(%s[i], count[i]*__gl_type_size(type));' % (arg.name)
José Fonsecaeced7472011-05-28 10:37:12 +0100610 print ' __writer.endElement();'
José Fonseca5c749e32011-05-09 11:11:37 +0100611 print ' }'
José Fonsecaeced7472011-05-28 10:37:12 +0100612 print ' __writer.endArray();'
José Fonseca5c749e32011-05-09 11:11:37 +0100613 else:
José Fonsecafd34e4e2011-06-03 19:34:29 +0100614 print ' __writer.writeBlob(%s, count*__gl_type_size(type));' % (arg.name)
José Fonseca8a6c6cb2011-03-23 16:44:30 +0000615 print ' } else {'
José Fonseca5c749e32011-05-09 11:11:37 +0100616 Tracer.dump_arg_instance(self, function, arg)
José Fonseca8a6c6cb2011-03-23 16:44:30 +0000617 print ' }'
618 return
619
José Fonsecae97bab92011-06-02 23:15:11 +0100620 # Recognize offsets instead of blobs when a PBO is bound
621 if function.name in self.unpack_function_names \
622 and (isinstance(arg.type, stdapi.Blob) \
623 or (isinstance(arg.type, stdapi.Const) \
624 and isinstance(arg.type.type, stdapi.Blob))):
José Fonsecac29f4f12011-06-11 12:19:05 +0100625 print ' {'
626 print ' GLint __unpack_buffer = 0;'
627 print ' __glGetIntegerv(GL_PIXEL_UNPACK_BUFFER_BINDING, &__unpack_buffer);'
628 print ' if (__unpack_buffer) {'
629 print ' __writer.writeOpaque(%s);' % arg.name
630 print ' } else {'
José Fonsecae97bab92011-06-02 23:15:11 +0100631 Tracer.dump_arg_instance(self, function, arg)
José Fonsecac29f4f12011-06-11 12:19:05 +0100632 print ' }'
José Fonsecae97bab92011-06-02 23:15:11 +0100633 print ' }'
634 return
635
José Fonsecaa3f89ae2011-04-26 08:50:32 +0100636 # Several GL state functions take GLenum symbolic names as
637 # integer/floats; so dump the symbolic name whenever possible
José Fonseca3bcb33c2011-05-27 20:14:31 +0100638 if function.name.startswith('gl') \
639 and arg.type in (glapi.GLint, glapi.GLfloat) \
640 and arg.name == 'param':
José Fonsecaa3f89ae2011-04-26 08:50:32 +0100641 assert arg.index > 0
642 assert function.args[arg.index - 1].name == 'pname'
643 assert function.args[arg.index - 1].type == glapi.GLenum
644 print ' if (is_symbolic_pname(pname) && is_symbolic_param(%s)) {' % arg.name
645 dump_instance(glapi.GLenum, arg.name)
646 print ' } else {'
647 Tracer.dump_arg_instance(self, function, arg)
648 print ' }'
649 return
650
José Fonseca8a6c6cb2011-03-23 16:44:30 +0000651 Tracer.dump_arg_instance(self, function, arg)
José Fonseca99221832011-03-22 22:15:46 +0000652
José Fonseca4c938c22011-04-30 22:44:38 +0100653 def footer(self, api):
654 Tracer.footer(self, api)
José Fonseca669b1222011-02-20 09:05:10 +0000655
José Fonseca4c938c22011-04-30 22:44:38 +0100656 # A simple state tracker to track the pointer values
José Fonseca669b1222011-02-20 09:05:10 +0000657 # update the state
José Fonseca8a6c6cb2011-03-23 16:44:30 +0000658 print 'static void __trace_user_arrays(GLuint maxindex)'
José Fonseca669b1222011-02-20 09:05:10 +0000659 print '{'
José Fonseca1a2fdd22011-04-01 00:55:09 +0100660
José Fonseca99221832011-03-22 22:15:46 +0000661 for camelcase_name, uppercase_name in self.arrays:
662 function_name = 'gl%sPointer' % camelcase_name
663 enable_name = 'GL_%s_ARRAY' % uppercase_name
664 binding_name = 'GL_%s_ARRAY_BUFFER_BINDING' % uppercase_name
José Fonseca14c21bc2011-02-20 23:32:22 +0000665 function = api.get_function_by_name(function_name)
José Fonseca99221832011-03-22 22:15:46 +0000666
667 print ' // %s' % function.name
José Fonsecafb6744f2011-04-15 11:18:37 +0100668 self.array_trace_prolog(api, uppercase_name)
669 self.array_prolog(api, uppercase_name)
670 print ' if (__glIsEnabled(%s)) {' % enable_name
José Fonseca7f5163e2011-03-31 23:37:26 +0100671 print ' GLint __binding = 0;'
672 print ' __glGetIntegerv(%s, &__binding);' % binding_name
673 print ' if (!__binding) {'
José Fonseca99221832011-03-22 22:15:46 +0000674
675 # Get the arguments via glGet*
676 for arg in function.args:
677 arg_get_enum = 'GL_%s_ARRAY_%s' % (uppercase_name, arg.name.upper())
678 arg_get_function, arg_type = TypeGetter().visit(arg.type)
José Fonseca7f5163e2011-03-31 23:37:26 +0100679 print ' %s %s = 0;' % (arg_type, arg.name)
680 print ' __%s(%s, &%s);' % (arg_get_function, arg_get_enum, arg.name)
José Fonseca99221832011-03-22 22:15:46 +0000681
682 arg_names = ', '.join([arg.name for arg in function.args[:-1]])
José Fonseca7f5163e2011-03-31 23:37:26 +0100683 print ' size_t __size = __%s_size(%s, maxindex);' % (function.name, arg_names)
José Fonseca99221832011-03-22 22:15:46 +0000684
685 # Emit a fake function
José Fonsecafb6744f2011-04-15 11:18:37 +0100686 self.array_trace_intermezzo(api, uppercase_name)
José Fonseca466753b2011-05-28 13:25:55 +0100687 print ' unsigned __call = __writer.beginEnter(&__%s_sig);' % (function.name,)
José Fonseca669b1222011-02-20 09:05:10 +0000688 for arg in function.args:
689 assert not arg.output
José Fonsecaeced7472011-05-28 10:37:12 +0100690 print ' __writer.beginArg(%u);' % (arg.index,)
José Fonseca14c21bc2011-02-20 23:32:22 +0000691 if arg.name != 'pointer':
José Fonseca99221832011-03-22 22:15:46 +0000692 dump_instance(arg.type, arg.name)
José Fonseca14c21bc2011-02-20 23:32:22 +0000693 else:
José Fonsecaeced7472011-05-28 10:37:12 +0100694 print ' __writer.writeBlob((const void *)%s, __size);' % (arg.name)
695 print ' __writer.endArg();'
José Fonseca99221832011-03-22 22:15:46 +0000696
José Fonsecaeced7472011-05-28 10:37:12 +0100697 print ' __writer.endEnter();'
698 print ' __writer.beginLeave(__call);'
699 print ' __writer.endLeave();'
José Fonseca99221832011-03-22 22:15:46 +0000700 print ' }'
José Fonseca669b1222011-02-20 09:05:10 +0000701 print ' }'
José Fonsecafb6744f2011-04-15 11:18:37 +0100702 self.array_epilog(api, uppercase_name)
703 self.array_trace_epilog(api, uppercase_name)
José Fonseca99221832011-03-22 22:15:46 +0000704 print
José Fonseca1a2fdd22011-04-01 00:55:09 +0100705
José Fonseca1601c412011-05-10 10:38:19 +0100706 # Samething, but for glVertexAttribPointer*
707 #
708 # Some variants of glVertexAttribPointer alias conventional and generic attributes:
709 # - glVertexAttribPointer: no
710 # - glVertexAttribPointerARB: implementation dependent
711 # - glVertexAttribPointerNV: yes
712 #
713 # This means that the implementations of these functions do not always
714 # alias, and they need to be considered independently.
715 #
José Fonseca5a568a92011-06-29 16:43:36 +0100716 print ' vertex_attrib __vertex_attrib = __get_vertex_attrib();'
717 print
718 for suffix in ['', 'ARB', 'NV']:
719 if suffix:
José Fonsecad94aaac2011-06-28 20:50:49 +0100720 SUFFIX = '_' + suffix
José Fonsecad94aaac2011-06-28 20:50:49 +0100721 else:
José Fonseca5a568a92011-06-29 16:43:36 +0100722 SUFFIX = suffix
José Fonseca1601c412011-05-10 10:38:19 +0100723 function_name = 'glVertexAttribPointer' + suffix
José Fonseca5a568a92011-06-29 16:43:36 +0100724 print ' // %s' % function_name
725 print ' if (__vertex_attrib == VERTEX_ATTRIB%s) {' % SUFFIX
726 if suffix == 'NV':
727 print ' GLint __max_vertex_attribs = 16;'
728 else:
729 print ' GLint __max_vertex_attribs = 0;'
730 print ' __glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &__max_vertex_attribs);'
731 print ' for (GLint index = 0; index < __max_vertex_attribs; ++index) {'
732 print ' GLint __enabled = 0;'
733 if suffix == 'NV':
734 print ' __glGetIntegerv(GL_VERTEX_ATTRIB_ARRAY0_NV + index, &__enabled);'
735 else:
736 print ' __glGetVertexAttribiv%s(index, GL_VERTEX_ATTRIB_ARRAY_ENABLED%s, &__enabled);' % (suffix, SUFFIX)
737 print ' if (__enabled) {'
738 print ' GLint __binding = 0;'
739 if suffix != 'NV':
740 # It doesn't seem possible to use VBOs with NV_vertex_program.
741 print ' __glGetVertexAttribiv%s(index, GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING%s, &__binding);' % (suffix, SUFFIX)
742 print ' if (!__binding) {'
José Fonseca1a2fdd22011-04-01 00:55:09 +0100743
José Fonseca1601c412011-05-10 10:38:19 +0100744 function = api.get_function_by_name(function_name)
José Fonseca1a2fdd22011-04-01 00:55:09 +0100745
José Fonseca1601c412011-05-10 10:38:19 +0100746 # Get the arguments via glGet*
747 for arg in function.args[1:]:
José Fonseca5a568a92011-06-29 16:43:36 +0100748 if suffix == 'NV':
749 arg_get_enum = 'GL_ATTRIB_ARRAY_%s%s' % (arg.name.upper(), SUFFIX)
750 else:
751 arg_get_enum = 'GL_VERTEX_ATTRIB_ARRAY_%s%s' % (arg.name.upper(), SUFFIX)
José Fonsecac493e3e2011-06-29 12:57:06 +0100752 arg_get_function, arg_type = TypeGetter('glGetVertexAttrib', False, suffix).visit(arg.type)
José Fonseca5a568a92011-06-29 16:43:36 +0100753 print ' %s %s = 0;' % (arg_type, arg.name)
754 print ' __%s(index, %s, &%s);' % (arg_get_function, arg_get_enum, arg.name)
José Fonseca1601c412011-05-10 10:38:19 +0100755
756 arg_names = ', '.join([arg.name for arg in function.args[1:-1]])
José Fonseca5a568a92011-06-29 16:43:36 +0100757 print ' size_t __size = __%s_size(%s, maxindex);' % (function.name, arg_names)
José Fonseca1a2fdd22011-04-01 00:55:09 +0100758
José Fonseca1601c412011-05-10 10:38:19 +0100759 # Emit a fake function
José Fonseca5a568a92011-06-29 16:43:36 +0100760 print ' unsigned __call = __writer.beginEnter(&__%s_sig);' % (function.name,)
José Fonseca1601c412011-05-10 10:38:19 +0100761 for arg in function.args:
762 assert not arg.output
José Fonseca5a568a92011-06-29 16:43:36 +0100763 print ' __writer.beginArg(%u);' % (arg.index,)
José Fonseca1601c412011-05-10 10:38:19 +0100764 if arg.name != 'pointer':
765 dump_instance(arg.type, arg.name)
766 else:
José Fonseca5a568a92011-06-29 16:43:36 +0100767 print ' __writer.writeBlob((const void *)%s, __size);' % (arg.name)
768 print ' __writer.endArg();'
José Fonseca1601c412011-05-10 10:38:19 +0100769
José Fonseca5a568a92011-06-29 16:43:36 +0100770 print ' __writer.endEnter();'
771 print ' __writer.beginLeave(__call);'
772 print ' __writer.endLeave();'
José Fonseca1601c412011-05-10 10:38:19 +0100773 print ' }'
774 print ' }'
775 print ' }'
776 print ' }'
777 print
José Fonseca1a2fdd22011-04-01 00:55:09 +0100778
José Fonseca669b1222011-02-20 09:05:10 +0000779 print '}'
780 print
781
José Fonsecafb6744f2011-04-15 11:18:37 +0100782 #
783 # Hooks for glTexCoordPointer, which is identical to the other array
784 # pointers except the fact that it is indexed by glClientActiveTexture.
785 #
786
787 def array_prolog(self, api, uppercase_name):
788 if uppercase_name == 'TEXTURE_COORD':
789 print ' GLint client_active_texture = 0;'
790 print ' __glGetIntegerv(GL_CLIENT_ACTIVE_TEXTURE, &client_active_texture);'
791 print ' GLint max_texture_coords = 0;'
792 print ' __glGetIntegerv(GL_MAX_TEXTURE_COORDS, &max_texture_coords);'
793 print ' for (GLint unit = 0; unit < max_texture_coords; ++unit) {'
794 print ' GLenum texture = GL_TEXTURE0 + unit;'
795 print ' __glClientActiveTexture(texture);'
796
797 def array_trace_prolog(self, api, uppercase_name):
798 if uppercase_name == 'TEXTURE_COORD':
799 print ' bool client_active_texture_dirty = false;'
800
801 def array_epilog(self, api, uppercase_name):
802 if uppercase_name == 'TEXTURE_COORD':
803 print ' }'
804 self.array_cleanup(api, uppercase_name)
805
806 def array_cleanup(self, api, uppercase_name):
807 if uppercase_name == 'TEXTURE_COORD':
808 print ' __glClientActiveTexture(client_active_texture);'
809
810 def array_trace_intermezzo(self, api, uppercase_name):
811 if uppercase_name == 'TEXTURE_COORD':
812 print ' if (texture != client_active_texture || client_active_texture_dirty) {'
813 print ' client_active_texture_dirty = true;'
814 self.fake_glClientActiveTexture_call(api, "texture");
815 print ' }'
816
817 def array_trace_epilog(self, api, uppercase_name):
818 if uppercase_name == 'TEXTURE_COORD':
819 print ' if (client_active_texture_dirty) {'
820 self.fake_glClientActiveTexture_call(api, "client_active_texture");
821 print ' }'
822
823 def fake_glClientActiveTexture_call(self, api, texture):
824 function = api.get_function_by_name('glClientActiveTexture')
825 self.fake_call(function, [texture])
826
827 def fake_call(self, function, args):
José Fonseca466753b2011-05-28 13:25:55 +0100828 print ' unsigned __fake_call = __writer.beginEnter(&__%s_sig);' % (function.name,)
José Fonsecafb6744f2011-04-15 11:18:37 +0100829 for arg, instance in zip(function.args, args):
830 assert not arg.output
José Fonsecaeced7472011-05-28 10:37:12 +0100831 print ' __writer.beginArg(%u);' % (arg.index,)
José Fonsecafb6744f2011-04-15 11:18:37 +0100832 dump_instance(arg.type, instance)
José Fonsecaeced7472011-05-28 10:37:12 +0100833 print ' __writer.endArg();'
834 print ' __writer.endEnter();'
835 print ' __writer.beginLeave(__fake_call);'
836 print ' __writer.endLeave();'
José Fonsecafb6744f2011-04-15 11:18:37 +0100837
838
839
840
841
José Fonseca669b1222011-02-20 09:05:10 +0000842
843
844
845
846
847