[Mesa-dev] [PATCH 2/7] intel/blorp: Handle more exotic destination formats
Pohjolainen, Topi
topi.pohjolainen at gmail.com
Thu Jan 26 07:32:52 UTC 2017
On Tue, Jan 24, 2017 at 03:45:49PM -0800, Jason Ekstrand wrote:
> This commit adds support for using both R24_UNORM_X8_TYPELESS and
> R9G9B9E5_SHAREDEXP as destination formats even though the hardware does
> not support rendering to them. This is done by using a different format
> and emitting shader code to fake it the rest of the way.
Okay, I compared the R9G9B9E5_SHAREDEXP conversion to the software version in
src/util/format_rgb9e5.h. Looks good to me.
Reviewed-by: Topi Pohjolainen <topi.pohjolainen at intel.com>
> ---
> src/intel/blorp/blorp_blit.c | 92 ++++++++++++++++++++++++++++++++++++++++++++
> src/intel/blorp/blorp_priv.h | 6 +++
> 2 files changed, 98 insertions(+)
>
> diff --git a/src/intel/blorp/blorp_blit.c b/src/intel/blorp/blorp_blit.c
> index fc76fd4..b964224 100644
> --- a/src/intel/blorp/blorp_blit.c
> +++ b/src/intel/blorp/blorp_blit.c
> @@ -26,6 +26,7 @@
> #include "blorp_priv.h"
> #include "brw_meta_util.h"
>
> +#include "util/format_rgb9e5.h"
> /* header-only include needed for _mesa_unorm_to_float and friends. */
> #include "mesa/main/format_utils.h"
>
> @@ -916,6 +917,88 @@ bit_cast_color(struct nir_builder *b, nir_ssa_def *color,
> }
> }
>
> +static nir_ssa_def *
> +convert_color(struct nir_builder *b, nir_ssa_def *color,
> + const struct brw_blorp_blit_prog_key *key)
> +{
> + /* All of our color conversions end up generating a single-channel color
> + * value that we need to write out.
> + */
> + nir_ssa_def *value;
> +
> + if (key->dst_format == ISL_FORMAT_R24_UNORM_X8_TYPELESS) {
> + /* The destination image is bound as R32_UNORM but the data needs to be
> + * in R24_UNORM_X8_TYPELESS. The bottom 24 are the actual data and the
> + * top 8 need to be zero. We can accomplish this by simply multiplying
> + * by a factor to scale things down.
> + */
> + float factor = (float)((1 << 24) - 1) / (float)UINT32_MAX;
> + value = nir_fmul(b, nir_fsat(b, nir_channel(b, color, 0)),
> + nir_imm_float(b, factor));
> + } else if (key->dst_format == ISL_FORMAT_R9G9B9E5_SHAREDEXP) {
> + /* See also float3_to_rgb9e5 */
> +
> + /* First, we need to clamp it to range. */
> + nir_ssa_def *clamped = nir_fmin(b, color, nir_imm_float(b, MAX_RGB9E5));
> +
> + /* Get rid of negatives and NaN */
> + clamped = nir_bcsel(b, nir_ult(b, nir_imm_int(b, 0x7f800000), color),
> + nir_imm_float(b, 0), clamped);
> +
> + /* maxrgb.u = MAX3(rc.u, gc.u, bc.u); */
> + nir_ssa_def *maxu = nir_umax(b, nir_channel(b, clamped, 0),
> + nir_umax(b, nir_channel(b, clamped, 1),
> + nir_channel(b, clamped, 2)));
> +
> + /* maxrgb.u += maxrgb.u & (1 << (23-9)); */
> + maxu = nir_iadd(b, maxu, nir_iand(b, maxu, nir_imm_int(b, 1 << 14)));
> +
> + /* exp_shared = MAX2((maxrgb.u >> 23), -RGB9E5_EXP_BIAS - 1 + 127) +
> + * 1 + RGB9E5_EXP_BIAS - 127;
> + */
> + nir_ssa_def *exp_shared =
> + nir_iadd(b, nir_umax(b, nir_ushr(b, maxu, nir_imm_int(b, 23)),
> + nir_imm_int(b, -RGB9E5_EXP_BIAS - 1 + 127)),
> + nir_imm_int(b, 1 + RGB9E5_EXP_BIAS - 127));
> +
> + /* revdenom_biasedexp = 127 - (exp_shared - RGB9E5_EXP_BIAS -
> + * RGB9E5_MANTISSA_BITS) + 1;
> + */
> + nir_ssa_def *revdenom_biasedexp =
> + nir_isub(b, nir_imm_int(b, 127 + RGB9E5_EXP_BIAS +
> + RGB9E5_MANTISSA_BITS + 1),
> + exp_shared);
> +
> + /* revdenom.u = revdenom_biasedexp << 23; */
> + nir_ssa_def *revdenom =
> + nir_ishl(b, revdenom_biasedexp, nir_imm_int(b, 23));
> +
> + /* rm = (int) (rc.f * revdenom.f);
> + * gm = (int) (gc.f * revdenom.f);
> + * bm = (int) (bc.f * revdenom.f);
> + */
> + nir_ssa_def *mantissa =
> + nir_f2i(b, nir_fmul(b, clamped, revdenom));
> +
> + /* rm = (rm & 1) + (rm >> 1);
> + * gm = (gm & 1) + (gm >> 1);
> + * bm = (bm & 1) + (bm >> 1);
> + */
> + mantissa = nir_iadd(b, nir_iand(b, mantissa, nir_imm_int(b, 1)),
> + nir_ushr(b, mantissa, nir_imm_int(b, 1)));
> +
> + value = nir_channel(b, mantissa, 0);
> + value = nir_mask_shift_or(b, value, nir_channel(b, mantissa, 1), ~0, 9);
> + value = nir_mask_shift_or(b, value, nir_channel(b, mantissa, 2), ~0, 18);
> + value = nir_mask_shift_or(b, value, exp_shared, ~0, 27);
> + } else {
> + unreachable("Unsupported format conversion");
> + }
> +
> + nir_ssa_def *u = nir_ssa_undef(b, 1, 32);
> + return nir_vec4(b, value, u, u, u);
> +}
> +
> /**
> * Generator for WM programs used in BLORP blits.
> *
> @@ -1274,6 +1357,9 @@ brw_blorp_build_nir_shader(struct blorp_context *blorp, void *mem_ctx,
> if (key->dst_bpc != key->src_bpc)
> color = bit_cast_color(&b, color, key);
>
> + if (key->dst_format)
> + color = convert_color(&b, color, key);
> +
> if (key->dst_rgb) {
> /* The destination image is bound as a red texture three times as wide
> * as the actual image. Our shader is effectively running one color
> @@ -1797,6 +1883,12 @@ try_blorp_blit(struct blorp_batch *batch,
>
> wm_prog_key->dst_rgb = true;
> wm_prog_key->need_dst_offset = true;
> + } else if (params->dst.view.format == ISL_FORMAT_R24_UNORM_X8_TYPELESS) {
> + wm_prog_key->dst_format = params->dst.view.format;
> + params->dst.view.format = ISL_FORMAT_R32_UNORM;
> + } else if (params->dst.view.format == ISL_FORMAT_R9G9B9E5_SHAREDEXP) {
> + wm_prog_key->dst_format = params->dst.view.format;
> + params->dst.view.format = ISL_FORMAT_R32_UINT;
> }
>
> if (params->src.tile_x_sa || params->src.tile_y_sa) {
> diff --git a/src/intel/blorp/blorp_priv.h b/src/intel/blorp/blorp_priv.h
> index d9c03b1..9c6b81e 100644
> --- a/src/intel/blorp/blorp_priv.h
> +++ b/src/intel/blorp/blorp_priv.h
> @@ -245,6 +245,12 @@ struct brw_blorp_blit_prog_key
> /* Number of bits per channel in the destination image. */
> uint8_t dst_bpc;
>
> + /* The format of the destination if format-specific workarounds are needed
> + * and 0 (ISL_FORMAT_R32G32B32A32_FLOAT) if the destination is natively
> + * renderable.
> + */
> + enum isl_format dst_format;
> +
> /* Type of the data to be read from the texture (one of
> * nir_type_(int|uint|float)).
> */
> --
> 2.5.0.400.gff86faf
>
> _______________________________________________
> mesa-dev mailing list
> mesa-dev at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/mesa-dev
More information about the mesa-dev
mailing list