blob: 5d58b2d58faa9f7509320fc290d249b140d2684d [file] [log] [blame]
José Fonseca7e329022010-11-19 17:05:18 +00001##########################################################################
2#
3# Copyright 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
José Fonseca4a826ed2010-11-30 16:58:22 +000027"""GL retracer generator."""
28
29
José Fonseca9796b842010-11-25 11:44:50 +000030import stdapi
José Fonseca8fbdd3a2010-11-23 20:55:07 +000031import glapi
José Fonsecadacd8dd2010-11-25 17:50:26 +000032from retrace import Retracer
José Fonseca7e329022010-11-19 17:05:18 +000033
34
José Fonsecadacd8dd2010-11-25 17:50:26 +000035class GlRetracer(Retracer):
José Fonsecac9edb832010-11-20 09:03:10 +000036
José Fonseca3d245f42010-11-28 00:08:23 +000037 def retrace_function(self, function):
38 Retracer.retrace_function(self, function)
39
José Fonseca62212972011-03-23 13:22:55 +000040 array_pointer_function_names = set((
41 "glVertexPointer",
42 "glNormalPointer",
43 "glColorPointer",
44 "glIndexPointer",
45 "glTexCoordPointer",
46 "glEdgeFlagPointer",
47 "glFogCoordPointer",
48 "glSecondaryColorPointer",
49
50 "glInterleavedArrays",
51
José Fonsecaac5285b2011-05-04 11:09:08 +010052 "glVertexPointerEXT",
53 "glNormalPointerEXT",
54 "glColorPointerEXT",
55 "glIndexPointerEXT",
56 "glTexCoordPointerEXT",
57 "glEdgeFlagPointerEXT",
58 "glFogCoordPointerEXT",
59 "glSecondaryColorPointerEXT",
José Fonseca62212972011-03-23 13:22:55 +000060
José Fonseca7f5163e2011-03-31 23:37:26 +010061 "glVertexAttribPointer",
62 "glVertexAttribPointerARB",
63 "glVertexAttribPointerNV",
José Fonsecaac5285b2011-05-04 11:09:08 +010064 "glVertexAttribIPointer",
65 "glVertexAttribIPointerEXT",
José Fonseca7f5163e2011-03-31 23:37:26 +010066 "glVertexAttribLPointer",
67 "glVertexAttribLPointerEXT",
José Fonseca62212972011-03-23 13:22:55 +000068
69 #"glMatrixIndexPointerARB",
70 ))
71
José Fonseca8caf2c82010-11-30 12:09:12 +000072 draw_array_function_names = set([
73 "glDrawArrays",
74 "glDrawArraysEXT",
75 "glDrawArraysIndirect",
76 "glDrawArraysInstanced",
77 "glDrawArraysInstancedARB",
78 "glDrawArraysInstancedEXT",
79 "glDrawMeshArraysSUN",
80 "glMultiDrawArrays",
81 "glMultiDrawArraysEXT",
82 "glMultiModeDrawArraysIBM",
83 ])
84
85 draw_elements_function_names = set([
86 "glDrawElements",
87 "glDrawElementsBaseVertex",
88 "glDrawElementsIndirect",
89 "glDrawElementsInstanced",
90 "glDrawElementsInstancedARB",
91 "glDrawElementsInstancedBaseVertex",
92 "glDrawElementsInstancedEXT",
93 "glDrawRangeElements",
94 "glDrawRangeElementsBaseVertex",
95 "glDrawRangeElementsEXT",
José Fonsecafd34e4e2011-06-03 19:34:29 +010096 "glMultiDrawElements",
97 "glMultiDrawElementsBaseVertex",
98 "glMultiDrawElementsEXT",
99 "glMultiModeDrawElementsIBM",
José Fonseca8caf2c82010-11-30 12:09:12 +0000100 ])
101
José Fonseca920bffd2011-06-02 10:04:52 +0100102 misc_draw_function_names = set([
103 "glClear",
104 "glEnd",
José Fonsecaf8a99a02011-06-07 20:49:56 +0100105 "glDrawPixels",
106 "glBlitFramebuffer",
107 "glBlitFramebufferEXT",
José Fonseca920bffd2011-06-02 10:04:52 +0100108 ])
109
110 bind_framebuffer_function_names = set([
111 "glBindFramebuffer",
112 "glBindFramebufferARB",
113 "glBindFramebufferEXT",
114 ])
115
José Fonsecac29f4f12011-06-11 12:19:05 +0100116 # Names of the functions that can pack into the current pixel buffer
117 # object. See also the ARB_pixel_buffer_object specification.
118 pack_function_names = set([
119 'glGetCompressedTexImage',
120 'glGetConvolutionFilter',
121 'glGetHistogram',
122 'glGetMinmax',
123 'glGetPixelMapfv',
124 'glGetPixelMapuiv',
125 'glGetPixelMapusv',
126 'glGetPolygonStipple',
127 'glGetSeparableFilter,',
128 'glGetTexImage',
129 'glReadPixels',
130 'glGetnCompressedTexImageARB',
131 'glGetnConvolutionFilterARB',
132 'glGetnHistogramARB',
133 'glGetnMinmaxARB',
134 'glGetnPixelMapfvARB',
135 'glGetnPixelMapuivARB',
136 'glGetnPixelMapusvARB',
137 'glGetnPolygonStippleARB',
138 'glGetnSeparableFilterARB',
139 'glGetnTexImageARB',
140 'glReadnPixelsARB',
141 ])
142
José Fonseca62212972011-03-23 13:22:55 +0000143 def retrace_function_body(self, function):
144 is_array_pointer = function.name in self.array_pointer_function_names
145 is_draw_array = function.name in self.draw_array_function_names
146 is_draw_elements = function.name in self.draw_elements_function_names
José Fonseca920bffd2011-06-02 10:04:52 +0100147 is_misc_draw = function.name in self.misc_draw_function_names
José Fonseca62212972011-03-23 13:22:55 +0000148
149 if is_array_pointer or is_draw_array or is_draw_elements:
José Fonseca6117e312011-04-15 23:52:58 +0100150 print ' if (glretrace::parser.version < 1) {'
José Fonseca62212972011-03-23 13:22:55 +0000151
152 if is_array_pointer or is_draw_array:
153 print ' GLint __array_buffer = 0;'
154 print ' glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &__array_buffer);'
155 print ' if (!__array_buffer) {'
156 self.fail_function(function)
157 print ' }'
158
159 if is_draw_elements:
160 print ' GLint __element_array_buffer = 0;'
161 print ' glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &__element_array_buffer);'
162 print ' if (!__element_array_buffer) {'
163 self.fail_function(function)
164 print ' }'
165
166 print ' }'
167
José Fonsecac29f4f12011-06-11 12:19:05 +0100168 # When no pack buffer object is bound, the pack functions are no-ops.
169 if function.name in self.pack_function_names:
170 print ' GLint __pack_buffer = 0;'
171 print ' glGetIntegerv(GL_PIXEL_PACK_BUFFER_BINDING, &__pack_buffer);'
172 print ' if (!__pack_buffer) {'
173 print ' return;'
174 print ' }'
175
José Fonseca920bffd2011-06-02 10:04:52 +0100176 # Pre-snapshots
177 if function.name in self.bind_framebuffer_function_names:
178 print ' if (glretrace::snapshot_frequency == glretrace::FREQUENCY_FRAMEBUFFER) {'
179 print ' glretrace::snapshot(call.no - 1);'
180 print ' }'
181
José Fonseca62212972011-03-23 13:22:55 +0000182 Retracer.retrace_function_body(self, function)
183
José Fonseca920bffd2011-06-02 10:04:52 +0100184 # Post-snapshots
José Fonseca4d7f1fe2011-05-09 20:54:31 +0100185 if function.name in ('glFlush', 'glFinish'):
186 print ' if (!glretrace::double_buffer) {'
187 print ' glretrace::frame_complete(call.no);'
188 print ' }'
José Fonseca4d7f1fe2011-05-09 20:54:31 +0100189 if function.name == 'glReadPixels':
190 print ' glFinish();'
José Fonseca920bffd2011-06-02 10:04:52 +0100191 print ' if (glretrace::snapshot_frequency == glretrace::FREQUENCY_FRAME ||'
192 print ' glretrace::snapshot_frequency == glretrace::FREQUENCY_FRAMEBUFFER) {'
193 print ' glretrace::snapshot(call.no);'
194 print ' }'
195 if is_draw_array or is_draw_elements or is_misc_draw:
196 print ' if (glretrace::snapshot_frequency == glretrace::FREQUENCY_DRAW) {'
197 print ' glretrace::snapshot(call.no);'
198 print ' }'
199
José Fonseca4d7f1fe2011-05-09 20:54:31 +0100200
José Fonsecafa15d332010-11-25 20:22:39 +0000201 def call_function(self, function):
José Fonsecacdb574a2010-11-29 12:23:35 +0000202 if function.name == "glViewport":
José Fonseca29d21622011-05-06 20:50:52 +0100203 print ' if (glretrace::drawable) {'
204 print ' int drawable_width = x + width;'
205 print ' int drawable_height = y + height;'
206 print ' if (drawable_width > (int)glretrace::drawable->width ||'
207 print ' drawable_height > (int)glretrace::drawable->height) {'
208 print ' glretrace::drawable->resize(drawable_width, drawable_height);'
José Fonsecad3a6f152011-05-20 23:54:13 +0100209 print ' if (!glretrace::drawable->visible) {'
210 print ' glretrace::drawable->show();'
211 print ' }'
José Fonsecaa4d77a92011-05-18 09:54:36 +0100212 print ' glScissor(0, 0, drawable_width, drawable_height);'
José Fonseca29d21622011-05-06 20:50:52 +0100213 print ' }'
José Fonsecacdb574a2010-11-29 12:23:35 +0000214 print ' }'
215
José Fonseca3d245f42010-11-28 00:08:23 +0000216 if function.name == "glEnd":
José Fonseca32871ed2011-04-10 13:40:52 +0100217 print ' glretrace::insideGlBeginEnd = false;'
José Fonsecafea81f92011-05-23 21:20:53 +0100218
219 if function.name == 'memcpy':
220 print ' if (!dest || !src || !n) return;'
José Fonsecacdb574a2010-11-29 12:23:35 +0000221
José Fonsecafa15d332010-11-25 20:22:39 +0000222 Retracer.call_function(self, function)
José Fonsecacdb574a2010-11-29 12:23:35 +0000223
José Fonsecaecf37412011-05-21 01:56:08 +0100224 # Error checking
José Fonseca3d245f42010-11-28 00:08:23 +0000225 if function.name == "glBegin":
José Fonseca32871ed2011-04-10 13:40:52 +0100226 print ' glretrace::insideGlBeginEnd = true;'
José Fonsecab8c56072011-05-05 01:13:04 +0100227 elif function.name.startswith('gl'):
José Fonseca3d245f42010-11-28 00:08:23 +0000228 # glGetError is not allowed inside glBegin/glEnd
José Fonsecaecf37412011-05-21 01:56:08 +0100229 print ' if (!glretrace::benchmark && !glretrace::insideGlBeginEnd) {'
230 print ' glretrace::checkGlError(call);'
231 if function.name in ('glProgramStringARB', 'glProgramStringNV'):
232 print r' GLint error_position = -1;'
233 print r' glGetIntegerv(GL_PROGRAM_ERROR_POSITION_ARB, &error_position);'
234 print r' if (error_position != -1) {'
235 print r' const char *error_string = (const char *)glGetString(GL_PROGRAM_ERROR_STRING_ARB);'
236 print r' std::cerr << call.no << ": warning: " << error_string << "\n";'
237 print r' }'
238 if function.name == 'glCompileShader':
239 print r' GLint compile_status = 0;'
240 print r' glGetShaderiv(shader, GL_COMPILE_STATUS, &compile_status);'
241 print r' if (!compile_status) {'
242 print r' GLint info_log_length = 0;'
243 print r' glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &info_log_length);'
244 print r' GLchar *infoLog = new GLchar[info_log_length];'
245 print r' glGetShaderInfoLog(shader, info_log_length, NULL, infoLog);'
246 print r' std::cerr << call.no << ": warning: " << infoLog << "\n";'
247 print r' delete [] infoLog;'
248 print r' }'
249 if function.name == 'glLinkProgram':
250 print r' GLint link_status = 0;'
251 print r' glGetProgramiv(program, GL_LINK_STATUS, &link_status);'
252 print r' if (!link_status) {'
253 print r' GLint info_log_length = 0;'
254 print r' glGetProgramiv(program, GL_INFO_LOG_LENGTH, &info_log_length);'
255 print r' GLchar *infoLog = new GLchar[info_log_length];'
256 print r' glGetProgramInfoLog(program, info_log_length, NULL, infoLog);'
257 print r' std::cerr << call.no << ": warning: " << infoLog << "\n";'
258 print r' delete [] infoLog;'
259 print r' }'
260 if function.name == 'glCompileShaderARB':
261 print r' GLint compile_status = 0;'
262 print r' glGetObjectParameterivARB(shaderObj, GL_OBJECT_COMPILE_STATUS_ARB, &compile_status);'
263 print r' if (!compile_status) {'
264 print r' GLint info_log_length = 0;'
265 print r' glGetObjectParameterivARB(shaderObj, GL_OBJECT_INFO_LOG_LENGTH_ARB, &info_log_length);'
266 print r' GLchar *infoLog = new GLchar[info_log_length];'
267 print r' glGetInfoLogARB(shaderObj, info_log_length, NULL, infoLog);'
268 print r' std::cerr << call.no << ": warning: " << infoLog << "\n";'
269 print r' delete [] infoLog;'
270 print r' }'
271 if function.name == 'glLinkProgramARB':
272 print r' GLint link_status = 0;'
273 print r' glGetObjectParameterivARB(programObj, GL_OBJECT_LINK_STATUS_ARB, &link_status);'
274 print r' if (!link_status) {'
275 print r' GLint info_log_length = 0;'
276 print r' glGetObjectParameterivARB(programObj, GL_OBJECT_INFO_LOG_LENGTH_ARB, &info_log_length);'
277 print r' GLchar *infoLog = new GLchar[info_log_length];'
278 print r' glGetInfoLogARB(programObj, info_log_length, NULL, infoLog);'
279 print r' std::cerr << call.no << ": warning: " << infoLog << "\n";'
280 print r' delete [] infoLog;'
281 print r' }'
José Fonsecafea81f92011-05-23 21:20:53 +0100282 if function.name in ('glMapBuffer', 'glMapBufferARB', 'glMapBufferRange', 'glMapNamedBufferEXT', 'glMapNamedBufferRangeEXT'):
283 print r' if (!__result) {'
284 print r' std::cerr << call.no << ": warning: failed to map buffer\n";'
285 print r' }'
José Fonseca91492d22011-05-23 21:20:31 +0100286 if function.name in ('glGetAttribLocation', 'glGetAttribLocationARB'):
287 print r' GLint __orig_result = call.ret->toSInt();'
288 print r' if (__result != __orig_result) {'
289 print r' std::cerr << call.no << ": warning vertex attrib location mismatch " << __orig_result << " -> " << __result << "\n";'
290 print r' }'
José Fonsecad5377812011-06-07 20:48:55 +0100291 if function.name in ('glCheckFramebufferStatus', 'glCheckFramebufferStatusEXT', 'glCheckNamedFramebufferStatusEXT'):
292 print r' GLint __orig_result = call.ret->toSInt();'
293 print r' if (__orig_result == GL_FRAMEBUFFER_COMPLETE &&'
294 print r' __result != GL_FRAMEBUFFER_COMPLETE) {'
295 print r' std::cerr << call.no << ": incomplete framebuffer (" << __result << ")\n";'
296 print r' }'
José Fonsecaecf37412011-05-21 01:56:08 +0100297 print ' }'
José Fonsecae4999b92011-05-05 00:31:01 +0100298
José Fonsecadacd8dd2010-11-25 17:50:26 +0000299 def extract_arg(self, function, arg, arg_type, lvalue, rvalue):
José Fonseca7f5163e2011-03-31 23:37:26 +0100300 if function.name in self.array_pointer_function_names and arg.name == 'pointer':
José Fonseca7ebb9e22011-05-06 09:58:45 +0100301 print ' %s = static_cast<%s>(%s.toPointer());' % (lvalue, arg_type, rvalue)
José Fonseca14c21bc2011-02-20 23:32:22 +0000302 return
303
304 if function.name in self.draw_elements_function_names and arg.name == 'indices':
José Fonsecafd34e4e2011-06-03 19:34:29 +0100305 self.extract_opaque_arg(function, arg, arg_type, lvalue, rvalue)
José Fonseca8a844ae2010-12-06 18:50:52 +0000306 return
José Fonsecadacd8dd2010-11-25 17:50:26 +0000307
José Fonsecac29f4f12011-06-11 12:19:05 +0100308 # Handle pointer with offsets into the current pack pixel buffer
309 # object.
310 if function.name in self.pack_function_names and arg.output:
311 self.extract_opaque_arg(function, arg, arg_type, lvalue, rvalue)
312 return
313
José Fonseca3c1b7ce2011-05-09 11:22:54 +0100314 if arg.type is glapi.GLlocation \
315 and 'program' not in [arg.name for arg in function.args]:
José Fonseca8a844ae2010-12-06 18:50:52 +0000316 print ' GLint program = -1;'
317 print ' glGetIntegerv(GL_CURRENT_PROGRAM, &program);'
José Fonseca3c1b7ce2011-05-09 11:22:54 +0100318
319 if arg.type is glapi.GLlocationARB \
320 and 'programObj' not in [arg.name for arg in function.args]:
José Fonseca3a84b682011-05-09 11:33:47 +0100321 print ' GLhandleARB programObj = glGetHandleARB(GL_PROGRAM_OBJECT_ARB);'
José Fonseca8a844ae2010-12-06 18:50:52 +0000322
323 Retracer.extract_arg(self, function, arg, arg_type, lvalue, rvalue)
José Fonsecae6a50bd2010-11-24 10:12:22 +0000324
José Fonseca42926462011-05-09 11:32:15 +0100325 # Don't try to use more samples than the implementation supports
326 if arg.name == 'samples':
327 assert arg.type is glapi.GLsizei
328 print ' GLint max_samples = 0;'
329 print ' glGetIntegerv(GL_MAX_SAMPLES, &max_samples);'
330 print ' if (samples > max_samples) {'
331 print ' samples = max_samples;'
332 print ' }'
333
José Fonsecae6a50bd2010-11-24 10:12:22 +0000334
José Fonseca7e329022010-11-19 17:05:18 +0000335if __name__ == '__main__':
José Fonseca796a3042010-11-29 14:21:06 +0000336 print r'''
José Fonseca867b1b72011-04-24 11:58:04 +0100337#include <string.h>
338
José Fonsecadf66a902010-11-29 13:24:20 +0000339#include "glproc.hpp"
José Fonseca32871ed2011-04-10 13:40:52 +0100340#include "glretrace.hpp"
José Fonseca589082d2011-03-30 09:10:40 +0100341
José Fonsecadf66a902010-11-29 13:24:20 +0000342
José Fonseca3d245f42010-11-28 00:08:23 +0000343'''
José Fonsecae0e61402010-11-25 15:03:23 +0000344 api = glapi.glapi
José Fonseca867b1b72011-04-24 11:58:04 +0100345 api.add_function(glapi.memcpy)
José Fonsecae0e61402010-11-25 15:03:23 +0000346 retracer = GlRetracer()
José Fonseca06aa2842011-05-05 07:55:54 +0100347 retracer.retrace_api(api)