mirror of
https://github.com/KhronosGroup/OpenCL-CTS.git
synced 2026-03-19 06:09:01 +00:00
Initial open source release of OpenCL 2.2 CTS.
This commit is contained in:
34
test_conformance/gles/CMakeLists.txt
Normal file
34
test_conformance/gles/CMakeLists.txt
Normal file
@@ -0,0 +1,34 @@
|
||||
set (MODULE_NAME GLES)
|
||||
|
||||
set (${MODULE_NAME}_SOURCES
|
||||
main.cpp
|
||||
test_buffers.cpp
|
||||
test_images_2D.cpp
|
||||
test_images_3D.cpp
|
||||
test_renderbuffer.cpp
|
||||
test_images_2D_info.cpp
|
||||
test_images_3D_info.cpp
|
||||
test_renderbuffer_info.cpp
|
||||
test_fence_sync.cpp
|
||||
helpers.cpp
|
||||
setup_egl.cpp
|
||||
../../test_common/gles/helpers.cpp
|
||||
../../test_common/harness/genericThread.cpp
|
||||
../../test_common/harness/errorHelpers.c
|
||||
../../test_common/harness/threadTesting.c
|
||||
../../test_common/harness/testHarness.c
|
||||
../../test_common/harness/kernelHelpers.c
|
||||
../../test_common/harness/mt19937.c
|
||||
../../test_common/harness/conversions.c
|
||||
../../test_common/harness/msvc9.c
|
||||
../../test_common/harness/parseParameters.cpp
|
||||
)
|
||||
|
||||
if(ANDROID)
|
||||
list(APPEND CLConform_LIBRARIES GLESv2)
|
||||
elseif(WIN32)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DGLES3")
|
||||
list(APPEND CLConform_LIBRARIES libEGL libGLESv2 )
|
||||
endif(ANDROID)
|
||||
|
||||
include(../CMakeCommon.txt)
|
||||
481
test_conformance/gles/helpers.cpp
Normal file
481
test_conformance/gles/helpers.cpp
Normal file
@@ -0,0 +1,481 @@
|
||||
//
|
||||
// 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 "gl_headers.h"
|
||||
|
||||
const char *get_kernel_suffix( cl_image_format *format )
|
||||
{
|
||||
switch( format->image_channel_data_type )
|
||||
{
|
||||
case CL_UNORM_INT8:
|
||||
case CL_UNORM_INT16:
|
||||
case CL_SNORM_INT8:
|
||||
case CL_SNORM_INT16:
|
||||
case CL_FLOAT:
|
||||
return "f";
|
||||
case CL_HALF_FLOAT:
|
||||
return "h";
|
||||
case CL_SIGNED_INT8:
|
||||
case CL_SIGNED_INT16:
|
||||
case CL_SIGNED_INT32:
|
||||
return "i";
|
||||
case CL_UNSIGNED_INT8:
|
||||
case CL_UNSIGNED_INT16:
|
||||
case CL_UNSIGNED_INT32:
|
||||
return "ui";
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
ExplicitType get_read_kernel_type( cl_image_format *format )
|
||||
{
|
||||
switch( format->image_channel_data_type )
|
||||
{
|
||||
case CL_UNORM_INT8:
|
||||
case CL_UNORM_INT16:
|
||||
case CL_SNORM_INT8:
|
||||
case CL_SNORM_INT16:
|
||||
case CL_FLOAT:
|
||||
return kFloat;
|
||||
case CL_HALF_FLOAT:
|
||||
return kHalf;
|
||||
case CL_SIGNED_INT8:
|
||||
case CL_SIGNED_INT16:
|
||||
case CL_SIGNED_INT32:
|
||||
return kInt;
|
||||
case CL_UNSIGNED_INT8:
|
||||
case CL_UNSIGNED_INT16:
|
||||
case CL_UNSIGNED_INT32:
|
||||
return kUInt;
|
||||
default:
|
||||
return kInt;
|
||||
}
|
||||
}
|
||||
|
||||
ExplicitType get_write_kernel_type( cl_image_format *format )
|
||||
{
|
||||
switch( format->image_channel_data_type )
|
||||
{
|
||||
case CL_UNORM_INT8:
|
||||
return kFloat;
|
||||
case CL_UNORM_INT16:
|
||||
return kFloat;
|
||||
case CL_SNORM_INT8:
|
||||
return kFloat;
|
||||
case CL_SNORM_INT16:
|
||||
return kFloat;
|
||||
case CL_HALF_FLOAT:
|
||||
return kHalf;
|
||||
case CL_FLOAT:
|
||||
return kFloat;
|
||||
case CL_SIGNED_INT8:
|
||||
return kChar;
|
||||
case CL_SIGNED_INT16:
|
||||
return kShort;
|
||||
case CL_SIGNED_INT32:
|
||||
return kInt;
|
||||
case CL_UNSIGNED_INT8:
|
||||
return kUChar;
|
||||
case CL_UNSIGNED_INT16:
|
||||
return kUShort;
|
||||
case CL_UNSIGNED_INT32:
|
||||
return kUInt;
|
||||
default:
|
||||
return kInt;
|
||||
}
|
||||
}
|
||||
|
||||
const char* get_write_conversion( cl_image_format *format, ExplicitType type )
|
||||
{
|
||||
switch( format->image_channel_data_type )
|
||||
{
|
||||
case CL_UNORM_INT8:
|
||||
case CL_UNORM_INT16:
|
||||
case CL_SNORM_INT8:
|
||||
case CL_SNORM_INT16:
|
||||
case CL_FLOAT:
|
||||
if(type != kFloat) return "convert_float4";
|
||||
break;
|
||||
case CL_HALF_FLOAT:
|
||||
break;
|
||||
case CL_SIGNED_INT8:
|
||||
case CL_SIGNED_INT16:
|
||||
case CL_SIGNED_INT32:
|
||||
if(type != kInt) return "convert_int4";
|
||||
break;
|
||||
case CL_UNSIGNED_INT8:
|
||||
case CL_UNSIGNED_INT16:
|
||||
case CL_UNSIGNED_INT32:
|
||||
if(type != kUInt) return "convert_uint4";
|
||||
break;
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
// The only three input types to this function are kInt, kUInt and kFloat, due to the way we set up our tests
|
||||
// The output types, though, are pretty much anything valid for GL to receive
|
||||
|
||||
#define DOWNSCALE_INTEGER_CASE( enum, type, bitShift ) \
|
||||
case enum: \
|
||||
{ \
|
||||
cl_##type *dst = new cl_##type[ numPixels * 4 ]; \
|
||||
for( size_t i = 0; i < numPixels * 4; i++ ) \
|
||||
dst[ i ] = src[ i ]; \
|
||||
return (char *)dst; \
|
||||
}
|
||||
|
||||
#define UPSCALE_FLOAT_CASE( enum, type, typeMax ) \
|
||||
case enum: \
|
||||
{ \
|
||||
cl_##type *dst = new cl_##type[ numPixels * 4 ]; \
|
||||
for( size_t i = 0; i < numPixels * 4; i++ ) \
|
||||
dst[ i ] = (cl_##type)( src[ i ] * typeMax ); \
|
||||
return (char *)dst; \
|
||||
}
|
||||
|
||||
char * convert_to_expected( void * inputBuffer, size_t numPixels, ExplicitType inType, ExplicitType outType )
|
||||
{
|
||||
#ifdef GLES_DEBUG
|
||||
log_info( "- Converting from input type '%s' to output type '%s'\n",
|
||||
get_explicit_type_name( inType ), get_explicit_type_name( outType ) );
|
||||
#endif
|
||||
|
||||
if( inType == outType )
|
||||
{
|
||||
char *outData = new char[ numPixels * 4 * get_explicit_type_size(outType) ] ; // sizeof( cl_int ) ];
|
||||
memcpy( outData, inputBuffer, numPixels * 4 * get_explicit_type_size(inType) );
|
||||
return outData;
|
||||
}
|
||||
else if( inType == kChar )
|
||||
{
|
||||
cl_char *src = (cl_char *)inputBuffer;
|
||||
|
||||
switch( outType )
|
||||
{
|
||||
case kInt:
|
||||
{
|
||||
cl_int *outData = new cl_int[ numPixels * 4 ];
|
||||
for( size_t i = 0; i < numPixels * 4; i++ )
|
||||
{
|
||||
outData[ i ] = (cl_int)((src[ i ]));
|
||||
}
|
||||
return (char *)outData;
|
||||
}
|
||||
case kFloat:
|
||||
{
|
||||
// If we're converting to float, then CL decided that we should be normalized
|
||||
cl_float *outData = new cl_float[ numPixels * 4 ];
|
||||
for( size_t i = 0; i < numPixels * 4; i++ )
|
||||
{
|
||||
outData[ i ] = (cl_float)src[ i ] / 127.0f;
|
||||
}
|
||||
return (char *)outData;
|
||||
}
|
||||
default:
|
||||
log_error( "ERROR: Unsupported conversion from %s to %s!\n", get_explicit_type_name( inType ), get_explicit_type_name( outType ) );
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
else if( inType == kUChar )
|
||||
{
|
||||
cl_uchar *src = (cl_uchar *)inputBuffer;
|
||||
|
||||
switch( outType )
|
||||
{
|
||||
case kUInt:
|
||||
{
|
||||
cl_uint *outData = new cl_uint[ numPixels * 4 ];
|
||||
for( size_t i = 0; i < numPixels * 4; i++ )
|
||||
{
|
||||
outData[ i ] = (cl_uint)((src[ i ]));
|
||||
}
|
||||
return (char *)outData;
|
||||
}
|
||||
case kFloat:
|
||||
{
|
||||
// If we're converting to float, then CL decided that we should be normalized
|
||||
cl_float *outData = new cl_float[ numPixels * 4 ];
|
||||
for( size_t i = 0; i < numPixels * 4; i++ )
|
||||
{
|
||||
outData[ i ] = (cl_float)(src[ i ]) / 256.0f;
|
||||
}
|
||||
return (char *)outData;
|
||||
}
|
||||
default:
|
||||
log_error( "ERROR: Unsupported conversion from %s to %s!\n", get_explicit_type_name( inType ), get_explicit_type_name( outType ) );
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
else if( inType == kShort )
|
||||
{
|
||||
cl_short *src = (cl_short *)inputBuffer;
|
||||
|
||||
switch( outType )
|
||||
{
|
||||
case kInt:
|
||||
{
|
||||
cl_int *outData = new cl_int[ numPixels * 4 ];
|
||||
for( size_t i = 0; i < numPixels * 4; i++ )
|
||||
{
|
||||
outData[ i ] = (cl_int)((src[ i ]));
|
||||
}
|
||||
return (char *)outData;
|
||||
}
|
||||
case kFloat:
|
||||
{
|
||||
// If we're converting to float, then CL decided that we should be normalized
|
||||
cl_float *outData = new cl_float[ numPixels * 4 ];
|
||||
for( size_t i = 0; i < numPixels * 4; i++ )
|
||||
{
|
||||
outData[ i ] = (cl_float)src[ i ] / 32768.0f;
|
||||
}
|
||||
return (char *)outData;
|
||||
}
|
||||
default:
|
||||
log_error( "ERROR: Unsupported conversion from %s to %s!\n", get_explicit_type_name( inType ), get_explicit_type_name( outType ) );
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
else if( inType == kUShort )
|
||||
{
|
||||
cl_ushort *src = (cl_ushort *)inputBuffer;
|
||||
|
||||
switch( outType )
|
||||
{
|
||||
case kUInt:
|
||||
{
|
||||
cl_uint *outData = new cl_uint[ numPixels * 4 ];
|
||||
for( size_t i = 0; i < numPixels * 4; i++ )
|
||||
{
|
||||
outData[ i ] = (cl_uint)((src[ i ]));
|
||||
}
|
||||
return (char *)outData;
|
||||
}
|
||||
case kFloat:
|
||||
{
|
||||
// If we're converting to float, then CL decided that we should be normalized
|
||||
cl_float *outData = new cl_float[ numPixels * 4 ];
|
||||
for( size_t i = 0; i < numPixels * 4; i++ )
|
||||
{
|
||||
outData[ i ] = (cl_float)(src[ i ]) / 65535.0f;
|
||||
}
|
||||
return (char *)outData;
|
||||
}
|
||||
default:
|
||||
log_error( "ERROR: Unsupported conversion from %s to %s!\n", get_explicit_type_name( inType ), get_explicit_type_name( outType ) );
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
else if( inType == kInt )
|
||||
{
|
||||
cl_int *src = (cl_int *)inputBuffer;
|
||||
|
||||
switch( outType )
|
||||
{
|
||||
DOWNSCALE_INTEGER_CASE( kShort, short, 16 )
|
||||
DOWNSCALE_INTEGER_CASE( kChar, char, 24 )
|
||||
case kFloat:
|
||||
{
|
||||
// If we're converting to float, then CL decided that we should be normalized
|
||||
cl_float *outData = new cl_float[ numPixels * 4 ];
|
||||
for( size_t i = 0; i < numPixels * 4; i++ )
|
||||
{
|
||||
outData[ i ] = (cl_float)fmaxf( (float)src[ i ] / 2147483647.f, -1.f );
|
||||
}
|
||||
return (char *)outData;
|
||||
}
|
||||
default:
|
||||
log_error( "ERROR: Unsupported conversion from %s to %s!\n", get_explicit_type_name( inType ), get_explicit_type_name( outType ) );
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
else if( inType == kUInt )
|
||||
{
|
||||
cl_uint *src = (cl_uint *)inputBuffer;
|
||||
|
||||
switch( outType )
|
||||
{
|
||||
DOWNSCALE_INTEGER_CASE( kUShort, ushort, 16 )
|
||||
DOWNSCALE_INTEGER_CASE( kUChar, uchar, 24 )
|
||||
case kFloat:
|
||||
{
|
||||
// If we're converting to float, then CL decided that we should be normalized
|
||||
cl_float *outData = new cl_float[ numPixels * 4 ];
|
||||
for( size_t i = 0; i < numPixels * 4; i++ )
|
||||
{
|
||||
outData[ i ] = (cl_float)src[ i ] / 4294967295.f;
|
||||
}
|
||||
return (char *)outData;
|
||||
}
|
||||
default:
|
||||
log_error( "ERROR: Unsupported conversion from %s to %s!\n", get_explicit_type_name( inType ), get_explicit_type_name( outType ) );
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
cl_float *src = (cl_float *)inputBuffer;
|
||||
|
||||
switch( outType )
|
||||
{
|
||||
UPSCALE_FLOAT_CASE( kChar, char, 127.f )
|
||||
UPSCALE_FLOAT_CASE( kUChar, uchar, 255.f )
|
||||
UPSCALE_FLOAT_CASE( kShort, short, 32767.f )
|
||||
UPSCALE_FLOAT_CASE( kUShort, ushort, 65535.f )
|
||||
UPSCALE_FLOAT_CASE( kInt, int, 2147483647.f )
|
||||
UPSCALE_FLOAT_CASE( kUInt, uint, 4294967295.f )
|
||||
default:
|
||||
log_error( "ERROR: Unsupported conversion from %s to %s!\n", get_explicit_type_name( inType ), get_explicit_type_name( outType ) );
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int validate_integer_results( void *expectedResults, void *actualResults, size_t width, size_t height, size_t typeSize )
|
||||
{
|
||||
return validate_integer_results( expectedResults, actualResults, width, height, 0, typeSize );
|
||||
}
|
||||
|
||||
int validate_integer_results( void *expectedResults, void *actualResults, size_t width, size_t height, size_t depth, size_t typeSize )
|
||||
{
|
||||
char *expected = (char *)expectedResults;
|
||||
char *actual = (char *)actualResults;
|
||||
for( size_t z = 0; z < ( ( depth == 0 ) ? 1 : depth ); z++ )
|
||||
{
|
||||
for( size_t y = 0; y < height; y++ )
|
||||
{
|
||||
for( size_t x = 0; x < width; x++ )
|
||||
{
|
||||
if( memcmp( expected, actual, typeSize * 4 ) != 0 )
|
||||
{
|
||||
char scratch[ 1024 ];
|
||||
|
||||
if( depth == 0 )
|
||||
log_error( "ERROR: Data sample %d,%d did not validate!\n", (int)x, (int)y );
|
||||
else
|
||||
log_error( "ERROR: Data sample %d,%d,%d did not validate!\n", (int)x, (int)y, (int)z );
|
||||
log_error( "\tExpected: %s\n", GetDataVectorString( expected, typeSize, 4, scratch ) );
|
||||
log_error( "\t Actual: %s\n", GetDataVectorString( actual, typeSize, 4, scratch ) );
|
||||
return -1;
|
||||
}
|
||||
expected += typeSize * 4;
|
||||
actual += typeSize * 4;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int validate_float_results( void *expectedResults, void *actualResults, size_t width, size_t height )
|
||||
{
|
||||
return validate_float_results( expectedResults, actualResults, width, height, 0 );
|
||||
}
|
||||
|
||||
int validate_float_results( void *expectedResults, void *actualResults, size_t width, size_t height, size_t depth )
|
||||
{
|
||||
cl_float *expected = (cl_float *)expectedResults;
|
||||
cl_float *actual = (cl_float *)actualResults;
|
||||
for( size_t z = 0; z < ( ( depth == 0 ) ? 1 : depth ); z++ )
|
||||
{
|
||||
for( size_t y = 0; y < height; y++ )
|
||||
{
|
||||
for( size_t x = 0; x < width; x++ )
|
||||
{
|
||||
float err = 0.f;
|
||||
for( size_t i = 0; i < 4; i++ )
|
||||
{
|
||||
float error = fabsf( expected[ i ] - actual[ i ] );
|
||||
if( error > err )
|
||||
err = error;
|
||||
}
|
||||
|
||||
if( err > 1.f / 127.f ) // Max expected range of error if we converted from an 8-bit integer to a normalized float
|
||||
{
|
||||
if( depth == 0 )
|
||||
log_error( "ERROR: Data sample %d,%d did not validate!\n", (int)x, (int)y );
|
||||
else
|
||||
log_error( "ERROR: Data sample %d,%d,%d did not validate!\n", (int)x, (int)y, (int)z );
|
||||
log_error( "\tExpected: %f %f %f %f\n", expected[ 0 ], expected[ 1 ], expected[ 2 ], expected[ 3 ] );
|
||||
log_error( "\t : %a %a %a %a\n", expected[ 0 ], expected[ 1 ], expected[ 2 ], expected[ 3 ] );
|
||||
log_error( "\t Actual: %f %f %f %f\n", actual[ 0 ], actual[ 1 ], actual[ 2 ], actual[ 3 ] );
|
||||
log_error( "\t : %a %a %a %a\n", actual[ 0 ], actual[ 1 ], actual[ 2 ], actual[ 3 ] );
|
||||
return -1;
|
||||
}
|
||||
expected += 4;
|
||||
actual += 4;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int CheckGLObjectInfo(cl_mem mem, cl_gl_object_type expected_cl_gl_type, GLuint expected_gl_name,
|
||||
GLenum expected_cl_gl_texture_target, GLint expected_cl_gl_mipmap_level)
|
||||
{
|
||||
cl_gl_object_type object_type;
|
||||
GLuint object_name;
|
||||
GLenum texture_target;
|
||||
GLint mipmap_level;
|
||||
int error;
|
||||
|
||||
error = (*clGetGLObjectInfo_ptr)(mem, &object_type, &object_name);
|
||||
test_error( error, "clGetGLObjectInfo failed");
|
||||
if (object_type != expected_cl_gl_type) {
|
||||
log_error("clGetGLObjectInfo did not return expected object type: expected %d, got %d.\n", expected_cl_gl_type, object_type);
|
||||
return -1;
|
||||
}
|
||||
if (object_name != expected_gl_name) {
|
||||
log_error("clGetGLObjectInfo did not return expected object name: expected %d, got %d.\n", expected_gl_name, object_name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (object_type == CL_GL_OBJECT_TEXTURE2D || object_type == CL_GL_OBJECT_TEXTURE3D) {
|
||||
error = (*clGetGLTextureInfo_ptr)(mem, CL_GL_TEXTURE_TARGET, sizeof(texture_target), &texture_target, NULL);
|
||||
test_error( error, "clGetGLTextureInfo for CL_GL_TEXTURE_TARGET failed");
|
||||
|
||||
if (texture_target != expected_cl_gl_texture_target) {
|
||||
log_error("clGetGLTextureInfo did not return expected texture target: expected %d, got %d.\n", expected_cl_gl_texture_target, texture_target);
|
||||
return -1;
|
||||
}
|
||||
|
||||
error = (*clGetGLTextureInfo_ptr)(mem, CL_GL_MIPMAP_LEVEL, sizeof(mipmap_level), &mipmap_level, NULL);
|
||||
test_error( error, "clGetGLTextureInfo for CL_GL_MIPMAP_LEVEL failed");
|
||||
|
||||
if (mipmap_level != expected_cl_gl_mipmap_level) {
|
||||
log_error("clGetGLTextureInfo did not return expected mipmap level: expected %d, got %d.\n", expected_cl_gl_mipmap_level, mipmap_level);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool CheckGLIntegerExtensionSupport()
|
||||
{
|
||||
// Get the OpenGL version and supported extensions
|
||||
const GLubyte *glVersion = glGetString(GL_VERSION);
|
||||
const GLubyte *glExtensionList = glGetString(GL_EXTENSIONS);
|
||||
|
||||
// Check if the OpenGL vrsion is 3.0 or grater or GL_EXT_texture_integer is supported
|
||||
return (((glVersion[0] - '0') >= 3) || (strstr((const char*)glExtensionList, "GL_EXT_texture_integer")));
|
||||
}
|
||||
402
test_conformance/gles/main.cpp
Normal file
402
test_conformance/gles/main.cpp
Normal file
@@ -0,0 +1,402 @@
|
||||
//
|
||||
// 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 <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#if !defined(_WIN32)
|
||||
#include <stdbool.h>
|
||||
#endif
|
||||
|
||||
#include <math.h>
|
||||
#include <string.h>
|
||||
|
||||
#if !defined (__APPLE__)
|
||||
#include <CL/cl.h>
|
||||
#endif
|
||||
|
||||
#include "procs.h"
|
||||
#include "../../test_common/gles/setup.h"
|
||||
#include "../../test_common/harness/testHarness.h"
|
||||
|
||||
#if !defined(_WIN32)
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
static cl_context sCurrentContext = NULL;
|
||||
|
||||
|
||||
#define TEST_FN_REDIRECT( fn ) redirect_##fn
|
||||
#define TEST_FN_REDIRECTOR( fn ) \
|
||||
int redirect_##fn(cl_device_id device, cl_context context, cl_command_queue queue, int numElements ) \
|
||||
{ \
|
||||
int error; \
|
||||
clCommandQueueWrapper realQueue = clCreateCommandQueue( sCurrentContext, device, 0, &error ); \
|
||||
test_error( error, "Unable to create command queue" ); \
|
||||
return fn( device, sCurrentContext, realQueue, numElements ); \
|
||||
}
|
||||
|
||||
TEST_FN_REDIRECTOR( test_buffers )
|
||||
TEST_FN_REDIRECTOR( test_buffers_getinfo )
|
||||
TEST_FN_REDIRECTOR( test_images_read )
|
||||
TEST_FN_REDIRECTOR( test_images_2D_getinfo )
|
||||
TEST_FN_REDIRECTOR( test_images_read_cube )
|
||||
TEST_FN_REDIRECTOR( test_images_cube_getinfo )
|
||||
TEST_FN_REDIRECTOR( test_images_read_3D )
|
||||
TEST_FN_REDIRECTOR( test_images_3D_getinfo )
|
||||
TEST_FN_REDIRECTOR( test_images_write )
|
||||
TEST_FN_REDIRECTOR( test_images_write_cube )
|
||||
TEST_FN_REDIRECTOR( test_renderbuffer_read )
|
||||
TEST_FN_REDIRECTOR( test_renderbuffer_write )
|
||||
TEST_FN_REDIRECTOR( test_renderbuffer_getinfo )
|
||||
|
||||
#ifndef GL_ES_VERSION_2_0
|
||||
TEST_FN_REDIRECTOR( test_fence_sync )
|
||||
#endif
|
||||
|
||||
basefn basefn_list[] = {
|
||||
TEST_FN_REDIRECT( test_buffers ),
|
||||
TEST_FN_REDIRECT( test_buffers_getinfo ),
|
||||
TEST_FN_REDIRECT( test_images_read ),
|
||||
TEST_FN_REDIRECT( test_images_2D_getinfo ),
|
||||
TEST_FN_REDIRECT( test_images_read_cube ),
|
||||
TEST_FN_REDIRECT( test_images_cube_getinfo ),
|
||||
TEST_FN_REDIRECT( test_images_read_3D ),
|
||||
TEST_FN_REDIRECT( test_images_3D_getinfo ),
|
||||
TEST_FN_REDIRECT( test_images_write ),
|
||||
TEST_FN_REDIRECT( test_images_write_cube ),
|
||||
TEST_FN_REDIRECT( test_renderbuffer_read ),
|
||||
TEST_FN_REDIRECT( test_renderbuffer_write ),
|
||||
TEST_FN_REDIRECT( test_renderbuffer_getinfo )
|
||||
};
|
||||
|
||||
#ifndef GL_ES_VERSION_2_0
|
||||
basefn basefn_list32[] = {
|
||||
TEST_FN_REDIRECT( test_fence_sync )
|
||||
};
|
||||
#endif
|
||||
|
||||
const char *basefn_names[] = {
|
||||
"buffers",
|
||||
"buffers_getinfo",
|
||||
"images_read",
|
||||
"images_2D_getinfo",
|
||||
"images_read_cube",
|
||||
"images_cube_getinfo",
|
||||
"images_read_3D",
|
||||
"images_3D_getinfo",
|
||||
"images_write",
|
||||
"images_write_cube",
|
||||
"renderbuffer_read",
|
||||
"renderbuffer_write",
|
||||
"renderbuffer_getinfo",
|
||||
"all"
|
||||
};
|
||||
|
||||
const char *basefn_names32[] = {
|
||||
"fence_sync",
|
||||
"all"
|
||||
};
|
||||
|
||||
ct_assert((sizeof(basefn_names) / sizeof(basefn_names[0]) - 1) == (sizeof(basefn_list) / sizeof(basefn_list[0])));
|
||||
|
||||
int num_fns = sizeof(basefn_names) / sizeof(char *);
|
||||
int num_fns32 = sizeof(basefn_names32) / sizeof(char *);
|
||||
|
||||
|
||||
int main(int argc, const char *argv[])
|
||||
{
|
||||
int error = 0;
|
||||
cl_platform_id platform_id = NULL;
|
||||
/* To keep it simple, use a static allocation of 32 argv pointers.
|
||||
argc is not expected to go beyond 32 */
|
||||
const char* argv_tmp[32] = {0};
|
||||
int argc_tmp = 0;
|
||||
|
||||
test_start();
|
||||
|
||||
cl_device_type requestedDeviceType = CL_DEVICE_TYPE_DEFAULT;
|
||||
|
||||
for(int z = 1; z < argc; ++z)
|
||||
{//for
|
||||
if(strcmp( argv[ z ], "-list" ) == 0 )
|
||||
{
|
||||
log_info( "Available 2.x tests:\n" );
|
||||
for( int i = 0; i < num_fns - 1; i++ )
|
||||
log_info( "\t%s\n", basefn_names[ i ] );
|
||||
|
||||
log_info( "Available 3.2 tests:\n" );
|
||||
for( int i = 0; i < num_fns32 - 1; i++ )
|
||||
log_info( "\t%s\n", basefn_names32[ i ] );
|
||||
|
||||
log_info( "Note: Any 3.2 test names must follow 2.1 test names on the command line." );
|
||||
log_info( "Use environment variables to specify desired device." );
|
||||
|
||||
test_finish();
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* support requested device type */
|
||||
if(!strcmp(argv[z], "CL_DEVICE_TYPE_GPU"))
|
||||
{
|
||||
printf("Requested device type is CL_DEVICE_TYPE_GPU\n");
|
||||
requestedDeviceType = CL_DEVICE_TYPE_GPU;
|
||||
}
|
||||
else
|
||||
if(!strcmp(argv[z], "CL_DEVICE_TYPE_CPU"))
|
||||
{
|
||||
printf("Requested device type is CL_DEVICE_TYPE_CPU\n");
|
||||
log_info("Invalid CL device type. GL tests can only run on a GPU device.\n");
|
||||
test_finish();
|
||||
return 0;
|
||||
}
|
||||
}//for
|
||||
|
||||
// Check to see if any 2.x or 3.2 test names were specified on the command line.
|
||||
unsigned first_32_testname = 0;
|
||||
|
||||
for (int j=1; (j<argc) && (!first_32_testname); ++j)
|
||||
for (int i=0;i<num_fns32-1;++i)
|
||||
if (strcmp(basefn_names32[i],argv[j])==0) {
|
||||
first_32_testname = j;
|
||||
break;
|
||||
}
|
||||
|
||||
// Create the environment for the test.
|
||||
GLEnvironment *glEnv = GLEnvironment::Instance();
|
||||
|
||||
// Check if any devices of the requested type support CL/GL interop.
|
||||
int supported = glEnv->SupportsCLGLInterop( requestedDeviceType );
|
||||
if( supported == 0 ) {
|
||||
log_info("Test not run because GL-CL interop is not supported for any devices of the requested type.\n");
|
||||
test_finish();
|
||||
error = 0;
|
||||
goto cleanup;
|
||||
} else if ( supported == -1 ) {
|
||||
log_error("Failed to determine if CL-GL interop is supported.\n");
|
||||
test_finish();
|
||||
error = -1;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
// OpenGL tests for non-3.2 ////////////////////////////////////////////////////////
|
||||
if ((argc == 1) || (first_32_testname != 1)) {
|
||||
|
||||
// At least one device supports CL-GL interop, so init the test.
|
||||
if( glEnv->Init( &argc, (char **)argv, CL_FALSE ) ) {
|
||||
log_error("Failed to initialize the GL environment for this test.\n");
|
||||
test_finish();
|
||||
error = -1;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
// Create a context to use and then grab a device (or devices) from it
|
||||
sCurrentContext = glEnv->CreateCLContext();
|
||||
if( sCurrentContext == NULL )
|
||||
{
|
||||
log_error( "ERROR: Unable to obtain CL context from GL\n" );
|
||||
test_finish();
|
||||
error = -1;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
size_t numDevices = 0;
|
||||
cl_device_id deviceIDs[ 16 ];
|
||||
|
||||
error = clGetContextInfo( sCurrentContext, CL_CONTEXT_DEVICES, 0, NULL, &numDevices);
|
||||
if( error != CL_SUCCESS )
|
||||
{
|
||||
print_error( error, "Unable to get device count from context" );
|
||||
test_finish();
|
||||
error = -1;
|
||||
goto cleanup;
|
||||
}
|
||||
numDevices /= sizeof(cl_device_id);
|
||||
|
||||
if (numDevices < 1) {
|
||||
log_error("No devices found.\n");
|
||||
test_finish();
|
||||
error = -1;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
error = clGetContextInfo( sCurrentContext, CL_CONTEXT_DEVICES, sizeof( deviceIDs ), deviceIDs, NULL);
|
||||
if( error != CL_SUCCESS ) {
|
||||
print_error( error, "Unable to get device list from context" );
|
||||
test_finish();
|
||||
error = -1;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
// Execute tests.
|
||||
int argc_ = (first_32_testname) ? first_32_testname : argc;
|
||||
|
||||
for( size_t i = 0; i < numDevices; i++ ) {
|
||||
log_info( "\nTesting OpenGL 2.x\n" );
|
||||
if( printDeviceHeader( deviceIDs[ i ] ) != CL_SUCCESS ) {
|
||||
test_finish();
|
||||
error = -1;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
error = clGetDeviceInfo(deviceIDs[ i ],
|
||||
CL_DEVICE_PLATFORM,
|
||||
sizeof(platform_id),
|
||||
&platform_id,
|
||||
NULL);
|
||||
if(error)
|
||||
{
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
error = init_clgl_ext(platform_id);
|
||||
if (error < 0)
|
||||
{
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* parseAndCallCommandLineTests considers every command line argument
|
||||
as a test name. This results in the test failing because of considering
|
||||
args such as 'CL_DEVICE_TYPE_GPU' as test names unless
|
||||
the actual test name happens to be the first argument.
|
||||
Instead of changing the behaviour of parseAndCallCommandLineTests
|
||||
modify the arguments passed to it so as to not affect other tests.
|
||||
*/
|
||||
int w = 1;
|
||||
argc_tmp= argc_;
|
||||
for(int k = 1; k < argc; k++)
|
||||
{
|
||||
if( (strcmp(argv[k], "full") == 0) ||
|
||||
(strcmp(argv[k], "CL_DEVICE_TYPE_CPU") == 0) ||
|
||||
(strcmp(argv[k], "CL_DEVICE_TYPE_GPU") == 0))
|
||||
{
|
||||
argc_tmp--;
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
argv_tmp[w++] = argv[k];
|
||||
}
|
||||
}
|
||||
|
||||
// Note: don't use the entire harness, because we have a different way of obtaining the device (via the context)
|
||||
error = parseAndCallCommandLineTests( argc_tmp, argv_tmp, deviceIDs[ i ], num_fns, basefn_list, basefn_names, true, 0, 1024 );
|
||||
if( error != 0 )
|
||||
break;
|
||||
}
|
||||
|
||||
// Clean-up.
|
||||
// We move this to a common cleanup step to make sure that things will be released properly before the test exit
|
||||
goto cleanup;
|
||||
// clReleaseContext( sCurrentContext );
|
||||
// delete glEnv;
|
||||
}
|
||||
|
||||
// OpenGL 3.2 tests. ////////////////////////////////////////////////////////
|
||||
if ((argc==1) || first_32_testname) {
|
||||
|
||||
// At least one device supports CL-GL interop, so init the test.
|
||||
if( glEnv->Init( &argc, (char **)argv, CL_TRUE ) ) {
|
||||
log_error("Failed to initialize the GL environment for this test.\n");
|
||||
test_finish();
|
||||
error = -1;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
// Create a context to use and then grab a device (or devices) from it
|
||||
sCurrentContext = glEnv->CreateCLContext();
|
||||
if( sCurrentContext == NULL ) {
|
||||
log_error( "ERROR: Unable to obtain CL context from GL\n" );
|
||||
test_finish();
|
||||
error = -1;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
size_t numDevices = 0;
|
||||
cl_device_id deviceIDs[ 16 ];
|
||||
|
||||
error = clGetContextInfo( sCurrentContext, CL_CONTEXT_DEVICES, 0, NULL, &numDevices);
|
||||
if( error != CL_SUCCESS ) {
|
||||
print_error( error, "Unable to get device count from context" );
|
||||
test_finish();
|
||||
error = -1;
|
||||
goto cleanup;
|
||||
}
|
||||
numDevices /= sizeof(cl_device_id);
|
||||
|
||||
if (numDevices < 1) {
|
||||
log_error("No devices found.\n");
|
||||
test_finish();
|
||||
error = -1;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
error = clGetContextInfo( sCurrentContext, CL_CONTEXT_DEVICES, sizeof( deviceIDs ), deviceIDs, NULL);
|
||||
if( error != CL_SUCCESS ) {
|
||||
print_error( error, "Unable to get device list from context" );
|
||||
test_finish();
|
||||
error = -1;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
int argc_ = (first_32_testname) ? 1 + (argc - first_32_testname) : argc;
|
||||
const char** argv_ = (first_32_testname) ? &argv[first_32_testname-1] : argv;
|
||||
|
||||
// Execute the tests.
|
||||
for( size_t i = 0; i < numDevices; i++ ) {
|
||||
log_info( "\nTesting OpenGL 3.2\n" );
|
||||
if( printDeviceHeader( deviceIDs[ i ] ) != CL_SUCCESS ) {
|
||||
test_finish();
|
||||
error = -1;
|
||||
goto cleanup;
|
||||
}
|
||||
#ifdef GL_ES_VERSION_2_0
|
||||
log_info("Cannot test OpenGL 3.2! This test was built for OpenGL ES 2.0\n");
|
||||
test_finish();
|
||||
error = -1;
|
||||
goto cleanup;
|
||||
#else
|
||||
// Note: don't use the entire harness, because we have a different way of obtaining the device (via the context)
|
||||
error = parseAndCallCommandLineTests( argc_, argv_, deviceIDs[ i ], num_fns32, basefn_list32, basefn_names32, true, 0, 1024 );
|
||||
if( error != 0 )
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
|
||||
// Converge on a common cleanup to make sure that things will be released properly before the test exit
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
|
||||
// cleanup CL/GL/EGL environment properly when the test exit.
|
||||
// This change does not affect any functionality of the test
|
||||
|
||||
// Intentional falling through
|
||||
cleanup:
|
||||
|
||||
// Cleanup EGL
|
||||
glEnv->terminate_egl_display();
|
||||
|
||||
// Always make sure that OpenCL context is released properly when the test exit
|
||||
if(sCurrentContext)
|
||||
{
|
||||
clReleaseContext( sCurrentContext );
|
||||
sCurrentContext = NULL;
|
||||
}
|
||||
delete glEnv;
|
||||
|
||||
|
||||
return error;
|
||||
}
|
||||
35
test_conformance/gles/procs.h
Normal file
35
test_conformance/gles/procs.h
Normal file
@@ -0,0 +1,35 @@
|
||||
//
|
||||
// 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 "../../test_common/harness/mt19937.h"
|
||||
|
||||
|
||||
extern int test_buffers( cl_device_id device, cl_context context, cl_command_queue queue, int num_elements );
|
||||
extern int test_buffers_getinfo( cl_device_id device, cl_context context, cl_command_queue queue, int numElements );
|
||||
extern int test_images_create( cl_device_id device, cl_context context, cl_command_queue queue, int num_elements );
|
||||
extern int test_images_read( cl_device_id device, cl_context context, cl_command_queue queue, int num_elements );
|
||||
extern int test_images_2D_getinfo( cl_device_id device, cl_context context, cl_command_queue queue, int numElements );
|
||||
extern int test_images_read_cube( cl_device_id device, cl_context context, cl_command_queue queue, int num_elements );
|
||||
extern int test_images_cube_getinfo( cl_device_id device, cl_context context, cl_command_queue queue, int numElements );
|
||||
extern int test_images_read_3D( cl_device_id device, cl_context context, cl_command_queue queue, int num_elements );
|
||||
extern int test_images_3D_getinfo( cl_device_id device, cl_context context, cl_command_queue queue, int numElements );
|
||||
extern int test_images_write( cl_device_id device, cl_context context, cl_command_queue queue, int num_elements );
|
||||
extern int test_images_write_cube( cl_device_id device, cl_context context, cl_command_queue queue, int num_elements );
|
||||
extern int test_renderbuffer_read( cl_device_id device, cl_context context, cl_command_queue queue, int num_elements );
|
||||
extern int test_renderbuffer_write( cl_device_id device, cl_context context, cl_command_queue queue, int num_elements );
|
||||
extern int test_renderbuffer_getinfo( cl_device_id device, cl_context context, cl_command_queue queue, int numElements );
|
||||
extern int test_fence_sync( cl_device_id device, cl_context context, cl_command_queue queue, int numElements );
|
||||
|
||||
215
test_conformance/gles/setup_egl.cpp
Normal file
215
test_conformance/gles/setup_egl.cpp
Normal file
@@ -0,0 +1,215 @@
|
||||
//
|
||||
// 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 "setup.h"
|
||||
#include "testBase.h"
|
||||
#include "../../test_common/harness/errorHelpers.h"
|
||||
#include <assert.h>
|
||||
|
||||
#include <CL/cl.h>
|
||||
#include <CL/cl_ext.h>
|
||||
|
||||
#define EGLERR() \
|
||||
assert(eglGetError() == EGL_SUCCESS); \
|
||||
|
||||
#define MAX_DEVICES 10
|
||||
|
||||
class EGLGLEnvironment : public GLEnvironment
|
||||
{
|
||||
private:
|
||||
cl_platform_id _platform;
|
||||
EGLDisplay _display;
|
||||
EGLContext _context;
|
||||
EGLSurface _surface;
|
||||
|
||||
public:
|
||||
EGLGLEnvironment()
|
||||
:_platform(NULL)
|
||||
,_display(EGL_NO_DISPLAY)
|
||||
,_context(NULL)
|
||||
,_surface(EGL_NO_SURFACE)
|
||||
{
|
||||
}
|
||||
|
||||
virtual int Init( int *argc, char **argv, int use_opengl_32 )
|
||||
{
|
||||
EGLint ConfigAttribs[] =
|
||||
{
|
||||
EGL_RED_SIZE, 8,
|
||||
EGL_GREEN_SIZE, 8,
|
||||
EGL_BLUE_SIZE, 8,
|
||||
EGL_ALPHA_SIZE, 8,
|
||||
EGL_DEPTH_SIZE, 16,
|
||||
EGL_SURFACE_TYPE, EGL_PBUFFER_BIT,
|
||||
// EGL_BIND_TO_TEXTURE_RGBA, EGL_TRUE,
|
||||
EGL_NONE
|
||||
};
|
||||
|
||||
static const EGLint ContextAttribs[] =
|
||||
{
|
||||
EGL_CONTEXT_CLIENT_VERSION, 2,
|
||||
EGL_NONE
|
||||
};
|
||||
|
||||
EGLint conf_list[] = {
|
||||
EGL_WIDTH, 512,
|
||||
EGL_HEIGHT, 512,
|
||||
EGL_TEXTURE_FORMAT, EGL_TEXTURE_RGBA,
|
||||
EGL_TEXTURE_TARGET, EGL_TEXTURE_2D,
|
||||
EGL_NONE};
|
||||
|
||||
EGLint majorVersion;
|
||||
EGLint minorVersion;
|
||||
EGLConfig config;
|
||||
EGLint numConfigs;
|
||||
|
||||
EGLERR();
|
||||
_display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
|
||||
EGLERR();
|
||||
|
||||
eglInitialize(_display, &majorVersion, &minorVersion);
|
||||
EGLERR();
|
||||
|
||||
eglBindAPI(EGL_OPENGL_ES_API);
|
||||
EGLERR();
|
||||
|
||||
eglChooseConfig(_display, ConfigAttribs, &config, 1, &numConfigs);
|
||||
EGLERR();
|
||||
|
||||
_context = eglCreateContext(_display, config, NULL, ContextAttribs);
|
||||
EGLERR();
|
||||
|
||||
_surface = eglCreatePbufferSurface(_display, config, conf_list);
|
||||
EGLERR();
|
||||
|
||||
eglMakeCurrent(_display, _surface, _surface, _context);
|
||||
EGLERR();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
virtual cl_context CreateCLContext( void )
|
||||
{
|
||||
cl_context_properties properties[] = {
|
||||
CL_CONTEXT_PLATFORM, (cl_context_properties) _platform,
|
||||
CL_GL_CONTEXT_KHR, (cl_context_properties) _context,
|
||||
CL_EGL_DISPLAY_KHR, (cl_context_properties) _display,
|
||||
0
|
||||
};
|
||||
cl_device_id devices[MAX_DEVICES];
|
||||
size_t dev_size;
|
||||
cl_int status;
|
||||
|
||||
status = clGetGLContextInfoKHR(properties,
|
||||
CL_DEVICES_FOR_GL_CONTEXT_KHR,
|
||||
sizeof(devices),
|
||||
devices,
|
||||
&dev_size);
|
||||
if (status != CL_SUCCESS) {
|
||||
print_error(status, "clGetGLContextInfoKHR failed");
|
||||
return NULL;
|
||||
}
|
||||
dev_size /= sizeof(cl_device_id);
|
||||
log_info("GL _context supports %d compute devices\n", dev_size);
|
||||
|
||||
status = clGetGLContextInfoKHR(properties,
|
||||
CL_CURRENT_DEVICE_FOR_GL_CONTEXT_KHR,
|
||||
sizeof(devices),
|
||||
devices,
|
||||
&dev_size);
|
||||
if (status != CL_SUCCESS) {
|
||||
print_error(status, "clGetGLContextInfoKHR failed");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!dev_size)
|
||||
{
|
||||
log_info("GL _context current device is not a CL device.\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return clCreateContext(properties, 1, &devices[0], NULL, NULL, &status);
|
||||
}
|
||||
|
||||
virtual int SupportsCLGLInterop( cl_device_type device_type )
|
||||
{
|
||||
cl_device_id devices[MAX_DEVICES];
|
||||
cl_uint num_of_devices;
|
||||
int interop_devices = 0;
|
||||
int error;
|
||||
|
||||
error = clGetPlatformIDs(1, &_platform, NULL);
|
||||
if (error) {
|
||||
print_error(error, "clGetPlatformIDs failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
error = clGetDeviceIDs(_platform, device_type, MAX_DEVICES, devices, &num_of_devices);
|
||||
if (error) {
|
||||
print_error(error, "clGetDeviceIDs failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Check all devices, search for one that supports cl_khr_gl_sharing
|
||||
char extensions[8192];
|
||||
for (int i=0; i<(int)num_of_devices; i++) {
|
||||
error = clGetDeviceInfo(devices[i], CL_DEVICE_EXTENSIONS, sizeof(extensions), extensions, NULL);
|
||||
if (error) {
|
||||
print_error(error, "clGetDeviceInfo failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (strstr(extensions, "cl_khr_gl_sharing ") == NULL) {
|
||||
log_info("Device %d of %d does not support required extension cl_khr_gl_sharing.\n", i+1, num_of_devices);
|
||||
} else {
|
||||
log_info("Device %d of %d supports required extension cl_khr_gl_sharing.\n", i+1, num_of_devices);
|
||||
interop_devices++;
|
||||
}
|
||||
}
|
||||
return interop_devices > 0;
|
||||
}
|
||||
|
||||
// Change to cleanup egl environment properly when the test exit.
|
||||
// This change does not affect any functionality of the test it self
|
||||
virtual void terminate_egl_display()
|
||||
{
|
||||
if(_display != EGL_NO_DISPLAY)
|
||||
{
|
||||
eglMakeCurrent(_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
|
||||
EGLERR();
|
||||
|
||||
eglDestroyContext(_display, _context);
|
||||
EGLERR();
|
||||
_context = EGL_NO_CONTEXT;
|
||||
|
||||
eglDestroySurface(_display, _surface);
|
||||
EGLERR();
|
||||
_surface = EGL_NO_SURFACE;
|
||||
|
||||
eglTerminate(_display);
|
||||
EGLERR();
|
||||
_display = EGL_NO_DISPLAY;
|
||||
}
|
||||
}
|
||||
|
||||
virtual ~EGLGLEnvironment()
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
GLEnvironment * GLEnvironment::Instance( void )
|
||||
{
|
||||
return new EGLGLEnvironment();
|
||||
}
|
||||
71
test_conformance/gles/testBase.h
Normal file
71
test_conformance/gles/testBase.h
Normal file
@@ -0,0 +1,71 @@
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
#ifndef _testBase_h
|
||||
#define _testBase_h
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
#include <string.h>
|
||||
|
||||
#if !defined(_WIN32)
|
||||
#include <stdbool.h>
|
||||
#endif
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#if !defined (__APPLE__)
|
||||
#include <CL/cl.h>
|
||||
#include "../../test_common/gles/gl_headers.h"
|
||||
#include <CL/cl_gl.h>
|
||||
#else
|
||||
#include "../../test_common/gl/gl_headers.h"
|
||||
#endif
|
||||
|
||||
#include "../../test_common/harness/errorHelpers.h"
|
||||
#include "../../test_common/harness/kernelHelpers.h"
|
||||
#include "../../test_common/harness/threadTesting.h"
|
||||
#include "../../test_common/harness/typeWrappers.h"
|
||||
#include "../../test_common/harness/conversions.h"
|
||||
#include "../../test_common/harness/mt19937.h"
|
||||
|
||||
#ifdef GL_ES_VERSION_2_0
|
||||
#include "../../test_common/gles/helpers.h"
|
||||
#else
|
||||
#include "../../test_common/gl/helpers.h"
|
||||
#endif
|
||||
|
||||
extern const char *get_kernel_suffix( cl_image_format *format );
|
||||
extern const char *get_write_conversion( cl_image_format *format, ExplicitType type);
|
||||
extern ExplicitType get_read_kernel_type( cl_image_format *format );
|
||||
extern ExplicitType get_write_kernel_type( cl_image_format *format );
|
||||
|
||||
extern char * convert_to_expected( void * inputBuffer, size_t numPixels, ExplicitType inType, ExplicitType outType );
|
||||
extern int validate_integer_results( void *expectedResults, void *actualResults, size_t width, size_t height, size_t typeSize );
|
||||
extern int validate_integer_results( void *expectedResults, void *actualResults, size_t width, size_t height, size_t depth, size_t typeSize );
|
||||
extern int validate_float_results( void *expectedResults, void *actualResults, size_t width, size_t height );
|
||||
extern int validate_float_results( void *expectedResults, void *actualResults, size_t width, size_t height, size_t depth );
|
||||
|
||||
extern int CheckGLObjectInfo(cl_mem mem, cl_gl_object_type expected_cl_gl_type, GLuint expected_gl_name,
|
||||
GLenum expected_cl_gl_texture_target, GLint expected_cl_gl_mipmap_level);
|
||||
|
||||
extern bool CheckGLIntegerExtensionSupport();
|
||||
|
||||
#endif // _testBase_h
|
||||
|
||||
|
||||
|
||||
402
test_conformance/gles/test_buffers.cpp
Normal file
402
test_conformance/gles/test_buffers.cpp
Normal file
@@ -0,0 +1,402 @@
|
||||
//
|
||||
// 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 "testHarness.h"
|
||||
#include "../../test_common/harness/conversions.h"
|
||||
#include "../../test_common/harness/typeWrappers.h"
|
||||
#include <math.h>
|
||||
#include <float.h>
|
||||
|
||||
#if !defined (__APPLE__)
|
||||
#include <CL/cl_gl.h>
|
||||
#endif
|
||||
|
||||
extern "C" { extern cl_uint gRandomSeed; };
|
||||
|
||||
static const char *bufferKernelPattern =
|
||||
"__kernel void sample_test( __global %s%s *source, __global %s%s *clDest, __global %s%s *glDest )\n"
|
||||
"{\n"
|
||||
" int tid = get_global_id(0);\n"
|
||||
" clDest[ tid ] = source[ tid ] + (%s%s)(1);\n"
|
||||
" glDest[ tid ] = source[ tid ] + (%s%s)(2);\n"
|
||||
"}\n";
|
||||
|
||||
#define TYPE_CASE( enum, type, range, offset ) \
|
||||
case enum: \
|
||||
{ \
|
||||
cl_##type *ptr = (cl_##type *)outData; \
|
||||
for( i = 0; i < count; i++ ) \
|
||||
ptr[ i ] = (cl_##type)( ( genrand_int32(d) & range ) - offset ); \
|
||||
break; \
|
||||
}
|
||||
|
||||
void gen_input_data( ExplicitType type, size_t count, MTdata d, void *outData )
|
||||
{
|
||||
size_t i;
|
||||
|
||||
switch( type )
|
||||
{
|
||||
case kBool:
|
||||
{
|
||||
bool *boolPtr = (bool *)outData;
|
||||
for( i = 0; i < count; i++ )
|
||||
{
|
||||
boolPtr[i] = ( genrand_int32(d) & 1 ) ? true : false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
TYPE_CASE( kChar, char, 250, 127 )
|
||||
TYPE_CASE( kUChar, uchar, 250, 0 )
|
||||
TYPE_CASE( kShort, short, 65530, 32767 )
|
||||
TYPE_CASE( kUShort, ushort, 65530, 0 )
|
||||
TYPE_CASE( kInt, int, 0x0fffffff, 0x70000000 )
|
||||
TYPE_CASE( kUInt, uint, 0x0fffffff, 0 )
|
||||
|
||||
case kLong:
|
||||
{
|
||||
cl_long *longPtr = (cl_long *)outData;
|
||||
for( i = 0; i < count; i++ )
|
||||
{
|
||||
longPtr[i] = (cl_long)genrand_int32(d) | ( (cl_ulong)genrand_int32(d) << 32 );
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case kULong:
|
||||
{
|
||||
cl_ulong *ulongPtr = (cl_ulong *)outData;
|
||||
for( i = 0; i < count; i++ )
|
||||
{
|
||||
ulongPtr[i] = (cl_ulong)genrand_int32(d) | ( (cl_ulong)genrand_int32(d) << 32 );
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case kFloat:
|
||||
{
|
||||
cl_float *floatPtr = (float *)outData;
|
||||
for( i = 0; i < count; i++ )
|
||||
floatPtr[i] = get_random_float( -100000.f, 100000.f, d );
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
log_error( "ERROR: Invalid type passed in to generate_random_data!\n" );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#define INC_CASE( enum, type ) \
|
||||
case enum: \
|
||||
{ \
|
||||
cl_##type *src = (cl_##type *)inData; \
|
||||
cl_##type *dst = (cl_##type *)outData; \
|
||||
*dst = *src + 1; \
|
||||
break; \
|
||||
}
|
||||
|
||||
void get_incremented_value( void *inData, void *outData, ExplicitType type )
|
||||
{
|
||||
switch( type )
|
||||
{
|
||||
INC_CASE( kChar, char )
|
||||
INC_CASE( kUChar, uchar )
|
||||
INC_CASE( kShort, short )
|
||||
INC_CASE( kUShort, ushort )
|
||||
INC_CASE( kInt, int )
|
||||
INC_CASE( kUInt, uint )
|
||||
INC_CASE( kLong, long )
|
||||
INC_CASE( kULong, ulong )
|
||||
INC_CASE( kFloat, float )
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int test_buffer_kernel(cl_context context, cl_command_queue queue, ExplicitType vecType, size_t vecSize, int numElements, int validate_only, MTdata d)
|
||||
{
|
||||
clProgramWrapper program;
|
||||
clKernelWrapper kernel;
|
||||
clMemWrapper streams[ 3 ];
|
||||
size_t dataSize = numElements * 16 * sizeof(cl_long);
|
||||
#if !(defined(_WIN32) && defined(_MSC_VER))
|
||||
cl_long inData[numElements * 16], outDataCL[numElements * 16], outDataGL[ numElements * 16 ];
|
||||
#else
|
||||
cl_long* inData = (cl_long*)_malloca(dataSize);
|
||||
cl_long* outDataCL = (cl_long*)_malloca(dataSize);
|
||||
cl_long* outDataGL = (cl_long*)_malloca(dataSize);
|
||||
#endif
|
||||
glBufferWrapper inGLBuffer, outGLBuffer;
|
||||
int i;
|
||||
size_t bufferSize;
|
||||
|
||||
int error;
|
||||
size_t threads[1], localThreads[1];
|
||||
char kernelSource[10240];
|
||||
char *programPtr;
|
||||
char sizeName[4];
|
||||
|
||||
/* Create the source */
|
||||
if( vecSize == 1 )
|
||||
sizeName[ 0 ] = 0;
|
||||
else
|
||||
sprintf( sizeName, "%d", (int)vecSize );
|
||||
|
||||
sprintf( kernelSource, bufferKernelPattern, get_explicit_type_name( vecType ), sizeName,
|
||||
get_explicit_type_name( vecType ), sizeName,
|
||||
get_explicit_type_name( vecType ), sizeName,
|
||||
get_explicit_type_name( vecType ), sizeName,
|
||||
get_explicit_type_name( vecType ), sizeName );
|
||||
|
||||
/* Create kernels */
|
||||
programPtr = kernelSource;
|
||||
if( create_single_kernel_helper( context, &program, &kernel, 1, (const char **)&programPtr, "sample_test" ) )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
bufferSize = numElements * vecSize * get_explicit_type_size( vecType );
|
||||
|
||||
/* Generate some almost-random input data */
|
||||
gen_input_data( vecType, vecSize * numElements, d, inData );
|
||||
memset( outDataCL, 0, dataSize );
|
||||
memset( outDataGL, 0, dataSize );
|
||||
|
||||
/* Generate some GL buffers to go against */
|
||||
glGenBuffers( 1, &inGLBuffer );
|
||||
glGenBuffers( 1, &outGLBuffer );
|
||||
|
||||
glBindBuffer( GL_ARRAY_BUFFER, inGLBuffer );
|
||||
glBufferData( GL_ARRAY_BUFFER, bufferSize, inData, GL_STATIC_DRAW );
|
||||
|
||||
// Note: we need to bind the output buffer, even though we don't care about its values yet,
|
||||
// because CL needs it to get the buffer size
|
||||
glBindBuffer( GL_ARRAY_BUFFER, outGLBuffer );
|
||||
glBufferData( GL_ARRAY_BUFFER, bufferSize, outDataGL, GL_STATIC_DRAW );
|
||||
|
||||
glBindBuffer( GL_ARRAY_BUFFER, 0 );
|
||||
glFlush();
|
||||
|
||||
|
||||
/* Generate some streams. The first and last ones are GL, middle one just vanilla CL */
|
||||
streams[ 0 ] = (*clCreateFromGLBuffer_ptr)( context, CL_MEM_READ_ONLY, inGLBuffer, &error );
|
||||
test_error( error, "Unable to create input GL buffer" );
|
||||
|
||||
streams[ 1 ] = clCreateBuffer( context, CL_MEM_READ_WRITE, bufferSize, NULL, &error );
|
||||
test_error( error, "Unable to create output CL buffer" );
|
||||
|
||||
streams[ 2 ] = (*clCreateFromGLBuffer_ptr)( context, CL_MEM_WRITE_ONLY, outGLBuffer, &error );
|
||||
test_error( error, "Unable to create output GL buffer" );
|
||||
|
||||
|
||||
/* Validate the info */
|
||||
if (validate_only) {
|
||||
int result = (CheckGLObjectInfo(streams[0], CL_GL_OBJECT_BUFFER, (GLuint)inGLBuffer, (GLenum)0, 0) |
|
||||
CheckGLObjectInfo(streams[2], CL_GL_OBJECT_BUFFER, (GLuint)outGLBuffer, (GLenum)0, 0) );
|
||||
for(i=0;i<3;i++)
|
||||
{
|
||||
clReleaseMemObject(streams[i]);
|
||||
streams[i] = NULL;
|
||||
}
|
||||
|
||||
glDeleteBuffers(1, &inGLBuffer); inGLBuffer = 0;
|
||||
glDeleteBuffers(1, &outGLBuffer); outGLBuffer = 0;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Assign streams and execute */
|
||||
for( int i = 0; i < 3; i++ )
|
||||
{
|
||||
error = clSetKernelArg( kernel, i, sizeof( streams[ i ] ), &streams[ i ] );
|
||||
test_error( error, "Unable to set kernel arguments" );
|
||||
}
|
||||
error = (*clEnqueueAcquireGLObjects_ptr)( queue, 1, &streams[ 0 ], 0, NULL, NULL);
|
||||
test_error( error, "Unable to acquire GL obejcts");
|
||||
error = (*clEnqueueAcquireGLObjects_ptr)( queue, 1, &streams[ 2 ], 0, NULL, NULL);
|
||||
test_error( error, "Unable to acquire GL obejcts");
|
||||
|
||||
/* Run the kernel */
|
||||
threads[0] = numElements;
|
||||
|
||||
error = get_max_common_work_group_size( context, kernel, threads[0], &localThreads[0] );
|
||||
test_error( error, "Unable to get work group size to use" );
|
||||
|
||||
error = clEnqueueNDRangeKernel( queue, kernel, 1, NULL, threads, localThreads, 0, NULL, NULL );
|
||||
test_error( error, "Unable to execute test kernel" );
|
||||
|
||||
error = (*clEnqueueReleaseGLObjects_ptr)( queue, 1, &streams[ 0 ], 0, NULL, NULL );
|
||||
test_error(error, "clEnqueueReleaseGLObjects failed");
|
||||
error = (*clEnqueueReleaseGLObjects_ptr)( queue, 1, &streams[ 2 ], 0, NULL, NULL );
|
||||
test_error(error, "clEnqueueReleaseGLObjects failed");
|
||||
|
||||
// Get the results from both CL and GL and make sure everything looks correct
|
||||
error = clEnqueueReadBuffer( queue, streams[ 1 ], CL_TRUE, 0, bufferSize, outDataCL, 0, NULL, NULL );
|
||||
test_error( error, "Unable to read output CL array!" );
|
||||
glBindBuffer( GL_ARRAY_BUFFER, outGLBuffer );
|
||||
void *glMem = glMapBufferRange(GL_ARRAY_BUFFER, 0, bufferSize, GL_MAP_READ_BIT );
|
||||
memcpy( outDataGL, glMem, bufferSize );
|
||||
glUnmapBuffer( GL_ARRAY_BUFFER );
|
||||
char *inP = (char *)inData, *glP = (char *)outDataGL, *clP = (char *)outDataCL;
|
||||
error = 0;
|
||||
for( size_t i = 0; i < numElements * vecSize; i++ )
|
||||
{
|
||||
cl_long expectedCLValue, expectedGLValue;
|
||||
get_incremented_value( inP, &expectedCLValue, vecType );
|
||||
get_incremented_value( &expectedCLValue, &expectedGLValue, vecType );
|
||||
|
||||
if( memcmp( clP, &expectedCLValue, get_explicit_type_size( vecType ) ) != 0 )
|
||||
{
|
||||
char scratch[ 64 ];
|
||||
log_error( "ERROR: Data sample %d from the CL output did not validate!\n", (int)i );
|
||||
log_error( "\t Input: %s\n", GetDataVectorString( inP, get_explicit_type_size( vecType ), 1, scratch ) );
|
||||
log_error( "\tExpected: %s\n", GetDataVectorString( &expectedCLValue, get_explicit_type_size( vecType ), 1, scratch ) );
|
||||
log_error( "\t Actual: %s\n", GetDataVectorString( clP, get_explicit_type_size( vecType ), 1, scratch ) );
|
||||
error = -1;
|
||||
}
|
||||
|
||||
if( memcmp( glP, &expectedGLValue, get_explicit_type_size( vecType ) ) != 0 )
|
||||
{
|
||||
char scratch[ 64 ];
|
||||
log_error( "ERROR: Data sample %d from the GL output did not validate!\n", (int)i );
|
||||
log_error( "\t Input: %s\n", GetDataVectorString( inP, get_explicit_type_size( vecType ), 1, scratch ) );
|
||||
log_error( "\tExpected: %s\n", GetDataVectorString( &expectedGLValue, get_explicit_type_size( vecType ), 1, scratch ) );
|
||||
log_error( "\t Actual: %s\n", GetDataVectorString( glP, get_explicit_type_size( vecType ), 1, scratch ) );
|
||||
error = -1;
|
||||
}
|
||||
|
||||
if( error )
|
||||
return error;
|
||||
|
||||
inP += get_explicit_type_size( vecType );
|
||||
glP += get_explicit_type_size( vecType );
|
||||
clP += get_explicit_type_size( vecType );
|
||||
}
|
||||
|
||||
for(i=0;i<3;i++)
|
||||
{
|
||||
clReleaseMemObject(streams[i]);
|
||||
streams[i] = NULL;
|
||||
}
|
||||
|
||||
glDeleteBuffers(1, &inGLBuffer); inGLBuffer = 0;
|
||||
glDeleteBuffers(1, &outGLBuffer); outGLBuffer = 0;
|
||||
|
||||
#if (defined(_WIN32) && defined(_MSC_VER))
|
||||
_freea(inData);
|
||||
_freea(outDataCL);
|
||||
_freea(outDataGL);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int test_buffers( cl_device_id device, cl_context context, cl_command_queue queue, int numElements )
|
||||
{
|
||||
ExplicitType vecType[] = { kChar, kUChar, kShort, kUShort, kInt, kUInt, kLong, kULong, kFloat, kNumExplicitTypes };
|
||||
unsigned int vecSizes[] = { 1, 2, 4, 8, 16, 0 };
|
||||
unsigned int index, typeIndex;
|
||||
int retVal = 0;
|
||||
RandomSeed seed(gRandomSeed);
|
||||
|
||||
/* 64-bit ints optional in embedded profile */
|
||||
int hasLong = 1;
|
||||
int isEmbedded = 0;
|
||||
char profile[1024] = "";
|
||||
retVal = clGetDeviceInfo(device, CL_DEVICE_PROFILE, sizeof(profile), profile, NULL);
|
||||
if (retVal)
|
||||
{
|
||||
print_error(retVal, "clGetDeviceInfo for CL_DEVICE_PROFILE failed\n" );
|
||||
return -1;
|
||||
}
|
||||
isEmbedded = NULL != strstr(profile, "EMBEDDED_PROFILE");
|
||||
if(isEmbedded && !is_extension_available(device, "cles_khr_int64"))
|
||||
{
|
||||
hasLong = 0;
|
||||
}
|
||||
|
||||
for( typeIndex = 0; vecType[ typeIndex ] != kNumExplicitTypes; typeIndex++ )
|
||||
{
|
||||
for( index = 0; vecSizes[ index ] != 0; index++ )
|
||||
{
|
||||
/* Fix bug 7124 */
|
||||
if ( (vecType[ typeIndex ] == kLong || vecType[ typeIndex ] == kULong) && !hasLong )
|
||||
continue;
|
||||
|
||||
// Test!
|
||||
if( test_buffer_kernel( context, queue, vecType[ typeIndex ], vecSizes[ index ], numElements, 0, seed) != 0 )
|
||||
{
|
||||
char sizeNames[][ 4 ] = { "", "", "2", "", "4", "", "", "", "8", "", "", "", "", "", "", "", "16" };
|
||||
log_error( " Buffer test %s%s FAILED\n", get_explicit_type_name( vecType[ typeIndex ] ), sizeNames[ vecSizes[ index ] ] );
|
||||
retVal++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return retVal;
|
||||
|
||||
}
|
||||
|
||||
|
||||
int test_buffers_getinfo( cl_device_id device, cl_context context, cl_command_queue queue, int numElements )
|
||||
{
|
||||
ExplicitType vecType[] = { kChar, kUChar, kShort, kUShort, kInt, kUInt, kLong, kULong, kFloat, kNumExplicitTypes };
|
||||
unsigned int vecSizes[] = { 1, 2, 4, 8, 16, 0 };
|
||||
unsigned int index, typeIndex;
|
||||
int retVal = 0;
|
||||
RandomSeed seed( gRandomSeed );
|
||||
|
||||
/* 64-bit ints optional in embedded profile */
|
||||
int hasLong = 1;
|
||||
int isEmbedded = 0;
|
||||
char profile[1024] = "";
|
||||
retVal = clGetDeviceInfo(device, CL_DEVICE_PROFILE, sizeof(profile), profile, NULL);
|
||||
if (retVal)
|
||||
{
|
||||
print_error(retVal, "clGetDeviceInfo for CL_DEVICE_PROFILE failed\n" );
|
||||
return -1;
|
||||
}
|
||||
isEmbedded = NULL != strstr(profile, "EMBEDDED_PROFILE");
|
||||
if(isEmbedded && !is_extension_available(device, "cles_khr_int64"))
|
||||
{
|
||||
hasLong = 0;
|
||||
}
|
||||
|
||||
for( typeIndex = 0; vecType[ typeIndex ] != kNumExplicitTypes; typeIndex++ )
|
||||
{
|
||||
for( index = 0; vecSizes[ index ] != 0; index++ )
|
||||
{
|
||||
/* Fix bug 7124 */
|
||||
if ( (vecType[ typeIndex ] == kLong || vecType[ typeIndex ] == kULong) && !hasLong )
|
||||
continue;
|
||||
|
||||
// Test!
|
||||
if( test_buffer_kernel( context, queue, vecType[ typeIndex ], vecSizes[ index ], numElements, 1, seed ) != 0 )
|
||||
{
|
||||
char sizeNames[][ 4 ] = { "", "", "2", "", "4", "", "", "", "8", "", "", "", "", "", "", "", "16" };
|
||||
log_error( " Buffer test %s%s FAILED\n", get_explicit_type_name( vecType[ typeIndex ] ), sizeNames[ vecSizes[ index ] ] );
|
||||
retVal++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return retVal;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
664
test_conformance/gles/test_fence_sync.cpp
Normal file
664
test_conformance/gles/test_fence_sync.cpp
Normal file
@@ -0,0 +1,664 @@
|
||||
//
|
||||
// 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 "gl_headers.h"
|
||||
|
||||
#include "testBase.h"
|
||||
#include "setup.h"
|
||||
#include "../../test_common/harness/genericThread.h"
|
||||
|
||||
#ifndef GLsync
|
||||
// For OpenGL before 3.2, we look for the ARB_sync extension and try to use that
|
||||
#if !defined(_WIN32)
|
||||
#include <inttypes.h>
|
||||
#endif // !_WIN32
|
||||
typedef int64_t GLint64;
|
||||
typedef uint64_t GLuint64;
|
||||
typedef struct __GLsync *GLsync;
|
||||
|
||||
typedef GLsync (*glFenceSyncPtr)(GLenum condition,GLbitfield flags);
|
||||
glFenceSyncPtr glFenceSyncFunc;
|
||||
|
||||
typedef bool (*glIsSyncPtr)(GLsync sync);
|
||||
glIsSyncPtr glIsSyncFunc;
|
||||
|
||||
typedef void (*glDeleteSyncPtr)(GLsync sync);
|
||||
glDeleteSyncPtr glDeleteSyncFunc;
|
||||
|
||||
typedef GLenum (*glClientWaitSyncPtr)(GLsync sync,GLbitfield flags,GLuint64 timeout);
|
||||
glClientWaitSyncPtr glClientWaitSyncFunc;
|
||||
|
||||
typedef void (*glWaitSyncPtr)(GLsync sync,GLbitfield flags,GLuint64 timeout);
|
||||
glWaitSyncPtr glWaitSyncFunc;
|
||||
|
||||
typedef void (*glGetInteger64vPtr)(GLenum pname, GLint64 *params);
|
||||
glGetInteger64vPtr glGetInteger64vFunc;
|
||||
|
||||
typedef void (*glGetSyncivPtr)(GLsync sync,GLenum pname,GLsizei bufSize,GLsizei *length,
|
||||
GLint *values);
|
||||
glGetSyncivPtr glGetSyncivFunc;
|
||||
|
||||
#define CHK_GL_ERR() printf("%s\n", gluErrorString(glGetError()))
|
||||
|
||||
static void InitSyncFns( void )
|
||||
{
|
||||
glFenceSyncFunc = (glFenceSyncPtr)glutGetProcAddress( "glFenceSync" );
|
||||
glIsSyncFunc = (glIsSyncPtr)glutGetProcAddress( "glIsSync" );
|
||||
glDeleteSyncFunc = (glDeleteSyncPtr)glutGetProcAddress( "glDeleteSync" );
|
||||
glClientWaitSyncFunc = (glClientWaitSyncPtr)glutGetProcAddress( "glClientWaitSync" );
|
||||
glWaitSyncFunc = (glWaitSyncPtr)glutGetProcAddress( "glWaitSync" );
|
||||
glGetInteger64vFunc = (glGetInteger64vPtr)glutGetProcAddress( "glGetInteger64v" );
|
||||
glGetSyncivFunc = (glGetSyncivPtr)glutGetProcAddress( "glGetSynciv" );
|
||||
}
|
||||
|
||||
#define GL_MAX_SERVER_WAIT_TIMEOUT 0x9111
|
||||
|
||||
#define GL_OBJECT_TYPE 0x9112
|
||||
#define GL_SYNC_CONDITION 0x9113
|
||||
#define GL_SYNC_STATUS 0x9114
|
||||
#define GL_SYNC_FLAGS 0x9115
|
||||
|
||||
#define GL_SYNC_FENCE 0x9116
|
||||
|
||||
#define GL_SYNC_GPU_COMMANDS_COMPLETE 0x9117
|
||||
|
||||
#define GL_UNSIGNALED 0x9118
|
||||
#define GL_SIGNALED 0x9119
|
||||
|
||||
#define GL_SYNC_FLUSH_COMMANDS_BIT 0x00000001
|
||||
|
||||
#define GL_TIMEOUT_IGNORED 0xFFFFFFFFFFFFFFFFull
|
||||
|
||||
#define GL_ALREADY_SIGNALED 0x911A
|
||||
#define GL_TIMEOUT_EXPIRED 0x911B
|
||||
#define GL_CONDITION_SATISFIED 0x911C
|
||||
#define GL_WAIT_FAILED 0x911D
|
||||
|
||||
#define USING_ARB_sync 1
|
||||
#endif
|
||||
|
||||
typedef cl_event (CL_API_CALL *clCreateEventFromGLsyncKHR_fn)( cl_context context, GLsync sync, cl_int *errCode_ret) ;
|
||||
|
||||
clCreateEventFromGLsyncKHR_fn clCreateEventFromGLsyncKHR_ptr;
|
||||
|
||||
|
||||
static const char *updateBuffersKernel[] = {
|
||||
"__kernel void update( __global float4 * vertices, __global float4 *colors, int horizWrap, int rowIdx )\n"
|
||||
"{\n"
|
||||
" size_t tid = get_global_id(0);\n"
|
||||
"\n"
|
||||
" size_t xVal = ( tid & ( horizWrap - 1 ) );\n"
|
||||
" vertices[ tid * 2 + 0 ] = (float4)( xVal, rowIdx*16.f, 0.0f, 1.f );\n"
|
||||
" vertices[ tid * 2 + 1 ] = (float4)( xVal, rowIdx*16.f + 4.0f, 0.0f, 1.f );\n"
|
||||
"\n"
|
||||
" int rowV = rowIdx + 1;\n"
|
||||
" colors[ tid * 2 + 0 ] = (float4)( ( rowV & 1 ) / 255.f, ( ( rowV & 2 ) >> 1 ) / 255.f, ( ( rowV & 4 ) >> 2 ) / 255.f, 1.f );\n"
|
||||
" //colors[ tid * 2 + 0 ] = (float4)( (float)xVal/(float)horizWrap, 1.0f, 1.0f, 1.0f );\n"
|
||||
" colors[ tid * 2 + 1 ] = colors[ tid * 2 + 0 ];\n"
|
||||
"}\n" };
|
||||
|
||||
//Passthrough VertexShader
|
||||
static const char vertexshader[] =
|
||||
"uniform mat4 projMatrix;\n"
|
||||
"attribute vec4 inPosition;\n"
|
||||
"attribute vec4 inColor;\n"
|
||||
"varying vec4 outColor;\n"
|
||||
"void main (void) {\n"
|
||||
" gl_Position = projMatrix*inPosition;\n"
|
||||
" outColor = inColor;\n"
|
||||
"}\n";
|
||||
|
||||
//Passthrough FragmentShader
|
||||
static const char fragmentshader[] =
|
||||
"varying vec4 outColor;\n"
|
||||
"void main (void) {\n"
|
||||
" gl_FragColor = outColor;\n"
|
||||
"}\n";
|
||||
|
||||
GLuint createShaderProgram(GLint *posLoc, GLint *colLoc)
|
||||
{
|
||||
GLint logLength, status;
|
||||
GLuint program = glCreateProgram();
|
||||
GLuint vpShader;
|
||||
|
||||
char* vpstr = (char*)malloc(sizeof(vertexshader));
|
||||
strcpy(vpstr, vertexshader);
|
||||
|
||||
vpShader = glCreateShader(GL_VERTEX_SHADER);
|
||||
glShaderSource(vpShader, 1, (const GLchar **)&vpstr, NULL);
|
||||
glCompileShader(vpShader);
|
||||
glGetShaderiv(vpShader, GL_INFO_LOG_LENGTH, &logLength);
|
||||
if (logLength > 0) {
|
||||
GLchar *log = (GLchar*) malloc(logLength);
|
||||
glGetShaderInfoLog(vpShader, logLength, &logLength, log);
|
||||
log_info("Vtx Shader compile log:\n%s", log);
|
||||
free(log);
|
||||
}
|
||||
|
||||
free(vpstr);
|
||||
vpstr = NULL;
|
||||
|
||||
glGetShaderiv(vpShader, GL_COMPILE_STATUS, &status);
|
||||
if (status == 0)
|
||||
{
|
||||
log_error("Failed to compile vtx shader:\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
glAttachShader(program, vpShader);
|
||||
|
||||
GLuint fpShader;
|
||||
char* fpstr = (char*)malloc(strlen(fragmentshader));
|
||||
strcpy(fpstr, fragmentshader);
|
||||
fpShader = glCreateShader(GL_FRAGMENT_SHADER);
|
||||
glShaderSource(fpShader, 1, (const GLchar **)&fpstr, NULL);
|
||||
glCompileShader(fpShader);
|
||||
|
||||
free(fpstr);
|
||||
fpstr = NULL;
|
||||
|
||||
glGetShaderiv(fpShader, GL_INFO_LOG_LENGTH, &logLength);
|
||||
if (logLength > 0) {
|
||||
GLchar *log = (GLchar*)malloc(logLength);
|
||||
glGetShaderInfoLog(fpShader, logLength, &logLength, log);
|
||||
log_info("Frag Shader compile log:\n%s", log);
|
||||
free(log);
|
||||
}
|
||||
|
||||
glAttachShader(program, fpShader);
|
||||
glGetShaderiv(fpShader, GL_COMPILE_STATUS, &status);
|
||||
if (status == 0)
|
||||
{
|
||||
log_error("Failed to compile frag shader:\n\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
glLinkProgram(program);
|
||||
glGetProgramiv(program, GL_INFO_LOG_LENGTH, &logLength);
|
||||
if (logLength > 0) {
|
||||
GLchar *log = (GLchar*)malloc(logLength);
|
||||
glGetProgramInfoLog(program, logLength, &logLength, log);
|
||||
log_info("Program link log:\n%s", log);
|
||||
free(log);
|
||||
}
|
||||
|
||||
glGetProgramiv(program, GL_LINK_STATUS, &status);
|
||||
if (status == 0)
|
||||
{
|
||||
log_error("Failed to link program\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
glValidateProgram(program);
|
||||
glGetProgramiv(program, GL_INFO_LOG_LENGTH, &logLength);
|
||||
if (logLength > 0) {
|
||||
GLchar *log = (GLchar*)malloc(logLength);
|
||||
glGetProgramInfoLog(program, logLength, &logLength, log);
|
||||
log_info("Program validate log:\n%s", log);
|
||||
free(log);
|
||||
}
|
||||
|
||||
glGetProgramiv(program, GL_VALIDATE_STATUS, &status);
|
||||
if (status == 0)
|
||||
{
|
||||
log_error("Failed to validate program\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
*posLoc = glGetAttribLocation(program, "inPosition");
|
||||
*colLoc = glGetAttribLocation(program, "inColor");
|
||||
|
||||
return program;
|
||||
}
|
||||
|
||||
void destroyShaderProgram(GLuint program)
|
||||
{
|
||||
GLuint shaders[2];
|
||||
GLsizei count;
|
||||
glUseProgram(0);
|
||||
glGetAttachedShaders(program, 2, &count, shaders);
|
||||
int i;
|
||||
for(i = 0; i < count; i++)
|
||||
{
|
||||
glDetachShader(program, shaders[i]);
|
||||
glDeleteShader(shaders[i]);
|
||||
}
|
||||
glDeleteProgram(program);
|
||||
}
|
||||
|
||||
// This function queues up and runs the above CL kernel that writes the vertex data
|
||||
cl_int run_cl_kernel( cl_kernel kernel, cl_command_queue queue, cl_mem stream0, cl_mem stream1,
|
||||
cl_int rowIdx, cl_event fenceEvent, size_t numThreads )
|
||||
{
|
||||
cl_int error = clSetKernelArg( kernel, 3, sizeof( rowIdx ), &rowIdx );
|
||||
test_error( error, "Unable to set kernel arguments" );
|
||||
|
||||
clEventWrapper acqEvent1, acqEvent2, kernEvent, relEvent1, relEvent2;
|
||||
int numEvents = ( fenceEvent != NULL ) ? 1 : 0;
|
||||
cl_event *fence_evt = ( fenceEvent != NULL ) ? &fenceEvent : NULL;
|
||||
|
||||
error = (*clEnqueueAcquireGLObjects_ptr)( queue, 1, &stream0, numEvents, fence_evt, &acqEvent1 );
|
||||
test_error( error, "Unable to acquire GL obejcts");
|
||||
error = (*clEnqueueAcquireGLObjects_ptr)( queue, 1, &stream1, numEvents, fence_evt, &acqEvent2 );
|
||||
test_error( error, "Unable to acquire GL obejcts");
|
||||
|
||||
cl_event evts[ 2 ] = { acqEvent1, acqEvent2 };
|
||||
|
||||
error = clEnqueueNDRangeKernel( queue, kernel, 1, NULL, &numThreads, NULL, 2, evts, &kernEvent );
|
||||
test_error( error, "Unable to execute test kernel" );
|
||||
|
||||
error = (*clEnqueueReleaseGLObjects_ptr)( queue, 1, &stream0, 1, &kernEvent, &relEvent1 );
|
||||
test_error(error, "clEnqueueReleaseGLObjects failed");
|
||||
error = (*clEnqueueReleaseGLObjects_ptr)( queue, 1, &stream1, 1, &kernEvent, &relEvent2 );
|
||||
test_error(error, "clEnqueueReleaseGLObjects failed");
|
||||
|
||||
evts[ 0 ] = relEvent1;
|
||||
evts[ 1 ] = relEvent2;
|
||||
error = clWaitForEvents( 2, evts );
|
||||
test_error( error, "Unable to wait for release events" );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
class RunThread : public genericThread
|
||||
{
|
||||
public:
|
||||
|
||||
cl_kernel mKernel;
|
||||
cl_command_queue mQueue;
|
||||
cl_mem mStream0, mStream1;
|
||||
cl_int mRowIdx;
|
||||
cl_event mFenceEvent;
|
||||
size_t mNumThreads;
|
||||
|
||||
RunThread( cl_kernel kernel, cl_command_queue queue, cl_mem stream0, cl_mem stream1, size_t numThreads )
|
||||
: mKernel( kernel ), mQueue( queue ), mStream0( stream0 ), mStream1( stream1 ), mNumThreads( numThreads )
|
||||
{
|
||||
}
|
||||
|
||||
void SetRunData( cl_int rowIdx, cl_event fenceEvent )
|
||||
{
|
||||
mRowIdx = rowIdx;
|
||||
mFenceEvent = fenceEvent;
|
||||
}
|
||||
|
||||
virtual void * IRun( void )
|
||||
{
|
||||
cl_int error = run_cl_kernel( mKernel, mQueue, mStream0, mStream1, mRowIdx, mFenceEvent, mNumThreads );
|
||||
return (void *)error;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
int test_fence_sync_single( cl_device_id device, cl_context context, cl_command_queue queue, bool separateThreads, GLint rend_vs, GLint read_vs, cl_device_id rend_device )
|
||||
{
|
||||
int error;
|
||||
const int framebufferSize = 512;
|
||||
cl_platform_id platform_id = NULL;
|
||||
|
||||
if( !is_extension_available( device, "cl_khr_gl_event" ) )
|
||||
{
|
||||
log_info( "NOTE: cl_khr_gl_event extension not present on this device; skipping fence sync test\n" );
|
||||
return 0;
|
||||
}
|
||||
|
||||
error = clGetDeviceInfo(device,
|
||||
CL_DEVICE_PLATFORM,
|
||||
sizeof(platform_id),
|
||||
&platform_id,
|
||||
NULL);
|
||||
if(error)
|
||||
{
|
||||
return error;
|
||||
}
|
||||
|
||||
clCreateEventFromGLsyncKHR_ptr = \
|
||||
(clCreateEventFromGLsyncKHR_fn)clGetExtensionFunctionAddressForPlatform(platform_id,"clCreateEventFromGLsyncKHR");
|
||||
if( clCreateEventFromGLsyncKHR_ptr == NULL )
|
||||
{
|
||||
log_error( "ERROR: Unable to run fence_sync test (clCreateEventFromGLsyncKHR function not discovered!)\n" );
|
||||
clCreateEventFromGLsyncKHR_ptr = \
|
||||
(clCreateEventFromGLsyncKHR_fn)clGetExtensionFunctionAddressForPlatform(platform_id, "clCreateEventFromGLsyncAPPLE");
|
||||
return -1;
|
||||
}
|
||||
|
||||
#ifdef USING_ARB_sync
|
||||
char *gl_version_str = (char*)glGetString( GL_VERSION );
|
||||
float glCoreVersion;
|
||||
sscanf(gl_version_str, "%f", &glCoreVersion);
|
||||
if( glCoreVersion < 3.0f )
|
||||
{
|
||||
log_info( "OpenGL version %f does not support fence/sync! Skipping test.\n", glCoreVersion );
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef __APPLE__
|
||||
CGLContextObj currCtx = CGLGetCurrentContext();
|
||||
CGLPixelFormatObj pixFmt = CGLGetPixelFormat(currCtx);
|
||||
GLint val, screen;
|
||||
CGLGetVirtualScreen(currCtx, &screen);
|
||||
CGLDescribePixelFormat(pixFmt, screen, kCGLPFAOpenGLProfile, &val);
|
||||
if(val != kCGLOGLPVersion_3_2_Core)
|
||||
{
|
||||
log_error( "OpenGL context was not created with OpenGL version >= 3.0 profile even though platform supports it"
|
||||
"OpenGL profile %f does not support fence/sync! Skipping test.\n", glCoreVersion );
|
||||
return -1;
|
||||
}
|
||||
#else
|
||||
// Need platform specific way to query if current GL context was created with 3.x profile
|
||||
log_error( "ERROR: not implemented\n\n" );
|
||||
return -1;
|
||||
#endif
|
||||
|
||||
InitSyncFns();
|
||||
#endif
|
||||
|
||||
#ifdef __APPLE__
|
||||
CGLSetVirtualScreen(CGLGetCurrentContext(), rend_vs);
|
||||
#else
|
||||
// Need platform specific way to set device with id rend_vs the current
|
||||
// rendering target
|
||||
log_error( "ERROR: not implemented\n\n" );
|
||||
return -1;
|
||||
#endif
|
||||
|
||||
GLint posLoc, colLoc;
|
||||
GLuint shaderprogram = createShaderProgram(&posLoc, &colLoc);
|
||||
if(!shaderprogram)
|
||||
{
|
||||
log_error("Failed to create shader program\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
float l = 0.0f; float r = framebufferSize;
|
||||
float b = 0.0f; float t = framebufferSize;
|
||||
|
||||
float projMatrix[16] = { 2.0f/(r-l), 0.0f, 0.0f, 0.0f,
|
||||
0.0f, 2.0f/(t-b), 0.0f, 0.0f,
|
||||
0.0f, 0.0f, -1.0f, 0.0f,
|
||||
-(r+l)/(r-l), -(t+b)/(t-b), 0.0f, 1.0f
|
||||
};
|
||||
|
||||
glUseProgram(shaderprogram);
|
||||
GLuint projMatLoc = glGetUniformLocation(shaderprogram, "projMatrix");
|
||||
glUniformMatrix4fv(projMatLoc, 1, 0, projMatrix);
|
||||
glUseProgram(0);
|
||||
|
||||
// Note: the framebuffer is just the target to verify our results against, so we don't
|
||||
// really care to go through all the possible formats in this case
|
||||
glFramebufferWrapper glFramebuffer;
|
||||
glRenderbufferWrapper glRenderbuffer;
|
||||
error = CreateGLRenderbufferRaw( framebufferSize, 128, GL_COLOR_ATTACHMENT0_EXT,
|
||||
GL_RGBA, GL_UNSIGNED_BYTE,
|
||||
&glFramebuffer, &glRenderbuffer );
|
||||
if( error != 0 )
|
||||
return error;
|
||||
|
||||
// GLuint vao;
|
||||
// glGenVertexArrays(1, &vao);
|
||||
// glBindVertexArray(vao);
|
||||
|
||||
glBufferWrapper vtxBuffer, colorBuffer;
|
||||
glGenBuffers( 1, &vtxBuffer );
|
||||
glGenBuffers( 1, &colorBuffer );
|
||||
|
||||
const int numHorizVertices = ( framebufferSize * 64 ) + 1;
|
||||
|
||||
glBindBuffer( GL_ARRAY_BUFFER, vtxBuffer );
|
||||
glBufferData( GL_ARRAY_BUFFER, sizeof( GLfloat ) * numHorizVertices * 2 * 4, NULL, GL_STATIC_DRAW );
|
||||
|
||||
glBindBuffer( GL_ARRAY_BUFFER, colorBuffer );
|
||||
glBufferData( GL_ARRAY_BUFFER, sizeof( GLfloat ) * numHorizVertices * 2 * 4, NULL, GL_STATIC_DRAW );
|
||||
|
||||
clProgramWrapper program;
|
||||
clKernelWrapper kernel;
|
||||
clMemWrapper streams[ 2 ];
|
||||
|
||||
if( create_single_kernel_helper( context, &program, &kernel, 1, updateBuffersKernel, "update" ) )
|
||||
return -1;
|
||||
|
||||
|
||||
streams[ 0 ] = (*clCreateFromGLBuffer_ptr)( context, CL_MEM_READ_WRITE, vtxBuffer, &error );
|
||||
test_error( error, "Unable to create CL buffer from GL vertex buffer" );
|
||||
|
||||
streams[ 1 ] = (*clCreateFromGLBuffer_ptr)( context, CL_MEM_READ_WRITE, colorBuffer, &error );
|
||||
test_error( error, "Unable to create CL buffer from GL color buffer" );
|
||||
|
||||
error = clSetKernelArg( kernel, 0, sizeof( streams[ 0 ] ), &streams[ 0 ] );
|
||||
test_error( error, "Unable to set kernel arguments" );
|
||||
|
||||
error = clSetKernelArg( kernel, 1, sizeof( streams[ 1 ] ), &streams[ 1 ] );
|
||||
test_error( error, "Unable to set kernel arguments" );
|
||||
|
||||
cl_int horizWrap = (cl_int)framebufferSize;
|
||||
error = clSetKernelArg( kernel, 2, sizeof( horizWrap ), &horizWrap );
|
||||
test_error( error, "Unable to set kernel arguments" );
|
||||
|
||||
glViewport( 0, 0, framebufferSize, framebufferSize );
|
||||
glClearColor( 0, 0, 0, 0 );
|
||||
glClear( GL_COLOR_BUFFER_BIT );
|
||||
glClear( GL_DEPTH_BUFFER_BIT );
|
||||
glDisable( GL_DEPTH_TEST );
|
||||
glEnable( GL_BLEND );
|
||||
glBlendFunc( GL_ONE, GL_ONE );
|
||||
|
||||
clEventWrapper fenceEvent;
|
||||
GLsync glFence = 0;
|
||||
|
||||
// Do a loop through 8 different horizontal stripes against the framebuffer
|
||||
RunThread thread( kernel, queue, streams[ 0 ], streams[ 1 ], (size_t)numHorizVertices );
|
||||
|
||||
for( int i = 0; i < 8; i++ )
|
||||
{
|
||||
// if current rendering device is not the compute device and
|
||||
// separateThreads == false which means compute is going on same
|
||||
// thread and we are using implicit synchronization (no GLSync obj used)
|
||||
// then glFlush by clEnqueueAcquireGLObject is not sufficient ... we need
|
||||
// to wait for rendering to finish on other device before CL can start
|
||||
// writing to CL/GL shared mem objects. When separateThreads is true i.e.
|
||||
// we are using GLSync obj to synchronize then we dont need to call glFinish
|
||||
// here since CL should wait for rendering on other device before this
|
||||
// GLSync object to finish before it starts writing to shared mem object.
|
||||
// Also rend_device == compute_device no need to call glFinish
|
||||
if(rend_device != device && !separateThreads)
|
||||
glFinish();
|
||||
|
||||
if( separateThreads )
|
||||
{
|
||||
thread.SetRunData( (cl_int)i, fenceEvent );
|
||||
thread.Start();
|
||||
|
||||
error = (cl_int)(size_t)thread.Join();
|
||||
}
|
||||
else
|
||||
{
|
||||
error = run_cl_kernel( kernel, queue, streams[ 0 ], streams[ 1 ], (cl_int)i, fenceEvent, (size_t)numHorizVertices );
|
||||
}
|
||||
test_error( error, "Unable to run CL kernel" );
|
||||
|
||||
glUseProgram(shaderprogram);
|
||||
glEnableVertexAttribArray(posLoc);
|
||||
glEnableVertexAttribArray(colLoc);
|
||||
glBindBuffer( GL_ARRAY_BUFFER, vtxBuffer );
|
||||
glVertexAttribPointer(posLoc, 4, GL_FLOAT, GL_FALSE, 4*sizeof(GLfloat), 0);
|
||||
glBindBuffer( GL_ARRAY_BUFFER, colorBuffer );
|
||||
glVertexAttribPointer(colLoc, 4, GL_FLOAT, GL_FALSE, 4*sizeof(GLfloat), 0);
|
||||
glBindBuffer( GL_ARRAY_BUFFER, 0 );
|
||||
|
||||
glDrawArrays( GL_TRIANGLE_STRIP, 0, numHorizVertices * 2 );
|
||||
|
||||
glDisableVertexAttribArray(posLoc);
|
||||
glDisableVertexAttribArray(colLoc);
|
||||
glUseProgram(0);
|
||||
|
||||
if( separateThreads )
|
||||
{
|
||||
// If we're on the same thread, then we're testing implicit syncing, so we
|
||||
// don't need the actual fence code
|
||||
if( fenceEvent != NULL )
|
||||
{
|
||||
clReleaseEvent( fenceEvent );
|
||||
glDeleteSyncFunc( glFence );
|
||||
}
|
||||
|
||||
glFence = glFenceSyncFunc( GL_SYNC_GPU_COMMANDS_COMPLETE, 0 );
|
||||
fenceEvent = clCreateEventFromGLsyncKHR_ptr( context, glFence, &error );
|
||||
test_error( error, "Unable to create CL event from GL fence" );
|
||||
|
||||
// in case of explicit synchronization, we just wait for the sync object to complete
|
||||
// in clEnqueueAcquireGLObject but we dont flush. Its application's responsibility
|
||||
// to flush on the context on which glSync is created
|
||||
glFlush();
|
||||
}
|
||||
}
|
||||
|
||||
if( glFence != 0 )
|
||||
// Don't need the final release for fenceEvent, because the wrapper will take care of that
|
||||
glDeleteSyncFunc( glFence );
|
||||
|
||||
#ifdef __APPLE__
|
||||
CGLSetVirtualScreen(CGLGetCurrentContext(), read_vs);
|
||||
#else
|
||||
// Need platform specific code to set the current rendering device (OpenGL target)
|
||||
// to device with id read_vs so that next glReadPixels get submitted to that device
|
||||
log_error( "ERROR: not implemented\n\n" );
|
||||
return -1;
|
||||
#endif
|
||||
// Grab the contents of the final framebuffer
|
||||
BufferOwningPtr<char> resultData( ReadGLRenderbuffer( glFramebuffer, glRenderbuffer,
|
||||
GL_COLOR_ATTACHMENT0_EXT,
|
||||
GL_RGBA8_OES, GL_UNSIGNED_BYTE, GL_RGBA, GL_UNSIGNED_BYTE, kUChar,
|
||||
framebufferSize, 128 ) );
|
||||
|
||||
// Check the contents now. We should end up with solid color bands 32 pixels high and the
|
||||
// full width of the framebuffer, at values (128,128,128) due to the additive blending
|
||||
for( int i = 0; i < 8; i++ )
|
||||
{
|
||||
for( int y = 0; y < 4; y++ )
|
||||
{
|
||||
// Note: coverage will be double because the 63-0 triangle overwrites again at the end of the pass
|
||||
cl_uchar valA = ( ( ( i + 1 ) & 1 ) ) * numHorizVertices * 2 / framebufferSize;
|
||||
cl_uchar valB = ( ( ( i + 1 ) & 2 ) >> 1 ) * numHorizVertices * 2 / framebufferSize;
|
||||
cl_uchar valC = ( ( ( i + 1 ) & 4 ) >> 2 ) * numHorizVertices * 2 / framebufferSize;
|
||||
|
||||
cl_uchar *row = (cl_uchar *)&resultData[ ( i * 16 + y ) * framebufferSize * 4 ];
|
||||
for( int x = 0; x < ( framebufferSize - 1 ) - 1; x++ )
|
||||
{
|
||||
if( ( row[ x * 4 ] != valA ) || ( row[ x * 4 + 1 ] != valB ) ||
|
||||
( row[ x * 4 + 2 ] != valC ) )
|
||||
{
|
||||
log_error( "ERROR: Output framebuffer did not validate!\n" );
|
||||
DumpGLBuffer( GL_UNSIGNED_BYTE, framebufferSize, 128, resultData );
|
||||
log_error( "RUNS:\n" );
|
||||
uint32_t *p = (uint32_t *)(char *)resultData;
|
||||
size_t a = 0;
|
||||
for( size_t t = 1; t < framebufferSize * framebufferSize; t++ )
|
||||
{
|
||||
if( p[ a ] != 0 )
|
||||
{
|
||||
if( p[ t ] == 0 )
|
||||
{
|
||||
log_error( "RUN: %ld to %ld (%d,%d to %d,%d) 0x%08x\n", a, t - 1,
|
||||
(int)( a % framebufferSize ), (int)( a / framebufferSize ),
|
||||
(int)( ( t - 1 ) % framebufferSize ), (int)( ( t - 1 ) / framebufferSize ),
|
||||
p[ a ] );
|
||||
a = t;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( p[ t ] != 0 )
|
||||
{
|
||||
a = t;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
glDeleteBuffers( 1, &vtxBuffer );
|
||||
glDeleteBuffers( 1, &colorBuffer );
|
||||
destroyShaderProgram(shaderprogram);
|
||||
// glDeleteVertexArrays(1, &vao);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int test_fence_sync( cl_device_id device, cl_context context, cl_command_queue queue, int numElements )
|
||||
{
|
||||
GLint vs_count = 0;
|
||||
cl_device_id *device_list = NULL;
|
||||
|
||||
if( !is_extension_available( device, "cl_khr_gl_event" ) )
|
||||
{
|
||||
log_info( "NOTE: cl_khr_gl_event extension not present on this device; skipping fence sync test\n" );
|
||||
return 0;
|
||||
}
|
||||
#ifdef __APPLE__
|
||||
CGLContextObj ctx = CGLGetCurrentContext();
|
||||
CGLPixelFormatObj pix = CGLGetPixelFormat(ctx);
|
||||
CGLError err = CGLDescribePixelFormat(pix, 0, kCGLPFAVirtualScreenCount, &vs_count);
|
||||
|
||||
device_list = (cl_device_id *) malloc(sizeof(cl_device_id)*vs_count);
|
||||
clGetGLContextInfoAPPLE(context, ctx, CL_CGL_DEVICES_FOR_SUPPORTED_VIRTUAL_SCREENS_APPLE, sizeof(cl_device_id)*vs_count, device_list, NULL);
|
||||
#else
|
||||
// Need platform specific way of getting devices from CL context to which OpenGL can render
|
||||
// If not available it can be replaced with clGetContextInfo with CL_CONTEXT_DEVICES
|
||||
log_error( "ERROR: not implemented\n\n" );
|
||||
return -1;
|
||||
#endif
|
||||
|
||||
GLint rend_vs, read_vs;
|
||||
int error = 0;
|
||||
int any_failed = 0;
|
||||
|
||||
// Loop through all the devices capable to OpenGL rendering
|
||||
// and set them as current rendering target
|
||||
for(rend_vs = 0; rend_vs < vs_count; rend_vs++)
|
||||
{
|
||||
// Loop through all the devices and set them as current
|
||||
// compute target
|
||||
for(read_vs = 0; read_vs < vs_count; read_vs++)
|
||||
{
|
||||
cl_device_id rend_device = device_list[rend_vs], read_device = device_list[read_vs];
|
||||
char rend_name[200], read_name[200];
|
||||
|
||||
clGetDeviceInfo(rend_device, CL_DEVICE_NAME, sizeof(rend_name), rend_name, NULL);
|
||||
clGetDeviceInfo(read_device, CL_DEVICE_NAME, sizeof(read_name), read_name, NULL);
|
||||
|
||||
log_info("Rendering on: %s, read back on: %s\n", rend_name, read_name);
|
||||
error = test_fence_sync_single( device, context, queue, false, rend_vs, read_vs, rend_device );
|
||||
any_failed |= error;
|
||||
if( error != 0 )
|
||||
log_error( "ERROR: Implicit syncing with GL sync events failed!\n\n" );
|
||||
else
|
||||
log_info("Implicit syncing Passed\n");
|
||||
|
||||
error = test_fence_sync_single( device, context, queue, true, rend_vs, read_vs, rend_device );
|
||||
any_failed |= error;
|
||||
if( error != 0 )
|
||||
log_error( "ERROR: Explicit syncing with GL sync events failed!\n\n" );
|
||||
else
|
||||
log_info("Explicit syncing Passed\n");
|
||||
}
|
||||
}
|
||||
|
||||
free(device_list);
|
||||
|
||||
return any_failed;
|
||||
}
|
||||
749
test_conformance/gles/test_images_2D.cpp
Normal file
749
test_conformance/gles/test_images_2D.cpp
Normal file
@@ -0,0 +1,749 @@
|
||||
//
|
||||
// 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 "gl_headers.h"
|
||||
|
||||
extern "C" { extern cl_uint gRandomSeed; }
|
||||
|
||||
static const char *imageReadKernelPattern =
|
||||
"#pragma OPENCL EXTENSION cl_khr_fp16 : enable\n" /* added support for half floats */
|
||||
"__kernel void sample_test( read_only image2d_t source, sampler_t sampler, __global %s4 *results )\n"
|
||||
"{\n"
|
||||
" int tidX = get_global_id(0);\n"
|
||||
" int tidY = get_global_id(1);\n"
|
||||
" results[ tidY * get_image_width( source ) + tidX ] = read_image%s( source, sampler, (int2)( tidX, tidY ) );\n"
|
||||
"}\n";
|
||||
|
||||
static const char *imageWriteKernelPattern =
|
||||
"#pragma OPENCL EXTENSION cl_khr_fp16 : enable\n" /* added support for half floats */
|
||||
"__kernel void sample_test( __global %s4 *source, write_only image2d_t dest )\n"
|
||||
"{\n"
|
||||
" int tidX = get_global_id(0);\n"
|
||||
" int tidY = get_global_id(1);\n"
|
||||
" uint index = tidY * get_image_width( dest ) + tidX;\n"
|
||||
" %s4 value = source[index];\n"
|
||||
" write_image%s( dest, (int2)( tidX, tidY ), %s(value));\n"
|
||||
"}\n";
|
||||
|
||||
int test_cl_image_read( cl_context context, cl_command_queue queue, cl_mem clImage,
|
||||
size_t imageWidth, size_t imageHeight, cl_image_format *outFormat, ExplicitType *outType, void **outResultBuffer )
|
||||
{
|
||||
clProgramWrapper program;
|
||||
clKernelWrapper kernel;
|
||||
clMemWrapper outStream;
|
||||
|
||||
int error;
|
||||
size_t threads[ 2 ], localThreads[ 2 ];
|
||||
char kernelSource[10240];
|
||||
char *programPtr;
|
||||
|
||||
|
||||
// Determine data type and format that CL came up with
|
||||
error = clGetImageInfo( clImage, CL_IMAGE_FORMAT, sizeof( cl_image_format ), outFormat, NULL );
|
||||
test_error( error, "Unable to get CL image format" );
|
||||
|
||||
/* Create the source */
|
||||
*outType = get_read_kernel_type( outFormat );
|
||||
size_t channelSize = get_explicit_type_size( *outType );
|
||||
|
||||
sprintf( kernelSource, imageReadKernelPattern, get_explicit_type_name( *outType ), get_kernel_suffix( outFormat ) );
|
||||
|
||||
#ifdef GLES_DEBUG
|
||||
log_info("-- start cl image read kernel --\n");
|
||||
log_info("%s", kernelSource);
|
||||
log_info("-- end cl image read kernel --\n");
|
||||
#endif
|
||||
|
||||
/* Create kernel */
|
||||
programPtr = kernelSource;
|
||||
if( create_single_kernel_helper( context, &program, &kernel, 1, (const char **)&programPtr, "sample_test" ) )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
// Create a vanilla output buffer
|
||||
outStream = clCreateBuffer( context, CL_MEM_READ_WRITE, channelSize * 4 * imageWidth * imageHeight, NULL, &error );
|
||||
test_error( error, "Unable to create output buffer" );
|
||||
|
||||
|
||||
/* Assign streams and execute */
|
||||
clSamplerWrapper sampler = clCreateSampler( context, CL_FALSE, CL_ADDRESS_NONE, CL_FILTER_NEAREST, &error );
|
||||
test_error( error, "Unable to create sampler" );
|
||||
|
||||
error = clSetKernelArg( kernel, 0, sizeof( clImage ), &clImage );
|
||||
test_error( error, "Unable to set kernel arguments" );
|
||||
error = clSetKernelArg( kernel, 1, sizeof( sampler ), &sampler );
|
||||
test_error( error, "Unable to set kernel arguments" );
|
||||
error = clSetKernelArg( kernel, 2, sizeof( outStream ), &outStream );
|
||||
test_error( error, "Unable to set kernel arguments" );
|
||||
|
||||
glFlush();
|
||||
|
||||
error = (*clEnqueueAcquireGLObjects_ptr)( queue, 1, &clImage, 0, NULL, NULL);
|
||||
test_error( error, "Unable to acquire GL obejcts");
|
||||
|
||||
/* Run the kernel */
|
||||
threads[ 0 ] = imageWidth;
|
||||
threads[ 1 ] = imageHeight;
|
||||
|
||||
error = get_max_common_2D_work_group_size( context, kernel, threads, localThreads );
|
||||
test_error( error, "Unable to get work group size to use" );
|
||||
|
||||
error = clEnqueueNDRangeKernel( queue, kernel, 2, NULL, threads, localThreads, 0, NULL, NULL );
|
||||
test_error( error, "Unable to execute test kernel" );
|
||||
|
||||
|
||||
error = (*clEnqueueReleaseGLObjects_ptr)( queue, 1, &clImage, 0, NULL, NULL );
|
||||
test_error(error, "clEnqueueReleaseGLObjects failed");
|
||||
|
||||
// Read results from the CL buffer
|
||||
*outResultBuffer = malloc(channelSize * 4 * imageWidth * imageHeight);
|
||||
error = clEnqueueReadBuffer( queue, outStream, CL_TRUE, 0, channelSize * 4 * imageWidth * imageHeight,
|
||||
*outResultBuffer, 0, NULL, NULL );
|
||||
test_error( error, "Unable to read output CL buffer!" );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int test_image_read( cl_context context, cl_command_queue queue, GLenum glTarget, GLuint glTexture,
|
||||
size_t imageWidth, size_t imageHeight, cl_image_format *outFormat, ExplicitType *outType, void **outResultBuffer )
|
||||
{
|
||||
// Create a CL image from the supplied GL texture
|
||||
int error;
|
||||
clMemWrapper image = (*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" );
|
||||
#ifndef GL_ES_VERSION_2_0
|
||||
GLint fmt;
|
||||
glGetTexLevelParameteriv( glTarget, 0, GL_TEXTURE_INTERNAL_FORMAT, &fmt );
|
||||
log_error( " Supplied GL texture was baseformat %s and internalformat %s\n", GetGLBaseFormatName( fmt ), GetGLFormatName( fmt ) );
|
||||
#endif
|
||||
return error;
|
||||
}
|
||||
|
||||
return test_cl_image_read( context, queue, image, imageWidth, imageHeight, outFormat, outType, outResultBuffer );
|
||||
}
|
||||
|
||||
int test_image_format_read( cl_context context, cl_command_queue queue,
|
||||
size_t width, size_t height, GLenum target,
|
||||
GLenum format, GLenum internalFormat,
|
||||
GLenum glType, ExplicitType type, MTdata d )
|
||||
{
|
||||
int error;
|
||||
|
||||
|
||||
// Create the GL texture
|
||||
glTextureWrapper glTexture;
|
||||
void *tmp = CreateGLTexture2D( width, height, target, format, internalFormat, glType, type, &glTexture, &error, true, d );
|
||||
BufferOwningPtr<char> inputBuffer(tmp);
|
||||
if( error != 0 )
|
||||
{
|
||||
return error;
|
||||
}
|
||||
|
||||
/* skip formats not supported by OpenGL */
|
||||
if(!tmp)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Run and get the results
|
||||
cl_image_format clFormat;
|
||||
ExplicitType actualType;
|
||||
char *outBuffer;
|
||||
error = test_image_read( context, queue, target, glTexture, width, height, &clFormat, &actualType, (void **)&outBuffer );
|
||||
if( error != 0 )
|
||||
return error;
|
||||
BufferOwningPtr<char> actualResults(outBuffer);
|
||||
|
||||
log_info( "- Read [%4d x %4d] : GL Texture : %s : %s : %s => CL Image : %s : %s \n", (int)width, (int)height,
|
||||
GetGLFormatName( format ), GetGLFormatName( internalFormat ), GetGLTypeName( glType),
|
||||
GetChannelOrderName( clFormat.image_channel_order ), GetChannelTypeName( clFormat.image_channel_data_type ));
|
||||
|
||||
// We have to convert our input buffer to the returned type, so we can validate.
|
||||
BufferOwningPtr<char> convertedInputs(convert_to_expected( inputBuffer, width * height, type, actualType ));
|
||||
|
||||
// Now we validate
|
||||
int valid = 0;
|
||||
if(convertedInputs) {
|
||||
if( actualType == kFloat )
|
||||
valid = validate_float_results( convertedInputs, actualResults, width, height );
|
||||
else
|
||||
valid = validate_integer_results( convertedInputs, actualResults, width, height, get_explicit_type_size( actualType ) );
|
||||
}
|
||||
|
||||
return valid;
|
||||
}
|
||||
|
||||
int test_images_read( cl_device_id device, cl_context context, cl_command_queue queue, int numElements )
|
||||
{
|
||||
GLenum targets[] =
|
||||
#ifdef GL_ES_VERSION_2_0
|
||||
{ GL_TEXTURE_2D };
|
||||
#else // GL_ES_VERSION_2_0
|
||||
{ GL_TEXTURE_2D, GL_TEXTURE_RECTANGLE_EXT };
|
||||
#endif // GL_ES_VERSION_2_0
|
||||
|
||||
struct {
|
||||
GLenum internal;
|
||||
GLenum format;
|
||||
GLenum datatype;
|
||||
ExplicitType type;
|
||||
|
||||
} formats[] = {
|
||||
{ GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, kUChar },
|
||||
{ GL_RGBA, GL_RGBA, GL_UNSIGNED_SHORT, kUShort },
|
||||
{ GL_RGBA, GL_RGBA, GL_FLOAT, kFloat },
|
||||
};
|
||||
|
||||
size_t fmtIdx, tgtIdx;
|
||||
int error = 0;
|
||||
size_t iter = 6;
|
||||
RandomSeed seed(gRandomSeed );
|
||||
|
||||
// Check if images are supported
|
||||
if (checkForImageSupport(device)) {
|
||||
log_info("Device does not support images. 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( tgtIdx = 0; tgtIdx < sizeof( targets ) / sizeof( targets[ 0 ] ); tgtIdx++ )
|
||||
{
|
||||
size_t i;
|
||||
|
||||
log_info( "Testing image read for GL format %s : %s : %s : %s\n",
|
||||
GetGLTargetName( targets[ tgtIdx ] ),
|
||||
GetGLFormatName( formats[ fmtIdx ].internal ),
|
||||
GetGLBaseFormatName( formats[ fmtIdx ].format ),
|
||||
GetGLTypeName( formats[ fmtIdx ].datatype ) );
|
||||
|
||||
for( i = 0; i < iter; i++ )
|
||||
{
|
||||
size_t width = random_in_range( 16, 512, seed );
|
||||
size_t height = random_in_range( 16, 512, seed );
|
||||
|
||||
if( test_image_format_read( context, queue, width, height,
|
||||
targets[ tgtIdx ],
|
||||
formats[ fmtIdx ].format,
|
||||
formats[ fmtIdx ].internal,
|
||||
formats[ fmtIdx ].datatype,
|
||||
formats[ fmtIdx ].type, seed ) )
|
||||
{
|
||||
log_error( "ERROR: Image read test failed for %s : %s : %s : %s\n\n",
|
||||
GetGLTargetName( targets[ tgtIdx ] ),
|
||||
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: Image read for GL format %s : %s : %s : %s\n\n",
|
||||
GetGLTargetName( targets[ tgtIdx ] ),
|
||||
GetGLFormatName( formats[ fmtIdx ].internal ),
|
||||
GetGLBaseFormatName( formats[ fmtIdx ].format ),
|
||||
GetGLTypeName( formats[ fmtIdx ].datatype ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
int test_images_read_cube( cl_device_id device, cl_context context, cl_command_queue queue, int numElements )
|
||||
{
|
||||
GLenum targets[] = {
|
||||
GL_TEXTURE_CUBE_MAP_POSITIVE_X,
|
||||
GL_TEXTURE_CUBE_MAP_POSITIVE_Y,
|
||||
GL_TEXTURE_CUBE_MAP_POSITIVE_Z,
|
||||
GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
|
||||
GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,
|
||||
GL_TEXTURE_CUBE_MAP_NEGATIVE_Z };
|
||||
|
||||
struct {
|
||||
GLenum internal;
|
||||
GLenum format;
|
||||
GLenum datatype;
|
||||
ExplicitType type;
|
||||
|
||||
} formats[] = {
|
||||
#ifdef GL_ES_VERSION_2_0
|
||||
{ GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, kUChar },
|
||||
{ GL_RGBA, GL_RGBA, GL_UNSIGNED_SHORT, kUShort },
|
||||
// XXX add others
|
||||
#else // GL_ES_VERSION_2_0
|
||||
{ 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 },
|
||||
{ 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 },
|
||||
{ GL_RGBA32F_ARB, GL_RGBA, GL_FLOAT, kFloat }
|
||||
#endif
|
||||
};
|
||||
|
||||
size_t sizes[] = { 16, 32, 64, 128, 256, 512, 1024, 2048, 4096 };
|
||||
|
||||
size_t fmtIdx, tgtIdx;
|
||||
int error = 0;
|
||||
size_t iter = 6;
|
||||
RandomSeed seed(gRandomSeed);
|
||||
|
||||
// Check if images are supported
|
||||
if (checkForImageSupport(device)) {
|
||||
log_info("Device does not support images. 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( tgtIdx = 0; tgtIdx < sizeof( targets ) / sizeof( targets[ 0 ] ); tgtIdx++ )
|
||||
{
|
||||
size_t i;
|
||||
|
||||
log_info( "Testing image read cubemap for GL format %s : %s : %s : %s\n\n",
|
||||
GetGLTargetName( targets[ tgtIdx ] ),
|
||||
GetGLFormatName( formats[ fmtIdx ].internal ),
|
||||
GetGLBaseFormatName( formats[ fmtIdx ].format ),
|
||||
GetGLTypeName( formats[ fmtIdx ].datatype ) );
|
||||
|
||||
for( i = 0; i < iter; i++ )
|
||||
{
|
||||
if( test_image_format_read( context, queue, sizes[i], sizes[i],
|
||||
targets[ tgtIdx ],
|
||||
formats[ fmtIdx ].format,
|
||||
formats[ fmtIdx ].internal,
|
||||
formats[ fmtIdx ].datatype,
|
||||
formats[ fmtIdx ].type, seed ) )
|
||||
{
|
||||
log_error( "ERROR: Image read cubemap test failed for %s : %s : %s : %s\n\n",
|
||||
GetGLTargetName( targets[ tgtIdx ] ),
|
||||
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: Image read cubemap for GL format %s : %s : %s : %s\n\n",
|
||||
GetGLTargetName( targets[ tgtIdx ] ),
|
||||
GetGLFormatName( formats[ fmtIdx ].internal ),
|
||||
GetGLBaseFormatName( formats[ fmtIdx ].format ),
|
||||
GetGLTypeName( formats[ fmtIdx ].datatype ) );
|
||||
|
||||
}
|
||||
else
|
||||
break; // Skip other cube map targets; they're unlikely to pass either
|
||||
}
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
#pragma mark -------------------- Write tests -------------------------
|
||||
|
||||
|
||||
int test_cl_image_write( cl_context context, cl_command_queue queue, cl_mem clImage,
|
||||
size_t imageWidth, size_t imageHeight, cl_image_format *outFormat, ExplicitType *outType, void **outSourceBuffer, MTdata d )
|
||||
{
|
||||
clProgramWrapper program;
|
||||
clKernelWrapper kernel;
|
||||
clMemWrapper inStream;
|
||||
|
||||
int error;
|
||||
size_t threads[ 2 ], localThreads[ 2 ];
|
||||
char kernelSource[10240];
|
||||
char *programPtr;
|
||||
|
||||
// Determine data type and format that CL came up with
|
||||
error = clGetImageInfo( clImage, CL_IMAGE_FORMAT, sizeof( cl_image_format ), outFormat, NULL );
|
||||
test_error( error, "Unable to get CL image format" );
|
||||
|
||||
/* Create the source */
|
||||
*outType = get_write_kernel_type( outFormat );
|
||||
size_t channelSize = get_explicit_type_size( *outType );
|
||||
|
||||
const char* suffix = get_kernel_suffix( outFormat );
|
||||
const char* convert = get_write_conversion( outFormat, *outType );
|
||||
|
||||
sprintf( kernelSource, imageWriteKernelPattern, get_explicit_type_name( *outType ), get_explicit_type_name( *outType ), suffix, convert);
|
||||
|
||||
#ifdef GLES_DEBUG
|
||||
log_info("-- start cl image write kernel --\n");
|
||||
log_info("%s", kernelSource);
|
||||
log_info("-- end cl image write kernel --\n");
|
||||
#endif
|
||||
|
||||
/* Create kernel */
|
||||
programPtr = kernelSource;
|
||||
if( create_single_kernel_helper( context, &program, &kernel, 1, (const char **)&programPtr, "sample_test" ) )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Generate some source data based on the input type we need
|
||||
*outSourceBuffer = CreateRandomData(*outType, imageWidth * imageHeight * 4, d);
|
||||
|
||||
// Create a vanilla input buffer
|
||||
inStream = clCreateBuffer( context, CL_MEM_COPY_HOST_PTR, channelSize * 4 * imageWidth * imageHeight, *outSourceBuffer, &error );
|
||||
test_error( error, "Unable to create output buffer" );
|
||||
|
||||
/* Assign streams and execute */
|
||||
clSamplerWrapper sampler = clCreateSampler( context, CL_FALSE, CL_ADDRESS_NONE, CL_FILTER_NEAREST, &error );
|
||||
test_error( error, "Unable to create sampler" );
|
||||
|
||||
error = clSetKernelArg( kernel, 0, sizeof( inStream ), &inStream );
|
||||
test_error( error, "Unable to set kernel arguments" );
|
||||
error = clSetKernelArg( kernel, 1, sizeof( clImage ), &clImage );
|
||||
test_error( error, "Unable to set kernel arguments" );
|
||||
|
||||
glFlush();
|
||||
|
||||
error = (*clEnqueueAcquireGLObjects_ptr)( queue, 1, &clImage, 0, NULL, NULL);
|
||||
test_error( error, "Unable to acquire GL obejcts");
|
||||
|
||||
/* Run the kernel */
|
||||
threads[ 0 ] = imageWidth;
|
||||
threads[ 1 ] = imageHeight;
|
||||
|
||||
error = get_max_common_2D_work_group_size( context, kernel, threads, localThreads );
|
||||
test_error( error, "Unable to get work group size to use" );
|
||||
|
||||
error = clEnqueueNDRangeKernel( queue, kernel, 2, NULL, threads, localThreads, 0, NULL, NULL );
|
||||
test_error( error, "Unable to execute test kernel" );
|
||||
|
||||
clEventWrapper event;
|
||||
error = (*clEnqueueReleaseGLObjects_ptr)( queue, 1, &clImage, 0, NULL, &event );
|
||||
test_error(error, "clEnqueueReleaseGLObjects failed");
|
||||
|
||||
error = clWaitForEvents( 1, &event );
|
||||
test_error(error, "clWaitForEvents failed");
|
||||
|
||||
#ifdef GLES_DEBUG
|
||||
int i;
|
||||
size_t origin[] = {0, 0, 0,};
|
||||
size_t region[] = {imageWidth, imageHeight, 1 };
|
||||
void* cldata = malloc( channelSize * 4 * imageWidth * imageHeight );
|
||||
clEnqueueReadImage( queue, clImage, 1, origin, region, 0, 0, cldata, 0, 0, 0);
|
||||
log_info("- start CL Image Data -- \n");
|
||||
DumpGLBuffer(GetGLTypeForExplicitType(*outType), imageWidth, imageHeight, cldata);
|
||||
log_info("- end CL Image Data -- \n");
|
||||
free(cldata);
|
||||
#endif
|
||||
|
||||
// All done!
|
||||
return 0;
|
||||
}
|
||||
|
||||
int test_image_write( cl_context context, cl_command_queue queue, GLenum glTarget, GLuint glTexture,
|
||||
size_t imageWidth, size_t imageHeight, cl_image_format *outFormat, ExplicitType *outType, void **outSourceBuffer, MTdata d )
|
||||
{
|
||||
int error;
|
||||
|
||||
// Create a CL image from the supplied GL texture
|
||||
clMemWrapper image = (*clCreateFromGLTexture_ptr)( context, CL_MEM_WRITE_ONLY, glTarget, 0, glTexture, &error );
|
||||
if( error != CL_SUCCESS )
|
||||
{
|
||||
print_error( error, "Unable to create CL image from GL texture" );
|
||||
#ifndef GL_ES_VERSION_2_0
|
||||
GLint fmt;
|
||||
glGetTexLevelParameteriv( glTarget, 0, GL_TEXTURE_INTERNAL_FORMAT, &fmt );
|
||||
log_error( " Supplied GL texture was baseformat %s and internalformat %s\n", GetGLBaseFormatName( fmt ), GetGLFormatName( fmt ) );
|
||||
#endif
|
||||
return error;
|
||||
}
|
||||
|
||||
return test_cl_image_write( context, queue, image, imageWidth, imageHeight, outFormat, outType, outSourceBuffer, d );
|
||||
}
|
||||
|
||||
|
||||
int test_image_format_write( cl_context context, cl_command_queue queue,
|
||||
size_t width, size_t height, GLenum target,
|
||||
GLenum format, GLenum internalFormat,
|
||||
GLenum glType, ExplicitType type, MTdata d )
|
||||
{
|
||||
int error;
|
||||
|
||||
// Create the GL texture
|
||||
glTextureWrapper glTexture;
|
||||
void *tmp = CreateGLTexture2D( width, height, target, format, internalFormat, glType, type, &glTexture, &error, true, d );
|
||||
BufferOwningPtr<char> inputBuffer(tmp);
|
||||
if( error != 0 )
|
||||
{
|
||||
return error;
|
||||
}
|
||||
|
||||
/* skip formats not supported by OpenGL */
|
||||
if(!tmp)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Run and get the results
|
||||
cl_image_format clFormat;
|
||||
ExplicitType sourceType;
|
||||
void *outSourceBuffer;
|
||||
error = test_image_write( context, queue, target, glTexture, width, height, &clFormat, &sourceType, (void **)&outSourceBuffer, d );
|
||||
if( error != 0 )
|
||||
return error;
|
||||
|
||||
BufferOwningPtr<char> actualSource(outSourceBuffer);
|
||||
|
||||
log_info( "- Write [%4d x %4d] : GL Texture : %s : %s : %s => CL Image : %s : %s \n", (int)width, (int)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 texture
|
||||
ExplicitType readType = type;
|
||||
BufferOwningPtr<char> glResults( ReadGLTexture( target, glTexture, format, internalFormat, glType, readType, width, height ) );
|
||||
|
||||
// We have to convert our input buffer to the returned type, so we can validate.
|
||||
BufferOwningPtr<char> convertedGLResults( convert_to_expected( glResults, width * height, readType, sourceType ) );
|
||||
|
||||
#ifdef GLES_DEBUG
|
||||
log_info("- start read GL data -- \n");
|
||||
DumpGLBuffer(glType, width, height, glResults);
|
||||
log_info("- end read GL data -- \n");
|
||||
|
||||
log_info("- start converted data -- \n");
|
||||
DumpGLBuffer(glType, width, height, convertedGLResults);
|
||||
log_info("- end converted data -- \n");
|
||||
#endif
|
||||
|
||||
// Now we validate
|
||||
int valid = 0;
|
||||
if(convertedGLResults) {
|
||||
if( sourceType == kFloat )
|
||||
valid = validate_float_results( actualSource, convertedGLResults, width, height );
|
||||
else
|
||||
valid = validate_integer_results( actualSource, convertedGLResults, width, height, get_explicit_type_size( readType ) );
|
||||
}
|
||||
|
||||
return valid;
|
||||
}
|
||||
|
||||
int test_images_write( cl_device_id device, cl_context context, cl_command_queue queue, int numElements )
|
||||
{
|
||||
GLenum targets[] =
|
||||
#ifdef GL_ES_VERSION_2_0
|
||||
{ GL_TEXTURE_2D };
|
||||
#else // GL_ES_VERSION_2_0
|
||||
{ GL_TEXTURE_2D, GL_TEXTURE_RECTANGLE_EXT };
|
||||
#endif
|
||||
|
||||
struct {
|
||||
GLenum internal;
|
||||
GLenum format;
|
||||
GLenum datatype;
|
||||
ExplicitType type;
|
||||
|
||||
} formats[] = {
|
||||
#ifdef GL_ES_VERSION_2_0
|
||||
{ GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, kUChar },
|
||||
{ GL_RGBA, GL_RGBA, GL_UNSIGNED_SHORT, kUShort },
|
||||
// XXX add others
|
||||
#else // GL_ES_VERSION_2_0
|
||||
{ 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 },
|
||||
{ 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 },
|
||||
{ GL_RGBA32F_ARB, GL_RGBA, GL_FLOAT, kFloat }
|
||||
#endif
|
||||
};
|
||||
|
||||
size_t fmtIdx, tgtIdx;
|
||||
int error = 0;
|
||||
size_t iter = 6;
|
||||
RandomSeed seed(gRandomSeed);
|
||||
|
||||
// Check if images are supported
|
||||
if (checkForImageSupport(device)) {
|
||||
log_info("Device does not support images. 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( tgtIdx = 0; tgtIdx < sizeof( targets ) / sizeof( targets[ 0 ] ); tgtIdx++ )
|
||||
{
|
||||
log_info( "Testing image write test for %s : %s : %s : %s\n",
|
||||
GetGLTargetName( targets[ tgtIdx ] ),
|
||||
GetGLFormatName( formats[ fmtIdx ].internal ),
|
||||
GetGLBaseFormatName( formats[ fmtIdx ].format ),
|
||||
GetGLTypeName( formats[ fmtIdx ].datatype ) );
|
||||
|
||||
size_t i;
|
||||
for( i = 0; i < iter; i++ )
|
||||
{
|
||||
size_t width = random_in_range( 16, 512, seed );
|
||||
size_t height = random_in_range( 16, 512, seed );
|
||||
|
||||
if( targets[ tgtIdx ] == GL_TEXTURE_2D )
|
||||
width = height;
|
||||
|
||||
if( test_image_format_write( context, queue, width, height,
|
||||
targets[ tgtIdx ],
|
||||
formats[ fmtIdx ].format,
|
||||
formats[ fmtIdx ].internal,
|
||||
formats[ fmtIdx ].datatype,
|
||||
formats[ fmtIdx ].type, seed ) )
|
||||
{
|
||||
log_error( "ERROR: Image write test failed for %s : %s : %s : %s\n\n",
|
||||
GetGLTargetName( targets[ tgtIdx ] ),
|
||||
GetGLFormatName( formats[ fmtIdx ].internal ),
|
||||
GetGLBaseFormatName( formats[ fmtIdx ].format ),
|
||||
GetGLTypeName( formats[ fmtIdx ].datatype ) );
|
||||
|
||||
error++;
|
||||
break; // Skip other sizes for this combination
|
||||
}
|
||||
}
|
||||
if( i == 6 )
|
||||
{
|
||||
log_info( "passed: Image write for GL format %s : %s : %s : %s\n\n",
|
||||
GetGLTargetName( targets[ tgtIdx ] ),
|
||||
GetGLFormatName( formats[ fmtIdx ].internal ),
|
||||
GetGLBaseFormatName( formats[ fmtIdx ].format ),
|
||||
GetGLTypeName( formats[ fmtIdx ].datatype ) );
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
int test_images_write_cube( cl_device_id device, cl_context context, cl_command_queue queue, int numElements )
|
||||
{
|
||||
GLenum targets[] = {
|
||||
GL_TEXTURE_CUBE_MAP_POSITIVE_X,
|
||||
GL_TEXTURE_CUBE_MAP_POSITIVE_Y,
|
||||
GL_TEXTURE_CUBE_MAP_POSITIVE_Z,
|
||||
GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
|
||||
GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,
|
||||
GL_TEXTURE_CUBE_MAP_NEGATIVE_Z };
|
||||
|
||||
struct {
|
||||
GLenum internal;
|
||||
GLenum format;
|
||||
GLenum datatype;
|
||||
ExplicitType type;
|
||||
|
||||
} formats[] = {
|
||||
#ifdef GL_ES_VERSION_2_0
|
||||
{ GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, kUChar },
|
||||
{ GL_RGBA, GL_RGBA, GL_UNSIGNED_SHORT, kUShort },
|
||||
// XXX add others
|
||||
#else // GL_ES_VERSION_2_0
|
||||
{ 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 },
|
||||
{ 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 },
|
||||
{ GL_RGBA32F_ARB, GL_RGBA, GL_FLOAT, kFloat }
|
||||
#endif
|
||||
};
|
||||
|
||||
size_t sizes[] = { 16, 32, 64, 128, 256, 512, 1024, 2048, 4096 };
|
||||
|
||||
size_t fmtIdx, tgtIdx;
|
||||
int error = 0;
|
||||
size_t iter = 6;
|
||||
RandomSeed seed( gRandomSeed );
|
||||
|
||||
// Check if images are supported
|
||||
if (checkForImageSupport(device)) {
|
||||
log_info("Device does not support images. 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( tgtIdx = 0; tgtIdx < sizeof( targets ) / sizeof( targets[ 0 ] ); tgtIdx++ )
|
||||
{
|
||||
size_t i;
|
||||
log_info( "Testing image write cubemap test for %s : %s : %s : %s\n",
|
||||
GetGLTargetName( targets[ tgtIdx ] ),
|
||||
GetGLFormatName( formats[ fmtIdx ].internal ),
|
||||
GetGLBaseFormatName( formats[ fmtIdx ].format ),
|
||||
GetGLTypeName( formats[ fmtIdx ].datatype ) );
|
||||
|
||||
for( i = 0; i < iter; i++ )
|
||||
{
|
||||
if( test_image_format_write( context, queue, sizes[i], sizes[i],
|
||||
targets[ tgtIdx ],
|
||||
formats[ fmtIdx ].format,
|
||||
formats[ fmtIdx ].internal,
|
||||
formats[ fmtIdx ].datatype,
|
||||
formats[ fmtIdx ].type, seed ) )
|
||||
{
|
||||
log_error( "ERROR: Image write cubemap test failed for %s : %s : %s : %s\n\n",
|
||||
GetGLTargetName( targets[ tgtIdx ] ),
|
||||
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: Image write cubemap for GL format %s : %s : %s : %s\n\n",
|
||||
GetGLTargetName( targets[ tgtIdx ] ),
|
||||
GetGLFormatName( formats[ fmtIdx ].internal ),
|
||||
GetGLBaseFormatName( formats[ fmtIdx ].format ),
|
||||
GetGLTypeName( formats[ fmtIdx ].datatype ) );
|
||||
}
|
||||
else
|
||||
break; // Skip other cube map targets; they're unlikely to pass either
|
||||
}
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
256
test_conformance/gles/test_images_2D_info.cpp
Normal file
256
test_conformance/gles/test_images_2D_info.cpp
Normal file
@@ -0,0 +1,256 @@
|
||||
//
|
||||
// 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 "gl_headers.h"
|
||||
|
||||
extern "C" {extern cl_uint gRandomSeed;};
|
||||
|
||||
static int test_image_read( cl_context context, cl_command_queue queue, GLenum glTarget, GLuint glTexture,
|
||||
size_t imageWidth, size_t imageHeight, cl_image_format *outFormat,
|
||||
ExplicitType *outType, void **outResultBuffer )
|
||||
{
|
||||
// Create a CL image from the supplied GL texture
|
||||
int error;
|
||||
clMemWrapper image = (*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" );
|
||||
#ifndef GL_ES_VERSION_2_0
|
||||
GLint fmt;
|
||||
glGetTexLevelParameteriv( glTarget, 0, GL_TEXTURE_INTERNAL_FORMAT, &fmt );
|
||||
log_error( " Supplied GL texture was baseformat %s and internalformat %s\n", GetGLBaseFormatName( fmt ), GetGLFormatName( fmt ) );
|
||||
#endif
|
||||
return error;
|
||||
}
|
||||
|
||||
// Determine data type and format that CL came up with
|
||||
error = clGetImageInfo( image, CL_IMAGE_FORMAT, sizeof( cl_image_format ), outFormat, NULL );
|
||||
test_error( error, "Unable to get CL image format" );
|
||||
|
||||
return CheckGLObjectInfo(image, CL_GL_OBJECT_TEXTURE2D, glTexture, glTarget, 0);
|
||||
}
|
||||
|
||||
static int test_image_object_info( cl_context context, cl_command_queue queue,
|
||||
size_t width, size_t height, GLenum target,
|
||||
GLenum format, GLenum internalFormat,
|
||||
GLenum glType, ExplicitType type, MTdata d )
|
||||
{
|
||||
int error;
|
||||
|
||||
// Create the GL texture
|
||||
glTextureWrapper glTexture;
|
||||
void *tmp = CreateGLTexture2D( width, height, target, format, internalFormat, glType, type, &glTexture, &error, true, d );
|
||||
BufferOwningPtr<char> inputBuffer(tmp);
|
||||
if( error != 0 )
|
||||
{
|
||||
// GL_RGBA_INTEGER_EXT doesn't exist in GLES2. No need to check for it.
|
||||
return error;
|
||||
}
|
||||
|
||||
/* skip formats not supported by OpenGL */
|
||||
if(!tmp)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Run and get the results
|
||||
cl_image_format clFormat;
|
||||
ExplicitType actualType;
|
||||
char *outBuffer;
|
||||
error = test_image_read( context, queue, target, glTexture, width, height, &clFormat, &actualType, (void **)&outBuffer );
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
int test_images_2D_getinfo( cl_device_id device, cl_context context, cl_command_queue queue, int numElements )
|
||||
{
|
||||
GLenum targets[] =
|
||||
#ifdef GL_ES_VERSION_2_0
|
||||
{ GL_TEXTURE_2D };
|
||||
#else // GL_ES_VERSION_2_0
|
||||
{ GL_TEXTURE_2D, GL_TEXTURE_RECTANGLE_EXT };
|
||||
#endif // GL_ES_VERSION_2_0
|
||||
|
||||
struct {
|
||||
GLenum internal;
|
||||
GLenum format;
|
||||
GLenum datatype;
|
||||
ExplicitType type;
|
||||
|
||||
} formats[] = {
|
||||
{ GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, kUChar },
|
||||
{ GL_RGBA, GL_RGBA, GL_UNSIGNED_SHORT, kUShort },
|
||||
{ GL_RGBA, GL_RGBA, GL_HALF_FLOAT_OES, kHalf },
|
||||
{ GL_RGBA, GL_RGBA, GL_FLOAT, kFloat },
|
||||
};
|
||||
|
||||
size_t sizes[] = { 16, 32, 64, 128, 256, 512, 1024, 2048, 4096 };
|
||||
|
||||
size_t fmtIdx, tgtIdx;
|
||||
int error = 0;
|
||||
size_t iter = 6;
|
||||
RandomSeed seed( gRandomSeed );
|
||||
|
||||
// Check if images are supported
|
||||
if (checkForImageSupport(device)) {
|
||||
log_info("Device does not support images. 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( tgtIdx = 0; tgtIdx < sizeof( targets ) / sizeof( targets[ 0 ] ); tgtIdx++ )
|
||||
{
|
||||
size_t i;
|
||||
log_info( "Testing image texture object info test for %s : %s : %s : %s\n",
|
||||
GetGLTargetName( targets[ tgtIdx ] ),
|
||||
GetGLFormatName( formats[ fmtIdx ].internal ),
|
||||
GetGLBaseFormatName( formats[ fmtIdx ].format ),
|
||||
GetGLTypeName( formats[ fmtIdx ].datatype ) );
|
||||
|
||||
for( i = 0; i < iter; i++ )
|
||||
{
|
||||
if( test_image_object_info( context, queue, sizes[i], sizes[i],
|
||||
targets[ tgtIdx ],
|
||||
formats[ fmtIdx ].format,
|
||||
formats[ fmtIdx ].internal,
|
||||
formats[ fmtIdx ].datatype,
|
||||
formats[ fmtIdx ].type, seed ) )
|
||||
{
|
||||
log_error( "ERROR: Image texture object info test failed for %s : %s : %s : %s\n\n",
|
||||
GetGLTargetName( targets[ tgtIdx ] ),
|
||||
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: Image texture object info test passed for %s : %s : %s : %s\n\n",
|
||||
GetGLTargetName( targets[ tgtIdx ] ),
|
||||
GetGLFormatName( formats[ fmtIdx ].internal ),
|
||||
GetGLBaseFormatName( formats[ fmtIdx ].format ),
|
||||
GetGLTypeName( formats[ fmtIdx ].datatype ) );
|
||||
}
|
||||
else
|
||||
break; // Skip other cube map targets; they're unlikely to pass either
|
||||
}
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
int test_images_cube_getinfo( cl_device_id device, cl_context context, cl_command_queue queue, int numElements )
|
||||
{
|
||||
GLenum targets[] = {
|
||||
GL_TEXTURE_CUBE_MAP_POSITIVE_X,
|
||||
GL_TEXTURE_CUBE_MAP_POSITIVE_Y,
|
||||
GL_TEXTURE_CUBE_MAP_POSITIVE_Z,
|
||||
GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
|
||||
GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,
|
||||
GL_TEXTURE_CUBE_MAP_NEGATIVE_Z };
|
||||
|
||||
struct {
|
||||
GLenum internal;
|
||||
GLenum format;
|
||||
GLenum datatype;
|
||||
ExplicitType type;
|
||||
|
||||
} formats[] = {
|
||||
#ifdef GL_ES_VERSION_2_0
|
||||
{ GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, kUChar },
|
||||
{ GL_RGBA, GL_RGBA, GL_UNSIGNED_SHORT, kUShort },
|
||||
// XXX add others
|
||||
#else // GL_ES_VERSION_2_0
|
||||
{ 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 },
|
||||
{ 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 },
|
||||
{ GL_RGBA32F_ARB, GL_RGBA, GL_FLOAT, kFloat }
|
||||
#endif
|
||||
};
|
||||
|
||||
size_t sizes[] = { 16, 32, 64, 128, 256, 512, 1024, 2048, 4096 };
|
||||
|
||||
size_t fmtIdx, tgtIdx;
|
||||
int error = 0;
|
||||
size_t iter = 6;
|
||||
RandomSeed seed( gRandomSeed );
|
||||
|
||||
// Check if images are supported
|
||||
if (checkForImageSupport(device)) {
|
||||
log_info("Device does not support images. 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( tgtIdx = 0; tgtIdx < sizeof( targets ) / sizeof( targets[ 0 ] ); tgtIdx++ )
|
||||
{
|
||||
size_t i;
|
||||
log_info( "Testing cube map object info test for %s : %s : %s : %s\n",
|
||||
GetGLTargetName( targets[ tgtIdx ] ),
|
||||
GetGLFormatName( formats[ fmtIdx ].internal ),
|
||||
GetGLBaseFormatName( formats[ fmtIdx ].format ),
|
||||
GetGLTypeName( formats[ fmtIdx ].datatype ) );
|
||||
|
||||
for( i = 0; i < iter; i++ )
|
||||
{
|
||||
if( test_image_object_info( context, queue, sizes[i], sizes[i],
|
||||
targets[ tgtIdx ],
|
||||
formats[ fmtIdx ].format,
|
||||
formats[ fmtIdx ].internal,
|
||||
formats[ fmtIdx ].datatype,
|
||||
formats[ fmtIdx ].type, seed ) )
|
||||
{
|
||||
log_error( "ERROR: Cube map object info test failed for %s : %s : %s : %s\n\n",
|
||||
GetGLTargetName( targets[ tgtIdx ] ),
|
||||
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: Cube map object info test passed for %s : %s : %s : %s\n\n",
|
||||
GetGLTargetName( targets[ tgtIdx ] ),
|
||||
GetGLFormatName( formats[ fmtIdx ].internal ),
|
||||
GetGLBaseFormatName( formats[ fmtIdx ].format ),
|
||||
GetGLTypeName( formats[ fmtIdx ].datatype ) );
|
||||
}
|
||||
else
|
||||
break; // Skip other cube map targets; they're unlikely to pass either
|
||||
}
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
268
test_conformance/gles/test_images_3D.cpp
Normal file
268
test_conformance/gles/test_images_3D.cpp
Normal file
@@ -0,0 +1,268 @@
|
||||
//
|
||||
// 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 "gl_headers.h"
|
||||
|
||||
extern "C" { extern cl_uint gRandomSeed; };
|
||||
|
||||
static const char *imageReadKernelPattern =
|
||||
"__kernel void sample_test( read_only image3d_t source, sampler_t sampler, __global %s4 *results )\n"
|
||||
"{\n"
|
||||
" int tidX = get_global_id(0);\n"
|
||||
" int tidY = get_global_id(1);\n"
|
||||
" int tidZ = get_global_id(2);\n"
|
||||
" int width = get_image_width( source );\n"
|
||||
" int height = get_image_height( source );\n"
|
||||
" int offset = tidZ * width * height + tidY * width + tidX;\n"
|
||||
"\n"
|
||||
" results[ offset ] = read_image%s( source, sampler, (int4)( tidX, tidY, tidZ, 0 ) );\n"
|
||||
"}\n";
|
||||
|
||||
static int test_image_read( 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 )
|
||||
{
|
||||
clProgramWrapper program;
|
||||
clKernelWrapper kernel;
|
||||
clMemWrapper streams[ 2 ];
|
||||
|
||||
int error;
|
||||
size_t threads[ 3 ], localThreads[ 3 ];
|
||||
char kernelSource[1024];
|
||||
char *programPtr;
|
||||
|
||||
|
||||
// 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" );
|
||||
#ifndef GL_ES_VERSION_2_0
|
||||
GLint fmt;
|
||||
glGetTexLevelParameteriv( glTarget, 0, GL_TEXTURE_INTERNAL_FORMAT, &fmt );
|
||||
log_error( " Supplied GL texture was format %s\n", GetGLFormatName( fmt ) );
|
||||
#endif
|
||||
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" );
|
||||
|
||||
/* Create the source */
|
||||
*outType = get_read_kernel_type( outFormat );
|
||||
size_t channelSize = get_explicit_type_size( *outType );
|
||||
|
||||
sprintf( kernelSource, imageReadKernelPattern, get_explicit_type_name( *outType ), get_kernel_suffix( outFormat ) );
|
||||
|
||||
/* Create kernel */
|
||||
programPtr = kernelSource;
|
||||
if( create_single_kernel_helper( context, &program, &kernel, 1, (const char **)&programPtr, "sample_test" ) )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
// Create a vanilla output buffer
|
||||
streams[ 1 ] = clCreateBuffer( context, CL_MEM_READ_WRITE, channelSize * 4 * imageWidth * imageHeight * imageDepth, NULL, &error );
|
||||
test_error( error, "Unable to create output buffer" );
|
||||
|
||||
|
||||
/* Assign streams and execute */
|
||||
clSamplerWrapper sampler = clCreateSampler( context, CL_FALSE, CL_ADDRESS_NONE, CL_FILTER_NEAREST, &error );
|
||||
test_error( error, "Unable to create sampler" );
|
||||
|
||||
error = clSetKernelArg( kernel, 0, sizeof( streams[ 0 ] ), &streams[ 0 ] );
|
||||
test_error( error, "Unable to set kernel arguments" );
|
||||
error = clSetKernelArg( kernel, 1, sizeof( sampler ), &sampler );
|
||||
test_error( error, "Unable to set kernel arguments" );
|
||||
error = clSetKernelArg( kernel, 2, sizeof( streams[ 1 ] ), &streams[ 1 ] );
|
||||
test_error( error, "Unable to set kernel arguments" );
|
||||
|
||||
glFlush();
|
||||
|
||||
error = (*clEnqueueAcquireGLObjects_ptr)( queue, 1, &streams[ 0 ], 0, NULL, NULL);
|
||||
test_error( error, "Unable to acquire GL obejcts");
|
||||
|
||||
/* Run the kernel */
|
||||
threads[ 0 ] = imageWidth;
|
||||
threads[ 1 ] = imageHeight;
|
||||
threads[ 2 ] = imageDepth;
|
||||
|
||||
error = get_max_common_3D_work_group_size( context, kernel, threads, localThreads );
|
||||
test_error( error, "Unable to get work group size to use" );
|
||||
|
||||
error = clEnqueueNDRangeKernel( queue, kernel, 3, NULL, threads, localThreads, 0, NULL, NULL );
|
||||
test_error( error, "Unable to execute test kernel" );
|
||||
|
||||
|
||||
error = (*clEnqueueReleaseGLObjects_ptr)( queue, 1, &streams[ 0 ], 0, NULL, NULL );
|
||||
test_error(error, "clEnqueueReleaseGLObjects failed");
|
||||
|
||||
// Read results from the CL buffer
|
||||
*outResultBuffer = (void *)( new char[ channelSize * 4 * imageWidth * imageHeight * imageDepth ] );
|
||||
error = clEnqueueReadBuffer( queue, streams[ 1 ], CL_TRUE, 0, channelSize * 4 * imageWidth * imageHeight * imageDepth,
|
||||
*outResultBuffer, 0, NULL, NULL );
|
||||
test_error( error, "Unable to read output CL buffer!" );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int test_image_format_read( cl_context context, cl_command_queue queue,
|
||||
size_t width, size_t height, size_t depth,
|
||||
GLenum target, GLenum format, GLenum internalFormat,
|
||||
GLenum glType, ExplicitType type, MTdata d )
|
||||
{
|
||||
int error;
|
||||
|
||||
|
||||
// Create the GL texture
|
||||
glTextureWrapper glTexture;
|
||||
void* tmp = CreateGLTexture3D( width, height, depth, target, format, internalFormat, glType, type, &glTexture, &error, d );
|
||||
BufferOwningPtr<char> inputBuffer(tmp);
|
||||
if( error != 0 )
|
||||
{
|
||||
return error;
|
||||
}
|
||||
|
||||
/* skip formats not supported by OpenGL */
|
||||
if(!tmp)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Run and get the results
|
||||
cl_image_format clFormat;
|
||||
ExplicitType actualType;
|
||||
char *outBuffer;
|
||||
error = test_image_read( context, queue, target, glTexture, width, height, depth, &clFormat, &actualType, (void **)&outBuffer );
|
||||
if( error != 0 )
|
||||
return error;
|
||||
BufferOwningPtr<char> actualResults(outBuffer);
|
||||
|
||||
log_info( "- Read [%4d x %4d x %4d] : GL Texture : %s : %s : %s => CL Image : %s : %s \n",
|
||||
(int)width, (int)height, (int)depth,
|
||||
GetGLFormatName( format ), GetGLFormatName( internalFormat ), GetGLTypeName( glType),
|
||||
GetChannelOrderName( clFormat.image_channel_order ), GetChannelTypeName( clFormat.image_channel_data_type ));
|
||||
|
||||
// We have to convert our input buffer to the returned type, so we can validate.
|
||||
// This is necessary because OpenCL might not actually pick an internal format that actually matches our
|
||||
// input format (for example, if it picks a normalized format, the results will come out as floats instead of
|
||||
// going in as ints).
|
||||
|
||||
BufferOwningPtr<char> convertedInputs(convert_to_expected( inputBuffer, width * height * depth, type, actualType ));
|
||||
if( convertedInputs == NULL )
|
||||
return -1;
|
||||
|
||||
// Now we validate
|
||||
if( actualType == kFloat )
|
||||
return validate_float_results( convertedInputs, actualResults, width, height, depth );
|
||||
else
|
||||
return validate_integer_results( convertedInputs, actualResults, width, height, depth, get_explicit_type_size( actualType ) );
|
||||
}
|
||||
|
||||
|
||||
int test_images_read_3D( cl_device_id device, cl_context context, cl_command_queue queue, int numElements )
|
||||
{
|
||||
GLenum targets[] = { GL_TEXTURE_3D };
|
||||
|
||||
struct {
|
||||
GLenum internal;
|
||||
GLenum format;
|
||||
GLenum datatype;
|
||||
ExplicitType type;
|
||||
|
||||
} formats[] = {
|
||||
#ifdef GL_ES_VERSION_2_0
|
||||
{ GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, kUChar },
|
||||
{ GL_RGBA, GL_RGBA, GL_UNSIGNED_SHORT, kUShort },
|
||||
// XXX add others
|
||||
#else // GL_ES_VERSION_2_0
|
||||
{ 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 },
|
||||
{ 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 },
|
||||
{ GL_RGBA32F_ARB, GL_RGBA, GL_FLOAT, kFloat }
|
||||
#endif
|
||||
};
|
||||
|
||||
size_t sizes[] = { 2, 4, 8, 16, 32, 64, 128 };
|
||||
size_t fmtIdx, tgtIdx;
|
||||
int error = 0;
|
||||
RandomSeed seed(gRandomSeed);
|
||||
|
||||
size_t iter = sizeof(sizes)/sizeof(sizes[0]);
|
||||
|
||||
// Check if images are supported
|
||||
if (checkForImageSupport(device)) {
|
||||
log_info("Device does not support images. 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( tgtIdx = 0; tgtIdx < sizeof( targets ) / sizeof( targets[ 0 ] ); tgtIdx++ )
|
||||
{
|
||||
size_t i;
|
||||
|
||||
log_info( "Testing image read for GL format %s : %s : %s : %s\n",
|
||||
GetGLTargetName( targets[ tgtIdx ] ),
|
||||
GetGLFormatName( formats[ fmtIdx ].internal ),
|
||||
GetGLBaseFormatName( formats[ fmtIdx ].format ),
|
||||
GetGLTypeName( formats[ fmtIdx ].datatype ) );
|
||||
|
||||
for( i = 0; i < iter; i++ )
|
||||
{
|
||||
if( test_image_format_read( context, queue, sizes[i], sizes[i], sizes[i],
|
||||
targets[ tgtIdx ],
|
||||
formats[ fmtIdx ].format,
|
||||
formats[ fmtIdx ].internal,
|
||||
formats[ fmtIdx ].datatype,
|
||||
formats[ fmtIdx ].type, seed ) )
|
||||
{
|
||||
log_error( "ERROR: Image read test failed for %s : %s : %s : %s\n\n",
|
||||
GetGLTargetName( targets[ tgtIdx ] ),
|
||||
GetGLFormatName( formats[ fmtIdx ].internal ),
|
||||
GetGLBaseFormatName( formats[ fmtIdx ].format ),
|
||||
GetGLTypeName( formats[ fmtIdx ].datatype ) );
|
||||
|
||||
error++;
|
||||
break; // Skip other sizes for this combination
|
||||
}
|
||||
}
|
||||
if( i == sizeof (sizes) / sizeof( sizes[0] ) )
|
||||
{
|
||||
log_info( "passed: Image read test for GL format %s : %s : %s : %s\n\n",
|
||||
GetGLTargetName( targets[ tgtIdx ] ),
|
||||
GetGLFormatName( formats[ fmtIdx ].internal ),
|
||||
GetGLBaseFormatName( formats[ fmtIdx ].format ),
|
||||
GetGLTypeName( formats[ fmtIdx ].datatype ) );
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
166
test_conformance/gles/test_images_3D_info.cpp
Normal file
166
test_conformance/gles/test_images_3D_info.cpp
Normal file
@@ -0,0 +1,166 @@
|
||||
//
|
||||
// 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 "gl_headers.h"
|
||||
#include "testBase.h"
|
||||
|
||||
extern "C" {extern cl_uint gRandomSeed;};
|
||||
|
||||
static int test_image_read( 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" );
|
||||
#ifndef GL_ES_VERSION_2_0
|
||||
GLint fmt;
|
||||
glGetTexLevelParameteriv( glTarget, 0, GL_TEXTURE_INTERNAL_FORMAT, &fmt );
|
||||
log_error( " Supplied GL texture was format %s\n", GetGLFormatName( fmt ) );
|
||||
#endif
|
||||
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" );
|
||||
|
||||
return CheckGLObjectInfo(streams[0], CL_GL_OBJECT_TEXTURE3D, glTexture, glTarget, 0);
|
||||
}
|
||||
|
||||
static int test_image_format_read( cl_context context, cl_command_queue queue,
|
||||
size_t width, size_t height, size_t depth,
|
||||
GLenum target, GLenum format, GLenum internalFormat,
|
||||
GLenum glType, ExplicitType type, MTdata d )
|
||||
{
|
||||
int error;
|
||||
|
||||
|
||||
// Create the GL texture
|
||||
glTextureWrapper glTexture;
|
||||
void* tmp = CreateGLTexture3D( width, height, depth, target, format, internalFormat, glType, type, &glTexture, &error, d, true );
|
||||
BufferOwningPtr<char> inputBuffer(tmp);
|
||||
if( error != 0 )
|
||||
{
|
||||
return error;
|
||||
}
|
||||
|
||||
/* skip formats not supported by OpenGL */
|
||||
if(!tmp)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Run and get the results
|
||||
cl_image_format clFormat;
|
||||
ExplicitType actualType;
|
||||
char *outBuffer;
|
||||
return test_image_read( context, queue, target, glTexture, width, height, depth, &clFormat, &actualType, (void **)&outBuffer );
|
||||
}
|
||||
|
||||
|
||||
int test_images_3D_getinfo( cl_device_id device, cl_context context, cl_command_queue queue, int numElements )
|
||||
{
|
||||
GLenum targets[] = { GL_TEXTURE_3D };
|
||||
|
||||
struct {
|
||||
GLenum internal;
|
||||
GLenum format;
|
||||
GLenum datatype;
|
||||
ExplicitType type;
|
||||
|
||||
} formats[] = {
|
||||
#ifdef GL_ES_VERSION_2_0
|
||||
{ GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, kUChar },
|
||||
{ GL_RGBA, GL_RGBA, GL_UNSIGNED_SHORT, kUShort },
|
||||
// { 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 },
|
||||
// { GL_RGBA32F_ARB, GL_RGBA, GL_FLOAT, kFloat }
|
||||
#else // GL_ES_VERSION_2_0
|
||||
{ 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 },
|
||||
{ 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 },
|
||||
{ GL_RGBA32F_ARB, GL_RGBA, GL_FLOAT, kFloat }
|
||||
#endif
|
||||
};
|
||||
|
||||
size_t sizes[] = { 2, 4, 8, 16, 32, 64, 128 };
|
||||
|
||||
size_t fmtIdx, tgtIdx;
|
||||
int error = 0;
|
||||
RandomSeed seed(gRandomSeed);
|
||||
|
||||
size_t iter = sizeof(sizes)/sizeof(sizes[0]);
|
||||
|
||||
// Check if images are supported
|
||||
if (checkForImageSupport(device)) {
|
||||
log_info("Device does not support images. 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( tgtIdx = 0; tgtIdx < sizeof( targets ) / sizeof( targets[ 0 ] ); tgtIdx++ )
|
||||
{
|
||||
size_t i;
|
||||
|
||||
log_info( "Testing image info for GL format %s : %s : %s : %s\n",
|
||||
GetGLTargetName( targets[ tgtIdx ] ),
|
||||
GetGLFormatName( formats[ fmtIdx ].internal ),
|
||||
GetGLBaseFormatName( formats[ fmtIdx ].format ),
|
||||
GetGLTypeName( formats[ fmtIdx ].datatype ) );
|
||||
|
||||
for( i = 0; i < iter; i++ )
|
||||
{
|
||||
if( test_image_format_read( context, queue, sizes[i], sizes[i], sizes[i],
|
||||
targets[ tgtIdx ],
|
||||
formats[ fmtIdx ].format,
|
||||
formats[ fmtIdx ].internal,
|
||||
formats[ fmtIdx ].datatype,
|
||||
formats[ fmtIdx ].type, seed ) )
|
||||
{
|
||||
log_error( "ERROR: Image info test failed for %s : %s : %s : %s\n\n",
|
||||
GetGLTargetName( targets[ tgtIdx ] ),
|
||||
GetGLFormatName( formats[ fmtIdx ].internal ),
|
||||
GetGLBaseFormatName( formats[ fmtIdx ].format ),
|
||||
GetGLTypeName( formats[ fmtIdx ].datatype ) );
|
||||
|
||||
error++;
|
||||
break; // Skip other sizes for this combination
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
373
test_conformance/gles/test_renderbuffer.cpp
Normal file
373
test_conformance/gles/test_renderbuffer.cpp
Normal file
@@ -0,0 +1,373 @@
|
||||
//
|
||||
// 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 "helpers.h"
|
||||
|
||||
#include "gl_headers.h"
|
||||
|
||||
extern "C" { extern cl_uint gRandomSeed; };
|
||||
|
||||
extern int test_cl_image_write( cl_context context, cl_command_queue queue, cl_mem clImage,
|
||||
size_t imageWidth, size_t imageHeight, cl_image_format *outFormat,
|
||||
ExplicitType *outType, void **outSourceBuffer, MTdata d );
|
||||
|
||||
extern int test_cl_image_read( cl_context context, cl_command_queue queue, cl_mem clImage,
|
||||
size_t imageWidth, size_t imageHeight, cl_image_format *outFormat,
|
||||
ExplicitType *outType, void **outResultBuffer );
|
||||
|
||||
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
|
||||
clMemWrapper 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, image, imageWidth, imageHeight, outFormat, outType, outResultBuffer );
|
||||
}
|
||||
|
||||
int test_renderbuffer_read_image( cl_context context, cl_command_queue queue,
|
||||
GLsizei width, GLsizei height, GLenum attachment,
|
||||
GLenum rbFormat, GLenum rbType,
|
||||
GLenum texFormat, GLenum texType,
|
||||
ExplicitType type, MTdata d )
|
||||
{
|
||||
int error;
|
||||
|
||||
|
||||
// Create the GL renderbuffer
|
||||
glFramebufferWrapper glFramebuffer;
|
||||
glRenderbufferWrapper glRenderbuffer;
|
||||
void *tmp = CreateGLRenderbuffer( width, height, attachment, rbFormat, rbType, texFormat, texType,
|
||||
type, &glFramebuffer, &glRenderbuffer, &error, d, true );
|
||||
BufferOwningPtr<char> inputBuffer(tmp);
|
||||
if( error != 0 )
|
||||
{
|
||||
// GL_RGBA_INTEGER_EXT doesn't exist in GLES2. No need to check for it.
|
||||
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( rbFormat ), GetGLFormatName( rbFormat ), GetGLTypeName( rbType ),
|
||||
GetChannelOrderName( clFormat.image_channel_order ), GetChannelTypeName( clFormat.image_channel_data_type ));
|
||||
|
||||
#ifdef GLES_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 GLES_DEBUG
|
||||
log_info("- start input data -- \n");
|
||||
DumpGLBuffer(GetGLTypeForExplicitType(actualType), width, height, convertedInput);
|
||||
log_info("- end input data -- \n");
|
||||
#endif
|
||||
|
||||
#ifdef GLES_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 rbFormat;
|
||||
GLenum rbType;
|
||||
GLenum texFormat;
|
||||
GLenum texType;
|
||||
ExplicitType type;
|
||||
|
||||
} formats[] = {
|
||||
{ GL_RGBA8_OES, GL_UNSIGNED_BYTE, GL_RGBA, GL_UNSIGNED_BYTE, kUChar },
|
||||
//{ GL_RGBA16F_QCOM, GL_HALF_FLOAT_OES, GL_RGBA, GL_HALF_FLOAT_OES, kHalf }, // Half-float not supported by ReadPixels
|
||||
{ GL_RGBA32F, GL_FLOAT, GL_RGBA, GL_FLOAT, kFloat},
|
||||
// XXX add others
|
||||
};
|
||||
|
||||
size_t fmtIdx, attIdx;
|
||||
int error = 0;
|
||||
#ifdef GLES_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;
|
||||
}
|
||||
|
||||
// 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 ].rbFormat ),
|
||||
GetGLBaseFormatName( formats[ fmtIdx ].rbFormat ),
|
||||
GetGLTypeName( formats[ fmtIdx ].rbType ) );
|
||||
|
||||
for( i = 0; i < iter; i++ )
|
||||
{
|
||||
GLsizei width = random_in_range( 16, 512, seed );
|
||||
GLsizei height = random_in_range( 16, 512, seed );
|
||||
#ifdef GLES_DEBUG
|
||||
width = height = 4;
|
||||
#endif
|
||||
|
||||
if( test_renderbuffer_read_image( context, queue, width, height,
|
||||
attachments[ attIdx ],
|
||||
formats[ fmtIdx ].rbFormat,
|
||||
formats[ fmtIdx ].rbType,
|
||||
formats[ fmtIdx ].texFormat,
|
||||
formats[ fmtIdx ].texType,
|
||||
formats[ fmtIdx ].type, seed ) )
|
||||
|
||||
{
|
||||
log_error( "ERROR: Renderbuffer read test failed for %s : %s : %s : %s\n\n",
|
||||
GetGLAttachmentName( attachments[ attIdx ] ),
|
||||
GetGLFormatName( formats[ fmtIdx ].rbFormat ),
|
||||
GetGLBaseFormatName( formats[ fmtIdx ].rbFormat ),
|
||||
GetGLTypeName( formats[ fmtIdx ].rbType ) );
|
||||
|
||||
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 ].rbFormat ),
|
||||
GetGLBaseFormatName( formats[ fmtIdx ].rbFormat ),
|
||||
GetGLTypeName( formats[ fmtIdx ].rbType ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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 )
|
||||
{
|
||||
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, image, imageWidth, imageHeight, outFormat, outType, outSourceBuffer, d );
|
||||
}
|
||||
|
||||
int test_renderbuffer_image_write( cl_context context, cl_command_queue queue,
|
||||
GLsizei width, GLsizei height, GLenum attachment,
|
||||
GLenum rbFormat, GLenum rbType,
|
||||
GLenum texFormat, GLenum texType,
|
||||
ExplicitType type, MTdata d)
|
||||
{
|
||||
int error;
|
||||
|
||||
// Create the GL renderbuffer
|
||||
glFramebufferWrapper glFramebuffer;
|
||||
glRenderbufferWrapper glRenderbuffer;
|
||||
CreateGLRenderbuffer( width, height, attachment, rbFormat, rbType, texFormat, texType,
|
||||
type, &glFramebuffer, &glRenderbuffer, &error, d, false );
|
||||
if( error != 0 )
|
||||
{
|
||||
// GL_RGBA_INTEGER_EXT doesn't exist in GLES2. No need to check for it.
|
||||
return error;
|
||||
}
|
||||
|
||||
// Run and get the results
|
||||
cl_image_format clFormat;
|
||||
ExplicitType sourceType;
|
||||
void *outSourceBuffer;
|
||||
error = test_attach_renderbuffer_write_to_image( context, queue, attachment, glRenderbuffer, width, height, &clFormat, &sourceType, d, (void **)&outSourceBuffer );
|
||||
if( error != 0 )
|
||||
return error;
|
||||
|
||||
BufferOwningPtr<char> sourceData(outSourceBuffer);
|
||||
|
||||
log_info( "- Write [%4d x %4d] : GL Renderbuffer : %s : %s : %s => CL Image : %s : %s \n", width, height,
|
||||
GetGLFormatName( rbFormat ), GetGLFormatName( rbFormat ), GetGLTypeName( rbType),
|
||||
GetChannelOrderName( clFormat.image_channel_order ), GetChannelTypeName( clFormat.image_channel_data_type ));
|
||||
|
||||
// Now read the results from the GL renderbuffer
|
||||
void* tmp = ReadGLRenderbuffer( glFramebuffer, glRenderbuffer, attachment, rbFormat, rbType,
|
||||
texFormat, texType, type, width, height );
|
||||
BufferOwningPtr<char> resultData( tmp );
|
||||
|
||||
#ifdef GLES_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, sourceType ) );
|
||||
|
||||
#ifdef GLES_DEBUG
|
||||
log_info("- start input data -- \n");
|
||||
DumpGLBuffer(GetGLTypeForExplicitType(sourceType), width, height, sourceData);
|
||||
log_info("- end input data -- \n");
|
||||
#endif
|
||||
|
||||
#ifdef GLES_DEBUG
|
||||
log_info("- start converted data -- \n");
|
||||
DumpGLBuffer(GetGLTypeForExplicitType(sourceType), width, height, convertedData);
|
||||
log_info("- end converted data -- \n");
|
||||
#endif
|
||||
|
||||
// Now we validate
|
||||
int valid = 0;
|
||||
if(convertedData) {
|
||||
if( sourceType == kFloat )
|
||||
valid = validate_float_results( sourceData, convertedData, width, height );
|
||||
else
|
||||
valid = validate_integer_results( sourceData, 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 rbFormat;
|
||||
GLenum rbType;
|
||||
GLenum texFormat;
|
||||
GLenum texType;
|
||||
ExplicitType type;
|
||||
|
||||
} formats[] = {
|
||||
{ GL_RGBA8_OES, GL_UNSIGNED_BYTE, GL_RGBA, GL_UNSIGNED_BYTE, kUChar },
|
||||
//{ GL_RGBA16F_QCOM, GL_UNSIGNED_SHORT, GL_RGBA, GL_UNSIGNED_SHORT, kHalf }, // Half float not supported by ReadPixels
|
||||
{ GL_RGBA32F, GL_FLOAT, GL_RGBA, GL_FLOAT, kFloat},
|
||||
// XXX add others
|
||||
};
|
||||
|
||||
size_t fmtIdx, attIdx;
|
||||
int error = 0;
|
||||
size_t iter = 6;
|
||||
#ifdef GLES_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;
|
||||
}
|
||||
|
||||
// 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 ].rbFormat ),
|
||||
GetGLBaseFormatName( formats[ fmtIdx ].rbFormat ),
|
||||
GetGLTypeName( formats[ fmtIdx ].rbType) );
|
||||
|
||||
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 GLES_DEBUG
|
||||
width = height = 4;
|
||||
#endif
|
||||
|
||||
if( test_renderbuffer_image_write( context, queue, width, height,
|
||||
attachments[ attIdx ],
|
||||
formats[ fmtIdx ].rbFormat,
|
||||
formats[ fmtIdx ].rbType,
|
||||
formats[ fmtIdx ].texFormat,
|
||||
formats[ fmtIdx ].texType,
|
||||
formats[ fmtIdx ].type, seed ) )
|
||||
{
|
||||
log_error( "ERROR: Renderbuffer write test failed for %s : %s : %s : %s\n\n",
|
||||
GetGLAttachmentName( attachments[ attIdx ] ),
|
||||
GetGLFormatName( formats[ fmtIdx ].rbFormat ),
|
||||
GetGLBaseFormatName( formats[ fmtIdx ].rbFormat ),
|
||||
GetGLTypeName( formats[ fmtIdx ].rbType ) );
|
||||
|
||||
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 ].rbFormat ),
|
||||
GetGLBaseFormatName( formats[ fmtIdx ].rbFormat ),
|
||||
GetGLTypeName( formats[ fmtIdx ].rbType ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
119
test_conformance/gles/test_renderbuffer_info.cpp
Normal file
119
test_conformance/gles/test_renderbuffer_info.cpp
Normal file
@@ -0,0 +1,119 @@
|
||||
//
|
||||
// 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 "gl_headers.h"
|
||||
#include "testBase.h"
|
||||
|
||||
extern "C" {extern cl_uint gRandomSeed;};
|
||||
|
||||
static int test_renderbuffer_object_info( cl_context context, cl_command_queue queue,
|
||||
GLsizei width, GLsizei height, GLenum attachment,
|
||||
GLenum rbFormat, GLenum rbType,
|
||||
GLenum texFormat, GLenum texType,
|
||||
ExplicitType type, MTdata d )
|
||||
{
|
||||
int error;
|
||||
|
||||
// Create the GL render buffer
|
||||
glFramebufferWrapper glFramebuffer;
|
||||
glRenderbufferWrapper glRenderbuffer;
|
||||
void* tmp = CreateGLRenderbuffer( width, height, attachment, rbFormat, rbType, texFormat, texType,
|
||||
type, &glFramebuffer, &glRenderbuffer, &error, d, true );
|
||||
BufferOwningPtr<char> inputBuffer(tmp);
|
||||
if( error != 0 )
|
||||
return error;
|
||||
|
||||
clMemWrapper image = (*clCreateFromGLRenderbuffer_ptr)(context, CL_MEM_READ_ONLY, glRenderbuffer, &error);
|
||||
test_error(error, "clCreateFromGLRenderbuffer failed");
|
||||
|
||||
log_info( "- Given a GL format of %s, input type was %s, size was %d x %d\n",
|
||||
GetGLFormatName( rbFormat ),
|
||||
get_explicit_type_name( type ), (int)width, (int)height );
|
||||
|
||||
// Verify the expected information here.
|
||||
return CheckGLObjectInfo(image, CL_GL_OBJECT_RENDERBUFFER, (GLuint)glRenderbuffer, rbFormat, 0);
|
||||
}
|
||||
|
||||
int test_renderbuffer_getinfo( cl_device_id device, cl_context context, cl_command_queue queue, int numElements )
|
||||
{
|
||||
GLenum attachments[] = { GL_COLOR_ATTACHMENT0_EXT };
|
||||
|
||||
struct {
|
||||
GLenum rbFormat;
|
||||
GLenum rbType;
|
||||
GLenum texFormat;
|
||||
GLenum texType;
|
||||
ExplicitType type;
|
||||
|
||||
} formats[] = {
|
||||
{ GL_RGBA8_OES, GL_UNSIGNED_BYTE, GL_RGBA, GL_UNSIGNED_BYTE, kUChar },
|
||||
{ GL_RGBA32F, GL_FLOAT, GL_RGBA, GL_FLOAT, kFloat }
|
||||
};
|
||||
|
||||
size_t fmtIdx, tgtIdx;
|
||||
int error = 0;
|
||||
size_t iter = 6;
|
||||
RandomSeed seed(gRandomSeed);
|
||||
|
||||
// Check if images are supported
|
||||
if (checkForImageSupport(device)) {
|
||||
log_info("Device does not support images. 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( tgtIdx = 0; tgtIdx < sizeof( attachments ) / sizeof( attachments[ 0 ] ); tgtIdx++ )
|
||||
{
|
||||
log_info( "Testing Renderbuffer object info for %s : %s : %s\n",
|
||||
GetGLFormatName( formats[ fmtIdx ].rbFormat ),
|
||||
GetGLBaseFormatName( formats[ fmtIdx ].rbFormat ),
|
||||
GetGLTypeName( formats[ fmtIdx ].type ) );
|
||||
|
||||
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 );
|
||||
|
||||
if( test_renderbuffer_object_info( context, queue, (int)width, (int)height,
|
||||
attachments[ tgtIdx ],
|
||||
formats[ fmtIdx ].rbFormat,
|
||||
formats[ fmtIdx ].rbType,
|
||||
formats[ fmtIdx ].texFormat,
|
||||
formats[ fmtIdx ].texType,
|
||||
formats[ fmtIdx ].type, seed ) )
|
||||
{
|
||||
log_error( "ERROR: Renderbuffer write test failed for GL format %s : %s\n\n",
|
||||
GetGLFormatName( formats[ fmtIdx ].rbFormat ),
|
||||
GetGLTypeName( formats[ fmtIdx ].rbType ) );
|
||||
|
||||
error++;
|
||||
break; // Skip other sizes for this combination
|
||||
}
|
||||
}
|
||||
if( i == iter )
|
||||
{
|
||||
log_info( "passed: Renderbuffer write test passed for GL format %s : %s\n\n",
|
||||
GetGLFormatName( formats[ fmtIdx ].rbFormat ),
|
||||
GetGLTypeName( formats[ fmtIdx ].rbType ) );
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
Reference in New Issue
Block a user