Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

  1. //
  2. // Copyright 2012 Francisco Jerez
  3. //
  4. // Permission is hereby granted, free of charge, to any person obtaining a
  5. // copy of this software and associated documentation files (the "Software"),
  6. // to deal in the Software without restriction, including without limitation
  7. // the rights to use, copy, modify, merge, publish, distribute, sublicense,
  8. // and/or sell copies of the Software, and to permit persons to whom the
  9. // Software is furnished to do so, subject to the following conditions:
  10. //
  11. // The above copyright notice and this permission notice shall be included in
  12. // all copies or substantial portions of the Software.
  13. //
  14. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  17. // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
  18. // OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
  19. // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  20. // OTHER DEALINGS IN THE SOFTWARE.
  21. //
  22.  
  23. #include "api/util.hpp"
  24. #include "core/memory.hpp"
  25. #include "core/format.hpp"
  26.  
  27. using namespace clover;
  28.  
  29. PUBLIC cl_mem
  30. clCreateBuffer(cl_context ctx, cl_mem_flags flags, size_t size,
  31.                void *host_ptr, cl_int *errcode_ret) try {
  32.    if (!ctx)
  33.       throw error(CL_INVALID_CONTEXT);
  34.  
  35.    if (bool(host_ptr) != bool(flags & (CL_MEM_USE_HOST_PTR |
  36.                                        CL_MEM_COPY_HOST_PTR)))
  37.       throw error(CL_INVALID_HOST_PTR);
  38.  
  39.    if (!size)
  40.       throw error(CL_INVALID_BUFFER_SIZE);
  41.  
  42.    if (flags & ~(CL_MEM_READ_WRITE | CL_MEM_WRITE_ONLY | CL_MEM_READ_ONLY |
  43.                  CL_MEM_USE_HOST_PTR | CL_MEM_ALLOC_HOST_PTR |
  44.                  CL_MEM_COPY_HOST_PTR))
  45.       throw error(CL_INVALID_VALUE);
  46.  
  47.    ret_error(errcode_ret, CL_SUCCESS);
  48.    return new root_buffer(*ctx, flags, size, host_ptr);
  49.  
  50. } catch (error &e) {
  51.    ret_error(errcode_ret, e);
  52.    return NULL;
  53. }
  54.  
  55. PUBLIC cl_mem
  56. clCreateSubBuffer(cl_mem obj, cl_mem_flags flags, cl_buffer_create_type op,
  57.                   const void *op_info, cl_int *errcode_ret) try {
  58.    root_buffer *parent = dynamic_cast<root_buffer *>(obj);
  59.  
  60.    if (!parent)
  61.       throw error(CL_INVALID_MEM_OBJECT);
  62.  
  63.    if ((flags & (CL_MEM_USE_HOST_PTR |
  64.                  CL_MEM_ALLOC_HOST_PTR |
  65.                  CL_MEM_COPY_HOST_PTR)) ||
  66.        (~flags & parent->flags() & (CL_MEM_READ_ONLY |
  67.                                     CL_MEM_WRITE_ONLY)))
  68.       throw error(CL_INVALID_VALUE);
  69.  
  70.    if (op == CL_BUFFER_CREATE_TYPE_REGION) {
  71.       const cl_buffer_region *reg = (const cl_buffer_region *)op_info;
  72.  
  73.       if (!reg ||
  74.           reg->origin > parent->size() ||
  75.           reg->origin + reg->size > parent->size())
  76.          throw error(CL_INVALID_VALUE);
  77.  
  78.       if (!reg->size)
  79.          throw error(CL_INVALID_BUFFER_SIZE);
  80.  
  81.       ret_error(errcode_ret, CL_SUCCESS);
  82.       return new sub_buffer(*parent, flags, reg->origin, reg->size);
  83.  
  84.    } else {
  85.       throw error(CL_INVALID_VALUE);
  86.    }
  87.  
  88. } catch (error &e) {
  89.    ret_error(errcode_ret, e);
  90.    return NULL;
  91. }
  92.  
  93. PUBLIC cl_mem
  94. clCreateImage2D(cl_context ctx, cl_mem_flags flags,
  95.                 const cl_image_format *format,
  96.                 size_t width, size_t height, size_t row_pitch,
  97.                 void *host_ptr, cl_int *errcode_ret) try {
  98.    if (!ctx)
  99.       throw error(CL_INVALID_CONTEXT);
  100.  
  101.    if (flags & ~(CL_MEM_READ_WRITE | CL_MEM_WRITE_ONLY | CL_MEM_READ_ONLY |
  102.                  CL_MEM_USE_HOST_PTR | CL_MEM_ALLOC_HOST_PTR |
  103.                  CL_MEM_COPY_HOST_PTR))
  104.       throw error(CL_INVALID_VALUE);
  105.  
  106.    if (!format)
  107.       throw error(CL_INVALID_IMAGE_FORMAT_DESCRIPTOR);
  108.  
  109.    if (width < 1 || height < 1)
  110.       throw error(CL_INVALID_IMAGE_SIZE);
  111.  
  112.    if (bool(host_ptr) != bool(flags & (CL_MEM_USE_HOST_PTR |
  113.                                        CL_MEM_COPY_HOST_PTR)))
  114.       throw error(CL_INVALID_HOST_PTR);
  115.  
  116.    if (!supported_formats(ctx, CL_MEM_OBJECT_IMAGE2D).count(*format))
  117.       throw error(CL_IMAGE_FORMAT_NOT_SUPPORTED);
  118.  
  119.    ret_error(errcode_ret, CL_SUCCESS);
  120.    return new image2d(*ctx, flags, format, width, height,
  121.                       row_pitch, host_ptr);
  122.  
  123. } catch (error &e) {
  124.    ret_error(errcode_ret, e);
  125.    return NULL;
  126. }
  127.  
  128. PUBLIC cl_mem
  129. clCreateImage3D(cl_context ctx, cl_mem_flags flags,
  130.                 const cl_image_format *format,
  131.                 size_t width, size_t height, size_t depth,
  132.                 size_t row_pitch, size_t slice_pitch,
  133.                 void *host_ptr, cl_int *errcode_ret) try {
  134.    if (!ctx)
  135.       throw error(CL_INVALID_CONTEXT);
  136.  
  137.    if (flags & ~(CL_MEM_READ_WRITE | CL_MEM_WRITE_ONLY | CL_MEM_READ_ONLY |
  138.                  CL_MEM_USE_HOST_PTR | CL_MEM_ALLOC_HOST_PTR |
  139.                  CL_MEM_COPY_HOST_PTR))
  140.       throw error(CL_INVALID_VALUE);
  141.  
  142.    if (!format)
  143.       throw error(CL_INVALID_IMAGE_FORMAT_DESCRIPTOR);
  144.  
  145.    if (width < 1 || height < 1 || depth < 2)
  146.       throw error(CL_INVALID_IMAGE_SIZE);
  147.  
  148.    if (bool(host_ptr) != bool(flags & (CL_MEM_USE_HOST_PTR |
  149.                                        CL_MEM_COPY_HOST_PTR)))
  150.       throw error(CL_INVALID_HOST_PTR);
  151.  
  152.    if (!supported_formats(ctx, CL_MEM_OBJECT_IMAGE3D).count(*format))
  153.       throw error(CL_IMAGE_FORMAT_NOT_SUPPORTED);
  154.  
  155.    ret_error(errcode_ret, CL_SUCCESS);
  156.    return new image3d(*ctx, flags, format, width, height, depth,
  157.                       row_pitch, slice_pitch, host_ptr);
  158.  
  159. } catch (error &e) {
  160.    ret_error(errcode_ret, e);
  161.    return NULL;
  162. }
  163.  
  164. PUBLIC cl_int
  165. clGetSupportedImageFormats(cl_context ctx, cl_mem_flags flags,
  166.                            cl_mem_object_type type, cl_uint count,
  167.                            cl_image_format *buf, cl_uint *count_ret) try {
  168.    if (!ctx)
  169.       throw error(CL_INVALID_CONTEXT);
  170.  
  171.    if (flags & ~(CL_MEM_READ_WRITE | CL_MEM_WRITE_ONLY | CL_MEM_READ_ONLY |
  172.                  CL_MEM_USE_HOST_PTR | CL_MEM_ALLOC_HOST_PTR |
  173.                  CL_MEM_COPY_HOST_PTR))
  174.       throw error(CL_INVALID_VALUE);
  175.  
  176.    if (!count && buf)
  177.       throw error(CL_INVALID_VALUE);
  178.  
  179.    auto formats = supported_formats(ctx, type);
  180.  
  181.    if (buf)
  182.       std::copy_n(formats.begin(), std::min((cl_uint)formats.size(), count),
  183.                   buf);
  184.    if (count_ret)
  185.       *count_ret = formats.size();
  186.  
  187.    return CL_SUCCESS;
  188.  
  189. } catch (error &e) {
  190.    return e.get();
  191. }
  192.  
  193. PUBLIC cl_int
  194. clGetMemObjectInfo(cl_mem obj, cl_mem_info param,
  195.                    size_t size, void *buf, size_t *size_ret) {
  196.    if (!obj)
  197.       return CL_INVALID_MEM_OBJECT;
  198.  
  199.    switch (param) {
  200.    case CL_MEM_TYPE:
  201.       return scalar_property<cl_mem_object_type>(buf, size, size_ret,
  202.                                                  obj->type());
  203.  
  204.    case CL_MEM_FLAGS:
  205.       return scalar_property<cl_mem_flags>(buf, size, size_ret, obj->flags());
  206.  
  207.    case CL_MEM_SIZE:
  208.       return scalar_property<size_t>(buf, size, size_ret, obj->size());
  209.  
  210.    case CL_MEM_HOST_PTR:
  211.       return scalar_property<void *>(buf, size, size_ret, obj->host_ptr());
  212.  
  213.    case CL_MEM_MAP_COUNT:
  214.       return scalar_property<cl_uint>(buf, size, size_ret, 0);
  215.  
  216.    case CL_MEM_REFERENCE_COUNT:
  217.       return scalar_property<cl_uint>(buf, size, size_ret, obj->ref_count());
  218.  
  219.    case CL_MEM_CONTEXT:
  220.       return scalar_property<cl_context>(buf, size, size_ret, &obj->ctx);
  221.  
  222.    case CL_MEM_ASSOCIATED_MEMOBJECT: {
  223.       sub_buffer *sub = dynamic_cast<sub_buffer *>(obj);
  224.       return scalar_property<cl_mem>(buf, size, size_ret,
  225.                                      (sub ? &sub->parent : NULL));
  226.    }
  227.    case CL_MEM_OFFSET: {
  228.       sub_buffer *sub = dynamic_cast<sub_buffer *>(obj);
  229.       return scalar_property<size_t>(buf, size, size_ret,
  230.                                      (sub ? sub->offset() : 0));
  231.    }
  232.    default:
  233.       return CL_INVALID_VALUE;
  234.    }
  235. }
  236.  
  237. PUBLIC cl_int
  238. clGetImageInfo(cl_mem obj, cl_image_info param,
  239.                size_t size, void *buf, size_t *size_ret) {
  240.    image *img = dynamic_cast<image *>(obj);
  241.    if (!img)
  242.       return CL_INVALID_MEM_OBJECT;
  243.  
  244.    switch (param) {
  245.    case CL_IMAGE_FORMAT:
  246.       return scalar_property<cl_image_format>(buf, size, size_ret,
  247.                                               img->format());
  248.  
  249.    case CL_IMAGE_ELEMENT_SIZE:
  250.       return scalar_property<size_t>(buf, size, size_ret, 0);
  251.  
  252.    case CL_IMAGE_ROW_PITCH:
  253.       return scalar_property<size_t>(buf, size, size_ret, img->row_pitch());
  254.  
  255.    case CL_IMAGE_SLICE_PITCH:
  256.       return scalar_property<size_t>(buf, size, size_ret, img->slice_pitch());
  257.  
  258.    case CL_IMAGE_WIDTH:
  259.       return scalar_property<size_t>(buf, size, size_ret, img->width());
  260.  
  261.    case CL_IMAGE_HEIGHT:
  262.       return scalar_property<size_t>(buf, size, size_ret, img->height());
  263.  
  264.    case CL_IMAGE_DEPTH:
  265.       return scalar_property<size_t>(buf, size, size_ret, img->depth());
  266.  
  267.    default:
  268.       return CL_INVALID_VALUE;
  269.    }
  270. }
  271.  
  272. PUBLIC cl_int
  273. clRetainMemObject(cl_mem obj) {
  274.    if (!obj)
  275.       return CL_INVALID_MEM_OBJECT;
  276.  
  277.    obj->retain();
  278.    return CL_SUCCESS;
  279. }
  280.  
  281. PUBLIC cl_int
  282. clReleaseMemObject(cl_mem obj) {
  283.    if (!obj)
  284.       return CL_INVALID_MEM_OBJECT;
  285.  
  286.    if (obj->release())
  287.       delete obj;
  288.  
  289.    return CL_SUCCESS;
  290. }
  291.  
  292. PUBLIC cl_int
  293. clSetMemObjectDestructorCallback(cl_mem obj,
  294.                                  void (CL_CALLBACK *pfn_notify)(cl_mem, void *),
  295.                                  void *user_data) {
  296.    if (!obj)
  297.       return CL_INVALID_MEM_OBJECT;
  298.  
  299.    if (!pfn_notify)
  300.       return CL_INVALID_VALUE;
  301.  
  302.    obj->destroy_notify([=]{ pfn_notify(obj, user_data); });
  303.  
  304.    return CL_SUCCESS;
  305. }
  306.