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);
481 //printf("format: 0x%X type: 0x%X width: %i height: %i depth: %i alignment: %i row_length: %i image_height: %i skip_rows: %i skip_pixels: %i skip_images: %i\n",
482 // format, type, (int)width, (int)height, (int)depth, alignment, row_length, image_height, skip_rows, skip_pixels, skip_images);
489 size_t row_stride = (row_length * bits_per_pixel + 7) / 8;
491 if (((bits_per_element == 1 * 8) ||
492 (bits_per_element == 2 * 8) ||
493 (bits_per_element == 4 * 8) ||
494 (bits_per_element == 8 * 8)) &&
495 ((GLint)bits_per_element < alignment * 8))
497 row_stride = math::align_up_value(row_stride, alignment);
500 if (image_height <= 0)
502 image_height = height;
505 // GL_UNPACK_IMAGE_HEIGHT and GL_UNPACK_SKIP_IMAGES should probably not be considered for pixel rectangles
507 size_t image_stride = image_height * row_stride;
509 size_t size = depth * image_stride;
511 size += (skip_pixels * bits_per_pixel + 7) / 8;
512 size += skip_rows * row_stride;
513 size += skip_images * image_stride;
518 //----------------------------------------------------------------------------------------------------------------------
519 // vogl_get_tex_target_image_size
520 //----------------------------------------------------------------------------------------------------------------------
521 size_t vogl_get_tex_target_image_size(GLenum target, GLint level, GLenum format, GLenum type)
525 GLint width = 0, height = 0, depth = 0;
527 if (!vogl_has_active_context())
529 vogl_error_printf("%s: vogl_get_tex_target_image_size() called without an active context!\n", VOGL_FUNCTION_NAME);
533 if (!GL_ENTRYPOINT(glGetTexLevelParameteriv))
535 vogl_error_printf("%s: vogl_get_tex_target_image_size() called but the glGetTexLevelParameteriv function ptr is NULL!\n", VOGL_FUNCTION_NAME);
539 if (g_vogl_actual_gl_entrypoints.m_glGetTexLevelParameteriv)
541 GL_ENTRYPOINT(glGetTexLevelParameteriv)(target, level, GL_TEXTURE_WIDTH, &width);
542 GL_ENTRYPOINT(glGetTexLevelParameteriv)(target, level, GL_TEXTURE_HEIGHT, &height);
543 GL_ENTRYPOINT(glGetTexLevelParameteriv)(target, level, GL_TEXTURE_DEPTH, &depth);
546 if ((!width) || (!height) || (!depth))
549 return vogl_get_image_size(format, type, width, height, depth);
552 //----------------------------------------------------------------------------------------------------------------------
553 // vogl_determine_glMap1_size (originally from apitrace)
554 //----------------------------------------------------------------------------------------------------------------------
555 size_t vogl_determine_glMap1_size(GLenum target, GLint stride, GLint order)
566 case GL_MAP1_TEXTURE_COORD_1:
569 case GL_MAP1_TEXTURE_COORD_2:
573 case GL_MAP1_TEXTURE_COORD_3:
574 case GL_MAP1_VERTEX_3:
577 case GL_MAP1_COLOR_4:
578 case GL_MAP1_TEXTURE_COORD_4:
579 case GL_MAP1_VERTEX_4:
583 vogl_warning_printf("%s: unknown GLenum 0x%04X\n", VOGL_FUNCTION_NAME, target);
587 if (stride < channels)
590 return channels + stride * (order - 1);
593 //----------------------------------------------------------------------------------------------------------------------
594 // vogl_determine_glMap2_size (originally from apitrace)
595 //----------------------------------------------------------------------------------------------------------------------
596 size_t vogl_determine_glMap2_size(GLenum target, GLint ustride, GLint uorder, GLint vstride, GLint vorder)
600 if (uorder < 1 || vorder < 1)
607 case GL_MAP2_TEXTURE_COORD_1:
610 case GL_MAP2_TEXTURE_COORD_2:
614 case GL_MAP2_TEXTURE_COORD_3:
615 case GL_MAP2_VERTEX_3:
618 case GL_MAP2_COLOR_4:
619 case GL_MAP2_TEXTURE_COORD_4:
620 case GL_MAP2_VERTEX_4:
624 vogl_warning_printf("%s: unknown GLenum 0x%04X\n", VOGL_FUNCTION_NAME, target);
628 if (ustride < channels || vstride < channels)
632 ustride * (uorder - 1) +
633 vstride * (vorder - 1);
636 //----------------------------------------------------------------------------------------------------------------------
637 // vogl_enum_desc::init_sort_priority
638 //----------------------------------------------------------------------------------------------------------------------
639 void vogl_enum_desc::init_sort_priority()
643 m_sort_priority = cSCNone;
645 if (m_macro_name.ends_with("_EXT"))
646 m_sort_priority = cSCEXT;
647 else if (m_macro_name.ends_with("_ARB"))
648 m_sort_priority = cSCARB;
649 else if (m_macro_name.ends_with("_OES"))
650 m_sort_priority = cSCOES;
653 static const char *s_vendor_suffixes[] = { "_NV", "_AMD", "_INTEL", "_QCOM", "_ATI", "_SGIS", "_SGIX", "_ANGLE", "_APPLE", "_MESA", "_IBM" };
654 for (uint i = 0; i < VOGL_ARRAY_SIZE(s_vendor_suffixes); i++)
656 if (m_macro_name.ends_with(s_vendor_suffixes[i]))
658 m_sort_priority = cSCVendor;
665 //----------------------------------------------------------------------------------------------------------------------
666 // vogl_enum_desc::operator <
667 //----------------------------------------------------------------------------------------------------------------------
668 bool vogl_enum_desc::operator<(const vogl_enum_desc &rhs) const
672 if (m_sort_priority < rhs.m_sort_priority)
674 else if (m_sort_priority == rhs.m_sort_priority)
676 int comp_result = m_prefix.compare_using_length(rhs.m_prefix, true);
679 else if (comp_result == 0)
680 return m_macro_name.compare_using_length(rhs.m_macro_name, true) < 0;
685 //----------------------------------------------------------------------------------------------------------------------
686 // gl_enums::gl_enums
687 //----------------------------------------------------------------------------------------------------------------------
692 memset(m_gl_enum_to_pname_def_index, 0xFF, sizeof(m_gl_enum_to_pname_def_index));
694 for (uint i = 0; i < GL_PNAME_DEFS_ARRAY_SIZE; i++)
696 if (g_gl_pname_defs[i].m_gl_enum < 0x10000)
698 if (m_gl_enum_to_pname_def_index[g_gl_pname_defs[i].m_gl_enum] != 0xFFFF)
700 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);
704 m_gl_enum_to_pname_def_index[g_gl_pname_defs[i].m_gl_enum] = i;
706 m_enum_name_hash_map.insert(g_gl_pname_defs[i].m_pName, g_gl_pname_defs[i].m_gl_enum);
711 init_image_formats();
714 //----------------------------------------------------------------------------------------------------------------------
715 // gl_enums::add_enum
716 //----------------------------------------------------------------------------------------------------------------------
717 void gl_enums::add_enum(const char *pPrefix, const char *pSpec_type, const char *pGL_type, const char *pName, uint64_t value)
722 gl_enum_value_to_enum_desc_hash_map::insert_result ins_result(m_enum_value_hash_map.insert(value, vogl_enum_desc_vec()));
723 vogl_enum_desc_vec &vec = ins_result.first->second;
724 vogl_enum_desc *pDesc = vec.enlarge(1);
725 pDesc->m_value = value;
726 pDesc->m_prefix = pPrefix;
727 pDesc->m_spec_type = pSpec_type;
728 pDesc->m_gl_type = pGL_type;
729 pDesc->m_macro_name = pName;
730 pDesc->init_sort_priority();
734 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()));
735 vogl_enum_desc_vec &vec = ins_result.first->second;
737 vogl_enum_desc *pDesc = vec.enlarge(1);
738 pDesc->m_value = value;
739 pDesc->m_prefix = pPrefix;
740 pDesc->m_spec_type = pSpec_type;
741 pDesc->m_gl_type = pGL_type;
742 pDesc->m_macro_name = pName;
743 pDesc->init_sort_priority();
747 gl_enum_name_hash_map::insert_result res(m_enum_name_hash_map.insert(pName, value));
749 // Check for duplicate definitions with different values (compare apitrace's pname table vs. the spec)
750 uint64_t value_in_map = res.first->second;
751 VOGL_ASSERT(value_in_map == value);
752 VOGL_NOTE_UNUSED(value_in_map);
756 //----------------------------------------------------------------------------------------------------------------------
757 // gl_enums::init_enum_descs
758 //----------------------------------------------------------------------------------------------------------------------
759 void gl_enums::init_enum_descs()
763 #define DEFINE_GL_ENUM_CATEGORY_BEGIN(spectype)
764 #define DEFINE_GL_DEFINE_MEMBER(prefix, spec_type, enum_name)
765 #define DEFINE_GL_ENUM_MEMBER(prefix, spec_type, gl_type, enum_name, value) add_enum(#prefix, #spec_type, gl_type, enum_name, value);
766 #define DEFINE_GL_ENUM_CATEGORY_END(x)
768 #include "gl_enum_desc.inc"
769 #include "glx_enum_desc.inc"
771 #undef DEFINE_GL_ENUM_CATEGORY_BEGIN
772 #undef DEFINE_GL_DEFINE_MEMBER
773 #undef DEFINE_GL_ENUM_MEMBER
774 #undef DEFINE_GL_ENUM_CATEGORY_END
776 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)
778 vogl_enum_desc_vec &vec = it->second;
782 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)
784 vogl_enum_desc_vec &vec = it->second;
789 //----------------------------------------------------------------------------------------------------------------------
790 // gl_enums::get_name
791 //----------------------------------------------------------------------------------------------------------------------
792 const char *gl_enums::find_name(uint64_t gl_enum, const char *pPreferred_prefix) const
796 gl_enum_value_to_enum_desc_hash_map::const_iterator it(m_enum_value_hash_map.find(gl_enum));
797 if (it != m_enum_value_hash_map.end())
799 const vogl_enum_desc_vec &desc_vec = it->second;
801 if (pPreferred_prefix)
803 for (uint i = 0; i < desc_vec.size(); i++)
804 if (!desc_vec[i].m_prefix.compare(pPreferred_prefix, false)) // purposely not case sensitive
805 return desc_vec[i].m_macro_name.get_ptr();
808 return desc_vec[0].m_macro_name.get_ptr();
811 // 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.
812 int pname_index = find_pname_def_index(gl_enum);
813 if ((pname_index >= 0) && (g_gl_pname_defs[pname_index].m_pName))
814 return g_gl_pname_defs[pname_index].m_pName;
816 if (g_command_line_params.get_value_as_bool("debug"))
818 vogl_debug_printf("%s: Failed finding GL enum 0x%08" PRIX64 ", API prefix \"%s\"\n", VOGL_METHOD_NAME, gl_enum, pPreferred_prefix ? pPreferred_prefix : "");
824 //----------------------------------------------------------------------------------------------------------------------
825 // gl_enums::find_gl_image_format_name
826 //----------------------------------------------------------------------------------------------------------------------
827 const char *gl_enums::find_gl_image_format_name(GLenum gl_enum) const
831 const char *const *ppName = m_image_formats.find_value(gl_enum);
834 return find_gl_name(gl_enum);
837 //----------------------------------------------------------------------------------------------------------------------
838 // gl_enums::find_name
839 //----------------------------------------------------------------------------------------------------------------------
840 const char *gl_enums::find_name(const char *pSpec_type, uint64_t gl_enum, const char *pPreferred_prefix) const
844 // The spec type search is fuzzy but it does guide the search to saner enums in many common cases.
845 // The spec types in the enum table don't always match up with the spec types in the GL API param desc's.
846 // This isn't critical but it would be nice to try resolving this crap.
849 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)));
850 if (it != m_spec_type_and_enum_value_hash_map.end())
852 const vogl_enum_desc_vec &desc_vec = it->second;
854 if (pPreferred_prefix)
856 for (uint i = 0; i < desc_vec.size(); i++)
857 if (!desc_vec[i].m_prefix.compare(pPreferred_prefix, false)) // purposely not case sensitive
858 return desc_vec[i].m_macro_name.get_ptr();
861 return desc_vec[0].m_macro_name.get_ptr();
865 if (g_command_line_params.get_value_as_bool("debug"))
867 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",
868 VOGL_METHOD_NAME, pSpec_type, gl_enum, pPreferred_prefix ? pPreferred_prefix : "");
873 return find_name(gl_enum, pPreferred_prefix);
876 //----------------------------------------------------------------------------------------------------------------------
877 // gl_enums::find_enum
878 //----------------------------------------------------------------------------------------------------------------------
879 const char *gl_enums::find_name(uint64_t gl_enum, gl_entrypoint_id_t entrypoint_id, int param_index) const
881 VOGL_ASSERT(entrypoint_id < VOGL_NUM_ENTRYPOINTS);
883 const gl_entrypoint_desc_t &entrypoint_desc = g_vogl_entrypoint_descs[entrypoint_id];
885 const char *pSpec_type = NULL;
888 pSpec_type = entrypoint_desc.m_pReturn_spec_type;
892 VOGL_ASSERT(param_index < static_cast<int>(entrypoint_desc.m_num_params));
894 pSpec_type = g_vogl_entrypoint_param_descs[entrypoint_id][param_index].m_pSpec_type;
897 return find_name(pSpec_type, gl_enum, entrypoint_desc.m_pAPI_prefix);
900 //----------------------------------------------------------------------------------------------------------------------
901 // gl_enums::find_enum
902 //----------------------------------------------------------------------------------------------------------------------
903 uint64_t gl_enums::find_enum(const dynamic_string &str) const
907 gl_enum_name_hash_map::const_iterator it(m_enum_name_hash_map.find(str));
908 return (it == m_enum_name_hash_map.end()) ? static_cast<uint64_t>(cUnknownEnum) : it->second;
911 //----------------------------------------------------------------------------------------------------------------------
912 // gl_enums::get_pname_count
913 //----------------------------------------------------------------------------------------------------------------------
914 int gl_enums::get_pname_count(uint64_t gl_enum) const
918 if (GL_ENTRYPOINT(glGetIntegerv))
920 if (gl_enum == GL_COMPRESSED_TEXTURE_FORMATS)
923 GL_ENTRYPOINT(glGetIntegerv)(GL_NUM_COMPRESSED_TEXTURE_FORMATS, &value);
926 else if (gl_enum == GL_PROGRAM_BINARY_FORMATS)
929 GL_ENTRYPOINT(glGetIntegerv)(GL_NUM_PROGRAM_BINARY_FORMATS, &value);
934 int pname_index = find_pname_def_index(gl_enum);
935 if (pname_index >= 0)
936 return g_gl_pname_defs[pname_index].m_count;
938 vogl_warning_printf("%s: Unknown GL enum: 0x%08" PRIX64 "\n", VOGL_METHOD_NAME, gl_enum);
942 //----------------------------------------------------------------------------------------------------------------------
943 // gl_enums::get_pname_type
944 //----------------------------------------------------------------------------------------------------------------------
945 int gl_enums::get_pname_type(uint64_t gl_enum) const
948 int pname_index = find_pname_def_index(gl_enum);
949 if (pname_index >= 0)
950 return g_gl_pname_defs[pname_index].m_type;
952 vogl_warning_printf("%s: Unknown GL enum: 0x%08" PRIX64 "\n", VOGL_METHOD_NAME, gl_enum);
956 //----------------------------------------------------------------------------------------------------------------------
957 // gl_enums::find_pname_def_index
958 //----------------------------------------------------------------------------------------------------------------------
959 int gl_enums::find_pname_def_index(uint64_t gl_enum) const
963 if (gl_enum < 0x10000)
965 int pname_index = m_gl_enum_to_pname_def_index[static_cast<uint>(gl_enum)];
966 if (pname_index != 0xFFFF)
969 return vogl::cInvalidIndex;
972 //----------------------------------------------------------------------------------------------------------------------
973 // GL image format to enum helpers
974 //----------------------------------------------------------------------------------------------------------------------
975 void gl_enums::init_image_formats()
979 #define IMG_FMT(x) m_image_formats.insert(x, #x);
980 #include "vogl_image_formats.inc"
984 //----------------------------------------------------------------------------------------------------------------------
985 // vogl_get_bound_gl_buffer
986 //----------------------------------------------------------------------------------------------------------------------
987 GLuint vogl_get_bound_gl_buffer(GLenum target)
994 case GL_ARRAY_BUFFER:
995 t = GL_ARRAY_BUFFER_BINDING;
997 case GL_ATOMIC_COUNTER_BUFFER:
998 t = GL_ATOMIC_COUNTER_BUFFER_BINDING;
1000 case GL_COPY_READ_BUFFER:
1001 t = GL_COPY_READ_BUFFER_BINDING;
1003 case GL_COPY_WRITE_BUFFER:
1004 t = GL_COPY_WRITE_BUFFER_BINDING;
1006 case GL_DRAW_INDIRECT_BUFFER:
1007 t = GL_DRAW_INDIRECT_BUFFER_BINDING;
1009 case GL_DISPATCH_INDIRECT_BUFFER:
1010 t = GL_DISPATCH_INDIRECT_BUFFER_BINDING;
1012 case GL_ELEMENT_ARRAY_BUFFER:
1013 t = GL_ELEMENT_ARRAY_BUFFER_BINDING;
1015 case GL_PIXEL_PACK_BUFFER:
1016 t = GL_PIXEL_PACK_BUFFER_BINDING;
1018 case GL_PIXEL_UNPACK_BUFFER:
1019 t = GL_PIXEL_UNPACK_BUFFER_BINDING;
1021 case GL_SHADER_STORAGE_BUFFER:
1022 t = GL_SHADER_STORAGE_BUFFER_BINDING;
1024 case GL_TRANSFORM_FEEDBACK_BUFFER:
1025 t = GL_TRANSFORM_FEEDBACK_BUFFER_BINDING;
1027 case GL_UNIFORM_BUFFER:
1028 t = GL_UNIFORM_BUFFER_BINDING;
1030 case GL_TEXTURE_BUFFER:
1031 t = GL_TEXTURE_BINDING_BUFFER;
1035 console::warning("%s: Unknown buffer GL enum 0x%08X\n", VOGL_FUNCTION_NAME, target);
1040 GL_ENTRYPOINT(glGetIntegerv)(t, &id);
1044 //----------------------------------------------------------------------------------------------------------------------
1045 // vogl_reset_pixel_store_states
1046 //----------------------------------------------------------------------------------------------------------------------
1047 void vogl_reset_pixel_store_states()
1051 GL_ENTRYPOINT(glPixelStorei)(GL_PACK_SWAP_BYTES, false);
1052 GL_ENTRYPOINT(glPixelStorei)(GL_PACK_LSB_FIRST, false);
1053 GL_ENTRYPOINT(glPixelStorei)(GL_PACK_ROW_LENGTH, 0);
1054 GL_ENTRYPOINT(glPixelStorei)(GL_PACK_IMAGE_HEIGHT, 0);
1055 GL_ENTRYPOINT(glPixelStorei)(GL_PACK_SKIP_ROWS, 0);
1056 GL_ENTRYPOINT(glPixelStorei)(GL_PACK_SKIP_PIXELS, 0);
1057 GL_ENTRYPOINT(glPixelStorei)(GL_PACK_SKIP_IMAGES, 0);
1058 GL_ENTRYPOINT(glPixelStorei)(GL_PACK_ALIGNMENT, 1);
1059 GL_ENTRYPOINT(glPixelStorei)(GL_UNPACK_SWAP_BYTES, false);
1060 GL_ENTRYPOINT(glPixelStorei)(GL_UNPACK_LSB_FIRST, false);
1061 GL_ENTRYPOINT(glPixelStorei)(GL_UNPACK_ROW_LENGTH, 0);
1062 GL_ENTRYPOINT(glPixelStorei)(GL_UNPACK_IMAGE_HEIGHT, 0);
1063 GL_ENTRYPOINT(glPixelStorei)(GL_UNPACK_SKIP_ROWS, 0);
1064 GL_ENTRYPOINT(glPixelStorei)(GL_UNPACK_SKIP_PIXELS, 0);
1065 GL_ENTRYPOINT(glPixelStorei)(GL_UNPACK_SKIP_IMAGES, 0);
1066 GL_ENTRYPOINT(glPixelStorei)(GL_UNPACK_ALIGNMENT, 1);
1069 //----------------------------------------------------------------------------------------------------------------------
1070 // vogl_reset_pixel_transfer_states
1071 //----------------------------------------------------------------------------------------------------------------------
1072 void vogl_reset_pixel_transfer_states()
1076 GL_ENTRYPOINT(glPixelTransferi)(GL_MAP_COLOR, GL_FALSE);
1078 GL_ENTRYPOINT(glPixelTransferi)(GL_MAP_STENCIL, GL_FALSE);
1079 GL_ENTRYPOINT(glPixelTransferi)(GL_INDEX_SHIFT, 0);
1080 GL_ENTRYPOINT(glPixelTransferi)(GL_INDEX_OFFSET, 0);
1082 GL_ENTRYPOINT(glPixelTransferf)(GL_RED_SCALE, 1.0f);
1083 GL_ENTRYPOINT(glPixelTransferf)(GL_GREEN_SCALE, 1.0f);
1084 GL_ENTRYPOINT(glPixelTransferf)(GL_BLUE_SCALE, 1.0f);
1085 GL_ENTRYPOINT(glPixelTransferf)(GL_ALPHA_SCALE, 1.0f);
1086 GL_ENTRYPOINT(glPixelTransferf)(GL_DEPTH_SCALE, 1.0f);
1088 GL_ENTRYPOINT(glPixelTransferf)(GL_RED_BIAS, 0.0f);
1089 GL_ENTRYPOINT(glPixelTransferf)(GL_GREEN_BIAS, 0.0f);
1090 GL_ENTRYPOINT(glPixelTransferf)(GL_BLUE_BIAS, 0.0f);
1091 GL_ENTRYPOINT(glPixelTransferf)(GL_ALPHA_BIAS, 0.0f);
1092 GL_ENTRYPOINT(glPixelTransferf)(GL_DEPTH_BIAS, 0.0f);
1094 GL_ENTRYPOINT(glPixelTransferf)(GL_POST_CONVOLUTION_RED_SCALE, 1.0f);
1095 GL_ENTRYPOINT(glPixelTransferf)(GL_POST_CONVOLUTION_GREEN_SCALE, 1.0f);
1096 GL_ENTRYPOINT(glPixelTransferf)(GL_POST_CONVOLUTION_BLUE_SCALE, 1.0f);
1097 GL_ENTRYPOINT(glPixelTransferf)(GL_POST_CONVOLUTION_ALPHA_SCALE, 1.0f);
1099 GL_ENTRYPOINT(glPixelTransferf)(GL_POST_CONVOLUTION_RED_BIAS, 0.0f);
1100 GL_ENTRYPOINT(glPixelTransferf)(GL_POST_CONVOLUTION_GREEN_BIAS, 0.0f);
1101 GL_ENTRYPOINT(glPixelTransferf)(GL_POST_CONVOLUTION_BLUE_BIAS, 0.0f);
1102 GL_ENTRYPOINT(glPixelTransferf)(GL_POST_CONVOLUTION_ALPHA_BIAS, 0.0f);
1104 GL_ENTRYPOINT(glPixelTransferf)(GL_POST_COLOR_MATRIX_RED_SCALE, 1.0f);
1105 GL_ENTRYPOINT(glPixelTransferf)(GL_POST_COLOR_MATRIX_GREEN_SCALE, 1.0f);
1106 GL_ENTRYPOINT(glPixelTransferf)(GL_POST_COLOR_MATRIX_BLUE_SCALE, 1.0f);
1107 GL_ENTRYPOINT(glPixelTransferf)(GL_POST_COLOR_MATRIX_ALPHA_SCALE, 1.0f);
1109 GL_ENTRYPOINT(glPixelTransferf)(GL_POST_COLOR_MATRIX_RED_BIAS, 0.0f);
1110 GL_ENTRYPOINT(glPixelTransferf)(GL_POST_COLOR_MATRIX_GREEN_BIAS, 0.0f);
1111 GL_ENTRYPOINT(glPixelTransferf)(GL_POST_COLOR_MATRIX_BLUE_BIAS, 0.0f);
1112 GL_ENTRYPOINT(glPixelTransferf)(GL_POST_COLOR_MATRIX_ALPHA_BIAS, 0.0f);
1115 #include "vogl_general_context_state.h"
1117 //----------------------------------------------------------------------------------------------------------------------
1118 // vogl_copy_buffer_to_image
1119 //----------------------------------------------------------------------------------------------------------------------
1120 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)
1124 if ((!width) || (!height))
1130 // Forceably discard any errors up to here, even in benchmark mode, because glReadPixels() is going to be slow as hell anyway
1131 GL_ENTRYPOINT(glGetError)();
1133 // Save the state we'll be changing
1134 vogl_scoped_state_saver state_saver(cGSTPixelStore);
1135 vogl_scoped_binding_state orig_framebuffers(GL_DRAW_FRAMEBUFFER, GL_READ_FRAMEBUFFER, GL_PIXEL_PACK_BUFFER);
1137 // Set the state we need to do a glReadPixels()
1138 vogl_reset_pixel_store_states();
1140 GL_ENTRYPOINT(glBindBuffer)(GL_PIXEL_PACK_BUFFER, pixel_pack_buffer);
1141 GL_ENTRYPOINT(glBindFramebuffer)(GL_FRAMEBUFFER, framebuffer);
1143 vogl_scoped_state_saver framebuffer_state_saver(cGSTReadBuffer, cGSTDrawBuffer);
1145 GL_ENTRYPOINT(glReadBuffer)(read_buffer);
1147 VOGL_CHECK_GL_ERROR;
1149 // Now read the pixels
1150 GLenum err = GL_INVALID_VALUE;
1152 // Ensure the destination buffer is big enough
1153 size_t image_size = vogl_get_image_size(format, type, width, height, 1);
1154 if ((pDst) && ((!image_size) || (dst_size < image_size)))
1160 GL_ENTRYPOINT(glReadPixels)(0, 0, width, height, format, type, pDst);
1162 err = GL_ENTRYPOINT(glGetError());
1167 console::warning("%s: GL error 0x%X while calling glReadPixels()!\n", VOGL_FUNCTION_NAME, err);
1170 // Optionally flip the image
1171 if ((flip_image) && (err == GL_NO_ERROR) && (pDst))
1173 size_t pitch = vogl_get_image_size(format, type, width, 1, 1);
1174 if (pitch > cUINT32_MAX)
1180 if ((pitch) && ((image_size / pitch) == height))
1182 vogl::vector<uint8> row_buf(static_cast<uint>(pitch));
1184 for (uint y = 0; y < (height / 2); y++)
1186 uint8 *pA = reinterpret_cast<uint8 *>(pDst) + y * pitch;
1187 uint8 *pB = reinterpret_cast<uint8 *>(pDst) + (height - 1 - y) * pitch;
1188 memcpy(row_buf.get_ptr(), pA, pitch);
1189 memcpy(pA, pB, pitch);
1190 memcpy(pB, row_buf.get_ptr(), pitch);
1195 // Don't know how to flip it
1200 // Restore previous state - order is critical here!
1201 framebuffer_state_saver.restore();
1202 orig_framebuffers.restore();
1203 state_saver.restore();
1205 VOGL_CHECK_GL_ERROR;
1207 return (err == GL_NO_ERROR);
1210 //----------------------------------------------------------------------------------------------------------------------
1211 // vogl_check_gl_error_internal
1212 // Returns *true* on error
1213 //----------------------------------------------------------------------------------------------------------------------
1214 bool vogl_check_gl_error_internal(bool suppress_error_message, const char *pFile, uint line, const char *pFunc)
1218 bool status = false;
1221 // http://www.opengl.org/sdk/docs/man/xhtml/glGetError.xml
1222 // "Thus, glGetError should always be called in a loop, until it returns GL_NO_ERROR, if all error flags are to be reset."
1223 GLenum gl_err = GL_ENTRYPOINT(glGetError)();
1224 if (gl_err == GL_NO_ERROR)
1227 if (!suppress_error_message)
1229 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 : "?");
1232 dynamic_string_array backtrace;
1233 if (get_printable_backtrace(backtrace))
1235 console::error("Backtrace:\n");
1236 for (uint i = 0; i < backtrace.size(); i++)
1237 console::error("%s\n", backtrace[i].get_ptr());
1247 //----------------------------------------------------------------------------------------------------------------------
1248 // vogl_enable_gl_get_errors
1249 //----------------------------------------------------------------------------------------------------------------------
1250 void vogl_enable_gl_get_error()
1252 g_gl_get_error_enabled = true;
1255 //----------------------------------------------------------------------------------------------------------------------
1256 // vogl_disable_gl_get_errors
1257 //----------------------------------------------------------------------------------------------------------------------
1258 void vogl_disable_gl_get_error()
1260 g_gl_get_error_enabled = false;
1263 //----------------------------------------------------------------------------------------------------------------------
1264 // vogl_is_gl_get_error_enabled
1265 //----------------------------------------------------------------------------------------------------------------------
1266 bool vogl_is_gl_get_error_enabled()
1268 return g_gl_get_error_enabled;
1271 //----------------------------------------------------------------------------------------------------------------------
1272 // vogl_is_draw_entrypoint
1273 //----------------------------------------------------------------------------------------------------------------------
1274 bool vogl_is_draw_entrypoint(gl_entrypoint_id_t id)
1280 case VOGL_ENTRYPOINT_glDrawRangeElements:
1281 case VOGL_ENTRYPOINT_glDrawRangeElementsBaseVertex:
1282 case VOGL_ENTRYPOINT_glDrawElements:
1283 case VOGL_ENTRYPOINT_glDrawArrays:
1284 case VOGL_ENTRYPOINT_glDrawArraysEXT:
1285 case VOGL_ENTRYPOINT_glDrawElementsBaseVertex:
1286 case VOGL_ENTRYPOINT_glDrawElementsInstanced:
1287 case VOGL_ENTRYPOINT_glDrawElementsInstancedARB:
1288 case VOGL_ENTRYPOINT_glDrawElementsInstancedBaseVertex:
1289 case VOGL_ENTRYPOINT_glDrawArraysIndirect:
1290 case VOGL_ENTRYPOINT_glDrawArraysInstanced:
1291 case VOGL_ENTRYPOINT_glDrawArraysInstancedARB:
1292 case VOGL_ENTRYPOINT_glDrawArraysInstancedBaseInstance:
1293 case VOGL_ENTRYPOINT_glDrawArraysInstancedEXT:
1294 case VOGL_ENTRYPOINT_glMultiDrawArrays:
1295 case VOGL_ENTRYPOINT_glMultiDrawArraysEXT:
1296 case VOGL_ENTRYPOINT_glMultiDrawElements:
1297 case VOGL_ENTRYPOINT_glMultiDrawElementsEXT:
1298 case VOGL_ENTRYPOINT_glMultiDrawElementsBaseVertex:
1299 case VOGL_ENTRYPOINT_glDrawElementArrayAPPLE:
1300 case VOGL_ENTRYPOINT_glDrawElementArrayATI:
1301 case VOGL_ENTRYPOINT_glDrawElementsIndirect:
1302 case VOGL_ENTRYPOINT_glDrawElementsInstancedBaseInstance:
1303 case VOGL_ENTRYPOINT_glDrawElementsInstancedBaseVertexBaseInstance:
1304 case VOGL_ENTRYPOINT_glDrawElementsInstancedEXT:
1305 case VOGL_ENTRYPOINT_glDrawRangeElementArrayAPPLE:
1306 case VOGL_ENTRYPOINT_glDrawRangeElementArrayATI:
1307 case VOGL_ENTRYPOINT_glDrawRangeElementsEXT:
1308 case VOGL_ENTRYPOINT_glDrawTransformFeedback:
1309 case VOGL_ENTRYPOINT_glDrawTransformFeedbackInstanced:
1310 case VOGL_ENTRYPOINT_glDrawTransformFeedbackNV:
1311 case VOGL_ENTRYPOINT_glDrawTransformFeedbackStream:
1312 case VOGL_ENTRYPOINT_glDrawTransformFeedbackStreamInstanced:
1313 case VOGL_ENTRYPOINT_glMultiDrawArraysIndirect:
1314 case VOGL_ENTRYPOINT_glMultiDrawArraysIndirectAMD:
1315 case VOGL_ENTRYPOINT_glMultiDrawElementArrayAPPLE:
1316 case VOGL_ENTRYPOINT_glMultiDrawElementsIndirect:
1317 case VOGL_ENTRYPOINT_glMultiDrawElementsIndirectAMD:
1318 case VOGL_ENTRYPOINT_glMultiDrawRangeElementArrayAPPLE:
1326 //----------------------------------------------------------------------------------------------------------------------
1327 // vogl_is_clear_entrypoint
1328 //----------------------------------------------------------------------------------------------------------------------
1329 bool vogl_is_clear_entrypoint(gl_entrypoint_id_t id)
1335 case VOGL_ENTRYPOINT_glClear:
1336 case VOGL_ENTRYPOINT_glClearBufferiv:
1337 case VOGL_ENTRYPOINT_glClearBufferfv:
1338 case VOGL_ENTRYPOINT_glClearBufferuiv:
1339 case VOGL_ENTRYPOINT_glClearBufferfi:
1347 //----------------------------------------------------------------------------------------------------------------------
1348 // vogl_get_json_value_as_enum
1349 //----------------------------------------------------------------------------------------------------------------------
1350 GLenum vogl_get_json_value_as_enum(const json_node &node, const char *pKey, GLenum def)
1354 uint64_t v = g_gl_enums.find_enum(node.value_as_string(pKey));
1355 if (v == gl_enums::cUnknownEnum)
1357 VOGL_ASSERT(v <= cUINT32_MAX);
1358 return static_cast<GLenum>(v);
1361 //----------------------------------------------------------------------------------------------------------------------
1362 // vogl_get_json_value_as_enum
1363 //----------------------------------------------------------------------------------------------------------------------
1364 GLenum vogl_get_json_value_as_enum(const json_value &val, GLenum def)
1368 uint64_t v = g_gl_enums.find_enum(val.as_string());
1369 if (v == gl_enums::cUnknownEnum)
1371 VOGL_ASSERT(v <= cUINT32_MAX);
1372 return static_cast<GLenum>(v);
1375 //----------------------------------------------------------------------------------------------------------------------
1376 // vogl_get_binding_from_target
1377 //----------------------------------------------------------------------------------------------------------------------
1378 GLenum vogl_get_binding_from_target(GLenum target)
1384 #define DEFINE_BINDING(c, t, b) \
1387 #include "gl_buffer_bindings.inc"
1388 #undef DEFINE_BINDING
1392 console::warning("%s: Unknown target GL enum 0x%08X\n", VOGL_FUNCTION_NAME, target);
1398 //----------------------------------------------------------------------------------------------------------------------
1399 // vogl_get_object_category_from_binding
1400 //----------------------------------------------------------------------------------------------------------------------
1401 GLenum vogl_get_object_category_from_binding(GLenum binding)
1407 #define DEFINE_BINDING(c, t, b) \
1410 #include "gl_buffer_bindings.inc"
1411 #undef DEFINE_BINDING
1415 console::warning("%s: Unknown binding GL enum 0x%08X\n", VOGL_FUNCTION_NAME, binding);
1421 //----------------------------------------------------------------------------------------------------------------------
1422 // vogl_get_object_category_from_target
1423 //----------------------------------------------------------------------------------------------------------------------
1424 GLenum vogl_get_object_category_from_target(GLenum target)
1430 #define DEFINE_BINDING(c, t, b) \
1433 #include "gl_buffer_bindings.inc"
1434 #undef DEFINE_BINDING
1438 console::warning("%s: Unknown target GL enum 0x%08X\n", VOGL_FUNCTION_NAME, target);
1444 //----------------------------------------------------------------------------------------------------------------------
1445 // vogl_get_target_from_binding
1446 //----------------------------------------------------------------------------------------------------------------------
1447 GLenum vogl_get_target_from_binding(GLenum binding)
1453 #define DEFINE_BINDING(c, t, b) \
1456 #include "gl_buffer_bindings.inc"
1457 #undef DEFINE_BINDING
1461 console::warning("%s: Unknown binding GL enum 0x%08X\n", VOGL_FUNCTION_NAME, binding);
1467 //----------------------------------------------------------------------------------------------------------------------
1469 //----------------------------------------------------------------------------------------------------------------------
1470 void vogl_bind_object(GLenum target, GLuint handle)
1474 GLenum category = vogl_get_object_category_from_target(target);
1480 GL_ENTRYPOINT(glBindTexture)(target, handle);
1485 GL_ENTRYPOINT(glBindBuffer)(target, handle);
1488 case GL_FRAMEBUFFER:
1490 GL_ENTRYPOINT(glBindFramebuffer)(target, handle);
1493 case GL_RENDERBUFFER:
1495 GL_ENTRYPOINT(glBindRenderbuffer)(target, handle);
1500 GL_ENTRYPOINT(glBindSampler)(target, handle);
1503 case GL_VERTEX_ARRAY:
1505 GL_ENTRYPOINT(glBindVertexArray)(handle);
1508 case GL_ACTIVE_TEXTURE:
1510 // not really a binding, exactly, but seems useful
1511 GL_ENTRYPOINT(glActiveTexture)(handle);
1516 GL_ENTRYPOINT(glUseProgram)(handle);
1526 VOGL_CHECK_GL_ERROR;
1529 //----------------------------------------------------------------------------------------------------------------------
1530 // vogl_get_bound_object
1531 //----------------------------------------------------------------------------------------------------------------------
1532 GLuint vogl_get_bound_object(GLenum target)
1536 GLenum binding = vogl_get_binding_from_target(target);
1537 if (binding == GL_NONE)
1544 GL_ENTRYPOINT(glGetIntegerv)(binding, &handle);
1545 VOGL_CHECK_GL_ERROR;
1550 //----------------------------------------------------------------------------------------------------------------------
1551 // vogl_debug_message_control
1552 //----------------------------------------------------------------------------------------------------------------------
1553 void vogl_debug_message_control(const vogl_context_info &context_info, GLenum err_code, bool enabled)
1557 if (!context_info.is_debug_context())
1560 if (!context_info.supports_extension("GL_ARB_debug_output") || (!GL_ENTRYPOINT(glDebugMessageControlARB)))
1563 GL_ENTRYPOINT(glDebugMessageControlARB)(GL_DEBUG_SOURCE_API_ARB, GL_DEBUG_TYPE_ERROR_ARB, GL_DONT_CARE, 1, &err_code, enabled);
1566 //----------------------------------------------------------------------------------------------------------------------
1567 // vogl_determine_texture_target
1568 // NOTE: Don't use this for anything other than debugging!
1569 //----------------------------------------------------------------------------------------------------------------------
1570 GLenum vogl_determine_texture_target(const vogl_context_info &context_info, GLuint handle)
1574 GLboolean is_texture = GL_ENTRYPOINT(glIsTexture)(handle);
1578 vogl_scoped_binding_state orig_texture_state;
1579 orig_texture_state.save_textures();
1581 VOGL_CHECK_GL_ERROR;
1583 // roughly sorted by most likely to least
1584 static const GLenum s_possible_targets[] =
1586 GL_TEXTURE_2D, GL_TEXTURE_CUBE_MAP,
1587 GL_TEXTURE_3D, GL_TEXTURE_2D_ARRAY, GL_TEXTURE_1D, GL_TEXTURE_1D_ARRAY,
1588 GL_TEXTURE_RECTANGLE, GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_BUFFER, GL_TEXTURE_2D_MULTISAMPLE, GL_TEXTURE_2D_MULTISAMPLE_ARRAY
1591 vogl_debug_message_control(context_info, GL_INVALID_OPERATION, false);
1594 for (i = 0; i < VOGL_ARRAY_SIZE(s_possible_targets); i++)
1596 GL_ENTRYPOINT(glBindTexture)(s_possible_targets[i], handle);
1597 if (!vogl_check_gl_error_suppress_message())
1601 if (i == VOGL_ARRAY_SIZE(s_possible_targets))
1602 vogl_check_gl_error_suppress_message();
1604 vogl_debug_message_control(context_info, GL_INVALID_OPERATION, true);
1606 return (i < VOGL_ARRAY_SIZE(s_possible_targets)) ? s_possible_targets[i] : GL_NONE;
1609 //----------------------------------------------------------------------------------------------------------------------
1610 // vogl_state_saver::save
1611 //----------------------------------------------------------------------------------------------------------------------
1612 void vogl_state_saver::save(vogl_generic_state_type type)
1616 #define SAVE_INT_STATE(type, pname) \
1619 m_states.push_back(saved_state(type, pname, vogl_get_gl_integer(pname))); \
1621 #define SAVE_FLOAT_STATE(type, pname) \
1624 m_states.push_back(saved_state(type, pname, vogl_get_gl_float(pname))); \
1629 case cGSTPixelStore:
1631 static const GLenum s_pixel_store_enums[] =
1633 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,
1634 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
1637 for (uint i = 0; i < VOGL_ARRAY_SIZE(s_pixel_store_enums); i++)
1638 SAVE_INT_STATE(cGSTPixelStore, s_pixel_store_enums[i]);
1642 case cGSTPixelTransfer:
1644 // FIXME: All pixel transfer was marked deprecated and not available in a Core Profile (let the caller worry about it)
1645 static const GLenum s_pixel_transfer_int_enums[] =
1647 GL_MAP_COLOR, GL_MAP_STENCIL, GL_INDEX_SHIFT, GL_INDEX_OFFSET
1650 for (uint i = 0; i < VOGL_ARRAY_SIZE(s_pixel_transfer_int_enums); i++)
1651 SAVE_INT_STATE(cGSTPixelTransfer, s_pixel_transfer_int_enums[i]);
1653 static const GLfloat s_pixel_transfer_float_enums[] =
1655 GL_INDEX_OFFSET, GL_RED_SCALE, GL_GREEN_SCALE, GL_BLUE_SCALE, GL_ALPHA_SCALE, GL_DEPTH_SCALE, GL_RED_BIAS, GL_GREEN_BIAS,
1656 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,
1657 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,
1658 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,
1659 GL_POST_CONVOLUTION_GREEN_BIAS, GL_POST_CONVOLUTION_BLUE_BIAS, GL_POST_CONVOLUTION_ALPHA_BIAS
1662 for (uint i = 0; i < VOGL_ARRAY_SIZE(s_pixel_transfer_float_enums); i++)
1663 SAVE_FLOAT_STATE(cGSTPixelTransfer, s_pixel_transfer_float_enums[i]);
1667 case cGSTReadBuffer:
1669 SAVE_INT_STATE(type, GL_READ_BUFFER);
1672 case cGSTDrawBuffer:
1674 uint max_draw_buffers = vogl_get_gl_integer(GL_MAX_DRAW_BUFFERS);
1675 m_draw_buffers.resize(max_draw_buffers);
1677 for (uint i = 0; i < max_draw_buffers; i++)
1678 m_draw_buffers[i] = vogl_get_gl_integer(GL_DRAW_BUFFER0 + i);
1682 case cGSTActiveTexture:
1684 GLint active_texture = 0;
1685 GL_ENTRYPOINT(glGetIntegerv)(GL_ACTIVE_TEXTURE, &active_texture);
1686 m_states.push_back(saved_state(type, GL_ACTIVE_TEXTURE, active_texture));
1689 case cGSTClientActiveTexture:
1691 // FIXME: Don't think this is available in core (let the caller worry about it)
1692 GLint client_active_texture = 0;
1693 GL_ENTRYPOINT(glGetIntegerv)(GL_CLIENT_ACTIVE_TEXTURE, &client_active_texture);
1694 m_states.push_back(saved_state(type, GL_CLIENT_ACTIVE_TEXTURE, client_active_texture));
1697 case cGSTMatrixMode:
1699 SAVE_INT_STATE(type, GL_MATRIX_MODE);
1702 case cGSTARBVertexProgram:
1704 GLint cur_arb_vertex_program = 0;
1705 GL_ENTRYPOINT(glGetProgramivARB)(GL_VERTEX_PROGRAM_ARB, GL_PROGRAM_BINDING_ARB, &cur_arb_vertex_program);
1706 m_states.push_back(saved_state(type, GL_VERTEX_PROGRAM_ARB, cur_arb_vertex_program));
1709 case cGSTARBFragmentProgram:
1711 GLint cur_arb_fragment_program = 0;
1712 GL_ENTRYPOINT(glGetProgramivARB)(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_BINDING_ARB, &cur_arb_fragment_program);
1713 m_states.push_back(saved_state(type, GL_FRAGMENT_PROGRAM_ARB, cur_arb_fragment_program));
1723 #undef SAVE_INT_STATE
1724 #undef SAVE_FLOAT_STATE
1726 VOGL_CHECK_GL_ERROR;
1729 //----------------------------------------------------------------------------------------------------------------------
1730 // vogl_state_saver::restore
1731 //----------------------------------------------------------------------------------------------------------------------
1732 void vogl_state_saver::restore()
1736 if (m_draw_buffers.size())
1739 for (i = m_draw_buffers.size() - 1; i >= 0; --i)
1740 if (m_draw_buffers[i] != GL_NONE)
1743 VOGL_ASSERT(i >= 0);
1745 // On NV, we can cvall glDrawBuffers() with a single GL_BACK, etc. and it's fine. On AMD it barfs.
1748 GL_ENTRYPOINT(glDrawBuffer)(m_draw_buffers[0]);
1749 VOGL_CHECK_GL_ERROR;
1753 GL_ENTRYPOINT(glDrawBuffers)(i + 1, m_draw_buffers.get_ptr());
1754 VOGL_CHECK_GL_ERROR;
1758 for (uint i = 0; i < m_states.size(); i++)
1760 const vogl::value_data_type value_type = m_states[i].m_value.get_data_type();
1762 switch (m_states[i].m_state_type)
1764 case cGSTPixelStore:
1766 VOGL_ASSERT(value_type == cDTInt);
1767 GL_ENTRYPOINT(glPixelStorei)(m_states[i].m_pname, m_states[i].m_value.get_int());
1768 VOGL_CHECK_GL_ERROR;
1771 case cGSTPixelTransfer:
1773 if (value_type == cDTFloat)
1775 GL_ENTRYPOINT(glPixelTransferf)(m_states[i].m_pname, m_states[i].m_value.get_float());
1776 VOGL_CHECK_GL_ERROR;
1778 else if (value_type == cDTInt)
1780 GL_ENTRYPOINT(glPixelTransferi)(m_states[i].m_pname, m_states[i].m_value.get_int());
1781 VOGL_CHECK_GL_ERROR;
1790 case cGSTReadBuffer:
1792 VOGL_ASSERT(m_states[i].m_pname == GL_READ_BUFFER);
1793 VOGL_ASSERT(value_type == cDTInt);
1794 GL_ENTRYPOINT(glReadBuffer)(m_states[i].m_value.get_int());
1795 VOGL_CHECK_GL_ERROR;
1798 case cGSTDrawBuffer:
1803 case cGSTActiveTexture:
1805 VOGL_ASSERT(m_states[i].m_pname == GL_ACTIVE_TEXTURE);
1806 VOGL_ASSERT(value_type == cDTInt);
1807 GL_ENTRYPOINT(glActiveTexture)(m_states[i].m_value.get_int());
1808 VOGL_CHECK_GL_ERROR;
1811 case cGSTClientActiveTexture:
1813 VOGL_ASSERT(m_states[i].m_pname == GL_CLIENT_ACTIVE_TEXTURE);
1814 VOGL_ASSERT(value_type == cDTInt);
1815 GL_ENTRYPOINT(glClientActiveTexture)(m_states[i].m_value.get_int());
1816 VOGL_CHECK_GL_ERROR;
1819 case cGSTMatrixMode:
1821 VOGL_ASSERT(m_states[i].m_pname == GL_MATRIX_MODE);
1822 VOGL_ASSERT(value_type == cDTInt);
1823 GL_ENTRYPOINT(glMatrixMode)(m_states[i].m_value.get_int());
1824 VOGL_CHECK_GL_ERROR;
1827 case cGSTARBVertexProgram:
1829 VOGL_ASSERT(m_states[i].m_pname == GL_VERTEX_PROGRAM_ARB);
1830 VOGL_ASSERT(value_type == cDTInt);
1831 GL_ENTRYPOINT(glBindProgramARB)(GL_VERTEX_PROGRAM_ARB, m_states[i].m_value.get_int());
1832 VOGL_CHECK_GL_ERROR;
1835 case cGSTARBFragmentProgram:
1837 VOGL_ASSERT(m_states[i].m_pname == GL_FRAGMENT_PROGRAM_ARB);
1838 VOGL_ASSERT(value_type == cDTInt);
1839 GL_ENTRYPOINT(glBindProgramARB)(GL_FRAGMENT_PROGRAM_ARB, m_states[i].m_value.get_int());
1840 VOGL_CHECK_GL_ERROR;
1852 //----------------------------------------------------------------------------------------------------------------------
1853 // vogl_gl_get_uniform_size_in_GLints
1854 //----------------------------------------------------------------------------------------------------------------------
1855 int vogl_gl_get_uniform_size_in_GLints(GLenum type)
1863 case GL_UNSIGNED_INT:
1869 case GL_SAMPLER_CUBE:
1870 case GL_SAMPLER_1D_SHADOW:
1871 case GL_SAMPLER_2D_SHADOW:
1872 case GL_SAMPLER_1D_ARRAY:
1873 case GL_SAMPLER_2D_ARRAY:
1874 case GL_SAMPLER_1D_ARRAY_SHADOW:
1875 case GL_SAMPLER_2D_ARRAY_SHADOW:
1876 case GL_SAMPLER_2D_MULTISAMPLE:
1877 case GL_SAMPLER_2D_MULTISAMPLE_ARRAY:
1878 case GL_SAMPLER_CUBE_SHADOW:
1879 case GL_SAMPLER_BUFFER:
1880 case GL_SAMPLER_2D_RECT:
1881 case GL_SAMPLER_2D_RECT_SHADOW:
1882 case GL_INT_SAMPLER_1D:
1883 case GL_INT_SAMPLER_2D:
1884 case GL_INT_SAMPLER_3D:
1885 case GL_INT_SAMPLER_CUBE:
1886 case GL_INT_SAMPLER_1D_ARRAY:
1887 case GL_INT_SAMPLER_2D_ARRAY:
1888 case GL_INT_SAMPLER_2D_MULTISAMPLE:
1889 case GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY:
1890 case GL_INT_SAMPLER_BUFFER:
1891 case GL_INT_SAMPLER_2D_RECT:
1892 case GL_UNSIGNED_INT_SAMPLER_1D:
1893 case GL_UNSIGNED_INT_SAMPLER_2D:
1894 case GL_UNSIGNED_INT_SAMPLER_3D:
1895 case GL_UNSIGNED_INT_SAMPLER_CUBE:
1896 case GL_UNSIGNED_INT_SAMPLER_1D_ARRAY:
1897 case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY:
1898 case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE:
1899 case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY:
1900 case GL_UNSIGNED_INT_SAMPLER_BUFFER:
1901 case GL_UNSIGNED_INT_SAMPLER_2D_RECT:
1906 case GL_IMAGE_2D_RECT:
1908 case GL_IMAGE_BUFFER:
1909 case GL_IMAGE_1D_ARRAY:
1910 case GL_IMAGE_2D_ARRAY:
1911 case GL_IMAGE_2D_MULTISAMPLE:
1912 case GL_IMAGE_2D_MULTISAMPLE_ARRAY:
1913 case GL_INT_IMAGE_1D:
1914 case GL_INT_IMAGE_2D:
1915 case GL_INT_IMAGE_3D:
1916 case GL_INT_IMAGE_2D_RECT:
1917 case GL_INT_IMAGE_CUBE:
1918 case GL_INT_IMAGE_BUFFER:
1919 case GL_INT_IMAGE_1D_ARRAY:
1920 case GL_INT_IMAGE_2D_ARRAY:
1921 case GL_INT_IMAGE_2D_MULTISAMPLE:
1922 case GL_INT_IMAGE_2D_MULTISAMPLE_ARRAY:
1923 case GL_UNSIGNED_INT_IMAGE_1D:
1924 case GL_UNSIGNED_INT_IMAGE_2D:
1925 case GL_UNSIGNED_INT_IMAGE_3D:
1926 case GL_UNSIGNED_INT_IMAGE_2D_RECT:
1927 case GL_UNSIGNED_INT_IMAGE_CUBE:
1928 case GL_UNSIGNED_INT_IMAGE_BUFFER:
1929 case GL_UNSIGNED_INT_IMAGE_1D_ARRAY:
1930 case GL_UNSIGNED_INT_IMAGE_2D_ARRAY:
1931 case GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE:
1932 case GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_ARRAY:
1934 case GL_UNSIGNED_INT_ATOMIC_COUNTER:
1941 case GL_UNSIGNED_INT_VEC2:
1947 case GL_UNSIGNED_INT_VEC3:
1951 case GL_DOUBLE_VEC2:
1954 case GL_UNSIGNED_INT_VEC4:
1965 case GL_DOUBLE_VEC3:
1966 case GL_FLOAT_MAT2x3:
1967 case GL_FLOAT_MAT3x2:
1970 case GL_DOUBLE_VEC4:
1971 case GL_DOUBLE_MAT2:
1972 case GL_FLOAT_MAT2x4:
1973 case GL_FLOAT_MAT4x2:
1976 case GL_DOUBLE_MAT2x3:
1977 case GL_DOUBLE_MAT3x2:
1978 case GL_FLOAT_MAT3x4:
1979 case GL_FLOAT_MAT4x3:
1982 case GL_DOUBLE_MAT2x4:
1983 case GL_DOUBLE_MAT4x2:
1986 case GL_DOUBLE_MAT3:
1989 case GL_DOUBLE_MAT3x4:
1990 case GL_DOUBLE_MAT4x3:
1993 case GL_DOUBLE_MAT4:
1999 vogl_warning_printf("%s: Unknown uniform type 0x%04X\n", VOGL_FUNCTION_NAME, type);
2005 //----------------------------------------------------------------------------------------------------------------------
2006 // vogl_gl_get_uniform_size_in_bytes
2007 //----------------------------------------------------------------------------------------------------------------------
2008 int vogl_gl_get_uniform_size_in_bytes(GLenum type)
2012 return vogl_gl_get_uniform_size_in_GLints(type) * sizeof(GLint);
2015 //----------------------------------------------------------------------------------------------------------------------
2016 // vogl_gl_get_uniform_base_type
2017 //----------------------------------------------------------------------------------------------------------------------
2018 int vogl_gl_get_uniform_base_type(GLenum type)
2031 case GL_FLOAT_MAT2x3:
2032 case GL_FLOAT_MAT3x2:
2033 case GL_FLOAT_MAT2x4:
2034 case GL_FLOAT_MAT4x2:
2035 case GL_FLOAT_MAT3x4:
2036 case GL_FLOAT_MAT4x3:
2040 case GL_DOUBLE_VEC2:
2041 case GL_DOUBLE_VEC3:
2042 case GL_DOUBLE_VEC4:
2043 case GL_DOUBLE_MAT2:
2044 case GL_DOUBLE_MAT3:
2045 case GL_DOUBLE_MAT4:
2046 case GL_DOUBLE_MAT2x3:
2047 case GL_DOUBLE_MAT3x2:
2048 case GL_DOUBLE_MAT2x4:
2049 case GL_DOUBLE_MAT4x2:
2050 case GL_DOUBLE_MAT3x4:
2051 case GL_DOUBLE_MAT4x3:
2060 case GL_UNSIGNED_INT:
2061 case GL_UNSIGNED_INT_VEC2:
2062 case GL_UNSIGNED_INT_VEC3:
2063 case GL_UNSIGNED_INT_VEC4:
2064 case GL_UNSIGNED_INT_ATOMIC_COUNTER:
2065 return GL_UNSIGNED_INT;
2076 case GL_SAMPLER_CUBE:
2077 case GL_SAMPLER_1D_SHADOW:
2078 case GL_SAMPLER_2D_SHADOW:
2079 case GL_SAMPLER_1D_ARRAY:
2080 case GL_SAMPLER_2D_ARRAY:
2081 case GL_SAMPLER_1D_ARRAY_SHADOW:
2082 case GL_SAMPLER_2D_ARRAY_SHADOW:
2083 case GL_SAMPLER_2D_MULTISAMPLE:
2084 case GL_SAMPLER_2D_MULTISAMPLE_ARRAY:
2085 case GL_SAMPLER_CUBE_SHADOW:
2086 case GL_SAMPLER_BUFFER:
2087 case GL_SAMPLER_2D_RECT:
2088 case GL_SAMPLER_2D_RECT_SHADOW:
2089 case GL_INT_SAMPLER_1D:
2090 case GL_INT_SAMPLER_2D:
2091 case GL_INT_SAMPLER_3D:
2092 case GL_INT_SAMPLER_CUBE:
2093 case GL_INT_SAMPLER_1D_ARRAY:
2094 case GL_INT_SAMPLER_2D_ARRAY:
2095 case GL_INT_SAMPLER_2D_MULTISAMPLE:
2096 case GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY:
2097 case GL_INT_SAMPLER_BUFFER:
2098 case GL_INT_SAMPLER_2D_RECT:
2099 case GL_UNSIGNED_INT_SAMPLER_1D:
2100 case GL_UNSIGNED_INT_SAMPLER_2D:
2101 case GL_UNSIGNED_INT_SAMPLER_3D:
2102 case GL_UNSIGNED_INT_SAMPLER_CUBE:
2103 case GL_UNSIGNED_INT_SAMPLER_1D_ARRAY:
2104 case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY:
2105 case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE:
2106 case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY:
2107 case GL_UNSIGNED_INT_SAMPLER_BUFFER:
2108 case GL_UNSIGNED_INT_SAMPLER_2D_RECT:
2114 case GL_IMAGE_2D_RECT:
2116 case GL_IMAGE_BUFFER:
2117 case GL_IMAGE_1D_ARRAY:
2118 case GL_IMAGE_2D_ARRAY:
2119 case GL_IMAGE_2D_MULTISAMPLE:
2120 case GL_IMAGE_2D_MULTISAMPLE_ARRAY:
2121 case GL_INT_IMAGE_1D:
2122 case GL_INT_IMAGE_2D:
2123 case GL_INT_IMAGE_3D:
2124 case GL_INT_IMAGE_2D_RECT:
2125 case GL_INT_IMAGE_CUBE:
2126 case GL_INT_IMAGE_BUFFER:
2127 case GL_INT_IMAGE_1D_ARRAY:
2128 case GL_INT_IMAGE_2D_ARRAY:
2129 case GL_INT_IMAGE_2D_MULTISAMPLE:
2130 case GL_INT_IMAGE_2D_MULTISAMPLE_ARRAY:
2131 case GL_UNSIGNED_INT_IMAGE_1D:
2132 case GL_UNSIGNED_INT_IMAGE_2D:
2133 case GL_UNSIGNED_INT_IMAGE_3D:
2134 case GL_UNSIGNED_INT_IMAGE_2D_RECT:
2135 case GL_UNSIGNED_INT_IMAGE_CUBE:
2136 case GL_UNSIGNED_INT_IMAGE_BUFFER:
2137 case GL_UNSIGNED_INT_IMAGE_1D_ARRAY:
2138 case GL_UNSIGNED_INT_IMAGE_2D_ARRAY:
2139 case GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE:
2140 case GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_ARRAY:
2141 return GL_IMAGE_1D; // what do we return??
2146 vogl_warning_printf("%s: Unknown uniform type 0x%04X\n", VOGL_FUNCTION_NAME, type);
2152 //----------------------------------------------------------------------------------------------------------------------
2153 // vogl_format_debug_output_arb
2154 // Loosely derived from http://www.altdevblogaday.com/2011/06/23/improving-opengl-error-messages/
2155 //----------------------------------------------------------------------------------------------------------------------
2156 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)
2160 char source_str[32];
2161 const char *source_fmt = "UNDEFINED(0x%04X)";
2165 case GL_DEBUG_SOURCE_API_ARB:
2168 case GL_DEBUG_SOURCE_WINDOW_SYSTEM_ARB:
2169 source_fmt = "WINDOW_SYSTEM";
2171 case GL_DEBUG_SOURCE_SHADER_COMPILER_ARB:
2172 source_fmt = "SHADER_COMPILER";
2174 case GL_DEBUG_SOURCE_THIRD_PARTY_ARB:
2175 source_fmt = "THIRD_PARTY";
2177 case GL_DEBUG_SOURCE_APPLICATION_ARB:
2178 source_fmt = "APPLICATION";
2180 case GL_DEBUG_SOURCE_OTHER_ARB:
2181 source_fmt = "OTHER";
2187 vogl_sprintf_s(source_str, sizeof(source_str), source_fmt, source);
2190 const char *type_fmt = "UNDEFINED(0x%04X)";
2193 case GL_DEBUG_TYPE_ERROR_ARB:
2196 case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_ARB:
2197 type_fmt = "DEPRECATED_BEHAVIOR";
2199 case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_ARB:
2200 type_fmt = "UNDEFINED_BEHAVIOR";
2202 case GL_DEBUG_TYPE_PORTABILITY_ARB:
2203 type_fmt = "PORTABILITY";
2205 case GL_DEBUG_TYPE_PERFORMANCE_ARB:
2206 type_fmt = "PERFORMANCE";
2208 case GL_DEBUG_TYPE_OTHER_ARB:
2214 vogl_sprintf_s(type_str, sizeof(type_str), type_fmt, type);
2216 char severity_str[32];
2217 const char *severity_fmt = "UNDEFINED";
2220 case GL_DEBUG_SEVERITY_HIGH_ARB:
2221 severity_fmt = "HIGH";
2223 case GL_DEBUG_SEVERITY_MEDIUM_ARB:
2224 severity_fmt = "MEDIUM";
2226 case GL_DEBUG_SEVERITY_LOW_ARB:
2227 severity_fmt = "LOW";
2233 vogl_sprintf_s(severity_str, sizeof(severity_str), severity_fmt, severity);
2235 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);
2238 //----------------------------------------------------------------------------------------------------------------------
2239 // vogl_generic_arb_debug_callback
2240 //----------------------------------------------------------------------------------------------------------------------
2241 void vogl_generic_arb_debug_callback(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *message, GLvoid *pUser_param)
2245 VOGL_NOTE_UNUSED(length);
2246 VOGL_NOTE_UNUSED(pUser_param);
2248 char final_message[4096];
2250 vogl_format_debug_output_arb(final_message, sizeof(final_message), source, type, id, severity, reinterpret_cast<const char *>(message));
2252 vogl_warning_printf("%s: %s\n", VOGL_FUNCTION_NAME, final_message);
2255 //----------------------------------------------------------------------------------------------------------------------
2256 // vogl_enable_generic_context_debug_messages
2257 //----------------------------------------------------------------------------------------------------------------------
2258 void vogl_enable_generic_context_debug_messages()
2260 GL_ENTRYPOINT(glDebugMessageCallbackARB)(vogl_generic_arb_debug_callback, NULL);
2261 GL_ENTRYPOINT(glEnable)(GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB);
2262 VOGL_CHECK_GL_ERROR;
2265 //----------------------------------------------------------------------------------------------------------------------
2266 // vogl_create_context
2267 //----------------------------------------------------------------------------------------------------------------------
2268 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)
2270 vogl_context_attribs attribs;
2271 attribs.add_key(GLX_CONTEXT_MAJOR_VERSION_ARB, major_ver);
2272 attribs.add_key(GLX_CONTEXT_MINOR_VERSION_ARB, minor_ver);
2274 if (flags & (cCHCCoreProfileFlag | cCHCCompatProfileFlag))
2276 uint profile_mask = 0;
2277 if (flags & cCHCCoreProfileFlag)
2278 profile_mask |= GLX_CONTEXT_CORE_PROFILE_BIT_ARB;
2280 if (flags & cCHCCompatProfileFlag)
2281 profile_mask |= GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB;
2283 attribs.add_key(GLX_CONTEXT_PROFILE_MASK_ARB, profile_mask);
2285 if (flags & eCHCDebugContextFlag)
2287 attribs.add_key(GLX_CONTEXT_FLAGS_ARB, GLX_CONTEXT_DEBUG_BIT_ARB);
2290 GLXContext context = GL_ENTRYPOINT(glXCreateContextAttribsARB)(display, fb_config, share_context, GL_TRUE, attribs.get_ptr());
2297 pDesc->init(VOGL_ENTRYPOINT_glXCreateContextAttribsARB, GL_TRUE, (vogl_trace_ptr_value)context, (vogl_trace_ptr_value)share_context, attribs);
2303 //----------------------------------------------------------------------------------------------------------------------
2304 // vogl_get_current_context
2305 //----------------------------------------------------------------------------------------------------------------------
2306 vogl_gl_context vogl_get_current_context()
2308 return GL_ENTRYPOINT(glXGetCurrentContext)();
2311 //----------------------------------------------------------------------------------------------------------------------
2312 // vogl_get_current_display
2313 //----------------------------------------------------------------------------------------------------------------------
2314 vogl_gl_display vogl_get_current_display()
2316 return GL_ENTRYPOINT(glXGetCurrentDisplay)();
2319 //----------------------------------------------------------------------------------------------------------------------
2320 // vogl_get_current_drawable
2321 //----------------------------------------------------------------------------------------------------------------------
2322 vogl_gl_drawable vogl_get_current_drawable()
2324 return GL_ENTRYPOINT(glXGetCurrentDrawable)();
2327 //----------------------------------------------------------------------------------------------------------------------
2328 // vogl_get_current_fb_config
2329 //----------------------------------------------------------------------------------------------------------------------
2330 vogl_gl_fb_config vogl_get_current_fb_config(uint screen)
2332 GLXDrawable pDrawable = GL_ENTRYPOINT(glXGetCurrentDrawable)();
2333 Display *pDisplay = GL_ENTRYPOINT(glXGetCurrentDisplay)();
2334 if ((!pDrawable) || (!pDisplay))
2337 GLuint fbconfig_id = 0;
2338 GL_ENTRYPOINT(glXQueryDrawable)(pDisplay, pDrawable, GLX_FBCONFIG_ID, &fbconfig_id);
2340 GLint attrib_list[3] = { GLX_FBCONFIG_ID, static_cast<GLint>(fbconfig_id), None };
2341 GLint nelements = 0;
2342 GLXFBConfig *pConfigs = GL_ENTRYPOINT(glXChooseFBConfig)(pDisplay, screen, attrib_list, &nelements);
2344 if ((pConfigs) && (nelements > 0))
2350 //----------------------------------------------------------------------------------------------------------------------
2351 // vogl_make_current
2352 //----------------------------------------------------------------------------------------------------------------------
2353 void vogl_make_current(vogl_gl_display display, vogl_gl_drawable drawable, vogl_gl_context context)
2355 GL_ENTRYPOINT(glXMakeCurrent)(display, drawable, context);
2358 //----------------------------------------------------------------------------------------------------------------------
2359 // vogl_destroy_context
2360 //----------------------------------------------------------------------------------------------------------------------
2361 void vogl_destroy_context(vogl_gl_display display, vogl_gl_context context)
2363 GL_ENTRYPOINT(glXDestroyContext)(display, context);
2366 //----------------------------------------------------------------------------------------------------------------------
2367 // vogl_get_max_supported_mip_levels
2368 //----------------------------------------------------------------------------------------------------------------------
2369 int vogl_get_max_supported_mip_levels()
2371 int max_texture_size = vogl_get_gl_integer(GL_MAX_TEXTURE_SIZE);
2372 return math::floor_log2i(max_texture_size);