Fix clCopyImage 1D buffer images tests with use_pitches flag (#2167)

This change fixes the following issues when running `clCopyImage` test
with `use_pitches` flag for 1D buffer images.

1. Query device CL version using `get_device_cl_version` rather than
using `CL_DEVICE_VERSION`. Previously, using `char` may not be enough to
store the return value.
2. Pass `host_ptr` to `clCreateBuffer` when creating the buffer for the
1D image. `host_ptr` may not be `nullptr` if use_pitches flag is used.
Also, `buffer_flags` will contain `CL_MEM_USE_HOST_PTR` which requires a
host pointer to be passed.
3. Conditionally use the `host_ptr` when calling `clCreateImage`, it
will not be used with 1D image buffer. This is made to align with the
spec, in which if `mem_flags` has `CL_MEM_USE_HOST_PTR` a host pointer
must be present, but if the memory flag is not present, host pointer
must be `nullptr`.
4. Use the correct free function `free` and `align_free` based on the
allocation function that was used.

Signed-off-by: Michael Rizkalla <michael.rizkalla@arm.com>
This commit is contained in:
Michael Rizkalla
2024-12-17 17:53:56 +00:00
committed by GitHub
parent 177be0969b
commit 09e4d03e46

View File

@@ -16,9 +16,24 @@
#include "../testBase.h" #include "../testBase.h"
#include <CL/cl.h> #include <CL/cl.h>
static void CL_CALLBACK free_pitch_buffer( cl_mem image, void *buf ) struct pitch_buffer_data
{ {
free( buf ); void *buf;
bool is_aligned;
};
static void CL_CALLBACK free_pitch_buffer(cl_mem image, void *data)
{
pitch_buffer_data *d = static_cast<pitch_buffer_data *>(data);
if (d->is_aligned)
{
align_free(d->buf);
}
else
{
free(d->buf);
}
free(d);
} }
static void CL_CALLBACK release_cl_buffer(cl_mem image, void *buf) static void CL_CALLBACK release_cl_buffer(cl_mem image, void *buf)
@@ -32,6 +47,7 @@ cl_mem create_image( cl_context context, cl_command_queue queue, BufferOwningPtr
cl_image_desc imageDesc; cl_image_desc imageDesc;
cl_mem_flags mem_flags = CL_MEM_READ_ONLY; cl_mem_flags mem_flags = CL_MEM_READ_ONLY;
void *host_ptr = NULL; void *host_ptr = NULL;
bool is_host_ptr_aligned = false;
memset(&imageDesc, 0x0, sizeof(cl_image_desc)); memset(&imageDesc, 0x0, sizeof(cl_image_desc));
imageDesc.image_type = imageInfo->type; imageDesc.image_type = imageInfo->type;
@@ -43,6 +59,19 @@ cl_mem create_image( cl_context context, cl_command_queue queue, BufferOwningPtr
imageDesc.image_slice_pitch = gEnablePitch ? imageInfo->slicePitch : 0; imageDesc.image_slice_pitch = gEnablePitch ? imageInfo->slicePitch : 0;
imageDesc.num_mip_levels = gTestMipmaps ? imageInfo->num_mip_levels : 0; imageDesc.num_mip_levels = gTestMipmaps ? imageInfo->num_mip_levels : 0;
Version version;
cl_device_id device;
{
cl_int err = clGetCommandQueueInfo(queue, CL_QUEUE_DEVICE,
sizeof(device), &device, nullptr);
if (err != CL_SUCCESS)
{
log_error("Error: Could not get CL_QUEUE_DEVICE from queue");
return nullptr;
}
version = get_device_cl_version(device);
}
switch (imageInfo->type) switch (imageInfo->type)
{ {
case CL_MEM_OBJECT_IMAGE1D: case CL_MEM_OBJECT_IMAGE1D:
@@ -84,27 +113,7 @@ cl_mem create_image( cl_context context, cl_command_queue queue, BufferOwningPtr
cl_mem_flags buffer_flags = CL_MEM_READ_WRITE; cl_mem_flags buffer_flags = CL_MEM_READ_WRITE;
if (gEnablePitch) if (gEnablePitch)
{ {
cl_device_id device; if (version.major() == 1)
err =
clGetCommandQueueInfo(queue, CL_QUEUE_DEVICE,
sizeof(device), &device, nullptr);
if (err != CL_SUCCESS)
{
log_error(
"Error: Could not get CL_QUEUE_DEVICE from queue");
return NULL;
}
char major_version;
err = clGetDeviceInfo(device, CL_DEVICE_VERSION,
sizeof(major_version), &major_version,
nullptr);
if (err != CL_SUCCESS)
{
log_error("Error: Could not get CL_DEVICE_VERSION from "
"device");
return NULL;
}
if (major_version == '1')
{ {
host_ptr = malloc(imageInfo->rowPitch); host_ptr = malloc(imageInfo->rowPitch);
} }
@@ -124,12 +133,13 @@ cl_mem create_image( cl_context context, cl_command_queue queue, BufferOwningPtr
} }
host_ptr = align_malloc(imageInfo->rowPitch, host_ptr = align_malloc(imageInfo->rowPitch,
base_address_alignment); base_address_alignment);
is_host_ptr_aligned = true;
} }
buffer_flags |= CL_MEM_USE_HOST_PTR; buffer_flags |= CL_MEM_USE_HOST_PTR;
} }
cl_mem buffer = clCreateBuffer(context, buffer_flags, cl_mem buffer = clCreateBuffer(
imageInfo->rowPitch, NULL, &err); context, buffer_flags, imageInfo->rowPitch, host_ptr, &err);
if (err != CL_SUCCESS) if (err != CL_SUCCESS)
{ {
log_error("ERROR: Could not create buffer for 1D buffer " log_error("ERROR: Could not create buffer for 1D buffer "
@@ -160,23 +170,39 @@ cl_mem create_image( cl_context context, cl_command_queue queue, BufferOwningPtr
} }
} }
img = clCreateImage(context, mem_flags, imageInfo->format, &imageDesc, host_ptr, error); if (imageInfo->type != CL_MEM_OBJECT_IMAGE1D_BUFFER)
{
img = clCreateImage(context, mem_flags, imageInfo->format, &imageDesc,
host_ptr, error);
}
else
{
img = clCreateImage(context, mem_flags, imageInfo->format, &imageDesc,
nullptr, error);
}
if (gEnablePitch) if (gEnablePitch)
{ {
pitch_buffer_data *data =
static_cast<pitch_buffer_data *>(malloc(sizeof(pitch_buffer_data)));
data->buf = host_ptr;
data->is_aligned = is_host_ptr_aligned;
if ( *error == CL_SUCCESS ) if ( *error == CL_SUCCESS )
{ {
int callbackError = clSetMemObjectDestructorCallback( img, free_pitch_buffer, host_ptr ); int callbackError =
clSetMemObjectDestructorCallback(img, free_pitch_buffer, data);
if ( CL_SUCCESS != callbackError ) if ( CL_SUCCESS != callbackError )
{ {
free( host_ptr ); free_pitch_buffer(img, data);
log_error( "ERROR: Unable to attach destructor callback to pitched 3D image. Err: %d\n", callbackError ); log_error( "ERROR: Unable to attach destructor callback to pitched 3D image. Err: %d\n", callbackError );
clReleaseMemObject( img ); clReleaseMemObject( img );
return NULL; return NULL;
} }
} }
else else
free(host_ptr); {
free_pitch_buffer(img, data);
}
} }
if (imageDesc.buffer != NULL) if (imageDesc.buffer != NULL)