José Fonseca | 7e32902 | 2010-11-19 17:05:18 +0000 | [diff] [blame] | 1 | ########################################################################## |
| 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é Fonseca | 4a826ed | 2010-11-30 16:58:22 +0000 | [diff] [blame] | 27 | """GL retracer generator.""" |
| 28 | |
| 29 | |
José Fonseca | ac3d464 | 2014-08-14 19:20:03 +0100 | [diff] [blame] | 30 | import re |
| 31 | import sys |
| 32 | |
José Fonseca | 9d27a54 | 2012-04-14 17:22:57 +0100 | [diff] [blame] | 33 | from retrace import Retracer |
José Fonseca | bd86a22 | 2011-09-27 09:21:38 +0100 | [diff] [blame] | 34 | import specs.stdapi as stdapi |
| 35 | import specs.glapi as glapi |
José Fonseca | 7e32902 | 2010-11-19 17:05:18 +0000 | [diff] [blame] | 36 | |
| 37 | |
José Fonseca | dacd8dd | 2010-11-25 17:50:26 +0000 | [diff] [blame] | 38 | class GlRetracer(Retracer): |
José Fonseca | c9edb83 | 2010-11-20 09:03:10 +0000 | [diff] [blame] | 39 | |
José Fonseca | 2741ed8 | 2011-10-07 23:36:39 +0100 | [diff] [blame] | 40 | table_name = 'glretrace::gl_callbacks' |
| 41 | |
José Fonseca | 9a24038 | 2014-11-12 22:32:17 +0000 | [diff] [blame] | 42 | def retraceApi(self, api): |
| 43 | # Ensure pack function have side effects |
| 44 | abort = False |
| 45 | for function in api.getAllFunctions(): |
Jose Fonseca | 0a676c5 | 2016-04-04 23:24:32 +0100 | [diff] [blame] | 46 | if not function.sideeffects: |
| 47 | if self.pack_function_regex.match(function.name) or \ |
| 48 | function.name.startswith('glGetQueryObject'): |
| 49 | sys.stderr.write('error: function %s must have sideeffects\n' % function.name) |
| 50 | abort = True |
José Fonseca | 9a24038 | 2014-11-12 22:32:17 +0000 | [diff] [blame] | 51 | if abort: |
| 52 | sys.exit(1) |
| 53 | |
| 54 | Retracer.retraceApi(self, api) |
José Fonseca | 3d245f4 | 2010-11-28 00:08:23 +0000 | [diff] [blame] | 55 | |
José Fonseca | 6221297 | 2011-03-23 13:22:55 +0000 | [diff] [blame] | 56 | array_pointer_function_names = set(( |
| 57 | "glVertexPointer", |
| 58 | "glNormalPointer", |
| 59 | "glColorPointer", |
| 60 | "glIndexPointer", |
| 61 | "glTexCoordPointer", |
| 62 | "glEdgeFlagPointer", |
| 63 | "glFogCoordPointer", |
| 64 | "glSecondaryColorPointer", |
| 65 | |
| 66 | "glInterleavedArrays", |
| 67 | |
José Fonseca | ac5285b | 2011-05-04 11:09:08 +0100 | [diff] [blame] | 68 | "glVertexPointerEXT", |
| 69 | "glNormalPointerEXT", |
| 70 | "glColorPointerEXT", |
| 71 | "glIndexPointerEXT", |
| 72 | "glTexCoordPointerEXT", |
| 73 | "glEdgeFlagPointerEXT", |
| 74 | "glFogCoordPointerEXT", |
| 75 | "glSecondaryColorPointerEXT", |
José Fonseca | 6221297 | 2011-03-23 13:22:55 +0000 | [diff] [blame] | 76 | |
José Fonseca | 7f5163e | 2011-03-31 23:37:26 +0100 | [diff] [blame] | 77 | "glVertexAttribPointer", |
| 78 | "glVertexAttribPointerARB", |
| 79 | "glVertexAttribPointerNV", |
José Fonseca | ac5285b | 2011-05-04 11:09:08 +0100 | [diff] [blame] | 80 | "glVertexAttribIPointer", |
| 81 | "glVertexAttribIPointerEXT", |
José Fonseca | 7f5163e | 2011-03-31 23:37:26 +0100 | [diff] [blame] | 82 | "glVertexAttribLPointer", |
| 83 | "glVertexAttribLPointerEXT", |
José Fonseca | 6221297 | 2011-03-23 13:22:55 +0000 | [diff] [blame] | 84 | |
| 85 | #"glMatrixIndexPointerARB", |
| 86 | )) |
| 87 | |
José Fonseca | ac3d464 | 2014-08-14 19:20:03 +0100 | [diff] [blame] | 88 | draw_arrays_function_regex = re.compile(r'^gl([A-Z][a-z]+)*Draw(Range)?Arrays([A-Z][a-zA-Z]*)?$' ) |
| 89 | draw_elements_function_regex = re.compile(r'^gl([A-Z][a-z]+)*Draw(Range)?Elements([A-Z][a-zA-Z]*)?$' ) |
| 90 | draw_indirect_function_regex = re.compile(r'^gl([A-Z][a-z]+)*Draw(Range)?(Arrays|Elements)Indirect([A-Z][a-zA-Z]*)?$' ) |
José Fonseca | 9b126ea | 2011-09-15 08:15:33 +0100 | [diff] [blame] | 91 | |
José Fonseca | e16ee25 | 2014-11-18 20:27:46 +0000 | [diff] [blame] | 92 | misc_draw_function_regex = re.compile(r'^gl(' + r'|'.join([ |
| 93 | r'CallList', |
| 94 | r'CallLists', |
| 95 | r'Clear', |
| 96 | r'End', |
| 97 | r'DrawPixels', |
José Fonseca | 1c968fd | 2014-12-30 20:58:42 +0000 | [diff] [blame] | 98 | r'DrawTransformFeedback([A-Z][a-zA-Z]*)?', |
José Fonseca | e16ee25 | 2014-11-18 20:27:46 +0000 | [diff] [blame] | 99 | r'BlitFramebuffer', |
José Fonseca | 1c968fd | 2014-12-30 20:58:42 +0000 | [diff] [blame] | 100 | r'Rect[dfis]v?', |
| 101 | r'EvalMesh[0-9]+', |
José Fonseca | e16ee25 | 2014-11-18 20:27:46 +0000 | [diff] [blame] | 102 | ]) + r')[0-9A-Z]*$') |
José Fonseca | 920bffd | 2011-06-02 10:04:52 +0100 | [diff] [blame] | 103 | |
José Fonseca | e16ee25 | 2014-11-18 20:27:46 +0000 | [diff] [blame] | 104 | |
| 105 | bind_framebuffer_function_regex = re.compile(r'^glBindFramebuffer[0-9A-Z]*$') |
José Fonseca | 920bffd | 2011-06-02 10:04:52 +0100 | [diff] [blame] | 106 | |
José Fonseca | c29f4f1 | 2011-06-11 12:19:05 +0100 | [diff] [blame] | 107 | # Names of the functions that can pack into the current pixel buffer |
| 108 | # object. See also the ARB_pixel_buffer_object specification. |
José Fonseca | 920f8e7 | 2014-11-12 21:31:59 +0000 | [diff] [blame] | 109 | pack_function_regex = re.compile(r'^gl(' + r'|'.join([ |
| 110 | r'Getn?Histogram', |
| 111 | r'Getn?PolygonStipple', |
| 112 | r'Getn?PixelMap[a-z]+v', |
| 113 | r'Getn?Minmax', |
| 114 | r'Getn?(Convolution|Separable)Filter', |
| 115 | r'Getn?(Compressed)?(Multi)?Tex(ture)?(Sub)?Image', |
| 116 | r'Readn?Pixels', |
| 117 | ]) + r')[0-9A-Z]*$') |
José Fonseca | c29f4f1 | 2011-06-11 12:19:05 +0100 | [diff] [blame] | 118 | |
José Fonseca | bd503ed | 2014-11-12 21:36:10 +0000 | [diff] [blame] | 119 | map_function_regex = re.compile(r'^glMap(|Named|Object)Buffer(Range)?[0-9A-Z]*$') |
José Fonseca | 46a4839 | 2011-10-14 11:34:27 +0100 | [diff] [blame] | 120 | |
José Fonseca | bd503ed | 2014-11-12 21:36:10 +0000 | [diff] [blame] | 121 | unmap_function_regex = re.compile(r'^glUnmap(|Named|Object)Buffer[0-9A-Z]*$') |
José Fonseca | 46a4839 | 2011-10-14 11:34:27 +0100 | [diff] [blame] | 122 | |
José Fonseca | 54f304a | 2012-01-14 19:33:08 +0000 | [diff] [blame] | 123 | def retraceFunctionBody(self, function): |
José Fonseca | 6221297 | 2011-03-23 13:22:55 +0000 | [diff] [blame] | 124 | is_array_pointer = function.name in self.array_pointer_function_names |
José Fonseca | ac3d464 | 2014-08-14 19:20:03 +0100 | [diff] [blame] | 125 | is_draw_arrays = self.draw_arrays_function_regex.match(function.name) is not None |
| 126 | is_draw_elements = self.draw_elements_function_regex.match(function.name) is not None |
| 127 | is_draw_indirect = self.draw_indirect_function_regex.match(function.name) is not None |
José Fonseca | e16ee25 | 2014-11-18 20:27:46 +0000 | [diff] [blame] | 128 | is_misc_draw = self.misc_draw_function_regex.match(function.name) |
José Fonseca | 6221297 | 2011-03-23 13:22:55 +0000 | [diff] [blame] | 129 | |
Jose Fonseca | 0a676c5 | 2016-04-04 23:24:32 +0100 | [diff] [blame] | 130 | if function.name.startswith('gl') and not function.name.startswith('glX'): |
| 131 | # The Windows OpenGL runtime will skip calls when there's no |
| 132 | # context bound to the current context, but this might cause |
| 133 | # crashes on other systems, particularly with NVIDIA Linux drivers. |
Piotr Podsiadły | 0b8b019 | 2019-01-03 20:39:55 +0100 | [diff] [blame] | 134 | print(r' glretrace::Context *currentContext = glretrace::getCurrentContext();') |
| 135 | print(r' if (!currentContext) {') |
| 136 | print(r' if (retrace::debug > 0) {') |
| 137 | print(r' retrace::warning(call) << "no current context\n";') |
| 138 | print(r' }') |
| 139 | print(r'#ifndef _WIN32') |
| 140 | print(r' return;') |
| 141 | print(r'#endif') |
| 142 | print(r' }') |
Jose Fonseca | 0a676c5 | 2016-04-04 23:24:32 +0100 | [diff] [blame] | 143 | |
Piotr Podsiadły | 0b8b019 | 2019-01-03 20:39:55 +0100 | [diff] [blame] | 144 | print(r' if (retrace::markers) {') |
| 145 | print(r' glretrace::insertCallMarker(call, currentContext);') |
| 146 | print(r' }') |
Jose Fonseca | 0a676c5 | 2016-04-04 23:24:32 +0100 | [diff] [blame] | 147 | |
José Fonseca | ac3d464 | 2014-08-14 19:20:03 +0100 | [diff] [blame] | 148 | # For backwards compatibility with old traces where non VBO drawing was supported |
| 149 | if (is_array_pointer or is_draw_arrays or is_draw_elements) and not is_draw_indirect: |
Piotr Podsiadły | 0b8b019 | 2019-01-03 20:39:55 +0100 | [diff] [blame] | 150 | print(' if (retrace::parser->getVersion() < 1) {') |
José Fonseca | 6221297 | 2011-03-23 13:22:55 +0000 | [diff] [blame] | 151 | |
José Fonseca | ac3d464 | 2014-08-14 19:20:03 +0100 | [diff] [blame] | 152 | if is_array_pointer or is_draw_arrays: |
Piotr Podsiadły | 0b8b019 | 2019-01-03 20:39:55 +0100 | [diff] [blame] | 153 | print(' GLint _array_buffer = 0;') |
| 154 | print(' glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &_array_buffer);') |
| 155 | print(' if (!_array_buffer) {') |
José Fonseca | 54f304a | 2012-01-14 19:33:08 +0000 | [diff] [blame] | 156 | self.failFunction(function) |
Piotr Podsiadły | 0b8b019 | 2019-01-03 20:39:55 +0100 | [diff] [blame] | 157 | print(' }') |
José Fonseca | 6221297 | 2011-03-23 13:22:55 +0000 | [diff] [blame] | 158 | |
| 159 | if is_draw_elements: |
Piotr Podsiadły | 0b8b019 | 2019-01-03 20:39:55 +0100 | [diff] [blame] | 160 | print(' GLint _element_array_buffer = 0;') |
| 161 | print(' glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &_element_array_buffer);') |
| 162 | print(' if (!_element_array_buffer) {') |
José Fonseca | 54f304a | 2012-01-14 19:33:08 +0000 | [diff] [blame] | 163 | self.failFunction(function) |
Piotr Podsiadły | 0b8b019 | 2019-01-03 20:39:55 +0100 | [diff] [blame] | 164 | print(' }') |
José Fonseca | 6221297 | 2011-03-23 13:22:55 +0000 | [diff] [blame] | 165 | |
Piotr Podsiadły | 0b8b019 | 2019-01-03 20:39:55 +0100 | [diff] [blame] | 166 | print(' }') |
José Fonseca | 6221297 | 2011-03-23 13:22:55 +0000 | [diff] [blame] | 167 | |
José Fonseca | c29f4f1 | 2011-06-11 12:19:05 +0100 | [diff] [blame] | 168 | # When no pack buffer object is bound, the pack functions are no-ops. |
José Fonseca | 920f8e7 | 2014-11-12 21:31:59 +0000 | [diff] [blame] | 169 | if self.pack_function_regex.match(function.name): |
Piotr Podsiadły | 0b8b019 | 2019-01-03 20:39:55 +0100 | [diff] [blame] | 170 | print(r' GLint _pack_buffer = 0;') |
Jose Fonseca | 4b44839 | 2019-08-22 11:04:53 +0100 | [diff] [blame] | 171 | print(r' if (currentContext && currentContext->features().pixel_buffer_object) {') |
Piotr Podsiadły | 0b8b019 | 2019-01-03 20:39:55 +0100 | [diff] [blame] | 172 | print(r' glGetIntegerv(GL_PIXEL_PACK_BUFFER_BINDING, &_pack_buffer);') |
| 173 | print(r' }') |
| 174 | print(r' if (!_pack_buffer) {') |
| 175 | print(r' return;') |
| 176 | print(r' }') |
José Fonseca | c29f4f1 | 2011-06-11 12:19:05 +0100 | [diff] [blame] | 177 | |
Jose Fonseca | 0a676c5 | 2016-04-04 23:24:32 +0100 | [diff] [blame] | 178 | # When no query buffer object is bound, glGetQueryObject is a no-op. |
| 179 | if function.name.startswith('glGetQueryObject'): |
Piotr Podsiadły | 0b8b019 | 2019-01-03 20:39:55 +0100 | [diff] [blame] | 180 | print(r' GLint _query_buffer = 0;') |
Jose Fonseca | 4b44839 | 2019-08-22 11:04:53 +0100 | [diff] [blame] | 181 | print(r' if (currentContext && currentContext->features().query_buffer_object) {') |
Piotr Podsiadły | 0b8b019 | 2019-01-03 20:39:55 +0100 | [diff] [blame] | 182 | print(r' glGetIntegerv(GL_QUERY_BUFFER_BINDING, &_query_buffer);') |
| 183 | print(r' }') |
| 184 | print(r' if (!_query_buffer) {') |
| 185 | print(r' return;') |
| 186 | print(r' }') |
Jose Fonseca | 0a676c5 | 2016-04-04 23:24:32 +0100 | [diff] [blame] | 187 | |
José Fonseca | 920bffd | 2011-06-02 10:04:52 +0100 | [diff] [blame] | 188 | # Pre-snapshots |
José Fonseca | e16ee25 | 2014-11-18 20:27:46 +0000 | [diff] [blame] | 189 | if self.bind_framebuffer_function_regex.match(function.name): |
Piotr Podsiadły | 0b8b019 | 2019-01-03 20:39:55 +0100 | [diff] [blame] | 190 | print(' assert(call.flags & trace::CALL_FLAG_SWAP_RENDERTARGET);') |
José Fonseca | 3ee3cd4 | 2013-10-29 19:28:31 +0000 | [diff] [blame] | 191 | if function.name == 'glStringMarkerGREMEDY': |
| 192 | return |
José Fonseca | 439ae3c | 2011-09-01 17:36:10 +0100 | [diff] [blame] | 193 | if function.name == 'glFrameTerminatorGREMEDY': |
Piotr Podsiadły | 0b8b019 | 2019-01-03 20:39:55 +0100 | [diff] [blame] | 194 | print(' glretrace::frame_complete(call);') |
José Fonseca | 439ae3c | 2011-09-01 17:36:10 +0100 | [diff] [blame] | 195 | return |
José Fonseca | 920bffd | 2011-06-02 10:04:52 +0100 | [diff] [blame] | 196 | |
José Fonseca | 54f304a | 2012-01-14 19:33:08 +0000 | [diff] [blame] | 197 | Retracer.retraceFunctionBody(self, function) |
José Fonseca | 6221297 | 2011-03-23 13:22:55 +0000 | [diff] [blame] | 198 | |
José Fonseca | 920bffd | 2011-06-02 10:04:52 +0100 | [diff] [blame] | 199 | # Post-snapshots |
José Fonseca | 4d7f1fe | 2011-05-09 20:54:31 +0100 | [diff] [blame] | 200 | if function.name in ('glFlush', 'glFinish'): |
Piotr Podsiadły | 0b8b019 | 2019-01-03 20:39:55 +0100 | [diff] [blame] | 201 | print(' if (!retrace::doubleBuffer) {') |
| 202 | print(' glretrace::frame_complete(call);') |
| 203 | print(' }') |
José Fonseca | ac3d464 | 2014-08-14 19:20:03 +0100 | [diff] [blame] | 204 | if is_draw_arrays or is_draw_elements or is_misc_draw: |
Piotr Podsiadły | 0b8b019 | 2019-01-03 20:39:55 +0100 | [diff] [blame] | 205 | print(' assert(call.flags & trace::CALL_FLAG_RENDER);') |
José Fonseca | 920bffd | 2011-06-02 10:04:52 +0100 | [diff] [blame] | 206 | |
José Fonseca | 4d7f1fe | 2011-05-09 20:54:31 +0100 | [diff] [blame] | 207 | |
José Fonseca | 54f304a | 2012-01-14 19:33:08 +0000 | [diff] [blame] | 208 | def invokeFunction(self, function): |
Mark Janes | 35b2536 | 2020-01-02 20:47:44 -0800 | [diff] [blame] | 209 | if function.name == "glGetActiveUniformBlockName": |
| 210 | print(' std::vector<GLchar> name_buf(bufSize);') |
| 211 | print(' uniformBlockName = name_buf.data();') |
| 212 | print(' const auto traced_name = (const GLchar *)((call.arg(4)).toString());') |
| 213 | print(' glretrace::mapUniformBlockName(program, (call.arg(1)).toSInt(), traced_name, _uniformBlock_map);') |
Mark Janes | 95feab7 | 2019-12-20 17:01:56 -0800 | [diff] [blame] | 214 | if function.name == "glGetProgramResourceName": |
| 215 | print(' std::vector<GLchar> name_buf(bufSize);') |
| 216 | print(' name = name_buf.data();') |
| 217 | print(' const auto traced_name = (const GLchar *)((call.arg(5)).toString());') |
| 218 | print(' glretrace::trackResourceName(program, programInterface, index, traced_name);') |
| 219 | if function.name == "glGetProgramResourceiv": |
| 220 | print(' glretrace::mapResourceLocation(program, programInterface, index, call.arg(4).toArray(), call.arg(7).toArray(), _location_map);') |
José Fonseca | 757b2b6 | 2011-09-19 10:09:53 +0100 | [diff] [blame] | 221 | # Infer the drawable size from GL calls |
José Fonseca | cdb574a | 2010-11-29 12:23:35 +0000 | [diff] [blame] | 222 | if function.name == "glViewport": |
Piotr Podsiadły | 0b8b019 | 2019-01-03 20:39:55 +0100 | [diff] [blame] | 223 | print(' glretrace::updateDrawable(x + width, y + height);') |
Jose Fonseca | f89d3d7 | 2016-12-02 15:14:06 +0000 | [diff] [blame] | 224 | if function.name == "glViewportArrayv": |
José Fonseca | ea82c3f | 2012-03-29 08:19:19 +0100 | [diff] [blame] | 225 | # We are concerned about drawables so only care for the first viewport |
Piotr Podsiadły | 0b8b019 | 2019-01-03 20:39:55 +0100 | [diff] [blame] | 226 | print(' if (first == 0 && count > 0) {') |
| 227 | print(' GLfloat x = v[0], y = v[1], w = v[2], h = v[3];') |
| 228 | print(' glretrace::updateDrawable(x + w, y + h);') |
| 229 | print(' }') |
José Fonseca | ea82c3f | 2012-03-29 08:19:19 +0100 | [diff] [blame] | 230 | if function.name == "glViewportIndexedf": |
Piotr Podsiadły | 0b8b019 | 2019-01-03 20:39:55 +0100 | [diff] [blame] | 231 | print(' if (index == 0) {') |
| 232 | print(' glretrace::updateDrawable(x + w, y + h);') |
| 233 | print(' }') |
José Fonseca | ea82c3f | 2012-03-29 08:19:19 +0100 | [diff] [blame] | 234 | if function.name == "glViewportIndexedfv": |
Piotr Podsiadły | 0b8b019 | 2019-01-03 20:39:55 +0100 | [diff] [blame] | 235 | print(' if (index == 0) {') |
| 236 | print(' GLfloat x = v[0], y = v[1], w = v[2], h = v[3];') |
| 237 | print(' glretrace::updateDrawable(x + w, y + h);') |
| 238 | print(' }') |
José Fonseca | 757b2b6 | 2011-09-19 10:09:53 +0100 | [diff] [blame] | 239 | if function.name in ('glBlitFramebuffer', 'glBlitFramebufferEXT'): |
| 240 | # Some applications do all their rendering in a framebuffer, and |
| 241 | # then just blit to the drawable without ever calling glViewport. |
Piotr Podsiadły | 0b8b019 | 2019-01-03 20:39:55 +0100 | [diff] [blame] | 242 | print(' glretrace::updateDrawable(std::max(dstX0, dstX1), std::max(dstY0, dstY1));') |
José Fonseca | cdb574a | 2010-11-29 12:23:35 +0000 | [diff] [blame] | 243 | |
Jose Fonseca | 12b8217 | 2015-08-06 13:41:54 +0100 | [diff] [blame] | 244 | if function.name == "glEnd": |
Piotr Podsiadły | 0b8b019 | 2019-01-03 20:39:55 +0100 | [diff] [blame] | 245 | print(r' if (currentContext) {') |
| 246 | print(r' currentContext->insideBeginEnd = false;') |
| 247 | print(r' }') |
José Fonseca | ae9c4c1 | 2012-02-02 13:59:31 +0000 | [diff] [blame] | 248 | |
José Fonseca | fea81f9 | 2011-05-23 21:20:53 +0100 | [diff] [blame] | 249 | if function.name == 'memcpy': |
Piotr Podsiadły | 0b8b019 | 2019-01-03 20:39:55 +0100 | [diff] [blame] | 250 | print(' if (!dest || !src || !n) return;') |
José Fonseca | 694dc0b | 2012-03-01 15:44:07 +0000 | [diff] [blame] | 251 | |
Gregory Hainaut | 8ac8b6b | 2012-06-11 13:58:22 +0100 | [diff] [blame] | 252 | # Skip glEnable/Disable(GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB) as we don't |
| 253 | # faithfully set the CONTEXT_DEBUG_BIT_ARB flags on context creation. |
| 254 | if function.name in ('glEnable', 'glDisable'): |
Piotr Podsiadły | 0b8b019 | 2019-01-03 20:39:55 +0100 | [diff] [blame] | 255 | print(' if (cap == GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB) return;') |
Gregory Hainaut | 8ac8b6b | 2012-06-11 13:58:22 +0100 | [diff] [blame] | 256 | |
José Fonseca | 694dc0b | 2012-03-01 15:44:07 +0000 | [diff] [blame] | 257 | # Destroy the buffer mapping |
José Fonseca | bd503ed | 2014-11-12 21:36:10 +0000 | [diff] [blame] | 258 | if self.unmap_function_regex.match(function.name): |
Piotr Podsiadły | 0b8b019 | 2019-01-03 20:39:55 +0100 | [diff] [blame] | 259 | print(r' GLvoid *ptr = NULL;') |
José Fonseca | 694dc0b | 2012-03-01 15:44:07 +0000 | [diff] [blame] | 260 | if function.name == 'glUnmapBuffer': |
Piotr Podsiadły | 0b8b019 | 2019-01-03 20:39:55 +0100 | [diff] [blame] | 261 | print(r' glGetBufferPointerv(target, GL_BUFFER_MAP_POINTER, &ptr);') |
José Fonseca | 694dc0b | 2012-03-01 15:44:07 +0000 | [diff] [blame] | 262 | elif function.name == 'glUnmapBufferARB': |
Piotr Podsiadły | 0b8b019 | 2019-01-03 20:39:55 +0100 | [diff] [blame] | 263 | print(r' glGetBufferPointervARB(target, GL_BUFFER_MAP_POINTER_ARB, &ptr);') |
José Fonseca | 694dc0b | 2012-03-01 15:44:07 +0000 | [diff] [blame] | 264 | elif function.name == 'glUnmapBufferOES': |
Piotr Podsiadły | 0b8b019 | 2019-01-03 20:39:55 +0100 | [diff] [blame] | 265 | print(r' glGetBufferPointervOES(target, GL_BUFFER_MAP_POINTER_OES, &ptr);') |
José Fonseca | 4920c30 | 2014-08-13 18:35:57 +0100 | [diff] [blame] | 266 | elif function.name == 'glUnmapNamedBuffer': |
Piotr Podsiadły | 0b8b019 | 2019-01-03 20:39:55 +0100 | [diff] [blame] | 267 | print(r' glGetNamedBufferPointerv(buffer, GL_BUFFER_MAP_POINTER, &ptr);') |
José Fonseca | 694dc0b | 2012-03-01 15:44:07 +0000 | [diff] [blame] | 268 | elif function.name == 'glUnmapNamedBufferEXT': |
Piotr Podsiadły | 0b8b019 | 2019-01-03 20:39:55 +0100 | [diff] [blame] | 269 | print(r' glGetNamedBufferPointervEXT(buffer, GL_BUFFER_MAP_POINTER, &ptr);') |
José Fonseca | cbc859f | 2012-04-05 19:55:53 +0100 | [diff] [blame] | 270 | elif function.name == 'glUnmapObjectBufferATI': |
| 271 | # TODO |
| 272 | pass |
José Fonseca | 694dc0b | 2012-03-01 15:44:07 +0000 | [diff] [blame] | 273 | else: |
| 274 | assert False |
Piotr Podsiadły | 0b8b019 | 2019-01-03 20:39:55 +0100 | [diff] [blame] | 275 | print(r' if (ptr) {') |
| 276 | print(r' retrace::delRegionByPointer(ptr);') |
| 277 | print(r' } else {') |
| 278 | print(r' retrace::warning(call) << "failed to get mapped pointer\n";') |
| 279 | print(r' }') |
Gregory Hainaut | b79e26a | 2012-05-11 14:49:10 +0100 | [diff] [blame] | 280 | |
Nicolai Hähnle | 019ebe2 | 2016-06-07 13:19:44 +0100 | [diff] [blame] | 281 | # Implicit destruction of buffer mappings |
| 282 | # TODO: handle BufferData variants |
| 283 | # TODO: don't rely on GL_ARB_direct_state_access |
| 284 | if function.name in ('glDeleteBuffers', 'glDeleteBuffersARB'): |
Jose Fonseca | 4b44839 | 2019-08-22 11:04:53 +0100 | [diff] [blame] | 285 | print(r' if (currentContext && currentContext->features().ARB_direct_state_access) {') |
Piotr Podsiadły | 0b8b019 | 2019-01-03 20:39:55 +0100 | [diff] [blame] | 286 | print(r' for (GLsizei i = 0; i < n; ++i) {') |
| 287 | print(r' GLvoid *ptr = nullptr;') |
| 288 | print(r' glGetNamedBufferPointerv(buffers[i], GL_BUFFER_MAP_POINTER, &ptr);') |
| 289 | print(r' if (ptr) {') |
| 290 | print(r' retrace::delRegionByPointer(ptr);') |
| 291 | print(r' }') |
| 292 | print(r' }') |
| 293 | print(r' }') |
Nicolai Hähnle | 019ebe2 | 2016-06-07 13:19:44 +0100 | [diff] [blame] | 294 | |
Jose Fonseca | e99df40 | 2015-12-22 12:31:20 +0000 | [diff] [blame] | 295 | if function.name.startswith('glCopyImageSubData'): |
Piotr Podsiadły | 0b8b019 | 2019-01-03 20:39:55 +0100 | [diff] [blame] | 296 | print(r' if (srcTarget == GL_RENDERBUFFER || dstTarget == GL_RENDERBUFFER) {') |
| 297 | print(r' retrace::warning(call) << " renderbuffer targets unsupported (https://github.com/apitrace/apitrace/issues/404)\n";') |
| 298 | print(r' }') |
Jose Fonseca | e99df40 | 2015-12-22 12:31:20 +0000 | [diff] [blame] | 299 | |
Jose Fonseca | ae3c638 | 2015-04-25 06:52:33 +0100 | [diff] [blame] | 300 | is_draw_arrays = self.draw_arrays_function_regex.match(function.name) is not None |
| 301 | is_draw_elements = self.draw_elements_function_regex.match(function.name) is not None |
| 302 | is_misc_draw = self.misc_draw_function_regex.match(function.name) is not None |
| 303 | |
James Benton | addf7f9 | 2012-07-20 18:56:19 +0100 | [diff] [blame] | 304 | profileDraw = ( |
Jose Fonseca | ae3c638 | 2015-04-25 06:52:33 +0100 | [diff] [blame] | 305 | is_draw_arrays or |
| 306 | is_draw_elements or |
| 307 | is_misc_draw or |
Jose Fonseca | 9c8857d | 2016-03-05 22:14:00 +0000 | [diff] [blame] | 308 | function.name == 'glBegin' or |
| 309 | function.name.startswith('glDispatchCompute') |
James Benton | addf7f9 | 2012-07-20 18:56:19 +0100 | [diff] [blame] | 310 | ) |
| 311 | |
Jose Fonseca | 8e0a030 | 2016-05-04 23:53:46 +0100 | [diff] [blame] | 312 | # Keep track of current program/pipeline |
James Benton | 6d92327 | 2012-07-25 13:48:20 +0100 | [diff] [blame] | 313 | if function.name in ('glUseProgram', 'glUseProgramObjectARB'): |
Piotr Podsiadły | 0b8b019 | 2019-01-03 20:39:55 +0100 | [diff] [blame] | 314 | print(r' if (currentContext) {') |
| 315 | print(r' currentContext->currentUserProgram = call.arg(0).toUInt();') |
| 316 | print(r' currentContext->currentProgram = %s;' % function.args[0].name) |
| 317 | print(r' }') |
Jose Fonseca | 8e0a030 | 2016-05-04 23:53:46 +0100 | [diff] [blame] | 318 | if function.name in ('glBindProgramPipeline', 'glBindProgramPipelineEXT'): |
Piotr Podsiadły | 0b8b019 | 2019-01-03 20:39:55 +0100 | [diff] [blame] | 319 | print(r' if (currentContext) {') |
| 320 | print(r' currentContext->currentPipeline = %s;' % function.args[0].name) |
| 321 | print(r' }') |
James Benton | 6d92327 | 2012-07-25 13:48:20 +0100 | [diff] [blame] | 322 | |
| 323 | # Only profile if not inside a list as the queries get inserted into list |
James Benton | addf7f9 | 2012-07-20 18:56:19 +0100 | [diff] [blame] | 324 | if function.name == 'glNewList': |
Piotr Podsiadły | 0b8b019 | 2019-01-03 20:39:55 +0100 | [diff] [blame] | 325 | print(r' if (currentContext) {') |
| 326 | print(r' currentContext->insideList = true;') |
| 327 | print(r' }') |
James Benton | addf7f9 | 2012-07-20 18:56:19 +0100 | [diff] [blame] | 328 | |
| 329 | if function.name == 'glEndList': |
Piotr Podsiadły | 0b8b019 | 2019-01-03 20:39:55 +0100 | [diff] [blame] | 330 | print(r' if (currentContext) {') |
| 331 | print(r' currentContext->insideList = false;') |
| 332 | print(r' }') |
James Benton | addf7f9 | 2012-07-20 18:56:19 +0100 | [diff] [blame] | 333 | |
Jose Fonseca | ae3c638 | 2015-04-25 06:52:33 +0100 | [diff] [blame] | 334 | if function.name == 'glBegin' or \ |
| 335 | is_draw_arrays or \ |
| 336 | is_draw_elements or \ |
| 337 | function.name.startswith('glBeginTransformFeedback'): |
Piotr Podsiadły | 0b8b019 | 2019-01-03 20:39:55 +0100 | [diff] [blame] | 338 | print(r' if (retrace::debug > 0) {') |
| 339 | print(r' _validateActiveProgram(call);') |
| 340 | print(r' }') |
Jose Fonseca | 21b8f33 | 2015-04-24 22:43:23 +0100 | [diff] [blame] | 341 | |
James Benton | c53c649 | 2012-08-13 18:21:16 +0100 | [diff] [blame] | 342 | if function.name != 'glEnd': |
Piotr Podsiadły | 0b8b019 | 2019-01-03 20:39:55 +0100 | [diff] [blame] | 343 | print(r' if (currentContext && !currentContext->insideList && !currentContext->insideBeginEnd && retrace::profiling) {') |
James Benton | c53c649 | 2012-08-13 18:21:16 +0100 | [diff] [blame] | 344 | if profileDraw: |
Piotr Podsiadły | 0b8b019 | 2019-01-03 20:39:55 +0100 | [diff] [blame] | 345 | print(r' glretrace::beginProfile(call, true);') |
James Benton | c53c649 | 2012-08-13 18:21:16 +0100 | [diff] [blame] | 346 | else: |
Piotr Podsiadły | 0b8b019 | 2019-01-03 20:39:55 +0100 | [diff] [blame] | 347 | print(r' glretrace::beginProfile(call, false);') |
| 348 | print(r' }') |
James Benton | addf7f9 | 2012-07-20 18:56:19 +0100 | [diff] [blame] | 349 | |
José Fonseca | 474c502 | 2015-01-29 12:02:03 +0000 | [diff] [blame] | 350 | if function.name in ('glCreateShaderProgramv', 'glCreateShaderProgramEXT', 'glCreateShaderProgramvEXT'): |
| 351 | # When dumping state, break down glCreateShaderProgram* so that the |
José Fonseca | 3db3b2f | 2012-05-11 14:55:50 +0100 | [diff] [blame] | 352 | # shader source can be recovered. |
Piotr Podsiadły | 0b8b019 | 2019-01-03 20:39:55 +0100 | [diff] [blame] | 353 | print(r' if (retrace::dumpingState) {') |
| 354 | print(r' GLuint _shader = glCreateShader(type);') |
| 355 | print(r' if (_shader) {') |
José Fonseca | 474c502 | 2015-01-29 12:02:03 +0000 | [diff] [blame] | 356 | if not function.name.startswith('glCreateShaderProgramv'): |
Piotr Podsiadły | 0b8b019 | 2019-01-03 20:39:55 +0100 | [diff] [blame] | 357 | print(r' GLsizei count = 1;') |
| 358 | print(r' const GLchar **strings = &string;') |
| 359 | print(r' glShaderSource(_shader, count, strings, NULL);') |
| 360 | print(r' glCompileShader(_shader);') |
| 361 | print(r' const GLuint _program = glCreateProgram();') |
| 362 | print(r' if (_program) {') |
| 363 | print(r' GLint compiled = GL_FALSE;') |
| 364 | print(r' glGetShaderiv(_shader, GL_COMPILE_STATUS, &compiled);') |
José Fonseca | 474c502 | 2015-01-29 12:02:03 +0000 | [diff] [blame] | 365 | if function.name == 'glCreateShaderProgramvEXT': |
Piotr Podsiadły | 0b8b019 | 2019-01-03 20:39:55 +0100 | [diff] [blame] | 366 | print(r' glProgramParameteriEXT(_program, GL_PROGRAM_SEPARABLE, GL_TRUE);') |
José Fonseca | 474c502 | 2015-01-29 12:02:03 +0000 | [diff] [blame] | 367 | else: |
Piotr Podsiadły | 0b8b019 | 2019-01-03 20:39:55 +0100 | [diff] [blame] | 368 | print(r' glProgramParameteri(_program, GL_PROGRAM_SEPARABLE, GL_TRUE);') |
| 369 | print(r' if (compiled) {') |
| 370 | print(r' glAttachShader(_program, _shader);') |
| 371 | print(r' glLinkProgram(_program);') |
| 372 | print(r' if (false) glDetachShader(_program, _shader);') |
| 373 | print(r' }') |
| 374 | print(r' // TODO: append shader info log to program info log') |
| 375 | print(r' }') |
| 376 | print(r' glDeleteShader(_shader);') |
| 377 | print(r' _result = _program;') |
| 378 | print(r' } else {') |
| 379 | print(r' _result = 0;') |
| 380 | print(r' }') |
| 381 | print(r' } else {') |
José Fonseca | 3db3b2f | 2012-05-11 14:55:50 +0100 | [diff] [blame] | 382 | Retracer.invokeFunction(self, function) |
Piotr Podsiadły | 0b8b019 | 2019-01-03 20:39:55 +0100 | [diff] [blame] | 383 | print(r' }') |
José Fonseca | a4d4d77 | 2015-01-29 15:20:11 +0000 | [diff] [blame] | 384 | elif function.name in ('glDetachShader', 'glDetachObjectARB'): |
Piotr Podsiadły | 0b8b019 | 2019-01-03 20:39:55 +0100 | [diff] [blame] | 385 | print(r' if (!retrace::dumpingState) {') |
gregory | a468a7a | 2012-07-01 16:30:08 +0200 | [diff] [blame] | 386 | Retracer.invokeFunction(self, function) |
Piotr Podsiadły | 0b8b019 | 2019-01-03 20:39:55 +0100 | [diff] [blame] | 387 | print(r' }') |
José Fonseca | 04e95f6 | 2014-12-12 21:09:21 +0000 | [diff] [blame] | 388 | elif function.name == 'glClientWaitSync': |
Piotr Podsiadły | 0b8b019 | 2019-01-03 20:39:55 +0100 | [diff] [blame] | 389 | print(r' _result = glretrace::clientWaitSync(call, sync, flags, timeout);') |
| 390 | print(r' (void)_result;') |
José Fonseca | 04e95f6 | 2014-12-12 21:09:21 +0000 | [diff] [blame] | 391 | elif function.name == 'glGetSynciv': |
Piotr Podsiadły | 0b8b019 | 2019-01-03 20:39:55 +0100 | [diff] [blame] | 392 | print(r' if (pname == GL_SYNC_STATUS &&') |
| 393 | print(r' bufSize >= 1 &&') |
| 394 | print(r' values != NULL &&') |
| 395 | print(r' call.arg(4)[0].toSInt() == GL_SIGNALED) {') |
| 396 | print(r' // Fence was signalled, so ensure it happened here') |
| 397 | print(r' glretrace::blockOnFence(call, sync, GL_SYNC_FLUSH_COMMANDS_BIT);') |
| 398 | print(r' (void)length;') |
| 399 | print(r' }') |
José Fonseca | 3db3b2f | 2012-05-11 14:55:50 +0100 | [diff] [blame] | 400 | else: |
| 401 | Retracer.invokeFunction(self, function) |
José Fonseca | cdb574a | 2010-11-29 12:23:35 +0000 | [diff] [blame] | 402 | |
Jose Fonseca | a7caf01 | 2016-04-14 07:11:12 +0100 | [diff] [blame] | 403 | # Ensure this context flushes before switching to another thread to |
| 404 | # prevent deadlock. |
| 405 | # TODO: Defer flushing until another thread actually invokes |
| 406 | # ClientWaitSync. |
| 407 | if function.name.startswith("glFenceSync"): |
Piotr Podsiadły | 0b8b019 | 2019-01-03 20:39:55 +0100 | [diff] [blame] | 408 | print(' if (currentContext) {') |
| 409 | print(' currentContext->needsFlush = true;') |
| 410 | print(' }') |
Jose Fonseca | a7caf01 | 2016-04-14 07:11:12 +0100 | [diff] [blame] | 411 | if function.name in ("glFlush", "glFinish"): |
Piotr Podsiadły | 0b8b019 | 2019-01-03 20:39:55 +0100 | [diff] [blame] | 412 | print(' if (currentContext) {') |
| 413 | print(' currentContext->needsFlush = false;') |
| 414 | print(' }') |
Jose Fonseca | a7caf01 | 2016-04-14 07:11:12 +0100 | [diff] [blame] | 415 | |
James Benton | d852eae | 2012-08-10 15:56:18 +0100 | [diff] [blame] | 416 | if function.name == "glBegin": |
Piotr Podsiadły | 0b8b019 | 2019-01-03 20:39:55 +0100 | [diff] [blame] | 417 | print(' if (currentContext) {') |
| 418 | print(' currentContext->insideBeginEnd = true;') |
| 419 | print(' }') |
James Benton | d852eae | 2012-08-10 15:56:18 +0100 | [diff] [blame] | 420 | |
Piotr Podsiadły | 0b8b019 | 2019-01-03 20:39:55 +0100 | [diff] [blame] | 421 | print(r' if (currentContext && !currentContext->insideList && !currentContext->insideBeginEnd && retrace::profiling) {') |
James Benton | c53c649 | 2012-08-13 18:21:16 +0100 | [diff] [blame] | 422 | if profileDraw: |
Piotr Podsiadły | 0b8b019 | 2019-01-03 20:39:55 +0100 | [diff] [blame] | 423 | print(r' glretrace::endProfile(call, true);') |
James Benton | c53c649 | 2012-08-13 18:21:16 +0100 | [diff] [blame] | 424 | else: |
Piotr Podsiadły | 0b8b019 | 2019-01-03 20:39:55 +0100 | [diff] [blame] | 425 | print(r' glretrace::endProfile(call, false);') |
| 426 | print(r' }') |
James Benton | addf7f9 | 2012-07-20 18:56:19 +0100 | [diff] [blame] | 427 | |
José Fonseca | ecf3741 | 2011-05-21 01:56:08 +0100 | [diff] [blame] | 428 | # Error checking |
James Benton | d852eae | 2012-08-10 15:56:18 +0100 | [diff] [blame] | 429 | if function.name.startswith('gl'): |
José Fonseca | 3d245f4 | 2010-11-28 00:08:23 +0000 | [diff] [blame] | 430 | # glGetError is not allowed inside glBegin/glEnd |
Piotr Podsiadły | 0b8b019 | 2019-01-03 20:39:55 +0100 | [diff] [blame] | 431 | print(' if (retrace::debug > 0 && currentContext && !currentContext->insideBeginEnd) {') |
| 432 | print(' glretrace::checkGlError(call);') |
José Fonseca | 8f39c87 | 2015-01-25 22:20:15 +0000 | [diff] [blame] | 433 | if function.name in ('glProgramStringARB', 'glLoadProgramNV'): |
Piotr Podsiadły | 0b8b019 | 2019-01-03 20:39:55 +0100 | [diff] [blame] | 434 | print(r' GLint error_position = -1;') |
| 435 | print(r' glGetIntegerv(GL_PROGRAM_ERROR_POSITION_ARB, &error_position);') |
| 436 | print(r' if (error_position != -1) {') |
| 437 | print(r' const char *error_string = (const char *)glGetString(GL_PROGRAM_ERROR_STRING_ARB);') |
| 438 | print(r' retrace::warning(call) << "error in position " << error_position << ": " << error_string << "\n";') |
| 439 | print(r' }') |
José Fonseca | ecf3741 | 2011-05-21 01:56:08 +0100 | [diff] [blame] | 440 | if function.name == 'glCompileShader': |
Piotr Podsiadły | 0b8b019 | 2019-01-03 20:39:55 +0100 | [diff] [blame] | 441 | print(r' GLint compile_status = 0;') |
| 442 | print(r' glGetShaderiv(shader, GL_COMPILE_STATUS, &compile_status);') |
| 443 | print(r' if (!compile_status) {') |
| 444 | print(r' retrace::warning(call) << "compilation failed\n";') |
| 445 | print(r' }') |
| 446 | print(r' GLint info_log_length = 0;') |
| 447 | print(r' glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &info_log_length);') |
| 448 | print(r' if (info_log_length > 1) {') |
| 449 | print(r' GLchar *infoLog = new GLchar[info_log_length];') |
| 450 | print(r' glGetShaderInfoLog(shader, info_log_length, NULL, infoLog);') |
| 451 | print(r' retrace::warning(call) << infoLog << "\n";') |
| 452 | print(r' delete [] infoLog;') |
| 453 | print(r' }') |
José Fonseca | 8f39c87 | 2015-01-25 22:20:15 +0000 | [diff] [blame] | 454 | if function.name in ('glLinkProgram', 'glCreateShaderProgramv', 'glCreateShaderProgramEXT', 'glCreateShaderProgramvEXT', 'glProgramBinary', 'glProgramBinaryOES'): |
| 455 | if function.name.startswith('glCreateShaderProgram'): |
Piotr Podsiadły | 0b8b019 | 2019-01-03 20:39:55 +0100 | [diff] [blame] | 456 | print(r' GLuint program = _result;') |
| 457 | print(r' GLint link_status = 0;') |
| 458 | print(r' glGetProgramiv(program, GL_LINK_STATUS, &link_status);') |
| 459 | print(r' if (!link_status) {') |
| 460 | print(r' retrace::warning(call) << "link failed\n";') |
| 461 | print(r' }') |
| 462 | print(r' GLint info_log_length = 0;') |
| 463 | print(r' glGetProgramiv(program, GL_INFO_LOG_LENGTH, &info_log_length);') |
| 464 | print(r' if (info_log_length > 1) {') |
| 465 | print(r' GLchar *infoLog = new GLchar[info_log_length];') |
| 466 | print(r' glGetProgramInfoLog(program, info_log_length, NULL, infoLog);') |
| 467 | print(r' retrace::warning(call) << infoLog << "\n";') |
| 468 | print(r' delete [] infoLog;') |
| 469 | print(r' }') |
José Fonseca | ecf3741 | 2011-05-21 01:56:08 +0100 | [diff] [blame] | 470 | if function.name == 'glCompileShaderARB': |
Piotr Podsiadły | 0b8b019 | 2019-01-03 20:39:55 +0100 | [diff] [blame] | 471 | print(r' GLint compile_status = 0;') |
| 472 | print(r' glGetObjectParameterivARB(shaderObj, GL_OBJECT_COMPILE_STATUS_ARB, &compile_status);') |
| 473 | print(r' if (!compile_status) {') |
| 474 | print(r' retrace::warning(call) << "compilation failed\n";') |
| 475 | print(r' }') |
| 476 | print(r' GLint info_log_length = 0;') |
| 477 | print(r' glGetObjectParameterivARB(shaderObj, GL_OBJECT_INFO_LOG_LENGTH_ARB, &info_log_length);') |
| 478 | print(r' if (info_log_length > 1) {') |
| 479 | print(r' GLchar *infoLog = new GLchar[info_log_length];') |
| 480 | print(r' glGetInfoLogARB(shaderObj, info_log_length, NULL, infoLog);') |
| 481 | print(r' retrace::warning(call) << infoLog << "\n";') |
| 482 | print(r' delete [] infoLog;') |
| 483 | print(r' }') |
José Fonseca | ecf3741 | 2011-05-21 01:56:08 +0100 | [diff] [blame] | 484 | if function.name == 'glLinkProgramARB': |
Piotr Podsiadły | 0b8b019 | 2019-01-03 20:39:55 +0100 | [diff] [blame] | 485 | print(r' GLint link_status = 0;') |
| 486 | print(r' glGetObjectParameterivARB(programObj, GL_OBJECT_LINK_STATUS_ARB, &link_status);') |
| 487 | print(r' if (!link_status) {') |
| 488 | print(r' retrace::warning(call) << "link failed\n";') |
| 489 | print(r' }') |
| 490 | print(r' GLint info_log_length = 0;') |
| 491 | print(r' glGetObjectParameterivARB(programObj, GL_OBJECT_INFO_LOG_LENGTH_ARB, &info_log_length);') |
| 492 | print(r' if (info_log_length > 1) {') |
| 493 | print(r' GLchar *infoLog = new GLchar[info_log_length];') |
| 494 | print(r' glGetInfoLogARB(programObj, info_log_length, NULL, infoLog);') |
| 495 | print(r' retrace::warning(call) << infoLog << "\n";') |
| 496 | print(r' delete [] infoLog;') |
| 497 | print(r' }') |
José Fonseca | bd503ed | 2014-11-12 21:36:10 +0000 | [diff] [blame] | 498 | if self.map_function_regex.match(function.name): |
Piotr Podsiadły | 0b8b019 | 2019-01-03 20:39:55 +0100 | [diff] [blame] | 499 | print(r' if (!_result) {') |
| 500 | print(r' retrace::warning(call) << "failed to map buffer\n";') |
| 501 | print(r' }') |
José Fonseca | bd503ed | 2014-11-12 21:36:10 +0000 | [diff] [blame] | 502 | if self.unmap_function_regex.match(function.name) and function.type is not stdapi.Void: |
Piotr Podsiadły | 0b8b019 | 2019-01-03 20:39:55 +0100 | [diff] [blame] | 503 | print(r' if (!_result) {') |
| 504 | print(r' retrace::warning(call) << "failed to unmap buffer\n";') |
| 505 | print(r' }') |
José Fonseca | 91492d2 | 2011-05-23 21:20:31 +0100 | [diff] [blame] | 506 | if function.name in ('glGetAttribLocation', 'glGetAttribLocationARB'): |
Piotr Podsiadły | 0b8b019 | 2019-01-03 20:39:55 +0100 | [diff] [blame] | 507 | print(r' GLint _origResult = call.ret->toSInt();') |
| 508 | print(r' if (_result != _origResult) {') |
| 509 | print(r' retrace::warning(call) << "vertex attrib location mismatch " << _origResult << " -> " << _result << "\n";') |
| 510 | print(r' }') |
José Fonseca | 4920c30 | 2014-08-13 18:35:57 +0100 | [diff] [blame] | 511 | if function.name in ('glCheckFramebufferStatus', 'glCheckFramebufferStatusEXT', 'glCheckNamedFramebufferStatus', 'glCheckNamedFramebufferStatusEXT'): |
Piotr Podsiadły | 0b8b019 | 2019-01-03 20:39:55 +0100 | [diff] [blame] | 512 | print(r' GLint _origResult = call.ret->toSInt();') |
| 513 | print(r' if (_origResult == GL_FRAMEBUFFER_COMPLETE &&') |
| 514 | print(r' _result != GL_FRAMEBUFFER_COMPLETE) {') |
| 515 | print(r' retrace::warning(call) << "incomplete framebuffer (" << glstate::enumToString(_result) << ")\n";') |
| 516 | print(r' }') |
| 517 | print(' }') |
José Fonseca | e4999b9 | 2011-05-05 00:31:01 +0100 | [diff] [blame] | 518 | |
José Fonseca | 561266b | 2012-03-21 06:49:41 +0000 | [diff] [blame] | 519 | # Query the buffer length for whole buffer mappings |
José Fonseca | bd503ed | 2014-11-12 21:36:10 +0000 | [diff] [blame] | 520 | if self.map_function_regex.match(function.name): |
José Fonseca | 561266b | 2012-03-21 06:49:41 +0000 | [diff] [blame] | 521 | if 'length' in function.argNames(): |
| 522 | assert 'BufferRange' in function.name |
| 523 | else: |
| 524 | assert 'BufferRange' not in function.name |
Piotr Podsiadły | 0b8b019 | 2019-01-03 20:39:55 +0100 | [diff] [blame] | 525 | print(r' GLint length = 0;') |
José Fonseca | 561266b | 2012-03-21 06:49:41 +0000 | [diff] [blame] | 526 | if function.name in ('glMapBuffer', 'glMapBufferOES'): |
Piotr Podsiadły | 0b8b019 | 2019-01-03 20:39:55 +0100 | [diff] [blame] | 527 | print(r' glGetBufferParameteriv(target, GL_BUFFER_SIZE, &length);') |
José Fonseca | 561266b | 2012-03-21 06:49:41 +0000 | [diff] [blame] | 528 | elif function.name == 'glMapBufferARB': |
Piotr Podsiadły | 0b8b019 | 2019-01-03 20:39:55 +0100 | [diff] [blame] | 529 | print(r' glGetBufferParameterivARB(target, GL_BUFFER_SIZE_ARB, &length);') |
José Fonseca | 4920c30 | 2014-08-13 18:35:57 +0100 | [diff] [blame] | 530 | elif function.name == 'glMapNamedBuffer': |
Piotr Podsiadły | 0b8b019 | 2019-01-03 20:39:55 +0100 | [diff] [blame] | 531 | print(r' glGetNamedBufferParameteriv(buffer, GL_BUFFER_SIZE, &length);') |
José Fonseca | 561266b | 2012-03-21 06:49:41 +0000 | [diff] [blame] | 532 | elif function.name == 'glMapNamedBufferEXT': |
Piotr Podsiadły | 0b8b019 | 2019-01-03 20:39:55 +0100 | [diff] [blame] | 533 | print(r' glGetNamedBufferParameterivEXT(buffer, GL_BUFFER_SIZE, &length);') |
José Fonseca | cbc859f | 2012-04-05 19:55:53 +0100 | [diff] [blame] | 534 | elif function.name == 'glMapObjectBufferATI': |
Piotr Podsiadły | 0b8b019 | 2019-01-03 20:39:55 +0100 | [diff] [blame] | 535 | print(r' glGetObjectBufferivATI(buffer, GL_OBJECT_BUFFER_SIZE_ATI, &length);') |
José Fonseca | 59ee88e | 2012-01-15 14:24:10 +0000 | [diff] [blame] | 536 | else: |
José Fonseca | 561266b | 2012-03-21 06:49:41 +0000 | [diff] [blame] | 537 | assert False |
José Fonseca | 46a4839 | 2011-10-14 11:34:27 +0100 | [diff] [blame] | 538 | |
José Fonseca | 54f304a | 2012-01-14 19:33:08 +0000 | [diff] [blame] | 539 | def extractArg(self, function, arg, arg_type, lvalue, rvalue): |
José Fonseca | 7f5163e | 2011-03-31 23:37:26 +0100 | [diff] [blame] | 540 | if function.name in self.array_pointer_function_names and arg.name == 'pointer': |
Piotr Podsiadły | 0b8b019 | 2019-01-03 20:39:55 +0100 | [diff] [blame] | 541 | print(' %s = static_cast<%s>(retrace::toPointer(%s, true));' % (lvalue, arg_type, rvalue)) |
José Fonseca | 14c21bc | 2011-02-20 23:32:22 +0000 | [diff] [blame] | 542 | return |
| 543 | |
José Fonseca | ac3d464 | 2014-08-14 19:20:03 +0100 | [diff] [blame] | 544 | if self.draw_elements_function_regex.match(function.name) and arg.name == 'indices' or\ |
| 545 | self.draw_indirect_function_regex.match(function.name) and arg.name == 'indirect': |
José Fonseca | 54f304a | 2012-01-14 19:33:08 +0000 | [diff] [blame] | 546 | self.extractOpaqueArg(function, arg, arg_type, lvalue, rvalue) |
José Fonseca | 8a844ae | 2010-12-06 18:50:52 +0000 | [diff] [blame] | 547 | return |
José Fonseca | dacd8dd | 2010-11-25 17:50:26 +0000 | [diff] [blame] | 548 | |
José Fonseca | c29f4f1 | 2011-06-11 12:19:05 +0100 | [diff] [blame] | 549 | # Handle pointer with offsets into the current pack pixel buffer |
| 550 | # object. |
José Fonseca | 920f8e7 | 2014-11-12 21:31:59 +0000 | [diff] [blame] | 551 | if self.pack_function_regex.match(function.name) and arg.output: |
José Fonseca | 4a2c57b | 2012-04-07 10:50:53 +0100 | [diff] [blame] | 552 | assert isinstance(arg_type, (stdapi.Pointer, stdapi.Array, stdapi.Blob, stdapi.Opaque)) |
Piotr Podsiadły | 0b8b019 | 2019-01-03 20:39:55 +0100 | [diff] [blame] | 553 | print(' %s = static_cast<%s>((%s).toPointer());' % (lvalue, arg_type, rvalue)) |
José Fonseca | c29f4f1 | 2011-06-11 12:19:05 +0100 | [diff] [blame] | 554 | return |
Jose Fonseca | 0a676c5 | 2016-04-04 23:24:32 +0100 | [diff] [blame] | 555 | if function.name.startswith('glGetQueryObject') and arg.output: |
Piotr Podsiadły | 0b8b019 | 2019-01-03 20:39:55 +0100 | [diff] [blame] | 556 | print(' %s = static_cast<%s>((%s).toPointer());' % (lvalue, arg_type, rvalue)) |
Jose Fonseca | 0a676c5 | 2016-04-04 23:24:32 +0100 | [diff] [blame] | 557 | return |
José Fonseca | c29f4f1 | 2011-06-11 12:19:05 +0100 | [diff] [blame] | 558 | |
José Fonseca | 13b9343 | 2014-11-18 20:21:23 +0000 | [diff] [blame] | 559 | if (arg.type.depends(glapi.GLlocation) or \ |
| 560 | arg.type.depends(glapi.GLsubroutine)) \ |
José Fonseca | 568ecc2 | 2012-01-15 13:57:03 +0000 | [diff] [blame] | 561 | and 'program' not in function.argNames(): |
Gregory Hainaut | b79e26a | 2012-05-11 14:49:10 +0100 | [diff] [blame] | 562 | # Determine the active program for uniforms swizzling |
Piotr Podsiadły | 0b8b019 | 2019-01-03 20:39:55 +0100 | [diff] [blame] | 563 | print(' GLint program = _getActiveProgram();') |
Gregory Hainaut | b79e26a | 2012-05-11 14:49:10 +0100 | [diff] [blame] | 564 | |
José Fonseca | 3c1b7ce | 2011-05-09 11:22:54 +0100 | [diff] [blame] | 565 | if arg.type is glapi.GLlocationARB \ |
José Fonseca | 568ecc2 | 2012-01-15 13:57:03 +0000 | [diff] [blame] | 566 | and 'programObj' not in function.argNames(): |
Piotr Podsiadły | 0b8b019 | 2019-01-03 20:39:55 +0100 | [diff] [blame] | 567 | print(' GLhandleARB programObj = glGetHandleARB(GL_PROGRAM_OBJECT_ARB);') |
José Fonseca | 8a844ae | 2010-12-06 18:50:52 +0000 | [diff] [blame] | 568 | |
José Fonseca | 54f304a | 2012-01-14 19:33:08 +0000 | [diff] [blame] | 569 | Retracer.extractArg(self, function, arg, arg_type, lvalue, rvalue) |
José Fonseca | e6a50bd | 2010-11-24 10:12:22 +0000 | [diff] [blame] | 570 | |
José Fonseca | 4292646 | 2011-05-09 11:32:15 +0100 | [diff] [blame] | 571 | # Don't try to use more samples than the implementation supports |
| 572 | if arg.name == 'samples': |
Kimmo Kinnunen | 24ce749 | 2015-05-25 13:18:44 +0300 | [diff] [blame] | 573 | if function.name == 'glRasterSamplesEXT': |
| 574 | assert arg.type is glapi.GLuint |
Piotr Podsiadły | 0b8b019 | 2019-01-03 20:39:55 +0100 | [diff] [blame] | 575 | print(' GLint max_samples = 0;') |
| 576 | print(' glGetIntegerv(GL_MAX_RASTER_SAMPLES_EXT, &max_samples);') |
| 577 | print(' if (samples > static_cast<GLuint>(max_samples)) {') |
| 578 | print(' samples = static_cast<GLuint>(max_samples);') |
| 579 | print(' }') |
Kimmo Kinnunen | 24ce749 | 2015-05-25 13:18:44 +0300 | [diff] [blame] | 580 | else: |
| 581 | assert arg.type is glapi.GLsizei |
Piotr Podsiadły | 0b8b019 | 2019-01-03 20:39:55 +0100 | [diff] [blame] | 582 | print(' GLint max_samples = 0;') |
| 583 | print(' glGetIntegerv(GL_MAX_SAMPLES, &max_samples);') |
| 584 | print(' if (samples > max_samples) {') |
| 585 | print(' samples = max_samples;') |
| 586 | print(' }') |
José Fonseca | 4292646 | 2011-05-09 11:32:15 +0100 | [diff] [blame] | 587 | |
José Fonseca | 62abddc | 2012-04-13 14:57:08 +0100 | [diff] [blame] | 588 | # These parameters are referred beyond the call life-time |
| 589 | # TODO: Replace ad-hoc solution for bindable parameters with general one |
| 590 | if function.name in ('glFeedbackBuffer', 'glSelectBuffer') and arg.output: |
Piotr Podsiadły | 0b8b019 | 2019-01-03 20:39:55 +0100 | [diff] [blame] | 591 | print(' _allocator.bind(%s);' % arg.name) |
José Fonseca | 62abddc | 2012-04-13 14:57:08 +0100 | [diff] [blame] | 592 | |
| 593 | |
José Fonseca | e6a50bd | 2010-11-24 10:12:22 +0000 | [diff] [blame] | 594 | |
José Fonseca | 7e32902 | 2010-11-19 17:05:18 +0000 | [diff] [blame] | 595 | if __name__ == '__main__': |
Piotr Podsiadły | 0b8b019 | 2019-01-03 20:39:55 +0100 | [diff] [blame] | 596 | print(r''' |
José Fonseca | 867b1b7 | 2011-04-24 11:58:04 +0100 | [diff] [blame] | 597 | #include <string.h> |
| 598 | |
José Fonseca | df66a90 | 2010-11-29 13:24:20 +0000 | [diff] [blame] | 599 | #include "glproc.hpp" |
José Fonseca | 32871ed | 2011-04-10 13:40:52 +0100 | [diff] [blame] | 600 | #include "glretrace.hpp" |
José Fonseca | 5639126 | 2011-09-19 09:30:10 +0100 | [diff] [blame] | 601 | #include "glstate.hpp" |
Jose Fonseca | 8e0a030 | 2016-05-04 23:53:46 +0100 | [diff] [blame] | 602 | #include "glsize.hpp" |
José Fonseca | 8a56fde | 2014-11-12 22:59:18 +0000 | [diff] [blame] | 603 | |
| 604 | |
| 605 | static GLint |
| 606 | _getActiveProgram(void); |
| 607 | |
Jose Fonseca | 21b8f33 | 2015-04-24 22:43:23 +0100 | [diff] [blame] | 608 | static void |
| 609 | _validateActiveProgram(trace::Call &call); |
| 610 | |
Piotr Podsiadły | 0b8b019 | 2019-01-03 20:39:55 +0100 | [diff] [blame] | 611 | ''') |
José Fonseca | 8130193 | 2012-11-11 00:10:20 +0000 | [diff] [blame] | 612 | api = stdapi.API() |
| 613 | api.addModule(glapi.glapi) |
José Fonseca | e0e6140 | 2010-11-25 15:03:23 +0000 | [diff] [blame] | 614 | retracer = GlRetracer() |
José Fonseca | 54f304a | 2012-01-14 19:33:08 +0000 | [diff] [blame] | 615 | retracer.retraceApi(api) |
José Fonseca | 8a56fde | 2014-11-12 22:59:18 +0000 | [diff] [blame] | 616 | |
Piotr Podsiadły | 0b8b019 | 2019-01-03 20:39:55 +0100 | [diff] [blame] | 617 | print(r''' |
José Fonseca | 8a56fde | 2014-11-12 22:59:18 +0000 | [diff] [blame] | 618 | static GLint |
| 619 | _getActiveProgram(void) |
| 620 | { |
| 621 | GLint program = -1; |
Jose Fonseca | 12b8217 | 2015-08-06 13:41:54 +0100 | [diff] [blame] | 622 | glretrace::Context *currentContext = glretrace::getCurrentContext(); |
Jose Fonseca | 8e0a030 | 2016-05-04 23:53:46 +0100 | [diff] [blame] | 623 | if (currentContext) { |
| 624 | GLint pipeline = currentContext->currentPipeline; |
José Fonseca | 8a56fde | 2014-11-12 22:59:18 +0000 | [diff] [blame] | 625 | if (pipeline) { |
| 626 | glGetProgramPipelineiv(pipeline, GL_ACTIVE_PROGRAM, &program); |
| 627 | } else { |
Jose Fonseca | 8e0a030 | 2016-05-04 23:53:46 +0100 | [diff] [blame] | 628 | program = currentContext->currentProgram; |
| 629 | assert(program == _glGetInteger(GL_CURRENT_PROGRAM)); |
José Fonseca | 8a56fde | 2014-11-12 22:59:18 +0000 | [diff] [blame] | 630 | } |
| 631 | } |
| 632 | return program; |
| 633 | } |
| 634 | |
Jose Fonseca | 21b8f33 | 2015-04-24 22:43:23 +0100 | [diff] [blame] | 635 | static void |
| 636 | _validateActiveProgram(trace::Call &call) |
| 637 | { |
Jose Fonseca | 65dc5c3 | 2018-08-22 19:20:00 +0100 | [diff] [blame] | 638 | assert(retrace::debug > 0); |
Jose Fonseca | 12b8217 | 2015-08-06 13:41:54 +0100 | [diff] [blame] | 639 | |
| 640 | glretrace::Context *currentContext = glretrace::getCurrentContext(); |
| 641 | if (!currentContext || |
| 642 | currentContext->insideList || |
| 643 | currentContext->insideBeginEnd || |
| 644 | currentContext->wsContext->profile.major < 2) { |
| 645 | return; |
| 646 | } |
Jose Fonseca | 21b8f33 | 2015-04-24 22:43:23 +0100 | [diff] [blame] | 647 | |
Jose Fonseca | 8e0a030 | 2016-05-04 23:53:46 +0100 | [diff] [blame] | 648 | GLint pipeline = currentContext->currentPipeline; |
Jose Fonseca | 21b8f33 | 2015-04-24 22:43:23 +0100 | [diff] [blame] | 649 | if (pipeline) { |
| 650 | // TODO |
| 651 | } else { |
Jose Fonseca | 8e0a030 | 2016-05-04 23:53:46 +0100 | [diff] [blame] | 652 | GLint program = currentContext->currentProgram; |
| 653 | assert(program == _glGetInteger(GL_CURRENT_PROGRAM)); |
Jose Fonseca | 21b8f33 | 2015-04-24 22:43:23 +0100 | [diff] [blame] | 654 | if (!program) { |
| 655 | return; |
| 656 | } |
| 657 | |
| 658 | GLint validate_status = GL_FALSE; |
| 659 | glGetProgramiv(program, GL_VALIDATE_STATUS, &validate_status); |
| 660 | if (validate_status) { |
| 661 | // Validate only once |
| 662 | return; |
| 663 | } |
| 664 | |
| 665 | glValidateProgram(program); |
| 666 | glGetProgramiv(program, GL_VALIDATE_STATUS, &validate_status); |
| 667 | if (!validate_status) { |
| 668 | retrace::warning(call) << "program validation failed\n"; |
| 669 | } |
| 670 | |
| 671 | GLint info_log_length = 0; |
| 672 | glGetProgramiv(program, GL_INFO_LOG_LENGTH, &info_log_length); |
| 673 | if (info_log_length > 1) { |
| 674 | GLchar *infoLog = new GLchar[info_log_length]; |
| 675 | glGetProgramInfoLog(program, info_log_length, NULL, infoLog); |
| 676 | retrace::warning(call) << infoLog << "\n"; |
| 677 | delete [] infoLog; |
| 678 | } |
| 679 | } |
| 680 | } |
| 681 | |
Piotr Podsiadły | 0b8b019 | 2019-01-03 20:39:55 +0100 | [diff] [blame] | 682 | ''') |