blob: e9169ce8501d86b39ad5baff880de5e8eb806698 [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;'
Mike Stroyan5a67d492013-05-06 13:14:22 -0600360 print ' _glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &buffer_binding);'
José Fonseca219c9f22012-11-03 10:13:17 +0000361 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',
José Fonseca29ac7c72013-04-14 15:40:01 +0100446 'glMultiDrawArraysIndirect',
447 'glMultiDrawArraysIndirectAMD',
448 'glMultiDrawElementsIndirect',
449 'glMultiDrawElementsIndirectAMD',
José Fonseca5c749e32011-05-09 11:11:37 +0100450 'glDrawArraysEXT',
José Fonseca7e0bfd92011-04-30 23:09:03 +0100451 'glDrawRangeElementsEXT',
José Fonseca5c749e32011-05-09 11:11:37 +0100452 'glDrawRangeElementsEXT_size',
453 'glMultiDrawArraysEXT',
454 'glMultiDrawElementsEXT',
455 'glMultiModeDrawArraysIBM',
456 'glMultiModeDrawElementsIBM',
457 'glDrawArraysInstancedEXT',
458 'glDrawElementsInstancedEXT',
José Fonseca99221832011-03-22 22:15:46 +0000459 ))
460
José Fonsecac9f12232011-03-25 20:07:42 +0000461 interleaved_formats = [
462 'GL_V2F',
463 'GL_V3F',
464 'GL_C4UB_V2F',
465 'GL_C4UB_V3F',
466 'GL_C3F_V3F',
467 'GL_N3F_V3F',
468 'GL_C4F_N3F_V3F',
469 'GL_T2F_V3F',
470 'GL_T4F_V4F',
471 'GL_T2F_C4UB_V3F',
472 'GL_T2F_C3F_V3F',
473 'GL_T2F_N3F_V3F',
474 'GL_T2F_C4F_N3F_V3F',
475 'GL_T4F_C4F_N3F_V4F',
476 ]
477
José Fonseca54f304a2012-01-14 19:33:08 +0000478 def traceFunctionImplBody(self, function):
José Fonseca8a6c6cb2011-03-23 16:44:30 +0000479 # Defer tracing of user array pointers...
José Fonseca99221832011-03-22 22:15:46 +0000480 if function.name in self.array_pointer_function_names:
José Fonseca632a78d2012-04-19 07:18:59 +0100481 print ' GLint _array_buffer = 0;'
482 print ' _glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &_array_buffer);'
483 print ' if (!_array_buffer) {'
José Fonsecaf028a8f2012-02-15 23:33:35 +0000484 print ' gltrace::Context *ctx = gltrace::getContext();'
Chia-I Wu8ef66972011-11-03 01:19:46 +0800485 print ' ctx->user_arrays = true;'
José Fonseca5a568a92011-06-29 16:43:36 +0100486 if function.name == "glVertexAttribPointerARB":
Chia-I Wu8ef66972011-11-03 01:19:46 +0800487 print ' ctx->user_arrays_arb = true;'
José Fonseca5a568a92011-06-29 16:43:36 +0100488 if function.name == "glVertexAttribPointerNV":
Chia-I Wu8ef66972011-11-03 01:19:46 +0800489 print ' ctx->user_arrays_nv = true;'
José Fonseca54f304a2012-01-14 19:33:08 +0000490 self.invokeFunction(function)
José Fonsecaac5285b2011-05-04 11:09:08 +0100491
492 # And also break down glInterleavedArrays into the individual calls
493 if function.name == 'glInterleavedArrays':
494 print
495
496 # Initialize the enable flags
497 for camelcase_name, uppercase_name in self.arrays:
José Fonseca632a78d2012-04-19 07:18:59 +0100498 flag_name = '_' + uppercase_name.lower()
José Fonsecaac5285b2011-05-04 11:09:08 +0100499 print ' GLboolean %s = GL_FALSE;' % flag_name
500 print
501
502 # Switch for the interleaved formats
503 print ' switch (format) {'
504 for format in self.interleaved_formats:
505 print ' case %s:' % format
506 for camelcase_name, uppercase_name in self.arrays:
José Fonseca632a78d2012-04-19 07:18:59 +0100507 flag_name = '_' + uppercase_name.lower()
José Fonsecaac5285b2011-05-04 11:09:08 +0100508 if format.find('_' + uppercase_name[0]) >= 0:
509 print ' %s = GL_TRUE;' % flag_name
510 print ' break;'
511 print ' default:'
512 print ' return;'
513 print ' }'
514 print
515
516 # Emit fake glEnableClientState/glDisableClientState flags
517 for camelcase_name, uppercase_name in self.arrays:
José Fonseca632a78d2012-04-19 07:18:59 +0100518 flag_name = '_' + uppercase_name.lower()
José Fonsecaac5285b2011-05-04 11:09:08 +0100519 enable_name = 'GL_%s_ARRAY' % uppercase_name
520
521 # Emit a fake function
522 print ' {'
José Fonseca632a78d2012-04-19 07:18:59 +0100523 print ' static const trace::FunctionSig &_sig = %s ? _glEnableClientState_sig : _glDisableClientState_sig;' % flag_name
524 print ' unsigned _call = trace::localWriter.beginEnter(&_sig);'
José Fonsecab4a3d142011-10-27 07:43:19 +0100525 print ' trace::localWriter.beginArg(0);'
José Fonseca54f304a2012-01-14 19:33:08 +0000526 self.serializeValue(glapi.GLenum, enable_name)
José Fonsecab4a3d142011-10-27 07:43:19 +0100527 print ' trace::localWriter.endArg();'
528 print ' trace::localWriter.endEnter();'
José Fonseca632a78d2012-04-19 07:18:59 +0100529 print ' trace::localWriter.beginLeave(_call);'
José Fonsecab4a3d142011-10-27 07:43:19 +0100530 print ' trace::localWriter.endLeave();'
José Fonsecaac5285b2011-05-04 11:09:08 +0100531 print ' }'
532
José Fonseca99221832011-03-22 22:15:46 +0000533 print ' return;'
534 print ' }'
José Fonseca14c21bc2011-02-20 23:32:22 +0000535
José Fonseca8a6c6cb2011-03-23 16:44:30 +0000536 # ... to the draw calls
José Fonseca99221832011-03-22 22:15:46 +0000537 if function.name in self.draw_function_names:
José Fonseca632a78d2012-04-19 07:18:59 +0100538 print ' if (_need_user_arrays()) {'
José Fonseca99221832011-03-22 22:15:46 +0000539 arg_names = ', '.join([arg.name for arg in function.args[1:]])
José Fonseca14cb9ef2012-05-17 21:33:14 +0100540 print ' GLuint _count = _%s_count(%s);' % (function.name, arg_names)
541 print ' _trace_user_arrays(_count);'
José Fonseca8a6c6cb2011-03-23 16:44:30 +0000542 print ' }'
José Fonseca14c21bc2011-02-20 23:32:22 +0000543
José Fonseca73373602011-05-20 17:45:26 +0100544 # Emit a fake memcpy on buffer uploads
José Fonseca9c536b02012-02-29 20:54:13 +0000545 if function.name == 'glBufferParameteriAPPLE':
546 print ' if (pname == GL_BUFFER_FLUSHING_UNMAP_APPLE && param == GL_FALSE) {'
José Fonseca632a78d2012-04-19 07:18:59 +0100547 print ' _checkBufferFlushingUnmapAPPLE = true;'
José Fonseca9c536b02012-02-29 20:54:13 +0000548 print ' }'
José Fonsecacdc322c2012-02-29 19:29:51 +0000549 if function.name in ('glUnmapBuffer', 'glUnmapBufferARB'):
José Fonseca9c536b02012-02-29 20:54:13 +0000550 if function.name.endswith('ARB'):
551 suffix = 'ARB'
552 else:
553 suffix = ''
554 print ' GLint access = 0;'
José Fonseca632a78d2012-04-19 07:18:59 +0100555 print ' _glGetBufferParameteriv%s(target, GL_BUFFER_ACCESS, &access);' % suffix
José Fonseca9c536b02012-02-29 20:54:13 +0000556 print ' if (access != GL_READ_ONLY) {'
557 print ' GLvoid *map = NULL;'
José Fonseca632a78d2012-04-19 07:18:59 +0100558 print ' _glGetBufferPointerv%s(target, GL_BUFFER_MAP_POINTER, &map);' % suffix
José Fonseca9c536b02012-02-29 20:54:13 +0000559 print ' if (map) {'
560 print ' GLint length = -1;'
561 print ' bool flush = true;'
José Fonseca632a78d2012-04-19 07:18:59 +0100562 print ' if (_checkBufferMapRange) {'
563 print ' _glGetBufferParameteriv%s(target, GL_BUFFER_MAP_LENGTH, &length);' % suffix
José Fonseca9c536b02012-02-29 20:54:13 +0000564 print ' GLint access_flags = 0;'
José Fonseca632a78d2012-04-19 07:18:59 +0100565 print ' _glGetBufferParameteriv(target, GL_BUFFER_ACCESS_FLAGS, &access_flags);'
José Fonseca9c536b02012-02-29 20:54:13 +0000566 print ' flush = flush && !(access_flags & GL_MAP_FLUSH_EXPLICIT_BIT);'
567 print ' if (length == -1) {'
568 print ' // Mesa drivers refuse GL_BUFFER_MAP_LENGTH without GL 3.0'
José Fonsecadb1ccce2012-02-29 21:09:24 +0000569 print ' static bool warned = false;'
570 print ' if (!warned) {'
571 print ' os::log("apitrace: warning: glGetBufferParameteriv%s(GL_BUFFER_MAP_LENGTH) failed\\n");' % suffix
572 print ' warned = true;'
573 print ' }'
José Fonseca9c536b02012-02-29 20:54:13 +0000574 print ' struct buffer_mapping *mapping = get_buffer_mapping(target);'
575 print ' if (mapping) {'
576 print ' length = mapping->length;'
577 print ' flush = flush && !mapping->explicit_flush;'
578 print ' } else {'
579 print ' length = 0;'
580 print ' flush = false;'
581 print ' }'
582 print ' }'
583 print ' } else {'
584 print ' length = 0;'
José Fonseca632a78d2012-04-19 07:18:59 +0100585 print ' _glGetBufferParameteriv%s(target, GL_BUFFER_SIZE, &length);' % suffix
José Fonseca9c536b02012-02-29 20:54:13 +0000586 print ' }'
José Fonseca632a78d2012-04-19 07:18:59 +0100587 print ' if (_checkBufferFlushingUnmapAPPLE) {'
José Fonseca9c536b02012-02-29 20:54:13 +0000588 print ' GLint flushing_unmap = GL_TRUE;'
José Fonseca632a78d2012-04-19 07:18:59 +0100589 print ' _glGetBufferParameteriv%s(target, GL_BUFFER_FLUSHING_UNMAP_APPLE, &flushing_unmap);' % suffix
José Fonseca9c536b02012-02-29 20:54:13 +0000590 print ' flush = flush && flushing_unmap;'
591 print ' }'
592 print ' if (flush && length > 0) {'
593 self.emit_memcpy('map', 'map', 'length')
594 print ' }'
595 print ' }'
596 print ' }'
José Fonsecacdc322c2012-02-29 19:29:51 +0000597 if function.name == 'glUnmapBufferOES':
598 print ' GLint access = 0;'
José Fonseca632a78d2012-04-19 07:18:59 +0100599 print ' _glGetBufferParameteriv(target, GL_BUFFER_ACCESS_OES, &access);'
José Fonsecacdc322c2012-02-29 19:29:51 +0000600 print ' if (access == GL_WRITE_ONLY_OES) {'
601 print ' GLvoid *map = NULL;'
José Fonseca632a78d2012-04-19 07:18:59 +0100602 print ' _glGetBufferPointervOES(target, GL_BUFFER_MAP_POINTER_OES, &map);'
José Fonsecacdc322c2012-02-29 19:29:51 +0000603 print ' GLint size = 0;'
José Fonseca632a78d2012-04-19 07:18:59 +0100604 print ' _glGetBufferParameteriv(target, GL_BUFFER_SIZE, &size);'
José Fonsecacdc322c2012-02-29 19:29:51 +0000605 print ' if (map && size > 0) {'
606 self.emit_memcpy('map', 'map', 'size')
José Fonseca219c9f22012-11-03 10:13:17 +0000607 self.shadowBufferMethod('bufferSubData(0, size, map)')
José Fonsecacdc322c2012-02-29 19:29:51 +0000608 print ' }'
José Fonseca867b1b72011-04-24 11:58:04 +0100609 print ' }'
José Fonsecafb3bd602012-01-15 13:56:28 +0000610 if function.name == 'glUnmapNamedBufferEXT':
José Fonseca024aff42012-02-29 18:00:06 +0000611 print ' GLint access_flags = 0;'
José Fonseca632a78d2012-04-19 07:18:59 +0100612 print ' _glGetNamedBufferParameterivEXT(buffer, GL_BUFFER_ACCESS_FLAGS, &access_flags);'
José Fonseca024aff42012-02-29 18:00:06 +0000613 print ' if ((access_flags & GL_MAP_WRITE_BIT) && !(access_flags & GL_MAP_FLUSH_EXPLICIT_BIT)) {'
José Fonsecafb3bd602012-01-15 13:56:28 +0000614 print ' GLvoid *map = NULL;'
José Fonseca632a78d2012-04-19 07:18:59 +0100615 print ' _glGetNamedBufferPointervEXT(buffer, GL_BUFFER_MAP_POINTER, &map);'
José Fonsecafb3bd602012-01-15 13:56:28 +0000616 print ' GLint length = 0;'
José Fonseca632a78d2012-04-19 07:18:59 +0100617 print ' _glGetNamedBufferParameterivEXT(buffer, GL_BUFFER_MAP_LENGTH, &length);'
José Fonseca024aff42012-02-29 18:00:06 +0000618 print ' if (map && length > 0) {'
José Fonsecafb3bd602012-01-15 13:56:28 +0000619 self.emit_memcpy('map', 'map', 'length')
José Fonseca024aff42012-02-29 18:00:06 +0000620 print ' }'
José Fonsecafb3bd602012-01-15 13:56:28 +0000621 print ' }'
José Fonseca77ef0ce2012-02-29 18:08:48 +0000622 if function.name == 'glFlushMappedBufferRange':
623 print ' GLvoid *map = NULL;'
José Fonseca632a78d2012-04-19 07:18:59 +0100624 print ' _glGetBufferPointerv(target, GL_BUFFER_MAP_POINTER, &map);'
José Fonseca77ef0ce2012-02-29 18:08:48 +0000625 print ' if (map && length > 0) {'
626 self.emit_memcpy('(char *)map + offset', '(const char *)map + offset', 'length')
627 print ' }'
628 if function.name == 'glFlushMappedBufferRangeAPPLE':
629 print ' GLvoid *map = NULL;'
José Fonseca632a78d2012-04-19 07:18:59 +0100630 print ' _glGetBufferPointerv(target, GL_BUFFER_MAP_POINTER, &map);'
José Fonseca77ef0ce2012-02-29 18:08:48 +0000631 print ' if (map && size > 0) {'
632 self.emit_memcpy('(char *)map + offset', '(const char *)map + offset', 'size')
José Fonseca73373602011-05-20 17:45:26 +0100633 print ' }'
José Fonsecafb3bd602012-01-15 13:56:28 +0000634 if function.name == 'glFlushMappedNamedBufferRangeEXT':
635 print ' GLvoid *map = NULL;'
José Fonseca632a78d2012-04-19 07:18:59 +0100636 print ' _glGetNamedBufferPointervEXT(buffer, GL_BUFFER_MAP_POINTER, &map);'
José Fonseca024aff42012-02-29 18:00:06 +0000637 print ' if (map && length > 0) {'
José Fonsecafb3bd602012-01-15 13:56:28 +0000638 self.emit_memcpy('(char *)map + offset', '(const char *)map + offset', 'length')
639 print ' }'
José Fonseca867b1b72011-04-24 11:58:04 +0100640
José Fonseca91492d22011-05-23 21:20:31 +0100641 # Don't leave vertex attrib locations to chance. Instead emit fake
642 # glBindAttribLocation calls to ensure that the same locations will be
643 # used when retracing. Trying to remap locations after the fact would
644 # be an herculian task given that vertex attrib locations appear in
645 # many entry-points, including non-shader related ones.
646 if function.name == 'glLinkProgram':
José Fonseca54f304a2012-01-14 19:33:08 +0000647 Tracer.invokeFunction(self, function)
José Fonseca91492d22011-05-23 21:20:31 +0100648 print ' GLint active_attributes = 0;'
José Fonseca632a78d2012-04-19 07:18:59 +0100649 print ' _glGetProgramiv(program, GL_ACTIVE_ATTRIBUTES, &active_attributes);'
José Fonseca7525e6f2011-09-28 09:04:56 +0100650 print ' for (GLint attrib = 0; attrib < active_attributes; ++attrib) {'
José Fonseca91492d22011-05-23 21:20:31 +0100651 print ' GLint size = 0;'
652 print ' GLenum type = 0;'
653 print ' GLchar name[256];'
654 # TODO: Use ACTIVE_ATTRIBUTE_MAX_LENGTH instead of 256
José Fonseca632a78d2012-04-19 07:18:59 +0100655 print ' _glGetActiveAttrib(program, attrib, sizeof name, NULL, &size, &type, name);'
José Fonseca2a794f52011-05-26 20:54:29 +0100656 print " if (name[0] != 'g' || name[1] != 'l' || name[2] != '_') {"
José Fonseca632a78d2012-04-19 07:18:59 +0100657 print ' GLint location = _glGetAttribLocation(program, name);'
José Fonseca2a794f52011-05-26 20:54:29 +0100658 print ' if (location >= 0) {'
José Fonseca1b6c8752012-04-15 14:33:00 +0100659 bind_function = glapi.glapi.getFunctionByName('glBindAttribLocation')
José Fonseca91492d22011-05-23 21:20:31 +0100660 self.fake_call(bind_function, ['program', 'location', 'name'])
José Fonseca2a794f52011-05-26 20:54:29 +0100661 print ' }'
José Fonseca91492d22011-05-23 21:20:31 +0100662 print ' }'
663 print ' }'
664 if function.name == 'glLinkProgramARB':
José Fonseca54f304a2012-01-14 19:33:08 +0000665 Tracer.invokeFunction(self, function)
José Fonseca91492d22011-05-23 21:20:31 +0100666 print ' GLint active_attributes = 0;'
José Fonseca632a78d2012-04-19 07:18:59 +0100667 print ' _glGetObjectParameterivARB(programObj, GL_OBJECT_ACTIVE_ATTRIBUTES_ARB, &active_attributes);'
José Fonseca7525e6f2011-09-28 09:04:56 +0100668 print ' for (GLint attrib = 0; attrib < active_attributes; ++attrib) {'
José Fonseca91492d22011-05-23 21:20:31 +0100669 print ' GLint size = 0;'
670 print ' GLenum type = 0;'
671 print ' GLcharARB name[256];'
672 # TODO: Use ACTIVE_ATTRIBUTE_MAX_LENGTH instead of 256
José Fonseca632a78d2012-04-19 07:18:59 +0100673 print ' _glGetActiveAttribARB(programObj, attrib, sizeof name, NULL, &size, &type, name);'
José Fonseca2a794f52011-05-26 20:54:29 +0100674 print " if (name[0] != 'g' || name[1] != 'l' || name[2] != '_') {"
José Fonseca632a78d2012-04-19 07:18:59 +0100675 print ' GLint location = _glGetAttribLocationARB(programObj, name);'
José Fonseca2a794f52011-05-26 20:54:29 +0100676 print ' if (location >= 0) {'
José Fonseca1b6c8752012-04-15 14:33:00 +0100677 bind_function = glapi.glapi.getFunctionByName('glBindAttribLocationARB')
José Fonseca91492d22011-05-23 21:20:31 +0100678 self.fake_call(bind_function, ['programObj', 'location', 'name'])
José Fonseca2a794f52011-05-26 20:54:29 +0100679 print ' }'
José Fonseca91492d22011-05-23 21:20:31 +0100680 print ' }'
681 print ' }'
682
Imre Deakd4937372012-04-24 14:06:48 +0300683 self.shadowBufferProlog(function)
684
José Fonseca54f304a2012-01-14 19:33:08 +0000685 Tracer.traceFunctionImplBody(self, function)
José Fonseca73373602011-05-20 17:45:26 +0100686
José Fonsecaf028a8f2012-02-15 23:33:35 +0000687 marker_functions = [
688 # GL_GREMEDY_string_marker
José Fonseca8f34d342011-07-15 20:16:40 +0100689 'glStringMarkerGREMEDY',
José Fonsecaf028a8f2012-02-15 23:33:35 +0000690 # GL_GREMEDY_frame_terminator
José Fonseca8f34d342011-07-15 20:16:40 +0100691 'glFrameTerminatorGREMEDY',
José Fonsecaf028a8f2012-02-15 23:33:35 +0000692 # GL_EXT_debug_marker
693 'glInsertEventMarkerEXT',
694 'glPushGroupMarkerEXT',
695 'glPopGroupMarkerEXT',
José Fonseca8f34d342011-07-15 20:16:40 +0100696 ]
697
José Fonseca54f304a2012-01-14 19:33:08 +0000698 def invokeFunction(self, function):
José Fonseca91492d22011-05-23 21:20:31 +0100699 if function.name in ('glLinkProgram', 'glLinkProgramARB'):
700 # These functions have been dispatched already
701 return
702
José Fonsecaf028a8f2012-02-15 23:33:35 +0000703 # We implement GL_EXT_debug_marker, GL_GREMEDY_*, etc., and not the
704 # driver
705 if function.name in self.marker_functions:
José Fonseca8f34d342011-07-15 20:16:40 +0100706 return
707
708 if function.name in ('glXGetProcAddress', 'glXGetProcAddressARB', 'wglGetProcAddress'):
José Fonsecaf028a8f2012-02-15 23:33:35 +0000709 else_ = ''
710 for marker_function in self.marker_functions:
José Fonseca1b6c8752012-04-15 14:33:00 +0100711 if self.api.getFunctionByName(marker_function):
José Fonsecaf028a8f2012-02-15 23:33:35 +0000712 print ' %sif (strcmp("%s", (const char *)%s) == 0) {' % (else_, marker_function, function.args[0].name)
José Fonseca632a78d2012-04-19 07:18:59 +0100713 print ' _result = (%s)&%s;' % (function.type, marker_function)
José Fonsecaf028a8f2012-02-15 23:33:35 +0000714 print ' }'
715 else_ = 'else '
716 print ' %s{' % else_
José Fonseca54f304a2012-01-14 19:33:08 +0000717 Tracer.invokeFunction(self, function)
José Fonseca8f34d342011-07-15 20:16:40 +0100718 print ' }'
José Fonseca1b3d3752011-07-15 10:15:19 +0100719 return
720
José Fonsecaa08d2752011-08-25 13:26:43 +0100721 # Override GL extensions
722 if function.name in ('glGetString', 'glGetIntegerv', 'glGetStringi'):
José Fonseca632a78d2012-04-19 07:18:59 +0100723 Tracer.invokeFunction(self, function, prefix = 'gltrace::_', suffix = '_override')
José Fonsecaa08d2752011-08-25 13:26:43 +0100724 return
725
José Fonseca54f304a2012-01-14 19:33:08 +0000726 Tracer.invokeFunction(self, function)
José Fonseca91492d22011-05-23 21:20:31 +0100727
José Fonseca867b1b72011-04-24 11:58:04 +0100728 buffer_targets = [
729 'ARRAY_BUFFER',
730 'ELEMENT_ARRAY_BUFFER',
731 'PIXEL_PACK_BUFFER',
732 'PIXEL_UNPACK_BUFFER',
José Fonseca7b20d672012-01-10 19:13:58 +0000733 'UNIFORM_BUFFER',
734 'TEXTURE_BUFFER',
735 'TRANSFORM_FEEDBACK_BUFFER',
736 'COPY_READ_BUFFER',
737 'COPY_WRITE_BUFFER',
738 'DRAW_INDIRECT_BUFFER',
739 'ATOMIC_COUNTER_BUFFER',
José Fonseca867b1b72011-04-24 11:58:04 +0100740 ]
741
José Fonseca54f304a2012-01-14 19:33:08 +0000742 def wrapRet(self, function, instance):
743 Tracer.wrapRet(self, function, instance)
José Fonseca1b3d3752011-07-15 10:15:19 +0100744
José Fonseca1b6c8752012-04-15 14:33:00 +0100745 # Replace function addresses with ours
746 if function.name in self.getProcAddressFunctionNames:
747 print ' %s = _wrapProcAddress(%s, %s);' % (instance, function.args[0].name, instance)
748
José Fonsecacdc322c2012-02-29 19:29:51 +0000749 # Keep track of buffer mappings
750 if function.name in ('glMapBuffer', 'glMapBufferARB'):
José Fonseca867b1b72011-04-24 11:58:04 +0100751 print ' struct buffer_mapping *mapping = get_buffer_mapping(target);'
752 print ' if (mapping) {'
753 print ' mapping->map = %s;' % (instance)
754 print ' mapping->length = 0;'
José Fonseca632a78d2012-04-19 07:18:59 +0100755 print ' _glGetBufferParameteriv(target, GL_BUFFER_SIZE, &mapping->length);'
José Fonseca867b1b72011-04-24 11:58:04 +0100756 print ' mapping->write = (access != GL_READ_ONLY);'
José Fonseca73373602011-05-20 17:45:26 +0100757 print ' mapping->explicit_flush = false;'
José Fonseca867b1b72011-04-24 11:58:04 +0100758 print ' }'
José Fonseca867b1b72011-04-24 11:58:04 +0100759 if function.name == 'glMapBufferRange':
José Fonseca9c536b02012-02-29 20:54:13 +0000760 print ' if (access & GL_MAP_WRITE_BIT) {'
José Fonseca632a78d2012-04-19 07:18:59 +0100761 print ' _checkBufferMapRange = true;'
José Fonseca9c536b02012-02-29 20:54:13 +0000762 print ' }'
José Fonseca867b1b72011-04-24 11:58:04 +0100763 print ' struct buffer_mapping *mapping = get_buffer_mapping(target);'
764 print ' if (mapping) {'
765 print ' mapping->map = %s;' % (instance)
766 print ' mapping->length = length;'
767 print ' mapping->write = access & GL_MAP_WRITE_BIT;'
José Fonseca73373602011-05-20 17:45:26 +0100768 print ' mapping->explicit_flush = access & GL_MAP_FLUSH_EXPLICIT_BIT;'
José Fonseca867b1b72011-04-24 11:58:04 +0100769 print ' }'
José Fonseca669b1222011-02-20 09:05:10 +0000770
José Fonsecac9f12232011-03-25 20:07:42 +0000771 boolean_names = [
772 'GL_FALSE',
773 'GL_TRUE',
774 ]
775
776 def gl_boolean(self, value):
777 return self.boolean_names[int(bool(value))]
778
José Fonsecac29f4f12011-06-11 12:19:05 +0100779 # Names of the functions that unpack from a pixel buffer object. See the
780 # ARB_pixel_buffer_object specification.
José Fonsecae97bab92011-06-02 23:15:11 +0100781 unpack_function_names = set([
782 'glBitmap',
José Fonsecac29f4f12011-06-11 12:19:05 +0100783 'glColorSubTable',
784 'glColorTable',
José Fonsecad2bd4ca2013-04-12 11:41:00 +0100785 'glCompressedMultiTexImage1DEXT',
786 'glCompressedMultiTexImage2DEXT',
787 'glCompressedMultiTexImage3DEXT',
788 'glCompressedMultiTexSubImage1DEXT',
789 'glCompressedMultiTexSubImage2DEXT',
790 'glCompressedMultiTexSubImage3DEXT',
José Fonsecac29f4f12011-06-11 12:19:05 +0100791 'glCompressedTexImage1D',
792 'glCompressedTexImage2D',
793 'glCompressedTexImage3D',
794 'glCompressedTexSubImage1D',
795 'glCompressedTexSubImage2D',
796 'glCompressedTexSubImage3D',
José Fonsecad2bd4ca2013-04-12 11:41:00 +0100797 'glCompressedTextureImage1DEXT',
798 'glCompressedTextureImage2DEXT',
799 'glCompressedTextureImage3DEXT',
800 'glCompressedTextureSubImage1DEXT',
801 'glCompressedTextureSubImage2DEXT',
802 'glCompressedTextureSubImage3DEXT',
José Fonsecac29f4f12011-06-11 12:19:05 +0100803 'glConvolutionFilter1D',
804 'glConvolutionFilter2D',
José Fonsecae97bab92011-06-02 23:15:11 +0100805 'glDrawPixels',
806 'glMultiTexImage1DEXT',
807 'glMultiTexImage2DEXT',
808 'glMultiTexImage3DEXT',
809 'glMultiTexSubImage1DEXT',
810 'glMultiTexSubImage2DEXT',
811 'glMultiTexSubImage3DEXT',
José Fonsecac29f4f12011-06-11 12:19:05 +0100812 'glPixelMapfv',
813 'glPixelMapuiv',
814 'glPixelMapusv',
José Fonsecae97bab92011-06-02 23:15:11 +0100815 'glPolygonStipple',
José Fonsecac29f4f12011-06-11 12:19:05 +0100816 'glSeparableFilter2D',
José Fonsecae97bab92011-06-02 23:15:11 +0100817 'glTexImage1D',
818 'glTexImage1DEXT',
819 'glTexImage2D',
820 'glTexImage2DEXT',
821 'glTexImage3D',
822 'glTexImage3DEXT',
823 'glTexSubImage1D',
824 'glTexSubImage1DEXT',
825 'glTexSubImage2D',
826 'glTexSubImage2DEXT',
827 'glTexSubImage3D',
828 'glTexSubImage3DEXT',
829 'glTextureImage1DEXT',
830 'glTextureImage2DEXT',
831 'glTextureImage3DEXT',
832 'glTextureSubImage1DEXT',
833 'glTextureSubImage2DEXT',
834 'glTextureSubImage3DEXT',
835 ])
836
José Fonseca54f304a2012-01-14 19:33:08 +0000837 def serializeArgValue(self, function, arg):
José Fonsecae97bab92011-06-02 23:15:11 +0100838 # Recognize offsets instead of blobs when a PBO is bound
839 if function.name in self.unpack_function_names \
840 and (isinstance(arg.type, stdapi.Blob) \
841 or (isinstance(arg.type, stdapi.Const) \
842 and isinstance(arg.type.type, stdapi.Blob))):
José Fonsecac29f4f12011-06-11 12:19:05 +0100843 print ' {'
José Fonsecaf028a8f2012-02-15 23:33:35 +0000844 print ' gltrace::Context *ctx = gltrace::getContext();'
José Fonseca632a78d2012-04-19 07:18:59 +0100845 print ' GLint _unpack_buffer = 0;'
José Fonsecaf028a8f2012-02-15 23:33:35 +0000846 print ' if (ctx->profile == gltrace::PROFILE_COMPAT)'
José Fonseca632a78d2012-04-19 07:18:59 +0100847 print ' _glGetIntegerv(GL_PIXEL_UNPACK_BUFFER_BINDING, &_unpack_buffer);'
848 print ' if (_unpack_buffer) {'
José Fonsecad559f022012-04-15 16:13:51 +0100849 print ' trace::localWriter.writePointer((uintptr_t)%s);' % arg.name
José Fonsecac29f4f12011-06-11 12:19:05 +0100850 print ' } else {'
José Fonseca54f304a2012-01-14 19:33:08 +0000851 Tracer.serializeArgValue(self, function, arg)
José Fonsecac29f4f12011-06-11 12:19:05 +0100852 print ' }'
José Fonsecae97bab92011-06-02 23:15:11 +0100853 print ' }'
854 return
855
José Fonsecaa3f89ae2011-04-26 08:50:32 +0100856 # Several GL state functions take GLenum symbolic names as
857 # integer/floats; so dump the symbolic name whenever possible
José Fonseca3bcb33c2011-05-27 20:14:31 +0100858 if function.name.startswith('gl') \
José Fonsecae3571092011-10-13 08:26:27 +0100859 and arg.type in (glapi.GLint, glapi.GLfloat, glapi.GLdouble) \
José Fonseca3bcb33c2011-05-27 20:14:31 +0100860 and arg.name == 'param':
José Fonsecaa3f89ae2011-04-26 08:50:32 +0100861 assert arg.index > 0
862 assert function.args[arg.index - 1].name == 'pname'
863 assert function.args[arg.index - 1].type == glapi.GLenum
864 print ' if (is_symbolic_pname(pname) && is_symbolic_param(%s)) {' % arg.name
José Fonseca54f304a2012-01-14 19:33:08 +0000865 self.serializeValue(glapi.GLenum, arg.name)
José Fonsecaa3f89ae2011-04-26 08:50:32 +0100866 print ' } else {'
José Fonseca54f304a2012-01-14 19:33:08 +0000867 Tracer.serializeArgValue(self, function, arg)
José Fonsecaa3f89ae2011-04-26 08:50:32 +0100868 print ' }'
869 return
870
José Fonseca54f304a2012-01-14 19:33:08 +0000871 Tracer.serializeArgValue(self, function, arg)
José Fonseca99221832011-03-22 22:15:46 +0000872
José Fonseca4c938c22011-04-30 22:44:38 +0100873 def footer(self, api):
874 Tracer.footer(self, api)
José Fonseca669b1222011-02-20 09:05:10 +0000875
José Fonseca4c938c22011-04-30 22:44:38 +0100876 # A simple state tracker to track the pointer values
José Fonseca669b1222011-02-20 09:05:10 +0000877 # update the state
José Fonseca14cb9ef2012-05-17 21:33:14 +0100878 print 'static void _trace_user_arrays(GLuint count)'
José Fonseca669b1222011-02-20 09:05:10 +0000879 print '{'
José Fonsecaf028a8f2012-02-15 23:33:35 +0000880 print ' gltrace::Context *ctx = gltrace::getContext();'
José Fonseca1a2fdd22011-04-01 00:55:09 +0100881
José Fonseca99221832011-03-22 22:15:46 +0000882 for camelcase_name, uppercase_name in self.arrays:
Chia-I Wub3d218d2011-11-03 01:37:36 +0800883 # in which profile is the array available?
José Fonsecaf028a8f2012-02-15 23:33:35 +0000884 profile_check = 'ctx->profile == gltrace::PROFILE_COMPAT'
Chia-I Wub3d218d2011-11-03 01:37:36 +0800885 if camelcase_name in self.arrays_es1:
José Fonsecaf028a8f2012-02-15 23:33:35 +0000886 profile_check = '(' + profile_check + ' || ctx->profile == gltrace::PROFILE_ES1)';
Chia-I Wub3d218d2011-11-03 01:37:36 +0800887
José Fonseca99221832011-03-22 22:15:46 +0000888 function_name = 'gl%sPointer' % camelcase_name
889 enable_name = 'GL_%s_ARRAY' % uppercase_name
890 binding_name = 'GL_%s_ARRAY_BUFFER_BINDING' % uppercase_name
José Fonseca1b6c8752012-04-15 14:33:00 +0100891 function = api.getFunctionByName(function_name)
José Fonseca99221832011-03-22 22:15:46 +0000892
José Fonseca06e85192011-10-16 14:15:36 +0100893 print ' // %s' % function.prototype()
Chia-I Wub3d218d2011-11-03 01:37:36 +0800894 print ' if (%s) {' % profile_check
José Fonsecafb6744f2011-04-15 11:18:37 +0100895 self.array_trace_prolog(api, uppercase_name)
896 self.array_prolog(api, uppercase_name)
José Fonseca632a78d2012-04-19 07:18:59 +0100897 print ' if (_glIsEnabled(%s)) {' % enable_name
898 print ' GLint _binding = 0;'
899 print ' _glGetIntegerv(%s, &_binding);' % binding_name
900 print ' if (!_binding) {'
José Fonseca99221832011-03-22 22:15:46 +0000901
902 # Get the arguments via glGet*
903 for arg in function.args:
904 arg_get_enum = 'GL_%s_ARRAY_%s' % (uppercase_name, arg.name.upper())
905 arg_get_function, arg_type = TypeGetter().visit(arg.type)
José Fonseca7f5163e2011-03-31 23:37:26 +0100906 print ' %s %s = 0;' % (arg_type, arg.name)
José Fonseca632a78d2012-04-19 07:18:59 +0100907 print ' _%s(%s, &%s);' % (arg_get_function, arg_get_enum, arg.name)
José Fonseca99221832011-03-22 22:15:46 +0000908
909 arg_names = ', '.join([arg.name for arg in function.args[:-1]])
José Fonseca14cb9ef2012-05-17 21:33:14 +0100910 print ' size_t _size = _%s_size(%s, count);' % (function.name, arg_names)
José Fonseca99221832011-03-22 22:15:46 +0000911
912 # Emit a fake function
José Fonsecafb6744f2011-04-15 11:18:37 +0100913 self.array_trace_intermezzo(api, uppercase_name)
José Fonseca632a78d2012-04-19 07:18:59 +0100914 print ' unsigned _call = trace::localWriter.beginEnter(&_%s_sig);' % (function.name,)
José Fonseca669b1222011-02-20 09:05:10 +0000915 for arg in function.args:
916 assert not arg.output
José Fonsecab4a3d142011-10-27 07:43:19 +0100917 print ' trace::localWriter.beginArg(%u);' % (arg.index,)
José Fonseca14c21bc2011-02-20 23:32:22 +0000918 if arg.name != 'pointer':
José Fonseca54f304a2012-01-14 19:33:08 +0000919 self.serializeValue(arg.type, arg.name)
José Fonseca14c21bc2011-02-20 23:32:22 +0000920 else:
José Fonseca632a78d2012-04-19 07:18:59 +0100921 print ' trace::localWriter.writeBlob((const void *)%s, _size);' % (arg.name)
José Fonsecab4a3d142011-10-27 07:43:19 +0100922 print ' trace::localWriter.endArg();'
José Fonseca99221832011-03-22 22:15:46 +0000923
José Fonsecab4a3d142011-10-27 07:43:19 +0100924 print ' trace::localWriter.endEnter();'
José Fonseca632a78d2012-04-19 07:18:59 +0100925 print ' trace::localWriter.beginLeave(_call);'
José Fonsecab4a3d142011-10-27 07:43:19 +0100926 print ' trace::localWriter.endLeave();'
José Fonseca99221832011-03-22 22:15:46 +0000927 print ' }'
José Fonseca669b1222011-02-20 09:05:10 +0000928 print ' }'
José Fonsecafb6744f2011-04-15 11:18:37 +0100929 self.array_epilog(api, uppercase_name)
930 self.array_trace_epilog(api, uppercase_name)
Chia-I Wub3d218d2011-11-03 01:37:36 +0800931 print ' }'
José Fonseca99221832011-03-22 22:15:46 +0000932 print
José Fonseca1a2fdd22011-04-01 00:55:09 +0100933
José Fonseca1601c412011-05-10 10:38:19 +0100934 # Samething, but for glVertexAttribPointer*
935 #
936 # Some variants of glVertexAttribPointer alias conventional and generic attributes:
937 # - glVertexAttribPointer: no
938 # - glVertexAttribPointerARB: implementation dependent
939 # - glVertexAttribPointerNV: yes
940 #
941 # This means that the implementations of these functions do not always
942 # alias, and they need to be considered independently.
943 #
Chia-I Wub3d218d2011-11-03 01:37:36 +0800944 print ' // ES1 does not support generic vertex attributes'
José Fonsecaf028a8f2012-02-15 23:33:35 +0000945 print ' if (ctx->profile == gltrace::PROFILE_ES1)'
Chia-I Wub3d218d2011-11-03 01:37:36 +0800946 print ' return;'
947 print
José Fonseca632a78d2012-04-19 07:18:59 +0100948 print ' vertex_attrib _vertex_attrib = _get_vertex_attrib();'
José Fonseca5a568a92011-06-29 16:43:36 +0100949 print
950 for suffix in ['', 'ARB', 'NV']:
951 if suffix:
José Fonsecad94aaac2011-06-28 20:50:49 +0100952 SUFFIX = '_' + suffix
José Fonsecad94aaac2011-06-28 20:50:49 +0100953 else:
José Fonseca5a568a92011-06-29 16:43:36 +0100954 SUFFIX = suffix
José Fonseca1601c412011-05-10 10:38:19 +0100955 function_name = 'glVertexAttribPointer' + suffix
José Fonseca1b6c8752012-04-15 14:33:00 +0100956 function = api.getFunctionByName(function_name)
José Fonseca06e85192011-10-16 14:15:36 +0100957
958 print ' // %s' % function.prototype()
José Fonseca632a78d2012-04-19 07:18:59 +0100959 print ' if (_vertex_attrib == VERTEX_ATTRIB%s) {' % SUFFIX
José Fonseca5a568a92011-06-29 16:43:36 +0100960 if suffix == 'NV':
José Fonseca632a78d2012-04-19 07:18:59 +0100961 print ' GLint _max_vertex_attribs = 16;'
José Fonseca5a568a92011-06-29 16:43:36 +0100962 else:
José Fonseca632a78d2012-04-19 07:18:59 +0100963 print ' GLint _max_vertex_attribs = 0;'
964 print ' _glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &_max_vertex_attribs);'
965 print ' for (GLint index = 0; index < _max_vertex_attribs; ++index) {'
966 print ' GLint _enabled = 0;'
José Fonseca5a568a92011-06-29 16:43:36 +0100967 if suffix == 'NV':
José Fonseca632a78d2012-04-19 07:18:59 +0100968 print ' _glGetIntegerv(GL_VERTEX_ATTRIB_ARRAY0_NV + index, &_enabled);'
José Fonseca5a568a92011-06-29 16:43:36 +0100969 else:
José Fonseca632a78d2012-04-19 07:18:59 +0100970 print ' _glGetVertexAttribiv%s(index, GL_VERTEX_ATTRIB_ARRAY_ENABLED%s, &_enabled);' % (suffix, SUFFIX)
971 print ' if (_enabled) {'
972 print ' GLint _binding = 0;'
José Fonseca5a568a92011-06-29 16:43:36 +0100973 if suffix != 'NV':
974 # It doesn't seem possible to use VBOs with NV_vertex_program.
José Fonseca632a78d2012-04-19 07:18:59 +0100975 print ' _glGetVertexAttribiv%s(index, GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING%s, &_binding);' % (suffix, SUFFIX)
976 print ' if (!_binding) {'
José Fonseca1a2fdd22011-04-01 00:55:09 +0100977
José Fonseca1601c412011-05-10 10:38:19 +0100978 # Get the arguments via glGet*
979 for arg in function.args[1:]:
José Fonseca5a568a92011-06-29 16:43:36 +0100980 if suffix == 'NV':
981 arg_get_enum = 'GL_ATTRIB_ARRAY_%s%s' % (arg.name.upper(), SUFFIX)
982 else:
983 arg_get_enum = 'GL_VERTEX_ATTRIB_ARRAY_%s%s' % (arg.name.upper(), SUFFIX)
José Fonsecac493e3e2011-06-29 12:57:06 +0100984 arg_get_function, arg_type = TypeGetter('glGetVertexAttrib', False, suffix).visit(arg.type)
José Fonseca5a568a92011-06-29 16:43:36 +0100985 print ' %s %s = 0;' % (arg_type, arg.name)
José Fonseca632a78d2012-04-19 07:18:59 +0100986 print ' _%s(index, %s, &%s);' % (arg_get_function, arg_get_enum, arg.name)
José Fonseca1601c412011-05-10 10:38:19 +0100987
988 arg_names = ', '.join([arg.name for arg in function.args[1:-1]])
José Fonseca14cb9ef2012-05-17 21:33:14 +0100989 print ' size_t _size = _%s_size(%s, count);' % (function.name, arg_names)
José Fonseca1a2fdd22011-04-01 00:55:09 +0100990
José Fonseca1601c412011-05-10 10:38:19 +0100991 # Emit a fake function
José Fonseca632a78d2012-04-19 07:18:59 +0100992 print ' unsigned _call = trace::localWriter.beginEnter(&_%s_sig);' % (function.name,)
José Fonseca1601c412011-05-10 10:38:19 +0100993 for arg in function.args:
994 assert not arg.output
José Fonsecab4a3d142011-10-27 07:43:19 +0100995 print ' trace::localWriter.beginArg(%u);' % (arg.index,)
José Fonseca1601c412011-05-10 10:38:19 +0100996 if arg.name != 'pointer':
José Fonseca54f304a2012-01-14 19:33:08 +0000997 self.serializeValue(arg.type, arg.name)
José Fonseca1601c412011-05-10 10:38:19 +0100998 else:
José Fonseca632a78d2012-04-19 07:18:59 +0100999 print ' trace::localWriter.writeBlob((const void *)%s, _size);' % (arg.name)
José Fonsecab4a3d142011-10-27 07:43:19 +01001000 print ' trace::localWriter.endArg();'
José Fonseca1601c412011-05-10 10:38:19 +01001001
José Fonsecab4a3d142011-10-27 07:43:19 +01001002 print ' trace::localWriter.endEnter();'
José Fonseca632a78d2012-04-19 07:18:59 +01001003 print ' trace::localWriter.beginLeave(_call);'
José Fonsecab4a3d142011-10-27 07:43:19 +01001004 print ' trace::localWriter.endLeave();'
José Fonseca1601c412011-05-10 10:38:19 +01001005 print ' }'
1006 print ' }'
1007 print ' }'
1008 print ' }'
1009 print
José Fonseca1a2fdd22011-04-01 00:55:09 +01001010
José Fonseca669b1222011-02-20 09:05:10 +00001011 print '}'
1012 print
1013
José Fonsecafb6744f2011-04-15 11:18:37 +01001014 #
1015 # Hooks for glTexCoordPointer, which is identical to the other array
1016 # pointers except the fact that it is indexed by glClientActiveTexture.
1017 #
1018
1019 def array_prolog(self, api, uppercase_name):
1020 if uppercase_name == 'TEXTURE_COORD':
1021 print ' GLint client_active_texture = 0;'
José Fonseca632a78d2012-04-19 07:18:59 +01001022 print ' _glGetIntegerv(GL_CLIENT_ACTIVE_TEXTURE, &client_active_texture);'
José Fonsecafb6744f2011-04-15 11:18:37 +01001023 print ' GLint max_texture_coords = 0;'
José Fonsecaf028a8f2012-02-15 23:33:35 +00001024 print ' if (ctx->profile == gltrace::PROFILE_COMPAT)'
José Fonseca632a78d2012-04-19 07:18:59 +01001025 print ' _glGetIntegerv(GL_MAX_TEXTURE_COORDS, &max_texture_coords);'
Chia-I Wub3d218d2011-11-03 01:37:36 +08001026 print ' else'
José Fonseca632a78d2012-04-19 07:18:59 +01001027 print ' _glGetIntegerv(GL_MAX_TEXTURE_UNITS, &max_texture_coords);'
José Fonsecafb6744f2011-04-15 11:18:37 +01001028 print ' for (GLint unit = 0; unit < max_texture_coords; ++unit) {'
José Fonseca7525e6f2011-09-28 09:04:56 +01001029 print ' GLint texture = GL_TEXTURE0 + unit;'
José Fonseca632a78d2012-04-19 07:18:59 +01001030 print ' _glClientActiveTexture(texture);'
José Fonsecafb6744f2011-04-15 11:18:37 +01001031
1032 def array_trace_prolog(self, api, uppercase_name):
1033 if uppercase_name == 'TEXTURE_COORD':
1034 print ' bool client_active_texture_dirty = false;'
1035
1036 def array_epilog(self, api, uppercase_name):
1037 if uppercase_name == 'TEXTURE_COORD':
1038 print ' }'
1039 self.array_cleanup(api, uppercase_name)
1040
1041 def array_cleanup(self, api, uppercase_name):
1042 if uppercase_name == 'TEXTURE_COORD':
José Fonseca632a78d2012-04-19 07:18:59 +01001043 print ' _glClientActiveTexture(client_active_texture);'
José Fonsecafb6744f2011-04-15 11:18:37 +01001044
1045 def array_trace_intermezzo(self, api, uppercase_name):
1046 if uppercase_name == 'TEXTURE_COORD':
1047 print ' if (texture != client_active_texture || client_active_texture_dirty) {'
1048 print ' client_active_texture_dirty = true;'
1049 self.fake_glClientActiveTexture_call(api, "texture");
1050 print ' }'
1051
1052 def array_trace_epilog(self, api, uppercase_name):
1053 if uppercase_name == 'TEXTURE_COORD':
1054 print ' if (client_active_texture_dirty) {'
1055 self.fake_glClientActiveTexture_call(api, "client_active_texture");
1056 print ' }'
1057
1058 def fake_glClientActiveTexture_call(self, api, texture):
José Fonseca1b6c8752012-04-15 14:33:00 +01001059 function = api.getFunctionByName('glClientActiveTexture')
José Fonsecafb6744f2011-04-15 11:18:37 +01001060 self.fake_call(function, [texture])
1061
José Fonseca151c3702013-05-10 08:28:15 +01001062 def emitFakeTexture2D(self):
1063 function = glapi.glapi.getFunctionByName('glTexImage2D')
1064 instances = function.argNames()
1065 print ' unsigned _fake_call = trace::localWriter.beginEnter(&_%s_sig);' % (function.name,)
1066 for arg in function.args:
1067 assert not arg.output
1068 self.serializeArg(function, arg)
1069 print ' trace::localWriter.endEnter();'
1070 print ' trace::localWriter.beginLeave(_fake_call);'
1071 print ' trace::localWriter.endLeave();'
José Fonsecafb6744f2011-04-15 11:18:37 +01001072
1073
1074
1075
1076
José Fonseca669b1222011-02-20 09:05:10 +00001077
1078
1079
1080
1081
1082