blob: 5811e7bb5d1889e893f1a119a1e8e367bec23c5a [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é Fonseca452d3252012-04-14 15:55:40 +010030from trace import Tracer
José Fonseca1b6c8752012-04-15 14:33:00 +010031from dispatch import function_pointer_type, function_pointer_value
José Fonsecabd86a222011-09-27 09:21:38 +010032import specs.stdapi as stdapi
33import specs.glapi as glapi
34import specs.glparams as glparams
35from specs.glxapi import glxapi
José Fonseca669b1222011-02-20 09:05:10 +000036
37
José Fonseca99221832011-03-22 22:15:46 +000038class TypeGetter(stdapi.Visitor):
39 '''Determine which glGet*v function that matches the specified type.'''
40
José Fonsecac493e3e2011-06-29 12:57:06 +010041 def __init__(self, prefix = 'glGet', long_suffix = True, ext_suffix = ''):
José Fonseca1a2fdd22011-04-01 00:55:09 +010042 self.prefix = prefix
43 self.long_suffix = long_suffix
José Fonsecac493e3e2011-06-29 12:57:06 +010044 self.ext_suffix = ext_suffix
José Fonseca1a2fdd22011-04-01 00:55:09 +010045
José Fonseca54f304a2012-01-14 19:33:08 +000046 def visitConst(self, const):
José Fonseca99221832011-03-22 22:15:46 +000047 return self.visit(const.type)
48
José Fonseca54f304a2012-01-14 19:33:08 +000049 def visitAlias(self, alias):
José Fonseca99221832011-03-22 22:15:46 +000050 if alias.expr == 'GLboolean':
José Fonseca1a2fdd22011-04-01 00:55:09 +010051 if self.long_suffix:
José Fonsecac493e3e2011-06-29 12:57:06 +010052 suffix = 'Booleanv'
53 arg_type = alias.expr
José Fonseca1a2fdd22011-04-01 00:55:09 +010054 else:
José Fonsecac493e3e2011-06-29 12:57:06 +010055 suffix = 'iv'
56 arg_type = 'GLint'
José Fonseca99221832011-03-22 22:15:46 +000057 elif alias.expr == 'GLdouble':
José Fonseca1a2fdd22011-04-01 00:55:09 +010058 if self.long_suffix:
José Fonsecac493e3e2011-06-29 12:57:06 +010059 suffix = 'Doublev'
60 arg_type = alias.expr
José Fonseca1a2fdd22011-04-01 00:55:09 +010061 else:
José Fonsecac493e3e2011-06-29 12:57:06 +010062 suffix = 'dv'
63 arg_type = alias.expr
José Fonseca99221832011-03-22 22:15:46 +000064 elif alias.expr == 'GLfloat':
José Fonseca1a2fdd22011-04-01 00:55:09 +010065 if self.long_suffix:
José Fonsecac493e3e2011-06-29 12:57:06 +010066 suffix = 'Floatv'
67 arg_type = alias.expr
José Fonseca1a2fdd22011-04-01 00:55:09 +010068 else:
José Fonsecac493e3e2011-06-29 12:57:06 +010069 suffix = 'fv'
70 arg_type = alias.expr
José Fonseca7f5163e2011-03-31 23:37:26 +010071 elif alias.expr in ('GLint', 'GLuint', 'GLsizei'):
José Fonseca1a2fdd22011-04-01 00:55:09 +010072 if self.long_suffix:
José Fonsecac493e3e2011-06-29 12:57:06 +010073 suffix = 'Integerv'
74 arg_type = 'GLint'
José Fonseca1a2fdd22011-04-01 00:55:09 +010075 else:
José Fonsecac493e3e2011-06-29 12:57:06 +010076 suffix = 'iv'
77 arg_type = 'GLint'
José Fonseca99221832011-03-22 22:15:46 +000078 else:
79 print alias.expr
80 assert False
José Fonsecac493e3e2011-06-29 12:57:06 +010081 function_name = self.prefix + suffix + self.ext_suffix
82 return function_name, arg_type
José Fonseca99221832011-03-22 22:15:46 +000083
José Fonseca54f304a2012-01-14 19:33:08 +000084 def visitEnum(self, enum):
José Fonseca1a2fdd22011-04-01 00:55:09 +010085 return self.visit(glapi.GLint)
José Fonseca99221832011-03-22 22:15:46 +000086
José Fonseca54f304a2012-01-14 19:33:08 +000087 def visitBitmask(self, bitmask):
José Fonseca1a2fdd22011-04-01 00:55:09 +010088 return self.visit(glapi.GLint)
José Fonseca99221832011-03-22 22:15:46 +000089
José Fonseca54f304a2012-01-14 19:33:08 +000090 def visitOpaque(self, pointer):
José Fonsecac493e3e2011-06-29 12:57:06 +010091 return self.prefix + 'Pointerv' + self.ext_suffix, 'GLvoid *'
José Fonseca99221832011-03-22 22:15:46 +000092
93
José Fonseca669b1222011-02-20 09:05:10 +000094class GlTracer(Tracer):
95
José Fonseca99221832011-03-22 22:15:46 +000096 arrays = [
97 ("Vertex", "VERTEX"),
98 ("Normal", "NORMAL"),
99 ("Color", "COLOR"),
100 ("Index", "INDEX"),
101 ("TexCoord", "TEXTURE_COORD"),
102 ("EdgeFlag", "EDGE_FLAG"),
103 ("FogCoord", "FOG_COORD"),
104 ("SecondaryColor", "SECONDARY_COLOR"),
José Fonseca14c21bc2011-02-20 23:32:22 +0000105 ]
José Fonsecac9f12232011-03-25 20:07:42 +0000106 arrays.reverse()
José Fonseca669b1222011-02-20 09:05:10 +0000107
Chia-I Wub3d218d2011-11-03 01:37:36 +0800108 # arrays available in PROFILE_ES1
109 arrays_es1 = ("Vertex", "Normal", "Color", "TexCoord")
110
José Fonseca4c938c22011-04-30 22:44:38 +0100111 def header(self, api):
112 Tracer.header(self, api)
113
José Fonseca1b3d3752011-07-15 10:15:19 +0100114 print '#include "gltrace.hpp"'
115 print
José Fonseca5a568a92011-06-29 16:43:36 +0100116
117 # Which glVertexAttrib* variant to use
118 print 'enum vertex_attrib {'
119 print ' VERTEX_ATTRIB,'
120 print ' VERTEX_ATTRIB_ARB,'
121 print ' VERTEX_ATTRIB_NV,'
122 print '};'
123 print
José Fonseca632a78d2012-04-19 07:18:59 +0100124 print 'static vertex_attrib _get_vertex_attrib(void) {'
José Fonsecaf028a8f2012-02-15 23:33:35 +0000125 print ' gltrace::Context *ctx = gltrace::getContext();'
Chia-I Wu8ef66972011-11-03 01:19:46 +0800126 print ' if (ctx->user_arrays_arb || ctx->user_arrays_nv) {'
José Fonseca632a78d2012-04-19 07:18:59 +0100127 print ' GLboolean _vertex_program = GL_FALSE;'
128 print ' _glGetBooleanv(GL_VERTEX_PROGRAM_ARB, &_vertex_program);'
129 print ' if (_vertex_program) {'
Chia-I Wu8ef66972011-11-03 01:19:46 +0800130 print ' if (ctx->user_arrays_nv) {'
José Fonseca632a78d2012-04-19 07:18:59 +0100131 print ' GLint _vertex_program_binding_nv = 0;'
132 print ' _glGetIntegerv(GL_VERTEX_PROGRAM_BINDING_NV, &_vertex_program_binding_nv);'
133 print ' if (_vertex_program_binding_nv) {'
José Fonseca5a568a92011-06-29 16:43:36 +0100134 print ' return VERTEX_ATTRIB_NV;'
135 print ' }'
136 print ' }'
137 print ' return VERTEX_ATTRIB_ARB;'
138 print ' }'
139 print ' }'
140 print ' return VERTEX_ATTRIB;'
141 print '}'
142 print
143
Imre Deakd4937372012-04-24 14:06:48 +0300144 self.defineShadowBufferHelper()
145
José Fonseca8a6c6cb2011-03-23 16:44:30 +0000146 # Whether we need user arrays
José Fonseca632a78d2012-04-19 07:18:59 +0100147 print 'static inline bool _need_user_arrays(void)'
José Fonseca8a6c6cb2011-03-23 16:44:30 +0000148 print '{'
José Fonsecaf028a8f2012-02-15 23:33:35 +0000149 print ' gltrace::Context *ctx = gltrace::getContext();'
Chia-I Wu8ef66972011-11-03 01:19:46 +0800150 print ' if (!ctx->user_arrays) {'
José Fonseca25ebe542011-04-24 10:08:22 +0100151 print ' return false;'
152 print ' }'
153 print
José Fonseca1a2fdd22011-04-01 00:55:09 +0100154
José Fonseca8a6c6cb2011-03-23 16:44:30 +0000155 for camelcase_name, uppercase_name in self.arrays:
Chia-I Wub3d218d2011-11-03 01:37:36 +0800156 # in which profile is the array available?
José Fonsecaf028a8f2012-02-15 23:33:35 +0000157 profile_check = 'ctx->profile == gltrace::PROFILE_COMPAT'
Chia-I Wub3d218d2011-11-03 01:37:36 +0800158 if camelcase_name in self.arrays_es1:
José Fonsecaf028a8f2012-02-15 23:33:35 +0000159 profile_check = '(' + profile_check + ' || ctx->profile == gltrace::PROFILE_ES1)';
Chia-I Wub3d218d2011-11-03 01:37:36 +0800160
José Fonseca8a6c6cb2011-03-23 16:44:30 +0000161 function_name = 'gl%sPointer' % camelcase_name
162 enable_name = 'GL_%s_ARRAY' % uppercase_name
163 binding_name = 'GL_%s_ARRAY_BUFFER_BINDING' % uppercase_name
164 print ' // %s' % function_name
Chia-I Wub3d218d2011-11-03 01:37:36 +0800165 print ' if (%s) {' % profile_check
José Fonsecafb6744f2011-04-15 11:18:37 +0100166 self.array_prolog(api, uppercase_name)
José Fonseca632a78d2012-04-19 07:18:59 +0100167 print ' if (_glIsEnabled(%s)) {' % enable_name
168 print ' GLint _binding = 0;'
169 print ' _glGetIntegerv(%s, &_binding);' % binding_name
170 print ' if (!_binding) {'
José Fonsecafb6744f2011-04-15 11:18:37 +0100171 self.array_cleanup(api, uppercase_name)
José Fonseca7f5163e2011-03-31 23:37:26 +0100172 print ' return true;'
José Fonseca8a6c6cb2011-03-23 16:44:30 +0000173 print ' }'
174 print ' }'
José Fonsecafb6744f2011-04-15 11:18:37 +0100175 self.array_epilog(api, uppercase_name)
Chia-I Wub3d218d2011-11-03 01:37:36 +0800176 print ' }'
José Fonseca8a6c6cb2011-03-23 16:44:30 +0000177 print
José Fonseca7f5163e2011-03-31 23:37:26 +0100178
Chia-I Wub3d218d2011-11-03 01:37:36 +0800179 print ' // ES1 does not support generic vertex attributes'
José Fonsecaf028a8f2012-02-15 23:33:35 +0000180 print ' if (ctx->profile == gltrace::PROFILE_ES1)'
Chia-I Wub3d218d2011-11-03 01:37:36 +0800181 print ' return false;'
182 print
José Fonseca632a78d2012-04-19 07:18:59 +0100183 print ' vertex_attrib _vertex_attrib = _get_vertex_attrib();'
José Fonseca5a568a92011-06-29 16:43:36 +0100184 print
185 print ' // glVertexAttribPointer'
José Fonseca632a78d2012-04-19 07:18:59 +0100186 print ' if (_vertex_attrib == VERTEX_ATTRIB) {'
187 print ' GLint _max_vertex_attribs = 0;'
188 print ' _glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &_max_vertex_attribs);'
189 print ' for (GLint index = 0; index < _max_vertex_attribs; ++index) {'
190 print ' GLint _enabled = 0;'
191 print ' _glGetVertexAttribiv(index, GL_VERTEX_ATTRIB_ARRAY_ENABLED, &_enabled);'
192 print ' if (_enabled) {'
193 print ' GLint _binding = 0;'
194 print ' _glGetVertexAttribiv(index, GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING, &_binding);'
195 print ' if (!_binding) {'
José Fonseca5a568a92011-06-29 16:43:36 +0100196 print ' return true;'
197 print ' }'
198 print ' }'
199 print ' }'
200 print ' }'
201 print
202 print ' // glVertexAttribPointerARB'
José Fonseca632a78d2012-04-19 07:18:59 +0100203 print ' if (_vertex_attrib == VERTEX_ATTRIB_ARB) {'
204 print ' GLint _max_vertex_attribs = 0;'
205 print ' _glGetIntegerv(GL_MAX_VERTEX_ATTRIBS_ARB, &_max_vertex_attribs);'
206 print ' for (GLint index = 0; index < _max_vertex_attribs; ++index) {'
207 print ' GLint _enabled = 0;'
208 print ' _glGetVertexAttribivARB(index, GL_VERTEX_ATTRIB_ARRAY_ENABLED_ARB, &_enabled);'
209 print ' if (_enabled) {'
210 print ' GLint _binding = 0;'
211 print ' _glGetVertexAttribivARB(index, GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING_ARB, &_binding);'
212 print ' if (!_binding) {'
José Fonsecad94aaac2011-06-28 20:50:49 +0100213 print ' return true;'
214 print ' }'
215 print ' }'
216 print ' }'
José Fonseca5a568a92011-06-29 16:43:36 +0100217 print ' }'
218 print
219 print ' // glVertexAttribPointerNV'
José Fonseca632a78d2012-04-19 07:18:59 +0100220 print ' if (_vertex_attrib == VERTEX_ATTRIB_NV) {'
José Fonseca5a568a92011-06-29 16:43:36 +0100221 print ' for (GLint index = 0; index < 16; ++index) {'
José Fonseca632a78d2012-04-19 07:18:59 +0100222 print ' GLint _enabled = 0;'
223 print ' _glGetIntegerv(GL_VERTEX_ATTRIB_ARRAY0_NV + index, &_enabled);'
224 print ' if (_enabled) {'
José Fonseca5a568a92011-06-29 16:43:36 +0100225 print ' return true;'
José Fonseca1a2fdd22011-04-01 00:55:09 +0100226 print ' }'
227 print ' }'
228 print ' }'
229 print
230
José Fonseca8a6c6cb2011-03-23 16:44:30 +0000231 print ' return false;'
232 print '}'
233 print
José Fonseca669b1222011-02-20 09:05:10 +0000234
José Fonseca14cb9ef2012-05-17 21:33:14 +0100235 print 'static void _trace_user_arrays(GLuint count);'
José Fonseca14c21bc2011-02-20 23:32:22 +0000236 print
José Fonseca867b1b72011-04-24 11:58:04 +0100237
José Fonseca9c536b02012-02-29 20:54:13 +0000238 # Buffer mappings
239 print '// whether glMapBufferRange(GL_MAP_WRITE_BIT) has ever been called'
José Fonseca632a78d2012-04-19 07:18:59 +0100240 print 'static bool _checkBufferMapRange = false;'
José Fonseca9c536b02012-02-29 20:54:13 +0000241 print
242 print '// whether glBufferParameteriAPPLE(GL_BUFFER_FLUSHING_UNMAP_APPLE, GL_FALSE) has ever been called'
José Fonseca632a78d2012-04-19 07:18:59 +0100243 print 'static bool _checkBufferFlushingUnmapAPPLE = false;'
José Fonseca9c536b02012-02-29 20:54:13 +0000244 print
245 # Buffer mapping information, necessary for old Mesa 2.1 drivers which
246 # do not support glGetBufferParameteriv(GL_BUFFER_ACCESS_FLAGS/GL_BUFFER_MAP_LENGTH)
José Fonseca867b1b72011-04-24 11:58:04 +0100247 print 'struct buffer_mapping {'
248 print ' void *map;'
249 print ' GLint length;'
250 print ' bool write;'
José Fonseca73373602011-05-20 17:45:26 +0100251 print ' bool explicit_flush;'
José Fonseca867b1b72011-04-24 11:58:04 +0100252 print '};'
253 print
254 for target in self.buffer_targets:
José Fonseca632a78d2012-04-19 07:18:59 +0100255 print 'struct buffer_mapping _%s_mapping;' % target.lower();
José Fonseca867b1b72011-04-24 11:58:04 +0100256 print
257 print 'static inline struct buffer_mapping *'
258 print 'get_buffer_mapping(GLenum target) {'
José Fonseca06e85192011-10-16 14:15:36 +0100259 print ' switch (target) {'
José Fonseca867b1b72011-04-24 11:58:04 +0100260 for target in self.buffer_targets:
261 print ' case GL_%s:' % target
José Fonseca632a78d2012-04-19 07:18:59 +0100262 print ' return & _%s_mapping;' % target.lower()
José Fonseca867b1b72011-04-24 11:58:04 +0100263 print ' default:'
José Fonseca559d5342011-10-27 08:10:56 +0100264 print ' os::log("apitrace: warning: unknown buffer target 0x%04X\\n", target);'
José Fonseca867b1b72011-04-24 11:58:04 +0100265 print ' return NULL;'
266 print ' }'
267 print '}'
268 print
269
José Fonsecaa3f89ae2011-04-26 08:50:32 +0100270 # Generate a helper function to determine whether a parameter name
271 # refers to a symbolic value or not
272 print 'static bool'
273 print 'is_symbolic_pname(GLenum pname) {'
José Fonseca06e85192011-10-16 14:15:36 +0100274 print ' switch (pname) {'
José Fonseca5ea91872011-05-04 09:41:55 +0100275 for function, type, count, name in glparams.parameters:
José Fonsecaa3f89ae2011-04-26 08:50:32 +0100276 if type is glapi.GLenum:
José Fonseca4c938c22011-04-30 22:44:38 +0100277 print ' case %s:' % name
278 print ' return true;'
279 print ' default:'
280 print ' return false;'
José Fonsecaa3f89ae2011-04-26 08:50:32 +0100281 print ' }'
282 print '}'
283 print
284
285 # Generate a helper function to determine whether a parameter value is
286 # potentially symbolic or not; i.e., if the value can be represented in
287 # an enum or not
288 print 'template<class T>'
289 print 'static inline bool'
290 print 'is_symbolic_param(T param) {'
291 print ' return static_cast<T>(static_cast<GLenum>(param)) == param;'
292 print '}'
293 print
José Fonseca4c938c22011-04-30 22:44:38 +0100294
295 # Generate a helper function to know how many elements a parameter has
296 print 'static size_t'
José Fonseca632a78d2012-04-19 07:18:59 +0100297 print '_gl_param_size(GLenum pname) {'
José Fonseca06e85192011-10-16 14:15:36 +0100298 print ' switch (pname) {'
José Fonseca5ea91872011-05-04 09:41:55 +0100299 for function, type, count, name in glparams.parameters:
José Fonseca4c938c22011-04-30 22:44:38 +0100300 if type is not None:
José Fonsecaddf6d2c2012-12-20 15:34:50 +0000301 print ' case %s: return %s;' % (name, count)
José Fonseca4c938c22011-04-30 22:44:38 +0100302 print ' default:'
José Fonseca559d5342011-10-27 08:10:56 +0100303 print r' os::log("apitrace: warning: %s: unknown GLenum 0x%04X\n", __FUNCTION__, pname);'
José Fonseca4c938c22011-04-30 22:44:38 +0100304 print ' return 1;'
305 print ' }'
306 print '}'
307 print
308
Chia-I Wu335efb42011-11-03 01:59:22 +0800309 # states such as GL_UNPACK_ROW_LENGTH are not available in GLES
310 print 'static inline bool'
311 print 'can_unpack_subimage(void) {'
José Fonsecaf028a8f2012-02-15 23:33:35 +0000312 print ' gltrace::Context *ctx = gltrace::getContext();'
313 print ' return (ctx->profile == gltrace::PROFILE_COMPAT);'
Chia-I Wu335efb42011-11-03 01:59:22 +0800314 print '}'
315 print
316
José Fonseca1b6c8752012-04-15 14:33:00 +0100317 getProcAddressFunctionNames = []
318
319 def traceApi(self, api):
320 if self.getProcAddressFunctionNames:
321 # Generate a function to wrap proc addresses
322 getProcAddressFunction = api.getFunctionByName(self.getProcAddressFunctionNames[0])
323 argType = getProcAddressFunction.args[0].type
324 retType = getProcAddressFunction.type
325
326 print 'static %s _wrapProcAddress(%s procName, %s procPtr);' % (retType, argType, retType)
327 print
328
329 Tracer.traceApi(self, api)
330
331 print 'static %s _wrapProcAddress(%s procName, %s procPtr) {' % (retType, argType, retType)
332 print ' if (!procPtr) {'
333 print ' return procPtr;'
334 print ' }'
José Fonseca81301932012-11-11 00:10:20 +0000335 for function in api.getAllFunctions():
José Fonseca1b6c8752012-04-15 14:33:00 +0100336 ptype = function_pointer_type(function)
337 pvalue = function_pointer_value(function)
338 print ' if (strcmp("%s", (const char *)procName) == 0) {' % function.name
339 print ' %s = (%s)procPtr;' % (pvalue, ptype)
340 print ' return (%s)&%s;' % (retType, function.name,)
341 print ' }'
342 print ' os::log("apitrace: warning: unknown function \\"%s\\"\\n", (const char *)procName);'
343 print ' return procPtr;'
344 print '}'
345 print
346 else:
347 Tracer.traceApi(self, api)
348
Imre Deakd4937372012-04-24 14:06:48 +0300349 def defineShadowBufferHelper(self):
350 print 'void _shadow_glGetBufferSubData(GLenum target, GLintptr offset,'
351 print ' GLsizeiptr size, GLvoid *data)'
352 print '{'
José Fonsecaa33d0bb2012-11-10 09:11:42 +0000353 print ' gltrace::Context *ctx = gltrace::getContext();'
Imre Deakd4937372012-04-24 14:06:48 +0300354 print ' if (!ctx->needsShadowBuffers() || target != GL_ELEMENT_ARRAY_BUFFER) {'
José Fonseca219c9f22012-11-03 10:13:17 +0000355 print ' _glGetBufferSubData(target, offset, size, data);'
Imre Deakd4937372012-04-24 14:06:48 +0300356 print ' return;'
357 print ' }'
358 print
José Fonseca219c9f22012-11-03 10:13:17 +0000359 print ' GLint buffer_binding = 0;'
360 print ' _glGetIntegerv(target, &buffer_binding);'
361 print ' if (buffer_binding > 0) {'
362 print ' gltrace::Buffer & buf = ctx->buffers[buffer_binding];'
363 print ' buf.getSubData(offset, size, data);'
364 print ' }'
Imre Deakd4937372012-04-24 14:06:48 +0300365 print '}'
366
José Fonseca219c9f22012-11-03 10:13:17 +0000367 def shadowBufferMethod(self, method):
368 # Emit code to fetch the shadow buffer, and invoke a method
369 print ' gltrace::Context *ctx = gltrace::getContext();'
370 print ' if (ctx->needsShadowBuffers() && target == GL_ELEMENT_ARRAY_BUFFER) {'
371 print ' GLint buffer_binding = 0;'
372 print ' _glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &buffer_binding);'
373 print ' if (buffer_binding > 0) {'
374 print ' gltrace::Buffer & buf = ctx->buffers[buffer_binding];'
375 print ' buf.' + method + ';'
376 print ' }'
377 print ' }'
378 print
379
Imre Deakd4937372012-04-24 14:06:48 +0300380 def shadowBufferProlog(self, function):
381 if function.name == 'glBufferData':
José Fonseca219c9f22012-11-03 10:13:17 +0000382 self.shadowBufferMethod('bufferData(size, data)')
Imre Deakd4937372012-04-24 14:06:48 +0300383
384 if function.name == 'glBufferSubData':
José Fonseca219c9f22012-11-03 10:13:17 +0000385 self.shadowBufferMethod('bufferSubData(offset, size, data)')
Imre Deakd4937372012-04-24 14:06:48 +0300386
387 if function.name == 'glDeleteBuffers':
388 print ' gltrace::Context *ctx = gltrace::getContext();'
389 print ' if (ctx->needsShadowBuffers()) {'
José Fonseca219c9f22012-11-03 10:13:17 +0000390 print ' for (GLsizei i = 0; i < n; i++) {'
391 print ' ctx->buffers.erase(buffer[i]);'
Imre Deakd4937372012-04-24 14:06:48 +0300392 print ' }'
393 print ' }'
394
José Fonseca99221832011-03-22 22:15:46 +0000395 array_pointer_function_names = set((
396 "glVertexPointer",
397 "glNormalPointer",
398 "glColorPointer",
399 "glIndexPointer",
400 "glTexCoordPointer",
401 "glEdgeFlagPointer",
402 "glFogCoordPointer",
403 "glSecondaryColorPointer",
José Fonseca7f5163e2011-03-31 23:37:26 +0100404
José Fonsecaac5285b2011-05-04 11:09:08 +0100405 "glInterleavedArrays",
406
José Fonseca7e0bfd92011-04-30 23:09:03 +0100407 "glVertexPointerEXT",
408 "glNormalPointerEXT",
409 "glColorPointerEXT",
410 "glIndexPointerEXT",
411 "glTexCoordPointerEXT",
412 "glEdgeFlagPointerEXT",
413 "glFogCoordPointerEXT",
414 "glSecondaryColorPointerEXT",
José Fonseca99221832011-03-22 22:15:46 +0000415
José Fonseca7f5163e2011-03-31 23:37:26 +0100416 "glVertexAttribPointer",
417 "glVertexAttribPointerARB",
418 "glVertexAttribPointerNV",
José Fonsecaac5285b2011-05-04 11:09:08 +0100419 "glVertexAttribIPointer",
420 "glVertexAttribIPointerEXT",
José Fonseca7f5163e2011-03-31 23:37:26 +0100421 "glVertexAttribLPointer",
422 "glVertexAttribLPointerEXT",
José Fonseca99221832011-03-22 22:15:46 +0000423
424 #"glMatrixIndexPointerARB",
425 ))
426
427 draw_function_names = set((
428 'glDrawArrays',
429 'glDrawElements',
430 'glDrawRangeElements',
José Fonseca5c749e32011-05-09 11:11:37 +0100431 'glMultiDrawArrays',
432 'glMultiDrawElements',
433 'glDrawArraysInstanced',
José Fonsecaff8848b2011-10-09 01:04:17 +0100434 "glDrawArraysInstancedBaseInstance",
José Fonseca5c749e32011-05-09 11:11:37 +0100435 'glDrawElementsInstanced',
436 'glDrawArraysInstancedARB',
437 'glDrawElementsInstancedARB',
438 'glDrawElementsBaseVertex',
439 'glDrawRangeElementsBaseVertex',
440 'glDrawElementsInstancedBaseVertex',
José Fonsecaff8848b2011-10-09 01:04:17 +0100441 "glDrawElementsInstancedBaseInstance",
442 "glDrawElementsInstancedBaseVertexBaseInstance",
José Fonseca5c749e32011-05-09 11:11:37 +0100443 'glMultiDrawElementsBaseVertex',
444 'glDrawArraysIndirect',
445 'glDrawElementsIndirect',
446 'glDrawArraysEXT',
José Fonseca7e0bfd92011-04-30 23:09:03 +0100447 'glDrawRangeElementsEXT',
José Fonseca5c749e32011-05-09 11:11:37 +0100448 'glDrawRangeElementsEXT_size',
449 'glMultiDrawArraysEXT',
450 'glMultiDrawElementsEXT',
451 'glMultiModeDrawArraysIBM',
452 'glMultiModeDrawElementsIBM',
453 'glDrawArraysInstancedEXT',
454 'glDrawElementsInstancedEXT',
José Fonseca99221832011-03-22 22:15:46 +0000455 ))
456
José Fonsecac9f12232011-03-25 20:07:42 +0000457 interleaved_formats = [
458 'GL_V2F',
459 'GL_V3F',
460 'GL_C4UB_V2F',
461 'GL_C4UB_V3F',
462 'GL_C3F_V3F',
463 'GL_N3F_V3F',
464 'GL_C4F_N3F_V3F',
465 'GL_T2F_V3F',
466 'GL_T4F_V4F',
467 'GL_T2F_C4UB_V3F',
468 'GL_T2F_C3F_V3F',
469 'GL_T2F_N3F_V3F',
470 'GL_T2F_C4F_N3F_V3F',
471 'GL_T4F_C4F_N3F_V4F',
472 ]
473
José Fonseca54f304a2012-01-14 19:33:08 +0000474 def traceFunctionImplBody(self, function):
José Fonseca8a6c6cb2011-03-23 16:44:30 +0000475 # Defer tracing of user array pointers...
José Fonseca99221832011-03-22 22:15:46 +0000476 if function.name in self.array_pointer_function_names:
José Fonseca632a78d2012-04-19 07:18:59 +0100477 print ' GLint _array_buffer = 0;'
478 print ' _glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &_array_buffer);'
479 print ' if (!_array_buffer) {'
José Fonsecaf028a8f2012-02-15 23:33:35 +0000480 print ' gltrace::Context *ctx = gltrace::getContext();'
Chia-I Wu8ef66972011-11-03 01:19:46 +0800481 print ' ctx->user_arrays = true;'
José Fonseca5a568a92011-06-29 16:43:36 +0100482 if function.name == "glVertexAttribPointerARB":
Chia-I Wu8ef66972011-11-03 01:19:46 +0800483 print ' ctx->user_arrays_arb = true;'
José Fonseca5a568a92011-06-29 16:43:36 +0100484 if function.name == "glVertexAttribPointerNV":
Chia-I Wu8ef66972011-11-03 01:19:46 +0800485 print ' ctx->user_arrays_nv = true;'
José Fonseca54f304a2012-01-14 19:33:08 +0000486 self.invokeFunction(function)
José Fonsecaac5285b2011-05-04 11:09:08 +0100487
488 # And also break down glInterleavedArrays into the individual calls
489 if function.name == 'glInterleavedArrays':
490 print
491
492 # Initialize the enable flags
493 for camelcase_name, uppercase_name in self.arrays:
José Fonseca632a78d2012-04-19 07:18:59 +0100494 flag_name = '_' + uppercase_name.lower()
José Fonsecaac5285b2011-05-04 11:09:08 +0100495 print ' GLboolean %s = GL_FALSE;' % flag_name
496 print
497
498 # Switch for the interleaved formats
499 print ' switch (format) {'
500 for format in self.interleaved_formats:
501 print ' case %s:' % format
502 for camelcase_name, uppercase_name in self.arrays:
José Fonseca632a78d2012-04-19 07:18:59 +0100503 flag_name = '_' + uppercase_name.lower()
José Fonsecaac5285b2011-05-04 11:09:08 +0100504 if format.find('_' + uppercase_name[0]) >= 0:
505 print ' %s = GL_TRUE;' % flag_name
506 print ' break;'
507 print ' default:'
508 print ' return;'
509 print ' }'
510 print
511
512 # Emit fake glEnableClientState/glDisableClientState flags
513 for camelcase_name, uppercase_name in self.arrays:
José Fonseca632a78d2012-04-19 07:18:59 +0100514 flag_name = '_' + uppercase_name.lower()
José Fonsecaac5285b2011-05-04 11:09:08 +0100515 enable_name = 'GL_%s_ARRAY' % uppercase_name
516
517 # Emit a fake function
518 print ' {'
José Fonseca632a78d2012-04-19 07:18:59 +0100519 print ' static const trace::FunctionSig &_sig = %s ? _glEnableClientState_sig : _glDisableClientState_sig;' % flag_name
520 print ' unsigned _call = trace::localWriter.beginEnter(&_sig);'
José Fonsecab4a3d142011-10-27 07:43:19 +0100521 print ' trace::localWriter.beginArg(0);'
José Fonseca54f304a2012-01-14 19:33:08 +0000522 self.serializeValue(glapi.GLenum, enable_name)
José Fonsecab4a3d142011-10-27 07:43:19 +0100523 print ' trace::localWriter.endArg();'
524 print ' trace::localWriter.endEnter();'
José Fonseca632a78d2012-04-19 07:18:59 +0100525 print ' trace::localWriter.beginLeave(_call);'
José Fonsecab4a3d142011-10-27 07:43:19 +0100526 print ' trace::localWriter.endLeave();'
José Fonsecaac5285b2011-05-04 11:09:08 +0100527 print ' }'
528
José Fonseca99221832011-03-22 22:15:46 +0000529 print ' return;'
530 print ' }'
José Fonseca14c21bc2011-02-20 23:32:22 +0000531
José Fonseca8a6c6cb2011-03-23 16:44:30 +0000532 # ... to the draw calls
José Fonseca99221832011-03-22 22:15:46 +0000533 if function.name in self.draw_function_names:
José Fonseca632a78d2012-04-19 07:18:59 +0100534 print ' if (_need_user_arrays()) {'
José Fonseca99221832011-03-22 22:15:46 +0000535 arg_names = ', '.join([arg.name for arg in function.args[1:]])
José Fonseca14cb9ef2012-05-17 21:33:14 +0100536 print ' GLuint _count = _%s_count(%s);' % (function.name, arg_names)
537 print ' _trace_user_arrays(_count);'
José Fonseca8a6c6cb2011-03-23 16:44:30 +0000538 print ' }'
José Fonseca14c21bc2011-02-20 23:32:22 +0000539
José Fonseca73373602011-05-20 17:45:26 +0100540 # Emit a fake memcpy on buffer uploads
José Fonseca9c536b02012-02-29 20:54:13 +0000541 if function.name == 'glBufferParameteriAPPLE':
542 print ' if (pname == GL_BUFFER_FLUSHING_UNMAP_APPLE && param == GL_FALSE) {'
José Fonseca632a78d2012-04-19 07:18:59 +0100543 print ' _checkBufferFlushingUnmapAPPLE = true;'
José Fonseca9c536b02012-02-29 20:54:13 +0000544 print ' }'
José Fonsecacdc322c2012-02-29 19:29:51 +0000545 if function.name in ('glUnmapBuffer', 'glUnmapBufferARB'):
José Fonseca9c536b02012-02-29 20:54:13 +0000546 if function.name.endswith('ARB'):
547 suffix = 'ARB'
548 else:
549 suffix = ''
550 print ' GLint access = 0;'
José Fonseca632a78d2012-04-19 07:18:59 +0100551 print ' _glGetBufferParameteriv%s(target, GL_BUFFER_ACCESS, &access);' % suffix
José Fonseca9c536b02012-02-29 20:54:13 +0000552 print ' if (access != GL_READ_ONLY) {'
553 print ' GLvoid *map = NULL;'
José Fonseca632a78d2012-04-19 07:18:59 +0100554 print ' _glGetBufferPointerv%s(target, GL_BUFFER_MAP_POINTER, &map);' % suffix
José Fonseca9c536b02012-02-29 20:54:13 +0000555 print ' if (map) {'
556 print ' GLint length = -1;'
557 print ' bool flush = true;'
José Fonseca632a78d2012-04-19 07:18:59 +0100558 print ' if (_checkBufferMapRange) {'
559 print ' _glGetBufferParameteriv%s(target, GL_BUFFER_MAP_LENGTH, &length);' % suffix
José Fonseca9c536b02012-02-29 20:54:13 +0000560 print ' GLint access_flags = 0;'
José Fonseca632a78d2012-04-19 07:18:59 +0100561 print ' _glGetBufferParameteriv(target, GL_BUFFER_ACCESS_FLAGS, &access_flags);'
José Fonseca9c536b02012-02-29 20:54:13 +0000562 print ' flush = flush && !(access_flags & GL_MAP_FLUSH_EXPLICIT_BIT);'
563 print ' if (length == -1) {'
564 print ' // Mesa drivers refuse GL_BUFFER_MAP_LENGTH without GL 3.0'
José Fonsecadb1ccce2012-02-29 21:09:24 +0000565 print ' static bool warned = false;'
566 print ' if (!warned) {'
567 print ' os::log("apitrace: warning: glGetBufferParameteriv%s(GL_BUFFER_MAP_LENGTH) failed\\n");' % suffix
568 print ' warned = true;'
569 print ' }'
José Fonseca9c536b02012-02-29 20:54:13 +0000570 print ' struct buffer_mapping *mapping = get_buffer_mapping(target);'
571 print ' if (mapping) {'
572 print ' length = mapping->length;'
573 print ' flush = flush && !mapping->explicit_flush;'
574 print ' } else {'
575 print ' length = 0;'
576 print ' flush = false;'
577 print ' }'
578 print ' }'
579 print ' } else {'
580 print ' length = 0;'
José Fonseca632a78d2012-04-19 07:18:59 +0100581 print ' _glGetBufferParameteriv%s(target, GL_BUFFER_SIZE, &length);' % suffix
José Fonseca9c536b02012-02-29 20:54:13 +0000582 print ' }'
José Fonseca632a78d2012-04-19 07:18:59 +0100583 print ' if (_checkBufferFlushingUnmapAPPLE) {'
José Fonseca9c536b02012-02-29 20:54:13 +0000584 print ' GLint flushing_unmap = GL_TRUE;'
José Fonseca632a78d2012-04-19 07:18:59 +0100585 print ' _glGetBufferParameteriv%s(target, GL_BUFFER_FLUSHING_UNMAP_APPLE, &flushing_unmap);' % suffix
José Fonseca9c536b02012-02-29 20:54:13 +0000586 print ' flush = flush && flushing_unmap;'
587 print ' }'
588 print ' if (flush && length > 0) {'
589 self.emit_memcpy('map', 'map', 'length')
590 print ' }'
591 print ' }'
592 print ' }'
José Fonsecacdc322c2012-02-29 19:29:51 +0000593 if function.name == 'glUnmapBufferOES':
594 print ' GLint access = 0;'
José Fonseca632a78d2012-04-19 07:18:59 +0100595 print ' _glGetBufferParameteriv(target, GL_BUFFER_ACCESS_OES, &access);'
José Fonsecacdc322c2012-02-29 19:29:51 +0000596 print ' if (access == GL_WRITE_ONLY_OES) {'
597 print ' GLvoid *map = NULL;'
José Fonseca632a78d2012-04-19 07:18:59 +0100598 print ' _glGetBufferPointervOES(target, GL_BUFFER_MAP_POINTER_OES, &map);'
José Fonsecacdc322c2012-02-29 19:29:51 +0000599 print ' GLint size = 0;'
José Fonseca632a78d2012-04-19 07:18:59 +0100600 print ' _glGetBufferParameteriv(target, GL_BUFFER_SIZE, &size);'
José Fonsecacdc322c2012-02-29 19:29:51 +0000601 print ' if (map && size > 0) {'
602 self.emit_memcpy('map', 'map', 'size')
José Fonseca219c9f22012-11-03 10:13:17 +0000603 self.shadowBufferMethod('bufferSubData(0, size, map)')
José Fonsecacdc322c2012-02-29 19:29:51 +0000604 print ' }'
José Fonseca867b1b72011-04-24 11:58:04 +0100605 print ' }'
José Fonsecafb3bd602012-01-15 13:56:28 +0000606 if function.name == 'glUnmapNamedBufferEXT':
José Fonseca024aff42012-02-29 18:00:06 +0000607 print ' GLint access_flags = 0;'
José Fonseca632a78d2012-04-19 07:18:59 +0100608 print ' _glGetNamedBufferParameterivEXT(buffer, GL_BUFFER_ACCESS_FLAGS, &access_flags);'
José Fonseca024aff42012-02-29 18:00:06 +0000609 print ' if ((access_flags & GL_MAP_WRITE_BIT) && !(access_flags & GL_MAP_FLUSH_EXPLICIT_BIT)) {'
José Fonsecafb3bd602012-01-15 13:56:28 +0000610 print ' GLvoid *map = NULL;'
José Fonseca632a78d2012-04-19 07:18:59 +0100611 print ' _glGetNamedBufferPointervEXT(buffer, GL_BUFFER_MAP_POINTER, &map);'
José Fonsecafb3bd602012-01-15 13:56:28 +0000612 print ' GLint length = 0;'
José Fonseca632a78d2012-04-19 07:18:59 +0100613 print ' _glGetNamedBufferParameterivEXT(buffer, GL_BUFFER_MAP_LENGTH, &length);'
José Fonseca024aff42012-02-29 18:00:06 +0000614 print ' if (map && length > 0) {'
José Fonsecafb3bd602012-01-15 13:56:28 +0000615 self.emit_memcpy('map', 'map', 'length')
José Fonseca024aff42012-02-29 18:00:06 +0000616 print ' }'
José Fonsecafb3bd602012-01-15 13:56:28 +0000617 print ' }'
José Fonseca77ef0ce2012-02-29 18:08:48 +0000618 if function.name == 'glFlushMappedBufferRange':
619 print ' GLvoid *map = NULL;'
José Fonseca632a78d2012-04-19 07:18:59 +0100620 print ' _glGetBufferPointerv(target, GL_BUFFER_MAP_POINTER, &map);'
José Fonseca77ef0ce2012-02-29 18:08:48 +0000621 print ' if (map && length > 0) {'
622 self.emit_memcpy('(char *)map + offset', '(const char *)map + offset', 'length')
623 print ' }'
624 if function.name == 'glFlushMappedBufferRangeAPPLE':
625 print ' GLvoid *map = NULL;'
José Fonseca632a78d2012-04-19 07:18:59 +0100626 print ' _glGetBufferPointerv(target, GL_BUFFER_MAP_POINTER, &map);'
José Fonseca77ef0ce2012-02-29 18:08:48 +0000627 print ' if (map && size > 0) {'
628 self.emit_memcpy('(char *)map + offset', '(const char *)map + offset', 'size')
José Fonseca73373602011-05-20 17:45:26 +0100629 print ' }'
José Fonsecafb3bd602012-01-15 13:56:28 +0000630 if function.name == 'glFlushMappedNamedBufferRangeEXT':
631 print ' GLvoid *map = NULL;'
José Fonseca632a78d2012-04-19 07:18:59 +0100632 print ' _glGetNamedBufferPointervEXT(buffer, GL_BUFFER_MAP_POINTER, &map);'
José Fonseca024aff42012-02-29 18:00:06 +0000633 print ' if (map && length > 0) {'
José Fonsecafb3bd602012-01-15 13:56:28 +0000634 self.emit_memcpy('(char *)map + offset', '(const char *)map + offset', 'length')
635 print ' }'
José Fonseca867b1b72011-04-24 11:58:04 +0100636
José Fonseca91492d22011-05-23 21:20:31 +0100637 # Don't leave vertex attrib locations to chance. Instead emit fake
638 # glBindAttribLocation calls to ensure that the same locations will be
639 # used when retracing. Trying to remap locations after the fact would
640 # be an herculian task given that vertex attrib locations appear in
641 # many entry-points, including non-shader related ones.
642 if function.name == 'glLinkProgram':
José Fonseca54f304a2012-01-14 19:33:08 +0000643 Tracer.invokeFunction(self, function)
José Fonseca91492d22011-05-23 21:20:31 +0100644 print ' GLint active_attributes = 0;'
José Fonseca632a78d2012-04-19 07:18:59 +0100645 print ' _glGetProgramiv(program, GL_ACTIVE_ATTRIBUTES, &active_attributes);'
José Fonseca7525e6f2011-09-28 09:04:56 +0100646 print ' for (GLint attrib = 0; attrib < active_attributes; ++attrib) {'
José Fonseca91492d22011-05-23 21:20:31 +0100647 print ' GLint size = 0;'
648 print ' GLenum type = 0;'
649 print ' GLchar name[256];'
650 # TODO: Use ACTIVE_ATTRIBUTE_MAX_LENGTH instead of 256
José Fonseca632a78d2012-04-19 07:18:59 +0100651 print ' _glGetActiveAttrib(program, attrib, sizeof name, NULL, &size, &type, name);'
José Fonseca2a794f52011-05-26 20:54:29 +0100652 print " if (name[0] != 'g' || name[1] != 'l' || name[2] != '_') {"
José Fonseca632a78d2012-04-19 07:18:59 +0100653 print ' GLint location = _glGetAttribLocation(program, name);'
José Fonseca2a794f52011-05-26 20:54:29 +0100654 print ' if (location >= 0) {'
José Fonseca1b6c8752012-04-15 14:33:00 +0100655 bind_function = glapi.glapi.getFunctionByName('glBindAttribLocation')
José Fonseca91492d22011-05-23 21:20:31 +0100656 self.fake_call(bind_function, ['program', 'location', 'name'])
José Fonseca2a794f52011-05-26 20:54:29 +0100657 print ' }'
José Fonseca91492d22011-05-23 21:20:31 +0100658 print ' }'
659 print ' }'
660 if function.name == 'glLinkProgramARB':
José Fonseca54f304a2012-01-14 19:33:08 +0000661 Tracer.invokeFunction(self, function)
José Fonseca91492d22011-05-23 21:20:31 +0100662 print ' GLint active_attributes = 0;'
José Fonseca632a78d2012-04-19 07:18:59 +0100663 print ' _glGetObjectParameterivARB(programObj, GL_OBJECT_ACTIVE_ATTRIBUTES_ARB, &active_attributes);'
José Fonseca7525e6f2011-09-28 09:04:56 +0100664 print ' for (GLint attrib = 0; attrib < active_attributes; ++attrib) {'
José Fonseca91492d22011-05-23 21:20:31 +0100665 print ' GLint size = 0;'
666 print ' GLenum type = 0;'
667 print ' GLcharARB name[256];'
668 # TODO: Use ACTIVE_ATTRIBUTE_MAX_LENGTH instead of 256
José Fonseca632a78d2012-04-19 07:18:59 +0100669 print ' _glGetActiveAttribARB(programObj, attrib, sizeof name, NULL, &size, &type, name);'
José Fonseca2a794f52011-05-26 20:54:29 +0100670 print " if (name[0] != 'g' || name[1] != 'l' || name[2] != '_') {"
José Fonseca632a78d2012-04-19 07:18:59 +0100671 print ' GLint location = _glGetAttribLocationARB(programObj, name);'
José Fonseca2a794f52011-05-26 20:54:29 +0100672 print ' if (location >= 0) {'
José Fonseca1b6c8752012-04-15 14:33:00 +0100673 bind_function = glapi.glapi.getFunctionByName('glBindAttribLocationARB')
José Fonseca91492d22011-05-23 21:20:31 +0100674 self.fake_call(bind_function, ['programObj', 'location', 'name'])
José Fonseca2a794f52011-05-26 20:54:29 +0100675 print ' }'
José Fonseca91492d22011-05-23 21:20:31 +0100676 print ' }'
677 print ' }'
678
Imre Deakd4937372012-04-24 14:06:48 +0300679 self.shadowBufferProlog(function)
680
José Fonseca54f304a2012-01-14 19:33:08 +0000681 Tracer.traceFunctionImplBody(self, function)
José Fonseca73373602011-05-20 17:45:26 +0100682
José Fonsecaf028a8f2012-02-15 23:33:35 +0000683 marker_functions = [
684 # GL_GREMEDY_string_marker
José Fonseca8f34d342011-07-15 20:16:40 +0100685 'glStringMarkerGREMEDY',
José Fonsecaf028a8f2012-02-15 23:33:35 +0000686 # GL_GREMEDY_frame_terminator
José Fonseca8f34d342011-07-15 20:16:40 +0100687 'glFrameTerminatorGREMEDY',
José Fonsecaf028a8f2012-02-15 23:33:35 +0000688 # GL_EXT_debug_marker
689 'glInsertEventMarkerEXT',
690 'glPushGroupMarkerEXT',
691 'glPopGroupMarkerEXT',
José Fonseca8f34d342011-07-15 20:16:40 +0100692 ]
693
José Fonseca54f304a2012-01-14 19:33:08 +0000694 def invokeFunction(self, function):
José Fonseca91492d22011-05-23 21:20:31 +0100695 if function.name in ('glLinkProgram', 'glLinkProgramARB'):
696 # These functions have been dispatched already
697 return
698
José Fonsecaf028a8f2012-02-15 23:33:35 +0000699 # We implement GL_EXT_debug_marker, GL_GREMEDY_*, etc., and not the
700 # driver
701 if function.name in self.marker_functions:
José Fonseca8f34d342011-07-15 20:16:40 +0100702 return
703
704 if function.name in ('glXGetProcAddress', 'glXGetProcAddressARB', 'wglGetProcAddress'):
José Fonsecaf028a8f2012-02-15 23:33:35 +0000705 else_ = ''
706 for marker_function in self.marker_functions:
José Fonseca1b6c8752012-04-15 14:33:00 +0100707 if self.api.getFunctionByName(marker_function):
José Fonsecaf028a8f2012-02-15 23:33:35 +0000708 print ' %sif (strcmp("%s", (const char *)%s) == 0) {' % (else_, marker_function, function.args[0].name)
José Fonseca632a78d2012-04-19 07:18:59 +0100709 print ' _result = (%s)&%s;' % (function.type, marker_function)
José Fonsecaf028a8f2012-02-15 23:33:35 +0000710 print ' }'
711 else_ = 'else '
712 print ' %s{' % else_
José Fonseca54f304a2012-01-14 19:33:08 +0000713 Tracer.invokeFunction(self, function)
José Fonseca8f34d342011-07-15 20:16:40 +0100714 print ' }'
José Fonseca1b3d3752011-07-15 10:15:19 +0100715 return
716
José Fonsecaa08d2752011-08-25 13:26:43 +0100717 # Override GL extensions
718 if function.name in ('glGetString', 'glGetIntegerv', 'glGetStringi'):
José Fonseca632a78d2012-04-19 07:18:59 +0100719 Tracer.invokeFunction(self, function, prefix = 'gltrace::_', suffix = '_override')
José Fonsecaa08d2752011-08-25 13:26:43 +0100720 return
721
José Fonseca54f304a2012-01-14 19:33:08 +0000722 Tracer.invokeFunction(self, function)
José Fonseca91492d22011-05-23 21:20:31 +0100723
José Fonseca867b1b72011-04-24 11:58:04 +0100724 buffer_targets = [
725 'ARRAY_BUFFER',
726 'ELEMENT_ARRAY_BUFFER',
727 'PIXEL_PACK_BUFFER',
728 'PIXEL_UNPACK_BUFFER',
José Fonseca7b20d672012-01-10 19:13:58 +0000729 'UNIFORM_BUFFER',
730 'TEXTURE_BUFFER',
731 'TRANSFORM_FEEDBACK_BUFFER',
732 'COPY_READ_BUFFER',
733 'COPY_WRITE_BUFFER',
734 'DRAW_INDIRECT_BUFFER',
735 'ATOMIC_COUNTER_BUFFER',
José Fonseca867b1b72011-04-24 11:58:04 +0100736 ]
737
José Fonseca54f304a2012-01-14 19:33:08 +0000738 def wrapRet(self, function, instance):
739 Tracer.wrapRet(self, function, instance)
José Fonseca1b3d3752011-07-15 10:15:19 +0100740
José Fonseca1b6c8752012-04-15 14:33:00 +0100741 # Replace function addresses with ours
742 if function.name in self.getProcAddressFunctionNames:
743 print ' %s = _wrapProcAddress(%s, %s);' % (instance, function.args[0].name, instance)
744
José Fonsecacdc322c2012-02-29 19:29:51 +0000745 # Keep track of buffer mappings
746 if function.name in ('glMapBuffer', 'glMapBufferARB'):
José Fonseca867b1b72011-04-24 11:58:04 +0100747 print ' struct buffer_mapping *mapping = get_buffer_mapping(target);'
748 print ' if (mapping) {'
749 print ' mapping->map = %s;' % (instance)
750 print ' mapping->length = 0;'
José Fonseca632a78d2012-04-19 07:18:59 +0100751 print ' _glGetBufferParameteriv(target, GL_BUFFER_SIZE, &mapping->length);'
José Fonseca867b1b72011-04-24 11:58:04 +0100752 print ' mapping->write = (access != GL_READ_ONLY);'
José Fonseca73373602011-05-20 17:45:26 +0100753 print ' mapping->explicit_flush = false;'
José Fonseca867b1b72011-04-24 11:58:04 +0100754 print ' }'
José Fonseca867b1b72011-04-24 11:58:04 +0100755 if function.name == 'glMapBufferRange':
José Fonseca9c536b02012-02-29 20:54:13 +0000756 print ' if (access & GL_MAP_WRITE_BIT) {'
José Fonseca632a78d2012-04-19 07:18:59 +0100757 print ' _checkBufferMapRange = true;'
José Fonseca9c536b02012-02-29 20:54:13 +0000758 print ' }'
José Fonseca867b1b72011-04-24 11:58:04 +0100759 print ' struct buffer_mapping *mapping = get_buffer_mapping(target);'
760 print ' if (mapping) {'
761 print ' mapping->map = %s;' % (instance)
762 print ' mapping->length = length;'
763 print ' mapping->write = access & GL_MAP_WRITE_BIT;'
José Fonseca73373602011-05-20 17:45:26 +0100764 print ' mapping->explicit_flush = access & GL_MAP_FLUSH_EXPLICIT_BIT;'
José Fonseca867b1b72011-04-24 11:58:04 +0100765 print ' }'
José Fonseca669b1222011-02-20 09:05:10 +0000766
José Fonsecac9f12232011-03-25 20:07:42 +0000767 boolean_names = [
768 'GL_FALSE',
769 'GL_TRUE',
770 ]
771
772 def gl_boolean(self, value):
773 return self.boolean_names[int(bool(value))]
774
José Fonsecac29f4f12011-06-11 12:19:05 +0100775 # Names of the functions that unpack from a pixel buffer object. See the
776 # ARB_pixel_buffer_object specification.
José Fonsecae97bab92011-06-02 23:15:11 +0100777 unpack_function_names = set([
778 'glBitmap',
José Fonsecac29f4f12011-06-11 12:19:05 +0100779 'glColorSubTable',
780 'glColorTable',
José Fonsecad2bd4ca2013-04-12 11:41:00 +0100781 'glCompressedMultiTexImage1DEXT',
782 'glCompressedMultiTexImage2DEXT',
783 'glCompressedMultiTexImage3DEXT',
784 'glCompressedMultiTexSubImage1DEXT',
785 'glCompressedMultiTexSubImage2DEXT',
786 'glCompressedMultiTexSubImage3DEXT',
José Fonsecac29f4f12011-06-11 12:19:05 +0100787 'glCompressedTexImage1D',
788 'glCompressedTexImage2D',
789 'glCompressedTexImage3D',
790 'glCompressedTexSubImage1D',
791 'glCompressedTexSubImage2D',
792 'glCompressedTexSubImage3D',
José Fonsecad2bd4ca2013-04-12 11:41:00 +0100793 'glCompressedTextureImage1DEXT',
794 'glCompressedTextureImage2DEXT',
795 'glCompressedTextureImage3DEXT',
796 'glCompressedTextureSubImage1DEXT',
797 'glCompressedTextureSubImage2DEXT',
798 'glCompressedTextureSubImage3DEXT',
José Fonsecac29f4f12011-06-11 12:19:05 +0100799 'glConvolutionFilter1D',
800 'glConvolutionFilter2D',
José Fonsecae97bab92011-06-02 23:15:11 +0100801 'glDrawPixels',
802 'glMultiTexImage1DEXT',
803 'glMultiTexImage2DEXT',
804 'glMultiTexImage3DEXT',
805 'glMultiTexSubImage1DEXT',
806 'glMultiTexSubImage2DEXT',
807 'glMultiTexSubImage3DEXT',
José Fonsecac29f4f12011-06-11 12:19:05 +0100808 'glPixelMapfv',
809 'glPixelMapuiv',
810 'glPixelMapusv',
José Fonsecae97bab92011-06-02 23:15:11 +0100811 'glPolygonStipple',
José Fonsecac29f4f12011-06-11 12:19:05 +0100812 'glSeparableFilter2D',
José Fonsecae97bab92011-06-02 23:15:11 +0100813 'glTexImage1D',
814 'glTexImage1DEXT',
815 'glTexImage2D',
816 'glTexImage2DEXT',
817 'glTexImage3D',
818 'glTexImage3DEXT',
819 'glTexSubImage1D',
820 'glTexSubImage1DEXT',
821 'glTexSubImage2D',
822 'glTexSubImage2DEXT',
823 'glTexSubImage3D',
824 'glTexSubImage3DEXT',
825 'glTextureImage1DEXT',
826 'glTextureImage2DEXT',
827 'glTextureImage3DEXT',
828 'glTextureSubImage1DEXT',
829 'glTextureSubImage2DEXT',
830 'glTextureSubImage3DEXT',
831 ])
832
José Fonseca54f304a2012-01-14 19:33:08 +0000833 def serializeArgValue(self, function, arg):
José Fonsecae97bab92011-06-02 23:15:11 +0100834 # Recognize offsets instead of blobs when a PBO is bound
835 if function.name in self.unpack_function_names \
836 and (isinstance(arg.type, stdapi.Blob) \
837 or (isinstance(arg.type, stdapi.Const) \
838 and isinstance(arg.type.type, stdapi.Blob))):
José Fonsecac29f4f12011-06-11 12:19:05 +0100839 print ' {'
José Fonsecaf028a8f2012-02-15 23:33:35 +0000840 print ' gltrace::Context *ctx = gltrace::getContext();'
José Fonseca632a78d2012-04-19 07:18:59 +0100841 print ' GLint _unpack_buffer = 0;'
José Fonsecaf028a8f2012-02-15 23:33:35 +0000842 print ' if (ctx->profile == gltrace::PROFILE_COMPAT)'
José Fonseca632a78d2012-04-19 07:18:59 +0100843 print ' _glGetIntegerv(GL_PIXEL_UNPACK_BUFFER_BINDING, &_unpack_buffer);'
844 print ' if (_unpack_buffer) {'
José Fonsecad559f022012-04-15 16:13:51 +0100845 print ' trace::localWriter.writePointer((uintptr_t)%s);' % arg.name
José Fonsecac29f4f12011-06-11 12:19:05 +0100846 print ' } else {'
José Fonseca54f304a2012-01-14 19:33:08 +0000847 Tracer.serializeArgValue(self, function, arg)
José Fonsecac29f4f12011-06-11 12:19:05 +0100848 print ' }'
José Fonsecae97bab92011-06-02 23:15:11 +0100849 print ' }'
850 return
851
José Fonsecaa3f89ae2011-04-26 08:50:32 +0100852 # Several GL state functions take GLenum symbolic names as
853 # integer/floats; so dump the symbolic name whenever possible
José Fonseca3bcb33c2011-05-27 20:14:31 +0100854 if function.name.startswith('gl') \
José Fonsecae3571092011-10-13 08:26:27 +0100855 and arg.type in (glapi.GLint, glapi.GLfloat, glapi.GLdouble) \
José Fonseca3bcb33c2011-05-27 20:14:31 +0100856 and arg.name == 'param':
José Fonsecaa3f89ae2011-04-26 08:50:32 +0100857 assert arg.index > 0
858 assert function.args[arg.index - 1].name == 'pname'
859 assert function.args[arg.index - 1].type == glapi.GLenum
860 print ' if (is_symbolic_pname(pname) && is_symbolic_param(%s)) {' % arg.name
José Fonseca54f304a2012-01-14 19:33:08 +0000861 self.serializeValue(glapi.GLenum, arg.name)
José Fonsecaa3f89ae2011-04-26 08:50:32 +0100862 print ' } else {'
José Fonseca54f304a2012-01-14 19:33:08 +0000863 Tracer.serializeArgValue(self, function, arg)
José Fonsecaa3f89ae2011-04-26 08:50:32 +0100864 print ' }'
865 return
866
José Fonseca54f304a2012-01-14 19:33:08 +0000867 Tracer.serializeArgValue(self, function, arg)
José Fonseca99221832011-03-22 22:15:46 +0000868
José Fonseca4c938c22011-04-30 22:44:38 +0100869 def footer(self, api):
870 Tracer.footer(self, api)
José Fonseca669b1222011-02-20 09:05:10 +0000871
José Fonseca4c938c22011-04-30 22:44:38 +0100872 # A simple state tracker to track the pointer values
José Fonseca669b1222011-02-20 09:05:10 +0000873 # update the state
José Fonseca14cb9ef2012-05-17 21:33:14 +0100874 print 'static void _trace_user_arrays(GLuint count)'
José Fonseca669b1222011-02-20 09:05:10 +0000875 print '{'
José Fonsecaf028a8f2012-02-15 23:33:35 +0000876 print ' gltrace::Context *ctx = gltrace::getContext();'
José Fonseca1a2fdd22011-04-01 00:55:09 +0100877
José Fonseca99221832011-03-22 22:15:46 +0000878 for camelcase_name, uppercase_name in self.arrays:
Chia-I Wub3d218d2011-11-03 01:37:36 +0800879 # in which profile is the array available?
José Fonsecaf028a8f2012-02-15 23:33:35 +0000880 profile_check = 'ctx->profile == gltrace::PROFILE_COMPAT'
Chia-I Wub3d218d2011-11-03 01:37:36 +0800881 if camelcase_name in self.arrays_es1:
José Fonsecaf028a8f2012-02-15 23:33:35 +0000882 profile_check = '(' + profile_check + ' || ctx->profile == gltrace::PROFILE_ES1)';
Chia-I Wub3d218d2011-11-03 01:37:36 +0800883
José Fonseca99221832011-03-22 22:15:46 +0000884 function_name = 'gl%sPointer' % camelcase_name
885 enable_name = 'GL_%s_ARRAY' % uppercase_name
886 binding_name = 'GL_%s_ARRAY_BUFFER_BINDING' % uppercase_name
José Fonseca1b6c8752012-04-15 14:33:00 +0100887 function = api.getFunctionByName(function_name)
José Fonseca99221832011-03-22 22:15:46 +0000888
José Fonseca06e85192011-10-16 14:15:36 +0100889 print ' // %s' % function.prototype()
Chia-I Wub3d218d2011-11-03 01:37:36 +0800890 print ' if (%s) {' % profile_check
José Fonsecafb6744f2011-04-15 11:18:37 +0100891 self.array_trace_prolog(api, uppercase_name)
892 self.array_prolog(api, uppercase_name)
José Fonseca632a78d2012-04-19 07:18:59 +0100893 print ' if (_glIsEnabled(%s)) {' % enable_name
894 print ' GLint _binding = 0;'
895 print ' _glGetIntegerv(%s, &_binding);' % binding_name
896 print ' if (!_binding) {'
José Fonseca99221832011-03-22 22:15:46 +0000897
898 # Get the arguments via glGet*
899 for arg in function.args:
900 arg_get_enum = 'GL_%s_ARRAY_%s' % (uppercase_name, arg.name.upper())
901 arg_get_function, arg_type = TypeGetter().visit(arg.type)
José Fonseca7f5163e2011-03-31 23:37:26 +0100902 print ' %s %s = 0;' % (arg_type, arg.name)
José Fonseca632a78d2012-04-19 07:18:59 +0100903 print ' _%s(%s, &%s);' % (arg_get_function, arg_get_enum, arg.name)
José Fonseca99221832011-03-22 22:15:46 +0000904
905 arg_names = ', '.join([arg.name for arg in function.args[:-1]])
José Fonseca14cb9ef2012-05-17 21:33:14 +0100906 print ' size_t _size = _%s_size(%s, count);' % (function.name, arg_names)
José Fonseca99221832011-03-22 22:15:46 +0000907
908 # Emit a fake function
José Fonsecafb6744f2011-04-15 11:18:37 +0100909 self.array_trace_intermezzo(api, uppercase_name)
José Fonseca632a78d2012-04-19 07:18:59 +0100910 print ' unsigned _call = trace::localWriter.beginEnter(&_%s_sig);' % (function.name,)
José Fonseca669b1222011-02-20 09:05:10 +0000911 for arg in function.args:
912 assert not arg.output
José Fonsecab4a3d142011-10-27 07:43:19 +0100913 print ' trace::localWriter.beginArg(%u);' % (arg.index,)
José Fonseca14c21bc2011-02-20 23:32:22 +0000914 if arg.name != 'pointer':
José Fonseca54f304a2012-01-14 19:33:08 +0000915 self.serializeValue(arg.type, arg.name)
José Fonseca14c21bc2011-02-20 23:32:22 +0000916 else:
José Fonseca632a78d2012-04-19 07:18:59 +0100917 print ' trace::localWriter.writeBlob((const void *)%s, _size);' % (arg.name)
José Fonsecab4a3d142011-10-27 07:43:19 +0100918 print ' trace::localWriter.endArg();'
José Fonseca99221832011-03-22 22:15:46 +0000919
José Fonsecab4a3d142011-10-27 07:43:19 +0100920 print ' trace::localWriter.endEnter();'
José Fonseca632a78d2012-04-19 07:18:59 +0100921 print ' trace::localWriter.beginLeave(_call);'
José Fonsecab4a3d142011-10-27 07:43:19 +0100922 print ' trace::localWriter.endLeave();'
José Fonseca99221832011-03-22 22:15:46 +0000923 print ' }'
José Fonseca669b1222011-02-20 09:05:10 +0000924 print ' }'
José Fonsecafb6744f2011-04-15 11:18:37 +0100925 self.array_epilog(api, uppercase_name)
926 self.array_trace_epilog(api, uppercase_name)
Chia-I Wub3d218d2011-11-03 01:37:36 +0800927 print ' }'
José Fonseca99221832011-03-22 22:15:46 +0000928 print
José Fonseca1a2fdd22011-04-01 00:55:09 +0100929
José Fonseca1601c412011-05-10 10:38:19 +0100930 # Samething, but for glVertexAttribPointer*
931 #
932 # Some variants of glVertexAttribPointer alias conventional and generic attributes:
933 # - glVertexAttribPointer: no
934 # - glVertexAttribPointerARB: implementation dependent
935 # - glVertexAttribPointerNV: yes
936 #
937 # This means that the implementations of these functions do not always
938 # alias, and they need to be considered independently.
939 #
Chia-I Wub3d218d2011-11-03 01:37:36 +0800940 print ' // ES1 does not support generic vertex attributes'
José Fonsecaf028a8f2012-02-15 23:33:35 +0000941 print ' if (ctx->profile == gltrace::PROFILE_ES1)'
Chia-I Wub3d218d2011-11-03 01:37:36 +0800942 print ' return;'
943 print
José Fonseca632a78d2012-04-19 07:18:59 +0100944 print ' vertex_attrib _vertex_attrib = _get_vertex_attrib();'
José Fonseca5a568a92011-06-29 16:43:36 +0100945 print
946 for suffix in ['', 'ARB', 'NV']:
947 if suffix:
José Fonsecad94aaac2011-06-28 20:50:49 +0100948 SUFFIX = '_' + suffix
José Fonsecad94aaac2011-06-28 20:50:49 +0100949 else:
José Fonseca5a568a92011-06-29 16:43:36 +0100950 SUFFIX = suffix
José Fonseca1601c412011-05-10 10:38:19 +0100951 function_name = 'glVertexAttribPointer' + suffix
José Fonseca1b6c8752012-04-15 14:33:00 +0100952 function = api.getFunctionByName(function_name)
José Fonseca06e85192011-10-16 14:15:36 +0100953
954 print ' // %s' % function.prototype()
José Fonseca632a78d2012-04-19 07:18:59 +0100955 print ' if (_vertex_attrib == VERTEX_ATTRIB%s) {' % SUFFIX
José Fonseca5a568a92011-06-29 16:43:36 +0100956 if suffix == 'NV':
José Fonseca632a78d2012-04-19 07:18:59 +0100957 print ' GLint _max_vertex_attribs = 16;'
José Fonseca5a568a92011-06-29 16:43:36 +0100958 else:
José Fonseca632a78d2012-04-19 07:18:59 +0100959 print ' GLint _max_vertex_attribs = 0;'
960 print ' _glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &_max_vertex_attribs);'
961 print ' for (GLint index = 0; index < _max_vertex_attribs; ++index) {'
962 print ' GLint _enabled = 0;'
José Fonseca5a568a92011-06-29 16:43:36 +0100963 if suffix == 'NV':
José Fonseca632a78d2012-04-19 07:18:59 +0100964 print ' _glGetIntegerv(GL_VERTEX_ATTRIB_ARRAY0_NV + index, &_enabled);'
José Fonseca5a568a92011-06-29 16:43:36 +0100965 else:
José Fonseca632a78d2012-04-19 07:18:59 +0100966 print ' _glGetVertexAttribiv%s(index, GL_VERTEX_ATTRIB_ARRAY_ENABLED%s, &_enabled);' % (suffix, SUFFIX)
967 print ' if (_enabled) {'
968 print ' GLint _binding = 0;'
José Fonseca5a568a92011-06-29 16:43:36 +0100969 if suffix != 'NV':
970 # It doesn't seem possible to use VBOs with NV_vertex_program.
José Fonseca632a78d2012-04-19 07:18:59 +0100971 print ' _glGetVertexAttribiv%s(index, GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING%s, &_binding);' % (suffix, SUFFIX)
972 print ' if (!_binding) {'
José Fonseca1a2fdd22011-04-01 00:55:09 +0100973
José Fonseca1601c412011-05-10 10:38:19 +0100974 # Get the arguments via glGet*
975 for arg in function.args[1:]:
José Fonseca5a568a92011-06-29 16:43:36 +0100976 if suffix == 'NV':
977 arg_get_enum = 'GL_ATTRIB_ARRAY_%s%s' % (arg.name.upper(), SUFFIX)
978 else:
979 arg_get_enum = 'GL_VERTEX_ATTRIB_ARRAY_%s%s' % (arg.name.upper(), SUFFIX)
José Fonsecac493e3e2011-06-29 12:57:06 +0100980 arg_get_function, arg_type = TypeGetter('glGetVertexAttrib', False, suffix).visit(arg.type)
José Fonseca5a568a92011-06-29 16:43:36 +0100981 print ' %s %s = 0;' % (arg_type, arg.name)
José Fonseca632a78d2012-04-19 07:18:59 +0100982 print ' _%s(index, %s, &%s);' % (arg_get_function, arg_get_enum, arg.name)
José Fonseca1601c412011-05-10 10:38:19 +0100983
984 arg_names = ', '.join([arg.name for arg in function.args[1:-1]])
José Fonseca14cb9ef2012-05-17 21:33:14 +0100985 print ' size_t _size = _%s_size(%s, count);' % (function.name, arg_names)
José Fonseca1a2fdd22011-04-01 00:55:09 +0100986
José Fonseca1601c412011-05-10 10:38:19 +0100987 # Emit a fake function
José Fonseca632a78d2012-04-19 07:18:59 +0100988 print ' unsigned _call = trace::localWriter.beginEnter(&_%s_sig);' % (function.name,)
José Fonseca1601c412011-05-10 10:38:19 +0100989 for arg in function.args:
990 assert not arg.output
José Fonsecab4a3d142011-10-27 07:43:19 +0100991 print ' trace::localWriter.beginArg(%u);' % (arg.index,)
José Fonseca1601c412011-05-10 10:38:19 +0100992 if arg.name != 'pointer':
José Fonseca54f304a2012-01-14 19:33:08 +0000993 self.serializeValue(arg.type, arg.name)
José Fonseca1601c412011-05-10 10:38:19 +0100994 else:
José Fonseca632a78d2012-04-19 07:18:59 +0100995 print ' trace::localWriter.writeBlob((const void *)%s, _size);' % (arg.name)
José Fonsecab4a3d142011-10-27 07:43:19 +0100996 print ' trace::localWriter.endArg();'
José Fonseca1601c412011-05-10 10:38:19 +0100997
José Fonsecab4a3d142011-10-27 07:43:19 +0100998 print ' trace::localWriter.endEnter();'
José Fonseca632a78d2012-04-19 07:18:59 +0100999 print ' trace::localWriter.beginLeave(_call);'
José Fonsecab4a3d142011-10-27 07:43:19 +01001000 print ' trace::localWriter.endLeave();'
José Fonseca1601c412011-05-10 10:38:19 +01001001 print ' }'
1002 print ' }'
1003 print ' }'
1004 print ' }'
1005 print
José Fonseca1a2fdd22011-04-01 00:55:09 +01001006
José Fonseca669b1222011-02-20 09:05:10 +00001007 print '}'
1008 print
1009
José Fonsecafb6744f2011-04-15 11:18:37 +01001010 #
1011 # Hooks for glTexCoordPointer, which is identical to the other array
1012 # pointers except the fact that it is indexed by glClientActiveTexture.
1013 #
1014
1015 def array_prolog(self, api, uppercase_name):
1016 if uppercase_name == 'TEXTURE_COORD':
1017 print ' GLint client_active_texture = 0;'
José Fonseca632a78d2012-04-19 07:18:59 +01001018 print ' _glGetIntegerv(GL_CLIENT_ACTIVE_TEXTURE, &client_active_texture);'
José Fonsecafb6744f2011-04-15 11:18:37 +01001019 print ' GLint max_texture_coords = 0;'
José Fonsecaf028a8f2012-02-15 23:33:35 +00001020 print ' if (ctx->profile == gltrace::PROFILE_COMPAT)'
José Fonseca632a78d2012-04-19 07:18:59 +01001021 print ' _glGetIntegerv(GL_MAX_TEXTURE_COORDS, &max_texture_coords);'
Chia-I Wub3d218d2011-11-03 01:37:36 +08001022 print ' else'
José Fonseca632a78d2012-04-19 07:18:59 +01001023 print ' _glGetIntegerv(GL_MAX_TEXTURE_UNITS, &max_texture_coords);'
José Fonsecafb6744f2011-04-15 11:18:37 +01001024 print ' for (GLint unit = 0; unit < max_texture_coords; ++unit) {'
José Fonseca7525e6f2011-09-28 09:04:56 +01001025 print ' GLint texture = GL_TEXTURE0 + unit;'
José Fonseca632a78d2012-04-19 07:18:59 +01001026 print ' _glClientActiveTexture(texture);'
José Fonsecafb6744f2011-04-15 11:18:37 +01001027
1028 def array_trace_prolog(self, api, uppercase_name):
1029 if uppercase_name == 'TEXTURE_COORD':
1030 print ' bool client_active_texture_dirty = false;'
1031
1032 def array_epilog(self, api, uppercase_name):
1033 if uppercase_name == 'TEXTURE_COORD':
1034 print ' }'
1035 self.array_cleanup(api, uppercase_name)
1036
1037 def array_cleanup(self, api, uppercase_name):
1038 if uppercase_name == 'TEXTURE_COORD':
José Fonseca632a78d2012-04-19 07:18:59 +01001039 print ' _glClientActiveTexture(client_active_texture);'
José Fonsecafb6744f2011-04-15 11:18:37 +01001040
1041 def array_trace_intermezzo(self, api, uppercase_name):
1042 if uppercase_name == 'TEXTURE_COORD':
1043 print ' if (texture != client_active_texture || client_active_texture_dirty) {'
1044 print ' client_active_texture_dirty = true;'
1045 self.fake_glClientActiveTexture_call(api, "texture");
1046 print ' }'
1047
1048 def array_trace_epilog(self, api, uppercase_name):
1049 if uppercase_name == 'TEXTURE_COORD':
1050 print ' if (client_active_texture_dirty) {'
1051 self.fake_glClientActiveTexture_call(api, "client_active_texture");
1052 print ' }'
1053
1054 def fake_glClientActiveTexture_call(self, api, texture):
José Fonseca1b6c8752012-04-15 14:33:00 +01001055 function = api.getFunctionByName('glClientActiveTexture')
José Fonsecafb6744f2011-04-15 11:18:37 +01001056 self.fake_call(function, [texture])
1057
José Fonsecafb6744f2011-04-15 11:18:37 +01001058
1059
1060
1061
1062
José Fonseca669b1222011-02-20 09:05:10 +00001063
1064
1065
1066
1067
1068