2 * Copyright © 2012 Intel Corporation
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
24 * Xiang Haihao <haihao.xiang@intel.com>
32 #include "intel_batchbuffer.h"
33 #include "intel_driver.h"
35 #include "i965_gpe_utils.h"
38 i965_gpe_select(VADriverContextP ctx,
39 struct i965_gpe_context *gpe_context,
40 struct intel_batchbuffer *batch)
42 BEGIN_BATCH(batch, 1);
43 OUT_BATCH(batch, CMD_PIPELINE_SELECT | PIPELINE_SELECT_MEDIA);
48 gen6_gpe_state_base_address(VADriverContextP ctx,
49 struct i965_gpe_context *gpe_context,
50 struct intel_batchbuffer *batch)
52 BEGIN_BATCH(batch, 10);
54 OUT_BATCH(batch, CMD_STATE_BASE_ADDRESS | (10 - 2));
55 OUT_BATCH(batch, BASE_ADDRESS_MODIFY); /* General State Base Address */
57 gpe_context->surface_state_binding_table.bo,
58 I915_GEM_DOMAIN_INSTRUCTION,
60 BASE_ADDRESS_MODIFY); /* Surface state base address */
61 OUT_BATCH(batch, BASE_ADDRESS_MODIFY); /* Dynamic State Base Address */
62 OUT_BATCH(batch, BASE_ADDRESS_MODIFY); /* Indirect Object Base Address */
63 OUT_BATCH(batch, BASE_ADDRESS_MODIFY); /* Instruction Base Address */
64 OUT_BATCH(batch, BASE_ADDRESS_MODIFY); /* General State Access Upper Bound */
65 OUT_BATCH(batch, BASE_ADDRESS_MODIFY); /* Dynamic State Access Upper Bound */
66 OUT_BATCH(batch, BASE_ADDRESS_MODIFY); /* Indirect Object Access Upper Bound */
67 OUT_BATCH(batch, BASE_ADDRESS_MODIFY); /* Instruction Access Upper Bound */
73 gen6_gpe_vfe_state(VADriverContextP ctx,
74 struct i965_gpe_context *gpe_context,
75 struct intel_batchbuffer *batch)
78 BEGIN_BATCH(batch, 8);
80 OUT_BATCH(batch, CMD_MEDIA_VFE_STATE | (8 - 2));
81 OUT_BATCH(batch, 0); /* Scratch Space Base Pointer and Space */
83 gpe_context->vfe_state.max_num_threads << 16 | /* Maximum Number of Threads */
84 gpe_context->vfe_state.num_urb_entries << 8 | /* Number of URB Entries */
85 gpe_context->vfe_state.gpgpu_mode << 2); /* MEDIA Mode */
86 OUT_BATCH(batch, 0); /* Debug: Object ID */
88 gpe_context->vfe_state.urb_entry_size << 16 | /* URB Entry Allocation Size */
89 gpe_context->vfe_state.curbe_allocation_size); /* CURBE Allocation Size */
90 OUT_BATCH(batch, 0); /* Disable Scoreboard */
91 OUT_BATCH(batch, 0); /* Disable Scoreboard */
92 OUT_BATCH(batch, 0); /* Disable Scoreboard */
99 gen6_gpe_curbe_load(VADriverContextP ctx,
100 struct i965_gpe_context *gpe_context,
101 struct intel_batchbuffer *batch)
103 BEGIN_BATCH(batch, 4);
105 OUT_BATCH(batch, CMD_MEDIA_CURBE_LOAD | (4 - 2));
107 OUT_BATCH(batch, gpe_context->curbe.length);
108 OUT_RELOC(batch, gpe_context->curbe.bo, I915_GEM_DOMAIN_INSTRUCTION, 0, 0);
110 ADVANCE_BATCH(batch);
114 gen6_gpe_idrt(VADriverContextP ctx,
115 struct i965_gpe_context *gpe_context,
116 struct intel_batchbuffer *batch)
118 BEGIN_BATCH(batch, 4);
120 OUT_BATCH(batch, CMD_MEDIA_INTERFACE_LOAD | (4 - 2));
122 OUT_BATCH(batch, gpe_context->idrt.max_entries * gpe_context->idrt.entry_size);
123 OUT_RELOC(batch, gpe_context->idrt.bo, I915_GEM_DOMAIN_INSTRUCTION, 0, 0);
125 ADVANCE_BATCH(batch);
129 i965_gpe_load_kernels(VADriverContextP ctx,
130 struct i965_gpe_context *gpe_context,
131 struct i965_kernel *kernel_list,
132 unsigned int num_kernels)
134 struct i965_driver_data *i965 = i965_driver_data(ctx);
137 assert(num_kernels <= MAX_GPE_KERNELS);
138 memcpy(gpe_context->kernels, kernel_list, sizeof(*kernel_list) * num_kernels);
139 gpe_context->num_kernels = num_kernels;
141 for (i = 0; i < num_kernels; i++) {
142 struct i965_kernel *kernel = &gpe_context->kernels[i];
144 kernel->bo = dri_bo_alloc(i965->intel.bufmgr,
149 dri_bo_subdata(kernel->bo, 0, kernel->size, kernel->bin);
154 i965_gpe_context_destroy(struct i965_gpe_context *gpe_context)
158 dri_bo_unreference(gpe_context->surface_state_binding_table.bo);
159 gpe_context->surface_state_binding_table.bo = NULL;
161 dri_bo_unreference(gpe_context->idrt.bo);
162 gpe_context->idrt.bo = NULL;
164 dri_bo_unreference(gpe_context->curbe.bo);
165 gpe_context->curbe.bo = NULL;
167 for (i = 0; i < gpe_context->num_kernels; i++) {
168 struct i965_kernel *kernel = &gpe_context->kernels[i];
170 dri_bo_unreference(kernel->bo);
176 i965_gpe_context_init(VADriverContextP ctx,
177 struct i965_gpe_context *gpe_context)
179 struct i965_driver_data *i965 = i965_driver_data(ctx);
182 dri_bo_unreference(gpe_context->surface_state_binding_table.bo);
183 bo = dri_bo_alloc(i965->intel.bufmgr,
184 "surface state & binding table",
185 gpe_context->surface_state_binding_table.length,
188 gpe_context->surface_state_binding_table.bo = bo;
190 dri_bo_unreference(gpe_context->idrt.bo);
191 bo = dri_bo_alloc(i965->intel.bufmgr,
192 "interface descriptor table",
193 gpe_context->idrt.entry_size * gpe_context->idrt.max_entries,
196 gpe_context->idrt.bo = bo;
198 dri_bo_unreference(gpe_context->curbe.bo);
199 bo = dri_bo_alloc(i965->intel.bufmgr,
201 gpe_context->curbe.length,
204 gpe_context->curbe.bo = bo;
208 gen6_gpe_pipeline_setup(VADriverContextP ctx,
209 struct i965_gpe_context *gpe_context,
210 struct intel_batchbuffer *batch)
212 intel_batchbuffer_emit_mi_flush(batch);
214 i965_gpe_select(ctx, gpe_context, batch);
215 gen6_gpe_state_base_address(ctx, gpe_context, batch);
216 gen6_gpe_vfe_state(ctx, gpe_context, batch);
217 gen6_gpe_curbe_load(ctx, gpe_context, batch);
218 gen6_gpe_idrt(ctx, gpe_context, batch);
222 i965_gpe_set_surface_tiling(struct i965_surface_state *ss, unsigned int tiling)
225 case I915_TILING_NONE:
226 ss->ss3.tiled_surface = 0;
227 ss->ss3.tile_walk = 0;
230 ss->ss3.tiled_surface = 1;
231 ss->ss3.tile_walk = I965_TILEWALK_XMAJOR;
234 ss->ss3.tiled_surface = 1;
235 ss->ss3.tile_walk = I965_TILEWALK_YMAJOR;
241 i965_gpe_set_surface2_tiling(struct i965_surface_state2 *ss, unsigned int tiling)
244 case I915_TILING_NONE:
245 ss->ss2.tiled_surface = 0;
246 ss->ss2.tile_walk = 0;
249 ss->ss2.tiled_surface = 1;
250 ss->ss2.tile_walk = I965_TILEWALK_XMAJOR;
253 ss->ss2.tiled_surface = 1;
254 ss->ss2.tile_walk = I965_TILEWALK_YMAJOR;
260 gen7_gpe_set_surface_tiling(struct gen7_surface_state *ss, unsigned int tiling)
263 case I915_TILING_NONE:
264 ss->ss0.tiled_surface = 0;
265 ss->ss0.tile_walk = 0;
268 ss->ss0.tiled_surface = 1;
269 ss->ss0.tile_walk = I965_TILEWALK_XMAJOR;
272 ss->ss0.tiled_surface = 1;
273 ss->ss0.tile_walk = I965_TILEWALK_YMAJOR;
279 gen7_gpe_set_surface2_tiling(struct gen7_surface_state2 *ss, unsigned int tiling)
282 case I915_TILING_NONE:
283 ss->ss2.tiled_surface = 0;
284 ss->ss2.tile_walk = 0;
287 ss->ss2.tiled_surface = 1;
288 ss->ss2.tile_walk = I965_TILEWALK_XMAJOR;
291 ss->ss2.tiled_surface = 1;
292 ss->ss2.tile_walk = I965_TILEWALK_YMAJOR;
298 i965_gpe_set_surface2_state(VADriverContextP ctx,
299 struct object_surface *obj_surface,
300 struct i965_surface_state2 *ss)
303 unsigned int tiling, swizzle;
305 assert(obj_surface->bo);
306 assert(obj_surface->fourcc == VA_FOURCC('N', 'V', '1', '2'));
308 dri_bo_get_tiling(obj_surface->bo, &tiling, &swizzle);
309 w = obj_surface->orig_width;
310 h = obj_surface->orig_height;
311 w_pitch = obj_surface->width;
313 memset(ss, 0, sizeof(*ss));
315 ss->ss0.surface_base_address = obj_surface->bo->offset;
317 ss->ss1.cbcr_pixel_offset_v_direction = 2;
318 ss->ss1.width = w - 1;
319 ss->ss1.height = h - 1;
321 ss->ss2.surface_format = MFX_SURFACE_PLANAR_420_8;
322 ss->ss2.interleave_chroma = 1;
323 ss->ss2.pitch = w_pitch - 1;
324 ss->ss2.half_pitch_for_chroma = 0;
325 i965_gpe_set_surface2_tiling(ss, tiling);
326 /* ss3: UV offset for interleave mode */
327 ss->ss3.x_offset_for_cb = obj_surface->x_cb_offset;
328 ss->ss3.y_offset_for_cb = obj_surface->y_cb_offset;
332 i965_gpe_surface2_setup(VADriverContextP ctx,
333 struct i965_gpe_context *gpe_context,
334 struct object_surface *obj_surface,
335 unsigned long binding_table_offset,
336 unsigned long surface_state_offset)
338 struct i965_surface_state2 *ss;
341 bo = gpe_context->surface_state_binding_table.bo;
345 ss = (struct i965_surface_state2 *)((char *)bo->virtual + surface_state_offset);
346 i965_gpe_set_surface2_state(ctx, obj_surface, ss);
347 dri_bo_emit_reloc(bo,
348 I915_GEM_DOMAIN_RENDER, 0,
350 surface_state_offset + offsetof(struct i965_surface_state2, ss0),
353 *((unsigned int *)((char *)bo->virtual + binding_table_offset)) = surface_state_offset;
358 i965_gpe_set_media_rw_surface_state(VADriverContextP ctx,
359 struct object_surface *obj_surface,
360 struct i965_surface_state *ss)
363 unsigned int tiling, swizzle;
365 dri_bo_get_tiling(obj_surface->bo, &tiling, &swizzle);
366 w = obj_surface->orig_width;
367 h = obj_surface->orig_height;
368 w_pitch = obj_surface->width;
370 memset(ss, 0, sizeof(*ss));
372 ss->ss0.surface_type = I965_SURFACE_2D;
373 ss->ss0.surface_format = I965_SURFACEFORMAT_R8_UNORM;
375 ss->ss1.base_addr = obj_surface->bo->offset;
377 ss->ss2.width = w / 4 - 1; /* in DWORDs for media read & write message */
378 ss->ss2.height = h - 1;
380 ss->ss3.pitch = w_pitch - 1;
381 i965_gpe_set_surface_tiling(ss, tiling);
385 i965_gpe_media_rw_surface_setup(VADriverContextP ctx,
386 struct i965_gpe_context *gpe_context,
387 struct object_surface *obj_surface,
388 unsigned long binding_table_offset,
389 unsigned long surface_state_offset)
391 struct i965_surface_state *ss;
394 bo = gpe_context->surface_state_binding_table.bo;
395 dri_bo_map(bo, True);
398 ss = (struct i965_surface_state *)((char *)bo->virtual + surface_state_offset);
399 i965_gpe_set_media_rw_surface_state(ctx, obj_surface, ss);
400 dri_bo_emit_reloc(bo,
401 I915_GEM_DOMAIN_RENDER, 0,
403 surface_state_offset + offsetof(struct i965_surface_state, ss1),
406 *((unsigned int *)((char *)bo->virtual + binding_table_offset)) = surface_state_offset;
411 i965_gpe_set_buffer_surface_state(VADriverContextP ctx,
412 struct i965_buffer_surface *buffer_surface,
413 struct i965_surface_state *ss)
417 assert(buffer_surface->bo);
418 num_entries = buffer_surface->num_blocks * buffer_surface->size_block / buffer_surface->pitch;
420 memset(ss, 0, sizeof(*ss));
422 ss->ss0.render_cache_read_mode = 1;
423 ss->ss0.surface_type = I965_SURFACE_BUFFER;
425 ss->ss1.base_addr = buffer_surface->bo->offset;
427 ss->ss2.width = ((num_entries - 1) & 0x7f);
428 ss->ss2.height = (((num_entries - 1) >> 7) & 0x1fff);
430 ss->ss3.depth = (((num_entries - 1) >> 20) & 0x7f);
431 ss->ss3.pitch = buffer_surface->pitch - 1;
435 i965_gpe_buffer_suface_setup(VADriverContextP ctx,
436 struct i965_gpe_context *gpe_context,
437 struct i965_buffer_surface *buffer_surface,
438 unsigned long binding_table_offset,
439 unsigned long surface_state_offset)
441 struct i965_surface_state *ss;
444 bo = gpe_context->surface_state_binding_table.bo;
448 ss = (struct i965_surface_state *)((char *)bo->virtual + surface_state_offset);
449 i965_gpe_set_buffer_surface_state(ctx, buffer_surface, ss);
450 dri_bo_emit_reloc(bo,
451 I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER,
453 surface_state_offset + offsetof(struct i965_surface_state, ss1),
456 *((unsigned int *)((char *)bo->virtual + binding_table_offset)) = surface_state_offset;
461 gen7_gpe_set_surface2_state(VADriverContextP ctx,
462 struct object_surface *obj_surface,
463 struct gen7_surface_state2 *ss)
466 unsigned int tiling, swizzle;
468 assert(obj_surface->bo);
469 assert(obj_surface->fourcc == VA_FOURCC('N', 'V', '1', '2'));
471 dri_bo_get_tiling(obj_surface->bo, &tiling, &swizzle);
472 w = obj_surface->orig_width;
473 h = obj_surface->orig_height;
474 w_pitch = obj_surface->width;
476 memset(ss, 0, sizeof(*ss));
478 ss->ss0.surface_base_address = obj_surface->bo->offset;
480 ss->ss1.cbcr_pixel_offset_v_direction = 2;
481 ss->ss1.width = w - 1;
482 ss->ss1.height = h - 1;
484 ss->ss2.surface_format = MFX_SURFACE_PLANAR_420_8;
485 ss->ss2.interleave_chroma = 1;
486 ss->ss2.pitch = w_pitch - 1;
487 ss->ss2.half_pitch_for_chroma = 0;
488 gen7_gpe_set_surface2_tiling(ss, tiling);
489 /* ss3: UV offset for interleave mode */
490 ss->ss3.x_offset_for_cb = obj_surface->x_cb_offset;
491 ss->ss3.y_offset_for_cb = obj_surface->y_cb_offset;
495 gen7_gpe_surface2_setup(VADriverContextP ctx,
496 struct i965_gpe_context *gpe_context,
497 struct object_surface *obj_surface,
498 unsigned long binding_table_offset,
499 unsigned long surface_state_offset)
501 struct gen7_surface_state2 *ss;
504 bo = gpe_context->surface_state_binding_table.bo;
508 ss = (struct gen7_surface_state2 *)((char *)bo->virtual + surface_state_offset);
509 gen7_gpe_set_surface2_state(ctx, obj_surface, ss);
510 dri_bo_emit_reloc(bo,
511 I915_GEM_DOMAIN_RENDER, 0,
513 surface_state_offset + offsetof(struct gen7_surface_state2, ss0),
516 *((unsigned int *)((char *)bo->virtual + binding_table_offset)) = surface_state_offset;
521 gen7_gpe_set_media_rw_surface_state(VADriverContextP ctx,
522 struct object_surface *obj_surface,
523 struct gen7_surface_state *ss)
526 unsigned int tiling, swizzle;
528 dri_bo_get_tiling(obj_surface->bo, &tiling, &swizzle);
529 w = obj_surface->orig_width;
530 h = obj_surface->orig_height;
531 w_pitch = obj_surface->width;
533 memset(ss, 0, sizeof(*ss));
535 ss->ss0.surface_type = I965_SURFACE_2D;
536 ss->ss0.surface_format = I965_SURFACEFORMAT_R8_UNORM;
538 ss->ss1.base_addr = obj_surface->bo->offset;
540 ss->ss2.width = w / 4 - 1; /* in DWORDs for media read & write message */
541 ss->ss2.height = h - 1;
543 ss->ss3.pitch = w_pitch - 1;
544 gen7_gpe_set_surface_tiling(ss, tiling);
548 gen75_gpe_set_media_chroma_surface_state(VADriverContextP ctx,
549 struct object_surface *obj_surface,
550 struct gen7_surface_state *ss)
553 unsigned int tiling, swizzle;
556 dri_bo_get_tiling(obj_surface->bo, &tiling, &swizzle);
557 w = obj_surface->orig_width;
558 h = obj_surface->orig_height;
559 w_pitch = obj_surface->width;
561 cbcr_offset = obj_surface->height * obj_surface->width;
562 memset(ss, 0, sizeof(*ss));
564 ss->ss0.surface_type = I965_SURFACE_2D;
565 ss->ss0.surface_format = I965_SURFACEFORMAT_R8_UNORM;
567 ss->ss1.base_addr = obj_surface->bo->offset + cbcr_offset;
569 ss->ss2.width = w / 4 - 1; /* in DWORDs for media read & write message */
570 ss->ss2.height = (obj_surface->height / 2) -1;
572 ss->ss3.pitch = w_pitch - 1;
573 gen7_gpe_set_surface_tiling(ss, tiling);
577 gen7_gpe_media_rw_surface_setup(VADriverContextP ctx,
578 struct i965_gpe_context *gpe_context,
579 struct object_surface *obj_surface,
580 unsigned long binding_table_offset,
581 unsigned long surface_state_offset)
583 struct gen7_surface_state *ss;
586 bo = gpe_context->surface_state_binding_table.bo;
587 dri_bo_map(bo, True);
590 ss = (struct gen7_surface_state *)((char *)bo->virtual + surface_state_offset);
591 gen7_gpe_set_media_rw_surface_state(ctx, obj_surface, ss);
592 dri_bo_emit_reloc(bo,
593 I915_GEM_DOMAIN_RENDER, 0,
595 surface_state_offset + offsetof(struct gen7_surface_state, ss1),
598 *((unsigned int *)((char *)bo->virtual + binding_table_offset)) = surface_state_offset;
603 gen75_gpe_media_chroma_surface_setup(VADriverContextP ctx,
604 struct i965_gpe_context *gpe_context,
605 struct object_surface *obj_surface,
606 unsigned long binding_table_offset,
607 unsigned long surface_state_offset)
609 struct gen7_surface_state *ss;
613 assert(obj_surface->fourcc == VA_FOURCC('N', 'V', '1', '2'));
614 bo = gpe_context->surface_state_binding_table.bo;
615 dri_bo_map(bo, True);
618 cbcr_offset = obj_surface->height * obj_surface->width;
619 ss = (struct gen7_surface_state *)((char *)bo->virtual + surface_state_offset);
620 gen75_gpe_set_media_chroma_surface_state(ctx, obj_surface, ss);
621 dri_bo_emit_reloc(bo,
622 I915_GEM_DOMAIN_RENDER, 0,
624 surface_state_offset + offsetof(struct gen7_surface_state, ss1),
627 *((unsigned int *)((char *)bo->virtual + binding_table_offset)) = surface_state_offset;
633 gen7_gpe_set_buffer_surface_state(VADriverContextP ctx,
634 struct i965_buffer_surface *buffer_surface,
635 struct gen7_surface_state *ss)
639 assert(buffer_surface->bo);
640 num_entries = buffer_surface->num_blocks * buffer_surface->size_block / buffer_surface->pitch;
642 memset(ss, 0, sizeof(*ss));
644 ss->ss0.surface_type = I965_SURFACE_BUFFER;
646 ss->ss1.base_addr = buffer_surface->bo->offset;
648 ss->ss2.width = ((num_entries - 1) & 0x7f);
649 ss->ss2.height = (((num_entries - 1) >> 7) & 0x3fff);
651 ss->ss3.depth = (((num_entries - 1) >> 21) & 0x3f);
652 ss->ss3.pitch = buffer_surface->pitch - 1;
656 gen7_gpe_buffer_suface_setup(VADriverContextP ctx,
657 struct i965_gpe_context *gpe_context,
658 struct i965_buffer_surface *buffer_surface,
659 unsigned long binding_table_offset,
660 unsigned long surface_state_offset)
662 struct gen7_surface_state *ss;
665 bo = gpe_context->surface_state_binding_table.bo;
669 ss = (struct gen7_surface_state *)((char *)bo->virtual + surface_state_offset);
670 gen7_gpe_set_buffer_surface_state(ctx, buffer_surface, ss);
671 dri_bo_emit_reloc(bo,
672 I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER,
674 surface_state_offset + offsetof(struct gen7_surface_state, ss1),
677 *((unsigned int *)((char *)bo->virtual + binding_table_offset)) = surface_state_offset;