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. VAStatus
  57. vpp_surface_convert(VADriverContextP ctx, struct object_surface *src_obj_surf,
  58.     struct object_surface *dst_obj_surf)
  59. {
  60.     VAStatus va_status = VA_STATUS_SUCCESS;
  61.  
  62.     assert(src_obj_surf->orig_width  == dst_obj_surf->orig_width);
  63.     assert(src_obj_surf->orig_height == dst_obj_surf->orig_height);
  64.  
  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;
  70.  
  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;
  75.  
  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;
  79.  
  80.     va_status = i965_image_processing(ctx,
  81.                                      &src_surface,
  82.                                      &src_rect,
  83.                                      &dst_surface,
  84.                                      &dst_rect);
  85.     return va_status;
  86. }
  87.  
  88. static VAStatus
  89. vpp_surface_scaling(VADriverContextP ctx, struct object_surface *src_obj_surf,
  90.     struct object_surface *dst_obj_surf, uint32_t flags)
  91. {
  92.     VAStatus va_status = VA_STATUS_SUCCESS;
  93.  
  94.     assert(src_obj_surf->fourcc == VA_FOURCC_NV12);
  95.     assert(dst_obj_surf->fourcc == VA_FOURCC_NV12);
  96.  
  97.     VARectangle src_rect, dst_rect;
  98.     src_rect.x = 0;
  99.     src_rect.y = 0;
  100.     src_rect.width  = src_obj_surf->orig_width;
  101.     src_rect.height = src_obj_surf->orig_height;
  102.  
  103.     dst_rect.x = 0;
  104.     dst_rect.y = 0;
  105.     dst_rect.width  = dst_obj_surf->orig_width;
  106.     dst_rect.height = dst_obj_surf->orig_height;
  107.  
  108.     va_status = i965_scaling_processing(ctx,
  109.                                        src_obj_surf,
  110.                                        &src_rect,
  111.                                        dst_obj_surf,
  112.                                        &dst_rect,
  113.                                        flags);
  114.      
  115.     return va_status;
  116. }
  117.  
  118. void hsw_veb_dndi_table(VADriverContextP ctx, struct intel_vebox_context *proc_ctx)
  119. {
  120.     struct i965_driver_data *i965 = i965_driver_data(ctx);
  121.     unsigned int* p_table ;
  122.     unsigned int progressive_dn = 1;
  123.     unsigned int dndi_top_first = 0;
  124.     unsigned int is_mcdi_enabled = 0;
  125.  
  126.     if (proc_ctx->is_di_enabled) {
  127.         const VAProcFilterParameterBufferDeinterlacing * const deint_params =
  128.             proc_ctx->filter_di;
  129.  
  130.         progressive_dn = 0;
  131.  
  132.         /* If we are in "First Frame" mode, i.e. past frames are not
  133.            available for motion measure, then don't use the TFF flag */
  134.         dndi_top_first = !(deint_params->flags & (proc_ctx->is_first_frame ?
  135.                 VA_DEINTERLACING_BOTTOM_FIELD :
  136.                 VA_DEINTERLACING_BOTTOM_FIELD_FIRST));
  137.  
  138.         is_mcdi_enabled =
  139.             (deint_params->algorithm == VAProcDeinterlacingMotionCompensated);
  140.     }
  141.  
  142.     /*
  143.     VAProcFilterParameterBufferDeinterlacing *di_param =
  144.             (VAProcFilterParameterBufferDeinterlacing *) proc_ctx->filter_di;
  145.  
  146.     VAProcFilterParameterBuffer * dn_param =
  147.             (VAProcFilterParameterBuffer *) proc_ctx->filter_dn;
  148.     */
  149.     p_table = (unsigned int *)proc_ctx->dndi_state_table.ptr;
  150.  
  151.      if (IS_HASWELL(i965->intel.device_info))
  152.          *p_table ++ = 0;               // reserved  . w0
  153.  
  154.     *p_table ++ = ( 140 << 24 |    // denoise STAD threshold . w1
  155.                     192 << 16 |    // dnmh_history_max
  156.                     0   << 12 |    // reserved
  157.                     7   << 8  |    // dnmh_delta[3:0]
  158.                     38 );          // denoise ASD threshold
  159.  
  160.     *p_table ++ = ( 0  << 30 |    // reserved . w2
  161.                     0  << 24 |    // temporal diff th
  162.                     0  << 22 |    // reserved.
  163.                     0  << 16 |    // low temporal diff th
  164.                     2  << 13 |    // STMM C2
  165.                     1  << 8  |    // denoise moving pixel th
  166.                     38 );         // denoise th for sum of complexity measure
  167.  
  168.     *p_table ++ = ( 0 << 30  |   // reserved . w3
  169.                     12<< 24  |   // good neighbor th[5:0]
  170.                     9 << 20  |   // CAT slope minus 1
  171.                     5 << 16  |   // SAD Tight in
  172.                     0 << 14  |   // smooth mv th
  173.                     0 << 12  |   // reserved
  174.                     1 << 8   |   // bne_edge_th[3:0]
  175.                     20 );        // block noise estimate noise th
  176.  
  177.     *p_table ++ = ( 0  << 31  |  // STMM blending constant select. w4
  178.                     64 << 24  |  // STMM trc1
  179.                     125<< 16  |  // STMM trc2
  180.                     0  << 14  |  // reserved
  181.                     30 << 8   |  // VECM_mul
  182.                     150 );       // maximum STMM
  183.  
  184.     *p_table ++ = ( 118<< 24  |  // minumum STMM  . W5
  185.                     0  << 22  |  // STMM shift down
  186.                     1  << 20  |  // STMM shift up
  187.                     5  << 16  |  // STMM output shift
  188.                     100 << 8  |  // SDI threshold
  189.                     5 );         // SDI delta
  190.  
  191.     *p_table ++ = ( 50  << 24 |  // SDI fallback mode 1 T1 constant . W6
  192.                     100 << 16 |  // SDI fallback mode 1 T2 constant
  193.                     37  << 8  |  // SDI fallback mode 2 constant(angle2x1)
  194.                     175 );       // FMD temporal difference threshold
  195.  
  196.     *p_table ++ = ( 16 << 24  |  // FMD #1 vertical difference th . w7
  197.                     100<< 16  |  // FMD #2 vertical difference th
  198.                     0  << 14  |  // CAT th1
  199.                     2  << 8   |  // FMD tear threshold
  200.                     is_mcdi_enabled  << 7  |  // MCDI Enable, use motion compensated deinterlace algorithm
  201.                     progressive_dn  << 6   |  // progressive DN
  202.                     0  << 4   |  // reserved
  203.                     dndi_top_first  << 3   |  // DN/DI Top First
  204.                     0 );         // reserved
  205.  
  206.     *p_table ++ = ( 0  << 29  |  // reserved . W8
  207.                     32 << 23  |  // dnmh_history_init[5:0]
  208.                     10 << 19  |  // neighborPixel th
  209.                     0  << 18  |  // reserved
  210.                     0  << 16  |  // FMD for 2nd field of previous frame
  211.                     25 << 10  |  // MC pixel consistency th
  212.                     0  << 8   |  // FMD for 1st field for current frame
  213.                     10 << 4   |  // SAD THB
  214.                     5 );         // SAD THA
  215.  
  216.     *p_table ++ = ( 0  << 24  |  // reserved
  217.                     140<< 16  |  // chr_dnmh_stad_th
  218.                     0  << 13  |  // reserved
  219.                     1  << 12  |  // chrome denoise enable
  220.                     13 << 6   |  // chr temp diff th
  221.                     7 );         // chr temp diff low
  222.  
  223.     if (IS_GEN8(i965->intel.device_info) ||
  224.         IS_GEN9(i965->intel.device_info))
  225.         *p_table ++ = 0;         // parameters for hot pixel,
  226. }
  227.  
  228. //Set default values for STDE
  229. void set_std_table_default(struct intel_vebox_context *proc_ctx, unsigned int *p_table) {
  230.  
  231.         //DWord 15
  232.         *p_table ++ = ( 0 << 31     |    // Reserved
  233.                         0x3F8 << 21 |    // SATB1 (10 bits, default 8, optimized value -8)
  234.                         31 << 14    |    // SATP3
  235.                         6 << 7      |    // SATP2
  236.                         0x7A );          // SATP1 (7 bits, default 6, optimized value -6)
  237.  
  238.         //DWord 16
  239.         *p_table ++ = ( 0 << 31   |    // Reserved
  240.                         297 << 20 |    // SATS0
  241.                         124 << 10 |    // SATB3
  242.                         8 );           // SATB2
  243.  
  244.         //DWord 17
  245.         *p_table ++ = ( 0 << 22   |    // Reserved
  246.                         297 << 11 |    // SATS2
  247.                         85 );          // SATS1
  248.  
  249.         //DWord 18
  250.         *p_table ++ = ( 14 << 25    |    // HUEP3
  251.                         6 << 18     |    // HUEP2
  252.                         0x7A << 11  |    // HUEP1 (7 bits, default value -6 = 7Ah)
  253.                         256 );           // SATS3
  254.  
  255.         //DWord 19
  256.         *p_table ++ = ( 0 << 30   |    // Reserved
  257.                         256 << 20 |    // HUEB3
  258.                         8 << 10   |    // HUEB2
  259.                         0x3F8 );       // HUEB1 (10 bits, default value 8, optimized value -8)
  260.  
  261.         //DWord 20
  262.         *p_table ++ = ( 0 << 22   |    // Reserved
  263.                         85 << 11  |    // HUES1
  264.                         384 );         // HUES0
  265.  
  266.         //DWord 21
  267.         *p_table ++ = ( 0 << 22   |    // Reserved
  268.                         256 << 11 |    // HUES3
  269.                         384 );         // HUES2
  270.  
  271.         //DWord 22
  272.         *p_table ++ = ( 0 << 31   |    // Reserved
  273.                         0 << 21   |    // SATB1_DARK
  274.                         31 << 14  |    // SATP3_DARK
  275.                         31 << 7   |    // SATP2_DARK
  276.                         0x7B );        // SATP1_DARK (7 bits, default value -11 = FF5h, optimized value -5)
  277.  
  278.         //DWord 23
  279.         *p_table ++ = ( 0 << 31   |    // Reserved
  280.                         305 << 20 |    // SATS0_DARK
  281.                         124 << 10 |    // SATB3_DARK
  282.                         124 );         // SATB2_DARK
  283.  
  284.         //DWord 24
  285.         *p_table ++ = ( 0 << 22   |    // Reserved
  286.                         256 << 11 |    // SATS2_DARK
  287.                         220 );         // SATS1_DARK
  288.  
  289.         //DWord 25
  290.         *p_table ++ = ( 14 << 25  |    // HUEP3_DARK
  291.                         14 << 18  |    // HUEP2_DARK
  292.                         14 << 11  |    // HUEP1_DARK
  293.                         256 );         // SATS3_DARK
  294.  
  295.         //DWord 26
  296.         *p_table ++ = ( 0 << 30   |    // Reserved
  297.                         56 << 20  |    // HUEB3_DARK
  298.                         56 << 10  |    // HUEB2_DARK
  299.                         56 );          // HUEB1_DARK
  300.  
  301.         //DWord 27
  302.         *p_table ++ = ( 0 << 22   |    // Reserved
  303.                         256 << 11 |    // HUES1_DARK
  304.                         256 );         // HUES0_DARK
  305.  
  306.         //DWord 28
  307.         *p_table ++ = ( 0 << 22   |    // Reserved
  308.                         256 << 11 |    // HUES3_DARK
  309.                         256 );         // HUES2_DARK
  310. }
  311.  
  312. //Set values for STDE factor 3
  313. void set_std_table_3(struct intel_vebox_context *proc_ctx, unsigned int *p_table) {
  314.  
  315.         //DWord 15
  316.         *p_table ++ = ( 0 << 31     |    // Reserved
  317.                         1016 << 21  |    // SATB1 (10 bits, default 8, optimized value 1016)
  318.                         31 << 14    |    // SATP3
  319.                         6 << 7      |    // SATP2
  320.                         122 );           // SATP1 (7 bits, default 6, optimized value 122)
  321.  
  322.         //DWord 16
  323.         *p_table ++ = ( 0 << 31   |    // Reserved
  324.                         297 << 20 |    // SATS0
  325.                         124 << 10 |    // SATB3
  326.                         8 );           // SATB2
  327.  
  328.         //DWord 17
  329.         *p_table ++ = ( 0 << 22   |    // Reserved
  330.                         297 << 11 |    // SATS2
  331.                         85 );          // SATS1
  332.  
  333.         //DWord 18
  334.         *p_table ++ = ( 14 << 25    |    // HUEP3
  335.                         6 << 18     |    // HUEP2
  336.                         122 << 11   |    // HUEP1 (7 bits, default value -6 = 7Ah, optimized 122)
  337.                         256 );           // SATS3
  338.  
  339.         //DWord 19
  340.         *p_table ++ = ( 0 << 30   |    // Reserved
  341.                         56 << 20  |    // HUEB3 (default 256, optimized 56)
  342.                         8 << 10   |    // HUEB2
  343.                         1016 );        // HUEB1 (10 bits, default value 8, optimized value 1016)
  344.  
  345.         //DWord 20
  346.         *p_table ++ = ( 0 << 22   |    // Reserved
  347.                         85 << 11  |    // HUES1
  348.                         384 );         // HUES0
  349.  
  350.         //DWord 21
  351.         *p_table ++ = ( 0 << 22   |    // Reserved
  352.                         256 << 11 |    // HUES3
  353.                         384 );         // HUES2
  354.  
  355.         //DWord 22
  356.         *p_table ++ = ( 0 << 31   |    // Reserved
  357.                         0 << 21   |    // SATB1_DARK
  358.                         31 << 14  |    // SATP3_DARK
  359.                         31 << 7   |    // SATP2_DARK
  360.                         123 );         // SATP1_DARK (7 bits, default value -11 = FF5h, optimized value 123)
  361.  
  362.         //DWord 23
  363.         *p_table ++ = ( 0 << 31   |    // Reserved
  364.                         305 << 20 |    // SATS0_DARK
  365.                         124 << 10 |    // SATB3_DARK
  366.                         124 );         // SATB2_DARK
  367.  
  368.         //DWord 24
  369.         *p_table ++ = ( 0 << 22   |    // Reserved
  370.                         256 << 11 |    // SATS2_DARK
  371.                         220 );         // SATS1_DARK
  372.  
  373.         //DWord 25
  374.         *p_table ++ = ( 14 << 25  |    // HUEP3_DARK
  375.                         14 << 18  |    // HUEP2_DARK
  376.                         14 << 11  |    // HUEP1_DARK
  377.                         256 );         // SATS3_DARK
  378.  
  379.         //DWord 26
  380.         *p_table ++ = ( 0 << 30   |    // Reserved
  381.                         56 << 20  |    // HUEB3_DARK
  382.                         56 << 10  |    // HUEB2_DARK
  383.                         56 );          // HUEB1_DARK
  384.  
  385.         //DWord 27
  386.         *p_table ++ = ( 0 << 22   |    // Reserved
  387.                         256 << 11 |    // HUES1_DARK
  388.                         256 );         // HUES0_DARK
  389.  
  390.         //DWord 28
  391.         *p_table ++ = ( 0 << 22   |    // Reserved
  392.                         256 << 11 |    // HUES3_DARK
  393.                         256 );         // HUES2_DARK
  394. }
  395.  
  396. //Set values for STDE factor 6
  397. void set_std_table_6(struct intel_vebox_context *proc_ctx, unsigned int *p_table) {
  398.  
  399.         //DWord 15
  400.         *p_table ++ = ( 0 << 31     |    // Reserved
  401.                         0 << 21     |    // SATB1 (10 bits, default 8, optimized value 0)
  402.                         31 << 14    |    // SATP3
  403.                         31 << 7     |    // SATP2 (default 6, optimized 31)
  404.                         114 );           // SATP1 (7 bits, default 6, optimized value 114)
  405.  
  406.         //DWord 16
  407.         *p_table ++ = ( 0 << 31   |    // Reserved
  408.                         467 << 20 |    // SATS0 (default 297, optimized 467)
  409.                         124 << 10 |    // SATB3
  410.                         124 );         // SATB2
  411.  
  412.         //DWord 17
  413.         *p_table ++ = ( 0 << 22   |    // Reserved
  414.                         256 << 11 |    // SATS2 (default 297, optimized 256)
  415.                         176 );         // SATS1
  416.  
  417.         //DWord 18
  418.         *p_table ++ = ( 14 << 25    |    // HUEP3
  419.                         14 << 18    |    // HUEP2
  420.                         14 << 11    |    // HUEP1 (7 bits, default value -6 = 7Ah, optimized value 14)
  421.                         256 );           // SATS3
  422.  
  423.         //DWord 19
  424.         *p_table ++ = ( 0 << 30   |    // Reserved
  425.                         56 << 20  |    // HUEB3
  426.                         56 << 10  |    // HUEB2
  427.                         56 );          // HUEB1 (10 bits, default value 8, optimized value 56)
  428.  
  429.         //DWord 20
  430.         *p_table ++ = ( 0 << 22   |    // Reserved
  431.                         256 << 11 |    // HUES1
  432.                         256 );         // HUES0
  433.  
  434.         //DWord 21
  435.         *p_table ++ = ( 0 << 22   |    // Reserved
  436.                         256 << 11 |    // HUES3
  437.                         256 );         // HUES2
  438.  
  439.         //DWord 22
  440.         *p_table ++ = ( 0 << 31   |    // Reserved
  441.                         0 << 21   |    // SATB1_DARK
  442.                         31 << 14  |    // SATP3_DARK
  443.                         31 << 7   |    // SATP2_DARK
  444.                         123 );         // SATP1_DARK (7 bits, default value -11 = FF5h, optimized value 123)
  445.  
  446.         //DWord 23
  447.         *p_table ++ = ( 0 << 31   |    // Reserved
  448.                         305 << 20 |    // SATS0_DARK
  449.                         124 << 10 |    // SATB3_DARK
  450.                         124 );         // SATB2_DARK
  451.  
  452.         //DWord 24
  453.         *p_table ++ = ( 0 << 22   |    // Reserved
  454.                         256 << 11 |    // SATS2_DARK
  455.                         220 );         // SATS1_DARK
  456.  
  457.         //DWord 25
  458.         *p_table ++ = ( 14 << 25  |    // HUEP3_DARK
  459.                         14 << 18  |    // HUEP2_DARK
  460.                         14 << 11  |    // HUEP1_DARK
  461.                         256 );         // SATS3_DARK
  462.  
  463.         //DWord 26
  464.         *p_table ++ = ( 0 << 30   |    // Reserved
  465.                         56 << 20  |    // HUEB3_DARK
  466.                         56 << 10  |    // HUEB2_DARK
  467.                         56 );          // HUEB1_DARK
  468.  
  469.         //DWord 27
  470.         *p_table ++ = ( 0 << 22   |    // Reserved
  471.                         256 << 11 |    // HUES1_DARK
  472.                         256 );         // HUES0_DARK
  473.  
  474.         //DWord 28
  475.         *p_table ++ = ( 0 << 22   |    // Reserved
  476.                         256 << 11 |    // HUES3_DARK
  477.                         256 );         // HUES2_DARK
  478. }
  479.  
  480. //Set values for STDE factor 9
  481. void set_std_table_9(struct intel_vebox_context *proc_ctx, unsigned int *p_table) {
  482.  
  483.         //DWord 15
  484.         *p_table ++ = ( 0 << 31     |    // Reserved
  485.                         0 << 21     |    // SATB1 (10 bits, default 8, optimized value 0)
  486.                         31 << 14    |    // SATP3
  487.                         31 << 7     |    // SATP2 (default 6, optimized 31)
  488.                         108 );           // SATP1 (7 bits, default 6, optimized value 108)
  489.  
  490.         //DWord 16
  491.         *p_table ++ = ( 0 << 31   |    // Reserved
  492.                         721 << 20 |    // SATS0 (default 297, optimized 721)
  493.                         124 << 10 |    // SATB3
  494.                         124 );         // SATB2
  495.  
  496.         //DWord 17
  497.         *p_table ++ = ( 0 << 22   |    // Reserved
  498.                         256 << 11 |    // SATS2 (default 297, optimized 256)
  499.                         156 );         // SATS1 (default 176, optimized 156)
  500.  
  501.         //DWord 18
  502.         *p_table ++ = ( 14 << 25    |    // HUEP3
  503.                         14 << 18    |    // HUEP2
  504.                         14 << 11    |    // HUEP1 (7 bits, default value -6 = 7Ah, optimized value 14)
  505.                         256 );           // SATS3
  506.  
  507.         //DWord 19
  508.         *p_table ++ = ( 0 << 30   |    // Reserved
  509.                         56 << 20  |    // HUEB3
  510.                         56 << 10  |    // HUEB2
  511.                         56 );          // HUEB1 (10 bits, default value 8, optimized value 56)
  512.  
  513.         //DWord 20
  514.         *p_table ++ = ( 0 << 22   |    // Reserved
  515.                         256 << 11 |    // HUES1
  516.                         256 );         // HUES0
  517.  
  518.         //DWord 21
  519.         *p_table ++ = ( 0 << 22   |    // Reserved
  520.                         256 << 11 |    // HUES3
  521.                         256 );         // HUES2
  522.  
  523.         //DWord 22
  524.         *p_table ++ = ( 0 << 31   |    // Reserved
  525.                         0 << 21   |    // SATB1_DARK
  526.                         31 << 14  |    // SATP3_DARK
  527.                         31 << 7   |    // SATP2_DARK
  528.                         123 );         // SATP1_DARK (7 bits, default value -11 = FF5h, optimized value 123)
  529.  
  530.         //DWord 23
  531.         *p_table ++ = ( 0 << 31   |    // Reserved
  532.                         305 << 20 |    // SATS0_DARK
  533.                         124 << 10 |    // SATB3_DARK
  534.                         124 );         // SATB2_DARK
  535.  
  536.         //DWord 24
  537.         *p_table ++ = ( 0 << 22   |    // Reserved
  538.                         256 << 11 |    // SATS2_DARK
  539.                         220 );         // SATS1_DARK
  540.  
  541.         //DWord 25
  542.         *p_table ++ = ( 14 << 25  |    // HUEP3_DARK
  543.                         14 << 18  |    // HUEP2_DARK
  544.                         14 << 11  |    // HUEP1_DARK
  545.                         256 );         // SATS3_DARK
  546.  
  547.         //DWord 26
  548.         *p_table ++ = ( 0 << 30   |    // Reserved
  549.                         56 << 20  |    // HUEB3_DARK
  550.                         56 << 10  |    // HUEB2_DARK
  551.                         56 );          // HUEB1_DARK
  552.  
  553.         //DWord 27
  554.         *p_table ++ = ( 0 << 22   |    // Reserved
  555.                         256 << 11 |    // HUES1_DARK
  556.                         256 );         // HUES0_DARK
  557.  
  558.         //DWord 28
  559.         *p_table ++ = ( 0 << 22   |    // Reserved
  560.                         256 << 11 |    // HUES3_DARK
  561.                         256 );         // HUES2_DARK
  562. }
  563.  
  564.  
  565. void hsw_veb_iecp_std_table(VADriverContextP ctx, struct intel_vebox_context *proc_ctx)
  566. {
  567.     unsigned int *p_table = proc_ctx->iecp_state_table.ptr + 0 ;
  568.  
  569.     if(!(proc_ctx->filters_mask & VPP_IECP_STD_STE)){
  570.         memset(p_table, 0, 29 * 4);
  571.     }else{
  572.         int stde_factor = 0; //default value
  573.         VAProcFilterParameterBuffer * std_param = (VAProcFilterParameterBuffer *) proc_ctx->filter_iecp_std;
  574.         stde_factor = std_param->value;
  575.  
  576.         //DWord 0
  577.         *p_table ++ = ( 154 << 24 |   // V_Mid
  578.                         110 << 16 |   // U_Mid
  579.                         14 << 10  |   // Hue_Max
  580.                         31 << 4   |   // Sat_Max
  581.                         0 << 3    |   // Reserved
  582.                         0 << 2    |   // Output Control is set to output the 1=STD score /0=Output Pixels
  583.                         1 << 1    |   // Set STE Enable
  584.                         1 );          // Set STD Enable
  585.  
  586.         //DWord 1
  587.         *p_table ++ = ( 0 << 31   |   // Reserved
  588.                         4 << 28   |   // Diamond Margin
  589.                         0 << 21   |   // Diamond_du
  590.                         3 << 18   |   // HS_Margin
  591.                         79 << 10  |   // Cos(alpha)
  592.                         0 << 8    |   // Reserved
  593.                         101 );        // Sin(alpha)
  594.  
  595.         //DWord 2
  596.         *p_table ++ = ( 0 << 21   |   // Reserved
  597.                         100 << 13 |   // Diamond_alpha
  598.                         35 << 7   |   // Diamond_Th
  599.                         0 );
  600.  
  601.         //DWord 3
  602.         *p_table ++ = ( 254 << 24 |   // Y_point_3
  603.                         47 << 16  |   // Y_point_2
  604.                         46 << 8   |   // Y_point_1
  605.                         1 << 7    |   // VY_STD_Enable
  606.                         0 );          // Reserved
  607.  
  608.         //DWord 4
  609.         *p_table ++ = ( 0 << 18   |   // Reserved
  610.                         31 << 13  |   // Y_slope_2
  611.                         31 << 8   |   // Y_slope_1
  612.                         255 );        // Y_point_4
  613.  
  614.         //DWord 5
  615.         *p_table ++ = ( 400 << 16 |   // INV_Skin_types_margin = 20* Skin_Type_margin => 20*20
  616.                         3300 );       // INV_Margin_VYL => 1/Margin_VYL
  617.  
  618.         //DWord 6
  619.         *p_table ++ = ( 216 << 24 |   // P1L
  620.                         46 << 16  |   // P0L
  621.                         1600 );       // INV_Margin_VYU
  622.  
  623.         //DWord 7
  624.         *p_table ++ = ( 130 << 24 |   // B1L
  625.                         133 << 16 |   // B0L
  626.                         236 << 8  |   // P3L
  627.                         236 );        // P2L
  628.  
  629.         //DWord 8
  630.         *p_table ++ = ( 0 << 27      |   // Reserved
  631.                         0x7FB << 16  |   // S0L (11 bits, Default value: -5 = FBh, pad it with 1s to make it 11bits)
  632.                         130 << 8     |   // B3L
  633.                         130 );
  634.  
  635.         //DWord 9
  636.         *p_table ++ = ( 0 << 22   |    // Reserved
  637.                         0 << 11   |    // S2L
  638.                         0);            // S1L
  639.  
  640.         //DWord 10
  641.         *p_table ++ = ( 0 << 27   |    // Reserved
  642.                         66 << 19  |    // P1U
  643.                         46 << 11  |    // P0U
  644.                         0 );           // S3
  645.  
  646.         //DWord 11
  647.         *p_table ++ = ( 163 << 24 |    // B1U
  648.                         143 << 16 |    // B0U
  649.                         236 << 8  |    // P3U
  650.                         150 );         // P2U
  651.  
  652.         //DWord 12
  653.         *p_table ++ = ( 0 << 27   |    // Reserved
  654.                         256 << 16 |    // S0U
  655.                         200 << 8  |    // B3U
  656.                         200 );         // B2U
  657.  
  658.         //DWord 13
  659.         *p_table ++ = ( 0 << 22     |    // Reserved
  660.                         0x74D << 11 |    // S2U (11 bits, Default value -179 = F4Dh)
  661.                         113 );           // S1U
  662.  
  663.         //DWoord 14
  664.         *p_table ++ = ( 0 << 28   |    // Reserved
  665.                         20 << 20  |    // Skin_types_margin
  666.                         120 << 12 |    // Skin_types_thresh
  667.                         1 << 11   |    // Skin_Types_Enable
  668.                         0 );           // S3U
  669.  
  670.         //Set DWord 15 through DWord 28 in their respective methods.
  671.         switch(stde_factor) {
  672.             case 3:
  673.                 set_std_table_3(proc_ctx, p_table);
  674.                 break;
  675.  
  676.             case 6:
  677.                 set_std_table_6(proc_ctx, p_table);
  678.                 break;
  679.  
  680.             case 9:
  681.                 set_std_table_9(proc_ctx, p_table);
  682.                 break;
  683.  
  684.             default:
  685.                 set_std_table_default(proc_ctx, p_table);
  686.                 break;
  687.         }
  688.     }//end of else
  689. }
  690.  
  691. void hsw_veb_iecp_ace_table(VADriverContextP ctx, struct intel_vebox_context *proc_ctx)
  692. {
  693.    unsigned int *p_table = (unsigned int*)(proc_ctx->iecp_state_table.ptr + 116);
  694.  
  695.     if(!(proc_ctx->filters_mask & VPP_IECP_ACE)){
  696.         memset(p_table, 0, 13 * 4);
  697.     }else{
  698.         *p_table ++ = 0x00000068;
  699.         *p_table ++ = 0x4c382410;
  700.         *p_table ++ = 0x9c887460;
  701.         *p_table ++ = 0xebd8c4b0;
  702.         *p_table ++ = 0x604c3824;
  703.  
  704.         *p_table ++ = 0xb09c8874;
  705.         *p_table ++ = 0x0000d8c4;
  706.         *p_table ++ = 0x00000000;
  707.         *p_table ++ = 0x00000000;
  708.         *p_table ++ = 0x00000000;
  709.  
  710.         *p_table ++ = 0x00000000;
  711.         *p_table ++ = 0x00000000;
  712.         *p_table ++ = 0x00000000;
  713.    }
  714. }
  715.  
  716. void hsw_veb_iecp_tcc_table(VADriverContextP ctx, struct intel_vebox_context *proc_ctx)
  717. {
  718.     unsigned int *p_table = (unsigned int*)(proc_ctx->iecp_state_table.ptr + 168);
  719. //    VAProcFilterParameterBuffer * tcc_param =
  720. //            (VAProcFilterParameterBuffer *) proc_ctx->filter_iecp_tcc;
  721.  
  722.    if(!(proc_ctx->filters_mask & VPP_IECP_TCC)){
  723.         memset(p_table, 0, 11 * 4);
  724.     }else{
  725.         *p_table ++ = 0x00000000;
  726.         *p_table ++ = 0x00000000;
  727.         *p_table ++ = 0x1e34cc91;
  728.         *p_table ++ = 0x3e3cce91;
  729.         *p_table ++ = 0x02e80195;
  730.  
  731.         *p_table ++ = 0x0197046b;
  732.         *p_table ++ = 0x01790174;
  733.         *p_table ++ = 0x00000000;
  734.         *p_table ++ = 0x00000000;
  735.         *p_table ++ = 0x03030000;
  736.  
  737.         *p_table ++ = 0x009201c0;
  738.    }
  739. }
  740.  
  741. void hsw_veb_iecp_pro_amp_table(VADriverContextP ctx, struct intel_vebox_context *proc_ctx)
  742. {
  743.     unsigned int contrast = 0x80;  //default
  744.     int brightness = 0x00;         //default
  745.     int cos_c_s    = 256 ;         //default
  746.     int sin_c_s    = 0;            //default
  747.     unsigned int *p_table = (unsigned int*)(proc_ctx->iecp_state_table.ptr + 212);
  748.  
  749.     if(!(proc_ctx->filters_mask & VPP_IECP_PRO_AMP)){
  750.         memset(p_table, 0, 2 * 4);
  751.     }else {
  752.         float  src_saturation = 1.0;
  753.         float  src_hue = 0.0;
  754.         float  src_contrast = 1.0;
  755.         float  src_brightness = 0.0;
  756.         float  tmp_value = 0.0;
  757.         unsigned int i = 0;
  758.  
  759.         VAProcFilterParameterBufferColorBalance * amp_params =
  760.             (VAProcFilterParameterBufferColorBalance *) proc_ctx->filter_iecp_amp;
  761.  
  762.         for (i = 0; i < proc_ctx->filter_iecp_amp_num_elements; i++){
  763.             VAProcColorBalanceType attrib = amp_params[i].attrib;
  764.  
  765.             if(attrib == VAProcColorBalanceHue) {
  766.                src_hue = amp_params[i].value;         //(-180.0, 180.0)
  767.             }else if(attrib == VAProcColorBalanceSaturation) {
  768.                src_saturation = amp_params[i].value; //(0.0, 10.0)
  769.             }else if(attrib == VAProcColorBalanceBrightness) {
  770.                src_brightness = amp_params[i].value; // (-100.0, 100.0)
  771.                brightness = intel_format_convert(src_brightness, 7, 4, 1);
  772.             }else if(attrib == VAProcColorBalanceContrast) {
  773.                src_contrast = amp_params[i].value;  //  (0.0, 10.0)
  774.                contrast = intel_format_convert(src_contrast, 4, 7, 0);
  775.             }
  776.         }
  777.  
  778.         tmp_value = cos(src_hue/180*PI) * src_contrast * src_saturation;
  779.         cos_c_s = intel_format_convert(tmp_value, 7, 8, 1);
  780.        
  781.         tmp_value = sin(src_hue/180*PI) * src_contrast * src_saturation;
  782.         sin_c_s = intel_format_convert(tmp_value, 7, 8, 1);
  783.      
  784.         *p_table ++ = ( 0 << 28 |         //reserved
  785.                         contrast << 17 |  //contrast value (U4.7 format)
  786.                         0 << 13 |         //reserved
  787.                         brightness << 1|  // S7.4 format
  788.                         1);
  789.  
  790.         *p_table ++ = ( cos_c_s << 16 |  // cos(h) * contrast * saturation
  791.                         sin_c_s);        // sin(h) * contrast * saturation
  792.                  
  793.     }
  794. }
  795.  
  796.  
  797. void hsw_veb_iecp_csc_table(VADriverContextP ctx, struct intel_vebox_context *proc_ctx)
  798. {
  799.     unsigned int *p_table = (unsigned int*)(proc_ctx->iecp_state_table.ptr + 220);
  800.     float tran_coef[9] = {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0};
  801.     float v_coef[3]    = {0.0, 0.0, 0.0};
  802.     float u_coef[3]    = {0.0, 0.0, 0.0};
  803.     int   is_transform_enabled = 0;
  804.  
  805.     if(!(proc_ctx->filters_mask & VPP_IECP_CSC)){
  806.         memset(p_table, 0, 8 * 4);
  807.         return;
  808.     }
  809.  
  810.     if(proc_ctx->fourcc_input == VA_FOURCC_RGBA &&
  811.        (proc_ctx->fourcc_output == VA_FOURCC_NV12 ||
  812.         proc_ctx->fourcc_output == VA_FOURCC_YV12 ||
  813.         proc_ctx->fourcc_output == VA_FOURCC_YVY2 ||
  814.         proc_ctx->fourcc_output == VA_FOURCC_AYUV)) {
  815.  
  816.          tran_coef[0] = 0.257;
  817.          tran_coef[1] = 0.504;
  818.          tran_coef[2] = 0.098;
  819.          tran_coef[3] = -0.148;
  820.          tran_coef[4] = -0.291;
  821.          tran_coef[5] = 0.439;
  822.          tran_coef[6] = 0.439;
  823.          tran_coef[7] = -0.368;
  824.          tran_coef[8] = -0.071;
  825.  
  826.          u_coef[0] = 16 * 4;
  827.          u_coef[1] = 128 * 4;
  828.          u_coef[2] = 128 * 4;
  829.  
  830.          is_transform_enabled = 1;
  831.     }else if((proc_ctx->fourcc_input  == VA_FOURCC_NV12 ||
  832.               proc_ctx->fourcc_input  == VA_FOURCC_YV12 ||
  833.               proc_ctx->fourcc_input  == VA_FOURCC_YUY2 ||
  834.               proc_ctx->fourcc_input  == VA_FOURCC_AYUV) &&
  835.               proc_ctx->fourcc_output == VA_FOURCC_RGBA) {
  836.          tran_coef[0] = 1.164;
  837.          tran_coef[1] = 0.000;
  838.          tran_coef[2] = 1.569;
  839.          tran_coef[3] = 1.164;
  840.          tran_coef[4] = -0.813;
  841.          tran_coef[5] = -0.392;
  842.          tran_coef[6] = 1.164;
  843.          tran_coef[7] = 2.017;
  844.          tran_coef[8] = 0.000;
  845.  
  846.          v_coef[0] = -16 * 4;
  847.          v_coef[1] = -128 * 4;
  848.          v_coef[2] = -128 * 4;
  849.  
  850.         is_transform_enabled = 1;
  851.     }else if(proc_ctx->fourcc_input != proc_ctx->fourcc_output){
  852.          //enable when input and output format are different.
  853.          is_transform_enabled = 1;
  854.     }
  855.  
  856.     if(is_transform_enabled == 0){
  857.         memset(p_table, 0, 8 * 4);
  858.     }else{
  859.         *p_table ++ = ( 0 << 29 | //reserved
  860.                         intel_format_convert(tran_coef[1], 2, 10, 1) << 16 | //c1, s2.10 format
  861.                         intel_format_convert(tran_coef[0], 2, 10, 1) << 3 |  //c0, s2.10 format
  862.                         0 << 2 | //reserved
  863.                         0 << 1 | // yuv_channel swap
  864.                         is_transform_enabled);                
  865.  
  866.         *p_table ++ = ( 0 << 26 | //reserved
  867.                         intel_format_convert(tran_coef[3], 2, 10, 1) << 13 |
  868.                         intel_format_convert(tran_coef[2], 2, 10, 1));
  869.    
  870.         *p_table ++ = ( 0 << 26 | //reserved
  871.                         intel_format_convert(tran_coef[5], 2, 10, 1) << 13 |
  872.                         intel_format_convert(tran_coef[4], 2, 10, 1));
  873.  
  874.         *p_table ++ = ( 0 << 26 | //reserved
  875.                         intel_format_convert(tran_coef[7], 2, 10, 1) << 13 |
  876.                         intel_format_convert(tran_coef[6], 2, 10, 1));
  877.  
  878.         *p_table ++ = ( 0 << 13 | //reserved
  879.                         intel_format_convert(tran_coef[8], 2, 10, 1));
  880.  
  881.         *p_table ++ = ( 0 << 22 | //reserved
  882.                         intel_format_convert(u_coef[0], 10, 0, 1) << 11 |
  883.                         intel_format_convert(v_coef[0], 10, 0, 1));
  884.  
  885.         *p_table ++ = ( 0 << 22 | //reserved
  886.                         intel_format_convert(u_coef[1], 10, 0, 1) << 11 |
  887.                         intel_format_convert(v_coef[1], 10, 0, 1));
  888.  
  889.         *p_table ++ = ( 0 << 22 | //reserved
  890.                         intel_format_convert(u_coef[2], 10, 0, 1) << 11 |
  891.                         intel_format_convert(v_coef[2], 10, 0, 1));
  892.     }
  893. }
  894.  
  895. void hsw_veb_iecp_aoi_table(VADriverContextP ctx, struct intel_vebox_context *proc_ctx)
  896. {
  897.     unsigned int *p_table = (unsigned int*)(proc_ctx->iecp_state_table.ptr + 252);
  898.    // VAProcFilterParameterBuffer * tcc_param =
  899.    //         (VAProcFilterParameterBuffer *) proc_ctx->filter_iecp_tcc;
  900.  
  901.     if(!(proc_ctx->filters_mask & VPP_IECP_AOI)){
  902.         memset(p_table, 0, 3 * 4);
  903.     }else{
  904.         *p_table ++ = 0x00000000;
  905.         *p_table ++ = 0x00030000;
  906.         *p_table ++ = 0x00030000;
  907.    }
  908. }
  909.  
  910. void hsw_veb_state_table_setup(VADriverContextP ctx, struct intel_vebox_context *proc_ctx)
  911. {
  912.     if(proc_ctx->filters_mask & VPP_DNDI_MASK) {
  913.         dri_bo *dndi_bo = proc_ctx->dndi_state_table.bo;
  914.         dri_bo_map(dndi_bo, 1);
  915.         proc_ctx->dndi_state_table.ptr = dndi_bo->virtual;
  916.  
  917.         hsw_veb_dndi_table(ctx, proc_ctx);
  918.  
  919.         dri_bo_unmap(dndi_bo);
  920.     }
  921.  
  922.     if(proc_ctx->filters_mask & VPP_IECP_MASK) {
  923.         dri_bo *iecp_bo = proc_ctx->iecp_state_table.bo;
  924.         dri_bo_map(iecp_bo, 1);
  925.         proc_ctx->iecp_state_table.ptr = iecp_bo->virtual;
  926.  
  927.         hsw_veb_iecp_std_table(ctx, proc_ctx);
  928.         hsw_veb_iecp_ace_table(ctx, proc_ctx);
  929.         hsw_veb_iecp_tcc_table(ctx, proc_ctx);
  930.         hsw_veb_iecp_pro_amp_table(ctx, proc_ctx);
  931.         hsw_veb_iecp_csc_table(ctx, proc_ctx);
  932.         hsw_veb_iecp_aoi_table(ctx, proc_ctx);
  933.    
  934.         dri_bo_unmap(iecp_bo);
  935.     }
  936. }
  937.  
  938. void hsw_veb_state_command(VADriverContextP ctx, struct intel_vebox_context *proc_ctx)
  939. {
  940.     struct intel_batchbuffer *batch = proc_ctx->batch;
  941.  
  942.     BEGIN_VEB_BATCH(batch, 6);
  943.     OUT_VEB_BATCH(batch, VEB_STATE | (6 - 2));
  944.     OUT_VEB_BATCH(batch,
  945.                   0 << 26 |       // state surface control bits
  946.                   0 << 11 |       // reserved.
  947.                   0 << 10 |       // pipe sync disable
  948.                   proc_ctx->current_output_type << 8  | // DI output frame
  949.                   1 << 7  |       // 444->422 downsample method
  950.                   1 << 6  |       // 422->420 downsample method
  951.                   proc_ctx->is_first_frame  << 5  |   // DN/DI first frame
  952.                   proc_ctx->is_di_enabled   << 4  |   // DI enable
  953.                   proc_ctx->is_dn_enabled   << 3  |   // DN enable
  954.                   proc_ctx->is_iecp_enabled << 2  |   // global IECP enabled
  955.                   0 << 1  |       // ColorGamutCompressionEnable
  956.                   0 ) ;           // ColorGamutExpansionEnable.
  957.  
  958.     OUT_RELOC(batch,
  959.               proc_ctx->dndi_state_table.bo,
  960.               I915_GEM_DOMAIN_INSTRUCTION, 0, 0);
  961.  
  962.     OUT_RELOC(batch,
  963.               proc_ctx->iecp_state_table.bo,
  964.               I915_GEM_DOMAIN_INSTRUCTION, 0, 0);
  965.  
  966.     OUT_RELOC(batch,
  967.               proc_ctx->gamut_state_table.bo,
  968.               I915_GEM_DOMAIN_INSTRUCTION, 0, 0);
  969.  
  970.     OUT_RELOC(batch,
  971.               proc_ctx->vertex_state_table.bo,
  972.               I915_GEM_DOMAIN_INSTRUCTION, 0, 0);
  973.  
  974.     ADVANCE_VEB_BATCH(batch);
  975. }
  976.  
  977. void hsw_veb_surface_state(VADriverContextP ctx, struct intel_vebox_context *proc_ctx, unsigned int is_output)
  978. {
  979.     struct intel_batchbuffer *batch = proc_ctx->batch;
  980.     unsigned int u_offset_y = 0, v_offset_y = 0;
  981.     unsigned int is_uv_interleaved = 0, tiling = 0, swizzle = 0;
  982.     unsigned int surface_format = PLANAR_420_8;
  983.     struct object_surface* obj_surf = NULL;
  984.     unsigned int surface_pitch = 0;
  985.     unsigned int half_pitch_chroma = 0;
  986.  
  987.     if(is_output){  
  988.         obj_surf = proc_ctx->frame_store[FRAME_OUT_CURRENT].obj_surface;
  989.     }else {
  990.         obj_surf = proc_ctx->frame_store[FRAME_IN_CURRENT].obj_surface;
  991.     }
  992.  
  993.     assert(obj_surf->fourcc == VA_FOURCC_NV12 ||
  994.            obj_surf->fourcc == VA_FOURCC_YUY2 ||
  995.            obj_surf->fourcc == VA_FOURCC_AYUV ||
  996.            obj_surf->fourcc == VA_FOURCC_RGBA);
  997.  
  998.     if (obj_surf->fourcc == VA_FOURCC_NV12) {
  999.         surface_format = PLANAR_420_8;
  1000.         surface_pitch = obj_surf->width;
  1001.         is_uv_interleaved = 1;
  1002.         half_pitch_chroma = 0;
  1003.     } else if (obj_surf->fourcc == VA_FOURCC_YUY2) {
  1004.         surface_format = YCRCB_NORMAL;
  1005.         surface_pitch = obj_surf->width * 2;
  1006.         is_uv_interleaved = 0;
  1007.         half_pitch_chroma = 0;
  1008.     } else if (obj_surf->fourcc == VA_FOURCC_AYUV) {
  1009.         surface_format = PACKED_444A_8;
  1010.         surface_pitch = obj_surf->width * 4;
  1011.         is_uv_interleaved = 0;
  1012.         half_pitch_chroma = 0;
  1013.     } else if (obj_surf->fourcc == VA_FOURCC_RGBA) {
  1014.         surface_format = R8G8B8A8_UNORM_SRGB;
  1015.         surface_pitch = obj_surf->width * 4;
  1016.         is_uv_interleaved = 0;
  1017.         half_pitch_chroma = 0;
  1018.     }
  1019.  
  1020.     u_offset_y = obj_surf->y_cb_offset;
  1021.     v_offset_y = obj_surf->y_cr_offset;
  1022.      
  1023.     dri_bo_get_tiling(obj_surf->bo, &tiling, &swizzle);
  1024.  
  1025.     BEGIN_VEB_BATCH(batch, 6);
  1026.     OUT_VEB_BATCH(batch, VEB_SURFACE_STATE | (6 - 2));
  1027.     OUT_VEB_BATCH(batch,
  1028.                   0 << 1 |         // reserved
  1029.                   is_output);      // surface indentification.
  1030.  
  1031.     OUT_VEB_BATCH(batch,
  1032.                   (obj_surf->height - 1) << 18 |  // height . w3
  1033.                   (obj_surf->width -1 )  << 4  |  // width
  1034.                   0);                             // reserve
  1035.  
  1036.     OUT_VEB_BATCH(batch,
  1037.                   surface_format      << 28  |  // surface format, YCbCr420. w4
  1038.                   is_uv_interleaved   << 27  |  // interleave chrome , two seperate palar
  1039.                   0                   << 20  |  // reserved
  1040.                   (surface_pitch - 1) << 3   |  // surface pitch, 64 align
  1041.                   half_pitch_chroma   << 2   |  // half pitch for chrome
  1042.                   !!tiling            << 1   |  // tiled surface, linear surface used
  1043.                   (tiling == I915_TILING_Y));   // tiled walk, ignored when liner surface
  1044.  
  1045.     OUT_VEB_BATCH(batch,
  1046.                   0 << 29  |     // reserved . w5
  1047.                   0 << 16  |     // X offset for V(Cb)
  1048.                   0 << 15  |     // reserved
  1049.                   u_offset_y);   // Y offset for V(Cb)
  1050.  
  1051.     OUT_VEB_BATCH(batch,
  1052.                   0 << 29  |     // reserved . w6
  1053.                   0 << 16  |     // X offset for V(Cr)
  1054.                   0 << 15  |     // reserved
  1055.                   v_offset_y );  // Y offset for V(Cr)
  1056.  
  1057.     ADVANCE_VEB_BATCH(batch);
  1058. }
  1059.  
  1060. void hsw_veb_dndi_iecp_command(VADriverContextP ctx, struct intel_vebox_context *proc_ctx)
  1061. {
  1062.     struct intel_batchbuffer *batch = proc_ctx->batch;
  1063.     unsigned char frame_ctrl_bits = 0;
  1064.     const unsigned int width64 = ALIGN(proc_ctx->width_input, 64);
  1065.  
  1066.     /* s1:update the previous and current input */
  1067. /*    tempFrame = proc_ctx->frame_store[FRAME_IN_PREVIOUS];
  1068.     proc_ctx->frame_store[FRAME_IN_PREVIOUS] = proc_ctx->frame_store[FRAME_IN_CURRENT]; ;
  1069.     proc_ctx->frame_store[FRAME_IN_CURRENT] = tempFrame;
  1070.  
  1071.     if(proc_ctx->surface_input_vebox != -1){
  1072.         vpp_surface_copy(ctx, proc_ctx->frame_store[FRAME_IN_CURRENT].surface_id,
  1073.                      proc_ctx->surface_input_vebox);
  1074.     } else {
  1075.         vpp_surface_copy(ctx, proc_ctx->frame_store[FRAME_IN_CURRENT].surface_id,
  1076.                      proc_ctx->surface_input);
  1077.     }
  1078. */
  1079.     /*s2: update the STMM input and output */
  1080. /*    tempFrame = proc_ctx->frame_store[FRAME_IN_STMM];
  1081.     proc_ctx->frame_store[FRAME_IN_STMM] = proc_ctx->frame_store[FRAME_OUT_STMM]; ;
  1082.     proc_ctx->frame_store[FRAME_OUT_STMM] = tempFrame;
  1083. */     
  1084.     /*s3:set reloc buffer address */
  1085.     BEGIN_VEB_BATCH(batch, 10);
  1086.     OUT_VEB_BATCH(batch, VEB_DNDI_IECP_STATE | (10 - 2));
  1087.     OUT_VEB_BATCH(batch, (width64 - 1));
  1088.     OUT_RELOC(batch,
  1089.               proc_ctx->frame_store[FRAME_IN_CURRENT].obj_surface->bo,
  1090.               I915_GEM_DOMAIN_RENDER, 0, frame_ctrl_bits);
  1091.     OUT_RELOC(batch,
  1092.               proc_ctx->frame_store[FRAME_IN_PREVIOUS].obj_surface->bo,
  1093.               I915_GEM_DOMAIN_RENDER, 0, frame_ctrl_bits);
  1094.     OUT_RELOC(batch,
  1095.               proc_ctx->frame_store[FRAME_IN_STMM].obj_surface->bo,
  1096.               I915_GEM_DOMAIN_RENDER, 0, frame_ctrl_bits);
  1097.     OUT_RELOC(batch,
  1098.               proc_ctx->frame_store[FRAME_OUT_STMM].obj_surface->bo,
  1099.               I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, frame_ctrl_bits);
  1100.     OUT_RELOC(batch,
  1101.               proc_ctx->frame_store[FRAME_OUT_CURRENT_DN].obj_surface->bo,
  1102.               I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, frame_ctrl_bits);
  1103.     OUT_RELOC(batch,
  1104.               proc_ctx->frame_store[FRAME_OUT_CURRENT].obj_surface->bo,
  1105.               I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, frame_ctrl_bits);
  1106.     OUT_RELOC(batch,
  1107.               proc_ctx->frame_store[FRAME_OUT_PREVIOUS].obj_surface->bo,
  1108.               I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, frame_ctrl_bits);
  1109.     OUT_RELOC(batch,
  1110.               proc_ctx->frame_store[FRAME_OUT_STATISTIC].obj_surface->bo,
  1111.               I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, frame_ctrl_bits);
  1112.  
  1113.     ADVANCE_VEB_BATCH(batch);
  1114. }
  1115.  
  1116. static void
  1117. frame_store_reset(VEBFrameStore *fs)
  1118. {
  1119.     fs->obj_surface = NULL;
  1120.     fs->surface_id = VA_INVALID_ID;
  1121.     fs->is_internal_surface = 0;
  1122.     fs->is_scratch_surface = 0;
  1123. }
  1124.  
  1125. static void
  1126. frame_store_clear(VEBFrameStore *fs, VADriverContextP ctx)
  1127. {
  1128.     if (fs->obj_surface && fs->is_scratch_surface) {
  1129.         VASurfaceID surface_id = fs->obj_surface->base.id;
  1130.         i965_DestroySurfaces(ctx, &surface_id, 1);
  1131.     }
  1132.     frame_store_reset(fs);
  1133. }
  1134.  
  1135. static VAStatus
  1136. gen75_vebox_ensure_surfaces_storage(VADriverContextP ctx,
  1137.     struct intel_vebox_context *proc_ctx)
  1138. {
  1139.     struct i965_driver_data * const i965 = i965_driver_data(ctx);
  1140.     struct object_surface *input_obj_surface, *output_obj_surface;
  1141.     unsigned int input_fourcc, output_fourcc;
  1142.     unsigned int input_sampling, output_sampling;
  1143.     unsigned int input_tiling, output_tiling;
  1144.     unsigned int i, swizzle;
  1145.     drm_intel_bo *bo;
  1146.     VAStatus status;
  1147.  
  1148.     /* Determine input surface info. Use native VEBOX format whenever
  1149.        possible. i.e. when the input surface format is not supported
  1150.        by the VEBOX engine, then allocate a temporary surface (live
  1151.        during the whole VPP pipeline lifetime)
  1152.  
  1153.        XXX: derive an actual surface format compatible with the input
  1154.        surface chroma format */
  1155.     input_obj_surface = proc_ctx->surface_input_vebox_object ?
  1156.         proc_ctx->surface_input_vebox_object : proc_ctx->surface_input_object;
  1157.     if (input_obj_surface->bo) {
  1158.         input_fourcc = input_obj_surface->fourcc;
  1159.         input_sampling = input_obj_surface->subsampling;
  1160.         dri_bo_get_tiling(input_obj_surface->bo, &input_tiling, &swizzle);
  1161.         input_tiling = !!input_tiling;
  1162.     }
  1163.     else {
  1164.         input_fourcc = VA_FOURCC_NV12;
  1165.         input_sampling = SUBSAMPLE_YUV420;
  1166.         input_tiling = 1;
  1167.         status = i965_check_alloc_surface_bo(ctx, input_obj_surface,
  1168.             input_tiling, input_fourcc, input_sampling);
  1169.         if (status != VA_STATUS_SUCCESS)
  1170.             return status;
  1171.     }
  1172.  
  1173.     /* Determine output surface info.
  1174.  
  1175.        XXX: derive an actual surface format compatible with the input
  1176.        surface chroma format */
  1177.     output_obj_surface = proc_ctx->surface_output_vebox_object ?
  1178.         proc_ctx->surface_output_vebox_object : proc_ctx->surface_output_object;
  1179.     if (output_obj_surface->bo) {
  1180.         output_fourcc   = output_obj_surface->fourcc;
  1181.         output_sampling = output_obj_surface->subsampling;
  1182.         dri_bo_get_tiling(output_obj_surface->bo, &output_tiling, &swizzle);
  1183.         output_tiling = !!output_tiling;
  1184.     }
  1185.     else {
  1186.         output_fourcc = VA_FOURCC_NV12;
  1187.         output_sampling = SUBSAMPLE_YUV420;
  1188.         output_tiling = 1;
  1189.         status = i965_check_alloc_surface_bo(ctx, output_obj_surface,
  1190.             output_tiling, output_fourcc, output_sampling);
  1191.         if (status != VA_STATUS_SUCCESS)
  1192.             return status;
  1193.     }
  1194.  
  1195.     /* Update VEBOX pipeline formats */
  1196.     proc_ctx->fourcc_input = input_fourcc;
  1197.     proc_ctx->fourcc_output = output_fourcc;
  1198.     if (input_fourcc != output_fourcc)
  1199.         proc_ctx->is_iecp_enabled = 1; // IECP needed for format conversion
  1200.    
  1201.     /* Create pipeline surfaces */
  1202.     for (i = 0; i < ARRAY_ELEMS(proc_ctx->frame_store); i ++) {
  1203.         struct object_surface *obj_surface;
  1204.         VASurfaceID new_surface;
  1205.  
  1206.         if (proc_ctx->frame_store[i].obj_surface)
  1207.             continue; // user allocated surface, not VEBOX internal
  1208.  
  1209.         status = i965_CreateSurfaces(ctx, proc_ctx->width_input,
  1210.             proc_ctx->height_input, VA_RT_FORMAT_YUV420, 1, &new_surface);
  1211.         if (status != VA_STATUS_SUCCESS)
  1212.             return status;
  1213.  
  1214.         obj_surface = SURFACE(new_surface);
  1215.         assert(obj_surface != NULL);
  1216.  
  1217.         if (i <= FRAME_IN_PREVIOUS || i == FRAME_OUT_CURRENT_DN) {
  1218.             status = i965_check_alloc_surface_bo(ctx, obj_surface,
  1219.                 input_tiling, input_fourcc, input_sampling);
  1220.         }
  1221.         else if (i == FRAME_IN_STMM || i == FRAME_OUT_STMM) {
  1222.             status = i965_check_alloc_surface_bo(ctx, obj_surface,
  1223.                 1, input_fourcc, input_sampling);
  1224.         }
  1225.         else if (i >= FRAME_OUT_CURRENT) {
  1226.             status = i965_check_alloc_surface_bo(ctx, obj_surface,
  1227.                 output_tiling, output_fourcc, output_sampling);
  1228.         }
  1229.         if (status != VA_STATUS_SUCCESS)
  1230.             return status;
  1231.  
  1232.         proc_ctx->frame_store[i].obj_surface = obj_surface;
  1233.         proc_ctx->frame_store[i].is_internal_surface = 1;
  1234.         proc_ctx->frame_store[i].is_scratch_surface = 1;
  1235.     }
  1236.  
  1237.     /* Allocate DNDI state table  */
  1238.     drm_intel_bo_unreference(proc_ctx->dndi_state_table.bo);
  1239.     bo = drm_intel_bo_alloc(i965->intel.bufmgr, "vebox: dndi state Buffer",
  1240.         0x1000, 0x1000);
  1241.     proc_ctx->dndi_state_table.bo = bo;
  1242.     if (!bo)
  1243.         return VA_STATUS_ERROR_ALLOCATION_FAILED;
  1244.  
  1245.     /* Allocate IECP state table  */
  1246.     drm_intel_bo_unreference(proc_ctx->iecp_state_table.bo);
  1247.     bo = drm_intel_bo_alloc(i965->intel.bufmgr, "vebox: iecp state Buffer",
  1248.         0x1000, 0x1000);
  1249.     proc_ctx->iecp_state_table.bo = bo;
  1250.     if (!bo)
  1251.         return VA_STATUS_ERROR_ALLOCATION_FAILED;
  1252.  
  1253.     /* Allocate Gamut state table  */
  1254.     drm_intel_bo_unreference(proc_ctx->gamut_state_table.bo);
  1255.     bo = drm_intel_bo_alloc(i965->intel.bufmgr, "vebox: gamut state Buffer",
  1256.         0x1000, 0x1000);
  1257.     proc_ctx->gamut_state_table.bo = bo;
  1258.     if (!bo)
  1259.         return VA_STATUS_ERROR_ALLOCATION_FAILED;
  1260.  
  1261.     /* Allocate vertex state table  */
  1262.     drm_intel_bo_unreference(proc_ctx->vertex_state_table.bo);
  1263.     bo = drm_intel_bo_alloc(i965->intel.bufmgr, "vebox: vertex state Buffer",
  1264.         0x1000, 0x1000);
  1265.     proc_ctx->vertex_state_table.bo = bo;
  1266.     if (!bo)
  1267.         return VA_STATUS_ERROR_ALLOCATION_FAILED;
  1268.  
  1269.     return VA_STATUS_SUCCESS;
  1270. }
  1271.  
  1272. static VAStatus
  1273. gen75_vebox_ensure_surfaces(VADriverContextP ctx,
  1274.     struct intel_vebox_context *proc_ctx)
  1275. {
  1276.     struct i965_driver_data * const i965 = i965_driver_data(ctx);
  1277.     struct object_surface *obj_surface;
  1278.     VEBFrameStore *ifs, *ofs;
  1279.     bool is_new_frame = 0;
  1280.     int i;
  1281.  
  1282.     /* Update the previous input surface */
  1283.     obj_surface = proc_ctx->surface_input_object;
  1284.  
  1285.     is_new_frame = proc_ctx->frame_store[FRAME_IN_CURRENT].surface_id !=
  1286.         obj_surface->base.id;
  1287.     if (is_new_frame) {
  1288.         ifs = &proc_ctx->frame_store[FRAME_IN_PREVIOUS];
  1289.         ofs = &proc_ctx->frame_store[proc_ctx->is_dn_enabled ?
  1290.             FRAME_OUT_CURRENT_DN : FRAME_IN_CURRENT];
  1291.         do {
  1292.             const VAProcPipelineParameterBuffer * const pipe =
  1293.                 proc_ctx->pipeline_param;
  1294.  
  1295.             if (pipe->num_forward_references < 1)
  1296.                 break;
  1297.             if (pipe->forward_references[0] == VA_INVALID_ID)
  1298.                 break;
  1299.  
  1300.             obj_surface = SURFACE(pipe->forward_references[0]);
  1301.             if (!obj_surface || obj_surface->base.id == ifs->surface_id)
  1302.                 break;
  1303.  
  1304.             frame_store_clear(ifs, ctx);
  1305.             if (obj_surface->base.id == ofs->surface_id) {
  1306.                 *ifs = *ofs;
  1307.                 frame_store_reset(ofs);
  1308.             }
  1309.             else {
  1310.                 ifs->obj_surface = obj_surface;
  1311.                 ifs->surface_id = obj_surface->base.id;
  1312.                 ifs->is_internal_surface = 0;
  1313.                 ifs->is_scratch_surface = 0;
  1314.             }
  1315.         } while (0);
  1316.     }
  1317.  
  1318.     /* Update the input surface */
  1319.     obj_surface = proc_ctx->surface_input_vebox_object ?
  1320.         proc_ctx->surface_input_vebox_object : proc_ctx->surface_input_object;
  1321.  
  1322.     ifs = &proc_ctx->frame_store[FRAME_IN_CURRENT];
  1323.     frame_store_clear(ifs, ctx);
  1324.     ifs->obj_surface = obj_surface;
  1325.     ifs->surface_id = proc_ctx->surface_input_object->base.id;
  1326.     ifs->is_internal_surface = proc_ctx->surface_input_vebox_object != NULL;
  1327.     ifs->is_scratch_surface = 0;
  1328.  
  1329.     /* Update the Spatial Temporal Motion Measure (STMM) surfaces */
  1330.     if (is_new_frame) {
  1331.         const VEBFrameStore tmpfs = proc_ctx->frame_store[FRAME_IN_STMM];
  1332.         proc_ctx->frame_store[FRAME_IN_STMM] =
  1333.             proc_ctx->frame_store[FRAME_OUT_STMM];
  1334.         proc_ctx->frame_store[FRAME_OUT_STMM] = tmpfs;
  1335.     }
  1336.  
  1337.     /* Reset the output surfaces to defaults. i.e. clean from user surfaces */
  1338.     for (i = FRAME_OUT_CURRENT_DN; i <= FRAME_OUT_PREVIOUS; i++) {
  1339.         ofs = &proc_ctx->frame_store[i];
  1340.         if (!ofs->is_scratch_surface)
  1341.             ofs->obj_surface = NULL;
  1342.         ofs->surface_id = proc_ctx->surface_input_object->base.id;
  1343.     }
  1344.  
  1345.     /* Update the output surfaces */
  1346.     obj_surface = proc_ctx->surface_output_vebox_object ?
  1347.         proc_ctx->surface_output_vebox_object : proc_ctx->surface_output_object;
  1348.  
  1349.     proc_ctx->current_output_type = 2;
  1350.     if (proc_ctx->filters_mask == VPP_DNDI_DN && !proc_ctx->is_iecp_enabled)
  1351.         proc_ctx->current_output = FRAME_OUT_CURRENT_DN;
  1352.     else if (proc_ctx->is_di_adv_enabled && !proc_ctx->is_first_frame) {
  1353.         proc_ctx->current_output_type = 0;
  1354.         proc_ctx->current_output = proc_ctx->is_second_field ?
  1355.             FRAME_OUT_CURRENT : FRAME_OUT_PREVIOUS;
  1356.     }
  1357.     else
  1358.         proc_ctx->current_output = FRAME_OUT_CURRENT;
  1359.     ofs = &proc_ctx->frame_store[proc_ctx->current_output];
  1360.     frame_store_clear(ofs, ctx);
  1361.     ofs->obj_surface = obj_surface;
  1362.     ofs->surface_id = proc_ctx->surface_input_object->base.id;
  1363.     ofs->is_internal_surface = proc_ctx->surface_output_vebox_object != NULL;
  1364.     ofs->is_scratch_surface = 0;
  1365.  
  1366.     return VA_STATUS_SUCCESS;
  1367. }
  1368.  
  1369. int hsw_veb_pre_format_convert(VADriverContextP ctx,
  1370.                            struct intel_vebox_context *proc_ctx)
  1371. {
  1372.     VAStatus va_status;
  1373.     struct i965_driver_data *i965 = i965_driver_data(ctx);
  1374.     struct object_surface* obj_surf_input = proc_ctx->surface_input_object;
  1375.     struct object_surface* obj_surf_output = proc_ctx->surface_output_object;
  1376.     struct object_surface* obj_surf_input_vebox;
  1377.     struct object_surface* obj_surf_output_vebox;
  1378.  
  1379.     proc_ctx->format_convert_flags = 0;
  1380.  
  1381.     proc_ctx->width_input   = obj_surf_input->orig_width;
  1382.     proc_ctx->height_input  = obj_surf_input->orig_height;
  1383.     proc_ctx->width_output  = obj_surf_output->orig_width;
  1384.     proc_ctx->height_output = obj_surf_output->orig_height;
  1385.    
  1386.     /* only partial frame is not supported to be processed */
  1387.     /*
  1388.     assert(proc_ctx->width_input   == proc_ctx->pipeline_param->surface_region->width);
  1389.     assert(proc_ctx->height_input  == proc_ctx->pipeline_param->surface_region->height);
  1390.     assert(proc_ctx->width_output  == proc_ctx->pipeline_param->output_region->width);
  1391.     assert(proc_ctx->height_output == proc_ctx->pipeline_param->output_region->height);
  1392.     */
  1393.  
  1394.     if(proc_ctx->width_output  != proc_ctx->width_input ||
  1395.        proc_ctx->height_output != proc_ctx->height_input){
  1396.         proc_ctx->format_convert_flags |= POST_SCALING_CONVERT;
  1397.     }
  1398.  
  1399.      /* convert the following format to NV12 format */
  1400.      if(obj_surf_input->fourcc ==  VA_FOURCC_YV12 ||
  1401.         obj_surf_input->fourcc ==  VA_FOURCC_I420 ||
  1402.         obj_surf_input->fourcc ==  VA_FOURCC_IMC1 ||
  1403.         obj_surf_input->fourcc ==  VA_FOURCC_IMC3 ||
  1404.         obj_surf_input->fourcc ==  VA_FOURCC_RGBA ||
  1405.         obj_surf_input->fourcc ==  VA_FOURCC_BGRA){
  1406.  
  1407.          proc_ctx->format_convert_flags |= PRE_FORMAT_CONVERT;
  1408.  
  1409.       } else if(obj_surf_input->fourcc ==  VA_FOURCC_AYUV ||
  1410.                 obj_surf_input->fourcc ==  VA_FOURCC_YUY2 ||
  1411.                 obj_surf_input->fourcc ==  VA_FOURCC_NV12){
  1412.                 // nothing to do here
  1413.      } else {
  1414.            /* not support other format as input */
  1415.            assert(0);
  1416.      }
  1417.    
  1418.      if (proc_ctx->format_convert_flags & PRE_FORMAT_CONVERT) {
  1419.          if(proc_ctx->surface_input_vebox_object == NULL){
  1420.              va_status = i965_CreateSurfaces(ctx,
  1421.                                             proc_ctx->width_input,
  1422.                                             proc_ctx->height_input,
  1423.                                             VA_RT_FORMAT_YUV420,
  1424.                                             1,
  1425.                                             &(proc_ctx->surface_input_vebox));
  1426.              assert(va_status == VA_STATUS_SUCCESS);
  1427.              obj_surf_input_vebox = SURFACE(proc_ctx->surface_input_vebox);
  1428.              assert(obj_surf_input_vebox);
  1429.  
  1430.              if (obj_surf_input_vebox) {
  1431.                  proc_ctx->surface_input_vebox_object = obj_surf_input_vebox;
  1432.                  i965_check_alloc_surface_bo(ctx, obj_surf_input_vebox, 1, VA_FOURCC_NV12, SUBSAMPLE_YUV420);
  1433.              }
  1434.          }
  1435.        
  1436.          vpp_surface_convert(ctx, proc_ctx->surface_input_object, proc_ctx->surface_input_vebox_object);
  1437.       }
  1438.  
  1439.       /* create one temporary NV12 surfaces for conversion*/
  1440.      if(obj_surf_output->fourcc ==  VA_FOURCC_YV12 ||
  1441.         obj_surf_output->fourcc ==  VA_FOURCC_I420 ||
  1442.         obj_surf_output->fourcc ==  VA_FOURCC_IMC1 ||
  1443.         obj_surf_output->fourcc ==  VA_FOURCC_IMC3 ||
  1444.         obj_surf_output->fourcc ==  VA_FOURCC_RGBA ||
  1445.         obj_surf_output->fourcc ==  VA_FOURCC_BGRA) {
  1446.  
  1447.         proc_ctx->format_convert_flags |= POST_FORMAT_CONVERT;
  1448.     } else if(obj_surf_output->fourcc ==  VA_FOURCC_AYUV ||
  1449.               obj_surf_output->fourcc ==  VA_FOURCC_YUY2 ||
  1450.               obj_surf_output->fourcc ==  VA_FOURCC_NV12){
  1451.               /* Nothing to do here */
  1452.      } else {
  1453.            /* not support other format as input */
  1454.            assert(0);
  1455.      }
  1456.  
  1457.      if(proc_ctx->format_convert_flags & POST_FORMAT_CONVERT ||
  1458.         proc_ctx->format_convert_flags & POST_SCALING_CONVERT){
  1459.        if(proc_ctx->surface_output_vebox_object == NULL){
  1460.              va_status = i965_CreateSurfaces(ctx,
  1461.                                             proc_ctx->width_input,
  1462.                                             proc_ctx->height_input,
  1463.                                             VA_RT_FORMAT_YUV420,
  1464.                                             1,
  1465.                                             &(proc_ctx->surface_output_vebox));
  1466.              assert(va_status == VA_STATUS_SUCCESS);
  1467.              obj_surf_output_vebox = SURFACE(proc_ctx->surface_output_vebox);
  1468.              assert(obj_surf_output_vebox);
  1469.  
  1470.              if (obj_surf_output_vebox) {
  1471.                  proc_ctx->surface_output_vebox_object = obj_surf_output_vebox;
  1472.                  i965_check_alloc_surface_bo(ctx, obj_surf_output_vebox, 1, VA_FOURCC_NV12, SUBSAMPLE_YUV420);
  1473.              }
  1474.        }
  1475.      }  
  1476.  
  1477.      if(proc_ctx->format_convert_flags & POST_SCALING_CONVERT){
  1478.        if(proc_ctx->surface_output_scaled_object == NULL){
  1479.              va_status = i965_CreateSurfaces(ctx,
  1480.                                             proc_ctx->width_output,
  1481.                                             proc_ctx->height_output,
  1482.                                             VA_RT_FORMAT_YUV420,
  1483.                                             1,
  1484.                                             &(proc_ctx->surface_output_scaled));
  1485.              assert(va_status == VA_STATUS_SUCCESS);
  1486.              obj_surf_output_vebox = SURFACE(proc_ctx->surface_output_scaled);
  1487.              assert(obj_surf_output_vebox);
  1488.  
  1489.              if (obj_surf_output_vebox) {
  1490.                  proc_ctx->surface_output_scaled_object = obj_surf_output_vebox;
  1491.                  i965_check_alloc_surface_bo(ctx, obj_surf_output_vebox, 1, VA_FOURCC_NV12, SUBSAMPLE_YUV420);
  1492.              }
  1493.        }
  1494.      }
  1495.    
  1496.      return 0;
  1497. }
  1498.  
  1499. int hsw_veb_post_format_convert(VADriverContextP ctx,
  1500.                            struct intel_vebox_context *proc_ctx)
  1501. {
  1502.     struct object_surface *obj_surface = NULL;
  1503.    
  1504.     obj_surface = proc_ctx->frame_store[proc_ctx->current_output].obj_surface;
  1505.  
  1506.     if (proc_ctx->format_convert_flags & POST_COPY_CONVERT) {
  1507.         /* copy the saved frame in the second call */
  1508.         vpp_surface_convert(ctx, obj_surface, proc_ctx->surface_output_object);
  1509.     } else if(!(proc_ctx->format_convert_flags & POST_FORMAT_CONVERT) &&
  1510.        !(proc_ctx->format_convert_flags & POST_SCALING_CONVERT)){
  1511.         /* Output surface format is covered by vebox pipeline and
  1512.          * processed picture is already store in output surface
  1513.          * so nothing will be done here */
  1514.     } else if ((proc_ctx->format_convert_flags & POST_FORMAT_CONVERT) &&
  1515.                !(proc_ctx->format_convert_flags & POST_SCALING_CONVERT)){
  1516.        /* convert and copy NV12 to YV12/IMC3/IMC2/RGBA output*/
  1517.         vpp_surface_convert(ctx, obj_surface, proc_ctx->surface_output_object);
  1518.  
  1519.     } else if(proc_ctx->format_convert_flags & POST_SCALING_CONVERT) {
  1520.         VAProcPipelineParameterBuffer * const pipe = proc_ctx->pipeline_param;
  1521.        /* scaling, convert and copy NV12 to YV12/IMC3/IMC2/RGBA output*/
  1522.         assert(obj_surface->fourcc == VA_FOURCC_NV12);
  1523.      
  1524.         /* first step :surface scaling */
  1525.         vpp_surface_scaling(ctx, obj_surface,
  1526.             proc_ctx->surface_output_scaled_object, pipe->filter_flags);
  1527.  
  1528.         /* second step: color format convert and copy to output */
  1529.         obj_surface = proc_ctx->surface_output_object;
  1530.  
  1531.         if(obj_surface->fourcc ==  VA_FOURCC_NV12 ||
  1532.            obj_surface->fourcc ==  VA_FOURCC_YV12 ||
  1533.            obj_surface->fourcc ==  VA_FOURCC_I420 ||
  1534.            obj_surface->fourcc ==  VA_FOURCC_YUY2 ||
  1535.            obj_surface->fourcc ==  VA_FOURCC_IMC1 ||
  1536.            obj_surface->fourcc ==  VA_FOURCC_IMC3 ||
  1537.            obj_surface->fourcc ==  VA_FOURCC_RGBA) {
  1538.             vpp_surface_convert(ctx, proc_ctx->surface_output_scaled_object, obj_surface);
  1539.        }else {
  1540.            assert(0);
  1541.        }
  1542.    }
  1543.  
  1544.     return 0;
  1545. }
  1546.  
  1547. static VAStatus
  1548. gen75_vebox_init_pipe_params(VADriverContextP ctx,
  1549.     struct intel_vebox_context *proc_ctx)
  1550. {
  1551.     struct i965_driver_data * const i965 = i965_driver_data(ctx);
  1552.     const VAProcPipelineParameterBuffer * const pipe = proc_ctx->pipeline_param;
  1553.     VAProcFilterParameterBuffer *filter;
  1554.     unsigned int i;
  1555.  
  1556.     proc_ctx->filters_mask = 0;
  1557.     for (i = 0; i < pipe->num_filters; i++) {
  1558.         struct object_buffer * const obj_buffer = BUFFER(pipe->filters[i]);
  1559.  
  1560.         assert(obj_buffer && obj_buffer->buffer_store);
  1561.         if (!obj_buffer || !obj_buffer->buffer_store)
  1562.             return VA_STATUS_ERROR_INVALID_PARAMETER;
  1563.  
  1564.         filter = (VAProcFilterParameterBuffer *)
  1565.             obj_buffer->buffer_store->buffer;
  1566.         switch (filter->type) {
  1567.         case VAProcFilterNoiseReduction:
  1568.             proc_ctx->filters_mask |= VPP_DNDI_DN;
  1569.             proc_ctx->filter_dn = filter;
  1570.             break;
  1571.         case VAProcFilterDeinterlacing:
  1572.             proc_ctx->filters_mask |= VPP_DNDI_DI;
  1573.             proc_ctx->filter_di = filter;
  1574.             break;
  1575.         case VAProcFilterColorBalance:
  1576.             proc_ctx->filters_mask |= VPP_IECP_PRO_AMP;
  1577.             proc_ctx->filter_iecp_amp = filter;
  1578.             proc_ctx->filter_iecp_amp_num_elements = obj_buffer->num_elements;
  1579.             break;
  1580.         case VAProcFilterSkinToneEnhancement:
  1581.             proc_ctx->filters_mask |= VPP_IECP_STD_STE;
  1582.             proc_ctx->filter_iecp_std = filter;
  1583.             break;
  1584.         default:
  1585.             WARN_ONCE("unsupported filter (type: %d)\n", filter->type);
  1586.             return VA_STATUS_ERROR_UNSUPPORTED_FILTER;
  1587.         }
  1588.     }
  1589.     return VA_STATUS_SUCCESS;
  1590. }
  1591.  
  1592. static VAStatus
  1593. gen75_vebox_init_filter_params(VADriverContextP ctx,
  1594.     struct intel_vebox_context *proc_ctx)
  1595. {
  1596.     proc_ctx->format_convert_flags = 0; /* initialized in hsw_veb_pre_format_convert() */
  1597.  
  1598.     proc_ctx->is_iecp_enabled = (proc_ctx->filters_mask & VPP_IECP_MASK) != 0;
  1599.     proc_ctx->is_dn_enabled = (proc_ctx->filters_mask & VPP_DNDI_DN) != 0;
  1600.     proc_ctx->is_di_enabled = (proc_ctx->filters_mask & VPP_DNDI_DI) != 0;
  1601.     proc_ctx->is_di_adv_enabled = 0;
  1602.     proc_ctx->is_first_frame = 0;
  1603.     proc_ctx->is_second_field = 0;
  1604.  
  1605.     /* Check whether we are deinterlacing the second field */
  1606.     if (proc_ctx->is_di_enabled) {
  1607.         const VAProcFilterParameterBufferDeinterlacing * const deint_params =
  1608.             proc_ctx->filter_di;
  1609.  
  1610.         const unsigned int tff =
  1611.             !(deint_params->flags & VA_DEINTERLACING_BOTTOM_FIELD_FIRST);
  1612.         const unsigned int is_top_field =
  1613.             !(deint_params->flags & VA_DEINTERLACING_BOTTOM_FIELD);
  1614.  
  1615.         if ((tff ^ is_top_field) != 0) {
  1616.             struct object_surface * const obj_surface =
  1617.                 proc_ctx->surface_input_object;
  1618.  
  1619.             if (proc_ctx->frame_store[FRAME_IN_CURRENT].surface_id != obj_surface->base.id) {
  1620.                 WARN_ONCE("invalid surface provided for second field\n");
  1621.                 return VA_STATUS_ERROR_INVALID_PARAMETER;
  1622.             }
  1623.             proc_ctx->is_second_field = 1;
  1624.         }
  1625.     }
  1626.  
  1627.     /* Check whether we are deinterlacing the first frame */
  1628.     if (proc_ctx->is_di_enabled) {
  1629.         const VAProcFilterParameterBufferDeinterlacing * const deint_params =
  1630.             proc_ctx->filter_di;
  1631.  
  1632.         switch (deint_params->algorithm) {
  1633.         case VAProcDeinterlacingBob:
  1634.             proc_ctx->is_first_frame = 1;
  1635.             break;
  1636.         case VAProcDeinterlacingMotionAdaptive:
  1637.         case VAProcDeinterlacingMotionCompensated:
  1638.             if (proc_ctx->frame_store[FRAME_IN_CURRENT].surface_id == VA_INVALID_ID)
  1639.                 proc_ctx->is_first_frame = 1;
  1640.             else if (proc_ctx->is_second_field) {
  1641.                 /* At this stage, we have already deinterlaced the
  1642.                    first field successfully. So, the first frame flag
  1643.                    is trigerred if the previous field was deinterlaced
  1644.                    without reference frame */
  1645.                 if (proc_ctx->frame_store[FRAME_IN_PREVIOUS].surface_id == VA_INVALID_ID)
  1646.                     proc_ctx->is_first_frame = 1;
  1647.             }
  1648.             else {
  1649.                 const VAProcPipelineParameterBuffer * const pipe =
  1650.                     proc_ctx->pipeline_param;
  1651.  
  1652.                 if (pipe->num_forward_references < 1 ||
  1653.                     pipe->forward_references[0] == VA_INVALID_ID) {
  1654.                     WARN_ONCE("A forward temporal reference is needed for Motion adaptive/compensated deinterlacing !!!\n");
  1655.                     return VA_STATUS_ERROR_INVALID_PARAMETER;
  1656.                 }
  1657.             }
  1658.             proc_ctx->is_di_adv_enabled = 1;
  1659.             break;
  1660.         default:
  1661.             WARN_ONCE("unsupported deinterlacing algorithm (%d)\n",
  1662.                       deint_params->algorithm);
  1663.             return VA_STATUS_ERROR_UNSUPPORTED_FILTER;
  1664.         }
  1665.     }
  1666.     return VA_STATUS_SUCCESS;
  1667. }
  1668.  
  1669. VAStatus
  1670. gen75_vebox_process_picture(VADriverContextP ctx,
  1671.     struct intel_vebox_context *proc_ctx)
  1672. {
  1673.     VAStatus status;
  1674.  
  1675.     status = gen75_vebox_init_pipe_params(ctx, proc_ctx);
  1676.     if (status != VA_STATUS_SUCCESS)
  1677.         return status;
  1678.  
  1679.     status = gen75_vebox_init_filter_params(ctx, proc_ctx);
  1680.     if (status != VA_STATUS_SUCCESS)
  1681.         return status;
  1682.  
  1683.     hsw_veb_pre_format_convert(ctx, proc_ctx);
  1684.  
  1685.     status = gen75_vebox_ensure_surfaces(ctx, proc_ctx);
  1686.     if (status != VA_STATUS_SUCCESS)
  1687.         return status;
  1688.  
  1689.     status = gen75_vebox_ensure_surfaces_storage(ctx, proc_ctx);
  1690.     if (status != VA_STATUS_SUCCESS)
  1691.         return status;
  1692.  
  1693.     if (proc_ctx->format_convert_flags & POST_COPY_CONVERT) {
  1694.         assert(proc_ctx->is_second_field);
  1695.         /* directly copy the saved frame in the second call */
  1696.     } else {
  1697.         intel_batchbuffer_start_atomic_veb(proc_ctx->batch, 0x1000);
  1698.         intel_batchbuffer_emit_mi_flush(proc_ctx->batch);
  1699.         hsw_veb_state_table_setup(ctx, proc_ctx);
  1700.         hsw_veb_state_command(ctx, proc_ctx);          
  1701.         hsw_veb_surface_state(ctx, proc_ctx, INPUT_SURFACE);
  1702.         hsw_veb_surface_state(ctx, proc_ctx, OUTPUT_SURFACE);
  1703.         hsw_veb_dndi_iecp_command(ctx, proc_ctx);
  1704.         intel_batchbuffer_end_atomic(proc_ctx->batch);
  1705.         intel_batchbuffer_flush(proc_ctx->batch);
  1706.     }
  1707.  
  1708.     hsw_veb_post_format_convert(ctx, proc_ctx);
  1709.      
  1710.     return VA_STATUS_SUCCESS;
  1711. }
  1712.  
  1713. void gen75_vebox_context_destroy(VADriverContextP ctx,
  1714.                           struct intel_vebox_context *proc_ctx)
  1715. {
  1716.     int i;
  1717.  
  1718.     if(proc_ctx->surface_input_vebox != VA_INVALID_ID){
  1719.        i965_DestroySurfaces(ctx, &proc_ctx->surface_input_vebox, 1);
  1720.        proc_ctx->surface_input_vebox = VA_INVALID_ID;
  1721.        proc_ctx->surface_input_vebox_object = NULL;
  1722.      }
  1723.  
  1724.     if(proc_ctx->surface_output_vebox != VA_INVALID_ID){
  1725.        i965_DestroySurfaces(ctx, &proc_ctx->surface_output_vebox, 1);
  1726.        proc_ctx->surface_output_vebox = VA_INVALID_ID;
  1727.        proc_ctx->surface_output_vebox_object = NULL;
  1728.      }
  1729.  
  1730.     if(proc_ctx->surface_output_scaled != VA_INVALID_ID){
  1731.        i965_DestroySurfaces(ctx, &proc_ctx->surface_output_scaled, 1);
  1732.        proc_ctx->surface_output_scaled = VA_INVALID_ID;
  1733.        proc_ctx->surface_output_scaled_object = NULL;
  1734.      }
  1735.  
  1736.     for (i = 0; i < ARRAY_ELEMS(proc_ctx->frame_store); i++)
  1737.         frame_store_clear(&proc_ctx->frame_store[i], ctx);
  1738.  
  1739.     /* dndi state table  */
  1740.     drm_intel_bo_unreference(proc_ctx->dndi_state_table.bo);
  1741.     proc_ctx->dndi_state_table.bo = NULL;
  1742.  
  1743.     /* iecp state table  */
  1744.     drm_intel_bo_unreference(proc_ctx->iecp_state_table.bo);
  1745.     proc_ctx->iecp_state_table.bo = NULL;
  1746.  
  1747.     /* gamut statu table */
  1748.     drm_intel_bo_unreference(proc_ctx->gamut_state_table.bo);
  1749.     proc_ctx->gamut_state_table.bo = NULL;
  1750.  
  1751.     /* vertex state table  */
  1752.     drm_intel_bo_unreference(proc_ctx->vertex_state_table.bo);
  1753.     proc_ctx->vertex_state_table.bo = NULL;
  1754.  
  1755.     intel_batchbuffer_free(proc_ctx->batch);
  1756.  
  1757.     free(proc_ctx);
  1758. }
  1759.  
  1760. struct intel_vebox_context * gen75_vebox_context_init(VADriverContextP ctx)
  1761. {
  1762.     struct intel_driver_data *intel = intel_driver_data(ctx);
  1763.     struct intel_vebox_context *proc_context = calloc(1, sizeof(struct intel_vebox_context));
  1764.     int i;
  1765.  
  1766.     assert(proc_context);
  1767.     proc_context->batch = intel_batchbuffer_new(intel, I915_EXEC_VEBOX, 0);
  1768.  
  1769.     for (i = 0; i < ARRAY_ELEMS(proc_context->frame_store); i++)
  1770.         proc_context->frame_store[i].surface_id = VA_INVALID_ID;
  1771.  
  1772.     proc_context->filters_mask          = 0;
  1773.     proc_context->surface_output_object = NULL;
  1774.     proc_context->surface_input_object  = NULL;
  1775.     proc_context->surface_input_vebox   = VA_INVALID_ID;
  1776.     proc_context->surface_input_vebox_object = NULL;
  1777.     proc_context->surface_output_vebox  = VA_INVALID_ID;
  1778.     proc_context->surface_output_vebox_object = NULL;
  1779.     proc_context->surface_output_scaled = VA_INVALID_ID;
  1780.     proc_context->surface_output_scaled_object = NULL;
  1781.     proc_context->filters_mask          = 0;
  1782.     proc_context->format_convert_flags  = 0;
  1783.  
  1784.     return proc_context;
  1785. }
  1786.  
  1787. void bdw_veb_state_command(VADriverContextP ctx, struct intel_vebox_context *proc_ctx)
  1788. {
  1789.     struct intel_batchbuffer *batch = proc_ctx->batch;
  1790.  
  1791.     BEGIN_VEB_BATCH(batch, 0xc);
  1792.     OUT_VEB_BATCH(batch, VEB_STATE | (0xc - 2));
  1793.     OUT_VEB_BATCH(batch,
  1794.                   0 << 25 |       // state surface control bits
  1795.                   0 << 23 |       // reserved.
  1796.                   0 << 22 |       // gamut expansion position
  1797.                   0 << 15 |       // reserved.
  1798.                   0 << 14 |       // single slice vebox enable
  1799.                   0 << 13 |       // hot pixel filter enable
  1800.                   0 << 12 |       // alpha plane enable
  1801.                   0 << 11 |       // vignette enable
  1802.                   0 << 10 |       // demosaic enable
  1803.                   proc_ctx->current_output_type << 8  | // DI output frame
  1804.                   1 << 7  |       // 444->422 downsample method
  1805.                   1 << 6  |       // 422->420 downsample method
  1806.                   proc_ctx->is_first_frame  << 5  |   // DN/DI first frame
  1807.                   proc_ctx->is_di_enabled   << 4  |   // DI enable
  1808.                   proc_ctx->is_dn_enabled   << 3  |   // DN enable
  1809.                   proc_ctx->is_iecp_enabled << 2  |   // global IECP enabled
  1810.                   0 << 1  |       // ColorGamutCompressionEnable
  1811.                   0 ) ;           // ColorGamutExpansionEnable.
  1812.  
  1813.     OUT_RELOC(batch,
  1814.               proc_ctx->dndi_state_table.bo,
  1815.               I915_GEM_DOMAIN_INSTRUCTION, 0, 0);
  1816.  
  1817.     OUT_VEB_BATCH(batch, 0);
  1818.  
  1819.     OUT_RELOC(batch,
  1820.               proc_ctx->iecp_state_table.bo,
  1821.               I915_GEM_DOMAIN_INSTRUCTION, 0, 0);
  1822.  
  1823.     OUT_VEB_BATCH(batch, 0);
  1824.  
  1825.     OUT_RELOC(batch,
  1826.               proc_ctx->gamut_state_table.bo,
  1827.               I915_GEM_DOMAIN_INSTRUCTION, 0, 0);
  1828.  
  1829.     OUT_VEB_BATCH(batch, 0);
  1830.  
  1831.     OUT_RELOC(batch,
  1832.               proc_ctx->vertex_state_table.bo,
  1833.               I915_GEM_DOMAIN_INSTRUCTION, 0, 0);
  1834.  
  1835.     OUT_VEB_BATCH(batch, 0);
  1836.  
  1837.     OUT_VEB_BATCH(batch, 0);/*caputre pipe state pointer*/
  1838.     OUT_VEB_BATCH(batch, 0);
  1839.  
  1840.     ADVANCE_VEB_BATCH(batch);
  1841. }
  1842.  
  1843. void bdw_veb_dndi_iecp_command(VADriverContextP ctx, struct intel_vebox_context *proc_ctx)
  1844. {
  1845.     struct intel_batchbuffer *batch = proc_ctx->batch;
  1846.     unsigned char frame_ctrl_bits = 0;
  1847.     const unsigned int width64 = ALIGN(proc_ctx->width_input, 64);
  1848.  
  1849.     BEGIN_VEB_BATCH(batch, 0x14);
  1850.     OUT_VEB_BATCH(batch, VEB_DNDI_IECP_STATE | (0x14 - 2));//DWord 0
  1851.     OUT_VEB_BATCH(batch, (width64 - 1));
  1852.  
  1853.     OUT_RELOC(batch,
  1854.               proc_ctx->frame_store[FRAME_IN_CURRENT].obj_surface->bo,
  1855.               I915_GEM_DOMAIN_RENDER, 0, frame_ctrl_bits);//DWord 2
  1856.     OUT_VEB_BATCH(batch,0);//DWord 3
  1857.  
  1858.     OUT_RELOC(batch,
  1859.               proc_ctx->frame_store[FRAME_IN_PREVIOUS].obj_surface->bo,
  1860.               I915_GEM_DOMAIN_RENDER, 0, frame_ctrl_bits);//DWord 4
  1861.     OUT_VEB_BATCH(batch,0);//DWord 5
  1862.  
  1863.     OUT_RELOC(batch,
  1864.               proc_ctx->frame_store[FRAME_IN_STMM].obj_surface->bo,
  1865.               I915_GEM_DOMAIN_RENDER, 0, frame_ctrl_bits);//DWord 6
  1866.     OUT_VEB_BATCH(batch,0);//DWord 7
  1867.  
  1868.     OUT_RELOC(batch,
  1869.               proc_ctx->frame_store[FRAME_OUT_STMM].obj_surface->bo,
  1870.               I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, frame_ctrl_bits);//DWord 8
  1871.     OUT_VEB_BATCH(batch,0);//DWord 9
  1872.  
  1873.     OUT_RELOC(batch,
  1874.               proc_ctx->frame_store[FRAME_OUT_CURRENT_DN].obj_surface->bo,
  1875.               I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, frame_ctrl_bits);//DWord 10
  1876.     OUT_VEB_BATCH(batch,0);//DWord 11
  1877.  
  1878.     OUT_RELOC(batch,
  1879.               proc_ctx->frame_store[FRAME_OUT_CURRENT].obj_surface->bo,
  1880.               I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, frame_ctrl_bits);//DWord 12
  1881.     OUT_VEB_BATCH(batch,0);//DWord 13
  1882.  
  1883.     OUT_RELOC(batch,
  1884.               proc_ctx->frame_store[FRAME_OUT_PREVIOUS].obj_surface->bo,
  1885.               I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, frame_ctrl_bits);//DWord 14
  1886.     OUT_VEB_BATCH(batch,0);//DWord 15
  1887.  
  1888.     OUT_RELOC(batch,
  1889.               proc_ctx->frame_store[FRAME_OUT_STATISTIC].obj_surface->bo,
  1890.               I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, frame_ctrl_bits);//DWord 16
  1891.     OUT_VEB_BATCH(batch,0);//DWord 17
  1892.  
  1893.     OUT_VEB_BATCH(batch,0);//DWord 18
  1894.     OUT_VEB_BATCH(batch,0);//DWord 19
  1895.  
  1896.     ADVANCE_VEB_BATCH(batch);
  1897. }
  1898.  
  1899. VAStatus
  1900. gen8_vebox_process_picture(VADriverContextP ctx,
  1901.     struct intel_vebox_context *proc_ctx)
  1902. {
  1903.     VAStatus status;
  1904.  
  1905.     status = gen75_vebox_init_pipe_params(ctx, proc_ctx);
  1906.     if (status != VA_STATUS_SUCCESS)
  1907.         return status;
  1908.  
  1909.     status = gen75_vebox_init_filter_params(ctx, proc_ctx);
  1910.     if (status != VA_STATUS_SUCCESS)
  1911.         return status;
  1912.  
  1913.     hsw_veb_pre_format_convert(ctx, proc_ctx);
  1914.  
  1915.     status = gen75_vebox_ensure_surfaces(ctx, proc_ctx);
  1916.     if (status != VA_STATUS_SUCCESS)
  1917.         return status;
  1918.  
  1919.     status = gen75_vebox_ensure_surfaces_storage(ctx, proc_ctx);
  1920.     if (status != VA_STATUS_SUCCESS)
  1921.         return status;
  1922.  
  1923.     if (proc_ctx->format_convert_flags & POST_COPY_CONVERT) {
  1924.         assert(proc_ctx->is_second_field);
  1925.         /* directly copy the saved frame in the second call */
  1926.     } else {
  1927.         intel_batchbuffer_start_atomic_veb(proc_ctx->batch, 0x1000);
  1928.         intel_batchbuffer_emit_mi_flush(proc_ctx->batch);
  1929.         hsw_veb_state_table_setup(ctx, proc_ctx);
  1930.         bdw_veb_state_command(ctx, proc_ctx);          
  1931.         hsw_veb_surface_state(ctx, proc_ctx, INPUT_SURFACE);
  1932.         hsw_veb_surface_state(ctx, proc_ctx, OUTPUT_SURFACE);
  1933.         bdw_veb_dndi_iecp_command(ctx, proc_ctx);
  1934.         intel_batchbuffer_end_atomic(proc_ctx->batch);
  1935.         intel_batchbuffer_flush(proc_ctx->batch);
  1936.     }
  1937.  
  1938.     hsw_veb_post_format_convert(ctx, proc_ctx);
  1939.      
  1940.     return VA_STATUS_SUCCESS;
  1941. }
  1942.  
  1943.  
  1944. void
  1945. skl_veb_dndi_table(VADriverContextP ctx, struct intel_vebox_context *proc_ctx)
  1946. {
  1947.     unsigned int* p_table ;
  1948.     unsigned int progressive_dn = 1;
  1949.     unsigned int dndi_top_first = 0;
  1950.     unsigned int is_mcdi_enabled = 0;
  1951.  
  1952.     if (proc_ctx->is_di_enabled) {
  1953.         const VAProcFilterParameterBufferDeinterlacing * const deint_params =
  1954.             proc_ctx->filter_di;
  1955.  
  1956.         progressive_dn = 0;
  1957.  
  1958.         /* If we are in "First Frame" mode, i.e. past frames are not
  1959.            available for motion measure, then don't use the TFF flag */
  1960.         dndi_top_first = !(deint_params->flags & (proc_ctx->is_first_frame ?
  1961.                 VA_DEINTERLACING_BOTTOM_FIELD :
  1962.                 VA_DEINTERLACING_BOTTOM_FIELD_FIRST));
  1963.  
  1964.         is_mcdi_enabled =
  1965.             (deint_params->algorithm == VAProcDeinterlacingMotionCompensated);
  1966.     }
  1967.  
  1968.     /*
  1969.     VAProcFilterParameterBufferDeinterlacing *di_param =
  1970.             (VAProcFilterParameterBufferDeinterlacing *) proc_ctx->filter_di;
  1971.  
  1972.     VAProcFilterParameterBuffer * dn_param =
  1973.             (VAProcFilterParameterBuffer *) proc_ctx->filter_dn;
  1974.     */
  1975.     p_table = (unsigned int *)proc_ctx->dndi_state_table.ptr;
  1976.  
  1977.     *p_table ++ = ( 140 << 20 |   // denoise stad threshold . w1
  1978.                     192 << 12 |   // dnmh_history_max
  1979.                     7   << 8  |   // dnmh_delta[3:0]
  1980.                     1 );          // denoise moving pixel threshold
  1981.  
  1982.     *p_table ++ = ( 38 << 20 |    // denoise asd threshold
  1983.                     0  << 10 |    // temporal diff th
  1984.                     0 );          // low temporal diff th
  1985.  
  1986.     *p_table ++ = ( progressive_dn << 28  |  // progressive dn
  1987.                     38 << 16 |    // denoise th for sum of complexity measure
  1988.                     32 << 10 |    // dnmh_history_init[5:0]
  1989.                     0 );          // reserved
  1990.  
  1991.     *p_table ++ = ( 0 << 28  |    // hot pixel count
  1992.                     0 << 20  |    // hot pixel threshold
  1993.                     1 << 12  |    // block noise estimate edge threshold
  1994.                     20 );         // block noise estimate noise threshold
  1995.  
  1996.     *p_table ++ = ( 140<< 16 |    // chroma denoise stad threshold
  1997.                     0  << 13 |    // reserved
  1998.                     1  << 12 |    // chrome denoise enable
  1999.                     13 << 6  |    // chr temp diff th
  2000.                     7 );          // chr temp diff low
  2001.  
  2002.     *p_table ++ = 0;              // weight
  2003.  
  2004.     *p_table ++ = ( 0 << 16  |    // dn_thmax
  2005.                     0 );          // dn_thmin
  2006.  
  2007.     *p_table ++ = ( 0 << 16  |    // dn_prt5
  2008.                     0 );          // dn_dyn_thmin
  2009.  
  2010.     *p_table ++ = ( 0 << 16  |    // dn_prt4
  2011.                     0 );          // dn_prt3
  2012.  
  2013.     *p_table ++ = ( 0 << 16  |    // dn_prt2
  2014.                     0 );          // dn_prt1
  2015.  
  2016.     *p_table ++ = ( 0 << 16  |    // dn_prt0
  2017.                     0 << 10  |    // dn_wd22
  2018.                     0 << 5   |    // dh_wd21
  2019.                     0 );          // dh_wd20
  2020.  
  2021.    *p_table ++ = ( 0 << 25  |    // dn_wd12
  2022.                     0 << 20  |    // dn_wd11
  2023.                     0 << 15  |    // dn_wd10
  2024.                     0 << 10  |    // dn_wd02
  2025.                     0 << 5   |    // dn_wd01
  2026.                     0 );          // dn_wd00
  2027.  
  2028.     *p_table ++ = ( 2 << 10 |     // stmm c2
  2029.                     9 << 6  |     // cat slope minus 1
  2030.                     5 << 2  |     // sad tight threshold
  2031.                     0 );          // smooth mv th
  2032.  
  2033.     *p_table ++ = ( 0  << 31 |    // stmm blending constant select
  2034.                     64 << 24 |    // stmm trc1
  2035.                     125<< 16 |    // stmm trc2
  2036.                     0  << 14 |    // reserved
  2037.                     30 << 8  |    // multiplier for vecm
  2038.                     150 );        // maximum stmm
  2039.  
  2040.     *p_table ++ = ( 118<< 24  |   // minumum stmm
  2041.                     0  << 22  |   // stmm shift down
  2042.                     1  << 20  |   // stmm shift up
  2043.                     5  << 16  |   // stmm output shift
  2044.                     100 << 8  |   // sdi threshold
  2045.                     5 );          // sdi delta
  2046.  
  2047.     *p_table ++ = ( 50  << 24 |   // sdi fallback mode 1 t1 constant
  2048.                     100 << 16 |   // sdi fallback mode 1 t2 constant
  2049.                     37  << 8  |   // sdi fallback mode 2 constant(angle2x1)
  2050.                     175 );        // fmd temporal difference threshold
  2051.  
  2052.     *p_table ++ = ( 16 << 24  |   // fmd #1 vertical difference th . w7
  2053.                     100<< 16  |   // fmd #2 vertical difference th
  2054.                     0  << 14  |   // cat threshold
  2055.                     2  << 8   |   // fmd tear threshold
  2056.                     is_mcdi_enabled  << 7  |  // mcdi enable, use motion compensated deinterlace algorithm
  2057.                     dndi_top_first  << 3   |  // dn/di top first
  2058.                     0 );          // reserved
  2059.  
  2060.     *p_table ++ = ( 10 << 19  |   // neighbor pixel threshold
  2061.                     0  << 16  |   // fmd for 2nd field of previous frame
  2062.                     25 << 10  |   // mc pixel consistency threshold
  2063.                     0  << 8   |   // fmd for 1st field for current frame
  2064.                     10 << 4   |   // sad thb
  2065.                     5 );          // sad tha
  2066. }
  2067.  
  2068. void skl_veb_iecp_csc_table(VADriverContextP ctx, struct intel_vebox_context *proc_ctx)
  2069. {
  2070.     unsigned int *p_table = (unsigned int*)(proc_ctx->iecp_state_table.ptr + 220);
  2071.     float tran_coef[9] = {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0};
  2072.     float v_coef[3]    = {0.0, 0.0, 0.0};
  2073.     float u_coef[3]    = {0.0, 0.0, 0.0};
  2074.     int   is_transform_enabled = 0;
  2075.  
  2076.     if(!(proc_ctx->filters_mask & VPP_IECP_CSC)){
  2077.         memset(p_table, 0, 12 * 4);
  2078.         return;
  2079.     }
  2080.  
  2081.     if(proc_ctx->fourcc_input == VA_FOURCC_RGBA &&
  2082.        (proc_ctx->fourcc_output == VA_FOURCC_NV12 ||
  2083.         proc_ctx->fourcc_output == VA_FOURCC_YV12 ||
  2084.         proc_ctx->fourcc_output == VA_FOURCC_YVY2 ||
  2085.         proc_ctx->fourcc_output == VA_FOURCC_AYUV)) {
  2086.  
  2087.         tran_coef[0] = 0.257;
  2088.         tran_coef[1] = 0.504;
  2089.         tran_coef[2] = 0.098;
  2090.         tran_coef[3] = -0.148;
  2091.         tran_coef[4] = -0.291;
  2092.         tran_coef[5] = 0.439;
  2093.         tran_coef[6] = 0.439;
  2094.         tran_coef[7] = -0.368;
  2095.         tran_coef[8] = -0.071;
  2096.  
  2097.         u_coef[0] = 16 * 4;
  2098.         u_coef[1] = 128 * 4;
  2099.         u_coef[2] = 128 * 4;
  2100.  
  2101.         is_transform_enabled = 1;
  2102.     }else if((proc_ctx->fourcc_input  == VA_FOURCC_NV12 ||
  2103.               proc_ctx->fourcc_input  == VA_FOURCC_YV12 ||
  2104.               proc_ctx->fourcc_input  == VA_FOURCC_YUY2 ||
  2105.               proc_ctx->fourcc_input  == VA_FOURCC_AYUV) &&
  2106.              proc_ctx->fourcc_output == VA_FOURCC_RGBA) {
  2107.         tran_coef[0] = 1.164;
  2108.         tran_coef[1] = 0.000;
  2109.         tran_coef[2] = 1.569;
  2110.         tran_coef[3] = 1.164;
  2111.         tran_coef[4] = -0.813;
  2112.         tran_coef[5] = -0.392;
  2113.         tran_coef[6] = 1.164;
  2114.         tran_coef[7] = 2.017;
  2115.         tran_coef[8] = 0.000;
  2116.  
  2117.         v_coef[0] = -16 * 4;
  2118.         v_coef[1] = -128 * 4;
  2119.         v_coef[2] = -128 * 4;
  2120.  
  2121.         is_transform_enabled = 1;
  2122.     }else if(proc_ctx->fourcc_input != proc_ctx->fourcc_output){
  2123.         //enable when input and output format are different.
  2124.         is_transform_enabled = 1;
  2125.     }
  2126.  
  2127.     if(is_transform_enabled == 0){
  2128.         memset(p_table, 0, 12 * 4);
  2129.     }else{
  2130.         *p_table ++ = ( is_transform_enabled << 31 |
  2131.                         0 << 29 | // yuv_channel swap
  2132.                         intel_format_convert(tran_coef[0], 2, 16, 1));          //c0, s2.16 format
  2133.  
  2134.         *p_table ++ = ( 0 << 19 | //reserved
  2135.                         intel_format_convert(tran_coef[1], 2, 16, 1));          //c1, s2.16 format
  2136.  
  2137.         *p_table ++ = ( 0 << 19 | //reserved
  2138.                         intel_format_convert(tran_coef[2], 2, 16, 1));          //c2, s2.16 format
  2139.  
  2140.         *p_table ++ = ( 0 << 19 | //reserved
  2141.                         intel_format_convert(tran_coef[3], 2, 16, 1));          //c3, s2.16 format
  2142.  
  2143.         *p_table ++ = ( 0 << 19 | //reserved
  2144.                         intel_format_convert(tran_coef[4], 2, 16, 1));          //c4, s2.16 format
  2145.  
  2146.         *p_table ++ = ( 0 << 19 | //reserved
  2147.                         intel_format_convert(tran_coef[5], 2, 16, 1));          //c5, s2.16 format
  2148.  
  2149.         *p_table ++ = ( 0 << 19 | //reserved
  2150.                         intel_format_convert(tran_coef[6], 2, 16, 1));          //c6, s2.16 format
  2151.  
  2152.         *p_table ++ = ( 0 << 19 | //reserved
  2153.                         intel_format_convert(tran_coef[7], 2, 16, 1));          //c7, s2.16 format
  2154.  
  2155.         *p_table ++ = ( 0 << 19 | //reserved
  2156.                         intel_format_convert(tran_coef[8], 2, 16, 1));          //c8, s2.16 format
  2157.  
  2158.         *p_table ++ = ( intel_format_convert(u_coef[0], 16, 0, 1) << 16 |
  2159.                         intel_format_convert(v_coef[0], 16, 0, 1));
  2160.  
  2161.         *p_table ++ = ( intel_format_convert(u_coef[1], 16, 0, 1) << 16 |
  2162.                         intel_format_convert(v_coef[1], 16, 0, 1));
  2163.  
  2164.         *p_table ++ = ( intel_format_convert(u_coef[2], 16, 0, 1) << 16 |
  2165.                         intel_format_convert(v_coef[2], 16, 0, 1));
  2166.     }
  2167. }
  2168.  
  2169. void skl_veb_iecp_aoi_table(VADriverContextP ctx, struct intel_vebox_context *proc_ctx)
  2170. {
  2171.     unsigned int *p_table = (unsigned int*)(proc_ctx->iecp_state_table.ptr + 27 * sizeof(unsigned int));
  2172.  
  2173.     if (!(proc_ctx->filters_mask & VPP_IECP_AOI)) {
  2174.         memset(p_table, 0, 3 * 4);
  2175.     } else {
  2176.         *p_table ++ = 0x00000000;
  2177.         *p_table ++ = 0x00030000;
  2178.         *p_table ++ = 0x00030000;
  2179.     }
  2180. }
  2181.  
  2182. void skl_veb_state_table_setup(VADriverContextP ctx, struct intel_vebox_context *proc_ctx)
  2183. {
  2184.     if(proc_ctx->filters_mask & VPP_DNDI_MASK) {
  2185.         dri_bo *dndi_bo = proc_ctx->dndi_state_table.bo;
  2186.         dri_bo_map(dndi_bo, 1);
  2187.         proc_ctx->dndi_state_table.ptr = dndi_bo->virtual;
  2188.  
  2189.         skl_veb_dndi_table(ctx, proc_ctx);
  2190.  
  2191.         dri_bo_unmap(dndi_bo);
  2192.     }
  2193.  
  2194.     if(proc_ctx->filters_mask & VPP_IECP_MASK) {
  2195.         dri_bo *iecp_bo = proc_ctx->iecp_state_table.bo;
  2196.         dri_bo_map(iecp_bo, 1);
  2197.         proc_ctx->iecp_state_table.ptr = iecp_bo->virtual;
  2198.  
  2199.         hsw_veb_iecp_std_table(ctx, proc_ctx);
  2200.         hsw_veb_iecp_ace_table(ctx, proc_ctx);
  2201.         hsw_veb_iecp_tcc_table(ctx, proc_ctx);
  2202.         hsw_veb_iecp_pro_amp_table(ctx, proc_ctx);
  2203.         skl_veb_iecp_csc_table(ctx, proc_ctx);
  2204.         skl_veb_iecp_aoi_table(ctx, proc_ctx);
  2205.  
  2206.         dri_bo_unmap(iecp_bo);
  2207.     }
  2208. }
  2209.  
  2210. void
  2211. skl_veb_state_command(VADriverContextP ctx, struct intel_vebox_context *proc_ctx)
  2212. {
  2213.     struct intel_batchbuffer *batch = proc_ctx->batch;
  2214.  
  2215.     BEGIN_VEB_BATCH(batch, 0x10);
  2216.     OUT_VEB_BATCH(batch, VEB_STATE | (0x10 - 2));
  2217.     OUT_VEB_BATCH(batch,
  2218.                   0 << 25 |       // state surface control bits
  2219.                   0 << 23 |       // reserved.
  2220.                   0 << 22 |       // gamut expansion position
  2221.                   0 << 15 |       // reserved.
  2222.                   0 << 14 |       // single slice vebox enable
  2223.                   0 << 13 |       // hot pixel filter enable
  2224.                   0 << 12 |       // alpha plane enable
  2225.                   0 << 11 |       // vignette enable
  2226.                   0 << 10 |       // demosaic enable
  2227.                   proc_ctx->current_output_type << 8  | // DI output frame
  2228.                   1 << 7  |       // 444->422 downsample method
  2229.                   1 << 6  |       // 422->420 downsample method
  2230.                   proc_ctx->is_first_frame  << 5  |   // DN/DI first frame
  2231.                   proc_ctx->is_di_enabled   << 4  |   // DI enable
  2232.                   proc_ctx->is_dn_enabled   << 3  |   // DN enable
  2233.                   proc_ctx->is_iecp_enabled << 2  |   // global IECP enabled
  2234.                   0 << 1  |       // ColorGamutCompressionEnable
  2235.                   0 ) ;           // ColorGamutExpansionEnable.
  2236.  
  2237.     OUT_RELOC(batch,
  2238.               proc_ctx->dndi_state_table.bo,
  2239.               I915_GEM_DOMAIN_INSTRUCTION, 0, 0);
  2240.  
  2241.     OUT_VEB_BATCH(batch, 0);
  2242.  
  2243.     OUT_RELOC(batch,
  2244.               proc_ctx->iecp_state_table.bo,
  2245.               I915_GEM_DOMAIN_INSTRUCTION, 0, 0);
  2246.  
  2247.     OUT_VEB_BATCH(batch, 0);
  2248.  
  2249.     OUT_RELOC(batch,
  2250.               proc_ctx->gamut_state_table.bo,
  2251.               I915_GEM_DOMAIN_INSTRUCTION, 0, 0);
  2252.  
  2253.     OUT_VEB_BATCH(batch, 0);
  2254.  
  2255.     OUT_RELOC(batch,
  2256.               proc_ctx->vertex_state_table.bo,
  2257.               I915_GEM_DOMAIN_INSTRUCTION, 0, 0);
  2258.  
  2259.     OUT_VEB_BATCH(batch, 0);
  2260.  
  2261.     OUT_VEB_BATCH(batch, 0);/*caputre pipe state pointer*/
  2262.     OUT_VEB_BATCH(batch, 0);
  2263.  
  2264.     OUT_VEB_BATCH(batch, 0);/*lace lut table state pointer*/
  2265.     OUT_VEB_BATCH(batch, 0);
  2266.  
  2267.     OUT_VEB_BATCH(batch, 0);/*gamma correction values address*/
  2268.     OUT_VEB_BATCH(batch, 0);
  2269.  
  2270.     ADVANCE_VEB_BATCH(batch);
  2271. }
  2272.  
  2273. void skl_veb_surface_state(VADriverContextP ctx, struct intel_vebox_context *proc_ctx, unsigned int is_output)
  2274. {
  2275.     struct intel_batchbuffer *batch = proc_ctx->batch;
  2276.     unsigned int u_offset_y = 0, v_offset_y = 0;
  2277.     unsigned int is_uv_interleaved = 0, tiling = 0, swizzle = 0;
  2278.     unsigned int surface_format = PLANAR_420_8;
  2279.     struct object_surface* obj_surf = NULL;
  2280.     unsigned int surface_pitch = 0;
  2281.     unsigned int half_pitch_chroma = 0;
  2282.     unsigned int derived_pitch;
  2283.  
  2284.     if (is_output) {
  2285.         obj_surf = proc_ctx->frame_store[FRAME_OUT_CURRENT].obj_surface;
  2286.     } else {
  2287.         obj_surf = proc_ctx->frame_store[FRAME_IN_CURRENT].obj_surface;
  2288.     }
  2289.  
  2290.     assert(obj_surf->fourcc == VA_FOURCC_NV12 ||
  2291.            obj_surf->fourcc == VA_FOURCC_YUY2 ||
  2292.            obj_surf->fourcc == VA_FOURCC_AYUV ||
  2293.            obj_surf->fourcc == VA_FOURCC_RGBA);
  2294.  
  2295.     if (obj_surf->fourcc == VA_FOURCC_NV12) {
  2296.         surface_format = PLANAR_420_8;
  2297.         surface_pitch = obj_surf->width;
  2298.         is_uv_interleaved = 1;
  2299.         half_pitch_chroma = 0;
  2300.     } else if (obj_surf->fourcc == VA_FOURCC_YUY2) {
  2301.         surface_format = YCRCB_NORMAL;
  2302.         surface_pitch = obj_surf->width * 2;
  2303.         is_uv_interleaved = 0;
  2304.         half_pitch_chroma = 0;
  2305.     } else if (obj_surf->fourcc == VA_FOURCC_AYUV) {
  2306.         surface_format = PACKED_444A_8;
  2307.         surface_pitch = obj_surf->width * 4;
  2308.         is_uv_interleaved = 0;
  2309.         half_pitch_chroma = 0;
  2310.     } else if (obj_surf->fourcc == VA_FOURCC_RGBA) {
  2311.         surface_format = R8G8B8A8_UNORM_SRGB;
  2312.         surface_pitch = obj_surf->width * 4;
  2313.         is_uv_interleaved = 0;
  2314.         half_pitch_chroma = 0;
  2315.     }
  2316.  
  2317.     derived_pitch = surface_pitch;
  2318.  
  2319.     u_offset_y = obj_surf->y_cb_offset;
  2320.     v_offset_y = obj_surf->y_cr_offset;
  2321.  
  2322.     dri_bo_get_tiling(obj_surf->bo, &tiling, &swizzle);
  2323.  
  2324.     BEGIN_VEB_BATCH(batch, 9);
  2325.     OUT_VEB_BATCH(batch, VEB_SURFACE_STATE | (9 - 2));
  2326.     OUT_VEB_BATCH(batch,
  2327.                   0 << 1 |         // reserved
  2328.                   is_output);      // surface indentification.
  2329.  
  2330.     OUT_VEB_BATCH(batch,
  2331.                   (obj_surf->height - 1) << 18 |  // height . w3
  2332.                   (obj_surf->width -1 )  << 4  |  // width
  2333.                   0);                             // reserve
  2334.  
  2335.     OUT_VEB_BATCH(batch,
  2336.                   surface_format      << 28  |  // surface format, YCbCr420. w4
  2337.                   is_uv_interleaved   << 27  |  // interleave chrome , two seperate palar
  2338.                   0                   << 20  |  // reserved
  2339.                   (surface_pitch - 1) << 3   |  // surface pitch, 64 align
  2340.                   half_pitch_chroma   << 2   |  // half pitch for chrome
  2341.                   !!tiling            << 1   |  // tiled surface, linear surface used
  2342.                   (tiling == I915_TILING_Y));   // tiled walk, ignored when liner surface
  2343.  
  2344.     OUT_VEB_BATCH(batch,
  2345.                   0 << 16  |     // X offset for V(Cb)
  2346.                   u_offset_y);   // Y offset for V(Cb)
  2347.  
  2348.     OUT_VEB_BATCH(batch,
  2349.                   0 << 16  |     // X offset for V(Cr)
  2350.                   v_offset_y );  // Y offset for V(Cr)
  2351.  
  2352.     OUT_VEB_BATCH(batch, 0);
  2353.  
  2354.     OUT_VEB_BATCH(batch, derived_pitch - 1);
  2355.  
  2356.     OUT_VEB_BATCH(batch, 0);
  2357.  
  2358.     ADVANCE_VEB_BATCH(batch);
  2359. }
  2360.  
  2361. VAStatus
  2362. gen9_vebox_process_picture(VADriverContextP ctx,
  2363.     struct intel_vebox_context *proc_ctx)
  2364. {
  2365.     VAStatus status;
  2366.  
  2367.     status = gen75_vebox_init_pipe_params(ctx, proc_ctx);
  2368.     if (status != VA_STATUS_SUCCESS)
  2369.         return status;
  2370.  
  2371.     status = gen75_vebox_init_filter_params(ctx, proc_ctx);
  2372.     if (status != VA_STATUS_SUCCESS)
  2373.         return status;
  2374.  
  2375.     hsw_veb_pre_format_convert(ctx, proc_ctx);
  2376.  
  2377.     status = gen75_vebox_ensure_surfaces(ctx, proc_ctx);
  2378.     if (status != VA_STATUS_SUCCESS)
  2379.         return status;
  2380.  
  2381.     status = gen75_vebox_ensure_surfaces_storage(ctx, proc_ctx);
  2382.     if (status != VA_STATUS_SUCCESS)
  2383.         return status;
  2384.  
  2385.     if (proc_ctx->format_convert_flags & POST_COPY_CONVERT) {
  2386.         assert(proc_ctx->is_second_field);
  2387.         /* directly copy the saved frame in the second call */
  2388.     } else {
  2389.         intel_batchbuffer_start_atomic_veb(proc_ctx->batch, 0x1000);
  2390.         intel_batchbuffer_emit_mi_flush(proc_ctx->batch);
  2391.         skl_veb_state_table_setup(ctx, proc_ctx);
  2392.         skl_veb_state_command(ctx, proc_ctx);
  2393.         skl_veb_surface_state(ctx, proc_ctx, INPUT_SURFACE);
  2394.         skl_veb_surface_state(ctx, proc_ctx, OUTPUT_SURFACE);
  2395.         bdw_veb_dndi_iecp_command(ctx, proc_ctx);
  2396.         intel_batchbuffer_end_atomic(proc_ctx->batch);
  2397.         intel_batchbuffer_flush(proc_ctx->batch);
  2398.     }
  2399.  
  2400.     hsw_veb_post_format_convert(ctx, proc_ctx);
  2401.  
  2402.     return VA_STATUS_SUCCESS;
  2403. }
  2404.