I defined GL_GLEXT_PROTOTYPES to enable the automatic linkage in my application, and right inside calling glTexStorage2DEXT, it crashes.
This is the binary dump I got if it helps:
0x10044f4e2: leaq 0x161f67(%rip), %rdi ; gles::extensions::EXT_TextureStorage& gles::State::getgles::extensions::EXT_TextureStorage()::obj
0x10044f4e9: movl %r15d, %ecx
0x10044f4ec: movl %r14d, %r8d
0x10044f4ef: movl %ebx, %r9d
0x10044f4f2: callq 0x10044ee30 ; gles::extensions::EXT_TextureStorage::TexStorage2DEXT(gles::Context, unsigned int, int, unsigned int, int, int)
0x10044f4f7: cmpl $0x0, -0x60(%rbp) <<<<<<<<<<<< crashed here <<<<<<<<<<<<
0x10044f4fb: je 0x10044f506 ; glTexStorage2DEXT + 214
0x10044f4fd: leaq -0x60(%rbp), %rdi
0x10044f501: callq 0x100440d10 ; gles::update_gl_error(gles::Context const&)
OSX 10.9.2/Macbook Pro mid-2010
My code is very similar to this sample code: OGLES2HelloAPI_OSX.mm, (I only moved the code around to fit my layout). I also modified the original example by adding this function; it didn’t crash but report a INVALID_OPERATION error. The code is added after eglMakeCurrent, as follows:
glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_BGRA8_EXT, 128, 128);
I also use some other extensions, i.e. GL_OES_vertex_array_object, and it crashes too, in a similar manner.
This is the output from the modified sample:
(Info) Hardware profile: None
(Info) PVRVFrame version 9.6
(Error) in function: glTexStorage2DEXT GL: 502
(GL_INVALID_OPERATION) VF: A0001 (an internal error occurred)
After a bit more investigation, I made a dumb mistake that’s misleading the problem… I enabled “break at all exceptions” in xcode, and it looked to me as a crash. However, the issue still occurs - instead of crashing, it always reports 502 error, and this happens to glGenVertexArraysOES as well.
Those are dumped information:
Vendor: Imagination Technologies (Host: NVIDIA Corporation)
Renderer: PVRVFrame 9.6 - None (Host: NVIDIA GeForce GT 330M OpenGL Engine) (SDK Build: 3.2@2637721)
Version: OpenGL ES 2.0 (Host: 2.1 NVIDIA-8.24.11 310.90.9b01)
GL_IMG_texture_compression_pvrtc GL_APPLE_copy_texture_levels GL_APPLE_sync GL_IMG_multisampled_render_to_texture GL_EXT_discard_framebuffer GL_EXT_multi_draw_arrays GL_EXT_texture_storage GL_OES_compressed_ETC1_RGB8_texture GL_OES_mapbuffer GL_OES_vertex_array_object GL_OES_byte_coordinates GL_OES_fixed_point GL_OES_single_precision GL_OES_matrix_get GL_OES_read_format GL_OES_point_sprite GL_OES_texture_env_crossbar GL_OES_texture_mirrored_repeat GL_OES_texture_cube_map GL_OES_blend_func_separate GL_OES_stencil_wrap GL_OES_extended_matrix_palette GL_OES_required_internalformat GL_IMG_read_format GL_IMG_texture_stream GL_OES_egl_sync GL_IMG_vertex_array_object GL_APPLE_texture_2D_limited_npot GL_IMG_uniform_buffer_object GL_EXT_debug_marker GL_IMG_texture_env_enhanced_fixed_function GL_OES_matrix_palette GL_IMG_user_clip_plane GL_OES_draw_texture GL_OES_point_size_array GL_OES_framebuffer_object GL_OES_query_matrix GL_OES_blend_equation_separate GL_OES_blend_subtract GL_OES_texture_float GL_OES_texture_half_float GL_OES_element_index_uint GL_OES_fragment_precision_high GL_OES_depth_texture GL_OES_packed_depth_stencil GL_OES_standard_derivatives GL_EXT_shader_texture_lod GL_IMG_shader_binary GL_IMG_texture_stream2 GL_IMG_texture_npot GL_IMG_program_binary GL_EXT_texture_filter_anisotropic GL_IMG_texture_compression_pvrtc2 GL_EXT_blend_minmax GL_EXT_draw_buffers GL_EXT_multisampled_render_to_texture GL_EXT_occlusion_query_boolean GL_KHR_debug GL_OES_get_program_binary GL_EXT_texture_type_2_10_10_10_REV GL_EXT_texture_rg GL_OES_depth_texture_cube_map
Instead of defining GL_GLEXT_PROTOTYPES, you should retrieve a pointer to any extension function you want to use by first calling glGetString to check if the extension is supported, and then eglGetProcAddress with the name of the function.
PFNGLTEXSTORAGE2DEXTPROC glTexStorage2DEXT = 0;
if(strcmp((char*)(glGetString(GL_EXTENSIONS)), “GL_EXT_texture_storage”) == 0)
glTexStorage2DEXT = eglGetProcAddress(“glTexStorage2DEXT”);
// extension is not supported
glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_BGRA8_EXT, 128, 128);
Thanks for your reply! I did that too; as I mentioned in the comment, the extension does include GL_EXT_texture_storage.
Are you definitely retrieving the functions explicitly using eglGetProcAddress? Using the prototypes defined in the headers won’t work because the library doesn’t export extension functions.
Otherwise, you could try updating the emulator to the latest version. You may be hitting a bug which we fixed where OES_vertex_array_object operations weren’t being initialised in some cases, but it sounds like something different.
Yes, I was using eglGetProcAddress to retrieve the function address explicitly and it gave me the same error.
From the crash dump, it looked like it happened around checking the egl context. One of my guesses was that as glTexStorage2DEXT is escalated to the standard API, the SDK got confused about the current context because the code may be shared for both GLES2 and GLES3? But OES_vertex_array_object gave me the similar error…
I will try to upgrade to the latest SDK and see if that helps.
After updating the SDK, it does help! It looks like all the symbols are removed from the lib so I have to retrieve them by eglGetProcAddress. However there is a new problem: even the extension strings include GL_EXT_texture_storage, but the function returns null pointer. And when I looked through some example code, (CPVRTgles2Ext::LoadExtensions), some of them are actually getting null returns. Is this expected? or a bug?
Unfortunately it turns out we don’t support EXT_texture_storage on OSX right now. The reason for this is we rely on the “compatibility” OpenGL profile to simplify the emulation process. Sadly OSX doesn’t support the operations required to emulate EXT_texture_storage when in compatibility mode. The name shouldn’t appear in the extension string either, so that sounds like a bug.
Support for EXT_texture_storage may come in a future update. Better feature support on OSX, including ES 3 support, is something we are currently looking into.
Thanks! It makes a lot sense now. Hopefully, you guys can fix this kind of bugs in the next release; but for now, the reliable to check the extension is to fetch the function pointer and check if it’s null.