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 "i965_yuv_coefs.h"
41 #include "gen8_post_processing.h"
42 #include "gen75_picture_process.h"
43 #include "intel_gen_vppapi.h"
44 #include "intel_common_vpp_internal.h"
46 static const uint32_t pp_null_gen9[][4] = {
49 static const uint32_t pp_nv12_load_save_nv12_gen9[][4] = {
50 #include "shaders/post_processing/gen9/pl2_to_pl2.g9b"
53 static const uint32_t pp_nv12_load_save_pl3_gen9[][4] = {
54 #include "shaders/post_processing/gen9/pl2_to_pl3.g9b"
57 static const uint32_t pp_pl3_load_save_nv12_gen9[][4] = {
58 #include "shaders/post_processing/gen9/pl3_to_pl2.g9b"
61 static const uint32_t pp_pl3_load_save_pl3_gen9[][4] = {
62 #include "shaders/post_processing/gen9/pl3_to_pl3.g9b"
65 static const uint32_t pp_nv12_scaling_gen9[][4] = {
66 #include "shaders/post_processing/gen9/pl2_to_pl2.g9b"
69 static const uint32_t pp_nv12_avs_gen9[][4] = {
70 #include "shaders/post_processing/gen9/pl2_to_pl2.g9b"
73 static const uint32_t pp_nv12_dndi_gen9[][4] = {
76 static const uint32_t pp_nv12_dn_gen9[][4] = {
79 static const uint32_t pp_nv12_load_save_pa_gen9[][4] = {
80 #include "shaders/post_processing/gen9/pl2_to_pa.g9b"
83 static const uint32_t pp_pl3_load_save_pa_gen9[][4] = {
84 #include "shaders/post_processing/gen9/pl3_to_pa.g9b"
87 static const uint32_t pp_pa_load_save_nv12_gen9[][4] = {
88 #include "shaders/post_processing/gen9/pa_to_pl2.g9b"
91 static const uint32_t pp_pa_load_save_pl3_gen9[][4] = {
92 #include "shaders/post_processing/gen9/pa_to_pl3.g9b"
95 static const uint32_t pp_pa_load_save_pa_gen9[][4] = {
96 #include "shaders/post_processing/gen9/pa_to_pa.g9b"
99 static const uint32_t pp_rgbx_load_save_nv12_gen9[][4] = {
100 #include "shaders/post_processing/gen9/rgbx_to_nv12.g9b"
103 static const uint32_t pp_nv12_load_save_rgbx_gen9[][4] = {
104 #include "shaders/post_processing/gen9/pl2_to_rgbx.g9b"
107 #define MAX_SCALING_SURFACES 16
109 #define DEFAULT_MOCS 0x02
111 static const uint32_t pp_10bit_scaling_gen9[][4] = {
112 #include "shaders/post_processing/gen9/conv_p010.g9b"
115 static const uint32_t pp_yuv420p8_scaling_gen9[][4] = {
116 #include "shaders/post_processing/gen9/conv_nv12.g9b"
119 static const uint32_t pp_10bit_8bit_scaling_gen9[][4] = {
120 #include "shaders/post_processing/gen9/conv_10bit_8bit.g9b"
123 static const uint32_t pp_8bit_420_rgb32_scaling_gen9[][4] = {
124 #include "shaders/post_processing/gen9/conv_8bit_420_rgb32.g9b"
127 struct i965_kernel pp_common_scaling_gen9[] = {
131 pp_10bit_scaling_gen9,
132 sizeof(pp_10bit_scaling_gen9),
139 pp_yuv420p8_scaling_gen9,
140 sizeof(pp_yuv420p8_scaling_gen9),
147 pp_10bit_8bit_scaling_gen9,
148 sizeof(pp_10bit_8bit_scaling_gen9),
155 pp_8bit_420_rgb32_scaling_gen9,
156 sizeof(pp_8bit_420_rgb32_scaling_gen9),
161 static struct pp_module pp_modules_gen9[] = {
164 "NULL module (for testing)",
167 sizeof(pp_null_gen9),
177 PP_NV12_LOAD_SAVE_N12,
178 pp_nv12_load_save_nv12_gen9,
179 sizeof(pp_nv12_load_save_nv12_gen9),
183 gen8_pp_plx_avs_initialize,
189 PP_NV12_LOAD_SAVE_PL3,
190 pp_nv12_load_save_pl3_gen9,
191 sizeof(pp_nv12_load_save_pl3_gen9),
194 gen8_pp_plx_avs_initialize,
200 PP_PL3_LOAD_SAVE_N12,
201 pp_pl3_load_save_nv12_gen9,
202 sizeof(pp_pl3_load_save_nv12_gen9),
206 gen8_pp_plx_avs_initialize,
212 PP_PL3_LOAD_SAVE_PL3,
213 pp_pl3_load_save_pl3_gen9,
214 sizeof(pp_pl3_load_save_pl3_gen9),
218 gen8_pp_plx_avs_initialize,
223 "NV12 Scaling module",
225 pp_nv12_scaling_gen9,
226 sizeof(pp_nv12_scaling_gen9),
230 gen8_pp_plx_avs_initialize,
238 sizeof(pp_nv12_avs_gen9),
242 gen8_pp_plx_avs_initialize,
250 sizeof(pp_nv12_dndi_gen9),
262 sizeof(pp_nv12_dn_gen9),
271 PP_NV12_LOAD_SAVE_PA,
272 pp_nv12_load_save_pa_gen9,
273 sizeof(pp_nv12_load_save_pa_gen9),
277 gen8_pp_plx_avs_initialize,
284 pp_pl3_load_save_pa_gen9,
285 sizeof(pp_pl3_load_save_pa_gen9),
289 gen8_pp_plx_avs_initialize,
295 PP_PA_LOAD_SAVE_NV12,
296 pp_pa_load_save_nv12_gen9,
297 sizeof(pp_pa_load_save_nv12_gen9),
301 gen8_pp_plx_avs_initialize,
308 pp_pa_load_save_pl3_gen9,
309 sizeof(pp_pa_load_save_pl3_gen9),
313 gen8_pp_plx_avs_initialize,
320 pp_pa_load_save_pa_gen9,
321 sizeof(pp_pa_load_save_pa_gen9),
325 gen8_pp_plx_avs_initialize,
331 PP_RGBX_LOAD_SAVE_NV12,
332 pp_rgbx_load_save_nv12_gen9,
333 sizeof(pp_rgbx_load_save_nv12_gen9),
337 gen8_pp_plx_avs_initialize,
343 PP_NV12_LOAD_SAVE_RGBX,
344 pp_nv12_load_save_rgbx_gen9,
345 sizeof(pp_nv12_load_save_rgbx_gen9),
349 gen8_pp_plx_avs_initialize,
353 static const AVSConfig gen9_avs_config = {
354 .coeff_frac_bits = 6,
355 .coeff_epsilon = 1.0f / (1U << 6),
357 .num_luma_coeffs = 8,
358 .num_chroma_coeffs = 4,
362 .y_k_h = { -2, -2, -2, -2, -2, -2, -2, -2 },
363 .y_k_v = { -2, -2, -2, -2, -2, -2, -2, -2 },
364 .uv_k_h = { -2, -2, -2, -2 },
365 .uv_k_v = { -2, -2, -2, -2 },
368 .y_k_h = { 2, 2, 2, 2, 2, 2, 2, 2 },
369 .y_k_v = { 2, 2, 2, 2, 2, 2, 2, 2 },
370 .uv_k_h = { 2, 2, 2, 2 },
371 .uv_k_v = { 2, 2, 2, 2 },
377 gen9_pp_pipeline_select(VADriverContextP ctx,
378 struct i965_post_processing_context *pp_context)
380 struct intel_batchbuffer *batch = pp_context->batch;
382 BEGIN_BATCH(batch, 1);
384 CMD_PIPELINE_SELECT |
385 PIPELINE_SELECT_MEDIA |
386 GEN9_FORCE_MEDIA_AWAKE_ON |
387 GEN9_MEDIA_DOP_GATE_OFF |
388 GEN9_PIPELINE_SELECTION_MASK |
389 GEN9_MEDIA_DOP_GATE_MASK |
390 GEN9_FORCE_MEDIA_AWAKE_MASK);
391 ADVANCE_BATCH(batch);
395 gen9_pp_state_base_address(VADriverContextP ctx,
396 struct i965_post_processing_context *pp_context)
398 struct intel_batchbuffer *batch = pp_context->batch;
400 BEGIN_BATCH(batch, 19);
401 OUT_BATCH(batch, CMD_STATE_BASE_ADDRESS | (19 - 2));
402 /* DW1 Generate state address */
403 OUT_BATCH(batch, 0 | BASE_ADDRESS_MODIFY);
406 /* DW4-5 Surface state address */
407 OUT_RELOC64(batch, pp_context->surface_state_binding_table.bo, I915_GEM_DOMAIN_INSTRUCTION, 0, BASE_ADDRESS_MODIFY); /* Surface state base address */
408 /* DW6-7 Dynamic state address */
409 OUT_RELOC64(batch, pp_context->dynamic_state.bo, I915_GEM_DOMAIN_RENDER | I915_GEM_DOMAIN_SAMPLER,
410 0, 0 | BASE_ADDRESS_MODIFY);
412 /* DW8. Indirect object address */
413 OUT_BATCH(batch, 0 | BASE_ADDRESS_MODIFY);
416 /* DW10-11 Instruction base address */
417 OUT_RELOC64(batch, pp_context->instruction_state.bo, I915_GEM_DOMAIN_INSTRUCTION, 0, BASE_ADDRESS_MODIFY);
419 OUT_BATCH(batch, 0xFFFF0000 | BASE_ADDRESS_MODIFY);
420 OUT_BATCH(batch, 0xFFFF0000 | BASE_ADDRESS_MODIFY);
421 OUT_BATCH(batch, 0xFFFF0000 | BASE_ADDRESS_MODIFY);
422 OUT_BATCH(batch, 0xFFFF0000 | BASE_ADDRESS_MODIFY);
424 /* Bindless surface state base address */
425 OUT_BATCH(batch, 0 | BASE_ADDRESS_MODIFY);
427 OUT_BATCH(batch, 0xfffff000);
429 ADVANCE_BATCH(batch);
433 gen9_pp_end_pipeline(VADriverContextP ctx,
434 struct i965_post_processing_context *pp_context)
436 struct intel_batchbuffer *batch = pp_context->batch;
438 BEGIN_BATCH(batch, 1);
440 CMD_PIPELINE_SELECT |
441 PIPELINE_SELECT_MEDIA |
442 GEN9_FORCE_MEDIA_AWAKE_OFF |
443 GEN9_MEDIA_DOP_GATE_ON |
444 GEN9_PIPELINE_SELECTION_MASK |
445 GEN9_MEDIA_DOP_GATE_MASK |
446 GEN9_FORCE_MEDIA_AWAKE_MASK);
447 ADVANCE_BATCH(batch);
451 gen9_pp_pipeline_setup(VADriverContextP ctx,
452 struct i965_post_processing_context *pp_context)
454 struct intel_batchbuffer *batch = pp_context->batch;
456 intel_batchbuffer_start_atomic(batch, 0x1000);
457 intel_batchbuffer_emit_mi_flush(batch);
458 gen9_pp_pipeline_select(ctx, pp_context);
459 gen9_pp_state_base_address(ctx, pp_context);
460 gen8_pp_vfe_state(ctx, pp_context);
461 gen8_pp_curbe_load(ctx, pp_context);
462 gen8_interface_descriptor_load(ctx, pp_context);
463 gen8_pp_object_walker(ctx, pp_context);
464 gen9_pp_end_pipeline(ctx, pp_context);
465 intel_batchbuffer_end_atomic(batch);
469 gen9_post_processing(VADriverContextP ctx,
470 struct i965_post_processing_context *pp_context,
471 const struct i965_surface *src_surface,
472 const VARectangle *src_rect,
473 struct i965_surface *dst_surface,
474 const VARectangle *dst_rect,
480 va_status = gen8_pp_initialize(ctx, pp_context,
488 if (va_status == VA_STATUS_SUCCESS) {
489 gen8_pp_states_setup(ctx, pp_context);
490 gen9_pp_pipeline_setup(ctx, pp_context);
497 gen9_vpp_scaling_sample_state(VADriverContextP ctx,
498 struct i965_gpe_context *gpe_context,
499 VARectangle *src_rect,
500 VARectangle *dst_rect)
502 struct gen8_sampler_state *sampler_state;
504 if (gpe_context == NULL || !src_rect || !dst_rect)
506 dri_bo_map(gpe_context->sampler.bo, 1);
508 if (gpe_context->sampler.bo->virtual == NULL)
511 assert(gpe_context->sampler.bo->virtual);
513 sampler_state = (struct gen8_sampler_state *)
514 (gpe_context->sampler.bo->virtual + gpe_context->sampler.offset);
516 memset(sampler_state, 0, sizeof(*sampler_state));
518 if ((src_rect->width == dst_rect->width) &&
519 (src_rect->height == dst_rect->height)) {
520 sampler_state->ss0.min_filter = I965_MAPFILTER_NEAREST;
521 sampler_state->ss0.mag_filter = I965_MAPFILTER_NEAREST;
523 sampler_state->ss0.min_filter = I965_MAPFILTER_LINEAR;
524 sampler_state->ss0.mag_filter = I965_MAPFILTER_LINEAR;
527 sampler_state->ss3.r_wrap_mode = I965_TEXCOORDMODE_CLAMP;
528 sampler_state->ss3.s_wrap_mode = I965_TEXCOORDMODE_CLAMP;
529 sampler_state->ss3.t_wrap_mode = I965_TEXCOORDMODE_CLAMP;
531 dri_bo_unmap(gpe_context->sampler.bo);
535 gen9_post_processing_context_init(VADriverContextP ctx,
537 struct intel_batchbuffer *batch)
539 struct i965_driver_data *i965 = i965_driver_data(ctx);
540 struct i965_post_processing_context *pp_context = data;
541 struct i965_gpe_context *gpe_context;
543 gen8_post_processing_context_common_init(ctx, data, pp_modules_gen9, ARRAY_ELEMS(pp_modules_gen9), batch);
544 avs_init_state(&pp_context->pp_avs_context.state, &gen9_avs_config);
546 pp_context->intel_post_processing = gen9_post_processing;
548 gpe_context = &pp_context->scaling_gpe_context;
549 gen8_gpe_load_kernels(ctx, gpe_context, pp_common_scaling_gen9, ARRAY_ELEMS(pp_common_scaling_gen9));
550 gpe_context->idrt.entry_size = ALIGN(sizeof(struct gen8_interface_descriptor_data), 64);
551 gpe_context->idrt.max_entries = ALIGN(ARRAY_ELEMS(pp_common_scaling_gen9), 2);
552 gpe_context->sampler.entry_size = ALIGN(sizeof(struct gen8_sampler_state), 64);
553 gpe_context->sampler.max_entries = 1;
554 gpe_context->curbe.length = ALIGN(sizeof(struct scaling_input_parameter), 64);
556 gpe_context->surface_state_binding_table.max_entries = MAX_SCALING_SURFACES;
557 gpe_context->surface_state_binding_table.binding_table_offset = 0;
558 gpe_context->surface_state_binding_table.surface_state_offset = ALIGN(MAX_SCALING_SURFACES * 4, 64);
559 gpe_context->surface_state_binding_table.length = ALIGN(MAX_SCALING_SURFACES * 4, 64) + ALIGN(MAX_SCALING_SURFACES * SURFACE_STATE_PADDED_SIZE_GEN9, 64);
561 if (i965->intel.eu_total > 0) {
562 gpe_context->vfe_state.max_num_threads = i965->intel.eu_total * 6;
564 if (i965->intel.has_bsd2)
565 gpe_context->vfe_state.max_num_threads = 300;
567 gpe_context->vfe_state.max_num_threads = 60;
570 gpe_context->vfe_state.curbe_allocation_size = 37;
571 gpe_context->vfe_state.urb_entry_size = 16;
572 gpe_context->vfe_state.num_urb_entries = 127;
573 gpe_context->vfe_state.gpgpu_mode = 0;
575 gen8_gpe_context_init(ctx, gpe_context);
576 pp_context->scaling_gpe_context_initialized |= (VPPGPE_8BIT_8BIT | VPPGPE_10BIT_10BIT | VPPGPE_10BIT_8BIT | VPPGPE_8BIT_420_RGB32);
582 gen9_add_dri_buffer_2d_gpe_surface(VADriverContextP ctx,
583 struct i965_gpe_context *gpe_context,
585 unsigned int bo_offset,
589 int is_media_block_rw,
594 struct i965_gpe_resource gpe_resource;
595 struct i965_gpe_surface gpe_surface;
597 i965_dri_object_to_2d_gpe_resource(&gpe_resource, bo, width, height, pitch);
598 memset(&gpe_surface, 0, sizeof(gpe_surface));
599 gpe_surface.gpe_resource = &gpe_resource;
600 gpe_surface.is_2d_surface = 1;
601 gpe_surface.is_media_block_rw = !!is_media_block_rw;
602 gpe_surface.cacheability_control = DEFAULT_MOCS;
603 gpe_surface.format = format;
604 gpe_surface.is_override_offset = 1;
605 gpe_surface.offset = bo_offset;
606 gpe_surface.is_16bpp = is_16bit;
608 gen9_gpe_context_add_surface(gpe_context, &gpe_surface, index);
610 i965_free_gpe_resource(&gpe_resource);
614 gen9_run_kernel_media_object_walker(VADriverContextP ctx,
615 struct intel_batchbuffer *batch,
616 struct i965_gpe_context *gpe_context,
617 struct gpe_media_object_walker_parameter *param)
619 if (!batch || !gpe_context || !param)
622 intel_batchbuffer_start_atomic(batch, 0x1000);
624 intel_batchbuffer_emit_mi_flush(batch);
626 gen9_gpe_pipeline_setup(ctx, gpe_context, batch);
627 gen8_gpe_media_object_walker(ctx, gpe_context, batch, param);
628 gen8_gpe_media_state_flush(ctx, gpe_context, batch);
630 gen9_gpe_pipeline_end(ctx, gpe_context, batch);
632 intel_batchbuffer_end_atomic(batch);
634 intel_batchbuffer_flush(batch);
639 gen9_gpe_context_p010_scaling_curbe(VADriverContextP ctx,
640 struct i965_gpe_context *gpe_context,
641 VARectangle *src_rect,
642 struct i965_surface *src_surface,
643 VARectangle *dst_rect,
644 struct i965_surface *dst_surface)
646 struct scaling_input_parameter *scaling_curbe;
647 float src_width, src_height;
651 if ((gpe_context == NULL) ||
652 (src_rect == NULL) || (src_surface == NULL) ||
653 (dst_rect == NULL) || (dst_surface == NULL))
656 scaling_curbe = i965_gpe_context_map_curbe(gpe_context);
661 memset(scaling_curbe, 0, sizeof(struct scaling_input_parameter));
663 scaling_curbe->bti_input = BTI_SCALING_INPUT_Y;
664 scaling_curbe->bti_output = BTI_SCALING_OUTPUT_Y;
666 /* As the src_rect/dst_rect is already checked, it is skipped.*/
667 scaling_curbe->x_dst = dst_rect->x;
668 scaling_curbe->y_dst = dst_rect->y;
670 src_width = src_rect->x + src_rect->width;
671 src_height = src_rect->y + src_rect->height;
673 scaling_curbe->inv_width = 1 / src_width;
674 scaling_curbe->inv_height = 1 / src_height;
676 coeff = (float)(src_rect->width) / dst_rect->width;
677 scaling_curbe->x_factor = coeff / src_width;
678 scaling_curbe->x_orig = (float)(src_rect->x) / src_width;
680 coeff = (float)(src_rect->height) / dst_rect->height;
681 scaling_curbe->y_factor = coeff / src_height;
682 scaling_curbe->y_orig = (float)(src_rect->y) / src_height;
684 fourcc = pp_get_surface_fourcc(ctx, src_surface);
685 if (fourcc == VA_FOURCC_P010) {
686 scaling_curbe->dw2.src_packed = 1;
687 scaling_curbe->dw2.src_msb = 1;
689 /* I010 will use LSB */
691 fourcc = pp_get_surface_fourcc(ctx, dst_surface);
693 if (fourcc == VA_FOURCC_P010) {
694 scaling_curbe->dw2.dst_packed = 1;
695 scaling_curbe->dw2.dst_msb = 1;
697 /* I010 will use LSB */
699 i965_gpe_context_unmap_curbe(gpe_context);
703 gen9_pp_context_get_surface_conf(VADriverContextP ctx,
704 struct i965_surface *surface,
712 if (!rect || !surface || !width || !height || !pitch || !bo_offset)
715 if (surface->base == NULL)
718 fourcc = pp_get_surface_fourcc(ctx, surface);
719 if (surface->type == I965_SURFACE_TYPE_SURFACE) {
720 struct object_surface *obj_surface;
722 obj_surface = (struct object_surface *)surface->base;
723 width[0] = MIN(rect->x + rect->width, obj_surface->orig_width);
724 height[0] = MIN(rect->y + rect->height, obj_surface->orig_height);
725 pitch[0] = obj_surface->width;
728 if (fourcc == VA_FOURCC_RGBX ||
729 fourcc == VA_FOURCC_RGBA ||
730 fourcc == VA_FOURCC_BGRX ||
731 fourcc == VA_FOURCC_BGRA) {
732 /* nothing to do here */
733 } else if (fourcc == VA_FOURCC_P010 || fourcc == VA_FOURCC_NV12) {
734 width[1] = width[0] / 2;
735 height[1] = height[0] / 2;
736 pitch[1] = obj_surface->cb_cr_pitch;
737 bo_offset[1] = obj_surface->width * obj_surface->y_cb_offset;
738 } else if (fourcc == VA_FOURCC_YUY2 || fourcc == VA_FOURCC_UYVY) {
739 /* nothing to do here */
741 width[1] = width[0] / 2;
742 height[1] = height[0] / 2;
743 pitch[1] = obj_surface->cb_cr_pitch;
744 bo_offset[1] = obj_surface->width * obj_surface->y_cb_offset;
745 width[2] = width[0] / 2;
746 height[2] = height[0] / 2;
747 pitch[2] = obj_surface->cb_cr_pitch;
748 bo_offset[2] = obj_surface->width * obj_surface->y_cr_offset;
752 struct object_image *obj_image;
754 obj_image = (struct object_image *)surface->base;
756 width[0] = MIN(rect->x + rect->width, obj_image->image.width);
757 height[0] = MIN(rect->y + rect->height, obj_image->image.height);
758 pitch[0] = obj_image->image.pitches[0];
759 bo_offset[0] = obj_image->image.offsets[0];
761 if (fourcc == VA_FOURCC_RGBX ||
762 fourcc == VA_FOURCC_RGBA ||
763 fourcc == VA_FOURCC_BGRX ||
764 fourcc == VA_FOURCC_BGRA) {
765 /* nothing to do here */
766 } else if (fourcc == VA_FOURCC_P010 || fourcc == VA_FOURCC_NV12) {
767 width[1] = width[0] / 2;
768 height[1] = height[0] / 2;
769 pitch[1] = obj_image->image.pitches[1];
770 bo_offset[1] = obj_image->image.offsets[1];
771 } else if (fourcc == VA_FOURCC_YUY2 || fourcc == VA_FOURCC_UYVY) {
772 /* nothing to do here */
776 if (fourcc == VA_FOURCC_YV12 || fourcc == VA_FOURCC_IMC1)
779 width[1] = width[0] / 2;
780 height[1] = height[0] / 2;
781 pitch[1] = obj_image->image.pitches[u];
782 bo_offset[1] = obj_image->image.offsets[u];
783 width[2] = width[0] / 2;
784 height[2] = height[0] / 2;
785 pitch[2] = obj_image->image.pitches[v];
786 bo_offset[2] = obj_image->image.offsets[v];
795 gen9_gpe_context_p010_scaling_surfaces(VADriverContextP ctx,
796 struct i965_gpe_context *gpe_context,
797 VARectangle *src_rect,
798 struct i965_surface *src_surface,
799 VARectangle *dst_rect,
800 struct i965_surface *dst_surface)
803 int width[3], height[3], pitch[3], bo_offset[3];
805 struct object_surface *obj_surface;
806 struct object_image *obj_image;
809 if ((gpe_context == NULL) ||
810 (src_rect == NULL) || (src_surface == NULL) ||
811 (dst_rect == NULL) || (dst_surface == NULL))
814 if (src_surface->base == NULL || dst_surface->base == NULL)
817 fourcc = pp_get_surface_fourcc(ctx, src_surface);
819 if (src_surface->type == I965_SURFACE_TYPE_SURFACE) {
820 obj_surface = (struct object_surface *)src_surface->base;
821 bo = obj_surface->bo;
823 obj_image = (struct object_image *)src_surface->base;
828 if (gen9_pp_context_get_surface_conf(ctx, src_surface, src_rect,
829 width, height, pitch,
831 bti = BTI_SCALING_INPUT_Y;
833 gen9_add_dri_buffer_2d_gpe_surface(ctx, gpe_context, bo,
837 I965_SURFACEFORMAT_R16_UNORM,
839 if (fourcc == VA_FOURCC_P010) {
840 gen9_add_dri_buffer_2d_gpe_surface(ctx, gpe_context, bo,
844 I965_SURFACEFORMAT_R16G16_UNORM,
847 gen9_add_dri_buffer_2d_gpe_surface(ctx, gpe_context, bo,
851 I965_SURFACEFORMAT_R16_UNORM,
854 gen9_add_dri_buffer_2d_gpe_surface(ctx, gpe_context, bo,
858 I965_SURFACEFORMAT_R16_UNORM,
863 fourcc = pp_get_surface_fourcc(ctx, dst_surface);
865 if (dst_surface->type == I965_SURFACE_TYPE_SURFACE) {
866 obj_surface = (struct object_surface *)dst_surface->base;
867 bo = obj_surface->bo;
869 obj_image = (struct object_image *)dst_surface->base;
873 if (gen9_pp_context_get_surface_conf(ctx, dst_surface, dst_rect,
874 width, height, pitch,
876 bti = BTI_SCALING_OUTPUT_Y;
878 gen9_add_dri_buffer_2d_gpe_surface(ctx, gpe_context, bo,
882 I965_SURFACEFORMAT_R16_UINT,
884 if (fourcc == VA_FOURCC_P010) {
885 gen9_add_dri_buffer_2d_gpe_surface(ctx, gpe_context, bo,
887 width[1] * 2, height[1],
889 I965_SURFACEFORMAT_R16_UINT,
892 gen9_add_dri_buffer_2d_gpe_surface(ctx, gpe_context, bo,
896 I965_SURFACEFORMAT_R16_UINT,
899 gen9_add_dri_buffer_2d_gpe_surface(ctx, gpe_context, bo,
903 I965_SURFACEFORMAT_R16_UINT,
912 gen9_p010_scaling_post_processing(
913 VADriverContextP ctx,
914 struct i965_post_processing_context *pp_context,
915 struct i965_surface *src_surface,
916 VARectangle *src_rect,
917 struct i965_surface *dst_surface,
918 VARectangle *dst_rect)
920 struct i965_gpe_context *gpe_context;
921 struct gpe_media_object_walker_parameter media_object_walker_param;
922 struct intel_vpp_kernel_walker_parameter kernel_walker_param;
924 if (!pp_context || !src_surface || !src_rect || !dst_surface || !dst_rect)
925 return VA_STATUS_ERROR_INVALID_PARAMETER;
927 if (!(pp_context->scaling_gpe_context_initialized & VPPGPE_10BIT_10BIT))
928 return VA_STATUS_ERROR_UNIMPLEMENTED;
930 gpe_context = &pp_context->scaling_gpe_context;
932 gen8_gpe_context_init(ctx, gpe_context);
933 gen9_vpp_scaling_sample_state(ctx, gpe_context, src_rect, dst_rect);
934 gen9_gpe_reset_binding_table(ctx, gpe_context);
935 gen9_gpe_context_p010_scaling_curbe(ctx, gpe_context,
936 src_rect, src_surface,
937 dst_rect, dst_surface);
939 gen9_gpe_context_p010_scaling_surfaces(ctx, gpe_context,
940 src_rect, src_surface,
941 dst_rect, dst_surface);
943 gen8_gpe_setup_interface_data(ctx, gpe_context);
945 memset(&kernel_walker_param, 0, sizeof(kernel_walker_param));
946 kernel_walker_param.resolution_x = ALIGN(dst_rect->width, 16) >> 4;
947 kernel_walker_param.resolution_y = ALIGN(dst_rect->height, 16) >> 4;
948 kernel_walker_param.no_dependency = 1;
950 intel_vpp_init_media_object_walker_parameter(&kernel_walker_param, &media_object_walker_param);
951 media_object_walker_param.interface_offset = 0;
952 gen9_run_kernel_media_object_walker(ctx, pp_context->batch,
954 &media_object_walker_param);
956 return VA_STATUS_SUCCESS;
960 gen9_gpe_context_yuv420p8_scaling_curbe(VADriverContextP ctx,
961 struct i965_gpe_context *gpe_context,
962 VARectangle *src_rect,
963 struct i965_surface *src_surface,
964 VARectangle *dst_rect,
965 struct i965_surface *dst_surface)
967 struct scaling_input_parameter *scaling_curbe;
968 float src_width, src_height;
972 if ((gpe_context == NULL) ||
973 (src_rect == NULL) || (src_surface == NULL) ||
974 (dst_rect == NULL) || (dst_surface == NULL))
977 scaling_curbe = i965_gpe_context_map_curbe(gpe_context);
982 memset(scaling_curbe, 0, sizeof(struct scaling_input_parameter));
984 scaling_curbe->bti_input = BTI_SCALING_INPUT_Y;
985 scaling_curbe->bti_output = BTI_SCALING_OUTPUT_Y;
987 /* As the src_rect/dst_rect is already checked, it is skipped.*/
988 scaling_curbe->x_dst = dst_rect->x;
989 scaling_curbe->y_dst = dst_rect->y;
991 src_width = src_rect->x + src_rect->width;
992 src_height = src_rect->y + src_rect->height;
994 scaling_curbe->inv_width = 1 / src_width;
995 scaling_curbe->inv_height = 1 / src_height;
997 coeff = (float)(src_rect->width) / dst_rect->width;
998 scaling_curbe->x_factor = coeff / src_width;
999 scaling_curbe->x_orig = (float)(src_rect->x) / src_width;
1001 coeff = (float)(src_rect->height) / dst_rect->height;
1002 scaling_curbe->y_factor = coeff / src_height;
1003 scaling_curbe->y_orig = (float)(src_rect->y) / src_height;
1005 fourcc = pp_get_surface_fourcc(ctx, src_surface);
1006 if (fourcc == VA_FOURCC_NV12) {
1007 scaling_curbe->dw2.src_packed = 1;
1010 fourcc = pp_get_surface_fourcc(ctx, dst_surface);
1012 if (fourcc == VA_FOURCC_NV12) {
1013 scaling_curbe->dw2.dst_packed = 1;
1016 i965_gpe_context_unmap_curbe(gpe_context);
1020 gen9_gpe_context_yuv420p8_scaling_surfaces(VADriverContextP ctx,
1021 struct i965_gpe_context *gpe_context,
1022 VARectangle *src_rect,
1023 struct i965_surface *src_surface,
1024 VARectangle *dst_rect,
1025 struct i965_surface *dst_surface)
1027 unsigned int fourcc;
1028 int width[3], height[3], pitch[3], bo_offset[3];
1030 struct object_surface *obj_surface;
1031 struct object_image *obj_image;
1034 if ((gpe_context == NULL) ||
1035 (src_rect == NULL) || (src_surface == NULL) ||
1036 (dst_rect == NULL) || (dst_surface == NULL))
1039 if (src_surface->base == NULL || dst_surface->base == NULL)
1042 fourcc = pp_get_surface_fourcc(ctx, src_surface);
1044 if (src_surface->type == I965_SURFACE_TYPE_SURFACE) {
1045 obj_surface = (struct object_surface *)src_surface->base;
1046 bo = obj_surface->bo;
1048 obj_image = (struct object_image *)src_surface->base;
1053 if (gen9_pp_context_get_surface_conf(ctx, src_surface, src_rect,
1054 width, height, pitch,
1056 bti = BTI_SCALING_INPUT_Y;
1058 gen9_add_dri_buffer_2d_gpe_surface(ctx, gpe_context, bo,
1060 width[0], height[0],
1062 I965_SURFACEFORMAT_R8_UNORM,
1064 if (fourcc == VA_FOURCC_NV12) {
1065 gen9_add_dri_buffer_2d_gpe_surface(ctx, gpe_context, bo,
1067 width[1], height[1],
1069 I965_SURFACEFORMAT_R8G8_UNORM,
1072 gen9_add_dri_buffer_2d_gpe_surface(ctx, gpe_context, bo,
1074 width[1], height[1],
1076 I965_SURFACEFORMAT_R8_UNORM,
1079 gen9_add_dri_buffer_2d_gpe_surface(ctx, gpe_context, bo,
1081 width[2], height[2],
1083 I965_SURFACEFORMAT_R8_UNORM,
1088 fourcc = pp_get_surface_fourcc(ctx, dst_surface);
1090 if (dst_surface->type == I965_SURFACE_TYPE_SURFACE) {
1091 obj_surface = (struct object_surface *)dst_surface->base;
1092 bo = obj_surface->bo;
1094 obj_image = (struct object_image *)dst_surface->base;
1098 if (gen9_pp_context_get_surface_conf(ctx, dst_surface, dst_rect,
1099 width, height, pitch,
1101 bti = BTI_SCALING_OUTPUT_Y;
1103 gen9_add_dri_buffer_2d_gpe_surface(ctx, gpe_context, bo,
1105 width[0], height[0],
1107 I965_SURFACEFORMAT_R8_UINT,
1109 if (fourcc == VA_FOURCC_NV12) {
1110 gen9_add_dri_buffer_2d_gpe_surface(ctx, gpe_context, bo,
1112 width[1] * 2, height[1],
1114 I965_SURFACEFORMAT_R16_UINT,
1117 gen9_add_dri_buffer_2d_gpe_surface(ctx, gpe_context, bo,
1119 width[1], height[1],
1121 I965_SURFACEFORMAT_R8_UINT,
1124 gen9_add_dri_buffer_2d_gpe_surface(ctx, gpe_context, bo,
1126 width[2], height[2],
1128 I965_SURFACEFORMAT_R8_UINT,
1137 gen9_yuv420p8_scaling_post_processing(
1138 VADriverContextP ctx,
1139 struct i965_post_processing_context *pp_context,
1140 struct i965_surface *src_surface,
1141 VARectangle *src_rect,
1142 struct i965_surface *dst_surface,
1143 VARectangle *dst_rect)
1145 struct i965_gpe_context *gpe_context;
1146 struct gpe_media_object_walker_parameter media_object_walker_param;
1147 struct intel_vpp_kernel_walker_parameter kernel_walker_param;
1149 if (!pp_context || !src_surface || !src_rect || !dst_surface || !dst_rect)
1150 return VA_STATUS_ERROR_INVALID_PARAMETER;
1152 if (!(pp_context->scaling_gpe_context_initialized & VPPGPE_8BIT_8BIT))
1153 return VA_STATUS_ERROR_UNIMPLEMENTED;
1155 gpe_context = &pp_context->scaling_gpe_context;
1157 gen8_gpe_context_init(ctx, gpe_context);
1158 gen9_vpp_scaling_sample_state(ctx, gpe_context, src_rect, dst_rect);
1159 gen9_gpe_reset_binding_table(ctx, gpe_context);
1160 gen9_gpe_context_yuv420p8_scaling_curbe(ctx, gpe_context,
1161 src_rect, src_surface,
1162 dst_rect, dst_surface);
1164 gen9_gpe_context_yuv420p8_scaling_surfaces(ctx, gpe_context,
1165 src_rect, src_surface,
1166 dst_rect, dst_surface);
1168 gen8_gpe_setup_interface_data(ctx, gpe_context);
1170 memset(&kernel_walker_param, 0, sizeof(kernel_walker_param));
1171 kernel_walker_param.resolution_x = ALIGN(dst_rect->width, 16) >> 4;
1172 kernel_walker_param.resolution_y = ALIGN(dst_rect->height, 16) >> 4;
1173 kernel_walker_param.no_dependency = 1;
1175 intel_vpp_init_media_object_walker_parameter(&kernel_walker_param, &media_object_walker_param);
1176 media_object_walker_param.interface_offset = 1;
1177 gen9_run_kernel_media_object_walker(ctx, pp_context->batch,
1179 &media_object_walker_param);
1181 return VA_STATUS_SUCCESS;
1185 gen9_gpe_context_10bit_8bit_scaling_curbe(VADriverContextP ctx,
1186 struct i965_gpe_context *gpe_context,
1187 VARectangle *src_rect,
1188 struct i965_surface *src_surface,
1189 VARectangle *dst_rect,
1190 struct i965_surface *dst_surface)
1192 struct scaling_input_parameter *scaling_curbe;
1193 float src_width, src_height;
1195 unsigned int fourcc;
1196 int src_format = SRC_FORMAT_P010, dst_format = DST_FORMAT_YUY2;
1198 if ((gpe_context == NULL) ||
1199 (src_rect == NULL) || (src_surface == NULL) ||
1200 (dst_rect == NULL) || (dst_surface == NULL))
1203 scaling_curbe = i965_gpe_context_map_curbe(gpe_context);
1208 memset(scaling_curbe, 0, sizeof(struct scaling_input_parameter));
1210 scaling_curbe->bti_input = BTI_SCALING_INPUT_Y;
1211 scaling_curbe->bti_output = BTI_SCALING_OUTPUT_Y;
1213 /* As the src_rect/dst_rect is already checked, it is skipped.*/
1214 scaling_curbe->x_dst = dst_rect->x;
1215 scaling_curbe->y_dst = dst_rect->y;
1217 src_width = src_rect->x + src_rect->width;
1218 src_height = src_rect->y + src_rect->height;
1220 scaling_curbe->inv_width = 1 / src_width;
1221 scaling_curbe->inv_height = 1 / src_height;
1223 coeff = (float)(src_rect->width) / dst_rect->width;
1224 scaling_curbe->x_factor = coeff / src_width;
1225 scaling_curbe->x_orig = (float)(src_rect->x) / src_width;
1227 coeff = (float)(src_rect->height) / dst_rect->height;
1228 scaling_curbe->y_factor = coeff / src_height;
1229 scaling_curbe->y_orig = (float)(src_rect->y) / src_height;
1231 fourcc = pp_get_surface_fourcc(ctx, src_surface);
1234 case VA_FOURCC_P010:
1235 src_format = SRC_FORMAT_P010;
1238 case VA_FOURCC_I010:
1239 src_format = SRC_FORMAT_I010;
1246 fourcc = pp_get_surface_fourcc(ctx, dst_surface);
1249 case VA_FOURCC_YUY2:
1250 dst_format = DST_FORMAT_YUY2;
1253 case VA_FOURCC_UYVY:
1254 dst_format = DST_FORMAT_UYVY;
1257 case VA_FOURCC_NV12:
1258 dst_format = DST_FORMAT_NV12;
1261 case VA_FOURCC_I420:
1262 case VA_FOURCC_IMC3: /* pitch / base address is set via surface_state */
1263 dst_format = DST_FORMAT_I420;
1266 case VA_FOURCC_YV12:
1267 case VA_FOURCC_IMC1: /* pitch / base address is set via surface_state */
1268 dst_format = DST_FORMAT_YV12;
1275 scaling_curbe->dw2.src_format = src_format;
1276 scaling_curbe->dw2.dst_format = dst_format;
1278 i965_gpe_context_unmap_curbe(gpe_context);
1282 gen9_gpe_context_10bit_8bit_scaling_surfaces(VADriverContextP ctx,
1283 struct i965_gpe_context *gpe_context,
1284 VARectangle *src_rect,
1285 struct i965_surface *src_surface,
1286 VARectangle *dst_rect,
1287 struct i965_surface *dst_surface)
1289 unsigned int fourcc;
1290 int width[3], height[3], pitch[3], bo_offset[3];
1292 struct object_surface *obj_surface;
1293 struct object_image *obj_image;
1296 if ((gpe_context == NULL) ||
1297 (src_rect == NULL) || (src_surface == NULL) ||
1298 (dst_rect == NULL) || (dst_surface == NULL))
1301 if (src_surface->base == NULL || dst_surface->base == NULL)
1304 fourcc = pp_get_surface_fourcc(ctx, src_surface);
1306 if (src_surface->type == I965_SURFACE_TYPE_SURFACE) {
1307 obj_surface = (struct object_surface *)src_surface->base;
1308 bo = obj_surface->bo;
1310 obj_image = (struct object_image *)src_surface->base;
1315 if (gen9_pp_context_get_surface_conf(ctx, src_surface, src_rect,
1316 width, height, pitch,
1318 bti = BTI_SCALING_INPUT_Y;
1320 gen9_add_dri_buffer_2d_gpe_surface(ctx, gpe_context, bo,
1322 width[0], height[0],
1324 I965_SURFACEFORMAT_R16_UNORM,
1326 if (fourcc == VA_FOURCC_P010) {
1327 gen9_add_dri_buffer_2d_gpe_surface(ctx, gpe_context, bo,
1329 width[1], height[1],
1331 I965_SURFACEFORMAT_R16G16_UNORM,
1334 gen9_add_dri_buffer_2d_gpe_surface(ctx, gpe_context, bo,
1336 width[1], height[1],
1338 I965_SURFACEFORMAT_R16_UNORM,
1341 gen9_add_dri_buffer_2d_gpe_surface(ctx, gpe_context, bo,
1343 width[2], height[2],
1345 I965_SURFACEFORMAT_R16_UNORM,
1350 fourcc = pp_get_surface_fourcc(ctx, dst_surface);
1352 if (dst_surface->type == I965_SURFACE_TYPE_SURFACE) {
1353 obj_surface = (struct object_surface *)dst_surface->base;
1354 bo = obj_surface->bo;
1356 obj_image = (struct object_image *)dst_surface->base;
1360 if (gen9_pp_context_get_surface_conf(ctx, dst_surface, dst_rect,
1361 width, height, pitch,
1363 bti = BTI_SCALING_OUTPUT_Y;
1364 /* Output surface */
1366 if (fourcc == VA_FOURCC_YUY2 || fourcc == VA_FOURCC_UYVY) {
1367 gen9_add_dri_buffer_2d_gpe_surface(ctx, gpe_context, bo,
1369 width[0] * 2, height[0],
1371 I965_SURFACEFORMAT_R8_UINT,
1374 gen9_add_dri_buffer_2d_gpe_surface(ctx, gpe_context, bo,
1376 width[0], height[0],
1378 I965_SURFACEFORMAT_R8_UINT,
1381 if (fourcc == VA_FOURCC_NV12) {
1382 gen9_add_dri_buffer_2d_gpe_surface(ctx, gpe_context, bo,
1384 width[1] * 2, height[1],
1386 I965_SURFACEFORMAT_R16_UINT,
1389 gen9_add_dri_buffer_2d_gpe_surface(ctx, gpe_context, bo,
1391 width[1], height[1],
1393 I965_SURFACEFORMAT_R8_UINT,
1396 gen9_add_dri_buffer_2d_gpe_surface(ctx, gpe_context, bo,
1398 width[2], height[2],
1400 I965_SURFACEFORMAT_R8_UINT,
1408 gen9_10bit_8bit_scaling_post_processing(VADriverContextP ctx,
1409 struct i965_post_processing_context *pp_context,
1410 struct i965_surface *src_surface,
1411 VARectangle *src_rect,
1412 struct i965_surface *dst_surface,
1413 VARectangle *dst_rect)
1415 struct i965_gpe_context *gpe_context;
1416 struct gpe_media_object_walker_parameter media_object_walker_param;
1417 struct intel_vpp_kernel_walker_parameter kernel_walker_param;
1419 if (!pp_context || !src_surface || !src_rect || !dst_surface || !dst_rect)
1420 return VA_STATUS_ERROR_INVALID_PARAMETER;
1422 if (!(pp_context->scaling_gpe_context_initialized & VPPGPE_10BIT_10BIT))
1423 return VA_STATUS_ERROR_UNIMPLEMENTED;
1425 gpe_context = &pp_context->scaling_gpe_context;
1427 gen8_gpe_context_init(ctx, gpe_context);
1428 gen9_vpp_scaling_sample_state(ctx, gpe_context, src_rect, dst_rect);
1429 gen9_gpe_reset_binding_table(ctx, gpe_context);
1430 gen9_gpe_context_10bit_8bit_scaling_curbe(ctx, gpe_context,
1431 src_rect, src_surface,
1432 dst_rect, dst_surface);
1434 gen9_gpe_context_10bit_8bit_scaling_surfaces(ctx, gpe_context,
1435 src_rect, src_surface,
1436 dst_rect, dst_surface);
1438 gen8_gpe_setup_interface_data(ctx, gpe_context);
1440 memset(&kernel_walker_param, 0, sizeof(kernel_walker_param));
1441 kernel_walker_param.resolution_x = ALIGN(dst_rect->width, 16) >> 4;
1442 kernel_walker_param.resolution_y = ALIGN(dst_rect->height, 16) >> 4;
1443 kernel_walker_param.no_dependency = 1;
1445 intel_vpp_init_media_object_walker_parameter(&kernel_walker_param, &media_object_walker_param);
1446 media_object_walker_param.interface_offset = 2;
1447 gen9_run_kernel_media_object_walker(ctx, pp_context->batch,
1449 &media_object_walker_param);
1451 return VA_STATUS_SUCCESS;
1455 gen9_gpe_context_8bit_420_rgb32_scaling_curbe(VADriverContextP ctx,
1456 struct i965_gpe_context *gpe_context,
1457 VARectangle *src_rect,
1458 struct i965_surface *src_surface,
1459 VARectangle *dst_rect,
1460 struct i965_surface *dst_surface)
1462 struct scaling_input_parameter *scaling_curbe;
1463 float src_width, src_height;
1465 unsigned int fourcc;
1466 int src_format = SRC_FORMAT_I420, dst_format = DST_FORMAT_RGBX;
1467 const float * yuv_to_rgb_coefs;
1468 size_t yuv_to_rgb_coefs_size;
1470 if ((gpe_context == NULL) ||
1471 (src_rect == NULL) || (src_surface == NULL) ||
1472 (dst_rect == NULL) || (dst_surface == NULL))
1475 scaling_curbe = i965_gpe_context_map_curbe(gpe_context);
1480 memset(scaling_curbe, 0, sizeof(struct scaling_input_parameter));
1482 scaling_curbe->bti_input = BTI_SCALING_INPUT_Y;
1483 scaling_curbe->bti_output = BTI_SCALING_OUTPUT_Y;
1485 /* As the src_rect/dst_rect is already checked, it is skipped.*/
1486 scaling_curbe->x_dst = dst_rect->x;
1487 scaling_curbe->y_dst = dst_rect->y;
1489 src_width = src_rect->x + src_rect->width;
1490 src_height = src_rect->y + src_rect->height;
1492 scaling_curbe->inv_width = 1 / src_width;
1493 scaling_curbe->inv_height = 1 / src_height;
1495 coeff = (float)(src_rect->width) / dst_rect->width;
1496 scaling_curbe->x_factor = coeff / src_width;
1497 scaling_curbe->x_orig = (float)(src_rect->x) / src_width;
1499 coeff = (float)(src_rect->height) / dst_rect->height;
1500 scaling_curbe->y_factor = coeff / src_height;
1501 scaling_curbe->y_orig = (float)(src_rect->y) / src_height;
1503 fourcc = pp_get_surface_fourcc(ctx, src_surface);
1506 case VA_FOURCC_I420:
1507 case VA_FOURCC_IMC3: /* pitch / base address is set via surface_state */
1508 src_format = SRC_FORMAT_I420;
1511 case VA_FOURCC_NV12:
1512 src_format = SRC_FORMAT_NV12;
1515 case VA_FOURCC_YV12:
1516 case VA_FOURCC_IMC1: /* pitch / base address is set via surface_state */
1517 src_format = SRC_FORMAT_YV12;
1524 fourcc = pp_get_surface_fourcc(ctx, dst_surface);
1527 case VA_FOURCC_RGBX:
1528 dst_format = DST_FORMAT_RGBX;
1531 case VA_FOURCC_RGBA:
1532 dst_format = DST_FORMAT_RGBA;
1535 case VA_FOURCC_BGRX:
1536 dst_format = DST_FORMAT_BGRX;
1539 case VA_FOURCC_BGRA:
1540 dst_format = DST_FORMAT_BGRA;
1547 scaling_curbe->dw2.src_format = src_format;
1548 scaling_curbe->dw2.dst_format = dst_format;
1550 yuv_to_rgb_coefs = i915_color_standard_to_coefs(i915_filter_to_color_standard(src_surface->flags & VA_SRC_COLOR_MASK), &yuv_to_rgb_coefs_size);
1551 memcpy(&scaling_curbe->coef_ry, yuv_to_rgb_coefs, yuv_to_rgb_coefs_size);
1553 i965_gpe_context_unmap_curbe(gpe_context);
1557 gen9_gpe_context_8bit_420_rgb32_scaling_surfaces(VADriverContextP ctx,
1558 struct i965_gpe_context *gpe_context,
1559 VARectangle *src_rect,
1560 struct i965_surface *src_surface,
1561 VARectangle *dst_rect,
1562 struct i965_surface *dst_surface)
1564 unsigned int fourcc;
1565 int width[3], height[3], pitch[3], bo_offset[3];
1567 struct object_surface *obj_surface;
1568 struct object_image *obj_image;
1571 if ((gpe_context == NULL) ||
1572 (src_rect == NULL) || (src_surface == NULL) ||
1573 (dst_rect == NULL) || (dst_surface == NULL))
1576 if (src_surface->base == NULL || dst_surface->base == NULL)
1579 fourcc = pp_get_surface_fourcc(ctx, src_surface);
1581 if (src_surface->type == I965_SURFACE_TYPE_SURFACE) {
1582 obj_surface = (struct object_surface *)src_surface->base;
1583 bo = obj_surface->bo;
1585 obj_image = (struct object_image *)src_surface->base;
1589 if (gen9_pp_context_get_surface_conf(ctx, src_surface, src_rect,
1590 width, height, pitch,
1593 bti = BTI_SCALING_INPUT_Y;
1594 gen9_add_dri_buffer_2d_gpe_surface(ctx, gpe_context, bo,
1596 width[0], height[0],
1598 I965_SURFACEFORMAT_R8_UNORM,
1601 if (fourcc == VA_FOURCC_NV12) {
1602 gen9_add_dri_buffer_2d_gpe_surface(ctx, gpe_context, bo,
1604 width[1], height[1],
1606 I965_SURFACEFORMAT_R8G8_UNORM,
1609 /* The corresponding shader handles U, V plane in order */
1610 gen9_add_dri_buffer_2d_gpe_surface(ctx, gpe_context, bo,
1612 width[1], height[1],
1614 I965_SURFACEFORMAT_R8_UNORM,
1617 gen9_add_dri_buffer_2d_gpe_surface(ctx, gpe_context, bo,
1619 width[2], height[2],
1621 I965_SURFACEFORMAT_R8_UNORM,
1626 fourcc = pp_get_surface_fourcc(ctx, dst_surface);
1628 if (dst_surface->type == I965_SURFACE_TYPE_SURFACE) {
1629 obj_surface = (struct object_surface *)dst_surface->base;
1630 bo = obj_surface->bo;
1632 obj_image = (struct object_image *)dst_surface->base;
1636 if (gen9_pp_context_get_surface_conf(ctx, dst_surface, dst_rect,
1637 width, height, pitch,
1639 assert(fourcc == VA_FOURCC_RGBX ||
1640 fourcc == VA_FOURCC_RGBA ||
1641 fourcc == VA_FOURCC_BGRX ||
1642 fourcc == VA_FOURCC_BGRA);
1643 assert(width[0] * 4 <= pitch[0]);
1645 /* output surface */
1646 bti = BTI_SCALING_OUTPUT_Y;
1647 gen9_add_dri_buffer_2d_gpe_surface(ctx, gpe_context, bo,
1649 width[0] * 4, height[0],
1651 I965_SURFACEFORMAT_R8_UINT,
1657 gen9_8bit_420_rgb32_scaling_post_processing(VADriverContextP ctx,
1658 struct i965_post_processing_context *pp_context,
1659 struct i965_surface *src_surface,
1660 VARectangle *src_rect,
1661 struct i965_surface *dst_surface,
1662 VARectangle *dst_rect)
1664 struct i965_gpe_context *gpe_context;
1665 struct gpe_media_object_walker_parameter media_object_walker_param;
1666 struct intel_vpp_kernel_walker_parameter kernel_walker_param;
1668 if (!pp_context || !src_surface || !src_rect || !dst_surface || !dst_rect)
1669 return VA_STATUS_ERROR_INVALID_PARAMETER;
1671 if (!(pp_context->scaling_gpe_context_initialized & VPPGPE_8BIT_420_RGB32))
1672 return VA_STATUS_ERROR_UNIMPLEMENTED;
1674 gpe_context = &pp_context->scaling_gpe_context;
1676 gen8_gpe_context_init(ctx, gpe_context);
1677 gen9_vpp_scaling_sample_state(ctx, gpe_context, src_rect, dst_rect);
1678 gen9_gpe_reset_binding_table(ctx, gpe_context);
1679 gen9_gpe_context_8bit_420_rgb32_scaling_curbe(ctx, gpe_context,
1680 src_rect, src_surface,
1681 dst_rect, dst_surface);
1683 gen9_gpe_context_8bit_420_rgb32_scaling_surfaces(ctx, gpe_context,
1684 src_rect, src_surface,
1685 dst_rect, dst_surface);
1687 gen8_gpe_setup_interface_data(ctx, gpe_context);
1689 memset(&kernel_walker_param, 0, sizeof(kernel_walker_param));
1690 kernel_walker_param.resolution_x = ALIGN(dst_rect->width, 16) >> 4;
1691 kernel_walker_param.resolution_y = ALIGN(dst_rect->height, 16) >> 4;
1692 kernel_walker_param.no_dependency = 1;
1694 intel_vpp_init_media_object_walker_parameter(&kernel_walker_param, &media_object_walker_param);
1695 media_object_walker_param.interface_offset = 3;
1696 gen9_run_kernel_media_object_walker(ctx, pp_context->batch,
1698 &media_object_walker_param);
1700 return VA_STATUS_SUCCESS;