diff options
Diffstat (limited to 'src/gallium/state_trackers/clover/api/memory.cpp')
-rw-r--r-- | src/gallium/state_trackers/clover/api/memory.cpp | 69 |
1 files changed, 61 insertions, 8 deletions
diff --git a/src/gallium/state_trackers/clover/api/memory.cpp b/src/gallium/state_trackers/clover/api/memory.cpp index 6a0717680cf..107815bde72 100644 --- a/src/gallium/state_trackers/clover/api/memory.cpp +++ b/src/gallium/state_trackers/clover/api/memory.cpp @@ -29,15 +29,20 @@ using namespace clover; namespace { cl_mem_flags - validate_flags(cl_mem d_parent, cl_mem_flags d_flags) { + validate_flags(cl_mem d_parent, cl_mem_flags d_flags, bool svm) { 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 svm_flags = + CL_MEM_SVM_FINE_GRAIN_BUFFER | CL_MEM_SVM_ATOMICS; + const cl_mem_flags valid_flags = - dev_access_flags | host_access_flags | (d_parent ? 0 : host_ptr_flags); + dev_access_flags + | (svm || d_parent ? 0 : host_ptr_flags) + | (svm ? svm_flags : host_access_flags); if ((d_flags & ~valid_flags) || util_bitcount(d_flags & dev_access_flags) > 1 || @@ -48,6 +53,10 @@ namespace { (d_flags & (CL_MEM_COPY_HOST_PTR | CL_MEM_ALLOC_HOST_PTR))) throw error(CL_INVALID_VALUE); + if ((d_flags & CL_MEM_SVM_ATOMICS) && + !(d_flags & CL_MEM_SVM_FINE_GRAIN_BUFFER)) + throw error(CL_INVALID_VALUE); + if (d_parent) { const auto &parent = obj(d_parent); const cl_mem_flags flags = (d_flags | @@ -77,7 +86,7 @@ namespace { 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 = validate_flags(NULL, d_flags); + const cl_mem_flags flags = validate_flags(NULL, d_flags, false); auto &ctx = obj(d_ctx); if (bool(host_ptr) != bool(flags & (CL_MEM_USE_HOST_PTR | @@ -103,7 +112,7 @@ 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 = validate_flags(d_mem, d_flags); + const cl_mem_flags flags = validate_flags(d_mem, d_flags, false); if (op == CL_BUFFER_CREATE_TYPE_REGION) { auto reg = reinterpret_cast<const cl_buffer_region *>(op_info); @@ -163,7 +172,7 @@ clCreateImage(cl_context d_ctx, cl_mem_flags d_flags, CL_MEM_COPY_HOST_PTR))) throw error(CL_INVALID_HOST_PTR); - const cl_mem_flags flags = validate_flags(desc->buffer, d_flags); + const cl_mem_flags flags = validate_flags(desc->buffer, d_flags, false); if (!supported_formats(ctx, desc->image_type).count(*format)) throw error(CL_IMAGE_FORMAT_NOT_SUPPORTED); @@ -249,7 +258,7 @@ clGetSupportedImageFormats(cl_context d_ctx, cl_mem_flags flags, auto &ctx = obj(d_ctx); auto formats = supported_formats(ctx, type); - validate_flags(NULL, flags); + validate_flags(NULL, flags, false); if (r_buf && !r_count) throw error(CL_INVALID_VALUE); @@ -313,6 +322,15 @@ clGetMemObjectInfo(cl_mem d_mem, cl_mem_info param, buf.as_scalar<size_t>() = (sub ? sub->offset() : 0); break; } + case CL_MEM_USES_SVM_POINTER: { + // with system SVM all host ptrs are SVM pointers + // TODO: once we support devices with lower levels of SVM, we have to + // check the ptr in more detail + const bool system_svm = all_of(std::mem_fn(&device::has_system_svm), + mem.context().devices()); + buf.as_scalar<cl_bool>() = mem.host_ptr() && system_svm; + break; + } default: throw error(CL_INVALID_VALUE); } @@ -431,13 +449,48 @@ CLOVER_API void * clSVMAlloc(cl_context d_ctx, cl_svm_mem_flags flags, size_t size, - unsigned int alignment) { + unsigned int alignment) try { + auto &ctx = obj(d_ctx); + validate_flags(NULL, flags, true); + + if (!size || + size > fold(minimum(), cl_ulong(ULONG_MAX), + map(std::mem_fn(&device::max_mem_alloc_size), ctx.devices()))) + return nullptr; + + if (!util_is_power_of_two_or_zero(alignment)) + return nullptr; + + if (!alignment) + alignment = 0x80; // sizeof(long16) + + bool can_emulate = all_of(std::mem_fn(&device::has_system_svm), ctx.devices()); + if (can_emulate) { + // we can ignore all the flags as it's not required to honor them. + void *ptr = nullptr; + if (alignment < sizeof(void*)) + alignment = sizeof(void*); + posix_memalign(&ptr, alignment, size); + return ptr; + } + CLOVER_NOT_SUPPORTED_UNTIL("2.0"); return nullptr; + +} catch (error &e) { + return nullptr; } CLOVER_API void clSVMFree(cl_context d_ctx, - void *svm_pointer) { + void *svm_pointer) try { + auto &ctx = obj(d_ctx); + bool can_emulate = all_of(std::mem_fn(&device::has_system_svm), ctx.devices()); + + if (can_emulate) + return free(svm_pointer); + CLOVER_NOT_SUPPORTED_UNTIL("2.0"); + +} catch (error &e) { } |