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
24 namespace XCam {
25
CLVaBuffer(const SmartPtr<CLIntelContext> & context,SmartPtr<DrmBoBuffer> & bo)26 CLVaBuffer::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
35 bool
init_va_buffer(const SmartPtr<CLIntelContext> & context,SmartPtr<DrmBoBuffer> & bo)36 CLVaBuffer::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
CLVaImage(const SmartPtr<CLIntelContext> & context,SmartPtr<DrmBoBuffer> & bo,uint32_t offset,bool single_plane)62 CLVaImage::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
CLVaImage(const SmartPtr<CLIntelContext> & context,SmartPtr<DrmBoBuffer> & bo,const CLImageDesc & image_info,uint32_t offset)88 CLVaImage::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
99 bool
merge_multi_plane(const VideoBufferInfo & video_info,CLImageDesc & cl_desc)100 CLVaImage::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
131 bool
init_va_image(const SmartPtr<CLIntelContext> & context,SmartPtr<DrmBoBuffer> & bo,const CLImageDesc & cl_desc,uint32_t offset)132 CLVaImage::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