Hi all,
I’m trying to interop between EGL which is bound to either OpenGL or OpenGLES as the client API. I can create the EGL context and surface just fine. But when I attempt to create the OpenCL context I get an CL_INVALID_OPERATION error.
System details:
Linux 64, Amazon EC2 instance. uname -r = 4.4.20-0.1.fm.237.49.326.metal1.x86_64
GPU - Grid K520. Driver 367.124
Program runtime details:
I’ve created a sample program to help me figure out why this is failing. It dumps some information such as the available extensions in the implementations.
EGL Extensions: EGL_EXT_create_context_robustness EGL_EXT_output_base EGL_EXT_output_drm EGL_EXT_stream_consumer_egloutput EGL_EXT_stream_acquire_mode EGL_IMG_context_priority EGL_KHR_config_attribs EGL_KHR_create_context_no_error EGL_KHR_create_context EGL_KHR_fence_sync EGL_KHR_get_all_proc_addresses EGL_KHR_swap_buffers_with_damage EGL_KHR_gl_renderbuffer_image EGL_KHR_gl_texture_2D_image EGL_KHR_gl_texture_cubemap_image EGL_KHR_image EGL_KHR_image_base EGL_KHR_reusable_sync EGL_KHR_stream EGL_KHR_stream_consumer_gltexture EGL_KHR_stream_cross_process_fd EGL_KHR_stream_fifo EGL_KHR_stream_producer_eglsurface EGL_KHR_surfaceless_context EGL_NV_stream_metadata EGL_NV_stream_sync EGL_NV_stream_consumer_gltexture_yuv EGL_NV_sync EGL_NV_system_time EGL_NV_output_drm_flip_event EGL_WL_bind_wayland_display
OpenCL extensions (same in both platform and device): cl_khr_global_int32_base_atomics cl_khr_global_int32_extended_atomics cl_khr_local_int32_base_atomics cl_khr_local_int32_extended_atomics cl_khr_fp64 cl_khr_byte_addressable_store cl_khr_icd cl_khr_gl_sharing cl_nv_compiler_options cl_nv_device_attribute_query cl_nv_pragma_unroll cl_nv_copy_opts
The key extension I believe is the cl_khr_gl_sharing.
The program creates the EGL resources (Display, Surface and Context). Since the EGL_KHR_surfaceless_context is available I have also tried this without creating a surface (same error). I have also tried the EGL extension for querying the displays but this also returns only one and still fails in the same way.
The program then moves onto querying the OCL platforms (there’s only one) and then the same for the available devices (also just one). Then it attempts to create the OCL context using the extensions by providing the attributes CL_EGL_DISPLAY_KHR and CL_GL_CONTEXT_KHR.
I’ve been through the help for CL and EGL but I don’t see anything that makes it clear why this is failing. In the help for OCL the closest hint I can find is this: “CL_INVALID_OPERATION: Any of the devices specified in the devices argument cannot support OpenCL objects which share the data store of an OpenGL object, as described in section 9.7” But looking over section 9.7 in the spec offers no insight into the actual problem (This test is the equivalent of a shrug).
As far as I can tell this should be working. Any ideas or hints? Below is the code I’ve been using to test this.
In the code there are a lot of various flags passed to the config attribs. I have tested these in MANY combinations and they are likely not the culprits.
#define EGL_EXT_PROTOTYPES 1
#include <EGL/egl.h>
#include <EGL/eglext.h>
#include <CL/cl.h>
#include <CL/cl_ext.h>
#include <CL/cl_gl.h>
void dumpEglConfigAttributes(EGLDisplay eglDisplay, EGLint numConfig, const EGLConfig &eglConfig);
void dumpEglExtensions( EGLDisplay eglDisplay );
void dumpOclPlatformAttributes(cl_int platNum, cl_platform_id platId);
void dumpOclDeviceAttributes(cl_int devNum, cl_device_id devId);
void clCallback( const char *errinfo, const void *private_info, size_t cb, void *user_data );
int main()
{
std::cout << “Initializeing EGL” << std::endl;
////////////////////////////////////////
// Initialize and bind to the OGL API
EGLDisplay eglDisplay = eglGetDisplay( EGL_DEFAULT_DISPLAY );
if( eglDisplay == EGL_NO_DISPLAY )
{
std::cout << "EGL: Can not get current display." << std::endl;
return -1;
}
if( eglBindAPI( EGL_OPENGL_API ) == EGL_FALSE )
{
std::cout << "Error calling bind for OPEN_GL api during EGL init." << std::endl;
return -1;
}
if( eglQueryAPI() != EGL_OPENGL_API )
{
std::cout << "The bound API is not correct. Should be OpenGL" << std::endl;
return -1;
}
////////////////////////////////////////
// Use Extensions to find the EGL Display
bool useDisplayExtension = false;
if( useDisplayExtension )
{
int MAX_DEVICES = 20;
EGLint numDevices = 0;
EGLDeviceEXT eglDevices[ MAX_DEVICES ];
PFNEGLQUERYDEVICESEXTPROC eglQueryDevicesEXT = (PFNEGLQUERYDEVICESEXTPROC) eglGetProcAddress("eglQueryDevicesEXT");
eglQueryDevicesEXT(MAX_DEVICES, eglDevices, &numDevices);
std::cout << "Num EXT Devices: " << numDevices << std::endl;
PFNEGLGETPLATFORMDISPLAYEXTPROC eglGetPlatformDisplayEXT = (PFNEGLGETPLATFORMDISPLAYEXTPROC) eglGetProcAddress("eglGetPlatformDisplayEXT");
EGLDisplay extEglDpy = eglGetPlatformDisplayEXT( EGL_PLATFORM_DEVICE_EXT, eglDevices[0], 0 );
if( extEglDpy == eglDisplay )
{
std::cout << "Displays are the same, nothing new here." << std::endl;
}
else
{
std::cout << "Display is different. Trying new display." << std::endl;
eglDisplay = extEglDpy;
}
}
EGLint eglVersionMajor = 0;
EGLint eglVersionMinor = 0;
if( eglInitialize( eglDisplay, &eglVersionMajor, &eglVersionMinor ) == EGL_FALSE )
{
std::cout << "EGL: Attempt to initialize on display failed." << std::endl;
return -1;
}
std::cout << "Initialized default display. Got version " << eglVersionMajor << "." << eglVersionMinor << std::endl;
EGLint numConfigs = 0;
if( eglGetConfigs( eglDisplay, nullptr, 0, &numConfigs ) == EGL_FALSE )
{
std::cout << "Filed to query for the number of available configs." << std::endl;
return -1;
}
if( numConfigs == 0 )
{
std::cout << "Config query returned 0. That's just wrong!" << std::endl;
return -1;
}
std::vector< EGLConfig > eglConfigs( numConfigs );
if( eglGetConfigs( eglDisplay, eglConfigs.data(), numConfigs, &numConfigs ) == EGL_FALSE )
{
std::cout << "Failed to query for the number of available configs." << std::endl;
return -1;
}
std::cout << "Number of configs: " << numConfigs << std::endl;
EGLint configNum = 0;
for( const EGLConfig &eglConfig : eglConfigs )
{
dumpEglConfigAttributes( eglDisplay, configNum, eglConfig );
configNum++;
}
EGLint configAttribs[] =
{
EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT,
EGL_CONFORMANT, EGL_OPENGL_BIT,
EGL_SURFACE_TYPE, EGL_PBUFFER_BIT,
//EGL_BIND_TO_TEXTURE_RGBA, EGL_TRUE,
EGL_COLOR_BUFFER_TYPE, EGL_RGB_BUFFER,
EGL_RED_SIZE, 8,
EGL_GREEN_SIZE, 8,
EGL_BLUE_SIZE, 8,
EGL_ALPHA_SIZE, 8,
EGL_NONE
};
EGLConfig eglConfig;
int nConfig = 0;
if( eglChooseConfig( eglDisplay, configAttribs, &eglConfig, 1, &nConfig ) == EGL_FALSE )
{
std::cout << "Choosing config for display failed." << std::endl;
return -1;
}
std::cout << "Choose config reutrned [" << nConfig << "] configs." << std::endl;
dumpEglExtensions( eglDisplay );
/*
int surfAttribs =
{
EGL_WIDTH, 128,
EGL_HEIGHT, 128,
//EGL_TEXTURE_FORMAT, EGL_TEXTURE_RGBA,
EGL_NONE
};
EGLSurface eglSurface = eglCreatePbufferSurface( eglDisplay, eglConfig, surfAttribs );
if( eglSurface == EGL_NO_SURFACE )
{
std::cout << "EGL: Creating PBuffer surface failed." << std::endl;
return -1;
}
*/
EGLint createAttribs[] =
{
//EGL_CONFORMANT, EGL_OPENGL_BIT,
EGL_CONTEXT_CLIENT_VERSION, 3,
// EGL_CONTEXT_MAJOR_VERSION_KHR, 3,
// EGL_CONTEXT_MINOR_VERSION_KHR, 0,
//EGL_CONTEXT_FLAGS_KHR, EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR | EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR | EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR,
// EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR, EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR,// | EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT_KHR,
// EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT, EGL_TRUE,
// EGL_CONTEXT_OPENGL_NO_ERROR_KHR, EGL_TRUE,
EGL_NONE
};
// EGLContext eglContext = eglCreateContext( eglDisplay, eglConfig, EGL_NO_CONTEXT, nullptr );
EGLContext eglContext = eglCreateContext( eglDisplay, eglConfig, EGL_NO_CONTEXT, createAttribs );
if( eglContext == EGL_NO_CONTEXT )
{
std::cout << “EGL: Can not create context for display.” << eglGetError() << std::endl;
return -1;
}
std::cout << "Context created for EGL." << std::endl;
//if( eglMakeCurrent( eglDisplay, eglSurface, eglSurface, eglContext ) == EGL_FALSE )
if( eglMakeCurrent( eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, eglContext ) == EGL_FALSE )
{
std::cout << "EGL: Failed on making context current." << std::endl;
return -1;
}
std::cout << "I think we're done with EGL initialization. Working on OCL init" << std::endl;
cl_int clRetVal = CL_SUCCESS;
cl_uint numPlatformsFound = 0;
clRetVal = clGetPlatformIDs( 0, nullptr, &numPlatformsFound );
if( clRetVal != CL_SUCCESS )
{
std::cout << "FAILED: Getting platform count failed :-(. Error code[" << clRetVal << "] NumPlats["
<< numPlatformsFound << "]" << std::endl;
return -1;
}
std::cout << "Platforms available: " << numPlatformsFound << std::endl;
std::vector< cl_platform_id > platforms( numPlatformsFound );
clRetVal = clGetPlatformIDs( numPlatformsFound, platforms.data(), nullptr );
if( clRetVal != CL_SUCCESS )
{
std::cout << "FAILED: Getting platforms failed :-(. Error code[" << clRetVal << "] NumPlats["
<< numPlatformsFound << "]" << std::endl;
return -1;
}
cl_int platNum = 0;
for( const cl_platform_id &clPlatform : platforms )
{
dumpOclPlatformAttributes( platNum, clPlatform );
/* This test seems to return the exact same platofrm
// Use KHR ICDS to get the list of platforms
clIcdGetPlatformIDsKHR_fn getKHRPlatforms = (clIcdGetPlatformIDsKHR_fn)clGetExtensionFunctionAddressForPlatform ( clPlatform , “clIcdGetPlatformIDsKHR” );
if( getKHRPlatforms != nullptr )
{
std::cout << "Getting the platofrm extension is not NULL. Trying to get EXT platforms." << std::endl;
cl_uint extPlatsFound = 0;
clRetVal = getKHRPlatforms( 0, nullptr, &extPlatsFound );
if( clRetVal != CL_SUCCESS )
{
std::cout << "FAILED: Getting platform count failed :-(. Error code[" << clRetVal << "] NumPlats["
<< extPlatsFound << "]" << std::endl;
return -1;
}
else
{
std::cout << "ICDs Platforms found: " << extPlatsFound << std::endl;
}
std::vector< cl_platform_id > extPlats( extPlatsFound );
clRetVal = getKHRPlatforms( extPlatsFound, extPlats.data(), nullptr );
if( clRetVal != CL_SUCCESS )
{
std::cout << "FAILED: Getting platforms failed :-(. Error code[" << clRetVal << "] NumPlats["
<< extPlatsFound << "]" << std::endl;
return -1;
}
dumpOclPlatformAttributes( platNum, extPlats[ 0 ] );
}
*/
// Use these platform ids to find the device id / info
cl_uint clDevicesFound = 0;
clRetVal = clGetDeviceIDs( clPlatform, CL_DEVICE_TYPE_GPU, 0, nullptr, &clDevicesFound );
if( clRetVal != CL_SUCCESS )
{
std::cout << "FAILED: Can not query for number of devies on platform id[" << clPlatform << "], num["
<< platNum << "]" << std::endl;
return -1;
}
std::cout << "Number of devices for platform: " << clDevicesFound << std::endl;
std::vector< cl_device_id > clDevices( clDevicesFound );
clRetVal = clGetDeviceIDs( clPlatform, CL_DEVICE_TYPE_GPU, clDevicesFound, clDevices.data(), nullptr );
if( clRetVal != CL_SUCCESS )
{
std::cout << "FAILED: Can not get devies on platform id[" << clPlatform << "], num["
<< platNum << "]" << std::endl;
return -1;
}
std::cout << "Devices retrieved. Attempting to create context using shared EGL reference." << std::endl;
cl_int devNum = 0;
for( cl_device_id clDevice : clDevices )
{
dumpOclDeviceAttributes( devNum, clDevice );
//cl_bool interOp = CL_TRUE;
cl_context_properties properties[] =
{
CL_CONTEXT_PLATFORM, reinterpret_cast< cl_context_properties >( clPlatform ),
//CL_CONTEXT_INTEROP_USER_SYNC, static_cast< cl_context_properties >( interOp ),
//CL_EGL_DISPLAY_KHR, reinterpret_cast< cl_context_properties >( eglGetCurrentDisplay() ),
//CL_GL_CONTEXT_KHR, reinterpret_cast< cl_context_properties >( eglGetCurrentContext() ),
CL_EGL_DISPLAY_KHR, reinterpret_cast< cl_context_properties >( eglDisplay ),
CL_GL_CONTEXT_KHR, reinterpret_cast< cl_context_properties >( eglContext ),
0
};
/*cl_context clContext = */clCreateContext( properties, 1, &clDevice, clCallback, nullptr, &clRetVal );
if( clRetVal != CL_SUCCESS )
{
std::cout << "ERROR: Failed to create context for CL device. Error code[" << clRetVal << "]" << std::endl;
return -1;
}
std::cout << "Successful creating context for device!" << std::endl;
devNum++;
}
platNum++;
}
return 0;
}
void dumpEglConfigAttributes( EGLDisplay eglDisplay, EGLint numConfig, const EGLConfig &eglConfig )
{
EGLint attribValue;
// EGL_ALPHA_SIZE - Returns the number of bits of alpha stored in the color buffer.
if( eglGetConfigAttrib( eglDisplay, eglConfig, EGL_ALPHA_SIZE, &attribValue ) == EGL_FALSE )
std::cout << "FAILED: No attribute data for [EGL_ALPHA_SIZE]" << std::endl;
else
std::cout << "[" << numConfig << "] " << "EGL_ALPHA_SIZE: " << attribValue << std::endl;
// EGL_ALPHA_MASK_SIZE - Returns the number of bits in the alpha mask buffer.
if( eglGetConfigAttrib( eglDisplay, eglConfig, EGL_ALPHA_MASK_SIZE, &attribValue ) == EGL_FALSE )
std::cout << "FAILED: No attribute data for [EGL_ALPHA_MASK_SIZE]" << std::endl;
else
std::cout << "[" << numConfig << "] " << "EGL_ALPHA_MASK_SIZE: " << attribValue << std::endl;
// EGL_BIND_TO_TEXTURE_RGB - Returns EGL_TRUE if color buffers can be bound to an RGB texture, EGL_FALSE otherwise.
if( eglGetConfigAttrib( eglDisplay, eglConfig, EGL_BIND_TO_TEXTURE_RGB, &attribValue ) == EGL_FALSE )
std::cout << "FAILED: No attribute data for [EGL_BIND_TO_TEXTURE_RGB]" << std::endl;
else
std::cout << "[" << numConfig << "] " << "EGL_BIND_TO_TEXTURE_RGB: " << ( ( attribValue == EGL_TRUE ) ? "True" : "False" ) << std::endl;
// EGL_BIND_TO_TEXTURE_RGBA - Returns EGL_TRUE if color buffers can be bound to an RGBA texture, EGL_FALSE otherwise.
if( eglGetConfigAttrib( eglDisplay, eglConfig, EGL_BIND_TO_TEXTURE_RGBA, &attribValue ) == EGL_FALSE )
std::cout << "FAILED: No attribute data for [EGL_BIND_TO_TEXTURE_RGBA]" << std::endl;
else
std::cout << "[" << numConfig << "] " << "EGL_BIND_TO_TEXTURE_RGBA: " << ( ( attribValue == EGL_TRUE ) ? "True" : "False" ) << std::endl;
// EGL_BLUE_SIZE - Returns the number of bits of blue stored in the color buffer.
if( eglGetConfigAttrib( eglDisplay, eglConfig, EGL_BLUE_SIZE, &attribValue ) == EGL_FALSE )
std::cout << "FAILED: No attribute data for [EGL_BLUE_SIZE]" << std::endl;
else
std::cout << "[" << numConfig << "] " << "EGL_BLUE_SIZE: " << attribValue << std::endl;
// EGL_BUFFER_SIZE - Returns the depth of the color buffer. It is the sum of EGL_RED_SIZE, EGL_GREEN_SIZE, EGL_BLUE_SIZE, and EGL_ALPHA_SIZE.
if( eglGetConfigAttrib( eglDisplay, eglConfig, EGL_BUFFER_SIZE, &attribValue ) == EGL_FALSE )
std::cout << "FAILED: No attribute data for [EGL_BUFFER_SIZE]" << std::endl;
else
std::cout << "[" << numConfig << "] " << "EGL_BUFFER_SIZE: " << attribValue << std::endl;
// EGL_COLOR_BUFFER_TYPE - Returns the color buffer type. Possible types are EGL_RGB_BUFFER and EGL_LUMINANCE_BUFFER.
// EGL_CONFIG_CAVEAT - Returns the caveats for the frame buffer configuration. Possible caveat values are EGL_NONE, EGL_SLOW_CONFIG, and EGL_NON_CONFORMANT.
// EGL_CONFIG_ID - Returns the ID of the frame buffer configuration.
if( eglGetConfigAttrib( eglDisplay, eglConfig, EGL_CONFIG_ID, &attribValue ) == EGL_FALSE )
std::cout << "FAILED: No attribute data for [EGL_CONFIG_ID]" << std::endl;
else
std::cout << "[" << numConfig << "] " << "EGL_CONFIG_ID: " << attribValue << std::endl;
// EGL_CONFORMANT - Returns a bitmask indicating which client API contexts created with respect to this config are conformant.
if( eglGetConfigAttrib( eglDisplay, eglConfig, EGL_CONFORMANT, &attribValue ) == EGL_FALSE )
std::cout << "FAILED: No attribute data for [EGL_CONFORMANT]" << std::endl;
else
{
std::cout << "[" << numConfig << "] " << "EGL_CONFORMANT: ";
if( attribValue & EGL_OPENGL_BIT ) std::cout << ".EGL_OPENGL_BIT";
if( attribValue & EGL_OPENGL_ES_BIT ) std::cout << ".EGL_OPENGL_ES_BIT";
if( attribValue & EGL_OPENGL_ES2_BIT ) std::cout << ".EGL_OPENGL_ES2_BIT";
if( attribValue & EGL_OPENGL_ES3_BIT ) std::cout << ".EGL_OPENGL_ES3_BIT";
if( attribValue & EGL_OPENVG_BIT ) std::cout << ".EGL_OPENVG_BIT";
std::cout << std::endl;
}
// EGL_DEPTH_SIZE - Returns the number of bits in the depth buffer.
if( eglGetConfigAttrib( eglDisplay, eglConfig, EGL_DEPTH_SIZE, &attribValue ) == EGL_FALSE )
std::cout << "FAILED: No attribute data for [EGL_DEPTH_SIZE]" << std::endl;
else
std::cout << "[" << numConfig << "] " << "EGL_DEPTH_SIZE: " << attribValue << std::endl;
// EGL_GREEN_SIZE - Returns the number of bits of green stored in the color buffer.
if( eglGetConfigAttrib( eglDisplay, eglConfig, EGL_GREEN_SIZE, &attribValue ) == EGL_FALSE )
std::cout << "FAILED: No attribute data for [EGL_GREEN_SIZE]" << std::endl;
else
std::cout << "[" << numConfig << "] " << "EGL_GREEN_SIZE: " << attribValue << std::endl;
// EGL_LEVEL - Returns the frame buffer level. Level zero is the default frame buffer. Positive levels correspond to frame buffers that overlay the default buffer and negative levels correspond to frame buffers that underlay the default buffer.
if( eglGetConfigAttrib( eglDisplay, eglConfig, EGL_LEVEL, &attribValue ) == EGL_FALSE )
std::cout << "FAILED: No attribute data for [EGL_LEVEL]" << std::endl;
else
std::cout << "[" << numConfig << "] " << "EGL_LEVEL: " << attribValue << std::endl;
// EGL_LUMINANCE_SIZE - Returns the number of bits of luminance stored in the luminance buffer.
if( eglGetConfigAttrib( eglDisplay, eglConfig, EGL_LUMINANCE_SIZE, &attribValue ) == EGL_FALSE )
std::cout << "FAILED: No attribute data for [EGL_LUMINANCE_SIZE]" << std::endl;
else
std::cout << "[" << numConfig << "] " << "EGL_LUMINANCE_SIZE: " << attribValue << std::endl;
// EGL_MAX_PBUFFER_WIDTH - Returns the maximum width of a pixel buffer surface in pixels.
if( eglGetConfigAttrib( eglDisplay, eglConfig, EGL_MAX_PBUFFER_WIDTH, &attribValue ) == EGL_FALSE )
std::cout << "FAILED: No attribute data for [EGL_MAX_PBUFFER_WIDTH]" << std::endl;
else
std::cout << "[" << numConfig << "] " << "EGL_MAX_PBUFFER_WIDTH: " << attribValue << std::endl;
// EGL_MAX_PBUFFER_HEIGHT - Returns the maximum height of a pixel buffer surface in pixels.
if( eglGetConfigAttrib( eglDisplay, eglConfig, EGL_MAX_PBUFFER_HEIGHT, &attribValue ) == EGL_FALSE )
std::cout << "FAILED: No attribute data for [EGL_MAX_PBUFFER_HEIGHT]" << std::endl;
else
std::cout << "[" << numConfig << "] " << "EGL_MAX_PBUFFER_HEIGHT: " << attribValue << std::endl;
// EGL_MAX_PBUFFER_PIXELS - Returns the maximum size of a pixel buffer surface in pixels.
if( eglGetConfigAttrib( eglDisplay, eglConfig, EGL_MAX_PBUFFER_PIXELS, &attribValue ) == EGL_FALSE )
std::cout << "FAILED: No attribute data for [EGL_MAX_PBUFFER_PIXELS]" << std::endl;
else
std::cout << "[" << numConfig << "] " << "EGL_MAX_PBUFFER_PIXELS: " << attribValue << std::endl;
// EGL_MAX_SWAP_INTERVAL - Returns the maximum value that can be passed to eglSwapInterval.
if( eglGetConfigAttrib( eglDisplay, eglConfig, EGL_MAX_SWAP_INTERVAL, &attribValue ) == EGL_FALSE )
std::cout << "FAILED: No attribute data for [EGL_MAX_SWAP_INTERVAL]" << std::endl;
else
std::cout << "[" << numConfig << "] " << "EGL_MAX_SWAP_INTERVAL: " << attribValue << std::endl;
// EGL_MIN_SWAP_INTERVAL - Returns the minimum value that can be passed to eglSwapInterval.
if( eglGetConfigAttrib( eglDisplay, eglConfig, EGL_MIN_SWAP_INTERVAL, &attribValue ) == EGL_FALSE )
std::cout << "FAILED: No attribute data for [EGL_MIN_SWAP_INTERVAL]" << std::endl;
else
std::cout << "[" << numConfig << "] " << "EGL_MIN_SWAP_INTERVAL: " << attribValue << std::endl;
// EGL_NATIVE_RENDERABLE - Returns EGL_TRUE if native rendering APIs can render into the surface, EGL_FALSE otherwise.
if( eglGetConfigAttrib( eglDisplay, eglConfig, EGL_NATIVE_RENDERABLE, &attribValue ) == EGL_FALSE )
std::cout << "FAILED: No attribute data for [EGL_NATIVE_RENDERABLE]" << std::endl;
else
std::cout << "[" << numConfig << "] " << "EGL_NATIVE_RENDERABLE: " << ( ( attribValue == EGL_TRUE ) ? "True" : "False" ) << std::endl;
// EGL_NATIVE_VISUAL_ID - Returns the ID of the associated native visual.
if( eglGetConfigAttrib( eglDisplay, eglConfig, EGL_NATIVE_VISUAL_ID, &attribValue ) == EGL_FALSE )
std::cout << "FAILED: No attribute data for [EGL_NATIVE_VISUAL_ID]" << std::endl;
else
std::cout << "[" << numConfig << "] " << "EGL_NATIVE_VISUAL_ID: " << attribValue << std::endl;
// EGL_NATIVE_VISUAL_TYPE - Returns the type of the associated native visual.
// EGL_RED_SIZE - Returns the number of bits of red stored in the color buffer.
if( eglGetConfigAttrib( eglDisplay, eglConfig, EGL_RED_SIZE, &attribValue ) == EGL_FALSE )
std::cout << "FAILED: No attribute data for [EGL_RED_SIZE]" << std::endl;
else
std::cout << "[" << numConfig << "] " << "EGL_RED_SIZE: " << attribValue << std::endl;
// EGL_RENDERABLE_TYPE - Returns a bitmask indicating the types of supported client API contexts.
if( eglGetConfigAttrib( eglDisplay, eglConfig, EGL_RENDERABLE_TYPE, &attribValue ) == EGL_FALSE )
std::cout << "FAILED: No attribute data for [EGL_RENDERABLE_TYPE]" << std::endl;
else
{
std::cout << "[" << numConfig << "] " << "EGL_RENDERABLE_TYPE: ";
if( attribValue & EGL_OPENGL_BIT ) std::cout << ".EGL_OPENGL_BIT";
if( attribValue & EGL_OPENGL_ES_BIT ) std::cout << ".EGL_OPENGL_ES_BIT";
if( attribValue & EGL_OPENGL_ES2_BIT ) std::cout << ".EGL_OPENGL_ES2_BIT";
if( attribValue & EGL_OPENGL_ES3_BIT ) std::cout << ".EGL_OPENGL_ES3_BIT";
if( attribValue & EGL_OPENVG_BIT ) std::cout << ".EGL_OPENVG_BIT";
std::cout << std::endl;
}
// EGL_SAMPLE_BUFFERS - Returns the number of multisample buffers.
if( eglGetConfigAttrib( eglDisplay, eglConfig, EGL_SAMPLE_BUFFERS, &attribValue ) == EGL_FALSE )
std::cout << "FAILED: No attribute data for [EGL_SAMPLE_BUFFERS]" << std::endl;
else
std::cout << "[" << numConfig << "] " << "EGL_SAMPLE_BUFFERS: " << attribValue << std::endl;
// EGL_SAMPLES - Returns the number of samples per pixel.
if( eglGetConfigAttrib( eglDisplay, eglConfig, EGL_SAMPLES, &attribValue ) == EGL_FALSE )
std::cout << "FAILED: No attribute data for [EGL_SAMPLES]" << std::endl;
else
std::cout << "[" << numConfig << "] " << "EGL_SAMPLES: " << attribValue << std::endl;
// EGL_STENCIL_SIZE - Returns the number of bits in the stencil buffer.
if( eglGetConfigAttrib( eglDisplay, eglConfig, EGL_STENCIL_SIZE, &attribValue ) == EGL_FALSE )
std::cout << "FAILED: No attribute data for [EGL_STENCIL_SIZE]" << std::endl;
else
std::cout << "[" << numConfig << "] " << "EGL_STENCIL_SIZE: " << attribValue << std::endl;
// EGL_SURFACE_TYPE - Returns a bitmask indicating the types of supported EGL surfaces.
if( eglGetConfigAttrib( eglDisplay, eglConfig, EGL_SURFACE_TYPE, &attribValue ) == EGL_FALSE )
std::cout << "FAILED: No attribute data for [EGL_SURFACE_TYPE]" << std::endl;
else
{
std::cout << "[" << numConfig << "] " << "EGL_SURFACE_TYPE: ";
if( attribValue & EGL_MULTISAMPLE_RESOLVE_BOX_BIT ) std::cout << ".EGL_MULTISAMPLE_RESOLVE_BOX_BIT";
if( attribValue & EGL_PBUFFER_BIT ) std::cout << ".EGL_PBUFFER_BIT";
if( attribValue & EGL_PIXMAP_BIT ) std::cout << ".EGL_PIXMAP_BIT";
if( attribValue & EGL_SWAP_BEHAVIOR_PRESERVED_BIT ) std::cout << ".EGL_SWAP_BEHAVIOR_PRESERVED_BIT";
if( attribValue & EGL_VG_ALPHA_FORMAT_PRE_BIT ) std::cout << ".EGL_VG_ALPHA_FORMAT_PRE_BIT";
if( attribValue & EGL_VG_COLORSPACE_LINEAR_BIT ) std::cout << ".EGL_VG_COLORSPACE_LINEAR_BIT";
if( attribValue & EGL_WINDOW_BIT ) std::cout << ".EGL_WINDOW_BIT";
std::cout << std::endl;
}
// EGL_TRANSPARENT_TYPE - Returns the type of supported transparency. Possible transparency values are: EGL_NONE, and EGL_TRANSPARENT_RGB.
// EGL_TRANSPARENT_RED_VALUE - Returns the transparent red value.
if( eglGetConfigAttrib( eglDisplay, eglConfig, EGL_TRANSPARENT_RED_VALUE, &attribValue ) == EGL_FALSE )
std::cout << "FAILED: No attribute data for [EGL_TRANSPARENT_RED_VALUE]" << std::endl;
else
std::cout << "[" << numConfig << "] " << "EGL_TRANSPARENT_RED_VALUE: " << attribValue << std::endl;
// EGL_TRANSPARENT_GREEN_VALUE - Returns the transparent green value.
if( eglGetConfigAttrib( eglDisplay, eglConfig, EGL_TRANSPARENT_GREEN_VALUE, &attribValue ) == EGL_FALSE )
std::cout << "FAILED: No attribute data for [EGL_TRANSPARENT_GREEN_VALUE]" << std::endl;
else
std::cout << "[" << numConfig << "] " << "EGL_TRANSPARENT_GREEN_VALUE: " << attribValue << std::endl;
// EGL_TRANSPARENT_BLUE_VALUE - Returns the transparent blue value.
if( eglGetConfigAttrib( eglDisplay, eglConfig, EGL_TRANSPARENT_BLUE_VALUE, &attribValue ) == EGL_FALSE )
std::cout << "FAILED: No attribute data for [EGL_TRANSPARENT_BLUE_VALUE]" << std::endl;
else
std::cout << "[" << numConfig << "] " << "EGL_TRANSPARENT_BLUE_VALUE: " << attribValue << std::endl;
}
void dumpEglExtensions( EGLDisplay eglDisplay )
{
std::cout << "EGL Query[EGL_CLIENT_APIS]: " << eglQueryString( eglDisplay, EGL_CLIENT_APIS ) << std::endl;
std::cout << "EGL Query[EGL_VENDOR]: " << eglQueryString( eglDisplay, EGL_VENDOR ) << std::endl;
std::cout << "EGL Query[EGL_VERSION]: " << eglQueryString( eglDisplay, EGL_VERSION ) << std::endl;
std::cout << "EGL Query[EGL_EXTENSIONS]: " << eglQueryString( eglDisplay, EGL_EXTENSIONS ) << std::endl;
}
void showPlatformAttribute(cl_int platNum, cl_platform_id platId, std::string friendlyName, cl_platform_info platAttribute )
{
std::vector< char > platformAttributeData;
size_t attributeDataSize = 0;
cl_int clRetVal = clGetPlatformInfo( platId, platAttribute, 0, nullptr, &attributeDataSize );
if( clRetVal == CL_SUCCESS || attributeDataSize != 0 )
{
platformAttributeData.resize( attributeDataSize + 1 );
clGetPlatformInfo( platId, platAttribute, attributeDataSize, platformAttributeData.data(), nullptr );
platformAttributeData[ attributeDataSize ] = '\0';
}
if( clRetVal != CL_SUCCESS || attributeDataSize == 0 )
{
std::cout << "[" << platNum << "] FAILED to get attribute[" << friendlyName << "]" << std::endl;
}
else
{
std::cout << "[" << platNum << "] " << friendlyName << ": " << std::string( platformAttributeData.data() )
<< std::endl;
}
}
void dumpOclPlatformAttributes(cl_int platNum, cl_platform_id platId)
{
showPlatformAttribute( platNum, platId, “CL_PLATFORM_VENDOR”, CL_PLATFORM_VENDOR );
showPlatformAttribute( platNum, platId, “CL_PLATFORM_EXTENSIONS”, CL_PLATFORM_EXTENSIONS );
}
void showDeviceAttribute(cl_int devNum, cl_device_id devId, std::string friendlyName, cl_device_info devAttribute )
{
std::vector< char > deviceAttributeData;
size_t attributeDataSize = 0;
cl_int clRetVal = clGetDeviceInfo( devId, devAttribute, 0, nullptr, &attributeDataSize );
if( clRetVal == CL_SUCCESS || attributeDataSize != 0 )
{
deviceAttributeData.resize( attributeDataSize + 1 );
clGetDeviceInfo( devId, devAttribute, attributeDataSize, deviceAttributeData.data(), nullptr );
deviceAttributeData[ attributeDataSize ] = '\0';
}
if( clRetVal != CL_SUCCESS || attributeDataSize == 0 )
{
std::cout << "[" << devNum << "] FAILED to get attribute[" << friendlyName << "]" << std::endl;
}
else
{
std::cout << "[" << devNum << "] " << friendlyName << ": " << std::string( deviceAttributeData.data() )
<< std::endl;
}
}
void dumpOclDeviceAttributes(cl_int devNum, cl_device_id devId)
{
showDeviceAttribute( devNum, devId, “CL_DEVICE_EXTENSIONS”, CL_DEVICE_EXTENSIONS );
showDeviceAttribute( devNum, devId, “CL_DEVICE_NAME”, CL_DEVICE_NAME );
showDeviceAttribute( devNum, devId, “CL_DEVICE_OPENCL_C_VERSION”, CL_DEVICE_OPENCL_C_VERSION );
showDeviceAttribute( devNum, devId, “CL_DEVICE_PROFILE”, CL_DEVICE_PROFILE );
}
void clCallback( const char *errinfo, const void *private_info, size_t cb, void *user_data )
{
std::cout << "CL Call Back: " << errinfo << std::endl;
}