summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFrancisco Jerez <[email protected]>2013-10-06 13:49:49 -0700
committerFrancisco Jerez <[email protected]>2013-10-21 10:47:02 -0700
commitd8b499428183178885bb182c898ee6f52e92ef03 (patch)
treec8b9ab03b332285576275f4d4e1a32fb5d0def5e
parent7d61769e447e47022bea5e9fd415344b45a5a050 (diff)
clover: Clean up property query functions by using a new property_buffer helper class.
Tested-by: Tom Stellard <[email protected]>
-rw-r--r--src/gallium/state_trackers/clover/Makefile.sources1
-rw-r--r--src/gallium/state_trackers/clover/api/context.cpp24
-rw-r--r--src/gallium/state_trackers/clover/api/device.cpp199
-rw-r--r--src/gallium/state_trackers/clover/api/event.cpp45
-rw-r--r--src/gallium/state_trackers/clover/api/kernel.cpp60
-rw-r--r--src/gallium/state_trackers/clover/api/memory.cpp74
-rw-r--r--src/gallium/state_trackers/clover/api/platform.cpp27
-rw-r--r--src/gallium/state_trackers/clover/api/program.cpp64
-rw-r--r--src/gallium/state_trackers/clover/api/queue.cpp24
-rw-r--r--src/gallium/state_trackers/clover/api/sampler.cpp28
-rw-r--r--src/gallium/state_trackers/clover/api/util.hpp71
-rw-r--r--src/gallium/state_trackers/clover/core/property.hpp193
12 files changed, 547 insertions, 263 deletions
diff --git a/src/gallium/state_trackers/clover/Makefile.sources b/src/gallium/state_trackers/clover/Makefile.sources
index daa50918346..96e7a4168f9 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 8586b3ece25..43d5ac3b838 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<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();
}
diff --git a/src/gallium/state_trackers/clover/api/device.cpp b/src/gallium/state_trackers/clover/api/device.cpp
index 3e8b3f821c3..495ac41f17e 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<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();
}
diff --git a/src/gallium/state_trackers/clover/api/event.cpp b/src/gallium/state_trackers/clover/api/event.cpp
index 849d829f530..b2ab78ecc05 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<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;
diff --git a/src/gallium/state_trackers/clover/api/kernel.cpp b/src/gallium/state_trackers/clover/api/kernel.cpp
index 24b17b6eb3b..0ebe479de8b 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<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 {
diff --git a/src/gallium/state_trackers/clover/api/memory.cpp b/src/gallium/state_trackers/clover/api/memory.cpp
index 63b3619f820..112094a84c9 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<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
diff --git a/src/gallium/state_trackers/clover/api/platform.cpp b/src/gallium/state_trackers/clover/api/platform.cpp
index 1f996a38299..034bbef7777 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 2ef3a2eced4..972f1566ccc 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<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();
}
diff --git a/src/gallium/state_trackers/clover/api/queue.cpp b/src/gallium/state_trackers/clover/api/queue.cpp
index 9c7d7e6120d..b2927ecabef 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<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
diff --git a/src/gallium/state_trackers/clover/api/sampler.cpp b/src/gallium/state_trackers/clover/api/sampler.cpp
index 4f5ea2fd898..84d5d643154 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<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();
}
diff --git a/src/gallium/state_trackers/clover/api/util.hpp b/src/gallium/state_trackers/clover/api/util.hpp
index d9d9b7a73cb..e94b4b26a34 100644
--- a/src/gallium/state_trackers/clover/api/util.hpp
+++ b/src/gallium/state_trackers/clover/api/util.hpp
@@ -29,81 +29,12 @@
#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.
///
template<typename T>
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 00000000000..f2e5f2bcd6d
--- /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 <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