From d8b499428183178885bb182c898ee6f52e92ef03 Mon Sep 17 00:00:00 2001 From: Francisco Jerez Date: Sun, 6 Oct 2013 13:49:49 -0700 Subject: [PATCH] clover: Clean up property query functions by using a new property_buffer helper class. Tested-by: Tom Stellard --- src/gallium/state_trackers/clover/Makefile.sources | 1 + src/gallium/state_trackers/clover/api/context.cpp | 24 ++- src/gallium/state_trackers/clover/api/device.cpp | 199 +++++++++++++-------- src/gallium/state_trackers/clover/api/event.cpp | 45 +++-- src/gallium/state_trackers/clover/api/kernel.cpp | 60 ++++--- src/gallium/state_trackers/clover/api/memory.cpp | 74 +++++--- src/gallium/state_trackers/clover/api/platform.cpp | 27 ++- src/gallium/state_trackers/clover/api/program.cpp | 64 ++++--- src/gallium/state_trackers/clover/api/queue.cpp | 24 ++- src/gallium/state_trackers/clover/api/sampler.cpp | 28 ++- src/gallium/state_trackers/clover/api/util.hpp | 71 +------- .../state_trackers/clover/core/property.hpp | 193 ++++++++++++++++++++ 12 files changed, 547 insertions(+), 263 deletions(-) create mode 100644 src/gallium/state_trackers/clover/core/property.hpp diff --git a/src/gallium/state_trackers/clover/Makefile.sources b/src/gallium/state_trackers/clover/Makefile.sources index daa5091..96e7a41 100644 --- a/src/gallium/state_trackers/clover/Makefile.sources +++ b/src/gallium/state_trackers/clover/Makefile.sources @@ -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 \ diff --git a/src/gallium/state_trackers/clover/api/context.cpp b/src/gallium/state_trackers/clover/api/context.cpp index 8586b3e..43d5ac3 100644 --- a/src/gallium/state_trackers/clover/api/context.cpp +++ b/src/gallium/state_trackers/clover/api/context.cpp @@ -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(buf, size, size_ret, ctx->ref_count()); + buf.as_scalar() = ctx->ref_count(); + break; case CL_CONTEXT_NUM_DEVICES: - return scalar_property(buf, size, size_ret, ctx->devs.size()); + buf.as_scalar() = ctx->devs.size(); + break; case CL_CONTEXT_DEVICES: - return vector_property(buf, size, size_ret, ctx->devs); + buf.as_vector() = ctx->devs; + break; case CL_CONTEXT_PROPERTIES: - return vector_property(buf, size, size_ret, - ctx->props()); + buf.as_vector() = ctx->props(); + break; default: - return CL_INVALID_VALUE; + throw error(CL_INVALID_VALUE); } + + return CL_SUCCESS; + +} catch (error &e) { + return e.get(); } diff --git a/src/gallium/state_trackers/clover/api/device.cpp b/src/gallium/state_trackers/clover/api/device.cpp index 3e8b3f8..495ac41 100644 --- a/src/gallium/state_trackers/clover/api/device.cpp +++ b/src/gallium/state_trackers/clover/api/device.cpp @@ -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(buf, size, size_ret, dev->type()); + buf.as_scalar() = dev->type(); + break; case CL_DEVICE_VENDOR_ID: - return scalar_property(buf, size, size_ret, dev->vendor_id()); + buf.as_scalar() = dev->vendor_id(); + break; case CL_DEVICE_MAX_COMPUTE_UNITS: - return scalar_property(buf, size, size_ret, 1); + buf.as_scalar() = 1; + break; case CL_DEVICE_MAX_WORK_ITEM_DIMENSIONS: - return scalar_property(buf, size, size_ret, - dev->max_block_size().size()); + buf.as_scalar() = dev->max_block_size().size(); + break; case CL_DEVICE_MAX_WORK_ITEM_SIZES: - return vector_property(buf, size, size_ret, - dev->max_block_size()); + buf.as_vector() = dev->max_block_size(); + break; case CL_DEVICE_MAX_WORK_GROUP_SIZE: - return scalar_property(buf, size, size_ret, - dev->max_threads_per_block()); + buf.as_scalar() = dev->max_threads_per_block(); + break; case CL_DEVICE_PREFERRED_VECTOR_WIDTH_CHAR: - return scalar_property(buf, size, size_ret, 16); + buf.as_scalar() = 16; + break; case CL_DEVICE_PREFERRED_VECTOR_WIDTH_SHORT: - return scalar_property(buf, size, size_ret, 8); + buf.as_scalar() = 8; + break; case CL_DEVICE_PREFERRED_VECTOR_WIDTH_INT: - return scalar_property(buf, size, size_ret, 4); + buf.as_scalar() = 4; + break; case CL_DEVICE_PREFERRED_VECTOR_WIDTH_LONG: - return scalar_property(buf, size, size_ret, 2); + buf.as_scalar() = 2; + break; case CL_DEVICE_PREFERRED_VECTOR_WIDTH_FLOAT: - return scalar_property(buf, size, size_ret, 4); + buf.as_scalar() = 4; + break; case CL_DEVICE_PREFERRED_VECTOR_WIDTH_DOUBLE: - return scalar_property(buf, size, size_ret, 2); + buf.as_scalar() = 2; + break; case CL_DEVICE_PREFERRED_VECTOR_WIDTH_HALF: - return scalar_property(buf, size, size_ret, 0); + buf.as_scalar() = 0; + break; case CL_DEVICE_MAX_CLOCK_FREQUENCY: - return scalar_property(buf, size, size_ret, 0); + buf.as_scalar() = 0; + break; case CL_DEVICE_ADDRESS_BITS: - return scalar_property(buf, size, size_ret, 32); + buf.as_scalar() = 32; + break; case CL_DEVICE_MAX_READ_IMAGE_ARGS: - return scalar_property(buf, size, size_ret, - dev->max_images_read()); + buf.as_scalar() = dev->max_images_read(); + break; case CL_DEVICE_MAX_WRITE_IMAGE_ARGS: - return scalar_property(buf, size, size_ret, - dev->max_images_write()); + buf.as_scalar() = dev->max_images_write(); + break; case CL_DEVICE_MAX_MEM_ALLOC_SIZE: - return scalar_property(buf, size, size_ret, - dev->max_mem_alloc_size()); + buf.as_scalar() = dev->max_mem_alloc_size(); + break; case CL_DEVICE_IMAGE2D_MAX_WIDTH: case CL_DEVICE_IMAGE2D_MAX_HEIGHT: - return scalar_property(buf, size, size_ret, - 1 << dev->max_image_levels_2d()); + buf.as_scalar() = 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(buf, size, size_ret, - 1 << dev->max_image_levels_3d()); + buf.as_scalar() = 1 << dev->max_image_levels_3d(); + break; case CL_DEVICE_IMAGE_SUPPORT: - return scalar_property(buf, size, size_ret, CL_TRUE); + buf.as_scalar() = CL_TRUE; + break; case CL_DEVICE_MAX_PARAMETER_SIZE: - return scalar_property(buf, size, size_ret, - dev->max_mem_input()); + buf.as_scalar() = dev->max_mem_input(); + break; case CL_DEVICE_MAX_SAMPLERS: - return scalar_property(buf, size, size_ret, - dev->max_samplers()); + buf.as_scalar() = dev->max_samplers(); + break; case CL_DEVICE_MEM_BASE_ADDR_ALIGN: case CL_DEVICE_MIN_DATA_TYPE_ALIGN_SIZE: - return scalar_property(buf, size, size_ret, 128); + buf.as_scalar() = 128; + break; case CL_DEVICE_SINGLE_FP_CONFIG: - return scalar_property(buf, size, size_ret, - CL_FP_DENORM | CL_FP_INF_NAN | CL_FP_ROUND_TO_NEAREST); + buf.as_scalar() = + CL_FP_DENORM | CL_FP_INF_NAN | CL_FP_ROUND_TO_NEAREST; + break; case CL_DEVICE_GLOBAL_MEM_CACHE_TYPE: - return scalar_property(buf, size, size_ret, - CL_NONE); + buf.as_scalar() = CL_NONE; + break; case CL_DEVICE_GLOBAL_MEM_CACHELINE_SIZE: - return scalar_property(buf, size, size_ret, 0); + buf.as_scalar() = 0; + break; case CL_DEVICE_GLOBAL_MEM_CACHE_SIZE: - return scalar_property(buf, size, size_ret, 0); + buf.as_scalar() = 0; + break; case CL_DEVICE_GLOBAL_MEM_SIZE: - return scalar_property(buf, size, size_ret, - dev->max_mem_global()); + buf.as_scalar() = dev->max_mem_global(); + break; case CL_DEVICE_MAX_CONSTANT_BUFFER_SIZE: - return scalar_property(buf, size, size_ret, - dev->max_const_buffer_size()); + buf.as_scalar() = dev->max_const_buffer_size(); + break; case CL_DEVICE_MAX_CONSTANT_ARGS: - return scalar_property(buf, size, size_ret, - dev->max_const_buffers()); + buf.as_scalar() = dev->max_const_buffers(); + break; case CL_DEVICE_LOCAL_MEM_TYPE: - return scalar_property(buf, size, size_ret, - CL_LOCAL); + buf.as_scalar() = CL_LOCAL; + break; case CL_DEVICE_LOCAL_MEM_SIZE: - return scalar_property(buf, size, size_ret, - dev->max_mem_local()); + buf.as_scalar() = dev->max_mem_local(); + break; case CL_DEVICE_ERROR_CORRECTION_SUPPORT: - return scalar_property(buf, size, size_ret, CL_FALSE); + buf.as_scalar() = CL_FALSE; + break; case CL_DEVICE_PROFILING_TIMER_RESOLUTION: - return scalar_property(buf, size, size_ret, 0); + buf.as_scalar() = 0; + break; case CL_DEVICE_ENDIAN_LITTLE: - return scalar_property(buf, size, size_ret, - dev->endianness() == PIPE_ENDIAN_LITTLE); + buf.as_scalar() = (dev->endianness() == PIPE_ENDIAN_LITTLE); + break; case CL_DEVICE_AVAILABLE: case CL_DEVICE_COMPILER_AVAILABLE: - return scalar_property(buf, size, size_ret, CL_TRUE); + buf.as_scalar() = CL_TRUE; + break; case CL_DEVICE_EXECUTION_CAPABILITIES: - return scalar_property(buf, size, size_ret, - CL_EXEC_KERNEL); + buf.as_scalar() = CL_EXEC_KERNEL; + break; case CL_DEVICE_QUEUE_PROPERTIES: - return scalar_property(buf, size, size_ret, - CL_QUEUE_PROFILING_ENABLE); + buf.as_scalar() = 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(buf, size, size_ret, - &dev->platform); + buf.as_scalar() = &dev->platform; + break; case CL_DEVICE_HOST_UNIFIED_MEMORY: - return scalar_property(buf, size, size_ret, CL_TRUE); + buf.as_scalar() = CL_TRUE; + break; case CL_DEVICE_NATIVE_VECTOR_WIDTH_CHAR: - return scalar_property(buf, size, size_ret, 16); + buf.as_scalar() = 16; + break; case CL_DEVICE_NATIVE_VECTOR_WIDTH_SHORT: - return scalar_property(buf, size, size_ret, 8); + buf.as_scalar() = 8; + break; case CL_DEVICE_NATIVE_VECTOR_WIDTH_INT: - return scalar_property(buf, size, size_ret, 4); + buf.as_scalar() = 4; + break; case CL_DEVICE_NATIVE_VECTOR_WIDTH_LONG: - return scalar_property(buf, size, size_ret, 2); + buf.as_scalar() = 2; + break; case CL_DEVICE_NATIVE_VECTOR_WIDTH_FLOAT: - return scalar_property(buf, size, size_ret, 4); + buf.as_scalar() = 4; + break; case CL_DEVICE_NATIVE_VECTOR_WIDTH_DOUBLE: - return scalar_property(buf, size, size_ret, 2); + buf.as_scalar() = 2; + break; case CL_DEVICE_NATIVE_VECTOR_WIDTH_HALF: - return scalar_property(buf, size, size_ret, 0); + buf.as_scalar() = 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(); } diff --git a/src/gallium/state_trackers/clover/api/event.cpp b/src/gallium/state_trackers/clover/api/event.cpp index 849d829..b2ab78e 100644 --- a/src/gallium/state_trackers/clover/api/event.cpp +++ b/src/gallium/state_trackers/clover/api/event.cpp @@ -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(buf, size, size_ret, ev->queue()); + buf.as_scalar() = ev->queue(); + break; case CL_EVENT_CONTEXT: - return scalar_property(buf, size, size_ret, &ev->ctx); + buf.as_scalar() = &ev->ctx; + break; case CL_EVENT_COMMAND_TYPE: - return scalar_property(buf, size, size_ret, ev->command()); + buf.as_scalar() = ev->command(); + break; case CL_EVENT_COMMAND_EXECUTION_STATUS: - return scalar_property(buf, size, size_ret, ev->status()); + buf.as_scalar() = ev->status(); + break; case CL_EVENT_REFERENCE_COUNT: - return scalar_property(buf, size, size_ret, ev->ref_count()); + buf.as_scalar() = 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(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(buf, size, size_ret, hev->time_queued()); + buf.as_scalar() = hev->time_queued(); + break; case CL_PROFILING_COMMAND_SUBMIT: - return scalar_property(buf, size, size_ret, hev->time_submit()); + buf.as_scalar() = hev->time_submit(); + break; case CL_PROFILING_COMMAND_START: - return scalar_property(buf, size, size_ret, hev->time_start()); + buf.as_scalar() = hev->time_start(); + break; case CL_PROFILING_COMMAND_END: - return scalar_property(buf, size, size_ret, hev->time_end()); + buf.as_scalar() = hev->time_end(); + break; default: - return CL_INVALID_VALUE; + throw error(CL_INVALID_VALUE); } + return CL_SUCCESS; + } catch (lazy::undefined_error &e) { return CL_PROFILING_INFO_NOT_AVAILABLE; diff --git a/src/gallium/state_trackers/clover/api/kernel.cpp b/src/gallium/state_trackers/clover/api/kernel.cpp index 24b17b6..0ebe479 100644 --- a/src/gallium/state_trackers/clover/api/kernel.cpp +++ b/src/gallium/state_trackers/clover/api/kernel.cpp @@ -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(buf, size, size_ret, - kern->args.size()); + buf.as_scalar() = kern->args.size(); + break; case CL_KERNEL_REFERENCE_COUNT: - return scalar_property(buf, size, size_ret, - kern->ref_count()); + buf.as_scalar() = kern->ref_count(); + break; case CL_KERNEL_CONTEXT: - return scalar_property(buf, size, size_ret, - &kern->prog.ctx); + buf.as_scalar() = &kern->prog.ctx; + break; case CL_KERNEL_PROGRAM: - return scalar_property(buf, size, size_ret, - &kern->prog); + buf.as_scalar() = &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(buf, size, size_ret, - kern->max_block_size()); + buf.as_scalar() = kern->max_block_size(); + break; case CL_KERNEL_COMPILE_WORK_GROUP_SIZE: - return vector_property(buf, size, size_ret, - kern->block_size()); + buf.as_vector() = kern->block_size(); + break; case CL_KERNEL_LOCAL_MEM_SIZE: - return scalar_property(buf, size, size_ret, - kern->mem_local()); + buf.as_scalar() = kern->mem_local(); + break; case CL_KERNEL_PREFERRED_WORK_GROUP_SIZE_MULTIPLE: - return scalar_property(buf, size, size_ret, 1); + buf.as_scalar() = 1; + break; case CL_KERNEL_PRIVATE_MEM_SIZE: - return scalar_property(buf, size, size_ret, - kern->mem_private()); + buf.as_scalar() = kern->mem_private(); + break; default: - return CL_INVALID_VALUE; + throw error(CL_INVALID_VALUE); } + + return CL_SUCCESS; + +} catch (error &e) { + return e.get(); } namespace { diff --git a/src/gallium/state_trackers/clover/api/memory.cpp b/src/gallium/state_trackers/clover/api/memory.cpp index 63b3619..112094a 100644 --- a/src/gallium/state_trackers/clover/api/memory.cpp +++ b/src/gallium/state_trackers/clover/api/memory.cpp @@ -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(buf, size, size_ret, - obj->type()); + buf.as_scalar() = obj->type(); + break; case CL_MEM_FLAGS: - return scalar_property(buf, size, size_ret, obj->flags()); + buf.as_scalar() = obj->flags(); + break; case CL_MEM_SIZE: - return scalar_property(buf, size, size_ret, obj->size()); + buf.as_scalar() = obj->size(); + break; case CL_MEM_HOST_PTR: - return scalar_property(buf, size, size_ret, obj->host_ptr()); + buf.as_scalar() = obj->host_ptr(); + break; case CL_MEM_MAP_COUNT: - return scalar_property(buf, size, size_ret, 0); + buf.as_scalar() = 0; + break; case CL_MEM_REFERENCE_COUNT: - return scalar_property(buf, size, size_ret, obj->ref_count()); + buf.as_scalar() = obj->ref_count(); + break; case CL_MEM_CONTEXT: - return scalar_property(buf, size, size_ret, &obj->ctx); + buf.as_scalar() = &obj->ctx; + break; case CL_MEM_ASSOCIATED_MEMOBJECT: { sub_buffer *sub = dynamic_cast(obj); - return scalar_property(buf, size, size_ret, - (sub ? &sub->parent : NULL)); + buf.as_scalar() = (sub ? &sub->parent : NULL); + break; } case CL_MEM_OFFSET: { sub_buffer *sub = dynamic_cast(obj); - return scalar_property(buf, size, size_ret, - (sub ? sub->offset() : 0)); + buf.as_scalar() = (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(obj); + if (!img) return CL_INVALID_MEM_OBJECT; switch (param) { case CL_IMAGE_FORMAT: - return scalar_property(buf, size, size_ret, - img->format()); + buf.as_scalar() = img->format(); + break; case CL_IMAGE_ELEMENT_SIZE: - return scalar_property(buf, size, size_ret, 0); + buf.as_scalar() = 0; + break; case CL_IMAGE_ROW_PITCH: - return scalar_property(buf, size, size_ret, img->row_pitch()); + buf.as_scalar() = img->row_pitch(); + break; case CL_IMAGE_SLICE_PITCH: - return scalar_property(buf, size, size_ret, img->slice_pitch()); + buf.as_scalar() = img->slice_pitch(); + break; case CL_IMAGE_WIDTH: - return scalar_property(buf, size, size_ret, img->width()); + buf.as_scalar() = img->width(); + break; case CL_IMAGE_HEIGHT: - return scalar_property(buf, size, size_ret, img->height()); + buf.as_scalar() = img->height(); + break; case CL_IMAGE_DEPTH: - return scalar_property(buf, size, size_ret, img->depth()); + buf.as_scalar() = 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 diff --git a/src/gallium/state_trackers/clover/api/platform.cpp b/src/gallium/state_trackers/clover/api/platform.cpp index 1f996a3..034bbef 100644 --- a/src/gallium/state_trackers/clover/api/platform.cpp +++ b/src/gallium/state_trackers/clover/api/platform.cpp @@ -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(); } diff --git a/src/gallium/state_trackers/clover/api/program.cpp b/src/gallium/state_trackers/clover/api/program.cpp index 2ef3a2e..972f156 100644 --- a/src/gallium/state_trackers/clover/api/program.cpp +++ b/src/gallium/state_trackers/clover/api/program.cpp @@ -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(buf, size, size_ret, - prog->ref_count()); + buf.as_scalar() = prog->ref_count(); + break; case CL_PROGRAM_CONTEXT: - return scalar_property(buf, size, size_ret, - &prog->ctx); + buf.as_scalar() = &prog->ctx; + break; case CL_PROGRAM_NUM_DEVICES: - return scalar_property(buf, size, size_ret, - prog->binaries().size()); + buf.as_scalar() = prog->binaries().size(); + break; case CL_PROGRAM_DEVICES: - return vector_property( - buf, size, size_ret, - map(keys(), prog->binaries())); + buf.as_vector() = 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( - buf, size, size_ret, + buf.as_vector() = map([](const std::pair &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( - buf, size, size_ret, + buf.as_matrix() = map([](const std::pair &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(buf, size, size_ret, - prog->build_status(dev)); + buf.as_scalar() = 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(); } diff --git a/src/gallium/state_trackers/clover/api/queue.cpp b/src/gallium/state_trackers/clover/api/queue.cpp index 9c7d7e6..b2927ec 100644 --- a/src/gallium/state_trackers/clover/api/queue.cpp +++ b/src/gallium/state_trackers/clover/api/queue.cpp @@ -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(buf, size, size_ret, &q->ctx); + buf.as_scalar() = &q->ctx; + break; case CL_QUEUE_DEVICE: - return scalar_property(buf, size, size_ret, &q->dev); + buf.as_scalar() = &q->dev; + break; case CL_QUEUE_REFERENCE_COUNT: - return scalar_property(buf, size, size_ret, q->ref_count()); + buf.as_scalar() = q->ref_count(); + break; case CL_QUEUE_PROPERTIES: - return scalar_property(buf, size, size_ret, - q->props()); + buf.as_scalar() = 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 diff --git a/src/gallium/state_trackers/clover/api/sampler.cpp b/src/gallium/state_trackers/clover/api/sampler.cpp index 4f5ea2f..84d5d64 100644 --- a/src/gallium/state_trackers/clover/api/sampler.cpp +++ b/src/gallium/state_trackers/clover/api/sampler.cpp @@ -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(buf, size, size_ret, s->ref_count()); + buf.as_scalar() = s->ref_count(); + break; case CL_SAMPLER_CONTEXT: - return scalar_property(buf, size, size_ret, &s->ctx); + buf.as_scalar() = &s->ctx; + break; case CL_SAMPLER_NORMALIZED_COORDS: - return scalar_property(buf, size, size_ret, s->norm_mode()); + buf.as_scalar() = s->norm_mode(); + break; case CL_SAMPLER_ADDRESSING_MODE: - return scalar_property(buf, size, size_ret, - s->addr_mode()); + buf.as_scalar() = s->addr_mode(); + break; case CL_SAMPLER_FILTER_MODE: - return scalar_property(buf, size, size_ret, - s->filter_mode()); + buf.as_scalar() = s->filter_mode(); + break; default: - return CL_INVALID_VALUE; + throw error(CL_INVALID_VALUE); } + + return CL_SUCCESS; + +} catch (error &e) { + return e.get(); } diff --git a/src/gallium/state_trackers/clover/api/util.hpp b/src/gallium/state_trackers/clover/api/util.hpp index d9d9b7a..e94b4b2 100644 --- a/src/gallium/state_trackers/clover/api/util.hpp +++ b/src/gallium/state_trackers/clover/api/util.hpp @@ -29,81 +29,12 @@ #include #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 - 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 - 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 - cl_int - scalar_property(void *buf, size_t size, size_t *size_ret, T v) { - return vector_property(buf, size, size_ret, std::vector(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. /// template diff --git a/src/gallium/state_trackers/clover/core/property.hpp b/src/gallium/state_trackers/clover/core/property.hpp new file mode 100644 index 0000000..f2e5f2b --- /dev/null +++ b/src/gallium/state_trackers/clover/core/property.hpp @@ -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 + +#include "util/range.hpp" +#include "util/algorithm.hpp" + +namespace clover { + class property_buffer; + + namespace detail { + template + class property_scalar { + public: + property_scalar(property_buffer &buf) : buf(buf) { + } + + inline property_scalar & + operator=(const T &x); + + private: + property_buffer &buf; + }; + + template + class property_vector { + public: + property_vector(property_buffer &buf) : buf(buf) { + } + + template + inline property_vector & + operator=(const S &v); + + private: + property_buffer &buf; + }; + + template + class property_matrix { + public: + property_matrix(property_buffer &buf) : buf(buf) { + } + + template + 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 + detail::property_scalar + as_scalar() { + return { *this }; + } + + template + detail::property_vector + as_vector() { + return { *this }; + } + + template + detail::property_matrix + as_matrix() { + return { *this }; + } + + detail::property_string + as_string() { + return { *this }; + } + + template + iterator_range + 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 + inline property_scalar & + property_scalar::operator=(const T &x) { + auto r = buf.allocate(1); + + if (!r.empty()) + r.front() = x; + + return *this; + } + + template + template + inline property_vector & + property_vector::operator=(const S &v) { + auto r = buf.allocate(v.size()); + + if (!r.empty()) + copy(v, r.begin()); + + return *this; + } + + template + template + inline property_matrix & + property_matrix::operator=(const S &v) { + auto r = buf.allocate(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(v.size() + 1); + + if (!r.empty()) + copy(range(v.begin(), r.size()), r.begin()); + + return *this; + } + }; +} + +#endif -- 2.7.4