drm/amd/display: Add support for SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616.
authorMario Kleiner <mario.kleiner.de@gmail.com>
Fri, 19 Mar 2021 21:03:14 +0000 (22:03 +0100)
committerAlex Deucher <alexander.deucher@amd.com>
Thu, 27 May 2021 19:00:47 +0000 (15:00 -0400)
Add the necessary format definition, bandwidth and pixel size mappings,
prescaler setup, and pixelformat selection, following the logic
already present for SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616.

The new SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616 is implemented as the
old SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616 format, but with swapped
red <-> green color channel, by use of the hardware xbar.

Please note that on the DCN 1/2/3 display engines, the pixelformat
in hubp and dpp setup for the old SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616
and the new SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616 was changed from
format id 22 to id 26. See amd/include/navi10_enum.h for the meaning
of the id's.

For format 22, the display engine read the framebuffer in 16 bpc format,
but truncated to the 12 bpc actually supported by later pipeline stages.
However, the engine took the 12 LSB of each color component for
truncation, which is incompatible with rendering at least under Vulkan,
where content is 16 bit wide, and a 12 MSB alignment would be appropriate,
if any. Format 20 for ARGB16161616_12MSB does work, but even better, we
can choose format 26 for ARGB16161616_UNORM, keeping all 16 bits around
until later stages of the display pipeline.

This allows to directly consume what the rendering hw produces under
Vulkan for swapchain format VK_FORMAT_R16G16B16A16_UNORM, as tested
with a patched version of the current AMD open-source amdvlk driver
which maps swapchain format VK_FORMAT_R16G16B16A16_UNORM onto
DRM_FORMAT_XBGR16161616.

The old id 22 would cause colorful pixeltrash to be displayed instead.

Tested under DCN-1.0 and DCE-11.2.

Signed-off-by: Mario Kleiner <mario.kleiner.de@gmail.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
15 files changed:
drivers/gpu/drm/amd/display/dc/calcs/dce_calcs.c
drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c
drivers/gpu/drm/amd/display/dc/core/dc_resource.c
drivers/gpu/drm/amd/display/dc/dc_hw_types.h
drivers/gpu/drm/amd/display/dc/dce/dce_mem_input.c
drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c
drivers/gpu/drm/amd/display/dc/dce110/dce110_mem_input_v.c
drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.c
drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubbub.c
drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.c
drivers/gpu/drm/amd/display/dc/dcn20/dcn20_dpp.c
drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hubbub.c
drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hubp.c
drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c
drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dpp.c

index 1244fcb..ff5bb15 100644 (file)
@@ -2863,6 +2863,7 @@ static void populate_initial_data(
                        data->bytes_per_pixel[num_displays + 4] = 4;
                        break;
                case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616:
+               case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616:
                case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F:
                        data->bytes_per_pixel[num_displays + 4] = 8;
                        break;
@@ -2966,6 +2967,7 @@ static void populate_initial_data(
                                data->bytes_per_pixel[num_displays + 4] = 4;
                                break;
                        case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616:
+                       case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616:
                        case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F:
                                data->bytes_per_pixel[num_displays + 4] = 8;
                                break;
index d4df4da..0e18df1 100644 (file)
@@ -236,6 +236,7 @@ static enum dcn_bw_defs tl_pixel_format_to_bw_defs(enum surface_pixel_format for
        case SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010_XR_BIAS:
                return dcn_bw_rgb_sub_32;
        case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616:
+       case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616:
        case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616F:
        case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F:
                return dcn_bw_rgb_sub_64;
@@ -375,6 +376,7 @@ static void pipe_ctx_to_e2e_pipe_params (
                input->src.viewport_height_c   = input->src.viewport_height / 2;
                break;
        case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616:
+       case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616:
        case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616F:
        case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F:
                input->src.source_format = dm_444_64;
index aea7d4c..c4d699e 100644 (file)
@@ -611,6 +611,7 @@ static enum pixel_format convert_pixel_format_to_dalsurface(
                dal_pixel_format = PIXEL_FORMAT_420BPP10;
                break;
        case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616:
+       case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616:
        default:
                dal_pixel_format = PIXEL_FORMAT_UNKNOWN;
                break;
@@ -2880,6 +2881,7 @@ unsigned int resource_pixel_format_to_bpp(enum surface_pixel_format format)
 #endif
                return 32;
        case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616:
+       case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616:
        case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616F:
        case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F:
                return 64;
index 04957a9..52355fe 100644 (file)
@@ -182,6 +182,8 @@ enum surface_pixel_format {
        SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010_XR_BIAS,
        /*64 bpp */
        SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616,
+       /*swapped*/
+       SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616,
        /*float*/
        SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616F,
        /*swaped & float*/
index 79a6f26..4cdd4da 100644 (file)
@@ -566,6 +566,7 @@ static void program_grph_pixel_format(
                         *  should problem swap endian*/
                format == SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010 ||
                format == SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010_XR_BIAS ||
+               format == SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616 ||
                format == SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F) {
                /* ABGR formats */
                red_xbar = 2;
@@ -606,6 +607,7 @@ static void program_grph_pixel_format(
                fallthrough;
        case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616F: /* shouldn't this get float too? */
        case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616:
+       case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616:
                grph_depth = 3;
                grph_format = 0;
                break;
index 1ef1b1b..e731987 100644 (file)
@@ -267,6 +267,7 @@ static void build_prescale_params(struct ipp_prescale_params *prescale_params,
                prescale_params->scale = 0x2008;
                break;
        case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616:
+       case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616:
        case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F:
                prescale_params->scale = 0x2000;
                break;
index 8bbb499..db7557a 100644 (file)
@@ -393,6 +393,7 @@ static void program_pixel_format(
                        grph_format = 1;
                        break;
                case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616:
+               case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616:
                case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F:
                case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616F:
                        grph_depth = 3;
index 7f8456b..a77e7bd 100644 (file)
@@ -257,7 +257,8 @@ static void dpp1_setup_format_flags(enum surface_pixel_format input_format,\
        if (input_format == SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616F ||
                input_format == SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F)
                *fmt = PIXEL_FORMAT_FLOAT;
-       else if (input_format == SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616)
+       else if (input_format == SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616 ||
+               input_format == SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616)
                *fmt = PIXEL_FORMAT_FIXED16;
        else
                *fmt = PIXEL_FORMAT_FIXED;
@@ -368,7 +369,8 @@ void dpp1_cnv_setup (
                select = INPUT_CSC_SELECT_ICSC;
                break;
        case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616:
-               pixel_format = 22;
+       case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616:
+               pixel_format = 26; /* ARGB16161616_UNORM */
                break;
        case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616F:
                pixel_format = 24;
index 6f42d10..f4f423d 100644 (file)
@@ -785,6 +785,7 @@ static bool hubbub1_dcc_support_pixel_format(
                *bytes_per_element = 4;
                return true;
        case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616:
+       case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616:
        case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616F:
        case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F:
                *bytes_per_element = 8;
index e39e8a2..04303fe 100644 (file)
@@ -245,6 +245,7 @@ void hubp1_program_pixel_format(
        if (format == SURFACE_PIXEL_FORMAT_GRPH_ABGR8888
                        || format == SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010
                        || format == SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010_XR_BIAS
+                       || format == SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616
                        || format == SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F) {
                red_bar = 2;
                blue_bar = 3;
@@ -277,8 +278,9 @@ void hubp1_program_pixel_format(
                                SURFACE_PIXEL_FORMAT, 10);
                break;
        case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616:
+       case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616: /*we use crossbar already*/
                REG_UPDATE(DCSURF_SURFACE_CONFIG,
-                               SURFACE_PIXEL_FORMAT, 22);
+                               SURFACE_PIXEL_FORMAT, 26); /* ARGB16161616_UNORM */
                break;
        case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616F:
        case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F:/*we use crossbar already*/
index 4af96cc..f2f44dd 100644 (file)
@@ -166,7 +166,8 @@ static void dpp2_cnv_setup (
                select = DCN2_ICSC_SELECT_ICSC_A;
                break;
        case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616:
-               pixel_format = 22;
+       case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616:
+               pixel_format = 26; /* ARGB16161616_UNORM */
                break;
        case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616F:
                pixel_format = 24;
index 6d03d98..91a9305 100644 (file)
@@ -158,6 +158,7 @@ bool hubbub2_dcc_support_pixel_format(
                *bytes_per_element = 4;
                return true;
        case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616:
+       case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616:
        case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616F:
        case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F:
                *bytes_per_element = 8;
index a1318c3..7e54058 100644 (file)
@@ -431,6 +431,7 @@ void hubp2_program_pixel_format(
        if (format == SURFACE_PIXEL_FORMAT_GRPH_ABGR8888
                        || format == SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010
                        || format == SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010_XR_BIAS
+                       || format == SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616
                        || format == SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F) {
                red_bar = 2;
                blue_bar = 3;
@@ -463,8 +464,9 @@ void hubp2_program_pixel_format(
                                SURFACE_PIXEL_FORMAT, 10);
                break;
        case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616:
+       case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616: /*we use crossbar already*/
                REG_UPDATE(DCSURF_SURFACE_CONFIG,
-                               SURFACE_PIXEL_FORMAT, 22);
+                               SURFACE_PIXEL_FORMAT, 26); /* ARGB16161616_UNORM */
                break;
        case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616F:
        case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F:/*we use crossbar already*/
index a3bc917..0d06307 100644 (file)
@@ -2365,6 +2365,7 @@ int dcn20_populate_dml_pipes_from_context(
                                pipes[pipe_cnt].pipe.src.source_format = dm_420_10;
                                break;
                        case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616:
+                       case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616:
                        case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616F:
                        case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F:
                                pipes[pipe_cnt].pipe.src.source_format = dm_444_64;
index 434d3c4..154279b 100644 (file)
@@ -245,7 +245,8 @@ static void dpp3_cnv_setup (
                select = INPUT_CSC_SELECT_ICSC;
                break;
        case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616:
-               pixel_format = 22;
+       case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616:
+               pixel_format = 26; /* ARGB16161616_UNORM */
                break;
        case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616F:
                pixel_format = 24;