]> git.cworth.org Git - vogl/blob - src/voglcommon/vogl_ctypes.cpp
Initial vogl checkin
[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 #if 1
149     // sanity check
150     for (uint ctype_iter = 0; ctype_iter < VOGL_NUM_CTYPES; ctype_iter++)
151     {
152         vogl_ctype_desc_t &desc = m_vogl_ctype_descs[ctype_iter];
153         if ((!desc.m_is_pointer) && (!desc.m_is_pointer_diff))
154         {
155             VOGL_ASSERT(!desc.m_is_opaque_pointer);
156             continue;
157         }
158
159         VOGL_ASSERT(desc.m_size == static_cast<int>(trace_ptr_size));
160     }
161 #endif
162 }
163
164 //----------------------------------------------------------------------------------------------------------------------
165 // vogl_ctypes::operator=
166 //----------------------------------------------------------------------------------------------------------------------
167 vogl_ctypes &vogl_ctypes::operator=(const vogl_ctypes &other)
168 {
169     if (this == &other)
170         return *this;
171     memcpy(this, &other, sizeof(*this));
172     return *this;
173 }
174
175 //----------------------------------------------------------------------------------------------------------------------
176 // vogl_dump_gl_ctypes
177 //----------------------------------------------------------------------------------------------------------------------
178 void vogl_dump_gl_ctypes()
179 {
180     printf("vogl_ctypes:\n");
181     for (int i = 0; i < VOGL_NUM_CTYPES; i++)
182     {
183         const vogl_ctype_desc_t &desc = g_vogl_ctype_descs[i];
184
185         printf("%u: %s \"%s\" is_pointer: %u size: %i, pointee type: %s, opaque pointer: %u, pointer diff type: %u, type flags: 0x%08X\n",
186                i, desc.m_pName, desc.m_pCType,
187                desc.m_is_pointer, desc.m_size,
188                (desc.m_pointee_ctype != VOGL_INVALID_CTYPE) ? g_vogl_ctype_descs[desc.m_pointee_ctype].m_pName : "N/A",
189                desc.m_is_opaque_pointer,
190                desc.m_is_pointer_diff,
191                desc.m_loki_type_flags);
192     }
193     printf("\n");
194 }
195
196 //----------------------------------------------------------------------------------------------------------------------
197 // vogl_define_special_ctypes
198 // define opaque and pointer diff types
199 // Note: Opaque types may have different sizes in 32-bit vs 64-bit. We don't even try to get their ctype desc sizes
200 // right, because they can change.
201 //----------------------------------------------------------------------------------------------------------------------
202 static void vogl_define_special_ctypes()
203 {
204 // define opaque and opaque ptr types
205 #define DEF_OPAQUE_TYPE(type)                                 \
206     VOGL_ASSERT(!g_vogl_ctype_descs[type].m_is_pointer);     \
207     VOGL_ASSERT(!g_vogl_ctype_descs[type].m_is_opaque_type); \
208     g_vogl_ctype_descs[type].m_is_opaque_type = true;
209
210 #define DEF_OPAQUE_PTR_TYPE(type)                                                               \
211     {                                                                                           \
212         VOGL_ASSERT(g_vogl_ctype_descs[type].m_is_pointer);                                    \
213         VOGL_ASSERT(!g_vogl_ctype_descs[type].m_is_opaque_pointer);                            \
214         g_vogl_ctype_descs[type].m_is_opaque_pointer = true;                                     \
215         if (g_vogl_ctype_descs[type].m_pointee_ctype != VOGL_VOID)                                \
216             g_vogl_ctype_descs[g_vogl_ctype_descs[type].m_pointee_ctype].m_is_opaque_type = true; \
217     }
218
219     DEF_OPAQUE_PTR_TYPE(VOGL_CONST_VOID_PTR)
220     DEF_OPAQUE_PTR_TYPE(VOGL_GLDEBUGPROC)
221     DEF_OPAQUE_PTR_TYPE(VOGL_GLDEBUGPROCAMD)
222     DEF_OPAQUE_PTR_TYPE(VOGL_GLDEBUGPROCARB)
223     DEF_OPAQUE_PTR_TYPE(VOGL_GLVOID_PTR)
224     DEF_OPAQUE_PTR_TYPE(VOGL_GLXEXTFUNCPTR)
225     DEF_OPAQUE_PTR_TYPE(VOGL_GLSYNC)
226     DEF_OPAQUE_PTR_TYPE(VOGL_GLXCONTEXT)
227     DEF_OPAQUE_PTR_TYPE(VOGL_CONST_GLXCONTEXT)
228     DEF_OPAQUE_PTR_TYPE(VOGL_GLXFBCONFIG)
229     DEF_OPAQUE_PTR_TYPE(VOGL_DISPLAY_PTR)
230     DEF_OPAQUE_PTR_TYPE(VOGL_STRUCT_CLCONTEXT_PTR)
231     DEF_OPAQUE_PTR_TYPE(VOGL_STRUCT_CLEVENT_PTR)
232     //DEF_OPAQUE_PTR_TYPE(VOGL_CONST_XVISUALINFO_PTR)
233     //DEF_OPAQUE_PTR_TYPE(VOGL_XVISUALINFO_PTR)
234
235     DEF_OPAQUE_TYPE(VOGL_VOID)
236     DEF_OPAQUE_TYPE(VOGL_WINDOW)
237     DEF_OPAQUE_TYPE(VOGL_XVISUALINFO)
238     DEF_OPAQUE_TYPE(VOGL_COLORMAP) // rg - added 11/14/13
239
240 #undef DEF_OPAQUE_PTR_TYPE
241 #undef DEF_OPAQUE_TYPE
242
243 // Define pointer diff types
244 #define DEF_POINTER_DIFF_TYPE(x) g_vogl_ctype_descs[x].m_is_pointer_diff = true;
245     DEF_POINTER_DIFF_TYPE(VOGL_GLVDPAUSURFACENV)
246     DEF_POINTER_DIFF_TYPE(VOGL_GLINTPTR)
247     DEF_POINTER_DIFF_TYPE(VOGL_GLINTPTRARB)
248     DEF_POINTER_DIFF_TYPE(VOGL_GLSIZEIPTR)
249     DEF_POINTER_DIFF_TYPE(VOGL_GLSIZEIPTRARB)
250 #undef DEF_POINTER_DIFF_TYPE
251 }
252
253 //----------------------------------------------------------------------------------------------------------------------
254 // vogl_init_gl_ctypes
255 //----------------------------------------------------------------------------------------------------------------------
256 void vogl_init_gl_ctypes()
257 {
258 // Define ctypes
259 #define DEF_TYPE(name, ctype)                             \
260     {                                                     \
261         vogl_ctype_desc_t &desc = g_vogl_ctype_descs[name]; \
262         typedef Loki::TypeTraits<ctype> ctype_traits;     \
263         desc.m_size = gl_ctype_sizeof<ctype>::size;       \
264         desc.m_is_pointer = ctype_traits::isPointer;      \
265         desc.m_loki_type_flags = ctype_traits::typeFlags; \
266     }
267 #include "gl_glx_ctypes.inc"
268 #undef DEF_TYPE
269
270 // Define ptr to pointee mappings
271 #define DEF_PTR_TO_POINTEE_TYPE(ptr_ctype, pointee_ctype) g_vogl_ctype_descs[ptr_ctype].m_pointee_ctype = pointee_ctype;
272 #include "gl_glx_ctypes_ptr_to_pointee.inc"
273 #undef DEF_PTR_TO_POINTEE_TYPE
274
275     vogl_define_special_ctypes();
276
277     for (int i = 0; i < VOGL_NUM_CTYPES; i++)
278     {
279         const vogl_ctype_desc_t &desc = g_vogl_ctype_descs[i];
280         bool has_pointee_ctype = (desc.m_pointee_ctype != VOGL_INVALID_CTYPE);
281
282         if (desc.m_is_pointer)
283         {
284             if (!has_pointee_ctype)
285             {
286                 if (!desc.m_is_opaque_pointer)
287                     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);
288             }
289             else
290             {
291                 const vogl_ctype_desc_t &pointee_desc = g_vogl_ctype_descs[desc.m_pointee_ctype];
292
293                 if ((desc.m_is_opaque_pointer) && (pointee_desc.m_size > 0))
294                 {
295                     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);
296                 }
297
298                 if ((!pointee_desc.m_size) && (desc.m_pointee_ctype != VOGL_GLVOID) && (desc.m_pointee_ctype != VOGL_VOID))
299                     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);
300             }
301         }
302         else if (has_pointee_ctype)
303             vogl_warning_printf("%s: ctype %s is not a pointer, but has a pointee ctype!\n", VOGL_FUNCTION_NAME, desc.m_pName);
304         else if (desc.m_is_opaque_pointer)
305             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);
306     }
307
308     g_vogl_process_gl_ctypes.init();
309
310     if (vogl::check_for_command_line_param("--vogl_debug"))
311         vogl_dump_gl_ctypes();
312
313     // sanity checks
314     for (uint ctype_iter = 0; ctype_iter < VOGL_NUM_CTYPES; ctype_iter++)
315     {
316         vogl_ctype_desc_t &desc = g_vogl_ctype_descs[ctype_iter];
317         if ((desc.m_is_pointer_diff) ||
318             (desc.m_loki_type_flags & LOKI_TYPE_BITMASK(LOKI_IS_POINTER)) ||
319             (desc.m_loki_type_flags & LOKI_TYPE_BITMASK(LOKI_IS_SIGNED_LONG)) ||
320             (desc.m_loki_type_flags & LOKI_TYPE_BITMASK(LOKI_IS_UNSIGNED_LONG)))
321         {
322             // This will fail on long long and unsigned long long, but GL/GLX don't use those types.
323             VOGL_ASSERT(desc.m_size == sizeof(void *));
324         }
325         else
326         {
327             VOGL_ASSERT(!desc.m_is_pointer && !desc.m_is_opaque_pointer);
328         }
329     }
330 }