Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /*
  2.  * Copyright © 2009 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.  *    Xiang Haihao <haihao.xiang@intel.com>
  26.  *    Zou Nan hai <nanhai.zou@intel.com>
  27.  *
  28.  */
  29.  
  30. #include <stdlib.h>
  31. #include <stdio.h>
  32. #include <string.h>
  33. #include <assert.h>
  34.  
  35. #include "intel_batchbuffer.h"
  36. #include "intel_driver.h"
  37. #include "i965_defines.h"
  38. #include "i965_drv_video.h"
  39. #include "i965_decoder_utils.h"
  40.  
  41. #include "i965_media.h"
  42. #include "i965_media_mpeg2.h"
  43.  
  44. #define SURFACE_TARGET      0
  45. #define SURFACE_FORWARD     1
  46. #define SURFACE_BACKWARD    2
  47. #define SURFACE_BIDIRECT    3
  48.  
  49. enum interface {
  50.     FRAME_INTRA = 0,
  51.     FRAME_FRAME_PRED_FORWARD,
  52.     FRAME_FRAME_PRED_BACKWARD,
  53.     FRAME_FRAME_PRED_BIDIRECT,
  54.     FRAME_FIELD_PRED_FORWARD,
  55.     FRAME_FIELD_PRED_BACKWARD,
  56.     FRAME_FIELD_PRED_BIDIRECT,
  57.     LIB_INTERFACE,
  58.     FIELD_INTRA,
  59.     FIELD_FORWARD,
  60.     FIELD_FORWARD_16X8,
  61.     FIELD_BACKWARD,
  62.     FIELD_BACKWARD_16X8,
  63.     FIELD_BIDIRECT,
  64.     FIELD_BIDIRECT_16X8
  65. };
  66.  
  67. /* idct table */
  68. #define C0 23170
  69. #define C1 22725
  70. #define C2 21407
  71. #define C3 19266
  72. #define C4 16383
  73. #define C5 12873
  74. #define C6 8867
  75. #define C7 4520
  76. const uint32_t idct_table[] = {
  77.     C4, C1, C2, C3, C4, C5, C6, C7,             //g5
  78.     C4, C1, C2, C3, C4, C5, C6, C7,
  79.     C4, C3, C6,-C7,-C4,-C1,-C2,-C5,
  80.     C4, C3, C6,-C7,-C4,-C1,-C2,-C5,
  81.     C4, C5,-C6,-C1,-C4, C7, C2, C3,
  82.     C4, C5,-C6,-C1,-C4, C7, C2, C3,
  83.     C4, C7,-C2,-C5, C4, C3,-C6,-C1,
  84.     C4, C7,-C2,-C5, C4, C3,-C6,-C1,
  85.     C4,-C7,-C2, C5, C4,-C3,-C6, C1,
  86.     C4,-C7,-C2, C5, C4,-C3,-C6, C1,
  87.     C4,-C5,-C6, C1,-C4,-C7, C2,-C3,
  88.     C4,-C5,-C6, C1,-C4,-C7, C2,-C3,
  89.     C4,-C3, C6, C7,-C4, C1,-C2, C5,
  90.     C4,-C3, C6, C7,-C4, C1,-C2, C5,
  91.     C4,-C1, C2,-C3, C4,-C5, C6,-C7,
  92.     C4,-C1, C2,-C3, C4,-C5, C6,-C7              //g20
  93. };
  94. #undef C0
  95. #undef C1
  96. #undef C2
  97. #undef C3
  98. #undef C4
  99. #undef C5
  100. #undef C6
  101. #undef C7
  102.  
  103. const uint32_t zigzag_direct[64] = {
  104.     0,   1,  8, 16,  9,  2,  3, 10,
  105.     17, 24, 32, 25, 18, 11,  4,  5,
  106.     12, 19, 26, 33, 40, 48, 41, 34,
  107.     27, 20, 13,  6,  7, 14, 21, 28,
  108.     35, 42, 49, 56, 57, 50, 43, 36,
  109.     29, 22, 15, 23, 30, 37, 44, 51,
  110.     58, 59, 52, 45, 38, 31, 39, 46,
  111.     53, 60, 61, 54, 47, 55, 62, 63
  112. };
  113.  
  114. static const uint32_t frame_intra_kernel[][4] = {
  115.    #include "shaders/mpeg2/vld/frame_intra.g4b"
  116. };
  117. static const uint32_t frame_frame_pred_forward_kernel[][4] = {
  118.    #include "shaders/mpeg2/vld/frame_frame_pred_forward.g4b"
  119. };
  120. static const uint32_t frame_frame_pred_backward_kernel[][4] = {
  121.    #include "shaders/mpeg2/vld/frame_frame_pred_backward.g4b"
  122. };
  123. static const uint32_t frame_frame_pred_bidirect_kernel[][4] = {
  124.    #include "shaders/mpeg2/vld/frame_frame_pred_bidirect.g4b"
  125. };
  126. static const uint32_t frame_field_pred_forward_kernel[][4] = {
  127.    #include "shaders/mpeg2/vld/frame_field_pred_forward.g4b"
  128. };
  129. static const uint32_t frame_field_pred_backward_kernel[][4] = {
  130.    #include "shaders/mpeg2/vld/frame_field_pred_backward.g4b"
  131. };
  132. static const uint32_t frame_field_pred_bidirect_kernel[][4] = {
  133.    #include "shaders/mpeg2/vld/frame_field_pred_bidirect.g4b"
  134. };
  135. static const uint32_t lib_kernel[][4] = {
  136.    #include "shaders/mpeg2/vld/lib.g4b"
  137. };
  138. /*field picture*/
  139. static const uint32_t field_intra_kernel[][4] = {
  140.    #include "shaders/mpeg2/vld/field_intra.g4b"
  141. };
  142. static const uint32_t field_forward_kernel[][4] = {
  143.    #include "shaders/mpeg2/vld/field_forward.g4b"
  144. };
  145. static const uint32_t field_forward_16x8_kernel[][4] = {
  146.    #include "shaders/mpeg2/vld/field_forward_16x8.g4b"
  147. };
  148. static const uint32_t field_backward_kernel[][4] = {
  149.    #include "shaders/mpeg2/vld/field_backward.g4b"
  150. };
  151. static const uint32_t field_backward_16x8_kernel[][4] = {
  152.    #include "shaders/mpeg2/vld/field_backward_16x8.g4b"
  153. };
  154. static const uint32_t field_bidirect_kernel[][4] = {
  155.    #include "shaders/mpeg2/vld/field_bidirect.g4b"
  156. };
  157. static const uint32_t field_bidirect_16x8_kernel[][4] = {
  158.    #include "shaders/mpeg2/vld/field_bidirect_16x8.g4b"
  159. };
  160.  
  161. static struct i965_kernel  mpeg2_vld_kernels_gen4[] = {
  162.     {
  163.         "FRAME_INTRA",
  164.         FRAME_INTRA,
  165.         frame_intra_kernel,
  166.         sizeof(frame_intra_kernel),
  167.         NULL
  168.     },
  169.  
  170.     {
  171.         "FRAME_FRAME_PRED_FORWARD",
  172.         FRAME_FRAME_PRED_FORWARD,
  173.         frame_frame_pred_forward_kernel,
  174.         sizeof(frame_frame_pred_forward_kernel),
  175.         NULL
  176.     },
  177.  
  178.     {
  179.         "FRAME_FRAME_PRED_BACKWARD",
  180.         FRAME_FRAME_PRED_BACKWARD,
  181.         frame_frame_pred_backward_kernel,
  182.         sizeof(frame_frame_pred_backward_kernel),
  183.         NULL
  184.     },
  185.  
  186.     {  
  187.         "FRAME_FRAME_PRED_BIDIRECT",
  188.         FRAME_FRAME_PRED_BIDIRECT,
  189.         frame_frame_pred_bidirect_kernel,
  190.         sizeof(frame_frame_pred_bidirect_kernel),
  191.         NULL
  192.     },
  193.  
  194.     {
  195.         "FRAME_FIELD_PRED_FORWARD",
  196.         FRAME_FIELD_PRED_FORWARD,
  197.         frame_field_pred_forward_kernel,
  198.         sizeof(frame_field_pred_forward_kernel),
  199.         NULL
  200.     },
  201.  
  202.     {
  203.         "FRAME_FIELD_PRED_BACKWARD",
  204.         FRAME_FIELD_PRED_BACKWARD,
  205.         frame_field_pred_backward_kernel,
  206.         sizeof(frame_field_pred_backward_kernel),
  207.         NULL
  208.     },
  209.  
  210.     {
  211.         "FRAME_FIELD_PRED_BIDIRECT",
  212.         FRAME_FIELD_PRED_BIDIRECT,
  213.         frame_field_pred_bidirect_kernel,
  214.         sizeof(frame_field_pred_bidirect_kernel),
  215.         NULL
  216.     },
  217.    
  218.     {  
  219.         "LIB",
  220.         LIB_INTERFACE,
  221.         lib_kernel,
  222.         sizeof(lib_kernel),
  223.         NULL
  224.     },
  225.  
  226.     {
  227.         "FIELD_INTRA",
  228.         FIELD_INTRA,
  229.         field_intra_kernel,
  230.         sizeof(field_intra_kernel),
  231.         NULL
  232.     },
  233.  
  234.     {
  235.         "FIELD_FORWARD",
  236.         FIELD_FORWARD,
  237.         field_forward_kernel,
  238.         sizeof(field_forward_kernel),
  239.         NULL
  240.     },
  241.  
  242.     {
  243.         "FIELD_FORWARD_16X8",
  244.         FIELD_FORWARD_16X8,
  245.         field_forward_16x8_kernel,
  246.         sizeof(field_forward_16x8_kernel),
  247.         NULL
  248.     },
  249.  
  250.     {
  251.         "FIELD_BACKWARD",
  252.         FIELD_BACKWARD,
  253.         field_backward_kernel,
  254.         sizeof(field_backward_kernel),
  255.         NULL
  256.     },
  257.  
  258.     {
  259.         "FIELD_BACKWARD_16X8",
  260.         FIELD_BACKWARD_16X8,
  261.         field_backward_16x8_kernel,
  262.         sizeof(field_backward_16x8_kernel),
  263.         NULL
  264.     },
  265.  
  266.     {
  267.         "FIELD_BIDIRECT",
  268.         FIELD_BIDIRECT,
  269.         field_bidirect_kernel,
  270.         sizeof(field_bidirect_kernel),
  271.         NULL
  272.     },
  273.  
  274.     {
  275.         "FIELD_BIDIRECT_16X8",
  276.         FIELD_BIDIRECT_16X8,
  277.         field_bidirect_16x8_kernel,
  278.         sizeof(field_bidirect_16x8_kernel),
  279.         NULL
  280.     }
  281. };
  282.  
  283. /* On IRONLAKE */
  284. static const uint32_t frame_intra_kernel_gen5[][4] = {
  285.    #include "shaders/mpeg2/vld/frame_intra.g4b.gen5"
  286. };
  287. static const uint32_t frame_frame_pred_forward_kernel_gen5[][4] = {
  288.    #include "shaders/mpeg2/vld/frame_frame_pred_forward.g4b.gen5"
  289. };
  290. static const uint32_t frame_frame_pred_backward_kernel_gen5[][4] = {
  291.    #include "shaders/mpeg2/vld/frame_frame_pred_backward.g4b.gen5"
  292. };
  293. static const uint32_t frame_frame_pred_bidirect_kernel_gen5[][4] = {
  294.    #include "shaders/mpeg2/vld/frame_frame_pred_bidirect.g4b.gen5"
  295. };
  296. static const uint32_t frame_field_pred_forward_kernel_gen5[][4] = {
  297.    #include "shaders/mpeg2/vld/frame_field_pred_forward.g4b.gen5"
  298. };
  299. static const uint32_t frame_field_pred_backward_kernel_gen5[][4] = {
  300.    #include "shaders/mpeg2/vld/frame_field_pred_backward.g4b.gen5"
  301. };
  302. static const uint32_t frame_field_pred_bidirect_kernel_gen5[][4] = {
  303.    #include "shaders/mpeg2/vld/frame_field_pred_bidirect.g4b.gen5"
  304. };
  305. static const uint32_t lib_kernel_gen5[][4] = {
  306.    #include "shaders/mpeg2/vld/lib.g4b.gen5"
  307. };
  308. /*field picture*/
  309. static const uint32_t field_intra_kernel_gen5[][4] = {
  310.    #include "shaders/mpeg2/vld/field_intra.g4b.gen5"
  311. };
  312. static const uint32_t field_forward_kernel_gen5[][4] = {
  313.    #include "shaders/mpeg2/vld/field_forward.g4b.gen5"
  314. };
  315. static const uint32_t field_forward_16x8_kernel_gen5[][4] = {
  316.    #include "shaders/mpeg2/vld/field_forward_16x8.g4b.gen5"
  317. };
  318. static const uint32_t field_backward_kernel_gen5[][4] = {
  319.    #include "shaders/mpeg2/vld/field_backward.g4b.gen5"
  320. };
  321. static const uint32_t field_backward_16x8_kernel_gen5[][4] = {
  322.    #include "shaders/mpeg2/vld/field_backward_16x8.g4b.gen5"
  323. };
  324. static const uint32_t field_bidirect_kernel_gen5[][4] = {
  325.    #include "shaders/mpeg2/vld/field_bidirect.g4b.gen5"
  326. };
  327. static const uint32_t field_bidirect_16x8_kernel_gen5[][4] = {
  328.    #include "shaders/mpeg2/vld/field_bidirect_16x8.g4b.gen5"
  329. };
  330.  
  331. static struct i965_kernel  mpeg2_vld_kernels_gen5[] = {
  332.     {
  333.         "FRAME_INTRA",
  334.         FRAME_INTRA,
  335.         frame_intra_kernel_gen5,
  336.         sizeof(frame_intra_kernel_gen5),
  337.         NULL
  338.     },
  339.  
  340.     {
  341.         "FRAME_FRAME_PRED_FORWARD",
  342.         FRAME_FRAME_PRED_FORWARD,
  343.         frame_frame_pred_forward_kernel_gen5,
  344.         sizeof(frame_frame_pred_forward_kernel_gen5),
  345.         NULL
  346.     },
  347.  
  348.     {
  349.         "FRAME_FRAME_PRED_BACKWARD",
  350.         FRAME_FRAME_PRED_BACKWARD,
  351.         frame_frame_pred_backward_kernel_gen5,
  352.         sizeof(frame_frame_pred_backward_kernel_gen5),
  353.         NULL
  354.     },
  355.  
  356.     {  
  357.         "FRAME_FRAME_PRED_BIDIRECT",
  358.         FRAME_FRAME_PRED_BIDIRECT,
  359.         frame_frame_pred_bidirect_kernel_gen5,
  360.         sizeof(frame_frame_pred_bidirect_kernel_gen5),
  361.         NULL
  362.     },
  363.  
  364.     {
  365.         "FRAME_FIELD_PRED_FORWARD",
  366.         FRAME_FIELD_PRED_FORWARD,
  367.         frame_field_pred_forward_kernel_gen5,
  368.         sizeof(frame_field_pred_forward_kernel_gen5),
  369.         NULL
  370.     },
  371.  
  372.     {
  373.         "FRAME_FIELD_PRED_BACKWARD",
  374.         FRAME_FIELD_PRED_BACKWARD,
  375.         frame_field_pred_backward_kernel_gen5,
  376.         sizeof(frame_field_pred_backward_kernel_gen5),
  377.         NULL
  378.     },
  379.  
  380.     {
  381.         "FRAME_FIELD_PRED_BIDIRECT",
  382.         FRAME_FIELD_PRED_BIDIRECT,
  383.         frame_field_pred_bidirect_kernel_gen5,
  384.         sizeof(frame_field_pred_bidirect_kernel_gen5),
  385.         NULL
  386.     },
  387.    
  388.     {  
  389.         "LIB",
  390.         LIB_INTERFACE,
  391.         lib_kernel_gen5,
  392.         sizeof(lib_kernel_gen5),
  393.         NULL
  394.     },
  395.  
  396.     {
  397.         "FIELD_INTRA",
  398.         FIELD_INTRA,
  399.         field_intra_kernel_gen5,
  400.         sizeof(field_intra_kernel_gen5),
  401.         NULL
  402.     },
  403.  
  404.     {
  405.         "FIELD_FORWARD",
  406.         FIELD_FORWARD,
  407.         field_forward_kernel_gen5,
  408.         sizeof(field_forward_kernel_gen5),
  409.         NULL
  410.     },
  411.  
  412.     {
  413.         "FIELD_FORWARD_16X8",
  414.         FIELD_FORWARD_16X8,
  415.         field_forward_16x8_kernel_gen5,
  416.         sizeof(field_forward_16x8_kernel_gen5),
  417.         NULL
  418.     },
  419.  
  420.     {
  421.         "FIELD_BACKWARD",
  422.         FIELD_BACKWARD,
  423.         field_backward_kernel_gen5,
  424.         sizeof(field_backward_kernel_gen5),
  425.         NULL
  426.     },
  427.  
  428.     {
  429.         "FIELD_BACKWARD_16X8",
  430.         FIELD_BACKWARD_16X8,
  431.         field_backward_16x8_kernel_gen5,
  432.         sizeof(field_backward_16x8_kernel_gen5),
  433.         NULL
  434.     },
  435.  
  436.     {
  437.         "FIELD_BIDIRECT",
  438.         FIELD_BIDIRECT,
  439.         field_bidirect_kernel_gen5,
  440.         sizeof(field_bidirect_kernel_gen5),
  441.         NULL
  442.     },
  443.  
  444.     {
  445.         "FIELD_BIDIRECT_16X8",
  446.         FIELD_BIDIRECT_16X8,
  447.         field_bidirect_16x8_kernel_gen5,
  448.         sizeof(field_bidirect_16x8_kernel_gen5),
  449.         NULL
  450.     }
  451. };
  452.  
  453. static void
  454. i965_media_mpeg2_surface_state(VADriverContextP ctx,
  455.                                int index,
  456.                                struct object_surface *obj_surface,
  457.                                unsigned long offset,
  458.                                int w, int h,
  459.                                Bool is_dst,
  460.                                int vert_line_stride,
  461.                                int vert_line_stride_ofs,
  462.                                struct i965_media_context *media_context)
  463. {
  464.     struct i965_driver_data *i965 = i965_driver_data(ctx);  
  465.     struct i965_surface_state *ss;
  466.     dri_bo *bo;
  467.     uint32_t write_domain, read_domain;
  468.  
  469.     bo = dri_bo_alloc(i965->intel.bufmgr,
  470.                       "surface state",
  471.                       sizeof(struct i965_surface_state), 32);
  472.     assert(bo);
  473.     dri_bo_map(bo, 1);
  474.     assert(bo->virtual);
  475.     ss = bo->virtual;
  476.     memset(ss, 0, sizeof(*ss));
  477.     ss->ss0.surface_type = I965_SURFACE_2D;
  478.     ss->ss0.surface_format = I965_SURFACEFORMAT_R8_SINT;
  479.     ss->ss0.vert_line_stride = vert_line_stride;
  480.     ss->ss0.vert_line_stride_ofs = vert_line_stride_ofs;
  481.     ss->ss1.base_addr = obj_surface->bo->offset + offset;
  482.     ss->ss2.width = w - 1;
  483.     ss->ss2.height = h - 1;
  484.     ss->ss3.pitch = w - 1;
  485.  
  486.     if (is_dst) {
  487.         write_domain = I915_GEM_DOMAIN_RENDER;
  488.         read_domain = I915_GEM_DOMAIN_RENDER;
  489.     } else {
  490.         write_domain = 0;
  491.         read_domain = I915_GEM_DOMAIN_SAMPLER;
  492.     }
  493.  
  494.     dri_bo_emit_reloc(bo,
  495.                       read_domain, write_domain,
  496.                       offset,
  497.                       offsetof(struct i965_surface_state, ss1),
  498.                       obj_surface->bo);
  499.     dri_bo_unmap(bo);
  500.  
  501.     assert(index < MAX_MEDIA_SURFACES);
  502. //    assert(media_context->surface_state[index].bo == NULL);
  503.     media_context->surface_state[index].bo = bo;
  504. }
  505.  
  506. static void
  507. i965_media_mpeg2_surface_setup(VADriverContextP ctx,
  508.                                int base_index,
  509.                                struct object_surface *obj_surface,
  510.                                Bool is_dst,
  511.                                int picture_structure,
  512.                                int surface,
  513.                                struct i965_media_context *media_context)
  514. {
  515.     int w = obj_surface->width;
  516.     int h = obj_surface->height;
  517.  
  518.     i965_check_alloc_surface_bo(ctx, obj_surface, 0, VA_FOURCC_I420, SUBSAMPLE_YUV420);
  519.  
  520.     if (picture_structure == MPEG_FRAME) {
  521.         i965_media_mpeg2_surface_state(ctx, base_index + 0, obj_surface,
  522.                                        0, w, h,
  523.                                        is_dst, 0, 0,
  524.                                        media_context);
  525.         i965_media_mpeg2_surface_state(ctx, base_index + 1, obj_surface,
  526.                                        w * h, w / 2, h / 2,
  527.                                        is_dst, 0, 0,
  528.                                        media_context);
  529.         i965_media_mpeg2_surface_state(ctx, base_index + 2, obj_surface,
  530.                                        w * h + w * h / 4, w / 2, h / 2,
  531.                                        is_dst, 0, 0,
  532.                                        media_context);
  533.     } else {
  534.         if (surface == SURFACE_TARGET) {
  535.             i965_media_mpeg2_surface_state(ctx, 3, obj_surface,
  536.                                            0, w, h,
  537.                                            False, 0, 0,
  538.                                            media_context);
  539.             i965_media_mpeg2_surface_state(ctx, 10, obj_surface,
  540.                                            w * h, w / 2, h / 2,
  541.                                            False, 0, 0,
  542.                                            media_context);
  543.             i965_media_mpeg2_surface_state(ctx, 11, obj_surface,
  544.                                            w * h + w * h / 4, w / 2, h / 2,
  545.                                            False, 0, 0,
  546.                                            media_context);
  547.             if (picture_structure == MPEG_TOP_FIELD) {
  548.                 i965_media_mpeg2_surface_state(ctx, base_index + 0, obj_surface,
  549.                                                0, w, h,
  550.                                                True, 1, 0,
  551.                                                media_context);
  552.                 i965_media_mpeg2_surface_state(ctx, base_index + 1, obj_surface,
  553.                                                w * h, w / 2, h / 2,
  554.                                                True, 1, 0,
  555.                                                media_context);
  556.                 i965_media_mpeg2_surface_state(ctx, base_index + 2, obj_surface,
  557.                                                w * h + w * h / 4, w / 2, h / 2,
  558.                                                True, 1, 0,
  559.                                                media_context);
  560.             } else {
  561.                 assert(picture_structure == MPEG_BOTTOM_FIELD);
  562.                 i965_media_mpeg2_surface_state(ctx, base_index + 0, obj_surface,
  563.                                                0, w, h,
  564.                                                True, 1, 1,
  565.                                                media_context);
  566.                 i965_media_mpeg2_surface_state(ctx, base_index + 1, obj_surface,
  567.                                                w * h, w / 2, h / 2,
  568.                                                True, 1, 1,
  569.                                                media_context);
  570.                 i965_media_mpeg2_surface_state(ctx, base_index + 2, obj_surface,
  571.                                                w * h + w * h / 4, w / 2, h / 2,
  572.                                                True, 1, 1,
  573.                                                media_context);
  574.             }
  575.         } else {
  576.             i965_media_mpeg2_surface_state(ctx, base_index + 0, obj_surface,
  577.                                            0, w, h,
  578.                                            is_dst, 0, 0,
  579.                                            media_context);
  580.             i965_media_mpeg2_surface_state(ctx, base_index + 1, obj_surface,
  581.                                            w * h, w / 2, h / 2,
  582.                                            is_dst, 0, 0,
  583.                                            media_context);
  584.             i965_media_mpeg2_surface_state(ctx, base_index + 2, obj_surface,
  585.                                            w * h + w * h / 4, w / 2, h / 2,
  586.                                            is_dst, 0, 0,
  587.                                            media_context);
  588.         }
  589.     }
  590. }
  591.  
  592. void
  593. i965_media_mpeg2_surfaces_setup(VADriverContextP ctx,
  594.                                 struct decode_state *decode_state,
  595.                                 struct i965_media_context *media_context)
  596. {
  597.     struct object_surface *obj_surface;
  598.     VAPictureParameterBufferMPEG2 *param;
  599.  
  600.     assert(decode_state->pic_param && decode_state->pic_param->buffer);
  601.     param = (VAPictureParameterBufferMPEG2 *)decode_state->pic_param->buffer;
  602.  
  603.     obj_surface = decode_state->render_object;
  604.  
  605.     i965_media_mpeg2_surface_setup(ctx, 0, obj_surface, True,
  606.                                    param->picture_coding_extension.bits.picture_structure,
  607.                                    SURFACE_TARGET,
  608.                                    media_context);
  609.  
  610.     obj_surface = decode_state->reference_objects[0];
  611.  
  612.     if (!obj_surface) {
  613. //        assert(param->picture_coding_type == 1); /* I-picture */
  614.     } else {
  615.         i965_media_mpeg2_surface_setup(ctx, 4, obj_surface, False,
  616.                                        param->picture_coding_extension.bits.picture_structure,
  617.                                        SURFACE_FORWARD,
  618.                                        media_context);
  619.  
  620.         obj_surface = decode_state->reference_objects[1];
  621.  
  622.         if (!obj_surface) {
  623.             assert(param->picture_coding_type == 2); /* P-picture */
  624.  
  625.             obj_surface = decode_state->reference_objects[0];
  626.             i965_media_mpeg2_surface_setup(ctx, 7, obj_surface, False,
  627.                                            param->picture_coding_extension.bits.picture_structure,
  628.                                            SURFACE_BACKWARD,
  629.                                            media_context);
  630.         } else {
  631.             assert(param->picture_coding_type == 3); /* B-picture */
  632.             i965_media_mpeg2_surface_setup(ctx, 7, obj_surface, False,
  633.                                            param->picture_coding_extension.bits.picture_structure,
  634.                                            SURFACE_BIDIRECT,
  635.                                            media_context);
  636.         }
  637.     }
  638. }
  639.  
  640. static void
  641. i965_media_mpeg2_binding_table(VADriverContextP ctx, struct i965_media_context *media_context)
  642. {
  643.     int i;
  644.     unsigned int *binding_table;
  645.     dri_bo *bo = media_context->binding_table.bo;
  646.  
  647.     dri_bo_map(bo, 1);
  648.     assert(bo->virtual);
  649.     binding_table = bo->virtual;
  650.     memset(binding_table, 0, bo->size);
  651.  
  652.     for (i = 0; i < MAX_MEDIA_SURFACES; i++) {
  653.         if (media_context->surface_state[i].bo) {
  654.             binding_table[i] = media_context->surface_state[i].bo->offset;
  655.             dri_bo_emit_reloc(bo,
  656.                               I915_GEM_DOMAIN_INSTRUCTION, 0,
  657.                               0,
  658.                               i * sizeof(*binding_table),
  659.                               media_context->surface_state[i].bo);
  660.         }
  661.     }
  662.  
  663.     dri_bo_unmap(media_context->binding_table.bo);
  664. }
  665.  
  666. static void
  667. i965_media_mpeg2_vfe_state(VADriverContextP ctx, struct i965_media_context *media_context)
  668. {
  669.     struct i965_vfe_state *vfe_state;
  670.     dri_bo *bo;
  671.  
  672.     bo = media_context->vfe_state.bo;
  673.     dri_bo_map(bo, 1);
  674.     assert(bo->virtual);
  675.     vfe_state = bo->virtual;
  676.     memset(vfe_state, 0, sizeof(*vfe_state));
  677.     vfe_state->vfe0.extend_vfe_state_present = 1;
  678.     vfe_state->vfe1.vfe_mode = VFE_VLD_MODE;
  679.     vfe_state->vfe1.num_urb_entries = media_context->urb.num_vfe_entries;
  680.     vfe_state->vfe1.children_present = 0;
  681.     vfe_state->vfe1.urb_entry_alloc_size = media_context->urb.size_vfe_entry - 1;
  682.     vfe_state->vfe1.max_threads = media_context->urb.num_vfe_entries - 1;
  683.     vfe_state->vfe2.interface_descriptor_base =
  684.         media_context->idrt.bo->offset >> 4; /* reloc */
  685.     dri_bo_emit_reloc(bo,
  686.                       I915_GEM_DOMAIN_INSTRUCTION, 0,
  687.                       0,
  688.                       offsetof(struct i965_vfe_state, vfe2),
  689.                       media_context->idrt.bo);
  690.     dri_bo_unmap(bo);
  691. }
  692.  
  693. static void
  694. i965_media_mpeg2_interface_descriptor_remap_table(VADriverContextP ctx, struct i965_media_context *media_context)
  695. {
  696.     struct i965_mpeg2_context *i965_mpeg2_context = (struct i965_mpeg2_context *)media_context->private_context;
  697.     struct i965_interface_descriptor *desc;
  698.     int i;
  699.     dri_bo *bo;
  700.  
  701.     bo = media_context->idrt.bo;
  702.     dri_bo_map(bo, 1);
  703.     assert(bo->virtual);
  704.     desc = bo->virtual;
  705.  
  706.     for (i = 0; i < NUM_MPEG2_VLD_KERNELS; i++) {
  707.         memset(desc, 0, sizeof(*desc));
  708.         desc->desc0.grf_reg_blocks = 15;
  709.         desc->desc0.kernel_start_pointer = i965_mpeg2_context->vld_kernels[i].bo->offset >> 6; /* reloc */
  710.         desc->desc1.const_urb_entry_read_offset = 0;
  711.         desc->desc1.const_urb_entry_read_len = 30;
  712.         desc->desc3.binding_table_entry_count = 0;
  713.         desc->desc3.binding_table_pointer =
  714.             media_context->binding_table.bo->offset >> 5; /*reloc */
  715.  
  716.         dri_bo_emit_reloc(bo,
  717.                           I915_GEM_DOMAIN_INSTRUCTION, 0,
  718.                           desc->desc0.grf_reg_blocks,
  719.                           i * sizeof(*desc) + offsetof(struct i965_interface_descriptor, desc0),
  720.                           i965_mpeg2_context->vld_kernels[i].bo);
  721.  
  722.         dri_bo_emit_reloc(bo,
  723.                           I915_GEM_DOMAIN_INSTRUCTION, 0,
  724.                           desc->desc3.binding_table_entry_count,
  725.                           i * sizeof(*desc) + offsetof(struct i965_interface_descriptor, desc3),
  726.                           media_context->binding_table.bo);
  727.         desc++;
  728.     }
  729.  
  730.     dri_bo_unmap(bo);
  731. }
  732.  
  733. void
  734. i965_media_mpeg2_vld_state(VADriverContextP ctx,
  735.                            struct decode_state *decode_state,
  736.                            struct i965_media_context *media_context)
  737. {
  738.     struct i965_vld_state *vld_state;
  739.     VAPictureParameterBufferMPEG2 *param;
  740.  
  741.     assert(decode_state->pic_param && decode_state->pic_param->buffer);
  742.     param = (VAPictureParameterBufferMPEG2 *)decode_state->pic_param->buffer;
  743.  
  744.     assert(media_context->extended_state.bo);
  745.     dri_bo_map(media_context->extended_state.bo, 1);
  746.     assert(media_context->extended_state.bo->virtual);
  747.     vld_state = media_context->extended_state.bo->virtual;
  748.     memset(vld_state, 0, sizeof(*vld_state));
  749.  
  750.     vld_state->vld0.f_code_0_0 = ((param->f_code >> 12) & 0xf);
  751.     vld_state->vld0.f_code_0_1 = ((param->f_code >> 8) & 0xf);
  752.     vld_state->vld0.f_code_1_0 = ((param->f_code >> 4) & 0xf);
  753.     vld_state->vld0.f_code_1_1 = (param->f_code & 0xf);
  754.     vld_state->vld0.intra_dc_precision = param->picture_coding_extension.bits.intra_dc_precision;
  755.     vld_state->vld0.picture_structure = param->picture_coding_extension.bits.picture_structure;
  756.     vld_state->vld0.top_field_first = param->picture_coding_extension.bits.top_field_first;
  757.     vld_state->vld0.frame_predict_frame_dct = param->picture_coding_extension.bits.frame_pred_frame_dct;
  758.     vld_state->vld0.concealment_motion_vector = param->picture_coding_extension.bits.concealment_motion_vectors;
  759.     vld_state->vld0.quantizer_scale_type = param->picture_coding_extension.bits.q_scale_type;
  760.     vld_state->vld0.intra_vlc_format = param->picture_coding_extension.bits.intra_vlc_format;
  761.     vld_state->vld0.scan_order = param->picture_coding_extension.bits.alternate_scan;
  762.  
  763.     vld_state->vld1.picture_coding_type = param->picture_coding_type;
  764.  
  765.     if (vld_state->vld0.picture_structure == MPEG_FRAME) {
  766.         /*frame picture*/
  767.         vld_state->desc_remap_table0.index_0 = FRAME_INTRA;
  768.         vld_state->desc_remap_table0.index_1 = FRAME_FRAME_PRED_FORWARD;
  769.         vld_state->desc_remap_table0.index_2 = FRAME_FIELD_PRED_FORWARD;
  770.         vld_state->desc_remap_table0.index_3 = FRAME_FIELD_PRED_BIDIRECT; /* dual prime */
  771.         vld_state->desc_remap_table0.index_4 = FRAME_FRAME_PRED_BACKWARD;
  772.         vld_state->desc_remap_table0.index_5 = FRAME_FIELD_PRED_BACKWARD;
  773.         vld_state->desc_remap_table0.index_6 = FRAME_FRAME_PRED_BIDIRECT;
  774.         vld_state->desc_remap_table0.index_7 = FRAME_FIELD_PRED_BIDIRECT;
  775.  
  776.         vld_state->desc_remap_table1.index_8 = FRAME_INTRA;
  777.         vld_state->desc_remap_table1.index_9 = FRAME_FRAME_PRED_FORWARD;
  778.         vld_state->desc_remap_table1.index_10 = FRAME_FIELD_PRED_FORWARD;
  779.         vld_state->desc_remap_table1.index_11 = FRAME_FIELD_PRED_BIDIRECT;
  780.         vld_state->desc_remap_table1.index_12 = FRAME_FRAME_PRED_BACKWARD;
  781.         vld_state->desc_remap_table1.index_13 = FRAME_FIELD_PRED_BACKWARD;
  782.         vld_state->desc_remap_table1.index_14 = FRAME_FRAME_PRED_BIDIRECT;
  783.         vld_state->desc_remap_table1.index_15 = FRAME_FIELD_PRED_BIDIRECT;
  784.     } else {
  785.         /*field picture*/
  786.         vld_state->desc_remap_table0.index_0 = FIELD_INTRA;
  787.         vld_state->desc_remap_table0.index_1 = FIELD_FORWARD;
  788.         vld_state->desc_remap_table0.index_2 = FIELD_FORWARD_16X8;
  789.         vld_state->desc_remap_table0.index_3 = FIELD_BIDIRECT; /* dual prime */
  790.         vld_state->desc_remap_table0.index_4 = FIELD_BACKWARD;
  791.         vld_state->desc_remap_table0.index_5 = FIELD_BACKWARD_16X8;
  792.         vld_state->desc_remap_table0.index_6 = FIELD_BIDIRECT;
  793.         vld_state->desc_remap_table0.index_7 = FIELD_BIDIRECT_16X8;
  794.     }
  795.  
  796.     dri_bo_unmap(media_context->extended_state.bo);
  797. }
  798.  
  799. static void
  800. i965_media_mpeg2_upload_constants(VADriverContextP ctx,
  801.                                   struct decode_state *decode_state,
  802.                                   struct i965_media_context *media_context)
  803. {
  804.     struct i965_mpeg2_context *i965_mpeg2_context = (struct i965_mpeg2_context *)media_context->private_context;
  805.     VAIQMatrixBufferMPEG2 * const gen_iq_matrix = &i965_mpeg2_context->iq_matrix;
  806.     int i;
  807.     unsigned char *constant_buffer;
  808.     unsigned int *lib_reloc;
  809.     int lib_reloc_offset = 0;
  810.  
  811.     dri_bo_map(media_context->curbe.bo, 1);
  812.     assert(media_context->curbe.bo->virtual);
  813.     constant_buffer = media_context->curbe.bo->virtual;
  814.  
  815.     /* iq_matrix */
  816.     if (decode_state->iq_matrix && decode_state->iq_matrix->buffer) {
  817.         VAIQMatrixBufferMPEG2 * const iq_matrix =
  818.             (VAIQMatrixBufferMPEG2 *)decode_state->iq_matrix->buffer;
  819.  
  820.         gen_iq_matrix->load_intra_quantiser_matrix =
  821.             iq_matrix->load_intra_quantiser_matrix;
  822.         if (iq_matrix->load_intra_quantiser_matrix) {
  823.             for (i = 0; i < 64; i++)
  824.                 gen_iq_matrix->intra_quantiser_matrix[zigzag_direct[i]] =
  825.                     iq_matrix->intra_quantiser_matrix[i];
  826.         }
  827.  
  828.         gen_iq_matrix->load_non_intra_quantiser_matrix =
  829.             iq_matrix->load_non_intra_quantiser_matrix;
  830.         if (iq_matrix->load_non_intra_quantiser_matrix) {
  831.             for (i = 0; i < 64; i++)
  832.                 gen_iq_matrix->non_intra_quantiser_matrix[zigzag_direct[i]] =
  833.                     iq_matrix->non_intra_quantiser_matrix[i];
  834.         }
  835.  
  836.         /* no chroma quantisation matrices for 4:2:0 data */
  837.     }
  838.  
  839.     if (gen_iq_matrix->load_intra_quantiser_matrix) {
  840.         unsigned char * const qm = constant_buffer;
  841.         memcpy(qm, gen_iq_matrix->intra_quantiser_matrix, 64);
  842.     }
  843.  
  844.     if (gen_iq_matrix->load_non_intra_quantiser_matrix) {
  845.         unsigned char * const qm = constant_buffer + 64;
  846.         memcpy(qm, gen_iq_matrix->non_intra_quantiser_matrix, 64);
  847.     }
  848.  
  849.     /* idct table */
  850.     memcpy(constant_buffer + 128, idct_table, sizeof(idct_table));
  851.  
  852.     /* idct lib reloc */
  853.     lib_reloc_offset = 128 + sizeof(idct_table);
  854.     lib_reloc = (unsigned int *)(constant_buffer + lib_reloc_offset);
  855.     for (i = 0; i < 8; i++) {
  856.         lib_reloc[i] = i965_mpeg2_context->vld_kernels[LIB_INTERFACE].bo->offset;
  857.         dri_bo_emit_reloc(media_context->curbe.bo,
  858.                           I915_GEM_DOMAIN_INSTRUCTION, 0,
  859.                           0,
  860.                           lib_reloc_offset + i * sizeof(unsigned int),
  861.                           i965_mpeg2_context->vld_kernels[LIB_INTERFACE].bo);
  862.     }
  863.  
  864.     dri_bo_unmap(media_context->curbe.bo);
  865. }
  866.  
  867. static void
  868. i965_media_mpeg2_states_setup(VADriverContextP ctx,
  869.                               struct decode_state *decode_state,
  870.                               struct i965_media_context *media_context)
  871. {
  872.     i965_media_mpeg2_surfaces_setup(ctx, decode_state, media_context);
  873.     i965_media_mpeg2_binding_table(ctx, media_context);
  874.     i965_media_mpeg2_interface_descriptor_remap_table(ctx, media_context);
  875.     i965_media_mpeg2_vld_state(ctx, decode_state, media_context);
  876.     i965_media_mpeg2_vfe_state(ctx, media_context);
  877.     i965_media_mpeg2_upload_constants(ctx, decode_state, media_context);
  878. }
  879.  
  880. static void
  881. i965_media_mpeg2_objects(VADriverContextP ctx,
  882.                          struct decode_state *decode_state,
  883.                          struct i965_media_context *media_context)
  884. {
  885.     struct i965_mpeg2_context * const i965_mpeg2_context = media_context->private_context;
  886.     struct intel_batchbuffer *batch = media_context->base.batch;
  887.     VASliceParameterBufferMPEG2 *slice_param;
  888.     VAPictureParameterBufferMPEG2 *pic_param;
  889.     int i, j;
  890.  
  891.     assert(decode_state->pic_param && decode_state->pic_param->buffer);
  892.     pic_param = (VAPictureParameterBufferMPEG2 *)decode_state->pic_param->buffer;
  893.  
  894.     if (i965_mpeg2_context->wa_slice_vertical_position < 0)
  895.         i965_mpeg2_context->wa_slice_vertical_position =
  896.             mpeg2_wa_slice_vertical_position(decode_state, pic_param);
  897.  
  898.     for (j = 0; j < decode_state->num_slice_params; j++) {
  899.         assert(decode_state->slice_params[j] && decode_state->slice_params[j]->buffer);
  900.         assert(decode_state->slice_datas[j] && decode_state->slice_datas[j]->bo);
  901.         slice_param = (VASliceParameterBufferMPEG2 *)decode_state->slice_params[j]->buffer;
  902.  
  903.         for (i = 0; i < decode_state->slice_params[j]->num_elements; i++) {
  904.             int vpos, hpos, is_field_pic = 0;
  905.  
  906.             if (i965_mpeg2_context->wa_slice_vertical_position > 0 &&
  907.                 (pic_param->picture_coding_extension.bits.picture_structure == MPEG_TOP_FIELD ||
  908.                  pic_param->picture_coding_extension.bits.picture_structure == MPEG_BOTTOM_FIELD))
  909.                 is_field_pic = 1;
  910.  
  911.             assert(slice_param->slice_data_flag == VA_SLICE_DATA_FLAG_ALL);
  912.             vpos = slice_param->slice_vertical_position / (1 + is_field_pic);
  913.             hpos = slice_param->slice_horizontal_position;
  914.  
  915.             BEGIN_BATCH(batch, 6);
  916.             OUT_BATCH(batch, CMD_MEDIA_OBJECT | 4);
  917.             OUT_BATCH(batch, 0);
  918.             OUT_BATCH(batch, slice_param->slice_data_size - (slice_param->macroblock_offset >> 3));
  919.             OUT_RELOC(batch, decode_state->slice_datas[j]->bo,
  920.                       I915_GEM_DOMAIN_SAMPLER, 0,
  921.                       slice_param->slice_data_offset + (slice_param->macroblock_offset >> 3));
  922.             OUT_BATCH(batch,
  923.                       ((hpos << 24) |    
  924.                        (vpos << 16) |
  925.                        (127 << 8) |
  926.                        (slice_param->macroblock_offset & 0x7)));
  927.             OUT_BATCH(batch, slice_param->quantiser_scale_code << 24);
  928.             ADVANCE_BATCH(batch);          
  929.             slice_param++;
  930.         }
  931.     }
  932. }
  933.  
  934. static void
  935. i965_media_mpeg2_free_private_context(void **data)
  936. {
  937.     struct i965_mpeg2_context *i965_mpeg2_context = *data;
  938.     int i;
  939.  
  940.     if (i965_mpeg2_context == NULL)
  941.         return;
  942.  
  943.     for (i = 0; i < NUM_MPEG2_VLD_KERNELS; i++) {
  944.         struct i965_kernel *kernel = &i965_mpeg2_context->vld_kernels[i];
  945.  
  946.         dri_bo_unreference(kernel->bo);
  947.         kernel->bo = NULL;
  948.     }
  949.  
  950.     free(i965_mpeg2_context);
  951.     *data = NULL;
  952. }
  953.  
  954. void
  955. i965_media_mpeg2_decode_init(VADriverContextP ctx,
  956.                              struct decode_state *decode_state,
  957.                              struct i965_media_context *media_context)
  958. {
  959.     struct i965_driver_data *i965 = i965_driver_data(ctx);
  960.     dri_bo *bo;
  961.  
  962.     dri_bo_unreference(media_context->indirect_object.bo);
  963.     media_context->indirect_object.bo = NULL;
  964.  
  965.     media_context->extended_state.enabled = 1;
  966.     dri_bo_unreference(media_context->extended_state.bo);
  967.     bo = dri_bo_alloc(i965->intel.bufmgr,
  968.                       "vld state",
  969.                       sizeof(struct i965_vld_state), 32);
  970.     assert(bo);
  971.     media_context->extended_state.bo = bo;
  972. }
  973.  
  974. void
  975. i965_media_mpeg2_dec_context_init(VADriverContextP ctx, struct i965_media_context *media_context)
  976. {
  977.     struct i965_driver_data *i965 = i965_driver_data(ctx);
  978.     struct i965_mpeg2_context *i965_mpeg2_context;
  979.     int i;
  980.  
  981.     i965_mpeg2_context = calloc(1, sizeof(struct i965_mpeg2_context));
  982.     i965_mpeg2_context->wa_slice_vertical_position = -1;
  983.  
  984.     /* kernel */
  985.     assert(NUM_MPEG2_VLD_KERNELS == (sizeof(mpeg2_vld_kernels_gen4) /
  986.                                      sizeof(mpeg2_vld_kernels_gen4[0])));
  987.     assert(NUM_MPEG2_VLD_KERNELS == (sizeof(mpeg2_vld_kernels_gen5) /
  988.                                      sizeof(mpeg2_vld_kernels_gen5[0])));
  989.     assert(NUM_MPEG2_VLD_KERNELS <= MAX_INTERFACE_DESC);
  990.  
  991.     if (IS_IRONLAKE(i965->intel.device_info))
  992.         memcpy(i965_mpeg2_context->vld_kernels, mpeg2_vld_kernels_gen5, sizeof(i965_mpeg2_context->vld_kernels));
  993.     else
  994.         memcpy(i965_mpeg2_context->vld_kernels, mpeg2_vld_kernels_gen4, sizeof(i965_mpeg2_context->vld_kernels));
  995.  
  996.     for (i = 0; i < NUM_MPEG2_VLD_KERNELS; i++) {
  997.         struct i965_kernel *kernel = &i965_mpeg2_context->vld_kernels[i];
  998.         kernel->bo = dri_bo_alloc(i965->intel.bufmgr,
  999.                                   kernel->name,
  1000.                                   kernel->size, 64);
  1001.         assert(kernel->bo);
  1002.         dri_bo_subdata(kernel->bo, 0, kernel->size, kernel->bin);
  1003.     }
  1004.  
  1005.     /* URB */
  1006.     media_context->urb.num_vfe_entries = 28;
  1007.     media_context->urb.size_vfe_entry = 13;
  1008.  
  1009.     media_context->urb.num_cs_entries = 1;
  1010.     media_context->urb.size_cs_entry = 16;
  1011.  
  1012.     media_context->urb.vfe_start = 0;
  1013.     media_context->urb.cs_start = media_context->urb.vfe_start +
  1014.         media_context->urb.num_vfe_entries * media_context->urb.size_vfe_entry;
  1015.     assert(media_context->urb.cs_start +
  1016.            media_context->urb.num_cs_entries * media_context->urb.size_cs_entry <= i965->intel.device_info->urb_size);
  1017.  
  1018.     /* hook functions */
  1019.     media_context->media_states_setup = i965_media_mpeg2_states_setup;
  1020.     media_context->media_objects = i965_media_mpeg2_objects;
  1021.     media_context->private_context = i965_mpeg2_context;
  1022.     media_context->free_private_context = i965_media_mpeg2_free_private_context;
  1023. }
  1024.