clover: Clean up property query functions by using a new property_buffer helper class.
authorFrancisco Jerez <currojerez@riseup.net>
Sun, 6 Oct 2013 20:49:49 +0000 (13:49 -0700)
committerFrancisco Jerez <currojerez@riseup.net>
Mon, 21 Oct 2013 17:47:02 +0000 (10:47 -0700)
Tested-by: Tom Stellard <thomas.stellard@amd.com>
12 files changed:
src/gallium/state_trackers/clover/Makefile.sources
src/gallium/state_trackers/clover/api/context.cpp
src/gallium/state_trackers/clover/api/device.cpp
src/gallium/state_trackers/clover/api/event.cpp
src/gallium/state_trackers/clover/api/kernel.cpp
src/gallium/state_trackers/clover/api/memory.cpp
src/gallium/state_trackers/clover/api/platform.cpp
src/gallium/state_trackers/clover/api/program.cpp
src/gallium/state_trackers/clover/api/queue.cpp
src/gallium/state_trackers/clover/api/sampler.cpp
src/gallium/state_trackers/clover/api/util.hpp
src/gallium/state_trackers/clover/core/property.hpp [new file with mode: 0644]

index daa50918346fb0cd6888a8dda579508cd3e0ffc0..96e7a4168f9b418d1e7fc36789e49967a83482bb 100644 (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 \
index 8586b3ece254f106e27a6ee166c945633cd5756b..43d5ac3b838e592bf11915e5916a69a6c7a10257 100644 (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();
 }
index 3e8b3f821c3147309a75ab37a54dce3eec721805..495ac41f17e70a48e62bafc5660e25e0196469df 100644 (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();
 }
index 849d829f530a207e2aad195d24cc5cc69f9298f5..b2ab78ecc052eb7f73fd2079ba50361642b4b04c 100644 (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;
 
index 24b17b6eb3bda7cf6667c27687ebedaab0f92b4f..0ebe479de8ba5447ccde87a346a2077a5937d542 100644 (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 {
index 63b3619f820f964868b78a9ad0c6b56792707587..112094a84c90edcdf74c7bae335411ca3857088c 100644 (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
index 1f996a3829944175dc6a4447421cf4e92a7430b8..034bbef777773ad26ccf21c9d51da6302f381254 100644 (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();
 }
index 2ef3a2eced402237c758e2d381cd8c0071529b7b..972f1566cccd088d625ed3f33bd6013ba1533a79 100644 (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();
 }
index 9c7d7e6120d0e280e3c6740471d7d533ff4e105d..b2927ecabef48586ac04e140abd622113911cb4c 100644 (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
index 4f5ea2fd89891014886ec99c6b8cf30cf625fc11..84d5d64315494f0107dfa4b21d006a375c954565 100644 (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();
 }
index d9d9b7a73cb6ace21884f1a6e6f0ac5028e0a7ca..e94b4b26a34e0013db576036f89b4cb78e02f9dc 100644 (file)
 #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.
    ///
diff --git a/src/gallium/state_trackers/clover/core/property.hpp b/src/gallium/state_trackers/clover/core/property.hpp
new file mode 100644 (file)
index 0000000..f2e5f2b
--- /dev/null
@@ -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