mirror of
https://github.com/KhronosGroup/OpenCL-CTS.git
synced 2026-03-24 15:59:03 +00:00
Initial open source release of OpenCL 2.1 CTS.
This commit is contained in:
63
test_conformance/gl/CMakeLists.txt
Normal file
63
test_conformance/gl/CMakeLists.txt
Normal file
@@ -0,0 +1,63 @@
|
||||
if(WIN32)
|
||||
list(APPEND CLConform_LIBRARIES glut32 opengl32 glu32 )
|
||||
else(WIN32)
|
||||
list(APPEND CLConform_LIBRARIES GL glut GLEW GLU)
|
||||
endif(WIN32)
|
||||
|
||||
set (GL_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
|
||||
../../test_common/gl/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 (WIN32)
|
||||
list (APPEND GL_SOURCES ../../test_common/gl/setup_win32.cpp)
|
||||
else(WIN32)
|
||||
list (APPEND GL_SOURCES ../../test_common/gl/setup_x11.cpp)
|
||||
endif(WIN32)
|
||||
|
||||
# Compiling GLEW along with the project if the compiler is MINGW.
|
||||
# The mingw linker was giving weird errors while linking to glew32.lib generated by
|
||||
# MSVC.
|
||||
if(MINGW)
|
||||
list (APPEND GL_SOURCES GLEW/glew.c)
|
||||
set_source_files_properties(
|
||||
${GL_SOURCES}
|
||||
COMPILE_FLAGS -DGLEW_STATIC)
|
||||
include_directories("./GLEW/")
|
||||
endif(MINGW)
|
||||
|
||||
if (MSVC)
|
||||
if(CMAKE_CL_64)
|
||||
list(APPEND CLConform_LIBRARIES glew64)
|
||||
else(CMAKE_CL_64)
|
||||
list(APPEND CLConform_LIBRARIES glew32)
|
||||
endif(CMAKE_CL_64)
|
||||
endif(MSVC)
|
||||
|
||||
add_executable(conformance_test_gl
|
||||
${GL_SOURCES} ${GLUT_SOURCES})
|
||||
|
||||
set_source_files_properties(
|
||||
${GL_SOURCES}
|
||||
PROPERTIES LANGUAGE CXX)
|
||||
|
||||
TARGET_LINK_LIBRARIES(conformance_test_gl
|
||||
${CLConform_LIBRARIES})
|
||||
12262
test_conformance/gl/GLEW/GL/glew.h
Normal file
12262
test_conformance/gl/GLEW/GL/glew.h
Normal file
File diff suppressed because it is too large
Load Diff
1397
test_conformance/gl/GLEW/GL/glxew.h
Normal file
1397
test_conformance/gl/GLEW/GL/glxew.h
Normal file
File diff suppressed because it is too large
Load Diff
1165
test_conformance/gl/GLEW/GL/wglew.h
Normal file
1165
test_conformance/gl/GLEW/GL/wglew.h
Normal file
File diff suppressed because it is too large
Load Diff
10835
test_conformance/gl/GLEW/glew.c
Normal file
10835
test_conformance/gl/GLEW/glew.c
Normal file
File diff suppressed because it is too large
Load Diff
28
test_conformance/gl/Jamfile
Normal file
28
test_conformance/gl/Jamfile
Normal file
@@ -0,0 +1,28 @@
|
||||
project
|
||||
: requirements
|
||||
# <toolset>gcc:<cflags>-xc++
|
||||
# <toolset>msvc:<cflags>"/TP"
|
||||
;
|
||||
|
||||
exe test_gl
|
||||
: helpers.cpp
|
||||
main.cpp
|
||||
test_buffers.cpp
|
||||
test_images_2D.cpp
|
||||
test_images_2D_info.cpp
|
||||
test_images_3D.cpp
|
||||
test_images_3D_info.cpp
|
||||
test_renderbuffer.cpp
|
||||
test_renderbuffer_info.cpp
|
||||
: <target-os>darwin:<source>setup_osx.cpp
|
||||
<target-os>linux:<source>setup_x11.cpp
|
||||
<target-os>windows:<source>setup_win32.cpp
|
||||
<library>../..//glut
|
||||
<library>../..//glew
|
||||
;
|
||||
|
||||
install dist
|
||||
: test_gl
|
||||
: <variant>debug:<location>$(DIST)/debug/tests/test_conformance/gl
|
||||
<variant>release:<location>$(DIST)/release/tests/test_conformance/gl
|
||||
;
|
||||
62
test_conformance/gl/Makefile
Normal file
62
test_conformance/gl/Makefile
Normal file
@@ -0,0 +1,62 @@
|
||||
ifdef BUILD_WITH_ATF
|
||||
ATF = -framework ATF
|
||||
USE_ATF = -DUSE_ATF
|
||||
endif
|
||||
|
||||
SRCS = main.cpp \
|
||||
helpers.cpp \
|
||||
test_buffers.cpp \
|
||||
test_fence_sync.cpp \
|
||||
test_images_1D.cpp \
|
||||
test_images_1Darray.cpp \
|
||||
test_images_2Darray.cpp \
|
||||
test_images_2D.cpp \
|
||||
test_images_3D.cpp \
|
||||
test_images_getinfo_common.cpp \
|
||||
test_images_read_common.cpp \
|
||||
test_images_write_common.cpp \
|
||||
test_renderbuffer.cpp \
|
||||
test_renderbuffer_info.cpp \
|
||||
test_images_depth.cpp \
|
||||
test_images_multisample.cpp \
|
||||
test_image_methods.cpp \
|
||||
../../test_common/gl/helpers.cpp \
|
||||
../../test_common/gl/setup_osx.cpp \
|
||||
../../test_common/harness/conversions.c \
|
||||
../../test_common/harness/errorHelpers.c \
|
||||
../../test_common/harness/genericThread.cpp \
|
||||
../../test_common/harness/imageHelpers.c \
|
||||
../../test_common/harness/kernelHelpers.c \
|
||||
../../test_common/harness/mt19937.c \
|
||||
../../test_common/harness/testHarness.c \
|
||||
../../test_common/harness/threadTesting.c
|
||||
|
||||
DEFINES =
|
||||
|
||||
SOURCES = $(abspath $(SRCS))
|
||||
LIBPATH += -L/System/Library/Frameworks/OpenCL.framework/Libraries
|
||||
LIBPATH += -L.
|
||||
FRAMEWORK = $(SOURCES)
|
||||
HEADERS =
|
||||
TARGET = test_gl
|
||||
INCLUDE =
|
||||
COMPILERFLAGS = -c -Wall -g -Wshorten-64-to-32
|
||||
CC = c++
|
||||
CFLAGS = $(COMPILERFLAGS) ${RC_CFLAGS} ${USE_ATF} $(DEFINES:%=-D%) $(INCLUDE)
|
||||
CXXFLAGS = $(COMPILERFLAGS) ${RC_CFLAGS} ${USE_ATF} $(DEFINES:%=-D%) $(INCLUDE)
|
||||
LIBRARIES = -framework OpenCL -framework OpenGL -framework GLUT -framework AppKit ${ATF}
|
||||
|
||||
OBJECTS := ${SOURCES:.c=.o}
|
||||
OBJECTS := ${OBJECTS:.cpp=.o}
|
||||
|
||||
TARGETOBJECT =
|
||||
all: $(TARGET)
|
||||
|
||||
$(TARGET): $(OBJECTS)
|
||||
$(CC) $(RC_CFLAGS) $(OBJECTS) -o $@ $(LIBPATH) $(LIBRARIES)
|
||||
|
||||
clean:
|
||||
rm -f $(TARGET) $(OBJECTS)
|
||||
|
||||
.DEFAULT:
|
||||
@echo The target \"$@\" does not exist in Makefile.
|
||||
78
test_conformance/gl/common.h
Normal file
78
test_conformance/gl/common.h
Normal file
@@ -0,0 +1,78 @@
|
||||
//
|
||||
// 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 __COMMON_H__
|
||||
#define __COMMON_H__
|
||||
|
||||
#include "testBase.h"
|
||||
|
||||
typedef struct {
|
||||
size_t width;
|
||||
size_t height;
|
||||
size_t depth;
|
||||
} sizevec_t;
|
||||
|
||||
struct format {
|
||||
GLenum internal;
|
||||
GLenum formattype;
|
||||
GLenum datatype;
|
||||
ExplicitType type;
|
||||
};
|
||||
|
||||
// These are the typically tested formats.
|
||||
|
||||
static struct format common_formats[] = {
|
||||
#ifdef __APPLE__
|
||||
{ GL_RGBA8, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8, kUChar },
|
||||
{ GL_RGBA8, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, kUChar },
|
||||
{ GL_RGBA8, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, kUChar },
|
||||
// { GL_RGB10, GL_BGRA, GL_UNSIGNED_INT_2_10_10_10_REV, kFloat },
|
||||
#endif
|
||||
{ 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 },
|
||||
{ GL_RGBA16F_ARB, GL_RGBA, GL_HALF_FLOAT, kHalf }
|
||||
};
|
||||
|
||||
#ifdef GL_VERSION_3_2
|
||||
static struct format depth_formats[] = {
|
||||
{ GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, kUShort },
|
||||
{ GL_DEPTH_COMPONENT32F, GL_DEPTH_COMPONENT, GL_FLOAT, kFloat },
|
||||
{ GL_DEPTH24_STENCIL8, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, kUInt },
|
||||
{ GL_DEPTH32F_STENCIL8, GL_DEPTH_STENCIL, GL_FLOAT_32_UNSIGNED_INT_24_8_REV, kFloat },
|
||||
};
|
||||
#endif
|
||||
|
||||
int test_images_write_common(cl_device_id device, cl_context context,
|
||||
cl_command_queue queue, struct format* formats, size_t nformats,
|
||||
GLenum *targets, size_t ntargets, sizevec_t* sizes, size_t nsizes );
|
||||
|
||||
int test_images_read_common( cl_device_id device, cl_context context,
|
||||
cl_command_queue queue, struct format* formats, size_t nformats,
|
||||
GLenum *targets, size_t ntargets, sizevec_t *sizes, size_t nsizes );
|
||||
|
||||
int test_images_get_info_common( cl_device_id device, cl_context context,
|
||||
cl_command_queue queue, struct format* formats, size_t nformats,
|
||||
GLenum *targets, size_t ntargets, sizevec_t *sizes, size_t nsizes );
|
||||
|
||||
int is_rgb_101010_supported( cl_context context, GLenum gl_target );
|
||||
|
||||
#endif // __COMMON_H__
|
||||
657
test_conformance/gl/helpers.cpp
Normal file
657
test_conformance/gl/helpers.cpp
Normal file
@@ -0,0 +1,657 @@
|
||||
//
|
||||
// Copyright (c) 2017 The Khronos Group Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
#include "testBase.h"
|
||||
#if defined( __APPLE__ )
|
||||
#include <OpenGL/glu.h>
|
||||
#else
|
||||
#include <GL/glu.h>
|
||||
#endif
|
||||
|
||||
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_UNORM_INT24:
|
||||
case CL_SNORM_INT8:
|
||||
case CL_SNORM_INT16:
|
||||
case CL_HALF_FLOAT:
|
||||
case CL_FLOAT:
|
||||
case CL_UNORM_INT_101010:
|
||||
return "f";
|
||||
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:
|
||||
log_error("Test error: unsupported kernel suffix for image_channel_data_type 0x%X\n",format->image_channel_data_type);
|
||||
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_UNORM_INT24:
|
||||
case CL_SNORM_INT8:
|
||||
case CL_SNORM_INT16:
|
||||
case CL_HALF_FLOAT:
|
||||
case CL_FLOAT:
|
||||
case CL_UNORM_INT_101010:
|
||||
#ifdef GL_VERSION_3_2
|
||||
case CL_DEPTH:
|
||||
#endif
|
||||
return kFloat;
|
||||
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:
|
||||
log_error("Test error: unsupported kernel suffix for image_channel_data_type 0x%X\n",format->image_channel_data_type);
|
||||
return kNumExplicitTypes;
|
||||
}
|
||||
}
|
||||
|
||||
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_UNORM_INT24:
|
||||
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;
|
||||
case CL_UNORM_INT_101010:
|
||||
return kFloat;
|
||||
#ifdef GL_VERSION_3_2
|
||||
case CL_DEPTH:
|
||||
return kFloat;
|
||||
#endif
|
||||
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_HALF_FLOAT:
|
||||
case CL_FLOAT:
|
||||
case CL_UNORM_INT_101010:
|
||||
case CL_UNORM_INT24:
|
||||
if(type != kFloat) return "convert_float4";
|
||||
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, size_t channelNum, GLenum glDataType )
|
||||
{
|
||||
#ifdef 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 * channelNum * get_explicit_type_size(outType) ] ; // sizeof( cl_int ) ];
|
||||
if (glDataType == GL_FLOAT_32_UNSIGNED_INT_24_8_REV) {
|
||||
for (size_t i = 0; i < numPixels; ++i) {
|
||||
((cl_float*)outData)[i] = ((cl_float*)inputBuffer)[2 * i];
|
||||
}
|
||||
}
|
||||
else {
|
||||
memcpy( outData, inputBuffer, numPixels * channelNum * 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 * channelNum ];
|
||||
for( size_t i = 0; i < numPixels * channelNum; 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 * channelNum ];
|
||||
for( size_t i = 0; i < numPixels * channelNum; 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 * channelNum ];
|
||||
for( size_t i = 0; i < numPixels * channelNum; 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 * channelNum ];
|
||||
for( size_t i = 0; i < numPixels * channelNum; 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 * channelNum ];
|
||||
for( size_t i = 0; i < numPixels * channelNum; 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 * channelNum ];
|
||||
for( size_t i = 0; i < numPixels * channelNum; 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 * channelNum ];
|
||||
for( size_t i = 0; i < numPixels * channelNum; 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 * channelNum ];
|
||||
for( size_t i = 0; i < numPixels * channelNum; 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 * channelNum ];
|
||||
for( size_t i = 0; i < numPixels * channelNum; 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 * channelNum ];
|
||||
const cl_float MaxValue = (glDataType == GL_UNSIGNED_INT_24_8) ? 16777215.f : 4294967295.f;
|
||||
const cl_uint ShiftBits = (glDataType == GL_UNSIGNED_INT_24_8) ? 8 : 0;
|
||||
for( size_t i = 0; i < numPixels * channelNum; i++ )
|
||||
{
|
||||
outData[ i ] = (cl_float)(src[ i ] >> ShiftBits) / MaxValue;
|
||||
}
|
||||
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 == kHalf )
|
||||
{
|
||||
cl_half *src = (cl_half *)inputBuffer;
|
||||
|
||||
switch( outType )
|
||||
{
|
||||
case kFloat:
|
||||
{
|
||||
cl_float *outData = new cl_float[ numPixels * channelNum ];
|
||||
for( size_t i = 0; i < numPixels * channelNum; i++ )
|
||||
{
|
||||
outData[ i ] = convert_half_to_float(src[ i ]);
|
||||
}
|
||||
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 sampleNum, size_t typeSize )
|
||||
{
|
||||
return validate_integer_results( expectedResults, actualResults, width, height, sampleNum, 0, typeSize );
|
||||
}
|
||||
|
||||
int validate_integer_results( void *expectedResults, void *actualResults, size_t width, size_t height, size_t depth, size_t sampleNum, size_t typeSize )
|
||||
{
|
||||
char *expected = (char *)expectedResults;
|
||||
char *actual = (char *)actualResults;
|
||||
for ( size_t s = 0; s < sampleNum; s++ )
|
||||
{
|
||||
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,%d did not validate!\n", (int)x, (int)y, (int)s );
|
||||
else
|
||||
log_error( "ERROR: Data sample %d,%d,%d,%d did not validate!\n", (int)x, (int)y, (int)z, (int)s );
|
||||
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, size_t sampleNum, size_t channelNum )
|
||||
{
|
||||
return validate_float_results( expectedResults, actualResults, width, height, sampleNum, 0, channelNum );
|
||||
}
|
||||
|
||||
int validate_float_results( void *expectedResults, void *actualResults, size_t width, size_t height, size_t depth, size_t sampleNum, size_t channelNum )
|
||||
{
|
||||
cl_float *expected = (cl_float *)expectedResults;
|
||||
cl_float *actual = (cl_float *)actualResults;
|
||||
for ( size_t s = 0; s < sampleNum; s++ )
|
||||
{
|
||||
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 < channelNum; 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,%d did not validate!\n", (int)x, (int)y, (int)s );
|
||||
else
|
||||
log_error( "ERROR: Data sample %d,%d,%d,%d did not validate!\n", (int)x, (int)y, (int)z, (int)s );
|
||||
|
||||
if (channelNum == 4)
|
||||
{
|
||||
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 ] );
|
||||
}
|
||||
else if(channelNum == 1)
|
||||
{
|
||||
log_error( "\tExpected: %f\n", expected[ 0 ] );
|
||||
log_error( "\t : %a\n", expected[ 0 ] );
|
||||
log_error( "\t Actual: %f\n", actual[ 0 ] );
|
||||
log_error( "\t : %a\n", actual[ 0 ] );
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
expected += channelNum;
|
||||
actual += channelNum;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int validate_float_results_rgb_101010( void *expectedResults, void *actualResults, size_t width, size_t height, size_t sampleNum )
|
||||
{
|
||||
return validate_float_results_rgb_101010( expectedResults, actualResults, width, height, sampleNum, 0 );
|
||||
}
|
||||
|
||||
int validate_float_results_rgb_101010( void *expectedResults, void *actualResults, size_t width, size_t height, size_t depth, size_t sampleNum )
|
||||
{
|
||||
cl_float *expected = (cl_float *)expectedResults;
|
||||
cl_float *actual = (cl_float *)actualResults;
|
||||
for ( size_t s = 0; s < sampleNum; s++ )
|
||||
{
|
||||
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 < 3; i++ ) // skip the fourth channel
|
||||
{
|
||||
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,%d did not validate!\n", (int)x, (int)y, (int)s );
|
||||
else
|
||||
log_error( "ERROR: Data sample %d,%d,%d,%d did not validate!\n", (int)x, (int)y, (int)z, (int)s );
|
||||
log_error( "\tExpected: %f %f %f\n", expected[ 0 ], expected[ 1 ], expected[ 2 ] );
|
||||
log_error( "\t : %a %a %a\n", expected[ 0 ], expected[ 1 ], expected[ 2 ] );
|
||||
log_error( "\t Actual: %f %f %f\n", actual[ 0 ], actual[ 1 ], actual[ 2 ] );
|
||||
log_error( "\t : %a %a %a\n", actual[ 0 ], actual[ 1 ], actual[ 2 ] );
|
||||
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 we're dealing with a buffer or render buffer, we are done.
|
||||
|
||||
if (object_type == CL_GL_OBJECT_BUFFER || object_type == CL_GL_OBJECT_RENDERBUFFER) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Otherwise, it's a texture-based object and requires a bit more checking.
|
||||
|
||||
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")));
|
||||
}
|
||||
|
||||
int is_rgb_101010_supported( cl_context context, GLenum gl_target )
|
||||
{
|
||||
cl_image_format formatList[ 128 ];
|
||||
cl_uint formatCount = 0;
|
||||
unsigned int i;
|
||||
int error;
|
||||
|
||||
cl_mem_object_type image_type;
|
||||
|
||||
switch (get_base_gl_target(gl_target)) {
|
||||
case GL_TEXTURE_1D:
|
||||
image_type = CL_MEM_OBJECT_IMAGE1D;
|
||||
case GL_TEXTURE_BUFFER:
|
||||
image_type = CL_MEM_OBJECT_IMAGE1D_BUFFER;
|
||||
break;
|
||||
case GL_TEXTURE_RECTANGLE_EXT:
|
||||
case GL_TEXTURE_2D:
|
||||
case GL_COLOR_ATTACHMENT0:
|
||||
case GL_RENDERBUFFER:
|
||||
case GL_TEXTURE_CUBE_MAP:
|
||||
case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
|
||||
case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
|
||||
case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
|
||||
case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
|
||||
case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
|
||||
case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
|
||||
image_type = CL_MEM_OBJECT_IMAGE2D;
|
||||
break;
|
||||
case GL_TEXTURE_3D:
|
||||
image_type = CL_MEM_OBJECT_IMAGE3D;
|
||||
case GL_TEXTURE_1D_ARRAY:
|
||||
image_type = CL_MEM_OBJECT_IMAGE1D_ARRAY;
|
||||
case GL_TEXTURE_2D_ARRAY:
|
||||
image_type = CL_MEM_OBJECT_IMAGE2D_ARRAY;
|
||||
break;
|
||||
default:
|
||||
image_type = CL_MEM_OBJECT_IMAGE2D;
|
||||
}
|
||||
|
||||
if ((error = clGetSupportedImageFormats(context, CL_MEM_READ_WRITE,
|
||||
image_type, 128, formatList,
|
||||
&formatCount ))) {
|
||||
return error;
|
||||
}
|
||||
|
||||
// Check if the RGB 101010 format is supported
|
||||
for( i = 0; i < formatCount; i++ )
|
||||
{
|
||||
if( formatList[ i ].image_channel_data_type == CL_UNORM_INT_101010 )
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
453
test_conformance/gl/main.cpp
Normal file
453
test_conformance/gl/main.cpp
Normal file
@@ -0,0 +1,453 @@
|
||||
//
|
||||
// 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 "../../test_common/harness/compat.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#if !defined (__APPLE__)
|
||||
#include <CL/cl.h>
|
||||
#endif
|
||||
|
||||
#include "procs.h"
|
||||
#include "../../test_common/gl/setup.h"
|
||||
#include "../../test_common/harness/testHarness.h"
|
||||
#include "../../test_common/harness/parseParameters.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 = clCreateCommandQueueWithProperties( sCurrentContext, device, 0, &error ); \
|
||||
test_error( error, "Unable to create command queue" ); \
|
||||
return fn( device, sCurrentContext, realQueue, numElements ); \
|
||||
}
|
||||
|
||||
// buffers:
|
||||
TEST_FN_REDIRECTOR( test_buffers )
|
||||
TEST_FN_REDIRECTOR( test_buffers_getinfo )
|
||||
|
||||
// 1D images:
|
||||
TEST_FN_REDIRECTOR( test_images_read_1D )
|
||||
TEST_FN_REDIRECTOR( test_images_write_1D )
|
||||
TEST_FN_REDIRECTOR( test_images_1D_getinfo )
|
||||
|
||||
// 1D image arrays:
|
||||
TEST_FN_REDIRECTOR( test_images_read_1Darray )
|
||||
TEST_FN_REDIRECTOR( test_images_write_1Darray )
|
||||
TEST_FN_REDIRECTOR( test_images_1Darray_getinfo )
|
||||
|
||||
// 2D images:
|
||||
TEST_FN_REDIRECTOR( test_images_read_2D )
|
||||
TEST_FN_REDIRECTOR( test_images_read_cube )
|
||||
TEST_FN_REDIRECTOR( test_images_write )
|
||||
TEST_FN_REDIRECTOR( test_images_write_cube )
|
||||
TEST_FN_REDIRECTOR( test_images_2D_getinfo )
|
||||
TEST_FN_REDIRECTOR( test_images_cube_getinfo )
|
||||
|
||||
// 2D image arrays:
|
||||
TEST_FN_REDIRECTOR( test_images_read_2Darray )
|
||||
TEST_FN_REDIRECTOR( test_images_write_2Darray )
|
||||
TEST_FN_REDIRECTOR( test_images_2Darray_getinfo )
|
||||
|
||||
// 3D images:
|
||||
TEST_FN_REDIRECTOR( test_images_read_3D )
|
||||
TEST_FN_REDIRECTOR( test_images_write_3D )
|
||||
TEST_FN_REDIRECTOR( test_images_3D_getinfo )
|
||||
|
||||
#ifdef GL_VERSION_3_2
|
||||
|
||||
TEST_FN_REDIRECTOR( test_images_read_texturebuffer )
|
||||
TEST_FN_REDIRECTOR( test_images_write_texturebuffer )
|
||||
TEST_FN_REDIRECTOR( test_images_texturebuffer_getinfo )
|
||||
|
||||
// depth textures
|
||||
TEST_FN_REDIRECTOR( test_images_read_2D_depth )
|
||||
TEST_FN_REDIRECTOR( test_images_write_2D_depth )
|
||||
TEST_FN_REDIRECTOR( test_images_read_2Darray_depth )
|
||||
TEST_FN_REDIRECTOR( test_images_write_2Darray_depth )
|
||||
|
||||
TEST_FN_REDIRECTOR( test_images_read_2D_multisample )
|
||||
TEST_FN_REDIRECTOR( test_images_read_2Darray_multisample )
|
||||
TEST_FN_REDIRECTOR( test_image_methods_depth );
|
||||
TEST_FN_REDIRECTOR( test_image_methods_multisample );
|
||||
#endif
|
||||
|
||||
// Renderbuffer-backed images:
|
||||
TEST_FN_REDIRECTOR( test_renderbuffer_read )
|
||||
TEST_FN_REDIRECTOR( test_renderbuffer_write )
|
||||
TEST_FN_REDIRECTOR( test_renderbuffer_getinfo )
|
||||
|
||||
TEST_FN_REDIRECTOR( test_fence_sync )
|
||||
|
||||
basefn basefn_list[] = {
|
||||
TEST_FN_REDIRECT( test_buffers ),
|
||||
TEST_FN_REDIRECT( test_buffers_getinfo ),
|
||||
|
||||
TEST_FN_REDIRECT( test_images_read_1D ),
|
||||
TEST_FN_REDIRECT( test_images_write_1D ),
|
||||
TEST_FN_REDIRECT( test_images_1D_getinfo ),
|
||||
|
||||
TEST_FN_REDIRECT( test_images_read_1Darray ),
|
||||
TEST_FN_REDIRECT( test_images_write_1Darray ),
|
||||
TEST_FN_REDIRECT( test_images_1Darray_getinfo ),
|
||||
|
||||
TEST_FN_REDIRECT( test_images_read_2D ),
|
||||
TEST_FN_REDIRECT( test_images_write ),
|
||||
TEST_FN_REDIRECT( test_images_2D_getinfo ),
|
||||
|
||||
TEST_FN_REDIRECT( test_images_read_cube ),
|
||||
TEST_FN_REDIRECT( test_images_write_cube ),
|
||||
TEST_FN_REDIRECT( test_images_cube_getinfo ),
|
||||
|
||||
TEST_FN_REDIRECT( test_images_read_2Darray ),
|
||||
TEST_FN_REDIRECT( test_images_write_2Darray),
|
||||
TEST_FN_REDIRECT( test_images_2Darray_getinfo ),
|
||||
|
||||
TEST_FN_REDIRECT( test_images_read_3D ),
|
||||
TEST_FN_REDIRECT( test_images_write_3D ),
|
||||
TEST_FN_REDIRECT( test_images_3D_getinfo ),
|
||||
|
||||
TEST_FN_REDIRECT( test_renderbuffer_read ),
|
||||
TEST_FN_REDIRECT( test_renderbuffer_write ),
|
||||
TEST_FN_REDIRECT( test_renderbuffer_getinfo )
|
||||
};
|
||||
|
||||
basefn basefn_list32[] = {
|
||||
TEST_FN_REDIRECT( test_images_read_texturebuffer ),
|
||||
TEST_FN_REDIRECT( test_images_write_texturebuffer ),
|
||||
TEST_FN_REDIRECT( test_images_texturebuffer_getinfo ),
|
||||
|
||||
TEST_FN_REDIRECT( test_fence_sync ),
|
||||
TEST_FN_REDIRECT( test_images_read_2D_depth ),
|
||||
TEST_FN_REDIRECT( test_images_write_2D_depth ),
|
||||
TEST_FN_REDIRECT( test_images_read_2Darray_depth ),
|
||||
TEST_FN_REDIRECT( test_images_write_2Darray_depth ),
|
||||
TEST_FN_REDIRECT( test_images_read_2D_multisample ),
|
||||
TEST_FN_REDIRECT( test_images_read_2Darray_multisample ),
|
||||
TEST_FN_REDIRECT( test_image_methods_depth ),
|
||||
TEST_FN_REDIRECT( test_image_methods_multisample)
|
||||
};
|
||||
|
||||
const char *basefn_names[] = {
|
||||
"buffers",
|
||||
"buffers_getinfo",
|
||||
|
||||
"images_read_1D",
|
||||
"images_write_1D",
|
||||
"images_1D_getinfo",
|
||||
|
||||
"images_read_1Darray",
|
||||
"images_write_1Darray",
|
||||
"images_1Darray_getinfo",
|
||||
|
||||
"images_read", /* 2D */
|
||||
"images_write",
|
||||
"images_2D_getinfo",
|
||||
|
||||
"images_read_cube",
|
||||
"images_write_cube",
|
||||
"images_cube_getinfo",
|
||||
|
||||
"images_read_2Darray",
|
||||
"images_write_2Darray",
|
||||
"images_2Darray_getinfo",
|
||||
|
||||
"images_read_3D",
|
||||
"images_write_3D",
|
||||
"images_3D_getinfo",
|
||||
|
||||
"renderbuffer_read",
|
||||
"renderbuffer_write",
|
||||
"renderbuffer_getinfo",
|
||||
};
|
||||
|
||||
const char *basefn_names32[] = {
|
||||
"images_read_texturebuffer",
|
||||
"images_write_texturebuffer",
|
||||
"images_texturebuffer_getinfo",
|
||||
|
||||
"fence_sync",
|
||||
"images_read_2D_depth",
|
||||
"images_write_2D_depth",
|
||||
"images_read_2D_array_depth",
|
||||
"images_write_2D_array_depth",
|
||||
|
||||
"images_read_2D_multisample",
|
||||
"images_read_2D_array_multisample",
|
||||
"image_methods_depth",
|
||||
"image_methods_multisample",
|
||||
};
|
||||
|
||||
ct_assert((sizeof(basefn_names) / sizeof(basefn_names[0])) == (sizeof(basefn_list) / sizeof(basefn_list[0])));
|
||||
ct_assert((sizeof(basefn_names32) / sizeof(basefn_names32[0])) == (sizeof(basefn_list32) / sizeof(basefn_list32[0])));
|
||||
|
||||
int num_fns = sizeof(basefn_names) / sizeof(char *);
|
||||
int num_fns32 = sizeof(basefn_names32) / sizeof(char *);
|
||||
|
||||
cl_device_type gDeviceType = CL_DEVICE_TYPE_DEFAULT;
|
||||
bool gTestRounding = true;
|
||||
|
||||
int main(int argc, const char *argv[])
|
||||
{
|
||||
int error = 0;
|
||||
int numErrors = 0;
|
||||
|
||||
test_start();
|
||||
argc = parseCustomParam(argc, argv);
|
||||
if (argc == -1)
|
||||
{
|
||||
test_finish ();
|
||||
return -1;
|
||||
}
|
||||
|
||||
cl_device_type requestedDeviceType = CL_DEVICE_TYPE_DEFAULT;
|
||||
checkDeviceTypeOverride(&requestedDeviceType);
|
||||
|
||||
/* Do we have a CPU/GPU specification? */
|
||||
if( argc > 1 )
|
||||
{
|
||||
if( strcmp( argv[ argc - 1 ], "gpu" ) == 0 || strcmp( argv[ argc - 1 ], "CL_DEVICE_TYPE_GPU" ) == 0 )
|
||||
{
|
||||
requestedDeviceType = CL_DEVICE_TYPE_GPU;
|
||||
argc--;
|
||||
}
|
||||
else if( strcmp( argv[ argc - 1 ], "cpu" ) == 0 || strcmp( argv[ argc - 1 ], "CL_DEVICE_TYPE_CPU" ) == 0 )
|
||||
{
|
||||
requestedDeviceType = CL_DEVICE_TYPE_CPU;
|
||||
argc--;
|
||||
}
|
||||
else if( strcmp( argv[ argc - 1 ], "accelerator" ) == 0 || strcmp( argv[ argc - 1 ], "CL_DEVICE_TYPE_ACCELERATOR" ) == 0 )
|
||||
{
|
||||
requestedDeviceType = CL_DEVICE_TYPE_ACCELERATOR;
|
||||
argc--;
|
||||
}
|
||||
else if( strcmp( argv[ argc - 1 ], "CL_DEVICE_TYPE_DEFAULT" ) == 0 )
|
||||
{
|
||||
requestedDeviceType = CL_DEVICE_TYPE_DEFAULT;
|
||||
argc--;
|
||||
}
|
||||
}
|
||||
|
||||
if( argc > 1 && strcmp( argv[ 1 ], "-list" ) == 0 )
|
||||
{
|
||||
log_info( "Available 2.x tests:\n" );
|
||||
for( int i = 0; i < num_fns; i++ )
|
||||
log_info( "\t%s\n", basefn_names[ i ] );
|
||||
|
||||
log_info( "Available 3.2 tests:\n" );
|
||||
for( int i = 0; i < num_fns32; 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.\n" );
|
||||
log_info( "Use environment variables to specify desired device.\n" );
|
||||
|
||||
test_finish();
|
||||
return 0;
|
||||
}
|
||||
|
||||
// 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;++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();
|
||||
return 0;
|
||||
} else if ( supported == -1 ) {
|
||||
log_error("Unable to setup the test or failed to determine if CL-GL interop is supported.\n");
|
||||
test_finish();
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Initialize function pointers.
|
||||
error = init_clgl_ext();
|
||||
if (error < 0) {
|
||||
return error;
|
||||
}
|
||||
|
||||
// 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();
|
||||
return -1;
|
||||
}
|
||||
|
||||
// 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();
|
||||
return -1;
|
||||
}
|
||||
|
||||
size_t numDevices = 0;
|
||||
cl_device_id *deviceIDs;
|
||||
|
||||
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();
|
||||
return -1;
|
||||
}
|
||||
deviceIDs = (cl_device_id *)malloc(numDevices);
|
||||
if (deviceIDs == NULL) {
|
||||
print_error( error, "malloc failed" );
|
||||
test_finish();
|
||||
return -1;
|
||||
}
|
||||
error = clGetContextInfo( sCurrentContext, CL_CONTEXT_DEVICES, numDevices, deviceIDs, NULL);
|
||||
if( error != CL_SUCCESS ) {
|
||||
print_error( error, "Unable to get device list from context" );
|
||||
test_finish();
|
||||
return -1;
|
||||
}
|
||||
|
||||
numDevices /= sizeof(cl_device_id);
|
||||
|
||||
if (numDevices < 1) {
|
||||
log_error("No devices found.\n");
|
||||
test_finish();
|
||||
return -1;
|
||||
}
|
||||
|
||||
// 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();
|
||||
return -1;
|
||||
}
|
||||
|
||||
// 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_fns, basefn_list, basefn_names, true, 0, 1024 );
|
||||
if( error != 0 )
|
||||
break;
|
||||
}
|
||||
|
||||
numErrors += error;
|
||||
|
||||
// Clean-up.
|
||||
free(deviceIDs);
|
||||
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();
|
||||
return -1;
|
||||
}
|
||||
|
||||
// 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();
|
||||
return -1;
|
||||
}
|
||||
|
||||
size_t numDevices = 0;
|
||||
cl_device_id *deviceIDs;
|
||||
|
||||
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();
|
||||
return -1;
|
||||
}
|
||||
deviceIDs = (cl_device_id *)malloc(numDevices);
|
||||
if (deviceIDs == NULL) {
|
||||
print_error( error, "malloc failed" );
|
||||
test_finish();
|
||||
return -1;
|
||||
}
|
||||
error = clGetContextInfo( sCurrentContext, CL_CONTEXT_DEVICES, numDevices, deviceIDs, NULL);
|
||||
if( error != CL_SUCCESS ) {
|
||||
print_error( error, "Unable to get device list from context" );
|
||||
test_finish();
|
||||
return -1;
|
||||
}
|
||||
|
||||
numDevices /= sizeof(cl_device_id);
|
||||
|
||||
if (numDevices < 1) {
|
||||
log_error("No devices found.\n");
|
||||
test_finish();
|
||||
return -1;
|
||||
}
|
||||
|
||||
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();
|
||||
return -1;
|
||||
}
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
numErrors += error;
|
||||
|
||||
// Clean-up.
|
||||
free(deviceIDs);
|
||||
clReleaseContext( sCurrentContext );
|
||||
delete glEnv;
|
||||
|
||||
}
|
||||
|
||||
//All done.
|
||||
return numErrors;
|
||||
}
|
||||
|
||||
|
||||
140
test_conformance/gl/procs.h
Normal file
140
test_conformance/gl/procs.h
Normal file
@@ -0,0 +1,140 @@
|
||||
//
|
||||
// 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"
|
||||
|
||||
|
||||
#pragma mark -
|
||||
#pragma Misc tests
|
||||
|
||||
extern int test_buffers( cl_device_id device, cl_context context,
|
||||
cl_command_queue queue, int num_elements );
|
||||
|
||||
extern int test_fence_sync( cl_device_id device, cl_context context,
|
||||
cl_command_queue queue, int numElements );
|
||||
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark Tead tests
|
||||
|
||||
extern int test_images_read_2D( cl_device_id device, cl_context context,
|
||||
cl_command_queue queue, int num_elements );
|
||||
|
||||
extern int test_images_read_1D( cl_device_id device, cl_context context,
|
||||
cl_command_queue queue, int num_elements );
|
||||
|
||||
extern int test_images_read_texturebuffer( cl_device_id device, cl_context context,
|
||||
cl_command_queue queue, int num_elements );
|
||||
|
||||
extern int test_images_read_1Darray( cl_device_id device, cl_context context,
|
||||
cl_command_queue queue, int num_elements );
|
||||
|
||||
extern int test_images_read_2Darray( cl_device_id device, cl_context context,
|
||||
cl_command_queue queue, int num_elements );
|
||||
|
||||
extern int test_images_read_cube( cl_device_id device, cl_context context,
|
||||
cl_command_queue queue, int num_elements );
|
||||
|
||||
extern int test_images_read_3D( 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 );
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark Write tests
|
||||
|
||||
// 2D tests are the ones with no suffix:
|
||||
|
||||
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_write( cl_device_id device, cl_context context,
|
||||
cl_command_queue queue, int num_elements );
|
||||
|
||||
// Here are the rest:
|
||||
|
||||
extern int test_images_write_1D( cl_device_id device, cl_context context,
|
||||
cl_command_queue queue, int num_elements );
|
||||
|
||||
extern int test_images_write_texturebuffer( cl_device_id device, cl_context context,
|
||||
cl_command_queue queue, int num_elements );
|
||||
|
||||
extern int test_images_write_1Darray( cl_device_id device, cl_context context,
|
||||
cl_command_queue queue, int num_elements );
|
||||
|
||||
extern int test_images_write_2Darray( cl_device_id device, cl_context context,
|
||||
cl_command_queue queue, int num_elements );
|
||||
|
||||
extern int test_images_write_3D( cl_device_id device, cl_context context,
|
||||
cl_command_queue queue, int num_elements );
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark Get info test entry points
|
||||
|
||||
extern int test_buffers_getinfo( cl_device_id device, cl_context context,
|
||||
cl_command_queue queue, int numElements );
|
||||
|
||||
extern int test_images_1D_getinfo( cl_device_id device, cl_context context,
|
||||
cl_command_queue queue, int numElements );
|
||||
|
||||
extern int test_images_texturebuffer_getinfo( cl_device_id device, cl_context context,
|
||||
cl_command_queue queue, int numElements );
|
||||
|
||||
extern int test_images_1Darray_getinfo( cl_device_id device, cl_context context,
|
||||
cl_command_queue queue, int numElements );
|
||||
|
||||
extern int test_images_2D_getinfo( cl_device_id device, cl_context context,
|
||||
cl_command_queue queue, int numElements );
|
||||
|
||||
extern int test_images_2Darray_getinfo( cl_device_id device, cl_context context,
|
||||
cl_command_queue queue, int numElements );
|
||||
|
||||
extern int test_images_cube_getinfo( cl_device_id device, cl_context context,
|
||||
cl_command_queue queue, int numElements );
|
||||
|
||||
extern int test_images_3D_getinfo( cl_device_id device, cl_context context,
|
||||
cl_command_queue queue, int numElements );
|
||||
|
||||
extern int test_images_read_2D_depth( cl_device_id device, cl_context context,
|
||||
cl_command_queue queue, int numElements );
|
||||
|
||||
extern int test_images_write_2D_depth( cl_device_id device, cl_context context,
|
||||
cl_command_queue queue, int numElements );
|
||||
|
||||
extern int test_images_read_2Darray_depth( cl_device_id device, cl_context context,
|
||||
cl_command_queue queue, int );
|
||||
|
||||
extern int test_images_write_2Darray_depth( cl_device_id device, cl_context context,
|
||||
cl_command_queue queue, int numElements );
|
||||
|
||||
extern int test_images_read_2D_multisample( cl_device_id device, cl_context context,
|
||||
cl_command_queue queue, int numElements );
|
||||
|
||||
extern int test_images_read_2Darray_multisample( cl_device_id device, cl_context context,
|
||||
cl_command_queue queue, int );
|
||||
|
||||
extern int test_image_methods_depth( cl_device_id device, cl_context context,
|
||||
cl_command_queue queue, int );
|
||||
|
||||
extern int test_image_methods_multisample( cl_device_id device, cl_context context,
|
||||
cl_command_queue queue, int );
|
||||
|
||||
extern int test_renderbuffer_getinfo( cl_device_id device, cl_context context,
|
||||
cl_command_queue queue, int numElements );
|
||||
65
test_conformance/gl/testBase.h
Normal file
65
test_conformance/gl/testBase.h
Normal file
@@ -0,0 +1,65 @@
|
||||
//
|
||||
// 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 "../../test_common/harness/compat.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#if !defined (__APPLE__)
|
||||
#include <CL/cl.h>
|
||||
#include "../../test_common/gl/gl_headers.h"
|
||||
#include <CL/cl_gl.h>
|
||||
#else
|
||||
#include "../../test_common/gl/gl_headers.h"
|
||||
#endif
|
||||
|
||||
#include "../../test_common/harness/imageHelpers.h"
|
||||
#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"
|
||||
|
||||
#include "../../test_common/gl/helpers.h"
|
||||
|
||||
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, size_t channelNum, GLenum glDataType = 0);
|
||||
extern int validate_integer_results( void *expectedResults, void *actualResults, size_t width, size_t height, size_t sampleNum, size_t typeSize );
|
||||
extern int validate_integer_results( void *expectedResults, void *actualResults, size_t width, size_t height, size_t depth, size_t sampleNum, size_t typeSize );
|
||||
extern int validate_float_results( void *expectedResults, void *actualResults, size_t width, size_t height, size_t sampleNum, size_t channelNum );
|
||||
extern int validate_float_results( void *expectedResults, void *actualResults, size_t width, size_t height, size_t depth, size_t sampleNum, size_t channelNum );
|
||||
extern int validate_float_results_rgb_101010( void *expectedResults, void *actualResults, size_t width, size_t height, size_t sampleNum );
|
||||
extern int validate_float_results_rgb_101010( void *expectedResults, void *actualResults, size_t width, size_t height, size_t depth, size_t sampleNum );
|
||||
|
||||
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
|
||||
|
||||
|
||||
|
||||
357
test_conformance/gl/test_buffers.cpp
Normal file
357
test_conformance/gl/test_buffers.cpp
Normal file
@@ -0,0 +1,357 @@
|
||||
//
|
||||
// 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/conversions.h"
|
||||
#include "../../test_common/harness/typeWrappers.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 = glMapBuffer( GL_ARRAY_BUFFER, GL_READ_ONLY );
|
||||
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;
|
||||
|
||||
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);
|
||||
|
||||
|
||||
for( typeIndex = 0; vecType[ typeIndex ] != kNumExplicitTypes; typeIndex++ )
|
||||
{
|
||||
for( index = 0; vecSizes[ index ] != 0; index++ )
|
||||
{
|
||||
// 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 );
|
||||
|
||||
|
||||
for( typeIndex = 0; vecType[ typeIndex ] != kNumExplicitTypes; typeIndex++ )
|
||||
{
|
||||
for( index = 0; vecSizes[ index ] != 0; index++ )
|
||||
{
|
||||
// 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;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
730
test_conformance/gl/test_fence_sync.cpp
Normal file
730
test_conformance/gl/test_fence_sync.cpp
Normal file
@@ -0,0 +1,730 @@
|
||||
//
|
||||
// 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/gl/setup.h"
|
||||
#include "../../test_common/harness/genericThread.h"
|
||||
|
||||
#if defined( __APPLE__ )
|
||||
#include <OpenGL/glu.h>
|
||||
#else
|
||||
#include <GL/glu.h>
|
||||
#include <CL/cl_gl.h>
|
||||
#if !defined(_WIN32) && !defined(__ANDROID__)
|
||||
#include <GL/glx.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#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;
|
||||
|
||||
#ifndef APIENTRY
|
||||
#define APIENTRY
|
||||
#endif
|
||||
|
||||
typedef GLsync (APIENTRY *glFenceSyncPtr)(GLenum condition,GLbitfield flags);
|
||||
glFenceSyncPtr glFenceSyncFunc;
|
||||
|
||||
typedef bool (APIENTRY *glIsSyncPtr)(GLsync sync);
|
||||
glIsSyncPtr glIsSyncFunc;
|
||||
|
||||
typedef void (APIENTRY *glDeleteSyncPtr)(GLsync sync);
|
||||
glDeleteSyncPtr glDeleteSyncFunc;
|
||||
|
||||
typedef GLenum (APIENTRY *glClientWaitSyncPtr)(GLsync sync,GLbitfield flags,GLuint64 timeout);
|
||||
glClientWaitSyncPtr glClientWaitSyncFunc;
|
||||
|
||||
typedef void (APIENTRY *glWaitSyncPtr)(GLsync sync,GLbitfield flags,GLuint64 timeout);
|
||||
glWaitSyncPtr glWaitSyncFunc;
|
||||
|
||||
typedef void (APIENTRY *glGetInteger64vPtr)(GLenum pname, GLint64 *params);
|
||||
glGetInteger64vPtr glGetInteger64vFunc;
|
||||
|
||||
typedef void (APIENTRY *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 =
|
||||
"#version 150\n"
|
||||
"uniform mat4 projMatrix;\n"
|
||||
"in vec4 inPosition;\n"
|
||||
"in vec4 inColor;\n"
|
||||
"out vec4 vertColor;\n"
|
||||
"void main (void) {\n"
|
||||
" gl_Position = projMatrix*inPosition;\n"
|
||||
" vertColor = inColor;\n"
|
||||
"}\n";
|
||||
|
||||
//Passthrough FragmentShader
|
||||
static const char *fragmentshader =
|
||||
"#version 150\n"
|
||||
"in vec4 vertColor;\n"
|
||||
"out vec4 outColor;\n"
|
||||
"void main (void) {\n"
|
||||
" outColor = vertColor;\n"
|
||||
"}\n";
|
||||
|
||||
GLuint createShaderProgram(GLint *posLoc, GLint *colLoc)
|
||||
{
|
||||
GLint logLength, status;
|
||||
GLuint program = glCreateProgram();
|
||||
GLuint vpShader;
|
||||
|
||||
vpShader = glCreateShader(GL_VERTEX_SHADER);
|
||||
glShaderSource(vpShader, 1, (const GLchar **)&vertexshader, 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);
|
||||
}
|
||||
|
||||
glGetShaderiv(vpShader, GL_COMPILE_STATUS, &status);
|
||||
if (status == 0)
|
||||
{
|
||||
log_error("Failed to compile vtx shader:\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
glAttachShader(program, vpShader);
|
||||
|
||||
GLuint fpShader;
|
||||
fpShader = glCreateShader(GL_FRAGMENT_SHADER);
|
||||
glShaderSource(fpShader, 1, (const GLchar **)&fragmentshader, NULL);
|
||||
glCompileShader(fpShader);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
*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;
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
// Ask OpenCL for the platforms. Warn if more than one platform found,
|
||||
// since this might not be the platform we want. By default, we simply
|
||||
// use the first returned platform.
|
||||
|
||||
cl_uint nplatforms;
|
||||
cl_platform_id platform;
|
||||
clGetPlatformIDs(0, NULL, &nplatforms);
|
||||
clGetPlatformIDs(1, &platform, NULL);
|
||||
|
||||
if (nplatforms > 1) {
|
||||
log_info("clGetPlatformIDs returned multiple values. This is not "
|
||||
"an error, but might result in obtaining incorrect function "
|
||||
"pointers if you do not want the first returned platform.\n");
|
||||
|
||||
// Show them the platform name, in case it is a problem.
|
||||
|
||||
size_t size;
|
||||
char *name;
|
||||
|
||||
clGetPlatformInfo(platform, CL_PLATFORM_NAME, 0, NULL, &size);
|
||||
name = (char*)malloc(size);
|
||||
clGetPlatformInfo(platform, CL_PLATFORM_NAME, size, name, NULL);
|
||||
|
||||
log_info("Using platform with name: %s \n", name);
|
||||
free(name);
|
||||
}
|
||||
|
||||
clCreateEventFromGLsyncKHR_ptr = (clCreateEventFromGLsyncKHR_fn)clGetExtensionFunctionAddressForPlatform(platform, "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, "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
|
||||
#ifdef _WIN32
|
||||
HDC hdc = wglGetCurrentDC();
|
||||
HGLRC hglrc = wglGetCurrentContext();
|
||||
#else
|
||||
Display* dpy = glXGetCurrentDisplay();
|
||||
GLXDrawable drawable = glXGetCurrentDrawable();
|
||||
GLXContext ctx = glXGetCurrentContext();
|
||||
#endif
|
||||
#endif
|
||||
|
||||
InitSyncFns();
|
||||
#endif
|
||||
|
||||
#ifdef __APPLE__
|
||||
CGLSetVirtualScreen(CGLGetCurrentContext(), rend_vs);
|
||||
#else
|
||||
#ifdef _WIN32
|
||||
wglMakeCurrent(hdc, hglrc);
|
||||
#else
|
||||
glXMakeCurrent(dpy, drawable, ctx);
|
||||
#endif
|
||||
#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_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV,
|
||||
&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 );
|
||||
|
||||
// Now that the requisite objects are bound, we can attempt program
|
||||
// validation:
|
||||
|
||||
glValidateProgram(shaderprogram);
|
||||
|
||||
GLint logLength, status;
|
||||
glGetProgramiv(shaderprogram, GL_INFO_LOG_LENGTH, &logLength);
|
||||
if (logLength > 0) {
|
||||
GLchar *log = (GLchar*)malloc(logLength);
|
||||
glGetProgramInfoLog(shaderprogram, logLength, &logLength, log);
|
||||
log_info("Program validate log:\n%s", log);
|
||||
free(log);
|
||||
}
|
||||
|
||||
glGetProgramiv(shaderprogram, GL_VALIDATE_STATUS, &status);
|
||||
if (status == 0)
|
||||
{
|
||||
log_error("Failed to validate program\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
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 )
|
||||
{
|
||||
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();
|
||||
|
||||
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();
|
||||
}
|
||||
else
|
||||
glFinish();
|
||||
}
|
||||
|
||||
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
|
||||
#ifdef _WIN32
|
||||
wglMakeCurrent(hdc, hglrc);
|
||||
#else
|
||||
glXMakeCurrent(dpy, drawable, ctx);
|
||||
#endif
|
||||
#endif
|
||||
// Grab the contents of the final framebuffer
|
||||
BufferOwningPtr<char> resultData( ReadGLRenderbuffer( glFramebuffer, glRenderbuffer,
|
||||
GL_COLOR_ATTACHMENT0_EXT,
|
||||
GL_RGBA, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
size_t device_cb;
|
||||
cl_int err = clGetContextInfo( context, CL_CONTEXT_DEVICES, 0, NULL, &device_cb);
|
||||
if( err != CL_SUCCESS )
|
||||
{
|
||||
print_error( err, "Unable to get device count from context" );
|
||||
test_finish();
|
||||
return -1;
|
||||
}
|
||||
vs_count = (GLint)device_cb / sizeof(cl_device_id);
|
||||
|
||||
if (vs_count < 1) {
|
||||
log_error("No devices found.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
device_list = (cl_device_id *) malloc(device_cb);
|
||||
err = clGetContextInfo( context, CL_CONTEXT_DEVICES, device_cb, device_list, NULL);
|
||||
if( err != CL_SUCCESS ) {
|
||||
free(device_list);
|
||||
print_error( err, "Unable to get device list from context" );
|
||||
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;
|
||||
}
|
||||
405
test_conformance/gl/test_image_methods.cpp
Normal file
405
test_conformance/gl/test_image_methods.cpp
Normal file
@@ -0,0 +1,405 @@
|
||||
//
|
||||
// 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 "common.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
using namespace std;
|
||||
|
||||
typedef struct image_kernel_data
|
||||
{
|
||||
cl_int width;
|
||||
cl_int height;
|
||||
cl_int depth;
|
||||
cl_int arraySize;
|
||||
cl_int widthDim;
|
||||
cl_int heightDim;
|
||||
cl_int channelType;
|
||||
cl_int channelOrder;
|
||||
cl_int expectedChannelType;
|
||||
cl_int expectedChannelOrder;
|
||||
cl_int numSamples;
|
||||
};
|
||||
|
||||
static const char *methodTestKernelPattern =
|
||||
"typedef struct {\n"
|
||||
" int width;\n"
|
||||
" int height;\n"
|
||||
" int depth;\n"
|
||||
" int arraySize;\n"
|
||||
" int widthDim;\n"
|
||||
" int heightDim;\n"
|
||||
" int channelType;\n"
|
||||
" int channelOrder;\n"
|
||||
" int expectedChannelType;\n"
|
||||
" int expectedChannelOrder;\n"
|
||||
" int numSamples;\n"
|
||||
" } image_kernel_data;\n"
|
||||
"__kernel void sample_kernel( read_only %s input, __global image_kernel_data *outData )\n"
|
||||
"{\n"
|
||||
"%s%s%s%s%s%s%s%s%s%s%s"
|
||||
"}\n";
|
||||
|
||||
static const char *arraySizeKernelLine =
|
||||
" outData->arraySize = get_image_array_size( input );\n";
|
||||
static const char *imageWidthKernelLine =
|
||||
" outData->width = get_image_width( input );\n";
|
||||
static const char *imageHeightKernelLine =
|
||||
" outData->height = get_image_height( input );\n";
|
||||
static const char *imageDimKernelLine =
|
||||
" int2 dim = get_image_dim( input );\n";
|
||||
static const char *imageWidthDimKernelLine =
|
||||
" outData->widthDim = dim.x;\n";
|
||||
static const char *imageHeightDimKernelLine =
|
||||
" outData->heightDim = dim.y;\n";
|
||||
static const char *channelTypeKernelLine =
|
||||
" outData->channelType = get_image_channel_data_type( input );\n";
|
||||
static const char *channelTypeConstLine =
|
||||
" outData->expectedChannelType = CLK_%s;\n";
|
||||
static const char *channelOrderKernelLine =
|
||||
" outData->channelOrder = get_image_channel_order( input );\n";
|
||||
static const char *channelOrderConstLine =
|
||||
" outData->expectedChannelOrder = CLK_%s;\n";
|
||||
static const char *numSamplesKernelLine =
|
||||
" outData->numSamples = get_image_num_samples( input );\n";
|
||||
|
||||
static int verify(cl_int input, cl_int kernelOutput, const char * description)
|
||||
{
|
||||
if( kernelOutput != input )
|
||||
{
|
||||
log_error( "ERROR: %s did not validate (expected %d, got %d)\n", description, input, kernelOutput);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern int supportsMsaa(cl_context context, bool* supports_msaa);
|
||||
extern int supportsDepth(cl_context context, bool* supports_depth);
|
||||
|
||||
int test_image_format_methods( cl_device_id device, cl_context context, cl_command_queue queue,
|
||||
size_t width, size_t height, size_t arraySize, size_t samples,
|
||||
GLenum target, format format, MTdata d )
|
||||
{
|
||||
int error, result=0;
|
||||
|
||||
clProgramWrapper program;
|
||||
clKernelWrapper kernel;
|
||||
clMemWrapper image, outDataBuffer;
|
||||
char programSrc[ 10240 ];
|
||||
|
||||
image_kernel_data outKernelData;
|
||||
|
||||
#ifdef GL_VERSION_3_2
|
||||
if (get_base_gl_target(target) == GL_TEXTURE_2D_MULTISAMPLE ||
|
||||
get_base_gl_target(target) == GL_TEXTURE_2D_MULTISAMPLE_ARRAY)
|
||||
{
|
||||
bool supports_msaa;
|
||||
error = supportsMsaa(context, &supports_msaa);
|
||||
if( error != 0 ) return error;
|
||||
if (!supports_msaa) return 0;
|
||||
}
|
||||
if (format.formattype == GL_DEPTH_COMPONENT ||
|
||||
format.formattype == GL_DEPTH_STENCIL)
|
||||
{
|
||||
bool supports_depth;
|
||||
error = supportsDepth(context, &supports_depth);
|
||||
if( error != 0 ) return error;
|
||||
if (!supports_depth) return 0;
|
||||
}
|
||||
#endif
|
||||
DetectFloatToHalfRoundingMode(queue);
|
||||
|
||||
glTextureWrapper glTexture;
|
||||
switch (get_base_gl_target(target)) {
|
||||
case GL_TEXTURE_2D:
|
||||
CreateGLTexture2D( width, height, target,
|
||||
format.formattype, format.internal, format.datatype,
|
||||
format.type, &glTexture, &error, false, d );
|
||||
break;
|
||||
case GL_TEXTURE_2D_ARRAY:
|
||||
CreateGLTexture2DArray( width, height, arraySize, target,
|
||||
format.formattype, format.internal, format.datatype,
|
||||
format.type, &glTexture, &error, false, d );
|
||||
break;
|
||||
case GL_TEXTURE_2D_MULTISAMPLE:
|
||||
CreateGLTexture2DMultisample( width, height, samples, target,
|
||||
format.formattype, format.internal, format.datatype,
|
||||
format.type, &glTexture, &error, false, d, false);
|
||||
break;
|
||||
case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
|
||||
CreateGLTexture2DArrayMultisample( width, height, arraySize, samples, target,
|
||||
format.formattype, format.internal, format.datatype,
|
||||
format.type, &glTexture, &error, false, d, false);
|
||||
break;
|
||||
|
||||
default:
|
||||
log_error("Unsupported GL tex target (%s) passed to write test: "
|
||||
"%s (%s):%d", GetGLTargetName(target), __FUNCTION__,
|
||||
__FILE__, __LINE__);
|
||||
}
|
||||
|
||||
// Check to see if the texture could not be created for some other reason like
|
||||
// GL_FRAMEBUFFER_UNSUPPORTED
|
||||
if (error == GL_FRAMEBUFFER_UNSUPPORTED) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Construct testing source
|
||||
log_info( " - Creating image %d by %d...\n", width, height );
|
||||
// Create a CL image from the supplied GL texture
|
||||
image = (*clCreateFromGLTexture_ptr)( context, CL_MEM_READ_ONLY,
|
||||
target, 0, glTexture, &error );
|
||||
|
||||
if ( error != CL_SUCCESS ) {
|
||||
print_error( error, "Unable to create CL image from GL texture" );
|
||||
GLint fmt;
|
||||
glGetTexLevelParameteriv( target, 0, GL_TEXTURE_INTERNAL_FORMAT, &fmt );
|
||||
log_error( " Supplied GL texture was base format %s and internal "
|
||||
"format %s\n", GetGLBaseFormatName( fmt ), GetGLFormatName( fmt ) );
|
||||
return error;
|
||||
}
|
||||
|
||||
cl_image_format imageFormat;
|
||||
error = clGetImageInfo (image, CL_IMAGE_FORMAT,
|
||||
sizeof(imageFormat), &imageFormat, NULL);
|
||||
test_error(error, "Failed to get image format");
|
||||
|
||||
const char * imageType = 0;
|
||||
bool doArraySize = false;
|
||||
bool doImageWidth = false;
|
||||
bool doImageHeight = false;
|
||||
bool doImageChannelDataType = false;
|
||||
bool doImageChannelOrder = false;
|
||||
bool doImageDim = false;
|
||||
bool doNumSamples = false;
|
||||
switch(target) {
|
||||
case GL_TEXTURE_2D:
|
||||
imageType = "image2d_depth_t";
|
||||
doImageWidth = true;
|
||||
doImageHeight = true;
|
||||
doImageChannelDataType = true;
|
||||
doImageChannelOrder = true;
|
||||
doImageDim = true;
|
||||
break;
|
||||
case GL_TEXTURE_2D_ARRAY:
|
||||
imageType = "image2d_array_depth_t";
|
||||
doImageWidth = true;
|
||||
doImageHeight = true;
|
||||
doArraySize = true;
|
||||
doImageChannelDataType = true;
|
||||
doImageChannelOrder = true;
|
||||
doImageDim = true;
|
||||
doArraySize = true;
|
||||
break;
|
||||
case GL_TEXTURE_2D_MULTISAMPLE:
|
||||
doNumSamples = true;
|
||||
if(format.formattype == GL_DEPTH_COMPONENT) {
|
||||
doImageWidth = true;
|
||||
imageType = "image2d_msaa_depth_t";
|
||||
} else {
|
||||
imageType = "image2d_msaa_t";
|
||||
}
|
||||
break;
|
||||
case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
|
||||
if(format.formattype == GL_DEPTH_COMPONENT) {
|
||||
doImageWidth = true;
|
||||
imageType = "image2d_msaa_array_depth_t";
|
||||
} else {
|
||||
imageType = "image2d_array_msaa_t";
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
|
||||
char channelTypeConstKernelLine[512] = {0};
|
||||
char channelOrderConstKernelLine[512] = {0};
|
||||
const char* channelTypeName=0;
|
||||
const char* channelOrderName=0;
|
||||
if(doImageChannelDataType) {
|
||||
channelTypeName = GetChannelTypeName( imageFormat.image_channel_data_type );
|
||||
if(channelTypeName && strlen(channelTypeName)) {
|
||||
// replace CL_* with CLK_*
|
||||
sprintf(channelTypeConstKernelLine, channelTypeConstLine, &channelTypeName[3]);
|
||||
}
|
||||
}
|
||||
if(doImageChannelOrder) {
|
||||
channelOrderName = GetChannelOrderName( imageFormat.image_channel_order );
|
||||
if(channelOrderName && strlen(channelOrderName)) {
|
||||
// replace CL_* with CLK_*
|
||||
sprintf(channelOrderConstKernelLine, channelOrderConstLine, &channelOrderName[3]);
|
||||
}
|
||||
}
|
||||
|
||||
// Create a program to run against
|
||||
sprintf( programSrc, methodTestKernelPattern,
|
||||
imageType,
|
||||
( doArraySize ) ? arraySizeKernelLine : "",
|
||||
( doImageWidth ) ? imageWidthKernelLine : "",
|
||||
( doImageHeight ) ? imageHeightKernelLine : "",
|
||||
( doImageChannelDataType ) ? channelTypeKernelLine : "",
|
||||
( doImageChannelDataType ) ? channelTypeConstKernelLine : "",
|
||||
( doImageChannelOrder ) ? channelOrderKernelLine : "",
|
||||
( doImageChannelOrder ) ? channelOrderConstKernelLine : "",
|
||||
( doImageDim ) ? imageDimKernelLine : "",
|
||||
( doImageDim && doImageWidth ) ? imageWidthDimKernelLine : "",
|
||||
( doImageDim && doImageHeight ) ? imageHeightDimKernelLine : "",
|
||||
( doNumSamples ) ? numSamplesKernelLine : "");
|
||||
|
||||
|
||||
//log_info("-----------------------------------\n%s\n", programSrc);
|
||||
error = clFinish(queue);
|
||||
if (error)
|
||||
print_error(error, "clFinish failed.\n");
|
||||
const char *ptr = programSrc;
|
||||
error = create_single_kernel_helper( context, &program, &kernel, 1, &ptr, "sample_kernel" );
|
||||
test_error( error, "Unable to create kernel to test against" );
|
||||
|
||||
// Create an output buffer
|
||||
outDataBuffer = clCreateBuffer( context, (cl_mem_flags)(CL_MEM_READ_WRITE), sizeof( outKernelData ), NULL, &error );
|
||||
test_error( error, "Unable to create output buffer" );
|
||||
|
||||
// Set up arguments and run
|
||||
error = clSetKernelArg( kernel, 0, sizeof( image ), &image );
|
||||
test_error( error, "Unable to set kernel argument" );
|
||||
error = clSetKernelArg( kernel, 1, sizeof( outDataBuffer ), &outDataBuffer );
|
||||
test_error( error, "Unable to set kernel argument" );
|
||||
|
||||
// Flush and Acquire.
|
||||
glFlush();
|
||||
error = (*clEnqueueAcquireGLObjects_ptr)( queue, 1, &image, 0, NULL, NULL);
|
||||
test_error( error, "Unable to acquire GL obejcts");
|
||||
|
||||
size_t threads[1] = { 1 }, localThreads[1] = { 1 };
|
||||
|
||||
error = clEnqueueNDRangeKernel( queue, kernel, 1, NULL, threads, localThreads, 0, NULL, NULL );
|
||||
test_error( error, "Unable to run kernel" );
|
||||
|
||||
error = clEnqueueReadBuffer( queue, outDataBuffer, CL_TRUE, 0, sizeof( outKernelData ), &outKernelData, 0, NULL, NULL );
|
||||
test_error( error, "Unable to read data buffer" );
|
||||
|
||||
// Verify the results now
|
||||
if( doImageWidth )
|
||||
result |= verify(width, outKernelData.width, "width");
|
||||
if( doImageHeight)
|
||||
result |= verify(height, outKernelData.height, "height");
|
||||
if( doImageDim && doImageWidth )
|
||||
result |= verify(width, outKernelData.widthDim, "width from get_image_dim");
|
||||
if( doImageDim && doImageHeight )
|
||||
result |= verify(height, outKernelData.heightDim, "height from get_image_dim");
|
||||
if( doImageChannelDataType )
|
||||
result |= verify(outKernelData.channelType, outKernelData.expectedChannelType, channelTypeName);
|
||||
if( doImageChannelOrder )
|
||||
result |= verify(outKernelData.channelOrder, outKernelData.expectedChannelOrder, channelOrderName);
|
||||
if( doArraySize )
|
||||
result |= verify(arraySize, outKernelData.arraySize, "array size");
|
||||
if( doNumSamples )
|
||||
result |= verify(samples, outKernelData.numSamples, "samples");
|
||||
if(result) {
|
||||
log_error("Test image methods failed");
|
||||
}
|
||||
|
||||
clEventWrapper event;
|
||||
error = (*clEnqueueReleaseGLObjects_ptr)( queue, 1, &image, 0, NULL, &event );
|
||||
test_error(error, "clEnqueueReleaseGLObjects failed");
|
||||
|
||||
error = clWaitForEvents( 1, &event );
|
||||
test_error(error, "clWaitForEvents failed");
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
int test_image_methods_depth( cl_device_id device, cl_context context, cl_command_queue queue, int numElements ){
|
||||
if (!is_extension_available(device, "cl_khr_gl_depth_images")) {
|
||||
log_info("Test not run because 'cl_khr_gl_depth_images' extension is not supported by the tested device\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t pixelSize;
|
||||
int result = 0;
|
||||
GLenum depth_targets[] = {GL_TEXTURE_2D, GL_TEXTURE_2D_ARRAY};
|
||||
size_t ntargets = sizeof(depth_targets) / sizeof(depth_targets[0]);
|
||||
size_t nformats = sizeof(depth_formats) / sizeof(depth_formats[0]);
|
||||
|
||||
const size_t nsizes = 5;
|
||||
sizevec_t sizes[nsizes];
|
||||
// Need to limit texture size according to GL device properties
|
||||
GLint maxTextureSize = 4096, maxTextureRectangleSize = 4096, maxTextureLayers = 16, size;
|
||||
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxTextureSize);
|
||||
glGetIntegerv(GL_MAX_RECTANGLE_TEXTURE_SIZE_EXT, &maxTextureRectangleSize);
|
||||
glGetIntegerv(GL_MAX_ARRAY_TEXTURE_LAYERS, &maxTextureLayers);
|
||||
|
||||
size = min(maxTextureSize, maxTextureRectangleSize);
|
||||
|
||||
RandomSeed seed( gRandomSeed );
|
||||
|
||||
// Generate some random sizes (within reasonable ranges)
|
||||
for (size_t i = 0; i < nsizes; i++) {
|
||||
sizes[i].width = random_in_range( 2, min(size, 1<<(i+4)), seed );
|
||||
sizes[i].height = random_in_range( 2, min(size, 1<<(i+4)), seed );
|
||||
sizes[i].depth = random_in_range( 2, min(maxTextureLayers, 1<<(i+4)), seed );
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < nsizes; i++) {
|
||||
for(size_t itarget = 0; itarget < ntargets; ++itarget) {
|
||||
for(size_t iformat = 0; iformat < nformats; ++iformat)
|
||||
result |= test_image_format_methods(device, context, queue, sizes[i].width, sizes[i].height, (depth_targets[itarget] == GL_TEXTURE_2D_ARRAY) ? sizes[i].depth: 1, 0,
|
||||
depth_targets[itarget], depth_formats[iformat], seed );
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
int test_image_methods_multisample( cl_device_id device, cl_context context, cl_command_queue queue, int numElements ){
|
||||
if (!is_extension_available(device, "cl_khr_gl_msaa_sharing")) {
|
||||
log_info("Test not run because 'cl_khr_gl_msaa_sharing' extension is not supported by the tested device\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t pixelSize;
|
||||
int result = 0;
|
||||
GLenum targets[] = {GL_TEXTURE_2D_MULTISAMPLE, GL_TEXTURE_2D_MULTISAMPLE_ARRAY};
|
||||
size_t ntargets = sizeof(targets) / sizeof(targets[0]);
|
||||
size_t nformats = sizeof(common_formats) / sizeof(common_formats[0]);
|
||||
|
||||
const size_t nsizes = 5;
|
||||
sizevec_t sizes[nsizes];
|
||||
GLint maxTextureLayers = 16, maxTextureSize = 4096;
|
||||
glGetIntegerv(GL_MAX_ARRAY_TEXTURE_LAYERS, &maxTextureLayers);
|
||||
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxTextureSize);
|
||||
|
||||
RandomSeed seed( gRandomSeed );
|
||||
|
||||
// Generate some random sizes (within reasonable ranges)
|
||||
for (size_t i = 0; i < nsizes; i++) {
|
||||
sizes[i].width = random_in_range( 2, min(maxTextureSize, 1<<(i+4)), seed );
|
||||
sizes[i].height = random_in_range( 2, min(maxTextureSize, 1<<(i+4)), seed );
|
||||
sizes[i].depth = random_in_range( 2, min(maxTextureLayers, 1<<(i+4)), seed );
|
||||
}
|
||||
|
||||
glEnable(GL_MULTISAMPLE);
|
||||
|
||||
for (size_t i = 0; i < nsizes; i++) {
|
||||
for(size_t itarget = 0; itarget < ntargets; ++itarget) {
|
||||
for(size_t iformat = 0; iformat < nformats; ++iformat) {
|
||||
GLint samples = get_gl_max_samples(targets[itarget], common_formats[iformat].internal);
|
||||
result |= test_image_format_methods(device, context, queue, sizes[i].width, sizes[i].height, (targets[ntargets] == GL_TEXTURE_2D_MULTISAMPLE_ARRAY) ? sizes[i].depth: 1,
|
||||
samples, targets[itarget], common_formats[iformat], seed );
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
141
test_conformance/gl/test_images_1D.cpp
Normal file
141
test_conformance/gl/test_images_1D.cpp
Normal file
@@ -0,0 +1,141 @@
|
||||
//
|
||||
// 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 "common.h"
|
||||
#include "testBase.h"
|
||||
|
||||
#if defined( __APPLE__ )
|
||||
#include <OpenGL/glu.h>
|
||||
#else
|
||||
#include <GL/glu.h>
|
||||
#include <CL/cl_gl.h>
|
||||
#endif
|
||||
#include <algorithm>
|
||||
|
||||
using namespace std;
|
||||
|
||||
void calc_test_size_descriptors(sizevec_t* sizes, size_t nsizes)
|
||||
{
|
||||
// Need to limit array size according to GL device properties
|
||||
GLint maxTextureSize = 4096, maxTextureBufferSize = 4096, size;
|
||||
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxTextureSize);
|
||||
glGetIntegerv(GL_MAX_TEXTURE_BUFFER_SIZE, &maxTextureBufferSize);
|
||||
|
||||
size = min(maxTextureSize, maxTextureBufferSize);
|
||||
|
||||
RandomSeed seed( gRandomSeed );
|
||||
|
||||
// Generate some random sizes (within reasonable ranges)
|
||||
for (size_t i = 0; i < nsizes; i++) {
|
||||
sizes[i].width = random_in_range( 2, min(size, 1<<(i+4)), seed );
|
||||
sizes[i].height = 1;
|
||||
sizes[i].depth = 1;
|
||||
}
|
||||
}
|
||||
|
||||
int test_images_read_1D( cl_device_id device, cl_context context,
|
||||
cl_command_queue queue, int numElements )
|
||||
{
|
||||
size_t nformats = sizeof(common_formats) / sizeof(common_formats[0]);
|
||||
|
||||
GLenum targets[] = { GL_TEXTURE_1D };
|
||||
size_t ntargets = sizeof(targets) / sizeof(targets[0]);
|
||||
|
||||
const size_t nsizes = 8;
|
||||
sizevec_t sizes[nsizes];
|
||||
calc_test_size_descriptors(sizes, nsizes);
|
||||
|
||||
return test_images_read_common(device, context, queue, common_formats,
|
||||
nformats, targets, ntargets, sizes, nsizes);
|
||||
}
|
||||
|
||||
int test_images_write_1D( cl_device_id device, cl_context context,
|
||||
cl_command_queue queue, int numElements )
|
||||
{
|
||||
GLenum targets[] = { GL_TEXTURE_1D };
|
||||
size_t ntargets = sizeof(targets) / sizeof(targets[0]);
|
||||
size_t nformats = sizeof(common_formats) / sizeof(common_formats[0]);
|
||||
|
||||
const size_t nsizes = 8;
|
||||
sizevec_t sizes[nsizes];
|
||||
calc_test_size_descriptors(sizes, nsizes);
|
||||
|
||||
return test_images_write_common( device, context, queue, common_formats,
|
||||
nformats, targets, ntargets, sizes, nsizes );
|
||||
}
|
||||
|
||||
int test_images_1D_getinfo( cl_device_id device, cl_context context,
|
||||
cl_command_queue queue, int numElements )
|
||||
{
|
||||
size_t nformats = sizeof(common_formats) / sizeof(common_formats[0]);
|
||||
|
||||
GLenum targets[] = { GL_TEXTURE_1D };
|
||||
size_t ntargets = sizeof(targets) / sizeof(targets[0]);
|
||||
|
||||
const size_t nsizes = 8;
|
||||
sizevec_t sizes[nsizes];
|
||||
calc_test_size_descriptors(sizes, nsizes);
|
||||
|
||||
return test_images_get_info_common( device, context, queue, common_formats,
|
||||
nformats, targets, ntargets, sizes, nsizes);
|
||||
}
|
||||
|
||||
int test_images_read_texturebuffer( cl_device_id device, cl_context context,
|
||||
cl_command_queue queue, int numElements )
|
||||
{
|
||||
size_t nformats = sizeof(common_formats) / sizeof(common_formats[0]);
|
||||
|
||||
GLenum targets[] = { GL_TEXTURE_BUFFER };
|
||||
size_t ntargets = sizeof(targets) / sizeof(targets[0]);
|
||||
|
||||
const size_t nsizes = 8;
|
||||
sizevec_t sizes[nsizes];
|
||||
calc_test_size_descriptors(sizes, nsizes);
|
||||
|
||||
return test_images_read_common(device, context, queue, common_formats,
|
||||
nformats, targets, ntargets, sizes, nsizes);
|
||||
}
|
||||
|
||||
int test_images_write_texturebuffer( cl_device_id device, cl_context context,
|
||||
cl_command_queue queue, int numElements )
|
||||
{
|
||||
GLenum targets[] = { GL_TEXTURE_BUFFER };
|
||||
size_t ntargets = sizeof(targets) / sizeof(targets[0]);
|
||||
size_t nformats = sizeof(common_formats) / sizeof(common_formats[0]);
|
||||
|
||||
const size_t nsizes = 8;
|
||||
sizevec_t sizes[nsizes];
|
||||
calc_test_size_descriptors(sizes, nsizes);
|
||||
|
||||
return test_images_write_common( device, context, queue, common_formats,
|
||||
nformats, targets, ntargets, sizes, nsizes );
|
||||
}
|
||||
|
||||
int test_images_texturebuffer_getinfo( cl_device_id device, cl_context context,
|
||||
cl_command_queue queue, int numElements )
|
||||
{
|
||||
size_t nformats = sizeof(common_formats) / sizeof(common_formats[0]);
|
||||
|
||||
GLenum targets[] = { GL_TEXTURE_BUFFER };
|
||||
size_t ntargets = sizeof(targets) / sizeof(targets[0]);
|
||||
|
||||
const size_t nsizes = 8;
|
||||
sizevec_t sizes[nsizes];
|
||||
calc_test_size_descriptors(sizes, nsizes);
|
||||
|
||||
return test_images_get_info_common( device, context, queue, common_formats,
|
||||
nformats, targets, ntargets, sizes, nsizes);
|
||||
}
|
||||
|
||||
90
test_conformance/gl/test_images_1Darray.cpp
Normal file
90
test_conformance/gl/test_images_1Darray.cpp
Normal file
@@ -0,0 +1,90 @@
|
||||
//
|
||||
// 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 "common.h"
|
||||
#include "testBase.h"
|
||||
|
||||
#if defined( __APPLE__ )
|
||||
#include <OpenGL/glu.h>
|
||||
#else
|
||||
#include <GL/glu.h>
|
||||
#include <CL/cl_gl.h>
|
||||
#endif
|
||||
#include <algorithm>
|
||||
|
||||
using namespace std;
|
||||
void calc_1D_array_size_descriptors(sizevec_t* sizes, size_t nsizes)
|
||||
{
|
||||
// Need to limit array size according to GL device properties
|
||||
GLint maxTextureLayers = 16, maxTextureSize = 4096;
|
||||
glGetIntegerv(GL_MAX_ARRAY_TEXTURE_LAYERS, &maxTextureLayers);
|
||||
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxTextureSize);
|
||||
|
||||
RandomSeed seed( gRandomSeed );
|
||||
|
||||
// Generate some random sizes (within reasonable ranges)
|
||||
for (size_t i = 0; i < nsizes; i++) {
|
||||
sizes[i].width = random_in_range( 2, min(maxTextureSize, 1<<(i+4)), seed );
|
||||
sizes[i].height = random_in_range( 2, min(maxTextureLayers, 1<<(i+4)), seed );
|
||||
sizes[i].depth = 1;
|
||||
}
|
||||
}
|
||||
|
||||
int test_images_read_1Darray( cl_device_id device, cl_context context,
|
||||
cl_command_queue queue, int )
|
||||
{
|
||||
size_t nformats = sizeof(common_formats) / sizeof(common_formats[0]);
|
||||
|
||||
GLenum targets[] = { GL_TEXTURE_1D_ARRAY };
|
||||
size_t ntargets = sizeof(targets) / sizeof(targets[0]);
|
||||
|
||||
const size_t nsizes = 8;
|
||||
sizevec_t sizes[nsizes];
|
||||
calc_1D_array_size_descriptors(sizes, nsizes);
|
||||
|
||||
return test_images_read_common(device, context, queue, common_formats,
|
||||
nformats, targets, ntargets, sizes, nsizes);
|
||||
}
|
||||
|
||||
int test_images_write_1Darray( cl_device_id device, cl_context context,
|
||||
cl_command_queue queue, int numElements )
|
||||
{
|
||||
GLenum targets[] = { GL_TEXTURE_1D_ARRAY };
|
||||
size_t ntargets = sizeof(targets) / sizeof(targets[0]);
|
||||
size_t nformats = sizeof(common_formats) / sizeof(common_formats[0]);
|
||||
|
||||
const size_t nsizes = 8;
|
||||
sizevec_t sizes[nsizes];
|
||||
calc_1D_array_size_descriptors(sizes, nsizes);
|
||||
|
||||
return test_images_write_common( device, context, queue, common_formats,
|
||||
nformats, targets, ntargets, sizes, nsizes );
|
||||
}
|
||||
|
||||
int test_images_1Darray_getinfo( cl_device_id device, cl_context context,
|
||||
cl_command_queue queue, int )
|
||||
{
|
||||
size_t nformats = sizeof(common_formats) / sizeof(common_formats[0]);
|
||||
|
||||
GLenum targets[] = { GL_TEXTURE_1D_ARRAY };
|
||||
size_t ntargets = sizeof(targets) / sizeof(targets[0]);
|
||||
|
||||
const size_t nsizes = 8;
|
||||
sizevec_t sizes[nsizes];
|
||||
calc_1D_array_size_descriptors(sizes, nsizes);
|
||||
|
||||
return test_images_get_info_common(device, context, queue, common_formats,
|
||||
nformats, targets, ntargets, sizes, nsizes);
|
||||
}
|
||||
190
test_conformance/gl/test_images_2D.cpp
Normal file
190
test_conformance/gl/test_images_2D.cpp
Normal file
@@ -0,0 +1,190 @@
|
||||
//
|
||||
// Copyright (c) 2017 The Khronos Group Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
#include "testBase.h"
|
||||
#include "common.h"
|
||||
|
||||
#if defined( __APPLE__ )
|
||||
#include <OpenGL/glu.h>
|
||||
#else
|
||||
#include <GL/glu.h>
|
||||
#include <CL/cl_gl.h>
|
||||
#endif
|
||||
#include <algorithm>
|
||||
|
||||
using namespace std;
|
||||
|
||||
extern "C" { extern cl_uint gRandomSeed; }
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark _2D read tests
|
||||
|
||||
void calc_2D_test_size_descriptors(sizevec_t* sizes, size_t nsizes)
|
||||
{
|
||||
// Need to limit array size according to GL device properties
|
||||
// Need to limit texture size according to GL device properties
|
||||
GLint maxTextureSize = 4096, maxTextureRectangleSize = 4096, size;
|
||||
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxTextureSize);
|
||||
glGetIntegerv(GL_MAX_RECTANGLE_TEXTURE_SIZE_EXT, &maxTextureRectangleSize);
|
||||
|
||||
size = min(maxTextureSize, maxTextureRectangleSize);
|
||||
|
||||
RandomSeed seed( gRandomSeed );
|
||||
|
||||
// Generate some random sizes (within reasonable ranges)
|
||||
for (size_t i = 0; i < nsizes; i++) {
|
||||
sizes[i].width = random_in_range( 2, min(size, 1<<(i+4)), seed );
|
||||
sizes[i].height = random_in_range( 2, min(size, 1<<(i+4)), seed );
|
||||
sizes[i].depth = 1;
|
||||
}
|
||||
}
|
||||
|
||||
void calc_cube_test_size_descriptors(sizevec_t* sizes, size_t nsizes)
|
||||
{
|
||||
// Need to limit array size according to GL device properties
|
||||
// Need to limit texture size according to GL device properties
|
||||
GLint maxQubeMapSize = 4096;
|
||||
glGetIntegerv(GL_MAX_CUBE_MAP_TEXTURE_SIZE, &maxQubeMapSize);
|
||||
|
||||
RandomSeed seed( gRandomSeed );
|
||||
|
||||
// Generate some random sizes (within reasonable ranges)
|
||||
for (size_t i = 0; i < nsizes; i++) {
|
||||
sizes[i].width = sizes[i].height = random_in_range( 2, min(maxQubeMapSize, 1<<(i+4)), seed );
|
||||
sizes[i].depth = 1;
|
||||
}
|
||||
}
|
||||
|
||||
int test_images_read_2D( cl_device_id device, cl_context context,
|
||||
cl_command_queue queue, int numElements )
|
||||
{
|
||||
GLenum targets[] = { GL_TEXTURE_2D, GL_TEXTURE_RECTANGLE_EXT };
|
||||
size_t ntargets = sizeof(targets) / sizeof(targets[0]);
|
||||
|
||||
size_t nformats = sizeof(common_formats) / sizeof(common_formats[0]);
|
||||
|
||||
const size_t nsizes = 8;
|
||||
sizevec_t sizes[nsizes];
|
||||
calc_2D_test_size_descriptors(sizes, nsizes);
|
||||
|
||||
return test_images_read_common(device, context, queue, common_formats,
|
||||
nformats, targets, ntargets, sizes, nsizes);
|
||||
}
|
||||
|
||||
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 };
|
||||
|
||||
size_t ntargets = sizeof(targets) / sizeof(targets[0]);
|
||||
size_t nformats = sizeof(common_formats) / sizeof(common_formats[0]);
|
||||
|
||||
const size_t nsizes = 8;
|
||||
sizevec_t sizes[nsizes];
|
||||
calc_cube_test_size_descriptors(sizes, nsizes);
|
||||
|
||||
return test_images_read_common(device, context, queue, common_formats,
|
||||
nformats, targets, ntargets, sizes, nsizes);
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark _2D write tests
|
||||
|
||||
#include "common.h"
|
||||
|
||||
int test_images_write( cl_device_id device, cl_context context,
|
||||
cl_command_queue queue, int numElements )
|
||||
{
|
||||
GLenum targets[] = { GL_TEXTURE_2D, GL_TEXTURE_RECTANGLE_EXT };
|
||||
size_t ntargets = sizeof(targets) / sizeof(targets[0]);
|
||||
size_t nformats = sizeof(common_formats) / sizeof(common_formats[0]);
|
||||
|
||||
const size_t nsizes = 8;
|
||||
sizevec_t sizes[nsizes];
|
||||
calc_2D_test_size_descriptors(sizes, nsizes);
|
||||
|
||||
return test_images_write_common( device, context, queue, common_formats,
|
||||
nformats, targets, ntargets, sizes, nsizes );
|
||||
}
|
||||
|
||||
int test_images_write_cube( cl_device_id device, cl_context context,
|
||||
cl_command_queue queue, int numElements )
|
||||
{
|
||||
size_t nformats = sizeof(common_formats) / sizeof(common_formats[0]);
|
||||
|
||||
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
|
||||
};
|
||||
size_t ntargets = sizeof(targets) / sizeof(targets[0]);
|
||||
|
||||
const size_t nsizes = 8;
|
||||
sizevec_t sizes[nsizes];
|
||||
calc_cube_test_size_descriptors(sizes, nsizes);
|
||||
|
||||
return test_images_write_common( device, context, queue, common_formats,
|
||||
nformats, targets, ntargets, sizes, nsizes );
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark _2D get info tests
|
||||
|
||||
int test_images_2D_getinfo( cl_device_id device, cl_context context,
|
||||
cl_command_queue queue, int numElements )
|
||||
{
|
||||
GLenum targets[] = { GL_TEXTURE_2D, GL_TEXTURE_RECTANGLE_EXT };
|
||||
size_t ntargets = sizeof(targets) / sizeof(targets[0]);
|
||||
|
||||
size_t nformats = sizeof(common_formats) / sizeof(common_formats[0]);
|
||||
|
||||
const size_t nsizes = 8;
|
||||
sizevec_t sizes[nsizes];
|
||||
calc_2D_test_size_descriptors(sizes, nsizes);
|
||||
|
||||
return test_images_get_info_common(device, context, queue, common_formats,
|
||||
nformats, targets, ntargets, sizes, nsizes);
|
||||
}
|
||||
|
||||
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
|
||||
};
|
||||
size_t ntargets = sizeof(targets) / sizeof(targets[0]);
|
||||
size_t nformats = sizeof(common_formats) / sizeof(common_formats[0]);
|
||||
|
||||
const size_t nsizes = 8;
|
||||
sizevec_t sizes[nsizes];
|
||||
calc_cube_test_size_descriptors(sizes, nsizes);
|
||||
|
||||
return test_images_get_info_common(device, context, queue, common_formats,
|
||||
nformats, targets, ntargets, sizes, nsizes);
|
||||
}
|
||||
93
test_conformance/gl/test_images_2Darray.cpp
Normal file
93
test_conformance/gl/test_images_2Darray.cpp
Normal file
@@ -0,0 +1,93 @@
|
||||
//
|
||||
// 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 "common.h"
|
||||
#include "testBase.h"
|
||||
|
||||
#if defined( __APPLE__ )
|
||||
#include <OpenGL/glu.h>
|
||||
#else
|
||||
#include <GL/glu.h>
|
||||
#include <CL/cl_gl.h>
|
||||
#endif
|
||||
#include <algorithm>
|
||||
|
||||
using namespace std;
|
||||
|
||||
void calc_2D_array_size_descriptors(sizevec_t* sizes, size_t nsizes)
|
||||
{
|
||||
// Need to limit array size according to GL device properties
|
||||
GLint maxTextureLayers = 16, maxTextureSize = 4096;
|
||||
glGetIntegerv(GL_MAX_ARRAY_TEXTURE_LAYERS, &maxTextureLayers);
|
||||
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxTextureSize);
|
||||
|
||||
RandomSeed seed( gRandomSeed );
|
||||
|
||||
// Generate some random sizes (within reasonable ranges)
|
||||
for (size_t i = 0; i < nsizes; i++) {
|
||||
sizes[i].width = random_in_range( 2, min(maxTextureSize, 1<<(i+4)), seed );
|
||||
sizes[i].height = random_in_range( 2, min(maxTextureSize, 1<<(i+4)), seed );
|
||||
sizes[i].depth = random_in_range( 2, min(maxTextureLayers, 1<<(i+4)), seed );
|
||||
}
|
||||
}
|
||||
|
||||
int test_images_read_2Darray( cl_device_id device, cl_context context,
|
||||
cl_command_queue queue, int )
|
||||
{
|
||||
size_t nformats = sizeof(common_formats) / sizeof(common_formats[0]);
|
||||
|
||||
GLenum targets[] = { GL_TEXTURE_2D_ARRAY };
|
||||
size_t ntargets = sizeof(targets) / sizeof(targets[0]);
|
||||
|
||||
const size_t nsizes = 6;
|
||||
sizevec_t sizes[nsizes];
|
||||
calc_2D_array_size_descriptors(sizes, nsizes);
|
||||
|
||||
return test_images_read_common(device, context, queue, common_formats,
|
||||
nformats, targets, ntargets, sizes, nsizes);
|
||||
}
|
||||
|
||||
int test_images_write_2Darray( cl_device_id device, cl_context context,
|
||||
cl_command_queue queue, int numElements )
|
||||
{
|
||||
// FIXME: Query for 2D image array write support.
|
||||
|
||||
GLenum targets[] = { GL_TEXTURE_2D_ARRAY };
|
||||
size_t ntargets = sizeof(targets) / sizeof(targets[0]);
|
||||
size_t nformats = sizeof(common_formats) / sizeof(common_formats[0]);
|
||||
|
||||
const size_t nsizes = 6;
|
||||
sizevec_t sizes[nsizes];
|
||||
calc_2D_array_size_descriptors(sizes, nsizes);
|
||||
|
||||
return test_images_write_common( device, context, queue, common_formats,
|
||||
nformats, targets, ntargets, sizes, nsizes );
|
||||
}
|
||||
|
||||
int test_images_2Darray_getinfo( cl_device_id device, cl_context context,
|
||||
cl_command_queue queue, int )
|
||||
{
|
||||
size_t nformats = sizeof(common_formats) / sizeof(common_formats[0]);
|
||||
|
||||
GLenum targets[] = { GL_TEXTURE_2D_ARRAY };
|
||||
size_t ntargets = sizeof(targets) / sizeof(targets[0]);
|
||||
|
||||
const size_t nsizes = 6;
|
||||
sizevec_t sizes[nsizes];
|
||||
calc_2D_array_size_descriptors(sizes, nsizes);
|
||||
|
||||
return test_images_get_info_common(device, context, queue, common_formats,
|
||||
nformats, targets, ntargets, sizes, nsizes);
|
||||
}
|
||||
109
test_conformance/gl/test_images_3D.cpp
Normal file
109
test_conformance/gl/test_images_3D.cpp
Normal file
@@ -0,0 +1,109 @@
|
||||
//
|
||||
// Copyright (c) 2017 The Khronos Group Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
#include "testBase.h"
|
||||
#include "common.h"
|
||||
|
||||
#if defined( __APPLE__ )
|
||||
#include <OpenGL/glu.h>
|
||||
#else
|
||||
#include <GL/glu.h>
|
||||
#include <CL/cl_gl.h>
|
||||
#endif
|
||||
#include <algorithm>
|
||||
|
||||
using namespace std;
|
||||
|
||||
extern "C" { extern cl_uint gRandomSeed; };
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark _3D read test
|
||||
|
||||
void calc_3D_size_descriptors(sizevec_t* sizes, size_t nsizes)
|
||||
{
|
||||
// Need to limit array size according to GL device properties
|
||||
GLint maxTextureSize = 2048;
|
||||
glGetIntegerv(GL_MAX_3D_TEXTURE_SIZE, &maxTextureSize);
|
||||
|
||||
RandomSeed seed( gRandomSeed );
|
||||
|
||||
// Generate some random sizes (within reasonable ranges)
|
||||
for (size_t i = 0; i < nsizes; i++) {
|
||||
sizes[i].width = random_in_range( 2, min(maxTextureSize, 1<<(i+4)), seed );
|
||||
sizes[i].height = random_in_range( 2, min(maxTextureSize, 1<<(i+4)), seed );
|
||||
sizes[i].depth = random_in_range( 2, min(maxTextureSize, 1<<(i+4)), seed );
|
||||
}
|
||||
}
|
||||
|
||||
int test_images_read_3D( cl_device_id device, cl_context context, cl_command_queue queue, int numElements )
|
||||
{
|
||||
GLenum targets[] = { GL_TEXTURE_3D };
|
||||
size_t ntargets = 1;
|
||||
|
||||
size_t nformats = sizeof(common_formats) / sizeof(common_formats[0]);
|
||||
|
||||
const size_t nsizes = 6;
|
||||
sizevec_t sizes[nsizes];
|
||||
calc_3D_size_descriptors(sizes, nsizes);
|
||||
|
||||
return test_images_read_common(device, context, queue, common_formats,
|
||||
nformats, targets, ntargets, sizes, nsizes);
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
#pragma marm _3D write test
|
||||
|
||||
int test_images_write_3D( cl_device_id device, cl_context context,
|
||||
cl_command_queue queue, int numElements )
|
||||
{
|
||||
// TODO: Perhaps the expected behavior is to FAIL if 3D images are
|
||||
// unsupported?
|
||||
|
||||
if (!is_extension_available(device, "cl_khr_3d_image_writes")) {
|
||||
log_info("This device does not support 3D image writes. Skipping test.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
GLenum targets[] = { GL_TEXTURE_3D };
|
||||
size_t ntargets = sizeof(targets) / sizeof(targets[0]);
|
||||
size_t nformats = sizeof(common_formats) / sizeof(common_formats[0]);
|
||||
|
||||
|
||||
const size_t nsizes = 6;
|
||||
sizevec_t sizes[nsizes];
|
||||
calc_3D_size_descriptors(sizes, nsizes);
|
||||
|
||||
return test_images_write_common( device, context, queue, common_formats,
|
||||
nformats, targets, ntargets, sizes, nsizes );
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark _3D get info test
|
||||
|
||||
int test_images_3D_getinfo( cl_device_id device, cl_context context,
|
||||
cl_command_queue queue, int numElements )
|
||||
{
|
||||
GLenum targets[] = { GL_TEXTURE_3D };
|
||||
size_t ntargets = 1;
|
||||
|
||||
size_t nformats = sizeof(common_formats) / sizeof(common_formats[0]);
|
||||
|
||||
const size_t nsizes = 6;
|
||||
sizevec_t sizes[nsizes];
|
||||
calc_3D_size_descriptors(sizes, nsizes);
|
||||
|
||||
return test_images_get_info_common(device, context, queue, common_formats,
|
||||
nformats, targets, ntargets, sizes, nsizes);
|
||||
}
|
||||
162
test_conformance/gl/test_images_depth.cpp
Normal file
162
test_conformance/gl/test_images_depth.cpp
Normal file
@@ -0,0 +1,162 @@
|
||||
//
|
||||
// Copyright (c) 2017 The Khronos Group Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
#include "testBase.h"
|
||||
#include "common.h"
|
||||
|
||||
#if defined( __APPLE__ )
|
||||
#include <OpenGL/glu.h>
|
||||
#else
|
||||
#include <GL/glu.h>
|
||||
#include <CL/cl_gl.h>
|
||||
#endif
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
using namespace std;
|
||||
|
||||
extern "C" { extern cl_uint gRandomSeed; }
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark _2D depth read tests
|
||||
|
||||
void calc_depth_size_descriptors(sizevec_t* sizes, size_t nsizes)
|
||||
{
|
||||
// Need to limit texture size according to GL device properties
|
||||
GLint maxTextureSize = 4096, maxTextureRectangleSize = 4096, size;
|
||||
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxTextureSize);
|
||||
glGetIntegerv(GL_MAX_RECTANGLE_TEXTURE_SIZE_EXT, &maxTextureRectangleSize);
|
||||
|
||||
size = min(maxTextureSize, maxTextureRectangleSize);
|
||||
|
||||
RandomSeed seed( gRandomSeed );
|
||||
|
||||
// Generate some random sizes (within reasonable ranges)
|
||||
for (size_t i = 0; i < nsizes; i++) {
|
||||
sizes[i].width = random_in_range( 2, min(size, 1<<(i+4)), seed );
|
||||
sizes[i].height = random_in_range( 2, min(size, 1<<(i+4)), seed );
|
||||
sizes[i].depth = 1;
|
||||
}
|
||||
}
|
||||
|
||||
void calc_depth_array_size_descriptors(sizevec_t* sizes, size_t nsizes)
|
||||
{
|
||||
// Need to limit texture size according to GL device properties
|
||||
GLint maxTextureSize = 4096, maxTextureRectangleSize = 4096, maxTextureLayers = 16, size;
|
||||
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxTextureSize);
|
||||
glGetIntegerv(GL_MAX_RECTANGLE_TEXTURE_SIZE_EXT, &maxTextureRectangleSize);
|
||||
glGetIntegerv(GL_MAX_ARRAY_TEXTURE_LAYERS, &maxTextureLayers);
|
||||
|
||||
size = min(maxTextureSize, maxTextureRectangleSize);
|
||||
|
||||
RandomSeed seed( gRandomSeed );
|
||||
|
||||
// Generate some random sizes (within reasonable ranges)
|
||||
for (size_t i = 0; i < nsizes; i++) {
|
||||
sizes[i].width = random_in_range( 2, min(size, 1<<(i+4)), seed );
|
||||
sizes[i].height = random_in_range( 2, min(size, 1<<(i+4)), seed );
|
||||
sizes[i].depth = random_in_range( 2, min(maxTextureLayers, 1<<(i+4)), seed );
|
||||
}
|
||||
}
|
||||
|
||||
int test_images_read_2D_depth( cl_device_id device, cl_context context,
|
||||
cl_command_queue queue, int numElements )
|
||||
{
|
||||
if (!is_extension_available(device, "cl_khr_gl_depth_images")) {
|
||||
log_info("Test not run because 'cl_khr_gl_depth_images' extension is not supported by the tested device\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
RandomSeed seed( gRandomSeed );
|
||||
|
||||
GLenum targets[] = { GL_TEXTURE_2D, GL_TEXTURE_RECTANGLE_EXT };
|
||||
size_t ntargets = sizeof(targets) / sizeof(targets[0]);
|
||||
|
||||
size_t nformats = sizeof(depth_formats) / sizeof(depth_formats[0]);
|
||||
|
||||
const size_t nsizes = 8;
|
||||
sizevec_t sizes[nsizes];
|
||||
calc_depth_size_descriptors(sizes, nsizes);
|
||||
|
||||
return test_images_read_common(device, context, queue, depth_formats,
|
||||
nformats, targets, ntargets, sizes, nsizes);
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark _2D depth write tests
|
||||
|
||||
|
||||
int test_images_write_2D_depth( cl_device_id device, cl_context context,
|
||||
cl_command_queue queue, int numElements )
|
||||
{
|
||||
if (!is_extension_available(device, "cl_khr_gl_depth_images")) {
|
||||
log_info("Test not run because 'cl_khr_gl_depth_images' extension is not supported by the tested device\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
GLenum targets[] = { GL_TEXTURE_2D, GL_TEXTURE_RECTANGLE_EXT };
|
||||
size_t ntargets = sizeof(targets) / sizeof(targets[0]);
|
||||
size_t nformats = sizeof(depth_formats) / sizeof(depth_formats[0]);
|
||||
|
||||
const size_t nsizes = 8;
|
||||
sizevec_t sizes[nsizes];
|
||||
calc_depth_size_descriptors(sizes, nsizes);
|
||||
|
||||
return test_images_write_common( device, context, queue, depth_formats,
|
||||
nformats, targets, ntargets, sizes, nsizes );
|
||||
}
|
||||
|
||||
int test_images_read_2Darray_depth( cl_device_id device, cl_context context,
|
||||
cl_command_queue queue, int )
|
||||
{
|
||||
if (!is_extension_available(device, "cl_khr_gl_depth_images")) {
|
||||
log_info("Test not run because 'cl_khr_gl_depth_images' extension is not supported by the tested device\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t nformats = sizeof(depth_formats) / sizeof(depth_formats[0]);
|
||||
GLenum targets[] = { GL_TEXTURE_2D_ARRAY };
|
||||
size_t ntargets = sizeof(targets) / sizeof(targets[0]);
|
||||
|
||||
const size_t nsizes = 6;
|
||||
sizevec_t sizes[nsizes];
|
||||
calc_depth_array_size_descriptors(sizes, nsizes);
|
||||
|
||||
return test_images_read_common(device, context, queue, depth_formats,
|
||||
nformats, targets, ntargets, sizes, nsizes);
|
||||
}
|
||||
|
||||
int test_images_write_2Darray_depth( cl_device_id device, cl_context context,
|
||||
cl_command_queue queue, int numElements )
|
||||
{
|
||||
if (!is_extension_available(device, "cl_khr_gl_depth_images")) {
|
||||
log_info("Test not run because 'cl_khr_gl_depth_images' extension is not supported by the tested device\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
// FIXME: Query for 2D image array write support.
|
||||
|
||||
GLenum targets[] = { GL_TEXTURE_2D_ARRAY };
|
||||
size_t ntargets = sizeof(targets) / sizeof(targets[0]);
|
||||
size_t nformats = sizeof(depth_formats) / sizeof(depth_formats[0]);
|
||||
|
||||
const size_t nsizes = 6;
|
||||
sizevec_t sizes[nsizes];
|
||||
calc_depth_array_size_descriptors(sizes, nsizes);
|
||||
|
||||
return test_images_write_common( device, context, queue, depth_formats,
|
||||
nformats, targets, ntargets, sizes, nsizes );
|
||||
}
|
||||
|
||||
262
test_conformance/gl/test_images_getinfo_common.cpp
Normal file
262
test_conformance/gl/test_images_getinfo_common.cpp
Normal file
@@ -0,0 +1,262 @@
|
||||
//
|
||||
// Copyright (c) 2017 The Khronos Group Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
#include "testBase.h"
|
||||
#include "common.h"
|
||||
|
||||
#if defined( __APPLE__ )
|
||||
#include <OpenGL/glu.h>
|
||||
#else
|
||||
#include <GL/glu.h>
|
||||
#include <CL/cl_gl.h>
|
||||
#endif
|
||||
|
||||
extern "C" { extern cl_uint gRandomSeed; };
|
||||
|
||||
extern int supportsHalf(cl_context context, bool* supports_half);
|
||||
|
||||
static int test_image_info( cl_context context, cl_command_queue queue,
|
||||
GLenum glTarget, GLuint glTexture, size_t imageWidth, size_t imageHeight,
|
||||
size_t imageDepth, cl_image_format *outFormat, ExplicitType *outType,
|
||||
void **outResultBuffer )
|
||||
{
|
||||
clMemWrapper streams[ 2 ];
|
||||
|
||||
int error;
|
||||
|
||||
// Create a CL image from the supplied GL texture
|
||||
streams[ 0 ] = (*clCreateFromGLTexture_ptr)( context, CL_MEM_READ_ONLY,
|
||||
glTarget, 0, glTexture, &error );
|
||||
if( error != CL_SUCCESS )
|
||||
{
|
||||
print_error( error, "Unable to create CL image from GL texture" );
|
||||
GLint fmt;
|
||||
glGetTexLevelParameteriv( glTarget, 0, GL_TEXTURE_INTERNAL_FORMAT, &fmt );
|
||||
log_error( " Supplied GL texture was format %s\n", GetGLFormatName( fmt ) );
|
||||
return error;
|
||||
}
|
||||
|
||||
// Determine data type and format that CL came up with
|
||||
error = clGetImageInfo( streams[ 0 ], CL_IMAGE_FORMAT,
|
||||
sizeof( cl_image_format ), outFormat, NULL );
|
||||
test_error( error, "Unable to get CL image format" );
|
||||
|
||||
cl_gl_object_type object_type;
|
||||
switch (glTarget) {
|
||||
case GL_TEXTURE_1D:
|
||||
object_type = CL_GL_OBJECT_TEXTURE1D;
|
||||
break;
|
||||
case GL_TEXTURE_BUFFER:
|
||||
object_type = CL_GL_OBJECT_TEXTURE_BUFFER;
|
||||
break;
|
||||
case GL_TEXTURE_1D_ARRAY:
|
||||
object_type = CL_GL_OBJECT_TEXTURE1D_ARRAY;
|
||||
break;
|
||||
case GL_TEXTURE_2D:
|
||||
case GL_TEXTURE_RECTANGLE_EXT:
|
||||
case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
|
||||
case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
|
||||
case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
|
||||
case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
|
||||
case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
|
||||
case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
|
||||
object_type = CL_GL_OBJECT_TEXTURE2D;
|
||||
break;
|
||||
case GL_TEXTURE_2D_ARRAY:
|
||||
object_type = CL_GL_OBJECT_TEXTURE2D_ARRAY;
|
||||
break;
|
||||
case GL_TEXTURE_3D:
|
||||
object_type = CL_GL_OBJECT_TEXTURE3D;
|
||||
break;
|
||||
default:
|
||||
log_error("Unsupported texture target.");
|
||||
return 1;
|
||||
}
|
||||
|
||||
return CheckGLObjectInfo(streams[0], object_type, glTexture, glTarget, 0);
|
||||
}
|
||||
|
||||
static int test_image_format_get_info(
|
||||
cl_context context, cl_command_queue queue,
|
||||
size_t width, size_t height, size_t depth,
|
||||
GLenum target, struct format* fmt, MTdata data)
|
||||
{
|
||||
int error = 0;
|
||||
|
||||
// If we're testing a half float format, then we need to determine the
|
||||
// rounding mode of this machine. Punt if we fail to do so.
|
||||
|
||||
if( fmt->type == kHalf )
|
||||
{
|
||||
if( DetectFloatToHalfRoundingMode(queue) )
|
||||
return 0;
|
||||
bool supports_half = false;
|
||||
error = supportsHalf(context, &supports_half);
|
||||
if( error != 0 )
|
||||
return error;
|
||||
if (!supports_half) return 0;
|
||||
}
|
||||
|
||||
size_t w = width, h = height, d = depth;
|
||||
|
||||
// Unpack the format and use it, along with the target, to create an
|
||||
// appropriate GL texture.
|
||||
|
||||
GLenum gl_fmt = fmt->formattype;
|
||||
GLenum gl_internal_fmt = fmt->internal;
|
||||
GLenum gl_type = fmt->datatype;
|
||||
ExplicitType type = fmt->type;
|
||||
|
||||
glTextureWrapper texture;
|
||||
glBufferWrapper glbuf;
|
||||
|
||||
// If we're testing a half float format, then we need to determine the
|
||||
// rounding mode of this machine. Punt if we fail to do so.
|
||||
|
||||
if( fmt->type == kHalf )
|
||||
if( DetectFloatToHalfRoundingMode(queue) )
|
||||
return 1;
|
||||
|
||||
// Use the correct texture creation function depending on the target, and
|
||||
// adjust width, height, depth as appropriate so subsequent size calculations
|
||||
// succeed.
|
||||
|
||||
switch (target) {
|
||||
case GL_TEXTURE_1D:
|
||||
h = 1; d = 1;
|
||||
CreateGLTexture1D( width, target, gl_fmt,
|
||||
gl_internal_fmt, gl_type, type, &texture, &error, false, data );
|
||||
break;
|
||||
case GL_TEXTURE_BUFFER:
|
||||
h = 1; d = 1;
|
||||
CreateGLTextureBuffer( width, target, gl_fmt,
|
||||
gl_internal_fmt, gl_type, type, &texture, &glbuf, &error, false, data );
|
||||
break;
|
||||
case GL_TEXTURE_1D_ARRAY:
|
||||
d = 1;
|
||||
CreateGLTexture1DArray( width, height, target, gl_fmt,
|
||||
gl_internal_fmt, gl_type, type, &texture, &error, false, data );
|
||||
break;
|
||||
case GL_TEXTURE_RECTANGLE_EXT:
|
||||
case GL_TEXTURE_2D:
|
||||
case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
|
||||
case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
|
||||
case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
|
||||
case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
|
||||
case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
|
||||
case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
|
||||
d = 1;
|
||||
CreateGLTexture2D( width, height, target, gl_fmt,
|
||||
gl_internal_fmt, gl_type, type, &texture, &error, false, data );
|
||||
break;
|
||||
case GL_TEXTURE_2D_ARRAY:
|
||||
CreateGLTexture2DArray( width, height, depth, target, gl_fmt,
|
||||
gl_internal_fmt, gl_type, type, &texture, &error, false, data );
|
||||
break;
|
||||
case GL_TEXTURE_3D:
|
||||
d = 1;
|
||||
CreateGLTexture3D( width, height, depth, target, gl_fmt,
|
||||
gl_internal_fmt, gl_type, type, &texture, &error, data, false );
|
||||
break;
|
||||
default:
|
||||
log_error("Unsupported texture target.\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if ( error == -2 ) {
|
||||
log_info("OpenGL texture couldn't be created, because a texture is too big. Skipping test.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ( error != 0 ) {
|
||||
if ((gl_fmt == GL_RGBA_INTEGER_EXT) && (!CheckGLIntegerExtensionSupport())) {
|
||||
log_info("OpenGL version does not support GL_RGBA_INTEGER_EXT. "
|
||||
"Skipping test.\n");
|
||||
return 0;
|
||||
} else {
|
||||
return error;
|
||||
}
|
||||
}
|
||||
|
||||
cl_image_format clFormat;
|
||||
ExplicitType actualType;
|
||||
char *outBuffer;
|
||||
|
||||
// Perform the info check:
|
||||
return test_image_info( context, queue, target, texture, w, h, d, &clFormat,
|
||||
&actualType, (void **)&outBuffer );
|
||||
}
|
||||
|
||||
int test_images_get_info_common( cl_device_id device, cl_context context,
|
||||
cl_command_queue queue, struct format* formats, size_t nformats,
|
||||
GLenum *targets, size_t ntargets, sizevec_t *sizes, size_t nsizes )
|
||||
{
|
||||
int error = 0;
|
||||
RandomSeed seed(gRandomSeed);
|
||||
|
||||
// First, ensure this device supports images.
|
||||
|
||||
if (checkForImageSupport(device)) {
|
||||
log_info("Device does not support images. Skipping test.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t fidx, tidx, sidx;
|
||||
|
||||
// Test each format on every target, every size.
|
||||
|
||||
for ( fidx = 0; fidx < nformats; fidx++ ) {
|
||||
for ( tidx = 0; tidx < ntargets; tidx++ ) {
|
||||
|
||||
if ( formats[ fidx ].datatype == GL_UNSIGNED_INT_2_10_10_10_REV )
|
||||
{
|
||||
// Check if the RGB 101010 format is supported
|
||||
if ( is_rgb_101010_supported( context, targets[ tidx ] ) == 0 )
|
||||
break; // skip
|
||||
}
|
||||
|
||||
log_info( "Testing image info for GL format %s : %s : %s : %s\n",
|
||||
GetGLTargetName( targets[ tidx ] ),
|
||||
GetGLFormatName( formats[ fidx ].internal ),
|
||||
GetGLBaseFormatName( formats[ fidx ].formattype ),
|
||||
GetGLTypeName( formats[ fidx ].datatype ) );
|
||||
|
||||
for ( sidx = 0; sidx < nsizes; sidx++ ) {
|
||||
|
||||
// Test this format + size:
|
||||
|
||||
if ( test_image_format_get_info(context, queue,
|
||||
sizes[sidx].width, sizes[sidx].height, sizes[sidx].depth,
|
||||
targets[tidx], &formats[fidx], seed) )
|
||||
{
|
||||
// We land here in the event of test failure.
|
||||
|
||||
log_error( "ERROR: Image info test failed for %s : %s : %s : %s\n\n",
|
||||
GetGLTargetName( targets[ tidx ] ),
|
||||
GetGLFormatName( formats[ fidx ].internal ),
|
||||
GetGLBaseFormatName( formats[ fidx ].formattype ),
|
||||
GetGLTypeName( formats[ fidx ].datatype ) );
|
||||
error++;
|
||||
|
||||
// Skip the other sizes for this format.
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
118
test_conformance/gl/test_images_multisample.cpp
Normal file
118
test_conformance/gl/test_images_multisample.cpp
Normal file
@@ -0,0 +1,118 @@
|
||||
//
|
||||
// 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 "common.h"
|
||||
#include "testBase.h"
|
||||
|
||||
#if defined( __APPLE__ )
|
||||
#include <OpenGL/glu.h>
|
||||
#else
|
||||
#include <GL/glu.h>
|
||||
#include <CL/cl_gl.h>
|
||||
#endif
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
using namespace std;
|
||||
|
||||
void calc_2D_multisample_size_descriptors(sizevec_t* sizes, size_t nsizes)
|
||||
{
|
||||
// Need to limit texture size according to GL device properties
|
||||
GLint maxTextureSize = 4096;
|
||||
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxTextureSize);
|
||||
|
||||
RandomSeed seed( gRandomSeed );
|
||||
|
||||
// Generate some random sizes (within reasonable ranges)
|
||||
for (size_t i = 0; i < nsizes; i++) {
|
||||
sizes[i].width = random_in_range( 2, min(maxTextureSize, 1<<(i+4)), seed );
|
||||
sizes[i].height = random_in_range( 2, min(maxTextureSize, 1<<(i+4)), seed );
|
||||
sizes[i].depth = 1;
|
||||
}
|
||||
}
|
||||
|
||||
void calc_2D_array_multisample_size_descriptors(sizevec_t* sizes, size_t nsizes)
|
||||
{
|
||||
// Need to limit array size according to GL device properties
|
||||
GLint maxTextureLayers = 16, maxTextureSize = 4096;
|
||||
glGetIntegerv(GL_MAX_ARRAY_TEXTURE_LAYERS, &maxTextureLayers);
|
||||
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxTextureSize);
|
||||
|
||||
RandomSeed seed( gRandomSeed );
|
||||
|
||||
// Generate some random sizes (within reasonable ranges)
|
||||
for (size_t i = 0; i < nsizes; i++) {
|
||||
sizes[i].width = random_in_range( 2, min(maxTextureSize, 1<<(i+4)), seed );
|
||||
sizes[i].height = random_in_range( 2, min(maxTextureSize, 1<<(i+4)), seed );
|
||||
sizes[i].depth = random_in_range( 2, min(maxTextureLayers, 1<<(i+4)), seed );
|
||||
}
|
||||
}
|
||||
|
||||
int test_images_read_2D_multisample( cl_device_id device, cl_context context,
|
||||
cl_command_queue queue, int numElements )
|
||||
{
|
||||
if (!is_extension_available(device, "cl_khr_gl_msaa_sharing")) {
|
||||
log_info("Test not run because 'cl_khr_gl_msaa_sharing' extension is not supported by the tested device\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
glEnable(GL_MULTISAMPLE);
|
||||
|
||||
const size_t nsizes = 8;
|
||||
sizevec_t sizes[nsizes];
|
||||
calc_2D_multisample_size_descriptors(sizes, nsizes);
|
||||
|
||||
size_t nformats;
|
||||
|
||||
GLenum targets[] = { GL_TEXTURE_2D_MULTISAMPLE };
|
||||
size_t ntargets = sizeof(targets) / sizeof(targets[0]);
|
||||
|
||||
nformats = sizeof(common_formats) / sizeof(common_formats[0]);
|
||||
int ret_common = test_images_read_common(device, context, queue, common_formats, nformats, targets, ntargets, sizes, nsizes);
|
||||
|
||||
nformats = sizeof(depth_formats) / sizeof(depth_formats[0]);
|
||||
int ret_depth = test_images_read_common(device, context, queue, depth_formats, nformats, targets, ntargets, sizes, nsizes);
|
||||
|
||||
return (ret_common) ? ret_common : ret_depth;
|
||||
}
|
||||
|
||||
int test_images_read_2Darray_multisample( cl_device_id device, cl_context context,
|
||||
cl_command_queue queue, int )
|
||||
{
|
||||
if (!is_extension_available(device, "cl_khr_gl_msaa_sharing")) {
|
||||
log_info("Test not run because 'cl_khr_gl_msaa_sharing' extension is not supported by the tested device\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
glEnable(GL_MULTISAMPLE);
|
||||
|
||||
const size_t nsizes = 4;
|
||||
sizevec_t sizes[nsizes];
|
||||
calc_2D_array_multisample_size_descriptors(sizes, nsizes);
|
||||
|
||||
size_t nformats;
|
||||
|
||||
GLenum targets[] = { GL_TEXTURE_2D_MULTISAMPLE_ARRAY };
|
||||
size_t ntargets = sizeof(targets) / sizeof(targets[0]);
|
||||
|
||||
nformats = sizeof(common_formats) / sizeof(common_formats[0]);
|
||||
int ret_common = test_images_read_common(device, context, queue, common_formats, nformats, targets, ntargets, sizes, nsizes);
|
||||
|
||||
nformats = sizeof(depth_formats) / sizeof(depth_formats[0]);
|
||||
int ret_depth = test_images_read_common(device, context, queue, depth_formats, nformats, targets, ntargets, sizes, nsizes);
|
||||
|
||||
return (ret_common) ? ret_common : ret_depth;
|
||||
}
|
||||
|
||||
736
test_conformance/gl/test_images_read_common.cpp
Normal file
736
test_conformance/gl/test_images_read_common.cpp
Normal file
@@ -0,0 +1,736 @@
|
||||
//
|
||||
// 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 "common.h"
|
||||
#include "testBase.h"
|
||||
|
||||
#if defined( __APPLE__ )
|
||||
#include <OpenGL/glu.h>
|
||||
#else
|
||||
#include <GL/glu.h>
|
||||
#include <CL/cl_gl.h>
|
||||
#endif
|
||||
|
||||
extern "C" { extern cl_uint gRandomSeed; };
|
||||
|
||||
extern int supportsHalf(cl_context context, bool* supports_half);
|
||||
extern int supportsMsaa(cl_context context, bool* supports_msaa);
|
||||
extern int supportsDepth(cl_context context, bool* supports_depth);
|
||||
|
||||
static const char *kernelpattern_image_read_1d =
|
||||
"__kernel void sample_test( read_only image1d_t source, sampler_t sampler, __global %s4 *results )\n"
|
||||
"{\n"
|
||||
" int offset = get_global_id(0);\n"
|
||||
" results[ offset ] = read_image%s( source, sampler, offset );\n"
|
||||
"}\n";
|
||||
|
||||
static const char *kernelpattern_image_read_1d_buffer =
|
||||
"__kernel void sample_test( read_only image1d_buffer_t source, sampler_t sampler, __global %s4 *results )\n"
|
||||
"{\n"
|
||||
" int offset = get_global_id(0);\n"
|
||||
" results[ offset ] = read_image%s( source, offset );\n"
|
||||
"}\n";
|
||||
|
||||
static const char *kernelpattern_image_read_1darray =
|
||||
"__kernel void sample_test( read_only image1d_array_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 *kernelpattern_image_read_2d =
|
||||
"__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 *kernelpattern_image_read_2darray =
|
||||
"__kernel void sample_test( read_only image2d_array_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 const char *kernelpattern_image_read_3d =
|
||||
"__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 const char *kernelpattern_image_read_2d_depth =
|
||||
"__kernel void sample_test( read_only image2d_depth_t source, sampler_t sampler, __global %s *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 *kernelpattern_image_read_2darray_depth =
|
||||
"__kernel void sample_test( read_only image2d_array_depth_t source, sampler_t sampler, __global %s *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 const char *kernelpattern_image_multisample_read_2d =
|
||||
"__kernel void sample_test( read_only image2d_msaa_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 width = get_image_width( source );\n"
|
||||
" int height = get_image_height( source );\n"
|
||||
" int num_samples = get_image_num_samples( source );\n"
|
||||
" for(size_t sample = 0; sample < num_samples; sample++ ) {\n"
|
||||
" int offset = sample * width * height + tidY * width + tidX;\n"
|
||||
" results[ offset ] = read_image%s( source, (int2)( tidX, tidY ), sample );\n"
|
||||
" }\n"
|
||||
"}\n";
|
||||
|
||||
static const char *kernelpattern_image_multisample_read_2d_depth =
|
||||
"__kernel void sample_test( read_only image2d_msaa_depth_t source, sampler_t sampler, __global %s *results )\n"
|
||||
"{\n"
|
||||
" int tidX = get_global_id(0);\n"
|
||||
" int tidY = get_global_id(1);\n"
|
||||
" int width = get_image_width( source );\n"
|
||||
" int height = get_image_height( source );\n"
|
||||
" int num_samples = get_image_num_samples( source );\n"
|
||||
" for(size_t sample = 0; sample < num_samples; sample++ ) {\n"
|
||||
" int offset = sample * width * height + tidY * width + tidX;\n"
|
||||
" results[ offset ] = read_image%s( source, (int2)( tidX, tidY ), sample );\n"
|
||||
" }\n"
|
||||
"}\n";
|
||||
|
||||
static const char *kernelpattern_image_multisample_read_2darray =
|
||||
"__kernel void sample_test( read_only image2d_array_msaa_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 num_samples = get_image_num_samples( source );\n"
|
||||
" int width = get_image_width( source );\n"
|
||||
" int height = get_image_height( source );\n"
|
||||
" int array_size = get_image_array_size( source );\n"
|
||||
" for(size_t sample = 0; sample< num_samples; ++sample) {\n"
|
||||
" int offset = (array_size * width * height) * sample + (width * height) * tidZ + tidY * width + tidX;\n"
|
||||
" results[ offset ] = read_image%s( source, (int4)( tidX, tidY, tidZ, 1 ), sample );\n"
|
||||
" }\n"
|
||||
"}\n";
|
||||
|
||||
static const char *kernelpattern_image_multisample_read_2darray_depth =
|
||||
"__kernel void sample_test( read_only image2d_array_msaa_depth_t source, sampler_t sampler, __global %s *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 num_samples = get_image_num_samples( source );\n"
|
||||
" int width = get_image_width( source );\n"
|
||||
" int height = get_image_height( source );\n"
|
||||
" int array_size = get_image_array_size( source );\n"
|
||||
" for(size_t sample = 0; sample < num_samples; ++sample) {\n"
|
||||
" int offset = (array_size * width * height) * sample + (width * height) * tidZ + tidY * width + tidX;\n"
|
||||
" results[ offset ] = read_image%s( source, (int4)( tidX, tidY, tidZ, 1 ), sample );\n"
|
||||
" }\n"
|
||||
"}\n";
|
||||
|
||||
static const char* get_appropriate_kernel_for_target(GLenum target, cl_channel_order channel_order) {
|
||||
|
||||
switch (get_base_gl_target(target)) {
|
||||
case GL_TEXTURE_1D:
|
||||
return kernelpattern_image_read_1d;
|
||||
case GL_TEXTURE_BUFFER:
|
||||
return kernelpattern_image_read_1d_buffer;
|
||||
case GL_TEXTURE_1D_ARRAY:
|
||||
return kernelpattern_image_read_1darray;
|
||||
case GL_TEXTURE_RECTANGLE_EXT:
|
||||
case GL_TEXTURE_2D:
|
||||
case GL_COLOR_ATTACHMENT0:
|
||||
case GL_RENDERBUFFER:
|
||||
case GL_TEXTURE_CUBE_MAP:
|
||||
#ifdef GL_VERSION_3_2
|
||||
if(channel_order == CL_DEPTH || channel_order == CL_DEPTH_STENCIL)
|
||||
return kernelpattern_image_read_2d_depth;
|
||||
#endif
|
||||
return kernelpattern_image_read_2d;
|
||||
case GL_TEXTURE_2D_ARRAY:
|
||||
#ifdef GL_VERSION_3_2
|
||||
if(channel_order == CL_DEPTH || channel_order == CL_DEPTH_STENCIL)
|
||||
return kernelpattern_image_read_2darray_depth;
|
||||
#endif
|
||||
return kernelpattern_image_read_2darray;
|
||||
case GL_TEXTURE_3D:
|
||||
return kernelpattern_image_read_3d;
|
||||
case GL_TEXTURE_2D_MULTISAMPLE:
|
||||
#ifdef GL_VERSION_3_2
|
||||
if(channel_order == CL_DEPTH || channel_order == CL_DEPTH_STENCIL)
|
||||
return kernelpattern_image_multisample_read_2d_depth;
|
||||
#endif
|
||||
return kernelpattern_image_multisample_read_2d;
|
||||
break;
|
||||
case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
|
||||
#ifdef GL_VERSION_3_2
|
||||
if(channel_order == CL_DEPTH || channel_order == CL_DEPTH_STENCIL)
|
||||
return kernelpattern_image_multisample_read_2darray_depth;
|
||||
#endif
|
||||
return kernelpattern_image_multisample_read_2darray;
|
||||
break;
|
||||
default:
|
||||
log_error("Unsupported texture target (%s); cannot determine "
|
||||
"appropriate kernel.", GetGLTargetName(target));
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
int test_cl_image_read( cl_context context, cl_command_queue queue,
|
||||
GLenum gl_target, cl_mem image, size_t width, size_t height, size_t depth, size_t sampleNum,
|
||||
cl_image_format *outFormat, ExplicitType *outType, void **outResultBuffer )
|
||||
{
|
||||
clProgramWrapper program;
|
||||
clKernelWrapper kernel;
|
||||
clMemWrapper streams[ 2 ];
|
||||
|
||||
int error;
|
||||
char kernelSource[2048];
|
||||
char *programPtr;
|
||||
|
||||
// Use the image created from the GL texture.
|
||||
streams[ 0 ] = image;
|
||||
|
||||
// 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" );
|
||||
|
||||
// Determine the number of samples
|
||||
cl_uint samples = 0;
|
||||
error = clGetImageInfo( streams[ 0 ], CL_IMAGE_NUM_SAMPLES, sizeof( samples ), &samples, NULL );
|
||||
test_error( error, "Unable to get CL_IMAGE_NUM_SAMPLES" );
|
||||
|
||||
// Create the source
|
||||
*outType = get_read_kernel_type( outFormat );
|
||||
size_t channelSize = get_explicit_type_size( *outType );
|
||||
|
||||
const char* source = get_appropriate_kernel_for_target(gl_target, outFormat->image_channel_order);
|
||||
|
||||
sprintf( kernelSource, source, get_explicit_type_name( *outType ),
|
||||
get_kernel_suffix( outFormat ) );
|
||||
|
||||
programPtr = kernelSource;
|
||||
if( create_single_kernel_helper( context, &program, &kernel, 1,
|
||||
(const char **)&programPtr, "sample_test" ) )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Create a vanilla output buffer
|
||||
cl_device_id device;
|
||||
error = clGetCommandQueueInfo(queue, CL_QUEUE_DEVICE, sizeof(device), &device, NULL);
|
||||
test_error( error, "Unable to get queue device" );
|
||||
|
||||
cl_ulong maxAllocSize = 0;
|
||||
error = clGetDeviceInfo( device, CL_DEVICE_MAX_MEM_ALLOC_SIZE, sizeof( maxAllocSize ), &maxAllocSize, NULL );
|
||||
test_error( error, "Unable to get CL_DEVICE_MAX_MEM_ALLOC_SIZE" );
|
||||
|
||||
size_t buffer_bytes = channelSize * get_channel_order_channel_count(outFormat->image_channel_order) * width * height * depth * sampleNum;
|
||||
if (buffer_bytes > maxAllocSize) {
|
||||
log_info("Output buffer size %d is too large for device (max alloc size %d) Skipping...\n",
|
||||
(int)buffer_bytes, (int)maxAllocSize);
|
||||
return 1;
|
||||
}
|
||||
|
||||
streams[ 1 ] = clCreateBuffer( context, CL_MEM_READ_WRITE, buffer_bytes, NULL, &error );
|
||||
test_error( error, "Unable to create output buffer" );
|
||||
|
||||
/* Assign streams and execute */
|
||||
cl_sampler_properties properties[] = {
|
||||
CL_SAMPLER_NORMALIZED_COORDS, CL_FALSE,
|
||||
CL_SAMPLER_ADDRESSING_MODE, CL_ADDRESS_NONE,
|
||||
CL_SAMPLER_FILTER_MODE, CL_FILTER_NEAREST,
|
||||
0 };
|
||||
clSamplerWrapper sampler = clCreateSamplerWithProperties( context, properties, &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" );
|
||||
|
||||
glFinish();
|
||||
|
||||
error = (*clEnqueueAcquireGLObjects_ptr)( queue, 1, &streams[ 0 ], 0, NULL, NULL);
|
||||
test_error( error, "Unable to acquire GL obejcts");
|
||||
|
||||
// The ND range we use is a function of the dimensionality of the image.
|
||||
size_t global_range[3] = { width, height, depth };
|
||||
size_t *local_range = NULL;
|
||||
int ndim = 1;
|
||||
|
||||
switch (get_base_gl_target(gl_target)) {
|
||||
case GL_TEXTURE_1D:
|
||||
case GL_TEXTURE_BUFFER:
|
||||
ndim = 1;
|
||||
break;
|
||||
case GL_TEXTURE_RECTANGLE_EXT:
|
||||
case GL_TEXTURE_2D:
|
||||
case GL_TEXTURE_1D_ARRAY:
|
||||
case GL_COLOR_ATTACHMENT0:
|
||||
case GL_RENDERBUFFER:
|
||||
case GL_TEXTURE_CUBE_MAP:
|
||||
ndim = 2;
|
||||
break;
|
||||
case GL_TEXTURE_3D:
|
||||
case GL_TEXTURE_2D_ARRAY:
|
||||
#ifdef GL_VERSION_3_2
|
||||
case GL_TEXTURE_2D_MULTISAMPLE:
|
||||
case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
|
||||
ndim = 3;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
log_error("Test error: Unsupported texture target.\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
// 2D and 3D images have a special way to set the local size (legacy).
|
||||
// Otherwise, we let CL select by leaving local_range as NULL.
|
||||
|
||||
if (gl_target == GL_TEXTURE_2D) {
|
||||
local_range = (size_t*)malloc(sizeof(size_t) * ndim);
|
||||
get_max_common_2D_work_group_size( context, kernel, global_range, local_range );
|
||||
|
||||
} else if (gl_target == GL_TEXTURE_3D) {
|
||||
local_range = (size_t*)malloc(sizeof(size_t) * ndim);
|
||||
get_max_common_3D_work_group_size( context, kernel, global_range, local_range );
|
||||
}
|
||||
|
||||
error = clEnqueueNDRangeKernel( queue, kernel, ndim, NULL, global_range,
|
||||
local_range, 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 * get_channel_order_channel_count(outFormat->image_channel_order) * width * height * depth * sampleNum] );
|
||||
error = clEnqueueReadBuffer( queue, streams[ 1 ], CL_TRUE, 0,
|
||||
channelSize * get_channel_order_channel_count(outFormat->image_channel_order) * width * height * depth * sampleNum, *outResultBuffer, 0, NULL, NULL );
|
||||
test_error( error, "Unable to read output CL buffer!" );
|
||||
|
||||
// free the ranges
|
||||
if (local_range) free(local_range);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int test_image_read( cl_context context, cl_command_queue queue,
|
||||
GLenum target, GLuint globj, size_t width, size_t height, size_t depth, size_t sampleNum,
|
||||
cl_image_format *outFormat, ExplicitType *outType, void **outResultBuffer )
|
||||
{
|
||||
int error;
|
||||
|
||||
// Create a CL image from the supplied GL texture or renderbuffer.
|
||||
cl_mem image;
|
||||
if (target == GL_RENDERBUFFER || target == GL_COLOR_ATTACHMENT0) {
|
||||
image = (*clCreateFromGLRenderbuffer_ptr)( context, CL_MEM_READ_ONLY, globj, &error );
|
||||
} else {
|
||||
image = (*clCreateFromGLTexture_ptr)( context, CL_MEM_READ_ONLY,
|
||||
target, 0, globj, &error );
|
||||
}
|
||||
|
||||
if( error != CL_SUCCESS ) {
|
||||
if (target == GL_RENDERBUFFER || target == GL_COLOR_ATTACHMENT0) {
|
||||
print_error( error, "Unable to create CL image from GL renderbuffer" );
|
||||
} else {
|
||||
print_error( error, "Unable to create CL image from GL texture" );
|
||||
GLint fmt;
|
||||
glGetTexLevelParameteriv( target, 0, GL_TEXTURE_INTERNAL_FORMAT, &fmt );
|
||||
log_error( " Supplied GL texture was base format %s and internal "
|
||||
"format %s\n", GetGLBaseFormatName( fmt ), GetGLFormatName( fmt ) );
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
return test_cl_image_read( context, queue, target, image,
|
||||
width, height, depth, sampleNum, outFormat, outType, outResultBuffer );
|
||||
}
|
||||
|
||||
static int test_image_format_read(
|
||||
cl_context context, cl_command_queue queue,
|
||||
size_t width, size_t height, size_t depth,
|
||||
GLenum target, struct format* fmt, MTdata data)
|
||||
{
|
||||
int error = 0;
|
||||
|
||||
// Determine the maximum number of supported samples
|
||||
GLint samples = 1;
|
||||
if (target == GL_TEXTURE_2D_MULTISAMPLE || target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY)
|
||||
samples = get_gl_max_samples(target, fmt->internal);
|
||||
|
||||
// If we're testing a half float format, then we need to determine the
|
||||
// rounding mode of this machine. Punt if we fail to do so.
|
||||
|
||||
if( fmt->type == kHalf )
|
||||
{
|
||||
if( DetectFloatToHalfRoundingMode(queue) )
|
||||
return 1;
|
||||
bool supports_half = false;
|
||||
error = supportsHalf(context, &supports_half);
|
||||
if( error != 0 )
|
||||
return error;
|
||||
if (!supports_half) return 0;
|
||||
}
|
||||
#ifdef GL_VERSION_3_2
|
||||
if (get_base_gl_target(target) == GL_TEXTURE_2D_MULTISAMPLE ||
|
||||
get_base_gl_target(target) == GL_TEXTURE_2D_MULTISAMPLE_ARRAY)
|
||||
{
|
||||
bool supports_msaa;
|
||||
error = supportsMsaa(context, &supports_msaa);
|
||||
if( error != 0 ) return error;
|
||||
if (!supports_msaa) return 0;
|
||||
}
|
||||
if (fmt->formattype == GL_DEPTH_COMPONENT ||
|
||||
fmt->formattype == GL_DEPTH_STENCIL)
|
||||
{
|
||||
bool supports_depth;
|
||||
error = supportsDepth(context, &supports_depth);
|
||||
if( error != 0 ) return error;
|
||||
if (!supports_depth) return 0;
|
||||
}
|
||||
#endif
|
||||
size_t w = width, h = height, d = depth;
|
||||
|
||||
// Unpack the format and use it, along with the target, to create an
|
||||
// appropriate GL texture.
|
||||
|
||||
GLenum gl_fmt = fmt->formattype;
|
||||
GLenum gl_internal_fmt = fmt->internal;
|
||||
GLenum gl_type = fmt->datatype;
|
||||
ExplicitType type = fmt->type;
|
||||
|
||||
// Required for most of the texture-backed cases:
|
||||
glTextureWrapper texture;
|
||||
|
||||
// Required for the special case of TextureBuffer textures:
|
||||
glBufferWrapper glbuf;
|
||||
|
||||
// And these are required for the case of Renderbuffer images:
|
||||
glFramebufferWrapper glFramebuffer;
|
||||
glRenderbufferWrapper glRenderbuffer;
|
||||
|
||||
void* buffer = NULL;
|
||||
|
||||
// Use the correct texture creation function depending on the target, and
|
||||
// adjust width, height, depth as appropriate so subsequent size calculations
|
||||
// succeed.
|
||||
|
||||
switch (get_base_gl_target(target)) {
|
||||
case GL_TEXTURE_1D:
|
||||
h = 1; d = 1;
|
||||
buffer = CreateGLTexture1D( width, target, gl_fmt,
|
||||
gl_internal_fmt, gl_type, type, &texture, &error, true, data );
|
||||
break;
|
||||
case GL_TEXTURE_BUFFER:
|
||||
h = 1; d = 1;
|
||||
buffer = CreateGLTextureBuffer(width, target, gl_fmt, gl_internal_fmt,
|
||||
gl_type, type, &texture, &glbuf, &error, true, data);
|
||||
break;
|
||||
case GL_RENDERBUFFER:
|
||||
case GL_COLOR_ATTACHMENT0:
|
||||
d = 1;
|
||||
buffer = CreateGLRenderbuffer(width, height, target, gl_fmt,
|
||||
gl_internal_fmt, gl_type, type, &glFramebuffer, &glRenderbuffer, &error,
|
||||
data, true);
|
||||
break;
|
||||
case GL_TEXTURE_2D:
|
||||
case GL_TEXTURE_RECTANGLE_EXT:
|
||||
case GL_TEXTURE_CUBE_MAP:
|
||||
d = 1;
|
||||
buffer = CreateGLTexture2D(width, height, target, gl_fmt, gl_internal_fmt,
|
||||
gl_type, type, &texture, &error, true, data);
|
||||
break;
|
||||
case GL_TEXTURE_1D_ARRAY:
|
||||
d = 1;
|
||||
buffer = CreateGLTexture1DArray( width, height, target, gl_fmt,
|
||||
gl_internal_fmt, gl_type, type, &texture, &error, true, data );
|
||||
break;
|
||||
case GL_TEXTURE_2D_ARRAY:
|
||||
buffer = CreateGLTexture2DArray( width, height, depth, target, gl_fmt,
|
||||
gl_internal_fmt, gl_type, type, &texture, &error, true, data );
|
||||
break;
|
||||
case GL_TEXTURE_3D:
|
||||
buffer = CreateGLTexture3D( width, height, depth, target, gl_fmt,
|
||||
gl_internal_fmt, gl_type, type, &texture, &error, data, true );
|
||||
break;
|
||||
#ifdef GL_VERSION_3_2
|
||||
case GL_TEXTURE_2D_MULTISAMPLE:
|
||||
d = 1;
|
||||
buffer = CreateGLTexture2DMultisample( width, height, samples, target, gl_fmt,
|
||||
gl_internal_fmt, gl_type, type, &texture, &error, true, data, true );
|
||||
break;
|
||||
case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
|
||||
buffer = CreateGLTexture2DArrayMultisample( width, height, depth, samples, target, gl_fmt,
|
||||
gl_internal_fmt, gl_type, type, &texture, &error, true, data, true );
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
log_error("Unsupported texture target.");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if ( error == -2 ) {
|
||||
log_info("OpenGL texture couldn't be created, because a texture is too big. Skipping test.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Check to see if the texture could not be created for some other reason like
|
||||
// GL_FRAMEBUFFER_UNSUPPORTED
|
||||
if (error == GL_FRAMEBUFFER_UNSUPPORTED) {
|
||||
log_info("Skipping...\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ( error != 0 ) {
|
||||
if ((gl_fmt == GL_RGBA_INTEGER_EXT) && (!CheckGLIntegerExtensionSupport())){
|
||||
log_info("OpenGL version does not support GL_RGBA_INTEGER_EXT. "
|
||||
"Skipping test.\n");
|
||||
return 0;
|
||||
} else {
|
||||
return error;
|
||||
}
|
||||
}
|
||||
|
||||
BufferOwningPtr<char> inputBuffer(buffer);
|
||||
if( inputBuffer == NULL )
|
||||
return -1;
|
||||
|
||||
cl_image_format clFormat;
|
||||
ExplicitType actualType;
|
||||
char *outBuffer;
|
||||
|
||||
// Perform the read:
|
||||
|
||||
GLuint globj = texture;
|
||||
if (target == GL_RENDERBUFFER || target == GL_COLOR_ATTACHMENT0) {
|
||||
globj = glRenderbuffer;
|
||||
}
|
||||
|
||||
error = test_image_read( context, queue, target, globj, w, h, d, samples, &clFormat,
|
||||
&actualType, (void **)&outBuffer );
|
||||
|
||||
if( error != 0 )
|
||||
return error;
|
||||
|
||||
BufferOwningPtr<char> actualResults(outBuffer);
|
||||
if( actualResults == NULL )
|
||||
return -1;
|
||||
|
||||
log_info( "- Read [%4d x %4d x %4d x %4d] : GL Texture : %s : %s : %s => CL Image : %s : %s \n",
|
||||
(int)w, (int)h, (int)d, (int)samples, GetGLFormatName( gl_fmt ), GetGLFormatName( gl_internal_fmt ),
|
||||
GetGLTypeName( gl_type ), GetChannelOrderName( clFormat.image_channel_order ),
|
||||
GetChannelTypeName( clFormat.image_channel_data_type ));
|
||||
|
||||
BufferOwningPtr<char> convertedInputs;
|
||||
|
||||
// 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).
|
||||
|
||||
if ( gl_type == GL_UNSIGNED_INT_2_10_10_10_REV )
|
||||
{
|
||||
cl_uint *p = (cl_uint *)buffer;
|
||||
float *inData = (float *)malloc( w * h * d * samples * sizeof(float) );
|
||||
|
||||
for( size_t i = 0; i < 4 * w * h * d * samples; i += 4 )
|
||||
{
|
||||
inData[ i + 0 ] = (float)( ( p[ 0 ] >> 20 ) & 0x3ff ) / (float)1023;
|
||||
inData[ i + 1 ] = (float)( ( p[ 0 ] >> 10 ) & 0x3ff ) / (float)1023;
|
||||
inData[ i + 2 ] = (float)( p[ 0 ] & 0x3ff ) / (float)1023;
|
||||
p++;
|
||||
}
|
||||
|
||||
convertedInputs.reset( inData );
|
||||
if( convertedInputs == NULL )
|
||||
return -1;
|
||||
}
|
||||
else if ( gl_type == GL_DEPTH24_STENCIL8 )
|
||||
{
|
||||
// GL_DEPTH24_STENCIL8 is treated as CL_UNORM_INT24 + CL_DEPTH_STENCIL where
|
||||
// the stencil is ignored.
|
||||
cl_uint *p = (cl_uint *)buffer;
|
||||
float *inData = (float *)malloc( w * h * d * samples * sizeof(float) );
|
||||
|
||||
for( size_t i = 0; i < w * h * d * samples; i++ )
|
||||
{
|
||||
inData[ i ] = (float)((p[i] >> 8) & 0xffffff) / (float)0xfffffe;
|
||||
}
|
||||
|
||||
convertedInputs.reset( inData );
|
||||
if( convertedInputs == NULL )
|
||||
return -1;
|
||||
}
|
||||
else if ( gl_type == GL_FLOAT_32_UNSIGNED_INT_24_8_REV)
|
||||
{
|
||||
// GL_FLOAT_32_UNSIGNED_INT_24_8_REV is treated as a CL_FLOAT +
|
||||
// unused 24 + CL_DEPTH_STENCIL; we check the float value and ignore the
|
||||
// second word
|
||||
|
||||
float *p = (float *)buffer;
|
||||
float *inData = (float *)malloc( w * h * d * samples * sizeof(float) );
|
||||
|
||||
for( size_t i = 0; i < w * h * d * samples; i++ )
|
||||
{
|
||||
inData[ i ] = p[i*2];
|
||||
}
|
||||
|
||||
convertedInputs.reset( inData );
|
||||
if( convertedInputs == NULL )
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
convertedInputs.reset(convert_to_expected( inputBuffer,
|
||||
w * h * d * samples, type, actualType, get_channel_order_channel_count(clFormat.image_channel_order) ));
|
||||
if( convertedInputs == NULL )
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Now we validate
|
||||
if( actualType == kFloat )
|
||||
{
|
||||
if ( clFormat.image_channel_data_type == CL_UNORM_INT_101010 )
|
||||
{
|
||||
return validate_float_results_rgb_101010( convertedInputs, actualResults, w, h, d, samples );
|
||||
}
|
||||
else
|
||||
{
|
||||
return validate_float_results( convertedInputs, actualResults, w, h, d, samples, get_channel_order_channel_count(clFormat.image_channel_order) );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return validate_integer_results( convertedInputs, actualResults, w, h, d, samples, get_explicit_type_size( actualType ) );
|
||||
}
|
||||
}
|
||||
|
||||
int test_images_read_common( cl_device_id device, cl_context context,
|
||||
cl_command_queue queue, struct format* formats, size_t nformats,
|
||||
GLenum *targets, size_t ntargets, sizevec_t *sizes, size_t nsizes )
|
||||
{
|
||||
int error = 0;
|
||||
RandomSeed seed(gRandomSeed);
|
||||
|
||||
// First, ensure this device supports images.
|
||||
|
||||
if (checkForImageSupport(device)) {
|
||||
log_info("Device does not support images. Skipping test.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t fidx, tidx, sidx;
|
||||
|
||||
// Test each format on every target, every size.
|
||||
|
||||
for ( fidx = 0; fidx < nformats; fidx++ ) {
|
||||
for ( tidx = 0; tidx < ntargets; tidx++ ) {
|
||||
|
||||
// Texture buffer only takes an internal format, so the level data passed
|
||||
// by the test and used for verification must match the internal format
|
||||
if ((targets[tidx] == GL_TEXTURE_BUFFER) && (GetGLFormat(formats[ fidx ].internal) != formats[fidx].formattype))
|
||||
continue;
|
||||
|
||||
if ( formats[ fidx ].datatype == GL_UNSIGNED_INT_2_10_10_10_REV )
|
||||
{
|
||||
// Check if the RGB 101010 format is supported
|
||||
if ( is_rgb_101010_supported( context, targets[ tidx ] ) == 0 )
|
||||
break; // skip
|
||||
}
|
||||
|
||||
if (targets[tidx] != GL_TEXTURE_BUFFER)
|
||||
log_info( "Testing image read for GL format %s : %s : %s : %s\n",
|
||||
GetGLTargetName( targets[ tidx ] ),
|
||||
GetGLFormatName( formats[ fidx ].internal ),
|
||||
GetGLBaseFormatName( formats[ fidx ].formattype ),
|
||||
GetGLTypeName( formats[ fidx ].datatype ) );
|
||||
else
|
||||
log_info( "Testing image read for GL format %s : %s\n",
|
||||
GetGLTargetName( targets[ tidx ] ),
|
||||
GetGLFormatName( formats[ fidx ].internal ));
|
||||
|
||||
for ( sidx = 0; sidx < nsizes; sidx++ ) {
|
||||
|
||||
// Test this format + size:
|
||||
int err;
|
||||
if ((err = test_image_format_read(context, queue,
|
||||
sizes[sidx].width, sizes[sidx].height, sizes[sidx].depth,
|
||||
targets[tidx], &formats[fidx], seed) ))
|
||||
{
|
||||
// Negative return values are errors, positive mean the test was skipped
|
||||
if (err < 0) {
|
||||
|
||||
// We land here in the event of test failure.
|
||||
|
||||
log_error( "ERROR: Image read test failed for %s : %s : %s : %s\n\n",
|
||||
GetGLTargetName( targets[ tidx ] ),
|
||||
GetGLFormatName( formats[ fidx ].internal ),
|
||||
GetGLBaseFormatName( formats[ fidx ].formattype ),
|
||||
GetGLTypeName( formats[ fidx ].datatype ) );
|
||||
error++;
|
||||
}
|
||||
|
||||
// Skip the other sizes for this format.
|
||||
printf("Skipping remaining sizes for this format\n");
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Note a successful format test, if we passed every size.
|
||||
|
||||
if( sidx == sizeof (sizes) / sizeof( sizes[0] ) ) {
|
||||
log_info( "passed: Image read test for GL format %s : %s : %s : %s\n\n",
|
||||
GetGLTargetName( targets[ tidx ] ),
|
||||
GetGLFormatName( formats[ fidx ].internal ),
|
||||
GetGLBaseFormatName( formats[ fidx ].formattype ),
|
||||
GetGLTypeName( formats[ fidx ].datatype ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
868
test_conformance/gl/test_images_write_common.cpp
Normal file
868
test_conformance/gl/test_images_write_common.cpp
Normal file
@@ -0,0 +1,868 @@
|
||||
//
|
||||
// Copyright (c) 2017 The Khronos Group Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
#include "testBase.h"
|
||||
#include "common.h"
|
||||
#include <limits.h>
|
||||
|
||||
#if defined( __APPLE__ )
|
||||
#include <OpenGL/glu.h>
|
||||
#else
|
||||
#include <GL/glu.h>
|
||||
#include <CL/cl_gl.h>
|
||||
#endif
|
||||
|
||||
extern "C" { extern cl_uint gRandomSeed; };
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark Write test kernels
|
||||
|
||||
static const char *kernelpattern_image_write_1D =
|
||||
"__kernel void sample_test( __global %s4 *source, write_only image1d_t dest )\n"
|
||||
"{\n"
|
||||
" uint index = get_global_id(0);\n"
|
||||
" %s4 value = source[index];\n"
|
||||
" write_image%s( dest, index, %s(value));\n"
|
||||
"}\n";
|
||||
|
||||
static const char *kernelpattern_image_write_1D_half =
|
||||
"__kernel void sample_test( __global half4 *source, write_only image1d_t dest )\n"
|
||||
"{\n"
|
||||
" uint index = get_global_id(0);\n"
|
||||
" write_imagef( dest, index, vload_half4(index, (__global half *)source));\n"
|
||||
"}\n";
|
||||
|
||||
static const char *kernelpattern_image_write_1D_buffer =
|
||||
"__kernel void sample_test( __global %s4 *source, write_only image1d_buffer_t dest )\n"
|
||||
"{\n"
|
||||
" uint index = get_global_id(0);\n"
|
||||
" %s4 value = source[index];\n"
|
||||
" write_image%s( dest, index, %s(value));\n"
|
||||
"}\n";
|
||||
|
||||
static const char *kernelpattern_image_write_1D_buffer_half =
|
||||
"__kernel void sample_test( __global half4 *source, write_only image1d_buffer_t dest )\n"
|
||||
"{\n"
|
||||
" uint index = get_global_id(0);\n"
|
||||
" write_imagef( dest, index, vload_half4(index, (__global half *)source));\n"
|
||||
"}\n";
|
||||
|
||||
static const char *kernelpattern_image_write_2D =
|
||||
"__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";
|
||||
|
||||
static const char *kernelpattern_image_write_2D_half =
|
||||
"__kernel void sample_test( __global half4 *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"
|
||||
" write_imagef( dest, (int2)( tidX, tidY ), vload_half4(index, (__global half *)source));\n"
|
||||
"}\n";
|
||||
|
||||
static const char *kernelpattern_image_write_1Darray =
|
||||
"__kernel void sample_test( __global %s4 *source, write_only image1d_array_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";
|
||||
|
||||
static const char *kernelpattern_image_write_1Darray_half =
|
||||
"__kernel void sample_test( __global half4 *source, write_only image1d_array_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"
|
||||
" write_imagef( dest, (int2)( tidX, tidY ), vload_half4(index, (__global half *)source));\n"
|
||||
"}\n";
|
||||
|
||||
static const char *kernelpattern_image_write_3D =
|
||||
"__kernel void sample_test( __global %s4 *source, write_only image3d_t dest )\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( dest );\n"
|
||||
" int height = get_image_height( dest );\n"
|
||||
" int index = tidZ * width * height + tidY * width + tidX;\n"
|
||||
" %s4 value = source[index];\n"
|
||||
" write_image%s( dest, (int4)( tidX, tidY, tidZ, 0 ), %s(value));\n"
|
||||
"}\n";
|
||||
|
||||
static const char *kernelpattern_image_write_3D_half =
|
||||
"__kernel void sample_test( __global half4 *source, write_only image3d_t dest )\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( dest );\n"
|
||||
" int height = get_image_height( dest );\n"
|
||||
" int index = tidZ * width * height + tidY * width + tidX;\n"
|
||||
" write_imagef( dest, (int4)( tidX, tidY, tidZ, 0 ), vload_half4(index, (__global half *)source));\n"
|
||||
"}\n";
|
||||
|
||||
static const char *kernelpattern_image_write_2Darray =
|
||||
"__kernel void sample_test( __global %s4 *source, write_only image2d_array_t dest )\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( dest );\n"
|
||||
" int height = get_image_height( dest );\n"
|
||||
" int index = tidZ * width * height + tidY * width + tidX;\n"
|
||||
" %s4 value = source[index];\n"
|
||||
" write_image%s( dest, (int4)( tidX, tidY, tidZ, 0 ), %s(value));\n"
|
||||
"}\n";
|
||||
|
||||
static const char *kernelpattern_image_write_2Darray_half =
|
||||
"__kernel void sample_test( __global half4 *source, write_only image2d_array_t dest )\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( dest );\n"
|
||||
" int height = get_image_height( dest );\n"
|
||||
" int index = tidZ * width * height + tidY * width + tidX;\n"
|
||||
" write_imagef( dest, (int4)( tidX, tidY, tidZ, 0 ), vload_half4(index, (__global half *)source));\n"
|
||||
"}\n";
|
||||
|
||||
#ifdef GL_VERSION_3_2
|
||||
|
||||
static const char * kernelpattern_image_write_2D_depth =
|
||||
"__kernel void sample_test( __global %s *source, write_only image2d_depth_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"
|
||||
" float value = source[index];\n"
|
||||
" write_imagef( dest, (int2)( tidX, tidY ), value);\n"
|
||||
"}\n";
|
||||
|
||||
static const char * kernelpattern_image_write_2D_array_depth =
|
||||
"__kernel void sample_test( __global %s *source, write_only image2d_array_depth_t dest )\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( dest );\n"
|
||||
" int height = get_image_height( dest );\n"
|
||||
" int index = tidZ * width * height + tidY * width + tidX;\n"
|
||||
" %s value = source[index];\n"
|
||||
" write_image%s( dest, (int4)( tidX, tidY, tidZ, 0 ), %s(value));\n"
|
||||
"}\n";
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark Utility functions
|
||||
|
||||
static const char* get_appropriate_write_kernel(GLenum target,
|
||||
ExplicitType type, cl_channel_order channel_order)
|
||||
{
|
||||
switch (get_base_gl_target(target)) {
|
||||
case GL_TEXTURE_1D:
|
||||
|
||||
if (type == kHalf)
|
||||
return kernelpattern_image_write_1D_half;
|
||||
else
|
||||
return kernelpattern_image_write_1D;
|
||||
break;
|
||||
case GL_TEXTURE_BUFFER:
|
||||
if (type == kHalf)
|
||||
return kernelpattern_image_write_1D_buffer_half;
|
||||
else
|
||||
return kernelpattern_image_write_1D_buffer;
|
||||
break;
|
||||
case GL_TEXTURE_1D_ARRAY:
|
||||
if (type == kHalf)
|
||||
return kernelpattern_image_write_1Darray_half;
|
||||
else
|
||||
return kernelpattern_image_write_1Darray;
|
||||
break;
|
||||
case GL_COLOR_ATTACHMENT0:
|
||||
case GL_RENDERBUFFER:
|
||||
case GL_TEXTURE_RECTANGLE_EXT:
|
||||
case GL_TEXTURE_2D:
|
||||
case GL_TEXTURE_CUBE_MAP:
|
||||
#ifdef GL_VERSION_3_2
|
||||
if (channel_order == CL_DEPTH || channel_order == CL_DEPTH_STENCIL)
|
||||
return kernelpattern_image_write_2D_depth;
|
||||
#endif
|
||||
if (type == kHalf)
|
||||
return kernelpattern_image_write_2D_half;
|
||||
else
|
||||
return kernelpattern_image_write_2D;
|
||||
break;
|
||||
|
||||
case GL_TEXTURE_2D_ARRAY:
|
||||
#ifdef GL_VERSION_3_2
|
||||
if (channel_order == CL_DEPTH || channel_order == CL_DEPTH_STENCIL)
|
||||
return kernelpattern_image_write_2D_array_depth;
|
||||
#endif
|
||||
if (type == kHalf)
|
||||
return kernelpattern_image_write_2Darray_half;
|
||||
else
|
||||
return kernelpattern_image_write_2Darray;
|
||||
break;
|
||||
|
||||
case GL_TEXTURE_3D:
|
||||
if (type == kHalf)
|
||||
return kernelpattern_image_write_3D_half;
|
||||
else
|
||||
return kernelpattern_image_write_3D;
|
||||
break;
|
||||
|
||||
default:
|
||||
log_error("Unsupported GL tex target (%s) passed to write test: "
|
||||
"%s (%s):%d", GetGLTargetName(target), __FUNCTION__,
|
||||
__FILE__, __LINE__);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void set_dimensions_by_target(GLenum target, size_t *dims, size_t sizes[3],
|
||||
size_t width, size_t height, size_t depth)
|
||||
{
|
||||
switch (get_base_gl_target(target)) {
|
||||
case GL_TEXTURE_1D:
|
||||
sizes[0] = width;
|
||||
*dims = 1;
|
||||
break;
|
||||
|
||||
case GL_TEXTURE_BUFFER:
|
||||
sizes[0] = width;
|
||||
*dims = 1;
|
||||
break;
|
||||
|
||||
case GL_TEXTURE_1D_ARRAY:
|
||||
sizes[0] = width;
|
||||
sizes[1] = height;
|
||||
*dims = 2;
|
||||
break;
|
||||
|
||||
case GL_COLOR_ATTACHMENT0:
|
||||
case GL_RENDERBUFFER:
|
||||
case GL_TEXTURE_RECTANGLE_EXT:
|
||||
case GL_TEXTURE_2D:
|
||||
case GL_TEXTURE_CUBE_MAP:
|
||||
|
||||
sizes[0] = width;
|
||||
sizes[1] = height;
|
||||
*dims = 2;
|
||||
break;
|
||||
|
||||
case GL_TEXTURE_2D_ARRAY:
|
||||
sizes[0] = width;
|
||||
sizes[1] = height;
|
||||
sizes[2] = depth;
|
||||
*dims = 3;
|
||||
break;
|
||||
|
||||
case GL_TEXTURE_3D:
|
||||
sizes[0] = width;
|
||||
sizes[1] = height;
|
||||
sizes[2] = depth;
|
||||
*dims = 3;
|
||||
break;
|
||||
|
||||
default:
|
||||
log_error("Unsupported GL tex target (%s) passed to write test: "
|
||||
"%s (%s):%d", GetGLTargetName(target), __FUNCTION__,
|
||||
__FILE__, __LINE__);
|
||||
}
|
||||
}
|
||||
|
||||
int test_cl_image_write( cl_context context, cl_command_queue queue,
|
||||
GLenum target, cl_mem clImage, size_t width, size_t height, size_t depth,
|
||||
cl_image_format *outFormat, ExplicitType *outType, void **outSourceBuffer,
|
||||
MTdata d, bool supports_half )
|
||||
{
|
||||
size_t global_dims, global_sizes[3];
|
||||
clProgramWrapper program;
|
||||
clKernelWrapper kernel;
|
||||
clMemWrapper inStream;
|
||||
char* programPtr;
|
||||
int error;
|
||||
char kernelSource[2048];
|
||||
|
||||
// What CL format did we get from the texture?
|
||||
|
||||
error = clGetImageInfo(clImage, CL_IMAGE_FORMAT, sizeof(cl_image_format),
|
||||
outFormat, NULL);
|
||||
test_error(error, "Unable to get the CL image format");
|
||||
|
||||
// Create the kernel source. The target and the data type will influence
|
||||
// which particular kernel we choose.
|
||||
|
||||
*outType = get_write_kernel_type( outFormat );
|
||||
size_t channelSize = get_explicit_type_size(*outType);
|
||||
|
||||
const char* appropriateKernel = get_appropriate_write_kernel(target,
|
||||
*outType, outFormat->image_channel_order);
|
||||
if (*outType == kHalf && !supports_half) {
|
||||
log_info("cl_khr_fp16 isn't supported. Skip this test.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char* suffix = get_kernel_suffix( outFormat );
|
||||
const char* convert = get_write_conversion( outFormat, *outType );
|
||||
|
||||
sprintf(kernelSource, appropriateKernel, get_explicit_type_name( *outType ),
|
||||
get_explicit_type_name( *outType ), suffix, convert);
|
||||
|
||||
programPtr = kernelSource;
|
||||
if( create_single_kernel_helper( context, &program, &kernel, 1,
|
||||
(const char **)&programPtr, "sample_test" ) )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Create an appropriately-sized output buffer.
|
||||
|
||||
// Check to see if the output buffer will fit on the device
|
||||
size_t bytes = channelSize * 4 * width * height * depth;
|
||||
cl_ulong alloc_size = 0;
|
||||
|
||||
cl_device_id device = NULL;
|
||||
error = clGetCommandQueueInfo(queue, CL_QUEUE_DEVICE, sizeof(device), &device, NULL);
|
||||
test_error( error, "Unable to query command queue for device" );
|
||||
|
||||
error = clGetDeviceInfo(device, CL_DEVICE_MAX_MEM_ALLOC_SIZE, sizeof(alloc_size), &alloc_size, NULL);
|
||||
test_error( error, "Unable to device for max mem alloc size" );
|
||||
|
||||
if (bytes > alloc_size) {
|
||||
log_info(" Skipping: Buffer size (%lu) is greater than CL_DEVICE_MAX_MEM_ALLOC_SIZE (%lu)\n", bytes, alloc_size);
|
||||
*outSourceBuffer = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
*outSourceBuffer = CreateRandomData(*outType, width * height * depth * 4, d);
|
||||
|
||||
inStream = clCreateBuffer( context, CL_MEM_COPY_HOST_PTR,
|
||||
channelSize * 4 * width * height * depth, *outSourceBuffer, &error );
|
||||
test_error( error, "Unable to create output buffer" );
|
||||
|
||||
cl_sampler_properties properties[] = {
|
||||
CL_SAMPLER_NORMALIZED_COORDS, CL_FALSE,
|
||||
CL_SAMPLER_ADDRESSING_MODE, CL_ADDRESS_NONE,
|
||||
CL_SAMPLER_FILTER_MODE, CL_FILTER_NEAREST,
|
||||
0 };
|
||||
clSamplerWrapper sampler = clCreateSamplerWithProperties( context, properties, &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" );
|
||||
|
||||
// Flush and Acquire.
|
||||
|
||||
glFinish();
|
||||
|
||||
error = (*clEnqueueAcquireGLObjects_ptr)( queue, 1, &clImage, 0, NULL, NULL);
|
||||
test_error( error, "Unable to acquire GL obejcts");
|
||||
|
||||
// Execute ( letting OpenCL choose the local size )
|
||||
|
||||
// Setup the global dimensions and sizes based on the target type.
|
||||
set_dimensions_by_target(target, &global_dims, global_sizes,
|
||||
width, height, depth);
|
||||
|
||||
error = clEnqueueNDRangeKernel( queue, kernel, global_dims, NULL,
|
||||
global_sizes, NULL, 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");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int test_image_write( cl_context context, cl_command_queue queue,
|
||||
GLenum glTarget, GLuint glTexture, size_t width, size_t height, size_t depth,
|
||||
cl_image_format *outFormat, ExplicitType *outType, void **outSourceBuffer,
|
||||
MTdata d, bool supports_half )
|
||||
{
|
||||
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" );
|
||||
GLint fmt;
|
||||
glGetTexLevelParameteriv( glTarget, 0, GL_TEXTURE_INTERNAL_FORMAT, &fmt );
|
||||
log_error( " Supplied GL texture was base format %s and internal "
|
||||
"format %s\n", GetGLBaseFormatName( fmt ), GetGLFormatName( fmt ) );
|
||||
return error;
|
||||
}
|
||||
|
||||
return test_cl_image_write( context, queue, glTarget, image,
|
||||
width, height, depth, outFormat, outType, outSourceBuffer, d, supports_half );
|
||||
}
|
||||
|
||||
int supportsHalf(cl_context context, bool* supports_half)
|
||||
{
|
||||
int error;
|
||||
size_t size;
|
||||
cl_uint numDev;
|
||||
|
||||
error = clGetContextInfo(context, CL_CONTEXT_NUM_DEVICES, sizeof(cl_uint), &numDev, NULL);
|
||||
test_error(error, "clGetContextInfo for CL_CONTEXT_NUM_DEVICES failed");
|
||||
|
||||
cl_device_id* devices = new cl_device_id[numDev];
|
||||
error = clGetContextInfo(context, CL_CONTEXT_DEVICES, numDev * sizeof(cl_device_id), devices, NULL);
|
||||
test_error(error, "clGetContextInfo for CL_CONTEXT_DEVICES failed");
|
||||
|
||||
// Get the extensions string for the device
|
||||
error = clGetDeviceInfo(devices[0], CL_DEVICE_EXTENSIONS, 0, NULL, &size);
|
||||
test_error(error, "clGetDeviceInfo for CL_DEVICE_EXTENSIONS size failed");
|
||||
|
||||
char *extensions = new char[size+1];
|
||||
if (extensions == 0) {
|
||||
log_error("Failed to allocate memory for extensions string.\n");
|
||||
return -1;
|
||||
}
|
||||
memset( extensions, CHAR_MIN, sizeof(char)*(size+1) );
|
||||
|
||||
error = clGetDeviceInfo(devices[0], CL_DEVICE_EXTENSIONS, sizeof(char)*size, extensions, NULL);
|
||||
test_error(error, "clGetDeviceInfo for CL_DEVICE_EXTENSIONS failed");
|
||||
|
||||
*supports_half = strstr(extensions, "cl_khr_fp16");
|
||||
delete [] extensions;
|
||||
delete [] devices;
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
int supportsMsaa(cl_context context, bool* supports_msaa)
|
||||
{
|
||||
int error;
|
||||
size_t size;
|
||||
cl_uint numDev;
|
||||
|
||||
error = clGetContextInfo(context, CL_CONTEXT_NUM_DEVICES, sizeof(cl_uint), &numDev, NULL);
|
||||
test_error(error, "clGetContextInfo for CL_CONTEXT_NUM_DEVICES failed");
|
||||
|
||||
cl_device_id* devices = new cl_device_id[numDev];
|
||||
error = clGetContextInfo(context, CL_CONTEXT_DEVICES, numDev * sizeof(cl_device_id), devices, NULL);
|
||||
test_error(error, "clGetContextInfo for CL_CONTEXT_DEVICES failed");
|
||||
|
||||
// Get the extensions string for the device
|
||||
error = clGetDeviceInfo(devices[0], CL_DEVICE_EXTENSIONS, 0, NULL, &size);
|
||||
test_error(error, "clGetDeviceInfo for CL_DEVICE_EXTENSIONS size failed");
|
||||
|
||||
char *extensions = new char[size+1];
|
||||
if (extensions == 0) {
|
||||
log_error("Failed to allocate memory for extensions string.\n");
|
||||
return -1;
|
||||
}
|
||||
memset( extensions, CHAR_MIN, sizeof(char)*(size+1) );
|
||||
|
||||
error = clGetDeviceInfo(devices[0], CL_DEVICE_EXTENSIONS, sizeof(char)*size, extensions, NULL);
|
||||
test_error(error, "clGetDeviceInfo for CL_DEVICE_EXTENSIONS failed");
|
||||
|
||||
*supports_msaa = strstr(extensions, "cl_khr_gl_msaa_sharing");
|
||||
delete [] extensions;
|
||||
delete [] devices;
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
int supportsDepth(cl_context context, bool* supports_depth)
|
||||
{
|
||||
int error;
|
||||
size_t size;
|
||||
cl_uint numDev;
|
||||
|
||||
error = clGetContextInfo(context, CL_CONTEXT_NUM_DEVICES, sizeof(cl_uint), &numDev, NULL);
|
||||
test_error(error, "clGetContextInfo for CL_CONTEXT_NUM_DEVICES failed");
|
||||
|
||||
cl_device_id* devices = new cl_device_id[numDev];
|
||||
error = clGetContextInfo(context, CL_CONTEXT_DEVICES, numDev * sizeof(cl_device_id), devices, NULL);
|
||||
test_error(error, "clGetContextInfo for CL_CONTEXT_DEVICES failed");
|
||||
|
||||
// Get the extensions string for the device
|
||||
error = clGetDeviceInfo(devices[0], CL_DEVICE_EXTENSIONS, 0, NULL, &size);
|
||||
test_error(error, "clGetDeviceInfo for CL_DEVICE_EXTENSIONS size failed");
|
||||
|
||||
char *extensions = new char[size+1];
|
||||
if (extensions == 0) {
|
||||
log_error("Failed to allocate memory for extensions string.\n");
|
||||
return -1;
|
||||
}
|
||||
memset( extensions, CHAR_MIN, sizeof(char)*(size+1) );
|
||||
|
||||
error = clGetDeviceInfo(devices[0], CL_DEVICE_EXTENSIONS, sizeof(char)*size, extensions, NULL);
|
||||
test_error(error, "clGetDeviceInfo for CL_DEVICE_EXTENSIONS failed");
|
||||
|
||||
*supports_depth = strstr(extensions, "cl_khr_gl_depth_images");
|
||||
delete [] extensions;
|
||||
delete [] devices;
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
static int test_image_format_write( 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;
|
||||
int samples = 8;
|
||||
// If we're testing a half float format, then we need to determine the
|
||||
// rounding mode of this machine. Punt if we fail to do so.
|
||||
|
||||
if( type == kHalf )
|
||||
if( DetectFloatToHalfRoundingMode(queue) )
|
||||
return 1;
|
||||
|
||||
// Create an appropriate GL texture or renderbuffer, given the target.
|
||||
|
||||
glTextureWrapper glTexture;
|
||||
glBufferWrapper glBuf;
|
||||
glFramebufferWrapper glFramebuffer;
|
||||
glRenderbufferWrapper glRenderbuffer;
|
||||
switch (get_base_gl_target(target)) {
|
||||
case GL_TEXTURE_1D:
|
||||
CreateGLTexture1D( width, target, format, internalFormat, glType,
|
||||
type, &glTexture, &error, false, d );
|
||||
break;
|
||||
case GL_TEXTURE_BUFFER:
|
||||
CreateGLTextureBuffer( width, target, format, internalFormat, glType,
|
||||
type, &glTexture, &glBuf, &error, false, d );
|
||||
break;
|
||||
case GL_TEXTURE_1D_ARRAY:
|
||||
CreateGLTexture1DArray( width, height, target, format, internalFormat,
|
||||
glType, type, &glTexture, &error, false, d );
|
||||
break;
|
||||
case GL_TEXTURE_RECTANGLE_EXT:
|
||||
case GL_TEXTURE_2D:
|
||||
case GL_TEXTURE_CUBE_MAP:
|
||||
CreateGLTexture2D( width, height, target, format, internalFormat, glType,
|
||||
type, &glTexture, &error, false, d );
|
||||
break;
|
||||
case GL_COLOR_ATTACHMENT0:
|
||||
case GL_RENDERBUFFER:
|
||||
CreateGLRenderbuffer(width, height, target, format, internalFormat,
|
||||
glType, type, &glFramebuffer, &glRenderbuffer, &error, d, false);
|
||||
case GL_TEXTURE_2D_ARRAY:
|
||||
CreateGLTexture2DArray( width, height, depth, target, format,
|
||||
internalFormat, glType, type, &glTexture, &error, false, d );
|
||||
break;
|
||||
case GL_TEXTURE_3D:
|
||||
CreateGLTexture3D( width, height, depth, target, format,
|
||||
internalFormat, glType, type, &glTexture, &error, d, false );
|
||||
break;
|
||||
|
||||
default:
|
||||
log_error("Unsupported GL tex target (%s) passed to write test: "
|
||||
"%s (%s):%d", GetGLTargetName(target), __FUNCTION__,
|
||||
__FILE__, __LINE__);
|
||||
}
|
||||
|
||||
// If there was a problem during creation, make sure it isn't a known
|
||||
// cause, and then complain.
|
||||
if ( error == -2 ) {
|
||||
log_info("OpenGL texture couldn't be created, because a texture is too big. Skipping test.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ( error != 0 ) {
|
||||
if ((format == GL_RGBA_INTEGER_EXT) && (!CheckGLIntegerExtensionSupport())){
|
||||
log_info("OpenGL version does not support GL_RGBA_INTEGER_EXT. "
|
||||
"Skipping test.\n");
|
||||
return 0;
|
||||
} else {
|
||||
return error;
|
||||
}
|
||||
}
|
||||
|
||||
// Run and get the results
|
||||
cl_image_format clFormat;
|
||||
ExplicitType sourceType;
|
||||
ExplicitType validationType;
|
||||
void *outSourceBuffer = NULL;
|
||||
|
||||
GLenum globj = glTexture;
|
||||
if (target == GL_RENDERBUFFER || target == GL_COLOR_ATTACHMENT0) {
|
||||
globj = glRenderbuffer;
|
||||
}
|
||||
|
||||
bool supports_half = false;
|
||||
error = supportsHalf(context, &supports_half);
|
||||
if( error != 0 )
|
||||
return error;
|
||||
|
||||
error = test_image_write( context, queue, target, globj, width, height,
|
||||
depth, &clFormat, &sourceType, (void **)&outSourceBuffer, d, supports_half );
|
||||
|
||||
if( error != 0 || ((sourceType == kHalf ) && !supports_half)) {
|
||||
if (outSourceBuffer)
|
||||
free(outSourceBuffer);
|
||||
return error;
|
||||
}
|
||||
|
||||
if (!outSourceBuffer)
|
||||
return 0;
|
||||
|
||||
// If actual source type was half, convert to float for validation.
|
||||
|
||||
if ( sourceType == kHalf )
|
||||
validationType = kFloat;
|
||||
else
|
||||
validationType = sourceType;
|
||||
|
||||
BufferOwningPtr<char> validationSource;
|
||||
|
||||
if ( clFormat.image_channel_data_type == CL_UNORM_INT_101010 )
|
||||
{
|
||||
validationSource.reset( outSourceBuffer );
|
||||
}
|
||||
else
|
||||
{
|
||||
validationSource.reset( convert_to_expected( outSourceBuffer,
|
||||
width * height * depth, sourceType, validationType, get_channel_order_channel_count(clFormat.image_channel_order) ) );
|
||||
free(outSourceBuffer);
|
||||
}
|
||||
|
||||
log_info( "- Write for %s [%4ld x %4ld x %4ld] : GL Texture : %s : %s : %s =>"
|
||||
" CL Image : %s : %s \n",
|
||||
GetGLTargetName(target),
|
||||
width, height, depth,
|
||||
GetGLFormatName( format ),
|
||||
GetGLFormatName( internalFormat ),
|
||||
GetGLTypeName( glType),
|
||||
GetChannelOrderName( clFormat.image_channel_order ),
|
||||
GetChannelTypeName( clFormat.image_channel_data_type ));
|
||||
|
||||
// Read the results from the GL texture.
|
||||
|
||||
ExplicitType readType = type;
|
||||
BufferOwningPtr<char> glResults( ReadGLTexture(
|
||||
target, glTexture, glBuf, width, format,
|
||||
internalFormat, glType, readType, /* unused */ 1, 1 ) );
|
||||
if( glResults == NULL )
|
||||
return -1;
|
||||
|
||||
// We have to convert our input buffer to the returned type, so we can validate.
|
||||
BufferOwningPtr<char> convertedGLResults;
|
||||
if ( clFormat.image_channel_data_type != CL_UNORM_INT_101010 )
|
||||
{
|
||||
convertedGLResults.reset( convert_to_expected(
|
||||
glResults, width * height * depth, readType, validationType, get_channel_order_channel_count(clFormat.image_channel_order), glType ));
|
||||
}
|
||||
|
||||
// Validate.
|
||||
|
||||
int valid = 0;
|
||||
if (convertedGLResults) {
|
||||
if( sourceType == kFloat || sourceType == kHalf )
|
||||
{
|
||||
if ( clFormat.image_channel_data_type == CL_UNORM_INT_101010 )
|
||||
{
|
||||
valid = validate_float_results_rgb_101010( validationSource, glResults, width, height, depth, 1 );
|
||||
}
|
||||
else
|
||||
{
|
||||
valid = validate_float_results( validationSource, convertedGLResults,
|
||||
width, height, depth, 1, get_channel_order_channel_count(clFormat.image_channel_order) );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
valid = validate_integer_results( validationSource, convertedGLResults,
|
||||
width, height, depth, 1, get_explicit_type_size( readType ) );
|
||||
}
|
||||
}
|
||||
|
||||
return valid;
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark Write test common entry point
|
||||
|
||||
// This is the main loop for all of the write tests. It iterates over the
|
||||
// given formats & targets, testing a variety of sizes against each
|
||||
// combination.
|
||||
|
||||
int test_images_write_common(cl_device_id device, cl_context context,
|
||||
cl_command_queue queue, struct format* formats, size_t nformats,
|
||||
GLenum *targets, size_t ntargets, sizevec_t* sizes, size_t nsizes )
|
||||
{
|
||||
int err = 0;
|
||||
int error = 0;
|
||||
RandomSeed seed(gRandomSeed);
|
||||
|
||||
// First, ensure this device supports images.
|
||||
|
||||
if (checkForImageSupport(device)) {
|
||||
log_info("Device does not support images. Skipping test.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Get the value of CL_DEVICE_MAX_MEM_ALLOC_SIZE
|
||||
cl_ulong max_individual_allocation_size = 0;
|
||||
err = clGetDeviceInfo(device, CL_DEVICE_MAX_MEM_ALLOC_SIZE,
|
||||
sizeof(max_individual_allocation_size),
|
||||
&max_individual_allocation_size, NULL);
|
||||
if (err) {
|
||||
log_error("ERROR: clGetDeviceInfo failed for CL_DEVICE_MAX_MEM_ALLOC_SIZE.\n");
|
||||
error++;
|
||||
return error;
|
||||
}
|
||||
|
||||
size_t total_allocation_size;
|
||||
size_t fidx, tidx, sidx;
|
||||
|
||||
for ( fidx = 0; fidx < nformats; fidx++ ) {
|
||||
for ( tidx = 0; tidx < ntargets; tidx++ ) {
|
||||
|
||||
// Texture buffer only takes an internal format, so the level data passed
|
||||
// by the test and used for verification must match the internal format
|
||||
if ((targets[tidx] == GL_TEXTURE_BUFFER) && (GetGLFormat(formats[ fidx ].internal) != formats[fidx].formattype))
|
||||
continue;
|
||||
|
||||
if ( formats[ fidx ].datatype == GL_UNSIGNED_INT_2_10_10_10_REV )
|
||||
{
|
||||
// Check if the RGB 101010 format is supported
|
||||
if ( is_rgb_101010_supported( context, targets[ tidx ] ) == 0 )
|
||||
continue; // skip
|
||||
}
|
||||
|
||||
if (formats[ fidx ].datatype == GL_UNSIGNED_INT_24_8)
|
||||
{
|
||||
//check if a implementation supports writing to the depth stencil formats
|
||||
cl_image_format imageFormat = { CL_DEPTH_STENCIL, CL_UNORM_INT24 };
|
||||
if (!is_image_format_supported(context, CL_MEM_WRITE_ONLY, (targets[tidx] == GL_TEXTURE_2D || targets[tidx] == GL_TEXTURE_RECTANGLE) ? CL_MEM_OBJECT_IMAGE2D: CL_MEM_OBJECT_IMAGE2D_ARRAY, &imageFormat))
|
||||
continue;
|
||||
}
|
||||
|
||||
if (formats[ fidx ].datatype == GL_FLOAT_32_UNSIGNED_INT_24_8_REV)
|
||||
{
|
||||
//check if a implementation supports writing to the depth stencil formats
|
||||
cl_image_format imageFormat = { CL_DEPTH_STENCIL, CL_FLOAT};
|
||||
if (!is_image_format_supported(context, CL_MEM_WRITE_ONLY, (targets[tidx] == GL_TEXTURE_2D || targets[tidx] == GL_TEXTURE_RECTANGLE) ? CL_MEM_OBJECT_IMAGE2D: CL_MEM_OBJECT_IMAGE2D_ARRAY, &imageFormat))
|
||||
continue;
|
||||
}
|
||||
|
||||
if (targets[tidx] != GL_TEXTURE_BUFFER)
|
||||
log_info( "Testing image write for GL format %s : %s : %s : %s\n",
|
||||
GetGLTargetName( targets[ tidx ] ),
|
||||
GetGLFormatName( formats[ fidx ].internal ),
|
||||
GetGLBaseFormatName( formats[ fidx ].formattype ),
|
||||
GetGLTypeName( formats[ fidx ].datatype ) );
|
||||
else
|
||||
log_info( "Testing image write for GL format %s : %s\n",
|
||||
GetGLTargetName( targets[ tidx ] ),
|
||||
GetGLFormatName( formats[ fidx ].internal ));
|
||||
|
||||
|
||||
for (sidx = 0; sidx < nsizes; sidx++) {
|
||||
|
||||
// All tested formats are 4-channel formats
|
||||
total_allocation_size =
|
||||
sizes[sidx].width * sizes[sidx].height * sizes[sidx].depth *
|
||||
4 * get_explicit_type_size( formats[ fidx ].type );
|
||||
|
||||
if (total_allocation_size > max_individual_allocation_size) {
|
||||
log_info( "The requested allocation size (%gMB) is larger than the "
|
||||
"maximum individual allocation size (%gMB)\n",
|
||||
total_allocation_size/(1024.0*1024.0),
|
||||
max_individual_allocation_size/(1024.0*1024.0));
|
||||
log_info( "Skipping write test for %s : %s : %s : %s "
|
||||
" and size (%ld, %ld, %ld)\n",
|
||||
GetGLTargetName( targets[ tidx ] ),
|
||||
GetGLFormatName( formats[ fidx ].internal ),
|
||||
GetGLBaseFormatName( formats[ fidx ].formattype ),
|
||||
GetGLTypeName( formats[ fidx ].datatype ),
|
||||
sizes[sidx].width,
|
||||
sizes[sidx].height,
|
||||
sizes[sidx].depth);
|
||||
continue;
|
||||
}
|
||||
#ifdef GL_VERSION_3_2
|
||||
if (get_base_gl_target(targets[ tidx ]) == GL_TEXTURE_2D_MULTISAMPLE ||
|
||||
get_base_gl_target(targets[ tidx ]) == GL_TEXTURE_2D_MULTISAMPLE_ARRAY)
|
||||
{
|
||||
bool supports_msaa;
|
||||
error = supportsMsaa(context, &supports_msaa);
|
||||
if( error != 0 ) return error;
|
||||
if (!supports_msaa) return 0;
|
||||
}
|
||||
if (formats[ fidx ].formattype == GL_DEPTH_COMPONENT ||
|
||||
formats[ fidx ].formattype == GL_DEPTH_STENCIL)
|
||||
{
|
||||
bool supports_depth;
|
||||
error = supportsDepth(context, &supports_depth);
|
||||
if( error != 0 ) return error;
|
||||
if (!supports_depth) return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
if( test_image_format_write( context, queue,
|
||||
sizes[sidx].width,
|
||||
sizes[sidx].height,
|
||||
sizes[sidx].depth,
|
||||
targets[ tidx ],
|
||||
formats[ fidx ].formattype,
|
||||
formats[ fidx ].internal,
|
||||
formats[ fidx ].datatype,
|
||||
formats[ fidx ].type, seed ) )
|
||||
{
|
||||
log_error( "ERROR: Image write test failed for %s : %s : %s : %s "
|
||||
" and size (%ld, %ld, %ld)\n\n",
|
||||
GetGLTargetName( targets[ tidx ] ),
|
||||
GetGLFormatName( formats[ fidx ].internal ),
|
||||
GetGLBaseFormatName( formats[ fidx ].formattype ),
|
||||
GetGLTypeName( formats[ fidx ].datatype ),
|
||||
sizes[sidx].width,
|
||||
sizes[sidx].height,
|
||||
sizes[sidx].depth);
|
||||
|
||||
error++;
|
||||
break; // Skip other sizes for this combination
|
||||
}
|
||||
}
|
||||
|
||||
// If we passed all sizes (check versus size loop count):
|
||||
|
||||
if (sidx == nsizes) {
|
||||
log_info( "passed: Image write for GL format %s : %s : %s : %s\n\n",
|
||||
GetGLTargetName( targets[ tidx ] ),
|
||||
GetGLFormatName( formats[ fidx ].internal ),
|
||||
GetGLBaseFormatName( formats[ fidx ].formattype ),
|
||||
GetGLTypeName( formats[ fidx ].datatype ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
479
test_conformance/gl/test_renderbuffer.cpp
Normal file
479
test_conformance/gl/test_renderbuffer.cpp
Normal file
@@ -0,0 +1,479 @@
|
||||
//
|
||||
// Copyright (c) 2017 The Khronos Group Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
#include "testBase.h"
|
||||
|
||||
#if defined( __APPLE__ )
|
||||
#include <OpenGL/glu.h>
|
||||
#else
|
||||
#include <GL/glu.h>
|
||||
#include <CL/cl_gl.h>
|
||||
#endif
|
||||
|
||||
#if defined (__linux__)
|
||||
GLboolean
|
||||
gluCheckExtension(const GLubyte *extension, const GLubyte *extensions)
|
||||
{
|
||||
const GLubyte *start;
|
||||
GLubyte *where, *terminator;
|
||||
|
||||
/* Extension names should not have spaces. */
|
||||
where = (GLubyte *) strchr((const char*)extension, ' ');
|
||||
if (where || *extension == '\0')
|
||||
return 0;
|
||||
/* It takes a bit of care to be fool-proof about parsing the
|
||||
OpenGL extensions string. Don't be fooled by sub-strings,
|
||||
etc. */
|
||||
start = extensions;
|
||||
for (;;) {
|
||||
where = (GLubyte *) strstr((const char *) start, (const char*) extension);
|
||||
if (!where)
|
||||
break;
|
||||
terminator = where + strlen((const char*) extension);
|
||||
if (where == start || *(where - 1) == ' ')
|
||||
if (*terminator == ' ' || *terminator == '\0')
|
||||
return 1;
|
||||
start = terminator;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
extern "C" { extern cl_uint gRandomSeed; };
|
||||
|
||||
// This is defined in the write common code:
|
||||
extern int test_cl_image_write( cl_context context, cl_command_queue queue,
|
||||
GLenum target, cl_mem clImage, size_t width, size_t height, size_t depth,
|
||||
cl_image_format *outFormat, ExplicitType *outType, void **outSourceBuffer,
|
||||
MTdata d, bool supports_half );
|
||||
|
||||
extern int test_cl_image_read( cl_context context, cl_command_queue queue,
|
||||
GLenum gl_target, cl_mem image, size_t width, size_t height, size_t depth, size_t sampleNum,
|
||||
cl_image_format *outFormat, ExplicitType *outType, void **outResultBuffer );
|
||||
|
||||
extern int supportsHalf(cl_context context, bool* supports_half);
|
||||
|
||||
static int test_attach_renderbuffer_read_image( cl_context context, cl_command_queue queue, GLenum glTarget, GLuint glRenderbuffer,
|
||||
size_t imageWidth, size_t imageHeight, cl_image_format *outFormat, ExplicitType *outType, void **outResultBuffer )
|
||||
{
|
||||
int error;
|
||||
|
||||
// Create a CL image from the supplied GL renderbuffer
|
||||
cl_mem image = (*clCreateFromGLRenderbuffer_ptr)( context, CL_MEM_READ_ONLY, glRenderbuffer, &error );
|
||||
if( error != CL_SUCCESS )
|
||||
{
|
||||
print_error( error, "Unable to create CL image from GL renderbuffer" );
|
||||
return error;
|
||||
}
|
||||
|
||||
return test_cl_image_read( context, queue, glTarget, image, imageWidth,
|
||||
imageHeight, 1, 1, outFormat, outType, outResultBuffer );
|
||||
}
|
||||
|
||||
int test_renderbuffer_read_image( cl_context context, cl_command_queue queue,
|
||||
GLsizei width, GLsizei height, GLenum attachment,
|
||||
GLenum format, GLenum internalFormat,
|
||||
GLenum glType, ExplicitType type, MTdata d )
|
||||
{
|
||||
int error;
|
||||
|
||||
if( type == kHalf )
|
||||
if( DetectFloatToHalfRoundingMode(queue) )
|
||||
return 1;
|
||||
|
||||
// Create the GL renderbuffer
|
||||
glFramebufferWrapper glFramebuffer;
|
||||
glRenderbufferWrapper glRenderbuffer;
|
||||
void *tmp = CreateGLRenderbuffer( width, height, attachment, format, internalFormat, glType, type, &glFramebuffer, &glRenderbuffer, &error, d, true );
|
||||
BufferOwningPtr<char> inputBuffer(tmp);
|
||||
if( error != 0 )
|
||||
{
|
||||
if ((format == GL_RGBA_INTEGER_EXT) && (!CheckGLIntegerExtensionSupport()))
|
||||
{
|
||||
log_info("OpenGL version does not support GL_RGBA_INTEGER_EXT. Skipping test.\n");
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
return error;
|
||||
}
|
||||
}
|
||||
|
||||
// Run and get the results
|
||||
cl_image_format clFormat;
|
||||
ExplicitType actualType;
|
||||
char *outBuffer;
|
||||
error = test_attach_renderbuffer_read_image( context, queue, attachment, glRenderbuffer, width, height, &clFormat, &actualType, (void **)&outBuffer );
|
||||
if( error != 0 )
|
||||
return error;
|
||||
BufferOwningPtr<char> actualResults(outBuffer);
|
||||
|
||||
log_info( "- Read [%4d x %4d] : GL renderbuffer : %s : %s : %s => CL Image : %s : %s \n", width, height,
|
||||
GetGLFormatName( format ), GetGLFormatName( internalFormat ), GetGLTypeName( glType),
|
||||
GetChannelOrderName( clFormat.image_channel_order ), GetChannelTypeName( clFormat.image_channel_data_type ));
|
||||
|
||||
#ifdef DEBUG
|
||||
log_info("- start read GL data -- \n");
|
||||
DumpGLBuffer(glType, width, height, actualResults);
|
||||
log_info("- end read GL data -- \n");
|
||||
#endif
|
||||
|
||||
// We have to convert our input buffer to the returned type, so we can validate.
|
||||
BufferOwningPtr<char> convertedInput(convert_to_expected( inputBuffer, width * height, type, actualType, get_channel_order_channel_count(clFormat.image_channel_order) ));
|
||||
|
||||
#ifdef DEBUG
|
||||
log_info("- start input data -- \n");
|
||||
DumpGLBuffer(GetGLTypeForExplicitType(actualType), width, height, convertedInput);
|
||||
log_info("- end input data -- \n");
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG
|
||||
log_info("- start converted data -- \n");
|
||||
DumpGLBuffer(GetGLTypeForExplicitType(actualType), width, height, actualResults);
|
||||
log_info("- end converted data -- \n");
|
||||
#endif
|
||||
|
||||
// Now we validate
|
||||
int valid = 0;
|
||||
if(convertedInput) {
|
||||
if( actualType == kFloat )
|
||||
valid = validate_float_results( convertedInput, actualResults, width, height, 1, get_channel_order_channel_count(clFormat.image_channel_order) );
|
||||
else
|
||||
valid = validate_integer_results( convertedInput, actualResults, width, height, 1, get_explicit_type_size( actualType ) );
|
||||
}
|
||||
|
||||
return valid;
|
||||
}
|
||||
|
||||
int test_renderbuffer_read( cl_device_id device, cl_context context, cl_command_queue queue, int numElements )
|
||||
{
|
||||
GLenum attachments[] = { GL_COLOR_ATTACHMENT0_EXT };
|
||||
|
||||
struct {
|
||||
GLenum internal;
|
||||
GLenum format;
|
||||
GLenum datatype;
|
||||
ExplicitType type;
|
||||
|
||||
} formats[] = {
|
||||
{ GL_RGBA, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, kUChar },
|
||||
{ GL_RGBA, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, kUChar },
|
||||
{ GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, kUChar },
|
||||
{ GL_RGBA16, GL_RGBA, GL_UNSIGNED_SHORT, kUShort },
|
||||
|
||||
// Renderbuffers with integer formats do not seem to work reliably across
|
||||
// platforms/implementations. Disabling this in version 1.0 of CL conformance tests.
|
||||
|
||||
#ifdef TEST_INTEGER_FORMATS
|
||||
|
||||
{ GL_RGBA8I_EXT, GL_RGBA_INTEGER_EXT, GL_BYTE, kChar },
|
||||
{ GL_RGBA16I_EXT, GL_RGBA_INTEGER_EXT, GL_SHORT, kShort },
|
||||
{ GL_RGBA32I_EXT, GL_RGBA_INTEGER_EXT, GL_INT, kInt },
|
||||
{ GL_RGBA8UI_EXT, GL_RGBA_INTEGER_EXT, GL_UNSIGNED_BYTE, kUChar },
|
||||
{ GL_RGBA16UI_EXT, GL_RGBA_INTEGER_EXT, GL_UNSIGNED_SHORT, kUShort },
|
||||
{ GL_RGBA32UI_EXT, GL_RGBA_INTEGER_EXT, GL_UNSIGNED_INT, kUInt },
|
||||
#endif
|
||||
{ GL_RGBA32F_ARB, GL_RGBA, GL_FLOAT, kFloat },
|
||||
{ GL_RGBA16F_ARB, GL_RGBA, GL_HALF_FLOAT, kHalf }
|
||||
};
|
||||
|
||||
size_t fmtIdx, attIdx;
|
||||
int error = 0;
|
||||
#ifdef DEBUG
|
||||
size_t iter = 1;
|
||||
#else
|
||||
size_t iter = 6;
|
||||
#endif
|
||||
RandomSeed seed( gRandomSeed );
|
||||
|
||||
// Check if images are supported
|
||||
if (checkForImageSupport(device)) {
|
||||
log_info("Device does not support images. Skipping test.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if( !gluCheckExtension( (const GLubyte *)"GL_EXT_framebuffer_object", glGetString( GL_EXTENSIONS ) ) )
|
||||
{
|
||||
log_info( "Renderbuffers are not supported by this OpenGL implementation; skipping test\n" );
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Loop through a set of GL formats, testing a set of sizes against each one
|
||||
for( fmtIdx = 0; fmtIdx < sizeof( formats ) / sizeof( formats[ 0 ] ); fmtIdx++ )
|
||||
{
|
||||
for( attIdx = 0; attIdx < sizeof( attachments ) / sizeof( attachments[ 0 ] ); attIdx++ )
|
||||
{
|
||||
size_t i;
|
||||
|
||||
log_info( "Testing renderbuffer read for %s : %s : %s : %s\n",
|
||||
GetGLAttachmentName( attachments[ attIdx ] ),
|
||||
GetGLFormatName( formats[ fmtIdx ].internal ),
|
||||
GetGLBaseFormatName( formats[ fmtIdx ].format ),
|
||||
GetGLTypeName( formats[ fmtIdx ].datatype ) );
|
||||
|
||||
for( i = 0; i < iter; i++ )
|
||||
{
|
||||
GLsizei width = random_in_range( 16, 512, seed );
|
||||
GLsizei height = random_in_range( 16, 512, seed );
|
||||
#ifdef DEBUG
|
||||
width = height = 4;
|
||||
#endif
|
||||
|
||||
if( test_renderbuffer_read_image( context, queue, width, height,
|
||||
attachments[ attIdx ],
|
||||
formats[ fmtIdx ].format,
|
||||
formats[ fmtIdx ].internal,
|
||||
formats[ fmtIdx ].datatype,
|
||||
formats[ fmtIdx ].type, seed ) )
|
||||
|
||||
{
|
||||
log_error( "ERROR: Renderbuffer read test failed for %s : %s : %s : %s\n\n",
|
||||
GetGLAttachmentName( attachments[ attIdx ] ),
|
||||
GetGLFormatName( formats[ fmtIdx ].internal ),
|
||||
GetGLBaseFormatName( formats[ fmtIdx ].format ),
|
||||
GetGLTypeName( formats[ fmtIdx ].datatype ) );
|
||||
|
||||
error++;
|
||||
break; // Skip other sizes for this combination
|
||||
}
|
||||
}
|
||||
if( i == iter )
|
||||
{
|
||||
log_info( "passed: Renderbuffer read test passed for %s : %s : %s : %s\n\n",
|
||||
GetGLAttachmentName( attachments[ attIdx ] ),
|
||||
GetGLFormatName( formats[ fmtIdx ].internal ),
|
||||
GetGLBaseFormatName( formats[ fmtIdx ].format ),
|
||||
GetGLTypeName( formats[ fmtIdx ].datatype ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
#pragma mark -------------------- Write tests -------------------------
|
||||
|
||||
int test_attach_renderbuffer_write_to_image( cl_context context, cl_command_queue queue, GLenum glTarget, GLuint glRenderbuffer,
|
||||
size_t imageWidth, size_t imageHeight, cl_image_format *outFormat, ExplicitType *outType, MTdata d, void **outSourceBuffer, bool supports_half )
|
||||
{
|
||||
int error;
|
||||
|
||||
// Create a CL image from the supplied GL renderbuffer
|
||||
clMemWrapper image = (*clCreateFromGLRenderbuffer_ptr)( context, CL_MEM_WRITE_ONLY, glRenderbuffer, &error );
|
||||
if( error != CL_SUCCESS )
|
||||
{
|
||||
print_error( error, "Unable to create CL image from GL renderbuffer" );
|
||||
return error;
|
||||
}
|
||||
|
||||
return test_cl_image_write( context, queue, glTarget, image, imageWidth,
|
||||
imageHeight, 1, outFormat, outType, outSourceBuffer, d, supports_half );
|
||||
}
|
||||
|
||||
int test_renderbuffer_image_write( cl_context context, cl_command_queue queue,
|
||||
GLsizei width, GLsizei height, GLenum attachment,
|
||||
GLenum format, GLenum internalFormat,
|
||||
GLenum glType, ExplicitType type, MTdata d )
|
||||
{
|
||||
int error;
|
||||
|
||||
if( type == kHalf )
|
||||
if( DetectFloatToHalfRoundingMode(queue) )
|
||||
return 1;
|
||||
|
||||
// Create the GL renderbuffer
|
||||
glFramebufferWrapper glFramebuffer;
|
||||
glRenderbufferWrapper glRenderbuffer;
|
||||
CreateGLRenderbuffer( width, height, attachment, format, internalFormat, glType, type, &glFramebuffer, &glRenderbuffer, &error, d, false );
|
||||
if( error != 0 )
|
||||
{
|
||||
if ((format == GL_RGBA_INTEGER_EXT) && (!CheckGLIntegerExtensionSupport()))
|
||||
{
|
||||
log_info("OpenGL version does not support GL_RGBA_INTEGER_EXT. Skipping test.\n");
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
return error;
|
||||
}
|
||||
}
|
||||
|
||||
// Run and get the results
|
||||
cl_image_format clFormat;
|
||||
ExplicitType sourceType;
|
||||
ExplicitType validationType;
|
||||
void *outSourceBuffer;
|
||||
|
||||
bool supports_half = false;
|
||||
error = supportsHalf(context, &supports_half);
|
||||
if( error != 0 )
|
||||
return error;
|
||||
|
||||
error = test_attach_renderbuffer_write_to_image( context, queue, attachment, glRenderbuffer, width, height, &clFormat, &sourceType, d, (void **)&outSourceBuffer, supports_half );
|
||||
if( error != 0 || ((sourceType == kHalf ) && !supports_half))
|
||||
return error;
|
||||
|
||||
// If actual source type was half, convert to float for validation.
|
||||
if( sourceType == kHalf )
|
||||
validationType = kFloat;
|
||||
else
|
||||
validationType = sourceType;
|
||||
|
||||
BufferOwningPtr<char> validationSource( convert_to_expected( outSourceBuffer, width * height, sourceType, validationType, get_channel_order_channel_count(clFormat.image_channel_order) ) );
|
||||
|
||||
log_info( "- Write [%4d x %4d] : GL Renderbuffer : %s : %s : %s => CL Image : %s : %s \n", width, height,
|
||||
GetGLFormatName( format ), GetGLFormatName( internalFormat ), GetGLTypeName( glType),
|
||||
GetChannelOrderName( clFormat.image_channel_order ), GetChannelTypeName( clFormat.image_channel_data_type ));
|
||||
|
||||
// Now read the results from the GL renderbuffer
|
||||
BufferOwningPtr<char> resultData( ReadGLRenderbuffer( glFramebuffer, glRenderbuffer, attachment, format, internalFormat, glType, type, width, height ) );
|
||||
|
||||
#ifdef DEBUG
|
||||
log_info("- start result data -- \n");
|
||||
DumpGLBuffer(glType, width, height, resultData);
|
||||
log_info("- end result data -- \n");
|
||||
#endif
|
||||
|
||||
// We have to convert our input buffer to the returned type, so we can validate.
|
||||
BufferOwningPtr<char> convertedData( convert_to_expected( resultData, width * height, type, validationType, get_channel_order_channel_count(clFormat.image_channel_order) ) );
|
||||
|
||||
#ifdef DEBUG
|
||||
log_info("- start input data -- \n");
|
||||
DumpGLBuffer(GetGLTypeForExplicitType(validationType), width, height, validationSource);
|
||||
log_info("- end input data -- \n");
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG
|
||||
log_info("- start converted data -- \n");
|
||||
DumpGLBuffer(GetGLTypeForExplicitType(validationType), width, height, convertedData);
|
||||
log_info("- end converted data -- \n");
|
||||
#endif
|
||||
|
||||
// Now we validate
|
||||
int valid = 0;
|
||||
if(convertedData) {
|
||||
if( sourceType == kFloat || sourceType == kHalf )
|
||||
valid = validate_float_results( validationSource, convertedData, width, height, 1, get_channel_order_channel_count(clFormat.image_channel_order) );
|
||||
else
|
||||
valid = validate_integer_results( validationSource, convertedData, width, height, 1, get_explicit_type_size( type ) );
|
||||
}
|
||||
|
||||
return valid;
|
||||
}
|
||||
|
||||
int test_renderbuffer_write( cl_device_id device, cl_context context, cl_command_queue queue, int numElements )
|
||||
{
|
||||
GLenum attachments[] = { GL_COLOR_ATTACHMENT0_EXT };
|
||||
|
||||
struct {
|
||||
GLenum internal;
|
||||
GLenum format;
|
||||
GLenum datatype;
|
||||
ExplicitType type;
|
||||
|
||||
} formats[] = {
|
||||
{ GL_RGBA, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, kUChar },
|
||||
{ GL_RGBA, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, kUChar },
|
||||
{ GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, kUChar },
|
||||
{ GL_RGBA16, GL_RGBA, GL_UNSIGNED_SHORT, kUShort },
|
||||
|
||||
// Renderbuffers with integer formats do not seem to work reliably across
|
||||
// platforms/implementations. Disabling this in version 1.0 of CL conformance tests.
|
||||
|
||||
#ifdef TEST_INTEGER_FORMATS
|
||||
|
||||
{ GL_RGBA8I_EXT, GL_RGBA_INTEGER_EXT, GL_BYTE, kChar },
|
||||
{ GL_RGBA16I_EXT, GL_RGBA_INTEGER_EXT, GL_SHORT, kShort },
|
||||
{ GL_RGBA32I_EXT, GL_RGBA_INTEGER_EXT, GL_INT, kInt },
|
||||
{ GL_RGBA8UI_EXT, GL_RGBA_INTEGER_EXT, GL_UNSIGNED_BYTE, kUChar },
|
||||
{ GL_RGBA16UI_EXT, GL_RGBA_INTEGER_EXT, GL_UNSIGNED_SHORT, kUShort },
|
||||
{ GL_RGBA32UI_EXT, GL_RGBA_INTEGER_EXT, GL_UNSIGNED_INT, kUInt },
|
||||
#endif
|
||||
{ GL_RGBA32F_ARB, GL_RGBA, GL_FLOAT, kFloat },
|
||||
{ GL_RGBA16F_ARB, GL_RGBA, GL_HALF_FLOAT, kHalf }
|
||||
};
|
||||
|
||||
size_t fmtIdx, attIdx;
|
||||
int error = 0;
|
||||
size_t iter = 6;
|
||||
#ifdef DEBUG
|
||||
iter = 1;
|
||||
#endif
|
||||
RandomSeed seed( gRandomSeed );
|
||||
|
||||
// Check if images are supported
|
||||
if (checkForImageSupport(device)) {
|
||||
log_info("Device does not support images. Skipping test.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if( !gluCheckExtension( (const GLubyte *)"GL_EXT_framebuffer_object", glGetString( GL_EXTENSIONS ) ) )
|
||||
{
|
||||
log_info( "Renderbuffers are not supported by this OpenGL implementation; skipping test\n" );
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Loop through a set of GL formats, testing a set of sizes against each one
|
||||
for( fmtIdx = 0; fmtIdx < sizeof( formats ) / sizeof( formats[ 0 ] ); fmtIdx++ )
|
||||
{
|
||||
for( attIdx = 0; attIdx < sizeof( attachments ) / sizeof( attachments[ 0 ] ); attIdx++ )
|
||||
{
|
||||
log_info( "Testing Renderbuffer write test for %s : %s : %s : %s\n",
|
||||
GetGLAttachmentName( attachments[ attIdx ] ),
|
||||
GetGLFormatName( formats[ fmtIdx ].internal ),
|
||||
GetGLBaseFormatName( formats[ fmtIdx ].format ),
|
||||
GetGLTypeName( formats[ fmtIdx ].datatype ) );
|
||||
|
||||
size_t i;
|
||||
for( i = 0; i < iter; i++ )
|
||||
{
|
||||
GLsizei width = random_in_range( 16, 512, seed );
|
||||
GLsizei height = random_in_range( 16, 512, seed );
|
||||
#ifdef DEBUG
|
||||
width = height = 4;
|
||||
#endif
|
||||
|
||||
if( test_renderbuffer_image_write( context, queue, width, height,
|
||||
attachments[ attIdx ],
|
||||
formats[ fmtIdx ].format,
|
||||
formats[ fmtIdx ].internal,
|
||||
formats[ fmtIdx ].datatype,
|
||||
formats[ fmtIdx ].type, seed ) )
|
||||
{
|
||||
log_error( "ERROR: Renderbuffer write test failed for %s : %s : %s : %s\n\n",
|
||||
GetGLAttachmentName( attachments[ attIdx ] ),
|
||||
GetGLFormatName( formats[ fmtIdx ].internal ),
|
||||
GetGLBaseFormatName( formats[ fmtIdx ].format ),
|
||||
GetGLTypeName( formats[ fmtIdx ].datatype ) );
|
||||
|
||||
error++;
|
||||
break; // Skip other sizes for this combination
|
||||
}
|
||||
}
|
||||
if( i == iter )
|
||||
{
|
||||
log_info( "passed: Renderbuffer write test passed for %s : %s : %s : %s\n\n",
|
||||
GetGLAttachmentName( attachments[ attIdx ] ),
|
||||
GetGLFormatName( formats[ fmtIdx ].internal ),
|
||||
GetGLBaseFormatName( formats[ fmtIdx ].format ),
|
||||
GetGLTypeName( formats[ fmtIdx ].datatype ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
133
test_conformance/gl/test_renderbuffer_info.cpp
Normal file
133
test_conformance/gl/test_renderbuffer_info.cpp
Normal file
@@ -0,0 +1,133 @@
|
||||
//
|
||||
// Copyright (c) 2017 The Khronos Group Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
#include "testBase.h"
|
||||
#if defined( __APPLE__ )
|
||||
#include <OpenGL/glu.h>
|
||||
#else
|
||||
#include <GL/glu.h>
|
||||
#include <CL/cl_gl.h>
|
||||
#endif
|
||||
|
||||
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 format, GLenum internalFormat,
|
||||
GLenum glType, ExplicitType type, MTdata d )
|
||||
{
|
||||
int error;
|
||||
|
||||
if( type == kHalf )
|
||||
if( DetectFloatToHalfRoundingMode(queue) )
|
||||
return 1;
|
||||
|
||||
// Create the GL render buffer
|
||||
glFramebufferWrapper glFramebuffer;
|
||||
glRenderbufferWrapper glRenderbuffer;
|
||||
BufferOwningPtr<char> inputBuffer(CreateGLRenderbuffer( width, height, attachment, format, internalFormat, glType, type, &glFramebuffer, &glRenderbuffer, &error, d, true ));
|
||||
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( internalFormat ),
|
||||
get_explicit_type_name( type ), (int)width, (int)height );
|
||||
|
||||
// Verify the expected information here.
|
||||
return CheckGLObjectInfo(image, CL_GL_OBJECT_RENDERBUFFER, (GLuint)glRenderbuffer, internalFormat, 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 internal;
|
||||
GLenum format;
|
||||
GLenum datatype;
|
||||
ExplicitType type;
|
||||
|
||||
} formats[] = {
|
||||
{ GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, kUChar },
|
||||
{ GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, kUChar },
|
||||
{ GL_RGBA16, GL_RGBA, GL_UNSIGNED_SHORT, kUShort },
|
||||
{ GL_RGBA32F_ARB, GL_RGBA, GL_FLOAT, kFloat },
|
||||
{ GL_RGBA16F_ARB, GL_RGBA, GL_HALF_FLOAT, kHalf }
|
||||
};
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
if( !gluCheckExtension( (const GLubyte *)"GL_EXT_framebuffer_object", glGetString( GL_EXTENSIONS ) ) )
|
||||
{
|
||||
log_info( "Renderbuffers are not supported by this OpenGL implementation; skipping test\n" );
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Loop through a set of GL formats, testing a set of sizes against each one
|
||||
for( fmtIdx = 0; fmtIdx < sizeof( formats ) / sizeof( formats[ 0 ] ); fmtIdx++ )
|
||||
{
|
||||
for( tgtIdx = 0; tgtIdx < sizeof( attachments ) / sizeof( attachments[ 0 ] ); tgtIdx++ )
|
||||
{
|
||||
log_info( "Testing Renderbuffer object info for %s : %s : %s\n",
|
||||
GetGLFormatName( formats[ fmtIdx ].internal ),
|
||||
GetGLBaseFormatName( formats[ fmtIdx ].format ),
|
||||
GetGLTypeName( formats[ fmtIdx ].datatype ) );
|
||||
|
||||
size_t i;
|
||||
for( i = 0; i < iter; i++ )
|
||||
{
|
||||
GLsizei width = random_in_range( 16, 512, seed );
|
||||
GLsizei height = random_in_range( 16, 512, seed );
|
||||
|
||||
if( test_renderbuffer_object_info( context, queue, (int)width, (int)height,
|
||||
attachments[ tgtIdx ],
|
||||
formats[ fmtIdx ].format,
|
||||
formats[ fmtIdx ].internal,
|
||||
formats[ fmtIdx ].datatype,
|
||||
formats[ fmtIdx ].type, seed ) )
|
||||
{
|
||||
log_error( "ERROR: Renderbuffer write test failed for GL format %s : %s\n\n",
|
||||
GetGLFormatName( formats[ fmtIdx ].internal ),
|
||||
GetGLTypeName( formats[ fmtIdx ].datatype ) );
|
||||
|
||||
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 ].internal ),
|
||||
GetGLTypeName( formats[ fmtIdx ].datatype ) );
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user