2 * Copyright © 2014 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
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:
12 * The above copyright notice and this permission notice (including the
13 * next paragraph) shall be included in all copies or substantial portions
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.
31 #include "intel_batchbuffer.h"
32 #include "intel_driver.h"
33 #include "i965_defines.h"
34 #include "i965_structs.h"
35 #include "i965_drv_video.h"
36 #include "i965_post_processing.h"
37 #include "i965_render.h"
38 #include "intel_media.h"
40 #include "gen8_post_processing.h"
41 #include "gen75_picture_process.h"
42 #include "intel_gen_vppapi.h"
43 #include "intel_common_vpp_internal.h"
45 static const uint32_t pp_null_gen9[][4] = {
48 static const uint32_t pp_nv12_load_save_nv12_gen9[][4] = {
49 #include "shaders/post_processing/gen9/pl2_to_pl2.g9b"
52 static const uint32_t pp_nv12_load_save_pl3_gen9[][4] = {
53 #include "shaders/post_processing/gen9/pl2_to_pl3.g9b"
56 static const uint32_t pp_pl3_load_save_nv12_gen9[][4] = {
57 #include "shaders/post_processing/gen9/pl3_to_pl2.g9b"
60 static const uint32_t pp_pl3_load_save_pl3_gen9[][4] = {
61 #include "shaders/post_processing/gen9/pl3_to_pl3.g9b"
64 static const uint32_t pp_nv12_scaling_gen9[][4] = {
65 #include "shaders/post_processing/gen9/pl2_to_pl2.g9b"
68 static const uint32_t pp_nv12_avs_gen9[][4] = {
69 #include "shaders/post_processing/gen9/pl2_to_pl2.g9b"
72 static const uint32_t pp_nv12_dndi_gen9[][4] = {
75 static const uint32_t pp_nv12_dn_gen9[][4] = {
78 static const uint32_t pp_nv12_load_save_pa_gen9[][4] = {
79 #include "shaders/post_processing/gen9/pl2_to_pa.g9b"
82 static const uint32_t pp_pl3_load_save_pa_gen9[][4] = {
83 #include "shaders/post_processing/gen9/pl3_to_pa.g9b"
86 static const uint32_t pp_pa_load_save_nv12_gen9[][4] = {
87 #include "shaders/post_processing/gen9/pa_to_pl2.g9b"
90 static const uint32_t pp_pa_load_save_pl3_gen9[][4] = {
91 #include "shaders/post_processing/gen9/pa_to_pl3.g9b"
94 static const uint32_t pp_pa_load_save_pa_gen9[][4] = {
95 #include "shaders/post_processing/gen9/pa_to_pa.g9b"
98 static const uint32_t pp_rgbx_load_save_nv12_gen9[][4] = {
99 #include "shaders/post_processing/gen9/rgbx_to_nv12.g9b"
102 static const uint32_t pp_nv12_load_save_rgbx_gen9[][4] = {
103 #include "shaders/post_processing/gen9/pl2_to_rgbx.g9b"
106 static const uint32_t pp_nv12_blending_gen9[][4] = {
109 #define MAX_SCALING_SURFACES 16
111 #define DEFAULT_MOCS 0x02
113 static const uint32_t pp_10bit_scaling_gen9[][4] = {
114 #include "shaders/post_processing/gen9/conv_p010.g9b"
117 static const uint32_t pp_yuv420p8_scaling_gen9[][4] = {
118 #include "shaders/post_processing/gen9/conv_nv12.g9b"
121 static struct pp_module pp_modules_gen9[] = {
124 "NULL module (for testing)",
127 sizeof(pp_null_gen9),
137 PP_NV12_LOAD_SAVE_N12,
138 pp_nv12_load_save_nv12_gen9,
139 sizeof(pp_nv12_load_save_nv12_gen9),
143 gen8_pp_plx_avs_initialize,
149 PP_NV12_LOAD_SAVE_PL3,
150 pp_nv12_load_save_pl3_gen9,
151 sizeof(pp_nv12_load_save_pl3_gen9),
154 gen8_pp_plx_avs_initialize,
160 PP_PL3_LOAD_SAVE_N12,
161 pp_pl3_load_save_nv12_gen9,
162 sizeof(pp_pl3_load_save_nv12_gen9),
166 gen8_pp_plx_avs_initialize,
172 PP_PL3_LOAD_SAVE_PL3,
173 pp_pl3_load_save_pl3_gen9,
174 sizeof(pp_pl3_load_save_pl3_gen9),
178 gen8_pp_plx_avs_initialize,
183 "NV12 Scaling module",
185 pp_nv12_scaling_gen9,
186 sizeof(pp_nv12_scaling_gen9),
190 gen8_pp_plx_avs_initialize,
198 sizeof(pp_nv12_avs_gen9),
202 gen8_pp_plx_avs_initialize,
210 sizeof(pp_nv12_dndi_gen9),
222 sizeof(pp_nv12_dn_gen9),
231 PP_NV12_LOAD_SAVE_PA,
232 pp_nv12_load_save_pa_gen9,
233 sizeof(pp_nv12_load_save_pa_gen9),
237 gen8_pp_plx_avs_initialize,
244 pp_pl3_load_save_pa_gen9,
245 sizeof(pp_pl3_load_save_pa_gen9),
249 gen8_pp_plx_avs_initialize,
255 PP_PA_LOAD_SAVE_NV12,
256 pp_pa_load_save_nv12_gen9,
257 sizeof(pp_pa_load_save_nv12_gen9),
261 gen8_pp_plx_avs_initialize,
268 pp_pa_load_save_pl3_gen9,
269 sizeof(pp_pa_load_save_pl3_gen9),
273 gen8_pp_plx_avs_initialize,
280 pp_pa_load_save_pa_gen9,
281 sizeof(pp_pa_load_save_pa_gen9),
285 gen8_pp_plx_avs_initialize,
291 PP_RGBX_LOAD_SAVE_NV12,
292 pp_rgbx_load_save_nv12_gen9,
293 sizeof(pp_rgbx_load_save_nv12_gen9),
297 gen8_pp_plx_avs_initialize,
303 PP_NV12_LOAD_SAVE_RGBX,
304 pp_nv12_load_save_rgbx_gen9,
305 sizeof(pp_nv12_load_save_rgbx_gen9),
309 gen8_pp_plx_avs_initialize,
313 static const AVSConfig gen9_avs_config = {
314 .coeff_frac_bits = 6,
315 .coeff_epsilon = 1.0f / (1U << 6),
317 .num_luma_coeffs = 8,
318 .num_chroma_coeffs = 4,
322 .y_k_h = { -2, -2, -2, -2, -2, -2, -2, -2 },
323 .y_k_v = { -2, -2, -2, -2, -2, -2, -2, -2 },
324 .uv_k_h = { -2, -2, -2, -2 },
325 .uv_k_v = { -2, -2, -2, -2 },
328 .y_k_h = { 2, 2, 2, 2, 2, 2, 2, 2 },
329 .y_k_v = { 2, 2, 2, 2, 2, 2, 2, 2 },
330 .uv_k_h = { 2, 2, 2, 2 },
331 .uv_k_v = { 2, 2, 2, 2 },
337 gen9_pp_pipeline_select(VADriverContextP ctx,
338 struct i965_post_processing_context *pp_context)
340 struct intel_batchbuffer *batch = pp_context->batch;
342 BEGIN_BATCH(batch, 1);
344 CMD_PIPELINE_SELECT |
345 PIPELINE_SELECT_MEDIA |
346 GEN9_FORCE_MEDIA_AWAKE_ON |
347 GEN9_MEDIA_DOP_GATE_OFF |
348 GEN9_PIPELINE_SELECTION_MASK |
349 GEN9_MEDIA_DOP_GATE_MASK |
350 GEN9_FORCE_MEDIA_AWAKE_MASK);
351 ADVANCE_BATCH(batch);
355 gen9_pp_state_base_address(VADriverContextP ctx,
356 struct i965_post_processing_context *pp_context)
358 struct intel_batchbuffer *batch = pp_context->batch;
360 BEGIN_BATCH(batch, 19);
361 OUT_BATCH(batch, CMD_STATE_BASE_ADDRESS | (19 - 2));
362 /* DW1 Generate state address */
363 OUT_BATCH(batch, 0 | BASE_ADDRESS_MODIFY);
366 /* DW4-5 Surface state address */
367 OUT_RELOC64(batch, pp_context->surface_state_binding_table.bo, I915_GEM_DOMAIN_INSTRUCTION, 0, BASE_ADDRESS_MODIFY); /* Surface state base address */
368 /* DW6-7 Dynamic state address */
369 OUT_RELOC64(batch, pp_context->dynamic_state.bo, I915_GEM_DOMAIN_RENDER | I915_GEM_DOMAIN_SAMPLER,
370 0, 0 | BASE_ADDRESS_MODIFY);
372 /* DW8. Indirect object address */
373 OUT_BATCH(batch, 0 | BASE_ADDRESS_MODIFY);
376 /* DW10-11 Instruction base address */
377 OUT_RELOC64(batch, pp_context->instruction_state.bo, I915_GEM_DOMAIN_INSTRUCTION, 0, BASE_ADDRESS_MODIFY);
379 OUT_BATCH(batch, 0xFFFF0000 | BASE_ADDRESS_MODIFY);
380 OUT_BATCH(batch, 0xFFFF0000 | BASE_ADDRESS_MODIFY);
381 OUT_BATCH(batch, 0xFFFF0000 | BASE_ADDRESS_MODIFY);
382 OUT_BATCH(batch, 0xFFFF0000 | BASE_ADDRESS_MODIFY);
384 /* Bindless surface state base address */
385 OUT_BATCH(batch, 0 | BASE_ADDRESS_MODIFY);
387 OUT_BATCH(batch, 0xfffff000);
389 ADVANCE_BATCH(batch);
393 gen9_pp_end_pipeline(VADriverContextP ctx,
394 struct i965_post_processing_context *pp_context)
396 struct intel_batchbuffer *batch = pp_context->batch;
398 BEGIN_BATCH(batch, 1);
400 CMD_PIPELINE_SELECT |
401 PIPELINE_SELECT_MEDIA |
402 GEN9_FORCE_MEDIA_AWAKE_OFF |
403 GEN9_MEDIA_DOP_GATE_ON |
404 GEN9_PIPELINE_SELECTION_MASK |
405 GEN9_MEDIA_DOP_GATE_MASK |
406 GEN9_FORCE_MEDIA_AWAKE_MASK);
407 ADVANCE_BATCH(batch);
411 gen9_pp_pipeline_setup(VADriverContextP ctx,
412 struct i965_post_processing_context *pp_context)
414 struct intel_batchbuffer *batch = pp_context->batch;
416 intel_batchbuffer_start_atomic(batch, 0x1000);
417 intel_batchbuffer_emit_mi_flush(batch);
418 gen9_pp_pipeline_select(ctx, pp_context);
419 gen9_pp_state_base_address(ctx, pp_context);
420 gen8_pp_vfe_state(ctx, pp_context);
421 gen8_pp_curbe_load(ctx, pp_context);
422 gen8_interface_descriptor_load(ctx, pp_context);
423 gen8_pp_object_walker(ctx, pp_context);
424 gen9_pp_end_pipeline(ctx, pp_context);
425 intel_batchbuffer_end_atomic(batch);
429 gen9_post_processing(VADriverContextP ctx,
430 struct i965_post_processing_context *pp_context,
431 const struct i965_surface *src_surface,
432 const VARectangle *src_rect,
433 struct i965_surface *dst_surface,
434 const VARectangle *dst_rect,
440 va_status = gen8_pp_initialize(ctx, pp_context,
448 if (va_status == VA_STATUS_SUCCESS) {
449 gen8_pp_states_setup(ctx, pp_context);
450 gen9_pp_pipeline_setup(ctx, pp_context);
457 gen9_vpp_scaling_sample_state(VADriverContextP ctx,
458 struct i965_gpe_context *gpe_context,
459 VARectangle *src_rect,
460 VARectangle *dst_rect)
462 struct gen8_sampler_state *sampler_state;
464 if (gpe_context == NULL || !src_rect || !dst_rect)
466 dri_bo_map(gpe_context->sampler.bo, 1);
468 if (gpe_context->sampler.bo->virtual == NULL)
471 assert(gpe_context->sampler.bo->virtual);
473 sampler_state = (struct gen8_sampler_state *)
474 (gpe_context->sampler.bo->virtual + gpe_context->sampler.offset);
476 memset(sampler_state, 0, sizeof(*sampler_state));
478 if ((src_rect->width == dst_rect->width) &&
479 (src_rect->height == dst_rect->height)) {
480 sampler_state->ss0.min_filter = I965_MAPFILTER_NEAREST;
481 sampler_state->ss0.mag_filter = I965_MAPFILTER_NEAREST;
483 sampler_state->ss0.min_filter = I965_MAPFILTER_LINEAR;
484 sampler_state->ss0.mag_filter = I965_MAPFILTER_LINEAR;
487 sampler_state->ss3.r_wrap_mode = I965_TEXCOORDMODE_CLAMP;
488 sampler_state->ss3.s_wrap_mode = I965_TEXCOORDMODE_CLAMP;
489 sampler_state->ss3.t_wrap_mode = I965_TEXCOORDMODE_CLAMP;
491 dri_bo_unmap(gpe_context->sampler.bo);
495 gen9_post_processing_context_init(VADriverContextP ctx,
497 struct intel_batchbuffer *batch)
499 struct i965_driver_data *i965 = i965_driver_data(ctx);
500 struct i965_post_processing_context *pp_context = data;
501 struct i965_gpe_context *gpe_context;
502 struct i965_kernel scaling_kernel;
504 gen8_post_processing_context_common_init(ctx, data, pp_modules_gen9, ARRAY_ELEMS(pp_modules_gen9), batch);
505 avs_init_state(&pp_context->pp_avs_context.state, &gen9_avs_config);
507 pp_context->intel_post_processing = gen9_post_processing;
509 gpe_context = &pp_context->scaling_10bit_context;
510 memset(&scaling_kernel, 0, sizeof(scaling_kernel));
511 scaling_kernel.bin = pp_10bit_scaling_gen9;
512 scaling_kernel.size = sizeof(pp_10bit_scaling_gen9);
513 gen8_gpe_load_kernels(ctx, gpe_context, &scaling_kernel, 1);
514 gpe_context->idrt.entry_size = ALIGN(sizeof(struct gen8_interface_descriptor_data), 64);
515 gpe_context->idrt.max_entries = 1;
516 gpe_context->sampler.entry_size = ALIGN(sizeof(struct gen8_sampler_state), 64);
517 gpe_context->sampler.max_entries = 1;
518 gpe_context->curbe.length = ALIGN(sizeof(struct scaling_input_parameter), 64);
520 gpe_context->surface_state_binding_table.max_entries = MAX_SCALING_SURFACES;
521 gpe_context->surface_state_binding_table.binding_table_offset = 0;
522 gpe_context->surface_state_binding_table.surface_state_offset = ALIGN(MAX_SCALING_SURFACES * 4, 64);
523 gpe_context->surface_state_binding_table.length = ALIGN(MAX_SCALING_SURFACES * 4, 64) + ALIGN(MAX_SCALING_SURFACES * SURFACE_STATE_PADDED_SIZE_GEN9, 64);
525 if (i965->intel.eu_total > 0) {
526 gpe_context->vfe_state.max_num_threads = i965->intel.eu_total * 6;
528 if (i965->intel.has_bsd2)
529 gpe_context->vfe_state.max_num_threads = 300;
531 gpe_context->vfe_state.max_num_threads = 60;
534 gpe_context->vfe_state.curbe_allocation_size = 37;
535 gpe_context->vfe_state.urb_entry_size = 16;
536 gpe_context->vfe_state.num_urb_entries = 127;
537 gpe_context->vfe_state.gpgpu_mode = 0;
539 gen8_gpe_context_init(ctx, gpe_context);
540 pp_context->scaling_context_initialized = 1;
542 /* initialize the YUV420 8-Bit scaling context. The below is supported.
548 gpe_context = &pp_context->scaling_yuv420p8_context;
549 memset(&scaling_kernel, 0, sizeof(scaling_kernel));
550 scaling_kernel.bin = pp_yuv420p8_scaling_gen9;
551 scaling_kernel.size = sizeof(pp_yuv420p8_scaling_gen9);
552 gen8_gpe_load_kernels(ctx, gpe_context, &scaling_kernel, 1);
553 gpe_context->idrt.entry_size = ALIGN(sizeof(struct gen8_interface_descriptor_data), 64);
554 gpe_context->idrt.max_entries = 1;
555 gpe_context->sampler.entry_size = ALIGN(sizeof(struct gen8_sampler_state), 64);
556 gpe_context->sampler.max_entries = 1;
557 gpe_context->curbe.length = ALIGN(sizeof(struct scaling_input_parameter), 32);
559 gpe_context->surface_state_binding_table.max_entries = MAX_SCALING_SURFACES;
560 gpe_context->surface_state_binding_table.binding_table_offset = 0;
561 gpe_context->surface_state_binding_table.surface_state_offset = ALIGN(MAX_SCALING_SURFACES * 4, 64);
562 gpe_context->surface_state_binding_table.length = ALIGN(MAX_SCALING_SURFACES * 4, 64) + ALIGN(MAX_SCALING_SURFACES * SURFACE_STATE_PADDED_SIZE_GEN9, 64);
564 if (i965->intel.eu_total > 0) {
565 gpe_context->vfe_state.max_num_threads = i965->intel.eu_total * 6;
567 if (i965->intel.has_bsd2)
568 gpe_context->vfe_state.max_num_threads = 300;
570 gpe_context->vfe_state.max_num_threads = 60;
573 gpe_context->vfe_state.curbe_allocation_size = 37;
574 gpe_context->vfe_state.urb_entry_size = 16;
575 gpe_context->vfe_state.num_urb_entries = 127;
576 gpe_context->vfe_state.gpgpu_mode = 0;
578 gen8_gpe_context_init(ctx, gpe_context);
579 pp_context->scaling_8bit_initialized = VPPGPE_8BIT_420;
584 gen9_add_dri_buffer_2d_gpe_surface(VADriverContextP ctx,
585 struct i965_gpe_context *gpe_context,
587 unsigned int bo_offset,
591 int is_media_block_rw,
596 struct i965_gpe_resource gpe_resource;
597 struct i965_gpe_surface gpe_surface;
599 i965_dri_object_to_2d_gpe_resource(&gpe_resource, bo, width, height, pitch);
600 memset(&gpe_surface, 0, sizeof(gpe_surface));
601 gpe_surface.gpe_resource = &gpe_resource;
602 gpe_surface.is_2d_surface = 1;
603 gpe_surface.is_media_block_rw = !!is_media_block_rw;
604 gpe_surface.cacheability_control = DEFAULT_MOCS;
605 gpe_surface.format = format;
606 gpe_surface.is_override_offset = 1;
607 gpe_surface.offset = bo_offset;
608 gpe_surface.is_16bpp = is_10bit;
610 gen9_gpe_context_add_surface(gpe_context, &gpe_surface, index);
612 i965_free_gpe_resource(&gpe_resource);
616 gen9_run_kernel_media_object_walker(VADriverContextP ctx,
617 struct intel_batchbuffer *batch,
618 struct i965_gpe_context *gpe_context,
619 struct gpe_media_object_walker_parameter *param)
621 if (!batch || !gpe_context || !param)
624 intel_batchbuffer_start_atomic(batch, 0x1000);
626 intel_batchbuffer_emit_mi_flush(batch);
628 gen9_gpe_pipeline_setup(ctx, gpe_context, batch);
629 gen8_gpe_media_object_walker(ctx, gpe_context, batch, param);
630 gen8_gpe_media_state_flush(ctx, gpe_context, batch);
632 gen9_gpe_pipeline_end(ctx, gpe_context, batch);
634 intel_batchbuffer_end_atomic(batch);
636 intel_batchbuffer_flush(batch);
641 pp_get_surface_fourcc(VADriverContextP ctx, struct i965_surface *surface)
645 if (surface->type == I965_SURFACE_TYPE_IMAGE) {
646 struct object_image *obj_image = (struct object_image *)surface->base;
647 fourcc = obj_image->image.format.fourcc;
649 struct object_surface *obj_surface = (struct object_surface *)surface->base;
650 fourcc = obj_surface->fourcc;
657 gen9_gpe_context_p010_scaling_curbe(VADriverContextP ctx,
658 struct i965_gpe_context *gpe_context,
659 VARectangle *src_rect,
660 struct i965_surface *src_surface,
661 VARectangle *dst_rect,
662 struct i965_surface *dst_surface)
664 struct scaling_input_parameter *scaling_curbe;
665 float src_width, src_height;
669 if ((gpe_context == NULL) ||
670 (src_rect == NULL) || (src_surface == NULL) ||
671 (dst_rect == NULL) || (dst_surface == NULL))
674 scaling_curbe = i965_gpe_context_map_curbe(gpe_context);
679 memset(scaling_curbe, 0, sizeof(struct scaling_input_parameter));
681 scaling_curbe->bti_input = BTI_SCALING_INPUT_Y;
682 scaling_curbe->bti_output = BTI_SCALING_OUTPUT_Y;
684 /* As the src_rect/dst_rect is already checked, it is skipped.*/
685 scaling_curbe->x_dst = dst_rect->x;
686 scaling_curbe->y_dst = dst_rect->y;
688 src_width = src_rect->x + src_rect->width;
689 src_height = src_rect->y + src_rect->height;
691 scaling_curbe->inv_width = 1 / src_width;
692 scaling_curbe->inv_height = 1 / src_height;
694 coeff = (float) (src_rect->width) / dst_rect->width;
695 scaling_curbe->x_factor = coeff / src_width;
696 scaling_curbe->x_orig = (float)(src_rect->x) / src_width;
698 coeff = (float) (src_rect->height) / dst_rect->height;
699 scaling_curbe->y_factor = coeff / src_height;
700 scaling_curbe->y_orig = (float)(src_rect->y) / src_height;
702 fourcc = pp_get_surface_fourcc(ctx, src_surface);
703 if (fourcc == VA_FOURCC_P010) {
704 scaling_curbe->dw7.src_packed = 1;
705 scaling_curbe->dw7.src_msb = 1;
707 /* I010 will use LSB */
709 fourcc = pp_get_surface_fourcc(ctx, dst_surface);
711 if (fourcc == VA_FOURCC_P010) {
712 scaling_curbe->dw7.dst_packed = 1;
713 scaling_curbe->dw7.dst_msb = 1;
715 /* I010 will use LSB */
717 i965_gpe_context_unmap_curbe(gpe_context);
721 gen9_pp_context_get_surface_conf(VADriverContextP ctx,
722 struct i965_surface *surface,
730 if (!rect || !surface || !width || !height || !pitch || !bo_offset)
733 if (surface->base == NULL)
736 fourcc = pp_get_surface_fourcc(ctx, surface);
737 if (surface->type == I965_SURFACE_TYPE_SURFACE) {
738 struct object_surface *obj_surface;
740 obj_surface = (struct object_surface *)surface->base;
741 width[0] = MIN(rect->x + rect->width, obj_surface->orig_width);
742 height[0] = MIN(rect->y + rect->height, obj_surface->orig_height);
743 pitch[0] = obj_surface->width;
746 if (fourcc == VA_FOURCC_P010 || fourcc == VA_FOURCC_NV12) {
747 width[1] = width[0] / 2;
748 height[1] = height[0] / 2;
749 pitch[1] = obj_surface->cb_cr_pitch;
750 bo_offset[1] = obj_surface->width * obj_surface->y_cb_offset;
752 /* I010/I420 format */
753 width[1] = width[0] / 2;
754 height[1] = height[0] / 2;
755 pitch[1] = obj_surface->cb_cr_pitch;
756 bo_offset[1] = obj_surface->width * obj_surface->y_cb_offset;
757 width[2] = width[0] / 2;
758 height[2] = height[0] / 2;
759 pitch[2] = obj_surface->cb_cr_pitch;
760 bo_offset[2] = obj_surface->width * obj_surface->y_cr_offset;
764 struct object_image *obj_image;
766 obj_image = (struct object_image *)surface->base;
768 width[0] = MIN(rect->x + rect->width, obj_image->image.width);
769 height[0] = MIN(rect->y + rect->height, obj_image->image.height);
770 pitch[0] = obj_image->image.pitches[0];
771 bo_offset[0] = obj_image->image.offsets[0];
773 if (fourcc == VA_FOURCC_P010 || fourcc == VA_FOURCC_NV12) {
774 width[1] = width[0] / 2;
775 height[1] = height[0] / 2;
776 pitch[1] = obj_image->image.pitches[1];
777 bo_offset[1] = obj_image->image.offsets[1];
779 /* I010/I420 format */
780 width[1] = width[0] / 2;
781 height[1] = height[0] / 2;
782 pitch[1] = obj_image->image.pitches[1];
783 bo_offset[1] = obj_image->image.offsets[1];
784 width[2] = width[0] / 2;
785 height[2] = height[0] / 2;
786 pitch[2] = obj_image->image.pitches[2];
787 bo_offset[2] = obj_image->image.offsets[2];
796 gen9_gpe_context_p010_scaling_surfaces(VADriverContextP ctx,
797 struct i965_gpe_context *gpe_context,
798 VARectangle *src_rect,
799 struct i965_surface *src_surface,
800 VARectangle *dst_rect,
801 struct i965_surface *dst_surface)
804 int width[3], height[3], pitch[3], bo_offset[3];
806 struct object_surface *obj_surface;
807 struct object_image *obj_image;
810 if ((gpe_context == NULL) ||
811 (src_rect == NULL) || (src_surface == NULL) ||
812 (dst_rect == NULL) || (dst_surface == NULL))
815 if (src_surface->base == NULL || dst_surface->base == NULL)
818 fourcc = pp_get_surface_fourcc(ctx, src_surface);
820 if (src_surface->type == I965_SURFACE_TYPE_SURFACE) {
821 obj_surface = (struct object_surface *)src_surface->base;
822 bo = obj_surface->bo;
824 obj_image = (struct object_image *)src_surface->base;
829 if (gen9_pp_context_get_surface_conf(ctx, src_surface, src_rect,
830 width, height, pitch,
832 bti = BTI_SCALING_INPUT_Y;
834 gen9_add_dri_buffer_2d_gpe_surface(ctx, gpe_context, bo,
838 I965_SURFACEFORMAT_R16_UNORM,
840 if (fourcc == VA_FOURCC_P010) {
841 gen9_add_dri_buffer_2d_gpe_surface(ctx, gpe_context, bo,
845 I965_SURFACEFORMAT_R16G16_UNORM,
848 gen9_add_dri_buffer_2d_gpe_surface(ctx, gpe_context, bo,
852 I965_SURFACEFORMAT_R16_UNORM,
855 gen9_add_dri_buffer_2d_gpe_surface(ctx, gpe_context, bo,
859 I965_SURFACEFORMAT_R16_UNORM,
864 fourcc = pp_get_surface_fourcc(ctx, dst_surface);
866 if (dst_surface->type == I965_SURFACE_TYPE_SURFACE) {
867 obj_surface = (struct object_surface *)dst_surface->base;
868 bo = obj_surface->bo;
870 obj_image = (struct object_image *)dst_surface->base;
874 if (gen9_pp_context_get_surface_conf(ctx, dst_surface, dst_rect,
875 width, height, pitch,
877 bti = BTI_SCALING_OUTPUT_Y;
879 gen9_add_dri_buffer_2d_gpe_surface(ctx, gpe_context, bo,
883 I965_SURFACEFORMAT_R16_UINT,
885 if (fourcc == VA_FOURCC_P010) {
886 gen9_add_dri_buffer_2d_gpe_surface(ctx, gpe_context, bo,
888 width[1] * 2, height[1],
890 I965_SURFACEFORMAT_R16_UINT,
893 gen9_add_dri_buffer_2d_gpe_surface(ctx, gpe_context, bo,
897 I965_SURFACEFORMAT_R16_UINT,
900 gen9_add_dri_buffer_2d_gpe_surface(ctx, gpe_context, bo,
904 I965_SURFACEFORMAT_R16_UINT,
913 gen9_p010_scaling_post_processing(
914 VADriverContextP ctx,
915 struct i965_post_processing_context *pp_context,
916 struct i965_surface *src_surface,
917 VARectangle *src_rect,
918 struct i965_surface *dst_surface,
919 VARectangle *dst_rect)
921 struct i965_gpe_context *gpe_context;
922 struct gpe_media_object_walker_parameter media_object_walker_param;
923 struct intel_vpp_kernel_walker_parameter kernel_walker_param;
925 if (!pp_context || !src_surface || !src_rect || !dst_surface || !dst_rect)
926 return VA_STATUS_ERROR_INVALID_PARAMETER;
928 if (!pp_context->scaling_context_initialized)
929 return VA_STATUS_ERROR_UNIMPLEMENTED;
931 gpe_context = &pp_context->scaling_10bit_context;
933 gen8_gpe_context_init(ctx, gpe_context);
934 gen9_vpp_scaling_sample_state(ctx, gpe_context, src_rect, dst_rect);
935 gen9_gpe_reset_binding_table(ctx, gpe_context);
936 gen9_gpe_context_p010_scaling_curbe(ctx, gpe_context,
937 src_rect, src_surface,
938 dst_rect, dst_surface);
940 gen9_gpe_context_p010_scaling_surfaces(ctx, gpe_context,
941 src_rect, src_surface,
942 dst_rect, dst_surface);
944 gen8_gpe_setup_interface_data(ctx, gpe_context);
946 memset(&kernel_walker_param, 0, sizeof(kernel_walker_param));
947 kernel_walker_param.resolution_x = ALIGN(dst_rect->width, 16) >> 4;
948 kernel_walker_param.resolution_y = ALIGN(dst_rect->height, 16) >> 4;
949 kernel_walker_param.no_dependency = 1;
951 intel_vpp_init_media_object_walker_parameter(&kernel_walker_param, &media_object_walker_param);
953 gen9_run_kernel_media_object_walker(ctx, pp_context->batch,
955 &media_object_walker_param);
957 return VA_STATUS_SUCCESS;
961 gen9_gpe_context_yuv420p8_scaling_curbe(VADriverContextP ctx,
962 struct i965_gpe_context *gpe_context,
963 VARectangle *src_rect,
964 struct i965_surface *src_surface,
965 VARectangle *dst_rect,
966 struct i965_surface *dst_surface)
968 struct scaling_input_parameter *scaling_curbe;
969 float src_width, src_height;
973 if ((gpe_context == NULL) ||
974 (src_rect == NULL) || (src_surface == NULL) ||
975 (dst_rect == NULL) || (dst_surface == NULL))
978 scaling_curbe = i965_gpe_context_map_curbe(gpe_context);
983 memset(scaling_curbe, 0, sizeof(struct scaling_input_parameter));
985 scaling_curbe->bti_input = BTI_SCALING_INPUT_Y;
986 scaling_curbe->bti_output = BTI_SCALING_OUTPUT_Y;
988 /* As the src_rect/dst_rect is already checked, it is skipped.*/
989 scaling_curbe->x_dst = dst_rect->x;
990 scaling_curbe->y_dst = dst_rect->y;
992 src_width = src_rect->x + src_rect->width;
993 src_height = src_rect->y + src_rect->height;
995 scaling_curbe->inv_width = 1 / src_width;
996 scaling_curbe->inv_height = 1 / src_height;
998 coeff = (float) (src_rect->width) / dst_rect->width;
999 scaling_curbe->x_factor = coeff / src_width;
1000 scaling_curbe->x_orig = (float)(src_rect->x) / src_width;
1002 coeff = (float) (src_rect->height) / dst_rect->height;
1003 scaling_curbe->y_factor = coeff / src_height;
1004 scaling_curbe->y_orig = (float)(src_rect->y) / src_height;
1006 fourcc = pp_get_surface_fourcc(ctx, src_surface);
1007 if (fourcc == VA_FOURCC_NV12) {
1008 scaling_curbe->dw7.src_packed = 1;
1011 fourcc = pp_get_surface_fourcc(ctx, dst_surface);
1013 if (fourcc == VA_FOURCC_NV12) {
1014 scaling_curbe->dw7.dst_packed = 1;
1017 i965_gpe_context_unmap_curbe(gpe_context);
1021 gen9_gpe_context_yuv420p8_scaling_surfaces(VADriverContextP ctx,
1022 struct i965_gpe_context *gpe_context,
1023 VARectangle *src_rect,
1024 struct i965_surface *src_surface,
1025 VARectangle *dst_rect,
1026 struct i965_surface *dst_surface)
1028 unsigned int fourcc;
1029 int width[3], height[3], pitch[3], bo_offset[3];
1031 struct object_surface *obj_surface;
1032 struct object_image *obj_image;
1035 if ((gpe_context == NULL) ||
1036 (src_rect == NULL) || (src_surface == NULL) ||
1037 (dst_rect == NULL) || (dst_surface == NULL))
1040 if (src_surface->base == NULL || dst_surface->base == NULL)
1043 fourcc = pp_get_surface_fourcc(ctx, src_surface);
1045 if (src_surface->type == I965_SURFACE_TYPE_SURFACE) {
1046 obj_surface = (struct object_surface *)src_surface->base;
1047 bo = obj_surface->bo;
1049 obj_image = (struct object_image *)src_surface->base;
1054 if (gen9_pp_context_get_surface_conf(ctx, src_surface, src_rect,
1055 width, height, pitch,
1057 bti = BTI_SCALING_INPUT_Y;
1059 gen9_add_dri_buffer_2d_gpe_surface(ctx, gpe_context, bo,
1061 width[0], height[0],
1063 I965_SURFACEFORMAT_R8_UNORM,
1065 if (fourcc == VA_FOURCC_NV12) {
1066 gen9_add_dri_buffer_2d_gpe_surface(ctx, gpe_context, bo,
1068 width[1], height[1],
1070 I965_SURFACEFORMAT_R8G8_UNORM,
1073 gen9_add_dri_buffer_2d_gpe_surface(ctx, gpe_context, bo,
1075 width[1], height[1],
1077 I965_SURFACEFORMAT_R8_UNORM,
1080 gen9_add_dri_buffer_2d_gpe_surface(ctx, gpe_context, bo,
1082 width[2], height[2],
1084 I965_SURFACEFORMAT_R8_UNORM,
1089 fourcc = pp_get_surface_fourcc(ctx, dst_surface);
1091 if (dst_surface->type == I965_SURFACE_TYPE_SURFACE) {
1092 obj_surface = (struct object_surface *)dst_surface->base;
1093 bo = obj_surface->bo;
1095 obj_image = (struct object_image *)dst_surface->base;
1099 if (gen9_pp_context_get_surface_conf(ctx, dst_surface, dst_rect,
1100 width, height, pitch,
1102 bti = BTI_SCALING_OUTPUT_Y;
1104 gen9_add_dri_buffer_2d_gpe_surface(ctx, gpe_context, bo,
1106 width[0], height[0],
1108 I965_SURFACEFORMAT_R8_UINT,
1110 if (fourcc == VA_FOURCC_NV12) {
1111 gen9_add_dri_buffer_2d_gpe_surface(ctx, gpe_context, bo,
1113 width[1] * 2, height[1],
1115 I965_SURFACEFORMAT_R16_UINT,
1118 gen9_add_dri_buffer_2d_gpe_surface(ctx, gpe_context, bo,
1120 width[1], height[1],
1122 I965_SURFACEFORMAT_R8_UINT,
1125 gen9_add_dri_buffer_2d_gpe_surface(ctx, gpe_context, bo,
1127 width[2], height[2],
1129 I965_SURFACEFORMAT_R8_UINT,
1138 gen9_yuv420p8_scaling_post_processing(
1139 VADriverContextP ctx,
1140 struct i965_post_processing_context *pp_context,
1141 struct i965_surface *src_surface,
1142 VARectangle *src_rect,
1143 struct i965_surface *dst_surface,
1144 VARectangle *dst_rect)
1146 struct i965_gpe_context *gpe_context;
1147 struct gpe_media_object_walker_parameter media_object_walker_param;
1148 struct intel_vpp_kernel_walker_parameter kernel_walker_param;
1150 if (!pp_context || !src_surface || !src_rect || !dst_surface || !dst_rect)
1151 return VA_STATUS_ERROR_INVALID_PARAMETER;
1153 if (!(pp_context->scaling_8bit_initialized & VPPGPE_8BIT_420))
1154 return VA_STATUS_ERROR_UNIMPLEMENTED;
1156 gpe_context = &pp_context->scaling_yuv420p8_context;
1158 gen8_gpe_context_init(ctx, gpe_context);
1159 gen9_vpp_scaling_sample_state(ctx, gpe_context, src_rect, dst_rect);
1160 gen9_gpe_reset_binding_table(ctx, gpe_context);
1161 gen9_gpe_context_yuv420p8_scaling_curbe(ctx, gpe_context,
1162 src_rect, src_surface,
1163 dst_rect, dst_surface);
1165 gen9_gpe_context_yuv420p8_scaling_surfaces(ctx, gpe_context,
1166 src_rect, src_surface,
1167 dst_rect, dst_surface);
1169 gen8_gpe_setup_interface_data(ctx, gpe_context);
1171 memset(&kernel_walker_param, 0, sizeof(kernel_walker_param));
1172 kernel_walker_param.resolution_x = ALIGN(dst_rect->width, 16) >> 4;
1173 kernel_walker_param.resolution_y = ALIGN(dst_rect->height, 16) >> 4;
1174 kernel_walker_param.no_dependency = 1;
1176 intel_vpp_init_media_object_walker_parameter(&kernel_walker_param, &media_object_walker_param);
1178 gen9_run_kernel_media_object_walker(ctx, pp_context->batch,
1180 &media_object_walker_param);
1182 return VA_STATUS_SUCCESS;