Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /*
  2.  * Copyright © 2011 Intel Corporation
  3.  *
  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:
  11.  *
  12.  * The above copyright notice and this permission notice (including the
  13.  * next paragraph) shall be included in all copies or substantial portions
  14.  * of the Software.
  15.  *
  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.
  23.  *
  24.  * Authors:
  25.  *   Li Xiaowei <xiaowei.a.li@intel.com>
  26.  *   Li Zhong <zhong.li@intel.com>
  27.  */
  28.  
  29. #include <stdio.h>
  30. #include <stdlib.h>
  31. #include <string.h>
  32. #include <assert.h>
  33. #include <math.h>
  34.  
  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"
  41.  
  42. #define PI  3.1415926
  43.  
  44. extern VAStatus
  45. i965_MapBuffer(VADriverContextP ctx, VABufferID buf_id, void **);
  46.  
  47. extern VAStatus
  48. i965_UnmapBuffer(VADriverContextP ctx, VABufferID buf_id);
  49.  
  50. extern VAStatus
  51. i965_DeriveImage(VADriverContextP ctx, VABufferID surface, VAImage *out_image);
  52.  
  53. extern VAStatus
  54. i965_DestroyImage(VADriverContextP ctx, VAImageID image);
  55.  
  56.  
  57. VAStatus vpp_surface_convert(VADriverContextP ctx,
  58.                              struct object_surface *src_obj_surf,
  59.                              struct object_surface *dst_obj_surf)
  60. {
  61.     VAStatus va_status = VA_STATUS_SUCCESS;
  62.  
  63.     assert(src_obj_surf->orig_width  == dst_obj_surf->orig_width);
  64.     assert(src_obj_surf->orig_height == dst_obj_surf->orig_height);
  65.  
  66.     VARectangle src_rect, dst_rect;
  67.     src_rect.x = dst_rect.x = 0;
  68.     src_rect.y = dst_rect.y = 0;
  69.     src_rect.width  = dst_rect.width  = src_obj_surf->orig_width;
  70.     src_rect.height = dst_rect.height = dst_obj_surf->orig_height;
  71.  
  72.     struct i965_surface src_surface, dst_surface;
  73.     src_surface.base  = (struct object_base *)src_obj_surf;
  74.     src_surface.type  = I965_SURFACE_TYPE_SURFACE;
  75.     src_surface.flags = I965_SURFACE_FLAG_FRAME;
  76.  
  77.     dst_surface.base  = (struct object_base *)dst_obj_surf;
  78.     dst_surface.type  = I965_SURFACE_TYPE_SURFACE;
  79.     dst_surface.flags = I965_SURFACE_FLAG_FRAME;
  80.  
  81.     va_status = i965_image_processing(ctx,
  82.                                      &src_surface,
  83.                                      &src_rect,
  84.                                      &dst_surface,
  85.                                      &dst_rect);
  86.     return va_status;
  87. }
  88.  
  89. VAStatus vpp_surface_scaling(VADriverContextP ctx,
  90.                              struct object_surface *dst_obj_surf,
  91.                              struct object_surface *src_obj_surf)
  92. {
  93.     VAStatus va_status = VA_STATUS_SUCCESS;
  94.     int flags = I965_PP_FLAG_AVS;
  95.  
  96.     assert(src_obj_surf->fourcc == VA_FOURCC_NV12);
  97.     assert(dst_obj_surf->fourcc == VA_FOURCC_NV12);
  98.  
  99.     VARectangle src_rect, dst_rect;
  100.     src_rect.x = 0;
  101.     src_rect.y = 0;
  102.     src_rect.width  = src_obj_surf->orig_width;
  103.     src_rect.height = src_obj_surf->orig_height;
  104.  
  105.     dst_rect.x = 0;
  106.     dst_rect.y = 0;
  107.     dst_rect.width  = dst_obj_surf->orig_width;
  108.     dst_rect.height = dst_obj_surf->orig_height;
  109.  
  110.     va_status = i965_scaling_processing(ctx,
  111.                                        src_obj_surf,
  112.                                        &src_rect,
  113.                                        dst_obj_surf,
  114.                                        &dst_rect,
  115.                                        flags);
  116.      
  117.     return va_status;
  118. }
  119.  
  120. void hsw_veb_dndi_table(VADriverContextP ctx, struct intel_vebox_context *proc_ctx)
  121. {
  122.     struct i965_driver_data *i965 = i965_driver_data(ctx);
  123.     unsigned int* p_table ;
  124.     int progressive_dn = 1;
  125.     int dndi_top_first = 0;
  126.     int motion_compensated_enable = 0;
  127.  
  128.     if (proc_ctx->filters_mask & VPP_DNDI_DI) {
  129.         VAProcFilterParameterBufferDeinterlacing *di_param =
  130.             (VAProcFilterParameterBufferDeinterlacing *)proc_ctx->filter_di;
  131.         assert(di_param);
  132.  
  133.         progressive_dn = 0;
  134.         dndi_top_first = !(di_param->flags & VA_DEINTERLACING_BOTTOM_FIELD);
  135.         motion_compensated_enable = (di_param->algorithm == VAProcDeinterlacingMotionCompensated);
  136.     }
  137.  
  138.     /*
  139.     VAProcFilterParameterBufferDeinterlacing *di_param =
  140.             (VAProcFilterParameterBufferDeinterlacing *) proc_ctx->filter_di;
  141.  
  142.     VAProcFilterParameterBuffer * dn_param =
  143.             (VAProcFilterParameterBuffer *) proc_ctx->filter_dn;
  144.     */
  145.     p_table = (unsigned int *)proc_ctx->dndi_state_table.ptr;
  146.  
  147.      if (IS_HASWELL(i965->intel.device_info))
  148.          *p_table ++ = 0;               // reserved  . w0
  149.  
  150.     *p_table ++ = ( 140 << 24 |    // denoise STAD threshold . w1
  151.                     192 << 16 |    // dnmh_history_max
  152.                     0   << 12 |    // reserved
  153.                     7   << 8  |    // dnmh_delta[3:0]
  154.                     38 );          // denoise ASD threshold
  155.  
  156.     *p_table ++ = ( 0  << 30 |    // reserved . w2
  157.                     0  << 24 |    // temporal diff th
  158.                     0  << 22 |    // reserved.
  159.                     0  << 16 |    // low temporal diff th
  160.                     2  << 13 |    // STMM C2
  161.                     1  << 8  |    // denoise moving pixel th
  162.                     38 );         // denoise th for sum of complexity measure
  163.  
  164.     *p_table ++ = ( 0 << 30  |   // reserved . w3
  165.                     12<< 24  |   // good neighbor th[5:0]
  166.                     9 << 20  |   // CAT slope minus 1
  167.                     5 << 16  |   // SAD Tight in
  168.                     0 << 14  |   // smooth mv th
  169.                     0 << 12  |   // reserved
  170.                     1 << 8   |   // bne_edge_th[3:0]
  171.                     20 );        // block noise estimate noise th
  172.  
  173.     *p_table ++ = ( 0  << 31  |  // STMM blending constant select. w4
  174.                     64 << 24  |  // STMM trc1
  175.                     125<< 16  |  // STMM trc2
  176.                     0  << 14  |  // reserved
  177.                     30 << 8   |  // VECM_mul
  178.                     150 );       // maximum STMM
  179.  
  180.     *p_table ++ = ( 118<< 24  |  // minumum STMM  . W5
  181.                     0  << 22  |  // STMM shift down
  182.                     1  << 20  |  // STMM shift up
  183.                     5  << 16  |  // STMM output shift
  184.                     100 << 8  |  // SDI threshold
  185.                     5 );         // SDI delta
  186.  
  187.     *p_table ++ = ( 50  << 24 |  // SDI fallback mode 1 T1 constant . W6
  188.                     100 << 16 |  // SDI fallback mode 1 T2 constant
  189.                     37  << 8  |  // SDI fallback mode 2 constant(angle2x1)
  190.                     175 );       // FMD temporal difference threshold
  191.  
  192.     *p_table ++ = ( 16 << 24  |  // FMD #1 vertical difference th . w7
  193.                     100<< 16  |  // FMD #2 vertical difference th
  194.                     0  << 14  |  // CAT th1
  195.                     2  << 8   |  // FMD tear threshold
  196.                     motion_compensated_enable  << 7   |  // MCDI Enable, use motion compensated deinterlace algorithm
  197.                     progressive_dn  << 6   |  // progressive DN
  198.                     0  << 4   |  // reserved
  199.                     dndi_top_first  << 3   |  // DN/DI Top First
  200.                     0 );         // reserved
  201.  
  202.     *p_table ++ = ( 0  << 29  |  // reserved . W8
  203.                     32 << 23  |  // dnmh_history_init[5:0]
  204.                     10 << 19  |  // neighborPixel th
  205.                     0  << 18  |  // reserved
  206.                     0  << 16  |  // FMD for 2nd field of previous frame
  207.                     25 << 10  |  // MC pixel consistency th
  208.                     0  << 8   |  // FMD for 1st field for current frame
  209.                     10 << 4   |  // SAD THB
  210.                     5 );         // SAD THA
  211.  
  212.     *p_table ++ = ( 0  << 24  |  // reserved
  213.                     140<< 16  |  // chr_dnmh_stad_th
  214.                     0  << 13  |  // reserved
  215.                     1  << 12  |  // chrome denoise enable
  216.                     13 << 6   |  // chr temp diff th
  217.                     7 );         // chr temp diff low
  218.  
  219.     if (IS_GEN8(i965->intel.device_info))
  220.         *p_table ++ = 0;         // parameters for hot pixel,
  221. }
  222.  
  223. void hsw_veb_iecp_std_table(VADriverContextP ctx, struct intel_vebox_context *proc_ctx)
  224. {
  225.     unsigned int *p_table = proc_ctx->iecp_state_table.ptr + 0 ;
  226.     //VAProcFilterParameterBuffer * std_param =
  227.     //        (VAProcFilterParameterBuffer *) proc_ctx->filter_std;
  228.  
  229.     if(!(proc_ctx->filters_mask & VPP_IECP_STD_STE)){
  230.         memset(p_table, 0, 29 * 4);
  231.     }else{
  232.         //DWord 0
  233.         *p_table ++ = ( 154 << 24 |   // V_Mid
  234.                         110 << 16 |   // U_Mid
  235.                         14 << 10  |   // Hue_Max
  236.                         31 << 4   |   // Sat_Max
  237.                         0 << 3    |   // Reserved
  238.                         0 << 2    |   // Output Control is set to output the 1=STD score /0=Output Pixels
  239.                         1 << 1    |   // Set STE Enable
  240.                         1 );          // Set STD Enable
  241.  
  242.         //DWord 1
  243.         *p_table ++ = ( 0 << 31   |   // Reserved
  244.                         4 << 28   |   // Diamond Margin
  245.                         0 << 21   |   // Diamond_du
  246.                         3 << 18   |   // HS_Margin
  247.                         79 << 10  |   // Cos(alpha)
  248.                         0 << 8    |   // Reserved
  249.                         101 );        // Sin(alpha)
  250.  
  251.         //DWord 2
  252.         *p_table ++ = ( 0 << 21   |   // Reserved
  253.                         100 << 13 |   // Diamond_alpha
  254.                         35 << 7   |   // Diamond_Th
  255.                         0 );
  256.  
  257.         //DWord 3
  258.         *p_table ++ = ( 254 << 24 |   // Y_point_3
  259.                         47 << 16  |   // Y_point_2
  260.                         46 << 8   |   // Y_point_1
  261.                         1 << 7    |   // VY_STD_Enable
  262.                         0 );          // Reserved
  263.  
  264.         //DWord 4
  265.         *p_table ++ = ( 0 << 18   |   // Reserved
  266.                         31 << 13  |   // Y_slope_2
  267.                         31 << 8   |   // Y_slope_1
  268.                         255 );        // Y_point_4
  269.  
  270.         //DWord 5
  271.         *p_table ++ = ( 400 << 16 |   // INV_Skin_types_margin = 20* Skin_Type_margin => 20*20
  272.                         3300 );       // INV_Margin_VYL => 1/Margin_VYL
  273.  
  274.         //DWord 6
  275.         *p_table ++ = ( 216 << 24 |   // P1L
  276.                         46 << 16  |   // P0L
  277.                         1600 );       // INV_Margin_VYU
  278.  
  279.         //DWord 7
  280.         *p_table ++ = ( 130 << 24 |   // B1L
  281.                         133 << 16 |   // B0L
  282.                         236 << 8  |   // P3L
  283.                         236 );        // P2L
  284.  
  285.         //DWord 8
  286.         *p_table ++ = ( 0 << 27      |   // Reserved
  287.                         0x7FB << 16  |   // S0L (11 bits, Default value: -5 = FBh, pad it with 1s to make it 11bits)
  288.                         130 << 8     |   // B3L
  289.                         130 );
  290.  
  291.         //DWord 9
  292.         *p_table ++ = ( 0 << 22   |    // Reserved
  293.                         0 << 11   |    // S2L
  294.                         0);            // S1L
  295.  
  296.         //DWord 10
  297.         *p_table ++ = ( 0 << 27   |    // Reserved
  298.                         66 << 19  |    // P1U
  299.                         46 << 11  |    // P0U
  300.                         0 );           // S3
  301.  
  302.         //DWord 11
  303.         *p_table ++ = ( 163 << 24 |    // B1U
  304.                         143 << 16 |    // B0U
  305.                         236 << 8  |    // P3U
  306.                         150 );         // P2U
  307.  
  308.         //DWord 12
  309.         *p_table ++ = ( 0 << 27   |    // Reserved
  310.                         256 << 16 |    // S0U
  311.                         200 << 8  |    // B3U
  312.                         200 );         // B2U
  313.  
  314.         //DWord 13
  315.         *p_table ++ = ( 0 << 22     |    // Reserved
  316.                         0x74D << 11 |    // S2U (11 bits, Default value -179 = F4Dh)
  317.                         113 );           // S1U
  318.  
  319.         //DWoord 14
  320.         *p_table ++ = ( 0 << 28   |    // Reserved
  321.                         20 << 20  |    // Skin_types_margin
  322.                         120 << 12 |    // Skin_types_thresh
  323.                         1 << 11   |    // Skin_Types_Enable
  324.                         0 );           // S3U
  325.  
  326.         //DWord 15
  327.         *p_table ++ = ( 0 << 31     |    // Reserved
  328.                         0x3F8 << 21 |    // SATB1 (10 bits, default 8, optimized value -8)
  329.                         31 << 14    |    // SATP3
  330.                         6 << 7      |    // SATP2
  331.                         0x7A );          // SATP1 (7 bits, default 6, optimized value -6)
  332.  
  333.         //DWord 16
  334.         *p_table ++ = ( 0 << 31   |    // Reserved
  335.                         297 << 20 |    // SATS0
  336.                         124 << 10 |    // SATB3
  337.                         8 );           // SATB2
  338.  
  339.         //DWord 17
  340.         *p_table ++ = ( 0 << 22   |    // Reserved
  341.                         297 << 11 |    // SATS2
  342.                         85 );          // SATS1
  343.  
  344.         //DWord 18
  345.         *p_table ++ = ( 14 << 25    |    // HUEP3
  346.                         6 << 18     |    // HUEP2
  347.                         0x7A << 11  |    // HUEP1 (7 bits, default value -6 = 7Ah)
  348.                         256 );           // SATS3
  349.  
  350.         //DWord 19
  351.         *p_table ++ = ( 0 << 30   |    // Reserved
  352.                         256 << 20 |    // HUEB3
  353.                         8 << 10   |    // HUEB2
  354.                         0x3F8 );       // HUEB1 (10 bits, default value 8, optimized value -8)
  355.  
  356.         //DWord 20
  357.         *p_table ++ = ( 0 << 22   |    // Reserved
  358.                         85 << 11  |    // HUES1
  359.                         384 );         // HUES
  360.  
  361.         //DWord 21
  362.         *p_table ++ = ( 0 << 22   |    // Reserved
  363.                         256 << 11 |    // HUES3
  364.                         384 );         // HUES2
  365.  
  366.         //DWord 22
  367.         *p_table ++ = ( 0 << 31   |    // Reserved
  368.                         0 << 21   |    // SATB1_DARK
  369.                         31 << 14  |    // SATP3_DARK
  370.                         31 << 7   |    // SATP2_DARK
  371.                         0x7B );        // SATP1_DARK (7 bits, default value -11 = FF5h, optimized value -5)
  372.  
  373.         //DWord 23
  374.         *p_table ++ = ( 0 << 31   |    // Reserved
  375.                         305 << 20 |    // SATS0_DARK
  376.                         124 << 10 |    // SATB3_DARK
  377.                         124 );         // SATB2_DARK
  378.  
  379.         //DWord 24
  380.         *p_table ++ = ( 0 << 22   |    // Reserved
  381.                         256 << 11 |    // SATS2_DARK
  382.                         220 );         // SATS1_DARK
  383.  
  384.         //DWord 25
  385.         *p_table ++ = ( 14 << 25  |    // HUEP3_DARK
  386.                         14 << 18  |    // HUEP2_DARK
  387.                         14 << 11  |    // HUEP1_DARK
  388.                         256 );         // SATS3_DARK
  389.  
  390.         //DWord 26
  391.         *p_table ++ = ( 0 << 30   |    // Reserved
  392.                         56 << 20  |    // HUEB3_DARK
  393.                         56 << 10  |    // HUEB2_DARK
  394.                         56 );          // HUEB1_DARK
  395.  
  396.         //DWord 27
  397.         *p_table ++ = ( 0 << 22   |    // Reserved
  398.                         256 << 11 |    // HUES1_DARK
  399.                         256 );         // HUES0_DARK
  400.  
  401.         //DWord 28
  402.         *p_table ++ = ( 0 << 22   |    // Reserved
  403.                         256 << 11 |    // HUES3_DARK
  404.                         256 );         // HUES2_DARK
  405.     }
  406. }
  407.  
  408. void hsw_veb_iecp_ace_table(VADriverContextP ctx, struct intel_vebox_context *proc_ctx)
  409. {
  410.    unsigned int *p_table = (unsigned int*)(proc_ctx->iecp_state_table.ptr + 116);
  411.  
  412.     if(!(proc_ctx->filters_mask & VPP_IECP_ACE)){
  413.         memset(p_table, 0, 13 * 4);
  414.     }else{
  415.         *p_table ++ = 0x00000068;
  416.         *p_table ++ = 0x4c382410;
  417.         *p_table ++ = 0x9c887460;
  418.         *p_table ++ = 0xebd8c4b0;
  419.         *p_table ++ = 0x604c3824;
  420.  
  421.         *p_table ++ = 0xb09c8874;
  422.         *p_table ++ = 0x0000d8c4;
  423.         *p_table ++ = 0x00000000;
  424.         *p_table ++ = 0x00000000;
  425.         *p_table ++ = 0x00000000;
  426.  
  427.         *p_table ++ = 0x00000000;
  428.         *p_table ++ = 0x00000000;
  429.         *p_table ++ = 0x00000000;
  430.    }
  431. }
  432.  
  433. void hsw_veb_iecp_tcc_table(VADriverContextP ctx, struct intel_vebox_context *proc_ctx)
  434. {
  435.     unsigned int *p_table = (unsigned int*)(proc_ctx->iecp_state_table.ptr + 168);
  436. //    VAProcFilterParameterBuffer * tcc_param =
  437. //            (VAProcFilterParameterBuffer *) proc_ctx->filter_iecp_tcc;
  438.  
  439.    if(!(proc_ctx->filters_mask & VPP_IECP_TCC)){
  440.         memset(p_table, 0, 11 * 4);
  441.     }else{
  442.         *p_table ++ = 0x00000000;
  443.         *p_table ++ = 0x00000000;
  444.         *p_table ++ = 0x1e34cc91;
  445.         *p_table ++ = 0x3e3cce91;
  446.         *p_table ++ = 0x02e80195;
  447.  
  448.         *p_table ++ = 0x0197046b;
  449.         *p_table ++ = 0x01790174;
  450.         *p_table ++ = 0x00000000;
  451.         *p_table ++ = 0x00000000;
  452.         *p_table ++ = 0x03030000;
  453.  
  454.         *p_table ++ = 0x009201c0;
  455.    }
  456. }
  457.  
  458. void hsw_veb_iecp_pro_amp_table(VADriverContextP ctx, struct intel_vebox_context *proc_ctx)
  459. {
  460.     unsigned int contrast = 0x80;  //default
  461.     int brightness = 0x00;         //default
  462.     int cos_c_s    = 256 ;         //default
  463.     int sin_c_s    = 0;            //default
  464.     unsigned int *p_table = (unsigned int*)(proc_ctx->iecp_state_table.ptr + 212);
  465.  
  466.     if(!(proc_ctx->filters_mask & VPP_IECP_PRO_AMP)){
  467.         memset(p_table, 0, 2 * 4);
  468.     }else {
  469.         float  src_saturation = 1.0;
  470.         float  src_hue = 0.0;
  471.         float  src_contrast = 1.0;
  472.         float  src_brightness = 0.0;
  473.         float  tmp_value = 0.0;
  474.         unsigned int i = 0;
  475.  
  476.         VAProcFilterParameterBufferColorBalance * amp_params =
  477.             (VAProcFilterParameterBufferColorBalance *) proc_ctx->filter_iecp_amp;
  478.  
  479.         for (i = 0; i < proc_ctx->filter_iecp_amp_num_elements; i++){
  480.             VAProcColorBalanceType attrib = amp_params[i].attrib;
  481.  
  482.             if(attrib == VAProcColorBalanceHue) {
  483.                src_hue = amp_params[i].value;         //(-180.0, 180.0)
  484.             }else if(attrib == VAProcColorBalanceSaturation) {
  485.                src_saturation = amp_params[i].value; //(0.0, 10.0)
  486.             }else if(attrib == VAProcColorBalanceBrightness) {
  487.                src_brightness = amp_params[i].value; // (-100.0, 100.0)
  488.                brightness = intel_format_convert(src_brightness, 7, 4, 1);
  489.             }else if(attrib == VAProcColorBalanceContrast) {
  490.                src_contrast = amp_params[i].value;  //  (0.0, 10.0)
  491.                contrast = intel_format_convert(src_contrast, 4, 7, 0);
  492.             }
  493.         }
  494.  
  495.         tmp_value = cos(src_hue/180*PI) * src_contrast * src_saturation;
  496.         cos_c_s = intel_format_convert(tmp_value, 7, 8, 1);
  497.        
  498.         tmp_value = sin(src_hue/180*PI) * src_contrast * src_saturation;
  499.         sin_c_s = intel_format_convert(tmp_value, 7, 8, 1);
  500.      
  501.         *p_table ++ = ( 0 << 28 |         //reserved
  502.                         contrast << 17 |  //contrast value (U4.7 format)
  503.                         0 << 13 |         //reserved
  504.                         brightness << 1|  // S7.4 format
  505.                         1);
  506.  
  507.         *p_table ++ = ( cos_c_s << 16 |  // cos(h) * contrast * saturation
  508.                         sin_c_s);        // sin(h) * contrast * saturation
  509.                  
  510.     }
  511. }
  512.  
  513.  
  514. void hsw_veb_iecp_csc_table(VADriverContextP ctx, struct intel_vebox_context *proc_ctx)
  515. {
  516.     unsigned int *p_table = (unsigned int*)(proc_ctx->iecp_state_table.ptr + 220);
  517.     float tran_coef[9] = {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0};
  518.     float v_coef[3]    = {0.0, 0.0, 0.0};
  519.     float u_coef[3]    = {0.0, 0.0, 0.0};
  520.     int   is_transform_enabled = 0;
  521.  
  522.     if(!(proc_ctx->filters_mask & VPP_IECP_CSC)){
  523.         memset(p_table, 0, 8 * 4);
  524.         return;
  525.     }
  526.  
  527.     if(proc_ctx->fourcc_input == VA_FOURCC_RGBA &&
  528.        (proc_ctx->fourcc_output == VA_FOURCC_NV12 ||
  529.         proc_ctx->fourcc_output == VA_FOURCC_YV12 ||
  530.         proc_ctx->fourcc_output == VA_FOURCC_YVY2 ||
  531.         proc_ctx->fourcc_output == VA_FOURCC_AYUV)) {
  532.  
  533.          tran_coef[0] = 0.257;
  534.          tran_coef[1] = 0.504;
  535.          tran_coef[2] = 0.098;
  536.          tran_coef[3] = -0.148;
  537.          tran_coef[4] = -0.291;
  538.          tran_coef[5] = 0.439;
  539.          tran_coef[6] = 0.439;
  540.          tran_coef[7] = -0.368;
  541.          tran_coef[8] = -0.071;
  542.  
  543.          u_coef[0] = 16 * 4;
  544.          u_coef[1] = 128 * 4;
  545.          u_coef[2] = 128 * 4;
  546.  
  547.          is_transform_enabled = 1;
  548.     }else if((proc_ctx->fourcc_input  == VA_FOURCC_NV12 ||
  549.               proc_ctx->fourcc_input  == VA_FOURCC_YV12 ||
  550.               proc_ctx->fourcc_input  == VA_FOURCC_YUY2 ||
  551.               proc_ctx->fourcc_input  == VA_FOURCC_AYUV) &&
  552.               proc_ctx->fourcc_output == VA_FOURCC_RGBA) {
  553.          tran_coef[0] = 1.164;
  554.          tran_coef[1] = 0.000;
  555.          tran_coef[2] = 1.569;
  556.          tran_coef[3] = 1.164;
  557.          tran_coef[4] = -0.813;
  558.          tran_coef[5] = -0.392;
  559.          tran_coef[6] = 1.164;
  560.          tran_coef[7] = 2.017;
  561.          tran_coef[8] = 0.000;
  562.  
  563.          v_coef[0] = -16 * 4;
  564.          v_coef[1] = -128 * 4;
  565.          v_coef[2] = -128 * 4;
  566.  
  567.         is_transform_enabled = 1;
  568.     }else if(proc_ctx->fourcc_input != proc_ctx->fourcc_output){
  569.          //enable when input and output format are different.
  570.          is_transform_enabled = 1;
  571.     }
  572.  
  573.     if(is_transform_enabled == 0){
  574.         memset(p_table, 0, 8 * 4);
  575.     }else{
  576.         *p_table ++ = ( 0 << 29 | //reserved
  577.                         intel_format_convert(tran_coef[1], 2, 10, 1) << 16 | //c1, s2.10 format
  578.                         intel_format_convert(tran_coef[0], 2, 10, 1) << 3 |  //c0, s2.10 format
  579.                         0 << 2 | //reserved
  580.                         0 << 1 | // yuv_channel swap
  581.                         is_transform_enabled);                
  582.  
  583.         *p_table ++ = ( 0 << 26 | //reserved
  584.                         intel_format_convert(tran_coef[3], 2, 10, 1) << 13 |
  585.                         intel_format_convert(tran_coef[2], 2, 10, 1));
  586.    
  587.         *p_table ++ = ( 0 << 26 | //reserved
  588.                         intel_format_convert(tran_coef[5], 2, 10, 1) << 13 |
  589.                         intel_format_convert(tran_coef[4], 2, 10, 1));
  590.  
  591.         *p_table ++ = ( 0 << 26 | //reserved
  592.                         intel_format_convert(tran_coef[7], 2, 10, 1) << 13 |
  593.                         intel_format_convert(tran_coef[6], 2, 10, 1));
  594.  
  595.         *p_table ++ = ( 0 << 13 | //reserved
  596.                         intel_format_convert(tran_coef[8], 2, 10, 1));
  597.  
  598.         *p_table ++ = ( 0 << 22 | //reserved
  599.                         intel_format_convert(u_coef[0], 10, 0, 1) << 11 |
  600.                         intel_format_convert(v_coef[0], 10, 0, 1));
  601.  
  602.         *p_table ++ = ( 0 << 22 | //reserved
  603.                         intel_format_convert(u_coef[1], 10, 0, 1) << 11 |
  604.                         intel_format_convert(v_coef[1], 10, 0, 1));
  605.  
  606.         *p_table ++ = ( 0 << 22 | //reserved
  607.                         intel_format_convert(u_coef[2], 10, 0, 1) << 11 |
  608.                         intel_format_convert(v_coef[2], 10, 0, 1));
  609.     }
  610. }
  611.  
  612. void hsw_veb_iecp_aoi_table(VADriverContextP ctx, struct intel_vebox_context *proc_ctx)
  613. {
  614.     unsigned int *p_table = (unsigned int*)(proc_ctx->iecp_state_table.ptr + 252);
  615.    // VAProcFilterParameterBuffer * tcc_param =
  616.    //         (VAProcFilterParameterBuffer *) proc_ctx->filter_iecp_tcc;
  617.  
  618.     if(!(proc_ctx->filters_mask & VPP_IECP_AOI)){
  619.         memset(p_table, 0, 3 * 4);
  620.     }else{
  621.         *p_table ++ = 0x00000000;
  622.         *p_table ++ = 0x00030000;
  623.         *p_table ++ = 0x00030000;
  624.    }
  625. }
  626.  
  627. void hsw_veb_state_table_setup(VADriverContextP ctx, struct intel_vebox_context *proc_ctx)
  628. {
  629.     if(proc_ctx->filters_mask & 0x000000ff) {
  630.         dri_bo *dndi_bo = proc_ctx->dndi_state_table.bo;
  631.         dri_bo_map(dndi_bo, 1);
  632.         proc_ctx->dndi_state_table.ptr = dndi_bo->virtual;
  633.  
  634.         hsw_veb_dndi_table(ctx, proc_ctx);
  635.  
  636.         dri_bo_unmap(dndi_bo);
  637.     }
  638.  
  639.     if(proc_ctx->filters_mask & 0x0000ff00) {
  640.         dri_bo *iecp_bo = proc_ctx->iecp_state_table.bo;
  641.         dri_bo_map(iecp_bo, 1);
  642.         proc_ctx->iecp_state_table.ptr = iecp_bo->virtual;
  643.  
  644.         hsw_veb_iecp_std_table(ctx, proc_ctx);
  645.         hsw_veb_iecp_ace_table(ctx, proc_ctx);
  646.         hsw_veb_iecp_tcc_table(ctx, proc_ctx);
  647.         hsw_veb_iecp_pro_amp_table(ctx, proc_ctx);
  648.         hsw_veb_iecp_csc_table(ctx, proc_ctx);
  649.         hsw_veb_iecp_aoi_table(ctx, proc_ctx);
  650.    
  651.         dri_bo_unmap(iecp_bo);
  652.     }
  653. }
  654.  
  655. void hsw_veb_state_command(VADriverContextP ctx, struct intel_vebox_context *proc_ctx)
  656. {
  657.     struct intel_batchbuffer *batch = proc_ctx->batch;
  658.     unsigned int is_dn_enabled   = (proc_ctx->filters_mask & 0x01)? 1: 0;
  659.     unsigned int is_di_enabled   = (proc_ctx->filters_mask & 0x02)? 1: 0;
  660.     unsigned int is_iecp_enabled = (proc_ctx->filters_mask & 0xff00)?1:0;
  661.     unsigned int is_first_frame  = !!((proc_ctx->frame_order == -1) &&
  662.                                       (is_di_enabled ||
  663.                                        is_dn_enabled));
  664.     unsigned int di_output_frames_flag = 2; /* Output Current Frame Only */
  665.  
  666.     if(proc_ctx->fourcc_input != proc_ctx->fourcc_output ||
  667.        (is_dn_enabled == 0 && is_di_enabled == 0)){
  668.        is_iecp_enabled = 1;
  669.     }
  670.  
  671.     if (is_di_enabled) {
  672.         VAProcFilterParameterBufferDeinterlacing *di_param =
  673.             (VAProcFilterParameterBufferDeinterlacing *)proc_ctx->filter_di;
  674.  
  675.         assert(di_param);
  676.        
  677.         if (di_param->algorithm == VAProcDeinterlacingBob)
  678.             is_first_frame = 1;
  679.  
  680.         if ((di_param->algorithm == VAProcDeinterlacingMotionAdaptive ||
  681.             di_param->algorithm == VAProcDeinterlacingMotionCompensated) &&
  682.             proc_ctx->frame_order != -1)
  683.             di_output_frames_flag = 0; /* Output both Current Frame and Previous Frame */
  684.     }
  685.  
  686.     BEGIN_VEB_BATCH(batch, 6);
  687.     OUT_VEB_BATCH(batch, VEB_STATE | (6 - 2));
  688.     OUT_VEB_BATCH(batch,
  689.                   0 << 26 |       // state surface control bits
  690.                   0 << 11 |       // reserved.
  691.                   0 << 10 |       // pipe sync disable
  692.                   di_output_frames_flag << 8  |       // DI output frame
  693.                   1 << 7  |       // 444->422 downsample method
  694.                   1 << 6  |       // 422->420 downsample method
  695.                   is_first_frame  << 5  |   // DN/DI first frame
  696.                   is_di_enabled   << 4  |             // DI enable
  697.                   is_dn_enabled   << 3  |             // DN enable
  698.                   is_iecp_enabled << 2  |             // global IECP enabled
  699.                   0 << 1  |       // ColorGamutCompressionEnable
  700.                   0 ) ;           // ColorGamutExpansionEnable.
  701.  
  702.     OUT_RELOC(batch,
  703.               proc_ctx->dndi_state_table.bo,
  704.               I915_GEM_DOMAIN_INSTRUCTION, 0, 0);
  705.  
  706.     OUT_RELOC(batch,
  707.               proc_ctx->iecp_state_table.bo,
  708.               I915_GEM_DOMAIN_INSTRUCTION, 0, 0);
  709.  
  710.     OUT_RELOC(batch,
  711.               proc_ctx->gamut_state_table.bo,
  712.               I915_GEM_DOMAIN_INSTRUCTION, 0, 0);
  713.  
  714.     OUT_RELOC(batch,
  715.               proc_ctx->vertex_state_table.bo,
  716.               I915_GEM_DOMAIN_INSTRUCTION, 0, 0);
  717.  
  718.     ADVANCE_VEB_BATCH(batch);
  719. }
  720.  
  721. void hsw_veb_surface_state(VADriverContextP ctx, struct intel_vebox_context *proc_ctx, unsigned int is_output)
  722. {
  723.     struct intel_batchbuffer *batch = proc_ctx->batch;
  724.     unsigned int u_offset_y = 0, v_offset_y = 0;
  725.     unsigned int is_uv_interleaved = 0, tiling = 0, swizzle = 0;
  726.     unsigned int surface_format = PLANAR_420_8;
  727.     struct object_surface* obj_surf = NULL;
  728.     unsigned int surface_pitch = 0;
  729.     unsigned int half_pitch_chroma = 0;
  730.  
  731.     if(is_output){  
  732.         obj_surf = proc_ctx->frame_store[FRAME_OUT_CURRENT].obj_surface;
  733.     }else {
  734.         obj_surf = proc_ctx->frame_store[FRAME_IN_CURRENT].obj_surface;
  735.     }
  736.  
  737.     assert(obj_surf->fourcc == VA_FOURCC_NV12 ||
  738.            obj_surf->fourcc == VA_FOURCC_YUY2 ||
  739.            obj_surf->fourcc == VA_FOURCC_AYUV ||
  740.            obj_surf->fourcc == VA_FOURCC_RGBA);
  741.  
  742.     if (obj_surf->fourcc == VA_FOURCC_NV12) {
  743.         surface_format = PLANAR_420_8;
  744.         surface_pitch = obj_surf->width;
  745.         is_uv_interleaved = 1;
  746.         half_pitch_chroma = 0;
  747.     } else if (obj_surf->fourcc == VA_FOURCC_YUY2) {
  748.         surface_format = YCRCB_NORMAL;
  749.         surface_pitch = obj_surf->width * 2;
  750.         is_uv_interleaved = 0;
  751.         half_pitch_chroma = 0;
  752.     } else if (obj_surf->fourcc == VA_FOURCC_AYUV) {
  753.         surface_format = PACKED_444A_8;
  754.         surface_pitch = obj_surf->width * 4;
  755.         is_uv_interleaved = 0;
  756.         half_pitch_chroma = 0;
  757.     } else if (obj_surf->fourcc == VA_FOURCC_RGBA) {
  758.         surface_format = R8G8B8A8_UNORM_SRGB;
  759.         surface_pitch = obj_surf->width * 4;
  760.         is_uv_interleaved = 0;
  761.         half_pitch_chroma = 0;
  762.     }
  763.  
  764.     u_offset_y = obj_surf->y_cb_offset;
  765.     v_offset_y = obj_surf->y_cr_offset;
  766.      
  767.     dri_bo_get_tiling(obj_surf->bo, &tiling, &swizzle);
  768.  
  769.     BEGIN_VEB_BATCH(batch, 6);
  770.     OUT_VEB_BATCH(batch, VEB_SURFACE_STATE | (6 - 2));
  771.     OUT_VEB_BATCH(batch,
  772.                   0 << 1 |         // reserved
  773.                   is_output);      // surface indentification.
  774.  
  775.     OUT_VEB_BATCH(batch,
  776.                   (obj_surf->height - 1) << 18 |  // height . w3
  777.                   (obj_surf->width -1 )  << 4  |  // width
  778.                   0);                             // reserve
  779.  
  780.     OUT_VEB_BATCH(batch,
  781.                   surface_format      << 28  |  // surface format, YCbCr420. w4
  782.                   is_uv_interleaved   << 27  |  // interleave chrome , two seperate palar
  783.                   0                   << 20  |  // reserved
  784.                   (surface_pitch - 1) << 3   |  // surface pitch, 64 align
  785.                   half_pitch_chroma   << 2   |  // half pitch for chrome
  786.                   !!tiling            << 1   |  // tiled surface, linear surface used
  787.                   (tiling == I915_TILING_Y));   // tiled walk, ignored when liner surface
  788.  
  789.     OUT_VEB_BATCH(batch,
  790.                   0 << 29  |     // reserved . w5
  791.                   0 << 16  |     // X offset for V(Cb)
  792.                   0 << 15  |     // reserved
  793.                   u_offset_y);   // Y offset for V(Cb)
  794.  
  795.     OUT_VEB_BATCH(batch,
  796.                   0 << 29  |     // reserved . w6
  797.                   0 << 16  |     // X offset for V(Cr)
  798.                   0 << 15  |     // reserved
  799.                   v_offset_y );  // Y offset for V(Cr)
  800.  
  801.     ADVANCE_VEB_BATCH(batch);
  802. }
  803.  
  804. void hsw_veb_dndi_iecp_command(VADriverContextP ctx, struct intel_vebox_context *proc_ctx)
  805. {
  806.     struct intel_batchbuffer *batch = proc_ctx->batch;
  807.     unsigned char frame_ctrl_bits = 0;
  808.     unsigned int startingX = 0;
  809.     unsigned int endingX = (proc_ctx->width_input + 63 ) / 64 * 64;
  810.  
  811.     /* s1:update the previous and current input */
  812. /*    tempFrame = proc_ctx->frame_store[FRAME_IN_PREVIOUS];
  813.     proc_ctx->frame_store[FRAME_IN_PREVIOUS] = proc_ctx->frame_store[FRAME_IN_CURRENT]; ;
  814.     proc_ctx->frame_store[FRAME_IN_CURRENT] = tempFrame;
  815.  
  816.     if(proc_ctx->surface_input_vebox != -1){
  817.         vpp_surface_copy(ctx, proc_ctx->frame_store[FRAME_IN_CURRENT].surface_id,
  818.                      proc_ctx->surface_input_vebox);
  819.     } else {
  820.         vpp_surface_copy(ctx, proc_ctx->frame_store[FRAME_IN_CURRENT].surface_id,
  821.                      proc_ctx->surface_input);
  822.     }
  823. */
  824.     /*s2: update the STMM input and output */
  825. /*    tempFrame = proc_ctx->frame_store[FRAME_IN_STMM];
  826.     proc_ctx->frame_store[FRAME_IN_STMM] = proc_ctx->frame_store[FRAME_OUT_STMM]; ;
  827.     proc_ctx->frame_store[FRAME_OUT_STMM] = tempFrame;
  828. */     
  829.     /*s3:set reloc buffer address */
  830.     BEGIN_VEB_BATCH(batch, 10);
  831.     OUT_VEB_BATCH(batch, VEB_DNDI_IECP_STATE | (10 - 2));
  832.     OUT_VEB_BATCH(batch,
  833.                   startingX << 16 |
  834.                   (endingX-1));
  835.     OUT_RELOC(batch,
  836.               proc_ctx->frame_store[FRAME_IN_CURRENT].obj_surface->bo,
  837.               I915_GEM_DOMAIN_RENDER, 0, frame_ctrl_bits);
  838.     OUT_RELOC(batch,
  839.               proc_ctx->frame_store[FRAME_IN_PREVIOUS].obj_surface->bo,
  840.               I915_GEM_DOMAIN_RENDER, 0, frame_ctrl_bits);
  841.     OUT_RELOC(batch,
  842.               proc_ctx->frame_store[FRAME_IN_STMM].obj_surface->bo,
  843.               I915_GEM_DOMAIN_RENDER, 0, frame_ctrl_bits);
  844.     OUT_RELOC(batch,
  845.               proc_ctx->frame_store[FRAME_OUT_STMM].obj_surface->bo,
  846.               I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, frame_ctrl_bits);
  847.     OUT_RELOC(batch,
  848.               proc_ctx->frame_store[FRAME_OUT_CURRENT_DN].obj_surface->bo,
  849.               I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, frame_ctrl_bits);
  850.     OUT_RELOC(batch,
  851.               proc_ctx->frame_store[FRAME_OUT_CURRENT].obj_surface->bo,
  852.               I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, frame_ctrl_bits);
  853.     OUT_RELOC(batch,
  854.               proc_ctx->frame_store[FRAME_OUT_PREVIOUS].obj_surface->bo,
  855.               I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, frame_ctrl_bits);
  856.     OUT_RELOC(batch,
  857.               proc_ctx->frame_store[FRAME_OUT_STATISTIC].obj_surface->bo,
  858.               I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, frame_ctrl_bits);
  859.  
  860.     ADVANCE_VEB_BATCH(batch);
  861. }
  862.  
  863. void hsw_veb_resource_prepare(VADriverContextP ctx,
  864.                               struct intel_vebox_context *proc_ctx)
  865. {
  866.     VAStatus va_status;
  867.     dri_bo *bo;
  868.     struct i965_driver_data *i965 = i965_driver_data(ctx);
  869.     unsigned int input_fourcc, output_fourcc;
  870.     unsigned int input_sampling, output_sampling;
  871.     unsigned int input_tiling, output_tiling;
  872.     unsigned int i, swizzle;
  873.     struct object_surface *obj_surf_out = NULL, *obj_surf_in = NULL;
  874.  
  875.     if (proc_ctx->surface_input_vebox_object != NULL) {
  876.         obj_surf_in = proc_ctx->surface_input_vebox_object;
  877.     } else {
  878.         obj_surf_in = proc_ctx->surface_input_object;
  879.     }
  880.  
  881.     if (proc_ctx->surface_output_vebox_object != NULL) {
  882.         obj_surf_out = proc_ctx->surface_output_vebox_object;
  883.     } else {
  884.         obj_surf_out = proc_ctx->surface_output_object;
  885.     }
  886.  
  887.     if(obj_surf_in->bo == NULL){
  888.           input_fourcc = VA_FOURCC_NV12;
  889.           input_sampling = SUBSAMPLE_YUV420;
  890.           input_tiling = 0;
  891.           i965_check_alloc_surface_bo(ctx, obj_surf_in, input_tiling, input_fourcc, input_sampling);
  892.     } else {
  893.         input_fourcc = obj_surf_in->fourcc;
  894.         input_sampling = obj_surf_in->subsampling;
  895.         dri_bo_get_tiling(obj_surf_in->bo, &input_tiling, &swizzle);
  896.         input_tiling = !!input_tiling;
  897.     }
  898.  
  899.     if(obj_surf_out->bo == NULL){
  900.           output_fourcc = VA_FOURCC_NV12;
  901.           output_sampling = SUBSAMPLE_YUV420;
  902.           output_tiling = 0;
  903.           i965_check_alloc_surface_bo(ctx, obj_surf_out, output_tiling, output_fourcc, output_sampling);
  904.     }else {
  905.         output_fourcc   = obj_surf_out->fourcc;
  906.         output_sampling = obj_surf_out->subsampling;
  907.         dri_bo_get_tiling(obj_surf_out->bo, &output_tiling, &swizzle);
  908.         output_tiling = !!output_tiling;
  909.     }
  910.  
  911.     /* vebox pipelien input surface format info */
  912.     proc_ctx->fourcc_input = input_fourcc;
  913.     proc_ctx->fourcc_output = output_fourcc;
  914.    
  915.     /* create pipeline surfaces */
  916.     for(i = 0; i < FRAME_STORE_SUM; i ++) {
  917.         if(proc_ctx->frame_store[i].obj_surface){
  918.             continue; //refer external surface for vebox pipeline
  919.         }
  920.    
  921.         VASurfaceID new_surface;
  922.         struct object_surface *obj_surf = NULL;
  923.  
  924.         va_status =   i965_CreateSurfaces(ctx,
  925.                                           proc_ctx ->width_input,
  926.                                           proc_ctx ->height_input,
  927.                                           VA_RT_FORMAT_YUV420,
  928.                                           1,
  929.                                           &new_surface);
  930.         assert(va_status == VA_STATUS_SUCCESS);
  931.  
  932.         obj_surf = SURFACE(new_surface);
  933.         assert(obj_surf);
  934.  
  935.         if( i <= FRAME_IN_PREVIOUS || i == FRAME_OUT_CURRENT_DN) {
  936.             i965_check_alloc_surface_bo(ctx, obj_surf, input_tiling, input_fourcc, input_sampling);
  937.         } else if( i == FRAME_IN_STMM || i == FRAME_OUT_STMM){
  938.             i965_check_alloc_surface_bo(ctx, obj_surf, 1, input_fourcc, input_sampling);
  939.         } else if( i >= FRAME_OUT_CURRENT){
  940.             i965_check_alloc_surface_bo(ctx, obj_surf, output_tiling, output_fourcc, output_sampling);
  941.         }
  942.  
  943.         proc_ctx->frame_store[i].surface_id = new_surface;
  944.         proc_ctx->frame_store[i].is_internal_surface = 1;
  945.         proc_ctx->frame_store[i].obj_surface = obj_surf;
  946.     }
  947.  
  948.     /* alloc dndi state table  */
  949.     dri_bo_unreference(proc_ctx->dndi_state_table.bo);
  950.     bo = dri_bo_alloc(i965->intel.bufmgr,
  951.                       "vebox: dndi state Buffer",
  952.                       0x1000, 0x1000);
  953.     proc_ctx->dndi_state_table.bo = bo;
  954.     dri_bo_reference(proc_ctx->dndi_state_table.bo);
  955.  
  956.     /* alloc iecp state table  */
  957.     dri_bo_unreference(proc_ctx->iecp_state_table.bo);
  958.     bo = dri_bo_alloc(i965->intel.bufmgr,
  959.                       "vebox: iecp state Buffer",
  960.                       0x1000, 0x1000);
  961.     proc_ctx->iecp_state_table.bo = bo;
  962.     dri_bo_reference(proc_ctx->iecp_state_table.bo);
  963.  
  964.     /* alloc gamut state table  */
  965.     dri_bo_unreference(proc_ctx->gamut_state_table.bo);
  966.     bo = dri_bo_alloc(i965->intel.bufmgr,
  967.                       "vebox: gamut state Buffer",
  968.                       0x1000, 0x1000);
  969.     proc_ctx->gamut_state_table.bo = bo;
  970.     dri_bo_reference(proc_ctx->gamut_state_table.bo);
  971.  
  972.     /* alloc vertex state table  */
  973.     dri_bo_unreference(proc_ctx->vertex_state_table.bo);
  974.     bo = dri_bo_alloc(i965->intel.bufmgr,
  975.                       "vertex: iecp state Buffer",
  976.                       0x1000, 0x1000);
  977.     proc_ctx->vertex_state_table.bo = bo;
  978.     dri_bo_reference(proc_ctx->vertex_state_table.bo);
  979.  
  980. }
  981.  
  982. static VAStatus
  983. hsw_veb_surface_reference(VADriverContextP ctx,
  984.                           struct intel_vebox_context *proc_ctx)
  985. {
  986.     struct object_surface * obj_surf;
  987.     VEBFrameStore tmp_store;
  988.  
  989.     if (proc_ctx->surface_input_vebox_object != NULL) {
  990.         obj_surf = proc_ctx->surface_input_vebox_object;
  991.     } else {
  992.         obj_surf = proc_ctx->surface_input_object;
  993.     }
  994.  
  995.     /* update the input surface */
  996.     proc_ctx->frame_store[FRAME_IN_CURRENT].surface_id = VA_INVALID_ID;
  997.     proc_ctx->frame_store[FRAME_IN_CURRENT].is_internal_surface = 0;
  998.     proc_ctx->frame_store[FRAME_IN_CURRENT].obj_surface = obj_surf;
  999.  
  1000.     /* update the previous input surface */
  1001.     if (proc_ctx->frame_order != -1) {
  1002.         if (proc_ctx->filters_mask == VPP_DNDI_DN) {
  1003.             proc_ctx->frame_store[FRAME_IN_PREVIOUS] = proc_ctx->frame_store[FRAME_OUT_CURRENT_DN];
  1004.         } else if (proc_ctx->filters_mask & VPP_DNDI_DI) {
  1005.             VAProcFilterParameterBufferDeinterlacing *di_param =
  1006.                 (VAProcFilterParameterBufferDeinterlacing *)proc_ctx->filter_di;
  1007.  
  1008.             if (di_param &&
  1009.                 (di_param->algorithm == VAProcDeinterlacingMotionAdaptive ||
  1010.                 di_param->algorithm == VAProcDeinterlacingMotionCompensated)) {
  1011.                 if ((proc_ctx->filters_mask & VPP_DNDI_DN) &&
  1012.                     proc_ctx->frame_order == 0) { /* DNDI */
  1013.                     tmp_store = proc_ctx->frame_store[FRAME_OUT_CURRENT_DN];
  1014.                     proc_ctx->frame_store[FRAME_OUT_CURRENT_DN] = proc_ctx->frame_store[FRAME_IN_PREVIOUS];
  1015.                     proc_ctx->frame_store[FRAME_IN_PREVIOUS] = tmp_store;
  1016.                 } else { /* DI only */
  1017.                     VAProcPipelineParameterBuffer *pipe = proc_ctx->pipeline_param;
  1018.                     struct object_surface *obj_surf = NULL;
  1019.                     struct i965_driver_data * const i965 = i965_driver_data(ctx);
  1020.  
  1021.                     if (!pipe ||
  1022.                         !pipe->num_forward_references ||
  1023.                         pipe->forward_references[0] == VA_INVALID_ID) {
  1024.                         WARN_ONCE("A forward temporal reference is needed for Motion adaptive/compensated deinterlacing !!!\n");
  1025.  
  1026.                         return VA_STATUS_ERROR_INVALID_PARAMETER;
  1027.                     }
  1028.  
  1029.                     obj_surf = SURFACE(pipe->forward_references[0]);
  1030.                     assert(obj_surf && obj_surf->bo);
  1031.                
  1032.                     proc_ctx->frame_store[FRAME_IN_PREVIOUS].surface_id = pipe->forward_references[0];
  1033.                     proc_ctx->frame_store[FRAME_IN_PREVIOUS].is_internal_surface = 0;
  1034.                     proc_ctx->frame_store[FRAME_IN_PREVIOUS].obj_surface = obj_surf;
  1035.                 }
  1036.             }
  1037.         }
  1038.     }
  1039.  
  1040.     /* update STMM surface */
  1041.     if (proc_ctx->frame_order != -1) {
  1042.         tmp_store = proc_ctx->frame_store[FRAME_IN_STMM];
  1043.         proc_ctx->frame_store[FRAME_IN_STMM] = proc_ctx->frame_store[FRAME_OUT_STMM];
  1044.         proc_ctx->frame_store[FRAME_OUT_STMM] = tmp_store;
  1045.     }
  1046.  
  1047.     /* update the output surface */
  1048.     if (proc_ctx->surface_output_vebox_object != NULL) {
  1049.         obj_surf = proc_ctx->surface_output_vebox_object;
  1050.     } else {
  1051.         obj_surf = proc_ctx->surface_output_object;
  1052.     }
  1053.  
  1054.     if (proc_ctx->filters_mask == VPP_DNDI_DN) {
  1055.         proc_ctx->frame_store[FRAME_OUT_CURRENT_DN].surface_id = VA_INVALID_ID;
  1056.         proc_ctx->frame_store[FRAME_OUT_CURRENT_DN].is_internal_surface = 0;
  1057.         proc_ctx->frame_store[FRAME_OUT_CURRENT_DN].obj_surface = obj_surf;
  1058.         proc_ctx->current_output = FRAME_OUT_CURRENT_DN;
  1059.     } else if (proc_ctx->filters_mask & VPP_DNDI_DI) {
  1060.         VAProcFilterParameterBufferDeinterlacing *di_param =
  1061.             (VAProcFilterParameterBufferDeinterlacing *)proc_ctx->filter_di;
  1062.  
  1063.         if (di_param &&
  1064.             (di_param->algorithm == VAProcDeinterlacingMotionAdaptive ||
  1065.             di_param->algorithm == VAProcDeinterlacingMotionCompensated)) {
  1066.             if (proc_ctx->frame_order == -1) {
  1067.                 proc_ctx->frame_store[FRAME_OUT_CURRENT].surface_id = VA_INVALID_ID;
  1068.                 proc_ctx->frame_store[FRAME_OUT_CURRENT].is_internal_surface = 0;
  1069.                 proc_ctx->frame_store[FRAME_OUT_CURRENT].obj_surface = obj_surf;
  1070.                 proc_ctx->current_output = FRAME_OUT_CURRENT;
  1071.             } else if (proc_ctx->frame_order == 0) {
  1072.                 proc_ctx->frame_store[FRAME_OUT_PREVIOUS].surface_id = VA_INVALID_ID;
  1073.                 proc_ctx->frame_store[FRAME_OUT_PREVIOUS].is_internal_surface = 0;
  1074.                 proc_ctx->frame_store[FRAME_OUT_PREVIOUS].obj_surface = obj_surf;
  1075.                 proc_ctx->current_output = FRAME_OUT_PREVIOUS;
  1076.             } else {
  1077.                 proc_ctx->current_output = FRAME_OUT_CURRENT;
  1078.                 proc_ctx->format_convert_flags |= POST_COPY_CONVERT;
  1079.             }
  1080.         } else {
  1081.             proc_ctx->frame_store[FRAME_OUT_CURRENT].surface_id = VA_INVALID_ID;
  1082.             proc_ctx->frame_store[FRAME_OUT_CURRENT].is_internal_surface = 0;
  1083.             proc_ctx->frame_store[FRAME_OUT_CURRENT].obj_surface = obj_surf;
  1084.             proc_ctx->current_output = FRAME_OUT_CURRENT;
  1085.         }
  1086.     } else {
  1087.         proc_ctx->frame_store[FRAME_OUT_CURRENT].surface_id = VA_INVALID_ID;
  1088.         proc_ctx->frame_store[FRAME_OUT_CURRENT].is_internal_surface = 0;
  1089.         proc_ctx->frame_store[FRAME_OUT_CURRENT].obj_surface = obj_surf;
  1090.         proc_ctx->current_output = FRAME_OUT_CURRENT;
  1091.     }
  1092.  
  1093.     return VA_STATUS_SUCCESS;
  1094. }
  1095.  
  1096. void hsw_veb_surface_unreference(VADriverContextP ctx,
  1097.                                  struct intel_vebox_context *proc_ctx)
  1098. {
  1099.     /* unreference the input surface */
  1100.     proc_ctx->frame_store[FRAME_IN_CURRENT].surface_id = VA_INVALID_ID;
  1101.     proc_ctx->frame_store[FRAME_IN_CURRENT].is_internal_surface = 0;
  1102.     proc_ctx->frame_store[FRAME_IN_CURRENT].obj_surface = NULL;
  1103.  
  1104.     /* unreference the shared output surface */
  1105.     if (proc_ctx->filters_mask == VPP_DNDI_DN) {
  1106.         proc_ctx->frame_store[FRAME_OUT_CURRENT_DN].surface_id = VA_INVALID_ID;
  1107.         proc_ctx->frame_store[FRAME_OUT_CURRENT_DN].is_internal_surface = 0;
  1108.         proc_ctx->frame_store[FRAME_OUT_CURRENT_DN].obj_surface = NULL;
  1109.     } else {
  1110.         proc_ctx->frame_store[FRAME_OUT_CURRENT].surface_id = VA_INVALID_ID;
  1111.         proc_ctx->frame_store[FRAME_OUT_CURRENT].is_internal_surface = 0;
  1112.         proc_ctx->frame_store[FRAME_OUT_CURRENT].obj_surface = NULL;
  1113.     }
  1114. }
  1115.  
  1116. int hsw_veb_pre_format_convert(VADriverContextP ctx,
  1117.                            struct intel_vebox_context *proc_ctx)
  1118. {
  1119.     VAStatus va_status;
  1120.     struct i965_driver_data *i965 = i965_driver_data(ctx);
  1121.     struct object_surface* obj_surf_input = proc_ctx->surface_input_object;
  1122.     struct object_surface* obj_surf_output = proc_ctx->surface_output_object;
  1123.     struct object_surface* obj_surf_input_vebox;
  1124.     struct object_surface* obj_surf_output_vebox;
  1125.  
  1126.     proc_ctx->format_convert_flags = 0;
  1127.  
  1128.     proc_ctx->width_input   = obj_surf_input->orig_width;
  1129.     proc_ctx->height_input  = obj_surf_input->orig_height;
  1130.     proc_ctx->width_output  = obj_surf_output->orig_width;
  1131.     proc_ctx->height_output = obj_surf_output->orig_height;
  1132.    
  1133.     /* only partial frame is not supported to be processed */
  1134.     /*
  1135.     assert(proc_ctx->width_input   == proc_ctx->pipeline_param->surface_region->width);
  1136.     assert(proc_ctx->height_input  == proc_ctx->pipeline_param->surface_region->height);
  1137.     assert(proc_ctx->width_output  == proc_ctx->pipeline_param->output_region->width);
  1138.     assert(proc_ctx->height_output == proc_ctx->pipeline_param->output_region->height);
  1139.     */
  1140.  
  1141.     if(proc_ctx->width_output  != proc_ctx->width_input ||
  1142.        proc_ctx->height_output != proc_ctx->height_input){
  1143.         proc_ctx->format_convert_flags |= POST_SCALING_CONVERT;
  1144.     }
  1145.  
  1146.      /* convert the following format to NV12 format */
  1147.      if(obj_surf_input->fourcc ==  VA_FOURCC_YV12 ||
  1148.         obj_surf_input->fourcc ==  VA_FOURCC_I420 ||
  1149.         obj_surf_input->fourcc ==  VA_FOURCC_IMC1 ||
  1150.         obj_surf_input->fourcc ==  VA_FOURCC_IMC3 ||
  1151.         obj_surf_input->fourcc ==  VA_FOURCC_RGBA){
  1152.  
  1153.          proc_ctx->format_convert_flags |= PRE_FORMAT_CONVERT;
  1154.  
  1155.       } else if(obj_surf_input->fourcc ==  VA_FOURCC_AYUV ||
  1156.                 obj_surf_input->fourcc ==  VA_FOURCC_YUY2 ||
  1157.                 obj_surf_input->fourcc ==  VA_FOURCC_NV12){
  1158.                 // nothing to do here
  1159.      } else {
  1160.            /* not support other format as input */
  1161.            assert(0);
  1162.      }
  1163.    
  1164.      if (proc_ctx->format_convert_flags & PRE_FORMAT_CONVERT) {
  1165.          if(proc_ctx->surface_input_vebox_object == NULL){
  1166.              va_status = i965_CreateSurfaces(ctx,
  1167.                                             proc_ctx->width_input,
  1168.                                             proc_ctx->height_input,
  1169.                                             VA_RT_FORMAT_YUV420,
  1170.                                             1,
  1171.                                             &(proc_ctx->surface_input_vebox));
  1172.              assert(va_status == VA_STATUS_SUCCESS);
  1173.              obj_surf_input_vebox = SURFACE(proc_ctx->surface_input_vebox);
  1174.              assert(obj_surf_input_vebox);
  1175.  
  1176.              if (obj_surf_input_vebox) {
  1177.                  proc_ctx->surface_input_vebox_object = obj_surf_input_vebox;
  1178.                  i965_check_alloc_surface_bo(ctx, obj_surf_input_vebox, 1, VA_FOURCC_NV12, SUBSAMPLE_YUV420);
  1179.              }
  1180.          }
  1181.        
  1182.          vpp_surface_convert(ctx, proc_ctx->surface_input_vebox_object, proc_ctx->surface_input_object);
  1183.       }
  1184.  
  1185.       /* create one temporary NV12 surfaces for conversion*/
  1186.      if(obj_surf_output->fourcc ==  VA_FOURCC_YV12 ||
  1187.         obj_surf_output->fourcc ==  VA_FOURCC_I420 ||
  1188.         obj_surf_output->fourcc ==  VA_FOURCC_IMC1 ||
  1189.         obj_surf_output->fourcc ==  VA_FOURCC_IMC3 ||
  1190.         obj_surf_output->fourcc ==  VA_FOURCC_RGBA) {
  1191.  
  1192.         proc_ctx->format_convert_flags |= POST_FORMAT_CONVERT;
  1193.     } else if(obj_surf_output->fourcc ==  VA_FOURCC_AYUV ||
  1194.               obj_surf_output->fourcc ==  VA_FOURCC_YUY2 ||
  1195.               obj_surf_output->fourcc ==  VA_FOURCC_NV12){
  1196.               /* Nothing to do here */
  1197.      } else {
  1198.            /* not support other format as input */
  1199.            assert(0);
  1200.      }
  1201.  
  1202.      if(proc_ctx->format_convert_flags & POST_FORMAT_CONVERT ||
  1203.         proc_ctx->format_convert_flags & POST_SCALING_CONVERT){
  1204.        if(proc_ctx->surface_output_vebox_object == NULL){
  1205.              va_status = i965_CreateSurfaces(ctx,
  1206.                                             proc_ctx->width_input,
  1207.                                             proc_ctx->height_input,
  1208.                                             VA_RT_FORMAT_YUV420,
  1209.                                             1,
  1210.                                             &(proc_ctx->surface_output_vebox));
  1211.              assert(va_status == VA_STATUS_SUCCESS);
  1212.              obj_surf_output_vebox = SURFACE(proc_ctx->surface_output_vebox);
  1213.              assert(obj_surf_output_vebox);
  1214.  
  1215.              if (obj_surf_output_vebox) {
  1216.                  proc_ctx->surface_output_vebox_object = obj_surf_output_vebox;
  1217.                  i965_check_alloc_surface_bo(ctx, obj_surf_output_vebox, 1, VA_FOURCC_NV12, SUBSAMPLE_YUV420);
  1218.              }
  1219.        }
  1220.      }  
  1221.  
  1222.      if(proc_ctx->format_convert_flags & POST_SCALING_CONVERT){
  1223.        if(proc_ctx->surface_output_scaled_object == NULL){
  1224.              va_status = i965_CreateSurfaces(ctx,
  1225.                                             proc_ctx->width_output,
  1226.                                             proc_ctx->height_output,
  1227.                                             VA_RT_FORMAT_YUV420,
  1228.                                             1,
  1229.                                             &(proc_ctx->surface_output_scaled));
  1230.              assert(va_status == VA_STATUS_SUCCESS);
  1231.              obj_surf_output_vebox = SURFACE(proc_ctx->surface_output_scaled);
  1232.              assert(obj_surf_output_vebox);
  1233.  
  1234.              if (obj_surf_output_vebox) {
  1235.                  proc_ctx->surface_output_scaled_object = obj_surf_output_vebox;
  1236.                  i965_check_alloc_surface_bo(ctx, obj_surf_output_vebox, 1, VA_FOURCC_NV12, SUBSAMPLE_YUV420);
  1237.              }
  1238.        }
  1239.      }
  1240.    
  1241.      return 0;
  1242. }
  1243.  
  1244. int hsw_veb_post_format_convert(VADriverContextP ctx,
  1245.                            struct intel_vebox_context *proc_ctx)
  1246. {
  1247.     struct object_surface *obj_surface = NULL;
  1248.    
  1249.     obj_surface = proc_ctx->frame_store[proc_ctx->current_output].obj_surface;
  1250.  
  1251.     if (proc_ctx->format_convert_flags & POST_COPY_CONVERT) {
  1252.         /* copy the saved frame in the second call */
  1253.         vpp_surface_convert(ctx,proc_ctx->surface_output_object, obj_surface);
  1254.     } else if(!(proc_ctx->format_convert_flags & POST_FORMAT_CONVERT) &&
  1255.        !(proc_ctx->format_convert_flags & POST_SCALING_CONVERT)){
  1256.         /* Output surface format is covered by vebox pipeline and
  1257.          * processed picture is already store in output surface
  1258.          * so nothing will be done here */
  1259.     } else if ((proc_ctx->format_convert_flags & POST_FORMAT_CONVERT) &&
  1260.                !(proc_ctx->format_convert_flags & POST_SCALING_CONVERT)){
  1261.        /* convert and copy NV12 to YV12/IMC3/IMC2/RGBA output*/
  1262.         vpp_surface_convert(ctx,proc_ctx->surface_output_object, obj_surface);
  1263.  
  1264.     } else if(proc_ctx->format_convert_flags & POST_SCALING_CONVERT) {
  1265.        /* scaling, convert and copy NV12 to YV12/IMC3/IMC2/RGBA output*/
  1266.         assert(obj_surface->fourcc == VA_FOURCC_NV12);
  1267.      
  1268.         /* first step :surface scaling */
  1269.         vpp_surface_scaling(ctx,proc_ctx->surface_output_scaled_object, obj_surface);
  1270.  
  1271.         /* second step: color format convert and copy to output */
  1272.         obj_surface = proc_ctx->surface_output_object;
  1273.  
  1274.         if(obj_surface->fourcc ==  VA_FOURCC_NV12 ||
  1275.            obj_surface->fourcc ==  VA_FOURCC_YV12 ||
  1276.            obj_surface->fourcc ==  VA_FOURCC_I420 ||
  1277.            obj_surface->fourcc ==  VA_FOURCC_YUY2 ||
  1278.            obj_surface->fourcc ==  VA_FOURCC_IMC1 ||
  1279.            obj_surface->fourcc ==  VA_FOURCC_IMC3 ||
  1280.            obj_surface->fourcc ==  VA_FOURCC_RGBA) {
  1281.            vpp_surface_convert(ctx, proc_ctx->surface_output_object, proc_ctx->surface_output_scaled_object);
  1282.        }else {
  1283.            assert(0);
  1284.        }
  1285.    }
  1286.  
  1287.     return 0;
  1288. }
  1289.  
  1290. VAStatus gen75_vebox_process_picture(VADriverContextP ctx,
  1291.                          struct intel_vebox_context *proc_ctx)
  1292. {
  1293.     struct i965_driver_data *i965 = i965_driver_data(ctx);
  1294.  
  1295.     VAProcPipelineParameterBuffer *pipe = proc_ctx->pipeline_param;
  1296.     VAProcFilterParameterBuffer* filter = NULL;
  1297.     struct object_buffer *obj_buf = NULL;
  1298.     unsigned int i;
  1299.  
  1300.     for (i = 0; i < pipe->num_filters; i ++) {
  1301.          obj_buf = BUFFER(pipe->filters[i]);
  1302.          
  1303.          assert(obj_buf && obj_buf->buffer_store);
  1304.  
  1305.          if (!obj_buf || !obj_buf->buffer_store)
  1306.              goto error;
  1307.  
  1308.          filter = (VAProcFilterParameterBuffer*)obj_buf-> buffer_store->buffer;
  1309.            
  1310.          if (filter->type == VAProcFilterNoiseReduction) {
  1311.              proc_ctx->filters_mask |= VPP_DNDI_DN;
  1312.              proc_ctx->filter_dn = filter;
  1313.          } else if (filter->type == VAProcFilterDeinterlacing) {
  1314.              proc_ctx->filters_mask |= VPP_DNDI_DI;
  1315.              proc_ctx->filter_di = filter;
  1316.          } else if (filter->type == VAProcFilterColorBalance) {
  1317.              proc_ctx->filters_mask |= VPP_IECP_PRO_AMP;
  1318.              proc_ctx->filter_iecp_amp = filter;
  1319.              proc_ctx->filter_iecp_amp_num_elements = obj_buf->num_elements;
  1320.          } else if (filter->type == VAProcFilterSkinToneEnhancement) {
  1321.              proc_ctx->filters_mask |= VPP_IECP_STD_STE;
  1322.              proc_ctx->filter_iecp_std = filter;
  1323.          }
  1324.     }
  1325.  
  1326.     hsw_veb_pre_format_convert(ctx, proc_ctx);
  1327.     hsw_veb_surface_reference(ctx, proc_ctx);
  1328.  
  1329.     if (proc_ctx->frame_order == -1) {
  1330.         hsw_veb_resource_prepare(ctx, proc_ctx);
  1331.     }
  1332.  
  1333.     if (proc_ctx->format_convert_flags & POST_COPY_CONVERT) {
  1334.         assert(proc_ctx->frame_order == 1);
  1335.         /* directly copy the saved frame in the second call */
  1336.     } else {
  1337.         intel_batchbuffer_start_atomic_veb(proc_ctx->batch, 0x1000);
  1338.         intel_batchbuffer_emit_mi_flush(proc_ctx->batch);
  1339.         hsw_veb_surface_state(ctx, proc_ctx, INPUT_SURFACE);
  1340.         hsw_veb_surface_state(ctx, proc_ctx, OUTPUT_SURFACE);
  1341.         hsw_veb_state_table_setup(ctx, proc_ctx);
  1342.  
  1343.         hsw_veb_state_command(ctx, proc_ctx);          
  1344.         hsw_veb_dndi_iecp_command(ctx, proc_ctx);
  1345.         intel_batchbuffer_end_atomic(proc_ctx->batch);
  1346.         intel_batchbuffer_flush(proc_ctx->batch);
  1347.     }
  1348.  
  1349.     hsw_veb_post_format_convert(ctx, proc_ctx);
  1350.     // hsw_veb_surface_unreference(ctx, proc_ctx);
  1351.  
  1352.     proc_ctx->frame_order = (proc_ctx->frame_order + 1) % 2;
  1353.      
  1354.     return VA_STATUS_SUCCESS;
  1355.  
  1356. error:
  1357.     return VA_STATUS_ERROR_INVALID_PARAMETER;
  1358. }
  1359.  
  1360. void gen75_vebox_context_destroy(VADriverContextP ctx,
  1361.                           struct intel_vebox_context *proc_ctx)
  1362. {
  1363.     int i;
  1364.  
  1365.     if(proc_ctx->surface_input_vebox != VA_INVALID_ID){
  1366.        i965_DestroySurfaces(ctx, &proc_ctx->surface_input_vebox, 1);
  1367.        proc_ctx->surface_input_vebox = VA_INVALID_ID;
  1368.        proc_ctx->surface_input_vebox_object = NULL;
  1369.      }
  1370.  
  1371.     if(proc_ctx->surface_output_vebox != VA_INVALID_ID){
  1372.        i965_DestroySurfaces(ctx, &proc_ctx->surface_output_vebox, 1);
  1373.        proc_ctx->surface_output_vebox = VA_INVALID_ID;
  1374.        proc_ctx->surface_output_vebox_object = NULL;
  1375.      }
  1376.  
  1377.     if(proc_ctx->surface_output_scaled != VA_INVALID_ID){
  1378.        i965_DestroySurfaces(ctx, &proc_ctx->surface_output_scaled, 1);
  1379.        proc_ctx->surface_output_scaled = VA_INVALID_ID;
  1380.        proc_ctx->surface_output_scaled_object = NULL;
  1381.      }
  1382.  
  1383.     for(i = 0; i < FRAME_STORE_SUM; i ++) {
  1384.         if (proc_ctx->frame_store[i].is_internal_surface == 1) {
  1385.             assert(proc_ctx->frame_store[i].surface_id != VA_INVALID_ID);
  1386.  
  1387.             if (proc_ctx->frame_store[i].surface_id != VA_INVALID_ID)
  1388.                 i965_DestroySurfaces(ctx, &proc_ctx->frame_store[i].surface_id, 1);
  1389.         }
  1390.  
  1391.         proc_ctx->frame_store[i].surface_id = VA_INVALID_ID;
  1392.         proc_ctx->frame_store[i].is_internal_surface = 0;
  1393.         proc_ctx->frame_store[i].obj_surface = NULL;
  1394.     }
  1395.  
  1396.     /* dndi state table  */
  1397.     dri_bo_unreference(proc_ctx->dndi_state_table.bo);
  1398.     proc_ctx->dndi_state_table.bo = NULL;
  1399.  
  1400.     /* iecp state table  */
  1401.     dri_bo_unreference(proc_ctx->iecp_state_table.bo);
  1402.     proc_ctx->dndi_state_table.bo = NULL;
  1403.  
  1404.     /* gamut statu table */
  1405.     dri_bo_unreference(proc_ctx->gamut_state_table.bo);
  1406.     proc_ctx->gamut_state_table.bo = NULL;
  1407.  
  1408.     /* vertex state table  */
  1409.     dri_bo_unreference(proc_ctx->vertex_state_table.bo);
  1410.     proc_ctx->vertex_state_table.bo = NULL;
  1411.  
  1412.     intel_batchbuffer_free(proc_ctx->batch);
  1413.  
  1414.     free(proc_ctx);
  1415. }
  1416.  
  1417. struct intel_vebox_context * gen75_vebox_context_init(VADriverContextP ctx)
  1418. {
  1419.     struct intel_driver_data *intel = intel_driver_data(ctx);
  1420.     struct intel_vebox_context *proc_context = calloc(1, sizeof(struct intel_vebox_context));
  1421.     int i;
  1422.  
  1423.     proc_context->batch = intel_batchbuffer_new(intel, I915_EXEC_VEBOX, 0);
  1424.     memset(proc_context->frame_store, 0, sizeof(VEBFrameStore)*FRAME_STORE_SUM);
  1425.  
  1426.     for (i = 0; i < FRAME_STORE_SUM; i ++) {
  1427.         proc_context->frame_store[i].surface_id = VA_INVALID_ID;
  1428.         proc_context->frame_store[i].is_internal_surface = 0;
  1429.         proc_context->frame_store[i].obj_surface = NULL;
  1430.     }
  1431.  
  1432.     proc_context->filters_mask          = 0;
  1433.     proc_context->frame_order           = -1; /* the first frame */
  1434.     proc_context->surface_output_object = NULL;
  1435.     proc_context->surface_input_object  = NULL;
  1436.     proc_context->surface_input_vebox   = VA_INVALID_ID;
  1437.     proc_context->surface_input_vebox_object = NULL;
  1438.     proc_context->surface_output_vebox  = VA_INVALID_ID;
  1439.     proc_context->surface_output_vebox_object = NULL;
  1440.     proc_context->surface_output_scaled = VA_INVALID_ID;
  1441.     proc_context->surface_output_scaled_object = NULL;
  1442.     proc_context->filters_mask          = 0;
  1443.     proc_context->format_convert_flags  = 0;
  1444.  
  1445.     return proc_context;
  1446. }
  1447.  
  1448. void bdw_veb_state_command(VADriverContextP ctx, struct intel_vebox_context *proc_ctx)
  1449. {
  1450.     struct intel_batchbuffer *batch = proc_ctx->batch;
  1451.     unsigned int is_dn_enabled   = (proc_ctx->filters_mask & 0x01)? 1: 0;
  1452.     unsigned int is_di_enabled   = (proc_ctx->filters_mask & 0x02)? 1: 0;
  1453.     unsigned int is_iecp_enabled = (proc_ctx->filters_mask & 0xff00)?1:0;
  1454.     unsigned int is_first_frame  = !!((proc_ctx->frame_order == -1) &&
  1455.                                       (is_di_enabled ||
  1456.                                        is_dn_enabled));
  1457.     unsigned int di_output_frames_flag = 2; /* Output Current Frame Only */
  1458.  
  1459.     if(proc_ctx->fourcc_input != proc_ctx->fourcc_output ||
  1460.        (is_dn_enabled == 0 && is_di_enabled == 0)){
  1461.        is_iecp_enabled = 1;
  1462.     }
  1463.  
  1464.     if (is_di_enabled) {
  1465.         VAProcFilterParameterBufferDeinterlacing *di_param =
  1466.             (VAProcFilterParameterBufferDeinterlacing *)proc_ctx->filter_di;
  1467.  
  1468.         assert(di_param);
  1469.        
  1470.         if (di_param->algorithm == VAProcDeinterlacingBob)
  1471.             is_first_frame = 1;
  1472.  
  1473.         if ((di_param->algorithm == VAProcDeinterlacingMotionAdaptive ||
  1474.             di_param->algorithm == VAProcDeinterlacingMotionCompensated) &&
  1475.             proc_ctx->frame_order != -1)
  1476.             di_output_frames_flag = 0; /* Output both Current Frame and Previous Frame */
  1477.     }
  1478.  
  1479.     BEGIN_VEB_BATCH(batch, 0xc);
  1480.     OUT_VEB_BATCH(batch, VEB_STATE | (0xc - 2));
  1481.     OUT_VEB_BATCH(batch,
  1482.                   0 << 25 |       // state surface control bits
  1483.                   0 << 23 |       // reserved.
  1484.                   0 << 22 |       // gamut expansion position
  1485.                   0 << 15 |       // reserved.
  1486.                   0 << 14 |       // single slice vebox enable
  1487.                   0 << 13 |       // hot pixel filter enable
  1488.                   0 << 12 |       // alpha plane enable
  1489.                   0 << 11 |       // vignette enable
  1490.                   0 << 10 |       // demosaic enable
  1491.                   di_output_frames_flag << 8  |       // DI output frame
  1492.                   1 << 7  |       // 444->422 downsample method
  1493.                   1 << 6  |       // 422->420 downsample method
  1494.                   is_first_frame  << 5  |   // DN/DI first frame
  1495.                   is_di_enabled   << 4  |             // DI enable
  1496.                   is_dn_enabled   << 3  |             // DN enable
  1497.                   is_iecp_enabled << 2  |             // global IECP enabled
  1498.                   0 << 1  |       // ColorGamutCompressionEnable
  1499.                   0 ) ;           // ColorGamutExpansionEnable.
  1500.  
  1501.     OUT_RELOC(batch,
  1502.               proc_ctx->dndi_state_table.bo,
  1503.               I915_GEM_DOMAIN_INSTRUCTION, 0, 0);
  1504.  
  1505.     OUT_VEB_BATCH(batch, 0);
  1506.  
  1507.     OUT_RELOC(batch,
  1508.               proc_ctx->iecp_state_table.bo,
  1509.               I915_GEM_DOMAIN_INSTRUCTION, 0, 0);
  1510.  
  1511.     OUT_VEB_BATCH(batch, 0);
  1512.  
  1513.     OUT_RELOC(batch,
  1514.               proc_ctx->gamut_state_table.bo,
  1515.               I915_GEM_DOMAIN_INSTRUCTION, 0, 0);
  1516.  
  1517.     OUT_VEB_BATCH(batch, 0);
  1518.  
  1519.     OUT_RELOC(batch,
  1520.               proc_ctx->vertex_state_table.bo,
  1521.               I915_GEM_DOMAIN_INSTRUCTION, 0, 0);
  1522.  
  1523.     OUT_VEB_BATCH(batch, 0);
  1524.  
  1525.     OUT_VEB_BATCH(batch, 0);/*caputre pipe state pointer*/
  1526.     OUT_VEB_BATCH(batch, 0);
  1527.  
  1528.     ADVANCE_VEB_BATCH(batch);
  1529. }
  1530.  
  1531. void bdw_veb_dndi_iecp_command(VADriverContextP ctx, struct intel_vebox_context *proc_ctx)
  1532. {
  1533.     struct intel_batchbuffer *batch = proc_ctx->batch;
  1534.     unsigned char frame_ctrl_bits = 0;
  1535.     unsigned int startingX = 0;
  1536.     unsigned int endingX = (proc_ctx->width_input + 63 ) / 64 * 64;
  1537.  
  1538.     BEGIN_VEB_BATCH(batch, 0x14);
  1539.     OUT_VEB_BATCH(batch, VEB_DNDI_IECP_STATE | (0x14 - 2));//DWord 0
  1540.     OUT_VEB_BATCH(batch,
  1541.                   startingX << 16 |
  1542.                   endingX -1);//DWord 1
  1543.  
  1544.     OUT_RELOC(batch,
  1545.               proc_ctx->frame_store[FRAME_IN_CURRENT].obj_surface->bo,
  1546.               I915_GEM_DOMAIN_RENDER, 0, frame_ctrl_bits);//DWord 2
  1547.     OUT_VEB_BATCH(batch,0);//DWord 3
  1548.  
  1549.     OUT_RELOC(batch,
  1550.               proc_ctx->frame_store[FRAME_IN_PREVIOUS].obj_surface->bo,
  1551.               I915_GEM_DOMAIN_RENDER, 0, frame_ctrl_bits);//DWord 4
  1552.     OUT_VEB_BATCH(batch,0);//DWord 5
  1553.  
  1554.     OUT_RELOC(batch,
  1555.               proc_ctx->frame_store[FRAME_IN_STMM].obj_surface->bo,
  1556.               I915_GEM_DOMAIN_RENDER, 0, frame_ctrl_bits);//DWord 6
  1557.     OUT_VEB_BATCH(batch,0);//DWord 7
  1558.  
  1559.     OUT_RELOC(batch,
  1560.               proc_ctx->frame_store[FRAME_OUT_STMM].obj_surface->bo,
  1561.               I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, frame_ctrl_bits);//DWord 8
  1562.     OUT_VEB_BATCH(batch,0);//DWord 9
  1563.  
  1564.     OUT_RELOC(batch,
  1565.               proc_ctx->frame_store[FRAME_OUT_CURRENT_DN].obj_surface->bo,
  1566.               I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, frame_ctrl_bits);//DWord 10
  1567.     OUT_VEB_BATCH(batch,0);//DWord 11
  1568.  
  1569.     OUT_RELOC(batch,
  1570.               proc_ctx->frame_store[FRAME_OUT_CURRENT].obj_surface->bo,
  1571.               I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, frame_ctrl_bits);//DWord 12
  1572.     OUT_VEB_BATCH(batch,0);//DWord 13
  1573.  
  1574.     OUT_RELOC(batch,
  1575.               proc_ctx->frame_store[FRAME_OUT_PREVIOUS].obj_surface->bo,
  1576.               I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, frame_ctrl_bits);//DWord 14
  1577.     OUT_VEB_BATCH(batch,0);//DWord 15
  1578.  
  1579.     OUT_RELOC(batch,
  1580.               proc_ctx->frame_store[FRAME_OUT_STATISTIC].obj_surface->bo,
  1581.               I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, frame_ctrl_bits);//DWord 16
  1582.     OUT_VEB_BATCH(batch,0);//DWord 17
  1583.  
  1584.     OUT_VEB_BATCH(batch,0);//DWord 18
  1585.     OUT_VEB_BATCH(batch,0);//DWord 19
  1586.  
  1587.     ADVANCE_VEB_BATCH(batch);
  1588. }
  1589.  
  1590. VAStatus gen8_vebox_process_picture(VADriverContextP ctx,
  1591.                          struct intel_vebox_context *proc_ctx)
  1592. {
  1593.     struct i965_driver_data *i965 = i965_driver_data(ctx);
  1594.  
  1595.     VAProcPipelineParameterBuffer *pipe = proc_ctx->pipeline_param;
  1596.     VAProcFilterParameterBuffer* filter = NULL;
  1597.     struct object_buffer *obj_buf = NULL;
  1598.     unsigned int i;
  1599.  
  1600.     for (i = 0; i < pipe->num_filters; i ++) {
  1601.          obj_buf = BUFFER(pipe->filters[i]);
  1602.          
  1603.          assert(obj_buf && obj_buf->buffer_store);
  1604.  
  1605.          if (!obj_buf || !obj_buf->buffer_store)
  1606.              goto error;
  1607.  
  1608.          filter = (VAProcFilterParameterBuffer*)obj_buf-> buffer_store->buffer;
  1609.            
  1610.          if (filter->type == VAProcFilterNoiseReduction) {
  1611.              proc_ctx->filters_mask |= VPP_DNDI_DN;
  1612.              proc_ctx->filter_dn = filter;
  1613.          } else if (filter->type == VAProcFilterDeinterlacing) {
  1614.              proc_ctx->filters_mask |= VPP_DNDI_DI;
  1615.              proc_ctx->filter_di = filter;
  1616.          } else if (filter->type == VAProcFilterColorBalance) {
  1617.              proc_ctx->filters_mask |= VPP_IECP_PRO_AMP;
  1618.              proc_ctx->filter_iecp_amp = filter;
  1619.              proc_ctx->filter_iecp_amp_num_elements = obj_buf->num_elements;
  1620.          } else if (filter->type == VAProcFilterSkinToneEnhancement) {
  1621.              proc_ctx->filters_mask |= VPP_IECP_STD_STE;
  1622.              proc_ctx->filter_iecp_std = filter;
  1623.          }
  1624.     }
  1625.  
  1626.     hsw_veb_pre_format_convert(ctx, proc_ctx);
  1627.     hsw_veb_surface_reference(ctx, proc_ctx);
  1628.  
  1629.     if (proc_ctx->frame_order == -1) {
  1630.         hsw_veb_resource_prepare(ctx, proc_ctx);
  1631.     }
  1632.  
  1633.     if (proc_ctx->format_convert_flags & POST_COPY_CONVERT) {
  1634.         assert(proc_ctx->frame_order == 1);
  1635.         /* directly copy the saved frame in the second call */
  1636.     } else {
  1637.         intel_batchbuffer_start_atomic_veb(proc_ctx->batch, 0x1000);
  1638.         intel_batchbuffer_emit_mi_flush(proc_ctx->batch);
  1639.         hsw_veb_surface_state(ctx, proc_ctx, INPUT_SURFACE);
  1640.         hsw_veb_surface_state(ctx, proc_ctx, OUTPUT_SURFACE);
  1641.         hsw_veb_state_table_setup(ctx, proc_ctx);
  1642.  
  1643.         bdw_veb_state_command(ctx, proc_ctx);          
  1644.         bdw_veb_dndi_iecp_command(ctx, proc_ctx);
  1645.         intel_batchbuffer_end_atomic(proc_ctx->batch);
  1646.         intel_batchbuffer_flush(proc_ctx->batch);
  1647.     }
  1648.  
  1649.     hsw_veb_post_format_convert(ctx, proc_ctx);
  1650.     // hsw_veb_surface_unreference(ctx, proc_ctx);
  1651.  
  1652.     proc_ctx->frame_order = (proc_ctx->frame_order + 1) % 2;
  1653.      
  1654.     return VA_STATUS_SUCCESS;
  1655.  
  1656. error:
  1657.     return VA_STATUS_ERROR_INVALID_PARAMETER;
  1658. }
  1659.  
  1660.