]> git.cworth.org Git - vogl/blob - src/voglcommon/vogl_context_info.h
fabad658a3118131c754f163688d7583c39ae522
[vogl] / src / voglcommon / vogl_context_info.h
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_context_info.h
27 #ifndef VOGL_CONTEXT_INFO_H
28 #define VOGL_CONTEXT_INFO_H
29
30 #include "vogl_common.h"
31 #include "vogl_dynamic_string.h"
32
33 #include "vogl_json.h"
34
35 enum vogl_gl_version_t
36 {
37     VOGL_GL_VERSION_UNKNOWN = 0x000000,
38     VOGL_GL_VERSION_1_0 = 0x010000,
39     VOGL_GL_VERSION_1_1 = 0x010100,
40     VOGL_GL_VERSION_1_2 = 0x010200,
41     VOGL_GL_VERSION_1_2_1 = 0x010201,
42     VOGL_GL_VERSION_1_3 = 0x010300,
43     VOGL_GL_VERSION_1_4 = 0x010400,
44     VOGL_GL_VERSION_1_5 = 0x010500,
45     VOGL_GL_VERSION_2_0 = 0x020000,
46     VOGL_GL_VERSION_2_1 = 0x020100,
47     VOGL_GL_VERSION_3_0 = 0x030000,
48     VOGL_GL_VERSION_3_1 = 0x030100,
49     VOGL_GL_VERSION_3_2 = 0x030200,
50     VOGL_GL_VERSION_3_3 = 0x030300,
51     VOGL_GL_VERSION_4_0 = 0x040000,
52     VOGL_GL_VERSION_4_1 = 0x040100,
53     VOGL_GL_VERSION_4_2 = 0x040200,
54     VOGL_GL_VERSION_4_3 = 0x040300,
55     VOGL_GL_VERSION_4_4 = 0x040400,
56     VOGL_GL_VERSION_4_5 = 0x040500,
57     VOGL_GL_VERSION_4_6 = 0x040600,
58     VOGL_GL_VERSION_4_7 = 0x040700,
59     VOGL_GL_VERSION_4_8 = 0x040800,
60     VOGL_GL_VERSION_4_9 = 0x040900,
61     VOGL_GL_VERSION_5_0 = 0x050000,
62     VOGL_GL_VERSION_5_1 = 0x050100,
63     VOGL_GL_VERSION_5_2 = 0x050200,
64     VOGL_GL_VERSION_5_3 = 0x050300,
65     VOGL_GL_VERSION_5_4 = 0x050400,
66     VOGL_GL_VERSION_5_5 = 0x050500
67 };
68
69 #define VOGL_CREATE_GL_VERSION(major, minor, patch) static_cast<vogl_gl_version_t>(((major) << 16) | ((minor) << 8) | (patch))
70
71 #define VOGL_GL_VERSION_GET_MAJOR(x) (((x) >> 16) & 0xFF)
72 #define VOGL_GL_VERSION_GET_MINOR(x) (((x) >> 8) & 0xFF)
73 #define VOGL_GL_VERSION_GET_PATCH(x) ((x) & 0xFF)
74
75 int vogl_determine_attrib_list_array_size(const int *attrib_list);
76
77 class vogl_context_attribs
78 {
79 public:
80     typedef vogl::vector<int> attrib_vec;
81
82     vogl_context_attribs();
83     vogl_context_attribs(const int *pAttribs);
84     vogl_context_attribs(const int *pAttribs, uint num_attribs);
85     vogl_context_attribs(const attrib_vec &vec);
86
87     void init(const int *pAttribs);
88     void init(const int *pAttribs, uint num_attribs);
89     void init(const attrib_vec &vec);
90
91     void clear()
92     {
93         m_attribs.clear();
94     }
95
96     bool serialize(vogl::json_node &node) const;
97     bool deserialize(const vogl::json_node &node);
98
99     const attrib_vec &get_vec() const
100     {
101         return m_attribs;
102     }
103     attrib_vec &get_vec()
104     {
105         return m_attribs;
106     }
107
108     int *get_ptr()
109     {
110         return m_attribs.get_ptr();
111     }
112     const int *get_ptr() const
113     {
114         return m_attribs.get_ptr();
115     }
116
117     uint size() const
118     {
119         return m_attribs.size();
120     }
121     int operator[](uint i) const
122     {
123         return m_attribs[i];
124     }
125     int &operator[](uint i)
126     {
127         return m_attribs[i];
128     }
129
130     // Returns offset of value following key, or -1 if not found (or if the key was found but it was at the very end of the int array).
131     int find_value_ofs(int key_to_find) const;
132     bool has_key(int key_to_find) const
133     {
134         return find_value_ofs(key_to_find) >= 0;
135     }
136     bool get_value(int key_to_find, int &val) const;
137     int get_value_or_default(int key_to_find, int def = 0) const
138     {
139         int val = 0;
140         if (!get_value(key_to_find, val))
141             return def;
142         return val;
143     }
144     void add_key(int key, int value);
145
146     bool check() const;
147
148 private:
149     attrib_vec m_attribs;
150 };
151
152 // TODO: Add replay context handle
153 class vogl_context_desc
154 {
155 public:
156     vogl_context_desc()
157     {
158         VOGL_FUNC_TRACER
159
160         clear();
161     }
162
163     vogl_context_desc(gl_entrypoint_id_t creation_func, GLboolean direct, vogl_trace_ptr_value trace_context, vogl_trace_ptr_value trace_share_context, const vogl_context_attribs &attribs)
164     {
165         VOGL_FUNC_TRACER
166
167         clear();
168
169         init(creation_func, direct, trace_context, trace_share_context, attribs);
170     }
171
172     void init(gl_entrypoint_id_t creation_func, GLboolean direct, vogl_trace_ptr_value trace_context, vogl_trace_ptr_value trace_share_context, const vogl_context_attribs &attribs)
173     {
174         VOGL_FUNC_TRACER
175
176         m_creation_func = creation_func;
177         m_direct = direct;
178         m_trace_context = trace_context;
179         m_trace_share_context = trace_share_context;
180         m_attribs = attribs;
181     }
182
183     void clear()
184     {
185         VOGL_FUNC_TRACER
186
187         m_creation_func = VOGL_ENTRYPOINT_INVALID;
188         m_direct = false;
189         m_trace_context = 0;
190         m_trace_share_context = 0;
191         m_attribs.clear();
192     }
193
194     bool serialize(json_node &node, const vogl_blob_manager &blob_manager) const
195     {
196         VOGL_FUNC_TRACER
197
198         VOGL_NOTE_UNUSED(blob_manager);
199
200         node.add_key_value("creation_func", (m_creation_func != VOGL_ENTRYPOINT_INVALID) ? g_vogl_entrypoint_descs[m_creation_func].m_pName : "");
201         node.add_key_value("direct", m_direct);
202         node.add_key_value("trace_context", static_cast<uint64_t>(m_trace_context));
203         node.add_key_value("trace_share_handle", static_cast<uint64_t>(m_trace_share_context));
204
205         return m_attribs.serialize(node);
206     }
207
208     bool deserialize(const json_node &node, const vogl_blob_manager &blob_manager)
209     {
210         VOGL_FUNC_TRACER
211
212         VOGL_NOTE_UNUSED(blob_manager);
213
214         m_creation_func = vogl_find_entrypoint(node.value_as_string("creation_func"));
215         m_direct = node.value_as_bool("direct");
216         m_trace_context = static_cast<vogl_trace_ptr_value>(node.value_as_uint64("trace_context"));
217         m_trace_share_context = static_cast<vogl_trace_ptr_value>(node.value_as_uint64("trace_share_handle"));
218
219         return m_attribs.deserialize(node);
220     }
221
222     gl_entrypoint_id_t get_creation_func() const
223     {
224         return m_creation_func;
225     }
226     GLboolean get_direct() const
227     {
228         return m_direct;
229     }
230     vogl_trace_ptr_value get_trace_context() const
231     {
232         return m_trace_context;
233     }
234     vogl_trace_ptr_value get_trace_share_context() const
235     {
236         return m_trace_share_context;
237     }
238
239     const vogl_context_attribs &get_attribs() const
240     {
241         return m_attribs;
242     }
243     vogl_context_attribs &get_attribs()
244     {
245         return m_attribs;
246     }
247
248 private:
249     gl_entrypoint_id_t m_creation_func;
250     GLboolean m_direct;
251     vogl_trace_ptr_value m_trace_context;
252     vogl_trace_ptr_value m_trace_share_context;
253
254     vogl_context_attribs m_attribs;
255 };
256
257 class vogl_context_info
258 {
259 public:
260     vogl_context_info();
261
262     // Inits from the current GL context
263     vogl_context_info(const vogl_context_desc &desc);
264
265     // Inits from the current GL context
266     bool init(const vogl_context_desc &desc);
267
268     void clear();
269
270     inline bool is_valid() const
271     {
272         return m_is_valid;
273     }
274
275     bool serialize(vogl::json_node &node, const vogl_blob_manager &blob_manager) const;
276     bool deserialize(const vogl::json_node &node, const vogl_blob_manager &blob_manager);
277
278     const vogl_context_desc &get_desc() const
279     {
280         return m_desc;
281     }
282
283     inline vogl_gl_version_t get_version() const
284     {
285         return m_version;
286     }
287     inline vogl_gl_version_t get_glsl_version() const
288     {
289         return m_glsl_version;
290     }
291
292     inline bool is_forward_compatible() const
293     {
294         return m_forward_compatible;
295     }
296     inline bool is_core_profile() const
297     {
298         return m_core_profile;
299     }
300     inline bool is_compatibility_profile() const
301     {
302         return !m_core_profile;
303     }
304     inline bool is_debug_context() const
305     {
306         return m_debug_context;
307     }
308
309     inline const vogl::dynamic_string &get_vendor_str() const
310     {
311         return m_vendor_str;
312     }
313     inline const vogl::dynamic_string &get_renderer_str() const
314     {
315         return m_renderer_str;
316     }
317     inline const vogl::dynamic_string &get_version_str() const
318     {
319         return m_version_str;
320     }
321     inline const vogl::dynamic_string &get_glsl_version_str() const
322     {
323         return m_glsl_version_str;
324     }
325
326     inline const vogl::dynamic_string_array &get_extensions() const
327     {
328         return m_extensions;
329     }
330
331     // Not case sensitive. Currently uses a binary search of strings, so it's not terribly slow but it's not super fast either.
332     bool supports_extension(const char *pExt) const;
333
334     uint get_max_vertex_attribs() const
335     {
336         return m_max_vertex_attribs;
337     }
338     uint get_max_texture_coords() const
339     {
340         return m_max_texture_coords;
341     }
342     uint get_max_texture_units() const
343     {
344         return m_max_texture_units;
345     }
346     uint get_max_texture_image_units() const
347     {
348         return m_max_texture_image_units;
349     }
350     uint get_max_combined_texture_coords() const
351     {
352         return m_max_combined_texture_coords;
353     }
354     uint get_max_draw_buffers() const
355     {
356         return m_max_draw_buffers;
357     }
358     uint get_max_lights() const
359     {
360         return m_max_lights;
361     }
362     uint get_max_uniform_buffer_bindings() const
363     {
364         return m_max_uniform_buffer_bindings;
365     }
366     uint get_max_arb_program_matrices() const
367     {
368         return m_max_arb_program_matrices;
369     }
370     uint get_max_arb_vertex_program_env_params() const
371     {
372         return m_max_arb_vertex_program_env_params;
373     }
374     uint get_max_arb_fragment_program_env_params() const
375     {
376         return m_max_arb_fragment_program_env_params;
377     }
378     uint get_max_transform_feedback_separate_attribs() const
379     {
380         return m_max_transform_feedback_separate_attribs;
381     }
382
383 private:
384     vogl_context_desc m_desc;
385
386     vogl_gl_version_t m_version;
387     vogl_gl_version_t m_glsl_version;
388
389     bool m_forward_compatible;
390     bool m_core_profile;
391     bool m_debug_context;
392
393     vogl::dynamic_string m_version_str;
394     vogl::dynamic_string m_glsl_version_str;
395     vogl::dynamic_string m_vendor_str;
396     vogl::dynamic_string m_renderer_str;
397
398     // Sorted driver reported extensions.
399     vogl::dynamic_string_array m_extensions;
400     // "Core" extensions are those extensions we know this context must support, independent of whether or not it actually appears in extensions.
401     vogl::dynamic_string_array m_core_extensions;
402
403     uint m_max_vertex_attribs;
404     uint m_max_texture_coords;
405     uint m_max_texture_units;
406     uint m_max_texture_image_units;
407     uint m_max_combined_texture_coords;
408     uint m_max_draw_buffers;
409     uint m_max_lights;
410     uint m_max_uniform_buffer_bindings;
411     uint m_max_arb_program_matrices;
412     uint m_max_arb_vertex_program_env_params;
413     uint m_max_arb_fragment_program_env_params;
414     uint m_max_transform_feedback_separate_attribs;
415
416     bool m_is_valid;
417
418     void query_string(vogl::dynamic_string &str, GLenum name);
419     vogl_gl_version_t parse_version_string(const vogl::dynamic_string &str);
420     bool query_extensions();
421     void init_context_limits();
422     void determine_core_extensions();
423 };
424
425 #endif // VOGL_CONTEXT_INFO_H