| 1026 | } |
| 1027 | |
| 1028 | amd::Image* ihipImageCreate(const cl_channel_order channelOrder, const cl_channel_type channelType, |
| 1029 | const cl_mem_object_type imageType, const size_t imageWidth, |
| 1030 | const size_t imageHeight, const size_t imageDepth, |
| 1031 | const size_t imageArraySize, const size_t imageRowPitch, |
| 1032 | const size_t imageSlicePitch, const uint32_t numMipLevels, |
| 1033 | const size_t offset, amd::Memory* buffer, hipError_t& status) { |
| 1034 | status = hipSuccess; |
| 1035 | const amd::Image::Format imageFormat({channelOrder, channelType}); |
| 1036 | if (!imageFormat.isValid()) { |
| 1037 | LogPrintfError("Invalid Image format for channel Order:%u Type:%u", channelOrder, channelType); |
| 1038 | status = hipErrorInvalidValue; |
| 1039 | return nullptr; |
| 1040 | } |
| 1041 | |
| 1042 | amd::Context& context = *hip::getCurrentDevice()->asContext(); |
| 1043 | if (!imageFormat.isSupported(context, imageType)) { |
| 1044 | LogPrintfError("Image type: %u not supported", imageType); |
| 1045 | status = hipErrorInvalidValue; |
| 1046 | return nullptr; |
| 1047 | } |
| 1048 | |
| 1049 | const std::vector<amd::Device*>& devices = context.devices(); |
| 1050 | if (!devices[0]->info().imageSupport_) { |
| 1051 | LogPrintfError("Device: 0x%x does not support image", devices[0]); |
| 1052 | status = hipErrorNotSupported; |
| 1053 | return nullptr; |
| 1054 | } |
| 1055 | |
| 1056 | if (!amd::Image::validateDimensions(devices, imageType, imageWidth, imageHeight, imageDepth, |
| 1057 | imageArraySize)) { |
| 1058 | DevLogError("Image does not have valid dimensions"); |
| 1059 | status = hipErrorInvalidValue; |
| 1060 | return nullptr; |
| 1061 | } |
| 1062 | |
| 1063 | if (numMipLevels > 0) { |
| 1064 | size_t max_dim = std::max(std::max(imageWidth, imageHeight), imageDepth); |
| 1065 | size_t mip_levels = 0; |
| 1066 | for (mip_levels = 0; max_dim > 0; max_dim >>= 1, mip_levels++); |
| 1067 | // empty for loop |
| 1068 | |
| 1069 | if (mip_levels < numMipLevels) { |
| 1070 | LogPrintfError("Invalid Mip Levels: %d", numMipLevels); |
| 1071 | status = hipErrorInvalidValue; |
| 1072 | return nullptr; |
| 1073 | } |
| 1074 | } |
| 1075 | |
| 1076 | // TODO validate the image descriptor. |
| 1077 | bool isExternalBuffer = buffer != nullptr ? buffer->isInterop() : false; |
| 1078 | amd::Image* image = nullptr; |
| 1079 | if (isExternalBuffer) { |
| 1080 | // We will create mipmap image view on top of external buffer which is from Vulkan or D3D |
| 1081 | // image. The buffer contains subchunks of tiled image, or it's just a linear image. Lower |
| 1082 | // level PAL will infer memory layout (offset, pitch, slice pitch, size) for each level |
| 1083 | // array in terms of tiling mode(linear or optimal), extent, format and mipmap levels. |
| 1084 | // Note that RocR will support mipmap in the future. |
| 1085 | switch (imageType) { |
no test coverage detected