2 * Copyright © 2016 Intel Corporation
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the
6 * "Software"), to deal in the Software without restriction, including
7 * without limitation the rights to use, copy, modify, merge, publish,
8 * distribute, sub license, and/or sell copies of the Software, and to
9 * permit persons to whom the Software is furnished to do so, subject to
10 * the following conditions:
12 * The above copyright notice and this permission notice (including the
13 * next paragraph) shall be included in all copies or substantial portions
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
19 * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
20 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
21 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
22 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
31 #include "intel_batchbuffer.h"
32 #include "intel_driver.h"
33 #include "i965_drv_video.h"
34 #include "i965_post_processing.h"
35 #include "gen75_picture_process.h"
37 #include "intel_gen_vppapi.h"
38 #include "intel_common_vpp_internal.h"
41 intel_yuv420p8_scaling_post_processing(
43 struct i965_post_processing_context *pp_context,
44 struct i965_surface *src_surface,
45 VARectangle *src_rect,
46 struct i965_surface *dst_surface,
47 VARectangle *dst_rect)
49 struct i965_driver_data *i965 = i965_driver_data(ctx);
52 if (IS_GEN8(i965->intel.device_info))
53 va_status = gen8_yuv420p8_scaling_post_processing(ctx, pp_context,
59 va_status = gen9_yuv420p8_scaling_post_processing(ctx, pp_context,
69 intel_10bit_8bit_scaling_post_processing(VADriverContextP ctx,
70 struct i965_post_processing_context *pp_context,
71 struct i965_surface *src_surface,
72 VARectangle *src_rect,
73 struct i965_surface *dst_surface,
74 VARectangle *dst_rect)
76 struct i965_driver_data *i965 = i965_driver_data(ctx);
77 VAStatus va_status = VA_STATUS_ERROR_UNIMPLEMENTED;
79 if (IS_GEN9(i965->intel.device_info) ||
80 IS_GEN10(i965->intel.device_info))
81 va_status = gen9_10bit_8bit_scaling_post_processing(ctx, pp_context,
91 intel_8bit_420_rgb32_scaling_post_processing(VADriverContextP ctx,
92 struct i965_post_processing_context *pp_context,
93 struct i965_surface *src_surface,
94 VARectangle *src_rect,
95 struct i965_surface *dst_surface,
96 VARectangle *dst_rect)
98 struct i965_driver_data *i965 = i965_driver_data(ctx);
99 VAStatus va_status = VA_STATUS_ERROR_UNIMPLEMENTED;
101 if (IS_GEN8(i965->intel.device_info))
102 va_status = gen8_8bit_420_rgb32_scaling_post_processing(ctx, pp_context,
108 va_status = gen9_8bit_420_rgb32_scaling_post_processing(ctx, pp_context,
118 intel_common_scaling_post_processing(VADriverContextP ctx,
119 struct i965_post_processing_context *pp_context,
120 const struct i965_surface *src_surface,
121 const VARectangle *src_rect,
122 struct i965_surface *dst_surface,
123 const VARectangle *dst_rect)
125 struct i965_driver_data *i965 = i965_driver_data(ctx);
126 VAStatus status = VA_STATUS_ERROR_UNIMPLEMENTED;
127 VARectangle aligned_dst_rect;
128 int src_fourcc = pp_get_surface_fourcc(ctx, src_surface);
129 int dst_fourcc = pp_get_surface_fourcc(ctx, dst_surface);
130 unsigned int scale_flag = 0;
131 unsigned int tmp_width, tmp_x;
133 /* The Bit 2 is used to indicate that it is 10bit or 8bit.
134 * The Bit 0/1 is used to indicate the 420/422/444 format
136 #define SRC_8BIT_420 (1 << 0)
137 #define SRC_8BIT_422 (2 << 0)
138 #define SRC_8BIT_444 (3 << 0)
139 #define SRC_10BIT_420 (5 << 0)
140 #define SRC_10BIT_422 (6 << 0)
141 #define SRC_10BIT_444 (7 << 0)
143 /* The Bit 6 is used to indicate that it is 10bit or 8bit.
144 * The Bit 5/4 is used to indicate the 420/422/444 format
146 #define DST_8BIT_420 (1 << 4)
147 #define DST_8BIT_422 (2 << 0)
148 #define DST_8BIT_444 (3 << 0)
149 #define DST_10BIT_420 (5 << 4)
150 #define DST_10BIT_422 (6 << 4)
151 #define DST_10BIT_444 (7 << 4)
153 #define SRC_YUV_PACKED (1 << 3)
154 #define DST_YUV_PACKED (1 << 7)
156 #define SRC_RGB32 (1 << 8)
157 #define DST_RGB32 (1 << 12)
159 #define MASK_CSC (0xFFFF)
161 #define SCALE_10BIT_10BIT_420 (SRC_10BIT_420 | DST_10BIT_420)
162 #define SCALE_8BIT_8BIT_420 (SRC_8BIT_420 | DST_8BIT_420)
163 #define SCALE_10BIT420_8BIT422 (SRC_10BIT_420 | DST_8BIT_422 | DST_YUV_PACKED)
164 #define SCALE_10BIT420_8BIT420 (SRC_10BIT_420 | DST_8BIT_420)
165 #define SCALE_8BIT_420_RGB32 (SRC_8BIT_420 | DST_RGB32)
167 if (src_fourcc == VA_FOURCC_P010 ||
168 src_fourcc == VA_FOURCC_I010)
169 scale_flag |= SRC_10BIT_420;
171 if (src_fourcc == VA_FOURCC_NV12 ||
172 src_fourcc == VA_FOURCC_I420 ||
173 src_fourcc == VA_FOURCC_IMC3 ||
174 src_fourcc == VA_FOURCC_YV12 ||
175 src_fourcc == VA_FOURCC_IMC1)
176 scale_flag |= SRC_8BIT_420;
178 if (src_fourcc == VA_FOURCC_YUY2 ||
179 src_fourcc == VA_FOURCC_UYVY)
180 scale_flag |= (SRC_8BIT_422 | SRC_YUV_PACKED);
182 if (dst_fourcc == VA_FOURCC_P010 ||
183 dst_fourcc == VA_FOURCC_I010)
184 scale_flag |= DST_10BIT_420;
186 if (dst_fourcc == VA_FOURCC_NV12 ||
187 dst_fourcc == VA_FOURCC_I420 ||
188 dst_fourcc == VA_FOURCC_IMC3 ||
189 dst_fourcc == VA_FOURCC_YV12 ||
190 dst_fourcc == VA_FOURCC_IMC1)
191 scale_flag |= DST_8BIT_420;
193 if (dst_fourcc == VA_FOURCC_YUY2 ||
194 dst_fourcc == VA_FOURCC_UYVY)
195 scale_flag |= (DST_8BIT_422 | DST_YUV_PACKED);
197 if (dst_fourcc == VA_FOURCC_YUY2 ||
198 dst_fourcc == VA_FOURCC_UYVY)
199 scale_flag |= (DST_8BIT_422 | DST_YUV_PACKED);
201 if (dst_fourcc == VA_FOURCC_RGBX ||
202 dst_fourcc == VA_FOURCC_RGBA ||
203 dst_fourcc == VA_FOURCC_BGRX ||
204 dst_fourcc == VA_FOURCC_BGRA)
205 scale_flag |= DST_RGB32;
207 /* If P010 is converted without resolution change,
210 if (i965->intel.has_vebox &&
211 (src_fourcc == VA_FOURCC_P010) &&
212 (dst_fourcc == VA_FOURCC_P010 || dst_fourcc == VA_FOURCC_NV12) &&
213 (src_rect->width == dst_rect->width) &&
214 (src_rect->height == dst_rect->height))
217 if (((scale_flag & MASK_CSC) == SCALE_10BIT_10BIT_420) &&
218 (pp_context->scaling_gpe_context_initialized & VPPGPE_10BIT_10BIT)) {
219 unsigned int tmp_width, tmp_x;
221 tmp_x = ALIGN_FLOOR(dst_rect->x, 2);
222 tmp_width = dst_rect->x + dst_rect->width - tmp_x;
223 aligned_dst_rect.x = tmp_x;
224 aligned_dst_rect.width = tmp_width;
225 aligned_dst_rect.y = dst_rect->y;
226 aligned_dst_rect.height = dst_rect->height;
228 status = gen9_p010_scaling_post_processing(ctx, pp_context,
229 (struct i965_surface *)src_surface, (VARectangle *)src_rect,
230 dst_surface, &aligned_dst_rect);
233 if (((scale_flag & MASK_CSC) == SCALE_8BIT_8BIT_420) &&
234 (pp_context->scaling_gpe_context_initialized & VPPGPE_8BIT_8BIT)) {
236 tmp_x = ALIGN_FLOOR(dst_rect->x, 4);
237 tmp_width = dst_rect->x + dst_rect->width - tmp_x;
238 aligned_dst_rect.x = tmp_x;
239 aligned_dst_rect.width = tmp_width;
240 aligned_dst_rect.y = dst_rect->y;
241 aligned_dst_rect.height = dst_rect->height;
243 status = intel_yuv420p8_scaling_post_processing(ctx, pp_context,
244 (struct i965_surface *)src_surface, (VARectangle *)src_rect,
245 dst_surface, &aligned_dst_rect);
248 if (((scale_flag & MASK_CSC) == SCALE_10BIT420_8BIT420 ||
249 (scale_flag & MASK_CSC) == SCALE_10BIT420_8BIT422) &&
250 (pp_context->scaling_gpe_context_initialized & VPPGPE_10BIT_8BIT)) {
252 tmp_x = ALIGN_FLOOR(dst_rect->x, 4);
253 tmp_width = dst_rect->x + dst_rect->width - tmp_x;
254 aligned_dst_rect.x = tmp_x;
255 aligned_dst_rect.width = tmp_width;
256 aligned_dst_rect.y = dst_rect->y;
257 aligned_dst_rect.height = dst_rect->height;
259 status = intel_10bit_8bit_scaling_post_processing(ctx, pp_context,
260 (struct i965_surface *)src_surface, (VARectangle *)src_rect,
261 dst_surface, &aligned_dst_rect);
264 if (((scale_flag & MASK_CSC) == SCALE_8BIT_420_RGB32) &&
265 (pp_context->scaling_gpe_context_initialized & VPPGPE_8BIT_420_RGB32)) {
266 tmp_x = ALIGN_FLOOR(dst_rect->x, 4);
267 tmp_width = dst_rect->x + dst_rect->width - tmp_x;
268 aligned_dst_rect.x = tmp_x;
269 aligned_dst_rect.width = tmp_width;
270 aligned_dst_rect.y = dst_rect->y;
271 aligned_dst_rect.height = dst_rect->height;
273 status = intel_8bit_420_rgb32_scaling_post_processing(ctx, pp_context,
274 (struct i965_surface *)src_surface, (VARectangle *)src_rect,
275 dst_surface, &aligned_dst_rect);