blob: ccfeaafa1380afec85219a9105a7dbe5b22c9857 [file] [log] [blame]
//
// 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 "harness/typeWrappers.h"
#include "harness/testHarness.h"
#define TEST_MEM_OBJECT_PARAM( mem, paramName, val, expected, name, type, cast ) \
error = clGetMemObjectInfo( mem, paramName, sizeof( val ), &val, &size ); \
test_error( error, "Unable to get mem object " name ); \
if( val != expected ) \
{ \
log_error( "ERROR: Mem object " name " did not validate! (expected " type ", got " type " from %s:%d)\n", \
expected, (cast)val, __FILE__, __LINE__ ); \
return -1; \
} \
if( size != sizeof( val ) ) \
{ \
log_error( "ERROR: Returned size of mem object " name " does not validate! (expected %d, got %d from %s:%d)\n", \
(int)sizeof( val ), (int)size , __FILE__, __LINE__ ); \
return -1; \
}
static void CL_CALLBACK mem_obj_destructor_callback( cl_mem, void * data )
{
free( data );
}
static unsigned int
get_image_dim(MTdata *d, unsigned int mod)
{
unsigned int val = 0;
do
{
val = (unsigned int)genrand_int32(*d) % mod;
} while (val == 0);
return val;
}
int test_get_buffer_info( cl_device_id deviceID, cl_context context, cl_command_queue ignoreQueue, int num_elements )
{
int error;
size_t size;
void * buffer = NULL;
clMemWrapper bufferObject;
clMemWrapper subBufferObject;
cl_mem_flags bufferFlags[] = {
CL_MEM_READ_WRITE,
CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR,
CL_MEM_READ_WRITE | CL_MEM_ALLOC_HOST_PTR,
CL_MEM_READ_WRITE | CL_MEM_ALLOC_HOST_PTR | CL_MEM_COPY_HOST_PTR,
CL_MEM_READ_WRITE | CL_MEM_USE_HOST_PTR,
CL_MEM_READ_ONLY,
CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR,
CL_MEM_READ_ONLY | CL_MEM_ALLOC_HOST_PTR,
CL_MEM_READ_ONLY | CL_MEM_ALLOC_HOST_PTR | CL_MEM_COPY_HOST_PTR,
CL_MEM_READ_ONLY | CL_MEM_USE_HOST_PTR,
CL_MEM_WRITE_ONLY,
CL_MEM_WRITE_ONLY | CL_MEM_COPY_HOST_PTR,
CL_MEM_WRITE_ONLY | CL_MEM_ALLOC_HOST_PTR,
CL_MEM_WRITE_ONLY | CL_MEM_ALLOC_HOST_PTR | CL_MEM_COPY_HOST_PTR,
CL_MEM_WRITE_ONLY | CL_MEM_USE_HOST_PTR,
CL_MEM_HOST_READ_ONLY | CL_MEM_READ_WRITE,
CL_MEM_HOST_READ_ONLY | CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR,
CL_MEM_HOST_READ_ONLY | CL_MEM_READ_WRITE | CL_MEM_ALLOC_HOST_PTR,
CL_MEM_HOST_READ_ONLY | CL_MEM_READ_WRITE | CL_MEM_ALLOC_HOST_PTR | CL_MEM_COPY_HOST_PTR,
CL_MEM_HOST_READ_ONLY | CL_MEM_READ_WRITE | CL_MEM_USE_HOST_PTR,
CL_MEM_HOST_READ_ONLY | CL_MEM_READ_ONLY,
CL_MEM_HOST_READ_ONLY | CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR,
CL_MEM_HOST_READ_ONLY | CL_MEM_READ_ONLY | CL_MEM_ALLOC_HOST_PTR,
CL_MEM_HOST_READ_ONLY | CL_MEM_READ_ONLY | CL_MEM_ALLOC_HOST_PTR | CL_MEM_COPY_HOST_PTR,
CL_MEM_HOST_READ_ONLY | CL_MEM_READ_ONLY | CL_MEM_USE_HOST_PTR,
CL_MEM_HOST_READ_ONLY | CL_MEM_WRITE_ONLY,
CL_MEM_HOST_READ_ONLY | CL_MEM_WRITE_ONLY | CL_MEM_COPY_HOST_PTR,
CL_MEM_HOST_READ_ONLY | CL_MEM_WRITE_ONLY | CL_MEM_ALLOC_HOST_PTR,
CL_MEM_HOST_READ_ONLY | CL_MEM_WRITE_ONLY | CL_MEM_ALLOC_HOST_PTR | CL_MEM_COPY_HOST_PTR,
CL_MEM_HOST_READ_ONLY | CL_MEM_WRITE_ONLY | CL_MEM_USE_HOST_PTR,
CL_MEM_HOST_WRITE_ONLY | CL_MEM_READ_WRITE,
CL_MEM_HOST_WRITE_ONLY | CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR,
CL_MEM_HOST_WRITE_ONLY | CL_MEM_READ_WRITE | CL_MEM_ALLOC_HOST_PTR,
CL_MEM_HOST_WRITE_ONLY | CL_MEM_READ_WRITE | CL_MEM_ALLOC_HOST_PTR | CL_MEM_COPY_HOST_PTR,
CL_MEM_HOST_WRITE_ONLY | CL_MEM_READ_WRITE | CL_MEM_USE_HOST_PTR,
CL_MEM_HOST_WRITE_ONLY | CL_MEM_READ_ONLY,
CL_MEM_HOST_WRITE_ONLY | CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR,
CL_MEM_HOST_WRITE_ONLY | CL_MEM_READ_ONLY | CL_MEM_ALLOC_HOST_PTR,
CL_MEM_HOST_WRITE_ONLY | CL_MEM_READ_ONLY | CL_MEM_ALLOC_HOST_PTR | CL_MEM_COPY_HOST_PTR,
CL_MEM_HOST_WRITE_ONLY | CL_MEM_READ_ONLY | CL_MEM_USE_HOST_PTR,
CL_MEM_HOST_WRITE_ONLY | CL_MEM_WRITE_ONLY,
CL_MEM_HOST_WRITE_ONLY | CL_MEM_WRITE_ONLY | CL_MEM_COPY_HOST_PTR,
CL_MEM_HOST_WRITE_ONLY | CL_MEM_WRITE_ONLY | CL_MEM_ALLOC_HOST_PTR,
CL_MEM_HOST_WRITE_ONLY | CL_MEM_WRITE_ONLY | CL_MEM_ALLOC_HOST_PTR | CL_MEM_COPY_HOST_PTR,
CL_MEM_HOST_WRITE_ONLY | CL_MEM_WRITE_ONLY | CL_MEM_USE_HOST_PTR,
CL_MEM_HOST_NO_ACCESS | CL_MEM_READ_WRITE,
CL_MEM_HOST_NO_ACCESS | CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR,
CL_MEM_HOST_NO_ACCESS | CL_MEM_READ_WRITE | CL_MEM_ALLOC_HOST_PTR,
CL_MEM_HOST_NO_ACCESS | CL_MEM_READ_WRITE | CL_MEM_ALLOC_HOST_PTR | CL_MEM_COPY_HOST_PTR,
CL_MEM_HOST_NO_ACCESS | CL_MEM_READ_WRITE | CL_MEM_USE_HOST_PTR,
CL_MEM_HOST_NO_ACCESS | CL_MEM_READ_ONLY,
CL_MEM_HOST_NO_ACCESS | CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR,
CL_MEM_HOST_NO_ACCESS | CL_MEM_READ_ONLY | CL_MEM_ALLOC_HOST_PTR,
CL_MEM_HOST_NO_ACCESS | CL_MEM_READ_ONLY | CL_MEM_ALLOC_HOST_PTR | CL_MEM_COPY_HOST_PTR,
CL_MEM_HOST_NO_ACCESS | CL_MEM_READ_ONLY | CL_MEM_USE_HOST_PTR,
CL_MEM_HOST_NO_ACCESS | CL_MEM_WRITE_ONLY,
CL_MEM_HOST_NO_ACCESS | CL_MEM_WRITE_ONLY | CL_MEM_COPY_HOST_PTR,
CL_MEM_HOST_NO_ACCESS | CL_MEM_WRITE_ONLY | CL_MEM_ALLOC_HOST_PTR,
CL_MEM_HOST_NO_ACCESS | CL_MEM_WRITE_ONLY | CL_MEM_ALLOC_HOST_PTR | CL_MEM_COPY_HOST_PTR,
CL_MEM_HOST_NO_ACCESS | CL_MEM_WRITE_ONLY | CL_MEM_USE_HOST_PTR,
};
cl_mem_flags subBufferFlags[] = {
CL_MEM_READ_WRITE,
CL_MEM_READ_ONLY,
CL_MEM_WRITE_ONLY,
0,
CL_MEM_HOST_READ_ONLY | CL_MEM_READ_WRITE,
CL_MEM_HOST_READ_ONLY | CL_MEM_READ_ONLY,
CL_MEM_HOST_READ_ONLY | CL_MEM_WRITE_ONLY,
CL_MEM_HOST_READ_ONLY | 0,
CL_MEM_HOST_WRITE_ONLY | CL_MEM_READ_WRITE,
CL_MEM_HOST_WRITE_ONLY | CL_MEM_READ_ONLY,
CL_MEM_HOST_WRITE_ONLY | CL_MEM_WRITE_ONLY,
CL_MEM_HOST_WRITE_ONLY | 0,
CL_MEM_HOST_NO_ACCESS | CL_MEM_READ_WRITE,
CL_MEM_HOST_NO_ACCESS | CL_MEM_READ_ONLY,
CL_MEM_HOST_NO_ACCESS | CL_MEM_WRITE_ONLY,
CL_MEM_HOST_NO_ACCESS | 0,
};
// Get the address alignment, so we can make sure the sub-buffer test later works properly.
cl_uint addressAlignBits;
error = clGetDeviceInfo( deviceID, CL_DEVICE_MEM_BASE_ADDR_ALIGN, sizeof(addressAlignBits), &addressAlignBits, NULL );
size_t addressAlign = addressAlignBits/8;
if ( addressAlign < 128 )
{
addressAlign = 128;
}
for ( unsigned int i = 0; i < sizeof(bufferFlags) / sizeof(cl_mem_flags); ++i )
{
//printf("@@@ bufferFlags[%u]=0x%x\n", i, bufferFlags[ i ]);
if ( bufferFlags[ i ] & CL_MEM_USE_HOST_PTR )
{
// Create a buffer object to test against.
buffer = malloc( addressAlign * 4 );
bufferObject = clCreateBuffer( context, bufferFlags[ i ], addressAlign * 4, buffer, &error );
if ( error )
{
free( buffer );
test_error( error, "Unable to create buffer (CL_MEM_USE_HOST_PTR) to test with" );
}
// Make sure buffer is cleaned up appropriately if we encounter an error in the rest of the calls.
error = clSetMemObjectDestructorCallback( bufferObject, mem_obj_destructor_callback, buffer );
test_error( error, "Unable to set mem object destructor callback" );
void * ptr;
TEST_MEM_OBJECT_PARAM( bufferObject, CL_MEM_HOST_PTR, ptr, buffer, "host pointer", "%p", void * )
}
else if ( (bufferFlags[ i ] & CL_MEM_ALLOC_HOST_PTR) && (bufferFlags[ i ] & CL_MEM_COPY_HOST_PTR) )
{
// Create a buffer object to test against.
buffer = malloc( addressAlign * 4 );
bufferObject = clCreateBuffer( context, bufferFlags[ i ], addressAlign * 4, buffer, &error );
if ( error )
{
free( buffer );
test_error( error, "Unable to create buffer (CL_MEM_ALLOC_HOST_PTR | CL_MEM_COPY_HOST_PTR) to test with" );
}
// Make sure buffer is cleaned up appropriately if we encounter an error in the rest of the calls.
error = clSetMemObjectDestructorCallback( bufferObject, mem_obj_destructor_callback, buffer );
test_error( error, "Unable to set mem object destructor callback" );
}
else if ( bufferFlags[ i ] & CL_MEM_ALLOC_HOST_PTR )
{
// Create a buffer object to test against.
bufferObject = clCreateBuffer( context, bufferFlags[ i ], addressAlign * 4, NULL, &error );
test_error( error, "Unable to create buffer (CL_MEM_ALLOC_HOST_PTR) to test with" );
}
else if ( bufferFlags[ i ] & CL_MEM_COPY_HOST_PTR )
{
// Create a buffer object to test against.
buffer = malloc( addressAlign * 4 );
bufferObject = clCreateBuffer( context, bufferFlags[ i ], addressAlign * 4, buffer, &error );
if ( error )
{
free( buffer );
test_error( error, "Unable to create buffer (CL_MEM_COPY_HOST_PTR) to test with" );
}
// Make sure buffer is cleaned up appropriately if we encounter an error in the rest of the calls.
error = clSetMemObjectDestructorCallback( bufferObject, mem_obj_destructor_callback, buffer );
test_error( error, "Unable to set mem object destructor callback" );
}
else
{
// Create a buffer object to test against.
bufferObject = clCreateBuffer( context, bufferFlags[ i ], addressAlign * 4, NULL, &error );
test_error( error, "Unable to create buffer to test with" );
}
// Perform buffer object queries.
cl_mem_object_type type;
TEST_MEM_OBJECT_PARAM( bufferObject, CL_MEM_TYPE, type, CL_MEM_OBJECT_BUFFER, "type", "%d", int )
cl_mem_flags flags;
TEST_MEM_OBJECT_PARAM( bufferObject, CL_MEM_FLAGS, flags, (unsigned int)bufferFlags[ i ], "flags", "%d", unsigned int )
size_t sz;
TEST_MEM_OBJECT_PARAM( bufferObject, CL_MEM_SIZE, sz, (size_t)( addressAlign * 4 ), "size", "%ld", size_t )
cl_uint mapCount;
error = clGetMemObjectInfo( bufferObject, CL_MEM_MAP_COUNT, sizeof( mapCount ), &mapCount, &size );
test_error( error, "Unable to get mem object map count" );
if( size != sizeof( mapCount ) )
{
log_error( "ERROR: Returned size of mem object map count does not validate! (expected %d, got %d from %s:%d)\n",
(int)sizeof( mapCount ), (int)size, __FILE__, __LINE__ );
return -1;
}
cl_uint refCount;
error = clGetMemObjectInfo( bufferObject, CL_MEM_REFERENCE_COUNT, sizeof( refCount ), &refCount, &size );
test_error( error, "Unable to get mem object reference count" );
if( size != sizeof( refCount ) )
{
log_error( "ERROR: Returned size of mem object reference count does not validate! (expected %d, got %d from %s:%d)\n",
(int)sizeof( refCount ), (int)size, __FILE__, __LINE__ );
return -1;
}
cl_context otherCtx;
TEST_MEM_OBJECT_PARAM( bufferObject, CL_MEM_CONTEXT, otherCtx, context, "context", "%p", cl_context )
cl_mem origObj;
TEST_MEM_OBJECT_PARAM( bufferObject, CL_MEM_ASSOCIATED_MEMOBJECT, origObj, (void *)NULL, "associated mem object", "%p", void * )
size_t offset;
TEST_MEM_OBJECT_PARAM( bufferObject, CL_MEM_OFFSET, offset, 0L, "offset", "%ld", size_t )
cl_buffer_region region;
region.origin = addressAlign;
region.size = addressAlign;
// Loop over possible sub-buffer objects to create.
for ( unsigned int j = 0; j < sizeof(subBufferFlags) / sizeof(cl_mem_flags); ++j )
{
if ( subBufferFlags[ j ] & CL_MEM_READ_WRITE )
{
if ( !(bufferFlags[ i ] & CL_MEM_READ_WRITE) )
continue; // Buffer must be read_write for sub-buffer to be read_write.
}
if ( subBufferFlags[ j ] & CL_MEM_READ_ONLY )
{
if ( !(bufferFlags[ i ] & CL_MEM_READ_WRITE) && !(bufferFlags[ i ] & CL_MEM_READ_ONLY) )
continue; // Buffer must be read_write or read_only for sub-buffer to be read_only
}
if ( subBufferFlags[ j ] & CL_MEM_WRITE_ONLY )
{
if ( !(bufferFlags[ i ] & CL_MEM_READ_WRITE) && !(bufferFlags[ i ] & CL_MEM_WRITE_ONLY) )
continue; // Buffer must be read_write or write_only for sub-buffer to be write_only
}
if ( subBufferFlags[ j ] & CL_MEM_HOST_READ_ONLY )
{
if ( (bufferFlags[ i ] & CL_MEM_HOST_NO_ACCESS) || (bufferFlags[ i ] & CL_MEM_HOST_WRITE_ONLY) )
continue; // Buffer must be host all access or host read_only for sub-buffer to be host read_only
}
if ( subBufferFlags[ j ] & CL_MEM_HOST_WRITE_ONLY )
{
if ( (bufferFlags[ i ] & CL_MEM_HOST_NO_ACCESS) || (bufferFlags[ i ] & CL_MEM_HOST_READ_ONLY) )
continue; // Buffer must be host all access or host write_only for sub-buffer to be host write_only
}
//printf("@@@ bufferFlags[%u]=0x%x subBufferFlags[%u]=0x%x\n", i, bufferFlags[ i ], j, subBufferFlags[ j ]);
subBufferObject = clCreateSubBuffer( bufferObject, subBufferFlags[ j ], CL_BUFFER_CREATE_TYPE_REGION, &region, &error );
test_error( error, "Unable to create sub-buffer to test against" );
// Perform sub-buffer object queries.
cl_mem_object_type type;
TEST_MEM_OBJECT_PARAM( subBufferObject, CL_MEM_TYPE, type, CL_MEM_OBJECT_BUFFER, "type", "%d", int )
cl_mem_flags flags;
cl_mem_flags inheritedFlags = subBufferFlags[ j ];
if ( (subBufferFlags[ j ] & (CL_MEM_READ_WRITE | CL_MEM_READ_ONLY | CL_MEM_WRITE_ONLY)) == 0 )
{
inheritedFlags |= bufferFlags[ i ] & (CL_MEM_READ_WRITE | CL_MEM_READ_ONLY | CL_MEM_WRITE_ONLY);
}
inheritedFlags |= bufferFlags[ i ] & (CL_MEM_ALLOC_HOST_PTR | CL_MEM_COPY_HOST_PTR | CL_MEM_USE_HOST_PTR);
if ( (subBufferFlags[ j ] & (CL_MEM_HOST_READ_ONLY | CL_MEM_HOST_WRITE_ONLY | CL_MEM_HOST_NO_ACCESS)) == 0)
{
inheritedFlags |= bufferFlags[ i ] & (CL_MEM_HOST_READ_ONLY | CL_MEM_HOST_WRITE_ONLY | CL_MEM_HOST_NO_ACCESS);
}
TEST_MEM_OBJECT_PARAM( subBufferObject, CL_MEM_FLAGS, flags, (unsigned int)inheritedFlags, "flags", "%d", unsigned int )
TEST_MEM_OBJECT_PARAM( subBufferObject, CL_MEM_SIZE, sz, (size_t)( addressAlign ), "size", "%ld", size_t )
if ( bufferFlags[ i ] & CL_MEM_USE_HOST_PTR )
{
void * ptr;
void * offsetInBuffer = (char *)buffer + addressAlign;
TEST_MEM_OBJECT_PARAM( subBufferObject, CL_MEM_HOST_PTR, ptr, offsetInBuffer, "host pointer", "%p", void * )
}
cl_uint mapCount;
error = clGetMemObjectInfo( subBufferObject, CL_MEM_MAP_COUNT, sizeof( mapCount ), &mapCount, &size );
test_error( error, "Unable to get mem object map count" );
if( size != sizeof( mapCount ) )
{
log_error( "ERROR: Returned size of mem object map count does not validate! (expected %d, got %d from %s:%d)\n",
(int)sizeof( mapCount ), (int)size, __FILE__, __LINE__ );
return -1;
}
cl_uint refCount;
error = clGetMemObjectInfo( subBufferObject, CL_MEM_REFERENCE_COUNT, sizeof( refCount ), &refCount, &size );
test_error( error, "Unable to get mem object reference count" );
if( size != sizeof( refCount ) )
{
log_error( "ERROR: Returned size of mem object reference count does not validate! (expected %d, got %d from %s:%d)\n",
(int)sizeof( refCount ), (int)size, __FILE__, __LINE__ );
return -1;
}
cl_context otherCtx;
TEST_MEM_OBJECT_PARAM( subBufferObject, CL_MEM_CONTEXT, otherCtx, context, "context", "%p", cl_context )
TEST_MEM_OBJECT_PARAM( subBufferObject, CL_MEM_ASSOCIATED_MEMOBJECT, origObj, (cl_mem)bufferObject, "associated mem object", "%p", void * )
TEST_MEM_OBJECT_PARAM( subBufferObject, CL_MEM_OFFSET, offset, (size_t)( addressAlign ), "offset", "%ld", size_t )
clReleaseMemObject( subBufferObject );
subBufferObject = NULL;
}
clReleaseMemObject( bufferObject );
bufferObject = NULL;
}
return CL_SUCCESS;
}
int test_get_imageObject_info( cl_mem * image, cl_mem_flags objectFlags, cl_image_desc *imageInfo, cl_image_format *imageFormat, size_t pixelSize, cl_context context )
{
int error;
size_t size;
cl_mem_object_type type;
cl_mem_flags flags;
cl_uint mapCount;
cl_uint refCount;
size_t rowPitchMultiplier;
size_t slicePitchMultiplier;
cl_context otherCtx;
size_t offset;
size_t sz;
TEST_MEM_OBJECT_PARAM( *image, CL_MEM_TYPE, type, imageInfo->image_type, "type", "%d", int )
TEST_MEM_OBJECT_PARAM( *image, CL_MEM_FLAGS, flags, (unsigned int)objectFlags, "flags", "%d", unsigned int )
error = clGetMemObjectInfo( *image, CL_MEM_SIZE, sizeof( sz ), &sz, NULL );
test_error( error, "Unable to get mem size" );
// The size returned is not constrained by the spec.
error = clGetMemObjectInfo( *image, CL_MEM_MAP_COUNT, sizeof( mapCount ), &mapCount, &size );
test_error( error, "Unable to get mem object map count" );
if( size != sizeof( mapCount ) )
{
log_error( "ERROR: Returned size of mem object map count does not validate! (expected %d, got %d from %s:%d)\n",
(int)sizeof( mapCount ), (int)size, __FILE__, __LINE__ );
return -1;
}
error = clGetMemObjectInfo( *image, CL_MEM_REFERENCE_COUNT, sizeof( refCount ), &refCount, &size );
test_error( error, "Unable to get mem object reference count" );
if( size != sizeof( refCount ) )
{
log_error( "ERROR: Returned size of mem object reference count does not validate! (expected %d, got %d from %s:%d)\n",
(int)sizeof( refCount ), (int)size, __FILE__, __LINE__ );
return -1;
}
TEST_MEM_OBJECT_PARAM( *image, CL_MEM_CONTEXT, otherCtx, context, "context", "%p", cl_context )
TEST_MEM_OBJECT_PARAM( *image, CL_MEM_OFFSET, offset, 0L, "offset", "%ld", size_t )
return CL_SUCCESS;
}
int test_get_image_info( cl_device_id deviceID, cl_context context, cl_mem_object_type type )
{
int error;
size_t size;
void * image = NULL;
cl_mem imageObject;
cl_image_desc imageInfo;
cl_mem_flags imageFlags[] = {
CL_MEM_READ_WRITE,
CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR,
CL_MEM_READ_WRITE | CL_MEM_ALLOC_HOST_PTR,
CL_MEM_READ_WRITE | CL_MEM_ALLOC_HOST_PTR | CL_MEM_COPY_HOST_PTR,
CL_MEM_READ_WRITE | CL_MEM_USE_HOST_PTR,
CL_MEM_READ_ONLY,
CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR,
CL_MEM_READ_ONLY | CL_MEM_ALLOC_HOST_PTR,
CL_MEM_READ_ONLY | CL_MEM_ALLOC_HOST_PTR | CL_MEM_COPY_HOST_PTR,
CL_MEM_READ_ONLY | CL_MEM_USE_HOST_PTR,
CL_MEM_WRITE_ONLY,
CL_MEM_WRITE_ONLY | CL_MEM_COPY_HOST_PTR,
CL_MEM_WRITE_ONLY | CL_MEM_ALLOC_HOST_PTR,
CL_MEM_WRITE_ONLY | CL_MEM_ALLOC_HOST_PTR | CL_MEM_COPY_HOST_PTR,
CL_MEM_WRITE_ONLY | CL_MEM_USE_HOST_PTR,
CL_MEM_HOST_READ_ONLY | CL_MEM_READ_WRITE,
CL_MEM_HOST_READ_ONLY | CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR,
CL_MEM_HOST_READ_ONLY | CL_MEM_READ_WRITE | CL_MEM_ALLOC_HOST_PTR,
CL_MEM_HOST_READ_ONLY | CL_MEM_READ_WRITE | CL_MEM_ALLOC_HOST_PTR | CL_MEM_COPY_HOST_PTR,
CL_MEM_HOST_READ_ONLY | CL_MEM_READ_WRITE | CL_MEM_USE_HOST_PTR,
CL_MEM_HOST_READ_ONLY | CL_MEM_READ_ONLY,
CL_MEM_HOST_READ_ONLY | CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR,
CL_MEM_HOST_READ_ONLY | CL_MEM_READ_ONLY | CL_MEM_ALLOC_HOST_PTR,
CL_MEM_HOST_READ_ONLY | CL_MEM_READ_ONLY | CL_MEM_ALLOC_HOST_PTR | CL_MEM_COPY_HOST_PTR,
CL_MEM_HOST_READ_ONLY | CL_MEM_READ_ONLY | CL_MEM_USE_HOST_PTR,
CL_MEM_HOST_READ_ONLY | CL_MEM_WRITE_ONLY,
CL_MEM_HOST_READ_ONLY | CL_MEM_WRITE_ONLY | CL_MEM_COPY_HOST_PTR,
CL_MEM_HOST_READ_ONLY | CL_MEM_WRITE_ONLY | CL_MEM_ALLOC_HOST_PTR,
CL_MEM_HOST_READ_ONLY | CL_MEM_WRITE_ONLY | CL_MEM_ALLOC_HOST_PTR | CL_MEM_COPY_HOST_PTR,
CL_MEM_HOST_READ_ONLY | CL_MEM_WRITE_ONLY | CL_MEM_USE_HOST_PTR,
CL_MEM_HOST_WRITE_ONLY | CL_MEM_READ_WRITE,
CL_MEM_HOST_WRITE_ONLY | CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR,
CL_MEM_HOST_WRITE_ONLY | CL_MEM_READ_WRITE | CL_MEM_ALLOC_HOST_PTR,
CL_MEM_HOST_WRITE_ONLY | CL_MEM_READ_WRITE | CL_MEM_ALLOC_HOST_PTR | CL_MEM_COPY_HOST_PTR,
CL_MEM_HOST_WRITE_ONLY | CL_MEM_READ_WRITE | CL_MEM_USE_HOST_PTR,
CL_MEM_HOST_WRITE_ONLY | CL_MEM_READ_ONLY,
CL_MEM_HOST_WRITE_ONLY | CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR,
CL_MEM_HOST_WRITE_ONLY | CL_MEM_READ_ONLY | CL_MEM_ALLOC_HOST_PTR,
CL_MEM_HOST_WRITE_ONLY | CL_MEM_READ_ONLY | CL_MEM_ALLOC_HOST_PTR | CL_MEM_COPY_HOST_PTR,
CL_MEM_HOST_WRITE_ONLY | CL_MEM_READ_ONLY | CL_MEM_USE_HOST_PTR,
CL_MEM_HOST_WRITE_ONLY | CL_MEM_WRITE_ONLY,
CL_MEM_HOST_WRITE_ONLY | CL_MEM_WRITE_ONLY | CL_MEM_COPY_HOST_PTR,
CL_MEM_HOST_WRITE_ONLY | CL_MEM_WRITE_ONLY | CL_MEM_ALLOC_HOST_PTR,
CL_MEM_HOST_WRITE_ONLY | CL_MEM_WRITE_ONLY | CL_MEM_ALLOC_HOST_PTR | CL_MEM_COPY_HOST_PTR,
CL_MEM_HOST_WRITE_ONLY | CL_MEM_WRITE_ONLY | CL_MEM_USE_HOST_PTR,
CL_MEM_HOST_NO_ACCESS | CL_MEM_READ_WRITE,
CL_MEM_HOST_NO_ACCESS | CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR,
CL_MEM_HOST_NO_ACCESS | CL_MEM_READ_WRITE | CL_MEM_ALLOC_HOST_PTR,
CL_MEM_HOST_NO_ACCESS | CL_MEM_READ_WRITE | CL_MEM_ALLOC_HOST_PTR | CL_MEM_COPY_HOST_PTR,
CL_MEM_HOST_NO_ACCESS | CL_MEM_READ_WRITE | CL_MEM_USE_HOST_PTR,
CL_MEM_HOST_NO_ACCESS | CL_MEM_READ_ONLY,
CL_MEM_HOST_NO_ACCESS | CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR,
CL_MEM_HOST_NO_ACCESS | CL_MEM_READ_ONLY | CL_MEM_ALLOC_HOST_PTR,
CL_MEM_HOST_NO_ACCESS | CL_MEM_READ_ONLY | CL_MEM_ALLOC_HOST_PTR | CL_MEM_COPY_HOST_PTR,
CL_MEM_HOST_NO_ACCESS | CL_MEM_READ_ONLY | CL_MEM_USE_HOST_PTR,
CL_MEM_HOST_NO_ACCESS | CL_MEM_WRITE_ONLY,
CL_MEM_HOST_NO_ACCESS | CL_MEM_WRITE_ONLY | CL_MEM_COPY_HOST_PTR,
CL_MEM_HOST_NO_ACCESS | CL_MEM_WRITE_ONLY | CL_MEM_ALLOC_HOST_PTR,
CL_MEM_HOST_NO_ACCESS | CL_MEM_WRITE_ONLY | CL_MEM_ALLOC_HOST_PTR | CL_MEM_COPY_HOST_PTR,
CL_MEM_HOST_NO_ACCESS | CL_MEM_WRITE_ONLY | CL_MEM_USE_HOST_PTR,
};
MTdata d;
PASSIVE_REQUIRE_IMAGE_SUPPORT( deviceID )
cl_image_format imageFormat;
size_t pixelSize = 4;
imageFormat.image_channel_order = CL_RGBA;
imageFormat.image_channel_data_type = CL_UNORM_INT8;
imageInfo.image_width = imageInfo.image_height = imageInfo.image_depth = 1;
imageInfo.image_array_size = 0;
imageInfo.num_mip_levels = imageInfo.num_samples = 0;
#ifdef CL_VERSION_2_0
imageInfo.mem_object = NULL;
#else
imageInfo.buffer = NULL;
#endif
d = init_genrand( gRandomSeed );
for ( unsigned int i = 0; i < sizeof(imageFlags) / sizeof(cl_mem_flags); ++i )
{
imageInfo.image_row_pitch = 0;
imageInfo.image_slice_pitch = 0;
switch (type)
{
case CL_MEM_OBJECT_IMAGE1D:
imageInfo.image_width = get_image_dim(&d, 1023);
imageInfo.image_type = CL_MEM_OBJECT_IMAGE1D;
break;
case CL_MEM_OBJECT_IMAGE2D:
imageInfo.image_width = get_image_dim(&d, 1023);
imageInfo.image_height = get_image_dim(&d, 1023);
imageInfo.image_type = CL_MEM_OBJECT_IMAGE2D;
break;
case CL_MEM_OBJECT_IMAGE3D:
error = checkFor3DImageSupport(deviceID);
if (error == CL_IMAGE_FORMAT_NOT_SUPPORTED)
{
log_info("Device doesn't support 3D images. Skipping test.\n");
return CL_SUCCESS;
}
imageInfo.image_width = get_image_dim(&d, 127);
imageInfo.image_height = get_image_dim(&d, 127);
imageInfo.image_depth = get_image_dim(&d, 127);
imageInfo.image_type = CL_MEM_OBJECT_IMAGE3D;
break;
case CL_MEM_OBJECT_IMAGE1D_ARRAY:
imageInfo.image_width = get_image_dim(&d, 1023);
imageInfo.image_array_size = get_image_dim(&d, 1023);
imageInfo.image_type = CL_MEM_OBJECT_IMAGE1D_ARRAY;
break;
case CL_MEM_OBJECT_IMAGE2D_ARRAY:
imageInfo.image_width = get_image_dim(&d, 255);
imageInfo.image_height = get_image_dim(&d, 255);
imageInfo.image_array_size = get_image_dim(&d, 255);
imageInfo.image_type = CL_MEM_OBJECT_IMAGE2D_ARRAY;
break;
}
if ( imageFlags[i] & CL_MEM_USE_HOST_PTR )
{
// Create an image object to test against.
image = malloc( imageInfo.image_width * imageInfo.image_height * imageInfo.image_depth * pixelSize *
((imageInfo.image_array_size == 0) ? 1 : imageInfo.image_array_size) );
imageObject = clCreateImage( context, imageFlags[i], &imageFormat, &imageInfo, image, &error );
if ( error )
{
free( image );
test_error( error, "Unable to create image with (CL_MEM_USE_HOST_PTR) to test with" );
}
// Make sure image is cleaned up appropriately if we encounter an error in the rest of the calls.
error = clSetMemObjectDestructorCallback( imageObject, mem_obj_destructor_callback, image );
test_error( error, "Unable to set mem object destructor callback" );
void * ptr;
TEST_MEM_OBJECT_PARAM( imageObject, CL_MEM_HOST_PTR, ptr, image, "host pointer", "%p", void * )
int ret = test_get_imageObject_info( &imageObject, imageFlags[i], &imageInfo, &imageFormat, pixelSize, context );
if (ret)
return ret;
// release image object
clReleaseMemObject(imageObject);
// Try again with non-zero rowPitch.
imageInfo.image_row_pitch = imageInfo.image_width * pixelSize;
switch (type)
{
case CL_MEM_OBJECT_IMAGE1D_ARRAY:
case CL_MEM_OBJECT_IMAGE2D_ARRAY:
case CL_MEM_OBJECT_IMAGE3D:
imageInfo.image_slice_pitch = imageInfo.image_row_pitch * imageInfo.image_height;
break;
}
image = malloc( imageInfo.image_width * imageInfo.image_height * imageInfo.image_depth * pixelSize *
((imageInfo.image_array_size == 0) ? 1 : imageInfo.image_array_size) );
imageObject = clCreateImage( context, imageFlags[i], &imageFormat, &imageInfo, image, &error );
if ( error )
{
free( image );
test_error( error, "Unable to create image2d (CL_MEM_USE_HOST_PTR) to test with" );
}
// Make sure image2d is cleaned up appropriately if we encounter an error in the rest of the calls.
error = clSetMemObjectDestructorCallback( imageObject, mem_obj_destructor_callback, image );
test_error( error, "Unable to set mem object destructor callback" );
TEST_MEM_OBJECT_PARAM( imageObject, CL_MEM_HOST_PTR, ptr, image, "host pointer", "%p", void * )
ret = test_get_imageObject_info( &imageObject, imageFlags[i], &imageInfo, &imageFormat, pixelSize, context );
if (ret)
return ret;
}
else if ( (imageFlags[i] & CL_MEM_ALLOC_HOST_PTR) && (imageFlags[i] & CL_MEM_COPY_HOST_PTR) )
{
// Create an image object to test against.
image = malloc( imageInfo.image_width * imageInfo.image_height * imageInfo.image_depth * pixelSize *
((imageInfo.image_array_size == 0) ? 1 : imageInfo.image_array_size) );
imageObject = clCreateImage( context, imageFlags[i], &imageFormat, &imageInfo, image, &error );
if ( error )
{
free( image );
test_error( error, "Unable to create image with (CL_MEM_ALLOC_HOST_PTR | CL_MEM_COPY_HOST_PTR) to test with" );
}
// Make sure image is cleaned up appropriately if we encounter an error in the rest of the calls.
error = clSetMemObjectDestructorCallback( imageObject, mem_obj_destructor_callback, image );
test_error( error, "Unable to set mem object destructor callback" );
int ret = test_get_imageObject_info( &imageObject, imageFlags[ i ], &imageInfo, &imageFormat, pixelSize, context );
if (ret)
return ret;
// release image object
clReleaseMemObject(imageObject);
// Try again with non-zero rowPitch.
imageInfo.image_row_pitch = imageInfo.image_width * pixelSize;
switch (type)
{
case CL_MEM_OBJECT_IMAGE1D_ARRAY:
case CL_MEM_OBJECT_IMAGE2D_ARRAY:
case CL_MEM_OBJECT_IMAGE3D:
imageInfo.image_slice_pitch = imageInfo.image_row_pitch * imageInfo.image_height;
break;
}
image = malloc( imageInfo.image_width * imageInfo.image_height * imageInfo.image_depth * pixelSize *
((imageInfo.image_array_size == 0) ? 1 : imageInfo.image_array_size) );
imageObject = clCreateImage( context, imageFlags[i], &imageFormat, &imageInfo, image, &error );
if ( error )
{
free( image );
test_error( error, "Unable to create image with (CL_MEM_ALLOC_HOST_PTR | CL_MEM_COPY_HOST_PTR) to test with" );
}
// Make sure image is cleaned up appropriately if we encounter an error in the rest of the calls.
error = clSetMemObjectDestructorCallback( imageObject, mem_obj_destructor_callback, image );
test_error( error, "Unable to set mem object destructor callback" );
ret = test_get_imageObject_info( &imageObject, imageFlags[i], &imageInfo, &imageFormat, pixelSize, context );
if (ret)
return ret;
}
else if ( imageFlags[i] & CL_MEM_ALLOC_HOST_PTR )
{
// Create an image object to test against.
imageObject = clCreateImage( context, imageFlags[i], &imageFormat, &imageInfo, NULL, &error );
test_error( error, "Unable to create image with (CL_MEM_ALLOC_HOST_PTR) to test with" );
int ret = test_get_imageObject_info( &imageObject, imageFlags[i], &imageInfo, &imageFormat, pixelSize, context );
if (ret)
return ret;
}
else if ( imageFlags[i] & CL_MEM_COPY_HOST_PTR )
{
// Create an image object to test against.
image = malloc( imageInfo.image_width * imageInfo.image_height * imageInfo.image_depth * pixelSize *
((imageInfo.image_array_size == 0) ? 1 : imageInfo.image_array_size) );
imageObject = clCreateImage( context, imageFlags[i], &imageFormat, &imageInfo, image, &error );
if ( error )
{
free( image );
test_error( error, "Unable to create image with (CL_MEM_COPY_HOST_PTR) to test with" );
}
// Make sure image is cleaned up appropriately if we encounter an error in the rest of the calls.
error = clSetMemObjectDestructorCallback( imageObject, mem_obj_destructor_callback, image );
test_error( error, "Unable to set mem object destructor callback" );
int ret = test_get_imageObject_info( &imageObject, imageFlags[i], &imageInfo, &imageFormat, pixelSize, context );
if (ret)
return ret;
clReleaseMemObject(imageObject);
// Try again with non-zero rowPitch.
imageInfo.image_row_pitch = imageInfo.image_width * pixelSize;
switch (type)
{
case CL_MEM_OBJECT_IMAGE1D_ARRAY:
case CL_MEM_OBJECT_IMAGE2D_ARRAY:
case CL_MEM_OBJECT_IMAGE3D:
imageInfo.image_slice_pitch = imageInfo.image_row_pitch * imageInfo.image_height;
break;
}
image = malloc( imageInfo.image_width * imageInfo.image_height * imageInfo.image_depth * pixelSize *
((imageInfo.image_array_size == 0) ? 1 : imageInfo.image_array_size) );
imageObject = clCreateImage( context, imageFlags[i], &imageFormat, &imageInfo, image, &error );
if ( error )
{
free( image );
test_error( error, "Unable to create image with (CL_MEM_COPY_HOST_PTR) to test with" );
}
// Make sure image is cleaned up appropriately if we encounter an error in the rest of the calls.
error = clSetMemObjectDestructorCallback( imageObject, mem_obj_destructor_callback, image );
test_error( error, "Unable to set mem object destructor callback" );
ret = test_get_imageObject_info( &imageObject, imageFlags[i], &imageInfo, &imageFormat, pixelSize, context );
if (ret)
return ret;
}
else
{
// Create an image object to test against.
imageObject = clCreateImage( context, imageFlags[i], &imageFormat, &imageInfo, NULL, &error );
test_error( error, "Unable to create image to test with" );
int ret = test_get_imageObject_info( &imageObject, imageFlags[i], &imageInfo, &imageFormat, pixelSize, context );
if (ret)
return ret;
}
clReleaseMemObject( imageObject );
}
return CL_SUCCESS;
}
int test_get_image2d_info( cl_device_id deviceID, cl_context context, cl_command_queue ignoreQueue, int num_elements )
{
return test_get_image_info(deviceID, context, CL_MEM_OBJECT_IMAGE2D);
}
int test_get_image3d_info( cl_device_id deviceID, cl_context context, cl_command_queue ignoreQueue, int num_elements )
{
return test_get_image_info(deviceID, context, CL_MEM_OBJECT_IMAGE3D);
}
int test_get_image1d_info( cl_device_id deviceID, cl_context context, cl_command_queue ignoreQueue, int num_elements )
{
return test_get_image_info(deviceID, context, CL_MEM_OBJECT_IMAGE1D);
}
int test_get_image1d_array_info( cl_device_id deviceID, cl_context context, cl_command_queue ignoreQueue, int num_elements )
{
return test_get_image_info(deviceID, context, CL_MEM_OBJECT_IMAGE1D_ARRAY);
}
int test_get_image2d_array_info( cl_device_id deviceID, cl_context context, cl_command_queue ignoreQueue, int num_elements )
{
return test_get_image_info(deviceID, context, CL_MEM_OBJECT_IMAGE2D_ARRAY);
}