]> git.cworth.org Git - vogl/blob - src/voglcommon/vogl_context_info.h
- regression test now works on AMD
[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
339     // compat only - will be 0 in core
340     uint get_max_texture_coords() const
341     {
342         return m_max_texture_coords;
343     }
344     // compat only - will be 0 in core
345     uint get_max_texture_units() const
346     {
347         return m_max_texture_units;
348     }
349     uint get_max_texture_image_units() const
350     {
351         return m_max_texture_image_units;
352     }
353     uint get_max_combined_texture_coords() const
354     {
355         return m_max_combined_texture_coords;
356     }
357     uint get_max_draw_buffers() const
358     {
359         return m_max_draw_buffers;
360     }
361     uint get_max_lights() const
362     {
363         return m_max_lights;
364     }
365     uint get_max_uniform_buffer_bindings() const
366     {
367         return m_max_uniform_buffer_bindings;
368     }
369     uint get_max_arb_program_matrices() const
370     {
371         return m_max_arb_program_matrices;
372     }
373     uint get_max_arb_vertex_program_env_params() const
374     {
375         return m_max_arb_vertex_program_env_params;
376     }
377     uint get_max_arb_fragment_program_env_params() const
378     {
379         return m_max_arb_fragment_program_env_params;
380     }
381     uint get_max_transform_feedback_separate_attribs() const
382     {
383         return m_max_transform_feedback_separate_attribs;
384     }
385
386 private:
387     vogl_context_desc m_desc;
388
389     vogl_gl_version_t m_version;
390     vogl_gl_version_t m_glsl_version;
391
392     bool m_forward_compatible;
393     bool m_core_profile;
394     bool m_debug_context;
395
396     vogl::dynamic_string m_version_str;
397     vogl::dynamic_string m_glsl_version_str;
398     vogl::dynamic_string m_vendor_str;
399     vogl::dynamic_string m_renderer_str;
400
401     // Sorted driver reported extensions.
402     vogl::dynamic_string_array m_extensions;
403     // "Core" extensions are those extensions we know this context must support, independent of whether or not it actually appears in extensions.
404     vogl::dynamic_string_array m_core_extensions;
405
406     uint m_max_vertex_attribs;
407     uint m_max_texture_coords;
408     uint m_max_texture_units;
409     uint m_max_texture_image_units;
410     uint m_max_combined_texture_coords;
411     uint m_max_draw_buffers;
412     uint m_max_lights;
413     uint m_max_uniform_buffer_bindings;
414     uint m_max_arb_program_matrices;
415     uint m_max_arb_vertex_program_env_params;
416     uint m_max_arb_fragment_program_env_params;
417     uint m_max_transform_feedback_separate_attribs;
418
419     bool m_is_valid;
420
421     void query_string(vogl::dynamic_string &str, GLenum name);
422     vogl_gl_version_t parse_version_string(const vogl::dynamic_string &str);
423     bool query_extensions();
424     void init_context_limits();
425     void determine_core_extensions();
426 };
427
428 #endif // VOGL_CONTEXT_INFO_H