mirror of
https://github.com/KhronosGroup/OpenCL-CTS.git
synced 2026-03-19 22:19:02 +00:00
The maintenance of the conformance tests is moving to Github. This commit contains all the changes that have been done in Gitlab since the first public release of the conformance tests. Signed-off-by: Kevin Petit <kevin.petit@arm.com>
480 lines
19 KiB
C++
480 lines
19 KiB
C++
//
|
|
// 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"
|
|
|
|
#if defined( __APPLE__ )
|
|
#include <OpenGL/glu.h>
|
|
#else
|
|
#include <GL/glu.h>
|
|
#include <CL/cl_gl.h>
|
|
#endif
|
|
|
|
#if defined (__linux__)
|
|
GLboolean
|
|
gluCheckExtension(const GLubyte *extension, const GLubyte *extensions)
|
|
{
|
|
const GLubyte *start;
|
|
GLubyte *where, *terminator;
|
|
|
|
/* Extension names should not have spaces. */
|
|
where = (GLubyte *) strchr((const char*)extension, ' ');
|
|
if (where || *extension == '\0')
|
|
return 0;
|
|
/* It takes a bit of care to be fool-proof about parsing the
|
|
OpenGL extensions string. Don't be fooled by sub-strings,
|
|
etc. */
|
|
start = extensions;
|
|
for (;;) {
|
|
where = (GLubyte *) strstr((const char *) start, (const char*) extension);
|
|
if (!where)
|
|
break;
|
|
terminator = where + strlen((const char*) extension);
|
|
if (where == start || *(where - 1) == ' ')
|
|
if (*terminator == ' ' || *terminator == '\0')
|
|
return 1;
|
|
start = terminator;
|
|
}
|
|
return 0;
|
|
}
|
|
#endif
|
|
|
|
|
|
extern "C" { extern cl_uint gRandomSeed; };
|
|
|
|
// This is defined in the write common code:
|
|
extern int test_cl_image_write( cl_context context, cl_command_queue queue,
|
|
GLenum target, cl_mem clImage, size_t imageWidth, size_t imageHeight,
|
|
size_t imageDepth, cl_image_format *outFormat, ExplicitType *outType,
|
|
void **outSourceBuffer, MTdata d, bool supports_half );
|
|
|
|
extern int test_cl_image_read( cl_context context, cl_command_queue queue,
|
|
GLenum gl_target, cl_mem image, size_t width, size_t height, size_t depth,
|
|
cl_image_format *outFormat, ExplicitType *outType, void **outResultBuffer );
|
|
|
|
extern int supportsHalf(cl_context context, bool* supports_half);
|
|
|
|
static int test_attach_renderbuffer_read_image( cl_context context, cl_command_queue queue, GLenum glTarget, GLuint glRenderbuffer,
|
|
size_t imageWidth, size_t imageHeight, cl_image_format *outFormat, ExplicitType *outType, void **outResultBuffer )
|
|
{
|
|
int error;
|
|
|
|
// Create a CL image from the supplied GL renderbuffer
|
|
cl_mem image = (*clCreateFromGLRenderbuffer_ptr)( context, CL_MEM_READ_ONLY, glRenderbuffer, &error );
|
|
if( error != CL_SUCCESS )
|
|
{
|
|
print_error( error, "Unable to create CL image from GL renderbuffer" );
|
|
return error;
|
|
}
|
|
|
|
return test_cl_image_read( context, queue, glTarget, image, imageWidth,
|
|
imageHeight, 1, outFormat, outType, outResultBuffer );
|
|
}
|
|
|
|
int test_renderbuffer_read_image( cl_context context, cl_command_queue queue,
|
|
GLsizei width, GLsizei height, GLenum attachment,
|
|
GLenum format, GLenum internalFormat,
|
|
GLenum glType, ExplicitType type, MTdata d )
|
|
{
|
|
int error;
|
|
|
|
if( type == kHalf )
|
|
if( DetectFloatToHalfRoundingMode(queue) )
|
|
return 1;
|
|
|
|
// Create the GL renderbuffer
|
|
glFramebufferWrapper glFramebuffer;
|
|
glRenderbufferWrapper glRenderbuffer;
|
|
void *tmp = CreateGLRenderbuffer( width, height, attachment, format, internalFormat, glType, type, &glFramebuffer, &glRenderbuffer, &error, d, true );
|
|
BufferOwningPtr<char> inputBuffer(tmp);
|
|
if( error != 0 )
|
|
{
|
|
if ((format == GL_RGBA_INTEGER_EXT) && (!CheckGLIntegerExtensionSupport()))
|
|
{
|
|
log_info("OpenGL version does not support GL_RGBA_INTEGER_EXT. Skipping test.\n");
|
|
return 0;
|
|
}
|
|
else
|
|
{
|
|
return error;
|
|
}
|
|
}
|
|
|
|
// Run and get the results
|
|
cl_image_format clFormat;
|
|
ExplicitType actualType;
|
|
char *outBuffer;
|
|
error = test_attach_renderbuffer_read_image( context, queue, attachment, glRenderbuffer, width, height, &clFormat, &actualType, (void **)&outBuffer );
|
|
if( error != 0 )
|
|
return error;
|
|
BufferOwningPtr<char> actualResults(outBuffer);
|
|
|
|
log_info( "- Read [%4d x %4d] : GL renderbuffer : %s : %s : %s => CL Image : %s : %s \n", width, height,
|
|
GetGLFormatName( format ), GetGLFormatName( internalFormat ), GetGLTypeName( glType),
|
|
GetChannelOrderName( clFormat.image_channel_order ), GetChannelTypeName( clFormat.image_channel_data_type ));
|
|
|
|
#ifdef DEBUG
|
|
log_info("- start read GL data -- \n");
|
|
DumpGLBuffer(glType, width, height, actualResults);
|
|
log_info("- end read GL data -- \n");
|
|
#endif
|
|
|
|
// We have to convert our input buffer to the returned type, so we can validate.
|
|
BufferOwningPtr<char> convertedInput(convert_to_expected( inputBuffer, width * height, type, actualType ));
|
|
|
|
#ifdef DEBUG
|
|
log_info("- start input data -- \n");
|
|
DumpGLBuffer(GetGLTypeForExplicitType(actualType), width, height, convertedInput);
|
|
log_info("- end input data -- \n");
|
|
#endif
|
|
|
|
#ifdef DEBUG
|
|
log_info("- start converted data -- \n");
|
|
DumpGLBuffer(GetGLTypeForExplicitType(actualType), width, height, actualResults);
|
|
log_info("- end converted data -- \n");
|
|
#endif
|
|
|
|
// Now we validate
|
|
int valid = 0;
|
|
if(convertedInput) {
|
|
if( actualType == kFloat )
|
|
valid = validate_float_results( convertedInput, actualResults, width, height );
|
|
else
|
|
valid = validate_integer_results( convertedInput, actualResults, width, height, get_explicit_type_size( actualType ) );
|
|
}
|
|
|
|
return valid;
|
|
}
|
|
|
|
int test_renderbuffer_read( cl_device_id device, cl_context context, cl_command_queue queue, int numElements )
|
|
{
|
|
GLenum attachments[] = { GL_COLOR_ATTACHMENT0_EXT };
|
|
|
|
struct {
|
|
GLenum internal;
|
|
GLenum format;
|
|
GLenum datatype;
|
|
ExplicitType type;
|
|
|
|
} formats[] = {
|
|
{ GL_RGBA, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, kUChar },
|
|
{ GL_RGBA, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, kUChar },
|
|
{ GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, kUChar },
|
|
{ GL_RGBA16, GL_RGBA, GL_UNSIGNED_SHORT, kUShort },
|
|
|
|
// Renderbuffers with integer formats do not seem to work reliably across
|
|
// platforms/implementations. Disabling this in version 1.0 of CL conformance tests.
|
|
|
|
#ifdef TEST_INTEGER_FORMATS
|
|
|
|
{ GL_RGBA8I_EXT, GL_RGBA_INTEGER_EXT, GL_BYTE, kChar },
|
|
{ GL_RGBA16I_EXT, GL_RGBA_INTEGER_EXT, GL_SHORT, kShort },
|
|
{ GL_RGBA32I_EXT, GL_RGBA_INTEGER_EXT, GL_INT, kInt },
|
|
{ GL_RGBA8UI_EXT, GL_RGBA_INTEGER_EXT, GL_UNSIGNED_BYTE, kUChar },
|
|
{ GL_RGBA16UI_EXT, GL_RGBA_INTEGER_EXT, GL_UNSIGNED_SHORT, kUShort },
|
|
{ GL_RGBA32UI_EXT, GL_RGBA_INTEGER_EXT, GL_UNSIGNED_INT, kUInt },
|
|
#endif
|
|
{ GL_RGBA32F_ARB, GL_RGBA, GL_FLOAT, kFloat },
|
|
{ GL_RGBA16F_ARB, GL_RGBA, GL_HALF_FLOAT, kHalf }
|
|
};
|
|
|
|
size_t fmtIdx, attIdx;
|
|
int error = 0;
|
|
#ifdef DEBUG
|
|
size_t iter = 1;
|
|
#else
|
|
size_t iter = 6;
|
|
#endif
|
|
RandomSeed seed( gRandomSeed );
|
|
|
|
// Check if images are supported
|
|
if (checkForImageSupport(device)) {
|
|
log_info("Device does not support images. Skipping test.\n");
|
|
return 0;
|
|
}
|
|
|
|
if( !gluCheckExtension( (const GLubyte *)"GL_EXT_framebuffer_object", glGetString( GL_EXTENSIONS ) ) )
|
|
{
|
|
log_info( "Renderbuffers are not supported by this OpenGL implementation; skipping test\n" );
|
|
return 0;
|
|
}
|
|
|
|
// Loop through a set of GL formats, testing a set of sizes against each one
|
|
for( fmtIdx = 0; fmtIdx < sizeof( formats ) / sizeof( formats[ 0 ] ); fmtIdx++ )
|
|
{
|
|
for( attIdx = 0; attIdx < sizeof( attachments ) / sizeof( attachments[ 0 ] ); attIdx++ )
|
|
{
|
|
size_t i;
|
|
|
|
log_info( "Testing renderbuffer read for %s : %s : %s : %s\n",
|
|
GetGLAttachmentName( attachments[ attIdx ] ),
|
|
GetGLFormatName( formats[ fmtIdx ].internal ),
|
|
GetGLBaseFormatName( formats[ fmtIdx ].format ),
|
|
GetGLTypeName( formats[ fmtIdx ].datatype ) );
|
|
|
|
for( i = 0; i < iter; i++ )
|
|
{
|
|
GLsizei width = random_in_range( 16, 512, seed );
|
|
GLsizei height = random_in_range( 16, 512, seed );
|
|
#ifdef DEBUG
|
|
width = height = 4;
|
|
#endif
|
|
|
|
if( test_renderbuffer_read_image( context, queue, width, height,
|
|
attachments[ attIdx ],
|
|
formats[ fmtIdx ].format,
|
|
formats[ fmtIdx ].internal,
|
|
formats[ fmtIdx ].datatype,
|
|
formats[ fmtIdx ].type, seed ) )
|
|
|
|
{
|
|
log_error( "ERROR: Renderbuffer read test failed for %s : %s : %s : %s\n\n",
|
|
GetGLAttachmentName( attachments[ attIdx ] ),
|
|
GetGLFormatName( formats[ fmtIdx ].internal ),
|
|
GetGLBaseFormatName( formats[ fmtIdx ].format ),
|
|
GetGLTypeName( formats[ fmtIdx ].datatype ) );
|
|
|
|
error++;
|
|
break; // Skip other sizes for this combination
|
|
}
|
|
}
|
|
if( i == iter )
|
|
{
|
|
log_info( "passed: Renderbuffer read test passed for %s : %s : %s : %s\n\n",
|
|
GetGLAttachmentName( attachments[ attIdx ] ),
|
|
GetGLFormatName( formats[ fmtIdx ].internal ),
|
|
GetGLBaseFormatName( formats[ fmtIdx ].format ),
|
|
GetGLTypeName( formats[ fmtIdx ].datatype ) );
|
|
}
|
|
}
|
|
}
|
|
|
|
return error;
|
|
}
|
|
|
|
|
|
#pragma mark -------------------- Write tests -------------------------
|
|
|
|
int test_attach_renderbuffer_write_to_image( cl_context context, cl_command_queue queue, GLenum glTarget, GLuint glRenderbuffer,
|
|
size_t imageWidth, size_t imageHeight, cl_image_format *outFormat, ExplicitType *outType, MTdata d, void **outSourceBuffer, bool supports_half )
|
|
{
|
|
int error;
|
|
|
|
// Create a CL image from the supplied GL renderbuffer
|
|
clMemWrapper image = (*clCreateFromGLRenderbuffer_ptr)( context, CL_MEM_WRITE_ONLY, glRenderbuffer, &error );
|
|
if( error != CL_SUCCESS )
|
|
{
|
|
print_error( error, "Unable to create CL image from GL renderbuffer" );
|
|
return error;
|
|
}
|
|
|
|
return test_cl_image_write( context, queue, glTarget, image, imageWidth,
|
|
imageHeight, 1, outFormat, outType, outSourceBuffer, d, supports_half );
|
|
}
|
|
|
|
int test_renderbuffer_image_write( cl_context context, cl_command_queue queue,
|
|
GLsizei width, GLsizei height, GLenum attachment,
|
|
GLenum format, GLenum internalFormat,
|
|
GLenum glType, ExplicitType type, MTdata d )
|
|
{
|
|
int error;
|
|
|
|
if( type == kHalf )
|
|
if( DetectFloatToHalfRoundingMode(queue) )
|
|
return 1;
|
|
|
|
// Create the GL renderbuffer
|
|
glFramebufferWrapper glFramebuffer;
|
|
glRenderbufferWrapper glRenderbuffer;
|
|
CreateGLRenderbuffer( width, height, attachment, format, internalFormat, glType, type, &glFramebuffer, &glRenderbuffer, &error, d, false );
|
|
if( error != 0 )
|
|
{
|
|
if ((format == GL_RGBA_INTEGER_EXT) && (!CheckGLIntegerExtensionSupport()))
|
|
{
|
|
log_info("OpenGL version does not support GL_RGBA_INTEGER_EXT. Skipping test.\n");
|
|
return 0;
|
|
}
|
|
else
|
|
{
|
|
return error;
|
|
}
|
|
}
|
|
|
|
// Run and get the results
|
|
cl_image_format clFormat;
|
|
ExplicitType sourceType;
|
|
ExplicitType validationType;
|
|
void *outSourceBuffer;
|
|
|
|
bool supports_half = false;
|
|
error = supportsHalf(context, &supports_half);
|
|
if( error != 0 )
|
|
return error;
|
|
|
|
error = test_attach_renderbuffer_write_to_image( context, queue, attachment, glRenderbuffer, width, height, &clFormat, &sourceType, d, (void **)&outSourceBuffer, supports_half );
|
|
if( error != 0 || ((sourceType == kHalf ) && !supports_half))
|
|
return error;
|
|
|
|
// If actual source type was half, convert to float for validation.
|
|
if( sourceType == kHalf )
|
|
validationType = kFloat;
|
|
else
|
|
validationType = sourceType;
|
|
|
|
BufferOwningPtr<char> validationSource( convert_to_expected( outSourceBuffer, width * height, sourceType, validationType ) );
|
|
|
|
log_info( "- Write [%4d x %4d] : GL Renderbuffer : %s : %s : %s => CL Image : %s : %s \n", width, height,
|
|
GetGLFormatName( format ), GetGLFormatName( internalFormat ), GetGLTypeName( glType),
|
|
GetChannelOrderName( clFormat.image_channel_order ), GetChannelTypeName( clFormat.image_channel_data_type ));
|
|
|
|
// Now read the results from the GL renderbuffer
|
|
BufferOwningPtr<char> resultData( ReadGLRenderbuffer( glFramebuffer, glRenderbuffer, attachment, format, internalFormat, glType, type, width, height ) );
|
|
|
|
#ifdef DEBUG
|
|
log_info("- start result data -- \n");
|
|
DumpGLBuffer(glType, width, height, resultData);
|
|
log_info("- end result data -- \n");
|
|
#endif
|
|
|
|
// We have to convert our input buffer to the returned type, so we can validate.
|
|
BufferOwningPtr<char> convertedData( convert_to_expected( resultData, width * height, type, validationType ) );
|
|
|
|
#ifdef DEBUG
|
|
log_info("- start input data -- \n");
|
|
DumpGLBuffer(GetGLTypeForExplicitType(validationType), width, height, validationSource);
|
|
log_info("- end input data -- \n");
|
|
#endif
|
|
|
|
#ifdef DEBUG
|
|
log_info("- start converted data -- \n");
|
|
DumpGLBuffer(GetGLTypeForExplicitType(validationType), width, height, convertedData);
|
|
log_info("- end converted data -- \n");
|
|
#endif
|
|
|
|
// Now we validate
|
|
int valid = 0;
|
|
if(convertedData) {
|
|
if( sourceType == kFloat || sourceType == kHalf )
|
|
valid = validate_float_results( validationSource, convertedData, width, height );
|
|
else
|
|
valid = validate_integer_results( validationSource, convertedData, width, height, get_explicit_type_size( type ) );
|
|
}
|
|
|
|
return valid;
|
|
}
|
|
|
|
int test_renderbuffer_write( cl_device_id device, cl_context context, cl_command_queue queue, int numElements )
|
|
{
|
|
GLenum attachments[] = { GL_COLOR_ATTACHMENT0_EXT };
|
|
|
|
struct {
|
|
GLenum internal;
|
|
GLenum format;
|
|
GLenum datatype;
|
|
ExplicitType type;
|
|
|
|
} formats[] = {
|
|
{ GL_RGBA, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, kUChar },
|
|
{ GL_RGBA, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, kUChar },
|
|
{ GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, kUChar },
|
|
{ GL_RGBA16, GL_RGBA, GL_UNSIGNED_SHORT, kUShort },
|
|
|
|
// Renderbuffers with integer formats do not seem to work reliably across
|
|
// platforms/implementations. Disabling this in version 1.0 of CL conformance tests.
|
|
|
|
#ifdef TEST_INTEGER_FORMATS
|
|
|
|
{ GL_RGBA8I_EXT, GL_RGBA_INTEGER_EXT, GL_BYTE, kChar },
|
|
{ GL_RGBA16I_EXT, GL_RGBA_INTEGER_EXT, GL_SHORT, kShort },
|
|
{ GL_RGBA32I_EXT, GL_RGBA_INTEGER_EXT, GL_INT, kInt },
|
|
{ GL_RGBA8UI_EXT, GL_RGBA_INTEGER_EXT, GL_UNSIGNED_BYTE, kUChar },
|
|
{ GL_RGBA16UI_EXT, GL_RGBA_INTEGER_EXT, GL_UNSIGNED_SHORT, kUShort },
|
|
{ GL_RGBA32UI_EXT, GL_RGBA_INTEGER_EXT, GL_UNSIGNED_INT, kUInt },
|
|
#endif
|
|
{ GL_RGBA32F_ARB, GL_RGBA, GL_FLOAT, kFloat },
|
|
{ GL_RGBA16F_ARB, GL_RGBA, GL_HALF_FLOAT, kHalf }
|
|
};
|
|
|
|
size_t fmtIdx, attIdx;
|
|
int error = 0;
|
|
size_t iter = 6;
|
|
#ifdef DEBUG
|
|
iter = 1;
|
|
#endif
|
|
RandomSeed seed( gRandomSeed );
|
|
|
|
// Check if images are supported
|
|
if (checkForImageSupport(device)) {
|
|
log_info("Device does not support images. Skipping test.\n");
|
|
return 0;
|
|
}
|
|
|
|
if( !gluCheckExtension( (const GLubyte *)"GL_EXT_framebuffer_object", glGetString( GL_EXTENSIONS ) ) )
|
|
{
|
|
log_info( "Renderbuffers are not supported by this OpenGL implementation; skipping test\n" );
|
|
return 0;
|
|
}
|
|
|
|
// Loop through a set of GL formats, testing a set of sizes against each one
|
|
for( fmtIdx = 0; fmtIdx < sizeof( formats ) / sizeof( formats[ 0 ] ); fmtIdx++ )
|
|
{
|
|
for( attIdx = 0; attIdx < sizeof( attachments ) / sizeof( attachments[ 0 ] ); attIdx++ )
|
|
{
|
|
log_info( "Testing Renderbuffer write test for %s : %s : %s : %s\n",
|
|
GetGLAttachmentName( attachments[ attIdx ] ),
|
|
GetGLFormatName( formats[ fmtIdx ].internal ),
|
|
GetGLBaseFormatName( formats[ fmtIdx ].format ),
|
|
GetGLTypeName( formats[ fmtIdx ].datatype ) );
|
|
|
|
size_t i;
|
|
for( i = 0; i < iter; i++ )
|
|
{
|
|
GLsizei width = random_in_range( 16, 512, seed );
|
|
GLsizei height = random_in_range( 16, 512, seed );
|
|
#ifdef DEBUG
|
|
width = height = 4;
|
|
#endif
|
|
|
|
if( test_renderbuffer_image_write( context, queue, width, height,
|
|
attachments[ attIdx ],
|
|
formats[ fmtIdx ].format,
|
|
formats[ fmtIdx ].internal,
|
|
formats[ fmtIdx ].datatype,
|
|
formats[ fmtIdx ].type, seed ) )
|
|
{
|
|
log_error( "ERROR: Renderbuffer write test failed for %s : %s : %s : %s\n\n",
|
|
GetGLAttachmentName( attachments[ attIdx ] ),
|
|
GetGLFormatName( formats[ fmtIdx ].internal ),
|
|
GetGLBaseFormatName( formats[ fmtIdx ].format ),
|
|
GetGLTypeName( formats[ fmtIdx ].datatype ) );
|
|
|
|
error++;
|
|
break; // Skip other sizes for this combination
|
|
}
|
|
}
|
|
if( i == iter )
|
|
{
|
|
log_info( "passed: Renderbuffer write test passed for %s : %s : %s : %s\n\n",
|
|
GetGLAttachmentName( attachments[ attIdx ] ),
|
|
GetGLFormatName( formats[ fmtIdx ].internal ),
|
|
GetGLBaseFormatName( formats[ fmtIdx ].format ),
|
|
GetGLTypeName( formats[ fmtIdx ].datatype ) );
|
|
}
|
|
}
|
|
}
|
|
|
|
return error;
|
|
}
|