// // Copyright (c) 2017 The Khronos Group Inc. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // #include "testBase.h" #include "common.h" #if defined( __APPLE__ ) #include #else #include #include #endif extern int supportsHalf(cl_context context, bool* supports_half); static int test_image_info( cl_context context, cl_command_queue queue, GLenum glTarget, GLuint glTexture, size_t imageWidth, size_t imageHeight, size_t imageDepth, cl_image_format *outFormat, ExplicitType *outType, void **outResultBuffer ) { clMemWrapper streams[ 2 ]; int error; // Create a CL image from the supplied GL texture streams[ 0 ] = (*clCreateFromGLTexture_ptr)( context, CL_MEM_READ_ONLY, glTarget, 0, glTexture, &error ); if( error != CL_SUCCESS ) { print_error( error, "Unable to create CL image from GL texture" ); GLint fmt; glGetTexLevelParameteriv( glTarget, 0, GL_TEXTURE_INTERNAL_FORMAT, &fmt ); log_error( " Supplied GL texture was format %s\n", GetGLFormatName( fmt ) ); return error; } // Determine data type and format that CL came up with error = clGetImageInfo( streams[ 0 ], CL_IMAGE_FORMAT, sizeof( cl_image_format ), outFormat, NULL ); test_error( error, "Unable to get CL image format" ); cl_gl_object_type object_type; switch (glTarget) { case GL_TEXTURE_1D: object_type = CL_GL_OBJECT_TEXTURE1D; break; case GL_TEXTURE_BUFFER: object_type = CL_GL_OBJECT_TEXTURE_BUFFER; break; case GL_TEXTURE_1D_ARRAY: object_type = CL_GL_OBJECT_TEXTURE1D_ARRAY; break; case GL_TEXTURE_2D: case GL_TEXTURE_RECTANGLE_EXT: case GL_TEXTURE_CUBE_MAP_POSITIVE_X: case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: object_type = CL_GL_OBJECT_TEXTURE2D; break; case GL_TEXTURE_2D_ARRAY: object_type = CL_GL_OBJECT_TEXTURE2D_ARRAY; break; case GL_TEXTURE_3D: object_type = CL_GL_OBJECT_TEXTURE3D; break; default: log_error("Unsupported texture target."); return 1; } return CheckGLObjectInfo(streams[0], object_type, glTexture, glTarget, 0); } static int test_image_format_get_info( cl_context context, cl_command_queue queue, size_t width, size_t height, size_t depth, GLenum target, struct format* fmt, MTdata data) { int error = 0; // If we're testing a half float format, then we need to determine the // rounding mode of this machine. Punt if we fail to do so. if( fmt->type == kHalf ) { if( DetectFloatToHalfRoundingMode(queue) ) return 0; bool supports_half = false; error = supportsHalf(context, &supports_half); if( error != 0 ) return error; if (!supports_half) return 0; } size_t w = width, h = height, d = depth; // Unpack the format and use it, along with the target, to create an // appropriate GL texture. GLenum gl_fmt = fmt->formattype; GLenum gl_internal_fmt = fmt->internal; GLenum gl_type = fmt->datatype; ExplicitType type = fmt->type; glTextureWrapper texture; glBufferWrapper glbuf; // If we're testing a half float format, then we need to determine the // rounding mode of this machine. Punt if we fail to do so. if( fmt->type == kHalf ) if( DetectFloatToHalfRoundingMode(queue) ) return 1; // Use the correct texture creation function depending on the target, and // adjust width, height, depth as appropriate so subsequent size calculations // succeed. switch (target) { case GL_TEXTURE_1D: h = 1; d = 1; CreateGLTexture1D( width, target, gl_fmt, gl_internal_fmt, gl_type, type, &texture, &error, false, data ); break; case GL_TEXTURE_BUFFER: h = 1; d = 1; CreateGLTextureBuffer( width, target, gl_fmt, gl_internal_fmt, gl_type, type, &texture, &glbuf, &error, false, data ); break; case GL_TEXTURE_1D_ARRAY: d = 1; CreateGLTexture1DArray( width, height, target, gl_fmt, gl_internal_fmt, gl_type, type, &texture, &error, false, data ); break; case GL_TEXTURE_RECTANGLE_EXT: case GL_TEXTURE_2D: case GL_TEXTURE_CUBE_MAP_POSITIVE_X: case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: d = 1; CreateGLTexture2D( width, height, target, gl_fmt, gl_internal_fmt, gl_type, type, &texture, &error, false, data ); break; case GL_TEXTURE_2D_ARRAY: CreateGLTexture2DArray( width, height, depth, target, gl_fmt, gl_internal_fmt, gl_type, type, &texture, &error, false, data ); break; case GL_TEXTURE_3D: d = 1; CreateGLTexture3D( width, height, depth, target, gl_fmt, gl_internal_fmt, gl_type, type, &texture, &error, data, false ); break; default: log_error("Unsupported texture target.\n"); return 1; } if ( error == -2 ) { log_info("OpenGL texture couldn't be created, because a texture is too big. Skipping test.\n"); return 0; } if ( error != 0 ) { if ((gl_fmt == GL_RGBA_INTEGER_EXT) && (!CheckGLIntegerExtensionSupport())) { log_info("OpenGL version does not support GL_RGBA_INTEGER_EXT. " "Skipping test.\n"); return 0; } else { return error; } } cl_image_format clFormat; ExplicitType actualType; char *outBuffer; // Perform the info check: return test_image_info( context, queue, target, texture, w, h, d, &clFormat, &actualType, (void **)&outBuffer ); } int test_images_get_info_common( cl_device_id device, cl_context context, cl_command_queue queue, struct format* formats, size_t nformats, GLenum *targets, size_t ntargets, sizevec_t *sizes, size_t nsizes ) { int error = 0; RandomSeed seed(gRandomSeed); // First, ensure this device supports images. if (checkForImageSupport(device)) { log_info("Device does not support images. Skipping test.\n"); return 0; } size_t fidx, tidx, sidx; // Test each format on every target, every size. for ( fidx = 0; fidx < nformats; fidx++ ) { for ( tidx = 0; tidx < ntargets; tidx++ ) { if ( formats[ fidx ].datatype == GL_UNSIGNED_INT_2_10_10_10_REV ) { // Check if the RGB 101010 format is supported if ( is_rgb_101010_supported( context, targets[ tidx ] ) == 0 ) break; // skip } log_info( "Testing image info for GL format %s : %s : %s : %s\n", GetGLTargetName( targets[ tidx ] ), GetGLFormatName( formats[ fidx ].internal ), GetGLBaseFormatName( formats[ fidx ].formattype ), GetGLTypeName( formats[ fidx ].datatype ) ); for ( sidx = 0; sidx < nsizes; sidx++ ) { // Test this format + size: if ( test_image_format_get_info(context, queue, sizes[sidx].width, sizes[sidx].height, sizes[sidx].depth, targets[tidx], &formats[fidx], seed) ) { // We land here in the event of test failure. log_error( "ERROR: Image info test failed for %s : %s : %s : %s\n\n", GetGLTargetName( targets[ tidx ] ), GetGLFormatName( formats[ fidx ].internal ), GetGLBaseFormatName( formats[ fidx ].formattype ), GetGLTypeName( formats[ fidx ].datatype ) ); error++; // Skip the other sizes for this format. break; } } } } return error; }