| 1154 | } |
| 1155 | |
| 1156 | hipError_t ihipArrayCreate(hipArray_t* array, const HIP_ARRAY3D_DESCRIPTOR* pAllocateArray, |
| 1157 | unsigned int numMipmapLevels) { |
| 1158 | if (!array || !pAllocateArray) { |
| 1159 | return hipErrorInvalidValue; |
| 1160 | } |
| 1161 | // NumChannels specifies the number of packed components per HIP array element; it may be 1, 2, or |
| 1162 | // 4; |
| 1163 | if ((pAllocateArray->NumChannels != 1) && (pAllocateArray->NumChannels != 2) && |
| 1164 | (pAllocateArray->NumChannels != 4)) { |
| 1165 | return hipErrorInvalidValue; |
| 1166 | } |
| 1167 | unsigned int flags = hipArrayDefault | hipArrayLayered | hipArraySurfaceLoadStore | |
| 1168 | hipArrayTextureGather; // hipArrayCubemap isn't supported |
| 1169 | if (pAllocateArray->Flags & (~flags)) { |
| 1170 | return hipErrorInvalidValue; |
| 1171 | } |
| 1172 | if (pAllocateArray->Flags & hipArrayTextureGather) { |
| 1173 | // hipArrayTextureGather only works for 2D |
| 1174 | if (pAllocateArray->Width == 0 || pAllocateArray->Height == 0 || pAllocateArray->Depth > 0) |
| 1175 | return hipErrorInvalidValue; |
| 1176 | } |
| 1177 | |
| 1178 | const cl_channel_order channelOrder = hip::getCLChannelOrder(pAllocateArray->NumChannels, 0); |
| 1179 | const cl_channel_type channelType = |
| 1180 | hip::getCLChannelType(pAllocateArray->Format, hipReadModeElementType); |
| 1181 | const cl_mem_object_type imageType = hip::getCLMemObjectType( |
| 1182 | pAllocateArray->Width, pAllocateArray->Height, pAllocateArray->Depth, pAllocateArray->Flags); |
| 1183 | hipError_t status = hipSuccess; |
| 1184 | amd::Image* image = ihipImageCreate(channelOrder, channelType, imageType, pAllocateArray->Width, |
| 1185 | pAllocateArray->Height, pAllocateArray->Depth, |
| 1186 | // The number of layers is determined by the depth extent. |
| 1187 | pAllocateArray->Depth, /* array size */ |
| 1188 | 0, /* row pitch */ |
| 1189 | 0, /* slice pitch */ |
| 1190 | numMipmapLevels, 0, nullptr, /* buffer */ |
| 1191 | status); |
| 1192 | |
| 1193 | if (image == nullptr) { |
| 1194 | return status; |
| 1195 | } |
| 1196 | |
| 1197 | cl_mem memObj = as_cl<amd::Memory>(image); |
| 1198 | *array = new hipArray{reinterpret_cast<void*>(memObj)}; |
| 1199 | |
| 1200 | // It is UB to call hipGet*() on an array created via hipArrayCreate()/hipArray3DCreate(). |
| 1201 | // This is due to hip not differentiating between runtime and driver types. |
| 1202 | // TODO change the hipArray struct in driver_types.h. |
| 1203 | (*array)->desc = hip::getChannelFormatDesc(pAllocateArray->NumChannels, pAllocateArray->Format); |
| 1204 | (*array)->width = pAllocateArray->Width; |
| 1205 | (*array)->height = pAllocateArray->Height; |
| 1206 | (*array)->depth = pAllocateArray->Depth; |
| 1207 | (*array)->Format = pAllocateArray->Format; |
| 1208 | (*array)->NumChannels = pAllocateArray->NumChannels; |
| 1209 | (*array)->flags = pAllocateArray->Flags; |
| 1210 | { |
| 1211 | amd::ScopedLock lock(hipArraySetLock); |
| 1212 | hip::hipArraySet.insert(*array); |
| 1213 | } |
no test coverage detected