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 1244fcb0f446dafb0d014a2fec137ab5c1d4e294..ff5bb152ef494f96667cb941a7e1976578910571 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 d4df4da5b81a83ddea381b5a8dcfbc3145488e95..0e18df1283b685fd592fe08cafa6f85ec1b3afe8 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 aea7d4cbb62c33bdb08513a3fe806bf8e9de67ac..c4d699e2c2fc1a4b20eefec69c0f2c1e73fc337b 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 04957a9efab2c8fab438b1b6607b8b1efc382802..52355fe6994c1448b0d9591e3efa9d2462b9c70d 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 79a6f261a0da99a5854d9cb6c3d570095f1bbdeb..4cdd4dacb7618663dc979ae3e888e98bf97f69d7 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 1ef1b1b33fb09038b64af4dbc034ab877f419c4e..e73198738fd80e2c248f172ef00dcb94ef52d879 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 8bbb499067f747a168178e54bb5859200dd8d65f..db7557a1c6134780e0bebe3a4db24a899f1319f9 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 7f8456b9988b243711e75136ff7fd6a0fd5f4ba0..a77e7bd3b8d5b23477d01dbd01a043861d8d941e 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 6f42d10dd772cd82f2b01478309e10e29a938f72..f4f423d0b8c3f85894c085de7edbfcfd8f1f5c7d 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 e39e8a2f715daf9740ea6ad367d7f80155b638fb..04303fe9c65930ead41850fd84b0c8be3be0d587 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 4af96cc5d9d623913bcb6922e4706cc694efd564..f2f44ddf522a48b9e8cfe035432adeacbf367b6d 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 6d03d98fca22e08c194a3014d8cc6ca025663c36..91a9305d42e89766f28083067890bc604f2cb37a 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 a1318c31bcfa52033066761b65db13440a22d087..7e54058715aaba91c8d0040904d9343d0b9fb41b 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 a3bc9176cc133f1f3e21aa1005e2ed21d007e346..0d06307456a21e6128424163ee0c10dd6a1fbcc0 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 434d3c46cad480774989ed226e2d2654e8492101..154279b91967104ada076323555690e4f7376257 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;