From c6db1b3396384186aab5b685fe1fd540e17b3a62 Mon Sep 17 00:00:00 2001 From: Francisco Jerez Date: Fri, 20 Apr 2012 16:56:19 +0200 Subject: clover: Import OpenCL state tracker. --- src/gallium/state_trackers/clover/api/memory.cpp | 305 +++++++++++++++++++++++ 1 file changed, 305 insertions(+) create mode 100644 src/gallium/state_trackers/clover/api/memory.cpp (limited to 'src/gallium/state_trackers/clover/api/memory.cpp') diff --git a/src/gallium/state_trackers/clover/api/memory.cpp b/src/gallium/state_trackers/clover/api/memory.cpp new file mode 100644 index 00000000000..1b1ae73796f --- /dev/null +++ b/src/gallium/state_trackers/clover/api/memory.cpp @@ -0,0 +1,305 @@ +// +// Copyright 2012 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 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. +// + +#include "api/util.hpp" +#include "core/memory.hpp" +#include "core/format.hpp" + +using namespace clover; + +PUBLIC cl_mem +clCreateBuffer(cl_context ctx, cl_mem_flags flags, size_t size, + void *host_ptr, cl_int *errcode_ret) try { + if (!ctx) + throw error(CL_INVALID_CONTEXT); + + if (bool(host_ptr) != bool(flags & (CL_MEM_USE_HOST_PTR | + CL_MEM_COPY_HOST_PTR))) + throw error(CL_INVALID_HOST_PTR); + + if (!size) + throw error(CL_INVALID_BUFFER_SIZE); + + if (flags & ~(CL_MEM_WRITE_ONLY | CL_MEM_READ_ONLY | + CL_MEM_USE_HOST_PTR | CL_MEM_ALLOC_HOST_PTR | + CL_MEM_COPY_HOST_PTR)) + throw error(CL_INVALID_VALUE); + + ret_error(errcode_ret, CL_SUCCESS); + return new root_buffer(*ctx, flags, size, host_ptr); + +} catch (error &e) { + ret_error(errcode_ret, e); + return NULL; +} + +PUBLIC cl_mem +clCreateSubBuffer(cl_mem obj, cl_mem_flags flags, cl_buffer_create_type op, + const void *op_info, cl_int *errcode_ret) try { + root_buffer *parent = dynamic_cast(obj); + + if (!parent) + throw error(CL_INVALID_MEM_OBJECT); + + if ((flags & (CL_MEM_USE_HOST_PTR | + CL_MEM_ALLOC_HOST_PTR | + CL_MEM_COPY_HOST_PTR)) || + (~flags & parent->flags() & (CL_MEM_READ_ONLY | + CL_MEM_WRITE_ONLY))) + throw error(CL_INVALID_VALUE); + + if (op == CL_BUFFER_CREATE_TYPE_REGION) { + const cl_buffer_region *reg = (const cl_buffer_region *)op_info; + + if (!reg || + reg->origin > parent->size() || + reg->origin + reg->size > parent->size()) + throw error(CL_INVALID_VALUE); + + if (!reg->size) + throw error(CL_INVALID_BUFFER_SIZE); + + ret_error(errcode_ret, CL_SUCCESS); + return new sub_buffer(*parent, flags, reg->origin, reg->size); + + } else { + throw error(CL_INVALID_VALUE); + } + +} catch (error &e) { + ret_error(errcode_ret, e); + return NULL; +} + +PUBLIC cl_mem +clCreateImage2D(cl_context ctx, cl_mem_flags flags, + const cl_image_format *format, + size_t width, size_t height, size_t row_pitch, + void *host_ptr, cl_int *errcode_ret) try { + if (!ctx) + throw error(CL_INVALID_CONTEXT); + + if (flags & ~(CL_MEM_WRITE_ONLY | CL_MEM_READ_ONLY | + CL_MEM_USE_HOST_PTR | CL_MEM_ALLOC_HOST_PTR | + CL_MEM_COPY_HOST_PTR)) + throw error(CL_INVALID_VALUE); + + if (!format) + throw error(CL_INVALID_IMAGE_FORMAT_DESCRIPTOR); + + if (width < 1 || height < 1) + throw error(CL_INVALID_IMAGE_SIZE); + + if (bool(host_ptr) != bool(flags & (CL_MEM_USE_HOST_PTR | + CL_MEM_COPY_HOST_PTR))) + throw error(CL_INVALID_HOST_PTR); + + if (!supported_formats(ctx, CL_MEM_OBJECT_IMAGE2D).count(*format)) + throw error(CL_IMAGE_FORMAT_NOT_SUPPORTED); + + ret_error(errcode_ret, CL_SUCCESS); + return new image2d(*ctx, flags, format, width, height, + row_pitch, host_ptr); + +} catch (error &e) { + ret_error(errcode_ret, e); + return NULL; +} + +PUBLIC cl_mem +clCreateImage3D(cl_context ctx, cl_mem_flags flags, + const cl_image_format *format, + size_t width, size_t height, size_t depth, + size_t row_pitch, size_t slice_pitch, + void *host_ptr, cl_int *errcode_ret) try { + if (!ctx) + throw error(CL_INVALID_CONTEXT); + + if (flags & ~(CL_MEM_WRITE_ONLY | CL_MEM_READ_ONLY | + CL_MEM_USE_HOST_PTR | CL_MEM_ALLOC_HOST_PTR | + CL_MEM_COPY_HOST_PTR)) + throw error(CL_INVALID_VALUE); + + if (!format) + throw error(CL_INVALID_IMAGE_FORMAT_DESCRIPTOR); + + if (width < 1 || height < 1 || depth < 2) + throw error(CL_INVALID_IMAGE_SIZE); + + if (bool(host_ptr) != bool(flags & (CL_MEM_USE_HOST_PTR | + CL_MEM_COPY_HOST_PTR))) + throw error(CL_INVALID_HOST_PTR); + + if (!supported_formats(ctx, CL_MEM_OBJECT_IMAGE3D).count(*format)) + throw error(CL_IMAGE_FORMAT_NOT_SUPPORTED); + + ret_error(errcode_ret, CL_SUCCESS); + return new image3d(*ctx, flags, format, width, height, depth, + row_pitch, slice_pitch, host_ptr); + +} catch (error &e) { + ret_error(errcode_ret, e); + return NULL; +} + +PUBLIC cl_int +clGetSupportedImageFormats(cl_context ctx, cl_mem_flags flags, + cl_mem_object_type type, cl_uint count, + cl_image_format *buf, cl_uint *count_ret) try { + if (!ctx) + throw error(CL_INVALID_CONTEXT); + + if (flags & ~(CL_MEM_WRITE_ONLY | CL_MEM_READ_ONLY | + CL_MEM_USE_HOST_PTR | CL_MEM_ALLOC_HOST_PTR | + CL_MEM_COPY_HOST_PTR)) + throw error(CL_INVALID_VALUE); + + if (!count && buf) + throw error(CL_INVALID_VALUE); + + auto formats = supported_formats(ctx, type); + + if (buf) + std::copy_n(formats.begin(), std::min((cl_uint)formats.size(), count), + buf); + if (count_ret) + *count_ret = formats.size(); + + return CL_SUCCESS; + +} catch (error &e) { + return e.get(); +} + +PUBLIC cl_int +clGetMemObjectInfo(cl_mem obj, cl_mem_info param, + size_t size, void *buf, size_t *size_ret) { + if (!obj) + return CL_INVALID_MEM_OBJECT; + + switch (param) { + case CL_MEM_TYPE: + return scalar_property(buf, size, size_ret, + obj->type()); + + case CL_MEM_FLAGS: + return scalar_property(buf, size, size_ret, obj->flags()); + + case CL_MEM_SIZE: + return scalar_property(buf, size, size_ret, obj->size()); + + case CL_MEM_HOST_PTR: + return scalar_property(buf, size, size_ret, obj->host_ptr()); + + case CL_MEM_MAP_COUNT: + return scalar_property(buf, size, size_ret, 0); + + case CL_MEM_REFERENCE_COUNT: + return scalar_property(buf, size, size_ret, obj->ref_count()); + + case CL_MEM_CONTEXT: + return scalar_property(buf, size, size_ret, &obj->ctx); + + case CL_MEM_ASSOCIATED_MEMOBJECT: { + sub_buffer *sub = dynamic_cast(obj); + return scalar_property(buf, size, size_ret, + (sub ? &sub->parent : NULL)); + } + case CL_MEM_OFFSET: { + sub_buffer *sub = dynamic_cast(obj); + return scalar_property(buf, size, size_ret, + (sub ? sub->offset() : 0)); + } + default: + return CL_INVALID_VALUE; + } +} + +PUBLIC cl_int +clGetImageInfo(cl_mem obj, cl_image_info param, + size_t size, void *buf, size_t *size_ret) { + 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()); + + case CL_IMAGE_ELEMENT_SIZE: + return scalar_property(buf, size, size_ret, 0); + + case CL_IMAGE_ROW_PITCH: + return scalar_property(buf, size, size_ret, img->row_pitch()); + + case CL_IMAGE_SLICE_PITCH: + return scalar_property(buf, size, size_ret, img->slice_pitch()); + + case CL_IMAGE_WIDTH: + return scalar_property(buf, size, size_ret, img->width()); + + case CL_IMAGE_HEIGHT: + return scalar_property(buf, size, size_ret, img->height()); + + case CL_IMAGE_DEPTH: + return scalar_property(buf, size, size_ret, img->depth()); + + default: + return CL_INVALID_VALUE; + } +} + +PUBLIC cl_int +clRetainMemObject(cl_mem obj) { + if (!obj) + return CL_INVALID_MEM_OBJECT; + + obj->retain(); + return CL_SUCCESS; +} + +PUBLIC cl_int +clReleaseMemObject(cl_mem obj) { + if (!obj) + return CL_INVALID_MEM_OBJECT; + + if (obj->release()) + delete obj; + + return CL_SUCCESS; +} + +PUBLIC cl_int +clSetMemObjectDestructorCallback(cl_mem obj, + void (CL_CALLBACK *pfn_notify)(cl_mem, void *), + void *user_data) { + if (!obj) + return CL_INVALID_MEM_OBJECT; + + if (!pfn_notify) + return CL_INVALID_VALUE; + + obj->destroy_notify([=]{ pfn_notify(obj, user_data); }); + + return CL_SUCCESS; +} -- cgit v1.2.3