clover: Clean up property query functions by using a new property_buffer helper class.

Tested-by: Tom Stellard <thomas.stellard@amd.com>
This commit is contained in:
Francisco Jerez
2013-10-06 13:49:49 -07:00
parent 7d61769e44
commit d8b4994281
12 changed files with 547 additions and 263 deletions

View File

@@ -33,6 +33,7 @@ CPP_SOURCES := \
core/event.cpp \
core/program.hpp \
core/program.cpp \
core/property.hpp \
core/kernel.hpp \
core/kernel.cpp \
core/module.hpp \

View File

@@ -103,25 +103,35 @@ clReleaseContext(cl_context ctx) {
PUBLIC cl_int
clGetContextInfo(cl_context ctx, cl_context_info param,
size_t size, void *buf, size_t *size_ret) {
size_t size, void *r_buf, size_t *r_size) try {
property_buffer buf { r_buf, size, r_size };
if (!ctx)
return CL_INVALID_CONTEXT;
switch (param) {
case CL_CONTEXT_REFERENCE_COUNT:
return scalar_property<cl_uint>(buf, size, size_ret, ctx->ref_count());
buf.as_scalar<cl_uint>() = ctx->ref_count();
break;
case CL_CONTEXT_NUM_DEVICES:
return scalar_property<cl_uint>(buf, size, size_ret, ctx->devs.size());
buf.as_scalar<cl_uint>() = ctx->devs.size();
break;
case CL_CONTEXT_DEVICES:
return vector_property<cl_device_id>(buf, size, size_ret, ctx->devs);
buf.as_vector<cl_device_id>() = ctx->devs;
break;
case CL_CONTEXT_PROPERTIES:
return vector_property<cl_context_properties>(buf, size, size_ret,
ctx->props());
buf.as_vector<cl_context_properties>() = ctx->props();
break;
default:
return CL_INVALID_VALUE;
throw error(CL_INVALID_VALUE);
}
return CL_SUCCESS;
} catch (error &e) {
return e.get();
}

View File

@@ -60,204 +60,245 @@ clGetDeviceIDs(cl_platform_id platform, cl_device_type device_type,
PUBLIC cl_int
clGetDeviceInfo(cl_device_id dev, cl_device_info param,
size_t size, void *buf, size_t *size_ret) {
size_t size, void *r_buf, size_t *r_size) try {
property_buffer buf { r_buf, size, r_size };
if (!dev)
return CL_INVALID_DEVICE;
switch (param) {
case CL_DEVICE_TYPE:
return scalar_property<cl_device_type>(buf, size, size_ret, dev->type());
buf.as_scalar<cl_device_type>() = dev->type();
break;
case CL_DEVICE_VENDOR_ID:
return scalar_property<cl_uint>(buf, size, size_ret, dev->vendor_id());
buf.as_scalar<cl_uint>() = dev->vendor_id();
break;
case CL_DEVICE_MAX_COMPUTE_UNITS:
return scalar_property<cl_uint>(buf, size, size_ret, 1);
buf.as_scalar<cl_uint>() = 1;
break;
case CL_DEVICE_MAX_WORK_ITEM_DIMENSIONS:
return scalar_property<cl_uint>(buf, size, size_ret,
dev->max_block_size().size());
buf.as_scalar<cl_uint>() = dev->max_block_size().size();
break;
case CL_DEVICE_MAX_WORK_ITEM_SIZES:
return vector_property<size_t>(buf, size, size_ret,
dev->max_block_size());
buf.as_vector<size_t>() = dev->max_block_size();
break;
case CL_DEVICE_MAX_WORK_GROUP_SIZE:
return scalar_property<size_t>(buf, size, size_ret,
dev->max_threads_per_block());
buf.as_scalar<size_t>() = dev->max_threads_per_block();
break;
case CL_DEVICE_PREFERRED_VECTOR_WIDTH_CHAR:
return scalar_property<cl_uint>(buf, size, size_ret, 16);
buf.as_scalar<cl_uint>() = 16;
break;
case CL_DEVICE_PREFERRED_VECTOR_WIDTH_SHORT:
return scalar_property<cl_uint>(buf, size, size_ret, 8);
buf.as_scalar<cl_uint>() = 8;
break;
case CL_DEVICE_PREFERRED_VECTOR_WIDTH_INT:
return scalar_property<cl_uint>(buf, size, size_ret, 4);
buf.as_scalar<cl_uint>() = 4;
break;
case CL_DEVICE_PREFERRED_VECTOR_WIDTH_LONG:
return scalar_property<cl_uint>(buf, size, size_ret, 2);
buf.as_scalar<cl_uint>() = 2;
break;
case CL_DEVICE_PREFERRED_VECTOR_WIDTH_FLOAT:
return scalar_property<cl_uint>(buf, size, size_ret, 4);
buf.as_scalar<cl_uint>() = 4;
break;
case CL_DEVICE_PREFERRED_VECTOR_WIDTH_DOUBLE:
return scalar_property<cl_uint>(buf, size, size_ret, 2);
buf.as_scalar<cl_uint>() = 2;
break;
case CL_DEVICE_PREFERRED_VECTOR_WIDTH_HALF:
return scalar_property<cl_uint>(buf, size, size_ret, 0);
buf.as_scalar<cl_uint>() = 0;
break;
case CL_DEVICE_MAX_CLOCK_FREQUENCY:
return scalar_property<cl_uint>(buf, size, size_ret, 0);
buf.as_scalar<cl_uint>() = 0;
break;
case CL_DEVICE_ADDRESS_BITS:
return scalar_property<cl_uint>(buf, size, size_ret, 32);
buf.as_scalar<cl_uint>() = 32;
break;
case CL_DEVICE_MAX_READ_IMAGE_ARGS:
return scalar_property<cl_uint>(buf, size, size_ret,
dev->max_images_read());
buf.as_scalar<cl_uint>() = dev->max_images_read();
break;
case CL_DEVICE_MAX_WRITE_IMAGE_ARGS:
return scalar_property<cl_uint>(buf, size, size_ret,
dev->max_images_write());
buf.as_scalar<cl_uint>() = dev->max_images_write();
break;
case CL_DEVICE_MAX_MEM_ALLOC_SIZE:
return scalar_property<cl_ulong>(buf, size, size_ret,
dev->max_mem_alloc_size());
buf.as_scalar<cl_ulong>() = dev->max_mem_alloc_size();
break;
case CL_DEVICE_IMAGE2D_MAX_WIDTH:
case CL_DEVICE_IMAGE2D_MAX_HEIGHT:
return scalar_property<size_t>(buf, size, size_ret,
1 << dev->max_image_levels_2d());
buf.as_scalar<size_t>() = 1 << dev->max_image_levels_2d();
break;
case CL_DEVICE_IMAGE3D_MAX_WIDTH:
case CL_DEVICE_IMAGE3D_MAX_HEIGHT:
case CL_DEVICE_IMAGE3D_MAX_DEPTH:
return scalar_property<size_t>(buf, size, size_ret,
1 << dev->max_image_levels_3d());
buf.as_scalar<size_t>() = 1 << dev->max_image_levels_3d();
break;
case CL_DEVICE_IMAGE_SUPPORT:
return scalar_property<cl_bool>(buf, size, size_ret, CL_TRUE);
buf.as_scalar<cl_bool>() = CL_TRUE;
break;
case CL_DEVICE_MAX_PARAMETER_SIZE:
return scalar_property<size_t>(buf, size, size_ret,
dev->max_mem_input());
buf.as_scalar<size_t>() = dev->max_mem_input();
break;
case CL_DEVICE_MAX_SAMPLERS:
return scalar_property<cl_uint>(buf, size, size_ret,
dev->max_samplers());
buf.as_scalar<cl_uint>() = dev->max_samplers();
break;
case CL_DEVICE_MEM_BASE_ADDR_ALIGN:
case CL_DEVICE_MIN_DATA_TYPE_ALIGN_SIZE:
return scalar_property<cl_uint>(buf, size, size_ret, 128);
buf.as_scalar<cl_uint>() = 128;
break;
case CL_DEVICE_SINGLE_FP_CONFIG:
return scalar_property<cl_device_fp_config>(buf, size, size_ret,
CL_FP_DENORM | CL_FP_INF_NAN | CL_FP_ROUND_TO_NEAREST);
buf.as_scalar<cl_device_fp_config>() =
CL_FP_DENORM | CL_FP_INF_NAN | CL_FP_ROUND_TO_NEAREST;
break;
case CL_DEVICE_GLOBAL_MEM_CACHE_TYPE:
return scalar_property<cl_device_mem_cache_type>(buf, size, size_ret,
CL_NONE);
buf.as_scalar<cl_device_mem_cache_type>() = CL_NONE;
break;
case CL_DEVICE_GLOBAL_MEM_CACHELINE_SIZE:
return scalar_property<cl_uint>(buf, size, size_ret, 0);
buf.as_scalar<cl_uint>() = 0;
break;
case CL_DEVICE_GLOBAL_MEM_CACHE_SIZE:
return scalar_property<cl_ulong>(buf, size, size_ret, 0);
buf.as_scalar<cl_ulong>() = 0;
break;
case CL_DEVICE_GLOBAL_MEM_SIZE:
return scalar_property<cl_ulong>(buf, size, size_ret,
dev->max_mem_global());
buf.as_scalar<cl_ulong>() = dev->max_mem_global();
break;
case CL_DEVICE_MAX_CONSTANT_BUFFER_SIZE:
return scalar_property<cl_ulong>(buf, size, size_ret,
dev->max_const_buffer_size());
buf.as_scalar<cl_ulong>() = dev->max_const_buffer_size();
break;
case CL_DEVICE_MAX_CONSTANT_ARGS:
return scalar_property<cl_uint>(buf, size, size_ret,
dev->max_const_buffers());
buf.as_scalar<cl_uint>() = dev->max_const_buffers();
break;
case CL_DEVICE_LOCAL_MEM_TYPE:
return scalar_property<cl_device_local_mem_type>(buf, size, size_ret,
CL_LOCAL);
buf.as_scalar<cl_device_local_mem_type>() = CL_LOCAL;
break;
case CL_DEVICE_LOCAL_MEM_SIZE:
return scalar_property<cl_ulong>(buf, size, size_ret,
dev->max_mem_local());
buf.as_scalar<cl_ulong>() = dev->max_mem_local();
break;
case CL_DEVICE_ERROR_CORRECTION_SUPPORT:
return scalar_property<cl_bool>(buf, size, size_ret, CL_FALSE);
buf.as_scalar<cl_bool>() = CL_FALSE;
break;
case CL_DEVICE_PROFILING_TIMER_RESOLUTION:
return scalar_property<size_t>(buf, size, size_ret, 0);
buf.as_scalar<size_t>() = 0;
break;
case CL_DEVICE_ENDIAN_LITTLE:
return scalar_property<cl_bool>(buf, size, size_ret,
dev->endianness() == PIPE_ENDIAN_LITTLE);
buf.as_scalar<cl_bool>() = (dev->endianness() == PIPE_ENDIAN_LITTLE);
break;
case CL_DEVICE_AVAILABLE:
case CL_DEVICE_COMPILER_AVAILABLE:
return scalar_property<cl_bool>(buf, size, size_ret, CL_TRUE);
buf.as_scalar<cl_bool>() = CL_TRUE;
break;
case CL_DEVICE_EXECUTION_CAPABILITIES:
return scalar_property<cl_device_exec_capabilities>(buf, size, size_ret,
CL_EXEC_KERNEL);
buf.as_scalar<cl_device_exec_capabilities>() = CL_EXEC_KERNEL;
break;
case CL_DEVICE_QUEUE_PROPERTIES:
return scalar_property<cl_command_queue_properties>(buf, size, size_ret,
CL_QUEUE_PROFILING_ENABLE);
buf.as_scalar<cl_command_queue_properties>() = CL_QUEUE_PROFILING_ENABLE;
break;
case CL_DEVICE_NAME:
return string_property(buf, size, size_ret, dev->device_name());
buf.as_string() = dev->device_name();
break;
case CL_DEVICE_VENDOR:
return string_property(buf, size, size_ret, dev->vendor_name());
buf.as_string() = dev->vendor_name();
break;
case CL_DRIVER_VERSION:
return string_property(buf, size, size_ret, PACKAGE_VERSION);
buf.as_string() = PACKAGE_VERSION;
break;
case CL_DEVICE_PROFILE:
return string_property(buf, size, size_ret, "FULL_PROFILE");
buf.as_string() = "FULL_PROFILE";
break;
case CL_DEVICE_VERSION:
return string_property(buf, size, size_ret,
"OpenCL 1.1 MESA " PACKAGE_VERSION);
buf.as_string() = "OpenCL 1.1 MESA " PACKAGE_VERSION;
break;
case CL_DEVICE_EXTENSIONS:
return string_property(buf, size, size_ret, "");
buf.as_string() = "";
break;
case CL_DEVICE_PLATFORM:
return scalar_property<cl_platform_id>(buf, size, size_ret,
&dev->platform);
buf.as_scalar<cl_platform_id>() = &dev->platform;
break;
case CL_DEVICE_HOST_UNIFIED_MEMORY:
return scalar_property<cl_bool>(buf, size, size_ret, CL_TRUE);
buf.as_scalar<cl_bool>() = CL_TRUE;
break;
case CL_DEVICE_NATIVE_VECTOR_WIDTH_CHAR:
return scalar_property<cl_uint>(buf, size, size_ret, 16);
buf.as_scalar<cl_uint>() = 16;
break;
case CL_DEVICE_NATIVE_VECTOR_WIDTH_SHORT:
return scalar_property<cl_uint>(buf, size, size_ret, 8);
buf.as_scalar<cl_uint>() = 8;
break;
case CL_DEVICE_NATIVE_VECTOR_WIDTH_INT:
return scalar_property<cl_uint>(buf, size, size_ret, 4);
buf.as_scalar<cl_uint>() = 4;
break;
case CL_DEVICE_NATIVE_VECTOR_WIDTH_LONG:
return scalar_property<cl_uint>(buf, size, size_ret, 2);
buf.as_scalar<cl_uint>() = 2;
break;
case CL_DEVICE_NATIVE_VECTOR_WIDTH_FLOAT:
return scalar_property<cl_uint>(buf, size, size_ret, 4);
buf.as_scalar<cl_uint>() = 4;
break;
case CL_DEVICE_NATIVE_VECTOR_WIDTH_DOUBLE:
return scalar_property<cl_uint>(buf, size, size_ret, 2);
buf.as_scalar<cl_uint>() = 2;
break;
case CL_DEVICE_NATIVE_VECTOR_WIDTH_HALF:
return scalar_property<cl_uint>(buf, size, size_ret, 0);
buf.as_scalar<cl_uint>() = 0;
break;
case CL_DEVICE_OPENCL_C_VERSION:
return string_property(buf, size, size_ret, "OpenCL C 1.1");
buf.as_string() = "OpenCL C 1.1";
break;
default:
return CL_INVALID_VALUE;
throw error(CL_INVALID_VALUE);
}
return CL_SUCCESS;
} catch (error &e) {
return e.get();
}

View File

@@ -89,29 +89,41 @@ clWaitForEvents(cl_uint num_evs, const cl_event *evs) try {
PUBLIC cl_int
clGetEventInfo(cl_event ev, cl_event_info param,
size_t size, void *buf, size_t *size_ret) {
size_t size, void *r_buf, size_t *r_size) try {
property_buffer buf { r_buf, size, r_size };
if (!ev)
return CL_INVALID_EVENT;
switch (param) {
case CL_EVENT_COMMAND_QUEUE:
return scalar_property<cl_command_queue>(buf, size, size_ret, ev->queue());
buf.as_scalar<cl_command_queue>() = ev->queue();
break;
case CL_EVENT_CONTEXT:
return scalar_property<cl_context>(buf, size, size_ret, &ev->ctx);
buf.as_scalar<cl_context>() = &ev->ctx;
break;
case CL_EVENT_COMMAND_TYPE:
return scalar_property<cl_command_type>(buf, size, size_ret, ev->command());
buf.as_scalar<cl_command_type>() = ev->command();
break;
case CL_EVENT_COMMAND_EXECUTION_STATUS:
return scalar_property<cl_int>(buf, size, size_ret, ev->status());
buf.as_scalar<cl_int>() = ev->status();
break;
case CL_EVENT_REFERENCE_COUNT:
return scalar_property<cl_uint>(buf, size, size_ret, ev->ref_count());
buf.as_scalar<cl_uint>() = ev->ref_count();
break;
default:
return CL_INVALID_VALUE;
throw error(CL_INVALID_VALUE);
}
return CL_SUCCESS;
} catch (error &e) {
return e.get();
}
PUBLIC cl_int
@@ -216,7 +228,8 @@ clEnqueueWaitForEvents(cl_command_queue q, cl_uint num_evs,
PUBLIC cl_int
clGetEventProfilingInfo(cl_event ev, cl_profiling_info param,
size_t size, void *buf, size_t *size_ret) try {
size_t size, void *r_buf, size_t *r_size) try {
property_buffer buf { r_buf, size, r_size };
hard_event *hev = dynamic_cast<hard_event *>(ev);
if (!ev)
@@ -227,21 +240,27 @@ clGetEventProfilingInfo(cl_event ev, cl_profiling_info param,
switch (param) {
case CL_PROFILING_COMMAND_QUEUED:
return scalar_property<cl_ulong>(buf, size, size_ret, hev->time_queued());
buf.as_scalar<cl_ulong>() = hev->time_queued();
break;
case CL_PROFILING_COMMAND_SUBMIT:
return scalar_property<cl_ulong>(buf, size, size_ret, hev->time_submit());
buf.as_scalar<cl_ulong>() = hev->time_submit();
break;
case CL_PROFILING_COMMAND_START:
return scalar_property<cl_ulong>(buf, size, size_ret, hev->time_start());
buf.as_scalar<cl_ulong>() = hev->time_start();
break;
case CL_PROFILING_COMMAND_END:
return scalar_property<cl_ulong>(buf, size, size_ret, hev->time_end());
buf.as_scalar<cl_ulong>() = hev->time_end();
break;
default:
return CL_INVALID_VALUE;
throw error(CL_INVALID_VALUE);
}
return CL_SUCCESS;
} catch (lazy<cl_ulong>::undefined_error &e) {
return CL_PROFILING_INFO_NOT_AVAILABLE;

View File

@@ -118,39 +118,49 @@ clSetKernelArg(cl_kernel kern, cl_uint idx, size_t size,
PUBLIC cl_int
clGetKernelInfo(cl_kernel kern, cl_kernel_info param,
size_t size, void *buf, size_t *size_ret) {
size_t size, void *r_buf, size_t *r_size) try {
property_buffer buf { r_buf, size, r_size };
if (!kern)
return CL_INVALID_KERNEL;
switch (param) {
case CL_KERNEL_FUNCTION_NAME:
return string_property(buf, size, size_ret, kern->name());
buf.as_string() = kern->name();
break;
case CL_KERNEL_NUM_ARGS:
return scalar_property<cl_uint>(buf, size, size_ret,
kern->args.size());
buf.as_scalar<cl_uint>() = kern->args.size();
break;
case CL_KERNEL_REFERENCE_COUNT:
return scalar_property<cl_uint>(buf, size, size_ret,
kern->ref_count());
buf.as_scalar<cl_uint>() = kern->ref_count();
break;
case CL_KERNEL_CONTEXT:
return scalar_property<cl_context>(buf, size, size_ret,
&kern->prog.ctx);
buf.as_scalar<cl_context>() = &kern->prog.ctx;
break;
case CL_KERNEL_PROGRAM:
return scalar_property<cl_program>(buf, size, size_ret,
&kern->prog);
buf.as_scalar<cl_program>() = &kern->prog;
break;
default:
return CL_INVALID_VALUE;
throw error(CL_INVALID_VALUE);
}
return CL_SUCCESS;
} catch (error &e) {
return e.get();
}
PUBLIC cl_int
clGetKernelWorkGroupInfo(cl_kernel kern, cl_device_id dev,
cl_kernel_work_group_info param,
size_t size, void *buf, size_t *size_ret) {
size_t size, void *r_buf, size_t *r_size) try {
property_buffer buf { r_buf, size, r_size };
if (!kern)
return CL_INVALID_KERNEL;
@@ -160,27 +170,33 @@ clGetKernelWorkGroupInfo(cl_kernel kern, cl_device_id dev,
switch (param) {
case CL_KERNEL_WORK_GROUP_SIZE:
return scalar_property<size_t>(buf, size, size_ret,
kern->max_block_size());
buf.as_scalar<size_t>() = kern->max_block_size();
break;
case CL_KERNEL_COMPILE_WORK_GROUP_SIZE:
return vector_property<size_t>(buf, size, size_ret,
kern->block_size());
buf.as_vector<size_t>() = kern->block_size();
break;
case CL_KERNEL_LOCAL_MEM_SIZE:
return scalar_property<cl_ulong>(buf, size, size_ret,
kern->mem_local());
buf.as_scalar<cl_ulong>() = kern->mem_local();
break;
case CL_KERNEL_PREFERRED_WORK_GROUP_SIZE_MULTIPLE:
return scalar_property<size_t>(buf, size, size_ret, 1);
buf.as_scalar<size_t>() = 1;
break;
case CL_KERNEL_PRIVATE_MEM_SIZE:
return scalar_property<cl_ulong>(buf, size, size_ret,
kern->mem_private());
buf.as_scalar<cl_ulong>() = kern->mem_private();
break;
default:
return CL_INVALID_VALUE;
throw error(CL_INVALID_VALUE);
}
return CL_SUCCESS;
} catch (error &e) {
return e.get();
}
namespace {

View File

@@ -192,81 +192,107 @@ clGetSupportedImageFormats(cl_context ctx, cl_mem_flags flags,
PUBLIC cl_int
clGetMemObjectInfo(cl_mem obj, cl_mem_info param,
size_t size, void *buf, size_t *size_ret) {
size_t size, void *r_buf, size_t *r_size) try {
property_buffer buf { r_buf, size, r_size };
if (!obj)
return CL_INVALID_MEM_OBJECT;
switch (param) {
case CL_MEM_TYPE:
return scalar_property<cl_mem_object_type>(buf, size, size_ret,
obj->type());
buf.as_scalar<cl_mem_object_type>() = obj->type();
break;
case CL_MEM_FLAGS:
return scalar_property<cl_mem_flags>(buf, size, size_ret, obj->flags());
buf.as_scalar<cl_mem_flags>() = obj->flags();
break;
case CL_MEM_SIZE:
return scalar_property<size_t>(buf, size, size_ret, obj->size());
buf.as_scalar<size_t>() = obj->size();
break;
case CL_MEM_HOST_PTR:
return scalar_property<void *>(buf, size, size_ret, obj->host_ptr());
buf.as_scalar<void *>() = obj->host_ptr();
break;
case CL_MEM_MAP_COUNT:
return scalar_property<cl_uint>(buf, size, size_ret, 0);
buf.as_scalar<cl_uint>() = 0;
break;
case CL_MEM_REFERENCE_COUNT:
return scalar_property<cl_uint>(buf, size, size_ret, obj->ref_count());
buf.as_scalar<cl_uint>() = obj->ref_count();
break;
case CL_MEM_CONTEXT:
return scalar_property<cl_context>(buf, size, size_ret, &obj->ctx);
buf.as_scalar<cl_context>() = &obj->ctx;
break;
case CL_MEM_ASSOCIATED_MEMOBJECT: {
sub_buffer *sub = dynamic_cast<sub_buffer *>(obj);
return scalar_property<cl_mem>(buf, size, size_ret,
(sub ? &sub->parent : NULL));
buf.as_scalar<cl_mem>() = (sub ? &sub->parent : NULL);
break;
}
case CL_MEM_OFFSET: {
sub_buffer *sub = dynamic_cast<sub_buffer *>(obj);
return scalar_property<size_t>(buf, size, size_ret,
(sub ? sub->offset() : 0));
buf.as_scalar<size_t>() = (sub ? sub->offset() : 0);
break;
}
default:
return CL_INVALID_VALUE;
throw error(CL_INVALID_VALUE);
}
return CL_SUCCESS;
} catch (error &e) {
return e.get();
}
PUBLIC cl_int
clGetImageInfo(cl_mem obj, cl_image_info param,
size_t size, void *buf, size_t *size_ret) {
size_t size, void *r_buf, size_t *r_size) try {
property_buffer buf { r_buf, size, r_size };
image *img = dynamic_cast<image *>(obj);
if (!img)
return CL_INVALID_MEM_OBJECT;
switch (param) {
case CL_IMAGE_FORMAT:
return scalar_property<cl_image_format>(buf, size, size_ret,
img->format());
buf.as_scalar<cl_image_format>() = img->format();
break;
case CL_IMAGE_ELEMENT_SIZE:
return scalar_property<size_t>(buf, size, size_ret, 0);
buf.as_scalar<size_t>() = 0;
break;
case CL_IMAGE_ROW_PITCH:
return scalar_property<size_t>(buf, size, size_ret, img->row_pitch());
buf.as_scalar<size_t>() = img->row_pitch();
break;
case CL_IMAGE_SLICE_PITCH:
return scalar_property<size_t>(buf, size, size_ret, img->slice_pitch());
buf.as_scalar<size_t>() = img->slice_pitch();
break;
case CL_IMAGE_WIDTH:
return scalar_property<size_t>(buf, size, size_ret, img->width());
buf.as_scalar<size_t>() = img->width();
break;
case CL_IMAGE_HEIGHT:
return scalar_property<size_t>(buf, size, size_ret, img->height());
buf.as_scalar<size_t>() = img->height();
break;
case CL_IMAGE_DEPTH:
return scalar_property<size_t>(buf, size, size_ret, img->depth());
buf.as_scalar<size_t>() = img->depth();
break;
default:
return CL_INVALID_VALUE;
throw error(CL_INVALID_VALUE);
}
return CL_SUCCESS;
} catch (error &e) {
return e.get();
}
PUBLIC cl_int

View File

@@ -46,28 +46,39 @@ clGetPlatformIDs(cl_uint num_entries, cl_platform_id *platforms,
PUBLIC cl_int
clGetPlatformInfo(cl_platform_id platform, cl_platform_info param_name,
size_t size, void *buf, size_t *size_ret) {
size_t size, void *r_buf, size_t *r_size) try {
property_buffer buf { r_buf, size, r_size };
if (platform != &_clover_platform)
return CL_INVALID_PLATFORM;
switch (param_name) {
case CL_PLATFORM_PROFILE:
return string_property(buf, size, size_ret, "FULL_PROFILE");
buf.as_string() = "FULL_PROFILE";
break;
case CL_PLATFORM_VERSION:
return string_property(buf, size, size_ret,
"OpenCL 1.1 MESA " PACKAGE_VERSION);
buf.as_string() = "OpenCL 1.1 MESA " PACKAGE_VERSION;
break;
case CL_PLATFORM_NAME:
return string_property(buf, size, size_ret, "Default");
buf.as_string() = "Default";
break;
case CL_PLATFORM_VENDOR:
return string_property(buf, size, size_ret, "Mesa");
buf.as_string() = "Mesa";
break;
case CL_PLATFORM_EXTENSIONS:
return string_property(buf, size, size_ret, "");
buf.as_string() = "";
break;
default:
return CL_INVALID_VALUE;
throw error(CL_INVALID_VALUE);
}
return CL_SUCCESS;
} catch (error &e) {
return e.get();
}

View File

@@ -166,62 +166,71 @@ clUnloadCompiler() {
PUBLIC cl_int
clGetProgramInfo(cl_program prog, cl_program_info param,
size_t size, void *buf, size_t *size_ret) {
size_t size, void *r_buf, size_t *r_size) try {
property_buffer buf { r_buf, size, r_size };
if (!prog)
return CL_INVALID_PROGRAM;
switch (param) {
case CL_PROGRAM_REFERENCE_COUNT:
return scalar_property<cl_uint>(buf, size, size_ret,
prog->ref_count());
buf.as_scalar<cl_uint>() = prog->ref_count();
break;
case CL_PROGRAM_CONTEXT:
return scalar_property<cl_context>(buf, size, size_ret,
&prog->ctx);
buf.as_scalar<cl_context>() = &prog->ctx;
break;
case CL_PROGRAM_NUM_DEVICES:
return scalar_property<cl_uint>(buf, size, size_ret,
prog->binaries().size());
buf.as_scalar<cl_uint>() = prog->binaries().size();
break;
case CL_PROGRAM_DEVICES:
return vector_property<cl_device_id>(
buf, size, size_ret,
map(keys(), prog->binaries()));
buf.as_vector<cl_device_id>() = map(keys(), prog->binaries());
break;
case CL_PROGRAM_SOURCE:
return string_property(buf, size, size_ret, prog->source());
buf.as_string() = prog->source();
break;
case CL_PROGRAM_BINARY_SIZES:
return vector_property<size_t>(
buf, size, size_ret,
buf.as_vector<size_t>() =
map([](const std::pair<device *, module> &ent) {
compat::ostream::buffer_t bin;
compat::ostream s(bin);
ent.second.serialize(s);
return bin.size();
},
prog->binaries()));
prog->binaries());
break;
case CL_PROGRAM_BINARIES:
return matrix_property<unsigned char>(
buf, size, size_ret,
buf.as_matrix<unsigned char>() =
map([](const std::pair<device *, module> &ent) {
compat::ostream::buffer_t bin;
compat::ostream s(bin);
ent.second.serialize(s);
return bin;
},
prog->binaries()));
prog->binaries());
break;
default:
return CL_INVALID_VALUE;
throw error(CL_INVALID_VALUE);
}
return CL_SUCCESS;
} catch (error &e) {
return e.get();
}
PUBLIC cl_int
clGetProgramBuildInfo(cl_program prog, cl_device_id dev,
cl_program_build_info param,
size_t size, void *buf, size_t *size_ret) {
size_t size, void *r_buf, size_t *r_size) try {
property_buffer buf { r_buf, size, r_size };
if (!prog)
return CL_INVALID_PROGRAM;
@@ -230,16 +239,23 @@ clGetProgramBuildInfo(cl_program prog, cl_device_id dev,
switch (param) {
case CL_PROGRAM_BUILD_STATUS:
return scalar_property<cl_build_status>(buf, size, size_ret,
prog->build_status(dev));
buf.as_scalar<cl_build_status>() = prog->build_status(dev);
break;
case CL_PROGRAM_BUILD_OPTIONS:
return string_property(buf, size, size_ret, prog->build_opts(dev));
buf.as_string() = prog->build_opts(dev);
break;
case CL_PROGRAM_BUILD_LOG:
return string_property(buf, size, size_ret, prog->build_log(dev));
buf.as_string() = prog->build_log(dev);
break;
default:
return CL_INVALID_VALUE;
throw error(CL_INVALID_VALUE);
}
return CL_SUCCESS;
} catch (error &e) {
return e.get();
}

View File

@@ -69,27 +69,37 @@ clReleaseCommandQueue(cl_command_queue q) {
PUBLIC cl_int
clGetCommandQueueInfo(cl_command_queue q, cl_command_queue_info param,
size_t size, void *buf, size_t *size_ret) {
size_t size, void *r_buf, size_t *r_size) try {
property_buffer buf { r_buf, size, r_size };
if (!q)
return CL_INVALID_COMMAND_QUEUE;
switch (param) {
case CL_QUEUE_CONTEXT:
return scalar_property<cl_context>(buf, size, size_ret, &q->ctx);
buf.as_scalar<cl_context>() = &q->ctx;
break;
case CL_QUEUE_DEVICE:
return scalar_property<cl_device_id>(buf, size, size_ret, &q->dev);
buf.as_scalar<cl_device_id>() = &q->dev;
break;
case CL_QUEUE_REFERENCE_COUNT:
return scalar_property<cl_uint>(buf, size, size_ret, q->ref_count());
buf.as_scalar<cl_uint>() = q->ref_count();
break;
case CL_QUEUE_PROPERTIES:
return scalar_property<cl_command_queue_properties>(buf, size, size_ret,
q->props());
buf.as_scalar<cl_command_queue_properties>() = q->props();
break;
default:
return CL_INVALID_VALUE;
throw error(CL_INVALID_VALUE);
}
return CL_SUCCESS;
} catch (error &e) {
return e.get();
}
PUBLIC cl_int

View File

@@ -62,29 +62,39 @@ clReleaseSampler(cl_sampler s) {
PUBLIC cl_int
clGetSamplerInfo(cl_sampler s, cl_sampler_info param,
size_t size, void *buf, size_t *size_ret) {
size_t size, void *r_buf, size_t *r_size) try {
property_buffer buf { r_buf, size, r_size };
if (!s)
throw error(CL_INVALID_SAMPLER);
switch (param) {
case CL_SAMPLER_REFERENCE_COUNT:
return scalar_property<cl_uint>(buf, size, size_ret, s->ref_count());
buf.as_scalar<cl_uint>() = s->ref_count();
break;
case CL_SAMPLER_CONTEXT:
return scalar_property<cl_context>(buf, size, size_ret, &s->ctx);
buf.as_scalar<cl_context>() = &s->ctx;
break;
case CL_SAMPLER_NORMALIZED_COORDS:
return scalar_property<cl_bool>(buf, size, size_ret, s->norm_mode());
buf.as_scalar<cl_bool>() = s->norm_mode();
break;
case CL_SAMPLER_ADDRESSING_MODE:
return scalar_property<cl_addressing_mode>(buf, size, size_ret,
s->addr_mode());
buf.as_scalar<cl_addressing_mode>() = s->addr_mode();
break;
case CL_SAMPLER_FILTER_MODE:
return scalar_property<cl_filter_mode>(buf, size, size_ret,
s->filter_mode());
buf.as_scalar<cl_filter_mode>() = s->filter_mode();
break;
default:
return CL_INVALID_VALUE;
throw error(CL_INVALID_VALUE);
}
return CL_SUCCESS;
} catch (error &e) {
return e.get();
}

View File

@@ -29,80 +29,11 @@
#include <map>
#include "core/base.hpp"
#include "core/property.hpp"
#include "util/algorithm.hpp"
#include "pipe/p_compiler.h"
namespace clover {
///
/// Return a matrix (a container of containers) in \a buf with
/// argument and bounds checking. Intended to be used by
/// implementations of \a clGetXXXInfo().
///
template<typename T, typename V>
cl_int
matrix_property(void *buf, size_t size, size_t *size_ret, const V& v) {
if (buf && size < sizeof(T *) * v.size())
return CL_INVALID_VALUE;
if (size_ret)
*size_ret = sizeof(T *) * v.size();
if (buf)
for_each([](typename V::value_type src, T *dst) {
if (dst)
copy(src, dst);
},
v, range((T **)buf, v.size()));
return CL_SUCCESS;
}
///
/// Return a vector in \a buf with argument and bounds checking.
/// Intended to be used by implementations of \a clGetXXXInfo().
///
template<typename T, typename V>
cl_int
vector_property(void *buf, size_t size, size_t *size_ret, const V& v) {
if (buf && size < sizeof(T) * v.size())
return CL_INVALID_VALUE;
if (size_ret)
*size_ret = sizeof(T) * v.size();
if (buf)
copy(v, (T *)buf);
return CL_SUCCESS;
}
///
/// Return a scalar in \a buf with argument and bounds checking.
/// Intended to be used by implementations of \a clGetXXXInfo().
///
template<typename T>
cl_int
scalar_property(void *buf, size_t size, size_t *size_ret, T v) {
return vector_property<T>(buf, size, size_ret, std::vector<T>(1, v));
}
///
/// Return a string in \a buf with argument and bounds checking.
/// Intended to be used by implementations of \a clGetXXXInfo().
///
inline cl_int
string_property(void *buf, size_t size, size_t *size_ret,
const std::string &v) {
if (buf && size < v.size() + 1)
return CL_INVALID_VALUE;
if (size_ret)
*size_ret = v.size() + 1;
if (buf)
std::strcpy((char *)buf, v.c_str());
return CL_SUCCESS;
}
///
/// Convert a NULL-terminated property list into an std::map.
///

View File

@@ -0,0 +1,193 @@
//
// Copyright 2013 Francisco Jerez
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
//
#ifndef CLOVER_CORE_PROPERTY_HPP
#define CLOVER_CORE_PROPERTY_HPP
#include <map>
#include "util/range.hpp"
#include "util/algorithm.hpp"
namespace clover {
class property_buffer;
namespace detail {
template<typename T>
class property_scalar {
public:
property_scalar(property_buffer &buf) : buf(buf) {
}
inline property_scalar &
operator=(const T &x);
private:
property_buffer &buf;
};
template<typename T>
class property_vector {
public:
property_vector(property_buffer &buf) : buf(buf) {
}
template<typename S>
inline property_vector &
operator=(const S &v);
private:
property_buffer &buf;
};
template<typename T>
class property_matrix {
public:
property_matrix(property_buffer &buf) : buf(buf) {
}
template<typename S>
inline property_matrix &
operator=(const S &v);
private:
property_buffer &buf;
};
class property_string {
public:
property_string(property_buffer &buf) : buf(buf) {
}
inline property_string &
operator=(const std::string &v);
private:
property_buffer &buf;
};
};
///
/// Return value buffer used by the CL property query functions.
///
class property_buffer {
public:
property_buffer(void *r_buf, size_t size, size_t *r_size) :
r_buf(r_buf), size(size), r_size(r_size) {
}
template<typename T>
detail::property_scalar<T>
as_scalar() {
return { *this };
}
template<typename T>
detail::property_vector<T>
as_vector() {
return { *this };
}
template<typename T>
detail::property_matrix<T>
as_matrix() {
return { *this };
}
detail::property_string
as_string() {
return { *this };
}
template<typename T>
iterator_range<T *>
allocate(size_t n) {
if (r_buf && size < n * sizeof(T))
throw error(CL_INVALID_VALUE);
if (r_size)
*r_size = n * sizeof(T);
if (r_buf)
return range((T *)r_buf, n);
else
return { };
}
private:
void *const r_buf;
const size_t size;
size_t *const r_size;
};
namespace detail {
template<typename T>
inline property_scalar<T> &
property_scalar<T>::operator=(const T &x) {
auto r = buf.allocate<T>(1);
if (!r.empty())
r.front() = x;
return *this;
}
template<typename T>
template<typename S>
inline property_vector<T> &
property_vector<T>::operator=(const S &v) {
auto r = buf.allocate<T>(v.size());
if (!r.empty())
copy(v, r.begin());
return *this;
}
template<typename T>
template<typename S>
inline property_matrix<T> &
property_matrix<T>::operator=(const S &v) {
auto r = buf.allocate<T *>(v.size());
if (!r.empty())
for_each([](typename S::value_type src, T *dst) {
if (dst)
copy(src, dst);
}, v, r);
return *this;
}
inline property_string &
property_string::operator=(const std::string &v) {
auto r = buf.allocate<char>(v.size() + 1);
if (!r.empty())
copy(range(v.begin(), r.size()), r.begin());
return *this;
}
};
}
#endif