st/nine: Add debug warning when application uses sw processing
[mesa.git] / src / gallium / state_trackers / clover / api / memory.cpp
index b01a1bc5bd1cc755ef5b097c6b2bbad97db41d5e..3ff6ba0e1c505342f773a419a5aac3f3eceb7ad3 100644 (file)
 // OTHER DEALINGS IN THE SOFTWARE.
 //
 
+#include "util/u_math.h"
 #include "api/util.hpp"
 #include "core/memory.hpp"
 #include "core/format.hpp"
 
 using namespace clover;
 
-PUBLIC cl_mem
-clCreateBuffer(cl_context d_ctx, cl_mem_flags flags, size_t size,
+namespace {
+   const cl_mem_flags dev_access_flags =
+      CL_MEM_READ_WRITE | CL_MEM_WRITE_ONLY | CL_MEM_READ_ONLY;
+   const cl_mem_flags host_ptr_flags =
+      CL_MEM_USE_HOST_PTR | CL_MEM_ALLOC_HOST_PTR | CL_MEM_COPY_HOST_PTR;
+   const cl_mem_flags host_access_flags =
+      CL_MEM_HOST_WRITE_ONLY | CL_MEM_HOST_READ_ONLY | CL_MEM_HOST_NO_ACCESS;
+   const cl_mem_flags all_mem_flags =
+      dev_access_flags | host_ptr_flags | host_access_flags;
+
+   void
+   validate_flags(cl_mem_flags flags, cl_mem_flags valid) {
+      if ((flags & ~valid) ||
+          util_bitcount(flags & dev_access_flags) > 1 ||
+          util_bitcount(flags & host_access_flags) > 1)
+         throw error(CL_INVALID_VALUE);
+
+      if ((flags & CL_MEM_USE_HOST_PTR) &&
+          (flags & (CL_MEM_COPY_HOST_PTR | CL_MEM_ALLOC_HOST_PTR)))
+         throw error(CL_INVALID_VALUE);
+   }
+}
+
+CLOVER_API cl_mem
+clCreateBuffer(cl_context d_ctx, cl_mem_flags d_flags, size_t size,
                void *host_ptr, cl_int *r_errcode) try {
+   const cl_mem_flags flags = d_flags |
+      (d_flags & dev_access_flags ? 0 : CL_MEM_READ_WRITE);
    auto &ctx = obj(d_ctx);
 
+   validate_flags(d_flags, all_mem_flags);
+
    if (bool(host_ptr) != bool(flags & (CL_MEM_USE_HOST_PTR |
                                        CL_MEM_COPY_HOST_PTR)))
       throw error(CL_INVALID_HOST_PTR);
 
-   if (!size)
+   if (!size ||
+       size > fold(maximum(), cl_ulong(0),
+                   map(std::mem_fn(&device::max_mem_alloc_size), ctx.devices())
+          ))
       throw error(CL_INVALID_BUFFER_SIZE);
 
-   if (flags & ~(CL_MEM_READ_WRITE | 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(r_errcode, CL_SUCCESS);
    return new root_buffer(ctx, flags, size, host_ptr);
 
@@ -51,17 +77,20 @@ clCreateBuffer(cl_context d_ctx, cl_mem_flags flags, size_t size,
    return NULL;
 }
 
-PUBLIC cl_mem
-clCreateSubBuffer(cl_mem d_mem, cl_mem_flags flags,
+CLOVER_API cl_mem
+clCreateSubBuffer(cl_mem d_mem, cl_mem_flags d_flags,
                   cl_buffer_create_type op,
                   const void *op_info, cl_int *r_errcode) try {
    auto &parent = obj<root_buffer>(d_mem);
+   const cl_mem_flags flags = d_flags |
+      (d_flags & dev_access_flags ? 0 : parent.flags() & dev_access_flags) |
+      (d_flags & host_access_flags ? 0 : parent.flags() & host_access_flags) |
+      (parent.flags() & host_ptr_flags);
 
-   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)))
+   validate_flags(d_flags, dev_access_flags | host_access_flags);
+
+   if (~flags & parent.flags() &
+       ((dev_access_flags & ~CL_MEM_READ_WRITE) | host_access_flags))
       throw error(CL_INVALID_VALUE);
 
    if (op == CL_BUFFER_CREATE_TYPE_REGION) {
@@ -87,17 +116,19 @@ clCreateSubBuffer(cl_mem d_mem, cl_mem_flags flags,
    return NULL;
 }
 
-PUBLIC cl_mem
-clCreateImage2D(cl_context d_ctx, cl_mem_flags flags,
+CLOVER_API cl_mem
+clCreateImage2D(cl_context d_ctx, cl_mem_flags d_flags,
                 const cl_image_format *format,
                 size_t width, size_t height, size_t row_pitch,
                 void *host_ptr, cl_int *r_errcode) try {
+   const cl_mem_flags flags = d_flags |
+      (d_flags & dev_access_flags ? 0 : CL_MEM_READ_WRITE);
    auto &ctx = obj(d_ctx);
 
-   if (flags & ~(CL_MEM_READ_WRITE | 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);
+   validate_flags(d_flags, all_mem_flags);
+
+   if (!any_of(std::mem_fn(&device::image_support), ctx.devices()))
+      throw error(CL_INVALID_OPERATION);
 
    if (!format)
       throw error(CL_INVALID_IMAGE_FORMAT_DESCRIPTOR);
@@ -121,18 +152,20 @@ clCreateImage2D(cl_context d_ctx, cl_mem_flags flags,
    return NULL;
 }
 
-PUBLIC cl_mem
-clCreateImage3D(cl_context d_ctx, cl_mem_flags flags,
+CLOVER_API cl_mem
+clCreateImage3D(cl_context d_ctx, cl_mem_flags d_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 *r_errcode) try {
+   const cl_mem_flags flags = d_flags |
+      (d_flags & dev_access_flags ? 0 : CL_MEM_READ_WRITE);
    auto &ctx = obj(d_ctx);
 
-   if (flags & ~(CL_MEM_READ_WRITE | 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);
+   validate_flags(d_flags, all_mem_flags);
+
+   if (!any_of(std::mem_fn(&device::image_support), ctx.devices()))
+      throw error(CL_INVALID_OPERATION);
 
    if (!format)
       throw error(CL_INVALID_IMAGE_FORMAT_DESCRIPTOR);
@@ -156,22 +189,18 @@ clCreateImage3D(cl_context d_ctx, cl_mem_flags flags,
    return NULL;
 }
 
-PUBLIC cl_int
+CLOVER_API cl_int
 clGetSupportedImageFormats(cl_context d_ctx, cl_mem_flags flags,
                            cl_mem_object_type type, cl_uint count,
                            cl_image_format *r_buf, cl_uint *r_count) try {
    auto &ctx = obj(d_ctx);
+   auto formats = supported_formats(ctx, type);
 
-   if (flags & ~(CL_MEM_READ_WRITE | 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);
+   validate_flags(flags, all_mem_flags);
 
    if (r_buf && !r_count)
       throw error(CL_INVALID_VALUE);
 
-   auto formats = supported_formats(ctx, type);
-
    if (r_buf)
       std::copy_n(formats.begin(),
                   std::min((cl_uint)formats.size(), count),
@@ -186,7 +215,7 @@ clGetSupportedImageFormats(cl_context d_ctx, cl_mem_flags flags,
    return e.get();
 }
 
-PUBLIC cl_int
+CLOVER_API cl_int
 clGetMemObjectInfo(cl_mem d_mem, cl_mem_info param,
                    size_t size, void *r_buf, size_t *r_size) try {
    property_buffer buf { r_buf, size, r_size };
@@ -218,12 +247,12 @@ clGetMemObjectInfo(cl_mem d_mem, cl_mem_info param,
       break;
 
    case CL_MEM_CONTEXT:
-      buf.as_scalar<cl_context>() = desc(mem.ctx);
+      buf.as_scalar<cl_context>() = desc(mem.context());
       break;
 
    case CL_MEM_ASSOCIATED_MEMOBJECT: {
       sub_buffer *sub = dynamic_cast<sub_buffer *>(&mem);
-      buf.as_scalar<cl_mem>() = (sub ? desc(sub->parent) : NULL);
+      buf.as_scalar<cl_mem>() = (sub ? desc(sub->parent()) : NULL);
       break;
    }
    case CL_MEM_OFFSET: {
@@ -241,7 +270,7 @@ clGetMemObjectInfo(cl_mem d_mem, cl_mem_info param,
    return e.get();
 }
 
-PUBLIC cl_int
+CLOVER_API cl_int
 clGetImageInfo(cl_mem d_mem, cl_image_info param,
                size_t size, void *r_buf, size_t *r_size) try {
    property_buffer buf { r_buf, size, r_size };
@@ -286,7 +315,7 @@ clGetImageInfo(cl_mem d_mem, cl_image_info param,
    return e.get();
 }
 
-PUBLIC cl_int
+CLOVER_API cl_int
 clRetainMemObject(cl_mem d_mem) try {
    obj(d_mem).retain();
    return CL_SUCCESS;
@@ -295,7 +324,7 @@ clRetainMemObject(cl_mem d_mem) try {
    return e.get();
 }
 
-PUBLIC cl_int
+CLOVER_API cl_int
 clReleaseMemObject(cl_mem d_mem) try {
    if (obj(d_mem).release())
       delete pobj(d_mem);
@@ -306,7 +335,7 @@ clReleaseMemObject(cl_mem d_mem) try {
    return e.get();
 }
 
-PUBLIC cl_int
+CLOVER_API cl_int
 clSetMemObjectDestructorCallback(cl_mem d_mem,
                                  void (CL_CALLBACK *pfn_notify)(cl_mem, void *),
                                  void *user_data) try {
@@ -322,3 +351,15 @@ clSetMemObjectDestructorCallback(cl_mem d_mem,
 } catch (error &e) {
    return e.get();
 }
+
+CLOVER_API cl_mem
+clCreateImage(cl_context d_ctx, cl_mem_flags flags,
+              const cl_image_format *format,
+              const cl_image_desc *image_desc,
+              void *host_ptr, cl_int *r_errcode) {
+   // This function was added in OpenCL 1.2
+   std::cerr << "CL user error: clCreateImage() not supported by OpenCL 1.1." <<
+                std::endl;
+   ret_error(r_errcode, CL_INVALID_OPERATION);
+   return NULL;
+}