1/* 2 * cl_va_memory.cpp - CL va memory 3 * 4 * Copyright (c) 2015 Intel Corporation 5 * 6 * Licensed under the Apache License, Version 2.0 (the "License"); 7 * you may not use this file except in compliance with the License. 8 * You may obtain a copy of the License at 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, software 13 * distributed under the License is distributed on an "AS IS" BASIS, 14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 * See the License for the specific language governing permissions and 16 * limitations under the License. 17 * 18 * Author: Wind Yuan <feng.yuan@intel.com> 19 */ 20 21#include "cl_va_memory.h" 22#include "cl_image_bo_buffer.h" 23 24namespace XCam { 25 26CLVaBuffer::CLVaBuffer ( 27 const SmartPtr<CLIntelContext> &context, 28 SmartPtr<DrmBoBuffer> &bo) 29 : CLBuffer (context) 30 , _bo (bo) 31{ 32 init_va_buffer (context, bo); 33} 34 35bool 36CLVaBuffer::init_va_buffer (const SmartPtr<CLIntelContext> &context, SmartPtr<DrmBoBuffer> &bo) 37{ 38 cl_mem mem_id = NULL; 39 uint32_t bo_name = 0; 40 cl_import_buffer_info_intel import_buffer_info; 41 42 xcam_mem_clear (import_buffer_info); 43 import_buffer_info.fd = bo->get_fd (); 44 import_buffer_info.size = bo->get_size (); 45 if (import_buffer_info.fd != -1) { 46 mem_id = context->import_dma_buffer (import_buffer_info); 47 } 48 49 if (mem_id == NULL) { 50 drm_intel_bo_flink (bo->get_bo (), &bo_name); 51 mem_id = context->create_va_buffer (bo_name); 52 if (mem_id == NULL) { 53 XCAM_LOG_WARNING ("CLVaBuffer create va buffer failed"); 54 return false; 55 } 56 } 57 58 set_mem_id (mem_id); 59 return true; 60} 61 62CLVaImage::CLVaImage ( 63 const SmartPtr<CLIntelContext> &context, 64 SmartPtr<DrmBoBuffer> &bo, 65 uint32_t offset, 66 bool single_plane) 67 : CLImage (context) 68 , _bo (bo) 69{ 70 CLImageDesc cl_desc; 71 72 const VideoBufferInfo & video_info = bo->get_video_info (); 73 if (!video_info_2_cl_image_desc (video_info, cl_desc)) { 74 XCAM_LOG_WARNING ("CLVaImage create va image failed on default videoinfo"); 75 return; 76 } 77 if (single_plane) { 78 cl_desc.array_size = 0; 79 cl_desc.slice_pitch = 0; 80 } else if (!merge_multi_plane (video_info, cl_desc)) { 81 XCAM_LOG_WARNING ("CLVaImage create va image failed on merging planes"); 82 return; 83 } 84 85 init_va_image (context, bo, cl_desc, offset); 86} 87 88CLVaImage::CLVaImage ( 89 const SmartPtr<CLIntelContext> &context, 90 SmartPtr<DrmBoBuffer> &bo, 91 const CLImageDesc &image_info, 92 uint32_t offset) 93 : CLImage (context) 94 , _bo (bo) 95{ 96 init_va_image (context, bo, image_info, offset); 97} 98 99bool 100CLVaImage::merge_multi_plane ( 101 const VideoBufferInfo &video_info, 102 CLImageDesc &cl_desc) 103{ 104 if (cl_desc.array_size <= 1) 105 return true; 106 107 switch (video_info.format) { 108 case V4L2_PIX_FMT_NV12: 109 cl_desc.height = video_info.aligned_height + video_info.height / 2; 110 break; 111 112 case XCAM_PIX_FMT_RGB48_planar: 113 case XCAM_PIX_FMT_RGB24_planar: 114 cl_desc.height = video_info.aligned_height * 3; 115 break; 116 117 case XCAM_PIX_FMT_SGRBG16_planar: 118 case XCAM_PIX_FMT_SGRBG8_planar: 119 cl_desc.height = video_info.aligned_height * 4; 120 break; 121 122 default: 123 XCAM_LOG_WARNING ("CLVaImage unknown format(%s) plane change", xcam_fourcc_to_string(video_info.format)); 124 return false; 125 } 126 cl_desc.array_size = 0; 127 cl_desc.slice_pitch = 0; 128 return true; 129} 130 131bool 132CLVaImage::init_va_image ( 133 const SmartPtr<CLIntelContext> &context, SmartPtr<DrmBoBuffer> &bo, 134 const CLImageDesc &cl_desc, uint32_t offset) 135{ 136 137 uint32_t bo_name = 0; 138 cl_mem mem_id = 0; 139 bool need_create = true; 140 cl_libva_image va_image_info; 141 cl_import_image_info_intel import_image_info; 142 143 xcam_mem_clear (va_image_info); 144 xcam_mem_clear (import_image_info); 145 import_image_info.offset = va_image_info.offset = offset; 146 import_image_info.width = va_image_info.width = cl_desc.width; 147 import_image_info.height = va_image_info.height = cl_desc.height; 148 import_image_info.fmt = va_image_info.fmt = cl_desc.format; 149 import_image_info.row_pitch = va_image_info.row_pitch = cl_desc.row_pitch; 150 import_image_info.size = cl_desc.size; 151 import_image_info.type = CL_MEM_OBJECT_IMAGE2D; 152 153 XCAM_ASSERT (bo.ptr ()); 154 155 SmartPtr<CLImageBoBuffer> cl_image_buffer = bo.dynamic_cast_ptr<CLImageBoBuffer> (); 156 if (cl_image_buffer.ptr ()) { 157 SmartPtr<CLImage> cl_image_data = cl_image_buffer->get_cl_image (); 158 XCAM_ASSERT (cl_image_data.ptr ()); 159 CLImageDesc old_desc = cl_image_data->get_image_desc (); 160 if (cl_desc == old_desc) { 161 need_create = false; 162 mem_id = cl_image_data->get_mem_id (); 163 } 164 } 165 166 if (need_create) { 167 import_image_info.fd = bo->get_fd(); 168 if (import_image_info.fd != -1) 169 mem_id = context->import_dma_image (import_image_info); 170 171 if (mem_id == NULL) { 172 if (drm_intel_bo_flink (bo->get_bo (), &bo_name) == 0) { 173 va_image_info.bo_name = bo_name; 174 mem_id = context->create_va_image (va_image_info); 175 } 176 if (mem_id == NULL) { 177 XCAM_LOG_WARNING ("create va image failed"); 178 return false; 179 } 180 } 181 } else { 182 va_image_info.bo_name = uint32_t(-1); 183 } 184 185 set_mem_id (mem_id, need_create); 186 init_desc_by_image (); 187 _va_image_info = va_image_info; 188 return true; 189} 190 191}; 192