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