xref: /aosp_15_r20/external/angle/src/libANGLE/CLMemory.cpp (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
1 //
2 // Copyright 2021 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6 // CLMemory.cpp: Implements the cl::Memory class.
7 
8 #include "libANGLE/CLMemory.h"
9 
10 #include "libANGLE/CLBuffer.h"
11 #include "libANGLE/CLContext.h"
12 #include "libANGLE/CLImage.h"
13 #include "libANGLE/cl_utils.h"
14 
15 #include <cstring>
16 
17 namespace cl
18 {
19 
20 namespace
21 {
22 
InheritMemFlags(MemFlags flags,Memory * parent)23 MemFlags InheritMemFlags(MemFlags flags, Memory *parent)
24 {
25     if (parent != nullptr)
26     {
27         const MemFlags parentFlags = parent->getFlags();
28         const MemFlags access(CL_MEM_READ_WRITE | CL_MEM_READ_ONLY | CL_MEM_WRITE_ONLY);
29         const MemFlags hostAccess(CL_MEM_HOST_WRITE_ONLY | CL_MEM_HOST_READ_ONLY |
30                                   CL_MEM_HOST_NO_ACCESS);
31         const MemFlags hostPtrFlags(CL_MEM_USE_HOST_PTR | CL_MEM_ALLOC_HOST_PTR |
32                                     CL_MEM_COPY_HOST_PTR);
33         if (flags.excludes(access))
34         {
35             flags.set(parentFlags.mask(access));
36         }
37         if (flags.excludes(hostAccess))
38         {
39             flags.set(parentFlags.mask(hostAccess));
40         }
41         flags.set(parentFlags.mask(hostPtrFlags));
42     }
43     return flags;
44 }
45 
46 }  // namespace
47 
setDestructorCallback(MemoryCB pfnNotify,void * userData)48 angle::Result Memory::setDestructorCallback(MemoryCB pfnNotify, void *userData)
49 {
50     mDestructorCallbacks->emplace(pfnNotify, userData);
51     return angle::Result::Continue;
52 }
53 
getInfo(MemInfo name,size_t valueSize,void * value,size_t * valueSizeRet) const54 angle::Result Memory::getInfo(MemInfo name,
55                               size_t valueSize,
56                               void *value,
57                               size_t *valueSizeRet) const
58 {
59     static_assert(
60         std::is_same<cl_uint, cl_bool>::value && std::is_same<cl_uint, cl_mem_object_type>::value,
61         "OpenCL type mismatch");
62 
63     cl_uint valUInt       = 0u;
64     void *valPointer      = nullptr;
65     const void *copyValue = nullptr;
66     size_t copySize       = 0u;
67 
68     switch (name)
69     {
70         case MemInfo::Type:
71             valUInt   = ToCLenum(getType());
72             copyValue = &valUInt;
73             copySize  = sizeof(valUInt);
74             break;
75         case MemInfo::Flags:
76             copyValue = &mFlags;
77             copySize  = sizeof(mFlags);
78             break;
79         case MemInfo::Size:
80             copyValue = &mSize;
81             copySize  = sizeof(mSize);
82             break;
83         case MemInfo::HostPtr:
84             copyValue = &mHostPtr;
85             copySize  = sizeof(mHostPtr);
86             break;
87         case MemInfo::MapCount:
88             valUInt   = mMapCount;
89             copyValue = &valUInt;
90             copySize  = sizeof(valUInt);
91             break;
92         case MemInfo::ReferenceCount:
93             valUInt   = getRefCount();
94             copyValue = &valUInt;
95             copySize  = sizeof(valUInt);
96             break;
97         case MemInfo::Context:
98             valPointer = mContext->getNative();
99             copyValue  = &valPointer;
100             copySize   = sizeof(valPointer);
101             break;
102         case MemInfo::AssociatedMemObject:
103             valPointer = Memory::CastNative(mParent.get());
104             copyValue  = &valPointer;
105             copySize   = sizeof(valPointer);
106             break;
107         case MemInfo::Offset:
108             copyValue = &mOffset;
109             copySize  = sizeof(mOffset);
110             break;
111         case MemInfo::UsesSVM_Pointer:
112             valUInt   = CL_FALSE;  // TODO(jplate) Check for SVM pointer anglebug.com/42264535
113             copyValue = &valUInt;
114             copySize  = sizeof(valUInt);
115             break;
116         case MemInfo::Properties:
117             copyValue = mProperties.data();
118             copySize  = mProperties.size() * sizeof(decltype(mProperties)::value_type);
119             break;
120         default:
121             ANGLE_CL_RETURN_ERROR(CL_INVALID_VALUE);
122     }
123 
124     if (value != nullptr)
125     {
126         // CL_INVALID_VALUE if size in bytes specified by param_value_size is < size of return type
127         // as described in the Memory Object Info table and param_value is not NULL.
128         if (valueSize < copySize)
129         {
130             ANGLE_CL_RETURN_ERROR(CL_INVALID_VALUE);
131         }
132         if (copyValue != nullptr)
133         {
134             std::memcpy(value, copyValue, copySize);
135         }
136     }
137     if (valueSizeRet != nullptr)
138     {
139         *valueSizeRet = copySize;
140     }
141     return angle::Result::Continue;
142 }
143 
~Memory()144 Memory::~Memory()
145 {
146     std::stack<CallbackData> callbacks;
147     mDestructorCallbacks->swap(callbacks);
148     while (!callbacks.empty())
149     {
150         const MemoryCB callback = callbacks.top().first;
151         void *const userData    = callbacks.top().second;
152         callbacks.pop();
153         callback(this, userData);
154     }
155 }
156 
Memory(const Buffer & buffer,Context & context,PropArray && properties,MemFlags flags,size_t size,void * hostPtr)157 Memory::Memory(const Buffer &buffer,
158                Context &context,
159                PropArray &&properties,
160                MemFlags flags,
161                size_t size,
162                void *hostPtr)
163     : mContext(&context),
164       mProperties(std::move(properties)),
165       mFlags(flags.excludes(CL_MEM_READ_WRITE | CL_MEM_READ_ONLY | CL_MEM_WRITE_ONLY)
166                  ? cl::MemFlags{flags.get() | CL_MEM_READ_WRITE}
167                  : flags),
168       mHostPtr(flags.intersects(CL_MEM_USE_HOST_PTR) ? hostPtr : nullptr),
169       mImpl(nullptr),
170       mSize(size),
171       mMapCount(0u)
172 {
173     ANGLE_CL_IMPL_TRY(context.getImpl().createBuffer(buffer, hostPtr, &mImpl));
174 }
175 
Memory(const Buffer & buffer,Buffer & parent,MemFlags flags,size_t offset,size_t size)176 Memory::Memory(const Buffer &buffer, Buffer &parent, MemFlags flags, size_t offset, size_t size)
177     : mContext(parent.mContext),
178       mFlags(InheritMemFlags(flags, &parent)),
179       mHostPtr(parent.mHostPtr != nullptr ? static_cast<char *>(parent.mHostPtr) + offset
180                                           : nullptr),
181       mParent(&parent),
182       mOffset(offset),
183       mImpl(nullptr),
184       mSize(size),
185       mMapCount(0u)
186 {
187     ANGLE_CL_IMPL_TRY(parent.mImpl->createSubBuffer(buffer, flags, size, &mImpl));
188 }
189 
Memory(Context & context,PropArray && properties,MemFlags flags,Memory * parent,void * hostPtr)190 Memory::Memory(Context &context,
191                PropArray &&properties,
192                MemFlags flags,
193                Memory *parent,
194                void *hostPtr)
195     : mContext(&context),
196       mProperties(std::move(properties)),
197       mFlags(InheritMemFlags(flags, parent)),
198       mHostPtr(flags.intersects(CL_MEM_USE_HOST_PTR) ? hostPtr : nullptr),
199       mParent(parent),
200       mImpl(nullptr),
201       mSize(0u),
202       mMapCount(0u)
203 {}
204 
205 }  // namespace cl
206