Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /*
  2.  * Copyright © 2012 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.  *    Zhao Yakui <yakui.zhao@intel.com>
  26.  *    Xiang Haihao <haihao.xiang@intel.com>
  27.  */
  28.  
  29. #include <stdio.h>
  30. #include <stdlib.h>
  31. #include <stdbool.h>
  32. #include <string.h>
  33. #include <assert.h>
  34.  
  35. #include "intel_batchbuffer.h"
  36. #include "intel_driver.h"
  37.  
  38. #include "i965_defines.h"
  39. #include "i965_drv_video.h"
  40. #include "i965_encoder.h"
  41. #include "gen6_vme.h"
  42. #include "gen6_mfc.h"
  43.  
  44. #ifdef SURFACE_STATE_PADDED_SIZE
  45. #undef SURFACE_STATE_PADDED_SIZE
  46. #endif
  47.  
  48. #define SURFACE_STATE_PADDED_SIZE               SURFACE_STATE_PADDED_SIZE_GEN8
  49. #define SURFACE_STATE_OFFSET(index)             (SURFACE_STATE_PADDED_SIZE * index)
  50. #define BINDING_TABLE_OFFSET(index)             (SURFACE_STATE_OFFSET(MAX_MEDIA_SURFACES_GEN6) + sizeof(unsigned int) * index)
  51.  
  52. #define VME_INTRA_SHADER        0
  53. #define VME_INTER_SHADER        1
  54. #define VME_BINTER_SHADER       2
  55.  
  56. #define CURBE_ALLOCATION_SIZE   37              /* in 256-bit */
  57. #define CURBE_TOTAL_DATA_LENGTH (4 * 32)        /* in byte, it should be less than or equal to CURBE_ALLOCATION_SIZE * 32 */
  58. #define CURBE_URB_ENTRY_LENGTH  4               /* in 256-bit, it should be less than or equal to CURBE_TOTAL_DATA_LENGTH / 32 */
  59.  
  60. #define VME_MSG_LENGTH          32
  61.  
  62. static const uint32_t gen8_vme_intra_frame[][4] = {
  63. #include "shaders/vme/intra_frame_gen8.g8b"
  64. };
  65.  
  66. static const uint32_t gen8_vme_inter_frame[][4] = {
  67. #include "shaders/vme/inter_frame_gen8.g8b"
  68. };
  69.  
  70. static const uint32_t gen8_vme_inter_bframe[][4] = {
  71. #include "shaders/vme/inter_bframe_gen8.g8b"
  72. };
  73.  
  74. static struct i965_kernel gen8_vme_kernels[] = {
  75.     {
  76.         "VME Intra Frame",
  77.         VME_INTRA_SHADER, /*index*/
  78.         gen8_vme_intra_frame,                  
  79.         sizeof(gen8_vme_intra_frame),          
  80.         NULL
  81.     },
  82.     {
  83.         "VME inter Frame",
  84.         VME_INTER_SHADER,
  85.         gen8_vme_inter_frame,
  86.         sizeof(gen8_vme_inter_frame),
  87.         NULL
  88.     },
  89.     {
  90.         "VME inter BFrame",
  91.         VME_BINTER_SHADER,
  92.         gen8_vme_inter_bframe,
  93.         sizeof(gen8_vme_inter_bframe),
  94.         NULL
  95.     }
  96. };
  97.  
  98. static const uint32_t gen8_vme_mpeg2_intra_frame[][4] = {
  99. #include "shaders/vme/intra_frame_gen8.g8b"
  100. };
  101.  
  102. static const uint32_t gen8_vme_mpeg2_inter_frame[][4] = {
  103. #include "shaders/vme/mpeg2_inter_gen8.g8b"
  104. };
  105.  
  106. static struct i965_kernel gen8_vme_mpeg2_kernels[] = {
  107.     {
  108.         "VME Intra Frame",
  109.         VME_INTRA_SHADER, /*index*/
  110.         gen8_vme_mpeg2_intra_frame,                    
  111.         sizeof(gen8_vme_mpeg2_intra_frame),            
  112.         NULL
  113.     },
  114.     {
  115.         "VME inter Frame",
  116.         VME_INTER_SHADER,
  117.         gen8_vme_mpeg2_inter_frame,
  118.         sizeof(gen8_vme_mpeg2_inter_frame),
  119.         NULL
  120.     },
  121. };
  122.  
  123. static const uint32_t gen8_vme_vp8_intra_frame[][4] = {
  124. #include "shaders/vme/vp8_intra_frame_gen8.g8b"
  125. };
  126.  
  127. static const uint32_t gen8_vme_vp8_inter_frame[][4] = {
  128. #include "shaders/vme/vp8_inter_frame_gen8.g8b"
  129. };
  130.  
  131. static struct i965_kernel gen8_vme_vp8_kernels[] = {
  132.     {
  133.         "VME Intra Frame",
  134.         VME_INTRA_SHADER, /*index*/
  135.         gen8_vme_vp8_intra_frame,
  136.         sizeof(gen8_vme_vp8_intra_frame),
  137.         NULL
  138.     },
  139.     {
  140.         "VME inter Frame",
  141.         VME_INTER_SHADER,
  142.         gen8_vme_vp8_inter_frame,
  143.         sizeof(gen8_vme_vp8_inter_frame),
  144.         NULL
  145.     },
  146. };
  147.  
  148. /* only used for VME source surface state */
  149. static void
  150. gen8_vme_source_surface_state(VADriverContextP ctx,
  151.                               int index,
  152.                               struct object_surface *obj_surface,
  153.                               struct intel_encoder_context *encoder_context)
  154. {
  155.     struct gen6_vme_context *vme_context = encoder_context->vme_context;
  156.  
  157.     vme_context->vme_surface2_setup(ctx,
  158.                                     &vme_context->gpe_context,
  159.                                     obj_surface,
  160.                                     BINDING_TABLE_OFFSET(index),
  161.                                     SURFACE_STATE_OFFSET(index));
  162. }
  163.  
  164. static void
  165. gen8_vme_media_source_surface_state(VADriverContextP ctx,
  166.                                     int index,
  167.                                     struct object_surface *obj_surface,
  168.                                     struct intel_encoder_context *encoder_context)
  169. {
  170.     struct gen6_vme_context *vme_context = encoder_context->vme_context;
  171.  
  172.     vme_context->vme_media_rw_surface_setup(ctx,
  173.                                             &vme_context->gpe_context,
  174.                                             obj_surface,
  175.                                             BINDING_TABLE_OFFSET(index),
  176.                                             SURFACE_STATE_OFFSET(index));
  177. }
  178.  
  179. static void
  180. gen8_vme_media_chroma_source_surface_state(VADriverContextP ctx,
  181.                                            int index,
  182.                                            struct object_surface *obj_surface,
  183.                                            struct intel_encoder_context *encoder_context)
  184. {
  185.     struct gen6_vme_context *vme_context = encoder_context->vme_context;
  186.  
  187.     vme_context->vme_media_chroma_surface_setup(ctx,
  188.                                                 &vme_context->gpe_context,
  189.                                                 obj_surface,
  190.                                                 BINDING_TABLE_OFFSET(index),
  191.                                                 SURFACE_STATE_OFFSET(index));
  192. }
  193.  
  194. static void
  195. gen8_vme_output_buffer_setup(VADriverContextP ctx,
  196.                              struct encode_state *encode_state,
  197.                              int index,
  198.                              struct intel_encoder_context *encoder_context,
  199.                              int is_intra,
  200.                              int width_in_mbs,
  201.                              int height_in_mbs)
  202.  
  203. {
  204.     struct i965_driver_data *i965 = i965_driver_data(ctx);
  205.     struct gen6_vme_context *vme_context = encoder_context->vme_context;
  206.  
  207.     vme_context->vme_output.num_blocks = width_in_mbs * height_in_mbs;
  208.     vme_context->vme_output.pitch = 16; /* in bytes, always 16 */
  209.  
  210.     if (is_intra)
  211.         vme_context->vme_output.size_block = INTRA_VME_OUTPUT_IN_BYTES * 2;
  212.     else
  213.         vme_context->vme_output.size_block = INTRA_VME_OUTPUT_IN_BYTES * 24;
  214.     /*
  215.      * Inter MV . 32-byte Intra search + 16 IME info + 128 IME MV + 32 IME Ref
  216.      * + 16 FBR Info + 128 FBR MV + 32 FBR Ref.
  217.      * 16 * (2 + 2 * (1 + 8 + 2))= 16 * 24.
  218.      */
  219.  
  220.     vme_context->vme_output.bo = dri_bo_alloc(i965->intel.bufmgr,
  221.                                               "VME output buffer",
  222.                                               vme_context->vme_output.num_blocks * vme_context->vme_output.size_block,
  223.                                               0x1000);
  224.     assert(vme_context->vme_output.bo);
  225.     vme_context->vme_buffer_suface_setup(ctx,
  226.                                          &vme_context->gpe_context,
  227.                                          &vme_context->vme_output,
  228.                                          BINDING_TABLE_OFFSET(index),
  229.                                          SURFACE_STATE_OFFSET(index));
  230. }
  231.  
  232. static void
  233. gen8_vme_avc_output_buffer_setup(VADriverContextP ctx,
  234.                              struct encode_state *encode_state,
  235.                              int index,
  236.                              struct intel_encoder_context *encoder_context)
  237. {
  238.     VAEncSequenceParameterBufferH264 *pSequenceParameter = (VAEncSequenceParameterBufferH264 *)encode_state->seq_param_ext->buffer;
  239.     VAEncSliceParameterBufferH264 *pSliceParameter = (VAEncSliceParameterBufferH264 *)encode_state->slice_params_ext[0]->buffer;
  240.     int is_intra = pSliceParameter->slice_type == SLICE_TYPE_I;
  241.     int width_in_mbs = pSequenceParameter->picture_width_in_mbs;
  242.     int height_in_mbs = pSequenceParameter->picture_height_in_mbs;
  243.  
  244.     gen8_vme_output_buffer_setup(ctx, encode_state, index, encoder_context, is_intra, width_in_mbs, height_in_mbs);
  245.  
  246. }
  247.  
  248. static void
  249. gen8_vme_output_vme_batchbuffer_setup(VADriverContextP ctx,
  250.                                       struct encode_state *encode_state,
  251.                                       int index,
  252.                                       struct intel_encoder_context *encoder_context,
  253.                                       int width_in_mbs,
  254.                                       int height_in_mbs)
  255. {
  256.     struct i965_driver_data *i965 = i965_driver_data(ctx);
  257.     struct gen6_vme_context *vme_context = encoder_context->vme_context;
  258.  
  259.     vme_context->vme_batchbuffer.num_blocks = width_in_mbs * height_in_mbs + 1;
  260.     vme_context->vme_batchbuffer.size_block = 64; /* 4 OWORDs */
  261.     vme_context->vme_batchbuffer.pitch = 16;
  262.     vme_context->vme_batchbuffer.bo = dri_bo_alloc(i965->intel.bufmgr,
  263.                                                    "VME batchbuffer",
  264.                                                    vme_context->vme_batchbuffer.num_blocks * vme_context->vme_batchbuffer.size_block,
  265.                                                    0x1000);
  266.     vme_context->vme_buffer_suface_setup(ctx,
  267.                                          &vme_context->gpe_context,
  268.                                          &vme_context->vme_batchbuffer,
  269.                                          BINDING_TABLE_OFFSET(index),
  270.                                          SURFACE_STATE_OFFSET(index));
  271. }
  272.  
  273. static void
  274. gen8_vme_avc_output_vme_batchbuffer_setup(VADriverContextP ctx,
  275.                                       struct encode_state *encode_state,
  276.                                       int index,
  277.                                       struct intel_encoder_context *encoder_context)
  278. {
  279.     VAEncSequenceParameterBufferH264 *pSequenceParameter = (VAEncSequenceParameterBufferH264 *)encode_state->seq_param_ext->buffer;
  280.     int width_in_mbs = pSequenceParameter->picture_width_in_mbs;
  281.     int height_in_mbs = pSequenceParameter->picture_height_in_mbs;
  282.  
  283.     gen8_vme_output_vme_batchbuffer_setup(ctx, encode_state, index, encoder_context, width_in_mbs, height_in_mbs);
  284. }
  285.  
  286. static VAStatus
  287. gen8_vme_surface_setup(VADriverContextP ctx,
  288.                        struct encode_state *encode_state,
  289.                        int is_intra,
  290.                        struct intel_encoder_context *encoder_context)
  291. {
  292.     struct object_surface *obj_surface;
  293.  
  294.     /*Setup surfaces state*/
  295.     /* current picture for encoding */
  296.     obj_surface = encode_state->input_yuv_object;
  297.     gen8_vme_source_surface_state(ctx, 0, obj_surface, encoder_context);
  298.     gen8_vme_media_source_surface_state(ctx, 4, obj_surface, encoder_context);
  299.     gen8_vme_media_chroma_source_surface_state(ctx, 6, obj_surface, encoder_context);
  300.  
  301.     if (!is_intra) {
  302.         VAEncSliceParameterBufferH264 *slice_param = (VAEncSliceParameterBufferH264 *)encode_state->slice_params_ext[0]->buffer;
  303.         int slice_type;
  304.  
  305.         slice_type = intel_avc_enc_slice_type_fixup(slice_param->slice_type);
  306.         assert(slice_type != SLICE_TYPE_I && slice_type != SLICE_TYPE_SI);
  307.  
  308.         intel_avc_vme_reference_state(ctx, encode_state, encoder_context, 0, 1, gen8_vme_source_surface_state);
  309.  
  310.         if (slice_type == SLICE_TYPE_B)
  311.             intel_avc_vme_reference_state(ctx, encode_state, encoder_context, 1, 2, gen8_vme_source_surface_state);
  312.     }
  313.  
  314.     /* VME output */
  315.     gen8_vme_avc_output_buffer_setup(ctx, encode_state, 3, encoder_context);
  316.     gen8_vme_avc_output_vme_batchbuffer_setup(ctx, encode_state, 5, encoder_context);
  317.  
  318.     return VA_STATUS_SUCCESS;
  319. }
  320.  
  321. static VAStatus gen8_vme_interface_setup(VADriverContextP ctx,
  322.                                          struct encode_state *encode_state,
  323.                                          struct intel_encoder_context *encoder_context)
  324. {
  325.     struct gen6_vme_context *vme_context = encoder_context->vme_context;
  326.     struct gen8_interface_descriptor_data *desc;  
  327.     int i;
  328.     dri_bo *bo;
  329.     unsigned char *desc_ptr;
  330.  
  331.     bo = vme_context->gpe_context.dynamic_state.bo;
  332.     dri_bo_map(bo, 1);
  333.     assert(bo->virtual);
  334.     desc_ptr = (unsigned char *)bo->virtual + vme_context->gpe_context.idrt_offset;
  335.  
  336.     desc = (struct gen8_interface_descriptor_data *)desc_ptr;
  337.  
  338.     for (i = 0; i < vme_context->vme_kernel_sum; i++) {
  339.         struct i965_kernel *kernel;
  340.         kernel = &vme_context->gpe_context.kernels[i];
  341.         assert(sizeof(*desc) == 32);
  342.         /*Setup the descritor table*/
  343.         memset(desc, 0, sizeof(*desc));
  344.         desc->desc0.kernel_start_pointer = kernel->kernel_offset >> 6;
  345.         desc->desc3.sampler_count = 0; /* FIXME: */
  346.         desc->desc3.sampler_state_pointer = 0;
  347.         desc->desc4.binding_table_entry_count = 1; /* FIXME: */
  348.         desc->desc4.binding_table_pointer = (BINDING_TABLE_OFFSET(0) >> 5);
  349.         desc->desc5.constant_urb_entry_read_offset = 0;
  350.         desc->desc5.constant_urb_entry_read_length = CURBE_URB_ENTRY_LENGTH;
  351.  
  352.                
  353.         desc++;
  354.     }
  355.  
  356.     dri_bo_unmap(bo);
  357.  
  358.     return VA_STATUS_SUCCESS;
  359. }
  360.  
  361. static VAStatus gen8_vme_constant_setup(VADriverContextP ctx,
  362.                                         struct encode_state *encode_state,
  363.                                         struct intel_encoder_context *encoder_context)
  364. {
  365.     struct gen6_vme_context *vme_context = encoder_context->vme_context;
  366.     unsigned char *constant_buffer;
  367.     unsigned int *vme_state_message;
  368.     int mv_num = 32;
  369.  
  370.     vme_state_message = (unsigned int *)vme_context->vme_state_message;
  371.  
  372.     if (encoder_context->codec == CODEC_H264 ||
  373.         encoder_context->codec == CODEC_H264_MVC) {
  374.         if (vme_context->h264_level >= 30) {
  375.             mv_num = 16;
  376.        
  377.             if (vme_context->h264_level >= 31)
  378.                 mv_num = 8;
  379.         }
  380.     } else if (encoder_context->codec == CODEC_MPEG2) {
  381.         mv_num = 2;
  382.     }
  383.  
  384.     vme_state_message[31] = mv_num;
  385.  
  386.     dri_bo_map(vme_context->gpe_context.dynamic_state.bo, 1);
  387.     assert(vme_context->gpe_context.dynamic_state.bo->virtual);
  388.     constant_buffer = (unsigned char *)vme_context->gpe_context.dynamic_state.bo->virtual +
  389.                                          vme_context->gpe_context.curbe_offset;
  390.  
  391.     /* VME MV/Mb cost table is passed by using const buffer */
  392.     /* Now it uses the fixed search path. So it is constructed directly
  393.      * in the GPU shader.
  394.      */
  395.     memcpy(constant_buffer, (char *)vme_context->vme_state_message, 128);
  396.        
  397.     dri_bo_unmap(vme_context->gpe_context.dynamic_state.bo);
  398.  
  399.     return VA_STATUS_SUCCESS;
  400. }
  401.  
  402. #define         MB_SCOREBOARD_A         (1 << 0)
  403. #define         MB_SCOREBOARD_B         (1 << 1)
  404. #define         MB_SCOREBOARD_C         (1 << 2)
  405.  
  406. /* check whether the mb of (x_index, y_index) is out of bound */
  407. static inline int loop_in_bounds(int x_index, int y_index, int first_mb, int num_mb, int mb_width, int mb_height)
  408. {
  409.     int mb_index;
  410.     if (x_index < 0 || x_index >= mb_width)
  411.         return -1;
  412.     if (y_index < 0 || y_index >= mb_height)
  413.         return -1;
  414.        
  415.     mb_index = y_index * mb_width + x_index;
  416.     if (mb_index < first_mb || mb_index > (first_mb + num_mb))
  417.         return -1;
  418.     return 0;
  419. }
  420.  
  421. static void
  422. gen8wa_vme_walker_fill_vme_batchbuffer(VADriverContextP ctx,
  423.                                      struct encode_state *encode_state,
  424.                                      int mb_width, int mb_height,
  425.                                      int kernel,
  426.                                      int transform_8x8_mode_flag,
  427.                                      struct intel_encoder_context *encoder_context)
  428. {
  429.     struct gen6_vme_context *vme_context = encoder_context->vme_context;
  430.     int mb_row;
  431.     int s;
  432.     unsigned int *command_ptr;
  433.  
  434. #define         USE_SCOREBOARD          (1 << 21)
  435.  
  436.     dri_bo_map(vme_context->vme_batchbuffer.bo, 1);
  437.     command_ptr = vme_context->vme_batchbuffer.bo->virtual;
  438.  
  439.     for (s = 0; s < encode_state->num_slice_params_ext; s++) {
  440.         VAEncSliceParameterBufferH264 *pSliceParameter = (VAEncSliceParameterBufferH264 *)encode_state->slice_params_ext[s]->buffer;
  441.         int first_mb = pSliceParameter->macroblock_address;
  442.         int num_mb = pSliceParameter->num_macroblocks;
  443.         unsigned int mb_intra_ub, score_dep;
  444.         int x_outer, y_outer, x_inner, y_inner;
  445.         int xtemp_outer = 0;
  446.  
  447.         x_outer = first_mb % mb_width;
  448.         y_outer = first_mb / mb_width;
  449.         mb_row = y_outer;
  450.                                  
  451.         for (; x_outer < (mb_width -2 ) && !loop_in_bounds(x_outer, y_outer, first_mb, num_mb, mb_width, mb_height); ) {
  452.             x_inner = x_outer;
  453.             y_inner = y_outer;
  454.             for (; !loop_in_bounds(x_inner, y_inner, first_mb, num_mb, mb_width, mb_height);) {
  455.                 mb_intra_ub = 0;
  456.                 score_dep = 0;
  457.                 if (x_inner != 0) {
  458.                     mb_intra_ub |= INTRA_PRED_AVAIL_FLAG_AE;
  459.                     score_dep |= MB_SCOREBOARD_A;
  460.                 }
  461.                 if (y_inner != mb_row) {
  462.                     mb_intra_ub |= INTRA_PRED_AVAIL_FLAG_B;
  463.                     score_dep |= MB_SCOREBOARD_B;
  464.                     if (x_inner != 0)
  465.                         mb_intra_ub |= INTRA_PRED_AVAIL_FLAG_D;
  466.                     if (x_inner != (mb_width -1)) {
  467.                         mb_intra_ub |= INTRA_PRED_AVAIL_FLAG_C;
  468.                         score_dep |= MB_SCOREBOARD_C;
  469.                     }
  470.                 }
  471.                                                        
  472.                 *command_ptr++ = (CMD_MEDIA_OBJECT | (8 - 2));
  473.                 *command_ptr++ = kernel;
  474.                 *command_ptr++ = USE_SCOREBOARD;
  475.                 /* Indirect data */
  476.                 *command_ptr++ = 0;
  477.                 /* the (X, Y) term of scoreboard */
  478.                 *command_ptr++ = ((y_inner << 16) | x_inner);
  479.                 *command_ptr++ = score_dep;
  480.                 /*inline data */
  481.                 *command_ptr++ = (mb_width << 16 | y_inner << 8 | x_inner);
  482.                 *command_ptr++ = ((1 << 18) | (1 << 16) | transform_8x8_mode_flag | (mb_intra_ub << 8));
  483.                 *command_ptr++ = CMD_MEDIA_STATE_FLUSH;
  484.                 *command_ptr++ = 0;
  485.  
  486.                 x_inner -= 2;
  487.                 y_inner += 1;
  488.             }
  489.             x_outer += 1;
  490.         }
  491.  
  492.         xtemp_outer = mb_width - 2;
  493.         if (xtemp_outer < 0)
  494.             xtemp_outer = 0;
  495.         x_outer = xtemp_outer;
  496.         y_outer = first_mb / mb_width;
  497.         for (;!loop_in_bounds(x_outer, y_outer, first_mb, num_mb, mb_width, mb_height); ) {
  498.             y_inner = y_outer;
  499.             x_inner = x_outer;
  500.             for (; !loop_in_bounds(x_inner, y_inner, first_mb, num_mb, mb_width, mb_height);) {
  501.                 mb_intra_ub = 0;
  502.                 score_dep = 0;
  503.                 if (x_inner != 0) {
  504.                     mb_intra_ub |= INTRA_PRED_AVAIL_FLAG_AE;
  505.                     score_dep |= MB_SCOREBOARD_A;
  506.                 }
  507.                 if (y_inner != mb_row) {
  508.                     mb_intra_ub |= INTRA_PRED_AVAIL_FLAG_B;
  509.                     score_dep |= MB_SCOREBOARD_B;
  510.                     if (x_inner != 0)
  511.                         mb_intra_ub |= INTRA_PRED_AVAIL_FLAG_D;
  512.  
  513.                     if (x_inner != (mb_width -1)) {
  514.                         mb_intra_ub |= INTRA_PRED_AVAIL_FLAG_C;
  515.                         score_dep |= MB_SCOREBOARD_C;
  516.                     }
  517.                 }
  518.  
  519.                 *command_ptr++ = (CMD_MEDIA_OBJECT | (8 - 2));
  520.                 *command_ptr++ = kernel;
  521.                 *command_ptr++ = USE_SCOREBOARD;
  522.                 /* Indirect data */
  523.                 *command_ptr++ = 0;
  524.                 /* the (X, Y) term of scoreboard */
  525.                 *command_ptr++ = ((y_inner << 16) | x_inner);
  526.                 *command_ptr++ = score_dep;
  527.                 /*inline data */
  528.                 *command_ptr++ = (mb_width << 16 | y_inner << 8 | x_inner);
  529.                 *command_ptr++ = ((1 << 18) | (1 << 16) | transform_8x8_mode_flag | (mb_intra_ub << 8));
  530.  
  531.                 *command_ptr++ = CMD_MEDIA_STATE_FLUSH;
  532.                 *command_ptr++ = 0;
  533.                 x_inner -= 2;
  534.                 y_inner += 1;
  535.             }
  536.             x_outer++;
  537.             if (x_outer >= mb_width) {
  538.                 y_outer += 1;
  539.                 x_outer = xtemp_outer;
  540.             }          
  541.         }
  542.     }
  543.  
  544.     *command_ptr++ = MI_BATCH_BUFFER_END;
  545.     *command_ptr++ = 0;
  546.  
  547.     dri_bo_unmap(vme_context->vme_batchbuffer.bo);
  548. }
  549.  
  550. static void
  551. gen8_vme_fill_vme_batchbuffer(VADriverContextP ctx,
  552.                               struct encode_state *encode_state,
  553.                               int mb_width, int mb_height,
  554.                               int kernel,
  555.                               int transform_8x8_mode_flag,
  556.                               struct intel_encoder_context *encoder_context)
  557. {
  558.     struct gen6_vme_context *vme_context = encoder_context->vme_context;
  559.     int mb_x = 0, mb_y = 0;
  560.     int i, s;
  561.     unsigned int *command_ptr;
  562.  
  563.     dri_bo_map(vme_context->vme_batchbuffer.bo, 1);
  564.     command_ptr = vme_context->vme_batchbuffer.bo->virtual;
  565.  
  566.     for (s = 0; s < encode_state->num_slice_params_ext; s++) {
  567.         VAEncSliceParameterBufferH264 *pSliceParameter = (VAEncSliceParameterBufferH264 *)encode_state->slice_params_ext[s]->buffer;
  568.         int slice_mb_begin = pSliceParameter->macroblock_address;
  569.         int slice_mb_number = pSliceParameter->num_macroblocks;
  570.         unsigned int mb_intra_ub;
  571.         int slice_mb_x = pSliceParameter->macroblock_address % mb_width;
  572.         for (i = 0; i < slice_mb_number;  ) {
  573.             int mb_count = i + slice_mb_begin;    
  574.             mb_x = mb_count % mb_width;
  575.             mb_y = mb_count / mb_width;
  576.             mb_intra_ub = 0;
  577.             if (mb_x != 0) {
  578.                 mb_intra_ub |= INTRA_PRED_AVAIL_FLAG_AE;
  579.             }
  580.             if (mb_y != 0) {
  581.                 mb_intra_ub |= INTRA_PRED_AVAIL_FLAG_B;
  582.                 if (mb_x != 0)
  583.                     mb_intra_ub |= INTRA_PRED_AVAIL_FLAG_D;
  584.                 if (mb_x != (mb_width -1))
  585.                     mb_intra_ub |= INTRA_PRED_AVAIL_FLAG_C;
  586.             }
  587.             if (i < mb_width) {
  588.                 if (i == 0)
  589.                     mb_intra_ub &= ~(INTRA_PRED_AVAIL_FLAG_AE);
  590.                 mb_intra_ub &= ~(INTRA_PRED_AVAIL_FLAG_BCD_MASK);
  591.                 if ((i == (mb_width - 1)) && slice_mb_x) {
  592.                     mb_intra_ub |= INTRA_PRED_AVAIL_FLAG_C;
  593.                 }
  594.             }
  595.                
  596.             if ((i == mb_width) && slice_mb_x) {
  597.                 mb_intra_ub &= ~(INTRA_PRED_AVAIL_FLAG_D);
  598.             }
  599.             *command_ptr++ = (CMD_MEDIA_OBJECT | (8 - 2));
  600.             *command_ptr++ = kernel;
  601.             *command_ptr++ = 0;
  602.             *command_ptr++ = 0;
  603.             *command_ptr++ = 0;
  604.             *command_ptr++ = 0;
  605.    
  606.             /*inline data */
  607.             *command_ptr++ = (mb_width << 16 | mb_y << 8 | mb_x);
  608.             *command_ptr++ = ((encoder_context->quality_level << 24) | (1 << 16) | transform_8x8_mode_flag | (mb_intra_ub << 8));
  609.  
  610.             *command_ptr++ = CMD_MEDIA_STATE_FLUSH;
  611.             *command_ptr++ = 0;
  612.             i += 1;
  613.         }
  614.     }
  615.  
  616.     *command_ptr++ = MI_BATCH_BUFFER_END;
  617.     *command_ptr++ = 0;
  618.  
  619.     dri_bo_unmap(vme_context->vme_batchbuffer.bo);
  620. }
  621.  
  622. static void gen8_vme_media_init(VADriverContextP ctx, struct intel_encoder_context *encoder_context)
  623. {
  624.     struct gen6_vme_context *vme_context = encoder_context->vme_context;
  625.  
  626.     gen8_gpe_context_init(ctx, &vme_context->gpe_context);
  627.  
  628.     /* VME output buffer */
  629.     dri_bo_unreference(vme_context->vme_output.bo);
  630.     vme_context->vme_output.bo = NULL;
  631.  
  632.     dri_bo_unreference(vme_context->vme_batchbuffer.bo);
  633.     vme_context->vme_batchbuffer.bo = NULL;
  634.  
  635.     /* VME state */
  636.     dri_bo_unreference(vme_context->vme_state.bo);
  637.     vme_context->vme_state.bo = NULL;
  638. }
  639.  
  640. static void gen8_vme_pipeline_programing(VADriverContextP ctx,
  641.                                          struct encode_state *encode_state,
  642.                                          struct intel_encoder_context *encoder_context)
  643. {
  644.     struct gen6_vme_context *vme_context = encoder_context->vme_context;
  645.     struct intel_batchbuffer *batch = encoder_context->base.batch;
  646.     VAEncPictureParameterBufferH264 *pPicParameter = (VAEncPictureParameterBufferH264 *)encode_state->pic_param_ext->buffer;
  647.     VAEncSliceParameterBufferH264 *pSliceParameter = (VAEncSliceParameterBufferH264 *)encode_state->slice_params_ext[0]->buffer;
  648.     VAEncSequenceParameterBufferH264 *pSequenceParameter = (VAEncSequenceParameterBufferH264 *)encode_state->seq_param_ext->buffer;
  649.     int width_in_mbs = pSequenceParameter->picture_width_in_mbs;
  650.     int height_in_mbs = pSequenceParameter->picture_height_in_mbs;
  651.     int kernel_shader;
  652.     bool allow_hwscore = true;
  653.     int s;
  654.     unsigned int is_low_quality = (encoder_context->quality_level == ENCODER_LOW_QUALITY);
  655.  
  656.     if (is_low_quality)
  657.         allow_hwscore = false;
  658.     else {
  659.         for (s = 0; s < encode_state->num_slice_params_ext; s++) {
  660.             pSliceParameter = (VAEncSliceParameterBufferH264 *)encode_state->slice_params_ext[s]->buffer;
  661.             if ((pSliceParameter->macroblock_address % width_in_mbs)) {
  662.                 allow_hwscore = false;
  663.                 break;
  664.             }
  665.         }
  666.     }
  667.  
  668.     if ((pSliceParameter->slice_type == SLICE_TYPE_I) ||
  669.         (pSliceParameter->slice_type == SLICE_TYPE_SI)) {
  670.         kernel_shader = VME_INTRA_SHADER;
  671.     } else if ((pSliceParameter->slice_type == SLICE_TYPE_P) ||
  672.                (pSliceParameter->slice_type == SLICE_TYPE_SP)) {
  673.         kernel_shader = VME_INTER_SHADER;
  674.     } else {
  675.         kernel_shader = VME_BINTER_SHADER;
  676.         if (!allow_hwscore)
  677.             kernel_shader = VME_INTER_SHADER;
  678.     }
  679.     if (allow_hwscore)
  680.         gen8wa_vme_walker_fill_vme_batchbuffer(ctx,
  681.                                              encode_state,
  682.                                              width_in_mbs, height_in_mbs,
  683.                                              kernel_shader,
  684.                                              pPicParameter->pic_fields.bits.transform_8x8_mode_flag,
  685.                                              encoder_context);
  686.     else
  687.         gen8_vme_fill_vme_batchbuffer(ctx,
  688.                                       encode_state,
  689.                                       width_in_mbs, height_in_mbs,
  690.                                       kernel_shader,
  691.                                       pPicParameter->pic_fields.bits.transform_8x8_mode_flag,
  692.                                       encoder_context);
  693.  
  694.     intel_batchbuffer_start_atomic(batch, 0x1000);
  695.     gen8_gpe_pipeline_setup(ctx, &vme_context->gpe_context, batch);
  696.     BEGIN_BATCH(batch, 3);
  697.     OUT_BATCH(batch, MI_BATCH_BUFFER_START | (1 << 8) | (1 << 0));
  698.     OUT_RELOC(batch,
  699.               vme_context->vme_batchbuffer.bo,
  700.               I915_GEM_DOMAIN_COMMAND, 0,
  701.               0);
  702.     OUT_BATCH(batch, 0);
  703.     ADVANCE_BATCH(batch);
  704.  
  705.     intel_batchbuffer_end_atomic(batch);       
  706. }
  707.  
  708. static VAStatus gen8_vme_prepare(VADriverContextP ctx,
  709.                                  struct encode_state *encode_state,
  710.                                  struct intel_encoder_context *encoder_context)
  711. {
  712.     VAStatus vaStatus = VA_STATUS_SUCCESS;
  713.     VAEncSliceParameterBufferH264 *pSliceParameter = (VAEncSliceParameterBufferH264 *)encode_state->slice_params_ext[0]->buffer;
  714.     int is_intra = pSliceParameter->slice_type == SLICE_TYPE_I;
  715.     VAEncSequenceParameterBufferH264 *pSequenceParameter = (VAEncSequenceParameterBufferH264 *)encode_state->seq_param_ext->buffer;
  716.     struct gen6_vme_context *vme_context = encoder_context->vme_context;
  717.  
  718.     if (!vme_context->h264_level ||
  719.         (vme_context->h264_level != pSequenceParameter->level_idc)) {
  720.         vme_context->h264_level = pSequenceParameter->level_idc;       
  721.     }  
  722.  
  723.     intel_vme_update_mbmv_cost(ctx, encode_state, encoder_context);
  724.        
  725.     /*Setup all the memory object*/
  726.     gen8_vme_surface_setup(ctx, encode_state, is_intra, encoder_context);
  727.     gen8_vme_interface_setup(ctx, encode_state, encoder_context);
  728.     //gen8_vme_vme_state_setup(ctx, encode_state, is_intra, encoder_context);
  729.     gen8_vme_constant_setup(ctx, encode_state, encoder_context);
  730.  
  731.     /*Programing media pipeline*/
  732.     gen8_vme_pipeline_programing(ctx, encode_state, encoder_context);
  733.  
  734.     return vaStatus;
  735. }
  736.  
  737. static VAStatus gen8_vme_run(VADriverContextP ctx,
  738.                              struct encode_state *encode_state,
  739.                              struct intel_encoder_context *encoder_context)
  740. {
  741.     struct intel_batchbuffer *batch = encoder_context->base.batch;
  742.  
  743.     intel_batchbuffer_flush(batch);
  744.  
  745.     return VA_STATUS_SUCCESS;
  746. }
  747.  
  748. static VAStatus gen8_vme_stop(VADriverContextP ctx,
  749.                               struct encode_state *encode_state,
  750.                               struct intel_encoder_context *encoder_context)
  751. {
  752.     return VA_STATUS_SUCCESS;
  753. }
  754.  
  755. static VAStatus
  756. gen8_vme_pipeline(VADriverContextP ctx,
  757.                   VAProfile profile,
  758.                   struct encode_state *encode_state,
  759.                   struct intel_encoder_context *encoder_context)
  760. {
  761.     gen8_vme_media_init(ctx, encoder_context);
  762.     gen8_vme_prepare(ctx, encode_state, encoder_context);
  763.     gen8_vme_run(ctx, encode_state, encoder_context);
  764.     gen8_vme_stop(ctx, encode_state, encoder_context);
  765.  
  766.     return VA_STATUS_SUCCESS;
  767. }
  768.  
  769. static void
  770. gen8_vme_mpeg2_output_buffer_setup(VADriverContextP ctx,
  771.                                    struct encode_state *encode_state,
  772.                                    int index,
  773.                                    int is_intra,
  774.                                    struct intel_encoder_context *encoder_context)
  775. {
  776.     VAEncSequenceParameterBufferMPEG2 *seq_param = (VAEncSequenceParameterBufferMPEG2 *)encode_state->seq_param_ext->buffer;
  777.     int width_in_mbs = ALIGN(seq_param->picture_width, 16) / 16;
  778.     int height_in_mbs = ALIGN(seq_param->picture_height, 16) / 16;
  779.  
  780.     gen8_vme_output_buffer_setup(ctx, encode_state, index, encoder_context, is_intra, width_in_mbs, height_in_mbs);
  781. }
  782.  
  783. static void
  784. gen8_vme_mpeg2_output_vme_batchbuffer_setup(VADriverContextP ctx,
  785.                                             struct encode_state *encode_state,
  786.                                             int index,
  787.                                             struct intel_encoder_context *encoder_context)
  788. {
  789.     VAEncSequenceParameterBufferMPEG2 *seq_param = (VAEncSequenceParameterBufferMPEG2 *)encode_state->seq_param_ext->buffer;
  790.     int width_in_mbs = ALIGN(seq_param->picture_width, 16) / 16;
  791.     int height_in_mbs = ALIGN(seq_param->picture_height, 16) / 16;
  792.  
  793.     gen8_vme_output_vme_batchbuffer_setup(ctx, encode_state, index, encoder_context, width_in_mbs, height_in_mbs);
  794. }
  795.  
  796. static VAStatus
  797. gen8_vme_mpeg2_surface_setup(VADriverContextP ctx,
  798.                              struct encode_state *encode_state,
  799.                              int is_intra,
  800.                              struct intel_encoder_context *encoder_context)
  801. {
  802.     struct object_surface *obj_surface;
  803.  
  804.     /*Setup surfaces state*/
  805.     /* current picture for encoding */
  806.     obj_surface = encode_state->input_yuv_object;
  807.     gen8_vme_source_surface_state(ctx, 0, obj_surface, encoder_context);
  808.     gen8_vme_media_source_surface_state(ctx, 4, obj_surface, encoder_context);
  809.     gen8_vme_media_chroma_source_surface_state(ctx, 6, obj_surface, encoder_context);
  810.  
  811.     if (!is_intra) {
  812.         /* reference 0 */
  813.         obj_surface = encode_state->reference_objects[0];
  814.  
  815.         if (obj_surface->bo != NULL)
  816.             gen8_vme_source_surface_state(ctx, 1, obj_surface, encoder_context);
  817.  
  818.         /* reference 1 */
  819.         obj_surface = encode_state->reference_objects[1];
  820.  
  821.         if (obj_surface && obj_surface->bo != NULL)
  822.             gen8_vme_source_surface_state(ctx, 2, obj_surface, encoder_context);
  823.     }
  824.  
  825.     /* VME output */
  826.     gen8_vme_mpeg2_output_buffer_setup(ctx, encode_state, 3, is_intra, encoder_context);
  827.     gen8_vme_mpeg2_output_vme_batchbuffer_setup(ctx, encode_state, 5, encoder_context);
  828.  
  829.     return VA_STATUS_SUCCESS;
  830. }
  831.  
  832. static void
  833. gen8wa_vme_mpeg2_walker_fill_vme_batchbuffer(VADriverContextP ctx,
  834.                                            struct encode_state *encode_state,
  835.                                            int mb_width, int mb_height,
  836.                                            int kernel,
  837.                                            struct intel_encoder_context *encoder_context)
  838. {
  839.     struct gen6_vme_context *vme_context = encoder_context->vme_context;
  840.     unsigned int *command_ptr;
  841.  
  842. #define         MPEG2_SCOREBOARD                (1 << 21)
  843.  
  844.     dri_bo_map(vme_context->vme_batchbuffer.bo, 1);
  845.     command_ptr = vme_context->vme_batchbuffer.bo->virtual;
  846.  
  847.     {
  848.         unsigned int mb_intra_ub, score_dep;
  849.         int x_outer, y_outer, x_inner, y_inner;
  850.         int xtemp_outer = 0;
  851.         int first_mb = 0;
  852.         int num_mb = mb_width * mb_height;
  853.  
  854.         x_outer = 0;
  855.         y_outer = 0;
  856.        
  857.                                  
  858.         for (; x_outer < (mb_width -2 ) && !loop_in_bounds(x_outer, y_outer, first_mb, num_mb, mb_width, mb_height); ) {
  859.             x_inner = x_outer;
  860.             y_inner = y_outer;
  861.             for (; !loop_in_bounds(x_inner, y_inner, first_mb, num_mb, mb_width, mb_height);) {
  862.                 mb_intra_ub = 0;
  863.                 score_dep = 0;
  864.                 if (x_inner != 0) {
  865.                     mb_intra_ub |= INTRA_PRED_AVAIL_FLAG_AE;
  866.                     score_dep |= MB_SCOREBOARD_A;
  867.                 }
  868.                 if (y_inner != 0) {
  869.                     mb_intra_ub |= INTRA_PRED_AVAIL_FLAG_B;
  870.                     score_dep |= MB_SCOREBOARD_B;
  871.  
  872.                     if (x_inner != 0)
  873.                         mb_intra_ub |= INTRA_PRED_AVAIL_FLAG_D;
  874.  
  875.                     if (x_inner != (mb_width -1)) {
  876.                         mb_intra_ub |= INTRA_PRED_AVAIL_FLAG_C;
  877.                         score_dep |= MB_SCOREBOARD_C;
  878.                     }
  879.                 }
  880.                                                        
  881.                 *command_ptr++ = (CMD_MEDIA_OBJECT | (8 - 2));
  882.                 *command_ptr++ = kernel;
  883.                 *command_ptr++ = MPEG2_SCOREBOARD;
  884.                 /* Indirect data */
  885.                 *command_ptr++ = 0;
  886.                 /* the (X, Y) term of scoreboard */
  887.                 *command_ptr++ = ((y_inner << 16) | x_inner);
  888.                 *command_ptr++ = score_dep;
  889.                 /*inline data */
  890.                 *command_ptr++ = (mb_width << 16 | y_inner << 8 | x_inner);
  891.                 *command_ptr++ = ((1 << 18) | (1 << 16) | (mb_intra_ub << 8));
  892.                 *command_ptr++ = CMD_MEDIA_STATE_FLUSH;
  893.                 *command_ptr++ = 0;
  894.  
  895.                 x_inner -= 2;
  896.                 y_inner += 1;
  897.             }
  898.             x_outer += 1;
  899.         }
  900.  
  901.         xtemp_outer = mb_width - 2;
  902.         if (xtemp_outer < 0)
  903.             xtemp_outer = 0;
  904.         x_outer = xtemp_outer;
  905.         y_outer = 0;
  906.         for (;!loop_in_bounds(x_outer, y_outer, first_mb, num_mb, mb_width, mb_height); ) {
  907.             y_inner = y_outer;
  908.             x_inner = x_outer;
  909.             for (; !loop_in_bounds(x_inner, y_inner, first_mb, num_mb, mb_width, mb_height);) {
  910.                 mb_intra_ub = 0;
  911.                 score_dep = 0;
  912.                 if (x_inner != 0) {
  913.                     mb_intra_ub |= INTRA_PRED_AVAIL_FLAG_AE;
  914.                     score_dep |= MB_SCOREBOARD_A;
  915.                 }
  916.                 if (y_inner != 0) {
  917.                     mb_intra_ub |= INTRA_PRED_AVAIL_FLAG_B;
  918.                     score_dep |= MB_SCOREBOARD_B;
  919.  
  920.                     if (x_inner != 0)
  921.                         mb_intra_ub |= INTRA_PRED_AVAIL_FLAG_D;
  922.  
  923.                     if (x_inner != (mb_width -1)) {
  924.                         mb_intra_ub |= INTRA_PRED_AVAIL_FLAG_C;
  925.                         score_dep |= MB_SCOREBOARD_C;
  926.                     }
  927.                 }
  928.  
  929.                 *command_ptr++ = (CMD_MEDIA_OBJECT | (8 - 2));
  930.                 *command_ptr++ = kernel;
  931.                 *command_ptr++ = MPEG2_SCOREBOARD;
  932.                 /* Indirect data */
  933.                 *command_ptr++ = 0;
  934.                 /* the (X, Y) term of scoreboard */
  935.                 *command_ptr++ = ((y_inner << 16) | x_inner);
  936.                 *command_ptr++ = score_dep;
  937.                 /*inline data */
  938.                 *command_ptr++ = (mb_width << 16 | y_inner << 8 | x_inner);
  939.                 *command_ptr++ = ((1 << 18) | (1 << 16) | (mb_intra_ub << 8));
  940.  
  941.                 *command_ptr++ = CMD_MEDIA_STATE_FLUSH;
  942.                 *command_ptr++ = 0;
  943.                 x_inner -= 2;
  944.                 y_inner += 1;
  945.             }
  946.             x_outer++;
  947.             if (x_outer >= mb_width) {
  948.                 y_outer += 1;
  949.                 x_outer = xtemp_outer;
  950.             }          
  951.         }
  952.     }
  953.  
  954.     *command_ptr++ = MI_BATCH_BUFFER_END;
  955.     *command_ptr++ = 0;
  956.  
  957.     dri_bo_unmap(vme_context->vme_batchbuffer.bo);
  958.     return;
  959. }
  960.  
  961. static void
  962. gen8_vme_mpeg2_fill_vme_batchbuffer(VADriverContextP ctx,
  963.                                     struct encode_state *encode_state,
  964.                                     int mb_width, int mb_height,
  965.                                     int kernel,
  966.                                     int transform_8x8_mode_flag,
  967.                                     struct intel_encoder_context *encoder_context)
  968. {
  969.     struct gen6_vme_context *vme_context = encoder_context->vme_context;
  970.     int mb_x = 0, mb_y = 0;
  971.     int i, s, j;
  972.     unsigned int *command_ptr;
  973.  
  974.  
  975.     dri_bo_map(vme_context->vme_batchbuffer.bo, 1);
  976.     command_ptr = vme_context->vme_batchbuffer.bo->virtual;
  977.  
  978.     for (s = 0; s < encode_state->num_slice_params_ext; s++) {
  979.         VAEncSliceParameterBufferMPEG2 *slice_param = (VAEncSliceParameterBufferMPEG2 *)encode_state->slice_params_ext[s]->buffer;
  980.  
  981.         for (j = 0; j < encode_state->slice_params_ext[s]->num_elements; j++) {
  982.             int slice_mb_begin = slice_param->macroblock_address;
  983.             int slice_mb_number = slice_param->num_macroblocks;
  984.             unsigned int mb_intra_ub;
  985.  
  986.             for (i = 0; i < slice_mb_number;) {
  987.                 int mb_count = i + slice_mb_begin;    
  988.  
  989.                 mb_x = mb_count % mb_width;
  990.                 mb_y = mb_count / mb_width;
  991.                 mb_intra_ub = 0;
  992.  
  993.                 if (mb_x != 0) {
  994.                     mb_intra_ub |= INTRA_PRED_AVAIL_FLAG_AE;
  995.                 }
  996.  
  997.                 if (mb_y != 0) {
  998.                     mb_intra_ub |= INTRA_PRED_AVAIL_FLAG_B;
  999.  
  1000.                     if (mb_x != 0)
  1001.                         mb_intra_ub |= INTRA_PRED_AVAIL_FLAG_D;
  1002.  
  1003.                     if (mb_x != (mb_width -1))
  1004.                         mb_intra_ub |= INTRA_PRED_AVAIL_FLAG_C;
  1005.                 }
  1006.  
  1007.                 *command_ptr++ = (CMD_MEDIA_OBJECT | (8 - 2));
  1008.                 *command_ptr++ = kernel;
  1009.                 *command_ptr++ = 0;
  1010.                 *command_ptr++ = 0;
  1011.                 *command_ptr++ = 0;
  1012.                 *command_ptr++ = 0;
  1013.    
  1014.                 /*inline data */
  1015.                 *command_ptr++ = (mb_width << 16 | mb_y << 8 | mb_x);
  1016.                 *command_ptr++ = ( (1 << 16) | transform_8x8_mode_flag | (mb_intra_ub << 8));
  1017.  
  1018.                 *command_ptr++ = CMD_MEDIA_STATE_FLUSH;
  1019.                 *command_ptr++ = 0;
  1020.                 i += 1;
  1021.             }
  1022.  
  1023.             slice_param++;
  1024.         }
  1025.     }
  1026.  
  1027.     *command_ptr++ = MI_BATCH_BUFFER_END;
  1028.     *command_ptr++ = 0;
  1029.  
  1030.     dri_bo_unmap(vme_context->vme_batchbuffer.bo);
  1031. }
  1032.  
  1033. static void
  1034. gen8_vme_mpeg2_pipeline_programing(VADriverContextP ctx,
  1035.                                    struct encode_state *encode_state,
  1036.                                    int is_intra,
  1037.                                    struct intel_encoder_context *encoder_context)
  1038. {
  1039.     struct gen6_vme_context *vme_context = encoder_context->vme_context;
  1040.     struct intel_batchbuffer *batch = encoder_context->base.batch;
  1041.     VAEncSequenceParameterBufferMPEG2 *seq_param = (VAEncSequenceParameterBufferMPEG2 *)encode_state->seq_param_ext->buffer;
  1042.     int width_in_mbs = ALIGN(seq_param->picture_width, 16) / 16;
  1043.     int height_in_mbs = ALIGN(seq_param->picture_height, 16) / 16;
  1044.     bool allow_hwscore = true;
  1045.     int s;
  1046.     int kernel_shader;
  1047.     VAEncPictureParameterBufferMPEG2 *pic_param = NULL;
  1048.  
  1049.     for (s = 0; s < encode_state->num_slice_params_ext; s++) {
  1050.         int j;
  1051.         VAEncSliceParameterBufferMPEG2 *slice_param = (VAEncSliceParameterBufferMPEG2 *)encode_state->slice_params_ext[s]->buffer;
  1052.  
  1053.         for (j = 0; j < encode_state->slice_params_ext[s]->num_elements; j++) {
  1054.             if (slice_param->macroblock_address % width_in_mbs) {
  1055.                 allow_hwscore = false;
  1056.                 break;
  1057.             }
  1058.         }
  1059.     }
  1060.  
  1061.     pic_param = (VAEncPictureParameterBufferMPEG2 *)encode_state->pic_param_ext->buffer;
  1062.     if (pic_param->picture_type == VAEncPictureTypeIntra) {
  1063.         allow_hwscore = false;
  1064.         kernel_shader = VME_INTRA_SHADER;
  1065.     } else {
  1066.         kernel_shader = VME_INTER_SHADER;
  1067.     }
  1068.  
  1069.     if (allow_hwscore)
  1070.         gen8wa_vme_mpeg2_walker_fill_vme_batchbuffer(ctx,
  1071.                                                    encode_state,
  1072.                                                    width_in_mbs, height_in_mbs,
  1073.                                                    kernel_shader,
  1074.                                                    encoder_context);
  1075.     else
  1076.         gen8_vme_mpeg2_fill_vme_batchbuffer(ctx,
  1077.                                             encode_state,
  1078.                                             width_in_mbs, height_in_mbs,
  1079.                                             is_intra ? VME_INTRA_SHADER : VME_INTER_SHADER,
  1080.                                             0,
  1081.                                             encoder_context);
  1082.  
  1083.     intel_batchbuffer_start_atomic(batch, 0x1000);
  1084.     gen8_gpe_pipeline_setup(ctx, &vme_context->gpe_context, batch);
  1085.     BEGIN_BATCH(batch, 4);
  1086.     OUT_BATCH(batch, MI_BATCH_BUFFER_START | (1 << 8) | (1 << 0));
  1087.     OUT_RELOC(batch,
  1088.               vme_context->vme_batchbuffer.bo,
  1089.               I915_GEM_DOMAIN_COMMAND, 0,
  1090.               0);
  1091.     OUT_BATCH(batch, 0);
  1092.     OUT_BATCH(batch, 0);
  1093.     ADVANCE_BATCH(batch);
  1094.  
  1095.     intel_batchbuffer_end_atomic(batch);       
  1096. }
  1097.  
  1098. static VAStatus
  1099. gen8_vme_mpeg2_prepare(VADriverContextP ctx,
  1100.                        struct encode_state *encode_state,
  1101.                        struct intel_encoder_context *encoder_context)
  1102. {
  1103.     VAStatus vaStatus = VA_STATUS_SUCCESS;
  1104.     VAEncSliceParameterBufferMPEG2 *slice_param = (VAEncSliceParameterBufferMPEG2 *)encode_state->slice_params_ext[0]->buffer;
  1105.     VAEncSequenceParameterBufferMPEG2 *seq_param = (VAEncSequenceParameterBufferMPEG2 *)encode_state->seq_param_ext->buffer;
  1106.     struct gen6_vme_context *vme_context = encoder_context->vme_context;
  1107.  
  1108.     if ((!vme_context->mpeg2_level) ||
  1109.         (vme_context->mpeg2_level != (seq_param->sequence_extension.bits.profile_and_level_indication & MPEG2_LEVEL_MASK))) {
  1110.         vme_context->mpeg2_level = seq_param->sequence_extension.bits.profile_and_level_indication & MPEG2_LEVEL_MASK;
  1111.     }
  1112.  
  1113.        
  1114.     /*Setup all the memory object*/
  1115.     gen8_vme_mpeg2_surface_setup(ctx, encode_state, slice_param->is_intra_slice, encoder_context);
  1116.     gen8_vme_interface_setup(ctx, encode_state, encoder_context);
  1117.     //gen8_vme_vme_state_setup(ctx, encode_state, slice_param->is_intra_slice, encoder_context);
  1118.     intel_vme_mpeg2_state_setup(ctx, encode_state, encoder_context);
  1119.     gen8_vme_constant_setup(ctx, encode_state, encoder_context);
  1120.  
  1121.     /*Programing media pipeline*/
  1122.     gen8_vme_mpeg2_pipeline_programing(ctx, encode_state, slice_param->is_intra_slice, encoder_context);
  1123.  
  1124.     return vaStatus;
  1125. }
  1126.  
  1127. static VAStatus
  1128. gen8_vme_mpeg2_pipeline(VADriverContextP ctx,
  1129.                         VAProfile profile,
  1130.                         struct encode_state *encode_state,
  1131.                         struct intel_encoder_context *encoder_context)
  1132. {
  1133.     gen8_vme_media_init(ctx, encoder_context);
  1134.     gen8_vme_mpeg2_prepare(ctx, encode_state, encoder_context);
  1135.     gen8_vme_run(ctx, encode_state, encoder_context);
  1136.     gen8_vme_stop(ctx, encode_state, encoder_context);
  1137.  
  1138.     return VA_STATUS_SUCCESS;
  1139. }
  1140.  
  1141. static void
  1142. gen8_vme_vp8_output_buffer_setup(VADriverContextP ctx,
  1143.                                    struct encode_state *encode_state,
  1144.                                    int index,
  1145.                                    int is_intra,
  1146.                                    struct intel_encoder_context *encoder_context)
  1147. {
  1148.     VAEncSequenceParameterBufferVP8 *seq_param = (VAEncSequenceParameterBufferVP8 *)encode_state->seq_param_ext->buffer;
  1149.     int width_in_mbs = ALIGN(seq_param->frame_width, 16) / 16;
  1150.     int height_in_mbs = ALIGN(seq_param->frame_height, 16) / 16;
  1151.  
  1152.     gen8_vme_output_buffer_setup(ctx, encode_state, index, encoder_context, is_intra, width_in_mbs, height_in_mbs);
  1153. }
  1154.  
  1155. static void
  1156. gen8_vme_vp8_output_vme_batchbuffer_setup(VADriverContextP ctx,
  1157.                                             struct encode_state *encode_state,
  1158.                                             int index,
  1159.                                             struct intel_encoder_context *encoder_context)
  1160. {
  1161.     VAEncSequenceParameterBufferVP8 *seq_param = (VAEncSequenceParameterBufferVP8 *)encode_state->seq_param_ext->buffer;
  1162.     int width_in_mbs = ALIGN(seq_param->frame_width, 16) / 16;
  1163.     int height_in_mbs = ALIGN(seq_param->frame_height, 16) / 16;
  1164.  
  1165.     gen8_vme_output_vme_batchbuffer_setup(ctx, encode_state, index, encoder_context, width_in_mbs, height_in_mbs);
  1166. }
  1167.  
  1168. static VAStatus
  1169. gen8_vme_vp8_surface_setup(VADriverContextP ctx,
  1170.                              struct encode_state *encode_state,
  1171.                              int is_intra,
  1172.                              struct intel_encoder_context *encoder_context)
  1173. {
  1174.     struct object_surface *obj_surface;
  1175.  
  1176.     /*Setup surfaces state*/
  1177.     /* current picture for encoding */
  1178.     obj_surface = encode_state->input_yuv_object;
  1179.     gen8_vme_source_surface_state(ctx, 0, obj_surface, encoder_context);
  1180.     gen8_vme_media_source_surface_state(ctx, 4, obj_surface, encoder_context);
  1181.     gen8_vme_media_chroma_source_surface_state(ctx, 6, obj_surface, encoder_context);
  1182.  
  1183.     if (!is_intra) {
  1184.         /* reference 0 */
  1185.         obj_surface = encode_state->reference_objects[0];
  1186.  
  1187.         if (obj_surface->bo != NULL)
  1188.             gen8_vme_source_surface_state(ctx, 1, obj_surface, encoder_context);
  1189.  
  1190.         /* reference 1 */
  1191.         obj_surface = encode_state->reference_objects[1];
  1192.  
  1193.         if (obj_surface && obj_surface->bo != NULL)
  1194.             gen8_vme_source_surface_state(ctx, 2, obj_surface, encoder_context);
  1195.     }
  1196.  
  1197.     /* VME output */
  1198.     gen8_vme_vp8_output_buffer_setup(ctx, encode_state, 3, is_intra, encoder_context);
  1199.     gen8_vme_vp8_output_vme_batchbuffer_setup(ctx, encode_state, 5, encoder_context);
  1200.  
  1201.     return VA_STATUS_SUCCESS;
  1202. }
  1203.  
  1204. static void
  1205. gen8_vme_vp8_pipeline_programing(VADriverContextP ctx,
  1206.                                    struct encode_state *encode_state,
  1207.                                    int is_intra,
  1208.                                    struct intel_encoder_context *encoder_context)
  1209. {
  1210.     struct gen6_vme_context *vme_context = encoder_context->vme_context;
  1211.     struct intel_batchbuffer *batch = encoder_context->base.batch;
  1212.     VAEncSequenceParameterBufferVP8 *seq_param = (VAEncSequenceParameterBufferVP8 *)encode_state->seq_param_ext->buffer;
  1213.     int width_in_mbs = ALIGN(seq_param->frame_width, 16) / 16;
  1214.     int height_in_mbs = ALIGN(seq_param->frame_height, 16) / 16;
  1215.     int kernel_shader = (is_intra ? VME_INTRA_SHADER : VME_INTER_SHADER);
  1216.  
  1217.     gen8wa_vme_mpeg2_walker_fill_vme_batchbuffer(ctx,
  1218.                                                  encode_state,
  1219.                                                  width_in_mbs, height_in_mbs,
  1220.                                                  kernel_shader,
  1221.                                                  encoder_context);
  1222.  
  1223.     intel_batchbuffer_start_atomic(batch, 0x1000);
  1224.     gen8_gpe_pipeline_setup(ctx, &vme_context->gpe_context, batch);
  1225.     BEGIN_BATCH(batch, 4);
  1226.     OUT_BATCH(batch, MI_BATCH_BUFFER_START | (1 << 8) | (1 << 0));
  1227.     OUT_RELOC(batch,
  1228.               vme_context->vme_batchbuffer.bo,
  1229.               I915_GEM_DOMAIN_COMMAND, 0,
  1230.               0);
  1231.     OUT_BATCH(batch, 0);
  1232.     OUT_BATCH(batch, 0);
  1233.     ADVANCE_BATCH(batch);
  1234.  
  1235.     intel_batchbuffer_end_atomic(batch);
  1236. }
  1237.  
  1238. static VAStatus gen8_vme_vp8_prepare(VADriverContextP ctx,
  1239.                                  struct encode_state *encode_state,
  1240.                                  struct intel_encoder_context *encoder_context)
  1241. {
  1242.     VAStatus vaStatus = VA_STATUS_SUCCESS;
  1243.     VAEncPictureParameterBufferVP8 *pPicParameter = (VAEncPictureParameterBufferVP8 *)encode_state->pic_param_ext->buffer;
  1244.     int is_intra = !pPicParameter->pic_flags.bits.frame_type;
  1245.  
  1246.     /* update vp8 mbmv cost */
  1247.     intel_vme_vp8_update_mbmv_cost(ctx, encode_state, encoder_context);
  1248.  
  1249.     /*Setup all the memory object*/
  1250.     gen8_vme_vp8_surface_setup(ctx, encode_state, is_intra, encoder_context);
  1251.     gen8_vme_interface_setup(ctx, encode_state, encoder_context);
  1252.     gen8_vme_constant_setup(ctx, encode_state, encoder_context);
  1253.  
  1254.     /*Programing media pipeline*/
  1255.     gen8_vme_vp8_pipeline_programing(ctx, encode_state, is_intra, encoder_context);
  1256.  
  1257.     return vaStatus;
  1258. }
  1259.  
  1260. static VAStatus
  1261. gen8_vme_vp8_pipeline(VADriverContextP ctx,
  1262.                         VAProfile profile,
  1263.                         struct encode_state *encode_state,
  1264.                         struct intel_encoder_context *encoder_context)
  1265. {
  1266.     gen8_vme_media_init(ctx, encoder_context);
  1267.     gen8_vme_vp8_prepare(ctx, encode_state, encoder_context);
  1268.     gen8_vme_run(ctx, encode_state, encoder_context);
  1269.     gen8_vme_stop(ctx, encode_state, encoder_context);
  1270.  
  1271.     return VA_STATUS_SUCCESS;
  1272. }
  1273.  
  1274. static void
  1275. gen8_vme_context_destroy(void *context)
  1276. {
  1277.     struct gen6_vme_context *vme_context = context;
  1278.  
  1279.     gen8_gpe_context_destroy(&vme_context->gpe_context);
  1280.  
  1281.     dri_bo_unreference(vme_context->vme_output.bo);
  1282.     vme_context->vme_output.bo = NULL;
  1283.  
  1284.     dri_bo_unreference(vme_context->vme_state.bo);
  1285.     vme_context->vme_state.bo = NULL;
  1286.  
  1287.     dri_bo_unreference(vme_context->vme_batchbuffer.bo);
  1288.     vme_context->vme_batchbuffer.bo = NULL;
  1289.  
  1290.     if (vme_context->vme_state_message) {
  1291.         free(vme_context->vme_state_message);
  1292.         vme_context->vme_state_message = NULL;
  1293.     }
  1294.  
  1295.     free(vme_context);
  1296. }
  1297.  
  1298. Bool gen8_vme_context_init(VADriverContextP ctx, struct intel_encoder_context *encoder_context)
  1299. {
  1300.     struct gen6_vme_context *vme_context = NULL;
  1301.     struct i965_kernel *vme_kernel_list = NULL;
  1302.     int i965_kernel_num;
  1303.  
  1304.     switch (encoder_context->codec) {
  1305.     case CODEC_H264:
  1306.     case CODEC_H264_MVC:
  1307.         vme_kernel_list = gen8_vme_kernels;
  1308.         encoder_context->vme_pipeline = gen8_vme_pipeline;
  1309.         i965_kernel_num = sizeof(gen8_vme_kernels) / sizeof(struct i965_kernel);
  1310.         break;
  1311.  
  1312.     case CODEC_MPEG2:
  1313.         vme_kernel_list = gen8_vme_mpeg2_kernels;
  1314.         encoder_context->vme_pipeline = gen8_vme_mpeg2_pipeline;
  1315.         i965_kernel_num = sizeof(gen8_vme_mpeg2_kernels) / sizeof(struct i965_kernel);
  1316.         break;
  1317.  
  1318.    case CODEC_JPEG:
  1319.         //JPEG encode doesnt have vme. So, set the corresponding fields to NULL.
  1320.         encoder_context->vme_context = NULL;
  1321.         encoder_context->vme_pipeline = NULL;
  1322.         encoder_context->vme_context_destroy = NULL;
  1323.         break;
  1324.  
  1325.     case CODEC_VP8:
  1326.         vme_kernel_list = gen8_vme_vp8_kernels;
  1327.         encoder_context->vme_pipeline = gen8_vme_vp8_pipeline;
  1328.         i965_kernel_num = sizeof(gen8_vme_vp8_kernels) / sizeof(struct i965_kernel);
  1329.         break;
  1330.  
  1331.     default:
  1332.         /* never get here */
  1333.         assert(0);
  1334.  
  1335.         break;
  1336.     }
  1337.  
  1338.     //If the codec is JPEG, bypass VME
  1339.     if(encoder_context->codec != CODEC_JPEG) {
  1340.         vme_context = calloc(1, sizeof(struct gen6_vme_context));
  1341.         assert(vme_context);
  1342.         vme_context->vme_kernel_sum = i965_kernel_num;
  1343.         vme_context->gpe_context.surface_state_binding_table.length = (SURFACE_STATE_PADDED_SIZE + sizeof(unsigned int)) * MAX_MEDIA_SURFACES_GEN6;
  1344.  
  1345.         vme_context->gpe_context.idrt_size = sizeof(struct gen8_interface_descriptor_data) * MAX_INTERFACE_DESC_GEN6;
  1346.         vme_context->gpe_context.curbe_size = CURBE_TOTAL_DATA_LENGTH;
  1347.         vme_context->gpe_context.sampler_size = 0;
  1348.  
  1349.  
  1350.         vme_context->gpe_context.vfe_state.max_num_threads = 60 - 1;
  1351.         vme_context->gpe_context.vfe_state.num_urb_entries = 64;
  1352.         vme_context->gpe_context.vfe_state.gpgpu_mode = 0;
  1353.         vme_context->gpe_context.vfe_state.urb_entry_size = 16;
  1354.         vme_context->gpe_context.vfe_state.curbe_allocation_size = CURBE_ALLOCATION_SIZE - 1;
  1355.  
  1356.         gen7_vme_scoreboard_init(ctx, vme_context);
  1357.  
  1358.         gen8_gpe_load_kernels(ctx,
  1359.                           &vme_context->gpe_context,
  1360.                           vme_kernel_list,
  1361.                           i965_kernel_num);
  1362.         vme_context->vme_surface2_setup = gen8_gpe_surface2_setup;
  1363.         vme_context->vme_media_rw_surface_setup = gen8_gpe_media_rw_surface_setup;
  1364.         vme_context->vme_buffer_suface_setup = gen8_gpe_buffer_suface_setup;
  1365.         vme_context->vme_media_chroma_surface_setup = gen8_gpe_media_chroma_surface_setup;
  1366.  
  1367.         encoder_context->vme_context = vme_context;
  1368.         encoder_context->vme_context_destroy = gen8_vme_context_destroy;
  1369.  
  1370.         vme_context->vme_state_message = malloc(VME_MSG_LENGTH * sizeof(int));
  1371.     }
  1372.  
  1373.     return True;
  1374. }
  1375.