[Mesa-dev] [PATCH 6/7] radeonsi: use all SPI color formats

Marek Olšák maraeo at gmail.com
Tue Jan 19 08:41:09 PST 2016


On Tue, Jan 19, 2016 at 5:20 PM, Axel Davy <axel.davy at ens.fr> wrote:
> On 19/01/2016 17:11, Marek Olšák wrote:
>>
>> From: Marek Olšák <marek.olsak at amd.com>
>>
>> because not using SPI_SHADER_32_ABGR doubles fill rate.
>>
>> We should also get optimal performance if alpha isn't needed or blending
>> isn't enabled.
>> ---
>>   src/gallium/drivers/radeon/r600_pipe_common.h   |   6 +-
>>   src/gallium/drivers/radeonsi/si_blit.c          |   8 +
>>   src/gallium/drivers/radeonsi/si_pipe.h          |   4 +
>>   src/gallium/drivers/radeonsi/si_state.c         | 207
>> +++++++++++++++++-------
>>   src/gallium/drivers/radeonsi/si_state.h         |   5 +
>>   src/gallium/drivers/radeonsi/si_state_shaders.c |  23 ++-
>>   6 files changed, 195 insertions(+), 58 deletions(-)
>>
>> diff --git a/src/gallium/drivers/radeon/r600_pipe_common.h
>> b/src/gallium/drivers/radeon/r600_pipe_common.h
>> index f3271e2..d66e74f 100644
>> --- a/src/gallium/drivers/radeon/r600_pipe_common.h
>> +++ b/src/gallium/drivers/radeon/r600_pipe_common.h
>> @@ -236,6 +236,7 @@ struct r600_surface {
>>         /* Misc. color flags. */
>>         bool alphatest_bypass;
>>         bool export_16bpc;
>> +       bool color_is_int8;
>>         /* Color registers. */
>>         unsigned cb_color_info;
>> @@ -252,7 +253,10 @@ struct r600_surface {
>>         unsigned cb_color_fmask_slice;  /* EG and later */
>>         unsigned cb_color_cmask;        /* CB_COLORn_TILE (r600 only) */
>>         unsigned cb_color_mask;         /* R600 only */
>> -       unsigned spi_shader_col_format; /* SI+ */
>> +       unsigned spi_shader_col_format;         /* SI+, no blending, no
>> alpha-to-coverage. */
>> +       unsigned spi_shader_col_format_alpha;   /* SI+, alpha-to-coverage
>> */
>> +       unsigned spi_shader_col_format_blend;   /* SI+, blending without
>> alpha. */
>> +       unsigned spi_shader_col_format_blend_alpha; /* SI+, blending with
>> alpha. */
>>         unsigned sx_ps_downconvert;     /* Stoney only */
>>         unsigned sx_blend_opt_epsilon;  /* Stoney only */
>>         struct r600_resource *cb_buffer_fmask; /* Used for FMASK
>> relocations. R600 only */
>> diff --git a/src/gallium/drivers/radeonsi/si_blit.c
>> b/src/gallium/drivers/radeonsi/si_blit.c
>> index 75a9d56..a93887e 100644
>> --- a/src/gallium/drivers/radeonsi/si_blit.c
>> +++ b/src/gallium/drivers/radeonsi/si_blit.c
>> @@ -680,6 +680,14 @@ static bool do_hardware_msaa_resolve(struct
>> pipe_context *ctx,
>>         enum pipe_format format = int_to_norm_format(info->dst.format);
>>         unsigned sample_mask = ~0;
>>   +     /* Hardware MSAA resolve doesn't work if SPI format = NORM16_ABGR
>> and
>> +        * the format is R16G16. Use R16A16, which does work.
>> +        */
>> +       if (format == PIPE_FORMAT_R16G16_UNORM)
>> +               format = PIPE_FORMAT_R16A16_UNORM;
>> +       if (format == PIPE_FORMAT_R16G16_SNORM)
>> +               format = PIPE_FORMAT_R16A16_SNORM;
>> +
>>         if (info->src.resource->nr_samples > 1 &&
>>             info->dst.resource->nr_samples <= 1 &&
>>             util_max_layer(info->src.resource, 0) == 0 &&
>> diff --git a/src/gallium/drivers/radeonsi/si_pipe.h
>> b/src/gallium/drivers/radeonsi/si_pipe.h
>> index e2009de..e2725fe 100644
>> --- a/src/gallium/drivers/radeonsi/si_pipe.h
>> +++ b/src/gallium/drivers/radeonsi/si_pipe.h
>> @@ -126,6 +126,10 @@ struct si_framebuffer {
>>         unsigned                        cb0_is_integer;
>>         unsigned                        compressed_cb_mask;
>>         unsigned                        spi_shader_col_format;
>> +       unsigned                        spi_shader_col_format_alpha;
>> +       unsigned                        spi_shader_col_format_blend;
>> +       unsigned                        spi_shader_col_format_blend_alpha;
>> +       unsigned                        color_is_int8; /* bitmask */
>>         unsigned                        dirty_cbufs;
>>         bool                            dirty_zsbuf;
>>   };
>> diff --git a/src/gallium/drivers/radeonsi/si_state.c
>> b/src/gallium/drivers/radeonsi/si_state.c
>> index 492d3f9..42f5291 100644
>> --- a/src/gallium/drivers/radeonsi/si_state.c
>> +++ b/src/gallium/drivers/radeonsi/si_state.c
>> @@ -420,6 +420,9 @@ static void *si_create_blend_state_mode(struct
>> pipe_context *ctx,
>>                        S_028B70_ALPHA_TO_MASK_OFFSET2(2) |
>>                        S_028B70_ALPHA_TO_MASK_OFFSET3(2));
>>   +     if (state->alpha_to_coverage)
>> +               blend->need_src_alpha_4bit |= 0xf;
>> +
>>         blend->cb_target_mask = 0;
>>         for (int i = 0; i < 8; i++) {
>>                 /* state->rt entries > 0 only written if independent
>> blending */
>> @@ -457,6 +460,17 @@ static void *si_create_blend_state_mode(struct
>> pipe_context *ctx,
>>                         blend_cntl |=
>> S_028780_ALPHA_DESTBLEND(si_translate_blend_factor(dstA));
>>                 }
>>                 si_pm4_set_reg(pm4, R_028780_CB_BLEND0_CONTROL + i * 4,
>> blend_cntl);
>> +
>> +               blend->blend_enable_4bit |= 0xf << (i * 4);
>> +
>> +               /* This is only important for formats without alpha. */
>> +               if (srcRGB == PIPE_BLENDFACTOR_SRC_ALPHA ||
>> +                   dstRGB == PIPE_BLENDFACTOR_SRC_ALPHA ||
>> +                   srcRGB == PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE ||
>> +                   dstRGB == PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE ||
>> +                   srcRGB == PIPE_BLENDFACTOR_INV_SRC_ALPHA ||
>> +                   dstRGB == PIPE_BLENDFACTOR_INV_SRC_ALPHA)
>> +                       blend->need_src_alpha_4bit |= 0xf << (i * 4);
>>         }
>>         if (blend->cb_target_mask) {
>> @@ -1270,53 +1284,6 @@ static uint32_t si_colorformat_endian_swap(uint32_t
>> colorformat)
>>         }
>>   }
>>   -/* Returns the size in bits of the widest component of a CB format */
>> -static unsigned si_colorformat_max_comp_size(uint32_t colorformat)
>> -{
>> -       switch(colorformat) {
>> -       case V_028C70_COLOR_4_4_4_4:
>> -               return 4;
>> -
>> -       case V_028C70_COLOR_1_5_5_5:
>> -       case V_028C70_COLOR_5_5_5_1:
>> -               return 5;
>> -
>> -       case V_028C70_COLOR_5_6_5:
>> -               return 6;
>> -
>> -       case V_028C70_COLOR_8:
>> -       case V_028C70_COLOR_8_8:
>> -       case V_028C70_COLOR_8_8_8_8:
>> -               return 8;
>> -
>> -       case V_028C70_COLOR_10_10_10_2:
>> -       case V_028C70_COLOR_2_10_10_10:
>> -               return 10;
>> -
>> -       case V_028C70_COLOR_10_11_11:
>> -       case V_028C70_COLOR_11_11_10:
>> -               return 11;
>> -
>> -       case V_028C70_COLOR_16:
>> -       case V_028C70_COLOR_16_16:
>> -       case V_028C70_COLOR_16_16_16_16:
>> -               return 16;
>> -
>> -       case V_028C70_COLOR_8_24:
>> -       case V_028C70_COLOR_24_8:
>> -               return 24;
>> -
>> -       case V_028C70_COLOR_32:
>> -       case V_028C70_COLOR_32_32:
>> -       case V_028C70_COLOR_32_32_32_32:
>> -       case V_028C70_COLOR_X24_8_32_FLOAT:
>> -               return 32;
>> -       }
>> -
>> -       assert(!"Unknown maximum component size");
>> -       return 0;
>> -}
>> -
>>   static uint32_t si_translate_dbformat(enum pipe_format format)
>>   {
>>         switch (format) {
>> @@ -1886,17 +1853,119 @@ unsigned si_tile_mode_index(struct r600_texture
>> *rtex, unsigned level, bool sten
>>     static void si_choose_spi_color_formats(struct r600_surface *surf,
>>                                         unsigned format, unsigned swap,
>> -                                       unsigned ntype)
>> +                                       unsigned ntype, bool is_depth)
>>   {
>> -       unsigned max_comp_size = si_colorformat_max_comp_size(format);
>> +       /* Alpha is needed for alpha-to-coverage.
>> +        * Blending may be with or without alpha.
>> +        */
>> +       unsigned normal = 0; /* most optimal, may not support blending or
>> export alpha */
>> +       unsigned alpha = 0; /* exports alpha, but may not support blending
>> */
>> +       unsigned blend = 0; /* supports blending, but may not export alpha
>> */
>> +       unsigned blend_alpha = 0; /* least optimal, supports blending and
>> exports alpha */
>>   -     surf->spi_shader_col_format = V_028714_SPI_SHADER_32_ABGR;
>> +       /* Choose the SPI color formats. These are required values for
>> Stoney/RB+.
>> +        * Other chips have multiple choices, though they are not
>> necessarily better.
>> +        */
>> +       switch (format) {
>> +       case V_028C70_COLOR_5_6_5:
>> +       case V_028C70_COLOR_1_5_5_5:
>> +       case V_028C70_COLOR_5_5_5_1:
>> +       case V_028C70_COLOR_4_4_4_4:
>> +       case V_028C70_COLOR_10_11_11:
>> +       case V_028C70_COLOR_11_11_10:
>> +       case V_028C70_COLOR_8:
>> +       case V_028C70_COLOR_8_8:
>> +       case V_028C70_COLOR_8_8_8_8:
>> +       case V_028C70_COLOR_10_10_10_2:
>> +       case V_028C70_COLOR_2_10_10_10:
>> +               if (ntype == V_028C70_NUMBER_UINT)
>> +                       alpha = blend = blend_alpha = normal =
>> V_028714_SPI_SHADER_UINT16_ABGR;
>
>
> Hi,
>
> The documentation of the  "BLEND_BYPASS" bit says it should be set if SINT
> or UINT is used.
> I deduce blending is not possible with these formats, and thus I guess here
> you cannot use them
> for blend and blend_alpha.

Yes, the code takes that into account. UINT16_ABGR is not blendable,
which is why the code sets "blend" the same as "normal". It means that
no matter what's enabled, always use UINT16_ABGR.

This allows trivial selection of export formats in
si_shader_selector_key by combining the formats with enable masks.

Marek


More information about the mesa-dev mailing list