Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
5361 | serge | 1 | /* |
2 | * Copyright © 2010-2011 Intel Corporation |
||
3 | * |
||
4 | * Permission is hereby granted, free of charge, to any person obtaining a |
||
5 | * copy of this software and associated documentation files (the |
||
6 | * "Software"), to deal in the Software without restriction, including |
||
7 | * without limitation the rights to use, copy, modify, merge, publish, |
||
8 | * distribute, sub license, and/or sell copies of the Software, and to |
||
9 | * permit persons to whom the Software is furnished to do so, subject to |
||
10 | * the following conditions: |
||
11 | * |
||
12 | * The above copyright notice and this permission notice (including the |
||
13 | * next paragraph) shall be included in all copies or substantial portions |
||
14 | * of the Software. |
||
15 | * |
||
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS |
||
17 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
||
18 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. |
||
19 | * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR |
||
20 | * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, |
||
21 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE |
||
22 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
||
23 | * |
||
24 | * Authors: |
||
25 | * Zhou Chang |
||
26 | * |
||
27 | */ |
||
28 | |||
29 | #include |
||
30 | #include |
||
31 | #include |
||
32 | #include |
||
33 | |||
34 | #include "intel_batchbuffer.h" |
||
35 | #include "intel_driver.h" |
||
36 | |||
37 | #include "i965_defines.h" |
||
38 | #include "i965_drv_video.h" |
||
39 | #include "i965_encoder.h" |
||
40 | #include "gen6_vme.h" |
||
41 | #include "gen6_mfc.h" |
||
42 | |||
43 | #define SURFACE_STATE_PADDED_SIZE MAX(SURFACE_STATE_PADDED_SIZE_GEN6, SURFACE_STATE_PADDED_SIZE_GEN7) |
||
44 | #define SURFACE_STATE_OFFSET(index) (SURFACE_STATE_PADDED_SIZE * index) |
||
45 | #define BINDING_TABLE_OFFSET(index) (SURFACE_STATE_OFFSET(MAX_MEDIA_SURFACES_GEN6) + sizeof(unsigned int) * index) |
||
46 | |||
47 | #define CURBE_ALLOCATION_SIZE 37 /* in 256-bit */ |
||
48 | #define CURBE_TOTAL_DATA_LENGTH (4 * 32) /* in byte, it should be less than or equal to CURBE_ALLOCATION_SIZE * 32 */ |
||
49 | #define CURBE_URB_ENTRY_LENGTH 4 /* in 256-bit, it should be less than or equal to CURBE_TOTAL_DATA_LENGTH / 32 */ |
||
50 | |||
51 | enum VIDEO_CODING_TYPE{ |
||
52 | VIDEO_CODING_AVC = 0, |
||
53 | VIDEO_CODING_SUM |
||
54 | }; |
||
55 | |||
56 | enum AVC_VME_KERNEL_TYPE{ |
||
57 | AVC_VME_INTRA_SHADER = 0, |
||
58 | AVC_VME_INTER_SHADER, |
||
59 | AVC_VME_BATCHBUFFER, |
||
60 | AVC_VME_KERNEL_SUM |
||
61 | }; |
||
62 | |||
63 | static const uint32_t gen6_vme_intra_frame[][4] = { |
||
64 | #include "shaders/vme/intra_frame.g6b" |
||
65 | }; |
||
66 | |||
67 | static const uint32_t gen6_vme_inter_frame[][4] = { |
||
68 | #include "shaders/vme/inter_frame.g6b" |
||
69 | }; |
||
70 | |||
71 | static const uint32_t gen6_vme_batchbuffer[][4] = { |
||
72 | #include "shaders/vme/batchbuffer.g6b" |
||
73 | }; |
||
74 | |||
75 | static struct i965_kernel gen6_vme_kernels[] = { |
||
76 | { |
||
77 | "AVC VME Intra Frame", |
||
78 | AVC_VME_INTRA_SHADER, /*index*/ |
||
79 | gen6_vme_intra_frame, |
||
80 | sizeof(gen6_vme_intra_frame), |
||
81 | NULL |
||
82 | }, |
||
83 | { |
||
84 | "AVC VME inter Frame", |
||
85 | AVC_VME_INTER_SHADER, |
||
86 | gen6_vme_inter_frame, |
||
87 | sizeof(gen6_vme_inter_frame), |
||
88 | NULL |
||
89 | }, |
||
90 | { |
||
91 | "AVC VME BATCHBUFFER", |
||
92 | AVC_VME_BATCHBUFFER, |
||
93 | gen6_vme_batchbuffer, |
||
94 | sizeof(gen6_vme_batchbuffer), |
||
95 | NULL |
||
96 | }, |
||
97 | }; |
||
98 | |||
99 | /* only used for VME source surface state */ |
||
100 | static void |
||
101 | gen6_vme_source_surface_state(VADriverContextP ctx, |
||
102 | int index, |
||
103 | struct object_surface *obj_surface, |
||
104 | struct intel_encoder_context *encoder_context) |
||
105 | { |
||
106 | struct gen6_vme_context *vme_context = encoder_context->vme_context; |
||
107 | |||
108 | vme_context->vme_surface2_setup(ctx, |
||
109 | &vme_context->gpe_context, |
||
110 | obj_surface, |
||
111 | BINDING_TABLE_OFFSET(index), |
||
112 | SURFACE_STATE_OFFSET(index)); |
||
113 | } |
||
114 | |||
115 | static void |
||
116 | gen6_vme_media_source_surface_state(VADriverContextP ctx, |
||
117 | int index, |
||
118 | struct object_surface *obj_surface, |
||
119 | struct intel_encoder_context *encoder_context) |
||
120 | { |
||
121 | struct gen6_vme_context *vme_context = encoder_context->vme_context; |
||
122 | |||
123 | vme_context->vme_media_rw_surface_setup(ctx, |
||
124 | &vme_context->gpe_context, |
||
125 | obj_surface, |
||
126 | BINDING_TABLE_OFFSET(index), |
||
127 | SURFACE_STATE_OFFSET(index)); |
||
128 | } |
||
129 | |||
130 | static void |
||
131 | gen6_vme_output_buffer_setup(VADriverContextP ctx, |
||
132 | struct encode_state *encode_state, |
||
133 | int index, |
||
134 | struct intel_encoder_context *encoder_context) |
||
135 | |||
136 | { |
||
137 | struct i965_driver_data *i965 = i965_driver_data(ctx); |
||
138 | struct gen6_vme_context *vme_context = encoder_context->vme_context; |
||
139 | VAEncSequenceParameterBufferH264 *pSequenceParameter = (VAEncSequenceParameterBufferH264 *)encode_state->seq_param_ext->buffer; |
||
140 | VAEncSliceParameterBufferH264 *pSliceParameter = (VAEncSliceParameterBufferH264 *)encode_state->slice_params_ext[0]->buffer; |
||
141 | int is_intra = pSliceParameter->slice_type == SLICE_TYPE_I; |
||
142 | int width_in_mbs = pSequenceParameter->picture_width_in_mbs; |
||
143 | int height_in_mbs = pSequenceParameter->picture_height_in_mbs; |
||
144 | |||
145 | vme_context->vme_output.num_blocks = width_in_mbs * height_in_mbs; |
||
146 | vme_context->vme_output.pitch = 16; /* in bytes, always 16 */ |
||
147 | |||
148 | if (is_intra) |
||
149 | vme_context->vme_output.size_block = INTRA_VME_OUTPUT_IN_BYTES; |
||
150 | else |
||
151 | vme_context->vme_output.size_block = INTER_VME_OUTPUT_IN_BYTES; |
||
152 | |||
153 | vme_context->vme_output.bo = dri_bo_alloc(i965->intel.bufmgr, |
||
154 | "VME output buffer", |
||
155 | vme_context->vme_output.num_blocks * vme_context->vme_output.size_block, |
||
156 | 0x1000); |
||
157 | assert(vme_context->vme_output.bo); |
||
158 | vme_context->vme_buffer_suface_setup(ctx, |
||
159 | &vme_context->gpe_context, |
||
160 | &vme_context->vme_output, |
||
161 | BINDING_TABLE_OFFSET(index), |
||
162 | SURFACE_STATE_OFFSET(index)); |
||
163 | } |
||
164 | |||
165 | static void |
||
166 | gen6_vme_output_vme_batchbuffer_setup(VADriverContextP ctx, |
||
167 | struct encode_state *encode_state, |
||
168 | int index, |
||
169 | struct intel_encoder_context *encoder_context) |
||
170 | |||
171 | { |
||
172 | struct i965_driver_data *i965 = i965_driver_data(ctx); |
||
173 | struct gen6_vme_context *vme_context = encoder_context->vme_context; |
||
174 | VAEncSequenceParameterBufferH264 *pSequenceParameter = (VAEncSequenceParameterBufferH264 *)encode_state->seq_param_ext->buffer; |
||
175 | int width_in_mbs = pSequenceParameter->picture_width_in_mbs; |
||
176 | int height_in_mbs = pSequenceParameter->picture_height_in_mbs; |
||
177 | |||
178 | vme_context->vme_batchbuffer.num_blocks = width_in_mbs * height_in_mbs + 1; |
||
179 | vme_context->vme_batchbuffer.size_block = 32; /* 2 OWORDs */ |
||
180 | vme_context->vme_batchbuffer.pitch = 16; |
||
181 | vme_context->vme_batchbuffer.bo = dri_bo_alloc(i965->intel.bufmgr, |
||
182 | "VME batchbuffer", |
||
183 | vme_context->vme_batchbuffer.num_blocks * vme_context->vme_batchbuffer.size_block, |
||
184 | 0x1000); |
||
185 | vme_context->vme_buffer_suface_setup(ctx, |
||
186 | &vme_context->gpe_context, |
||
187 | &vme_context->vme_batchbuffer, |
||
188 | BINDING_TABLE_OFFSET(index), |
||
189 | SURFACE_STATE_OFFSET(index)); |
||
190 | } |
||
191 | |||
192 | static VAStatus |
||
193 | gen6_vme_surface_setup(VADriverContextP ctx, |
||
194 | struct encode_state *encode_state, |
||
195 | int is_intra, |
||
196 | struct intel_encoder_context *encoder_context) |
||
197 | { |
||
198 | struct object_surface *obj_surface; |
||
199 | |||
200 | /*Setup surfaces state*/ |
||
201 | /* current picture for encoding */ |
||
202 | obj_surface = encode_state->input_yuv_object; |
||
203 | gen6_vme_source_surface_state(ctx, 0, obj_surface, encoder_context); |
||
204 | gen6_vme_media_source_surface_state(ctx, 4, obj_surface, encoder_context); |
||
205 | |||
206 | if (!is_intra) { |
||
207 | VAEncSliceParameterBufferH264 *slice_param = (VAEncSliceParameterBufferH264 *)encode_state->slice_params_ext[0]->buffer; |
||
208 | int slice_type; |
||
209 | |||
210 | slice_type = intel_avc_enc_slice_type_fixup(slice_param->slice_type); |
||
211 | assert(slice_type != SLICE_TYPE_I && slice_type != SLICE_TYPE_SI); |
||
212 | |||
213 | intel_avc_vme_reference_state(ctx, encode_state, encoder_context, 0, 1, gen6_vme_source_surface_state); |
||
214 | |||
215 | if (slice_type == SLICE_TYPE_B) |
||
216 | intel_avc_vme_reference_state(ctx, encode_state, encoder_context, 1, 2, gen6_vme_source_surface_state); |
||
217 | } |
||
218 | |||
219 | /* VME output */ |
||
220 | gen6_vme_output_buffer_setup(ctx, encode_state, 3, encoder_context); |
||
221 | gen6_vme_output_vme_batchbuffer_setup(ctx, encode_state, 5, encoder_context); |
||
222 | |||
223 | return VA_STATUS_SUCCESS; |
||
224 | } |
||
225 | |||
226 | static VAStatus gen6_vme_interface_setup(VADriverContextP ctx, |
||
227 | struct encode_state *encode_state, |
||
228 | struct intel_encoder_context *encoder_context) |
||
229 | { |
||
230 | struct gen6_vme_context *vme_context = encoder_context->vme_context; |
||
231 | struct gen6_interface_descriptor_data *desc; |
||
232 | int i; |
||
233 | dri_bo *bo; |
||
234 | |||
235 | bo = vme_context->gpe_context.idrt.bo; |
||
236 | dri_bo_map(bo, 1); |
||
237 | assert(bo->virtual); |
||
238 | desc = bo->virtual; |
||
239 | |||
240 | for (i = 0; i < vme_context->vme_kernel_sum; i++) { |
||
241 | struct i965_kernel *kernel; |
||
242 | kernel = &vme_context->gpe_context.kernels[i]; |
||
243 | assert(sizeof(*desc) == 32); |
||
244 | /*Setup the descritor table*/ |
||
245 | memset(desc, 0, sizeof(*desc)); |
||
246 | desc->desc0.kernel_start_pointer = (kernel->bo->offset >> 6); |
||
247 | desc->desc2.sampler_count = 1; /* FIXME: */ |
||
248 | desc->desc2.sampler_state_pointer = (vme_context->vme_state.bo->offset >> 5); |
||
249 | desc->desc3.binding_table_entry_count = 1; /* FIXME: */ |
||
250 | desc->desc3.binding_table_pointer = (BINDING_TABLE_OFFSET(0) >> 5); |
||
251 | desc->desc4.constant_urb_entry_read_offset = 0; |
||
252 | desc->desc4.constant_urb_entry_read_length = CURBE_URB_ENTRY_LENGTH; |
||
253 | |||
254 | /*kernel start*/ |
||
255 | dri_bo_emit_reloc(bo, |
||
256 | I915_GEM_DOMAIN_INSTRUCTION, 0, |
||
257 | 0, |
||
258 | i * sizeof(*desc) + offsetof(struct gen6_interface_descriptor_data, desc0), |
||
259 | kernel->bo); |
||
260 | /*Sampler State(VME state pointer)*/ |
||
261 | dri_bo_emit_reloc(bo, |
||
262 | I915_GEM_DOMAIN_INSTRUCTION, 0, |
||
263 | (1 << 2), // |
||
264 | i * sizeof(*desc) + offsetof(struct gen6_interface_descriptor_data, desc2), |
||
265 | vme_context->vme_state.bo); |
||
266 | desc++; |
||
267 | } |
||
268 | dri_bo_unmap(bo); |
||
269 | |||
270 | return VA_STATUS_SUCCESS; |
||
271 | } |
||
272 | |||
273 | static VAStatus gen6_vme_constant_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 | // unsigned char *constant_buffer; |
||
279 | unsigned int *vme_state_message; |
||
280 | int mv_num = 32; |
||
281 | if (vme_context->h264_level >= 30) { |
||
282 | mv_num = 16; |
||
283 | if (vme_context->h264_level >= 31) |
||
284 | mv_num = 8; |
||
285 | } |
||
286 | |||
287 | dri_bo_map(vme_context->gpe_context.curbe.bo, 1); |
||
288 | assert(vme_context->gpe_context.curbe.bo->virtual); |
||
289 | // constant_buffer = vme_context->curbe.bo->virtual; |
||
290 | vme_state_message = (unsigned int *)vme_context->gpe_context.curbe.bo->virtual; |
||
291 | vme_state_message[31] = mv_num; |
||
292 | |||
293 | /*TODO copy buffer into CURB*/ |
||
294 | |||
295 | dri_bo_unmap( vme_context->gpe_context.curbe.bo); |
||
296 | |||
297 | return VA_STATUS_SUCCESS; |
||
298 | } |
||
299 | |||
300 | static const unsigned int intra_mb_mode_cost_table[] = { |
||
301 | 0x31110001, // for qp0 |
||
302 | 0x09110001, // for qp1 |
||
303 | 0x15030001, // for qp2 |
||
304 | 0x0b030001, // for qp3 |
||
305 | 0x0d030011, // for qp4 |
||
306 | 0x17210011, // for qp5 |
||
307 | 0x41210011, // for qp6 |
||
308 | 0x19210011, // for qp7 |
||
309 | 0x25050003, // for qp8 |
||
310 | 0x1b130003, // for qp9 |
||
311 | 0x1d130003, // for qp10 |
||
312 | 0x27070021, // for qp11 |
||
313 | 0x51310021, // for qp12 |
||
314 | 0x29090021, // for qp13 |
||
315 | 0x35150005, // for qp14 |
||
316 | 0x2b0b0013, // for qp15 |
||
317 | 0x2d0d0013, // for qp16 |
||
318 | 0x37170007, // for qp17 |
||
319 | 0x61410031, // for qp18 |
||
320 | 0x39190009, // for qp19 |
||
321 | 0x45250015, // for qp20 |
||
322 | 0x3b1b000b, // for qp21 |
||
323 | 0x3d1d000d, // for qp22 |
||
324 | 0x47270017, // for qp23 |
||
325 | 0x71510041, // for qp24 ! center for qp=0..30 |
||
326 | 0x49290019, // for qp25 |
||
327 | 0x55350025, // for qp26 |
||
328 | 0x4b2b001b, // for qp27 |
||
329 | 0x4d2d001d, // for qp28 |
||
330 | 0x57370027, // for qp29 |
||
331 | 0x81610051, // for qp30 |
||
332 | 0x57270017, // for qp31 |
||
333 | 0x81510041, // for qp32 ! center for qp=31..51 |
||
334 | 0x59290019, // for qp33 |
||
335 | 0x65350025, // for qp34 |
||
336 | 0x5b2b001b, // for qp35 |
||
337 | 0x5d2d001d, // for qp36 |
||
338 | 0x67370027, // for qp37 |
||
339 | 0x91610051, // for qp38 |
||
340 | 0x69390029, // for qp39 |
||
341 | 0x75450035, // for qp40 |
||
342 | 0x6b3b002b, // for qp41 |
||
343 | 0x6d3d002d, // for qp42 |
||
344 | 0x77470037, // for qp43 |
||
345 | 0xa1710061, // for qp44 |
||
346 | 0x79490039, // for qp45 |
||
347 | 0x85550045, // for qp46 |
||
348 | 0x7b4b003b, // for qp47 |
||
349 | 0x7d4d003d, // for qp48 |
||
350 | 0x87570047, // for qp49 |
||
351 | 0xb1810071, // for qp50 |
||
352 | 0x89590049 // for qp51 |
||
353 | }; |
||
354 | |||
355 | static void gen6_vme_state_setup_fixup(VADriverContextP ctx, |
||
356 | struct encode_state *encode_state, |
||
357 | struct intel_encoder_context *encoder_context, |
||
358 | unsigned int *vme_state_message) |
||
359 | { |
||
360 | struct gen6_mfc_context *mfc_context = encoder_context->mfc_context; |
||
361 | VAEncPictureParameterBufferH264 *pic_param = (VAEncPictureParameterBufferH264 *)encode_state->pic_param_ext->buffer; |
||
362 | VAEncSliceParameterBufferH264 *slice_param = (VAEncSliceParameterBufferH264 *)encode_state->slice_params_ext[0]->buffer; |
||
363 | |||
364 | if (slice_param->slice_type != SLICE_TYPE_I && |
||
365 | slice_param->slice_type != SLICE_TYPE_SI) |
||
366 | return; |
||
367 | |||
368 | if (encoder_context->rate_control_mode == VA_RC_CQP) |
||
369 | vme_state_message[16] = intra_mb_mode_cost_table[pic_param->pic_init_qp + slice_param->slice_qp_delta]; |
||
370 | else |
||
371 | vme_state_message[16] = intra_mb_mode_cost_table[mfc_context->bit_rate_control_context[SLICE_TYPE_I].QpPrimeY]; |
||
372 | } |
||
373 | |||
374 | static VAStatus gen6_vme_vme_state_setup(VADriverContextP ctx, |
||
375 | struct encode_state *encode_state, |
||
376 | int is_intra, |
||
377 | struct intel_encoder_context *encoder_context) |
||
378 | { |
||
379 | struct gen6_vme_context *vme_context = encoder_context->vme_context; |
||
380 | unsigned int *vme_state_message; |
||
381 | int i; |
||
382 | |||
383 | //building VME state message |
||
384 | dri_bo_map(vme_context->vme_state.bo, 1); |
||
385 | assert(vme_context->vme_state.bo->virtual); |
||
386 | vme_state_message = (unsigned int *)vme_context->vme_state.bo->virtual; |
||
387 | |||
388 | if (encoder_context->quality_level != ENCODER_LOW_QUALITY) { |
||
389 | vme_state_message[0] = 0x01010101; |
||
390 | vme_state_message[1] = 0x10010101; |
||
391 | vme_state_message[2] = 0x0F0F0F0F; |
||
392 | vme_state_message[3] = 0x100F0F0F; |
||
393 | vme_state_message[4] = 0x01010101; |
||
394 | vme_state_message[5] = 0x10010101; |
||
395 | vme_state_message[6] = 0x0F0F0F0F; |
||
396 | vme_state_message[7] = 0x100F0F0F; |
||
397 | vme_state_message[8] = 0x01010101; |
||
398 | vme_state_message[9] = 0x10010101; |
||
399 | vme_state_message[10] = 0x0F0F0F0F; |
||
400 | vme_state_message[11] = 0x000F0F0F; |
||
401 | vme_state_message[12] = 0x00; |
||
402 | vme_state_message[13] = 0x00; |
||
403 | } else { |
||
404 | vme_state_message[0] = 0x10010101; |
||
405 | vme_state_message[1] = 0x100F0F0F; |
||
406 | vme_state_message[2] = 0x10010101; |
||
407 | vme_state_message[3] = 0x000F0F0F; |
||
408 | vme_state_message[4] = 0; |
||
409 | vme_state_message[5] = 0; |
||
410 | vme_state_message[6] = 0; |
||
411 | vme_state_message[7] = 0; |
||
412 | vme_state_message[8] = 0; |
||
413 | vme_state_message[9] = 0; |
||
414 | vme_state_message[10] = 0; |
||
415 | vme_state_message[11] = 0; |
||
416 | vme_state_message[12] = 0; |
||
417 | vme_state_message[13] = 0; |
||
418 | } |
||
419 | |||
420 | vme_state_message[14] = 0x4a4a; |
||
421 | vme_state_message[15] = 0x0; |
||
422 | vme_state_message[16] = 0x4a4a4a4a; |
||
423 | vme_state_message[17] = 0x4a4a4a4a; |
||
424 | vme_state_message[18] = 0x21110100; |
||
425 | vme_state_message[19] = 0x61514131; |
||
426 | |||
427 | for(i = 20; i < 32; i++) { |
||
428 | vme_state_message[i] = 0; |
||
429 | } |
||
430 | //vme_state_message[16] = 0x42424242; //cost function LUT set 0 for Intra |
||
431 | |||
432 | gen6_vme_state_setup_fixup(ctx, encode_state, encoder_context, vme_state_message); |
||
433 | |||
434 | dri_bo_unmap( vme_context->vme_state.bo); |
||
435 | return VA_STATUS_SUCCESS; |
||
436 | } |
||
437 | |||
438 | static void |
||
439 | gen6_vme_fill_vme_batchbuffer(VADriverContextP ctx, |
||
440 | struct encode_state *encode_state, |
||
441 | int mb_width, int mb_height, |
||
442 | int kernel, |
||
443 | int transform_8x8_mode_flag, |
||
444 | struct intel_encoder_context *encoder_context) |
||
445 | { |
||
446 | struct gen6_vme_context *vme_context = encoder_context->vme_context; |
||
447 | int number_mb_cmds; |
||
448 | int mb_x = 0, mb_y = 0; |
||
449 | int i, s; |
||
450 | unsigned int *command_ptr; |
||
451 | |||
452 | dri_bo_map(vme_context->vme_batchbuffer.bo, 1); |
||
453 | command_ptr = vme_context->vme_batchbuffer.bo->virtual; |
||
454 | |||
455 | for (s = 0; s < encode_state->num_slice_params_ext; s++) { |
||
456 | VAEncSliceParameterBufferH264 *pSliceParameter = (VAEncSliceParameterBufferH264 *)encode_state->slice_params_ext[s]->buffer; |
||
457 | int slice_mb_begin = pSliceParameter->macroblock_address; |
||
458 | int slice_mb_number = pSliceParameter->num_macroblocks; |
||
459 | |||
460 | for (i = 0; i < slice_mb_number; ) { |
||
461 | int mb_count = i + slice_mb_begin; |
||
462 | mb_x = mb_count % mb_width; |
||
463 | mb_y = mb_count / mb_width; |
||
464 | if( i == 0 ) { |
||
465 | number_mb_cmds = mb_width; // we must mark the slice edge. |
||
466 | } else if ( (i + 128 ) <= slice_mb_number) { |
||
467 | number_mb_cmds = 128; |
||
468 | } else { |
||
469 | number_mb_cmds = slice_mb_number - i; |
||
470 | } |
||
471 | |||
472 | *command_ptr++ = (CMD_MEDIA_OBJECT | (9 - 2)); |
||
473 | *command_ptr++ = kernel; |
||
474 | *command_ptr++ = 0; |
||
475 | *command_ptr++ = 0; |
||
476 | *command_ptr++ = 0; |
||
477 | *command_ptr++ = 0; |
||
478 | |||
479 | /*inline data */ |
||
480 | *command_ptr++ = (mb_width << 16 | mb_y << 8 | mb_x); |
||
481 | *command_ptr++ = (number_mb_cmds << 16 | transform_8x8_mode_flag | ((i==0) << 1)); |
||
482 | *command_ptr++ = encoder_context->quality_level; |
||
483 | |||
484 | i += number_mb_cmds; |
||
485 | } |
||
486 | } |
||
487 | |||
488 | *command_ptr++ = 0; |
||
489 | *command_ptr++ = MI_BATCH_BUFFER_END; |
||
490 | |||
491 | dri_bo_unmap(vme_context->vme_batchbuffer.bo); |
||
492 | } |
||
493 | |||
494 | static void gen6_vme_media_init(VADriverContextP ctx, struct intel_encoder_context *encoder_context) |
||
495 | { |
||
496 | struct i965_driver_data *i965 = i965_driver_data(ctx); |
||
497 | struct gen6_vme_context *vme_context = encoder_context->vme_context; |
||
498 | dri_bo *bo; |
||
499 | |||
500 | i965_gpe_context_init(ctx, &vme_context->gpe_context); |
||
501 | |||
502 | /* VME output buffer */ |
||
503 | dri_bo_unreference(vme_context->vme_output.bo); |
||
504 | vme_context->vme_output.bo = NULL; |
||
505 | |||
506 | dri_bo_unreference(vme_context->vme_batchbuffer.bo); |
||
507 | vme_context->vme_batchbuffer.bo = NULL; |
||
508 | |||
509 | /* VME state */ |
||
510 | dri_bo_unreference(vme_context->vme_state.bo); |
||
511 | bo = dri_bo_alloc(i965->intel.bufmgr, |
||
512 | "Buffer", |
||
513 | 1024*16, 64); |
||
514 | assert(bo); |
||
515 | vme_context->vme_state.bo = bo; |
||
516 | } |
||
517 | |||
518 | static void gen6_vme_pipeline_programing(VADriverContextP ctx, |
||
519 | struct encode_state *encode_state, |
||
520 | struct intel_encoder_context *encoder_context) |
||
521 | { |
||
522 | struct gen6_vme_context *vme_context = encoder_context->vme_context; |
||
523 | struct intel_batchbuffer *batch = encoder_context->base.batch; |
||
524 | VAEncPictureParameterBufferH264 *pPicParameter = (VAEncPictureParameterBufferH264 *)encode_state->pic_param_ext->buffer; |
||
525 | VAEncSliceParameterBufferH264 *pSliceParameter = (VAEncSliceParameterBufferH264 *)encode_state->slice_params_ext[0]->buffer; |
||
526 | VAEncSequenceParameterBufferH264 *pSequenceParameter = (VAEncSequenceParameterBufferH264 *)encode_state->seq_param_ext->buffer; |
||
527 | int is_intra = pSliceParameter->slice_type == SLICE_TYPE_I; |
||
528 | int width_in_mbs = pSequenceParameter->picture_width_in_mbs; |
||
529 | int height_in_mbs = pSequenceParameter->picture_height_in_mbs; |
||
530 | |||
531 | gen6_vme_fill_vme_batchbuffer(ctx, |
||
532 | encode_state, |
||
533 | width_in_mbs, height_in_mbs, |
||
534 | is_intra ? AVC_VME_INTRA_SHADER : AVC_VME_INTER_SHADER, |
||
535 | pPicParameter->pic_fields.bits.transform_8x8_mode_flag, |
||
536 | encoder_context); |
||
537 | |||
538 | intel_batchbuffer_start_atomic(batch, 0x1000); |
||
539 | gen6_gpe_pipeline_setup(ctx, &vme_context->gpe_context, batch); |
||
540 | BEGIN_BATCH(batch, 2); |
||
541 | OUT_BATCH(batch, MI_BATCH_BUFFER_START | (1 << 8)); |
||
542 | OUT_RELOC(batch, |
||
543 | vme_context->vme_batchbuffer.bo, |
||
544 | I915_GEM_DOMAIN_COMMAND, 0, |
||
545 | 0); |
||
546 | ADVANCE_BATCH(batch); |
||
547 | |||
548 | intel_batchbuffer_end_atomic(batch); |
||
549 | } |
||
550 | |||
551 | static VAStatus gen6_vme_prepare(VADriverContextP ctx, |
||
552 | struct encode_state *encode_state, |
||
553 | struct intel_encoder_context *encoder_context) |
||
554 | { |
||
555 | VAStatus vaStatus = VA_STATUS_SUCCESS; |
||
556 | VAEncSliceParameterBufferH264 *pSliceParameter = (VAEncSliceParameterBufferH264 *)encode_state->slice_params_ext[0]->buffer; |
||
557 | int is_intra = pSliceParameter->slice_type == SLICE_TYPE_I; |
||
558 | VAEncSequenceParameterBufferH264 *pSequenceParameter = (VAEncSequenceParameterBufferH264 *)encode_state->seq_param_ext->buffer; |
||
559 | struct gen6_vme_context *vme_context = encoder_context->vme_context; |
||
560 | |||
561 | if (!vme_context->h264_level || |
||
562 | (vme_context->h264_level != pSequenceParameter->level_idc)) { |
||
563 | vme_context->h264_level = pSequenceParameter->level_idc; |
||
564 | } |
||
565 | /*Setup all the memory object*/ |
||
566 | gen6_vme_surface_setup(ctx, encode_state, is_intra, encoder_context); |
||
567 | gen6_vme_interface_setup(ctx, encode_state, encoder_context); |
||
568 | gen6_vme_constant_setup(ctx, encode_state, encoder_context); |
||
569 | gen6_vme_vme_state_setup(ctx, encode_state, is_intra, encoder_context); |
||
570 | |||
571 | /*Programing media pipeline*/ |
||
572 | gen6_vme_pipeline_programing(ctx, encode_state, encoder_context); |
||
573 | |||
574 | return vaStatus; |
||
575 | } |
||
576 | |||
577 | static VAStatus gen6_vme_run(VADriverContextP ctx, |
||
578 | struct encode_state *encode_state, |
||
579 | struct intel_encoder_context *encoder_context) |
||
580 | { |
||
581 | struct intel_batchbuffer *batch = encoder_context->base.batch; |
||
582 | |||
583 | intel_batchbuffer_flush(batch); |
||
584 | |||
585 | return VA_STATUS_SUCCESS; |
||
586 | } |
||
587 | |||
588 | static VAStatus gen6_vme_stop(VADriverContextP ctx, |
||
589 | struct encode_state *encode_state, |
||
590 | struct intel_encoder_context *encoder_context) |
||
591 | { |
||
592 | return VA_STATUS_SUCCESS; |
||
593 | } |
||
594 | |||
595 | static VAStatus |
||
596 | gen6_vme_pipeline(VADriverContextP ctx, |
||
597 | VAProfile profile, |
||
598 | struct encode_state *encode_state, |
||
599 | struct intel_encoder_context *encoder_context) |
||
600 | { |
||
601 | gen6_vme_media_init(ctx, encoder_context); |
||
602 | gen6_vme_prepare(ctx, encode_state, encoder_context); |
||
603 | gen6_vme_run(ctx, encode_state, encoder_context); |
||
604 | gen6_vme_stop(ctx, encode_state, encoder_context); |
||
605 | |||
606 | return VA_STATUS_SUCCESS; |
||
607 | } |
||
608 | |||
609 | static void |
||
610 | gen6_vme_context_destroy(void *context) |
||
611 | { |
||
612 | struct gen6_vme_context *vme_context = context; |
||
613 | |||
614 | i965_gpe_context_destroy(&vme_context->gpe_context); |
||
615 | |||
616 | dri_bo_unreference(vme_context->vme_output.bo); |
||
617 | vme_context->vme_output.bo = NULL; |
||
618 | |||
619 | dri_bo_unreference(vme_context->vme_state.bo); |
||
620 | vme_context->vme_state.bo = NULL; |
||
621 | |||
622 | dri_bo_unreference(vme_context->vme_batchbuffer.bo); |
||
623 | vme_context->vme_batchbuffer.bo = NULL; |
||
624 | |||
625 | free(vme_context); |
||
626 | } |
||
627 | |||
628 | Bool gen6_vme_context_init(VADriverContextP ctx, struct intel_encoder_context *encoder_context) |
||
629 | { |
||
630 | struct gen6_vme_context *vme_context = NULL; |
||
631 | |||
632 | if (encoder_context->codec != CODEC_H264) { |
||
633 | /* Never get here */ |
||
634 | assert(0); |
||
635 | return False; |
||
636 | } |
||
637 | |||
638 | vme_context = calloc(1, sizeof(struct gen6_vme_context)); |
||
639 | vme_context->gpe_context.surface_state_binding_table.length = |
||
640 | (SURFACE_STATE_PADDED_SIZE + sizeof(unsigned int)) * MAX_MEDIA_SURFACES_GEN6; |
||
641 | |||
642 | vme_context->gpe_context.idrt.max_entries = MAX_INTERFACE_DESC_GEN6; |
||
643 | vme_context->gpe_context.idrt.entry_size = sizeof(struct gen6_interface_descriptor_data); |
||
644 | vme_context->gpe_context.curbe.length = CURBE_TOTAL_DATA_LENGTH; |
||
645 | |||
646 | vme_context->gpe_context.vfe_state.max_num_threads = 60 - 1; |
||
647 | vme_context->gpe_context.vfe_state.num_urb_entries = 16; |
||
648 | vme_context->gpe_context.vfe_state.gpgpu_mode = 0; |
||
649 | vme_context->gpe_context.vfe_state.urb_entry_size = 59 - 1; |
||
650 | vme_context->gpe_context.vfe_state.curbe_allocation_size = CURBE_ALLOCATION_SIZE - 1; |
||
651 | |||
652 | vme_context->video_coding_type = VIDEO_CODING_AVC; |
||
653 | vme_context->vme_kernel_sum = AVC_VME_KERNEL_SUM; |
||
654 | i965_gpe_load_kernels(ctx, |
||
655 | &vme_context->gpe_context, |
||
656 | gen6_vme_kernels, |
||
657 | vme_context->vme_kernel_sum); |
||
658 | |||
659 | encoder_context->vme_pipeline = gen6_vme_pipeline; |
||
660 | vme_context->vme_surface2_setup = i965_gpe_surface2_setup; |
||
661 | vme_context->vme_media_rw_surface_setup = i965_gpe_media_rw_surface_setup; |
||
662 | vme_context->vme_buffer_suface_setup = i965_gpe_buffer_suface_setup; |
||
663 | |||
664 | encoder_context->vme_context = vme_context; |
||
665 | encoder_context->vme_context_destroy = gen6_vme_context_destroy; |
||
666 | |||
667 | return True; |
||
668 | }><>><>><>><>><>=>>>>><>> |