Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | Download | 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.  */
  27.  
  28. #include <stdio.h>
  29. #include <stdlib.h>
  30. #include <string.h>
  31. #include <assert.h>
  32. #include <math.h>
  33.  
  34. #include "intel_batchbuffer.h"
  35. #include "intel_driver.h"
  36. #include "i965_defines.h"
  37. #include "i965_structs.h"
  38. #include "gen75_vpp_vebox.h"
  39.  
  40. #define PI  3.1415926
  41.  
  42. extern VAStatus
  43. i965_CreateSurfaces(VADriverContextP ctx,
  44.                     int width,
  45.                     int height,
  46.                     int format,
  47.                     int num_surfaces,
  48.                     VASurfaceID *surfaces);      
  49.  
  50. int format_convert(float src, int out_int_bits, int out_frac_bits,int out_sign_flag)
  51. {
  52.      unsigned char negative_flag = (src < 0.0) ? 1 : 0;
  53.      float src_1 = (!negative_flag)? src: -src ;
  54.      unsigned int factor = 1 << out_frac_bits;
  55.      int output_value = 0;        
  56.  
  57.      unsigned int integer_part = 0;//floor(src_1);
  58.      unsigned int fraction_part = ((int)((src_1 - integer_part) * factor)) & (factor - 1) ;
  59.  
  60.      output_value = (integer_part << out_frac_bits) | fraction_part;
  61.  
  62.      if(negative_flag)
  63.          output_value = (~output_value + 1) & ((1 <<(out_int_bits + out_frac_bits)) -1);
  64.  
  65.      if(out_sign_flag == 1 && negative_flag)
  66.      {
  67.           output_value |= negative_flag <<(out_int_bits + out_frac_bits);
  68.      }
  69.      return output_value;
  70. }
  71.  
  72. void hsw_veb_dndi_table(VADriverContextP ctx, struct intel_vebox_context *proc_ctx)
  73. {
  74.     unsigned int* p_table ;
  75.     /*
  76.     VAProcFilterParameterBufferDeinterlacing *di_param =
  77.             (VAProcFilterParameterBufferDeinterlacing *) proc_ctx->filter_di;
  78.  
  79.     VAProcFilterParameterBuffer * dn_param =
  80.             (VAProcFilterParameterBuffer *) proc_ctx->filter_dn;
  81.     */
  82.     p_table = (unsigned int *)proc_ctx->dndi_state_table.ptr;
  83.  
  84.     *p_table ++ = 0;               // reserved  . w0
  85.     *p_table ++ = ( 0   << 24 |    // denoise STAD threshold . w1
  86.                     128 << 16 |    // dnmh_history_max
  87.                     0   << 12 |    // reserved
  88.                     8   << 8  |    // dnmh_delta[3:0]
  89.                     0 );           // denoise ASD threshold
  90.  
  91.     *p_table ++ = ( 0  << 30 |    // reserved . w2
  92.                     16 << 24 |    // temporal diff th
  93.                     0  << 22 |    // reserved.
  94.                     8  << 16 |    // low temporal diff th
  95.                     0  << 13 |    // STMM C2
  96.                     0  << 8  |    // denoise moving pixel th
  97.                     64 );         // denoise th for sum of complexity measure
  98.  
  99.     *p_table ++ = ( 0 << 30  |   // reserved . w3
  100.                     4 << 24  |   // good neighbor th[5:0]
  101.                     9 << 20  |   // CAT slope minus 1
  102.                     5 << 16  |   // SAD Tight in
  103.                     0 << 14  |   // smooth mv th
  104.                     0 << 12  |   // reserved
  105.                     1 << 8   |   // bne_edge_th[3:0]
  106.                     15 );        // block noise estimate noise th
  107.  
  108.     *p_table ++ = ( 0  << 31  |  // STMM blending constant select. w4
  109.                     64 << 24  |  // STMM trc1
  110.                     0  << 16  |  // STMM trc2
  111.                     0  << 14  |  // reserved
  112.                     2  << 8   |  // VECM_mul
  113.                     128 );       // maximum STMM
  114.  
  115.     *p_table ++ = ( 0  << 24  |  // minumum STMM  . W5
  116.                     0  << 22  |  // STMM shift down
  117.                     0  << 20  |  // STMM shift up
  118.                     7  << 16  |  // STMM output shift
  119.                     128 << 8  |  // SDI threshold
  120.                     8 );         // SDI delta
  121.  
  122.     *p_table ++ = ( 0 << 24  |   // SDI fallback mode 1 T1 constant . W6
  123.                     0 << 16  |   // SDI fallback mode 1 T2 constant
  124.                     0 << 8   |   // SDI fallback mode 2 constant(angle2x1)
  125.                     0 );         // FMD temporal difference threshold
  126.  
  127.     *p_table ++ = ( 32 << 24  |  // FMD #1 vertical difference th . w7
  128.                     32 << 16  |  // FMD #2 vertical difference th
  129.                     1  << 14  |  // CAT th1
  130.                     32 << 8   |  // FMD tear threshold
  131.                     0  << 7   |  // MCDI Enable, use motion compensated deinterlace algorithm
  132.                     0  << 6   |  // progressive DN
  133.                     0  << 4   |  // reserved
  134.                     0  << 3   |  // DN/DI Top First
  135.                     0 );         // reserved
  136.  
  137.     *p_table ++ = ( 0  << 29  |  // reserved . W8
  138.                     0  << 23  |  // dnmh_history_init[5:0]
  139.                     10 << 19  |  // neighborPixel th
  140.                     0  << 18  |  // reserved
  141.                     0  << 16  |  // FMD for 2nd field of previous frame
  142.                     25 << 10  |  // MC pixel consistency th
  143.                     0  << 8   |  // FMD for 1st field for current frame
  144.                     10 << 4   |  // SAD THB
  145.                     5 );         // SAD THA
  146.  
  147.     *p_table ++ = ( 0 << 24  |  // reserved
  148.                     0 << 16  |  // chr_dnmh_stad_th
  149.                     0 << 13  |  // reserved
  150.                     0 << 12  |  // chrome denoise enable
  151.                     0 << 6   |  // chr temp diff th
  152.                     0 );        // chr temp diff low
  153.  
  154. }
  155.  
  156. void hsw_veb_iecp_std_table(VADriverContextP ctx, struct intel_vebox_context *proc_ctx)
  157. {
  158.     unsigned int *p_table = proc_ctx->iecp_state_table.ptr + 0 ;
  159.     /*
  160.       VAProcFilterParameterBuffer * std_param =
  161.              (VAProcFilterParameterBuffer *) proc_ctx->filter_std;
  162.     */
  163.     if(!(proc_ctx->filters_mask & VPP_IECP_STD_STE)){
  164.         memset(p_table, 0, 29 * 4);
  165.     }else{
  166.         *p_table ++ = 0x9a6e39f0;
  167.         *p_table ++ = 0x400c0000;
  168.         *p_table ++ = 0x00001180;
  169.         *p_table ++ = 0xfe2f2e00;
  170.         *p_table ++ = 0x000000ff;
  171.  
  172.         *p_table ++ = 0x00140000;
  173.         *p_table ++ = 0xd82e0000;
  174.         *p_table ++ = 0x8285ecec;
  175.         *p_table ++ = 0x00008282;
  176.         *p_table ++ = 0x00000000;
  177.  
  178.         *p_table ++ = 0x02117000;
  179.         *p_table ++ = 0xa38fec96;
  180.         *p_table ++ = 0x0000c8c8;
  181.         *p_table ++ = 0x00000000;
  182.         *p_table ++ = 0x01478000;
  183.  
  184.         *p_table ++ = 0x0007c306;
  185.         *p_table ++ = 0x00000000;
  186.         *p_table ++ = 0x00000000;
  187.         *p_table ++ = 0x1c1bd000;
  188.         *p_table ++ = 0x00000000;
  189.  
  190.         *p_table ++ = 0x00000000;
  191.         *p_table ++ = 0x00000000;
  192.         *p_table ++ = 0x0007cf80;
  193.         *p_table ++ = 0x00000000;
  194.         *p_table ++ = 0x00000000;
  195.  
  196.         *p_table ++ = 0x1c080000;
  197.         *p_table ++ = 0x00000000;
  198.         *p_table ++ = 0x00000000;
  199.         *p_table ++ = 0x00000000;
  200.     }
  201. }
  202.  
  203. void hsw_veb_iecp_ace_table(VADriverContextP ctx, struct intel_vebox_context *proc_ctx)
  204. {
  205.    unsigned int *p_table = (unsigned int*)(proc_ctx->iecp_state_table.ptr + 116);
  206.  
  207.     if(!(proc_ctx->filters_mask & VPP_IECP_ACE)){
  208.         memset(p_table, 0, 13 * 4);
  209.     }else{
  210.         *p_table ++ = 0x00000068;
  211.         *p_table ++ = 0x4c382410;
  212.         *p_table ++ = 0x9c887460;
  213.         *p_table ++ = 0xebd8c4b0;
  214.         *p_table ++ = 0x604c3824;
  215.  
  216.         *p_table ++ = 0xb09c8874;
  217.         *p_table ++ = 0x0000d8c4;
  218.         *p_table ++ = 0x00000000;
  219.         *p_table ++ = 0x00000000;
  220.         *p_table ++ = 0x00000000;
  221.  
  222.         *p_table ++ = 0x00000000;
  223.         *p_table ++ = 0x00000000;
  224.         *p_table ++ = 0x00000000;
  225.    }
  226. }
  227.  
  228. void hsw_veb_iecp_tcc_table(VADriverContextP ctx, struct intel_vebox_context *proc_ctx)
  229. {
  230.     unsigned int *p_table = (unsigned int*)(proc_ctx->iecp_state_table.ptr + 168);
  231.     /*
  232.       VAProcFilterParameterBuffer * tcc_param =
  233.               (VAProcFilterParameterBuffer *) proc_ctx->filter_iecp_tcc;
  234.    */
  235.    if(!(proc_ctx->filters_mask & VPP_IECP_TCC)){
  236.         memset(p_table, 0, 11 * 4);
  237.     }else{
  238.         *p_table ++ = 0x00000000;
  239.         *p_table ++ = 0x00000000;
  240.         *p_table ++ = 0x1e34cc91;
  241.         *p_table ++ = 0x3e3cce91;
  242.         *p_table ++ = 0x02e80195;
  243.  
  244.         *p_table ++ = 0x0197046b;
  245.         *p_table ++ = 0x01790174;
  246.         *p_table ++ = 0x00000000;
  247.         *p_table ++ = 0x00000000;
  248.         *p_table ++ = 0x03030000;
  249.  
  250.         *p_table ++ = 0x009201c0;
  251.    }
  252. }
  253.  
  254. void hsw_veb_iecp_pro_amp_table(VADriverContextP ctx, struct intel_vebox_context *proc_ctx)
  255. {
  256.     unsigned int contrast = 0x80;  //default
  257.     int brightness = 0x00;         //default
  258.     int cos_c_s    = 256 ;         //default
  259.     int sin_c_s    = 0;            //default
  260.     unsigned int *p_table = (unsigned int*)(proc_ctx->iecp_state_table.ptr + 212);
  261.  
  262.     if(!(proc_ctx->filters_mask & VPP_IECP_PRO_AMP)){
  263.         memset(p_table, 0, 2 * 4);
  264.     }else {
  265.         float  tmp_value = 0.0;
  266.         float  src_saturation = 1.0;
  267.         float  src_hue = 0.0;
  268.         float  src_contrast   = 1.0;
  269.         /*
  270.         float  src_brightness = 0.0;
  271.  
  272.         VAProcFilterParameterBufferColorBalance * amp_param =
  273.         (VAProcFilterParameterBufferColorBalance *) proc_ctx->filter_iecp_amp;
  274.         VAProcColorBalanceType attrib = amp_param->attrib;
  275.  
  276.         if(attrib == VAProcColorBalanceHue) {
  277.            src_hue = amp_param->value;         //(-180.0, 180.0)
  278.         }else if(attrib == VAProcColorBalanceSaturation) {
  279.            src_saturation = amp_param->value; //(0.0, 10.0)
  280.         }else if(attrib == VAProcColorBalanceBrightness) {
  281.            src_brightness = amp_param->value; // (-100.0, 100.0)
  282.            brightness = format_convert(src_brightness, 7, 4, 1);
  283.         }else if(attrib == VAProcColorBalanceContrast) {
  284.            src_contrast = amp_param->value;  //  (0.0, 10.0)
  285.            contrast = format_convert(src_contrast, 4, 7, 0);
  286.         }
  287.         */
  288.         tmp_value = cos(src_hue/180*PI) * src_contrast * src_saturation;
  289.         cos_c_s = format_convert(tmp_value, 7, 8, 1);
  290.        
  291.         tmp_value = sin(src_hue/180*PI) * src_contrast * src_saturation;
  292.         sin_c_s = format_convert(tmp_value, 7, 8, 1);
  293.      
  294.         *p_table ++ = ( 0 << 28 |         //reserved
  295.                         contrast << 17 |  //contrast value (U4.7 format)
  296.                         0 << 13 |         //reserved
  297.                         brightness << 1|  // S7.4 format
  298.                         1);
  299.  
  300.         *p_table ++ = ( cos_c_s << 16 |  // cos(h) * contrast * saturation
  301.                         sin_c_s);        // sin(h) * contrast * saturation
  302.                  
  303.     }
  304. }
  305.  
  306.  
  307. void hsw_veb_iecp_csc_table(VADriverContextP ctx, struct intel_vebox_context *proc_ctx)
  308. {
  309.     unsigned int *p_table = (unsigned int*)(proc_ctx->iecp_state_table.ptr + 220);
  310.     float tran_coef[9] = {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0};
  311.     float v_coef[3]    = {0.0, 0.0, 0.0};
  312.     float u_coef[3]    = {0.0, 0.0, 0.0};
  313.     int   is_transform_enabled = 0;
  314.  
  315.     if(!(proc_ctx->filters_mask & VPP_IECP_CSC)){
  316.         memset(p_table, 0, 8 * 4);
  317.         return;
  318.     }
  319.     /*
  320.     VAProcColorStandardType   in_color_std  = proc_ctx->pipeline_param->surface_color_standard;
  321.     VAProcColorStandardType   out_color_std = proc_ctx->pipeline_param->output_color_standard;
  322.     assert(in_color_std == out_color_std);  
  323.     */
  324.     if(proc_ctx->fourcc_input == VA_FOURCC('R','G','B','A') &&
  325.        (proc_ctx->fourcc_output == VA_FOURCC('N','V','1','2') ||
  326.         proc_ctx->fourcc_output == VA_FOURCC('Y','V','1','2') ||
  327.         proc_ctx->fourcc_output == VA_FOURCC('Y','V','Y','2') ||
  328.         proc_ctx->fourcc_output == VA_FOURCC('A','Y','U','V'))) {
  329.  
  330.          tran_coef[0] = 0.257;
  331.          tran_coef[1] = 0.504;
  332.          tran_coef[2] = 0.098;
  333.          tran_coef[3] = -0.148;
  334.          tran_coef[4] = -0.291;
  335.          tran_coef[5] = 0.439;
  336.          tran_coef[6] = 0.439;
  337.          tran_coef[7] = -0.368;
  338.          tran_coef[8] = -0.071;
  339.  
  340.          u_coef[0] = 16 * 4;
  341.          u_coef[1] = 128 * 4;
  342.          u_coef[2] = 128 * 4;
  343.  
  344.          is_transform_enabled = 1;
  345.     }else if((proc_ctx->fourcc_input  == VA_FOURCC('N','V','1','2') ||
  346.               proc_ctx->fourcc_input  == VA_FOURCC('Y','V','1','2') ||
  347.               proc_ctx->fourcc_input  == VA_FOURCC('Y','U','Y','2') ||
  348.               proc_ctx->fourcc_input  == VA_FOURCC('A','Y','U','V'))&&
  349.               proc_ctx->fourcc_output == VA_FOURCC('R','G','B','A')) {
  350.  
  351.          tran_coef[0] = 1.164;
  352.          tran_coef[1] = 0.000;
  353.          tran_coef[2] = 1.569;
  354.          tran_coef[3] = 1.164;
  355.          tran_coef[4] = -0.813;
  356.          tran_coef[5] = -0.392;
  357.          tran_coef[6] = 1.164;
  358.          tran_coef[7] = 2.017;
  359.          tran_coef[8] = 0.000;
  360.  
  361.          v_coef[0] = -16 * 4;
  362.          v_coef[1] = -128 * 4;
  363.          v_coef[2] = -128 * 4;
  364.  
  365.         is_transform_enabled = 1;
  366.     }else if(proc_ctx->fourcc_input != proc_ctx->fourcc_output){
  367.          //enable when input and output format are different.
  368.          is_transform_enabled = 1;
  369.     }
  370.  
  371.     if(is_transform_enabled == 0){
  372.         memset(p_table, 0, 8 * 4);
  373.     }else{
  374.         *p_table ++ = ( 0 << 29 | //reserved
  375.                         format_convert(tran_coef[1], 2, 10, 1) << 16 | //c1, s2.10 format
  376.                         format_convert(tran_coef[0], 2, 10, 1) << 3 |  //c0, s2.10 format
  377.                         0 << 2 | //reserved
  378.                         0 << 1 | // yuv_channel swap
  379.                         is_transform_enabled);                
  380.  
  381.         *p_table ++ = ( 0 << 26 | //reserved
  382.                         format_convert(tran_coef[3], 2, 10, 1) << 13 |
  383.                         format_convert(tran_coef[2], 2, 10, 1));
  384.    
  385.         *p_table ++ = ( 0 << 26 | //reserved
  386.                         format_convert(tran_coef[5], 2, 10, 1) << 13 |
  387.                         format_convert(tran_coef[4], 2, 10, 1));
  388.  
  389.         *p_table ++ = ( 0 << 26 | //reserved
  390.                         format_convert(tran_coef[7], 2, 10, 1) << 13 |
  391.                         format_convert(tran_coef[6], 2, 10, 1));
  392.  
  393.         *p_table ++ = ( 0 << 13 | //reserved
  394.                         format_convert(tran_coef[8], 2, 10, 1));
  395.  
  396.         *p_table ++ = ( 0 << 22 | //reserved
  397.                         format_convert(u_coef[0], 10, 0, 1) << 11 |
  398.                         format_convert(v_coef[0], 10, 0, 1));
  399.  
  400.         *p_table ++ = ( 0 << 22 | //reserved
  401.                         format_convert(u_coef[1], 10, 0, 1) << 11 |
  402.                         format_convert(v_coef[1], 10, 0, 1));
  403.  
  404.         *p_table ++ = ( 0 << 22 | //reserved
  405.                         format_convert(u_coef[2], 10, 0, 1) << 11 |
  406.                         format_convert(v_coef[2], 10, 0, 1));
  407.     }
  408. }
  409.  
  410. void hsw_veb_iecp_aoi_table(VADriverContextP ctx, struct intel_vebox_context *proc_ctx)
  411. {
  412.     unsigned int *p_table = (unsigned int*)(proc_ctx->iecp_state_table.ptr + 252);
  413.     /*
  414.      VAProcFilterParameterBuffer * tcc_param =
  415.              (VAProcFilterParameterBuffer *) proc_ctx->filter_iecp_tcc;
  416.     */
  417.     if(!(proc_ctx->filters_mask & VPP_IECP_AOI)){
  418.         memset(p_table, 0, 3 * 4);
  419.     }else{
  420.         *p_table ++ = 0x00000000;
  421.         *p_table ++ = 0x00030000;
  422.         *p_table ++ = 0x00030000;
  423.    }
  424. }
  425.  
  426. void hsw_veb_state_table_setup(VADriverContextP ctx, struct intel_vebox_context *proc_ctx)
  427. {
  428.     if(proc_ctx->filters_mask & 0x000000ff) {
  429.         dri_bo *dndi_bo = proc_ctx->dndi_state_table.bo;
  430.         dri_bo_map(dndi_bo, 1);
  431.         proc_ctx->dndi_state_table.ptr = dndi_bo->virtual;
  432.  
  433.         hsw_veb_dndi_table(ctx, proc_ctx);
  434.  
  435.         dri_bo_unmap(dndi_bo);
  436.     }
  437.  
  438.     if(proc_ctx->filters_mask & 0x0000ff00 ||
  439.        proc_ctx->fourcc_input != proc_ctx->fourcc_output) {
  440.         dri_bo *iecp_bo = proc_ctx->iecp_state_table.bo;
  441.         dri_bo_map(iecp_bo, 1);
  442.         proc_ctx->iecp_state_table.ptr = iecp_bo->virtual;
  443.  
  444.         hsw_veb_iecp_std_table(ctx, proc_ctx);
  445.         hsw_veb_iecp_ace_table(ctx, proc_ctx);
  446.         hsw_veb_iecp_tcc_table(ctx, proc_ctx);
  447.         hsw_veb_iecp_pro_amp_table(ctx, proc_ctx);
  448.         hsw_veb_iecp_csc_table(ctx, proc_ctx);
  449.         hsw_veb_iecp_aoi_table(ctx, proc_ctx);
  450.    
  451.         dri_bo_unmap(iecp_bo);
  452.     }
  453. }
  454.  
  455. void hsw_veb_state_command(VADriverContextP ctx, struct intel_vebox_context *proc_ctx)
  456. {
  457.     struct intel_batchbuffer *batch = proc_ctx->batch;
  458.     unsigned int is_dn_enabled   = (proc_ctx->filters_mask & 0x01)? 1: 0;
  459.     unsigned int is_di_enabled   = (proc_ctx->filters_mask & 0x02)? 1: 0;
  460.     unsigned int is_iecp_enabled = (proc_ctx->filters_mask & 0xff00)?1:0;
  461.  
  462.     BEGIN_VEB_BATCH(batch, 6);
  463.     OUT_VEB_BATCH(batch, VEB_STATE | (6 - 2));
  464.     OUT_VEB_BATCH(batch,
  465.                   0 << 26 |       // state surface control bits
  466.                   0 << 11 |       // reserved.
  467.                   0 << 10 |       // pipe sync disable
  468.                   2 << 8  |       // DI output frame
  469.                   0 << 7  |       // 444->422 downsample method
  470.                   0 << 6  |       // 422->420 downsample method
  471.                   !!(proc_ctx->is_first_frame && (is_di_enabled || is_dn_enabled)) << 5  |   // DN/DI first frame
  472.                   is_di_enabled   << 4  |             // DI enable
  473.                   is_dn_enabled   << 3  |             // DN enable
  474.                   is_iecp_enabled << 2  |             // global IECP enabled
  475.                   0 << 1  |       // ColorGamutCompressionEnable
  476.                   0 ) ;           // ColorGamutExpansionEnable.
  477.  
  478.     OUT_RELOC(batch,
  479.               proc_ctx->dndi_state_table.bo,
  480.               I915_GEM_DOMAIN_INSTRUCTION, 0, 0);
  481.  
  482.     OUT_RELOC(batch,
  483.               proc_ctx->iecp_state_table.bo,
  484.               I915_GEM_DOMAIN_INSTRUCTION, 0, 0);
  485.  
  486.     OUT_RELOC(batch,
  487.               proc_ctx->gamut_state_table.bo,
  488.               I915_GEM_DOMAIN_INSTRUCTION, 0, 0);
  489.  
  490.     OUT_RELOC(batch,
  491.               proc_ctx->vertex_state_table.bo,
  492.               I915_GEM_DOMAIN_INSTRUCTION, 0, 0);
  493.  
  494.     ADVANCE_VEB_BATCH(batch);
  495. }
  496.  
  497. void hsw_veb_surface_state(VADriverContextP ctx, struct intel_vebox_context *proc_ctx, unsigned int is_output)
  498. {
  499.     struct  i965_driver_data *i965 = i965_driver_data(ctx);
  500.     struct intel_batchbuffer *batch = proc_ctx->batch;
  501.     unsigned int u_offset_y = 0, v_offset_y = 0;
  502.     unsigned int is_uv_interleaved = 0, tiling = 0, swizzle = 0;
  503.     unsigned int surface_format = PLANAR_420_8;
  504.     struct object_surface* obj_surf = NULL;
  505.     unsigned int surface_pitch = 0;
  506.     unsigned int half_pitch_chroma = 0;
  507.  
  508.     if(is_output){  
  509.          obj_surf = SURFACE(proc_ctx->frame_store[FRAME_OUT_CURRENT].surface_id);
  510.     }else {
  511.          obj_surf = SURFACE(proc_ctx->frame_store[FRAME_IN_CURRENT].surface_id);
  512.     }
  513.  
  514.     if (obj_surf->fourcc == VA_FOURCC_NV12) {
  515.         surface_format = PLANAR_420_8;
  516.         surface_pitch = obj_surf->width;
  517.         printf("NV12, is_output=%d, width = %d, pitch is =  %d\n",is_output, obj_surf->orig_width, obj_surf->width);
  518.         is_uv_interleaved = 1;
  519.         half_pitch_chroma = 0;
  520.     } else if (obj_surf->fourcc == VA_FOURCC_YUY2) {
  521.         surface_format = YCRCB_NORMAL;
  522.         surface_pitch = obj_surf->width * 2;
  523.         is_uv_interleaved = 0;
  524.         half_pitch_chroma = 0;
  525.     } else if (obj_surf->fourcc == VA_FOURCC_AYUV) {
  526.         surface_format = PACKED_444A_8;
  527.         surface_pitch = obj_surf->width * 4;
  528.         is_uv_interleaved = 0;
  529.         half_pitch_chroma = 0;
  530.     } else if (obj_surf->fourcc == VA_FOURCC_RGBA) {
  531.         surface_format = R8G8B8A8_UNORM_SRGB;
  532.         surface_pitch = obj_surf->width * 4;
  533.         is_uv_interleaved = 0;
  534.         half_pitch_chroma = 0;
  535.     }
  536.  
  537.     u_offset_y = obj_surf->y_cb_offset;
  538.     v_offset_y = obj_surf->y_cr_offset;
  539.      
  540.     dri_bo_get_tiling(obj_surf->bo, &tiling, &swizzle);
  541.  
  542.     BEGIN_VEB_BATCH(batch, 6);
  543.     OUT_VEB_BATCH(batch, VEB_SURFACE_STATE | (6 - 2));
  544.     OUT_VEB_BATCH(batch,
  545.                   0 << 1 |         // reserved
  546.                   is_output);      // surface indentification.
  547.  
  548.     OUT_VEB_BATCH(batch,
  549.                   (proc_ctx->pic_height - 1) << 18 |  // height . w3
  550.                   (proc_ctx->pic_width )  << 4  |  // width
  551.                   0);                                 // reserve
  552.  
  553.     OUT_VEB_BATCH(batch,
  554.                   surface_format      << 28  |  // surface format, YCbCr420. w4
  555.                   is_uv_interleaved   << 27  |  // interleave chrome , two seperate palar
  556.                   0                   << 20  |  // reserved
  557.                   (surface_pitch - 1) << 3   |  // surface pitch, 64 align
  558.                   half_pitch_chroma   << 2   |  // half pitch for chrome
  559.                   !!tiling            << 1   |  // tiled surface, linear surface used
  560.                   (tiling == I915_TILING_Y));   // tiled walk, ignored when liner surface
  561.  
  562.     OUT_VEB_BATCH(batch,
  563.                   0 << 29  |     // reserved . w5
  564.                   0 << 16  |     // X offset for V(Cb)
  565.                   0 << 15  |     // reserved
  566.                   u_offset_y);   // Y offset for V(Cb)
  567.  
  568.     OUT_VEB_BATCH(batch,
  569.                   0 << 29  |     // reserved . w6
  570.                   0 << 16  |     // X offset for V(Cr)
  571.                   0 << 15  |     // reserved
  572.                   v_offset_y );  // Y offset for V(Cr)
  573.  
  574.     ADVANCE_VEB_BATCH(batch);
  575. }
  576.  
  577. void hsw_veb_dndi_iecp_command(VADriverContextP ctx, struct intel_vebox_context *proc_ctx)
  578. {
  579.     struct intel_batchbuffer *batch = proc_ctx->batch;
  580.     unsigned char frame_ctrl_bits = 0;
  581.     unsigned int startingX = 0;
  582.     unsigned int endingX = proc_ctx->pic_width;
  583.  
  584.     BEGIN_VEB_BATCH(batch, 10);
  585.     OUT_VEB_BATCH(batch, VEB_DNDI_IECP_STATE | (10 - 2));
  586.     OUT_VEB_BATCH(batch,
  587.                   startingX << 16 |
  588.                   endingX);
  589.     OUT_RELOC(batch,
  590.               proc_ctx->frame_store[FRAME_IN_CURRENT].bo,
  591.               I915_GEM_DOMAIN_RENDER, 0, frame_ctrl_bits);
  592.     OUT_RELOC(batch,
  593.               proc_ctx->frame_store[FRAME_IN_PREVIOUS].bo,
  594.               I915_GEM_DOMAIN_RENDER, 0, frame_ctrl_bits);
  595.     OUT_RELOC(batch,
  596.               proc_ctx->frame_store[FRAME_IN_STMM].bo,
  597.               I915_GEM_DOMAIN_RENDER, 0, frame_ctrl_bits);
  598.     OUT_RELOC(batch,
  599.               proc_ctx->frame_store[FRAME_OUT_STMM].bo,
  600.               I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, frame_ctrl_bits);
  601.     OUT_RELOC(batch,
  602.               proc_ctx->frame_store[FRAME_OUT_CURRENT_DN].bo,
  603.               I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, frame_ctrl_bits);
  604.     OUT_RELOC(batch,
  605.               proc_ctx->frame_store[FRAME_OUT_CURRENT].bo,
  606.               I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, frame_ctrl_bits);
  607.     OUT_RELOC(batch,
  608.               proc_ctx->frame_store[FRAME_OUT_PREVIOUS].bo,
  609.               I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, frame_ctrl_bits);
  610.     OUT_RELOC(batch,
  611.               proc_ctx->frame_store[FRAME_OUT_STATISTIC].bo,
  612.               I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, frame_ctrl_bits);
  613.  
  614.     ADVANCE_VEB_BATCH(batch);
  615. }
  616.  
  617.  
  618. void hsw_veb_surface_reference(VADriverContextP ctx,
  619.                               struct intel_vebox_context *proc_ctx)
  620. {
  621.     struct object_surface * obj_surf;
  622.     struct i965_driver_data *i965 = i965_driver_data(ctx);
  623.  
  624.     /* update the input surface */
  625.      obj_surf = SURFACE(proc_ctx->surface_input);
  626.      proc_ctx->frame_store[FRAME_IN_CURRENT].surface_id = proc_ctx->surface_input;
  627.      proc_ctx->frame_store[FRAME_IN_CURRENT].bo = obj_surf->bo;
  628.      proc_ctx->frame_store[FRAME_IN_CURRENT].is_internal_surface = 0;
  629.      dri_bo_reference(proc_ctx->frame_store[FRAME_IN_CURRENT].bo);
  630.  
  631.      /* update the output surface */
  632.      if(proc_ctx->filters_mask == VPP_DNDI_DN){
  633.          obj_surf = SURFACE(proc_ctx->surface_output);
  634.          proc_ctx->frame_store[FRAME_OUT_CURRENT_DN].surface_id = proc_ctx->surface_output;
  635.          proc_ctx->frame_store[FRAME_OUT_CURRENT_DN].bo = obj_surf->bo;
  636.          proc_ctx->frame_store[FRAME_OUT_CURRENT_DN].is_internal_surface = 0;
  637.          dri_bo_reference(proc_ctx->frame_store[FRAME_OUT_CURRENT_DN].bo);
  638.      }else {
  639.          obj_surf = SURFACE(proc_ctx->surface_output);
  640.          proc_ctx->frame_store[FRAME_OUT_CURRENT].surface_id = proc_ctx->surface_output;
  641.          proc_ctx->frame_store[FRAME_OUT_CURRENT].bo = obj_surf->bo;
  642.          proc_ctx->frame_store[FRAME_OUT_CURRENT].is_internal_surface = 0;
  643.          dri_bo_reference(proc_ctx->frame_store[FRAME_OUT_CURRENT].bo);
  644.      }
  645. }
  646.  
  647. void hsw_veb_surface_unreference(VADriverContextP ctx,
  648.                                  struct intel_vebox_context *proc_ctx)
  649. {
  650.     /* unreference the input surface */
  651.     dri_bo_unreference(proc_ctx->frame_store[FRAME_IN_CURRENT].bo);
  652.     proc_ctx->frame_store[FRAME_IN_CURRENT].surface_id = -1;
  653.     proc_ctx->frame_store[FRAME_IN_CURRENT].bo = NULL;
  654.     proc_ctx->frame_store[FRAME_IN_CURRENT].is_internal_surface = 0;
  655.     dri_bo_unreference(proc_ctx->frame_store[FRAME_IN_CURRENT].bo);
  656.  
  657.     /* unreference the shared output surface */
  658.     if(proc_ctx->filters_mask == VPP_DNDI_DN){
  659.        proc_ctx->frame_store[FRAME_OUT_CURRENT_DN].surface_id = -1;
  660.        proc_ctx->frame_store[FRAME_OUT_CURRENT_DN].bo = NULL;
  661.        proc_ctx->frame_store[FRAME_OUT_CURRENT_DN].is_internal_surface = 0;
  662.        dri_bo_unreference(proc_ctx->frame_store[FRAME_OUT_CURRENT_DN].bo);
  663.     }else{
  664.         proc_ctx->frame_store[FRAME_OUT_CURRENT].surface_id = -1;
  665.         proc_ctx->frame_store[FRAME_OUT_CURRENT].bo = NULL;
  666.         proc_ctx->frame_store[FRAME_OUT_CURRENT].is_internal_surface = 0;
  667.         dri_bo_unreference(proc_ctx->frame_store[FRAME_OUT_CURRENT].bo);
  668.      }
  669. }
  670.  
  671. void hsw_veb_resource_prepare(VADriverContextP ctx,
  672.                               struct intel_vebox_context *proc_ctx)
  673. {
  674.     VAStatus va_status;
  675.     dri_bo *bo;
  676.     struct i965_driver_data *i965 = i965_driver_data(ctx);
  677.     unsigned int input_fourcc, output_fourcc;
  678.     unsigned int input_sampling, output_sampling;
  679.     unsigned int input_tiling, output_tiling;
  680.     unsigned int i, swizzle;
  681.  
  682.     struct object_surface* obj_surf_in  = SURFACE(proc_ctx->surface_input);
  683.     struct object_surface* obj_surf_out = SURFACE(proc_ctx->surface_output);
  684.    
  685.     assert(obj_surf_in->orig_width  == obj_surf_out->orig_width &&
  686.            obj_surf_in->orig_height == obj_surf_out->orig_height);
  687.  
  688.     proc_ctx->pic_width   = obj_surf_in->orig_width;
  689.     proc_ctx->pic_height  = obj_surf_in->orig_height;
  690.  
  691.     /* record vebox pipeline input surface format information*/
  692.     if(obj_surf_in->bo == NULL){
  693.         input_fourcc = VA_FOURCC('N','V','1','2');
  694.         input_sampling = SUBSAMPLE_YUV420;
  695.         input_tiling = 1;
  696.         i965_check_alloc_surface_bo(ctx, obj_surf_in, input_tiling, input_fourcc, input_sampling);
  697.     } else {
  698.         input_fourcc = obj_surf_in->fourcc;
  699.         input_sampling = obj_surf_in->subsampling;
  700.         dri_bo_get_tiling(obj_surf_in->bo, &input_tiling, &swizzle);
  701.         input_tiling = !!input_tiling;
  702.     }
  703.  
  704.     /* record vebox pipeline output surface format information */
  705.     if(obj_surf_out->bo == NULL){
  706.         output_fourcc = VA_FOURCC('N','V','1','2');
  707.         output_sampling = SUBSAMPLE_YUV420;
  708.         output_tiling = 1;
  709.         i965_check_alloc_surface_bo(ctx, obj_surf_out, output_tiling, output_fourcc, output_sampling);
  710.     }else {
  711.         output_fourcc   = obj_surf_out->fourcc;
  712.         output_sampling = obj_surf_out->subsampling;
  713.         dri_bo_get_tiling(obj_surf_out->bo, &output_tiling, &swizzle);
  714.         output_tiling = !!output_tiling;
  715.     }
  716.    
  717.     assert(input_fourcc == VA_FOURCC_NV12 ||
  718.            input_fourcc == VA_FOURCC_YUY2 ||
  719.            input_fourcc == VA_FOURCC_AYUV ||
  720.            input_fourcc == VA_FOURCC_RGBA);
  721.     assert(output_fourcc == VA_FOURCC_NV12 ||
  722.            output_fourcc == VA_FOURCC_YUY2 ||
  723.            output_fourcc == VA_FOURCC_AYUV ||
  724.            output_fourcc == VA_FOURCC_RGBA);
  725.  
  726.     proc_ctx->fourcc_input = input_fourcc;
  727.     proc_ctx->fourcc_output = output_fourcc;
  728.  
  729.     /* allocate vebox pipeline surfaces */
  730.     VASurfaceID surfaces[FRAME_STORE_SUM];
  731.     va_status = i965_CreateSurfaces(ctx,
  732.                                    proc_ctx ->pic_width,
  733.                                    proc_ctx ->pic_height,
  734.                                    VA_RT_FORMAT_YUV420,
  735.                                    FRAME_STORE_SUM,
  736.                                    surfaces);
  737.     assert(va_status == VA_STATUS_SUCCESS);
  738.  
  739.     for(i = FRAME_IN_CURRENT; i < FRAME_STORE_SUM; i ++) {
  740.         proc_ctx->frame_store[i].surface_id = surfaces[i];
  741.         struct object_surface* obj_surf = SURFACE(surfaces[i]);
  742.         if( i == FRAME_IN_CURRENT) {
  743.             proc_ctx->frame_store[i].surface_id = proc_ctx->surface_input;
  744.             proc_ctx->frame_store[i].bo = (SURFACE(proc_ctx->surface_input))->bo;
  745.             proc_ctx->frame_store[i].is_internal_surface = 0;
  746.             continue;
  747.         }else if( i == FRAME_IN_PREVIOUS || i == FRAME_OUT_CURRENT_DN) {
  748.             i965_check_alloc_surface_bo(ctx, obj_surf, input_tiling, input_fourcc, input_sampling);
  749.         } else if( i == FRAME_IN_STMM || i == FRAME_OUT_STMM){
  750.             i965_check_alloc_surface_bo(ctx, obj_surf, 1, input_fourcc, input_sampling);
  751.         } else if( i >= FRAME_OUT_CURRENT){
  752.             i965_check_alloc_surface_bo(ctx, obj_surf, output_tiling, output_fourcc, output_sampling);
  753.         }
  754.         proc_ctx->frame_store[i].bo = obj_surf->bo;
  755.         dri_bo_reference(proc_ctx->frame_store[i].bo);
  756.         proc_ctx->frame_store[i].is_internal_surface = 1;
  757.     }
  758.  
  759.     /* alloc dndi state table  */
  760.     dri_bo_unreference(proc_ctx->dndi_state_table.bo);
  761.     bo = dri_bo_alloc(i965->intel.bufmgr,
  762.                       "vebox: dndi state Buffer",
  763.                       0x1000, 0x1000);
  764.     proc_ctx->dndi_state_table.bo = bo;
  765.     dri_bo_reference(proc_ctx->dndi_state_table.bo);
  766.  
  767.     /* alloc iecp state table  */
  768.     dri_bo_unreference(proc_ctx->iecp_state_table.bo);
  769.     bo = dri_bo_alloc(i965->intel.bufmgr,
  770.                       "vebox: iecp state Buffer",
  771.                       0x1000, 0x1000);
  772.     proc_ctx->iecp_state_table.bo = bo;
  773.     dri_bo_reference(proc_ctx->iecp_state_table.bo);
  774.  
  775.     /* alloc gamut state table  */
  776.     dri_bo_unreference(proc_ctx->gamut_state_table.bo);
  777.     bo = dri_bo_alloc(i965->intel.bufmgr,
  778.                       "vebox: gamut state Buffer",
  779.                       0x1000, 0x1000);
  780.     proc_ctx->gamut_state_table.bo = bo;
  781.     dri_bo_reference(proc_ctx->gamut_state_table.bo);
  782.  
  783.     /* alloc vertex state table  */
  784.     dri_bo_unreference(proc_ctx->vertex_state_table.bo);
  785.     bo = dri_bo_alloc(i965->intel.bufmgr,
  786.                       "vertex: iecp state Buffer",
  787.                       0x1000, 0x1000);
  788.     proc_ctx->vertex_state_table.bo = bo;
  789.     dri_bo_reference(proc_ctx->vertex_state_table.bo);
  790.  
  791. }
  792.  
  793. VAStatus gen75_vebox_process_picture(VADriverContextP ctx,
  794.                          struct intel_vebox_context *proc_ctx)
  795. {
  796.     VAStatus va_status = VA_STATUS_SUCCESS;
  797.    
  798.     if(proc_ctx->is_first_frame)
  799.        hsw_veb_resource_prepare(ctx, proc_ctx);
  800.  
  801.     hsw_veb_surface_reference(ctx, proc_ctx);
  802.  
  803.     intel_batchbuffer_start_atomic_veb(proc_ctx->batch, 0x1000);
  804.     intel_batchbuffer_emit_mi_flush(proc_ctx->batch);
  805.     hsw_veb_surface_state(ctx, proc_ctx, INPUT_SURFACE);
  806.     hsw_veb_surface_state(ctx, proc_ctx, OUTPUT_SURFACE);
  807.     hsw_veb_state_table_setup(ctx, proc_ctx);
  808.  
  809.     hsw_veb_state_command(ctx, proc_ctx);              
  810.     hsw_veb_dndi_iecp_command(ctx, proc_ctx);
  811.     intel_batchbuffer_end_atomic(proc_ctx->batch);
  812.     intel_batchbuffer_flush(proc_ctx->batch);
  813.  
  814.     hsw_veb_surface_unreference(ctx, proc_ctx);
  815.  
  816.    if(proc_ctx->is_first_frame)
  817.        proc_ctx->is_first_frame = 0;
  818.    
  819.     return va_status;
  820. }
  821.  
  822. void gen75_vebox_context_destroy(VADriverContextP ctx,
  823.                           struct intel_vebox_context *proc_ctx)
  824. {
  825.     int i;
  826.     /* release vebox pipeline surface */
  827.     for(i = 0; i < FRAME_STORE_SUM; i ++) {
  828.         if(proc_ctx->frame_store[i].is_internal_surface){
  829.             dri_bo_unreference(proc_ctx->frame_store[i].bo);
  830.         }
  831.         proc_ctx->frame_store[i].surface_id = -1;
  832.         proc_ctx->frame_store[i].bo = NULL;
  833.     }
  834.     /* release dndi state table  */
  835.     dri_bo_unreference(proc_ctx->dndi_state_table.bo);
  836.     proc_ctx->dndi_state_table.bo = NULL;
  837.  
  838.     /* release iecp state table  */
  839.     dri_bo_unreference(proc_ctx->iecp_state_table.bo);
  840.     proc_ctx->dndi_state_table.bo = NULL;
  841.  
  842.     intel_batchbuffer_free(proc_ctx->batch);
  843.  
  844.     free(proc_ctx);
  845. }
  846.  
  847. struct intel_vebox_context * gen75_vebox_context_init(VADriverContextP ctx)
  848. {
  849.     struct intel_driver_data *intel = intel_driver_data(ctx);
  850.     struct intel_vebox_context *proc_context = calloc(1, sizeof(struct intel_vebox_context));
  851.  
  852.     proc_context->batch = intel_batchbuffer_new(intel, I915_EXEC_VEBOX, 0);
  853.     memset(proc_context->frame_store, 0, sizeof(VEBFrameStore)*FRAME_STORE_SUM);
  854.  
  855.     proc_context->filters_mask             = 0;
  856.     proc_context->is_first_frame           = 1;
  857.     proc_context->filters_mask             = 0;
  858.  
  859.     return proc_context;
  860. }
  861.  
  862.