]> git.cworth.org Git - vogl/blob - src/voglcommon/vogl_ctypes.cpp
Fixing various issues that were showing up when trying to snapshot/restore Cube 2:
[vogl] / src / voglcommon / vogl_ctypes.cpp
1 /**************************************************************************
2  *
3  * Copyright 2013-2014 RAD Game Tools and Valve Software
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 // File: vogl_ctypes.cpp
27
28 /*
29   Linux x86 is ILP32, x64 is LP64:
30
31                                         ILP32      LP64    LLP64        ILP64
32         char                    8                       8                       8                       8
33         short                   16                      16                      16                      16
34         int                     32                      32                      32                      64
35         long                    32                      64                      32                      64
36         long long       64                      64                      64                      64
37         pointer         32                      64                      64                      64
38  */
39
40 #include "vogl_common.h"
41 #include "vogl_console.h"
42 #include "vogl_command_line_params.h"
43
44 // loki
45 #include "TypeTraits.h"
46
47 //----------------------------------------------------------------------------------------------------------------------
48 // global array mapping gl/glx type enums to descriptions, valid for the current process (not necessarily the trace)
49 //----------------------------------------------------------------------------------------------------------------------
50 static vogl_ctype_desc_t g_vogl_ctype_descs[] =
51     {
52 #define DEF_TYPE(name, ctype)                                                        \
53     {                                                                                \
54         name, VOGL_INVALID_CTYPE, #name, #ctype, 0, false, false, false, false, false \
55     }                                                                                \
56     ,
57 #include "gl_glx_ctypes.inc"
58 #undef DEF_TYPE
59     };
60
61 //----------------------------------------------------------------------------------------------------------------------
62 //  Global process vogl_ctypes object
63 //----------------------------------------------------------------------------------------------------------------------
64 vogl_ctypes g_vogl_process_gl_ctypes;
65
66 //----------------------------------------------------------------------------------------------------------------------
67 // vogl_ctypes::vogl_ctypes
68 //----------------------------------------------------------------------------------------------------------------------
69 vogl_ctypes::vogl_ctypes()
70 {
71     // purposely do nothing here, because this object is initialized before global construction time
72 }
73
74 //----------------------------------------------------------------------------------------------------------------------
75 // vogl_ctypes::init
76 //----------------------------------------------------------------------------------------------------------------------
77 void vogl_ctypes::init()
78 {
79     m_pointer_size = sizeof(void *);
80
81     memcpy(m_vogl_ctype_descs, g_vogl_ctype_descs, sizeof(m_vogl_ctype_descs));
82
83     // sanity checks
84     VOGL_ASSERT(m_vogl_ctype_descs[VOGL_GLVOID_PTR].m_is_pointer == true);
85     VOGL_ASSERT(m_vogl_ctype_descs[VOGL_GLVOID_PTR].m_is_opaque_pointer == true);
86     VOGL_ASSERT(m_vogl_ctype_descs[VOGL_GLVOID_PTR].m_size == static_cast<int>(m_pointer_size));
87 }
88
89 //----------------------------------------------------------------------------------------------------------------------
90 // vogl_ctypes::init
91 //----------------------------------------------------------------------------------------------------------------------
92 void vogl_ctypes::init(uint trace_ptr_size)
93 {
94     m_pointer_size = trace_ptr_size;
95
96     change_pointer_sizes(trace_ptr_size);
97 }
98
99 //----------------------------------------------------------------------------------------------------------------------
100 // vogl_ctypes::change_pointer_sizes
101 // This code attempts to programmatically change the ctype sizes depending on the platform (x86 vs. x64).
102 //----------------------------------------------------------------------------------------------------------------------
103 void vogl_ctypes::change_pointer_sizes(uint trace_ptr_size)
104 {
105     VOGL_ASSUME(sizeof(intptr_t) == sizeof(void *));
106     VOGL_ASSUME(sizeof(ptrdiff_t) == sizeof(void *));
107     VOGL_ASSUME(sizeof(long) == sizeof(void *));
108     VOGL_ASSUME(sizeof(long long) == sizeof(uint64_t));
109
110     VOGL_ASSERT((trace_ptr_size == sizeof(uint32)) || (trace_ptr_size == sizeof(uint64_t)));
111
112     m_pointer_size = trace_ptr_size;
113
114     memcpy(m_vogl_ctype_descs, g_vogl_ctype_descs, sizeof(m_vogl_ctype_descs));
115
116     for (uint ctype_iter = 0; ctype_iter < VOGL_NUM_CTYPES; ctype_iter++)
117     {
118         vogl_ctype_desc_t &desc = m_vogl_ctype_descs[ctype_iter];
119         if ((desc.m_is_pointer_diff) || (desc.m_loki_type_flags & LOKI_TYPE_BITMASK(LOKI_IS_POINTER)))
120         {
121             desc.m_size = trace_ptr_size;
122         }
123         else
124         {
125             // sanity check
126             VOGL_ASSERT(!desc.m_is_pointer && !desc.m_is_opaque_pointer);
127         }
128     }
129
130 // Mark up long and XID types, which are unsigned longs
131 #define DEF_LONG_TYPE(x) m_vogl_ctype_descs[x].m_size = trace_ptr_size;
132     DEF_LONG_TYPE(VOGL_LONG);
133     DEF_LONG_TYPE(VOGL_UNSIGNED_LONG);
134     DEF_LONG_TYPE(VOGL_GLXPIXMAP);
135     DEF_LONG_TYPE(VOGL_GLXDRAWABLE);
136     DEF_LONG_TYPE(VOGL_GLXCONTEXTID);
137     DEF_LONG_TYPE(VOGL_GLXWINDOW);
138     DEF_LONG_TYPE(VOGL_GLXPBUFFER);
139     DEF_LONG_TYPE(VOGL_GLXVIDEOCAPTUREDEVICENV);
140     DEF_LONG_TYPE(VOGL_COLORMAP);
141     DEF_LONG_TYPE(VOGL_WINDOW);
142     DEF_LONG_TYPE(VOGL_FONT);
143     //DEF_LONG_TYPE(VOGL_DRAWABLE);
144     DEF_LONG_TYPE(VOGL_PIXMAP);
145 //DEF_LONG_TYPE(VOGL_CURSOR);
146 #undef DEF_LONG_TYPE
147
148     // Special case the XVisualInfo struct because its size differs between 32-bit and 64-bit - argh this sucks and we need a MUCH cleaner way of handling this.
149     // In practice this only fixes an assertion, because the packets always describe the exact length of objects.
150     m_vogl_ctype_descs[VOGL_XVISUALINFO].m_size = (trace_ptr_size == 8) ? 64 : 40;
151
152 #if 1
153     // sanity check
154     for (uint ctype_iter = 0; ctype_iter < VOGL_NUM_CTYPES; ctype_iter++)
155     {
156         vogl_ctype_desc_t &desc = m_vogl_ctype_descs[ctype_iter];
157         if ((!desc.m_is_pointer) && (!desc.m_is_pointer_diff))
158         {
159             VOGL_ASSERT(!desc.m_is_opaque_pointer);
160             continue;
161         }
162
163         VOGL_ASSERT(desc.m_size == static_cast<int>(trace_ptr_size));
164     }
165 #endif
166 }
167
168 //----------------------------------------------------------------------------------------------------------------------
169 // vogl_ctypes::operator=
170 //----------------------------------------------------------------------------------------------------------------------
171 vogl_ctypes &vogl_ctypes::operator=(const vogl_ctypes &other)
172 {
173     if (this == &other)
174         return *this;
175     memcpy(this, &other, sizeof(*this));
176     return *this;
177 }
178
179 //----------------------------------------------------------------------------------------------------------------------
180 // vogl_dump_gl_ctypes
181 //----------------------------------------------------------------------------------------------------------------------
182 void vogl_dump_gl_ctypes()
183 {
184     printf("vogl_ctypes:\n");
185     for (int i = 0; i < VOGL_NUM_CTYPES; i++)
186     {
187         const vogl_ctype_desc_t &desc = g_vogl_ctype_descs[i];
188
189         printf("%u: %s \"%s\" is_pointer: %u size: %i, pointee type: %s, opaque pointer: %u, pointer diff type: %u, type flags: 0x%08X\n",
190                i, desc.m_pName, desc.m_pCType,
191                desc.m_is_pointer, desc.m_size,
192                (desc.m_pointee_ctype != VOGL_INVALID_CTYPE) ? g_vogl_ctype_descs[desc.m_pointee_ctype].m_pName : "N/A",
193                desc.m_is_opaque_pointer,
194                desc.m_is_pointer_diff,
195                desc.m_loki_type_flags);
196     }
197     printf("\n");
198 }
199
200 //----------------------------------------------------------------------------------------------------------------------
201 // vogl_define_special_ctypes
202 // define opaque and pointer diff types
203 // Note: Opaque types may have different sizes in 32-bit vs 64-bit. We don't even try to get their ctype desc sizes
204 // right, because they can change.
205 //----------------------------------------------------------------------------------------------------------------------
206 static void vogl_define_special_ctypes()
207 {
208 // define opaque and opaque ptr types
209 #define DEF_OPAQUE_TYPE(type)                                 \
210     VOGL_ASSERT(!g_vogl_ctype_descs[type].m_is_pointer);     \
211     VOGL_ASSERT(!g_vogl_ctype_descs[type].m_is_opaque_type); \
212     g_vogl_ctype_descs[type].m_is_opaque_type = true;
213
214 #define DEF_OPAQUE_PTR_TYPE(type)                                                               \
215     {                                                                                           \
216         VOGL_ASSERT(g_vogl_ctype_descs[type].m_is_pointer);                                    \
217         VOGL_ASSERT(!g_vogl_ctype_descs[type].m_is_opaque_pointer);                            \
218         g_vogl_ctype_descs[type].m_is_opaque_pointer = true;                                     \
219         if (g_vogl_ctype_descs[type].m_pointee_ctype != VOGL_VOID)                                \
220             g_vogl_ctype_descs[g_vogl_ctype_descs[type].m_pointee_ctype].m_is_opaque_type = true; \
221     }
222
223     DEF_OPAQUE_PTR_TYPE(VOGL_CONST_VOID_PTR)
224     DEF_OPAQUE_PTR_TYPE(VOGL_GLDEBUGPROC)
225     DEF_OPAQUE_PTR_TYPE(VOGL_GLDEBUGPROCAMD)
226     DEF_OPAQUE_PTR_TYPE(VOGL_GLDEBUGPROCARB)
227     DEF_OPAQUE_PTR_TYPE(VOGL_GLVOID_PTR)
228     DEF_OPAQUE_PTR_TYPE(VOGL_GLXEXTFUNCPTR)
229     DEF_OPAQUE_PTR_TYPE(VOGL_GLSYNC)
230     DEF_OPAQUE_PTR_TYPE(VOGL_GLXCONTEXT)
231     DEF_OPAQUE_PTR_TYPE(VOGL_CONST_GLXCONTEXT)
232     DEF_OPAQUE_PTR_TYPE(VOGL_GLXFBCONFIG)
233     DEF_OPAQUE_PTR_TYPE(VOGL_DISPLAY_PTR)
234     DEF_OPAQUE_PTR_TYPE(VOGL_STRUCT_CLCONTEXT_PTR)
235     DEF_OPAQUE_PTR_TYPE(VOGL_STRUCT_CLEVENT_PTR)
236     //DEF_OPAQUE_PTR_TYPE(VOGL_CONST_XVISUALINFO_PTR)
237     //DEF_OPAQUE_PTR_TYPE(VOGL_XVISUALINFO_PTR)
238
239     DEF_OPAQUE_TYPE(VOGL_VOID)
240     DEF_OPAQUE_TYPE(VOGL_WINDOW)
241     DEF_OPAQUE_TYPE(VOGL_XVISUALINFO)
242     DEF_OPAQUE_TYPE(VOGL_COLORMAP) // rg - added 11/14/13
243
244 #undef DEF_OPAQUE_PTR_TYPE
245 #undef DEF_OPAQUE_TYPE
246
247 // Define pointer diff types
248 #define DEF_POINTER_DIFF_TYPE(x) g_vogl_ctype_descs[x].m_is_pointer_diff = true;
249     DEF_POINTER_DIFF_TYPE(VOGL_GLVDPAUSURFACENV)
250     DEF_POINTER_DIFF_TYPE(VOGL_GLINTPTR)
251     DEF_POINTER_DIFF_TYPE(VOGL_GLINTPTRARB)
252     DEF_POINTER_DIFF_TYPE(VOGL_GLSIZEIPTR)
253     DEF_POINTER_DIFF_TYPE(VOGL_GLSIZEIPTRARB)
254 #undef DEF_POINTER_DIFF_TYPE
255 }
256
257 //----------------------------------------------------------------------------------------------------------------------
258 // vogl_init_gl_ctypes
259 //----------------------------------------------------------------------------------------------------------------------
260 void vogl_init_gl_ctypes()
261 {
262 // Define ctypes
263 #define DEF_TYPE(name, ctype)                             \
264     {                                                     \
265         vogl_ctype_desc_t &desc = g_vogl_ctype_descs[name]; \
266         typedef Loki::TypeTraits<ctype> ctype_traits;     \
267         desc.m_size = gl_ctype_sizeof<ctype>::size;       \
268         desc.m_is_pointer = ctype_traits::isPointer;      \
269         desc.m_loki_type_flags = ctype_traits::typeFlags; \
270     }
271 #include "gl_glx_ctypes.inc"
272 #undef DEF_TYPE
273
274 // Define ptr to pointee mappings
275 #define DEF_PTR_TO_POINTEE_TYPE(ptr_ctype, pointee_ctype) g_vogl_ctype_descs[ptr_ctype].m_pointee_ctype = pointee_ctype;
276 #include "gl_glx_ctypes_ptr_to_pointee.inc"
277 #undef DEF_PTR_TO_POINTEE_TYPE
278
279     vogl_define_special_ctypes();
280
281     for (int i = 0; i < VOGL_NUM_CTYPES; i++)
282     {
283         const vogl_ctype_desc_t &desc = g_vogl_ctype_descs[i];
284         bool has_pointee_ctype = (desc.m_pointee_ctype != VOGL_INVALID_CTYPE);
285
286         if (desc.m_is_pointer)
287         {
288             if (!has_pointee_ctype)
289             {
290                 if (!desc.m_is_opaque_pointer)
291                     vogl_warning_printf("%s: ctype %s is a non-opaque pointer, but does not have a valid pointee ctype!\n", VOGL_FUNCTION_NAME, desc.m_pName);
292             }
293             else
294             {
295                 const vogl_ctype_desc_t &pointee_desc = g_vogl_ctype_descs[desc.m_pointee_ctype];
296
297                 if ((desc.m_is_opaque_pointer) && (pointee_desc.m_size > 0))
298                 {
299                     vogl_warning_printf("%s: ctype %s is a pointer with a valid pointee ctype %s size %i, but has been marked as an opaque ptr!\n", VOGL_FUNCTION_NAME, desc.m_pName, g_vogl_ctype_descs[desc.m_pointee_ctype].m_pName, pointee_desc.m_size);
300                 }
301
302                 if ((!pointee_desc.m_size) && (desc.m_pointee_ctype != VOGL_GLVOID) && (desc.m_pointee_ctype != VOGL_VOID))
303                     vogl_warning_printf("%s: ctype %s is a pointer with a valid pointee ctype, but the pointee type has a size of zero\n", VOGL_FUNCTION_NAME, desc.m_pName);
304             }
305         }
306         else if (has_pointee_ctype)
307             vogl_warning_printf("%s: ctype %s is not a pointer, but has a pointee ctype!\n", VOGL_FUNCTION_NAME, desc.m_pName);
308         else if (desc.m_is_opaque_pointer)
309             vogl_warning_printf("%s: ctype %s is not a pointer, but has been marked as an opaque pointer!\n", VOGL_FUNCTION_NAME, desc.m_pName);
310     }
311
312     g_vogl_process_gl_ctypes.init();
313
314     if (vogl::check_for_command_line_param("--vogl_debug"))
315         vogl_dump_gl_ctypes();
316
317     // sanity checks
318     for (uint ctype_iter = 0; ctype_iter < VOGL_NUM_CTYPES; ctype_iter++)
319     {
320         vogl_ctype_desc_t &desc = g_vogl_ctype_descs[ctype_iter];
321         if ((desc.m_is_pointer_diff) ||
322             (desc.m_loki_type_flags & LOKI_TYPE_BITMASK(LOKI_IS_POINTER)) ||
323             (desc.m_loki_type_flags & LOKI_TYPE_BITMASK(LOKI_IS_SIGNED_LONG)) ||
324             (desc.m_loki_type_flags & LOKI_TYPE_BITMASK(LOKI_IS_UNSIGNED_LONG)))
325         {
326             // This will fail on long long and unsigned long long, but GL/GLX don't use those types.
327             VOGL_ASSERT(desc.m_size == sizeof(void *));
328         }
329         else
330         {
331             VOGL_ASSERT(!desc.m_is_pointer && !desc.m_is_opaque_pointer);
332         }
333     }
334 }