1 /**************************************************************************
3 * Copyright 2013-2014 RAD Game Tools and Valve Software
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:
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
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
24 **************************************************************************/
26 // File: vogl_gl_utils.cpp
27 #include "vogl_common.h"
29 #include "vogl_console.h"
30 #include "vogl_json.h"
31 #include "vogl_image.h"
32 #include "vogl_context_info.h"
33 #include "vogl_backtrace.h"
35 #define VOGL_DECLARE_PNAME_DEF_TABLE
36 #include "gl_pname_defs.inc"
38 #define VOGL_NAMESPACES_IMPLEMENTATION
39 #include "vogl_namespaces.h"
40 #undef VOGL_NAMESPACES_IMPLEMENTATION
42 //----------------------------------------------------------------------------------------------------------------------
44 //----------------------------------------------------------------------------------------------------------------------
46 bool g_gl_get_error_enabled = true;
48 //----------------------------------------------------------------------------------------------------------------------
49 // client side array tables
50 //----------------------------------------------------------------------------------------------------------------------
51 const vogl_client_side_array_desc_t g_vogl_client_side_array_descs[] =
53 #define VOGL_CLIENT_SIDE_ARRAY_DESC(id, entrypoint, is_enabled, get_binding, get_pointer, get_size, get_stride, get_type) \
55 entrypoint, is_enabled, get_binding, get_pointer, get_size, get_stride, get_type \
58 #include "vogl_client_side_array_descs.inc"
59 #undef VOGL_CLIENT_SIDE_ARRAY_DESC
62 //----------------------------------------------------------------------------------------------------------------------
63 // vogl_get_gl_integer
64 //----------------------------------------------------------------------------------------------------------------------
65 GLint vogl_get_gl_integer(GLenum pname)
69 VOGL_ASSERT(g_gl_enums.get_pname_count(pname) <= 4);
71 GLint values[4] = { 0, 0, 0, 0 };
72 GL_ENTRYPOINT(glGetIntegerv)(pname, values);
76 //----------------------------------------------------------------------------------------------------------------------
78 //----------------------------------------------------------------------------------------------------------------------
79 vec4I vogl_get_gl_vec4I(GLenum pname)
83 VOGL_ASSERT(g_gl_enums.get_pname_count(pname) <= 4);
86 GL_ENTRYPOINT(glGetIntegerv)(pname, &result[0]);
90 //----------------------------------------------------------------------------------------------------------------------
91 // vogl_get_gl_integer_indexed
92 //----------------------------------------------------------------------------------------------------------------------
93 GLint vogl_get_gl_integer_indexed(GLenum pname, uint index)
97 VOGL_ASSERT(g_gl_enums.get_pname_count(pname) <= 4);
99 GLint values[4] = { 0, 0, 0, 0 };
100 GL_ENTRYPOINT(glGetIntegeri_v)(pname, index, values);
104 //----------------------------------------------------------------------------------------------------------------------
105 // vogl_get_gl_integer64
106 //----------------------------------------------------------------------------------------------------------------------
107 GLint64 vogl_get_gl_integer64(GLenum pname)
111 VOGL_ASSERT(g_gl_enums.get_pname_count(pname) <= 4);
113 GLint64 values[4] = { 0, 0, 0, 0 };
114 GL_ENTRYPOINT(glGetInteger64v)(pname, values);
118 //----------------------------------------------------------------------------------------------------------------------
119 // vogl_get_gl_integer64_indexed
120 //----------------------------------------------------------------------------------------------------------------------
121 GLint64 vogl_get_gl_integer64_indexed(GLenum pname, uint index)
125 VOGL_ASSERT(g_gl_enums.get_pname_count(pname) <= 4);
127 GLint64 values[4] = { 0, 0, 0, 0 };
128 GL_ENTRYPOINT(glGetInteger64i_v)(pname, index, values);
132 //----------------------------------------------------------------------------------------------------------------------
133 // vogl_get_gl_boolean
134 //----------------------------------------------------------------------------------------------------------------------
135 GLboolean vogl_get_gl_boolean(GLenum pname)
139 VOGL_ASSERT(g_gl_enums.get_pname_count(pname) <= 4);
141 GLboolean values[4] = { 0, 0, 0, 0 };
142 GL_ENTRYPOINT(glGetBooleanv)(pname, values);
146 //----------------------------------------------------------------------------------------------------------------------
147 // vogl_get_gl_boolean_indexed
148 //----------------------------------------------------------------------------------------------------------------------
149 GLboolean vogl_get_gl_boolean_indexed(GLenum pname, uint index)
153 VOGL_ASSERT(g_gl_enums.get_pname_count(pname) <= 4);
155 GLboolean values[4] = { 0, 0, 0, 0 };
156 GL_ENTRYPOINT(glGetBooleani_v)(pname, index, values);
160 //----------------------------------------------------------------------------------------------------------------------
162 //----------------------------------------------------------------------------------------------------------------------
163 GLfloat vogl_get_gl_float(GLenum pname)
167 VOGL_ASSERT(g_gl_enums.get_pname_count(pname) <= 4);
169 GLfloat values[4] = { 0, 0, 0, 0 };
170 GL_ENTRYPOINT(glGetFloatv)(pname, values);
174 //----------------------------------------------------------------------------------------------------------------------
176 //----------------------------------------------------------------------------------------------------------------------
177 vec4F vogl_get_gl_vec4F(GLenum pname)
181 VOGL_ASSERT(g_gl_enums.get_pname_count(pname) <= 4);
184 GL_ENTRYPOINT(glGetFloatv)(pname, &values[0]);
188 //----------------------------------------------------------------------------------------------------------------------
189 // vogl_get_gl_matrix44F
190 //----------------------------------------------------------------------------------------------------------------------
191 matrix44F vogl_get_gl_matrix44F(GLenum pname)
195 VOGL_ASSERT(g_gl_enums.get_pname_count(pname) <= 16);
197 matrix44F values(cClear);
198 GL_ENTRYPOINT(glGetFloatv)(pname, &values[0][0]);
202 //----------------------------------------------------------------------------------------------------------------------
203 // vogl_get_gl_double
204 //----------------------------------------------------------------------------------------------------------------------
205 GLdouble vogl_get_gl_double(GLenum pname)
209 VOGL_ASSERT(g_gl_enums.get_pname_count(pname) <= 4);
211 GLdouble values[4] = { 0, 0, 0, 0 };
212 GL_ENTRYPOINT(glGetDoublev)(pname, values);
216 //----------------------------------------------------------------------------------------------------------------------
218 //----------------------------------------------------------------------------------------------------------------------
219 vec4D vogl_get_gl_vec4D(GLenum pname)
223 VOGL_ASSERT(g_gl_enums.get_pname_count(pname) <= 4);
226 GL_ENTRYPOINT(glGetDoublev)(pname, &values[0]);
230 //----------------------------------------------------------------------------------------------------------------------
231 // vogl_get_gl_matrix44D
232 //----------------------------------------------------------------------------------------------------------------------
233 matrix44D vogl_get_gl_matrix44D(GLenum pname)
237 VOGL_ASSERT(g_gl_enums.get_pname_count(pname) <= 16);
239 matrix44D values(cClear);
240 GL_ENTRYPOINT(glGetDoublev)(pname, &values[0][0]);
244 //----------------------------------------------------------------------------------------------------------------------
245 // vogl_get_gl_type_size (derived from apitrace)
246 //----------------------------------------------------------------------------------------------------------------------
247 uint32_t vogl_get_gl_type_size(uint32_t ogl_type)
254 case GL_UNSIGNED_BYTE:
256 case GL_UNSIGNED_BYTE_3_3_2:
257 case GL_UNSIGNED_BYTE_2_3_3_REV:
260 case GL_UNSIGNED_SHORT:
262 case GL_UNSIGNED_SHORT_5_6_5:
263 case GL_UNSIGNED_SHORT_5_6_5_REV:
264 case GL_UNSIGNED_SHORT_4_4_4_4:
265 case GL_UNSIGNED_SHORT_4_4_4_4_REV:
266 case GL_UNSIGNED_SHORT_5_5_5_1:
267 case GL_UNSIGNED_SHORT_1_5_5_5_REV:
273 case GL_UNSIGNED_INT:
276 case GL_UNSIGNED_INT_8_8_8_8:
277 case GL_UNSIGNED_INT_8_8_8_8_REV:
278 case GL_UNSIGNED_INT_10_10_10_2:
279 case GL_UNSIGNED_INT_2_10_10_10_REV:
280 case GL_UNSIGNED_INT_24_8:
281 case GL_UNSIGNED_INT_10F_11F_11F_REV:
282 case GL_UNSIGNED_INT_5_9_9_9_REV:
283 case GL_INT_2_10_10_10_REV:
289 vogl_warning_printf("%s: unknown GL type: 0x%04X\n", VOGL_FUNCTION_NAME, ogl_type);
295 //----------------------------------------------------------------------------------------------------------------------
296 // vogl_get_image_format_channels (derived from apitrace)
297 //----------------------------------------------------------------------------------------------------------------------
298 uint vogl_get_image_format_channels(GLenum format)
308 case GL_GREEN_INTEGER:
310 case GL_BLUE_INTEGER:
312 case GL_ALPHA_INTEGER:
315 case GL_LUMINANCE_INTEGER_EXT:
316 case GL_DEPTH_COMPONENT:
317 case GL_STENCIL_INDEX:
319 case GL_DEPTH_STENCIL:
320 case GL_LUMINANCE_ALPHA:
321 case GL_LUMINANCE_ALPHA_INTEGER_EXT:
324 case GL_422_EXT: // (luminance, chrominance)
325 case GL_422_REV_EXT: // (luminance, chrominance)
326 case GL_422_AVERAGE_EXT: // (luminance, chrominance)
327 case GL_422_REV_AVERAGE_EXT: // (luminance, chrominance)
328 case GL_HILO_NV: // (hi, lo)
329 case GL_DSDT_NV: // (ds, dt)
330 case GL_YCBCR_422_APPLE: // (luminance, chroma)
331 case GL_RGB_422_APPLE: // (G, B) on even pixels, (G, R) on odd pixels
332 case GL_YCRCB_422_SGIX: // (Y, [Cb,Cr])
338 case GL_DSDT_MAG_NV: // (ds, dt, magnitude)
339 case GL_YCRCB_444_SGIX: // (Cb, Y, Cr)
342 case GL_RGBA_INTEGER:
344 case GL_BGRA_INTEGER:
347 case GL_DSDT_MAG_VIB_NV: // (ds, dt, magnitude, vibrance)
351 case GL_FORMAT_SUBSAMPLE_24_24_OML:
352 case GL_FORMAT_SUBSAMPLE_244_244_OML:
353 // requires UNSIGNED_INT_10_10_10_2, so this value will be ignored
356 vogl_warning_printf("%s: unknown format 0x%04X\n", VOGL_FUNCTION_NAME, format);
362 //----------------------------------------------------------------------------------------------------------------------
363 // vogl_get_image_format_info (derived from apitrace)
364 //----------------------------------------------------------------------------------------------------------------------
365 void vogl_get_image_format_info(GLenum format, GLenum type, uint &num_channels, uint &bits_per_element, uint &bits_per_pixel)
369 num_channels = vogl_get_image_format_channels(format);
374 bits_per_pixel = bits_per_element = 1;
377 case GL_UNSIGNED_BYTE:
378 bits_per_element = 8;
379 bits_per_pixel = bits_per_element * num_channels;
382 case GL_UNSIGNED_SHORT:
384 bits_per_element = 16;
385 bits_per_pixel = bits_per_element * num_channels;
388 case GL_UNSIGNED_INT:
390 bits_per_element = 32;
391 bits_per_pixel = bits_per_element * num_channels;
393 case GL_UNSIGNED_BYTE_3_3_2:
394 case GL_UNSIGNED_BYTE_2_3_3_REV:
395 bits_per_pixel = bits_per_element = 8;
397 case GL_UNSIGNED_SHORT_4_4_4_4:
398 case GL_UNSIGNED_SHORT_4_4_4_4_REV:
399 case GL_UNSIGNED_SHORT_5_5_5_1:
400 case GL_UNSIGNED_SHORT_1_5_5_5_REV:
401 case GL_UNSIGNED_SHORT_5_6_5:
402 case GL_UNSIGNED_SHORT_5_6_5_REV:
403 case GL_UNSIGNED_SHORT_8_8_MESA:
404 case GL_UNSIGNED_SHORT_8_8_REV_MESA:
405 bits_per_pixel = bits_per_element = 16;
407 case GL_UNSIGNED_INT_8_8_8_8:
408 case GL_UNSIGNED_INT_8_8_8_8_REV:
409 case GL_UNSIGNED_INT_10_10_10_2:
410 case GL_UNSIGNED_INT_2_10_10_10_REV:
411 case GL_UNSIGNED_INT_24_8:
412 case GL_UNSIGNED_INT_10F_11F_11F_REV:
413 case GL_UNSIGNED_INT_5_9_9_9_REV:
414 case GL_UNSIGNED_INT_S8_S8_8_8_NV:
415 case GL_UNSIGNED_INT_8_8_S8_S8_REV_NV:
416 bits_per_pixel = bits_per_element = 32;
418 case GL_FLOAT_32_UNSIGNED_INT_24_8_REV:
419 bits_per_pixel = bits_per_element = 64;
422 vogl_warning_printf("%s: unknown type 0x%04X\n", VOGL_FUNCTION_NAME, type);
423 bits_per_pixel = bits_per_element = 0;
428 //----------------------------------------------------------------------------------------------------------------------
429 // vogl_get_image_format_size_in_bytes
430 //----------------------------------------------------------------------------------------------------------------------
431 uint vogl_get_image_format_size_in_bytes(GLenum format, GLenum type)
435 uint num_channels, bits_per_element, bits_per_pixel;
436 vogl_get_image_format_info(format, type, num_channels, bits_per_element, bits_per_pixel);
437 return (bits_per_pixel + 7) >> 3;
440 //----------------------------------------------------------------------------------------------------------------------
441 // vogl_has_active_context
442 //----------------------------------------------------------------------------------------------------------------------
443 bool vogl_has_active_context()
447 if (!GL_ENTRYPOINT(glXGetCurrentContext))
450 if (!GL_ENTRYPOINT(glXGetCurrentContext)())
456 //----------------------------------------------------------------------------------------------------------------------
457 // vogl_get_image_size (derived from apitrace)
458 //----------------------------------------------------------------------------------------------------------------------
459 size_t vogl_get_image_size(GLenum format, GLenum type, GLsizei width, GLsizei height, GLsizei depth)
463 if (!vogl_has_active_context())
465 vogl_error_printf("%s: vogl_get_image_size() called without an active context!\n", VOGL_FUNCTION_NAME);
470 uint bits_per_element;
472 vogl_get_image_format_info(format, type, num_channels, bits_per_element, bits_per_pixel);
474 GLint alignment = vogl_get_gl_integer(GL_UNPACK_ALIGNMENT);
475 GLint row_length = vogl_get_gl_integer(GL_UNPACK_ROW_LENGTH);
476 GLint image_height = vogl_get_gl_integer(GL_UNPACK_IMAGE_HEIGHT);
477 GLint skip_rows = vogl_get_gl_integer(GL_UNPACK_SKIP_ROWS);
478 GLint skip_pixels = vogl_get_gl_integer(GL_UNPACK_SKIP_PIXELS);
479 GLint skip_images = vogl_get_gl_integer(GL_UNPACK_SKIP_IMAGES);
486 size_t row_stride = (row_length * bits_per_pixel + 7) / 8;
488 if (((bits_per_element == 1 * 8) ||
489 (bits_per_element == 2 * 8) ||
490 (bits_per_element == 4 * 8) ||
491 (bits_per_element == 8 * 8)) &&
492 ((GLint)bits_per_element < alignment * 8))
494 row_stride = math::align_up_value(row_stride, alignment);
497 if (image_height <= 0)
499 image_height = height;
502 // GL_UNPACK_IMAGE_HEIGHT and GL_UNPACK_SKIP_IMAGES should probably not be considered for pixel rectangles
504 size_t image_stride = image_height * row_stride;
506 size_t size = depth * image_stride;
508 size += (skip_pixels * bits_per_pixel + 7) / 8;
509 size += skip_rows * row_stride;
510 size += skip_images * image_stride;
515 //----------------------------------------------------------------------------------------------------------------------
516 // vogl_get_tex_target_image_size
517 //----------------------------------------------------------------------------------------------------------------------
518 size_t vogl_get_tex_target_image_size(GLenum target, GLint level, GLenum format, GLenum type)
522 GLint width = 0, height = 0, depth = 0;
524 if (!vogl_has_active_context())
526 vogl_error_printf("%s: vogl_get_tex_target_image_size() called without an active context!\n", VOGL_FUNCTION_NAME);
530 if (!GL_ENTRYPOINT(glGetTexLevelParameteriv))
532 vogl_error_printf("%s: vogl_get_tex_target_image_size() called but the glGetTexLevelParameteriv function ptr is NULL!\n", VOGL_FUNCTION_NAME);
536 if (g_vogl_actual_gl_entrypoints.m_glGetTexLevelParameteriv)
538 GL_ENTRYPOINT(glGetTexLevelParameteriv)(target, level, GL_TEXTURE_WIDTH, &width);
539 GL_ENTRYPOINT(glGetTexLevelParameteriv)(target, level, GL_TEXTURE_HEIGHT, &height);
540 GL_ENTRYPOINT(glGetTexLevelParameteriv)(target, level, GL_TEXTURE_DEPTH, &depth);
543 if ((!width) || (!height) || (!depth))
546 return vogl_get_image_size(format, type, width, height, depth);
549 //----------------------------------------------------------------------------------------------------------------------
550 // vogl_determine_glMap1_size (originally from apitrace)
551 //----------------------------------------------------------------------------------------------------------------------
552 size_t vogl_determine_glMap1_size(GLenum target, GLint stride, GLint order)
563 case GL_MAP1_TEXTURE_COORD_1:
566 case GL_MAP1_TEXTURE_COORD_2:
570 case GL_MAP1_TEXTURE_COORD_3:
571 case GL_MAP1_VERTEX_3:
574 case GL_MAP1_COLOR_4:
575 case GL_MAP1_TEXTURE_COORD_4:
576 case GL_MAP1_VERTEX_4:
580 vogl_warning_printf("%s: unknown GLenum 0x%04X\n", VOGL_FUNCTION_NAME, target);
584 if (stride < channels)
587 return channels + stride * (order - 1);
590 //----------------------------------------------------------------------------------------------------------------------
591 // vogl_determine_glMap2_size (originally from apitrace)
592 //----------------------------------------------------------------------------------------------------------------------
593 size_t vogl_determine_glMap2_size(GLenum target, GLint ustride, GLint uorder, GLint vstride, GLint vorder)
597 if (uorder < 1 || vorder < 1)
604 case GL_MAP2_TEXTURE_COORD_1:
607 case GL_MAP2_TEXTURE_COORD_2:
611 case GL_MAP2_TEXTURE_COORD_3:
612 case GL_MAP2_VERTEX_3:
615 case GL_MAP2_COLOR_4:
616 case GL_MAP2_TEXTURE_COORD_4:
617 case GL_MAP2_VERTEX_4:
621 vogl_warning_printf("%s: unknown GLenum 0x%04X\n", VOGL_FUNCTION_NAME, target);
625 if (ustride < channels || vstride < channels)
629 ustride * (uorder - 1) +
630 vstride * (vorder - 1);
633 //----------------------------------------------------------------------------------------------------------------------
634 // vogl_enum_desc::init_sort_priority
635 //----------------------------------------------------------------------------------------------------------------------
636 void vogl_enum_desc::init_sort_priority()
640 m_sort_priority = cSCNone;
642 if (m_macro_name.ends_with("_EXT"))
643 m_sort_priority = cSCEXT;
644 else if (m_macro_name.ends_with("_ARB"))
645 m_sort_priority = cSCARB;
646 else if (m_macro_name.ends_with("_OES"))
647 m_sort_priority = cSCOES;
650 static const char *s_vendor_suffixes[] = { "_NV", "_AMD", "_INTEL", "_QCOM", "_ATI", "_SGIS", "_SGIX", "_ANGLE", "_APPLE", "_MESA", "_IBM" };
651 for (uint i = 0; i < VOGL_ARRAY_SIZE(s_vendor_suffixes); i++)
653 if (m_macro_name.ends_with(s_vendor_suffixes[i]))
655 m_sort_priority = cSCVendor;
662 //----------------------------------------------------------------------------------------------------------------------
663 // vogl_enum_desc::operator <
664 //----------------------------------------------------------------------------------------------------------------------
665 bool vogl_enum_desc::operator<(const vogl_enum_desc &rhs) const
669 if (m_sort_priority < rhs.m_sort_priority)
671 else if (m_sort_priority == rhs.m_sort_priority)
673 int comp_result = m_prefix.compare_using_length(rhs.m_prefix, true);
676 else if (comp_result == 0)
677 return m_macro_name.compare_using_length(rhs.m_macro_name, true) < 0;
682 //----------------------------------------------------------------------------------------------------------------------
683 // gl_enums::gl_enums
684 //----------------------------------------------------------------------------------------------------------------------
689 memset(m_gl_enum_to_pname_def_index, 0xFF, sizeof(m_gl_enum_to_pname_def_index));
691 for (uint i = 0; i < GL_PNAME_DEFS_ARRAY_SIZE; i++)
693 if (g_gl_pname_defs[i].m_gl_enum < 0x10000)
695 if (m_gl_enum_to_pname_def_index[g_gl_pname_defs[i].m_gl_enum] != 0xFFFF)
697 vogl_debug_printf("%s: duplicate GL enum in g_gl_pname_defs table: 0x%04X %s\n", VOGL_METHOD_NAME, i, g_gl_pname_defs[i].m_pName);
701 m_gl_enum_to_pname_def_index[g_gl_pname_defs[i].m_gl_enum] = i;
703 m_enum_name_hash_map.insert(g_gl_pname_defs[i].m_pName, g_gl_pname_defs[i].m_gl_enum);
708 init_image_formats();
711 //----------------------------------------------------------------------------------------------------------------------
712 // gl_enums::add_enum
713 //----------------------------------------------------------------------------------------------------------------------
714 void gl_enums::add_enum(const char *pPrefix, const char *pSpec_type, const char *pGL_type, const char *pName, uint64_t value)
719 gl_enum_value_to_enum_desc_hash_map::insert_result ins_result(m_enum_value_hash_map.insert(value, vogl_enum_desc_vec()));
720 vogl_enum_desc_vec &vec = ins_result.first->second;
721 vogl_enum_desc *pDesc = vec.enlarge(1);
722 pDesc->m_value = value;
723 pDesc->m_prefix = pPrefix;
724 pDesc->m_spec_type = pSpec_type;
725 pDesc->m_gl_type = pGL_type;
726 pDesc->m_macro_name = pName;
727 pDesc->init_sort_priority();
731 gl_spec_type_and_value_to_enum_desc_hash_map_t::insert_result ins_result(m_spec_type_and_enum_value_hash_map.insert(vogl_spec_type_and_value_enum_key(pSpec_type, value), vogl_enum_desc_vec()));
732 vogl_enum_desc_vec &vec = ins_result.first->second;
734 vogl_enum_desc *pDesc = vec.enlarge(1);
735 pDesc->m_value = value;
736 pDesc->m_prefix = pPrefix;
737 pDesc->m_spec_type = pSpec_type;
738 pDesc->m_gl_type = pGL_type;
739 pDesc->m_macro_name = pName;
740 pDesc->init_sort_priority();
744 gl_enum_name_hash_map::insert_result res(m_enum_name_hash_map.insert(pName, value));
746 // Check for duplicate definitions with different values (compare apitrace's pname table vs. the spec)
747 uint64_t value_in_map = res.first->second;
748 VOGL_ASSERT(value_in_map == value);
749 VOGL_NOTE_UNUSED(value_in_map);
753 //----------------------------------------------------------------------------------------------------------------------
754 // gl_enums::init_enum_descs
755 //----------------------------------------------------------------------------------------------------------------------
756 void gl_enums::init_enum_descs()
760 #define DEFINE_GL_ENUM_CATEGORY_BEGIN(spectype)
761 #define DEFINE_GL_DEFINE_MEMBER(prefix, spec_type, enum_name)
762 #define DEFINE_GL_ENUM_MEMBER(prefix, spec_type, gl_type, enum_name, value) add_enum(#prefix, #spec_type, gl_type, enum_name, value);
763 #define DEFINE_GL_ENUM_CATEGORY_END(x)
765 #include "gl_enum_desc.inc"
766 #include "glx_enum_desc.inc"
768 #undef DEFINE_GL_ENUM_CATEGORY_BEGIN
769 #undef DEFINE_GL_DEFINE_MEMBER
770 #undef DEFINE_GL_ENUM_MEMBER
771 #undef DEFINE_GL_ENUM_CATEGORY_END
773 for (gl_enum_value_to_enum_desc_hash_map::iterator it = m_enum_value_hash_map.begin(); it != m_enum_value_hash_map.end(); ++it)
775 vogl_enum_desc_vec &vec = it->second;
779 for (gl_spec_type_and_value_to_enum_desc_hash_map_t::iterator it = m_spec_type_and_enum_value_hash_map.begin(); it != m_spec_type_and_enum_value_hash_map.end(); ++it)
781 vogl_enum_desc_vec &vec = it->second;
786 //----------------------------------------------------------------------------------------------------------------------
787 // gl_enums::get_name
788 //----------------------------------------------------------------------------------------------------------------------
789 const char *gl_enums::find_name(uint64_t gl_enum, const char *pPreferred_prefix) const
793 gl_enum_value_to_enum_desc_hash_map::const_iterator it(m_enum_value_hash_map.find(gl_enum));
794 if (it != m_enum_value_hash_map.end())
796 const vogl_enum_desc_vec &desc_vec = it->second;
798 if (pPreferred_prefix)
800 for (uint i = 0; i < desc_vec.size(); i++)
801 if (!desc_vec[i].m_prefix.compare(pPreferred_prefix, false)) // purposely not case sensitive
802 return desc_vec[i].m_macro_name.get_ptr();
805 return desc_vec[0].m_macro_name.get_ptr();
808 // Try falling back to the pname table - some of the extension enums are not in the .spec files but are in apitrace's pname table.
809 int pname_index = find_pname_def_index(gl_enum);
810 if ((pname_index >= 0) && (g_gl_pname_defs[pname_index].m_pName))
811 return g_gl_pname_defs[pname_index].m_pName;
813 if (g_command_line_params.get_value_as_bool("debug"))
815 vogl_debug_printf("%s: Failed finding GL enum 0x%08" PRIX64 ", API prefix \"%s\"\n", VOGL_METHOD_NAME, gl_enum, pPreferred_prefix ? pPreferred_prefix : "");
821 //----------------------------------------------------------------------------------------------------------------------
822 // gl_enums::find_gl_image_format_name
823 //----------------------------------------------------------------------------------------------------------------------
824 const char *gl_enums::find_gl_image_format_name(GLenum gl_enum) const
828 const char *const *ppName = m_image_formats.find_value(gl_enum);
831 return find_gl_name(gl_enum);
834 //----------------------------------------------------------------------------------------------------------------------
835 // gl_enums::find_name
836 //----------------------------------------------------------------------------------------------------------------------
837 const char *gl_enums::find_name(const char *pSpec_type, uint64_t gl_enum, const char *pPreferred_prefix) const
841 // The spec type search is fuzzy but it does guide the search to saner enums in many common cases.
842 // The spec types in the enum table don't always match up with the spec types in the GL API param desc's.
843 // This isn't critical but it would be nice to try resolving this crap.
846 gl_spec_type_and_value_to_enum_desc_hash_map_t::const_iterator it(m_spec_type_and_enum_value_hash_map.find(vogl_spec_type_and_value_enum_key(pSpec_type, gl_enum)));
847 if (it != m_spec_type_and_enum_value_hash_map.end())
849 const vogl_enum_desc_vec &desc_vec = it->second;
851 if (pPreferred_prefix)
853 for (uint i = 0; i < desc_vec.size(); i++)
854 if (!desc_vec[i].m_prefix.compare(pPreferred_prefix, false)) // purposely not case sensitive
855 return desc_vec[i].m_macro_name.get_ptr();
858 return desc_vec[0].m_macro_name.get_ptr();
862 if (g_command_line_params.get_value_as_bool("debug"))
864 vogl_debug_printf("%s: Failed finding GL enum with spec type %s, enum 0x%08" PRIX64 ", API prefix \"%s\", falling back to non-spec type search\n",
865 VOGL_METHOD_NAME, pSpec_type, gl_enum, pPreferred_prefix ? pPreferred_prefix : "");
870 return find_name(gl_enum, pPreferred_prefix);
873 //----------------------------------------------------------------------------------------------------------------------
874 // gl_enums::find_enum
875 //----------------------------------------------------------------------------------------------------------------------
876 const char *gl_enums::find_name(uint64_t gl_enum, gl_entrypoint_id_t entrypoint_id, int param_index) const
878 VOGL_ASSERT(entrypoint_id < VOGL_NUM_ENTRYPOINTS);
880 const gl_entrypoint_desc_t &entrypoint_desc = g_vogl_entrypoint_descs[entrypoint_id];
882 const char *pSpec_type = NULL;
885 pSpec_type = entrypoint_desc.m_pReturn_spec_type;
889 VOGL_ASSERT(param_index < static_cast<int>(entrypoint_desc.m_num_params));
891 pSpec_type = g_vogl_entrypoint_param_descs[entrypoint_id][param_index].m_pSpec_type;
894 return find_name(pSpec_type, gl_enum, entrypoint_desc.m_pAPI_prefix);
897 //----------------------------------------------------------------------------------------------------------------------
898 // gl_enums::find_enum
899 //----------------------------------------------------------------------------------------------------------------------
900 uint64_t gl_enums::find_enum(const dynamic_string &str) const
904 gl_enum_name_hash_map::const_iterator it(m_enum_name_hash_map.find(str));
905 return (it == m_enum_name_hash_map.end()) ? static_cast<uint64_t>(cUnknownEnum) : it->second;
908 //----------------------------------------------------------------------------------------------------------------------
909 // gl_enums::get_pname_count
910 //----------------------------------------------------------------------------------------------------------------------
911 int gl_enums::get_pname_count(uint64_t gl_enum) const
915 if (GL_ENTRYPOINT(glGetIntegerv))
917 if (gl_enum == GL_COMPRESSED_TEXTURE_FORMATS)
920 GL_ENTRYPOINT(glGetIntegerv)(GL_NUM_COMPRESSED_TEXTURE_FORMATS, &value);
923 else if (gl_enum == GL_PROGRAM_BINARY_FORMATS)
926 GL_ENTRYPOINT(glGetIntegerv)(GL_NUM_PROGRAM_BINARY_FORMATS, &value);
931 int pname_index = find_pname_def_index(gl_enum);
932 if (pname_index >= 0)
933 return g_gl_pname_defs[pname_index].m_count;
935 vogl_warning_printf("%s: Unknown GL enum: 0x%08" PRIX64 "\n", VOGL_METHOD_NAME, gl_enum);
939 //----------------------------------------------------------------------------------------------------------------------
940 // gl_enums::get_pname_type
941 //----------------------------------------------------------------------------------------------------------------------
942 int gl_enums::get_pname_type(uint64_t gl_enum) const
945 int pname_index = find_pname_def_index(gl_enum);
946 if (pname_index >= 0)
947 return g_gl_pname_defs[pname_index].m_type;
949 vogl_warning_printf("%s: Unknown GL enum: 0x%08" PRIX64 "\n", VOGL_METHOD_NAME, gl_enum);
953 //----------------------------------------------------------------------------------------------------------------------
954 // gl_enums::find_pname_def_index
955 //----------------------------------------------------------------------------------------------------------------------
956 int gl_enums::find_pname_def_index(uint64_t gl_enum) const
960 if (gl_enum < 0x10000)
962 int pname_index = m_gl_enum_to_pname_def_index[static_cast<uint>(gl_enum)];
963 if (pname_index != 0xFFFF)
966 return vogl::cInvalidIndex;
969 //----------------------------------------------------------------------------------------------------------------------
970 // GL image format to enum helpers
971 //----------------------------------------------------------------------------------------------------------------------
972 void gl_enums::init_image_formats()
976 #define IMG_FMT(x) m_image_formats.insert(x, #x);
977 #include "vogl_image_formats.inc"
981 //----------------------------------------------------------------------------------------------------------------------
982 // vogl_get_bound_gl_buffer
983 //----------------------------------------------------------------------------------------------------------------------
984 GLuint vogl_get_bound_gl_buffer(GLenum target)
991 case GL_ARRAY_BUFFER:
992 t = GL_ARRAY_BUFFER_BINDING;
994 case GL_ATOMIC_COUNTER_BUFFER:
995 t = GL_ATOMIC_COUNTER_BUFFER_BINDING;
997 case GL_COPY_READ_BUFFER:
998 t = GL_COPY_READ_BUFFER_BINDING;
1000 case GL_COPY_WRITE_BUFFER:
1001 t = GL_COPY_WRITE_BUFFER_BINDING;
1003 case GL_DRAW_INDIRECT_BUFFER:
1004 t = GL_DRAW_INDIRECT_BUFFER_BINDING;
1006 case GL_DISPATCH_INDIRECT_BUFFER:
1007 t = GL_DISPATCH_INDIRECT_BUFFER_BINDING;
1009 case GL_ELEMENT_ARRAY_BUFFER:
1010 t = GL_ELEMENT_ARRAY_BUFFER_BINDING;
1012 case GL_PIXEL_PACK_BUFFER:
1013 t = GL_PIXEL_PACK_BUFFER_BINDING;
1015 case GL_PIXEL_UNPACK_BUFFER:
1016 t = GL_PIXEL_UNPACK_BUFFER_BINDING;
1018 case GL_SHADER_STORAGE_BUFFER:
1019 t = GL_SHADER_STORAGE_BUFFER_BINDING;
1021 case GL_TRANSFORM_FEEDBACK_BUFFER:
1022 t = GL_TRANSFORM_FEEDBACK_BUFFER_BINDING;
1024 case GL_UNIFORM_BUFFER:
1025 t = GL_UNIFORM_BUFFER_BINDING;
1027 case GL_TEXTURE_BUFFER:
1028 t = GL_TEXTURE_BINDING_BUFFER;
1032 console::warning("%s: Unknown buffer GL enum 0x%08X\n", VOGL_FUNCTION_NAME, target);
1037 GL_ENTRYPOINT(glGetIntegerv)(t, &id);
1041 //----------------------------------------------------------------------------------------------------------------------
1042 // vogl_reset_pixel_store_states
1043 //----------------------------------------------------------------------------------------------------------------------
1044 void vogl_reset_pixel_store_states()
1048 GL_ENTRYPOINT(glPixelStorei)(GL_PACK_SWAP_BYTES, false);
1049 GL_ENTRYPOINT(glPixelStorei)(GL_PACK_LSB_FIRST, false);
1050 GL_ENTRYPOINT(glPixelStorei)(GL_PACK_ROW_LENGTH, 0);
1051 GL_ENTRYPOINT(glPixelStorei)(GL_PACK_IMAGE_HEIGHT, 0);
1052 GL_ENTRYPOINT(glPixelStorei)(GL_PACK_SKIP_ROWS, 0);
1053 GL_ENTRYPOINT(glPixelStorei)(GL_PACK_SKIP_PIXELS, 0);
1054 GL_ENTRYPOINT(glPixelStorei)(GL_PACK_SKIP_IMAGES, 0);
1055 GL_ENTRYPOINT(glPixelStorei)(GL_PACK_ALIGNMENT, 1);
1056 GL_ENTRYPOINT(glPixelStorei)(GL_UNPACK_SWAP_BYTES, false);
1057 GL_ENTRYPOINT(glPixelStorei)(GL_UNPACK_LSB_FIRST, false);
1058 GL_ENTRYPOINT(glPixelStorei)(GL_UNPACK_ROW_LENGTH, 0);
1059 GL_ENTRYPOINT(glPixelStorei)(GL_UNPACK_IMAGE_HEIGHT, 0);
1060 GL_ENTRYPOINT(glPixelStorei)(GL_UNPACK_SKIP_ROWS, 0);
1061 GL_ENTRYPOINT(glPixelStorei)(GL_UNPACK_SKIP_PIXELS, 0);
1062 GL_ENTRYPOINT(glPixelStorei)(GL_UNPACK_SKIP_IMAGES, 0);
1063 GL_ENTRYPOINT(glPixelStorei)(GL_UNPACK_ALIGNMENT, 1);
1066 //----------------------------------------------------------------------------------------------------------------------
1067 // vogl_reset_pixel_transfer_states
1068 //----------------------------------------------------------------------------------------------------------------------
1069 void vogl_reset_pixel_transfer_states()
1073 GL_ENTRYPOINT(glPixelTransferi)(GL_MAP_COLOR, GL_FALSE);
1075 GL_ENTRYPOINT(glPixelTransferi)(GL_MAP_STENCIL, GL_FALSE);
1076 GL_ENTRYPOINT(glPixelTransferi)(GL_INDEX_SHIFT, 0);
1077 GL_ENTRYPOINT(glPixelTransferi)(GL_INDEX_OFFSET, 0);
1079 GL_ENTRYPOINT(glPixelTransferf)(GL_RED_SCALE, 1.0f);
1080 GL_ENTRYPOINT(glPixelTransferf)(GL_GREEN_SCALE, 1.0f);
1081 GL_ENTRYPOINT(glPixelTransferf)(GL_BLUE_SCALE, 1.0f);
1082 GL_ENTRYPOINT(glPixelTransferf)(GL_ALPHA_SCALE, 1.0f);
1083 GL_ENTRYPOINT(glPixelTransferf)(GL_DEPTH_SCALE, 1.0f);
1085 GL_ENTRYPOINT(glPixelTransferf)(GL_RED_BIAS, 0.0f);
1086 GL_ENTRYPOINT(glPixelTransferf)(GL_GREEN_BIAS, 0.0f);
1087 GL_ENTRYPOINT(glPixelTransferf)(GL_BLUE_BIAS, 0.0f);
1088 GL_ENTRYPOINT(glPixelTransferf)(GL_ALPHA_BIAS, 0.0f);
1089 GL_ENTRYPOINT(glPixelTransferf)(GL_DEPTH_BIAS, 0.0f);
1091 GL_ENTRYPOINT(glPixelTransferf)(GL_POST_CONVOLUTION_RED_SCALE, 1.0f);
1092 GL_ENTRYPOINT(glPixelTransferf)(GL_POST_CONVOLUTION_GREEN_SCALE, 1.0f);
1093 GL_ENTRYPOINT(glPixelTransferf)(GL_POST_CONVOLUTION_BLUE_SCALE, 1.0f);
1094 GL_ENTRYPOINT(glPixelTransferf)(GL_POST_CONVOLUTION_ALPHA_SCALE, 1.0f);
1096 GL_ENTRYPOINT(glPixelTransferf)(GL_POST_CONVOLUTION_RED_BIAS, 0.0f);
1097 GL_ENTRYPOINT(glPixelTransferf)(GL_POST_CONVOLUTION_GREEN_BIAS, 0.0f);
1098 GL_ENTRYPOINT(glPixelTransferf)(GL_POST_CONVOLUTION_BLUE_BIAS, 0.0f);
1099 GL_ENTRYPOINT(glPixelTransferf)(GL_POST_CONVOLUTION_ALPHA_BIAS, 0.0f);
1101 GL_ENTRYPOINT(glPixelTransferf)(GL_POST_COLOR_MATRIX_RED_SCALE, 1.0f);
1102 GL_ENTRYPOINT(glPixelTransferf)(GL_POST_COLOR_MATRIX_GREEN_SCALE, 1.0f);
1103 GL_ENTRYPOINT(glPixelTransferf)(GL_POST_COLOR_MATRIX_BLUE_SCALE, 1.0f);
1104 GL_ENTRYPOINT(glPixelTransferf)(GL_POST_COLOR_MATRIX_ALPHA_SCALE, 1.0f);
1106 GL_ENTRYPOINT(glPixelTransferf)(GL_POST_COLOR_MATRIX_RED_BIAS, 0.0f);
1107 GL_ENTRYPOINT(glPixelTransferf)(GL_POST_COLOR_MATRIX_GREEN_BIAS, 0.0f);
1108 GL_ENTRYPOINT(glPixelTransferf)(GL_POST_COLOR_MATRIX_BLUE_BIAS, 0.0f);
1109 GL_ENTRYPOINT(glPixelTransferf)(GL_POST_COLOR_MATRIX_ALPHA_BIAS, 0.0f);
1112 #include "vogl_general_context_state.h"
1114 //----------------------------------------------------------------------------------------------------------------------
1115 // vogl_copy_buffer_to_image
1116 //----------------------------------------------------------------------------------------------------------------------
1117 bool vogl_copy_buffer_to_image(void *pDst, uint dst_size, uint width, uint height, GLuint format, GLuint type, bool flip_image, GLuint framebuffer, GLuint read_buffer, GLuint pixel_pack_buffer)
1121 if ((!width) || (!height))
1127 // Forceably discard any errors up to here, even in benchmark mode, because glReadPixels() is going to be slow as hell anyway
1128 GL_ENTRYPOINT(glGetError)();
1130 // Save the state we'll be changing
1131 vogl_scoped_state_saver state_saver(cGSTPixelStore);
1132 vogl_scoped_binding_state orig_framebuffers(GL_DRAW_FRAMEBUFFER, GL_READ_FRAMEBUFFER, GL_PIXEL_PACK_BUFFER);
1134 // Set the state we need to do a glReadPixels()
1135 vogl_reset_pixel_store_states();
1137 GL_ENTRYPOINT(glBindBuffer)(GL_PIXEL_PACK_BUFFER, pixel_pack_buffer);
1138 GL_ENTRYPOINT(glBindFramebuffer)(GL_FRAMEBUFFER, framebuffer);
1140 vogl_scoped_state_saver framebuffer_state_saver(cGSTReadBuffer, cGSTDrawBuffer);
1142 GL_ENTRYPOINT(glReadBuffer)(read_buffer);
1144 VOGL_CHECK_GL_ERROR;
1146 // Now read the pixels
1147 GLenum err = GL_INVALID_VALUE;
1149 // Ensure the destination buffer is big enough
1150 size_t image_size = vogl_get_image_size(format, type, width, height, 1);
1151 if ((pDst) && ((!image_size) || (dst_size < image_size)))
1157 GL_ENTRYPOINT(glReadPixels)(0, 0, width, height, format, type, pDst);
1159 err = GL_ENTRYPOINT(glGetError());
1164 console::warning("%s: GL error 0x%X while calling glReadPixels()!\n", VOGL_FUNCTION_NAME, err);
1167 // Optionally flip the image
1168 if ((flip_image) && (err == GL_NO_ERROR) && (pDst))
1170 size_t pitch = vogl_get_image_size(format, type, width, 1, 1);
1171 if (pitch > cUINT32_MAX)
1177 if ((pitch) && ((image_size / pitch) == height))
1179 vogl::vector<uint8> row_buf(static_cast<uint>(pitch));
1181 for (uint y = 0; y < (height / 2); y++)
1183 uint8 *pA = reinterpret_cast<uint8 *>(pDst) + y * pitch;
1184 uint8 *pB = reinterpret_cast<uint8 *>(pDst) + (height - 1 - y) * pitch;
1185 memcpy(row_buf.get_ptr(), pA, pitch);
1186 memcpy(pA, pB, pitch);
1187 memcpy(pB, row_buf.get_ptr(), pitch);
1192 // Don't know how to flip it
1197 // Restore previous state - order is critical here!
1198 framebuffer_state_saver.restore();
1199 orig_framebuffers.restore();
1200 state_saver.restore();
1202 VOGL_CHECK_GL_ERROR;
1204 return (err == GL_NO_ERROR);
1207 //----------------------------------------------------------------------------------------------------------------------
1208 // vogl_check_gl_error_internal
1209 // Returns *true* on error
1210 //----------------------------------------------------------------------------------------------------------------------
1211 bool vogl_check_gl_error_internal(bool suppress_error_message, const char *pFile, uint line, const char *pFunc)
1215 bool status = false;
1218 // http://www.opengl.org/sdk/docs/man/xhtml/glGetError.xml
1219 // "Thus, glGetError should always be called in a loop, until it returns GL_NO_ERROR, if all error flags are to be reset."
1220 GLenum gl_err = GL_ENTRYPOINT(glGetError)();
1221 if (gl_err == GL_NO_ERROR)
1224 if (!suppress_error_message)
1226 console::error("%s: GL error: 0x%08X (%u): %s (Called From File: %s, line: %u, func: %s)\n", VOGL_FUNCTION_NAME, gl_err, gl_err, g_gl_enums.find_name("ErrorCode", gl_err), pFile ? pFile : "?", line, pFunc ? pFunc : "?");
1229 dynamic_string_array backtrace;
1230 if (get_printable_backtrace(backtrace))
1232 console::error("Backtrace:\n");
1233 for (uint i = 0; i < backtrace.size(); i++)
1234 console::error("%s\n", backtrace[i].get_ptr());
1244 //----------------------------------------------------------------------------------------------------------------------
1245 // vogl_enable_gl_get_errors
1246 //----------------------------------------------------------------------------------------------------------------------
1247 void vogl_enable_gl_get_error()
1249 g_gl_get_error_enabled = true;
1252 //----------------------------------------------------------------------------------------------------------------------
1253 // vogl_disable_gl_get_errors
1254 //----------------------------------------------------------------------------------------------------------------------
1255 void vogl_disable_gl_get_error()
1257 g_gl_get_error_enabled = false;
1260 //----------------------------------------------------------------------------------------------------------------------
1261 // vogl_is_gl_get_error_enabled
1262 //----------------------------------------------------------------------------------------------------------------------
1263 bool vogl_is_gl_get_error_enabled()
1265 return g_gl_get_error_enabled;
1268 //----------------------------------------------------------------------------------------------------------------------
1269 // vogl_is_draw_entrypoint
1270 //----------------------------------------------------------------------------------------------------------------------
1271 bool vogl_is_draw_entrypoint(gl_entrypoint_id_t id)
1277 case VOGL_ENTRYPOINT_glDrawRangeElements:
1278 case VOGL_ENTRYPOINT_glDrawRangeElementsBaseVertex:
1279 case VOGL_ENTRYPOINT_glDrawElements:
1280 case VOGL_ENTRYPOINT_glDrawArrays:
1281 case VOGL_ENTRYPOINT_glDrawArraysEXT:
1282 case VOGL_ENTRYPOINT_glDrawElementsBaseVertex:
1283 case VOGL_ENTRYPOINT_glDrawElementsInstanced:
1284 case VOGL_ENTRYPOINT_glDrawElementsInstancedARB:
1285 case VOGL_ENTRYPOINT_glDrawElementsInstancedBaseVertex:
1286 case VOGL_ENTRYPOINT_glDrawArraysIndirect:
1287 case VOGL_ENTRYPOINT_glDrawArraysInstanced:
1288 case VOGL_ENTRYPOINT_glDrawArraysInstancedARB:
1289 case VOGL_ENTRYPOINT_glDrawArraysInstancedBaseInstance:
1290 case VOGL_ENTRYPOINT_glDrawArraysInstancedEXT:
1291 case VOGL_ENTRYPOINT_glMultiDrawArrays:
1292 case VOGL_ENTRYPOINT_glMultiDrawArraysEXT:
1293 case VOGL_ENTRYPOINT_glMultiDrawElements:
1294 case VOGL_ENTRYPOINT_glMultiDrawElementsEXT:
1295 case VOGL_ENTRYPOINT_glMultiDrawElementsBaseVertex:
1296 case VOGL_ENTRYPOINT_glDrawElementArrayAPPLE:
1297 case VOGL_ENTRYPOINT_glDrawElementArrayATI:
1298 case VOGL_ENTRYPOINT_glDrawElementsIndirect:
1299 case VOGL_ENTRYPOINT_glDrawElementsInstancedBaseInstance:
1300 case VOGL_ENTRYPOINT_glDrawElementsInstancedBaseVertexBaseInstance:
1301 case VOGL_ENTRYPOINT_glDrawElementsInstancedEXT:
1302 case VOGL_ENTRYPOINT_glDrawRangeElementArrayAPPLE:
1303 case VOGL_ENTRYPOINT_glDrawRangeElementArrayATI:
1304 case VOGL_ENTRYPOINT_glDrawRangeElementsEXT:
1305 case VOGL_ENTRYPOINT_glDrawTransformFeedback:
1306 case VOGL_ENTRYPOINT_glDrawTransformFeedbackInstanced:
1307 case VOGL_ENTRYPOINT_glDrawTransformFeedbackNV:
1308 case VOGL_ENTRYPOINT_glDrawTransformFeedbackStream:
1309 case VOGL_ENTRYPOINT_glDrawTransformFeedbackStreamInstanced:
1310 case VOGL_ENTRYPOINT_glMultiDrawArraysIndirect:
1311 case VOGL_ENTRYPOINT_glMultiDrawArraysIndirectAMD:
1312 case VOGL_ENTRYPOINT_glMultiDrawElementArrayAPPLE:
1313 case VOGL_ENTRYPOINT_glMultiDrawElementsIndirect:
1314 case VOGL_ENTRYPOINT_glMultiDrawElementsIndirectAMD:
1315 case VOGL_ENTRYPOINT_glMultiDrawRangeElementArrayAPPLE:
1323 //----------------------------------------------------------------------------------------------------------------------
1324 // vogl_is_clear_entrypoint
1325 //----------------------------------------------------------------------------------------------------------------------
1326 bool vogl_is_clear_entrypoint(gl_entrypoint_id_t id)
1332 case VOGL_ENTRYPOINT_glClear:
1333 case VOGL_ENTRYPOINT_glClearBufferiv:
1334 case VOGL_ENTRYPOINT_glClearBufferfv:
1335 case VOGL_ENTRYPOINT_glClearBufferuiv:
1336 case VOGL_ENTRYPOINT_glClearBufferfi:
1344 //----------------------------------------------------------------------------------------------------------------------
1345 // vogl_get_json_value_as_enum
1346 //----------------------------------------------------------------------------------------------------------------------
1347 GLenum vogl_get_json_value_as_enum(const json_node &node, const char *pKey, GLenum def)
1351 uint64_t v = g_gl_enums.find_enum(node.value_as_string(pKey));
1352 if (v == gl_enums::cUnknownEnum)
1354 VOGL_ASSERT(v <= cUINT32_MAX);
1355 return static_cast<GLenum>(v);
1358 //----------------------------------------------------------------------------------------------------------------------
1359 // vogl_get_json_value_as_enum
1360 //----------------------------------------------------------------------------------------------------------------------
1361 GLenum vogl_get_json_value_as_enum(const json_value &val, GLenum def)
1365 uint64_t v = g_gl_enums.find_enum(val.as_string());
1366 if (v == gl_enums::cUnknownEnum)
1368 VOGL_ASSERT(v <= cUINT32_MAX);
1369 return static_cast<GLenum>(v);
1372 //----------------------------------------------------------------------------------------------------------------------
1373 // vogl_get_binding_from_target
1374 //----------------------------------------------------------------------------------------------------------------------
1375 GLenum vogl_get_binding_from_target(GLenum target)
1381 #define DEFINE_BINDING(c, t, b) \
1384 #include "gl_buffer_bindings.inc"
1385 #undef DEFINE_BINDING
1389 console::warning("%s: Unknown target GL enum 0x%08X\n", VOGL_FUNCTION_NAME, target);
1395 //----------------------------------------------------------------------------------------------------------------------
1396 // vogl_get_object_category_from_binding
1397 //----------------------------------------------------------------------------------------------------------------------
1398 GLenum vogl_get_object_category_from_binding(GLenum binding)
1404 #define DEFINE_BINDING(c, t, b) \
1407 #include "gl_buffer_bindings.inc"
1408 #undef DEFINE_BINDING
1412 console::warning("%s: Unknown binding GL enum 0x%08X\n", VOGL_FUNCTION_NAME, binding);
1418 //----------------------------------------------------------------------------------------------------------------------
1419 // vogl_get_object_category_from_target
1420 //----------------------------------------------------------------------------------------------------------------------
1421 GLenum vogl_get_object_category_from_target(GLenum target)
1427 #define DEFINE_BINDING(c, t, b) \
1430 #include "gl_buffer_bindings.inc"
1431 #undef DEFINE_BINDING
1435 console::warning("%s: Unknown target GL enum 0x%08X\n", VOGL_FUNCTION_NAME, target);
1441 //----------------------------------------------------------------------------------------------------------------------
1442 // vogl_get_target_from_binding
1443 //----------------------------------------------------------------------------------------------------------------------
1444 GLenum vogl_get_target_from_binding(GLenum binding)
1450 #define DEFINE_BINDING(c, t, b) \
1453 #include "gl_buffer_bindings.inc"
1454 #undef DEFINE_BINDING
1458 console::warning("%s: Unknown binding GL enum 0x%08X\n", VOGL_FUNCTION_NAME, binding);
1464 //----------------------------------------------------------------------------------------------------------------------
1466 //----------------------------------------------------------------------------------------------------------------------
1467 void vogl_bind_object(GLenum target, GLuint handle)
1471 GLenum category = vogl_get_object_category_from_target(target);
1477 GL_ENTRYPOINT(glBindTexture)(target, handle);
1482 GL_ENTRYPOINT(glBindBuffer)(target, handle);
1485 case GL_FRAMEBUFFER:
1487 GL_ENTRYPOINT(glBindFramebuffer)(target, handle);
1490 case GL_RENDERBUFFER:
1492 GL_ENTRYPOINT(glBindRenderbuffer)(target, handle);
1497 GL_ENTRYPOINT(glBindSampler)(target, handle);
1500 case GL_VERTEX_ARRAY:
1502 GL_ENTRYPOINT(glBindVertexArray)(handle);
1505 case GL_ACTIVE_TEXTURE:
1507 // not really a binding, exactly, but seems useful
1508 GL_ENTRYPOINT(glActiveTexture)(handle);
1513 GL_ENTRYPOINT(glUseProgram)(handle);
1523 VOGL_CHECK_GL_ERROR;
1526 //----------------------------------------------------------------------------------------------------------------------
1527 // vogl_get_bound_object
1528 //----------------------------------------------------------------------------------------------------------------------
1529 GLuint vogl_get_bound_object(GLenum target)
1533 GLenum binding = vogl_get_binding_from_target(target);
1534 if (binding == GL_NONE)
1541 GL_ENTRYPOINT(glGetIntegerv)(binding, &handle);
1542 VOGL_CHECK_GL_ERROR;
1547 //----------------------------------------------------------------------------------------------------------------------
1548 // vogl_debug_message_control
1549 //----------------------------------------------------------------------------------------------------------------------
1550 void vogl_debug_message_control(const vogl_context_info &context_info, GLenum err_code, bool enabled)
1554 if (!context_info.is_debug_context())
1557 if (!context_info.supports_extension("GL_ARB_debug_output") || (!GL_ENTRYPOINT(glDebugMessageControlARB)))
1560 GL_ENTRYPOINT(glDebugMessageControlARB)(GL_DEBUG_SOURCE_API_ARB, GL_DEBUG_TYPE_ERROR_ARB, GL_DONT_CARE, 1, &err_code, enabled);
1563 //----------------------------------------------------------------------------------------------------------------------
1564 // vogl_determine_texture_target
1565 // NOTE: Don't use this for anything other than debugging!
1566 //----------------------------------------------------------------------------------------------------------------------
1567 GLenum vogl_determine_texture_target(const vogl_context_info &context_info, GLuint handle)
1571 GLboolean is_texture = GL_ENTRYPOINT(glIsTexture)(handle);
1575 vogl_scoped_binding_state orig_texture_state;
1576 orig_texture_state.save_textures();
1578 VOGL_CHECK_GL_ERROR;
1580 // roughly sorted by most likely to least
1581 static const GLenum s_possible_targets[] =
1583 GL_TEXTURE_2D, GL_TEXTURE_CUBE_MAP,
1584 GL_TEXTURE_3D, GL_TEXTURE_2D_ARRAY, GL_TEXTURE_1D, GL_TEXTURE_1D_ARRAY,
1585 GL_TEXTURE_RECTANGLE, GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_BUFFER, GL_TEXTURE_2D_MULTISAMPLE, GL_TEXTURE_2D_MULTISAMPLE_ARRAY
1588 vogl_debug_message_control(context_info, GL_INVALID_OPERATION, false);
1591 for (i = 0; i < VOGL_ARRAY_SIZE(s_possible_targets); i++)
1593 GL_ENTRYPOINT(glBindTexture)(s_possible_targets[i], handle);
1594 if (!vogl_check_gl_error_suppress_message())
1598 if (i == VOGL_ARRAY_SIZE(s_possible_targets))
1599 vogl_check_gl_error_suppress_message();
1601 vogl_debug_message_control(context_info, GL_INVALID_OPERATION, true);
1603 return (i < VOGL_ARRAY_SIZE(s_possible_targets)) ? s_possible_targets[i] : GL_NONE;
1606 //----------------------------------------------------------------------------------------------------------------------
1607 // vogl_state_saver::save
1608 //----------------------------------------------------------------------------------------------------------------------
1609 void vogl_state_saver::save(vogl_generic_state_type type)
1613 #define SAVE_INT_STATE(type, pname) \
1616 m_states.push_back(saved_state(type, pname, vogl_get_gl_integer(pname))); \
1618 #define SAVE_FLOAT_STATE(type, pname) \
1621 m_states.push_back(saved_state(type, pname, vogl_get_gl_float(pname))); \
1626 case cGSTPixelStore:
1628 static const GLenum s_pixel_store_enums[] =
1630 GL_PACK_SWAP_BYTES, GL_PACK_LSB_FIRST, GL_PACK_ROW_LENGTH, GL_PACK_IMAGE_HEIGHT, GL_PACK_SKIP_ROWS, GL_PACK_SKIP_PIXELS, GL_PACK_SKIP_IMAGES, GL_PACK_ALIGNMENT,
1631 GL_UNPACK_SWAP_BYTES, GL_UNPACK_LSB_FIRST, GL_UNPACK_ROW_LENGTH, GL_UNPACK_IMAGE_HEIGHT, GL_UNPACK_SKIP_ROWS, GL_UNPACK_SKIP_PIXELS, GL_UNPACK_SKIP_IMAGES, GL_UNPACK_ALIGNMENT
1634 for (uint i = 0; i < VOGL_ARRAY_SIZE(s_pixel_store_enums); i++)
1635 SAVE_INT_STATE(cGSTPixelStore, s_pixel_store_enums[i]);
1639 case cGSTPixelTransfer:
1641 // FIXME: All pixel transfer was marked deprecated and not available in a Core Profile (let the caller worry about it)
1642 static const GLenum s_pixel_transfer_int_enums[] =
1644 GL_MAP_COLOR, GL_MAP_STENCIL, GL_INDEX_SHIFT, GL_INDEX_OFFSET
1647 for (uint i = 0; i < VOGL_ARRAY_SIZE(s_pixel_transfer_int_enums); i++)
1648 SAVE_INT_STATE(cGSTPixelTransfer, s_pixel_transfer_int_enums[i]);
1650 static const GLfloat s_pixel_transfer_float_enums[] =
1652 GL_INDEX_OFFSET, GL_RED_SCALE, GL_GREEN_SCALE, GL_BLUE_SCALE, GL_ALPHA_SCALE, GL_DEPTH_SCALE, GL_RED_BIAS, GL_GREEN_BIAS,
1653 GL_BLUE_BIAS, GL_ALPHA_BIAS, GL_DEPTH_BIAS, GL_POST_COLOR_MATRIX_RED_SCALE, GL_POST_COLOR_MATRIX_GREEN_SCALE, GL_POST_COLOR_MATRIX_BLUE_SCALE,
1654 GL_POST_COLOR_MATRIX_ALPHA_SCALE, GL_POST_COLOR_MATRIX_RED_BIAS, GL_POST_COLOR_MATRIX_GREEN_BIAS, GL_POST_COLOR_MATRIX_BLUE_BIAS, GL_POST_COLOR_MATRIX_ALPHA_BIAS,
1655 GL_POST_CONVOLUTION_RED_SCALE, GL_POST_CONVOLUTION_GREEN_SCALE, GL_POST_CONVOLUTION_BLUE_SCALE, GL_POST_CONVOLUTION_ALPHA_SCALE, GL_POST_CONVOLUTION_RED_BIAS,
1656 GL_POST_CONVOLUTION_GREEN_BIAS, GL_POST_CONVOLUTION_BLUE_BIAS, GL_POST_CONVOLUTION_ALPHA_BIAS
1659 for (uint i = 0; i < VOGL_ARRAY_SIZE(s_pixel_transfer_float_enums); i++)
1660 SAVE_FLOAT_STATE(cGSTPixelTransfer, s_pixel_transfer_float_enums[i]);
1664 case cGSTReadBuffer:
1666 SAVE_INT_STATE(type, GL_READ_BUFFER);
1669 case cGSTDrawBuffer:
1671 uint max_draw_buffers = vogl_get_gl_integer(GL_MAX_DRAW_BUFFERS);
1672 m_draw_buffers.resize(max_draw_buffers);
1674 for (uint i = 0; i < max_draw_buffers; i++)
1675 m_draw_buffers[i] = vogl_get_gl_integer(GL_DRAW_BUFFER0 + i);
1679 case cGSTActiveTexture:
1681 GLint active_texture = 0;
1682 GL_ENTRYPOINT(glGetIntegerv)(GL_ACTIVE_TEXTURE, &active_texture);
1683 m_states.push_back(saved_state(type, GL_ACTIVE_TEXTURE, active_texture));
1686 case cGSTClientActiveTexture:
1688 // FIXME: Don't think this is available in core (let the caller worry about it)
1689 GLint client_active_texture = 0;
1690 GL_ENTRYPOINT(glGetIntegerv)(GL_CLIENT_ACTIVE_TEXTURE, &client_active_texture);
1691 m_states.push_back(saved_state(type, GL_CLIENT_ACTIVE_TEXTURE, client_active_texture));
1694 case cGSTMatrixMode:
1696 SAVE_INT_STATE(type, GL_MATRIX_MODE);
1699 case cGSTARBVertexProgram:
1701 GLint cur_arb_vertex_program = 0;
1702 GL_ENTRYPOINT(glGetProgramivARB)(GL_VERTEX_PROGRAM_ARB, GL_PROGRAM_BINDING_ARB, &cur_arb_vertex_program);
1703 m_states.push_back(saved_state(type, GL_VERTEX_PROGRAM_ARB, cur_arb_vertex_program));
1706 case cGSTARBFragmentProgram:
1708 GLint cur_arb_fragment_program = 0;
1709 GL_ENTRYPOINT(glGetProgramivARB)(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_BINDING_ARB, &cur_arb_fragment_program);
1710 m_states.push_back(saved_state(type, GL_FRAGMENT_PROGRAM_ARB, cur_arb_fragment_program));
1720 #undef SAVE_INT_STATE
1721 #undef SAVE_FLOAT_STATE
1723 VOGL_CHECK_GL_ERROR;
1726 //----------------------------------------------------------------------------------------------------------------------
1727 // vogl_state_saver::restore
1728 //----------------------------------------------------------------------------------------------------------------------
1729 void vogl_state_saver::restore()
1733 if (m_draw_buffers.size())
1736 for (i = m_draw_buffers.size() - 1; i >= 0; --i)
1737 if (m_draw_buffers[i] != GL_NONE)
1740 VOGL_ASSERT(i >= 0);
1742 // On NV, we can cvall glDrawBuffers() with a single GL_BACK, etc. and it's fine. On AMD it barfs.
1745 GL_ENTRYPOINT(glDrawBuffer)(m_draw_buffers[0]);
1746 VOGL_CHECK_GL_ERROR;
1750 GL_ENTRYPOINT(glDrawBuffers)(i + 1, m_draw_buffers.get_ptr());
1751 VOGL_CHECK_GL_ERROR;
1755 for (uint i = 0; i < m_states.size(); i++)
1757 const vogl::value_data_type value_type = m_states[i].m_value.get_data_type();
1759 switch (m_states[i].m_state_type)
1761 case cGSTPixelStore:
1763 VOGL_ASSERT(value_type == cDTInt);
1764 GL_ENTRYPOINT(glPixelStorei)(m_states[i].m_pname, m_states[i].m_value.get_int());
1765 VOGL_CHECK_GL_ERROR;
1768 case cGSTPixelTransfer:
1770 if (value_type == cDTFloat)
1772 GL_ENTRYPOINT(glPixelTransferf)(m_states[i].m_pname, m_states[i].m_value.get_float());
1773 VOGL_CHECK_GL_ERROR;
1775 else if (value_type == cDTInt)
1777 GL_ENTRYPOINT(glPixelTransferi)(m_states[i].m_pname, m_states[i].m_value.get_int());
1778 VOGL_CHECK_GL_ERROR;
1787 case cGSTReadBuffer:
1789 VOGL_ASSERT(m_states[i].m_pname == GL_READ_BUFFER);
1790 VOGL_ASSERT(value_type == cDTInt);
1791 GL_ENTRYPOINT(glReadBuffer)(m_states[i].m_value.get_int());
1792 VOGL_CHECK_GL_ERROR;
1795 case cGSTDrawBuffer:
1800 case cGSTActiveTexture:
1802 VOGL_ASSERT(m_states[i].m_pname == GL_ACTIVE_TEXTURE);
1803 VOGL_ASSERT(value_type == cDTInt);
1804 GL_ENTRYPOINT(glActiveTexture)(m_states[i].m_value.get_int());
1805 VOGL_CHECK_GL_ERROR;
1808 case cGSTClientActiveTexture:
1810 VOGL_ASSERT(m_states[i].m_pname == GL_CLIENT_ACTIVE_TEXTURE);
1811 VOGL_ASSERT(value_type == cDTInt);
1812 GL_ENTRYPOINT(glClientActiveTexture)(m_states[i].m_value.get_int());
1813 VOGL_CHECK_GL_ERROR;
1816 case cGSTMatrixMode:
1818 VOGL_ASSERT(m_states[i].m_pname == GL_MATRIX_MODE);
1819 VOGL_ASSERT(value_type == cDTInt);
1820 GL_ENTRYPOINT(glMatrixMode)(m_states[i].m_value.get_int());
1821 VOGL_CHECK_GL_ERROR;
1824 case cGSTARBVertexProgram:
1826 VOGL_ASSERT(m_states[i].m_pname == GL_VERTEX_PROGRAM_ARB);
1827 VOGL_ASSERT(value_type == cDTInt);
1828 GL_ENTRYPOINT(glBindProgramARB)(GL_VERTEX_PROGRAM_ARB, m_states[i].m_value.get_int());
1829 VOGL_CHECK_GL_ERROR;
1832 case cGSTARBFragmentProgram:
1834 VOGL_ASSERT(m_states[i].m_pname == GL_FRAGMENT_PROGRAM_ARB);
1835 VOGL_ASSERT(value_type == cDTInt);
1836 GL_ENTRYPOINT(glBindProgramARB)(GL_FRAGMENT_PROGRAM_ARB, m_states[i].m_value.get_int());
1837 VOGL_CHECK_GL_ERROR;
1849 //----------------------------------------------------------------------------------------------------------------------
1850 // vogl_gl_get_uniform_size_in_GLints
1851 //----------------------------------------------------------------------------------------------------------------------
1852 int vogl_gl_get_uniform_size_in_GLints(GLenum type)
1860 case GL_UNSIGNED_INT:
1866 case GL_SAMPLER_CUBE:
1867 case GL_SAMPLER_1D_SHADOW:
1868 case GL_SAMPLER_2D_SHADOW:
1869 case GL_SAMPLER_1D_ARRAY:
1870 case GL_SAMPLER_2D_ARRAY:
1871 case GL_SAMPLER_1D_ARRAY_SHADOW:
1872 case GL_SAMPLER_2D_ARRAY_SHADOW:
1873 case GL_SAMPLER_2D_MULTISAMPLE:
1874 case GL_SAMPLER_2D_MULTISAMPLE_ARRAY:
1875 case GL_SAMPLER_CUBE_SHADOW:
1876 case GL_SAMPLER_BUFFER:
1877 case GL_SAMPLER_2D_RECT:
1878 case GL_SAMPLER_2D_RECT_SHADOW:
1879 case GL_INT_SAMPLER_1D:
1880 case GL_INT_SAMPLER_2D:
1881 case GL_INT_SAMPLER_3D:
1882 case GL_INT_SAMPLER_CUBE:
1883 case GL_INT_SAMPLER_1D_ARRAY:
1884 case GL_INT_SAMPLER_2D_ARRAY:
1885 case GL_INT_SAMPLER_2D_MULTISAMPLE:
1886 case GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY:
1887 case GL_INT_SAMPLER_BUFFER:
1888 case GL_INT_SAMPLER_2D_RECT:
1889 case GL_UNSIGNED_INT_SAMPLER_1D:
1890 case GL_UNSIGNED_INT_SAMPLER_2D:
1891 case GL_UNSIGNED_INT_SAMPLER_3D:
1892 case GL_UNSIGNED_INT_SAMPLER_CUBE:
1893 case GL_UNSIGNED_INT_SAMPLER_1D_ARRAY:
1894 case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY:
1895 case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE:
1896 case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY:
1897 case GL_UNSIGNED_INT_SAMPLER_BUFFER:
1898 case GL_UNSIGNED_INT_SAMPLER_2D_RECT:
1903 case GL_IMAGE_2D_RECT:
1905 case GL_IMAGE_BUFFER:
1906 case GL_IMAGE_1D_ARRAY:
1907 case GL_IMAGE_2D_ARRAY:
1908 case GL_IMAGE_2D_MULTISAMPLE:
1909 case GL_IMAGE_2D_MULTISAMPLE_ARRAY:
1910 case GL_INT_IMAGE_1D:
1911 case GL_INT_IMAGE_2D:
1912 case GL_INT_IMAGE_3D:
1913 case GL_INT_IMAGE_2D_RECT:
1914 case GL_INT_IMAGE_CUBE:
1915 case GL_INT_IMAGE_BUFFER:
1916 case GL_INT_IMAGE_1D_ARRAY:
1917 case GL_INT_IMAGE_2D_ARRAY:
1918 case GL_INT_IMAGE_2D_MULTISAMPLE:
1919 case GL_INT_IMAGE_2D_MULTISAMPLE_ARRAY:
1920 case GL_UNSIGNED_INT_IMAGE_1D:
1921 case GL_UNSIGNED_INT_IMAGE_2D:
1922 case GL_UNSIGNED_INT_IMAGE_3D:
1923 case GL_UNSIGNED_INT_IMAGE_2D_RECT:
1924 case GL_UNSIGNED_INT_IMAGE_CUBE:
1925 case GL_UNSIGNED_INT_IMAGE_BUFFER:
1926 case GL_UNSIGNED_INT_IMAGE_1D_ARRAY:
1927 case GL_UNSIGNED_INT_IMAGE_2D_ARRAY:
1928 case GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE:
1929 case GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_ARRAY:
1931 case GL_UNSIGNED_INT_ATOMIC_COUNTER:
1938 case GL_UNSIGNED_INT_VEC2:
1944 case GL_UNSIGNED_INT_VEC3:
1948 case GL_DOUBLE_VEC2:
1951 case GL_UNSIGNED_INT_VEC4:
1962 case GL_DOUBLE_VEC3:
1963 case GL_FLOAT_MAT2x3:
1964 case GL_FLOAT_MAT3x2:
1967 case GL_DOUBLE_VEC4:
1968 case GL_DOUBLE_MAT2:
1969 case GL_FLOAT_MAT2x4:
1970 case GL_FLOAT_MAT4x2:
1973 case GL_DOUBLE_MAT2x3:
1974 case GL_DOUBLE_MAT3x2:
1975 case GL_FLOAT_MAT3x4:
1976 case GL_FLOAT_MAT4x3:
1979 case GL_DOUBLE_MAT2x4:
1980 case GL_DOUBLE_MAT4x2:
1983 case GL_DOUBLE_MAT3:
1986 case GL_DOUBLE_MAT3x4:
1987 case GL_DOUBLE_MAT4x3:
1990 case GL_DOUBLE_MAT4:
1996 vogl_warning_printf("%s: Unknown uniform type 0x%04X\n", VOGL_FUNCTION_NAME, type);
2002 //----------------------------------------------------------------------------------------------------------------------
2003 // vogl_gl_get_uniform_size_in_bytes
2004 //----------------------------------------------------------------------------------------------------------------------
2005 int vogl_gl_get_uniform_size_in_bytes(GLenum type)
2009 return vogl_gl_get_uniform_size_in_GLints(type) * sizeof(GLint);
2012 //----------------------------------------------------------------------------------------------------------------------
2013 // vogl_gl_get_uniform_base_type
2014 //----------------------------------------------------------------------------------------------------------------------
2015 int vogl_gl_get_uniform_base_type(GLenum type)
2028 case GL_FLOAT_MAT2x3:
2029 case GL_FLOAT_MAT3x2:
2030 case GL_FLOAT_MAT2x4:
2031 case GL_FLOAT_MAT4x2:
2032 case GL_FLOAT_MAT3x4:
2033 case GL_FLOAT_MAT4x3:
2037 case GL_DOUBLE_VEC2:
2038 case GL_DOUBLE_VEC3:
2039 case GL_DOUBLE_VEC4:
2040 case GL_DOUBLE_MAT2:
2041 case GL_DOUBLE_MAT3:
2042 case GL_DOUBLE_MAT4:
2043 case GL_DOUBLE_MAT2x3:
2044 case GL_DOUBLE_MAT3x2:
2045 case GL_DOUBLE_MAT2x4:
2046 case GL_DOUBLE_MAT4x2:
2047 case GL_DOUBLE_MAT3x4:
2048 case GL_DOUBLE_MAT4x3:
2057 case GL_UNSIGNED_INT:
2058 case GL_UNSIGNED_INT_VEC2:
2059 case GL_UNSIGNED_INT_VEC3:
2060 case GL_UNSIGNED_INT_VEC4:
2061 case GL_UNSIGNED_INT_ATOMIC_COUNTER:
2062 return GL_UNSIGNED_INT;
2073 case GL_SAMPLER_CUBE:
2074 case GL_SAMPLER_1D_SHADOW:
2075 case GL_SAMPLER_2D_SHADOW:
2076 case GL_SAMPLER_1D_ARRAY:
2077 case GL_SAMPLER_2D_ARRAY:
2078 case GL_SAMPLER_1D_ARRAY_SHADOW:
2079 case GL_SAMPLER_2D_ARRAY_SHADOW:
2080 case GL_SAMPLER_2D_MULTISAMPLE:
2081 case GL_SAMPLER_2D_MULTISAMPLE_ARRAY:
2082 case GL_SAMPLER_CUBE_SHADOW:
2083 case GL_SAMPLER_BUFFER:
2084 case GL_SAMPLER_2D_RECT:
2085 case GL_SAMPLER_2D_RECT_SHADOW:
2086 case GL_INT_SAMPLER_1D:
2087 case GL_INT_SAMPLER_2D:
2088 case GL_INT_SAMPLER_3D:
2089 case GL_INT_SAMPLER_CUBE:
2090 case GL_INT_SAMPLER_1D_ARRAY:
2091 case GL_INT_SAMPLER_2D_ARRAY:
2092 case GL_INT_SAMPLER_2D_MULTISAMPLE:
2093 case GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY:
2094 case GL_INT_SAMPLER_BUFFER:
2095 case GL_INT_SAMPLER_2D_RECT:
2096 case GL_UNSIGNED_INT_SAMPLER_1D:
2097 case GL_UNSIGNED_INT_SAMPLER_2D:
2098 case GL_UNSIGNED_INT_SAMPLER_3D:
2099 case GL_UNSIGNED_INT_SAMPLER_CUBE:
2100 case GL_UNSIGNED_INT_SAMPLER_1D_ARRAY:
2101 case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY:
2102 case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE:
2103 case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY:
2104 case GL_UNSIGNED_INT_SAMPLER_BUFFER:
2105 case GL_UNSIGNED_INT_SAMPLER_2D_RECT:
2111 case GL_IMAGE_2D_RECT:
2113 case GL_IMAGE_BUFFER:
2114 case GL_IMAGE_1D_ARRAY:
2115 case GL_IMAGE_2D_ARRAY:
2116 case GL_IMAGE_2D_MULTISAMPLE:
2117 case GL_IMAGE_2D_MULTISAMPLE_ARRAY:
2118 case GL_INT_IMAGE_1D:
2119 case GL_INT_IMAGE_2D:
2120 case GL_INT_IMAGE_3D:
2121 case GL_INT_IMAGE_2D_RECT:
2122 case GL_INT_IMAGE_CUBE:
2123 case GL_INT_IMAGE_BUFFER:
2124 case GL_INT_IMAGE_1D_ARRAY:
2125 case GL_INT_IMAGE_2D_ARRAY:
2126 case GL_INT_IMAGE_2D_MULTISAMPLE:
2127 case GL_INT_IMAGE_2D_MULTISAMPLE_ARRAY:
2128 case GL_UNSIGNED_INT_IMAGE_1D:
2129 case GL_UNSIGNED_INT_IMAGE_2D:
2130 case GL_UNSIGNED_INT_IMAGE_3D:
2131 case GL_UNSIGNED_INT_IMAGE_2D_RECT:
2132 case GL_UNSIGNED_INT_IMAGE_CUBE:
2133 case GL_UNSIGNED_INT_IMAGE_BUFFER:
2134 case GL_UNSIGNED_INT_IMAGE_1D_ARRAY:
2135 case GL_UNSIGNED_INT_IMAGE_2D_ARRAY:
2136 case GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE:
2137 case GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_ARRAY:
2138 return GL_IMAGE_1D; // what do we return??
2143 vogl_warning_printf("%s: Unknown uniform type 0x%04X\n", VOGL_FUNCTION_NAME, type);
2149 //----------------------------------------------------------------------------------------------------------------------
2150 // vogl_format_debug_output_arb
2151 // Loosely derived from http://www.altdevblogaday.com/2011/06/23/improving-opengl-error-messages/
2152 //----------------------------------------------------------------------------------------------------------------------
2153 void vogl_format_debug_output_arb(char out_str[], size_t out_str_size, GLenum source, GLenum type, GLuint id, GLenum severity, const char *msg)
2157 char source_str[32];
2158 const char *source_fmt = "UNDEFINED(0x%04X)";
2162 case GL_DEBUG_SOURCE_API_ARB:
2165 case GL_DEBUG_SOURCE_WINDOW_SYSTEM_ARB:
2166 source_fmt = "WINDOW_SYSTEM";
2168 case GL_DEBUG_SOURCE_SHADER_COMPILER_ARB:
2169 source_fmt = "SHADER_COMPILER";
2171 case GL_DEBUG_SOURCE_THIRD_PARTY_ARB:
2172 source_fmt = "THIRD_PARTY";
2174 case GL_DEBUG_SOURCE_APPLICATION_ARB:
2175 source_fmt = "APPLICATION";
2177 case GL_DEBUG_SOURCE_OTHER_ARB:
2178 source_fmt = "OTHER";
2184 vogl_sprintf_s(source_str, sizeof(source_str), source_fmt, source);
2187 const char *type_fmt = "UNDEFINED(0x%04X)";
2190 case GL_DEBUG_TYPE_ERROR_ARB:
2193 case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_ARB:
2194 type_fmt = "DEPRECATED_BEHAVIOR";
2196 case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_ARB:
2197 type_fmt = "UNDEFINED_BEHAVIOR";
2199 case GL_DEBUG_TYPE_PORTABILITY_ARB:
2200 type_fmt = "PORTABILITY";
2202 case GL_DEBUG_TYPE_PERFORMANCE_ARB:
2203 type_fmt = "PERFORMANCE";
2205 case GL_DEBUG_TYPE_OTHER_ARB:
2211 vogl_sprintf_s(type_str, sizeof(type_str), type_fmt, type);
2213 char severity_str[32];
2214 const char *severity_fmt = "UNDEFINED";
2217 case GL_DEBUG_SEVERITY_HIGH_ARB:
2218 severity_fmt = "HIGH";
2220 case GL_DEBUG_SEVERITY_MEDIUM_ARB:
2221 severity_fmt = "MEDIUM";
2223 case GL_DEBUG_SEVERITY_LOW_ARB:
2224 severity_fmt = "LOW";
2230 vogl_sprintf_s(severity_str, sizeof(severity_str), severity_fmt, severity);
2232 vogl_sprintf_s(out_str, out_str_size, "OpenGL: %s [source=%s type=%s severity=%s id=%d]", msg, source_str, type_str, severity_str, id);
2235 //----------------------------------------------------------------------------------------------------------------------
2236 // vogl_generic_arb_debug_callback
2237 //----------------------------------------------------------------------------------------------------------------------
2238 void vogl_generic_arb_debug_callback(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *message, GLvoid *pUser_param)
2242 VOGL_NOTE_UNUSED(length);
2243 VOGL_NOTE_UNUSED(pUser_param);
2245 char final_message[4096];
2247 vogl_format_debug_output_arb(final_message, sizeof(final_message), source, type, id, severity, reinterpret_cast<const char *>(message));
2249 vogl_warning_printf("%s: %s\n", VOGL_FUNCTION_NAME, final_message);
2252 //----------------------------------------------------------------------------------------------------------------------
2253 // vogl_enable_generic_context_debug_messages
2254 //----------------------------------------------------------------------------------------------------------------------
2255 void vogl_enable_generic_context_debug_messages()
2257 GL_ENTRYPOINT(glDebugMessageCallbackARB)(vogl_generic_arb_debug_callback, NULL);
2258 GL_ENTRYPOINT(glEnable)(GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB);
2259 VOGL_CHECK_GL_ERROR;
2262 //----------------------------------------------------------------------------------------------------------------------
2263 // vogl_create_context
2264 //----------------------------------------------------------------------------------------------------------------------
2265 vogl_gl_context vogl_create_context(vogl_gl_display display, vogl_gl_fb_config fb_config, vogl_gl_context share_context, uint major_ver, uint minor_ver, uint flags, vogl_context_desc *pDesc)
2267 vogl_context_attribs attribs;
2268 attribs.add_key(GLX_CONTEXT_MAJOR_VERSION_ARB, major_ver);
2269 attribs.add_key(GLX_CONTEXT_MINOR_VERSION_ARB, minor_ver);
2271 if (flags & (cCHCCoreProfileFlag | cCHCCompatProfileFlag))
2273 uint profile_mask = 0;
2274 if (flags & cCHCCoreProfileFlag)
2275 profile_mask |= GLX_CONTEXT_CORE_PROFILE_BIT_ARB;
2277 if (flags & cCHCCompatProfileFlag)
2278 profile_mask |= GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB;
2280 attribs.add_key(GLX_CONTEXT_PROFILE_MASK_ARB, profile_mask);
2282 if (flags & eCHCDebugContextFlag)
2284 attribs.add_key(GLX_CONTEXT_FLAGS_ARB, GLX_CONTEXT_DEBUG_BIT_ARB);
2287 GLXContext context = GL_ENTRYPOINT(glXCreateContextAttribsARB)(display, fb_config, share_context, GL_TRUE, attribs.get_ptr());
2294 pDesc->init(VOGL_ENTRYPOINT_glXCreateContextAttribsARB, GL_TRUE, (vogl_trace_ptr_value)context, (vogl_trace_ptr_value)share_context, attribs);
2300 //----------------------------------------------------------------------------------------------------------------------
2301 // vogl_get_current_context
2302 //----------------------------------------------------------------------------------------------------------------------
2303 vogl_gl_context vogl_get_current_context()
2305 return GL_ENTRYPOINT(glXGetCurrentContext)();
2308 //----------------------------------------------------------------------------------------------------------------------
2309 // vogl_get_current_display
2310 //----------------------------------------------------------------------------------------------------------------------
2311 vogl_gl_display vogl_get_current_display()
2313 return GL_ENTRYPOINT(glXGetCurrentDisplay)();
2316 //----------------------------------------------------------------------------------------------------------------------
2317 // vogl_get_current_drawable
2318 //----------------------------------------------------------------------------------------------------------------------
2319 vogl_gl_drawable vogl_get_current_drawable()
2321 return GL_ENTRYPOINT(glXGetCurrentDrawable)();
2324 //----------------------------------------------------------------------------------------------------------------------
2325 // vogl_get_current_fb_config
2326 //----------------------------------------------------------------------------------------------------------------------
2327 vogl_gl_fb_config vogl_get_current_fb_config(uint screen)
2329 GLXDrawable pDrawable = GL_ENTRYPOINT(glXGetCurrentDrawable)();
2330 Display *pDisplay = GL_ENTRYPOINT(glXGetCurrentDisplay)();
2331 if ((!pDrawable) || (!pDisplay))
2334 GLuint fbconfig_id = 0;
2335 GL_ENTRYPOINT(glXQueryDrawable)(pDisplay, pDrawable, GLX_FBCONFIG_ID, &fbconfig_id);
2337 GLint attrib_list[3] = { GLX_FBCONFIG_ID, static_cast<GLint>(fbconfig_id), None };
2338 GLint nelements = 0;
2339 GLXFBConfig *pConfigs = GL_ENTRYPOINT(glXChooseFBConfig)(pDisplay, screen, attrib_list, &nelements);
2341 if ((pConfigs) && (nelements > 0))
2347 //----------------------------------------------------------------------------------------------------------------------
2348 // vogl_make_current
2349 //----------------------------------------------------------------------------------------------------------------------
2350 void vogl_make_current(vogl_gl_display display, vogl_gl_drawable drawable, vogl_gl_context context)
2352 GL_ENTRYPOINT(glXMakeCurrent)(display, drawable, context);
2355 //----------------------------------------------------------------------------------------------------------------------
2356 // vogl_destroy_context
2357 //----------------------------------------------------------------------------------------------------------------------
2358 void vogl_destroy_context(vogl_gl_display display, vogl_gl_context context)
2360 GL_ENTRYPOINT(glXDestroyContext)(display, context);
2363 //----------------------------------------------------------------------------------------------------------------------
2364 // vogl_get_max_supported_mip_levels
2365 //----------------------------------------------------------------------------------------------------------------------
2366 int vogl_get_max_supported_mip_levels()
2368 int max_texture_size = vogl_get_gl_integer(GL_MAX_TEXTURE_SIZE);
2369 return math::floor_log2i(max_texture_size);