2 * Copyright © 2011 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.
25 * Li Xiaowei <xiaowei.a.li@intel.com>
26 * Li Zhong <zhong.li@intel.com>
35 #include "intel_batchbuffer.h"
36 #include "intel_driver.h"
37 #include "i965_defines.h"
38 #include "i965_structs.h"
39 #include "gen75_vpp_vebox.h"
40 #include "intel_media.h"
45 i965_MapBuffer(VADriverContextP ctx, VABufferID buf_id, void **);
48 i965_UnmapBuffer(VADriverContextP ctx, VABufferID buf_id);
51 i965_DeriveImage(VADriverContextP ctx, VABufferID surface, VAImage *out_image);
54 i965_DestroyImage(VADriverContextP ctx, VAImageID image);
57 vpp_surface_convert(VADriverContextP ctx, struct object_surface *src_obj_surf,
58 struct object_surface *dst_obj_surf)
60 VAStatus va_status = VA_STATUS_SUCCESS;
62 assert(src_obj_surf->orig_width == dst_obj_surf->orig_width);
63 assert(src_obj_surf->orig_height == dst_obj_surf->orig_height);
65 VARectangle src_rect, dst_rect;
66 src_rect.x = dst_rect.x = 0;
67 src_rect.y = dst_rect.y = 0;
68 src_rect.width = dst_rect.width = src_obj_surf->orig_width;
69 src_rect.height = dst_rect.height = dst_obj_surf->orig_height;
71 struct i965_surface src_surface, dst_surface;
72 src_surface.base = (struct object_base *)src_obj_surf;
73 src_surface.type = I965_SURFACE_TYPE_SURFACE;
74 src_surface.flags = I965_SURFACE_FLAG_FRAME;
76 dst_surface.base = (struct object_base *)dst_obj_surf;
77 dst_surface.type = I965_SURFACE_TYPE_SURFACE;
78 dst_surface.flags = I965_SURFACE_FLAG_FRAME;
80 va_status = i965_image_processing(ctx,
89 vpp_surface_scaling(VADriverContextP ctx, struct object_surface *src_obj_surf,
90 struct object_surface *dst_obj_surf, uint32_t flags)
92 VAStatus va_status = VA_STATUS_SUCCESS;
94 assert(src_obj_surf->fourcc == VA_FOURCC_NV12);
95 assert(dst_obj_surf->fourcc == VA_FOURCC_NV12);
97 VARectangle src_rect, dst_rect;
100 src_rect.width = src_obj_surf->orig_width;
101 src_rect.height = src_obj_surf->orig_height;
105 dst_rect.width = dst_obj_surf->orig_width;
106 dst_rect.height = dst_obj_surf->orig_height;
108 va_status = i965_scaling_processing(ctx,
119 vpp_sharpness_filtering(VADriverContextP ctx,
120 struct intel_vebox_context *proc_ctx)
122 VAStatus va_status = VA_STATUS_SUCCESS;
124 if(proc_ctx->vpp_gpe_ctx == NULL){
125 proc_ctx->vpp_gpe_ctx = vpp_gpe_context_init(ctx);
128 proc_ctx->vpp_gpe_ctx->pipeline_param = proc_ctx->pipeline_param;
129 proc_ctx->vpp_gpe_ctx->surface_pipeline_input_object = proc_ctx->frame_store[FRAME_IN_CURRENT].obj_surface;
130 proc_ctx->vpp_gpe_ctx->surface_output_object = proc_ctx->frame_store[FRAME_OUT_CURRENT].obj_surface;
132 va_status = vpp_gpe_process_picture(ctx, proc_ctx->vpp_gpe_ctx);
137 void hsw_veb_dndi_table(VADriverContextP ctx, struct intel_vebox_context *proc_ctx)
139 struct i965_driver_data *i965 = i965_driver_data(ctx);
140 unsigned int* p_table ;
141 unsigned int progressive_dn = 1;
142 unsigned int dndi_top_first = 0;
143 unsigned int is_mcdi_enabled = 0;
145 if (proc_ctx->is_di_enabled) {
146 const VAProcFilterParameterBufferDeinterlacing * const deint_params =
151 /* If we are in "First Frame" mode, i.e. past frames are not
152 available for motion measure, then don't use the TFF flag */
153 dndi_top_first = !(deint_params->flags & (proc_ctx->is_first_frame ?
154 VA_DEINTERLACING_BOTTOM_FIELD :
155 VA_DEINTERLACING_BOTTOM_FIELD_FIRST));
158 (deint_params->algorithm == VAProcDeinterlacingMotionCompensated);
162 VAProcFilterParameterBufferDeinterlacing *di_param =
163 (VAProcFilterParameterBufferDeinterlacing *) proc_ctx->filter_di;
165 VAProcFilterParameterBuffer * dn_param =
166 (VAProcFilterParameterBuffer *) proc_ctx->filter_dn;
168 p_table = (unsigned int *)proc_ctx->dndi_state_table.ptr;
170 if (IS_HASWELL(i965->intel.device_info))
171 *p_table ++ = 0; // reserved . w0
173 *p_table ++ = ( 140 << 24 | // denoise STAD threshold . w1
174 192 << 16 | // dnmh_history_max
175 0 << 12 | // reserved
176 7 << 8 | // dnmh_delta[3:0]
177 38 ); // denoise ASD threshold
179 *p_table ++ = ( 0 << 30 | // reserved . w2
180 0 << 24 | // temporal diff th
181 0 << 22 | // reserved.
182 0 << 16 | // low temporal diff th
184 1 << 8 | // denoise moving pixel th
185 38 ); // denoise th for sum of complexity measure
187 *p_table ++ = ( 0 << 30 | // reserved . w3
188 12<< 24 | // good neighbor th[5:0]
189 9 << 20 | // CAT slope minus 1
190 5 << 16 | // SAD Tight in
191 0 << 14 | // smooth mv th
192 0 << 12 | // reserved
193 1 << 8 | // bne_edge_th[3:0]
194 20 ); // block noise estimate noise th
196 *p_table ++ = ( 0 << 31 | // STMM blending constant select. w4
197 64 << 24 | // STMM trc1
198 125<< 16 | // STMM trc2
199 0 << 14 | // reserved
200 30 << 8 | // VECM_mul
201 150 ); // maximum STMM
203 *p_table ++ = ( 118<< 24 | // minumum STMM . W5
204 0 << 22 | // STMM shift down
205 1 << 20 | // STMM shift up
206 5 << 16 | // STMM output shift
207 100 << 8 | // SDI threshold
210 *p_table ++ = ( 50 << 24 | // SDI fallback mode 1 T1 constant . W6
211 100 << 16 | // SDI fallback mode 1 T2 constant
212 37 << 8 | // SDI fallback mode 2 constant(angle2x1)
213 175 ); // FMD temporal difference threshold
215 *p_table ++ = ( 16 << 24 | // FMD #1 vertical difference th . w7
216 100<< 16 | // FMD #2 vertical difference th
218 2 << 8 | // FMD tear threshold
219 is_mcdi_enabled << 7 | // MCDI Enable, use motion compensated deinterlace algorithm
220 progressive_dn << 6 | // progressive DN
222 dndi_top_first << 3 | // DN/DI Top First
225 *p_table ++ = ( 0 << 29 | // reserved . W8
226 32 << 23 | // dnmh_history_init[5:0]
227 10 << 19 | // neighborPixel th
228 0 << 18 | // reserved
229 0 << 16 | // FMD for 2nd field of previous frame
230 25 << 10 | // MC pixel consistency th
231 0 << 8 | // FMD for 1st field for current frame
235 *p_table ++ = ( 0 << 24 | // reserved
236 140<< 16 | // chr_dnmh_stad_th
237 0 << 13 | // reserved
238 1 << 12 | // chrome denoise enable
239 13 << 6 | // chr temp diff th
240 7 ); // chr temp diff low
242 if (IS_GEN8(i965->intel.device_info) ||
243 IS_GEN9(i965->intel.device_info))
244 *p_table ++ = 0; // parameters for hot pixel,
247 //Set default values for STDE
248 void set_std_table_default(struct intel_vebox_context *proc_ctx, unsigned int *p_table) {
251 *p_table ++ = ( 0 << 31 | // Reserved
252 0x3F8 << 21 | // SATB1 (10 bits, default 8, optimized value -8)
255 0x7A ); // SATP1 (7 bits, default 6, optimized value -6)
258 *p_table ++ = ( 0 << 31 | // Reserved
264 *p_table ++ = ( 0 << 22 | // Reserved
269 *p_table ++ = ( 14 << 25 | // HUEP3
271 0x7A << 11 | // HUEP1 (7 bits, default value -6 = 7Ah)
275 *p_table ++ = ( 0 << 30 | // Reserved
278 0x3F8 ); // HUEB1 (10 bits, default value 8, optimized value -8)
281 *p_table ++ = ( 0 << 22 | // Reserved
286 *p_table ++ = ( 0 << 22 | // Reserved
291 *p_table ++ = ( 0 << 31 | // Reserved
292 0 << 21 | // SATB1_DARK
293 31 << 14 | // SATP3_DARK
294 31 << 7 | // SATP2_DARK
295 0x7B ); // SATP1_DARK (7 bits, default value -11 = FF5h, optimized value -5)
298 *p_table ++ = ( 0 << 31 | // Reserved
299 305 << 20 | // SATS0_DARK
300 124 << 10 | // SATB3_DARK
304 *p_table ++ = ( 0 << 22 | // Reserved
305 256 << 11 | // SATS2_DARK
309 *p_table ++ = ( 14 << 25 | // HUEP3_DARK
310 14 << 18 | // HUEP2_DARK
311 14 << 11 | // HUEP1_DARK
315 *p_table ++ = ( 0 << 30 | // Reserved
316 56 << 20 | // HUEB3_DARK
317 56 << 10 | // HUEB2_DARK
321 *p_table ++ = ( 0 << 22 | // Reserved
322 256 << 11 | // HUES1_DARK
326 *p_table ++ = ( 0 << 22 | // Reserved
327 256 << 11 | // HUES3_DARK
331 //Set values for STDE factor 3
332 void set_std_table_3(struct intel_vebox_context *proc_ctx, unsigned int *p_table) {
335 *p_table ++ = ( 0 << 31 | // Reserved
336 1016 << 21 | // SATB1 (10 bits, default 8, optimized value 1016)
339 122 ); // SATP1 (7 bits, default 6, optimized value 122)
342 *p_table ++ = ( 0 << 31 | // Reserved
348 *p_table ++ = ( 0 << 22 | // Reserved
353 *p_table ++ = ( 14 << 25 | // HUEP3
355 122 << 11 | // HUEP1 (7 bits, default value -6 = 7Ah, optimized 122)
359 *p_table ++ = ( 0 << 30 | // Reserved
360 56 << 20 | // HUEB3 (default 256, optimized 56)
362 1016 ); // HUEB1 (10 bits, default value 8, optimized value 1016)
365 *p_table ++ = ( 0 << 22 | // Reserved
370 *p_table ++ = ( 0 << 22 | // Reserved
375 *p_table ++ = ( 0 << 31 | // Reserved
376 0 << 21 | // SATB1_DARK
377 31 << 14 | // SATP3_DARK
378 31 << 7 | // SATP2_DARK
379 123 ); // SATP1_DARK (7 bits, default value -11 = FF5h, optimized value 123)
382 *p_table ++ = ( 0 << 31 | // Reserved
383 305 << 20 | // SATS0_DARK
384 124 << 10 | // SATB3_DARK
388 *p_table ++ = ( 0 << 22 | // Reserved
389 256 << 11 | // SATS2_DARK
393 *p_table ++ = ( 14 << 25 | // HUEP3_DARK
394 14 << 18 | // HUEP2_DARK
395 14 << 11 | // HUEP1_DARK
399 *p_table ++ = ( 0 << 30 | // Reserved
400 56 << 20 | // HUEB3_DARK
401 56 << 10 | // HUEB2_DARK
405 *p_table ++ = ( 0 << 22 | // Reserved
406 256 << 11 | // HUES1_DARK
410 *p_table ++ = ( 0 << 22 | // Reserved
411 256 << 11 | // HUES3_DARK
415 //Set values for STDE factor 6
416 void set_std_table_6(struct intel_vebox_context *proc_ctx, unsigned int *p_table) {
419 *p_table ++ = ( 0 << 31 | // Reserved
420 0 << 21 | // SATB1 (10 bits, default 8, optimized value 0)
422 31 << 7 | // SATP2 (default 6, optimized 31)
423 114 ); // SATP1 (7 bits, default 6, optimized value 114)
426 *p_table ++ = ( 0 << 31 | // Reserved
427 467 << 20 | // SATS0 (default 297, optimized 467)
432 *p_table ++ = ( 0 << 22 | // Reserved
433 256 << 11 | // SATS2 (default 297, optimized 256)
437 *p_table ++ = ( 14 << 25 | // HUEP3
439 14 << 11 | // HUEP1 (7 bits, default value -6 = 7Ah, optimized value 14)
443 *p_table ++ = ( 0 << 30 | // Reserved
446 56 ); // HUEB1 (10 bits, default value 8, optimized value 56)
449 *p_table ++ = ( 0 << 22 | // Reserved
454 *p_table ++ = ( 0 << 22 | // Reserved
459 *p_table ++ = ( 0 << 31 | // Reserved
460 0 << 21 | // SATB1_DARK
461 31 << 14 | // SATP3_DARK
462 31 << 7 | // SATP2_DARK
463 123 ); // SATP1_DARK (7 bits, default value -11 = FF5h, optimized value 123)
466 *p_table ++ = ( 0 << 31 | // Reserved
467 305 << 20 | // SATS0_DARK
468 124 << 10 | // SATB3_DARK
472 *p_table ++ = ( 0 << 22 | // Reserved
473 256 << 11 | // SATS2_DARK
477 *p_table ++ = ( 14 << 25 | // HUEP3_DARK
478 14 << 18 | // HUEP2_DARK
479 14 << 11 | // HUEP1_DARK
483 *p_table ++ = ( 0 << 30 | // Reserved
484 56 << 20 | // HUEB3_DARK
485 56 << 10 | // HUEB2_DARK
489 *p_table ++ = ( 0 << 22 | // Reserved
490 256 << 11 | // HUES1_DARK
494 *p_table ++ = ( 0 << 22 | // Reserved
495 256 << 11 | // HUES3_DARK
499 //Set values for STDE factor 9
500 void set_std_table_9(struct intel_vebox_context *proc_ctx, unsigned int *p_table) {
503 *p_table ++ = ( 0 << 31 | // Reserved
504 0 << 21 | // SATB1 (10 bits, default 8, optimized value 0)
506 31 << 7 | // SATP2 (default 6, optimized 31)
507 108 ); // SATP1 (7 bits, default 6, optimized value 108)
510 *p_table ++ = ( 0 << 31 | // Reserved
511 721 << 20 | // SATS0 (default 297, optimized 721)
516 *p_table ++ = ( 0 << 22 | // Reserved
517 256 << 11 | // SATS2 (default 297, optimized 256)
518 156 ); // SATS1 (default 176, optimized 156)
521 *p_table ++ = ( 14 << 25 | // HUEP3
523 14 << 11 | // HUEP1 (7 bits, default value -6 = 7Ah, optimized value 14)
527 *p_table ++ = ( 0 << 30 | // Reserved
530 56 ); // HUEB1 (10 bits, default value 8, optimized value 56)
533 *p_table ++ = ( 0 << 22 | // Reserved
538 *p_table ++ = ( 0 << 22 | // Reserved
543 *p_table ++ = ( 0 << 31 | // Reserved
544 0 << 21 | // SATB1_DARK
545 31 << 14 | // SATP3_DARK
546 31 << 7 | // SATP2_DARK
547 123 ); // SATP1_DARK (7 bits, default value -11 = FF5h, optimized value 123)
550 *p_table ++ = ( 0 << 31 | // Reserved
551 305 << 20 | // SATS0_DARK
552 124 << 10 | // SATB3_DARK
556 *p_table ++ = ( 0 << 22 | // Reserved
557 256 << 11 | // SATS2_DARK
561 *p_table ++ = ( 14 << 25 | // HUEP3_DARK
562 14 << 18 | // HUEP2_DARK
563 14 << 11 | // HUEP1_DARK
567 *p_table ++ = ( 0 << 30 | // Reserved
568 56 << 20 | // HUEB3_DARK
569 56 << 10 | // HUEB2_DARK
573 *p_table ++ = ( 0 << 22 | // Reserved
574 256 << 11 | // HUES1_DARK
578 *p_table ++ = ( 0 << 22 | // Reserved
579 256 << 11 | // HUES3_DARK
584 void hsw_veb_iecp_std_table(VADriverContextP ctx, struct intel_vebox_context *proc_ctx)
586 unsigned int *p_table = (unsigned int *)proc_ctx->iecp_state_table.ptr;
588 if(!(proc_ctx->filters_mask & VPP_IECP_STD_STE)){
589 memset(p_table, 0, 29 * 4);
591 int stde_factor = 0; //default value
592 VAProcFilterParameterBuffer * std_param = (VAProcFilterParameterBuffer *) proc_ctx->filter_iecp_std;
593 stde_factor = std_param->value;
596 *p_table ++ = ( 154 << 24 | // V_Mid
598 14 << 10 | // Hue_Max
601 0 << 2 | // Output Control is set to output the 1=STD score /0=Output Pixels
602 1 << 1 | // Set STE Enable
603 1 ); // Set STD Enable
606 *p_table ++ = ( 0 << 31 | // Reserved
607 4 << 28 | // Diamond Margin
608 0 << 21 | // Diamond_du
609 3 << 18 | // HS_Margin
610 79 << 10 | // Cos(alpha)
615 *p_table ++ = ( 0 << 21 | // Reserved
616 100 << 13 | // Diamond_alpha
617 35 << 7 | // Diamond_Th
621 *p_table ++ = ( 254 << 24 | // Y_point_3
622 47 << 16 | // Y_point_2
623 46 << 8 | // Y_point_1
624 1 << 7 | // VY_STD_Enable
628 *p_table ++ = ( 0 << 18 | // Reserved
629 31 << 13 | // Y_slope_2
630 31 << 8 | // Y_slope_1
634 *p_table ++ = ( 400 << 16 | // INV_Skin_types_margin = 20* Skin_Type_margin => 20*20
635 3300 ); // INV_Margin_VYL => 1/Margin_VYL
638 *p_table ++ = ( 216 << 24 | // P1L
640 1600 ); // INV_Margin_VYU
643 *p_table ++ = ( 130 << 24 | // B1L
649 *p_table ++ = ( 0 << 27 | // Reserved
650 0x7FB << 16 | // S0L (11 bits, Default value: -5 = FBh, pad it with 1s to make it 11bits)
655 *p_table ++ = ( 0 << 22 | // Reserved
660 *p_table ++ = ( 0 << 27 | // Reserved
666 *p_table ++ = ( 163 << 24 | // B1U
672 *p_table ++ = ( 0 << 27 | // Reserved
678 *p_table ++ = ( 0 << 22 | // Reserved
679 0x74D << 11 | // S2U (11 bits, Default value -179 = F4Dh)
683 *p_table ++ = ( 0 << 28 | // Reserved
684 20 << 20 | // Skin_types_margin
685 120 << 12 | // Skin_types_thresh
686 1 << 11 | // Skin_Types_Enable
689 //Set DWord 15 through DWord 28 in their respective methods.
690 switch(stde_factor) {
692 set_std_table_3(proc_ctx, p_table);
696 set_std_table_6(proc_ctx, p_table);
700 set_std_table_9(proc_ctx, p_table);
704 set_std_table_default(proc_ctx, p_table);
710 void hsw_veb_iecp_ace_table(VADriverContextP ctx, struct intel_vebox_context *proc_ctx)
712 unsigned int *p_table = (unsigned int*)(proc_ctx->iecp_state_table.ptr + 116);
714 if(!(proc_ctx->filters_mask & VPP_IECP_ACE)){
715 memset(p_table, 0, 13 * 4);
717 *p_table ++ = 0x00000068;
718 *p_table ++ = 0x4c382410;
719 *p_table ++ = 0x9c887460;
720 *p_table ++ = 0xebd8c4b0;
721 *p_table ++ = 0x604c3824;
723 *p_table ++ = 0xb09c8874;
724 *p_table ++ = 0x0000d8c4;
725 *p_table ++ = 0x00000000;
726 *p_table ++ = 0x00000000;
727 *p_table ++ = 0x00000000;
729 *p_table ++ = 0x00000000;
730 *p_table ++ = 0x00000000;
731 *p_table ++ = 0x00000000;
735 void hsw_veb_iecp_tcc_table(VADriverContextP ctx, struct intel_vebox_context *proc_ctx)
737 unsigned int *p_table = (unsigned int*)(proc_ctx->iecp_state_table.ptr + 168);
738 // VAProcFilterParameterBuffer * tcc_param =
739 // (VAProcFilterParameterBuffer *) proc_ctx->filter_iecp_tcc;
741 if(!(proc_ctx->filters_mask & VPP_IECP_TCC)){
742 memset(p_table, 0, 11 * 4);
744 *p_table ++ = 0x00000000;
745 *p_table ++ = 0x00000000;
746 *p_table ++ = 0x1e34cc91;
747 *p_table ++ = 0x3e3cce91;
748 *p_table ++ = 0x02e80195;
750 *p_table ++ = 0x0197046b;
751 *p_table ++ = 0x01790174;
752 *p_table ++ = 0x00000000;
753 *p_table ++ = 0x00000000;
754 *p_table ++ = 0x03030000;
756 *p_table ++ = 0x009201c0;
760 void hsw_veb_iecp_pro_amp_table(VADriverContextP ctx, struct intel_vebox_context *proc_ctx)
762 unsigned int contrast = 0x80; //default
763 int brightness = 0x00; //default
764 int cos_c_s = 256 ; //default
765 int sin_c_s = 0; //default
766 unsigned int *p_table = (unsigned int*)(proc_ctx->iecp_state_table.ptr + 212);
768 if(!(proc_ctx->filters_mask & VPP_IECP_PRO_AMP)){
769 memset(p_table, 0, 2 * 4);
771 float src_saturation = 1.0;
773 float src_contrast = 1.0;
774 float src_brightness = 0.0;
775 float tmp_value = 0.0;
778 VAProcFilterParameterBufferColorBalance * amp_params =
779 (VAProcFilterParameterBufferColorBalance *) proc_ctx->filter_iecp_amp;
781 for (i = 0; i < proc_ctx->filter_iecp_amp_num_elements; i++){
782 VAProcColorBalanceType attrib = amp_params[i].attrib;
784 if(attrib == VAProcColorBalanceHue) {
785 src_hue = amp_params[i].value; //(-180.0, 180.0)
786 }else if(attrib == VAProcColorBalanceSaturation) {
787 src_saturation = amp_params[i].value; //(0.0, 10.0)
788 }else if(attrib == VAProcColorBalanceBrightness) {
789 src_brightness = amp_params[i].value; // (-100.0, 100.0)
790 brightness = intel_format_convert(src_brightness, 7, 4, 1);
791 }else if(attrib == VAProcColorBalanceContrast) {
792 src_contrast = amp_params[i].value; // (0.0, 10.0)
793 contrast = intel_format_convert(src_contrast, 4, 7, 0);
797 tmp_value = cos(src_hue/180*PI) * src_contrast * src_saturation;
798 cos_c_s = intel_format_convert(tmp_value, 7, 8, 1);
800 tmp_value = sin(src_hue/180*PI) * src_contrast * src_saturation;
801 sin_c_s = intel_format_convert(tmp_value, 7, 8, 1);
803 *p_table ++ = ( 0 << 28 | //reserved
804 contrast << 17 | //contrast value (U4.7 format)
806 brightness << 1| // S7.4 format
809 *p_table ++ = ( cos_c_s << 16 | // cos(h) * contrast * saturation
810 sin_c_s); // sin(h) * contrast * saturation
816 void hsw_veb_iecp_csc_transform_table(VADriverContextP ctx, struct intel_vebox_context *proc_ctx)
818 unsigned int *p_table = (unsigned int*)(proc_ctx->iecp_state_table.ptr + 220);
819 float tran_coef[9] = {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0};
820 float v_coef[3] = {0.0, 0.0, 0.0};
821 float u_coef[3] = {0.0, 0.0, 0.0};
822 int is_transform_enabled = 0;
824 if(!(proc_ctx->filters_mask & VPP_IECP_CSC_TRANSFORM)){
825 memset(p_table, 0, 8 * 4);
829 if(proc_ctx->fourcc_input == VA_FOURCC_RGBA &&
830 (proc_ctx->fourcc_output == VA_FOURCC_NV12 ||
831 proc_ctx->fourcc_output == VA_FOURCC_YV12 ||
832 proc_ctx->fourcc_output == VA_FOURCC_YVY2 ||
833 proc_ctx->fourcc_output == VA_FOURCC_AYUV)) {
835 tran_coef[0] = 0.257;
836 tran_coef[1] = 0.504;
837 tran_coef[2] = 0.098;
838 tran_coef[3] = -0.148;
839 tran_coef[4] = -0.291;
840 tran_coef[5] = 0.439;
841 tran_coef[6] = 0.439;
842 tran_coef[7] = -0.368;
843 tran_coef[8] = -0.071;
849 is_transform_enabled = 1;
850 }else if((proc_ctx->fourcc_input == VA_FOURCC_NV12 ||
851 proc_ctx->fourcc_input == VA_FOURCC_YV12 ||
852 proc_ctx->fourcc_input == VA_FOURCC_YUY2 ||
853 proc_ctx->fourcc_input == VA_FOURCC_AYUV) &&
854 proc_ctx->fourcc_output == VA_FOURCC_RGBA) {
855 tran_coef[0] = 1.164;
856 tran_coef[1] = 0.000;
857 tran_coef[2] = 1.569;
858 tran_coef[3] = 1.164;
859 tran_coef[4] = -0.813;
860 tran_coef[5] = -0.392;
861 tran_coef[6] = 1.164;
862 tran_coef[7] = 2.017;
863 tran_coef[8] = 0.000;
866 v_coef[1] = -128 * 4;
867 v_coef[2] = -128 * 4;
869 is_transform_enabled = 1;
870 }else if(proc_ctx->fourcc_input != proc_ctx->fourcc_output){
871 //enable when input and output format are different.
872 is_transform_enabled = 1;
875 if(is_transform_enabled == 0){
876 memset(p_table, 0, 8 * 4);
878 *p_table ++ = ( 0 << 29 | //reserved
879 intel_format_convert(tran_coef[1], 2, 10, 1) << 16 | //c1, s2.10 format
880 intel_format_convert(tran_coef[0], 2, 10, 1) << 3 | //c0, s2.10 format
882 0 << 1 | // yuv_channel swap
883 is_transform_enabled);
885 *p_table ++ = ( 0 << 26 | //reserved
886 intel_format_convert(tran_coef[3], 2, 10, 1) << 13 |
887 intel_format_convert(tran_coef[2], 2, 10, 1));
889 *p_table ++ = ( 0 << 26 | //reserved
890 intel_format_convert(tran_coef[5], 2, 10, 1) << 13 |
891 intel_format_convert(tran_coef[4], 2, 10, 1));
893 *p_table ++ = ( 0 << 26 | //reserved
894 intel_format_convert(tran_coef[7], 2, 10, 1) << 13 |
895 intel_format_convert(tran_coef[6], 2, 10, 1));
897 *p_table ++ = ( 0 << 13 | //reserved
898 intel_format_convert(tran_coef[8], 2, 10, 1));
900 *p_table ++ = ( 0 << 22 | //reserved
901 intel_format_convert(u_coef[0], 10, 0, 1) << 11 |
902 intel_format_convert(v_coef[0], 10, 0, 1));
904 *p_table ++ = ( 0 << 22 | //reserved
905 intel_format_convert(u_coef[1], 10, 0, 1) << 11 |
906 intel_format_convert(v_coef[1], 10, 0, 1));
908 *p_table ++ = ( 0 << 22 | //reserved
909 intel_format_convert(u_coef[2], 10, 0, 1) << 11 |
910 intel_format_convert(v_coef[2], 10, 0, 1));
914 void hsw_veb_iecp_aoi_table(VADriverContextP ctx, struct intel_vebox_context *proc_ctx)
916 unsigned int *p_table = (unsigned int*)(proc_ctx->iecp_state_table.ptr + 252);
917 // VAProcFilterParameterBuffer * tcc_param =
918 // (VAProcFilterParameterBuffer *) proc_ctx->filter_iecp_tcc;
920 if(!(proc_ctx->filters_mask & VPP_IECP_AOI)){
921 memset(p_table, 0, 3 * 4);
923 *p_table ++ = 0x00000000;
924 *p_table ++ = 0x00030000;
925 *p_table ++ = 0x00030000;
929 void hsw_veb_state_table_setup(VADriverContextP ctx, struct intel_vebox_context *proc_ctx)
931 if(proc_ctx->filters_mask & VPP_DNDI_MASK) {
932 dri_bo *dndi_bo = proc_ctx->dndi_state_table.bo;
933 dri_bo_map(dndi_bo, 1);
934 proc_ctx->dndi_state_table.ptr = dndi_bo->virtual;
936 hsw_veb_dndi_table(ctx, proc_ctx);
938 dri_bo_unmap(dndi_bo);
941 if(proc_ctx->filters_mask & VPP_IECP_MASK) {
942 dri_bo *iecp_bo = proc_ctx->iecp_state_table.bo;
943 dri_bo_map(iecp_bo, 1);
944 proc_ctx->iecp_state_table.ptr = iecp_bo->virtual;
945 memset(proc_ctx->iecp_state_table.ptr, 0, 97 * 4);
947 hsw_veb_iecp_std_table(ctx, proc_ctx);
948 hsw_veb_iecp_ace_table(ctx, proc_ctx);
949 hsw_veb_iecp_tcc_table(ctx, proc_ctx);
950 hsw_veb_iecp_pro_amp_table(ctx, proc_ctx);
951 hsw_veb_iecp_csc_transform_table(ctx, proc_ctx);
952 hsw_veb_iecp_aoi_table(ctx, proc_ctx);
954 dri_bo_unmap(iecp_bo);
958 void hsw_veb_state_command(VADriverContextP ctx, struct intel_vebox_context *proc_ctx)
960 struct intel_batchbuffer *batch = proc_ctx->batch;
962 BEGIN_VEB_BATCH(batch, 6);
963 OUT_VEB_BATCH(batch, VEB_STATE | (6 - 2));
965 0 << 26 | // state surface control bits
966 0 << 11 | // reserved.
967 0 << 10 | // pipe sync disable
968 proc_ctx->current_output_type << 8 | // DI output frame
969 1 << 7 | // 444->422 downsample method
970 1 << 6 | // 422->420 downsample method
971 proc_ctx->is_first_frame << 5 | // DN/DI first frame
972 proc_ctx->is_di_enabled << 4 | // DI enable
973 proc_ctx->is_dn_enabled << 3 | // DN enable
974 proc_ctx->is_iecp_enabled << 2 | // global IECP enabled
975 0 << 1 | // ColorGamutCompressionEnable
976 0 ) ; // ColorGamutExpansionEnable.
979 proc_ctx->dndi_state_table.bo,
980 I915_GEM_DOMAIN_INSTRUCTION, 0, 0);
983 proc_ctx->iecp_state_table.bo,
984 I915_GEM_DOMAIN_INSTRUCTION, 0, 0);
987 proc_ctx->gamut_state_table.bo,
988 I915_GEM_DOMAIN_INSTRUCTION, 0, 0);
991 proc_ctx->vertex_state_table.bo,
992 I915_GEM_DOMAIN_INSTRUCTION, 0, 0);
994 ADVANCE_VEB_BATCH(batch);
997 void hsw_veb_surface_state(VADriverContextP ctx, struct intel_vebox_context *proc_ctx, unsigned int is_output)
999 struct intel_batchbuffer *batch = proc_ctx->batch;
1000 unsigned int u_offset_y = 0, v_offset_y = 0;
1001 unsigned int is_uv_interleaved = 0, tiling = 0, swizzle = 0;
1002 unsigned int surface_format = PLANAR_420_8;
1003 struct object_surface* obj_surf = NULL;
1004 unsigned int surface_pitch = 0;
1005 unsigned int half_pitch_chroma = 0;
1008 obj_surf = proc_ctx->frame_store[FRAME_OUT_CURRENT].obj_surface;
1010 obj_surf = proc_ctx->frame_store[FRAME_IN_CURRENT].obj_surface;
1013 assert(obj_surf->fourcc == VA_FOURCC_NV12 ||
1014 obj_surf->fourcc == VA_FOURCC_YUY2 ||
1015 obj_surf->fourcc == VA_FOURCC_AYUV ||
1016 obj_surf->fourcc == VA_FOURCC_RGBA);
1018 if (obj_surf->fourcc == VA_FOURCC_NV12) {
1019 surface_format = PLANAR_420_8;
1020 surface_pitch = obj_surf->width;
1021 is_uv_interleaved = 1;
1022 half_pitch_chroma = 0;
1023 } else if (obj_surf->fourcc == VA_FOURCC_YUY2) {
1024 surface_format = YCRCB_NORMAL;
1025 surface_pitch = obj_surf->width * 2;
1026 is_uv_interleaved = 0;
1027 half_pitch_chroma = 0;
1028 } else if (obj_surf->fourcc == VA_FOURCC_AYUV) {
1029 surface_format = PACKED_444A_8;
1030 surface_pitch = obj_surf->width * 4;
1031 is_uv_interleaved = 0;
1032 half_pitch_chroma = 0;
1033 } else if (obj_surf->fourcc == VA_FOURCC_RGBA) {
1034 surface_format = R8G8B8A8_UNORM_SRGB;
1035 surface_pitch = obj_surf->width * 4;
1036 is_uv_interleaved = 0;
1037 half_pitch_chroma = 0;
1040 u_offset_y = obj_surf->y_cb_offset;
1041 v_offset_y = obj_surf->y_cr_offset;
1043 dri_bo_get_tiling(obj_surf->bo, &tiling, &swizzle);
1045 BEGIN_VEB_BATCH(batch, 6);
1046 OUT_VEB_BATCH(batch, VEB_SURFACE_STATE | (6 - 2));
1047 OUT_VEB_BATCH(batch,
1048 0 << 1 | // reserved
1049 is_output); // surface indentification.
1051 OUT_VEB_BATCH(batch,
1052 (obj_surf->orig_height - 1) << 18 | // height . w3
1053 (obj_surf->orig_width - 1) << 4 | // width
1056 OUT_VEB_BATCH(batch,
1057 surface_format << 28 | // surface format, YCbCr420. w4
1058 is_uv_interleaved << 27 | // interleave chrome , two seperate palar
1059 0 << 20 | // reserved
1060 (surface_pitch - 1) << 3 | // surface pitch, 64 align
1061 half_pitch_chroma << 2 | // half pitch for chrome
1062 !!tiling << 1 | // tiled surface, linear surface used
1063 (tiling == I915_TILING_Y)); // tiled walk, ignored when liner surface
1065 OUT_VEB_BATCH(batch,
1066 0 << 29 | // reserved . w5
1067 0 << 16 | // X offset for V(Cb)
1068 0 << 15 | // reserved
1069 u_offset_y); // Y offset for V(Cb)
1071 OUT_VEB_BATCH(batch,
1072 0 << 29 | // reserved . w6
1073 0 << 16 | // X offset for V(Cr)
1074 0 << 15 | // reserved
1075 v_offset_y ); // Y offset for V(Cr)
1077 ADVANCE_VEB_BATCH(batch);
1080 void hsw_veb_dndi_iecp_command(VADriverContextP ctx, struct intel_vebox_context *proc_ctx)
1082 struct intel_batchbuffer *batch = proc_ctx->batch;
1083 unsigned char frame_ctrl_bits = 0;
1084 struct object_surface *obj_surface = proc_ctx->frame_store[FRAME_IN_CURRENT].obj_surface;
1085 unsigned int width64 = ALIGN(proc_ctx->width_input, 64);
1087 assert(obj_surface);
1088 if (width64 > obj_surface->orig_width)
1089 width64 = obj_surface->orig_width;
1091 /* s1:update the previous and current input */
1092 /* tempFrame = proc_ctx->frame_store[FRAME_IN_PREVIOUS];
1093 proc_ctx->frame_store[FRAME_IN_PREVIOUS] = proc_ctx->frame_store[FRAME_IN_CURRENT]; ;
1094 proc_ctx->frame_store[FRAME_IN_CURRENT] = tempFrame;
1096 if(proc_ctx->surface_input_vebox != -1){
1097 vpp_surface_copy(ctx, proc_ctx->frame_store[FRAME_IN_CURRENT].surface_id,
1098 proc_ctx->surface_input_vebox);
1100 vpp_surface_copy(ctx, proc_ctx->frame_store[FRAME_IN_CURRENT].surface_id,
1101 proc_ctx->surface_input);
1104 /*s2: update the STMM input and output */
1105 /* tempFrame = proc_ctx->frame_store[FRAME_IN_STMM];
1106 proc_ctx->frame_store[FRAME_IN_STMM] = proc_ctx->frame_store[FRAME_OUT_STMM]; ;
1107 proc_ctx->frame_store[FRAME_OUT_STMM] = tempFrame;
1109 /*s3:set reloc buffer address */
1110 BEGIN_VEB_BATCH(batch, 10);
1111 OUT_VEB_BATCH(batch, VEB_DNDI_IECP_STATE | (10 - 2));
1112 OUT_VEB_BATCH(batch, (width64 - 1));
1114 proc_ctx->frame_store[FRAME_IN_CURRENT].obj_surface->bo,
1115 I915_GEM_DOMAIN_RENDER, 0, frame_ctrl_bits);
1117 proc_ctx->frame_store[FRAME_IN_PREVIOUS].obj_surface->bo,
1118 I915_GEM_DOMAIN_RENDER, 0, frame_ctrl_bits);
1120 proc_ctx->frame_store[FRAME_IN_STMM].obj_surface->bo,
1121 I915_GEM_DOMAIN_RENDER, 0, frame_ctrl_bits);
1123 proc_ctx->frame_store[FRAME_OUT_STMM].obj_surface->bo,
1124 I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, frame_ctrl_bits);
1126 proc_ctx->frame_store[FRAME_OUT_CURRENT_DN].obj_surface->bo,
1127 I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, frame_ctrl_bits);
1129 proc_ctx->frame_store[FRAME_OUT_CURRENT].obj_surface->bo,
1130 I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, frame_ctrl_bits);
1132 proc_ctx->frame_store[FRAME_OUT_PREVIOUS].obj_surface->bo,
1133 I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, frame_ctrl_bits);
1135 proc_ctx->frame_store[FRAME_OUT_STATISTIC].obj_surface->bo,
1136 I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, frame_ctrl_bits);
1138 ADVANCE_VEB_BATCH(batch);
1142 frame_store_reset(VEBFrameStore *fs)
1144 fs->obj_surface = NULL;
1145 fs->surface_id = VA_INVALID_ID;
1146 fs->is_internal_surface = 0;
1147 fs->is_scratch_surface = 0;
1151 frame_store_clear(VEBFrameStore *fs, VADriverContextP ctx)
1153 if (fs->obj_surface && fs->is_scratch_surface) {
1154 VASurfaceID surface_id = fs->obj_surface->base.id;
1155 i965_DestroySurfaces(ctx, &surface_id, 1);
1157 frame_store_reset(fs);
1161 gen75_vebox_ensure_surfaces_storage(VADriverContextP ctx,
1162 struct intel_vebox_context *proc_ctx)
1164 struct i965_driver_data * const i965 = i965_driver_data(ctx);
1165 struct object_surface *input_obj_surface, *output_obj_surface;
1166 unsigned int input_fourcc, output_fourcc;
1167 unsigned int input_sampling, output_sampling;
1168 unsigned int input_tiling, output_tiling;
1169 unsigned int i, swizzle;
1173 /* Determine input surface info. Use native VEBOX format whenever
1174 possible. i.e. when the input surface format is not supported
1175 by the VEBOX engine, then allocate a temporary surface (live
1176 during the whole VPP pipeline lifetime)
1178 XXX: derive an actual surface format compatible with the input
1179 surface chroma format */
1180 input_obj_surface = proc_ctx->surface_input_vebox_object ?
1181 proc_ctx->surface_input_vebox_object : proc_ctx->surface_input_object;
1182 if (input_obj_surface->bo) {
1183 input_fourcc = input_obj_surface->fourcc;
1184 input_sampling = input_obj_surface->subsampling;
1185 dri_bo_get_tiling(input_obj_surface->bo, &input_tiling, &swizzle);
1186 input_tiling = !!input_tiling;
1189 input_fourcc = VA_FOURCC_NV12;
1190 input_sampling = SUBSAMPLE_YUV420;
1192 status = i965_check_alloc_surface_bo(ctx, input_obj_surface,
1193 input_tiling, input_fourcc, input_sampling);
1194 if (status != VA_STATUS_SUCCESS)
1198 /* Determine output surface info.
1200 XXX: derive an actual surface format compatible with the input
1201 surface chroma format */
1202 output_obj_surface = proc_ctx->surface_output_vebox_object ?
1203 proc_ctx->surface_output_vebox_object : proc_ctx->surface_output_object;
1204 if (output_obj_surface->bo) {
1205 output_fourcc = output_obj_surface->fourcc;
1206 output_sampling = output_obj_surface->subsampling;
1207 dri_bo_get_tiling(output_obj_surface->bo, &output_tiling, &swizzle);
1208 output_tiling = !!output_tiling;
1211 output_fourcc = VA_FOURCC_NV12;
1212 output_sampling = SUBSAMPLE_YUV420;
1214 status = i965_check_alloc_surface_bo(ctx, output_obj_surface,
1215 output_tiling, output_fourcc, output_sampling);
1216 if (status != VA_STATUS_SUCCESS)
1220 /* Update VEBOX pipeline formats */
1221 proc_ctx->fourcc_input = input_fourcc;
1222 proc_ctx->fourcc_output = output_fourcc;
1223 if (input_fourcc != output_fourcc) {
1224 proc_ctx->filters_mask |= VPP_IECP_CSC;
1226 if (input_fourcc == VA_FOURCC_RGBA &&
1227 (output_fourcc == VA_FOURCC_NV12 ||
1228 output_fourcc == VA_FOURCC_P010)) {
1229 proc_ctx->filters_mask |= VPP_IECP_CSC_TRANSFORM;
1230 } else if (output_fourcc == VA_FOURCC_RGBA &&
1231 (input_fourcc == VA_FOURCC_NV12 ||
1232 input_fourcc == VA_FOURCC_P010)) {
1233 proc_ctx->filters_mask |= VPP_IECP_CSC_TRANSFORM;
1237 proc_ctx->is_iecp_enabled = (proc_ctx->filters_mask & VPP_IECP_MASK) != 0;
1239 /* Create pipeline surfaces */
1240 for (i = 0; i < ARRAY_ELEMS(proc_ctx->frame_store); i ++) {
1241 struct object_surface *obj_surface;
1242 VASurfaceID new_surface;
1244 if (proc_ctx->frame_store[i].obj_surface)
1245 continue; // user allocated surface, not VEBOX internal
1247 status = i965_CreateSurfaces(ctx, proc_ctx->width_input,
1248 proc_ctx->height_input, VA_RT_FORMAT_YUV420, 1, &new_surface);
1249 if (status != VA_STATUS_SUCCESS)
1252 obj_surface = SURFACE(new_surface);
1253 assert(obj_surface != NULL);
1255 if (i <= FRAME_IN_PREVIOUS || i == FRAME_OUT_CURRENT_DN) {
1256 status = i965_check_alloc_surface_bo(ctx, obj_surface,
1257 input_tiling, input_fourcc, input_sampling);
1259 else if (i == FRAME_IN_STMM || i == FRAME_OUT_STMM) {
1260 status = i965_check_alloc_surface_bo(ctx, obj_surface,
1261 1, input_fourcc, input_sampling);
1263 else if (i >= FRAME_OUT_CURRENT) {
1264 status = i965_check_alloc_surface_bo(ctx, obj_surface,
1265 output_tiling, output_fourcc, output_sampling);
1267 if (status != VA_STATUS_SUCCESS)
1270 proc_ctx->frame_store[i].obj_surface = obj_surface;
1271 proc_ctx->frame_store[i].is_internal_surface = 1;
1272 proc_ctx->frame_store[i].is_scratch_surface = 1;
1275 /* Allocate DNDI state table */
1276 drm_intel_bo_unreference(proc_ctx->dndi_state_table.bo);
1277 bo = drm_intel_bo_alloc(i965->intel.bufmgr, "vebox: dndi state Buffer",
1279 proc_ctx->dndi_state_table.bo = bo;
1281 return VA_STATUS_ERROR_ALLOCATION_FAILED;
1283 /* Allocate IECP state table */
1284 drm_intel_bo_unreference(proc_ctx->iecp_state_table.bo);
1285 bo = drm_intel_bo_alloc(i965->intel.bufmgr, "vebox: iecp state Buffer",
1287 proc_ctx->iecp_state_table.bo = bo;
1289 return VA_STATUS_ERROR_ALLOCATION_FAILED;
1291 /* Allocate Gamut state table */
1292 drm_intel_bo_unreference(proc_ctx->gamut_state_table.bo);
1293 bo = drm_intel_bo_alloc(i965->intel.bufmgr, "vebox: gamut state Buffer",
1295 proc_ctx->gamut_state_table.bo = bo;
1297 return VA_STATUS_ERROR_ALLOCATION_FAILED;
1299 /* Allocate vertex state table */
1300 drm_intel_bo_unreference(proc_ctx->vertex_state_table.bo);
1301 bo = drm_intel_bo_alloc(i965->intel.bufmgr, "vebox: vertex state Buffer",
1303 proc_ctx->vertex_state_table.bo = bo;
1305 return VA_STATUS_ERROR_ALLOCATION_FAILED;
1307 return VA_STATUS_SUCCESS;
1311 gen75_vebox_ensure_surfaces(VADriverContextP ctx,
1312 struct intel_vebox_context *proc_ctx)
1314 struct i965_driver_data * const i965 = i965_driver_data(ctx);
1315 struct object_surface *obj_surface;
1316 VEBFrameStore *ifs, *ofs;
1317 bool is_new_frame = 0;
1320 /* Update the previous input surface */
1321 obj_surface = proc_ctx->surface_input_object;
1323 is_new_frame = proc_ctx->frame_store[FRAME_IN_CURRENT].surface_id !=
1324 obj_surface->base.id;
1326 ifs = &proc_ctx->frame_store[FRAME_IN_PREVIOUS];
1327 ofs = &proc_ctx->frame_store[proc_ctx->is_dn_enabled ?
1328 FRAME_OUT_CURRENT_DN : FRAME_IN_CURRENT];
1330 const VAProcPipelineParameterBuffer * const pipe =
1331 proc_ctx->pipeline_param;
1333 if (pipe->num_forward_references < 1)
1335 if (pipe->forward_references[0] == VA_INVALID_ID)
1338 obj_surface = SURFACE(pipe->forward_references[0]);
1339 if (!obj_surface || obj_surface->base.id == ifs->surface_id)
1342 frame_store_clear(ifs, ctx);
1343 if (obj_surface->base.id == ofs->surface_id) {
1345 frame_store_reset(ofs);
1348 ifs->obj_surface = obj_surface;
1349 ifs->surface_id = obj_surface->base.id;
1350 ifs->is_internal_surface = 0;
1351 ifs->is_scratch_surface = 0;
1356 /* Update the input surface */
1357 obj_surface = proc_ctx->surface_input_vebox_object ?
1358 proc_ctx->surface_input_vebox_object : proc_ctx->surface_input_object;
1360 ifs = &proc_ctx->frame_store[FRAME_IN_CURRENT];
1361 frame_store_clear(ifs, ctx);
1362 ifs->obj_surface = obj_surface;
1363 ifs->surface_id = proc_ctx->surface_input_object->base.id;
1364 ifs->is_internal_surface = proc_ctx->surface_input_vebox_object != NULL;
1365 ifs->is_scratch_surface = 0;
1367 /* Update the Spatial Temporal Motion Measure (STMM) surfaces */
1369 const VEBFrameStore tmpfs = proc_ctx->frame_store[FRAME_IN_STMM];
1370 proc_ctx->frame_store[FRAME_IN_STMM] =
1371 proc_ctx->frame_store[FRAME_OUT_STMM];
1372 proc_ctx->frame_store[FRAME_OUT_STMM] = tmpfs;
1375 /* Reset the output surfaces to defaults. i.e. clean from user surfaces */
1376 for (i = FRAME_OUT_CURRENT_DN; i <= FRAME_OUT_PREVIOUS; i++) {
1377 ofs = &proc_ctx->frame_store[i];
1378 if (!ofs->is_scratch_surface)
1379 ofs->obj_surface = NULL;
1380 ofs->surface_id = proc_ctx->surface_input_object->base.id;
1383 /* Update the output surfaces */
1384 obj_surface = proc_ctx->surface_output_vebox_object ?
1385 proc_ctx->surface_output_vebox_object : proc_ctx->surface_output_object;
1387 proc_ctx->current_output_type = 2;
1388 if (proc_ctx->filters_mask == VPP_DNDI_DN && !proc_ctx->is_iecp_enabled)
1389 proc_ctx->current_output = FRAME_OUT_CURRENT_DN;
1390 else if (proc_ctx->is_di_adv_enabled && !proc_ctx->is_first_frame) {
1391 proc_ctx->current_output_type = 0;
1392 proc_ctx->current_output = proc_ctx->is_second_field ?
1393 FRAME_OUT_CURRENT : FRAME_OUT_PREVIOUS;
1396 proc_ctx->current_output = FRAME_OUT_CURRENT;
1397 ofs = &proc_ctx->frame_store[proc_ctx->current_output];
1398 frame_store_clear(ofs, ctx);
1399 ofs->obj_surface = obj_surface;
1400 ofs->surface_id = proc_ctx->surface_input_object->base.id;
1401 ofs->is_internal_surface = proc_ctx->surface_output_vebox_object != NULL;
1402 ofs->is_scratch_surface = 0;
1404 return VA_STATUS_SUCCESS;
1407 VAStatus hsw_veb_pre_format_convert(VADriverContextP ctx,
1408 struct intel_vebox_context *proc_ctx)
1411 struct i965_driver_data *i965 = i965_driver_data(ctx);
1412 struct object_surface* obj_surf_input = proc_ctx->surface_input_object;
1413 struct object_surface* obj_surf_output = proc_ctx->surface_output_object;
1414 struct object_surface* obj_surf_input_vebox;
1415 struct object_surface* obj_surf_output_vebox;
1417 proc_ctx->format_convert_flags = 0;
1419 if ((obj_surf_input == NULL) &&
1420 (proc_ctx->pipeline_param->surface_region == NULL))
1421 ASSERT_RET(0, VA_STATUS_ERROR_INVALID_PARAMETER);
1423 if ((obj_surf_output == NULL) &&
1424 (proc_ctx->pipeline_param->output_region == NULL))
1425 ASSERT_RET(0, VA_STATUS_ERROR_INVALID_PARAMETER);
1427 if (proc_ctx->pipeline_param->surface_region) {
1428 proc_ctx->width_input = proc_ctx->pipeline_param->surface_region->width;
1429 proc_ctx->height_input = proc_ctx->pipeline_param->surface_region->height;
1431 proc_ctx->width_input = obj_surf_input->orig_width;
1432 proc_ctx->height_input = obj_surf_input->orig_height;
1435 if (proc_ctx->pipeline_param->output_region) {
1436 proc_ctx->width_output = proc_ctx->pipeline_param->output_region->width;
1437 proc_ctx->height_output = proc_ctx->pipeline_param->output_region->height;
1439 proc_ctx->width_output = obj_surf_output->orig_width;
1440 proc_ctx->height_output = obj_surf_output->orig_height;
1443 /* only partial frame is not supported to be processed */
1445 assert(proc_ctx->width_input == proc_ctx->pipeline_param->surface_region->width);
1446 assert(proc_ctx->height_input == proc_ctx->pipeline_param->surface_region->height);
1447 assert(proc_ctx->width_output == proc_ctx->pipeline_param->output_region->width);
1448 assert(proc_ctx->height_output == proc_ctx->pipeline_param->output_region->height);
1451 if(proc_ctx->width_output != proc_ctx->width_input ||
1452 proc_ctx->height_output != proc_ctx->height_input){
1453 proc_ctx->format_convert_flags |= POST_SCALING_CONVERT;
1456 /* convert the following format to NV12 format */
1457 if(obj_surf_input->fourcc == VA_FOURCC_YV12 ||
1458 obj_surf_input->fourcc == VA_FOURCC_I420 ||
1459 obj_surf_input->fourcc == VA_FOURCC_IMC1 ||
1460 obj_surf_input->fourcc == VA_FOURCC_IMC3 ||
1461 obj_surf_input->fourcc == VA_FOURCC_RGBA ||
1462 obj_surf_input->fourcc == VA_FOURCC_BGRA){
1464 proc_ctx->format_convert_flags |= PRE_FORMAT_CONVERT;
1466 } else if(obj_surf_input->fourcc == VA_FOURCC_AYUV ||
1467 obj_surf_input->fourcc == VA_FOURCC_YUY2 ||
1468 obj_surf_input->fourcc == VA_FOURCC_NV12 ||
1469 obj_surf_input->fourcc == VA_FOURCC_P010){
1471 // nothing to do here
1473 /* not support other format as input */
1474 ASSERT_RET(0, VA_STATUS_ERROR_UNIMPLEMENTED);
1477 if (proc_ctx->format_convert_flags & PRE_FORMAT_CONVERT) {
1478 if(proc_ctx->surface_input_vebox_object == NULL){
1479 va_status = i965_CreateSurfaces(ctx,
1480 proc_ctx->width_input,
1481 proc_ctx->height_input,
1482 VA_RT_FORMAT_YUV420,
1484 &(proc_ctx->surface_input_vebox));
1485 assert(va_status == VA_STATUS_SUCCESS);
1486 obj_surf_input_vebox = SURFACE(proc_ctx->surface_input_vebox);
1487 assert(obj_surf_input_vebox);
1489 if (obj_surf_input_vebox) {
1490 proc_ctx->surface_input_vebox_object = obj_surf_input_vebox;
1491 i965_check_alloc_surface_bo(ctx, obj_surf_input_vebox, 1, VA_FOURCC_NV12, SUBSAMPLE_YUV420);
1495 vpp_surface_convert(ctx, proc_ctx->surface_input_object, proc_ctx->surface_input_vebox_object);
1498 /* create one temporary NV12 surfaces for conversion*/
1499 if(obj_surf_output->fourcc == VA_FOURCC_YV12 ||
1500 obj_surf_output->fourcc == VA_FOURCC_I420 ||
1501 obj_surf_output->fourcc == VA_FOURCC_IMC1 ||
1502 obj_surf_output->fourcc == VA_FOURCC_IMC3 ||
1503 obj_surf_output->fourcc == VA_FOURCC_RGBA ||
1504 obj_surf_output->fourcc == VA_FOURCC_BGRA) {
1506 proc_ctx->format_convert_flags |= POST_FORMAT_CONVERT;
1507 } else if(obj_surf_output->fourcc == VA_FOURCC_AYUV ||
1508 obj_surf_output->fourcc == VA_FOURCC_YUY2 ||
1509 obj_surf_output->fourcc == VA_FOURCC_NV12 ||
1510 obj_surf_output->fourcc == VA_FOURCC_P010) {
1512 /* Nothing to do here */
1514 /* not support other format as input */
1515 ASSERT_RET(0, VA_STATUS_ERROR_UNIMPLEMENTED);
1518 if(proc_ctx->format_convert_flags & POST_FORMAT_CONVERT ||
1519 proc_ctx->format_convert_flags & POST_SCALING_CONVERT){
1520 if(proc_ctx->surface_output_vebox_object == NULL){
1521 va_status = i965_CreateSurfaces(ctx,
1522 proc_ctx->width_input,
1523 proc_ctx->height_input,
1524 VA_RT_FORMAT_YUV420,
1526 &(proc_ctx->surface_output_vebox));
1527 assert(va_status == VA_STATUS_SUCCESS);
1528 obj_surf_output_vebox = SURFACE(proc_ctx->surface_output_vebox);
1529 assert(obj_surf_output_vebox);
1531 if (obj_surf_output_vebox) {
1532 proc_ctx->surface_output_vebox_object = obj_surf_output_vebox;
1533 i965_check_alloc_surface_bo(ctx, obj_surf_output_vebox, 1, VA_FOURCC_NV12, SUBSAMPLE_YUV420);
1538 if(proc_ctx->format_convert_flags & POST_SCALING_CONVERT){
1539 if(proc_ctx->surface_output_scaled_object == NULL){
1540 va_status = i965_CreateSurfaces(ctx,
1541 proc_ctx->width_output,
1542 proc_ctx->height_output,
1543 VA_RT_FORMAT_YUV420,
1545 &(proc_ctx->surface_output_scaled));
1546 assert(va_status == VA_STATUS_SUCCESS);
1547 obj_surf_output_vebox = SURFACE(proc_ctx->surface_output_scaled);
1548 assert(obj_surf_output_vebox);
1550 if (obj_surf_output_vebox) {
1551 proc_ctx->surface_output_scaled_object = obj_surf_output_vebox;
1552 i965_check_alloc_surface_bo(ctx, obj_surf_output_vebox, 1, VA_FOURCC_NV12, SUBSAMPLE_YUV420);
1557 return VA_STATUS_SUCCESS;
1561 hsw_veb_post_format_convert(VADriverContextP ctx,
1562 struct intel_vebox_context *proc_ctx)
1564 struct object_surface *obj_surface = NULL;
1565 VAStatus va_status = VA_STATUS_SUCCESS;
1567 obj_surface = proc_ctx->frame_store[proc_ctx->current_output].obj_surface;
1569 if (proc_ctx->format_convert_flags & POST_COPY_CONVERT) {
1570 /* copy the saved frame in the second call */
1571 va_status = vpp_surface_convert(ctx, obj_surface, proc_ctx->surface_output_object);
1572 } else if(!(proc_ctx->format_convert_flags & POST_FORMAT_CONVERT) &&
1573 !(proc_ctx->format_convert_flags & POST_SCALING_CONVERT)){
1574 /* Output surface format is covered by vebox pipeline and
1575 * processed picture is already store in output surface
1576 * so nothing will be done here */
1577 } else if ((proc_ctx->format_convert_flags & POST_FORMAT_CONVERT) &&
1578 !(proc_ctx->format_convert_flags & POST_SCALING_CONVERT)){
1579 /* convert and copy NV12 to YV12/IMC3/IMC2/RGBA output*/
1580 va_status = vpp_surface_convert(ctx, obj_surface, proc_ctx->surface_output_object);
1582 } else if(proc_ctx->format_convert_flags & POST_SCALING_CONVERT) {
1583 VAProcPipelineParameterBuffer * const pipe = proc_ctx->pipeline_param;
1584 /* scaling, convert and copy NV12 to YV12/IMC3/IMC2/RGBA output*/
1585 assert(obj_surface->fourcc == VA_FOURCC_NV12);
1587 /* first step :surface scaling */
1588 vpp_surface_scaling(ctx, obj_surface,
1589 proc_ctx->surface_output_scaled_object, pipe->filter_flags);
1591 /* second step: color format convert and copy to output */
1592 obj_surface = proc_ctx->surface_output_object;
1594 va_status = vpp_surface_convert(ctx, proc_ctx->surface_output_scaled_object, obj_surface);
1601 gen75_vebox_init_pipe_params(VADriverContextP ctx,
1602 struct intel_vebox_context *proc_ctx)
1604 struct i965_driver_data * const i965 = i965_driver_data(ctx);
1605 const VAProcPipelineParameterBuffer * const pipe = proc_ctx->pipeline_param;
1606 VAProcFilterParameterBuffer *filter;
1609 proc_ctx->filters_mask = 0;
1610 for (i = 0; i < pipe->num_filters; i++) {
1611 struct object_buffer * const obj_buffer = BUFFER(pipe->filters[i]);
1613 assert(obj_buffer && obj_buffer->buffer_store);
1614 if (!obj_buffer || !obj_buffer->buffer_store)
1615 return VA_STATUS_ERROR_INVALID_PARAMETER;
1617 filter = (VAProcFilterParameterBuffer *)
1618 obj_buffer->buffer_store->buffer;
1619 switch (filter->type) {
1620 case VAProcFilterNoiseReduction:
1621 proc_ctx->filters_mask |= VPP_DNDI_DN;
1622 proc_ctx->filter_dn = filter;
1624 case VAProcFilterDeinterlacing:
1625 proc_ctx->filters_mask |= VPP_DNDI_DI;
1626 proc_ctx->filter_di = filter;
1628 case VAProcFilterColorBalance:
1629 proc_ctx->filters_mask |= VPP_IECP_PRO_AMP;
1630 proc_ctx->filter_iecp_amp = filter;
1631 proc_ctx->filter_iecp_amp_num_elements = obj_buffer->num_elements;
1633 case VAProcFilterSkinToneEnhancement:
1634 proc_ctx->filters_mask |= VPP_IECP_STD_STE;
1635 proc_ctx->filter_iecp_std = filter;
1637 case VAProcFilterSharpening:
1638 proc_ctx->filters_mask |= VPP_SHARP;
1641 WARN_ONCE("unsupported filter (type: %d)\n", filter->type);
1642 return VA_STATUS_ERROR_UNSUPPORTED_FILTER;
1646 if(proc_ctx->filters_mask == 0)
1647 proc_ctx->filters_mask |= VPP_IECP_CSC;
1649 return VA_STATUS_SUCCESS;
1653 gen75_vebox_init_filter_params(VADriverContextP ctx,
1654 struct intel_vebox_context *proc_ctx)
1656 proc_ctx->format_convert_flags = 0; /* initialized in hsw_veb_pre_format_convert() */
1658 proc_ctx->is_iecp_enabled = (proc_ctx->filters_mask & VPP_IECP_MASK) != 0;
1659 proc_ctx->is_dn_enabled = (proc_ctx->filters_mask & VPP_DNDI_DN) != 0;
1660 proc_ctx->is_di_enabled = (proc_ctx->filters_mask & VPP_DNDI_DI) != 0;
1661 proc_ctx->is_di_adv_enabled = 0;
1662 proc_ctx->is_first_frame = 0;
1663 proc_ctx->is_second_field = 0;
1665 /* Check whether we are deinterlacing the second field */
1666 if (proc_ctx->is_di_enabled) {
1667 const VAProcFilterParameterBufferDeinterlacing * const deint_params =
1668 proc_ctx->filter_di;
1670 const unsigned int tff =
1671 !(deint_params->flags & VA_DEINTERLACING_BOTTOM_FIELD_FIRST);
1672 const unsigned int is_top_field =
1673 !(deint_params->flags & VA_DEINTERLACING_BOTTOM_FIELD);
1675 if ((tff ^ is_top_field) != 0) {
1676 struct object_surface * const obj_surface =
1677 proc_ctx->surface_input_object;
1679 if (proc_ctx->frame_store[FRAME_IN_CURRENT].surface_id != obj_surface->base.id) {
1680 WARN_ONCE("invalid surface provided for second field\n");
1681 return VA_STATUS_ERROR_INVALID_PARAMETER;
1683 proc_ctx->is_second_field = 1;
1687 /* Check whether we are deinterlacing the first frame */
1688 if (proc_ctx->is_di_enabled) {
1689 const VAProcFilterParameterBufferDeinterlacing * const deint_params =
1690 proc_ctx->filter_di;
1692 switch (deint_params->algorithm) {
1693 case VAProcDeinterlacingBob:
1694 proc_ctx->is_first_frame = 1;
1696 case VAProcDeinterlacingMotionAdaptive:
1697 case VAProcDeinterlacingMotionCompensated:
1698 if (proc_ctx->frame_store[FRAME_IN_CURRENT].surface_id == VA_INVALID_ID)
1699 proc_ctx->is_first_frame = 1;
1700 else if (proc_ctx->is_second_field) {
1701 /* At this stage, we have already deinterlaced the
1702 first field successfully. So, the first frame flag
1703 is trigerred if the previous field was deinterlaced
1704 without reference frame */
1705 if (proc_ctx->frame_store[FRAME_IN_PREVIOUS].surface_id == VA_INVALID_ID)
1706 proc_ctx->is_first_frame = 1;
1709 const VAProcPipelineParameterBuffer * const pipe =
1710 proc_ctx->pipeline_param;
1712 if (pipe->num_forward_references < 1 ||
1713 pipe->forward_references[0] == VA_INVALID_ID) {
1714 WARN_ONCE("A forward temporal reference is needed for Motion adaptive/compensated deinterlacing !!!\n");
1715 return VA_STATUS_ERROR_INVALID_PARAMETER;
1718 proc_ctx->is_di_adv_enabled = 1;
1721 WARN_ONCE("unsupported deinterlacing algorithm (%d)\n",
1722 deint_params->algorithm);
1723 return VA_STATUS_ERROR_UNSUPPORTED_FILTER;
1726 return VA_STATUS_SUCCESS;
1730 gen75_vebox_process_picture(VADriverContextP ctx,
1731 struct intel_vebox_context *proc_ctx)
1735 status = gen75_vebox_init_pipe_params(ctx, proc_ctx);
1736 if (status != VA_STATUS_SUCCESS)
1739 status = gen75_vebox_init_filter_params(ctx, proc_ctx);
1740 if (status != VA_STATUS_SUCCESS)
1743 status = hsw_veb_pre_format_convert(ctx, proc_ctx);
1744 if (status != VA_STATUS_SUCCESS)
1747 status = gen75_vebox_ensure_surfaces(ctx, proc_ctx);
1748 if (status != VA_STATUS_SUCCESS)
1751 status = gen75_vebox_ensure_surfaces_storage(ctx, proc_ctx);
1752 if (status != VA_STATUS_SUCCESS)
1755 if (proc_ctx->filters_mask & VPP_SHARP_MASK) {
1756 vpp_sharpness_filtering(ctx, proc_ctx);
1757 } else if (proc_ctx->format_convert_flags & POST_COPY_CONVERT) {
1758 assert(proc_ctx->is_second_field);
1759 /* directly copy the saved frame in the second call */
1761 intel_batchbuffer_start_atomic_veb(proc_ctx->batch, 0x1000);
1762 intel_batchbuffer_emit_mi_flush(proc_ctx->batch);
1763 hsw_veb_state_table_setup(ctx, proc_ctx);
1764 hsw_veb_state_command(ctx, proc_ctx);
1765 hsw_veb_surface_state(ctx, proc_ctx, INPUT_SURFACE);
1766 hsw_veb_surface_state(ctx, proc_ctx, OUTPUT_SURFACE);
1767 hsw_veb_dndi_iecp_command(ctx, proc_ctx);
1768 intel_batchbuffer_end_atomic(proc_ctx->batch);
1769 intel_batchbuffer_flush(proc_ctx->batch);
1772 status = hsw_veb_post_format_convert(ctx, proc_ctx);
1777 void gen75_vebox_context_destroy(VADriverContextP ctx,
1778 struct intel_vebox_context *proc_ctx)
1782 if(proc_ctx->vpp_gpe_ctx){
1783 vpp_gpe_context_destroy(ctx,proc_ctx->vpp_gpe_ctx);
1784 proc_ctx->vpp_gpe_ctx = NULL;
1787 if(proc_ctx->surface_input_vebox != VA_INVALID_ID){
1788 i965_DestroySurfaces(ctx, &proc_ctx->surface_input_vebox, 1);
1789 proc_ctx->surface_input_vebox = VA_INVALID_ID;
1790 proc_ctx->surface_input_vebox_object = NULL;
1793 if(proc_ctx->surface_output_vebox != VA_INVALID_ID){
1794 i965_DestroySurfaces(ctx, &proc_ctx->surface_output_vebox, 1);
1795 proc_ctx->surface_output_vebox = VA_INVALID_ID;
1796 proc_ctx->surface_output_vebox_object = NULL;
1799 if(proc_ctx->surface_output_scaled != VA_INVALID_ID){
1800 i965_DestroySurfaces(ctx, &proc_ctx->surface_output_scaled, 1);
1801 proc_ctx->surface_output_scaled = VA_INVALID_ID;
1802 proc_ctx->surface_output_scaled_object = NULL;
1805 for (i = 0; i < ARRAY_ELEMS(proc_ctx->frame_store); i++)
1806 frame_store_clear(&proc_ctx->frame_store[i], ctx);
1808 /* dndi state table */
1809 drm_intel_bo_unreference(proc_ctx->dndi_state_table.bo);
1810 proc_ctx->dndi_state_table.bo = NULL;
1812 /* iecp state table */
1813 drm_intel_bo_unreference(proc_ctx->iecp_state_table.bo);
1814 proc_ctx->iecp_state_table.bo = NULL;
1816 /* gamut statu table */
1817 drm_intel_bo_unreference(proc_ctx->gamut_state_table.bo);
1818 proc_ctx->gamut_state_table.bo = NULL;
1820 /* vertex state table */
1821 drm_intel_bo_unreference(proc_ctx->vertex_state_table.bo);
1822 proc_ctx->vertex_state_table.bo = NULL;
1824 intel_batchbuffer_free(proc_ctx->batch);
1829 struct intel_vebox_context * gen75_vebox_context_init(VADriverContextP ctx)
1831 struct intel_driver_data *intel = intel_driver_data(ctx);
1832 struct intel_vebox_context *proc_context = calloc(1, sizeof(struct intel_vebox_context));
1835 assert(proc_context);
1836 proc_context->batch = intel_batchbuffer_new(intel, I915_EXEC_VEBOX, 0);
1838 for (i = 0; i < ARRAY_ELEMS(proc_context->frame_store); i++)
1839 proc_context->frame_store[i].surface_id = VA_INVALID_ID;
1841 proc_context->filters_mask = 0;
1842 proc_context->surface_output_object = NULL;
1843 proc_context->surface_input_object = NULL;
1844 proc_context->surface_input_vebox = VA_INVALID_ID;
1845 proc_context->surface_input_vebox_object = NULL;
1846 proc_context->surface_output_vebox = VA_INVALID_ID;
1847 proc_context->surface_output_vebox_object = NULL;
1848 proc_context->surface_output_scaled = VA_INVALID_ID;
1849 proc_context->surface_output_scaled_object = NULL;
1850 proc_context->filters_mask = 0;
1851 proc_context->format_convert_flags = 0;
1852 proc_context->vpp_gpe_ctx = NULL;
1854 return proc_context;
1857 void bdw_veb_state_command(VADriverContextP ctx, struct intel_vebox_context *proc_ctx)
1859 struct intel_batchbuffer *batch = proc_ctx->batch;
1861 BEGIN_VEB_BATCH(batch, 0xc);
1862 OUT_VEB_BATCH(batch, VEB_STATE | (0xc - 2));
1863 OUT_VEB_BATCH(batch,
1864 0 << 25 | // state surface control bits
1865 0 << 23 | // reserved.
1866 0 << 22 | // gamut expansion position
1867 0 << 15 | // reserved.
1868 0 << 14 | // single slice vebox enable
1869 0 << 13 | // hot pixel filter enable
1870 0 << 12 | // alpha plane enable
1871 0 << 11 | // vignette enable
1872 0 << 10 | // demosaic enable
1873 proc_ctx->current_output_type << 8 | // DI output frame
1874 1 << 7 | // 444->422 downsample method
1875 1 << 6 | // 422->420 downsample method
1876 proc_ctx->is_first_frame << 5 | // DN/DI first frame
1877 proc_ctx->is_di_enabled << 4 | // DI enable
1878 proc_ctx->is_dn_enabled << 3 | // DN enable
1879 proc_ctx->is_iecp_enabled << 2 | // global IECP enabled
1880 0 << 1 | // ColorGamutCompressionEnable
1881 0 ) ; // ColorGamutExpansionEnable.
1884 proc_ctx->dndi_state_table.bo,
1885 I915_GEM_DOMAIN_INSTRUCTION, 0, 0);
1887 OUT_VEB_BATCH(batch, 0);
1890 proc_ctx->iecp_state_table.bo,
1891 I915_GEM_DOMAIN_INSTRUCTION, 0, 0);
1893 OUT_VEB_BATCH(batch, 0);
1896 proc_ctx->gamut_state_table.bo,
1897 I915_GEM_DOMAIN_INSTRUCTION, 0, 0);
1899 OUT_VEB_BATCH(batch, 0);
1902 proc_ctx->vertex_state_table.bo,
1903 I915_GEM_DOMAIN_INSTRUCTION, 0, 0);
1905 OUT_VEB_BATCH(batch, 0);
1907 OUT_VEB_BATCH(batch, 0);/*caputre pipe state pointer*/
1908 OUT_VEB_BATCH(batch, 0);
1910 ADVANCE_VEB_BATCH(batch);
1913 void bdw_veb_dndi_iecp_command(VADriverContextP ctx, struct intel_vebox_context *proc_ctx)
1915 struct intel_batchbuffer *batch = proc_ctx->batch;
1916 unsigned char frame_ctrl_bits = 0;
1917 struct object_surface *obj_surface = proc_ctx->frame_store[FRAME_IN_CURRENT].obj_surface;
1918 unsigned int width64 = ALIGN(proc_ctx->width_input, 64);
1920 assert(obj_surface);
1921 if (width64 > obj_surface->orig_width)
1922 width64 = obj_surface->orig_width;
1924 BEGIN_VEB_BATCH(batch, 0x14);
1925 OUT_VEB_BATCH(batch, VEB_DNDI_IECP_STATE | (0x14 - 2));//DWord 0
1926 OUT_VEB_BATCH(batch, (width64 - 1));
1929 proc_ctx->frame_store[FRAME_IN_CURRENT].obj_surface->bo,
1930 I915_GEM_DOMAIN_RENDER, 0, frame_ctrl_bits);//DWord 2
1931 OUT_VEB_BATCH(batch,0);//DWord 3
1934 proc_ctx->frame_store[FRAME_IN_PREVIOUS].obj_surface->bo,
1935 I915_GEM_DOMAIN_RENDER, 0, frame_ctrl_bits);//DWord 4
1936 OUT_VEB_BATCH(batch,0);//DWord 5
1939 proc_ctx->frame_store[FRAME_IN_STMM].obj_surface->bo,
1940 I915_GEM_DOMAIN_RENDER, 0, frame_ctrl_bits);//DWord 6
1941 OUT_VEB_BATCH(batch,0);//DWord 7
1944 proc_ctx->frame_store[FRAME_OUT_STMM].obj_surface->bo,
1945 I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, frame_ctrl_bits);//DWord 8
1946 OUT_VEB_BATCH(batch,0);//DWord 9
1949 proc_ctx->frame_store[FRAME_OUT_CURRENT_DN].obj_surface->bo,
1950 I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, frame_ctrl_bits);//DWord 10
1951 OUT_VEB_BATCH(batch,0);//DWord 11
1954 proc_ctx->frame_store[FRAME_OUT_CURRENT].obj_surface->bo,
1955 I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, frame_ctrl_bits);//DWord 12
1956 OUT_VEB_BATCH(batch,0);//DWord 13
1959 proc_ctx->frame_store[FRAME_OUT_PREVIOUS].obj_surface->bo,
1960 I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, frame_ctrl_bits);//DWord 14
1961 OUT_VEB_BATCH(batch,0);//DWord 15
1964 proc_ctx->frame_store[FRAME_OUT_STATISTIC].obj_surface->bo,
1965 I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, frame_ctrl_bits);//DWord 16
1966 OUT_VEB_BATCH(batch,0);//DWord 17
1968 OUT_VEB_BATCH(batch,0);//DWord 18
1969 OUT_VEB_BATCH(batch,0);//DWord 19
1971 ADVANCE_VEB_BATCH(batch);
1975 gen8_vebox_process_picture(VADriverContextP ctx,
1976 struct intel_vebox_context *proc_ctx)
1980 status = gen75_vebox_init_pipe_params(ctx, proc_ctx);
1981 if (status != VA_STATUS_SUCCESS)
1984 status = gen75_vebox_init_filter_params(ctx, proc_ctx);
1985 if (status != VA_STATUS_SUCCESS)
1988 status = hsw_veb_pre_format_convert(ctx, proc_ctx);
1989 if (status != VA_STATUS_SUCCESS)
1992 status = gen75_vebox_ensure_surfaces(ctx, proc_ctx);
1993 if (status != VA_STATUS_SUCCESS)
1996 status = gen75_vebox_ensure_surfaces_storage(ctx, proc_ctx);
1997 if (status != VA_STATUS_SUCCESS)
2000 if (proc_ctx->filters_mask & VPP_SHARP_MASK) {
2001 vpp_sharpness_filtering(ctx, proc_ctx);
2002 } else if (proc_ctx->format_convert_flags & POST_COPY_CONVERT) {
2003 assert(proc_ctx->is_second_field);
2004 /* directly copy the saved frame in the second call */
2006 intel_batchbuffer_start_atomic_veb(proc_ctx->batch, 0x1000);
2007 intel_batchbuffer_emit_mi_flush(proc_ctx->batch);
2008 hsw_veb_state_table_setup(ctx, proc_ctx);
2009 bdw_veb_state_command(ctx, proc_ctx);
2010 hsw_veb_surface_state(ctx, proc_ctx, INPUT_SURFACE);
2011 hsw_veb_surface_state(ctx, proc_ctx, OUTPUT_SURFACE);
2012 bdw_veb_dndi_iecp_command(ctx, proc_ctx);
2013 intel_batchbuffer_end_atomic(proc_ctx->batch);
2014 intel_batchbuffer_flush(proc_ctx->batch);
2017 status = hsw_veb_post_format_convert(ctx, proc_ctx);
2024 skl_veb_dndi_table(VADriverContextP ctx, struct intel_vebox_context *proc_ctx)
2026 unsigned int* p_table ;
2027 unsigned int progressive_dn = 1;
2028 unsigned int dndi_top_first = 0;
2029 unsigned int is_mcdi_enabled = 0;
2031 if (proc_ctx->is_di_enabled) {
2032 const VAProcFilterParameterBufferDeinterlacing * const deint_params =
2033 proc_ctx->filter_di;
2037 /* If we are in "First Frame" mode, i.e. past frames are not
2038 available for motion measure, then don't use the TFF flag */
2039 dndi_top_first = !(deint_params->flags & (proc_ctx->is_first_frame ?
2040 VA_DEINTERLACING_BOTTOM_FIELD :
2041 VA_DEINTERLACING_BOTTOM_FIELD_FIRST));
2044 (deint_params->algorithm == VAProcDeinterlacingMotionCompensated);
2048 VAProcFilterParameterBufferDeinterlacing *di_param =
2049 (VAProcFilterParameterBufferDeinterlacing *) proc_ctx->filter_di;
2051 VAProcFilterParameterBuffer * dn_param =
2052 (VAProcFilterParameterBuffer *) proc_ctx->filter_dn;
2054 p_table = (unsigned int *)proc_ctx->dndi_state_table.ptr;
2056 *p_table ++ = ( 140 << 20 | // denoise stad threshold . w1
2057 192 << 12 | // dnmh_history_max
2058 7 << 8 | // dnmh_delta[3:0]
2059 1 ); // denoise moving pixel threshold
2061 *p_table ++ = ( 38 << 20 | // denoise asd threshold
2062 0 << 10 | // temporal diff th
2063 0 ); // low temporal diff th
2065 *p_table ++ = ( progressive_dn << 28 | // progressive dn
2066 38 << 16 | // denoise th for sum of complexity measure
2067 32 << 10 | // dnmh_history_init[5:0]
2070 *p_table ++ = ( 0 << 28 | // hot pixel count
2071 0 << 20 | // hot pixel threshold
2072 1 << 12 | // block noise estimate edge threshold
2073 20 ); // block noise estimate noise threshold
2075 *p_table ++ = ( 140<< 16 | // chroma denoise stad threshold
2076 0 << 13 | // reserved
2077 1 << 12 | // chrome denoise enable
2078 13 << 6 | // chr temp diff th
2079 7 ); // chr temp diff low
2081 *p_table ++ = 0; // weight
2083 *p_table ++ = ( 0 << 16 | // dn_thmax
2086 *p_table ++ = ( 0 << 16 | // dn_prt5
2087 0 ); // dn_dyn_thmin
2089 *p_table ++ = ( 0 << 16 | // dn_prt4
2092 *p_table ++ = ( 0 << 16 | // dn_prt2
2095 *p_table ++ = ( 0 << 16 | // dn_prt0
2096 0 << 10 | // dn_wd22
2100 *p_table ++ = ( 0 << 25 | // dn_wd12
2101 0 << 20 | // dn_wd11
2102 0 << 15 | // dn_wd10
2103 0 << 10 | // dn_wd02
2107 *p_table ++ = ( 2 << 10 | // stmm c2
2108 9 << 6 | // cat slope minus 1
2109 5 << 2 | // sad tight threshold
2110 0 ); // smooth mv th
2112 *p_table ++ = ( 0 << 31 | // stmm blending constant select
2113 64 << 24 | // stmm trc1
2114 125<< 16 | // stmm trc2
2115 0 << 14 | // reserved
2116 30 << 8 | // multiplier for vecm
2117 150 ); // maximum stmm
2119 *p_table ++ = ( 118<< 24 | // minumum stmm
2120 0 << 22 | // stmm shift down
2121 1 << 20 | // stmm shift up
2122 5 << 16 | // stmm output shift
2123 100 << 8 | // sdi threshold
2126 *p_table ++ = ( 50 << 24 | // sdi fallback mode 1 t1 constant
2127 100 << 16 | // sdi fallback mode 1 t2 constant
2128 37 << 8 | // sdi fallback mode 2 constant(angle2x1)
2129 175 ); // fmd temporal difference threshold
2131 *p_table ++ = ( 16 << 24 | // fmd #1 vertical difference th . w7
2132 100<< 16 | // fmd #2 vertical difference th
2133 0 << 14 | // cat threshold
2134 2 << 8 | // fmd tear threshold
2135 is_mcdi_enabled << 7 | // mcdi enable, use motion compensated deinterlace algorithm
2136 dndi_top_first << 3 | // dn/di top first
2139 *p_table ++ = ( 10 << 19 | // neighbor pixel threshold
2140 0 << 16 | // fmd for 2nd field of previous frame
2141 25 << 10 | // mc pixel consistency threshold
2142 0 << 8 | // fmd for 1st field for current frame
2143 10 << 4 | // sad thb
2147 void skl_veb_iecp_csc_transform_table(VADriverContextP ctx, struct intel_vebox_context *proc_ctx)
2149 unsigned int *p_table = (unsigned int*)(proc_ctx->iecp_state_table.ptr + 220);
2150 float tran_coef[9] = {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0};
2151 float v_coef[3] = {0.0, 0.0, 0.0};
2152 float u_coef[3] = {0.0, 0.0, 0.0};
2153 int is_transform_enabled = 0;
2155 if(!(proc_ctx->filters_mask & VPP_IECP_CSC_TRANSFORM)){
2156 memset(p_table, 0, 12 * 4);
2160 if(proc_ctx->fourcc_input == VA_FOURCC_RGBA &&
2161 (proc_ctx->fourcc_output == VA_FOURCC_NV12 ||
2162 proc_ctx->fourcc_output == VA_FOURCC_YV12 ||
2163 proc_ctx->fourcc_output == VA_FOURCC_YVY2 ||
2164 proc_ctx->fourcc_output == VA_FOURCC_AYUV)) {
2166 tran_coef[0] = 0.257;
2167 tran_coef[1] = 0.504;
2168 tran_coef[2] = 0.098;
2169 tran_coef[3] = -0.148;
2170 tran_coef[4] = -0.291;
2171 tran_coef[5] = 0.439;
2172 tran_coef[6] = 0.439;
2173 tran_coef[7] = -0.368;
2174 tran_coef[8] = -0.071;
2177 u_coef[1] = 128 * 4;
2178 u_coef[2] = 128 * 4;
2180 is_transform_enabled = 1;
2181 }else if((proc_ctx->fourcc_input == VA_FOURCC_NV12 ||
2182 proc_ctx->fourcc_input == VA_FOURCC_YV12 ||
2183 proc_ctx->fourcc_input == VA_FOURCC_YUY2 ||
2184 proc_ctx->fourcc_input == VA_FOURCC_AYUV) &&
2185 proc_ctx->fourcc_output == VA_FOURCC_RGBA) {
2186 tran_coef[0] = 1.164;
2187 tran_coef[1] = 0.000;
2188 tran_coef[2] = 1.569;
2189 tran_coef[3] = 1.164;
2190 tran_coef[4] = -0.813;
2191 tran_coef[5] = -0.392;
2192 tran_coef[6] = 1.164;
2193 tran_coef[7] = 2.017;
2194 tran_coef[8] = 0.000;
2196 v_coef[0] = -16 * 4;
2197 v_coef[1] = -128 * 4;
2198 v_coef[2] = -128 * 4;
2200 is_transform_enabled = 1;
2201 }else if(proc_ctx->fourcc_input != proc_ctx->fourcc_output){
2202 //enable when input and output format are different.
2203 is_transform_enabled = 1;
2206 if(is_transform_enabled == 0){
2207 memset(p_table, 0, 12 * 4);
2209 *p_table ++ = ( is_transform_enabled << 31 |
2210 0 << 29 | // yuv_channel swap
2211 intel_format_convert(tran_coef[0], 2, 16, 1)); //c0, s2.16 format
2213 *p_table ++ = ( 0 << 19 | //reserved
2214 intel_format_convert(tran_coef[1], 2, 16, 1)); //c1, s2.16 format
2216 *p_table ++ = ( 0 << 19 | //reserved
2217 intel_format_convert(tran_coef[2], 2, 16, 1)); //c2, s2.16 format
2219 *p_table ++ = ( 0 << 19 | //reserved
2220 intel_format_convert(tran_coef[3], 2, 16, 1)); //c3, s2.16 format
2222 *p_table ++ = ( 0 << 19 | //reserved
2223 intel_format_convert(tran_coef[4], 2, 16, 1)); //c4, s2.16 format
2225 *p_table ++ = ( 0 << 19 | //reserved
2226 intel_format_convert(tran_coef[5], 2, 16, 1)); //c5, s2.16 format
2228 *p_table ++ = ( 0 << 19 | //reserved
2229 intel_format_convert(tran_coef[6], 2, 16, 1)); //c6, s2.16 format
2231 *p_table ++ = ( 0 << 19 | //reserved
2232 intel_format_convert(tran_coef[7], 2, 16, 1)); //c7, s2.16 format
2234 *p_table ++ = ( 0 << 19 | //reserved
2235 intel_format_convert(tran_coef[8], 2, 16, 1)); //c8, s2.16 format
2237 *p_table ++ = ( intel_format_convert(u_coef[0], 16, 0, 1) << 16 |
2238 intel_format_convert(v_coef[0], 16, 0, 1));
2240 *p_table ++ = ( intel_format_convert(u_coef[1], 16, 0, 1) << 16 |
2241 intel_format_convert(v_coef[1], 16, 0, 1));
2243 *p_table ++ = ( intel_format_convert(u_coef[2], 16, 0, 1) << 16 |
2244 intel_format_convert(v_coef[2], 16, 0, 1));
2248 void skl_veb_iecp_aoi_table(VADriverContextP ctx, struct intel_vebox_context *proc_ctx)
2250 unsigned int *p_table = (unsigned int*)(proc_ctx->iecp_state_table.ptr + 27 * sizeof(unsigned int));
2252 if (!(proc_ctx->filters_mask & VPP_IECP_AOI)) {
2253 memset(p_table, 0, 3 * 4);
2255 *p_table ++ = 0x00000000;
2256 *p_table ++ = 0x00030000;
2257 *p_table ++ = 0x00030000;
2261 void skl_veb_state_table_setup(VADriverContextP ctx, struct intel_vebox_context *proc_ctx)
2263 if(proc_ctx->filters_mask & VPP_DNDI_MASK) {
2264 dri_bo *dndi_bo = proc_ctx->dndi_state_table.bo;
2265 dri_bo_map(dndi_bo, 1);
2266 proc_ctx->dndi_state_table.ptr = dndi_bo->virtual;
2268 skl_veb_dndi_table(ctx, proc_ctx);
2270 dri_bo_unmap(dndi_bo);
2273 if(proc_ctx->filters_mask & VPP_IECP_MASK) {
2274 dri_bo *iecp_bo = proc_ctx->iecp_state_table.bo;
2275 dri_bo_map(iecp_bo, 1);
2276 proc_ctx->iecp_state_table.ptr = iecp_bo->virtual;
2277 memset(proc_ctx->iecp_state_table.ptr, 0, 90 * 4);
2279 hsw_veb_iecp_std_table(ctx, proc_ctx);
2280 hsw_veb_iecp_ace_table(ctx, proc_ctx);
2281 hsw_veb_iecp_tcc_table(ctx, proc_ctx);
2282 hsw_veb_iecp_pro_amp_table(ctx, proc_ctx);
2283 skl_veb_iecp_csc_transform_table(ctx, proc_ctx);
2284 skl_veb_iecp_aoi_table(ctx, proc_ctx);
2286 dri_bo_unmap(iecp_bo);
2291 skl_veb_state_command(VADriverContextP ctx, struct intel_vebox_context *proc_ctx)
2293 struct intel_batchbuffer *batch = proc_ctx->batch;
2295 BEGIN_VEB_BATCH(batch, 0x10);
2296 OUT_VEB_BATCH(batch, VEB_STATE | (0x10 - 2));
2297 OUT_VEB_BATCH(batch,
2298 0 << 25 | // state surface control bits
2299 0 << 23 | // reserved.
2300 0 << 22 | // gamut expansion position
2301 0 << 15 | // reserved.
2302 0 << 14 | // single slice vebox enable
2303 0 << 13 | // hot pixel filter enable
2304 0 << 12 | // alpha plane enable
2305 0 << 11 | // vignette enable
2306 0 << 10 | // demosaic enable
2307 proc_ctx->current_output_type << 8 | // DI output frame
2308 1 << 7 | // 444->422 downsample method
2309 1 << 6 | // 422->420 downsample method
2310 proc_ctx->is_first_frame << 5 | // DN/DI first frame
2311 proc_ctx->is_di_enabled << 4 | // DI enable
2312 proc_ctx->is_dn_enabled << 3 | // DN enable
2313 proc_ctx->is_iecp_enabled << 2 | // global IECP enabled
2314 0 << 1 | // ColorGamutCompressionEnable
2315 0 ) ; // ColorGamutExpansionEnable.
2318 proc_ctx->dndi_state_table.bo,
2319 I915_GEM_DOMAIN_INSTRUCTION, 0, 0);
2321 OUT_VEB_BATCH(batch, 0);
2324 proc_ctx->iecp_state_table.bo,
2325 I915_GEM_DOMAIN_INSTRUCTION, 0, 0);
2327 OUT_VEB_BATCH(batch, 0);
2330 proc_ctx->gamut_state_table.bo,
2331 I915_GEM_DOMAIN_INSTRUCTION, 0, 0);
2333 OUT_VEB_BATCH(batch, 0);
2336 proc_ctx->vertex_state_table.bo,
2337 I915_GEM_DOMAIN_INSTRUCTION, 0, 0);
2339 OUT_VEB_BATCH(batch, 0);
2341 OUT_VEB_BATCH(batch, 0);/*caputre pipe state pointer*/
2342 OUT_VEB_BATCH(batch, 0);
2344 OUT_VEB_BATCH(batch, 0);/*lace lut table state pointer*/
2345 OUT_VEB_BATCH(batch, 0);
2347 OUT_VEB_BATCH(batch, 0);/*gamma correction values address*/
2348 OUT_VEB_BATCH(batch, 0);
2350 ADVANCE_VEB_BATCH(batch);
2353 void skl_veb_surface_state(VADriverContextP ctx, struct intel_vebox_context *proc_ctx, unsigned int is_output)
2355 struct intel_batchbuffer *batch = proc_ctx->batch;
2356 unsigned int u_offset_y = 0, v_offset_y = 0;
2357 unsigned int is_uv_interleaved = 0, tiling = 0, swizzle = 0;
2358 unsigned int surface_format = PLANAR_420_8;
2359 struct object_surface* obj_surf = NULL;
2360 unsigned int surface_pitch = 0;
2361 unsigned int half_pitch_chroma = 0;
2362 unsigned int derived_pitch;
2365 obj_surf = proc_ctx->frame_store[FRAME_OUT_CURRENT].obj_surface;
2367 obj_surf = proc_ctx->frame_store[FRAME_IN_CURRENT].obj_surface;
2370 assert(obj_surf->fourcc == VA_FOURCC_NV12 ||
2371 obj_surf->fourcc == VA_FOURCC_YUY2 ||
2372 obj_surf->fourcc == VA_FOURCC_AYUV ||
2373 obj_surf->fourcc == VA_FOURCC_RGBA ||
2374 obj_surf->fourcc == VA_FOURCC_P010);
2376 if (obj_surf->fourcc == VA_FOURCC_NV12) {
2377 surface_format = PLANAR_420_8;
2378 surface_pitch = obj_surf->width;
2379 is_uv_interleaved = 1;
2380 half_pitch_chroma = 0;
2381 } else if (obj_surf->fourcc == VA_FOURCC_YUY2) {
2382 surface_format = YCRCB_NORMAL;
2383 surface_pitch = obj_surf->width * 2;
2384 is_uv_interleaved = 0;
2385 half_pitch_chroma = 0;
2386 } else if (obj_surf->fourcc == VA_FOURCC_AYUV) {
2387 surface_format = PACKED_444A_8;
2388 surface_pitch = obj_surf->width * 4;
2389 is_uv_interleaved = 0;
2390 half_pitch_chroma = 0;
2391 } else if (obj_surf->fourcc == VA_FOURCC_RGBA) {
2392 surface_format = R8G8B8A8_UNORM_SRGB;
2393 surface_pitch = obj_surf->width * 4;
2394 is_uv_interleaved = 0;
2395 half_pitch_chroma = 0;
2396 } else if (obj_surf->fourcc == VA_FOURCC_P010) {
2397 surface_format = PLANAR_420_16;
2398 surface_pitch = obj_surf->width;
2399 is_uv_interleaved = 1;
2400 half_pitch_chroma = 0;
2403 derived_pitch = surface_pitch;
2405 u_offset_y = obj_surf->y_cb_offset;
2406 v_offset_y = obj_surf->y_cr_offset;
2408 dri_bo_get_tiling(obj_surf->bo, &tiling, &swizzle);
2410 BEGIN_VEB_BATCH(batch, 9);
2411 OUT_VEB_BATCH(batch, VEB_SURFACE_STATE | (9 - 2));
2412 OUT_VEB_BATCH(batch,
2413 0 << 1 | // reserved
2414 is_output); // surface indentification.
2416 OUT_VEB_BATCH(batch,
2417 (obj_surf->orig_height - 1) << 18 | // height . w3
2418 (obj_surf->orig_width - 1) << 4 | // width
2421 OUT_VEB_BATCH(batch,
2422 surface_format << 28 | // surface format, YCbCr420. w4
2423 is_uv_interleaved << 27 | // interleave chrome , two seperate palar
2424 0 << 20 | // reserved
2425 (surface_pitch - 1) << 3 | // surface pitch, 64 align
2426 half_pitch_chroma << 2 | // half pitch for chrome
2427 !!tiling << 1 | // tiled surface, linear surface used
2428 (tiling == I915_TILING_Y)); // tiled walk, ignored when liner surface
2430 OUT_VEB_BATCH(batch,
2431 0 << 16 | // X offset for V(Cb)
2432 u_offset_y); // Y offset for V(Cb)
2434 OUT_VEB_BATCH(batch,
2435 0 << 16 | // X offset for V(Cr)
2436 v_offset_y ); // Y offset for V(Cr)
2438 OUT_VEB_BATCH(batch, 0);
2440 OUT_VEB_BATCH(batch, derived_pitch - 1);
2442 OUT_VEB_BATCH(batch, 0);
2444 ADVANCE_VEB_BATCH(batch);
2448 gen9_vebox_process_picture(VADriverContextP ctx,
2449 struct intel_vebox_context *proc_ctx)
2453 status = gen75_vebox_init_pipe_params(ctx, proc_ctx);
2454 if (status != VA_STATUS_SUCCESS)
2457 status = gen75_vebox_init_filter_params(ctx, proc_ctx);
2458 if (status != VA_STATUS_SUCCESS)
2461 status = hsw_veb_pre_format_convert(ctx, proc_ctx);
2462 if (status != VA_STATUS_SUCCESS)
2465 status = gen75_vebox_ensure_surfaces(ctx, proc_ctx);
2466 if (status != VA_STATUS_SUCCESS)
2469 status = gen75_vebox_ensure_surfaces_storage(ctx, proc_ctx);
2470 if (status != VA_STATUS_SUCCESS)
2473 if (proc_ctx->filters_mask & VPP_SHARP_MASK) {
2474 vpp_sharpness_filtering(ctx, proc_ctx);
2475 } else if (proc_ctx->format_convert_flags & POST_COPY_CONVERT) {
2476 assert(proc_ctx->is_second_field);
2477 /* directly copy the saved frame in the second call */
2479 intel_batchbuffer_start_atomic_veb(proc_ctx->batch, 0x1000);
2480 intel_batchbuffer_emit_mi_flush(proc_ctx->batch);
2481 skl_veb_state_table_setup(ctx, proc_ctx);
2482 skl_veb_state_command(ctx, proc_ctx);
2483 skl_veb_surface_state(ctx, proc_ctx, INPUT_SURFACE);
2484 skl_veb_surface_state(ctx, proc_ctx, OUTPUT_SURFACE);
2485 bdw_veb_dndi_iecp_command(ctx, proc_ctx);
2486 intel_batchbuffer_end_atomic(proc_ctx->batch);
2487 intel_batchbuffer_flush(proc_ctx->batch);
2490 status = hsw_veb_post_format_convert(ctx, proc_ctx);