From e4f2b5d5af9548f950b20b4699a2f751ca2146dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Tue, 29 May 2018 21:33:10 +0300 Subject: sna/video: Add XV_COLORSPACE attribute for the textured Xv adaptor MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Allow the client to select between BT.601 and BT.709 via the XV_COLORSPACE port attribute with the textured Xv adaptor as well. Since the BT.601 coefficients are currently hardcoded in the yuv->rgb shader, let's just add a mostly duplicated shader with hardcoded BT.709 coefficients instead. Not the most elegant solution but avoids having to touch any state setup etc. Signed-off-by: Ville Syrjälä Reviewed-by: Chris Wilson Signed-off-by: Chris Wilson --- src/render_program/Makefile.am | 11 +++ src/render_program/exa_wm_yuv_rgb_bt601.g4a | 32 ++++-- src/render_program/exa_wm_yuv_rgb_bt601.g8a | 31 ++++-- src/render_program/exa_wm_yuv_rgb_bt709.g4a | 111 +++++++++++++++++++++ src/render_program/exa_wm_yuv_rgb_bt709.g4b | 12 +++ src/render_program/exa_wm_yuv_rgb_bt709.g4b.gen5 | 12 +++ src/render_program/exa_wm_yuv_rgb_bt709.g5a | 1 + src/render_program/exa_wm_yuv_rgb_bt709.g5b | 12 +++ src/render_program/exa_wm_yuv_rgb_bt709.g6a | 1 + src/render_program/exa_wm_yuv_rgb_bt709.g6b | 12 +++ src/render_program/exa_wm_yuv_rgb_bt709.g7a | 1 + src/render_program/exa_wm_yuv_rgb_bt709.g7b | 12 +++ src/render_program/exa_wm_yuv_rgb_bt709.g8a | 118 +++++++++++++++++++++++ src/render_program/exa_wm_yuv_rgb_bt709.g8b | 19 ++++ src/sna/gen4_render.c | 67 +++++++++++-- src/sna/gen4_render.h | 11 ++- src/sna/gen5_render.c | 67 +++++++++++-- src/sna/gen5_render.h | 11 ++- src/sna/gen6_render.c | 67 ++++++++++--- src/sna/gen7_render.c | 53 +++++++--- src/sna/gen8_render.c | 53 +++++++--- src/sna/gen9_render.c | 53 +++++++--- src/sna/sna_render.h | 44 ++++++--- src/sna/sna_video_textured.c | 12 ++- 24 files changed, 724 insertions(+), 99 deletions(-) create mode 100644 src/render_program/exa_wm_yuv_rgb_bt709.g4a create mode 100644 src/render_program/exa_wm_yuv_rgb_bt709.g4b create mode 100644 src/render_program/exa_wm_yuv_rgb_bt709.g4b.gen5 create mode 120000 src/render_program/exa_wm_yuv_rgb_bt709.g5a create mode 100644 src/render_program/exa_wm_yuv_rgb_bt709.g5b create mode 120000 src/render_program/exa_wm_yuv_rgb_bt709.g6a create mode 100644 src/render_program/exa_wm_yuv_rgb_bt709.g6b create mode 120000 src/render_program/exa_wm_yuv_rgb_bt709.g7a create mode 100644 src/render_program/exa_wm_yuv_rgb_bt709.g7b create mode 100644 src/render_program/exa_wm_yuv_rgb_bt709.g8a create mode 100644 src/render_program/exa_wm_yuv_rgb_bt709.g8b diff --git a/src/render_program/Makefile.am b/src/render_program/Makefile.am index 44936734..dc58138f 100644 --- a/src/render_program/Makefile.am +++ b/src/render_program/Makefile.am @@ -16,6 +16,7 @@ INTEL_G4A = \ exa_wm_ca_srcalpha.g4a \ exa_wm_write.g4a \ exa_wm_yuv_rgb_bt601.g4a \ + exa_wm_yuv_rgb_bt709.g4a \ exa_wm_xy.g4a \ $(NULL) @@ -46,6 +47,7 @@ INTEL_G4B = \ exa_wm_ca_srcalpha.g4b \ exa_wm_write.g4b \ exa_wm_yuv_rgb_bt601.g4b \ + exa_wm_yuv_rgb_bt709.g4b \ exa_wm_xy.g4b \ $(NULL) @@ -68,6 +70,7 @@ INTEL_G4B_GEN5 = \ exa_wm_ca_srcalpha.g4b.gen5 \ exa_wm_write.g4b.gen5 \ exa_wm_yuv_rgb_bt601.g4b.gen5 \ + exa_wm_yuv_rgb_bt709.g4b.gen5 \ exa_wm_xy.g4b.gen5 \ $(NULL) @@ -89,6 +92,7 @@ INTEL_G5A = \ exa_wm_ca_srcalpha.g5a \ exa_wm_write.g5a \ exa_wm_yuv_rgb_bt601.g5a \ + exa_wm_yuv_rgb_bt709.g5a \ exa_wm_xy.g5a \ $(NULL) @@ -110,6 +114,7 @@ INTEL_G5B = \ exa_wm_ca_srcalpha.g5b \ exa_wm_write.g5b \ exa_wm_yuv_rgb_bt601.g5b \ + exa_wm_yuv_rgb_bt709.g5b \ exa_wm_xy.g5b \ $(NULL) @@ -134,6 +139,7 @@ INTEL_G6A = \ exa_wm_noca.g6a \ exa_wm_write.g6a \ exa_wm_yuv_rgb_bt601.g6a \ + exa_wm_yuv_rgb_bt709.g6a \ $(NULL) INTEL_G6B = \ @@ -152,6 +158,7 @@ INTEL_G6B = \ exa_wm_noca.g6b \ exa_wm_write.g6b \ exa_wm_yuv_rgb_bt601.g6b \ + exa_wm_yuv_rgb_bt709.g6b \ $(NULL) INTEL_G7A = \ @@ -167,6 +174,7 @@ INTEL_G7A = \ exa_wm_src_sample_planar.g7a \ exa_wm_write.g7a \ exa_wm_yuv_rgb_bt601.g7a \ + exa_wm_yuv_rgb_bt709.g7a \ $(NULL) INTEL_G7B = \ @@ -182,6 +190,7 @@ INTEL_G7B = \ exa_wm_src_sample_planar.g7b \ exa_wm_write.g7b \ exa_wm_yuv_rgb_bt601.g7b \ + exa_wm_yuv_rgb_bt709.g7b \ $(NULL) INTEL_G8A = \ @@ -191,6 +200,7 @@ INTEL_G8A = \ exa_wm_src_sample_planar.g8a \ exa_wm_write.g8a \ exa_wm_yuv_rgb_bt601.g8a \ + exa_wm_yuv_rgb_bt709.g8a \ $(NULL) INTEL_G8B = \ @@ -200,6 +210,7 @@ INTEL_G8B = \ exa_wm_src_sample_planar.g8b \ exa_wm_write.g8b \ exa_wm_yuv_rgb_bt601.g8b \ + exa_wm_yuv_rgb_bt709.g8b \ $(NULL) EXTRA_DIST = \ diff --git a/src/render_program/exa_wm_yuv_rgb_bt601.g4a b/src/render_program/exa_wm_yuv_rgb_bt601.g4a index 4fb2576a..7bc8dd14 100644 --- a/src/render_program/exa_wm_yuv_rgb_bt601.g4a +++ b/src/render_program/exa_wm_yuv_rgb_bt601.g4a @@ -55,14 +55,24 @@ define(`Cbn_01', `mask_sample_b_01') define(`Cbn_23', `mask_sample_b_23') /* color space conversion function: - * R = Clamp ( 1.164(Y-16/255) + 1.596(Cr-128/255), 0, 1) - * G = Clamp ( 1.164(Y-16/255) - 0.813(Cr-128/255) - 0.392(Cb-128/255), 0, 1) - * B = Clamp ( 1.164(Y-16/255) + 2.017(Cb-128/255), 0, 1) + * Cy = 255/(235-16) + * R = Clamp ( 255/(235-16)(Y-16/255) + + * 255/112(1.0-Kr)(Cr-128/255), 0, 1) + * G = Clamp ( 255/(235-16)(Y-16/255) - + * 255/112(1.0-Kr)Kr/Kg(Cr-128/255) - + * 255/112(1.0-Kb)Kb/Kg(Cb-128/255), 0, 1) + * B = Clamp ( 255/(235-16)(Y-16/255) + + * 255/112(1.0-Kb)(Cb-128/255), 0, 1) + * + * BT.601: + * Kr = 0.299 + * Kb = 0.114 + * Kg = (1.0 - Kr - Kb) = 0.587 */ /* Normalize Y, Cb and Cr: * - * Yn = (Y - 16/255) * 1.164 + * Yn = (Y - 16/255) * 255/(235-16) * Crn = Cr - 128 / 255 * Cbn = Cb - 128 / 255 */ @@ -73,21 +83,25 @@ add (16) Crn<1>F Cr<8,8,1>F -0.501961F { compr align1 }; add (16) Cbn<1>F Cb<8,8,1>F -0.501961F { compr align1 }; - /* - * R = Y + Cr * 1.596 + /* + * R = Yn + + * Crn * 255/112 * (1.0 - Kr) */ mov (16) acc0<1>F Yn<8,8,1>F { compr align1 }; mac.sat(16) src_sample_r<1>F Crn<8,8,1>F 1.596F { compr align1 }; - + /* - * G = Crn * -0.813 + Cbn * -0.392 + Y + * G = Yn - + * Crn * 255/112 * (1.0 - Kr) * Kr / Kg - + * Cbn * 255/112 * (1.0 - Kb) * Kb / Kg */ mov (16) acc0<1>F Yn<8,8,1>F { compr align1 }; mac (16) acc0<1>F Crn<8,8,1>F -0.813F { compr align1 }; mac.sat(16) src_sample_g<1>F Cbn<8,8,1>F -0.392F { compr align1 }; /* - * B = Cbn * 2.017 + Y + * B = Yn + + * Cbn * 255/112 * (1.0 - Kb) */ mov (16) acc0<1>F Yn<8,8,1>F { compr align1 }; mac.sat(16) src_sample_b<1>F Cbn<8,8,1>F 2.017F { compr align1 }; diff --git a/src/render_program/exa_wm_yuv_rgb_bt601.g8a b/src/render_program/exa_wm_yuv_rgb_bt601.g8a index 34973ba8..360501dc 100644 --- a/src/render_program/exa_wm_yuv_rgb_bt601.g8a +++ b/src/render_program/exa_wm_yuv_rgb_bt601.g8a @@ -55,14 +55,23 @@ define(`Cbn_01', `mask_sample_b_01') define(`Cbn_23', `mask_sample_b_23') /* color space conversion function: - * R = Clamp ( 1.164(Y-16/255) + 1.596(Cr-128/255), 0, 1) - * G = Clamp ( 1.164(Y-16/255) - 0.813(Cr-128/255) - 0.392(Cb-128/255), 0, 1) - * B = Clamp ( 1.164(Y-16/255) + 2.017(Cb-128/255), 0, 1) + * R = Clamp ( 255/(235-16)(Y-16/255) + + * 255/112(1.0-Kr)(Cr-128/255), 0, 1) + * G = Clamp ( 255/(235-16)(Y-16/255) - + * 255/112(1.0-Kr)Kr/Kg(Cr-128/255) - + * 255/112(1.0-Kb)Kb/Kg(Cb-128/255), 0, 1) + * B = Clamp ( 255/(235-16)(Y-16/255) + + * 255/112(1.0-Kb)(Cb-128/255), 0, 1) + * + * BT.601: + * Kr = 0.299 + * Kb = 0.114 + * Kg = (1.0 - Kr - Kb) = 0.587 */ /* Normalize Y, Cb and Cr: * - * Yn = (Y - 16/255) * 1.164 + * Yn = (Y - 16/255) * 255/(235-16) * Crn = Cr - 128 / 255 * Cbn = Cb - 128 / 255 */ @@ -73,16 +82,19 @@ add (16) Crn<1>F Cr<8,8,1>F -0.501961F { compr align1 }; add (16) Cbn<1>F Cb<8,8,1>F -0.501961F { compr align1 }; - /* - * R = Y + Cr * 1.596 + /* + * R = Yn + + * Crn * 255/112 * (1.0 - Kr) */ mov (8) acc0<1>F Yn_01<8,8,1>F { compr align1 }; mac.sat(8) src_sample_r_01<1>F Crn_01<8,8,1>F 1.596F { compr align1 }; - + mov (8) acc0<1>F Yn_23<8,8,1>F { compr align1 }; mac.sat(8) src_sample_r_23<1>F Crn_23<8,8,1>F 1.596F { compr align1 }; /* - * G = Crn * -0.813 + Cbn * -0.392 + Y + * G = Yn - + * Crn * 255/112 * (1.0 - Kr) * Kr / Kg - + * Cbn * 255/112 * (1.0 - Kb) * Kb / Kg */ mov (8) acc0<1>F Yn_01<8,8,1>F { compr align1 }; mac (8) acc0<1>F Crn_01<8,8,1>F -0.813F { compr align1 }; @@ -92,7 +104,8 @@ mov (8) acc0<1>F Yn_23<8,8,1>F { compr align1 }; mac (8) acc0<1>F Crn_23<8,8,1>F -0.813F { compr align1 }; mac.sat(16) src_sample_g_23<1>F Cbn_23<8,8,1>F -0.392F { compr align1 }; /* - * B = Cbn * 2.017 + Y + * B = Yn + + * Cbn * 255/112 * (1.0 - Kb) */ mov (8) acc0<1>F Yn_01<8,8,1>F { compr align1 }; mac.sat(8) src_sample_b_01<1>F Cbn_01<8,8,1>F 2.017F { compr align1 }; diff --git a/src/render_program/exa_wm_yuv_rgb_bt709.g4a b/src/render_program/exa_wm_yuv_rgb_bt709.g4a new file mode 100644 index 00000000..e498f18f --- /dev/null +++ b/src/render_program/exa_wm_yuv_rgb_bt709.g4a @@ -0,0 +1,111 @@ +/* + * Copyright © 2006 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + * + * Authors: + * Keith Packard + * Eric Anholt + * + */ + +include(`exa_wm.g4i') + +define(`YCbCr_base', `src_sample_base') + +define(`Cr', `src_sample_r') +define(`Cr_01', `src_sample_r_01') +define(`Cr_23', `src_sample_r_23') + +define(`Y', `src_sample_g') +define(`Y_01', `src_sample_g_01') +define(`Y_23', `src_sample_g_23') + +define(`Cb', `src_sample_b') +define(`Cb_01', `src_sample_b_01') +define(`Cb_23', `src_sample_b_23') + +define(`Crn', `mask_sample_r') +define(`Crn_01', `mask_sample_r_01') +define(`Crn_23', `mask_sample_r_23') + +define(`Yn', `mask_sample_g') +define(`Yn_01', `mask_sample_g_01') +define(`Yn_23', `mask_sample_g_23') + +define(`Cbn', `mask_sample_b') +define(`Cbn_01', `mask_sample_b_01') +define(`Cbn_23', `mask_sample_b_23') + + /* color space conversion function: + * R = Clamp ( 255/(235-16)(Y-16/255) + + * 255/112(1.0-Kr)(Cr-128/255), 0, 1) + * G = Clamp ( 255/(235-16)(Y-16/255) - + * 255/112(1.0-Kr)Kr/Kg(Cr-128/255) - + * 255/112(1.0-Kb)Kb/Kg(Cb-128/255), 0, 1) + * B = Clamp ( 255/(235-16)(Y-16/255) + + * 255/112(1.0-Kb)(Cb-128/255), 0, 1) + * + * BT.709: + * Kr = .2126 + * Kb = .0722 + * Kg = (1.0 - Kr - Kb) = 0.7152 + */ + + /* Normalize Y, Cb and Cr: + * + * Yn = (Y - 16/255) * 255/(235-16) + * Crn = Cr - 128 / 255 + * Cbn = Cb - 128 / 255 + */ +add (16) Yn<1>F Y<8,8,1>F -0.0627451F { compr align1 }; +mul (16) Yn<1>F Yn<8,8,1>F 1.164F { compr align1 }; + +add (16) Crn<1>F Cr<8,8,1>F -0.501961F { compr align1 }; + +add (16) Cbn<1>F Cb<8,8,1>F -0.501961F { compr align1 }; + + /* + * R = Yn + + * Crn * 255/112 * (1.0 - Kr) + */ +mov (16) acc0<1>F Yn<8,8,1>F { compr align1 }; +mac.sat(16) src_sample_r<1>F Crn<8,8,1>F 1.793F { compr align1 }; + + /* + * G = Yn - + * Crn * 255/112 * (1.0 - Kr) * Kr / Kg - + * Cbn * 255/112 * (1.0 - Kb) * Kb / Kg + */ +mov (16) acc0<1>F Yn<8,8,1>F { compr align1 }; +mac (16) acc0<1>F Crn<8,8,1>F -0.533F { compr align1 }; +mac.sat(16) src_sample_g<1>F Cbn<8,8,1>F -0.213F { compr align1 }; + + /* + * B = Yn + + * Cbn * 255/112 * (1.0 - Kb) + */ +mov (16) acc0<1>F Yn<8,8,1>F { compr align1 }; +mac.sat(16) src_sample_b<1>F Cbn<8,8,1>F 2.112F { compr align1 }; + + /* + * A = 1.0 + */ +mov (16) src_sample_a<1>F 1.0F { compr align1 }; diff --git a/src/render_program/exa_wm_yuv_rgb_bt709.g4b b/src/render_program/exa_wm_yuv_rgb_bt709.g4b new file mode 100644 index 00000000..5b7621b5 --- /dev/null +++ b/src/render_program/exa_wm_yuv_rgb_bt709.g4b @@ -0,0 +1,12 @@ + { 0x00802040, 0x23007fbd, 0x008d0200, 0xbd808081 }, + { 0x00802041, 0x23007fbd, 0x008d0300, 0x3f94fdf4 }, + { 0x00802040, 0x22c07fbd, 0x008d01c0, 0xbf008084 }, + { 0x00802040, 0x23407fbd, 0x008d0240, 0xbf008084 }, + { 0x00802001, 0x240003bc, 0x008d0300, 0x00000000 }, + { 0x80802048, 0x21c07fbd, 0x008d02c0, 0x3fe58106 }, + { 0x00802001, 0x240003bc, 0x008d0300, 0x00000000 }, + { 0x00802048, 0x24007fbc, 0x008d02c0, 0xbf0872b0 }, + { 0x80802048, 0x22007fbd, 0x008d0340, 0xbe5a1cac }, + { 0x00802001, 0x240003bc, 0x008d0300, 0x00000000 }, + { 0x80802048, 0x22407fbd, 0x008d0340, 0x40072b02 }, + { 0x00802001, 0x228003fd, 0x00000000, 0x3f800000 }, diff --git a/src/render_program/exa_wm_yuv_rgb_bt709.g4b.gen5 b/src/render_program/exa_wm_yuv_rgb_bt709.g4b.gen5 new file mode 100644 index 00000000..5b7621b5 --- /dev/null +++ b/src/render_program/exa_wm_yuv_rgb_bt709.g4b.gen5 @@ -0,0 +1,12 @@ + { 0x00802040, 0x23007fbd, 0x008d0200, 0xbd808081 }, + { 0x00802041, 0x23007fbd, 0x008d0300, 0x3f94fdf4 }, + { 0x00802040, 0x22c07fbd, 0x008d01c0, 0xbf008084 }, + { 0x00802040, 0x23407fbd, 0x008d0240, 0xbf008084 }, + { 0x00802001, 0x240003bc, 0x008d0300, 0x00000000 }, + { 0x80802048, 0x21c07fbd, 0x008d02c0, 0x3fe58106 }, + { 0x00802001, 0x240003bc, 0x008d0300, 0x00000000 }, + { 0x00802048, 0x24007fbc, 0x008d02c0, 0xbf0872b0 }, + { 0x80802048, 0x22007fbd, 0x008d0340, 0xbe5a1cac }, + { 0x00802001, 0x240003bc, 0x008d0300, 0x00000000 }, + { 0x80802048, 0x22407fbd, 0x008d0340, 0x40072b02 }, + { 0x00802001, 0x228003fd, 0x00000000, 0x3f800000 }, diff --git a/src/render_program/exa_wm_yuv_rgb_bt709.g5a b/src/render_program/exa_wm_yuv_rgb_bt709.g5a new file mode 120000 index 00000000..9b4ca312 --- /dev/null +++ b/src/render_program/exa_wm_yuv_rgb_bt709.g5a @@ -0,0 +1 @@ +exa_wm_yuv_rgb_bt709.g4a \ No newline at end of file diff --git a/src/render_program/exa_wm_yuv_rgb_bt709.g5b b/src/render_program/exa_wm_yuv_rgb_bt709.g5b new file mode 100644 index 00000000..5b7621b5 --- /dev/null +++ b/src/render_program/exa_wm_yuv_rgb_bt709.g5b @@ -0,0 +1,12 @@ + { 0x00802040, 0x23007fbd, 0x008d0200, 0xbd808081 }, + { 0x00802041, 0x23007fbd, 0x008d0300, 0x3f94fdf4 }, + { 0x00802040, 0x22c07fbd, 0x008d01c0, 0xbf008084 }, + { 0x00802040, 0x23407fbd, 0x008d0240, 0xbf008084 }, + { 0x00802001, 0x240003bc, 0x008d0300, 0x00000000 }, + { 0x80802048, 0x21c07fbd, 0x008d02c0, 0x3fe58106 }, + { 0x00802001, 0x240003bc, 0x008d0300, 0x00000000 }, + { 0x00802048, 0x24007fbc, 0x008d02c0, 0xbf0872b0 }, + { 0x80802048, 0x22007fbd, 0x008d0340, 0xbe5a1cac }, + { 0x00802001, 0x240003bc, 0x008d0300, 0x00000000 }, + { 0x80802048, 0x22407fbd, 0x008d0340, 0x40072b02 }, + { 0x00802001, 0x228003fd, 0x00000000, 0x3f800000 }, diff --git a/src/render_program/exa_wm_yuv_rgb_bt709.g6a b/src/render_program/exa_wm_yuv_rgb_bt709.g6a new file mode 120000 index 00000000..9b4ca312 --- /dev/null +++ b/src/render_program/exa_wm_yuv_rgb_bt709.g6a @@ -0,0 +1 @@ +exa_wm_yuv_rgb_bt709.g4a \ No newline at end of file diff --git a/src/render_program/exa_wm_yuv_rgb_bt709.g6b b/src/render_program/exa_wm_yuv_rgb_bt709.g6b new file mode 100644 index 00000000..392957e7 --- /dev/null +++ b/src/render_program/exa_wm_yuv_rgb_bt709.g6b @@ -0,0 +1,12 @@ + { 0x00800040, 0x23007fbd, 0x008d0200, 0xbd808081 }, + { 0x00800041, 0x23007fbd, 0x008d0300, 0x3f94fdf4 }, + { 0x00800040, 0x22c07fbd, 0x008d01c0, 0xbf008084 }, + { 0x00800040, 0x23407fbd, 0x008d0240, 0xbf008084 }, + { 0x00800001, 0x240003bc, 0x008d0300, 0x00000000 }, + { 0x80800048, 0x21c07fbd, 0x008d02c0, 0x3fe58106 }, + { 0x00800001, 0x240003bc, 0x008d0300, 0x00000000 }, + { 0x00800048, 0x24007fbc, 0x008d02c0, 0xbf0872b0 }, + { 0x80800048, 0x22007fbd, 0x008d0340, 0xbe5a1cac }, + { 0x00800001, 0x240003bc, 0x008d0300, 0x00000000 }, + { 0x80800048, 0x22407fbd, 0x008d0340, 0x40072b02 }, + { 0x00800001, 0x228003fd, 0x00000000, 0x3f800000 }, diff --git a/src/render_program/exa_wm_yuv_rgb_bt709.g7a b/src/render_program/exa_wm_yuv_rgb_bt709.g7a new file mode 120000 index 00000000..9b4ca312 --- /dev/null +++ b/src/render_program/exa_wm_yuv_rgb_bt709.g7a @@ -0,0 +1 @@ +exa_wm_yuv_rgb_bt709.g4a \ No newline at end of file diff --git a/src/render_program/exa_wm_yuv_rgb_bt709.g7b b/src/render_program/exa_wm_yuv_rgb_bt709.g7b new file mode 100644 index 00000000..392957e7 --- /dev/null +++ b/src/render_program/exa_wm_yuv_rgb_bt709.g7b @@ -0,0 +1,12 @@ + { 0x00800040, 0x23007fbd, 0x008d0200, 0xbd808081 }, + { 0x00800041, 0x23007fbd, 0x008d0300, 0x3f94fdf4 }, + { 0x00800040, 0x22c07fbd, 0x008d01c0, 0xbf008084 }, + { 0x00800040, 0x23407fbd, 0x008d0240, 0xbf008084 }, + { 0x00800001, 0x240003bc, 0x008d0300, 0x00000000 }, + { 0x80800048, 0x21c07fbd, 0x008d02c0, 0x3fe58106 }, + { 0x00800001, 0x240003bc, 0x008d0300, 0x00000000 }, + { 0x00800048, 0x24007fbc, 0x008d02c0, 0xbf0872b0 }, + { 0x80800048, 0x22007fbd, 0x008d0340, 0xbe5a1cac }, + { 0x00800001, 0x240003bc, 0x008d0300, 0x00000000 }, + { 0x80800048, 0x22407fbd, 0x008d0340, 0x40072b02 }, + { 0x00800001, 0x228003fd, 0x00000000, 0x3f800000 }, diff --git a/src/render_program/exa_wm_yuv_rgb_bt709.g8a b/src/render_program/exa_wm_yuv_rgb_bt709.g8a new file mode 100644 index 00000000..9ab2ca0d --- /dev/null +++ b/src/render_program/exa_wm_yuv_rgb_bt709.g8a @@ -0,0 +1,118 @@ +/* + * Copyright © 2006 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + * + * Authors: + * Keith Packard + * Eric Anholt + * + */ + +include(`exa_wm.g4i') + +define(`YCbCr_base', `src_sample_base') + +define(`Cr', `src_sample_r') +define(`Cr_01', `src_sample_r_01') +define(`Cr_23', `src_sample_r_23') + +define(`Y', `src_sample_g') +define(`Y_01', `src_sample_g_01') +define(`Y_23', `src_sample_g_23') + +define(`Cb', `src_sample_b') +define(`Cb_01', `src_sample_b_01') +define(`Cb_23', `src_sample_b_23') + +define(`Crn', `mask_sample_r') +define(`Crn_01', `mask_sample_r_01') +define(`Crn_23', `mask_sample_r_23') + +define(`Yn', `mask_sample_g') +define(`Yn_01', `mask_sample_g_01') +define(`Yn_23', `mask_sample_g_23') + +define(`Cbn', `mask_sample_b') +define(`Cbn_01', `mask_sample_b_01') +define(`Cbn_23', `mask_sample_b_23') + + /* color space conversion function: + * R = Clamp ( 255/(235-16)(Y-16/255) + + * 255/112(1.0-Kr)(Cr-128/255), 0, 1) + * G = Clamp ( 255/(235-16)(Y-16/255) - + * 255/112(1.0-Kr)Kr/Kg(Cr-128/255) - + * 255/112(1.0-Kb)Kb/Kg(Cb-128/255), 0, 1) + * B = Clamp ( 255/(235-16)(Y-16/255) + + * 255/112(1.0-Kb)(Cb-128/255), 0, 1) + * + * BT.709: + * Kr = .2126 + * Kb = .0722 + * Kg = (1.0 - Kr - Kb) = 0.7152 + */ + + /* Normalize Y, Cb and Cr: + * + * Yn = (Y - 16/255) * 255/(235-16) + * Crn = Cr - 128 / 255 + * Cbn = Cb - 128 / 255 + */ +add (16) Yn<1>F Y<8,8,1>F -0.0627451F { compr align1 }; +mul (16) Yn<1>F Yn<8,8,1>F 1.164F { compr align1 }; + +add (16) Crn<1>F Cr<8,8,1>F -0.501961F { compr align1 }; + +add (16) Cbn<1>F Cb<8,8,1>F -0.501961F { compr align1 }; + + /* + * R = Yn + + * Crn * 255/112 * (1.0 - Kr) + */ +mov (8) acc0<1>F Yn_01<8,8,1>F { compr align1 }; +mac.sat(8) src_sample_r_01<1>F Crn_01<8,8,1>F 1.793F { compr align1 }; + +mov (8) acc0<1>F Yn_23<8,8,1>F { compr align1 }; +mac.sat(8) src_sample_r_23<1>F Crn_23<8,8,1>F 1.793F { compr align1 }; + /* + * G = Yn - + * Crn * 255/112 * (1.0 - Kr) * Kr / Kg + * Cbn * 255/112 * (1.0 - Kb) * Kb / Kg + */ +mov (8) acc0<1>F Yn_01<8,8,1>F { compr align1 }; +mac (8) acc0<1>F Crn_01<8,8,1>F -0.533F { compr align1 }; +mac.sat(8) src_sample_g_01<1>F Cbn_01<8,8,1>F -0.213F { compr align1 }; + +mov (8) acc0<1>F Yn_23<8,8,1>F { compr align1 }; +mac (8) acc0<1>F Crn_23<8,8,1>F -0.533F { compr align1 }; +mac.sat(16) src_sample_g_23<1>F Cbn_23<8,8,1>F -0.213F { compr align1 }; + /* + * B = Yn + + * Cbn * 255/112 * (1.0 - Kb) + */ +mov (8) acc0<1>F Yn_01<8,8,1>F { compr align1 }; +mac.sat(8) src_sample_b_01<1>F Cbn_01<8,8,1>F 2.112F { compr align1 }; + +mov (8) acc0<1>F Yn_23<8,8,1>F { compr align1 }; +mac.sat(8) src_sample_b_23<1>F Cbn_23<8,8,1>F 2.112F { compr align1 }; + /* + * A = 1.0 + */ +mov (16) src_sample_a<1>F 1.0F { compr align1 }; diff --git a/src/render_program/exa_wm_yuv_rgb_bt709.g8b b/src/render_program/exa_wm_yuv_rgb_bt709.g8b new file mode 100644 index 00000000..9bfe1ca4 --- /dev/null +++ b/src/render_program/exa_wm_yuv_rgb_bt709.g8b @@ -0,0 +1,19 @@ + { 0x00800040, 0x23003ae8, 0x3e8d0200, 0xbd808081 }, + { 0x00800041, 0x23003ae8, 0x3e8d0300, 0x3f94fdf4 }, + { 0x00800040, 0x22c03ae8, 0x3e8d01c0, 0xbf008084 }, + { 0x00800040, 0x23403ae8, 0x3e8d0240, 0xbf008084 }, + { 0x00600001, 0x24003ae0, 0x008d0300, 0x00000000 }, + { 0x80600048, 0x21c03ae8, 0x3e8d02c0, 0x3fe58106 }, + { 0x00600001, 0x24003ae0, 0x008d0320, 0x00000000 }, + { 0x80600048, 0x21e03ae8, 0x3e8d02e0, 0x3fe58106 }, + { 0x00600001, 0x24003ae0, 0x008d0300, 0x00000000 }, + { 0x00600048, 0x24003ae0, 0x3e8d02c0, 0xbf0872b0 }, + { 0x80600048, 0x22003ae8, 0x3e8d0340, 0xbe5a1cac }, + { 0x00600001, 0x24003ae0, 0x008d0320, 0x00000000 }, + { 0x00600048, 0x24003ae0, 0x3e8d02e0, 0xbf0872b0 }, + { 0x80800048, 0x22203ae8, 0x3e8d0360, 0xbe5a1cac }, + { 0x00600001, 0x24003ae0, 0x008d0300, 0x00000000 }, + { 0x80600048, 0x22403ae8, 0x3e8d0340, 0x40072b02 }, + { 0x00600001, 0x24003ae0, 0x008d0320, 0x00000000 }, + { 0x80600048, 0x22603ae8, 0x3e8d0360, 0x40072b02 }, + { 0x00800001, 0x22803ee8, 0x38000000, 0x3f800000 }, diff --git a/src/sna/gen4_render.c b/src/sna/gen4_render.c index 01f8040f..b6a496ca 100644 --- a/src/sna/gen4_render.c +++ b/src/sna/gen4_render.c @@ -99,7 +99,7 @@ #define GEN4_MAX_WM_THREADS 32 #define G4X_MAX_WM_THREADS 50 -static const uint32_t ps_kernel_packed_static[][4] = { +static const uint32_t ps_kernel_packed_bt601_static[][4] = { #include "exa_wm_xy.g4b" #include "exa_wm_src_affine.g4b" #include "exa_wm_src_sample_argb.g4b" @@ -107,7 +107,7 @@ static const uint32_t ps_kernel_packed_static[][4] = { #include "exa_wm_write.g4b" }; -static const uint32_t ps_kernel_planar_static[][4] = { +static const uint32_t ps_kernel_planar_bt601_static[][4] = { #include "exa_wm_xy.g4b" #include "exa_wm_src_affine.g4b" #include "exa_wm_src_sample_planar.g4b" @@ -115,7 +115,7 @@ static const uint32_t ps_kernel_planar_static[][4] = { #include "exa_wm_write.g4b" }; -static const uint32_t ps_kernel_nv12_static[][4] = { +static const uint32_t ps_kernel_nv12_bt601_static[][4] = { #include "exa_wm_xy.g4b" #include "exa_wm_src_affine.g4b" #include "exa_wm_src_sample_nv12.g4b" @@ -123,6 +123,30 @@ static const uint32_t ps_kernel_nv12_static[][4] = { #include "exa_wm_write.g4b" }; +static const uint32_t ps_kernel_packed_bt709_static[][4] = { +#include "exa_wm_xy.g4b" +#include "exa_wm_src_affine.g4b" +#include "exa_wm_src_sample_argb.g4b" +#include "exa_wm_yuv_rgb_bt709.g4b" +#include "exa_wm_write.g4b" +}; + +static const uint32_t ps_kernel_planar_bt709_static[][4] = { +#include "exa_wm_xy.g4b" +#include "exa_wm_src_affine.g4b" +#include "exa_wm_src_sample_planar.g4b" +#include "exa_wm_yuv_rgb_bt709.g4b" +#include "exa_wm_write.g4b" +}; + +static const uint32_t ps_kernel_nv12_bt709_static[][4] = { +#include "exa_wm_xy.g4b" +#include "exa_wm_src_affine.g4b" +#include "exa_wm_src_sample_nv12.g4b" +#include "exa_wm_yuv_rgb_bt709.g4b" +#include "exa_wm_write.g4b" +}; + #define NOKERNEL(kernel_enum, func, masked) \ [kernel_enum] = {func, 0, masked} #define KERNEL(kernel_enum, kernel, masked) \ @@ -147,9 +171,13 @@ static const struct wm_kernel_info { NOKERNEL(WM_KERNEL_OPACITY, brw_wm_kernel__affine_opacity, true), NOKERNEL(WM_KERNEL_OPACITY_P, brw_wm_kernel__projective_opacity, true), - KERNEL(WM_KERNEL_VIDEO_PLANAR, ps_kernel_planar_static, false), - KERNEL(WM_KERNEL_VIDEO_NV12, ps_kernel_nv12_static, false), - KERNEL(WM_KERNEL_VIDEO_PACKED, ps_kernel_packed_static, false), + KERNEL(WM_KERNEL_VIDEO_PLANAR_BT601, ps_kernel_planar_bt601_static, false), + KERNEL(WM_KERNEL_VIDEO_NV12_BT601, ps_kernel_nv12_bt601_static, false), + KERNEL(WM_KERNEL_VIDEO_PACKED_BT601, ps_kernel_packed_bt601_static, false), + + KERNEL(WM_KERNEL_VIDEO_PLANAR_BT709, ps_kernel_planar_bt709_static, false), + KERNEL(WM_KERNEL_VIDEO_NV12_BT709, ps_kernel_nv12_bt709_static, false), + KERNEL(WM_KERNEL_VIDEO_PACKED_BT709, ps_kernel_packed_bt709_static, false), }; #undef KERNEL @@ -1404,6 +1432,29 @@ static void gen4_video_bind_surfaces(struct sna *sna, gen4_emit_state(sna, op, offset | dirty); } +static unsigned select_video_kernel(const struct sna_video *video, + const struct sna_video_frame *frame) +{ + switch (frame->id) { + case FOURCC_YV12: + case FOURCC_I420: + case FOURCC_XVMC: + return video->colorspace ? + WM_KERNEL_VIDEO_PLANAR_BT709 : + WM_KERNEL_VIDEO_PLANAR_BT601; + + case FOURCC_NV12: + return video->colorspace ? + WM_KERNEL_VIDEO_NV12_BT709 : + WM_KERNEL_VIDEO_NV12_BT601; + + default: + return video->colorspace ? + WM_KERNEL_VIDEO_PACKED_BT709 : + WM_KERNEL_VIDEO_PACKED_BT601; + } +} + static bool gen4_render_video(struct sna *sna, struct sna_video *video, @@ -1442,9 +1493,7 @@ gen4_render_video(struct sna *sna, tmp.src.repeat = SAMPLER_EXTEND_PAD; tmp.src.bo = frame->bo; tmp.mask.bo = NULL; - tmp.u.gen4.wm_kernel = - is_nv12_fourcc(frame->id) ? WM_KERNEL_VIDEO_NV12 : - is_planar_fourcc(frame->id) ? WM_KERNEL_VIDEO_PLANAR : WM_KERNEL_VIDEO_PACKED; + tmp.u.gen4.wm_kernel = select_video_kernel(video, frame); tmp.u.gen4.ve_id = 2; tmp.is_affine = true; tmp.floats_per_vertex = 3; diff --git a/src/sna/gen4_render.h b/src/sna/gen4_render.h index 3b37f96a..f516c316 100644 --- a/src/sna/gen4_render.h +++ b/src/sna/gen4_render.h @@ -2685,9 +2685,14 @@ typedef enum { WM_KERNEL_OPACITY, WM_KERNEL_OPACITY_P, - WM_KERNEL_VIDEO_PLANAR, - WM_KERNEL_VIDEO_NV12, - WM_KERNEL_VIDEO_PACKED, + WM_KERNEL_VIDEO_PLANAR_BT601, + WM_KERNEL_VIDEO_NV12_BT601, + WM_KERNEL_VIDEO_PACKED_BT601, + + WM_KERNEL_VIDEO_PLANAR_BT709, + WM_KERNEL_VIDEO_NV12_BT709, + WM_KERNEL_VIDEO_PACKED_BT709, + KERNEL_COUNT } wm_kernel_t; diff --git a/src/sna/gen5_render.c b/src/sna/gen5_render.c index bed4a3ed..3d9d35f1 100644 --- a/src/sna/gen5_render.c +++ b/src/sna/gen5_render.c @@ -89,7 +89,7 @@ #define PS_KERNEL_NUM_GRF 32 #define PS_MAX_THREADS 72 -static const uint32_t ps_kernel_packed_static[][4] = { +static const uint32_t ps_kernel_packed_bt601_static[][4] = { #include "exa_wm_xy.g5b" #include "exa_wm_src_affine.g5b" #include "exa_wm_src_sample_argb.g5b" @@ -97,7 +97,7 @@ static const uint32_t ps_kernel_packed_static[][4] = { #include "exa_wm_write.g5b" }; -static const uint32_t ps_kernel_planar_static[][4] = { +static const uint32_t ps_kernel_planar_bt601_static[][4] = { #include "exa_wm_xy.g5b" #include "exa_wm_src_affine.g5b" #include "exa_wm_src_sample_planar.g5b" @@ -105,7 +105,7 @@ static const uint32_t ps_kernel_planar_static[][4] = { #include "exa_wm_write.g5b" }; -static const uint32_t ps_kernel_nv12_static[][4] = { +static const uint32_t ps_kernel_nv12_bt601_static[][4] = { #include "exa_wm_xy.g5b" #include "exa_wm_src_affine.g5b" #include "exa_wm_src_sample_nv12.g5b" @@ -113,6 +113,30 @@ static const uint32_t ps_kernel_nv12_static[][4] = { #include "exa_wm_write.g5b" }; +static const uint32_t ps_kernel_packed_bt709_static[][4] = { +#include "exa_wm_xy.g5b" +#include "exa_wm_src_affine.g5b" +#include "exa_wm_src_sample_argb.g5b" +#include "exa_wm_yuv_rgb_bt709.g5b" +#include "exa_wm_write.g5b" +}; + +static const uint32_t ps_kernel_planar_bt709_static[][4] = { +#include "exa_wm_xy.g5b" +#include "exa_wm_src_affine.g5b" +#include "exa_wm_src_sample_planar.g5b" +#include "exa_wm_yuv_rgb_bt709.g5b" +#include "exa_wm_write.g5b" +}; + +static const uint32_t ps_kernel_nv12_bt709_static[][4] = { +#include "exa_wm_xy.g5b" +#include "exa_wm_src_affine.g5b" +#include "exa_wm_src_sample_nv12.g5b" +#include "exa_wm_yuv_rgb_bt709.g5b" +#include "exa_wm_write.g5b" +}; + #define NOKERNEL(kernel_enum, func, masked) \ [kernel_enum] = {func, 0, masked} #define KERNEL(kernel_enum, kernel, masked) \ @@ -137,9 +161,13 @@ static const struct wm_kernel_info { NOKERNEL(WM_KERNEL_OPACITY, brw_wm_kernel__affine_opacity, true), NOKERNEL(WM_KERNEL_OPACITY_P, brw_wm_kernel__projective_opacity, true), - KERNEL(WM_KERNEL_VIDEO_PLANAR, ps_kernel_planar_static, false), - KERNEL(WM_KERNEL_VIDEO_NV12, ps_kernel_nv12_static, false), - KERNEL(WM_KERNEL_VIDEO_PACKED, ps_kernel_packed_static, false), + KERNEL(WM_KERNEL_VIDEO_PLANAR_BT601, ps_kernel_planar_bt601_static, false), + KERNEL(WM_KERNEL_VIDEO_NV12_BT601, ps_kernel_nv12_bt601_static, false), + KERNEL(WM_KERNEL_VIDEO_PACKED_BT601, ps_kernel_packed_bt601_static, false), + + KERNEL(WM_KERNEL_VIDEO_PLANAR_BT709, ps_kernel_planar_bt709_static, false), + KERNEL(WM_KERNEL_VIDEO_NV12_BT709, ps_kernel_nv12_bt709_static, false), + KERNEL(WM_KERNEL_VIDEO_PACKED_BT709, ps_kernel_packed_bt709_static, false), }; #undef KERNEL @@ -1354,6 +1382,29 @@ static void gen5_video_bind_surfaces(struct sna *sna, gen5_emit_state(sna, op, offset | dirty); } +static unsigned select_video_kernel(const struct sna_video *video, + const struct sna_video_frame *frame) +{ + switch (frame->id) { + case FOURCC_YV12: + case FOURCC_I420: + case FOURCC_XVMC: + return video->colorspace ? + WM_KERNEL_VIDEO_PLANAR_BT709 : + WM_KERNEL_VIDEO_PLANAR_BT601; + + case FOURCC_NV12: + return video->colorspace ? + WM_KERNEL_VIDEO_NV12_BT709 : + WM_KERNEL_VIDEO_NV12_BT601; + + default: + return video->colorspace ? + WM_KERNEL_VIDEO_PACKED_BT709 : + WM_KERNEL_VIDEO_PACKED_BT601; + } +} + static bool gen5_render_video(struct sna *sna, struct sna_video *video, @@ -1392,9 +1443,7 @@ gen5_render_video(struct sna *sna, tmp.src.repeat = SAMPLER_EXTEND_PAD; tmp.src.bo = frame->bo; tmp.mask.bo = NULL; - tmp.u.gen5.wm_kernel = - is_nv12_fourcc(frame->id) ? WM_KERNEL_VIDEO_NV12 : - is_planar_fourcc(frame->id) ? WM_KERNEL_VIDEO_PLANAR : WM_KERNEL_VIDEO_PACKED; + tmp.u.gen5.wm_kernel = select_video_kernel(video, frame); tmp.u.gen5.ve_id = 2; tmp.is_affine = true; tmp.floats_per_vertex = 3; diff --git a/src/sna/gen5_render.h b/src/sna/gen5_render.h index f1a9a68c..8901480a 100644 --- a/src/sna/gen5_render.h +++ b/src/sna/gen5_render.h @@ -2765,9 +2765,14 @@ typedef enum { WM_KERNEL_OPACITY, WM_KERNEL_OPACITY_P, - WM_KERNEL_VIDEO_PLANAR, - WM_KERNEL_VIDEO_NV12, - WM_KERNEL_VIDEO_PACKED, + WM_KERNEL_VIDEO_PLANAR_BT601, + WM_KERNEL_VIDEO_NV12_BT601, + WM_KERNEL_VIDEO_PACKED_BT601, + + WM_KERNEL_VIDEO_PLANAR_BT709, + WM_KERNEL_VIDEO_NV12_BT709, + WM_KERNEL_VIDEO_PACKED_BT709, + KERNEL_COUNT } wm_kernel_t; #endif diff --git a/src/sna/gen6_render.c b/src/sna/gen6_render.c index 39ea5b6f..0a53ef56 100644 --- a/src/sna/gen6_render.c +++ b/src/sna/gen6_render.c @@ -101,27 +101,48 @@ static const struct gt_info gt2_info = { .gt = 2, }; -static const uint32_t ps_kernel_packed[][4] = { +static const uint32_t ps_kernel_packed_bt601[][4] = { #include "exa_wm_src_affine.g6b" #include "exa_wm_src_sample_argb.g6b" #include "exa_wm_yuv_rgb_bt601.g6b" #include "exa_wm_write.g6b" }; -static const uint32_t ps_kernel_planar[][4] = { +static const uint32_t ps_kernel_planar_bt601[][4] = { #include "exa_wm_src_affine.g6b" #include "exa_wm_src_sample_planar.g6b" #include "exa_wm_yuv_rgb_bt601.g6b" #include "exa_wm_write.g6b" }; -static const uint32_t ps_kernel_nv12[][4] = { +static const uint32_t ps_kernel_nv12_bt601[][4] = { #include "exa_wm_src_affine.g6b" #include "exa_wm_src_sample_nv12.g6b" #include "exa_wm_yuv_rgb_bt601.g6b" #include "exa_wm_write.g6b" }; +static const uint32_t ps_kernel_packed_bt709[][4] = { +#include "exa_wm_src_affine.g6b" +#include "exa_wm_src_sample_argb.g6b" +#include "exa_wm_yuv_rgb_bt709.g6b" +#include "exa_wm_write.g6b" +}; + +static const uint32_t ps_kernel_planar_bt709[][4] = { +#include "exa_wm_src_affine.g6b" +#include "exa_wm_src_sample_planar.g6b" +#include "exa_wm_yuv_rgb_bt709.g6b" +#include "exa_wm_write.g6b" +}; + +static const uint32_t ps_kernel_nv12_bt709[][4] = { +#include "exa_wm_src_affine.g6b" +#include "exa_wm_src_sample_nv12.g6b" +#include "exa_wm_yuv_rgb_bt709.g6b" +#include "exa_wm_write.g6b" +}; + #define NOKERNEL(kernel_enum, func, ns) \ [GEN6_WM_KERNEL_##kernel_enum] = {#kernel_enum, func, 0, ns} #define KERNEL(kernel_enum, kernel, ns) \ @@ -148,9 +169,14 @@ static const struct wm_kernel_info { NOKERNEL(OPACITY, brw_wm_kernel__affine_opacity, 2), NOKERNEL(OPACITY_P, brw_wm_kernel__projective_opacity, 2), - KERNEL(VIDEO_PLANAR, ps_kernel_planar, 7), - KERNEL(VIDEO_NV12, ps_kernel_nv12, 7), - KERNEL(VIDEO_PACKED, ps_kernel_packed, 2), + + KERNEL(VIDEO_PLANAR_BT601, ps_kernel_planar_bt601, 7), + KERNEL(VIDEO_NV12_BT601, ps_kernel_nv12_bt601, 7), + KERNEL(VIDEO_PACKED_BT601, ps_kernel_packed_bt601, 2), + + KERNEL(VIDEO_PLANAR_BT709, ps_kernel_planar_bt709, 7), + KERNEL(VIDEO_NV12_BT709, ps_kernel_nv12_bt709, 7), + KERNEL(VIDEO_PACKED_BT709, ps_kernel_packed_bt709, 2), }; #undef KERNEL @@ -1631,6 +1657,29 @@ static void gen6_emit_video_state(struct sna *sna, gen6_emit_state(sna, op, offset | dirty); } +static unsigned select_video_kernel(const struct sna_video *video, + const struct sna_video_frame *frame) +{ + switch (frame->id) { + case FOURCC_YV12: + case FOURCC_I420: + case FOURCC_XVMC: + return video->colorspace ? + GEN6_WM_KERNEL_VIDEO_PLANAR_BT709 : + GEN6_WM_KERNEL_VIDEO_PLANAR_BT601; + + case FOURCC_NV12: + return video->colorspace ? + GEN6_WM_KERNEL_VIDEO_NV12_BT709 : + GEN6_WM_KERNEL_VIDEO_NV12_BT601; + + default: + return video->colorspace ? + GEN6_WM_KERNEL_VIDEO_PACKED_BT709 : + GEN6_WM_KERNEL_VIDEO_PACKED_BT601; + } +} + static bool gen6_render_video(struct sna *sna, struct sna_video *video, @@ -1683,11 +1732,7 @@ gen6_render_video(struct sna *sna, GEN6_SET_FLAGS(SAMPLER_OFFSET(filter, SAMPLER_EXTEND_PAD, SAMPLER_FILTER_NEAREST, SAMPLER_EXTEND_NONE), NO_BLEND, - is_nv12_fourcc(frame->id) ? - GEN6_WM_KERNEL_VIDEO_NV12 : - is_planar_fourcc(frame->id) ? - GEN6_WM_KERNEL_VIDEO_PLANAR : - GEN6_WM_KERNEL_VIDEO_PACKED, + select_video_kernel(video, frame), 2); tmp.priv = frame; diff --git a/src/sna/gen7_render.c b/src/sna/gen7_render.c index b1fdfb51..0a3bda76 100644 --- a/src/sna/gen7_render.c +++ b/src/sna/gen7_render.c @@ -193,27 +193,48 @@ inline static bool is_hsw(struct sna *sna) return sna->kgem.gen == 075; } -static const uint32_t ps_kernel_packed[][4] = { +static const uint32_t ps_kernel_packed_bt601[][4] = { #include "exa_wm_src_affine.g7b" #include "exa_wm_src_sample_argb.g7b" #include "exa_wm_yuv_rgb_bt601.g7b" #include "exa_wm_write.g7b" }; -static const uint32_t ps_kernel_planar[][4] = { +static const uint32_t ps_kernel_planar_bt601[][4] = { #include "exa_wm_src_affine.g7b" #include "exa_wm_src_sample_planar.g7b" #include "exa_wm_yuv_rgb_bt601.g7b" #include "exa_wm_write.g7b" }; -static const uint32_t ps_kernel_nv12[][4] = { +static const uint32_t ps_kernel_nv12_bt601[][4] = { #include "exa_wm_src_affine.g7b" #include "exa_wm_src_sample_nv12.g7b" #include "exa_wm_yuv_rgb_bt601.g7b" #include "exa_wm_write.g7b" }; +static const uint32_t ps_kernel_packed_bt709[][4] = { +#include "exa_wm_src_affine.g7b" +#include "exa_wm_src_sample_argb.g7b" +#include "exa_wm_yuv_rgb_bt709.g7b" +#include "exa_wm_write.g7b" +}; + +static const uint32_t ps_kernel_planar_bt709[][4] = { +#include "exa_wm_src_affine.g7b" +#include "exa_wm_src_sample_planar.g7b" +#include "exa_wm_yuv_rgb_bt709.g7b" +#include "exa_wm_write.g7b" +}; + +static const uint32_t ps_kernel_nv12_bt709[][4] = { +#include "exa_wm_src_affine.g7b" +#include "exa_wm_src_sample_nv12.g7b" +#include "exa_wm_yuv_rgb_bt709.g7b" +#include "exa_wm_write.g7b" +}; + static const uint32_t ps_kernel_rgb[][4] = { #include "exa_wm_src_affine.g7b" #include "exa_wm_src_sample_argb.g7b" @@ -245,9 +266,12 @@ static const struct wm_kernel_info { NOKERNEL(OPACITY, brw_wm_kernel__affine_opacity, 2), NOKERNEL(OPACITY_P, brw_wm_kernel__projective_opacity, 2), - KERNEL(VIDEO_PLANAR, ps_kernel_planar, 7), - KERNEL(VIDEO_NV12, ps_kernel_nv12, 7), - KERNEL(VIDEO_PACKED, ps_kernel_packed, 2), + KERNEL(VIDEO_PLANAR_BT601, ps_kernel_planar_bt601, 7), + KERNEL(VIDEO_NV12_BT601, ps_kernel_nv12_bt601, 7), + KERNEL(VIDEO_PACKED_BT601, ps_kernel_packed_bt601, 2), + KERNEL(VIDEO_PLANAR_BT709, ps_kernel_planar_bt709, 7), + KERNEL(VIDEO_NV12_BT709, ps_kernel_nv12_bt709, 7), + KERNEL(VIDEO_PACKED_BT709, ps_kernel_packed_bt709, 2), KERNEL(VIDEO_RGB, ps_kernel_rgb, 2), }; #undef KERNEL @@ -1846,23 +1870,30 @@ static void gen7_emit_video_state(struct sna *sna, gen7_emit_state(sna, op, offset | dirty); } -static unsigned select_video_kernel(const struct sna_video_frame *frame) +static unsigned select_video_kernel(const struct sna_video *video, + const struct sna_video_frame *frame) { switch (frame->id) { case FOURCC_YV12: case FOURCC_I420: case FOURCC_XVMC: - return GEN7_WM_KERNEL_VIDEO_PLANAR; + return video->colorspace ? + GEN7_WM_KERNEL_VIDEO_PLANAR_BT709 : + GEN7_WM_KERNEL_VIDEO_PLANAR_BT601; case FOURCC_NV12: - return GEN7_WM_KERNEL_VIDEO_NV12; + return video->colorspace ? + GEN7_WM_KERNEL_VIDEO_NV12_BT709 : + GEN7_WM_KERNEL_VIDEO_NV12_BT601; case FOURCC_RGB888: case FOURCC_RGB565: return GEN7_WM_KERNEL_VIDEO_RGB; default: - return GEN7_WM_KERNEL_VIDEO_PACKED; + return video->colorspace ? + GEN7_WM_KERNEL_VIDEO_PACKED_BT709 : + GEN7_WM_KERNEL_VIDEO_PACKED_BT601; } } @@ -1918,7 +1949,7 @@ gen7_render_video(struct sna *sna, GEN7_SET_FLAGS(SAMPLER_OFFSET(filter, SAMPLER_EXTEND_PAD, SAMPLER_FILTER_NEAREST, SAMPLER_EXTEND_NONE), NO_BLEND, - select_video_kernel(frame), + select_video_kernel(video, frame), 2); tmp.priv = frame; diff --git a/src/sna/gen8_render.c b/src/sna/gen8_render.c index eadb09eb..69617da5 100644 --- a/src/sna/gen8_render.c +++ b/src/sna/gen8_render.c @@ -93,27 +93,48 @@ */ #if !NO_VIDEO -static const uint32_t ps_kernel_packed[][4] = { +static const uint32_t ps_kernel_packed_bt601[][4] = { #include "exa_wm_src_affine.g8b" #include "exa_wm_src_sample_argb.g8b" #include "exa_wm_yuv_rgb_bt601.g8b" #include "exa_wm_write.g8b" }; -static const uint32_t ps_kernel_planar[][4] = { +static const uint32_t ps_kernel_planar_bt601[][4] = { #include "exa_wm_src_affine.g8b" #include "exa_wm_src_sample_planar.g8b" #include "exa_wm_yuv_rgb_bt601.g8b" #include "exa_wm_write.g8b" }; -static const uint32_t ps_kernel_nv12[][4] = { +static const uint32_t ps_kernel_nv12_bt601[][4] = { #include "exa_wm_src_affine.g8b" #include "exa_wm_src_sample_nv12.g8b" #include "exa_wm_yuv_rgb_bt601.g8b" #include "exa_wm_write.g8b" }; +static const uint32_t ps_kernel_packed_bt709[][4] = { +#include "exa_wm_src_affine.g8b" +#include "exa_wm_src_sample_argb.g8b" +#include "exa_wm_yuv_rgb_bt709.g8b" +#include "exa_wm_write.g8b" +}; + +static const uint32_t ps_kernel_planar_bt709[][4] = { +#include "exa_wm_src_affine.g8b" +#include "exa_wm_src_sample_planar.g8b" +#include "exa_wm_yuv_rgb_bt709.g8b" +#include "exa_wm_write.g8b" +}; + +static const uint32_t ps_kernel_nv12_bt709[][4] = { +#include "exa_wm_src_affine.g8b" +#include "exa_wm_src_sample_nv12.g8b" +#include "exa_wm_yuv_rgb_bt709.g8b" +#include "exa_wm_write.g8b" +}; + static const uint32_t ps_kernel_rgb[][4] = { #include "exa_wm_src_affine.g8b" #include "exa_wm_src_sample_argb.g8b" @@ -149,9 +170,12 @@ static const struct wm_kernel_info { NOKERNEL(OPACITY_P, gen8_wm_kernel__projective_opacity, 2), #if !NO_VIDEO - KERNEL(VIDEO_PLANAR, ps_kernel_planar, 7), - KERNEL(VIDEO_NV12, ps_kernel_nv12, 7), - KERNEL(VIDEO_PACKED, ps_kernel_packed, 2), + KERNEL(VIDEO_PLANAR_BT601, ps_kernel_planar_bt601, 7), + KERNEL(VIDEO_NV12_BT601, ps_kernel_nv12_bt601, 7), + KERNEL(VIDEO_PACKED_BT601, ps_kernel_packed_bt601, 2), + KERNEL(VIDEO_PLANAR_BT709, ps_kernel_planar_bt709, 7), + KERNEL(VIDEO_NV12_BT709, ps_kernel_nv12_bt709, 7), + KERNEL(VIDEO_PACKED_BT709, ps_kernel_packed_bt709, 2), KERNEL(VIDEO_RGB, ps_kernel_rgb, 2), #endif }; @@ -3790,23 +3814,30 @@ static void gen8_emit_video_state(struct sna *sna, gen8_emit_state(sna, op, offset); } -static unsigned select_video_kernel(const struct sna_video_frame *frame) +static unsigned select_video_kernel(const struct sna_video *video, + const struct sna_video_frame *frame) { switch (frame->id) { case FOURCC_YV12: case FOURCC_I420: case FOURCC_XVMC: - return GEN8_WM_KERNEL_VIDEO_PLANAR; + return video->colorspace ? + GEN8_WM_KERNEL_VIDEO_PLANAR_BT709 : + GEN8_WM_KERNEL_VIDEO_PLANAR_BT601; case FOURCC_NV12: - return GEN8_WM_KERNEL_VIDEO_NV12; + return video->colorspace ? + GEN8_WM_KERNEL_VIDEO_NV12_BT709 : + GEN8_WM_KERNEL_VIDEO_NV12_BT601; case FOURCC_RGB888: case FOURCC_RGB565: return GEN8_WM_KERNEL_VIDEO_RGB; default: - return GEN8_WM_KERNEL_VIDEO_PACKED; + return video->colorspace ? + GEN8_WM_KERNEL_VIDEO_PACKED_BT709 : + GEN8_WM_KERNEL_VIDEO_PACKED_BT601; } } @@ -3870,7 +3901,7 @@ gen8_render_video(struct sna *sna, GEN8_SET_FLAGS(SAMPLER_OFFSET(filter, SAMPLER_EXTEND_PAD, SAMPLER_FILTER_NEAREST, SAMPLER_EXTEND_NONE), NO_BLEND, - select_video_kernel(frame), + select_video_kernel(video, frame), 2); tmp.priv = frame; diff --git a/src/sna/gen9_render.c b/src/sna/gen9_render.c index 721a186a..505b98af 100644 --- a/src/sna/gen9_render.c +++ b/src/sna/gen9_render.c @@ -94,27 +94,48 @@ */ #if !NO_VIDEO -static const uint32_t ps_kernel_packed[][4] = { +static const uint32_t ps_kernel_packed_bt601[][4] = { #include "exa_wm_src_affine.g8b" #include "exa_wm_src_sample_argb.g8b" #include "exa_wm_yuv_rgb_bt601.g8b" #include "exa_wm_write.g8b" }; -static const uint32_t ps_kernel_planar[][4] = { +static const uint32_t ps_kernel_planar_bt601[][4] = { #include "exa_wm_src_affine.g8b" #include "exa_wm_src_sample_planar.g8b" #include "exa_wm_yuv_rgb_bt601.g8b" #include "exa_wm_write.g8b" }; -static const uint32_t ps_kernel_nv12[][4] = { +static const uint32_t ps_kernel_nv12_bt601[][4] = { #include "exa_wm_src_affine.g8b" #include "exa_wm_src_sample_nv12.g8b" #include "exa_wm_yuv_rgb_bt601.g8b" #include "exa_wm_write.g8b" }; +static const uint32_t ps_kernel_packed_bt709[][4] = { +#include "exa_wm_src_affine.g8b" +#include "exa_wm_src_sample_argb.g8b" +#include "exa_wm_yuv_rgb_bt709.g8b" +#include "exa_wm_write.g8b" +}; + +static const uint32_t ps_kernel_planar_bt709[][4] = { +#include "exa_wm_src_affine.g8b" +#include "exa_wm_src_sample_planar.g8b" +#include "exa_wm_yuv_rgb_bt709.g8b" +#include "exa_wm_write.g8b" +}; + +static const uint32_t ps_kernel_nv12_bt709[][4] = { +#include "exa_wm_src_affine.g8b" +#include "exa_wm_src_sample_nv12.g8b" +#include "exa_wm_yuv_rgb_bt709.g8b" +#include "exa_wm_write.g8b" +}; + static const uint32_t ps_kernel_rgb[][4] = { #include "exa_wm_src_affine.g8b" #include "exa_wm_src_sample_argb.g8b" @@ -150,9 +171,12 @@ static const struct wm_kernel_info { NOKERNEL(OPACITY_P, gen8_wm_kernel__projective_opacity, 2), #if !NO_VIDEO - KERNEL(VIDEO_PLANAR, ps_kernel_planar, 7), - KERNEL(VIDEO_NV12, ps_kernel_nv12, 7), - KERNEL(VIDEO_PACKED, ps_kernel_packed, 2), + KERNEL(VIDEO_PLANAR_BT601, ps_kernel_planar_bt601, 7), + KERNEL(VIDEO_NV12_BT601, ps_kernel_nv12_bt601, 7), + KERNEL(VIDEO_PACKED_BT601, ps_kernel_packed_bt601, 2), + KERNEL(VIDEO_PLANAR_BT709, ps_kernel_planar_bt709, 7), + KERNEL(VIDEO_NV12_BT709, ps_kernel_nv12_bt709, 7), + KERNEL(VIDEO_PACKED_BT709, ps_kernel_packed_bt709, 2), KERNEL(VIDEO_RGB, ps_kernel_rgb, 2), #endif }; @@ -3853,23 +3877,30 @@ static void gen9_emit_video_state(struct sna *sna, gen9_emit_state(sna, op, offset); } -static unsigned select_video_kernel(const struct sna_video_frame *frame) +static unsigned select_video_kernel(const struct sna_video *video, + const struct sna_video_frame *frame) { switch (frame->id) { case FOURCC_YV12: case FOURCC_I420: case FOURCC_XVMC: - return GEN9_WM_KERNEL_VIDEO_PLANAR; + return video->colorspace ? + GEN9_WM_KERNEL_VIDEO_PLANAR_BT709 : + GEN9_WM_KERNEL_VIDEO_PLANAR_BT601; case FOURCC_NV12: - return GEN9_WM_KERNEL_VIDEO_NV12; + return video->colorspace ? + GEN9_WM_KERNEL_VIDEO_NV12_BT709 : + GEN9_WM_KERNEL_VIDEO_NV12_BT601; case FOURCC_RGB888: case FOURCC_RGB565: return GEN9_WM_KERNEL_VIDEO_RGB; default: - return GEN9_WM_KERNEL_VIDEO_PACKED; + return video->colorspace ? + GEN9_WM_KERNEL_VIDEO_PACKED_BT709 : + GEN9_WM_KERNEL_VIDEO_PACKED_BT601; } } @@ -3933,7 +3964,7 @@ gen9_render_video(struct sna *sna, GEN9_SET_FLAGS(SAMPLER_OFFSET(filter, SAMPLER_EXTEND_PAD, SAMPLER_FILTER_NEAREST, SAMPLER_EXTEND_NONE), NO_BLEND, - select_video_kernel(frame), + select_video_kernel(video, frame), 2); tmp.priv = frame; diff --git a/src/sna/sna_render.h b/src/sna/sna_render.h index 730cb21f..6669af9d 100644 --- a/src/sna/sna_render.h +++ b/src/sna/sna_render.h @@ -436,9 +436,14 @@ enum { GEN6_WM_KERNEL_OPACITY, GEN6_WM_KERNEL_OPACITY_P, - GEN6_WM_KERNEL_VIDEO_PLANAR, - GEN6_WM_KERNEL_VIDEO_NV12, - GEN6_WM_KERNEL_VIDEO_PACKED, + GEN6_WM_KERNEL_VIDEO_PLANAR_BT601, + GEN6_WM_KERNEL_VIDEO_NV12_BT601, + GEN6_WM_KERNEL_VIDEO_PACKED_BT601, + + GEN6_WM_KERNEL_VIDEO_PLANAR_BT709, + GEN6_WM_KERNEL_VIDEO_NV12_BT709, + GEN6_WM_KERNEL_VIDEO_PACKED_BT709, + GEN6_KERNEL_COUNT }; @@ -487,9 +492,14 @@ enum { GEN7_WM_KERNEL_OPACITY, GEN7_WM_KERNEL_OPACITY_P, - GEN7_WM_KERNEL_VIDEO_PLANAR, - GEN7_WM_KERNEL_VIDEO_NV12, - GEN7_WM_KERNEL_VIDEO_PACKED, + GEN7_WM_KERNEL_VIDEO_PLANAR_BT601, + GEN7_WM_KERNEL_VIDEO_NV12_BT601, + GEN7_WM_KERNEL_VIDEO_PACKED_BT601, + + GEN7_WM_KERNEL_VIDEO_PLANAR_BT709, + GEN7_WM_KERNEL_VIDEO_NV12_BT709, + GEN7_WM_KERNEL_VIDEO_PACKED_BT709, + GEN7_WM_KERNEL_VIDEO_RGB, GEN7_WM_KERNEL_COUNT }; @@ -541,9 +551,14 @@ enum { GEN8_WM_KERNEL_OPACITY, GEN8_WM_KERNEL_OPACITY_P, - GEN8_WM_KERNEL_VIDEO_PLANAR, - GEN8_WM_KERNEL_VIDEO_NV12, - GEN8_WM_KERNEL_VIDEO_PACKED, + GEN8_WM_KERNEL_VIDEO_PLANAR_BT601, + GEN8_WM_KERNEL_VIDEO_NV12_BT601, + GEN8_WM_KERNEL_VIDEO_PACKED_BT601, + + GEN8_WM_KERNEL_VIDEO_PLANAR_BT709, + GEN8_WM_KERNEL_VIDEO_NV12_BT709, + GEN8_WM_KERNEL_VIDEO_PACKED_BT709, + GEN8_WM_KERNEL_VIDEO_RGB, GEN8_WM_KERNEL_COUNT }; @@ -593,9 +608,14 @@ enum { GEN9_WM_KERNEL_OPACITY, GEN9_WM_KERNEL_OPACITY_P, - GEN9_WM_KERNEL_VIDEO_PLANAR, - GEN9_WM_KERNEL_VIDEO_NV12, - GEN9_WM_KERNEL_VIDEO_PACKED, + GEN9_WM_KERNEL_VIDEO_PLANAR_BT601, + GEN9_WM_KERNEL_VIDEO_NV12_BT601, + GEN9_WM_KERNEL_VIDEO_PACKED_BT601, + + GEN9_WM_KERNEL_VIDEO_PLANAR_BT709, + GEN9_WM_KERNEL_VIDEO_NV12_BT709, + GEN9_WM_KERNEL_VIDEO_PACKED_BT709, + GEN9_WM_KERNEL_VIDEO_RGB, GEN9_WM_KERNEL_COUNT }; diff --git a/src/sna/sna_video_textured.c b/src/sna/sna_video_textured.c index bcd42320..a784fe2e 100644 --- a/src/sna/sna_video_textured.c +++ b/src/sna/sna_video_textured.c @@ -36,7 +36,7 @@ #define MAKE_ATOM(a) MakeAtom(a, sizeof(a) - 1, true) -static Atom xvBrightness, xvContrast, xvSyncToVblank; +static Atom xvBrightness, xvContrast, xvSyncToVblank, xvColorspace; static XvFormatRec Formats[] = { {15}, {16}, {24} @@ -44,6 +44,7 @@ static XvFormatRec Formats[] = { static const XvAttributeRec Attributes[] = { {XvSettable | XvGettable, -1, 1, (char *)"XV_SYNC_TO_VBLANK"}, + {XvSettable | XvGettable, 0, 1, (char *)"XV_COLORSPACE"}, /* BT.601, BT.709 */ //{XvSettable | XvGettable, -128, 127, (char *)"XV_BRIGHTNESS"}, //{XvSettable | XvGettable, 0, 255, (char *)"XV_CONTRAST"}, }; @@ -102,6 +103,11 @@ sna_video_textured_set_attribute(ddSetPortAttribute_ARGS) return BadValue; video->SyncToVblank = value; + } else if (attribute == xvColorspace) { + if (value < 0 || value > 1) + return BadValue; + + video->colorspace = value; } else return BadMatch; @@ -119,6 +125,8 @@ sna_video_textured_get_attribute(ddGetPortAttribute_ARGS) *value = video->contrast; else if (attribute == xvSyncToVblank) *value = video->SyncToVblank; + else if (attribute == xvColorspace) + *value = video->colorspace; else return BadMatch; @@ -426,6 +434,7 @@ void sna_video_textured_setup(struct sna *sna, ScreenPtr screen) v->sna = sna; v->textured = true; v->alignment = 4; + v->colorspace = 1; /* BT.709 */ v->SyncToVblank = (sna->flags & SNA_NO_WAIT) == 0; RegionNull(&v->clip); @@ -446,6 +455,7 @@ void sna_video_textured_setup(struct sna *sna, ScreenPtr screen) xvBrightness = MAKE_ATOM("XV_BRIGHTNESS"); xvContrast = MAKE_ATOM("XV_CONTRAST"); + xvColorspace = MAKE_ATOM("XV_COLORSPACE"); xvSyncToVblank = MAKE_ATOM("XV_SYNC_TO_VBLANK"); DBG(("%s: '%s' initialized %d ports\n", __FUNCTION__, adaptor->name, adaptor->nPorts)); -- cgit v1.2.3